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 Eina_Bool _item_process(Elm_Genlist_Data *sd, Elm_Gen_Item *it);
175 static void _item_process_post(Elm_Genlist_Data *sd, Elm_Gen_Item *it,Eina_Bool qadd);
177 static const Elm_Action key_actions[] = {
178 {"move", _key_action_move},
179 {"select", _key_action_select},
180 {"escape", _key_action_escape},
185 _size_cache_free(void *data)
191 _is_no_select(Elm_Gen_Item *it)
193 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
195 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
196 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
197 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
198 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
204 _elm_genlist_pan_elm_pan_pos_set(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord x, Evas_Coord y)
208 Elm_Genlist_Data *sd = psd->wsd;
210 if ((x == sd->pan_x) && (y == sd->pan_y)) return;
214 EINA_INLIST_FOREACH(sd->blocks, itb)
216 if ((itb->y + itb->h) > y)
221 EINA_LIST_FOREACH(itb->items, l2, it)
223 if ((itb->y + it->y) >= y)
225 sd->anchor_item = it;
226 sd->anchor_y = -(itb->y + it->y - y);
233 if (!sd->reorder_move_animator) evas_object_smart_changed(obj);
237 _elm_genlist_pan_elm_pan_pos_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y)
239 if (x) *x = psd->wsd->pan_x;
240 if (y) *y = psd->wsd->pan_y;
244 _elm_genlist_pan_elm_pan_pos_max_get(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y)
248 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
249 ow = psd->wsd->minw - ow;
251 oh = psd->wsd->minh - oh;
258 _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)
265 _elm_genlist_pan_elm_pan_content_size_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *w, Evas_Coord *h)
267 if (w) *w = psd->wsd->minw;
268 if (h) *h = psd->wsd->minh;
271 //Tizen Only(20170113)
273 _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)
280 _elm_genlist_pan_evas_object_smart_del(Eo *obj, Elm_Genlist_Pan_Data *psd)
282 ecore_job_del(psd->resize_job);
284 eo_do_super(obj, MY_PAN_CLASS, evas_obj_smart_del());
288 _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)
290 psd->wsd->pan_changed = EINA_TRUE;
291 evas_object_smart_changed(obj);
292 ELM_SAFE_FREE(psd->wsd->calc_job, ecore_job_del);
296 _elm_genlist_pan_smart_resize_job(void *data)
298 ELM_GENLIST_PAN_DATA_GET(data, psd);
300 elm_layout_sizing_eval(psd->wobj);
301 psd->resize_job = NULL;
305 _elm_genlist_pan_evas_object_smart_resize(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord w, Evas_Coord h)
309 Elm_Genlist_Data *sd = psd->wsd;
311 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
312 if ((ow == w) && (oh == h)) return;
313 if ((sd->mode == ELM_LIST_COMPRESS || sd->mode == ELM_LIST_SCROLL) && (ow != w))
316 ecore_job_del(psd->resize_job);
318 ecore_job_add(_elm_genlist_pan_smart_resize_job, obj);
320 sd->pan_changed = EINA_TRUE;
321 evas_object_smart_changed(obj);
322 ecore_job_del(sd->calc_job);
323 // if the width changed we may have to resize content if scrollbar went
324 // away or appeared to queue a job to deal with it. it should settle in
325 // the end to a steady-state
327 sd->calc_job = ecore_job_add(_calc_job, psd->wobj);
333 _item_text_realize(Elm_Gen_Item *it,
343 if (!it->itc->func.text_get) return;
346 *source = elm_widget_stringlist_get
347 (edje_object_data_get(target, "texts"));
348 EINA_LIST_FOREACH(*source, l, key)
350 if (parts && fnmatch(parts, key, FNM_PERIOD)) continue;
352 s = it->itc->func.text_get
353 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
356 edje_object_part_text_escaped_set(target, key, s);
359 snprintf(buf, sizeof(buf), "elm,state,%s,visible", key);
360 edje_object_signal_emit(target, buf, "elm");
364 edje_object_part_text_set(target, key, "");
365 snprintf(buf, sizeof(buf), "elm,state,%s,hidden", key);
366 edje_object_signal_emit(target, buf, "elm");
368 if (_elm_config->atspi_mode)
369 elm_interface_atspi_accessible_name_changed_signal_emit(EO_OBJ(it));
374 _widget_calculate_recursive(Eo *obj)
376 Elm_Widget_Smart_Data *pd = NULL;
380 if (!eo_isa(obj, ELM_WIDGET_CLASS)) return;
382 pd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
385 if (!evas_object_smart_need_recalculate_get(obj) &&
386 !evas_object_smart_need_recalculate_get(pd->resize_obj))
389 EINA_LIST_FOREACH(pd->subobjs, l, child)
390 _widget_calculate_recursive(child);
392 evas_object_smart_calculate(obj);
396 _item_content_realize(Elm_Gen_Item *it,
398 Eina_List **contents,
403 Evas_Object *content;
410 EINA_LIST_FREE(*contents, content)
411 evas_object_del(content);
413 if ((!it->itc->func.content_get) &&
414 ((it->itc->version < 3) || (!it->itc->func.reusable_content_get))) return;
416 source = elm_widget_stringlist_get(edje_object_data_get(target, src));
418 EINA_LIST_FREE(source, key)
420 if (parts && fnmatch(parts, key, FNM_PERIOD))
423 Evas_Object *old = NULL;
424 old = edje_object_part_swallow_get(target, key);
426 // Reuse content by popping from the cache
428 if (it->itc->version >= 3 && it->itc->func.reusable_content_get)
429 content = it->itc->func.reusable_content_get(
430 (void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key, old);
433 // Call the content get
434 if (it->itc->func.content_get)
435 content = it->itc->func.content_get
436 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
439 snprintf(buf, sizeof(buf), "elm,state,%s,hidden", key);
440 edje_object_signal_emit(target, buf, "elm");
447 // FIXME: Genlist item doesn't update its size when the size of
448 // content is changed, so deferred calculation for content should
449 // be performed before realization.
450 if (eo_isa(content, ELM_WIDGET_CLASS))
452 ELM_WIDGET_DATA_GET_OR_RETURN(content, wd);
454 // FIXME : Layout need sizing eval before group calculate
455 if (eo_class_get(content) == ELM_LAYOUT_CLASS)
456 eo_do(content, elm_obj_layout_sizing_eval());
458 _widget_calculate_recursive(content);
461 if (!edje_object_part_swallow(target, key, content))
463 ERR("%s (%p) can not be swallowed into %s",
464 evas_object_type_get(content), content, key);
465 evas_object_del(content);
468 elm_widget_sub_object_add(WIDGET(it), content);
470 *contents = eina_list_append(*contents, content);
472 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()))
473 elm_widget_disabled_set(content, EINA_TRUE);
475 snprintf(buf, sizeof(buf), "elm,state,%s,visible", key);
476 edje_object_signal_emit(target, buf, "elm");
478 if (old && content != old)
480 *contents = eina_list_remove(*contents, old);
481 evas_object_del(old);
484 if (_elm_config->atspi_mode && eo_isa(content, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
486 eo_do(content, elm_interface_atspi_accessible_parent_set(EO_OBJ(it)));
487 elm_interface_atspi_accessible_children_changed_added_signal_emit(EO_OBJ(it), content);
493 _item_state_realize(Elm_Gen_Item *it, Evas_Object *target, const char *parts)
499 if (!it->itc->func.state_get) return;
501 src = elm_widget_stringlist_get(edje_object_data_get(target, "states"));
502 EINA_LIST_FREE(src, key)
504 if (parts && fnmatch(parts, key, FNM_PERIOD)) continue;
506 Eina_Bool on = it->itc->func.state_get
507 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
511 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
512 edje_object_signal_emit(target, buf, "elm");
516 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
517 edje_object_signal_emit(target, buf, "elm");
520 edje_object_message_signal_process(target);
524 * Apply the right style for the created item view.
526 // TIZEN_ONLY(20150622): update genlist style set
528 _view_style_find(Elm_Gen_Item *it, Evas_Object *view, const char *style)
532 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
534 // FIXME: There exists
535 // item, item_compress, item_odd, item_compress_odd,
536 // tree, tree_compress, tree_odd, tree_odd_compress
537 // But those used case by case. :-(
538 // Anyway, belows codes are for backward..
539 if (it->decorate_it_set)
541 // item, item_compress, item_odd, item_compress_odd
542 strncpy(buf, "item", sizeof(buf));
543 if (sd->mode == ELM_LIST_COMPRESS)
544 strncat(buf, "_compress", sizeof(buf) - strlen(buf) - 1);
546 if (it->item->order_num_in & 0x1)
547 strncat(buf, "_odd", sizeof(buf) - strlen(buf) - 1);
548 strncat(buf, "/", sizeof(buf) - strlen(buf) - 1);
549 strncat(buf, style, sizeof(buf) - strlen(buf) - 1);
553 // item, item_compress, tree, tree_compress
554 if (it->item->type & ELM_GENLIST_ITEM_TREE)
555 snprintf(buf, sizeof(buf), "tree%s/%s",
556 sd->mode == ELM_LIST_COMPRESS ? "_compress" :
557 "", style ? : "default");
559 snprintf(buf, sizeof(buf), "item%s/%s",
560 sd->mode == ELM_LIST_COMPRESS ? "_compress" :
561 "",style ? : "default");
563 Elm_Theme_Apply th_ret =
564 elm_widget_theme_object_set(WIDGET(it), view, "genlist", buf,
565 elm_widget_style_get(WIDGET(it)));
566 if (th_ret == ELM_THEME_APPLY_FAILED)
568 snprintf(buf2, sizeof(buf2), "item/%s", style ? : "default");
569 ERR("%s is not a valid genlist item style. fallback to %s", buf, buf2);
570 if (!strcmp(buf, buf2)) return EINA_FALSE;
571 th_ret = elm_widget_theme_object_set(WIDGET(it), view, "genlist", buf2,
572 elm_widget_style_get(WIDGET(it)));
573 if (th_ret == ELM_THEME_APPLY_FAILED) return EINA_FALSE;
581 _view_style_update(Elm_Gen_Item *it, Evas_Object *view, const char *style)
583 const char *stacking_even;
584 const char *stacking;
586 // TIZEN_ONLY(20150622): update genlist style set
587 if (!_view_style_find(it, view, style))
590 ERR("%s is not a valid genlist item style. "
591 "Automatically falls back into default style.",
593 elm_widget_theme_object_set
594 (WIDGET(it), view, "genlist", "item/default", "default");
597 edje_object_mirrored_set(view, elm_widget_mirrored_get(WIDGET(it)));
598 edje_object_scale_set(view, elm_widget_scale_get(WIDGET(it))
599 * elm_config_scale_get());
601 stacking_even = edje_object_data_get(view, "stacking_even");
602 if (!stacking_even) stacking_even = "above";
603 it->item->stacking_even = !!strcmp("above", stacking_even);
605 stacking = edje_object_data_get(view, "stacking");
606 if (!stacking) stacking = "yes";
607 it->item->nostacking = !!strcmp("yes", stacking);
611 * Create a VIEW(it) during _item_realize()
614 _view_create(Elm_Gen_Item *it, const char *style)
616 Evas_Object *view = edje_object_add(evas_object_evas_get(WIDGET(it)));
617 evas_object_smart_member_add(view, GL_IT(it)->wsd->pan_obj);
618 elm_widget_sub_object_add(WIDGET(it), view);
619 edje_object_scale_set(view, elm_widget_scale_get(WIDGET(it)) *
620 elm_config_scale_get());
622 _view_style_update(it, view, style);
627 _view_clear(Evas_Object *view, Eina_List **texts, Eina_List **contents)
633 EINA_LIST_FOREACH(*texts, l, part)
634 edje_object_part_text_set(view, part, NULL);
635 ELM_SAFE_FREE(*texts, elm_widget_stringlist_free);
639 EINA_LIST_FREE(*contents, c)
645 _item_scroll(Elm_Genlist_Data *sd)
648 Elm_Gen_Item *it = NULL;
649 Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0;
651 if (!sd->show_item) return;
653 evas_object_geometry_get(sd->pan_obj, NULL, NULL, &ow, &oh);
655 dx = it->x + it->item->block->x;
656 dy = it->y + it->item->block->y;
657 dw = it->item->block->w;
660 // hold on scrolling to item until block size calculation is finished.
663 switch (sd->scroll_to_type)
665 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
666 if (it->item->group_item) gith = it->item->group_item->item->h;
670 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
671 dy += ((it->item->h / 2) - (oh / 2));
674 case ELM_GENLIST_ITEM_SCROLLTO_IN:
676 if ((sd->expanded_item) &&
677 ((sd->show_item->y + sd->show_item->item->block->y
678 + sd->show_item->item->h) -
679 (sd->expanded_item->y + sd->expanded_item->item->block->y) > oh))
681 it = sd->expanded_item;
682 if (it->item->group_item) gith = it->item->group_item->item->h;
683 dx = it->x + it->item->block->x;
684 dy = it->y + it->item->block->y - gith;
685 dw = it->item->block->w;
689 if ((it->item->group_item) &&
690 (sd->pan_y > (it->y + it->item->block->y)))
691 gith = it->item->group_item->item->h;
698 eo_do(sd->obj, elm_interface_scrollable_region_bring_in(dx, dy, dw, dh));
700 eo_do(sd->obj, elm_interface_scrollable_content_region_show
703 it->item->show_me = EINA_FALSE;
704 sd->show_item = NULL;
705 sd->auto_scroll_enabled = EINA_FALSE;
706 sd->check_scroll = EINA_FALSE;
710 _elm_genlist_item_unrealize(Elm_Gen_Item *it,
713 if (!it->realized) return;
714 if (GL_IT(it)->wsd->reorder_it == it)
716 WRN("reordering item should not be unrealized");
720 evas_event_freeze(evas_object_evas_get(WIDGET(it)));
722 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_UNREALIZED, EO_OBJ(it)));
723 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
725 _view_clear(VIEW(it), &(it->texts), NULL);
726 ELM_SAFE_FREE(it->item_focus_chain, eina_list_free);
728 eo_do(EO_OBJ(it), elm_wdg_item_track_cancel());
732 it->realized = EINA_FALSE;
733 it->want_unrealize = EINA_FALSE;
735 evas_event_thaw(evas_object_evas_get(WIDGET(it)));
736 evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
740 _item_block_unrealize(Item_Block *itb)
744 Eina_Bool dragging = EINA_FALSE;
746 if (!itb->realized) return;
747 evas_event_freeze(evas_object_evas_get((itb->sd)->obj));
749 EINA_LIST_FOREACH(itb->items, l, it)
751 if (itb->must_recalc || !(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP))
755 dragging = EINA_TRUE;
756 it->want_unrealize = EINA_TRUE;
759 _elm_genlist_item_unrealize(it, EINA_FALSE);
764 itb->realized = EINA_FALSE;
765 itb->want_unrealize = EINA_TRUE;
768 itb->want_unrealize = EINA_FALSE;
769 evas_event_thaw(evas_object_evas_get((itb->sd)->obj));
770 evas_event_thaw_eval(evas_object_evas_get((itb->sd)->obj));
774 _must_recalc_idler(void *data)
776 ELM_GENLIST_DATA_GET(data, sd);
778 ecore_job_del(sd->calc_job);
779 sd->calc_job = ecore_job_add(_calc_job, data);
780 sd->must_recalc_idler = NULL;
781 return ECORE_CALLBACK_CANCEL;
785 _calc_job(void *data)
788 Item_Block *itb, *chb = NULL;
789 Evas_Coord pan_w = 0, pan_h = 0;
790 ELM_GENLIST_DATA_GET(data, sd);
791 Eina_Bool minw_change = EINA_FALSE;
792 Eina_Bool did_must_recalc = EINA_FALSE;
793 Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0, vw = 0;
795 evas_object_geometry_get(sd->pan_obj, NULL, NULL, &ow, &sd->h);
796 if (sd->mode == ELM_LIST_COMPRESS)
797 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
798 (NULL, NULL, &vw, NULL));
800 if (sd->w != ow) sd->w = ow;
802 evas_event_freeze(evas_object_evas_get(sd->obj));
803 EINA_INLIST_FOREACH(sd->blocks, itb)
805 Eina_Bool show_me = EINA_FALSE;
808 show_me = itb->show_me;
809 itb->show_me = EINA_FALSE;
812 // TIZEN_ONLY(20170106): Fix focus flicking issue when item is prepended
813 if (itb->realized) _item_block_recalc(itb, in, EINA_FALSE);
815 if ((itb->changed) || ((itb->must_recalc) && (!did_must_recalc)))
817 if (itb->must_recalc)
822 EINA_LIST_FOREACH(itb->items, l, it)
823 it->item->mincalcd = EINA_FALSE;
824 itb->changed = EINA_TRUE;
825 did_must_recalc = EINA_TRUE;
826 if (itb->realized) _item_block_unrealize(itb);
827 itb->must_recalc = EINA_FALSE;
829 show_me = _item_block_recalc(itb, in, EINA_FALSE);
835 if (minw < itb->minw)
839 minw_change = EINA_TRUE;
841 if ((sd->mode == ELM_LIST_COMPRESS) && (minw > vw))
844 minw_change = EINA_TRUE;
850 if ((show_me) && (sd->show_item) && (!sd->show_item->item->queued))
851 sd->check_scroll = EINA_TRUE;
855 EINA_INLIST_FOREACH(sd->blocks, itb)
862 if (minw < sd->w) minw = sd->w;
863 if ((minw != sd->minw) || (minh != sd->minh))
867 eo_do(sd->pan_obj, eo_event_callback_call
868 (ELM_PAN_EVENT_CHANGED, NULL));
869 elm_layout_sizing_eval(sd->obj);
876 if ((sd->anchor_item) && (sd->anchor_item->item->block)
877 && (!sd->auto_scroll_enabled))
882 it = sd->anchor_item;
884 eo_do(sd->obj, elm_interface_scrollable_content_pos_set
885 (sd->pan_x, it->item->block->y
886 + it->y + it_y, EINA_TRUE));
887 sd->anchor_item = it;
893 if (!sd->must_recalc_idler)
894 sd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, data);
896 if (!sd->show_item) sd->check_scroll = EINA_FALSE;
897 if (sd->check_scroll)
899 eo_do(sd->pan_obj, elm_obj_pan_content_size_get(&pan_w, &pan_h));
900 if (EINA_INLIST_GET(sd->show_item) == sd->items->last)
901 sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
903 switch (sd->scroll_to_type)
905 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
909 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
913 case ELM_GENLIST_ITEM_SCROLLTO_IN:
918 if ((sd->show_item) && (sd->show_item->item->block))
920 if ((pan_w > (sd->show_item->x + sd->show_item->item->block->x))
921 && (pan_h > (sd->show_item->y + sd->show_item->item->block->y
930 evas_object_smart_changed(sd->pan_obj);
931 evas_event_thaw(evas_object_evas_get(sd->obj));
932 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
936 _elm_genlist_elm_layout_sizing_eval(Eo *obj, Elm_Genlist_Data *sd)
938 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
939 Evas_Coord vmw = 0, vmh = 0;
941 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
943 if (sd->on_sub_del) return;;
945 evas_object_size_hint_min_get(obj, &minw, NULL);
946 evas_object_size_hint_max_get(obj, &maxw, &maxh);
948 edje_object_size_min_calc(wd->resize_obj, &vmw, &vmh);
950 if (sd->mode == ELM_LIST_COMPRESS || sd->mode == ELM_LIST_SCROLL)
952 Evas_Coord vw = 0, vh = 0;
954 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
955 (NULL, NULL, &vw, &vh));
956 if ((vw != 0) && (vw != sd->prev_viewport_w))
960 sd->prev_viewport_w = vw;
961 /* Free all buckets for updaing changed width */
962 eina_hash_free_buckets(sd->size_caches);
964 EINA_INLIST_FOREACH(sd->blocks, itb)
966 itb->must_recalc = EINA_TRUE;
968 ecore_job_del(sd->calc_job);
969 sd->calc_job = ecore_job_add(_calc_job, obj);
978 minw = vmw + sd->realminw;
987 minh = vmh + sd->minh;
995 if ((maxw > 0) && (minw > maxw))
997 if ((maxh > 0) && (minh > maxh))
1000 evas_object_size_hint_min_set(obj, minw, minh);
1001 evas_object_size_hint_max_set(obj, maxw, maxh);
1005 _content_min_limit_cb(Evas_Object *obj,
1009 ELM_GENLIST_DATA_GET(obj, sd);
1011 if ((sd->mode == ELM_LIST_LIMIT) ||
1012 (sd->mode == ELM_LIST_EXPAND)) return;
1016 elm_layout_sizing_eval(obj);
1020 _item_contract_emit(Elm_Object_Item *eo_it)
1022 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
1023 Elm_Object_Item *eo_it2;
1027 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACT_FLIP, "");
1028 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACT_FLIP, "elm");
1029 it->item->tree_effect_finished = EINA_FALSE;
1031 EINA_LIST_FOREACH(it->item->items, l, eo_it2)
1032 if (eo_it2) _item_contract_emit(eo_it2);
1036 _item_tree_effect_before(Elm_Gen_Item *it)
1038 Elm_Object_Item *eo_it2;
1040 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1042 EINA_LIST_FOREACH(it->item->items, l, eo_it2)
1044 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
1045 if (it2->parent && (it == it2->parent))
1048 it2->item->tree_effect_hide_me = EINA_TRUE;
1049 if (sd->move_effect_mode ==
1050 ELM_GENLIST_TREE_EFFECT_EXPAND)
1053 edje_object_signal_emit(VIEW(it2), SIGNAL_HIDE, "");
1054 edje_object_signal_emit(VIEW(it2), SIGNAL_HIDE, "elm");
1056 else if (sd->move_effect_mode ==
1057 ELM_GENLIST_TREE_EFFECT_CONTRACT)
1058 _item_contract_emit(eo_it2);
1061 return ECORE_CALLBACK_CANCEL;
1065 _item_position(Elm_Gen_Item *it,
1072 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1074 Evas_Object * highlighted_obj = _elm_object_accessibility_currently_highlighted_get();
1075 if (eo_isa(highlighted_obj, ELM_WIDGET_ITEM_CLASS))
1077 Elm_Widget_Item_Data *id = eo_data_scope_get(highlighted_obj, ELM_WIDGET_ITEM_CLASS);
1078 highlighted_obj = id->view;
1081 highlighted_obj = NULL;
1083 if (highlighted_obj && view == highlighted_obj)
1086 evas_object_geometry_get(sd->obj, &x, &y, &w, &h);
1088 Elm_Gen_Item * next_previous_item = NULL;
1089 if ((it_y + GL_IT(it)->h/2) < y)
1091 next_previous_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
1093 else if ((it_y + GL_IT(it)->h/2) > y + h)
1095 next_previous_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
1098 if (next_previous_item)
1099 eo_do(EO_OBJ(next_previous_item), elm_interface_atspi_component_highlight_grab());
1103 (evas_object_evas_get(sd->obj));
1104 evas_object_resize(view, it->item->w, it->item->h);
1105 evas_object_move(view, it_x, it_y);
1106 evas_object_show(view);
1107 evas_event_thaw(evas_object_evas_get(sd->obj));
1108 evas_event_thaw_eval
1109 (evas_object_evas_get(sd->obj));
1113 _item_tree_effect(Elm_Genlist_Data *sd,
1116 Elm_Gen_Item *expanded_next_it;
1117 Elm_Object_Item *eo_it;
1119 expanded_next_it = sd->expanded_next_item;
1121 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
1123 eo_it = elm_genlist_item_prev_get(EO_OBJ(expanded_next_it));
1126 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
1127 if (it->item->expanded_depth <=
1128 expanded_next_it->item->expanded_depth) break;
1129 if (it->item->scrl_y &&
1130 (it->item->scrl_y <= expanded_next_it->item->old_scrl_y + y)
1131 && (it->item->expanded_depth >
1132 expanded_next_it->item->expanded_depth))
1134 if (!it->item->tree_effect_finished)
1137 edje_object_signal_emit(VIEW(it), "flip_item", "");
1138 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ITEM,
1141 (it, VIEW(it), it->item->scrl_x, it->item->scrl_y);
1142 it->item->tree_effect_finished = EINA_TRUE;
1145 eo_it = elm_genlist_item_prev_get(eo_it);
1148 else if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
1150 eo_it = elm_genlist_item_prev_get(EO_OBJ(expanded_next_it));
1153 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
1154 if ((it->item->scrl_y > expanded_next_it->item->old_scrl_y + y) &&
1155 (it->item->expanded_depth >
1156 expanded_next_it->item->expanded_depth))
1158 if (!it->item->tree_effect_finished)
1161 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "");
1162 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "elm");
1163 it->item->tree_effect_finished = EINA_TRUE;
1168 eo_it = elm_genlist_item_prev_get(eo_it);
1174 _item_sub_items_clear(Elm_Gen_Item *it)
1176 Eina_List *tl = NULL, *l;
1177 Elm_Object_Item *eo_it2;
1179 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
1181 EINA_LIST_FOREACH(it->item->items, l, eo_it2)
1182 tl = eina_list_append(tl, eo_it2);
1183 EINA_LIST_FREE(tl, eo_it2)
1184 eo_do(eo_it2, elm_wdg_item_del());
1188 _item_auto_scroll(Elm_Genlist_Data *sd)
1190 Elm_Object_Item *eo_tmp_item = NULL;
1192 if ((sd->expanded_item) && (sd->auto_scroll_enabled))
1194 eo_tmp_item = eina_list_data_get
1195 (eina_list_last(sd->expanded_item->item->items));
1196 if (!eo_tmp_item) return;
1197 ELM_GENLIST_ITEM_DATA_GET(eo_tmp_item, tmp_item);
1198 sd->show_item = tmp_item;
1199 sd->bring_in = EINA_TRUE;
1200 sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
1201 if ((sd->show_item->item->queued) || (!sd->show_item->item->mincalcd))
1203 sd->show_item->item->show_me = EINA_TRUE;
1204 sd->auto_scroll_enabled = EINA_FALSE;
1212 _item_tree_effect_finish(Elm_Genlist_Data *sd)
1214 Elm_Object_Item *eo_it = NULL;
1220 if (sd->tree_effect_animator)
1222 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
1223 _item_sub_items_clear(sd->expanded_item);
1225 EINA_LIST_FOREACH(sd->expanded_item->item->items, l, eo_it)
1227 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
1228 it->item->tree_effect_finished = EINA_TRUE;
1229 it->item->old_scrl_y = it->item->scrl_y;
1230 if (GL_IT(it)->wsd->move_effect_mode ==
1231 ELM_GENLIST_TREE_EFFECT_EXPAND)
1234 edje_object_signal_emit(VIEW(it), SIGNAL_SHOW, "");
1235 edje_object_signal_emit(VIEW(it), SIGNAL_SHOW, "elm");
1238 if (sd->move_effect_mode ==
1239 ELM_GENLIST_TREE_EFFECT_EXPAND)
1241 EINA_INLIST_FOREACH(sd->blocks, itb)
1243 EINA_LIST_FOREACH(itb->items, l, it1)
1245 if (it1->item->scrl_y <= y)
1247 it1->item->scrl_y = y + it1->item->h;
1248 _elm_genlist_item_unrealize(it1, EINA_FALSE);
1250 y = it1->item->scrl_y;
1256 _item_auto_scroll(sd);
1257 evas_object_lower(sd->event_block_rect);
1258 evas_object_hide(sd->event_block_rect);
1259 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
1260 sd->move_items = eina_list_free(sd->move_items);
1262 eo_do(sd->pan_obj, eo_event_callback_call(ELM_PAN_EVENT_CHANGED, NULL));
1263 eo_do(sd->obj, eo_event_callback_call
1264 (ELM_GENLIST_EVENT_TREE_EFFECT_FINISHED, NULL));
1265 evas_object_smart_changed(sd->pan_obj);
1267 sd->tree_effect_animator = NULL;
1271 _elm_genlist_item_position_state_update(Elm_Gen_Item *it)
1273 unsigned idx = it->item->order_num_in;
1275 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1277 if (!it->item->nostacking)
1279 if ((idx & 0x1) ^ it->item->stacking_even)
1281 if (it->deco_all_view) evas_object_stack_below(it->deco_all_view, sd->stack[0]);
1282 else evas_object_stack_below(VIEW(it), sd->stack[0]);
1286 if (it->deco_all_view) evas_object_stack_above(it->deco_all_view, sd->stack[0]);
1287 else evas_object_stack_above(VIEW(it), sd->stack[0]);
1293 edje_object_signal_emit(VIEW(it), SIGNAL_ODD, "elm");
1294 if (it->deco_all_view)
1295 edje_object_signal_emit(it->deco_all_view, SIGNAL_ODD, "elm");
1299 edje_object_signal_emit(VIEW(it), SIGNAL_EVEN, "elm");
1300 if (it->deco_all_view)
1301 edje_object_signal_emit(it->deco_all_view, SIGNAL_EVEN, "elm");
1304 if (sd->item_count == 1)
1306 edje_object_signal_emit(VIEW(it), SIGNAL_LIST_SINGLE, "elm");
1307 if (it->deco_all_view)
1308 edje_object_signal_emit(it->deco_all_view, SIGNAL_LIST_SINGLE, "elm");
1312 edje_object_signal_emit(VIEW(it), SIGNAL_LIST_FIRST, "elm");
1313 if (it->deco_all_view)
1314 edje_object_signal_emit(it->deco_all_view, SIGNAL_LIST_FIRST, "elm");
1316 else if (idx == sd->item_count - 1)
1318 edje_object_signal_emit(VIEW(it), SIGNAL_LIST_LAST, "elm");
1319 if (it->deco_all_view)
1320 edje_object_signal_emit(it->deco_all_view, SIGNAL_LIST_LAST, "elm");
1324 edje_object_signal_emit(VIEW(it), SIGNAL_LIST_MIDDLE, "elm");
1325 if (it->deco_all_view)
1326 edje_object_signal_emit(it->deco_all_view, SIGNAL_LIST_MIDDLE, "elm");
1331 unsigned first_idx = it->parent->item->order_num_in + 1;
1332 unsigned count = eina_list_count(it->parent->item->items);
1336 edje_object_signal_emit(VIEW(it), SIGNAL_GROUP_SINGLE, "elm");
1337 if (it->deco_all_view)
1338 edje_object_signal_emit(it->deco_all_view, SIGNAL_GROUP_SINGLE,
1341 else if (idx == first_idx)
1343 edje_object_signal_emit(VIEW(it), SIGNAL_GROUP_FIRST, "elm");
1344 if (it->deco_all_view)
1345 edje_object_signal_emit(it->deco_all_view, SIGNAL_GROUP_FIRST,
1348 else if (EO_OBJ(it) == eina_list_data_get(eina_list_last(it->parent->item->items)))
1350 edje_object_signal_emit(VIEW(it), SIGNAL_GROUP_LAST, "elm");
1351 if (it->deco_all_view)
1352 edje_object_signal_emit(it->deco_all_view, SIGNAL_GROUP_LAST,
1355 else if (idx > first_idx)
1357 edje_object_signal_emit(VIEW(it), SIGNAL_GROUP_MIDDLE, "elm");
1358 if (it->deco_all_view)
1359 edje_object_signal_emit(it->deco_all_view, SIGNAL_GROUP_MIDDLE,
1366 _item_order_update(const Eina_Inlist *l,
1369 Elm_Gen_Item *it, *it2;
1372 * always update position state of previous item, it may have been
1373 * marked as "single" if it was the only element at the time, or
1374 * "middle", "first" or "last" in the case of insert into different
1377 if ((l->prev) && (start > 0))
1379 it = ELM_GEN_ITEM_FROM_INLIST(l->prev);
1380 it->item->order_num_in = start - 1;
1381 _elm_genlist_item_position_state_update(it);
1384 for (it = ELM_GEN_ITEM_FROM_INLIST(l); l; l = l->next,
1385 it = ELM_GEN_ITEM_FROM_INLIST(l))
1387 it->item->order_num_in = start++;
1388 _elm_genlist_item_position_state_update(it);
1389 it2 = ELM_GEN_ITEM_FROM_INLIST(l->next);
1390 if (it2 && (it->item->order_num_in != it2->item->order_num_in))
1396 _elm_genlist_item_state_update(Elm_Gen_Item *it)
1399 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1402 edje_object_signal_emit(VIEW(it), SIGNAL_SELECTED, "elm");
1403 if (it->deco_all_view)
1404 edje_object_signal_emit
1405 (it->deco_all_view, SIGNAL_SELECTED, "elm");
1407 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()))
1409 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
1410 if (it->deco_all_view)
1411 edje_object_signal_emit
1412 (it->deco_all_view, SIGNAL_DISABLED, "elm");
1414 if (it->item->expanded)
1416 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
1417 if (it->deco_all_view)
1418 edje_object_signal_emit
1419 (it->deco_all_view, SIGNAL_EXPANDED, "elm");
1421 // TIZEN_ONLY(20161206) : Fix duplicated focused signal emit
1422 //if ((EO_OBJ(it) == sd->focused_item) &&
1423 // (elm_widget_focus_highlight_enabled_get(WIDGET(it)) || _elm_config->win_auto_focus_enable))
1424 // edje_object_signal_emit(VIEW(it), SIGNAL_FOCUSED, "elm");
1429 _view_inflate(Evas_Object *view, Elm_Gen_Item *it, Eina_List **sources,
1430 Eina_List **contents)
1433 if (sources) _item_text_realize(it, view, sources, NULL);
1434 if (contents) _item_content_realize(it, view, contents, "contents", NULL);
1435 _item_state_realize(it, view, NULL);
1439 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1441 if (it->position_update || GL_IT(it)->block->position_update)
1443 eo_do(WIDGET(it), eo_event_callback_call
1444 (ELM_GENLIST_EVENT_INDEX_UPDATE, EO_OBJ(it)));
1445 it->position_update = EINA_FALSE;
1450 _decorate_all_item_position(Elm_Gen_Item *it,
1454 if ((!it) || (!GL_IT(it)->wsd->decorate_all_mode)) return;
1455 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
1456 evas_object_move(it->deco_all_view, itx, ity);
1460 _decorate_all_item_realize(Elm_Gen_Item *it,
1461 Eina_Bool effect_on)
1464 const char *stacking;
1465 const char *stacking_even;
1468 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1470 if (it->item->decorate_all_item_realized) return;
1472 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
1473 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
1474 elm_config_scale_get());
1475 evas_object_smart_member_add(it->deco_all_view, sd->pan_obj);
1476 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
1478 if (it->item->type & ELM_GENLIST_ITEM_TREE)
1479 strncpy(buf, "tree", sizeof(buf));
1480 else strncpy(buf, "item", sizeof(buf));
1481 if (sd->mode == ELM_LIST_COMPRESS)
1482 strncat(buf, "_compress", sizeof(buf) - strlen(buf) - 1);
1484 strncat(buf, "/", sizeof(buf) - strlen(buf) - 1);
1485 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf) - 1);
1487 elm_widget_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
1488 elm_widget_style_get(WIDGET(it)));
1490 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1491 if (!stacking_even) stacking_even = "above";
1492 it->item->stacking_even = !!strcmp("above", stacking_even);
1494 stacking = edje_object_data_get(VIEW(it), "stacking");
1495 if (!stacking) stacking = "yes";
1496 it->item->nostacking = !!strcmp("yes", stacking);
1498 edje_object_mirrored_set
1499 (it->deco_all_view, elm_widget_mirrored_get(WIDGET(it)));
1501 _elm_genlist_item_position_state_update(it);
1502 _elm_genlist_item_state_update(it);
1504 if (GL_IT(it)->wsd->reorder_mode)
1506 edje_object_signal_emit(it->deco_all_view, SIGNAL_REORDER_MODE_UNSET,
1511 edje_object_signal_emit
1512 (it->deco_all_view, SIGNAL_DECORATE_ENABLED_EFFECT, "elm");
1514 edje_object_signal_emit
1515 (it->deco_all_view, SIGNAL_DECORATE_ENABLED, "elm");
1517 _item_mouse_callbacks_del(it, VIEW(it));
1518 _item_mouse_callbacks_add(it, it->deco_all_view);
1521 edje_object_signal_emit
1522 (it->deco_all_view, SIGNAL_FLIP_ENABLED, "elm");
1523 _view_inflate(it->deco_all_view, it, NULL, &(GL_IT(it)->deco_all_contents));
1524 edje_object_part_swallow
1525 (it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
1527 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
1528 evas_object_show(it->deco_all_view);
1531 edje_object_signal_emit(it->deco_all_view, SIGNAL_SELECTED, "elm");
1533 it->item->decorate_all_item_realized = EINA_TRUE;
1534 it->want_unrealize = EINA_FALSE;
1537 //-- tree expand/contract signal handle routine --//
1539 _expand_toggle_signal_cb(void *data,
1540 Evas_Object *obj EINA_UNUSED,
1541 const char *emission EINA_UNUSED,
1542 const char *source EINA_UNUSED)
1544 Elm_Gen_Item *it = data;
1546 if (it->item->expanded)
1547 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_CONTRACT_REQUEST, EO_OBJ(it)));
1549 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_EXPAND_REQUEST, EO_OBJ(it)));
1553 _expand_signal_cb(void *data,
1554 Evas_Object *obj EINA_UNUSED,
1555 const char *emission EINA_UNUSED,
1556 const char *source EINA_UNUSED)
1558 Elm_Gen_Item *it = data;
1560 if (!it->item->expanded)
1561 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_EXPAND_REQUEST, EO_OBJ(it)));
1565 _contract_signal_cb(void *data,
1566 Evas_Object *obj EINA_UNUSED,
1567 const char *emission EINA_UNUSED,
1568 const char *source EINA_UNUSED)
1570 Elm_Gen_Item *it = data;
1572 if (it->item->expanded)
1573 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_CONTRACT_REQUEST, EO_OBJ(it)));
1576 //-- item cache handle routine --//
1577 // push item cache into caches
1579 _item_cache_push(Elm_Genlist_Data *sd, Item_Cache *itc)
1581 if (!itc || (sd->item_cache_max <= 0))
1584 sd->item_cache_count++;
1586 eina_inlist_prepend(sd->item_cache, EINA_INLIST_GET(itc));
1591 // pop item cache from caches
1593 _item_cache_pop(Elm_Genlist_Data *sd, Item_Cache *itc)
1595 if (!itc || (!sd->item_cache) ||
1596 (sd->item_cache_count <= 0))
1600 eina_inlist_remove (sd->item_cache, EINA_INLIST_GET(itc));
1601 sd->item_cache_count--;
1606 // free one item cache
1608 _item_cache_free(Item_Cache *itc)
1615 evas_object_del(itc->spacer);
1616 evas_object_del(itc->base_view);
1617 itc->item_class = NULL;
1618 EINA_LIST_FREE(itc->contents, c)
1622 ELM_SAFE_FREE(itc, free);
1625 // clean up item cache by removing overflowed caches
1627 _item_cache_clean(Elm_Genlist_Data *sd)
1629 evas_event_freeze(evas_object_evas_get(sd->obj));
1631 while ((sd->item_cache) && (sd->item_cache_count > sd->item_cache_max))
1634 EINA_INLIST_CONTAINER_GET(sd->item_cache->last, Item_Cache);
1635 _item_cache_free(_item_cache_pop(sd, itc));
1637 evas_event_thaw(evas_object_evas_get(sd->obj));
1638 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
1641 // empty all item caches
1643 _item_cache_zero(Elm_Genlist_Data *sd)
1645 int pmax = sd->item_cache_max;
1647 sd->item_cache_max = 0;
1648 _item_cache_clean(sd);
1649 sd->item_cache_max = pmax;
1652 // add an item to item cache
1654 _item_cache_add(Elm_Gen_Item *it, Eina_List *contents)
1656 if (it->item->nocache_once || it->item->nocache) return EINA_FALSE;
1658 Item_Cache *itc = NULL;
1659 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1660 Evas_Object *obj = sd->obj;
1663 evas_event_freeze(evas_object_evas_get(obj));
1665 if (sd->item_cache_max > 0)
1666 itc = ELM_NEW(Item_Cache);
1668 if (!_item_cache_push(sd, itc))
1670 if (itc) ELM_SAFE_FREE(itc, free);
1672 evas_event_thaw(evas_object_evas_get(obj));
1673 evas_event_thaw_eval(evas_object_evas_get(obj));
1676 itc->spacer = it->spacer;
1677 itc->base_view = VIEW(it);
1678 itc->item_class = it->itc;
1679 itc->contents = contents;
1680 if (it->item->type & ELM_GENLIST_ITEM_TREE)
1683 if (it->item->expanded)
1684 edje_object_signal_emit(itc->base_view, SIGNAL_CONTRACTED, "elm");
1688 edje_object_signal_emit(itc->base_view, SIGNAL_UNSELECTED, "elm");
1689 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()))
1690 edje_object_signal_emit(itc->base_view, SIGNAL_ENABLED, "elm");
1691 if ((EO_OBJ(it) == sd->focused_item) &&
1692 (elm_widget_focus_highlight_enabled_get(obj) || _elm_config->win_auto_focus_enable))
1693 edje_object_signal_emit(itc->base_view, SIGNAL_UNFOCUSED, "elm");
1695 //Tizen Only(20160307)
1696 edje_object_signal_emit(itc->base_view, SIGNAL_DEFAULT, "elm");
1698 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
1699 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
1701 // FIXME: other callbacks?
1702 edje_object_signal_callback_del_full
1703 (itc->base_view, "elm,action,expand,toggle", "elm",
1704 _expand_toggle_signal_cb, it);
1705 edje_object_signal_callback_del_full
1706 (itc->base_view, "elm,action,expand", "elm", _expand_signal_cb, it);
1707 edje_object_signal_callback_del_full
1708 (itc->base_view, "elm,action,contract", "elm", _contract_signal_cb, it);
1709 _item_mouse_callbacks_del(it, itc->base_view);
1711 edje_object_mirrored_set(itc->base_view,
1712 elm_widget_mirrored_get(WIDGET(it)));
1713 edje_object_scale_set(itc->base_view,
1714 elm_widget_scale_get(WIDGET(it))
1715 * elm_config_scale_get());
1719 evas_object_hide(itc->base_view);
1720 evas_object_move(itc->base_view, -9999, -9999);
1722 _item_cache_clean(sd);
1724 evas_event_thaw(evas_object_evas_get(obj));
1725 evas_event_thaw_eval(evas_object_evas_get(obj));
1730 // find an item from item cache and remove it from the cache
1732 _item_cache_find(Elm_Gen_Item *it)
1734 if (it->item->nocache_once || it->item->nocache) return EINA_FALSE;
1736 Item_Cache *itc = NULL;
1739 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1741 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1742 EINA_INLIST_FOREACH_SAFE(sd->item_cache, l, itc)
1744 if ((itc->tree == tree) &&
1745 (((!it->itc) && (!itc->item_class)) ||
1746 (it->itc && itc->item_class &&
1747 (it->itc == itc->item_class))))
1749 itc = _item_cache_pop(sd, itc);
1752 it->spacer = itc->spacer;
1753 VIEW(it) = itc->base_view;
1755 itc->base_view = NULL;
1757 eina_list_free(itc->contents);
1758 itc->contents = NULL;
1759 _item_cache_free(itc);
1767 _content_cache_add(Elm_Gen_Item *it, Eina_List **cache)
1769 Evas_Object *content = NULL;
1770 EINA_LIST_FREE(it->contents, content)
1772 *cache = eina_list_append(*cache, content);
1779 _access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
1784 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1785 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1787 buf = eina_strbuf_new();
1789 if (it->itc->func.text_get)
1794 if (!(it->texts)) it->texts =
1795 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1797 EINA_LIST_FOREACH(it->texts, l, key)
1799 char *s = it->itc->func.text_get
1800 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
1804 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
1805 eina_strbuf_append(buf, s);
1811 ret = eina_strbuf_string_steal(buf);
1812 eina_strbuf_free(buf);
1817 _access_state_cb(void *data, Evas_Object *obj EINA_UNUSED)
1819 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1820 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1822 if (it->base->disabled)
1823 return strdup(E_("State: Disabled"));
1829 _access_on_highlight_cb(void *data)
1831 Evas_Coord x, y, w, h;
1832 Evas_Coord sx, sy, sw, sh;
1833 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1834 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
1836 evas_object_geometry_get(it->base->view, &x, &y, &w, &h);
1837 // XXX There would be a reason.
1838 if ((w == 0) && (h == 0)) return;
1840 evas_object_geometry_get(it->base->widget, &sx, &sy, &sw, &sh);
1841 if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
1842 elm_genlist_item_bring_in(EO_OBJ(it),
1843 ELM_GENLIST_ITEM_SCROLLTO_IN);
1847 _access_widget_item_register(Elm_Gen_Item *it)
1849 Elm_Access_Info *ai;
1851 _elm_access_widget_item_register(it->base);
1853 ai = _elm_access_info_get(it->base->access_obj);
1855 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1856 _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
1857 _elm_access_on_highlight_hook_set(ai, _access_on_highlight_cb, it);
1858 _elm_access_activate_callback_set(ai, _access_activate_cb, EO_OBJ(it));
1862 _elm_genlist_item_focus_update(Elm_Gen_Item *it)
1864 const char *focus_raise;
1865 Evas_Object *obj = WIDGET(it);
1866 ELM_GENLIST_DATA_GET(obj, sd);
1868 if (elm_widget_focus_highlight_enabled_get(obj) || _elm_config->win_auto_focus_enable)
1869 edje_object_signal_emit(VIEW(it), SIGNAL_FOCUSED, "elm");
1871 focus_raise = edje_object_data_get(VIEW(it), "focusraise");
1872 if ((focus_raise) && (!strcmp(focus_raise, "on")))
1877 evas_object_raise(VIEW(it));
1878 EINA_LIST_FOREACH(sd->group_items, l, git)
1880 if (git->realized) evas_object_raise(VIEW(git));
1886 _item_realize(Elm_Gen_Item *it,
1890 const char *treesize;
1891 Item_Size *size = NULL;
1893 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1897 if (it->item->order_num_in != in)
1899 _item_order_update(EINA_INLIST_GET(it), in);
1900 _elm_genlist_item_state_update(it);
1901 _elm_genlist_item_index_update(it);
1905 it->item->order_num_in = in;
1907 if (sd->tree_effect_enabled ||
1908 (!_item_cache_find(it)))
1910 VIEW(it) = _view_create(it, it->itc->item_style);
1911 if (it->item->nocache_once)
1912 it->item->nocache_once = EINA_FALSE;
1915 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
1916 if (_elm_config->atspi_mode)
1918 elm_interface_atspi_accessible_added(EO_OBJ(it));
1919 elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
1924 if (_elm_config->access_mode) _access_widget_item_register(it);
1926 _item_order_update(EINA_INLIST_GET(it), in);
1928 if (sd->reorder_mode)
1929 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
1931 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_UNSET, "elm");
1933 treesize = edje_object_data_get(VIEW(it), "treesize");
1934 if (treesize) tsize = atoi(treesize);
1936 if (edje_object_part_exists(VIEW(it), "elm.swallow.pad"))
1938 if (!it->spacer && treesize)
1941 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1942 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1943 elm_widget_sub_object_add(WIDGET(it), it->spacer);
1946 evas_object_size_hint_min_set
1947 (it->spacer, (it->item->expanded_depth * tsize) *
1948 elm_config_scale_get(), 1);
1949 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1953 ELM_SAFE_FREE(it->spacer, evas_object_del);
1958 edje_object_signal_callback_add
1959 (VIEW(it), "elm,action,expand,toggle", "elm",
1960 _expand_toggle_signal_cb, it);
1961 edje_object_signal_callback_add
1962 (VIEW(it), "elm,action,expand", "elm", _expand_signal_cb, it);
1963 edje_object_signal_callback_add
1964 (VIEW(it), "elm,action,contract", "elm", _contract_signal_cb, it);
1965 _item_mouse_callbacks_add(it, VIEW(it));
1967 if ((sd->decorate_all_mode) && (!it->deco_all_view) &&
1968 (it->item->type != ELM_GENLIST_ITEM_GROUP) &&
1969 (it->itc->decorate_all_item_style))
1970 _decorate_all_item_realize(it, EINA_FALSE);
1972 _elm_genlist_item_state_update(it);
1973 _elm_genlist_item_index_update(it);
1975 if (EO_OBJ(it) == sd->focused_item)
1977 _elm_genlist_item_focus_update(it);
1978 _elm_widget_item_highlight_in_theme(WIDGET(it), EO_OBJ(it));
1979 _elm_widget_highlight_in_theme_update(WIDGET(it));
1980 _elm_widget_focus_highlight_start(WIDGET(it));
1984 size = eina_hash_find(sd->size_caches, &(it->itc));
1985 /* homogeneous genlist shortcut */
1986 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
1987 if ((calc) && (sd->homogeneous || it->itc->homogeneous) && (!it->item->mincalcd) && size)
1989 GL_IT(it)->w = GL_IT(it)->minw = size->minw;
1990 GL_IT(it)->h = GL_IT(it)->minh = size->minh;
1991 it->item->mincalcd = EINA_TRUE;
1995 if (eina_list_count(it->contents) != 0)
1996 ERR_ABORT("If you see this error, please notify us and we"
1999 _view_inflate(VIEW(it), it, &it->texts, &it->contents);
2000 if (it->has_contents != (!!it->contents))
2001 it->item->mincalcd = EINA_FALSE;
2002 it->has_contents = !!it->contents;
2005 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
2006 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_contents,
2010 /* access: unregister item which have no text and content */
2011 if (_elm_config->access_mode && !it->texts && !it->contents)
2012 _elm_access_widget_item_unregister(it->base);
2014 if (!it->item->mincalcd)
2016 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
2017 if ((sd->homogeneous || it->itc->homogeneous) && size)
2019 GL_IT(it)->w = GL_IT(it)->minw = size->minw;
2020 GL_IT(it)->h = GL_IT(it)->minh = size->minh;
2021 it->item->mincalcd = EINA_TRUE;
2025 Evas_Coord mw = -1, mh = -1;
2027 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2028 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2029 if (sd->mode == ELM_LIST_COMPRESS)
2030 mw = sd->prev_viewport_w;
2031 edje_object_message_signal_process(VIEW(it));
2032 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
2033 // TIZEN_ONLY(161209): Fix item shrink
2034 if (sd->mode == ELM_LIST_COMPRESS ||
2035 (sd->mode == ELM_LIST_SCROLL && mw < sd->prev_viewport_w))
2036 mw = sd->prev_viewport_w;
2038 it->item->w = it->item->minw = mw;
2039 it->item->h = it->item->minh = mh;
2040 it->item->mincalcd = EINA_TRUE;
2042 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
2043 if (sd->homogeneous || it->itc->homogeneous)
2046 eina_hash_del_by_key(sd->size_caches, &(it->itc));
2048 size = ELM_NEW(Item_Size);
2049 size->itc = it->itc;
2052 eina_hash_add(sd->size_caches, &(it->itc), size);
2056 if (!calc) evas_object_show(VIEW(it));
2059 if (it->tooltip.content_cb)
2062 elm_wdg_item_tooltip_content_cb_set(
2063 it->tooltip.content_cb, it->tooltip.data, NULL),
2064 elm_wdg_item_tooltip_style_set(it->tooltip.style),
2065 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
2068 if (it->mouse_cursor)
2070 elm_wdg_item_cursor_set(it->mouse_cursor));
2072 it->realized = EINA_TRUE;
2073 it->want_unrealize = EINA_FALSE;
2077 if (it->item->tree_effect_hide_me)
2079 if (sd->move_effect_mode
2080 != ELM_GENLIST_TREE_EFFECT_NONE)
2083 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "");
2084 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "elm");
2086 it->item->tree_effect_hide_me = EINA_FALSE;
2089 if (it->item->type == ELM_GENLIST_ITEM_NONE)
2093 EINA_LIST_FOREACH(it->contents, l, eobj)
2094 if (elm_widget_is(eobj) && elm_object_focus_allow_get(eobj))
2095 it->item_focus_chain = eina_list_append
2096 (it->item_focus_chain, eobj);
2100 if (it->item->type == ELM_GENLIST_ITEM_TREE)
2102 Evas_Object* t_eobj;
2104 EINA_LIST_FOREACH(it->contents, tl, t_eobj)
2105 if (elm_widget_is(t_eobj) && elm_object_focus_allow_get(t_eobj))
2106 it->item_focus_chain = eina_list_append
2107 (it->item_focus_chain, t_eobj);
2111 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_REALIZED, EO_OBJ(it)));
2114 //Send a signal so that an item changes its style according to its expand depth
2115 if (GL_IT(it)->expanded_depth > 0)
2118 snprintf(buf, sizeof(buf), "elm,state,expanded_depth,%d",
2119 GL_IT(it)->expanded_depth);
2120 edje_object_signal_emit(VIEW(it), buf, "elm");
2123 if ((!calc) && (sd->decorate_all_mode) &&
2124 (it->item->type != ELM_GENLIST_ITEM_GROUP))
2126 if (it->itc->decorate_all_item_style)
2128 if (!it->deco_all_view)
2129 _decorate_all_item_realize(it, EINA_FALSE);
2130 edje_object_message_signal_process(it->deco_all_view);
2134 if (it->decorate_it_set) _decorate_item_set(it);
2136 edje_object_message_signal_process(VIEW(it));
2137 //TIZEN_ONLY(20160329): genlist: enhance accessibility scroll & highlight (30d9a6012e629cd9ea60eae8d576f3ebb94ada86)
2138 if (sd->atspi_item_to_highlight == it)
2140 sd->atspi_item_to_highlight = NULL;
2141 eo_do_super(EO_OBJ(it), ELM_GENLIST_ITEM_CLASS, elm_interface_atspi_component_highlight_grab());
2147 _tree_effect_animator_cb(void *data)
2151 int y = 0, dy = 0, dh = 0;
2152 double effect_duration = 0.3, t;
2153 ELM_GENLIST_DATA_GET(data, sd);
2154 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
2155 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2156 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
2157 Elm_Object_Item *eo_it = NULL, *eo_it2;
2159 t = ((0.0 > (t = ecore_time_get() - sd->start_time)) ? 0.0 : t);
2160 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
2161 evas_output_viewport_get
2162 (evas_object_evas_get(sd->pan_obj), &cvx, &cvy, &cvw, &cvh);
2163 if (t > effect_duration) end = EINA_TRUE;
2165 // Below while statement is needed, when the genlist is resized.
2166 it2 = sd->expanded_item;
2167 eo_it2 = EO_OBJ(it2);
2168 while (eo_it2 && vis)
2170 it2 = eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
2171 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
2172 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y,
2173 it2->item->w, it2->item->h, cvx, cvy, cvw,
2175 eo_it2 = elm_genlist_item_prev_get(eo_it2);
2178 if (sd->expanded_next_item)
2180 expanded_next_it = sd->expanded_next_item;
2183 EINA_LIST_FOREACH(sd->move_items, l, it)
2185 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
2187 expanded_next_it->item->old_scrl_y =
2188 sd->expanded_item->item->old_scrl_y
2189 + sd->expanded_item->item->h;
2190 if (expanded_next_it->item->scrl_y <=
2191 expanded_next_it->item->old_scrl_y) /* did not
2195 expanded_next_it->item->scrl_y = cvy + cvh;
2197 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
2198 cvy + cvh : expanded_next_it->item->scrl_y) -
2199 expanded_next_it->item->old_scrl_y;
2201 else if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
2203 if (expanded_next_it->item->scrl_y >
2204 expanded_next_it->item->old_scrl_y) /* did not
2208 expanded_next_it->item->old_scrl_y = cvy + cvh;
2210 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
2212 dy = (sd->expanded_item->item->scrl_y +
2213 sd->expanded_item->item->h) - cvy + cvh;
2214 expanded_next_it->item->old_scrl_y = cvy + cvh;
2218 dy = (sd->expanded_item->item->scrl_y +
2219 sd->expanded_item->item->h) -
2220 expanded_next_it->item->old_scrl_y;
2224 if (t <= effect_duration)
2226 y = ((1 - (1 - (t / effect_duration)) *
2227 (1 - (t / effect_duration))) * dy);
2235 if (!it->realized && !it->item->queued)
2236 _item_realize(it, in, 0);
2239 if (it != expanded_next_it)
2241 it->item->old_scrl_y =
2242 expanded_next_it->item->old_scrl_y +
2243 expanded_next_it->item->h + dh;
2248 if ((it->item->old_scrl_y + y) < (cvy + cvh))
2249 _item_position(it, VIEW(it), it->item->scrl_x,
2250 it->item->old_scrl_y + y);
2253 _item_tree_effect(sd, y);
2257 int expanded_item_num = 0;
2260 if (sd->expanded_item)
2261 eo_it = elm_genlist_item_next_get(EO_OBJ(sd->expanded_item));
2266 expanded_item_num++;
2267 eo_it2 = elm_genlist_item_next_get(eo_it2);
2272 it = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
2274 if (sd->expanded_item->item->expanded_depth >=
2275 it->item->expanded_depth) break;
2276 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
2278 if (!it->item->tree_effect_finished)
2280 if (t >= (((num - 1) * effect_duration) /
2284 edje_object_signal_emit(VIEW(it), "flip_item", "");
2285 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ITEM,
2287 _item_position(it, VIEW(it), it->item->scrl_x,
2289 it->item->tree_effect_finished = EINA_TRUE;
2293 eo_it = elm_genlist_item_next_get(eo_it);
2299 _item_tree_effect_finish(sd);
2300 return ECORE_CALLBACK_CANCEL;
2303 return ECORE_CALLBACK_RENEW;
2307 _group_items_recalc(void *data)
2311 Elm_Genlist_Data *sd = data;
2313 evas_event_freeze(evas_object_evas_get(sd->obj));
2314 EINA_LIST_FOREACH(sd->group_items, l, git)
2316 if (git->item->want_realize)
2318 if (!git->realized) _item_realize(git, 0, EINA_FALSE);
2319 evas_object_resize(VIEW(git), sd->minw, git->item->h);
2320 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2321 evas_object_stack_above(VIEW(git), sd->stack[1]);
2322 evas_object_show(VIEW(git));
2324 else if (!git->item->want_realize && git->realized)
2327 _elm_genlist_item_unrealize(git, EINA_FALSE);
2330 evas_event_thaw(evas_object_evas_get(sd->obj));
2331 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
2335 _reorder_move_animator_cb(void *data)
2338 Elm_Gen_Item *it = data;
2339 Eina_Bool down = EINA_FALSE;
2340 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
2341 int y, dy = it->item->h / 10 * elm_config_scale_get(), diff;
2343 t = ((0.0 > (t = ecore_loop_time_get()
2344 - sd->start_time)) ? 0.0 : t);
2346 if (t <= REORDER_EFFECT_TIME)
2347 y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2350 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2351 if (diff < dy) y = diff;
2352 else if (diff > it->item->h) y = diff / 2;
2354 if (it->item->old_scrl_y < it->item->scrl_y)
2356 it->item->old_scrl_y += y;
2359 else if (it->item->old_scrl_y > it->item->scrl_y)
2361 it->item->old_scrl_y -= y;
2365 if (it->deco_all_view)
2367 (it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
2369 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2371 if ((sd->reorder_pan_move) ||
2372 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2373 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2375 it->item->old_scrl_y = it->item->scrl_y;
2376 it->item->move_effect_enabled = EINA_FALSE;
2377 sd->reorder_move_animator = NULL;
2378 return ECORE_CALLBACK_CANCEL;
2381 return ECORE_CALLBACK_RENEW;
2385 _reorder_item_space_get(Elm_Gen_Item *it)
2387 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
2388 Elm_Gen_Item *reorder_it = sd->reorder_it;
2389 Evas_Coord rox, roy, row, roh, oy, oh;
2390 Eina_Bool top = EINA_FALSE;
2392 if (!reorder_it) return 0;
2394 evas_object_geometry_get(sd->pan_obj, NULL, &oy, NULL, &oh);
2395 evas_object_geometry_get
2396 (sd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2398 if ((sd->reorder_start_y < it->item->block->y) &&
2399 (roy - oy + (roh / 2) >= it->item->block->y - sd->pan_y))
2401 it->item->block->reorder_offset =
2402 sd->reorder_it->item->h * -1;
2403 if (it->item->block->count == 1)
2404 sd->reorder_rel = it;
2406 else if ((sd->reorder_start_y >= it->item->block->y) &&
2407 (roy - oy + (roh / 2) <= it->item->block->y - sd->pan_y))
2409 it->item->block->reorder_offset = sd->reorder_it->item->h;
2412 it->item->block->reorder_offset = 0;
2414 it->item->scrl_y += it->item->block->reorder_offset;
2416 top = (ELM_RECTS_INTERSECT
2417 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2418 rox, roy + (roh / 2), row, 1));
2421 sd->reorder_rel = it;
2422 it->item->scrl_y += sd->reorder_it->item->h;
2423 return sd->reorder_it->item->h;
2430 _item_block_position(Item_Block *itb,
2435 Eina_Bool vis = EINA_FALSE;
2436 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2437 Elm_Genlist_Data *sd = NULL;
2439 evas_event_freeze(evas_object_evas_get((itb->sd)->obj));
2440 evas_object_geometry_get(itb->sd->pan_obj, &ox, &oy, &ow, &oh);
2441 evas_output_viewport_get
2442 (evas_object_evas_get((itb->sd)->obj),
2443 &cvx, &cvy, &cvw, &cvh);
2445 EINA_LIST_FOREACH(itb->items, l, it)
2447 sd = GL_IT(it)->wsd;
2448 if (sd->reorder_it == it) continue;
2450 if (!it->filtered) _item_filtered_get(it);
2451 if (it->want_hidden)
2453 if (it->realized) evas_object_hide(VIEW(it));
2458 it->item->w = itb->w;
2459 it->item->scrl_x = itb->x + it->x - sd->pan_x + ox;
2460 it->item->scrl_y = itb->y + it->y - sd->pan_y + oy;
2462 vis = (ELM_RECTS_INTERSECT
2463 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2464 cvx, cvy, cvw, cvh));
2465 if (!(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP))
2467 if ((itb->realized) && (!it->realized))
2469 if (vis) _item_realize(it, in, EINA_FALSE);
2473 if (vis || it->dragging)
2475 if (sd->reorder_mode)
2476 y += _reorder_item_space_get(it);
2477 if ((sd->reorder_it) &&
2478 (it->item->old_scrl_y != it->item->scrl_y))
2480 if (!it->item->move_effect_enabled)
2482 it->item->move_effect_enabled = EINA_TRUE;
2483 sd->reorder_move_animator =
2485 _reorder_move_animator_cb, it);
2488 if (!it->item->move_effect_enabled)
2490 if ((sd->decorate_all_mode) &&
2491 (it->itc->decorate_all_item_style))
2492 _decorate_all_item_position
2493 (it, it->item->scrl_x, it->item->scrl_y);
2496 if (!sd->tree_effect_enabled ||
2497 (sd->move_effect_mode ==
2498 ELM_GENLIST_TREE_EFFECT_NONE) ||
2499 ((sd->move_effect_mode !=
2500 ELM_GENLIST_TREE_EFFECT_NONE) &&
2501 (it->item->old_scrl_y ==
2504 if (it->item->deco_it_view)
2506 (it, it->item->deco_it_view,
2511 (it, VIEW(it), it->item->scrl_x,
2515 it->item->old_scrl_y = it->item->scrl_y;
2520 if (!sd->tree_effect_animator)
2521 _elm_genlist_item_unrealize(it, EINA_FALSE);
2528 if (vis) it->item->want_realize = EINA_TRUE;
2532 evas_event_thaw(evas_object_evas_get((itb->sd)->obj));
2533 evas_event_thaw_eval(evas_object_evas_get((itb->sd)->obj));
2537 _item_block_realize(Item_Block *itb)
2539 if (itb->realized) return;
2541 itb->realized = EINA_TRUE;
2542 itb->want_unrealize = EINA_FALSE;
2546 _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
2548 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2549 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0;
2555 Elm_Genlist_Data *sd = psd->wsd;
2557 evas_event_freeze(evas_object_evas_get(obj));
2559 if (sd->pan_changed)
2561 ecore_job_del(sd->calc_job);
2562 sd->calc_job = NULL;
2564 sd->pan_changed = EINA_FALSE;
2567 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2568 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2570 if (sd->tree_effect_enabled &&
2571 (sd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
2573 if (!sd->tree_effect_animator)
2575 _item_tree_effect_before(sd->expanded_item);
2576 evas_object_raise(sd->event_block_rect);
2577 evas_object_stack_below(sd->event_block_rect, sd->stack[1]);
2578 evas_object_show(sd->event_block_rect);
2579 sd->start_time = ecore_time_get();
2580 sd->tree_effect_animator =
2581 ecore_animator_add(_tree_effect_animator_cb, sd->obj);
2585 EINA_INLIST_FOREACH(sd->blocks, itb)
2588 if (ELM_RECTS_INTERSECT(itb->x - sd->pan_x + ox,
2589 itb->y - sd->pan_y + oy,
2591 cvx, cvy, cvw, cvh))
2593 if ((!itb->realized) || (itb->changed))
2594 _item_block_realize(itb);
2595 _item_block_position(itb, in);
2599 if (itb->realized) _item_block_unrealize(itb);
2603 if ((!sd->reorder_it) || (sd->reorder_pan_move))
2604 _group_items_recalc(sd);
2605 if ((sd->reorder_mode) && (sd->reorder_it))
2607 if (sd->pan_y != sd->reorder_old_pan_y)
2608 sd->reorder_pan_move = EINA_TRUE;
2609 else sd->reorder_pan_move = EINA_FALSE;
2611 evas_object_raise(sd->VIEW(reorder_it));
2612 evas_object_stack_below(sd->VIEW(reorder_it), sd->stack[1]);
2613 sd->reorder_old_pan_y = sd->pan_y;
2614 sd->start_time = ecore_loop_time_get();
2617 if (!sd->tree_effect_enabled ||
2618 (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
2619 _item_auto_scroll(sd);
2621 //FIXME: There are issue about wrong list positioning in prepend cases.
2622 // To prevent the issue, allocate repositioning in smart calculate.
2623 if (sd->prepend_items)
2625 Evas_Coord prepend_h = 0;
2626 Elm_Gen_Item *tmp = NULL;
2627 EINA_LIST_FREE(sd->prepend_items, tmp)
2629 prepend_h += tmp->item->minh;
2633 elm_interface_scrollable_content_pos_get(&vx, &vy),
2634 elm_interface_scrollable_content_viewport_geometry_get
2635 (NULL, NULL, &vw, &vh));
2636 /* Set adjusted position as prepended items height */
2637 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(vx, vy + prepend_h, vw, vh));
2641 elm_interface_scrollable_content_pos_get(&vx, &vy),
2642 elm_interface_scrollable_content_viewport_geometry_get
2643 (NULL, NULL, &vw, &vh));
2645 if (sd->reorder_fast == 1)
2646 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(vx, vy - 10, vw, vh));
2647 else if (sd->reorder_fast == -1)
2648 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(vx, vy + 10, vw, vh));
2650 if (sd->focused_item && !sd->item_loop_enable)
2651 _elm_widget_focus_highlight_start(psd->wobj);
2653 EINA_LIST_FOREACH(sd->group_items, l, git)
2655 git->item->want_realize = EINA_FALSE;
2656 if (git->realized) evas_object_raise(VIEW(git));
2659 //update item before the render to prevent delayed update by job.
2662 ELM_SAFE_FREE(sd->update_job, ecore_job_del);
2663 _update_job(sd->obj);
2666 evas_event_thaw(evas_object_evas_get(obj));
2667 evas_event_thaw_eval(evas_object_evas_get(obj));
2669 eo_do(psd->wobj, eo_event_callback_call
2670 (ELM_INTERFACE_SCROLLABLE_EVENT_CHANGED, NULL));
2674 _elm_genlist_pan_eo_base_destructor(Eo *obj, Elm_Genlist_Pan_Data *psd)
2676 eo_data_unref(psd->wobj, psd->wsd);
2677 eo_do_super(obj, MY_PAN_CLASS, eo_destructor());
2681 _elm_genlist_pan_class_constructor(Eo_Class *klass)
2683 evas_smart_legacy_type_register(MY_PAN_CLASS_NAME_LEGACY, klass);
2686 #include "elm_genlist_pan.eo.c"
2689 _item_multi_select_up(Elm_Genlist_Data *sd)
2691 Elm_Object_Item *eo_prev;
2693 if (!sd->selected) return EINA_FALSE;
2694 if (!sd->multi) return EINA_FALSE;
2696 eo_prev = elm_genlist_item_prev_get(sd->last_selected_item);
2699 ELM_GENLIST_ITEM_DATA_GET(eo_prev, prev);
2700 if ((!_is_no_select(prev)) &&
2701 (!elm_object_item_disabled_get(eo_prev)) && (!prev->want_hidden))
2703 eo_prev = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev));
2705 if (!eo_prev) return EINA_TRUE;
2707 if (elm_genlist_item_selected_get(eo_prev))
2709 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2710 sd->last_selected_item = eo_prev;
2714 elm_genlist_item_selected_set(eo_prev, EINA_TRUE);
2720 _item_multi_select_down(Elm_Genlist_Data *sd)
2722 Elm_Object_Item *eo_next;
2724 if (!sd->selected) return EINA_FALSE;
2725 if (!sd->multi) return EINA_FALSE;
2727 eo_next = elm_genlist_item_next_get(sd->last_selected_item);
2730 ELM_GENLIST_ITEM_DATA_GET(eo_next, next);
2731 if ((!_is_no_select(next)) &&
2732 (!elm_object_item_disabled_get(eo_next)) && (!next->want_hidden))
2734 eo_next = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next));
2736 if (!eo_next) return EINA_TRUE;
2738 if (elm_genlist_item_selected_get(eo_next))
2740 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2741 sd->last_selected_item = eo_next;
2745 elm_genlist_item_selected_set(eo_next, EINA_TRUE);
2752 _all_items_deselect(Elm_Genlist_Data *sd)
2754 if (!sd->selected) return EINA_FALSE;
2756 sd->deselecting = eina_list_clone(sd->selected);
2757 while (sd->deselecting)
2759 Elm_Object_Item *it = eina_list_data_get(sd->deselecting);
2761 sd->deselecting = eina_list_remove_list(sd->deselecting, sd->deselecting);
2762 elm_genlist_item_selected_set(it, EINA_FALSE);
2769 _item_single_select_up(Elm_Genlist_Data *sd)
2771 Elm_Gen_Item *prev = NULL;
2774 prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2777 Elm_Object_Item *eo_prev = elm_genlist_item_prev_get
2778 (sd->last_selected_item);
2779 prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
2784 if ((!_is_no_select(prev)) &&
2785 (!elm_object_item_disabled_get(EO_OBJ(prev))) && (!prev->want_hidden))
2787 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2790 if (!prev) return EINA_FALSE;
2792 _all_items_deselect(sd);
2794 elm_genlist_item_selected_set(EO_OBJ(prev), EINA_TRUE);
2799 _item_single_select_down(Elm_Genlist_Data *sd)
2801 Elm_Gen_Item *next = NULL;
2802 Elm_Object_Item *eo_next = NULL;
2805 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2808 eo_next = elm_genlist_item_next_get(sd->last_selected_item);
2809 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2814 if ((!_is_no_select(next)) &&
2815 (!elm_object_item_disabled_get(EO_OBJ(next))) && (!next->want_hidden))
2817 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2820 if (!next) return EINA_FALSE;
2822 _all_items_deselect(sd);
2824 elm_genlist_item_selected_set(EO_OBJ(next), EINA_TRUE);
2830 _elm_genlist_item_focused(Elm_Object_Item *eo_it)
2832 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
2833 Evas_Object *obj = WIDGET(it);
2834 ELM_GENLIST_DATA_GET(obj, sd);
2837 if (_is_no_select(it) ||
2838 (eo_it == sd->focused_item) ||
2839 (eo_do_ret(eo_it, tmp, elm_wdg_item_disabled_get())))
2842 //TIZEN_ONLY(20161209): Do not autoscroll if scroll to item is exist
2845 switch (_elm_config->focus_autoscroll_mode)
2847 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
2848 elm_genlist_item_show(eo_it,
2849 ELM_GENLIST_ITEM_SCROLLTO_IN);
2851 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
2852 elm_genlist_item_bring_in(eo_it,
2853 ELM_GENLIST_ITEM_SCROLLTO_IN);
2861 sd->focused_item = eo_it;
2864 _elm_genlist_item_focus_update(it);
2865 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_ITEM_FOCUSED, eo_it));
2866 if (_elm_config->atspi_mode)
2867 elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_FOCUSED, EINA_TRUE);
2871 _elm_genlist_item_unfocused(Elm_Object_Item *eo_it)
2875 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
2876 Evas_Object *obj = WIDGET(it);
2877 ELM_GENLIST_DATA_GET(obj, sd);
2879 if (_is_no_select(it))
2882 if ((!sd->focused_item) ||
2883 (eo_it != sd->focused_item))
2886 if (elm_widget_focus_highlight_enabled_get(obj) || _elm_config->win_auto_focus_enable)
2888 ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focus_it);
2889 edje_object_signal_emit(VIEW(focus_it), SIGNAL_UNFOCUSED, "elm");
2892 sd->focused_item = NULL;
2893 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_ITEM_UNFOCUSED, eo_it));
2894 if (_elm_config->atspi_mode)
2895 elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_FOCUSED, EINA_FALSE);
2899 _item_focused_next(Evas_Object *obj, Elm_Focus_Direction dir)
2901 ELM_GENLIST_DATA_GET(obj, sd);
2903 Elm_Object_Item *eo_next;
2904 Elm_Object_Item *eo_first_item;
2905 Elm_Object_Item *eo_last_item;
2908 if (!sd->focused_item)
2910 if (dir == ELM_FOCUS_UP)
2911 next = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2912 else if (dir == ELM_FOCUS_DOWN)
2913 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2918 ((eo_do_ret(EO_OBJ(next), tmp, elm_wdg_item_disabled_get())) ||
2919 (_is_no_select(next))))
2920 if (!next->want_hidden) next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2924 ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focus_it);
2925 if (dir == ELM_FOCUS_UP)
2927 eo_first_item = elm_genlist_first_item_get(WIDGET(focus_it));
2928 if (eo_first_item == sd->focused_item) return EINA_FALSE;
2929 eo_next = elm_genlist_item_prev_get(sd->focused_item);
2930 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2933 ((eo_do_ret(eo_next, tmp, elm_wdg_item_disabled_get())) ||
2934 (_is_no_select(next))))
2936 eo_next = elm_genlist_item_prev_get(eo_next);
2937 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2940 else if (dir == ELM_FOCUS_DOWN)
2942 eo_last_item = elm_genlist_last_item_get(WIDGET(focus_it));
2943 if (eo_last_item == sd->focused_item) return EINA_FALSE;
2944 eo_next = elm_genlist_item_next_get(sd->focused_item);
2945 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2948 ((eo_do_ret(eo_next, tmp, elm_wdg_item_disabled_get())) ||
2949 (_is_no_select(next))))
2951 eo_next = elm_genlist_item_next_get(eo_next);
2952 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2958 if (!next) return EINA_FALSE;
2961 elm_object_item_focus_set(EO_OBJ(next), EINA_TRUE);
2967 _elm_genlist_item_content_focus_set(Elm_Gen_Item *it, Elm_Focus_Direction dir)
2969 Evas_Object *focused_obj = NULL;
2973 if (!GL_IT(it)->wsd->focus_on_selection_enabled) return;
2975 if (!it->item_focus_chain)
2977 elm_object_focus_set(VIEW(it), EINA_TRUE);
2981 EINA_LIST_FOREACH(it->item_focus_chain, l, focused_obj)
2982 if (elm_object_focus_get(focused_obj)) break;
2984 if (focused_obj && (dir != ELM_FOCUS_PREVIOUS))
2986 Evas_Object *nextfocus;
2987 Elm_Object_Item *nextfocus_item;
2988 if (elm_widget_focus_next_get(focused_obj, dir, &nextfocus, &nextfocus_item))
2991 elm_object_item_focus_set(nextfocus_item, EINA_TRUE);
2993 elm_object_focus_set(nextfocus, EINA_TRUE);
2998 if (!l) l = it->item_focus_chain;
3000 if (dir == ELM_FOCUS_RIGHT)
3002 l = eina_list_next(l);
3003 if (!l) l = it->item_focus_chain;
3005 else if (dir == ELM_FOCUS_LEFT)
3007 l = eina_list_prev(l);
3008 if (!l) l = eina_list_last(it->item_focus_chain);
3011 elm_object_focus_set(eina_list_data_get(l), EINA_TRUE);
3015 _key_action_move_dir(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool multi)
3017 ELM_GENLIST_DATA_GET(obj, sd);
3018 Elm_Object_Item *it = NULL;
3019 Eina_Bool ret = EINA_FALSE;
3022 Eina_Bool focus_only = EINA_FALSE;
3024 // get content size and viewport size
3026 elm_interface_scrollable_content_viewport_geometry_get
3027 (NULL, NULL, NULL, &v),
3028 elm_interface_scrollable_content_size_get(NULL, &min));
3030 if (_elm_config->item_select_on_focus_disable)
3032 ret = _item_focused_next(obj, dir);
3038 if (dir == ELM_FOCUS_UP)
3039 ret = _item_multi_select_up(sd);
3040 else if (dir == ELM_FOCUS_DOWN)
3041 ret = _item_multi_select_down(sd);
3045 if (dir == ELM_FOCUS_UP)
3046 ret = _item_single_select_up(sd);
3047 else if (dir == ELM_FOCUS_DOWN)
3048 ret = _item_single_select_down(sd);
3054 focus_only = _elm_config->item_select_on_focus_disable;
3055 // handle item loop feature
3056 if (sd->item_loop_enable && !sd->item_looping_on)
3060 if (dir == ELM_FOCUS_UP)
3062 elm_layout_signal_emit(obj, "elm,action,looping,up", "elm");
3063 sd->item_looping_on = EINA_TRUE;
3065 else if (dir == ELM_FOCUS_DOWN)
3067 elm_layout_signal_emit(obj, "elm,action,looping,down", "elm");
3068 sd->item_looping_on = EINA_TRUE;
3073 if (dir == ELM_FOCUS_UP)
3074 it = elm_genlist_last_item_get(obj);
3075 else if (dir == ELM_FOCUS_DOWN)
3076 it = elm_genlist_first_item_get(obj);
3078 if (it && focus_only)
3079 elm_object_item_focus_set(it, EINA_TRUE);
3081 elm_genlist_item_selected_set(it, EINA_TRUE);
3085 else if (sd->item_looping_on)
3092 _key_action_move(Evas_Object *obj, const char *params)
3094 ELM_GENLIST_DATA_GET(obj, sd);
3095 const char *dir = params;
3101 Evas_Coord step_x = 0;
3102 Evas_Coord step_y = 0;
3103 Evas_Coord page_x = 0;
3104 Evas_Coord page_y = 0;
3105 Elm_Object_Item *it = NULL;
3106 Evas_Coord pan_max_x = 0, pan_max_y = 0;
3109 elm_interface_scrollable_content_pos_get(&x, &y),
3110 elm_interface_scrollable_step_size_get(&step_x, &step_y),
3111 elm_interface_scrollable_page_size_get(&page_x, &page_y),
3112 elm_interface_scrollable_content_viewport_geometry_get
3113 (NULL, NULL, &v_w, &v_h));
3115 _elm_widget_focus_auto_show(obj);
3116 if (!strcmp(dir, "left"))
3120 Elm_Object_Item *eo_gt = NULL;
3121 if (_elm_config->item_select_on_focus_disable)
3122 eo_gt = elm_object_focused_item_get(obj);
3124 eo_gt = elm_genlist_selected_item_get(obj);
3125 ELM_GENLIST_ITEM_DATA_GET(eo_gt, gt);
3126 _elm_genlist_item_content_focus_set(gt, ELM_FOCUS_LEFT);
3130 else if (!strcmp(dir, "right"))
3134 Elm_Object_Item *eo_gt = NULL;
3135 if (_elm_config->item_select_on_focus_disable)
3136 eo_gt = elm_object_focused_item_get(obj);
3138 eo_gt = elm_genlist_selected_item_get(obj);
3139 ELM_GENLIST_ITEM_DATA_GET(eo_gt, gt);
3140 _elm_genlist_item_content_focus_set(gt, ELM_FOCUS_RIGHT);
3144 else if (!strcmp(dir, "up"))
3146 if (_key_action_move_dir(obj, ELM_FOCUS_UP, EINA_FALSE)) return EINA_TRUE;
3147 else return EINA_FALSE;
3149 else if (!strcmp(dir, "up_multi"))
3151 if (_key_action_move_dir(obj, ELM_FOCUS_UP, EINA_TRUE)) return EINA_TRUE;
3152 else if (_key_action_move_dir(obj, ELM_FOCUS_UP, EINA_FALSE)) return EINA_TRUE;
3153 else return EINA_FALSE;
3155 else if (!strcmp(dir, "down"))
3157 if (_key_action_move_dir(obj, ELM_FOCUS_DOWN, EINA_FALSE)) return EINA_TRUE;
3158 else return EINA_FALSE;
3160 else if (!strcmp(dir, "down_multi"))
3162 if (_key_action_move_dir(obj, ELM_FOCUS_DOWN, EINA_TRUE)) return EINA_TRUE;
3163 else if (_key_action_move_dir(obj, ELM_FOCUS_DOWN, EINA_FALSE)) return EINA_TRUE;
3164 else return EINA_FALSE;
3166 else if (!strcmp(dir, "first"))
3168 it = elm_genlist_first_item_get(obj);
3171 if (_elm_config->item_select_on_focus_disable)
3173 elm_object_item_focus_set(it, EINA_TRUE);
3174 elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
3178 elm_genlist_item_selected_set(it, EINA_TRUE);
3183 else if (!strcmp(dir, "last"))
3185 it = elm_genlist_last_item_get(obj);
3188 if (_elm_config->item_select_on_focus_disable)
3190 elm_object_item_focus_set(it, EINA_TRUE);
3191 elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_BOTTOM);
3195 elm_genlist_item_selected_set(it, EINA_TRUE);
3200 else if (!strcmp(dir, "prior"))
3203 y -= -(page_y * v_h) / 100;
3207 else if (!strcmp(dir, "next"))
3210 y += -(page_y * v_h) / 100;
3214 else return EINA_FALSE;
3216 eo_do(sd->pan_obj, elm_obj_pan_pos_max_get(&pan_max_x, &pan_max_y));
3218 if (x > pan_max_x) x = pan_max_x;
3220 if (y > pan_max_y) y = pan_max_y;
3222 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
3228 _key_action_select(Evas_Object *obj, const char *params)
3230 Elm_Object_Item *eo_it = NULL;
3232 eo_it = elm_object_focused_item_get(obj);
3233 if (!eo_it) return EINA_TRUE;
3234 elm_genlist_item_expanded_set(eo_it, !elm_genlist_item_expanded_get(eo_it));
3235 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
3236 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3239 ((sd->multi_select_mode != ELM_OBJECT_MULTI_SELECT_MODE_WITH_CONTROL) ||
3240 (!strcmp(params, "multi"))))
3244 _item_highlight(it);
3245 if (_item_select(it)) goto deleted;
3254 while (sd->selected)
3256 Elm_Object_Item *eo_sel = sd->selected->data;
3257 Elm_Gen_Item *sel = eo_data_scope_get(eo_sel, ELM_GENLIST_ITEM_CLASS);
3258 _item_unselect(sel);
3263 const Eina_List *l, *l_next;
3264 Elm_Object_Item *eo_it2;
3266 EINA_LIST_FOREACH_SAFE(sd->selected, l, l_next, eo_it2)
3268 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
3270 _item_unselect(it2);
3273 _item_highlight(it);
3274 if (_item_select(it)) goto deleted;
3277 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_ACTIVATED, EO_OBJ(it)));
3286 _key_action_escape(Evas_Object *obj, const char *params EINA_UNUSED)
3288 ELM_GENLIST_DATA_GET(obj, sd);
3290 if (!_all_items_deselect(sd)) return EINA_FALSE;
3294 EOLIAN static Eina_Bool
3295 _elm_genlist_elm_widget_event(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *src, Evas_Callback_Type type, void *event_info)
3298 Evas_Event_Key_Down *ev = event_info;
3300 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3301 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
3302 if (!sd->items) return EINA_FALSE;
3304 if (!_elm_config_key_binding_call(obj, ev, key_actions))
3307 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3311 /* This function disables the specific code of the layout sub object add.
3312 * Only the widget sub_object_add is called.
3314 EOLIAN static Eina_Bool
3315 _elm_genlist_elm_layout_sub_object_add_enable(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3320 EOLIAN static Eina_Bool
3321 _elm_genlist_elm_widget_sub_object_add(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED, Evas_Object *sobj)
3323 Eina_Bool int_ret = EINA_FALSE;
3325 /* skipping layout's code, which registers size hint changing
3326 * callback on sub objects. this is here because items'
3327 * content_get() routines may change hints on the objects after
3328 * creation, thus issuing TOO MANY sizing_eval()'s here. they are
3329 * not needed at here anyway, so let's skip listening to those
3331 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_add(sobj));
3332 if (!int_ret) return EINA_FALSE;
3337 EOLIAN static Eina_Bool
3338 _elm_genlist_elm_widget_sub_object_del(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *sobj)
3340 Eina_Bool int_ret = EINA_FALSE;
3343 /* XXX: hack -- also skipping sizing recalculation on
3344 * sub-object-del. genlist's crazy code paths (like groups and
3345 * such) seem to issue a whole lot of deletions and Evas bitches
3346 * about too many recalculations */
3347 sd->on_sub_del = EINA_TRUE;
3349 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_del(sobj));
3350 if (!int_ret) return EINA_FALSE;
3352 sd->on_sub_del = EINA_FALSE;
3358 * This function searches the nearest visible item based on the given item.
3359 * If the given item is in the genlist viewport, this returns the given item.
3360 * Or this searches the realized items and checks the nearest fully visible item
3361 * according to the given item's position.
3363 static Elm_Object_Item *
3364 _elm_genlist_nearest_visible_item_get(Evas_Object *obj, Elm_Object_Item *eo_it)
3366 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0; // genlist viewport geometry
3367 Evas_Coord ix = 0, iy = 0, iw = 0, ih = 0; // given item geometry
3368 Evas_Coord cx = 0, cy = 0, cw = 0, ch = 0; // candidate item geometry
3369 Eina_List *item_list = NULL, *l = NULL;
3370 Elm_Object_Item *eo_item = NULL;
3371 ELM_GENLIST_DATA_GET(obj, sd);
3372 Eina_Bool search_next = EINA_FALSE;
3374 if (!eo_it) return NULL;
3375 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
3377 evas_object_geometry_get(sd->pan_obj, &vx, &vy, &vw, &vh);
3378 evas_object_geometry_get(VIEW(it), &ix, &iy, &iw, &ih); // FIXME: check if the item is realized or not
3380 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, ix, iy, iw, ih))
3382 if (!elm_object_item_disabled_get(eo_it))
3385 search_next = EINA_TRUE;
3388 item_list = elm_genlist_realized_items_get(obj);
3390 if ((iy < vy) || search_next)
3392 EINA_LIST_FOREACH(item_list, l, eo_item)
3394 ELM_GENLIST_ITEM_DATA_GET(eo_item, item);
3395 evas_object_geometry_get(VIEW(item), &cx, &cy, &cw, &ch);
3396 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, cx, cy, cw, ch) &&
3397 !elm_object_item_disabled_get(eo_item))
3399 eina_list_free(item_list);
3406 EINA_LIST_REVERSE_FOREACH(item_list, l, eo_item)
3408 ELM_GENLIST_ITEM_DATA_GET(eo_item, item);
3409 evas_object_geometry_get(VIEW(item), &cx, &cy, &cw, &ch);
3410 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, cx, cy, cw, ch) &&
3411 !elm_object_item_disabled_get(eo_item))
3413 eina_list_free(item_list);
3418 eina_list_free(item_list);
3423 EOLIAN static Eina_Bool
3424 _elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd, Elm_Object_Item *item EINA_UNUSED)
3426 Eina_Bool int_ret = EINA_FALSE;
3427 Elm_Object_Item *eo_it = NULL;
3428 Eina_Bool is_sel = EINA_FALSE;
3430 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_on_focus(NULL));
3431 if (!int_ret) return EINA_FALSE;
3433 if (elm_widget_focus_get(obj) && (sd->items) && (sd->selected) &&
3434 (!sd->last_selected_item))
3436 sd->last_selected_item = eina_list_data_get(sd->selected);
3439 if (elm_widget_focus_get(obj) && !sd->mouse_down)
3441 if (sd->last_focused_item)
3442 eo_it = sd->last_focused_item;
3443 else if (sd->last_selected_item)
3444 eo_it = sd->last_selected_item;
3445 else if (_elm_config->first_item_focus_on_first_focus_in)
3447 eo_it = elm_genlist_first_item_get(obj);
3453 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
3454 if ((!_is_no_select(it)) && (!elm_object_item_disabled_get(eo_it)))
3456 eo_it = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next));
3461 eo_it = _elm_genlist_nearest_visible_item_get(obj, eo_it);
3464 if (!_elm_config->item_select_on_focus_disable && is_sel)
3465 elm_genlist_item_selected_set(eo_it, EINA_TRUE);
3467 elm_object_item_focus_set(eo_it, EINA_TRUE);
3468 _elm_widget_focus_highlight_start(obj);
3474 if (sd->focused_item)
3476 sd->last_focused_item = sd->focused_item;
3477 _elm_genlist_item_unfocused(sd->focused_item);
3484 static Eina_Bool _elm_genlist_smart_focus_next_enable = EINA_FALSE;
3486 EOLIAN static Eina_Bool
3487 _elm_genlist_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3489 return _elm_genlist_smart_focus_next_enable;
3492 EOLIAN static Eina_Bool
3493 _elm_genlist_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3498 EOLIAN static Eina_Bool
3499 _elm_genlist_elm_widget_focus_next(Eo *obj, Elm_Genlist_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
3501 Evas_Coord x, y, w, h;
3502 Evas_Coord sx, sy, sw, sh;
3504 Eina_List *items = NULL;
3505 Eina_Bool done = EINA_FALSE;
3507 evas_object_geometry_get(sd->obj, &sx, &sy, &sw, &sh);
3509 EINA_INLIST_FOREACH(sd->blocks, itb)
3517 EINA_LIST_FOREACH(itb->items, l, it)
3521 evas_object_geometry_get(it->base->view, &x, &y, &w, &h);
3523 /* check item which displays more than half of its size */
3524 if (it->base->access_obj &&
3526 (x + (w / 2), y + (h / 2), 0, 0, sx, sy, sw, sh))
3527 items = eina_list_append(items, it->base->access_obj);
3529 if (!it->base->access_order) continue;
3533 EINA_LIST_FOREACH(it->base->access_order, subl, subo)
3534 items = eina_list_append(items, subo);
3538 else if (done) break;
3541 return elm_widget_focus_list_next_get
3542 (obj, items, eina_list_data_get, dir, next, next_item);
3546 _mirrored_set(Evas_Object *obj,
3549 ELM_GENLIST_DATA_GET(obj, sd);
3551 _item_cache_zero(sd);
3552 eo_do(obj, elm_interface_scrollable_mirrored_set(rtl));
3555 EOLIAN static Elm_Theme_Apply
3556 _elm_genlist_elm_widget_theme_apply(Eo *obj, Elm_Genlist_Data *sd)
3559 Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
3563 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
3564 if (!int_ret) return ELM_THEME_APPLY_FAILED;
3566 evas_event_freeze(evas_object_evas_get(obj));
3567 _item_cache_zero(sd);
3568 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3570 eina_hash_free_buckets(sd->size_caches);
3571 sd->minw = sd->minh = sd->realminw = 0;
3573 EINA_INLIST_FOREACH(sd->blocks, itb)
3575 if (itb->realized) _item_block_unrealize(itb);
3576 EINA_LIST_FOREACH(itb->items, l, it)
3577 it->item->mincalcd = EINA_FALSE;
3579 itb->changed = EINA_TRUE;
3581 ecore_job_del(sd->calc_job);
3582 sd->calc_job = ecore_job_add(_calc_job, obj);
3583 elm_layout_sizing_eval(obj);
3584 evas_event_thaw(evas_object_evas_get(obj));
3585 evas_event_thaw_eval(evas_object_evas_get(obj));
3590 /* FIXME: take off later. maybe this show region coords belong in the
3591 * interface (new api functions, set/get)? */
3593 _show_region_hook(void *data EINA_UNUSED,
3596 Evas_Coord x, y, w, h;
3598 ELM_GENLIST_DATA_GET_OR_RETURN(obj, sd);
3600 elm_widget_show_region_get(obj, &x, &y, &w, &h);
3601 //x & y are screen coordinates, Add with pan coordinates
3604 eo_do(obj, elm_interface_scrollable_content_region_show(x, y, w, h));
3607 //Tizen Only(20170113)
3608 EOLIAN static Eina_Bool
3609 _elm_genlist_elm_widget_translate(Eo *obj, Elm_Genlist_Data *sd)
3613 // Before calling text_get, inform user first.
3614 evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
3616 // FIXME: We should change item's height if lang is changed??
3617 EINA_INLIST_FOREACH(sd->blocks, itb)
3621 EINA_LIST_FOREACH(itb->items, l, it)
3625 elm_genlist_item_fields_update(EO_OBJ(it),
3627 ELM_GENLIST_ITEM_FIELD_TEXT);
3637 _item_highlight(Elm_Gen_Item *it)
3640 const char *selectraise;
3641 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3643 if (_is_no_select(it) ||
3645 (it->highlighted) || eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()) ||
3646 (it->item->deco_it_view))
3649 edje_object_signal_emit(VIEW(it), SIGNAL_SELECTED, "elm");
3650 if (it->deco_all_view)
3651 edje_object_signal_emit(it->deco_all_view, SIGNAL_SELECTED, "elm");
3652 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_HIGHLIGHTED, EO_OBJ(it)));
3654 selectraise = edje_object_data_get(VIEW(it), "selectraise");
3655 if ((selectraise) && (!strcmp(selectraise, "on")))
3657 if (it->deco_all_view) evas_object_stack_below(it->deco_all_view, sd->stack[1]);
3658 else evas_object_stack_below(VIEW(it), sd->stack[1]);
3659 if ((it->item->group_item) && (it->item->group_item->realized))
3660 evas_object_stack_above(it->item->VIEW(group_item), sd->stack[1]);
3662 it->highlighted = EINA_TRUE;
3666 _item_unhighlight(Elm_Gen_Item *it)
3668 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3670 if (!it->highlighted) return;
3672 edje_object_signal_emit(VIEW(it), SIGNAL_UNSELECTED, "elm");
3673 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_UNHIGHLIGHTED, EO_OBJ(it)));
3674 if (it->deco_all_view)
3675 edje_object_signal_emit
3676 (it->deco_all_view, SIGNAL_UNSELECTED, "elm");
3678 if (!it->item->nostacking)
3680 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
3682 if (it->deco_all_view) evas_object_stack_below(it->deco_all_view, sd->stack[0]);
3683 else evas_object_stack_below(VIEW(it), sd->stack[0]);
3687 if (it->deco_all_view) evas_object_stack_above(it->deco_all_view, sd->stack[0]);
3688 else evas_object_stack_above(VIEW(it), sd->stack[0]);
3691 it->highlighted = EINA_FALSE;
3695 _item_block_position_update(Eina_Inlist *list,
3700 EINA_INLIST_FOREACH(list, tmp)
3702 tmp->position = idx++;
3703 tmp->position_update = EINA_TRUE;
3708 _item_position_update(Eina_List *list,
3714 EINA_LIST_FOREACH(list, l, it)
3716 it->position = idx++;
3717 it->position_update = EINA_TRUE;
3722 _item_block_merge(Item_Block *left,
3728 EINA_LIST_FOREACH(right->items, l, it2)
3730 it2->item->block = left;
3732 left->changed = EINA_TRUE;
3734 left->items = eina_list_merge(left->items, right->items);
3738 _item_block_del(Elm_Gen_Item *it)
3741 Item_Block *itb = it->item->block;
3742 Eina_Bool block_changed = EINA_FALSE;
3743 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3745 itb->items = eina_list_remove(itb->items, it);
3747 itb->changed = EINA_TRUE;
3748 ecore_job_del(sd->calc_job);
3749 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
3754 il = EINA_INLIST_GET(itb);
3755 itbn = (Item_Block *)(il->next);
3757 it->parent->item->items =
3758 eina_list_remove(it->parent->item->items, EO_OBJ(it));
3761 _item_block_position_update(il->next, itb->position);
3762 sd->blocks = eina_inlist_remove(sd->blocks, il);
3765 if (itbn) itbn->changed = EINA_TRUE;
3769 if (itb->count < (sd->max_items_per_block / 2))
3774 il = EINA_INLIST_GET(itb);
3775 itbp = (Item_Block *)(il->prev);
3776 itbn = (Item_Block *)(il->next);
3778 /* merge block with previous */
3780 ((itbp->count + itb->count) <
3781 (sd->max_items_per_block +
3782 (sd->max_items_per_block / 2))))
3784 _item_block_merge(itbp, itb);
3785 _item_block_position_update
3786 (EINA_INLIST_GET(itb)->next, itb->position);
3787 sd->blocks = eina_inlist_remove
3788 (sd->blocks, EINA_INLIST_GET(itb));
3790 block_changed = EINA_TRUE;
3792 /* merge block with next */
3794 ((itbn->count + itb->count) <
3795 (sd->max_items_per_block +
3796 (sd->max_items_per_block / 2))))
3798 _item_block_merge(itb, itbn);
3799 _item_block_position_update
3800 (EINA_INLIST_GET(itbn)->next, itbn->position);
3802 eina_inlist_remove(sd->blocks, EINA_INLIST_GET(itbn));
3804 block_changed = EINA_TRUE;
3811 sd->pan_changed = EINA_TRUE;
3812 evas_object_smart_changed(sd->pan_obj);
3813 ecore_job_del(sd->calc_job);
3814 sd->calc_job = NULL;
3819 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3821 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3823 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3824 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
3825 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3826 _elm_genlist_item_position_state_update(it);
3827 _elm_genlist_item_state_update(it);
3829 if (it->item->wsd->reorder_mode)
3831 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
3832 edje_object_signal_emit(it->deco_all_view, SIGNAL_REORDER_MODE_UNSET,
3836 _view_clear(it->deco_all_view, &(GL_IT(it)->deco_all_texts),
3837 &(GL_IT(it)->deco_all_contents));
3839 edje_object_signal_emit(VIEW(it), SIGNAL_DECORATE_DISABLED, "elm");
3841 edje_object_message_signal_process(it->deco_all_view);
3842 _item_mouse_callbacks_del(it, it->deco_all_view);
3843 _item_mouse_callbacks_add(it, VIEW(it));
3845 ELM_SAFE_FREE(it->deco_all_view, evas_object_del);
3847 it->item->decorate_all_item_realized = EINA_FALSE;
3851 _elm_genlist_item_del_not_serious(Elm_Gen_Item *it)
3853 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3854 Elm_Object_Item *eo_it = EO_OBJ(it);
3856 eo_do(eo_it, elm_wdg_item_pre_notify_del());
3860 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
3861 if (sd->deselecting)
3862 sd->deselecting = eina_list_remove(sd->deselecting, it);
3864 if (sd->last_focused_item == eo_it)
3865 sd->last_focused_item = NULL;
3866 if (sd->focused_item == eo_it)
3867 sd->focused_item = NULL;
3868 if (sd->last_selected_item == eo_it)
3869 sd->last_selected_item = NULL;
3871 if (it->itc->func.del)
3872 it->itc->func.del((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it));
3876 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
3878 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3881 _elm_genlist_item_del_not_serious(it);
3883 //(it->walking == -1) means it's already removed from the list.
3884 if (it->walking != -1)
3885 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
3886 if (it->tooltip.del_cb)
3887 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
3888 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
3889 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
3890 sd->group_items = eina_list_remove(sd->group_items, it);
3892 ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
3893 ecore_job_del(sd->calc_job);
3894 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
3896 ELM_SAFE_FREE(it->item, free);
3900 _item_del(Elm_Gen_Item *it)
3902 Evas_Object *obj = WIDGET(it);
3903 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3905 evas_event_freeze(evas_object_evas_get(obj));
3907 if (it->item->rel_revs)
3910 EINA_LIST_FREE(it->item->rel_revs, tmp)
3912 if (tmp->item->queued && !(tmp->base)->on_deletion)
3914 tmp->item->queued = EINA_FALSE;
3915 sd->queue = eina_list_remove(sd->queue, tmp);
3916 _item_process(sd, tmp);
3917 _item_process_post(sd, tmp, EINA_TRUE);
3919 tmp->item->rel = NULL;
3924 it->item->rel->item->rel_revs =
3925 eina_list_remove(it->item->rel->item->rel_revs, it);
3927 elm_genlist_item_subitems_clear(EO_OBJ(it));
3928 if (sd->show_item == it) sd->show_item = NULL;
3929 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
3930 if (it->item->decorate_all_item_realized) _decorate_all_item_unrealize(it);
3931 if (it->item->block) _item_block_del(it);
3932 if (it->item->queued)
3933 sd->queue = eina_list_remove(sd->queue, it);
3934 if (sd->anchor_item == it)
3936 sd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3937 if (!sd->anchor_item)
3939 ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3941 if (sd->expanded_item == it)
3943 if (sd->tree_effect_animator)
3945 _item_tree_effect_finish(sd);
3946 ELM_SAFE_FREE(sd->tree_effect_animator, ecore_animator_del);
3948 sd->expanded_item = NULL;
3949 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
3951 if (sd->expanded_next_item == it) sd->expanded_next_item = NULL;
3952 if (sd->move_items) sd->move_items = eina_list_remove(sd->move_items, it);
3954 it->parent->item->items = eina_list_remove(it->parent->item->items, EO_OBJ(it));
3955 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
3956 _elm_genlist_item_del_serious(it);
3958 if (it->itc->refcount <= 1 && eina_hash_find(sd->size_caches, &(it->itc)))
3959 eina_hash_del_by_key(sd->size_caches, it->itc);
3960 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
3961 evas_event_thaw(evas_object_evas_get(obj));
3962 evas_event_thaw_eval(evas_object_evas_get(obj));
3963 if (!sd->queue) _item_scroll(sd);
3967 _item_unselect(Elm_Gen_Item *it)
3969 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3971 _item_unhighlight(it); /* unhighlight the item first */
3972 if (!it->selected) return; /* then check whether the item is selected */
3974 if (GL_IT(it)->wsd->focus_on_selection_enabled)
3978 EINA_LIST_FOREACH(it->item_focus_chain, l, eobj)
3979 elm_object_focus_set(eobj, EINA_FALSE);
3982 it->selected = EINA_FALSE;
3983 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
3984 eo_do(WIDGET(it), eo_event_callback_call
3985 (EVAS_SELECTABLE_INTERFACE_EVENT_UNSELECTED, EO_OBJ(it)));
3986 if (_elm_config->atspi_mode)
3987 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_SELECTED, EINA_FALSE);
3991 _item_mouse_in_cb(void *data,
3992 Evas *evas EINA_UNUSED,
3993 Evas_Object *obj EINA_UNUSED,
3994 void *event_info EINA_UNUSED)
3996 Elm_Gen_Item *it = data;
3997 if (!elm_object_item_disabled_get(EO_OBJ(it)) &&
3998 (_elm_config->focus_move_policy == ELM_FOCUS_MOVE_POLICY_IN))
3999 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
4003 _item_mouse_move_cb(void *data,
4004 Evas *evas EINA_UNUSED,
4008 Elm_Gen_Item *it = data;
4009 Evas_Event_Mouse_Move *ev = event_info;
4010 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
4011 Evas_Coord minw = 0, minh = 0, x, y, w, h, dx, dy, adx, ady;
4012 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4013 Elm_Object_Item *eo_it = EO_OBJ(it);
4015 evas_object_geometry_get(obj, &x, &y, &w, &h);
4016 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4020 sd->on_hold = EINA_TRUE;
4021 if ((!sd->wasselected) && (!it->flipped))
4025 else if (ELM_RECTS_POINT_OUT(x, y, w, h, ev->cur.canvas.x, ev->cur.canvas.y) &&
4028 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4029 if ((!sd->wasselected) && (!it->flipped))
4031 it->base->still_in = EINA_FALSE;
4034 if (sd->multi_touched)
4036 sd->cur_x = ev->cur.canvas.x;
4037 sd->cur_y = ev->cur.canvas.y;
4040 if ((it->dragging) && (it->down))
4042 if (sd->movements == SWIPE_MOVES)
4043 sd->swipe = EINA_TRUE;
4046 sd->history[sd->movements].x = ev->cur.canvas.x;
4047 sd->history[sd->movements].y = ev->cur.canvas.y;
4048 if (abs((sd->history[sd->movements].x -
4049 sd->history[0].x)) > 40)
4050 sd->swipe = EINA_TRUE;
4054 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4055 eo_do(WIDGET(it), eo_event_callback_call
4056 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG, eo_it));
4059 if ((!it->down) || (sd->longpressed))
4061 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4062 if ((sd->reorder_mode) && (sd->reorder_it))
4064 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
4066 if (ev->cur.canvas.y < (oy + (sd->reorder_it->item->h / 2)))
4067 sd->reorder_fast = 1;
4068 else if (ev->cur.canvas.y > (oy + oh - (sd->reorder_it->item->h / 2)))
4069 sd->reorder_fast = -1;
4070 else sd->reorder_fast = 0;
4072 it_scrl_y = ev->cur.canvas.y - sd->reorder_it->dy;
4074 if (!sd->reorder_start_y)
4075 sd->reorder_start_y = it->item->block->y + it->y;
4079 else if (it_scrl_y + sd->reorder_it->item->h > oy + oh)
4080 y_pos = oy + oh - sd->reorder_it->item->h;
4084 if (it->deco_all_view)
4085 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
4087 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
4089 ecore_job_del(sd->calc_job);
4090 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
4094 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
4095 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
4097 evas_object_geometry_get(obj, &x, &y, &w, &h);
4098 x = ev->cur.canvas.x - x;
4099 y = ev->cur.canvas.y - y;
4102 if (adx < 0) adx = -dx;
4106 if (ady < 0) ady = -dy;
4111 // gah! annoying drag detection - leave this alone
4114 if (minw < h) minw = h;
4115 if (minh < h) minh = h;
4119 if (minw < w) minw = w;
4120 if (minh < w) minh = w;
4122 if (minw < 5) minw = 5;
4123 if (minh < 5) minh = 5;
4125 if ((adx > minw) || (ady > minh))
4127 it->dragging = EINA_TRUE;
4128 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4132 eo_do(WIDGET(it), eo_event_callback_call
4133 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_UP, eo_it));
4137 eo_do(WIDGET(it), eo_event_callback_call
4138 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_LEFT, eo_it));
4140 eo_do(WIDGET(it), eo_event_callback_call
4141 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_RIGHT, eo_it));
4147 eo_do(WIDGET(it), eo_event_callback_call
4148 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_DOWN, eo_it));
4152 eo_do(WIDGET(it), eo_event_callback_call
4153 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_LEFT, eo_it));
4155 eo_do(WIDGET(it), eo_event_callback_call
4156 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_RIGHT, eo_it));
4163 _long_press_cb(void *data)
4166 Elm_Gen_Item *it = data;
4167 Elm_Object_Item *eo_it_tmp;
4169 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4171 if (_is_no_select(it) ||
4172 eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()) || (it->dragging))
4175 sd->longpressed = EINA_TRUE;
4176 eo_do(WIDGET(it), eo_event_callback_call
4177 (EVAS_CLICKABLE_INTERFACE_EVENT_LONGPRESSED, EO_OBJ(it)));
4178 if ((sd->reorder_mode) && !(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP))
4180 sd->reorder_it = it;
4181 sd->reorder_start_y = 0;
4182 if (it->deco_all_view)
4183 evas_object_stack_below(it->deco_all_view, sd->stack[1]);
4185 evas_object_stack_below(VIEW(it), sd->stack[1]);
4187 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
4188 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
4189 (EINA_FALSE, EINA_FALSE));
4191 list = elm_genlist_realized_items_get
4193 EINA_LIST_FREE(list, eo_it_tmp)
4195 ELM_GENLIST_ITEM_DATA_GET(eo_it_tmp, it_tmp);
4196 if (it != it_tmp) _item_unselect(it_tmp);
4199 if (elm_genlist_item_expanded_get(EO_OBJ(it)))
4201 elm_genlist_item_expanded_set(EO_OBJ(it), EINA_FALSE);
4202 return ECORE_CALLBACK_RENEW;
4205 if (!sd->decorate_all_mode)
4207 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
4208 //TIZEN_ONLY(20160520): genlist: added atspi support for drag n drop
4209 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_ANIMATED, EINA_TRUE);
4215 it->long_timer = NULL;
4216 return ECORE_CALLBACK_CANCEL;
4220 _swipe_do(Elm_Gen_Item *it)
4224 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4226 if (_is_no_select(it) ||
4227 eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get())) return;
4229 sd->swipe = EINA_FALSE;
4230 for (i = 0; i < sd->movements; i++)
4232 sum += sd->history[i].x;
4233 if (abs(sd->history[0].y - sd->history[i].y) > 10)
4237 sum /= sd->movements;
4238 if (abs(sum - sd->history[0].x) <= 10) return;
4239 eo_do(WIDGET(it), eo_event_callback_call
4240 (ELM_GENLIST_EVENT_SWIPE, EO_OBJ(it)));
4244 _swipe_cancel(void *data)
4246 Elm_Gen_Item *it = data;
4247 if (!it) return ECORE_CALLBACK_CANCEL;
4248 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4250 sd->swipe = EINA_FALSE;
4253 return ECORE_CALLBACK_RENEW;
4257 _multi_cancel(void *data)
4259 ELM_GENLIST_DATA_GET(data, sd);
4261 if (!sd) return ECORE_CALLBACK_CANCEL;
4262 sd->multi_timeout = EINA_TRUE;
4264 return ECORE_CALLBACK_RENEW;
4268 _multi_touch_gesture_eval(Elm_Gen_Item *it)
4270 Evas_Coord minw = 0, minh = 0;
4271 Evas_Coord off_x, off_y, off_mx, off_my;
4272 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4273 Elm_Object_Item *eo_it = EO_OBJ(it);
4275 sd->multi_touched = EINA_FALSE;
4276 ELM_SAFE_FREE(sd->multi_timer, ecore_timer_del);
4277 if (sd->multi_timeout)
4279 sd->multi_timeout = EINA_FALSE;
4283 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
4284 off_x = abs(sd->cur_x - sd->prev_x);
4285 off_y = abs(sd->cur_y - sd->prev_y);
4286 off_mx = abs(sd->cur_mx - sd->prev_mx);
4287 off_my = abs(sd->cur_my - sd->prev_my);
4289 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw)
4290 || (off_my > minh)))
4292 if ((off_x + off_mx) > (off_y + off_my))
4294 if ((sd->cur_x > sd->prev_x) && (sd->cur_mx > sd->prev_mx))
4295 eo_do(WIDGET(it), eo_event_callback_call
4296 (ELM_GENLIST_EVENT_MULTI_SWIPE_RIGHT, eo_it));
4297 else if ((sd->cur_x < sd->prev_x) && (sd->cur_mx < sd->prev_mx))
4298 eo_do(WIDGET(it), eo_event_callback_call
4299 (ELM_GENLIST_EVENT_MULTI_SWIPE_LEFT, eo_it));
4300 else if (abs(sd->cur_x - sd->cur_mx) >
4301 abs(sd->prev_x - sd->prev_mx))
4302 eo_do(WIDGET(it), eo_event_callback_call
4303 (ELM_GENLIST_EVENT_MULTI_PINCH_OUT, eo_it));
4305 eo_do(WIDGET(it), eo_event_callback_call
4306 (ELM_GENLIST_EVENT_MULTI_PINCH_IN, eo_it));
4310 if ((sd->cur_y > sd->prev_y) && (sd->cur_my > sd->prev_my))
4311 eo_do(WIDGET(it), eo_event_callback_call
4312 (ELM_GENLIST_EVENT_MULTI_SWIPE_DOWN, eo_it));
4313 else if ((sd->cur_y < sd->prev_y) && (sd->cur_my < sd->prev_my))
4314 eo_do(WIDGET(it), eo_event_callback_call
4315 (ELM_GENLIST_EVENT_MULTI_SWIPE_UP, eo_it));
4316 else if (abs(sd->cur_y - sd->cur_my) >
4317 abs(sd->prev_y - sd->prev_my))
4318 eo_do(WIDGET(it), eo_event_callback_call
4319 (ELM_GENLIST_EVENT_MULTI_PINCH_OUT, eo_it));
4321 eo_do(WIDGET(it), eo_event_callback_call
4322 (ELM_GENLIST_EVENT_MULTI_PINCH_IN, eo_it));
4326 sd->multi_timeout = EINA_FALSE;
4330 _item_multi_down_cb(void *data,
4331 Evas *evas EINA_UNUSED,
4332 Evas_Object *obj EINA_UNUSED,
4335 Elm_Gen_Item *it = data;
4336 Evas_Event_Multi_Down *ev = event_info;
4337 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4339 if ((sd->multi_device != 0) || (sd->multi_touched)
4340 || (sd->multi_timeout))
4343 sd->multi_device = ev->device;
4344 sd->multi_down = EINA_TRUE;
4345 sd->multi_touched = EINA_TRUE;
4346 sd->prev_mx = ev->canvas.x;
4347 sd->prev_my = ev->canvas.y;
4348 if (!sd->wasselected) _item_unselect(it);
4349 sd->wasselected = EINA_FALSE;
4350 sd->longpressed = EINA_FALSE;
4351 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4354 it->dragging = EINA_FALSE;
4355 eo_do(WIDGET(it), eo_event_callback_call
4356 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_STOP, EO_OBJ(it)));
4358 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
4361 sd->swipe = EINA_FALSE;
4363 sd->on_hold = EINA_FALSE;
4368 _item_multi_up_cb(void *data,
4369 Evas *evas EINA_UNUSED,
4370 Evas_Object *obj EINA_UNUSED,
4373 Elm_Gen_Item *it = data;
4374 Evas_Event_Multi_Up *ev = event_info;
4375 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4377 if (sd->multi_device != ev->device) return;
4378 sd->multi_device = 0;
4379 sd->multi_down = EINA_FALSE;
4380 if (sd->mouse_down) return;
4381 _multi_touch_gesture_eval(data);
4385 _item_multi_move_cb(void *data,
4386 Evas *evas EINA_UNUSED,
4387 Evas_Object *obj EINA_UNUSED,
4390 Elm_Gen_Item *it = data;
4391 Evas_Event_Multi_Move *ev = event_info;
4392 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4394 if (sd->multi_device != ev->device) return;
4395 sd->cur_mx = ev->cur.canvas.x;
4396 sd->cur_my = ev->cur.canvas.y;
4400 _item_mouse_down_cb(void *data,
4401 Evas *evas EINA_UNUSED,
4406 Evas_Event_Mouse_Down *ev = event_info;
4407 Elm_Gen_Item *it = data;
4409 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4410 Elm_Object_Item *eo_it = EO_OBJ(it);
4412 if (ev->button == 3)
4414 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4415 it->dx = ev->canvas.x - x;
4416 it->dy = ev->canvas.y - y;
4419 if (ev->button != 1) return;
4420 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4422 sd->on_hold = EINA_TRUE;
4425 it->down = EINA_TRUE;
4426 it->dragging = EINA_FALSE;
4427 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4428 it->dx = ev->canvas.x - x;
4429 it->dy = ev->canvas.y - y;
4430 sd->mouse_down = EINA_TRUE;
4431 if (!sd->multi_touched)
4433 sd->prev_x = ev->canvas.x;
4434 sd->prev_y = ev->canvas.y;
4435 sd->multi_timeout = EINA_FALSE;
4436 ecore_timer_del(sd->multi_timer);
4437 sd->multi_timer = ecore_timer_add(MULTI_DOWN_TIME, _multi_cancel, sd->obj);
4439 sd->longpressed = EINA_FALSE;
4440 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = EINA_TRUE;
4441 else sd->on_hold = EINA_FALSE;
4442 if (sd->on_hold) return;
4443 sd->wasselected = it->selected;
4445 ecore_timer_del(it->item->swipe_timer);
4446 it->item->swipe_timer = ecore_timer_add(SWIPE_TIME, _swipe_cancel, it);
4447 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4449 it->long_timer = ecore_timer_add
4450 (sd->longpress_timeout, _long_press_cb, it);
4452 it->long_timer = NULL;
4453 sd->swipe = EINA_FALSE;
4455 it->base->still_in = EINA_TRUE;
4457 if (_is_no_select(it) ||
4458 eo_do_ret((Eo *)eo_it, tmp, elm_wdg_item_disabled_get()))
4461 // and finally call the user callbacks.
4462 // NOTE: keep this code at the bottom, as the user can change the
4463 // list at this point (clear, delete, etc...)
4464 _item_highlight(it);
4465 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
4467 eo_do(WIDGET(it), eo_event_callback_call
4468 (EVAS_CLICKABLE_INTERFACE_EVENT_CLICKED_DOUBLE, eo_it));
4469 eo_do(WIDGET(it), eo_event_callback_call
4470 (ELM_GENLIST_EVENT_ACTIVATED, eo_it));
4472 eo_do(WIDGET(it), eo_event_callback_call
4473 (EVAS_CLICKABLE_INTERFACE_EVENT_PRESSED, eo_it));
4477 _item_block_new(Elm_Genlist_Data *sd,
4482 itb = calloc(1, sizeof(Item_Block));
4483 if (!itb) return NULL;
4487 sd->blocks = eina_inlist_prepend(sd->blocks, EINA_INLIST_GET(itb));
4488 _item_block_position_update(sd->blocks, 0);
4492 sd->blocks = eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4493 itb->position_update = EINA_TRUE;
4494 if (sd->blocks != EINA_INLIST_GET(itb))
4497 ((Item_Block *)(EINA_INLIST_GET(itb)->prev))->position + 1;
4511 * This function adds an item to a block's item list. This may or may not
4512 * rearrange existing blocks and create a new block.
4516 _item_block_add(Elm_Genlist_Data *sd,
4519 Item_Block *itb = NULL;
4521 // when a new item does not depend on another item
4527 itb = calloc(1, sizeof(Item_Block));
4528 if (!itb) return EINA_FALSE;
4530 if (!it->item->rel->item->block)
4533 eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4534 itb->items = eina_list_append(itb->items, it);
4535 itb->position_update = EINA_TRUE;
4536 it->position = eina_list_count(itb->items);
4537 it->position_update = EINA_TRUE;
4539 if (sd->blocks != EINA_INLIST_GET(itb))
4543 (EINA_INLIST_GET(itb)->prev))->position + 1;
4554 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4555 if (it->item->before)
4557 sd->blocks = eina_inlist_prepend_relative
4558 (sd->blocks, EINA_INLIST_GET(itb),
4559 EINA_INLIST_GET(it->item->rel->item->block));
4561 eina_list_prepend_relative_list(itb->items, it, tmp);
4563 /* Update index from where we prepended */
4564 _item_position_update
4565 (eina_list_prev(tmp), it->item->rel->position);
4566 _item_block_position_update
4567 (EINA_INLIST_GET(itb),
4568 it->item->rel->item->block->position);
4572 sd->blocks = eina_inlist_append_relative
4573 (sd->blocks, EINA_INLIST_GET(itb),
4574 EINA_INLIST_GET(it->item->rel->item->block));
4576 eina_list_append_relative_list(itb->items, it, tmp);
4578 /* Update block index from where we appended */
4579 _item_position_update
4580 (eina_list_next(tmp), it->item->rel->position + 1);
4581 _item_block_position_update
4582 (EINA_INLIST_GET(itb),
4583 it->item->rel->item->block->position + 1);
4589 // item move_before, prepend, insert_before, sorted_insert with before
4590 if (it->item->before)
4594 itb = (Item_Block *)(sd->blocks);
4595 if (itb->count >= sd->max_items_per_block)
4597 itb = _item_block_new(sd, EINA_TRUE);
4598 if (!itb) return EINA_FALSE;
4603 itb = _item_block_new(sd, EINA_TRUE);
4604 if (!itb) return EINA_FALSE;
4606 itb->items = eina_list_prepend(itb->items, it);
4608 _item_position_update(itb->items, 0);
4610 // item move_after, append, insert_after, sorted_insert without before
4615 itb = (Item_Block *)(sd->blocks->last);
4616 if (itb->count >= sd->max_items_per_block)
4618 itb = _item_block_new(sd, EINA_FALSE);
4619 if (!itb) return EINA_FALSE;
4624 itb = _item_block_new(sd, EINA_FALSE);
4625 if (!itb) return EINA_FALSE;
4627 itb->items = eina_list_append(itb->items, it);
4628 it->position = eina_list_count(itb->items);
4632 // when a new item depends on another item
4637 if (it->item->rel->item->queued)
4639 /* NOTE: for a strange reason eina_list and eina_inlist
4640 don't have the same property on sorted insertion
4641 order, so the queue is not always ordered like the
4642 item list. This lead to issue where we depend on an
4643 item that is not yet created. As a quick work around,
4644 we reschedule the calc of the item and stop reordering
4645 the list to prevent any nasty issue to show up here.
4647 sd->queue = eina_list_append(sd->queue, it);
4648 sd->requeued = EINA_TRUE;
4649 it->item->queued = EINA_TRUE;
4653 itb = it->item->rel->item->block;
4654 if (!itb) goto newblock;
4655 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4656 if (it->item->before)
4658 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4659 _item_position_update
4660 (eina_list_prev(tmp), it->item->rel->position);
4664 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4665 _item_position_update
4666 (eina_list_next(tmp), it->item->rel->position + 1);
4671 itb->changed = EINA_TRUE;
4672 it->item->block = itb;
4673 ecore_job_del(itb->sd->calc_job);
4674 itb->sd->calc_job = ecore_job_add(_calc_job, itb->sd->obj);
4676 if (itb->count > itb->sd->max_items_per_block)
4681 Eina_Bool done = EINA_FALSE;
4683 newc = itb->count / 2;
4685 if (EINA_INLIST_GET(itb)->prev)
4687 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4689 if (itbp->count + newc < sd->max_items_per_block / 2)
4691 /* moving items to previous block */
4692 while ((itb->count > newc) && (itb->items))
4694 it2 = eina_list_data_get(itb->items);
4695 itb->items = eina_list_remove_list
4696 (itb->items, itb->items);
4699 itbp->items = eina_list_append(itbp->items, it2);
4700 it2->item->block = itbp;
4703 if (it2->realized) itbp->realized = EINA_TRUE;
4710 if (!done && EINA_INLIST_GET(itb)->next)
4712 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4714 if (itbn->count + newc < sd->max_items_per_block / 2)
4716 /* moving items to next block */
4717 while ((itb->count > newc) && (itb->items))
4721 l = eina_list_last(itb->items);
4722 it2 = eina_list_data_get(l);
4723 itb->items = eina_list_remove_list(itb->items, l);
4726 itbn->items = eina_list_prepend(itbn->items, it2);
4727 it2->item->block = itbn;
4730 if (it2->realized) itbn->realized = EINA_TRUE;
4739 /* moving items to new block */
4740 itb2 = calloc(1, sizeof(Item_Block));
4741 if (!itb2) return EINA_FALSE;
4744 eina_inlist_append_relative(sd->blocks, EINA_INLIST_GET(itb2),
4745 EINA_INLIST_GET(itb));
4746 itb2->changed = EINA_TRUE;
4747 while ((itb->count > newc) && (itb->items))
4751 l = eina_list_last(itb->items);
4753 itb->items = eina_list_remove_list(itb->items, l);
4756 itb2->items = eina_list_prepend(itb2->items, it2);
4757 it2->item->block = itb2;
4760 if (it2->realized) itb2->realized = EINA_TRUE;
4769 _item_process(Elm_Genlist_Data *sd,
4772 if (!_item_block_add(sd, it)) return EINA_FALSE;
4774 _item_block_realize(it->item->block);
4780 _item_process_post(Elm_Genlist_Data *sd,
4784 Eina_Bool show_me = EINA_FALSE;
4786 if (it->item->block->changed)
4788 show_me = _item_block_recalc
4789 (it->item->block, it->item->block->num, qadd);
4790 it->item->block->changed = 0;
4791 if (sd->pan_changed)
4793 evas_object_smart_changed(sd->pan_obj);
4794 ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
4797 if (show_me) it->item->block->show_me = EINA_TRUE;
4799 /* when prepending, move the scroller along with the first selected
4800 * item to create the illusion that we're watching the selected
4801 * item this prevents the selected item being scrolled off the
4804 if (sd->selected && it->item->before)
4806 //FIXME: There are issue about wrong list positioning in prepend cases.
4807 // To prevent the issue, allocate repositioning in smart calculate.
4810 Elm_Object_Item *eo_it2;
4812 eo_it2 = sd->selected->data;
4813 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
4814 if (!it2->item->block) return;
4816 eo_do(sd->obj, elm_interface_scrollable_content_pos_get(NULL, &y));
4817 evas_object_geometry_get(sd->pan_obj, NULL, NULL, NULL, &h);
4818 if ((it->y + it->item->block->y > y + h) ||
4819 (it->y + it->item->block->y + it->item->h < y))
4820 /* offscreen, just update */
4821 eo_do(sd->obj, elm_interface_scrollable_content_region_show
4822 (it2->x + it2->item->block->x, y,
4823 it2->item->block->w, h));
4825 eo_do(sd->obj, elm_interface_scrollable_content_region_show
4826 (it->x + it->item->block->x,
4827 y + it->item->h, it->item->block->w, h));
4829 sd->prepend_items = eina_list_append(sd->prepend_items, it);
4834 _queue_process(Elm_Genlist_Data *sd)
4839 t0 = ecore_time_get();
4840 for (n = 0; (sd->queue) && (n < 128); n++)
4844 it = eina_list_data_get(sd->queue);
4845 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
4846 it->item->queued = EINA_FALSE;
4847 if (!_item_process(sd, it)) continue;
4848 t = ecore_time_get();
4849 _item_process_post(sd, it, EINA_TRUE);
4850 /* same as eina_inlist_count > 1 */
4851 if (sd->blocks && sd->blocks->next)
4853 if ((t - t0) > (ecore_animator_frametime_get())) break;
4861 _idle_process(void *data,
4864 Elm_Genlist_Data *sd = data;
4866 if (_queue_process(sd) > 0) *wakeup = EINA_TRUE;
4869 return ECORE_CALLBACK_CANCEL;
4871 return ECORE_CALLBACK_RENEW;
4875 _item_idle_enterer(void *data)
4877 Eina_Bool wakeup = EINA_FALSE;
4878 ELM_GENLIST_DATA_GET(data, sd);
4879 Eina_Bool ok = _idle_process(sd, &wakeup);
4884 ecore_job_del(sd->calc_job);
4885 sd->calc_job = ecore_job_add(_calc_job, data);
4887 if (ok == ECORE_CALLBACK_CANCEL) sd->queue_idle_enterer = NULL;
4893 _requeue_idle_enterer(Elm_Genlist_Data *sd)
4895 ecore_idle_enterer_del(sd->queue_idle_enterer);
4896 sd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, sd->obj);
4900 _item_queue(Elm_Genlist_Data *sd,
4906 if (it->item->queued) return;
4907 it->item->queued = EINA_TRUE;
4908 if (cb && !sd->requeued)
4909 sd->queue = eina_list_sorted_insert(sd->queue, cb, it);
4911 sd->queue = eina_list_append(sd->queue, it);
4912 // FIXME: why does a freeze then thaw here cause some genlist
4913 // elm_genlist_item_append() to be much much slower?
4914 // evas_event_freeze(evas_object_evas_get(sd->obj));
4915 while ((sd->queue) && ((!sd->blocks) || (!sd->blocks->next)))
4917 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
4920 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
4921 while ((sd->queue) && (sd->blocks) &&
4922 ((sd->homogeneous) || it->itc->homogeneous) && (sd->mode == ELM_LIST_COMPRESS))
4924 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
4928 // evas_event_thaw(evas_object_evas_get(sd->obj));
4929 // evas_event_thaw_eval(evas_object_evas_get(sd->obj));
4930 evas_object_geometry_get(sd->obj, NULL, NULL, &w, NULL);
4931 if (w > 0) _requeue_idle_enterer(sd);
4935 /* If the application wants to know the relative item, use
4936 * elm_genlist_item_prev_get(it)*/
4938 _item_move_after(Elm_Gen_Item *it,
4939 Elm_Gen_Item *after)
4943 if (it == after) return;
4944 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4947 eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
4948 if (it->item->block) _item_block_del(it);
4950 sd->items = eina_inlist_append_relative
4951 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4953 it->item->rel->item->rel_revs =
4954 eina_list_remove(it->item->rel->item->rel_revs, it);
4955 it->item->rel = after;
4956 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
4957 it->item->before = EINA_FALSE;
4958 if (after->item->group_item) it->item->group_item = after->item->group_item;
4959 _item_queue(sd, it, NULL);
4961 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_MOVED_AFTER, EO_OBJ(it)));
4965 _access_activate_cb(void *data EINA_UNUSED,
4966 Evas_Object *part_obj EINA_UNUSED,
4967 Elm_Object_Item *eo_it)
4969 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
4972 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4979 _item_highlight(it);
4989 while (sd->selected)
4991 Elm_Object_Item *eo_sel = sd->selected->data;
4992 Elm_Gen_Item *sel = eo_data_scope_get(eo_sel, ELM_GENLIST_ITEM_CLASS);
4993 _item_unselect(sel);
4998 const Eina_List *l, *l_next;
4999 Elm_Object_Item *eo_it2;
5001 EINA_LIST_FOREACH_SAFE(sd->selected, l, l_next, eo_it2)
5003 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
5005 _item_unselect(it2);
5008 _item_highlight(it);
5013 /* If the application wants to know the relative item, use
5014 * elm_genlist_item_next_get(it)*/
5016 _item_move_before(Elm_Gen_Item *it,
5017 Elm_Gen_Item *before)
5020 if (!before) return;
5021 if (it == before) return;
5022 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5025 eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
5026 if (it->item->block) _item_block_del(it);
5027 sd->items = eina_inlist_prepend_relative
5028 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
5030 it->item->rel->item->rel_revs =
5031 eina_list_remove(it->item->rel->item->rel_revs, it);
5032 it->item->rel = before;
5033 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
5034 it->item->before = EINA_TRUE;
5035 if (before->item->group_item)
5036 it->item->group_item = before->item->group_item;
5037 _item_queue(sd, it, NULL);
5039 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_MOVED_BEFORE, EO_OBJ(it)));
5043 _item_mouse_up_cb(void *data,
5044 Evas *evas EINA_UNUSED,
5045 Evas_Object *obj EINA_UNUSED,
5049 Evas_Event_Mouse_Up *ev = event_info;
5050 Eina_Bool dragged = EINA_FALSE;
5051 Elm_Gen_Item *it = data;
5052 Evas_Coord x, y, dx, dy;
5054 if ((ev->button == 3) && (!it->dragging))
5056 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
5057 dx = it->dx - (ev->canvas.x - x);
5058 dy = it->dy - (ev->canvas.y - y);
5059 if (dx < 0) dx = -dx;
5060 if (dy < 0) dy = -dy;
5061 if ((dx < 5) && (dy < 5))
5062 eo_do(WIDGET(it), eo_event_callback_call
5063 (EVAS_CLICKABLE_INTERFACE_EVENT_CLICKED_RIGHT, EO_OBJ(it)));
5067 if (ev->button != 1) return;
5068 it->down = EINA_FALSE;
5069 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5071 sd->mouse_down = EINA_FALSE;
5072 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_RELEASED, EO_OBJ(it)));
5073 if (sd->multi_touched)
5075 if ((!sd->multi) && (!it->selected) && (it->highlighted))
5076 _item_unhighlight(it);
5077 if (sd->multi_down) return;
5078 _multi_touch_gesture_eval(it);
5081 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
5082 sd->on_hold = EINA_TRUE;
5083 else sd->on_hold = EINA_FALSE;
5084 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
5087 it->dragging = EINA_FALSE;
5088 eo_do(WIDGET(it), eo_event_callback_call
5089 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_STOP, EO_OBJ(it)));
5092 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
5093 if (sd->multi_timer)
5095 ELM_SAFE_FREE(sd->multi_timer, ecore_timer_del);
5096 sd->multi_timeout = EINA_FALSE;
5100 if (!sd->wasselected) _item_unselect(it);
5102 sd->longpressed = EINA_FALSE;
5103 sd->on_hold = EINA_FALSE;
5104 sd->wasselected = EINA_FALSE;
5107 if ((sd->reorder_mode) && (sd->reorder_it))
5109 Evas_Coord it_scrl_y = ev->canvas.y - sd->reorder_it->dy;
5110 sd->reorder_fast = 0;
5112 if (sd->reorder_rel &&
5113 (sd->reorder_it->parent == sd->reorder_rel->parent))
5115 if (it_scrl_y <= sd->reorder_rel->item->scrl_y)
5116 _item_move_before(sd->reorder_it, sd->reorder_rel);
5118 _item_move_after(sd->reorder_it, sd->reorder_rel);
5119 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_MOVED, EO_OBJ(it)));
5123 ecore_job_del(sd->calc_job);
5124 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
5126 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_DISABLED, "elm");
5127 //TIZEN_ONLY(20160520): genlist: added atspi support for drag n drop
5128 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_ANIMATED, EINA_FALSE);
5130 sd->reorder_it = sd->reorder_rel = NULL;
5131 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5132 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
5133 (sd->h_bounce, sd->v_bounce));
5135 if (sd->longpressed)
5137 if (!sd->wasselected) _item_unselect(it);
5138 sd->longpressed = EINA_FALSE;
5139 sd->wasselected = EINA_FALSE;
5144 if (it->want_unrealize)
5146 _elm_genlist_item_unrealize(it, EINA_FALSE);
5147 if (it->item->block->want_unrealize)
5148 _item_block_unrealize(it->item->block);
5152 if (_is_no_select(it) ||
5153 (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get())))
5156 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD || !it->base->still_in) return;
5158 evas_object_ref(sd->obj);
5160 if (sd->focused_item != EO_OBJ(it))
5161 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
5164 ((sd->multi_select_mode != ELM_OBJECT_MULTI_SELECT_MODE_WITH_CONTROL) ||
5165 (evas_key_modifier_is_set(ev->modifiers, "Control"))))
5169 _item_highlight(it);
5170 if (_item_select(it)) goto deleted;
5179 while (sd->selected)
5181 Elm_Object_Item *eo_sel = sd->selected->data;
5182 Elm_Gen_Item *sel = eo_data_scope_get(eo_sel, ELM_GENLIST_ITEM_CLASS);
5183 _item_unselect(sel);
5188 const Eina_List *l, *l_next;
5189 Elm_Object_Item *eo_it2;
5191 EINA_LIST_FOREACH_SAFE(sd->selected, l, l_next, eo_it2)
5193 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
5195 _item_unselect(it2);
5198 _item_highlight(it);
5199 if (_item_select(it)) goto deleted;
5203 evas_object_unref(sd->obj);
5207 _item_mouse_callbacks_add(Elm_Gen_Item *it,
5210 evas_object_event_callback_add
5211 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
5212 evas_object_event_callback_add
5213 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
5214 evas_object_event_callback_add
5215 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
5216 evas_object_event_callback_add
5217 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
5218 evas_object_event_callback_add
5219 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
5220 evas_object_event_callback_add
5221 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
5222 evas_object_event_callback_add
5223 (view, EVAS_CALLBACK_MOUSE_IN, _item_mouse_in_cb, it);
5227 _item_mouse_callbacks_del(Elm_Gen_Item *it,
5230 evas_object_event_callback_del_full
5231 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
5232 evas_object_event_callback_del_full
5233 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
5234 evas_object_event_callback_del_full
5235 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
5236 evas_object_event_callback_del_full
5237 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
5238 evas_object_event_callback_del_full
5239 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
5240 evas_object_event_callback_del_full
5241 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
5242 evas_object_event_callback_del_full
5243 (view, EVAS_CALLBACK_MOUSE_IN, _item_mouse_in_cb, it);
5247 _scroll_hold_timer_cb(void *data)
5249 ELM_GENLIST_DATA_GET(data, sd);
5251 if (!data) return ECORE_CALLBACK_CANCEL;
5253 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5254 sd->scr_hold_timer = NULL;
5256 return ECORE_CALLBACK_CANCEL;
5260 _decorate_item_unrealize(Elm_Gen_Item *it)
5262 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5263 Evas_Object *obj = sd->obj;
5265 if (!it->item->deco_it_view) return;
5267 evas_event_freeze(evas_object_evas_get(obj));
5269 _view_clear(GL_IT(it)->deco_it_view, &(GL_IT(it)->deco_it_texts),
5270 &(GL_IT(it)->deco_it_contents));
5272 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
5273 evas_object_smart_member_add(VIEW(it), sd->pan_obj);
5274 ELM_SAFE_FREE(it->item->deco_it_view, evas_object_del);
5276 if (sd->mode_item == it)
5277 sd->mode_item = NULL;
5278 evas_event_thaw(evas_object_evas_get(obj));
5279 evas_event_thaw_eval(evas_object_evas_get(obj));
5283 _decorate_item_finished_signal_cb(void *data,
5285 const char *emission EINA_UNUSED,
5286 const char *source EINA_UNUSED)
5288 Elm_Gen_Item *it = data;
5292 if (!it || !obj) return;
5293 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5295 te = evas_object_evas_get(obj);
5297 if ((!it->realized) || (!it->item->deco_it_view)) return;
5299 evas_event_freeze(te);
5300 it->item->nocache_once = EINA_FALSE;
5301 _decorate_item_unrealize(it);
5302 if (it->item->group_item)
5303 evas_object_stack_above(it->item->VIEW(group_item), sd->stack[1]);
5305 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished",
5306 sd->decorate_it_type);
5307 edje_object_signal_callback_del_full
5308 (obj, buf, "elm", _decorate_item_finished_signal_cb, it);
5309 evas_event_thaw(te);
5310 evas_event_thaw_eval(te);
5314 _item_unrealize(Elm_Gen_Item *it)
5317 Eina_List *cache = NULL;
5318 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5320 EINA_LIST_FREE(it->item->flip_contents, c)
5324 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
5325 _elm_access_widget_item_unregister(it->base);
5327 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
5328 if (_elm_config->atspi_mode)
5330 elm_interface_atspi_accessible_removed(EO_OBJ(it));
5331 elm_interface_atspi_accessible_children_changed_del_signal_emit(sd->obj, EO_OBJ(it));
5335 // unswallow VIEW(it) first then manipulate VIEW(it)
5336 _decorate_item_unrealize(it);
5337 if (GL_IT(it)->wsd->decorate_all_mode) _decorate_all_item_unrealize(it);
5339 if (!_item_cache_add(it, _content_cache_add(it, &cache)))
5341 ELM_SAFE_FREE(VIEW(it), evas_object_del);
5342 ELM_SAFE_FREE(it->spacer, evas_object_del);
5343 EINA_LIST_FREE(cache, c)
5350 it->realized = EINA_FALSE;
5351 it->want_unrealize = EINA_FALSE;
5355 _item_block_recalc(Item_Block *itb,
5361 Evas_Coord minw = 0, minh = 0;
5362 Eina_Bool show_me = EINA_FALSE, changed = EINA_FALSE;
5364 Item_Size *size = NULL;
5367 EINA_LIST_FOREACH(itb->items, l, it)
5369 show_me |= it->item->show_me;
5371 if (!it->filtered) _item_filtered_get(it);
5372 if (it->want_hidden)
5374 if (it->realized) evas_object_hide(VIEW(it));
5379 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5380 if ((itb->sd->homogeneous || it->itc->homogeneous) &&
5381 ((!size) || it->itc != size->itc))
5382 size = eina_hash_find(itb->sd->size_caches, &(it->itc));
5383 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5384 if (qadd || ((itb->sd->homogeneous || it->itc->homogeneous) && !size))
5386 if (!it->item->mincalcd) changed = EINA_TRUE;
5391 _item_realize(it, in, EINA_TRUE);
5392 _elm_genlist_item_unrealize(it, EINA_TRUE);
5396 it->item->w = it->item->minw = size->minw;
5397 it->item->h = it->item->minh = size->minh;
5398 it->item->mincalcd = EINA_TRUE;
5404 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5405 if ((itb->sd->homogeneous || it->itc->homogeneous) && size &&
5406 (itb->sd->mode == ELM_LIST_COMPRESS))
5408 it->item->w = it->item->minw = size->minw;
5409 it->item->h = it->item->minh = size->minh;
5410 it->item->mincalcd = EINA_TRUE;
5414 _item_realize(it, in, EINA_TRUE);
5415 _elm_genlist_item_unrealize(it, EINA_TRUE);
5421 if (!it->item->mincalcd) changed = EINA_TRUE;
5422 _item_realize(it, in, EINA_FALSE);
5424 minh += it->item->minh;
5425 if (minw < it->item->minw) minw = it->item->minw;
5431 if (changed) itb->sd->pan_changed = changed;
5434 itb->changed = EINA_FALSE;
5435 itb->position_update = EINA_FALSE;
5441 _update_job(void *data)
5443 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
5444 ELM_GENLIST_DATA_GET(data, sd);
5449 sd->update_job = NULL;
5452 evas_event_freeze(evas_object_evas_get(sd->obj));
5453 EINA_INLIST_FOREACH(sd->blocks, itb)
5455 Evas_Coord itminw, itminh;
5462 _item_block_position(itb, num);
5466 recalc = EINA_FALSE;
5467 EINA_LIST_FOREACH(itb->items, l2, it)
5469 if (it->item->updateme)
5471 itminw = it->item->minw;
5472 itminh = it->item->minh;
5474 it->item->updateme = EINA_FALSE;
5477 _elm_genlist_item_unrealize(it, EINA_FALSE);
5478 _item_realize(it, num, EINA_FALSE);
5479 position = EINA_TRUE;
5483 _item_realize(it, num, EINA_TRUE);
5484 _elm_genlist_item_unrealize(it, EINA_TRUE);
5486 if ((it->item->minw != itminw) || (it->item->minh != itminh))
5491 itb->updateme = EINA_FALSE;
5494 position = EINA_TRUE;
5495 itb->changed = EINA_TRUE;
5496 _item_block_recalc(itb, num0, EINA_FALSE);
5497 _item_block_position(itb, num0);
5502 ecore_job_del(sd->calc_job);
5503 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
5505 evas_event_thaw(evas_object_evas_get(sd->obj));
5506 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
5510 _scroll_animate_start_cb(Evas_Object *obj,
5511 void *data EINA_UNUSED)
5513 eo_do(obj, eo_event_callback_call(EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL_ANIM_START, NULL));
5517 _scroll_animate_stop_cb(Evas_Object *obj,
5518 void *data EINA_UNUSED)
5520 eo_do(obj, eo_event_callback_call(EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL_ANIM_STOP, NULL));
5524 _scroll_drag_start_cb(Evas_Object *obj,
5525 void *data EINA_UNUSED)
5527 eo_do(obj, eo_event_callback_call(EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL_DRAG_START, NULL));
5531 _scroll_cb(Evas_Object *obj,
5532 void *data EINA_UNUSED)
5534 eo_do(obj, eo_event_callback_call(EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL, NULL));
5538 _scroll_drag_stop_cb(Evas_Object *obj,
5539 void *data EINA_UNUSED)
5541 eo_do(obj, eo_event_callback_call(EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL_DRAG_STOP, NULL));
5545 _edge_left_cb(Evas_Object *obj,
5546 void *data EINA_UNUSED)
5548 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_EDGE_LEFT, NULL));
5552 _edge_right_cb(Evas_Object *obj,
5553 void *data EINA_UNUSED)
5555 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_EDGE_RIGHT, NULL));
5559 _edge_top_cb(Evas_Object *obj,
5560 void *data EINA_UNUSED)
5562 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_EDGE_TOP, NULL));
5566 _edge_bottom_cb(Evas_Object *obj,
5567 void *data EINA_UNUSED)
5569 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_EDGE_BOTTOM, NULL));
5573 _vbar_drag_cb(Evas_Object *obj,
5574 void *data EINA_UNUSED)
5576 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_VBAR_DRAG, NULL));
5580 _vbar_press_cb(Evas_Object *obj,
5581 void *data EINA_UNUSED)
5583 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_VBAR_PRESS, NULL));
5587 _vbar_unpress_cb(Evas_Object *obj,
5588 void *data EINA_UNUSED)
5590 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_VBAR_UNPRESS, NULL));
5594 _hbar_drag_cb(Evas_Object *obj,
5595 void *data EINA_UNUSED)
5597 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_HBAR_DRAG, NULL));
5601 _hbar_press_cb(Evas_Object *obj,
5602 void *data EINA_UNUSED)
5604 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_HBAR_PRESS, NULL));
5608 _hbar_unpress_cb(Evas_Object *obj,
5609 void *data EINA_UNUSED)
5611 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_HBAR_UNPRESS, NULL));
5615 _decorate_item_realize(Elm_Gen_Item *it)
5617 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5618 Evas_Object *obj = sd->obj;
5621 if (GL_IT(it)->deco_it_view) return;
5623 evas_event_freeze(evas_object_evas_get(obj));
5624 it->item->deco_it_view = _view_create(it, it->itc->decorate_item_style);
5626 /* signal callback add */
5627 evas_object_event_callback_add
5628 (GL_IT(it)->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb,
5630 evas_object_event_callback_add
5631 (GL_IT(it)->deco_it_view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
5632 evas_object_event_callback_add
5633 (GL_IT(it)->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb,
5636 _view_inflate(it->item->deco_it_view, it, &GL_IT(it)->deco_it_texts,
5637 &GL_IT(it)->deco_it_contents);
5638 edje_object_part_swallow
5639 (it->item->deco_it_view,
5640 edje_object_data_get(it->item->deco_it_view, "mode_part"), VIEW(it));
5642 snprintf(buf, sizeof(buf), "elm,state,%s,active", sd->decorate_it_type);
5643 edje_object_signal_emit(GL_IT(it)->deco_it_view, buf, "elm");
5644 edje_object_signal_emit(VIEW(it), buf, "elm");
5646 it->want_unrealize = EINA_FALSE;
5647 evas_event_thaw(evas_object_evas_get(obj));
5648 evas_event_thaw_eval(evas_object_evas_get(obj));
5652 _decorate_item_set(Elm_Gen_Item *it)
5656 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5659 it->item->nocache_once = EINA_TRUE;
5661 ELM_SAFE_FREE(sd->scr_hold_timer, ecore_timer_del);
5662 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
5663 sd->scr_hold_timer = ecore_timer_add(SCR_HOLD_TIME, _scroll_hold_timer_cb, sd->obj);
5665 evas_event_freeze(evas_object_evas_get(sd->obj));
5666 _decorate_item_realize(it);
5667 if (it->item->group_item)
5668 evas_object_stack_above(it->item->VIEW(group_item), sd->stack[1]);
5670 (it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
5671 evas_event_thaw(evas_object_evas_get(sd->obj));
5672 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
5677 _decorate_item_unset(Elm_Genlist_Data *sd)
5679 char buf[1024], buf2[1024];
5682 if (!sd->mode_item) return;
5685 it->item->nocache_once = EINA_TRUE;
5687 snprintf(buf, sizeof(buf), "elm,state,%s,passive", sd->decorate_it_type);
5688 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished",
5689 sd->decorate_it_type);
5690 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
5691 edje_object_signal_callback_add
5692 (it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb,
5694 sd->mode_item = NULL;
5698 _elm_genlist_looping_up_cb(void *data,
5699 Evas_Object *obj EINA_UNUSED,
5700 const char *emission EINA_UNUSED,
5701 const char *source EINA_UNUSED)
5703 Evas_Object *genlist = data;
5705 ELM_GENLIST_DATA_GET(genlist, sd);
5707 Elm_Object_Item *eo_it = elm_genlist_last_item_get(genlist);
5709 // TIZEN_ONLY(20150629): add checking item bring in enable on item looping
5710 switch (_elm_config->focus_autoscroll_mode)
5712 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
5713 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
5715 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
5716 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
5722 elm_layout_signal_emit(genlist, "elm,action,looping,up,end", "elm");
5723 sd->item_looping_on = EINA_FALSE;
5725 if (!_elm_config->item_select_on_focus_disable)
5726 elm_genlist_item_selected_set(eo_it, EINA_TRUE);
5728 elm_object_item_focus_set(eo_it, EINA_TRUE);
5732 _elm_genlist_looping_down_cb(void *data,
5733 Evas_Object *obj EINA_UNUSED,
5734 const char *emission EINA_UNUSED,
5735 const char *source EINA_UNUSED)
5737 Evas_Object *genlist = data;
5739 ELM_GENLIST_DATA_GET(genlist, sd);
5741 Elm_Object_Item *eo_it = elm_genlist_first_item_get(genlist);
5743 // TIZEN_ONLY(20150629): add checking item bring in enable on item looping
5744 switch (_elm_config->focus_autoscroll_mode)
5746 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
5747 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
5749 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
5750 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
5756 elm_layout_signal_emit(genlist, "elm,action,looping,down,end", "elm");
5757 sd->item_looping_on = EINA_FALSE;
5759 if (!_elm_config->item_select_on_focus_disable)
5760 elm_genlist_item_selected_set(eo_it, EINA_TRUE);
5762 elm_object_item_focus_set(eo_it, EINA_TRUE);
5766 _evas_viewport_resize_cb(void *d, Evas *e EINA_UNUSED, void *ei EINA_UNUSED)
5768 Elm_Genlist_Data *priv = d;
5769 evas_object_smart_changed(priv->pan_obj);
5773 _elm_genlist_evas_object_smart_add(Eo *obj, Elm_Genlist_Data *priv)
5775 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5776 Elm_Genlist_Pan_Data *pan_data;
5777 Evas_Coord minw, minh;
5780 eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
5781 elm_widget_sub_object_parent_add(obj);
5783 priv->size_caches = eina_hash_pointer_new(_size_cache_free);
5784 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
5785 evas_object_smart_member_add(priv->hit_rect, obj);
5786 elm_widget_sub_object_add(obj, priv->hit_rect);
5788 /* common scroller hit rectangle setup */
5789 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
5790 evas_object_show(priv->hit_rect);
5791 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
5793 elm_widget_can_focus_set(obj, EINA_TRUE);
5794 elm_widget_on_show_region_hook_set(obj, _show_region_hook, NULL);
5796 if (!elm_layout_theme_set
5797 (obj, "genlist", "base", elm_widget_style_get(obj)))
5798 CRI("Failed to set layout!");
5800 eo_do(obj, elm_interface_scrollable_objects_set(wd->resize_obj, priv->hit_rect));
5802 eo_do(obj, elm_interface_scrollable_bounce_allow_set
5803 (EINA_FALSE, _elm_config->thumbscroll_bounce_enable));
5804 priv->v_bounce = _elm_config->thumbscroll_bounce_enable;
5807 elm_interface_scrollable_animate_start_cb_set(_scroll_animate_start_cb),
5808 elm_interface_scrollable_animate_stop_cb_set(_scroll_animate_stop_cb),
5809 elm_interface_scrollable_scroll_cb_set(_scroll_cb),
5810 elm_interface_scrollable_drag_start_cb_set(_scroll_drag_start_cb),
5811 elm_interface_scrollable_drag_stop_cb_set(_scroll_drag_stop_cb),
5812 elm_interface_scrollable_edge_left_cb_set(_edge_left_cb),
5813 elm_interface_scrollable_edge_right_cb_set(_edge_right_cb),
5814 elm_interface_scrollable_edge_top_cb_set(_edge_top_cb),
5815 elm_interface_scrollable_edge_bottom_cb_set(_edge_bottom_cb),
5816 elm_interface_scrollable_vbar_drag_cb_set(_vbar_drag_cb),
5817 elm_interface_scrollable_vbar_press_cb_set(_vbar_press_cb),
5818 elm_interface_scrollable_vbar_unpress_cb_set(_vbar_unpress_cb),
5819 elm_interface_scrollable_hbar_drag_cb_set(_hbar_drag_cb),
5820 elm_interface_scrollable_hbar_press_cb_set(_hbar_press_cb),
5821 elm_interface_scrollable_hbar_unpress_cb_set(_hbar_unpress_cb),
5822 elm_interface_scrollable_content_min_limit_cb_set(_content_min_limit_cb));
5824 priv->mode = ELM_LIST_SCROLL;
5825 priv->max_items_per_block = MAX_ITEMS_PER_BLOCK;
5826 priv->item_cache_max = priv->max_items_per_block * 2;
5827 priv->longpress_timeout = _elm_config->longpress_timeout;
5828 priv->highlight = EINA_TRUE;
5830 priv->pan_obj = eo_add(MY_PAN_CLASS, evas_object_evas_get(obj));
5831 pan_data = eo_data_scope_get(priv->pan_obj, MY_PAN_CLASS);
5832 eo_data_ref(obj, NULL);
5833 pan_data->wobj = obj;
5834 pan_data->wsd = priv;
5836 for (i = 0; i < 2; i++)
5838 priv->stack[i] = evas_object_rectangle_add(evas_object_evas_get(obj));
5839 evas_object_smart_member_add(priv->stack[i], priv->pan_obj);
5842 eo_do(obj, elm_interface_scrollable_extern_pan_set(priv->pan_obj));
5844 edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
5845 evas_object_size_hint_min_set(obj, minw, minh);
5847 _mirrored_set(obj, elm_widget_mirrored_get(obj));
5849 elm_layout_sizing_eval(obj);
5851 edje_object_signal_callback_add(wd->resize_obj, "elm,looping,up,done", "elm", _elm_genlist_looping_up_cb, obj);
5852 edje_object_signal_callback_add(wd->resize_obj, "elm,looping,down,done", "elm", _elm_genlist_looping_down_cb, obj);
5853 evas_event_callback_add(evas_object_evas_get(obj),
5854 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
5855 _evas_viewport_resize_cb, priv);
5859 _elm_genlist_evas_object_smart_del(Eo *obj, Elm_Genlist_Data *sd)
5863 elm_genlist_clear(obj);
5864 for (i = 0; i < 2; i++)
5865 ELM_SAFE_FREE(sd->stack[i], evas_object_del);
5867 evas_event_callback_del_full(evas_object_evas_get(obj),
5868 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
5869 _evas_viewport_resize_cb, sd);
5870 ELM_SAFE_FREE(sd->pan_obj, evas_object_del);
5872 _item_cache_zero(sd);
5873 ecore_job_del(sd->calc_job);
5874 ecore_job_del(sd->update_job);
5875 ecore_idle_enterer_del(sd->queue_idle_enterer);
5876 ecore_idler_del(sd->must_recalc_idler);
5877 ecore_timer_del(sd->multi_timer);
5878 eina_stringshare_del(sd->decorate_it_type);
5879 ecore_animator_del(sd->tree_effect_animator);
5881 eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
5885 _elm_genlist_evas_object_smart_move(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y)
5887 eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
5889 evas_object_move(sd->hit_rect, x, y);
5893 _elm_genlist_evas_object_smart_resize(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord w, Evas_Coord h)
5895 eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
5897 evas_object_resize(sd->hit_rect, w, h);
5898 if ((sd->queue) && (!sd->queue_idle_enterer) && (w > 0))
5899 _requeue_idle_enterer(sd);
5903 _elm_genlist_evas_object_smart_member_add(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *member)
5905 eo_do_super(obj, MY_CLASS, evas_obj_smart_member_add(member));
5908 evas_object_raise(sd->hit_rect);
5912 _access_obj_process(Elm_Genlist_Data *sd, Eina_Bool is_access)
5915 Eina_Bool done = EINA_FALSE;
5917 EINA_INLIST_FOREACH(sd->blocks, itb)
5925 EINA_LIST_FOREACH(itb->items, l, it)
5927 if (!it->realized || it->want_hidden) continue;
5928 if (is_access) _access_widget_item_register(it);
5930 _elm_access_widget_item_unregister(it->base);
5933 else if (done) break;
5938 _elm_genlist_elm_widget_access(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool acs)
5940 _elm_genlist_smart_focus_next_enable = acs;
5941 _access_obj_process(sd, _elm_genlist_smart_focus_next_enable);
5944 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
5945 //register/unregister access objects accordingly.
5946 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
5948 _elm_genlist_elm_widget_screen_reader(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool is_screen_reader)
5951 Eina_Bool done = EINA_FALSE;
5952 Evas_Object *content = NULL;
5956 EINA_INLIST_FOREACH(sd->blocks, itb)
5961 EINA_LIST_FOREACH(itb->items, l, it)
5963 if (!it->realized || it->want_hidden) continue;
5964 if (is_screen_reader)
5966 elm_interface_atspi_accessible_added(EO_OBJ(it));
5967 elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
5968 EINA_LIST_FOREACH(it->contents, ll, content)
5970 if (eo_isa(content, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
5972 eo_do(content, elm_interface_atspi_accessible_parent_set(EO_OBJ(it)));
5973 elm_interface_atspi_accessible_children_changed_added_signal_emit(EO_OBJ(it), content);
5976 elm_interface_atspi_accessible_name_changed_signal_emit(EO_OBJ(it));
5980 elm_interface_atspi_accessible_removed(EO_OBJ(it));
5981 elm_interface_atspi_accessible_children_changed_del_signal_emit(sd->obj, EO_OBJ(it));
5985 else if (done) break;
5987 //TIZEN_ONLY(20161213): apply screen_reader_changed callback
5988 evas_object_smart_callback_call(obj, SIG_ATSPI_SCREEN_READER_CHANGED, &is_screen_reader);
5995 elm_genlist_add(Evas_Object *parent)
5997 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
5998 Evas_Object *obj = eo_add(MY_CLASS, parent);
6003 _elm_genlist_eo_base_constructor(Eo *obj, Elm_Genlist_Data *sd)
6005 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
6009 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
6010 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
6011 elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST));
6017 _internal_elm_genlist_clear(Evas_Object *obj)
6019 ELM_GENLIST_DATA_GET(obj, sd);
6022 _elm_genlist_item_unfocused(sd->focused_item);
6023 if (sd->mode_item) sd->mode_item = NULL;
6025 ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
6027 sd->filter_data = NULL;
6028 if (sd->filter_queue)
6029 ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
6030 ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
6031 ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
6033 evas_event_freeze(evas_object_evas_get(sd->obj));
6035 // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
6036 // because sd->items can be modified inside elm_widget_item_del()
6039 it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
6040 eo_do(EO_OBJ(it), elm_wdg_item_del());
6043 sd->pan_changed = EINA_TRUE;
6046 ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
6047 sd->anchor_item = NULL;
6048 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
6049 ELM_SAFE_FREE(sd->must_recalc_idler, ecore_idler_del);
6050 ELM_SAFE_FREE(sd->reorder_move_animator, ecore_animator_del);
6051 sd->reorder_old_pan_y = 0;
6054 if (sd->selected) ELM_SAFE_FREE(sd->selected, eina_list_free);
6056 sd->show_item = NULL;
6065 evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
6066 eo_do(sd->pan_obj, eo_event_callback_call
6067 (ELM_PAN_EVENT_CHANGED, NULL));
6069 elm_layout_sizing_eval(sd->obj);
6070 eo_do(obj, elm_interface_scrollable_content_region_show(0, 0, 0, 0));
6072 ELM_SAFE_FREE(sd->multi_timer, ecore_timer_del);
6073 ELM_SAFE_FREE(sd->update_job, ecore_job_del);
6074 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
6075 ELM_SAFE_FREE(sd->must_recalc_idler, ecore_idler_del);
6076 ELM_SAFE_FREE(sd->tree_effect_animator, ecore_animator_del);
6077 ELM_SAFE_FREE(sd->event_block_rect, evas_object_del);
6078 ELM_SAFE_FREE(sd->scr_hold_timer, ecore_timer_del);
6079 ELM_SAFE_FREE(sd->queue, eina_list_free);
6081 evas_event_thaw(evas_object_evas_get(sd->obj));
6082 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
6085 /* Return EINA_TRUE if the item is deleted in this function */
6087 _item_select(Elm_Gen_Item *it)
6090 Evas_Object *obj = WIDGET(it);
6091 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
6092 Elm_Object_Item *eo_it = EO_OBJ(it);
6094 if (eo_do_ret(eo_it, tmp, elm_wdg_item_disabled_get())) return EINA_FALSE;
6095 if (_is_no_select(it) || (it->decorate_it_set)) return EINA_FALSE;
6096 if ((sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) &&
6097 (it->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) && it->selected)
6102 const Eina_List *l, *ll;
6103 Elm_Object_Item *eo_it2;
6104 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it2)
6106 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6107 if (it2 != it) _item_unselect(it2);
6113 it->selected = EINA_TRUE;
6115 eina_list_append(sd->selected, eo_it);
6118 evas_object_ref(obj);
6121 elm_object_item_focus_set(eo_it, EINA_TRUE);
6122 if ((it->base)->on_deletion) goto item_deleted;
6123 _elm_genlist_item_content_focus_set(it, ELM_FOCUS_PREVIOUS);
6124 sd->last_selected_item = eo_it;
6125 _item_highlight(it);
6127 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), eo_it);
6128 // delete item if it's requested deletion in the above callbacks.
6129 if ((it->base)->on_deletion) goto item_deleted;
6130 eo_do(WIDGET(it), eo_event_callback_call(EVAS_SELECTABLE_INTERFACE_EVENT_SELECTED, eo_it));
6131 if (_elm_config->atspi_mode)
6132 elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_SELECTED, EINA_TRUE);
6133 // delete item if it's requested deletion in the above callbacks.
6134 if ((it->base)->on_deletion) goto item_deleted;
6137 if (!(sd->focus_on_selection_enabled || _elm_config->item_select_on_focus_disable))
6139 Evas_Object *swallow_obj;
6141 EINA_LIST_FOREACH(it->contents, l, swallow_obj)
6143 if (elm_widget_is(swallow_obj) && elm_object_focus_get(swallow_obj))
6145 elm_object_focus_set(obj, EINA_FALSE);
6146 elm_object_focus_set(obj, EINA_TRUE);
6152 evas_object_unref(obj);
6156 it->walking = -1; //This item was removed from it's item list.
6159 evas_object_unref(obj);
6163 EOLIAN static Evas_Object *
6164 _elm_genlist_item_elm_widget_item_part_content_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6166 Evas_Object *ret = NULL;
6167 if (it->deco_all_view)
6168 ret = edje_object_part_swallow_get(it->deco_all_view, part);
6169 else if (it->decorate_it_set)
6170 ret = edje_object_part_swallow_get(it->item->deco_it_view, part);
6174 ret = edje_object_part_swallow_get(VIEW(it), part);
6176 ret = edje_object_part_swallow_get(VIEW(it), "elm.swallow.icon");
6181 EOLIAN static const char *
6182 _elm_genlist_item_elm_widget_item_part_text_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6184 if (!it->itc->func.text_get) return NULL;
6185 const char *ret = NULL;
6186 if (it->deco_all_view)
6187 ret = edje_object_part_text_get(it->deco_all_view, part);
6188 else if (it->decorate_it_set)
6189 ret = edje_object_part_text_get(it->item->deco_it_view, part);
6193 ret = edje_object_part_text_get(VIEW(it), part);
6195 ret = edje_object_part_text_get(VIEW(it), "elm.text");
6201 _elm_genlist_item_elm_widget_item_disable(Eo *eo_it, Elm_Gen_Item *it)
6208 if (eo_it == GL_IT(it)->wsd->focused_item)
6209 _elm_genlist_item_unfocused(eo_it);
6210 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
6214 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()))
6216 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
6217 if (it->deco_all_view)
6218 edje_object_signal_emit
6219 (it->deco_all_view, SIGNAL_DISABLED, "elm");
6223 edje_object_signal_emit(VIEW(it), SIGNAL_ENABLED, "elm");
6224 if (it->deco_all_view)
6225 edje_object_signal_emit
6226 (it->deco_all_view, SIGNAL_ENABLED, "elm");
6228 EINA_LIST_FOREACH(it->contents, l, obj)
6229 elm_widget_disabled_set(obj, eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()));
6233 EOLIAN static Eina_Bool
6234 _elm_genlist_item_elm_widget_item_del_pre(Eo *eo_it EINA_UNUSED,
6237 /* This item is getting removed from a callback that triggered in the
6238 _item_select(). Just pend removing. Because this will be removed right
6239 after in the _item_select(). So pratically, this item won't be
6241 if (it->walking > 0)
6243 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
6244 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
6253 _elm_genlist_item_elm_widget_item_signal_emit(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char *emission, const char *source)
6257 WRN("Item is not realized yet");
6260 edje_object_signal_emit(VIEW(it), emission, source);
6261 if (it->deco_all_view)
6262 edje_object_signal_emit(it->deco_all_view, emission, source);
6266 _elm_genlist_item_elm_widget_item_focus_set(Eo *eo_it, Elm_Gen_Item *it, Eina_Bool focused)
6268 Evas_Object *obj = WIDGET(it);
6270 ELM_GENLIST_DATA_GET(obj, sd);
6274 sd->last_focused_item = eo_it;
6275 if (!elm_object_focus_get(obj))
6276 elm_object_focus_set(obj, EINA_TRUE);
6278 if (!elm_widget_focus_get(obj))
6281 fobj = elm_object_focused_object_get(obj);
6282 if (fobj && (fobj != obj))
6284 Evas_Object *content;
6286 EINA_LIST_FOREACH(it->contents, l, content)
6288 if (elm_object_focused_object_get(content))
6290 elm_object_focus_set(content, EINA_FALSE);
6296 if (eo_it != sd->focused_item)
6298 if (sd->focused_item)
6299 _elm_genlist_item_unfocused(sd->focused_item);
6300 _elm_genlist_item_focused(eo_it);
6302 /* If item is not realized state, widget couldn't get focus_highlight data. */
6305 _elm_widget_item_highlight_in_theme(obj, EO_OBJ(it));
6306 _elm_widget_highlight_in_theme_update(obj);
6307 _elm_widget_focus_highlight_start(obj);
6313 if (!elm_widget_focus_get(obj))
6315 _elm_genlist_item_unfocused(eo_it);
6319 EOLIAN static Eina_Bool
6320 _elm_genlist_item_elm_widget_item_focus_get(Eo *eo_it, Elm_Gen_Item *it)
6322 Evas_Object *obj = WIDGET(it);
6323 ELM_GENLIST_DATA_GET(obj, sd);
6325 if (eo_it == sd->focused_item)
6332 _elm_genlist_item_eo_base_constructor(Eo *eo_it, Elm_Gen_Item *it)
6334 eo_it = eo_do_super_ret(eo_it, ELM_GENLIST_ITEM_CLASS, eo_it, eo_constructor());
6336 it->base = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
6337 eo_do(eo_it, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST_ITEM));
6342 static Elm_Gen_Item *
6343 _elm_genlist_item_new(Elm_Genlist_Data *sd,
6344 const Elm_Genlist_Item_Class *itc,
6346 Elm_Object_Item *eo_parent,
6347 Elm_Genlist_Item_Type type,
6349 const void *func_data)
6354 if (!itc) return NULL;
6356 Eo *eo_it = eo_add(ELM_GENLIST_ITEM_CLASS, sd->obj);
6357 if (!eo_it) return NULL;
6358 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6361 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
6363 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6364 WIDGET_ITEM_DATA_SET(EO_OBJ(it), data);
6365 it->parent = parent;
6366 it->func.func = func;
6367 it->func.data = func_data;
6369 GL_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
6370 GL_IT(it)->wsd = sd;
6371 GL_IT(it)->type = type;
6375 if (GL_IT(it->parent)->type & ELM_GENLIST_ITEM_GROUP)
6376 GL_IT(it)->group_item = parent;
6377 else if (GL_IT(it->parent)->group_item)
6378 GL_IT(it)->group_item = GL_IT(it->parent)->group_item;
6380 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
6382 if (!(GL_IT(it2->parent)->type & ELM_GENLIST_ITEM_GROUP)) depth += 1;
6384 GL_IT(it)->expanded_depth = depth;
6391 _elm_genlist_item_compare(const void *data,
6394 const Elm_Gen_Item *it, *item1;
6396 it = ELM_GEN_ITEM_FROM_INLIST(data);
6397 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
6398 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6402 _elm_genlist_item_list_compare(const void *data,
6405 const Elm_Gen_Item *it = data;
6406 const Elm_Gen_Item *item1 = data1;
6408 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6412 _elm_genlist_eo_item_list_compare(const void *data,
6415 const Elm_Object_Item *eo_it = data;
6416 const Elm_Object_Item *eo_item1 = data1;
6417 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6419 return GL_IT(it)->wsd->item_compare_cb(eo_it, eo_item1);
6422 EOLIAN static unsigned int
6423 _elm_genlist_items_count(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6425 return sd->item_count;
6429 _list_last_recursive(Eina_List *list)
6431 Eina_List *ll, *ll2;
6432 Elm_Object_Item *eo_it2;
6434 ll = eina_list_last(list);
6435 if (!ll) return NULL;
6438 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6440 if (it2->item->items)
6442 ll2 = _list_last_recursive(it2->item->items);
6452 EOLIAN static Elm_Object_Item*
6453 _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)
6459 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6460 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6461 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6464 it = _elm_genlist_item_new
6465 (sd, itc, data, eo_parent, type, func, func_data);
6466 if (!it) return NULL;
6470 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
6471 sd->group_items = eina_list_append(sd->group_items, it);
6472 sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
6473 it->item->rel = NULL;
6477 Elm_Object_Item *eo_it2 = NULL;
6478 Eina_List *ll = _list_last_recursive(it->parent->item->items);
6480 if (ll) eo_it2 = ll->data;
6481 it->parent->item->items =
6482 eina_list_append(it->parent->item->items, EO_OBJ(it));
6483 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6484 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6485 sd->items = eina_inlist_append_relative
6486 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6487 it->item->rel = it2;
6488 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6490 it->item->before = EINA_FALSE;
6491 _item_queue(sd, it, NULL);
6496 EOLIAN static Elm_Object_Item*
6497 _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)
6503 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6504 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6505 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6506 /* first sub-item should allways be appended */
6507 if (!parent->item->items)
6508 return _elm_genlist_item_append(obj, sd, itc, data, eo_parent, type, func, func_data);
6511 it = _elm_genlist_item_new
6512 (sd, itc, data, eo_parent, type, func, func_data);
6513 if (!it) return NULL;
6517 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
6518 sd->group_items = eina_list_prepend(sd->group_items, it);
6519 sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
6520 it->item->rel = NULL;
6524 Elm_Object_Item *eo_it2 = NULL;
6525 Eina_List *ll = it->parent->item->items;
6527 if (ll) eo_it2 = ll->data;
6528 it->parent->item->items =
6529 eina_list_prepend(it->parent->item->items, EO_OBJ(it));
6530 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6531 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6532 sd->items = eina_inlist_prepend_relative
6533 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6534 it->item->rel = it2;
6535 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6537 it->item->before = EINA_TRUE;
6538 _item_queue(sd, it, NULL);
6543 EOLIAN static Elm_Object_Item*
6544 _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)
6546 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_after, NULL);
6547 ELM_GENLIST_ITEM_DATA_GET(eo_after, after);
6550 ELM_GENLIST_ITEM_CHECK_OR_RETURN(after, NULL);
6551 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(after)), NULL);
6554 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6555 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6556 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6559 /* It makes no sense to insert after in an empty list with after !=
6560 * NULL, something really bad is happening in your app. */
6561 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6563 it = _elm_genlist_item_new
6564 (sd, itc, data, eo_parent, type, func, func_data);
6565 if (!it) return NULL;
6569 if ((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) &&
6570 (GL_IT(after)->type & ELM_GENLIST_ITEM_GROUP))
6571 sd->group_items = eina_list_append_relative
6572 (sd->group_items, it, after);
6576 it->parent->item->items =
6577 eina_list_append_relative(it->parent->item->items, EO_OBJ(it), eo_after);
6579 sd->items = eina_inlist_append_relative
6580 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
6582 it->item->rel = after;
6583 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
6584 it->item->before = EINA_FALSE;
6585 _item_queue(sd, it, NULL);
6590 EOLIAN static Elm_Object_Item*
6591 _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)
6593 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_before, NULL);
6594 ELM_GENLIST_ITEM_DATA_GET(eo_before, before);
6597 ELM_GENLIST_ITEM_CHECK_OR_RETURN(before, NULL);
6598 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(before)), NULL);
6601 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6602 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6603 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6606 /* It makes no sense to insert before in an empty list with before
6607 * != NULL, something really bad is happening in your app. */
6608 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6610 it = _elm_genlist_item_new
6611 (sd, itc, data, eo_parent, type, func, func_data);
6612 if (!it) return NULL;
6616 if ((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) &&
6617 (GL_IT(before)->type & ELM_GENLIST_ITEM_GROUP))
6619 eina_list_prepend_relative(sd->group_items, it, before);
6623 it->parent->item->items =
6624 eina_list_prepend_relative(it->parent->item->items, EO_OBJ(it), eo_before);
6626 sd->items = eina_inlist_prepend_relative
6627 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
6629 it->item->rel = before;
6630 GL_IT(before)->rel_revs = eina_list_append(GL_IT(before)->rel_revs, it);
6631 it->item->before = EINA_TRUE;
6632 _item_queue(sd, it, NULL);
6637 EOLIAN static Elm_Object_Item*
6638 _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)
6640 Elm_Gen_Item *rel = NULL;
6645 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6646 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6647 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6650 it = _elm_genlist_item_new
6651 (sd, itc, data, eo_parent, type, func, func_data);
6652 if (!it) return NULL;
6653 Elm_Object_Item *eo_it = EO_OBJ(it);
6655 sd->item_compare_cb = comp;
6659 Elm_Object_Item *eo_rel = NULL;
6663 l = eina_list_search_sorted_near_list
6664 (it->parent->item->items, _elm_genlist_eo_item_list_compare, eo_it,
6669 eo_rel = eina_list_data_get(l);
6670 rel = eo_data_scope_get(eo_rel, ELM_GENLIST_ITEM_CLASS);
6672 if (cmp_result >= 0)
6674 it->parent->item->items = eina_list_prepend_relative_list
6675 (it->parent->item->items, eo_it, l);
6676 sd->items = eina_inlist_prepend_relative
6677 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6678 it->item->before = EINA_TRUE;
6680 else if (cmp_result < 0)
6682 it->parent->item->items = eina_list_append_relative_list
6683 (it->parent->item->items, eo_it, l);
6684 sd->items = eina_inlist_append_relative
6685 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6686 it->item->before = EINA_FALSE;
6693 // ignoring the comparison
6694 it->parent->item->items = eina_list_prepend_relative_list
6695 (it->parent->item->items, eo_it, l);
6696 sd->items = eina_inlist_prepend_relative
6697 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6698 it->item->before = EINA_FALSE;
6705 sd->state = eina_inlist_sorted_state_new();
6706 eina_inlist_sorted_state_init(sd->state, sd->items);
6707 sd->requeued = EINA_FALSE;
6710 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6711 sd->group_items = eina_list_append(sd->group_items, it);
6713 sd->items = eina_inlist_sorted_state_insert
6714 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
6717 if (EINA_INLIST_GET(it)->next)
6719 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6720 it->item->before = EINA_TRUE;
6722 else if (EINA_INLIST_GET(it)->prev)
6724 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6725 it->item->before = EINA_FALSE;
6731 GL_IT(it)->rel = rel;
6732 rel->item->rel_revs = eina_list_append(rel->item->rel_revs, it);
6735 _item_queue(sd, it, _elm_genlist_item_list_compare);
6741 _elm_genlist_clear(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED)
6743 _internal_elm_genlist_clear(obj);
6747 _elm_genlist_multi_select_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool multi)
6749 sd->multi = !!multi;
6751 if (!sd->multi && sd->selected)
6754 Elm_Object_Item *eo_it;
6755 Elm_Object_Item *last = sd->selected->data;
6756 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
6760 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6767 EOLIAN static Eina_Bool
6768 _elm_genlist_multi_select_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6774 _elm_genlist_multi_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Elm_Object_Multi_Select_Mode mode)
6776 if (mode >= ELM_OBJECT_MULTI_SELECT_MODE_MAX)
6779 if (sd->multi_select_mode != mode)
6780 sd->multi_select_mode = mode;
6783 EOLIAN static Elm_Object_Multi_Select_Mode
6784 _elm_genlist_multi_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6786 return sd->multi_select_mode;
6789 EOLIAN static Elm_Object_Item*
6790 _elm_genlist_selected_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6793 return sd->selected->data;
6798 EOLIAN static const Eina_List*
6799 _elm_genlist_selected_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6801 return sd->selected;
6804 EOLIAN static Eina_List*
6805 _elm_genlist_realized_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6808 Eina_Bool done = EINA_FALSE;
6810 Eina_List *ret = NULL;
6812 EINA_INLIST_FOREACH(sd->blocks, itb)
6820 EINA_LIST_FOREACH(itb->items, l, it)
6822 if (it->realized) ret = eina_list_append(ret, EO_OBJ(it));
6834 EOLIAN static Elm_Object_Item*
6835 _elm_genlist_at_xy_item_get(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y, int *posret)
6837 Evas_Coord ox, oy, ow, oh;
6841 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
6843 EINA_INLIST_FOREACH(sd->blocks, itb)
6848 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->sd->pan_x,
6849 oy + itb->y - itb->sd->pan_y,
6850 itb->w, itb->h, x, y, 1, 1))
6852 EINA_LIST_FOREACH(itb->items, l, it)
6854 Evas_Coord itx, ity;
6856 itx = ox + itb->x + it->x - itb->sd->pan_x;
6857 ity = oy + itb->y + it->y - itb->sd->pan_y;
6858 if (ELM_RECTS_INTERSECT
6859 (itx, ity, it->item->w, it->item->h, x, y, 1, 1))
6863 if (y <= (ity + (it->item->h / 4))) *posret = -1;
6864 else if (y >= (ity + it->item->h - (it->item->h / 4)))
6871 lasty = ity + it->item->h;
6876 if (y > lasty) *posret = 1;
6883 EOLIAN static Elm_Object_Item*
6884 _elm_genlist_first_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6886 return EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(sd->items));
6889 EOLIAN static Elm_Object_Item*
6890 _elm_genlist_last_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6894 if (!sd->items) return NULL;
6896 it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
6901 EOLIAN static Elm_Object_Item *
6902 _elm_genlist_item_next_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6906 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6910 if (it) return EO_OBJ(it);
6914 EOLIAN static Elm_Object_Item *
6915 _elm_genlist_item_prev_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6919 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6923 if (it) return EO_OBJ(it);
6927 EOLIAN static Elm_Object_Item *
6928 _elm_genlist_item_parent_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6930 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
6932 return EO_OBJ(it->parent);
6935 EOLIAN static unsigned int
6936 _elm_genlist_item_subitems_count(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
6938 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, 0);
6940 return eina_list_count(item->item->items);
6943 EOLIAN static const Eina_List *
6944 _elm_genlist_item_subitems_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
6946 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6948 return item->item->items;
6952 _elm_genlist_item_subitems_clear(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6954 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6955 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
6957 if (!sd->tree_effect_enabled || !sd->move_effect_mode)
6958 _item_sub_items_clear(it);
6961 if (!sd->tree_effect_animator)
6963 sd->expanded_item = it;
6964 _item_tree_effect_before(it);
6965 evas_object_stack_below(sd->event_block_rect, sd->stack[1]);
6966 evas_object_show(sd->event_block_rect);
6967 sd->start_time = ecore_time_get();
6968 sd->tree_effect_animator =
6969 ecore_animator_add(_tree_effect_animator_cb, sd->obj);
6972 _item_sub_items_clear(it);
6977 _elm_genlist_item_selected_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
6981 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6983 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get())) return;
6985 selected = !!selected;
6986 if (it->selected == selected) return;
6988 if (selected) _item_select(it);
6989 else _item_unselect(it);
6992 EOLIAN static Eina_Bool
6993 _elm_genlist_item_selected_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6995 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
6997 return it->selected;
7000 static Elm_Gen_Item *
7001 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
7003 Elm_Object_Item *eo_it = EO_OBJ(it);
7004 Elm_Object_Item *eo_it2;
7006 if (it->item->expanded)
7008 eo_it2 = elm_genlist_item_next_get(eo_it);
7009 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
7014 eo_it2 = elm_genlist_item_next_get(eo_it);
7017 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
7018 if (it->item->expanded_depth >= it2->item->expanded_depth) return it2;
7019 eo_it2 = elm_genlist_item_next_get(eo_it2);
7022 return eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
7026 _elm_genlist_move_items_set(Elm_Gen_Item *it)
7029 Elm_Gen_Item *it2 = NULL;
7030 Evas_Coord ox, oy, ow, oh, dh = 0;
7031 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7033 sd->expanded_next_item =
7034 _elm_genlist_expanded_next_item_get(it);
7036 if (it->item->expanded)
7038 Elm_Object_Item *eo_item;
7039 l = elm_genlist_realized_items_get((sd)->obj);
7040 EINA_LIST_FREE(l, eo_item)
7042 ELM_GENLIST_ITEM_DATA_GET(eo_item, item);
7043 sd->move_items = eina_list_append(sd->move_items, item);
7046 EINA_LIST_FOREACH_SAFE(sd->move_items, l, ll, it2)
7048 if (it2 == sd->expanded_next_item) break;
7049 sd->move_items = eina_list_remove(sd->move_items, it2);
7054 Elm_Object_Item *eo_it2 = NULL;
7055 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7056 if (sd->expanded_next_item) eo_it2 = EO_OBJ(sd->expanded_next_item);
7058 while (eo_it2 && (dh < oy + oh))
7060 it2 = eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
7062 sd->move_items = eina_list_append(sd->move_items, it2);
7063 eo_it2 = elm_genlist_item_next_get(eo_it2);
7069 _event_block_rect_update(const Evas_Object *obj)
7071 Evas_Coord ox, oy, ow, oh;
7073 ELM_GENLIST_CHECK(obj);
7074 ELM_GENLIST_DATA_GET(obj, sd);
7076 if (!sd->event_block_rect)
7078 sd->event_block_rect = evas_object_rectangle_add(
7079 evas_object_evas_get(sd->obj));
7080 evas_object_smart_member_add(sd->event_block_rect, sd->pan_obj);
7083 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7084 evas_object_color_set(sd->event_block_rect, 0, 0, 0, 0);
7085 evas_object_resize(sd->event_block_rect, ow, oh);
7086 evas_object_move(sd->event_block_rect, ox, oy);
7090 _elm_genlist_item_expanded_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool expanded)
7092 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7093 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7095 expanded = !!expanded;
7096 if (it->item->expanded == expanded) return;
7097 if (it->item->type != ELM_GENLIST_ITEM_TREE) return;
7098 it->item->expanded = expanded;
7099 sd->expanded_item = it;
7100 _elm_genlist_move_items_set(it);
7102 if (sd->tree_effect_enabled)
7103 _event_block_rect_update(WIDGET(it));
7105 if (it->item->expanded)
7107 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
7109 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
7110 eo_do(WIDGET(it), eo_event_callback_call
7111 (ELM_GENLIST_EVENT_EXPANDED, EO_OBJ(it)));
7112 sd->auto_scroll_enabled = EINA_TRUE;
7113 if (_elm_config->atspi_mode)
7114 elm_interface_atspi_accessible_state_changed_signal_emit(eo_item, ELM_ATSPI_STATE_EXPANDED, EINA_TRUE);
7118 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
7120 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACTED, "elm");
7121 eo_do(WIDGET(it), eo_event_callback_call
7122 (ELM_GENLIST_EVENT_CONTRACTED, EO_OBJ(it)));
7123 sd->auto_scroll_enabled = EINA_FALSE;
7124 if (_elm_config->atspi_mode)
7125 elm_interface_atspi_accessible_state_changed_signal_emit(eo_item, ELM_ATSPI_STATE_EXPANDED, EINA_FALSE);
7129 EOLIAN static Eina_Bool
7130 _elm_genlist_item_expanded_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7132 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7134 return GL_IT(it)->expanded;
7138 _elm_genlist_item_expanded_depth_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7140 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, 0);
7142 return GL_IT(it)->expanded_depth;
7146 _elm_genlist_item_coordinates_calc(Elm_Gen_Item *it,
7147 Elm_Genlist_Item_Scrollto_Type type,
7154 Evas_Coord gith = 0;
7155 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7157 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
7158 if ((sd->queue) || (it->item->block->w < 1) ||
7159 (!((sd->homogeneous || it->itc->homogeneous) &&
7160 (sd->mode == ELM_LIST_COMPRESS))))
7162 if ((it->item->queued) || (!it->item->mincalcd) ||
7163 (sd->queue) || (it->item->block->w < 1))
7165 sd->check_scroll = EINA_TRUE;
7167 sd->bring_in = bring_in;
7168 sd->scroll_to_type = type;
7169 it->item->show_me = EINA_TRUE;
7171 ecore_job_del(sd->calc_job);
7172 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
7179 sd->show_item->item->show_me = EINA_FALSE;
7180 sd->show_item = NULL;
7183 evas_object_geometry_get(sd->pan_obj, NULL, NULL, w, h);
7186 case ELM_GENLIST_ITEM_SCROLLTO_IN:
7187 if ((it->item->group_item) &&
7188 (sd->pan_y > (it->y + it->item->block->y)))
7189 gith = it->item->group_item->item->h;
7191 *y = it->y + it->item->block->y - gith;
7194 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
7195 if (it->item->group_item) gith = it->item->group_item->item->h;
7196 *y = it->y + it->item->block->y - gith;
7199 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
7200 *y = it->y + it->item->block->y - (*h / 2) + (it->item->h / 2);
7203 case ELM_GENLIST_ITEM_SCROLLTO_BOTTOM:
7204 *y = it->y + it->item->block->y - *h + it->item->h;
7211 *x = it->x + it->item->block->x;
7212 *w = it->item->block->w;
7218 _elm_genlist_item_promote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7220 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7222 Elm_Object_Item *eo_first_item = elm_genlist_first_item_get(WIDGET(it));
7223 ELM_GENLIST_ITEM_DATA_GET(eo_first_item, first_item);
7224 _item_move_before(it, first_item);
7228 _elm_genlist_item_demote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7230 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7231 Elm_Object_Item *eo_last_item = elm_genlist_last_item_get(WIDGET(it));
7232 ELM_GENLIST_ITEM_DATA_GET(eo_last_item, last_item);
7233 _item_move_after(it, last_item);
7237 _elm_genlist_item_show(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item, Elm_Genlist_Item_Scrollto_Type type)
7239 Evas_Coord x, y, w, h;
7241 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
7243 if (item->want_hidden)
7245 WRN("Filter hided item cannot move to show");
7249 if (_elm_genlist_item_coordinates_calc
7250 (item, type, EINA_FALSE, &x, &y, &w, &h))
7251 eo_do(WIDGET(item), elm_interface_scrollable_content_region_show
7256 _elm_genlist_item_bring_in(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item, Elm_Genlist_Item_Scrollto_Type type)
7258 Evas_Coord x, y, w, h;
7260 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
7262 if (item->want_hidden)
7264 WRN("Filter hided item cannot move to bring in");
7268 if (_elm_genlist_item_coordinates_calc
7269 (item, type, EINA_TRUE, &x, &y, &w, &h))
7270 eo_do(WIDGET(item), elm_interface_scrollable_region_bring_in(x, y, w, h));
7274 _elm_genlist_item_all_contents_unset(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_List **l)
7276 Evas_Object *content;
7278 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7280 EINA_LIST_FREE(it->contents, content)
7282 _elm_widget_sub_object_redirect_to_top(WIDGET(it), content);
7283 edje_object_part_unswallow(VIEW(it), content);
7284 evas_object_hide(content);
7285 if (l) *l = eina_list_append(*l, content);
7290 _elm_genlist_item_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7292 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7293 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7295 if (!it->item->block) return;
7296 it->item->mincalcd = EINA_FALSE;
7297 it->item->updateme = EINA_TRUE;
7298 it->item->block->updateme = EINA_TRUE;
7299 ecore_job_del(sd->update_job);
7300 sd->update_job = ecore_job_add(_update_job, sd->obj);
7304 _elm_genlist_item_fields_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
7306 Elm_Genlist_Item_Field_Type itf)
7308 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7310 if (!it->item->block) return;
7312 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
7314 _item_text_realize(it, VIEW(it), &it->texts, parts);
7316 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
7318 _item_content_realize(it, VIEW(it), &it->contents, "contents", parts);
7321 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_contents,
7324 if (GL_IT(it)->deco_it_view)
7326 _item_content_realize(it, GL_IT(it)->deco_it_view,
7327 &GL_IT(it)->deco_it_contents,
7330 if (GL_IT(it)->wsd->decorate_all_mode)
7332 _item_content_realize(it, it->deco_all_view,
7333 &GL_IT(it)->deco_all_contents,
7336 if (it->has_contents != (!!it->contents))
7337 it->item->mincalcd = EINA_FALSE;
7338 it->has_contents = !!it->contents;
7339 if (it->item->type == ELM_GENLIST_ITEM_NONE)
7343 it->item_focus_chain = eina_list_free(it->item_focus_chain);
7344 EINA_LIST_FOREACH(it->contents, l, eobj)
7345 if (elm_widget_is(eobj) && elm_object_focus_allow_get(eobj))
7346 it->item_focus_chain = eina_list_append(it->item_focus_chain, eobj);
7350 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
7351 _item_state_realize(it, VIEW(it), parts);
7353 if (!it->item->mincalcd)
7354 elm_genlist_item_update(eo_item);
7358 _elm_genlist_item_item_class_update(Eo *eo_it, Elm_Gen_Item *it,
7359 const Elm_Genlist_Item_Class *itc)
7361 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7362 EINA_SAFETY_ON_NULL_RETURN(itc);
7364 if (!it->item->block) return;
7365 it->item->nocache_once = EINA_TRUE;
7367 ELM_SAFE_FREE(it->texts, elm_widget_stringlist_free);
7368 ELM_SAFE_FREE(GL_IT(it)->deco_it_texts, elm_widget_stringlist_free);
7369 ELM_SAFE_FREE(GL_IT(it)->deco_all_texts, elm_widget_stringlist_free);
7371 elm_genlist_item_update(eo_it);
7374 EOLIAN static const Elm_Genlist_Item_Class *
7375 _elm_genlist_item_item_class_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7377 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
7382 static Evas_Object *
7383 _elm_genlist_item_label_create(void *data,
7384 Evas_Object *obj EINA_UNUSED,
7385 Evas_Object *tooltip,
7386 void *it EINA_UNUSED)
7388 Evas_Object *label = elm_label_add(tooltip);
7393 elm_object_style_set(label, "tooltip");
7394 elm_object_text_set(label, data);
7400 _elm_genlist_item_label_del_cb(void *data,
7401 Evas_Object *obj EINA_UNUSED,
7402 void *event_info EINA_UNUSED)
7404 eina_stringshare_del(data);
7408 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
7411 eo_do(it, elm_wdg_item_tooltip_text_set(text));
7415 _elm_genlist_item_elm_widget_item_tooltip_text_set(Eo *eo_it, Elm_Gen_Item *it, const char *text)
7417 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7419 text = eina_stringshare_add(text);
7420 elm_genlist_item_tooltip_content_cb_set
7421 (eo_it, _elm_genlist_item_label_create, text,
7422 _elm_genlist_item_label_del_cb);
7426 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item,
7427 Elm_Tooltip_Item_Content_Cb func,
7429 Evas_Smart_Cb del_cb)
7431 eo_do(item, elm_wdg_item_tooltip_content_cb_set(func, data, del_cb));
7435 _elm_genlist_item_elm_widget_item_tooltip_content_cb_set(Eo *eo_it, Elm_Gen_Item *it,
7436 Elm_Tooltip_Item_Content_Cb func,
7438 Evas_Smart_Cb del_cb)
7440 ELM_GENLIST_ITEM_CHECK_OR_GOTO(it, error);
7442 if ((it->tooltip.content_cb != func) || (it->tooltip.data != data))
7444 if (it->tooltip.del_cb)
7445 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7447 it->tooltip.content_cb = func;
7448 it->tooltip.data = data;
7449 it->tooltip.del_cb = del_cb;
7454 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7455 elm_wdg_item_tooltip_content_cb_set
7456 (it->tooltip.content_cb, it->tooltip.data, NULL));
7458 elm_wdg_item_tooltip_style_set(it->tooltip.style),
7459 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
7465 if (del_cb) del_cb((void *)data, NULL, NULL);
7469 elm_genlist_item_tooltip_unset(Elm_Object_Item *item)
7471 eo_do(item, elm_wdg_item_tooltip_unset());
7475 _elm_genlist_item_elm_widget_item_tooltip_unset(Eo *eo_it, Elm_Gen_Item *it)
7477 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7479 if ((VIEW(it)) && (it->tooltip.content_cb))
7480 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7481 elm_wdg_item_tooltip_unset());
7483 if (it->tooltip.del_cb)
7484 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7485 it->tooltip.del_cb = NULL;
7486 it->tooltip.content_cb = NULL;
7487 it->tooltip.data = NULL;
7488 it->tooltip.free_size = EINA_FALSE;
7489 if (it->tooltip.style)
7490 eo_do(eo_it, elm_wdg_item_tooltip_style_set(NULL));
7494 elm_genlist_item_tooltip_style_set(Elm_Object_Item *item,
7497 eo_do(item, elm_wdg_item_tooltip_style_set(style));
7501 _elm_genlist_item_elm_widget_item_tooltip_style_set(Eo *eo_it, Elm_Gen_Item *it,
7504 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7506 eina_stringshare_replace(&it->tooltip.style, style);
7507 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7508 elm_wdg_item_tooltip_style_set(style));
7512 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
7515 return eo_do_ret(it, ret, elm_wdg_item_tooltip_style_get());
7518 EOLIAN static const char *
7519 _elm_genlist_item_elm_widget_item_tooltip_style_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7521 return it->tooltip.style;
7525 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *item,
7529 return eo_do_ret(item, ret, elm_wdg_item_tooltip_window_mode_set(disable));
7532 EOLIAN static Eina_Bool
7533 _elm_genlist_item_elm_widget_item_tooltip_window_mode_set(Eo *eo_it, Elm_Gen_Item *it,
7536 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7538 it->tooltip.free_size = disable;
7542 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7543 ret = elm_wdg_item_tooltip_window_mode_set(disable));
7551 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *eo_it)
7554 return eo_do_ret(eo_it, ret, elm_wdg_item_tooltip_window_mode_get());
7557 EOLIAN static Eina_Bool
7558 _elm_genlist_item_elm_widget_item_tooltip_window_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7560 return it->tooltip.free_size;
7564 elm_genlist_item_cursor_set(Elm_Object_Item *item,
7567 eo_do(item, elm_wdg_item_cursor_set(cursor));
7571 _elm_genlist_item_elm_widget_item_cursor_set(Eo *eo_it, Elm_Gen_Item *it,
7574 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7575 eina_stringshare_replace(&it->mouse_cursor, cursor);
7576 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7577 elm_wdg_item_cursor_set(cursor));
7581 elm_genlist_item_cursor_get(const Elm_Object_Item *eo_it)
7584 return eo_do_ret(eo_it, ret, elm_wdg_item_cursor_get());
7588 elm_genlist_item_cursor_unset(Elm_Object_Item *item)
7590 eo_do(item, elm_wdg_item_cursor_unset());
7594 _elm_genlist_item_elm_widget_item_cursor_unset(Eo *eo_it, Elm_Gen_Item *it)
7596 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7598 if (!it->mouse_cursor) return;
7600 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7601 elm_wdg_item_cursor_unset());
7603 ELM_SAFE_FREE(it->mouse_cursor, eina_stringshare_del);
7607 elm_genlist_item_cursor_style_set(Elm_Object_Item *eo_it,
7610 eo_do(eo_it, elm_wdg_item_cursor_style_set(style));
7614 elm_genlist_item_cursor_style_get(const Elm_Object_Item *eo_it)
7617 return eo_do_ret(eo_it, ret, elm_wdg_item_cursor_style_get());
7621 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *eo_it,
7622 Eina_Bool engine_only)
7624 eo_do(eo_it, elm_wdg_item_cursor_engine_only_set(engine_only));
7628 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *eo_it)
7631 return eo_do_ret(eo_it, ret, elm_wdg_item_cursor_engine_only_get());
7635 _elm_genlist_item_index_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7639 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, -1);
7641 EINA_INLIST_FOREACH(GL_IT(it)->wsd->items, tmp)
7643 if (tmp == it) break;
7650 _elm_genlist_mode_set(Eo *obj, Elm_Genlist_Data *sd, Elm_List_Mode mode)
7652 if (sd->mode == mode) return;
7655 if (sd->mode == ELM_LIST_LIMIT)
7657 sd->scr_minw = EINA_TRUE;
7658 sd->scr_minh = EINA_FALSE;
7660 else if (sd->mode == ELM_LIST_EXPAND)
7662 sd->scr_minw = EINA_TRUE;
7663 sd->scr_minh = EINA_TRUE;
7667 sd->scr_minw = EINA_FALSE;
7668 sd->scr_minh = EINA_FALSE;
7671 elm_layout_sizing_eval(obj);
7674 EOLIAN static Elm_List_Mode
7675 _elm_genlist_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7681 elm_genlist_bounce_set(Evas_Object *obj,
7685 ELM_GENLIST_CHECK(obj);
7686 eo_do(obj, elm_interface_scrollable_bounce_allow_set(h_bounce, v_bounce));
7690 _elm_genlist_elm_interface_scrollable_bounce_allow_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool h_bounce, Eina_Bool v_bounce)
7692 sd->h_bounce = !!h_bounce;
7693 sd->v_bounce = !!v_bounce;
7694 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_bounce_allow_set
7695 (sd->h_bounce, sd->v_bounce));
7699 elm_genlist_bounce_get(const Evas_Object *obj,
7700 Eina_Bool *h_bounce,
7701 Eina_Bool *v_bounce)
7703 ELM_GENLIST_CHECK(obj);
7704 eo_do( obj, elm_interface_scrollable_bounce_allow_get
7705 (h_bounce, v_bounce));
7709 _elm_genlist_elm_interface_scrollable_bounce_allow_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
7711 if (h_bounce) *h_bounce = sd->h_bounce;
7712 if (v_bounce) *v_bounce = sd->v_bounce;
7716 _elm_genlist_homogeneous_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool homogeneous)
7718 sd->homogeneous = !!homogeneous;
7721 EOLIAN static Eina_Bool
7722 _elm_genlist_homogeneous_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7724 return sd->homogeneous;
7728 _elm_genlist_block_count_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, int count)
7730 EINA_SAFETY_ON_TRUE_RETURN(count < 1);
7732 sd->max_items_per_block = count;
7733 sd->item_cache_max = sd->max_items_per_block * 2;
7734 _item_cache_clean(sd);
7738 _elm_genlist_block_count_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7740 return sd->max_items_per_block;
7744 _filter_item_internal(Elm_Gen_Item *it)
7747 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7748 if (sd->filter_data)
7750 if ((it->parent && !_item_filtered_get(it->parent)) ||
7751 (it->itc->func.filter_get &&
7752 !it->itc->func.filter_get(
7753 (void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)),
7754 WIDGET(it), sd->filter_data)))
7756 it->want_hidden = EINA_TRUE;
7757 if (sd->show_item == it) sd->show_item = NULL;
7758 it->item->block->changed = EINA_TRUE;
7761 sd->filtered_count++;
7763 it->filtered = EINA_TRUE;
7764 sd->processed_count++;
7768 _item_filtered_get(Elm_Gen_Item *it)
7771 if (!it) return EINA_FALSE;
7772 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7775 l = eina_list_data_find_list(sd->filter_queue, it);
7777 sd->filter_queue = eina_list_remove_list(sd->queue, l);
7778 l = eina_list_data_find_list(sd->queue, it);
7781 sd->queue = eina_list_remove_list(sd->queue, l);
7782 it->item->queued = EINA_FALSE;
7783 _item_process(sd, it);
7784 _item_process_post(sd, it, EINA_TRUE);
7787 _filter_item_internal(it);
7788 it->item->block->changed = EINA_TRUE;
7789 ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
7790 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
7792 if (!it->want_hidden) return EINA_TRUE;
7797 _filter_queue_process(Elm_Genlist_Data *sd)
7803 t0 = ecore_loop_time_get();
7804 for (n = 0; (sd->filter_queue) && (sd->processed_count < sd->item_count); n++)
7806 it = eina_list_data_get(sd->filter_queue);
7807 //FIXME: This is added as a fail safe code for items not yet processed.
7808 while (it->item->queued)
7810 if ((ecore_loop_time_get() - t0) > (ecore_animator_frametime_get()))
7812 sd->filter_queue = eina_list_remove_list
7813 (sd->filter_queue, sd->filter_queue);
7814 sd->filter_queue = eina_list_append(sd->filter_queue, it);
7815 it = eina_list_data_get(sd->filter_queue);
7817 sd->filter_queue = eina_list_remove_list(sd->filter_queue, sd->filter_queue);
7818 _filter_item_internal(it);
7819 it->item->block->changed = EINA_TRUE;
7820 if ((ecore_loop_time_get() - t0) > (ecore_animator_frametime_get()))
7822 //At least 1 item is filtered by this time, so return n+1 for first loop
7831 _filter_process(void *data,
7834 Elm_Genlist_Data *sd = data;
7836 if (_filter_queue_process(sd) > 0) *wakeup = EINA_TRUE;
7837 if (!sd->filter_queue) return ECORE_CALLBACK_CANCEL;
7838 return ECORE_CALLBACK_RENEW;
7842 _item_filter_enterer(void *data)
7844 Eina_Bool wakeup = EINA_FALSE;
7845 ELM_GENLIST_DATA_GET(data, sd);
7846 Eina_Bool ok = _filter_process(sd, &wakeup);
7850 ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
7851 sd->calc_job = ecore_job_add(_calc_job, data);
7853 if (ok == ECORE_CALLBACK_CANCEL)
7855 sd->queue_idle_enterer = NULL;
7856 eo_do(sd->obj, eo_event_callback_call(ELM_GENLIST_EVENT_FILTER_DONE, NULL));
7863 _elm_genlist_filter_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, void *filter_data)
7869 if (sd->filter_queue)
7870 ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
7871 ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
7872 ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
7873 sd->filtered_count = 0;
7874 sd->processed_count = 0;
7875 sd->filter = EINA_TRUE;
7876 sd->filter_data = filter_data;
7878 EINA_INLIST_FOREACH(sd->blocks, itb)
7882 EINA_LIST_FOREACH(itb->items, l, it)
7884 it->filtered = EINA_FALSE;
7885 it->want_hidden = EINA_FALSE;
7887 _filter_item_internal(it);
7889 sd->filter_queue = eina_list_append(sd->filter_queue, it);
7891 itb->changed = EINA_TRUE;
7895 EINA_LIST_FOREACH(itb->items, l, it)
7897 it->filtered = EINA_FALSE;
7898 it->want_hidden = EINA_FALSE;
7899 sd->filter_queue = eina_list_append(sd->filter_queue, it);
7905 sd->queue_filter_enterer = ecore_idle_enterer_add(_item_filter_enterer,
7910 _filter_iterator_next(Elm_Genlist_Filter *iter, void **data)
7912 if (!iter->current) return EINA_FALSE;
7914 while (iter->current)
7916 item = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->current, Elm_Gen_Item);
7917 iter->current = iter->current->next;
7918 if (_item_filtered_get(item))
7921 *data = EO_OBJ(item);
7930 _filter_iterator_free(Elm_Genlist_Filter *iter)
7935 static Evas_Object *
7936 _filter_iterator_get_container(Elm_Genlist_Filter *iter)
7938 Elm_Gen_Item *it = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->head, Elm_Gen_Item);
7942 EOLIAN Eina_Iterator *
7943 _elm_genlist_filter_iterator_new(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7945 Elm_Genlist_Filter *iter;
7946 iter = calloc(1, sizeof (Elm_Genlist_Filter));
7947 if (!iter) return NULL;
7949 iter->head = sd->items;
7950 iter->current = sd->items;
7952 iter->iterator.version = EINA_ITERATOR_VERSION;
7953 iter->iterator.next = FUNC_ITERATOR_NEXT(_filter_iterator_next);
7954 iter->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
7955 _filter_iterator_get_container);
7956 iter->iterator.free = FUNC_ITERATOR_FREE(_filter_iterator_free);
7958 EINA_MAGIC_SET(&iter->iterator, EINA_MAGIC_ITERATOR);
7960 return &iter->iterator;
7964 _elm_genlist_longpress_timeout_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, double timeout)
7966 sd->longpress_timeout = timeout;
7969 EOLIAN static double
7970 _elm_genlist_longpress_timeout_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7972 return sd->longpress_timeout;
7976 elm_genlist_scroller_policy_set(Evas_Object *obj,
7977 Elm_Scroller_Policy policy_h,
7978 Elm_Scroller_Policy policy_v)
7980 ELM_GENLIST_CHECK(obj);
7981 eo_do(obj, elm_interface_scrollable_policy_set(policy_h, policy_v));
7985 _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)
7987 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
7988 (policy_v >= ELM_SCROLLER_POLICY_LAST))
7991 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_set(policy_h, policy_v));
7995 elm_genlist_scroller_policy_get(const Evas_Object *obj,
7996 Elm_Scroller_Policy *policy_h,
7997 Elm_Scroller_Policy *policy_v)
7999 ELM_GENLIST_CHECK(obj);
8000 eo_do( obj, elm_interface_scrollable_policy_get(policy_h, policy_v));
8004 _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)
8006 Elm_Scroller_Policy s_policy_h, s_policy_v;
8008 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_get
8009 (&s_policy_h, &s_policy_v));
8010 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
8011 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
8015 _elm_genlist_realized_items_update(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED)
8018 Elm_Object_Item *it;
8020 list = elm_genlist_realized_items_get(obj);
8021 EINA_LIST_FREE(list, it)
8022 elm_genlist_item_update(it);
8026 _elm_genlist_item_decorate_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8027 const char *decorate_it_type,
8028 Eina_Bool decorate_it_set)
8030 Elm_Genlist_Data *sd;
8032 Elm_Object_Item *eo_it2 = NULL;
8035 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8036 sd = GL_IT(it)->wsd;
8038 if (!decorate_it_type) return;
8039 if (eo_do_ret(eo_it, tmp, elm_wdg_item_disabled_get())) return;
8040 if (sd->decorate_all_mode) return;
8042 if ((sd->mode_item == it) &&
8043 (!strcmp(decorate_it_type, sd->decorate_it_type)) &&
8046 if (!it->itc->decorate_item_style) return;
8047 it->decorate_it_set = decorate_it_set;
8051 EINA_LIST_FOREACH(sd->selected, l, eo_it2)
8053 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
8055 elm_genlist_item_selected_set(eo_it2, EINA_FALSE);
8060 Elm_Gen_Item *it2 = NULL;
8061 eo_it2 = elm_genlist_selected_item_get(sd->obj);
8062 if (eo_it2) it2 = eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
8063 if (it2 && it2->realized)
8064 elm_genlist_item_selected_set(eo_it2, EINA_FALSE);
8067 if (((sd->decorate_it_type)
8068 && (strcmp(decorate_it_type, sd->decorate_it_type))) ||
8069 (decorate_it_set) || ((it == sd->mode_item) && (!decorate_it_set)))
8070 _decorate_item_unset(sd);
8072 eina_stringshare_replace(&sd->decorate_it_type, decorate_it_type);
8073 if (decorate_it_set) _decorate_item_set(it);
8076 EOLIAN static const char *
8077 _elm_genlist_item_decorate_mode_get(Eo *eo_i EINA_UNUSED, Elm_Gen_Item *i)
8079 ELM_GENLIST_ITEM_CHECK_OR_RETURN(i, NULL);
8080 return GL_IT(i)->wsd->decorate_it_type;
8083 EOLIAN static Elm_Object_Item *
8084 _elm_genlist_decorated_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8086 return EO_OBJ(sd->mode_item);
8089 EOLIAN static Eina_Bool
8090 _elm_genlist_decorate_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8092 return sd->decorate_all_mode;
8096 _elm_genlist_decorate_mode_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool decorated)
8098 Elm_Object_Item *eo_it;
8100 Elm_Object_Item *deco_it;
8102 decorated = !!decorated;
8103 if (sd->decorate_all_mode == decorated) return;
8104 // decorate_all_mode should be set first
8105 // because content_get func. will be called after this
8106 // and user can check whether decorate_all_mode_ is enabled.
8107 sd->decorate_all_mode = decorated;
8109 ELM_SAFE_FREE(sd->tree_effect_animator, ecore_animator_del);
8110 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
8112 list = elm_genlist_realized_items_get(obj);
8113 if (!sd->decorate_all_mode)
8115 EINA_LIST_FREE(list, eo_it)
8117 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8118 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
8119 _decorate_all_item_unrealize(it);
8121 _item_cache_zero(sd);
8125 // unset decorated item
8126 deco_it = elm_genlist_decorated_item_get(obj);
8129 elm_genlist_item_decorate_mode_set
8130 (deco_it, elm_genlist_item_decorate_mode_get
8131 (deco_it), EINA_FALSE);
8132 _decorate_item_finished_signal_cb(deco_it, obj, NULL, NULL);
8135 EINA_LIST_FREE(list, eo_it)
8137 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8138 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
8140 if (it->itc->decorate_all_item_style)
8141 _decorate_all_item_realize(it, EINA_TRUE);
8146 ecore_job_del(sd->calc_job);
8147 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
8151 _elm_genlist_reorder_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool reorder_mode)
8153 Eina_List *realized;
8154 Elm_Object_Item *eo_it;
8156 if (sd->reorder_mode == !!reorder_mode) return;
8157 sd->reorder_mode = !!reorder_mode;
8158 realized = elm_genlist_realized_items_get(obj);
8159 EINA_LIST_FREE(realized, eo_it)
8161 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8162 if (sd->reorder_mode)
8164 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
8165 if (it->deco_all_view)
8167 edje_object_signal_emit(it->deco_all_view,
8168 SIGNAL_REORDER_MODE_SET, "elm");
8173 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_UNSET, "elm");
8174 if (it->deco_all_view)
8176 edje_object_signal_emit(it->deco_all_view,
8177 SIGNAL_REORDER_MODE_UNSET, "elm");
8183 EOLIAN static Eina_Bool
8184 _elm_genlist_reorder_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8186 return sd->reorder_mode;
8189 EOLIAN static Elm_Genlist_Item_Type
8190 _elm_genlist_item_type_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8192 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
8194 return GL_IT(it)->type;
8197 EAPI Elm_Genlist_Item_Class *
8198 elm_genlist_item_class_new(void)
8200 Elm_Genlist_Item_Class *itc = ELM_NEW(Elm_Genlist_Item_Class);
8201 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
8203 itc->version = CLASS_ALLOCATED;
8205 itc->delete_me = EINA_FALSE;
8211 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
8213 if (itc && (itc->version == CLASS_ALLOCATED))
8215 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
8216 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
8226 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
8228 if (itc && (itc->version == CLASS_ALLOCATED))
8231 if (itc->refcount == 0) itc->refcount--;
8236 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
8238 if (itc && (itc->version == CLASS_ALLOCATED))
8240 if (itc->refcount > 0) itc->refcount--;
8241 if (itc->delete_me && (!itc->refcount))
8242 elm_genlist_item_class_free(itc);
8247 _flip_job(void *data)
8249 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
8250 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8253 _elm_genlist_item_unrealize(it, EINA_FALSE);
8255 it->flipped = EINA_TRUE;
8256 it->item->nocache = EINA_TRUE;
8257 ecore_job_del(sd->calc_job);
8258 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
8262 _elm_genlist_item_flip_set(Eo *eo_it, Elm_Gen_Item *it, Eina_Bool flip)
8264 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8267 if (it->flipped == flip) return;
8271 ecore_job_add(_flip_job, it);
8275 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_DISABLED, "elm");
8276 if (GL_IT(it)->wsd->decorate_all_mode)
8277 edje_object_signal_emit(it->deco_all_view, SIGNAL_FLIP_DISABLED,
8281 _item_cache_zero(GL_IT(it)->wsd);
8282 elm_genlist_item_update(eo_it);
8283 it->item->nocache = EINA_FALSE;
8287 EOLIAN static Eina_Bool
8288 _elm_genlist_item_flip_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8290 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
8296 _elm_genlist_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Elm_Object_Select_Mode mode)
8298 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (sd->select_mode == mode))
8301 sd->select_mode = mode;
8303 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8304 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
8307 Elm_Object_Item *eo_it;
8308 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
8310 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8316 EOLIAN static Elm_Object_Select_Mode
8317 _elm_genlist_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8319 return sd->select_mode;
8323 _elm_genlist_highlight_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool highlight)
8325 sd->highlight = !!highlight;
8328 EOLIAN static Eina_Bool
8329 _elm_genlist_highlight_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8331 return sd->highlight;
8335 _elm_genlist_item_select_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8336 Elm_Object_Select_Mode mode)
8338 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8339 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8341 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (it->select_mode == mode))
8344 it->select_mode = mode;
8346 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8347 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
8350 if (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
8352 it->item->mincalcd = EINA_FALSE;
8353 it->item->updateme = EINA_TRUE;
8354 if (it->item->block) it->item->block->updateme = EINA_TRUE;
8355 ecore_job_del(sd->update_job);
8356 sd->update_job = ecore_job_add(_update_job, sd->obj);
8358 // reset homogeneous item size
8359 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
8360 if (sd->homogeneous || it->itc->homogeneous)
8363 eina_hash_find(sd->size_caches, &(it->itc));
8365 eina_hash_del_by_key(sd->size_caches, it->itc);
8370 EOLIAN static Elm_Object_Select_Mode
8371 _elm_genlist_item_select_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8373 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
8375 return it->select_mode;
8378 EOLIAN Elm_Atspi_State_Set
8379 _elm_genlist_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_it, Elm_Gen_Item *it EINA_UNUSED)
8381 Elm_Atspi_State_Set ret;
8384 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
8386 eo_do(eo_it, sel = elm_obj_genlist_item_selected_get());
8388 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTABLE);
8391 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTED);
8393 if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_TREE)
8395 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDABLE);
8396 if (elm_genlist_item_expanded_get(eo_it))
8397 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8398 //TIZEN_ONLY(20160606): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8400 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8403 //TIZEN_ONLY(20160608): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8404 else if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_GROUP)
8406 if (elm_genlist_item_expanded_get(eo_it))
8407 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8409 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8417 _elm_genlist_item_elm_interface_atspi_accessible_name_get(Eo *eo_it,
8422 char *accessible_name;
8423 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_name_get());
8424 if (ret) return ret;
8425 Elm_Genlist_Item_Type genlist_item_type = elm_genlist_item_type_get(eo_it);
8427 //TIZEN ONLY (160609) : Added in order to read when group item contain checkbox, sub text and normal as per UX guide 0.3.
8428 Eina_List *children = NULL, *l;
8430 Eina_Bool flag_contain_checkbox = EINA_FALSE;
8431 eo_do(eo_it, children = elm_interface_atspi_accessible_children_get());
8432 EINA_LIST_FOREACH(children, l, item)
8434 if (eo_isa((item), ELM_CHECK_CLASS))
8436 flag_contain_checkbox = EINA_TRUE;
8442 buf = eina_strbuf_new();
8444 if (it->itc->func.text_get)
8450 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
8452 EINA_LIST_FREE(texts, key)
8454 char *str_markup = it->itc->func.text_get
8455 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
8456 char *str_utf8 = _elm_util_mkup_to_text(str_markup);
8460 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
8461 eina_strbuf_append(buf, str_utf8);
8467 //TIZEN ONLY (160609) : Added in order to read when group item contain checkbox, sub text and normal as per UX guide 0.3.
8468 if (((genlist_item_type & ELM_GENLIST_ITEM_GROUP) || (genlist_item_type & ELM_GENLIST_ITEM_TREE)) && !flag_contain_checkbox)
8469 eina_strbuf_append(buf,", header");
8472 accessible_name = eina_strbuf_string_steal(buf);
8473 eina_strbuf_free(buf);
8475 eina_stringshare_del(it->base->accessible_name);
8476 it->base->accessible_name = eina_stringshare_add(accessible_name);
8477 free(accessible_name);
8478 return it->base->accessible_name;
8482 _elm_genlist_item_elm_interface_atspi_accessible_children_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8484 Eina_List *ret = NULL;
8489 parts = elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "contents"));
8491 EINA_LIST_FREE(parts, key)
8494 part = edje_object_part_swallow_get(VIEW(it), key);
8495 if (part && eo_isa(part, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
8497 ret = eina_list_append(ret, part);
8498 eo_do(part, elm_interface_atspi_accessible_parent_set(eo_it));
8506 _elm_genlist_tree_effect_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enabled)
8508 sd->tree_effect_enabled = !!enabled;
8511 EOLIAN static Eina_Bool
8512 _elm_genlist_tree_effect_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8514 return sd->tree_effect_enabled;
8518 _elm_genlist_focus_on_selection_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enabled)
8520 sd->focus_on_selection_enabled = !!enabled;
8523 EOLIAN static Eina_Bool
8524 _elm_genlist_focus_on_selection_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8526 return sd->focus_on_selection_enabled;
8529 EAPI Elm_Object_Item *
8530 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth)
8532 Elm_Gen_Item *it = NULL;
8536 ELM_GENLIST_CHECK(obj) NULL;
8537 ELM_GENLIST_DATA_GET(obj, sd);
8539 if (!sd->items) return NULL;
8541 a = eina_inlist_accessor_new(sd->items);
8542 if (!a) return NULL;
8543 if (eina_accessor_data_get(a, nth, &data))
8544 it = ELM_GEN_ITEM_FROM_INLIST(data);
8545 eina_accessor_free(a);
8550 _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)
8552 Evas_Coord ox, oy, oh, ow, item_x = 0, item_y = 0, item_w = 0, item_h = 0;
8554 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
8556 if (sd->focused_item)
8558 ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focus_it);
8559 evas_object_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
8560 elm_widget_focus_highlight_focus_part_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
8572 if (item_y > (oy + oh - item_h))
8574 *y = oy + oh - item_h;
8577 if ((item_x + item_w) > (ox + ow))
8587 EOLIAN static Elm_Object_Item *
8588 _elm_genlist_search_by_text_item_get(Eo *obj EINA_UNUSED,
8589 Elm_Genlist_Data *sd,
8590 Elm_Object_Item *item_to_search_from,
8591 const char *part_name,
8592 const char *pattern,
8593 Elm_Glob_Match_Flags flags)
8595 Elm_Gen_Item *it = NULL;
8597 Eina_Inlist *start = NULL;
8600 if (!pattern) return NULL;
8601 if (!sd->items) return NULL;
8603 if (flags & ELM_GLOB_MATCH_NO_ESCAPE) fnflags |= FNM_NOESCAPE;
8604 if (flags & ELM_GLOB_MATCH_PATH) fnflags |= FNM_PATHNAME;
8605 if (flags & ELM_GLOB_MATCH_PERIOD) fnflags |= FNM_PERIOD;
8607 if (flags & ELM_GLOB_MATCH_NOCASE) fnflags |= FNM_CASEFOLD;
8610 start = (item_to_search_from) ?
8611 EINA_INLIST_GET((Elm_Gen_Item *)eo_data_scope_get(item_to_search_from, ELM_GENLIST_ITEM_CLASS)) :
8613 EINA_INLIST_FOREACH(start, it)
8615 if (!it->itc->func.text_get) continue;
8616 str = it->itc->func.text_get((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), part_name);
8618 if (!fnmatch(pattern, str, fnflags))
8628 EOLIAN static Elm_Object_Item*
8629 _elm_genlist_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8631 return sd->focused_item;
8635 _elm_genlist_elm_widget_item_loop_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enable)
8637 sd->item_loop_enable = !!enable;
8640 EOLIAN static Eina_Bool
8641 _elm_genlist_elm_widget_item_loop_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8643 return sd->item_loop_enable;
8647 _elm_genlist_class_constructor(Eo_Class *klass)
8649 if (_elm_config->access_mode)
8650 _elm_genlist_smart_focus_next_enable = EINA_TRUE;
8652 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
8655 EOLIAN const Elm_Atspi_Action *
8656 _elm_genlist_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd EINA_UNUSED)
8658 static Elm_Atspi_Action atspi_actions[] = {
8659 { "move,prior", "move", "prior", _key_action_move},
8660 { "move,next", "move", "next", _key_action_move},
8661 { "move,left", "move", "left", _key_action_move},
8662 { "move,right", "move", "right", _key_action_move},
8663 { "move,up", "move", "up", _key_action_move},
8664 { "move,up,multi", "move", "up_multi", _key_action_move},
8665 { "move,down", "move", "down", _key_action_move},
8666 { "move,down,multi", "move", "down_multi", _key_action_move},
8667 { "move,first", "move", "first", _key_action_move},
8668 { "move,last", "move", "last", _key_action_move},
8669 { "select", "select", NULL, _key_action_select},
8670 { "select,multi", "select", "multi", _key_action_select},
8671 { "escape", "escape", NULL, _key_action_escape},
8672 { NULL, NULL, NULL, NULL }
8674 return &atspi_actions[0];
8678 _elm_genlist_elm_interface_atspi_accessible_children_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8680 Eina_List *ret = NULL;
8683 EINA_INLIST_FOREACH(sd->items, it)
8684 ret = eina_list_append(ret, EO_OBJ(it));
8689 EOLIAN Elm_Atspi_State_Set
8690 _elm_genlist_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED)
8692 Elm_Atspi_State_Set ret;
8694 eo_do_super(obj, ELM_GENLIST_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
8696 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MANAGES_DESCENDANTS);
8698 if (elm_genlist_multi_select_get(obj))
8699 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MULTISELECTABLE);
8701 //TIZEN_ONLY(20160520): genlist: added atspi support for drag n drop
8702 if (elm_genlist_reorder_mode_get(obj))
8703 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_ANIMATED);
8710 _elm_genlist_elm_interface_atspi_selection_selected_children_count_get(Eo *objm EINA_UNUSED, Elm_Genlist_Data *pd)
8712 return eina_list_count(pd->selected);
8716 _elm_genlist_elm_interface_atspi_selection_selected_child_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_idx)
8718 return eina_list_nth(pd->selected, child_idx);
8722 _elm_genlist_elm_interface_atspi_selection_child_select(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
8725 if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
8727 EINA_INLIST_FOREACH(pd->items, item)
8729 if (child_index-- == 0)
8731 elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
8740 _elm_genlist_elm_interface_atspi_selection_selected_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
8745 EINA_LIST_FOREACH(pd->selected, l, item)
8747 if (child_index-- == 0)
8749 elm_genlist_item_selected_set(item, EINA_FALSE);
8757 _elm_genlist_elm_interface_atspi_selection_is_child_selected(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
8761 EINA_INLIST_FOREACH(pd->items, item)
8763 if (child_index-- == 0)
8765 return elm_genlist_item_selected_get(EO_OBJ(item));
8772 _elm_genlist_elm_interface_atspi_selection_all_children_select(Eo *obj, Elm_Genlist_Data *pd)
8776 if (!elm_genlist_multi_select_get(obj))
8779 EINA_INLIST_FOREACH(pd->items, item)
8780 elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
8786 _elm_genlist_elm_interface_atspi_selection_clear(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd)
8788 return _all_items_deselect(pd);
8792 _elm_genlist_elm_interface_atspi_selection_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
8795 if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
8797 EINA_INLIST_FOREACH(pd->items, item)
8799 if (child_index-- == 0)
8801 elm_genlist_item_selected_set(EO_OBJ(item), EINA_FALSE);
8809 //TIZEN_ONLY(20160329): genlist: enhance accessibility scroll & highlight (30d9a6012e629cd9ea60eae8d576f3ebb94ada86)
8810 static int _is_item_in_viewport(int viewport_y, int viewport_h, int obj_y, int obj_h)
8812 if ((obj_y + obj_h/2) < viewport_y)
8814 else if ((obj_y + obj_h/2) > viewport_y + viewport_h)
8819 static Eina_Bool _atspi_enabled()
8822 Eina_Bool ret = EINA_FALSE;
8823 if (_elm_config->atspi_mode && (bridge = _elm_atspi_bridge_get()))
8824 eo_do(bridge, ret = elm_obj_atspi_bridge_connected_get());
8829 _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)
8831 if (!_atspi_enabled())
8833 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
8837 int old_x, old_y, delta_y;
8838 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_get(&old_x,&old_y));
8839 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
8840 delta_y = old_y - y;
8842 //check if highlighted item is genlist descendant
8843 Evas_Object * highlighted_obj = _elm_object_accessibility_currently_highlighted_get();
8844 if (eo_isa(highlighted_obj, ELM_WIDGET_ITEM_CLASS))
8846 Elm_Widget_Item_Data *id = eo_data_scope_get(highlighted_obj, ELM_WIDGET_ITEM_CLASS);
8847 highlighted_obj = id->view;
8850 Evas_Object *parent = highlighted_obj;
8851 if (eo_isa(highlighted_obj, ELM_WIDGET_CLASS))
8853 while ((parent = elm_widget_parent_get(parent)))
8857 else if (eo_isa(highlighted_obj, EDJE_OBJECT_CLASS))
8859 while ((parent = evas_object_smart_parent_get(parent)))
8863 // TIZEN_ONLY(20160805): set _accessibility_currently_highlighted_obj to NULL in object delete callback
8866 WRN("Improper highlighted object: %p", highlighted_obj);
8873 int obj_x, obj_y, w, h, hx, hy, hw, hh;
8874 evas_object_geometry_get(obj, &obj_x, &obj_y, &w, &h);
8876 evas_object_geometry_get(highlighted_obj, &hx, &hy, &hw, &hh);
8878 Elm_Gen_Item * next_previous_item = NULL;
8879 int viewport_position_result = _is_item_in_viewport(obj_y, h, hy, hh);
8880 //only highlight if move direction is correct
8881 //sometimes highlighted item is brought in and it does not fit viewport
8882 //however content goes to the viewport position so soon it will
8883 //meet _is_item_in_viewport condition
8884 if ((viewport_position_result < 0 && delta_y > 0) ||
8885 (viewport_position_result > 0 && delta_y < 0))
8888 Eina_List *realized_items = elm_genlist_realized_items_get(obj);
8891 Eina_Bool traverse_direction = viewport_position_result > 0;
8892 l = traverse_direction ? realized_items: eina_list_last(realized_items);
8896 item = eina_list_data_get(l);
8897 ELM_GENLIST_ITEM_DATA_GET(item, it_data);
8898 next_previous_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it_data));
8899 evas_object_geometry_get(VIEW(next_previous_item), &hx, &hy, &hw, &hh);
8900 if (_is_item_in_viewport(obj_y, h, hy, hh) == 0)
8903 next_previous_item = NULL;
8905 l = traverse_direction ? eina_list_next(l): eina_list_prev(l);
8908 if (next_previous_item)
8909 eo_do(EO_OBJ(next_previous_item), elm_interface_atspi_component_highlight_grab());
8913 EOLIAN static Eina_Bool
8914 _elm_genlist_item_elm_interface_atspi_component_highlight_grab(Eo *eo_it, Elm_Gen_Item *it)
8916 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8917 Eina_Bool ret = EINA_TRUE;
8919 // if item is realized check if in viewport
8922 Evas_Coord wy, wh, y, h;
8923 evas_object_geometry_get(WIDGET(it), NULL, &wy, NULL, &wh);
8924 evas_object_geometry_get(VIEW(it), NULL, &y, NULL, &h);
8925 int res = _is_item_in_viewport(wy, wh, y, h);
8928 // new item is above current
8929 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_BOTTOM);
8933 // new item is below current
8934 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
8937 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
8939 else // if item is not realized we should search if we are over or below viewport
8941 Eina_List *realized;
8942 int idx, top, bottom;
8943 realized = elm_genlist_realized_items_get(WIDGET(it));
8946 // index of realized element on top of viewport
8947 eo_do(eina_list_nth(realized, 0), top = elm_obj_genlist_item_index_get());
8948 // index of realized element on bottom of viewport
8949 eo_do(eina_list_last_data_get(realized), bottom = elm_obj_genlist_item_index_get());
8950 eo_do(eo_it, idx = elm_obj_genlist_item_index_get());
8951 eina_list_free(realized);
8953 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_BOTTOM);
8954 else if (idx > bottom)
8955 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
8957 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
8962 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_component_highlight_grab());
8964 sd->atspi_item_to_highlight = it;//it will be highlighted when realized
8966 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_it);
8971 EOLIAN static Eina_Bool
8972 _elm_genlist_item_elm_interface_atspi_component_highlight_clear(Eo *eo_it, Elm_Gen_Item *it)
8975 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8976 if (sd->atspi_item_to_highlight == it)
8977 sd->atspi_item_to_highlight = NULL;
8979 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_it);
8981 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_component_highlight_clear());
8986 //Tizen Only(20170113) : Below Legacy APIs are Mobile Only Feature
8988 elm_genlist_realization_mode_set(Evas_Object *obj EINA_UNUSED, Eina_Bool mode EINA_UNUSED)
8990 // Mobile Only Feature;
8995 elm_genlist_realization_mode_get(Evas_Object *obj EINA_UNUSED)
8997 // Mobile Only Feature;
9002 elm_genlist_item_reorder_start(Elm_Object_Item *item EINA_UNUSED)
9004 // Mobile Only Feature;
9009 elm_genlist_item_reorder_stop(Elm_Object_Item *item EINA_UNUSED)
9011 // Mobile Only Feature;
9016 #include "elm_genlist.eo.c"
9017 #include "elm_genlist_item.eo.c"