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)
1401 edje_object_signal_emit(VIEW(it), SIGNAL_SELECTED, "elm");
1402 if (it->deco_all_view)
1403 edje_object_signal_emit
1404 (it->deco_all_view, SIGNAL_SELECTED, "elm");
1406 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()))
1408 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
1409 if (it->deco_all_view)
1410 edje_object_signal_emit
1411 (it->deco_all_view, SIGNAL_DISABLED, "elm");
1413 if (it->item->expanded)
1415 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
1416 if (it->deco_all_view)
1417 edje_object_signal_emit
1418 (it->deco_all_view, SIGNAL_EXPANDED, "elm");
1420 // TIZEN_ONLY(20161206) : Fix duplicated focused signal emit
1421 //if ((EO_OBJ(it) == sd->focused_item) &&
1422 // (elm_widget_focus_highlight_enabled_get(WIDGET(it)) || _elm_config->win_auto_focus_enable))
1423 // edje_object_signal_emit(VIEW(it), SIGNAL_FOCUSED, "elm");
1428 _view_inflate(Evas_Object *view, Elm_Gen_Item *it, Eina_List **sources,
1429 Eina_List **contents)
1432 if (sources) _item_text_realize(it, view, sources, NULL);
1433 if (contents) _item_content_realize(it, view, contents, "contents", NULL);
1434 _item_state_realize(it, view, NULL);
1438 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1440 if (it->position_update || GL_IT(it)->block->position_update)
1442 eo_do(WIDGET(it), eo_event_callback_call
1443 (ELM_GENLIST_EVENT_INDEX_UPDATE, EO_OBJ(it)));
1444 it->position_update = EINA_FALSE;
1449 _decorate_all_item_position(Elm_Gen_Item *it,
1453 if ((!it) || (!GL_IT(it)->wsd->decorate_all_mode)) return;
1454 evas_object_resize(it->deco_all_view, it->item->w, it->item->h);
1455 evas_object_move(it->deco_all_view, itx, ity);
1459 _decorate_all_item_realize(Elm_Gen_Item *it,
1460 Eina_Bool effect_on)
1463 const char *stacking;
1464 const char *stacking_even;
1467 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1469 if (it->item->decorate_all_item_realized) return;
1471 it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
1472 edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
1473 elm_config_scale_get());
1474 evas_object_smart_member_add(it->deco_all_view, sd->pan_obj);
1475 elm_widget_sub_object_add(WIDGET(it), it->deco_all_view);
1477 if (it->item->type & ELM_GENLIST_ITEM_TREE)
1478 strncpy(buf, "tree", sizeof(buf));
1479 else strncpy(buf, "item", sizeof(buf));
1480 if (sd->mode == ELM_LIST_COMPRESS)
1481 strncat(buf, "_compress", sizeof(buf) - strlen(buf) - 1);
1483 strncat(buf, "/", sizeof(buf) - strlen(buf) - 1);
1484 strncat(buf, it->itc->decorate_all_item_style, sizeof(buf) - strlen(buf) - 1);
1486 elm_widget_theme_object_set(WIDGET(it), it->deco_all_view, "genlist", buf,
1487 elm_widget_style_get(WIDGET(it)));
1489 stacking_even = edje_object_data_get(VIEW(it), "stacking_even");
1490 if (!stacking_even) stacking_even = "above";
1491 it->item->stacking_even = !!strcmp("above", stacking_even);
1493 stacking = edje_object_data_get(VIEW(it), "stacking");
1494 if (!stacking) stacking = "yes";
1495 it->item->nostacking = !!strcmp("yes", stacking);
1497 edje_object_mirrored_set
1498 (it->deco_all_view, elm_widget_mirrored_get(WIDGET(it)));
1500 _elm_genlist_item_position_state_update(it);
1501 _elm_genlist_item_state_update(it);
1503 if (GL_IT(it)->wsd->reorder_mode)
1505 edje_object_signal_emit(it->deco_all_view, SIGNAL_REORDER_MODE_UNSET,
1510 edje_object_signal_emit
1511 (it->deco_all_view, SIGNAL_DECORATE_ENABLED_EFFECT, "elm");
1513 edje_object_signal_emit
1514 (it->deco_all_view, SIGNAL_DECORATE_ENABLED, "elm");
1516 _item_mouse_callbacks_del(it, VIEW(it));
1517 _item_mouse_callbacks_add(it, it->deco_all_view);
1520 edje_object_signal_emit
1521 (it->deco_all_view, SIGNAL_FLIP_ENABLED, "elm");
1522 _view_inflate(it->deco_all_view, it, NULL, &(GL_IT(it)->deco_all_contents));
1523 edje_object_part_swallow
1524 (it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
1526 _decorate_all_item_position(it, it->item->scrl_x, it->item->scrl_y);
1527 evas_object_show(it->deco_all_view);
1530 edje_object_signal_emit(it->deco_all_view, SIGNAL_SELECTED, "elm");
1532 it->item->decorate_all_item_realized = EINA_TRUE;
1533 it->want_unrealize = EINA_FALSE;
1536 //-- tree expand/contract signal handle routine --//
1538 _expand_toggle_signal_cb(void *data,
1539 Evas_Object *obj EINA_UNUSED,
1540 const char *emission EINA_UNUSED,
1541 const char *source EINA_UNUSED)
1543 Elm_Gen_Item *it = data;
1545 if (it->item->expanded)
1546 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_CONTRACT_REQUEST, EO_OBJ(it)));
1548 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_EXPAND_REQUEST, EO_OBJ(it)));
1552 _expand_signal_cb(void *data,
1553 Evas_Object *obj EINA_UNUSED,
1554 const char *emission EINA_UNUSED,
1555 const char *source EINA_UNUSED)
1557 Elm_Gen_Item *it = data;
1559 if (!it->item->expanded)
1560 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_EXPAND_REQUEST, EO_OBJ(it)));
1564 _contract_signal_cb(void *data,
1565 Evas_Object *obj EINA_UNUSED,
1566 const char *emission EINA_UNUSED,
1567 const char *source EINA_UNUSED)
1569 Elm_Gen_Item *it = data;
1571 if (it->item->expanded)
1572 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_CONTRACT_REQUEST, EO_OBJ(it)));
1575 //-- item cache handle routine --//
1576 // push item cache into caches
1578 _item_cache_push(Elm_Genlist_Data *sd, Item_Cache *itc)
1580 if (!itc || (sd->item_cache_max <= 0))
1583 sd->item_cache_count++;
1585 eina_inlist_prepend(sd->item_cache, EINA_INLIST_GET(itc));
1590 // pop item cache from caches
1592 _item_cache_pop(Elm_Genlist_Data *sd, Item_Cache *itc)
1594 if (!itc || (!sd->item_cache) ||
1595 (sd->item_cache_count <= 0))
1599 eina_inlist_remove (sd->item_cache, EINA_INLIST_GET(itc));
1600 sd->item_cache_count--;
1605 // free one item cache
1607 _item_cache_free(Item_Cache *itc)
1613 evas_object_del(itc->spacer);
1614 evas_object_del(itc->base_view);
1615 itc->item_class = NULL;
1616 EINA_LIST_FREE(itc->contents, c)
1620 ELM_SAFE_FREE(itc, free);
1623 // clean up item cache by removing overflowed caches
1625 _item_cache_clean(Elm_Genlist_Data *sd)
1627 evas_event_freeze(evas_object_evas_get(sd->obj));
1629 while ((sd->item_cache) && (sd->item_cache_count > sd->item_cache_max))
1632 EINA_INLIST_CONTAINER_GET(sd->item_cache->last, Item_Cache);
1633 _item_cache_free(_item_cache_pop(sd, itc));
1635 evas_event_thaw(evas_object_evas_get(sd->obj));
1636 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
1639 // empty all item caches
1641 _item_cache_zero(Elm_Genlist_Data *sd)
1643 int pmax = sd->item_cache_max;
1645 sd->item_cache_max = 0;
1646 _item_cache_clean(sd);
1647 sd->item_cache_max = pmax;
1650 // add an item to item cache
1652 _item_cache_add(Elm_Gen_Item *it, Eina_List *contents)
1654 if (it->item->nocache_once || it->item->nocache) return EINA_FALSE;
1656 Item_Cache *itc = NULL;
1657 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1658 Evas_Object *obj = sd->obj;
1661 evas_event_freeze(evas_object_evas_get(obj));
1663 if (sd->item_cache_max > 0)
1664 itc = ELM_NEW(Item_Cache);
1666 if (!_item_cache_push(sd, itc))
1668 if (itc) ELM_SAFE_FREE(itc, free);
1670 evas_event_thaw(evas_object_evas_get(obj));
1671 evas_event_thaw_eval(evas_object_evas_get(obj));
1674 itc->spacer = it->spacer;
1675 itc->base_view = VIEW(it);
1676 itc->item_class = it->itc;
1677 itc->contents = contents;
1678 if (it->item->type & ELM_GENLIST_ITEM_TREE)
1681 if (it->item->expanded)
1682 edje_object_signal_emit(itc->base_view, SIGNAL_CONTRACTED, "elm");
1686 edje_object_signal_emit(itc->base_view, SIGNAL_UNSELECTED, "elm");
1687 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()))
1688 edje_object_signal_emit(itc->base_view, SIGNAL_ENABLED, "elm");
1689 if ((EO_OBJ(it) == sd->focused_item) &&
1690 (elm_widget_focus_highlight_enabled_get(obj) || _elm_config->win_auto_focus_enable))
1691 edje_object_signal_emit(itc->base_view, SIGNAL_UNFOCUSED, "elm");
1693 //Tizen Only(20160307)
1694 edje_object_signal_emit(itc->base_view, SIGNAL_DEFAULT, "elm");
1696 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
1697 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
1699 // FIXME: other callbacks?
1700 edje_object_signal_callback_del_full
1701 (itc->base_view, "elm,action,expand,toggle", "elm",
1702 _expand_toggle_signal_cb, it);
1703 edje_object_signal_callback_del_full
1704 (itc->base_view, "elm,action,expand", "elm", _expand_signal_cb, it);
1705 edje_object_signal_callback_del_full
1706 (itc->base_view, "elm,action,contract", "elm", _contract_signal_cb, it);
1707 _item_mouse_callbacks_del(it, itc->base_view);
1709 edje_object_mirrored_set(itc->base_view,
1710 elm_widget_mirrored_get(WIDGET(it)));
1711 edje_object_scale_set(itc->base_view,
1712 elm_widget_scale_get(WIDGET(it))
1713 * elm_config_scale_get());
1717 evas_object_hide(itc->base_view);
1718 evas_object_move(itc->base_view, -9999, -9999);
1720 _item_cache_clean(sd);
1722 evas_event_thaw(evas_object_evas_get(obj));
1723 evas_event_thaw_eval(evas_object_evas_get(obj));
1728 // find an item from item cache and remove it from the cache
1730 _item_cache_find(Elm_Gen_Item *it)
1732 if (it->item->nocache_once || it->item->nocache) return EINA_FALSE;
1734 Item_Cache *itc = NULL;
1737 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1739 if (it->item->type & ELM_GENLIST_ITEM_TREE) tree = 1;
1740 EINA_INLIST_FOREACH_SAFE(sd->item_cache, l, itc)
1742 if ((itc->tree == tree) &&
1743 (((!it->itc) && (!itc->item_class)) ||
1744 (it->itc && itc->item_class &&
1745 (it->itc == itc->item_class))))
1747 itc = _item_cache_pop(sd, itc);
1750 it->spacer = itc->spacer;
1751 VIEW(it) = itc->base_view;
1753 itc->base_view = NULL;
1755 eina_list_free(itc->contents);
1756 itc->contents = NULL;
1757 _item_cache_free(itc);
1765 _content_cache_add(Elm_Gen_Item *it, Eina_List **cache)
1767 Evas_Object *content = NULL;
1768 EINA_LIST_FREE(it->contents, content)
1770 *cache = eina_list_append(*cache, content);
1777 _access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
1782 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1783 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1785 buf = eina_strbuf_new();
1787 if (it->itc->func.text_get)
1792 if (!(it->texts)) it->texts =
1793 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1795 EINA_LIST_FOREACH(it->texts, l, key)
1797 char *s = it->itc->func.text_get
1798 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
1802 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
1803 eina_strbuf_append(buf, s);
1809 ret = eina_strbuf_string_steal(buf);
1810 eina_strbuf_free(buf);
1815 _access_state_cb(void *data, Evas_Object *obj EINA_UNUSED)
1817 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1818 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1820 if (it->base->disabled)
1821 return strdup(E_("State: Disabled"));
1827 _access_on_highlight_cb(void *data)
1829 Evas_Coord x, y, w, h;
1830 Evas_Coord sx, sy, sw, sh;
1831 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1832 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
1834 evas_object_geometry_get(it->base->view, &x, &y, &w, &h);
1835 // XXX There would be a reason.
1836 if ((w == 0) && (h == 0)) return;
1838 evas_object_geometry_get(it->base->widget, &sx, &sy, &sw, &sh);
1839 if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
1840 elm_genlist_item_bring_in(EO_OBJ(it),
1841 ELM_GENLIST_ITEM_SCROLLTO_IN);
1845 _access_widget_item_register(Elm_Gen_Item *it)
1847 Elm_Access_Info *ai;
1849 _elm_access_widget_item_register(it->base);
1851 ai = _elm_access_info_get(it->base->access_obj);
1853 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1854 _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
1855 _elm_access_on_highlight_hook_set(ai, _access_on_highlight_cb, it);
1856 _elm_access_activate_callback_set(ai, _access_activate_cb, EO_OBJ(it));
1860 _elm_genlist_item_focus_update(Elm_Gen_Item *it)
1862 const char *focus_raise;
1863 Evas_Object *obj = WIDGET(it);
1864 ELM_GENLIST_DATA_GET(obj, sd);
1866 if (elm_widget_focus_highlight_enabled_get(obj) || _elm_config->win_auto_focus_enable)
1867 edje_object_signal_emit(VIEW(it), SIGNAL_FOCUSED, "elm");
1869 focus_raise = edje_object_data_get(VIEW(it), "focusraise");
1870 if ((focus_raise) && (!strcmp(focus_raise, "on")))
1875 evas_object_raise(VIEW(it));
1876 EINA_LIST_FOREACH(sd->group_items, l, git)
1878 if (git->realized) evas_object_raise(VIEW(git));
1884 _item_realize(Elm_Gen_Item *it,
1888 const char *treesize;
1889 Item_Size *size = NULL;
1891 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
1895 if (it->item->order_num_in != in)
1897 _item_order_update(EINA_INLIST_GET(it), in);
1898 _elm_genlist_item_state_update(it);
1899 _elm_genlist_item_index_update(it);
1903 it->item->order_num_in = in;
1905 if (sd->tree_effect_enabled ||
1906 (!_item_cache_find(it)))
1908 VIEW(it) = _view_create(it, it->itc->item_style);
1909 if (it->item->nocache_once)
1910 it->item->nocache_once = EINA_FALSE;
1913 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
1914 if (_elm_config->atspi_mode)
1916 elm_interface_atspi_accessible_added(EO_OBJ(it));
1917 elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
1921 //TIZEN_ONLY(20180328): clean up elm color class feature
1922 if (it->base->color_classes)
1923 _elm_widget_item_color_class_update(it->base);
1927 if (_elm_config->access_mode) _access_widget_item_register(it);
1929 _item_order_update(EINA_INLIST_GET(it), in);
1931 if (sd->reorder_mode)
1932 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
1934 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_UNSET, "elm");
1936 treesize = edje_object_data_get(VIEW(it), "treesize");
1937 if (treesize) tsize = atoi(treesize);
1939 if (edje_object_part_exists(VIEW(it), "elm.swallow.pad"))
1941 if (!it->spacer && treesize)
1944 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1945 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1946 elm_widget_sub_object_add(WIDGET(it), it->spacer);
1949 evas_object_size_hint_min_set
1950 (it->spacer, (it->item->expanded_depth * tsize) *
1951 elm_config_scale_get(), 1);
1952 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1956 ELM_SAFE_FREE(it->spacer, evas_object_del);
1961 edje_object_signal_callback_add
1962 (VIEW(it), "elm,action,expand,toggle", "elm",
1963 _expand_toggle_signal_cb, it);
1964 edje_object_signal_callback_add
1965 (VIEW(it), "elm,action,expand", "elm", _expand_signal_cb, it);
1966 edje_object_signal_callback_add
1967 (VIEW(it), "elm,action,contract", "elm", _contract_signal_cb, it);
1968 _item_mouse_callbacks_add(it, VIEW(it));
1970 if ((sd->decorate_all_mode) && (!it->deco_all_view) &&
1971 (it->item->type != ELM_GENLIST_ITEM_GROUP) &&
1972 (it->itc->decorate_all_item_style))
1973 _decorate_all_item_realize(it, EINA_FALSE);
1975 _elm_genlist_item_state_update(it);
1976 _elm_genlist_item_index_update(it);
1978 if (EO_OBJ(it) == sd->focused_item)
1980 _elm_genlist_item_focus_update(it);
1981 _elm_widget_item_highlight_in_theme(WIDGET(it), EO_OBJ(it));
1982 _elm_widget_highlight_in_theme_update(WIDGET(it));
1983 _elm_widget_focus_highlight_start(WIDGET(it));
1987 size = eina_hash_find(sd->size_caches, &(it->itc));
1988 /* homogeneous genlist shortcut */
1989 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
1990 if ((calc) && (sd->homogeneous || it->itc->homogeneous) && (!it->item->mincalcd) && size)
1992 GL_IT(it)->w = GL_IT(it)->minw = size->minw;
1993 GL_IT(it)->h = GL_IT(it)->minh = size->minh;
1994 it->item->mincalcd = EINA_TRUE;
1998 if (eina_list_count(it->contents) != 0)
1999 ERR_ABORT("If you see this error, please notify us and we"
2002 _view_inflate(VIEW(it), it, &it->texts, &it->contents);
2003 if (it->has_contents != (!!it->contents))
2004 it->item->mincalcd = EINA_FALSE;
2005 it->has_contents = !!it->contents;
2008 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
2009 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_contents,
2013 /* access: unregister item which have no text and content */
2014 if (_elm_config->access_mode && !it->texts && !it->contents)
2015 _elm_access_widget_item_unregister(it->base);
2017 if (!it->item->mincalcd)
2019 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
2020 if ((sd->homogeneous || it->itc->homogeneous) && size)
2022 GL_IT(it)->w = GL_IT(it)->minw = size->minw;
2023 GL_IT(it)->h = GL_IT(it)->minh = size->minh;
2024 it->item->mincalcd = EINA_TRUE;
2028 Evas_Coord mw = -1, mh = -1;
2030 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
2031 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2032 if (sd->mode == ELM_LIST_COMPRESS)
2033 mw = sd->prev_viewport_w;
2034 edje_object_message_signal_process(VIEW(it));
2035 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
2036 // TIZEN_ONLY(161209): Fix item shrink
2037 if (sd->mode == ELM_LIST_COMPRESS ||
2038 (sd->mode == ELM_LIST_SCROLL && mw < sd->prev_viewport_w))
2039 mw = sd->prev_viewport_w;
2041 it->item->w = it->item->minw = mw;
2042 it->item->h = it->item->minh = mh;
2043 it->item->mincalcd = EINA_TRUE;
2045 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
2046 if (sd->homogeneous || it->itc->homogeneous)
2049 eina_hash_del_by_key(sd->size_caches, &(it->itc));
2051 size = ELM_NEW(Item_Size);
2052 size->itc = it->itc;
2055 eina_hash_add(sd->size_caches, &(it->itc), size);
2059 if (!calc) evas_object_show(VIEW(it));
2062 if (it->tooltip.content_cb)
2065 elm_wdg_item_tooltip_content_cb_set(
2066 it->tooltip.content_cb, it->tooltip.data, NULL),
2067 elm_wdg_item_tooltip_style_set(it->tooltip.style),
2068 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
2071 if (it->mouse_cursor)
2073 elm_wdg_item_cursor_set(it->mouse_cursor));
2075 it->realized = EINA_TRUE;
2076 it->want_unrealize = EINA_FALSE;
2080 if (it->item->tree_effect_hide_me)
2082 if (sd->move_effect_mode
2083 != ELM_GENLIST_TREE_EFFECT_NONE)
2086 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "");
2087 edje_object_signal_emit(VIEW(it), SIGNAL_HIDE, "elm");
2089 it->item->tree_effect_hide_me = EINA_FALSE;
2092 if (it->item->type == ELM_GENLIST_ITEM_NONE)
2096 EINA_LIST_FOREACH(it->contents, l, eobj)
2097 if (elm_widget_is(eobj) && elm_object_focus_allow_get(eobj))
2098 it->item_focus_chain = eina_list_append
2099 (it->item_focus_chain, eobj);
2103 if (it->item->type == ELM_GENLIST_ITEM_TREE)
2105 Evas_Object* t_eobj;
2107 EINA_LIST_FOREACH(it->contents, tl, t_eobj)
2108 if (elm_widget_is(t_eobj) && elm_object_focus_allow_get(t_eobj))
2109 it->item_focus_chain = eina_list_append
2110 (it->item_focus_chain, t_eobj);
2114 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_REALIZED, EO_OBJ(it)));
2117 //Send a signal so that an item changes its style according to its expand depth
2118 if (GL_IT(it)->expanded_depth > 0)
2121 snprintf(buf, sizeof(buf), "elm,state,expanded_depth,%d",
2122 GL_IT(it)->expanded_depth);
2123 edje_object_signal_emit(VIEW(it), buf, "elm");
2126 if ((!calc) && (sd->decorate_all_mode) &&
2127 (it->item->type != ELM_GENLIST_ITEM_GROUP))
2129 if (it->itc->decorate_all_item_style)
2131 if (!it->deco_all_view)
2132 _decorate_all_item_realize(it, EINA_FALSE);
2133 edje_object_message_signal_process(it->deco_all_view);
2137 if (it->decorate_it_set) _decorate_item_set(it);
2139 edje_object_message_signal_process(VIEW(it));
2140 //TIZEN_ONLY(20160329): genlist: enhance accessibility scroll & highlight (30d9a6012e629cd9ea60eae8d576f3ebb94ada86)
2141 if (sd->atspi_item_to_highlight == it)
2143 sd->atspi_item_to_highlight = NULL;
2144 eo_do_super(EO_OBJ(it), ELM_GENLIST_ITEM_CLASS, elm_interface_atspi_component_highlight_grab());
2150 _tree_effect_animator_cb(void *data)
2154 int y = 0, dy = 0, dh = 0;
2155 double effect_duration = 0.3, t;
2156 ELM_GENLIST_DATA_GET(data, sd);
2157 Eina_Bool end = EINA_FALSE, vis = EINA_TRUE;
2158 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2159 Elm_Gen_Item *it = NULL, *it2, *expanded_next_it;
2160 Elm_Object_Item *eo_it = NULL, *eo_it2;
2162 t = ((0.0 > (t = ecore_time_get() - sd->start_time)) ? 0.0 : t);
2163 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
2164 evas_output_viewport_get
2165 (evas_object_evas_get(sd->pan_obj), &cvx, &cvy, &cvw, &cvh);
2166 if (t > effect_duration) end = EINA_TRUE;
2168 // Below while statement is needed, when the genlist is resized.
2169 it2 = sd->expanded_item;
2170 eo_it2 = EO_OBJ(it2);
2171 while (eo_it2 && vis)
2173 it2 = eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
2174 evas_object_move(VIEW(it2), it2->item->scrl_x, it2->item->scrl_y);
2175 vis = (ELM_RECTS_INTERSECT(it2->item->scrl_x, it2->item->scrl_y,
2176 it2->item->w, it2->item->h, cvx, cvy, cvw,
2178 eo_it2 = elm_genlist_item_prev_get(eo_it2);
2181 if (sd->expanded_next_item)
2183 expanded_next_it = sd->expanded_next_item;
2186 EINA_LIST_FOREACH(sd->move_items, l, it)
2188 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
2190 expanded_next_it->item->old_scrl_y =
2191 sd->expanded_item->item->old_scrl_y
2192 + sd->expanded_item->item->h;
2193 if (expanded_next_it->item->scrl_y <=
2194 expanded_next_it->item->old_scrl_y) /* did not
2198 expanded_next_it->item->scrl_y = cvy + cvh;
2200 dy = ((expanded_next_it->item->scrl_y >= (cvy + cvh)) ?
2201 cvy + cvh : expanded_next_it->item->scrl_y) -
2202 expanded_next_it->item->old_scrl_y;
2204 else if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_CONTRACT)
2206 if (expanded_next_it->item->scrl_y >
2207 expanded_next_it->item->old_scrl_y) /* did not
2211 expanded_next_it->item->old_scrl_y = cvy + cvh;
2213 if (expanded_next_it->item->old_scrl_y > (cvy + cvh))
2215 dy = (sd->expanded_item->item->scrl_y +
2216 sd->expanded_item->item->h) - cvy + cvh;
2217 expanded_next_it->item->old_scrl_y = cvy + cvh;
2221 dy = (sd->expanded_item->item->scrl_y +
2222 sd->expanded_item->item->h) -
2223 expanded_next_it->item->old_scrl_y;
2227 if (t <= effect_duration)
2229 y = ((1 - (1 - (t / effect_duration)) *
2230 (1 - (t / effect_duration))) * dy);
2238 if (!it->realized && !it->item->queued)
2239 _item_realize(it, in, 0);
2242 if (it != expanded_next_it)
2244 it->item->old_scrl_y =
2245 expanded_next_it->item->old_scrl_y +
2246 expanded_next_it->item->h + dh;
2251 if ((it->item->old_scrl_y + y) < (cvy + cvh))
2252 _item_position(it, VIEW(it), it->item->scrl_x,
2253 it->item->old_scrl_y + y);
2256 _item_tree_effect(sd, y);
2260 int expanded_item_num = 0;
2263 if (sd->expanded_item)
2264 eo_it = elm_genlist_item_next_get(EO_OBJ(sd->expanded_item));
2269 expanded_item_num++;
2270 eo_it2 = elm_genlist_item_next_get(eo_it2);
2275 it = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
2277 if (sd->expanded_item->item->expanded_depth >=
2278 it->item->expanded_depth) break;
2279 if (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_EXPAND)
2281 if (!it->item->tree_effect_finished)
2283 if (t >= (((num - 1) * effect_duration) /
2287 edje_object_signal_emit(VIEW(it), "flip_item", "");
2288 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ITEM,
2290 _item_position(it, VIEW(it), it->item->scrl_x,
2292 it->item->tree_effect_finished = EINA_TRUE;
2296 eo_it = elm_genlist_item_next_get(eo_it);
2302 _item_tree_effect_finish(sd);
2303 return ECORE_CALLBACK_CANCEL;
2306 return ECORE_CALLBACK_RENEW;
2310 _group_items_recalc(void *data)
2314 Elm_Genlist_Data *sd = data;
2316 evas_event_freeze(evas_object_evas_get(sd->obj));
2317 EINA_LIST_FOREACH(sd->group_items, l, git)
2319 if (git->item->want_realize)
2321 if (!git->realized) _item_realize(git, 0, EINA_FALSE);
2322 evas_object_resize(VIEW(git), sd->minw, git->item->h);
2323 evas_object_move(VIEW(git), git->item->scrl_x, git->item->scrl_y);
2324 evas_object_stack_above(VIEW(git), sd->stack[1]);
2325 evas_object_show(VIEW(git));
2327 else if (!git->item->want_realize && git->realized)
2330 _elm_genlist_item_unrealize(git, EINA_FALSE);
2333 evas_event_thaw(evas_object_evas_get(sd->obj));
2334 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
2338 _reorder_move_animator_cb(void *data)
2341 Elm_Gen_Item *it = data;
2342 Eina_Bool down = EINA_FALSE;
2343 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
2344 int y, dy = it->item->h / 10 * elm_config_scale_get(), diff;
2346 t = ((0.0 > (t = ecore_loop_time_get()
2347 - sd->start_time)) ? 0.0 : t);
2349 if (t <= REORDER_EFFECT_TIME)
2350 y = (1 * sin((t / REORDER_EFFECT_TIME) * (M_PI / 2)) * dy);
2353 diff = abs(it->item->old_scrl_y - it->item->scrl_y);
2354 if (diff < dy) y = diff;
2355 else if (diff > it->item->h) y = diff / 2;
2357 if (it->item->old_scrl_y < it->item->scrl_y)
2359 it->item->old_scrl_y += y;
2362 else if (it->item->old_scrl_y > it->item->scrl_y)
2364 it->item->old_scrl_y -= y;
2368 if (it->deco_all_view)
2370 (it, it->deco_all_view, it->item->scrl_x, it->item->old_scrl_y);
2372 _item_position(it, VIEW(it), it->item->scrl_x, it->item->old_scrl_y);
2374 if ((sd->reorder_pan_move) ||
2375 (down && it->item->old_scrl_y >= it->item->scrl_y) ||
2376 (!down && it->item->old_scrl_y <= it->item->scrl_y))
2378 it->item->old_scrl_y = it->item->scrl_y;
2379 it->item->move_effect_enabled = EINA_FALSE;
2380 sd->reorder_move_animator = NULL;
2381 return ECORE_CALLBACK_CANCEL;
2384 return ECORE_CALLBACK_RENEW;
2388 _reorder_item_space_get(Elm_Gen_Item *it)
2390 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
2391 Elm_Gen_Item *reorder_it = sd->reorder_it;
2392 Evas_Coord rox, roy, row, roh, oy, oh;
2393 Eina_Bool top = EINA_FALSE;
2395 if (!reorder_it) return 0;
2397 evas_object_geometry_get(sd->pan_obj, NULL, &oy, NULL, &oh);
2398 evas_object_geometry_get
2399 (sd->VIEW(reorder_it), &rox, &roy, &row, &roh);
2401 if ((sd->reorder_start_y < it->item->block->y) &&
2402 (roy - oy + (roh / 2) >= it->item->block->y - sd->pan_y))
2404 it->item->block->reorder_offset =
2405 sd->reorder_it->item->h * -1;
2406 if (it->item->block->count == 1)
2407 sd->reorder_rel = it;
2409 else if ((sd->reorder_start_y >= it->item->block->y) &&
2410 (roy - oy + (roh / 2) <= it->item->block->y - sd->pan_y))
2412 it->item->block->reorder_offset = sd->reorder_it->item->h;
2415 it->item->block->reorder_offset = 0;
2417 it->item->scrl_y += it->item->block->reorder_offset;
2419 top = (ELM_RECTS_INTERSECT
2420 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2421 rox, roy + (roh / 2), row, 1));
2424 sd->reorder_rel = it;
2425 it->item->scrl_y += sd->reorder_it->item->h;
2426 return sd->reorder_it->item->h;
2433 _item_block_position(Item_Block *itb,
2438 Eina_Bool vis = EINA_FALSE;
2439 Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2440 Elm_Genlist_Data *sd = NULL;
2442 evas_event_freeze(evas_object_evas_get((itb->sd)->obj));
2443 evas_object_geometry_get(itb->sd->pan_obj, &ox, &oy, &ow, &oh);
2444 evas_output_viewport_get
2445 (evas_object_evas_get((itb->sd)->obj),
2446 &cvx, &cvy, &cvw, &cvh);
2448 EINA_LIST_FOREACH(itb->items, l, it)
2450 sd = GL_IT(it)->wsd;
2451 if (sd->reorder_it == it) continue;
2453 if (!it->filtered) _item_filtered_get(it);
2454 if (it->want_hidden)
2456 if (it->realized) evas_object_hide(VIEW(it));
2461 it->item->w = itb->w;
2462 it->item->scrl_x = itb->x + it->x - sd->pan_x + ox;
2463 it->item->scrl_y = itb->y + it->y - sd->pan_y + oy;
2465 vis = (ELM_RECTS_INTERSECT
2466 (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
2467 cvx, cvy, cvw, cvh));
2468 if (!(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP))
2470 if ((itb->realized) && (!it->realized))
2472 if (vis) _item_realize(it, in, EINA_FALSE);
2476 if (vis || it->dragging)
2478 if (sd->reorder_mode)
2479 y += _reorder_item_space_get(it);
2480 if ((sd->reorder_it) &&
2481 (it->item->old_scrl_y != it->item->scrl_y))
2483 if (!it->item->move_effect_enabled)
2485 it->item->move_effect_enabled = EINA_TRUE;
2486 sd->reorder_move_animator =
2488 _reorder_move_animator_cb, it);
2491 if (!it->item->move_effect_enabled)
2493 if ((sd->decorate_all_mode) &&
2494 (it->itc->decorate_all_item_style))
2495 _decorate_all_item_position
2496 (it, it->item->scrl_x, it->item->scrl_y);
2499 if (!sd->tree_effect_enabled ||
2500 (sd->move_effect_mode ==
2501 ELM_GENLIST_TREE_EFFECT_NONE) ||
2502 ((sd->move_effect_mode !=
2503 ELM_GENLIST_TREE_EFFECT_NONE) &&
2504 (it->item->old_scrl_y ==
2507 if (it->item->deco_it_view)
2509 (it, it->item->deco_it_view,
2514 (it, VIEW(it), it->item->scrl_x,
2518 it->item->old_scrl_y = it->item->scrl_y;
2523 if (!sd->tree_effect_animator)
2524 _elm_genlist_item_unrealize(it, EINA_FALSE);
2531 if (vis) it->item->want_realize = EINA_TRUE;
2535 evas_event_thaw(evas_object_evas_get((itb->sd)->obj));
2536 evas_event_thaw_eval(evas_object_evas_get((itb->sd)->obj));
2540 _item_block_realize(Item_Block *itb)
2542 if (itb->realized) return;
2544 itb->realized = EINA_TRUE;
2545 itb->want_unrealize = EINA_FALSE;
2549 _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
2551 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2552 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0;
2558 Elm_Genlist_Data *sd = psd->wsd;
2560 evas_event_freeze(evas_object_evas_get(obj));
2562 if (sd->pan_changed)
2564 ecore_job_del(sd->calc_job);
2565 sd->calc_job = NULL;
2567 sd->pan_changed = EINA_FALSE;
2570 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2571 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2573 if (sd->tree_effect_enabled &&
2574 (sd->move_effect_mode != ELM_GENLIST_TREE_EFFECT_NONE))
2576 if (!sd->tree_effect_animator)
2578 _item_tree_effect_before(sd->expanded_item);
2579 evas_object_raise(sd->event_block_rect);
2580 evas_object_stack_below(sd->event_block_rect, sd->stack[1]);
2581 evas_object_show(sd->event_block_rect);
2582 sd->start_time = ecore_time_get();
2583 sd->tree_effect_animator =
2584 ecore_animator_add(_tree_effect_animator_cb, sd->obj);
2588 EINA_INLIST_FOREACH(sd->blocks, itb)
2591 if (ELM_RECTS_INTERSECT(itb->x - sd->pan_x + ox,
2592 itb->y - sd->pan_y + oy,
2594 cvx, cvy, cvw, cvh))
2596 if ((!itb->realized) || (itb->changed))
2597 _item_block_realize(itb);
2598 _item_block_position(itb, in);
2602 if (itb->realized) _item_block_unrealize(itb);
2606 if ((!sd->reorder_it) || (sd->reorder_pan_move))
2607 _group_items_recalc(sd);
2608 if ((sd->reorder_mode) && (sd->reorder_it))
2610 if (sd->pan_y != sd->reorder_old_pan_y)
2611 sd->reorder_pan_move = EINA_TRUE;
2612 else sd->reorder_pan_move = EINA_FALSE;
2614 evas_object_raise(sd->VIEW(reorder_it));
2615 evas_object_stack_below(sd->VIEW(reorder_it), sd->stack[1]);
2616 sd->reorder_old_pan_y = sd->pan_y;
2617 sd->start_time = ecore_loop_time_get();
2620 if (!sd->tree_effect_enabled ||
2621 (sd->move_effect_mode == ELM_GENLIST_TREE_EFFECT_NONE))
2622 _item_auto_scroll(sd);
2624 //FIXME: There are issue about wrong list positioning in prepend cases.
2625 // To prevent the issue, allocate repositioning in smart calculate.
2626 if (sd->prepend_items)
2628 Evas_Coord prepend_h = 0;
2629 Elm_Gen_Item *tmp = NULL;
2630 EINA_LIST_FREE(sd->prepend_items, tmp)
2632 prepend_h += tmp->item->minh;
2636 elm_interface_scrollable_content_pos_get(&vx, &vy),
2637 elm_interface_scrollable_content_viewport_geometry_get
2638 (NULL, NULL, &vw, &vh));
2639 /* Set adjusted position as prepended items height */
2640 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(vx, vy + prepend_h, vw, vh));
2644 elm_interface_scrollable_content_pos_get(&vx, &vy),
2645 elm_interface_scrollable_content_viewport_geometry_get
2646 (NULL, NULL, &vw, &vh));
2648 if (sd->reorder_fast == 1)
2649 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(vx, vy - 10, vw, vh));
2650 else if (sd->reorder_fast == -1)
2651 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(vx, vy + 10, vw, vh));
2653 if (sd->focused_item && !sd->item_loop_enable)
2654 _elm_widget_focus_highlight_start(psd->wobj);
2656 EINA_LIST_FOREACH(sd->group_items, l, git)
2658 git->item->want_realize = EINA_FALSE;
2659 if (git->realized) evas_object_raise(VIEW(git));
2662 //update item before the render to prevent delayed update by job.
2665 ELM_SAFE_FREE(sd->update_job, ecore_job_del);
2666 _update_job(sd->obj);
2669 evas_event_thaw(evas_object_evas_get(obj));
2670 evas_event_thaw_eval(evas_object_evas_get(obj));
2672 eo_do(psd->wobj, eo_event_callback_call
2673 (ELM_INTERFACE_SCROLLABLE_EVENT_CHANGED, NULL));
2677 _elm_genlist_pan_eo_base_destructor(Eo *obj, Elm_Genlist_Pan_Data *psd)
2679 eo_data_unref(psd->wobj, psd->wsd);
2680 eo_do_super(obj, MY_PAN_CLASS, eo_destructor());
2684 _elm_genlist_pan_class_constructor(Eo_Class *klass)
2686 evas_smart_legacy_type_register(MY_PAN_CLASS_NAME_LEGACY, klass);
2689 #include "elm_genlist_pan.eo.c"
2692 _item_multi_select_up(Elm_Genlist_Data *sd)
2694 Elm_Object_Item *eo_prev;
2696 if (!sd->selected) return EINA_FALSE;
2697 if (!sd->multi) return EINA_FALSE;
2699 eo_prev = elm_genlist_item_prev_get(sd->last_selected_item);
2702 ELM_GENLIST_ITEM_DATA_GET(eo_prev, prev);
2703 if ((!_is_no_select(prev)) &&
2704 (!elm_object_item_disabled_get(eo_prev)) && (!prev->want_hidden))
2706 eo_prev = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev));
2708 if (!eo_prev) return EINA_TRUE;
2710 if (elm_genlist_item_selected_get(eo_prev))
2712 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2713 sd->last_selected_item = eo_prev;
2717 elm_genlist_item_selected_set(eo_prev, EINA_TRUE);
2723 _item_multi_select_down(Elm_Genlist_Data *sd)
2725 Elm_Object_Item *eo_next;
2727 if (!sd->selected) return EINA_FALSE;
2728 if (!sd->multi) return EINA_FALSE;
2730 eo_next = elm_genlist_item_next_get(sd->last_selected_item);
2733 ELM_GENLIST_ITEM_DATA_GET(eo_next, next);
2734 if ((!_is_no_select(next)) &&
2735 (!elm_object_item_disabled_get(eo_next)) && (!next->want_hidden))
2737 eo_next = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next));
2739 if (!eo_next) return EINA_TRUE;
2741 if (elm_genlist_item_selected_get(eo_next))
2743 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2744 sd->last_selected_item = eo_next;
2748 elm_genlist_item_selected_set(eo_next, EINA_TRUE);
2755 _all_items_deselect(Elm_Genlist_Data *sd)
2757 if (!sd->selected) return EINA_FALSE;
2759 sd->deselecting = eina_list_clone(sd->selected);
2760 while (sd->deselecting)
2762 Elm_Object_Item *it = eina_list_data_get(sd->deselecting);
2764 sd->deselecting = eina_list_remove_list(sd->deselecting, sd->deselecting);
2765 elm_genlist_item_selected_set(it, EINA_FALSE);
2772 _item_single_select_up(Elm_Genlist_Data *sd)
2774 Elm_Gen_Item *prev = NULL;
2777 prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2780 Elm_Object_Item *eo_prev = elm_genlist_item_prev_get
2781 (sd->last_selected_item);
2782 prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
2787 if ((!_is_no_select(prev)) &&
2788 (!elm_object_item_disabled_get(EO_OBJ(prev))) && (!prev->want_hidden))
2790 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2793 if (!prev) return EINA_FALSE;
2795 _all_items_deselect(sd);
2797 elm_genlist_item_selected_set(EO_OBJ(prev), EINA_TRUE);
2802 _item_single_select_down(Elm_Genlist_Data *sd)
2804 Elm_Gen_Item *next = NULL;
2805 Elm_Object_Item *eo_next = NULL;
2808 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2811 eo_next = elm_genlist_item_next_get(sd->last_selected_item);
2812 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2817 if ((!_is_no_select(next)) &&
2818 (!elm_object_item_disabled_get(EO_OBJ(next))) && (!next->want_hidden))
2820 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2823 if (!next) return EINA_FALSE;
2825 _all_items_deselect(sd);
2827 elm_genlist_item_selected_set(EO_OBJ(next), EINA_TRUE);
2833 _elm_genlist_item_focused(Elm_Object_Item *eo_it)
2835 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
2836 Evas_Object *obj = WIDGET(it);
2837 ELM_GENLIST_DATA_GET(obj, sd);
2840 if (_is_no_select(it) ||
2841 (eo_it == sd->focused_item) ||
2842 (eo_do_ret(eo_it, tmp, elm_wdg_item_disabled_get())))
2845 //TIZEN_ONLY(20161209): Do not autoscroll if scroll to item is exist
2848 switch (_elm_config->focus_autoscroll_mode)
2850 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
2851 elm_genlist_item_show(eo_it,
2852 ELM_GENLIST_ITEM_SCROLLTO_IN);
2854 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
2855 elm_genlist_item_bring_in(eo_it,
2856 ELM_GENLIST_ITEM_SCROLLTO_IN);
2864 sd->focused_item = eo_it;
2867 _elm_genlist_item_focus_update(it);
2868 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_ITEM_FOCUSED, eo_it));
2869 if (_elm_config->atspi_mode)
2870 elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_FOCUSED, EINA_TRUE);
2874 _elm_genlist_item_unfocused(Elm_Object_Item *eo_it)
2878 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
2879 Evas_Object *obj = WIDGET(it);
2880 ELM_GENLIST_DATA_GET(obj, sd);
2882 if (_is_no_select(it))
2885 if ((!sd->focused_item) ||
2886 (eo_it != sd->focused_item))
2889 if (elm_widget_focus_highlight_enabled_get(obj) || _elm_config->win_auto_focus_enable)
2891 ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focus_it);
2892 edje_object_signal_emit(VIEW(focus_it), SIGNAL_UNFOCUSED, "elm");
2895 sd->focused_item = NULL;
2896 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_ITEM_UNFOCUSED, eo_it));
2897 if (_elm_config->atspi_mode)
2898 elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_FOCUSED, EINA_FALSE);
2902 _item_focused_next(Evas_Object *obj, Elm_Focus_Direction dir)
2904 ELM_GENLIST_DATA_GET(obj, sd);
2906 Elm_Object_Item *eo_next;
2907 Elm_Object_Item *eo_first_item;
2908 Elm_Object_Item *eo_last_item;
2911 if (!sd->focused_item)
2913 if (dir == ELM_FOCUS_UP)
2914 next = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2915 else if (dir == ELM_FOCUS_DOWN)
2916 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2921 ((eo_do_ret(EO_OBJ(next), tmp, elm_wdg_item_disabled_get())) ||
2922 (_is_no_select(next))))
2923 if (!next->want_hidden) next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2927 ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focus_it);
2928 if (dir == ELM_FOCUS_UP)
2930 eo_first_item = elm_genlist_first_item_get(WIDGET(focus_it));
2931 if (eo_first_item == sd->focused_item) return EINA_FALSE;
2932 eo_next = elm_genlist_item_prev_get(sd->focused_item);
2933 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2936 ((eo_do_ret(eo_next, tmp, elm_wdg_item_disabled_get())) ||
2937 (_is_no_select(next))))
2939 eo_next = elm_genlist_item_prev_get(eo_next);
2940 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2943 else if (dir == ELM_FOCUS_DOWN)
2945 eo_last_item = elm_genlist_last_item_get(WIDGET(focus_it));
2946 if (eo_last_item == sd->focused_item) return EINA_FALSE;
2947 eo_next = elm_genlist_item_next_get(sd->focused_item);
2948 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2951 ((eo_do_ret(eo_next, tmp, elm_wdg_item_disabled_get())) ||
2952 (_is_no_select(next))))
2954 eo_next = elm_genlist_item_next_get(eo_next);
2955 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2961 if (!next) return EINA_FALSE;
2964 elm_object_item_focus_set(EO_OBJ(next), EINA_TRUE);
2970 _elm_genlist_item_content_focus_set(Elm_Gen_Item *it, Elm_Focus_Direction dir)
2972 Evas_Object *focused_obj = NULL;
2976 if (!GL_IT(it)->wsd->focus_on_selection_enabled) return;
2978 if (!it->item_focus_chain)
2980 elm_object_focus_set(VIEW(it), EINA_TRUE);
2984 EINA_LIST_FOREACH(it->item_focus_chain, l, focused_obj)
2985 if (elm_object_focus_get(focused_obj)) break;
2987 if (focused_obj && (dir != ELM_FOCUS_PREVIOUS))
2989 Evas_Object *nextfocus;
2990 Elm_Object_Item *nextfocus_item;
2991 if (elm_widget_focus_next_get(focused_obj, dir, &nextfocus, &nextfocus_item))
2994 elm_object_item_focus_set(nextfocus_item, EINA_TRUE);
2996 elm_object_focus_set(nextfocus, EINA_TRUE);
3001 if (!l) l = it->item_focus_chain;
3003 if (dir == ELM_FOCUS_RIGHT)
3005 l = eina_list_next(l);
3006 if (!l) l = it->item_focus_chain;
3008 else if (dir == ELM_FOCUS_LEFT)
3010 l = eina_list_prev(l);
3011 if (!l) l = eina_list_last(it->item_focus_chain);
3014 elm_object_focus_set(eina_list_data_get(l), EINA_TRUE);
3018 _key_action_move_dir(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool multi)
3020 ELM_GENLIST_DATA_GET(obj, sd);
3021 Elm_Object_Item *it = NULL;
3022 Eina_Bool ret = EINA_FALSE;
3025 Eina_Bool focus_only = EINA_FALSE;
3027 // get content size and viewport size
3029 elm_interface_scrollable_content_viewport_geometry_get
3030 (NULL, NULL, NULL, &v),
3031 elm_interface_scrollable_content_size_get(NULL, &min));
3033 if (_elm_config->item_select_on_focus_disable)
3035 ret = _item_focused_next(obj, dir);
3041 if (dir == ELM_FOCUS_UP)
3042 ret = _item_multi_select_up(sd);
3043 else if (dir == ELM_FOCUS_DOWN)
3044 ret = _item_multi_select_down(sd);
3048 if (dir == ELM_FOCUS_UP)
3049 ret = _item_single_select_up(sd);
3050 else if (dir == ELM_FOCUS_DOWN)
3051 ret = _item_single_select_down(sd);
3057 focus_only = _elm_config->item_select_on_focus_disable;
3058 // handle item loop feature
3059 if (sd->item_loop_enable && !sd->item_looping_on)
3063 if (dir == ELM_FOCUS_UP)
3065 elm_layout_signal_emit(obj, "elm,action,looping,up", "elm");
3066 sd->item_looping_on = EINA_TRUE;
3068 else if (dir == ELM_FOCUS_DOWN)
3070 elm_layout_signal_emit(obj, "elm,action,looping,down", "elm");
3071 sd->item_looping_on = EINA_TRUE;
3076 if (dir == ELM_FOCUS_UP)
3077 it = elm_genlist_last_item_get(obj);
3078 else if (dir == ELM_FOCUS_DOWN)
3079 it = elm_genlist_first_item_get(obj);
3081 if (it && focus_only)
3082 elm_object_item_focus_set(it, EINA_TRUE);
3084 elm_genlist_item_selected_set(it, EINA_TRUE);
3088 else if (sd->item_looping_on)
3095 _key_action_move(Evas_Object *obj, const char *params)
3097 ELM_GENLIST_DATA_GET(obj, sd);
3098 const char *dir = params;
3104 Evas_Coord step_x = 0;
3105 Evas_Coord step_y = 0;
3106 Evas_Coord page_x = 0;
3107 Evas_Coord page_y = 0;
3108 Elm_Object_Item *it = NULL;
3109 Evas_Coord pan_max_x = 0, pan_max_y = 0;
3112 elm_interface_scrollable_content_pos_get(&x, &y),
3113 elm_interface_scrollable_step_size_get(&step_x, &step_y),
3114 elm_interface_scrollable_page_size_get(&page_x, &page_y),
3115 elm_interface_scrollable_content_viewport_geometry_get
3116 (NULL, NULL, &v_w, &v_h));
3118 _elm_widget_focus_auto_show(obj);
3119 if (!strcmp(dir, "left"))
3123 Elm_Object_Item *eo_gt = NULL;
3124 if (_elm_config->item_select_on_focus_disable)
3125 eo_gt = elm_object_focused_item_get(obj);
3127 eo_gt = elm_genlist_selected_item_get(obj);
3128 ELM_GENLIST_ITEM_DATA_GET(eo_gt, gt);
3129 _elm_genlist_item_content_focus_set(gt, ELM_FOCUS_LEFT);
3133 else if (!strcmp(dir, "right"))
3137 Elm_Object_Item *eo_gt = NULL;
3138 if (_elm_config->item_select_on_focus_disable)
3139 eo_gt = elm_object_focused_item_get(obj);
3141 eo_gt = elm_genlist_selected_item_get(obj);
3142 ELM_GENLIST_ITEM_DATA_GET(eo_gt, gt);
3143 _elm_genlist_item_content_focus_set(gt, ELM_FOCUS_RIGHT);
3147 else if (!strcmp(dir, "up"))
3149 if (_key_action_move_dir(obj, ELM_FOCUS_UP, EINA_FALSE)) return EINA_TRUE;
3150 else return EINA_FALSE;
3152 else if (!strcmp(dir, "up_multi"))
3154 if (_key_action_move_dir(obj, ELM_FOCUS_UP, EINA_TRUE)) return EINA_TRUE;
3155 else if (_key_action_move_dir(obj, ELM_FOCUS_UP, EINA_FALSE)) return EINA_TRUE;
3156 else return EINA_FALSE;
3158 else if (!strcmp(dir, "down"))
3160 if (_key_action_move_dir(obj, ELM_FOCUS_DOWN, EINA_FALSE)) return EINA_TRUE;
3161 else return EINA_FALSE;
3163 else if (!strcmp(dir, "down_multi"))
3165 if (_key_action_move_dir(obj, ELM_FOCUS_DOWN, EINA_TRUE)) return EINA_TRUE;
3166 else if (_key_action_move_dir(obj, ELM_FOCUS_DOWN, EINA_FALSE)) return EINA_TRUE;
3167 else return EINA_FALSE;
3169 else if (!strcmp(dir, "first"))
3171 it = elm_genlist_first_item_get(obj);
3174 if (_elm_config->item_select_on_focus_disable)
3176 elm_object_item_focus_set(it, EINA_TRUE);
3177 elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
3181 elm_genlist_item_selected_set(it, EINA_TRUE);
3186 else if (!strcmp(dir, "last"))
3188 it = elm_genlist_last_item_get(obj);
3191 if (_elm_config->item_select_on_focus_disable)
3193 elm_object_item_focus_set(it, EINA_TRUE);
3194 elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_BOTTOM);
3198 elm_genlist_item_selected_set(it, EINA_TRUE);
3203 else if (!strcmp(dir, "prior"))
3206 y -= -(page_y * v_h) / 100;
3210 else if (!strcmp(dir, "next"))
3213 y += -(page_y * v_h) / 100;
3217 else return EINA_FALSE;
3219 eo_do(sd->pan_obj, elm_obj_pan_pos_max_get(&pan_max_x, &pan_max_y));
3221 if (x > pan_max_x) x = pan_max_x;
3223 if (y > pan_max_y) y = pan_max_y;
3225 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
3231 _key_action_select(Evas_Object *obj, const char *params)
3233 Elm_Object_Item *eo_it = NULL;
3235 eo_it = elm_object_focused_item_get(obj);
3236 if (!eo_it) return EINA_TRUE;
3237 elm_genlist_item_expanded_set(eo_it, !elm_genlist_item_expanded_get(eo_it));
3238 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
3239 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3242 ((sd->multi_select_mode != ELM_OBJECT_MULTI_SELECT_MODE_WITH_CONTROL) ||
3243 (!strcmp(params, "multi"))))
3247 _item_highlight(it);
3248 if (_item_select(it)) goto deleted;
3257 while (sd->selected)
3259 Elm_Object_Item *eo_sel = sd->selected->data;
3260 Elm_Gen_Item *sel = eo_data_scope_get(eo_sel, ELM_GENLIST_ITEM_CLASS);
3261 _item_unselect(sel);
3266 const Eina_List *l, *l_next;
3267 Elm_Object_Item *eo_it2;
3269 EINA_LIST_FOREACH_SAFE(sd->selected, l, l_next, eo_it2)
3271 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
3273 _item_unselect(it2);
3276 _item_highlight(it);
3277 if (_item_select(it)) goto deleted;
3280 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_ACTIVATED, EO_OBJ(it)));
3289 _key_action_escape(Evas_Object *obj, const char *params EINA_UNUSED)
3291 ELM_GENLIST_DATA_GET(obj, sd);
3293 if (!_all_items_deselect(sd)) return EINA_FALSE;
3297 EOLIAN static Eina_Bool
3298 _elm_genlist_elm_widget_event(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *src, Evas_Callback_Type type, void *event_info)
3301 Evas_Event_Key_Down *ev = event_info;
3303 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3304 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
3305 if (!sd->items) return EINA_FALSE;
3307 if (!_elm_config_key_binding_call(obj, ev, key_actions))
3310 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3314 /* This function disables the specific code of the layout sub object add.
3315 * Only the widget sub_object_add is called.
3317 EOLIAN static Eina_Bool
3318 _elm_genlist_elm_layout_sub_object_add_enable(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3323 EOLIAN static Eina_Bool
3324 _elm_genlist_elm_widget_sub_object_add(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED, Evas_Object *sobj)
3326 Eina_Bool int_ret = EINA_FALSE;
3328 /* skipping layout's code, which registers size hint changing
3329 * callback on sub objects. this is here because items'
3330 * content_get() routines may change hints on the objects after
3331 * creation, thus issuing TOO MANY sizing_eval()'s here. they are
3332 * not needed at here anyway, so let's skip listening to those
3334 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_add(sobj));
3335 if (!int_ret) return EINA_FALSE;
3340 EOLIAN static Eina_Bool
3341 _elm_genlist_elm_widget_sub_object_del(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *sobj)
3343 Eina_Bool int_ret = EINA_FALSE;
3346 /* XXX: hack -- also skipping sizing recalculation on
3347 * sub-object-del. genlist's crazy code paths (like groups and
3348 * such) seem to issue a whole lot of deletions and Evas bitches
3349 * about too many recalculations */
3350 sd->on_sub_del = EINA_TRUE;
3352 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_del(sobj));
3353 if (!int_ret) return EINA_FALSE;
3355 sd->on_sub_del = EINA_FALSE;
3361 * This function searches the nearest visible item based on the given item.
3362 * If the given item is in the genlist viewport, this returns the given item.
3363 * Or this searches the realized items and checks the nearest fully visible item
3364 * according to the given item's position.
3366 static Elm_Object_Item *
3367 _elm_genlist_nearest_visible_item_get(Evas_Object *obj, Elm_Object_Item *eo_it)
3369 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0; // genlist viewport geometry
3370 Evas_Coord ix = 0, iy = 0, iw = 0, ih = 0; // given item geometry
3371 Evas_Coord cx = 0, cy = 0, cw = 0, ch = 0; // candidate item geometry
3372 Eina_List *item_list = NULL, *l = NULL;
3373 Elm_Object_Item *eo_item = NULL;
3374 ELM_GENLIST_DATA_GET(obj, sd);
3375 Eina_Bool search_next = EINA_FALSE;
3377 if (!eo_it) return NULL;
3378 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
3380 evas_object_geometry_get(sd->pan_obj, &vx, &vy, &vw, &vh);
3381 evas_object_geometry_get(VIEW(it), &ix, &iy, &iw, &ih); // FIXME: check if the item is realized or not
3383 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, ix, iy, iw, ih))
3385 if (!elm_object_item_disabled_get(eo_it))
3388 search_next = EINA_TRUE;
3391 item_list = elm_genlist_realized_items_get(obj);
3393 if ((iy < vy) || search_next)
3395 EINA_LIST_FOREACH(item_list, l, eo_item)
3397 ELM_GENLIST_ITEM_DATA_GET(eo_item, item);
3398 evas_object_geometry_get(VIEW(item), &cx, &cy, &cw, &ch);
3399 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, cx, cy, cw, ch) &&
3400 !elm_object_item_disabled_get(eo_item))
3402 eina_list_free(item_list);
3409 EINA_LIST_REVERSE_FOREACH(item_list, l, eo_item)
3411 ELM_GENLIST_ITEM_DATA_GET(eo_item, item);
3412 evas_object_geometry_get(VIEW(item), &cx, &cy, &cw, &ch);
3413 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, cx, cy, cw, ch) &&
3414 !elm_object_item_disabled_get(eo_item))
3416 eina_list_free(item_list);
3421 eina_list_free(item_list);
3426 EOLIAN static Eina_Bool
3427 _elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd, Elm_Object_Item *item EINA_UNUSED)
3429 Eina_Bool int_ret = EINA_FALSE;
3430 Elm_Object_Item *eo_it = NULL;
3431 Eina_Bool is_sel = EINA_FALSE;
3433 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_on_focus(NULL));
3434 if (!int_ret) return EINA_FALSE;
3436 if (elm_widget_focus_get(obj) && (sd->items) && (sd->selected) &&
3437 (!sd->last_selected_item))
3439 sd->last_selected_item = eina_list_data_get(sd->selected);
3442 if (elm_widget_focus_get(obj) && !sd->mouse_down)
3444 if (sd->last_focused_item)
3445 eo_it = sd->last_focused_item;
3446 else if (sd->last_selected_item)
3447 eo_it = sd->last_selected_item;
3448 else if (_elm_config->first_item_focus_on_first_focus_in)
3450 eo_it = elm_genlist_first_item_get(obj);
3456 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
3457 if ((!_is_no_select(it)) && (!elm_object_item_disabled_get(eo_it)))
3459 eo_it = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next));
3464 eo_it = _elm_genlist_nearest_visible_item_get(obj, eo_it);
3467 if (!_elm_config->item_select_on_focus_disable && is_sel)
3468 elm_genlist_item_selected_set(eo_it, EINA_TRUE);
3470 elm_object_item_focus_set(eo_it, EINA_TRUE);
3471 _elm_widget_focus_highlight_start(obj);
3477 if (sd->focused_item)
3479 sd->last_focused_item = sd->focused_item;
3480 _elm_genlist_item_unfocused(sd->focused_item);
3487 static Eina_Bool _elm_genlist_smart_focus_next_enable = EINA_FALSE;
3489 EOLIAN static Eina_Bool
3490 _elm_genlist_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3492 return _elm_genlist_smart_focus_next_enable;
3495 EOLIAN static Eina_Bool
3496 _elm_genlist_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3501 EOLIAN static Eina_Bool
3502 _elm_genlist_elm_widget_focus_next(Eo *obj, Elm_Genlist_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
3504 Evas_Coord x, y, w, h;
3505 Evas_Coord sx, sy, sw, sh;
3507 Eina_List *items = NULL;
3508 Eina_Bool done = EINA_FALSE;
3510 evas_object_geometry_get(sd->obj, &sx, &sy, &sw, &sh);
3512 EINA_INLIST_FOREACH(sd->blocks, itb)
3520 EINA_LIST_FOREACH(itb->items, l, it)
3524 evas_object_geometry_get(it->base->view, &x, &y, &w, &h);
3526 /* check item which displays more than half of its size */
3527 if (it->base->access_obj &&
3529 (x + (w / 2), y + (h / 2), 0, 0, sx, sy, sw, sh))
3530 items = eina_list_append(items, it->base->access_obj);
3532 if (!it->base->access_order) continue;
3536 EINA_LIST_FOREACH(it->base->access_order, subl, subo)
3537 items = eina_list_append(items, subo);
3541 else if (done) break;
3544 return elm_widget_focus_list_next_get
3545 (obj, items, eina_list_data_get, dir, next, next_item);
3549 _mirrored_set(Evas_Object *obj,
3552 ELM_GENLIST_DATA_GET(obj, sd);
3554 _item_cache_zero(sd);
3555 eo_do(obj, elm_interface_scrollable_mirrored_set(rtl));
3558 EOLIAN static Elm_Theme_Apply
3559 _elm_genlist_elm_widget_theme_apply(Eo *obj, Elm_Genlist_Data *sd)
3562 Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
3566 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
3567 if (!int_ret) return ELM_THEME_APPLY_FAILED;
3569 evas_event_freeze(evas_object_evas_get(obj));
3570 _item_cache_zero(sd);
3571 _mirrored_set(obj, elm_widget_mirrored_get(obj));
3573 eina_hash_free_buckets(sd->size_caches);
3574 sd->minw = sd->minh = sd->realminw = 0;
3576 EINA_INLIST_FOREACH(sd->blocks, itb)
3578 if (itb->realized) _item_block_unrealize(itb);
3579 EINA_LIST_FOREACH(itb->items, l, it)
3580 it->item->mincalcd = EINA_FALSE;
3582 itb->changed = EINA_TRUE;
3584 ecore_job_del(sd->calc_job);
3585 sd->calc_job = ecore_job_add(_calc_job, obj);
3586 elm_layout_sizing_eval(obj);
3587 evas_event_thaw(evas_object_evas_get(obj));
3588 evas_event_thaw_eval(evas_object_evas_get(obj));
3593 /* FIXME: take off later. maybe this show region coords belong in the
3594 * interface (new api functions, set/get)? */
3596 _show_region_hook(void *data EINA_UNUSED,
3599 Evas_Coord x, y, w, h;
3601 ELM_GENLIST_DATA_GET_OR_RETURN(obj, sd);
3603 elm_widget_show_region_get(obj, &x, &y, &w, &h);
3604 //x & y are screen coordinates, Add with pan coordinates
3607 eo_do(obj, elm_interface_scrollable_content_region_show(x, y, w, h));
3610 //Tizen Only(20170113)
3611 EOLIAN static Eina_Bool
3612 _elm_genlist_elm_widget_translate(Eo *obj, Elm_Genlist_Data *sd)
3616 // Before calling text_get, inform user first.
3617 evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
3619 // FIXME: We should change item's height if lang is changed??
3620 EINA_INLIST_FOREACH(sd->blocks, itb)
3624 EINA_LIST_FOREACH(itb->items, l, it)
3628 elm_genlist_item_fields_update(EO_OBJ(it),
3630 ELM_GENLIST_ITEM_FIELD_TEXT);
3640 _item_highlight(Elm_Gen_Item *it)
3643 const char *selectraise;
3644 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3646 if (_is_no_select(it) ||
3648 (it->highlighted) || eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()) ||
3649 (it->item->deco_it_view))
3652 edje_object_signal_emit(VIEW(it), SIGNAL_SELECTED, "elm");
3653 if (it->deco_all_view)
3654 edje_object_signal_emit(it->deco_all_view, SIGNAL_SELECTED, "elm");
3655 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_HIGHLIGHTED, EO_OBJ(it)));
3657 selectraise = edje_object_data_get(VIEW(it), "selectraise");
3658 if ((selectraise) && (!strcmp(selectraise, "on")))
3660 if (it->deco_all_view) evas_object_stack_below(it->deco_all_view, sd->stack[1]);
3661 else evas_object_stack_below(VIEW(it), sd->stack[1]);
3662 if ((it->item->group_item) && (it->item->group_item->realized))
3663 evas_object_stack_above(it->item->VIEW(group_item), sd->stack[1]);
3665 it->highlighted = EINA_TRUE;
3669 _item_unhighlight(Elm_Gen_Item *it)
3671 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3673 if (!it->highlighted) return;
3675 edje_object_signal_emit(VIEW(it), SIGNAL_UNSELECTED, "elm");
3676 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_UNHIGHLIGHTED, EO_OBJ(it)));
3677 if (it->deco_all_view)
3678 edje_object_signal_emit
3679 (it->deco_all_view, SIGNAL_UNSELECTED, "elm");
3681 if (!it->item->nostacking)
3683 if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
3685 if (it->deco_all_view) evas_object_stack_below(it->deco_all_view, sd->stack[0]);
3686 else evas_object_stack_below(VIEW(it), sd->stack[0]);
3690 if (it->deco_all_view) evas_object_stack_above(it->deco_all_view, sd->stack[0]);
3691 else evas_object_stack_above(VIEW(it), sd->stack[0]);
3694 it->highlighted = EINA_FALSE;
3698 _item_block_position_update(Eina_Inlist *list,
3703 EINA_INLIST_FOREACH(list, tmp)
3705 tmp->position = idx++;
3706 tmp->position_update = EINA_TRUE;
3711 _item_position_update(Eina_List *list,
3717 EINA_LIST_FOREACH(list, l, it)
3719 it->position = idx++;
3720 it->position_update = EINA_TRUE;
3725 _item_block_merge(Item_Block *left,
3731 EINA_LIST_FOREACH(right->items, l, it2)
3733 it2->item->block = left;
3735 left->changed = EINA_TRUE;
3737 left->items = eina_list_merge(left->items, right->items);
3741 _item_block_del(Elm_Gen_Item *it)
3744 Item_Block *itb = it->item->block;
3745 Eina_Bool block_changed = EINA_FALSE;
3746 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3748 itb->items = eina_list_remove(itb->items, it);
3750 itb->changed = EINA_TRUE;
3751 ecore_job_del(sd->calc_job);
3752 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
3757 il = EINA_INLIST_GET(itb);
3758 itbn = (Item_Block *)(il->next);
3760 it->parent->item->items =
3761 eina_list_remove(it->parent->item->items, EO_OBJ(it));
3764 _item_block_position_update(il->next, itb->position);
3765 sd->blocks = eina_inlist_remove(sd->blocks, il);
3768 if (itbn) itbn->changed = EINA_TRUE;
3772 if (itb->count < (sd->max_items_per_block / 2))
3777 il = EINA_INLIST_GET(itb);
3778 itbp = (Item_Block *)(il->prev);
3779 itbn = (Item_Block *)(il->next);
3781 /* merge block with previous */
3783 ((itbp->count + itb->count) <
3784 (sd->max_items_per_block +
3785 (sd->max_items_per_block / 2))))
3787 _item_block_merge(itbp, itb);
3788 _item_block_position_update
3789 (EINA_INLIST_GET(itb)->next, itb->position);
3790 sd->blocks = eina_inlist_remove
3791 (sd->blocks, EINA_INLIST_GET(itb));
3793 block_changed = EINA_TRUE;
3795 /* merge block with next */
3797 ((itbn->count + itb->count) <
3798 (sd->max_items_per_block +
3799 (sd->max_items_per_block / 2))))
3801 _item_block_merge(itb, itbn);
3802 _item_block_position_update
3803 (EINA_INLIST_GET(itbn)->next, itbn->position);
3805 eina_inlist_remove(sd->blocks, EINA_INLIST_GET(itbn));
3807 block_changed = EINA_TRUE;
3814 sd->pan_changed = EINA_TRUE;
3815 evas_object_smart_changed(sd->pan_obj);
3816 ecore_job_del(sd->calc_job);
3817 sd->calc_job = NULL;
3822 _decorate_all_item_unrealize(Elm_Gen_Item *it)
3824 if ((!it) || (!it->item->decorate_all_item_realized)) return;
3826 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
3827 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
3828 elm_widget_sub_object_add(WIDGET(it), VIEW(it));
3829 _elm_genlist_item_position_state_update(it);
3830 _elm_genlist_item_state_update(it);
3832 if (it->item->wsd->reorder_mode)
3834 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
3835 edje_object_signal_emit(it->deco_all_view, SIGNAL_REORDER_MODE_UNSET,
3839 _view_clear(it->deco_all_view, &(GL_IT(it)->deco_all_texts),
3840 &(GL_IT(it)->deco_all_contents));
3842 edje_object_signal_emit(VIEW(it), SIGNAL_DECORATE_DISABLED, "elm");
3844 edje_object_message_signal_process(it->deco_all_view);
3845 _item_mouse_callbacks_del(it, it->deco_all_view);
3846 _item_mouse_callbacks_add(it, VIEW(it));
3848 ELM_SAFE_FREE(it->deco_all_view, evas_object_del);
3850 it->item->decorate_all_item_realized = EINA_FALSE;
3854 _elm_genlist_item_del_not_serious(Elm_Gen_Item *it)
3856 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3857 Elm_Object_Item *eo_it = EO_OBJ(it);
3859 eo_do(eo_it, elm_wdg_item_pre_notify_del());
3863 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
3864 if (sd->deselecting)
3865 sd->deselecting = eina_list_remove(sd->deselecting, it);
3867 if (sd->last_focused_item == eo_it)
3868 sd->last_focused_item = NULL;
3869 if (sd->focused_item == eo_it)
3870 sd->focused_item = NULL;
3871 if (sd->last_selected_item == eo_it)
3872 sd->last_selected_item = NULL;
3874 if (it->itc->func.del)
3875 it->itc->func.del((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it));
3879 _elm_genlist_item_del_serious(Elm_Gen_Item *it)
3881 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3884 _elm_genlist_item_del_not_serious(it);
3886 //(it->walking == -1) means it's already removed from the list.
3887 if (it->walking != -1)
3888 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
3889 if (it->tooltip.del_cb)
3890 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
3891 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
3892 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
3893 sd->group_items = eina_list_remove(sd->group_items, it);
3895 ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
3896 ecore_job_del(sd->calc_job);
3897 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
3899 ELM_SAFE_FREE(it->item, free);
3903 _item_del(Elm_Gen_Item *it)
3905 Evas_Object *obj = WIDGET(it);
3906 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3908 evas_event_freeze(evas_object_evas_get(obj));
3910 if (it->item->rel_revs)
3913 EINA_LIST_FREE(it->item->rel_revs, tmp)
3915 if (tmp->item->queued && !(tmp->base)->on_deletion)
3917 tmp->item->queued = EINA_FALSE;
3918 sd->queue = eina_list_remove(sd->queue, tmp);
3919 _item_process(sd, tmp);
3920 _item_process_post(sd, tmp, EINA_TRUE);
3922 tmp->item->rel = NULL;
3927 it->item->rel->item->rel_revs =
3928 eina_list_remove(it->item->rel->item->rel_revs, it);
3930 elm_genlist_item_subitems_clear(EO_OBJ(it));
3931 if (sd->show_item == it) sd->show_item = NULL;
3932 if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
3933 if (it->item->decorate_all_item_realized) _decorate_all_item_unrealize(it);
3934 if (it->item->block) _item_block_del(it);
3935 if (it->item->queued)
3936 sd->queue = eina_list_remove(sd->queue, it);
3937 if (sd->anchor_item == it)
3939 sd->anchor_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
3940 if (!sd->anchor_item)
3942 ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
3944 if (sd->expanded_item == it)
3946 if (sd->tree_effect_animator)
3948 _item_tree_effect_finish(sd);
3949 ELM_SAFE_FREE(sd->tree_effect_animator, ecore_animator_del);
3951 sd->expanded_item = NULL;
3952 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
3954 if (sd->expanded_next_item == it) sd->expanded_next_item = NULL;
3955 if (sd->move_items) sd->move_items = eina_list_remove(sd->move_items, it);
3957 it->parent->item->items = eina_list_remove(it->parent->item->items, EO_OBJ(it));
3958 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
3959 _elm_genlist_item_del_serious(it);
3961 if (it->itc->refcount <= 1 && eina_hash_find(sd->size_caches, &(it->itc)))
3962 eina_hash_del_by_key(sd->size_caches, it->itc);
3963 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
3964 evas_event_thaw(evas_object_evas_get(obj));
3965 evas_event_thaw_eval(evas_object_evas_get(obj));
3966 if (!sd->queue) _item_scroll(sd);
3970 _item_unselect(Elm_Gen_Item *it)
3972 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
3974 _item_unhighlight(it); /* unhighlight the item first */
3975 if (!it->selected) return; /* then check whether the item is selected */
3977 if (GL_IT(it)->wsd->focus_on_selection_enabled)
3981 EINA_LIST_FOREACH(it->item_focus_chain, l, eobj)
3982 elm_object_focus_set(eobj, EINA_FALSE);
3985 it->selected = EINA_FALSE;
3986 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
3987 eo_do(WIDGET(it), eo_event_callback_call
3988 (EVAS_SELECTABLE_INTERFACE_EVENT_UNSELECTED, EO_OBJ(it)));
3989 if (_elm_config->atspi_mode)
3990 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_SELECTED, EINA_FALSE);
3994 _item_mouse_in_cb(void *data,
3995 Evas *evas EINA_UNUSED,
3996 Evas_Object *obj EINA_UNUSED,
3997 void *event_info EINA_UNUSED)
3999 Elm_Gen_Item *it = data;
4000 if (!elm_object_item_disabled_get(EO_OBJ(it)) &&
4001 (_elm_config->focus_move_policy == ELM_FOCUS_MOVE_POLICY_IN))
4002 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
4006 _item_mouse_move_cb(void *data,
4007 Evas *evas EINA_UNUSED,
4011 Elm_Gen_Item *it = data;
4012 Evas_Event_Mouse_Move *ev = event_info;
4013 Evas_Coord ox, oy, ow, oh, it_scrl_y, y_pos;
4014 Evas_Coord minw = 0, minh = 0, x, y, w, h, dx, dy, adx, ady;
4015 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4016 Elm_Object_Item *eo_it = EO_OBJ(it);
4018 evas_object_geometry_get(obj, &x, &y, &w, &h);
4019 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4023 sd->on_hold = EINA_TRUE;
4024 if ((!sd->wasselected) && (!it->flipped))
4028 else if (ELM_RECTS_POINT_OUT(x, y, w, h, ev->cur.canvas.x, ev->cur.canvas.y) &&
4031 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4032 if ((!sd->wasselected) && (!it->flipped))
4034 it->base->still_in = EINA_FALSE;
4037 if (sd->multi_touched)
4039 sd->cur_x = ev->cur.canvas.x;
4040 sd->cur_y = ev->cur.canvas.y;
4043 if ((it->dragging) && (it->down))
4045 if (sd->movements == SWIPE_MOVES)
4046 sd->swipe = EINA_TRUE;
4049 sd->history[sd->movements].x = ev->cur.canvas.x;
4050 sd->history[sd->movements].y = ev->cur.canvas.y;
4051 if (abs((sd->history[sd->movements].x -
4052 sd->history[0].x)) > 40)
4053 sd->swipe = EINA_TRUE;
4057 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4058 eo_do(WIDGET(it), eo_event_callback_call
4059 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG, eo_it));
4062 if ((!it->down) || (sd->longpressed))
4064 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4065 if ((sd->reorder_mode) && (sd->reorder_it))
4067 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
4069 if (ev->cur.canvas.y < (oy + (sd->reorder_it->item->h / 2)))
4070 sd->reorder_fast = 1;
4071 else if (ev->cur.canvas.y > (oy + oh - (sd->reorder_it->item->h / 2)))
4072 sd->reorder_fast = -1;
4073 else sd->reorder_fast = 0;
4075 it_scrl_y = ev->cur.canvas.y - sd->reorder_it->dy;
4077 if (!sd->reorder_start_y)
4078 sd->reorder_start_y = it->item->block->y + it->y;
4082 else if (it_scrl_y + sd->reorder_it->item->h > oy + oh)
4083 y_pos = oy + oh - sd->reorder_it->item->h;
4087 if (it->deco_all_view)
4088 _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
4090 _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
4092 ecore_job_del(sd->calc_job);
4093 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
4097 if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
4098 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
4100 evas_object_geometry_get(obj, &x, &y, &w, &h);
4101 x = ev->cur.canvas.x - x;
4102 y = ev->cur.canvas.y - y;
4105 if (adx < 0) adx = -dx;
4109 if (ady < 0) ady = -dy;
4114 // gah! annoying drag detection - leave this alone
4117 if (minw < h) minw = h;
4118 if (minh < h) minh = h;
4122 if (minw < w) minw = w;
4123 if (minh < w) minh = w;
4125 if (minw < 5) minw = 5;
4126 if (minh < 5) minh = 5;
4128 if ((adx > minw) || (ady > minh))
4130 it->dragging = EINA_TRUE;
4131 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4135 eo_do(WIDGET(it), eo_event_callback_call
4136 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_UP, eo_it));
4140 eo_do(WIDGET(it), eo_event_callback_call
4141 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_LEFT, eo_it));
4143 eo_do(WIDGET(it), eo_event_callback_call
4144 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_RIGHT, eo_it));
4150 eo_do(WIDGET(it), eo_event_callback_call
4151 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_DOWN, eo_it));
4155 eo_do(WIDGET(it), eo_event_callback_call
4156 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_LEFT, eo_it));
4158 eo_do(WIDGET(it), eo_event_callback_call
4159 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_START_RIGHT, eo_it));
4166 _long_press_cb(void *data)
4169 Elm_Gen_Item *it = data;
4170 Elm_Object_Item *eo_it_tmp;
4172 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4174 if (_is_no_select(it) ||
4175 eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()) || (it->dragging))
4178 sd->longpressed = EINA_TRUE;
4179 eo_do(WIDGET(it), eo_event_callback_call
4180 (EVAS_CLICKABLE_INTERFACE_EVENT_LONGPRESSED, EO_OBJ(it)));
4181 if ((sd->reorder_mode) && !(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP))
4183 sd->reorder_it = it;
4184 sd->reorder_start_y = 0;
4185 if (it->deco_all_view)
4186 evas_object_stack_below(it->deco_all_view, sd->stack[1]);
4188 evas_object_stack_below(VIEW(it), sd->stack[1]);
4190 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
4191 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
4192 (EINA_FALSE, EINA_FALSE));
4194 list = elm_genlist_realized_items_get
4196 EINA_LIST_FREE(list, eo_it_tmp)
4198 ELM_GENLIST_ITEM_DATA_GET(eo_it_tmp, it_tmp);
4199 if (it != it_tmp) _item_unselect(it_tmp);
4202 if (elm_genlist_item_expanded_get(EO_OBJ(it)))
4204 elm_genlist_item_expanded_set(EO_OBJ(it), EINA_FALSE);
4205 return ECORE_CALLBACK_RENEW;
4208 if (!sd->decorate_all_mode)
4210 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
4211 //TIZEN_ONLY(20160520): genlist: added atspi support for drag n drop
4212 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_ANIMATED, EINA_TRUE);
4218 it->long_timer = NULL;
4219 return ECORE_CALLBACK_CANCEL;
4223 _swipe_do(Elm_Gen_Item *it)
4227 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4229 if (_is_no_select(it) ||
4230 eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get())) return;
4232 sd->swipe = EINA_FALSE;
4233 for (i = 0; i < sd->movements; i++)
4235 sum += sd->history[i].x;
4236 if (abs(sd->history[0].y - sd->history[i].y) > 10)
4240 sum /= sd->movements;
4241 if (abs(sum - sd->history[0].x) <= 10) return;
4242 eo_do(WIDGET(it), eo_event_callback_call
4243 (ELM_GENLIST_EVENT_SWIPE, EO_OBJ(it)));
4247 _swipe_cancel(void *data)
4249 Elm_Gen_Item *it = data;
4250 if (!it) return ECORE_CALLBACK_CANCEL;
4251 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4253 sd->swipe = EINA_FALSE;
4256 return ECORE_CALLBACK_RENEW;
4260 _multi_cancel(void *data)
4262 ELM_GENLIST_DATA_GET(data, sd);
4264 if (!sd) return ECORE_CALLBACK_CANCEL;
4265 sd->multi_timeout = EINA_TRUE;
4267 return ECORE_CALLBACK_RENEW;
4271 _multi_touch_gesture_eval(Elm_Gen_Item *it)
4273 Evas_Coord minw = 0, minh = 0;
4274 Evas_Coord off_x, off_y, off_mx, off_my;
4275 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4276 Elm_Object_Item *eo_it = EO_OBJ(it);
4278 sd->multi_touched = EINA_FALSE;
4279 ELM_SAFE_FREE(sd->multi_timer, ecore_timer_del);
4280 if (sd->multi_timeout)
4282 sd->multi_timeout = EINA_FALSE;
4286 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
4287 off_x = abs(sd->cur_x - sd->prev_x);
4288 off_y = abs(sd->cur_y - sd->prev_y);
4289 off_mx = abs(sd->cur_mx - sd->prev_mx);
4290 off_my = abs(sd->cur_my - sd->prev_my);
4292 if (((off_x > minw) || (off_y > minh)) && ((off_mx > minw)
4293 || (off_my > minh)))
4295 if ((off_x + off_mx) > (off_y + off_my))
4297 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_RIGHT, eo_it));
4300 else if ((sd->cur_x < sd->prev_x) && (sd->cur_mx < sd->prev_mx))
4301 eo_do(WIDGET(it), eo_event_callback_call
4302 (ELM_GENLIST_EVENT_MULTI_SWIPE_LEFT, eo_it));
4303 else if (abs(sd->cur_x - sd->cur_mx) >
4304 abs(sd->prev_x - sd->prev_mx))
4305 eo_do(WIDGET(it), eo_event_callback_call
4306 (ELM_GENLIST_EVENT_MULTI_PINCH_OUT, eo_it));
4308 eo_do(WIDGET(it), eo_event_callback_call
4309 (ELM_GENLIST_EVENT_MULTI_PINCH_IN, eo_it));
4313 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_DOWN, eo_it));
4316 else if ((sd->cur_y < sd->prev_y) && (sd->cur_my < sd->prev_my))
4317 eo_do(WIDGET(it), eo_event_callback_call
4318 (ELM_GENLIST_EVENT_MULTI_SWIPE_UP, eo_it));
4319 else if (abs(sd->cur_y - sd->cur_my) >
4320 abs(sd->prev_y - sd->prev_my))
4321 eo_do(WIDGET(it), eo_event_callback_call
4322 (ELM_GENLIST_EVENT_MULTI_PINCH_OUT, eo_it));
4324 eo_do(WIDGET(it), eo_event_callback_call
4325 (ELM_GENLIST_EVENT_MULTI_PINCH_IN, eo_it));
4329 sd->multi_timeout = EINA_FALSE;
4333 _item_multi_down_cb(void *data,
4334 Evas *evas EINA_UNUSED,
4335 Evas_Object *obj EINA_UNUSED,
4338 Elm_Gen_Item *it = data;
4339 Evas_Event_Multi_Down *ev = event_info;
4340 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4342 if ((sd->multi_device != 0) || (sd->multi_touched)
4343 || (sd->multi_timeout))
4346 sd->multi_device = ev->device;
4347 sd->multi_down = EINA_TRUE;
4348 sd->multi_touched = EINA_TRUE;
4349 sd->prev_mx = ev->canvas.x;
4350 sd->prev_my = ev->canvas.y;
4351 if (!sd->wasselected) _item_unselect(it);
4352 sd->wasselected = EINA_FALSE;
4353 sd->longpressed = EINA_FALSE;
4354 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4357 it->dragging = EINA_FALSE;
4358 eo_do(WIDGET(it), eo_event_callback_call
4359 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_STOP, EO_OBJ(it)));
4361 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
4364 sd->swipe = EINA_FALSE;
4366 sd->on_hold = EINA_FALSE;
4371 _item_multi_up_cb(void *data,
4372 Evas *evas EINA_UNUSED,
4373 Evas_Object *obj EINA_UNUSED,
4376 Elm_Gen_Item *it = data;
4377 Evas_Event_Multi_Up *ev = event_info;
4378 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4380 if (sd->multi_device != ev->device) return;
4381 sd->multi_device = 0;
4382 sd->multi_down = EINA_FALSE;
4383 if (sd->mouse_down) return;
4384 _multi_touch_gesture_eval(data);
4388 _item_multi_move_cb(void *data,
4389 Evas *evas EINA_UNUSED,
4390 Evas_Object *obj EINA_UNUSED,
4393 Elm_Gen_Item *it = data;
4394 Evas_Event_Multi_Move *ev = event_info;
4395 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4397 if (sd->multi_device != ev->device) return;
4398 sd->cur_mx = ev->cur.canvas.x;
4399 sd->cur_my = ev->cur.canvas.y;
4403 _item_mouse_down_cb(void *data,
4404 Evas *evas EINA_UNUSED,
4409 Evas_Event_Mouse_Down *ev = event_info;
4410 Elm_Gen_Item *it = data;
4412 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4413 Elm_Object_Item *eo_it = EO_OBJ(it);
4415 if (ev->button == 3)
4417 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4418 it->dx = ev->canvas.x - x;
4419 it->dy = ev->canvas.y - y;
4422 if (ev->button != 1) return;
4423 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4425 sd->on_hold = EINA_TRUE;
4428 it->down = EINA_TRUE;
4429 it->dragging = EINA_FALSE;
4430 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4431 it->dx = ev->canvas.x - x;
4432 it->dy = ev->canvas.y - y;
4433 sd->mouse_down = EINA_TRUE;
4434 if (!sd->multi_touched)
4436 sd->prev_x = ev->canvas.x;
4437 sd->prev_y = ev->canvas.y;
4438 sd->multi_timeout = EINA_FALSE;
4439 ecore_timer_del(sd->multi_timer);
4440 sd->multi_timer = ecore_timer_add(MULTI_DOWN_TIME, _multi_cancel, sd->obj);
4442 sd->longpressed = EINA_FALSE;
4443 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = EINA_TRUE;
4444 else sd->on_hold = EINA_FALSE;
4445 if (sd->on_hold) return;
4446 sd->wasselected = it->selected;
4448 ecore_timer_del(it->item->swipe_timer);
4449 it->item->swipe_timer = ecore_timer_add(SWIPE_TIME, _swipe_cancel, it);
4450 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
4452 it->long_timer = ecore_timer_add
4453 (sd->longpress_timeout, _long_press_cb, it);
4455 it->long_timer = NULL;
4456 sd->swipe = EINA_FALSE;
4458 it->base->still_in = EINA_TRUE;
4460 if (_is_no_select(it) ||
4461 eo_do_ret((Eo *)eo_it, tmp, elm_wdg_item_disabled_get()))
4464 // and finally call the user callbacks.
4465 // NOTE: keep this code at the bottom, as the user can change the
4466 // list at this point (clear, delete, etc...)
4467 _item_highlight(it);
4468 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
4470 eo_do(WIDGET(it), eo_event_callback_call
4471 (EVAS_CLICKABLE_INTERFACE_EVENT_CLICKED_DOUBLE, eo_it));
4472 eo_do(WIDGET(it), eo_event_callback_call
4473 (ELM_GENLIST_EVENT_ACTIVATED, eo_it));
4475 eo_do(WIDGET(it), eo_event_callback_call
4476 (EVAS_CLICKABLE_INTERFACE_EVENT_PRESSED, eo_it));
4480 _item_block_new(Elm_Genlist_Data *sd,
4485 itb = calloc(1, sizeof(Item_Block));
4486 if (!itb) return NULL;
4490 sd->blocks = eina_inlist_prepend(sd->blocks, EINA_INLIST_GET(itb));
4491 _item_block_position_update(sd->blocks, 0);
4495 sd->blocks = eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4496 itb->position_update = EINA_TRUE;
4497 if (sd->blocks != EINA_INLIST_GET(itb))
4500 ((Item_Block *)(EINA_INLIST_GET(itb)->prev))->position + 1;
4514 * This function adds an item to a block's item list. This may or may not
4515 * rearrange existing blocks and create a new block.
4519 _item_block_add(Elm_Genlist_Data *sd,
4522 Item_Block *itb = NULL;
4524 // when a new item does not depend on another item
4530 itb = calloc(1, sizeof(Item_Block));
4531 if (!itb) return EINA_FALSE;
4533 if (!it->item->rel->item->block)
4536 eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4537 itb->items = eina_list_append(itb->items, it);
4538 itb->position_update = EINA_TRUE;
4539 it->position = eina_list_count(itb->items);
4540 it->position_update = EINA_TRUE;
4542 if (sd->blocks != EINA_INLIST_GET(itb))
4546 (EINA_INLIST_GET(itb)->prev))->position + 1;
4557 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4558 if (it->item->before)
4560 sd->blocks = eina_inlist_prepend_relative
4561 (sd->blocks, EINA_INLIST_GET(itb),
4562 EINA_INLIST_GET(it->item->rel->item->block));
4564 eina_list_prepend_relative_list(itb->items, it, tmp);
4566 /* Update index from where we prepended */
4567 _item_position_update
4568 (eina_list_prev(tmp), it->item->rel->position);
4569 _item_block_position_update
4570 (EINA_INLIST_GET(itb),
4571 it->item->rel->item->block->position);
4575 sd->blocks = eina_inlist_append_relative
4576 (sd->blocks, EINA_INLIST_GET(itb),
4577 EINA_INLIST_GET(it->item->rel->item->block));
4579 eina_list_append_relative_list(itb->items, it, tmp);
4581 /* Update block index from where we appended */
4582 _item_position_update
4583 (eina_list_next(tmp), it->item->rel->position + 1);
4584 _item_block_position_update
4585 (EINA_INLIST_GET(itb),
4586 it->item->rel->item->block->position + 1);
4592 // item move_before, prepend, insert_before, sorted_insert with before
4593 if (it->item->before)
4597 itb = (Item_Block *)(sd->blocks);
4598 if (itb->count >= sd->max_items_per_block)
4600 itb = _item_block_new(sd, EINA_TRUE);
4601 if (!itb) return EINA_FALSE;
4606 itb = _item_block_new(sd, EINA_TRUE);
4607 if (!itb) return EINA_FALSE;
4609 itb->items = eina_list_prepend(itb->items, it);
4611 _item_position_update(itb->items, 0);
4613 // item move_after, append, insert_after, sorted_insert without before
4618 itb = (Item_Block *)(sd->blocks->last);
4619 if (itb->count >= sd->max_items_per_block)
4621 itb = _item_block_new(sd, EINA_FALSE);
4622 if (!itb) return EINA_FALSE;
4627 itb = _item_block_new(sd, EINA_FALSE);
4628 if (!itb) return EINA_FALSE;
4630 itb->items = eina_list_append(itb->items, it);
4631 it->position = eina_list_count(itb->items);
4635 // when a new item depends on another item
4640 if (it->item->rel->item->queued)
4642 /* NOTE: for a strange reason eina_list and eina_inlist
4643 don't have the same property on sorted insertion
4644 order, so the queue is not always ordered like the
4645 item list. This lead to issue where we depend on an
4646 item that is not yet created. As a quick work around,
4647 we reschedule the calc of the item and stop reordering
4648 the list to prevent any nasty issue to show up here.
4650 sd->queue = eina_list_append(sd->queue, it);
4651 sd->requeued = EINA_TRUE;
4652 it->item->queued = EINA_TRUE;
4656 itb = it->item->rel->item->block;
4657 if (!itb) goto newblock;
4658 tmp = eina_list_data_find_list(itb->items, it->item->rel);
4659 if (it->item->before)
4661 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4662 _item_position_update
4663 (eina_list_prev(tmp), it->item->rel->position);
4667 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4668 _item_position_update
4669 (eina_list_next(tmp), it->item->rel->position + 1);
4674 itb->changed = EINA_TRUE;
4675 it->item->block = itb;
4676 ecore_job_del(itb->sd->calc_job);
4677 itb->sd->calc_job = ecore_job_add(_calc_job, itb->sd->obj);
4679 if (itb->count > itb->sd->max_items_per_block)
4684 Eina_Bool done = EINA_FALSE;
4686 newc = itb->count / 2;
4688 if (EINA_INLIST_GET(itb)->prev)
4690 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4692 if (itbp->count + newc < sd->max_items_per_block / 2)
4694 /* moving items to previous block */
4695 while ((itb->count > newc) && (itb->items))
4697 it2 = eina_list_data_get(itb->items);
4698 itb->items = eina_list_remove_list
4699 (itb->items, itb->items);
4702 itbp->items = eina_list_append(itbp->items, it2);
4703 it2->item->block = itbp;
4706 if (it2->realized) itbp->realized = EINA_TRUE;
4713 if (!done && EINA_INLIST_GET(itb)->next)
4715 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4717 if (itbn->count + newc < sd->max_items_per_block / 2)
4719 /* moving items to next block */
4720 while ((itb->count > newc) && (itb->items))
4724 l = eina_list_last(itb->items);
4725 it2 = eina_list_data_get(l);
4726 itb->items = eina_list_remove_list(itb->items, l);
4729 itbn->items = eina_list_prepend(itbn->items, it2);
4730 it2->item->block = itbn;
4733 if (it2->realized) itbn->realized = EINA_TRUE;
4742 /* moving items to new block */
4743 itb2 = calloc(1, sizeof(Item_Block));
4744 if (!itb2) return EINA_FALSE;
4747 eina_inlist_append_relative(sd->blocks, EINA_INLIST_GET(itb2),
4748 EINA_INLIST_GET(itb));
4749 itb2->changed = EINA_TRUE;
4750 while ((itb->count > newc) && (itb->items))
4754 l = eina_list_last(itb->items);
4756 itb->items = eina_list_remove_list(itb->items, l);
4759 itb2->items = eina_list_prepend(itb2->items, it2);
4760 it2->item->block = itb2;
4763 if (it2->realized) itb2->realized = EINA_TRUE;
4772 _item_process(Elm_Genlist_Data *sd,
4775 if (!_item_block_add(sd, it)) return EINA_FALSE;
4777 _item_block_realize(it->item->block);
4783 _item_process_post(Elm_Genlist_Data *sd,
4787 Eina_Bool show_me = EINA_FALSE;
4789 if (it->item->block->changed)
4791 show_me = _item_block_recalc
4792 (it->item->block, it->item->block->num, qadd);
4793 it->item->block->changed = 0;
4794 if (sd->pan_changed)
4796 evas_object_smart_changed(sd->pan_obj);
4797 ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
4800 if (show_me) it->item->block->show_me = EINA_TRUE;
4802 /* when prepending, move the scroller along with the first selected
4803 * item to create the illusion that we're watching the selected
4804 * item this prevents the selected item being scrolled off the
4807 if (sd->selected && it->item->before)
4809 //FIXME: There are issue about wrong list positioning in prepend cases.
4810 // To prevent the issue, allocate repositioning in smart calculate.
4813 Elm_Object_Item *eo_it2;
4815 eo_it2 = sd->selected->data;
4816 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
4817 if (!it2->item->block) return;
4819 eo_do(sd->obj, elm_interface_scrollable_content_pos_get(NULL, &y));
4820 evas_object_geometry_get(sd->pan_obj, NULL, NULL, NULL, &h);
4821 if ((it->y + it->item->block->y > y + h) ||
4822 (it->y + it->item->block->y + it->item->h < y))
4823 /* offscreen, just update */
4824 eo_do(sd->obj, elm_interface_scrollable_content_region_show
4825 (it2->x + it2->item->block->x, y,
4826 it2->item->block->w, h));
4828 eo_do(sd->obj, elm_interface_scrollable_content_region_show
4829 (it->x + it->item->block->x,
4830 y + it->item->h, it->item->block->w, h));
4832 sd->prepend_items = eina_list_append(sd->prepend_items, it);
4837 _queue_process(Elm_Genlist_Data *sd)
4842 t0 = ecore_time_get();
4843 for (n = 0; (sd->queue) && (n < 128); n++)
4847 it = eina_list_data_get(sd->queue);
4848 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
4849 it->item->queued = EINA_FALSE;
4850 if (!_item_process(sd, it)) continue;
4851 t = ecore_time_get();
4852 _item_process_post(sd, it, EINA_TRUE);
4853 /* same as eina_inlist_count > 1 */
4854 if (sd->blocks && sd->blocks->next)
4856 if ((t - t0) > (ecore_animator_frametime_get())) break;
4864 _idle_process(void *data,
4867 Elm_Genlist_Data *sd = data;
4869 if (_queue_process(sd) > 0) *wakeup = EINA_TRUE;
4872 return ECORE_CALLBACK_CANCEL;
4874 return ECORE_CALLBACK_RENEW;
4878 _item_idle_enterer(void *data)
4880 Eina_Bool wakeup = EINA_FALSE;
4881 ELM_GENLIST_DATA_GET(data, sd);
4882 Eina_Bool ok = _idle_process(sd, &wakeup);
4887 ecore_job_del(sd->calc_job);
4888 sd->calc_job = ecore_job_add(_calc_job, data);
4890 if (ok == ECORE_CALLBACK_CANCEL) sd->queue_idle_enterer = NULL;
4896 _requeue_idle_enterer(Elm_Genlist_Data *sd)
4898 ecore_idle_enterer_del(sd->queue_idle_enterer);
4899 sd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, sd->obj);
4903 _item_queue(Elm_Genlist_Data *sd,
4909 if (it->item->queued) return;
4910 it->item->queued = EINA_TRUE;
4911 if (cb && !sd->requeued)
4912 sd->queue = eina_list_sorted_insert(sd->queue, cb, it);
4914 sd->queue = eina_list_append(sd->queue, it);
4915 // FIXME: why does a freeze then thaw here cause some genlist
4916 // elm_genlist_item_append() to be much much slower?
4917 // evas_event_freeze(evas_object_evas_get(sd->obj));
4918 while ((sd->queue) && ((!sd->blocks) || (!sd->blocks->next)))
4920 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
4923 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
4924 while ((sd->queue) && (sd->blocks) &&
4925 ((sd->homogeneous) || it->itc->homogeneous) && (sd->mode == ELM_LIST_COMPRESS))
4927 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
4931 // evas_event_thaw(evas_object_evas_get(sd->obj));
4932 // evas_event_thaw_eval(evas_object_evas_get(sd->obj));
4933 evas_object_geometry_get(sd->obj, NULL, NULL, &w, NULL);
4934 if (w > 0) _requeue_idle_enterer(sd);
4938 /* If the application wants to know the relative item, use
4939 * elm_genlist_item_prev_get(it)*/
4941 _item_move_after(Elm_Gen_Item *it,
4942 Elm_Gen_Item *after)
4946 if (it == after) return;
4947 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4950 eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
4951 if (it->item->block) _item_block_del(it);
4953 sd->items = eina_inlist_append_relative
4954 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
4956 it->item->rel->item->rel_revs =
4957 eina_list_remove(it->item->rel->item->rel_revs, it);
4958 it->item->rel = after;
4959 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
4960 it->item->before = EINA_FALSE;
4961 if (after->item->group_item) it->item->group_item = after->item->group_item;
4962 _item_queue(sd, it, NULL);
4964 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_MOVED_AFTER, EO_OBJ(it)));
4968 _access_activate_cb(void *data EINA_UNUSED,
4969 Evas_Object *part_obj EINA_UNUSED,
4970 Elm_Object_Item *eo_it)
4972 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
4975 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
4982 _item_highlight(it);
4992 while (sd->selected)
4994 Elm_Object_Item *eo_sel = sd->selected->data;
4995 Elm_Gen_Item *sel = eo_data_scope_get(eo_sel, ELM_GENLIST_ITEM_CLASS);
4996 _item_unselect(sel);
5001 const Eina_List *l, *l_next;
5002 Elm_Object_Item *eo_it2;
5004 EINA_LIST_FOREACH_SAFE(sd->selected, l, l_next, eo_it2)
5006 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
5008 _item_unselect(it2);
5011 _item_highlight(it);
5016 /* If the application wants to know the relative item, use
5017 * elm_genlist_item_next_get(it)*/
5019 _item_move_before(Elm_Gen_Item *it,
5020 Elm_Gen_Item *before)
5023 if (!before) return;
5024 if (it == before) return;
5025 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5028 eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
5029 if (it->item->block) _item_block_del(it);
5030 sd->items = eina_inlist_prepend_relative
5031 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
5033 it->item->rel->item->rel_revs =
5034 eina_list_remove(it->item->rel->item->rel_revs, it);
5035 it->item->rel = before;
5036 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
5037 it->item->before = EINA_TRUE;
5038 if (before->item->group_item)
5039 it->item->group_item = before->item->group_item;
5040 _item_queue(sd, it, NULL);
5042 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_MOVED_BEFORE, EO_OBJ(it)));
5046 _item_mouse_up_cb(void *data,
5047 Evas *evas EINA_UNUSED,
5048 Evas_Object *obj EINA_UNUSED,
5052 Evas_Event_Mouse_Up *ev = event_info;
5053 Eina_Bool dragged = EINA_FALSE;
5054 Elm_Gen_Item *it = data;
5055 Evas_Coord x, y, dx, dy;
5057 if ((ev->button == 3) && (!it->dragging))
5059 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
5060 dx = it->dx - (ev->canvas.x - x);
5061 dy = it->dy - (ev->canvas.y - y);
5062 if (dx < 0) dx = -dx;
5063 if (dy < 0) dy = -dy;
5064 if ((dx < 5) && (dy < 5))
5065 eo_do(WIDGET(it), eo_event_callback_call
5066 (EVAS_CLICKABLE_INTERFACE_EVENT_CLICKED_RIGHT, EO_OBJ(it)));
5070 if (ev->button != 1) return;
5071 it->down = EINA_FALSE;
5072 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5074 sd->mouse_down = EINA_FALSE;
5075 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_RELEASED, EO_OBJ(it)));
5076 if (sd->multi_touched)
5078 if ((!sd->multi) && (!it->selected) && (it->highlighted))
5079 _item_unhighlight(it);
5080 if (sd->multi_down) return;
5081 _multi_touch_gesture_eval(it);
5084 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
5085 sd->on_hold = EINA_TRUE;
5086 else sd->on_hold = EINA_FALSE;
5087 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
5090 it->dragging = EINA_FALSE;
5091 eo_do(WIDGET(it), eo_event_callback_call
5092 (EVAS_DRAGGABLE_INTERFACE_EVENT_DRAG_STOP, EO_OBJ(it)));
5095 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
5096 if (sd->multi_timer)
5098 ELM_SAFE_FREE(sd->multi_timer, ecore_timer_del);
5099 sd->multi_timeout = EINA_FALSE;
5103 if (!sd->wasselected) _item_unselect(it);
5105 sd->longpressed = EINA_FALSE;
5106 sd->on_hold = EINA_FALSE;
5107 sd->wasselected = EINA_FALSE;
5110 if ((sd->reorder_mode) && (sd->reorder_it))
5112 Evas_Coord it_scrl_y = ev->canvas.y - sd->reorder_it->dy;
5113 sd->reorder_fast = 0;
5115 if (sd->reorder_rel &&
5116 (sd->reorder_it->parent == sd->reorder_rel->parent))
5118 if (it_scrl_y <= sd->reorder_rel->item->scrl_y)
5119 _item_move_before(sd->reorder_it, sd->reorder_rel);
5121 _item_move_after(sd->reorder_it, sd->reorder_rel);
5122 eo_do(WIDGET(it), eo_event_callback_call(ELM_GENLIST_EVENT_MOVED, EO_OBJ(it)));
5126 ecore_job_del(sd->calc_job);
5127 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
5129 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_DISABLED, "elm");
5130 //TIZEN_ONLY(20160520): genlist: added atspi support for drag n drop
5131 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_ANIMATED, EINA_FALSE);
5133 sd->reorder_it = sd->reorder_rel = NULL;
5134 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5135 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
5136 (sd->h_bounce, sd->v_bounce));
5138 if (sd->longpressed)
5140 if (!sd->wasselected) _item_unselect(it);
5141 sd->longpressed = EINA_FALSE;
5142 sd->wasselected = EINA_FALSE;
5147 if (it->want_unrealize)
5149 _elm_genlist_item_unrealize(it, EINA_FALSE);
5150 if (it->item->block->want_unrealize)
5151 _item_block_unrealize(it->item->block);
5155 if (_is_no_select(it) ||
5156 (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get())))
5159 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD || !it->base->still_in) return;
5161 evas_object_ref(sd->obj);
5163 if (sd->focused_item != EO_OBJ(it))
5164 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
5167 ((sd->multi_select_mode != ELM_OBJECT_MULTI_SELECT_MODE_WITH_CONTROL) ||
5168 (evas_key_modifier_is_set(ev->modifiers, "Control"))))
5172 _item_highlight(it);
5173 if (_item_select(it)) goto deleted;
5182 while (sd->selected)
5184 Elm_Object_Item *eo_sel = sd->selected->data;
5185 Elm_Gen_Item *sel = eo_data_scope_get(eo_sel, ELM_GENLIST_ITEM_CLASS);
5186 _item_unselect(sel);
5191 const Eina_List *l, *l_next;
5192 Elm_Object_Item *eo_it2;
5194 EINA_LIST_FOREACH_SAFE(sd->selected, l, l_next, eo_it2)
5196 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
5198 _item_unselect(it2);
5201 _item_highlight(it);
5202 if (_item_select(it)) goto deleted;
5206 evas_object_unref(sd->obj);
5210 _item_mouse_callbacks_add(Elm_Gen_Item *it,
5213 evas_object_event_callback_add
5214 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
5215 evas_object_event_callback_add
5216 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
5217 evas_object_event_callback_add
5218 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
5219 evas_object_event_callback_add
5220 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
5221 evas_object_event_callback_add
5222 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
5223 evas_object_event_callback_add
5224 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
5225 evas_object_event_callback_add
5226 (view, EVAS_CALLBACK_MOUSE_IN, _item_mouse_in_cb, it);
5230 _item_mouse_callbacks_del(Elm_Gen_Item *it,
5233 evas_object_event_callback_del_full
5234 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
5235 evas_object_event_callback_del_full
5236 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
5237 evas_object_event_callback_del_full
5238 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
5239 evas_object_event_callback_del_full
5240 (view, EVAS_CALLBACK_MULTI_DOWN, _item_multi_down_cb, it);
5241 evas_object_event_callback_del_full
5242 (view, EVAS_CALLBACK_MULTI_UP, _item_multi_up_cb, it);
5243 evas_object_event_callback_del_full
5244 (view, EVAS_CALLBACK_MULTI_MOVE, _item_multi_move_cb, it);
5245 evas_object_event_callback_del_full
5246 (view, EVAS_CALLBACK_MOUSE_IN, _item_mouse_in_cb, it);
5250 _scroll_hold_timer_cb(void *data)
5252 ELM_GENLIST_DATA_GET(data, sd);
5254 if (!data) return ECORE_CALLBACK_CANCEL;
5256 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5257 sd->scr_hold_timer = NULL;
5259 return ECORE_CALLBACK_CANCEL;
5263 _decorate_item_unrealize(Elm_Gen_Item *it)
5265 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5266 Evas_Object *obj = sd->obj;
5268 if (!it->item->deco_it_view) return;
5270 evas_event_freeze(evas_object_evas_get(obj));
5272 _view_clear(GL_IT(it)->deco_it_view, &(GL_IT(it)->deco_it_texts),
5273 &(GL_IT(it)->deco_it_contents));
5275 edje_object_part_unswallow(it->item->deco_it_view, VIEW(it));
5276 evas_object_smart_member_add(VIEW(it), sd->pan_obj);
5277 ELM_SAFE_FREE(it->item->deco_it_view, evas_object_del);
5279 if (sd->mode_item == it)
5280 sd->mode_item = NULL;
5281 evas_event_thaw(evas_object_evas_get(obj));
5282 evas_event_thaw_eval(evas_object_evas_get(obj));
5286 _decorate_item_finished_signal_cb(void *data,
5288 const char *emission EINA_UNUSED,
5289 const char *source EINA_UNUSED)
5291 Elm_Gen_Item *it = data;
5295 if (!it || !obj) return;
5296 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5298 te = evas_object_evas_get(obj);
5300 if ((!it->realized) || (!it->item->deco_it_view)) return;
5302 evas_event_freeze(te);
5303 it->item->nocache_once = EINA_FALSE;
5304 _decorate_item_unrealize(it);
5305 if (it->item->group_item)
5306 evas_object_stack_above(it->item->VIEW(group_item), sd->stack[1]);
5308 snprintf(buf, sizeof(buf), "elm,state,%s,passive,finished",
5309 sd->decorate_it_type);
5310 edje_object_signal_callback_del_full
5311 (obj, buf, "elm", _decorate_item_finished_signal_cb, it);
5312 evas_event_thaw(te);
5313 evas_event_thaw_eval(te);
5317 _item_unrealize(Elm_Gen_Item *it)
5320 Eina_List *cache = NULL;
5321 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5323 EINA_LIST_FREE(it->item->flip_contents, c)
5327 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
5328 _elm_access_widget_item_unregister(it->base);
5330 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
5331 if (_elm_config->atspi_mode)
5333 elm_interface_atspi_accessible_removed(EO_OBJ(it));
5334 elm_interface_atspi_accessible_children_changed_del_signal_emit(sd->obj, EO_OBJ(it));
5338 //TIZEN_ONLY(20180328): clean up elm color class feature
5339 if (it->base->color_classes)
5340 edje_object_color_class_clear(VIEW(it));
5343 // unswallow VIEW(it) first then manipulate VIEW(it)
5344 _decorate_item_unrealize(it);
5345 if (GL_IT(it)->wsd->decorate_all_mode) _decorate_all_item_unrealize(it);
5347 if (!_item_cache_add(it, _content_cache_add(it, &cache)))
5349 ELM_SAFE_FREE(VIEW(it), evas_object_del);
5350 ELM_SAFE_FREE(it->spacer, evas_object_del);
5351 EINA_LIST_FREE(cache, c)
5358 it->realized = EINA_FALSE;
5359 it->want_unrealize = EINA_FALSE;
5363 _item_block_recalc(Item_Block *itb,
5369 Evas_Coord minw = 0, minh = 0;
5370 Eina_Bool show_me = EINA_FALSE, changed = EINA_FALSE;
5372 Item_Size *size = NULL;
5375 EINA_LIST_FOREACH(itb->items, l, it)
5377 show_me |= it->item->show_me;
5379 if (!it->filtered) _item_filtered_get(it);
5380 if (it->want_hidden)
5382 if (it->realized) evas_object_hide(VIEW(it));
5387 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5388 if ((itb->sd->homogeneous || it->itc->homogeneous) &&
5389 ((!size) || it->itc != size->itc))
5390 size = eina_hash_find(itb->sd->size_caches, &(it->itc));
5391 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5392 if (qadd || ((itb->sd->homogeneous || it->itc->homogeneous) && !size))
5394 if (!it->item->mincalcd) changed = EINA_TRUE;
5399 _item_realize(it, in, EINA_TRUE);
5400 _elm_genlist_item_unrealize(it, EINA_TRUE);
5404 it->item->w = it->item->minw = size->minw;
5405 it->item->h = it->item->minh = size->minh;
5406 it->item->mincalcd = EINA_TRUE;
5412 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5413 if ((itb->sd->homogeneous || it->itc->homogeneous) && size &&
5414 (itb->sd->mode == ELM_LIST_COMPRESS))
5416 it->item->w = it->item->minw = size->minw;
5417 it->item->h = it->item->minh = size->minh;
5418 it->item->mincalcd = EINA_TRUE;
5422 _item_realize(it, in, EINA_TRUE);
5423 _elm_genlist_item_unrealize(it, EINA_TRUE);
5429 if (!it->item->mincalcd) changed = EINA_TRUE;
5430 _item_realize(it, in, EINA_FALSE);
5432 minh += it->item->minh;
5433 if (minw < it->item->minw) minw = it->item->minw;
5439 if (changed) itb->sd->pan_changed = changed;
5442 itb->changed = EINA_FALSE;
5443 itb->position_update = EINA_FALSE;
5449 _update_job(void *data)
5451 Eina_Bool position = EINA_FALSE, recalc = EINA_FALSE;
5452 ELM_GENLIST_DATA_GET(data, sd);
5457 sd->update_job = NULL;
5460 evas_event_freeze(evas_object_evas_get(sd->obj));
5461 EINA_INLIST_FOREACH(sd->blocks, itb)
5463 Evas_Coord itminw, itminh;
5470 _item_block_position(itb, num);
5474 recalc = EINA_FALSE;
5475 EINA_LIST_FOREACH(itb->items, l2, it)
5477 if (it->item->updateme)
5479 itminw = it->item->minw;
5480 itminh = it->item->minh;
5482 it->item->updateme = EINA_FALSE;
5485 _elm_genlist_item_unrealize(it, EINA_FALSE);
5486 _item_realize(it, num, EINA_FALSE);
5487 position = EINA_TRUE;
5491 _item_realize(it, num, EINA_TRUE);
5492 _elm_genlist_item_unrealize(it, EINA_TRUE);
5494 if ((it->item->minw != itminw) || (it->item->minh != itminh))
5499 itb->updateme = EINA_FALSE;
5502 position = EINA_TRUE;
5503 itb->changed = EINA_TRUE;
5504 _item_block_recalc(itb, num0, EINA_FALSE);
5505 _item_block_position(itb, num0);
5510 ecore_job_del(sd->calc_job);
5511 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
5513 evas_event_thaw(evas_object_evas_get(sd->obj));
5514 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
5518 _scroll_animate_start_cb(Evas_Object *obj,
5519 void *data EINA_UNUSED)
5521 eo_do(obj, eo_event_callback_call(EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL_ANIM_START, NULL));
5525 _scroll_animate_stop_cb(Evas_Object *obj,
5526 void *data EINA_UNUSED)
5528 eo_do(obj, eo_event_callback_call(EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL_ANIM_STOP, NULL));
5532 _scroll_drag_start_cb(Evas_Object *obj,
5533 void *data EINA_UNUSED)
5535 eo_do(obj, eo_event_callback_call(EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL_DRAG_START, NULL));
5539 _scroll_cb(Evas_Object *obj,
5540 void *data EINA_UNUSED)
5542 eo_do(obj, eo_event_callback_call(EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL, NULL));
5546 _scroll_drag_stop_cb(Evas_Object *obj,
5547 void *data EINA_UNUSED)
5549 eo_do(obj, eo_event_callback_call(EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL_DRAG_STOP, NULL));
5553 _edge_left_cb(Evas_Object *obj,
5554 void *data EINA_UNUSED)
5556 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_EDGE_LEFT, NULL));
5560 _edge_right_cb(Evas_Object *obj,
5561 void *data EINA_UNUSED)
5563 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_EDGE_RIGHT, NULL));
5567 _edge_top_cb(Evas_Object *obj,
5568 void *data EINA_UNUSED)
5570 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_EDGE_TOP, NULL));
5574 _edge_bottom_cb(Evas_Object *obj,
5575 void *data EINA_UNUSED)
5577 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_EDGE_BOTTOM, NULL));
5581 _vbar_drag_cb(Evas_Object *obj,
5582 void *data EINA_UNUSED)
5584 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_VBAR_DRAG, NULL));
5588 _vbar_press_cb(Evas_Object *obj,
5589 void *data EINA_UNUSED)
5591 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_VBAR_PRESS, NULL));
5595 _vbar_unpress_cb(Evas_Object *obj,
5596 void *data EINA_UNUSED)
5598 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_VBAR_UNPRESS, NULL));
5602 _hbar_drag_cb(Evas_Object *obj,
5603 void *data EINA_UNUSED)
5605 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_HBAR_DRAG, NULL));
5609 _hbar_press_cb(Evas_Object *obj,
5610 void *data EINA_UNUSED)
5612 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_HBAR_PRESS, NULL));
5616 _hbar_unpress_cb(Evas_Object *obj,
5617 void *data EINA_UNUSED)
5619 eo_do(obj, eo_event_callback_call(ELM_GENLIST_EVENT_HBAR_UNPRESS, NULL));
5623 _decorate_item_realize(Elm_Gen_Item *it)
5625 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5626 Evas_Object *obj = sd->obj;
5629 if (GL_IT(it)->deco_it_view) return;
5631 evas_event_freeze(evas_object_evas_get(obj));
5632 it->item->deco_it_view = _view_create(it, it->itc->decorate_item_style);
5634 /* signal callback add */
5635 evas_object_event_callback_add
5636 (GL_IT(it)->deco_it_view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb,
5638 evas_object_event_callback_add
5639 (GL_IT(it)->deco_it_view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
5640 evas_object_event_callback_add
5641 (GL_IT(it)->deco_it_view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb,
5644 _view_inflate(it->item->deco_it_view, it, &GL_IT(it)->deco_it_texts,
5645 &GL_IT(it)->deco_it_contents);
5646 edje_object_part_swallow
5647 (it->item->deco_it_view,
5648 edje_object_data_get(it->item->deco_it_view, "mode_part"), VIEW(it));
5650 snprintf(buf, sizeof(buf), "elm,state,%s,active", sd->decorate_it_type);
5651 edje_object_signal_emit(GL_IT(it)->deco_it_view, buf, "elm");
5652 edje_object_signal_emit(VIEW(it), buf, "elm");
5654 it->want_unrealize = EINA_FALSE;
5655 evas_event_thaw(evas_object_evas_get(obj));
5656 evas_event_thaw_eval(evas_object_evas_get(obj));
5660 _decorate_item_set(Elm_Gen_Item *it)
5664 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5667 it->item->nocache_once = EINA_TRUE;
5669 ELM_SAFE_FREE(sd->scr_hold_timer, ecore_timer_del);
5670 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
5671 sd->scr_hold_timer = ecore_timer_add(SCR_HOLD_TIME, _scroll_hold_timer_cb, sd->obj);
5673 evas_event_freeze(evas_object_evas_get(sd->obj));
5674 _decorate_item_realize(it);
5675 if (it->item->group_item)
5676 evas_object_stack_above(it->item->VIEW(group_item), sd->stack[1]);
5678 (it, it->item->deco_it_view, it->item->scrl_x, it->item->scrl_y);
5679 evas_event_thaw(evas_object_evas_get(sd->obj));
5680 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
5685 _decorate_item_unset(Elm_Genlist_Data *sd)
5687 char buf[1024], buf2[1024];
5690 if (!sd->mode_item) return;
5693 it->item->nocache_once = EINA_TRUE;
5695 snprintf(buf, sizeof(buf), "elm,state,%s,passive", sd->decorate_it_type);
5696 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished",
5697 sd->decorate_it_type);
5698 edje_object_signal_emit(it->item->deco_it_view, buf, "elm");
5699 edje_object_signal_callback_add
5700 (it->item->deco_it_view, buf2, "elm", _decorate_item_finished_signal_cb,
5702 sd->mode_item = NULL;
5706 _elm_genlist_looping_up_cb(void *data,
5707 Evas_Object *obj EINA_UNUSED,
5708 const char *emission EINA_UNUSED,
5709 const char *source EINA_UNUSED)
5711 Evas_Object *genlist = data;
5713 ELM_GENLIST_DATA_GET(genlist, sd);
5715 Elm_Object_Item *eo_it = elm_genlist_last_item_get(genlist);
5717 // TIZEN_ONLY(20150629): add checking item bring in enable on item looping
5718 switch (_elm_config->focus_autoscroll_mode)
5720 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
5721 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
5723 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
5724 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
5730 elm_layout_signal_emit(genlist, "elm,action,looping,up,end", "elm");
5731 sd->item_looping_on = EINA_FALSE;
5733 if (!_elm_config->item_select_on_focus_disable)
5734 elm_genlist_item_selected_set(eo_it, EINA_TRUE);
5736 elm_object_item_focus_set(eo_it, EINA_TRUE);
5740 _elm_genlist_looping_down_cb(void *data,
5741 Evas_Object *obj EINA_UNUSED,
5742 const char *emission EINA_UNUSED,
5743 const char *source EINA_UNUSED)
5745 Evas_Object *genlist = data;
5747 ELM_GENLIST_DATA_GET(genlist, sd);
5749 Elm_Object_Item *eo_it = elm_genlist_first_item_get(genlist);
5751 // TIZEN_ONLY(20150629): add checking item bring in enable on item looping
5752 switch (_elm_config->focus_autoscroll_mode)
5754 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
5755 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
5757 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
5758 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
5764 elm_layout_signal_emit(genlist, "elm,action,looping,down,end", "elm");
5765 sd->item_looping_on = EINA_FALSE;
5767 if (!_elm_config->item_select_on_focus_disable)
5768 elm_genlist_item_selected_set(eo_it, EINA_TRUE);
5770 elm_object_item_focus_set(eo_it, EINA_TRUE);
5774 _evas_viewport_resize_cb(void *d, Evas *e EINA_UNUSED, void *ei EINA_UNUSED)
5776 Elm_Genlist_Data *priv = d;
5777 evas_object_smart_changed(priv->pan_obj);
5781 _elm_genlist_evas_object_smart_add(Eo *obj, Elm_Genlist_Data *priv)
5783 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5784 Elm_Genlist_Pan_Data *pan_data;
5785 Evas_Coord minw, minh;
5788 eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
5789 elm_widget_sub_object_parent_add(obj);
5791 priv->size_caches = eina_hash_pointer_new(_size_cache_free);
5792 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
5793 evas_object_smart_member_add(priv->hit_rect, obj);
5794 elm_widget_sub_object_add(obj, priv->hit_rect);
5796 /* common scroller hit rectangle setup */
5797 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
5798 evas_object_show(priv->hit_rect);
5799 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
5801 elm_widget_can_focus_set(obj, EINA_TRUE);
5802 elm_widget_on_show_region_hook_set(obj, _show_region_hook, NULL);
5804 if (!elm_layout_theme_set
5805 (obj, "genlist", "base", elm_widget_style_get(obj)))
5806 CRI("Failed to set layout!");
5808 eo_do(obj, elm_interface_scrollable_objects_set(wd->resize_obj, priv->hit_rect));
5810 eo_do(obj, elm_interface_scrollable_bounce_allow_set
5811 (EINA_FALSE, _elm_config->thumbscroll_bounce_enable));
5812 priv->v_bounce = _elm_config->thumbscroll_bounce_enable;
5815 elm_interface_scrollable_animate_start_cb_set(_scroll_animate_start_cb),
5816 elm_interface_scrollable_animate_stop_cb_set(_scroll_animate_stop_cb),
5817 elm_interface_scrollable_scroll_cb_set(_scroll_cb),
5818 elm_interface_scrollable_drag_start_cb_set(_scroll_drag_start_cb),
5819 elm_interface_scrollable_drag_stop_cb_set(_scroll_drag_stop_cb),
5820 elm_interface_scrollable_edge_left_cb_set(_edge_left_cb),
5821 elm_interface_scrollable_edge_right_cb_set(_edge_right_cb),
5822 elm_interface_scrollable_edge_top_cb_set(_edge_top_cb),
5823 elm_interface_scrollable_edge_bottom_cb_set(_edge_bottom_cb),
5824 elm_interface_scrollable_vbar_drag_cb_set(_vbar_drag_cb),
5825 elm_interface_scrollable_vbar_press_cb_set(_vbar_press_cb),
5826 elm_interface_scrollable_vbar_unpress_cb_set(_vbar_unpress_cb),
5827 elm_interface_scrollable_hbar_drag_cb_set(_hbar_drag_cb),
5828 elm_interface_scrollable_hbar_press_cb_set(_hbar_press_cb),
5829 elm_interface_scrollable_hbar_unpress_cb_set(_hbar_unpress_cb),
5830 elm_interface_scrollable_content_min_limit_cb_set(_content_min_limit_cb));
5832 priv->mode = ELM_LIST_SCROLL;
5833 priv->max_items_per_block = MAX_ITEMS_PER_BLOCK;
5834 priv->item_cache_max = priv->max_items_per_block * 2;
5835 priv->longpress_timeout = _elm_config->longpress_timeout;
5836 priv->highlight = EINA_TRUE;
5838 priv->pan_obj = eo_add(MY_PAN_CLASS, evas_object_evas_get(obj));
5839 pan_data = eo_data_scope_get(priv->pan_obj, MY_PAN_CLASS);
5840 eo_data_ref(obj, NULL);
5841 pan_data->wobj = obj;
5842 pan_data->wsd = priv;
5844 for (i = 0; i < 2; i++)
5846 priv->stack[i] = evas_object_rectangle_add(evas_object_evas_get(obj));
5847 evas_object_smart_member_add(priv->stack[i], priv->pan_obj);
5850 eo_do(obj, elm_interface_scrollable_extern_pan_set(priv->pan_obj));
5852 edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
5853 evas_object_size_hint_min_set(obj, minw, minh);
5855 _mirrored_set(obj, elm_widget_mirrored_get(obj));
5857 elm_layout_sizing_eval(obj);
5859 edje_object_signal_callback_add(wd->resize_obj, "elm,looping,up,done", "elm", _elm_genlist_looping_up_cb, obj);
5860 edje_object_signal_callback_add(wd->resize_obj, "elm,looping,down,done", "elm", _elm_genlist_looping_down_cb, obj);
5861 evas_event_callback_add(evas_object_evas_get(obj),
5862 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
5863 _evas_viewport_resize_cb, priv);
5867 _elm_genlist_evas_object_smart_del(Eo *obj, Elm_Genlist_Data *sd)
5871 elm_genlist_clear(obj);
5872 for (i = 0; i < 2; i++)
5873 ELM_SAFE_FREE(sd->stack[i], evas_object_del);
5875 evas_event_callback_del_full(evas_object_evas_get(obj),
5876 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
5877 _evas_viewport_resize_cb, sd);
5878 ELM_SAFE_FREE(sd->pan_obj, evas_object_del);
5880 _item_cache_zero(sd);
5881 ecore_job_del(sd->calc_job);
5882 ecore_job_del(sd->update_job);
5883 ecore_idle_enterer_del(sd->queue_idle_enterer);
5884 ecore_idler_del(sd->must_recalc_idler);
5885 ecore_timer_del(sd->multi_timer);
5886 eina_stringshare_del(sd->decorate_it_type);
5887 ecore_animator_del(sd->tree_effect_animator);
5889 eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
5893 _elm_genlist_evas_object_smart_move(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y)
5895 eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
5897 evas_object_move(sd->hit_rect, x, y);
5901 _elm_genlist_evas_object_smart_resize(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord w, Evas_Coord h)
5903 eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
5905 evas_object_resize(sd->hit_rect, w, h);
5906 if ((sd->queue) && (!sd->queue_idle_enterer) && (w > 0))
5907 _requeue_idle_enterer(sd);
5911 _elm_genlist_evas_object_smart_member_add(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *member)
5913 eo_do_super(obj, MY_CLASS, evas_obj_smart_member_add(member));
5916 evas_object_raise(sd->hit_rect);
5920 _access_obj_process(Elm_Genlist_Data *sd, Eina_Bool is_access)
5923 Eina_Bool done = EINA_FALSE;
5925 EINA_INLIST_FOREACH(sd->blocks, itb)
5933 EINA_LIST_FOREACH(itb->items, l, it)
5935 if (!it->realized || it->want_hidden) continue;
5936 if (is_access) _access_widget_item_register(it);
5938 _elm_access_widget_item_unregister(it->base);
5941 else if (done) break;
5946 _elm_genlist_elm_widget_access(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool acs)
5948 _elm_genlist_smart_focus_next_enable = acs;
5949 _access_obj_process(sd, _elm_genlist_smart_focus_next_enable);
5952 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
5953 //register/unregister access objects accordingly.
5954 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
5956 _elm_genlist_elm_widget_screen_reader(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool is_screen_reader)
5959 Eina_Bool done = EINA_FALSE;
5960 Evas_Object *content = NULL;
5964 EINA_INLIST_FOREACH(sd->blocks, itb)
5969 EINA_LIST_FOREACH(itb->items, l, it)
5971 if (!it->realized || it->want_hidden) continue;
5972 if (is_screen_reader)
5974 elm_interface_atspi_accessible_added(EO_OBJ(it));
5975 elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
5976 EINA_LIST_FOREACH(it->contents, ll, content)
5978 if (eo_isa(content, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
5980 eo_do(content, elm_interface_atspi_accessible_parent_set(EO_OBJ(it)));
5981 elm_interface_atspi_accessible_children_changed_added_signal_emit(EO_OBJ(it), content);
5984 elm_interface_atspi_accessible_name_changed_signal_emit(EO_OBJ(it));
5988 elm_interface_atspi_accessible_removed(EO_OBJ(it));
5989 elm_interface_atspi_accessible_children_changed_del_signal_emit(sd->obj, EO_OBJ(it));
5993 else if (done) break;
5995 //TIZEN_ONLY(20161213): apply screen_reader_changed callback
5996 evas_object_smart_callback_call(obj, SIG_ATSPI_SCREEN_READER_CHANGED, &is_screen_reader);
6003 elm_genlist_add(Evas_Object *parent)
6005 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
6006 Evas_Object *obj = eo_add(MY_CLASS, parent);
6011 _elm_genlist_eo_base_constructor(Eo *obj, Elm_Genlist_Data *sd)
6013 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
6017 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
6018 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
6019 elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST));
6025 _internal_elm_genlist_clear(Evas_Object *obj)
6027 ELM_GENLIST_DATA_GET(obj, sd);
6030 _elm_genlist_item_unfocused(sd->focused_item);
6031 if (sd->mode_item) sd->mode_item = NULL;
6033 ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
6035 sd->filter_data = NULL;
6036 if (sd->filter_queue)
6037 ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
6038 ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
6039 ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
6041 evas_event_freeze(evas_object_evas_get(sd->obj));
6043 // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
6044 // because sd->items can be modified inside elm_widget_item_del()
6047 it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
6048 eo_do(EO_OBJ(it), elm_wdg_item_del());
6051 sd->pan_changed = EINA_TRUE;
6054 ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
6055 sd->anchor_item = NULL;
6056 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
6057 ELM_SAFE_FREE(sd->must_recalc_idler, ecore_idler_del);
6058 ELM_SAFE_FREE(sd->reorder_move_animator, ecore_animator_del);
6059 sd->reorder_old_pan_y = 0;
6062 if (sd->selected) ELM_SAFE_FREE(sd->selected, eina_list_free);
6064 sd->show_item = NULL;
6073 evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
6074 eo_do(sd->pan_obj, eo_event_callback_call
6075 (ELM_PAN_EVENT_CHANGED, NULL));
6077 elm_layout_sizing_eval(sd->obj);
6078 eo_do(obj, elm_interface_scrollable_content_region_show(0, 0, 0, 0));
6080 ELM_SAFE_FREE(sd->multi_timer, ecore_timer_del);
6081 ELM_SAFE_FREE(sd->update_job, ecore_job_del);
6082 ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
6083 ELM_SAFE_FREE(sd->must_recalc_idler, ecore_idler_del);
6084 ELM_SAFE_FREE(sd->tree_effect_animator, ecore_animator_del);
6085 ELM_SAFE_FREE(sd->event_block_rect, evas_object_del);
6086 ELM_SAFE_FREE(sd->scr_hold_timer, ecore_timer_del);
6087 ELM_SAFE_FREE(sd->queue, eina_list_free);
6089 evas_event_thaw(evas_object_evas_get(sd->obj));
6090 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
6093 /* Return EINA_TRUE if the item is deleted in this function */
6095 _item_select(Elm_Gen_Item *it)
6098 Evas_Object *obj = WIDGET(it);
6099 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
6100 Elm_Object_Item *eo_it = EO_OBJ(it);
6102 if (eo_do_ret(eo_it, tmp, elm_wdg_item_disabled_get())) return EINA_FALSE;
6103 if (_is_no_select(it) || (it->decorate_it_set)) return EINA_FALSE;
6104 if ((sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) &&
6105 (it->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) && it->selected)
6110 const Eina_List *l, *ll;
6111 Elm_Object_Item *eo_it2;
6112 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it2)
6114 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6115 if (it2 != it) _item_unselect(it2);
6121 it->selected = EINA_TRUE;
6123 eina_list_append(sd->selected, eo_it);
6126 evas_object_ref(obj);
6129 elm_object_item_focus_set(eo_it, EINA_TRUE);
6130 if ((it->base)->on_deletion) goto item_deleted;
6131 _elm_genlist_item_content_focus_set(it, ELM_FOCUS_PREVIOUS);
6132 sd->last_selected_item = eo_it;
6133 _item_highlight(it);
6135 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), eo_it);
6136 // delete item if it's requested deletion in the above callbacks.
6137 if ((it->base)->on_deletion) goto item_deleted;
6138 eo_do(WIDGET(it), eo_event_callback_call(EVAS_SELECTABLE_INTERFACE_EVENT_SELECTED, eo_it));
6139 if (_elm_config->atspi_mode)
6140 elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_SELECTED, EINA_TRUE);
6141 // delete item if it's requested deletion in the above callbacks.
6142 if ((it->base)->on_deletion) goto item_deleted;
6145 if (!(sd->focus_on_selection_enabled || _elm_config->item_select_on_focus_disable))
6147 Evas_Object *swallow_obj;
6149 EINA_LIST_FOREACH(it->contents, l, swallow_obj)
6151 if (elm_widget_is(swallow_obj) && elm_object_focus_get(swallow_obj))
6153 elm_object_focus_set(obj, EINA_FALSE);
6154 elm_object_focus_set(obj, EINA_TRUE);
6160 evas_object_unref(obj);
6164 it->walking = -1; //This item was removed from it's item list.
6167 evas_object_unref(obj);
6171 EOLIAN static Evas_Object *
6172 _elm_genlist_item_elm_widget_item_part_content_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6174 Evas_Object *ret = NULL;
6175 if (it->deco_all_view)
6176 ret = edje_object_part_swallow_get(it->deco_all_view, part);
6177 else if (it->decorate_it_set)
6178 ret = edje_object_part_swallow_get(it->item->deco_it_view, part);
6182 ret = edje_object_part_swallow_get(VIEW(it), part);
6184 ret = edje_object_part_swallow_get(VIEW(it), "elm.swallow.icon");
6189 EOLIAN static const char *
6190 _elm_genlist_item_elm_widget_item_part_text_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6192 if (!it->itc->func.text_get) return NULL;
6193 const char *ret = NULL;
6194 if (it->deco_all_view)
6195 ret = edje_object_part_text_get(it->deco_all_view, part);
6196 else if (it->decorate_it_set)
6197 ret = edje_object_part_text_get(it->item->deco_it_view, part);
6201 ret = edje_object_part_text_get(VIEW(it), part);
6203 ret = edje_object_part_text_get(VIEW(it), "elm.text");
6209 _elm_genlist_item_elm_widget_item_disable(Eo *eo_it, Elm_Gen_Item *it)
6216 if (eo_it == GL_IT(it)->wsd->focused_item)
6217 _elm_genlist_item_unfocused(eo_it);
6218 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
6222 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()))
6224 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
6225 if (it->deco_all_view)
6226 edje_object_signal_emit
6227 (it->deco_all_view, SIGNAL_DISABLED, "elm");
6231 edje_object_signal_emit(VIEW(it), SIGNAL_ENABLED, "elm");
6232 if (it->deco_all_view)
6233 edje_object_signal_emit
6234 (it->deco_all_view, SIGNAL_ENABLED, "elm");
6236 EINA_LIST_FOREACH(it->contents, l, obj)
6237 elm_widget_disabled_set(obj, eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()));
6241 EOLIAN static Eina_Bool
6242 _elm_genlist_item_elm_widget_item_del_pre(Eo *eo_it EINA_UNUSED,
6245 /* This item is getting removed from a callback that triggered in the
6246 _item_select(). Just pend removing. Because this will be removed right
6247 after in the _item_select(). So pratically, this item won't be
6249 if (it->walking > 0)
6251 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
6252 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
6261 _elm_genlist_item_elm_widget_item_signal_emit(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char *emission, const char *source)
6265 WRN("Item is not realized yet");
6268 edje_object_signal_emit(VIEW(it), emission, source);
6269 if (it->deco_all_view)
6270 edje_object_signal_emit(it->deco_all_view, emission, source);
6274 _elm_genlist_item_elm_widget_item_focus_set(Eo *eo_it, Elm_Gen_Item *it, Eina_Bool focused)
6276 Evas_Object *obj = WIDGET(it);
6278 ELM_GENLIST_DATA_GET(obj, sd);
6282 sd->last_focused_item = eo_it;
6283 if (!elm_object_focus_get(obj))
6284 elm_object_focus_set(obj, EINA_TRUE);
6286 if (!elm_widget_focus_get(obj))
6289 fobj = elm_object_focused_object_get(obj);
6290 if (fobj && (fobj != obj))
6292 Evas_Object *content;
6294 EINA_LIST_FOREACH(it->contents, l, content)
6296 if (elm_object_focused_object_get(content))
6298 elm_object_focus_set(content, EINA_FALSE);
6304 if (eo_it != sd->focused_item)
6306 if (sd->focused_item)
6307 _elm_genlist_item_unfocused(sd->focused_item);
6308 _elm_genlist_item_focused(eo_it);
6310 /* If item is not realized state, widget couldn't get focus_highlight data. */
6313 _elm_widget_item_highlight_in_theme(obj, EO_OBJ(it));
6314 _elm_widget_highlight_in_theme_update(obj);
6315 _elm_widget_focus_highlight_start(obj);
6321 if (!elm_widget_focus_get(obj))
6323 _elm_genlist_item_unfocused(eo_it);
6327 EOLIAN static Eina_Bool
6328 _elm_genlist_item_elm_widget_item_focus_get(Eo *eo_it, Elm_Gen_Item *it)
6330 Evas_Object *obj = WIDGET(it);
6331 ELM_GENLIST_DATA_GET(obj, sd);
6333 if (eo_it == sd->focused_item)
6340 _elm_genlist_item_eo_base_constructor(Eo *eo_it, Elm_Gen_Item *it)
6342 eo_it = eo_do_super_ret(eo_it, ELM_GENLIST_ITEM_CLASS, eo_it, eo_constructor());
6344 it->base = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
6345 eo_do(eo_it, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST_ITEM));
6350 static Elm_Gen_Item *
6351 _elm_genlist_item_new(Elm_Genlist_Data *sd,
6352 const Elm_Genlist_Item_Class *itc,
6354 Elm_Object_Item *eo_parent,
6355 Elm_Genlist_Item_Type type,
6357 const void *func_data)
6362 if (!itc) return NULL;
6364 Eo *eo_it = eo_add(ELM_GENLIST_ITEM_CLASS, sd->obj);
6365 if (!eo_it) return NULL;
6366 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6369 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
6371 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6372 WIDGET_ITEM_DATA_SET(EO_OBJ(it), data);
6373 it->parent = parent;
6374 it->func.func = func;
6375 it->func.data = func_data;
6377 GL_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
6378 GL_IT(it)->wsd = sd;
6379 GL_IT(it)->type = type;
6383 if (GL_IT(it->parent)->type & ELM_GENLIST_ITEM_GROUP)
6384 GL_IT(it)->group_item = parent;
6385 else if (GL_IT(it->parent)->group_item)
6386 GL_IT(it)->group_item = GL_IT(it->parent)->group_item;
6388 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
6390 if (!(GL_IT(it2->parent)->type & ELM_GENLIST_ITEM_GROUP)) depth += 1;
6392 GL_IT(it)->expanded_depth = depth;
6399 _elm_genlist_item_compare(const void *data,
6402 const Elm_Gen_Item *it, *item1;
6404 it = ELM_GEN_ITEM_FROM_INLIST(data);
6405 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
6406 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6410 _elm_genlist_item_list_compare(const void *data,
6413 const Elm_Gen_Item *it = data;
6414 const Elm_Gen_Item *item1 = data1;
6416 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6420 _elm_genlist_eo_item_list_compare(const void *data,
6423 const Elm_Object_Item *eo_it = data;
6424 const Elm_Object_Item *eo_item1 = data1;
6425 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6427 return GL_IT(it)->wsd->item_compare_cb(eo_it, eo_item1);
6430 EOLIAN static unsigned int
6431 _elm_genlist_items_count(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6433 return sd->item_count;
6437 _list_last_recursive(Eina_List *list)
6439 Eina_List *ll, *ll2;
6440 Elm_Object_Item *eo_it2;
6442 ll = eina_list_last(list);
6443 if (!ll) return NULL;
6446 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6448 if (it2->item->items)
6450 ll2 = _list_last_recursive(it2->item->items);
6460 EOLIAN static Elm_Object_Item*
6461 _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)
6467 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6468 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6469 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6472 it = _elm_genlist_item_new
6473 (sd, itc, data, eo_parent, type, func, func_data);
6474 if (!it) return NULL;
6478 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
6479 sd->group_items = eina_list_append(sd->group_items, it);
6480 sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
6481 it->item->rel = NULL;
6485 Elm_Object_Item *eo_it2 = NULL;
6486 Eina_List *ll = _list_last_recursive(it->parent->item->items);
6488 if (ll) eo_it2 = ll->data;
6489 it->parent->item->items =
6490 eina_list_append(it->parent->item->items, EO_OBJ(it));
6491 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6492 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6493 sd->items = eina_inlist_append_relative
6494 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6495 it->item->rel = it2;
6496 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6498 it->item->before = EINA_FALSE;
6499 _item_queue(sd, it, NULL);
6504 EOLIAN static Elm_Object_Item*
6505 _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)
6511 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6512 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6513 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6514 /* first sub-item should allways be appended */
6515 if (!parent->item->items)
6516 return _elm_genlist_item_append(obj, sd, itc, data, eo_parent, type, func, func_data);
6519 it = _elm_genlist_item_new
6520 (sd, itc, data, eo_parent, type, func, func_data);
6521 if (!it) return NULL;
6525 if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)
6526 sd->group_items = eina_list_prepend(sd->group_items, it);
6527 sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
6528 it->item->rel = NULL;
6532 Elm_Object_Item *eo_it2 = NULL;
6533 Eina_List *ll = it->parent->item->items;
6535 if (ll) eo_it2 = ll->data;
6536 it->parent->item->items =
6537 eina_list_prepend(it->parent->item->items, EO_OBJ(it));
6538 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6539 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6540 sd->items = eina_inlist_prepend_relative
6541 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6542 it->item->rel = it2;
6543 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6545 it->item->before = EINA_TRUE;
6546 _item_queue(sd, it, NULL);
6551 EOLIAN static Elm_Object_Item*
6552 _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)
6554 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_after, NULL);
6555 ELM_GENLIST_ITEM_DATA_GET(eo_after, after);
6558 ELM_GENLIST_ITEM_CHECK_OR_RETURN(after, NULL);
6559 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(after)), NULL);
6562 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6563 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6564 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6567 /* It makes no sense to insert after in an empty list with after !=
6568 * NULL, something really bad is happening in your app. */
6569 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6571 it = _elm_genlist_item_new
6572 (sd, itc, data, eo_parent, type, func, func_data);
6573 if (!it) return NULL;
6577 if ((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) &&
6578 (GL_IT(after)->type & ELM_GENLIST_ITEM_GROUP))
6579 sd->group_items = eina_list_append_relative
6580 (sd->group_items, it, after);
6584 it->parent->item->items =
6585 eina_list_append_relative(it->parent->item->items, EO_OBJ(it), eo_after);
6587 sd->items = eina_inlist_append_relative
6588 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
6590 it->item->rel = after;
6591 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
6592 it->item->before = EINA_FALSE;
6593 _item_queue(sd, it, NULL);
6598 EOLIAN static Elm_Object_Item*
6599 _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)
6601 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_before, NULL);
6602 ELM_GENLIST_ITEM_DATA_GET(eo_before, before);
6605 ELM_GENLIST_ITEM_CHECK_OR_RETURN(before, NULL);
6606 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(before)), NULL);
6609 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6610 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6611 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6614 /* It makes no sense to insert before in an empty list with before
6615 * != NULL, something really bad is happening in your app. */
6616 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6618 it = _elm_genlist_item_new
6619 (sd, itc, data, eo_parent, type, func, func_data);
6620 if (!it) return NULL;
6624 if ((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) &&
6625 (GL_IT(before)->type & ELM_GENLIST_ITEM_GROUP))
6627 eina_list_prepend_relative(sd->group_items, it, before);
6631 it->parent->item->items =
6632 eina_list_prepend_relative(it->parent->item->items, EO_OBJ(it), eo_before);
6634 sd->items = eina_inlist_prepend_relative
6635 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
6637 it->item->rel = before;
6638 GL_IT(before)->rel_revs = eina_list_append(GL_IT(before)->rel_revs, it);
6639 it->item->before = EINA_TRUE;
6640 _item_queue(sd, it, NULL);
6645 EOLIAN static Elm_Object_Item*
6646 _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)
6648 Elm_Gen_Item *rel = NULL;
6653 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6654 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6655 EINA_SAFETY_ON_FALSE_RETURN_VAL((obj == WIDGET(parent)), NULL);
6658 it = _elm_genlist_item_new
6659 (sd, itc, data, eo_parent, type, func, func_data);
6660 if (!it) return NULL;
6661 Elm_Object_Item *eo_it = EO_OBJ(it);
6663 sd->item_compare_cb = comp;
6667 Elm_Object_Item *eo_rel = NULL;
6671 l = eina_list_search_sorted_near_list
6672 (it->parent->item->items, _elm_genlist_eo_item_list_compare, eo_it,
6677 eo_rel = eina_list_data_get(l);
6678 rel = eo_data_scope_get(eo_rel, ELM_GENLIST_ITEM_CLASS);
6680 if (cmp_result >= 0)
6682 it->parent->item->items = eina_list_prepend_relative_list
6683 (it->parent->item->items, eo_it, l);
6684 sd->items = eina_inlist_prepend_relative
6685 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6686 it->item->before = EINA_TRUE;
6688 else if (cmp_result < 0)
6690 it->parent->item->items = eina_list_append_relative_list
6691 (it->parent->item->items, eo_it, l);
6692 sd->items = eina_inlist_append_relative
6693 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6694 it->item->before = EINA_FALSE;
6701 // ignoring the comparison
6702 it->parent->item->items = eina_list_prepend_relative_list
6703 (it->parent->item->items, eo_it, l);
6704 sd->items = eina_inlist_prepend_relative
6705 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6706 it->item->before = EINA_FALSE;
6713 sd->state = eina_inlist_sorted_state_new();
6714 eina_inlist_sorted_state_init(sd->state, sd->items);
6715 sd->requeued = EINA_FALSE;
6718 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6719 sd->group_items = eina_list_append(sd->group_items, it);
6721 sd->items = eina_inlist_sorted_state_insert
6722 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
6725 if (EINA_INLIST_GET(it)->next)
6727 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6728 it->item->before = EINA_TRUE;
6730 else if (EINA_INLIST_GET(it)->prev)
6732 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6733 it->item->before = EINA_FALSE;
6739 GL_IT(it)->rel = rel;
6740 rel->item->rel_revs = eina_list_append(rel->item->rel_revs, it);
6743 _item_queue(sd, it, _elm_genlist_item_list_compare);
6749 _elm_genlist_clear(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED)
6751 _internal_elm_genlist_clear(obj);
6755 _elm_genlist_multi_select_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool multi)
6757 sd->multi = !!multi;
6759 if (!sd->multi && sd->selected)
6762 Elm_Object_Item *eo_it;
6763 Elm_Object_Item *last = sd->selected->data;
6764 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
6768 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6775 EOLIAN static Eina_Bool
6776 _elm_genlist_multi_select_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6782 _elm_genlist_multi_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Elm_Object_Multi_Select_Mode mode)
6784 if (mode >= ELM_OBJECT_MULTI_SELECT_MODE_MAX)
6787 if (sd->multi_select_mode != mode)
6788 sd->multi_select_mode = mode;
6791 EOLIAN static Elm_Object_Multi_Select_Mode
6792 _elm_genlist_multi_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6794 return sd->multi_select_mode;
6797 EOLIAN static Elm_Object_Item*
6798 _elm_genlist_selected_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6801 return sd->selected->data;
6806 EOLIAN static const Eina_List*
6807 _elm_genlist_selected_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6809 return sd->selected;
6812 EOLIAN static Eina_List*
6813 _elm_genlist_realized_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6816 Eina_Bool done = EINA_FALSE;
6818 Eina_List *ret = NULL;
6820 EINA_INLIST_FOREACH(sd->blocks, itb)
6828 EINA_LIST_FOREACH(itb->items, l, it)
6830 if (it->realized) ret = eina_list_append(ret, EO_OBJ(it));
6842 EOLIAN static Elm_Object_Item*
6843 _elm_genlist_at_xy_item_get(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y, int *posret)
6845 Evas_Coord ox, oy, ow, oh;
6849 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
6851 EINA_INLIST_FOREACH(sd->blocks, itb)
6856 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->sd->pan_x,
6857 oy + itb->y - itb->sd->pan_y,
6858 itb->w, itb->h, x, y, 1, 1))
6860 EINA_LIST_FOREACH(itb->items, l, it)
6862 Evas_Coord itx, ity;
6864 itx = ox + itb->x + it->x - itb->sd->pan_x;
6865 ity = oy + itb->y + it->y - itb->sd->pan_y;
6866 if (ELM_RECTS_INTERSECT
6867 (itx, ity, it->item->w, it->item->h, x, y, 1, 1))
6871 if (y <= (ity + (it->item->h / 4))) *posret = -1;
6872 else if (y >= (ity + it->item->h - (it->item->h / 4)))
6879 lasty = ity + it->item->h;
6884 if (y > lasty) *posret = 1;
6891 EOLIAN static Elm_Object_Item*
6892 _elm_genlist_first_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6894 return EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(sd->items));
6897 EOLIAN static Elm_Object_Item*
6898 _elm_genlist_last_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6902 if (!sd->items) return NULL;
6904 it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
6909 EOLIAN static Elm_Object_Item *
6910 _elm_genlist_item_next_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6914 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6918 if (it) return EO_OBJ(it);
6922 EOLIAN static Elm_Object_Item *
6923 _elm_genlist_item_prev_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6927 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6931 if (it) return EO_OBJ(it);
6935 EOLIAN static Elm_Object_Item *
6936 _elm_genlist_item_parent_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
6938 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
6940 return EO_OBJ(it->parent);
6943 EOLIAN static unsigned int
6944 _elm_genlist_item_subitems_count(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
6946 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, 0);
6948 return eina_list_count(item->item->items);
6951 EOLIAN static const Eina_List *
6952 _elm_genlist_item_subitems_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
6954 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
6956 return item->item->items;
6960 _elm_genlist_item_subitems_clear(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
6962 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6963 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
6965 if (!sd->tree_effect_enabled || !sd->move_effect_mode)
6966 _item_sub_items_clear(it);
6969 if (!sd->tree_effect_animator)
6971 sd->expanded_item = it;
6972 _item_tree_effect_before(it);
6973 evas_object_stack_below(sd->event_block_rect, sd->stack[1]);
6974 evas_object_show(sd->event_block_rect);
6975 sd->start_time = ecore_time_get();
6976 sd->tree_effect_animator =
6977 ecore_animator_add(_tree_effect_animator_cb, sd->obj);
6980 _item_sub_items_clear(it);
6985 _elm_genlist_item_selected_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
6989 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
6991 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get())) return;
6993 selected = !!selected;
6994 if (it->selected == selected) return;
6996 if (selected) _item_select(it);
6997 else _item_unselect(it);
7000 EOLIAN static Eina_Bool
7001 _elm_genlist_item_selected_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7003 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7005 return it->selected;
7008 static Elm_Gen_Item *
7009 _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
7011 Elm_Object_Item *eo_it = EO_OBJ(it);
7012 Elm_Object_Item *eo_it2;
7014 if (it->item->expanded)
7016 eo_it2 = elm_genlist_item_next_get(eo_it);
7017 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
7022 eo_it2 = elm_genlist_item_next_get(eo_it);
7025 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
7026 if (it->item->expanded_depth >= it2->item->expanded_depth) return it2;
7027 eo_it2 = elm_genlist_item_next_get(eo_it2);
7030 return eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
7034 _elm_genlist_move_items_set(Elm_Gen_Item *it)
7037 Elm_Gen_Item *it2 = NULL;
7038 Evas_Coord ox, oy, ow, oh, dh = 0;
7039 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7041 sd->expanded_next_item =
7042 _elm_genlist_expanded_next_item_get(it);
7044 if (it->item->expanded)
7046 Elm_Object_Item *eo_item;
7047 l = elm_genlist_realized_items_get((sd)->obj);
7048 EINA_LIST_FREE(l, eo_item)
7050 ELM_GENLIST_ITEM_DATA_GET(eo_item, item);
7051 sd->move_items = eina_list_append(sd->move_items, item);
7054 EINA_LIST_FOREACH_SAFE(sd->move_items, l, ll, it2)
7056 if (it2 == sd->expanded_next_item) break;
7057 sd->move_items = eina_list_remove(sd->move_items, it2);
7062 Elm_Object_Item *eo_it2 = NULL;
7063 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7064 if (sd->expanded_next_item) eo_it2 = EO_OBJ(sd->expanded_next_item);
7066 while (eo_it2 && (dh < oy + oh))
7068 it2 = eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
7070 sd->move_items = eina_list_append(sd->move_items, it2);
7071 eo_it2 = elm_genlist_item_next_get(eo_it2);
7077 _event_block_rect_update(const Evas_Object *obj)
7079 Evas_Coord ox, oy, ow, oh;
7081 ELM_GENLIST_CHECK(obj);
7082 ELM_GENLIST_DATA_GET(obj, sd);
7084 if (!sd->event_block_rect)
7086 sd->event_block_rect = evas_object_rectangle_add(
7087 evas_object_evas_get(sd->obj));
7088 evas_object_smart_member_add(sd->event_block_rect, sd->pan_obj);
7091 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7092 evas_object_color_set(sd->event_block_rect, 0, 0, 0, 0);
7093 evas_object_resize(sd->event_block_rect, ow, oh);
7094 evas_object_move(sd->event_block_rect, ox, oy);
7098 _elm_genlist_item_expanded_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool expanded)
7100 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7101 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7103 expanded = !!expanded;
7104 if (it->item->expanded == expanded) return;
7105 if (it->item->type != ELM_GENLIST_ITEM_TREE) return;
7106 it->item->expanded = expanded;
7107 sd->expanded_item = it;
7108 _elm_genlist_move_items_set(it);
7110 if (sd->tree_effect_enabled)
7111 _event_block_rect_update(WIDGET(it));
7113 if (it->item->expanded)
7115 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
7117 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
7118 eo_do(WIDGET(it), eo_event_callback_call
7119 (ELM_GENLIST_EVENT_EXPANDED, EO_OBJ(it)));
7120 sd->auto_scroll_enabled = EINA_TRUE;
7121 if (_elm_config->atspi_mode)
7122 elm_interface_atspi_accessible_state_changed_signal_emit(eo_item, ELM_ATSPI_STATE_EXPANDED, EINA_TRUE);
7126 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
7128 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACTED, "elm");
7129 eo_do(WIDGET(it), eo_event_callback_call
7130 (ELM_GENLIST_EVENT_CONTRACTED, EO_OBJ(it)));
7131 sd->auto_scroll_enabled = EINA_FALSE;
7132 if (_elm_config->atspi_mode)
7133 elm_interface_atspi_accessible_state_changed_signal_emit(eo_item, ELM_ATSPI_STATE_EXPANDED, EINA_FALSE);
7137 EOLIAN static Eina_Bool
7138 _elm_genlist_item_expanded_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7140 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7142 return GL_IT(it)->expanded;
7146 _elm_genlist_item_expanded_depth_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7148 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, 0);
7150 return GL_IT(it)->expanded_depth;
7154 _elm_genlist_item_coordinates_calc(Elm_Gen_Item *it,
7155 Elm_Genlist_Item_Scrollto_Type type,
7162 Evas_Coord gith = 0;
7163 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7165 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
7166 if ((sd->queue) || (it->item->block->w < 1) ||
7167 (!((sd->homogeneous || it->itc->homogeneous) &&
7168 (sd->mode == ELM_LIST_COMPRESS))))
7170 if ((it->item->queued) || (!it->item->mincalcd) ||
7171 (sd->queue) || (it->item->block->w < 1))
7173 sd->check_scroll = EINA_TRUE;
7175 sd->bring_in = bring_in;
7176 sd->scroll_to_type = type;
7177 it->item->show_me = EINA_TRUE;
7179 ecore_job_del(sd->calc_job);
7180 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
7187 sd->show_item->item->show_me = EINA_FALSE;
7188 sd->show_item = NULL;
7191 evas_object_geometry_get(sd->pan_obj, NULL, NULL, w, h);
7194 case ELM_GENLIST_ITEM_SCROLLTO_IN:
7195 if ((it->item->group_item) &&
7196 (sd->pan_y > (it->y + it->item->block->y)))
7197 gith = it->item->group_item->item->h;
7199 *y = it->y + it->item->block->y - gith;
7202 case ELM_GENLIST_ITEM_SCROLLTO_TOP:
7203 if (it->item->group_item) gith = it->item->group_item->item->h;
7204 *y = it->y + it->item->block->y - gith;
7207 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
7208 *y = it->y + it->item->block->y - (*h / 2) + (it->item->h / 2);
7211 case ELM_GENLIST_ITEM_SCROLLTO_BOTTOM:
7212 *y = it->y + it->item->block->y - *h + it->item->h;
7219 *x = it->x + it->item->block->x;
7220 *w = it->item->block->w;
7226 _elm_genlist_item_promote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7228 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7230 Elm_Object_Item *eo_first_item = elm_genlist_first_item_get(WIDGET(it));
7231 ELM_GENLIST_ITEM_DATA_GET(eo_first_item, first_item);
7232 _item_move_before(it, first_item);
7236 _elm_genlist_item_demote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7238 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7239 Elm_Object_Item *eo_last_item = elm_genlist_last_item_get(WIDGET(it));
7240 ELM_GENLIST_ITEM_DATA_GET(eo_last_item, last_item);
7241 _item_move_after(it, last_item);
7245 _elm_genlist_item_show(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item, Elm_Genlist_Item_Scrollto_Type type)
7247 Evas_Coord x, y, w, h;
7249 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
7251 if (item->want_hidden)
7253 WRN("Filter hided item cannot move to show");
7257 if (_elm_genlist_item_coordinates_calc
7258 (item, type, EINA_FALSE, &x, &y, &w, &h))
7259 eo_do(WIDGET(item), elm_interface_scrollable_content_region_show
7264 _elm_genlist_item_bring_in(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item, Elm_Genlist_Item_Scrollto_Type type)
7266 Evas_Coord x, y, w, h;
7268 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item);
7270 if (item->want_hidden)
7272 WRN("Filter hided item cannot move to bring in");
7276 if (_elm_genlist_item_coordinates_calc
7277 (item, type, EINA_TRUE, &x, &y, &w, &h))
7278 eo_do(WIDGET(item), elm_interface_scrollable_region_bring_in(x, y, w, h));
7282 _elm_genlist_item_all_contents_unset(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_List **l)
7284 Evas_Object *content;
7286 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7288 EINA_LIST_FREE(it->contents, content)
7290 _elm_widget_sub_object_redirect_to_top(WIDGET(it), content);
7291 edje_object_part_unswallow(VIEW(it), content);
7292 evas_object_hide(content);
7293 if (l) *l = eina_list_append(*l, content);
7298 _elm_genlist_item_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7300 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7301 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7303 if (!it->item->block) return;
7304 it->item->mincalcd = EINA_FALSE;
7305 it->item->updateme = EINA_TRUE;
7306 it->item->block->updateme = EINA_TRUE;
7307 ecore_job_del(sd->update_job);
7308 sd->update_job = ecore_job_add(_update_job, sd->obj);
7312 _elm_genlist_item_fields_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
7314 Elm_Genlist_Item_Field_Type itf)
7316 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7318 if (!it->item->block) return;
7320 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
7322 _item_text_realize(it, VIEW(it), &it->texts, parts);
7324 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
7326 _item_content_realize(it, VIEW(it), &it->contents, "contents", parts);
7329 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_contents,
7332 if (GL_IT(it)->deco_it_view)
7334 _item_content_realize(it, GL_IT(it)->deco_it_view,
7335 &GL_IT(it)->deco_it_contents,
7338 if (GL_IT(it)->wsd->decorate_all_mode)
7340 _item_content_realize(it, it->deco_all_view,
7341 &GL_IT(it)->deco_all_contents,
7344 if (it->has_contents != (!!it->contents))
7345 it->item->mincalcd = EINA_FALSE;
7346 it->has_contents = !!it->contents;
7347 if (it->item->type == ELM_GENLIST_ITEM_NONE)
7351 it->item_focus_chain = eina_list_free(it->item_focus_chain);
7352 EINA_LIST_FOREACH(it->contents, l, eobj)
7353 if (elm_widget_is(eobj) && elm_object_focus_allow_get(eobj))
7354 it->item_focus_chain = eina_list_append(it->item_focus_chain, eobj);
7358 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
7359 _item_state_realize(it, VIEW(it), parts);
7361 if (!it->item->mincalcd)
7362 elm_genlist_item_update(eo_item);
7366 _elm_genlist_item_item_class_update(Eo *eo_it, Elm_Gen_Item *it,
7367 const Elm_Genlist_Item_Class *itc)
7369 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7370 EINA_SAFETY_ON_NULL_RETURN(itc);
7372 if (!it->item->block) return;
7373 it->item->nocache_once = EINA_TRUE;
7375 ELM_SAFE_FREE(it->texts, elm_widget_stringlist_free);
7376 ELM_SAFE_FREE(GL_IT(it)->deco_it_texts, elm_widget_stringlist_free);
7377 ELM_SAFE_FREE(GL_IT(it)->deco_all_texts, elm_widget_stringlist_free);
7379 elm_genlist_item_update(eo_it);
7382 EOLIAN static const Elm_Genlist_Item_Class *
7383 _elm_genlist_item_item_class_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7385 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
7390 static Evas_Object *
7391 _elm_genlist_item_label_create(void *data,
7392 Evas_Object *obj EINA_UNUSED,
7393 Evas_Object *tooltip,
7394 void *it EINA_UNUSED)
7396 Evas_Object *label = elm_label_add(tooltip);
7401 elm_object_style_set(label, "tooltip");
7402 elm_object_text_set(label, data);
7408 _elm_genlist_item_label_del_cb(void *data,
7409 Evas_Object *obj EINA_UNUSED,
7410 void *event_info EINA_UNUSED)
7412 eina_stringshare_del(data);
7416 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
7419 eo_do(it, elm_wdg_item_tooltip_text_set(text));
7423 _elm_genlist_item_elm_widget_item_tooltip_text_set(Eo *eo_it, Elm_Gen_Item *it, const char *text)
7425 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7427 text = eina_stringshare_add(text);
7428 elm_genlist_item_tooltip_content_cb_set
7429 (eo_it, _elm_genlist_item_label_create, text,
7430 _elm_genlist_item_label_del_cb);
7434 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item,
7435 Elm_Tooltip_Item_Content_Cb func,
7437 Evas_Smart_Cb del_cb)
7439 eo_do(item, elm_wdg_item_tooltip_content_cb_set(func, data, del_cb));
7443 _elm_genlist_item_elm_widget_item_tooltip_content_cb_set(Eo *eo_it, Elm_Gen_Item *it,
7444 Elm_Tooltip_Item_Content_Cb func,
7446 Evas_Smart_Cb del_cb)
7448 ELM_GENLIST_ITEM_CHECK_OR_GOTO(it, error);
7450 if ((it->tooltip.content_cb != func) || (it->tooltip.data != data))
7452 if (it->tooltip.del_cb)
7453 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7455 it->tooltip.content_cb = func;
7456 it->tooltip.data = data;
7457 it->tooltip.del_cb = del_cb;
7462 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7463 elm_wdg_item_tooltip_content_cb_set
7464 (it->tooltip.content_cb, it->tooltip.data, NULL));
7466 elm_wdg_item_tooltip_style_set(it->tooltip.style),
7467 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
7473 if (del_cb) del_cb((void *)data, NULL, NULL);
7477 elm_genlist_item_tooltip_unset(Elm_Object_Item *item)
7479 eo_do(item, elm_wdg_item_tooltip_unset());
7483 _elm_genlist_item_elm_widget_item_tooltip_unset(Eo *eo_it, Elm_Gen_Item *it)
7485 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7487 if ((VIEW(it)) && (it->tooltip.content_cb))
7488 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7489 elm_wdg_item_tooltip_unset());
7491 if (it->tooltip.del_cb)
7492 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7493 it->tooltip.del_cb = NULL;
7494 it->tooltip.content_cb = NULL;
7495 it->tooltip.data = NULL;
7496 it->tooltip.free_size = EINA_FALSE;
7497 if (it->tooltip.style)
7498 eo_do(eo_it, elm_wdg_item_tooltip_style_set(NULL));
7502 elm_genlist_item_tooltip_style_set(Elm_Object_Item *item,
7505 eo_do(item, elm_wdg_item_tooltip_style_set(style));
7509 _elm_genlist_item_elm_widget_item_tooltip_style_set(Eo *eo_it, Elm_Gen_Item *it,
7512 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7514 eina_stringshare_replace(&it->tooltip.style, style);
7515 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7516 elm_wdg_item_tooltip_style_set(style));
7520 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
7523 return eo_do_ret(it, ret, elm_wdg_item_tooltip_style_get());
7526 EOLIAN static const char *
7527 _elm_genlist_item_elm_widget_item_tooltip_style_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7529 return it->tooltip.style;
7533 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *item,
7537 return eo_do_ret(item, ret, elm_wdg_item_tooltip_window_mode_set(disable));
7540 EOLIAN static Eina_Bool
7541 _elm_genlist_item_elm_widget_item_tooltip_window_mode_set(Eo *eo_it, Elm_Gen_Item *it,
7544 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7546 it->tooltip.free_size = disable;
7550 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7551 ret = elm_wdg_item_tooltip_window_mode_set(disable));
7559 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *eo_it)
7562 return eo_do_ret(eo_it, ret, elm_wdg_item_tooltip_window_mode_get());
7565 EOLIAN static Eina_Bool
7566 _elm_genlist_item_elm_widget_item_tooltip_window_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7568 return it->tooltip.free_size;
7572 elm_genlist_item_cursor_set(Elm_Object_Item *item,
7575 eo_do(item, elm_wdg_item_cursor_set(cursor));
7579 _elm_genlist_item_elm_widget_item_cursor_set(Eo *eo_it, Elm_Gen_Item *it,
7582 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7583 eina_stringshare_replace(&it->mouse_cursor, cursor);
7584 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7585 elm_wdg_item_cursor_set(cursor));
7589 elm_genlist_item_cursor_get(const Elm_Object_Item *eo_it)
7592 return eo_do_ret(eo_it, ret, elm_wdg_item_cursor_get());
7596 elm_genlist_item_cursor_unset(Elm_Object_Item *item)
7598 eo_do(item, elm_wdg_item_cursor_unset());
7602 _elm_genlist_item_elm_widget_item_cursor_unset(Eo *eo_it, Elm_Gen_Item *it)
7604 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7606 if (!it->mouse_cursor) return;
7608 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7609 elm_wdg_item_cursor_unset());
7611 ELM_SAFE_FREE(it->mouse_cursor, eina_stringshare_del);
7615 elm_genlist_item_cursor_style_set(Elm_Object_Item *eo_it,
7618 eo_do(eo_it, elm_wdg_item_cursor_style_set(style));
7622 elm_genlist_item_cursor_style_get(const Elm_Object_Item *eo_it)
7625 return eo_do_ret(eo_it, ret, elm_wdg_item_cursor_style_get());
7629 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *eo_it,
7630 Eina_Bool engine_only)
7632 eo_do(eo_it, elm_wdg_item_cursor_engine_only_set(engine_only));
7636 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *eo_it)
7639 return eo_do_ret(eo_it, ret, elm_wdg_item_cursor_engine_only_get());
7643 _elm_genlist_item_index_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7647 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, -1);
7649 EINA_INLIST_FOREACH(GL_IT(it)->wsd->items, tmp)
7651 if (tmp == it) break;
7658 _elm_genlist_mode_set(Eo *obj, Elm_Genlist_Data *sd, Elm_List_Mode mode)
7660 if (sd->mode == mode) return;
7663 if (sd->mode == ELM_LIST_LIMIT)
7665 sd->scr_minw = EINA_TRUE;
7666 sd->scr_minh = EINA_FALSE;
7668 else if (sd->mode == ELM_LIST_EXPAND)
7670 sd->scr_minw = EINA_TRUE;
7671 sd->scr_minh = EINA_TRUE;
7675 sd->scr_minw = EINA_FALSE;
7676 sd->scr_minh = EINA_FALSE;
7679 elm_layout_sizing_eval(obj);
7682 EOLIAN static Elm_List_Mode
7683 _elm_genlist_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7689 elm_genlist_bounce_set(Evas_Object *obj,
7693 ELM_GENLIST_CHECK(obj);
7694 eo_do(obj, elm_interface_scrollable_bounce_allow_set(h_bounce, v_bounce));
7698 _elm_genlist_elm_interface_scrollable_bounce_allow_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool h_bounce, Eina_Bool v_bounce)
7700 sd->h_bounce = !!h_bounce;
7701 sd->v_bounce = !!v_bounce;
7702 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_bounce_allow_set
7703 (sd->h_bounce, sd->v_bounce));
7707 elm_genlist_bounce_get(const Evas_Object *obj,
7708 Eina_Bool *h_bounce,
7709 Eina_Bool *v_bounce)
7711 ELM_GENLIST_CHECK(obj);
7712 eo_do( obj, elm_interface_scrollable_bounce_allow_get
7713 (h_bounce, v_bounce));
7717 _elm_genlist_elm_interface_scrollable_bounce_allow_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
7719 if (h_bounce) *h_bounce = sd->h_bounce;
7720 if (v_bounce) *v_bounce = sd->v_bounce;
7724 _elm_genlist_homogeneous_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool homogeneous)
7726 sd->homogeneous = !!homogeneous;
7729 EOLIAN static Eina_Bool
7730 _elm_genlist_homogeneous_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7732 return sd->homogeneous;
7736 _elm_genlist_block_count_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, int count)
7738 EINA_SAFETY_ON_TRUE_RETURN(count < 1);
7740 sd->max_items_per_block = count;
7741 sd->item_cache_max = sd->max_items_per_block * 2;
7742 _item_cache_clean(sd);
7746 _elm_genlist_block_count_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7748 return sd->max_items_per_block;
7752 _filter_item_internal(Elm_Gen_Item *it)
7755 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7756 if (sd->filter_data)
7758 if ((it->parent && !_item_filtered_get(it->parent)) ||
7759 (it->itc->func.filter_get &&
7760 !it->itc->func.filter_get(
7761 (void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)),
7762 WIDGET(it), sd->filter_data)))
7764 it->want_hidden = EINA_TRUE;
7765 if (sd->show_item == it) sd->show_item = NULL;
7766 it->item->block->changed = EINA_TRUE;
7769 sd->filtered_count++;
7771 it->filtered = EINA_TRUE;
7772 sd->processed_count++;
7776 _item_filtered_get(Elm_Gen_Item *it)
7779 if (!it) return EINA_FALSE;
7780 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
7783 l = eina_list_data_find_list(sd->filter_queue, it);
7785 sd->filter_queue = eina_list_remove_list(sd->queue, l);
7786 l = eina_list_data_find_list(sd->queue, it);
7789 sd->queue = eina_list_remove_list(sd->queue, l);
7790 it->item->queued = EINA_FALSE;
7791 _item_process(sd, it);
7792 _item_process_post(sd, it, EINA_TRUE);
7795 _filter_item_internal(it);
7796 it->item->block->changed = EINA_TRUE;
7797 ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
7798 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
7800 if (!it->want_hidden) return EINA_TRUE;
7805 _filter_queue_process(Elm_Genlist_Data *sd)
7811 t0 = ecore_loop_time_get();
7812 for (n = 0; (sd->filter_queue) && (sd->processed_count < sd->item_count); n++)
7814 it = eina_list_data_get(sd->filter_queue);
7815 //FIXME: This is added as a fail safe code for items not yet processed.
7816 while (it->item->queued)
7818 if ((ecore_loop_time_get() - t0) > (ecore_animator_frametime_get()))
7820 sd->filter_queue = eina_list_remove_list
7821 (sd->filter_queue, sd->filter_queue);
7822 sd->filter_queue = eina_list_append(sd->filter_queue, it);
7823 it = eina_list_data_get(sd->filter_queue);
7825 sd->filter_queue = eina_list_remove_list(sd->filter_queue, sd->filter_queue);
7826 _filter_item_internal(it);
7827 it->item->block->changed = EINA_TRUE;
7828 if ((ecore_loop_time_get() - t0) > (ecore_animator_frametime_get()))
7830 //At least 1 item is filtered by this time, so return n+1 for first loop
7839 _filter_process(void *data,
7842 Elm_Genlist_Data *sd = data;
7844 if (_filter_queue_process(sd) > 0) *wakeup = EINA_TRUE;
7845 if (!sd->filter_queue) return ECORE_CALLBACK_CANCEL;
7846 return ECORE_CALLBACK_RENEW;
7850 _item_filter_enterer(void *data)
7852 Eina_Bool wakeup = EINA_FALSE;
7853 ELM_GENLIST_DATA_GET(data, sd);
7854 Eina_Bool ok = _filter_process(sd, &wakeup);
7858 ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
7859 sd->calc_job = ecore_job_add(_calc_job, data);
7861 if (ok == ECORE_CALLBACK_CANCEL)
7863 sd->queue_idle_enterer = NULL;
7864 eo_do(sd->obj, eo_event_callback_call(ELM_GENLIST_EVENT_FILTER_DONE, NULL));
7871 _elm_genlist_filter_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, void *filter_data)
7877 if (sd->filter_queue)
7878 ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
7879 ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
7880 ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
7881 sd->filtered_count = 0;
7882 sd->processed_count = 0;
7883 sd->filter = EINA_TRUE;
7884 sd->filter_data = filter_data;
7886 EINA_INLIST_FOREACH(sd->blocks, itb)
7890 EINA_LIST_FOREACH(itb->items, l, it)
7892 it->filtered = EINA_FALSE;
7893 it->want_hidden = EINA_FALSE;
7895 _filter_item_internal(it);
7897 sd->filter_queue = eina_list_append(sd->filter_queue, it);
7899 itb->changed = EINA_TRUE;
7903 EINA_LIST_FOREACH(itb->items, l, it)
7905 it->filtered = EINA_FALSE;
7906 it->want_hidden = EINA_FALSE;
7907 sd->filter_queue = eina_list_append(sd->filter_queue, it);
7913 sd->queue_filter_enterer = ecore_idle_enterer_add(_item_filter_enterer,
7918 _filter_iterator_next(Elm_Genlist_Filter *iter, void **data)
7920 if (!iter->current) return EINA_FALSE;
7922 while (iter->current)
7924 item = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->current, Elm_Gen_Item);
7925 iter->current = iter->current->next;
7926 if (_item_filtered_get(item))
7929 *data = EO_OBJ(item);
7938 _filter_iterator_free(Elm_Genlist_Filter *iter)
7943 static Evas_Object *
7944 _filter_iterator_get_container(Elm_Genlist_Filter *iter)
7946 Elm_Gen_Item *it = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->head, Elm_Gen_Item);
7950 EOLIAN Eina_Iterator *
7951 _elm_genlist_filter_iterator_new(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7953 Elm_Genlist_Filter *iter;
7954 iter = calloc(1, sizeof (Elm_Genlist_Filter));
7955 if (!iter) return NULL;
7957 iter->head = sd->items;
7958 iter->current = sd->items;
7960 iter->iterator.version = EINA_ITERATOR_VERSION;
7961 iter->iterator.next = FUNC_ITERATOR_NEXT(_filter_iterator_next);
7962 iter->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
7963 _filter_iterator_get_container);
7964 iter->iterator.free = FUNC_ITERATOR_FREE(_filter_iterator_free);
7966 EINA_MAGIC_SET(&iter->iterator, EINA_MAGIC_ITERATOR);
7968 return &iter->iterator;
7972 _elm_genlist_longpress_timeout_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, double timeout)
7974 sd->longpress_timeout = timeout;
7977 EOLIAN static double
7978 _elm_genlist_longpress_timeout_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7980 return sd->longpress_timeout;
7984 elm_genlist_scroller_policy_set(Evas_Object *obj,
7985 Elm_Scroller_Policy policy_h,
7986 Elm_Scroller_Policy policy_v)
7988 ELM_GENLIST_CHECK(obj);
7989 eo_do(obj, elm_interface_scrollable_policy_set(policy_h, policy_v));
7993 _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)
7995 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
7996 (policy_v >= ELM_SCROLLER_POLICY_LAST))
7999 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_set(policy_h, policy_v));
8003 elm_genlist_scroller_policy_get(const Evas_Object *obj,
8004 Elm_Scroller_Policy *policy_h,
8005 Elm_Scroller_Policy *policy_v)
8007 ELM_GENLIST_CHECK(obj);
8008 eo_do( obj, elm_interface_scrollable_policy_get(policy_h, policy_v));
8012 _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)
8014 Elm_Scroller_Policy s_policy_h, s_policy_v;
8016 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_get
8017 (&s_policy_h, &s_policy_v));
8018 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
8019 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
8023 _elm_genlist_realized_items_update(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED)
8026 Elm_Object_Item *it;
8028 list = elm_genlist_realized_items_get(obj);
8029 EINA_LIST_FREE(list, it)
8030 elm_genlist_item_update(it);
8034 _elm_genlist_item_decorate_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8035 const char *decorate_it_type,
8036 Eina_Bool decorate_it_set)
8038 Elm_Genlist_Data *sd;
8040 Elm_Object_Item *eo_it2 = NULL;
8043 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8044 sd = GL_IT(it)->wsd;
8046 if (!decorate_it_type) return;
8047 if (eo_do_ret(eo_it, tmp, elm_wdg_item_disabled_get())) return;
8048 if (sd->decorate_all_mode) return;
8050 if ((sd->mode_item == it) &&
8051 (!strcmp(decorate_it_type, sd->decorate_it_type)) &&
8054 if (!it->itc->decorate_item_style) return;
8055 it->decorate_it_set = decorate_it_set;
8059 EINA_LIST_FOREACH(sd->selected, l, eo_it2)
8061 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
8063 elm_genlist_item_selected_set(eo_it2, EINA_FALSE);
8068 Elm_Gen_Item *it2 = NULL;
8069 eo_it2 = elm_genlist_selected_item_get(sd->obj);
8070 if (eo_it2) it2 = eo_data_scope_get(eo_it2, ELM_GENLIST_ITEM_CLASS);
8071 if (it2 && it2->realized)
8072 elm_genlist_item_selected_set(eo_it2, EINA_FALSE);
8075 if (((sd->decorate_it_type)
8076 && (strcmp(decorate_it_type, sd->decorate_it_type))) ||
8077 (decorate_it_set) || ((it == sd->mode_item) && (!decorate_it_set)))
8078 _decorate_item_unset(sd);
8080 eina_stringshare_replace(&sd->decorate_it_type, decorate_it_type);
8081 if (decorate_it_set) _decorate_item_set(it);
8084 EOLIAN static const char *
8085 _elm_genlist_item_decorate_mode_get(Eo *eo_i EINA_UNUSED, Elm_Gen_Item *i)
8087 ELM_GENLIST_ITEM_CHECK_OR_RETURN(i, NULL);
8088 return GL_IT(i)->wsd->decorate_it_type;
8091 EOLIAN static Elm_Object_Item *
8092 _elm_genlist_decorated_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8094 return EO_OBJ(sd->mode_item);
8097 EOLIAN static Eina_Bool
8098 _elm_genlist_decorate_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8100 return sd->decorate_all_mode;
8104 _elm_genlist_decorate_mode_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool decorated)
8106 Elm_Object_Item *eo_it;
8108 Elm_Object_Item *deco_it;
8110 decorated = !!decorated;
8111 if (sd->decorate_all_mode == decorated) return;
8112 // decorate_all_mode should be set first
8113 // because content_get func. will be called after this
8114 // and user can check whether decorate_all_mode_ is enabled.
8115 sd->decorate_all_mode = decorated;
8117 ELM_SAFE_FREE(sd->tree_effect_animator, ecore_animator_del);
8118 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_NONE;
8120 list = elm_genlist_realized_items_get(obj);
8121 if (!sd->decorate_all_mode)
8123 EINA_LIST_FREE(list, eo_it)
8125 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8126 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
8127 _decorate_all_item_unrealize(it);
8129 _item_cache_zero(sd);
8133 // unset decorated item
8134 deco_it = elm_genlist_decorated_item_get(obj);
8137 elm_genlist_item_decorate_mode_set
8138 (deco_it, elm_genlist_item_decorate_mode_get
8139 (deco_it), EINA_FALSE);
8140 _decorate_item_finished_signal_cb(deco_it, obj, NULL, NULL);
8143 EINA_LIST_FREE(list, eo_it)
8145 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8146 if (it->item->type != ELM_GENLIST_ITEM_GROUP)
8148 if (it->itc->decorate_all_item_style)
8149 _decorate_all_item_realize(it, EINA_TRUE);
8154 ecore_job_del(sd->calc_job);
8155 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
8159 _elm_genlist_reorder_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool reorder_mode)
8161 Eina_List *realized;
8162 Elm_Object_Item *eo_it;
8164 if (sd->reorder_mode == !!reorder_mode) return;
8165 sd->reorder_mode = !!reorder_mode;
8166 realized = elm_genlist_realized_items_get(obj);
8167 EINA_LIST_FREE(realized, eo_it)
8169 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8170 if (sd->reorder_mode)
8172 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
8173 if (it->deco_all_view)
8175 edje_object_signal_emit(it->deco_all_view,
8176 SIGNAL_REORDER_MODE_SET, "elm");
8181 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_UNSET, "elm");
8182 if (it->deco_all_view)
8184 edje_object_signal_emit(it->deco_all_view,
8185 SIGNAL_REORDER_MODE_UNSET, "elm");
8191 EOLIAN static Eina_Bool
8192 _elm_genlist_reorder_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8194 return sd->reorder_mode;
8197 EOLIAN static Elm_Genlist_Item_Type
8198 _elm_genlist_item_type_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8200 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
8202 return GL_IT(it)->type;
8205 EAPI Elm_Genlist_Item_Class *
8206 elm_genlist_item_class_new(void)
8208 Elm_Genlist_Item_Class *itc = ELM_NEW(Elm_Genlist_Item_Class);
8209 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
8211 itc->version = CLASS_ALLOCATED;
8213 itc->delete_me = EINA_FALSE;
8219 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
8221 if (itc && (itc->version == CLASS_ALLOCATED))
8223 if (!itc->delete_me) itc->delete_me = EINA_TRUE;
8224 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
8234 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
8236 if (itc && (itc->version == CLASS_ALLOCATED))
8239 if (itc->refcount == 0) itc->refcount--;
8244 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
8246 if (itc && (itc->version == CLASS_ALLOCATED))
8248 if (itc->refcount > 0) itc->refcount--;
8249 if (itc->delete_me && (!itc->refcount))
8250 elm_genlist_item_class_free(itc);
8255 _flip_job(void *data)
8257 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
8258 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8261 _elm_genlist_item_unrealize(it, EINA_FALSE);
8263 it->flipped = EINA_TRUE;
8264 it->item->nocache = EINA_TRUE;
8265 ecore_job_del(sd->calc_job);
8266 sd->calc_job = ecore_job_add(_calc_job, sd->obj);
8270 _elm_genlist_item_flip_set(Eo *eo_it, Elm_Gen_Item *it, Eina_Bool flip)
8272 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8275 if (it->flipped == flip) return;
8279 ecore_job_add(_flip_job, it);
8283 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_DISABLED, "elm");
8284 if (GL_IT(it)->wsd->decorate_all_mode)
8285 edje_object_signal_emit(it->deco_all_view, SIGNAL_FLIP_DISABLED,
8289 _item_cache_zero(GL_IT(it)->wsd);
8290 elm_genlist_item_update(eo_it);
8291 it->item->nocache = EINA_FALSE;
8295 EOLIAN static Eina_Bool
8296 _elm_genlist_item_flip_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8298 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
8304 _elm_genlist_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Elm_Object_Select_Mode mode)
8306 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (sd->select_mode == mode))
8309 sd->select_mode = mode;
8311 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8312 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
8315 Elm_Object_Item *eo_it;
8316 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
8318 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8324 EOLIAN static Elm_Object_Select_Mode
8325 _elm_genlist_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8327 return sd->select_mode;
8331 _elm_genlist_highlight_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool highlight)
8333 sd->highlight = !!highlight;
8336 EOLIAN static Eina_Bool
8337 _elm_genlist_highlight_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8339 return sd->highlight;
8343 _elm_genlist_item_select_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8344 Elm_Object_Select_Mode mode)
8346 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8347 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8349 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (it->select_mode == mode))
8352 it->select_mode = mode;
8354 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8355 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
8358 if (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
8360 it->item->mincalcd = EINA_FALSE;
8361 it->item->updateme = EINA_TRUE;
8362 if (it->item->block) it->item->block->updateme = EINA_TRUE;
8363 ecore_job_del(sd->update_job);
8364 sd->update_job = ecore_job_add(_update_job, sd->obj);
8366 // reset homogeneous item size
8367 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
8368 if (sd->homogeneous || it->itc->homogeneous)
8371 eina_hash_find(sd->size_caches, &(it->itc));
8373 eina_hash_del_by_key(sd->size_caches, it->itc);
8378 EOLIAN static Elm_Object_Select_Mode
8379 _elm_genlist_item_select_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8381 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
8383 return it->select_mode;
8386 EOLIAN Elm_Atspi_State_Set
8387 _elm_genlist_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_it, Elm_Gen_Item *it EINA_UNUSED)
8389 Elm_Atspi_State_Set ret;
8392 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
8394 eo_do(eo_it, sel = elm_obj_genlist_item_selected_get());
8396 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTABLE);
8399 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTED);
8401 if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_TREE)
8403 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDABLE);
8404 if (elm_genlist_item_expanded_get(eo_it))
8405 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8406 //TIZEN_ONLY(20160606): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8408 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8411 //TIZEN_ONLY(20160608): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8412 else if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_GROUP)
8414 if (elm_genlist_item_expanded_get(eo_it))
8415 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8417 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8425 _elm_genlist_item_elm_interface_atspi_accessible_name_get(Eo *eo_it,
8430 char *accessible_name;
8431 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_name_get());
8432 if (ret) return ret;
8433 Elm_Genlist_Item_Type genlist_item_type = elm_genlist_item_type_get(eo_it);
8435 //TIZEN ONLY (160609) : Added in order to read when group item contain checkbox, sub text and normal as per UX guide 0.3.
8436 Eina_List *children = NULL, *l;
8438 Eina_Bool flag_contain_checkbox = EINA_FALSE;
8439 eo_do(eo_it, children = elm_interface_atspi_accessible_children_get());
8440 EINA_LIST_FOREACH(children, l, item)
8442 if (eo_isa((item), ELM_CHECK_CLASS))
8444 flag_contain_checkbox = EINA_TRUE;
8450 buf = eina_strbuf_new();
8452 if (it->itc->func.text_get)
8458 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
8460 EINA_LIST_FREE(texts, key)
8462 char *str_markup = it->itc->func.text_get
8463 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
8464 char *str_utf8 = _elm_util_mkup_to_text(str_markup);
8468 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
8469 eina_strbuf_append(buf, str_utf8);
8475 //TIZEN ONLY (160609) : Added in order to read when group item contain checkbox, sub text and normal as per UX guide 0.3.
8476 if (((genlist_item_type & ELM_GENLIST_ITEM_GROUP) || (genlist_item_type & ELM_GENLIST_ITEM_TREE)) && !flag_contain_checkbox)
8477 eina_strbuf_append(buf,", header");
8480 accessible_name = eina_strbuf_string_steal(buf);
8481 eina_strbuf_free(buf);
8483 eina_stringshare_del(it->base->accessible_name);
8484 it->base->accessible_name = eina_stringshare_add(accessible_name);
8485 free(accessible_name);
8486 return it->base->accessible_name;
8490 _elm_genlist_item_elm_interface_atspi_accessible_children_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8492 Eina_List *ret = NULL;
8497 parts = elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "contents"));
8499 EINA_LIST_FREE(parts, key)
8502 part = edje_object_part_swallow_get(VIEW(it), key);
8503 if (part && eo_isa(part, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
8505 ret = eina_list_append(ret, part);
8506 eo_do(part, elm_interface_atspi_accessible_parent_set(eo_it));
8514 _elm_genlist_tree_effect_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enabled)
8516 sd->tree_effect_enabled = !!enabled;
8519 EOLIAN static Eina_Bool
8520 _elm_genlist_tree_effect_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8522 return sd->tree_effect_enabled;
8526 _elm_genlist_focus_on_selection_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enabled)
8528 sd->focus_on_selection_enabled = !!enabled;
8531 EOLIAN static Eina_Bool
8532 _elm_genlist_focus_on_selection_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8534 return sd->focus_on_selection_enabled;
8537 EAPI Elm_Object_Item *
8538 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth)
8540 Elm_Gen_Item *it = NULL;
8544 ELM_GENLIST_CHECK(obj) NULL;
8545 ELM_GENLIST_DATA_GET(obj, sd);
8547 if (!sd->items) return NULL;
8549 a = eina_inlist_accessor_new(sd->items);
8550 if (!a) return NULL;
8551 if (eina_accessor_data_get(a, nth, &data))
8552 it = ELM_GEN_ITEM_FROM_INLIST(data);
8553 eina_accessor_free(a);
8558 _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)
8560 Evas_Coord ox, oy, oh, ow, item_x = 0, item_y = 0, item_w = 0, item_h = 0;
8562 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
8564 if (sd->focused_item)
8566 ELM_GENLIST_ITEM_DATA_GET(sd->focused_item, focus_it);
8567 evas_object_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
8568 elm_widget_focus_highlight_focus_part_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
8580 if (item_y > (oy + oh - item_h))
8582 *y = oy + oh - item_h;
8585 if ((item_x + item_w) > (ox + ow))
8595 EOLIAN static Elm_Object_Item *
8596 _elm_genlist_search_by_text_item_get(Eo *obj EINA_UNUSED,
8597 Elm_Genlist_Data *sd,
8598 Elm_Object_Item *item_to_search_from,
8599 const char *part_name,
8600 const char *pattern,
8601 Elm_Glob_Match_Flags flags)
8603 Elm_Gen_Item *it = NULL;
8605 Eina_Inlist *start = NULL;
8608 if (!pattern) return NULL;
8609 if (!sd->items) return NULL;
8611 if (flags & ELM_GLOB_MATCH_NO_ESCAPE) fnflags |= FNM_NOESCAPE;
8612 if (flags & ELM_GLOB_MATCH_PATH) fnflags |= FNM_PATHNAME;
8613 if (flags & ELM_GLOB_MATCH_PERIOD) fnflags |= FNM_PERIOD;
8615 if (flags & ELM_GLOB_MATCH_NOCASE) fnflags |= FNM_CASEFOLD;
8618 start = (item_to_search_from) ?
8619 EINA_INLIST_GET((Elm_Gen_Item *)eo_data_scope_get(item_to_search_from, ELM_GENLIST_ITEM_CLASS)) :
8621 EINA_INLIST_FOREACH(start, it)
8623 if (!it->itc->func.text_get) continue;
8624 str = it->itc->func.text_get((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), part_name);
8626 if (!fnmatch(pattern, str, fnflags))
8636 EOLIAN static Elm_Object_Item*
8637 _elm_genlist_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8639 return sd->focused_item;
8643 _elm_genlist_elm_widget_item_loop_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enable)
8645 sd->item_loop_enable = !!enable;
8648 EOLIAN static Eina_Bool
8649 _elm_genlist_elm_widget_item_loop_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8651 return sd->item_loop_enable;
8655 _elm_genlist_class_constructor(Eo_Class *klass)
8657 if (_elm_config->access_mode)
8658 _elm_genlist_smart_focus_next_enable = EINA_TRUE;
8660 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
8663 EOLIAN const Elm_Atspi_Action *
8664 _elm_genlist_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd EINA_UNUSED)
8666 static Elm_Atspi_Action atspi_actions[] = {
8667 { "move,prior", "move", "prior", _key_action_move},
8668 { "move,next", "move", "next", _key_action_move},
8669 { "move,left", "move", "left", _key_action_move},
8670 { "move,right", "move", "right", _key_action_move},
8671 { "move,up", "move", "up", _key_action_move},
8672 { "move,up,multi", "move", "up_multi", _key_action_move},
8673 { "move,down", "move", "down", _key_action_move},
8674 { "move,down,multi", "move", "down_multi", _key_action_move},
8675 { "move,first", "move", "first", _key_action_move},
8676 { "move,last", "move", "last", _key_action_move},
8677 { "select", "select", NULL, _key_action_select},
8678 { "select,multi", "select", "multi", _key_action_select},
8679 { "escape", "escape", NULL, _key_action_escape},
8680 { NULL, NULL, NULL, NULL }
8682 return &atspi_actions[0];
8686 _elm_genlist_elm_interface_atspi_accessible_children_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8688 Eina_List *ret = NULL;
8691 EINA_INLIST_FOREACH(sd->items, it)
8692 ret = eina_list_append(ret, EO_OBJ(it));
8697 EOLIAN Elm_Atspi_State_Set
8698 _elm_genlist_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED)
8700 Elm_Atspi_State_Set ret;
8702 eo_do_super(obj, ELM_GENLIST_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
8704 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MANAGES_DESCENDANTS);
8706 if (elm_genlist_multi_select_get(obj))
8707 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MULTISELECTABLE);
8709 //TIZEN_ONLY(20160520): genlist: added atspi support for drag n drop
8710 if (elm_genlist_reorder_mode_get(obj))
8711 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_ANIMATED);
8718 _elm_genlist_elm_interface_atspi_selection_selected_children_count_get(Eo *objm EINA_UNUSED, Elm_Genlist_Data *pd)
8720 return eina_list_count(pd->selected);
8724 _elm_genlist_elm_interface_atspi_selection_selected_child_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_idx)
8726 return eina_list_nth(pd->selected, child_idx);
8730 _elm_genlist_elm_interface_atspi_selection_child_select(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
8733 if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
8735 EINA_INLIST_FOREACH(pd->items, item)
8737 if (child_index-- == 0)
8739 elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
8748 _elm_genlist_elm_interface_atspi_selection_selected_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
8753 EINA_LIST_FOREACH(pd->selected, l, item)
8755 if (child_index-- == 0)
8757 elm_genlist_item_selected_set(item, EINA_FALSE);
8765 _elm_genlist_elm_interface_atspi_selection_is_child_selected(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
8769 EINA_INLIST_FOREACH(pd->items, item)
8771 if (child_index-- == 0)
8773 return elm_genlist_item_selected_get(EO_OBJ(item));
8780 _elm_genlist_elm_interface_atspi_selection_all_children_select(Eo *obj, Elm_Genlist_Data *pd)
8784 if (!elm_genlist_multi_select_get(obj))
8787 EINA_INLIST_FOREACH(pd->items, item)
8788 elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
8794 _elm_genlist_elm_interface_atspi_selection_clear(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd)
8796 return _all_items_deselect(pd);
8800 _elm_genlist_elm_interface_atspi_selection_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
8803 if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
8805 EINA_INLIST_FOREACH(pd->items, item)
8807 if (child_index-- == 0)
8809 elm_genlist_item_selected_set(EO_OBJ(item), EINA_FALSE);
8817 //TIZEN_ONLY(20160329): genlist: enhance accessibility scroll & highlight (30d9a6012e629cd9ea60eae8d576f3ebb94ada86)
8818 static int _is_item_in_viewport(int viewport_y, int viewport_h, int obj_y, int obj_h)
8820 if ((obj_y + obj_h/2) < viewport_y)
8822 else if ((obj_y + obj_h/2) > viewport_y + viewport_h)
8827 static Eina_Bool _atspi_enabled()
8830 Eina_Bool ret = EINA_FALSE;
8831 if (_elm_config->atspi_mode && (bridge = _elm_atspi_bridge_get()))
8832 eo_do(bridge, ret = elm_obj_atspi_bridge_connected_get());
8837 _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)
8839 if (!_atspi_enabled())
8841 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
8845 int old_x, old_y, delta_y;
8846 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_get(&old_x,&old_y));
8847 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
8848 delta_y = old_y - y;
8850 //check if highlighted item is genlist descendant
8851 Evas_Object * highlighted_obj = _elm_object_accessibility_currently_highlighted_get();
8852 if (eo_isa(highlighted_obj, ELM_WIDGET_ITEM_CLASS))
8854 Elm_Widget_Item_Data *id = eo_data_scope_get(highlighted_obj, ELM_WIDGET_ITEM_CLASS);
8855 highlighted_obj = id->view;
8858 Evas_Object *parent = highlighted_obj;
8859 if (eo_isa(highlighted_obj, ELM_WIDGET_CLASS))
8861 while ((parent = elm_widget_parent_get(parent)))
8865 else if (eo_isa(highlighted_obj, EDJE_OBJECT_CLASS))
8867 while ((parent = evas_object_smart_parent_get(parent)))
8871 // TIZEN_ONLY(20160805): set _accessibility_currently_highlighted_obj to NULL in object delete callback
8874 WRN("Improper highlighted object: %p", highlighted_obj);
8881 int obj_x, obj_y, w, h, hx, hy, hw, hh;
8882 evas_object_geometry_get(obj, &obj_x, &obj_y, &w, &h);
8884 evas_object_geometry_get(highlighted_obj, &hx, &hy, &hw, &hh);
8886 Elm_Gen_Item * next_previous_item = NULL;
8887 int viewport_position_result = _is_item_in_viewport(obj_y, h, hy, hh);
8888 //only highlight if move direction is correct
8889 //sometimes highlighted item is brought in and it does not fit viewport
8890 //however content goes to the viewport position so soon it will
8891 //meet _is_item_in_viewport condition
8892 if ((viewport_position_result < 0 && delta_y > 0) ||
8893 (viewport_position_result > 0 && delta_y < 0))
8896 Eina_List *realized_items = elm_genlist_realized_items_get(obj);
8899 Eina_Bool traverse_direction = viewport_position_result > 0;
8900 l = traverse_direction ? realized_items: eina_list_last(realized_items);
8904 item = eina_list_data_get(l);
8905 ELM_GENLIST_ITEM_DATA_GET(item, it_data);
8906 next_previous_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it_data));
8907 evas_object_geometry_get(VIEW(next_previous_item), &hx, &hy, &hw, &hh);
8908 if (_is_item_in_viewport(obj_y, h, hy, hh) == 0)
8911 next_previous_item = NULL;
8913 l = traverse_direction ? eina_list_next(l): eina_list_prev(l);
8916 if (next_previous_item)
8917 eo_do(EO_OBJ(next_previous_item), elm_interface_atspi_component_highlight_grab());
8921 EOLIAN static Eina_Bool
8922 _elm_genlist_item_elm_interface_atspi_component_highlight_grab(Eo *eo_it, Elm_Gen_Item *it)
8924 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8925 Eina_Bool ret = EINA_TRUE;
8927 // if item is realized check if in viewport
8930 Evas_Coord wy, wh, y, h;
8931 evas_object_geometry_get(WIDGET(it), NULL, &wy, NULL, &wh);
8932 evas_object_geometry_get(VIEW(it), NULL, &y, NULL, &h);
8933 int res = _is_item_in_viewport(wy, wh, y, h);
8936 // new item is above current
8937 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_BOTTOM);
8941 // new item is below current
8942 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
8945 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
8947 else // if item is not realized we should search if we are over or below viewport
8949 Eina_List *realized;
8950 int idx, top, bottom;
8951 realized = elm_genlist_realized_items_get(WIDGET(it));
8954 // index of realized element on top of viewport
8955 eo_do(eina_list_nth(realized, 0), top = elm_obj_genlist_item_index_get());
8956 // index of realized element on bottom of viewport
8957 eo_do(eina_list_last_data_get(realized), bottom = elm_obj_genlist_item_index_get());
8958 eo_do(eo_it, idx = elm_obj_genlist_item_index_get());
8959 eina_list_free(realized);
8961 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_BOTTOM);
8962 else if (idx > bottom)
8963 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
8965 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
8970 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_component_highlight_grab());
8972 sd->atspi_item_to_highlight = it;//it will be highlighted when realized
8974 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_it);
8979 EOLIAN static Eina_Bool
8980 _elm_genlist_item_elm_interface_atspi_component_highlight_clear(Eo *eo_it, Elm_Gen_Item *it)
8983 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8984 if (sd->atspi_item_to_highlight == it)
8985 sd->atspi_item_to_highlight = NULL;
8987 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_it);
8989 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_component_highlight_clear());
8994 //Tizen Only(20170113) : Below Legacy APIs are Mobile Only Feature
8996 elm_genlist_realization_mode_set(Evas_Object *obj EINA_UNUSED, Eina_Bool mode EINA_UNUSED)
8998 // Mobile Only Feature;
9003 elm_genlist_realization_mode_get(Evas_Object *obj EINA_UNUSED)
9005 // Mobile Only Feature;
9010 elm_genlist_item_reorder_start(Elm_Object_Item *item EINA_UNUSED)
9012 // Mobile Only Feature;
9017 elm_genlist_item_reorder_stop(Elm_Object_Item *item EINA_UNUSED)
9019 // Mobile Only Feature;
9024 #include "elm_genlist.eo.c"
9025 #include "elm_genlist_item.eo.c"