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
14 #define ELM_ATSPI_BRIDGE_PROTECTED
16 #include <Elementary.h>
17 #include <Elementary_Cursor.h>
20 #include "elm_widget_genlist.h"
21 #include "elm_interface_scrollable.h"
23 #define MY_PAN_CLASS ELM_GENLIST_PAN_CLASS
25 #define MY_PAN_CLASS_NAME "Elm_Genlist_Pan"
26 #define MY_PAN_CLASS_NAME_LEGACY "elm_genlist_pan"
28 #define MY_CLASS ELM_GENLIST_CLASS
30 #define MY_CLASS_NAME "Elm_Genlist"
31 #define MY_CLASS_NAME_LEGACY "elm_genlist"
33 // internally allocated
34 #define CLASS_ALLOCATED 0x3a70f11f
36 #define REORDERED_ITEM_OFFSET (8 * elm_config_scale_get())
37 #define REORDER_FASTER (15 * elm_config_scale_get())
38 #define REORDER_ANIM_OFFSET (10 * elm_config_scale_get())
39 #define MAX_ITEMS_PER_BLOCK 32
40 #define PINCH_ZOOM_TOLERANCE 0.4
41 #define ITEM_SELECT_TIMER 0.05 // This is needed for highlight effect when item is unhighlighted right after item is highlighted and selected
42 #define ANIM_CNT_MAX (_elm_config->genlist_animation_duration / 1000 * _elm_config->fps) // frame time
43 #define HIGHLIGHT_ALPHA_MAX 0.74
44 #define ELM_ITEM_HIGHLIGHT_TIMER 0.1
45 #define ITEM_QUEUE_MAX 128
46 #define DIMED_ITEM_COLOR 50
47 #define ALIGNED_ITEM_SCALE_FACTOR 1.5
48 #define CENTER_CHECK_GAP 50
51 #define ERR_ABORT(_msg) \
54 if (getenv("ELM_ERROR_ABORT")) abort(); \
57 #define GL_IT(_it) (_it->item)
59 #define IS_ROOT_PARENT_IT(_it) \
60 ((_it->group) || ((GL_IT(_it)->items && GL_IT(_it)->expanded_depth == 0) \
61 &&(!(GL_IT(_it)->type & ELM_GENLIST_ITEM_TREE)))) \
63 #define ELM_PRIV_GENLIST_SIGNALS(cmd) \
64 cmd(SIG_ACTIVATED, "activated", "") \
65 cmd(SIG_CLICKED_DOUBLE, "clicked,double", "") \
66 cmd(SIG_SELECTED, "selected", "") \
67 cmd(SIG_UNSELECTED, "unselected", "") \
68 cmd(SIG_EXPANDED, "expanded", "") \
69 cmd(SIG_CONTRACTED, "contracted", "") \
70 cmd(SIG_EXPAND_REQUEST, "expand,request", "") \
71 cmd(SIG_CONTRACT_REQUEST, "contract,request", "") \
72 cmd(SIG_REALIZED, "realized", "") \
73 cmd(SIG_UNREALIZED, "unrealized", "") \
74 cmd(SIG_DRAG_START_UP, "drag,start,up", "") \
75 cmd(SIG_DRAG_START_DOWN, "drag,start,down", "") \
76 cmd(SIG_DRAG_START_LEFT, "drag,start,left", "") \
77 cmd(SIG_DRAG_START_RIGHT, "drag,start,right", "") \
78 cmd(SIG_DRAG_STOP, "drag,stop", "") \
79 cmd(SIG_DRAG, "drag", "") \
80 cmd(SIG_LONGPRESSED, "longpressed", "") \
81 cmd(SIG_SCROLL_ANIM_START, "scroll,anim,start", "") \
82 cmd(SIG_SCROLL_ANIM_STOP, "scroll,anim,stop", "") \
83 cmd(SIG_SCROLL_DRAG_START, "scroll,drag,start", "") \
84 cmd(SIG_SCROLL_DRAG_STOP, "scroll,drag,stop", "") \
85 cmd(SIG_SCROLL, "scroll", "") \
86 cmd(SIG_EDGE_TOP, "edge,top", "") \
87 cmd(SIG_EDGE_BOTTOM, "edge,bottom", "") \
88 cmd(SIG_EDGE_LEFT, "edge,left", "") \
89 cmd(SIG_EDGE_RIGHT, "edge,right", "") \
90 cmd(SIG_VBAR_DRAG, "vbar,drag", "") \
91 cmd(SIG_VBAR_PRESS, "vbar,press", "") \
92 cmd(SIG_VBAR_UNPRESS, "vbar,unpress", "") \
93 cmd(SIG_HBAR_DRAG, "hbar,drag", "") \
94 cmd(SIG_HBAR_PRESS, "hbar,press", "") \
95 cmd(SIG_HBAR_UNPRESS, "hbar,unpress", "") \
96 cmd(SIG_MULTI_SWIPE_LEFT, "multi,swipe,left", "") \
97 cmd(SIG_MULTI_SWIPE_RIGHT, "multi,swipe,right", "") \
98 cmd(SIG_MULTI_SWIPE_UP, "multi,swipe,up", "") \
99 cmd(SIG_MULTI_SWIPE_DOWN, "multi,swipe,down", "") \
100 cmd(SIG_MULTI_PINCH_OUT, "multi,pinch,out", "") \
101 cmd(SIG_MULTI_PINCH_IN, "multi,pinch,in", "") \
102 cmd(SIG_SWIPE, "swipe", "") \
103 cmd(SIG_MOVED, "moved", "") \
104 cmd(SIG_MOVED_AFTER, "moved,after", "") \
105 cmd(SIG_MOVED_BEFORE, "moved,before", "") \
106 cmd(SIG_INDEX_UPDATE, "index,update", "") \
107 cmd(SIG_TREE_EFFECT_FINISHED , "tree,effect,finished", "") \
108 cmd(SIG_HIGHLIGHTED, "highlighted", "") \
109 cmd(SIG_UNHIGHLIGHTED, "unhighlighted", "") \
110 cmd(SIG_LANG_CHANGED, "language,changed", "") \
111 cmd(SIG_PRESSED, "pressed", "") \
112 cmd(SIG_RELEASED, "released", "") \
113 cmd(SIG_ITEM_FOCUSED, "item,focused", "") \
114 cmd(SIG_ITEM_UNFOCUSED, "item,unfocused", "") \
115 cmd(SIG_ACCESS_CHANGED, "access,changed", "") \
116 cmd(SIG_LOADED, "loaded", "") \
117 cmd(SIG_ATSPI_SCREEN_READER_CHANGED, "atspi,screen,reader,changed", "") \
118 cmd(SIG_WIDGET_ATSPI_HIGHLIGHTED, "atspi,highlighted", "") \
119 cmd(SIG_FILTER_DONE, "filter,done", "")
121 ELM_PRIV_GENLIST_SIGNALS(ELM_PRIV_STATIC_VARIABLE_DECLARE);
123 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
124 ELM_PRIV_GENLIST_SIGNALS(ELM_PRIV_SMART_CALLBACKS_DESC)
125 {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
126 {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
127 {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
128 {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
129 {SIG_ITEM_FOCUSED, ""},
130 {SIG_ITEM_UNFOCUSED, ""},
131 //TIZEN_ONLY(20161213): apply screen_reader_changed callback
132 {SIG_ATSPI_SCREEN_READER_CHANGED, ""},
134 //TIZEN_ONLY(20170724): grab highlight using unrealized item
135 {SIG_WIDGET_ATSPI_HIGHLIGHTED, ""},
140 #undef ELM_PRIV_GENLIST_SIGNALS
142 // **** edje interface signals *** //
143 static const char SIGNAL_ENABLED[] = "elm,state,enabled";
144 static const char SIGNAL_DISABLED[] = "elm,state,disabled";
145 static const char SIGNAL_HIGHLIGHTED[] = "elm,state,selected"; // actually highlighted
146 static const char SIGNAL_UNHIGHLIGHTED[] = "elm,state,unselected"; // actually unhighlighted
147 static const char SIGNAL_CLICKED[] = "elm,state,clicked";
148 static const char SIGNAL_EXPANDED[] = "elm,state,expanded";
149 static const char SIGNAL_CONTRACTED[] = "elm,state,contracted";
150 static const char SIGNAL_FLIP_ENABLED[] = "elm,state,flip,enabled";
151 static const char SIGNAL_FLIP_DISABLED[] = "elm,state,flip,disabled";
152 static const char SIGNAL_DECORATE_ENABLED[] = "elm,state,decorate,enabled";
153 static const char SIGNAL_DECORATE_ENABLED_EFFECT[] = "elm,state,decorate,enabled,effect";
154 static const char SIGNAL_DECORATE_DISABLED[] = "elm,state,decorate,disabled";
155 static const char SIGNAL_REORDER_ENABLED[] = "elm,state,reorder,enabled";
156 static const char SIGNAL_REORDER_DISABLED[] = "elm,state,reorder,disabled";
157 static const char SIGNAL_REORDER_MODE_SET[] = "elm,state,reorder,mode_set";
158 static const char SIGNAL_REORDER_MODE_UNSET[] = "elm,state,reorder,mode_unset";
160 static const char SIGNAL_DEFAULT[] = "elm,state,default";
161 static const char SIGNAL_FOCUSED[] = "elm,state,focused";
162 static const char SIGNAL_UNFOCUSED[] = "elm,state,unfocused";
163 static const char SIGNAL_BG_CHANGE[] = "bg_color_change";
164 static const char SIGNAL_ITEM_HIGHLIGHTED[] = "elm,state,highlighted";
165 static const char SIGNAL_ITEM_UNHIGHLIGHTED[] = "elm,state,unhighlighted";
166 static const char SIGNAL_FOCUS_BG_SHOW[] = "elm,state,focus_bg,show";
167 //static const char SIGNAL_FOCUS_BG_HIDE[] = "elm,state,focus_bg,hide";
177 static void _item_mouse_down_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info);
178 static void _item_mouse_move_cb(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event_info);
179 static void _item_mouse_up_cb(void *data, Evas *evas, Evas_Object *obj EINA_UNUSED, void *event_info);
180 static Eina_Bool _long_press_cb(void *data);
182 static void _item_edje_callbacks_add(Elm_Gen_Item *it);
183 static void _item_edje_callbacks_del(Elm_Gen_Item *it);
185 static void _item_block_calc(Item_Block *itb, Evas_Coord vw, Evas_Coord vh);
186 static void _item_min_calc(Elm_Gen_Item *it);
187 static void _item_calc(Elm_Gen_Item *it);
188 static void _item_mouse_callbacks_add(Elm_Gen_Item *, Evas_Object *);
189 static void _item_mouse_callbacks_del(Elm_Gen_Item *, Evas_Object *);
190 static void _item_select(Elm_Gen_Item *it);
191 static void _item_realize(Elm_Gen_Item *it, Eina_Bool calc);
192 static void _item_unrealize(Elm_Gen_Item *it, Eina_Bool calc);
194 static void _expand_toggle_signal_cb(void *data, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED);
195 static void _expand_signal_cb(void *data, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED);
196 static void _contract_signal_cb(void *data, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED);
197 static void _decorate_item_unrealize(Elm_Gen_Item *it);
198 static void _decorate_item_realize(Elm_Gen_Item *it);
199 static void _decorate_all_item_unrealize(Elm_Gen_Item *it);
200 static void _item_queue(Elm_Gen_Item *it, Eina_Compare_Cb cb);
201 static Eina_Bool _queue_idle_enter(void *data);
202 static void _dummy_job(void *data);
203 static void _item_free(Elm_Gen_Item *it);
204 static void _evas_viewport_resize_cb(void *d, Evas *e EINA_UNUSED, void *ei EINA_UNUSED);
205 static Eina_Bool _item_process(Elm_Genlist_Data *sd, Elm_Gen_Item *it);
206 static int _is_item_in_viewport(int viewport_y, int viewport_h, int obj_y, int obj_h);
207 static Eina_Bool _item_filtered_get(Elm_Gen_Item *it);
208 static Eina_Bool _item_focusable_search(Elm_Gen_Item **it, int dir);
210 typedef struct _Size_Cache {
216 // TIZEN ONLY : for banded ux
218 _banded_item_bg_add(Elm_Gen_Item *it, Evas_Object *target)
222 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
224 if (sd->banded_bg_on)
226 bg_area = edje_object_data_get(VIEW(it), "banded_bg_area");
228 if (bg_area && !GL_IT(it)->banded_bg)
230 GL_IT(it)->banded_bg = evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
231 edje_object_part_swallow(target, bg_area, GL_IT(it)->banded_bg);
233 snprintf(buf, sizeof(buf), "elm,state,%s,visible", bg_area);
234 edje_object_signal_emit(VIEW(it), buf, "elm");
238 if (!sd->banded_bg_rect)
240 sd->banded_bg_rect = evas_object_rectangle_add(evas_object_evas_get(sd->obj));
241 if (sd->banded_bg_on)
242 evas_object_color_set(sd->banded_bg_rect, 250, 250, 250, 255);
244 evas_object_color_set(sd->banded_bg_rect, 0, 0, 0, 0);
245 evas_object_smart_member_add(sd->banded_bg_rect, sd->pan_obj);
246 elm_widget_sub_object_add(sd->obj, sd->banded_bg_rect);
247 evas_object_move(sd->banded_bg_rect, -9999, -9999);
248 evas_object_resize(sd->banded_bg_rect, 0, 0);
249 evas_object_repeat_events_set(sd->banded_bg_rect, EINA_TRUE);
254 _banded_bg_state_check(Eo *obj, Elm_Genlist_Data *sd)
256 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
258 const char *banded_bg = edje_object_data_get(wd->resize_obj, "banded_bg");
260 if (banded_bg && !strcmp("on", banded_bg))
261 sd->banded_bg_on = EINA_TRUE;
263 sd->banded_bg_on = EINA_FALSE;
267 _banded_item_bg_color_change(Elm_Gen_Item *it, Eina_Bool highlight)
269 if (GL_IT(it)->banded_bg)
271 int alpha = 255 * (1 - 0.04 * GL_IT(it)->banded_color_index);
275 alpha *= HIGHLIGHT_ALPHA_MAX;
277 color = (color * alpha) / 255;
278 evas_object_color_set(GL_IT(it)->banded_bg, color, color, color, alpha);
283 _banded_item_bg_index_color_set(Elm_Gen_Item *it_top, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
286 Elm_Genlist_Data *sd = GL_IT(it_top)->wsd;
287 Elm_Gen_Item *prev = NULL, *next = it_top;
288 int item_count, i = 0, j = 0;
292 if (!sd->banded_bg_on || !next->realized) return;
294 item_count = eina_list_count(l = elm_genlist_realized_items_get(WIDGET(it_top)));
297 while ((i < item_count) && (next))
299 if (!next->realized || next->want_hidden)
302 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
306 if (next != it_top && !ELM_RECTS_INTERSECT(GL_IT(next)->scrl_x, GL_IT(next)->scrl_y,
307 GL_IT(next)->w, GL_IT(next)->h, ox, oy, ow, oh))
312 ((GL_IT(prev)->type == ELM_GENLIST_ITEM_GROUP) ||
313 (prev->itc->item_style && !strncmp("group", prev->itc->item_style, 5))))
316 if (GL_IT(next)->banded_bg)
318 GL_IT(next)->banded_color_index = j;
319 _banded_item_bg_color_change(next, next->highlighted);
324 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
327 if ((j < 0) || (j > (BANDED_MAX_ITEMS - 1)))
337 _item_content_free(Evas_Object *content)
339 // FIXME: For animation, befor del, processing edc.
340 if (evas_object_smart_type_check(content, "elm_layout"))
341 edje_object_message_signal_process(elm_layout_edje_get(content));
342 // FIXME: If parent-child relationship was broken before 'ic'
343 // is deleted, freeze_pop will not be called. ex) elm_slider
344 // If layout is used instead of edje, this problme can be
346 if (elm_widget_is(content) && (0 != elm_widget_scroll_freeze_get(content)))
347 elm_widget_scroll_freeze_pop(content);
348 evas_object_del(content);
352 _item_cache_free(Elm_Genlist_Data *sd, Item_Cache *ic)
357 if (ic->base_view) evas_object_del(ic->base_view);
358 ic->item_class = NULL;
359 EINA_LIST_FREE(ic->contents, c)
361 _item_content_free(c);
363 sd->item_cache = eina_inlist_remove(sd->item_cache, EINA_INLIST_GET(ic));
364 sd->item_cache_count--;
365 // Free should be performed after inlist is poped
370 _item_cache_all_free(Elm_Genlist_Data *sd)
372 // It would be better not to use
373 // EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
374 while (sd->item_cache)
376 Item_Cache *ic = EINA_INLIST_CONTAINER_GET(sd->item_cache->last, Item_Cache);
377 _item_cache_free(sd, ic);
379 sd->item_cache = NULL;
380 sd->item_cache_count = 0;
384 _item_cache_push(Elm_Gen_Item *it, Eina_List *contents)
386 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
387 Item_Cache *ic = NULL;
388 Evas_Object *content;
392 if (VIEW(it)) evas_object_del(VIEW(it));
394 EINA_LIST_FREE(contents, content)
396 _item_content_free(content);
401 if (sd->item_cache_count >= sd->item_cache_max)
403 ic = EINA_INLIST_CONTAINER_GET(sd->item_cache->last, Item_Cache);
404 _item_cache_free(sd, ic);
407 ic = ELM_NEW(Item_Cache);
410 if (VIEW(it)) evas_object_del(VIEW(it));
412 EINA_LIST_FREE(contents, content)
414 _item_content_free(content);
418 // set item's state as default before pushing item into cache.
419 edje_object_signal_emit(VIEW(it), SIGNAL_DEFAULT, "elm");
421 edje_object_mirrored_set(VIEW(it),
422 elm_widget_mirrored_get(WIDGET(it)));
423 edje_object_scale_set(VIEW(it),
424 elm_widget_scale_get(WIDGET(it))
425 * elm_config_scale_get());
427 ic->base_view = VIEW(it);
428 ic->multiline = GL_IT(it)->multiline;
429 ic->item_class = it->itc;
430 ic->contents = contents;
431 evas_object_hide(ic->base_view);
432 evas_object_move(ic->base_view, -9999, -9999);
434 sd->item_cache = eina_inlist_prepend(sd->item_cache, EINA_INLIST_GET(ic));
435 sd->item_cache_count++;
441 _item_cache_pop(Elm_Gen_Item *it)
443 Item_Cache *ic = NULL;
445 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
447 if (!it->itc) return EINA_FALSE;
449 EINA_INLIST_FOREACH_SAFE(sd->item_cache, l, ic)
451 if (it->itc && ic->item_class &&
452 (it->itc == ic->item_class))
455 eina_inlist_remove(sd->item_cache, EINA_INLIST_GET(ic));
456 sd->item_cache_count--;
458 VIEW(it) = ic->base_view;
459 GL_IT(it)->multiline = ic->multiline;
461 eina_list_free(ic->contents);
470 // TIZEN_ONLY(20150828) : to prevent unnecessary genlist rendering
471 // _changed is called instead of evas_object_smart_changed API.
473 _changed(Evas_Object *pan_obj)
475 Elm_Genlist_Pan_Data *psd = eo_data_scope_get(pan_obj, MY_PAN_CLASS);
476 Elm_Genlist_Data *sd = psd->wsd;
478 if (sd->viewport_w > 1) evas_object_smart_changed(pan_obj);
483 _elm_genlist_pan_elm_pan_pos_set(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord x, Evas_Coord y)
485 if ((x == psd->wsd->pan_x) && (y == psd->wsd->pan_y)) return;
487 if (y > psd->wsd->pan_y) psd->wsd->dir = 1;
488 else psd->wsd->dir = -1;
496 _elm_genlist_pan_elm_pan_pos_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y)
498 if (x) *x = psd->wsd->pan_x;
499 if (y) *y = psd->wsd->pan_y;
502 // TIZEN_ONLY(20150705): genlist item align feature
503 static Elm_Gen_Item *
504 _elm_genlist_pos_adjust_xy_item_get(const Evas_Object *obj,
510 ELM_GENLIST_CHECK(obj) NULL;
511 ELM_GENLIST_DATA_GET(obj, sd);
513 EINA_INLIST_FOREACH(sd->blocks, itb)
517 if (!ELM_RECTS_INTERSECT(itb->x - sd->pan_x,
519 sd->minw, itb->minh, x, y, 1, 1))
521 EINA_LIST_FOREACH(itb->items, l, it)
523 Evas_Coord itx, ity, itw, ith;
525 itx = itb->x + it->x - sd->pan_x;
526 ity = itb->y + it->y - sd->pan_y;
528 itw = (GL_IT(it)->w ? GL_IT(it)->w : sd->minw);
529 ith = GL_IT(it)->minh;
531 if (ELM_RECTS_INTERSECT(itx, ity, itw, ith, x, y, 1, 1))
539 static Elm_Gen_Item *
540 _adjust_item_align(Elm_Gen_Item *it)
542 if (!it) return NULL;
545 Elm_Gen_Item *adjust_item = it;
546 Elm_Object_Item *eo_item = NULL;
547 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
549 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(adjust_item), wd, NULL);
551 if (!wd || !(wd->scroll_item_align_enable)) return it;
552 if (!sd || !sd->aligned_item || (it == sd->aligned_item)) return it;
554 direction = GL_IT(adjust_item)->scrl_y - GL_IT(sd->aligned_item)->scrl_y;
555 while (adjust_item && loop_count < 10)
557 const char *align = NULL;
558 if (!VIEW(adjust_item))
560 _item_realize(adjust_item, EINA_TRUE);
561 align = edje_object_data_get(VIEW(adjust_item), "align");
562 _item_unrealize(adjust_item, EINA_TRUE);
565 align = edje_object_data_get(VIEW(adjust_item), "align");
567 if (align && !strcmp(align, "off"))
570 eo_item = elm_genlist_item_prev_get(EO_OBJ(adjust_item));
572 eo_item = elm_genlist_item_next_get(EO_OBJ(adjust_item));
573 adjust_item = eo_data_scope_get(eo_item, ELM_GENLIST_ITEM_CLASS);
580 if (adjust_item) return adjust_item;
583 while (adjust_item && loop_count < 10)
585 const char *align = NULL;
586 if (!VIEW(adjust_item))
588 _item_realize(adjust_item, EINA_TRUE);
589 align = edje_object_data_get(VIEW(adjust_item), "align");
590 _item_unrealize(adjust_item, EINA_TRUE);
593 align = edje_object_data_get(VIEW(adjust_item), "align");
595 if (align && !strcmp(align, "off"))
598 eo_item = elm_genlist_item_prev_get(EO_OBJ(adjust_item));
600 eo_item = elm_genlist_item_next_get(EO_OBJ(adjust_item));
601 adjust_item = eo_data_scope_get(eo_item, ELM_GENLIST_ITEM_CLASS);
615 _elm_genlist_pan_elm_pan_pos_adjust(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *x EINA_UNUSED, Evas_Coord *y)
617 ELM_WIDGET_DATA_GET_OR_RETURN(psd->wobj, wd);
618 Elm_Genlist_Data *sd = psd->wsd;
620 if (!(wd->scroll_item_align_enable)) return;
624 Elm_Object_Item *eo_it;
626 Evas_Coord cx = 0, cy = 0;
627 Evas_Coord it_y, it_h;
630 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
631 (NULL, NULL, &vw, &vh));
632 if (!strcmp(wd->scroll_item_valign, "center"))
638 sd->adjusted_item = _elm_genlist_pos_adjust_xy_item_get(sd->obj, cx, cy);
640 if ((abs(*y) > FLICK_GAP) && (sd->adjusted_item == sd->aligned_item))
642 Elm_Gen_Item *adjusted_item = NULL;
644 eo_it = elm_genlist_item_next_get(EO_OBJ(sd->adjusted_item));
646 eo_it = elm_genlist_item_prev_get(EO_OBJ(sd->adjusted_item));
647 adjusted_item = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
649 sd->adjusted_item = adjusted_item;
651 sd->adjusted_item = _adjust_item_align(sd->adjusted_item);
652 if (!sd->adjusted_item) return;
654 cy += psd->wsd->pan_y;
655 it_y = sd->adjusted_item->y + GL_IT(sd->adjusted_item)->block->y;
656 it_h = GL_IT(sd->adjusted_item)->h;
658 if (GL_IT(sd->adjusted_item)->h <= vh)
660 it_h = it_y + (it_h / 2);
665 int it_b_y = it_y + it_h;
667 if (it_y <= cy && it_y >= cy - half_vh)
669 *y -= half_vh - (cy - it_y);
671 else if (it_b_y >= cy && it_b_y <= cy + half_vh)
673 *y += half_vh - (it_b_y - cy);
677 if (!*y && !sd->unhighlighted)
678 sd->adjusted_item = NULL;
680 evas_object_smart_changed(sd->pan_obj);
685 _elm_genlist_pan_elm_pan_pos_max_get(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y)
689 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
690 ow = psd->wsd->minw - ow;
692 oh = psd->wsd->minh - oh;
699 _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)
706 _elm_genlist_pan_elm_pan_content_size_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *w, Evas_Coord *h)
708 if (w) *w = psd->wsd->minw;
709 if (h) *h = psd->wsd->minh;
713 _elm_genlist_pan_evas_object_smart_del(Eo *obj, Elm_Genlist_Pan_Data *psd)
715 ecore_job_del(psd->resize_job);
717 eo_do_super(obj, MY_PAN_CLASS, evas_obj_smart_del());
721 _elm_genlist_pan_evas_object_smart_move(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord _gen_param2 EINA_UNUSED,
722 Evas_Coord _gen_param3 EINA_UNUSED)
729 _elm_genlist_pan_evas_object_smart_resize(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord w, Evas_Coord h)
731 if ((w > 1 || h > 1))
733 if (psd->wsd->queue && !psd->wsd->queue_idle_enterer)
735 psd->wsd->queue_idle_enterer = ecore_idle_enterer_add(_queue_idle_enter, psd->wsd);
738 if (psd->wsd->mode == ELM_LIST_COMPRESS &&
739 psd->wsd->prev_viewport_w != w)
742 ELM_WIDGET_DATA_GET_OR_RETURN(psd->wsd->obj, wd);
743 EINA_INLIST_FOREACH(psd->wsd->blocks, itb)
747 EINA_LIST_FOREACH(itb->items, l, it)
749 if (!wd->scroll_item_align_enable && !GL_IT(it)->multiline) continue;
750 if (GL_IT(it)->wsd->realization_mode)
752 GL_IT(it)->calc_done = EINA_FALSE;
753 GL_IT(it)->block->calc_done = EINA_FALSE;
757 GL_IT(it)->resized = EINA_TRUE;
760 GL_IT(it)->calc_done = EINA_FALSE;
761 GL_IT(it)->block->calc_done = EINA_FALSE;
763 else _item_queue(it, NULL);
767 psd->wsd->prev_viewport_w = w;
769 psd->wsd->viewport_w = w;
770 psd->wsd->viewport_h = h;
772 psd->wsd->calc_done = EINA_FALSE;
777 _item_text_realize(Elm_Gen_Item *it,
783 if (it->itc->func.text_get)
788 source = elm_widget_stringlist_get
789 (edje_object_data_get(target, "texts"));
790 EINA_LIST_FREE(source, key)
792 if (parts && fnmatch(parts, key, FNM_PERIOD))
795 char *s = it->itc->func.text_get
796 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
800 edje_object_part_text_escaped_set(target, key, s);
803 snprintf(buf, sizeof(buf), "elm,state,%s,visible", key);
804 edje_object_signal_emit(target, buf, "elm");
808 edje_object_part_text_set(target, key, "");
809 snprintf(buf, sizeof(buf), "elm,state,%s,hidden", key);
810 edje_object_signal_emit(target, buf, "elm");
813 edje_object_message_signal_process(target);
814 if (_elm_atspi_enabled())
815 elm_interface_atspi_accessible_name_changed_signal_emit(EO_OBJ(it));
820 _changed_size_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
822 Elm_Gen_Item *it = data;
823 GL_IT(it)->calc_done = EINA_FALSE;
824 GL_IT(it)->block->calc_done = EINA_FALSE;
825 GL_IT(it)->wsd->calc_done = EINA_FALSE;
826 _changed(GL_IT(it)->wsd->pan_obj);
829 // FIXME: There are applications which do not use elm_win as top widget.
830 // This is workaround! Those could not use focus!
832 static Eina_Bool _focus_enabled(Evas_Object *obj)
834 if (!elm_widget_focus_get(obj)) return EINA_FALSE;
836 const Evas_Object *win = elm_widget_top_get(obj);
837 const char *type = evas_object_type_get(win);
839 if (type && !strcmp(type, "elm_win"))
841 return elm_win_focus_highlight_enabled_get(win);
848 _widget_calculate_recursive(Eo *obj)
850 Elm_Widget_Smart_Data *pd = NULL;
854 if (!eo_isa(obj, ELM_WIDGET_CLASS)) return;
856 pd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
859 if (!evas_object_smart_need_recalculate_get(obj) &&
860 !evas_object_smart_need_recalculate_get(pd->resize_obj))
863 EINA_LIST_FOREACH(pd->subobjs, l, child)
864 _widget_calculate_recursive(child);
866 evas_object_smart_calculate(obj);
870 _item_content_realize(Elm_Gen_Item *it,
872 Eina_List **contents,
877 Evas_Object *content;
884 EINA_LIST_FREE(*contents, content)
885 _item_content_free(content);
887 if ((!it->itc->func.content_get) &&
888 ((it->itc->version < 3) || (!it->itc->func.reusable_content_get))) return;
890 source = elm_widget_stringlist_get(edje_object_data_get(target, src));
892 EINA_LIST_FREE(source, key)
894 if (parts && fnmatch(parts, key, FNM_PERIOD))
897 Evas_Object *old = NULL;
898 old = edje_object_part_swallow_get(target, key);
900 // Reuse content by popping from the cache
902 if (it->itc->version >= 3 && it->itc->func.reusable_content_get)
903 content = it->itc->func.reusable_content_get(
904 (void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key, old);
907 // Call the content get
908 if (it->itc->func.content_get)
909 content = it->itc->func.content_get
910 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
913 snprintf(buf, sizeof(buf), "elm,state,%s,hidden", key);
914 edje_object_signal_emit(target, buf, "elm");
920 // FIXME: Genlist item doesn't update its size when the size of
921 // content is changed, so deferred calculation for content should
922 // be performed before realization.
923 if (eo_isa(content, ELM_WIDGET_CLASS))
925 ELM_WIDGET_DATA_GET_OR_RETURN(content, wd);
927 // FIXME : Layout need sizing eval before group calculate
928 if (eo_class_get(content) == ELM_LAYOUT_CLASS)
929 eo_do(content, elm_obj_layout_sizing_eval());
931 _widget_calculate_recursive(content);
934 if (!edje_object_part_swallow(target, key, content))
936 ERR("%s (%p) can not be swallowed into %s",
937 evas_object_type_get(content), content, key);
938 evas_object_del(content);
941 elm_widget_sub_object_add(WIDGET(it), content);
943 *contents = eina_list_append(*contents, content);
945 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()))
946 elm_widget_disabled_set(content, EINA_TRUE);
948 if (GL_IT(it)->wsd->realization_mode)
950 evas_object_event_callback_add
951 (content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
952 _changed_size_hints, it);
955 snprintf(buf, sizeof(buf), "elm,state,%s,visible", key);
956 edje_object_signal_emit(target, buf, "elm");
958 // If content object is focused,
959 // genlist item should be focused.
960 if (elm_widget_focused_object_get(content))
962 if (GL_IT(it)->wsd->focused_item != it)
963 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
965 GL_IT(it)->wsd->focused_content = content;
968 if (old && content != old)
970 *contents = eina_list_remove(*contents, old);
971 _item_content_free(old);
977 _item_state_realize(Elm_Gen_Item *it,
981 if (it->itc->func.state_get)
987 src = elm_widget_stringlist_get
988 (edje_object_data_get(target, "states"));
989 EINA_LIST_FREE(src, key)
991 if (parts && fnmatch(parts, key, FNM_PERIOD))
994 Eina_Bool on = it->itc->func.state_get
995 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
999 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1000 edje_object_signal_emit(target, buf, "elm");
1004 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1005 edje_object_signal_emit(target, buf, "elm");
1012 _view_theme_update(Elm_Gen_Item *it, Evas_Object *view, const char *style)
1018 snprintf(buf, sizeof(buf), "item/%s", style ? : "default");
1020 Elm_Theme_Apply th_ret =
1021 elm_widget_theme_object_set(WIDGET(it), view, "genlist", buf,
1022 elm_widget_style_get(WIDGET(it)));
1023 if (th_ret == ELM_THEME_APPLY_FAILED)
1025 ERR("%s is not a valid genlist item style. "
1026 "Automatically falls back into default style.",
1028 elm_widget_theme_object_set
1029 (WIDGET(it), view, "genlist", "item/default", "default");
1032 edje_object_mirrored_set(view, elm_widget_mirrored_get(WIDGET(it)));
1033 edje_object_scale_set(view, elm_widget_scale_get(WIDGET(it))
1034 * elm_config_scale_get());
1036 GL_IT(it)->multiline = EINA_FALSE;
1037 Eina_List *txts = elm_widget_stringlist_get
1038 (edje_object_data_get(view, "texts"));
1039 EINA_LIST_FOREACH(txts, l, key)
1041 const Evas_Object *txt_obj = NULL;
1042 const char *type = NULL;
1043 txt_obj = edje_object_part_object_get(view, key);
1044 if (txt_obj) type = evas_object_type_get(txt_obj);
1045 if (!type) continue;
1046 if (type && strcmp(type, "textblock")) continue;
1048 const Evas_Textblock_Style *tb_style =
1049 evas_object_textblock_style_get(txt_obj);
1052 const char *str = evas_textblock_style_get(tb_style);
1055 if (strstr(str, "wrap="))
1057 GL_IT(it)->multiline = EINA_TRUE;
1063 eina_list_free(txts);
1066 static Evas_Object *
1067 _view_create(Elm_Gen_Item *it, const char *style)
1069 Evas_Object *view = edje_object_add(evas_object_evas_get(WIDGET(it)));
1070 evas_object_smart_member_add(view, GL_IT(it)->wsd->pan_obj);
1071 elm_widget_sub_object_add(WIDGET(it), view);
1072 edje_object_scale_set(view, elm_widget_scale_get(WIDGET(it)) *
1073 elm_config_scale_get());
1075 _view_theme_update(it, view, style);
1080 _view_clear(Evas_Object *view, Eina_List **contents)
1085 Eina_List *texts = elm_widget_stringlist_get
1086 (edje_object_data_get(view, "texts"));
1087 EINA_LIST_FREE(texts, part)
1088 edje_object_part_text_set(view, part, NULL);
1092 EINA_LIST_FREE(*contents, c)
1093 _item_content_free(c);
1098 _view_inflate(Evas_Object *view, Elm_Gen_Item *it, Eina_List **contents)
1101 _item_text_realize(it, view, NULL);
1102 if (contents) _item_content_realize(it, view, contents, "contents", NULL);
1103 _item_state_realize(it, view, NULL);
1107 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1109 if (it->position_update || GL_IT(it)->block->position_update)
1111 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, EO_OBJ(it));
1112 it->position_update = EINA_FALSE;
1117 _access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
1122 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1123 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1125 buf = eina_strbuf_new();
1127 if (it->itc->func.text_get)
1133 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1135 EINA_LIST_FREE(texts, key)
1137 char *s = it->itc->func.text_get
1138 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
1140 s = _elm_util_mkup_to_text(s);
1144 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
1145 eina_strbuf_append(buf, s);
1151 ret = eina_strbuf_string_steal(buf);
1152 eina_strbuf_free(buf);
1157 _access_state_cb(void *data, Evas_Object *obj EINA_UNUSED)
1159 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1161 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1163 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()))
1164 return strdup(E_("Disabled"));
1170 _access_activate_cb(void *data,
1171 Evas_Object *part_obj EINA_UNUSED,
1172 Elm_Object_Item *item EINA_UNUSED)
1174 Elm_Gen_Item *it = data;
1175 Evas_Object *parent = WIDGET(it);
1179 if (evas_object_freeze_events_get(parent)) return;
1180 parent = evas_object_smart_parent_get(parent);
1187 _access_widget_item_register(Elm_Gen_Item *it)
1189 Elm_Access_Info *ai;
1190 Eina_List *orders = NULL;
1191 Eina_List *l = NULL;
1192 Evas_Object *c, *child, *ret;
1193 Eina_List *listn, *ln;
1194 Eina_List *texts, *contents;
1196 if (!_elm_config->access_mode) return;
1198 /* access: unregister item which have no text and content */
1199 texts = elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1200 contents = elm_widget_stringlist_get(edje_object_data_get(VIEW(it),
1202 if (!texts && !contents) return;
1203 eina_list_free(texts);
1204 eina_list_free(contents);
1206 _elm_access_widget_item_unregister(it->base);
1207 // FIXME: if item->view is not it->item->deco_all_view!!
1208 if (it->deco_all_view)
1210 Evas_Object *acc = elm_access_object_register
1211 (it->deco_all_view, WIDGET(it));
1212 it->base->access_obj = acc;
1216 _elm_access_widget_item_register(it->base);
1219 ai = _elm_access_info_get(eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_access_object_get()));
1220 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1221 _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
1222 _elm_access_activate_callback_set(ai, _access_activate_cb, it);
1224 elm_object_item_access_order_unset(EO_OBJ(it));
1227 EINA_LIST_FOREACH(GL_IT(it)->flip_content_objs, l, c)
1229 if (elm_widget_can_focus_get(c))
1231 orders = eina_list_append(orders, c);
1237 if (it->deco_all_view)
1239 EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, c)
1241 if (elm_widget_can_focus_get(c))
1243 orders = eina_list_append(orders, c);
1247 EINA_LIST_FOREACH(it->content_objs, l, c)
1249 if (elm_widget_can_focus_get(c))
1251 /*FIXME The below change is done to push datetime's access objects
1252 like date field and time field in to genlist focus list to get focus.*/
1253 listn = elm_widget_can_focus_child_list_get(c);
1256 EINA_LIST_FOREACH(listn, ln, child)
1258 orders = eina_list_append(orders, child);
1263 orders = eina_list_append(orders, c);
1269 elm_object_item_access_order_set(EO_OBJ(it), orders);
1273 _item_unrealize(Elm_Gen_Item *it,
1276 Evas_Object *content;
1277 Eina_List *cache = NULL;
1279 if (!it->realized) return;
1281 if (GL_IT(it)->wsd->reorder.it == it)
1283 WRN("reordering item should not be unrealized");
1288 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, EO_OBJ(it));
1289 _elm_access_widget_item_unregister(it->base);
1290 elm_object_item_access_order_unset(EO_OBJ(it));
1291 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
1292 if (_elm_atspi_enabled())
1294 elm_interface_atspi_accessible_removed(EO_OBJ(it));
1295 elm_interface_atspi_accessible_children_changed_del_signal_emit(GL_IT(it)->wsd->obj, EO_OBJ(it));
1301 Elm_Widget_Item_Signal_Data *wisd;
1302 EINA_LIST_FOREACH(it->base->signals, l, wisd)
1304 eo_do(EO_OBJ(it), elm_wdg_item_signal_callback_del
1305 (wisd->emission, wisd->source, (Elm_Object_Item_Signal_Cb)wisd->func));
1308 _decorate_item_unrealize(it);
1309 _decorate_all_item_unrealize(it);
1311 _item_edje_callbacks_del(it);
1313 _item_mouse_callbacks_del(it, VIEW(it));
1314 if (!calc && it->item->proxy)
1316 evas_object_image_source_visible_set(it->item->proxy, EINA_TRUE);
1317 evas_object_smart_member_del(it->item->proxy);
1318 evas_object_del(it->item->proxy);
1319 it->item->proxy = NULL;
1322 EINA_LIST_FREE(GL_IT(it)->flip_content_objs, content)
1323 evas_object_del(content);
1324 if (it->spacer) evas_object_del(it->spacer);
1325 _view_clear(VIEW(it), NULL);
1327 // TIZEN ONLY : for banded ux
1328 if (!TIZEN_PROFILE_WEARABLE)
1330 if (GL_IT(it)->banded_bg)
1331 ELM_SAFE_FREE(GL_IT(it)->banded_bg, evas_object_del);
1332 if (GL_IT(it)->wsd->banded_bg_on)
1334 if (it->item->banded_anim) ecore_animator_del(it->item->banded_anim);
1335 it->item->banded_anim = NULL;
1339 if (GL_IT(it)->highlight_timer)
1341 ecore_timer_del(GL_IT(it)->highlight_timer);
1342 GL_IT(it)->highlight_timer = NULL;
1346 ecore_timer_del(it->long_timer);
1347 it->long_timer = NULL;
1350 eo_do(EO_OBJ(it), elm_wdg_item_track_cancel());
1351 //TIZEN_ONLY(20161013): clean up elm color class feature
1352 if (it->base->color_classes)
1353 edje_object_color_class_clear(VIEW(it));
1355 EINA_LIST_FREE(it->content_objs, content)
1357 if (it->itc->version >= 3 && it->itc->func.reusable_content_get)
1359 // Unfocus content object for initialization.
1360 if (GL_IT(it)->wsd->focused_content == content)
1362 elm_object_focus_set(content, EINA_FALSE);
1363 GL_IT(it)->wsd->focused_content = NULL;
1365 if (elm_widget_disabled_get(content))
1366 elm_widget_disabled_set(content, EINA_FALSE);
1368 cache = eina_list_append(cache, content);
1372 if (GL_IT(it)->wsd->focused_content == content)
1373 GL_IT(it)->wsd->focused_content = NULL;
1374 elm_object_focus_set(content, EINA_FALSE);
1375 evas_object_del(content);
1379 _item_cache_push(it, cache);
1381 it->realized = EINA_FALSE;
1385 _item_block_unrealize(Item_Block *itb)
1388 const Eina_List *l, *ll;
1389 Evas_Object *content;
1390 Eina_Bool unrealize = EINA_TRUE;
1392 // Do not check itb->realized
1393 // because it->item->block can be changed
1395 EINA_LIST_FOREACH(itb->items, l, it)
1397 if (!(((GL_IT(it)->wsd->reorder_force) || (GL_IT(it)->wsd->reorder_mode))
1398 && (GL_IT(it)->wsd->reorder.it == it))
1399 && !it->flipped && it->realized)
1401 /* FIXME: when content is on focused and unrealize item,
1402 focus is set to other object and scroll will be bring in */
1403 if (_elm_config->access_mode)
1405 EINA_LIST_FOREACH(it->content_objs, ll, content)
1407 if (elm_object_focus_get(content))
1409 unrealize = EINA_FALSE;
1415 _item_unrealize(it, EINA_FALSE);
1416 unrealize = EINA_TRUE;
1419 itb->realized = EINA_FALSE;
1425 Elm_Genlist_Data *sd = data;
1427 Evas_Coord minw = 99999999, minh = 0, vw = 0, vh = 0, current_minh = 0;
1428 Evas_Coord processed_size = sd->minh;
1431 if (sd->calc_done) return;
1433 // TIZEN_ONLY(20150828) : Calculate item which position on viewport area
1435 ((sd->viewport_h > processed_size) && (cnt < MAX_ITEMS_PER_BLOCK)))
1438 tmp = eina_list_data_get(sd->queue);
1439 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
1440 if (!_item_process(sd, tmp)) continue;
1441 processed_size += GL_IT(tmp)->minh;
1442 tmp->item->queued = EINA_FALSE;
1446 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
1447 (NULL, NULL, &vw, &vh));
1448 EINA_INLIST_FOREACH(sd->blocks, itb)
1452 _item_block_calc(itb, vw, vh);
1453 if (minw > itb->minw) minw = itb->minw;
1457 if ((sd->mode == ELM_LIST_COMPRESS) && (minw > vw))
1459 else if (minw < vw) minw = vw;
1461 if ((minw != sd->minw) || (minh != sd->minh))
1463 Eina_Bool load_done = EINA_FALSE;
1465 current_minh = sd->minh;
1468 if (!sd->queue && (minh != current_minh)) load_done = EINA_TRUE;
1469 elm_layout_sizing_eval(sd->obj);
1470 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
1472 evas_object_smart_callback_call(sd->obj, SIG_LOADED, NULL);
1473 sd->processed_sizes = 0;
1476 sd->calc_done = EINA_TRUE;
1480 _elm_genlist_elm_layout_sizing_eval(Eo *obj, Elm_Genlist_Data *sd)
1482 Evas_Coord minw = 0, minh = 0, maxw = -1, maxh = -1;
1484 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1486 if (sd->on_sub_del) return;;
1488 evas_object_size_hint_min_get(obj, &minw, NULL);
1489 evas_object_size_hint_max_get(obj, &maxw, &maxh);
1490 edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
1495 minw = minw + sd->minw;
1500 minh = minh + sd->minh;
1503 if ((maxw > 0) && (minw > maxw))
1505 if ((maxh > 0) && (minh > maxh))
1508 evas_object_size_hint_min_set(obj, minw, minh);
1509 evas_object_size_hint_max_set(obj, maxw, maxh);
1513 _elm_genlist_content_min_limit_cb(Evas_Object *obj,
1517 ELM_GENLIST_DATA_GET(obj, sd);
1519 if ((sd->mode == ELM_LIST_LIMIT) ||
1520 (sd->mode == ELM_LIST_EXPAND)) return;
1524 elm_layout_sizing_eval(obj);
1528 _focus_bg_show(Elm_Gen_Item *it)
1531 Evas_Coord h = 0, rectangle_h = GL_IT(it)->h;
1532 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wd);
1533 const Evas_Object *top, *bottom;
1534 Evas_Object *rectangle;
1535 const char *focus_bg;
1537 if (!VIEW(it)) return;
1538 focus_bg = edje_object_data_get(VIEW(it), "focus_bg");
1539 if (focus_bg && !strcmp(focus_bg, "off")) return;
1541 evas_object_geometry_get(wd->resize_obj, NULL, NULL, &w, NULL);
1542 top = edje_object_part_object_get(VIEW(it), "elm.padding.focus_bg.top");
1543 bottom = edje_object_part_object_get(VIEW(it), "elm.padding.focus_bg.bottom");
1547 evas_object_geometry_get(top, NULL, NULL, NULL, &h);
1549 evas_object_geometry_get(bottom, NULL, NULL, NULL, &h);
1553 rectangle = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
1554 evas_object_size_hint_min_set(rectangle, w, rectangle_h);
1555 evas_object_size_hint_max_set(rectangle, w, rectangle_h);
1556 evas_object_color_set(rectangle, 0, 0, 0, 0);
1557 elm_object_part_content_set(wd->obj, "focus_bg_size", rectangle);
1559 edje_object_signal_emit(wd->resize_obj, SIGNAL_FOCUS_BG_SHOW, "elm");
1563 _item_position(Elm_Gen_Item *it,
1571 Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0;
1572 Evas_Coord ix = 0, iy = 0, iw = 0, ih = 0;
1573 Elm_Gen_Item *target = it;
1574 Elm_Genlist_Data *sd = GL_IT(target)->wsd;
1575 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(target), wsd);
1579 iw = GL_IT(target)->w;
1580 ih = GL_IT(target)->h;
1582 evas_object_resize(view, iw, ih);
1583 evas_object_move(view, ix, iy);
1584 evas_object_show(view);
1586 if (wsd->scroll_item_align_enable)
1589 int pre_multiplied_color = 0;
1590 int resize_width = 0;
1591 int resize_hight = 0;
1594 double move_v[4] = {0.49, 0.99, 0.45, 1.0};
1595 double scale_v[4] = {0.49, 0.14, 1, 0.63};
1597 evas_object_geometry_get(wsd->obj, &ox, &oy, &ow, &oh);
1598 int g_center = oy + oh / 2;
1599 int i_center = GL_IT(target)->scrl_y + GL_IT(target)->h / 2;
1601 if (target->item->proxy && !ELM_RECTS_INTERSECT(ix, iy, iw, ih, ox, oy, ow, oh))
1602 evas_object_hide(target->item->proxy);
1605 const char *vi_effect = edje_object_data_get(VIEW(target), "vi_effect");
1606 if (vi_effect && !strcmp(vi_effect, "on"))
1608 ratio = (float)abs(g_center - i_center) / (float)((oh / 2) + ih / 2);
1609 color = DIMED_ITEM_COLOR + ((255 - DIMED_ITEM_COLOR) * (1.0 - ratio));
1610 double scale_p = ecore_animator_pos_map_n(ratio, ECORE_POS_MAP_CUBIC_BEZIER, 4, scale_v);
1611 scale = elm_config_scale_get() - (scale_p * ALIGNED_ITEM_SCALE_FACTOR);
1613 resize_width = GL_IT(target)->w * (scale / elm_config_scale_get());
1614 if (!((iw - resize_width) % 2))
1617 iw = resize_width + 1;
1618 ix = GL_IT(target)->scrl_x + (GL_IT(target)->w - iw) / 2;
1619 resize_hight = GL_IT(target)->h * (scale / elm_config_scale_get());
1621 if (!((ih - resize_hight) % 2))
1624 ih = resize_hight + 1;
1626 if (i_center < g_center)
1628 double move_p = ecore_animator_pos_map_n(ratio, ECORE_POS_MAP_CUBIC_BEZIER, 4, move_v);
1629 iy = GL_IT(target)->scrl_y + move_p * (GL_IT(target)->h - ih);
1632 iy = GL_IT(target)->scrl_y;
1634 const char *dim = edje_object_data_get(view, "dim");
1635 if (!dim || (dim && !strcmp(dim, "on")))
1637 pre_multiplied_color = 255 * color >> 8;
1638 if (!elm_object_item_disabled_get(EO_OBJ(target)))
1639 evas_object_color_set(target->item->proxy, pre_multiplied_color, pre_multiplied_color, pre_multiplied_color, color);
1641 evas_object_color_set(target->item->proxy, 255, 255, 255, 255);
1644 evas_object_move(target->item->proxy, ix, iy);
1645 evas_object_resize(target->item->proxy, iw, ih);
1646 evas_object_show(target->item->proxy);
1649 ELM_RECTS_INTERSECT(GL_IT(target)->scrl_x, GL_IT(target)->scrl_y,
1650 GL_IT(target)->w, GL_IT(target)->h,
1651 ox, g_center - CENTER_CHECK_GAP,
1652 ow, CENTER_CHECK_GAP * 2))
1654 if ((sd->adjusted_item == target) &&
1655 ((sd->adjusted_item != sd->aligned_item) || (sd->unhighlighted)))
1657 edje_object_signal_emit(VIEW(sd->adjusted_item), SIGNAL_ITEM_HIGHLIGHTED, "elm");
1659 if (sd->aligned_item && sd->adjusted_item != sd->aligned_item)
1660 edje_object_signal_emit(VIEW(sd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
1661 sd->aligned_item = sd->adjusted_item;
1662 sd->unhighlighted = EINA_FALSE;
1665 if (sd->adjusted_item == target &&
1666 sd->aligned_item == sd->adjusted_item &&
1667 ((i_center >= g_center && i_center < g_center + 10) ||
1668 (i_center <= g_center && i_center > g_center - 10)))
1670 sd->adjusted_item = NULL;
1671 _focus_bg_show(sd->aligned_item);
1679 _item_all_position(Elm_Gen_Item *it,
1685 if (it->deco_all_view)
1686 _item_position(it, it->deco_all_view, it_x, it_y);
1687 else if (GL_IT(it)->deco_it_view)
1688 _item_position(it, GL_IT(it)->deco_it_view, it_x, it_y);
1690 _item_position(it, VIEW(it), it_x, it_y);
1694 _decorate_item_unrealize(Elm_Gen_Item *it)
1696 if (!GL_IT(it)->deco_it_view) return;
1698 edje_object_part_unswallow(GL_IT(it)->deco_it_view, VIEW(it));
1699 _view_clear(GL_IT(it)->deco_it_view, &(GL_IT(it)->deco_it_contents));
1700 evas_object_del(GL_IT(it)->deco_it_view);
1701 GL_IT(it)->deco_it_view = NULL;
1703 _item_mouse_callbacks_add(it, VIEW(it));
1704 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
1708 _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect)
1711 if (it->deco_all_view || !it->itc->decorate_all_item_style) return;
1713 // Before adding & swallowing, delete it from smart member
1714 evas_object_smart_member_del(VIEW(it));
1716 it->deco_all_view = _view_create(it, it->itc->decorate_all_item_style);
1717 _view_inflate(it->deco_all_view, it, &(GL_IT(it)->deco_all_contents));
1718 edje_object_part_swallow
1719 (it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
1720 evas_object_show(it->deco_all_view);
1722 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()))
1723 edje_object_signal_emit(it->deco_all_view, SIGNAL_DISABLED, "elm");
1725 edje_object_signal_emit(it->deco_all_view, SIGNAL_HIGHLIGHTED, "elm");
1726 if (GL_IT(it)->wsd->reorder_force ||
1727 GL_IT(it)->wsd->reorder_mode)
1728 edje_object_signal_emit
1729 (it->deco_all_view, SIGNAL_REORDER_MODE_SET, "elm");
1733 edje_object_signal_emit(VIEW(it),
1734 SIGNAL_DECORATE_ENABLED_EFFECT, "elm");
1735 edje_object_signal_emit(it->deco_all_view,
1736 SIGNAL_DECORATE_ENABLED_EFFECT, "elm");
1740 edje_object_signal_emit(VIEW(it), SIGNAL_DECORATE_ENABLED, "elm");
1741 edje_object_signal_emit(it->deco_all_view,
1742 SIGNAL_DECORATE_ENABLED,"elm");
1745 edje_object_signal_emit(it->deco_all_view, SIGNAL_FLIP_ENABLED, "elm");
1747 _item_mouse_callbacks_add(it, it->deco_all_view);
1748 _item_mouse_callbacks_del(it, VIEW(it));
1752 _expand_toggle_signal_cb(void *data,
1753 Evas_Object *obj EINA_UNUSED,
1754 const char *emission EINA_UNUSED,
1755 const char *source EINA_UNUSED)
1757 Elm_Gen_Item *it = data;
1759 if (GL_IT(it)->expanded)
1760 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, EO_OBJ(it));
1762 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, EO_OBJ(it));
1766 _expand_signal_cb(void *data,
1767 Evas_Object *obj EINA_UNUSED,
1768 const char *emission EINA_UNUSED,
1769 const char *source EINA_UNUSED)
1771 Elm_Gen_Item *it = data;
1773 if (!GL_IT(it)->expanded)
1774 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, EO_OBJ(it));
1778 _contract_signal_cb(void *data,
1779 Evas_Object *obj EINA_UNUSED,
1780 const char *emission EINA_UNUSED,
1781 const char *source EINA_UNUSED)
1783 Elm_Gen_Item *it = data;
1785 if (GL_IT(it)->expanded)
1786 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, EO_OBJ(it));
1790 _item_mouse_callbacks_add(Elm_Gen_Item *it,
1793 evas_object_event_callback_add
1794 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
1795 evas_object_event_callback_add
1796 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
1797 evas_object_event_callback_add
1798 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
1802 _item_mouse_callbacks_del(Elm_Gen_Item *it,
1805 evas_object_event_callback_del_full
1806 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
1807 evas_object_event_callback_del_full
1808 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
1809 evas_object_event_callback_del_full
1810 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
1815 _item_edje_callbacks_add(Elm_Gen_Item *it)
1817 edje_object_signal_callback_add
1818 (VIEW(it), "elm,action,expand,toggle", "elm",
1819 _expand_toggle_signal_cb, it);
1820 edje_object_signal_callback_add
1821 (VIEW(it), "elm,action,expand", "elm", _expand_signal_cb, it);
1822 edje_object_signal_callback_add
1823 (VIEW(it), "elm,action,contract", "elm", _contract_signal_cb, it);
1827 _item_edje_callbacks_del(Elm_Gen_Item *it)
1829 edje_object_signal_callback_del_full(VIEW(it), "elm,action,expand,toggle",
1830 "elm", _expand_toggle_signal_cb, it);
1831 edje_object_signal_callback_del_full(VIEW(it), "elm,action,expand", "elm",
1832 _expand_signal_cb, it);
1833 edje_object_signal_callback_del_full(VIEW(it), "elm,action,contract", "elm",
1834 _contract_signal_cb, it);
1838 _item_realize(Elm_Gen_Item *it,
1841 const char *treesize;
1844 if (it->realized) return;
1845 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
1846 ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd);
1848 it->realized = EINA_TRUE;
1850 if (!_item_cache_pop(it))
1851 VIEW(it) = _view_create(it, it->itc->item_style);
1853 //TIZEN_ONLY(20161013): clean up elm color class feature
1854 if (it->base->color_classes)
1855 _elm_widget_item_color_class_update(it->base);
1858 treesize = edje_object_data_get(VIEW(it), "treesize");
1861 int tsize = atoi(treesize);
1864 (GL_IT(it->parent)->type == ELM_GENLIST_ITEM_TREE))
1867 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1868 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1869 evas_object_size_hint_min_set
1870 (it->spacer, (GL_IT(it)->expanded_depth * tsize) *
1871 elm_config_scale_get(), 1);
1872 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1875 _view_inflate(VIEW(it), it, &it->content_objs);
1876 if (wd->scroll_item_align_enable && !calc)
1878 const char *vi_effect = edje_object_data_get(VIEW(it), "vi_effect");
1879 if (vi_effect && !strcmp(vi_effect, "on"))
1881 Evas_Object *clip = evas_object_clip_get(VIEW(it));
1882 if (clip) evas_object_data_set(VIEW(it), "view,clip", clip);
1883 else clip = evas_object_data_get(VIEW(it), "view,clip");
1885 if (!it->item->proxy)
1887 it->item->proxy = evas_object_image_filled_add(evas_object_evas_get(wd->obj));
1888 evas_object_smart_member_add(it->item->proxy, sd->pan_obj);
1890 evas_object_clip_set(it->item->proxy, clip);
1891 if (evas_object_clip_get(VIEW(it))) evas_object_clip_unset(VIEW(it));
1892 evas_object_image_source_set(it->item->proxy, VIEW(it));
1893 evas_object_image_source_visible_set(it->item->proxy, EINA_FALSE);
1894 evas_object_image_source_events_set(it->item->proxy, EINA_TRUE);
1895 evas_object_image_source_clip_set(it->item->proxy, EINA_FALSE);
1896 evas_object_size_hint_min_set(it->item->proxy, GL_IT(it)->w, GL_IT(it)->h);
1897 evas_object_repeat_events_set(it->item->proxy, EINA_TRUE);
1901 _item_mouse_callbacks_add(it, VIEW(it));
1902 // Expand can be supported by only VIEW(it)
1903 _item_edje_callbacks_add(it);
1905 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()))
1906 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
1908 edje_object_signal_emit(VIEW(it), SIGNAL_ENABLED, "elm");
1911 if (!TIZEN_PROFILE_WEARABLE)
1913 if (sd->banded_bg_on)
1914 _banded_item_bg_color_change(it, EINA_TRUE);
1916 edje_object_signal_emit(VIEW(it), SIGNAL_HIGHLIGHTED, "elm");
1917 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
1919 if (GL_IT(it)->expanded)
1920 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
1921 if (sd->reorder_force || sd->reorder_mode)
1922 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
1923 if (GL_IT(it)->expanded_depth > 0)
1924 edje_object_signal_emit(VIEW(it), SIGNAL_BG_CHANGE, "elm");
1927 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_contents,
1929 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
1932 if (elm_widget_focus_highlight_enabled_get(WIDGET(it)) && (it == sd->focused_item))
1934 edje_object_signal_emit(VIEW(it), SIGNAL_FOCUSED, "elm");
1936 if (sd->decorate_all_mode && it->itc->decorate_all_item_style)
1938 _decorate_all_item_realize(it, EINA_FALSE);
1940 else if (it->decorate_it_set && it->itc->decorate_item_style &&
1941 (sd->mode_item == it))
1943 _decorate_item_realize(it);
1945 it->realized = EINA_TRUE;
1948 _elm_genlist_item_index_update(it);
1950 if (it->tooltip.content_cb)
1953 elm_wdg_item_tooltip_content_cb_set(
1954 it->tooltip.content_cb, it->tooltip.data, NULL),
1955 elm_wdg_item_tooltip_style_set(it->tooltip.style),
1956 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
1958 if (it->mouse_cursor)
1959 eo_do(EO_OBJ(it), elm_wdg_item_cursor_set(it->mouse_cursor));
1961 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
1962 if (_elm_atspi_enabled())
1964 elm_interface_atspi_accessible_added(EO_OBJ(it));
1965 elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
1968 if (!TIZEN_PROFILE_WEARABLE)
1969 _banded_item_bg_add(it, VIEW(it));
1971 // Register accessibility before realized callback
1972 // because user can customize accessibility.
1973 _access_widget_item_register(it);
1974 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, EO_OBJ(it));
1976 edje_object_message_signal_process(VIEW(it));
1977 if (it->deco_all_view)
1978 edje_object_message_signal_process(it->deco_all_view);
1979 if (GL_IT(it)->resized)
1981 sd->queue = eina_list_remove(sd->queue, it);
1982 GL_IT(it)->queued = EINA_FALSE;
1983 GL_IT(it)->resized = EINA_FALSE;
1984 GL_IT(it)->calc_done = EINA_FALSE;
1985 GL_IT(it)->block->calc_done = EINA_FALSE;
1986 sd->calc_done = EINA_FALSE;
1988 if (sd->atspi_item_to_highlight == it)
1990 sd->atspi_item_to_highlight = NULL;
1991 elm_object_accessibility_highlight_set(EO_OBJ(it), EINA_TRUE);
1992 //TIZEN_ONLY(20170724): grab highlight using unrealized item
1993 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it),
1994 ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
1995 evas_object_smart_callback_call(WIDGET(it),
1996 SIG_WIDGET_ATSPI_HIGHLIGHTED, EO_OBJ(it));
2002 _reorder_anim(void *data)
2006 Elm_Genlist_Data *sd = data;
2007 Evas_Coord oy, r_y, r_y_scrl, r_y_scrl_max, r_offset;
2008 evas_object_geometry_get(sd->pan_obj, NULL, &oy, NULL, NULL);
2010 r_y = sd->reorder.it->y + sd->reorder.it->item->block->y;
2011 r_y_scrl = sd->reorder.it->item->scrl_y;
2012 r_y_scrl_max = r_y_scrl + sd->reorder.it->item->h;
2015 // FIXME: 1. Reorder animation time should be equal regardless of item's height
2016 // 2. All item have same animation speed in reordering.
2017 // To support 1 and 2, offset value is scaled to reorder item's height.
2018 r_offset = (Evas_Coord) (GL_IT(sd->reorder.it)->h / REORDER_ANIM_OFFSET);
2019 if (r_offset < REORDER_ANIM_OFFSET) r_offset = REORDER_ANIM_OFFSET;
2022 EINA_LIST_FOREACH(sd->reorder.move_items, l, it)
2024 Evas_Coord it_y, it_y_scrl_center;
2025 it_y = it->y + GL_IT(it)->block->y;
2026 it_y_scrl_center = GL_IT(it)->scrl_y + (GL_IT(it)->h / 2);
2028 if ((sd->reorder.dir == -1) && (r_y_scrl <= it_y_scrl_center))
2029 GL_IT(it)->reorder_offset += r_offset;
2030 else if ((sd->reorder.dir == 1) && (r_y_scrl_max >= it_y_scrl_center))
2031 GL_IT(it)->reorder_offset -= r_offset;
2035 if (sd->reorder.it->item->h < GL_IT(it)->reorder_offset)
2036 GL_IT(it)->reorder_offset = sd->reorder.it->item->h;
2037 else if (0 > GL_IT(it)->reorder_offset)
2038 GL_IT(it)->reorder_offset = 0;
2040 else if (r_y < it_y)
2042 if (-(sd->reorder.it->item->h) > GL_IT(it)->reorder_offset)
2043 GL_IT(it)->reorder_offset = -(sd->reorder.it->item->h);
2044 else if (0 < GL_IT(it)->reorder_offset)
2045 GL_IT(it)->reorder_offset = 0;
2048 if (!sd->reorder.move_items)
2050 sd->reorder.anim = NULL;
2051 return ECORE_CALLBACK_CANCEL;
2054 _changed(sd->pan_obj);
2055 return ECORE_CALLBACK_RENEW;
2059 _reorder_space_get(Elm_Gen_Item *it)
2061 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2062 Evas_Coord oy, r_y, it_y, r_y_scrl, r_y_scrl_max, it_y_center;
2063 evas_object_geometry_get(sd->pan_obj, NULL, &oy, NULL, NULL);
2065 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) return 0;
2066 if (sd->reorder.it->parent != it->parent) return 0;
2068 r_y = sd->reorder.it->y + sd->reorder.it->item->block->y;
2069 it_y = it->y + GL_IT(it)->block->y;
2071 r_y_scrl = sd->reorder.it->item->scrl_y;
2072 r_y_scrl_max = r_y_scrl + sd->reorder.it->item->h;
2073 it_y_center = it_y + (GL_IT(it)->h / 2) - sd->pan_y + oy;
2075 if ((r_y > it_y) && (r_y_scrl <= it_y_center))
2077 if (!eina_list_data_find(sd->reorder.move_items, it))
2078 sd->reorder.move_items = eina_list_append(sd->reorder.move_items, it);
2079 if (!sd->reorder.anim)
2080 sd->reorder.anim = ecore_animator_add(_reorder_anim,
2083 else if ((r_y < it_y) && (r_y_scrl_max >= it_y_center))
2085 if (!eina_list_data_find(sd->reorder.move_items, it))
2086 sd->reorder.move_items = eina_list_append(sd->reorder.move_items, it);
2087 if (!sd->reorder.anim)
2088 sd->reorder.anim = ecore_animator_add(_reorder_anim,
2091 return GL_IT(it)->reorder_offset;
2095 _reorder_calc(Elm_Gen_Item *it, Elm_Genlist_Data *sd)
2097 Elm_Gen_Item *git = NULL;
2098 Elm_Gen_Item *ngit = NULL;
2100 Evas_Coord ox, oy, ow, oh;
2101 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
2103 // Do not cross the parent group items and
2104 // Do not exceeds viewport
2106 ngit = eina_list_data_get(eina_list_next
2107 (eina_list_data_find_list
2108 (sd->group_items, git)));
2109 if (git && git->realized && (GL_IT(it)->scrl_y <= (GL_IT(git)->scrl_y + GL_IT(git)->h)))
2111 GL_IT(it)->scrl_y = GL_IT(git)->scrl_y + GL_IT(git)->h;
2113 else if (ngit && ngit->realized && (GL_IT(it)->scrl_y >= (GL_IT(ngit)->scrl_y - GL_IT(it)->h)))
2115 GL_IT(it)->scrl_y = GL_IT(ngit)->scrl_y - GL_IT(ngit)->h;
2118 if (GL_IT(it)->scrl_y < oy)
2120 GL_IT(it)->scrl_y = oy;
2121 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(sd->pan_x, sd->pan_y
2122 - REORDER_FASTER, ow, oh));
2124 else if (GL_IT(it)->scrl_y + GL_IT(it)->h > oy + oh)
2126 GL_IT(it)->scrl_y = oy + oh - GL_IT(it)->h;
2127 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(sd->pan_x, sd->pan_y
2128 + REORDER_FASTER, ow, oh));
2131 if (TIZEN_PROFILE_WEARABLE)
2133 _item_all_position(it, GL_IT(it)->scrl_x - REORDERED_ITEM_OFFSET,
2134 GL_IT(it)->scrl_y - REORDERED_ITEM_OFFSET);
2138 _item_all_position(it, GL_IT(it)->scrl_x, GL_IT(it)->scrl_y - REORDERED_ITEM_OFFSET);
2141 if (it->deco_all_view)
2142 evas_object_raise(it->deco_all_view);
2143 else if (GL_IT(it)->deco_it_view)
2144 evas_object_raise(GL_IT(it)->deco_it_view);
2146 evas_object_raise(VIEW(it));
2149 #ifdef GENLIST_FX_SUPPORT
2151 _add_fx_anim(void *data)
2153 Elm_Genlist_Data *sd = data;
2158 _changed(sd->pan_obj);
2159 if (sd->add_fx.cnt <= 0)
2161 while (sd->add_fx.items)
2163 it = eina_list_data_get(sd->add_fx.items);
2164 sd->add_fx.items = eina_list_remove(sd->add_fx.items, it);
2165 if (it->deco_all_view)
2166 evas_object_color_set(it->deco_all_view, 255, 255, 255, 255);
2167 else if (it->item->deco_it_view)
2168 evas_object_color_set(it->item->deco_it_view, 255, 255, 255, 255);
2170 evas_object_color_set(VIEW(it), 255, 255, 255, 255);
2172 sd->add_fx.cnt = ANIM_CNT_MAX;
2173 sd->add_fx.anim = NULL;
2174 return ECORE_CALLBACK_CANCEL;
2176 return ECORE_CALLBACK_RENEW;
2180 _add_fx_space_get(Elm_Gen_Item *it)
2183 Elm_Genlist_Data *sd = it->item->wsd;
2184 Evas_Coord size = 0;
2186 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2187 else if (it->item->deco_it_view) evas_object_raise(it->item->deco_it_view);
2188 else if (VIEW(it)) evas_object_raise(VIEW(it));
2190 itt = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
2191 while (itt && itt->realized)
2193 if (eina_list_data_find_list(sd->add_fx.items, itt))
2195 size += itt->item->minh;
2197 itt = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(itt)->prev);
2199 size = size * ((double)sd->add_fx.cnt/ANIM_CNT_MAX);
2204 _del_fx_anim(void *data)
2206 Elm_Genlist_Data *sd = data;
2211 _changed(sd->pan_obj);
2212 if (sd->del_fx.cnt <= 0)
2214 while (sd->del_fx.pending_items)
2216 it = eina_list_data_get(sd->del_fx.pending_items);
2217 sd->del_fx.pending_items = eina_list_remove(sd->del_fx.pending_items, it);
2220 while (sd->del_fx.items)
2222 it = eina_list_data_get(sd->del_fx.items);
2223 sd->del_fx.items = eina_list_remove(sd->del_fx.items, it);
2224 if (it->deco_all_view)
2225 evas_object_color_set(it->deco_all_view, 255, 255, 255, 255);
2226 else if (it->item->deco_it_view)
2227 evas_object_color_set(it->item->deco_it_view, 255, 255, 255, 255);
2229 evas_object_color_set(VIEW(it), 255, 255, 255, 255);
2232 sd->del_fx.cnt = ANIM_CNT_MAX;
2233 sd->del_fx.anim = NULL;
2234 return ECORE_CALLBACK_CANCEL;
2236 return ECORE_CALLBACK_RENEW;
2240 _del_fx_space_get(Elm_Gen_Item *it)
2243 Elm_Genlist_Data *sd = it->item->wsd;
2244 Evas_Coord size = 0;
2246 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2247 else if (it->item->deco_it_view) evas_object_raise(it->item->deco_it_view);
2248 else if (VIEW(it)) evas_object_raise(VIEW(it));
2249 itt = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
2250 while (itt && itt->realized)
2252 if (eina_list_data_find_list(sd->del_fx.items, itt))
2254 size += itt->item->minh;
2256 itt = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(itt)->prev);
2258 size = size * (1 - ((double)sd->del_fx.cnt/ANIM_CNT_MAX));
2264 _item_block_realize(Item_Block *itb, Eina_Bool force)
2266 Elm_Genlist_Data *sd = itb->sd;
2268 Elm_Gen_Item *aligned_item = NULL;
2269 Elm_Gen_Item *top_drawn_item = NULL;
2270 const Eina_List *l, *ll;
2271 Evas_Object *content;
2272 Eina_Bool unrealize = EINA_TRUE;
2273 Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0, cvx = 0, cvy = 0, cvw = 0, cvh = 0;
2274 ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wsd);
2276 // Do not check itb->realized
2277 // because it->item->block can be changed
2279 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
2280 evas_output_viewport_get(evas_object_evas_get(sd->obj),
2281 &cvx, &cvy, &cvw, &cvh);
2283 if (_elm_config->access_mode || _elm_atspi_enabled())
2285 // If access is on, realize more items (3 times)
2289 #ifdef GENLIST_FX_SUPPORT
2290 else if (sd->del_fx.anim)
2293 EINA_LIST_FOREACH(sd->del_fx.items, l, it)
2295 size += it->item->minh;
2299 else if (sd->add_fx.anim)
2302 EINA_LIST_FOREACH(sd->add_fx.items, l, it)
2304 size += it->item->minh;
2310 if (sd->reorder.it) _reorder_calc(sd->reorder.it, sd);
2311 EINA_LIST_FOREACH(itb->items, l, it)
2313 if (sd->reorder.it == it) continue;
2314 if (!it->filtered) _item_filtered_get(it);
2315 if (it->want_hidden)
2317 if (it->realized) evas_object_hide(VIEW(it));
2320 GL_IT(it)->scrl_x = it->x + itb->x - sd->pan_x + ox;
2321 GL_IT(it)->scrl_y = it->y + itb->y - sd->pan_y + oy;
2322 GL_IT(it)->w = sd->minw;
2323 GL_IT(it)->h = GL_IT(it)->minh;
2325 if (!TIZEN_PROFILE_WEARABLE)
2328 if (!top_drawn_item)
2330 if (GL_IT(it)->scrl_y <= oy && ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
2331 GL_IT(it)->w, GL_IT(it)->h, ox, oy, ow, oh))
2333 top_drawn_item = it;
2334 sd->top_drawn_item = top_drawn_item;
2339 if (wsd->scroll_item_align_enable)
2341 if (!sd->aligned_item)
2343 if (ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
2344 GL_IT(it)->w, GL_IT(it)->h,
2345 ox + ow / 2, oy + oh / 2, 1, 1))
2346 aligned_item = sd->aligned_item = it;
2349 if (force || sd->realization_mode ||
2351 (ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
2352 GL_IT(it)->w, GL_IT(it)->h,
2353 cvx, cvy, cvw, cvh)))
2355 if (!it->realized) _item_realize(it, EINA_FALSE);
2357 GL_IT(it)->scrl_y += _reorder_space_get(it);
2358 #ifdef GENLIST_FX_SUPPORT
2359 if (sd->del_fx.anim && !eina_list_data_find(sd->del_fx.items, it))
2360 it->item->scrl_y -= _del_fx_space_get(it);
2361 if (sd->add_fx.anim && !eina_list_data_find(sd->add_fx.items, it))
2362 it->item->scrl_y -= _add_fx_space_get(it);
2365 _item_all_position(it, GL_IT(it)->scrl_x, GL_IT(it)->scrl_y);
2367 else if (it->realized)
2369 /* FIXME: when content is on focused and unrealize item,
2370 focus is set to other object and scroll will be bring in */
2371 if (_elm_config->access_mode)
2373 EINA_LIST_FOREACH(it->content_objs, ll, content)
2375 if (elm_object_focus_get(content))
2377 unrealize = EINA_FALSE;
2383 _item_unrealize(it, EINA_FALSE);
2384 unrealize = EINA_TRUE;
2388 itb->realized = EINA_TRUE;
2390 if (!TIZEN_PROFILE_WEARABLE)
2392 if (sd->banded_bg_on)
2393 _banded_item_bg_index_color_set(sd->top_drawn_item, ox, oy, ow, oh);
2398 edje_object_signal_emit(VIEW(aligned_item), SIGNAL_ITEM_HIGHLIGHTED, "elm");
2399 _focus_bg_show(aligned_item);
2401 edje_object_message_signal_process(VIEW(sd->aligned_item));
2405 // FIXME: Remove below macro after opensource is patched
2406 #define EINA_INLIST_REVERSE_FOREACH_FROM(list, it) \
2407 for (it = NULL, it = (list ? _EINA_INLIST_CONTAINER(it, list) : NULL); \
2408 it; it = (EINA_INLIST_GET(it)->prev ? _EINA_INLIST_CONTAINER(it, EINA_INLIST_GET(it)->prev) : NULL))
2411 _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
2413 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2416 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2417 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2419 //FIXME: This is for optimizing genlist calculation after
2420 // genlist sizing eval properly.
2421 if (ow <= 1) return;
2423 _calc((void *)psd->wsd);
2425 if (_elm_config->access_mode || _elm_atspi_enabled())
2427 // If access is on, realize more items (3 times)
2431 #ifdef GENLIST_FX_SUPPORT
2432 else if (psd->wsd->del_fx.anim)
2437 EINA_LIST_FOREACH(psd->wsd->del_fx.items, l, it)
2439 size += it->item->minh;
2443 else if (psd->wsd->add_fx.anim)
2448 EINA_LIST_FOREACH(psd->wsd->add_fx.items, l, it)
2450 size += it->item->minh;
2456 // Belows are tweaks for performance
2457 // Block is not needed anymore because of below algorithm..
2458 // later, we should remove dirty block algorithm
2459 Eina_Inlist *start = NULL;
2460 Eina_List *realized_new = NULL;
2461 Eina_Bool flag = EINA_FALSE;
2462 if ((psd->wsd->blocks_realized) && (psd->wsd->dir == -1) &&
2463 (!_elm_config->access_mode) && (!_elm_atspi_enabled()))
2465 start = EINA_INLIST_GET((Item_Block *)eina_list_data_get
2466 (eina_list_last(psd->wsd->blocks_realized)));
2467 EINA_INLIST_REVERSE_FOREACH_FROM(start, itb)
2469 Evas_Coord itb_x, itb_y, itb_w, itb_h;
2470 itb_x = itb->x - psd->wsd->pan_x + ox;
2471 itb_y = itb->y - psd->wsd->pan_y + oy;
2472 itb_w = psd->wsd->minw;
2474 if (psd->wsd->realization_mode ||
2475 ELM_RECTS_INTERSECT(itb_x, itb_y, itb_w, itb_h,
2476 cvx, cvy, cvw, cvh))
2479 realized_new = eina_list_prepend(realized_new, itb);
2480 _item_block_realize(itb, EINA_FALSE);
2484 _item_block_unrealize(itb);
2489 else if ((psd->wsd->blocks_realized) && (psd->wsd->dir == 1) &&
2490 (!_elm_config->access_mode) && (!_elm_atspi_enabled()))
2492 start = EINA_INLIST_GET((Item_Block *)eina_list_data_get
2493 (psd->wsd->blocks_realized));
2494 EINA_INLIST_FOREACH(start, itb)
2496 Evas_Coord itb_x, itb_y, itb_w, itb_h;
2497 itb_x = itb->x - psd->wsd->pan_x + ox;
2498 itb_y = itb->y - psd->wsd->pan_y + oy;
2499 itb_w = psd->wsd->minw;
2501 if (psd->wsd->realization_mode ||
2502 ELM_RECTS_INTERSECT(itb_x, itb_y, itb_w, itb_h,
2503 cvx, cvy, cvw, cvh))
2506 realized_new = eina_list_append(realized_new, itb);
2507 _item_block_realize(itb, EINA_FALSE);
2511 _item_block_unrealize(itb);
2518 if (!psd->wsd->show_item)
2520 EINA_INLIST_FOREACH(psd->wsd->blocks, itb)
2522 Evas_Coord itb_x, itb_y, itb_w, itb_h;
2523 itb_x = itb->x - psd->wsd->pan_x + ox;
2524 itb_y = itb->y - psd->wsd->pan_y + oy;
2525 itb_w = psd->wsd->minw;
2527 if (psd->wsd->realization_mode ||
2528 ELM_RECTS_INTERSECT(itb_x, itb_y, itb_w, itb_h,
2529 cvx, cvy, cvw, cvh))
2531 realized_new = eina_list_append(realized_new, itb);
2532 _item_block_realize(itb, EINA_FALSE);
2536 _item_block_unrealize(itb);
2541 eina_list_free(psd->wsd->blocks_realized);
2542 psd->wsd->blocks_realized = realized_new;
2544 // TIZEN_ONLY(20150701) : banded color background feature. enabled only un-scrollable
2545 if (!TIZEN_PROFILE_WEARABLE)
2547 if (psd->wsd->banded_bg_rect && !psd->wsd->reorder.it)
2549 Evas_Coord bg_x, bg_y, bg_w, bg_h, svy, svh;
2550 Elm_Gen_Item *tmp = NULL, *prev = NULL;
2552 tmp = ELM_GEN_ITEM_FROM_INLIST(psd->wsd->items->last);
2556 if (tmp->want_hidden || !tmp->realized )
2557 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
2562 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
2566 if(prev->want_hidden)
2567 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2576 eo_do(psd->wsd->obj, elm_interface_scrollable_content_viewport_geometry_get
2577 (NULL, &svy, NULL, &svh));
2579 bg_x = GL_IT(tmp)->scrl_x;
2580 bg_y = GL_IT(tmp)->scrl_y + GL_IT(tmp)->h;
2581 bg_w = GL_IT(tmp)->w;
2582 bg_h = svy + svh - bg_y;
2584 evas_object_stack_below(psd->wsd->banded_bg_rect, VIEW(tmp));
2585 evas_object_resize(psd->wsd->banded_bg_rect, bg_w, bg_h);
2586 evas_object_move(psd->wsd->banded_bg_rect, bg_x, bg_y);
2588 //GET COLOR OF LAST ITEM AND SET NEXT COLOR TO BANDED BG RECT
2589 if (psd->wsd->banded_bg_on)
2592 index = GL_IT(tmp)->banded_color_index + 1;
2595 int sign = GL_IT(tmp)->banded_color_index - GL_IT(prev)->banded_color_index;
2599 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2603 if(prev->want_hidden)
2604 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2612 sign = GL_IT(tmp)->banded_color_index - GL_IT(prev)->banded_color_index;
2615 index = GL_IT(tmp)->banded_color_index + sign;
2617 if (index < 0) index += 2;
2618 else if (index >= BANDED_MAX_ITEMS)
2619 index = BANDED_MAX_ITEMS - 2;
2622 int alpha = 255 * (1 - 0.04 * index);
2623 int color = (250 * alpha) / 255;
2625 evas_object_color_set(psd->wsd->banded_bg_rect, color, color, color, alpha);
2629 evas_object_color_set
2630 (psd->wsd->banded_bg_rect, 0, 0, 0, 0);
2633 evas_object_show(psd->wsd->banded_bg_rect);
2639 if (psd->wsd->comp_y)
2641 psd->wsd->unhighlight_skip = EINA_TRUE;
2642 eo_do((psd->wsd)->obj, elm_interface_scrollable_content_region_show(psd->wsd->pan_x,
2643 psd->wsd->pan_y + psd->wsd->comp_y, ow, oh));
2644 psd->wsd->comp_y = 0;
2645 psd->wsd->unhighlight_skip = EINA_FALSE;
2647 else if (psd->wsd->expanded_item &&
2648 GL_IT(psd->wsd->expanded_item)->calc_done)
2651 Evas_Coord size = GL_IT(psd->wsd->expanded_item)->minh;
2652 Elm_Object_Item *eo_tmp;
2653 EINA_LIST_FOREACH(psd->wsd->expanded_item->item->items, l, eo_tmp)
2655 ELM_GENLIST_ITEM_DATA_GET(eo_tmp, tmp);
2656 size += GL_IT(tmp)->minh;
2659 elm_genlist_item_bring_in
2660 (EO_OBJ(psd->wsd->expanded_item),
2661 ELM_GENLIST_ITEM_SCROLLTO_TOP);
2664 eo_tmp = eina_list_data_get
2665 (eina_list_last(psd->wsd->expanded_item->item->items));
2668 elm_genlist_item_bring_in(eo_tmp,
2669 ELM_GENLIST_ITEM_SCROLLTO_IN);
2671 psd->wsd->expanded_item = NULL;
2673 if (psd->wsd->show_item &&
2674 !psd->wsd->show_item->item->queued &&
2675 psd->wsd->show_item->item->calc_done &&
2676 psd->wsd->show_item->item->block->calc_done &&
2677 psd->wsd->calc_done)
2679 Evas_Coord x, y, w, h;
2680 Elm_Gen_Item *it = psd->wsd->show_item;
2681 psd->wsd->show_item = NULL;
2682 x = it->x + GL_IT(it)->block->x + psd->wsd->pan_x;
2683 y = it->y + GL_IT(it)->block->y;
2687 switch (psd->wsd->scroll_to_type)
2689 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2693 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2694 y = y - (oh / 2) + (GL_IT(it)->h / 2);
2697 case ELM_GENLIST_ITEM_SCROLLTO_BOTTOM:
2698 y = y - oh + GL_IT(it)->h;
2704 if (psd->wsd->bring_in)
2705 eo_do(WIDGET(it), elm_interface_scrollable_region_bring_in(x, y, w, h));
2708 if (psd->wsd->aligned_item && (psd->wsd->aligned_item != psd->wsd->adjusted_item))
2709 edje_object_signal_emit(VIEW(psd->wsd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
2710 psd->wsd->aligned_item = NULL;
2711 psd->wsd->unhighlight_skip = EINA_TRUE;
2712 eo_do(WIDGET(it), elm_interface_scrollable_content_region_show(x, y, ow, oh));
2713 psd->wsd->unhighlight_skip = EINA_FALSE;
2716 _changed(psd->wsd->pan_obj);
2718 #ifdef GENLIST_FX_SUPPORT
2719 if (psd->wsd->add_fx.anim)
2724 int alpha = 255 * (1 - ((double)psd->wsd->add_fx.cnt/ANIM_CNT_MAX));
2725 EINA_LIST_FOREACH(psd->wsd->add_fx.items, l, it)
2727 if (!it->realized) continue;
2728 if (it->deco_all_view)
2729 evas_object_color_set(it->deco_all_view, alpha, alpha, alpha, alpha);
2730 else if (it->item->deco_it_view)
2731 evas_object_color_set(it->item->deco_it_view, alpha, alpha, alpha, alpha);
2733 evas_object_color_set(VIEW(it), alpha, alpha, alpha, alpha);
2736 if (psd->wsd->del_fx.anim)
2741 int alpha = 255 * ((double)psd->wsd->del_fx.cnt/ANIM_CNT_MAX);
2742 EINA_LIST_FOREACH(psd->wsd->del_fx.items, l, it)
2744 if (it->deco_all_view)
2745 evas_object_color_set(it->deco_all_view, alpha, alpha, alpha, alpha);
2746 else if (it->item->deco_it_view)
2747 evas_object_color_set(it->item->deco_it_view, alpha, alpha, alpha, alpha);
2749 evas_object_color_set(VIEW(it), alpha, alpha, alpha, alpha);
2753 eo_do(psd->wobj, eo_event_callback_call
2754 (ELM_INTERFACE_SCROLLABLE_EVENT_CHANGED, NULL));
2758 _elm_genlist_pan_eo_base_destructor(Eo *obj, Elm_Genlist_Pan_Data *psd)
2760 eo_data_unref(psd->wobj, psd->wsd);
2761 eo_do_super(obj, MY_PAN_CLASS, eo_destructor());
2765 _elm_genlist_pan_class_constructor(Eo_Class *klass)
2767 evas_smart_legacy_type_register(MY_PAN_CLASS_NAME_LEGACY, klass);
2770 #include "elm_genlist_pan.eo.c"
2772 //#ifdef ELM_FOCUSED_UI
2774 _item_multi_select_up(Elm_Genlist_Data *sd)
2776 Elm_Object_Item *prev;
2778 if (!sd->selected) return EINA_FALSE;
2779 if (!sd->multi) return EINA_FALSE;
2781 prev = elm_genlist_item_prev_get(sd->last_selected_item);
2782 if (!prev) return EINA_TRUE;
2784 if (elm_genlist_item_selected_get(prev))
2786 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2787 sd->last_selected_item = prev;
2788 elm_genlist_item_show
2789 (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2793 elm_genlist_item_selected_set(prev, EINA_TRUE);
2794 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
2800 _item_multi_select_down(Elm_Genlist_Data *sd)
2802 Elm_Object_Item *next;
2804 if (!sd->selected) return EINA_FALSE;
2805 if (!sd->multi) return EINA_FALSE;
2807 next = elm_genlist_item_next_get(sd->last_selected_item);
2808 if (!next) return EINA_TRUE;
2810 if (elm_genlist_item_selected_get(next))
2812 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2813 sd->last_selected_item = next;
2814 elm_genlist_item_show
2815 (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2819 elm_genlist_item_selected_set(next, EINA_TRUE);
2820 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
2827 _all_items_deselect(Elm_Genlist_Data *sd)
2829 if (!sd->selected) return EINA_FALSE;
2831 while (sd->selected)
2832 elm_genlist_item_selected_set(sd->selected->data, EINA_FALSE);
2838 _item_single_select_up(Elm_Genlist_Data *sd)
2840 Elm_Object_Item *eo_prev;
2845 prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2847 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2851 eo_prev = elm_genlist_item_prev_get(sd->last_selected_item);
2852 prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
2855 if (!prev) return EINA_FALSE;
2857 _all_items_deselect(sd);
2859 elm_genlist_item_selected_set(EO_OBJ(prev), EINA_TRUE);
2860 elm_genlist_item_show(EO_OBJ(prev), ELM_GENLIST_ITEM_SCROLLTO_IN);
2865 _item_single_select_down(Elm_Genlist_Data *sd)
2867 Elm_Object_Item *eo_next;
2872 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2874 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2878 eo_next = elm_genlist_item_next_get(sd->last_selected_item);
2879 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2882 if (!next) return EINA_FALSE;
2884 _all_items_deselect(sd);
2886 elm_genlist_item_selected_set(EO_OBJ(next), EINA_TRUE);
2887 elm_genlist_item_show
2888 (EO_OBJ(next), ELM_GENLIST_ITEM_SCROLLTO_IN);
2894 static void _item_unfocused(Elm_Gen_Item *it)
2897 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2898 if (!sd->focused_item || it != sd->focused_item) return;
2900 edje_object_signal_emit
2901 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
2902 if (sd->focused_item->deco_all_view)
2903 edje_object_signal_emit
2904 (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
2905 sd->focused_item = NULL;
2906 evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_UNFOCUSED, EO_OBJ(it));
2909 static void _item_focused(Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
2911 Evas_Coord x, y, w, h, sx, sy, sw, sh;
2913 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2915 evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
2916 evas_object_geometry_get(sd->obj, &sx, &sy, &sw, &sh);
2917 if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
2919 elm_genlist_item_bring_in(EO_OBJ(it), type);
2922 if (elm_widget_focus_highlight_enabled_get(sd->obj))
2924 if (it->deco_all_view)
2925 edje_object_signal_emit
2926 (it->deco_all_view, SIGNAL_FOCUSED, "elm");
2928 edje_object_signal_emit
2929 (VIEW(it), SIGNAL_FOCUSED, "elm");
2932 sd->focused_item = it;
2933 evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_FOCUSED, EO_OBJ(it));
2934 if (_elm_atspi_enabled())
2935 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), EO_OBJ(it));
2939 _banded_item_highlight_anim(void *data, double pos)
2941 Elm_Gen_Item *it = data;
2943 double v[4] = {0.25, 0.46, 0.45, 1.00};
2945 if (GL_IT(it)->banded_bg)
2948 frame = ecore_animator_pos_map_n(pos, ECORE_POS_MAP_CUBIC_BEZIER, 4, v);
2950 it->item->banded_anim = NULL;
2952 if (it->highlighted)
2953 frame = HIGHLIGHT_ALPHA_MAX + (1.0 - HIGHLIGHT_ALPHA_MAX) * (1.0 - frame);
2955 frame = HIGHLIGHT_ALPHA_MAX + (1.0 - HIGHLIGHT_ALPHA_MAX) * frame;
2957 int alpha = 255 * frame * (1 - 0.04 * GL_IT(it)->banded_color_index);
2960 color = (color * alpha) / 255;
2961 evas_object_color_set(GL_IT(it)->banded_bg, color, color, color, alpha);
2968 _item_highlight(Elm_Gen_Item *it)
2970 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2971 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wsd);
2974 if (!sd->highlight) return;
2975 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get())) return;
2976 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2977 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ) ||
2978 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2979 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
2981 if (it->highlighted) return;
2982 if (wsd->scroll_item_align_enable)
2984 if (sd->aligned_item == it)
2985 edje_object_signal_emit(wsd->resize_obj, SIGNAL_HIGHLIGHTED, "elm");
2990 it->highlighted = EINA_TRUE;
2991 sd->highlighted_item = it;
2993 if (!it->realized) goto end;
2995 if (!TIZEN_PROFILE_WEARABLE)
2997 if (sd->banded_bg_on)
2999 if (it->item->banded_anim) ecore_animator_del(it->item->banded_anim);
3000 it->item->banded_anim = ecore_animator_timeline_add(ELM_ITEM_HIGHLIGHT_TIMER, _banded_item_highlight_anim, it);
3003 if (it->deco_all_view)
3005 edje_object_signal_emit(it->deco_all_view, SIGNAL_HIGHLIGHTED, "elm");
3006 edje_object_message_signal_process(it->deco_all_view);
3008 edje_object_signal_emit(VIEW(it), SIGNAL_HIGHLIGHTED, "elm");
3009 edje_object_message_signal_process(VIEW(it));
3011 //***************** TIZEN Only
3012 // If check or radio is used on genlist item, highlight it also.
3014 Evas_Object *content;
3015 if (sd->decorate_all_mode)
3017 EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, content)
3019 const char *type = elm_widget_type_get(content);
3020 if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3021 elm_object_signal_emit(content, "elm,state,mouse,down", "elm");
3026 EINA_LIST_FOREACH(it->content_objs, l, content)
3028 const char *type = elm_widget_type_get(content);
3029 if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3030 elm_object_signal_emit(content, "elm,state,mouse,down", "elm");
3033 //****************************
3035 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
3036 if (_elm_atspi_enabled())
3037 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), EO_OBJ(it));
3041 _item_unhighlight(Elm_Gen_Item *it, Eina_Bool effect EINA_UNUSED)
3043 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wsd);
3044 if (!it->highlighted) return;
3046 it->highlighted = EINA_FALSE;
3047 GL_IT(it)->wsd->highlighted_item = NULL;
3049 if (!it->realized) goto end;
3051 if (!TIZEN_PROFILE_WEARABLE)
3053 if (GL_IT(it)->wsd->banded_bg_on && effect)
3055 if (it->item->banded_anim) ecore_animator_del(it->item->banded_anim);
3056 it->item->banded_anim = ecore_animator_timeline_add(ELM_ITEM_HIGHLIGHT_TIMER, _banded_item_highlight_anim, it);
3060 if (it->item->banded_anim) ELM_SAFE_FREE(it->item->banded_anim, ecore_animator_del);
3061 _banded_item_bg_color_change(it, EINA_FALSE);
3064 if (it->deco_all_view)
3065 edje_object_signal_emit(it->deco_all_view, SIGNAL_UNHIGHLIGHTED, "elm");
3066 edje_object_signal_emit(VIEW(it), SIGNAL_UNHIGHLIGHTED, "elm");
3067 if (wsd->scroll_item_align_enable)
3068 edje_object_signal_emit(wsd->resize_obj, SIGNAL_UNHIGHLIGHTED, "elm");
3070 edje_object_signal_emit(VIEW(it), SIGNAL_UNHIGHLIGHTED, "elm");
3071 //******************** TIZEN Only
3072 // If check is used on genlist item, unhighlight it also.
3074 Evas_Object *content;
3075 if (GL_IT(it)->wsd->decorate_all_mode)
3077 EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, content)
3079 const char *type = elm_widget_type_get(content);
3080 if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3081 elm_object_signal_emit(content, "elm,state,mouse,up", "elm");
3086 EINA_LIST_FOREACH(it->content_objs, l, content)
3088 const char *type = elm_widget_type_get(content);
3089 if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3090 elm_object_signal_emit(content, "elm,state,mouse,up", "elm");
3093 //*******************************
3095 evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, EO_OBJ(it));
3099 _item_unselect(Elm_Gen_Item *it)
3101 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
3103 if (!it->selected) return;
3105 it->selected = EINA_FALSE;
3106 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
3107 _item_unhighlight(it, EINA_TRUE);
3108 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, EO_OBJ(it));
3112 _item_select(Elm_Gen_Item *it)
3114 Evas_Object *obj = WIDGET(it);
3115 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
3117 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get())) return;
3118 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3119 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
3120 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3121 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
3123 if (sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS &&
3124 it->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS &&
3129 const Eina_List *l, *ll;
3130 Elm_Object_Item *eo_it2;
3131 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it2)
3132 if (eo_it2 != EO_OBJ(it))
3134 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
3135 _item_unselect(it2);
3141 sd->selected = eina_list_append(sd->selected, EO_OBJ(it));
3142 it->selected = EINA_TRUE;
3144 sd->last_selected_item = EO_OBJ(it);
3145 _item_highlight(it);
3147 if (sd->focused_content)
3149 elm_object_focus_set(sd->focused_content, EINA_FALSE);
3150 evas_object_focus_set(obj, EINA_TRUE);
3151 sd->focused_content = NULL;
3154 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3155 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3159 // FIXME: after evas_object_raise, mouse event callbacks(ex, UP, DOWN)
3160 // can be called again eventhough already received it.
3161 const char *selectraise = edje_object_data_get(VIEW(it), "selectraise");
3162 if ((selectraise) && (!strcmp(selectraise, "on")))
3164 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
3165 else evas_object_raise(VIEW(it));
3166 if ((GL_IT(it)->group_item) && (GL_IT(it)->group_item->realized))
3167 evas_object_raise(GL_IT(it)->VIEW(group_item));
3170 edje_object_signal_emit
3171 (VIEW(it), SIGNAL_CLICKED, "elm");
3172 edje_object_message_signal_process(VIEW(it));
3174 evas_object_ref(obj);
3175 if (it->func.func) it->func.func((void *)it->func.data, obj, EO_OBJ(it));
3176 if (EINA_MAGIC_CHECK(it->base, ELM_WIDGET_ITEM_MAGIC))
3177 evas_object_smart_callback_call(obj, SIG_SELECTED, EO_OBJ(it));
3178 evas_object_unref(obj);
3182 _highlight_timer(void *data)
3184 Elm_Gen_Item *it = data;
3185 GL_IT(it)->highlight_timer = NULL;
3186 _item_highlight(it);
3191 _select_timer(void *data)
3193 Elm_Gen_Item *it = data;
3194 GL_IT(it)->highlight_timer = NULL;
3196 if ((GL_IT(it)->wsd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS) ||
3197 (it->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS))
3201 // TIZEN Only(20150708) : unselect when selected item is selected again
3202 // There need to be implemented 'SELECT_UNSELECT' mode in elm_config
3203 // select mode for support upsteam and TIZEN both.
3204 if (!it->selected) _item_select(it);
3205 else _item_unselect(it);
3213 *_item_focusable_content_search(Evas_Object *obj, Eina_List *l, int dir)
3215 if ((dir != 1) && (dir != -1)) return NULL;
3217 Evas_Object *next = NULL;
3218 Elm_Object_Item *next_item = NULL;
3222 next = eina_list_data_get(l);
3223 if (next && (elm_widget_can_focus_get(next) &&
3224 (evas_object_visible_get(next))))
3226 else if (next && (elm_widget_child_can_focus_get(next)))
3228 if (elm_widget_focused_object_get(next))
3232 Evas_Object *child = next;
3234 (elm_widget_focus_next_get(next, ELM_FOCUS_RIGHT, &child, &next_item)))
3236 else if ((dir == -1) &&
3237 (elm_widget_focus_next_get(next, ELM_FOCUS_LEFT, &child, &next_item)))
3243 if (dir == 1) l = eina_list_next(l);
3244 else l = eina_list_prev(l);
3247 if (!next) next = obj;
3252 static Eina_Bool _item_focusable_search(Elm_Gen_Item **it, int dir)
3254 if (!(*it)) return EINA_FALSE;
3255 if ((dir != 1) && (dir != -1)) return EINA_FALSE;
3257 Elm_Gen_Item *tmp = *it;
3261 if (!elm_object_item_disabled_get(EO_OBJ(tmp)) &&
3262 (!tmp->want_hidden))
3264 if ((tmp->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
3265 (tmp->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3268 Evas_Object *obj = NULL;
3269 Eina_List *contents = NULL;
3271 contents = GL_IT(tmp)->flip_content_objs;
3274 contents = tmp->content_objs;
3275 if (tmp->deco_all_view)
3278 contents = GL_IT(tmp)->deco_all_contents;
3280 contents = eina_list_merge(contents,
3281 GL_IT(tmp)->deco_all_contents);
3286 obj = _item_focusable_content_search(NULL, contents, 1);
3289 contents = eina_list_last(contents);
3290 obj = _item_focusable_content_search(NULL, contents, -1);
3295 if (GL_IT(tmp)->wsd->focused_content)
3296 elm_object_focus_set(GL_IT(tmp)->wsd->focused_content, EINA_FALSE);
3297 GL_IT(tmp)->wsd->focused_content = obj;
3298 elm_object_focus_set(obj, EINA_TRUE);
3303 if (GL_IT(tmp)->wsd->focused_content)
3305 elm_object_focus_set(GL_IT(tmp)->wsd->focused_content, EINA_FALSE);
3306 evas_object_focus_set(WIDGET(tmp), EINA_TRUE);
3307 GL_IT(tmp)->wsd->focused_content = NULL;
3313 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->next);
3315 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
3322 static Eina_Bool _item_focus_next(Elm_Genlist_Data *sd, Focus_Dir dir)
3324 Elm_Gen_Item *it = NULL;
3325 Elm_Gen_Item *old_focused = sd->focused_item;
3326 Evas_Object *old_content = sd->focused_content;
3328 if (dir == FOCUS_DIR_DOWN || dir == FOCUS_DIR_UP)
3330 Eina_Bool find_item;
3332 if (dir == FOCUS_DIR_DOWN)
3334 if (sd->focused_item)
3336 it = ELM_GEN_ITEM_FROM_INLIST
3337 (EINA_INLIST_GET(sd->focused_item)->next);
3338 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3340 else it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
3341 find_item = _item_focusable_search(&it, 1);
3343 else if (dir == FOCUS_DIR_UP)
3345 if (sd->focused_item)
3347 it = ELM_GEN_ITEM_FROM_INLIST
3348 (EINA_INLIST_GET(sd->focused_item)->prev);
3349 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3351 else it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
3352 find_item = _item_focusable_search(&it, -1);
3361 sd->focused_content = old_content;
3362 elm_object_focus_set(old_content, EINA_TRUE);
3366 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3367 elm_object_item_focus_set(EO_OBJ(old_focused), EINA_TRUE);
3372 else if (!find_item)
3375 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3376 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3378 else if (dir == FOCUS_DIR_LEFT || dir == FOCUS_DIR_RIGHT)
3380 Evas_Object *obj = NULL;
3381 Eina_List *contents = NULL;
3382 Eina_List *l = NULL;
3384 if (!sd->focused_item) return EINA_FALSE;
3385 if (sd->focused_item->flipped)
3386 contents = GL_IT(sd->focused_item)->flip_content_objs;
3389 contents = sd->focused_item->content_objs;
3390 if (sd->focused_item->deco_all_view)
3393 contents = GL_IT(sd->focused_item)->deco_all_contents;
3395 contents = eina_list_merge(contents,
3396 GL_IT(sd->focused_item)->deco_all_contents);
3400 if (sd->focused_content)
3402 l = eina_list_data_find_list(contents,
3403 sd->focused_content);
3404 obj = sd->focused_content;
3407 if (dir == FOCUS_DIR_LEFT)
3409 if ((l) && (eina_list_prev(l)))
3411 l = eina_list_prev(l);
3412 obj = _item_focusable_content_search(obj, l, -1);
3413 if (!obj) obj = sd->focused_content;
3417 //search focused content is child of content
3418 if (sd->focused_content)
3419 l = eina_list_data_find_list(contents,
3420 sd->focused_content);
3421 if (!l) l = eina_list_last(contents);
3422 obj = _item_focusable_content_search(obj, l, -1);
3424 else obj = sd->focused_content;
3426 else if (dir == FOCUS_DIR_RIGHT)
3428 if ((l) && (eina_list_next(l)))
3430 l = eina_list_next(l);
3431 obj = _item_focusable_content_search(obj, l, 1);
3432 if (!obj) obj = sd->focused_content;
3436 //search focused content is child of content
3437 if (sd->focused_content)
3438 l = eina_list_data_find_list(contents,
3439 sd->focused_content);
3440 if (!l) l = contents;
3441 obj = _item_focusable_content_search(obj, l, 1);
3443 else obj = sd->focused_content;
3448 sd->focused_content = obj;
3449 elm_object_focus_set(obj, EINA_TRUE);
3453 sd->focused_content = NULL;
3457 else return EINA_FALSE;
3462 //#ifdef ELM_FOCUSED_UI
3463 EOLIAN static Eina_Bool
3464 _elm_genlist_elm_widget_event(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *src EINA_UNUSED, Evas_Callback_Type type, void *event_info)
3470 Evas_Coord step_x = 0;
3471 Evas_Coord step_y = 0;
3472 Evas_Coord page_x = 0;
3473 Evas_Coord page_y = 0;
3474 Evas_Event_Key_Down *ev = event_info;
3475 Evas_Coord pan_max_x = 0, pan_max_y = 0;
3477 //ELM_GENLIST_DATA_GET(obj, sd);
3479 // TIZEN ONLY(20131221) : When access mode, focused ui is disabled.
3480 if (_elm_config->access_mode) return EINA_FALSE;
3482 if ((type != EVAS_CALLBACK_KEY_DOWN) && (type != EVAS_CALLBACK_KEY_UP))
3484 if (!sd->items) return EINA_FALSE;
3485 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
3486 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
3489 elm_interface_scrollable_content_pos_get(&x, &y),
3490 elm_interface_scrollable_step_size_get(&step_x, &step_y),
3491 elm_interface_scrollable_page_size_get(&page_x, &page_y),
3492 elm_interface_scrollable_content_viewport_geometry_get
3493 (NULL, NULL, &v_w, &v_h));
3495 if ((!strcmp(ev->keyname, "Left")) ||
3496 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)) ||
3497 (!strcmp(ev->keyname, "Right")) ||
3498 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)) ||
3499 (!strcmp(ev->keyname, "Up")) ||
3500 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)) ||
3501 (!strcmp(ev->keyname, "Down")) ||
3502 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)) ||
3503 (!strcmp(ev->keyname, "Home")) ||
3504 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)) ||
3505 (!strcmp(ev->keyname, "End")) ||
3506 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)) ||
3507 (!strcmp(ev->keyname, "Prior")) ||
3508 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)) ||
3509 (!strcmp(ev->keyname, "Next")) ||
3510 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
3512 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3513 _elm_widget_focus_auto_show(obj);
3516 if ((!strcmp(ev->keyname, "Left")) ||
3517 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
3519 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3520 if (sd->select_on_focus_enabled) x -= step_x;
3523 if (_item_focus_next(sd, FOCUS_DIR_LEFT))
3525 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3532 else if ((!strcmp(ev->keyname, "Right")) ||
3533 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
3535 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3536 if (sd->select_on_focus_enabled) x += step_x;
3539 if (_item_focus_next(sd, FOCUS_DIR_RIGHT))
3541 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3548 else if ((!strcmp(ev->keyname, "Up")) ||
3549 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
3551 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3552 if (sd->select_on_focus_enabled)
3554 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
3555 (_item_multi_select_up(sd))) || (_item_single_select_up(sd)))
3557 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3563 if (_item_focus_next(sd, FOCUS_DIR_UP))
3565 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3572 else if ((!strcmp(ev->keyname, "Down")) ||
3573 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
3575 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3576 if (sd->select_on_focus_enabled)
3578 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
3579 (_item_multi_select_down(sd))) ||
3580 (_item_single_select_down(sd)))
3582 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3588 if (_item_focus_next(sd, FOCUS_DIR_DOWN))
3590 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3597 else if ((!strcmp(ev->keyname, "Home")) ||
3598 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
3600 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3601 if (sd->select_on_focus_enabled)
3603 Elm_Object_Item *it = elm_genlist_first_item_get(obj);
3604 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
3605 elm_genlist_item_selected_set(it, EINA_TRUE);
3606 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3610 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3611 _item_focus_next(sd, FOCUS_DIR_DOWN);
3612 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3616 else if ((!strcmp(ev->keyname, "End")) ||
3617 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
3619 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3620 if (sd->select_on_focus_enabled)
3622 Elm_Object_Item *it = elm_genlist_last_item_get(obj);
3623 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
3624 elm_genlist_item_selected_set(it, EINA_TRUE);
3628 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3629 sd->focused_item = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
3630 _item_focus_next(sd, FOCUS_DIR_UP);
3632 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3635 else if ((!strcmp(ev->keyname, "Prior")) ||
3636 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
3638 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3639 Elm_Gen_Item *it = sd->focused_item;
3640 Elm_Object_Item *eo_prev;
3642 while (page_y <= v_h)
3644 if (elm_genlist_item_prev_get(EO_OBJ(it)))
3646 eo_prev = elm_genlist_item_prev_get(EO_OBJ(it));
3647 it = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
3650 page_y += GL_IT(it)->minh;
3652 if (_item_focusable_search(&it, -1))
3654 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3655 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3659 _item_focusable_search(&it, 1);
3660 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3661 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3664 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3667 else if ((!strcmp(ev->keyname, "Next")) ||
3668 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
3670 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3671 Elm_Gen_Item *it = sd->focused_item;
3672 Elm_Object_Item *eo_next;
3674 page_y = GL_IT(it)->minh;
3676 while (page_y <= v_h)
3678 if (elm_genlist_item_next_get(EO_OBJ(it)))
3680 eo_next = elm_genlist_item_next_get(EO_OBJ(it));
3681 it = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
3684 page_y += GL_IT(it)->minh;
3686 if (_item_focusable_search(&it, 1))
3688 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3689 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3693 _item_focusable_search(&it, -1);
3694 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3695 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3698 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3699 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3701 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3704 else if (!strcmp(ev->keyname, "Escape"))
3706 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3707 if (!_all_items_deselect(sd)) return EINA_FALSE;
3708 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3711 else if (!strcmp(ev->keyname, "Return") ||
3712 !strcmp(ev->keyname, "KP_Enter") ||
3713 !strcmp(ev->keyname, "space"))
3716 if (type == EVAS_CALLBACK_KEY_DOWN && !sd->key_down_item)
3718 if (sd->focused_item)
3720 sd->key_down_item = sd->focused_item;
3722 edje_object_signal_emit
3723 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
3724 if (sd->focused_item->deco_all_view)
3725 edje_object_signal_emit
3726 (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
3728 _item_highlight(sd->key_down_item);
3729 if (sd->key_down_item->long_timer)
3730 ecore_timer_del(sd->key_down_item->long_timer);
3731 sd->key_down_item->long_timer = ecore_timer_add
3732 (sd->longpress_timeout,
3733 _long_press_cb, sd->key_down_item);
3734 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3735 evas_object_smart_callback_call(obj, SIG_ACTIVATED, EO_OBJ(sd->key_down_item));
3738 else return EINA_FALSE;
3740 else if (type == EVAS_CALLBACK_KEY_UP && sd->key_down_item)
3742 edje_object_signal_emit
3743 (VIEW(sd->key_down_item), SIGNAL_FOCUSED, "elm");
3744 if (sd->key_down_item->deco_all_view)
3745 edje_object_signal_emit
3746 (sd->key_down_item->deco_all_view, SIGNAL_FOCUSED, "elm");
3748 if (sd->key_down_item->long_timer)
3749 ecore_timer_del(sd->key_down_item->long_timer);
3750 sd->key_down_item->long_timer = NULL;
3751 if (GL_IT(sd->key_down_item)->highlight_timer)
3752 ecore_timer_del(GL_IT(sd->key_down_item)->highlight_timer);
3753 GL_IT(sd->key_down_item)->highlight_timer = ecore_timer_add
3754 (ITEM_SELECT_TIMER, _select_timer, sd->key_down_item);
3755 sd->key_down_item = NULL;
3756 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3759 else return EINA_FALSE;
3761 else return EINA_FALSE;
3763 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3764 eo_do(sd->pan_obj, elm_obj_pan_pos_max_get(&pan_max_x, &pan_max_y));
3766 if (x > pan_max_x) x = pan_max_x;
3768 if (y > pan_max_y) y = pan_max_y;
3770 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
3776 /* This function disables the specific code of the layout sub object add.
3777 * Only the widget sub_object_add is called.
3779 EOLIAN static Eina_Bool
3780 _elm_genlist_elm_layout_sub_object_add_enable(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3785 EOLIAN static Eina_Bool
3786 _elm_genlist_elm_widget_sub_object_add(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED, Evas_Object *sobj)
3788 Eina_Bool int_ret = EINA_FALSE;
3790 /* skipping layout's code, which registers size hint changing
3791 * callback on sub objects. this is here because items'
3792 * content_get() routines may change hints on the objects after
3793 * creation, thus issuing TOO MANY sizing_eval()'s here. they are
3794 * not needed at here anyway, so let's skip listening to those
3797 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_add(sobj));
3798 if (!int_ret) return EINA_FALSE;
3800 //if (!parent_parent->sub_object_add(obj, sobj))
3801 // return EINA_FALSE;
3806 EOLIAN static Eina_Bool
3807 _elm_genlist_elm_widget_sub_object_del(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *sobj)
3809 Eina_Bool int_ret = EINA_FALSE;
3811 /* XXX: hack -- also skipping sizing recalculation on
3812 * sub-object-del. genlist's crazy code paths (like groups and
3813 * such) seem to issue a whole lot of deletions and Evas bitches
3814 * about too many recalculations */
3815 sd->on_sub_del = EINA_TRUE;
3817 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_del(sobj));
3818 if (!int_ret) return EINA_FALSE;
3820 sd->on_sub_del = EINA_FALSE;
3826 _elm_genlist_focus_highlight_show(void *data EINA_UNUSED,
3828 const char *emission EINA_UNUSED,
3829 const char *src EINA_UNUSED)
3831 ELM_GENLIST_DATA_GET(obj, sd);
3833 if (sd->focused_item)
3835 if (!sd->focused_content)
3837 Eina_Bool found = EINA_FALSE;
3838 Elm_Gen_Item *it = sd->focused_item;
3839 found = _item_focusable_search(&it, 1);
3842 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3843 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3846 else elm_object_focus_set(sd->focused_content, EINA_TRUE);
3851 _elm_genlist_focus_highlight_hide(void *data EINA_UNUSED,
3853 const char *emission EINA_UNUSED,
3854 const char *src EINA_UNUSED)
3856 ELM_GENLIST_DATA_GET(obj, sd);
3857 if (sd->focused_item)
3859 // Do not use _item_unfocused because focus should be remained
3860 edje_object_signal_emit
3861 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
3862 if (sd->focused_item->deco_all_view)
3863 edje_object_signal_emit
3864 (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
3869 _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)
3871 Evas_Coord ox, oy, oh, ow, item_x = 0, item_y = 0, item_w = 0, item_h = 0;
3872 Elm_Gen_Item *focus_it;
3874 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
3876 if (sd->focused_item)
3878 focus_it = sd->focused_item;
3879 evas_object_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
3880 elm_widget_focus_highlight_focus_part_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
3892 if (item_y > (oy + oh - item_h))
3894 *y = oy + oh - item_h;
3897 if ((item_x + item_w) > (ox + ow))
3907 EOLIAN static Eina_Bool
3908 _elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd, Elm_Object_Item *item EINA_UNUSED)
3910 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
3911 Eina_Bool int_ret = EINA_FALSE;
3913 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_on_focus(NULL));
3914 if (!int_ret) return EINA_FALSE;
3916 if ((sd->items) && (sd->selected) && (!sd->last_selected_item))
3917 sd->last_selected_item = eina_list_data_get(sd->selected);
3919 if (sd->select_on_focus_enabled) return EINA_TRUE;
3920 if (elm_widget_focus_get(obj))
3922 // Do nothing if on_focus is called by child's parent_focus
3923 if (!wd->is_focus_target) return EINA_TRUE;
3925 if (sd->focused_item)
3927 if (!sd->focused_content)
3929 Eina_Bool found = EINA_FALSE;
3930 Elm_Gen_Item *it = sd->focused_item;
3931 found = _item_focusable_search(&it, 1);
3934 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3935 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3939 elm_object_focus_set(sd->focused_content, EINA_TRUE);
3943 Item_Block *itb, *nib;
3944 EINA_INLIST_FOREACH(sd->blocks, itb)
3948 Elm_Gen_Item *tmp = eina_list_data_get(itb->items);
3949 while(tmp && tmp->item->block == itb)
3953 Elm_Gen_Item *old = tmp;
3954 Evas_Coord x, y, w, h, sx, sy, sw, sh;
3955 evas_object_geometry_get(VIEW(tmp), &x, &y, &w, &h);
3956 evas_object_geometry_get(obj, &sx, &sy, &sw, &sh);
3957 /* Item is included viewport and focusable */
3958 if ((ELM_RECTS_INCLUDE(sx, sy, sw, sh, x, y, w, h)) &&
3959 (_item_focusable_search(&tmp, 1)))
3961 Eina_Bool include = EINA_TRUE;
3962 if (old != tmp && tmp->realized)
3964 evas_object_geometry_get(VIEW(tmp), &x, &y, &w, &h);
3965 evas_object_geometry_get(obj, &sx, &sy, &sw, &sh);
3966 include = ELM_RECTS_INCLUDE(sx, sy, sw, sh, x, y, w, h);
3968 else if (!tmp->realized) include = EINA_FALSE;
3972 elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
3979 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->next);
3982 nib = EINA_INLIST_CONTAINER_GET(EINA_INLIST_GET(itb)->next, Item_Block);
3983 if (!nib || !nib->realized) break;
3986 if (!sd->focused_item) _item_focus_next(sd, FOCUS_DIR_DOWN);
3991 // when key down and not called key up
3992 // and focus is not on genlist, call select_timer forcely
3993 if (sd->key_down_item)
3995 _select_timer(sd->key_down_item);
3996 sd->key_down_item = NULL;
3999 if (sd->focused_item)
4001 if (sd->focused_content)
4003 //FIXME: when genlist contents loose their focus,
4004 // focus unset should automatically work.
4005 elm_object_focus_set(sd->focused_content, EINA_FALSE);
4007 // Do not use _item_unfocused because focus should be remained
4008 edje_object_signal_emit
4009 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
4010 if (sd->focused_item->deco_all_view)
4011 edje_object_signal_emit
4012 (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
4020 _elm_genlist_item_elm_widget_item_focus_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool focused)
4022 Evas_Object *obj = WIDGET(it);
4023 ELM_GENLIST_DATA_GET(obj, sd);
4027 if (!elm_object_focus_get(obj))
4028 elm_object_focus_set(obj, EINA_TRUE);
4030 if (!elm_widget_focus_get(obj))
4033 if (sd->focused_content)
4035 elm_object_focus_set(sd->focused_content, EINA_FALSE);
4036 sd->focused_content = NULL;
4039 if (it != sd->focused_item)
4041 if (sd->focused_item)
4042 _item_unfocused(sd->focused_item);
4043 _item_focused(it, sd->focus_scrollto_type);
4045 /* If item is not realized state, widget couldn't get focus_highlight data. */
4048 _elm_widget_item_highlight_in_theme(obj, EO_OBJ(it));
4049 _elm_widget_highlight_in_theme_update(obj);
4050 _elm_widget_focus_highlight_start(obj);
4056 if (!elm_widget_focus_get(obj))
4058 _item_unfocused(it);
4062 EOLIAN static Eina_Bool
4063 _elm_genlist_item_elm_widget_item_focus_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
4065 Evas_Object *obj = WIDGET(it);
4066 ELM_GENLIST_DATA_GET(obj, sd);
4068 if (it == sd->focused_item)
4074 EOLIAN static Elm_Object_Item*
4075 _elm_genlist_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
4077 return EO_OBJ(sd->focused_item);
4080 static Eina_Bool _elm_genlist_smart_focus_next_enable = EINA_FALSE;
4082 EOLIAN static Eina_Bool
4083 _elm_genlist_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
4085 return _elm_genlist_smart_focus_next_enable;
4088 EOLIAN static Eina_Bool
4089 _elm_genlist_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
4094 EOLIAN static Eina_Bool
4095 _elm_genlist_elm_widget_focus_next(Eo *obj, Elm_Genlist_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
4097 Eina_List *items = NULL;
4098 Item_Block *itb = NULL;
4099 Elm_Object_Item *eo_it = NULL;
4101 if (!sd->blocks) return EINA_FALSE;
4102 if (!sd->is_access) return EINA_FALSE;
4104 if (!elm_widget_highlight_get(obj))
4106 if (ELM_FOCUS_PREVIOUS == dir)
4108 eo_it = elm_genlist_last_item_get(obj);
4109 itb = EINA_INLIST_CONTAINER_GET(sd->blocks->last, Item_Block);
4111 else if (ELM_FOCUS_NEXT == dir)
4113 eo_it = elm_genlist_first_item_get(obj);
4114 itb = EINA_INLIST_CONTAINER_GET(sd->blocks, Item_Block);
4116 else return EINA_FALSE;
4118 if (eo_it && itb && itb->calc_done)
4120 _item_block_realize(itb, EINA_TRUE);
4121 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
4123 else return EINA_FALSE;
4126 // FIXME: do not use realized items get
4127 // because of above forcing realization case.
4128 EINA_INLIST_FOREACH(sd->blocks, itb)
4133 if (!itb->realized) continue;
4135 EINA_LIST_FOREACH(itb->items, l, it)
4138 Evas_Object *c, *ret;
4141 if (!(it->realized)) continue;
4143 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_access_object_get()))
4144 items = eina_list_append(items, eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_access_object_get()));
4146 items = eina_list_append(items, VIEW(it));
4148 orders = (Eina_List *)elm_object_item_access_order_get(EO_OBJ(it));
4149 EINA_LIST_FOREACH(orders, ll, c)
4151 items = eina_list_append(items, c);
4156 return elm_widget_focus_list_next_get
4157 (obj, items, eina_list_data_get, dir, next, next_item);
4161 _mirrored_set(Evas_Object *obj,
4164 eo_do(obj, elm_interface_scrollable_mirrored_set(rtl));
4167 EOLIAN static Elm_Theme_Apply
4168 _elm_genlist_elm_widget_theme_apply(Eo *obj, Elm_Genlist_Data *sd)
4171 Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
4172 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wsd, ELM_THEME_APPLY_FAILED);
4174 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
4175 if (!int_ret) return ELM_THEME_APPLY_FAILED;
4177 if (!TIZEN_PROFILE_WEARABLE)
4178 _banded_bg_state_check(obj, sd);
4180 EINA_INLIST_FOREACH(sd->blocks, itb)
4184 EINA_LIST_FOREACH(itb->items, l, it)
4188 _item_unrealize(it, EINA_FALSE);
4189 GL_IT(it)->calc_done = EINA_FALSE;
4190 GL_IT(it)->block->calc_done = EINA_FALSE;
4192 else _item_queue(it, NULL);
4195 sd->calc_done = EINA_FALSE;
4196 _item_cache_all_free(sd);
4197 eina_hash_free_buckets(sd->size_caches);
4198 elm_layout_sizing_eval(obj);
4199 _changed(sd->pan_obj);
4201 if (wsd->scroll_item_align_enable && sd->aligned_item)
4202 elm_genlist_item_show(EO_OBJ(sd->aligned_item), ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
4207 /* FIXME: take off later. maybe this show region coords belong in the
4208 * interface (new api functions, set/get)? */
4210 _show_region_hook(void *data,
4213 Evas_Coord x, y, w, h;
4215 ELM_GENLIST_DATA_GET(data, sd);
4217 elm_widget_show_region_get(obj, &x, &y, &w, &h);
4218 //x & y are screen coordinates, Add with pan coordinates
4222 eo_do(obj, elm_interface_scrollable_content_region_show(x, y, w, h));
4225 EOLIAN static Eina_Bool
4226 _elm_genlist_elm_widget_translate(Eo *obj, Elm_Genlist_Data *sd)
4230 // Before calling text_get, inform user first.
4231 evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
4233 // FIXME: We should change item's height if lang is changed??
4234 EINA_INLIST_FOREACH(sd->blocks, itb)
4238 EINA_LIST_FOREACH(itb->items, l, it)
4242 elm_genlist_item_fields_update(EO_OBJ(it),
4244 ELM_GENLIST_ITEM_FIELD_TEXT);
4246 else GL_IT(it)->calc_done = EINA_FALSE;
4248 itb->calc_done = EINA_FALSE;
4251 eina_hash_free_buckets(sd->size_caches);
4252 sd->calc_done = EINA_FALSE;
4258 _elm_genlist_elm_widget_item_loop_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enable EINA_UNUSED)
4260 // Need to be implemented
4261 //sd->item_loop_enable = !!enable;
4264 EOLIAN static Eina_Bool
4265 _elm_genlist_elm_widget_item_loop_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
4267 // Need to be implemented
4268 //return sd->item_loop_enable;
4273 _item_block_position_update(Eina_Inlist *list,
4278 EINA_INLIST_FOREACH(list, tmp)
4280 tmp->position = idx++;
4281 tmp->position_update = EINA_TRUE;
4286 _item_position_update(Eina_List *list,
4292 EINA_LIST_FOREACH(list, l, it)
4294 it->position = idx++;
4295 it->position_update = EINA_TRUE;
4300 _item_block_merge(Item_Block *left,
4306 EINA_LIST_FOREACH(right->items, l, it2)
4308 it2->item->block = left;
4310 left->calc_done = EINA_FALSE;
4312 left->items = eina_list_merge(left->items, right->items);
4316 _item_block_del(Elm_Gen_Item *it)
4318 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4320 Item_Block *itb = GL_IT(it)->block;
4321 Eina_Bool block_changed = EINA_FALSE;
4324 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
4325 (NULL, NULL, NULL, &vh));
4326 if (sd->processed_sizes >= vh) sd->processed_sizes = 0;
4328 itb->items = eina_list_remove(itb->items, it);
4330 itb->calc_done = EINA_FALSE;
4331 sd->calc_done = EINA_FALSE;
4332 _changed(sd->pan_obj);
4337 il = EINA_INLIST_GET(itb);
4338 itbn = (Item_Block *)(il->next);
4340 it->parent->item->items =
4341 eina_list_remove(it->parent->item->items, EO_OBJ(it));
4344 _item_block_position_update(il->next, itb->position);
4346 GL_IT(it)->wsd->blocks =
4347 eina_inlist_remove(GL_IT(it)->wsd->blocks, il);
4348 GL_IT(it)->wsd->blocks_realized = eina_list_remove
4349 (GL_IT(it)->wsd->blocks_realized, itb);
4352 if (itbn) itbn->calc_done = EINA_FALSE;
4356 if (itb->count < (itb->sd->max_items_per_block / 2))
4361 il = EINA_INLIST_GET(itb);
4362 itbp = (Item_Block *)(il->prev);
4363 itbn = (Item_Block *)(il->next);
4365 /* merge block with previous */
4367 ((itbp->count + itb->count) <
4368 (itb->sd->max_items_per_block +
4369 (itb->sd->max_items_per_block / 2))))
4371 _item_block_merge(itbp, itb);
4372 _item_block_position_update
4373 (EINA_INLIST_GET(itb)->next, itb->position);
4374 GL_IT(it)->wsd->blocks = eina_inlist_remove
4375 (GL_IT(it)->wsd->blocks, EINA_INLIST_GET(itb));
4376 GL_IT(it)->wsd->blocks_realized = eina_list_remove
4377 (GL_IT(it)->wsd->blocks_realized, itb);
4379 block_changed = EINA_TRUE;
4381 /* merge block with next */
4383 ((itbn->count + itb->count) <
4384 (itb->sd->max_items_per_block +
4385 (itb->sd->max_items_per_block / 2))))
4387 _item_block_merge(itb, itbn);
4388 _item_block_position_update
4389 (EINA_INLIST_GET(itbn)->next, itbn->position);
4390 GL_IT(it)->wsd->blocks =
4391 eina_inlist_remove(GL_IT(it)->wsd->blocks,
4392 EINA_INLIST_GET(itbn));
4393 GL_IT(it)->wsd->blocks_realized = eina_list_remove
4394 (GL_IT(it)->wsd->blocks_realized, itbn);
4396 block_changed = EINA_TRUE;
4403 _changed(sd->pan_obj);
4406 GL_IT(it)->block = NULL;
4410 _decorate_all_item_unrealize(Elm_Gen_Item *it)
4412 if (!it->deco_all_view) return;
4414 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
4415 _view_clear(it->deco_all_view, &(GL_IT(it)->deco_all_contents));
4416 evas_object_del(it->deco_all_view);
4417 it->deco_all_view = NULL;
4419 edje_object_signal_emit(VIEW(it), SIGNAL_DECORATE_DISABLED, "elm");
4421 _item_mouse_callbacks_add(it, VIEW(it));
4422 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
4427 _item_mouse_move_cb(void *data,
4428 Evas *evas EINA_UNUSED,
4432 Evas_Event_Mouse_Move *ev = event_info;
4433 Elm_Gen_Item *it = data;
4434 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4436 if (!it->down) return;
4438 if (((sd->reorder_force) || (sd->reorder_mode)) &&
4439 (sd->reorder.it == it) &&
4443 evas_object_geometry_get(sd->pan_obj, &ox, NULL, NULL, NULL);
4445 if ((ev->cur.canvas.y - it->dy) > GL_IT(it)->scrl_y)
4446 sd->reorder.dir = 1;
4447 else if ((ev->cur.canvas.y - it->dy) < GL_IT(it)->scrl_y)
4448 sd->reorder.dir = -1;
4450 GL_IT(it)->scrl_x = it->x + GL_IT(it)->block->x - sd->pan_x + ox;
4451 GL_IT(it)->scrl_y = ev->cur.canvas.y - it->dy;
4452 GL_IT(it)->w = sd->minw;
4453 GL_IT(it)->h = GL_IT(it)->minh;
4454 _changed(sd->pan_obj);
4457 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4459 if (GL_IT(it)->highlight_timer)
4461 ecore_timer_del(GL_IT(it)->highlight_timer);
4462 GL_IT(it)->highlight_timer = NULL;
4464 else if (!it->selected) _item_unhighlight(it, EINA_FALSE);
4468 ecore_timer_del(it->long_timer);
4469 it->long_timer = NULL;
4471 sd->on_hold = EINA_TRUE; /* for checking need to start select timer */
4473 //******************** TIZEN Only
4476 if (((sd->reorder_force) || (sd->reorder_mode)) &&
4477 (sd->reorder.it == it) && (!it->want_hidden))
4479 Evas_Coord x, y, w, h;
4480 evas_object_geometry_get(obj, &x, &y, &w, &h);
4481 if (ELM_RECTS_POINT_OUT(x, y, w, h, ev->cur.canvas.x, ev->cur.canvas.y))
4485 ecore_timer_del(it->long_timer);
4486 it->long_timer = NULL;
4488 if (GL_IT(it)->highlight_timer)
4490 ecore_timer_del(GL_IT(it)->highlight_timer);
4491 GL_IT(it)->highlight_timer = NULL;
4493 else if (!it->selected) _item_unhighlight(it, EINA_FALSE);
4496 //*******************************
4498 evas_object_ref(obj);
4502 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
4503 minw = GL_IT(it)->wsd->finger_minw;
4504 minh = GL_IT(it)->wsd->finger_minh;
4506 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4507 dx = ev->cur.canvas.x - x;
4508 dy = ev->cur.canvas.y - y;
4513 if (adx < 0) adx = -dx;
4514 if (ady < 0) ady = -dy;
4515 if ((adx > minw) || (ady > minh))
4517 it->dragging = EINA_TRUE;
4518 /* Genlist is scrolled vertically, so reduce left or right case for accuracy. */
4519 if (adx > (ady * 2))
4522 evas_object_smart_callback_call
4523 (WIDGET(it), SIG_DRAG_START_LEFT, EO_OBJ(it));
4525 evas_object_smart_callback_call
4526 (WIDGET(it), SIG_DRAG_START_RIGHT, EO_OBJ(it));
4531 evas_object_smart_callback_call
4532 (WIDGET(it), SIG_DRAG_START_UP, EO_OBJ(it));
4534 evas_object_smart_callback_call
4535 (WIDGET(it), SIG_DRAG_START_DOWN, EO_OBJ(it));
4540 /* If item magic value is changed, do not call smart callback*/
4541 if (EINA_MAGIC_CHECK(it->base, ELM_WIDGET_ITEM_MAGIC))
4544 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, EO_OBJ(it));
4547 evas_object_unref(obj);
4552 _long_press_cb(void *data)
4554 Elm_Gen_Item *it = data;
4555 Elm_Object_Item *eo_it2;
4556 Elm_Genlist_Data *sd;
4560 sd = GL_IT(it)->wsd;
4561 it->long_timer = NULL;
4563 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()) ||
4564 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
4565 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
4566 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
4567 (sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
4570 if ((sd->reorder_mode) &&
4571 (GL_IT(it)->type != ELM_GENLIST_ITEM_GROUP) &&
4572 (!sd->key_down_item))
4574 if (elm_genlist_item_expanded_get(EO_OBJ(it)))
4576 elm_genlist_item_expanded_set(EO_OBJ(it), EINA_FALSE);
4578 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it2)
4580 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
4581 _item_unselect(it2);
4584 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
4585 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
4586 (EINA_FALSE, EINA_FALSE));
4588 if (TIZEN_PROFILE_WEARABLE)
4591 if (sd->decorate_all_mode)
4592 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
4596 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
4599 sd->reorder.it = it;
4600 _changed(sd->pan_obj);
4602 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, EO_OBJ(it));
4605 it->long_timer = NULL;
4606 return ECORE_CALLBACK_CANCEL;
4610 _gesture_do(void *data)
4612 Elm_Genlist_Data *sd = data;
4614 if ((sd->g_item) && (sd->g_type))
4616 if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_LEFT))
4617 evas_object_smart_callback_call
4618 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_LEFT, EO_OBJ(sd->g_item));
4619 else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_RIGHT))
4620 evas_object_smart_callback_call
4621 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_RIGHT, EO_OBJ(sd->g_item));
4622 else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_UP))
4623 evas_object_smart_callback_call
4624 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_UP, EO_OBJ(sd->g_item));
4625 else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_DOWN))
4626 evas_object_smart_callback_call
4627 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_DOWN, EO_OBJ(sd->g_item));
4628 else if (!strcmp(sd->g_type, SIG_MULTI_PINCH_OUT))
4629 evas_object_smart_callback_call
4630 (WIDGET(sd->g_item), SIG_MULTI_PINCH_OUT, EO_OBJ(sd->g_item));
4631 else if (!strcmp(sd->g_type, SIG_MULTI_PINCH_IN))
4632 evas_object_smart_callback_call
4633 (WIDGET(sd->g_item), SIG_MULTI_PINCH_IN, EO_OBJ(sd->g_item));
4634 else if (!strcmp(sd->g_type, SIG_SWIPE))
4635 evas_object_smart_callback_call
4636 (WIDGET(sd->g_item), SIG_SWIPE, EO_OBJ(sd->g_item));
4644 _item_mouse_down_cb(void *data,
4649 Evas_Event_Mouse_Down *ev = event_info;
4650 Elm_Gen_Item *it = data;
4651 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4654 if (ev->event_flags & EVAS_EVENT_FLAG_ON_SCROLL)
4658 elm_genlist_item_reorder_stop(EO_OBJ(sd->reorder.it));
4659 sd->reorder.it = NULL;
4660 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
4661 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set(sd->h_bounce, sd->v_bounce));
4666 if (ev->button != 1) return;
4667 // mouse down is activate only one finger
4668 if (evas_event_down_count_get(evas) != 1) return;
4670 if (GL_IT(it)->highlight_timer)
4671 ecore_timer_del(GL_IT(it)->highlight_timer);
4672 // FIXME: To prevent timing issue about select and highlight
4673 else if (!sd->multi && sd->highlighted_item &&
4674 (GL_IT(sd->highlighted_item)->highlight_timer))
4677 it->down = EINA_TRUE;
4679 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4680 it->dx = ev->canvas.x - x;
4681 it->dy = ev->canvas.y - y;
4683 GL_IT(it)->wsd->was_selected = it->selected;
4684 GL_IT(it)->highlight_timer = ecore_timer_add(ELM_ITEM_HIGHLIGHT_TIMER,
4685 _highlight_timer, it);
4686 if (it->long_timer) ecore_timer_del(it->long_timer);
4687 it->long_timer = ecore_timer_add(sd->longpress_timeout, _long_press_cb, it);
4689 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
4691 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, EO_OBJ(it));
4692 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, EO_OBJ(it));
4694 evas_object_smart_callback_call(WIDGET(it), SIG_PRESSED, EO_OBJ(it));
4698 _item_block_new(Elm_Genlist_Data *sd,
4703 itb = calloc(1, sizeof(Item_Block));
4704 if (!itb) return NULL;
4708 sd->blocks = eina_inlist_prepend(sd->blocks, EINA_INLIST_GET(itb));
4709 _item_block_position_update(sd->blocks, 0);
4713 sd->blocks = eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4714 itb->position_update = EINA_TRUE;
4715 if (sd->blocks != EINA_INLIST_GET(itb))
4718 ((Item_Block *)(EINA_INLIST_GET(itb)->prev))->position + 1;
4730 _item_block_add(Elm_Genlist_Data *sd,
4733 Item_Block *itb = NULL;
4734 if (GL_IT(it)->block) return EINA_TRUE;
4736 if (!GL_IT(it)->rel)
4741 itb = calloc(1, sizeof(Item_Block));
4742 if (!itb) return EINA_FALSE;
4744 if (!GL_IT(it)->rel->item->block)
4747 eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4748 itb->items = eina_list_append(itb->items, it);
4749 itb->position_update = EINA_TRUE;
4750 it->position = eina_list_count(itb->items);
4751 it->position_update = EINA_TRUE;
4753 if (sd->blocks != EINA_INLIST_GET(itb))
4757 (EINA_INLIST_GET(itb)->prev))->position + 1;
4768 tmp = eina_list_data_find_list(itb->items, GL_IT(it)->rel);
4769 if (GL_IT(it)->before)
4771 sd->blocks = eina_inlist_prepend_relative
4772 (sd->blocks, EINA_INLIST_GET(itb),
4773 EINA_INLIST_GET(GL_IT(it)->rel->item->block));
4775 eina_list_prepend_relative_list(itb->items, it, tmp);
4777 /* Update index from where we prepended */
4778 _item_position_update
4779 (eina_list_prev(tmp), GL_IT(it)->rel->position);
4780 _item_block_position_update
4781 (EINA_INLIST_GET(itb),
4782 GL_IT(it)->rel->item->block->position);
4786 sd->blocks = eina_inlist_append_relative
4787 (sd->blocks, EINA_INLIST_GET(itb),
4788 EINA_INLIST_GET(GL_IT(it)->rel->item->block));
4790 eina_list_append_relative_list(itb->items, it, tmp);
4792 /* Update block index from where we appended */
4793 _item_position_update
4794 (eina_list_next(tmp), GL_IT(it)->rel->position + 1);
4795 _item_block_position_update
4796 (EINA_INLIST_GET(itb),
4797 GL_IT(it)->rel->item->block->position + 1);
4803 if (GL_IT(it)->before)
4807 itb = (Item_Block *)(sd->blocks);
4808 if (itb->count >= sd->max_items_per_block)
4810 itb = _item_block_new(sd, EINA_TRUE);
4811 if (!itb) return EINA_FALSE;
4816 itb = _item_block_new(sd, EINA_TRUE);
4817 if (!itb) return EINA_FALSE;
4819 itb->items = eina_list_prepend(itb->items, it);
4820 _item_position_update(itb->items, 1);
4826 itb = (Item_Block *)(sd->blocks->last);
4827 if (itb->count >= sd->max_items_per_block)
4829 itb = _item_block_new(sd, EINA_FALSE);
4830 if (!itb) return EINA_FALSE;
4835 itb = _item_block_new(sd, EINA_FALSE);
4836 if (!itb) return EINA_FALSE;
4838 itb->items = eina_list_append(itb->items, it);
4839 it->position = eina_list_count(itb->items);
4848 if ((!GL_IT(it)->wsd->sorting) && (GL_IT(it)->rel->item->queued))
4850 /* NOTE: for a strange reason eina_list and eina_inlist
4851 don't have the same property on sorted insertion
4852 order, so the queue is not always ordered like the
4853 item list. This lead to issue where we depend on an
4854 item that is not yet created. As a quick work around,
4855 we reschedule the calc of the item and stop reordering
4856 the list to prevent any nasty issue to show up here.
4858 sd->queue = eina_list_append(sd->queue, it);
4859 sd->requeued = EINA_TRUE;
4860 GL_IT(it)->queued = EINA_TRUE;
4865 itb = GL_IT(it)->rel->item->block;
4866 if (!itb) goto newblock;
4867 tmp = eina_list_data_find_list(itb->items, GL_IT(it)->rel);
4868 if (GL_IT(it)->before)
4870 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4871 _item_position_update
4872 (eina_list_prev(tmp), GL_IT(it)->rel->position);
4876 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4877 _item_position_update
4878 (eina_list_next(tmp), GL_IT(it)->rel->position + 1);
4883 itb->calc_done = EINA_FALSE;
4884 sd->calc_done = EINA_FALSE;
4885 GL_IT(it)->block = itb;
4886 _changed(itb->sd->pan_obj);
4888 if (itb->count > itb->sd->max_items_per_block)
4893 Eina_Bool done = EINA_FALSE;
4895 newc = itb->count / 2;
4897 if (EINA_INLIST_GET(itb)->prev)
4899 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4901 if (itbp->count + newc < sd->max_items_per_block / 2)
4903 /* moving items to previous block */
4904 while ((itb->count > newc) && (itb->items))
4906 it2 = eina_list_data_get(itb->items);
4907 itb->items = eina_list_remove_list
4908 (itb->items, itb->items);
4911 itbp->items = eina_list_append(itbp->items, it2);
4912 it2->item->block = itbp;
4920 if (!done && EINA_INLIST_GET(itb)->next)
4922 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4924 if (itbn->count + newc < sd->max_items_per_block / 2)
4926 /* moving items to next block */
4927 while ((itb->count > newc) && (itb->items))
4931 l = eina_list_last(itb->items);
4932 it2 = eina_list_data_get(l);
4933 itb->items = eina_list_remove_list(itb->items, l);
4936 itbn->items = eina_list_prepend(itbn->items, it2);
4937 it2->item->block = itbn;
4947 /* moving items to new block */
4948 itb2 = calloc(1, sizeof(Item_Block));
4949 if (!itb2) return EINA_FALSE;
4952 eina_inlist_append_relative(sd->blocks, EINA_INLIST_GET(itb2),
4953 EINA_INLIST_GET(itb));
4954 itb2->calc_done = EINA_FALSE;
4955 while ((itb->count > newc) && (itb->items))
4959 l = eina_list_last(itb->items);
4961 itb->items = eina_list_remove_list(itb->items, l);
4964 itb2->items = eina_list_prepend(itb2->items, it2);
4965 it2->item->block = itb2;
4975 _item_min_calc(Elm_Gen_Item *it)
4977 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4978 Evas_Coord mw = 0, mh = 0;
4981 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
4982 (NULL, NULL, &vw, NULL));
4984 if ((it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) &&
4985 (sd->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
4987 mw = sd->finger_minw;
4988 mh = sd->finger_minh;
4991 if ((sd->mode == ELM_LIST_COMPRESS) && vw && mw < vw)
4994 //FIXME: Some widget such as entry, label need to have fixed width size before
4995 // min calculation to get proper height size by multiline.
4996 if (sd->realization_mode || GL_IT(it)->resized)
4997 evas_object_resize(VIEW(it), mw, mh);
4999 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
5001 if ((sd->mode != ELM_LIST_LIMIT) && vw && mw < vw)
5004 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5005 if (sd->homogeneous || it->itc->homogeneous)
5007 Size_Cache *size, *tmp;
5008 tmp = eina_hash_find(sd->size_caches, it->itc->item_style);
5010 eina_hash_del_by_key(sd->size_caches, it->itc->item_style);
5012 size = ELM_NEW(Size_Cache);
5015 eina_hash_add(sd->size_caches, it->itc->item_style, size);
5018 GL_IT(it)->w = GL_IT(it)->minw = mw;
5019 GL_IT(it)->h = GL_IT(it)->minh = mh;
5021 // FIXME: This is workaround for entry size issue.
5022 if (sd->realization_mode || GL_IT(it)->resized)
5024 GL_IT(it)->resized = EINA_FALSE;
5025 if (it->deco_all_view)
5026 evas_object_resize(it->deco_all_view, GL_IT(it)->w, GL_IT(it)->h);
5027 else if (GL_IT(it)->deco_it_view)
5028 evas_object_resize(GL_IT(it)->deco_it_view, GL_IT(it)->w, GL_IT(it)->h);
5030 evas_object_resize(VIEW(it), GL_IT(it)->w, GL_IT(it)->h);
5036 _item_calc(Elm_Gen_Item *it)
5038 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5039 Size_Cache *size = NULL;
5040 Evas_Coord p_minw, p_minh;
5042 if (GL_IT(it)->calc_done) return;
5044 p_minw = GL_IT(it)->minw;
5045 p_minh = GL_IT(it)->minh;
5047 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5048 if (sd->homogeneous || it->itc->homogeneous)
5049 size = eina_hash_find(sd->size_caches, it->itc->item_style);
5052 GL_IT(it)->w = GL_IT(it)->minw = size->minw;
5053 GL_IT(it)->h = GL_IT(it)->minh = size->minh;
5059 if (sd->realization_mode)
5061 _item_realize(it, EINA_FALSE);
5066 _item_realize(it, EINA_TRUE);
5068 _item_unrealize(it, EINA_TRUE);
5075 GL_IT(it)->calc_done = EINA_TRUE;
5076 if ((p_minw != GL_IT(it)->minw) || (p_minh != GL_IT(it)->minh))
5078 GL_IT(it)->block->calc_done = EINA_FALSE;
5079 sd->calc_done = EINA_FALSE;
5084 _item_process(Elm_Genlist_Data *sd,
5087 if (!_item_block_add(sd, it)) return EINA_FALSE;
5089 GL_IT(it)->calc_done = EINA_FALSE;
5096 _dummy_job(void *data)
5098 Elm_Genlist_Data *sd = data;
5099 sd->dummy_job = NULL;
5104 _queue_idle_enter(void *data)
5106 Elm_Genlist_Data *sd = data;
5111 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
5112 (NULL, NULL, &vw, NULL));
5113 if (!sd->queue || (vw <= 1))
5117 ecore_job_del(sd->dummy_job);
5118 sd->dummy_job = NULL;
5120 sd->queue_idle_enterer = NULL;
5121 return ECORE_CALLBACK_CANCEL;
5124 ft = ecore_animator_frametime_get()/2;
5125 t0 = ecore_time_get();
5126 for (n = 0; (sd->queue) && (n < ITEM_QUEUE_MAX); n++)
5131 it = eina_list_data_get(sd->queue);
5132 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
5133 GL_IT(it)->queued = EINA_FALSE;
5134 GL_IT(it)->resized = EINA_FALSE;
5135 if (!_item_process(sd, it)) continue;
5136 t = ecore_time_get();
5137 /* same as eina_inlist_count > 1 */
5138 if (sd->blocks && sd->blocks->next)
5140 if ((t - t0) > ft) break;
5144 _changed(sd->pan_obj);
5149 ecore_job_del(sd->dummy_job);
5150 sd->dummy_job = NULL;
5152 sd->queue_idle_enterer = NULL;
5153 return ECORE_CALLBACK_CANCEL;
5156 // Do not use smart_changed
5157 // Instead make any events (job, idler, etc.) to call idle enterer
5158 if (sd->dummy_job) ecore_job_del(sd->dummy_job);
5159 sd->dummy_job = ecore_job_add(_dummy_job, sd);
5161 return ECORE_CALLBACK_RENEW;
5165 _item_queue(Elm_Gen_Item *it,
5166 Eina_Compare_Cb cb EINA_UNUSED)
5168 if (GL_IT(it)->queued) return;
5170 GL_IT(it)->queued = EINA_TRUE;
5171 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5173 // FIXME: Below code occurs item unsorted result.
5174 // genlist already calculate items position by sd->items
5175 // so no need to requeue items by sorting insert.
5176 // if (cb && !sd->requeued)
5177 // sd->queue = eina_list_sorted_insert(sd->queue, cb, it);
5179 sd->queue = eina_list_append(sd->queue, it);
5181 if (sd->queue_idle_enterer)
5182 ecore_idle_enterer_del(sd->queue_idle_enterer);
5183 sd->queue_idle_enterer = ecore_idle_enterer_add(_queue_idle_enter, sd);
5187 _item_queue_direct(Elm_Gen_Item *it,
5190 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5192 // Processing items within viewport if items already exist.
5193 // This can prevent flickering issue when content size is changed.
5194 // This can fix the flickering issue when expanded item have subitems whose total height > vh
5195 if (!sd->queue && (sd->viewport_w > 1) &&
5196 ((sd->processed_sizes <= sd->viewport_h) || (GL_IT(it)->expanded_depth > 0)))
5198 #ifdef GENLIST_FX_SUPPORT
5199 if (sd->fx_mode)// && !it->item->is_prepend) // For support preppended items - hs619.choi@samsung.com
5201 sd->add_fx.items = eina_list_append(sd->add_fx.items, it);
5202 if (!sd->add_fx.anim)
5204 sd->add_fx.cnt = ANIM_CNT_MAX;
5205 sd->add_fx.anim = ecore_animator_add(_add_fx_anim, sd);
5209 _item_process(sd, it);
5210 sd->processed_sizes += GL_IT(it)->minh;
5212 _changed(sd->pan_obj);
5215 _item_queue(it, cb);
5218 /* If the application wants to know the relative item, use
5219 * elm_genlist_item_prev_get(it)*/
5221 _item_move_after(Elm_Gen_Item *it,
5222 Elm_Gen_Item *after)
5226 if (it == after) return;
5228 GL_IT(it)->wsd->items =
5229 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
5230 if (GL_IT(it)->block) _item_block_del(it);
5232 GL_IT(it)->wsd->items = eina_inlist_append_relative
5233 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
5236 GL_IT(it)->rel->item->rel_revs =
5237 eina_list_remove(GL_IT(it)->rel->item->rel_revs, it);
5238 GL_IT(it)->rel = after;
5239 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
5240 GL_IT(it)->before = EINA_FALSE;
5241 if (after->item->group_item) GL_IT(it)->group_item = after->item->group_item;
5243 if (GL_IT(it)->queued)
5245 GL_IT(it)->wsd->queue = eina_list_remove(GL_IT(it)->wsd->queue, it);
5246 GL_IT(it)->queued = EINA_FALSE;
5248 _item_queue_direct(it, NULL);
5250 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, EO_OBJ(it));
5253 /* If the application wants to know the relative item, use
5254 * elm_genlist_item_next_get(it)*/
5256 _item_move_before(Elm_Gen_Item *it,
5257 Elm_Gen_Item *before)
5260 if (!before) return;
5261 if (it == before) return;
5263 GL_IT(it)->wsd->items =
5264 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
5265 if (GL_IT(it)->block) _item_block_del(it);
5266 GL_IT(it)->wsd->items = eina_inlist_prepend_relative
5267 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
5270 GL_IT(it)->rel->item->rel_revs =
5271 eina_list_remove(GL_IT(it)->rel->item->rel_revs, it);
5272 GL_IT(it)->rel = before;
5273 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
5274 GL_IT(it)->before = EINA_TRUE;
5275 if (before->item->group_item)
5276 GL_IT(it)->group_item = before->item->group_item;
5277 _item_queue_direct(it, NULL);
5279 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, EO_OBJ(it));
5283 _item_mouse_up_cb(void *data,
5285 Evas_Object *obj EINA_UNUSED,
5288 Evas_Event_Mouse_Up *ev = event_info;
5289 Elm_Gen_Item *it = data;
5290 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5292 ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd);
5294 if (!it->down) return;
5295 it->down = EINA_FALSE;
5297 if (ev->button != 1) return;
5301 it->dragging = EINA_FALSE;
5302 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, EO_OBJ(it));
5304 // When the event is cancelled, need to initialize mouse flags and timers.
5305 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = EINA_TRUE;
5309 if (evas_event_down_count_get(evas) != 0)
5311 if (!GL_IT(it)->highlight_timer) _item_unhighlight(it, EINA_TRUE);
5316 ecore_timer_del(it->long_timer);
5317 it->long_timer = NULL;
5319 if (GL_IT(it)->highlight_timer)
5321 ecore_timer_del(GL_IT(it)->highlight_timer);
5322 GL_IT(it)->highlight_timer = NULL;
5323 // Because naviframe can drop the all evevents.
5324 // highlight it before select timer is called.
5325 if (evas_event_down_count_get(evas) == 0) _item_highlight(it);
5328 if (!sd->reorder.it && (evas_event_down_count_get(evas) == 0))
5330 // FIXME: if highlight mode is not used, mouse move cannot disable
5332 if ((sd->was_selected == it->selected) && (!sd->on_hold))
5334 if (wd->scroll_item_align_enable)
5336 const char *align = edje_object_data_get(VIEW(it), "align");
5337 if (!align || strcmp(align, "off"))
5339 if (it != sd->aligned_item)
5341 elm_genlist_item_bring_in(EO_OBJ(it), ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
5345 if (((sd->highlight && it->highlighted) || !sd->highlight) &&
5346 ((!wd->scroll_item_align_enable) || (it == sd->aligned_item)))
5347 GL_IT(it)->highlight_timer =
5348 ecore_timer_add(ITEM_SELECT_TIMER, _select_timer, it);
5349 else if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
5350 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
5353 Evas_Object *content;
5354 if (sd->focused_item != it)
5355 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
5357 sd->focused_content = NULL;
5358 EINA_LIST_FOREACH(it->content_objs, l, content)
5360 if (elm_widget_focused_object_get(content))
5361 sd->focused_content = content;
5366 else if (sd->reorder.it == it)
5368 if (TIZEN_PROFILE_WEARABLE)
5370 Elm_Gen_Item *it2, *it_max = NULL, *it_min = NULL;
5371 Evas_Coord r_y_scrl, it_y_max = -99999999, it_y_min = 99999999;
5373 if (!it->selected) _item_unhighlight(it, EINA_TRUE);
5374 r_y_scrl = GL_IT(it)->scrl_y;
5375 EINA_LIST_FREE(sd->reorder.move_items, it2)
5377 if (sd->reorder.it->parent != it2->parent)
5379 it2->item->reorder_offset = 0;
5382 Evas_Coord it_y = it2->item->scrl_y +
5383 it2->item->reorder_offset + (it2->item->h / 2) +
5384 it2->item->block->y;
5386 if ((it_y < r_y_scrl) &&
5392 else if ((it_y > r_y_scrl) &&
5398 it2->item->reorder_offset = 0;
5402 _item_move_after(it, it_max);
5403 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5407 _item_move_before(it, it_min);
5408 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5414 Elm_Gen_Item *moved_it = NULL;
5415 Elm_Gen_Item *ptr_it = sd->top_drawn_item;
5416 Elm_Gen_Item *last_it = NULL;
5417 Eina_Bool after = EINA_TRUE;
5419 if (!it->selected) _item_unhighlight(it, EINA_FALSE);
5425 if (ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y, GL_IT(it)->w, GL_IT(it)->h,
5426 GL_IT(ptr_it)->scrl_x, GL_IT(ptr_it)->scrl_y, GL_IT(ptr_it)->w, GL_IT(ptr_it)->h))
5428 if (GL_IT(it)->scrl_y < GL_IT(ptr_it)->scrl_y)
5435 if ((GL_IT(it)->scrl_y + GL_IT(it)->h) > (GL_IT(ptr_it)->scrl_y + GL_IT(ptr_it)->h))
5437 if ((GL_IT(it)->scrl_y + GL_IT(it)->h) == GL_IT(ptr_it)->scrl_y)
5445 ptr_it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(ptr_it)->next);
5450 if (GL_IT(it)->scrl_y > GL_IT(last_it)->scrl_y + GL_IT(last_it)->h)
5454 moved_it = sd->top_drawn_item;
5459 EINA_LIST_FREE(sd->reorder.move_items, ptr_it)
5461 ptr_it->item->reorder_offset = 0;
5466 _item_move_after(it, moved_it);
5467 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5471 _item_move_before(it, moved_it);
5472 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5475 sd->reorder.it = NULL;
5476 sd->reorder.dir = 0;
5477 if (sd->reorder.anim)
5479 ecore_animator_del(sd->reorder.anim);
5480 sd->reorder.anim = NULL;
5483 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5484 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
5485 (sd->h_bounce, sd->v_bounce));
5487 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_DISABLED, "elm");
5488 _changed(sd->pan_obj);
5490 sd->on_hold = EINA_FALSE; /* for checking need to start select timer */
5491 evas_object_smart_callback_call(WIDGET(it), SIG_RELEASED, EO_OBJ(it));
5495 _scroll_hold_timer_cb(void *data)
5497 Elm_Genlist_Data *sd = data;
5498 sd->scr_hold_timer = NULL;
5500 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5502 return ECORE_CALLBACK_CANCEL;
5506 _decorate_item_finished_signal_cb(void *data,
5508 const char *emission EINA_UNUSED,
5509 const char *source EINA_UNUSED)
5511 Elm_Gen_Item *it = data;
5513 if (!data || !obj) return;
5514 if ((!it->realized)) return;
5516 _decorate_item_unrealize(it);
5520 _item_update(Elm_Gen_Item *it)
5523 if (!it->realized) return;
5525 _view_clear(VIEW(it), &(it->content_objs));
5526 EINA_LIST_FREE(GL_IT(it)->flip_content_objs, c)
5528 _view_clear(GL_IT(it)->deco_it_view, &(GL_IT(it)->deco_it_contents));
5529 _view_clear(it->deco_all_view, &(GL_IT(it)->deco_all_contents));
5531 _view_inflate(VIEW(it), it, &(it->content_objs));
5534 _item_content_realize(it, VIEW(it), &(GL_IT(it)->flip_content_objs),
5536 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
5538 if (GL_IT(it)->wsd->decorate_all_mode)
5539 _view_inflate(it->deco_all_view, it, &(GL_IT(it)->deco_all_contents));
5540 else if (GL_IT(it)->deco_it_view)
5541 _view_inflate(GL_IT(it)->deco_it_view, it, &(GL_IT(it)->deco_it_contents));
5543 if (!TIZEN_PROFILE_WEARABLE)
5544 _banded_item_bg_add(it, VIEW(it));
5547 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
5549 if (GL_IT(it)->wsd->aligned_item == it)
5550 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
5552 edje_object_message_signal_process(VIEW(it));
5556 _item_block_calc(Item_Block *itb, Evas_Coord vw EINA_UNUSED, Evas_Coord vh)
5560 Evas_Coord minw = 9999999, minh = 0;
5561 int sum_item_height = 0;
5562 ELM_WIDGET_DATA_GET_OR_RETURN(itb->sd->obj, wsd);
5564 if (itb->calc_done) return;
5566 EINA_LIST_FOREACH(itb->items, l, it)
5568 if (it->want_hidden) continue;
5569 if (GL_IT(it)->updateme)
5575 GL_IT(it)->calc_done = EINA_FALSE;
5576 GL_IT(it)->updateme = EINA_FALSE;
5578 if (!GL_IT(it)->queued) _item_calc(it);
5580 if (wsd->scroll_item_align_enable)
5582 int vcenter = vh / 2;
5583 int icenter = GL_IT(it)->h / 2;
5584 if ((itb->y + sum_item_height < vcenter && itb->y + sum_item_height + GL_IT(it)->h > vcenter) &&
5585 (sum_item_height + icenter < vcenter - 1 || sum_item_height + icenter > vcenter + 1))
5587 int first_item_height = sum_item_height = vcenter - icenter;
5589 Elm_Object_Item *eo_prev = elm_genlist_item_prev_get(EO_OBJ(it));
5590 Elm_Gen_Item *prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
5593 minh = sum_item_height;
5596 if (eo_prev == elm_genlist_first_item_get(wsd->obj))
5598 GL_IT(prev)->h = GL_IT(prev)->minh = first_item_height;
5601 first_item_height -= GL_IT(prev)->h;
5602 prev->y = first_item_height;
5603 eo_prev = elm_genlist_item_prev_get(eo_prev);
5604 prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
5607 sum_item_height += GL_IT(it)->h;
5612 if (minw > GL_IT(it)->minw) minw = GL_IT(it)->minw;
5613 minh += GL_IT(it)->minh;
5614 if (GL_IT(it)->is_prepend)
5616 itb->sd->comp_y += GL_IT(it)->minh;
5617 GL_IT(it)->is_prepend = EINA_FALSE;
5622 itb->calc_done = EINA_TRUE;
5623 itb->position_update = EINA_FALSE;
5627 _scroll_animate_start_cb(Evas_Object *obj,
5628 void *data EINA_UNUSED)
5630 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5631 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
5635 _scroll_animate_stop_cb(Evas_Object *obj,
5636 void *data EINA_UNUSED)
5638 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5639 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
5641 //TIZEN_ONLY: Let the screen-reader know when scroll animation ends
5642 if (_elm_atspi_enabled())
5644 elm_interface_atspi_accessible_visible_data_changed_signal_emit(obj);
5650 _scroll_drag_start_cb(Evas_Object *obj,
5651 void *data EINA_UNUSED)
5653 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5654 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
5658 _scroll_timeout_cb(void *data)
5660 Elm_Genlist_Data *sd = data;
5662 sd->scr_timer = NULL;
5663 if (sd->queue && !sd->queue_idle_enterer)
5665 sd->queue_idle_enterer = ecore_idle_enterer_add(_queue_idle_enter, sd);
5666 if (sd->dummy_job) ecore_job_del(sd->dummy_job);
5667 sd->dummy_job = ecore_job_add(_dummy_job, sd);
5669 return ECORE_CALLBACK_CANCEL;
5673 _scroll_cb(Evas_Object *obj,
5674 void *data EINA_UNUSED)
5676 ELM_GENLIST_DATA_GET(obj, sd);
5678 if (sd->queue_idle_enterer)
5680 ecore_idle_enterer_del(sd->queue_idle_enterer);
5681 sd->queue_idle_enterer = NULL;
5684 ecore_job_del(sd->dummy_job);
5685 sd->dummy_job = NULL;
5688 if (sd->scr_timer) ecore_timer_del(sd->scr_timer);
5689 sd->scr_timer = ecore_timer_add(0.25, _scroll_timeout_cb, sd);
5691 evas_object_smart_callback_call(obj, SIG_SCROLL, NULL);
5695 _scroll_drag_stop_cb(Evas_Object *obj,
5696 void *data EINA_UNUSED)
5698 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_STOP, NULL);
5699 //TIZEN_ONLY: Let the screen-reader know when drag ends
5700 if (_elm_atspi_enabled())
5702 elm_interface_atspi_accessible_visible_data_changed_signal_emit(obj);
5708 _edge_left_cb(Evas_Object *obj,
5709 void *data EINA_UNUSED)
5711 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
5715 _edge_right_cb(Evas_Object *obj,
5716 void *data EINA_UNUSED)
5718 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
5722 _edge_top_cb(Evas_Object *obj,
5723 void *data EINA_UNUSED)
5725 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
5729 _edge_bottom_cb(Evas_Object *obj,
5730 void *data EINA_UNUSED)
5732 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
5736 _vbar_drag_cb(Evas_Object *obj,
5737 void *data EINA_UNUSED)
5739 evas_object_smart_callback_call(obj, SIG_VBAR_DRAG, NULL);
5743 _vbar_press_cb(Evas_Object *obj,
5744 void *data EINA_UNUSED)
5746 evas_object_smart_callback_call(obj, SIG_VBAR_PRESS, NULL);
5750 _vbar_unpress_cb(Evas_Object *obj,
5751 void *data EINA_UNUSED)
5753 evas_object_smart_callback_call(obj, SIG_VBAR_UNPRESS, NULL);
5757 _hbar_drag_cb(Evas_Object *obj,
5758 void *data EINA_UNUSED)
5760 evas_object_smart_callback_call(obj, SIG_HBAR_DRAG, NULL);
5764 _hbar_press_cb(Evas_Object *obj,
5765 void *data EINA_UNUSED)
5767 evas_object_smart_callback_call(obj, SIG_HBAR_PRESS, NULL);
5771 _hbar_unpress_cb(Evas_Object *obj,
5772 void *data EINA_UNUSED)
5774 evas_object_smart_callback_call(obj, SIG_HBAR_UNPRESS, NULL);
5778 _decorate_item_realize(Elm_Gen_Item *it)
5781 if (GL_IT(it)->deco_it_view || !it->itc->decorate_item_style) return;
5783 // Before adding & swallowing, delete it from smart member
5784 evas_object_smart_member_del(VIEW(it));
5786 GL_IT(it)->deco_it_view = _view_create(it, it->itc->decorate_item_style);
5787 edje_object_part_swallow
5788 (GL_IT(it)->deco_it_view,
5789 edje_object_data_get(GL_IT(it)->deco_it_view, "mode_part"), VIEW(it));
5790 _view_inflate(GL_IT(it)->deco_it_view, it, &(GL_IT(it)->deco_it_contents));
5792 snprintf(buf, sizeof(buf), "elm,state,%s,active",
5793 GL_IT(it)->wsd->decorate_it_type);
5794 edje_object_signal_emit(GL_IT(it)->deco_it_view, buf, "elm");
5795 edje_object_signal_emit(VIEW(it), buf, "elm");
5797 _item_mouse_callbacks_add(it, GL_IT(it)->deco_it_view);
5799 _item_mouse_callbacks_del(it, VIEW(it));
5803 // FIXME: difference from upstream
5805 _mouse_down_scroller(void *data,
5806 Evas *evas EINA_UNUSED,
5807 Evas_Object *obj EINA_UNUSED,
5808 void *event_info EINA_UNUSED)
5810 Widget_Data *wd = elm_widget_data_get(data);
5813 wd->drag_started = EINA_FALSE;
5817 _mouse_up_scroller(void *data,
5818 Evas *evas EINA_UNUSED,
5819 Evas_Object *obj EINA_UNUSED,
5820 void *event_info EINA_UNUSED)
5822 Widget_Data *wd = elm_widget_data_get(data);
5825 wd->drag_started = EINA_FALSE;
5829 _mouse_move_scroller(void *data,
5830 Evas *evas EINA_UNUSED,
5831 Evas_Object *obj EINA_UNUSED,
5834 Widget_Data *wd = elm_widget_data_get(data);
5835 Evas_Event_Mouse_Move *ev = event_info;
5836 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
5839 if (wd->drag_started) return;
5841 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
5842 dx = ev->cur.canvas.x - ev->prev.canvas.x;
5843 dy = ev->cur.canvas.y - ev->prev.canvas.y;
5846 if (adx < 0) adx = -dx;
5847 if (ady < 0) ady = -dy;
5848 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
5852 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
5853 wd->drag_started = EINA_TRUE;
5857 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
5858 wd->drag_started = EINA_TRUE;
5865 _size_cache_free(void *data)
5867 if (data) free(data);
5870 static Evas_Event_Flags
5871 _pinch_zoom_start_cb(void *data, void *event_info)
5873 Elm_Genlist_Data *sd = data;
5874 Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
5875 Elm_Object_Item *eo_it;
5877 eo_it = elm_genlist_at_xy_item_get(sd->obj, p->x, p->y, NULL);
5878 sd->g_item = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
5879 return EVAS_EVENT_FLAG_NONE;
5882 static Evas_Event_Flags
5883 _pinch_zoom_cb(void *data, void *event_info)
5885 Elm_Genlist_Data *sd = data;
5886 Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
5888 if (p->zoom > 1.0 + PINCH_ZOOM_TOLERANCE)
5889 sd->g_type = SIG_MULTI_PINCH_OUT;
5890 else if (p->zoom < 1.0 - PINCH_ZOOM_TOLERANCE)
5891 sd->g_type = SIG_MULTI_PINCH_IN;
5893 return EVAS_EVENT_FLAG_NONE;
5896 static Evas_Event_Flags
5897 _gesture_n_lines_start_cb(void *data , void *event_info)
5899 Elm_Genlist_Data *sd = data;
5900 Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5902 Elm_Object_Item *eo_it;
5904 x = (p->momentum.x1 + p->momentum.x2) / 2;
5905 y = (p->momentum.y1 + p->momentum.y2) / 2;
5907 eo_it = elm_genlist_at_xy_item_get(sd->obj, x, y, NULL);
5908 sd->g_item = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
5909 return EVAS_EVENT_FLAG_NONE;
5912 static Evas_Event_Flags
5913 _gesture_n_lines_cb(void *data , void *event_info)
5915 Elm_Genlist_Data *sd = data;
5916 Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5918 if (p->momentum.n < 2)
5919 return EVAS_EVENT_FLAG_NONE;
5921 Evas_Coord minw = 0, minh = 0;
5922 Evas_Coord x, y, off_x, off_y;
5923 Evas_Coord cur_x, cur_y, prev_x, prev_y;
5924 Elm_Gen_Item *down_it;
5925 Elm_Object_Item *eo_down_it;
5927 minw = sd->finger_minw;
5928 minh = sd->finger_minh;
5930 prev_x = prev_y = 0;
5932 cur_x = p->momentum.x1;
5933 cur_y = p->momentum.y1;
5935 eo_down_it = elm_genlist_at_xy_item_get(sd->obj, cur_x, cur_y, NULL);
5936 down_it = eo_data_scope_get(eo_down_it, ELM_GENLIST_ITEM_CLASS);
5939 evas_object_geometry_get(VIEW(down_it), &x, &y, NULL, NULL);
5940 prev_x = down_it->dx + x;
5941 prev_y = down_it->dy + y;
5943 off_x = abs(cur_x - prev_x);
5944 off_y = abs(cur_y - prev_y);
5946 if ((off_x > minw) || (off_y > minh))
5951 sd->g_type = SIG_MULTI_SWIPE_RIGHT;
5953 sd->g_type = SIG_MULTI_SWIPE_LEFT;
5958 sd->g_type = SIG_MULTI_SWIPE_DOWN;
5960 sd->g_type = SIG_MULTI_SWIPE_UP;
5964 return EVAS_EVENT_FLAG_NONE;
5967 static Evas_Event_Flags
5968 _gesture_n_flicks_cb(void *data , void *event_info)
5970 Elm_Genlist_Data *sd = data;
5971 Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5973 if (p->momentum.n == 1)
5974 sd->g_type = SIG_SWIPE;
5976 return EVAS_EVENT_FLAG_NONE;
5980 _elm_genlist_evas_object_smart_del(Eo *obj, Elm_Genlist_Data *sd)
5982 sd->no_cache = EINA_TRUE;
5983 elm_genlist_clear(obj);
5984 evas_event_callback_del_full(evas_object_evas_get(obj),
5985 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
5986 _evas_viewport_resize_cb, sd);
5987 if (sd->size_caches) eina_hash_free(sd->size_caches);
5988 if (sd->decorate_it_type) eina_stringshare_del(sd->decorate_it_type);
5990 evas_object_del(sd->pan_obj);
5991 eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
5995 _elm_genlist_evas_object_smart_move(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y)
5997 Evas_Coord ox, oy, bg_x, bg_y;
5999 if (!TIZEN_PROFILE_WEARABLE)
6001 evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
6002 evas_object_geometry_get(sd->banded_bg_rect, &bg_x, &bg_y, NULL, NULL);
6005 eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
6006 evas_object_move(sd->hit_rect, x, y);
6008 if (!TIZEN_PROFILE_WEARABLE)
6009 evas_object_move(sd->banded_bg_rect, (bg_x + x - ox), (bg_y + y - oy));
6013 _elm_genlist_evas_object_smart_resize(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord w, Evas_Coord h)
6015 eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
6017 evas_object_resize(sd->hit_rect, w, h);
6021 _elm_genlist_evas_object_smart_member_add(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *member)
6023 eo_do_super(obj, MY_CLASS, evas_obj_smart_member_add(member));
6026 evas_object_raise(sd->hit_rect);
6031 _elm_genlist_elm_widget_access(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool acs)
6034 Elm_Object_Item *eo_it;
6036 l = elm_genlist_realized_items_get(obj);
6038 EINA_LIST_FREE(l, eo_it)
6040 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6041 _item_unrealize(it, EINA_FALSE);
6044 sd->is_access = acs;
6046 _changed(sd->pan_obj);
6047 evas_object_smart_callback_call(obj, SIG_ACCESS_CHANGED, NULL);
6051 _evas_viewport_resize_cb(void *d, Evas *e EINA_UNUSED, void *ei EINA_UNUSED)
6053 Elm_Genlist_Data *priv = d;
6054 _changed(priv->pan_obj);
6058 _elm_genlist_evas_object_smart_add(Eo *obj, Elm_Genlist_Data *priv)
6060 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
6061 Evas_Coord minw, minh;
6062 Elm_Genlist_Pan_Data *pan_data;
6064 eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
6065 elm_widget_sub_object_parent_add(obj);
6067 priv->finger_minw = 0;
6068 priv->finger_minh = 0;
6069 elm_coords_finger_size_adjust(1, &priv->finger_minw, 1, &priv->finger_minh);
6071 priv->size_caches = eina_hash_string_small_new(_size_cache_free);
6072 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
6073 evas_object_smart_member_add(priv->hit_rect, obj);
6074 elm_widget_sub_object_add(obj, priv->hit_rect);
6076 /* common scroller hit rectangle setup */
6077 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
6078 evas_object_show(priv->hit_rect);
6079 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
6081 elm_widget_can_focus_set(obj, EINA_TRUE);
6082 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
6084 elm_layout_theme_set(obj, "genlist", "base", elm_widget_style_get(obj));
6086 if (!TIZEN_PROFILE_WEARABLE)
6087 _banded_bg_state_check(obj, priv);
6089 /* interface's add() routine issued AFTER the object's smart_add() */
6090 eo_do(obj, elm_interface_scrollable_objects_set(wd->resize_obj, priv->hit_rect));
6092 eo_do(obj, elm_interface_scrollable_bounce_allow_set
6093 (EINA_FALSE, _elm_config->thumbscroll_bounce_enable));
6094 priv->v_bounce = _elm_config->thumbscroll_bounce_enable;
6097 elm_interface_scrollable_animate_start_cb_set(_scroll_animate_start_cb),
6098 elm_interface_scrollable_animate_stop_cb_set(_scroll_animate_stop_cb),
6099 elm_interface_scrollable_scroll_cb_set(_scroll_cb),
6100 elm_interface_scrollable_drag_start_cb_set(_scroll_drag_start_cb),
6101 elm_interface_scrollable_drag_stop_cb_set(_scroll_drag_stop_cb),
6102 elm_interface_scrollable_edge_left_cb_set(_edge_left_cb),
6103 elm_interface_scrollable_edge_right_cb_set(_edge_right_cb),
6104 elm_interface_scrollable_edge_top_cb_set(_edge_top_cb),
6105 elm_interface_scrollable_edge_bottom_cb_set(_edge_bottom_cb),
6106 elm_interface_scrollable_vbar_drag_cb_set(_vbar_drag_cb),
6107 elm_interface_scrollable_vbar_press_cb_set(_vbar_press_cb),
6108 elm_interface_scrollable_vbar_unpress_cb_set(_vbar_unpress_cb),
6109 elm_interface_scrollable_hbar_drag_cb_set(_hbar_drag_cb),
6110 elm_interface_scrollable_hbar_press_cb_set(_hbar_press_cb),
6111 elm_interface_scrollable_hbar_unpress_cb_set(_hbar_unpress_cb));
6113 eo_do(obj, elm_interface_scrollable_content_min_limit_cb_set(_elm_genlist_content_min_limit_cb));
6115 priv->mode = ELM_LIST_SCROLL;
6116 priv->max_items_per_block = MAX_ITEMS_PER_BLOCK;
6117 priv->item_cache_max = priv->max_items_per_block * 2;
6118 priv->longpress_timeout = _elm_config->longpress_timeout;
6119 priv->highlight = EINA_TRUE;
6120 priv->fx_mode = EINA_FALSE;
6121 priv->on_hold = EINA_FALSE;
6124 if (!TIZEN_PROFILE_WEARABLE)
6125 priv->top_drawn_item = NULL;
6127 priv->pan_obj = eo_add(MY_PAN_CLASS, evas_object_evas_get(obj));
6128 pan_data = eo_data_scope_get(priv->pan_obj, MY_PAN_CLASS);
6129 eo_data_ref(obj, NULL);
6131 pan_data->wobj = obj;
6133 pan_data->wsd = priv;
6136 // FIXME: difference from upstream
6137 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_DOWN,
6138 _mouse_down_scroller, obj);
6139 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_UP,
6140 _mouse_up_scroller, obj);
6141 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_MOVE,
6142 _mouse_move_scroller, obj);
6145 eo_do(obj, elm_interface_scrollable_extern_pan_set(priv->pan_obj));
6147 edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
6148 evas_object_size_hint_min_set(obj, minw, minh);
6150 _item_cache_all_free(priv);
6151 _mirrored_set(obj, elm_widget_mirrored_get(obj));
6153 const char *str = edje_object_data_get(wd->resize_obj,
6155 if ((str) && (!strcmp(str, "on")))
6156 elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
6158 elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
6159 priv->select_on_focus_enabled = EINA_FALSE;
6160 elm_widget_signal_callback_add(obj, "elm,action,focus_highlight,hide", "elm", _elm_genlist_focus_highlight_hide, obj);
6161 elm_widget_signal_callback_add(obj, "elm,action,focus_highlight,show", "elm", _elm_genlist_focus_highlight_show, obj);
6162 evas_event_callback_add(evas_object_evas_get(obj),
6163 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
6164 _evas_viewport_resize_cb, priv);
6166 priv->g_layer = elm_gesture_layer_add(obj);
6167 if (!priv->g_layer) ERR("elm_gesture_layer_add() failed");
6168 elm_gesture_layer_attach(priv->g_layer, priv->hit_rect);
6169 elm_gesture_layer_cb_set
6170 (priv->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_START,
6171 _pinch_zoom_start_cb, priv);
6172 elm_gesture_layer_cb_set
6173 (priv->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE,
6174 _pinch_zoom_cb, priv);
6176 elm_gesture_layer_cb_set
6177 (priv->g_layer, ELM_GESTURE_N_LINES, ELM_GESTURE_STATE_START,
6178 _gesture_n_lines_start_cb, priv);
6179 elm_gesture_layer_cb_set
6180 (priv->g_layer, ELM_GESTURE_N_LINES, ELM_GESTURE_STATE_MOVE,
6181 _gesture_n_lines_cb, priv);
6183 elm_gesture_layer_cb_set
6184 (priv->g_layer, ELM_GESTURE_N_FLICKS, ELM_GESTURE_STATE_START,
6185 _gesture_n_lines_start_cb, priv);
6186 elm_gesture_layer_cb_set
6187 (priv->g_layer, ELM_GESTURE_N_FLICKS, ELM_GESTURE_STATE_MOVE,
6188 _gesture_n_flicks_cb, priv);
6190 elm_layout_sizing_eval(obj);
6192 // TIZEN_ONLY(20150705): Genlist item align feature
6193 wd->scroll_item_align_enable = _elm_config->scroll_item_align_enable;
6194 wd->scroll_item_valign = _elm_config->scroll_item_valign;
6196 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
6197 (NULL, NULL, &priv->viewport_w, &priv->viewport_h));
6200 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
6201 //register/unregister access objects accordingly.
6202 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6204 _elm_genlist_elm_widget_screen_reader(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool is_screen_reader)
6207 Eina_Bool done = EINA_FALSE;
6208 Evas_Object *content = NULL;
6212 EINA_INLIST_FOREACH(sd->blocks, itb)
6217 EINA_LIST_FOREACH(itb->items, l, it)
6219 if (!it->realized || it->want_hidden) continue;
6220 if (is_screen_reader)
6222 elm_interface_atspi_accessible_added(EO_OBJ(it));
6223 elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
6224 EINA_LIST_FOREACH(it->content_objs, ll, content)
6226 if (eo_isa(content, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
6228 eo_do(content, elm_interface_atspi_accessible_parent_set(EO_OBJ(it)));
6229 elm_interface_atspi_accessible_children_changed_added_signal_emit(EO_OBJ(it), content);
6232 elm_interface_atspi_accessible_name_changed_signal_emit(EO_OBJ(it));
6236 elm_interface_atspi_accessible_removed(EO_OBJ(it));
6237 elm_interface_atspi_accessible_children_changed_del_signal_emit(sd->obj, EO_OBJ(it));
6241 else if (done) break;
6244 //TIZEN_ONLY(20161213): apply screen_reader_changed callback
6245 evas_object_smart_callback_call(obj, SIG_ATSPI_SCREEN_READER_CHANGED, &is_screen_reader);
6251 EOLIAN const Elm_Atspi_Action *
6252 _elm_genlist_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd EINA_UNUSED)
6254 /* Need to be implemented
6255 static Elm_Atspi_Action atspi_actions[] = {
6256 { "move,prior", "move", "prior", _key_action_move},
6257 { "move,next", "move", "next", _key_action_move},
6258 { "move,left", "move", "left", _key_action_move},
6259 { "move,right", "move", "right", _key_action_move},
6260 { "move,up", "move", "up", _key_action_move},
6261 { "move,up,multi", "move", "up_multi", _key_action_move},
6262 { "move,down", "move", "down", _key_action_move},
6263 { "move,down,multi", "move", "down_multi", _key_action_move},
6264 { "move,first", "move", "first", _key_action_move},
6265 { "move,last", "move", "last", _key_action_move},
6266 { "select", "select", NULL, _key_action_select},
6267 { "select,multi", "select", "multi", _key_action_select},
6268 { "escape", "escape", NULL, _key_action_escape},
6269 { NULL, NULL, NULL, NULL }
6271 return &atspi_actions[0];
6273 static Elm_Atspi_Action atspi_actions[] = {{NULL, NULL, NULL, NULL}};
6274 return &atspi_actions[0];
6278 elm_genlist_add(Evas_Object *parent)
6280 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
6281 Evas_Object *obj = eo_add(MY_CLASS, parent);
6286 _elm_genlist_eo_base_constructor(Eo *obj, Elm_Genlist_Data *sd)
6288 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
6292 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
6293 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
6294 elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST));
6299 EOLIAN static Evas_Object *
6300 _elm_genlist_item_elm_widget_item_part_content_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6302 Evas_Object *ret = NULL;
6303 if (it->deco_all_view)
6304 ret = edje_object_part_swallow_get(it->deco_all_view, part);
6305 else if (it->decorate_it_set)
6306 ret = edje_object_part_swallow_get(GL_IT(it)->deco_it_view, part);
6308 ret = edje_object_part_swallow_get(VIEW(it), part);
6312 EOLIAN static const char *
6313 _elm_genlist_item_elm_widget_item_part_text_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6315 if (!it->itc->func.text_get) return NULL;
6316 const char *ret = NULL;
6317 if (it->deco_all_view)
6318 ret = edje_object_part_text_get(it->deco_all_view, part);
6319 else if (it->decorate_it_set)
6320 ret = edje_object_part_text_get(GL_IT(it)->deco_it_view, part);
6322 ret = edje_object_part_text_get(VIEW(it), part);
6327 _elm_genlist_item_elm_widget_item_disable(Eo *eo_it, Elm_Gen_Item *it)
6334 if (it == GL_IT(it)->wsd->focused_item) elm_object_item_focus_set(EO_OBJ(it), EINA_FALSE);
6335 if (GL_IT(it)->highlight_timer)
6337 ecore_timer_del(GL_IT(it)->highlight_timer);
6338 GL_IT(it)->highlight_timer = NULL;
6342 ecore_timer_del(it->long_timer);
6343 it->long_timer = NULL;
6348 if (eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get()))
6350 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
6351 if (it->deco_all_view)
6352 edje_object_signal_emit
6353 (it->deco_all_view, SIGNAL_DISABLED, "elm");
6357 edje_object_signal_emit(VIEW(it), SIGNAL_ENABLED, "elm");
6358 if (it->deco_all_view)
6359 edje_object_signal_emit
6360 (it->deco_all_view, SIGNAL_ENABLED, "elm");
6362 EINA_LIST_FOREACH(it->content_objs, l, obj)
6363 elm_widget_disabled_set(obj, eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get()));
6368 _item_free(Elm_Gen_Item *it)
6371 Elm_Object_Item *eo_it2;
6372 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
6373 sd->processed_sizes -= GL_IT(it)->minh;
6374 if (sd->processed_sizes < 0) sd->processed_sizes = 0;
6376 eo_do(EO_OBJ(it), elm_wdg_item_pre_notify_del());
6377 if (it->tooltip.del_cb)
6378 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6380 #ifdef GENLIST_FX_SUPPORT
6381 sd->del_fx.items = eina_list_remove(sd->del_fx.items, it);
6382 sd->del_fx.pending_items = eina_list_remove(sd->del_fx.pending_items, it);
6383 sd->add_fx.items = eina_list_remove(sd->add_fx.items, it);
6387 GL_IT(it)->rel->item->rel_revs =
6388 eina_list_remove(GL_IT(it)->rel->item->rel_revs, it);
6389 if (GL_IT(it)->rel_revs)
6392 EINA_LIST_FREE(GL_IT(it)->rel_revs, tmp)
6394 if (tmp->item->queued && !(tmp->base)->on_deletion)
6396 GL_IT(tmp)->queued = EINA_FALSE;
6397 GL_IT(tmp)->resized = EINA_FALSE;
6398 sd->queue = eina_list_remove(sd->queue, tmp);
6399 _item_process(sd, tmp);
6401 tmp->item->rel = NULL;
6404 EINA_LIST_FOREACH_SAFE(it->item->items, l, ll, eo_it2)
6406 //elm_widget_item_del(it2);
6407 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6410 sd->reorder.move_items = eina_list_remove(sd->reorder.move_items, it);
6412 if (GL_IT(it)->block) _item_block_del(it);
6414 it->parent->item->items =
6415 eina_list_remove(it->parent->item->items, EO_OBJ(it));
6416 if (GL_IT(it)->queued)
6418 GL_IT(it)->queued = EINA_FALSE;
6419 sd->queue = eina_list_remove(sd->queue, it);
6421 if (sd->filter_queue && !it->filtered)
6423 l = eina_list_data_find_list(sd->filter_queue, it);
6424 if (l) sd->filter_queue = eina_list_remove_list(sd->filter_queue, l);
6426 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6427 sd->group_items = eina_list_remove(sd->group_items, it);
6431 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
6432 it->selected = EINA_FALSE;
6434 if (sd->show_item == it) sd->show_item = NULL;
6436 if ((sd->g_item) && (sd->g_item == it)) sd->g_item = NULL;
6437 if (sd->expanded_item == it) sd->expanded_item = NULL;
6438 if (sd->state) ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
6440 if (sd->last_selected_item == EO_OBJ(it))
6441 sd->last_selected_item = NULL;
6443 if (sd->realization_mode)
6446 EINA_LIST_FOREACH(GL_IT(it)->flip_content_objs, l, c)
6448 evas_object_event_callback_del_full(c,
6449 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6450 _changed_size_hints, it);
6452 EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, c)
6454 evas_object_event_callback_del_full(c,
6455 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6456 _changed_size_hints, it);
6458 EINA_LIST_FOREACH(it->content_objs, l, c)
6460 evas_object_event_callback_del_full(c,
6461 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6462 _changed_size_hints, it);
6466 if (sd->mode_item) sd->mode_item = NULL;
6467 if (it->selected) _item_unselect(it);
6468 if (it == sd->focused_item)
6472 if (!elm_widget_focus_get(WIDGET(it))) goto failed;
6474 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6475 find = _item_focusable_search(&tmp, 1);
6478 elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
6483 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6484 find = _item_focusable_search(&tmp, -1);
6487 elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
6492 elm_object_item_focus_set(EO_OBJ(it), EINA_FALSE);
6493 sd->focused_item = NULL;
6496 if (it == sd->key_down_item) sd->key_down_item = NULL;
6497 if (it == sd->highlighted_item) sd->highlighted_item = NULL;
6498 if (!TIZEN_PROFILE_WEARABLE)
6500 if (it == sd->top_drawn_item) sd->top_drawn_item = NULL;
6503 _item_unrealize(it, EINA_FALSE);
6505 if (sd->aligned_item == it) sd->aligned_item = NULL;
6507 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
6510 if (it->item->proxy)
6512 evas_object_smart_member_del(it->item->proxy);
6513 evas_object_del(it->item->proxy);
6516 if (it->itc->func.del)
6517 it->itc->func.del((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it));
6519 if (it->itc->refcount <= 1)
6523 EINA_INLIST_FOREACH_SAFE(sd->item_cache, l2, ic)
6525 if (it->itc == ic->item_class)
6526 _item_cache_free(sd, ic);
6530 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
6535 // TIZEN_ONLY(20150703) : banded color background feature. enabled only un-scrollable
6536 if (!TIZEN_PROFILE_WEARABLE)
6538 if (sd->banded_bg_rect && !sd->items)
6540 evas_object_smart_member_del(sd->banded_bg_rect);
6541 ELM_SAFE_FREE(sd->banded_bg_rect, evas_object_del);
6545 _changed(sd->pan_obj);
6548 EOLIAN static Eina_Bool
6549 _elm_genlist_item_elm_widget_item_del_pre(Eo *eo_it EINA_UNUSED,
6552 #ifdef GENLIST_FX_SUPPORT
6553 Elm_Genlist_Data *sd = it->item->wsd;
6554 Evas_Coord cvx, cvy, cvw, cvh;
6561 #ifdef GENLIST_FX_SUPPORT
6564 sd->add_fx.items = eina_list_remove(sd->add_fx.items, it);
6567 evas_output_viewport_get(evas_object_evas_get(sd->obj),
6568 &cvx, &cvy, &cvw, &cvh);
6569 if (!ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
6570 GL_IT(it)->w, GL_IT(it)->h,
6571 cvx, cvy, cvw, cvh))
6573 // Delete later, Above items in the viewport
6574 // Delete right now, below items in the viewport
6575 if (it->item->scrl_y < cvy)
6576 sd->del_fx.pending_items = eina_list_append(sd->del_fx.pending_items, it);
6580 _changed(sd->pan_obj);
6586 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
6587 else if (it->item->deco_it_view) evas_object_lower(it->item->deco_it_view);
6588 else if (VIEW(it)) evas_object_lower(VIEW(it));
6590 if (it->item->expanded_depth > 0)
6593 Elm_Object_Item *itt;
6594 EINA_LIST_FOREACH(it->item->items, l, itt)
6596 eo_do(itt, elm_wdg_item_del());
6599 sd->del_fx.items = eina_list_append(sd->del_fx.items, it);
6601 if (!sd->del_fx.anim)
6603 sd->del_fx.cnt = ANIM_CNT_MAX;
6604 sd->del_fx.anim = ecore_animator_add(_del_fx_anim, sd);
6606 _changed(sd->pan_obj);
6612 _elm_genlist_item_elm_widget_item_signal_emit(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char *emission, const char *source)
6616 WRN("item is not realized yet");
6619 edje_object_signal_emit
6620 (VIEW(it), emission, source);
6621 if (it->deco_all_view)
6622 edje_object_signal_emit
6623 (it->deco_all_view, emission, source);
6627 _elm_genlist_item_eo_base_constructor(Eo *eo_it, Elm_Gen_Item *it)
6629 eo_it = eo_do_super_ret(eo_it, ELM_GENLIST_ITEM_CLASS, eo_it, eo_constructor());
6631 it->base = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
6632 eo_do(eo_it, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST_ITEM));
6636 static Elm_Gen_Item *
6637 _elm_genlist_item_new(Elm_Genlist_Data *sd,
6638 const Elm_Genlist_Item_Class *itc,
6640 Elm_Object_Item *eo_parent,
6641 Elm_Genlist_Item_Type type,
6643 const void *func_data)
6648 if (!itc) return NULL;
6650 Eo *eo_it = eo_add(ELM_GENLIST_ITEM_CLASS, sd->obj);
6651 if (!eo_it) return NULL;
6652 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6655 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
6657 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6658 WIDGET_ITEM_DATA_SET(EO_OBJ(it), data);
6659 it->parent = parent;
6660 it->func.func = func;
6661 it->func.data = func_data;
6663 GL_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
6664 GL_IT(it)->wsd = sd;
6665 GL_IT(it)->type = type;
6669 if (GL_IT(it->parent)->type == ELM_GENLIST_ITEM_GROUP)
6670 GL_IT(it)->group_item = parent;
6671 else if (GL_IT(it->parent)->group_item)
6672 GL_IT(it)->group_item = GL_IT(it->parent)->group_item;
6674 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
6676 if (GL_IT(it2->parent)->type == ELM_GENLIST_ITEM_TREE) depth += 1;
6678 GL_IT(it)->expanded_depth = depth;
6685 _elm_genlist_item_compare(const void *data,
6688 const Elm_Gen_Item *it, *item1;
6690 it = ELM_GEN_ITEM_FROM_INLIST(data);
6691 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
6692 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6696 _elm_genlist_item_list_compare(const void *data,
6699 const Elm_Gen_Item *it = data;
6700 const Elm_Gen_Item *item1 = data1;
6702 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6705 EOLIAN static unsigned int
6706 _elm_genlist_items_count(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6708 return sd->item_count;
6712 _list_last_recursive(Eina_List *list)
6714 Eina_List *ll, *ll2;
6715 Elm_Object_Item *eo_it2;
6717 ll = eina_list_last(list);
6718 if (!ll) return NULL;
6721 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6723 if (it2->item->items)
6725 ll2 = _list_last_recursive(it2->item->items);
6735 EOLIAN static Elm_Object_Item*
6736 _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)
6740 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6744 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6745 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6746 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6749 it = _elm_genlist_item_new
6750 (sd, itc, data, eo_parent, type, func, func_data);
6751 if (!it) return NULL;
6755 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6756 sd->group_items = eina_list_append(sd->group_items, it);
6757 sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
6758 GL_IT(it)->rel = NULL;
6762 Elm_Object_Item *eo_it2 = NULL;
6763 Eina_List *ll = _list_last_recursive(it->parent->item->items);
6765 if (ll) eo_it2 = ll->data;
6766 it->parent->item->items =
6767 eina_list_append(it->parent->item->items, EO_OBJ(it));
6768 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6769 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6770 sd->items = eina_inlist_append_relative
6771 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6772 GL_IT(it)->rel = it2;
6773 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6775 GL_IT(it)->before = EINA_FALSE;
6776 _item_queue_direct(it, NULL);
6780 EOLIAN static Elm_Object_Item*
6781 _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)
6783 Elm_Gen_Item *it = NULL;
6785 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6788 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6789 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6790 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6791 /* first sub-item should allways be appended */
6792 if (!parent->item->items)
6793 return _elm_genlist_item_append(obj, sd, itc, data, eo_parent, type, func, func_data);
6795 it = _elm_genlist_item_new
6796 (sd, itc, data, eo_parent, type, func, func_data);
6798 if (!it) return NULL;
6800 if (sd->items) GL_IT(it)->is_prepend = EINA_TRUE;
6803 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6804 sd->group_items = eina_list_prepend(sd->group_items, it);
6805 sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
6806 GL_IT(it)->rel = NULL;
6810 Elm_Object_Item *eo_it2 = NULL;
6811 Eina_List *ll = it->parent->item->items;
6813 if (ll) eo_it2 = ll->data;
6814 it->parent->item->items =
6815 eina_list_prepend(it->parent->item->items, EO_OBJ(it));
6816 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6817 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6820 sd->items = eina_inlist_prepend_relative
6821 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6822 GL_IT(it)->rel = it2;
6823 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6826 GL_IT(it)->before = EINA_TRUE;
6827 _item_queue_direct(it, NULL);
6831 EOLIAN static Elm_Object_Item*
6832 _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)
6834 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_after, NULL);
6835 ELM_GENLIST_ITEM_DATA_GET(eo_after, after_it);
6838 ELM_GENLIST_ITEM_CHECK_OR_RETURN(after_it, NULL);
6839 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(after_it), NULL);
6842 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6843 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6844 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6847 /* It makes no sense to insert after in an empty list with after !=
6848 * NULL, something really bad is happening in your app. */
6849 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6851 it = _elm_genlist_item_new
6852 (sd, itc, data, eo_parent, type, func, func_data);
6853 if (!it) return NULL;
6857 if ((GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) &&
6858 (GL_IT(after_it)->type == ELM_GENLIST_ITEM_GROUP))
6859 sd->group_items = eina_list_append_relative
6860 (sd->group_items, it, after_it);
6864 it->parent->item->items =
6865 eina_list_append_relative(it->parent->item->items, EO_OBJ(it), eo_after);
6867 sd->items = eina_inlist_append_relative
6868 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after_it));
6870 GL_IT(it)->rel = after_it;
6871 after_it->item->rel_revs = eina_list_append(after_it->item->rel_revs, it);
6872 GL_IT(it)->before = EINA_FALSE;
6873 _item_queue_direct(it, NULL);
6875 if (elm_genlist_item_next_get(eo_after) == EO_OBJ(sd->aligned_item))
6876 sd->aligned_item = NULL;
6880 EOLIAN static Elm_Object_Item*
6881 _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)
6883 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_before, NULL);
6884 ELM_GENLIST_ITEM_DATA_GET(eo_before, before_it);
6887 ELM_GENLIST_ITEM_CHECK_OR_RETURN(before_it, NULL);
6888 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(before_it), NULL);
6891 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6892 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6893 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6896 /* It makes no sense to insert before in an empty list with before
6897 * != NULL, something really bad is happening in your app. */
6898 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6900 it = _elm_genlist_item_new
6901 (sd, itc, data, eo_parent, type, func, func_data);
6902 if (!it) return NULL;
6906 if ((GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) &&
6907 (GL_IT(before_it)->type == ELM_GENLIST_ITEM_GROUP))
6909 eina_list_prepend_relative(sd->group_items, it, before_it);
6913 it->parent->item->items =
6914 eina_list_prepend_relative(it->parent->item->items, EO_OBJ(it), eo_before);
6916 sd->items = eina_inlist_prepend_relative
6917 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before_it));
6919 GL_IT(it)->rel = before_it;
6920 before_it->item->rel_revs = eina_list_append(before_it->item->rel_revs, it);
6921 GL_IT(it)->before = EINA_TRUE;
6922 _item_queue_direct(it, NULL);
6924 if (before_it == sd->aligned_item)
6925 sd->aligned_item = NULL;
6930 EOLIAN static Elm_Object_Item*
6931 _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)
6933 Elm_Gen_Item *rel = NULL;
6935 Elm_Object_Item *eo_it;
6939 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6940 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6941 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6944 it = _elm_genlist_item_new
6945 (sd, itc, data, eo_parent, type, func, func_data);
6946 if (!it) return NULL;
6949 sd->item_compare_cb = comp;
6953 Elm_Object_Item *eo_rel = NULL;
6957 l = eina_list_search_sorted_near_list
6958 (it->parent->item->items, _elm_genlist_item_list_compare, eo_it,
6963 eo_rel = eina_list_data_get(l);
6964 rel = eo_data_scope_get(eo_rel, ELM_GENLIST_ITEM_CLASS);
6966 if (cmp_result >= 0)
6968 it->parent->item->items = eina_list_prepend_relative_list
6969 (it->parent->item->items, eo_it, l);
6970 sd->items = eina_inlist_prepend_relative
6971 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6972 it->item->before = EINA_TRUE;
6974 else if (cmp_result < 0)
6976 it->parent->item->items = eina_list_append_relative_list
6977 (it->parent->item->items, eo_it, l);
6978 sd->items = eina_inlist_append_relative
6979 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6980 it->item->before = EINA_FALSE;
6981 it->item->is_prepend = EINA_TRUE;
6988 // ignoring the comparison
6989 it->parent->item->items = eina_list_prepend_relative_list
6990 (it->parent->item->items, eo_it, l);
6991 sd->items = eina_inlist_prepend_relative
6992 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6993 it->item->before = EINA_FALSE;
7000 sd->state = eina_inlist_sorted_state_new();
7001 eina_inlist_sorted_state_init(sd->state, sd->items);
7002 sd->requeued = EINA_FALSE;
7005 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
7006 sd->group_items = eina_list_append(sd->group_items, it);
7008 sd->items = eina_inlist_sorted_state_insert
7009 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
7012 if (EINA_INLIST_GET(it)->next)
7014 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
7015 GL_IT(it)->before = EINA_TRUE;
7016 GL_IT(it)->is_prepend = EINA_TRUE;
7018 else if (EINA_INLIST_GET(it)->prev)
7020 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7021 GL_IT(it)->before = EINA_FALSE;
7027 GL_IT(it)->rel = rel;
7028 rel->item->rel_revs = eina_list_append(rel->item->rel_revs, it);
7031 _item_queue_direct(it, _elm_genlist_item_list_compare);
7036 _elm_genlist_clear(Eo *obj, Elm_Genlist_Data *sd)
7040 eina_hash_free_buckets(sd->size_caches);
7041 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
7042 if (sd->key_down_item) sd->key_down_item = NULL;
7043 if (sd->mode_item) sd->mode_item = NULL;
7047 eina_inlist_sorted_state_free(sd->state);
7051 sd->filter_data = NULL;
7052 if (sd->filter_queue)
7053 ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
7054 ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
7055 ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
7057 // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
7058 // because sd->items can be modified inside elm_widget_item_del()
7061 it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
7062 //elm_widget_item_del(it);
7065 sd->reorder.it = NULL;
7066 sd->reorder.dir = 0;
7067 eina_list_free(sd->reorder.move_items);
7071 _item_cache_all_free(sd);
7075 sd->selected = eina_list_free(sd->selected);
7076 sd->selected = NULL;
7079 sd->show_item = NULL;
7088 evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
7089 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
7091 elm_layout_sizing_eval(obj);
7093 eo_do(sd->obj, elm_interface_scrollable_content_region_show(0, 0, 0, 0));
7097 ecore_job_del(sd->dummy_job);
7098 sd->dummy_job = NULL;
7100 if (sd->queue_idle_enterer)
7102 ecore_idle_enterer_del(sd->queue_idle_enterer);
7103 sd->queue_idle_enterer = NULL;
7105 if (sd->scr_hold_timer)
7107 ecore_timer_del(sd->scr_hold_timer);
7108 sd->scr_hold_timer = NULL;
7110 if (sd->reorder.anim)
7112 ecore_animator_del(sd->reorder.anim);
7113 sd->reorder.anim = NULL;
7117 ecore_timer_del(sd->scr_timer);
7118 sd->scr_timer = NULL;
7120 #ifdef GENLIST_FX_SUPPORT
7121 if (sd->del_fx.anim)
7123 ecore_animator_del(sd->del_fx.anim);
7124 sd->del_fx.anim = NULL;
7126 if (sd->add_fx.anim)
7128 ecore_animator_del(sd->add_fx.anim);
7129 sd->add_fx.anim = NULL;
7133 if (sd->queue) sd->queue = eina_list_free(sd->queue);
7134 if (sd->g_item) sd->g_item = NULL;
7135 if (sd->g_type) sd->g_type = NULL;
7137 if (!TIZEN_PROFILE_WEARABLE)
7139 if (sd->banded_bg_rect)
7141 evas_object_smart_member_del(sd->banded_bg_rect);
7142 ELM_SAFE_FREE(sd->banded_bg_rect, evas_object_del);
7148 _elm_genlist_multi_select_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool multi)
7150 sd->multi = !!multi;
7151 if (!sd->multi && sd->selected)
7154 Elm_Object_Item *eo_it;
7155 Elm_Object_Item *last = sd->selected->data;
7156 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
7159 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
7165 EOLIAN static Eina_Bool
7166 _elm_genlist_multi_select_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7172 _elm_genlist_multi_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Elm_Object_Multi_Select_Mode mode EINA_UNUSED)
7174 /* Need to be implemented
7175 if (mode >= ELM_OBJECT_MULTI_SELECT_MODE_MAX)
7178 if (sd->multi_select_mode != mode)
7179 sd->multi_select_mode = mode;
7184 EOLIAN static Elm_Object_Multi_Select_Mode
7185 _elm_genlist_multi_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
7187 // Need to be implemented
7188 //return sd->multi_select_mode;
7189 return ELM_OBJECT_MULTI_SELECT_MODE_DEFAULT;
7192 EOLIAN static Elm_Object_Item*
7193 _elm_genlist_selected_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7196 return sd->selected->data;
7201 EOLIAN static const Eina_List*
7202 _elm_genlist_selected_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7204 return sd->selected;
7207 EOLIAN static Eina_List*
7208 _elm_genlist_realized_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7211 Eina_List *list = NULL;
7212 Eina_Bool done = EINA_FALSE;
7214 EINA_INLIST_FOREACH(sd->blocks, itb)
7222 EINA_LIST_FOREACH(itb->items, l, it)
7224 if (it->realized) list = eina_list_append(list, EO_OBJ(it));
7235 EOLIAN static Elm_Object_Item *
7236 _elm_genlist_search_by_text_item_get(Eo *obj EINA_UNUSED,
7237 Elm_Genlist_Data *sd,
7238 Elm_Object_Item *item_to_search_from,
7239 const char *part_name,
7240 const char *pattern,
7241 Elm_Glob_Match_Flags flags)
7243 Elm_Gen_Item *it = NULL;
7245 Eina_Inlist *start = NULL;
7248 if (!pattern) return NULL;
7249 if (!sd->items) return NULL;
7251 if (flags & ELM_GLOB_MATCH_NO_ESCAPE) fnflags |= FNM_NOESCAPE;
7252 if (flags & ELM_GLOB_MATCH_PATH) fnflags |= FNM_PATHNAME;
7253 if (flags & ELM_GLOB_MATCH_PERIOD) fnflags |= FNM_PERIOD;
7255 if (flags & ELM_GLOB_MATCH_NOCASE) fnflags |= FNM_CASEFOLD;
7258 start = (item_to_search_from) ?
7259 EINA_INLIST_GET((Elm_Gen_Item *)eo_data_scope_get(item_to_search_from, ELM_GENLIST_ITEM_CLASS)) :
7261 EINA_INLIST_FOREACH(start, it)
7263 if (!it->itc->func.text_get) continue;
7264 str = it->itc->func.text_get((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), part_name);
7266 if (!fnmatch(pattern, str, fnflags))
7276 EOLIAN static Elm_Object_Item*
7277 _elm_genlist_at_xy_item_get(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y, int *posret)
7279 Evas_Coord ox, oy, ow, oh;
7283 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7285 EINA_INLIST_FOREACH(sd->blocks, itb)
7289 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->sd->pan_x,
7290 oy + itb->y - itb->sd->pan_y,
7291 sd->minw, itb->minh, x, y, 1, 1))
7293 EINA_LIST_FOREACH(itb->items, l, it)
7295 Evas_Coord itx, ity;
7297 itx = ox + itb->x + it->x - itb->sd->pan_x;
7298 ity = oy + itb->y + it->y - itb->sd->pan_y;
7299 if (ELM_RECTS_INTERSECT
7300 (itx, ity, GL_IT(it)->w, GL_IT(it)->h, x, y, 1, 1))
7304 if (y <= (ity + (GL_IT(it)->h / 4))) *posret = -1;
7305 else if (y >= (ity + GL_IT(it)->h - (GL_IT(it)->h / 4)))
7312 lasty = ity + GL_IT(it)->h;
7317 if (y > lasty) *posret = 1;
7324 EOLIAN static Elm_Object_Item*
7325 _elm_genlist_first_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7327 Elm_Gen_Item *tit, *it = NULL;
7329 EINA_INLIST_REVERSE_FOREACH(sd->items, tit) it = tit;
7334 EOLIAN static Elm_Object_Item*
7335 _elm_genlist_last_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7339 if (!sd->items) return NULL;
7341 it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
7345 EOLIAN static Elm_Object_Item *
7346 _elm_genlist_item_next_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7350 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
7354 if (it) return EO_OBJ(it);
7358 EOLIAN static Elm_Object_Item *
7359 _elm_genlist_item_prev_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7363 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7367 if (it) return EO_OBJ(it);
7371 EOLIAN static Elm_Object_Item *
7372 _elm_genlist_item_parent_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7374 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
7376 return EO_OBJ(it->parent);
7379 EOLIAN static unsigned int
7380 _elm_genlist_item_subitems_count(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
7382 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, 0);
7384 return eina_list_count(item->item->items);
7387 EOLIAN static const Eina_List *
7388 _elm_genlist_item_subitems_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
7390 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
7392 return item->item->items;
7396 _elm_genlist_item_subitems_clear(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7398 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7400 Elm_Object_Item *eo_it2;
7402 EINA_LIST_FOREACH_SAFE(GL_IT(it)->items, l, ll, eo_it2)
7403 eo_do(eo_it2, elm_wdg_item_del());
7407 _elm_genlist_item_selected_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
7410 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7413 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get())) return;
7414 // FIXME: This API has highlight/unhighlith feature also..
7416 if (selected) _item_highlight(it);
7417 else _item_unhighlight(it, EINA_TRUE);
7419 selected = !!selected;
7420 if (it->selected == selected) return;
7422 if (selected) _item_select(it);
7423 else _item_unselect(it);
7426 EOLIAN static Eina_Bool
7427 _elm_genlist_item_selected_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7429 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7431 return it->selected;
7435 _elm_genlist_item_expanded_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool expanded)
7437 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7439 expanded = !!expanded;
7440 if (GL_IT(it)->expanded == expanded) return;
7441 if (GL_IT(it)->type != ELM_GENLIST_ITEM_TREE) return;
7442 GL_IT(it)->expanded = expanded;
7443 GL_IT(it)->wsd->expanded_item = it;
7445 if (GL_IT(it)->expanded)
7448 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
7449 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, EO_OBJ(it));
7450 if (_elm_atspi_enabled())
7451 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_item);
7456 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACTED, "elm");
7457 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, EO_OBJ(it));
7458 if (_elm_atspi_enabled())
7459 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_item);
7463 EOLIAN static Eina_Bool
7464 _elm_genlist_item_expanded_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7466 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7468 return GL_IT(it)->expanded;
7472 _elm_genlist_item_expanded_depth_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7474 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, 0);
7476 return GL_IT(it)->expanded_depth;
7480 _elm_genlist_item_promote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7482 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7484 Elm_Object_Item *eo_first_item = elm_genlist_first_item_get(WIDGET(it));
7485 ELM_GENLIST_ITEM_DATA_GET(eo_first_item, first_item);
7486 _item_move_before(it, first_item);
7490 _elm_genlist_item_demote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7492 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7493 Elm_Object_Item *eo_last_item = elm_genlist_last_item_get(WIDGET(it));
7494 ELM_GENLIST_ITEM_DATA_GET(eo_last_item, last_item);
7495 _item_move_after(it, last_item);
7499 _elm_genlist_item_show(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
7501 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7503 if (it->want_hidden)
7505 WRN("Filter hided item cannot move to show");
7509 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7511 sd->bring_in = EINA_FALSE;
7512 sd->scroll_to_type = type;
7513 _changed(sd->pan_obj);
7517 _elm_genlist_item_bring_in(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
7519 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7521 if (it->want_hidden)
7523 WRN("Filter hided item cannot move to bring in");
7527 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7528 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wd);
7529 sd->bring_in = EINA_TRUE;
7530 sd->scroll_to_type = type;
7532 if (wd->scroll_item_align_enable)
7534 it = _adjust_item_align(it);
7535 sd->adjusted_item = sd->show_item = it;
7537 if (sd->aligned_item && sd->show_item != sd->aligned_item)
7538 edje_object_signal_emit(VIEW(sd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
7543 _changed(sd->pan_obj);
7547 _elm_genlist_item_all_contents_unset(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_List **l)
7549 Evas_Object *content;
7551 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7553 EINA_LIST_FREE (it->content_objs, content)
7555 evas_object_smart_member_del(content);
7556 // edje can be reused by item caching,
7557 // content should be un-swallowed from edje
7558 edje_object_part_unswallow(VIEW(it), content);
7559 evas_object_hide(content);
7560 if (l) *l = eina_list_append(*l, content);
7565 _elm_genlist_item_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7567 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7569 if (!GL_IT(it)->block) return;
7571 GL_IT(it)->updateme = EINA_TRUE;
7572 GL_IT(it)->block->calc_done = EINA_FALSE;
7573 GL_IT(it)->wsd->calc_done = EINA_FALSE;
7574 _changed(GL_IT(it)->wsd->pan_obj);
7578 _elm_genlist_item_fields_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
7580 Elm_Genlist_Item_Field_Type itf)
7582 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7584 if (!GL_IT(it)->block) return;
7586 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
7588 _item_text_realize(it, VIEW(it), parts);
7590 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
7592 _item_content_realize(it, VIEW(it), &it->content_objs, "contents", parts);
7595 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_content_objs,
7598 if (GL_IT(it)->deco_it_view)
7600 _item_content_realize(it, GL_IT(it)->deco_it_view,
7601 &GL_IT(it)->deco_it_contents,
7604 if (GL_IT(it)->wsd->decorate_all_mode)
7606 _item_content_realize(it, it->deco_all_view,
7607 &GL_IT(it)->deco_all_contents,
7612 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
7613 _item_state_realize(it, VIEW(it), parts);
7615 GL_IT(it)->calc_done = EINA_FALSE;
7616 GL_IT(it)->block->calc_done = EINA_FALSE;
7617 GL_IT(it)->wsd->calc_done = EINA_FALSE;
7618 _changed(GL_IT(it)->wsd->pan_obj);
7622 _elm_genlist_item_item_class_update(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
7623 const Elm_Genlist_Item_Class *itc)
7625 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7626 EINA_SAFETY_ON_NULL_RETURN(itc);
7627 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7630 if (!GL_IT(it)->block) return;
7632 // FIXME(160711): orignal edje object updated by _view_theme_update
7633 // cannot recieve signal emit properly. This edje bug must be fixed.
7634 _item_cache_all_free(sd);
7636 sd->no_cache = EINA_TRUE;
7637 _item_unrealize(it, EINA_FALSE);
7638 sd->no_cache = EINA_FALSE;
7639 _item_realize(it, EINA_FALSE);
7641 if (sd->aligned_item == it)
7642 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
7644 GL_IT(it)->calc_done = EINA_FALSE;
7645 GL_IT(it)->block->calc_done = EINA_FALSE;
7646 sd->calc_done = EINA_FALSE;
7648 _changed(sd->pan_obj);
7651 EOLIAN static const Elm_Genlist_Item_Class *
7652 _elm_genlist_item_item_class_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7654 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
7658 static Evas_Object *
7659 _elm_genlist_item_label_create(void *data,
7660 Evas_Object *obj EINA_UNUSED,
7661 Evas_Object *tooltip,
7662 void *it EINA_UNUSED)
7664 Evas_Object *label = elm_label_add(tooltip);
7669 elm_object_style_set(label, "tooltip");
7670 elm_object_text_set(label, data);
7676 _elm_genlist_item_label_del_cb(void *data,
7677 Evas_Object *obj EINA_UNUSED,
7678 void *event_info EINA_UNUSED)
7680 eina_stringshare_del(data);
7684 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
7687 eo_do(it, elm_wdg_item_tooltip_text_set(text));
7691 _elm_genlist_item_elm_widget_item_tooltip_text_set(Eo *eo_it, Elm_Gen_Item *it, const char *text)
7693 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7695 text = eina_stringshare_add(text);
7696 elm_genlist_item_tooltip_content_cb_set
7697 (eo_it, _elm_genlist_item_label_create, text,
7698 _elm_genlist_item_label_del_cb);
7702 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item,
7703 Elm_Tooltip_Item_Content_Cb func,
7705 Evas_Smart_Cb del_cb)
7707 eo_do(item, elm_wdg_item_tooltip_content_cb_set(func, data, del_cb));
7712 _elm_genlist_item_elm_widget_item_tooltip_content_cb_set(Eo *eo_it, Elm_Gen_Item *it,
7713 Elm_Tooltip_Item_Content_Cb func,
7715 Evas_Smart_Cb del_cb)
7717 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7719 if ((it->tooltip.content_cb != func) || (it->tooltip.data != data))
7721 if (it->tooltip.del_cb)
7722 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7724 it->tooltip.content_cb = func;
7725 it->tooltip.data = data;
7726 it->tooltip.del_cb = del_cb;
7731 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7732 elm_wdg_item_tooltip_content_cb_set
7733 (it->tooltip.content_cb, it->tooltip.data, NULL));
7735 elm_wdg_item_tooltip_style_set(it->tooltip.style),
7736 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
7741 elm_genlist_item_tooltip_unset(Elm_Object_Item *item)
7743 eo_do(item, elm_wdg_item_tooltip_unset());
7747 _elm_genlist_item_elm_widget_item_tooltip_unset(Eo *eo_it, Elm_Gen_Item *it)
7749 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7751 if ((VIEW(it)) && (it->tooltip.content_cb))
7752 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7753 elm_wdg_item_tooltip_unset());
7755 if (it->tooltip.del_cb)
7756 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7757 it->tooltip.del_cb = NULL;
7758 it->tooltip.content_cb = NULL;
7759 it->tooltip.data = NULL;
7760 it->tooltip.free_size = EINA_FALSE;
7761 if (it->tooltip.style)
7762 eo_do(eo_it, elm_wdg_item_tooltip_style_set(NULL));
7766 elm_genlist_item_tooltip_style_set(Elm_Object_Item *item,
7769 eo_do(item, elm_wdg_item_tooltip_style_set(style));
7773 _elm_genlist_item_elm_widget_item_tooltip_style_set(Eo *eo_it, Elm_Gen_Item *it,
7776 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7778 eina_stringshare_replace(&it->tooltip.style, style);
7779 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7780 elm_wdg_item_tooltip_style_set(style));
7784 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
7787 return eo_do_ret(it, style, elm_wdg_item_tooltip_style_get());
7790 EOLIAN static const char *
7791 _elm_genlist_item_elm_widget_item_tooltip_style_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7793 return it->tooltip.style;
7797 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *item,
7801 return eo_do_ret(item, ret, elm_wdg_item_tooltip_window_mode_set(disable));
7804 EOLIAN static Eina_Bool
7805 _elm_genlist_item_elm_widget_item_tooltip_window_mode_set(Eo *eo_it, Elm_Gen_Item *it,
7808 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7811 it->tooltip.free_size = disable;
7813 return eo_do_super_ret(eo_it, ELM_GENLIST_ITEM_CLASS, ret,
7814 elm_wdg_item_tooltip_window_mode_set(disable));
7820 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *eo_it)
7823 return eo_do_ret(eo_it, ret, elm_wdg_item_tooltip_window_mode_get());
7826 EOLIAN static Eina_Bool
7827 _elm_genlist_item_elm_widget_item_tooltip_window_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7829 return it->tooltip.free_size;
7833 elm_genlist_item_cursor_set(Elm_Object_Item *item,
7836 eo_do(item, elm_wdg_item_cursor_set(cursor));
7840 _elm_genlist_item_elm_widget_item_cursor_set(Eo *eo_it, Elm_Gen_Item *it,
7843 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7844 eina_stringshare_replace(&it->mouse_cursor, cursor);
7845 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7846 elm_wdg_item_cursor_set(cursor));
7850 elm_genlist_item_cursor_get(const Elm_Object_Item *eo_it)
7853 return eo_do_ret(eo_it, cursor, elm_wdg_item_cursor_get());
7857 elm_genlist_item_cursor_unset(Elm_Object_Item *item)
7859 eo_do(item, elm_wdg_item_cursor_unset());
7863 _elm_genlist_item_elm_widget_item_cursor_unset(Eo *eo_it, Elm_Gen_Item *it)
7865 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7867 if (!it->mouse_cursor) return;
7869 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7870 elm_wdg_item_cursor_unset());
7872 ELM_SAFE_FREE(it->mouse_cursor, eina_stringshare_del);
7876 elm_genlist_item_cursor_style_set(Elm_Object_Item *eo_it,
7879 eo_do(eo_it, elm_wdg_item_cursor_style_set(style));
7883 elm_genlist_item_cursor_style_get(const Elm_Object_Item *eo_it)
7886 return eo_do_ret( eo_it, style, elm_wdg_item_cursor_style_get());
7890 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *eo_it,
7891 Eina_Bool engine_only)
7893 eo_do(eo_it, elm_wdg_item_cursor_engine_only_set(engine_only));
7897 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *eo_it)
7900 return eo_do_ret( eo_it, ret, elm_wdg_item_cursor_engine_only_get());
7904 _elm_genlist_item_index_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7908 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, -1);
7910 EINA_INLIST_FOREACH(GL_IT(it)->wsd->items, tmp)
7912 if (tmp == it) break;
7919 _elm_genlist_mode_set(Eo *obj, Elm_Genlist_Data *sd, Elm_List_Mode mode)
7921 if (sd->mode == mode) return;
7924 if (sd->mode == ELM_LIST_LIMIT)
7926 sd->scr_minw = EINA_TRUE;
7927 sd->scr_minh = EINA_FALSE;
7929 else if (sd->mode == ELM_LIST_EXPAND)
7931 sd->scr_minw = EINA_TRUE;
7932 sd->scr_minh = EINA_TRUE;
7936 sd->scr_minw = EINA_FALSE;
7937 sd->scr_minh = EINA_FALSE;
7940 elm_layout_sizing_eval(obj);
7943 EOLIAN static Elm_List_Mode
7944 _elm_genlist_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7950 elm_genlist_bounce_set(Evas_Object *obj,
7954 ELM_GENLIST_CHECK(obj);
7955 eo_do(obj, elm_interface_scrollable_bounce_allow_set(h_bounce, v_bounce));
7959 _elm_genlist_elm_interface_scrollable_bounce_allow_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool h_bounce, Eina_Bool v_bounce)
7961 sd->h_bounce = !!h_bounce;
7962 sd->v_bounce = !!v_bounce;
7964 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_bounce_allow_set
7965 (sd->h_bounce, sd->v_bounce));
7966 //sd->s_iface->bounce_allow_set(obj, sd->h_bounce, sd->v_bounce);
7970 elm_genlist_bounce_get(const Evas_Object *obj,
7971 Eina_Bool *h_bounce,
7972 Eina_Bool *v_bounce)
7974 ELM_GENLIST_CHECK(obj);
7975 eo_do( obj, elm_interface_scrollable_bounce_allow_get
7976 (h_bounce, v_bounce));
7980 _elm_genlist_elm_interface_scrollable_bounce_allow_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
7982 if (h_bounce) *h_bounce = sd->h_bounce;
7983 if (v_bounce) *v_bounce = sd->v_bounce;
7987 _elm_genlist_homogeneous_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool homogeneous)
7989 sd->homogeneous = !!homogeneous;
7992 EOLIAN static Eina_Bool
7993 _elm_genlist_homogeneous_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7995 return sd->homogeneous;
7999 _elm_genlist_block_count_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, int count)
8001 EINA_SAFETY_ON_TRUE_RETURN(count < 1);
8003 sd->max_items_per_block = count;
8004 sd->item_cache_max = sd->max_items_per_block * 2;
8005 _item_cache_all_free(sd);
8009 _elm_genlist_block_count_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8011 return sd->max_items_per_block;
8015 _filter_item_internal(Elm_Gen_Item *it)
8017 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8018 if (sd->filter_data && it->itc->func.filter_get)
8020 if (!it->itc->func.filter_get(
8021 (void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)),
8022 WIDGET(it), sd->filter_data))
8024 it->want_hidden = EINA_TRUE;
8025 if (sd->show_item == it) sd->show_item = NULL;
8026 GL_IT(it)->block->calc_done = EINA_FALSE;
8027 sd->calc_done = EINA_FALSE;
8030 sd->filtered_count++;
8032 it->filtered = EINA_TRUE;
8033 sd->processed_count++;
8037 _item_filtered_get(Elm_Gen_Item *it)
8040 if (!it) return EINA_FALSE;
8041 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8044 l = eina_list_data_find_list(sd->filter_queue, it);
8046 sd->filter_queue = eina_list_remove_list(sd->filter_queue, l);
8047 l = eina_list_data_find_list(sd->queue, it);
8050 sd->queue = eina_list_remove_list(sd->queue, l);
8051 GL_IT(it)->queued = EINA_FALSE;
8052 GL_IT(it)->resized = EINA_FALSE;
8053 _item_process(sd, it);
8056 _filter_item_internal(it);
8057 GL_IT(it)->block->calc_done = EINA_FALSE;
8058 sd->calc_done = EINA_FALSE;
8059 _changed(sd->pan_obj);
8061 if (!it->want_hidden) return EINA_TRUE;
8066 _filter_queue_process(Elm_Genlist_Data *sd)
8069 Elm_Gen_Item *it, *first;
8072 t0 = ecore_time_get();
8073 for (n = 0; ((sd->filter_queue) && (sd->processed_count < ITEM_QUEUE_MAX)); n++)
8075 first = it = eina_list_data_get(sd->filter_queue);
8076 //FIXME: This is added as a fail safe code for items not yet processed.
8077 while (it && it->item->queued)
8079 if ((ecore_time_get() - t0) > (ecore_animator_frametime_get()))
8081 sd->filter_queue = eina_list_remove_list
8082 (sd->filter_queue, sd->filter_queue);
8083 sd->filter_queue = eina_list_append(sd->filter_queue, it);
8084 it = eina_list_data_get(sd->filter_queue);
8086 //Do not iterate more than one loop
8087 if (it == first) return n;
8089 sd->filter_queue = eina_list_remove_list(sd->filter_queue, sd->filter_queue);
8092 _filter_item_internal(it);
8093 GL_IT(it)->block->calc_done = EINA_FALSE;
8095 sd->calc_done = EINA_FALSE;
8096 _changed(sd->pan_obj);
8097 if ((ecore_time_get() - t0) > (ecore_animator_frametime_get()))
8099 //At least 1 item is filtered by this time, so return n+1 for first loop
8108 _filter_process(void *data,
8111 Elm_Genlist_Data *sd = data;
8113 if (_filter_queue_process(sd) > 0) *wakeup = EINA_TRUE;
8114 if (!sd->filter_queue) return ECORE_CALLBACK_CANCEL;
8115 return ECORE_CALLBACK_RENEW;
8119 _item_filter_enterer(void *data)
8121 Eina_Bool wakeup = EINA_FALSE;
8122 ELM_GENLIST_DATA_GET(data, sd);
8123 Eina_Bool ok = _filter_process(sd, &wakeup);
8126 if (sd->dummy_job) ecore_job_del(sd->dummy_job);
8127 sd->dummy_job = ecore_job_add(_dummy_job, sd);
8129 if (ok == ECORE_CALLBACK_CANCEL)
8133 ecore_job_del(sd->dummy_job);
8134 sd->dummy_job = NULL;
8136 sd->queue_idle_enterer = NULL;
8137 evas_object_smart_callback_call((Evas_Object *)data, SIG_FILTER_DONE, NULL);
8144 _elm_genlist_filter_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, void *filter_data)
8150 if (sd->filter_queue)
8151 ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
8152 ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
8153 ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
8154 sd->filtered_count = 0;
8155 sd->processed_count = 0;
8156 sd->filter = EINA_TRUE;
8157 sd->filter_data = filter_data;
8159 EINA_INLIST_FOREACH(sd->blocks, itb)
8163 EINA_LIST_FOREACH(itb->items, l, it)
8165 it->filtered = EINA_FALSE;
8166 it->want_hidden = EINA_FALSE;
8168 _filter_item_internal(it);
8170 sd->filter_queue = eina_list_append(sd->filter_queue, it);
8172 itb->calc_done = EINA_FALSE;
8173 sd->calc_done = EINA_FALSE;
8177 EINA_LIST_FOREACH(itb->items, l, it)
8179 it->filtered = EINA_FALSE;
8180 it->want_hidden = EINA_FALSE;
8181 sd->filter_queue = eina_list_append(sd->filter_queue, it);
8185 _changed(sd->pan_obj);
8187 sd->queue_filter_enterer = ecore_idle_enterer_add(_item_filter_enterer,
8192 _filter_iterator_next(Elm_Genlist_Filter *iter, void **data)
8194 if (!iter->current) return EINA_FALSE;
8196 while (iter->current)
8198 item = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->current, Elm_Gen_Item);
8199 iter->current = iter->current->next;
8200 if (_item_filtered_get(item))
8203 *data = EO_OBJ(item);
8212 _filter_iterator_free(Elm_Genlist_Filter *iter)
8217 static Evas_Object *
8218 _filter_iterator_get_container(Elm_Genlist_Filter *iter)
8220 Elm_Gen_Item *it = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->head, Elm_Gen_Item);
8224 EOLIAN Eina_Iterator *
8225 _elm_genlist_filter_iterator_new(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8227 Elm_Genlist_Filter *iter;
8228 iter = calloc(1, sizeof (Elm_Genlist_Filter));
8229 if (!iter) return NULL;
8231 iter->head = sd->items;
8232 iter->current = sd->items;
8234 iter->iterator.version = EINA_ITERATOR_VERSION;
8235 iter->iterator.next = FUNC_ITERATOR_NEXT(_filter_iterator_next);
8236 iter->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
8237 _filter_iterator_get_container);
8238 iter->iterator.free = FUNC_ITERATOR_FREE(_filter_iterator_free);
8240 EINA_MAGIC_SET(&iter->iterator, EINA_MAGIC_ITERATOR);
8242 return &iter->iterator;
8246 _elm_genlist_longpress_timeout_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, double timeout)
8248 sd->longpress_timeout = timeout;
8251 EOLIAN static double
8252 _elm_genlist_longpress_timeout_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8254 return sd->longpress_timeout;
8258 elm_genlist_scroller_policy_set(Evas_Object *obj,
8259 Elm_Scroller_Policy policy_h,
8260 Elm_Scroller_Policy policy_v)
8262 ELM_GENLIST_CHECK(obj);
8263 eo_do(obj, elm_interface_scrollable_policy_set(policy_h, policy_v));
8267 _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)
8269 ELM_GENLIST_CHECK(obj);
8271 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
8272 (policy_v >= ELM_SCROLLER_POLICY_LAST))
8275 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_set(policy_h, policy_v));
8279 elm_genlist_scroller_policy_get(const Evas_Object *obj,
8280 Elm_Scroller_Policy *policy_h,
8281 Elm_Scroller_Policy *policy_v)
8283 ELM_GENLIST_CHECK(obj);
8284 eo_do( obj, elm_interface_scrollable_policy_get(policy_h, policy_v));
8288 _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)
8290 Elm_Scroller_Policy s_policy_h, s_policy_v;
8292 ELM_GENLIST_CHECK(obj);
8294 eo_do((Eo *)obj, elm_interface_scrollable_policy_get(&s_policy_h, &s_policy_v));
8295 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
8296 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
8300 _elm_genlist_realized_items_update(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED)
8303 Elm_Object_Item *eo_it;
8305 ELM_GENLIST_CHECK(obj);
8307 list = elm_genlist_realized_items_get(obj);
8308 EINA_LIST_FREE(list, eo_it)
8309 elm_genlist_item_update(eo_it);
8313 _elm_genlist_item_decorate_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8314 const char *decorate_it_type,
8315 Eina_Bool decorate_it_set)
8317 Elm_Genlist_Data *sd;
8320 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8321 sd = GL_IT(it)->wsd;
8323 if (!decorate_it_type) return;
8324 if (eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get())) return;
8325 if (sd->decorate_all_mode) return;
8327 if ((sd->mode_item == it) &&
8328 (!strcmp(decorate_it_type, sd->decorate_it_type)) &&
8331 if (!it->itc->decorate_item_style) return;
8332 it->decorate_it_set = decorate_it_set;
8335 if (((sd->decorate_it_type)
8336 && (strcmp(decorate_it_type, sd->decorate_it_type))) ||
8337 (decorate_it_set) || ((it == sd->mode_item) && (!decorate_it_set)))
8339 char buf[1024], buf2[1024];
8341 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8342 if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
8343 sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
8345 snprintf(buf, sizeof(buf), "elm,state,%s,passive", sd->decorate_it_type);
8346 edje_object_signal_emit(GL_IT(it)->deco_it_view, buf, "elm");
8347 edje_object_signal_emit(VIEW(it), buf, "elm");
8349 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished",
8350 sd->decorate_it_type);
8351 edje_object_signal_callback_add(GL_IT(it)->deco_it_view, buf2,
8353 _decorate_item_finished_signal_cb, it);
8354 sd->mode_item = NULL;
8357 eina_stringshare_replace(&sd->decorate_it_type, decorate_it_type);
8358 if (decorate_it_set)
8361 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8362 if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
8363 sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
8365 _decorate_item_realize(it);
8369 EOLIAN static const char *
8370 _elm_genlist_item_decorate_mode_get(Eo *eo_i EINA_UNUSED, Elm_Gen_Item *i)
8372 ELM_GENLIST_ITEM_CHECK_OR_RETURN(i, NULL);
8373 return GL_IT(i)->wsd->decorate_it_type;
8376 EOLIAN static Elm_Object_Item *
8377 _elm_genlist_decorated_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8379 return EO_OBJ(sd->mode_item);
8382 EOLIAN static Eina_Bool
8383 _elm_genlist_decorate_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8385 return sd->decorate_all_mode;
8389 _elm_genlist_decorate_mode_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool decorated)
8391 Elm_Object_Item *eo_it;
8394 decorated = !!decorated;
8395 if (sd->decorate_all_mode == decorated) return;
8396 // decorate_all_mode should be set first
8397 // because content_get func. will be called after this
8398 // and user can check whether deocrate_all_mode is enabeld.
8399 sd->decorate_all_mode = decorated;
8401 list = elm_genlist_realized_items_get(obj);
8402 EINA_LIST_FREE(list, eo_it)
8404 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8406 if (!sd->decorate_all_mode)
8408 _decorate_all_item_unrealize(it);
8410 else if (it->itc->decorate_all_item_style)
8412 _decorate_all_item_realize(it, EINA_TRUE);
8414 _access_widget_item_register(it);
8416 _changed(sd->pan_obj);
8420 _elm_genlist_reorder_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool reorder_mode)
8423 Elm_Object_Item *eo_it;
8425 if (sd->reorder_mode == !!reorder_mode) return;
8426 sd->reorder_mode = !!reorder_mode;
8428 list = elm_genlist_realized_items_get(obj);
8429 EINA_LIST_FREE(list, eo_it)
8431 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8432 if (sd->reorder_mode)
8434 edje_object_signal_emit
8435 (VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
8436 if (it->deco_all_view)
8437 edje_object_signal_emit
8438 (it->deco_all_view, SIGNAL_REORDER_MODE_SET, "elm");
8442 edje_object_signal_emit
8443 (VIEW(it), SIGNAL_REORDER_MODE_UNSET, "elm");
8444 if (it->deco_all_view)
8445 edje_object_signal_emit
8446 (it->deco_all_view, SIGNAL_REORDER_MODE_UNSET, "elm");
8451 EOLIAN static Eina_Bool
8452 _elm_genlist_reorder_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8454 return sd->reorder_mode;
8457 EOLIAN static Elm_Genlist_Item_Type
8458 _elm_genlist_item_type_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8460 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
8462 return GL_IT(it)->type;
8465 EAPI Elm_Genlist_Item_Class *
8466 elm_genlist_item_class_new(void)
8468 Elm_Genlist_Item_Class *itc = ELM_NEW(Elm_Genlist_Item_Class);
8469 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
8471 itc->version = CLASS_ALLOCATED;
8473 itc->delete_me = EINA_FALSE;
8474 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
8475 itc->homogeneous = EINA_FALSE;
8482 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
8484 if (itc && (itc->version == CLASS_ALLOCATED))
8486 itc->delete_me = EINA_TRUE;
8487 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
8497 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
8499 if (itc && (itc->version == CLASS_ALLOCATED))
8502 if (itc->refcount == 0) itc->refcount--;
8507 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
8509 if (itc && (itc->version == CLASS_ALLOCATED))
8511 if (itc->refcount > 0) itc->refcount--;
8512 if (itc->delete_me && (!itc->refcount))
8513 elm_genlist_item_class_free(itc);
8518 _elm_genlist_item_flip_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool flip)
8520 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8523 if (it->flipped == flip) return;
8528 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_content_objs,
8531 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
8532 if (GL_IT(it)->wsd->decorate_all_mode)
8533 edje_object_signal_emit
8534 (it->deco_all_view, SIGNAL_FLIP_ENABLED, "elm");
8539 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_DISABLED, "elm");
8540 if (GL_IT(it)->wsd->decorate_all_mode)
8541 edje_object_signal_emit
8542 (it->deco_all_view, SIGNAL_FLIP_DISABLED, "elm");
8544 EINA_LIST_FREE(GL_IT(it)->flip_content_objs, c)
8547 // FIXME: update texts should be done by app?
8548 _item_text_realize(it, VIEW(it), NULL);
8550 _access_widget_item_register(it);
8553 EOLIAN static Eina_Bool
8554 _elm_genlist_item_flip_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8556 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
8562 _elm_genlist_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Elm_Object_Select_Mode mode)
8564 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (sd->select_mode == mode))
8567 sd->select_mode = mode;
8569 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8570 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
8573 Elm_Object_Item *eo_it;
8574 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
8576 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8580 if (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
8583 EINA_INLIST_FOREACH(sd->items, it)
8585 if (!GL_IT(it)->block) continue;
8586 GL_IT(it)->calc_done = EINA_FALSE;
8587 GL_IT(it)->block->calc_done = EINA_FALSE;
8588 sd->calc_done = EINA_FALSE;
8589 _changed(sd->pan_obj);
8594 EOLIAN static Elm_Object_Select_Mode
8595 _elm_genlist_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8597 return sd->select_mode;
8601 _elm_genlist_highlight_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool highlight)
8603 sd->highlight = !!highlight;
8606 EOLIAN static Eina_Bool
8607 _elm_genlist_highlight_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8609 return sd->highlight;
8613 _elm_genlist_item_select_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8614 Elm_Object_Select_Mode mode)
8616 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8618 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (it->select_mode == mode))
8621 it->select_mode = mode;
8623 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8624 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
8627 if (GL_IT(it)->block && it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
8629 GL_IT(it)->calc_done = EINA_FALSE;
8630 GL_IT(it)->block->calc_done = EINA_FALSE;
8631 GL_IT(it)->wsd->calc_done = EINA_FALSE;
8632 _changed(GL_IT(it)->wsd->pan_obj);
8636 EOLIAN static Elm_Object_Select_Mode
8637 _elm_genlist_item_select_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8639 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
8641 return it->select_mode;
8644 EOLIAN Elm_Atspi_State_Set
8645 _elm_genlist_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_it, Elm_Gen_Item *it EINA_UNUSED)
8647 Elm_Atspi_State_Set ret;
8650 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
8652 eo_do(eo_it, sel = elm_obj_genlist_item_selected_get());
8654 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTABLE);
8657 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTED);
8659 if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_TREE)
8661 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDABLE);
8662 if (elm_genlist_item_expanded_get(eo_it))
8663 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8664 //TIZEN_ONLY(20160606): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8666 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8669 //TIZEN_ONLY(20160608): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8670 else if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_GROUP)
8672 if (elm_genlist_item_expanded_get(eo_it))
8673 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8675 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8683 _elm_genlist_item_elm_interface_atspi_accessible_name_get(Eo *eo_it,
8688 char *accessible_name;
8689 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_name_get());
8690 if (ret) return ret;
8692 buf = eina_strbuf_new();
8694 if (it->itc->func.text_get)
8700 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
8702 EINA_LIST_FREE(texts, key)
8704 char *str_markup = it->itc->func.text_get
8705 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
8706 char *str_utf8 = _elm_util_mkup_to_text(str_markup);
8710 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
8711 eina_strbuf_append(buf, str_utf8);
8717 accessible_name = eina_strbuf_string_steal(buf);
8718 eina_strbuf_free(buf);
8720 eina_stringshare_del(it->base->accessible_name);
8721 it->base->accessible_name = eina_stringshare_add(accessible_name);
8722 free(accessible_name);
8723 return it->base->accessible_name;
8727 _elm_genlist_item_elm_interface_atspi_accessible_children_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8729 Eina_List *ret = NULL;
8734 parts = elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "contents"));
8736 EINA_LIST_FREE(parts, key)
8739 part = edje_object_part_swallow_get(VIEW(it), key);
8740 if (part && eo_isa(part, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
8742 ret = eina_list_append(ret, part);
8743 eo_do(part, elm_interface_atspi_accessible_parent_set(eo_it));
8751 ///////////////////////////////////////////////////////////////////////////////
8752 //TIZEN ONLY:(20150623): Region show on item elements fixed
8753 //Grab and clear highlight on genlist items
8754 ///////////////////////////////////////////////////////////////////////////////
8755 EOLIAN static Eina_Bool
8756 _elm_genlist_item_elm_interface_atspi_component_highlight_grab(Eo *eo_it, Elm_Gen_Item *it)
8758 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8760 if (!TIZEN_PROFILE_WEARABLE)
8762 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
8763 eo_do_super(EO_OBJ(it), ELM_GENLIST_ITEM_CLASS, elm_interface_atspi_component_highlight_grab());
8768 // TIZEN_ONLY(20171011) : atspi : Do not center align when genlist item is highlighted in wearable profile
8769 //FIXME : First, last item is called centered because it may not have a proxy image.
8770 // This part will be revised in the next version.
8771 Eina_List *realized = elm_genlist_realized_items_get(WIDGET(it));
8772 if (VIEW(it) || realized)
8774 Elm_Object_Item *first_it = elm_genlist_first_item_get(WIDGET(it));
8775 Elm_Object_Item *last_it = elm_genlist_last_item_get(WIDGET(it));
8776 if (first_it == eo_it || last_it == eo_it)
8777 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
8779 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
8782 eina_list_free(realized);
8786 elm_object_accessibility_highlight_set(EO_OBJ(it), EINA_TRUE);
8787 ///TIZEN_ONLY(20170717) : expose highlight information on atspi
8788 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
8791 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
8792 // If you call eo_do_super, then you do NOT have to call smart callback.
8793 evas_object_smart_callback_call(WIDGET(it), "atspi,highlighted", EO_OBJ(it));
8800 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8801 sd->currently_highlighted_item = it;
8806 if (!TIZEN_PROFILE_WEARABLE)
8808 //TIZEN_ONLY(20170724): grab highlight using unrealized item
8809 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
8812 sd->atspi_item_to_highlight = it;//it will be highlighted when realized
8815 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8816 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
8822 EOLIAN static Eina_Bool
8823 _elm_genlist_item_elm_interface_atspi_component_highlight_clear(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8825 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8826 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8827 if(sd->currently_highlighted_item == it)
8828 sd->currently_highlighted_item = NULL;
8830 if (sd->atspi_item_to_highlight == it)
8831 sd->atspi_item_to_highlight = NULL;
8832 elm_object_accessibility_highlight_set(EO_OBJ(it), EINA_FALSE);
8833 ///TIZEN_ONLY(20170717) : expose highlight information on atspi
8834 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
8837 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8838 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
8840 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
8841 // If you call eo_do_super, then you do NOT have to call smart callback.
8842 evas_object_smart_callback_call(WIDGET(it), "atspi,unhighlighted", EO_OBJ(it));
8847 ///////////////////////////////////////////////////////////////////////////////
8850 _elm_genlist_tree_effect_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enabled EINA_UNUSED)
8852 // Need to implemented
8853 //sd->tree_effect_enabled = !!enabled;
8856 EOLIAN static Eina_Bool
8857 _elm_genlist_tree_effect_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
8863 _elm_genlist_focus_on_selection_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enabled EINA_UNUSED)
8865 // Need to Implemented
8866 sd->focus_on_selection_enabled = !!enabled;
8869 EOLIAN static Eina_Bool
8870 _elm_genlist_focus_on_selection_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
8872 // Need to Implemented
8873 return sd->focus_on_selection_enabled;
8876 EAPI Elm_Object_Item *
8877 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth)
8879 Elm_Gen_Item *it = NULL;
8883 ELM_GENLIST_CHECK(obj) NULL;
8884 ELM_GENLIST_DATA_GET(obj, sd);
8886 if (!sd->items) return NULL;
8888 a = eina_inlist_accessor_new(sd->items);
8889 if (!a) return NULL;
8890 if (eina_accessor_data_get(a, nth, &data))
8891 it = ELM_GEN_ITEM_FROM_INLIST(data);
8892 eina_accessor_free(a);
8897 elm_genlist_fx_mode_set(Evas_Object *obj, Eina_Bool mode)
8899 ELM_GENLIST_CHECK(obj);
8900 ELM_GENLIST_DATA_GET(obj, sd);
8907 elm_genlist_fx_mode_get(const Evas_Object *obj)
8909 ELM_GENLIST_CHECK(obj) EINA_FALSE;
8910 ELM_GENLIST_DATA_GET(obj, sd);
8916 elm_genlist_item_hide_set(const Elm_Object_Item *eo_item EINA_UNUSED, Eina_Bool hide EINA_UNUSED)
8918 WRN("This API is deprecated, please use filter_set instead of this");
8922 elm_genlist_item_hide_get(const Elm_Object_Item *eo_item EINA_UNUSED)
8924 WRN("This API is deprecated, please use filter_set instead of this");
8928 ///////////////////////////////////////////////////////////////////////////////
8929 //TIZEN ONLY:(20150126): its not decided whether deprecated or not to give away
8930 ///////////////////////////////////////////////////////////////////////////////
8932 elm_genlist_realization_mode_set(Evas_Object *obj, Eina_Bool realization_mode)
8934 ELM_GENLIST_CHECK(obj);
8935 ELM_GENLIST_DATA_GET(obj, sd);
8937 if (sd->realization_mode == realization_mode) return;
8938 sd->realization_mode = realization_mode;
8942 elm_genlist_realization_mode_get(Evas_Object *obj)
8944 ELM_GENLIST_CHECK(obj) EINA_FALSE;
8945 ELM_GENLIST_DATA_GET(obj, sd);
8947 return sd->realization_mode;
8949 ///////////////////////////////////////////////////////////////////////////////
8952 elm_genlist_item_reorder_start(Elm_Object_Item *eo_item)
8954 ELM_GENLIST_ITEM_DATA_GET(eo_item, it);
8955 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8956 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
8958 sd->reorder.it = it;
8960 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8961 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
8962 (EINA_FALSE, EINA_FALSE));
8963 //sd->s_iface->hold_set(sd->obj, EINA_TRUE);
8964 //sd->s_iface->bounce_allow_set(sd->obj, EINA_FALSE, EINA_FALSE);
8965 sd->reorder_force = EINA_TRUE;
8969 elm_genlist_item_reorder_stop(Elm_Object_Item *eo_item)
8971 ELM_GENLIST_ITEM_DATA_GET(eo_item, it);
8972 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8973 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
8975 sd->reorder_force = EINA_FALSE;
8979 _elm_genlist_class_constructor(Eo_Class *klass)
8981 if (_elm_config->access_mode)
8982 _elm_genlist_smart_focus_next_enable = EINA_TRUE;
8984 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
8988 _elm_genlist_elm_interface_atspi_accessible_children_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8990 Eina_List *ret = NULL;
8993 EINA_INLIST_FOREACH(sd->items, it)
8994 ret = eina_list_append(ret, EO_OBJ(it));
8999 EOLIAN Elm_Atspi_State_Set
9000 _elm_genlist_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED)
9002 Elm_Atspi_State_Set ret;
9004 eo_do_super(obj, ELM_GENLIST_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
9006 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MANAGES_DESCENDANTS);
9008 if (elm_genlist_multi_select_get(obj))
9009 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MULTISELECTABLE);
9015 _elm_genlist_elm_interface_atspi_selection_selected_children_count_get(Eo *objm EINA_UNUSED, Elm_Genlist_Data *pd)
9017 return eina_list_count(pd->selected);
9021 _elm_genlist_elm_interface_atspi_selection_selected_child_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_idx)
9023 return eina_list_nth(pd->selected, child_idx);
9027 _elm_genlist_elm_interface_atspi_selection_child_select(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9030 if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
9032 EINA_INLIST_FOREACH(pd->items, item)
9034 if (child_index-- == 0)
9036 elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
9045 _elm_genlist_elm_interface_atspi_selection_selected_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9050 EINA_LIST_FOREACH(pd->selected, l, item)
9052 if (child_index-- == 0)
9054 elm_genlist_item_selected_set(item, EINA_FALSE);
9062 _elm_genlist_elm_interface_atspi_selection_is_child_selected(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9066 EINA_INLIST_FOREACH(pd->items, item)
9068 if (child_index-- == 0)
9070 return elm_genlist_item_selected_get(EO_OBJ(item));
9077 _elm_genlist_elm_interface_atspi_selection_all_children_select(Eo *obj, Elm_Genlist_Data *pd)
9081 if (!elm_genlist_multi_select_get(obj))
9084 EINA_INLIST_FOREACH(pd->items, item)
9085 elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
9091 _elm_genlist_elm_interface_atspi_selection_clear(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd)
9093 return _all_items_deselect(pd);
9097 _elm_genlist_elm_interface_atspi_selection_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9100 if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
9102 EINA_INLIST_FOREACH(pd->items, item)
9104 if (child_index-- == 0)
9106 elm_genlist_item_selected_set(EO_OBJ(item), EINA_FALSE);
9114 // TIZEN only (20150914) : Accessibility: updated highlight change during genlist and list scroll
9115 static int _is_item_in_viewport(int viewport_y, int viewport_h, int obj_y, int obj_h)
9117 if (obj_y + obj_h <= viewport_y)
9119 else if (obj_y >= viewport_y + viewport_h)
9125 _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)
9127 if (!_elm_atspi_enabled())
9129 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
9133 int old_x, old_y, delta_y;
9134 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_get(&old_x,&old_y));
9135 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
9136 delta_y = old_y - y;
9138 //check if highlighted item is genlist descendant
9139 Evas_Object * highlighted_obj = _elm_object_accessibility_currently_highlighted_get();
9140 if (eo_isa(highlighted_obj, ELM_WIDGET_ITEM_CLASS))
9142 Elm_Widget_Item_Data *id = eo_data_scope_get(highlighted_obj, ELM_WIDGET_ITEM_CLASS);
9143 highlighted_obj = id->view;
9146 Evas_Object * parent = highlighted_obj;
9147 if (eo_isa(highlighted_obj, ELM_WIDGET_CLASS))
9149 while ((parent = elm_widget_parent_get(parent)))
9153 else if (eo_isa(highlighted_obj, EDJE_OBJECT_CLASS))
9155 while ((parent = evas_object_smart_parent_get(parent)))
9159 // TIZEN_ONLY(20160805): set _accessibility_currently_highlighted_obj to NULL in object delete callback
9162 WRN("Improper highlighted object: %p", highlighted_obj);
9169 int obj_x, obj_y, w, h, hx, hy, hw, hh;
9170 evas_object_geometry_get(obj, &obj_x, &obj_y, &w, &h);
9172 evas_object_geometry_get(highlighted_obj, &hx, &hy, &hw, &hh);
9174 Elm_Gen_Item * next_previous_item = NULL;
9175 int viewport_position_result = _is_item_in_viewport(obj_y, h, hy, hh);
9176 //only highlight if move direction is correct
9177 //sometimes highlighted item is brought in and it does not fit viewport
9178 //however content goes to the viewport position so soon it will
9179 //meet _is_item_in_viewport condition
9180 if ((viewport_position_result < 0 && delta_y > 0) ||
9181 (viewport_position_result > 0 && delta_y < 0))
9184 Eina_List *realized_items = elm_genlist_realized_items_get(obj);
9187 Eina_Bool traverse_direction = viewport_position_result > 0;
9188 l = traverse_direction ? realized_items: eina_list_last(realized_items);
9192 item = eina_list_data_get(l);
9193 ELM_GENLIST_ITEM_DATA_GET(item, it_data);
9194 next_previous_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it_data));
9195 evas_object_geometry_get(VIEW(next_previous_item), &hx, &hy, &hw, &hh);
9196 if (_is_item_in_viewport(obj_y, h, hy, hh) == 0)
9199 next_previous_item = NULL;
9201 l = traverse_direction ? eina_list_next(l): eina_list_prev(l);
9204 if (next_previous_item)
9206 elm_object_accessibility_highlight_set(EO_OBJ(next_previous_item), EINA_TRUE);
9207 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(next_previous_item), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
9211 // Tizen only (20150914)
9212 #include "elm_genlist.eo.c"
9213 #include "elm_genlist_item.eo.c"