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 const Eina_List *clipees = evas_object_clipees_get(clip);
1883 // FIXME: This clipee rect is prevent white rect generation by all clip unset.
1884 if ((eina_list_count(clipees) <= 2) && !sd->clipee)
1886 sd->clipee = evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1887 evas_object_color_set(sd->clipee, 0, 0, 0, 0);
1888 evas_object_clip_set(sd->clipee, clip);
1890 if (!it->item->proxy)
1892 it->item->proxy = evas_object_image_filled_add(evas_object_evas_get(wd->obj));
1893 evas_object_smart_member_add(it->item->proxy, sd->pan_obj);
1895 evas_object_clip_set(it->item->proxy, evas_object_clip_get(sd->pan_obj));
1896 evas_object_clip_unset(VIEW(it));
1897 evas_object_image_source_set(it->item->proxy, VIEW(it));
1898 evas_object_image_source_visible_set(it->item->proxy, EINA_FALSE);
1899 evas_object_image_source_events_set(it->item->proxy, EINA_TRUE);
1900 evas_object_image_source_clip_set(it->item->proxy, EINA_FALSE);
1901 evas_object_size_hint_min_set(it->item->proxy, GL_IT(it)->w, GL_IT(it)->h);
1902 evas_object_repeat_events_set(it->item->proxy, EINA_TRUE);
1906 _item_mouse_callbacks_add(it, VIEW(it));
1907 // Expand can be supported by only VIEW(it)
1908 _item_edje_callbacks_add(it);
1910 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()))
1911 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
1913 edje_object_signal_emit(VIEW(it), SIGNAL_ENABLED, "elm");
1916 if (!TIZEN_PROFILE_WEARABLE)
1918 if (sd->banded_bg_on)
1919 _banded_item_bg_color_change(it, EINA_TRUE);
1921 edje_object_signal_emit(VIEW(it), SIGNAL_HIGHLIGHTED, "elm");
1922 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
1924 if (GL_IT(it)->expanded)
1925 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
1926 if (sd->reorder_force || sd->reorder_mode)
1927 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
1928 if (GL_IT(it)->expanded_depth > 0)
1929 edje_object_signal_emit(VIEW(it), SIGNAL_BG_CHANGE, "elm");
1932 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_contents,
1934 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
1937 if (elm_widget_focus_highlight_enabled_get(WIDGET(it)) && (it == sd->focused_item))
1939 edje_object_signal_emit(VIEW(it), SIGNAL_FOCUSED, "elm");
1941 if (sd->decorate_all_mode && it->itc->decorate_all_item_style)
1943 _decorate_all_item_realize(it, EINA_FALSE);
1945 else if (it->decorate_it_set && it->itc->decorate_item_style &&
1946 (sd->mode_item == it))
1948 _decorate_item_realize(it);
1950 it->realized = EINA_TRUE;
1953 _elm_genlist_item_index_update(it);
1955 if (it->tooltip.content_cb)
1958 elm_wdg_item_tooltip_content_cb_set(
1959 it->tooltip.content_cb, it->tooltip.data, NULL),
1960 elm_wdg_item_tooltip_style_set(it->tooltip.style),
1961 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
1963 if (it->mouse_cursor)
1964 eo_do(EO_OBJ(it), elm_wdg_item_cursor_set(it->mouse_cursor));
1966 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
1967 if (_elm_atspi_enabled())
1969 elm_interface_atspi_accessible_added(EO_OBJ(it));
1970 elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
1973 if (!TIZEN_PROFILE_WEARABLE)
1974 _banded_item_bg_add(it, VIEW(it));
1976 // Register accessibility before realized callback
1977 // because user can customize accessibility.
1978 _access_widget_item_register(it);
1979 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, EO_OBJ(it));
1981 edje_object_message_signal_process(VIEW(it));
1982 if (it->deco_all_view)
1983 edje_object_message_signal_process(it->deco_all_view);
1984 if (GL_IT(it)->resized)
1986 sd->queue = eina_list_remove(sd->queue, it);
1987 GL_IT(it)->queued = EINA_FALSE;
1988 GL_IT(it)->resized = EINA_FALSE;
1989 GL_IT(it)->calc_done = EINA_FALSE;
1990 GL_IT(it)->block->calc_done = EINA_FALSE;
1991 sd->calc_done = EINA_FALSE;
1993 if (sd->atspi_item_to_highlight == it)
1995 sd->atspi_item_to_highlight = NULL;
1996 elm_object_accessibility_highlight_set(EO_OBJ(it), EINA_TRUE);
1997 //TIZEN_ONLY(20170724): grab highlight using unrealized item
1998 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it),
1999 ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
2000 evas_object_smart_callback_call(WIDGET(it),
2001 SIG_WIDGET_ATSPI_HIGHLIGHTED, EO_OBJ(it));
2007 _reorder_anim(void *data)
2011 Elm_Genlist_Data *sd = data;
2012 Evas_Coord oy, r_y, r_y_scrl, r_y_scrl_max, r_offset;
2013 evas_object_geometry_get(sd->pan_obj, NULL, &oy, NULL, NULL);
2015 r_y = sd->reorder.it->y + sd->reorder.it->item->block->y;
2016 r_y_scrl = sd->reorder.it->item->scrl_y;
2017 r_y_scrl_max = r_y_scrl + sd->reorder.it->item->h;
2020 // FIXME: 1. Reorder animation time should be equal regardless of item's height
2021 // 2. All item have same animation speed in reordering.
2022 // To support 1 and 2, offset value is scaled to reorder item's height.
2023 r_offset = (Evas_Coord) (GL_IT(sd->reorder.it)->h / REORDER_ANIM_OFFSET);
2024 if (r_offset < REORDER_ANIM_OFFSET) r_offset = REORDER_ANIM_OFFSET;
2027 EINA_LIST_FOREACH(sd->reorder.move_items, l, it)
2029 Evas_Coord it_y, it_y_scrl_center;
2030 it_y = it->y + GL_IT(it)->block->y;
2031 it_y_scrl_center = GL_IT(it)->scrl_y + (GL_IT(it)->h / 2);
2033 if ((sd->reorder.dir == -1) && (r_y_scrl <= it_y_scrl_center))
2034 GL_IT(it)->reorder_offset += r_offset;
2035 else if ((sd->reorder.dir == 1) && (r_y_scrl_max >= it_y_scrl_center))
2036 GL_IT(it)->reorder_offset -= r_offset;
2040 if (sd->reorder.it->item->h < GL_IT(it)->reorder_offset)
2041 GL_IT(it)->reorder_offset = sd->reorder.it->item->h;
2042 else if (0 > GL_IT(it)->reorder_offset)
2043 GL_IT(it)->reorder_offset = 0;
2045 else if (r_y < it_y)
2047 if (-(sd->reorder.it->item->h) > GL_IT(it)->reorder_offset)
2048 GL_IT(it)->reorder_offset = -(sd->reorder.it->item->h);
2049 else if (0 < GL_IT(it)->reorder_offset)
2050 GL_IT(it)->reorder_offset = 0;
2053 if (!sd->reorder.move_items)
2055 sd->reorder.anim = NULL;
2056 return ECORE_CALLBACK_CANCEL;
2059 _changed(sd->pan_obj);
2060 return ECORE_CALLBACK_RENEW;
2064 _reorder_space_get(Elm_Gen_Item *it)
2066 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2067 Evas_Coord oy, r_y, it_y, r_y_scrl, r_y_scrl_max, it_y_center;
2068 evas_object_geometry_get(sd->pan_obj, NULL, &oy, NULL, NULL);
2070 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) return 0;
2071 if (sd->reorder.it->parent != it->parent) return 0;
2073 r_y = sd->reorder.it->y + sd->reorder.it->item->block->y;
2074 it_y = it->y + GL_IT(it)->block->y;
2076 r_y_scrl = sd->reorder.it->item->scrl_y;
2077 r_y_scrl_max = r_y_scrl + sd->reorder.it->item->h;
2078 it_y_center = it_y + (GL_IT(it)->h / 2) - sd->pan_y + oy;
2080 if ((r_y > it_y) && (r_y_scrl <= it_y_center))
2082 if (!eina_list_data_find(sd->reorder.move_items, it))
2083 sd->reorder.move_items = eina_list_append(sd->reorder.move_items, it);
2084 if (!sd->reorder.anim)
2085 sd->reorder.anim = ecore_animator_add(_reorder_anim,
2088 else if ((r_y < it_y) && (r_y_scrl_max >= it_y_center))
2090 if (!eina_list_data_find(sd->reorder.move_items, it))
2091 sd->reorder.move_items = eina_list_append(sd->reorder.move_items, it);
2092 if (!sd->reorder.anim)
2093 sd->reorder.anim = ecore_animator_add(_reorder_anim,
2096 return GL_IT(it)->reorder_offset;
2100 _reorder_calc(Elm_Gen_Item *it, Elm_Genlist_Data *sd)
2102 Elm_Gen_Item *git = NULL;
2103 Elm_Gen_Item *ngit = NULL;
2105 Evas_Coord ox, oy, ow, oh;
2106 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
2108 // Do not cross the parent group items and
2109 // Do not exceeds viewport
2111 ngit = eina_list_data_get(eina_list_next
2112 (eina_list_data_find_list
2113 (sd->group_items, git)));
2114 if (git && git->realized && (GL_IT(it)->scrl_y <= (GL_IT(git)->scrl_y + GL_IT(git)->h)))
2116 GL_IT(it)->scrl_y = GL_IT(git)->scrl_y + GL_IT(git)->h;
2118 else if (ngit && ngit->realized && (GL_IT(it)->scrl_y >= (GL_IT(ngit)->scrl_y - GL_IT(it)->h)))
2120 GL_IT(it)->scrl_y = GL_IT(ngit)->scrl_y - GL_IT(ngit)->h;
2123 if (GL_IT(it)->scrl_y < oy)
2125 GL_IT(it)->scrl_y = oy;
2126 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(sd->pan_x, sd->pan_y
2127 - REORDER_FASTER, ow, oh));
2129 else if (GL_IT(it)->scrl_y + GL_IT(it)->h > oy + oh)
2131 GL_IT(it)->scrl_y = oy + oh - GL_IT(it)->h;
2132 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(sd->pan_x, sd->pan_y
2133 + REORDER_FASTER, ow, oh));
2136 if (TIZEN_PROFILE_WEARABLE)
2138 _item_all_position(it, GL_IT(it)->scrl_x - REORDERED_ITEM_OFFSET,
2139 GL_IT(it)->scrl_y - REORDERED_ITEM_OFFSET);
2143 _item_all_position(it, GL_IT(it)->scrl_x, GL_IT(it)->scrl_y - REORDERED_ITEM_OFFSET);
2146 if (it->deco_all_view)
2147 evas_object_raise(it->deco_all_view);
2148 else if (GL_IT(it)->deco_it_view)
2149 evas_object_raise(GL_IT(it)->deco_it_view);
2151 evas_object_raise(VIEW(it));
2154 #ifdef GENLIST_FX_SUPPORT
2156 _add_fx_anim(void *data)
2158 Elm_Genlist_Data *sd = data;
2163 _changed(sd->pan_obj);
2164 if (sd->add_fx.cnt <= 0)
2166 while (sd->add_fx.items)
2168 it = eina_list_data_get(sd->add_fx.items);
2169 sd->add_fx.items = eina_list_remove(sd->add_fx.items, it);
2170 if (it->deco_all_view)
2171 evas_object_color_set(it->deco_all_view, 255, 255, 255, 255);
2172 else if (it->item->deco_it_view)
2173 evas_object_color_set(it->item->deco_it_view, 255, 255, 255, 255);
2175 evas_object_color_set(VIEW(it), 255, 255, 255, 255);
2177 sd->add_fx.cnt = ANIM_CNT_MAX;
2178 sd->add_fx.anim = NULL;
2179 return ECORE_CALLBACK_CANCEL;
2181 return ECORE_CALLBACK_RENEW;
2185 _add_fx_space_get(Elm_Gen_Item *it)
2188 Elm_Genlist_Data *sd = it->item->wsd;
2189 Evas_Coord size = 0;
2191 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2192 else if (it->item->deco_it_view) evas_object_raise(it->item->deco_it_view);
2193 else if (VIEW(it)) evas_object_raise(VIEW(it));
2195 itt = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
2196 while (itt && itt->realized)
2198 if (eina_list_data_find_list(sd->add_fx.items, itt))
2200 size += itt->item->minh;
2202 itt = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(itt)->prev);
2204 size = size * ((double)sd->add_fx.cnt/ANIM_CNT_MAX);
2209 _del_fx_anim(void *data)
2211 Elm_Genlist_Data *sd = data;
2216 _changed(sd->pan_obj);
2217 if (sd->del_fx.cnt <= 0)
2219 while (sd->del_fx.pending_items)
2221 it = eina_list_data_get(sd->del_fx.pending_items);
2222 sd->del_fx.pending_items = eina_list_remove(sd->del_fx.pending_items, it);
2225 while (sd->del_fx.items)
2227 it = eina_list_data_get(sd->del_fx.items);
2228 sd->del_fx.items = eina_list_remove(sd->del_fx.items, it);
2229 if (it->deco_all_view)
2230 evas_object_color_set(it->deco_all_view, 255, 255, 255, 255);
2231 else if (it->item->deco_it_view)
2232 evas_object_color_set(it->item->deco_it_view, 255, 255, 255, 255);
2234 evas_object_color_set(VIEW(it), 255, 255, 255, 255);
2237 sd->del_fx.cnt = ANIM_CNT_MAX;
2238 sd->del_fx.anim = NULL;
2239 return ECORE_CALLBACK_CANCEL;
2241 return ECORE_CALLBACK_RENEW;
2245 _del_fx_space_get(Elm_Gen_Item *it)
2248 Elm_Genlist_Data *sd = it->item->wsd;
2249 Evas_Coord size = 0;
2251 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2252 else if (it->item->deco_it_view) evas_object_raise(it->item->deco_it_view);
2253 else if (VIEW(it)) evas_object_raise(VIEW(it));
2254 itt = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
2255 while (itt && itt->realized)
2257 if (eina_list_data_find_list(sd->del_fx.items, itt))
2259 size += itt->item->minh;
2261 itt = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(itt)->prev);
2263 size = size * (1 - ((double)sd->del_fx.cnt/ANIM_CNT_MAX));
2269 _item_block_realize(Item_Block *itb, Eina_Bool force)
2271 Elm_Genlist_Data *sd = itb->sd;
2273 Elm_Gen_Item *aligned_item = NULL;
2274 Elm_Gen_Item *top_drawn_item = NULL;
2275 const Eina_List *l, *ll;
2276 Evas_Object *content;
2277 Eina_Bool unrealize = EINA_TRUE;
2278 Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0, cvx = 0, cvy = 0, cvw = 0, cvh = 0;
2279 ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wsd);
2281 // Do not check itb->realized
2282 // because it->item->block can be changed
2284 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
2285 evas_output_viewport_get(evas_object_evas_get(sd->obj),
2286 &cvx, &cvy, &cvw, &cvh);
2288 if (_elm_config->access_mode || _elm_atspi_enabled())
2290 // If access is on, realize more items (3 times)
2294 #ifdef GENLIST_FX_SUPPORT
2295 else if (sd->del_fx.anim)
2298 EINA_LIST_FOREACH(sd->del_fx.items, l, it)
2300 size += it->item->minh;
2304 else if (sd->add_fx.anim)
2307 EINA_LIST_FOREACH(sd->add_fx.items, l, it)
2309 size += it->item->minh;
2315 if (sd->reorder.it) _reorder_calc(sd->reorder.it, sd);
2316 EINA_LIST_FOREACH(itb->items, l, it)
2318 if (sd->reorder.it == it) continue;
2319 if (!it->filtered) _item_filtered_get(it);
2320 if (it->want_hidden)
2322 if (it->realized) evas_object_hide(VIEW(it));
2325 GL_IT(it)->scrl_x = it->x + itb->x - sd->pan_x + ox;
2326 GL_IT(it)->scrl_y = it->y + itb->y - sd->pan_y + oy;
2327 GL_IT(it)->w = sd->minw;
2328 GL_IT(it)->h = GL_IT(it)->minh;
2330 if (!TIZEN_PROFILE_WEARABLE)
2333 if (!top_drawn_item)
2335 if (GL_IT(it)->scrl_y <= oy && ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
2336 GL_IT(it)->w, GL_IT(it)->h, ox, oy, ow, oh))
2338 top_drawn_item = it;
2339 sd->top_drawn_item = top_drawn_item;
2344 if (wsd->scroll_item_align_enable)
2346 if (!sd->aligned_item)
2348 if (ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
2349 GL_IT(it)->w, GL_IT(it)->h,
2350 ox + ow / 2, oy + oh / 2, 1, 1))
2351 aligned_item = sd->aligned_item = it;
2354 if (force || sd->realization_mode ||
2356 (ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
2357 GL_IT(it)->w, GL_IT(it)->h,
2358 cvx, cvy, cvw, cvh)))
2360 if (!it->realized) _item_realize(it, EINA_FALSE);
2362 GL_IT(it)->scrl_y += _reorder_space_get(it);
2363 #ifdef GENLIST_FX_SUPPORT
2364 if (sd->del_fx.anim && !eina_list_data_find(sd->del_fx.items, it))
2365 it->item->scrl_y -= _del_fx_space_get(it);
2366 if (sd->add_fx.anim && !eina_list_data_find(sd->add_fx.items, it))
2367 it->item->scrl_y -= _add_fx_space_get(it);
2370 _item_all_position(it, GL_IT(it)->scrl_x, GL_IT(it)->scrl_y);
2372 else if (it->realized)
2374 /* FIXME: when content is on focused and unrealize item,
2375 focus is set to other object and scroll will be bring in */
2376 if (_elm_config->access_mode)
2378 EINA_LIST_FOREACH(it->content_objs, ll, content)
2380 if (elm_object_focus_get(content))
2382 unrealize = EINA_FALSE;
2388 _item_unrealize(it, EINA_FALSE);
2389 unrealize = EINA_TRUE;
2393 itb->realized = EINA_TRUE;
2395 if (!TIZEN_PROFILE_WEARABLE)
2397 if (sd->banded_bg_on)
2398 _banded_item_bg_index_color_set(sd->top_drawn_item, ox, oy, ow, oh);
2403 edje_object_signal_emit(VIEW(aligned_item), SIGNAL_ITEM_HIGHLIGHTED, "elm");
2404 _focus_bg_show(aligned_item);
2406 edje_object_message_signal_process(VIEW(sd->aligned_item));
2410 // FIXME: Remove below macro after opensource is patched
2411 #define EINA_INLIST_REVERSE_FOREACH_FROM(list, it) \
2412 for (it = NULL, it = (list ? _EINA_INLIST_CONTAINER(it, list) : NULL); \
2413 it; it = (EINA_INLIST_GET(it)->prev ? _EINA_INLIST_CONTAINER(it, EINA_INLIST_GET(it)->prev) : NULL))
2416 _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
2418 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2421 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2422 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2424 //FIXME: This is for optimizing genlist calculation after
2425 // genlist sizing eval properly.
2426 if (ow <= 1) return;
2428 _calc((void *)psd->wsd);
2430 if (_elm_config->access_mode || _elm_atspi_enabled())
2432 // If access is on, realize more items (3 times)
2436 #ifdef GENLIST_FX_SUPPORT
2437 else if (psd->wsd->del_fx.anim)
2442 EINA_LIST_FOREACH(psd->wsd->del_fx.items, l, it)
2444 size += it->item->minh;
2448 else if (psd->wsd->add_fx.anim)
2453 EINA_LIST_FOREACH(psd->wsd->add_fx.items, l, it)
2455 size += it->item->minh;
2461 // Belows are tweaks for performance
2462 // Block is not needed anymore because of below algorithm..
2463 // later, we should remove dirty block algorithm
2464 Eina_Inlist *start = NULL;
2465 Eina_List *realized_new = NULL;
2466 Eina_Bool flag = EINA_FALSE;
2467 if ((psd->wsd->blocks_realized) && (psd->wsd->dir == -1) &&
2468 (!_elm_config->access_mode) && (!_elm_atspi_enabled()))
2470 start = EINA_INLIST_GET((Item_Block *)eina_list_data_get
2471 (eina_list_last(psd->wsd->blocks_realized)));
2472 EINA_INLIST_REVERSE_FOREACH_FROM(start, itb)
2474 Evas_Coord itb_x, itb_y, itb_w, itb_h;
2475 itb_x = itb->x - psd->wsd->pan_x + ox;
2476 itb_y = itb->y - psd->wsd->pan_y + oy;
2477 itb_w = psd->wsd->minw;
2479 if (psd->wsd->realization_mode ||
2480 ELM_RECTS_INTERSECT(itb_x, itb_y, itb_w, itb_h,
2481 cvx, cvy, cvw, cvh))
2484 realized_new = eina_list_prepend(realized_new, itb);
2485 _item_block_realize(itb, EINA_FALSE);
2489 _item_block_unrealize(itb);
2494 else if ((psd->wsd->blocks_realized) && (psd->wsd->dir == 1) &&
2495 (!_elm_config->access_mode) && (!_elm_atspi_enabled()))
2497 start = EINA_INLIST_GET((Item_Block *)eina_list_data_get
2498 (psd->wsd->blocks_realized));
2499 EINA_INLIST_FOREACH(start, itb)
2501 Evas_Coord itb_x, itb_y, itb_w, itb_h;
2502 itb_x = itb->x - psd->wsd->pan_x + ox;
2503 itb_y = itb->y - psd->wsd->pan_y + oy;
2504 itb_w = psd->wsd->minw;
2506 if (psd->wsd->realization_mode ||
2507 ELM_RECTS_INTERSECT(itb_x, itb_y, itb_w, itb_h,
2508 cvx, cvy, cvw, cvh))
2511 realized_new = eina_list_append(realized_new, itb);
2512 _item_block_realize(itb, EINA_FALSE);
2516 _item_block_unrealize(itb);
2523 if (!psd->wsd->show_item)
2525 EINA_INLIST_FOREACH(psd->wsd->blocks, itb)
2527 Evas_Coord itb_x, itb_y, itb_w, itb_h;
2528 itb_x = itb->x - psd->wsd->pan_x + ox;
2529 itb_y = itb->y - psd->wsd->pan_y + oy;
2530 itb_w = psd->wsd->minw;
2532 if (psd->wsd->realization_mode ||
2533 ELM_RECTS_INTERSECT(itb_x, itb_y, itb_w, itb_h,
2534 cvx, cvy, cvw, cvh))
2536 realized_new = eina_list_append(realized_new, itb);
2537 _item_block_realize(itb, EINA_FALSE);
2541 _item_block_unrealize(itb);
2546 eina_list_free(psd->wsd->blocks_realized);
2547 psd->wsd->blocks_realized = realized_new;
2549 // TIZEN_ONLY(20150701) : banded color background feature. enabled only un-scrollable
2550 if (!TIZEN_PROFILE_WEARABLE)
2552 if (psd->wsd->banded_bg_rect && !psd->wsd->reorder.it)
2554 Evas_Coord bg_x, bg_y, bg_w, bg_h, svy, svh;
2555 Elm_Gen_Item *tmp = NULL, *prev = NULL;
2557 tmp = ELM_GEN_ITEM_FROM_INLIST(psd->wsd->items->last);
2561 if (tmp->want_hidden || !tmp->realized )
2562 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
2567 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
2571 if(prev->want_hidden)
2572 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2581 eo_do(psd->wsd->obj, elm_interface_scrollable_content_viewport_geometry_get
2582 (NULL, &svy, NULL, &svh));
2584 bg_x = GL_IT(tmp)->scrl_x;
2585 bg_y = GL_IT(tmp)->scrl_y + GL_IT(tmp)->h;
2586 bg_w = GL_IT(tmp)->w;
2587 bg_h = svy + svh - bg_y;
2589 evas_object_stack_below(psd->wsd->banded_bg_rect, VIEW(tmp));
2590 evas_object_resize(psd->wsd->banded_bg_rect, bg_w, bg_h);
2591 evas_object_move(psd->wsd->banded_bg_rect, bg_x, bg_y);
2593 //GET COLOR OF LAST ITEM AND SET NEXT COLOR TO BANDED BG RECT
2594 if (psd->wsd->banded_bg_on)
2597 index = GL_IT(tmp)->banded_color_index + 1;
2600 int sign = GL_IT(tmp)->banded_color_index - GL_IT(prev)->banded_color_index;
2604 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2608 if(prev->want_hidden)
2609 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2617 sign = GL_IT(tmp)->banded_color_index - GL_IT(prev)->banded_color_index;
2620 index = GL_IT(tmp)->banded_color_index + sign;
2622 if (index < 0) index += 2;
2623 else if (index >= BANDED_MAX_ITEMS)
2624 index = BANDED_MAX_ITEMS - 2;
2627 int alpha = 255 * (1 - 0.04 * index);
2628 int color = (250 * alpha) / 255;
2630 evas_object_color_set(psd->wsd->banded_bg_rect, color, color, color, alpha);
2634 evas_object_color_set
2635 (psd->wsd->banded_bg_rect, 0, 0, 0, 0);
2638 evas_object_show(psd->wsd->banded_bg_rect);
2644 if (psd->wsd->comp_y)
2646 psd->wsd->unhighlight_skip = EINA_TRUE;
2647 eo_do((psd->wsd)->obj, elm_interface_scrollable_content_region_show(psd->wsd->pan_x,
2648 psd->wsd->pan_y + psd->wsd->comp_y, ow, oh));
2649 psd->wsd->comp_y = 0;
2650 psd->wsd->unhighlight_skip = EINA_FALSE;
2652 else if (psd->wsd->expanded_item &&
2653 GL_IT(psd->wsd->expanded_item)->calc_done)
2656 Evas_Coord size = GL_IT(psd->wsd->expanded_item)->minh;
2657 Elm_Object_Item *eo_tmp;
2658 EINA_LIST_FOREACH(psd->wsd->expanded_item->item->items, l, eo_tmp)
2660 ELM_GENLIST_ITEM_DATA_GET(eo_tmp, tmp);
2661 size += GL_IT(tmp)->minh;
2664 elm_genlist_item_bring_in
2665 (EO_OBJ(psd->wsd->expanded_item),
2666 ELM_GENLIST_ITEM_SCROLLTO_TOP);
2669 eo_tmp = eina_list_data_get
2670 (eina_list_last(psd->wsd->expanded_item->item->items));
2673 elm_genlist_item_bring_in(eo_tmp,
2674 ELM_GENLIST_ITEM_SCROLLTO_IN);
2676 psd->wsd->expanded_item = NULL;
2678 if (psd->wsd->show_item &&
2679 !psd->wsd->show_item->item->queued &&
2680 psd->wsd->show_item->item->calc_done &&
2681 psd->wsd->show_item->item->block->calc_done &&
2682 psd->wsd->calc_done)
2684 Evas_Coord x, y, w, h;
2685 Elm_Gen_Item *it = psd->wsd->show_item;
2686 psd->wsd->show_item = NULL;
2687 x = it->x + GL_IT(it)->block->x + psd->wsd->pan_x;
2688 y = it->y + GL_IT(it)->block->y;
2692 switch (psd->wsd->scroll_to_type)
2694 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2698 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2699 y = y - (oh / 2) + (GL_IT(it)->h / 2);
2702 case ELM_GENLIST_ITEM_SCROLLTO_BOTTOM:
2703 y = y - oh + GL_IT(it)->h;
2709 if (psd->wsd->bring_in)
2710 eo_do(WIDGET(it), elm_interface_scrollable_region_bring_in(x, y, w, h));
2713 if (psd->wsd->aligned_item && (psd->wsd->aligned_item != psd->wsd->adjusted_item))
2714 edje_object_signal_emit(VIEW(psd->wsd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
2715 psd->wsd->aligned_item = NULL;
2716 psd->wsd->unhighlight_skip = EINA_TRUE;
2717 eo_do(WIDGET(it), elm_interface_scrollable_content_region_show(x, y, ow, oh));
2718 psd->wsd->unhighlight_skip = EINA_FALSE;
2721 _changed(psd->wsd->pan_obj);
2723 #ifdef GENLIST_FX_SUPPORT
2724 if (psd->wsd->add_fx.anim)
2729 int alpha = 255 * (1 - ((double)psd->wsd->add_fx.cnt/ANIM_CNT_MAX));
2730 EINA_LIST_FOREACH(psd->wsd->add_fx.items, l, it)
2732 if (!it->realized) continue;
2733 if (it->deco_all_view)
2734 evas_object_color_set(it->deco_all_view, alpha, alpha, alpha, alpha);
2735 else if (it->item->deco_it_view)
2736 evas_object_color_set(it->item->deco_it_view, alpha, alpha, alpha, alpha);
2738 evas_object_color_set(VIEW(it), alpha, alpha, alpha, alpha);
2741 if (psd->wsd->del_fx.anim)
2746 int alpha = 255 * ((double)psd->wsd->del_fx.cnt/ANIM_CNT_MAX);
2747 EINA_LIST_FOREACH(psd->wsd->del_fx.items, l, it)
2749 if (it->deco_all_view)
2750 evas_object_color_set(it->deco_all_view, alpha, alpha, alpha, alpha);
2751 else if (it->item->deco_it_view)
2752 evas_object_color_set(it->item->deco_it_view, alpha, alpha, alpha, alpha);
2754 evas_object_color_set(VIEW(it), alpha, alpha, alpha, alpha);
2758 eo_do(psd->wobj, eo_event_callback_call
2759 (ELM_INTERFACE_SCROLLABLE_EVENT_CHANGED, NULL));
2763 _elm_genlist_pan_eo_base_destructor(Eo *obj, Elm_Genlist_Pan_Data *psd)
2765 eo_data_unref(psd->wobj, psd->wsd);
2766 eo_do_super(obj, MY_PAN_CLASS, eo_destructor());
2770 _elm_genlist_pan_class_constructor(Eo_Class *klass)
2772 evas_smart_legacy_type_register(MY_PAN_CLASS_NAME_LEGACY, klass);
2775 #include "elm_genlist_pan.eo.c"
2777 //#ifdef ELM_FOCUSED_UI
2779 _item_multi_select_up(Elm_Genlist_Data *sd)
2781 Elm_Object_Item *prev;
2783 if (!sd->selected) return EINA_FALSE;
2784 if (!sd->multi) return EINA_FALSE;
2786 prev = elm_genlist_item_prev_get(sd->last_selected_item);
2787 if (!prev) return EINA_TRUE;
2789 if (elm_genlist_item_selected_get(prev))
2791 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2792 sd->last_selected_item = prev;
2793 elm_genlist_item_show
2794 (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2798 elm_genlist_item_selected_set(prev, EINA_TRUE);
2799 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
2805 _item_multi_select_down(Elm_Genlist_Data *sd)
2807 Elm_Object_Item *next;
2809 if (!sd->selected) return EINA_FALSE;
2810 if (!sd->multi) return EINA_FALSE;
2812 next = elm_genlist_item_next_get(sd->last_selected_item);
2813 if (!next) return EINA_TRUE;
2815 if (elm_genlist_item_selected_get(next))
2817 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2818 sd->last_selected_item = next;
2819 elm_genlist_item_show
2820 (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2824 elm_genlist_item_selected_set(next, EINA_TRUE);
2825 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
2832 _all_items_deselect(Elm_Genlist_Data *sd)
2834 if (!sd->selected) return EINA_FALSE;
2836 while (sd->selected)
2837 elm_genlist_item_selected_set(sd->selected->data, EINA_FALSE);
2843 _item_single_select_up(Elm_Genlist_Data *sd)
2845 Elm_Object_Item *eo_prev;
2850 prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2852 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2856 eo_prev = elm_genlist_item_prev_get(sd->last_selected_item);
2857 prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
2860 if (!prev) return EINA_FALSE;
2862 _all_items_deselect(sd);
2864 elm_genlist_item_selected_set(EO_OBJ(prev), EINA_TRUE);
2865 elm_genlist_item_show(EO_OBJ(prev), ELM_GENLIST_ITEM_SCROLLTO_IN);
2870 _item_single_select_down(Elm_Genlist_Data *sd)
2872 Elm_Object_Item *eo_next;
2877 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2879 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2883 eo_next = elm_genlist_item_next_get(sd->last_selected_item);
2884 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2887 if (!next) return EINA_FALSE;
2889 _all_items_deselect(sd);
2891 elm_genlist_item_selected_set(EO_OBJ(next), EINA_TRUE);
2892 elm_genlist_item_show
2893 (EO_OBJ(next), ELM_GENLIST_ITEM_SCROLLTO_IN);
2899 static void _item_unfocused(Elm_Gen_Item *it)
2902 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2903 if (!sd->focused_item || it != sd->focused_item) return;
2905 edje_object_signal_emit
2906 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
2907 if (sd->focused_item->deco_all_view)
2908 edje_object_signal_emit
2909 (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
2910 sd->focused_item = NULL;
2911 evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_UNFOCUSED, EO_OBJ(it));
2914 static void _item_focused(Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
2916 Evas_Coord x, y, w, h, sx, sy, sw, sh;
2918 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2920 evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
2921 evas_object_geometry_get(sd->obj, &sx, &sy, &sw, &sh);
2922 if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
2924 elm_genlist_item_bring_in(EO_OBJ(it), type);
2927 if (elm_widget_focus_highlight_enabled_get(sd->obj))
2929 if (it->deco_all_view)
2930 edje_object_signal_emit
2931 (it->deco_all_view, SIGNAL_FOCUSED, "elm");
2933 edje_object_signal_emit
2934 (VIEW(it), SIGNAL_FOCUSED, "elm");
2937 sd->focused_item = it;
2938 evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_FOCUSED, EO_OBJ(it));
2939 if (_elm_atspi_enabled())
2940 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), EO_OBJ(it));
2944 _banded_item_highlight_anim(void *data, double pos)
2946 Elm_Gen_Item *it = data;
2948 double v[4] = {0.25, 0.46, 0.45, 1.00};
2950 if (GL_IT(it)->banded_bg)
2953 frame = ecore_animator_pos_map_n(pos, ECORE_POS_MAP_CUBIC_BEZIER, 4, v);
2955 it->item->banded_anim = NULL;
2957 if (it->highlighted)
2958 frame = HIGHLIGHT_ALPHA_MAX + (1.0 - HIGHLIGHT_ALPHA_MAX) * (1.0 - frame);
2960 frame = HIGHLIGHT_ALPHA_MAX + (1.0 - HIGHLIGHT_ALPHA_MAX) * frame;
2962 int alpha = 255 * frame * (1 - 0.04 * GL_IT(it)->banded_color_index);
2965 color = (color * alpha) / 255;
2966 evas_object_color_set(GL_IT(it)->banded_bg, color, color, color, alpha);
2973 _item_highlight(Elm_Gen_Item *it)
2975 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2976 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wsd);
2979 if (!sd->highlight) return;
2980 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get())) return;
2981 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2982 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ) ||
2983 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2984 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
2986 if (it->highlighted) return;
2987 if (wsd->scroll_item_align_enable)
2989 if (sd->aligned_item == it)
2990 edje_object_signal_emit(wsd->resize_obj, SIGNAL_HIGHLIGHTED, "elm");
2995 it->highlighted = EINA_TRUE;
2996 sd->highlighted_item = it;
2998 if (!it->realized) goto end;
3000 if (!TIZEN_PROFILE_WEARABLE)
3002 if (sd->banded_bg_on)
3004 if (it->item->banded_anim) ecore_animator_del(it->item->banded_anim);
3005 it->item->banded_anim = ecore_animator_timeline_add(ELM_ITEM_HIGHLIGHT_TIMER, _banded_item_highlight_anim, it);
3008 if (it->deco_all_view)
3010 edje_object_signal_emit(it->deco_all_view, SIGNAL_HIGHLIGHTED, "elm");
3011 edje_object_message_signal_process(it->deco_all_view);
3013 edje_object_signal_emit(VIEW(it), SIGNAL_HIGHLIGHTED, "elm");
3014 edje_object_message_signal_process(VIEW(it));
3016 //***************** TIZEN Only
3017 // If check or radio is used on genlist item, highlight it also.
3019 Evas_Object *content;
3020 if (sd->decorate_all_mode)
3022 EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, content)
3024 const char *type = elm_widget_type_get(content);
3025 if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3026 elm_object_signal_emit(content, "elm,state,mouse,down", "elm");
3031 EINA_LIST_FOREACH(it->content_objs, l, content)
3033 const char *type = elm_widget_type_get(content);
3034 if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3035 elm_object_signal_emit(content, "elm,state,mouse,down", "elm");
3038 //****************************
3040 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
3041 if (_elm_atspi_enabled())
3042 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), EO_OBJ(it));
3046 _item_unhighlight(Elm_Gen_Item *it, Eina_Bool effect EINA_UNUSED)
3048 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wsd);
3049 if (!it->highlighted) return;
3051 it->highlighted = EINA_FALSE;
3052 GL_IT(it)->wsd->highlighted_item = NULL;
3054 if (!it->realized) goto end;
3056 if (!TIZEN_PROFILE_WEARABLE)
3058 if (GL_IT(it)->wsd->banded_bg_on && effect)
3060 if (it->item->banded_anim) ecore_animator_del(it->item->banded_anim);
3061 it->item->banded_anim = ecore_animator_timeline_add(ELM_ITEM_HIGHLIGHT_TIMER, _banded_item_highlight_anim, it);
3065 if (it->item->banded_anim) ELM_SAFE_FREE(it->item->banded_anim, ecore_animator_del);
3066 _banded_item_bg_color_change(it, EINA_FALSE);
3069 if (it->deco_all_view)
3070 edje_object_signal_emit(it->deco_all_view, SIGNAL_UNHIGHLIGHTED, "elm");
3071 edje_object_signal_emit(VIEW(it), SIGNAL_UNHIGHLIGHTED, "elm");
3072 if (wsd->scroll_item_align_enable)
3073 edje_object_signal_emit(wsd->resize_obj, SIGNAL_UNHIGHLIGHTED, "elm");
3075 edje_object_signal_emit(VIEW(it), SIGNAL_UNHIGHLIGHTED, "elm");
3076 //******************** TIZEN Only
3077 // If check is used on genlist item, unhighlight it also.
3079 Evas_Object *content;
3080 if (GL_IT(it)->wsd->decorate_all_mode)
3082 EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, content)
3084 const char *type = elm_widget_type_get(content);
3085 if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3086 elm_object_signal_emit(content, "elm,state,mouse,up", "elm");
3091 EINA_LIST_FOREACH(it->content_objs, l, content)
3093 const char *type = elm_widget_type_get(content);
3094 if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3095 elm_object_signal_emit(content, "elm,state,mouse,up", "elm");
3098 //*******************************
3100 evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, EO_OBJ(it));
3104 _item_unselect(Elm_Gen_Item *it)
3106 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
3108 if (!it->selected) return;
3110 it->selected = EINA_FALSE;
3111 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
3112 _item_unhighlight(it, EINA_TRUE);
3113 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, EO_OBJ(it));
3117 _item_select(Elm_Gen_Item *it)
3119 Evas_Object *obj = WIDGET(it);
3120 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
3122 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get())) return;
3123 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3124 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
3125 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3126 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
3128 if (sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS &&
3129 it->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS &&
3134 const Eina_List *l, *ll;
3135 Elm_Object_Item *eo_it2;
3136 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it2)
3137 if (eo_it2 != EO_OBJ(it))
3139 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
3140 _item_unselect(it2);
3146 sd->selected = eina_list_append(sd->selected, EO_OBJ(it));
3147 it->selected = EINA_TRUE;
3149 sd->last_selected_item = EO_OBJ(it);
3150 _item_highlight(it);
3152 if (sd->focused_content)
3154 elm_object_focus_set(sd->focused_content, EINA_FALSE);
3155 evas_object_focus_set(obj, EINA_TRUE);
3156 sd->focused_content = NULL;
3159 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3160 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3164 // FIXME: after evas_object_raise, mouse event callbacks(ex, UP, DOWN)
3165 // can be called again eventhough already received it.
3166 const char *selectraise = edje_object_data_get(VIEW(it), "selectraise");
3167 if ((selectraise) && (!strcmp(selectraise, "on")))
3169 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
3170 else evas_object_raise(VIEW(it));
3171 if ((GL_IT(it)->group_item) && (GL_IT(it)->group_item->realized))
3172 evas_object_raise(GL_IT(it)->VIEW(group_item));
3175 edje_object_signal_emit
3176 (VIEW(it), SIGNAL_CLICKED, "elm");
3177 edje_object_message_signal_process(VIEW(it));
3179 evas_object_ref(obj);
3180 if (it->func.func) it->func.func((void *)it->func.data, obj, EO_OBJ(it));
3181 if (EINA_MAGIC_CHECK(it->base, ELM_WIDGET_ITEM_MAGIC))
3182 evas_object_smart_callback_call(obj, SIG_SELECTED, EO_OBJ(it));
3183 evas_object_unref(obj);
3187 _highlight_timer(void *data)
3189 Elm_Gen_Item *it = data;
3190 GL_IT(it)->highlight_timer = NULL;
3191 _item_highlight(it);
3196 _select_timer(void *data)
3198 Elm_Gen_Item *it = data;
3199 GL_IT(it)->highlight_timer = NULL;
3201 if ((GL_IT(it)->wsd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS) ||
3202 (it->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS))
3206 // TIZEN Only(20150708) : unselect when selected item is selected again
3207 // There need to be implemented 'SELECT_UNSELECT' mode in elm_config
3208 // select mode for support upsteam and TIZEN both.
3209 if (!it->selected) _item_select(it);
3210 else _item_unselect(it);
3218 *_item_focusable_content_search(Evas_Object *obj, Eina_List *l, int dir)
3220 if ((dir != 1) && (dir != -1)) return NULL;
3222 Evas_Object *next = NULL;
3223 Elm_Object_Item *next_item = NULL;
3227 next = eina_list_data_get(l);
3228 if (next && (elm_widget_can_focus_get(next) &&
3229 (evas_object_visible_get(next))))
3231 else if (next && (elm_widget_child_can_focus_get(next)))
3233 if (elm_widget_focused_object_get(next))
3237 Evas_Object *child = next;
3239 (elm_widget_focus_next_get(next, ELM_FOCUS_RIGHT, &child, &next_item)))
3241 else if ((dir == -1) &&
3242 (elm_widget_focus_next_get(next, ELM_FOCUS_LEFT, &child, &next_item)))
3248 if (dir == 1) l = eina_list_next(l);
3249 else l = eina_list_prev(l);
3252 if (!next) next = obj;
3257 static Eina_Bool _item_focusable_search(Elm_Gen_Item **it, int dir)
3259 if (!(*it)) return EINA_FALSE;
3260 if ((dir != 1) && (dir != -1)) return EINA_FALSE;
3262 Elm_Gen_Item *tmp = *it;
3266 if (!elm_object_item_disabled_get(EO_OBJ(tmp)) &&
3267 (!tmp->want_hidden))
3269 if ((tmp->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
3270 (tmp->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3273 Evas_Object *obj = NULL;
3274 Eina_List *contents = NULL;
3276 contents = GL_IT(tmp)->flip_content_objs;
3279 contents = tmp->content_objs;
3280 if (tmp->deco_all_view)
3283 contents = GL_IT(tmp)->deco_all_contents;
3285 contents = eina_list_merge(contents,
3286 GL_IT(tmp)->deco_all_contents);
3291 obj = _item_focusable_content_search(NULL, contents, 1);
3294 contents = eina_list_last(contents);
3295 obj = _item_focusable_content_search(NULL, contents, -1);
3300 if (GL_IT(tmp)->wsd->focused_content)
3301 elm_object_focus_set(GL_IT(tmp)->wsd->focused_content, EINA_FALSE);
3302 GL_IT(tmp)->wsd->focused_content = obj;
3303 elm_object_focus_set(obj, EINA_TRUE);
3308 if (GL_IT(tmp)->wsd->focused_content)
3310 elm_object_focus_set(GL_IT(tmp)->wsd->focused_content, EINA_FALSE);
3311 evas_object_focus_set(WIDGET(tmp), EINA_TRUE);
3312 GL_IT(tmp)->wsd->focused_content = NULL;
3318 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->next);
3320 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
3327 static Eina_Bool _item_focus_next(Elm_Genlist_Data *sd, Focus_Dir dir)
3329 Elm_Gen_Item *it = NULL;
3330 Elm_Gen_Item *old_focused = sd->focused_item;
3331 Evas_Object *old_content = sd->focused_content;
3333 if (dir == FOCUS_DIR_DOWN || dir == FOCUS_DIR_UP)
3335 Eina_Bool find_item;
3337 if (dir == FOCUS_DIR_DOWN)
3339 if (sd->focused_item)
3341 it = ELM_GEN_ITEM_FROM_INLIST
3342 (EINA_INLIST_GET(sd->focused_item)->next);
3343 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3345 else it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
3346 find_item = _item_focusable_search(&it, 1);
3348 else if (dir == FOCUS_DIR_UP)
3350 if (sd->focused_item)
3352 it = ELM_GEN_ITEM_FROM_INLIST
3353 (EINA_INLIST_GET(sd->focused_item)->prev);
3354 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3356 else it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
3357 find_item = _item_focusable_search(&it, -1);
3366 sd->focused_content = old_content;
3367 elm_object_focus_set(old_content, EINA_TRUE);
3371 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3372 elm_object_item_focus_set(EO_OBJ(old_focused), EINA_TRUE);
3377 else if (!find_item)
3380 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3381 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3383 else if (dir == FOCUS_DIR_LEFT || dir == FOCUS_DIR_RIGHT)
3385 Evas_Object *obj = NULL;
3386 Eina_List *contents = NULL;
3387 Eina_List *l = NULL;
3389 if (!sd->focused_item) return EINA_FALSE;
3390 if (sd->focused_item->flipped)
3391 contents = GL_IT(sd->focused_item)->flip_content_objs;
3394 contents = sd->focused_item->content_objs;
3395 if (sd->focused_item->deco_all_view)
3398 contents = GL_IT(sd->focused_item)->deco_all_contents;
3400 contents = eina_list_merge(contents,
3401 GL_IT(sd->focused_item)->deco_all_contents);
3405 if (sd->focused_content)
3407 l = eina_list_data_find_list(contents,
3408 sd->focused_content);
3409 obj = sd->focused_content;
3412 if (dir == FOCUS_DIR_LEFT)
3414 if ((l) && (eina_list_prev(l)))
3416 l = eina_list_prev(l);
3417 obj = _item_focusable_content_search(obj, l, -1);
3418 if (!obj) obj = sd->focused_content;
3422 //search focused content is child of content
3423 if (sd->focused_content)
3424 l = eina_list_data_find_list(contents,
3425 sd->focused_content);
3426 if (!l) l = eina_list_last(contents);
3427 obj = _item_focusable_content_search(obj, l, -1);
3429 else obj = sd->focused_content;
3431 else if (dir == FOCUS_DIR_RIGHT)
3433 if ((l) && (eina_list_next(l)))
3435 l = eina_list_next(l);
3436 obj = _item_focusable_content_search(obj, l, 1);
3437 if (!obj) obj = sd->focused_content;
3441 //search focused content is child of content
3442 if (sd->focused_content)
3443 l = eina_list_data_find_list(contents,
3444 sd->focused_content);
3445 if (!l) l = contents;
3446 obj = _item_focusable_content_search(obj, l, 1);
3448 else obj = sd->focused_content;
3453 sd->focused_content = obj;
3454 elm_object_focus_set(obj, EINA_TRUE);
3458 sd->focused_content = NULL;
3462 else return EINA_FALSE;
3467 //#ifdef ELM_FOCUSED_UI
3468 EOLIAN static Eina_Bool
3469 _elm_genlist_elm_widget_event(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *src EINA_UNUSED, Evas_Callback_Type type, void *event_info)
3475 Evas_Coord step_x = 0;
3476 Evas_Coord step_y = 0;
3477 Evas_Coord page_x = 0;
3478 Evas_Coord page_y = 0;
3479 Evas_Event_Key_Down *ev = event_info;
3480 Evas_Coord pan_max_x = 0, pan_max_y = 0;
3482 //ELM_GENLIST_DATA_GET(obj, sd);
3484 // TIZEN ONLY(20131221) : When access mode, focused ui is disabled.
3485 if (_elm_config->access_mode) return EINA_FALSE;
3487 if ((type != EVAS_CALLBACK_KEY_DOWN) && (type != EVAS_CALLBACK_KEY_UP))
3489 if (!sd->items) return EINA_FALSE;
3490 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
3491 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
3494 elm_interface_scrollable_content_pos_get(&x, &y),
3495 elm_interface_scrollable_step_size_get(&step_x, &step_y),
3496 elm_interface_scrollable_page_size_get(&page_x, &page_y),
3497 elm_interface_scrollable_content_viewport_geometry_get
3498 (NULL, NULL, &v_w, &v_h));
3500 if ((!strcmp(ev->keyname, "Left")) ||
3501 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)) ||
3502 (!strcmp(ev->keyname, "Right")) ||
3503 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)) ||
3504 (!strcmp(ev->keyname, "Up")) ||
3505 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)) ||
3506 (!strcmp(ev->keyname, "Down")) ||
3507 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)) ||
3508 (!strcmp(ev->keyname, "Home")) ||
3509 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)) ||
3510 (!strcmp(ev->keyname, "End")) ||
3511 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)) ||
3512 (!strcmp(ev->keyname, "Prior")) ||
3513 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)) ||
3514 (!strcmp(ev->keyname, "Next")) ||
3515 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
3517 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3518 _elm_widget_focus_auto_show(obj);
3521 if ((!strcmp(ev->keyname, "Left")) ||
3522 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
3524 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3525 if (sd->select_on_focus_enabled) x -= step_x;
3528 if (_item_focus_next(sd, FOCUS_DIR_LEFT))
3530 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3537 else if ((!strcmp(ev->keyname, "Right")) ||
3538 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
3540 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3541 if (sd->select_on_focus_enabled) x += step_x;
3544 if (_item_focus_next(sd, FOCUS_DIR_RIGHT))
3546 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3553 else if ((!strcmp(ev->keyname, "Up")) ||
3554 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
3556 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3557 if (sd->select_on_focus_enabled)
3559 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
3560 (_item_multi_select_up(sd))) || (_item_single_select_up(sd)))
3562 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3568 if (_item_focus_next(sd, FOCUS_DIR_UP))
3570 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3577 else if ((!strcmp(ev->keyname, "Down")) ||
3578 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
3580 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3581 if (sd->select_on_focus_enabled)
3583 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
3584 (_item_multi_select_down(sd))) ||
3585 (_item_single_select_down(sd)))
3587 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3593 if (_item_focus_next(sd, FOCUS_DIR_DOWN))
3595 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3602 else if ((!strcmp(ev->keyname, "Home")) ||
3603 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
3605 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3606 if (sd->select_on_focus_enabled)
3608 Elm_Object_Item *it = elm_genlist_first_item_get(obj);
3609 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
3610 elm_genlist_item_selected_set(it, EINA_TRUE);
3611 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3615 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3616 _item_focus_next(sd, FOCUS_DIR_DOWN);
3617 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3621 else if ((!strcmp(ev->keyname, "End")) ||
3622 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
3624 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3625 if (sd->select_on_focus_enabled)
3627 Elm_Object_Item *it = elm_genlist_last_item_get(obj);
3628 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
3629 elm_genlist_item_selected_set(it, EINA_TRUE);
3633 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3634 sd->focused_item = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
3635 _item_focus_next(sd, FOCUS_DIR_UP);
3637 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3640 else if ((!strcmp(ev->keyname, "Prior")) ||
3641 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
3643 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3644 Elm_Gen_Item *it = sd->focused_item;
3645 Elm_Object_Item *eo_prev;
3647 while (page_y <= v_h)
3649 if (elm_genlist_item_prev_get(EO_OBJ(it)))
3651 eo_prev = elm_genlist_item_prev_get(EO_OBJ(it));
3652 it = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
3655 page_y += GL_IT(it)->minh;
3657 if (_item_focusable_search(&it, -1))
3659 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3660 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3664 _item_focusable_search(&it, 1);
3665 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3666 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3669 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3672 else if ((!strcmp(ev->keyname, "Next")) ||
3673 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
3675 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3676 Elm_Gen_Item *it = sd->focused_item;
3677 Elm_Object_Item *eo_next;
3679 page_y = GL_IT(it)->minh;
3681 while (page_y <= v_h)
3683 if (elm_genlist_item_next_get(EO_OBJ(it)))
3685 eo_next = elm_genlist_item_next_get(EO_OBJ(it));
3686 it = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
3689 page_y += GL_IT(it)->minh;
3691 if (_item_focusable_search(&it, 1))
3693 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3694 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3698 _item_focusable_search(&it, -1);
3699 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3700 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3703 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3704 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3706 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3709 else if (!strcmp(ev->keyname, "Escape"))
3711 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3712 if (!_all_items_deselect(sd)) return EINA_FALSE;
3713 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3716 else if (!strcmp(ev->keyname, "Return") ||
3717 !strcmp(ev->keyname, "KP_Enter") ||
3718 !strcmp(ev->keyname, "space"))
3721 if (type == EVAS_CALLBACK_KEY_DOWN && !sd->key_down_item)
3723 if (sd->focused_item)
3725 sd->key_down_item = sd->focused_item;
3727 edje_object_signal_emit
3728 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
3729 if (sd->focused_item->deco_all_view)
3730 edje_object_signal_emit
3731 (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
3733 _item_highlight(sd->key_down_item);
3734 if (sd->key_down_item->long_timer)
3735 ecore_timer_del(sd->key_down_item->long_timer);
3736 sd->key_down_item->long_timer = ecore_timer_add
3737 (sd->longpress_timeout,
3738 _long_press_cb, sd->key_down_item);
3739 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3740 evas_object_smart_callback_call(obj, SIG_ACTIVATED, EO_OBJ(sd->key_down_item));
3743 else return EINA_FALSE;
3745 else if (type == EVAS_CALLBACK_KEY_UP && sd->key_down_item)
3747 edje_object_signal_emit
3748 (VIEW(sd->key_down_item), SIGNAL_FOCUSED, "elm");
3749 if (sd->key_down_item->deco_all_view)
3750 edje_object_signal_emit
3751 (sd->key_down_item->deco_all_view, SIGNAL_FOCUSED, "elm");
3753 if (sd->key_down_item->long_timer)
3754 ecore_timer_del(sd->key_down_item->long_timer);
3755 sd->key_down_item->long_timer = NULL;
3756 if (GL_IT(sd->key_down_item)->highlight_timer)
3757 ecore_timer_del(GL_IT(sd->key_down_item)->highlight_timer);
3758 GL_IT(sd->key_down_item)->highlight_timer = ecore_timer_add
3759 (ITEM_SELECT_TIMER, _select_timer, sd->key_down_item);
3760 sd->key_down_item = NULL;
3761 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3764 else return EINA_FALSE;
3766 else return EINA_FALSE;
3768 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3769 eo_do(sd->pan_obj, elm_obj_pan_pos_max_get(&pan_max_x, &pan_max_y));
3771 if (x > pan_max_x) x = pan_max_x;
3773 if (y > pan_max_y) y = pan_max_y;
3775 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
3781 /* This function disables the specific code of the layout sub object add.
3782 * Only the widget sub_object_add is called.
3784 EOLIAN static Eina_Bool
3785 _elm_genlist_elm_layout_sub_object_add_enable(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3790 EOLIAN static Eina_Bool
3791 _elm_genlist_elm_widget_sub_object_add(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED, Evas_Object *sobj)
3793 Eina_Bool int_ret = EINA_FALSE;
3795 /* skipping layout's code, which registers size hint changing
3796 * callback on sub objects. this is here because items'
3797 * content_get() routines may change hints on the objects after
3798 * creation, thus issuing TOO MANY sizing_eval()'s here. they are
3799 * not needed at here anyway, so let's skip listening to those
3802 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_add(sobj));
3803 if (!int_ret) return EINA_FALSE;
3805 //if (!parent_parent->sub_object_add(obj, sobj))
3806 // return EINA_FALSE;
3811 EOLIAN static Eina_Bool
3812 _elm_genlist_elm_widget_sub_object_del(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *sobj)
3814 Eina_Bool int_ret = EINA_FALSE;
3816 /* XXX: hack -- also skipping sizing recalculation on
3817 * sub-object-del. genlist's crazy code paths (like groups and
3818 * such) seem to issue a whole lot of deletions and Evas bitches
3819 * about too many recalculations */
3820 sd->on_sub_del = EINA_TRUE;
3822 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_del(sobj));
3823 if (!int_ret) return EINA_FALSE;
3825 sd->on_sub_del = EINA_FALSE;
3831 _elm_genlist_focus_highlight_show(void *data EINA_UNUSED,
3833 const char *emission EINA_UNUSED,
3834 const char *src EINA_UNUSED)
3836 ELM_GENLIST_DATA_GET(obj, sd);
3838 if (sd->focused_item)
3840 if (!sd->focused_content)
3842 Eina_Bool found = EINA_FALSE;
3843 Elm_Gen_Item *it = sd->focused_item;
3844 found = _item_focusable_search(&it, 1);
3847 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3848 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3851 else elm_object_focus_set(sd->focused_content, EINA_TRUE);
3856 _elm_genlist_focus_highlight_hide(void *data EINA_UNUSED,
3858 const char *emission EINA_UNUSED,
3859 const char *src EINA_UNUSED)
3861 ELM_GENLIST_DATA_GET(obj, sd);
3862 if (sd->focused_item)
3864 // Do not use _item_unfocused because focus should be remained
3865 edje_object_signal_emit
3866 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
3867 if (sd->focused_item->deco_all_view)
3868 edje_object_signal_emit
3869 (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
3874 _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)
3876 Evas_Coord ox, oy, oh, ow, item_x = 0, item_y = 0, item_w = 0, item_h = 0;
3877 Elm_Gen_Item *focus_it;
3879 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
3881 if (sd->focused_item)
3883 focus_it = sd->focused_item;
3884 evas_object_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
3885 elm_widget_focus_highlight_focus_part_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
3897 if (item_y > (oy + oh - item_h))
3899 *y = oy + oh - item_h;
3902 if ((item_x + item_w) > (ox + ow))
3912 EOLIAN static Eina_Bool
3913 _elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd, Elm_Object_Item *item EINA_UNUSED)
3915 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
3916 Eina_Bool int_ret = EINA_FALSE;
3918 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_on_focus(NULL));
3919 if (!int_ret) return EINA_FALSE;
3921 if ((sd->items) && (sd->selected) && (!sd->last_selected_item))
3922 sd->last_selected_item = eina_list_data_get(sd->selected);
3924 if (sd->select_on_focus_enabled) return EINA_TRUE;
3925 if (elm_widget_focus_get(obj))
3927 // Do nothing if on_focus is called by child's parent_focus
3928 if (!wd->is_focus_target) return EINA_TRUE;
3930 if (sd->focused_item)
3932 if (!sd->focused_content)
3934 Eina_Bool found = EINA_FALSE;
3935 Elm_Gen_Item *it = sd->focused_item;
3936 found = _item_focusable_search(&it, 1);
3939 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3940 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3944 elm_object_focus_set(sd->focused_content, EINA_TRUE);
3948 Item_Block *itb, *nib;
3949 EINA_INLIST_FOREACH(sd->blocks, itb)
3953 Elm_Gen_Item *tmp = eina_list_data_get(itb->items);
3954 while(tmp && tmp->item->block == itb)
3958 Elm_Gen_Item *old = tmp;
3959 Evas_Coord x, y, w, h, sx, sy, sw, sh;
3960 evas_object_geometry_get(VIEW(tmp), &x, &y, &w, &h);
3961 evas_object_geometry_get(obj, &sx, &sy, &sw, &sh);
3962 /* Item is included viewport and focusable */
3963 if ((ELM_RECTS_INCLUDE(sx, sy, sw, sh, x, y, w, h)) &&
3964 (_item_focusable_search(&tmp, 1)))
3966 Eina_Bool include = EINA_TRUE;
3967 if (old != tmp && tmp->realized)
3969 evas_object_geometry_get(VIEW(tmp), &x, &y, &w, &h);
3970 evas_object_geometry_get(obj, &sx, &sy, &sw, &sh);
3971 include = ELM_RECTS_INCLUDE(sx, sy, sw, sh, x, y, w, h);
3973 else if (!tmp->realized) include = EINA_FALSE;
3977 elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
3984 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->next);
3987 nib = EINA_INLIST_CONTAINER_GET(EINA_INLIST_GET(itb)->next, Item_Block);
3988 if (!nib || !nib->realized) break;
3991 if (!sd->focused_item) _item_focus_next(sd, FOCUS_DIR_DOWN);
3996 // when key down and not called key up
3997 // and focus is not on genlist, call select_timer forcely
3998 if (sd->key_down_item)
4000 _select_timer(sd->key_down_item);
4001 sd->key_down_item = NULL;
4004 if (sd->focused_item)
4006 if (sd->focused_content)
4008 //FIXME: when genlist contents loose their focus,
4009 // focus unset should automatically work.
4010 elm_object_focus_set(sd->focused_content, EINA_FALSE);
4012 // Do not use _item_unfocused because focus should be remained
4013 edje_object_signal_emit
4014 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
4015 if (sd->focused_item->deco_all_view)
4016 edje_object_signal_emit
4017 (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
4025 _elm_genlist_item_elm_widget_item_focus_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool focused)
4027 Evas_Object *obj = WIDGET(it);
4028 ELM_GENLIST_DATA_GET(obj, sd);
4032 if (!elm_object_focus_get(obj))
4033 elm_object_focus_set(obj, EINA_TRUE);
4035 if (!elm_widget_focus_get(obj))
4038 if (sd->focused_content)
4040 elm_object_focus_set(sd->focused_content, EINA_FALSE);
4041 sd->focused_content = NULL;
4044 if (it != sd->focused_item)
4046 if (sd->focused_item)
4047 _item_unfocused(sd->focused_item);
4048 _item_focused(it, sd->focus_scrollto_type);
4050 /* If item is not realized state, widget couldn't get focus_highlight data. */
4053 _elm_widget_item_highlight_in_theme(obj, EO_OBJ(it));
4054 _elm_widget_highlight_in_theme_update(obj);
4055 _elm_widget_focus_highlight_start(obj);
4061 if (!elm_widget_focus_get(obj))
4063 _item_unfocused(it);
4067 EOLIAN static Eina_Bool
4068 _elm_genlist_item_elm_widget_item_focus_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
4070 Evas_Object *obj = WIDGET(it);
4071 ELM_GENLIST_DATA_GET(obj, sd);
4073 if (it == sd->focused_item)
4079 EOLIAN static Elm_Object_Item*
4080 _elm_genlist_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
4082 return EO_OBJ(sd->focused_item);
4085 static Eina_Bool _elm_genlist_smart_focus_next_enable = EINA_FALSE;
4087 EOLIAN static Eina_Bool
4088 _elm_genlist_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
4090 return _elm_genlist_smart_focus_next_enable;
4093 EOLIAN static Eina_Bool
4094 _elm_genlist_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
4099 EOLIAN static Eina_Bool
4100 _elm_genlist_elm_widget_focus_next(Eo *obj, Elm_Genlist_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
4102 Eina_List *items = NULL;
4103 Item_Block *itb = NULL;
4104 Elm_Object_Item *eo_it = NULL;
4106 if (!sd->blocks) return EINA_FALSE;
4107 if (!sd->is_access) return EINA_FALSE;
4109 if (!elm_widget_highlight_get(obj))
4111 if (ELM_FOCUS_PREVIOUS == dir)
4113 eo_it = elm_genlist_last_item_get(obj);
4114 itb = EINA_INLIST_CONTAINER_GET(sd->blocks->last, Item_Block);
4116 else if (ELM_FOCUS_NEXT == dir)
4118 eo_it = elm_genlist_first_item_get(obj);
4119 itb = EINA_INLIST_CONTAINER_GET(sd->blocks, Item_Block);
4121 else return EINA_FALSE;
4123 if (eo_it && itb && itb->calc_done)
4125 _item_block_realize(itb, EINA_TRUE);
4126 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
4128 else return EINA_FALSE;
4131 // FIXME: do not use realized items get
4132 // because of above forcing realization case.
4133 EINA_INLIST_FOREACH(sd->blocks, itb)
4138 if (!itb->realized) continue;
4140 EINA_LIST_FOREACH(itb->items, l, it)
4143 Evas_Object *c, *ret;
4146 if (!(it->realized)) continue;
4148 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_access_object_get()))
4149 items = eina_list_append(items, eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_access_object_get()));
4151 items = eina_list_append(items, VIEW(it));
4153 orders = (Eina_List *)elm_object_item_access_order_get(EO_OBJ(it));
4154 EINA_LIST_FOREACH(orders, ll, c)
4156 items = eina_list_append(items, c);
4161 return elm_widget_focus_list_next_get
4162 (obj, items, eina_list_data_get, dir, next, next_item);
4166 _mirrored_set(Evas_Object *obj,
4169 eo_do(obj, elm_interface_scrollable_mirrored_set(rtl));
4172 EOLIAN static Elm_Theme_Apply
4173 _elm_genlist_elm_widget_theme_apply(Eo *obj, Elm_Genlist_Data *sd)
4176 Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
4177 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wsd, ELM_THEME_APPLY_FAILED);
4179 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
4180 if (!int_ret) return ELM_THEME_APPLY_FAILED;
4182 if (!TIZEN_PROFILE_WEARABLE)
4183 _banded_bg_state_check(obj, sd);
4185 EINA_INLIST_FOREACH(sd->blocks, itb)
4189 EINA_LIST_FOREACH(itb->items, l, it)
4193 _item_unrealize(it, EINA_FALSE);
4194 GL_IT(it)->calc_done = EINA_FALSE;
4195 GL_IT(it)->block->calc_done = EINA_FALSE;
4197 else _item_queue(it, NULL);
4200 sd->calc_done = EINA_FALSE;
4201 _item_cache_all_free(sd);
4202 eina_hash_free_buckets(sd->size_caches);
4203 elm_layout_sizing_eval(obj);
4204 _changed(sd->pan_obj);
4206 if (wsd->scroll_item_align_enable && sd->aligned_item)
4207 elm_genlist_item_show(EO_OBJ(sd->aligned_item), ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
4212 /* FIXME: take off later. maybe this show region coords belong in the
4213 * interface (new api functions, set/get)? */
4215 _show_region_hook(void *data,
4218 Evas_Coord x, y, w, h;
4220 ELM_GENLIST_DATA_GET(data, sd);
4222 elm_widget_show_region_get(obj, &x, &y, &w, &h);
4223 //x & y are screen coordinates, Add with pan coordinates
4227 eo_do(obj, elm_interface_scrollable_content_region_show(x, y, w, h));
4230 EOLIAN static Eina_Bool
4231 _elm_genlist_elm_widget_translate(Eo *obj, Elm_Genlist_Data *sd)
4235 // Before calling text_get, inform user first.
4236 evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
4238 // FIXME: We should change item's height if lang is changed??
4239 EINA_INLIST_FOREACH(sd->blocks, itb)
4243 EINA_LIST_FOREACH(itb->items, l, it)
4247 elm_genlist_item_fields_update(EO_OBJ(it),
4249 ELM_GENLIST_ITEM_FIELD_TEXT);
4251 else GL_IT(it)->calc_done = EINA_FALSE;
4253 itb->calc_done = EINA_FALSE;
4256 eina_hash_free_buckets(sd->size_caches);
4257 sd->calc_done = EINA_FALSE;
4263 _elm_genlist_elm_widget_item_loop_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enable EINA_UNUSED)
4265 // Need to be implemented
4266 //sd->item_loop_enable = !!enable;
4269 EOLIAN static Eina_Bool
4270 _elm_genlist_elm_widget_item_loop_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
4272 // Need to be implemented
4273 //return sd->item_loop_enable;
4278 _item_block_position_update(Eina_Inlist *list,
4283 EINA_INLIST_FOREACH(list, tmp)
4285 tmp->position = idx++;
4286 tmp->position_update = EINA_TRUE;
4291 _item_position_update(Eina_List *list,
4297 EINA_LIST_FOREACH(list, l, it)
4299 it->position = idx++;
4300 it->position_update = EINA_TRUE;
4305 _item_block_merge(Item_Block *left,
4311 EINA_LIST_FOREACH(right->items, l, it2)
4313 it2->item->block = left;
4315 left->calc_done = EINA_FALSE;
4317 left->items = eina_list_merge(left->items, right->items);
4321 _item_block_del(Elm_Gen_Item *it)
4323 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4325 Item_Block *itb = GL_IT(it)->block;
4326 Eina_Bool block_changed = EINA_FALSE;
4329 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
4330 (NULL, NULL, NULL, &vh));
4331 if (sd->processed_sizes >= vh) sd->processed_sizes = 0;
4333 itb->items = eina_list_remove(itb->items, it);
4335 itb->calc_done = EINA_FALSE;
4336 sd->calc_done = EINA_FALSE;
4337 _changed(sd->pan_obj);
4342 il = EINA_INLIST_GET(itb);
4343 itbn = (Item_Block *)(il->next);
4345 it->parent->item->items =
4346 eina_list_remove(it->parent->item->items, EO_OBJ(it));
4349 _item_block_position_update(il->next, itb->position);
4351 GL_IT(it)->wsd->blocks =
4352 eina_inlist_remove(GL_IT(it)->wsd->blocks, il);
4353 GL_IT(it)->wsd->blocks_realized = eina_list_remove
4354 (GL_IT(it)->wsd->blocks_realized, itb);
4357 if (itbn) itbn->calc_done = EINA_FALSE;
4361 if (itb->count < (itb->sd->max_items_per_block / 2))
4366 il = EINA_INLIST_GET(itb);
4367 itbp = (Item_Block *)(il->prev);
4368 itbn = (Item_Block *)(il->next);
4370 /* merge block with previous */
4372 ((itbp->count + itb->count) <
4373 (itb->sd->max_items_per_block +
4374 (itb->sd->max_items_per_block / 2))))
4376 _item_block_merge(itbp, itb);
4377 _item_block_position_update
4378 (EINA_INLIST_GET(itb)->next, itb->position);
4379 GL_IT(it)->wsd->blocks = eina_inlist_remove
4380 (GL_IT(it)->wsd->blocks, EINA_INLIST_GET(itb));
4381 GL_IT(it)->wsd->blocks_realized = eina_list_remove
4382 (GL_IT(it)->wsd->blocks_realized, itb);
4384 block_changed = EINA_TRUE;
4386 /* merge block with next */
4388 ((itbn->count + itb->count) <
4389 (itb->sd->max_items_per_block +
4390 (itb->sd->max_items_per_block / 2))))
4392 _item_block_merge(itb, itbn);
4393 _item_block_position_update
4394 (EINA_INLIST_GET(itbn)->next, itbn->position);
4395 GL_IT(it)->wsd->blocks =
4396 eina_inlist_remove(GL_IT(it)->wsd->blocks,
4397 EINA_INLIST_GET(itbn));
4398 GL_IT(it)->wsd->blocks_realized = eina_list_remove
4399 (GL_IT(it)->wsd->blocks_realized, itbn);
4401 block_changed = EINA_TRUE;
4408 _changed(sd->pan_obj);
4411 GL_IT(it)->block = NULL;
4415 _decorate_all_item_unrealize(Elm_Gen_Item *it)
4417 if (!it->deco_all_view) return;
4419 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
4420 _view_clear(it->deco_all_view, &(GL_IT(it)->deco_all_contents));
4421 evas_object_del(it->deco_all_view);
4422 it->deco_all_view = NULL;
4424 edje_object_signal_emit(VIEW(it), SIGNAL_DECORATE_DISABLED, "elm");
4426 _item_mouse_callbacks_add(it, VIEW(it));
4427 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
4432 _item_mouse_move_cb(void *data,
4433 Evas *evas EINA_UNUSED,
4437 Evas_Event_Mouse_Move *ev = event_info;
4438 Elm_Gen_Item *it = data;
4439 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4441 if (!it->down) return;
4443 if (((sd->reorder_force) || (sd->reorder_mode)) &&
4444 (sd->reorder.it == it) &&
4448 evas_object_geometry_get(sd->pan_obj, &ox, NULL, NULL, NULL);
4450 if ((ev->cur.canvas.y - it->dy) > GL_IT(it)->scrl_y)
4451 sd->reorder.dir = 1;
4452 else if ((ev->cur.canvas.y - it->dy) < GL_IT(it)->scrl_y)
4453 sd->reorder.dir = -1;
4455 GL_IT(it)->scrl_x = it->x + GL_IT(it)->block->x - sd->pan_x + ox;
4456 GL_IT(it)->scrl_y = ev->cur.canvas.y - it->dy;
4457 GL_IT(it)->w = sd->minw;
4458 GL_IT(it)->h = GL_IT(it)->minh;
4459 _changed(sd->pan_obj);
4462 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4464 if (GL_IT(it)->highlight_timer)
4466 ecore_timer_del(GL_IT(it)->highlight_timer);
4467 GL_IT(it)->highlight_timer = NULL;
4469 else if (!it->selected) _item_unhighlight(it, EINA_FALSE);
4473 ecore_timer_del(it->long_timer);
4474 it->long_timer = NULL;
4476 sd->on_hold = EINA_TRUE; /* for checking need to start select timer */
4478 //******************** TIZEN Only
4481 if (((sd->reorder_force) || (sd->reorder_mode)) &&
4482 (sd->reorder.it == it) && (!it->want_hidden))
4484 Evas_Coord x, y, w, h;
4485 evas_object_geometry_get(obj, &x, &y, &w, &h);
4486 if (ELM_RECTS_POINT_OUT(x, y, w, h, ev->cur.canvas.x, ev->cur.canvas.y))
4490 ecore_timer_del(it->long_timer);
4491 it->long_timer = NULL;
4493 if (GL_IT(it)->highlight_timer)
4495 ecore_timer_del(GL_IT(it)->highlight_timer);
4496 GL_IT(it)->highlight_timer = NULL;
4498 else if (!it->selected) _item_unhighlight(it, EINA_FALSE);
4501 //*******************************
4503 evas_object_ref(obj);
4507 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
4508 minw = GL_IT(it)->wsd->finger_minw;
4509 minh = GL_IT(it)->wsd->finger_minh;
4511 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4512 dx = ev->cur.canvas.x - x;
4513 dy = ev->cur.canvas.y - y;
4518 if (adx < 0) adx = -dx;
4519 if (ady < 0) ady = -dy;
4520 if ((adx > minw) || (ady > minh))
4522 it->dragging = EINA_TRUE;
4523 /* Genlist is scrolled vertically, so reduce left or right case for accuracy. */
4524 if (adx > (ady * 2))
4527 evas_object_smart_callback_call
4528 (WIDGET(it), SIG_DRAG_START_LEFT, EO_OBJ(it));
4530 evas_object_smart_callback_call
4531 (WIDGET(it), SIG_DRAG_START_RIGHT, EO_OBJ(it));
4536 evas_object_smart_callback_call
4537 (WIDGET(it), SIG_DRAG_START_UP, EO_OBJ(it));
4539 evas_object_smart_callback_call
4540 (WIDGET(it), SIG_DRAG_START_DOWN, EO_OBJ(it));
4545 /* If item magic value is changed, do not call smart callback*/
4546 if (EINA_MAGIC_CHECK(it->base, ELM_WIDGET_ITEM_MAGIC))
4549 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, EO_OBJ(it));
4552 evas_object_unref(obj);
4557 _long_press_cb(void *data)
4559 Elm_Gen_Item *it = data;
4560 Elm_Object_Item *eo_it2;
4561 Elm_Genlist_Data *sd;
4565 sd = GL_IT(it)->wsd;
4566 it->long_timer = NULL;
4568 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()) ||
4569 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
4570 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
4571 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
4572 (sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
4575 if ((sd->reorder_mode) &&
4576 (GL_IT(it)->type != ELM_GENLIST_ITEM_GROUP) &&
4577 (!sd->key_down_item))
4579 if (elm_genlist_item_expanded_get(EO_OBJ(it)))
4581 elm_genlist_item_expanded_set(EO_OBJ(it), EINA_FALSE);
4583 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it2)
4585 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
4586 _item_unselect(it2);
4589 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
4590 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
4591 (EINA_FALSE, EINA_FALSE));
4593 if (TIZEN_PROFILE_WEARABLE)
4596 if (sd->decorate_all_mode)
4597 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
4601 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
4604 sd->reorder.it = it;
4605 _changed(sd->pan_obj);
4607 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, EO_OBJ(it));
4610 it->long_timer = NULL;
4611 return ECORE_CALLBACK_CANCEL;
4615 _gesture_do(void *data)
4617 Elm_Genlist_Data *sd = data;
4619 if ((sd->g_item) && (sd->g_type))
4621 if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_LEFT))
4622 evas_object_smart_callback_call
4623 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_LEFT, EO_OBJ(sd->g_item));
4624 else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_RIGHT))
4625 evas_object_smart_callback_call
4626 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_RIGHT, EO_OBJ(sd->g_item));
4627 else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_UP))
4628 evas_object_smart_callback_call
4629 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_UP, EO_OBJ(sd->g_item));
4630 else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_DOWN))
4631 evas_object_smart_callback_call
4632 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_DOWN, EO_OBJ(sd->g_item));
4633 else if (!strcmp(sd->g_type, SIG_MULTI_PINCH_OUT))
4634 evas_object_smart_callback_call
4635 (WIDGET(sd->g_item), SIG_MULTI_PINCH_OUT, EO_OBJ(sd->g_item));
4636 else if (!strcmp(sd->g_type, SIG_MULTI_PINCH_IN))
4637 evas_object_smart_callback_call
4638 (WIDGET(sd->g_item), SIG_MULTI_PINCH_IN, EO_OBJ(sd->g_item));
4639 else if (!strcmp(sd->g_type, SIG_SWIPE))
4640 evas_object_smart_callback_call
4641 (WIDGET(sd->g_item), SIG_SWIPE, EO_OBJ(sd->g_item));
4649 _item_mouse_down_cb(void *data,
4654 Evas_Event_Mouse_Down *ev = event_info;
4655 Elm_Gen_Item *it = data;
4656 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4659 if (ev->event_flags & EVAS_EVENT_FLAG_ON_SCROLL)
4663 elm_genlist_item_reorder_stop(EO_OBJ(sd->reorder.it));
4664 sd->reorder.it = NULL;
4665 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
4666 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set(sd->h_bounce, sd->v_bounce));
4671 if (ev->button != 1) return;
4672 // mouse down is activate only one finger
4673 if (evas_event_down_count_get(evas) != 1) return;
4675 if (GL_IT(it)->highlight_timer)
4676 ecore_timer_del(GL_IT(it)->highlight_timer);
4677 // FIXME: To prevent timing issue about select and highlight
4678 else if (!sd->multi && sd->highlighted_item &&
4679 (GL_IT(sd->highlighted_item)->highlight_timer))
4682 it->down = EINA_TRUE;
4684 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4685 it->dx = ev->canvas.x - x;
4686 it->dy = ev->canvas.y - y;
4688 GL_IT(it)->wsd->was_selected = it->selected;
4689 GL_IT(it)->highlight_timer = ecore_timer_add(ELM_ITEM_HIGHLIGHT_TIMER,
4690 _highlight_timer, it);
4691 if (it->long_timer) ecore_timer_del(it->long_timer);
4692 it->long_timer = ecore_timer_add(sd->longpress_timeout, _long_press_cb, it);
4694 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
4696 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, EO_OBJ(it));
4697 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, EO_OBJ(it));
4699 evas_object_smart_callback_call(WIDGET(it), SIG_PRESSED, EO_OBJ(it));
4703 _item_block_new(Elm_Genlist_Data *sd,
4708 itb = calloc(1, sizeof(Item_Block));
4709 if (!itb) return NULL;
4713 sd->blocks = eina_inlist_prepend(sd->blocks, EINA_INLIST_GET(itb));
4714 _item_block_position_update(sd->blocks, 0);
4718 sd->blocks = eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4719 itb->position_update = EINA_TRUE;
4720 if (sd->blocks != EINA_INLIST_GET(itb))
4723 ((Item_Block *)(EINA_INLIST_GET(itb)->prev))->position + 1;
4735 _item_block_add(Elm_Genlist_Data *sd,
4738 Item_Block *itb = NULL;
4739 if (GL_IT(it)->block) return EINA_TRUE;
4741 if (!GL_IT(it)->rel)
4746 itb = calloc(1, sizeof(Item_Block));
4747 if (!itb) return EINA_FALSE;
4749 if (!GL_IT(it)->rel->item->block)
4752 eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4753 itb->items = eina_list_append(itb->items, it);
4754 itb->position_update = EINA_TRUE;
4755 it->position = eina_list_count(itb->items);
4756 it->position_update = EINA_TRUE;
4758 if (sd->blocks != EINA_INLIST_GET(itb))
4762 (EINA_INLIST_GET(itb)->prev))->position + 1;
4773 tmp = eina_list_data_find_list(itb->items, GL_IT(it)->rel);
4774 if (GL_IT(it)->before)
4776 sd->blocks = eina_inlist_prepend_relative
4777 (sd->blocks, EINA_INLIST_GET(itb),
4778 EINA_INLIST_GET(GL_IT(it)->rel->item->block));
4780 eina_list_prepend_relative_list(itb->items, it, tmp);
4782 /* Update index from where we prepended */
4783 _item_position_update
4784 (eina_list_prev(tmp), GL_IT(it)->rel->position);
4785 _item_block_position_update
4786 (EINA_INLIST_GET(itb),
4787 GL_IT(it)->rel->item->block->position);
4791 sd->blocks = eina_inlist_append_relative
4792 (sd->blocks, EINA_INLIST_GET(itb),
4793 EINA_INLIST_GET(GL_IT(it)->rel->item->block));
4795 eina_list_append_relative_list(itb->items, it, tmp);
4797 /* Update block index from where we appended */
4798 _item_position_update
4799 (eina_list_next(tmp), GL_IT(it)->rel->position + 1);
4800 _item_block_position_update
4801 (EINA_INLIST_GET(itb),
4802 GL_IT(it)->rel->item->block->position + 1);
4808 if (GL_IT(it)->before)
4812 itb = (Item_Block *)(sd->blocks);
4813 if (itb->count >= sd->max_items_per_block)
4815 itb = _item_block_new(sd, EINA_TRUE);
4816 if (!itb) return EINA_FALSE;
4821 itb = _item_block_new(sd, EINA_TRUE);
4822 if (!itb) return EINA_FALSE;
4824 itb->items = eina_list_prepend(itb->items, it);
4825 _item_position_update(itb->items, 1);
4831 itb = (Item_Block *)(sd->blocks->last);
4832 if (itb->count >= sd->max_items_per_block)
4834 itb = _item_block_new(sd, EINA_FALSE);
4835 if (!itb) return EINA_FALSE;
4840 itb = _item_block_new(sd, EINA_FALSE);
4841 if (!itb) return EINA_FALSE;
4843 itb->items = eina_list_append(itb->items, it);
4844 it->position = eina_list_count(itb->items);
4853 if ((!GL_IT(it)->wsd->sorting) && (GL_IT(it)->rel->item->queued))
4855 /* NOTE: for a strange reason eina_list and eina_inlist
4856 don't have the same property on sorted insertion
4857 order, so the queue is not always ordered like the
4858 item list. This lead to issue where we depend on an
4859 item that is not yet created. As a quick work around,
4860 we reschedule the calc of the item and stop reordering
4861 the list to prevent any nasty issue to show up here.
4863 sd->queue = eina_list_append(sd->queue, it);
4864 sd->requeued = EINA_TRUE;
4865 GL_IT(it)->queued = EINA_TRUE;
4870 itb = GL_IT(it)->rel->item->block;
4871 if (!itb) goto newblock;
4872 tmp = eina_list_data_find_list(itb->items, GL_IT(it)->rel);
4873 if (GL_IT(it)->before)
4875 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4876 _item_position_update
4877 (eina_list_prev(tmp), GL_IT(it)->rel->position);
4881 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4882 _item_position_update
4883 (eina_list_next(tmp), GL_IT(it)->rel->position + 1);
4888 itb->calc_done = EINA_FALSE;
4889 sd->calc_done = EINA_FALSE;
4890 GL_IT(it)->block = itb;
4891 _changed(itb->sd->pan_obj);
4893 if (itb->count > itb->sd->max_items_per_block)
4898 Eina_Bool done = EINA_FALSE;
4900 newc = itb->count / 2;
4902 if (EINA_INLIST_GET(itb)->prev)
4904 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4906 if (itbp->count + newc < sd->max_items_per_block / 2)
4908 /* moving items to previous block */
4909 while ((itb->count > newc) && (itb->items))
4911 it2 = eina_list_data_get(itb->items);
4912 itb->items = eina_list_remove_list
4913 (itb->items, itb->items);
4916 itbp->items = eina_list_append(itbp->items, it2);
4917 it2->item->block = itbp;
4925 if (!done && EINA_INLIST_GET(itb)->next)
4927 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4929 if (itbn->count + newc < sd->max_items_per_block / 2)
4931 /* moving items to next block */
4932 while ((itb->count > newc) && (itb->items))
4936 l = eina_list_last(itb->items);
4937 it2 = eina_list_data_get(l);
4938 itb->items = eina_list_remove_list(itb->items, l);
4941 itbn->items = eina_list_prepend(itbn->items, it2);
4942 it2->item->block = itbn;
4952 /* moving items to new block */
4953 itb2 = calloc(1, sizeof(Item_Block));
4954 if (!itb2) return EINA_FALSE;
4957 eina_inlist_append_relative(sd->blocks, EINA_INLIST_GET(itb2),
4958 EINA_INLIST_GET(itb));
4959 itb2->calc_done = EINA_FALSE;
4960 while ((itb->count > newc) && (itb->items))
4964 l = eina_list_last(itb->items);
4966 itb->items = eina_list_remove_list(itb->items, l);
4969 itb2->items = eina_list_prepend(itb2->items, it2);
4970 it2->item->block = itb2;
4980 _item_min_calc(Elm_Gen_Item *it)
4982 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4983 Evas_Coord mw = 0, mh = 0;
4986 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
4987 (NULL, NULL, &vw, NULL));
4989 if ((it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) &&
4990 (sd->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
4992 mw = sd->finger_minw;
4993 mh = sd->finger_minh;
4996 if ((sd->mode == ELM_LIST_COMPRESS) && vw && mw < vw)
4999 //FIXME: Some widget such as entry, label need to have fixed width size before
5000 // min calculation to get proper height size by multiline.
5001 if (sd->realization_mode || GL_IT(it)->resized)
5002 evas_object_resize(VIEW(it), mw, mh);
5004 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
5006 if ((sd->mode != ELM_LIST_LIMIT) && vw && mw < vw)
5009 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5010 if (sd->homogeneous || it->itc->homogeneous)
5012 Size_Cache *size, *tmp;
5013 tmp = eina_hash_find(sd->size_caches, it->itc->item_style);
5015 eina_hash_del_by_key(sd->size_caches, it->itc->item_style);
5017 size = ELM_NEW(Size_Cache);
5020 eina_hash_add(sd->size_caches, it->itc->item_style, size);
5023 GL_IT(it)->w = GL_IT(it)->minw = mw;
5024 GL_IT(it)->h = GL_IT(it)->minh = mh;
5026 // FIXME: This is workaround for entry size issue.
5027 if (sd->realization_mode || GL_IT(it)->resized)
5029 GL_IT(it)->resized = EINA_FALSE;
5030 if (it->deco_all_view)
5031 evas_object_resize(it->deco_all_view, GL_IT(it)->w, GL_IT(it)->h);
5032 else if (GL_IT(it)->deco_it_view)
5033 evas_object_resize(GL_IT(it)->deco_it_view, GL_IT(it)->w, GL_IT(it)->h);
5035 evas_object_resize(VIEW(it), GL_IT(it)->w, GL_IT(it)->h);
5041 _item_calc(Elm_Gen_Item *it)
5043 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5044 Size_Cache *size = NULL;
5045 Evas_Coord p_minw, p_minh;
5047 if (GL_IT(it)->calc_done) return;
5049 p_minw = GL_IT(it)->minw;
5050 p_minh = GL_IT(it)->minh;
5052 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5053 if (sd->homogeneous || it->itc->homogeneous)
5054 size = eina_hash_find(sd->size_caches, it->itc->item_style);
5057 GL_IT(it)->w = GL_IT(it)->minw = size->minw;
5058 GL_IT(it)->h = GL_IT(it)->minh = size->minh;
5064 if (sd->realization_mode)
5066 _item_realize(it, EINA_FALSE);
5071 _item_realize(it, EINA_TRUE);
5073 _item_unrealize(it, EINA_TRUE);
5080 GL_IT(it)->calc_done = EINA_TRUE;
5081 if ((p_minw != GL_IT(it)->minw) || (p_minh != GL_IT(it)->minh))
5083 GL_IT(it)->block->calc_done = EINA_FALSE;
5084 sd->calc_done = EINA_FALSE;
5089 _item_process(Elm_Genlist_Data *sd,
5092 if (!_item_block_add(sd, it)) return EINA_FALSE;
5094 GL_IT(it)->calc_done = EINA_FALSE;
5101 _dummy_job(void *data)
5103 Elm_Genlist_Data *sd = data;
5104 sd->dummy_job = NULL;
5109 _queue_idle_enter(void *data)
5111 Elm_Genlist_Data *sd = data;
5116 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
5117 (NULL, NULL, &vw, NULL));
5118 if (!sd->queue || (vw <= 1))
5122 ecore_job_del(sd->dummy_job);
5123 sd->dummy_job = NULL;
5125 sd->queue_idle_enterer = NULL;
5126 return ECORE_CALLBACK_CANCEL;
5129 ft = ecore_animator_frametime_get()/2;
5130 t0 = ecore_time_get();
5131 for (n = 0; (sd->queue) && (n < ITEM_QUEUE_MAX); n++)
5136 it = eina_list_data_get(sd->queue);
5137 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
5138 GL_IT(it)->queued = EINA_FALSE;
5139 GL_IT(it)->resized = EINA_FALSE;
5140 if (!_item_process(sd, it)) continue;
5141 t = ecore_time_get();
5142 /* same as eina_inlist_count > 1 */
5143 if (sd->blocks && sd->blocks->next)
5145 if ((t - t0) > ft) break;
5149 _changed(sd->pan_obj);
5154 ecore_job_del(sd->dummy_job);
5155 sd->dummy_job = NULL;
5157 sd->queue_idle_enterer = NULL;
5158 return ECORE_CALLBACK_CANCEL;
5161 // Do not use smart_changed
5162 // Instead make any events (job, idler, etc.) to call idle enterer
5163 if (sd->dummy_job) ecore_job_del(sd->dummy_job);
5164 sd->dummy_job = ecore_job_add(_dummy_job, sd);
5166 return ECORE_CALLBACK_RENEW;
5170 _item_queue(Elm_Gen_Item *it,
5171 Eina_Compare_Cb cb EINA_UNUSED)
5173 if (GL_IT(it)->queued) return;
5175 GL_IT(it)->queued = EINA_TRUE;
5176 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5178 // FIXME: Below code occurs item unsorted result.
5179 // genlist already calculate items position by sd->items
5180 // so no need to requeue items by sorting insert.
5181 // if (cb && !sd->requeued)
5182 // sd->queue = eina_list_sorted_insert(sd->queue, cb, it);
5184 sd->queue = eina_list_append(sd->queue, it);
5186 if (sd->queue_idle_enterer)
5187 ecore_idle_enterer_del(sd->queue_idle_enterer);
5188 sd->queue_idle_enterer = ecore_idle_enterer_add(_queue_idle_enter, sd);
5192 _item_queue_direct(Elm_Gen_Item *it,
5195 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5197 // Processing items within viewport if items already exist.
5198 // This can prevent flickering issue when content size is changed.
5199 // This can fix the flickering issue when expanded item have subitems whose total height > vh
5200 if (!sd->queue && (sd->viewport_w > 1) &&
5201 ((sd->processed_sizes <= sd->viewport_h) || (GL_IT(it)->expanded_depth > 0)))
5203 #ifdef GENLIST_FX_SUPPORT
5204 if (sd->fx_mode)// && !it->item->is_prepend) // For support preppended items - hs619.choi@samsung.com
5206 sd->add_fx.items = eina_list_append(sd->add_fx.items, it);
5207 if (!sd->add_fx.anim)
5209 sd->add_fx.cnt = ANIM_CNT_MAX;
5210 sd->add_fx.anim = ecore_animator_add(_add_fx_anim, sd);
5214 _item_process(sd, it);
5215 sd->processed_sizes += GL_IT(it)->minh;
5217 _changed(sd->pan_obj);
5220 _item_queue(it, cb);
5223 /* If the application wants to know the relative item, use
5224 * elm_genlist_item_prev_get(it)*/
5226 _item_move_after(Elm_Gen_Item *it,
5227 Elm_Gen_Item *after)
5231 if (it == after) return;
5233 GL_IT(it)->wsd->items =
5234 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
5235 if (GL_IT(it)->block) _item_block_del(it);
5237 GL_IT(it)->wsd->items = eina_inlist_append_relative
5238 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
5241 GL_IT(it)->rel->item->rel_revs =
5242 eina_list_remove(GL_IT(it)->rel->item->rel_revs, it);
5243 GL_IT(it)->rel = after;
5244 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
5245 GL_IT(it)->before = EINA_FALSE;
5246 if (after->item->group_item) GL_IT(it)->group_item = after->item->group_item;
5248 if (GL_IT(it)->queued)
5250 GL_IT(it)->wsd->queue = eina_list_remove(GL_IT(it)->wsd->queue, it);
5251 GL_IT(it)->queued = EINA_FALSE;
5253 _item_queue_direct(it, NULL);
5255 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, EO_OBJ(it));
5258 /* If the application wants to know the relative item, use
5259 * elm_genlist_item_next_get(it)*/
5261 _item_move_before(Elm_Gen_Item *it,
5262 Elm_Gen_Item *before)
5265 if (!before) return;
5266 if (it == before) return;
5268 GL_IT(it)->wsd->items =
5269 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
5270 if (GL_IT(it)->block) _item_block_del(it);
5271 GL_IT(it)->wsd->items = eina_inlist_prepend_relative
5272 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
5275 GL_IT(it)->rel->item->rel_revs =
5276 eina_list_remove(GL_IT(it)->rel->item->rel_revs, it);
5277 GL_IT(it)->rel = before;
5278 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
5279 GL_IT(it)->before = EINA_TRUE;
5280 if (before->item->group_item)
5281 GL_IT(it)->group_item = before->item->group_item;
5282 _item_queue_direct(it, NULL);
5284 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, EO_OBJ(it));
5288 _item_mouse_up_cb(void *data,
5290 Evas_Object *obj EINA_UNUSED,
5293 Evas_Event_Mouse_Up *ev = event_info;
5294 Elm_Gen_Item *it = data;
5295 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5297 ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd);
5299 if (!it->down) return;
5300 it->down = EINA_FALSE;
5302 if (ev->button != 1) return;
5306 it->dragging = EINA_FALSE;
5307 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, EO_OBJ(it));
5309 // When the event is cancelled, need to initialize mouse flags and timers.
5310 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = EINA_TRUE;
5314 if (evas_event_down_count_get(evas) != 0)
5316 if (!GL_IT(it)->highlight_timer) _item_unhighlight(it, EINA_TRUE);
5321 ecore_timer_del(it->long_timer);
5322 it->long_timer = NULL;
5324 if (GL_IT(it)->highlight_timer)
5326 ecore_timer_del(GL_IT(it)->highlight_timer);
5327 GL_IT(it)->highlight_timer = NULL;
5328 // Because naviframe can drop the all evevents.
5329 // highlight it before select timer is called.
5330 if (evas_event_down_count_get(evas) == 0) _item_highlight(it);
5333 if (!sd->reorder.it && (evas_event_down_count_get(evas) == 0))
5335 // FIXME: if highlight mode is not used, mouse move cannot disable
5337 if ((sd->was_selected == it->selected) && (!sd->on_hold))
5339 if (wd->scroll_item_align_enable)
5341 const char *align = edje_object_data_get(VIEW(it), "align");
5342 if (!align || strcmp(align, "off"))
5344 if (it != sd->aligned_item)
5346 elm_genlist_item_bring_in(EO_OBJ(it), ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
5350 if (((sd->highlight && it->highlighted) || !sd->highlight) &&
5351 ((!wd->scroll_item_align_enable) || (it == sd->aligned_item)))
5352 GL_IT(it)->highlight_timer =
5353 ecore_timer_add(ITEM_SELECT_TIMER, _select_timer, it);
5354 else if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
5355 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
5358 Evas_Object *content;
5359 if (sd->focused_item != it)
5360 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
5362 sd->focused_content = NULL;
5363 EINA_LIST_FOREACH(it->content_objs, l, content)
5365 if (elm_widget_focused_object_get(content))
5366 sd->focused_content = content;
5371 else if (sd->reorder.it == it)
5373 if (TIZEN_PROFILE_WEARABLE)
5375 Elm_Gen_Item *it2, *it_max = NULL, *it_min = NULL;
5376 Evas_Coord r_y_scrl, it_y_max = -99999999, it_y_min = 99999999;
5378 if (!it->selected) _item_unhighlight(it, EINA_TRUE);
5379 r_y_scrl = GL_IT(it)->scrl_y;
5380 EINA_LIST_FREE(sd->reorder.move_items, it2)
5382 if (sd->reorder.it->parent != it2->parent)
5384 it2->item->reorder_offset = 0;
5387 Evas_Coord it_y = it2->item->scrl_y +
5388 it2->item->reorder_offset + (it2->item->h / 2) +
5389 it2->item->block->y;
5391 if ((it_y < r_y_scrl) &&
5397 else if ((it_y > r_y_scrl) &&
5403 it2->item->reorder_offset = 0;
5407 _item_move_after(it, it_max);
5408 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5412 _item_move_before(it, it_min);
5413 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5419 Elm_Gen_Item *moved_it = NULL;
5420 Elm_Gen_Item *ptr_it = sd->top_drawn_item;
5421 Elm_Gen_Item *last_it = NULL;
5422 Eina_Bool after = EINA_TRUE;
5424 if (!it->selected) _item_unhighlight(it, EINA_FALSE);
5430 if (ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y, GL_IT(it)->w, GL_IT(it)->h,
5431 GL_IT(ptr_it)->scrl_x, GL_IT(ptr_it)->scrl_y, GL_IT(ptr_it)->w, GL_IT(ptr_it)->h))
5433 if (GL_IT(it)->scrl_y < GL_IT(ptr_it)->scrl_y)
5440 if ((GL_IT(it)->scrl_y + GL_IT(it)->h) > (GL_IT(ptr_it)->scrl_y + GL_IT(ptr_it)->h))
5442 if ((GL_IT(it)->scrl_y + GL_IT(it)->h) == GL_IT(ptr_it)->scrl_y)
5450 ptr_it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(ptr_it)->next);
5455 if (GL_IT(it)->scrl_y > GL_IT(last_it)->scrl_y + GL_IT(last_it)->h)
5459 moved_it = sd->top_drawn_item;
5464 EINA_LIST_FREE(sd->reorder.move_items, ptr_it)
5466 ptr_it->item->reorder_offset = 0;
5471 _item_move_after(it, moved_it);
5472 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5476 _item_move_before(it, moved_it);
5477 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5480 sd->reorder.it = NULL;
5481 sd->reorder.dir = 0;
5482 if (sd->reorder.anim)
5484 ecore_animator_del(sd->reorder.anim);
5485 sd->reorder.anim = NULL;
5488 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5489 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
5490 (sd->h_bounce, sd->v_bounce));
5492 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_DISABLED, "elm");
5493 _changed(sd->pan_obj);
5495 sd->on_hold = EINA_FALSE; /* for checking need to start select timer */
5496 evas_object_smart_callback_call(WIDGET(it), SIG_RELEASED, EO_OBJ(it));
5500 _scroll_hold_timer_cb(void *data)
5502 Elm_Genlist_Data *sd = data;
5503 sd->scr_hold_timer = NULL;
5505 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5507 return ECORE_CALLBACK_CANCEL;
5511 _decorate_item_finished_signal_cb(void *data,
5513 const char *emission EINA_UNUSED,
5514 const char *source EINA_UNUSED)
5516 Elm_Gen_Item *it = data;
5518 if (!data || !obj) return;
5519 if ((!it->realized)) return;
5521 _decorate_item_unrealize(it);
5525 _item_update(Elm_Gen_Item *it)
5528 if (!it->realized) return;
5530 _view_clear(VIEW(it), &(it->content_objs));
5531 EINA_LIST_FREE(GL_IT(it)->flip_content_objs, c)
5533 _view_clear(GL_IT(it)->deco_it_view, &(GL_IT(it)->deco_it_contents));
5534 _view_clear(it->deco_all_view, &(GL_IT(it)->deco_all_contents));
5536 _view_inflate(VIEW(it), it, &(it->content_objs));
5539 _item_content_realize(it, VIEW(it), &(GL_IT(it)->flip_content_objs),
5541 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
5543 if (GL_IT(it)->wsd->decorate_all_mode)
5544 _view_inflate(it->deco_all_view, it, &(GL_IT(it)->deco_all_contents));
5545 else if (GL_IT(it)->deco_it_view)
5546 _view_inflate(GL_IT(it)->deco_it_view, it, &(GL_IT(it)->deco_it_contents));
5548 if (!TIZEN_PROFILE_WEARABLE)
5549 _banded_item_bg_add(it, VIEW(it));
5552 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
5554 if (GL_IT(it)->wsd->aligned_item == it)
5555 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
5557 edje_object_message_signal_process(VIEW(it));
5561 _item_block_calc(Item_Block *itb, Evas_Coord vw EINA_UNUSED, Evas_Coord vh)
5565 Evas_Coord minw = 9999999, minh = 0;
5566 int sum_item_height = 0;
5567 ELM_WIDGET_DATA_GET_OR_RETURN(itb->sd->obj, wsd);
5569 if (itb->calc_done) return;
5571 EINA_LIST_FOREACH(itb->items, l, it)
5573 if (it->want_hidden) continue;
5574 if (GL_IT(it)->updateme)
5580 GL_IT(it)->calc_done = EINA_FALSE;
5581 GL_IT(it)->updateme = EINA_FALSE;
5583 if (!GL_IT(it)->queued) _item_calc(it);
5585 if (wsd->scroll_item_align_enable)
5587 int vcenter = vh / 2;
5588 int icenter = GL_IT(it)->h / 2;
5589 if ((itb->y + sum_item_height < vcenter && itb->y + sum_item_height + GL_IT(it)->h > vcenter) &&
5590 (sum_item_height + icenter < vcenter - 1 || sum_item_height + icenter > vcenter + 1))
5592 int first_item_height = sum_item_height = vcenter - icenter;
5594 Elm_Object_Item *eo_prev = elm_genlist_item_prev_get(EO_OBJ(it));
5595 Elm_Gen_Item *prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
5598 minh = sum_item_height;
5601 if (eo_prev == elm_genlist_first_item_get(wsd->obj))
5603 GL_IT(prev)->h = GL_IT(prev)->minh = first_item_height;
5606 first_item_height -= GL_IT(prev)->h;
5607 prev->y = first_item_height;
5608 eo_prev = elm_genlist_item_prev_get(eo_prev);
5609 prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
5612 sum_item_height += GL_IT(it)->h;
5617 if (minw > GL_IT(it)->minw) minw = GL_IT(it)->minw;
5618 minh += GL_IT(it)->minh;
5619 if (GL_IT(it)->is_prepend)
5621 itb->sd->comp_y += GL_IT(it)->minh;
5622 GL_IT(it)->is_prepend = EINA_FALSE;
5627 itb->calc_done = EINA_TRUE;
5628 itb->position_update = EINA_FALSE;
5632 _scroll_animate_start_cb(Evas_Object *obj,
5633 void *data EINA_UNUSED)
5635 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5636 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
5640 _scroll_animate_stop_cb(Evas_Object *obj,
5641 void *data EINA_UNUSED)
5643 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5644 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
5646 //TIZEN_ONLY: Let the screen-reader know when scroll animation ends
5647 if (_elm_atspi_enabled())
5649 elm_interface_atspi_accessible_visible_data_changed_signal_emit(obj);
5655 _scroll_drag_start_cb(Evas_Object *obj,
5656 void *data EINA_UNUSED)
5658 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5659 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
5663 _scroll_timeout_cb(void *data)
5665 Elm_Genlist_Data *sd = data;
5667 sd->scr_timer = NULL;
5668 if (sd->queue && !sd->queue_idle_enterer)
5670 sd->queue_idle_enterer = ecore_idle_enterer_add(_queue_idle_enter, sd);
5671 if (sd->dummy_job) ecore_job_del(sd->dummy_job);
5672 sd->dummy_job = ecore_job_add(_dummy_job, sd);
5674 return ECORE_CALLBACK_CANCEL;
5678 _scroll_cb(Evas_Object *obj,
5679 void *data EINA_UNUSED)
5681 ELM_GENLIST_DATA_GET(obj, sd);
5683 if (sd->queue_idle_enterer)
5685 ecore_idle_enterer_del(sd->queue_idle_enterer);
5686 sd->queue_idle_enterer = NULL;
5689 ecore_job_del(sd->dummy_job);
5690 sd->dummy_job = NULL;
5693 if (sd->scr_timer) ecore_timer_del(sd->scr_timer);
5694 sd->scr_timer = ecore_timer_add(0.25, _scroll_timeout_cb, sd);
5696 evas_object_smart_callback_call(obj, SIG_SCROLL, NULL);
5700 _scroll_drag_stop_cb(Evas_Object *obj,
5701 void *data EINA_UNUSED)
5703 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_STOP, NULL);
5704 //TIZEN_ONLY: Let the screen-reader know when drag ends
5705 if (_elm_atspi_enabled())
5707 elm_interface_atspi_accessible_visible_data_changed_signal_emit(obj);
5713 _edge_left_cb(Evas_Object *obj,
5714 void *data EINA_UNUSED)
5716 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
5720 _edge_right_cb(Evas_Object *obj,
5721 void *data EINA_UNUSED)
5723 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
5727 _edge_top_cb(Evas_Object *obj,
5728 void *data EINA_UNUSED)
5730 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
5734 _edge_bottom_cb(Evas_Object *obj,
5735 void *data EINA_UNUSED)
5737 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
5741 _vbar_drag_cb(Evas_Object *obj,
5742 void *data EINA_UNUSED)
5744 evas_object_smart_callback_call(obj, SIG_VBAR_DRAG, NULL);
5748 _vbar_press_cb(Evas_Object *obj,
5749 void *data EINA_UNUSED)
5751 evas_object_smart_callback_call(obj, SIG_VBAR_PRESS, NULL);
5755 _vbar_unpress_cb(Evas_Object *obj,
5756 void *data EINA_UNUSED)
5758 evas_object_smart_callback_call(obj, SIG_VBAR_UNPRESS, NULL);
5762 _hbar_drag_cb(Evas_Object *obj,
5763 void *data EINA_UNUSED)
5765 evas_object_smart_callback_call(obj, SIG_HBAR_DRAG, NULL);
5769 _hbar_press_cb(Evas_Object *obj,
5770 void *data EINA_UNUSED)
5772 evas_object_smart_callback_call(obj, SIG_HBAR_PRESS, NULL);
5776 _hbar_unpress_cb(Evas_Object *obj,
5777 void *data EINA_UNUSED)
5779 evas_object_smart_callback_call(obj, SIG_HBAR_UNPRESS, NULL);
5783 _decorate_item_realize(Elm_Gen_Item *it)
5786 if (GL_IT(it)->deco_it_view || !it->itc->decorate_item_style) return;
5788 // Before adding & swallowing, delete it from smart member
5789 evas_object_smart_member_del(VIEW(it));
5791 GL_IT(it)->deco_it_view = _view_create(it, it->itc->decorate_item_style);
5792 edje_object_part_swallow
5793 (GL_IT(it)->deco_it_view,
5794 edje_object_data_get(GL_IT(it)->deco_it_view, "mode_part"), VIEW(it));
5795 _view_inflate(GL_IT(it)->deco_it_view, it, &(GL_IT(it)->deco_it_contents));
5797 snprintf(buf, sizeof(buf), "elm,state,%s,active",
5798 GL_IT(it)->wsd->decorate_it_type);
5799 edje_object_signal_emit(GL_IT(it)->deco_it_view, buf, "elm");
5800 edje_object_signal_emit(VIEW(it), buf, "elm");
5802 _item_mouse_callbacks_add(it, GL_IT(it)->deco_it_view);
5804 _item_mouse_callbacks_del(it, VIEW(it));
5808 // FIXME: difference from upstream
5810 _mouse_down_scroller(void *data,
5811 Evas *evas EINA_UNUSED,
5812 Evas_Object *obj EINA_UNUSED,
5813 void *event_info EINA_UNUSED)
5815 Widget_Data *wd = elm_widget_data_get(data);
5818 wd->drag_started = EINA_FALSE;
5822 _mouse_up_scroller(void *data,
5823 Evas *evas EINA_UNUSED,
5824 Evas_Object *obj EINA_UNUSED,
5825 void *event_info EINA_UNUSED)
5827 Widget_Data *wd = elm_widget_data_get(data);
5830 wd->drag_started = EINA_FALSE;
5834 _mouse_move_scroller(void *data,
5835 Evas *evas EINA_UNUSED,
5836 Evas_Object *obj EINA_UNUSED,
5839 Widget_Data *wd = elm_widget_data_get(data);
5840 Evas_Event_Mouse_Move *ev = event_info;
5841 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
5844 if (wd->drag_started) return;
5846 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
5847 dx = ev->cur.canvas.x - ev->prev.canvas.x;
5848 dy = ev->cur.canvas.y - ev->prev.canvas.y;
5851 if (adx < 0) adx = -dx;
5852 if (ady < 0) ady = -dy;
5853 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
5857 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
5858 wd->drag_started = EINA_TRUE;
5862 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
5863 wd->drag_started = EINA_TRUE;
5870 _size_cache_free(void *data)
5872 if (data) free(data);
5875 static Evas_Event_Flags
5876 _pinch_zoom_start_cb(void *data, void *event_info)
5878 Elm_Genlist_Data *sd = data;
5879 Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
5880 Elm_Object_Item *eo_it;
5882 eo_it = elm_genlist_at_xy_item_get(sd->obj, p->x, p->y, NULL);
5883 sd->g_item = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
5884 return EVAS_EVENT_FLAG_NONE;
5887 static Evas_Event_Flags
5888 _pinch_zoom_cb(void *data, void *event_info)
5890 Elm_Genlist_Data *sd = data;
5891 Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
5893 if (p->zoom > 1.0 + PINCH_ZOOM_TOLERANCE)
5894 sd->g_type = SIG_MULTI_PINCH_OUT;
5895 else if (p->zoom < 1.0 - PINCH_ZOOM_TOLERANCE)
5896 sd->g_type = SIG_MULTI_PINCH_IN;
5898 return EVAS_EVENT_FLAG_NONE;
5901 static Evas_Event_Flags
5902 _gesture_n_lines_start_cb(void *data , void *event_info)
5904 Elm_Genlist_Data *sd = data;
5905 Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5907 Elm_Object_Item *eo_it;
5909 x = (p->momentum.x1 + p->momentum.x2) / 2;
5910 y = (p->momentum.y1 + p->momentum.y2) / 2;
5912 eo_it = elm_genlist_at_xy_item_get(sd->obj, x, y, NULL);
5913 sd->g_item = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
5914 return EVAS_EVENT_FLAG_NONE;
5917 static Evas_Event_Flags
5918 _gesture_n_lines_cb(void *data , void *event_info)
5920 Elm_Genlist_Data *sd = data;
5921 Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5923 if (p->momentum.n < 2)
5924 return EVAS_EVENT_FLAG_NONE;
5926 Evas_Coord minw = 0, minh = 0;
5927 Evas_Coord x, y, off_x, off_y;
5928 Evas_Coord cur_x, cur_y, prev_x, prev_y;
5929 Elm_Gen_Item *down_it;
5930 Elm_Object_Item *eo_down_it;
5932 minw = sd->finger_minw;
5933 minh = sd->finger_minh;
5935 prev_x = prev_y = 0;
5937 cur_x = p->momentum.x1;
5938 cur_y = p->momentum.y1;
5940 eo_down_it = elm_genlist_at_xy_item_get(sd->obj, cur_x, cur_y, NULL);
5941 down_it = eo_data_scope_get(eo_down_it, ELM_GENLIST_ITEM_CLASS);
5944 evas_object_geometry_get(VIEW(down_it), &x, &y, NULL, NULL);
5945 prev_x = down_it->dx + x;
5946 prev_y = down_it->dy + y;
5948 off_x = abs(cur_x - prev_x);
5949 off_y = abs(cur_y - prev_y);
5951 if ((off_x > minw) || (off_y > minh))
5956 sd->g_type = SIG_MULTI_SWIPE_RIGHT;
5958 sd->g_type = SIG_MULTI_SWIPE_LEFT;
5963 sd->g_type = SIG_MULTI_SWIPE_DOWN;
5965 sd->g_type = SIG_MULTI_SWIPE_UP;
5969 return EVAS_EVENT_FLAG_NONE;
5972 static Evas_Event_Flags
5973 _gesture_n_flicks_cb(void *data , void *event_info)
5975 Elm_Genlist_Data *sd = data;
5976 Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5978 if (p->momentum.n == 1)
5979 sd->g_type = SIG_SWIPE;
5981 return EVAS_EVENT_FLAG_NONE;
5985 _elm_genlist_evas_object_smart_del(Eo *obj, Elm_Genlist_Data *sd)
5987 sd->no_cache = EINA_TRUE;
5988 elm_genlist_clear(obj);
5989 evas_event_callback_del_full(evas_object_evas_get(obj),
5990 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
5991 _evas_viewport_resize_cb, sd);
5992 if (sd->size_caches) eina_hash_free(sd->size_caches);
5993 if (sd->decorate_it_type) eina_stringshare_del(sd->decorate_it_type);
5994 if (sd->clipee) evas_object_del(sd->clipee);
5996 evas_object_del(sd->pan_obj);
5997 eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
6001 _elm_genlist_evas_object_smart_move(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y)
6003 Evas_Coord ox, oy, bg_x, bg_y;
6005 if (!TIZEN_PROFILE_WEARABLE)
6007 evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
6008 evas_object_geometry_get(sd->banded_bg_rect, &bg_x, &bg_y, NULL, NULL);
6011 eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
6012 evas_object_move(sd->hit_rect, x, y);
6014 if (!TIZEN_PROFILE_WEARABLE)
6015 evas_object_move(sd->banded_bg_rect, (bg_x + x - ox), (bg_y + y - oy));
6019 _elm_genlist_evas_object_smart_resize(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord w, Evas_Coord h)
6021 eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
6023 evas_object_resize(sd->hit_rect, w, h);
6027 _elm_genlist_evas_object_smart_member_add(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *member)
6029 eo_do_super(obj, MY_CLASS, evas_obj_smart_member_add(member));
6032 evas_object_raise(sd->hit_rect);
6037 _elm_genlist_elm_widget_access(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool acs)
6040 Elm_Object_Item *eo_it;
6042 l = elm_genlist_realized_items_get(obj);
6044 EINA_LIST_FREE(l, eo_it)
6046 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6047 _item_unrealize(it, EINA_FALSE);
6050 sd->is_access = acs;
6052 _changed(sd->pan_obj);
6053 evas_object_smart_callback_call(obj, SIG_ACCESS_CHANGED, NULL);
6057 _evas_viewport_resize_cb(void *d, Evas *e EINA_UNUSED, void *ei EINA_UNUSED)
6059 Elm_Genlist_Data *priv = d;
6060 _changed(priv->pan_obj);
6064 _elm_genlist_evas_object_smart_add(Eo *obj, Elm_Genlist_Data *priv)
6066 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
6067 Evas_Coord minw, minh;
6068 Elm_Genlist_Pan_Data *pan_data;
6070 eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
6071 elm_widget_sub_object_parent_add(obj);
6073 priv->finger_minw = 0;
6074 priv->finger_minh = 0;
6075 elm_coords_finger_size_adjust(1, &priv->finger_minw, 1, &priv->finger_minh);
6077 priv->size_caches = eina_hash_string_small_new(_size_cache_free);
6078 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
6079 evas_object_smart_member_add(priv->hit_rect, obj);
6080 elm_widget_sub_object_add(obj, priv->hit_rect);
6082 /* common scroller hit rectangle setup */
6083 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
6084 evas_object_show(priv->hit_rect);
6085 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
6087 elm_widget_can_focus_set(obj, EINA_TRUE);
6088 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
6090 elm_layout_theme_set(obj, "genlist", "base", elm_widget_style_get(obj));
6092 if (!TIZEN_PROFILE_WEARABLE)
6093 _banded_bg_state_check(obj, priv);
6095 /* interface's add() routine issued AFTER the object's smart_add() */
6096 eo_do(obj, elm_interface_scrollable_objects_set(wd->resize_obj, priv->hit_rect));
6098 eo_do(obj, elm_interface_scrollable_bounce_allow_set
6099 (EINA_FALSE, _elm_config->thumbscroll_bounce_enable));
6100 priv->v_bounce = _elm_config->thumbscroll_bounce_enable;
6103 elm_interface_scrollable_animate_start_cb_set(_scroll_animate_start_cb),
6104 elm_interface_scrollable_animate_stop_cb_set(_scroll_animate_stop_cb),
6105 elm_interface_scrollable_scroll_cb_set(_scroll_cb),
6106 elm_interface_scrollable_drag_start_cb_set(_scroll_drag_start_cb),
6107 elm_interface_scrollable_drag_stop_cb_set(_scroll_drag_stop_cb),
6108 elm_interface_scrollable_edge_left_cb_set(_edge_left_cb),
6109 elm_interface_scrollable_edge_right_cb_set(_edge_right_cb),
6110 elm_interface_scrollable_edge_top_cb_set(_edge_top_cb),
6111 elm_interface_scrollable_edge_bottom_cb_set(_edge_bottom_cb),
6112 elm_interface_scrollable_vbar_drag_cb_set(_vbar_drag_cb),
6113 elm_interface_scrollable_vbar_press_cb_set(_vbar_press_cb),
6114 elm_interface_scrollable_vbar_unpress_cb_set(_vbar_unpress_cb),
6115 elm_interface_scrollable_hbar_drag_cb_set(_hbar_drag_cb),
6116 elm_interface_scrollable_hbar_press_cb_set(_hbar_press_cb),
6117 elm_interface_scrollable_hbar_unpress_cb_set(_hbar_unpress_cb));
6119 eo_do(obj, elm_interface_scrollable_content_min_limit_cb_set(_elm_genlist_content_min_limit_cb));
6121 priv->mode = ELM_LIST_SCROLL;
6122 priv->max_items_per_block = MAX_ITEMS_PER_BLOCK;
6123 priv->item_cache_max = priv->max_items_per_block * 2;
6124 priv->longpress_timeout = _elm_config->longpress_timeout;
6125 priv->highlight = EINA_TRUE;
6126 priv->fx_mode = EINA_FALSE;
6127 priv->on_hold = EINA_FALSE;
6130 if (!TIZEN_PROFILE_WEARABLE)
6131 priv->top_drawn_item = NULL;
6133 priv->pan_obj = eo_add(MY_PAN_CLASS, evas_object_evas_get(obj));
6134 pan_data = eo_data_scope_get(priv->pan_obj, MY_PAN_CLASS);
6135 eo_data_ref(obj, NULL);
6137 pan_data->wobj = obj;
6139 pan_data->wsd = priv;
6142 // FIXME: difference from upstream
6143 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_DOWN,
6144 _mouse_down_scroller, obj);
6145 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_UP,
6146 _mouse_up_scroller, obj);
6147 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_MOVE,
6148 _mouse_move_scroller, obj);
6151 eo_do(obj, elm_interface_scrollable_extern_pan_set(priv->pan_obj));
6153 edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
6154 evas_object_size_hint_min_set(obj, minw, minh);
6156 _item_cache_all_free(priv);
6157 _mirrored_set(obj, elm_widget_mirrored_get(obj));
6159 const char *str = edje_object_data_get(wd->resize_obj,
6161 if ((str) && (!strcmp(str, "on")))
6162 elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
6164 elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
6165 priv->select_on_focus_enabled = EINA_FALSE;
6166 elm_widget_signal_callback_add(obj, "elm,action,focus_highlight,hide", "elm", _elm_genlist_focus_highlight_hide, obj);
6167 elm_widget_signal_callback_add(obj, "elm,action,focus_highlight,show", "elm", _elm_genlist_focus_highlight_show, obj);
6168 evas_event_callback_add(evas_object_evas_get(obj),
6169 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
6170 _evas_viewport_resize_cb, priv);
6172 priv->g_layer = elm_gesture_layer_add(obj);
6173 if (!priv->g_layer) ERR("elm_gesture_layer_add() failed");
6174 elm_gesture_layer_attach(priv->g_layer, priv->hit_rect);
6175 elm_gesture_layer_cb_set
6176 (priv->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_START,
6177 _pinch_zoom_start_cb, priv);
6178 elm_gesture_layer_cb_set
6179 (priv->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE,
6180 _pinch_zoom_cb, priv);
6182 elm_gesture_layer_cb_set
6183 (priv->g_layer, ELM_GESTURE_N_LINES, ELM_GESTURE_STATE_START,
6184 _gesture_n_lines_start_cb, priv);
6185 elm_gesture_layer_cb_set
6186 (priv->g_layer, ELM_GESTURE_N_LINES, ELM_GESTURE_STATE_MOVE,
6187 _gesture_n_lines_cb, priv);
6189 elm_gesture_layer_cb_set
6190 (priv->g_layer, ELM_GESTURE_N_FLICKS, ELM_GESTURE_STATE_START,
6191 _gesture_n_lines_start_cb, priv);
6192 elm_gesture_layer_cb_set
6193 (priv->g_layer, ELM_GESTURE_N_FLICKS, ELM_GESTURE_STATE_MOVE,
6194 _gesture_n_flicks_cb, priv);
6196 elm_layout_sizing_eval(obj);
6198 // TIZEN_ONLY(20150705): Genlist item align feature
6199 wd->scroll_item_align_enable = _elm_config->scroll_item_align_enable;
6200 wd->scroll_item_valign = _elm_config->scroll_item_valign;
6202 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
6203 (NULL, NULL, &priv->viewport_w, &priv->viewport_h));
6206 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
6207 //register/unregister access objects accordingly.
6208 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6210 _elm_genlist_elm_widget_screen_reader(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool is_screen_reader)
6213 Eina_Bool done = EINA_FALSE;
6214 Evas_Object *content = NULL;
6218 EINA_INLIST_FOREACH(sd->blocks, itb)
6223 EINA_LIST_FOREACH(itb->items, l, it)
6225 if (!it->realized || it->want_hidden) continue;
6226 if (is_screen_reader)
6228 elm_interface_atspi_accessible_added(EO_OBJ(it));
6229 elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
6230 EINA_LIST_FOREACH(it->content_objs, ll, content)
6232 if (eo_isa(content, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
6234 eo_do(content, elm_interface_atspi_accessible_parent_set(EO_OBJ(it)));
6235 elm_interface_atspi_accessible_children_changed_added_signal_emit(EO_OBJ(it), content);
6238 elm_interface_atspi_accessible_name_changed_signal_emit(EO_OBJ(it));
6242 elm_interface_atspi_accessible_removed(EO_OBJ(it));
6243 elm_interface_atspi_accessible_children_changed_del_signal_emit(sd->obj, EO_OBJ(it));
6247 else if (done) break;
6250 //TIZEN_ONLY(20161213): apply screen_reader_changed callback
6251 evas_object_smart_callback_call(obj, SIG_ATSPI_SCREEN_READER_CHANGED, &is_screen_reader);
6257 EOLIAN const Elm_Atspi_Action *
6258 _elm_genlist_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd EINA_UNUSED)
6260 /* Need to be implemented
6261 static Elm_Atspi_Action atspi_actions[] = {
6262 { "move,prior", "move", "prior", _key_action_move},
6263 { "move,next", "move", "next", _key_action_move},
6264 { "move,left", "move", "left", _key_action_move},
6265 { "move,right", "move", "right", _key_action_move},
6266 { "move,up", "move", "up", _key_action_move},
6267 { "move,up,multi", "move", "up_multi", _key_action_move},
6268 { "move,down", "move", "down", _key_action_move},
6269 { "move,down,multi", "move", "down_multi", _key_action_move},
6270 { "move,first", "move", "first", _key_action_move},
6271 { "move,last", "move", "last", _key_action_move},
6272 { "select", "select", NULL, _key_action_select},
6273 { "select,multi", "select", "multi", _key_action_select},
6274 { "escape", "escape", NULL, _key_action_escape},
6275 { NULL, NULL, NULL, NULL }
6277 return &atspi_actions[0];
6279 static Elm_Atspi_Action atspi_actions[] = {{NULL, NULL, NULL, NULL}};
6280 return &atspi_actions[0];
6284 elm_genlist_add(Evas_Object *parent)
6286 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
6287 Evas_Object *obj = eo_add(MY_CLASS, parent);
6292 _elm_genlist_eo_base_constructor(Eo *obj, Elm_Genlist_Data *sd)
6294 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
6298 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
6299 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
6300 elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST));
6305 EOLIAN static Evas_Object *
6306 _elm_genlist_item_elm_widget_item_part_content_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6308 Evas_Object *ret = NULL;
6309 if (it->deco_all_view)
6310 ret = edje_object_part_swallow_get(it->deco_all_view, part);
6311 else if (it->decorate_it_set)
6312 ret = edje_object_part_swallow_get(GL_IT(it)->deco_it_view, part);
6314 ret = edje_object_part_swallow_get(VIEW(it), part);
6318 EOLIAN static const char *
6319 _elm_genlist_item_elm_widget_item_part_text_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6321 if (!it->itc->func.text_get) return NULL;
6322 const char *ret = NULL;
6323 if (it->deco_all_view)
6324 ret = edje_object_part_text_get(it->deco_all_view, part);
6325 else if (it->decorate_it_set)
6326 ret = edje_object_part_text_get(GL_IT(it)->deco_it_view, part);
6328 ret = edje_object_part_text_get(VIEW(it), part);
6333 _elm_genlist_item_elm_widget_item_disable(Eo *eo_it, Elm_Gen_Item *it)
6340 if (it == GL_IT(it)->wsd->focused_item) elm_object_item_focus_set(EO_OBJ(it), EINA_FALSE);
6341 if (GL_IT(it)->highlight_timer)
6343 ecore_timer_del(GL_IT(it)->highlight_timer);
6344 GL_IT(it)->highlight_timer = NULL;
6348 ecore_timer_del(it->long_timer);
6349 it->long_timer = NULL;
6354 if (eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get()))
6356 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
6357 if (it->deco_all_view)
6358 edje_object_signal_emit
6359 (it->deco_all_view, SIGNAL_DISABLED, "elm");
6363 edje_object_signal_emit(VIEW(it), SIGNAL_ENABLED, "elm");
6364 if (it->deco_all_view)
6365 edje_object_signal_emit
6366 (it->deco_all_view, SIGNAL_ENABLED, "elm");
6368 EINA_LIST_FOREACH(it->content_objs, l, obj)
6369 elm_widget_disabled_set(obj, eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get()));
6374 _item_free(Elm_Gen_Item *it)
6377 Elm_Object_Item *eo_it2;
6378 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
6379 sd->processed_sizes -= GL_IT(it)->minh;
6380 if (sd->processed_sizes < 0) sd->processed_sizes = 0;
6382 eo_do(EO_OBJ(it), elm_wdg_item_pre_notify_del());
6383 if (it->tooltip.del_cb)
6384 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6386 #ifdef GENLIST_FX_SUPPORT
6387 sd->del_fx.items = eina_list_remove(sd->del_fx.items, it);
6388 sd->del_fx.pending_items = eina_list_remove(sd->del_fx.pending_items, it);
6389 sd->add_fx.items = eina_list_remove(sd->add_fx.items, it);
6393 GL_IT(it)->rel->item->rel_revs =
6394 eina_list_remove(GL_IT(it)->rel->item->rel_revs, it);
6395 if (GL_IT(it)->rel_revs)
6398 EINA_LIST_FREE(GL_IT(it)->rel_revs, tmp)
6400 if (tmp->item->queued && !(tmp->base)->on_deletion)
6402 GL_IT(tmp)->queued = EINA_FALSE;
6403 GL_IT(tmp)->resized = EINA_FALSE;
6404 sd->queue = eina_list_remove(sd->queue, tmp);
6405 _item_process(sd, tmp);
6407 tmp->item->rel = NULL;
6410 EINA_LIST_FOREACH_SAFE(it->item->items, l, ll, eo_it2)
6412 //elm_widget_item_del(it2);
6413 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6416 sd->reorder.move_items = eina_list_remove(sd->reorder.move_items, it);
6418 if (GL_IT(it)->block) _item_block_del(it);
6420 it->parent->item->items =
6421 eina_list_remove(it->parent->item->items, EO_OBJ(it));
6422 if (GL_IT(it)->queued)
6424 GL_IT(it)->queued = EINA_FALSE;
6425 sd->queue = eina_list_remove(sd->queue, it);
6427 if (sd->filter_queue && !it->filtered)
6429 l = eina_list_data_find_list(sd->filter_queue, it);
6430 if (l) sd->filter_queue = eina_list_remove_list(sd->filter_queue, l);
6432 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6433 sd->group_items = eina_list_remove(sd->group_items, it);
6437 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
6438 it->selected = EINA_FALSE;
6440 if (sd->show_item == it) sd->show_item = NULL;
6442 if ((sd->g_item) && (sd->g_item == it)) sd->g_item = NULL;
6443 if (sd->expanded_item == it) sd->expanded_item = NULL;
6444 if (sd->state) ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
6446 if (sd->last_selected_item == EO_OBJ(it))
6447 sd->last_selected_item = NULL;
6449 if (sd->realization_mode)
6452 EINA_LIST_FOREACH(GL_IT(it)->flip_content_objs, 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(GL_IT(it)->deco_all_contents, l, c)
6460 evas_object_event_callback_del_full(c,
6461 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6462 _changed_size_hints, it);
6464 EINA_LIST_FOREACH(it->content_objs, l, c)
6466 evas_object_event_callback_del_full(c,
6467 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6468 _changed_size_hints, it);
6472 if (sd->mode_item) sd->mode_item = NULL;
6473 if (it->selected) _item_unselect(it);
6474 if (it == sd->focused_item)
6478 if (!elm_widget_focus_get(WIDGET(it))) goto failed;
6480 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6481 find = _item_focusable_search(&tmp, 1);
6484 elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
6489 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6490 find = _item_focusable_search(&tmp, -1);
6493 elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
6498 elm_object_item_focus_set(EO_OBJ(it), EINA_FALSE);
6499 sd->focused_item = NULL;
6502 if (it == sd->key_down_item) sd->key_down_item = NULL;
6503 if (it == sd->highlighted_item) sd->highlighted_item = NULL;
6504 if (!TIZEN_PROFILE_WEARABLE)
6506 if (it == sd->top_drawn_item) sd->top_drawn_item = NULL;
6509 _item_unrealize(it, EINA_FALSE);
6511 if (sd->aligned_item == it) sd->aligned_item = NULL;
6513 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
6516 if (it->item->proxy)
6518 evas_object_smart_member_del(it->item->proxy);
6519 evas_object_del(it->item->proxy);
6522 if (it->itc->func.del)
6523 it->itc->func.del((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it));
6525 if (it->itc->refcount <= 1)
6529 EINA_INLIST_FOREACH_SAFE(sd->item_cache, l2, ic)
6531 if (it->itc == ic->item_class)
6532 _item_cache_free(sd, ic);
6536 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
6541 // TIZEN_ONLY(20150703) : banded color background feature. enabled only un-scrollable
6542 if (!TIZEN_PROFILE_WEARABLE)
6544 if (sd->banded_bg_rect && !sd->items)
6546 evas_object_smart_member_del(sd->banded_bg_rect);
6547 ELM_SAFE_FREE(sd->banded_bg_rect, evas_object_del);
6551 _changed(sd->pan_obj);
6554 EOLIAN static Eina_Bool
6555 _elm_genlist_item_elm_widget_item_del_pre(Eo *eo_it EINA_UNUSED,
6558 #ifdef GENLIST_FX_SUPPORT
6559 Elm_Genlist_Data *sd = it->item->wsd;
6560 Evas_Coord cvx, cvy, cvw, cvh;
6567 #ifdef GENLIST_FX_SUPPORT
6570 sd->add_fx.items = eina_list_remove(sd->add_fx.items, it);
6573 evas_output_viewport_get(evas_object_evas_get(sd->obj),
6574 &cvx, &cvy, &cvw, &cvh);
6575 if (!ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
6576 GL_IT(it)->w, GL_IT(it)->h,
6577 cvx, cvy, cvw, cvh))
6579 // Delete later, Above items in the viewport
6580 // Delete right now, below items in the viewport
6581 if (it->item->scrl_y < cvy)
6582 sd->del_fx.pending_items = eina_list_append(sd->del_fx.pending_items, it);
6586 _changed(sd->pan_obj);
6592 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
6593 else if (it->item->deco_it_view) evas_object_lower(it->item->deco_it_view);
6594 else if (VIEW(it)) evas_object_lower(VIEW(it));
6596 if (it->item->expanded_depth > 0)
6599 Elm_Object_Item *itt;
6600 EINA_LIST_FOREACH(it->item->items, l, itt)
6602 eo_do(itt, elm_wdg_item_del());
6605 sd->del_fx.items = eina_list_append(sd->del_fx.items, it);
6607 if (!sd->del_fx.anim)
6609 sd->del_fx.cnt = ANIM_CNT_MAX;
6610 sd->del_fx.anim = ecore_animator_add(_del_fx_anim, sd);
6612 _changed(sd->pan_obj);
6618 _elm_genlist_item_elm_widget_item_signal_emit(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char *emission, const char *source)
6622 WRN("item is not realized yet");
6625 edje_object_signal_emit
6626 (VIEW(it), emission, source);
6627 if (it->deco_all_view)
6628 edje_object_signal_emit
6629 (it->deco_all_view, emission, source);
6633 _elm_genlist_item_eo_base_constructor(Eo *eo_it, Elm_Gen_Item *it)
6635 eo_it = eo_do_super_ret(eo_it, ELM_GENLIST_ITEM_CLASS, eo_it, eo_constructor());
6637 it->base = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
6638 eo_do(eo_it, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST_ITEM));
6642 static Elm_Gen_Item *
6643 _elm_genlist_item_new(Elm_Genlist_Data *sd,
6644 const Elm_Genlist_Item_Class *itc,
6646 Elm_Object_Item *eo_parent,
6647 Elm_Genlist_Item_Type type,
6649 const void *func_data)
6654 if (!itc) return NULL;
6656 Eo *eo_it = eo_add(ELM_GENLIST_ITEM_CLASS, sd->obj);
6657 if (!eo_it) return NULL;
6658 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6661 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
6663 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6664 WIDGET_ITEM_DATA_SET(EO_OBJ(it), data);
6665 it->parent = parent;
6666 it->func.func = func;
6667 it->func.data = func_data;
6669 GL_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
6670 GL_IT(it)->wsd = sd;
6671 GL_IT(it)->type = type;
6675 if (GL_IT(it->parent)->type == ELM_GENLIST_ITEM_GROUP)
6676 GL_IT(it)->group_item = parent;
6677 else if (GL_IT(it->parent)->group_item)
6678 GL_IT(it)->group_item = GL_IT(it->parent)->group_item;
6680 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
6682 if (GL_IT(it2->parent)->type == ELM_GENLIST_ITEM_TREE) depth += 1;
6684 GL_IT(it)->expanded_depth = depth;
6691 _elm_genlist_item_compare(const void *data,
6694 const Elm_Gen_Item *it, *item1;
6696 it = ELM_GEN_ITEM_FROM_INLIST(data);
6697 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
6698 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6702 _elm_genlist_item_list_compare(const void *data,
6705 const Elm_Gen_Item *it = data;
6706 const Elm_Gen_Item *item1 = data1;
6708 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6711 EOLIAN static unsigned int
6712 _elm_genlist_items_count(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6714 return sd->item_count;
6718 _list_last_recursive(Eina_List *list)
6720 Eina_List *ll, *ll2;
6721 Elm_Object_Item *eo_it2;
6723 ll = eina_list_last(list);
6724 if (!ll) return NULL;
6727 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6729 if (it2->item->items)
6731 ll2 = _list_last_recursive(it2->item->items);
6741 EOLIAN static Elm_Object_Item*
6742 _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)
6746 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6750 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6751 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6752 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6755 it = _elm_genlist_item_new
6756 (sd, itc, data, eo_parent, type, func, func_data);
6757 if (!it) return NULL;
6761 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6762 sd->group_items = eina_list_append(sd->group_items, it);
6763 sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
6764 GL_IT(it)->rel = NULL;
6768 Elm_Object_Item *eo_it2 = NULL;
6769 Eina_List *ll = _list_last_recursive(it->parent->item->items);
6771 if (ll) eo_it2 = ll->data;
6772 it->parent->item->items =
6773 eina_list_append(it->parent->item->items, EO_OBJ(it));
6774 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6775 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6776 sd->items = eina_inlist_append_relative
6777 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6778 GL_IT(it)->rel = it2;
6779 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6781 GL_IT(it)->before = EINA_FALSE;
6782 _item_queue_direct(it, NULL);
6786 EOLIAN static Elm_Object_Item*
6787 _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)
6789 Elm_Gen_Item *it = NULL;
6791 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6794 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6795 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6796 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6797 /* first sub-item should allways be appended */
6798 if (!parent->item->items)
6799 return _elm_genlist_item_append(obj, sd, itc, data, eo_parent, type, func, func_data);
6801 it = _elm_genlist_item_new
6802 (sd, itc, data, eo_parent, type, func, func_data);
6804 if (!it) return NULL;
6806 if (sd->items) GL_IT(it)->is_prepend = EINA_TRUE;
6809 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6810 sd->group_items = eina_list_prepend(sd->group_items, it);
6811 sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
6812 GL_IT(it)->rel = NULL;
6816 Elm_Object_Item *eo_it2 = NULL;
6817 Eina_List *ll = it->parent->item->items;
6819 if (ll) eo_it2 = ll->data;
6820 it->parent->item->items =
6821 eina_list_prepend(it->parent->item->items, EO_OBJ(it));
6822 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6823 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6826 sd->items = eina_inlist_prepend_relative
6827 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6828 GL_IT(it)->rel = it2;
6829 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6832 GL_IT(it)->before = EINA_TRUE;
6833 _item_queue_direct(it, NULL);
6837 EOLIAN static Elm_Object_Item*
6838 _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)
6840 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_after, NULL);
6841 ELM_GENLIST_ITEM_DATA_GET(eo_after, after_it);
6844 ELM_GENLIST_ITEM_CHECK_OR_RETURN(after_it, NULL);
6845 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(after_it), NULL);
6848 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6849 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6850 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6853 /* It makes no sense to insert after in an empty list with after !=
6854 * NULL, something really bad is happening in your app. */
6855 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6857 it = _elm_genlist_item_new
6858 (sd, itc, data, eo_parent, type, func, func_data);
6859 if (!it) return NULL;
6863 if ((GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) &&
6864 (GL_IT(after_it)->type == ELM_GENLIST_ITEM_GROUP))
6865 sd->group_items = eina_list_append_relative
6866 (sd->group_items, it, after_it);
6870 it->parent->item->items =
6871 eina_list_append_relative(it->parent->item->items, EO_OBJ(it), eo_after);
6873 sd->items = eina_inlist_append_relative
6874 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after_it));
6876 GL_IT(it)->rel = after_it;
6877 after_it->item->rel_revs = eina_list_append(after_it->item->rel_revs, it);
6878 GL_IT(it)->before = EINA_FALSE;
6879 _item_queue_direct(it, NULL);
6881 if (elm_genlist_item_next_get(eo_after) == EO_OBJ(sd->aligned_item))
6882 sd->aligned_item = NULL;
6886 EOLIAN static Elm_Object_Item*
6887 _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)
6889 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_before, NULL);
6890 ELM_GENLIST_ITEM_DATA_GET(eo_before, before_it);
6893 ELM_GENLIST_ITEM_CHECK_OR_RETURN(before_it, NULL);
6894 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(before_it), NULL);
6897 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6898 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6899 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6902 /* It makes no sense to insert before in an empty list with before
6903 * != NULL, something really bad is happening in your app. */
6904 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6906 it = _elm_genlist_item_new
6907 (sd, itc, data, eo_parent, type, func, func_data);
6908 if (!it) return NULL;
6912 if ((GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) &&
6913 (GL_IT(before_it)->type == ELM_GENLIST_ITEM_GROUP))
6915 eina_list_prepend_relative(sd->group_items, it, before_it);
6919 it->parent->item->items =
6920 eina_list_prepend_relative(it->parent->item->items, EO_OBJ(it), eo_before);
6922 sd->items = eina_inlist_prepend_relative
6923 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before_it));
6925 GL_IT(it)->rel = before_it;
6926 before_it->item->rel_revs = eina_list_append(before_it->item->rel_revs, it);
6927 GL_IT(it)->before = EINA_TRUE;
6928 _item_queue_direct(it, NULL);
6930 if (before_it == sd->aligned_item)
6931 sd->aligned_item = NULL;
6936 EOLIAN static Elm_Object_Item*
6937 _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)
6939 Elm_Gen_Item *rel = NULL;
6941 Elm_Object_Item *eo_it;
6945 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6946 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6947 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6950 it = _elm_genlist_item_new
6951 (sd, itc, data, eo_parent, type, func, func_data);
6952 if (!it) return NULL;
6955 sd->item_compare_cb = comp;
6959 Elm_Object_Item *eo_rel = NULL;
6963 l = eina_list_search_sorted_near_list
6964 (it->parent->item->items, _elm_genlist_item_list_compare, eo_it,
6969 eo_rel = eina_list_data_get(l);
6970 rel = eo_data_scope_get(eo_rel, ELM_GENLIST_ITEM_CLASS);
6972 if (cmp_result >= 0)
6974 it->parent->item->items = eina_list_prepend_relative_list
6975 (it->parent->item->items, eo_it, l);
6976 sd->items = eina_inlist_prepend_relative
6977 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6978 it->item->before = EINA_TRUE;
6980 else if (cmp_result < 0)
6982 it->parent->item->items = eina_list_append_relative_list
6983 (it->parent->item->items, eo_it, l);
6984 sd->items = eina_inlist_append_relative
6985 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6986 it->item->before = EINA_FALSE;
6987 it->item->is_prepend = EINA_TRUE;
6994 // ignoring the comparison
6995 it->parent->item->items = eina_list_prepend_relative_list
6996 (it->parent->item->items, eo_it, l);
6997 sd->items = eina_inlist_prepend_relative
6998 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6999 it->item->before = EINA_FALSE;
7006 sd->state = eina_inlist_sorted_state_new();
7007 eina_inlist_sorted_state_init(sd->state, sd->items);
7008 sd->requeued = EINA_FALSE;
7011 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
7012 sd->group_items = eina_list_append(sd->group_items, it);
7014 sd->items = eina_inlist_sorted_state_insert
7015 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
7018 if (EINA_INLIST_GET(it)->next)
7020 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
7021 GL_IT(it)->before = EINA_TRUE;
7022 GL_IT(it)->is_prepend = EINA_TRUE;
7024 else if (EINA_INLIST_GET(it)->prev)
7026 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7027 GL_IT(it)->before = EINA_FALSE;
7033 GL_IT(it)->rel = rel;
7034 rel->item->rel_revs = eina_list_append(rel->item->rel_revs, it);
7037 _item_queue_direct(it, _elm_genlist_item_list_compare);
7042 _elm_genlist_clear(Eo *obj, Elm_Genlist_Data *sd)
7046 eina_hash_free_buckets(sd->size_caches);
7047 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
7048 if (sd->key_down_item) sd->key_down_item = NULL;
7049 if (sd->mode_item) sd->mode_item = NULL;
7053 eina_inlist_sorted_state_free(sd->state);
7057 sd->filter_data = NULL;
7058 if (sd->filter_queue)
7059 ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
7060 ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
7061 ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
7063 // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
7064 // because sd->items can be modified inside elm_widget_item_del()
7067 it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
7068 //elm_widget_item_del(it);
7071 sd->reorder.it = NULL;
7072 sd->reorder.dir = 0;
7073 eina_list_free(sd->reorder.move_items);
7077 _item_cache_all_free(sd);
7081 sd->selected = eina_list_free(sd->selected);
7082 sd->selected = NULL;
7085 sd->show_item = NULL;
7094 evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
7095 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
7097 elm_layout_sizing_eval(obj);
7099 eo_do(sd->obj, elm_interface_scrollable_content_region_show(0, 0, 0, 0));
7103 ecore_job_del(sd->dummy_job);
7104 sd->dummy_job = NULL;
7106 if (sd->queue_idle_enterer)
7108 ecore_idle_enterer_del(sd->queue_idle_enterer);
7109 sd->queue_idle_enterer = NULL;
7111 if (sd->scr_hold_timer)
7113 ecore_timer_del(sd->scr_hold_timer);
7114 sd->scr_hold_timer = NULL;
7116 if (sd->reorder.anim)
7118 ecore_animator_del(sd->reorder.anim);
7119 sd->reorder.anim = NULL;
7123 ecore_timer_del(sd->scr_timer);
7124 sd->scr_timer = NULL;
7126 #ifdef GENLIST_FX_SUPPORT
7127 if (sd->del_fx.anim)
7129 ecore_animator_del(sd->del_fx.anim);
7130 sd->del_fx.anim = NULL;
7132 if (sd->add_fx.anim)
7134 ecore_animator_del(sd->add_fx.anim);
7135 sd->add_fx.anim = NULL;
7139 if (sd->queue) sd->queue = eina_list_free(sd->queue);
7140 if (sd->g_item) sd->g_item = NULL;
7141 if (sd->g_type) sd->g_type = NULL;
7143 if (!TIZEN_PROFILE_WEARABLE)
7145 if (sd->banded_bg_rect)
7147 evas_object_smart_member_del(sd->banded_bg_rect);
7148 ELM_SAFE_FREE(sd->banded_bg_rect, evas_object_del);
7154 _elm_genlist_multi_select_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool multi)
7156 sd->multi = !!multi;
7157 if (!sd->multi && sd->selected)
7160 Elm_Object_Item *eo_it;
7161 Elm_Object_Item *last = sd->selected->data;
7162 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
7165 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
7171 EOLIAN static Eina_Bool
7172 _elm_genlist_multi_select_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7178 _elm_genlist_multi_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Elm_Object_Multi_Select_Mode mode EINA_UNUSED)
7180 /* Need to be implemented
7181 if (mode >= ELM_OBJECT_MULTI_SELECT_MODE_MAX)
7184 if (sd->multi_select_mode != mode)
7185 sd->multi_select_mode = mode;
7190 EOLIAN static Elm_Object_Multi_Select_Mode
7191 _elm_genlist_multi_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
7193 // Need to be implemented
7194 //return sd->multi_select_mode;
7195 return ELM_OBJECT_MULTI_SELECT_MODE_DEFAULT;
7198 EOLIAN static Elm_Object_Item*
7199 _elm_genlist_selected_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7202 return sd->selected->data;
7207 EOLIAN static const Eina_List*
7208 _elm_genlist_selected_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7210 return sd->selected;
7213 EOLIAN static Eina_List*
7214 _elm_genlist_realized_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7217 Eina_List *list = NULL;
7218 Eina_Bool done = EINA_FALSE;
7220 EINA_INLIST_FOREACH(sd->blocks, itb)
7228 EINA_LIST_FOREACH(itb->items, l, it)
7230 if (it->realized) list = eina_list_append(list, EO_OBJ(it));
7241 EOLIAN static Elm_Object_Item *
7242 _elm_genlist_search_by_text_item_get(Eo *obj EINA_UNUSED,
7243 Elm_Genlist_Data *sd,
7244 Elm_Object_Item *item_to_search_from,
7245 const char *part_name,
7246 const char *pattern,
7247 Elm_Glob_Match_Flags flags)
7249 Elm_Gen_Item *it = NULL;
7251 Eina_Inlist *start = NULL;
7254 if (!pattern) return NULL;
7255 if (!sd->items) return NULL;
7257 if (flags & ELM_GLOB_MATCH_NO_ESCAPE) fnflags |= FNM_NOESCAPE;
7258 if (flags & ELM_GLOB_MATCH_PATH) fnflags |= FNM_PATHNAME;
7259 if (flags & ELM_GLOB_MATCH_PERIOD) fnflags |= FNM_PERIOD;
7261 if (flags & ELM_GLOB_MATCH_NOCASE) fnflags |= FNM_CASEFOLD;
7264 start = (item_to_search_from) ?
7265 EINA_INLIST_GET((Elm_Gen_Item *)eo_data_scope_get(item_to_search_from, ELM_GENLIST_ITEM_CLASS)) :
7267 EINA_INLIST_FOREACH(start, it)
7269 if (!it->itc->func.text_get) continue;
7270 str = it->itc->func.text_get((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), part_name);
7272 if (!fnmatch(pattern, str, fnflags))
7282 EOLIAN static Elm_Object_Item*
7283 _elm_genlist_at_xy_item_get(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y, int *posret)
7285 Evas_Coord ox, oy, ow, oh;
7289 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7291 EINA_INLIST_FOREACH(sd->blocks, itb)
7295 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->sd->pan_x,
7296 oy + itb->y - itb->sd->pan_y,
7297 sd->minw, itb->minh, x, y, 1, 1))
7299 EINA_LIST_FOREACH(itb->items, l, it)
7301 Evas_Coord itx, ity;
7303 itx = ox + itb->x + it->x - itb->sd->pan_x;
7304 ity = oy + itb->y + it->y - itb->sd->pan_y;
7305 if (ELM_RECTS_INTERSECT
7306 (itx, ity, GL_IT(it)->w, GL_IT(it)->h, x, y, 1, 1))
7310 if (y <= (ity + (GL_IT(it)->h / 4))) *posret = -1;
7311 else if (y >= (ity + GL_IT(it)->h - (GL_IT(it)->h / 4)))
7318 lasty = ity + GL_IT(it)->h;
7323 if (y > lasty) *posret = 1;
7330 EOLIAN static Elm_Object_Item*
7331 _elm_genlist_first_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7333 Elm_Gen_Item *tit, *it = NULL;
7335 EINA_INLIST_REVERSE_FOREACH(sd->items, tit) it = tit;
7340 EOLIAN static Elm_Object_Item*
7341 _elm_genlist_last_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7345 if (!sd->items) return NULL;
7347 it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
7351 EOLIAN static Elm_Object_Item *
7352 _elm_genlist_item_next_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7356 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
7360 if (it) return EO_OBJ(it);
7364 EOLIAN static Elm_Object_Item *
7365 _elm_genlist_item_prev_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7369 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7373 if (it) return EO_OBJ(it);
7377 EOLIAN static Elm_Object_Item *
7378 _elm_genlist_item_parent_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7380 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
7382 return EO_OBJ(it->parent);
7385 EOLIAN static unsigned int
7386 _elm_genlist_item_subitems_count(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
7388 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, 0);
7390 return eina_list_count(item->item->items);
7393 EOLIAN static const Eina_List *
7394 _elm_genlist_item_subitems_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
7396 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
7398 return item->item->items;
7402 _elm_genlist_item_subitems_clear(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7404 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7406 Elm_Object_Item *eo_it2;
7408 EINA_LIST_FOREACH_SAFE(GL_IT(it)->items, l, ll, eo_it2)
7409 eo_do(eo_it2, elm_wdg_item_del());
7413 _elm_genlist_item_selected_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
7416 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7419 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get())) return;
7420 // FIXME: This API has highlight/unhighlith feature also..
7422 if (selected) _item_highlight(it);
7423 else _item_unhighlight(it, EINA_TRUE);
7425 selected = !!selected;
7426 if (it->selected == selected) return;
7428 if (selected) _item_select(it);
7429 else _item_unselect(it);
7432 EOLIAN static Eina_Bool
7433 _elm_genlist_item_selected_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7435 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7437 return it->selected;
7441 _elm_genlist_item_expanded_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool expanded)
7443 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7445 expanded = !!expanded;
7446 if (GL_IT(it)->expanded == expanded) return;
7447 if (GL_IT(it)->type != ELM_GENLIST_ITEM_TREE) return;
7448 GL_IT(it)->expanded = expanded;
7449 GL_IT(it)->wsd->expanded_item = it;
7451 if (GL_IT(it)->expanded)
7454 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
7455 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, EO_OBJ(it));
7456 if (_elm_atspi_enabled())
7457 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_item);
7462 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACTED, "elm");
7463 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, EO_OBJ(it));
7464 if (_elm_atspi_enabled())
7465 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_item);
7469 EOLIAN static Eina_Bool
7470 _elm_genlist_item_expanded_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7472 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7474 return GL_IT(it)->expanded;
7478 _elm_genlist_item_expanded_depth_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7480 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, 0);
7482 return GL_IT(it)->expanded_depth;
7486 _elm_genlist_item_promote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7488 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7490 Elm_Object_Item *eo_first_item = elm_genlist_first_item_get(WIDGET(it));
7491 ELM_GENLIST_ITEM_DATA_GET(eo_first_item, first_item);
7492 _item_move_before(it, first_item);
7496 _elm_genlist_item_demote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7498 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7499 Elm_Object_Item *eo_last_item = elm_genlist_last_item_get(WIDGET(it));
7500 ELM_GENLIST_ITEM_DATA_GET(eo_last_item, last_item);
7501 _item_move_after(it, last_item);
7505 _elm_genlist_item_show(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
7507 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7509 if (it->want_hidden)
7511 WRN("Filter hided item cannot move to show");
7515 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7517 sd->bring_in = EINA_FALSE;
7518 sd->scroll_to_type = type;
7519 _changed(sd->pan_obj);
7523 _elm_genlist_item_bring_in(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
7525 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7527 if (it->want_hidden)
7529 WRN("Filter hided item cannot move to bring in");
7533 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7534 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wd);
7535 sd->bring_in = EINA_TRUE;
7536 sd->scroll_to_type = type;
7538 if (wd->scroll_item_align_enable)
7540 it = _adjust_item_align(it);
7541 sd->adjusted_item = sd->show_item = it;
7543 if (sd->aligned_item && sd->show_item != sd->aligned_item)
7544 edje_object_signal_emit(VIEW(sd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
7549 _changed(sd->pan_obj);
7553 _elm_genlist_item_all_contents_unset(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_List **l)
7555 Evas_Object *content;
7557 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7559 EINA_LIST_FREE (it->content_objs, content)
7561 evas_object_smart_member_del(content);
7562 // edje can be reused by item caching,
7563 // content should be un-swallowed from edje
7564 edje_object_part_unswallow(VIEW(it), content);
7565 evas_object_hide(content);
7566 if (l) *l = eina_list_append(*l, content);
7571 _elm_genlist_item_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7573 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7575 if (!GL_IT(it)->block) return;
7577 GL_IT(it)->updateme = EINA_TRUE;
7578 GL_IT(it)->block->calc_done = EINA_FALSE;
7579 GL_IT(it)->wsd->calc_done = EINA_FALSE;
7580 _changed(GL_IT(it)->wsd->pan_obj);
7584 _elm_genlist_item_fields_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
7586 Elm_Genlist_Item_Field_Type itf)
7588 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7590 if (!GL_IT(it)->block) return;
7592 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
7594 _item_text_realize(it, VIEW(it), parts);
7596 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
7598 _item_content_realize(it, VIEW(it), &it->content_objs, "contents", parts);
7601 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_content_objs,
7604 if (GL_IT(it)->deco_it_view)
7606 _item_content_realize(it, GL_IT(it)->deco_it_view,
7607 &GL_IT(it)->deco_it_contents,
7610 if (GL_IT(it)->wsd->decorate_all_mode)
7612 _item_content_realize(it, it->deco_all_view,
7613 &GL_IT(it)->deco_all_contents,
7618 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
7619 _item_state_realize(it, VIEW(it), parts);
7621 GL_IT(it)->calc_done = EINA_FALSE;
7622 GL_IT(it)->block->calc_done = EINA_FALSE;
7623 GL_IT(it)->wsd->calc_done = EINA_FALSE;
7624 _changed(GL_IT(it)->wsd->pan_obj);
7628 _elm_genlist_item_item_class_update(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
7629 const Elm_Genlist_Item_Class *itc)
7631 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7632 EINA_SAFETY_ON_NULL_RETURN(itc);
7633 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7636 if (!GL_IT(it)->block) return;
7638 // FIXME(160711): orignal edje object updated by _view_theme_update
7639 // cannot recieve signal emit properly. This edje bug must be fixed.
7640 _item_cache_all_free(sd);
7642 sd->no_cache = EINA_TRUE;
7643 _item_unrealize(it, EINA_FALSE);
7644 sd->no_cache = EINA_FALSE;
7645 _item_realize(it, EINA_FALSE);
7647 if (sd->aligned_item == it)
7648 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
7650 GL_IT(it)->calc_done = EINA_FALSE;
7651 GL_IT(it)->block->calc_done = EINA_FALSE;
7652 sd->calc_done = EINA_FALSE;
7654 _changed(sd->pan_obj);
7657 EOLIAN static const Elm_Genlist_Item_Class *
7658 _elm_genlist_item_item_class_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7660 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
7664 static Evas_Object *
7665 _elm_genlist_item_label_create(void *data,
7666 Evas_Object *obj EINA_UNUSED,
7667 Evas_Object *tooltip,
7668 void *it EINA_UNUSED)
7670 Evas_Object *label = elm_label_add(tooltip);
7675 elm_object_style_set(label, "tooltip");
7676 elm_object_text_set(label, data);
7682 _elm_genlist_item_label_del_cb(void *data,
7683 Evas_Object *obj EINA_UNUSED,
7684 void *event_info EINA_UNUSED)
7686 eina_stringshare_del(data);
7690 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
7693 eo_do(it, elm_wdg_item_tooltip_text_set(text));
7697 _elm_genlist_item_elm_widget_item_tooltip_text_set(Eo *eo_it, Elm_Gen_Item *it, const char *text)
7699 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7701 text = eina_stringshare_add(text);
7702 elm_genlist_item_tooltip_content_cb_set
7703 (eo_it, _elm_genlist_item_label_create, text,
7704 _elm_genlist_item_label_del_cb);
7708 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item,
7709 Elm_Tooltip_Item_Content_Cb func,
7711 Evas_Smart_Cb del_cb)
7713 eo_do(item, elm_wdg_item_tooltip_content_cb_set(func, data, del_cb));
7718 _elm_genlist_item_elm_widget_item_tooltip_content_cb_set(Eo *eo_it, Elm_Gen_Item *it,
7719 Elm_Tooltip_Item_Content_Cb func,
7721 Evas_Smart_Cb del_cb)
7723 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7725 if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
7728 if (it->tooltip.del_cb)
7729 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7731 it->tooltip.content_cb = func;
7732 it->tooltip.data = data;
7733 it->tooltip.del_cb = del_cb;
7737 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7738 elm_wdg_item_tooltip_content_cb_set
7739 (it->tooltip.content_cb, it->tooltip.data, NULL));
7741 elm_wdg_item_tooltip_style_set(it->tooltip.style),
7742 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
7747 elm_genlist_item_tooltip_unset(Elm_Object_Item *item)
7749 eo_do(item, elm_wdg_item_tooltip_unset());
7753 _elm_genlist_item_elm_widget_item_tooltip_unset(Eo *eo_it, Elm_Gen_Item *it)
7755 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7757 if ((VIEW(it)) && (it->tooltip.content_cb))
7758 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7759 elm_wdg_item_tooltip_unset());
7761 if (it->tooltip.del_cb)
7762 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7763 it->tooltip.del_cb = NULL;
7764 it->tooltip.content_cb = NULL;
7765 it->tooltip.data = NULL;
7766 it->tooltip.free_size = EINA_FALSE;
7767 if (it->tooltip.style)
7768 eo_do(eo_it, elm_wdg_item_tooltip_style_set(NULL));
7772 elm_genlist_item_tooltip_style_set(Elm_Object_Item *item,
7775 eo_do(item, elm_wdg_item_tooltip_style_set(style));
7779 _elm_genlist_item_elm_widget_item_tooltip_style_set(Eo *eo_it, Elm_Gen_Item *it,
7782 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7784 eina_stringshare_replace(&it->tooltip.style, style);
7785 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7786 elm_wdg_item_tooltip_style_set(style));
7790 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
7793 return eo_do_ret(it, style, elm_wdg_item_tooltip_style_get());
7796 EOLIAN static const char *
7797 _elm_genlist_item_elm_widget_item_tooltip_style_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7799 return it->tooltip.style;
7803 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *item,
7807 return eo_do_ret(item, ret, elm_wdg_item_tooltip_window_mode_set(disable));
7810 EOLIAN static Eina_Bool
7811 _elm_genlist_item_elm_widget_item_tooltip_window_mode_set(Eo *eo_it, Elm_Gen_Item *it,
7814 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7817 it->tooltip.free_size = disable;
7819 return eo_do_super_ret(eo_it, ELM_GENLIST_ITEM_CLASS, ret,
7820 elm_wdg_item_tooltip_window_mode_set(disable));
7826 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *eo_it)
7829 return eo_do_ret(eo_it, ret, elm_wdg_item_tooltip_window_mode_get());
7832 EOLIAN static Eina_Bool
7833 _elm_genlist_item_elm_widget_item_tooltip_window_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7835 return it->tooltip.free_size;
7839 elm_genlist_item_cursor_set(Elm_Object_Item *item,
7842 eo_do(item, elm_wdg_item_cursor_set(cursor));
7846 _elm_genlist_item_elm_widget_item_cursor_set(Eo *eo_it, Elm_Gen_Item *it,
7849 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7850 eina_stringshare_replace(&it->mouse_cursor, cursor);
7851 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7852 elm_wdg_item_cursor_set(cursor));
7856 elm_genlist_item_cursor_get(const Elm_Object_Item *eo_it)
7859 return eo_do_ret(eo_it, cursor, elm_wdg_item_cursor_get());
7863 elm_genlist_item_cursor_unset(Elm_Object_Item *item)
7865 eo_do(item, elm_wdg_item_cursor_unset());
7869 _elm_genlist_item_elm_widget_item_cursor_unset(Eo *eo_it, Elm_Gen_Item *it)
7871 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7873 if (!it->mouse_cursor) return;
7875 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7876 elm_wdg_item_cursor_unset());
7878 ELM_SAFE_FREE(it->mouse_cursor, eina_stringshare_del);
7882 elm_genlist_item_cursor_style_set(Elm_Object_Item *eo_it,
7885 eo_do(eo_it, elm_wdg_item_cursor_style_set(style));
7889 elm_genlist_item_cursor_style_get(const Elm_Object_Item *eo_it)
7892 return eo_do_ret( eo_it, style, elm_wdg_item_cursor_style_get());
7896 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *eo_it,
7897 Eina_Bool engine_only)
7899 eo_do(eo_it, elm_wdg_item_cursor_engine_only_set(engine_only));
7903 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *eo_it)
7906 return eo_do_ret( eo_it, ret, elm_wdg_item_cursor_engine_only_get());
7910 _elm_genlist_item_index_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7914 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, -1);
7916 EINA_INLIST_FOREACH(GL_IT(it)->wsd->items, tmp)
7918 if (tmp == it) break;
7925 _elm_genlist_mode_set(Eo *obj, Elm_Genlist_Data *sd, Elm_List_Mode mode)
7927 if (sd->mode == mode) return;
7930 if (sd->mode == ELM_LIST_LIMIT)
7932 sd->scr_minw = EINA_TRUE;
7933 sd->scr_minh = EINA_FALSE;
7935 else if (sd->mode == ELM_LIST_EXPAND)
7937 sd->scr_minw = EINA_TRUE;
7938 sd->scr_minh = EINA_TRUE;
7942 sd->scr_minw = EINA_FALSE;
7943 sd->scr_minh = EINA_FALSE;
7946 elm_layout_sizing_eval(obj);
7949 EOLIAN static Elm_List_Mode
7950 _elm_genlist_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7956 elm_genlist_bounce_set(Evas_Object *obj,
7960 ELM_GENLIST_CHECK(obj);
7961 eo_do(obj, elm_interface_scrollable_bounce_allow_set(h_bounce, v_bounce));
7965 _elm_genlist_elm_interface_scrollable_bounce_allow_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool h_bounce, Eina_Bool v_bounce)
7967 sd->h_bounce = !!h_bounce;
7968 sd->v_bounce = !!v_bounce;
7970 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_bounce_allow_set
7971 (sd->h_bounce, sd->v_bounce));
7972 //sd->s_iface->bounce_allow_set(obj, sd->h_bounce, sd->v_bounce);
7976 elm_genlist_bounce_get(const Evas_Object *obj,
7977 Eina_Bool *h_bounce,
7978 Eina_Bool *v_bounce)
7980 ELM_GENLIST_CHECK(obj);
7981 eo_do( obj, elm_interface_scrollable_bounce_allow_get
7982 (h_bounce, v_bounce));
7986 _elm_genlist_elm_interface_scrollable_bounce_allow_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
7988 if (h_bounce) *h_bounce = sd->h_bounce;
7989 if (v_bounce) *v_bounce = sd->v_bounce;
7993 _elm_genlist_homogeneous_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool homogeneous)
7995 sd->homogeneous = !!homogeneous;
7998 EOLIAN static Eina_Bool
7999 _elm_genlist_homogeneous_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8001 return sd->homogeneous;
8005 _elm_genlist_block_count_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, int count)
8007 EINA_SAFETY_ON_TRUE_RETURN(count < 1);
8009 sd->max_items_per_block = count;
8010 sd->item_cache_max = sd->max_items_per_block * 2;
8011 _item_cache_all_free(sd);
8015 _elm_genlist_block_count_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8017 return sd->max_items_per_block;
8021 _filter_item_internal(Elm_Gen_Item *it)
8023 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8024 if (sd->filter_data && it->itc->func.filter_get)
8026 if (!it->itc->func.filter_get(
8027 (void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)),
8028 WIDGET(it), sd->filter_data))
8030 it->want_hidden = EINA_TRUE;
8031 if (sd->show_item == it) sd->show_item = NULL;
8032 GL_IT(it)->block->calc_done = EINA_FALSE;
8033 sd->calc_done = EINA_FALSE;
8036 sd->filtered_count++;
8038 it->filtered = EINA_TRUE;
8039 sd->processed_count++;
8043 _item_filtered_get(Elm_Gen_Item *it)
8046 if (!it) return EINA_FALSE;
8047 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8050 l = eina_list_data_find_list(sd->filter_queue, it);
8052 sd->filter_queue = eina_list_remove_list(sd->filter_queue, l);
8053 l = eina_list_data_find_list(sd->queue, it);
8056 sd->queue = eina_list_remove_list(sd->queue, l);
8057 GL_IT(it)->queued = EINA_FALSE;
8058 GL_IT(it)->resized = EINA_FALSE;
8059 _item_process(sd, it);
8062 _filter_item_internal(it);
8063 GL_IT(it)->block->calc_done = EINA_FALSE;
8064 sd->calc_done = EINA_FALSE;
8065 _changed(sd->pan_obj);
8067 if (!it->want_hidden) return EINA_TRUE;
8072 _filter_queue_process(Elm_Genlist_Data *sd)
8075 Elm_Gen_Item *it, *first;
8078 t0 = ecore_time_get();
8079 for (n = 0; ((sd->filter_queue) && (sd->processed_count < ITEM_QUEUE_MAX)); n++)
8081 first = it = eina_list_data_get(sd->filter_queue);
8082 //FIXME: This is added as a fail safe code for items not yet processed.
8083 while (it && it->item->queued)
8085 if ((ecore_time_get() - t0) > (ecore_animator_frametime_get()))
8087 sd->filter_queue = eina_list_remove_list
8088 (sd->filter_queue, sd->filter_queue);
8089 sd->filter_queue = eina_list_append(sd->filter_queue, it);
8090 it = eina_list_data_get(sd->filter_queue);
8092 //Do not iterate more than one loop
8093 if (it == first) return n;
8095 sd->filter_queue = eina_list_remove_list(sd->filter_queue, sd->filter_queue);
8098 _filter_item_internal(it);
8099 GL_IT(it)->block->calc_done = EINA_FALSE;
8101 sd->calc_done = EINA_FALSE;
8102 _changed(sd->pan_obj);
8103 if ((ecore_time_get() - t0) > (ecore_animator_frametime_get()))
8105 //At least 1 item is filtered by this time, so return n+1 for first loop
8114 _filter_process(void *data,
8117 Elm_Genlist_Data *sd = data;
8119 if (_filter_queue_process(sd) > 0) *wakeup = EINA_TRUE;
8120 if (!sd->filter_queue) return ECORE_CALLBACK_CANCEL;
8121 return ECORE_CALLBACK_RENEW;
8125 _item_filter_enterer(void *data)
8127 Eina_Bool wakeup = EINA_FALSE;
8128 ELM_GENLIST_DATA_GET(data, sd);
8129 Eina_Bool ok = _filter_process(sd, &wakeup);
8132 if (sd->dummy_job) ecore_job_del(sd->dummy_job);
8133 sd->dummy_job = ecore_job_add(_dummy_job, sd);
8135 if (ok == ECORE_CALLBACK_CANCEL)
8139 ecore_job_del(sd->dummy_job);
8140 sd->dummy_job = NULL;
8142 sd->queue_idle_enterer = NULL;
8143 evas_object_smart_callback_call((Evas_Object *)data, SIG_FILTER_DONE, NULL);
8150 _elm_genlist_filter_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, void *filter_data)
8156 if (sd->filter_queue)
8157 ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
8158 ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
8159 ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
8160 sd->filtered_count = 0;
8161 sd->processed_count = 0;
8162 sd->filter = EINA_TRUE;
8163 sd->filter_data = filter_data;
8165 EINA_INLIST_FOREACH(sd->blocks, itb)
8169 EINA_LIST_FOREACH(itb->items, l, it)
8171 it->filtered = EINA_FALSE;
8172 it->want_hidden = EINA_FALSE;
8174 _filter_item_internal(it);
8176 sd->filter_queue = eina_list_append(sd->filter_queue, it);
8178 itb->calc_done = EINA_FALSE;
8179 sd->calc_done = EINA_FALSE;
8183 EINA_LIST_FOREACH(itb->items, l, it)
8185 it->filtered = EINA_FALSE;
8186 it->want_hidden = EINA_FALSE;
8187 sd->filter_queue = eina_list_append(sd->filter_queue, it);
8191 _changed(sd->pan_obj);
8193 sd->queue_filter_enterer = ecore_idle_enterer_add(_item_filter_enterer,
8198 _filter_iterator_next(Elm_Genlist_Filter *iter, void **data)
8200 if (!iter->current) return EINA_FALSE;
8202 while (iter->current)
8204 item = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->current, Elm_Gen_Item);
8205 iter->current = iter->current->next;
8206 if (_item_filtered_get(item))
8209 *data = EO_OBJ(item);
8218 _filter_iterator_free(Elm_Genlist_Filter *iter)
8223 static Evas_Object *
8224 _filter_iterator_get_container(Elm_Genlist_Filter *iter)
8226 Elm_Gen_Item *it = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->head, Elm_Gen_Item);
8230 EOLIAN Eina_Iterator *
8231 _elm_genlist_filter_iterator_new(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8233 Elm_Genlist_Filter *iter;
8234 iter = calloc(1, sizeof (Elm_Genlist_Filter));
8235 if (!iter) return NULL;
8237 iter->head = sd->items;
8238 iter->current = sd->items;
8240 iter->iterator.version = EINA_ITERATOR_VERSION;
8241 iter->iterator.next = FUNC_ITERATOR_NEXT(_filter_iterator_next);
8242 iter->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
8243 _filter_iterator_get_container);
8244 iter->iterator.free = FUNC_ITERATOR_FREE(_filter_iterator_free);
8246 EINA_MAGIC_SET(&iter->iterator, EINA_MAGIC_ITERATOR);
8248 return &iter->iterator;
8252 _elm_genlist_longpress_timeout_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, double timeout)
8254 sd->longpress_timeout = timeout;
8257 EOLIAN static double
8258 _elm_genlist_longpress_timeout_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8260 return sd->longpress_timeout;
8264 elm_genlist_scroller_policy_set(Evas_Object *obj,
8265 Elm_Scroller_Policy policy_h,
8266 Elm_Scroller_Policy policy_v)
8268 ELM_GENLIST_CHECK(obj);
8269 eo_do(obj, elm_interface_scrollable_policy_set(policy_h, policy_v));
8273 _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)
8275 ELM_GENLIST_CHECK(obj);
8277 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
8278 (policy_v >= ELM_SCROLLER_POLICY_LAST))
8281 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_set(policy_h, policy_v));
8285 elm_genlist_scroller_policy_get(const Evas_Object *obj,
8286 Elm_Scroller_Policy *policy_h,
8287 Elm_Scroller_Policy *policy_v)
8289 ELM_GENLIST_CHECK(obj);
8290 eo_do( obj, elm_interface_scrollable_policy_get(policy_h, policy_v));
8294 _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)
8296 Elm_Scroller_Policy s_policy_h, s_policy_v;
8298 ELM_GENLIST_CHECK(obj);
8300 eo_do((Eo *)obj, elm_interface_scrollable_policy_get(&s_policy_h, &s_policy_v));
8301 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
8302 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
8306 _elm_genlist_realized_items_update(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED)
8309 Elm_Object_Item *eo_it;
8311 ELM_GENLIST_CHECK(obj);
8313 list = elm_genlist_realized_items_get(obj);
8314 EINA_LIST_FREE(list, eo_it)
8315 elm_genlist_item_update(eo_it);
8319 _elm_genlist_item_decorate_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8320 const char *decorate_it_type,
8321 Eina_Bool decorate_it_set)
8323 Elm_Genlist_Data *sd;
8326 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8327 sd = GL_IT(it)->wsd;
8329 if (!decorate_it_type) return;
8330 if (eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get())) return;
8331 if (sd->decorate_all_mode) return;
8333 if ((sd->mode_item == it) &&
8334 (!strcmp(decorate_it_type, sd->decorate_it_type)) &&
8337 if (!it->itc->decorate_item_style) return;
8338 it->decorate_it_set = decorate_it_set;
8341 if (((sd->decorate_it_type)
8342 && (strcmp(decorate_it_type, sd->decorate_it_type))) ||
8343 (decorate_it_set) || ((it == sd->mode_item) && (!decorate_it_set)))
8345 char buf[1024], buf2[1024];
8347 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8348 if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
8349 sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
8351 snprintf(buf, sizeof(buf), "elm,state,%s,passive", sd->decorate_it_type);
8352 edje_object_signal_emit(GL_IT(it)->deco_it_view, buf, "elm");
8353 edje_object_signal_emit(VIEW(it), buf, "elm");
8355 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished",
8356 sd->decorate_it_type);
8357 edje_object_signal_callback_add(GL_IT(it)->deco_it_view, buf2,
8359 _decorate_item_finished_signal_cb, it);
8360 sd->mode_item = NULL;
8363 eina_stringshare_replace(&sd->decorate_it_type, decorate_it_type);
8364 if (decorate_it_set)
8367 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8368 if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
8369 sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
8371 _decorate_item_realize(it);
8375 EOLIAN static const char *
8376 _elm_genlist_item_decorate_mode_get(Eo *eo_i EINA_UNUSED, Elm_Gen_Item *i)
8378 ELM_GENLIST_ITEM_CHECK_OR_RETURN(i, NULL);
8379 return GL_IT(i)->wsd->decorate_it_type;
8382 EOLIAN static Elm_Object_Item *
8383 _elm_genlist_decorated_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8385 return EO_OBJ(sd->mode_item);
8388 EOLIAN static Eina_Bool
8389 _elm_genlist_decorate_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8391 return sd->decorate_all_mode;
8395 _elm_genlist_decorate_mode_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool decorated)
8397 Elm_Object_Item *eo_it;
8400 decorated = !!decorated;
8401 if (sd->decorate_all_mode == decorated) return;
8402 // decorate_all_mode should be set first
8403 // because content_get func. will be called after this
8404 // and user can check whether deocrate_all_mode is enabeld.
8405 sd->decorate_all_mode = decorated;
8407 list = elm_genlist_realized_items_get(obj);
8408 EINA_LIST_FREE(list, eo_it)
8410 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8412 if (!sd->decorate_all_mode)
8414 _decorate_all_item_unrealize(it);
8416 else if (it->itc->decorate_all_item_style)
8418 _decorate_all_item_realize(it, EINA_TRUE);
8420 _access_widget_item_register(it);
8422 _changed(sd->pan_obj);
8426 _elm_genlist_reorder_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool reorder_mode)
8429 Elm_Object_Item *eo_it;
8431 if (sd->reorder_mode == !!reorder_mode) return;
8432 sd->reorder_mode = !!reorder_mode;
8434 list = elm_genlist_realized_items_get(obj);
8435 EINA_LIST_FREE(list, eo_it)
8437 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8438 if (sd->reorder_mode)
8440 edje_object_signal_emit
8441 (VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
8442 if (it->deco_all_view)
8443 edje_object_signal_emit
8444 (it->deco_all_view, SIGNAL_REORDER_MODE_SET, "elm");
8448 edje_object_signal_emit
8449 (VIEW(it), SIGNAL_REORDER_MODE_UNSET, "elm");
8450 if (it->deco_all_view)
8451 edje_object_signal_emit
8452 (it->deco_all_view, SIGNAL_REORDER_MODE_UNSET, "elm");
8457 EOLIAN static Eina_Bool
8458 _elm_genlist_reorder_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8460 return sd->reorder_mode;
8463 EOLIAN static Elm_Genlist_Item_Type
8464 _elm_genlist_item_type_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8466 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
8468 return GL_IT(it)->type;
8471 EAPI Elm_Genlist_Item_Class *
8472 elm_genlist_item_class_new(void)
8474 Elm_Genlist_Item_Class *itc = ELM_NEW(Elm_Genlist_Item_Class);
8475 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
8477 itc->version = CLASS_ALLOCATED;
8479 itc->delete_me = EINA_FALSE;
8480 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
8481 itc->homogeneous = EINA_FALSE;
8488 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
8490 if (itc && (itc->version == CLASS_ALLOCATED))
8492 itc->delete_me = EINA_TRUE;
8493 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
8503 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
8505 if (itc && (itc->version == CLASS_ALLOCATED))
8508 if (itc->refcount == 0) itc->refcount--;
8513 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
8515 if (itc && (itc->version == CLASS_ALLOCATED))
8517 if (itc->refcount > 0) itc->refcount--;
8518 if (itc->delete_me && (!itc->refcount))
8519 elm_genlist_item_class_free(itc);
8524 _elm_genlist_item_flip_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool flip)
8526 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8529 if (it->flipped == flip) return;
8534 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_content_objs,
8537 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
8538 if (GL_IT(it)->wsd->decorate_all_mode)
8539 edje_object_signal_emit
8540 (it->deco_all_view, SIGNAL_FLIP_ENABLED, "elm");
8545 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_DISABLED, "elm");
8546 if (GL_IT(it)->wsd->decorate_all_mode)
8547 edje_object_signal_emit
8548 (it->deco_all_view, SIGNAL_FLIP_DISABLED, "elm");
8550 EINA_LIST_FREE(GL_IT(it)->flip_content_objs, c)
8553 // FIXME: update texts should be done by app?
8554 _item_text_realize(it, VIEW(it), NULL);
8556 _access_widget_item_register(it);
8559 EOLIAN static Eina_Bool
8560 _elm_genlist_item_flip_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8562 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
8568 _elm_genlist_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Elm_Object_Select_Mode mode)
8570 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (sd->select_mode == mode))
8573 sd->select_mode = mode;
8575 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8576 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
8579 Elm_Object_Item *eo_it;
8580 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
8582 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8586 if (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
8589 EINA_INLIST_FOREACH(sd->items, it)
8591 if (!GL_IT(it)->block) continue;
8592 GL_IT(it)->calc_done = EINA_FALSE;
8593 GL_IT(it)->block->calc_done = EINA_FALSE;
8594 sd->calc_done = EINA_FALSE;
8595 _changed(sd->pan_obj);
8600 EOLIAN static Elm_Object_Select_Mode
8601 _elm_genlist_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8603 return sd->select_mode;
8607 _elm_genlist_highlight_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool highlight)
8609 sd->highlight = !!highlight;
8612 EOLIAN static Eina_Bool
8613 _elm_genlist_highlight_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8615 return sd->highlight;
8619 _elm_genlist_item_select_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8620 Elm_Object_Select_Mode mode)
8622 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8624 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (it->select_mode == mode))
8627 it->select_mode = mode;
8629 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8630 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
8633 if (GL_IT(it)->block && it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
8635 GL_IT(it)->calc_done = EINA_FALSE;
8636 GL_IT(it)->block->calc_done = EINA_FALSE;
8637 GL_IT(it)->wsd->calc_done = EINA_FALSE;
8638 _changed(GL_IT(it)->wsd->pan_obj);
8642 EOLIAN static Elm_Object_Select_Mode
8643 _elm_genlist_item_select_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8645 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
8647 return it->select_mode;
8650 EOLIAN Elm_Atspi_State_Set
8651 _elm_genlist_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_it, Elm_Gen_Item *it EINA_UNUSED)
8653 Elm_Atspi_State_Set ret;
8656 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
8658 eo_do(eo_it, sel = elm_obj_genlist_item_selected_get());
8660 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTABLE);
8663 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTED);
8665 if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_TREE)
8667 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDABLE);
8668 if (elm_genlist_item_expanded_get(eo_it))
8669 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8670 //TIZEN_ONLY(20160606): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8672 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8675 //TIZEN_ONLY(20160608): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8676 else if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_GROUP)
8678 if (elm_genlist_item_expanded_get(eo_it))
8679 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8681 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8689 _elm_genlist_item_elm_interface_atspi_accessible_name_get(Eo *eo_it,
8694 char *accessible_name;
8695 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_name_get());
8696 if (ret) return ret;
8698 buf = eina_strbuf_new();
8700 if (it->itc->func.text_get)
8706 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
8708 EINA_LIST_FREE(texts, key)
8710 char *str_markup = it->itc->func.text_get
8711 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
8712 char *str_utf8 = _elm_util_mkup_to_text(str_markup);
8716 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
8717 eina_strbuf_append(buf, str_utf8);
8723 accessible_name = eina_strbuf_string_steal(buf);
8724 eina_strbuf_free(buf);
8726 eina_stringshare_del(it->base->accessible_name);
8727 it->base->accessible_name = eina_stringshare_add(accessible_name);
8728 free(accessible_name);
8729 return it->base->accessible_name;
8733 _elm_genlist_item_elm_interface_atspi_accessible_children_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8735 Eina_List *ret = NULL;
8740 parts = elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "contents"));
8742 EINA_LIST_FREE(parts, key)
8745 part = edje_object_part_swallow_get(VIEW(it), key);
8746 if (part && eo_isa(part, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
8748 ret = eina_list_append(ret, part);
8749 eo_do(part, elm_interface_atspi_accessible_parent_set(eo_it));
8757 ///////////////////////////////////////////////////////////////////////////////
8758 //TIZEN ONLY:(20150623): Region show on item elements fixed
8759 //Grab and clear highlight on genlist items
8760 ///////////////////////////////////////////////////////////////////////////////
8761 EOLIAN static Eina_Bool
8762 _elm_genlist_item_elm_interface_atspi_component_highlight_grab(Eo *eo_it, Elm_Gen_Item *it)
8764 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8766 if (!TIZEN_PROFILE_WEARABLE)
8768 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
8769 eo_do_super(EO_OBJ(it), ELM_GENLIST_ITEM_CLASS, elm_interface_atspi_component_highlight_grab());
8774 // if item is realized check if in viewport
8777 Evas_Coord wy, wh, y, h;
8778 evas_object_geometry_get(WIDGET(it), NULL, &wy, NULL, &wh);
8779 evas_object_geometry_get(VIEW(it), NULL, &y, NULL, &h);
8780 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8781 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
8784 else // if item is not realized we should search if we are over or below viewport
8786 Eina_List *realized = elm_genlist_realized_items_get(WIDGET(it));
8789 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
8790 eina_list_free(realized);
8794 elm_object_accessibility_highlight_set(EO_OBJ(it), EINA_TRUE);
8795 ///TIZEN_ONLY(20170717) : expose highlight information on atspi
8796 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
8799 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
8800 // If you call eo_do_super, then you do NOT have to call smart callback.
8801 evas_object_smart_callback_call(WIDGET(it), "atspi,highlighted", EO_OBJ(it));
8808 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8809 sd->currently_highlighted_item = it;
8814 if (!TIZEN_PROFILE_WEARABLE)
8816 //TIZEN_ONLY(20170724): grab highlight using unrealized item
8817 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
8820 sd->atspi_item_to_highlight = it;//it will be highlighted when realized
8823 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8824 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
8830 EOLIAN static Eina_Bool
8831 _elm_genlist_item_elm_interface_atspi_component_highlight_clear(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8833 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8834 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8835 if(sd->currently_highlighted_item == it)
8836 sd->currently_highlighted_item = NULL;
8838 if (sd->atspi_item_to_highlight == it)
8839 sd->atspi_item_to_highlight = NULL;
8840 elm_object_accessibility_highlight_set(EO_OBJ(it), EINA_FALSE);
8841 ///TIZEN_ONLY(20170717) : expose highlight information on atspi
8842 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
8845 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8846 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
8848 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
8849 // If you call eo_do_super, then you do NOT have to call smart callback.
8850 evas_object_smart_callback_call(WIDGET(it), "atspi,unhighlighted", EO_OBJ(it));
8855 ///////////////////////////////////////////////////////////////////////////////
8858 _elm_genlist_tree_effect_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enabled EINA_UNUSED)
8860 // Need to implemented
8861 //sd->tree_effect_enabled = !!enabled;
8864 EOLIAN static Eina_Bool
8865 _elm_genlist_tree_effect_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
8871 _elm_genlist_focus_on_selection_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enabled)
8873 // Need to Implemented
8874 //sd->focus_on_selection_enabled = !!enabled;
8877 EOLIAN static Eina_Bool
8878 _elm_genlist_focus_on_selection_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
8880 // Need to Implemented
8881 //return sd->focus_on_selection_enabled;
8885 EAPI Elm_Object_Item *
8886 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth)
8888 Elm_Gen_Item *it = NULL;
8892 ELM_GENLIST_CHECK(obj) NULL;
8893 ELM_GENLIST_DATA_GET(obj, sd);
8895 if (!sd->items) return NULL;
8897 a = eina_inlist_accessor_new(sd->items);
8898 if (!a) return NULL;
8899 if (eina_accessor_data_get(a, nth, &data))
8900 it = ELM_GEN_ITEM_FROM_INLIST(data);
8901 eina_accessor_free(a);
8906 elm_genlist_fx_mode_set(Evas_Object *obj, Eina_Bool mode)
8908 ELM_GENLIST_CHECK(obj);
8909 ELM_GENLIST_DATA_GET(obj, sd);
8916 elm_genlist_fx_mode_get(const Evas_Object *obj)
8918 ELM_GENLIST_CHECK(obj) EINA_FALSE;
8919 ELM_GENLIST_DATA_GET(obj, sd);
8925 elm_genlist_item_hide_set(const Elm_Object_Item *eo_item EINA_UNUSED, Eina_Bool hide EINA_UNUSED)
8927 WRN("This API is deprecated, please use filter_set instead of this");
8931 elm_genlist_item_hide_get(const Elm_Object_Item *eo_item EINA_UNUSED)
8933 WRN("This API is deprecated, please use filter_set instead of this");
8937 ///////////////////////////////////////////////////////////////////////////////
8938 //TIZEN ONLY:(20150126): its not decided whether deprecated or not to give away
8939 ///////////////////////////////////////////////////////////////////////////////
8941 elm_genlist_realization_mode_set(Evas_Object *obj, Eina_Bool realization_mode)
8943 ELM_GENLIST_CHECK(obj);
8944 ELM_GENLIST_DATA_GET(obj, sd);
8946 if (sd->realization_mode == realization_mode) return;
8947 sd->realization_mode = realization_mode;
8951 elm_genlist_realization_mode_get(Evas_Object *obj)
8953 ELM_GENLIST_CHECK(obj) EINA_FALSE;
8954 ELM_GENLIST_DATA_GET(obj, sd);
8956 return sd->realization_mode;
8958 ///////////////////////////////////////////////////////////////////////////////
8961 elm_genlist_item_reorder_start(Elm_Object_Item *eo_item)
8963 ELM_GENLIST_ITEM_DATA_GET(eo_item, it);
8964 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8965 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
8967 sd->reorder.it = it;
8969 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8970 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
8971 (EINA_FALSE, EINA_FALSE));
8972 //sd->s_iface->hold_set(sd->obj, EINA_TRUE);
8973 //sd->s_iface->bounce_allow_set(sd->obj, EINA_FALSE, EINA_FALSE);
8974 sd->reorder_force = EINA_TRUE;
8978 elm_genlist_item_reorder_stop(Elm_Object_Item *eo_item)
8980 ELM_GENLIST_ITEM_DATA_GET(eo_item, it);
8981 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8982 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
8984 sd->reorder_force = EINA_FALSE;
8988 _elm_genlist_class_constructor(Eo_Class *klass)
8990 if (_elm_config->access_mode)
8991 _elm_genlist_smart_focus_next_enable = EINA_TRUE;
8993 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
8997 _elm_genlist_elm_interface_atspi_accessible_children_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8999 Eina_List *ret = NULL;
9002 EINA_INLIST_FOREACH(sd->items, it)
9003 ret = eina_list_append(ret, EO_OBJ(it));
9008 EOLIAN Elm_Atspi_State_Set
9009 _elm_genlist_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED)
9011 Elm_Atspi_State_Set ret;
9013 eo_do_super(obj, ELM_GENLIST_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
9015 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MANAGES_DESCENDANTS);
9017 if (elm_genlist_multi_select_get(obj))
9018 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MULTISELECTABLE);
9024 _elm_genlist_elm_interface_atspi_selection_selected_children_count_get(Eo *objm EINA_UNUSED, Elm_Genlist_Data *pd)
9026 return eina_list_count(pd->selected);
9030 _elm_genlist_elm_interface_atspi_selection_selected_child_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_idx)
9032 return eina_list_nth(pd->selected, child_idx);
9036 _elm_genlist_elm_interface_atspi_selection_child_select(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9039 if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
9041 EINA_INLIST_FOREACH(pd->items, item)
9043 if (child_index-- == 0)
9045 elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
9054 _elm_genlist_elm_interface_atspi_selection_selected_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9059 EINA_LIST_FOREACH(pd->selected, l, item)
9061 if (child_index-- == 0)
9063 elm_genlist_item_selected_set(item, EINA_FALSE);
9071 _elm_genlist_elm_interface_atspi_selection_is_child_selected(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9075 EINA_INLIST_FOREACH(pd->items, item)
9077 if (child_index-- == 0)
9079 return elm_genlist_item_selected_get(EO_OBJ(item));
9086 _elm_genlist_elm_interface_atspi_selection_all_children_select(Eo *obj, Elm_Genlist_Data *pd)
9090 if (!elm_genlist_multi_select_get(obj))
9093 EINA_INLIST_FOREACH(pd->items, item)
9094 elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
9100 _elm_genlist_elm_interface_atspi_selection_clear(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd)
9102 return _all_items_deselect(pd);
9106 _elm_genlist_elm_interface_atspi_selection_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9109 if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
9111 EINA_INLIST_FOREACH(pd->items, item)
9113 if (child_index-- == 0)
9115 elm_genlist_item_selected_set(EO_OBJ(item), EINA_FALSE);
9123 // TIZEN only (20150914) : Accessibility: updated highlight change during genlist and list scroll
9124 static int _is_item_in_viewport(int viewport_y, int viewport_h, int obj_y, int obj_h)
9126 if (obj_y + obj_h <= viewport_y)
9128 else if (obj_y >= viewport_y + viewport_h)
9134 _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)
9136 if (!_elm_atspi_enabled())
9138 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
9142 int old_x, old_y, delta_y;
9143 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_get(&old_x,&old_y));
9144 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
9145 delta_y = old_y - y;
9147 //check if highlighted item is genlist descendant
9148 Evas_Object * highlighted_obj = _elm_object_accessibility_currently_highlighted_get();
9149 if (eo_isa(highlighted_obj, ELM_WIDGET_ITEM_CLASS))
9151 Elm_Widget_Item_Data *id = eo_data_scope_get(highlighted_obj, ELM_WIDGET_ITEM_CLASS);
9152 highlighted_obj = id->view;
9155 Evas_Object * parent = highlighted_obj;
9156 if (eo_isa(highlighted_obj, ELM_WIDGET_CLASS))
9158 while ((parent = elm_widget_parent_get(parent)))
9162 else if (eo_isa(highlighted_obj, EDJE_OBJECT_CLASS))
9164 while ((parent = evas_object_smart_parent_get(parent)))
9168 // TIZEN_ONLY(20160805): set _accessibility_currently_highlighted_obj to NULL in object delete callback
9171 WRN("Improper highlighted object: %p", highlighted_obj);
9178 int obj_x, obj_y, w, h, hx, hy, hw, hh;
9179 evas_object_geometry_get(obj, &obj_x, &obj_y, &w, &h);
9181 evas_object_geometry_get(highlighted_obj, &hx, &hy, &hw, &hh);
9183 Elm_Gen_Item * next_previous_item = NULL;
9184 int viewport_position_result = _is_item_in_viewport(obj_y, h, hy, hh);
9185 //only highlight if move direction is correct
9186 //sometimes highlighted item is brought in and it does not fit viewport
9187 //however content goes to the viewport position so soon it will
9188 //meet _is_item_in_viewport condition
9189 if ((viewport_position_result < 0 && delta_y > 0) ||
9190 (viewport_position_result > 0 && delta_y < 0))
9193 Eina_List *realized_items = elm_genlist_realized_items_get(obj);
9196 Eina_Bool traverse_direction = viewport_position_result > 0;
9197 l = traverse_direction ? realized_items: eina_list_last(realized_items);
9201 item = eina_list_data_get(l);
9202 ELM_GENLIST_ITEM_DATA_GET(item, it_data);
9203 next_previous_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it_data));
9204 evas_object_geometry_get(VIEW(next_previous_item), &hx, &hy, &hw, &hh);
9205 if (_is_item_in_viewport(obj_y, h, hy, hh) == 0)
9208 next_previous_item = NULL;
9210 l = traverse_direction ? eina_list_next(l): eina_list_prev(l);
9213 if (next_previous_item)
9215 elm_object_accessibility_highlight_set(EO_OBJ(next_previous_item), EINA_TRUE);
9216 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(next_previous_item), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
9220 // Tizen only (20150914)
9221 #include "elm_genlist.eo.c"
9222 #include "elm_genlist_item.eo.c"