3 #include <Elementary.h>
4 #include <Elementary_Cursor.h>
6 #include "els_scroller.h"
8 #include "elm_genlist.h"
10 #define SWIPE_MOVES 12
11 #define MAX_ITEMS_PER_BLOCK 32
12 #define REORDER_EFFECT_TIME 0.5
14 #define ELM_GEN_SETUP(wd) \
15 (wd)->calc_cb = (Ecore_Cb)_calc_job; \
16 (wd)->clear_cb = (Ecore_Cb)_clear_cb; \
17 (wd)->sizing_cb = (Ecore_Cb)_sizing_eval
20 #define ELM_GEN_ITEM_SETUP(it) \
21 (it)->del_cb = (Ecore_Cb)_item_del; \
22 (it)->highlight_cb = (Ecore_Cb)_item_highlight; \
23 (it)->unsel_cb = (Ecore_Cb)_item_unselect; \
24 (it)->unhighlight_cb = (Ecore_Cb)_item_unhighlight; \
25 (it)->unrealize_cb = (Ecore_Cb)_item_unrealize_cb
27 typedef struct _Item_Block Item_Block;
28 typedef struct _Item_Cache Item_Cache;
30 struct Elm_Gen_Item_Type
35 Evas_Coord w, h, minw, minh;
36 Elm_Gen_Item *group_item;
37 Elm_Genlist_Item_Flags flags;
38 Eina_List *mode_labels, *mode_contents, *mode_states, *mode_content_objs;
39 Ecore_Timer *swipe_timer;
40 Evas_Coord scrl_x, scrl_y, old_scrl_y;
43 Evas_Object *mode_view;
49 Eina_Bool want_realize : 1;
50 Eina_Bool expanded : 1;
51 Eina_Bool mincalcd : 1;
54 Eina_Bool updateme : 1;
55 Eina_Bool nocache : 1;
56 Eina_Bool stacking_even : 1;
57 Eina_Bool nostacking : 1;
58 Eina_Bool move_effect_enabled : 1;
63 Eina_Inlist_Sorted_State *state;
64 Evas_Object *obj; /* the genlist object */
65 Evas_Object *scr; /* a smart scroller object which is used internally in genlist */
66 Evas_Object *pan_smart; /* "elm_genlist_pan" evas smart object. this is an extern pan of smart scroller(scr). */
68 Eina_List *group_items; /* list of groups index items */
69 Eina_Inlist *items; /* inlist of all items */
70 Elm_Gen_Item *reorder_it; /* item currently being repositioned */
71 Elm_Gen_Item *last_selected_item;
72 Pan *pan; /* pan_smart object's smart data */
75 int item_width, item_height;
76 int group_item_width, group_item_height;
79 Evas_Coord pan_x, pan_y;
80 Eina_Bool reorder_mode : 1; /* a flag for reorder mode enable/disable */
81 Eina_Bool on_hold : 1;
82 Eina_Bool multi : 1; /* a flag for item multi selection */
83 Eina_Bool no_select : 1;
84 Eina_Bool wasselected : 1;
85 Eina_Bool always_select : 1;
86 Eina_Bool clear_me : 1;
87 Eina_Bool h_bounce : 1;
88 Eina_Bool v_bounce : 1;
89 Ecore_Cb del_cb, calc_cb, sizing_cb;
91 ////////////////////////////////////
92 Eina_Inlist *blocks; /* inlist of all blocks. a block consists of a certain number of items. maximum number of items in a block is 'max_items_per_block'. */
93 Evas_Coord reorder_old_pan_y, w, h, realminw, prev_viewport_w;
94 Ecore_Job *update_job;
95 Ecore_Idle_Enterer *queue_idle_enterer;
96 Ecore_Idler *must_recalc_idler;
98 Elm_Gen_Item *show_item, *anchor_item, *mode_item, *reorder_rel, *expanded_item;
99 Eina_Inlist *item_cache; /* an inlist of edje object it cache. */
101 Evas_Coord reorder_start_y; /* reorder it's initial y coordinate in the pan. */
103 Ecore_Timer *multi_timer, *scr_hold_timer;
104 Ecore_Animator *reorder_move_animator;
105 const char *mode_type;
106 const char *mode_item_style;
107 unsigned int start_time;
108 Evas_Coord prev_x, prev_y, prev_mx, prev_my;
109 Evas_Coord cur_x, cur_y, cur_mx, cur_my;
110 Eina_Bool mouse_down : 1;
111 Eina_Bool multi_down : 1;
112 Eina_Bool multi_timeout : 1;
113 Eina_Bool multitouched : 1;
114 Eina_Bool longpressed : 1;
115 Eina_Bool bring_in : 1;
116 Eina_Bool compress : 1;
117 Eina_Bool height_for_width : 1;
118 Eina_Bool homogeneous : 1;
120 Eina_Bool reorder_pan_move : 1;
121 Eina_Bool auto_scroll_enabled : 1;
122 Eina_Bool pan_resized : 1;
126 } history[SWIPE_MOVES];
128 int item_cache_count;
129 int item_cache_max; /* maximum number of cached items */
131 int max_items_per_block; /* maximum number of items per block */
132 double longpress_timeout; /* longpress timeout. this value comes from _elm_config by default. this can be changed by elm_genlist_longpress_timeout_set() */
143 Evas_Coord x, y, w, h, minw, minh;
144 Eina_Bool want_unrealize : 1;
145 Eina_Bool realized : 1;
146 Eina_Bool changed : 1;
147 Eina_Bool updateme : 1;
148 Eina_Bool showme : 1;
149 Eina_Bool must_recalc : 1;
156 Evas_Object *base_view, *spacer;
158 const char *item_style; // it->itc->item_style
159 Eina_Bool tree : 1; // it->group
160 Eina_Bool compress : 1; // it->wd->compress
162 Eina_Bool selected : 1; // it->selected
163 Eina_Bool disabled : 1; // it->disabled
164 Eina_Bool expanded : 1; // it->item->expanded
167 static const char *widtype = NULL;
168 static void _item_cache_zero(Widget_Data *wd);
169 static void _del_hook(Evas_Object *obj);
170 static void _mirrored_set(Evas_Object *obj,
172 static void _theme_hook(Evas_Object *obj);
173 static void _show_region_hook(void *data,
175 static void _sizing_eval(Evas_Object *obj);
176 static void _item_realize(Elm_Gen_Item *it,
179 static void _item_unrealize_cb(Elm_Gen_Item *it);
180 static void _item_block_unrealize(Item_Block *itb);
181 static void _calc_job(void *data);
182 static void _on_focus_hook(void *data,
184 static Eina_Bool _item_multi_select_up(Widget_Data *wd);
185 static Eina_Bool _item_multi_select_down(Widget_Data *wd);
186 static Eina_Bool _item_single_select_up(Widget_Data *wd);
187 static Eina_Bool _item_single_select_down(Widget_Data *wd);
188 static Eina_Bool _event_hook(Evas_Object *obj,
190 Evas_Callback_Type type,
192 static void _signal_emit_hook(Evas_Object *obj,
193 const char *emission,
195 static Eina_Bool _deselect_all_items(Widget_Data *wd);
196 static void _pan_calculate(Evas_Object *obj);
197 static void _pan_max_get(Evas_Object *obj,
200 static void _item_position(Elm_Gen_Item *it,
204 static void _mode_item_realize(Elm_Gen_Item *it);
205 static void _mode_item_unrealize(Elm_Gen_Item *it);
206 static void _item_mode_set(Elm_Gen_Item *it);
207 static void _item_mode_unset(Widget_Data *wd);
208 static void _group_items_recalc(void *data);
209 static void _item_move_after(Elm_Gen_Item *it,
210 Elm_Gen_Item *after);
211 static void _item_move_before(Elm_Gen_Item *it,
212 Elm_Gen_Item *before);
213 static void _item_auto_scroll(Widget_Data *wd);
215 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
217 static const char SIG_ACTIVATED[] = "activated";
218 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
219 static const char SIG_SELECTED[] = "selected";
220 static const char SIG_UNSELECTED[] = "unselected";
221 static const char SIG_EXPANDED[] = "expanded";
222 static const char SIG_CONTRACTED[] = "contracted";
223 static const char SIG_EXPAND_REQUEST[] = "expand,request";
224 static const char SIG_CONTRACT_REQUEST[] = "contract,request";
225 static const char SIG_REALIZED[] = "realized";
226 static const char SIG_UNREALIZED[] = "unrealized";
227 static const char SIG_DRAG_START_UP[] = "drag,start,up";
228 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
229 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
230 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
231 static const char SIG_DRAG_STOP[] = "drag,stop";
232 static const char SIG_DRAG[] = "drag";
233 static const char SIG_LONGPRESSED[] = "longpressed";
234 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
235 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
236 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
237 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
238 static const char SIG_EDGE_TOP[] = "edge,top";
239 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
240 static const char SIG_EDGE_LEFT[] = "edge,left";
241 static const char SIG_EDGE_RIGHT[] = "edge,right";
242 static const char SIG_MULTI_SWIPE_LEFT[] = "multi,swipe,left";
243 static const char SIG_MULTI_SWIPE_RIGHT[] = "multi,swipe,right";
244 static const char SIG_MULTI_SWIPE_UP[] = "multi,swipe,up";
245 static const char SIG_MULTI_SWIPE_DOWN[] = "multi,swipe,down";
246 static const char SIG_MULTI_PINCH_OUT[] = "multi,pinch,out";
247 static const char SIG_MULTI_PINCH_IN[] = "multi,pinch,in";
248 static const char SIG_SWIPE[] = "swipe";
249 static const char SIG_MOVED[] = "moved";
251 static const Evas_Smart_Cb_Description _signals[] = {
252 {SIG_CLICKED_DOUBLE, ""},
255 {SIG_UNSELECTED, ""},
257 {SIG_CONTRACTED, ""},
258 {SIG_EXPAND_REQUEST, ""},
259 {SIG_CONTRACT_REQUEST, ""},
261 {SIG_UNREALIZED, ""},
262 {SIG_DRAG_START_UP, ""},
263 {SIG_DRAG_START_DOWN, ""},
264 {SIG_DRAG_START_LEFT, ""},
265 {SIG_DRAG_START_RIGHT, ""},
268 {SIG_LONGPRESSED, ""},
269 {SIG_SCROLL_ANIM_START, ""},
270 {SIG_SCROLL_ANIM_STOP, ""},
271 {SIG_SCROLL_DRAG_START, ""},
272 {SIG_SCROLL_DRAG_STOP, ""},
274 {SIG_EDGE_BOTTOM, ""},
276 {SIG_EDGE_RIGHT, ""},
277 {SIG_MULTI_SWIPE_LEFT, ""},
278 {SIG_MULTI_SWIPE_RIGHT, ""},
279 {SIG_MULTI_SWIPE_UP, ""},
280 {SIG_MULTI_SWIPE_DOWN, ""},
281 {SIG_MULTI_PINCH_OUT, ""},
282 {SIG_MULTI_PINCH_IN, ""},
288 static Eina_Compare_Cb _elm_genlist_item_compare_cb;
289 static Eina_Compare_Cb _elm_genlist_item_compare_data_cb;
292 #undef ELM_CHECK_WIDTYPE
293 #define ELM_CHECK_WIDTYPE(obj, widtype) \
294 if ((!obj) || (!elm_genlist_type_check((obj), __func__))) return
295 #undef ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN
296 #define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...) \
297 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
298 ELM_CHECK_WIDTYPE(WIDGET((it)), widtype) __VA_ARGS__;
300 static const char *_gengrid = NULL;
301 static const char *_genlist = NULL;
303 /* THIS FUNCTION IS HACKY AND TEMPORARY!!! */
305 elm_genlist_type_check(const Evas_Object *obj,
308 const char *provided, *expected = "(unknown)";
309 static int abort_on_warn = -1;
310 provided = elm_widget_type_get(obj);
311 if (!_genlist) _genlist = eina_stringshare_add("genlist");
312 if (!_gengrid) _gengrid = eina_stringshare_add("gengrid");
313 if (EINA_LIKELY(provided == _genlist) || EINA_LIKELY(provided == _gengrid))
315 if ((!provided) || (!provided[0]))
317 provided = evas_object_type_get(obj);
318 if ((!provided) || (!provided[0]))
319 provided = "(unknown)";
321 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
322 if (abort_on_warn == -1)
324 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
325 else abort_on_warn = 0;
327 if (abort_on_warn == 1) abort();
332 _event_hook(Evas_Object *obj,
333 Evas_Object *src __UNUSED__,
334 Evas_Callback_Type type,
337 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
338 Evas_Event_Key_Down *ev = event_info;
339 Widget_Data *wd = elm_widget_data_get(obj);
340 Evas_Coord pan_max_x = 0, pan_max_y = 0;
341 if (!wd) return EINA_FALSE;
342 if (!wd->items) return EINA_FALSE;
343 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
344 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
346 Elm_Gen_Item *it = NULL;
349 Evas_Coord step_x = 0;
350 Evas_Coord step_y = 0;
353 Evas_Coord page_x = 0;
354 Evas_Coord page_y = 0;
356 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
357 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
358 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
359 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
361 if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
365 else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
369 else if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up")))
371 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
372 (_item_multi_select_up(wd)))
373 || (_item_single_select_up(wd)))
375 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
381 else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
383 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
384 (_item_multi_select_down(wd)))
385 || (_item_single_select_down(wd)))
387 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
393 else if ((!strcmp(ev->keyname, "Home")) || (!strcmp(ev->keyname, "KP_Home")))
395 it = elm_genlist_first_item_get(obj);
396 elm_genlist_item_bring_in(it);
397 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
400 else if ((!strcmp(ev->keyname, "End")) || (!strcmp(ev->keyname, "KP_End")))
402 it = elm_genlist_last_item_get(obj);
403 elm_genlist_item_bring_in(it);
404 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
407 else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
410 y -= -(page_y * v_h) / 100;
414 else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
417 y += -(page_y * v_h) / 100;
421 else if (!strcmp(ev->keyname, "Escape"))
423 if (!_deselect_all_items(wd)) return EINA_FALSE;
424 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
427 else if (((!strcmp(ev->keyname, "Return")) ||
428 (!strcmp(ev->keyname, "KP_Enter")) ||
429 (!strcmp(ev->keyname, "space")))
430 && (!wd->multi) && (wd->selected))
432 it = elm_genlist_selected_item_get(obj);
433 elm_genlist_item_expanded_set(it,
434 !elm_genlist_item_expanded_get(it));
435 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
437 else return EINA_FALSE;
439 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
440 _pan_max_get(wd->pan_smart, &pan_max_x, &pan_max_y);
442 if (x > pan_max_x) x = pan_max_x;
444 if (y > pan_max_y) y = pan_max_y;
445 elm_smart_scroller_child_pos_set(wd->scr, x, y);
450 _deselect_all_items(Widget_Data *wd)
452 if (!wd->selected) return EINA_FALSE;
454 elm_genlist_item_selected_set(wd->selected->data, EINA_FALSE);
460 _item_multi_select_up(Widget_Data *wd)
462 if (!wd->selected) return EINA_FALSE;
463 if (!wd->multi) return EINA_FALSE;
465 Elm_Gen_Item *prev = elm_genlist_item_prev_get(wd->last_selected_item);
466 if (!prev) return EINA_TRUE;
468 if (elm_genlist_item_selected_get(prev))
470 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
471 wd->last_selected_item = prev;
472 elm_genlist_item_show(wd->last_selected_item);
476 elm_genlist_item_selected_set(prev, EINA_TRUE);
477 elm_genlist_item_show(prev);
483 _item_multi_select_down(Widget_Data *wd)
485 if (!wd->selected) return EINA_FALSE;
486 if (!wd->multi) return EINA_FALSE;
488 Elm_Gen_Item *next = elm_genlist_item_next_get(wd->last_selected_item);
489 if (!next) return EINA_TRUE;
491 if (elm_genlist_item_selected_get(next))
493 elm_genlist_item_selected_set(wd->last_selected_item, EINA_FALSE);
494 wd->last_selected_item = next;
495 elm_genlist_item_show(wd->last_selected_item);
499 elm_genlist_item_selected_set(next, EINA_TRUE);
500 elm_genlist_item_show(next);
506 _item_single_select_up(Widget_Data *wd)
511 prev = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
512 while ((prev) && (prev->delete_me))
513 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
515 else prev = elm_genlist_item_prev_get(wd->last_selected_item);
517 if (!prev) return EINA_FALSE;
519 _deselect_all_items(wd);
521 elm_genlist_item_selected_set(prev, EINA_TRUE);
522 elm_genlist_item_show(prev);
527 _item_single_select_down(Widget_Data *wd)
532 next = ELM_GEN_ITEM_FROM_INLIST(wd->items);
533 while ((next) && (next->delete_me))
534 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
536 else next = elm_genlist_item_next_get(wd->last_selected_item);
538 if (!next) return EINA_FALSE;
540 _deselect_all_items(wd);
542 elm_genlist_item_selected_set(next, EINA_TRUE);
543 elm_genlist_item_show(next);
548 _on_focus_hook(void *data __UNUSED__,
551 Widget_Data *wd = elm_widget_data_get(obj);
553 if (elm_widget_focus_get(obj))
555 elm_object_signal_emit(wd->obj, "elm,action,focus", "elm");
556 evas_object_focus_set(wd->obj, EINA_TRUE);
557 if ((wd->selected) && (!wd->last_selected_item))
558 wd->last_selected_item = eina_list_data_get(wd->selected);
562 elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm");
563 evas_object_focus_set(wd->obj, EINA_FALSE);
568 _del_hook(Evas_Object *obj)
570 Widget_Data *wd = elm_widget_data_get(obj);
572 _item_cache_zero(wd);
573 if (wd->calc_job) ecore_job_del(wd->calc_job);
574 if (wd->update_job) ecore_job_del(wd->update_job);
575 if (wd->queue_idle_enterer) ecore_idle_enterer_del(wd->queue_idle_enterer);
576 if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler);
577 if (wd->multi_timer) ecore_timer_del(wd->multi_timer);
578 if (wd->mode_type) eina_stringshare_del(wd->mode_type);
579 if (wd->scr_hold_timer) ecore_timer_del(wd->scr_hold_timer);
584 _del_pre_hook(Evas_Object *obj)
586 Widget_Data *wd = elm_widget_data_get(obj);
588 elm_genlist_clear(obj);
589 evas_object_del(wd->pan_smart);
590 wd->pan_smart = NULL;
594 _mirrored_set(Evas_Object *obj,
597 Widget_Data *wd = elm_widget_data_get(obj);
599 _item_cache_zero(wd);
600 elm_smart_scroller_mirrored_set(wd->scr, rtl);
604 _theme_hook(Evas_Object *obj)
606 Widget_Data *wd = elm_widget_data_get(obj);
609 evas_event_freeze(evas_object_evas_get(wd->obj));
610 _item_cache_zero(wd);
611 _elm_widget_mirrored_reload(obj);
612 _mirrored_set(obj, elm_widget_mirrored_get(obj));
613 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
614 elm_widget_style_get(obj));
615 edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
616 wd->item_width = wd->item_height = 0;
617 wd->group_item_width = wd->group_item_height = 0;
618 wd->minw = wd->minh = wd->realminw = 0;
619 EINA_INLIST_FOREACH(wd->blocks, itb)
624 if (itb->realized) _item_block_unrealize(itb);
625 EINA_LIST_FOREACH(itb->items, l, it)
626 it->item->mincalcd = EINA_FALSE;
628 itb->changed = EINA_TRUE;
630 if (wd->calc_job) ecore_job_del(wd->calc_job);
631 wd->calc_job = ecore_job_add(_calc_job, wd);
633 evas_event_thaw(evas_object_evas_get(wd->obj));
634 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
638 _show_region_hook(void *data,
641 Widget_Data *wd = elm_widget_data_get(data);
642 Evas_Coord x, y, w, h;
644 elm_widget_show_region_get(obj, &x, &y, &w, &h);
645 //x & y are screen coordinates, Add with pan coordinates
648 elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
652 _translate_hook(Evas_Object *obj)
654 evas_object_smart_callback_call(obj, "language,changed", NULL);
658 _sizing_eval(Evas_Object *obj)
660 Widget_Data *wd = elm_widget_data_get(obj);
661 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
663 evas_object_size_hint_min_get(wd->scr, &minw, &minh);
664 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
666 if (wd->height_for_width)
670 elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
671 if ((vw != 0) && (vw != wd->prev_viewport_w))
675 wd->prev_viewport_w = vw;
676 EINA_INLIST_FOREACH(wd->blocks, itb)
678 itb->must_recalc = EINA_TRUE;
680 if (wd->calc_job) ecore_job_del(wd->calc_job);
681 wd->calc_job = ecore_job_add(_calc_job, wd);
684 if (wd->mode == ELM_LIST_LIMIT)
690 edje_object_size_min_calc
691 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
698 edje_object_size_min_calc
699 (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
703 evas_object_size_hint_min_set(obj, minw, minh);
704 evas_object_size_hint_max_set(obj, maxw, maxh);
708 _signal_emit_hook(Evas_Object *obj,
709 const char *emission,
712 Widget_Data *wd = elm_widget_data_get(obj);
713 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
718 _item_highlight(Elm_Gen_Item *it)
720 const char *selectraise;
721 if ((it->wd->no_select) || (it->delete_me) || (it->highlighted) ||
722 (it->disabled) || (it->display_only) || (it->item->mode_view))
724 edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
725 selectraise = edje_object_data_get(VIEW(it), "selectraise");
726 if ((selectraise) && (!strcmp(selectraise, "on")))
728 evas_object_raise(VIEW(it));
729 if ((it->item->group_item) && (it->item->group_item->realized))
730 evas_object_raise(it->item->VIEW(group_item));
732 it->highlighted = EINA_TRUE;
736 _item_unhighlight(Elm_Gen_Item *it)
738 if ((it->delete_me) || (!it->highlighted)) return;
739 edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
740 if (!it->item->nostacking)
742 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even) evas_object_lower(VIEW(it));
743 else evas_object_raise(VIEW(it));
745 it->highlighted = EINA_FALSE;
749 _item_block_del(Elm_Gen_Item *it)
752 Item_Block *itb = it->item->block;
754 itb->items = eina_list_remove(itb->items, it);
756 itb->changed = EINA_TRUE;
757 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
758 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
761 il = EINA_INLIST_GET(itb);
762 Item_Block *itbn = (Item_Block *)(il->next);
764 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
766 it->wd->blocks = eina_inlist_remove(it->wd->blocks, il);
768 if (itbn) itbn->changed = EINA_TRUE;
772 if (itb->count < itb->wd->max_items_per_block/2)
774 il = EINA_INLIST_GET(itb);
775 Item_Block *itbp = (Item_Block *)(il->prev);
776 Item_Block *itbn = (Item_Block *)(il->next);
777 if ((itbp) && ((itbp->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
781 EINA_LIST_FREE(itb->items, it2)
783 it2->item->block = itbp;
784 itbp->items = eina_list_append(itbp->items, it2);
786 itbp->changed = EINA_TRUE;
788 it->wd->blocks = eina_inlist_remove(it->wd->blocks,
789 EINA_INLIST_GET(itb));
792 else if ((itbn) && ((itbn->count + itb->count) < itb->wd->max_items_per_block + itb->wd->max_items_per_block/2))
796 Eina_List *last = eina_list_last(itb->items);
797 Elm_Gen_Item *it2 = last->data;
799 it2->item->block = itbn;
800 itb->items = eina_list_remove_list(itb->items, last);
801 itbn->items = eina_list_prepend(itbn->items, it2);
803 itbn->changed = EINA_TRUE;
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(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->block) _item_block_del(it);
823 if (it->item->queued)
824 it->wd->queue = eina_list_remove(it->wd->queue, it);
825 if (it->wd->anchor_item == it)
827 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
828 if (!it->wd->anchor_item)
829 it->wd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
832 it->parent->item->items = eina_list_remove(it->parent->item->items, it);
833 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
834 _elm_genlist_item_del_serious(it);
835 evas_event_thaw(evas_object_evas_get(obj));
836 evas_event_thaw_eval(evas_object_evas_get(obj));
840 _clear_cb(Widget_Data *wd)
842 wd->anchor_item = NULL;
845 Item_Block *itb = (Item_Block *)(wd->blocks);
847 wd->blocks = eina_inlist_remove(wd->blocks, wd->blocks);
848 if (itb->items) eina_list_free(itb->items);
851 if (wd->queue_idle_enterer)
853 ecore_idle_enterer_del(wd->queue_idle_enterer);
854 wd->queue_idle_enterer = NULL;
856 if (wd->must_recalc_idler)
858 ecore_idler_del(wd->must_recalc_idler);
859 wd->must_recalc_idler = NULL;
861 if (wd->queue) wd->queue = eina_list_free(wd->queue);
862 if (wd->reorder_move_animator)
864 ecore_animator_del(wd->reorder_move_animator);
865 wd->reorder_move_animator = NULL;
867 wd->show_item = NULL;
868 wd->reorder_old_pan_y = 0;
872 _item_unselect(Elm_Gen_Item *it)
874 if ((it->delete_me) || (!it->selected)) return;
875 it->selected = EINA_FALSE;
876 it->wd->selected = eina_list_remove(it->wd->selected, it);
877 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
881 _mouse_move(void *data,
882 Evas *evas __UNUSED__,
886 Elm_Gen_Item *it = data;
887 Evas_Event_Mouse_Move *ev = event_info;
888 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
889 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
891 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
893 if (!it->wd->on_hold)
895 it->wd->on_hold = EINA_TRUE;
896 if (!it->wd->wasselected)
898 _item_unhighlight(it);
903 if (it->wd->multitouched)
905 it->wd->cur_x = ev->cur.canvas.x;
906 it->wd->cur_y = ev->cur.canvas.y;
909 if ((it->dragging) && (it->down))
911 if (it->wd->movements == SWIPE_MOVES) it->wd->swipe = EINA_TRUE;
914 it->wd->history[it->wd->movements].x = ev->cur.canvas.x;
915 it->wd->history[it->wd->movements].y = ev->cur.canvas.y;
916 if (abs((it->wd->history[it->wd->movements].x -
917 it->wd->history[0].x)) > 40)
918 it->wd->swipe = EINA_TRUE;
924 ecore_timer_del(it->long_timer);
925 it->long_timer = NULL;
927 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
930 if ((!it->down) /* || (it->wd->on_hold)*/ || (it->wd->longpressed))
934 ecore_timer_del(it->long_timer);
935 it->long_timer = NULL;
937 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
939 evas_object_geometry_get(it->wd->pan_smart, &ox, &oy, &ow, &oh);
940 it_scrl_y = ev->cur.canvas.y - it->wd->reorder_it->dy;
942 if (!it->wd->reorder_start_y)
943 it->wd->reorder_start_y = it->item->block->y + it->y;
947 else if (it_scrl_y + it->wd->reorder_it->item->h > oy + oh)
948 y_pos = oy + oh - it->wd->reorder_it->item->h;
952 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
954 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
955 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
959 if (!it->display_only)
960 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
961 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
962 x = ev->cur.canvas.x - x;
963 y = ev->cur.canvas.y - y;
966 if (adx < 0) adx = -dx;
969 if (ady < 0) ady = -dy;
972 if ((adx > minw) || (ady > minh))
974 it->dragging = EINA_TRUE;
977 ecore_timer_del(it->long_timer);
978 it->long_timer = NULL;
980 if (!it->wd->wasselected)
982 _item_unhighlight(it);
988 evas_object_smart_callback_call(WIDGET(it),
989 SIG_DRAG_START_UP, it);
993 evas_object_smart_callback_call(WIDGET(it),
994 SIG_DRAG_START_LEFT, it);
996 evas_object_smart_callback_call(WIDGET(it),
997 SIG_DRAG_START_RIGHT, it);
1003 evas_object_smart_callback_call(WIDGET(it),
1004 SIG_DRAG_START_DOWN, it);
1008 evas_object_smart_callback_call(WIDGET(it),
1009 SIG_DRAG_START_LEFT, it);
1011 evas_object_smart_callback_call(WIDGET(it),
1012 SIG_DRAG_START_RIGHT, it);
1019 _long_press(void *data)
1021 Elm_Gen_Item *it = data, *it_tmp;
1022 Eina_List *list, *l;
1024 it->long_timer = NULL;
1025 if ((it->disabled) || (it->dragging) || (it->display_only))
1026 return ECORE_CALLBACK_CANCEL;
1027 it->wd->longpressed = EINA_TRUE;
1028 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1029 if ((it->wd->reorder_mode) && (!it->group))
1031 it->wd->reorder_it = it;
1032 it->wd->reorder_start_y = 0;
1034 evas_object_raise(VIEW(it));
1035 elm_smart_scroller_hold_set(it->wd->scr, EINA_TRUE);
1036 elm_smart_scroller_bounce_allow_set(it->wd->scr, EINA_FALSE, EINA_FALSE);
1038 list = elm_genlist_realized_items_get(it->wd->obj);
1039 EINA_LIST_FOREACH(list, l, it_tmp)
1041 if (it != it_tmp) _item_unselect(it_tmp);
1043 if (elm_genlist_item_expanded_get(it))
1045 elm_genlist_item_expanded_set(it, EINA_FALSE);
1046 return ECORE_CALLBACK_RENEW;
1048 edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
1050 return ECORE_CALLBACK_CANCEL;
1054 _swipe(Elm_Gen_Item *it)
1059 if ((it->display_only) || (it->disabled)) return;
1060 it->wd->swipe = EINA_FALSE;
1061 for (i = 0; i < it->wd->movements; i++)
1063 sum += it->wd->history[i].x;
1064 if (abs(it->wd->history[0].y - it->wd->history[i].y) > 10) return;
1067 sum /= it->wd->movements;
1068 if (abs(sum - it->wd->history[0].x) <= 10) return;
1069 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, it);
1073 _swipe_cancel(void *data)
1075 Elm_Gen_Item *it = data;
1077 if (!it) return ECORE_CALLBACK_CANCEL;
1078 it->wd->swipe = EINA_FALSE;
1079 it->wd->movements = 0;
1080 return ECORE_CALLBACK_RENEW;
1084 _multi_cancel(void *data)
1086 Widget_Data *wd = data;
1088 if (!wd) return ECORE_CALLBACK_CANCEL;
1089 wd->multi_timeout = EINA_TRUE;
1090 return ECORE_CALLBACK_RENEW;
1094 _multi_touch_gesture_eval(void *data)
1096 Elm_Gen_Item *it = data;
1098 it->wd->multitouched = EINA_FALSE;
1099 if (it->wd->multi_timer)
1101 ecore_timer_del(it->wd->multi_timer);
1102 it->wd->multi_timer = NULL;
1104 if (it->wd->multi_timeout)
1106 it->wd->multi_timeout = EINA_FALSE;
1110 Evas_Coord minw = 0, minh = 0;
1111 Evas_Coord off_x, off_y, off_mx, off_my;
1113 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1114 off_x = abs(it->wd->cur_x - it->wd->prev_x);
1115 off_y = abs(it->wd->cur_y - it->wd->prev_y);
1116 off_mx = abs(it->wd->cur_mx - it->wd->prev_mx);
1117 off_my = abs(it->wd->cur_my - it->wd->prev_my);
1119 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw) || (off_my > minh)))
1121 if ((off_x + off_mx) > (off_y + off_my))
1123 if ((it->wd->cur_x > it->wd->prev_x) && (it->wd->cur_mx > it->wd->prev_mx))
1124 evas_object_smart_callback_call(WIDGET(it),
1125 SIG_MULTI_SWIPE_RIGHT, it);
1126 else if ((it->wd->cur_x < it->wd->prev_x) && (it->wd->cur_mx < it->wd->prev_mx))
1127 evas_object_smart_callback_call(WIDGET(it),
1128 SIG_MULTI_SWIPE_LEFT, it);
1129 else if (abs(it->wd->cur_x - it->wd->cur_mx) > abs(it->wd->prev_x - it->wd->prev_mx))
1130 evas_object_smart_callback_call(WIDGET(it),
1131 SIG_MULTI_PINCH_OUT, it);
1133 evas_object_smart_callback_call(WIDGET(it),
1134 SIG_MULTI_PINCH_IN, it);
1138 if ((it->wd->cur_y > it->wd->prev_y) && (it->wd->cur_my > it->wd->prev_my))
1139 evas_object_smart_callback_call(WIDGET(it),
1140 SIG_MULTI_SWIPE_DOWN, it);
1141 else if ((it->wd->cur_y < it->wd->prev_y) && (it->wd->cur_my < it->wd->prev_my))
1142 evas_object_smart_callback_call(WIDGET(it),
1143 SIG_MULTI_SWIPE_UP, it);
1144 else if (abs(it->wd->cur_y - it->wd->cur_my) > abs(it->wd->prev_y - it->wd->prev_my))
1145 evas_object_smart_callback_call(WIDGET(it),
1146 SIG_MULTI_PINCH_OUT, it);
1148 evas_object_smart_callback_call(WIDGET(it),
1149 SIG_MULTI_PINCH_IN, it);
1152 it->wd->multi_timeout = EINA_FALSE;
1156 _multi_down(void *data,
1157 Evas *evas __UNUSED__,
1158 Evas_Object *obj __UNUSED__,
1161 Elm_Gen_Item *it = data;
1162 Evas_Event_Multi_Down *ev = event_info;
1164 if ((it->wd->multi_device != 0) || (it->wd->multitouched) || (it->wd->multi_timeout)) return;
1165 it->wd->multi_device = ev->device;
1166 it->wd->multi_down = EINA_TRUE;
1167 it->wd->multitouched = EINA_TRUE;
1168 it->wd->prev_mx = ev->canvas.x;
1169 it->wd->prev_my = ev->canvas.y;
1170 if (!it->wd->wasselected)
1172 _item_unhighlight(it);
1175 it->wd->wasselected = EINA_FALSE;
1176 it->wd->longpressed = EINA_FALSE;
1179 ecore_timer_del(it->long_timer);
1180 it->long_timer = NULL;
1184 it->dragging = EINA_FALSE;
1185 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1187 if (it->item->swipe_timer)
1189 ecore_timer_del(it->item->swipe_timer);
1190 it->item->swipe_timer = NULL;
1192 if (it->wd->on_hold)
1194 it->wd->swipe = EINA_FALSE;
1195 it->wd->movements = 0;
1196 it->wd->on_hold = EINA_FALSE;
1201 _multi_up(void *data,
1202 Evas *evas __UNUSED__,
1203 Evas_Object *obj __UNUSED__,
1206 Elm_Gen_Item *it = data;
1207 Evas_Event_Multi_Up *ev = event_info;
1209 if (it->wd->multi_device != ev->device) return;
1210 it->wd->multi_device = 0;
1211 it->wd->multi_down = EINA_FALSE;
1212 if (it->wd->mouse_down) return;
1213 _multi_touch_gesture_eval(data);
1217 _multi_move(void *data,
1218 Evas *evas __UNUSED__,
1219 Evas_Object *obj __UNUSED__,
1222 Elm_Gen_Item *it = data;
1223 Evas_Event_Multi_Move *ev = event_info;
1225 if (it->wd->multi_device != ev->device) return;
1226 it->wd->cur_mx = ev->cur.canvas.x;
1227 it->wd->cur_my = ev->cur.canvas.y;
1231 _mouse_down(void *data,
1232 Evas *evas __UNUSED__,
1236 Elm_Gen_Item *it = data;
1237 Evas_Event_Mouse_Down *ev = event_info;
1240 if (ev->button != 1) return;
1241 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1243 it->wd->on_hold = EINA_TRUE;
1246 it->down = EINA_TRUE;
1247 it->dragging = EINA_FALSE;
1248 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1249 it->dx = ev->canvas.x - x;
1250 it->dy = ev->canvas.y - y;
1251 it->wd->mouse_down = EINA_TRUE;
1252 if (!it->wd->multitouched)
1254 it->wd->prev_x = ev->canvas.x;
1255 it->wd->prev_y = ev->canvas.y;
1256 it->wd->multi_timeout = EINA_FALSE;
1257 if (it->wd->multi_timer) ecore_timer_del(it->wd->multi_timer);
1258 it->wd->multi_timer = ecore_timer_add(1, _multi_cancel, it->wd);
1260 it->wd->longpressed = EINA_FALSE;
1261 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1262 else it->wd->on_hold = EINA_FALSE;
1263 if (it->wd->on_hold) return;
1264 it->wd->wasselected = it->selected;
1265 _item_highlight(it);
1266 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1267 if ((!it->disabled) && (!it->display_only))
1269 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1270 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
1272 if (it->long_timer) ecore_timer_del(it->long_timer);
1273 if (it->item->swipe_timer) ecore_timer_del(it->item->swipe_timer);
1274 it->item->swipe_timer = ecore_timer_add(0.4, _swipe_cancel, it);
1276 it->long_timer = ecore_timer_add(it->wd->longpress_timeout, _long_press,
1279 it->long_timer = NULL;
1280 it->wd->swipe = EINA_FALSE;
1281 it->wd->movements = 0;
1285 _mouse_up(void *data,
1286 Evas *evas __UNUSED__,
1287 Evas_Object *obj __UNUSED__,
1290 Elm_Gen_Item *it = data;
1291 Evas_Event_Mouse_Up *ev = event_info;
1292 Eina_Bool dragged = EINA_FALSE;
1294 if (ev->button != 1) return;
1295 it->down = EINA_FALSE;
1296 it->wd->mouse_down = EINA_FALSE;
1297 if (it->wd->multitouched)
1299 if ((!it->wd->multi) && (!it->selected) && (it->highlighted)) _item_unhighlight(it);
1300 if (it->wd->multi_down) return;
1301 _multi_touch_gesture_eval(data);
1304 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->wd->on_hold = EINA_TRUE;
1305 else it->wd->on_hold = EINA_FALSE;
1308 ecore_timer_del(it->long_timer);
1309 it->long_timer = NULL;
1313 it->dragging = EINA_FALSE;
1314 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
1317 if (it->item->swipe_timer)
1319 ecore_timer_del(it->item->swipe_timer);
1320 it->item->swipe_timer = NULL;
1322 if (it->wd->multi_timer)
1324 ecore_timer_del(it->wd->multi_timer);
1325 it->wd->multi_timer = NULL;
1326 it->wd->multi_timeout = EINA_FALSE;
1328 if (it->wd->on_hold)
1330 if (it->wd->swipe) _swipe(data);
1331 it->wd->longpressed = EINA_FALSE;
1332 it->wd->on_hold = EINA_FALSE;
1335 if ((it->wd->reorder_mode) && (it->wd->reorder_it))
1337 Evas_Coord it_scrl_y = ev->canvas.y - it->wd->reorder_it->dy;
1339 if (it->wd->reorder_rel && (it->wd->reorder_it->parent == it->wd->reorder_rel->parent))
1341 if (it_scrl_y <= it->wd->reorder_rel->item->scrl_y)
1342 _item_move_before(it->wd->reorder_it, it->wd->reorder_rel);
1344 _item_move_after(it->wd->reorder_it, it->wd->reorder_rel);
1348 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
1349 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
1351 edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
1352 it->wd->reorder_it = it->wd->reorder_rel = NULL;
1353 elm_smart_scroller_hold_set(it->wd->scr, EINA_FALSE);
1354 elm_smart_scroller_bounce_allow_set(it->wd->scr, it->wd->h_bounce, it->wd->v_bounce);
1356 if (it->wd->longpressed)
1358 it->wd->longpressed = EINA_FALSE;
1359 if (!it->wd->wasselected)
1361 _item_unhighlight(it);
1364 it->wd->wasselected = EINA_FALSE;
1369 if (it->want_unrealize)
1371 _elm_genlist_item_unrealize(it, EINA_FALSE);
1372 if (it->item->block->want_unrealize)
1373 _item_block_unrealize(it->item->block);
1376 if ((it->disabled) || (dragged) || (it->display_only)) return;
1377 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1382 _item_highlight(it);
1387 _item_unhighlight(it);
1395 Widget_Data *wd = it->wd;
1398 while (wd->selected)
1400 _item_unhighlight(wd->selected->data);
1401 _item_unselect(wd->selected->data);
1407 const Eina_List *l, *l_next;
1410 EINA_LIST_FOREACH_SAFE(it->wd->selected, l, l_next, it2)
1413 _item_unhighlight(it2);
1414 _item_unselect(it2);
1416 //_item_highlight(it);
1419 _item_highlight(it);
1425 _signal_expand_toggle(void *data,
1426 Evas_Object *obj __UNUSED__,
1427 const char *emission __UNUSED__,
1428 const char *source __UNUSED__)
1430 Elm_Gen_Item *it = data;
1432 if (it->item->expanded)
1433 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, it);
1435 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1439 _signal_expand(void *data,
1440 Evas_Object *obj __UNUSED__,
1441 const char *emission __UNUSED__,
1442 const char *source __UNUSED__)
1444 Elm_Gen_Item *it = data;
1446 if (!it->item->expanded)
1447 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, it);
1451 _signal_contract(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_CONTRACT_REQUEST, it);
1463 _scr_hold_timer_cb(void *data)
1465 if (!data) return ECORE_CALLBACK_CANCEL;
1466 Widget_Data *wd = data;
1467 elm_smart_scroller_hold_set(wd->scr, EINA_FALSE);
1468 wd->scr_hold_timer = NULL;
1469 return ECORE_CALLBACK_CANCEL;
1473 _mode_finished_signal_cb(void *data,
1475 const char *emission __UNUSED__,
1476 const char *source __UNUSED__)
1480 Elm_Gen_Item *it = data;
1481 if ((it->delete_me) || (!it->realized) || (!it->item->mode_view)) return;
1483 Evas *te = evas_object_evas_get(obj);
1485 evas_event_freeze(te);
1486 it->item->nocache = EINA_FALSE;
1487 _mode_item_unrealize(it);
1488 if (it->item->group_item)
1489 evas_object_raise(it->item->VIEW(group_item));
1490 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished", it->wd->mode_type);
1491 edje_object_signal_callback_del_full(obj, buf, "elm", _mode_finished_signal_cb, it);
1492 evas_event_thaw(te);
1493 evas_event_thaw_eval(te);
1497 _item_cache_clean(Widget_Data *wd)
1499 evas_event_freeze(evas_object_evas_get(wd->obj));
1500 while ((wd->item_cache) && (wd->item_cache_count > wd->item_cache_max))
1504 itc = EINA_INLIST_CONTAINER_GET(wd->item_cache->last, Item_Cache);
1505 wd->item_cache = eina_inlist_remove(wd->item_cache,
1506 wd->item_cache->last);
1507 wd->item_cache_count--;
1508 if (itc->spacer) evas_object_del(itc->spacer);
1509 if (itc->base_view) evas_object_del(itc->base_view);
1510 if (itc->item_style) eina_stringshare_del(itc->item_style);
1513 evas_event_thaw(evas_object_evas_get(wd->obj));
1514 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
1518 _item_cache_zero(Widget_Data *wd)
1520 int pmax = wd->item_cache_max;
1521 wd->item_cache_max = 0;
1522 _item_cache_clean(wd);
1523 wd->item_cache_max = pmax;
1527 _item_cache_add(Elm_Gen_Item *it)
1531 evas_event_freeze(evas_object_evas_get(it->wd->obj));
1532 if (it->wd->item_cache_max <= 0)
1534 evas_object_del(VIEW(it));
1536 evas_object_del(it->spacer);
1538 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1539 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1543 it->wd->item_cache_count++;
1544 itc = calloc(1, sizeof(Item_Cache));
1545 it->wd->item_cache = eina_inlist_prepend(it->wd->item_cache,
1546 EINA_INLIST_GET(itc));
1547 itc->spacer = it->spacer;
1549 itc->base_view = VIEW(it);
1551 evas_object_hide(itc->base_view);
1552 evas_object_move(itc->base_view, -9999, -9999);
1553 itc->item_style = eina_stringshare_add(it->itc->item_style);
1554 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS) itc->tree = 1;
1555 itc->compress = (it->wd->compress);
1556 itc->selected = it->selected;
1557 itc->disabled = it->disabled;
1558 itc->expanded = it->item->expanded;
1561 ecore_timer_del(it->long_timer);
1562 it->long_timer = NULL;
1564 if (it->item->swipe_timer)
1566 ecore_timer_del(it->item->swipe_timer);
1567 it->item->swipe_timer = NULL;
1569 // FIXME: other callbacks?
1570 edje_object_signal_callback_del_full(itc->base_view,
1571 "elm,action,expand,toggle",
1572 "elm", _signal_expand_toggle, it);
1573 edje_object_signal_callback_del_full(itc->base_view, "elm,action,expand",
1575 _signal_expand, it);
1576 edje_object_signal_callback_del_full(itc->base_view, "elm,action,contract",
1577 "elm", _signal_contract, it);
1578 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_DOWN,
1580 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_UP,
1582 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MOUSE_MOVE,
1584 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_DOWN,
1586 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_UP,
1588 evas_object_event_callback_del_full(itc->base_view, EVAS_CALLBACK_MULTI_MOVE,
1590 _item_cache_clean(it->wd);
1591 evas_event_thaw(evas_object_evas_get(it->wd->obj));
1592 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1596 _item_cache_find(Elm_Gen_Item *it)
1601 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS) tree = 1;
1602 EINA_INLIST_FOREACH(it->wd->item_cache, itc)
1604 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1606 if ((itc->tree == tree) &&
1607 (itc->compress == it->wd->compress) &&
1608 (!strcmp(it->itc->item_style, itc->item_style)))
1610 it->wd->item_cache = eina_inlist_remove(it->wd->item_cache,
1611 EINA_INLIST_GET(itc));
1612 it->wd->item_cache_count--;
1620 _elm_genlist_item_odd_even_update(Elm_Gen_Item *it)
1622 if (!it->item->nostacking)
1624 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
1625 evas_object_lower(VIEW(it));
1627 evas_object_raise(VIEW(it));
1630 if (it->item->order_num_in & 0x1)
1631 edje_object_signal_emit(VIEW(it), "elm,state,odd", "elm");
1633 edje_object_signal_emit(VIEW(it), "elm,state,even", "elm");
1637 _elm_genlist_item_state_update(Elm_Gen_Item *it, Item_Cache *itc)
1641 if (it->selected != itc->selected)
1644 edje_object_signal_emit(VIEW(it),
1645 "elm,state,selected", "elm");
1647 if (it->disabled != itc->disabled)
1650 edje_object_signal_emit(VIEW(it),
1651 "elm,state,disabled", "elm");
1653 if (it->item->expanded != itc->expanded)
1655 if (it->item->expanded)
1656 edje_object_signal_emit(VIEW(it),
1657 "elm,state,expanded", "elm");
1663 edje_object_signal_emit(VIEW(it),
1664 "elm,state,selected", "elm");
1666 edje_object_signal_emit(VIEW(it),
1667 "elm,state,disabled", "elm");
1668 if (it->item->expanded)
1669 edje_object_signal_emit(VIEW(it),
1670 "elm,state,expanded", "elm");
1675 _item_cache_free(Item_Cache *itc)
1677 if (itc->spacer) evas_object_del(itc->spacer);
1678 if (itc->base_view) evas_object_del(itc->base_view);
1679 if (itc->item_style) eina_stringshare_del(itc->item_style);
1684 _item_del_hook(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1686 Elm_Gen_Item *it = event_info;
1688 if (it->wd->last_selected_item == it)
1689 it->wd->last_selected_item = NULL;
1693 _item_label_realize(Elm_Gen_Item *it,
1694 Evas_Object *target,
1698 if (it->itc->func.label_get)
1703 *source = elm_widget_stringlist_get(edje_object_data_get(target, "labels"));
1704 EINA_LIST_FOREACH(*source, l, key)
1706 if (parts && fnmatch(parts, key, FNM_PERIOD))
1709 char *s = it->itc->func.label_get
1710 ((void *)it->base.data, WIDGET(it), key);
1714 edje_object_part_text_set(target, key, s);
1719 edje_object_part_text_set(target, key, "");
1726 _item_content_unrealize(Elm_Gen_Item *it,
1727 Evas_Object *target,
1731 Eina_List *res = it->content_objs;
1733 if (it->itc->func.content_get)
1737 Evas_Object *ic = NULL;
1739 EINA_LIST_FOREACH(*source, l, key)
1741 if (parts && fnmatch(parts, key, FNM_PERIOD))
1744 ic = edje_object_part_swallow_get(target, key);
1747 res = eina_list_remove(res, ic);
1748 edje_object_part_unswallow(target, ic);
1749 evas_object_del(ic);
1758 _item_content_realize(Elm_Gen_Item *it,
1759 Evas_Object *target,
1763 Eina_List *res = NULL;
1765 if (it->itc->func.content_get)
1769 Evas_Object *ic = NULL;
1771 *source = elm_widget_stringlist_get(edje_object_data_get(target, "contents"));
1773 if (parts && (eina_list_count(*source) != eina_list_count(it->content_objs)))
1774 res = it->content_objs;
1776 EINA_LIST_FOREACH(*source, l, key)
1778 if (parts && fnmatch(parts, key, FNM_PERIOD))
1781 if (it->itc->func.content_get)
1782 ic = it->itc->func.content_get
1783 ((void *)it->base.data, WIDGET(it), key);
1786 res = eina_list_append(res, ic);
1787 edje_object_part_swallow(target, key, ic);
1788 evas_object_show(ic);
1789 elm_widget_sub_object_add(WIDGET(it), ic);
1791 elm_widget_disabled_set(ic, EINA_TRUE);
1800 _item_state_realize(Elm_Gen_Item *it,
1801 Evas_Object *target,
1805 if (it->itc->func.state_get)
1811 *source = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
1812 EINA_LIST_FOREACH(*source, l, key)
1814 if (parts && fnmatch(parts, key, FNM_PERIOD))
1817 Eina_Bool on = it->itc->func.state_get
1818 ((void *)it->base.data, WIDGET(it), key);
1822 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1823 edje_object_signal_emit(target, buf, "elm");
1827 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1828 edje_object_signal_emit(target, buf, "elm");
1835 _item_realize(Elm_Gen_Item *it,
1840 const char *treesize;
1842 int depth, tsize = 20;
1843 Item_Cache *itc = NULL;
1845 if (it->delete_me) return;
1846 //evas_event_freeze(evas_object_evas_get(it->wd->obj));
1849 if (it->item->order_num_in != in)
1851 it->item->order_num_in = in;
1852 _elm_genlist_item_odd_even_update(it);
1853 _elm_genlist_item_state_update(it, NULL);
1855 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
1856 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
1859 it->item->order_num_in = in;
1861 if (it->item->nocache)
1862 it->item->nocache = EINA_FALSE;
1864 itc = _item_cache_find(it);
1867 VIEW(it) = itc->base_view;
1868 itc->base_view = NULL;
1869 it->spacer = itc->spacer;
1874 const char *stacking_even;
1875 const char *stacking;
1877 VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
1878 edje_object_scale_set(VIEW(it),
1879 elm_widget_scale_get(WIDGET(it)) *
1880 _elm_config->scale);
1881 evas_object_smart_member_add(VIEW(it), it->wd->pan_smart);
1882 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
1884 if (it->item->flags & ELM_GENLIST_ITEM_SUBITEMS)
1885 strncpy(buf, "tree", sizeof(buf));
1886 else strncpy(buf, "item", sizeof(buf));
1887 if (it->wd->compress)
1888 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
1890 strncat(buf, "/", sizeof(buf) - strlen(buf));
1891 strncat(buf, it->itc->item_style, sizeof(buf) - strlen(buf));
1893 _elm_theme_object_set(WIDGET(it), VIEW(it), "genlist", buf,
1894 elm_widget_style_get(WIDGET(it)));
1896 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1897 if (!stacking_even) stacking_even = "above";
1898 it->item->stacking_even = !!strcmp("above", stacking_even);
1900 stacking = edje_object_data_get(VIEW(it), "stacking");
1901 if (!stacking) stacking = "yes";
1902 it->item->nostacking = !!strcmp("yes", stacking);
1904 edje_object_mirrored_set(VIEW(it),
1905 elm_widget_mirrored_get(WIDGET(it)));
1907 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1908 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1909 elm_widget_sub_object_add(WIDGET(it), it->spacer);
1912 _elm_genlist_item_odd_even_update(it);
1914 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
1916 if (!it2->parent->group) depth += 1;
1918 it->item->expanded_depth = depth;
1919 treesize = edje_object_data_get(VIEW(it), "treesize");
1920 if (treesize) tsize = atoi(treesize);
1921 evas_object_size_hint_min_set(it->spacer,
1922 (depth * tsize) * _elm_config->scale, 1);
1923 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1926 edje_object_signal_callback_add(VIEW(it),
1927 "elm,action,expand,toggle",
1928 "elm", _signal_expand_toggle, it);
1929 edje_object_signal_callback_add(VIEW(it), "elm,action,expand",
1930 "elm", _signal_expand, it);
1931 edje_object_signal_callback_add(VIEW(it), "elm,action,contract",
1932 "elm", _signal_contract, it);
1933 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN,
1935 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP,
1937 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
1939 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_DOWN,
1941 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_UP,
1943 evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MULTI_MOVE,
1946 _elm_genlist_item_state_update(it, itc);
1949 if ((calc) && (it->wd->homogeneous) &&
1950 ((it->wd->item_width) ||
1951 ((it->wd->item_width) && (it->wd->group_item_width))))
1953 /* homogenous genlist shortcut */
1954 if (!it->item->mincalcd)
1958 it->item->w = it->item->minw = it->wd->group_item_width;
1959 it->item->h = it->item->minh = it->wd->group_item_height;
1963 it->item->w = it->item->minw = it->wd->item_width;
1964 it->item->h = it->item->minh = it->wd->item_height;
1966 it->item->mincalcd = EINA_TRUE;
1971 /* FIXME: If you see that assert, please notify us and we
1972 will clean our mess */
1973 assert(eina_list_count(it->content_objs) == 0);
1975 _item_label_realize(it, VIEW(it), &it->labels, NULL);
1976 it->content_objs = _item_content_realize(it, VIEW(it), &it->contents, NULL);
1977 _item_state_realize(it, VIEW(it), &it->states, NULL);
1979 if (!it->item->mincalcd)
1981 Evas_Coord mw = -1, mh = -1;
1983 if (!it->display_only)
1984 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1985 if (it->wd->height_for_width) mw = it->wd->prev_viewport_w;
1986 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw,
1988 if (!it->display_only)
1989 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1990 it->item->w = it->item->minw = mw;
1991 it->item->h = it->item->minh = mh;
1992 it->item->mincalcd = EINA_TRUE;
1994 if ((!it->wd->group_item_width) && (it->group))
1996 it->wd->group_item_width = mw;
1997 it->wd->group_item_height = mh;
1999 else if ((!it->wd->item_width) && (it->item->flags == ELM_GENLIST_ITEM_NONE))
2001 it->wd->item_width = mw;
2002 it->wd->item_height = mh;
2005 if (!calc) evas_object_show(VIEW(it));
2008 if (it->tooltip.content_cb)
2010 elm_widget_item_tooltip_content_cb_set(it,
2011 it->tooltip.content_cb,
2012 it->tooltip.data, NULL);
2013 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
2014 elm_widget_item_tooltip_size_restrict_disable(it, it->tooltip.free_size);
2017 if (it->mouse_cursor)
2018 elm_widget_item_cursor_set(it, it->mouse_cursor);
2020 it->realized = EINA_TRUE;
2021 it->want_unrealize = EINA_FALSE;
2023 if (itc) _item_cache_free(itc);
2024 //evas_event_thaw(evas_object_evas_get(it->wd->obj));
2025 //evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2027 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
2028 edje_object_message_signal_process(VIEW(it));
2032 _item_unrealize_cb(Elm_Gen_Item *it)
2034 if (it->item->nocache)
2036 evas_object_del(VIEW(it));
2038 evas_object_del(it->spacer);
2043 edje_object_mirrored_set(VIEW(it),
2044 elm_widget_mirrored_get(WIDGET(it)));
2045 edje_object_scale_set(VIEW(it),
2046 elm_widget_scale_get(WIDGET(it))
2047 * _elm_config->scale);
2048 _item_cache_add(it);
2051 _mode_item_unrealize(it);
2053 it->realized = EINA_FALSE;
2054 it->want_unrealize = EINA_FALSE;
2058 _item_block_recalc(Item_Block *itb,
2064 Evas_Coord minw = 0, minh = 0;
2065 Eina_Bool showme = EINA_FALSE, changed = EINA_FALSE;
2068 //evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2070 EINA_LIST_FOREACH(itb->items, l, it)
2072 if (it->delete_me) continue;
2073 showme |= it->item->showme;
2078 if (!it->item->mincalcd) changed = EINA_TRUE;
2081 _item_realize(it, in, EINA_TRUE);
2082 _elm_genlist_item_unrealize(it, EINA_TRUE);
2087 _item_realize(it, in, EINA_TRUE);
2088 _elm_genlist_item_unrealize(it, EINA_TRUE);
2092 _item_realize(it, in, EINA_FALSE);
2093 minh += it->item->minh;
2094 if (minw < it->item->minw) minw = it->item->minw;
2102 itb->changed = EINA_FALSE;
2103 //evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2104 //evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2109 _item_block_realize(Item_Block *itb)
2111 if (itb->realized) return;
2112 itb->realized = EINA_TRUE;
2113 itb->want_unrealize = EINA_FALSE;
2117 _item_block_unrealize(Item_Block *itb)
2121 Eina_Bool dragging = EINA_FALSE;
2123 if (!itb->realized) return;
2124 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2125 EINA_LIST_FOREACH(itb->items, l, it)
2131 dragging = EINA_TRUE;
2132 it->want_unrealize = EINA_TRUE;
2135 _elm_genlist_item_unrealize(it, EINA_FALSE);
2140 itb->realized = EINA_FALSE;
2141 itb->want_unrealize = EINA_TRUE;
2144 itb->want_unrealize = EINA_FALSE;
2145 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2146 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2150 _get_space_for_reorder_item(Elm_Gen_Item *it)
2152 Evas_Coord rox, roy, row, roh, oy, oh;
2153 Eina_Bool top = EINA_FALSE;
2154 Elm_Gen_Item *reorder_it = it->wd->reorder_it;
2155 if (!reorder_it) return 0;
2157 evas_object_geometry_get(it->wd->pan_smart, NULL, &oy, NULL, &oh);
2158 evas_object_geometry_get(it->wd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2160 if ((it->wd->reorder_start_y < it->item->block->y) &&
2161 (roy - oy + (roh / 2) >= it->item->block->y - it->wd->pan_y))
2163 it->item->block->reorder_offset = it->wd->reorder_it->item->h * -1;
2164 if (it->item->block->count == 1)
2165 it->wd->reorder_rel = it;
2167 else if ((it->wd->reorder_start_y >= it->item->block->y) &&
2168 (roy - oy + (roh / 2) <= it->item->block->y - it->wd->pan_y))
2170 it->item->block->reorder_offset = it->wd->reorder_it->item->h;
2173 it->item->block->reorder_offset = 0;
2175 it->item->scrl_y += it->item->block->reorder_offset;
2177 top = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2178 rox, roy + (roh / 2), row, 1));
2181 it->wd->reorder_rel = it;
2182 it->item->scrl_y += it->wd->reorder_it->item->h;
2183 return it->wd->reorder_it->item->h;
2190 _reorder_move_animator_cb(void *data)
2192 Elm_Gen_Item *it = data;
2193 Eina_Bool down = EINA_FALSE;
2195 int y, dy = it->item->h / 10 * _elm_config->scale, diff;
2197 t = ((0.0 > (t = ecore_loop_time_get()-it->wd->start_time)) ? 0.0 : t);
2199 if (t <= REORDER_EFFECT_TIME) y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2202 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2203 if (diff > it->item->h) y = diff / 2;
2205 if (it->item->old_scrl_y < it->item->scrl_y)
2207 it->item->old_scrl_y += y;
2210 else if (it->item->old_scrl_y > it->item->scrl_y)
2212 it->item->old_scrl_y -= y;
2215 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2216 _group_items_recalc(it->wd);
2218 if ((it->wd->reorder_pan_move) ||
2219 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2220 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2222 it->item->old_scrl_y = it->item->scrl_y;
2223 it->item->move_effect_enabled = EINA_FALSE;
2224 it->wd->reorder_move_animator = NULL;
2225 return ECORE_CALLBACK_CANCEL;
2227 return ECORE_CALLBACK_RENEW;
2231 _item_position(Elm_Gen_Item *it,
2239 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2240 evas_object_resize(view, it->item->w, it->item->h);
2241 evas_object_move(view, it_x, it_y);
2242 evas_object_show(view);
2243 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2244 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2248 _item_block_position(Item_Block *itb,
2254 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2255 Eina_Bool vis = EINA_FALSE;
2257 evas_event_freeze(evas_object_evas_get(itb->wd->obj));
2258 evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, &ow, &oh);
2259 evas_output_viewport_get(evas_object_evas_get(itb->wd->obj), &cvx, &cvy,
2261 EINA_LIST_FOREACH(itb->items, l, it)
2263 if (it->delete_me) continue;
2264 else if (it->wd->reorder_it == it) continue;
2267 it->item->w = itb->w;
2268 it->item->scrl_x = itb->x + it->x - it->wd->pan_x + ox;
2269 it->item->scrl_y = itb->y + it->y - it->wd->pan_y + oy;
2271 vis = (ELM_RECTS_INTERSECT(it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2272 cvx, cvy, cvw, cvh));
2275 if ((itb->realized) && (!it->realized))
2277 if (vis) _item_realize(it, in, EINA_FALSE);
2283 if (it->wd->reorder_mode)
2284 y += _get_space_for_reorder_item(it);
2285 git = it->item->group_item;
2288 if (git->item->scrl_y < oy)
2289 git->item->scrl_y = oy;
2290 if ((git->item->scrl_y + git->item->h) > (it->item->scrl_y + it->item->h))
2291 git->item->scrl_y = (it->item->scrl_y + it->item->h) - git->item->h;
2292 git->item->want_realize = EINA_TRUE;
2294 if ((it->wd->reorder_it) && (it->item->old_scrl_y != it->item->scrl_y))
2296 if (!it->item->move_effect_enabled)
2298 it->item->move_effect_enabled = EINA_TRUE;
2299 it->wd->reorder_move_animator =
2301 _reorder_move_animator_cb, it);
2304 if (!it->item->move_effect_enabled)
2306 if (it->item->mode_view)
2307 _item_position(it, it->item->mode_view, it->item->scrl_x,
2310 _item_position(it, VIEW(it), it->item->scrl_x,
2312 it->item->old_scrl_y = it->item->scrl_y;
2317 if (!it->dragging) _elm_genlist_item_unrealize(it, EINA_FALSE);
2324 if (vis) it->item->want_realize = EINA_TRUE;
2328 evas_event_thaw(evas_object_evas_get(itb->wd->obj));
2329 evas_event_thaw_eval(evas_object_evas_get(itb->wd->obj));
2333 _group_items_recalc(void *data)
2335 Widget_Data *wd = data;
2339 evas_event_freeze(evas_object_evas_get(wd->obj));
2340 EINA_LIST_FOREACH(wd->group_items, l, git)
2342 if (git->item->want_realize)
2345 _item_realize(git, 0, EINA_FALSE);
2346 evas_object_resize(VIEW(git), wd->minw, git->item->h);
2347 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2348 evas_object_show(VIEW(git));
2349 evas_object_raise(VIEW(git));
2351 else if (!git->item->want_realize && git->realized)
2354 _elm_genlist_item_unrealize(git, EINA_FALSE);
2357 evas_event_thaw(evas_object_evas_get(wd->obj));
2358 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2362 _must_recalc_idler(void *data)
2364 Widget_Data *wd = data;
2365 if (wd->calc_job) ecore_job_del(wd->calc_job);
2366 wd->calc_job = ecore_job_add(_calc_job, wd);
2367 wd->must_recalc_idler = NULL;
2368 return ECORE_CALLBACK_CANCEL;
2372 _calc_job(void *data)
2374 Widget_Data *wd = data;
2375 Item_Block *itb, *chb = NULL;
2376 Evas_Coord minw = -1, minh = 0, y = 0, ow;
2378 Eina_Bool minw_change = EINA_FALSE;
2379 Eina_Bool did_must_recalc = EINA_FALSE;
2382 evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h);
2386 evas_event_freeze(evas_object_evas_get(wd->obj));
2387 EINA_INLIST_FOREACH(wd->blocks, itb)
2389 Eina_Bool showme = EINA_FALSE;
2392 showme = itb->showme;
2393 itb->showme = EINA_FALSE;
2396 if (itb->realized) _item_block_unrealize(itb);
2398 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
2400 if (itb->must_recalc)
2404 EINA_LIST_FOREACH(itb->items, l, it)
2405 if (it->item->mincalcd) it->item->mincalcd = EINA_FALSE;
2406 itb->changed = EINA_TRUE;
2407 if (itb->must_recalc) did_must_recalc = EINA_TRUE;
2408 itb->must_recalc = EINA_FALSE;
2410 if (itb->realized) _item_block_unrealize(itb);
2411 showme = _item_block_recalc(itb, in, EINA_FALSE);
2417 if (minw == -1) minw = itb->minw;
2418 else if ((!itb->must_recalc) && (minw < itb->minw))
2421 minw_change = EINA_TRUE;
2427 if ((showme) && (wd->show_item) && (!wd->show_item->item->queued))
2429 wd->show_item->item->showme = EINA_FALSE;
2431 elm_smart_scroller_region_bring_in(wd->scr,
2433 wd->show_item->item->block->x,
2435 wd->show_item->item->block->y,
2436 wd->show_item->item->block->w,
2437 wd->show_item->item->h);
2439 elm_smart_scroller_child_region_show(wd->scr,
2441 wd->show_item->item->block->x,
2443 wd->show_item->item->block->y,
2444 wd->show_item->item->block->w,
2445 wd->show_item->item->h);
2446 wd->show_item = NULL;
2451 EINA_INLIST_FOREACH(wd->blocks, itb)
2457 if ((chb) && (EINA_INLIST_GET(chb)->next))
2459 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
2461 if (itb->realized) _item_block_unrealize(itb);
2464 wd->realminw = minw;
2465 if (minw < wd->w) minw = wd->w;
2466 if ((minw != wd->minw) || (minh != wd->minh))
2470 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
2471 _sizing_eval(wd->obj);
2472 if ((wd->anchor_item) && (wd->anchor_item->item->block) && (!wd->auto_scroll_enabled))
2477 it = wd->anchor_item;
2478 it_y = wd->anchor_y;
2479 elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x,
2480 it->item->block->y + it->y + it_y);
2481 wd->anchor_item = it;
2482 wd->anchor_y = it_y;
2485 if (did_must_recalc)
2487 if (!wd->must_recalc_idler)
2488 wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd);
2490 wd->calc_job = NULL;
2491 evas_object_smart_changed(wd->pan_smart);
2492 evas_event_thaw(evas_object_evas_get(wd->obj));
2493 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2497 _update_job(void *data)
2499 Widget_Data *wd = data;
2503 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
2505 wd->update_job = NULL;
2508 evas_event_freeze(evas_object_evas_get(wd->obj));
2509 EINA_INLIST_FOREACH(wd->blocks, itb)
2511 Evas_Coord itminw, itminh;
2518 _item_block_position(itb, num);
2522 recalc = EINA_FALSE;
2523 EINA_LIST_FOREACH(itb->items, l2, it)
2525 if (it->item->updateme)
2527 itminw = it->item->minw;
2528 itminh = it->item->minh;
2530 it->item->updateme = EINA_FALSE;
2533 _elm_genlist_item_unrealize(it, EINA_FALSE);
2534 _item_realize(it, num, EINA_FALSE);
2535 position = EINA_TRUE;
2539 _item_realize(it, num, EINA_TRUE);
2540 _elm_genlist_item_unrealize(it, EINA_TRUE);
2542 if ((it->item->minw != itminw) || (it->item->minh != itminh))
2547 itb->updateme = EINA_FALSE;
2550 position = EINA_TRUE;
2551 itb->changed = EINA_TRUE;
2552 _item_block_recalc(itb, num0, EINA_FALSE);
2553 _item_block_position(itb, num0);
2558 if (wd->calc_job) ecore_job_del(wd->calc_job);
2559 wd->calc_job = ecore_job_add(_calc_job, wd);
2561 evas_event_thaw(evas_object_evas_get(wd->obj));
2562 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
2566 _pan_set(Evas_Object *obj,
2570 Pan *sd = evas_object_smart_data_get(obj);
2574 // Evas_Coord ow, oh;
2575 // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2576 // ow = sd->wd->minw - ow;
2577 // if (ow < 0) ow = 0;
2578 // oh = sd->wd->minh - oh;
2579 // if (oh < 0) oh = 0;
2580 // if (x < 0) x = 0;
2581 // if (y < 0) y = 0;
2582 // if (x > ow) x = ow;
2583 // if (y > oh) y = oh;
2584 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
2588 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2590 if ((itb->y + itb->h) > y)
2595 EINA_LIST_FOREACH(itb->items, l2, it)
2597 if ((itb->y + it->y) >= y)
2599 sd->wd->anchor_item = it;
2600 sd->wd->anchor_y = -(itb->y + it->y - y);
2607 if (!sd->wd->reorder_move_animator) evas_object_smart_changed(obj);
2611 _pan_get(Evas_Object *obj,
2615 Pan *sd = evas_object_smart_data_get(obj);
2618 if (x) *x = sd->wd->pan_x;
2619 if (y) *y = sd->wd->pan_y;
2623 _pan_max_get(Evas_Object *obj,
2627 Pan *sd = evas_object_smart_data_get(obj);
2631 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2632 ow = sd->wd->minw - ow;
2634 oh = sd->wd->minh - oh;
2641 _pan_min_get(Evas_Object *obj __UNUSED__,
2650 _pan_child_size_get(Evas_Object *obj,
2654 Pan *sd = evas_object_smart_data_get(obj);
2657 if (w) *w = sd->wd->minw;
2658 if (h) *h = sd->wd->minh;
2662 _pan_add(Evas_Object *obj)
2665 Evas_Object_Smart_Clipped_Data *cd;
2668 cd = evas_object_smart_data_get(obj);
2671 sd->__clipped_data = *cd;
2673 evas_object_smart_data_set(obj, sd);
2677 _pan_del(Evas_Object *obj)
2679 Pan *sd = evas_object_smart_data_get(obj);
2684 ecore_job_del(sd->resize_job);
2685 sd->resize_job = NULL;
2691 _pan_resize_job(void *data)
2695 _sizing_eval(sd->wd->obj);
2696 sd->resize_job = NULL;
2700 _pan_resize(Evas_Object *obj,
2704 Pan *sd = evas_object_smart_data_get(obj);
2708 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
2709 if ((ow == w) && (oh == h)) return;
2710 if ((sd->wd->height_for_width) && (ow != w))
2713 if (sd->resize_job) ecore_job_del(sd->resize_job);
2714 sd->resize_job = ecore_job_add(_pan_resize_job, sd);
2716 sd->wd->pan_resized = EINA_TRUE;
2717 evas_object_smart_changed(obj);
2718 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2719 sd->wd->calc_job = NULL;
2721 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2722 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2727 _pan_calculate(Evas_Object *obj)
2729 Pan *sd = evas_object_smart_data_get(obj);
2731 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2737 evas_event_freeze(evas_object_evas_get(obj));
2739 if (sd->wd->pan_resized)
2742 sd->wd->pan_resized = EINA_FALSE;
2745 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2746 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2747 EINA_LIST_FOREACH(sd->wd->group_items, l, git)
2749 git->item->want_realize = EINA_FALSE;
2751 EINA_INLIST_FOREACH(sd->wd->blocks, itb)
2753 itb->w = sd->wd->minw;
2754 if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x + ox,
2755 itb->y - sd->wd->pan_y + oy,
2757 cvx, cvy, cvw, cvh))
2759 if ((!itb->realized) || (itb->changed))
2760 _item_block_realize(itb);
2761 _item_block_position(itb, in);
2765 if (itb->realized) _item_block_unrealize(itb);
2769 if ((!sd->wd->reorder_it) || (sd->wd->reorder_pan_move))
2770 _group_items_recalc(sd->wd);
2771 if ((sd->wd->reorder_mode) && (sd->wd->reorder_it))
2773 if (sd->wd->pan_y != sd->wd->reorder_old_pan_y)
2774 sd->wd->reorder_pan_move = EINA_TRUE;
2775 else sd->wd->reorder_pan_move = EINA_FALSE;
2776 evas_object_raise(sd->wd->VIEW(reorder_it));
2777 sd->wd->reorder_old_pan_y = sd->wd->pan_y;
2778 sd->wd->start_time = ecore_loop_time_get();
2780 _item_auto_scroll(sd->wd);
2781 evas_event_thaw(evas_object_evas_get(obj));
2782 evas_event_thaw_eval(evas_object_evas_get(obj));
2786 _pan_move(Evas_Object *obj,
2787 Evas_Coord x __UNUSED__,
2788 Evas_Coord y __UNUSED__)
2790 Pan *sd = evas_object_smart_data_get(obj);
2793 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
2794 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
2798 _hold_on(void *data __UNUSED__,
2800 void *event_info __UNUSED__)
2802 Widget_Data *wd = elm_widget_data_get(obj);
2804 elm_smart_scroller_hold_set(wd->scr, 1);
2808 _hold_off(void *data __UNUSED__,
2810 void *event_info __UNUSED__)
2812 Widget_Data *wd = elm_widget_data_get(obj);
2814 elm_smart_scroller_hold_set(wd->scr, 0);
2818 _freeze_on(void *data __UNUSED__,
2820 void *event_info __UNUSED__)
2822 Widget_Data *wd = elm_widget_data_get(obj);
2824 elm_smart_scroller_freeze_set(wd->scr, 1);
2828 _freeze_off(void *data __UNUSED__,
2830 void *event_info __UNUSED__)
2832 Widget_Data *wd = elm_widget_data_get(obj);
2834 elm_smart_scroller_freeze_set(wd->scr, 0);
2838 _scr_anim_start(void *data,
2839 Evas_Object *obj __UNUSED__,
2840 void *event_info __UNUSED__)
2842 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_START, NULL);
2846 _scr_anim_stop(void *data,
2847 Evas_Object *obj __UNUSED__,
2848 void *event_info __UNUSED__)
2850 evas_object_smart_callback_call(data, SIG_SCROLL_ANIM_STOP, NULL);
2854 _scr_drag_start(void *data,
2855 Evas_Object *obj __UNUSED__,
2856 void *event_info __UNUSED__)
2858 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
2862 _scr_drag_stop(void *data,
2863 Evas_Object *obj __UNUSED__,
2864 void *event_info __UNUSED__)
2866 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
2870 _edge_left(void *data,
2871 Evas_Object *scr __UNUSED__,
2872 void *event_info __UNUSED__)
2874 Evas_Object *obj = data;
2875 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
2879 _edge_right(void *data,
2880 Evas_Object *scr __UNUSED__,
2881 void *event_info __UNUSED__)
2883 Evas_Object *obj = data;
2884 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
2888 _edge_top(void *data,
2889 Evas_Object *scr __UNUSED__,
2890 void *event_info __UNUSED__)
2892 Evas_Object *obj = data;
2893 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
2897 _edge_bottom(void *data,
2898 Evas_Object *scr __UNUSED__,
2899 void *event_info __UNUSED__)
2901 Evas_Object *obj = data;
2902 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
2906 _mode_item_realize(Elm_Gen_Item *it)
2910 if ((it->item->mode_view) || (it->delete_me)) return;
2912 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2913 it->item->mode_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
2914 edje_object_scale_set(it->item->mode_view,
2915 elm_widget_scale_get(WIDGET(it)) *
2916 _elm_config->scale);
2917 evas_object_smart_member_add(it->item->mode_view, it->wd->pan_smart);
2918 elm_widget_sub_object_add(WIDGET(it), it->item->mode_view);
2920 strncpy(buf, "item", sizeof(buf));
2921 if (it->wd->compress)
2922 strncat(buf, "_compress", sizeof(buf) - strlen(buf));
2924 if (it->item->order_num_in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
2925 strncat(buf, "/", sizeof(buf) - strlen(buf));
2926 strncat(buf, it->wd->mode_item_style, sizeof(buf) - strlen(buf));
2928 _elm_theme_object_set(WIDGET(it), it->item->mode_view, "genlist", buf,
2929 elm_widget_style_get(WIDGET(it)));
2930 edje_object_mirrored_set(it->item->mode_view,
2931 elm_widget_mirrored_get(WIDGET(it)));
2933 /* signal callback add */
2934 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_DOWN,
2936 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_UP,
2938 evas_object_event_callback_add(it->item->mode_view, EVAS_CALLBACK_MOUSE_MOVE,
2941 /* label_get, content_get, state_get */
2942 /* FIXME: If you see that assert, please notify us and we
2943 will clean our mess */
2944 assert(eina_list_count(it->item->mode_content_objs) == 0);
2946 _item_label_realize(it, it->item->mode_view, &it->item->mode_labels, NULL);
2947 it->item->mode_content_objs =
2948 _item_content_realize(it, it->item->mode_view,
2949 &it->item->mode_contents, NULL);
2950 _item_state_realize(it, it->item->mode_view, &it->item->mode_states, NULL);
2952 edje_object_part_swallow(it->item->mode_view,
2953 edje_object_data_get(it->item->mode_view, "mode_part"),
2956 it->want_unrealize = EINA_FALSE;
2957 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2958 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2962 _mode_item_unrealize(Elm_Gen_Item *it)
2964 Widget_Data *wd = it->wd;
2965 Evas_Object *content;
2966 if (!it->item->mode_view) return;
2968 evas_event_freeze(evas_object_evas_get(it->wd->obj));
2969 elm_widget_stringlist_free(it->item->mode_labels);
2970 it->item->mode_labels = NULL;
2971 elm_widget_stringlist_free(it->item->mode_contents);
2972 it->item->mode_contents = NULL;
2973 elm_widget_stringlist_free(it->item->mode_states);
2975 EINA_LIST_FREE(it->item->mode_content_objs, content)
2976 evas_object_del(content);
2978 edje_object_part_unswallow(it->item->mode_view, VIEW(it));
2979 evas_object_smart_member_add(VIEW(it), wd->pan_smart);
2980 evas_object_del(it->item->mode_view);
2981 it->item->mode_view = NULL;
2983 if (wd->mode_item == it)
2984 wd->mode_item = NULL;
2985 evas_event_thaw(evas_object_evas_get(it->wd->obj));
2986 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
2990 _item_mode_set(Elm_Gen_Item *it)
2993 Widget_Data *wd = it->wd;
2998 it->item->nocache = EINA_TRUE;
3000 if (wd->scr_hold_timer)
3002 ecore_timer_del(wd->scr_hold_timer);
3003 wd->scr_hold_timer = NULL;
3005 elm_smart_scroller_hold_set(wd->scr, EINA_TRUE);
3006 wd->scr_hold_timer = ecore_timer_add(0.1, _scr_hold_timer_cb, wd);
3008 evas_event_freeze(evas_object_evas_get(it->wd->obj));
3009 _mode_item_realize(it);
3010 if (it->item->group_item)
3011 evas_object_raise(it->item->VIEW(group_item));
3012 _item_position(it, it->item->mode_view, it->item->scrl_x, it->item->scrl_y);
3013 evas_event_thaw(evas_object_evas_get(it->wd->obj));
3014 evas_event_thaw_eval(evas_object_evas_get(it->wd->obj));
3016 snprintf(buf, sizeof(buf), "elm,state,%s,active", wd->mode_type);
3017 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3021 _item_mode_unset(Widget_Data *wd)
3024 if (!wd->mode_item) return;
3025 char buf[1024], buf2[1024];
3029 it->item->nocache = EINA_TRUE;
3031 snprintf(buf, sizeof(buf), "elm,state,%s,passive", wd->mode_type);
3032 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished", wd->mode_type);
3034 edje_object_signal_emit(it->item->mode_view, buf, "elm");
3035 edje_object_signal_callback_add(it->item->mode_view, buf2, "elm", _mode_finished_signal_cb, it);
3037 wd->mode_item = NULL;
3041 _item_auto_scroll(Widget_Data *wd)
3046 Evas_Coord ox, oy, ow, oh;
3048 if ((wd->expanded_item) && (wd->auto_scroll_enabled))
3050 evas_object_geometry_get(wd->obj, &ox, &oy, &ow, &oh);
3051 if (wd->expanded_item->item->scrl_y > (oh + oy) / 2)
3053 EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it)
3054 elm_genlist_item_bring_in(it);
3056 wd->auto_scroll_enabled = EINA_FALSE;
3061 elm_genlist_add(Evas_Object *parent)
3066 Evas_Coord minw, minh;
3067 static Evas_Smart *smart = NULL;
3071 static Evas_Smart_Class sc;
3073 evas_object_smart_clipped_smart_set(&_pan_sc);
3075 sc.name = "elm_genlist_pan";
3076 sc.version = EVAS_SMART_CLASS_VERSION;
3079 sc.resize = _pan_resize;
3080 sc.move = _pan_move;
3081 sc.calculate = _pan_calculate;
3082 if (!(smart = evas_smart_class_new(&sc))) return NULL;
3085 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
3087 ELM_SET_WIDTYPE(widtype, "genlist");
3089 elm_widget_type_set(obj, "genlist");
3090 elm_widget_sub_object_add(parent, obj);
3091 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
3092 elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
3093 elm_widget_data_set(obj, wd);
3094 elm_widget_del_hook_set(obj, _del_hook);
3095 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
3096 elm_widget_theme_hook_set(obj, _theme_hook);
3097 elm_widget_can_focus_set(obj, EINA_TRUE);
3098 elm_widget_event_hook_set(obj, _event_hook);
3099 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
3100 elm_widget_translate_hook_set(obj, _translate_hook);
3102 wd->scr = elm_smart_scroller_add(e);
3103 elm_smart_scroller_widget_set(wd->scr, obj);
3104 elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base",
3105 elm_widget_style_get(obj));
3106 elm_smart_scroller_bounce_allow_set(wd->scr, EINA_FALSE,
3107 _elm_config->thumbscroll_bounce_enable);
3108 elm_widget_resize_object_set(obj, wd->scr);
3110 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
3111 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
3112 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
3113 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
3114 evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
3115 evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
3116 evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
3117 evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
3120 wd->mode = ELM_LIST_SCROLL;
3121 wd->max_items_per_block = MAX_ITEMS_PER_BLOCK;
3122 wd->item_cache_max = wd->max_items_per_block * 2;
3123 wd->longpress_timeout = _elm_config->longpress_timeout;
3125 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
3126 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
3127 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
3128 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
3130 wd->pan_smart = evas_object_smart_add(e, smart);
3131 wd->pan = evas_object_smart_data_get(wd->pan_smart);
3134 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
3135 _pan_set, _pan_get, _pan_max_get,
3136 _pan_min_get, _pan_child_size_get);
3138 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
3140 evas_object_size_hint_min_set(obj, minw, minh);
3142 evas_object_smart_callbacks_descriptions_set(obj, _signals);
3144 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3150 _item_select(Elm_Gen_Item *it)
3152 if ((it->wd->no_select) || (it->delete_me) || (it->mode_set)) return;
3155 it->selected = EINA_TRUE;
3156 it->wd->selected = eina_list_append(it->wd->selected, it);
3158 else if (!it->wd->always_select) return;
3160 evas_object_ref(WIDGET(it));
3163 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3165 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3168 evas_object_unref(WIDGET(it));
3169 if ((it->wd->clear_me) && (!it->wd->walking))
3170 elm_genlist_clear(WIDGET(it));
3173 if ((!it->walking) && (it->delete_me))
3175 if (!it->relcount) it->del_cb(it);
3178 it->wd->last_selected_item = it;
3182 static Evas_Object *
3183 _item_content_get_hook(Elm_Gen_Item *it, const char *part)
3185 return edje_object_part_swallow_get(VIEW(it), part);
3189 _item_content_set_hook(Elm_Gen_Item *it, const char *part, Evas_Object *content)
3191 edje_object_part_swallow(VIEW(it), part, content);
3194 static Evas_Object *
3195 _item_content_unset_hook(Elm_Gen_Item *it, const char *part)
3199 obj = edje_object_part_swallow_get(VIEW(it), part);
3200 if (!obj) return NULL;
3201 edje_object_part_unswallow(VIEW(it), obj);
3206 _item_label_hook(Elm_Gen_Item *it, const char *part)
3208 if (!it->itc->func.label_get) return NULL;
3209 return edje_object_part_text_get(VIEW(it), part);
3213 _elm_genlist_item_new(Widget_Data *wd,
3214 const Elm_Gen_Item_Class *itc,
3216 Elm_Gen_Item *parent,
3218 const void *func_data)
3222 it = elm_widget_item_new(wd->obj, Elm_Gen_Item);
3223 if (!it) return NULL;
3226 it->base.data = data;
3227 it->parent = parent;
3228 it->func.func = func;
3229 it->func.data = func_data;
3230 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3231 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
3232 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
3234 it->sel_cb = (Ecore_Cb)_item_select;
3236 elm_widget_item_text_get_hook_set(it, _item_label_hook);
3240 static Elm_Gen_Item *
3241 _item_new(Widget_Data *wd,
3242 const Elm_Genlist_Item_Class *itc,
3244 Elm_Gen_Item *parent,
3245 Elm_Genlist_Item_Flags flags,
3247 const void *func_data)
3251 it = _elm_genlist_item_new(wd, itc, data, parent, func, func_data);
3252 if (!it) return NULL;
3253 it->item = ELM_NEW(Elm_Gen_Item_Type);
3254 it->item->flags = flags;
3255 if (flags & ELM_GENLIST_ITEM_GROUP) it->group++;
3256 it->item->expanded_depth = 0;
3257 elm_widget_item_del_cb_set(it, _item_del_hook);
3258 ELM_GEN_ITEM_SETUP(it);
3261 if (it->parent->group)
3262 it->item->group_item = parent;
3263 else if (it->parent->item->group_item)
3264 it->item->group_item = it->parent->item->group_item;
3270 _item_block_add(Widget_Data *wd,
3273 Item_Block *itb = NULL;
3280 itb = calloc(1, sizeof(Item_Block));
3283 if (!it->item->rel->item->block)
3286 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3287 itb->items = eina_list_append(itb->items, it);
3291 if (it->item->before)
3293 wd->blocks = eina_inlist_prepend_relative
3294 (wd->blocks, EINA_INLIST_GET(itb),
3295 EINA_INLIST_GET(it->item->rel->item->block));
3297 eina_list_prepend_relative(itb->items, it, it->item->rel);
3301 wd->blocks = eina_inlist_append_relative
3302 (wd->blocks, EINA_INLIST_GET(itb),
3303 EINA_INLIST_GET(it->item->rel->item->block));
3305 eina_list_append_relative(itb->items, it, it->item->rel);
3311 if (it->item->before)
3315 itb = (Item_Block *)(wd->blocks);
3316 if (itb->count >= wd->max_items_per_block)
3318 itb = calloc(1, sizeof(Item_Block));
3322 eina_inlist_prepend(wd->blocks,
3323 EINA_INLIST_GET(itb));
3328 itb = calloc(1, sizeof(Item_Block));
3332 eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
3334 itb->items = eina_list_prepend(itb->items, it);
3340 itb = (Item_Block *)(wd->blocks->last);
3341 if (itb->count >= wd->max_items_per_block)
3343 itb = calloc(1, sizeof(Item_Block));
3347 eina_inlist_append(wd->blocks,
3348 EINA_INLIST_GET(itb));
3353 itb = calloc(1, sizeof(Item_Block));
3357 eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
3359 itb->items = eina_list_append(itb->items, it);
3365 itb = it->item->rel->item->block;
3366 if (!itb) goto newblock;
3367 if (it->item->before)
3368 itb->items = eina_list_prepend_relative(itb->items, it, it->item->rel);
3370 itb->items = eina_list_append_relative(itb->items, it, it->item->rel);
3373 itb->changed = EINA_TRUE;
3374 it->item->block = itb;
3375 if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
3376 itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
3379 it->item->rel->relcount--;
3380 if ((it->item->rel->delete_me) && (!it->item->rel->relcount))
3381 _item_del(it->item->rel);
3382 it->item->rel = NULL;
3384 if (itb->count > itb->wd->max_items_per_block)
3390 newc = itb->count / 2;
3391 itb2 = calloc(1, sizeof(Item_Block));
3395 eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
3396 EINA_INLIST_GET(itb));
3397 itb2->changed = EINA_TRUE;
3398 while ((itb->count > newc) && (itb->items))
3402 l = eina_list_last(itb->items);
3404 itb->items = eina_list_remove_list(itb->items, l);
3407 itb2->items = eina_list_prepend(itb2->items, it2);
3408 it2->item->block = itb2;
3415 _queue_process(Widget_Data *wd)
3418 Eina_Bool showme = EINA_FALSE;
3421 t0 = ecore_time_get();
3422 //evas_event_freeze(evas_object_evas_get(wd->obj));
3423 for (n = 0; (wd->queue) && (n < 128); n++)
3427 it = wd->queue->data;
3428 wd->queue = eina_list_remove_list(wd->queue, wd->queue);
3429 it->item->queued = EINA_FALSE;
3430 _item_block_add(wd, it);
3432 _item_block_realize(it->item->block);
3433 t = ecore_time_get();
3434 if (it->item->block->changed)
3436 showme = _item_block_recalc(it->item->block, it->item->block->num, EINA_TRUE);
3437 it->item->block->changed = 0;
3439 if (showme) it->item->block->showme = EINA_TRUE;
3440 if (eina_inlist_count(wd->blocks) > 1)
3442 if ((t - t0) > (ecore_animator_frametime_get())) break;
3445 //evas_event_thaw(evas_object_evas_get(wd->obj));
3446 //evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3451 _idle_process(void *data, Eina_Bool *wakeup)
3453 Widget_Data *wd = data;
3456 //static double q_start = 0.0;
3457 //if (q_start == 0.0) q_start = ecore_time_get();
3459 if (_queue_process(wd) > 0) *wakeup = EINA_TRUE;
3463 //printf("PROCESS TIME: %3.3f\n", ecore_time_get() - q_start);
3465 return ECORE_CALLBACK_CANCEL;
3467 return ECORE_CALLBACK_RENEW;
3471 _item_idle_enterer(void *data)
3473 Widget_Data *wd = data;
3474 Eina_Bool wakeup = EINA_FALSE;
3475 Eina_Bool ok = _idle_process(data, &wakeup);
3480 if (wd->calc_job) ecore_job_del(wd->calc_job);
3481 wd->calc_job = ecore_job_add(_calc_job, wd);
3483 if (ok == ECORE_CALLBACK_CANCEL) wd->queue_idle_enterer = NULL;
3488 _item_queue(Widget_Data *wd,
3491 if (it->item->queued) return;
3492 it->item->queued = EINA_TRUE;
3493 wd->queue = eina_list_append(wd->queue, it);
3494 // FIXME: why does a freeze then thaw here cause some genlist
3495 // elm_genlist_item_append() to be much much slower?
3496 // evas_event_freeze(evas_object_evas_get(wd->obj));
3497 while ((wd->queue) && ((!wd->blocks) || (!wd->blocks->next)))
3499 if (wd->queue_idle_enterer)
3501 ecore_idle_enterer_del(wd->queue_idle_enterer);
3502 wd->queue_idle_enterer = NULL;
3506 // evas_event_thaw(evas_object_evas_get(wd->obj));
3507 // evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3508 if (!wd->queue_idle_enterer)
3509 wd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, wd);
3513 _elm_genlist_item_compare_data(const void *data, const void *data1)
3515 const Elm_Gen_Item *it = data;
3516 const Elm_Gen_Item *item1 = data1;
3518 return _elm_genlist_item_compare_data_cb(it->base.data, item1->base.data);
3522 _elm_genlist_item_compare(const void *data, const void *data1)
3524 const Elm_Gen_Item *it, *item1;
3525 it = ELM_GEN_ITEM_FROM_INLIST(data);
3526 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
3527 return _elm_genlist_item_compare_cb(it, item1);
3531 _elm_genlist_item_list_compare(const void *data, const void *data1)
3533 const Elm_Gen_Item *it = data;
3534 const Elm_Gen_Item *item1 = data1;
3535 return _elm_genlist_item_compare_cb(it, item1);
3539 _item_move_after(Elm_Gen_Item *it, Elm_Gen_Item *after)
3544 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
3545 _item_block_del(it);
3547 it->wd->items = eina_inlist_append_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
3548 it->item->rel = after;
3549 it->item->rel->relcount++;
3550 it->item->before = EINA_FALSE;
3551 if (after->item->group_item) it->item->group_item = after->item->group_item;
3552 _item_queue(it->wd, it);
3554 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
3558 _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before)
3561 if (!before) return;
3563 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
3564 _item_block_del(it);
3565 it->wd->items = eina_inlist_prepend_relative(it->wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
3566 it->item->rel = before;
3567 it->item->rel->relcount++;
3568 it->item->before = EINA_TRUE;
3569 if (before->item->group_item) it->item->group_item = before->item->group_item;
3570 _item_queue(it->wd, it);
3572 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, it);
3576 elm_genlist_item_append(Evas_Object *obj,
3577 const Elm_Genlist_Item_Class *itc,
3579 Elm_Gen_Item *parent,
3580 Elm_Genlist_Item_Flags flags,
3582 const void *func_data)
3584 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3585 Widget_Data *wd = elm_widget_data_get(obj);
3586 if (!wd) return NULL;
3587 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3589 if (!it) return NULL;
3593 wd->group_items = eina_list_append(wd->group_items, it);
3594 wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
3595 it->item->rel = NULL;
3599 Elm_Gen_Item *it2 = NULL;
3600 Eina_List *ll = eina_list_last(it->parent->item->items);
3601 if (ll) it2 = ll->data;
3602 it->parent->item->items = eina_list_append(it->parent->item->items, it);
3603 if (!it2) it2 = it->parent;
3605 eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3606 EINA_INLIST_GET(it2));
3607 it->item->rel = it2;
3608 it->item->rel->relcount++;
3610 it->item->before = EINA_FALSE;
3611 _item_queue(wd, it);
3616 elm_genlist_item_prepend(Evas_Object *obj,
3617 const Elm_Genlist_Item_Class *itc,
3619 Elm_Gen_Item *parent,
3620 Elm_Genlist_Item_Flags flags,
3622 const void *func_data)
3624 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3625 Widget_Data *wd = elm_widget_data_get(obj);
3626 if (!wd) return NULL;
3627 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3629 if (!it) return NULL;
3633 wd->group_items = eina_list_prepend(wd->group_items, it);
3634 wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
3635 it->item->rel = NULL;
3639 Elm_Gen_Item *it2 = NULL;
3640 Eina_List *ll = it->parent->item->items;
3641 if (ll) it2 = ll->data;
3642 it->parent->item->items = eina_list_prepend(it->parent->item->items, it);
3643 if (!it2) it2 = it->parent;
3645 eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3646 EINA_INLIST_GET(it2));
3647 it->item->rel = it2;
3648 it->item->rel->relcount++;
3650 it->item->before = EINA_TRUE;
3651 _item_queue(wd, it);
3656 elm_genlist_item_insert_after(Evas_Object *obj,
3657 const Elm_Genlist_Item_Class *itc,
3659 Elm_Gen_Item *parent,
3660 Elm_Gen_Item *after,
3661 Elm_Genlist_Item_Flags flags,
3663 const void *func_data)
3665 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3666 EINA_SAFETY_ON_NULL_RETURN_VAL(after, NULL);
3667 Widget_Data *wd = elm_widget_data_get(obj);
3668 if (!wd) return NULL;
3669 /* It makes no sense to insert after in an empty list with after != NULL, something really bad is happening in your app. */
3670 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
3672 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3674 if (!it) return NULL;
3679 wd->group_items = eina_list_append_relative(wd->group_items, it,
3684 it->parent->item->items = eina_list_append_relative(it->parent->item->items, it,
3687 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
3688 EINA_INLIST_GET(after));
3689 it->item->rel = after;
3690 it->item->rel->relcount++;
3691 it->item->before = EINA_FALSE;
3692 _item_queue(wd, it);
3697 elm_genlist_item_insert_before(Evas_Object *obj,
3698 const Elm_Genlist_Item_Class *itc,
3700 Elm_Gen_Item *parent,
3701 Elm_Gen_Item *before,
3702 Elm_Genlist_Item_Flags flags,
3704 const void *func_data)
3706 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3707 EINA_SAFETY_ON_NULL_RETURN_VAL(before, NULL);
3708 Widget_Data *wd = elm_widget_data_get(obj);
3709 if (!wd) return NULL;
3710 /* It makes no sense to insert before in an empty list with before != NULL, something really bad is happening in your app. */
3711 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->items, NULL);
3713 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3715 if (!it) return NULL;
3718 if (it->group && before->group)
3719 wd->group_items = eina_list_prepend_relative(wd->group_items, it,
3724 it->parent->item->items = eina_list_prepend_relative(it->parent->item->items, it,
3727 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
3728 EINA_INLIST_GET(before));
3729 it->item->rel = before;
3730 it->item->rel->relcount++;
3731 it->item->before = EINA_TRUE;
3732 _item_queue(wd, it);
3737 elm_genlist_item_direct_sorted_insert(Evas_Object *obj,
3738 const Elm_Genlist_Item_Class *itc,
3740 Elm_Gen_Item *parent,
3741 Elm_Genlist_Item_Flags flags,
3742 Eina_Compare_Cb comp,
3744 const void *func_data)
3746 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3747 Widget_Data *wd = elm_widget_data_get(obj);
3748 if (!wd) return NULL;
3749 Elm_Gen_Item *rel = NULL;
3750 Elm_Gen_Item *it = _item_new(wd, itc, data, parent, flags, func,
3752 if (!it) return NULL;
3754 _elm_genlist_item_compare_cb = comp;
3761 l = eina_list_search_sorted_near_list(it->parent->item->items,
3762 _elm_genlist_item_list_compare, it,
3765 rel = eina_list_data_get(l);
3769 if (cmp_result >= 0)
3771 it->parent->item->items = eina_list_prepend_relative_list(it->parent->item->items, it, l);
3772 wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
3773 it->item->before = EINA_FALSE;
3775 else if (cmp_result < 0)
3777 it->parent->item->items = eina_list_append_relative_list(it->parent->item->items, it, l);
3778 wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
3779 it->item->before = EINA_TRUE;
3786 wd->state = eina_inlist_sorted_state_new();
3787 eina_inlist_sorted_state_init(wd->state, wd->items);
3791 wd->group_items = eina_list_append(wd->group_items, it);
3793 wd->items = eina_inlist_sorted_state_insert(wd->items, EINA_INLIST_GET(it),
3794 _elm_genlist_item_compare, wd->state);
3796 if (EINA_INLIST_GET(it)->next)
3798 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3799 it->item->before = EINA_TRUE;
3801 else if (EINA_INLIST_GET(it)->prev)
3803 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3804 it->item->before = EINA_FALSE;
3810 it->item->rel = rel;
3811 it->item->rel->relcount++;
3814 _item_queue(wd, it);
3820 elm_genlist_item_sorted_insert(Evas_Object *obj,
3821 const Elm_Genlist_Item_Class *itc,
3823 Elm_Gen_Item *parent,
3824 Elm_Genlist_Item_Flags flags,
3825 Eina_Compare_Cb comp,
3827 const void *func_data)
3829 _elm_genlist_item_compare_data_cb = comp;
3831 return elm_genlist_item_direct_sorted_insert(obj, itc, data, parent, flags,
3832 _elm_genlist_item_compare_data, func, func_data);
3836 elm_genlist_clear(Evas_Object *obj)
3838 ELM_CHECK_WIDTYPE(obj, widtype);
3839 Widget_Data *wd = elm_widget_data_get(obj);
3844 eina_inlist_sorted_state_free(wd->state);
3848 if (wd->walking > 0)
3852 EINA_INLIST_FOREACH(wd->items, it)
3856 evas_event_freeze(evas_object_evas_get(wd->obj));
3859 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
3865 ecore_job_del(wd->calc_job);
3866 wd->calc_job = NULL;
3868 if (wd->selected) wd->selected = eina_list_free(wd->selected);
3869 if (wd->clear_cb) wd->clear_cb(wd);
3877 evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
3878 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
3880 if (wd->sizing_cb) wd->sizing_cb(wd->obj);
3881 elm_smart_scroller_child_region_show(wd->scr, 0, 0, 0, 0);
3882 evas_event_thaw(evas_object_evas_get(wd->obj));
3883 evas_event_thaw_eval(evas_object_evas_get(wd->obj));
3887 elm_genlist_multi_select_set(Evas_Object *obj,
3890 ELM_CHECK_WIDTYPE(obj, widtype);
3891 Widget_Data *wd = elm_widget_data_get(obj);
3897 elm_genlist_multi_select_get(const Evas_Object *obj)
3899 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
3900 Widget_Data *wd = elm_widget_data_get(obj);
3901 if (!wd) return EINA_FALSE;
3906 elm_genlist_selected_item_get(const Evas_Object *obj)
3908 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3909 Widget_Data *wd = elm_widget_data_get(obj);
3910 if (!wd) return NULL;
3911 if (wd->selected) return wd->selected->data;
3915 EAPI const Eina_List *
3916 elm_genlist_selected_items_get(const Evas_Object *obj)
3918 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3919 Widget_Data *wd = elm_widget_data_get(obj);
3920 if (!wd) return NULL;
3921 return wd->selected;
3925 elm_genlist_realized_items_get(const Evas_Object *obj)
3927 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3928 Widget_Data *wd = elm_widget_data_get(obj);
3929 Eina_List *list = NULL;
3931 Eina_Bool done = EINA_FALSE;
3932 if (!wd) return NULL;
3933 EINA_INLIST_FOREACH(wd->blocks, itb)
3941 EINA_LIST_FOREACH(itb->items, l, it)
3943 if (it->realized) list = eina_list_append(list, it);
3955 elm_genlist_at_xy_item_get(const Evas_Object *obj,
3960 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
3961 Widget_Data *wd = elm_widget_data_get(obj);
3962 Evas_Coord ox, oy, ow, oh;
3965 if (!wd) return NULL;
3966 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
3968 EINA_INLIST_FOREACH(wd->blocks, itb)
3973 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->wd->pan_x,
3974 oy + itb->y - itb->wd->pan_y,
3975 itb->w, itb->h, x, y, 1, 1))
3977 EINA_LIST_FOREACH(itb->items, l, it)
3979 Evas_Coord itx, ity;
3981 itx = ox + itb->x + it->x - itb->wd->pan_x;
3982 ity = oy + itb->y + it->y - itb->wd->pan_y;
3983 if (ELM_RECTS_INTERSECT(itx, ity, it->item->w, it->item->h, x, y, 1, 1))
3987 if (y <= (ity + (it->item->h / 4))) *posret = -1;
3988 else if (y >= (ity + it->item->h - (it->item->h / 4)))
3994 lasty = ity + it->item->h;
3999 if (y > lasty) *posret = 1;
4006 elm_genlist_first_item_get(const Evas_Object *obj)
4008 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4009 Widget_Data *wd = elm_widget_data_get(obj);
4010 if (!wd) return NULL;
4011 if (!wd->items) return NULL;
4012 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items);
4013 while ((it) && (it->delete_me))
4014 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4019 elm_genlist_last_item_get(const Evas_Object *obj)
4021 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4022 Widget_Data *wd = elm_widget_data_get(obj);
4023 if (!wd) return NULL;
4024 if (!wd->items) return NULL;
4025 Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(wd->items->last);
4026 while ((it) && (it->delete_me))
4027 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4032 elm_genlist_item_next_get(const Elm_Gen_Item *it)
4034 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4037 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4038 if ((it) && (!it->delete_me)) break;
4040 return (Elm_Gen_Item *)it;
4044 elm_genlist_item_prev_get(const Elm_Gen_Item *it)
4046 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4049 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4050 if ((it) && (!it->delete_me)) break;
4052 return (Elm_Gen_Item *)it;
4056 elm_genlist_item_genlist_get(const Elm_Gen_Item *it)
4058 return _elm_genlist_item_widget_get(it);
4062 elm_genlist_item_parent_get(const Elm_Gen_Item *it)
4064 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4069 elm_genlist_item_subitems_clear(Elm_Gen_Item *it)
4071 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4072 Eina_List *tl = NULL, *l;
4075 EINA_LIST_FOREACH(it->item->items, l, it2)
4076 tl = eina_list_append(tl, it2);
4077 EINA_LIST_FREE(tl, it2)
4078 elm_genlist_item_del(it2);
4082 elm_genlist_item_selected_set(Elm_Gen_Item *it,
4085 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4086 Widget_Data *wd = it->wd;
4088 if ((it->delete_me) || (it->disabled)) return;
4089 selected = !!selected;
4090 if (it->selected == selected) return;
4096 while (wd->selected)
4098 if (it->unhighlight_cb) it->unhighlight_cb(wd->selected->data);
4099 it->unsel_cb(wd->selected->data);
4102 it->highlight_cb(it);
4106 if (it->unhighlight_cb) it->unhighlight_cb(it);
4111 elm_genlist_item_selected_get(const Elm_Gen_Item *it)
4113 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4114 return it->selected;
4118 elm_genlist_item_expanded_set(Elm_Gen_Item *it,
4121 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4122 if (it->item->expanded == expanded) return;
4123 it->item->expanded = expanded;
4124 it->wd->expanded_item = it;
4125 if (it->item->expanded)
4128 edje_object_signal_emit(VIEW(it), "elm,state,expanded", "elm");
4129 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, it);
4130 it->wd->auto_scroll_enabled = EINA_TRUE;
4135 edje_object_signal_emit(VIEW(it), "elm,state,contracted", "elm");
4136 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, it);
4137 it->wd->auto_scroll_enabled = EINA_FALSE;
4142 elm_genlist_item_expanded_get(const Elm_Gen_Item *it)
4144 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4145 return it->item->expanded;
4149 elm_genlist_item_expanded_depth_get(const Elm_Gen_Item *it)
4151 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, 0);
4152 return it->item->expanded_depth;
4156 elm_genlist_item_disabled_set(Elm_Gen_Item *it,
4159 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4162 if (it->disabled == disabled) return;
4163 if (it->delete_me) return;
4164 it->disabled = !!disabled;
4166 elm_genlist_item_selected_set(it, EINA_FALSE);
4170 edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
4172 edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
4173 EINA_LIST_FOREACH(it->content_objs, l, obj)
4174 elm_widget_disabled_set(obj, disabled);
4179 elm_genlist_item_disabled_get(const Elm_Gen_Item *it)
4181 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4182 if (it->delete_me) return EINA_FALSE;
4183 return it->disabled;
4187 elm_genlist_item_display_only_set(Elm_Gen_Item *it,
4188 Eina_Bool display_only)
4190 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4191 if (it->display_only == display_only) return;
4192 if (it->delete_me) return;
4193 it->display_only = display_only;
4194 it->item->mincalcd = EINA_FALSE;
4195 it->item->updateme = EINA_TRUE;
4196 if (it->item->block) it->item->block->updateme = EINA_TRUE;
4197 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4198 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4202 elm_genlist_item_display_only_get(const Elm_Gen_Item *it)
4204 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4205 if (it->delete_me) return EINA_FALSE;
4206 return it->display_only;
4210 elm_genlist_item_show(Elm_Gen_Item *it)
4212 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4213 Evas_Coord gith = 0;
4214 if (it->delete_me) return;
4215 if ((it->item->queued) || (!it->item->mincalcd))
4217 it->wd->show_item = it;
4218 it->wd->bring_in = EINA_TRUE;
4219 it->item->showme = EINA_TRUE;
4222 if (it->wd->show_item)
4224 it->wd->show_item->item->showme = EINA_FALSE;
4225 it->wd->show_item = NULL;
4227 if ((it->item->group_item) && (it->wd->pan_y > (it->y + it->item->block->y)))
4228 gith = it->item->group_item->item->h;
4229 elm_smart_scroller_child_region_show(it->wd->scr,
4230 it->x + it->item->block->x,
4231 it->y + it->item->block->y - gith,
4232 it->item->block->w, it->item->h);
4236 elm_genlist_item_promote(Elm_Gen_Item *it)
4238 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4239 if (it->delete_me) return;
4240 _item_move_before(it, elm_genlist_first_item_get(WIDGET(it)));
4244 elm_genlist_item_demote(Elm_Gen_Item *it)
4246 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4247 if (it->delete_me) return;
4248 _item_move_after(it, elm_genlist_last_item_get(WIDGET(it)));
4252 elm_genlist_item_bring_in(Elm_Gen_Item *it)
4254 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4255 Evas_Coord gith = 0;
4256 if (it->delete_me) return;
4257 if ((it->item->queued) || (!it->item->mincalcd))
4259 it->wd->show_item = it;
4260 it->wd->bring_in = EINA_TRUE;
4261 it->item->showme = EINA_TRUE;
4264 if (it->wd->show_item)
4266 it->wd->show_item->item->showme = EINA_FALSE;
4267 it->wd->show_item = NULL;
4269 if ((it->item->group_item) && (it->wd->pan_y > (it->y + it->item->block->y)))
4270 gith = it->item->group_item->item->h;
4271 elm_smart_scroller_region_bring_in(it->wd->scr,
4272 it->x + it->item->block->x,
4273 it->y + it->item->block->y - gith,
4274 it->item->block->w, it->item->h);
4278 elm_genlist_item_top_show(Elm_Gen_Item *it)
4280 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4282 Evas_Coord gith = 0;
4284 if (it->delete_me) return;
4285 if ((it->item->queued) || (!it->item->mincalcd))
4287 it->wd->show_item = it;
4288 it->wd->bring_in = EINA_TRUE;
4289 it->item->showme = EINA_TRUE;
4292 if (it->wd->show_item)
4294 it->wd->show_item->item->showme = EINA_FALSE;
4295 it->wd->show_item = NULL;
4297 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4298 if (it->item->group_item) gith = it->item->group_item->item->h;
4299 elm_smart_scroller_child_region_show(it->wd->scr,
4300 it->x + it->item->block->x,
4301 it->y + it->item->block->y - gith,
4302 it->item->block->w, oh);
4306 elm_genlist_item_top_bring_in(Elm_Gen_Item *it)
4308 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4310 Evas_Coord gith = 0;
4312 if (it->delete_me) return;
4313 if ((it->item->queued) || (!it->item->mincalcd))
4315 it->wd->show_item = it;
4316 it->wd->bring_in = EINA_TRUE;
4317 it->item->showme = EINA_TRUE;
4320 if (it->wd->show_item)
4322 it->wd->show_item->item->showme = EINA_FALSE;
4323 it->wd->show_item = NULL;
4325 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4326 if (it->item->group_item) gith = it->item->group_item->item->h;
4327 elm_smart_scroller_region_bring_in(it->wd->scr,
4328 it->x + it->item->block->x,
4329 it->y + it->item->block->y - gith,
4330 it->item->block->w, oh);
4334 elm_genlist_item_middle_show(Elm_Gen_Item *it)
4336 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4339 if (it->delete_me) return;
4340 if ((it->item->queued) || (!it->item->mincalcd))
4342 it->wd->show_item = it;
4343 it->wd->bring_in = EINA_TRUE;
4344 it->item->showme = EINA_TRUE;
4347 if (it->wd->show_item)
4349 it->wd->show_item->item->showme = EINA_FALSE;
4350 it->wd->show_item = NULL;
4352 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4353 elm_smart_scroller_child_region_show(it->wd->scr,
4354 it->x + it->item->block->x,
4355 it->y + it->item->block->y - oh / 2 +
4356 it->item->h / 2, it->item->block->w, oh);
4360 elm_genlist_item_middle_bring_in(Elm_Gen_Item *it)
4362 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4365 if (it->delete_me) return;
4366 if ((it->item->queued) || (!it->item->mincalcd))
4368 it->wd->show_item = it;
4369 it->wd->bring_in = EINA_TRUE;
4370 it->item->showme = EINA_TRUE;
4373 if (it->wd->show_item)
4375 it->wd->show_item->item->showme = EINA_FALSE;
4376 it->wd->show_item = NULL;
4378 evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh);
4379 elm_smart_scroller_region_bring_in(it->wd->scr,
4380 it->x + it->item->block->x,
4381 it->y + it->item->block->y - oh / 2 + it->item->h / 2,
4382 it->item->block->w, oh);
4386 elm_genlist_item_del(Elm_Gen_Item *it)
4388 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4389 if ((it->relcount > 0) || (it->walking > 0))
4391 elm_genlist_item_subitems_clear(it);
4392 if (it->wd->show_item == it) it->wd->show_item = NULL;
4393 _elm_genlist_item_del_notserious(it);
4394 if (it->item->block)
4396 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
4397 it->item->block->changed = EINA_TRUE;
4398 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
4399 it->wd->calc_job = ecore_job_add(_calc_job, it->wd);
4407 elm_genlist_item_data_set(Elm_Gen_Item *it,
4410 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4411 elm_widget_item_data_set(it, data);
4415 elm_genlist_item_data_get(const Elm_Gen_Item *it)
4417 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4418 return elm_widget_item_data_get(it);
4422 elm_genlist_item_icons_orphan(Elm_Gen_Item *it)
4424 elm_genlist_item_contents_orphan(it);
4428 elm_genlist_item_contents_orphan(Elm_Gen_Item *it)
4430 Evas_Object *content;
4431 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4432 EINA_LIST_FREE(it->content_objs, content)
4434 elm_widget_sub_object_del(WIDGET(it), content);
4435 evas_object_smart_member_del(content);
4436 evas_object_hide(content);
4440 EAPI const Evas_Object *
4441 elm_genlist_item_object_get(const Elm_Gen_Item *it)
4443 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4448 elm_genlist_item_update(Elm_Gen_Item *it)
4450 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4451 if (!it->item->block) return;
4452 if (it->delete_me) return;
4453 it->item->mincalcd = EINA_FALSE;
4454 it->item->updateme = EINA_TRUE;
4455 it->item->block->updateme = EINA_TRUE;
4456 if (it->wd->update_job) ecore_job_del(it->wd->update_job);
4457 it->wd->update_job = ecore_job_add(_update_job, it->wd);
4461 elm_genlist_item_fields_update(Elm_Genlist_Item *it,
4463 Elm_Genlist_Item_Field_Flags itf)
4465 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4466 if (!it->item->block) return;
4467 if (it->delete_me) return;
4469 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_LABEL))
4470 _item_label_realize(it, it->base.view, &it->labels, parts);
4471 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
4473 it->content_objs = _item_content_unrealize(it, it->base.view,
4474 &it->contents, parts);
4475 it->content_objs = _item_content_realize(it, it->base.view,
4476 &it->contents, parts);
4478 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
4479 _item_state_realize(it, it->base.view, &it->states, parts);
4483 elm_genlist_item_item_class_update(Elm_Gen_Item *it,
4484 const Elm_Genlist_Item_Class *itc)
4486 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4487 if (!it->item->block) return;
4488 EINA_SAFETY_ON_NULL_RETURN(itc);
4489 if (it->delete_me) return;
4491 it->item->nocache = EINA_TRUE;
4492 elm_genlist_item_update(it);
4495 EAPI const Elm_Genlist_Item_Class *
4496 elm_genlist_item_item_class_get(const Elm_Gen_Item *it)
4498 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4499 if (it->delete_me) return NULL;
4503 static Evas_Object *
4504 _elm_genlist_item_label_create(void *data,
4505 Evas_Object *obj __UNUSED__,
4506 Evas_Object *tooltip,
4507 void *it __UNUSED__)
4509 Evas_Object *label = elm_label_add(tooltip);
4512 elm_object_style_set(label, "tooltip");
4513 elm_object_text_set(label, data);
4518 _elm_genlist_item_label_del_cb(void *data,
4519 Evas_Object *obj __UNUSED__,
4520 void *event_info __UNUSED__)
4522 eina_stringshare_del(data);
4526 elm_genlist_item_tooltip_text_set(Elm_Gen_Item *it,
4529 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4530 text = eina_stringshare_add(text);
4531 elm_genlist_item_tooltip_content_cb_set(it, _elm_genlist_item_label_create,
4533 _elm_genlist_item_label_del_cb);
4537 elm_genlist_item_tooltip_content_cb_set(Elm_Gen_Item *it,
4538 Elm_Tooltip_Item_Content_Cb func,
4540 Evas_Smart_Cb del_cb)
4542 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_GOTO(it, error);
4544 if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
4547 if (it->tooltip.del_cb)
4548 it->tooltip.del_cb((void *)it->tooltip.data,
4551 it->tooltip.content_cb = func;
4552 it->tooltip.data = data;
4553 it->tooltip.del_cb = del_cb;
4557 elm_widget_item_tooltip_content_cb_set(it,
4558 it->tooltip.content_cb,
4559 it->tooltip.data, NULL);
4560 elm_widget_item_tooltip_style_set(it, it->tooltip.style);
4561 elm_widget_item_tooltip_size_restrict_disable(it, it->tooltip.free_size);
4567 if (del_cb) del_cb((void *)data, NULL, NULL);
4571 elm_genlist_item_tooltip_unset(Elm_Gen_Item *it)
4573 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4574 if ((VIEW(it)) && (it->tooltip.content_cb))
4575 elm_widget_item_tooltip_unset(it);
4577 if (it->tooltip.del_cb)
4578 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
4579 it->tooltip.del_cb = NULL;
4580 it->tooltip.content_cb = NULL;
4581 it->tooltip.data = NULL;
4582 it->tooltip.free_size = EINA_FALSE;
4583 if (it->tooltip.style)
4584 elm_genlist_item_tooltip_style_set(it, NULL);
4588 elm_genlist_item_tooltip_style_set(Elm_Gen_Item *it,
4591 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4592 eina_stringshare_replace(&it->tooltip.style, style);
4593 if (VIEW(it)) elm_widget_item_tooltip_style_set(it, style);
4597 elm_genlist_item_tooltip_style_get(const Elm_Gen_Item *it)
4599 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4600 return it->tooltip.style;
4604 elm_genlist_item_tooltip_size_restrict_disable(Elm_Gen_Item *it, Eina_Bool disable)
4606 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4607 it->tooltip.free_size = disable;
4608 if (VIEW(it)) return elm_widget_item_tooltip_size_restrict_disable(it, disable);
4613 elm_genlist_item_tooltip_size_restrict_disabled_get(const Elm_Gen_Item *it)
4615 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4616 return it->tooltip.free_size;
4620 elm_genlist_item_cursor_set(Elm_Gen_Item *it,
4623 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4624 eina_stringshare_replace(&it->mouse_cursor, cursor);
4625 if (VIEW(it)) elm_widget_item_cursor_set(it, cursor);
4629 elm_genlist_item_cursor_get(const Elm_Gen_Item *it)
4631 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4632 return elm_widget_item_cursor_get(it);
4636 elm_genlist_item_cursor_unset(Elm_Gen_Item *it)
4638 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4639 if (!it->mouse_cursor)
4643 elm_widget_item_cursor_unset(it);
4645 eina_stringshare_del(it->mouse_cursor);
4646 it->mouse_cursor = NULL;
4650 elm_genlist_item_cursor_style_set(Elm_Gen_Item *it,
4653 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4654 elm_widget_item_cursor_style_set(it, style);
4658 elm_genlist_item_cursor_style_get(const Elm_Gen_Item *it)
4660 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
4661 return elm_widget_item_cursor_style_get(it);
4665 elm_genlist_item_cursor_engine_only_set(Elm_Gen_Item *it,
4666 Eina_Bool engine_only)
4668 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4669 elm_widget_item_cursor_engine_only_set(it, engine_only);
4673 elm_genlist_item_cursor_engine_only_get(const Elm_Gen_Item *it)
4675 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
4676 return elm_widget_item_cursor_engine_only_get(it);
4680 elm_genlist_horizontal_set(Evas_Object *obj,
4683 ELM_CHECK_WIDTYPE(obj, widtype);
4684 Widget_Data *wd = elm_widget_data_get(obj);
4686 if (wd->mode == mode) return;
4692 elm_genlist_horizontal_mode_set(Evas_Object *obj,
4695 elm_genlist_horizontal_set(obj, mode);
4699 elm_genlist_horizontal_get(const Evas_Object *obj)
4701 ELM_CHECK_WIDTYPE(obj, widtype) ELM_LIST_LAST;
4702 Widget_Data *wd = elm_widget_data_get(obj);
4703 if (!wd) return ELM_LIST_LAST;
4708 elm_genlist_horizontal_mode_get(const Evas_Object *obj)
4710 return elm_genlist_horizontal_get(obj);
4714 elm_genlist_always_select_mode_set(Evas_Object *obj,
4715 Eina_Bool always_select)
4717 ELM_CHECK_WIDTYPE(obj, widtype);
4718 Widget_Data *wd = elm_widget_data_get(obj);
4720 wd->always_select = always_select;
4724 elm_genlist_always_select_mode_get(const Evas_Object *obj)
4726 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4727 Widget_Data *wd = elm_widget_data_get(obj);
4728 if (!wd) return EINA_FALSE;
4729 return wd->always_select;
4733 elm_genlist_no_select_mode_set(Evas_Object *obj,
4734 Eina_Bool no_select)
4736 ELM_CHECK_WIDTYPE(obj, widtype);
4737 Widget_Data *wd = elm_widget_data_get(obj);
4739 wd->no_select = no_select;
4743 elm_genlist_no_select_mode_get(const Evas_Object *obj)
4745 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4746 Widget_Data *wd = elm_widget_data_get(obj);
4747 if (!wd) return EINA_FALSE;
4748 return wd->no_select;
4752 elm_genlist_compress_mode_set(Evas_Object *obj,
4755 ELM_CHECK_WIDTYPE(obj, widtype);
4756 Widget_Data *wd = elm_widget_data_get(obj);
4758 wd->compress = compress;
4759 if (!compress) elm_genlist_homogeneous_set(obj, EINA_FALSE);
4763 elm_genlist_compress_mode_get(const Evas_Object *obj)
4765 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4766 Widget_Data *wd = elm_widget_data_get(obj);
4767 if (!wd) return EINA_FALSE;
4768 return wd->compress;
4772 elm_genlist_height_for_width_mode_set(Evas_Object *obj,
4773 Eina_Bool height_for_width)
4775 ELM_CHECK_WIDTYPE(obj, widtype);
4776 Widget_Data *wd = elm_widget_data_get(obj);
4778 wd->height_for_width = !!height_for_width;
4779 if (wd->height_for_width)
4781 elm_genlist_homogeneous_set(obj, EINA_FALSE);
4782 elm_genlist_compress_mode_set(obj, EINA_TRUE);
4787 elm_genlist_height_for_width_mode_get(const Evas_Object *obj)
4789 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4790 Widget_Data *wd = elm_widget_data_get(obj);
4791 if (!wd) return EINA_FALSE;
4792 return wd->height_for_width;
4796 elm_genlist_bounce_set(Evas_Object *obj,
4800 ELM_CHECK_WIDTYPE(obj, widtype);
4801 Widget_Data *wd = elm_widget_data_get(obj);
4803 elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
4804 wd->h_bounce = h_bounce;
4805 wd->v_bounce = v_bounce;
4809 elm_genlist_bounce_get(const Evas_Object *obj,
4810 Eina_Bool *h_bounce,
4811 Eina_Bool *v_bounce)
4813 ELM_CHECK_WIDTYPE(obj, widtype);
4814 Widget_Data *wd = elm_widget_data_get(obj);
4816 if (h_bounce) *h_bounce = wd->h_bounce;
4817 if (v_bounce) *v_bounce = wd->v_bounce;
4821 elm_genlist_homogeneous_set(Evas_Object *obj,
4822 Eina_Bool homogeneous)
4824 ELM_CHECK_WIDTYPE(obj, widtype);
4825 Widget_Data *wd = elm_widget_data_get(obj);
4827 if (homogeneous) elm_genlist_compress_mode_set(obj, EINA_TRUE);
4828 wd->homogeneous = homogeneous;
4832 elm_genlist_homogeneous_get(const Evas_Object *obj)
4834 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4835 Widget_Data *wd = elm_widget_data_get(obj);
4836 if (!wd) return EINA_FALSE;
4837 return wd->homogeneous;
4841 elm_genlist_block_count_set(Evas_Object *obj,
4844 ELM_CHECK_WIDTYPE(obj, widtype);
4845 Widget_Data *wd = elm_widget_data_get(obj);
4847 wd->max_items_per_block = n;
4848 wd->item_cache_max = wd->max_items_per_block * 2;
4849 _item_cache_clean(wd);
4853 elm_genlist_block_count_get(const Evas_Object *obj)
4855 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4856 Widget_Data *wd = elm_widget_data_get(obj);
4858 return wd->max_items_per_block;
4862 elm_genlist_longpress_timeout_set(Evas_Object *obj,
4865 ELM_CHECK_WIDTYPE(obj, widtype);
4866 Widget_Data *wd = elm_widget_data_get(obj);
4868 wd->longpress_timeout = timeout;
4872 elm_genlist_longpress_timeout_get(const Evas_Object *obj)
4874 ELM_CHECK_WIDTYPE(obj, widtype) 0;
4875 Widget_Data *wd = elm_widget_data_get(obj);
4877 return wd->longpress_timeout;
4881 elm_genlist_scroller_policy_set(Evas_Object *obj,
4882 Elm_Scroller_Policy policy_h,
4883 Elm_Scroller_Policy policy_v)
4885 ELM_CHECK_WIDTYPE(obj, widtype);
4886 Widget_Data *wd = elm_widget_data_get(obj);
4887 if ((!wd) || (!wd->scr)) return;
4888 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
4889 (policy_v >= ELM_SCROLLER_POLICY_LAST))
4891 elm_smart_scroller_policy_set(wd->scr, policy_h, policy_v);
4895 elm_genlist_scroller_policy_get(const Evas_Object *obj,
4896 Elm_Scroller_Policy *policy_h,
4897 Elm_Scroller_Policy *policy_v)
4899 ELM_CHECK_WIDTYPE(obj, widtype);
4900 Widget_Data *wd = elm_widget_data_get(obj);
4901 Elm_Smart_Scroller_Policy s_policy_h, s_policy_v;
4902 if ((!wd) || (!wd->scr)) return;
4903 elm_smart_scroller_policy_get(wd->scr, &s_policy_h, &s_policy_v);
4904 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
4905 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
4909 elm_genlist_realized_items_update(Evas_Object *obj)
4911 ELM_CHECK_WIDTYPE(obj, widtype);
4913 Eina_List *list, *l;
4916 list = elm_genlist_realized_items_get(obj);
4917 EINA_LIST_FOREACH(list, l, it)
4918 elm_genlist_item_update(it);
4922 elm_genlist_item_mode_set(Elm_Gen_Item *it,
4923 const char *mode_type,
4926 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
4927 Widget_Data *wd = it->wd;
4932 if (!mode_type) return;
4933 if ((it->delete_me) || (it->disabled)) return;
4935 if ((wd->mode_item == it) &&
4936 (!strcmp(mode_type, wd->mode_type)) &&
4939 if (!wd->mode_item_style) return;
4940 it->mode_set = mode_set;
4944 EINA_LIST_FOREACH(wd->selected, l, it2)
4946 elm_genlist_item_selected_set(it2, EINA_FALSE);
4950 it2 = elm_genlist_selected_item_get(wd->obj);
4951 if ((it2) && (it2->realized))
4952 elm_genlist_item_selected_set(it2, EINA_FALSE);
4955 if (((wd->mode_type) && (strcmp(mode_type, wd->mode_type))) ||
4957 ((it == wd->mode_item) && (!mode_set)))
4958 _item_mode_unset(wd);
4960 eina_stringshare_replace(&wd->mode_type, mode_type);
4961 if (mode_set) _item_mode_set(it);
4966 elm_genlist_mode_item_style_get(const Evas_Object *obj)
4968 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4969 Widget_Data *wd = elm_widget_data_get(obj);
4970 if (!wd) return NULL;
4971 return wd->mode_item_style;
4975 elm_genlist_mode_item_style_set(Evas_Object *obj, const char *style)
4977 ELM_CHECK_WIDTYPE(obj, widtype);
4978 Widget_Data *wd = elm_widget_data_get(obj);
4980 if ((style == wd->mode_item_style) || (style && wd->mode_item_style &&
4981 (!strcmp(style, wd->mode_item_style))))
4983 eina_stringshare_replace(&wd->mode_item_style, style);
4984 elm_genlist_realized_items_update(obj);
4988 elm_genlist_mode_get(const Evas_Object *obj)
4990 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4991 Widget_Data *wd = elm_widget_data_get(obj);
4992 if (!wd) return NULL;
4993 return wd->mode_type;
4996 EAPI const Elm_Gen_Item *
4997 elm_genlist_mode_item_get(const Evas_Object *obj)
4999 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
5000 Widget_Data *wd = elm_widget_data_get(obj);
5001 if (!wd) return NULL;
5002 return wd->mode_item;
5006 elm_genlist_reorder_mode_set(Evas_Object *obj,
5007 Eina_Bool reorder_mode)
5009 ELM_CHECK_WIDTYPE(obj, widtype);
5010 Widget_Data *wd = elm_widget_data_get(obj);
5012 wd->reorder_mode = reorder_mode;
5016 elm_genlist_reorder_mode_get(const Evas_Object *obj)
5018 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
5019 Widget_Data *wd = elm_widget_data_get(obj);
5020 if (!wd) return EINA_FALSE;
5021 return wd->reorder_mode;
5024 /* for gengrid as of now */
5026 _elm_genlist_page_relative_set(Evas_Object *obj,
5030 Evas_Coord pagesize_h;
5031 Evas_Coord pagesize_v;
5033 ELM_CHECK_WIDTYPE(obj, widtype);
5034 Widget_Data *wd = elm_widget_data_get(obj);
5037 elm_smart_scroller_paging_get(wd->scr, NULL, NULL, &pagesize_h, &pagesize_v);
5038 elm_smart_scroller_paging_set(wd->scr, h_pagerel, v_pagerel, pagesize_h,
5042 /* for gengrid as of now */
5044 _elm_genlist_page_relative_get(const Evas_Object *obj,
5048 ELM_CHECK_WIDTYPE(obj, widtype);
5049 Widget_Data *wd = elm_widget_data_get(obj);
5052 elm_smart_scroller_paging_get(wd->scr, h_pagerel, v_pagerel, NULL, NULL);
5055 /* for gengrid as of now */
5057 _elm_genlist_page_size_set(Evas_Object *obj,
5058 Evas_Coord h_pagesize,
5059 Evas_Coord v_pagesize)
5064 ELM_CHECK_WIDTYPE(obj, widtype);
5065 Widget_Data *wd = elm_widget_data_get(obj);
5067 elm_smart_scroller_paging_get(wd->scr, &pagerel_h, &pagerel_v, NULL, NULL);
5068 elm_smart_scroller_paging_set(wd->scr, pagerel_h, pagerel_v, h_pagesize,
5072 /* for gengrid as of now */
5074 _elm_genlist_current_page_get(const Evas_Object *obj,
5078 ELM_CHECK_WIDTYPE(obj, widtype);
5079 Widget_Data *wd = elm_widget_data_get(obj);
5082 elm_smart_scroller_current_page_get(wd->scr, h_pagenumber, v_pagenumber);
5085 /* for gengrid as of now */
5087 _elm_genlist_last_page_get(const Evas_Object *obj,
5091 ELM_CHECK_WIDTYPE(obj, widtype);
5092 Widget_Data *wd = elm_widget_data_get(obj);
5095 elm_smart_scroller_last_page_get(wd->scr, h_pagenumber, v_pagenumber);
5098 /* for gengrid as of now */
5100 _elm_genlist_page_show(const Evas_Object *obj,
5104 ELM_CHECK_WIDTYPE(obj, widtype);
5105 Widget_Data *wd = elm_widget_data_get(obj);
5108 elm_smart_scroller_page_show(wd->scr, h_pagenumber, v_pagenumber);
5111 /* for gengrid as of now */
5113 _elm_genlist_page_bring_in(const Evas_Object *obj,
5117 ELM_CHECK_WIDTYPE(obj, widtype);
5118 Widget_Data *wd = elm_widget_data_get(obj);
5121 elm_smart_scroller_page_bring_in(wd->scr, h_pagenumber, v_pagenumber);
5125 _elm_genlist_item_widget_get(const Elm_Gen_Item *it)
5127 ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
5132 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
5135 Evas_Object *content;
5137 if (!it->realized) return;
5138 if (it->wd->reorder_it == it) return;
5139 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
5141 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
5144 ecore_timer_del(it->long_timer);
5145 it->long_timer = NULL;
5148 elm_widget_stringlist_free(it->labels);
5150 elm_widget_stringlist_free(it->contents);
5151 it->contents = NULL;
5152 elm_widget_stringlist_free(it->states);
5155 EINA_LIST_FREE(it->content_objs, content)
5156 evas_object_del(content);
5158 it->unrealize_cb(it);
5160 it->realized = EINA_FALSE;
5161 it->want_unrealize = EINA_FALSE;
5162 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
5163 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
5167 _elm_genlist_item_del_notserious(Elm_Gen_Item *it)
5169 elm_widget_item_pre_notify_del(it);
5170 it->delete_me = EINA_TRUE;
5171 if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it);
5173 if (it->itc->func.del)
5174 it->itc->func.del((void *)it->base.data, WIDGET(it));
5178 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
5180 _elm_genlist_item_del_notserious(it);
5181 it->wd->items = eina_inlist_remove(it->wd->items, EINA_INLIST_GET(it));
5182 if (it->tooltip.del_cb)
5183 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
5184 it->wd->walking -= it->walking;
5185 if (it->long_timer) ecore_timer_del(it->long_timer);
5187 it->wd->group_items = eina_list_remove(it->wd->group_items, it);
5189 if (it->wd->calc_job) ecore_job_del(it->wd->calc_job);
5190 it->wd->calc_job = ecore_job_add(it->wd->calc_cb, it->wd);
5193 elm_widget_item_del(it);