2 # include "elementary_config.h"
7 #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
8 //TIZEN_ONLY(20160329): genlist: enhance accessibility scroll & highlight (30d9a6012e629cd9ea60eae8d576f3ebb94ada86)
9 #define ELM_INTERFACE_ATSPI_COMPONENT_PROTECTED
11 #define ELM_INTERFACE_ATSPI_SELECTION_PROTECTED
12 #define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
13 #define ELM_WIDGET_ITEM_PROTECTED
15 #include <Elementary.h>
16 #include <Elementary_Cursor.h>
19 #include "elm_widget_genlist.h"
20 #include "elm_interface_scrollable.h"
22 #define MY_PAN_CLASS ELM_GENLIST_PAN_CLASS
24 #define MY_PAN_CLASS_NAME "Elm_Genlist_Pan"
25 #define MY_PAN_CLASS_NAME_LEGACY "elm_genlist_pan"
27 #define MY_CLASS ELM_GENLIST_CLASS
29 #define MY_CLASS_NAME "Elm_Genlist"
30 #define MY_CLASS_NAME_LEGACY "elm_genlist"
32 // internally allocated
33 #define CLASS_ALLOCATED 0x3a70f11f
35 #define MAX_ITEMS_PER_BLOCK 32
36 #define REORDER_EFFECT_TIME 0.5
37 #define MULTI_DOWN_TIME 1.0
38 #define SWIPE_TIME 0.4
39 #define SCR_HOLD_TIME 0.1
41 #define ERR_ABORT(_msg) \
44 if (getenv("ELM_ERROR_ABORT")) abort(); \
47 #define ELM_PRIV_GENLIST_SIGNALS(cmd) \
48 cmd(SIG_ACTIVATED, "activated", "") \
49 cmd(SIG_CLICKED_DOUBLE, "clicked,double", "") \
50 cmd(SIG_CLICKED_RIGHT, "clicked,right", "") \
51 cmd(SIG_SELECTED, "selected", "") \
52 cmd(SIG_UNSELECTED, "unselected", "") \
53 cmd(SIG_EXPANDED, "expanded", "") \
54 cmd(SIG_CONTRACTED, "contracted", "") \
55 cmd(SIG_EXPAND_REQUEST, "expand,request", "") \
56 cmd(SIG_CONTRACT_REQUEST, "contract,request", "") \
57 cmd(SIG_REALIZED, "realized", "") \
58 cmd(SIG_UNREALIZED, "unrealized", "") \
59 cmd(SIG_DRAG_START_UP, "drag,start,up", "") \
60 cmd(SIG_DRAG_START_DOWN, "drag,start,down", "") \
61 cmd(SIG_DRAG_START_LEFT, "drag,start,left", "") \
62 cmd(SIG_DRAG_START_RIGHT, "drag,start,right", "") \
63 cmd(SIG_DRAG_STOP, "drag,stop", "") \
64 cmd(SIG_DRAG, "drag", "") \
65 cmd(SIG_LONGPRESSED, "longpressed", "") \
66 cmd(SIG_SCROLL, "scroll", "") \
67 cmd(SIG_SCROLL_ANIM_START, "scroll,anim,start", "") \
68 cmd(SIG_SCROLL_ANIM_STOP, "scroll,anim,stop", "") \
69 cmd(SIG_SCROLL_DRAG_START, "scroll,drag,start", "") \
70 cmd(SIG_SCROLL_DRAG_STOP, "scroll,drag,stop", "") \
71 cmd(SIG_EDGE_TOP, "edge,top", "") \
72 cmd(SIG_EDGE_BOTTOM, "edge,bottom", "") \
73 cmd(SIG_EDGE_LEFT, "edge,left", "") \
74 cmd(SIG_EDGE_RIGHT, "edge,right", "") \
75 cmd(SIG_VBAR_DRAG, "vbar,drag", "") \
76 cmd(SIG_VBAR_PRESS, "vbar,press", "") \
77 cmd(SIG_VBAR_UNPRESS, "vbar,unpress", "") \
78 cmd(SIG_HBAR_DRAG, "hbar,drag", "") \
79 cmd(SIG_HBAR_PRESS, "hbar,press", "") \
80 cmd(SIG_HBAR_UNPRESS, "hbar,unpress", "") \
81 cmd(SIG_MULTI_SWIPE_LEFT, "multi,swipe,left", "") \
82 cmd(SIG_MULTI_SWIPE_RIGHT, "multi,swipe,right", "") \
83 cmd(SIG_MULTI_SWIPE_UP, "multi,swipe,up", "") \
84 cmd(SIG_MULTI_SWIPE_DOWN, "multi,swipe,down", "") \
85 cmd(SIG_MULTI_PINCH_OUT, "multi,pinch,out", "") \
86 cmd(SIG_MULTI_PINCH_IN, "multi,pinch,in", "") \
87 cmd(SIG_SWIPE, "swipe", "") \
88 cmd(SIG_MOVED, "moved", "") \
89 cmd(SIG_MOVED_AFTER, "moved,after", "") \
90 cmd(SIG_MOVED_BEFORE, "moved,before", "") \
91 cmd(SIG_INDEX_UPDATE, "index,update", "") \
92 cmd(SIG_TREE_EFFECT_FINISHED , "tree,effect,finished", "") \
93 cmd(SIG_HIGHLIGHTED, "highlighted", "") \
94 cmd(SIG_UNHIGHLIGHTED, "unhighlighted", "") \
95 cmd(SIG_ITEM_FOCUSED, "item,focused", "") \
96 cmd(SIG_ITEM_UNFOCUSED, "item,unfocused", "") \
97 cmd(SIG_PRESSED, "pressed", "") \
98 cmd(SIG_RELEASED, "released", "") \
99 cmd(SIG_CHANGED, "changed", "") \
100 cmd(SIG_ATSPI_SCREEN_READER_CHANGED, "atspi,screen,reader,changed", "") \
101 cmd(SIG_FILTER_DONE, "filter,done", "") \
102 cmd(SIG_LANG_CHANGED, "language,changed", "") // TIZEN_ONLY(20170113)
104 ELM_PRIV_GENLIST_SIGNALS(ELM_PRIV_STATIC_VARIABLE_DECLARE);
106 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
107 ELM_PRIV_GENLIST_SIGNALS(ELM_PRIV_SMART_CALLBACKS_DESC)
108 {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
109 {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
110 {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
111 {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
112 //TIZEN_ONLY(20161213): apply screen_reader_changed callback
113 {SIG_ATSPI_SCREEN_READER_CHANGED, ""},
118 #undef ELM_PRIV_GENLIST_SIGNALS
120 /* edje signals internally used */
121 static const char SIGNAL_ENABLED[] = "elm,state,enabled";
122 static const char SIGNAL_DISABLED[] = "elm,state,disabled";
123 static const char SIGNAL_SELECTED[] = "elm,state,selected";
124 static const char SIGNAL_UNSELECTED[] = "elm,state,unselected";
125 static const char SIGNAL_EXPANDED[] = "elm,state,expanded";
126 static const char SIGNAL_CONTRACTED[] = "elm,state,contracted";
127 static const char SIGNAL_FLIP_ENABLED[] = "elm,state,flip,enabled";
128 static const char SIGNAL_FLIP_DISABLED[] = "elm,state,flip,disabled";
129 static const char SIGNAL_DECORATE_ENABLED[] = "elm,state,decorate,enabled";
130 static const char SIGNAL_DECORATE_DISABLED[] = "elm,state,decorate,disabled";
131 static const char SIGNAL_DECORATE_ENABLED_EFFECT[] = "elm,state,decorate,enabled,effect";
132 static const char SIGNAL_REORDER_ENABLED[] = "elm,state,reorder,enabled";
133 static const char SIGNAL_REORDER_DISABLED[] = "elm,state,reorder,disabled";
134 static const char SIGNAL_REORDER_MODE_SET[] = "elm,state,reorder,mode_set";
135 static const char SIGNAL_REORDER_MODE_UNSET[] = "elm,state,reorder,mode_unset";
136 static const char SIGNAL_CONTRACT_FLIP[] = "elm,state,contract_flip";
137 static const char SIGNAL_SHOW[] = "elm,state,show";
138 static const char SIGNAL_HIDE[] = "elm,state,hide";
139 static const char SIGNAL_FLIP_ITEM[] = "elm,action,flip_item";
140 static const char SIGNAL_ODD[] = "elm,state,odd";
141 static const char SIGNAL_EVEN[] = "elm,state,even";
142 static const char SIGNAL_FOCUSED[] = "elm,state,focused";
143 static const char SIGNAL_UNFOCUSED[] = "elm,state,unfocused";
144 static const char SIGNAL_LIST_SINGLE[] = "elm,state,list,single";
145 static const char SIGNAL_LIST_FIRST[] = "elm,state,list,first";
146 static const char SIGNAL_LIST_LAST[] = "elm,state,list,last";
147 static const char SIGNAL_LIST_MIDDLE[] = "elm,state,list,middle";
148 static const char SIGNAL_GROUP_SINGLE[] = "elm,state,group,single";
149 static const char SIGNAL_GROUP_FIRST[] = "elm,state,group,first";
150 static const char SIGNAL_GROUP_LAST[] = "elm,state,group,last";
151 static const char SIGNAL_GROUP_MIDDLE[] = "elm,state,group,middle";
152 //Tizen Only(20160307)
153 static const char SIGNAL_DEFAULT[] = "elm,state,default";
155 static void _item_unrealize(Elm_Gen_Item *it);
156 static Eina_Bool _item_select(Elm_Gen_Item *it);
157 static void _item_unselect(Elm_Gen_Item *it);
158 static void _item_highlight(Elm_Gen_Item *it);
159 static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
160 static Eina_Bool _key_action_select(Evas_Object *obj, const char *params);
161 static Eina_Bool _key_action_escape(Evas_Object *obj, const char *params);
162 static void _calc_job(void *data);
163 static void _update_job(void *data);
164 static Eina_Bool _item_block_recalc(Item_Block *itb, int in, Eina_Bool qadd);
165 static void _item_mouse_callbacks_add(Elm_Gen_Item *it, Evas_Object *view);
166 static void _item_mouse_callbacks_del(Elm_Gen_Item *it, Evas_Object *view);
167 static void _access_activate_cb(void *data EINA_UNUSED,
168 Evas_Object *part_obj EINA_UNUSED,
169 Elm_Object_Item *item);
170 static void _decorate_item_set(Elm_Gen_Item *);
171 static void _internal_elm_genlist_clear(Evas_Object *obj);
172 static Eina_Bool _item_filtered_get(Elm_Gen_Item *it);
174 static const Elm_Action key_actions[] = {
175 {"move", _key_action_move},
176 {"select", _key_action_select},
177 {"escape", _key_action_escape},
182 _size_cache_free(void *data)
188 _is_no_select(Elm_Gen_Item *it)
190 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
192 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
193 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
194 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
195 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
201 _elm_genlist_pan_elm_pan_pos_set(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord x, Evas_Coord y)
205 Elm_Genlist_Data *sd = psd->wsd;
207 if ((x == sd->pan_x) && (y == sd->pan_y)) return;
211 EINA_INLIST_FOREACH(sd->blocks, itb)
213 if ((itb->y + itb->h) > y)
218 EINA_LIST_FOREACH(itb->items, l2, it)
220 if ((itb->y + it->y) >= y)
222 sd->anchor_item = it;
223 sd->anchor_y = -(itb->y + it->y - y);
230 if (!sd->reorder_move_animator) evas_object_smart_changed(obj);
234 _elm_genlist_pan_elm_pan_pos_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y)
236 if (x) *x = psd->wsd->pan_x;
237 if (y) *y = psd->wsd->pan_y;
241 _elm_genlist_pan_elm_pan_pos_max_get(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y)
245 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
246 ow = psd->wsd->minw - ow;
248 oh = psd->wsd->minh - oh;
255 _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)
262 _elm_genlist_pan_elm_pan_content_size_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *w, Evas_Coord *h)
264 if (w) *w = psd->wsd->minw;
265 if (h) *h = psd->wsd->minh;
268 //Tizen Only(20170113)
270 _elm_genlist_pan_elm_pan_pos_adjust(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd EINA_UNUSED, Evas_Coord *x EINA_UNUSED, Evas_Coord *y EINA_UNUSED)
277 _elm_genlist_pan_evas_object_smart_del(Eo *obj, Elm_Genlist_Pan_Data *psd)
279 ecore_job_del(psd->resize_job);
281 eo_do_super(obj, MY_PAN_CLASS, evas_obj_smart_del());
285 _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)
287 psd->wsd->pan_changed = EINA_TRUE;
288 evas_object_smart_changed(obj);
289 ELM_SAFE_FREE(psd->wsd->calc_job, ecore_job_del);
293 _elm_genlist_pan_smart_resize_job(void *data)
295 ELM_GENLIST_PAN_DATA_GET(data, psd);
297 elm_layout_sizing_eval(psd->wobj);
298 psd->resize_job = NULL;
302 _elm_genlist_pan_evas_object_smart_resize(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord w, Evas_Coord h)
306 Elm_Genlist_Data *sd = psd->wsd;
308 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
309 if ((ow == w) && (oh == h)) return;
310 if ((sd->mode == ELM_LIST_COMPRESS) && (ow != w))
313 ecore_job_del(psd->resize_job);
315 ecore_job_add(_elm_genlist_pan_smart_resize_job, obj);
317 sd->pan_changed = EINA_TRUE;
318 evas_object_smart_changed(obj);
319 ecore_job_del(sd->calc_job);
320 // if the width changed we may have to resize content if scrollbar went
321 // away or appeared to queue a job to deal with it. it should settle in
322 // the end to a steady-state
324 sd->calc_job = ecore_job_add(_calc_job, psd->wobj);
330 _item_text_realize(Elm_Gen_Item *it,
340 if (!it->itc->func.text_get) return;
343 *source = elm_widget_stringlist_get
344 (edje_object_data_get(target, "texts"));
345 EINA_LIST_FOREACH(*source, l, key)
347 if (parts && fnmatch(parts, key, FNM_PERIOD)) continue;
349 s = it->itc->func.text_get
350 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
353 edje_object_part_text_escaped_set(target, key, s);
356 snprintf(buf, sizeof(buf), "elm,state,%s,visible", key);
357 edje_object_signal_emit(target, buf, "elm");
361 edje_object_part_text_set(target, key, "");
362 snprintf(buf, sizeof(buf), "elm,state,%s,hidden", key);
363 edje_object_signal_emit(target, buf, "elm");
365 if (_elm_config->atspi_mode)
366 elm_interface_atspi_accessible_name_changed_signal_emit(EO_OBJ(it));
371 _item_content_realize(Elm_Gen_Item *it,
373 Eina_List **contents,
378 Evas_Object *content;
385 EINA_LIST_FREE(*contents, content)
386 evas_object_del(content);
388 if ((!it->itc->func.content_get) &&
389 ((it->itc->version < 3) || (!it->itc->func.reusable_content_get))) return;
391 source = elm_widget_stringlist_get(edje_object_data_get(target, src));
393 EINA_LIST_FREE(source, key)
395 if (parts && fnmatch(parts, key, FNM_PERIOD))
398 Evas_Object *old = NULL;
399 old = edje_object_part_swallow_get(target, key);
401 // Reuse content by popping from the cache
403 if (it->itc->version >= 3 && it->itc->func.reusable_content_get)
404 content = it->itc->func.reusable_content_get(
405 (void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key, old);
408 // Call the content get
409 if (it->itc->func.content_get)
410 content = it->itc->func.content_get
411 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
414 snprintf(buf, sizeof(buf), "elm,state,%s,hidden", key);
415 edje_object_signal_emit(target, buf, "elm");
422 // FIXME: cause elm_layout sizing eval is delayed by smart calc,
423 // genlist cannot get actual min size of edje.
424 // This is workaround code to set min size directly.
425 if (eo_class_get(content) == ELM_LAYOUT_CLASS)
427 Evas_Coord old_w, old_h, minw = 0, minh = 0;
428 evas_object_size_hint_min_get(content, &old_w, &old_h);
429 edje_object_size_min_calc(elm_layout_edje_get(content), &minw, &minh);
431 if (old_w > minw) minw = old_w;
432 if (old_h > minh) minw = old_h;
433 evas_object_size_hint_min_set(content, minw, minh);
436 if (!edje_object_part_swallow(target, key, content))
438 ERR("%s (%p) can not be swallowed into %s",
439 evas_object_type_get(content), content, key);
440 evas_object_del(content);
443 elm_widget_sub_object_add(WIDGET(it), content);
445 *contents = eina_list_append(*contents, content);
447 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()))
448 elm_widget_disabled_set(content, EINA_TRUE);
450 snprintf(buf, sizeof(buf), "elm,state,%s,visible", key);
451 edje_object_signal_emit(target, buf, "elm");
453 if (old && content != old)
455 *contents = eina_list_remove(*contents, old);
456 evas_object_del(old);
459 if (_elm_config->atspi_mode && eo_isa(content, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
461 eo_do(content, elm_interface_atspi_accessible_parent_set(EO_OBJ(it)));
462 elm_interface_atspi_accessible_children_changed_added_signal_emit(EO_OBJ(it), content);
468 _item_state_realize(Elm_Gen_Item *it, Evas_Object *target, const char *parts)
474 if (!it->itc->func.state_get) return;
476 src = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
477 EINA_LIST_FREE(src, key)
479 if (parts && fnmatch(parts, key, FNM_PERIOD)) continue;
481 Eina_Bool on = it->itc->func.state_get
482 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
486 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
487 edje_object_signal_emit(target, buf, "elm");
491 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
492 edje_object_signal_emit(target, buf, "elm");
495 edje_object_message_signal_process(target);
499 * Apply the right style for the created item view.
501 // TIZEN_ONLY(20150622): update genlist style set
503 _view_style_find(Elm_Gen_Item *it, Evas_Object *view, const char *style)
507 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
509 // FIXME: There exists
510 // item, item_compress, item_odd, item_compress_odd,
511 // tree, tree_compress, tree_odd, tree_odd_compress
512 // But those used case by case. :-(
513 // Anyway, belows codes are for backward..
514 if (it->decorate_it_set)
516 // item, item_compress, item_odd, item_compress_odd
517 strncpy(buf, "item", sizeof(buf));
518 if (sd->mode == ELM_LIST_COMPRESS)
519 strncat(buf, "_compress", sizeof(buf) - strlen(buf) - 1);
521 if (it->item->order_num_in & 0x1)
522 strncat(buf, "_odd", sizeof(buf) - strlen(buf) - 1);
523 strncat(buf, "/", sizeof(buf) - strlen(buf) - 1);
524 strncat(buf, style, sizeof(buf) - strlen(buf) - 1);
528 // item, item_compress, tree, tree_compress
529 if (it->item->type & ELM_GENLIST_ITEM_TREE)
530 snprintf(buf, sizeof(buf), "tree%s/%s",
531 sd->mode == ELM_LIST_COMPRESS ? "_compress" :
532 "", style ? : "default");
534 snprintf(buf, sizeof(buf), "item%s/%s",
535 sd->mode == ELM_LIST_COMPRESS ? "_compress" :
536 "",style ? : "default");
539 if (!elm_widget_theme_object_set(WIDGET(it), view,
541 elm_widget_style_get(WIDGET(it))))
543 snprintf(buf2, sizeof(buf2), "item/%s", style ? : "default");
544 ERR("%s is not a valid genlist item style. fallback to %s", buf, buf2);
545 if (!strcmp(buf, buf2)) return EINA_FALSE;
546 if (!elm_widget_theme_object_set(WIDGET(it), view,
548 elm_widget_style_get(WIDGET(it))))
557 _view_style_update(Elm_Gen_Item *it, Evas_Object *view, const char *style)
559 const char *stacking_even;
560 const char *stacking;
562 // TIZEN_ONLY(20150622): update genlist style set
563 if (!_view_style_find(it, view, style))
566 ERR("%s is not a valid genlist item style. "
567 "Automatically falls back into default style.",
569 elm_widget_theme_object_set
570 (WIDGET(it), view, "genlist", "item/default", "default");
573 edje_object_mirrored_set(view, elm_widget_mirrored_get(WIDGET(it)));
574 edje_object_scale_set(view, elm_widget_scale_get(WIDGET(it))
575 * elm_config_scale_get());
577 stacking_even = edje_object_data_get(view, "stacking_even");
578 if (!stacking_even) stacking_even = "above";
579 it->item->stacking_even = !!strcmp("above", stacking_even);
581 stacking = edje_object_data_get(view, "stacking");
582 if (!stacking) stacking = "yes";
583 it->item->nostacking = !!strcmp("yes", stacking);
587 * Create a VIEW(it) during _item_realize()
590 _view_create(Elm_Gen_Item *it, const char *style)
592 Evas_Object *view = edje_object_add(evas_object_evas_get(WIDGET(it)));
593 evas_object_smart_member_add(view, GL_IT(it)->wsd->pan_obj);
594 elm_widget_sub_object_add(WIDGET(it), view);
595 edje_object_scale_set(view, elm_widget_scale_get(WIDGET(it)) *
596 elm_config_scale_get());
598 _view_style_update(it, view, style);
603 _view_clear(Evas_Object *view, Eina_List **texts, Eina_List **contents)
609 EINA_LIST_FOREACH(*texts, l, part)
610 edje_object_part_text_set(view, part, NULL);
611 ELM_SAFE_FREE(*texts, elm_widget_stringlist_free);
615 EINA_LIST_FREE(*contents, c)
621 _item_scroll(Elm_Genlist_Data *sd)
624 Elm_Gen_Item *it = NULL;
625 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
627 if (!sd->show_item) return;
629 evas_object_geometry_get(sd->pan_obj, NULL, NULL, &ow, &oh);
631 dx = it->x + it->item->block->x;
632 dy = it->y + it->item->block->y;
633 dw = it->item->block->w;
636 // hold on scrolling to item until block size calculation is finished.
639 switch (sd->scroll_to_type)
641 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
642 if (it->item->group_item) gith = it->item->group_item->item->h;
646 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
647 dy += ((it->item->h / 2) - (oh / 2));
650 case ELM_GENLIST_ITEM_SCROLLTO_IN:
652 if ((sd->expanded_item) &&
653 ((sd->show_item->y + sd->show_item->item->block->y
654 + sd->show_item->item->h) -
655 (sd->expanded_item->y + sd->expanded_item->item->block->y) > oh))
657 it = sd->expanded_item;
658 if (it->item->group_item) gith = it->item->group_item->item->h;
659 dx = it->x + it->item->block->x;
660 dy = it->y + it->item->block->y - gith;
661 dw = it->item->block->w;
665 if ((it->item->group_item) &&
666 (sd->pan_y > (it->y + it->item->block->y)))
667 gith = it->item->group_item->item->h;
674 eo_do(sd->obj, elm_interface_scrollable_region_bring_in(dx, dy, dw, dh));
676 eo_do(sd->obj, elm_interface_scrollable_content_region_show
679 it->item->show_me = EINA_FALSE;
680 sd->show_item = NULL;
681 sd->auto_scroll_enabled = EINA_FALSE;
682 sd->check_scroll = EINA_FALSE;
686 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
689 if (!it->realized) return;
690 if (GL_IT(it)->wsd->reorder_it == it)
692 WRN("reordering item should not be unrealized");
696 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
698 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_UNREALIZED, EO_OBJ(it)));
699 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
701 _view_clear(VIEW(it), &(it->texts), NULL);
702 ELM_SAFE_FREE(it->item_focus_chain, eina_list_free);
704 eo_do(EO_OBJ(it), elm_wdg_item_track_cancel());
708 it->realized = EINA_FALSE;
709 it->want_unrealize = EINA_FALSE;
711 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
712 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
716 _item_block_unrealize(Item_Block *itb)
720 Eina_Bool dragging = EINA_FALSE;
722 if (!itb->realized) return;
723 evas_event_freeze(evas_object_evas_get((itb->sd)->obj));
725 EINA_LIST_FOREACH(itb->items, l, it)
727 if (itb->must_recalc || !(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP))
731 dragging = EINA_TRUE;
732 it->want_unrealize = EINA_TRUE;
735 _elm_genlist_item_unrealize(it, EINA_FALSE);
740 itb->realized = EINA_FALSE;
741 itb->want_unrealize = EINA_TRUE;
744 itb->want_unrealize = EINA_FALSE;
745 evas_event_thaw(evas_object_evas_get((itb->sd)->obj));
746 evas_event_thaw_eval(evas_object_evas_get((itb->sd)->obj));
750 _must_recalc_idler(void *data)
752 ELM_GENLIST_DATA_GET(data, sd);
754 ecore_job_del(sd->calc_job);
755 sd->calc_job = ecore_job_add(_calc_job, data);
756 sd->must_recalc_idler = NULL;
757 return ECORE_CALLBACK_CANCEL;
761 _calc_job(void *data)
764 Item_Block *itb, *chb = NULL;
765 Evas_Coord pan_w = 0, pan_h = 0;
766 ELM_GENLIST_DATA_GET(data, sd);
767 Eina_Bool minw_change = EINA_FALSE;
768 Eina_Bool did_must_recalc = EINA_FALSE;
769 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw = 0;
771 evas_object_geometry_get(sd->pan_obj, NULL, NULL, &ow, &sd->h);
772 if (sd->mode == ELM_LIST_COMPRESS)
773 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
774 (NULL, NULL, &vw, NULL));
776 if (sd->w != ow) sd->w = ow;
778 evas_event_freeze(evas_object_evas_get(sd->obj));
779 EINA_INLIST_FOREACH(sd->blocks, itb)
781 Eina_Bool show_me = EINA_FALSE;
784 show_me = itb->show_me;
785 itb->show_me = EINA_FALSE;
788 if (itb->realized) _item_block_unrealize(itb);
790 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
792 if (itb->must_recalc)
797 EINA_LIST_FOREACH(itb->items, l, it)
798 it->item->mincalcd = EINA_FALSE;
799 itb->changed = EINA_TRUE;
800 did_must_recalc = EINA_TRUE;
801 if (itb->realized) _item_block_unrealize(itb);
802 itb->must_recalc = EINA_FALSE;
804 show_me = _item_block_recalc(itb, in, EINA_FALSE);
810 if (minw < itb->minw)
814 minw_change = EINA_TRUE;
816 if ((sd->mode == ELM_LIST_COMPRESS) && (minw > vw))
819 minw_change = EINA_TRUE;
825 if ((show_me) && (sd->show_item) && (!sd->show_item->item->queued))
826 sd->check_scroll = EINA_TRUE;
830 EINA_INLIST_FOREACH(sd->blocks, itb)
836 if ((chb) && (EINA_INLIST_GET(chb)->next))
838 EINA_INLIST_FOREACH(EINA_INLIST_GET(chb)->next, itb)
840 if (itb->realized) _item_block_unrealize(itb);
844 if (minw < sd->w) minw = sd->w;
845 if ((minw != sd->minw) || (minh != sd->minh))
849 eo_do(sd->pan_obj, eo_event_callback_call
850 (ELM_PAN_EVENT_CHANGED, NULL));
851 elm_layout_sizing_eval(sd->obj);
858 if ((sd->anchor_item) && (sd->anchor_item->item->block)
859 && (!sd->auto_scroll_enabled))
864 it = sd->anchor_item;
866 eo_do(sd->obj, elm_interface_scrollable_content_pos_set
867 (sd->pan_x, it->item->block->y
868 + it->y + it_y, EINA_TRUE));
869 sd->anchor_item = it;
875 if (!sd->must_recalc_idler)
876 sd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, data);
878 if (!sd->show_item) sd->check_scroll = EINA_FALSE;
879 if (sd->check_scroll)
881 eo_do(sd->pan_obj, elm_obj_pan_content_size_get(&pan_w, &pan_h));
882 if (EINA_INLIST_GET(sd->show_item) == sd->items->last)
883 sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
885 switch (sd->scroll_to_type)
887 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
891 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
895 case ELM_GENLIST_ITEM_SCROLLTO_IN:
900 if ((sd->show_item) && (sd->show_item->item->block))
902 if ((pan_w > (sd->show_item->x + sd->show_item->item->block->x))
903 && (pan_h > (sd->show_item->y + sd->show_item->item->block->y
912 evas_object_smart_changed(sd->pan_obj);
913 evas_event_thaw(evas_object_evas_get(sd->obj));
914 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
918 _elm_genlist_elm_layout_sizing_eval(Eo *obj, Elm_Genlist_Data *sd)
920 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
921 Evas_Coord vmw = 0, vmh = 0;
923 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
925 if (sd->on_sub_del) return;;
927 evas_object_size_hint_min_get(obj, &minw, NULL);
928 evas_object_size_hint_max_get(obj, &maxw, &maxh);
930 edje_object_size_min_calc(wd->resize_obj, &vmw, &vmh);
932 if (sd->mode == ELM_LIST_COMPRESS)
934 Evas_Coord vw = 0, vh = 0;
936 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
937 (NULL, NULL, &vw, &vh));
938 if ((vw != 0) && (vw != sd->prev_viewport_w))
942 sd->prev_viewport_w = vw;
943 /* Free all buckets for updaing changed width */
944 eina_hash_free_buckets(sd->size_caches);
946 EINA_INLIST_FOREACH(sd->blocks, itb)
948 itb->must_recalc = EINA_TRUE;
950 ecore_job_del(sd->calc_job);
951 sd->calc_job = ecore_job_add(_calc_job, obj);
960 minw = vmw + sd->realminw;
969 minh = vmh + sd->minh;
977 if ((maxw > 0) && (minw > maxw))
979 if ((maxh > 0) && (minh > maxh))
982 evas_object_size_hint_min_set(obj, minw, minh);
983 evas_object_size_hint_max_set(obj, maxw, maxh);
987 _content_min_limit_cb(Evas_Object *obj,
991 ELM_GENLIST_DATA_GET(obj, sd);
993 if ((sd->mode == ELM_LIST_LIMIT) ||
994 (sd->mode == ELM_LIST_EXPAND)) return;
998 elm_layout_sizing_eval(obj);
1002 _item_contract_emit(Elm_Object_Item *eo_it)
1004 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
1005 Elm_Object_Item *eo_it2;
1009 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACT_FLIP, "");
1010 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACT_FLIP, "elm");
1011 it->item->tree_effect_finished = EINA_FALSE;
1013 EINA_LIST_FOREACH(it->item->items, l, eo_it2)
1014 if (eo_it2) _item_contract_emit(eo_it2);
1018 _item_tree_effect_before(Elm_Gen_Item *it)
1020 Elm_Object_Item *eo_it2;
1022 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1024 EINA_LIST_FOREACH(it->item->items, l, eo_it2)
1026 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
1027 if (it2->parent && (it == it2->parent))
1030 it2->item->tree_effect_hide_me = EINA_TRUE;
1031 if (sd->move_effect_mode ==
1032 ELM_GENLIST_TREE_EFFECT_EXPAND)
1035 edje_object_signal_emit(VIEW(it2), SIGNAL_HIDE, "");
1036 edje_object_signal_emit(VIEW(it2), SIGNAL_HIDE, "elm");
1038 else if (sd->move_effect_mode ==
1039 ELM_GENLIST_TREE_EFFECT_CONTRACT)
1040 _item_contract_emit(eo_it2);
1043 return ECORE_CALLBACK_CANCEL;
1047 _item_position(Elm_Gen_Item *it,
1054 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1056 Evas_Object * highlighted_obj = _elm_object_accessibility_currently_highlighted_get();
1057 if (eo_isa(highlighted_obj, ELM_WIDGET_ITEM_CLASS))
1059 Elm_Widget_Item_Data *id = eo_data_scope_get(highlighted_obj, ELM_WIDGET_ITEM_CLASS);
1060 highlighted_obj = id->view;
1063 highlighted_obj = NULL;
1065 if (highlighted_obj && view == highlighted_obj)
1068 evas_object_geometry_get(sd->obj, &x, &y, &w, &h);
1070 Elm_Gen_Item * next_previous_item = NULL;
1071 if ((it_y + GL_IT(it)->h/2) < y)
1073 next_previous_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
1075 else if ((it_y + GL_IT(it)->h/2) > y + h)
1077 next_previous_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
1080 if (next_previous_item)
1081 eo_do(EO_OBJ(next_previous_item), elm_interface_atspi_component_highlight_grab());
1085 (evas_object_evas_get(sd->obj));
1086 evas_object_resize(view, it->item->w, it->item->h);
1087 evas_object_move(view, it_x, it_y);
1088 evas_object_show(view);
1089 evas_event_thaw(evas_object_evas_get(sd->obj));
1090 evas_event_thaw_eval
1091 (evas_object_evas_get(sd->obj));
1095 _item_tree_effect(Elm_Genlist_Data *sd,
1098 Elm_Gen_Item *expanded_next_it;
1099 Elm_Object_Item *eo_it;
1101 expanded_next_it = sd->expanded_next_item;
1103 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
1105 eo_it = elm_genlist_item_prev_get(EO_OBJ(expanded_next_it));
1108 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
1109 if (it->item->expanded_depth <=
1110 expanded_next_it->item->expanded_depth) break;
1111 if (it->item->scrl_y &&
1112 (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y)
1113 && (it->item->expanded_depth >
1114 expanded_next_it->item->expanded_depth))
1116 if (!it->item->tree_effect_finished)
1119 edje_object_signal_emit(VIEW(it), "flip_item", "");
1120 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ITEM,
1123 (it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
1124 it->item->tree_effect_finished = EINA_TRUE;
1127 eo_it = elm_genlist_item_prev_get(eo_it);
1130 else if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
1132 eo_it = elm_genlist_item_prev_get(EO_OBJ(expanded_next_it));
1135 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
1136 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
1137 (it->item->expanded_depth >
1138 expanded_next_it->item->expanded_depth))
1140 if (!it->item->tree_effect_finished)
1143 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "");
1144 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "elm");
1145 it->item->tree_effect_finished = EINA_TRUE;
1150 eo_it = elm_genlist_item_prev_get(eo_it);
1156 _item_sub_items_clear(Elm_Gen_Item *it)
1158 Eina_List *tl = NULL, *l;
1159 Elm_Object_Item *eo_it2;
1161 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
1163 EINA_LIST_FOREACH(it->item->items, l, eo_it2)
1164 tl = eina_list_append(tl, eo_it2);
1165 EINA_LIST_FREE(tl, eo_it2)
1166 eo_do(eo_it2, elm_wdg_item_del());
1170 _item_auto_scroll(Elm_Genlist_Data *sd)
1172 Elm_Object_Item *eo_tmp_item = NULL;
1174 if ((sd->expanded_item) && (sd->auto_scroll_enabled))
1176 eo_tmp_item = eina_list_data_get
1177 (eina_list_last(sd->expanded_item->item->items));
1178 if (!eo_tmp_item) return;
1179 ELM_GENLIST_ITEM_DATA_GET(eo_tmp_item, tmp_item);
1180 sd->show_item = tmp_item;
1181 sd->bring_in = EINA_TRUE;
1182 sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
1183 if ((sd->show_item->item->queued) || (!sd->show_item->item->mincalcd))
1185 sd->show_item->item->show_me = EINA_TRUE;
1186 sd->auto_scroll_enabled = EINA_FALSE;
1194 _item_tree_effect_finish(Elm_Genlist_Data *sd)
1196 Elm_Object_Item *eo_it = NULL;
1202 if (sd->tree_effect_animator)
1204 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
1205 _item_sub_items_clear(sd->expanded_item);
1207 EINA_LIST_FOREACH(sd->expanded_item->item->items, l, eo_it)
1209 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
1210 it->item->tree_effect_finished = EINA_TRUE;
1211 it->item->old_scrl_y = it->item->scrl_y;
1212 if (GL_IT(it)->wsd->move_effect_mode ==
1213 ELM_GENLIST_TREE_EFFECT_EXPAND)
1216 edje_object_signal_emit(VIEW(it), SIGNAL_SHOW, "");
1217 edje_object_signal_emit(VIEW(it), SIGNAL_SHOW, "elm");
1220 if (sd->move_effect_mode ==
1221 ELM_GENLIST_TREE_EFFECT_EXPAND)
1223 EINA_INLIST_FOREACH(sd->blocks, itb)
1225 EINA_LIST_FOREACH(itb->items, l, it1)
1227 if (it1->item->scrl_y <= y)
1229 it1->item->scrl_y = y + it1->item->h;
1230 _elm_genlist_item_unrealize(it1, EINA_FALSE);
1232 y = it1->item->scrl_y;
1238 _item_auto_scroll(sd);
1239 evas_object_lower(sd->event_block_rect);
1240 evas_object_hide(sd->event_block_rect);
1241 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
1242 sd->move_items = eina_list_free(sd->move_items);
1244 eo_do(sd->pan_obj, eo_event_callback_call(ELM_PAN_EVENT_CHANGED, NULL));
1245 eo_do(sd->obj, eo_event_callback_call
1246 (ELM_GENLIST_EVENT_TREE_EFFECT_FINISHED, NULL));
1247 evas_object_smart_changed(sd->pan_obj);
1249 sd->tree_effect_animator = NULL;
1253 _elm_genlist_item_position_state_update(Elm_Gen_Item *it)
1255 unsigned idx = it->item->order_num_in;
1257 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1259 if (!it->item->nostacking)
1261 if ((idx & 0x1) ^ it->item->stacking_even)
1263 if (it->deco_all_view) evas_object_stack_below(it->deco_all_view, sd->stack[0]);
1264 else evas_object_stack_below(VIEW(it), sd->stack[0]);
1268 if (it->deco_all_view) evas_object_stack_above(it->deco_all_view, sd->stack[0]);
1269 else evas_object_stack_above(VIEW(it), sd->stack[0]);
1275 edje_object_signal_emit(VIEW(it), SIGNAL_ODD, "elm");
1276 if (it->deco_all_view)
1277 edje_object_signal_emit(it->deco_all_view, SIGNAL_ODD, "elm");
1281 edje_object_signal_emit(VIEW(it), SIGNAL_EVEN, "elm");
1282 if (it->deco_all_view)
1283 edje_object_signal_emit(it->deco_all_view, SIGNAL_EVEN, "elm");
1286 if (sd->item_count == 1)
1288 edje_object_signal_emit(VIEW(it), SIGNAL_LIST_SINGLE, "elm");
1289 if (it->deco_all_view)
1290 edje_object_signal_emit(it->deco_all_view, SIGNAL_LIST_SINGLE, "elm");
1294 edje_object_signal_emit(VIEW(it), SIGNAL_LIST_FIRST, "elm");
1295 if (it->deco_all_view)
1296 edje_object_signal_emit(it->deco_all_view, SIGNAL_LIST_FIRST, "elm");
1298 else if (idx == sd->item_count - 1)
1300 edje_object_signal_emit(VIEW(it), SIGNAL_LIST_LAST, "elm");
1301 if (it->deco_all_view)
1302 edje_object_signal_emit(it->deco_all_view, SIGNAL_LIST_LAST, "elm");
1306 edje_object_signal_emit(VIEW(it), SIGNAL_LIST_MIDDLE, "elm");
1307 if (it->deco_all_view)
1308 edje_object_signal_emit(it->deco_all_view, SIGNAL_LIST_MIDDLE, "elm");
1313 unsigned first_idx = it->parent->item->order_num_in + 1;
1314 unsigned count = eina_list_count(it->parent->item->items);
1318 edje_object_signal_emit(VIEW(it), SIGNAL_GROUP_SINGLE, "elm");
1319 if (it->deco_all_view)
1320 edje_object_signal_emit(it->deco_all_view, SIGNAL_GROUP_SINGLE,
1323 else if (idx == first_idx)
1325 edje_object_signal_emit(VIEW(it), SIGNAL_GROUP_FIRST, "elm");
1326 if (it->deco_all_view)
1327 edje_object_signal_emit(it->deco_all_view, SIGNAL_GROUP_FIRST,
1330 else if (EO_OBJ(it) == eina_list_data_get(eina_list_last(it->parent->item->items)))
1332 edje_object_signal_emit(VIEW(it), SIGNAL_GROUP_LAST, "elm");
1333 if (it->deco_all_view)
1334 edje_object_signal_emit(it->deco_all_view, SIGNAL_GROUP_LAST,
1337 else if (idx > first_idx)
1339 edje_object_signal_emit(VIEW(it), SIGNAL_GROUP_MIDDLE, "elm");
1340 if (it->deco_all_view)
1341 edje_object_signal_emit(it->deco_all_view, SIGNAL_GROUP_MIDDLE,
1348 _item_order_update(const Eina_Inlist *l,
1351 Elm_Gen_Item *it, *it2;
1354 * always update position state of previous item, it may have been
1355 * marked as "single" if it was the only element at the time, or
1356 * "middle", "first" or "last" in the case of insert into different
1359 if ((l->prev) && (start > 0))
1361 it = ELM_GEN_ITEM_FROM_INLIST(l->prev);
1362 it->item->order_num_in = start - 1;
1363 _elm_genlist_item_position_state_update(it);
1366 for (it = ELM_GEN_ITEM_FROM_INLIST(l); l; l = l->next,
1367 it = ELM_GEN_ITEM_FROM_INLIST(l))
1369 it->item->order_num_in = start++;
1370 _elm_genlist_item_position_state_update(it);
1371 it2 = ELM_GEN_ITEM_FROM_INLIST(l->next);
1372 if (it2 && (it->item->order_num_in != it2->item->order_num_in))
1378 _elm_genlist_item_state_update(Elm_Gen_Item *it)
1381 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1384 edje_object_signal_emit(VIEW(it), SIGNAL_SELECTED, "elm");
1385 if (it->deco_all_view)
1386 edje_object_signal_emit
1387 (it->deco_all_view, SIGNAL_SELECTED, "elm");
1389 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()))
1391 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
1392 if (it->deco_all_view)
1393 edje_object_signal_emit
1394 (it->deco_all_view, SIGNAL_DISABLED, "elm");
1396 if (it->item->expanded)
1398 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
1399 if (it->deco_all_view)
1400 edje_object_signal_emit
1401 (it->deco_all_view, SIGNAL_EXPANDED, "elm");
1403 if ((EO_OBJ(it) == sd->focused_item) &&
1404 (elm_widget_focus_highlight_enabled_get(WIDGET(it)) || _elm_config->win_auto_focus_enable))
1405 edje_object_signal_emit(VIEW(it), SIGNAL_FOCUSED, "elm");
1409 _view_inflate(Evas_Object *view, Elm_Gen_Item *it, Eina_List **sources,
1410 Eina_List **contents)
1413 if (sources) _item_text_realize(it, view, sources, NULL);
1414 if (contents) _item_content_realize(it, view, contents, "contents", NULL);
1415 _item_state_realize(it, view, NULL);
1419 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1421 if (it->position_update || GL_IT(it)->block->position_update)
1423 eo_do(WIDGET(it), eo_event_callback_call
1424 (ELM_GENLIST_EVENT_INDEX_UPDATE, EO_OBJ(it)));
1425 it->position_update = EINA_FALSE;
1430 _decorate_all_item_position(Elm_Gen_Item *it,
1434 if ((!it) || (!GL_IT(it)->wsd->decorate_all_mode)) return;
1435 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
1436 evas_object_move(it->deco_all_view, itx, ity);
1440 _decorate_all_item_realize(Elm_Gen_Item *it,
1441 Eina_Bool effect_on)
1444 const char *stacking;
1445 const char *stacking_even;
1448 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1450 if (it->item->decorate_all_item_realized) return;
1452 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
1453 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
1454 elm_config_scale_get());
1455 evas_object_smart_member_add(it->deco_all_view, sd->pan_obj);
1456 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
1458 if (it->item->type & ELM_GENLIST_ITEM_TREE)
1459 strncpy(buf, "tree", sizeof(buf));
1460 else strncpy(buf, "item", sizeof(buf));
1461 if (sd->mode == ELM_LIST_COMPRESS)
1462 strncat(buf, "_compress", sizeof(buf) - strlen(buf) - 1);
1464 strncat(buf, "/", sizeof(buf) - strlen(buf) - 1);
1465 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf) - 1);
1467 elm_widget_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
1468 elm_widget_style_get(WIDGET(it)));
1470 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1471 if (!stacking_even) stacking_even = "above";
1472 it->item->stacking_even = !!strcmp("above", stacking_even);
1474 stacking = edje_object_data_get(VIEW(it), "stacking");
1475 if (!stacking) stacking = "yes";
1476 it->item->nostacking = !!strcmp("yes", stacking);
1478 edje_object_mirrored_set
1479 (it->deco_all_view, elm_widget_mirrored_get(WIDGET(it)));
1481 _elm_genlist_item_position_state_update(it);
1482 _elm_genlist_item_state_update(it);
1484 if (GL_IT(it)->wsd->reorder_mode)
1486 edje_object_signal_emit(it->deco_all_view, SIGNAL_REORDER_MODE_UNSET,
1491 edje_object_signal_emit
1492 (it->deco_all_view, SIGNAL_DECORATE_ENABLED_EFFECT, "elm");
1494 edje_object_signal_emit
1495 (it->deco_all_view, SIGNAL_DECORATE_ENABLED, "elm");
1497 _item_mouse_callbacks_del(it, VIEW(it));
1498 _item_mouse_callbacks_add(it, it->deco_all_view);
1501 edje_object_signal_emit
1502 (it->deco_all_view, SIGNAL_FLIP_ENABLED, "elm");
1503 _view_inflate(it->deco_all_view, it, NULL, &(GL_IT(it)->deco_all_contents));
1504 edje_object_part_swallow
1505 (it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
1507 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
1508 evas_object_show(it->deco_all_view);
1511 edje_object_signal_emit(it->deco_all_view, SIGNAL_SELECTED, "elm");
1513 it->item->decorate_all_item_realized = EINA_TRUE;
1514 it->want_unrealize = EINA_FALSE;
1517 //-- tree expand/contract signal handle routine --//
1519 _expand_toggle_signal_cb(void *data,
1520 Evas_Object *obj EINA_UNUSED,
1521 const char *emission EINA_UNUSED,
1522 const char *source EINA_UNUSED)
1524 Elm_Gen_Item *it = data;
1526 if (it->item->expanded)
1527 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_CONTRACT_REQUEST, EO_OBJ(it)));
1529 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_EXPAND_REQUEST, EO_OBJ(it)));
1533 _expand_signal_cb(void *data,
1534 Evas_Object *obj EINA_UNUSED,
1535 const char *emission EINA_UNUSED,
1536 const char *source EINA_UNUSED)
1538 Elm_Gen_Item *it = data;
1540 if (!it->item->expanded)
1541 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_EXPAND_REQUEST, EO_OBJ(it)));
1545 _contract_signal_cb(void *data,
1546 Evas_Object *obj EINA_UNUSED,
1547 const char *emission EINA_UNUSED,
1548 const char *source EINA_UNUSED)
1550 Elm_Gen_Item *it = data;
1552 if (it->item->expanded)
1553 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_CONTRACT_REQUEST, EO_OBJ(it)));
1556 //-- item cache handle routine --//
1557 // push item cache into caches
1559 _item_cache_push(Elm_Genlist_Data *sd, Item_Cache *itc)
1561 if (!itc || (sd->item_cache_max <= 0))
1564 sd->item_cache_count++;
1566 eina_inlist_prepend(sd->item_cache, EINA_INLIST_GET(itc));
1571 // pop item cache from caches
1573 _item_cache_pop(Elm_Genlist_Data *sd, Item_Cache *itc)
1575 if (!itc || (!sd->item_cache) ||
1576 (sd->item_cache_count <= 0))
1580 eina_inlist_remove (sd->item_cache, EINA_INLIST_GET(itc));
1581 sd->item_cache_count--;
1586 // free one item cache
1588 _item_cache_free(Item_Cache *itc)
1595 evas_object_del(itc->spacer);
1596 evas_object_del(itc->base_view);
1597 itc->item_class = NULL;
1598 EINA_LIST_FREE(itc->contents, c)
1602 ELM_SAFE_FREE(itc, free);
1605 // clean up item cache by removing overflowed caches
1607 _item_cache_clean(Elm_Genlist_Data *sd)
1609 evas_event_freeze(evas_object_evas_get(sd->obj));
1611 while ((sd->item_cache) && (sd->item_cache_count > sd->item_cache_max))
1614 EINA_INLIST_CONTAINER_GET(sd->item_cache->last, Item_Cache);
1615 _item_cache_free(_item_cache_pop(sd, itc));
1617 evas_event_thaw(evas_object_evas_get(sd->obj));
1618 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
1621 // empty all item caches
1623 _item_cache_zero(Elm_Genlist_Data *sd)
1625 int pmax = sd->item_cache_max;
1627 sd->item_cache_max = 0;
1628 _item_cache_clean(sd);
1629 sd->item_cache_max = pmax;
1632 // add an item to item cache
1634 _item_cache_add(Elm_Gen_Item *it, Eina_List *contents)
1636 if (it->item->nocache_once || it->item->nocache) return EINA_FALSE;
1638 Item_Cache *itc = NULL;
1639 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1640 Evas_Object *obj = sd->obj;
1643 evas_event_freeze(evas_object_evas_get(obj));
1645 if (sd->item_cache_max > 0)
1646 itc = ELM_NEW(Item_Cache);
1648 if (!_item_cache_push(sd, itc))
1650 if (itc) ELM_SAFE_FREE(itc, free);
1652 evas_event_thaw(evas_object_evas_get(obj));
1653 evas_event_thaw_eval(evas_object_evas_get(obj));
1656 itc->spacer = it->spacer;
1657 itc->base_view = VIEW(it);
1658 itc->item_class = it->itc;
1659 itc->contents = contents;
1660 if (it->item->type & ELM_GENLIST_ITEM_TREE)
1663 if (it->item->expanded)
1664 edje_object_signal_emit(itc->base_view, SIGNAL_CONTRACTED, "elm");
1668 edje_object_signal_emit(itc->base_view, SIGNAL_UNSELECTED, "elm");
1669 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()))
1670 edje_object_signal_emit(itc->base_view, SIGNAL_ENABLED, "elm");
1671 if ((EO_OBJ(it) == sd->focused_item) &&
1672 (elm_widget_focus_highlight_enabled_get(obj) || _elm_config->win_auto_focus_enable))
1673 edje_object_signal_emit(itc->base_view, SIGNAL_UNFOCUSED, "elm");
1675 //Tizen Only(20160307)
1676 edje_object_signal_emit(itc->base_view, SIGNAL_DEFAULT, "elm");
1678 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
1679 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
1681 // FIXME: other callbacks?
1682 edje_object_signal_callback_del_full
1683 (itc->base_view, "elm,action,expand,toggle", "elm",
1684 _expand_toggle_signal_cb, it);
1685 edje_object_signal_callback_del_full
1686 (itc->base_view, "elm,action,expand", "elm", _expand_signal_cb, it);
1687 edje_object_signal_callback_del_full
1688 (itc->base_view, "elm,action,contract", "elm", _contract_signal_cb, it);
1689 _item_mouse_callbacks_del(it, itc->base_view);
1691 edje_object_mirrored_set(itc->base_view,
1692 elm_widget_mirrored_get(WIDGET(it)));
1693 edje_object_scale_set(itc->base_view,
1694 elm_widget_scale_get(WIDGET(it))
1695 * elm_config_scale_get());
1699 evas_object_hide(itc->base_view);
1700 evas_object_move(itc->base_view, -9999, -9999);
1702 _item_cache_clean(sd);
1704 evas_event_thaw(evas_object_evas_get(obj));
1705 evas_event_thaw_eval(evas_object_evas_get(obj));
1710 // find an item from item cache and remove it from the cache
1712 _item_cache_find(Elm_Gen_Item *it)
1714 if (it->item->nocache_once || it->item->nocache) return EINA_FALSE;
1716 Item_Cache *itc = NULL;
1719 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1721 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1722 EINA_INLIST_FOREACH_SAFE(sd->item_cache, l, itc)
1724 if ((itc->tree == tree) &&
1725 (((!it->itc) && (!itc->item_class)) ||
1726 (it->itc && itc->item_class &&
1727 (it->itc == itc->item_class))))
1729 itc = _item_cache_pop(sd, itc);
1732 it->spacer = itc->spacer;
1733 VIEW(it) = itc->base_view;
1735 itc->base_view = NULL;
1737 eina_list_free(itc->contents);
1738 itc->contents = NULL;
1739 _item_cache_free(itc);
1747 _content_cache_add(Elm_Gen_Item *it, Eina_List **cache)
1749 Evas_Object *content = NULL;
1750 EINA_LIST_FREE(it->contents, content)
1752 *cache = eina_list_append(*cache, content);
1759 _access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
1764 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1765 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1767 buf = eina_strbuf_new();
1769 if (it->itc->func.text_get)
1774 if (!(it->texts)) it->texts =
1775 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1777 EINA_LIST_FOREACH(it->texts, l, key)
1779 char *s = it->itc->func.text_get
1780 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
1784 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
1785 eina_strbuf_append(buf, s);
1791 ret = eina_strbuf_string_steal(buf);
1792 eina_strbuf_free(buf);
1797 _access_state_cb(void *data, Evas_Object *obj EINA_UNUSED)
1799 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1800 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1802 if (it->base->disabled)
1803 return strdup(E_("State: Disabled"));
1809 _access_on_highlight_cb(void *data)
1811 Evas_Coord x, y, w, h;
1812 Evas_Coord sx, sy, sw, sh;
1813 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1814 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
1816 evas_object_geometry_get(it->base->view, &x, &y, &w, &h);
1817 // XXX There would be a reason.
1818 if ((w == 0) && (h == 0)) return;
1820 evas_object_geometry_get(it->base->widget, &sx, &sy, &sw, &sh);
1821 if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
1822 elm_genlist_item_bring_in(EO_OBJ(it),
1823 ELM_GENLIST_ITEM_SCROLLTO_IN);
1827 _access_widget_item_register(Elm_Gen_Item *it)
1829 Elm_Access_Info *ai;
1831 _elm_access_widget_item_register(it->base);
1833 ai = _elm_access_info_get(it->base->access_obj);
1835 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1836 _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
1837 _elm_access_on_highlight_hook_set(ai, _access_on_highlight_cb, it);
1838 _elm_access_activate_callback_set(ai, _access_activate_cb, EO_OBJ(it));
1842 _elm_genlist_item_focus_update(Elm_Gen_Item *it)
1844 const char *focus_raise;
1845 Evas_Object *obj = WIDGET(it);
1846 ELM_GENLIST_DATA_GET(obj, sd);
1848 if (elm_widget_focus_highlight_enabled_get(obj))
1849 edje_object_signal_emit(VIEW(it), SIGNAL_FOCUSED, "elm");
1851 focus_raise = edje_object_data_get(VIEW(it), "focusraise");
1852 if ((focus_raise) && (!strcmp(focus_raise, "on")))
1857 evas_object_raise(VIEW(it));
1858 EINA_LIST_FOREACH(sd->group_items, l, git)
1860 if (git->realized) evas_object_raise(VIEW(git));
1866 _item_realize(Elm_Gen_Item *it,
1870 const char *treesize;
1871 Item_Size *size = NULL;
1873 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1877 if (it->item->order_num_in != in)
1879 _item_order_update(EINA_INLIST_GET(it), in);
1880 _elm_genlist_item_state_update(it);
1881 _elm_genlist_item_index_update(it);
1885 it->item->order_num_in = in;
1887 if (sd->tree_effect_enabled ||
1888 (!_item_cache_find(it)))
1890 VIEW(it) = _view_create(it, it->itc->item_style);
1891 if (it->item->nocache_once)
1892 it->item->nocache_once = EINA_FALSE;
1895 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
1896 if (_elm_config->atspi_mode)
1898 elm_interface_atspi_accessible_added(EO_OBJ(it));
1899 elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
1904 if (_elm_config->access_mode) _access_widget_item_register(it);
1906 _item_order_update(EINA_INLIST_GET(it), in);
1908 if (sd->reorder_mode)
1909 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
1911 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_UNSET, "elm");
1913 treesize = edje_object_data_get(VIEW(it), "treesize");
1914 if (treesize) tsize = atoi(treesize);
1916 if (edje_object_part_exists(VIEW(it), "elm.swallow.pad"))
1918 if (!it->spacer && treesize)
1921 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1922 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1923 elm_widget_sub_object_add(WIDGET(it), it->spacer);
1926 evas_object_size_hint_min_set
1927 (it->spacer, (it->item->expanded_depth * tsize) *
1928 elm_config_scale_get(), 1);
1929 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1933 ELM_SAFE_FREE(it->spacer, evas_object_del);
1938 edje_object_signal_callback_add
1939 (VIEW(it), "elm,action,expand,toggle", "elm",
1940 _expand_toggle_signal_cb, it);
1941 edje_object_signal_callback_add
1942 (VIEW(it), "elm,action,expand", "elm", _expand_signal_cb, it);
1943 edje_object_signal_callback_add
1944 (VIEW(it), "elm,action,contract", "elm", _contract_signal_cb, it);
1945 _item_mouse_callbacks_add(it, VIEW(it));
1947 if ((sd->decorate_all_mode) && (!it->deco_all_view) &&
1948 (it->item->type != ELM_GENLIST_ITEM_GROUP) &&
1949 (it->itc->decorate_all_item_style))
1950 _decorate_all_item_realize(it, EINA_FALSE);
1952 _elm_genlist_item_state_update(it);
1953 _elm_genlist_item_index_update(it);
1955 if (EO_OBJ(it) == sd->focused_item)
1957 _elm_genlist_item_focus_update(it);
1958 _elm_widget_item_highlight_in_theme(WIDGET(it), EO_OBJ(it));
1959 _elm_widget_highlight_in_theme_update(WIDGET(it));
1960 _elm_widget_focus_highlight_start(WIDGET(it));
1964 size = eina_hash_find(sd->size_caches, &(it->itc));
1965 /* homogeneous genlist shortcut */
1966 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
1967 if ((calc) && (sd->homogeneous || it->itc->homogeneous) && (!it->item->mincalcd) && size)
1969 GL_IT(it)->w = GL_IT(it)->minw = size->minw;
1970 GL_IT(it)->h = GL_IT(it)->minh = size->minh;
1971 it->item->mincalcd = EINA_TRUE;
1975 if (eina_list_count(it->contents) != 0)
1976 ERR_ABORT("If you see this error, please notify us and we"
1979 _view_inflate(VIEW(it), it, &it->texts, &it->contents);
1980 if (it->has_contents != (!!it->contents))
1981 it->item->mincalcd = EINA_FALSE;
1982 it->has_contents = !!it->contents;
1985 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
1986 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_contents,
1990 /* access: unregister item which have no text and content */
1991 if (_elm_config->access_mode && !it->texts && !it->contents)
1992 _elm_access_widget_item_unregister(it->base);
1994 if (!it->item->mincalcd)
1996 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
1997 if ((sd->homogeneous || it->itc->homogeneous) && size)
1999 GL_IT(it)->w = GL_IT(it)->minw = size->minw;
2000 GL_IT(it)->h = GL_IT(it)->minh = size->minh;
2001 it->item->mincalcd = EINA_TRUE;
2005 Evas_Coord mw = -1, mh = -1;
2007 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2008 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2009 if (sd->mode == ELM_LIST_COMPRESS)
2010 mw = sd->prev_viewport_w;
2011 edje_object_message_signal_process(VIEW(it));
2012 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
2013 it->item->w = it->item->minw = mw;
2014 it->item->h = it->item->minh = mh;
2015 it->item->mincalcd = EINA_TRUE;
2017 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
2018 if (sd->homogeneous || it->itc->homogeneous)
2021 eina_hash_del_by_key(sd->size_caches, &(it->itc));
2023 size = ELM_NEW(Item_Size);
2024 size->itc = it->itc;
2027 eina_hash_add(sd->size_caches, &(it->itc), size);
2031 if (!calc) evas_object_show(VIEW(it));
2034 if (it->tooltip.content_cb)
2037 elm_wdg_item_tooltip_content_cb_set(
2038 it->tooltip.content_cb, it->tooltip.data, NULL),
2039 elm_wdg_item_tooltip_style_set(it->tooltip.style),
2040 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
2043 if (it->mouse_cursor)
2045 elm_wdg_item_cursor_set(it->mouse_cursor));
2047 it->realized = EINA_TRUE;
2048 it->want_unrealize = EINA_FALSE;
2052 if (it->item->tree_effect_hide_me)
2054 if (sd->move_effect_mode
2055 != ELM_GENLIST_TREE_EFFECT_NONE)
2058 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "");
2059 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "elm");
2061 it->item->tree_effect_hide_me = EINA_FALSE;
2064 if (it->item->type == ELM_GENLIST_ITEM_NONE)
2068 EINA_LIST_FOREACH(it->contents, l, eobj)
2069 if (elm_widget_is(eobj) && elm_object_focus_allow_get(eobj))
2070 it->item_focus_chain = eina_list_append
2071 (it->item_focus_chain, eobj);
2075 if (it->item->type == ELM_GENLIST_ITEM_TREE)
2077 Evas_Object* t_eobj;
2079 EINA_LIST_FOREACH(it->contents, tl, t_eobj)
2080 if (elm_widget_is(t_eobj) && elm_object_focus_allow_get(t_eobj))
2081 it->item_focus_chain = eina_list_append
2082 (it->item_focus_chain, t_eobj);
2086 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_REALIZED, EO_OBJ(it)));
2089 //Send a signal so that an item changes its style according to its expand depth
2090 if (GL_IT(it)->expanded_depth > 0)
2093 snprintf(buf, sizeof(buf), "elm,state,expanded_depth,%d",
2094 GL_IT(it)->expanded_depth);
2095 edje_object_signal_emit(VIEW(it), buf, "elm");
2098 if ((!calc) && (sd->decorate_all_mode) &&
2099 (it->item->type != ELM_GENLIST_ITEM_GROUP))
2101 if (it->itc->decorate_all_item_style)
2103 if (!it->deco_all_view)
2104 _decorate_all_item_realize(it, EINA_FALSE);
2105 edje_object_message_signal_process(it->deco_all_view);
2109 if (it->decorate_it_set) _decorate_item_set(it);
2111 edje_object_message_signal_process(VIEW(it));
2112 //TIZEN_ONLY(20160329): genlist: enhance accessibility scroll & highlight (30d9a6012e629cd9ea60eae8d576f3ebb94ada86)
2113 if (sd->atspi_item_to_highlight == it)
2115 sd->atspi_item_to_highlight = NULL;
2116 eo_do_super(EO_OBJ(it), ELM_GENLIST_ITEM_CLASS, elm_interface_atspi_component_highlight_grab());
2122 _tree_effect_animator_cb(void *data)
2126 int y = 0, dy = 0, dh = 0;
2127 double effect_duration = 0.3, t;
2128 ELM_GENLIST_DATA_GET(data, sd);
2129 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
2130 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2131 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
2132 Elm_Object_Item *eo_it = NULL, *eo_it2;
2134 t = ((0.0 > (t = ecore_time_get() - sd->start_time)) ? 0.0 : t);
2135 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
2136 evas_output_viewport_get
2137 (evas_object_evas_get(sd->pan_obj), &cvx, &cvy, &cvw, &cvh);
2138 if (t > effect_duration) end = EINA_TRUE;
2140 // Below while statement is needed, when the genlist is resized.
2141 it2 = sd->expanded_item;
2142 eo_it2 = EO_OBJ(it2);
2143 while (eo_it2 && vis)
2145 it2 = eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
2146 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
2147 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y,
2148 it2->item->w, it2->item->h, cvx, cvy, cvw,
2150 eo_it2 = elm_genlist_item_prev_get(eo_it2);
2153 if (sd->expanded_next_item)
2155 expanded_next_it = sd->expanded_next_item;
2158 EINA_LIST_FOREACH(sd->move_items, l, it)
2160 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
2162 expanded_next_it->item->old_scrl_y =
2163 sd->expanded_item->item->old_scrl_y
2164 + sd->expanded_item->item->h;
2165 if (expanded_next_it->item->scrl_y <=
2166 expanded_next_it->item->old_scrl_y) /* did not
2170 expanded_next_it->item->scrl_y = cvy + cvh;
2172 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
2173 cvy + cvh : expanded_next_it->item->scrl_y) -
2174 expanded_next_it->item->old_scrl_y;
2176 else if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
2178 if (expanded_next_it->item->scrl_y >
2179 expanded_next_it->item->old_scrl_y) /* did not
2183 expanded_next_it->item->old_scrl_y = cvy + cvh;
2185 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
2187 dy = (sd->expanded_item->item->scrl_y +
2188 sd->expanded_item->item->h) - cvy + cvh;
2189 expanded_next_it->item->old_scrl_y = cvy + cvh;
2193 dy = (sd->expanded_item->item->scrl_y +
2194 sd->expanded_item->item->h) -
2195 expanded_next_it->item->old_scrl_y;
2199 if (t <= effect_duration)
2201 y = ((1 - (1 - (t / effect_duration)) *
2202 (1 - (t / effect_duration))) * dy);
2210 if (!it->realized && !it->item->queued)
2211 _item_realize(it, in, 0);
2214 if (it != expanded_next_it)
2216 it->item->old_scrl_y =
2217 expanded_next_it->item->old_scrl_y +
2218 expanded_next_it->item->h + dh;
2223 if ((it->item->old_scrl_y + y) < (cvy + cvh))
2224 _item_position(it, VIEW(it), it->item->scrl_x,
2225 it->item->old_scrl_y + y);
2228 _item_tree_effect(sd, y);
2232 int expanded_item_num = 0;
2235 if (sd->expanded_item)
2236 eo_it = elm_genlist_item_next_get(EO_OBJ(sd->expanded_item));
2241 expanded_item_num++;
2242 eo_it2 = elm_genlist_item_next_get(eo_it2);
2247 it = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
2249 if (sd->expanded_item->item->expanded_depth >=
2250 it->item->expanded_depth) break;
2251 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
2253 if (!it->item->tree_effect_finished)
2255 if (t >= (((num - 1) * effect_duration) /
2259 edje_object_signal_emit(VIEW(it), "flip_item", "");
2260 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ITEM,
2262 _item_position(it, VIEW(it), it->item->scrl_x,
2264 it->item->tree_effect_finished = EINA_TRUE;
2268 eo_it = elm_genlist_item_next_get(eo_it);
2274 _item_tree_effect_finish(sd);
2275 return ECORE_CALLBACK_CANCEL;
2278 return ECORE_CALLBACK_RENEW;
2282 _group_items_recalc(void *data)
2286 Elm_Genlist_Data *sd = data;
2288 evas_event_freeze(evas_object_evas_get(sd->obj));
2289 EINA_LIST_FOREACH(sd->group_items, l, git)
2291 if (git->item->want_realize)
2293 if (!git->realized) _item_realize(git, 0, EINA_FALSE);
2294 evas_object_resize(VIEW(git), sd->minw, git->item->h);
2295 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2296 evas_object_stack_above(VIEW(git), sd->stack[1]);
2297 evas_object_show(VIEW(git));
2299 else if (!git->item->want_realize && git->realized)
2302 _elm_genlist_item_unrealize(git, EINA_FALSE);
2305 evas_event_thaw(evas_object_evas_get(sd->obj));
2306 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
2310 _reorder_move_animator_cb(void *data)
2313 Elm_Gen_Item *it = data;
2314 Eina_Bool down = EINA_FALSE;
2315 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
2316 int y, dy = it->item->h / 10 * elm_config_scale_get(), diff;
2318 t = ((0.0 > (t = ecore_loop_time_get()
2319 - sd->start_time)) ? 0.0 : t);
2321 if (t <= REORDER_EFFECT_TIME)
2322 y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2325 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2326 if (diff < dy) y = diff;
2327 else if (diff > it->item->h) y = diff / 2;
2329 if (it->item->old_scrl_y < it->item->scrl_y)
2331 it->item->old_scrl_y += y;
2334 else if (it->item->old_scrl_y > it->item->scrl_y)
2336 it->item->old_scrl_y -= y;
2340 if (it->deco_all_view)
2342 (it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
2344 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2346 if ((sd->reorder_pan_move) ||
2347 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2348 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2350 it->item->old_scrl_y = it->item->scrl_y;
2351 it->item->move_effect_enabled = EINA_FALSE;
2352 sd->reorder_move_animator = NULL;
2353 return ECORE_CALLBACK_CANCEL;
2356 return ECORE_CALLBACK_RENEW;
2360 _reorder_item_space_get(Elm_Gen_Item *it)
2362 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
2363 Elm_Gen_Item *reorder_it = sd->reorder_it;
2364 Evas_Coord rox, roy, row, roh, oy, oh;
2365 Eina_Bool top = EINA_FALSE;
2367 if (!reorder_it) return 0;
2369 evas_object_geometry_get(sd->pan_obj, NULL, &oy, NULL, &oh);
2370 evas_object_geometry_get
2371 (sd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2373 if ((sd->reorder_start_y < it->item->block->y) &&
2374 (roy - oy + (roh / 2) >= it->item->block->y - sd->pan_y))
2376 it->item->block->reorder_offset =
2377 sd->reorder_it->item->h * -1;
2378 if (it->item->block->count == 1)
2379 sd->reorder_rel = it;
2381 else if ((sd->reorder_start_y >= it->item->block->y) &&
2382 (roy - oy + (roh / 2) <= it->item->block->y - sd->pan_y))
2384 it->item->block->reorder_offset = sd->reorder_it->item->h;
2387 it->item->block->reorder_offset = 0;
2389 it->item->scrl_y += it->item->block->reorder_offset;
2391 top = (ELM_RECTS_INTERSECT
2392 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2393 rox, roy + (roh / 2), row, 1));
2396 sd->reorder_rel = it;
2397 it->item->scrl_y += sd->reorder_it->item->h;
2398 return sd->reorder_it->item->h;
2405 _item_block_position(Item_Block *itb,
2410 Eina_Bool vis = EINA_FALSE;
2411 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2412 Elm_Genlist_Data *sd = NULL;
2414 evas_event_freeze(evas_object_evas_get((itb->sd)->obj));
2415 evas_object_geometry_get(itb->sd->pan_obj, &ox, &oy, &ow, &oh);
2416 evas_output_viewport_get
2417 (evas_object_evas_get((itb->sd)->obj),
2418 &cvx, &cvy, &cvw, &cvh);
2420 EINA_LIST_FOREACH(itb->items, l, it)
2422 sd = GL_IT(it)->wsd;
2423 if (sd->reorder_it == it) continue;
2425 if (!it->filtered) _item_filtered_get(it);
2426 if (it->want_hidden)
2428 if (it->realized) evas_object_hide(VIEW(it));
2433 it->item->w = itb->w;
2434 it->item->scrl_x = itb->x + it->x - sd->pan_x + ox;
2435 it->item->scrl_y = itb->y + it->y - sd->pan_y + oy;
2437 vis = (ELM_RECTS_INTERSECT
2438 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2439 cvx, cvy, cvw, cvh));
2440 if (!(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP))
2442 if ((itb->realized) && (!it->realized))
2444 if (vis) _item_realize(it, in, EINA_FALSE);
2448 if (vis || it->dragging)
2450 if (sd->reorder_mode)
2451 y += _reorder_item_space_get(it);
2452 if ((sd->reorder_it) &&
2453 (it->item->old_scrl_y != it->item->scrl_y))
2455 if (!it->item->move_effect_enabled)
2457 it->item->move_effect_enabled = EINA_TRUE;
2458 sd->reorder_move_animator =
2460 _reorder_move_animator_cb, it);
2463 if (!it->item->move_effect_enabled)
2465 if ((sd->decorate_all_mode) &&
2466 (it->itc->decorate_all_item_style))
2467 _decorate_all_item_position
2468 (it, it->item->scrl_x, it->item->scrl_y);
2471 if (!sd->tree_effect_enabled ||
2472 (sd->move_effect_mode ==
2473 ELM_GENLIST_TREE_EFFECT_NONE) ||
2474 ((sd->move_effect_mode !=
2475 ELM_GENLIST_TREE_EFFECT_NONE) &&
2476 (it->item->old_scrl_y ==
2479 if (it->item->deco_it_view)
2481 (it, it->item->deco_it_view,
2486 (it, VIEW(it), it->item->scrl_x,
2490 it->item->old_scrl_y = it->item->scrl_y;
2495 if (!sd->tree_effect_animator)
2496 _elm_genlist_item_unrealize(it, EINA_FALSE);
2503 if (vis) it->item->want_realize = EINA_TRUE;
2507 evas_event_thaw(evas_object_evas_get((itb->sd)->obj));
2508 evas_event_thaw_eval(evas_object_evas_get((itb->sd)->obj));
2512 _item_block_realize(Item_Block *itb)
2514 if (itb->realized) return;
2516 itb->realized = EINA_TRUE;
2517 itb->want_unrealize = EINA_FALSE;
2521 _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
2523 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2524 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0;
2530 Elm_Genlist_Data *sd = psd->wsd;
2532 evas_event_freeze(evas_object_evas_get(obj));
2534 if (sd->pan_changed)
2536 ecore_job_del(sd->calc_job);
2537 sd->calc_job = NULL;
2539 sd->pan_changed = EINA_FALSE;
2542 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2543 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2545 if (sd->tree_effect_enabled &&
2546 (sd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
2548 if (!sd->tree_effect_animator)
2550 _item_tree_effect_before(sd->expanded_item);
2551 evas_object_raise(sd->event_block_rect);
2552 evas_object_stack_below(sd->event_block_rect, sd->stack[1]);
2553 evas_object_show(sd->event_block_rect);
2554 sd->start_time = ecore_time_get();
2555 sd->tree_effect_animator =
2556 ecore_animator_add(_tree_effect_animator_cb, sd->obj);
2560 EINA_INLIST_FOREACH(sd->blocks, itb)
2563 if (ELM_RECTS_INTERSECT(itb->x - sd->pan_x + ox,
2564 itb->y - sd->pan_y + oy,
2566 cvx, cvy, cvw, cvh))
2568 if ((!itb->realized) || (itb->changed))
2569 _item_block_realize(itb);
2570 _item_block_position(itb, in);
2574 if (itb->realized) _item_block_unrealize(itb);
2578 if ((!sd->reorder_it) || (sd->reorder_pan_move))
2579 _group_items_recalc(sd);
2580 if ((sd->reorder_mode) && (sd->reorder_it))
2582 if (sd->pan_y != sd->reorder_old_pan_y)
2583 sd->reorder_pan_move = EINA_TRUE;
2584 else sd->reorder_pan_move = EINA_FALSE;
2586 evas_object_raise(sd->VIEW(reorder_it));
2587 evas_object_stack_below(sd->VIEW(reorder_it), sd->stack[1]);
2588 sd->reorder_old_pan_y = sd->pan_y;
2589 sd->start_time = ecore_loop_time_get();
2592 if (!sd->tree_effect_enabled ||
2593 (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
2594 _item_auto_scroll(sd);
2596 //FIXME: There are issue about wrong list positioning in prepend cases.
2597 // To prevent the issue, allocate repositioning in smart calculate.
2598 if (sd->prepend_items)
2600 Evas_Coord prepend_h = 0;
2601 Elm_Gen_Item *tmp = NULL;
2602 EINA_LIST_FREE(sd->prepend_items, tmp)
2604 prepend_h += tmp->item->minh;
2608 elm_interface_scrollable_content_pos_get(&vx, &vy),
2609 elm_interface_scrollable_content_viewport_geometry_get
2610 (NULL, NULL, &vw, &vh));
2611 /* Set adjusted position as prepended items height */
2612 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(vx, vy + prepend_h, vw, vh));
2616 elm_interface_scrollable_content_pos_get(&vx, &vy),
2617 elm_interface_scrollable_content_viewport_geometry_get
2618 (NULL, NULL, &vw, &vh));
2620 if (sd->reorder_fast == 1)
2621 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(vx, vy - 10, vw, vh));
2622 else if (sd->reorder_fast == -1)
2623 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(vx, vy + 10, vw, vh));
2625 if (sd->focused_item && !sd->item_loop_enable)
2626 _elm_widget_focus_highlight_start(psd->wobj);
2628 EINA_LIST_FOREACH(sd->group_items, l, git)
2630 git->item->want_realize = EINA_FALSE;
2631 if (git->realized) evas_object_raise(VIEW(git));
2634 //update item before the render to prevent delayed update by job.
2637 ELM_SAFE_FREE(sd->update_job, ecore_job_del);
2638 _update_job(sd->obj);
2641 evas_event_thaw(evas_object_evas_get(obj));
2642 evas_event_thaw_eval(evas_object_evas_get(obj));
2644 eo_do(psd->wobj, eo_event_callback_call
2645 (ELM_INTERFACE_SCROLLABLE_EVENT_CHANGED, NULL));
2649 _elm_genlist_pan_eo_base_destructor(Eo *obj, Elm_Genlist_Pan_Data *psd)
2651 eo_data_unref(psd->wobj, psd->wsd);
2652 eo_do_super(obj, MY_PAN_CLASS, eo_destructor());
2656 _elm_genlist_pan_class_constructor(Eo_Class *klass)
2658 evas_smart_legacy_type_register(MY_PAN_CLASS_NAME_LEGACY, klass);
2661 #include "elm_genlist_pan.eo.c"
2664 _item_multi_select_up(Elm_Genlist_Data *sd)
2666 Elm_Object_Item *eo_prev;
2668 if (!sd->selected) return EINA_FALSE;
2669 if (!sd->multi) return EINA_FALSE;
2671 eo_prev = elm_genlist_item_prev_get(sd->last_selected_item);
2674 ELM_GENLIST_ITEM_DATA_GET(eo_prev, prev);
2675 if ((!_is_no_select(prev)) &&
2676 (!elm_object_item_disabled_get(eo_prev)) && (!prev->want_hidden))
2678 eo_prev = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev));
2680 if (!eo_prev) return EINA_TRUE;
2682 if (elm_genlist_item_selected_get(eo_prev))
2684 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2685 sd->last_selected_item = eo_prev;
2689 elm_genlist_item_selected_set(eo_prev, EINA_TRUE);
2695 _item_multi_select_down(Elm_Genlist_Data *sd)
2697 Elm_Object_Item *eo_next;
2699 if (!sd->selected) return EINA_FALSE;
2700 if (!sd->multi) return EINA_FALSE;
2702 eo_next = elm_genlist_item_next_get(sd->last_selected_item);
2705 ELM_GENLIST_ITEM_DATA_GET(eo_next, next);
2706 if ((!_is_no_select(next)) &&
2707 (!elm_object_item_disabled_get(eo_next)) && (!next->want_hidden))
2709 eo_next = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next));
2711 if (!eo_next) return EINA_TRUE;
2713 if (elm_genlist_item_selected_get(eo_next))
2715 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2716 sd->last_selected_item = eo_next;
2720 elm_genlist_item_selected_set(eo_next, EINA_TRUE);
2727 _all_items_deselect(Elm_Genlist_Data *sd)
2729 if (!sd->selected) return EINA_FALSE;
2731 sd->deselecting = eina_list_clone(sd->selected);
2732 while (sd->deselecting)
2734 Elm_Object_Item *it = eina_list_data_get(sd->deselecting);
2736 sd->deselecting = eina_list_remove_list(sd->deselecting, sd->deselecting);
2737 elm_genlist_item_selected_set(it, EINA_FALSE);
2744 _item_single_select_up(Elm_Genlist_Data *sd)
2746 Elm_Gen_Item *prev = NULL;
2749 prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2752 Elm_Object_Item *eo_prev = elm_genlist_item_prev_get
2753 (sd->last_selected_item);
2754 prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
2759 if ((!_is_no_select(prev)) &&
2760 (!elm_object_item_disabled_get(EO_OBJ(prev))) && (!prev->want_hidden))
2762 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2765 if (!prev) return EINA_FALSE;
2767 _all_items_deselect(sd);
2769 elm_genlist_item_selected_set(EO_OBJ(prev), EINA_TRUE);
2774 _item_single_select_down(Elm_Genlist_Data *sd)
2776 Elm_Gen_Item *next = NULL;
2777 Elm_Object_Item *eo_next = NULL;
2780 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2783 eo_next = elm_genlist_item_next_get(sd->last_selected_item);
2784 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2789 if ((!_is_no_select(next)) &&
2790 (!elm_object_item_disabled_get(EO_OBJ(next))) && (!next->want_hidden))
2792 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2795 if (!next) return EINA_FALSE;
2797 _all_items_deselect(sd);
2799 elm_genlist_item_selected_set(EO_OBJ(next), EINA_TRUE);
2805 _elm_genlist_item_focused(Elm_Object_Item *eo_it)
2807 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
2808 Evas_Object *obj = WIDGET(it);
2809 ELM_GENLIST_DATA_GET(obj, sd);
2812 if (_is_no_select(it) ||
2813 (eo_it == sd->focused_item) ||
2814 (eo_do_ret(eo_it, tmp, elm_wdg_item_disabled_get())))
2817 //TIZEN_ONLY(20161209): Do not autoscroll if scroll to item is exist
2820 switch (_elm_config->focus_autoscroll_mode)
2822 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
2823 elm_genlist_item_show(eo_it,
2824 ELM_GENLIST_ITEM_SCROLLTO_IN);
2826 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
2827 elm_genlist_item_bring_in(eo_it,
2828 ELM_GENLIST_ITEM_SCROLLTO_IN);
2836 sd->focused_item = eo_it;
2839 _elm_genlist_item_focus_update(it);
2840 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_ITEM_FOCUSED, eo_it));
2841 if (_elm_config->atspi_mode)
2842 elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_FOCUSED, EINA_TRUE);
2846 _elm_genlist_item_unfocused(Elm_Object_Item *eo_it)
2850 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
2851 Evas_Object *obj = WIDGET(it);
2852 ELM_GENLIST_DATA_GET(obj, sd);
2854 if (_is_no_select(it))
2857 if ((!sd->focused_item) ||
2858 (eo_it != sd->focused_item))
2861 if (elm_widget_focus_highlight_enabled_get(obj))
2863 ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focus_it);
2864 edje_object_signal_emit(VIEW(focus_it), SIGNAL_UNFOCUSED, "elm");
2867 sd->focused_item = NULL;
2868 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_ITEM_UNFOCUSED, eo_it));
2869 if (_elm_config->atspi_mode)
2870 elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_FOCUSED, EINA_FALSE);
2874 _item_focused_next(Evas_Object *obj, Elm_Focus_Direction dir)
2876 ELM_GENLIST_DATA_GET(obj, sd);
2878 Elm_Object_Item *eo_next;
2879 Elm_Object_Item *eo_first_item;
2880 Elm_Object_Item *eo_last_item;
2883 if (!sd->focused_item)
2885 if (dir == ELM_FOCUS_UP)
2886 next = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2887 else if (dir == ELM_FOCUS_DOWN)
2888 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2893 ((eo_do_ret(EO_OBJ(next), tmp, elm_wdg_item_disabled_get())) ||
2894 (_is_no_select(next))))
2895 if (!next->want_hidden) next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2899 ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focus_it);
2900 if (dir == ELM_FOCUS_UP)
2902 eo_first_item = elm_genlist_first_item_get(WIDGET(focus_it));
2903 if (eo_first_item == sd->focused_item) return EINA_FALSE;
2904 eo_next = elm_genlist_item_prev_get(sd->focused_item);
2905 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2908 ((eo_do_ret(eo_next, tmp, elm_wdg_item_disabled_get())) ||
2909 (_is_no_select(next))))
2911 eo_next = elm_genlist_item_prev_get(eo_next);
2912 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2915 else if (dir == ELM_FOCUS_DOWN)
2917 eo_last_item = elm_genlist_last_item_get(WIDGET(focus_it));
2918 if (eo_last_item == sd->focused_item) return EINA_FALSE;
2919 eo_next = elm_genlist_item_next_get(sd->focused_item);
2920 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2923 ((eo_do_ret(eo_next, tmp, elm_wdg_item_disabled_get())) ||
2924 (_is_no_select(next))))
2926 eo_next = elm_genlist_item_next_get(eo_next);
2927 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2933 if (!next) return EINA_FALSE;
2936 elm_object_item_focus_set(EO_OBJ(next), EINA_TRUE);
2942 _elm_genlist_item_content_focus_set(Elm_Gen_Item *it, Elm_Focus_Direction dir)
2944 Evas_Object *focused_obj = NULL;
2948 if (!GL_IT(it)->wsd->focus_on_selection_enabled) return;
2950 if (!it->item_focus_chain)
2952 elm_object_focus_set(VIEW(it), EINA_TRUE);
2956 EINA_LIST_FOREACH(it->item_focus_chain, l, focused_obj)
2957 if (elm_object_focus_get(focused_obj)) break;
2959 if (focused_obj && (dir != ELM_FOCUS_PREVIOUS))
2961 Evas_Object *nextfocus;
2962 Elm_Object_Item *nextfocus_item;
2963 if (elm_widget_focus_next_get(focused_obj, dir, &nextfocus, &nextfocus_item))
2966 elm_object_item_focus_set(nextfocus_item, EINA_TRUE);
2968 elm_object_focus_set(nextfocus, EINA_TRUE);
2973 if (!l) l = it->item_focus_chain;
2975 if (dir == ELM_FOCUS_RIGHT)
2977 l = eina_list_next(l);
2978 if (!l) l = it->item_focus_chain;
2980 else if (dir == ELM_FOCUS_LEFT)
2982 l = eina_list_prev(l);
2983 if (!l) l = eina_list_last(it->item_focus_chain);
2986 elm_object_focus_set(eina_list_data_get(l), EINA_TRUE);
2990 _key_action_move_dir(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool multi)
2992 ELM_GENLIST_DATA_GET(obj, sd);
2993 Elm_Object_Item *it = NULL;
2994 Eina_Bool ret = EINA_FALSE;
2997 Eina_Bool focus_only = EINA_FALSE;
2999 // get content size and viewport size
3001 elm_interface_scrollable_content_viewport_geometry_get
3002 (NULL, NULL, NULL, &v),
3003 elm_interface_scrollable_content_size_get(NULL, &min));
3005 if (_elm_config->item_select_on_focus_disable)
3007 ret = _item_focused_next(obj, dir);
3013 if (dir == ELM_FOCUS_UP)
3014 ret = _item_multi_select_up(sd);
3015 else if (dir == ELM_FOCUS_DOWN)
3016 ret = _item_multi_select_down(sd);
3020 if (dir == ELM_FOCUS_UP)
3021 ret = _item_single_select_up(sd);
3022 else if (dir == ELM_FOCUS_DOWN)
3023 ret = _item_single_select_down(sd);
3029 focus_only = _elm_config->item_select_on_focus_disable;
3030 // handle item loop feature
3031 if (sd->item_loop_enable && !sd->item_looping_on)
3035 if (dir == ELM_FOCUS_UP)
3037 elm_layout_signal_emit(obj, "elm,action,looping,up", "elm");
3038 sd->item_looping_on = EINA_TRUE;
3040 else if (dir == ELM_FOCUS_DOWN)
3042 elm_layout_signal_emit(obj, "elm,action,looping,down", "elm");
3043 sd->item_looping_on = EINA_TRUE;
3048 if (dir == ELM_FOCUS_UP)
3049 it = elm_genlist_last_item_get(obj);
3050 else if (dir == ELM_FOCUS_DOWN)
3051 it = elm_genlist_first_item_get(obj);
3053 if (it && focus_only)
3054 elm_object_item_focus_set(it, EINA_TRUE);
3056 elm_genlist_item_selected_set(it, EINA_TRUE);
3060 else if (sd->item_looping_on)
3067 _key_action_move(Evas_Object *obj, const char *params)
3069 ELM_GENLIST_DATA_GET(obj, sd);
3070 const char *dir = params;
3076 Evas_Coord step_x = 0;
3077 Evas_Coord step_y = 0;
3078 Evas_Coord page_x = 0;
3079 Evas_Coord page_y = 0;
3080 Elm_Object_Item *it = NULL;
3081 Evas_Coord pan_max_x = 0, pan_max_y = 0;
3084 elm_interface_scrollable_content_pos_get(&x, &y),
3085 elm_interface_scrollable_step_size_get(&step_x, &step_y),
3086 elm_interface_scrollable_page_size_get(&page_x, &page_y),
3087 elm_interface_scrollable_content_viewport_geometry_get
3088 (NULL, NULL, &v_w, &v_h));
3090 _elm_widget_focus_auto_show(obj);
3091 if (!strcmp(dir, "left"))
3095 Elm_Object_Item *eo_gt = elm_genlist_selected_item_get(obj);
3096 ELM_GENLIST_ITEM_DATA_GET(eo_gt, gt);
3097 _elm_genlist_item_content_focus_set(gt, ELM_FOCUS_LEFT);
3101 else if (!strcmp(dir, "right"))
3105 Elm_Object_Item *eo_gt = elm_genlist_selected_item_get(obj);
3106 ELM_GENLIST_ITEM_DATA_GET(eo_gt, gt);
3107 _elm_genlist_item_content_focus_set(gt, ELM_FOCUS_RIGHT);
3111 else if (!strcmp(dir, "up"))
3113 if (_key_action_move_dir(obj, ELM_FOCUS_UP, EINA_FALSE)) return EINA_TRUE;
3114 else return EINA_FALSE;
3116 else if (!strcmp(dir, "up_multi"))
3118 if (_key_action_move_dir(obj, ELM_FOCUS_UP, EINA_TRUE)) return EINA_TRUE;
3119 else if (_key_action_move_dir(obj, ELM_FOCUS_UP, EINA_FALSE)) return EINA_TRUE;
3120 else return EINA_FALSE;
3122 else if (!strcmp(dir, "down"))
3124 if (_key_action_move_dir(obj, ELM_FOCUS_DOWN, EINA_FALSE)) return EINA_TRUE;
3125 else return EINA_FALSE;
3127 else if (!strcmp(dir, "down_multi"))
3129 if (_key_action_move_dir(obj, ELM_FOCUS_DOWN, EINA_TRUE)) return EINA_TRUE;
3130 else if (_key_action_move_dir(obj, ELM_FOCUS_DOWN, EINA_FALSE)) return EINA_TRUE;
3131 else return EINA_FALSE;
3133 else if (!strcmp(dir, "first"))
3135 it = elm_genlist_first_item_get(obj);
3138 if (_elm_config->item_select_on_focus_disable)
3140 elm_object_item_focus_set(it, EINA_TRUE);
3141 elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
3145 elm_genlist_item_selected_set(it, EINA_TRUE);
3150 else if (!strcmp(dir, "last"))
3152 it = elm_genlist_last_item_get(obj);
3155 if (_elm_config->item_select_on_focus_disable)
3157 elm_object_item_focus_set(it, EINA_TRUE);
3158 elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_BOTTOM);
3162 elm_genlist_item_selected_set(it, EINA_TRUE);
3167 else if (!strcmp(dir, "prior"))
3170 y -= -(page_y * v_h) / 100;
3174 else if (!strcmp(dir, "next"))
3177 y += -(page_y * v_h) / 100;
3181 else return EINA_FALSE;
3183 eo_do(sd->pan_obj, elm_obj_pan_pos_max_get(&pan_max_x, &pan_max_y));
3185 if (x > pan_max_x) x = pan_max_x;
3187 if (y > pan_max_y) y = pan_max_y;
3189 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
3195 _key_action_select(Evas_Object *obj, const char *params)
3197 Elm_Object_Item *eo_it = NULL;
3199 eo_it = elm_object_focused_item_get(obj);
3200 if (!eo_it) return EINA_TRUE;
3201 elm_genlist_item_expanded_set(eo_it, !elm_genlist_item_expanded_get(eo_it));
3202 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
3203 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3206 ((sd->multi_select_mode != ELM_OBJECT_MULTI_SELECT_MODE_WITH_CONTROL) ||
3207 (!strcmp(params, "multi"))))
3211 _item_highlight(it);
3212 if (_item_select(it)) goto deleted;
3221 while (sd->selected)
3223 Elm_Object_Item *eo_sel = sd->selected->data;
3224 Elm_Gen_Item *sel = eo_data_scope_get(eo_sel, ELM_GENLIST_ITEM_CLASS);
3225 _item_unselect(sel);
3230 const Eina_List *l, *l_next;
3231 Elm_Object_Item *eo_it2;
3233 EINA_LIST_FOREACH_SAFE(sd->selected, l, l_next, eo_it2)
3235 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
3237 _item_unselect(it2);
3240 _item_highlight(it);
3241 if (_item_select(it)) goto deleted;
3244 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_ACTIVATED, EO_OBJ(it)));
3253 _key_action_escape(Evas_Object *obj, const char *params EINA_UNUSED)
3255 ELM_GENLIST_DATA_GET(obj, sd);
3257 if (!_all_items_deselect(sd)) return EINA_FALSE;
3261 EOLIAN static Eina_Bool
3262 _elm_genlist_elm_widget_event(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *src, Evas_Callback_Type type, void *event_info)
3265 Evas_Event_Key_Down *ev = event_info;
3267 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3268 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
3269 if (!sd->items) return EINA_FALSE;
3271 if (!_elm_config_key_binding_call(obj, ev, key_actions))
3274 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3278 /* This function disables the specific code of the layout sub object add.
3279 * Only the widget sub_object_add is called.
3281 EOLIAN static Eina_Bool
3282 _elm_genlist_elm_layout_sub_object_add_enable(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3287 EOLIAN static Eina_Bool
3288 _elm_genlist_elm_widget_sub_object_add(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED, Evas_Object *sobj)
3290 Eina_Bool int_ret = EINA_FALSE;
3292 /* skipping layout's code, which registers size hint changing
3293 * callback on sub objects. this is here because items'
3294 * content_get() routines may change hints on the objects after
3295 * creation, thus issuing TOO MANY sizing_eval()'s here. they are
3296 * not needed at here anyway, so let's skip listening to those
3298 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_add(sobj));
3299 if (!int_ret) return EINA_FALSE;
3304 EOLIAN static Eina_Bool
3305 _elm_genlist_elm_widget_sub_object_del(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *sobj)
3307 Eina_Bool int_ret = EINA_FALSE;
3310 /* XXX: hack -- also skipping sizing recalculation on
3311 * sub-object-del. genlist's crazy code paths (like groups and
3312 * such) seem to issue a whole lot of deletions and Evas bitches
3313 * about too many recalculations */
3314 sd->on_sub_del = EINA_TRUE;
3316 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_del(sobj));
3317 if (!int_ret) return EINA_FALSE;
3319 sd->on_sub_del = EINA_FALSE;
3325 * This function searches the nearest visible item based on the given item.
3326 * If the given item is in the genlist viewport, this returns the given item.
3327 * Or this searches the realized items and checks the nearest fully visible item
3328 * according to the given item's position.
3330 static Elm_Object_Item *
3331 _elm_genlist_nearest_visible_item_get(Evas_Object *obj, Elm_Object_Item *eo_it)
3333 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0; // genlist viewport geometry
3334 Evas_Coord ix = 0, iy = 0, iw = 0, ih = 0; // given item geometry
3335 Evas_Coord cx = 0, cy = 0, cw = 0, ch = 0; // candidate item geometry
3336 Eina_List *item_list = NULL, *l = NULL;
3337 Elm_Object_Item *eo_item = NULL;
3338 ELM_GENLIST_DATA_GET(obj, sd);
3339 Eina_Bool search_next = EINA_FALSE;
3341 if (!eo_it) return NULL;
3342 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
3344 evas_object_geometry_get(sd->pan_obj, &vx, &vy, &vw, &vh);
3345 evas_object_geometry_get(VIEW(it), &ix, &iy, &iw, &ih); // FIXME: check if the item is realized or not
3347 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, ix, iy, iw, ih))
3349 if (!elm_object_item_disabled_get(eo_it))
3352 search_next = EINA_TRUE;
3355 item_list = elm_genlist_realized_items_get(obj);
3357 if ((iy < vy) || search_next)
3359 EINA_LIST_FOREACH(item_list, l, eo_item)
3361 ELM_GENLIST_ITEM_DATA_GET(eo_item, item);
3362 evas_object_geometry_get(VIEW(item), &cx, &cy, &cw, &ch);
3363 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, cx, cy, cw, ch) &&
3364 !elm_object_item_disabled_get(eo_item))
3366 eina_list_free(item_list);
3373 EINA_LIST_REVERSE_FOREACH(item_list, l, eo_item)
3375 ELM_GENLIST_ITEM_DATA_GET(eo_item, item);
3376 evas_object_geometry_get(VIEW(item), &cx, &cy, &cw, &ch);
3377 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, cx, cy, cw, ch) &&
3378 !elm_object_item_disabled_get(eo_item))
3380 eina_list_free(item_list);
3385 eina_list_free(item_list);
3390 EOLIAN static Eina_Bool
3391 _elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd, Elm_Object_Item *item EINA_UNUSED)
3393 Eina_Bool int_ret = EINA_FALSE;
3394 Elm_Object_Item *eo_it = NULL;
3395 Eina_Bool is_sel = EINA_FALSE;
3397 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_on_focus(NULL));
3398 if (!int_ret) return EINA_FALSE;
3400 if (elm_widget_focus_get(obj) && (sd->items) && (sd->selected) &&
3401 (!sd->last_selected_item))
3403 sd->last_selected_item = eina_list_data_get(sd->selected);
3406 if (elm_widget_focus_get(obj) && !sd->mouse_down)
3408 if (sd->last_focused_item)
3409 eo_it = sd->last_focused_item;
3410 else if (sd->last_selected_item)
3411 eo_it = sd->last_selected_item;
3412 else if (_elm_config->first_item_focus_on_first_focus_in)
3414 eo_it = elm_genlist_first_item_get(obj);
3420 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
3421 if ((!_is_no_select(it)) && (!elm_object_item_disabled_get(eo_it)))
3423 eo_it = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next));
3428 eo_it = _elm_genlist_nearest_visible_item_get(obj, eo_it);
3431 if (!_elm_config->item_select_on_focus_disable && is_sel)
3432 elm_genlist_item_selected_set(eo_it, EINA_TRUE);
3434 elm_object_item_focus_set(eo_it, EINA_TRUE);
3435 _elm_widget_focus_highlight_start(obj);
3441 if (sd->focused_item)
3443 sd->last_focused_item = sd->focused_item;
3444 _elm_genlist_item_unfocused(sd->focused_item);
3451 static Eina_Bool _elm_genlist_smart_focus_next_enable = EINA_FALSE;
3453 EOLIAN static Eina_Bool
3454 _elm_genlist_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3456 return _elm_genlist_smart_focus_next_enable;
3459 EOLIAN static Eina_Bool
3460 _elm_genlist_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3465 EOLIAN static Eina_Bool
3466 _elm_genlist_elm_widget_focus_next(Eo *obj, Elm_Genlist_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
3468 Evas_Coord x, y, w, h;
3469 Evas_Coord sx, sy, sw, sh;
3471 Eina_List *items = NULL;
3472 Eina_Bool done = EINA_FALSE;
3474 evas_object_geometry_get(sd->obj, &sx, &sy, &sw, &sh);
3476 EINA_INLIST_FOREACH(sd->blocks, itb)
3484 EINA_LIST_FOREACH(itb->items, l, it)
3488 evas_object_geometry_get(it->base->view, &x, &y, &w, &h);
3490 /* check item which displays more than half of its size */
3491 if (it->base->access_obj &&
3493 (x + (w / 2), y + (h / 2), 0, 0, sx, sy, sw, sh))
3494 items = eina_list_append(items, it->base->access_obj);
3496 if (!it->base->access_order) continue;
3500 EINA_LIST_FOREACH(it->base->access_order, subl, subo)
3501 items = eina_list_append(items, subo);
3505 else if (done) break;
3508 return elm_widget_focus_list_next_get
3509 (obj, items, eina_list_data_get, dir, next, next_item);
3513 _mirrored_set(Evas_Object *obj,
3516 ELM_GENLIST_DATA_GET(obj, sd);
3518 _item_cache_zero(sd);
3519 eo_do(obj, elm_interface_scrollable_mirrored_set(rtl));
3522 EOLIAN static Elm_Theme_Apply
3523 _elm_genlist_elm_widget_theme_apply(Eo *obj, Elm_Genlist_Data *sd)
3526 Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
3530 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
3531 if (!int_ret) return ELM_THEME_APPLY_FAILED;
3533 evas_event_freeze(evas_object_evas_get(obj));
3534 _item_cache_zero(sd);
3535 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3537 eina_hash_free_buckets(sd->size_caches);
3538 sd->minw = sd->minh = sd->realminw = 0;
3540 EINA_INLIST_FOREACH(sd->blocks, itb)
3542 if (itb->realized) _item_block_unrealize(itb);
3543 EINA_LIST_FOREACH(itb->items, l, it)
3544 it->item->mincalcd = EINA_FALSE;
3546 itb->changed = EINA_TRUE;
3548 ecore_job_del(sd->calc_job);
3549 sd->calc_job = ecore_job_add(_calc_job, obj);
3550 elm_layout_sizing_eval(obj);
3551 evas_event_thaw(evas_object_evas_get(obj));
3552 evas_event_thaw_eval(evas_object_evas_get(obj));
3557 /* FIXME: take off later. maybe this show region coords belong in the
3558 * interface (new api functions, set/get)? */
3560 _show_region_hook(void *data EINA_UNUSED,
3563 Evas_Coord x, y, w, h;
3565 ELM_GENLIST_DATA_GET_OR_RETURN(obj, sd);
3567 elm_widget_show_region_get(obj, &x, &y, &w, &h);
3568 //x & y are screen coordinates, Add with pan coordinates
3571 eo_do(obj, elm_interface_scrollable_content_region_show(x, y, w, h));
3574 //Tizen Only(20170113)
3575 EOLIAN static Eina_Bool
3576 _elm_genlist_elm_widget_translate(Eo *obj, Elm_Genlist_Data *sd)
3580 // Before calling text_get, inform user first.
3581 evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
3583 // FIXME: We should change item's height if lang is changed??
3584 EINA_INLIST_FOREACH(sd->blocks, itb)
3588 EINA_LIST_FOREACH(itb->items, l, it)
3592 elm_genlist_item_fields_update(EO_OBJ(it),
3594 ELM_GENLIST_ITEM_FIELD_TEXT);
3604 _item_highlight(Elm_Gen_Item *it)
3607 const char *selectraise;
3608 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3610 if (_is_no_select(it) ||
3612 (it->highlighted) || eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()) ||
3613 (it->item->deco_it_view))
3616 edje_object_signal_emit(VIEW(it), SIGNAL_SELECTED, "elm");
3617 if (it->deco_all_view)
3618 edje_object_signal_emit(it->deco_all_view, SIGNAL_SELECTED, "elm");
3619 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_HIGHLIGHTED, EO_OBJ(it)));
3621 selectraise = edje_object_data_get(VIEW(it), "selectraise");
3622 if ((selectraise) && (!strcmp(selectraise, "on")))
3624 if (it->deco_all_view) evas_object_stack_below(it->deco_all_view, sd->stack[1]);
3625 else evas_object_stack_below(VIEW(it), sd->stack[1]);
3626 if ((it->item->group_item) && (it->item->group_item->realized))
3627 evas_object_stack_above(it->item->VIEW(group_item), sd->stack[1]);
3629 it->highlighted = EINA_TRUE;
3633 _item_unhighlight(Elm_Gen_Item *it)
3635 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3637 if (!it->highlighted) return;
3639 edje_object_signal_emit(VIEW(it), SIGNAL_UNSELECTED, "elm");
3640 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_UNHIGHLIGHTED, EO_OBJ(it)));
3641 if (it->deco_all_view)
3642 edje_object_signal_emit
3643 (it->deco_all_view, SIGNAL_UNSELECTED, "elm");
3645 if (!it->item->nostacking)
3647 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
3649 if (it->deco_all_view) evas_object_stack_below(it->deco_all_view, sd->stack[0]);
3650 else evas_object_stack_below(VIEW(it), sd->stack[0]);
3654 if (it->deco_all_view) evas_object_stack_above(it->deco_all_view, sd->stack[0]);
3655 else evas_object_stack_above(VIEW(it), sd->stack[0]);
3658 it->highlighted = EINA_FALSE;
3662 _item_block_position_update(Eina_Inlist *list,
3667 EINA_INLIST_FOREACH(list, tmp)
3669 tmp->position = idx++;
3670 tmp->position_update = EINA_TRUE;
3675 _item_position_update(Eina_List *list,
3681 EINA_LIST_FOREACH(list, l, it)
3683 it->position = idx++;
3684 it->position_update = EINA_TRUE;
3689 _item_block_merge(Item_Block *left,
3695 EINA_LIST_FOREACH(right->items, l, it2)
3697 it2->item->block = left;
3699 left->changed = EINA_TRUE;
3701 left->items = eina_list_merge(left->items, right->items);
3705 _item_block_del(Elm_Gen_Item *it)
3708 Item_Block *itb = it->item->block;
3709 Eina_Bool block_changed = EINA_FALSE;
3710 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3712 itb->items = eina_list_remove(itb->items, it);
3714 itb->changed = EINA_TRUE;
3715 ecore_job_del(sd->calc_job);
3716 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
3721 il = EINA_INLIST_GET(itb);
3722 itbn = (Item_Block *)(il->next);
3724 it->parent->item->items =
3725 eina_list_remove(it->parent->item->items, EO_OBJ(it));
3728 _item_block_position_update(il->next, itb->position);
3729 sd->blocks = eina_inlist_remove(sd->blocks, il);
3732 if (itbn) itbn->changed = EINA_TRUE;
3736 if (itb->count < (sd->max_items_per_block / 2))
3741 il = EINA_INLIST_GET(itb);
3742 itbp = (Item_Block *)(il->prev);
3743 itbn = (Item_Block *)(il->next);
3745 /* merge block with previous */
3747 ((itbp->count + itb->count) <
3748 (sd->max_items_per_block +
3749 (sd->max_items_per_block / 2))))
3751 _item_block_merge(itbp, itb);
3752 _item_block_position_update
3753 (EINA_INLIST_GET(itb)->next, itb->position);
3754 sd->blocks = eina_inlist_remove
3755 (sd->blocks, EINA_INLIST_GET(itb));
3757 block_changed = EINA_TRUE;
3759 /* merge block with next */
3761 ((itbn->count + itb->count) <
3762 (sd->max_items_per_block +
3763 (sd->max_items_per_block / 2))))
3765 _item_block_merge(itb, itbn);
3766 _item_block_position_update
3767 (EINA_INLIST_GET(itbn)->next, itbn->position);
3769 eina_inlist_remove(sd->blocks, EINA_INLIST_GET(itbn));
3771 block_changed = EINA_TRUE;
3778 sd->pan_changed = EINA_TRUE;
3779 evas_object_smart_changed(sd->pan_obj);
3780 ecore_job_del(sd->calc_job);
3781 sd->calc_job = NULL;
3786 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3788 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3790 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3791 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
3792 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3793 _elm_genlist_item_position_state_update(it);
3794 _elm_genlist_item_state_update(it);
3796 if (it->item->wsd->reorder_mode)
3798 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
3799 edje_object_signal_emit(it->deco_all_view, SIGNAL_REORDER_MODE_UNSET,
3803 _view_clear(it->deco_all_view, &(GL_IT(it)->deco_all_texts),
3804 &(GL_IT(it)->deco_all_contents));
3806 edje_object_signal_emit(VIEW(it), SIGNAL_DECORATE_DISABLED, "elm");
3808 edje_object_message_signal_process(it->deco_all_view);
3809 _item_mouse_callbacks_del(it, it->deco_all_view);
3810 _item_mouse_callbacks_add(it, VIEW(it));
3812 ELM_SAFE_FREE(it->deco_all_view, evas_object_del);
3814 it->item->decorate_all_item_realized = EINA_FALSE;
3818 _elm_genlist_item_del_not_serious(Elm_Gen_Item *it)
3820 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3821 Elm_Object_Item *eo_it = EO_OBJ(it);
3823 eo_do(eo_it, elm_wdg_item_pre_notify_del());
3827 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
3828 if (sd->deselecting)
3829 sd->deselecting = eina_list_remove(sd->deselecting, it);
3831 if (sd->last_focused_item == eo_it)
3832 sd->last_focused_item = NULL;
3833 if (sd->focused_item == eo_it)
3834 sd->focused_item = NULL;
3835 if (sd->last_selected_item == eo_it)
3836 sd->last_selected_item = NULL;
3838 if (it->itc->func.del)
3839 it->itc->func.del((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it));
3843 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
3845 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3848 _elm_genlist_item_del_not_serious(it);
3850 //(it->walking == -1) means it's already removed from the list.
3851 if (it->walking != -1)
3852 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
3853 if (it->tooltip.del_cb)
3854 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
3855 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
3856 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
3857 sd->group_items = eina_list_remove(sd->group_items, it);
3859 ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
3860 ecore_job_del(sd->calc_job);
3861 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
3863 ELM_SAFE_FREE(it->item, free);
3867 _item_del(Elm_Gen_Item *it)
3869 Evas_Object *obj = WIDGET(it);
3870 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3872 evas_event_freeze(evas_object_evas_get(obj));
3876 it->item->rel->item->rel_revs =
3877 eina_list_remove(it->item->rel->item->rel_revs, it);
3879 if (it->item->rel_revs)
3882 EINA_LIST_FREE(it->item->rel_revs, tmp) tmp->item->rel = NULL;
3884 elm_genlist_item_subitems_clear(EO_OBJ(it));
3885 if (sd->show_item == it) sd->show_item = NULL;
3886 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
3887 if (it->item->decorate_all_item_realized) _decorate_all_item_unrealize(it);
3888 if (it->item->block) _item_block_del(it);
3889 if (it->item->queued)
3890 sd->queue = eina_list_remove(sd->queue, it);
3891 if (sd->anchor_item == it)
3893 sd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3894 if (!sd->anchor_item)
3896 ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3898 if (sd->expanded_item == it)
3900 if (sd->tree_effect_animator)
3902 _item_tree_effect_finish(sd);
3903 ELM_SAFE_FREE(sd->tree_effect_animator, ecore_animator_del);
3905 sd->expanded_item = NULL;
3906 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
3908 if (sd->expanded_next_item == it) sd->expanded_next_item = NULL;
3909 if (sd->move_items) sd->move_items = eina_list_remove(sd->move_items, it);
3911 it->parent->item->items = eina_list_remove(it->parent->item->items, EO_OBJ(it));
3912 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
3913 _elm_genlist_item_del_serious(it);
3915 if (it->itc->refcount <= 1 && eina_hash_find(sd->size_caches, &(it->itc)))
3916 eina_hash_del_by_key(sd->size_caches, it->itc);
3917 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
3918 evas_event_thaw(evas_object_evas_get(obj));
3919 evas_event_thaw_eval(evas_object_evas_get(obj));
3920 if (!sd->queue) _item_scroll(sd);
3924 _item_unselect(Elm_Gen_Item *it)
3926 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3928 _item_unhighlight(it); /* unhighlight the item first */
3929 if (!it->selected) return; /* then check whether the item is selected */
3931 if (GL_IT(it)->wsd->focus_on_selection_enabled)
3935 EINA_LIST_FOREACH(it->item_focus_chain, l, eobj)
3936 elm_object_focus_set(eobj, EINA_FALSE);
3939 it->selected = EINA_FALSE;
3940 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
3941 eo_do(WIDGET(it), eo_event_callback_call
3942 (EVAS_SELECTABLE_INTERFACE_EVENT_UNSELECTED, EO_OBJ(it)));
3943 if (_elm_config->atspi_mode)
3944 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_SELECTED, EINA_FALSE);
3948 _item_mouse_in_cb(void *data,
3949 Evas *evas EINA_UNUSED,
3950 Evas_Object *obj EINA_UNUSED,
3951 void *event_info EINA_UNUSED)
3953 Elm_Gen_Item *it = data;
3954 if (!elm_object_item_disabled_get(EO_OBJ(it)) &&
3955 (_elm_config->focus_move_policy == ELM_FOCUS_MOVE_POLICY_IN))
3956 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3960 _item_mouse_move_cb(void *data,
3961 Evas *evas EINA_UNUSED,
3965 Elm_Gen_Item *it = data;
3966 Evas_Event_Mouse_Move *ev = event_info;
3967 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
3968 Evas_Coord minw = 0, minh = 0, x, y, w, h, dx, dy, adx, ady;
3969 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3970 Elm_Object_Item *eo_it = EO_OBJ(it);
3972 evas_object_geometry_get(obj, &x, &y, &w, &h);
3973 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3977 sd->on_hold = EINA_TRUE;
3978 if ((!sd->wasselected) && (!it->flipped))
3982 else if (ELM_RECTS_POINT_OUT(x, y, w, h, ev->cur.canvas.x, ev->cur.canvas.y) &&
3985 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
3986 if ((!sd->wasselected) && (!it->flipped))
3988 it->base->still_in = EINA_FALSE;
3991 if (sd->multi_touched)
3993 sd->cur_x = ev->cur.canvas.x;
3994 sd->cur_y = ev->cur.canvas.y;
3997 if ((it->dragging) && (it->down))
3999 if (sd->movements == SWIPE_MOVES)
4000 sd->swipe = EINA_TRUE;
4003 sd->history[sd->movements].x = ev->cur.canvas.x;
4004 sd->history[sd->movements].y = ev->cur.canvas.y;
4005 if (abs((sd->history[sd->movements].x -
4006 sd->history[0].x)) > 40)
4007 sd->swipe = EINA_TRUE;
4011 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4012 eo_do(WIDGET(it), eo_event_callback_call
4013 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG, eo_it));
4016 if ((!it->down) || (sd->longpressed))
4018 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4019 if ((sd->reorder_mode) && (sd->reorder_it))
4021 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
4023 if (ev->cur.canvas.y < (oy + (sd->reorder_it->item->h / 2)))
4024 sd->reorder_fast = 1;
4025 else if (ev->cur.canvas.y > (oy + oh - (sd->reorder_it->item->h / 2)))
4026 sd->reorder_fast = -1;
4027 else sd->reorder_fast = 0;
4029 it_scrl_y = ev->cur.canvas.y - sd->reorder_it->dy;
4031 if (!sd->reorder_start_y)
4032 sd->reorder_start_y = it->item->block->y + it->y;
4036 else if (it_scrl_y + sd->reorder_it->item->h > oy + oh)
4037 y_pos = oy + oh - sd->reorder_it->item->h;
4041 if (it->deco_all_view)
4042 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
4044 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
4046 ecore_job_del(sd->calc_job);
4047 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
4051 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
4052 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
4054 evas_object_geometry_get(obj, &x, &y, &w, &h);
4055 x = ev->cur.canvas.x - x;
4056 y = ev->cur.canvas.y - y;
4059 if (adx < 0) adx = -dx;
4063 if (ady < 0) ady = -dy;
4068 // gah! annoying drag detection - leave this alone
4071 if (minw < h) minw = h;
4072 if (minh < h) minh = h;
4076 if (minw < w) minw = w;
4077 if (minh < w) minh = w;
4079 if (minw < 5) minw = 5;
4080 if (minh < 5) minh = 5;
4082 if ((adx > minw) || (ady > minh))
4084 it->dragging = EINA_TRUE;
4085 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4089 eo_do(WIDGET(it), eo_event_callback_call
4090 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_UP, eo_it));
4094 eo_do(WIDGET(it), eo_event_callback_call
4095 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_LEFT, eo_it));
4097 eo_do(WIDGET(it), eo_event_callback_call
4098 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_RIGHT, eo_it));
4104 eo_do(WIDGET(it), eo_event_callback_call
4105 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_DOWN, eo_it));
4109 eo_do(WIDGET(it), eo_event_callback_call
4110 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_LEFT, eo_it));
4112 eo_do(WIDGET(it), eo_event_callback_call
4113 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_RIGHT, eo_it));
4120 _long_press_cb(void *data)
4123 Elm_Gen_Item *it = data;
4124 Elm_Object_Item *eo_it_tmp;
4126 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4128 if (_is_no_select(it) ||
4129 eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()) || (it->dragging))
4132 sd->longpressed = EINA_TRUE;
4133 eo_do(WIDGET(it), eo_event_callback_call
4134 (EVAS_CLICKABLE_INTERFACE_EVENT_LONGPRESSED, EO_OBJ(it)));
4135 if ((sd->reorder_mode) && !(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP))
4137 sd->reorder_it = it;
4138 sd->reorder_start_y = 0;
4139 if (it->deco_all_view)
4140 evas_object_stack_below(it->deco_all_view, sd->stack[1]);
4142 evas_object_stack_below(VIEW(it), sd->stack[1]);
4144 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
4145 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
4146 (EINA_FALSE, EINA_FALSE));
4148 list = elm_genlist_realized_items_get
4150 EINA_LIST_FREE(list, eo_it_tmp)
4152 ELM_GENLIST_ITEM_DATA_GET(eo_it_tmp, it_tmp);
4153 if (it != it_tmp) _item_unselect(it_tmp);
4156 if (elm_genlist_item_expanded_get(EO_OBJ(it)))
4158 elm_genlist_item_expanded_set(EO_OBJ(it), EINA_FALSE);
4159 return ECORE_CALLBACK_RENEW;
4162 if (!sd->decorate_all_mode)
4164 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
4165 //TIZEN_ONLY(20160520): genlist: added atspi support for drag n drop
4166 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_ANIMATED, EINA_TRUE);
4172 it->long_timer = NULL;
4173 return ECORE_CALLBACK_CANCEL;
4177 _swipe_do(Elm_Gen_Item *it)
4181 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4183 if (_is_no_select(it) ||
4184 eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get())) return;
4186 sd->swipe = EINA_FALSE;
4187 for (i = 0; i < sd->movements; i++)
4189 sum += sd->history[i].x;
4190 if (abs(sd->history[0].y - sd->history[i].y) > 10)
4194 sum /= sd->movements;
4195 if (abs(sum - sd->history[0].x) <= 10) return;
4196 eo_do(WIDGET(it), eo_event_callback_call
4197 (ELM_GENLIST_EVENT_SWIPE, EO_OBJ(it)));
4201 _swipe_cancel(void *data)
4203 Elm_Gen_Item *it = data;
4204 if (!it) return ECORE_CALLBACK_CANCEL;
4205 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4207 sd->swipe = EINA_FALSE;
4210 return ECORE_CALLBACK_RENEW;
4214 _multi_cancel(void *data)
4216 ELM_GENLIST_DATA_GET(data, sd);
4218 if (!sd) return ECORE_CALLBACK_CANCEL;
4219 sd->multi_timeout = EINA_TRUE;
4221 return ECORE_CALLBACK_RENEW;
4225 _multi_touch_gesture_eval(Elm_Gen_Item *it)
4227 Evas_Coord minw = 0, minh = 0;
4228 Evas_Coord off_x, off_y, off_mx, off_my;
4229 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4230 Elm_Object_Item *eo_it = EO_OBJ(it);
4232 sd->multi_touched = EINA_FALSE;
4233 ELM_SAFE_FREE(sd->multi_timer, ecore_timer_del);
4234 if (sd->multi_timeout)
4236 sd->multi_timeout = EINA_FALSE;
4240 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
4241 off_x = abs(sd->cur_x - sd->prev_x);
4242 off_y = abs(sd->cur_y - sd->prev_y);
4243 off_mx = abs(sd->cur_mx - sd->prev_mx);
4244 off_my = abs(sd->cur_my - sd->prev_my);
4246 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw)
4247 || (off_my > minh)))
4249 if ((off_x + off_mx) > (off_y + off_my))
4251 if ((sd->cur_x > sd->prev_x) && (sd->cur_mx > sd->prev_mx))
4252 eo_do(WIDGET(it), eo_event_callback_call
4253 (ELM_GENLIST_EVENT_MULTI_SWIPE_RIGHT, eo_it));
4254 else if ((sd->cur_x < sd->prev_x) && (sd->cur_mx < sd->prev_mx))
4255 eo_do(WIDGET(it), eo_event_callback_call
4256 (ELM_GENLIST_EVENT_MULTI_SWIPE_LEFT, eo_it));
4257 else if (abs(sd->cur_x - sd->cur_mx) >
4258 abs(sd->prev_x - sd->prev_mx))
4259 eo_do(WIDGET(it), eo_event_callback_call
4260 (ELM_GENLIST_EVENT_MULTI_PINCH_OUT, eo_it));
4262 eo_do(WIDGET(it), eo_event_callback_call
4263 (ELM_GENLIST_EVENT_MULTI_PINCH_IN, eo_it));
4267 if ((sd->cur_y > sd->prev_y) && (sd->cur_my > sd->prev_my))
4268 eo_do(WIDGET(it), eo_event_callback_call
4269 (ELM_GENLIST_EVENT_MULTI_SWIPE_DOWN, eo_it));
4270 else if ((sd->cur_y < sd->prev_y) && (sd->cur_my < sd->prev_my))
4271 eo_do(WIDGET(it), eo_event_callback_call
4272 (ELM_GENLIST_EVENT_MULTI_SWIPE_UP, eo_it));
4273 else if (abs(sd->cur_y - sd->cur_my) >
4274 abs(sd->prev_y - sd->prev_my))
4275 eo_do(WIDGET(it), eo_event_callback_call
4276 (ELM_GENLIST_EVENT_MULTI_PINCH_OUT, eo_it));
4278 eo_do(WIDGET(it), eo_event_callback_call
4279 (ELM_GENLIST_EVENT_MULTI_PINCH_IN, eo_it));
4283 sd->multi_timeout = EINA_FALSE;
4287 _item_multi_down_cb(void *data,
4288 Evas *evas EINA_UNUSED,
4289 Evas_Object *obj EINA_UNUSED,
4292 Elm_Gen_Item *it = data;
4293 Evas_Event_Multi_Down *ev = event_info;
4294 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4296 if ((sd->multi_device != 0) || (sd->multi_touched)
4297 || (sd->multi_timeout))
4300 sd->multi_device = ev->device;
4301 sd->multi_down = EINA_TRUE;
4302 sd->multi_touched = EINA_TRUE;
4303 sd->prev_mx = ev->canvas.x;
4304 sd->prev_my = ev->canvas.y;
4305 if (!sd->wasselected) _item_unselect(it);
4306 sd->wasselected = EINA_FALSE;
4307 sd->longpressed = EINA_FALSE;
4308 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4311 it->dragging = EINA_FALSE;
4312 eo_do(WIDGET(it), eo_event_callback_call
4313 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_STOP, EO_OBJ(it)));
4315 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
4318 sd->swipe = EINA_FALSE;
4320 sd->on_hold = EINA_FALSE;
4325 _item_multi_up_cb(void *data,
4326 Evas *evas EINA_UNUSED,
4327 Evas_Object *obj EINA_UNUSED,
4330 Elm_Gen_Item *it = data;
4331 Evas_Event_Multi_Up *ev = event_info;
4332 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4334 if (sd->multi_device != ev->device) return;
4335 sd->multi_device = 0;
4336 sd->multi_down = EINA_FALSE;
4337 if (sd->mouse_down) return;
4338 _multi_touch_gesture_eval(data);
4342 _item_multi_move_cb(void *data,
4343 Evas *evas EINA_UNUSED,
4344 Evas_Object *obj EINA_UNUSED,
4347 Elm_Gen_Item *it = data;
4348 Evas_Event_Multi_Move *ev = event_info;
4349 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4351 if (sd->multi_device != ev->device) return;
4352 sd->cur_mx = ev->cur.canvas.x;
4353 sd->cur_my = ev->cur.canvas.y;
4357 _item_mouse_down_cb(void *data,
4358 Evas *evas EINA_UNUSED,
4363 Evas_Event_Mouse_Down *ev = event_info;
4364 Elm_Gen_Item *it = data;
4366 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4367 Elm_Object_Item *eo_it = EO_OBJ(it);
4369 if (ev->button == 3)
4371 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4372 it->dx = ev->canvas.x - x;
4373 it->dy = ev->canvas.y - y;
4376 if (ev->button != 1) return;
4377 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4379 sd->on_hold = EINA_TRUE;
4382 it->down = EINA_TRUE;
4383 it->dragging = EINA_FALSE;
4384 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4385 it->dx = ev->canvas.x - x;
4386 it->dy = ev->canvas.y - y;
4387 sd->mouse_down = EINA_TRUE;
4388 if (!sd->multi_touched)
4390 sd->prev_x = ev->canvas.x;
4391 sd->prev_y = ev->canvas.y;
4392 sd->multi_timeout = EINA_FALSE;
4393 ecore_timer_del(sd->multi_timer);
4394 sd->multi_timer = ecore_timer_add(MULTI_DOWN_TIME, _multi_cancel, sd->obj);
4396 sd->longpressed = EINA_FALSE;
4397 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = EINA_TRUE;
4398 else sd->on_hold = EINA_FALSE;
4399 if (sd->on_hold) return;
4400 sd->wasselected = it->selected;
4402 ecore_timer_del(it->item->swipe_timer);
4403 it->item->swipe_timer = ecore_timer_add(SWIPE_TIME, _swipe_cancel, it);
4404 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4406 it->long_timer = ecore_timer_add
4407 (sd->longpress_timeout, _long_press_cb, it);
4409 it->long_timer = NULL;
4410 sd->swipe = EINA_FALSE;
4412 it->base->still_in = EINA_TRUE;
4414 if (_is_no_select(it) ||
4415 eo_do_ret((Eo *)eo_it, tmp, elm_wdg_item_disabled_get()))
4418 // and finally call the user callbacks.
4419 // NOTE: keep this code at the bottom, as the user can change the
4420 // list at this point (clear, delete, etc...)
4421 _item_highlight(it);
4422 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
4424 eo_do(WIDGET(it), eo_event_callback_call
4425 (EVAS_CLICKABLE_INTERFACE_EVENT_CLICKED_DOUBLE, eo_it));
4426 eo_do(WIDGET(it), eo_event_callback_call
4427 (ELM_GENLIST_EVENT_ACTIVATED, eo_it));
4429 eo_do(WIDGET(it), eo_event_callback_call
4430 (EVAS_CLICKABLE_INTERFACE_EVENT_PRESSED, eo_it));
4434 _item_block_new(Elm_Genlist_Data *sd,
4439 itb = calloc(1, sizeof(Item_Block));
4440 if (!itb) return NULL;
4444 sd->blocks = eina_inlist_prepend(sd->blocks, EINA_INLIST_GET(itb));
4445 _item_block_position_update(sd->blocks, 0);
4449 sd->blocks = eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4450 itb->position_update = EINA_TRUE;
4451 if (sd->blocks != EINA_INLIST_GET(itb))
4454 ((Item_Block *)(EINA_INLIST_GET(itb)->prev))->position + 1;
4468 * This function adds an item to a block's item list. This may or may not
4469 * rearrange existing blocks and create a new block.
4473 _item_block_add(Elm_Genlist_Data *sd,
4476 Item_Block *itb = NULL;
4478 // when a new item does not depend on another item
4484 itb = calloc(1, sizeof(Item_Block));
4485 if (!itb) return EINA_FALSE;
4487 if (!it->item->rel->item->block)
4490 eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4491 itb->items = eina_list_append(itb->items, it);
4492 itb->position_update = EINA_TRUE;
4493 it->position = eina_list_count(itb->items);
4494 it->position_update = EINA_TRUE;
4496 if (sd->blocks != EINA_INLIST_GET(itb))
4500 (EINA_INLIST_GET(itb)->prev))->position + 1;
4511 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4512 if (it->item->before)
4514 sd->blocks = eina_inlist_prepend_relative
4515 (sd->blocks, EINA_INLIST_GET(itb),
4516 EINA_INLIST_GET(it->item->rel->item->block));
4518 eina_list_prepend_relative_list(itb->items, it, tmp);
4520 /* Update index from where we prepended */
4521 _item_position_update
4522 (eina_list_prev(tmp), it->item->rel->position);
4523 _item_block_position_update
4524 (EINA_INLIST_GET(itb),
4525 it->item->rel->item->block->position);
4529 sd->blocks = eina_inlist_append_relative
4530 (sd->blocks, EINA_INLIST_GET(itb),
4531 EINA_INLIST_GET(it->item->rel->item->block));
4533 eina_list_append_relative_list(itb->items, it, tmp);
4535 /* Update block index from where we appended */
4536 _item_position_update
4537 (eina_list_next(tmp), it->item->rel->position + 1);
4538 _item_block_position_update
4539 (EINA_INLIST_GET(itb),
4540 it->item->rel->item->block->position + 1);
4546 // item move_before, prepend, insert_before, sorted_insert with before
4547 if (it->item->before)
4551 itb = (Item_Block *)(sd->blocks);
4552 if (itb->count >= sd->max_items_per_block)
4554 itb = _item_block_new(sd, EINA_TRUE);
4555 if (!itb) return EINA_FALSE;
4560 itb = _item_block_new(sd, EINA_TRUE);
4561 if (!itb) return EINA_FALSE;
4563 itb->items = eina_list_prepend(itb->items, it);
4565 _item_position_update(itb->items, 0);
4567 // item move_after, append, insert_after, sorted_insert without before
4572 itb = (Item_Block *)(sd->blocks->last);
4573 if (itb->count >= sd->max_items_per_block)
4575 itb = _item_block_new(sd, EINA_FALSE);
4576 if (!itb) return EINA_FALSE;
4581 itb = _item_block_new(sd, EINA_FALSE);
4582 if (!itb) return EINA_FALSE;
4584 itb->items = eina_list_append(itb->items, it);
4585 it->position = eina_list_count(itb->items);
4589 // when a new item depends on another item
4594 if (it->item->rel->item->queued)
4596 /* NOTE: for a strange reason eina_list and eina_inlist
4597 don't have the same property on sorted insertion
4598 order, so the queue is not always ordered like the
4599 item list. This lead to issue where we depend on an
4600 item that is not yet created. As a quick work around,
4601 we reschedule the calc of the item and stop reordering
4602 the list to prevent any nasty issue to show up here.
4604 sd->queue = eina_list_append(sd->queue, it);
4605 sd->requeued = EINA_TRUE;
4606 it->item->queued = EINA_TRUE;
4610 itb = it->item->rel->item->block;
4611 if (!itb) goto newblock;
4612 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4613 if (it->item->before)
4615 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4616 _item_position_update
4617 (eina_list_prev(tmp), it->item->rel->position);
4621 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4622 _item_position_update
4623 (eina_list_next(tmp), it->item->rel->position + 1);
4628 itb->changed = EINA_TRUE;
4629 it->item->block = itb;
4630 ecore_job_del(itb->sd->calc_job);
4631 itb->sd->calc_job = ecore_job_add(_calc_job, itb->sd->obj);
4633 if (itb->count > itb->sd->max_items_per_block)
4638 Eina_Bool done = EINA_FALSE;
4640 newc = itb->count / 2;
4642 if (EINA_INLIST_GET(itb)->prev)
4644 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4646 if (itbp->count + newc < sd->max_items_per_block / 2)
4648 /* moving items to previous block */
4649 while ((itb->count > newc) && (itb->items))
4651 it2 = eina_list_data_get(itb->items);
4652 itb->items = eina_list_remove_list
4653 (itb->items, itb->items);
4656 itbp->items = eina_list_append(itbp->items, it2);
4657 it2->item->block = itbp;
4660 if (it2->realized) itbp->realized = EINA_TRUE;
4667 if (!done && EINA_INLIST_GET(itb)->next)
4669 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4671 if (itbn->count + newc < sd->max_items_per_block / 2)
4673 /* moving items to next block */
4674 while ((itb->count > newc) && (itb->items))
4678 l = eina_list_last(itb->items);
4679 it2 = eina_list_data_get(l);
4680 itb->items = eina_list_remove_list(itb->items, l);
4683 itbn->items = eina_list_prepend(itbn->items, it2);
4684 it2->item->block = itbn;
4687 if (it2->realized) itbn->realized = EINA_TRUE;
4696 /* moving items to new block */
4697 itb2 = calloc(1, sizeof(Item_Block));
4698 if (!itb2) return EINA_FALSE;
4701 eina_inlist_append_relative(sd->blocks, EINA_INLIST_GET(itb2),
4702 EINA_INLIST_GET(itb));
4703 itb2->changed = EINA_TRUE;
4704 while ((itb->count > newc) && (itb->items))
4708 l = eina_list_last(itb->items);
4710 itb->items = eina_list_remove_list(itb->items, l);
4713 itb2->items = eina_list_prepend(itb2->items, it2);
4714 it2->item->block = itb2;
4717 if (it2->realized) itb2->realized = EINA_TRUE;
4726 _item_process(Elm_Genlist_Data *sd,
4729 if (!_item_block_add(sd, it)) return EINA_FALSE;
4731 _item_block_realize(it->item->block);
4737 _item_process_post(Elm_Genlist_Data *sd,
4741 Eina_Bool show_me = EINA_FALSE;
4743 if (it->item->block->changed)
4745 show_me = _item_block_recalc
4746 (it->item->block, it->item->block->num, qadd);
4747 it->item->block->changed = 0;
4748 if (sd->pan_changed)
4750 evas_object_smart_changed(sd->pan_obj);
4751 ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
4754 if (show_me) it->item->block->show_me = EINA_TRUE;
4756 /* when prepending, move the scroller along with the first selected
4757 * item to create the illusion that we're watching the selected
4758 * item this prevents the selected item being scrolled off the
4761 if (sd->selected && it->item->before)
4764 Elm_Object_Item *eo_it2;
4766 eo_it2 = sd->selected->data;
4767 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
4768 if (!it2->item->block) return;
4770 //FIXME: There are issue about wrong list positioning in prepend cases.
4771 // To prevent the issue, allocate repositioning in smart calculate.
4772 sd->prepend_items = eina_list_append(sd->prepend_items, it);
4774 eo_do(sd->obj, elm_interface_scrollable_content_pos_get(NULL, &y));
4775 evas_object_geometry_get(sd->pan_obj, NULL, NULL, NULL, &h);
4776 if ((it->y + it->item->block->y > y + h) ||
4777 (it->y + it->item->block->y + it->item->h < y))
4778 /* offscreen, just update */
4779 eo_do(sd->obj, elm_interface_scrollable_content_region_show
4780 (it2->x + it2->item->block->x, y,
4781 it2->item->block->w, h));
4783 eo_do(sd->obj, elm_interface_scrollable_content_region_show
4784 (it->x + it->item->block->x,
4785 y + it->item->h, it->item->block->w, h));
4791 _queue_process(Elm_Genlist_Data *sd)
4796 t0 = ecore_time_get();
4797 for (n = 0; (sd->queue) && (n < 128); n++)
4801 it = eina_list_data_get(sd->queue);
4802 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
4803 it->item->queued = EINA_FALSE;
4804 if (!_item_process(sd, it)) continue;
4805 t = ecore_time_get();
4806 _item_process_post(sd, it, EINA_TRUE);
4807 /* same as eina_inlist_count > 1 */
4808 if (sd->blocks && sd->blocks->next)
4810 if ((t - t0) > (ecore_animator_frametime_get())) break;
4818 _idle_process(void *data,
4821 Elm_Genlist_Data *sd = data;
4823 if (_queue_process(sd) > 0) *wakeup = EINA_TRUE;
4826 return ECORE_CALLBACK_CANCEL;
4828 return ECORE_CALLBACK_RENEW;
4832 _item_idle_enterer(void *data)
4834 Eina_Bool wakeup = EINA_FALSE;
4835 ELM_GENLIST_DATA_GET(data, sd);
4836 Eina_Bool ok = _idle_process(sd, &wakeup);
4841 ecore_job_del(sd->calc_job);
4842 sd->calc_job = ecore_job_add(_calc_job, data);
4844 if (ok == ECORE_CALLBACK_CANCEL) sd->queue_idle_enterer = NULL;
4850 _requeue_idle_enterer(Elm_Genlist_Data *sd)
4852 ecore_idle_enterer_del(sd->queue_idle_enterer);
4853 sd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, sd->obj);
4857 _item_queue(Elm_Genlist_Data *sd,
4863 if (it->item->queued) return;
4864 it->item->queued = EINA_TRUE;
4865 if (cb && !sd->requeued)
4866 sd->queue = eina_list_sorted_insert(sd->queue, cb, it);
4868 sd->queue = eina_list_append(sd->queue, it);
4869 // FIXME: why does a freeze then thaw here cause some genlist
4870 // elm_genlist_item_append() to be much much slower?
4871 // evas_event_freeze(evas_object_evas_get(sd->obj));
4872 while ((sd->queue) && ((!sd->blocks) || (!sd->blocks->next)))
4874 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
4877 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
4878 while ((sd->queue) && (sd->blocks) &&
4879 ((sd->homogeneous) || it->itc->homogeneous) && (sd->mode == ELM_LIST_COMPRESS))
4881 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
4885 // evas_event_thaw(evas_object_evas_get(sd->obj));
4886 // evas_event_thaw_eval(evas_object_evas_get(sd->obj));
4887 evas_object_geometry_get(sd->obj, NULL, NULL, &w, NULL);
4888 if (w > 0) _requeue_idle_enterer(sd);
4892 /* If the application wants to know the relative item, use
4893 * elm_genlist_item_prev_get(it)*/
4895 _item_move_after(Elm_Gen_Item *it,
4896 Elm_Gen_Item *after)
4900 if (it == after) return;
4901 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4904 eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
4905 if (it->item->block) _item_block_del(it);
4907 sd->items = eina_inlist_append_relative
4908 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4910 it->item->rel->item->rel_revs =
4911 eina_list_remove(it->item->rel->item->rel_revs, it);
4912 it->item->rel = after;
4913 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
4914 it->item->before = EINA_FALSE;
4915 if (after->item->group_item) it->item->group_item = after->item->group_item;
4916 _item_queue(sd, it, NULL);
4918 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_MOVED_AFTER, EO_OBJ(it)));
4922 _access_activate_cb(void *data EINA_UNUSED,
4923 Evas_Object *part_obj EINA_UNUSED,
4924 Elm_Object_Item *eo_it)
4926 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
4929 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4936 _item_highlight(it);
4946 while (sd->selected)
4948 Elm_Object_Item *eo_sel = sd->selected->data;
4949 Elm_Gen_Item *sel = eo_data_scope_get(eo_sel, ELM_GENLIST_ITEM_CLASS);
4950 _item_unselect(sel);
4955 const Eina_List *l, *l_next;
4956 Elm_Object_Item *eo_it2;
4958 EINA_LIST_FOREACH_SAFE(sd->selected, l, l_next, eo_it2)
4960 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
4962 _item_unselect(it2);
4965 _item_highlight(it);
4970 /* If the application wants to know the relative item, use
4971 * elm_genlist_item_next_get(it)*/
4973 _item_move_before(Elm_Gen_Item *it,
4974 Elm_Gen_Item *before)
4977 if (!before) return;
4978 if (it == before) return;
4979 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4982 eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
4983 if (it->item->block) _item_block_del(it);
4984 sd->items = eina_inlist_prepend_relative
4985 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
4987 it->item->rel->item->rel_revs =
4988 eina_list_remove(it->item->rel->item->rel_revs, it);
4989 it->item->rel = before;
4990 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
4991 it->item->before = EINA_TRUE;
4992 if (before->item->group_item)
4993 it->item->group_item = before->item->group_item;
4994 _item_queue(sd, it, NULL);
4996 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_MOVED_BEFORE, EO_OBJ(it)));
5000 _item_mouse_up_cb(void *data,
5001 Evas *evas EINA_UNUSED,
5002 Evas_Object *obj EINA_UNUSED,
5006 Evas_Event_Mouse_Up *ev = event_info;
5007 Eina_Bool dragged = EINA_FALSE;
5008 Elm_Gen_Item *it = data;
5009 Evas_Coord x, y, dx, dy;
5011 if ((ev->button == 3) && (!it->dragging))
5013 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
5014 dx = it->dx - (ev->canvas.x - x);
5015 dy = it->dy - (ev->canvas.y - y);
5016 if (dx < 0) dx = -dx;
5017 if (dy < 0) dy = -dy;
5018 if ((dx < 5) && (dy < 5))
5019 eo_do(WIDGET(it), eo_event_callback_call
5020 (EVAS_CLICKABLE_INTERFACE_EVENT_CLICKED_RIGHT, EO_OBJ(it)));
5024 if (ev->button != 1) return;
5025 it->down = EINA_FALSE;
5026 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5028 sd->mouse_down = EINA_FALSE;
5029 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_RELEASED, EO_OBJ(it)));
5030 if (sd->multi_touched)
5032 if ((!sd->multi) && (!it->selected) && (it->highlighted))
5033 _item_unhighlight(it);
5034 if (sd->multi_down) return;
5035 _multi_touch_gesture_eval(it);
5038 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
5039 sd->on_hold = EINA_TRUE;
5040 else sd->on_hold = EINA_FALSE;
5041 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
5044 it->dragging = EINA_FALSE;
5045 eo_do(WIDGET(it), eo_event_callback_call
5046 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_STOP, EO_OBJ(it)));
5049 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
5050 if (sd->multi_timer)
5052 ELM_SAFE_FREE(sd->multi_timer, ecore_timer_del);
5053 sd->multi_timeout = EINA_FALSE;
5057 if (!sd->wasselected) _item_unselect(it);
5059 sd->longpressed = EINA_FALSE;
5060 sd->on_hold = EINA_FALSE;
5061 sd->wasselected = EINA_FALSE;
5064 if ((sd->reorder_mode) && (sd->reorder_it))
5066 Evas_Coord it_scrl_y = ev->canvas.y - sd->reorder_it->dy;
5067 sd->reorder_fast = 0;
5069 if (sd->reorder_rel &&
5070 (sd->reorder_it->parent == sd->reorder_rel->parent))
5072 if (it_scrl_y <= sd->reorder_rel->item->scrl_y)
5073 _item_move_before(sd->reorder_it, sd->reorder_rel);
5075 _item_move_after(sd->reorder_it, sd->reorder_rel);
5076 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_MOVED, EO_OBJ(it)));
5080 ecore_job_del(sd->calc_job);
5081 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
5083 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_DISABLED, "elm");
5084 //TIZEN_ONLY(20160520): genlist: added atspi support for drag n drop
5085 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_ANIMATED, EINA_FALSE);
5087 sd->reorder_it = sd->reorder_rel = NULL;
5088 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5089 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
5090 (sd->h_bounce, sd->v_bounce));
5092 if (sd->longpressed)
5094 if (!sd->wasselected) _item_unselect(it);
5095 sd->longpressed = EINA_FALSE;
5096 sd->wasselected = EINA_FALSE;
5101 if (it->want_unrealize)
5103 _elm_genlist_item_unrealize(it, EINA_FALSE);
5104 if (it->item->block->want_unrealize)
5105 _item_block_unrealize(it->item->block);
5109 if (_is_no_select(it) ||
5110 (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get())))
5113 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD || !it->base->still_in) return;
5115 evas_object_ref(sd->obj);
5117 if (sd->focused_item != EO_OBJ(it))
5118 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
5121 ((sd->multi_select_mode != ELM_OBJECT_MULTI_SELECT_MODE_WITH_CONTROL) ||
5122 (evas_key_modifier_is_set(ev->modifiers, "Control"))))
5126 _item_highlight(it);
5127 if (_item_select(it)) goto deleted;
5136 while (sd->selected)
5138 Elm_Object_Item *eo_sel = sd->selected->data;
5139 Elm_Gen_Item *sel = eo_data_scope_get(eo_sel, ELM_GENLIST_ITEM_CLASS);
5140 _item_unselect(sel);
5145 const Eina_List *l, *l_next;
5146 Elm_Object_Item *eo_it2;
5148 EINA_LIST_FOREACH_SAFE(sd->selected, l, l_next, eo_it2)
5150 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
5152 _item_unselect(it2);
5155 _item_highlight(it);
5156 if (_item_select(it)) goto deleted;
5160 evas_object_unref(sd->obj);
5164 _item_mouse_callbacks_add(Elm_Gen_Item *it,
5167 evas_object_event_callback_add
5168 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
5169 evas_object_event_callback_add
5170 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
5171 evas_object_event_callback_add
5172 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
5173 evas_object_event_callback_add
5174 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
5175 evas_object_event_callback_add
5176 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
5177 evas_object_event_callback_add
5178 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
5179 evas_object_event_callback_add
5180 (view, EVAS_CALLBACK_MOUSE_IN, _item_mouse_in_cb, it);
5184 _item_mouse_callbacks_del(Elm_Gen_Item *it,
5187 evas_object_event_callback_del_full
5188 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
5189 evas_object_event_callback_del_full
5190 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
5191 evas_object_event_callback_del_full
5192 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
5193 evas_object_event_callback_del_full
5194 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
5195 evas_object_event_callback_del_full
5196 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
5197 evas_object_event_callback_del_full
5198 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
5199 evas_object_event_callback_del_full
5200 (view, EVAS_CALLBACK_MOUSE_IN, _item_mouse_in_cb, it);
5204 _scroll_hold_timer_cb(void *data)
5206 ELM_GENLIST_DATA_GET(data, sd);
5208 if (!data) return ECORE_CALLBACK_CANCEL;
5210 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5211 sd->scr_hold_timer = NULL;
5213 return ECORE_CALLBACK_CANCEL;
5217 _decorate_item_unrealize(Elm_Gen_Item *it)
5219 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5220 Evas_Object *obj = sd->obj;
5222 if (!it->item->deco_it_view) return;
5224 evas_event_freeze(evas_object_evas_get(obj));
5226 _view_clear(GL_IT(it)->deco_it_view, &(GL_IT(it)->deco_it_texts),
5227 &(GL_IT(it)->deco_it_contents));
5229 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
5230 evas_object_smart_member_add(VIEW(it), sd->pan_obj);
5231 ELM_SAFE_FREE(it->item->deco_it_view, evas_object_del);
5233 if (sd->mode_item == it)
5234 sd->mode_item = NULL;
5235 evas_event_thaw(evas_object_evas_get(obj));
5236 evas_event_thaw_eval(evas_object_evas_get(obj));
5240 _decorate_item_finished_signal_cb(void *data,
5242 const char *emission EINA_UNUSED,
5243 const char *source EINA_UNUSED)
5245 Elm_Gen_Item *it = data;
5249 if (!it || !obj) return;
5250 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5252 te = evas_object_evas_get(obj);
5254 if ((!it->realized) || (!it->item->deco_it_view)) return;
5256 evas_event_freeze(te);
5257 it->item->nocache_once = EINA_FALSE;
5258 _decorate_item_unrealize(it);
5259 if (it->item->group_item)
5260 evas_object_stack_above(it->item->VIEW(group_item), sd->stack[1]);
5262 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished",
5263 sd->decorate_it_type);
5264 edje_object_signal_callback_del_full
5265 (obj, buf, "elm", _decorate_item_finished_signal_cb, it);
5266 evas_event_thaw(te);
5267 evas_event_thaw_eval(te);
5271 _item_unrealize(Elm_Gen_Item *it)
5274 Eina_List *cache = NULL;
5275 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5277 EINA_LIST_FREE(it->item->flip_contents, c)
5281 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
5282 _elm_access_widget_item_unregister(it->base);
5284 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
5285 if (_elm_config->atspi_mode)
5287 elm_interface_atspi_accessible_removed(EO_OBJ(it));
5288 elm_interface_atspi_accessible_children_changed_del_signal_emit(sd->obj, EO_OBJ(it));
5292 // unswallow VIEW(it) first then manipulate VIEW(it)
5293 _decorate_item_unrealize(it);
5294 if (GL_IT(it)->wsd->decorate_all_mode) _decorate_all_item_unrealize(it);
5296 if (!_item_cache_add(it, _content_cache_add(it, &cache)))
5298 ELM_SAFE_FREE(VIEW(it), evas_object_del);
5299 ELM_SAFE_FREE(it->spacer, evas_object_del);
5300 EINA_LIST_FREE(cache, c)
5307 it->realized = EINA_FALSE;
5308 it->want_unrealize = EINA_FALSE;
5312 _item_block_recalc(Item_Block *itb,
5318 Evas_Coord minw = 0, minh = 0;
5319 Eina_Bool show_me = EINA_FALSE, changed = EINA_FALSE;
5321 Item_Size *size = NULL;
5324 EINA_LIST_FOREACH(itb->items, l, it)
5326 show_me |= it->item->show_me;
5328 if (!it->filtered) _item_filtered_get(it);
5329 if (it->want_hidden)
5331 if (it->realized) evas_object_hide(VIEW(it));
5336 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5337 if ((itb->sd->homogeneous || it->itc->homogeneous) &&
5338 ((!size) || it->itc != size->itc))
5339 size = eina_hash_find(itb->sd->size_caches, &(it->itc));
5340 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5341 if (qadd || ((itb->sd->homogeneous || it->itc->homogeneous) && !size))
5343 if (!it->item->mincalcd) changed = EINA_TRUE;
5348 _item_realize(it, in, EINA_TRUE);
5349 _elm_genlist_item_unrealize(it, EINA_TRUE);
5353 it->item->w = it->item->minw = size->minw;
5354 it->item->h = it->item->minh = size->minh;
5355 it->item->mincalcd = EINA_TRUE;
5361 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5362 if ((itb->sd->homogeneous || it->itc->homogeneous) && size &&
5363 (itb->sd->mode == ELM_LIST_COMPRESS))
5365 it->item->w = it->item->minw = size->minw;
5366 it->item->h = it->item->minh = size->minh;
5367 it->item->mincalcd = EINA_TRUE;
5371 _item_realize(it, in, EINA_TRUE);
5372 _elm_genlist_item_unrealize(it, EINA_TRUE);
5378 if (!it->item->mincalcd) changed = EINA_TRUE;
5379 _item_realize(it, in, EINA_FALSE);
5381 minh += it->item->minh;
5382 if (minw < it->item->minw) minw = it->item->minw;
5388 if (changed) itb->sd->pan_changed = changed;
5391 itb->changed = EINA_FALSE;
5392 itb->position_update = EINA_FALSE;
5398 _update_job(void *data)
5400 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
5401 ELM_GENLIST_DATA_GET(data, sd);
5406 sd->update_job = NULL;
5409 evas_event_freeze(evas_object_evas_get(sd->obj));
5410 EINA_INLIST_FOREACH(sd->blocks, itb)
5412 Evas_Coord itminw, itminh;
5419 _item_block_position(itb, num);
5423 recalc = EINA_FALSE;
5424 EINA_LIST_FOREACH(itb->items, l2, it)
5426 if (it->item->updateme)
5428 itminw = it->item->minw;
5429 itminh = it->item->minh;
5431 it->item->updateme = EINA_FALSE;
5434 _elm_genlist_item_unrealize(it, EINA_FALSE);
5435 _item_realize(it, num, EINA_FALSE);
5436 position = EINA_TRUE;
5440 _item_realize(it, num, EINA_TRUE);
5441 _elm_genlist_item_unrealize(it, EINA_TRUE);
5443 if ((it->item->minw != itminw) || (it->item->minh != itminh))
5448 itb->updateme = EINA_FALSE;
5451 position = EINA_TRUE;
5452 itb->changed = EINA_TRUE;
5453 _item_block_recalc(itb, num0, EINA_FALSE);
5454 _item_block_position(itb, num0);
5459 ecore_job_del(sd->calc_job);
5460 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
5462 evas_event_thaw(evas_object_evas_get(sd->obj));
5463 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
5467 _scroll_animate_start_cb(Evas_Object *obj,
5468 void *data EINA_UNUSED)
5470 eo_do(obj, eo_event_callback_call(EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL_ANIM_START, NULL));
5474 _scroll_animate_stop_cb(Evas_Object *obj,
5475 void *data EINA_UNUSED)
5477 eo_do(obj, eo_event_callback_call(EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL_ANIM_STOP, NULL));
5481 _scroll_drag_start_cb(Evas_Object *obj,
5482 void *data EINA_UNUSED)
5484 eo_do(obj, eo_event_callback_call(EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL_DRAG_START, NULL));
5488 _scroll_cb(Evas_Object *obj,
5489 void *data EINA_UNUSED)
5491 eo_do(obj, eo_event_callback_call(EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL, NULL));
5495 _scroll_drag_stop_cb(Evas_Object *obj,
5496 void *data EINA_UNUSED)
5498 eo_do(obj, eo_event_callback_call(EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL_DRAG_STOP, NULL));
5502 _edge_left_cb(Evas_Object *obj,
5503 void *data EINA_UNUSED)
5505 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_EDGE_LEFT, NULL));
5509 _edge_right_cb(Evas_Object *obj,
5510 void *data EINA_UNUSED)
5512 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_EDGE_RIGHT, NULL));
5516 _edge_top_cb(Evas_Object *obj,
5517 void *data EINA_UNUSED)
5519 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_EDGE_TOP, NULL));
5523 _edge_bottom_cb(Evas_Object *obj,
5524 void *data EINA_UNUSED)
5526 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_EDGE_BOTTOM, NULL));
5530 _vbar_drag_cb(Evas_Object *obj,
5531 void *data EINA_UNUSED)
5533 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_VBAR_DRAG, NULL));
5537 _vbar_press_cb(Evas_Object *obj,
5538 void *data EINA_UNUSED)
5540 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_VBAR_PRESS, NULL));
5544 _vbar_unpress_cb(Evas_Object *obj,
5545 void *data EINA_UNUSED)
5547 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_VBAR_UNPRESS, NULL));
5551 _hbar_drag_cb(Evas_Object *obj,
5552 void *data EINA_UNUSED)
5554 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_HBAR_DRAG, NULL));
5558 _hbar_press_cb(Evas_Object *obj,
5559 void *data EINA_UNUSED)
5561 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_HBAR_PRESS, NULL));
5565 _hbar_unpress_cb(Evas_Object *obj,
5566 void *data EINA_UNUSED)
5568 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_HBAR_UNPRESS, NULL));
5572 _decorate_item_realize(Elm_Gen_Item *it)
5574 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5575 Evas_Object *obj = sd->obj;
5578 if (GL_IT(it)->deco_it_view) return;
5580 evas_event_freeze(evas_object_evas_get(obj));
5581 it->item->deco_it_view = _view_create(it, it->itc->decorate_item_style);
5583 /* signal callback add */
5584 evas_object_event_callback_add
5585 (GL_IT(it)->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb,
5587 evas_object_event_callback_add
5588 (GL_IT(it)->deco_it_view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
5589 evas_object_event_callback_add
5590 (GL_IT(it)->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb,
5593 _view_inflate(it->item->deco_it_view, it, &GL_IT(it)->deco_it_texts,
5594 &GL_IT(it)->deco_it_contents);
5595 edje_object_part_swallow
5596 (it->item->deco_it_view,
5597 edje_object_data_get(it->item->deco_it_view, "mode_part"), VIEW(it));
5599 snprintf(buf, sizeof(buf), "elm,state,%s,active", sd->decorate_it_type);
5600 edje_object_signal_emit(GL_IT(it)->deco_it_view, buf, "elm");
5601 edje_object_signal_emit(VIEW(it), buf, "elm");
5603 it->want_unrealize = EINA_FALSE;
5604 evas_event_thaw(evas_object_evas_get(obj));
5605 evas_event_thaw_eval(evas_object_evas_get(obj));
5609 _decorate_item_set(Elm_Gen_Item *it)
5613 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5616 it->item->nocache_once = EINA_TRUE;
5618 ELM_SAFE_FREE(sd->scr_hold_timer, ecore_timer_del);
5619 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
5620 sd->scr_hold_timer = ecore_timer_add(SCR_HOLD_TIME, _scroll_hold_timer_cb, sd->obj);
5622 evas_event_freeze(evas_object_evas_get(sd->obj));
5623 _decorate_item_realize(it);
5624 if (it->item->group_item)
5625 evas_object_stack_above(it->item->VIEW(group_item), sd->stack[1]);
5627 (it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
5628 evas_event_thaw(evas_object_evas_get(sd->obj));
5629 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
5634 _decorate_item_unset(Elm_Genlist_Data *sd)
5636 char buf[1024], buf2[1024];
5639 if (!sd->mode_item) return;
5642 it->item->nocache_once = EINA_TRUE;
5644 snprintf(buf, sizeof(buf), "elm,state,%s,passive", sd->decorate_it_type);
5645 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished",
5646 sd->decorate_it_type);
5647 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
5648 edje_object_signal_callback_add
5649 (it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb,
5651 sd->mode_item = NULL;
5655 _elm_genlist_looping_up_cb(void *data,
5656 Evas_Object *obj EINA_UNUSED,
5657 const char *emission EINA_UNUSED,
5658 const char *source EINA_UNUSED)
5660 Evas_Object *genlist = data;
5662 ELM_GENLIST_DATA_GET(genlist, sd);
5664 Elm_Object_Item *eo_it = elm_genlist_last_item_get(genlist);
5666 // TIZEN_ONLY(20150629): add checking item bring in enable on item looping
5667 switch (_elm_config->focus_autoscroll_mode)
5669 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
5670 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
5672 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
5673 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
5679 elm_layout_signal_emit(genlist, "elm,action,looping,up,end", "elm");
5680 sd->item_looping_on = EINA_FALSE;
5682 if (!_elm_config->item_select_on_focus_disable)
5683 elm_genlist_item_selected_set(eo_it, EINA_TRUE);
5685 elm_object_item_focus_set(eo_it, EINA_TRUE);
5689 _elm_genlist_looping_down_cb(void *data,
5690 Evas_Object *obj EINA_UNUSED,
5691 const char *emission EINA_UNUSED,
5692 const char *source EINA_UNUSED)
5694 Evas_Object *genlist = data;
5696 ELM_GENLIST_DATA_GET(genlist, sd);
5698 Elm_Object_Item *eo_it = elm_genlist_first_item_get(genlist);
5700 // TIZEN_ONLY(20150629): add checking item bring in enable on item looping
5701 switch (_elm_config->focus_autoscroll_mode)
5703 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
5704 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
5706 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
5707 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
5713 elm_layout_signal_emit(genlist, "elm,action,looping,down,end", "elm");
5714 sd->item_looping_on = EINA_FALSE;
5716 if (!_elm_config->item_select_on_focus_disable)
5717 elm_genlist_item_selected_set(eo_it, EINA_TRUE);
5719 elm_object_item_focus_set(eo_it, EINA_TRUE);
5723 _evas_viewport_resize_cb(void *d, Evas *e EINA_UNUSED, void *ei EINA_UNUSED)
5725 Elm_Genlist_Data *priv = d;
5726 evas_object_smart_changed(priv->pan_obj);
5730 _elm_genlist_evas_object_smart_add(Eo *obj, Elm_Genlist_Data *priv)
5732 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5733 Elm_Genlist_Pan_Data *pan_data;
5734 Evas_Coord minw, minh;
5737 eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
5738 elm_widget_sub_object_parent_add(obj);
5740 priv->size_caches = eina_hash_pointer_new(_size_cache_free);
5741 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
5742 evas_object_smart_member_add(priv->hit_rect, obj);
5743 elm_widget_sub_object_add(obj, priv->hit_rect);
5745 /* common scroller hit rectangle setup */
5746 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
5747 evas_object_show(priv->hit_rect);
5748 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
5750 elm_widget_can_focus_set(obj, EINA_TRUE);
5751 elm_widget_on_show_region_hook_set(obj, _show_region_hook, NULL);
5753 if (!elm_layout_theme_set
5754 (obj, "genlist", "base", elm_widget_style_get(obj)))
5755 CRI("Failed to set layout!");
5757 eo_do(obj, elm_interface_scrollable_objects_set(wd->resize_obj, priv->hit_rect));
5759 eo_do(obj, elm_interface_scrollable_bounce_allow_set
5760 (EINA_FALSE, _elm_config->thumbscroll_bounce_enable));
5761 priv->v_bounce = _elm_config->thumbscroll_bounce_enable;
5764 elm_interface_scrollable_animate_start_cb_set(_scroll_animate_start_cb),
5765 elm_interface_scrollable_animate_stop_cb_set(_scroll_animate_stop_cb),
5766 elm_interface_scrollable_scroll_cb_set(_scroll_cb),
5767 elm_interface_scrollable_drag_start_cb_set(_scroll_drag_start_cb),
5768 elm_interface_scrollable_drag_stop_cb_set(_scroll_drag_stop_cb),
5769 elm_interface_scrollable_edge_left_cb_set(_edge_left_cb),
5770 elm_interface_scrollable_edge_right_cb_set(_edge_right_cb),
5771 elm_interface_scrollable_edge_top_cb_set(_edge_top_cb),
5772 elm_interface_scrollable_edge_bottom_cb_set(_edge_bottom_cb),
5773 elm_interface_scrollable_vbar_drag_cb_set(_vbar_drag_cb),
5774 elm_interface_scrollable_vbar_press_cb_set(_vbar_press_cb),
5775 elm_interface_scrollable_vbar_unpress_cb_set(_vbar_unpress_cb),
5776 elm_interface_scrollable_hbar_drag_cb_set(_hbar_drag_cb),
5777 elm_interface_scrollable_hbar_press_cb_set(_hbar_press_cb),
5778 elm_interface_scrollable_hbar_unpress_cb_set(_hbar_unpress_cb),
5779 elm_interface_scrollable_content_min_limit_cb_set(_content_min_limit_cb));
5781 priv->mode = ELM_LIST_SCROLL;
5782 priv->max_items_per_block = MAX_ITEMS_PER_BLOCK;
5783 priv->item_cache_max = priv->max_items_per_block * 2;
5784 priv->longpress_timeout = _elm_config->longpress_timeout;
5785 priv->highlight = EINA_TRUE;
5787 priv->pan_obj = eo_add(MY_PAN_CLASS, evas_object_evas_get(obj));
5788 pan_data = eo_data_scope_get(priv->pan_obj, MY_PAN_CLASS);
5789 eo_data_ref(obj, NULL);
5790 pan_data->wobj = obj;
5791 pan_data->wsd = priv;
5793 for (i = 0; i < 2; i++)
5795 priv->stack[i] = evas_object_rectangle_add(evas_object_evas_get(obj));
5796 evas_object_smart_member_add(priv->stack[i], priv->pan_obj);
5799 eo_do(obj, elm_interface_scrollable_extern_pan_set(priv->pan_obj));
5801 edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
5802 evas_object_size_hint_min_set(obj, minw, minh);
5804 _mirrored_set(obj, elm_widget_mirrored_get(obj));
5806 elm_layout_sizing_eval(obj);
5808 edje_object_signal_callback_add(wd->resize_obj, "elm,looping,up,done", "elm", _elm_genlist_looping_up_cb, obj);
5809 edje_object_signal_callback_add(wd->resize_obj, "elm,looping,down,done", "elm", _elm_genlist_looping_down_cb, obj);
5810 evas_event_callback_add(evas_object_evas_get(obj),
5811 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
5812 _evas_viewport_resize_cb, priv);
5816 _elm_genlist_evas_object_smart_del(Eo *obj, Elm_Genlist_Data *sd)
5820 elm_genlist_clear(obj);
5821 for (i = 0; i < 2; i++)
5822 ELM_SAFE_FREE(sd->stack[i], evas_object_del);
5824 evas_event_callback_del_full(evas_object_evas_get(obj),
5825 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
5826 _evas_viewport_resize_cb, sd);
5827 ELM_SAFE_FREE(sd->pan_obj, evas_object_del);
5829 _item_cache_zero(sd);
5830 ecore_job_del(sd->calc_job);
5831 ecore_job_del(sd->update_job);
5832 ecore_idle_enterer_del(sd->queue_idle_enterer);
5833 ecore_idler_del(sd->must_recalc_idler);
5834 ecore_timer_del(sd->multi_timer);
5835 eina_stringshare_del(sd->decorate_it_type);
5836 ecore_animator_del(sd->tree_effect_animator);
5838 eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
5842 _elm_genlist_evas_object_smart_move(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y)
5844 eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
5846 evas_object_move(sd->hit_rect, x, y);
5850 _elm_genlist_evas_object_smart_resize(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord w, Evas_Coord h)
5852 eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
5854 evas_object_resize(sd->hit_rect, w, h);
5855 if ((sd->queue) && (!sd->queue_idle_enterer) && (w > 0))
5856 _requeue_idle_enterer(sd);
5860 _elm_genlist_evas_object_smart_member_add(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *member)
5862 eo_do_super(obj, MY_CLASS, evas_obj_smart_member_add(member));
5865 evas_object_raise(sd->hit_rect);
5869 _access_obj_process(Elm_Genlist_Data *sd, Eina_Bool is_access)
5872 Eina_Bool done = EINA_FALSE;
5874 EINA_INLIST_FOREACH(sd->blocks, itb)
5882 EINA_LIST_FOREACH(itb->items, l, it)
5884 if (!it->realized || it->want_hidden) continue;
5885 if (is_access) _access_widget_item_register(it);
5887 _elm_access_widget_item_unregister(it->base);
5890 else if (done) break;
5895 _elm_genlist_elm_widget_access(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool acs)
5897 _elm_genlist_smart_focus_next_enable = acs;
5898 _access_obj_process(sd, _elm_genlist_smart_focus_next_enable);
5901 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
5902 //register/unregister access objects accordingly.
5904 _elm_genlist_elm_widget_atspi(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool is_atspi)
5907 Eina_Bool done = EINA_FALSE;
5908 Evas_Object *content = NULL;
5911 EINA_INLIST_FOREACH(sd->blocks, itb)
5919 EINA_LIST_FOREACH(itb->items, l, it)
5921 if (!it->realized || it->want_hidden) continue;
5924 elm_interface_atspi_accessible_added(EO_OBJ(it));
5925 elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
5926 EINA_LIST_FOREACH(it->contents, l, content)
5928 if (eo_isa(content, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
5930 eo_do(content, elm_interface_atspi_accessible_parent_set(EO_OBJ(it)));
5931 elm_interface_atspi_accessible_children_changed_added_signal_emit(EO_OBJ(it), content);
5934 elm_interface_atspi_accessible_name_changed_signal_emit(EO_OBJ(it));
5938 elm_interface_atspi_accessible_removed(EO_OBJ(it));
5939 elm_interface_atspi_accessible_children_changed_del_signal_emit(sd->obj, EO_OBJ(it));
5943 else if (done) break;
5945 //TIZEN_ONLY(20161213): apply screen_reader_changed callback
5946 evas_object_smart_callback_call(obj, SIG_ATSPI_SCREEN_READER_CHANGED, &is_atspi);
5952 elm_genlist_add(Evas_Object *parent)
5954 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
5955 Evas_Object *obj = eo_add(MY_CLASS, parent);
5960 _elm_genlist_eo_base_constructor(Eo *obj, Elm_Genlist_Data *sd)
5962 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
5966 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
5967 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
5968 elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST));
5974 _internal_elm_genlist_clear(Evas_Object *obj)
5976 ELM_GENLIST_DATA_GET(obj, sd);
5979 _elm_genlist_item_unfocused(sd->focused_item);
5980 if (sd->mode_item) sd->mode_item = NULL;
5982 ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
5984 sd->filter_data = NULL;
5985 if (sd->filter_queue)
5986 ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
5987 ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
5988 ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
5990 evas_event_freeze(evas_object_evas_get(sd->obj));
5992 // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
5993 // because sd->items can be modified inside elm_widget_item_del()
5996 it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
5997 eo_do(EO_OBJ(it), elm_wdg_item_del());
6000 sd->pan_changed = EINA_TRUE;
6003 ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
6004 sd->anchor_item = NULL;
6005 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
6006 ELM_SAFE_FREE(sd->must_recalc_idler, ecore_idler_del);
6007 ELM_SAFE_FREE(sd->reorder_move_animator, ecore_animator_del);
6008 sd->reorder_old_pan_y = 0;
6011 if (sd->selected) ELM_SAFE_FREE(sd->selected, eina_list_free);
6013 sd->show_item = NULL;
6022 evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
6023 eo_do(sd->pan_obj, eo_event_callback_call
6024 (ELM_PAN_EVENT_CHANGED, NULL));
6026 elm_layout_sizing_eval(sd->obj);
6027 eo_do(obj, elm_interface_scrollable_content_region_show(0, 0, 0, 0));
6029 ELM_SAFE_FREE(sd->multi_timer, ecore_timer_del);
6030 ELM_SAFE_FREE(sd->update_job, ecore_job_del);
6031 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
6032 ELM_SAFE_FREE(sd->must_recalc_idler, ecore_idler_del);
6033 ELM_SAFE_FREE(sd->tree_effect_animator, ecore_animator_del);
6034 ELM_SAFE_FREE(sd->event_block_rect, evas_object_del);
6035 ELM_SAFE_FREE(sd->scr_hold_timer, ecore_timer_del);
6036 ELM_SAFE_FREE(sd->queue, eina_list_free);
6038 evas_event_thaw(evas_object_evas_get(sd->obj));
6039 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
6042 /* Return EINA_TRUE if the item is deleted in this function */
6044 _item_select(Elm_Gen_Item *it)
6047 Evas_Object *obj = WIDGET(it);
6048 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
6049 Elm_Object_Item *eo_it = EO_OBJ(it);
6051 if (eo_do_ret(eo_it, tmp, elm_wdg_item_disabled_get())) return EINA_FALSE;
6052 if (_is_no_select(it) || (it->decorate_it_set)) return EINA_FALSE;
6053 if ((sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) &&
6054 (it->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) && it->selected)
6059 const Eina_List *l, *ll;
6060 Elm_Object_Item *eo_it2;
6061 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it2)
6063 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6064 if (it2 != it) _item_unselect(it2);
6070 it->selected = EINA_TRUE;
6072 eina_list_append(sd->selected, eo_it);
6075 evas_object_ref(obj);
6078 elm_object_item_focus_set(eo_it, EINA_TRUE);
6079 if ((it->base)->on_deletion) goto item_deleted;
6080 _elm_genlist_item_content_focus_set(it, ELM_FOCUS_PREVIOUS);
6081 sd->last_selected_item = eo_it;
6082 _item_highlight(it);
6084 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), eo_it);
6085 // delete item if it's requested deletion in the above callbacks.
6086 if ((it->base)->on_deletion) goto item_deleted;
6087 eo_do(WIDGET(it), eo_event_callback_call(EVAS_SELECTABLE_INTERFACE_EVENT_SELECTED, eo_it));
6088 if (_elm_config->atspi_mode)
6089 elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_SELECTED, EINA_TRUE);
6090 // delete item if it's requested deletion in the above callbacks.
6091 if ((it->base)->on_deletion) goto item_deleted;
6094 if (!(sd->focus_on_selection_enabled || _elm_config->item_select_on_focus_disable))
6096 Evas_Object *swallow_obj;
6098 EINA_LIST_FOREACH(it->contents, l, swallow_obj)
6100 if (elm_widget_is(swallow_obj) && elm_object_focus_get(swallow_obj))
6102 elm_object_focus_set(obj, EINA_FALSE);
6103 elm_object_focus_set(obj, EINA_TRUE);
6109 evas_object_unref(obj);
6113 it->walking = -1; //This item was removed from it's item list.
6116 evas_object_unref(obj);
6120 EOLIAN static Evas_Object *
6121 _elm_genlist_item_elm_widget_item_part_content_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6123 Evas_Object *ret = NULL;
6124 if (it->deco_all_view)
6125 ret = edje_object_part_swallow_get(it->deco_all_view, part);
6126 else if (it->decorate_it_set)
6127 ret = edje_object_part_swallow_get(it->item->deco_it_view, part);
6131 ret = edje_object_part_swallow_get(VIEW(it), part);
6133 ret = edje_object_part_swallow_get(VIEW(it), "elm.swallow.icon");
6138 EOLIAN static const char *
6139 _elm_genlist_item_elm_widget_item_part_text_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6141 if (!it->itc->func.text_get) return NULL;
6142 const char *ret = NULL;
6143 if (it->deco_all_view)
6144 ret = edje_object_part_text_get(it->deco_all_view, part);
6145 else if (it->decorate_it_set)
6146 ret = edje_object_part_text_get(it->item->deco_it_view, part);
6150 ret = edje_object_part_text_get(VIEW(it), part);
6152 ret = edje_object_part_text_get(VIEW(it), "elm.text");
6158 _elm_genlist_item_elm_widget_item_disable(Eo *eo_it, Elm_Gen_Item *it)
6165 if (eo_it == GL_IT(it)->wsd->focused_item)
6166 _elm_genlist_item_unfocused(eo_it);
6167 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
6171 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()))
6173 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
6174 if (it->deco_all_view)
6175 edje_object_signal_emit
6176 (it->deco_all_view, SIGNAL_DISABLED, "elm");
6180 edje_object_signal_emit(VIEW(it), SIGNAL_ENABLED, "elm");
6181 if (it->deco_all_view)
6182 edje_object_signal_emit
6183 (it->deco_all_view, SIGNAL_ENABLED, "elm");
6185 EINA_LIST_FOREACH(it->contents, l, obj)
6186 elm_widget_disabled_set(obj, eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()));
6190 EOLIAN static Eina_Bool
6191 _elm_genlist_item_elm_widget_item_del_pre(Eo *eo_it EINA_UNUSED,
6194 /* This item is getting removed from a callback that triggered in the
6195 _item_select(). Just pend removing. Because this will be removed right
6196 after in the _item_select(). So pratically, this item won't be
6198 if (it->walking > 0)
6200 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
6201 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
6210 _elm_genlist_item_elm_widget_item_signal_emit(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char *emission, const char *source)
6214 WRN("Item is not realized yet");
6217 edje_object_signal_emit(VIEW(it), emission, source);
6218 if (it->deco_all_view)
6219 edje_object_signal_emit(it->deco_all_view, emission, source);
6223 _elm_genlist_item_elm_widget_item_focus_set(Eo *eo_it, Elm_Gen_Item *it, Eina_Bool focused)
6225 Evas_Object *obj = WIDGET(it);
6226 ELM_GENLIST_DATA_GET(obj, sd);
6230 sd->last_focused_item = eo_it;
6231 if (!elm_object_focus_get(obj))
6232 elm_object_focus_set(obj, EINA_TRUE);
6234 if (!elm_widget_focus_get(obj))
6237 if (eo_it != sd->focused_item)
6239 if (sd->focused_item)
6240 _elm_genlist_item_unfocused(sd->focused_item);
6241 _elm_genlist_item_focused(eo_it);
6243 /* If item is not realized state, widget couldn't get focus_highlight data. */
6246 _elm_widget_item_highlight_in_theme(obj, EO_OBJ(it));
6247 _elm_widget_highlight_in_theme_update(obj);
6248 _elm_widget_focus_highlight_start(obj);
6254 if (!elm_widget_focus_get(obj))
6256 _elm_genlist_item_unfocused(eo_it);
6260 EOLIAN static Eina_Bool
6261 _elm_genlist_item_elm_widget_item_focus_get(Eo *eo_it, Elm_Gen_Item *it)
6263 Evas_Object *obj = WIDGET(it);
6264 ELM_GENLIST_DATA_GET(obj, sd);
6266 if (eo_it == sd->focused_item)
6273 _elm_genlist_item_eo_base_constructor(Eo *eo_it, Elm_Gen_Item *it)
6275 eo_it = eo_do_super_ret(eo_it, ELM_GENLIST_ITEM_CLASS, eo_it, eo_constructor());
6277 it->base = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
6278 eo_do(eo_it, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST_ITEM));
6283 static Elm_Gen_Item *
6284 _elm_genlist_item_new(Elm_Genlist_Data *sd,
6285 const Elm_Genlist_Item_Class *itc,
6287 Elm_Object_Item *eo_parent,
6288 Elm_Genlist_Item_Type type,
6290 const void *func_data)
6295 if (!itc) return NULL;
6297 Eo *eo_it = eo_add(ELM_GENLIST_ITEM_CLASS, sd->obj);
6298 if (!eo_it) return NULL;
6299 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6302 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
6304 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6305 WIDGET_ITEM_DATA_SET(EO_OBJ(it), data);
6306 it->parent = parent;
6307 it->func.func = func;
6308 it->func.data = func_data;
6310 GL_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
6311 GL_IT(it)->wsd = sd;
6312 GL_IT(it)->type = type;
6316 if (GL_IT(it->parent)->type & ELM_GENLIST_ITEM_GROUP)
6317 GL_IT(it)->group_item = parent;
6318 else if (GL_IT(it->parent)->group_item)
6319 GL_IT(it)->group_item = GL_IT(it->parent)->group_item;
6321 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
6323 if (!(GL_IT(it2->parent)->type & ELM_GENLIST_ITEM_GROUP)) depth += 1;
6325 GL_IT(it)->expanded_depth = depth;
6332 _elm_genlist_item_compare(const void *data,
6335 const Elm_Gen_Item *it, *item1;
6337 it = ELM_GEN_ITEM_FROM_INLIST(data);
6338 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
6339 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6343 _elm_genlist_item_list_compare(const void *data,
6346 const Elm_Gen_Item *it = data;
6347 const Elm_Gen_Item *item1 = data1;
6349 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6353 _elm_genlist_eo_item_list_compare(const void *data,
6356 const Elm_Object_Item *eo_it = data;
6357 const Elm_Object_Item *eo_item1 = data1;
6358 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6360 return GL_IT(it)->wsd->item_compare_cb(eo_it, eo_item1);
6363 EOLIAN static unsigned int
6364 _elm_genlist_items_count(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6366 return sd->item_count;
6370 _list_last_recursive(Eina_List *list)
6372 Eina_List *ll, *ll2;
6373 Elm_Object_Item *eo_it2;
6375 ll = eina_list_last(list);
6376 if (!ll) return NULL;
6379 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6381 if (it2->item->items)
6383 ll2 = _list_last_recursive(it2->item->items);
6393 EOLIAN static Elm_Object_Item*
6394 _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)
6400 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6401 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6402 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6405 it = _elm_genlist_item_new
6406 (sd, itc, data, eo_parent, type, func, func_data);
6407 if (!it) return NULL;
6411 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
6412 sd->group_items = eina_list_append(sd->group_items, it);
6413 sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
6414 it->item->rel = NULL;
6418 Elm_Object_Item *eo_it2 = NULL;
6419 Eina_List *ll = _list_last_recursive(it->parent->item->items);
6421 if (ll) eo_it2 = ll->data;
6422 it->parent->item->items =
6423 eina_list_append(it->parent->item->items, EO_OBJ(it));
6424 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6425 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6426 sd->items = eina_inlist_append_relative
6427 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6428 it->item->rel = it2;
6429 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6431 it->item->before = EINA_FALSE;
6432 _item_queue(sd, it, NULL);
6437 EOLIAN static Elm_Object_Item*
6438 _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)
6444 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6445 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6446 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6447 /* first sub-item should allways be appended */
6448 if (!parent->item->items)
6449 return _elm_genlist_item_append(obj, sd, itc, data, eo_parent, type, func, func_data);
6452 it = _elm_genlist_item_new
6453 (sd, itc, data, eo_parent, type, func, func_data);
6454 if (!it) return NULL;
6458 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
6459 sd->group_items = eina_list_prepend(sd->group_items, it);
6460 sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
6461 it->item->rel = NULL;
6465 Elm_Object_Item *eo_it2 = NULL;
6466 Eina_List *ll = it->parent->item->items;
6468 if (ll) eo_it2 = ll->data;
6469 it->parent->item->items =
6470 eina_list_prepend(it->parent->item->items, EO_OBJ(it));
6471 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6472 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6473 sd->items = eina_inlist_prepend_relative
6474 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6475 it->item->rel = it2;
6476 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6478 it->item->before = EINA_TRUE;
6479 _item_queue(sd, it, NULL);
6484 EOLIAN static Elm_Object_Item*
6485 _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)
6487 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_after, NULL);
6488 ELM_GENLIST_ITEM_DATA_GET(eo_after, after);
6491 ELM_GENLIST_ITEM_CHECK_OR_RETURN(after, NULL);
6492 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(after)), NULL);
6495 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6496 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6497 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6500 /* It makes no sense to insert after in an empty list with after !=
6501 * NULL, something really bad is happening in your app. */
6502 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6504 it = _elm_genlist_item_new
6505 (sd, itc, data, eo_parent, type, func, func_data);
6506 if (!it) return NULL;
6510 if ((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) &&
6511 (GL_IT(after)->type & ELM_GENLIST_ITEM_GROUP))
6512 sd->group_items = eina_list_append_relative
6513 (sd->group_items, it, after);
6517 it->parent->item->items =
6518 eina_list_append_relative(it->parent->item->items, EO_OBJ(it), eo_after);
6520 sd->items = eina_inlist_append_relative
6521 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
6523 it->item->rel = after;
6524 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
6525 it->item->before = EINA_FALSE;
6526 _item_queue(sd, it, NULL);
6531 EOLIAN static Elm_Object_Item*
6532 _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)
6534 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_before, NULL);
6535 ELM_GENLIST_ITEM_DATA_GET(eo_before, before);
6538 ELM_GENLIST_ITEM_CHECK_OR_RETURN(before, NULL);
6539 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(before)), NULL);
6542 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6543 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6544 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6547 /* It makes no sense to insert before in an empty list with before
6548 * != NULL, something really bad is happening in your app. */
6549 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6551 it = _elm_genlist_item_new
6552 (sd, itc, data, eo_parent, type, func, func_data);
6553 if (!it) return NULL;
6557 if ((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) &&
6558 (GL_IT(before)->type & ELM_GENLIST_ITEM_GROUP))
6560 eina_list_prepend_relative(sd->group_items, it, before);
6564 it->parent->item->items =
6565 eina_list_prepend_relative(it->parent->item->items, EO_OBJ(it), eo_before);
6567 sd->items = eina_inlist_prepend_relative
6568 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
6570 it->item->rel = before;
6571 GL_IT(before)->rel_revs = eina_list_append(GL_IT(before)->rel_revs, it);
6572 it->item->before = EINA_TRUE;
6573 _item_queue(sd, it, NULL);
6578 EOLIAN static Elm_Object_Item*
6579 _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)
6581 Elm_Gen_Item *rel = NULL;
6586 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6587 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6588 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6591 it = _elm_genlist_item_new
6592 (sd, itc, data, eo_parent, type, func, func_data);
6593 if (!it) return NULL;
6594 Elm_Object_Item *eo_it = EO_OBJ(it);
6596 sd->item_compare_cb = comp;
6600 Elm_Object_Item *eo_rel = NULL;
6604 l = eina_list_search_sorted_near_list
6605 (it->parent->item->items, _elm_genlist_eo_item_list_compare, eo_it,
6610 eo_rel = eina_list_data_get(l);
6611 rel = eo_data_scope_get(eo_rel, ELM_GENLIST_ITEM_CLASS);
6613 if (cmp_result >= 0)
6615 it->parent->item->items = eina_list_prepend_relative_list
6616 (it->parent->item->items, eo_it, l);
6617 sd->items = eina_inlist_prepend_relative
6618 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6619 it->item->before = EINA_TRUE;
6621 else if (cmp_result < 0)
6623 it->parent->item->items = eina_list_append_relative_list
6624 (it->parent->item->items, eo_it, l);
6625 sd->items = eina_inlist_append_relative
6626 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6627 it->item->before = EINA_FALSE;
6634 // ignoring the comparison
6635 it->parent->item->items = eina_list_prepend_relative_list
6636 (it->parent->item->items, eo_it, l);
6637 sd->items = eina_inlist_prepend_relative
6638 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6639 it->item->before = EINA_FALSE;
6646 sd->state = eina_inlist_sorted_state_new();
6647 eina_inlist_sorted_state_init(sd->state, sd->items);
6648 sd->requeued = EINA_FALSE;
6651 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6652 sd->group_items = eina_list_append(sd->group_items, it);
6654 sd->items = eina_inlist_sorted_state_insert
6655 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
6658 if (EINA_INLIST_GET(it)->next)
6660 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6661 it->item->before = EINA_TRUE;
6663 else if (EINA_INLIST_GET(it)->prev)
6665 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6666 it->item->before = EINA_FALSE;
6672 GL_IT(it)->rel = rel;
6673 rel->item->rel_revs = eina_list_append(rel->item->rel_revs, it);
6676 _item_queue(sd, it, _elm_genlist_item_list_compare);
6682 _elm_genlist_clear(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED)
6684 _internal_elm_genlist_clear(obj);
6688 _elm_genlist_multi_select_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool multi)
6690 sd->multi = !!multi;
6692 if (!sd->multi && sd->selected)
6695 Elm_Object_Item *eo_it;
6696 Elm_Object_Item *last = sd->selected->data;
6697 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
6701 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6708 EOLIAN static Eina_Bool
6709 _elm_genlist_multi_select_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6715 _elm_genlist_multi_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Elm_Object_Multi_Select_Mode mode)
6717 if (mode >= ELM_OBJECT_MULTI_SELECT_MODE_MAX)
6720 if (sd->multi_select_mode != mode)
6721 sd->multi_select_mode = mode;
6724 EOLIAN static Elm_Object_Multi_Select_Mode
6725 _elm_genlist_multi_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6727 return sd->multi_select_mode;
6730 EOLIAN static Elm_Object_Item*
6731 _elm_genlist_selected_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6734 return sd->selected->data;
6739 EOLIAN static const Eina_List*
6740 _elm_genlist_selected_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6742 return sd->selected;
6745 EOLIAN static Eina_List*
6746 _elm_genlist_realized_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6749 Eina_Bool done = EINA_FALSE;
6751 Eina_List *ret = NULL;
6753 EINA_INLIST_FOREACH(sd->blocks, itb)
6761 EINA_LIST_FOREACH(itb->items, l, it)
6763 if (it->realized) ret = eina_list_append(ret, EO_OBJ(it));
6775 EOLIAN static Elm_Object_Item*
6776 _elm_genlist_at_xy_item_get(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y, int *posret)
6778 Evas_Coord ox, oy, ow, oh;
6782 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
6784 EINA_INLIST_FOREACH(sd->blocks, itb)
6789 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->sd->pan_x,
6790 oy + itb->y - itb->sd->pan_y,
6791 itb->w, itb->h, x, y, 1, 1))
6793 EINA_LIST_FOREACH(itb->items, l, it)
6795 Evas_Coord itx, ity;
6797 itx = ox + itb->x + it->x - itb->sd->pan_x;
6798 ity = oy + itb->y + it->y - itb->sd->pan_y;
6799 if (ELM_RECTS_INTERSECT
6800 (itx, ity, it->item->w, it->item->h, x, y, 1, 1))
6804 if (y <= (ity + (it->item->h / 4))) *posret = -1;
6805 else if (y >= (ity + it->item->h - (it->item->h / 4)))
6812 lasty = ity + it->item->h;
6817 if (y > lasty) *posret = 1;
6824 EOLIAN static Elm_Object_Item*
6825 _elm_genlist_first_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6827 return EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(sd->items));
6830 EOLIAN static Elm_Object_Item*
6831 _elm_genlist_last_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6835 if (!sd->items) return NULL;
6837 it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
6842 EOLIAN static Elm_Object_Item *
6843 _elm_genlist_item_next_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6847 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6851 if (it) return EO_OBJ(it);
6855 EOLIAN static Elm_Object_Item *
6856 _elm_genlist_item_prev_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6860 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6864 if (it) return EO_OBJ(it);
6868 EOLIAN static Elm_Object_Item *
6869 _elm_genlist_item_parent_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6871 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
6873 return EO_OBJ(it->parent);
6876 EOLIAN static unsigned int
6877 _elm_genlist_item_subitems_count(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
6879 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, 0);
6881 return eina_list_count(item->item->items);
6884 EOLIAN static const Eina_List *
6885 _elm_genlist_item_subitems_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
6887 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6889 return item->item->items;
6893 _elm_genlist_item_subitems_clear(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6895 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6896 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
6898 if (!sd->tree_effect_enabled || !sd->move_effect_mode)
6899 _item_sub_items_clear(it);
6902 if (!sd->tree_effect_animator)
6904 sd->expanded_item = it;
6905 _item_tree_effect_before(it);
6906 evas_object_stack_below(sd->event_block_rect, sd->stack[1]);
6907 evas_object_show(sd->event_block_rect);
6908 sd->start_time = ecore_time_get();
6909 sd->tree_effect_animator =
6910 ecore_animator_add(_tree_effect_animator_cb, sd->obj);
6913 _item_sub_items_clear(it);
6918 _elm_genlist_item_selected_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
6922 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6924 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get())) return;
6926 selected = !!selected;
6927 if (it->selected == selected) return;
6929 if (selected) _item_select(it);
6930 else _item_unselect(it);
6933 EOLIAN static Eina_Bool
6934 _elm_genlist_item_selected_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6936 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6938 return it->selected;
6941 static Elm_Gen_Item *
6942 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
6944 Elm_Object_Item *eo_it = EO_OBJ(it);
6945 Elm_Object_Item *eo_it2;
6947 if (it->item->expanded)
6949 eo_it2 = elm_genlist_item_next_get(eo_it);
6950 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6955 eo_it2 = elm_genlist_item_next_get(eo_it);
6958 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6959 if (it->item->expanded_depth >= it2->item->expanded_depth) return it2;
6960 eo_it2 = elm_genlist_item_next_get(eo_it2);
6963 return eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
6967 _elm_genlist_move_items_set(Elm_Gen_Item *it)
6970 Elm_Gen_Item *it2 = NULL;
6971 Evas_Coord ox, oy, ow, oh, dh = 0;
6972 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
6974 sd->expanded_next_item =
6975 _elm_genlist_expanded_next_item_get(it);
6977 if (it->item->expanded)
6979 Elm_Object_Item *eo_item;
6980 l = elm_genlist_realized_items_get((sd)->obj);
6981 EINA_LIST_FREE(l, eo_item)
6983 ELM_GENLIST_ITEM_DATA_GET(eo_item, item);
6984 sd->move_items = eina_list_append(sd->move_items, item);
6987 EINA_LIST_FOREACH_SAFE(sd->move_items, l, ll, it2)
6989 if (it2 == sd->expanded_next_item) break;
6990 sd->move_items = eina_list_remove(sd->move_items, it2);
6995 Elm_Object_Item *eo_it2 = NULL;
6996 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
6997 if (sd->expanded_next_item) eo_it2 = EO_OBJ(sd->expanded_next_item);
6999 while (eo_it2 && (dh < oy + oh))
7001 it2 = eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
7003 sd->move_items = eina_list_append(sd->move_items, it2);
7004 eo_it2 = elm_genlist_item_next_get(eo_it2);
7010 _event_block_rect_update(const Evas_Object *obj)
7012 Evas_Coord ox, oy, ow, oh;
7014 ELM_GENLIST_CHECK(obj);
7015 ELM_GENLIST_DATA_GET(obj, sd);
7017 if (!sd->event_block_rect)
7019 sd->event_block_rect = evas_object_rectangle_add(
7020 evas_object_evas_get(sd->obj));
7021 evas_object_smart_member_add(sd->event_block_rect, sd->pan_obj);
7024 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7025 evas_object_color_set(sd->event_block_rect, 0, 0, 0, 0);
7026 evas_object_resize(sd->event_block_rect, ow, oh);
7027 evas_object_move(sd->event_block_rect, ox, oy);
7031 _elm_genlist_item_expanded_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool expanded)
7033 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7034 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7036 expanded = !!expanded;
7037 if (it->item->expanded == expanded) return;
7038 if (it->item->type != ELM_GENLIST_ITEM_TREE) return;
7039 it->item->expanded = expanded;
7040 sd->expanded_item = it;
7041 _elm_genlist_move_items_set(it);
7043 if (sd->tree_effect_enabled)
7044 _event_block_rect_update(WIDGET(it));
7046 if (it->item->expanded)
7048 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
7050 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
7051 eo_do(WIDGET(it), eo_event_callback_call
7052 (ELM_GENLIST_EVENT_EXPANDED, EO_OBJ(it)));
7053 sd->auto_scroll_enabled = EINA_TRUE;
7054 if (_elm_config->atspi_mode)
7055 elm_interface_atspi_accessible_state_changed_signal_emit(eo_item, ELM_ATSPI_STATE_EXPANDED, EINA_TRUE);
7059 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
7061 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACTED, "elm");
7062 eo_do(WIDGET(it), eo_event_callback_call
7063 (ELM_GENLIST_EVENT_CONTRACTED, EO_OBJ(it)));
7064 sd->auto_scroll_enabled = EINA_FALSE;
7065 if (_elm_config->atspi_mode)
7066 elm_interface_atspi_accessible_state_changed_signal_emit(eo_item, ELM_ATSPI_STATE_EXPANDED, EINA_FALSE);
7070 EOLIAN static Eina_Bool
7071 _elm_genlist_item_expanded_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7073 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7075 return GL_IT(it)->expanded;
7079 _elm_genlist_item_expanded_depth_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7081 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, 0);
7083 return GL_IT(it)->expanded_depth;
7087 _elm_genlist_item_coordinates_calc(Elm_Gen_Item *it,
7088 Elm_Genlist_Item_Scrollto_Type type,
7095 Evas_Coord gith = 0;
7096 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7098 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
7100 (!((sd->homogeneous || it->itc->homogeneous) &&
7101 (sd->mode == ELM_LIST_COMPRESS))))
7103 if ((it->item->queued) || (!it->item->mincalcd) || (sd->queue))
7105 sd->check_scroll = EINA_TRUE;
7107 sd->bring_in = bring_in;
7108 sd->scroll_to_type = type;
7109 it->item->show_me = EINA_TRUE;
7111 ecore_job_del(sd->calc_job);
7112 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
7119 sd->show_item->item->show_me = EINA_FALSE;
7120 sd->show_item = NULL;
7123 evas_object_geometry_get(sd->pan_obj, NULL, NULL, w, h);
7126 case ELM_GENLIST_ITEM_SCROLLTO_IN:
7127 if ((it->item->group_item) &&
7128 (sd->pan_y > (it->y + it->item->block->y)))
7129 gith = it->item->group_item->item->h;
7131 *y = it->y + it->item->block->y - gith;
7134 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
7135 if (it->item->group_item) gith = it->item->group_item->item->h;
7136 *y = it->y + it->item->block->y - gith;
7139 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
7140 *y = it->y + it->item->block->y - (*h / 2) + (it->item->h / 2);
7143 case ELM_GENLIST_ITEM_SCROLLTO_BOTTOM:
7144 *y = it->y + it->item->block->y - *h + it->item->h;
7151 *x = it->x + it->item->block->x;
7152 *w = it->item->block->w;
7158 _elm_genlist_item_promote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7160 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7162 Elm_Object_Item *eo_first_item = elm_genlist_first_item_get(WIDGET(it));
7163 ELM_GENLIST_ITEM_DATA_GET(eo_first_item, first_item);
7164 _item_move_before(it, first_item);
7168 _elm_genlist_item_demote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7170 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7171 Elm_Object_Item *eo_last_item = elm_genlist_last_item_get(WIDGET(it));
7172 ELM_GENLIST_ITEM_DATA_GET(eo_last_item, last_item);
7173 _item_move_after(it, last_item);
7177 _elm_genlist_item_show(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item, Elm_Genlist_Item_Scrollto_Type type)
7179 Evas_Coord x, y, w, h;
7181 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
7183 if (item->want_hidden)
7185 WRN("Filter hided item cannot move to show");
7189 if (_elm_genlist_item_coordinates_calc
7190 (item, type, EINA_FALSE, &x, &y, &w, &h))
7191 eo_do(WIDGET(item), elm_interface_scrollable_content_region_show
7196 _elm_genlist_item_bring_in(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item, Elm_Genlist_Item_Scrollto_Type type)
7198 Evas_Coord x, y, w, h;
7200 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
7202 if (item->want_hidden)
7204 WRN("Filter hided item cannot move to bring in");
7208 if (_elm_genlist_item_coordinates_calc
7209 (item, type, EINA_TRUE, &x, &y, &w, &h))
7210 eo_do(WIDGET(item), elm_interface_scrollable_region_bring_in(x, y, w, h));
7214 _elm_genlist_item_all_contents_unset(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_List **l)
7216 Evas_Object *content;
7218 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7220 EINA_LIST_FREE(it->contents, content)
7222 _elm_widget_sub_object_redirect_to_top(WIDGET(it), content);
7223 edje_object_part_unswallow(VIEW(it), content);
7224 evas_object_hide(content);
7225 if (l) *l = eina_list_append(*l, content);
7230 _elm_genlist_item_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7232 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7233 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7235 if (!it->item->block) return;
7236 it->item->mincalcd = EINA_FALSE;
7237 it->item->updateme = EINA_TRUE;
7238 it->item->block->updateme = EINA_TRUE;
7239 ecore_job_del(sd->update_job);
7240 sd->update_job = ecore_job_add(_update_job, sd->obj);
7244 _elm_genlist_item_fields_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
7246 Elm_Genlist_Item_Field_Type itf)
7248 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7250 if (!it->item->block) return;
7252 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
7254 _item_text_realize(it, VIEW(it), &it->texts, parts);
7256 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
7258 _item_content_realize(it, VIEW(it), &it->contents, "contents", parts);
7261 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_contents,
7264 if (GL_IT(it)->deco_it_view)
7266 _item_content_realize(it, GL_IT(it)->deco_it_view,
7267 &GL_IT(it)->deco_it_contents,
7270 if (GL_IT(it)->wsd->decorate_all_mode)
7272 _item_content_realize(it, it->deco_all_view,
7273 &GL_IT(it)->deco_all_contents,
7276 if (it->has_contents != (!!it->contents))
7277 it->item->mincalcd = EINA_FALSE;
7278 it->has_contents = !!it->contents;
7279 if (it->item->type == ELM_GENLIST_ITEM_NONE)
7283 it->item_focus_chain = eina_list_free(it->item_focus_chain);
7284 EINA_LIST_FOREACH(it->contents, l, eobj)
7285 if (elm_widget_is(eobj) && elm_object_focus_allow_get(eobj))
7286 it->item_focus_chain = eina_list_append(it->item_focus_chain, eobj);
7290 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
7291 _item_state_realize(it, VIEW(it), parts);
7293 if (!it->item->mincalcd)
7294 elm_genlist_item_update(eo_item);
7298 _elm_genlist_item_item_class_update(Eo *eo_it, Elm_Gen_Item *it,
7299 const Elm_Genlist_Item_Class *itc)
7301 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7302 EINA_SAFETY_ON_NULL_RETURN(itc);
7304 if (!it->item->block) return;
7305 it->item->nocache_once = EINA_TRUE;
7307 ELM_SAFE_FREE(it->texts, elm_widget_stringlist_free);
7308 ELM_SAFE_FREE(GL_IT(it)->deco_it_texts, elm_widget_stringlist_free);
7309 ELM_SAFE_FREE(GL_IT(it)->deco_all_texts, elm_widget_stringlist_free);
7311 elm_genlist_item_update(eo_it);
7314 EOLIAN static const Elm_Genlist_Item_Class *
7315 _elm_genlist_item_item_class_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7317 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
7322 static Evas_Object *
7323 _elm_genlist_item_label_create(void *data,
7324 Evas_Object *obj EINA_UNUSED,
7325 Evas_Object *tooltip,
7326 void *it EINA_UNUSED)
7328 Evas_Object *label = elm_label_add(tooltip);
7333 elm_object_style_set(label, "tooltip");
7334 elm_object_text_set(label, data);
7340 _elm_genlist_item_label_del_cb(void *data,
7341 Evas_Object *obj EINA_UNUSED,
7342 void *event_info EINA_UNUSED)
7344 eina_stringshare_del(data);
7348 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
7351 eo_do(it, elm_wdg_item_tooltip_text_set(text));
7355 _elm_genlist_item_elm_widget_item_tooltip_text_set(Eo *eo_it, Elm_Gen_Item *it, const char *text)
7357 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7359 text = eina_stringshare_add(text);
7360 elm_genlist_item_tooltip_content_cb_set
7361 (eo_it, _elm_genlist_item_label_create, text,
7362 _elm_genlist_item_label_del_cb);
7366 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item,
7367 Elm_Tooltip_Item_Content_Cb func,
7369 Evas_Smart_Cb del_cb)
7371 eo_do(item, elm_wdg_item_tooltip_content_cb_set(func, data, del_cb));
7375 _elm_genlist_item_elm_widget_item_tooltip_content_cb_set(Eo *eo_it, Elm_Gen_Item *it,
7376 Elm_Tooltip_Item_Content_Cb func,
7378 Evas_Smart_Cb del_cb)
7380 ELM_GENLIST_ITEM_CHECK_OR_GOTO(it, error);
7382 if ((it->tooltip.content_cb != func) || (it->tooltip.data != data))
7384 if (it->tooltip.del_cb)
7385 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7387 it->tooltip.content_cb = func;
7388 it->tooltip.data = data;
7389 it->tooltip.del_cb = del_cb;
7394 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7395 elm_wdg_item_tooltip_content_cb_set
7396 (it->tooltip.content_cb, it->tooltip.data, NULL));
7398 elm_wdg_item_tooltip_style_set(it->tooltip.style),
7399 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
7405 if (del_cb) del_cb((void *)data, NULL, NULL);
7409 elm_genlist_item_tooltip_unset(Elm_Object_Item *item)
7411 eo_do(item, elm_wdg_item_tooltip_unset());
7415 _elm_genlist_item_elm_widget_item_tooltip_unset(Eo *eo_it, Elm_Gen_Item *it)
7417 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7419 if ((VIEW(it)) && (it->tooltip.content_cb))
7420 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7421 elm_wdg_item_tooltip_unset());
7423 if (it->tooltip.del_cb)
7424 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7425 it->tooltip.del_cb = NULL;
7426 it->tooltip.content_cb = NULL;
7427 it->tooltip.data = NULL;
7428 it->tooltip.free_size = EINA_FALSE;
7429 if (it->tooltip.style)
7430 eo_do(eo_it, elm_wdg_item_tooltip_style_set(NULL));
7434 elm_genlist_item_tooltip_style_set(Elm_Object_Item *item,
7437 eo_do(item, elm_wdg_item_tooltip_style_set(style));
7441 _elm_genlist_item_elm_widget_item_tooltip_style_set(Eo *eo_it, Elm_Gen_Item *it,
7444 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7446 eina_stringshare_replace(&it->tooltip.style, style);
7447 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7448 elm_wdg_item_tooltip_style_set(style));
7452 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
7455 return eo_do_ret(it, ret, elm_wdg_item_tooltip_style_get());
7458 EOLIAN static const char *
7459 _elm_genlist_item_elm_widget_item_tooltip_style_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7461 return it->tooltip.style;
7465 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *item,
7469 return eo_do_ret(item, ret, elm_wdg_item_tooltip_window_mode_set(disable));
7472 EOLIAN static Eina_Bool
7473 _elm_genlist_item_elm_widget_item_tooltip_window_mode_set(Eo *eo_it, Elm_Gen_Item *it,
7476 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7478 it->tooltip.free_size = disable;
7482 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7483 ret = elm_wdg_item_tooltip_window_mode_set(disable));
7491 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *eo_it)
7494 return eo_do_ret(eo_it, ret, elm_wdg_item_tooltip_window_mode_get());
7497 EOLIAN static Eina_Bool
7498 _elm_genlist_item_elm_widget_item_tooltip_window_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7500 return it->tooltip.free_size;
7504 elm_genlist_item_cursor_set(Elm_Object_Item *item,
7507 eo_do(item, elm_wdg_item_cursor_set(cursor));
7511 _elm_genlist_item_elm_widget_item_cursor_set(Eo *eo_it, Elm_Gen_Item *it,
7514 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7515 eina_stringshare_replace(&it->mouse_cursor, cursor);
7516 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7517 elm_wdg_item_cursor_set(cursor));
7521 elm_genlist_item_cursor_get(const Elm_Object_Item *eo_it)
7524 return eo_do_ret(eo_it, ret, elm_wdg_item_cursor_get());
7528 elm_genlist_item_cursor_unset(Elm_Object_Item *item)
7530 eo_do(item, elm_wdg_item_cursor_unset());
7534 _elm_genlist_item_elm_widget_item_cursor_unset(Eo *eo_it, Elm_Gen_Item *it)
7536 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7538 if (!it->mouse_cursor) return;
7540 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7541 elm_wdg_item_cursor_unset());
7543 ELM_SAFE_FREE(it->mouse_cursor, eina_stringshare_del);
7547 elm_genlist_item_cursor_style_set(Elm_Object_Item *eo_it,
7550 eo_do(eo_it, elm_wdg_item_cursor_style_set(style));
7554 elm_genlist_item_cursor_style_get(const Elm_Object_Item *eo_it)
7557 return eo_do_ret(eo_it, ret, elm_wdg_item_cursor_style_get());
7561 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *eo_it,
7562 Eina_Bool engine_only)
7564 eo_do(eo_it, elm_wdg_item_cursor_engine_only_set(engine_only));
7568 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *eo_it)
7571 return eo_do_ret(eo_it, ret, elm_wdg_item_cursor_engine_only_get());
7575 _elm_genlist_item_index_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7579 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, -1);
7581 EINA_INLIST_FOREACH(GL_IT(it)->wsd->items, tmp)
7583 if (tmp == it) break;
7590 _elm_genlist_mode_set(Eo *obj, Elm_Genlist_Data *sd, Elm_List_Mode mode)
7592 if (sd->mode == mode) return;
7595 if (sd->mode == ELM_LIST_LIMIT)
7597 sd->scr_minw = EINA_TRUE;
7598 sd->scr_minh = EINA_FALSE;
7600 else if (sd->mode == ELM_LIST_EXPAND)
7602 sd->scr_minw = EINA_TRUE;
7603 sd->scr_minh = EINA_TRUE;
7607 sd->scr_minw = EINA_FALSE;
7608 sd->scr_minh = EINA_FALSE;
7611 elm_layout_sizing_eval(obj);
7614 EOLIAN static Elm_List_Mode
7615 _elm_genlist_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7621 elm_genlist_bounce_set(Evas_Object *obj,
7625 ELM_GENLIST_CHECK(obj);
7626 eo_do(obj, elm_interface_scrollable_bounce_allow_set(h_bounce, v_bounce));
7630 _elm_genlist_elm_interface_scrollable_bounce_allow_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool h_bounce, Eina_Bool v_bounce)
7632 sd->h_bounce = !!h_bounce;
7633 sd->v_bounce = !!v_bounce;
7634 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_bounce_allow_set
7635 (sd->h_bounce, sd->v_bounce));
7639 elm_genlist_bounce_get(const Evas_Object *obj,
7640 Eina_Bool *h_bounce,
7641 Eina_Bool *v_bounce)
7643 ELM_GENLIST_CHECK(obj);
7644 eo_do( obj, elm_interface_scrollable_bounce_allow_get
7645 (h_bounce, v_bounce));
7649 _elm_genlist_elm_interface_scrollable_bounce_allow_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
7651 if (h_bounce) *h_bounce = sd->h_bounce;
7652 if (v_bounce) *v_bounce = sd->v_bounce;
7656 _elm_genlist_homogeneous_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool homogeneous)
7658 sd->homogeneous = !!homogeneous;
7661 EOLIAN static Eina_Bool
7662 _elm_genlist_homogeneous_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7664 return sd->homogeneous;
7668 _elm_genlist_block_count_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, int count)
7670 EINA_SAFETY_ON_TRUE_RETURN(count < 1);
7672 sd->max_items_per_block = count;
7673 sd->item_cache_max = sd->max_items_per_block * 2;
7674 _item_cache_clean(sd);
7678 _elm_genlist_block_count_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7680 return sd->max_items_per_block;
7684 _filter_item_internal(Elm_Gen_Item *it)
7686 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7687 if (sd->filter_data)
7689 if ((it->parent && !_item_filtered_get(it->parent)) ||
7690 (it->itc->func.filter_get &&
7691 !it->itc->func.filter_get(
7692 (void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)),
7693 WIDGET(it), sd->filter_data)))
7695 it->want_hidden = EINA_TRUE;
7696 if (sd->show_item == it) sd->show_item = NULL;
7697 it->item->block->changed = EINA_TRUE;
7700 sd->filtered_count++;
7702 it->filtered = EINA_TRUE;
7703 sd->processed_count++;
7707 _item_filtered_get(Elm_Gen_Item *it)
7710 if (!it) return EINA_FALSE;
7711 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7714 l = eina_list_data_find_list(sd->filter_queue, it);
7716 sd->filter_queue = eina_list_remove_list(sd->queue, l);
7717 l = eina_list_data_find_list(sd->queue, it);
7720 sd->queue = eina_list_remove_list(sd->queue, l);
7721 it->item->queued = EINA_FALSE;
7722 _item_process(sd, it);
7723 _item_process_post(sd, it, EINA_TRUE);
7726 _filter_item_internal(it);
7727 it->item->block->changed = EINA_TRUE;
7728 ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
7729 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
7731 if (!it->want_hidden) return EINA_TRUE;
7736 _filter_queue_process(Elm_Genlist_Data *sd)
7742 t0 = ecore_loop_time_get();
7743 for (n = 0; (sd->filter_queue) && (sd->processed_count < sd->item_count); n++)
7745 it = eina_list_data_get(sd->filter_queue);
7746 //FIXME: This is added as a fail safe code for items not yet processed.
7747 while (it->item->queued)
7749 if ((ecore_loop_time_get() - t0) > (ecore_animator_frametime_get()))
7751 sd->filter_queue = eina_list_remove_list
7752 (sd->filter_queue, sd->filter_queue);
7753 sd->filter_queue = eina_list_append(sd->filter_queue, it);
7754 it = eina_list_data_get(sd->filter_queue);
7756 sd->filter_queue = eina_list_remove_list(sd->filter_queue, sd->filter_queue);
7757 _filter_item_internal(it);
7758 it->item->block->changed = EINA_TRUE;
7759 if ((ecore_loop_time_get() - t0) > (ecore_animator_frametime_get()))
7761 //At least 1 item is filtered by this time, so return n+1 for first loop
7770 _filter_process(void *data,
7773 Elm_Genlist_Data *sd = data;
7775 if (_filter_queue_process(sd) > 0) *wakeup = EINA_TRUE;
7776 if (!sd->filter_queue) return ECORE_CALLBACK_CANCEL;
7777 return ECORE_CALLBACK_RENEW;
7781 _item_filter_enterer(void *data)
7783 Eina_Bool wakeup = EINA_FALSE;
7784 ELM_GENLIST_DATA_GET(data, sd);
7785 Eina_Bool ok = _filter_process(sd, &wakeup);
7789 ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
7790 sd->calc_job = ecore_job_add(_calc_job, data);
7792 if (ok == ECORE_CALLBACK_CANCEL)
7794 sd->queue_idle_enterer = NULL;
7795 eo_do(sd->obj, eo_event_callback_call(ELM_GENLIST_EVENT_FILTER_DONE, NULL));
7802 _elm_genlist_filter_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, void *filter_data)
7808 if (sd->filter_queue)
7809 ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
7810 ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
7811 ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
7812 sd->filtered_count = 0;
7813 sd->processed_count = 0;
7814 sd->filter = EINA_TRUE;
7815 sd->filter_data = filter_data;
7817 EINA_INLIST_FOREACH(sd->blocks, itb)
7821 EINA_LIST_FOREACH(itb->items, l, it)
7823 it->filtered = EINA_FALSE;
7824 it->want_hidden = EINA_FALSE;
7826 _filter_item_internal(it);
7828 sd->filter_queue = eina_list_append(sd->filter_queue, it);
7830 itb->changed = EINA_TRUE;
7834 EINA_LIST_FOREACH(itb->items, l, it)
7836 it->filtered = EINA_FALSE;
7837 it->want_hidden = EINA_FALSE;
7838 sd->filter_queue = eina_list_append(sd->filter_queue, it);
7844 sd->queue_filter_enterer = ecore_idle_enterer_add(_item_filter_enterer,
7849 _filter_iterator_next(Elm_Genlist_Filter *iter, void **data)
7851 if (!iter->current) return EINA_FALSE;
7853 while (iter->current)
7855 item = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->current, Elm_Gen_Item);
7856 iter->current = iter->current->next;
7857 if (_item_filtered_get(item))
7860 *data = EO_OBJ(item);
7869 _filter_iterator_free(Elm_Genlist_Filter *iter)
7874 static Evas_Object *
7875 _filter_iterator_get_container(Elm_Genlist_Filter *iter)
7877 Elm_Gen_Item *it = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->head, Elm_Gen_Item);
7881 EOLIAN Eina_Iterator *
7882 _elm_genlist_filter_iterator_new(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7884 Elm_Genlist_Filter *iter;
7885 iter = calloc(1, sizeof (Elm_Genlist_Filter));
7886 if (!iter) return NULL;
7888 iter->head = sd->items;
7889 iter->current = sd->items;
7891 iter->iterator.version = EINA_ITERATOR_VERSION;
7892 iter->iterator.next = FUNC_ITERATOR_NEXT(_filter_iterator_next);
7893 iter->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
7894 _filter_iterator_get_container);
7895 iter->iterator.free = FUNC_ITERATOR_FREE(_filter_iterator_free);
7897 EINA_MAGIC_SET(&iter->iterator, EINA_MAGIC_ITERATOR);
7899 return &iter->iterator;
7903 _elm_genlist_longpress_timeout_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, double timeout)
7905 sd->longpress_timeout = timeout;
7908 EOLIAN static double
7909 _elm_genlist_longpress_timeout_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7911 return sd->longpress_timeout;
7915 elm_genlist_scroller_policy_set(Evas_Object *obj,
7916 Elm_Scroller_Policy policy_h,
7917 Elm_Scroller_Policy policy_v)
7919 ELM_GENLIST_CHECK(obj);
7920 eo_do(obj, elm_interface_scrollable_policy_set(policy_h, policy_v));
7924 _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)
7926 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
7927 (policy_v >= ELM_SCROLLER_POLICY_LAST))
7930 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_set(policy_h, policy_v));
7934 elm_genlist_scroller_policy_get(const Evas_Object *obj,
7935 Elm_Scroller_Policy *policy_h,
7936 Elm_Scroller_Policy *policy_v)
7938 ELM_GENLIST_CHECK(obj);
7939 eo_do( obj, elm_interface_scrollable_policy_get(policy_h, policy_v));
7943 _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)
7945 Elm_Scroller_Policy s_policy_h, s_policy_v;
7947 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_get
7948 (&s_policy_h, &s_policy_v));
7949 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
7950 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
7954 _elm_genlist_realized_items_update(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED)
7957 Elm_Object_Item *it;
7959 list = elm_genlist_realized_items_get(obj);
7960 EINA_LIST_FREE(list, it)
7961 elm_genlist_item_update(it);
7965 _elm_genlist_item_decorate_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
7966 const char *decorate_it_type,
7967 Eina_Bool decorate_it_set)
7969 Elm_Genlist_Data *sd;
7971 Elm_Object_Item *eo_it2 = NULL;
7974 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7975 sd = GL_IT(it)->wsd;
7977 if (!decorate_it_type) return;
7978 if (eo_do_ret(eo_it, tmp, elm_wdg_item_disabled_get())) return;
7979 if (sd->decorate_all_mode) return;
7981 if ((sd->mode_item == it) &&
7982 (!strcmp(decorate_it_type, sd->decorate_it_type)) &&
7985 if (!it->itc->decorate_item_style) return;
7986 it->decorate_it_set = decorate_it_set;
7990 EINA_LIST_FOREACH(sd->selected, l, eo_it2)
7992 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
7994 elm_genlist_item_selected_set(eo_it2, EINA_FALSE);
7999 Elm_Gen_Item *it2 = NULL;
8000 eo_it2 = elm_genlist_selected_item_get(sd->obj);
8001 if (eo_it2) it2 = eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
8002 if (it2 && it2->realized)
8003 elm_genlist_item_selected_set(eo_it2, EINA_FALSE);
8006 if (((sd->decorate_it_type)
8007 && (strcmp(decorate_it_type, sd->decorate_it_type))) ||
8008 (decorate_it_set) || ((it == sd->mode_item) && (!decorate_it_set)))
8009 _decorate_item_unset(sd);
8011 eina_stringshare_replace(&sd->decorate_it_type, decorate_it_type);
8012 if (decorate_it_set) _decorate_item_set(it);
8015 EOLIAN static const char *
8016 _elm_genlist_item_decorate_mode_get(Eo *eo_i EINA_UNUSED, Elm_Gen_Item *i)
8018 ELM_GENLIST_ITEM_CHECK_OR_RETURN(i, NULL);
8019 return GL_IT(i)->wsd->decorate_it_type;
8022 EOLIAN static Elm_Object_Item *
8023 _elm_genlist_decorated_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8025 return EO_OBJ(sd->mode_item);
8028 EOLIAN static Eina_Bool
8029 _elm_genlist_decorate_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8031 return sd->decorate_all_mode;
8035 _elm_genlist_decorate_mode_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool decorated)
8037 Elm_Object_Item *eo_it;
8039 Elm_Object_Item *deco_it;
8041 decorated = !!decorated;
8042 if (sd->decorate_all_mode == decorated) return;
8043 // decorate_all_mode should be set first
8044 // because content_get func. will be called after this
8045 // and user can check whether decorate_all_mode_ is enabled.
8046 sd->decorate_all_mode = decorated;
8048 ELM_SAFE_FREE(sd->tree_effect_animator, ecore_animator_del);
8049 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
8051 list = elm_genlist_realized_items_get(obj);
8052 if (!sd->decorate_all_mode)
8054 EINA_LIST_FREE(list, eo_it)
8056 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8057 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
8058 _decorate_all_item_unrealize(it);
8060 _item_cache_zero(sd);
8064 // unset decorated item
8065 deco_it = elm_genlist_decorated_item_get(obj);
8068 elm_genlist_item_decorate_mode_set
8069 (deco_it, elm_genlist_item_decorate_mode_get
8070 (deco_it), EINA_FALSE);
8071 _decorate_item_finished_signal_cb(deco_it, obj, NULL, NULL);
8074 EINA_LIST_FREE(list, eo_it)
8076 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8077 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
8079 if (it->itc->decorate_all_item_style)
8080 _decorate_all_item_realize(it, EINA_TRUE);
8085 ecore_job_del(sd->calc_job);
8086 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
8090 _elm_genlist_reorder_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool reorder_mode)
8092 Eina_List *realized;
8093 Elm_Object_Item *eo_it;
8095 if (sd->reorder_mode == !!reorder_mode) return;
8096 sd->reorder_mode = !!reorder_mode;
8097 realized = elm_genlist_realized_items_get(obj);
8098 EINA_LIST_FREE(realized, eo_it)
8100 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8101 if (sd->reorder_mode)
8103 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
8104 if (it->deco_all_view)
8106 edje_object_signal_emit(it->deco_all_view,
8107 SIGNAL_REORDER_MODE_SET, "elm");
8112 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_UNSET, "elm");
8113 if (it->deco_all_view)
8115 edje_object_signal_emit(it->deco_all_view,
8116 SIGNAL_REORDER_MODE_UNSET, "elm");
8122 EOLIAN static Eina_Bool
8123 _elm_genlist_reorder_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8125 return sd->reorder_mode;
8128 EOLIAN static Elm_Genlist_Item_Type
8129 _elm_genlist_item_type_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8131 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
8133 return GL_IT(it)->type;
8136 EAPI Elm_Genlist_Item_Class *
8137 elm_genlist_item_class_new(void)
8139 Elm_Genlist_Item_Class *itc = ELM_NEW(Elm_Genlist_Item_Class);
8140 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
8142 itc->version = CLASS_ALLOCATED;
8144 itc->delete_me = EINA_FALSE;
8150 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
8152 if (itc && (itc->version == CLASS_ALLOCATED))
8154 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
8155 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
8165 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
8167 if (itc && (itc->version == CLASS_ALLOCATED))
8170 if (itc->refcount == 0) itc->refcount--;
8175 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
8177 if (itc && (itc->version == CLASS_ALLOCATED))
8179 if (itc->refcount > 0) itc->refcount--;
8180 if (itc->delete_me && (!itc->refcount))
8181 elm_genlist_item_class_free(itc);
8186 _flip_job(void *data)
8188 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
8189 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8192 _elm_genlist_item_unrealize(it, EINA_FALSE);
8194 it->flipped = EINA_TRUE;
8195 it->item->nocache = EINA_TRUE;
8196 ecore_job_del(sd->calc_job);
8197 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
8201 _elm_genlist_item_flip_set(Eo *eo_it, Elm_Gen_Item *it, Eina_Bool flip)
8203 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8206 if (it->flipped == flip) return;
8210 ecore_job_add(_flip_job, it);
8214 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_DISABLED, "elm");
8215 if (GL_IT(it)->wsd->decorate_all_mode)
8216 edje_object_signal_emit(it->deco_all_view, SIGNAL_FLIP_DISABLED,
8220 _item_cache_zero(GL_IT(it)->wsd);
8221 elm_genlist_item_update(eo_it);
8222 it->item->nocache = EINA_FALSE;
8226 EOLIAN static Eina_Bool
8227 _elm_genlist_item_flip_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8229 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
8235 _elm_genlist_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Elm_Object_Select_Mode mode)
8237 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (sd->select_mode == mode))
8240 sd->select_mode = mode;
8242 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8243 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
8246 Elm_Object_Item *eo_it;
8247 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
8249 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8255 EOLIAN static Elm_Object_Select_Mode
8256 _elm_genlist_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8258 return sd->select_mode;
8262 _elm_genlist_highlight_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool highlight)
8264 sd->highlight = !!highlight;
8267 EOLIAN static Eina_Bool
8268 _elm_genlist_highlight_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8270 return sd->highlight;
8274 _elm_genlist_item_select_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8275 Elm_Object_Select_Mode mode)
8277 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8278 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8280 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (it->select_mode == mode))
8283 it->select_mode = mode;
8285 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8286 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
8289 if (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
8291 it->item->mincalcd = EINA_FALSE;
8292 it->item->updateme = EINA_TRUE;
8293 if (it->item->block) it->item->block->updateme = EINA_TRUE;
8294 ecore_job_del(sd->update_job);
8295 sd->update_job = ecore_job_add(_update_job, sd->obj);
8297 // reset homogeneous item size
8298 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
8299 if (sd->homogeneous || it->itc->homogeneous)
8302 eina_hash_find(sd->size_caches, &(it->itc));
8304 eina_hash_del_by_key(sd->size_caches, it->itc);
8309 EOLIAN static Elm_Object_Select_Mode
8310 _elm_genlist_item_select_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8312 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
8314 return it->select_mode;
8317 EOLIAN Elm_Atspi_State_Set
8318 _elm_genlist_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_it, Elm_Gen_Item *it EINA_UNUSED)
8320 Elm_Atspi_State_Set ret;
8323 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
8325 eo_do(eo_it, sel = elm_obj_genlist_item_selected_get());
8327 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTABLE);
8330 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTED);
8332 if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_TREE)
8334 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDABLE);
8335 if (elm_genlist_item_expanded_get(eo_it))
8336 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8337 //TIZEN_ONLY(20160606): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8339 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8342 //TIZEN_ONLY(20160608): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8343 else if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_GROUP)
8345 if (elm_genlist_item_expanded_get(eo_it))
8346 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8348 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8356 _elm_genlist_item_elm_interface_atspi_accessible_name_get(Eo *eo_it,
8361 char *accessible_name;
8362 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_name_get());
8363 if (ret) return ret;
8364 Elm_Genlist_Item_Type genlist_item_type = elm_genlist_item_type_get(eo_it);
8366 //TIZEN ONLY (160609) : Added in order to read when group item contain checkbox, sub text and normal as per UX guide 0.3.
8367 Eina_List *children = NULL, *l;
8369 Eina_Bool flag_contain_checkbox = EINA_FALSE;
8370 eo_do(eo_it, children = elm_interface_atspi_accessible_children_get());
8371 EINA_LIST_FOREACH(children, l, item)
8373 if (eo_isa((item), ELM_CHECK_CLASS))
8375 flag_contain_checkbox = EINA_TRUE;
8381 buf = eina_strbuf_new();
8383 if (it->itc->func.text_get)
8389 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
8391 EINA_LIST_FREE(texts, key)
8393 char *str_markup = it->itc->func.text_get
8394 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
8395 char *str_utf8 = _elm_util_mkup_to_text(str_markup);
8399 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
8400 eina_strbuf_append(buf, str_utf8);
8406 //TIZEN ONLY (160609) : Added in order to read when group item contain checkbox, sub text and normal as per UX guide 0.3.
8407 if (((genlist_item_type & ELM_GENLIST_ITEM_GROUP) || (genlist_item_type & ELM_GENLIST_ITEM_TREE)) && !flag_contain_checkbox)
8408 eina_strbuf_append(buf,", header");
8411 accessible_name = eina_strbuf_string_steal(buf);
8412 eina_strbuf_free(buf);
8414 eina_stringshare_del(it->base->accessible_name);
8415 it->base->accessible_name = eina_stringshare_add(accessible_name);
8416 free(accessible_name);
8417 return it->base->accessible_name;
8421 _elm_genlist_item_elm_interface_atspi_accessible_children_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8423 Eina_List *ret = NULL;
8428 parts = elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "contents"));
8430 EINA_LIST_FREE(parts, key)
8433 part = edje_object_part_swallow_get(VIEW(it), key);
8434 if (part && eo_isa(part, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
8436 ret = eina_list_append(ret, part);
8437 eo_do(part, elm_interface_atspi_accessible_parent_set(eo_it));
8445 _elm_genlist_tree_effect_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enabled)
8447 sd->tree_effect_enabled = !!enabled;
8450 EOLIAN static Eina_Bool
8451 _elm_genlist_tree_effect_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8453 return sd->tree_effect_enabled;
8457 _elm_genlist_focus_on_selection_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enabled)
8459 sd->focus_on_selection_enabled = !!enabled;
8462 EOLIAN static Eina_Bool
8463 _elm_genlist_focus_on_selection_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8465 return sd->focus_on_selection_enabled;
8468 EAPI Elm_Object_Item *
8469 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth)
8471 Elm_Gen_Item *it = NULL;
8475 ELM_GENLIST_CHECK(obj) NULL;
8476 ELM_GENLIST_DATA_GET(obj, sd);
8478 if (!sd->items) return NULL;
8480 a = eina_inlist_accessor_new(sd->items);
8481 if (!a) return NULL;
8482 if (eina_accessor_data_get(a, nth, &data))
8483 it = ELM_GEN_ITEM_FROM_INLIST(data);
8484 eina_accessor_free(a);
8489 _elm_genlist_elm_widget_focus_highlight_geometry_get(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
8491 Evas_Coord ox, oy, oh, ow, item_x = 0, item_y = 0, item_w = 0, item_h = 0;
8493 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
8495 if (sd->focused_item)
8497 ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focus_it);
8498 evas_object_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
8499 elm_widget_focus_highlight_focus_part_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
8511 if (item_y > (oy + oh - item_h))
8513 *y = oy + oh - item_h;
8516 if ((item_x + item_w) > (ox + ow))
8526 EOLIAN static Elm_Object_Item *
8527 _elm_genlist_search_by_text_item_get(Eo *obj EINA_UNUSED,
8528 Elm_Genlist_Data *sd,
8529 Elm_Object_Item *item_to_search_from,
8530 const char *part_name,
8531 const char *pattern,
8532 Elm_Glob_Match_Flags flags)
8534 Elm_Gen_Item *it = NULL;
8536 Eina_Inlist *start = NULL;
8539 if (!pattern) return NULL;
8540 if (!sd->items) return NULL;
8542 if (flags & ELM_GLOB_MATCH_NO_ESCAPE) fnflags |= FNM_NOESCAPE;
8543 if (flags & ELM_GLOB_MATCH_PATH) fnflags |= FNM_PATHNAME;
8544 if (flags & ELM_GLOB_MATCH_PERIOD) fnflags |= FNM_PERIOD;
8546 if (flags & ELM_GLOB_MATCH_NOCASE) fnflags |= FNM_CASEFOLD;
8549 start = (item_to_search_from) ?
8550 EINA_INLIST_GET((Elm_Gen_Item *)eo_data_scope_get(item_to_search_from, ELM_GENLIST_ITEM_CLASS)) :
8552 EINA_INLIST_FOREACH(start, it)
8554 if (!it->itc->func.text_get) continue;
8555 str = it->itc->func.text_get((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), part_name);
8557 if (!fnmatch(pattern, str, fnflags))
8567 EOLIAN static Elm_Object_Item*
8568 _elm_genlist_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8570 return sd->focused_item;
8574 _elm_genlist_elm_widget_item_loop_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enable)
8576 sd->item_loop_enable = !!enable;
8579 EOLIAN static Eina_Bool
8580 _elm_genlist_elm_widget_item_loop_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8582 return sd->item_loop_enable;
8586 _elm_genlist_class_constructor(Eo_Class *klass)
8588 if (_elm_config->access_mode)
8589 _elm_genlist_smart_focus_next_enable = EINA_TRUE;
8591 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
8594 EOLIAN const Elm_Atspi_Action *
8595 _elm_genlist_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd EINA_UNUSED)
8597 static Elm_Atspi_Action atspi_actions[] = {
8598 { "move,prior", "move", "prior", _key_action_move},
8599 { "move,next", "move", "next", _key_action_move},
8600 { "move,left", "move", "left", _key_action_move},
8601 { "move,right", "move", "right", _key_action_move},
8602 { "move,up", "move", "up", _key_action_move},
8603 { "move,up,multi", "move", "up_multi", _key_action_move},
8604 { "move,down", "move", "down", _key_action_move},
8605 { "move,down,multi", "move", "down_multi", _key_action_move},
8606 { "move,first", "move", "first", _key_action_move},
8607 { "move,last", "move", "last", _key_action_move},
8608 { "select", "select", NULL, _key_action_select},
8609 { "select,multi", "select", "multi", _key_action_select},
8610 { "escape", "escape", NULL, _key_action_escape},
8611 { NULL, NULL, NULL, NULL }
8613 return &atspi_actions[0];
8617 _elm_genlist_elm_interface_atspi_accessible_children_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8619 Eina_List *ret = NULL;
8622 EINA_INLIST_FOREACH(sd->items, it)
8623 ret = eina_list_append(ret, EO_OBJ(it));
8628 EOLIAN Elm_Atspi_State_Set
8629 _elm_genlist_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED)
8631 Elm_Atspi_State_Set ret;
8633 eo_do_super(obj, ELM_GENLIST_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
8635 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MANAGES_DESCENDANTS);
8637 if (elm_genlist_multi_select_get(obj))
8638 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MULTISELECTABLE);
8640 //TIZEN_ONLY(20160520): genlist: added atspi support for drag n drop
8641 if (elm_genlist_reorder_mode_get(obj))
8642 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_ANIMATED);
8649 _elm_genlist_elm_interface_atspi_selection_selected_children_count_get(Eo *objm EINA_UNUSED, Elm_Genlist_Data *pd)
8651 return eina_list_count(pd->selected);
8655 _elm_genlist_elm_interface_atspi_selection_selected_child_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_idx)
8657 return eina_list_nth(pd->selected, child_idx);
8661 _elm_genlist_elm_interface_atspi_selection_child_select(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
8664 if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
8666 EINA_INLIST_FOREACH(pd->items, item)
8668 if (child_index-- == 0)
8670 elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
8679 _elm_genlist_elm_interface_atspi_selection_selected_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
8684 EINA_LIST_FOREACH(pd->selected, l, item)
8686 if (child_index-- == 0)
8688 elm_genlist_item_selected_set(item, EINA_FALSE);
8696 _elm_genlist_elm_interface_atspi_selection_is_child_selected(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
8700 EINA_INLIST_FOREACH(pd->items, item)
8702 if (child_index-- == 0)
8704 return elm_genlist_item_selected_get(EO_OBJ(item));
8711 _elm_genlist_elm_interface_atspi_selection_all_children_select(Eo *obj, Elm_Genlist_Data *pd)
8715 if (!elm_genlist_multi_select_get(obj))
8718 EINA_INLIST_FOREACH(pd->items, item)
8719 elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
8725 _elm_genlist_elm_interface_atspi_selection_clear(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd)
8727 return _all_items_deselect(pd);
8731 _elm_genlist_elm_interface_atspi_selection_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
8734 if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
8736 EINA_INLIST_FOREACH(pd->items, item)
8738 if (child_index-- == 0)
8740 elm_genlist_item_selected_set(EO_OBJ(item), EINA_FALSE);
8748 //TIZEN_ONLY(20160329): genlist: enhance accessibility scroll & highlight (30d9a6012e629cd9ea60eae8d576f3ebb94ada86)
8749 static int _is_item_in_viewport(int viewport_y, int viewport_h, int obj_y, int obj_h)
8751 if ((obj_y + obj_h/2) < viewport_y)
8753 else if ((obj_y + obj_h/2) > viewport_y + viewport_h)
8758 static Eina_Bool _atspi_enabled()
8761 Eina_Bool ret = EINA_FALSE;
8762 if (_elm_config->atspi_mode && (bridge = _elm_atspi_bridge_get()))
8763 eo_do(bridge, ret = elm_obj_atspi_bridge_connected_get());
8768 _elm_genlist_elm_interface_scrollable_content_pos_set(Eo *obj, Elm_Genlist_Data *sid EINA_UNUSED, Evas_Coord x, Evas_Coord y, Eina_Bool sig)
8770 if (!_atspi_enabled())
8772 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
8776 int old_x, old_y, delta_y;
8777 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_get(&old_x,&old_y));
8778 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
8779 delta_y = old_y - y;
8781 //check if highlighted item is genlist descendant
8782 Evas_Object * highlighted_obj = _elm_object_accessibility_currently_highlighted_get();
8783 if (eo_isa(highlighted_obj, ELM_WIDGET_ITEM_CLASS))
8785 Elm_Widget_Item_Data *id = eo_data_scope_get(highlighted_obj, ELM_WIDGET_ITEM_CLASS);
8786 highlighted_obj = id->view;
8789 Evas_Object *parent = highlighted_obj;
8790 if (eo_isa(highlighted_obj, ELM_WIDGET_CLASS))
8792 while ((parent = elm_widget_parent_get(parent)))
8796 else if (eo_isa(highlighted_obj, EDJE_OBJECT_CLASS))
8798 while ((parent = evas_object_smart_parent_get(parent)))
8802 // TIZEN_ONLY(20160805): set _accessibility_currently_highlighted_obj to NULL in object delete callback
8805 WRN("Improper highlighted object: %p", highlighted_obj);
8812 int obj_x, obj_y, w, h, hx, hy, hw, hh;
8813 evas_object_geometry_get(obj, &obj_x, &obj_y, &w, &h);
8815 evas_object_geometry_get(highlighted_obj, &hx, &hy, &hw, &hh);
8817 Elm_Gen_Item * next_previous_item = NULL;
8818 int viewport_position_result = _is_item_in_viewport(obj_y, h, hy, hh);
8819 //only highlight if move direction is correct
8820 //sometimes highlighted item is brought in and it does not fit viewport
8821 //however content goes to the viewport position so soon it will
8822 //meet _is_item_in_viewport condition
8823 if ((viewport_position_result < 0 && delta_y > 0) ||
8824 (viewport_position_result > 0 && delta_y < 0))
8827 Eina_List *realized_items = elm_genlist_realized_items_get(obj);
8830 Eina_Bool traverse_direction = viewport_position_result > 0;
8831 l = traverse_direction ? realized_items: eina_list_last(realized_items);
8835 item = eina_list_data_get(l);
8836 ELM_GENLIST_ITEM_DATA_GET(item, it_data);
8837 next_previous_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it_data));
8838 evas_object_geometry_get(VIEW(next_previous_item), &hx, &hy, &hw, &hh);
8839 if (_is_item_in_viewport(obj_y, h, hy, hh) == 0)
8842 next_previous_item = NULL;
8844 l = traverse_direction ? eina_list_next(l): eina_list_prev(l);
8847 if (next_previous_item)
8848 eo_do(EO_OBJ(next_previous_item), elm_interface_atspi_component_highlight_grab());
8852 EOLIAN static Eina_Bool
8853 _elm_genlist_item_elm_interface_atspi_component_highlight_grab(Eo *eo_it, Elm_Gen_Item *it)
8855 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8856 Eina_Bool ret = EINA_TRUE;
8858 // if item is realized check if in viewport
8861 Evas_Coord wy, wh, y, h;
8862 evas_object_geometry_get(WIDGET(it), NULL, &wy, NULL, &wh);
8863 evas_object_geometry_get(VIEW(it), NULL, &y, NULL, &h);
8864 int res = _is_item_in_viewport(wy, wh, y, h);
8867 // new item is above current
8868 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_BOTTOM);
8872 // new item is below current
8873 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
8876 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
8878 else // if item is not realized we should search if we are over or below viewport
8880 Eina_List *realized;
8881 int idx, top, bottom;
8882 realized = elm_genlist_realized_items_get(WIDGET(it));
8885 // index of realized element on top of viewport
8886 eo_do(eina_list_nth(realized, 0), top = elm_obj_genlist_item_index_get());
8887 // index of realized element on bottom of viewport
8888 eo_do(eina_list_last_data_get(realized), bottom = elm_obj_genlist_item_index_get());
8889 eo_do(eo_it, idx = elm_obj_genlist_item_index_get());
8890 eina_list_free(realized);
8892 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_BOTTOM);
8893 else if (idx > bottom)
8894 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
8896 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
8901 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_component_highlight_grab());
8903 sd->atspi_item_to_highlight = it;//it will be highlighted when realized
8905 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_it);
8910 EOLIAN static Eina_Bool
8911 _elm_genlist_item_elm_interface_atspi_component_highlight_clear(Eo *eo_it, Elm_Gen_Item *it)
8914 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8915 if (sd->atspi_item_to_highlight == it)
8916 sd->atspi_item_to_highlight = NULL;
8918 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_it);
8920 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_component_highlight_clear());
8925 //Tizen Only(20170113) : Below Legacy APIs are Mobile Only Feature
8927 elm_genlist_realization_mode_set(Evas_Object *obj EINA_UNUSED, Eina_Bool mode EINA_UNUSED)
8929 // Mobile Only Feature;
8934 elm_genlist_realization_mode_get(Evas_Object *obj EINA_UNUSED)
8936 // Mobile Only Feature;
8941 elm_genlist_item_reorder_start(Elm_Object_Item *item EINA_UNUSED)
8943 // Mobile Only Feature;
8948 elm_genlist_item_reorder_stop(Elm_Object_Item *item EINA_UNUSED)
8950 // Mobile Only Feature;
8955 #include "elm_genlist.eo.c"
8956 #include "elm_genlist_item.eo.c"