2 # include "elementary_config.h"
7 #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
8 #define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
9 #define ELM_WIDGET_ITEM_PROTECTED
11 #include <Elementary.h>
12 #include <Elementary_Cursor.h>
15 #include "elm_widget_genlist.h"
16 #include "elm_interface_scrollable.h"
18 #define MY_PAN_CLASS ELM_GENLIST_PAN_CLASS
20 #define MY_PAN_CLASS_NAME "Elm_Genlist_Pan"
21 #define MY_PAN_CLASS_NAME_LEGACY "elm_genlist_pan"
23 #define MY_CLASS ELM_GENLIST_CLASS
25 #define MY_CLASS_NAME "Elm_Genlist"
26 #define MY_CLASS_NAME_LEGACY "elm_genlist"
28 // internally allocated
29 #define CLASS_ALLOCATED 0x3a70f11f
31 #define MAX_ITEMS_PER_BLOCK 32
32 #define REORDER_EFFECT_TIME 0.5
33 #define MULTI_DOWN_TIME 1.0
34 #define SWIPE_TIME 0.4
35 #define SCR_HOLD_TIME 0.1
37 #define ERR_ABORT(_msg) \
40 if (getenv("ELM_ERROR_ABORT")) abort(); \
43 #define ELM_PRIV_GENLIST_SIGNALS(cmd) \
44 cmd(SIG_ACTIVATED, "activated", "") \
45 cmd(SIG_CLICKED_DOUBLE, "clicked,double", "") \
46 cmd(SIG_CLICKED_RIGHT, "clicked,right", "") \
47 cmd(SIG_SELECTED, "selected", "") \
48 cmd(SIG_UNSELECTED, "unselected", "") \
49 cmd(SIG_EXPANDED, "expanded", "") \
50 cmd(SIG_CONTRACTED, "contracted", "") \
51 cmd(SIG_EXPAND_REQUEST, "expand,request", "") \
52 cmd(SIG_CONTRACT_REQUEST, "contract,request", "") \
53 cmd(SIG_REALIZED, "realized", "") \
54 cmd(SIG_UNREALIZED, "unrealized", "") \
55 cmd(SIG_DRAG_START_UP, "drag,start,up", "") \
56 cmd(SIG_DRAG_START_DOWN, "drag,start,down", "") \
57 cmd(SIG_DRAG_START_LEFT, "drag,start,left", "") \
58 cmd(SIG_DRAG_START_RIGHT, "drag,start,right", "") \
59 cmd(SIG_DRAG_STOP, "drag,stop", "") \
60 cmd(SIG_DRAG, "drag", "") \
61 cmd(SIG_LONGPRESSED, "longpressed", "") \
62 cmd(SIG_SCROLL, "scroll", "") \
63 cmd(SIG_SCROLL_ANIM_START, "scroll,anim,start", "") \
64 cmd(SIG_SCROLL_ANIM_STOP, "scroll,anim,stop", "") \
65 cmd(SIG_SCROLL_DRAG_START, "scroll,drag,start", "") \
66 cmd(SIG_SCROLL_DRAG_STOP, "scroll,drag,stop", "") \
67 cmd(SIG_EDGE_TOP, "edge,top", "") \
68 cmd(SIG_EDGE_BOTTOM, "edge,bottom", "") \
69 cmd(SIG_EDGE_LEFT, "edge,left", "") \
70 cmd(SIG_EDGE_RIGHT, "edge,right", "") \
71 cmd(SIG_VBAR_DRAG, "vbar,drag", "") \
72 cmd(SIG_VBAR_PRESS, "vbar,press", "") \
73 cmd(SIG_VBAR_UNPRESS, "vbar,unpress", "") \
74 cmd(SIG_HBAR_DRAG, "hbar,drag", "") \
75 cmd(SIG_HBAR_PRESS, "hbar,press", "") \
76 cmd(SIG_HBAR_UNPRESS, "hbar,unpress", "") \
77 cmd(SIG_MULTI_SWIPE_LEFT, "multi,swipe,left", "") \
78 cmd(SIG_MULTI_SWIPE_RIGHT, "multi,swipe,right", "") \
79 cmd(SIG_MULTI_SWIPE_UP, "multi,swipe,up", "") \
80 cmd(SIG_MULTI_SWIPE_DOWN, "multi,swipe,down", "") \
81 cmd(SIG_MULTI_PINCH_OUT, "multi,pinch,out", "") \
82 cmd(SIG_MULTI_PINCH_IN, "multi,pinch,in", "") \
83 cmd(SIG_SWIPE, "swipe", "") \
84 cmd(SIG_MOVED, "moved", "") \
85 cmd(SIG_MOVED_AFTER, "moved,after", "") \
86 cmd(SIG_MOVED_BEFORE, "moved,before", "") \
87 cmd(SIG_INDEX_UPDATE, "index,update", "") \
88 cmd(SIG_TREE_EFFECT_FINISHED , "tree,effect,finished", "") \
89 cmd(SIG_HIGHLIGHTED, "highlighted", "") \
90 cmd(SIG_UNHIGHLIGHTED, "unhighlighted", "") \
91 cmd(SIG_ITEM_FOCUSED, "item,focused", "") \
92 cmd(SIG_ITEM_UNFOCUSED, "item,unfocused", "") \
93 cmd(SIG_PRESSED, "pressed", "") \
94 cmd(SIG_RELEASED, "released", "")
96 ELM_PRIV_GENLIST_SIGNALS(ELM_PRIV_STATIC_VARIABLE_DECLARE);
98 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
99 ELM_PRIV_GENLIST_SIGNALS(ELM_PRIV_SMART_CALLBACKS_DESC)
100 {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
101 {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
102 {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
103 {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
107 #undef ELM_PRIV_GENLIST_SIGNALS
109 /* edje signals internally used */
110 static const char SIGNAL_ENABLED[] = "elm,state,enabled";
111 static const char SIGNAL_DISABLED[] = "elm,state,disabled";
112 static const char SIGNAL_SELECTED[] = "elm,state,selected";
113 static const char SIGNAL_UNSELECTED[] = "elm,state,unselected";
114 static const char SIGNAL_EXPANDED[] = "elm,state,expanded";
115 static const char SIGNAL_CONTRACTED[] = "elm,state,contracted";
116 static const char SIGNAL_FLIP_ENABLED[] = "elm,state,flip,enabled";
117 static const char SIGNAL_FLIP_DISABLED[] = "elm,state,flip,disabled";
118 static const char SIGNAL_DECORATE_ENABLED[] = "elm,state,decorate,enabled";
119 static const char SIGNAL_DECORATE_DISABLED[] = "elm,state,decorate,disabled";
120 static const char SIGNAL_DECORATE_ENABLED_EFFECT[] = "elm,state,decorate,enabled,effect";
121 static const char SIGNAL_REORDER_ENABLED[] = "elm,state,reorder,enabled";
122 static const char SIGNAL_REORDER_DISABLED[] = "elm,state,reorder,disabled";
123 static const char SIGNAL_REORDER_MODE_SET[] = "elm,state,reorder,mode_set";
124 static const char SIGNAL_REORDER_MODE_UNSET[] = "elm,state,reorder,mode_unset";
125 static const char SIGNAL_CONTRACT_FLIP[] = "elm,state,contract_flip";
126 static const char SIGNAL_SHOW[] = "elm,state,show";
127 static const char SIGNAL_HIDE[] = "elm,state,hide";
128 static const char SIGNAL_FLIP_ITEM[] = "elm,action,flip_item";
129 static const char SIGNAL_ODD[] = "elm,state,odd";
130 static const char SIGNAL_EVEN[] = "elm,state,even";
131 static const char SIGNAL_FOCUSED[] = "elm,state,focused";
132 static const char SIGNAL_UNFOCUSED[] = "elm,state,unfocused";
133 static const char SIGNAL_LIST_SINGLE[] = "elm,state,list,single";
134 static const char SIGNAL_LIST_FIRST[] = "elm,state,list,first";
135 static const char SIGNAL_LIST_LAST[] = "elm,state,list,last";
136 static const char SIGNAL_LIST_MIDDLE[] = "elm,state,list,middle";
137 static const char SIGNAL_GROUP_SINGLE[] = "elm,state,group,single";
138 static const char SIGNAL_GROUP_FIRST[] = "elm,state,group,first";
139 static const char SIGNAL_GROUP_LAST[] = "elm,state,group,last";
140 static const char SIGNAL_GROUP_MIDDLE[] = "elm,state,group,middle";
142 static void _item_unrealize(Elm_Gen_Item *it);
143 static Eina_Bool _item_select(Elm_Gen_Item *it);
144 static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
145 static Eina_Bool _key_action_select(Evas_Object *obj, const char *params);
146 static Eina_Bool _key_action_escape(Evas_Object *obj, const char *params);
147 static void _calc_job(void *data);
148 static Eina_Bool _item_block_recalc(Item_Block *itb, int in, Eina_Bool qadd);
149 static void _item_mouse_callbacks_add(Elm_Gen_Item *it, Evas_Object *view);
150 static void _item_mouse_callbacks_del(Elm_Gen_Item *it, Evas_Object *view);
151 static void _access_activate_cb(void *data EINA_UNUSED,
152 Evas_Object *part_obj EINA_UNUSED,
153 Elm_Object_Item *item);
154 static void _decorate_item_set(Elm_Gen_Item *);
155 static void _internal_elm_genlist_clear(Evas_Object *obj);
157 static const Elm_Action key_actions[] = {
158 {"move", _key_action_move},
159 {"select", _key_action_select},
160 {"escape", _key_action_escape},
166 _is_no_select(Elm_Gen_Item *it)
168 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
170 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
171 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
172 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
173 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
179 _elm_genlist_pan_elm_pan_pos_set(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord x, Evas_Coord y)
183 Elm_Genlist_Data *sd = psd->wsd;
185 if ((x == sd->pan_x) && (y == sd->pan_y)) return;
189 EINA_INLIST_FOREACH(sd->blocks, itb)
191 if ((itb->y + itb->h) > y)
196 EINA_LIST_FOREACH(itb->items, l2, it)
198 if ((itb->y + it->y) >= y)
200 sd->anchor_item = it;
201 sd->anchor_y = -(itb->y + it->y - y);
208 if (!sd->reorder_move_animator) evas_object_smart_changed(obj);
212 _elm_genlist_pan_elm_pan_pos_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y)
214 if (x) *x = psd->wsd->pan_x;
215 if (y) *y = psd->wsd->pan_y;
219 _elm_genlist_pan_elm_pan_pos_max_get(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y)
223 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
224 ow = psd->wsd->minw - ow;
226 oh = psd->wsd->minh - oh;
233 _elm_genlist_pan_elm_pan_pos_min_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *_pd EINA_UNUSED, Evas_Coord *x, Evas_Coord *y)
240 _elm_genlist_pan_elm_pan_content_size_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *w, Evas_Coord *h)
242 if (w) *w = psd->wsd->minw;
243 if (h) *h = psd->wsd->minh;
247 _elm_genlist_pan_evas_object_smart_del(Eo *obj, Elm_Genlist_Pan_Data *psd)
249 ecore_job_del(psd->resize_job);
251 eo_do_super(obj, MY_PAN_CLASS, evas_obj_smart_del());
255 _elm_genlist_pan_evas_object_smart_move(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord _gen_param2 EINA_UNUSED, Evas_Coord _gen_param3 EINA_UNUSED)
257 psd->wsd->pan_changed = EINA_TRUE;
258 evas_object_smart_changed(obj);
259 ELM_SAFE_FREE(psd->wsd->calc_job, ecore_job_del);
263 _elm_genlist_pan_smart_resize_job(void *data)
265 ELM_GENLIST_PAN_DATA_GET(data, psd);
267 elm_layout_sizing_eval(psd->wobj);
268 psd->resize_job = NULL;
272 _elm_genlist_pan_evas_object_smart_resize(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord w, Evas_Coord h)
276 Elm_Genlist_Data *sd = psd->wsd;
278 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
279 if ((ow == w) && (oh == h)) return;
280 if ((sd->mode == ELM_LIST_COMPRESS) && (ow != w))
283 ecore_job_del(psd->resize_job);
285 ecore_job_add(_elm_genlist_pan_smart_resize_job, obj);
287 sd->pan_changed = EINA_TRUE;
288 evas_object_smart_changed(obj);
289 ecore_job_del(sd->calc_job);
290 // if the width changed we may have to resize content if scrollbar went
291 // away or appeared to queue a job to deal with it. it should settle in
292 // the end to a steady-state
294 sd->calc_job = ecore_job_add(_calc_job, psd->wobj);
300 _item_text_realize(Elm_Gen_Item *it,
309 if (!it->itc->func.text_get) return;
312 *source = elm_widget_stringlist_get
313 (edje_object_data_get(target, "texts"));
314 EINA_LIST_FOREACH(*source, l, key)
316 if (parts && fnmatch(parts, key, FNM_PERIOD)) continue;
318 s = it->itc->func.text_get
319 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
322 edje_object_part_text_escaped_set(target, key, s);
327 edje_object_part_text_set(target, key, "");
333 _item_content_realize(Elm_Gen_Item *it,
335 Eina_List **contents,
339 Evas_Object *content;
343 EINA_LIST_FREE(*contents, content)
344 evas_object_del(content);
346 if (it->itc->func.content_get)
351 source = elm_widget_stringlist_get(edje_object_data_get(target, src));
353 EINA_LIST_FREE(source, key)
355 if (parts && fnmatch(parts, key, FNM_PERIOD))
358 Evas_Object *old = edje_object_part_swallow_get(target, key);
361 *contents = eina_list_remove(*contents, old);
362 evas_object_del(old);
365 if (it->itc->func.content_get)
366 content = it->itc->func.content_get
367 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
368 if (!content) continue;
369 *contents = eina_list_append(*contents, content);
370 if (!edje_object_part_swallow(target, key, content))
372 ERR("%s (%p) can not be swallowed into %s",
373 evas_object_type_get(content), content, key);
374 evas_object_hide(content);
377 elm_widget_sub_object_add(WIDGET(it), content);
378 if (eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()))
379 elm_widget_disabled_set(content, EINA_TRUE);
385 _item_state_realize(Elm_Gen_Item *it, Evas_Object *target, const char *parts)
391 if (!it->itc->func.state_get) return;
393 src = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
394 EINA_LIST_FREE(src, key)
396 if (parts && fnmatch(parts, key, FNM_PERIOD)) continue;
398 Eina_Bool on = it->itc->func.state_get
399 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
403 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
404 edje_object_signal_emit(target, buf, "elm");
408 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
409 edje_object_signal_emit(target, buf, "elm");
412 edje_object_message_signal_process(target);
416 * Apply the right style for the created item view.
419 _view_style_update(Elm_Gen_Item *it, Evas_Object *view, const char *style)
422 const char *stacking_even;
423 const char *stacking;
424 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
426 // FIXME: There exists
427 // item, item_compress, item_odd, item_compress_odd,
428 // tree, tree_compress, tree_odd, tree_odd_compress
429 // But those used case by case. :-(
430 // Anyway, belows codes are for backward..
431 if (it->decorate_it_set)
433 // item, item_compress, item_odd, item_compress_odd
434 strncpy(buf, "item", sizeof(buf));
435 if (sd->mode == ELM_LIST_COMPRESS)
436 strncat(buf, "_compress", sizeof(buf) - strlen(buf) - 1);
438 if (it->item->order_num_in & 0x1)
439 strncat(buf, "_odd", sizeof(buf) - strlen(buf) - 1);
440 strncat(buf, "/", sizeof(buf) - strlen(buf) - 1);
441 strncat(buf, style, sizeof(buf) - strlen(buf) - 1);
445 // item, item_compress, tree, tree_compress
446 if (it->item->type & ELM_GENLIST_ITEM_TREE)
447 snprintf(buf, sizeof(buf), "tree%s/%s",
448 sd->mode == ELM_LIST_COMPRESS ? "_compress" :
449 "", style ? : "default");
451 snprintf(buf, sizeof(buf), "item%s/%s",
452 sd->mode == ELM_LIST_COMPRESS ? "_compress" :
453 "",style ? : "default");
456 if (!elm_widget_theme_object_set(WIDGET(it), view,
458 elm_widget_style_get(WIDGET(it))))
460 ERR("%s is not a valid genlist item style. "
461 "Automatically falls back into default style.",
463 elm_widget_theme_object_set
464 (WIDGET(it), VIEW(it), "genlist", "item/default", "default");
467 edje_object_mirrored_set(view, elm_widget_mirrored_get(WIDGET(it)));
468 edje_object_scale_set(view, elm_widget_scale_get(WIDGET(it))
469 * elm_config_scale_get());
471 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
472 if (!stacking_even) stacking_even = "above";
473 it->item->stacking_even = !!strcmp("above", stacking_even);
475 stacking = edje_object_data_get(VIEW(it), "stacking");
476 if (!stacking) stacking = "yes";
477 it->item->nostacking = !!strcmp("yes", stacking);
481 * Create a VIEW(it) during _item_realize()
484 _view_create(Elm_Gen_Item *it, const char *style)
486 Evas_Object *view = edje_object_add(evas_object_evas_get(WIDGET(it)));
487 evas_object_smart_member_add(view, GL_IT(it)->wsd->pan_obj);
488 elm_widget_sub_object_add(WIDGET(it), view);
489 edje_object_scale_set(view, elm_widget_scale_get(WIDGET(it)) *
490 elm_config_scale_get());
492 _view_style_update(it, view, style);
497 _view_clear(Evas_Object *view, Eina_List **texts, Eina_List **contents)
503 EINA_LIST_FOREACH(*texts, l, part)
504 edje_object_part_text_set(view, part, NULL);
505 ELM_SAFE_FREE(*texts, elm_widget_stringlist_free);
507 EINA_LIST_FREE(*contents, c)
512 _item_scroll(Elm_Genlist_Data *sd)
515 Elm_Gen_Item *it = NULL;
516 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
518 if (!sd->show_item) return;
520 evas_object_geometry_get(sd->pan_obj, NULL, NULL, &ow, &oh);
522 dx = it->x + it->item->block->x;
523 dy = it->y + it->item->block->y;
524 dw = it->item->block->w;
527 switch (sd->scroll_to_type)
529 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
530 if (it->item->group_item) gith = it->item->group_item->item->h;
534 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
535 dy += ((it->item->h / 2) - (oh / 2));
538 case ELM_GENLIST_ITEM_SCROLLTO_IN:
540 if ((sd->expanded_item) &&
541 ((sd->show_item->y + sd->show_item->item->block->y
542 + sd->show_item->item->h) -
543 (sd->expanded_item->y + sd->expanded_item->item->block->y) > oh))
545 it = sd->expanded_item;
546 if (it->item->group_item) gith = it->item->group_item->item->h;
547 dx = it->x + it->item->block->x;
548 dy = it->y + it->item->block->y - gith;
549 dw = it->item->block->w;
553 if ((it->item->group_item) &&
554 (sd->pan_y > (it->y + it->item->block->y)))
555 gith = it->item->group_item->item->h;
562 eo_do(sd->obj, elm_interface_scrollable_region_bring_in(dx, dy, dw, dh));
564 eo_do(sd->obj, elm_interface_scrollable_content_region_show
567 it->item->show_me = EINA_FALSE;
568 sd->show_item = NULL;
569 sd->auto_scroll_enabled = EINA_FALSE;
570 sd->check_scroll = EINA_FALSE;
574 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
577 if (!it->realized) return;
578 if (GL_IT(it)->wsd->reorder_it == it)
580 WRN("reordering item should not be unrealized");
584 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
586 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, EO_OBJ(it));
587 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
589 _view_clear(VIEW(it), &(it->texts), &(it->contents));
590 ELM_SAFE_FREE(it->item_focus_chain, eina_list_free);
592 eo_do(EO_OBJ(it), elm_wdg_item_track_cancel());
596 it->realized = EINA_FALSE;
597 it->want_unrealize = EINA_FALSE;
599 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
600 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
604 _item_block_unrealize(Item_Block *itb)
608 Eina_Bool dragging = EINA_FALSE;
610 if (!itb->realized) return;
611 evas_event_freeze(evas_object_evas_get((itb->sd)->obj));
613 EINA_LIST_FOREACH(itb->items, l, it)
615 if (itb->must_recalc || !(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP))
619 dragging = EINA_TRUE;
620 it->want_unrealize = EINA_TRUE;
623 _elm_genlist_item_unrealize(it, EINA_FALSE);
628 itb->realized = EINA_FALSE;
629 itb->want_unrealize = EINA_TRUE;
632 itb->want_unrealize = EINA_FALSE;
633 evas_event_thaw(evas_object_evas_get((itb->sd)->obj));
634 evas_event_thaw_eval(evas_object_evas_get((itb->sd)->obj));
638 _must_recalc_idler(void *data)
640 ELM_GENLIST_DATA_GET(data, sd);
642 ecore_job_del(sd->calc_job);
643 sd->calc_job = ecore_job_add(_calc_job, data);
644 sd->must_recalc_idler = NULL;
645 return ECORE_CALLBACK_CANCEL;
649 _calc_job(void *data)
652 Item_Block *itb, *chb = NULL;
653 Evas_Coord pan_w = 0, pan_h = 0;
654 ELM_GENLIST_DATA_GET(data, sd);
655 Eina_Bool minw_change = EINA_FALSE;
656 Eina_Bool did_must_recalc = EINA_FALSE;
657 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw = 0;
659 evas_object_geometry_get(sd->pan_obj, NULL, NULL, &ow, &sd->h);
660 if (sd->mode == ELM_LIST_COMPRESS)
661 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
662 (NULL, NULL, &vw, NULL));
664 if (sd->w != ow) sd->w = ow;
666 evas_event_freeze(evas_object_evas_get(sd->obj));
667 EINA_INLIST_FOREACH(sd->blocks, itb)
669 Eina_Bool show_me = EINA_FALSE;
672 show_me = itb->show_me;
673 itb->show_me = EINA_FALSE;
676 if (itb->realized) _item_block_unrealize(itb);
678 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
680 if (itb->must_recalc)
685 EINA_LIST_FOREACH(itb->items, l, it)
686 it->item->mincalcd = EINA_FALSE;
687 itb->changed = EINA_TRUE;
688 did_must_recalc = EINA_TRUE;
689 if (itb->realized) _item_block_unrealize(itb);
690 itb->must_recalc = EINA_FALSE;
692 show_me = _item_block_recalc(itb, in, EINA_FALSE);
698 if (minw < itb->minw)
702 minw_change = EINA_TRUE;
704 if ((sd->mode == ELM_LIST_COMPRESS) && (minw > vw))
707 minw_change = EINA_TRUE;
713 if ((show_me) && (sd->show_item) && (!sd->show_item->item->queued))
714 sd->check_scroll = EINA_TRUE;
718 EINA_INLIST_FOREACH(sd->blocks, itb)
724 if ((chb) && (EINA_INLIST_GET(chb)->next))
726 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
728 if (itb->realized) _item_block_unrealize(itb);
732 if (minw < sd->w) minw = sd->w;
733 if ((minw != sd->minw) || (minh != sd->minh))
737 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
738 elm_layout_sizing_eval(sd->obj);
745 if ((sd->anchor_item) && (sd->anchor_item->item->block)
746 && (!sd->auto_scroll_enabled))
751 it = sd->anchor_item;
753 eo_do(sd->obj, elm_interface_scrollable_content_pos_set
754 (sd->pan_x, it->item->block->y
755 + it->y + it_y, EINA_TRUE));
756 sd->anchor_item = it;
762 if (!sd->must_recalc_idler)
763 sd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, data);
765 if (sd->check_scroll)
767 eo_do(sd->pan_obj, elm_obj_pan_content_size_get(&pan_w, &pan_h));
768 if (EINA_INLIST_GET(sd->show_item) == sd->items->last)
769 sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
771 switch (sd->scroll_to_type)
773 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
777 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
781 case ELM_GENLIST_ITEM_SCROLLTO_IN:
786 if ((sd->show_item) && (sd->show_item->item->block))
788 if ((pan_w > (sd->show_item->x + sd->show_item->item->block->x))
789 && (pan_h > (sd->show_item->y + sd->show_item->item->block->y
798 evas_object_smart_changed(sd->pan_obj);
799 evas_event_thaw(evas_object_evas_get(sd->obj));
800 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
804 _elm_genlist_elm_layout_sizing_eval(Eo *obj, Elm_Genlist_Data *sd)
806 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
807 Evas_Coord vmw = 0, vmh = 0;
809 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
811 if (sd->on_sub_del) return;;
813 evas_object_size_hint_min_get(obj, &minw, NULL);
814 evas_object_size_hint_max_get(obj, &maxw, &maxh);
816 edje_object_size_min_calc(wd->resize_obj, &vmw, &vmh);
818 if (sd->mode == ELM_LIST_COMPRESS)
820 Evas_Coord vw = 0, vh = 0;
822 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
823 (NULL, NULL, &vw, &vh));
824 if ((vw != 0) && (vw != sd->prev_viewport_w))
828 sd->prev_viewport_w = vw;
830 EINA_INLIST_FOREACH(sd->blocks, itb)
832 itb->must_recalc = EINA_TRUE;
834 ecore_job_del(sd->calc_job);
835 sd->calc_job = ecore_job_add(_calc_job, obj);
840 else if (sd->mode == ELM_LIST_LIMIT)
843 minw = vmw + sd->realminw;
851 evas_object_size_hint_min_set(obj, minw, minh);
852 evas_object_size_hint_max_set(obj, maxw, maxh);
856 _item_contract_emit(Elm_Object_Item *eo_it)
858 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
859 Elm_Object_Item *eo_it2;
863 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACT_FLIP, "");
864 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACT_FLIP, "elm");
865 it->item->tree_effect_finished = EINA_FALSE;
867 EINA_LIST_FOREACH(it->item->items, l, eo_it2)
868 if (eo_it2) _item_contract_emit(eo_it2);
872 _item_tree_effect_before(Elm_Gen_Item *it)
874 Elm_Object_Item *eo_it2;
876 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
878 EINA_LIST_FOREACH(it->item->items, l, eo_it2)
880 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
881 if (it2->parent && (it == it2->parent))
884 it2->item->tree_effect_hide_me = EINA_TRUE;
885 if (sd->move_effect_mode ==
886 ELM_GENLIST_TREE_EFFECT_EXPAND)
889 edje_object_signal_emit(VIEW(it2), SIGNAL_HIDE, "");
890 edje_object_signal_emit(VIEW(it2), SIGNAL_HIDE, "elm");
892 else if (sd->move_effect_mode ==
893 ELM_GENLIST_TREE_EFFECT_CONTRACT)
894 _item_contract_emit(eo_it2);
897 return ECORE_CALLBACK_CANCEL;
901 _item_position(Elm_Gen_Item *it,
908 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
911 (evas_object_evas_get(sd->obj));
912 evas_object_resize(view, it->item->w, it->item->h);
913 evas_object_move(view, it_x, it_y);
914 evas_object_show(view);
915 evas_event_thaw(evas_object_evas_get(sd->obj));
917 (evas_object_evas_get(sd->obj));
921 _item_tree_effect(Elm_Genlist_Data *sd,
924 Elm_Gen_Item *expanded_next_it;
925 Elm_Object_Item *eo_it;
927 expanded_next_it = sd->expanded_next_item;
929 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
931 eo_it = elm_genlist_item_prev_get(EO_OBJ(expanded_next_it));
934 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
935 if (it->item->expanded_depth <=
936 expanded_next_it->item->expanded_depth) break;
937 if (it->item->scrl_y &&
938 (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y)
939 && (it->item->expanded_depth >
940 expanded_next_it->item->expanded_depth))
942 if (!it->item->tree_effect_finished)
945 edje_object_signal_emit(VIEW(it), "flip_item", "");
946 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ITEM,
949 (it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
950 it->item->tree_effect_finished = EINA_TRUE;
953 eo_it = elm_genlist_item_prev_get(eo_it);
956 else if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
958 eo_it = elm_genlist_item_prev_get(EO_OBJ(expanded_next_it));
961 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
962 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
963 (it->item->expanded_depth >
964 expanded_next_it->item->expanded_depth))
966 if (!it->item->tree_effect_finished)
969 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "");
970 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "elm");
971 it->item->tree_effect_finished = EINA_TRUE;
976 eo_it = elm_genlist_item_prev_get(eo_it);
982 _item_sub_items_clear(Elm_Gen_Item *it)
984 Eina_List *tl = NULL, *l;
985 Elm_Object_Item *eo_it2;
987 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
989 EINA_LIST_FOREACH(it->item->items, l, eo_it2)
990 tl = eina_list_append(tl, eo_it2);
991 EINA_LIST_FREE(tl, eo_it2)
992 eo_do(eo_it2, elm_wdg_item_del());
996 _item_auto_scroll(Elm_Genlist_Data *sd)
998 Elm_Object_Item *eo_tmp_item = NULL;
1000 if ((sd->expanded_item) && (sd->auto_scroll_enabled))
1002 eo_tmp_item = eina_list_data_get
1003 (eina_list_last(sd->expanded_item->item->items));
1004 if (!eo_tmp_item) return;
1005 ELM_GENLIST_ITEM_DATA_GET(eo_tmp_item, tmp_item);
1006 sd->show_item = tmp_item;
1007 sd->bring_in = EINA_TRUE;
1008 sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
1009 if ((sd->show_item->item->queued) || (!sd->show_item->item->mincalcd))
1011 sd->show_item->item->show_me = EINA_TRUE;
1012 sd->auto_scroll_enabled = EINA_FALSE;
1020 _item_tree_effect_finish(Elm_Genlist_Data *sd)
1022 Elm_Object_Item *eo_it = NULL;
1025 if (sd->tree_effect_animator)
1027 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
1028 _item_sub_items_clear(sd->expanded_item);
1030 EINA_LIST_FOREACH(sd->expanded_item->item->items, l, eo_it)
1032 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
1033 it->item->tree_effect_finished = EINA_TRUE;
1034 it->item->old_scrl_y = it->item->scrl_y;
1035 if (GL_IT(it)->wsd->move_effect_mode ==
1036 ELM_GENLIST_TREE_EFFECT_EXPAND)
1039 edje_object_signal_emit(VIEW(it), SIGNAL_SHOW, "");
1040 edje_object_signal_emit(VIEW(it), SIGNAL_SHOW, "elm");
1045 _item_auto_scroll(sd);
1046 evas_object_lower(sd->event_block_rect);
1047 evas_object_hide(sd->event_block_rect);
1048 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
1049 sd->move_items = eina_list_free(sd->move_items);
1051 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
1052 evas_object_smart_callback_call
1053 (sd->obj, SIG_TREE_EFFECT_FINISHED, NULL);
1054 evas_object_smart_changed(sd->pan_obj);
1056 sd->tree_effect_animator = NULL;
1060 _elm_genlist_item_position_state_update(Elm_Gen_Item *it)
1062 unsigned idx = it->item->order_num_in;
1064 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1066 if (!it->item->nostacking)
1068 if ((idx & 0x1) ^ it->item->stacking_even)
1070 if (it->deco_all_view) evas_object_stack_below(it->deco_all_view, sd->stack[0]);
1071 else evas_object_stack_below(VIEW(it), sd->stack[0]);
1075 if (it->deco_all_view) evas_object_stack_above(it->deco_all_view, sd->stack[0]);
1076 else evas_object_stack_above(VIEW(it), sd->stack[0]);
1082 edje_object_signal_emit(VIEW(it), SIGNAL_ODD, "elm");
1083 if (it->deco_all_view)
1084 edje_object_signal_emit(it->deco_all_view, SIGNAL_ODD, "elm");
1088 edje_object_signal_emit(VIEW(it), SIGNAL_EVEN, "elm");
1089 if (it->deco_all_view)
1090 edje_object_signal_emit(it->deco_all_view, SIGNAL_EVEN, "elm");
1093 if (sd->item_count == 1)
1095 edje_object_signal_emit(VIEW(it), SIGNAL_LIST_SINGLE, "elm");
1096 if (it->deco_all_view)
1097 edje_object_signal_emit(it->deco_all_view, SIGNAL_LIST_SINGLE, "elm");
1101 edje_object_signal_emit(VIEW(it), SIGNAL_LIST_FIRST, "elm");
1102 if (it->deco_all_view)
1103 edje_object_signal_emit(it->deco_all_view, SIGNAL_LIST_FIRST, "elm");
1105 else if (idx == sd->item_count - 1)
1107 edje_object_signal_emit(VIEW(it), SIGNAL_LIST_LAST, "elm");
1108 if (it->deco_all_view)
1109 edje_object_signal_emit(it->deco_all_view, SIGNAL_LIST_LAST, "elm");
1113 edje_object_signal_emit(VIEW(it), SIGNAL_LIST_MIDDLE, "elm");
1114 if (it->deco_all_view)
1115 edje_object_signal_emit(it->deco_all_view, SIGNAL_LIST_MIDDLE, "elm");
1120 unsigned first_idx = it->parent->item->order_num_in + 1;
1121 unsigned count = eina_list_count(it->parent->item->items);
1125 edje_object_signal_emit(VIEW(it), SIGNAL_GROUP_SINGLE, "elm");
1126 if (it->deco_all_view)
1127 edje_object_signal_emit(it->deco_all_view, SIGNAL_GROUP_SINGLE,
1130 else if (idx == first_idx)
1132 edje_object_signal_emit(VIEW(it), SIGNAL_GROUP_FIRST, "elm");
1133 if (it->deco_all_view)
1134 edje_object_signal_emit(it->deco_all_view, SIGNAL_GROUP_FIRST,
1137 else if (EO_OBJ(it) == eina_list_data_get(eina_list_last(it->parent->item->items)))
1139 edje_object_signal_emit(VIEW(it), SIGNAL_GROUP_LAST, "elm");
1140 if (it->deco_all_view)
1141 edje_object_signal_emit(it->deco_all_view, SIGNAL_GROUP_LAST,
1144 else if (idx > first_idx)
1146 edje_object_signal_emit(VIEW(it), SIGNAL_GROUP_MIDDLE, "elm");
1147 if (it->deco_all_view)
1148 edje_object_signal_emit(it->deco_all_view, SIGNAL_GROUP_MIDDLE,
1155 _item_order_update(const Eina_Inlist *l,
1158 Elm_Gen_Item *it, *it2;
1161 * always update position state of previous item, it may have been
1162 * marked as "single" if it was the only element at the time, or
1163 * "middle", "first" or "last" in the case of insert into different
1166 if ((l->prev) && (start > 0))
1168 it = ELM_GEN_ITEM_FROM_INLIST(l->prev);
1169 it->item->order_num_in = start - 1;
1170 _elm_genlist_item_position_state_update(it);
1173 for (it = ELM_GEN_ITEM_FROM_INLIST(l); l; l = l->next,
1174 it = ELM_GEN_ITEM_FROM_INLIST(l))
1176 it->item->order_num_in = start++;
1177 _elm_genlist_item_position_state_update(it);
1178 it2 = ELM_GEN_ITEM_FROM_INLIST(l->next);
1179 if (it2 && (it->item->order_num_in != it2->item->order_num_in))
1185 _elm_genlist_item_state_update(Elm_Gen_Item *it,
1190 if (it->selected != itc->selected)
1194 edje_object_signal_emit(VIEW(it), SIGNAL_SELECTED, "elm");
1195 if (it->deco_all_view)
1196 edje_object_signal_emit
1197 (it->deco_all_view, SIGNAL_SELECTED, "elm");
1200 if (eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()) != itc->disabled)
1202 if (eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()))
1203 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED,"elm");
1204 if (it->deco_all_view)
1205 edje_object_signal_emit
1206 (it->deco_all_view, SIGNAL_DISABLED, "elm");
1208 if (it->item->expanded != itc->expanded)
1210 if (it->item->expanded)
1211 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
1212 if (it->deco_all_view)
1213 edje_object_signal_emit
1214 (it->deco_all_view, SIGNAL_EXPANDED, "elm");
1221 edje_object_signal_emit(VIEW(it), SIGNAL_SELECTED, "elm");
1222 if (it->deco_all_view)
1223 edje_object_signal_emit
1224 (it->deco_all_view, SIGNAL_SELECTED, "elm");
1226 if (eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()))
1228 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
1229 if (it->deco_all_view)
1230 edje_object_signal_emit
1231 (it->deco_all_view, SIGNAL_DISABLED, "elm");
1233 if (it->item->expanded)
1235 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
1236 if (it->deco_all_view)
1237 edje_object_signal_emit
1238 (it->deco_all_view, SIGNAL_EXPANDED, "elm");
1241 if (it == (Elm_Gen_Item *)GL_IT(it)->wsd->focused_item &&
1242 elm_widget_focus_highlight_enabled_get(WIDGET(it)))
1243 edje_object_signal_emit(VIEW(it), SIGNAL_FOCUSED, "elm");
1247 _view_inflate(Evas_Object *view, Elm_Gen_Item *it, Eina_List **sources,
1248 Eina_List **contents)
1251 if (sources) _item_text_realize(it, view, sources, NULL);
1252 if (contents) _item_content_realize(it, view, contents, "contents", NULL);
1253 _item_state_realize(it, view, NULL);
1257 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1259 if (it->position_update || GL_IT(it)->block->position_update)
1261 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE,
1263 it->position_update = EINA_FALSE;
1268 _decorate_all_item_position(Elm_Gen_Item *it,
1272 if ((!it) || (!GL_IT(it)->wsd->decorate_all_mode)) return;
1273 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
1274 evas_object_move(it->deco_all_view, itx, ity);
1278 _decorate_all_item_realize(Elm_Gen_Item *it,
1279 Eina_Bool effect_on)
1282 const char *stacking;
1283 const char *stacking_even;
1286 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1288 if (it->item->decorate_all_item_realized) return;
1290 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
1291 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
1292 elm_config_scale_get());
1293 evas_object_smart_member_add(it->deco_all_view, sd->pan_obj);
1294 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
1296 if (it->item->type & ELM_GENLIST_ITEM_TREE)
1297 strncpy(buf, "tree", sizeof(buf));
1298 else strncpy(buf, "item", sizeof(buf));
1299 if (sd->mode == ELM_LIST_COMPRESS)
1300 strncat(buf, "_compress", sizeof(buf) - strlen(buf) - 1);
1302 strncat(buf, "/", sizeof(buf) - strlen(buf) - 1);
1303 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf) - 1);
1305 elm_widget_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
1306 elm_widget_style_get(WIDGET(it)));
1308 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1309 if (!stacking_even) stacking_even = "above";
1310 it->item->stacking_even = !!strcmp("above", stacking_even);
1312 stacking = edje_object_data_get(VIEW(it), "stacking");
1313 if (!stacking) stacking = "yes";
1314 it->item->nostacking = !!strcmp("yes", stacking);
1316 edje_object_mirrored_set
1317 (it->deco_all_view, elm_widget_mirrored_get(WIDGET(it)));
1319 _elm_genlist_item_position_state_update(it);
1320 _elm_genlist_item_state_update(it, NULL);
1322 if (GL_IT(it)->wsd->reorder_mode)
1324 edje_object_signal_emit(it->deco_all_view, SIGNAL_REORDER_MODE_UNSET,
1329 edje_object_signal_emit
1330 (it->deco_all_view, SIGNAL_DECORATE_ENABLED_EFFECT, "elm");
1332 edje_object_signal_emit
1333 (it->deco_all_view, SIGNAL_DECORATE_ENABLED, "elm");
1335 _item_mouse_callbacks_del(it, VIEW(it));
1336 _item_mouse_callbacks_add(it, it->deco_all_view);
1339 edje_object_signal_emit
1340 (it->deco_all_view, SIGNAL_FLIP_ENABLED, "elm");
1341 _view_inflate(it->deco_all_view, it, NULL, &(GL_IT(it)->deco_all_contents));
1342 edje_object_part_swallow
1343 (it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
1345 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
1346 evas_object_show(it->deco_all_view);
1349 edje_object_signal_emit(it->deco_all_view, SIGNAL_SELECTED, "elm");
1351 it->item->decorate_all_item_realized = EINA_TRUE;
1352 it->want_unrealize = EINA_FALSE;
1355 //-- tree expand/contract signal handle routine --//
1357 _expand_toggle_signal_cb(void *data,
1358 Evas_Object *obj EINA_UNUSED,
1359 const char *emission EINA_UNUSED,
1360 const char *source EINA_UNUSED)
1362 Elm_Gen_Item *it = data;
1364 if (it->item->expanded)
1365 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, EO_OBJ(it));
1367 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, EO_OBJ(it));
1371 _expand_signal_cb(void *data,
1372 Evas_Object *obj EINA_UNUSED,
1373 const char *emission EINA_UNUSED,
1374 const char *source EINA_UNUSED)
1376 Elm_Gen_Item *it = data;
1378 if (!it->item->expanded)
1379 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, EO_OBJ(it));
1383 _contract_signal_cb(void *data,
1384 Evas_Object *obj EINA_UNUSED,
1385 const char *emission EINA_UNUSED,
1386 const char *source EINA_UNUSED)
1388 Elm_Gen_Item *it = data;
1390 if (it->item->expanded)
1391 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, EO_OBJ(it));
1394 //-- item cache handle routine --//
1395 // clean up item cache by removing overflowed caches
1397 _item_cache_clean(Elm_Genlist_Data *sd)
1399 evas_event_freeze(evas_object_evas_get(sd->obj));
1401 while ((sd->item_cache) && (sd->item_cache_count > sd->item_cache_max))
1405 itc = EINA_INLIST_CONTAINER_GET(sd->item_cache->last, Item_Cache);
1406 sd->item_cache = eina_inlist_remove
1407 (sd->item_cache, sd->item_cache->last);
1408 sd->item_cache_count--;
1409 evas_object_del(itc->spacer);
1410 evas_object_del(itc->base_view);
1411 eina_stringshare_del(itc->item_style);
1414 evas_event_thaw(evas_object_evas_get(sd->obj));
1415 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
1418 // free one item cache
1420 _item_cache_free(Item_Cache *itc)
1422 evas_object_del(itc->spacer);
1423 evas_object_del(itc->base_view);
1424 eina_stringshare_del(itc->item_style);
1428 // empty all item caches
1430 _item_cache_zero(Elm_Genlist_Data *sd)
1432 int pmax = sd->item_cache_max;
1434 sd->item_cache_max = 0;
1435 _item_cache_clean(sd);
1436 sd->item_cache_max = pmax;
1439 // add an item to item cache
1441 _item_cache_add(Elm_Gen_Item *it)
1444 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1445 Evas_Object *obj = sd->obj;
1447 evas_event_freeze(evas_object_evas_get(obj));
1448 if (sd->item_cache_max <= 0)
1450 ELM_SAFE_FREE(VIEW(it), evas_object_del);
1451 ELM_SAFE_FREE(it->spacer, evas_object_del);
1453 evas_event_thaw(evas_object_evas_get(obj));
1454 evas_event_thaw_eval(evas_object_evas_get(obj));
1459 sd->item_cache_count++;
1460 itc = calloc(1, sizeof(Item_Cache));
1463 evas_event_thaw(evas_object_evas_get(obj));
1464 evas_event_thaw_eval(evas_object_evas_get(obj));
1468 eina_inlist_prepend(sd->item_cache, EINA_INLIST_GET(itc));
1469 itc->spacer = it->spacer;
1471 itc->base_view = VIEW(it);
1474 edje_object_signal_emit(itc->base_view, SIGNAL_UNSELECTED, "elm");
1475 evas_object_hide(itc->base_view);
1476 evas_object_move(itc->base_view, -9999, -9999);
1477 itc->item_style = eina_stringshare_add(it->itc->item_style);
1478 if (it->item->type & ELM_GENLIST_ITEM_TREE) itc->tree = 1;
1479 itc->selected = it->selected;
1480 itc->disabled = eo_do(EO_OBJ(it), elm_wdg_item_disabled_get());
1481 itc->expanded = it->item->expanded;
1482 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
1483 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
1485 // FIXME: other callbacks?
1486 edje_object_signal_callback_del_full
1487 (itc->base_view, "elm,action,expand,toggle", "elm",
1488 _expand_toggle_signal_cb, it);
1489 edje_object_signal_callback_del_full
1490 (itc->base_view, "elm,action,expand", "elm", _expand_signal_cb, it);
1491 edje_object_signal_callback_del_full
1492 (itc->base_view, "elm,action,contract", "elm", _contract_signal_cb, it);
1493 _item_mouse_callbacks_del(it, itc->base_view);
1494 _item_cache_clean(sd);
1496 evas_event_thaw(evas_object_evas_get(obj));
1497 evas_event_thaw_eval(evas_object_evas_get(obj));
1500 // find an item from item cache and remove it from the cache
1502 _item_cache_find(Elm_Gen_Item *it)
1504 Item_Cache *itc = NULL;
1507 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1509 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1510 EINA_INLIST_FOREACH_SAFE(sd->item_cache, l, itc)
1512 if ((itc->selected) || (itc->disabled) || (itc->expanded))
1515 if ((itc->tree == tree) &&
1516 (((!it->itc->item_style) && (!itc->item_style)) ||
1517 (it->itc->item_style && itc->item_style &&
1518 (!strcmp(it->itc->item_style, itc->item_style)))))
1521 eina_inlist_remove (sd->item_cache, EINA_INLIST_GET(itc));
1522 sd->item_cache_count--;
1531 _access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
1536 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1537 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1539 buf = eina_strbuf_new();
1541 if (it->itc->func.text_get)
1546 if (!(it->texts)) it->texts =
1547 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1549 EINA_LIST_FOREACH(it->texts, l, key)
1551 char *s = it->itc->func.text_get
1552 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
1556 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
1557 eina_strbuf_append(buf, s);
1563 ret = eina_strbuf_string_steal(buf);
1564 eina_strbuf_free(buf);
1569 _access_state_cb(void *data, Evas_Object *obj EINA_UNUSED)
1571 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1572 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1574 if (it->base->disabled)
1575 return strdup(E_("State: Disabled"));
1581 _access_on_highlight_cb(void *data)
1583 Evas_Coord x, y, w, h;
1584 Evas_Coord sx, sy, sw, sh;
1585 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1586 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
1588 evas_object_geometry_get(it->base->view, &x, &y, &w, &h);
1589 // XXX There would be a reason.
1590 if ((w == 0) && (h == 0)) return;
1592 evas_object_geometry_get(it->base->widget, &sx, &sy, &sw, &sh);
1593 if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
1594 elm_genlist_item_bring_in(EO_OBJ(it),
1595 ELM_GENLIST_ITEM_SCROLLTO_IN);
1599 _access_widget_item_register(Elm_Gen_Item *it)
1601 Elm_Access_Info *ai;
1603 _elm_access_widget_item_register(it->base);
1605 ai = _elm_access_info_get(it->base->access_obj);
1607 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1608 _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
1609 _elm_access_on_highlight_hook_set(ai, _access_on_highlight_cb, it);
1610 _elm_access_activate_callback_set(ai, _access_activate_cb, EO_OBJ(it));
1614 _item_realize(Elm_Gen_Item *it,
1618 Item_Cache *itc = NULL;
1619 const char *treesize;
1621 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1625 if (it->item->order_num_in != in)
1627 _item_order_update(EINA_INLIST_GET(it), in);
1628 _elm_genlist_item_state_update(it, NULL);
1629 _elm_genlist_item_index_update(it);
1633 it->item->order_num_in = in;
1635 if (it->item->nocache_once)
1636 it->item->nocache_once = EINA_FALSE;
1637 else if (!it->item->nocache)
1638 itc = _item_cache_find(it);
1639 if (itc && (!sd->tree_effect_enabled))
1641 VIEW(it) = itc->base_view;
1642 itc->base_view = NULL;
1643 it->spacer = itc->spacer;
1647 VIEW(it) = _view_create(it, it->itc->item_style);
1650 if (_elm_config->access_mode) _access_widget_item_register(it);
1652 _item_order_update(EINA_INLIST_GET(it), in);
1654 if (sd->reorder_mode)
1655 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
1657 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_UNSET, "elm");
1659 treesize = edje_object_data_get(VIEW(it), "treesize");
1660 if (treesize) tsize = atoi(treesize);
1662 if (edje_object_part_exists(VIEW(it), "elm.swallow.pad"))
1664 if (!it->spacer && treesize)
1667 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1668 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1669 elm_widget_sub_object_add(WIDGET(it), it->spacer);
1672 evas_object_size_hint_min_set
1673 (it->spacer, (it->item->expanded_depth * tsize) *
1674 elm_config_scale_get(), 1);
1675 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1679 ELM_SAFE_FREE(it->spacer, evas_object_del);
1684 edje_object_signal_callback_add
1685 (VIEW(it), "elm,action,expand,toggle", "elm",
1686 _expand_toggle_signal_cb, it);
1687 edje_object_signal_callback_add
1688 (VIEW(it), "elm,action,expand", "elm", _expand_signal_cb, it);
1689 edje_object_signal_callback_add
1690 (VIEW(it), "elm,action,contract", "elm", _contract_signal_cb, it);
1691 _item_mouse_callbacks_add(it, VIEW(it));
1693 if ((sd->decorate_all_mode) && (!it->deco_all_view) &&
1694 (it->item->type != ELM_GENLIST_ITEM_GROUP) &&
1695 (it->itc->decorate_all_item_style))
1696 _decorate_all_item_realize(it, EINA_FALSE);
1698 _elm_genlist_item_state_update(it, itc);
1699 _elm_genlist_item_index_update(it);
1702 /* homogeneous genlist shortcut */
1703 if ((calc) && (sd->homogeneous) && (!it->item->mincalcd) &&
1704 (((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) && sd->group_item_width) ||
1705 (!(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) && sd->item_width)))
1707 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
1709 it->item->w = it->item->minw = sd->group_item_width;
1710 it->item->h = it->item->minh = sd->group_item_height;
1714 it->item->w = it->item->minw = sd->item_width;
1715 it->item->h = it->item->minh = sd->item_height;
1717 it->item->mincalcd = EINA_TRUE;
1721 if (eina_list_count(it->contents) != 0)
1722 ERR_ABORT("If you see this error, please notify us and we"
1725 _view_inflate(VIEW(it), it, &it->texts, &it->contents);
1726 if (it->has_contents != (!!it->contents))
1727 it->item->mincalcd = EINA_FALSE;
1728 it->has_contents = !!it->contents;
1731 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
1732 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_contents,
1736 /* access: unregister item which have no text and content */
1737 if (_elm_config->access_mode && !it->texts && !it->contents)
1738 _elm_access_widget_item_unregister(it->base);
1740 if (!it->item->mincalcd)
1742 Evas_Coord mw = -1, mh = -1;
1744 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1745 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1746 if (sd->mode == ELM_LIST_COMPRESS)
1747 mw = sd->prev_viewport_w;
1748 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
1749 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1750 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1751 it->item->w = it->item->minw = mw;
1752 it->item->h = it->item->minh = mh;
1753 it->item->mincalcd = EINA_TRUE;
1755 if ((!sd->group_item_width) &&
1756 (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP))
1758 sd->group_item_width = mw;
1759 sd->group_item_height = mh;
1761 else if ((!sd->item_width) &&
1762 (it->item->type == ELM_GENLIST_ITEM_NONE))
1764 sd->item_width = mw;
1765 sd->item_height = mh;
1768 if (!calc) evas_object_show(VIEW(it));
1771 if (it->tooltip.content_cb)
1774 elm_wdg_item_tooltip_content_cb_set(
1775 it->tooltip.content_cb, it->tooltip.data, NULL),
1776 elm_wdg_item_tooltip_style_set(it->tooltip.style),
1777 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
1780 if (it->mouse_cursor)
1782 elm_wdg_item_cursor_set(it->mouse_cursor));
1784 it->realized = EINA_TRUE;
1785 it->want_unrealize = EINA_FALSE;
1787 if (itc) _item_cache_free(itc);
1790 if (it->item->tree_effect_hide_me)
1792 if (sd->move_effect_mode
1793 != ELM_GENLIST_TREE_EFFECT_NONE)
1796 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "");
1797 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "elm");
1799 it->item->tree_effect_hide_me = EINA_FALSE;
1802 if (it->item->type == ELM_GENLIST_ITEM_NONE)
1806 EINA_LIST_FOREACH(it->contents, l, eobj)
1807 if (elm_widget_is(eobj) && elm_object_focus_allow_get(eobj))
1808 it->item_focus_chain = eina_list_append
1809 (it->item_focus_chain, eobj);
1813 if (it->item->type == ELM_GENLIST_ITEM_TREE)
1815 Evas_Object* t_eobj;
1817 EINA_LIST_FOREACH(it->contents, tl, t_eobj)
1818 if (elm_widget_is(t_eobj) && elm_object_focus_allow_get(t_eobj))
1819 it->item_focus_chain = eina_list_append
1820 (it->item_focus_chain, t_eobj);
1824 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, EO_OBJ(it));
1827 //Send a signal so that an item changes its style according to its expand depth
1828 if (GL_IT(it)->expanded_depth > 0)
1831 snprintf(buf, sizeof(buf), "elm,state,expanded_depth,%d",
1832 GL_IT(it)->expanded_depth);
1833 edje_object_signal_emit(VIEW(it), buf, "elm");
1836 if ((!calc) && (sd->decorate_all_mode) &&
1837 (it->item->type != ELM_GENLIST_ITEM_GROUP))
1839 if (it->itc->decorate_all_item_style)
1841 if (!it->deco_all_view)
1842 _decorate_all_item_realize(it, EINA_FALSE);
1843 edje_object_message_signal_process(it->deco_all_view);
1847 if (it->decorate_it_set) _decorate_item_set(it);
1849 edje_object_message_signal_process(VIEW(it));
1853 _tree_effect_animator_cb(void *data)
1857 int y = 0, dy = 0, dh = 0;
1858 double effect_duration = 0.3, t;
1859 ELM_GENLIST_DATA_GET(data, sd);
1860 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
1861 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
1862 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
1863 Elm_Object_Item *eo_it = NULL, *eo_it2;
1865 t = ((0.0 > (t = ecore_time_get() - sd->start_time)) ? 0.0 : t);
1866 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
1867 evas_output_viewport_get
1868 (evas_object_evas_get(sd->pan_obj), &cvx, &cvy, &cvw, &cvh);
1869 if (t > effect_duration) end = EINA_TRUE;
1871 // Below while statement is needed, when the genlist is resized.
1872 it2 = sd->expanded_item;
1873 eo_it2 = EO_OBJ(it2);
1874 while (eo_it2 && vis)
1876 it2 = eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
1877 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
1878 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y,
1879 it2->item->w, it2->item->h, cvx, cvy, cvw,
1881 eo_it2 = elm_genlist_item_prev_get(eo_it2);
1884 if (sd->expanded_next_item)
1886 expanded_next_it = sd->expanded_next_item;
1889 EINA_LIST_FOREACH(sd->move_items, l, it)
1891 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
1893 expanded_next_it->item->old_scrl_y =
1894 sd->expanded_item->item->old_scrl_y
1895 + sd->expanded_item->item->h;
1896 if (expanded_next_it->item->scrl_y <=
1897 expanded_next_it->item->old_scrl_y) /* did not
1901 expanded_next_it->item->scrl_y = cvy + cvh;
1903 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
1904 cvy + cvh : expanded_next_it->item->scrl_y) -
1905 expanded_next_it->item->old_scrl_y;
1907 else if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
1909 if (expanded_next_it->item->scrl_y >
1910 expanded_next_it->item->old_scrl_y) /* did not
1914 expanded_next_it->item->old_scrl_y = cvy + cvh;
1916 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
1918 dy = (sd->expanded_item->item->scrl_y +
1919 sd->expanded_item->item->h) - cvy + cvh;
1920 expanded_next_it->item->old_scrl_y = cvy + cvh;
1924 dy = (sd->expanded_item->item->scrl_y +
1925 sd->expanded_item->item->h) -
1926 expanded_next_it->item->old_scrl_y;
1930 if (t <= effect_duration)
1932 y = ((1 - (1 - (t / effect_duration)) *
1933 (1 - (t / effect_duration))) * dy);
1941 if (!it->realized && !it->item->queued)
1942 _item_realize(it, in, 0);
1945 if (it != expanded_next_it)
1947 it->item->old_scrl_y =
1948 expanded_next_it->item->old_scrl_y +
1949 expanded_next_it->item->h + dh;
1954 if ((it->item->old_scrl_y + y) < (cvy + cvh))
1955 _item_position(it, VIEW(it), it->item->scrl_x,
1956 it->item->old_scrl_y + y);
1959 _item_tree_effect(sd, y);
1963 int expanded_item_num = 0;
1966 if (sd->expanded_item)
1967 eo_it = elm_genlist_item_next_get(EO_OBJ(sd->expanded_item));
1972 expanded_item_num++;
1973 eo_it2 = elm_genlist_item_next_get(eo_it2);
1978 it = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
1980 if (sd->expanded_item->item->expanded_depth >=
1981 it->item->expanded_depth) break;
1982 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
1984 if (!it->item->tree_effect_finished)
1986 if (t >= (((num - 1) * effect_duration) /
1990 edje_object_signal_emit(VIEW(it), "flip_item", "");
1991 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ITEM,
1993 _item_position(it, VIEW(it), it->item->scrl_x,
1995 it->item->tree_effect_finished = EINA_TRUE;
1999 eo_it = elm_genlist_item_next_get(eo_it);
2005 _item_tree_effect_finish(sd);
2006 return ECORE_CALLBACK_CANCEL;
2009 return ECORE_CALLBACK_RENEW;
2013 _group_items_recalc(void *data)
2017 Elm_Genlist_Data *sd = data;
2019 evas_event_freeze(evas_object_evas_get(sd->obj));
2020 EINA_LIST_FOREACH(sd->group_items, l, git)
2022 if (git->item->want_realize)
2024 if (!git->realized) _item_realize(git, 0, EINA_FALSE);
2025 evas_object_resize(VIEW(git), sd->minw, git->item->h);
2026 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2027 evas_object_stack_above(VIEW(git), sd->stack[1]);
2028 evas_object_show(VIEW(git));
2030 else if (!git->item->want_realize && git->realized)
2033 _elm_genlist_item_unrealize(git, EINA_FALSE);
2036 evas_event_thaw(evas_object_evas_get(sd->obj));
2037 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
2041 _reorder_move_animator_cb(void *data)
2044 Elm_Gen_Item *it = data;
2045 Eina_Bool down = EINA_FALSE;
2046 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
2047 int y, dy = it->item->h / 10 * elm_config_scale_get(), diff;
2049 t = ((0.0 > (t = ecore_loop_time_get()
2050 - sd->start_time)) ? 0.0 : t);
2052 if (t <= REORDER_EFFECT_TIME)
2053 y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2056 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2057 if (diff < dy) y = diff;
2058 else if (diff > it->item->h) y = diff / 2;
2060 if (it->item->old_scrl_y < it->item->scrl_y)
2062 it->item->old_scrl_y += y;
2065 else if (it->item->old_scrl_y > it->item->scrl_y)
2067 it->item->old_scrl_y -= y;
2071 if (it->deco_all_view)
2073 (it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
2075 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2076 _group_items_recalc(sd);
2078 if ((sd->reorder_pan_move) ||
2079 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2080 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2082 it->item->old_scrl_y = it->item->scrl_y;
2083 it->item->move_effect_enabled = EINA_FALSE;
2084 sd->reorder_move_animator = NULL;
2085 return ECORE_CALLBACK_CANCEL;
2088 return ECORE_CALLBACK_RENEW;
2092 _reorder_item_space_get(Elm_Gen_Item *it)
2094 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
2095 Elm_Gen_Item *reorder_it = sd->reorder_it;
2096 Evas_Coord rox, roy, row, roh, oy, oh;
2097 Eina_Bool top = EINA_FALSE;
2099 if (!reorder_it) return 0;
2101 evas_object_geometry_get(sd->pan_obj, NULL, &oy, NULL, &oh);
2102 evas_object_geometry_get
2103 (sd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2105 if ((sd->reorder_start_y < it->item->block->y) &&
2106 (roy - oy + (roh / 2) >= it->item->block->y - sd->pan_y))
2108 it->item->block->reorder_offset =
2109 sd->reorder_it->item->h * -1;
2110 if (it->item->block->count == 1)
2111 sd->reorder_rel = it;
2113 else if ((sd->reorder_start_y >= it->item->block->y) &&
2114 (roy - oy + (roh / 2) <= it->item->block->y - sd->pan_y))
2116 it->item->block->reorder_offset = sd->reorder_it->item->h;
2119 it->item->block->reorder_offset = 0;
2121 it->item->scrl_y += it->item->block->reorder_offset;
2123 top = (ELM_RECTS_INTERSECT
2124 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2125 rox, roy + (roh / 2), row, 1));
2128 sd->reorder_rel = it;
2129 it->item->scrl_y += sd->reorder_it->item->h;
2130 return sd->reorder_it->item->h;
2137 _item_block_position(Item_Block *itb,
2143 Eina_Bool vis = EINA_FALSE;
2144 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2145 Elm_Genlist_Data *sd = NULL;
2147 evas_event_freeze(evas_object_evas_get((itb->sd)->obj));
2148 evas_object_geometry_get(itb->sd->pan_obj, &ox, &oy, &ow, &oh);
2149 evas_output_viewport_get
2150 (evas_object_evas_get((itb->sd)->obj),
2151 &cvx, &cvy, &cvw, &cvh);
2153 EINA_LIST_FOREACH(itb->items, l, it)
2155 sd = GL_IT(it)->wsd;
2156 if (sd->reorder_it == it) continue;
2160 it->item->w = itb->w;
2161 it->item->scrl_x = itb->x + it->x - sd->pan_x + ox;
2162 it->item->scrl_y = itb->y + it->y - sd->pan_y + oy;
2164 vis = (ELM_RECTS_INTERSECT
2165 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2166 cvx, cvy, cvw, cvh));
2167 if (!(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP))
2169 if ((itb->realized) && (!it->realized))
2171 if (vis) _item_realize(it, in, EINA_FALSE);
2175 if (vis || it->dragging)
2177 if (sd->reorder_mode)
2178 y += _reorder_item_space_get(it);
2179 git = it->item->group_item;
2182 if (git->item->scrl_y < oy)
2183 git->item->scrl_y = oy;
2184 if ((git->item->scrl_y + git->item->h) >
2185 (it->item->scrl_y + it->item->h))
2186 git->item->scrl_y = (it->item->scrl_y +
2187 it->item->h) - git->item->h;
2188 git->item->scrl_x = it->item->scrl_x;
2189 git->item->want_realize = EINA_TRUE;
2191 if ((sd->reorder_it) &&
2192 (it->item->old_scrl_y != it->item->scrl_y))
2194 if (!it->item->move_effect_enabled)
2196 it->item->move_effect_enabled = EINA_TRUE;
2197 sd->reorder_move_animator =
2199 _reorder_move_animator_cb, it);
2202 if (!it->item->move_effect_enabled)
2204 if ((sd->decorate_all_mode) &&
2205 (it->itc->decorate_all_item_style))
2206 _decorate_all_item_position
2207 (it, it->item->scrl_x, it->item->scrl_y);
2210 if (!sd->tree_effect_enabled ||
2211 (sd->move_effect_mode ==
2212 ELM_GENLIST_TREE_EFFECT_NONE) ||
2213 ((sd->move_effect_mode !=
2214 ELM_GENLIST_TREE_EFFECT_NONE) &&
2215 (it->item->old_scrl_y ==
2218 if (it->item->deco_it_view)
2220 (it, it->item->deco_it_view,
2225 (it, VIEW(it), it->item->scrl_x,
2229 it->item->old_scrl_y = it->item->scrl_y;
2234 if (!sd->tree_effect_animator)
2235 _elm_genlist_item_unrealize(it, EINA_FALSE);
2242 if (vis) it->item->want_realize = EINA_TRUE;
2246 evas_event_thaw(evas_object_evas_get((itb->sd)->obj));
2247 evas_event_thaw_eval(evas_object_evas_get((itb->sd)->obj));
2251 _item_block_realize(Item_Block *itb)
2253 if (itb->realized) return;
2255 itb->realized = EINA_TRUE;
2256 itb->want_unrealize = EINA_FALSE;
2260 _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
2262 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2263 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0;
2269 Elm_Genlist_Data *sd = psd->wsd;
2271 evas_event_freeze(evas_object_evas_get(obj));
2273 if (sd->pan_changed)
2275 ecore_job_del(sd->calc_job);
2276 sd->calc_job = NULL;
2278 sd->pan_changed = EINA_FALSE;
2281 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2282 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2283 EINA_LIST_FOREACH(sd->group_items, l, git)
2285 git->item->want_realize = EINA_FALSE;
2288 if (sd->tree_effect_enabled &&
2289 (sd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
2291 if (!sd->tree_effect_animator)
2293 _item_tree_effect_before(sd->expanded_item);
2294 evas_object_raise(sd->event_block_rect);
2295 evas_object_stack_below(sd->event_block_rect, sd->stack[1]);
2296 evas_object_show(sd->event_block_rect);
2297 sd->start_time = ecore_time_get();
2298 sd->tree_effect_animator =
2299 ecore_animator_add(_tree_effect_animator_cb, sd->obj);
2303 EINA_INLIST_FOREACH(sd->blocks, itb)
2306 if (ELM_RECTS_INTERSECT(itb->x - sd->pan_x + ox,
2307 itb->y - sd->pan_y + oy,
2309 cvx, cvy, cvw, cvh))
2311 if ((!itb->realized) || (itb->changed))
2312 _item_block_realize(itb);
2313 _item_block_position(itb, in);
2317 if (itb->realized) _item_block_unrealize(itb);
2321 if ((!sd->reorder_it) || (sd->reorder_pan_move))
2322 _group_items_recalc(sd);
2323 if ((sd->reorder_mode) && (sd->reorder_it))
2325 if (sd->pan_y != sd->reorder_old_pan_y)
2326 sd->reorder_pan_move = EINA_TRUE;
2327 else sd->reorder_pan_move = EINA_FALSE;
2329 evas_object_raise(sd->VIEW(reorder_it));
2330 evas_object_stack_below(sd->VIEW(reorder_it), sd->stack[1]);
2331 sd->reorder_old_pan_y = sd->pan_y;
2332 sd->start_time = ecore_loop_time_get();
2335 if (!sd->tree_effect_enabled ||
2336 (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
2337 _item_auto_scroll(sd);
2340 elm_interface_scrollable_content_pos_get(&vx, &vy),
2341 elm_interface_scrollable_content_viewport_geometry_get
2342 (NULL, NULL, &vw, &vh));
2344 if (sd->reorder_fast == 1)
2345 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(vx, vy - 10, vw, vh));
2346 else if (sd->reorder_fast == -1)
2347 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(vx, vy + 10, vw, vh));
2349 if (sd->focused_item && !sd->item_loop_enable)
2350 _elm_widget_focus_highlight_start(psd->wobj);
2352 evas_event_thaw(evas_object_evas_get(obj));
2353 evas_event_thaw_eval(evas_object_evas_get(obj));
2357 _elm_genlist_pan_eo_base_destructor(Eo *obj, Elm_Genlist_Pan_Data *psd)
2359 eo_data_unref(psd->wobj, psd->wsd);
2360 eo_do_super(obj, MY_PAN_CLASS, eo_destructor());
2364 _elm_genlist_pan_class_constructor(Eo_Class *klass)
2366 evas_smart_legacy_type_register(MY_PAN_CLASS_NAME_LEGACY, klass);
2369 #include "elm_genlist_pan.eo.c"
2372 _item_multi_select_up(Elm_Genlist_Data *sd)
2374 Elm_Object_Item *eo_prev;
2376 if (!sd->selected) return EINA_FALSE;
2377 if (!sd->multi) return EINA_FALSE;
2379 eo_prev = elm_genlist_item_prev_get(sd->last_selected_item);
2382 ELM_GENLIST_ITEM_DATA_GET(eo_prev, prev);
2383 if ((!_is_no_select(prev)) && (!elm_object_item_disabled_get(eo_prev)))
2385 eo_prev = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev));
2387 if (!eo_prev) return EINA_TRUE;
2389 if (elm_genlist_item_selected_get(eo_prev))
2391 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2392 sd->last_selected_item = eo_prev;
2396 elm_genlist_item_selected_set(eo_prev, EINA_TRUE);
2402 _item_multi_select_down(Elm_Genlist_Data *sd)
2404 Elm_Object_Item *eo_next;
2406 if (!sd->selected) return EINA_FALSE;
2407 if (!sd->multi) return EINA_FALSE;
2409 eo_next = elm_genlist_item_next_get(sd->last_selected_item);
2412 ELM_GENLIST_ITEM_DATA_GET(eo_next, next);
2413 if ((_is_no_select(next)) && (!elm_object_item_disabled_get(eo_next)))
2415 eo_next = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next));
2417 if (!eo_next) return EINA_TRUE;
2419 if (elm_genlist_item_selected_get(eo_next))
2421 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2422 sd->last_selected_item = eo_next;
2426 elm_genlist_item_selected_set(eo_next, EINA_TRUE);
2433 _all_items_deselect(Elm_Genlist_Data *sd)
2435 if (!sd->selected) return EINA_FALSE;
2437 sd->deselecting = eina_list_clone(sd->selected);
2438 while (sd->deselecting)
2440 Elm_Object_Item *it = eina_list_data_get(sd->deselecting);
2442 sd->deselecting = eina_list_remove_list(sd->deselecting, sd->deselecting);
2443 elm_genlist_item_selected_set(it, EINA_FALSE);
2450 _item_single_select_up(Elm_Genlist_Data *sd)
2452 Elm_Gen_Item *prev = NULL;
2455 prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2458 Elm_Object_Item *eo_prev = elm_genlist_item_prev_get
2459 (sd->last_selected_item);
2460 prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
2465 if ((!_is_no_select(prev)) &&
2466 (!elm_object_item_disabled_get(EO_OBJ(prev))))
2468 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2471 if (!prev) return EINA_FALSE;
2473 _all_items_deselect(sd);
2475 elm_genlist_item_selected_set(EO_OBJ(prev), EINA_TRUE);
2480 _item_single_select_down(Elm_Genlist_Data *sd)
2482 Elm_Gen_Item *next = NULL;
2483 Elm_Object_Item *eo_next = NULL;
2486 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2489 eo_next = elm_genlist_item_next_get(sd->last_selected_item);
2490 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2495 if ((!_is_no_select(next)) &&
2496 (!elm_object_item_disabled_get(EO_OBJ(next))))
2498 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2501 if (!next) return EINA_FALSE;
2503 _all_items_deselect(sd);
2505 elm_genlist_item_selected_set(EO_OBJ(next), EINA_TRUE);
2511 _elm_genlist_item_focused(Elm_Object_Item *eo_it)
2513 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
2514 Evas_Object *obj = WIDGET(it);
2515 ELM_GENLIST_DATA_GET(obj, sd);
2516 const char *focus_raise;
2518 if (_is_no_select(it) ||
2519 (eo_it == sd->focused_item) ||
2520 (eo_do(eo_it, elm_wdg_item_disabled_get())))
2523 switch (_elm_config->focus_autoscroll_mode)
2525 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
2526 elm_genlist_item_show(eo_it,
2527 ELM_GENLIST_ITEM_SCROLLTO_IN);
2529 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
2530 elm_genlist_item_bring_in(eo_it,
2531 ELM_GENLIST_ITEM_SCROLLTO_IN);
2537 sd->focused_item = eo_it;
2539 if (elm_widget_focus_highlight_enabled_get(obj))
2540 edje_object_signal_emit(VIEW(it), SIGNAL_FOCUSED, "elm");
2542 focus_raise = edje_object_data_get(VIEW(it), "focusraise");
2543 if ((focus_raise) && (!strcmp(focus_raise, "on")))
2544 evas_object_raise(VIEW(it));
2545 evas_object_smart_callback_call(obj, SIG_ITEM_FOCUSED, eo_it);
2549 _elm_genlist_item_unfocused(Elm_Object_Item *eo_it)
2553 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
2554 Evas_Object *obj = WIDGET(it);
2555 ELM_GENLIST_DATA_GET(obj, sd);
2557 if (_is_no_select(it))
2560 if ((!sd->focused_item) ||
2561 (eo_it != sd->focused_item))
2564 if (elm_widget_focus_highlight_enabled_get(obj))
2566 ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focus_it);
2567 edje_object_signal_emit(VIEW(focus_it), SIGNAL_UNFOCUSED, "elm");
2570 sd->focused_item = NULL;
2571 evas_object_smart_callback_call(obj, SIG_ITEM_UNFOCUSED, eo_it);
2575 _item_focused_next(Evas_Object *obj, Elm_Focus_Direction dir)
2577 ELM_GENLIST_DATA_GET(obj, sd);
2579 Elm_Object_Item *eo_next;
2580 Elm_Object_Item *eo_first_item;
2581 Elm_Object_Item *eo_last_item;
2583 if (!sd->focused_item)
2585 if (dir == ELM_FOCUS_UP)
2586 next = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2587 else if (dir == ELM_FOCUS_DOWN)
2588 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2593 (!eo_do(EO_OBJ(next), elm_wdg_item_disabled_get())))
2594 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2598 ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focus_it);
2599 if (dir == ELM_FOCUS_UP)
2601 eo_first_item = elm_genlist_first_item_get(WIDGET(focus_it));
2602 if (eo_first_item == sd->focused_item) return EINA_FALSE;
2603 eo_next = elm_genlist_item_prev_get(sd->focused_item);
2604 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2606 while (eo_do(eo_next, elm_wdg_item_disabled_get()))
2608 eo_next = elm_genlist_item_prev_get(eo_next);
2609 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2612 else if (dir == ELM_FOCUS_DOWN)
2614 eo_last_item = elm_genlist_last_item_get(WIDGET(focus_it));
2615 if (eo_last_item == sd->focused_item) return EINA_FALSE;
2616 eo_next = elm_genlist_item_next_get(sd->focused_item);
2617 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2619 while (eo_do(eo_next, elm_wdg_item_disabled_get()))
2621 eo_next = elm_genlist_item_next_get(eo_next);
2622 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2628 if (!next) return EINA_FALSE;
2631 elm_object_item_focus_set(EO_OBJ(next), EINA_TRUE);
2637 _elm_genlist_item_content_focus_set(Elm_Gen_Item *it, Elm_Focus_Direction dir)
2639 Evas_Object *focused_obj = NULL;
2643 if (!GL_IT(it)->wsd->focus_on_selection_enabled) return;
2645 if (!it->item_focus_chain)
2647 elm_object_focus_set(VIEW(it), EINA_TRUE);
2651 EINA_LIST_FOREACH(it->item_focus_chain, l, focused_obj)
2652 if (elm_object_focus_get(focused_obj)) break;
2654 if (focused_obj && (dir != ELM_FOCUS_PREVIOUS))
2656 Evas_Object *nextfocus;
2657 if (elm_widget_focus_next_get(focused_obj, dir, &nextfocus))
2659 elm_object_focus_set(nextfocus, EINA_TRUE);
2664 if (!l) l = it->item_focus_chain;
2666 if (dir == ELM_FOCUS_RIGHT)
2668 l = eina_list_next(l);
2669 if (!l) l = it->item_focus_chain;
2671 else if (dir == ELM_FOCUS_LEFT)
2673 l = eina_list_prev(l);
2674 if (!l) l = eina_list_last(it->item_focus_chain);
2677 elm_object_focus_set(eina_list_data_get(l), EINA_TRUE);
2681 _key_action_move_dir(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool multi)
2683 ELM_GENLIST_DATA_GET(obj, sd);
2684 Elm_Object_Item *it = NULL;
2685 Eina_Bool ret = EINA_FALSE;
2688 Eina_Bool focus_only = EINA_FALSE;
2690 // get content size and viewport size
2692 elm_interface_scrollable_content_viewport_geometry_get
2693 (NULL, NULL, NULL, &v),
2694 elm_interface_scrollable_content_size_get(NULL, &min));
2696 if (_elm_config->item_select_on_focus_disable)
2698 ret = _item_focused_next(obj, dir);
2704 if (dir == ELM_FOCUS_UP)
2705 ret = _item_multi_select_up(sd);
2706 else if (dir == ELM_FOCUS_DOWN)
2707 ret = _item_multi_select_down(sd);
2711 if (dir == ELM_FOCUS_UP)
2712 ret = _item_single_select_up(sd);
2713 else if (dir == ELM_FOCUS_DOWN)
2714 ret = _item_single_select_down(sd);
2720 focus_only = _elm_config->item_select_on_focus_disable && elm_widget_focus_highlight_enabled_get(obj);
2721 // handle item loop feature
2722 if (sd->item_loop_enable && !sd->item_looping_on)
2726 if (dir == ELM_FOCUS_UP)
2728 elm_layout_signal_emit(obj, "elm,action,looping,up", "elm");
2729 sd->item_looping_on = EINA_TRUE;
2731 else if (dir == ELM_FOCUS_DOWN)
2733 elm_layout_signal_emit(obj, "elm,action,looping,down", "elm");
2734 sd->item_looping_on = EINA_TRUE;
2739 if (dir == ELM_FOCUS_UP)
2740 it = elm_genlist_last_item_get(obj);
2741 else if (dir == ELM_FOCUS_DOWN)
2742 it = elm_genlist_first_item_get(obj);
2744 if (it && focus_only)
2745 elm_object_item_focus_set(it, EINA_TRUE);
2747 elm_genlist_item_selected_set(it, EINA_TRUE);
2751 else if (sd->item_looping_on)
2758 _key_action_move(Evas_Object *obj, const char *params)
2760 ELM_GENLIST_DATA_GET(obj, sd);
2761 const char *dir = params;
2767 Evas_Coord step_x = 0;
2768 Evas_Coord step_y = 0;
2769 Evas_Coord page_x = 0;
2770 Evas_Coord page_y = 0;
2771 Elm_Object_Item *it = NULL;
2772 Evas_Coord pan_max_x = 0, pan_max_y = 0;
2775 elm_interface_scrollable_content_pos_get(&x, &y),
2776 elm_interface_scrollable_step_size_get(&step_x, &step_y),
2777 elm_interface_scrollable_page_size_get(&page_x, &page_y),
2778 elm_interface_scrollable_content_viewport_geometry_get
2779 (NULL, NULL, &v_w, &v_h));
2781 if (!strcmp(dir, "left"))
2785 Elm_Object_Item *eo_gt = elm_genlist_selected_item_get(obj);
2786 ELM_GENLIST_ITEM_DATA_GET(eo_gt, gt);
2787 _elm_genlist_item_content_focus_set(gt, ELM_FOCUS_LEFT);
2791 else if (!strcmp(dir, "right"))
2795 Elm_Object_Item *eo_gt = elm_genlist_selected_item_get(obj);
2796 ELM_GENLIST_ITEM_DATA_GET(eo_gt, gt);
2797 _elm_genlist_item_content_focus_set(gt, ELM_FOCUS_RIGHT);
2801 else if (!strcmp(dir, "up"))
2803 if (_key_action_move_dir(obj, ELM_FOCUS_UP, EINA_FALSE)) return EINA_TRUE;
2804 else return EINA_FALSE;
2806 else if (!strcmp(dir, "up_multi"))
2808 if (_key_action_move_dir(obj, ELM_FOCUS_UP, EINA_TRUE)) return EINA_TRUE;
2809 else if (_key_action_move_dir(obj, ELM_FOCUS_UP, EINA_FALSE)) return EINA_TRUE;
2810 else return EINA_FALSE;
2812 else if (!strcmp(dir, "down"))
2814 if (_key_action_move_dir(obj, ELM_FOCUS_DOWN, EINA_FALSE)) return EINA_TRUE;
2815 else return EINA_FALSE;
2817 else if (!strcmp(dir, "down_multi"))
2819 if (_key_action_move_dir(obj, ELM_FOCUS_DOWN, EINA_TRUE)) return EINA_TRUE;
2820 else if (_key_action_move_dir(obj, ELM_FOCUS_DOWN, EINA_FALSE)) return EINA_TRUE;
2821 else return EINA_FALSE;
2823 else if (!strcmp(dir, "first"))
2825 it = elm_genlist_first_item_get(obj);
2828 elm_genlist_item_selected_set(it, EINA_TRUE);
2832 else if (!strcmp(dir, "last"))
2834 it = elm_genlist_last_item_get(obj);
2837 elm_genlist_item_selected_set(it, EINA_TRUE);
2841 else if (!strcmp(dir, "prior"))
2844 y -= -(page_y * v_h) / 100;
2848 else if (!strcmp(dir, "next"))
2851 y += -(page_y * v_h) / 100;
2855 else return EINA_FALSE;
2857 eo_do(sd->pan_obj, elm_obj_pan_pos_max_get(&pan_max_x, &pan_max_y));
2859 if (x > pan_max_x) x = pan_max_x;
2861 if (y > pan_max_y) y = pan_max_y;
2863 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
2869 _key_action_select(Evas_Object *obj, const char *params EINA_UNUSED)
2871 Elm_Object_Item *eo_it = NULL;
2873 eo_it = elm_object_focused_item_get(obj);
2874 if (!eo_it) return EINA_TRUE;
2875 elm_genlist_item_expanded_set(eo_it, !elm_genlist_item_expanded_get(eo_it));
2876 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
2877 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, EO_OBJ(it));
2883 _key_action_escape(Evas_Object *obj, const char *params EINA_UNUSED)
2885 ELM_GENLIST_DATA_GET(obj, sd);
2887 if (!_all_items_deselect(sd)) return EINA_FALSE;
2891 EOLIAN static Eina_Bool
2892 _elm_genlist_elm_widget_event(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *src, Evas_Callback_Type type, void *event_info)
2895 Evas_Event_Key_Down *ev = event_info;
2897 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2898 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
2899 if (!sd->items) return EINA_FALSE;
2901 if (!_elm_config_key_binding_call(obj, ev, key_actions))
2904 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2908 /* This function disables the specific code of the layout sub object add.
2909 * Only the widget sub_object_add is called.
2911 EOLIAN static Eina_Bool
2912 _elm_genlist_elm_layout_sub_object_add_enable(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
2917 EOLIAN static Eina_Bool
2918 _elm_genlist_elm_widget_sub_object_add(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED, Evas_Object *sobj)
2920 Eina_Bool int_ret = EINA_FALSE;
2922 /* skipping layout's code, which registers size hint changing
2923 * callback on sub objects. this is here because items'
2924 * content_get() routines may change hints on the objects after
2925 * creation, thus issuing TOO MANY sizing_eval()'s here. they are
2926 * not needed at here anyway, so let's skip listening to those
2928 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_add(sobj));
2929 if (!int_ret) return EINA_FALSE;
2934 EOLIAN static Eina_Bool
2935 _elm_genlist_elm_widget_sub_object_del(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *sobj)
2937 Eina_Bool int_ret = EINA_FALSE;
2940 /* XXX: hack -- also skipping sizing recalculation on
2941 * sub-object-del. genlist's crazy code paths (like groups and
2942 * such) seem to issue a whole lot of deletions and Evas bitches
2943 * about too many recalculations */
2944 sd->on_sub_del = EINA_TRUE;
2946 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_del(sobj));
2947 if (!int_ret) return EINA_FALSE;
2949 sd->on_sub_del = EINA_FALSE;
2955 * This function searches the nearest visible item based on the given item.
2956 * If the given item is in the genlist viewport, this returns the given item.
2957 * Or this searches the realized items and checks the nearest fully visible item
2958 * according to the given item's position.
2960 static Elm_Object_Item *
2961 _elm_genlist_nearest_visible_item_get(Evas_Object *obj, Elm_Object_Item *eo_it)
2963 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0; // genlist viewport geometry
2964 Evas_Coord ix = 0, iy = 0, iw = 0, ih = 0; // given item geometry
2965 Evas_Coord cx = 0, cy = 0, cw = 0, ch = 0; // candidate item geometry
2966 Eina_List *item_list = NULL, *l = NULL;
2967 Elm_Object_Item *eo_item = NULL;
2968 ELM_GENLIST_DATA_GET(obj, sd);
2969 Eina_Bool search_next = EINA_FALSE;
2971 if (!eo_it) return NULL;
2972 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
2974 evas_object_geometry_get(sd->pan_obj, &vx, &vy, &vw, &vh);
2975 evas_object_geometry_get(VIEW(it), &ix, &iy, &iw, &ih); // FIXME: check if the item is realized or not
2977 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, ix, iy, iw, ih))
2979 if (!elm_object_item_disabled_get(eo_it))
2982 search_next = EINA_TRUE;
2985 item_list = elm_genlist_realized_items_get(obj);
2987 if ((iy < vy) || search_next)
2989 EINA_LIST_FOREACH(item_list, l, eo_item)
2991 ELM_GENLIST_ITEM_DATA_GET(eo_item, item);
2992 evas_object_geometry_get(VIEW(item), &cx, &cy, &cw, &ch);
2993 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, cx, cy, cw, ch) &&
2994 !elm_object_item_disabled_get(eo_item))
2996 eina_list_free(item_list);
3003 EINA_LIST_REVERSE_FOREACH(item_list, l, eo_item)
3005 ELM_GENLIST_ITEM_DATA_GET(eo_item, item);
3006 evas_object_geometry_get(VIEW(item), &cx, &cy, &cw, &ch);
3007 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, cx, cy, cw, ch) &&
3008 !elm_object_item_disabled_get(eo_item))
3010 eina_list_free(item_list);
3015 eina_list_free(item_list);
3020 EOLIAN static Eina_Bool
3021 _elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd)
3023 Eina_Bool int_ret = EINA_FALSE;
3024 Elm_Object_Item *eo_it = NULL;
3025 Eina_Bool is_sel = EINA_FALSE;
3027 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_on_focus());
3028 if (!int_ret) return EINA_FALSE;
3030 if (elm_widget_focus_get(obj) && (sd->items) && (sd->selected) &&
3031 (!sd->last_selected_item))
3033 sd->last_selected_item = eina_list_data_get(sd->selected);
3036 if (elm_widget_focus_get(obj) && !sd->mouse_down)
3038 if (sd->last_focused_item)
3039 eo_it = sd->last_focused_item;
3040 else if (sd->last_selected_item)
3041 eo_it = sd->last_selected_item;
3042 else if (_elm_config->first_item_focus_on_first_focus_in &&
3043 elm_widget_focus_highlight_enabled_get(obj))
3045 eo_it = elm_genlist_first_item_get(obj);
3051 eo_it = _elm_genlist_nearest_visible_item_get(obj, eo_it);
3054 if (!_elm_config->item_select_on_focus_disable && is_sel)
3055 elm_genlist_item_selected_set(eo_it, EINA_TRUE);
3057 elm_object_item_focus_set(eo_it, EINA_TRUE);
3058 _elm_widget_focus_highlight_start(obj);
3064 if (sd->focused_item)
3066 sd->last_focused_item = sd->focused_item;
3067 _elm_genlist_item_unfocused(sd->focused_item);
3074 static Eina_Bool _elm_genlist_smart_focus_next_enable = EINA_FALSE;
3076 EOLIAN static Eina_Bool
3077 _elm_genlist_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3079 return _elm_genlist_smart_focus_next_enable;
3082 EOLIAN static Eina_Bool
3083 _elm_genlist_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3088 EOLIAN static Eina_Bool
3089 _elm_genlist_elm_widget_focus_next(Eo *obj, Elm_Genlist_Data *sd, Elm_Focus_Direction dir, Evas_Object **next)
3091 Evas_Coord x, y, w, h;
3092 Evas_Coord sx, sy, sw, sh;
3094 Eina_List *items = NULL;
3095 Eina_Bool done = EINA_FALSE;
3097 evas_object_geometry_get(sd->obj, &sx, &sy, &sw, &sh);
3099 EINA_INLIST_FOREACH(sd->blocks, itb)
3107 EINA_LIST_FOREACH(itb->items, l, it)
3111 evas_object_geometry_get(it->base->view, &x, &y, &w, &h);
3113 /* check item which displays more than half of its size */
3114 if (it->base->access_obj &&
3116 (x + (w / 2), y + (h / 2), 0, 0, sx, sy, sw, sh))
3117 items = eina_list_append(items, it->base->access_obj);
3119 if (!it->base->access_order) continue;
3123 EINA_LIST_FOREACH(it->base->access_order, subl, subo)
3124 items = eina_list_append(items, subo);
3128 else if (done) break;
3131 return elm_widget_focus_list_next_get
3132 (obj, items, eina_list_data_get, dir, next);
3136 _mirrored_set(Evas_Object *obj,
3139 ELM_GENLIST_DATA_GET(obj, sd);
3141 _item_cache_zero(sd);
3142 eo_do(obj, elm_interface_scrollable_mirrored_set(rtl));
3145 EOLIAN static Eina_Bool
3146 _elm_genlist_elm_widget_theme_apply(Eo *obj, Elm_Genlist_Data *sd)
3149 Eina_Bool int_ret = EINA_FALSE;
3153 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
3154 if (!int_ret) return EINA_FALSE;
3156 evas_event_freeze(evas_object_evas_get(obj));
3157 _item_cache_zero(sd);
3158 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3160 sd->item_width = sd->item_height = 0;
3161 sd->group_item_width = sd->group_item_height = 0;
3162 sd->minw = sd->minh = sd->realminw = 0;
3164 EINA_INLIST_FOREACH(sd->blocks, itb)
3166 if (itb->realized) _item_block_unrealize(itb);
3167 EINA_LIST_FOREACH(itb->items, l, it)
3168 it->item->mincalcd = EINA_FALSE;
3170 itb->changed = EINA_TRUE;
3172 ecore_job_del(sd->calc_job);
3173 sd->calc_job = ecore_job_add(_calc_job, obj);
3174 elm_layout_sizing_eval(obj);
3175 evas_event_thaw(evas_object_evas_get(obj));
3176 evas_event_thaw_eval(evas_object_evas_get(obj));
3181 /* FIXME: take off later. maybe this show region coords belong in the
3182 * interface (new api functions, set/get)? */
3184 _show_region_hook(void *data EINA_UNUSED,
3187 Evas_Coord x, y, w, h;
3189 ELM_GENLIST_DATA_GET_OR_RETURN(obj, sd);
3191 elm_widget_show_region_get(obj, &x, &y, &w, &h);
3192 //x & y are screen coordinates, Add with pan coordinates
3195 eo_do(obj, elm_interface_scrollable_content_region_show(x, y, w, h));
3199 _item_highlight(Elm_Gen_Item *it)
3201 const char *selectraise;
3202 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3204 if (_is_no_select(it) ||
3206 (it->highlighted) || eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()) ||
3207 (it->item->deco_it_view))
3210 edje_object_signal_emit(VIEW(it), SIGNAL_SELECTED, "elm");
3211 if (it->deco_all_view)
3212 edje_object_signal_emit(it->deco_all_view, SIGNAL_SELECTED, "elm");
3213 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
3215 selectraise = edje_object_data_get(VIEW(it), "selectraise");
3216 if ((selectraise) && (!strcmp(selectraise, "on")))
3218 if (it->deco_all_view) evas_object_stack_below(it->deco_all_view, sd->stack[1]);
3219 else evas_object_stack_below(VIEW(it), sd->stack[1]);
3220 if ((it->item->group_item) && (it->item->group_item->realized))
3221 evas_object_stack_above(it->item->VIEW(group_item), sd->stack[1]);
3223 it->highlighted = EINA_TRUE;
3227 _item_unhighlight(Elm_Gen_Item *it)
3229 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3231 if (!it->highlighted) return;
3233 edje_object_signal_emit(VIEW(it), SIGNAL_UNSELECTED, "elm");
3234 evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, EO_OBJ(it));
3235 if (it->deco_all_view)
3236 edje_object_signal_emit
3237 (it->deco_all_view, SIGNAL_UNSELECTED, "elm");
3239 if (!it->item->nostacking)
3241 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
3243 if (it->deco_all_view) evas_object_stack_below(it->deco_all_view, sd->stack[0]);
3244 else evas_object_stack_below(VIEW(it), sd->stack[0]);
3248 if (it->deco_all_view) evas_object_stack_above(it->deco_all_view, sd->stack[0]);
3249 else evas_object_stack_above(VIEW(it), sd->stack[0]);
3252 it->highlighted = EINA_FALSE;
3256 _item_block_position_update(Eina_Inlist *list,
3261 EINA_INLIST_FOREACH(list, tmp)
3263 tmp->position = idx++;
3264 tmp->position_update = EINA_TRUE;
3269 _item_position_update(Eina_List *list,
3275 EINA_LIST_FOREACH(list, l, it)
3277 it->position = idx++;
3278 it->position_update = EINA_TRUE;
3283 _item_block_merge(Item_Block *left,
3289 EINA_LIST_FOREACH(right->items, l, it2)
3291 it2->item->block = left;
3293 left->changed = EINA_TRUE;
3295 left->items = eina_list_merge(left->items, right->items);
3299 _item_block_del(Elm_Gen_Item *it)
3302 Item_Block *itb = it->item->block;
3303 Eina_Bool block_changed = EINA_FALSE;
3304 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3306 itb->items = eina_list_remove(itb->items, it);
3308 itb->changed = EINA_TRUE;
3309 ecore_job_del(sd->calc_job);
3310 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
3315 il = EINA_INLIST_GET(itb);
3316 itbn = (Item_Block *)(il->next);
3318 it->parent->item->items =
3319 eina_list_remove(it->parent->item->items, EO_OBJ(it));
3322 _item_block_position_update(il->next, itb->position);
3323 sd->blocks = eina_inlist_remove(sd->blocks, il);
3326 if (itbn) itbn->changed = EINA_TRUE;
3330 if (itb->count < (sd->max_items_per_block / 2))
3335 il = EINA_INLIST_GET(itb);
3336 itbp = (Item_Block *)(il->prev);
3337 itbn = (Item_Block *)(il->next);
3339 /* merge block with previous */
3341 ((itbp->count + itb->count) <
3342 (sd->max_items_per_block +
3343 (sd->max_items_per_block / 2))))
3345 _item_block_merge(itbp, itb);
3346 _item_block_position_update
3347 (EINA_INLIST_GET(itb)->next, itb->position);
3348 sd->blocks = eina_inlist_remove
3349 (sd->blocks, EINA_INLIST_GET(itb));
3351 block_changed = EINA_TRUE;
3353 /* merge block with next */
3355 ((itbn->count + itb->count) <
3356 (sd->max_items_per_block +
3357 (sd->max_items_per_block / 2))))
3359 _item_block_merge(itb, itbn);
3360 _item_block_position_update
3361 (EINA_INLIST_GET(itbn)->next, itbn->position);
3363 eina_inlist_remove(sd->blocks, EINA_INLIST_GET(itbn));
3365 block_changed = EINA_TRUE;
3372 sd->pan_changed = EINA_TRUE;
3373 evas_object_smart_changed(sd->pan_obj);
3374 ecore_job_del(sd->calc_job);
3375 sd->calc_job = NULL;
3380 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3382 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3384 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3385 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
3386 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3387 _elm_genlist_item_position_state_update(it);
3388 _elm_genlist_item_state_update(it, NULL);
3390 if (it->item->wsd->reorder_mode)
3392 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
3393 edje_object_signal_emit(it->deco_all_view, SIGNAL_REORDER_MODE_UNSET,
3397 _view_clear(it->deco_all_view, &(GL_IT(it)->deco_all_texts),
3398 &(GL_IT(it)->deco_all_contents));
3400 edje_object_signal_emit(VIEW(it), SIGNAL_DECORATE_DISABLED, "elm");
3402 edje_object_message_signal_process(it->deco_all_view);
3403 _item_mouse_callbacks_del(it, it->deco_all_view);
3404 _item_mouse_callbacks_add(it, VIEW(it));
3406 ELM_SAFE_FREE(it->deco_all_view, evas_object_del);
3408 it->item->decorate_all_item_realized = EINA_FALSE;
3412 _elm_genlist_item_del_not_serious(Elm_Gen_Item *it)
3414 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3415 Elm_Object_Item *eo_it = EO_OBJ(it);
3417 eo_do(eo_it, elm_wdg_item_pre_notify_del());
3421 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
3422 if (sd->deselecting)
3423 sd->deselecting = eina_list_remove(sd->deselecting, it);
3425 if (sd->last_focused_item == eo_it)
3426 sd->last_focused_item = NULL;
3427 if (sd->focused_item == eo_it)
3428 sd->focused_item = NULL;
3429 if (sd->last_selected_item == eo_it)
3430 sd->last_selected_item = NULL;
3432 if (it->itc->func.del)
3433 it->itc->func.del((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it));
3437 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
3439 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3441 _elm_genlist_item_del_not_serious(it);
3443 //(it->walking == -1) means it's already removed from the list.
3444 if (it->walking != -1)
3445 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
3446 if (it->tooltip.del_cb)
3447 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
3448 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
3449 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
3450 sd->group_items = eina_list_remove(sd->group_items, it);
3452 ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
3453 ecore_job_del(sd->calc_job);
3454 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
3458 ELM_SAFE_FREE(it->item, free);
3462 _item_del(Elm_Gen_Item *it)
3464 Evas_Object *obj = WIDGET(it);
3465 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3467 evas_event_freeze(evas_object_evas_get(obj));
3471 it->item->rel->item->rel_revs =
3472 eina_list_remove(it->item->rel->item->rel_revs, it);
3474 if (it->item->rel_revs)
3477 EINA_LIST_FREE(it->item->rel_revs, tmp) tmp->item->rel = NULL;
3479 elm_genlist_item_subitems_clear(EO_OBJ(it));
3480 if (sd->show_item == it) sd->show_item = NULL;
3481 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
3482 if (it->item->decorate_all_item_realized) _decorate_all_item_unrealize(it);
3483 if (it->item->block) _item_block_del(it);
3484 if (it->item->queued)
3485 sd->queue = eina_list_remove(sd->queue, it);
3486 if (sd->anchor_item == it)
3488 sd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3489 if (!sd->anchor_item)
3491 ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3493 if (sd->expanded_item == it)
3495 if (sd->tree_effect_animator)
3497 _item_tree_effect_finish(sd);
3498 ELM_SAFE_FREE(sd->tree_effect_animator, ecore_animator_del);
3500 sd->expanded_item = NULL;
3501 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
3503 if (sd->expanded_next_item == it) sd->expanded_next_item = NULL;
3504 if (sd->move_items) sd->move_items = eina_list_remove(sd->move_items, it);
3506 it->parent->item->items = eina_list_remove(it->parent->item->items, EO_OBJ(it));
3507 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
3508 _elm_genlist_item_del_serious(it);
3509 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
3510 evas_event_thaw(evas_object_evas_get(obj));
3511 evas_event_thaw_eval(evas_object_evas_get(obj));
3512 if (!sd->queue) _item_scroll(sd);
3516 _item_unselect(Elm_Gen_Item *it)
3518 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3520 _item_unhighlight(it); /* unhighlight the item first */
3521 if (!it->selected) return; /* then check whether the item is selected */
3523 if (GL_IT(it)->wsd->focus_on_selection_enabled)
3527 EINA_LIST_FOREACH(it->item_focus_chain, l, eobj)
3528 elm_object_focus_set(eobj, EINA_FALSE);
3531 it->selected = EINA_FALSE;
3532 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
3533 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, EO_OBJ(it));
3537 _item_mouse_in_cb(void *data,
3538 Evas *evas EINA_UNUSED,
3539 Evas_Object *obj EINA_UNUSED,
3540 void *event_info EINA_UNUSED)
3542 Elm_Gen_Item *it = data;
3543 if (!elm_object_item_disabled_get(EO_OBJ(it)) &&
3544 (_elm_config->focus_move_policy == ELM_FOCUS_MOVE_POLICY_IN))
3545 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3549 _item_mouse_move_cb(void *data,
3550 Evas *evas EINA_UNUSED,
3554 Elm_Gen_Item *it = data;
3555 Evas_Event_Mouse_Move *ev = event_info;
3556 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
3557 Evas_Coord minw = 0, minh = 0, x, y, w, h, dx, dy, adx, ady;
3558 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3559 Elm_Object_Item *eo_it = EO_OBJ(it);
3561 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3565 sd->on_hold = EINA_TRUE;
3566 if ((!sd->wasselected) && (!it->flipped))
3570 if (sd->multi_touched)
3572 sd->cur_x = ev->cur.canvas.x;
3573 sd->cur_y = ev->cur.canvas.y;
3576 if ((it->dragging) && (it->down))
3578 if (sd->movements == SWIPE_MOVES)
3579 sd->swipe = EINA_TRUE;
3582 sd->history[sd->movements].x = ev->cur.canvas.x;
3583 sd->history[sd->movements].y = ev->cur.canvas.y;
3584 if (abs((sd->history[sd->movements].x -
3585 sd->history[0].x)) > 40)
3586 sd->swipe = EINA_TRUE;
3590 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
3591 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, eo_it);
3594 if ((!it->down) || (sd->longpressed))
3596 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
3597 if ((sd->reorder_mode) && (sd->reorder_it))
3599 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
3601 if (ev->cur.canvas.y < (oy + (sd->reorder_it->item->h / 2)))
3602 sd->reorder_fast = 1;
3603 else if (ev->cur.canvas.y > (oy + oh - (sd->reorder_it->item->h / 2)))
3604 sd->reorder_fast = -1;
3605 else sd->reorder_fast = 0;
3607 it_scrl_y = ev->cur.canvas.y - sd->reorder_it->dy;
3609 if (!sd->reorder_start_y)
3610 sd->reorder_start_y = it->item->block->y + it->y;
3614 else if (it_scrl_y + sd->reorder_it->item->h > oy + oh)
3615 y_pos = oy + oh - sd->reorder_it->item->h;
3619 if (it->deco_all_view)
3620 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
3622 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
3624 ecore_job_del(sd->calc_job);
3625 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
3629 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
3630 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
3632 evas_object_geometry_get(obj, &x, &y, &w, &h);
3633 x = ev->cur.canvas.x - x;
3634 y = ev->cur.canvas.y - y;
3637 if (adx < 0) adx = -dx;
3641 if (ady < 0) ady = -dy;
3646 // gah! annoying drag detection - leave this alone
3649 if (minw < h) minw = h;
3650 if (minh < h) minh = h;
3654 if (minw < w) minw = w;
3655 if (minh < w) minh = w;
3657 if (minw < 5) minw = 5;
3658 if (minh < 5) minh = 5;
3660 if ((adx > minw) || (ady > minh))
3662 it->dragging = EINA_TRUE;
3663 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
3664 if (!sd->wasselected)
3669 evas_object_smart_callback_call
3670 (WIDGET(it), SIG_DRAG_START_UP, eo_it);
3674 evas_object_smart_callback_call
3675 (WIDGET(it), SIG_DRAG_START_LEFT, eo_it);
3677 evas_object_smart_callback_call
3678 (WIDGET(it), SIG_DRAG_START_RIGHT, eo_it);
3684 evas_object_smart_callback_call
3685 (WIDGET(it), SIG_DRAG_START_DOWN, eo_it);
3689 evas_object_smart_callback_call
3690 (WIDGET(it), SIG_DRAG_START_LEFT, eo_it);
3692 evas_object_smart_callback_call
3693 (WIDGET(it), SIG_DRAG_START_RIGHT, eo_it);
3700 _long_press_cb(void *data)
3702 Elm_Gen_Item *it = data;
3703 Elm_Object_Item *eo_it_tmp;
3705 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3707 it->long_timer = NULL;
3708 if (_is_no_select(it) ||
3709 eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()) || (it->dragging))
3710 return ECORE_CALLBACK_CANCEL;
3712 sd->longpressed = EINA_TRUE;
3713 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, EO_OBJ(it));
3714 if ((sd->reorder_mode) && !(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP))
3716 sd->reorder_it = it;
3717 sd->reorder_start_y = 0;
3718 if (it->deco_all_view)
3719 evas_object_stack_below(it->deco_all_view, sd->stack[1]);
3721 evas_object_stack_below(VIEW(it), sd->stack[1]);
3723 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
3724 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
3725 (EINA_FALSE, EINA_FALSE));
3727 list = elm_genlist_realized_items_get
3729 EINA_LIST_FREE(list, eo_it_tmp)
3731 ELM_GENLIST_ITEM_DATA_GET(eo_it_tmp, it_tmp);
3732 if (it != it_tmp) _item_unselect(it_tmp);
3735 if (elm_genlist_item_expanded_get(EO_OBJ(it)))
3737 elm_genlist_item_expanded_set(EO_OBJ(it), EINA_FALSE);
3738 return ECORE_CALLBACK_RENEW;
3741 if (!sd->decorate_all_mode)
3742 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
3745 return ECORE_CALLBACK_CANCEL;
3749 _swipe_do(Elm_Gen_Item *it)
3752 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3754 if (_is_no_select(it) ||
3755 eo_do(EO_OBJ(it), elm_wdg_item_disabled_get())) return;
3757 sd->swipe = EINA_FALSE;
3758 for (i = 0; i < sd->movements; i++)
3760 sum += sd->history[i].x;
3761 if (abs(sd->history[0].y - sd->history[i].y) > 10)
3765 sum /= sd->movements;
3766 if (abs(sum - sd->history[0].x) <= 10) return;
3767 evas_object_smart_callback_call(WIDGET(it), SIG_SWIPE, EO_OBJ(it));
3771 _swipe_cancel(void *data)
3773 Elm_Gen_Item *it = data;
3774 if (!it) return ECORE_CALLBACK_CANCEL;
3775 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3777 sd->swipe = EINA_FALSE;
3780 return ECORE_CALLBACK_RENEW;
3784 _multi_cancel(void *data)
3786 ELM_GENLIST_DATA_GET(data, sd);
3788 if (!sd) return ECORE_CALLBACK_CANCEL;
3789 sd->multi_timeout = EINA_TRUE;
3791 return ECORE_CALLBACK_RENEW;
3795 _multi_touch_gesture_eval(Elm_Gen_Item *it)
3797 Evas_Coord minw = 0, minh = 0;
3798 Evas_Coord off_x, off_y, off_mx, off_my;
3799 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3800 Elm_Object_Item *eo_it = EO_OBJ(it);
3802 sd->multi_touched = EINA_FALSE;
3803 ELM_SAFE_FREE(sd->multi_timer, ecore_timer_del);
3804 if (sd->multi_timeout)
3806 sd->multi_timeout = EINA_FALSE;
3810 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
3811 off_x = abs(sd->cur_x - sd->prev_x);
3812 off_y = abs(sd->cur_y - sd->prev_y);
3813 off_mx = abs(sd->cur_mx - sd->prev_mx);
3814 off_my = abs(sd->cur_my - sd->prev_my);
3816 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw)
3817 || (off_my > minh)))
3819 if ((off_x + off_mx) > (off_y + off_my))
3821 if ((sd->cur_x > sd->prev_x) && (sd->cur_mx > sd->prev_mx))
3822 evas_object_smart_callback_call
3823 (WIDGET(it), SIG_MULTI_SWIPE_RIGHT, eo_it);
3824 else if ((sd->cur_x < sd->prev_x) && (sd->cur_mx < sd->prev_mx))
3825 evas_object_smart_callback_call
3826 (WIDGET(it), SIG_MULTI_SWIPE_LEFT, eo_it);
3827 else if (abs(sd->cur_x - sd->cur_mx) >
3828 abs(sd->prev_x - sd->prev_mx))
3829 evas_object_smart_callback_call
3830 (WIDGET(it), SIG_MULTI_PINCH_OUT, eo_it);
3832 evas_object_smart_callback_call
3833 (WIDGET(it), SIG_MULTI_PINCH_IN, eo_it);
3837 if ((sd->cur_y > sd->prev_y) && (sd->cur_my > sd->prev_my))
3838 evas_object_smart_callback_call
3839 (WIDGET(it), SIG_MULTI_SWIPE_DOWN, eo_it);
3840 else if ((sd->cur_y < sd->prev_y) && (sd->cur_my < sd->prev_my))
3841 evas_object_smart_callback_call
3842 (WIDGET(it), SIG_MULTI_SWIPE_UP, eo_it);
3843 else if (abs(sd->cur_y - sd->cur_my) >
3844 abs(sd->prev_y - sd->prev_my))
3845 evas_object_smart_callback_call
3846 (WIDGET(it), SIG_MULTI_PINCH_OUT, eo_it);
3848 evas_object_smart_callback_call
3849 (WIDGET(it), SIG_MULTI_PINCH_IN, eo_it);
3853 sd->multi_timeout = EINA_FALSE;
3857 _item_multi_down_cb(void *data,
3858 Evas *evas EINA_UNUSED,
3859 Evas_Object *obj EINA_UNUSED,
3862 Elm_Gen_Item *it = data;
3863 Evas_Event_Multi_Down *ev = event_info;
3864 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3866 if ((sd->multi_device != 0) || (sd->multi_touched)
3867 || (sd->multi_timeout))
3870 sd->multi_device = ev->device;
3871 sd->multi_down = EINA_TRUE;
3872 sd->multi_touched = EINA_TRUE;
3873 sd->prev_mx = ev->canvas.x;
3874 sd->prev_my = ev->canvas.y;
3875 if (!sd->wasselected) _item_unselect(it);
3876 sd->wasselected = EINA_FALSE;
3877 sd->longpressed = EINA_FALSE;
3878 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
3881 it->dragging = EINA_FALSE;
3882 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, EO_OBJ(it));
3884 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
3887 sd->swipe = EINA_FALSE;
3889 sd->on_hold = EINA_FALSE;
3894 _item_multi_up_cb(void *data,
3895 Evas *evas EINA_UNUSED,
3896 Evas_Object *obj EINA_UNUSED,
3899 Elm_Gen_Item *it = data;
3900 Evas_Event_Multi_Up *ev = event_info;
3901 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3903 if (sd->multi_device != ev->device) return;
3904 sd->multi_device = 0;
3905 sd->multi_down = EINA_FALSE;
3906 if (sd->mouse_down) return;
3907 _multi_touch_gesture_eval(data);
3911 _item_multi_move_cb(void *data,
3912 Evas *evas EINA_UNUSED,
3913 Evas_Object *obj EINA_UNUSED,
3916 Elm_Gen_Item *it = data;
3917 Evas_Event_Multi_Move *ev = event_info;
3918 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3920 if (sd->multi_device != ev->device) return;
3921 sd->cur_mx = ev->cur.canvas.x;
3922 sd->cur_my = ev->cur.canvas.y;
3926 _item_mouse_down_cb(void *data,
3927 Evas *evas EINA_UNUSED,
3931 Evas_Event_Mouse_Down *ev = event_info;
3932 Elm_Gen_Item *it = data;
3934 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3935 Elm_Object_Item *eo_it = EO_OBJ(it);
3937 if (ev->button == 3)
3939 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3940 it->dx = ev->canvas.x - x;
3941 it->dy = ev->canvas.y - y;
3944 if (ev->button != 1) return;
3945 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3947 sd->on_hold = EINA_TRUE;
3950 it->down = EINA_TRUE;
3951 it->dragging = EINA_FALSE;
3952 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3953 it->dx = ev->canvas.x - x;
3954 it->dy = ev->canvas.y - y;
3955 sd->mouse_down = EINA_TRUE;
3956 if (!sd->multi_touched)
3958 sd->prev_x = ev->canvas.x;
3959 sd->prev_y = ev->canvas.y;
3960 sd->multi_timeout = EINA_FALSE;
3961 ecore_timer_del(sd->multi_timer);
3962 sd->multi_timer = ecore_timer_add(MULTI_DOWN_TIME, _multi_cancel, sd->obj);
3964 sd->longpressed = EINA_FALSE;
3965 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = EINA_TRUE;
3966 else sd->on_hold = EINA_FALSE;
3967 if (sd->on_hold) return;
3968 sd->wasselected = it->selected;
3970 ecore_timer_del(it->item->swipe_timer);
3971 it->item->swipe_timer = ecore_timer_add(SWIPE_TIME, _swipe_cancel, it);
3972 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
3974 it->long_timer = ecore_timer_add
3975 (sd->longpress_timeout, _long_press_cb, it);
3977 it->long_timer = NULL;
3978 sd->swipe = EINA_FALSE;
3981 if (_is_no_select(it) ||
3982 eo_do((Eo *)eo_it, elm_wdg_item_disabled_get()))
3985 // and finally call the user callbacks.
3986 // NOTE: keep this code at the bottom, as the user can change the
3987 // list at this point (clear, delete, etc...)
3988 _item_highlight(it);
3989 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
3991 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, eo_it);
3992 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, eo_it);
3994 evas_object_smart_callback_call(WIDGET(it), SIG_PRESSED, eo_it);
3998 _item_block_new(Elm_Genlist_Data *sd,
4003 itb = calloc(1, sizeof(Item_Block));
4004 if (!itb) return NULL;
4008 sd->blocks = eina_inlist_prepend(sd->blocks, EINA_INLIST_GET(itb));
4009 _item_block_position_update(sd->blocks, 0);
4013 sd->blocks = eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4014 itb->position_update = EINA_TRUE;
4015 if (sd->blocks != EINA_INLIST_GET(itb))
4018 ((Item_Block *)(EINA_INLIST_GET(itb)->prev))->position + 1;
4032 * This function adds an item to a block's item list. This may or may not
4033 * rearrange existing blocks and create a new block.
4037 _item_block_add(Elm_Genlist_Data *sd,
4040 Item_Block *itb = NULL;
4042 // when a new item does not depend on another item
4048 itb = calloc(1, sizeof(Item_Block));
4049 if (!itb) return EINA_FALSE;
4051 if (!it->item->rel->item->block)
4054 eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4055 itb->items = eina_list_append(itb->items, it);
4056 itb->position_update = EINA_TRUE;
4057 it->position = eina_list_count(itb->items);
4058 it->position_update = EINA_TRUE;
4060 if (sd->blocks != EINA_INLIST_GET(itb))
4064 (EINA_INLIST_GET(itb)->prev))->position + 1;
4075 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4076 if (it->item->before)
4078 sd->blocks = eina_inlist_prepend_relative
4079 (sd->blocks, EINA_INLIST_GET(itb),
4080 EINA_INLIST_GET(it->item->rel->item->block));
4082 eina_list_prepend_relative_list(itb->items, it, tmp);
4084 /* Update index from where we prepended */
4085 _item_position_update
4086 (eina_list_prev(tmp), it->item->rel->position);
4087 _item_block_position_update
4088 (EINA_INLIST_GET(itb),
4089 it->item->rel->item->block->position);
4093 sd->blocks = eina_inlist_append_relative
4094 (sd->blocks, EINA_INLIST_GET(itb),
4095 EINA_INLIST_GET(it->item->rel->item->block));
4097 eina_list_append_relative_list(itb->items, it, tmp);
4099 /* Update block index from where we appended */
4100 _item_position_update
4101 (eina_list_next(tmp), it->item->rel->position + 1);
4102 _item_block_position_update
4103 (EINA_INLIST_GET(itb),
4104 it->item->rel->item->block->position + 1);
4110 // item move_before, prepend, insert_before, sorted_insert with before
4111 if (it->item->before)
4115 itb = (Item_Block *)(sd->blocks);
4116 if (itb->count >= sd->max_items_per_block)
4118 itb = _item_block_new(sd, EINA_TRUE);
4119 if (!itb) return EINA_FALSE;
4124 itb = _item_block_new(sd, EINA_TRUE);
4125 if (!itb) return EINA_FALSE;
4127 itb->items = eina_list_prepend(itb->items, it);
4129 _item_position_update(itb->items, 0);
4131 // item move_after, append, insert_after, sorted_insert without before
4136 itb = (Item_Block *)(sd->blocks->last);
4137 if (itb->count >= sd->max_items_per_block)
4139 itb = _item_block_new(sd, EINA_FALSE);
4140 if (!itb) return EINA_FALSE;
4145 itb = _item_block_new(sd, EINA_FALSE);
4146 if (!itb) return EINA_FALSE;
4148 itb->items = eina_list_append(itb->items, it);
4149 it->position = eina_list_count(itb->items);
4153 // when a new item depends on another item
4158 if (it->item->rel->item->queued)
4160 /* NOTE: for a strange reason eina_list and eina_inlist
4161 don't have the same property on sorted insertion
4162 order, so the queue is not always ordered like the
4163 item list. This lead to issue where we depend on an
4164 item that is not yet created. As a quick work around,
4165 we reschedule the calc of the item and stop reordering
4166 the list to prevent any nasty issue to show up here.
4168 sd->queue = eina_list_append(sd->queue, it);
4169 sd->requeued = EINA_TRUE;
4170 it->item->queued = EINA_TRUE;
4174 itb = it->item->rel->item->block;
4175 if (!itb) goto newblock;
4176 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4177 if (it->item->before)
4179 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4180 _item_position_update
4181 (eina_list_prev(tmp), it->item->rel->position);
4185 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4186 _item_position_update
4187 (eina_list_next(tmp), it->item->rel->position + 1);
4192 itb->changed = EINA_TRUE;
4193 it->item->block = itb;
4194 ecore_job_del(itb->sd->calc_job);
4195 itb->sd->calc_job = ecore_job_add(_calc_job, itb->sd->obj);
4197 if (itb->count > itb->sd->max_items_per_block)
4202 Eina_Bool done = EINA_FALSE;
4204 newc = itb->count / 2;
4206 if (EINA_INLIST_GET(itb)->prev)
4208 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4210 if (itbp->count + newc < sd->max_items_per_block / 2)
4212 /* moving items to previous block */
4213 while ((itb->count > newc) && (itb->items))
4215 it2 = eina_list_data_get(itb->items);
4216 itb->items = eina_list_remove_list
4217 (itb->items, itb->items);
4220 itbp->items = eina_list_append(itbp->items, it2);
4221 it2->item->block = itbp;
4229 if (!done && EINA_INLIST_GET(itb)->next)
4231 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4233 if (itbn->count + newc < sd->max_items_per_block / 2)
4235 /* moving items to next block */
4236 while ((itb->count > newc) && (itb->items))
4240 l = eina_list_last(itb->items);
4241 it2 = eina_list_data_get(l);
4242 itb->items = eina_list_remove_list(itb->items, l);
4245 itbn->items = eina_list_prepend(itbn->items, it2);
4246 it2->item->block = itbn;
4256 /* moving items to new block */
4257 itb2 = calloc(1, sizeof(Item_Block));
4258 if (!itb2) return EINA_FALSE;
4261 eina_inlist_append_relative(sd->blocks, EINA_INLIST_GET(itb2),
4262 EINA_INLIST_GET(itb));
4263 itb2->changed = EINA_TRUE;
4264 while ((itb->count > newc) && (itb->items))
4268 l = eina_list_last(itb->items);
4270 itb->items = eina_list_remove_list(itb->items, l);
4273 itb2->items = eina_list_prepend(itb2->items, it2);
4274 it2->item->block = itb2;
4284 _item_process(Elm_Genlist_Data *sd,
4287 if (!_item_block_add(sd, it)) return EINA_TRUE;
4289 _item_block_realize(it->item->block);
4295 _item_process_post(Elm_Genlist_Data *sd,
4299 Eina_Bool show_me = EINA_FALSE;
4301 if (it->item->block->changed)
4303 show_me = _item_block_recalc
4304 (it->item->block, it->item->block->num, qadd);
4305 it->item->block->changed = 0;
4306 if (sd->pan_changed)
4308 ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
4310 sd->pan_changed = EINA_FALSE;
4313 if (show_me) it->item->block->show_me = EINA_TRUE;
4315 /* when prepending, move the scroller along with the first selected
4316 * item to create the illusion that we're watching the selected
4317 * item this prevents the selected item being scrolled off the
4320 if (sd->selected && it->item->before)
4323 Elm_Object_Item *eo_it2;
4325 eo_it2 = sd->selected->data;
4326 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
4327 if (!it2->item->block) return;
4328 eo_do(sd->obj, elm_interface_scrollable_content_pos_get(NULL, &y));
4329 evas_object_geometry_get(sd->pan_obj, NULL, NULL, NULL, &h);
4330 if ((it->y + it->item->block->y > y + h) ||
4331 (it->y + it->item->block->y + it->item->h < y))
4332 /* offscreen, just update */
4333 eo_do(sd->obj, elm_interface_scrollable_content_region_show
4334 (it2->x + it2->item->block->x, y,
4335 it2->item->block->w, h));
4337 eo_do(sd->obj, elm_interface_scrollable_content_region_show
4338 (it->x + it->item->block->x,
4339 y + it->item->h, it->item->block->w, h));
4344 _queue_process(Elm_Genlist_Data *sd)
4349 t0 = ecore_time_get();
4350 for (n = 0; (sd->queue) && (n < 128); n++)
4354 it = eina_list_data_get(sd->queue);
4355 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
4356 it->item->queued = EINA_FALSE;
4357 if (_item_process(sd, it)) continue;
4358 t = ecore_time_get();
4359 _item_process_post(sd, it, EINA_TRUE);
4360 /* same as eina_inlist_count > 1 */
4361 if (sd->blocks && sd->blocks->next)
4363 if ((t - t0) > (ecore_animator_frametime_get())) break;
4366 if (!sd->queue) _item_scroll(sd);
4371 _idle_process(void *data,
4374 Elm_Genlist_Data *sd = data;
4376 if (_queue_process(sd) > 0) *wakeup = EINA_TRUE;
4379 return ECORE_CALLBACK_CANCEL;
4381 return ECORE_CALLBACK_RENEW;
4385 _item_idle_enterer(void *data)
4387 Eina_Bool wakeup = EINA_FALSE;
4388 ELM_GENLIST_DATA_GET(data, sd);
4389 Eina_Bool ok = _idle_process(sd, &wakeup);
4394 ecore_job_del(sd->calc_job);
4395 sd->calc_job = ecore_job_add(_calc_job, data);
4397 if (ok == ECORE_CALLBACK_CANCEL) sd->queue_idle_enterer = NULL;
4403 _requeue_idle_enterer(Elm_Genlist_Data *sd)
4405 ecore_idle_enterer_del(sd->queue_idle_enterer);
4406 sd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, sd->obj);
4410 _item_queue(Elm_Genlist_Data *sd,
4416 if (it->item->queued) return;
4417 it->item->queued = EINA_TRUE;
4418 if (cb && !sd->requeued)
4419 sd->queue = eina_list_sorted_insert(sd->queue, cb, it);
4421 sd->queue = eina_list_append(sd->queue, it);
4422 // FIXME: why does a freeze then thaw here cause some genlist
4423 // elm_genlist_item_append() to be much much slower?
4424 // evas_event_freeze(evas_object_evas_get(sd->obj));
4425 while ((sd->queue) && ((!sd->blocks) || (!sd->blocks->next)))
4427 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
4430 while ((sd->queue) && (sd->blocks) &&
4431 (sd->homogeneous) && (sd->mode == ELM_LIST_COMPRESS))
4433 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
4437 // evas_event_thaw(evas_object_evas_get(sd->obj));
4438 // evas_event_thaw_eval(evas_object_evas_get(sd->obj));
4439 evas_object_geometry_get(sd->obj, NULL, NULL, &w, NULL);
4440 if (w > 0) _requeue_idle_enterer(sd);
4443 /* If the application wants to know the relative item, use
4444 * elm_genlist_item_prev_get(it)*/
4446 _item_move_after(Elm_Gen_Item *it,
4447 Elm_Gen_Item *after)
4451 if (it == after) return;
4452 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4455 eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
4456 if (it->item->block) _item_block_del(it);
4458 sd->items = eina_inlist_append_relative
4459 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4461 it->item->rel->item->rel_revs =
4462 eina_list_remove(it->item->rel->item->rel_revs, it);
4463 it->item->rel = after;
4464 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
4465 it->item->before = EINA_FALSE;
4466 if (after->item->group_item) it->item->group_item = after->item->group_item;
4467 _item_queue(sd, it, NULL);
4469 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, EO_OBJ(it));
4473 _access_activate_cb(void *data EINA_UNUSED,
4474 Evas_Object *part_obj EINA_UNUSED,
4475 Elm_Object_Item *eo_it)
4477 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
4480 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4487 _item_highlight(it);
4497 while (sd->selected)
4499 Elm_Object_Item *eo_sel = sd->selected->data;
4500 Elm_Gen_Item *sel = eo_data_scope_get(eo_sel, ELM_GENLIST_ITEM_CLASS);
4501 _item_unselect(sel);
4506 const Eina_List *l, *l_next;
4507 Elm_Object_Item *eo_it2;
4509 EINA_LIST_FOREACH_SAFE(sd->selected, l, l_next, eo_it2)
4511 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
4513 _item_unselect(it2);
4516 _item_highlight(it);
4521 /* If the application wants to know the relative item, use
4522 * elm_genlist_item_next_get(it)*/
4524 _item_move_before(Elm_Gen_Item *it,
4525 Elm_Gen_Item *before)
4528 if (!before) return;
4529 if (it == before) return;
4530 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4533 eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
4534 if (it->item->block) _item_block_del(it);
4535 sd->items = eina_inlist_prepend_relative
4536 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4538 it->item->rel->item->rel_revs =
4539 eina_list_remove(it->item->rel->item->rel_revs, it);
4540 it->item->rel = before;
4541 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
4542 it->item->before = EINA_TRUE;
4543 if (before->item->group_item)
4544 it->item->group_item = before->item->group_item;
4545 _item_queue(sd, it, NULL);
4547 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, EO_OBJ(it));
4551 _item_mouse_up_cb(void *data,
4552 Evas *evas EINA_UNUSED,
4553 Evas_Object *obj EINA_UNUSED,
4556 Evas_Event_Mouse_Up *ev = event_info;
4557 Eina_Bool dragged = EINA_FALSE;
4558 Elm_Gen_Item *it = data;
4559 Evas_Coord x, y, dx, dy;
4561 if ((ev->button == 3) && (!it->dragging))
4563 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4564 dx = it->dx - (ev->canvas.x - x);
4565 dy = it->dy - (ev->canvas.y - y);
4566 if (dx < 0) dx = -dx;
4567 if (dy < 0) dy = -dy;
4568 if ((dx < 5) && (dy < 5))
4569 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_RIGHT, EO_OBJ(it));
4573 if (ev->button != 1) return;
4574 it->down = EINA_FALSE;
4575 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4577 sd->mouse_down = EINA_FALSE;
4578 evas_object_smart_callback_call(WIDGET(it), SIG_RELEASED, EO_OBJ(it));
4579 if (sd->multi_touched)
4581 if ((!sd->multi) && (!it->selected) && (it->highlighted))
4582 _item_unhighlight(it);
4583 if (sd->multi_down) return;
4584 _multi_touch_gesture_eval(it);
4587 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4588 sd->on_hold = EINA_TRUE;
4589 else sd->on_hold = EINA_FALSE;
4590 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4593 it->dragging = EINA_FALSE;
4594 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, EO_OBJ(it));
4597 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
4598 if (sd->multi_timer)
4600 ELM_SAFE_FREE(sd->multi_timer, ecore_timer_del);
4601 sd->multi_timeout = EINA_FALSE;
4605 if (sd->swipe) _swipe_do(it);
4606 sd->longpressed = EINA_FALSE;
4607 sd->on_hold = EINA_FALSE;
4610 if ((sd->reorder_mode) && (sd->reorder_it))
4612 Evas_Coord it_scrl_y = ev->canvas.y - sd->reorder_it->dy;
4613 sd->reorder_fast = 0;
4615 if (sd->reorder_rel &&
4616 (sd->reorder_it->parent == sd->reorder_rel->parent))
4618 if (it_scrl_y <= sd->reorder_rel->item->scrl_y)
4619 _item_move_before(sd->reorder_it, sd->reorder_rel);
4621 _item_move_after(sd->reorder_it, sd->reorder_rel);
4622 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
4626 ecore_job_del(sd->calc_job);
4627 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
4629 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_DISABLED, "elm");
4630 sd->reorder_it = sd->reorder_rel = NULL;
4631 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
4632 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
4633 (sd->h_bounce, sd->v_bounce));
4635 if (sd->longpressed)
4637 sd->longpressed = EINA_FALSE;
4638 if ((!sd->wasselected) && (!it->flipped))
4640 sd->wasselected = EINA_FALSE;
4645 if (it->want_unrealize)
4647 _elm_genlist_item_unrealize(it, EINA_FALSE);
4648 if (it->item->block->want_unrealize)
4649 _item_block_unrealize(it->item->block);
4653 if (_is_no_select(it) ||
4654 (eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()) || (dragged)))
4657 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
4659 evas_object_ref(sd->obj);
4662 ((sd->multi_select_mode != ELM_OBJECT_MULTI_SELECT_MODE_WITH_CONTROL) ||
4663 (evas_key_modifier_is_set(ev->modifiers, "Control"))))
4667 _item_highlight(it);
4668 if (_item_select(it)) goto deleted;
4677 while (sd->selected)
4679 Elm_Object_Item *eo_sel = sd->selected->data;
4680 Elm_Gen_Item *sel = eo_data_scope_get(eo_sel, ELM_GENLIST_ITEM_CLASS);
4681 _item_unselect(sel);
4686 const Eina_List *l, *l_next;
4687 Elm_Object_Item *eo_it2;
4689 EINA_LIST_FOREACH_SAFE(sd->selected, l, l_next, eo_it2)
4691 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
4693 _item_unselect(it2);
4696 _item_highlight(it);
4697 if (_item_select(it)) goto deleted;
4700 if (sd->focused_item != EO_OBJ(it))
4701 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
4704 evas_object_unref(sd->obj);
4708 _item_mouse_callbacks_add(Elm_Gen_Item *it,
4711 evas_object_event_callback_add
4712 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
4713 evas_object_event_callback_add
4714 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4715 evas_object_event_callback_add
4716 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
4717 evas_object_event_callback_add
4718 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
4719 evas_object_event_callback_add
4720 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
4721 evas_object_event_callback_add
4722 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
4723 evas_object_event_callback_add
4724 (view, EVAS_CALLBACK_MOUSE_IN, _item_mouse_in_cb, it);
4728 _item_mouse_callbacks_del(Elm_Gen_Item *it,
4731 evas_object_event_callback_del_full
4732 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
4733 evas_object_event_callback_del_full
4734 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
4735 evas_object_event_callback_del_full
4736 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
4737 evas_object_event_callback_del_full
4738 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
4739 evas_object_event_callback_del_full
4740 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
4741 evas_object_event_callback_del_full
4742 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
4743 evas_object_event_callback_del_full
4744 (view, EVAS_CALLBACK_MOUSE_IN, _item_mouse_in_cb, it);
4748 _scroll_hold_timer_cb(void *data)
4750 ELM_GENLIST_DATA_GET(data, sd);
4752 if (!data) return ECORE_CALLBACK_CANCEL;
4754 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
4755 sd->scr_hold_timer = NULL;
4757 return ECORE_CALLBACK_CANCEL;
4761 _decorate_item_unrealize(Elm_Gen_Item *it)
4763 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4764 Evas_Object *obj = sd->obj;
4766 if (!it->item->deco_it_view) return;
4768 evas_event_freeze(evas_object_evas_get(obj));
4770 _view_clear(GL_IT(it)->deco_it_view, &(GL_IT(it)->deco_it_texts),
4771 &(GL_IT(it)->deco_it_contents));
4773 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
4774 evas_object_smart_member_add(VIEW(it), sd->pan_obj);
4775 ELM_SAFE_FREE(it->item->deco_it_view, evas_object_del);
4777 if (sd->mode_item == it)
4778 sd->mode_item = NULL;
4779 evas_event_thaw(evas_object_evas_get(obj));
4780 evas_event_thaw_eval(evas_object_evas_get(obj));
4784 _decorate_item_finished_signal_cb(void *data,
4786 const char *emission EINA_UNUSED,
4787 const char *source EINA_UNUSED)
4789 Elm_Gen_Item *it = data;
4793 if (!it || !obj) return;
4794 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4796 te = evas_object_evas_get(obj);
4798 if ((!it->realized) || (!it->item->deco_it_view)) return;
4800 evas_event_freeze(te);
4801 it->item->nocache_once = EINA_FALSE;
4802 _decorate_item_unrealize(it);
4803 if (it->item->group_item)
4804 evas_object_stack_above(it->item->VIEW(group_item), sd->stack[1]);
4806 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished",
4807 sd->decorate_it_type);
4808 edje_object_signal_callback_del_full
4809 (obj, buf, "elm", _decorate_item_finished_signal_cb, it);
4810 evas_event_thaw(te);
4811 evas_event_thaw_eval(te);
4815 _item_unrealize(Elm_Gen_Item *it)
4817 Evas_Object *content;
4818 EINA_LIST_FREE(it->item->flip_contents, content)
4819 evas_object_del(content);
4822 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
4823 _elm_access_widget_item_unregister(it->base);
4825 // unswallow VIEW(it) first then manipulate VIEW(it)
4826 _decorate_item_unrealize(it);
4827 if (GL_IT(it)->wsd->decorate_all_mode) _decorate_all_item_unrealize(it);
4829 if (it->item->nocache_once || it->item->nocache)
4831 ELM_SAFE_FREE(VIEW(it), evas_object_del);
4832 ELM_SAFE_FREE(it->spacer, evas_object_del);
4836 edje_object_mirrored_set(VIEW(it),
4837 elm_widget_mirrored_get(WIDGET(it)));
4838 edje_object_scale_set(VIEW(it),
4839 elm_widget_scale_get(WIDGET(it))
4840 * elm_config_scale_get());
4841 _item_cache_add(it);
4845 it->realized = EINA_FALSE;
4846 it->want_unrealize = EINA_FALSE;
4850 _item_block_recalc(Item_Block *itb,
4856 Evas_Coord minw = 0, minh = 0;
4857 Eina_Bool show_me = EINA_FALSE, changed = EINA_FALSE;
4859 Elm_Genlist_Data *sd = NULL;
4862 EINA_LIST_FOREACH(itb->items, l, it)
4864 sd = GL_IT(it)->wsd;
4865 show_me |= it->item->show_me;
4868 if (qadd || (itb->sd->homogeneous &&
4869 (((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) &&
4870 (!itb->sd->group_item_height)) ||
4871 (!(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) &&
4872 (!itb->sd->item_height)))))
4874 if (!it->item->mincalcd) changed = EINA_TRUE;
4877 Eina_Bool doit = EINA_TRUE;
4879 if (itb->sd->homogeneous)
4881 if ((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) &&
4882 (itb->sd->group_item_height == 0))
4884 else if (itb->sd->item_height == 0)
4891 _item_realize(it, in, EINA_TRUE);
4892 _elm_genlist_item_unrealize(it, EINA_TRUE);
4896 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
4898 it->item->w = it->item->minw =
4899 sd->group_item_width;
4900 it->item->h = it->item->minh =
4901 sd->group_item_height;
4905 it->item->w = it->item->minw =
4907 it->item->h = it->item->minh =
4910 it->item->mincalcd = EINA_TRUE;
4916 if ((itb->sd->homogeneous) &&
4917 (itb->sd->mode == ELM_LIST_COMPRESS))
4919 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
4921 it->item->w = it->item->minw =
4922 sd->group_item_width;
4923 it->item->h = it->item->minh =
4924 sd->group_item_height;
4928 it->item->w = it->item->minw =
4930 it->item->h = it->item->minh =
4933 it->item->mincalcd = EINA_TRUE;
4937 _item_realize(it, in, EINA_TRUE);
4938 _elm_genlist_item_unrealize(it, EINA_TRUE);
4944 if (!it->item->mincalcd) changed = EINA_TRUE;
4945 _item_realize(it, in, EINA_FALSE);
4947 minh += it->item->minh;
4948 if (minw < it->item->minw) minw = it->item->minw;
4954 if (changed) itb->sd->pan_changed = changed;
4957 itb->changed = EINA_FALSE;
4958 itb->position_update = EINA_FALSE;
4964 _update_job(void *data)
4966 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
4967 ELM_GENLIST_DATA_GET(data, sd);
4972 sd->update_job = NULL;
4975 evas_event_freeze(evas_object_evas_get(sd->obj));
4976 EINA_INLIST_FOREACH(sd->blocks, itb)
4978 Evas_Coord itminw, itminh;
4985 _item_block_position(itb, num);
4989 recalc = EINA_FALSE;
4990 EINA_LIST_FOREACH(itb->items, l2, it)
4992 if (it->item->updateme)
4994 itminw = it->item->minw;
4995 itminh = it->item->minh;
4997 it->item->updateme = EINA_FALSE;
5000 _elm_genlist_item_unrealize(it, EINA_FALSE);
5001 _item_realize(it, num, EINA_FALSE);
5002 position = EINA_TRUE;
5006 _item_realize(it, num, EINA_TRUE);
5007 _elm_genlist_item_unrealize(it, EINA_TRUE);
5009 if ((it->item->minw != itminw) || (it->item->minh != itminh))
5014 itb->updateme = EINA_FALSE;
5017 position = EINA_TRUE;
5018 itb->changed = EINA_TRUE;
5019 _item_block_recalc(itb, num0, EINA_FALSE);
5020 _item_block_position(itb, num0);
5025 ecore_job_del(sd->calc_job);
5026 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
5028 evas_event_thaw(evas_object_evas_get(sd->obj));
5029 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
5033 _scroll_animate_start_cb(Evas_Object *obj,
5034 void *data EINA_UNUSED)
5036 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
5040 _scroll_animate_stop_cb(Evas_Object *obj,
5041 void *data EINA_UNUSED)
5043 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
5047 _scroll_drag_start_cb(Evas_Object *obj,
5048 void *data EINA_UNUSED)
5050 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
5054 _scroll_cb(Evas_Object *obj,
5055 void *data EINA_UNUSED)
5057 evas_object_smart_callback_call(obj, SIG_SCROLL, NULL);
5061 _scroll_drag_stop_cb(Evas_Object *obj,
5062 void *data EINA_UNUSED)
5064 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_STOP, NULL);
5068 _edge_left_cb(Evas_Object *obj,
5069 void *data EINA_UNUSED)
5071 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
5075 _edge_right_cb(Evas_Object *obj,
5076 void *data EINA_UNUSED)
5078 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
5082 _edge_top_cb(Evas_Object *obj,
5083 void *data EINA_UNUSED)
5085 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
5089 _edge_bottom_cb(Evas_Object *obj,
5090 void *data EINA_UNUSED)
5092 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
5096 _vbar_drag_cb(Evas_Object *obj,
5097 void *data EINA_UNUSED)
5099 evas_object_smart_callback_call(obj, SIG_VBAR_DRAG, NULL);
5103 _vbar_press_cb(Evas_Object *obj,
5104 void *data EINA_UNUSED)
5106 evas_object_smart_callback_call(obj, SIG_VBAR_PRESS, NULL);
5110 _vbar_unpress_cb(Evas_Object *obj,
5111 void *data EINA_UNUSED)
5113 evas_object_smart_callback_call(obj, SIG_VBAR_UNPRESS, NULL);
5117 _hbar_drag_cb(Evas_Object *obj,
5118 void *data EINA_UNUSED)
5120 evas_object_smart_callback_call(obj, SIG_HBAR_DRAG, NULL);
5124 _hbar_press_cb(Evas_Object *obj,
5125 void *data EINA_UNUSED)
5127 evas_object_smart_callback_call(obj, SIG_HBAR_PRESS, NULL);
5131 _hbar_unpress_cb(Evas_Object *obj,
5132 void *data EINA_UNUSED)
5134 evas_object_smart_callback_call(obj, SIG_HBAR_UNPRESS, NULL);
5138 _decorate_item_realize(Elm_Gen_Item *it)
5140 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5141 Evas_Object *obj = sd->obj;
5144 if (GL_IT(it)->deco_it_view) return;
5146 evas_event_freeze(evas_object_evas_get(obj));
5147 it->item->deco_it_view = _view_create(it, it->itc->decorate_item_style);
5149 /* signal callback add */
5150 evas_object_event_callback_add
5151 (GL_IT(it)->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb,
5153 evas_object_event_callback_add
5154 (GL_IT(it)->deco_it_view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
5155 evas_object_event_callback_add
5156 (GL_IT(it)->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb,
5159 _view_inflate(it->item->deco_it_view, it, &GL_IT(it)->deco_it_texts,
5160 &GL_IT(it)->deco_it_contents);
5161 edje_object_part_swallow
5162 (it->item->deco_it_view,
5163 edje_object_data_get(it->item->deco_it_view, "mode_part"), VIEW(it));
5165 snprintf(buf, sizeof(buf), "elm,state,%s,active", sd->decorate_it_type);
5166 edje_object_signal_emit(GL_IT(it)->deco_it_view, buf, "elm");
5167 edje_object_signal_emit(VIEW(it), buf, "elm");
5169 it->want_unrealize = EINA_FALSE;
5170 evas_event_thaw(evas_object_evas_get(obj));
5171 evas_event_thaw_eval(evas_object_evas_get(obj));
5175 _decorate_item_set(Elm_Gen_Item *it)
5179 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5182 it->item->nocache_once = EINA_TRUE;
5184 ELM_SAFE_FREE(sd->scr_hold_timer, ecore_timer_del);
5185 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
5186 sd->scr_hold_timer = ecore_timer_add(SCR_HOLD_TIME, _scroll_hold_timer_cb, sd->obj);
5188 evas_event_freeze(evas_object_evas_get(sd->obj));
5189 _decorate_item_realize(it);
5190 if (it->item->group_item)
5191 evas_object_stack_above(it->item->VIEW(group_item), sd->stack[1]);
5193 (it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
5194 evas_event_thaw(evas_object_evas_get(sd->obj));
5195 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
5200 _decorate_item_unset(Elm_Genlist_Data *sd)
5202 char buf[1024], buf2[1024];
5205 if (!sd->mode_item) return;
5208 it->item->nocache_once = EINA_TRUE;
5210 snprintf(buf, sizeof(buf), "elm,state,%s,passive", sd->decorate_it_type);
5211 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished",
5212 sd->decorate_it_type);
5213 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
5214 edje_object_signal_callback_add
5215 (it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb,
5217 sd->mode_item = NULL;
5221 _elm_genlist_looping_up_cb(void *data,
5222 Evas_Object *obj EINA_UNUSED,
5223 const char *emission EINA_UNUSED,
5224 const char *source EINA_UNUSED)
5226 Evas_Object *genlist = data;
5228 ELM_GENLIST_DATA_GET(genlist, sd);
5230 Elm_Object_Item *eo_it = elm_genlist_last_item_get(genlist);
5232 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
5233 _elm_widget_focus_highlight_signal_emit(genlist, "elm,action,focus,move,up", "elm");
5234 elm_layout_signal_emit(genlist, "elm,action,looping,up,end", "elm");
5235 sd->item_looping_on = EINA_FALSE;
5239 _elm_genlist_looping_down_cb(void *data,
5240 Evas_Object *obj EINA_UNUSED,
5241 const char *emission EINA_UNUSED,
5242 const char *source EINA_UNUSED)
5244 Evas_Object *genlist = data;
5246 ELM_GENLIST_DATA_GET(genlist, sd);
5248 Elm_Object_Item *eo_it = elm_genlist_first_item_get(genlist);
5250 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
5251 _elm_widget_focus_highlight_signal_emit(genlist, "elm,action,focus,move,down", "elm");
5252 elm_layout_signal_emit(genlist, "elm,action,looping,down,end", "elm");
5253 sd->item_looping_on = EINA_FALSE;
5257 _elm_genlist_focus_highlight_move_down_end_cb(void *data,
5258 Evas_Object *obj EINA_UNUSED,
5259 const char *emission EINA_UNUSED,
5260 const char *source EINA_UNUSED)
5262 Evas_Object *gl = data;
5263 Elm_Object_Item *eo_it = elm_genlist_first_item_get(gl);
5265 if (!_elm_config->item_select_on_focus_disable)
5266 elm_genlist_item_selected_set(eo_it, EINA_TRUE);
5268 elm_object_item_focus_set(eo_it, EINA_TRUE);
5270 _elm_widget_focus_highlight_signal_emit(gl, "elm,action,focus,move,home,up", "elm");
5274 _elm_genlist_focus_highlight_move_up_end_cb(void *data,
5275 Evas_Object *obj EINA_UNUSED,
5276 const char *emission EINA_UNUSED,
5277 const char *source EINA_UNUSED)
5279 Evas_Object *gl = data;
5280 Elm_Object_Item *eo_it = elm_genlist_last_item_get(gl);
5282 if (!_elm_config->item_select_on_focus_disable)
5283 elm_genlist_item_selected_set(eo_it, EINA_TRUE);
5285 elm_object_item_focus_set(eo_it, EINA_TRUE);
5287 _elm_widget_focus_highlight_signal_emit(gl, "elm,action,focus,move,home,down", "elm");
5291 _elm_genlist_evas_object_smart_add(Eo *obj, Elm_Genlist_Data *priv)
5293 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5294 Elm_Genlist_Pan_Data *pan_data;
5295 Evas_Coord minw, minh;
5298 eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
5299 elm_widget_sub_object_parent_add(obj);
5301 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
5302 evas_object_smart_member_add(priv->hit_rect, obj);
5303 elm_widget_sub_object_add(obj, priv->hit_rect);
5305 /* common scroller hit rectangle setup */
5306 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
5307 evas_object_show(priv->hit_rect);
5308 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
5310 elm_widget_can_focus_set(obj, EINA_TRUE);
5311 elm_widget_on_show_region_hook_set(obj, _show_region_hook, NULL);
5313 if (!elm_layout_theme_set
5314 (obj, "genlist", "base", elm_widget_style_get(obj)))
5315 CRI("Failed to set layout!");
5317 eo_do(obj, elm_interface_scrollable_objects_set(wd->resize_obj, priv->hit_rect));
5319 eo_do(obj, elm_interface_scrollable_bounce_allow_set
5320 (EINA_FALSE, _elm_config->thumbscroll_bounce_enable));
5321 priv->v_bounce = _elm_config->thumbscroll_bounce_enable;
5324 elm_interface_scrollable_animate_start_cb_set(_scroll_animate_start_cb),
5325 elm_interface_scrollable_animate_stop_cb_set(_scroll_animate_stop_cb),
5326 elm_interface_scrollable_scroll_cb_set(_scroll_cb),
5327 elm_interface_scrollable_drag_start_cb_set(_scroll_drag_start_cb),
5328 elm_interface_scrollable_drag_stop_cb_set(_scroll_drag_stop_cb),
5329 elm_interface_scrollable_edge_left_cb_set(_edge_left_cb),
5330 elm_interface_scrollable_edge_right_cb_set(_edge_right_cb),
5331 elm_interface_scrollable_edge_top_cb_set(_edge_top_cb),
5332 elm_interface_scrollable_edge_bottom_cb_set(_edge_bottom_cb),
5333 elm_interface_scrollable_vbar_drag_cb_set(_vbar_drag_cb),
5334 elm_interface_scrollable_vbar_press_cb_set(_vbar_press_cb),
5335 elm_interface_scrollable_vbar_unpress_cb_set(_vbar_unpress_cb),
5336 elm_interface_scrollable_hbar_drag_cb_set(_hbar_drag_cb),
5337 elm_interface_scrollable_hbar_press_cb_set(_hbar_press_cb),
5338 elm_interface_scrollable_hbar_unpress_cb_set(_hbar_unpress_cb));
5340 priv->mode = ELM_LIST_SCROLL;
5341 priv->max_items_per_block = MAX_ITEMS_PER_BLOCK;
5342 priv->item_cache_max = priv->max_items_per_block * 2;
5343 priv->longpress_timeout = _elm_config->longpress_timeout;
5344 priv->highlight = EINA_TRUE;
5346 priv->pan_obj = eo_add(MY_PAN_CLASS, evas_object_evas_get(obj));
5347 pan_data = eo_data_scope_get(priv->pan_obj, MY_PAN_CLASS);
5348 eo_data_ref(obj, NULL);
5349 pan_data->wobj = obj;
5350 pan_data->wsd = priv;
5352 for (i = 0; i < 2; i++)
5354 priv->stack[i] = evas_object_rectangle_add(evas_object_evas_get(obj));
5355 evas_object_smart_member_add(priv->stack[i], priv->pan_obj);
5358 eo_do(obj, elm_interface_scrollable_extern_pan_set(priv->pan_obj));
5360 edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
5361 evas_object_size_hint_min_set(obj, minw, minh);
5363 _mirrored_set(obj, elm_widget_mirrored_get(obj));
5365 elm_layout_sizing_eval(obj);
5367 edje_object_signal_callback_add(wd->resize_obj, "elm,looping,up,done", "elm", _elm_genlist_looping_up_cb, obj);
5368 edje_object_signal_callback_add(wd->resize_obj, "elm,looping,down,done", "elm", _elm_genlist_looping_down_cb, obj);
5372 _elm_genlist_evas_object_smart_del(Eo *obj, Elm_Genlist_Data *sd)
5376 elm_genlist_clear(obj);
5377 for (i = 0; i < 2; i++)
5378 ELM_SAFE_FREE(sd->stack[i], evas_object_del);
5379 ELM_SAFE_FREE(sd->pan_obj, evas_object_del);
5381 _item_cache_zero(sd);
5382 ecore_job_del(sd->calc_job);
5383 ecore_job_del(sd->update_job);
5384 ecore_idle_enterer_del(sd->queue_idle_enterer);
5385 ecore_idler_del(sd->must_recalc_idler);
5386 ecore_timer_del(sd->multi_timer);
5387 eina_stringshare_del(sd->decorate_it_type);
5388 ecore_animator_del(sd->tree_effect_animator);
5390 eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
5394 _elm_genlist_evas_object_smart_move(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y)
5396 eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
5398 evas_object_move(sd->hit_rect, x, y);
5402 _elm_genlist_evas_object_smart_resize(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord w, Evas_Coord h)
5404 eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
5406 evas_object_resize(sd->hit_rect, w, h);
5407 if ((sd->queue) && (!sd->queue_idle_enterer) && (w > 0))
5408 _requeue_idle_enterer(sd);
5412 _elm_genlist_evas_object_smart_member_add(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *member)
5414 eo_do_super(obj, MY_CLASS, evas_obj_smart_member_add(member));
5417 evas_object_raise(sd->hit_rect);
5421 _access_obj_process(Elm_Genlist_Data *sd, Eina_Bool is_access)
5424 Eina_Bool done = EINA_FALSE;
5426 EINA_INLIST_FOREACH(sd->blocks, itb)
5434 EINA_LIST_FOREACH(itb->items, l, it)
5436 if (!it->realized) continue;
5437 if (is_access) _access_widget_item_register(it);
5439 _elm_access_widget_item_unregister(it->base);
5442 else if (done) break;
5447 _elm_genlist_elm_widget_access(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool acs)
5449 _elm_genlist_smart_focus_next_enable = acs;
5450 _access_obj_process(sd, _elm_genlist_smart_focus_next_enable);
5454 elm_genlist_add(Evas_Object *parent)
5456 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
5457 Evas_Object *obj = eo_add(MY_CLASS, parent);
5462 _elm_genlist_eo_base_constructor(Eo *obj, Elm_Genlist_Data *sd)
5466 eo_do_super(obj, MY_CLASS, eo_constructor());
5468 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
5469 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
5470 elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST));
5474 _internal_elm_genlist_clear(Evas_Object *obj)
5476 ELM_GENLIST_DATA_GET(obj, sd);
5479 _elm_genlist_item_unfocused(sd->focused_item);
5480 if (sd->mode_item) sd->mode_item = NULL;
5482 ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
5484 evas_event_freeze(evas_object_evas_get(sd->obj));
5486 // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
5487 // because sd->items can be modified inside elm_widget_item_del()
5490 it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
5491 eo_do(EO_OBJ(it), elm_wdg_item_del());
5494 sd->pan_changed = EINA_TRUE;
5497 ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
5498 sd->anchor_item = NULL;
5499 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
5500 ELM_SAFE_FREE(sd->must_recalc_idler, ecore_idler_del);
5501 ELM_SAFE_FREE(sd->reorder_move_animator, ecore_animator_del);
5502 sd->reorder_old_pan_y = 0;
5505 if (sd->selected) ELM_SAFE_FREE(sd->selected, eina_list_free);
5507 sd->show_item = NULL;
5516 evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
5517 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
5519 elm_layout_sizing_eval(sd->obj);
5520 eo_do(obj, elm_interface_scrollable_content_region_show(0, 0, 0, 0));
5522 ELM_SAFE_FREE(sd->event_block_rect, evas_object_del);
5523 ELM_SAFE_FREE(sd->scr_hold_timer, ecore_timer_del);
5524 ELM_SAFE_FREE(sd->queue, eina_list_free);
5526 evas_event_thaw(evas_object_evas_get(sd->obj));
5527 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
5530 /* Return EINA_TRUE if the item is deleted in this function */
5532 _item_select(Elm_Gen_Item *it)
5534 Evas_Object *obj = WIDGET(it);
5535 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5536 Elm_Object_Item *eo_it = EO_OBJ(it);
5538 if (eo_do(eo_it, elm_wdg_item_disabled_get())) return EINA_FALSE;
5539 if (_is_no_select(it) || (it->decorate_it_set)) return EINA_FALSE;
5540 if ((sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) &&
5541 (it->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) && it->selected)
5546 const Eina_List *l, *ll;
5547 Elm_Object_Item *eo_it2;
5548 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it2)
5550 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
5551 if (it2 != it) _item_unselect(it2);
5557 it->selected = EINA_TRUE;
5559 eina_list_append(sd->selected, eo_it);
5562 evas_object_ref(obj);
5564 elm_object_item_focus_set(eo_it, EINA_TRUE);
5565 _elm_genlist_item_content_focus_set(it, ELM_FOCUS_PREVIOUS);
5566 sd->last_selected_item = eo_it;
5567 _item_highlight(it);
5570 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), eo_it);
5571 // delete item if it's requested deletion in the above callbacks.
5572 if ((it->base)->on_deletion) goto item_deleted;
5573 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, eo_it);
5574 // delete item if it's requested deletion in the above callbacks.
5575 if ((it->base)->on_deletion) goto item_deleted;
5578 if (!(sd->focus_on_selection_enabled || _elm_config->item_select_on_focus_disable))
5580 Evas_Object *swallow_obj;
5582 EINA_LIST_FOREACH(it->contents, l, swallow_obj)
5584 if (elm_widget_is(swallow_obj) && elm_object_focus_get(swallow_obj))
5586 elm_object_focus_set(obj, EINA_FALSE);
5587 elm_object_focus_set(obj, EINA_TRUE);
5593 evas_object_unref(obj);
5597 it->walking = -1; //This item was removed from it's item list.
5600 evas_object_unref(obj);
5604 EOLIAN static Evas_Object *
5605 _elm_genlist_item_elm_widget_item_part_content_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
5607 Evas_Object *ret = NULL;
5608 if (it->deco_all_view)
5609 ret = edje_object_part_swallow_get(it->deco_all_view, part);
5610 else if (it->decorate_it_set)
5611 ret = edje_object_part_swallow_get(it->item->deco_it_view, part);
5615 ret = edje_object_part_swallow_get(VIEW(it), part);
5617 ret = edje_object_part_swallow_get(VIEW(it), "elm.swallow.icon");
5622 EOLIAN static const char *
5623 _elm_genlist_item_elm_widget_item_part_text_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
5625 if (!it->itc->func.text_get) return NULL;
5626 const char *ret = NULL;
5627 if (it->deco_all_view)
5628 ret = edje_object_part_text_get(it->deco_all_view, part);
5629 else if (it->decorate_it_set)
5630 ret = edje_object_part_text_get(it->item->deco_it_view, part);
5634 ret = edje_object_part_text_get(VIEW(it), part);
5636 ret = edje_object_part_text_get(VIEW(it), "elm.text");
5642 _elm_genlist_item_elm_widget_item_disable(Eo *eo_it, Elm_Gen_Item *it)
5648 if (eo_it == GL_IT(it)->wsd->focused_item)
5649 _elm_genlist_item_unfocused(eo_it);
5650 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
5654 if (eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()))
5656 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
5657 if (it->deco_all_view)
5658 edje_object_signal_emit
5659 (it->deco_all_view, SIGNAL_DISABLED, "elm");
5663 edje_object_signal_emit(VIEW(it), SIGNAL_ENABLED, "elm");
5664 if (it->deco_all_view)
5665 edje_object_signal_emit
5666 (it->deco_all_view, SIGNAL_ENABLED, "elm");
5668 EINA_LIST_FOREACH(it->contents, l, obj)
5669 elm_widget_disabled_set(obj, eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()));
5673 EOLIAN static Eina_Bool
5674 _elm_genlist_item_elm_widget_item_del_pre(Eo *eo_it EINA_UNUSED,
5677 /* This item is getting removed from a callback that triggered in the
5678 _item_select(). Just pend removing. Because this will be removed right
5679 after in the _item_select(). So pratically, this item won't be
5681 if (it->walking > 0)
5683 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5684 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
5693 _elm_genlist_item_elm_widget_item_signal_emit(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char *emission, const char *source)
5697 WRN("Item is not realized yet");
5700 edje_object_signal_emit(VIEW(it), emission, source);
5701 if (it->deco_all_view)
5702 edje_object_signal_emit(it->deco_all_view, emission, source);
5706 _elm_genlist_item_elm_widget_item_focus_set(Eo *eo_it, Elm_Gen_Item *it, Eina_Bool focused)
5708 Evas_Object *obj = WIDGET(it);
5709 ELM_GENLIST_DATA_GET(obj, sd);
5713 sd->last_focused_item = eo_it;
5714 if (!elm_object_focus_get(obj))
5715 elm_object_focus_set(obj, EINA_TRUE);
5717 if (!elm_widget_focus_get(obj))
5720 if (eo_it != sd->focused_item)
5722 if (sd->focused_item)
5723 _elm_genlist_item_unfocused(sd->focused_item);
5724 _elm_genlist_item_focused(eo_it);
5726 _elm_widget_item_highlight_in_theme(obj, EO_OBJ(it));
5727 _elm_widget_highlight_in_theme_update(obj);
5728 _elm_widget_focus_highlight_start(obj);
5733 if (!elm_widget_focus_get(obj))
5735 _elm_genlist_item_unfocused(eo_it);
5739 EOLIAN static Eina_Bool
5740 _elm_genlist_item_elm_widget_item_focus_get(Eo *eo_it, Elm_Gen_Item *it)
5742 Evas_Object *obj = WIDGET(it);
5743 ELM_GENLIST_DATA_GET(obj, sd);
5745 if (eo_it == sd->focused_item)
5752 _elm_genlist_item_eo_base_constructor(Eo *eo_it, Elm_Gen_Item *it)
5754 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, eo_constructor());
5755 it->base = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
5758 static Elm_Gen_Item *
5759 _elm_genlist_item_new(Elm_Genlist_Data *sd,
5760 const Elm_Genlist_Item_Class *itc,
5762 Elm_Object_Item *eo_parent,
5763 Elm_Genlist_Item_Type type,
5765 const void *func_data)
5770 if (!itc) return NULL;
5772 Eo *eo_it = eo_add(ELM_GENLIST_ITEM_CLASS, sd->obj);
5773 if (!eo_it) return NULL;
5774 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
5777 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
5779 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
5780 WIDGET_ITEM_DATA_SET(EO_OBJ(it), data);
5781 it->parent = parent;
5782 it->func.func = func;
5783 it->func.data = func_data;
5785 GL_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
5786 GL_IT(it)->wsd = sd;
5787 GL_IT(it)->type = type;
5791 if (GL_IT(it->parent)->type & ELM_GENLIST_ITEM_GROUP)
5792 GL_IT(it)->group_item = parent;
5793 else if (GL_IT(it->parent)->group_item)
5794 GL_IT(it)->group_item = GL_IT(it->parent)->group_item;
5796 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
5798 if (!(GL_IT(it2->parent)->type & ELM_GENLIST_ITEM_GROUP)) depth += 1;
5800 GL_IT(it)->expanded_depth = depth;
5807 _elm_genlist_item_compare(const void *data,
5810 const Elm_Gen_Item *it, *item1;
5812 it = ELM_GEN_ITEM_FROM_INLIST(data);
5813 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
5814 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
5818 _elm_genlist_item_list_compare(const void *data,
5821 const Elm_Gen_Item *it = data;
5822 const Elm_Gen_Item *item1 = data1;
5824 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
5828 _elm_genlist_eo_item_list_compare(const void *data,
5831 const Elm_Object_Item *eo_it = data;
5832 const Elm_Object_Item *eo_item1 = data1;
5833 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
5835 return GL_IT(it)->wsd->item_compare_cb(eo_it, eo_item1);
5838 EOLIAN static unsigned int
5839 _elm_genlist_items_count(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
5841 return sd->item_count;
5845 _list_last_recursive(Eina_List *list)
5847 Eina_List *ll, *ll2;
5848 Elm_Object_Item *eo_it2;
5850 ll = eina_list_last(list);
5851 if (!ll) return NULL;
5854 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
5856 if (it2->item->items)
5858 ll2 = _list_last_recursive(it2->item->items);
5868 EOLIAN static Elm_Object_Item*
5869 _elm_genlist_item_append(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
5875 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
5876 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
5877 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
5880 it = _elm_genlist_item_new
5881 (sd, itc, data, eo_parent, type, func, func_data);
5882 if (!it) return NULL;
5886 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
5887 sd->group_items = eina_list_append(sd->group_items, it);
5888 sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
5889 it->item->rel = NULL;
5893 Elm_Object_Item *eo_it2 = NULL;
5894 Eina_List *ll = _list_last_recursive(it->parent->item->items);
5896 if (ll) eo_it2 = ll->data;
5897 it->parent->item->items =
5898 eina_list_append(it->parent->item->items, EO_OBJ(it));
5899 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
5900 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
5901 sd->items = eina_inlist_append_relative
5902 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
5903 it->item->rel = it2;
5904 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
5906 it->item->before = EINA_FALSE;
5907 _item_queue(sd, it, NULL);
5912 EOLIAN static Elm_Object_Item*
5913 _elm_genlist_item_prepend(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
5919 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
5920 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
5921 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
5924 it = _elm_genlist_item_new
5925 (sd, itc, data, eo_parent, type, func, func_data);
5926 if (!it) return NULL;
5930 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
5931 sd->group_items = eina_list_prepend(sd->group_items, it);
5932 sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
5933 it->item->rel = NULL;
5937 Elm_Object_Item *eo_it2 = NULL;
5938 Eina_List *ll = it->parent->item->items;
5940 if (ll) eo_it2 = ll->data;
5941 it->parent->item->items =
5942 eina_list_prepend(it->parent->item->items, EO_OBJ(it));
5943 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
5944 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
5945 sd->items = eina_inlist_prepend_relative
5946 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
5947 it->item->rel = it2;
5948 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
5950 it->item->before = EINA_TRUE;
5951 _item_queue(sd, it, NULL);
5956 EOLIAN static Elm_Object_Item*
5957 _elm_genlist_item_insert_after(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Object_Item *eo_after, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
5959 ELM_GENLIST_ITEM_DATA_GET(eo_after, after);
5962 ELM_GENLIST_ITEM_CHECK_OR_RETURN(after, NULL);
5963 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(after)), NULL);
5966 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
5967 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
5968 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
5971 /* It makes no sense to insert after in an empty list with after !=
5972 * NULL, something really bad is happening in your app. */
5973 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
5975 it = _elm_genlist_item_new
5976 (sd, itc, data, eo_parent, type, func, func_data);
5977 if (!it) return NULL;
5981 if ((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) &&
5982 (GL_IT(after)->type & ELM_GENLIST_ITEM_GROUP))
5983 sd->group_items = eina_list_append_relative
5984 (sd->group_items, it, after);
5988 it->parent->item->items =
5989 eina_list_append_relative(it->parent->item->items, EO_OBJ(it), eo_after);
5991 sd->items = eina_inlist_append_relative
5992 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
5994 it->item->rel = after;
5995 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
5996 it->item->before = EINA_FALSE;
5997 _item_queue(sd, it, NULL);
6002 EOLIAN static Elm_Object_Item*
6003 _elm_genlist_item_insert_before(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Object_Item *eo_before, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
6005 ELM_GENLIST_ITEM_DATA_GET(eo_before, before);
6008 ELM_GENLIST_ITEM_CHECK_OR_RETURN(before, NULL);
6009 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(before)), NULL);
6012 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6013 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6014 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6017 /* It makes no sense to insert before in an empty list with before
6018 * != NULL, something really bad is happening in your app. */
6019 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6021 it = _elm_genlist_item_new
6022 (sd, itc, data, eo_parent, type, func, func_data);
6023 if (!it) return NULL;
6027 if ((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) &&
6028 (GL_IT(before)->type & ELM_GENLIST_ITEM_GROUP))
6030 eina_list_prepend_relative(sd->group_items, it, before);
6034 it->parent->item->items =
6035 eina_list_prepend_relative(it->parent->item->items, EO_OBJ(it), eo_before);
6037 sd->items = eina_inlist_prepend_relative
6038 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
6040 it->item->rel = before;
6041 GL_IT(before)->rel_revs = eina_list_append(GL_IT(before)->rel_revs, it);
6042 it->item->before = EINA_TRUE;
6043 _item_queue(sd, it, NULL);
6048 EOLIAN static Elm_Object_Item*
6049 _elm_genlist_item_sorted_insert(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Genlist_Item_Type type, Eina_Compare_Cb comp, Evas_Smart_Cb func, const void *func_data)
6051 Elm_Gen_Item *rel = NULL;
6056 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6057 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6058 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6061 it = _elm_genlist_item_new
6062 (sd, itc, data, eo_parent, type, func, func_data);
6063 if (!it) return NULL;
6064 Elm_Object_Item *eo_it = EO_OBJ(it);
6066 sd->item_compare_cb = comp;
6070 Elm_Object_Item *eo_rel = NULL;
6074 l = eina_list_search_sorted_near_list
6075 (it->parent->item->items, _elm_genlist_eo_item_list_compare, eo_it,
6080 eo_rel = eina_list_data_get(l);
6081 rel = eo_data_scope_get(eo_rel, ELM_GENLIST_ITEM_CLASS);
6083 if (cmp_result >= 0)
6085 it->parent->item->items = eina_list_prepend_relative_list
6086 (it->parent->item->items, eo_it, l);
6087 sd->items = eina_inlist_prepend_relative
6088 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6089 it->item->before = EINA_TRUE;
6091 else if (cmp_result < 0)
6093 it->parent->item->items = eina_list_append_relative_list
6094 (it->parent->item->items, eo_it, l);
6095 sd->items = eina_inlist_append_relative
6096 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6097 it->item->before = EINA_FALSE;
6104 // ignoring the comparison
6105 it->parent->item->items = eina_list_prepend_relative_list
6106 (it->parent->item->items, eo_it, l);
6107 sd->items = eina_inlist_prepend_relative
6108 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6109 it->item->before = EINA_FALSE;
6116 sd->state = eina_inlist_sorted_state_new();
6117 eina_inlist_sorted_state_init(sd->state, sd->items);
6118 sd->requeued = EINA_FALSE;
6121 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6122 sd->group_items = eina_list_append(sd->group_items, it);
6124 sd->items = eina_inlist_sorted_state_insert
6125 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
6128 if (EINA_INLIST_GET(it)->next)
6130 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6131 it->item->before = EINA_TRUE;
6133 else if (EINA_INLIST_GET(it)->prev)
6135 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6136 it->item->before = EINA_FALSE;
6142 GL_IT(it)->rel = rel;
6143 rel->item->rel_revs = eina_list_append(rel->item->rel_revs, it);
6146 _item_queue(sd, it, _elm_genlist_item_list_compare);
6152 _elm_genlist_clear(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED)
6154 _internal_elm_genlist_clear(obj);
6158 _elm_genlist_multi_select_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool multi)
6160 sd->multi = !!multi;
6162 if (!sd->multi && sd->selected)
6165 Elm_Object_Item *eo_it;
6166 Elm_Object_Item *last = sd->selected->data;
6167 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
6171 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6178 EOLIAN static Eina_Bool
6179 _elm_genlist_multi_select_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6185 _elm_genlist_multi_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Elm_Object_Multi_Select_Mode mode)
6187 if (mode >= ELM_OBJECT_MULTI_SELECT_MODE_MAX)
6190 if (sd->multi_select_mode != mode)
6191 sd->multi_select_mode = mode;
6194 EOLIAN static Elm_Object_Multi_Select_Mode
6195 _elm_genlist_multi_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6197 return sd->multi_select_mode;
6200 EOLIAN static Elm_Object_Item*
6201 _elm_genlist_selected_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6204 return sd->selected->data;
6209 EOLIAN static const Eina_List*
6210 _elm_genlist_selected_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6212 return sd->selected;
6215 EOLIAN static Eina_List*
6216 _elm_genlist_realized_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6219 Eina_Bool done = EINA_FALSE;
6221 Eina_List *ret = NULL;
6223 EINA_INLIST_FOREACH(sd->blocks, itb)
6231 EINA_LIST_FOREACH(itb->items, l, it)
6233 if (it->realized) ret = eina_list_append(ret, EO_OBJ(it));
6245 EOLIAN static Elm_Object_Item*
6246 _elm_genlist_at_xy_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y, int *posret)
6248 Evas_Coord ox, oy, ow, oh;
6252 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
6254 EINA_INLIST_FOREACH(sd->blocks, itb)
6259 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->sd->pan_x,
6260 oy + itb->y - itb->sd->pan_y,
6261 itb->w, itb->h, x, y, 1, 1))
6263 EINA_LIST_FOREACH(itb->items, l, it)
6265 Evas_Coord itx, ity;
6267 itx = ox + itb->x + it->x - itb->sd->pan_x;
6268 ity = oy + itb->y + it->y - itb->sd->pan_y;
6269 if (ELM_RECTS_INTERSECT
6270 (itx, ity, it->item->w, it->item->h, x, y, 1, 1))
6274 if (y <= (ity + (it->item->h / 4))) *posret = -1;
6275 else if (y >= (ity + it->item->h - (it->item->h / 4)))
6282 lasty = ity + it->item->h;
6287 if (y > lasty) *posret = 1;
6294 EOLIAN static Elm_Object_Item*
6295 _elm_genlist_first_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6297 return EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(sd->items));
6300 EOLIAN static Elm_Object_Item*
6301 _elm_genlist_last_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6305 if (!sd->items) return NULL;
6307 it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
6312 EOLIAN static Elm_Object_Item *
6313 _elm_genlist_item_next_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6317 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6321 if (it) return EO_OBJ(it);
6325 EOLIAN static Elm_Object_Item *
6326 _elm_genlist_item_prev_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6330 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6334 if (it) return EO_OBJ(it);
6338 EOLIAN static Elm_Object_Item *
6339 _elm_genlist_item_parent_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6341 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
6343 return EO_OBJ(it->parent);
6346 EOLIAN static unsigned int
6347 _elm_genlist_item_subitems_count(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
6349 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, 0);
6351 return eina_list_count(item->item->items);
6354 EOLIAN static const Eina_List *
6355 _elm_genlist_item_subitems_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
6357 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6359 return item->item->items;
6363 _elm_genlist_item_subitems_clear(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6365 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6366 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
6368 if (!sd->tree_effect_enabled || !sd->move_effect_mode)
6369 _item_sub_items_clear(it);
6372 if (!sd->tree_effect_animator)
6374 sd->expanded_item = it;
6375 _item_tree_effect_before(it);
6376 evas_object_stack_below(sd->event_block_rect, sd->stack[1]);
6377 evas_object_show(sd->event_block_rect);
6378 sd->start_time = ecore_time_get();
6379 sd->tree_effect_animator =
6380 ecore_animator_add(_tree_effect_animator_cb, sd->obj);
6383 _item_sub_items_clear(it);
6388 _elm_genlist_item_selected_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
6391 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6393 if (eo_do(EO_OBJ(it), elm_wdg_item_disabled_get())) return;
6395 selected = !!selected;
6396 if (it->selected == selected) return;
6398 if (selected) _item_select(it);
6399 else _item_unselect(it);
6402 EOLIAN static Eina_Bool
6403 _elm_genlist_item_selected_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6405 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6407 return it->selected;
6410 static Elm_Gen_Item *
6411 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
6413 Elm_Object_Item *eo_it = EO_OBJ(it);
6414 Elm_Object_Item *eo_it2;
6416 if (it->item->expanded)
6418 eo_it2 = elm_genlist_item_next_get(eo_it);
6419 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6424 eo_it2 = elm_genlist_item_next_get(eo_it);
6427 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6428 if (it->item->expanded_depth >= it2->item->expanded_depth) return it2;
6429 eo_it2 = elm_genlist_item_next_get(eo_it2);
6432 return eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
6436 _elm_genlist_move_items_set(Elm_Gen_Item *it)
6439 Elm_Gen_Item *it2 = NULL;
6440 Evas_Coord ox, oy, ow, oh, dh = 0;
6441 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
6443 sd->expanded_next_item =
6444 _elm_genlist_expanded_next_item_get(it);
6446 if (it->item->expanded)
6448 Elm_Object_Item *eo_item;
6449 l = elm_genlist_realized_items_get((sd)->obj);
6450 EINA_LIST_FREE(l, eo_item)
6452 ELM_GENLIST_ITEM_DATA_GET(eo_item, item);
6453 sd->move_items = eina_list_append(sd->move_items, item);
6456 EINA_LIST_FOREACH_SAFE(sd->move_items, l, ll, it2)
6458 if (it2 == sd->expanded_next_item) break;
6459 sd->move_items = eina_list_remove(sd->move_items, it2);
6464 Elm_Object_Item *eo_it2 = NULL;
6465 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
6466 if (sd->expanded_next_item) eo_it2 = EO_OBJ(sd->expanded_next_item);
6468 while (eo_it2 && (dh < oy + oh))
6470 it2 = eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
6472 sd->move_items = eina_list_append(sd->move_items, it2);
6473 eo_it2 = elm_genlist_item_next_get(eo_it2);
6479 _event_block_rect_update(const Evas_Object *obj)
6481 Evas_Coord ox, oy, ow, oh;
6483 ELM_GENLIST_CHECK(obj);
6484 ELM_GENLIST_DATA_GET(obj, sd);
6486 if (!sd->event_block_rect)
6488 sd->event_block_rect = evas_object_rectangle_add(
6489 evas_object_evas_get(sd->obj));
6490 evas_object_smart_member_add(sd->event_block_rect, sd->pan_obj);
6493 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
6494 evas_object_color_set(sd->event_block_rect, 0, 0, 0, 0);
6495 evas_object_resize(sd->event_block_rect, ow, oh);
6496 evas_object_move(sd->event_block_rect, ox, oy);
6500 _elm_genlist_item_expanded_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool expanded)
6502 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6503 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
6505 expanded = !!expanded;
6506 if (it->item->expanded == expanded) return;
6507 if (it->item->type != ELM_GENLIST_ITEM_TREE) return;
6508 it->item->expanded = expanded;
6509 sd->expanded_item = it;
6510 _elm_genlist_move_items_set(it);
6512 if (sd->tree_effect_enabled)
6513 _event_block_rect_update(WIDGET(it));
6515 if (it->item->expanded)
6517 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
6519 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
6520 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, EO_OBJ(it));
6521 sd->auto_scroll_enabled = EINA_TRUE;
6525 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
6527 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACTED, "elm");
6528 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, EO_OBJ(it));
6529 sd->auto_scroll_enabled = EINA_FALSE;
6533 EOLIAN static Eina_Bool
6534 _elm_genlist_item_expanded_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6536 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6538 return GL_IT(it)->expanded;
6542 _elm_genlist_item_expanded_depth_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6544 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, 0);
6546 return GL_IT(it)->expanded_depth;
6550 _elm_genlist_item_coordinates_calc(Elm_Gen_Item *it,
6551 Elm_Genlist_Item_Scrollto_Type type,
6558 Evas_Coord gith = 0;
6559 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
6562 (!((sd->homogeneous) &&
6563 (sd->mode == ELM_LIST_COMPRESS))))
6565 if ((it->item->queued) || (!it->item->mincalcd) || (sd->queue))
6568 sd->bring_in = bring_in;
6569 sd->scroll_to_type = type;
6570 it->item->show_me = EINA_TRUE;
6576 sd->show_item->item->show_me = EINA_FALSE;
6577 sd->show_item = NULL;
6580 evas_object_geometry_get(sd->pan_obj, NULL, NULL, w, h);
6583 case ELM_GENLIST_ITEM_SCROLLTO_IN:
6584 if ((it->item->group_item) &&
6585 (sd->pan_y > (it->y + it->item->block->y)))
6586 gith = it->item->group_item->item->h;
6588 *y = it->y + it->item->block->y - gith;
6591 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
6592 if (it->item->group_item) gith = it->item->group_item->item->h;
6593 *y = it->y + it->item->block->y - gith;
6596 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
6597 *y = it->y + it->item->block->y - (*h / 2) + (it->item->h / 2);
6604 *x = it->x + it->item->block->x;
6605 *w = it->item->block->w;
6611 _elm_genlist_item_promote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6613 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6615 Elm_Object_Item *eo_first_item = elm_genlist_first_item_get(WIDGET(it));
6616 ELM_GENLIST_ITEM_DATA_GET(eo_first_item, first_item);
6617 _item_move_before(it, first_item);
6621 _elm_genlist_item_demote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6623 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6624 Elm_Object_Item *eo_last_item = elm_genlist_last_item_get(WIDGET(it));
6625 ELM_GENLIST_ITEM_DATA_GET(eo_last_item, last_item);
6626 _item_move_after(it, last_item);
6630 _elm_genlist_item_show(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item, Elm_Genlist_Item_Scrollto_Type type)
6632 Evas_Coord x, y, w, h;
6634 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6636 if (_elm_genlist_item_coordinates_calc
6637 (item, type, EINA_FALSE, &x, &y, &w, &h))
6638 eo_do(WIDGET(item), elm_interface_scrollable_content_region_show
6643 _elm_genlist_item_bring_in(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item, Elm_Genlist_Item_Scrollto_Type type)
6645 Evas_Coord x, y, w, h;
6647 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
6649 if (_elm_genlist_item_coordinates_calc
6650 (item, type, EINA_TRUE, &x, &y, &w, &h))
6651 eo_do(WIDGET(item), elm_interface_scrollable_region_bring_in(x, y, w, h));
6655 _elm_genlist_item_all_contents_unset(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_List **l)
6657 Evas_Object *content;
6659 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6661 EINA_LIST_FREE(it->contents, content)
6663 elm_widget_sub_object_del(WIDGET(it), content);
6664 edje_object_part_unswallow(VIEW(it), content);
6665 evas_object_hide(content);
6666 if (l) *l = eina_list_append(*l, content);
6671 _elm_genlist_item_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6673 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6674 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
6676 if (!it->item->block) return;
6677 it->item->mincalcd = EINA_FALSE;
6678 it->item->updateme = EINA_TRUE;
6679 it->item->block->updateme = EINA_TRUE;
6680 ecore_job_del(sd->update_job);
6681 sd->update_job = ecore_job_add(_update_job, sd->obj);
6685 _elm_genlist_item_fields_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
6687 Elm_Genlist_Item_Field_Type itf)
6689 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6691 if (!it->item->block) return;
6693 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
6695 _item_text_realize(it, VIEW(it), &it->texts, parts);
6697 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
6699 _item_content_realize(it, VIEW(it), &it->contents, "contents", parts);
6702 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_contents,
6705 if (GL_IT(it)->deco_it_view)
6707 _item_content_realize(it, GL_IT(it)->deco_it_view,
6708 &GL_IT(it)->deco_it_contents,
6711 if (GL_IT(it)->wsd->decorate_all_mode)
6713 _item_content_realize(it, it->deco_all_view,
6714 &GL_IT(it)->deco_all_contents,
6717 if (it->has_contents != (!!it->contents))
6718 it->item->mincalcd = EINA_FALSE;
6719 it->has_contents = !!it->contents;
6720 if (it->item->type == ELM_GENLIST_ITEM_NONE)
6724 it->item_focus_chain = eina_list_free(it->item_focus_chain);
6725 EINA_LIST_FOREACH(it->contents, l, eobj)
6726 if (elm_widget_is(eobj) && elm_object_focus_allow_get(eobj))
6727 it->item_focus_chain = eina_list_append(it->item_focus_chain, eobj);
6731 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
6732 _item_state_realize(it, VIEW(it), parts);
6734 if (!it->item->mincalcd)
6735 elm_genlist_item_update(eo_item);
6739 _elm_genlist_item_item_class_update(Eo *eo_it, Elm_Gen_Item *it,
6740 const Elm_Genlist_Item_Class *itc)
6742 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6743 EINA_SAFETY_ON_NULL_RETURN(itc);
6745 if (!it->item->block) return;
6746 it->item->nocache_once = EINA_TRUE;
6748 ELM_SAFE_FREE(it->texts, elm_widget_stringlist_free);
6749 ELM_SAFE_FREE(GL_IT(it)->deco_it_texts, elm_widget_stringlist_free);
6750 ELM_SAFE_FREE(GL_IT(it)->deco_all_texts, elm_widget_stringlist_free);
6752 elm_genlist_item_update(eo_it);
6755 EOLIAN static const Elm_Genlist_Item_Class *
6756 _elm_genlist_item_item_class_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6758 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
6763 static Evas_Object *
6764 _elm_genlist_item_label_create(void *data,
6765 Evas_Object *obj EINA_UNUSED,
6766 Evas_Object *tooltip,
6767 void *it EINA_UNUSED)
6769 Evas_Object *label = elm_label_add(tooltip);
6774 elm_object_style_set(label, "tooltip");
6775 elm_object_text_set(label, data);
6781 _elm_genlist_item_label_del_cb(void *data,
6782 Evas_Object *obj EINA_UNUSED,
6783 void *event_info EINA_UNUSED)
6785 eina_stringshare_del(data);
6789 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
6792 eo_do(it, elm_wdg_item_tooltip_text_set(text));
6796 _elm_genlist_item_elm_widget_item_tooltip_text_set(Eo *eo_it, Elm_Gen_Item *it, const char *text)
6798 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6800 text = eina_stringshare_add(text);
6801 elm_genlist_item_tooltip_content_cb_set
6802 (eo_it, _elm_genlist_item_label_create, text,
6803 _elm_genlist_item_label_del_cb);
6807 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item,
6808 Elm_Tooltip_Item_Content_Cb func,
6810 Evas_Smart_Cb del_cb)
6812 eo_do(item, elm_wdg_item_tooltip_content_cb_set(func, data, del_cb));
6816 _elm_genlist_item_elm_widget_item_tooltip_content_cb_set(Eo *eo_it, Elm_Gen_Item *it,
6817 Elm_Tooltip_Item_Content_Cb func,
6819 Evas_Smart_Cb del_cb)
6821 ELM_GENLIST_ITEM_CHECK_OR_GOTO(it, error);
6823 if ((it->tooltip.content_cb != func) || (it->tooltip.data != data))
6825 if (it->tooltip.del_cb)
6826 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6828 it->tooltip.content_cb = func;
6829 it->tooltip.data = data;
6830 it->tooltip.del_cb = del_cb;
6835 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
6836 elm_wdg_item_tooltip_content_cb_set
6837 (it->tooltip.content_cb, it->tooltip.data, NULL));
6839 elm_wdg_item_tooltip_style_set(it->tooltip.style),
6840 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
6846 if (del_cb) del_cb((void *)data, NULL, NULL);
6850 elm_genlist_item_tooltip_unset(Elm_Object_Item *item)
6852 eo_do(item, elm_wdg_item_tooltip_unset());
6856 _elm_genlist_item_elm_widget_item_tooltip_unset(Eo *eo_it, Elm_Gen_Item *it)
6858 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6860 if ((VIEW(it)) && (it->tooltip.content_cb))
6861 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
6862 elm_wdg_item_tooltip_unset());
6864 if (it->tooltip.del_cb)
6865 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6866 it->tooltip.del_cb = NULL;
6867 it->tooltip.content_cb = NULL;
6868 it->tooltip.data = NULL;
6869 it->tooltip.free_size = EINA_FALSE;
6870 if (it->tooltip.style)
6871 eo_do(eo_it, elm_wdg_item_tooltip_style_set(NULL));
6875 elm_genlist_item_tooltip_style_set(Elm_Object_Item *item,
6878 eo_do(item, elm_wdg_item_tooltip_style_set(style));
6882 _elm_genlist_item_elm_widget_item_tooltip_style_set(Eo *eo_it, Elm_Gen_Item *it,
6885 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6887 eina_stringshare_replace(&it->tooltip.style, style);
6888 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
6889 elm_wdg_item_tooltip_style_set(style));
6893 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
6895 return eo_do(it, elm_wdg_item_tooltip_style_get());
6899 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *item,
6902 return eo_do(item, elm_wdg_item_tooltip_window_mode_set(disable));
6905 EOLIAN static Eina_Bool
6906 _elm_genlist_item_elm_widget_item_tooltip_window_mode_set(Eo *eo_it, Elm_Gen_Item *it,
6909 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6911 it->tooltip.free_size = disable;
6913 return eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
6914 elm_wdg_item_tooltip_window_mode_set(disable));
6920 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *eo_it)
6922 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6923 return eo_do(VIEW(it), elm_wdg_item_tooltip_window_mode_get());
6927 elm_genlist_item_cursor_set(Elm_Object_Item *item,
6930 eo_do(item, elm_wdg_item_cursor_set(cursor));
6934 _elm_genlist_item_elm_widget_item_cursor_set(Eo *eo_it, Elm_Gen_Item *it,
6937 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6938 eina_stringshare_replace(&it->mouse_cursor, cursor);
6939 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
6940 elm_wdg_item_cursor_set(cursor));
6944 elm_genlist_item_cursor_get(const Elm_Object_Item *eo_it)
6946 return eo_do(eo_it, elm_wdg_item_cursor_get());
6950 elm_genlist_item_cursor_unset(Elm_Object_Item *item)
6952 eo_do(item, elm_wdg_item_cursor_unset());
6956 _elm_genlist_item_elm_widget_item_cursor_unset(Eo *eo_it, Elm_Gen_Item *it)
6958 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6960 if (!it->mouse_cursor) return;
6962 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
6963 elm_wdg_item_cursor_unset());
6965 ELM_SAFE_FREE(it->mouse_cursor, eina_stringshare_del);
6969 elm_genlist_item_cursor_style_set(Elm_Object_Item *eo_it,
6972 eo_do(eo_it, elm_wdg_item_cursor_style_set(style));
6976 elm_genlist_item_cursor_style_get(const Elm_Object_Item *eo_it)
6978 return eo_do( eo_it, elm_wdg_item_cursor_style_get());
6982 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *eo_it,
6983 Eina_Bool engine_only)
6985 eo_do(eo_it, elm_wdg_item_cursor_engine_only_set(engine_only));
6989 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *eo_it)
6991 return eo_do( eo_it, elm_wdg_item_cursor_engine_only_get());
6995 _elm_genlist_item_index_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6999 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, -1);
7001 EINA_INLIST_FOREACH(GL_IT(it)->wsd->items, tmp)
7003 if (tmp == it) break;
7010 _elm_genlist_mode_set(Eo *obj, Elm_Genlist_Data *sd, Elm_List_Mode mode)
7012 if (sd->mode == mode) return;
7014 elm_layout_sizing_eval(obj);
7017 EOLIAN static Elm_List_Mode
7018 _elm_genlist_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7024 elm_genlist_bounce_set(Evas_Object *obj,
7028 ELM_GENLIST_CHECK(obj);
7029 eo_do(obj, elm_interface_scrollable_bounce_allow_set(h_bounce, v_bounce));
7033 _elm_genlist_elm_interface_scrollable_bounce_allow_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool h_bounce, Eina_Bool v_bounce)
7035 sd->h_bounce = !!h_bounce;
7036 sd->v_bounce = !!v_bounce;
7037 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_bounce_allow_set
7038 (sd->h_bounce, sd->v_bounce));
7042 elm_genlist_bounce_get(const Evas_Object *obj,
7043 Eina_Bool *h_bounce,
7044 Eina_Bool *v_bounce)
7046 ELM_GENLIST_CHECK(obj);
7047 eo_do( obj, elm_interface_scrollable_bounce_allow_get
7048 (h_bounce, v_bounce));
7052 _elm_genlist_elm_interface_scrollable_bounce_allow_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
7054 if (h_bounce) *h_bounce = sd->h_bounce;
7055 if (v_bounce) *v_bounce = sd->v_bounce;
7059 _elm_genlist_homogeneous_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool homogeneous)
7061 sd->homogeneous = !!homogeneous;
7064 EOLIAN static Eina_Bool
7065 _elm_genlist_homogeneous_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7067 return sd->homogeneous;
7071 _elm_genlist_block_count_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, int count)
7073 EINA_SAFETY_ON_TRUE_RETURN(count < 1);
7075 sd->max_items_per_block = count;
7076 sd->item_cache_max = sd->max_items_per_block * 2;
7077 _item_cache_clean(sd);
7081 _elm_genlist_block_count_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7083 return sd->max_items_per_block;
7087 _elm_genlist_longpress_timeout_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, double timeout)
7089 sd->longpress_timeout = timeout;
7092 EOLIAN static double
7093 _elm_genlist_longpress_timeout_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7095 return sd->longpress_timeout;
7099 elm_genlist_scroller_policy_set(Evas_Object *obj,
7100 Elm_Scroller_Policy policy_h,
7101 Elm_Scroller_Policy policy_v)
7103 ELM_GENLIST_CHECK(obj);
7104 eo_do(obj, elm_interface_scrollable_policy_set(policy_h, policy_v));
7108 _elm_genlist_elm_interface_scrollable_policy_set(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v)
7110 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
7111 (policy_v >= ELM_SCROLLER_POLICY_LAST))
7114 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_set(policy_h, policy_v));
7118 elm_genlist_scroller_policy_get(const Evas_Object *obj,
7119 Elm_Scroller_Policy *policy_h,
7120 Elm_Scroller_Policy *policy_v)
7122 ELM_GENLIST_CHECK(obj);
7123 eo_do( obj, elm_interface_scrollable_policy_get(policy_h, policy_v));
7127 _elm_genlist_elm_interface_scrollable_policy_get(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED, Elm_Scroller_Policy *policy_h, Elm_Scroller_Policy *policy_v)
7129 Elm_Scroller_Policy s_policy_h, s_policy_v;
7131 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_get
7132 (&s_policy_h, &s_policy_v));
7133 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
7134 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
7138 _elm_genlist_realized_items_update(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED)
7141 Elm_Object_Item *it;
7143 list = elm_genlist_realized_items_get(obj);
7144 EINA_LIST_FREE(list, it)
7145 elm_genlist_item_update(it);
7149 _elm_genlist_item_decorate_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
7150 const char *decorate_it_type,
7151 Eina_Bool decorate_it_set)
7153 Elm_Genlist_Data *sd;
7155 Elm_Object_Item *eo_it2 = NULL;
7157 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7158 sd = GL_IT(it)->wsd;
7160 if (!decorate_it_type) return;
7161 if (eo_do(eo_it, elm_wdg_item_disabled_get())) return;
7162 if (sd->decorate_all_mode) return;
7164 if ((sd->mode_item == it) &&
7165 (!strcmp(decorate_it_type, sd->decorate_it_type)) &&
7168 if (!it->itc->decorate_item_style) return;
7169 it->decorate_it_set = decorate_it_set;
7173 EINA_LIST_FOREACH(sd->selected, l, eo_it2)
7175 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
7177 elm_genlist_item_selected_set(eo_it2, EINA_FALSE);
7182 Elm_Gen_Item *it2 = NULL;
7183 eo_it2 = elm_genlist_selected_item_get(sd->obj);
7184 if (eo_it2) it2 = eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
7185 if (it2 && it2->realized)
7186 elm_genlist_item_selected_set(eo_it2, EINA_FALSE);
7189 if (((sd->decorate_it_type)
7190 && (strcmp(decorate_it_type, sd->decorate_it_type))) ||
7191 (decorate_it_set) || ((it == sd->mode_item) && (!decorate_it_set)))
7192 _decorate_item_unset(sd);
7194 eina_stringshare_replace(&sd->decorate_it_type, decorate_it_type);
7195 if (decorate_it_set) _decorate_item_set(it);
7198 EOLIAN static const char *
7199 _elm_genlist_item_decorate_mode_get(Eo *eo_i EINA_UNUSED, Elm_Gen_Item *i)
7201 ELM_GENLIST_ITEM_CHECK_OR_RETURN(i, NULL);
7202 return GL_IT(i)->wsd->decorate_it_type;
7205 EOLIAN static Elm_Object_Item *
7206 _elm_genlist_decorated_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7208 return EO_OBJ(sd->mode_item);
7211 EOLIAN static Eina_Bool
7212 _elm_genlist_decorate_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7214 return sd->decorate_all_mode;
7218 _elm_genlist_decorate_mode_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool decorated)
7220 Elm_Object_Item *eo_it;
7222 Elm_Object_Item *deco_it;
7224 decorated = !!decorated;
7225 if (sd->decorate_all_mode == decorated) return;
7226 // decorate_all_mode should be set first
7227 // because content_get func. will be called after this
7228 // and user can check whether decorate_all_mode_ is enabled.
7229 sd->decorate_all_mode = decorated;
7231 ELM_SAFE_FREE(sd->tree_effect_animator, ecore_animator_del);
7232 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
7234 list = elm_genlist_realized_items_get(obj);
7235 if (!sd->decorate_all_mode)
7237 EINA_LIST_FREE(list, eo_it)
7239 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
7240 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
7241 _decorate_all_item_unrealize(it);
7243 _item_cache_zero(sd);
7247 // unset decorated item
7248 deco_it = elm_genlist_decorated_item_get(obj);
7251 elm_genlist_item_decorate_mode_set
7252 (deco_it, elm_genlist_item_decorate_mode_get
7253 (deco_it), EINA_FALSE);
7254 _decorate_item_finished_signal_cb(deco_it, obj, NULL, NULL);
7257 EINA_LIST_FREE(list, eo_it)
7259 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
7260 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
7262 if (it->itc->decorate_all_item_style)
7263 _decorate_all_item_realize(it, EINA_TRUE);
7268 ecore_job_del(sd->calc_job);
7269 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
7273 _elm_genlist_reorder_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool reorder_mode)
7275 Eina_List *realized;
7276 Elm_Object_Item *eo_it;
7278 if (sd->reorder_mode == !!reorder_mode) return;
7279 sd->reorder_mode = !!reorder_mode;
7280 realized = elm_genlist_realized_items_get(obj);
7281 EINA_LIST_FREE(realized, eo_it)
7283 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
7284 if (sd->reorder_mode)
7286 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
7287 if (it->deco_all_view)
7289 edje_object_signal_emit(it->deco_all_view,
7290 SIGNAL_REORDER_MODE_SET, "elm");
7295 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_UNSET, "elm");
7296 if (it->deco_all_view)
7298 edje_object_signal_emit(it->deco_all_view,
7299 SIGNAL_REORDER_MODE_UNSET, "elm");
7305 EOLIAN static Eina_Bool
7306 _elm_genlist_reorder_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7308 return sd->reorder_mode;
7311 EOLIAN static Elm_Genlist_Item_Type
7312 _elm_genlist_item_type_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7314 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
7316 return GL_IT(it)->type;
7319 EAPI Elm_Genlist_Item_Class *
7320 elm_genlist_item_class_new(void)
7322 Elm_Genlist_Item_Class *itc = ELM_NEW(Elm_Genlist_Item_Class);
7323 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
7325 itc->version = CLASS_ALLOCATED;
7327 itc->delete_me = EINA_FALSE;
7333 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
7335 if (itc && (itc->version == CLASS_ALLOCATED))
7337 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
7338 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
7348 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
7350 if (itc && (itc->version == CLASS_ALLOCATED))
7353 if (itc->refcount == 0) itc->refcount--;
7358 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
7360 if (itc && (itc->version == CLASS_ALLOCATED))
7362 if (itc->refcount > 0) itc->refcount--;
7363 if (itc->delete_me && (!itc->refcount))
7364 elm_genlist_item_class_free(itc);
7369 _flip_job(void *data)
7371 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
7372 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7375 _elm_genlist_item_unrealize(it, EINA_FALSE);
7377 it->flipped = EINA_TRUE;
7378 it->item->nocache = EINA_TRUE;
7379 ecore_job_del(sd->calc_job);
7380 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
7384 _elm_genlist_item_flip_set(Eo *eo_it, Elm_Gen_Item *it, Eina_Bool flip)
7386 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7389 if (it->flipped == flip) return;
7393 ecore_job_add(_flip_job, it);
7397 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_DISABLED, "elm");
7398 if (GL_IT(it)->wsd->decorate_all_mode)
7399 edje_object_signal_emit(it->deco_all_view, SIGNAL_FLIP_DISABLED,
7403 _item_cache_zero(GL_IT(it)->wsd);
7404 elm_genlist_item_update(eo_it);
7405 it->item->nocache = EINA_FALSE;
7409 EOLIAN static Eina_Bool
7410 _elm_genlist_item_flip_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7412 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7418 _elm_genlist_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Elm_Object_Select_Mode mode)
7420 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (sd->select_mode == mode))
7423 sd->select_mode = mode;
7425 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
7426 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
7430 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it)
7435 EOLIAN static Elm_Object_Select_Mode
7436 _elm_genlist_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7438 return sd->select_mode;
7442 _elm_genlist_highlight_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool highlight)
7444 sd->highlight = !!highlight;
7447 EOLIAN static Eina_Bool
7448 _elm_genlist_highlight_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7450 return sd->highlight;
7454 _elm_genlist_item_select_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
7455 Elm_Object_Select_Mode mode)
7457 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7458 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7460 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (it->select_mode == mode))
7463 it->select_mode = mode;
7465 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
7466 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
7469 if (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
7471 it->item->mincalcd = EINA_FALSE;
7472 it->item->updateme = EINA_TRUE;
7473 if (it->item->block) it->item->block->updateme = EINA_TRUE;
7474 ecore_job_del(sd->update_job);
7475 sd->update_job = ecore_job_add(_update_job, sd->obj);
7477 // reset homogeneous item size
7478 if (sd->homogeneous)
7480 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
7481 sd->group_item_width = sd->group_item_height = 0;
7483 sd->item_width = sd->item_height = 0;
7488 EOLIAN static Elm_Object_Select_Mode
7489 _elm_genlist_item_select_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7491 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
7493 return it->select_mode;
7497 _elm_genlist_tree_effect_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enabled)
7499 sd->tree_effect_enabled = !!enabled;
7502 EOLIAN static Eina_Bool
7503 _elm_genlist_tree_effect_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7505 return sd->tree_effect_enabled;
7509 _elm_genlist_focus_on_selection_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enabled)
7511 sd->focus_on_selection_enabled = !!enabled;
7514 EOLIAN static Eina_Bool
7515 _elm_genlist_focus_on_selection_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7517 return sd->focus_on_selection_enabled;
7520 EAPI Elm_Object_Item *
7521 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth)
7523 Elm_Gen_Item *it = NULL;
7527 ELM_GENLIST_CHECK(obj) NULL;
7528 ELM_GENLIST_DATA_GET(obj, sd);
7530 if (!sd->items) return NULL;
7532 a = eina_inlist_accessor_new(sd->items);
7533 if (!a) return NULL;
7534 if (eina_accessor_data_get(a, nth, &data))
7535 it = ELM_GEN_ITEM_FROM_INLIST(data);
7536 eina_accessor_free(a);
7541 _elm_genlist_elm_widget_focus_highlight_geometry_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
7543 Evas_Coord ox, oy, oh, ow, item_x = 0, item_y = 0, item_w = 0, item_h = 0;
7545 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7547 if (sd->focused_item)
7549 ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focus_it);
7550 evas_object_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
7551 elm_widget_focus_highlight_focus_part_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
7563 if (item_y > (oy + oh - item_h))
7565 *y = oy + oh - item_h;
7568 if ((item_x + item_w) > (ox + ow))
7578 EOLIAN static Elm_Object_Item *
7579 _elm_genlist_search_by_text_item_get(Eo *obj EINA_UNUSED,
7580 Elm_Genlist_Data *sd,
7581 Elm_Object_Item *item_to_search_from,
7582 const char *part_name,
7583 const char *pattern,
7584 Elm_Glob_Match_Flags flags)
7586 Elm_Gen_Item *it = NULL;
7588 Eina_Inlist *start = NULL;
7591 if (!pattern) return NULL;
7592 if (!sd->items) return NULL;
7594 if (flags & ELM_GLOB_MATCH_NO_ESCAPE) fnflags |= FNM_NOESCAPE;
7595 if (flags & ELM_GLOB_MATCH_PATH) fnflags |= FNM_PATHNAME;
7596 if (flags & ELM_GLOB_MATCH_PERIOD) fnflags |= FNM_PERIOD;
7598 if (flags & ELM_GLOB_MATCH_NOCASE) fnflags |= FNM_CASEFOLD;
7601 start = (item_to_search_from) ?
7602 EINA_INLIST_GET((Elm_Gen_Item *)eo_data_scope_get(item_to_search_from, ELM_GENLIST_ITEM_CLASS)) :
7604 EINA_INLIST_FOREACH(start, it)
7606 if (!it->itc->func.text_get) continue;
7607 str = it->itc->func.text_get((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), part_name);
7609 if (!fnmatch(pattern, str, fnflags))
7619 EOLIAN static Elm_Object_Item*
7620 _elm_genlist_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7622 return sd->focused_item;
7626 _elm_genlist_elm_widget_item_loop_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enable)
7628 if (enable == EINA_TRUE)
7630 _elm_widget_focus_highlight_signal_callback_add(obj, "elm,focus,move,down,end",
7631 "elm", _elm_genlist_focus_highlight_move_down_end_cb, obj);
7632 _elm_widget_focus_highlight_signal_callback_add(obj, "elm,focus,move,up,end",
7633 "elm", _elm_genlist_focus_highlight_move_up_end_cb, obj);
7637 _elm_widget_focus_highlight_signal_callback_del(obj, "elm,focus,move,down,end",
7638 "elm", _elm_genlist_focus_highlight_move_down_end_cb);
7639 _elm_widget_focus_highlight_signal_callback_del(obj, "elm,focus,move,up,end",
7640 "elm", _elm_genlist_focus_highlight_move_up_end_cb);
7643 sd->item_loop_enable = !!enable;
7646 EOLIAN static Eina_Bool
7647 _elm_genlist_elm_widget_item_loop_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7649 return sd->item_loop_enable;
7653 _elm_genlist_class_constructor(Eo_Class *klass)
7655 if (_elm_config->access_mode)
7656 _elm_genlist_smart_focus_next_enable = EINA_TRUE;
7658 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
7661 EOLIAN const Elm_Atspi_Action *
7662 _elm_genlist_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd EINA_UNUSED)
7664 static Elm_Atspi_Action atspi_actions[] = {
7665 { "move,prior", "move", "prior", _key_action_move},
7666 { "move,next", "move", "next", _key_action_move},
7667 { "move,left", "move", "left", _key_action_move},
7668 { "move,right", "move", "right", _key_action_move},
7669 { "move,up", "move", "up", _key_action_move},
7670 { "move,up,multi", "move", "up_multi", _key_action_move},
7671 { "move,down", "move", "down", _key_action_move},
7672 { "move,down,multi", "move", "down_multi", _key_action_move},
7673 { "move,first", "move", "first", _key_action_move},
7674 { "move,last", "move", "last", _key_action_move},
7675 { "select", "select", NULL, _key_action_select},
7676 { "escape", "escape", NULL, _key_action_escape},
7677 { NULL, NULL, NULL, NULL }
7679 return &atspi_actions[0];
7682 #include "elm_genlist.eo.c"
7683 #include "elm_genlist_item.eo.c"