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 (it != sd->focused_item)
4040 if (sd->focused_item)
4041 _item_unfocused(sd->focused_item);
4042 _item_focused(it, sd->focus_scrollto_type);
4044 /* If item is not realized state, widget couldn't get focus_highlight data. */
4047 _elm_widget_item_highlight_in_theme(obj, EO_OBJ(it));
4048 _elm_widget_highlight_in_theme_update(obj);
4049 _elm_widget_focus_highlight_start(obj);
4055 if (!elm_widget_focus_get(obj))
4057 _item_unfocused(it);
4061 EOLIAN static Eina_Bool
4062 _elm_genlist_item_elm_widget_item_focus_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
4064 Evas_Object *obj = WIDGET(it);
4065 ELM_GENLIST_DATA_GET(obj, sd);
4067 if (it == sd->focused_item)
4073 EOLIAN static Elm_Object_Item*
4074 _elm_genlist_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
4076 return EO_OBJ(sd->focused_item);
4079 static Eina_Bool _elm_genlist_smart_focus_next_enable = EINA_FALSE;
4081 EOLIAN static Eina_Bool
4082 _elm_genlist_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
4084 return _elm_genlist_smart_focus_next_enable;
4087 EOLIAN static Eina_Bool
4088 _elm_genlist_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
4093 EOLIAN static Eina_Bool
4094 _elm_genlist_elm_widget_focus_next(Eo *obj, Elm_Genlist_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
4096 Eina_List *items = NULL;
4097 Item_Block *itb = NULL;
4098 Elm_Object_Item *eo_it = NULL;
4100 if (!sd->blocks) return EINA_FALSE;
4101 if (!sd->is_access) return EINA_FALSE;
4103 if (!elm_widget_highlight_get(obj))
4105 if (ELM_FOCUS_PREVIOUS == dir)
4107 eo_it = elm_genlist_last_item_get(obj);
4108 itb = EINA_INLIST_CONTAINER_GET(sd->blocks->last, Item_Block);
4110 else if (ELM_FOCUS_NEXT == dir)
4112 eo_it = elm_genlist_first_item_get(obj);
4113 itb = EINA_INLIST_CONTAINER_GET(sd->blocks, Item_Block);
4115 else return EINA_FALSE;
4117 if (eo_it && itb && itb->calc_done)
4119 _item_block_realize(itb, EINA_TRUE);
4120 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
4122 else return EINA_FALSE;
4125 // FIXME: do not use realized items get
4126 // because of above forcing realization case.
4127 EINA_INLIST_FOREACH(sd->blocks, itb)
4132 if (!itb->realized) continue;
4134 EINA_LIST_FOREACH(itb->items, l, it)
4137 Evas_Object *c, *ret;
4140 if (!(it->realized)) continue;
4142 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_access_object_get()))
4143 items = eina_list_append(items, eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_access_object_get()));
4145 items = eina_list_append(items, VIEW(it));
4147 orders = (Eina_List *)elm_object_item_access_order_get(EO_OBJ(it));
4148 EINA_LIST_FOREACH(orders, ll, c)
4150 items = eina_list_append(items, c);
4155 return elm_widget_focus_list_next_get
4156 (obj, items, eina_list_data_get, dir, next, next_item);
4160 _mirrored_set(Evas_Object *obj,
4163 eo_do(obj, elm_interface_scrollable_mirrored_set(rtl));
4166 EOLIAN static Elm_Theme_Apply
4167 _elm_genlist_elm_widget_theme_apply(Eo *obj, Elm_Genlist_Data *sd)
4170 Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
4171 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wsd, ELM_THEME_APPLY_FAILED);
4173 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
4174 if (!int_ret) return ELM_THEME_APPLY_FAILED;
4176 if (!TIZEN_PROFILE_WEARABLE)
4177 _banded_bg_state_check(obj, sd);
4179 EINA_INLIST_FOREACH(sd->blocks, itb)
4183 EINA_LIST_FOREACH(itb->items, l, it)
4187 _item_unrealize(it, EINA_FALSE);
4188 GL_IT(it)->calc_done = EINA_FALSE;
4189 GL_IT(it)->block->calc_done = EINA_FALSE;
4191 else _item_queue(it, NULL);
4194 sd->calc_done = EINA_FALSE;
4195 _item_cache_all_free(sd);
4196 eina_hash_free_buckets(sd->size_caches);
4197 elm_layout_sizing_eval(obj);
4198 _changed(sd->pan_obj);
4200 if (wsd->scroll_item_align_enable && sd->aligned_item)
4201 elm_genlist_item_show(EO_OBJ(sd->aligned_item), ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
4206 /* FIXME: take off later. maybe this show region coords belong in the
4207 * interface (new api functions, set/get)? */
4209 _show_region_hook(void *data,
4212 Evas_Coord x, y, w, h;
4214 ELM_GENLIST_DATA_GET(data, sd);
4216 elm_widget_show_region_get(obj, &x, &y, &w, &h);
4217 //x & y are screen coordinates, Add with pan coordinates
4221 eo_do(obj, elm_interface_scrollable_content_region_show(x, y, w, h));
4224 EOLIAN static Eina_Bool
4225 _elm_genlist_elm_widget_translate(Eo *obj, Elm_Genlist_Data *sd)
4229 // Before calling text_get, inform user first.
4230 evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
4232 // FIXME: We should change item's height if lang is changed??
4233 EINA_INLIST_FOREACH(sd->blocks, itb)
4237 EINA_LIST_FOREACH(itb->items, l, it)
4241 elm_genlist_item_fields_update(EO_OBJ(it),
4243 ELM_GENLIST_ITEM_FIELD_TEXT);
4245 else GL_IT(it)->calc_done = EINA_FALSE;
4247 itb->calc_done = EINA_FALSE;
4250 eina_hash_free_buckets(sd->size_caches);
4251 sd->calc_done = EINA_FALSE;
4257 _elm_genlist_elm_widget_item_loop_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enable EINA_UNUSED)
4259 // Need to be implemented
4260 //sd->item_loop_enable = !!enable;
4263 EOLIAN static Eina_Bool
4264 _elm_genlist_elm_widget_item_loop_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
4266 // Need to be implemented
4267 //return sd->item_loop_enable;
4272 _item_block_position_update(Eina_Inlist *list,
4277 EINA_INLIST_FOREACH(list, tmp)
4279 tmp->position = idx++;
4280 tmp->position_update = EINA_TRUE;
4285 _item_position_update(Eina_List *list,
4291 EINA_LIST_FOREACH(list, l, it)
4293 it->position = idx++;
4294 it->position_update = EINA_TRUE;
4299 _item_block_merge(Item_Block *left,
4305 EINA_LIST_FOREACH(right->items, l, it2)
4307 it2->item->block = left;
4309 left->calc_done = EINA_FALSE;
4311 left->items = eina_list_merge(left->items, right->items);
4315 _item_block_del(Elm_Gen_Item *it)
4317 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4319 Item_Block *itb = GL_IT(it)->block;
4320 Eina_Bool block_changed = EINA_FALSE;
4323 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
4324 (NULL, NULL, NULL, &vh));
4325 if (sd->processed_sizes >= vh) sd->processed_sizes = 0;
4327 itb->items = eina_list_remove(itb->items, it);
4329 itb->calc_done = EINA_FALSE;
4330 sd->calc_done = EINA_FALSE;
4331 _changed(sd->pan_obj);
4336 il = EINA_INLIST_GET(itb);
4337 itbn = (Item_Block *)(il->next);
4339 it->parent->item->items =
4340 eina_list_remove(it->parent->item->items, EO_OBJ(it));
4343 _item_block_position_update(il->next, itb->position);
4345 GL_IT(it)->wsd->blocks =
4346 eina_inlist_remove(GL_IT(it)->wsd->blocks, il);
4347 GL_IT(it)->wsd->blocks_realized = eina_list_remove
4348 (GL_IT(it)->wsd->blocks_realized, itb);
4351 if (itbn) itbn->calc_done = EINA_FALSE;
4355 if (itb->count < (itb->sd->max_items_per_block / 2))
4360 il = EINA_INLIST_GET(itb);
4361 itbp = (Item_Block *)(il->prev);
4362 itbn = (Item_Block *)(il->next);
4364 /* merge block with previous */
4366 ((itbp->count + itb->count) <
4367 (itb->sd->max_items_per_block +
4368 (itb->sd->max_items_per_block / 2))))
4370 _item_block_merge(itbp, itb);
4371 _item_block_position_update
4372 (EINA_INLIST_GET(itb)->next, itb->position);
4373 GL_IT(it)->wsd->blocks = eina_inlist_remove
4374 (GL_IT(it)->wsd->blocks, EINA_INLIST_GET(itb));
4375 GL_IT(it)->wsd->blocks_realized = eina_list_remove
4376 (GL_IT(it)->wsd->blocks_realized, itb);
4378 block_changed = EINA_TRUE;
4380 /* merge block with next */
4382 ((itbn->count + itb->count) <
4383 (itb->sd->max_items_per_block +
4384 (itb->sd->max_items_per_block / 2))))
4386 _item_block_merge(itb, itbn);
4387 _item_block_position_update
4388 (EINA_INLIST_GET(itbn)->next, itbn->position);
4389 GL_IT(it)->wsd->blocks =
4390 eina_inlist_remove(GL_IT(it)->wsd->blocks,
4391 EINA_INLIST_GET(itbn));
4392 GL_IT(it)->wsd->blocks_realized = eina_list_remove
4393 (GL_IT(it)->wsd->blocks_realized, itbn);
4395 block_changed = EINA_TRUE;
4402 _changed(sd->pan_obj);
4405 GL_IT(it)->block = NULL;
4409 _decorate_all_item_unrealize(Elm_Gen_Item *it)
4411 if (!it->deco_all_view) return;
4413 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
4414 _view_clear(it->deco_all_view, &(GL_IT(it)->deco_all_contents));
4415 evas_object_del(it->deco_all_view);
4416 it->deco_all_view = NULL;
4418 edje_object_signal_emit(VIEW(it), SIGNAL_DECORATE_DISABLED, "elm");
4420 _item_mouse_callbacks_add(it, VIEW(it));
4421 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
4426 _item_mouse_move_cb(void *data,
4427 Evas *evas EINA_UNUSED,
4431 Evas_Event_Mouse_Move *ev = event_info;
4432 Elm_Gen_Item *it = data;
4433 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4435 if (!it->down) return;
4437 if (((sd->reorder_force) || (sd->reorder_mode)) &&
4438 (sd->reorder.it == it) &&
4442 evas_object_geometry_get(sd->pan_obj, &ox, NULL, NULL, NULL);
4444 if ((ev->cur.canvas.y - it->dy) > GL_IT(it)->scrl_y)
4445 sd->reorder.dir = 1;
4446 else if ((ev->cur.canvas.y - it->dy) < GL_IT(it)->scrl_y)
4447 sd->reorder.dir = -1;
4449 GL_IT(it)->scrl_x = it->x + GL_IT(it)->block->x - sd->pan_x + ox;
4450 GL_IT(it)->scrl_y = ev->cur.canvas.y - it->dy;
4451 GL_IT(it)->w = sd->minw;
4452 GL_IT(it)->h = GL_IT(it)->minh;
4453 _changed(sd->pan_obj);
4456 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4458 if (GL_IT(it)->highlight_timer)
4460 ecore_timer_del(GL_IT(it)->highlight_timer);
4461 GL_IT(it)->highlight_timer = NULL;
4463 else if (!it->selected) _item_unhighlight(it, EINA_FALSE);
4467 ecore_timer_del(it->long_timer);
4468 it->long_timer = NULL;
4470 sd->on_hold = EINA_TRUE; /* for checking need to start select timer */
4472 //******************** TIZEN Only
4475 if (((sd->reorder_force) || (sd->reorder_mode)) &&
4476 (sd->reorder.it == it) && (!it->want_hidden))
4478 Evas_Coord x, y, w, h;
4479 evas_object_geometry_get(obj, &x, &y, &w, &h);
4480 if (ELM_RECTS_POINT_OUT(x, y, w, h, ev->cur.canvas.x, ev->cur.canvas.y))
4484 ecore_timer_del(it->long_timer);
4485 it->long_timer = NULL;
4487 if (GL_IT(it)->highlight_timer)
4489 ecore_timer_del(GL_IT(it)->highlight_timer);
4490 GL_IT(it)->highlight_timer = NULL;
4492 else if (!it->selected) _item_unhighlight(it, EINA_FALSE);
4495 //*******************************
4497 evas_object_ref(obj);
4501 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
4502 minw = GL_IT(it)->wsd->finger_minw;
4503 minh = GL_IT(it)->wsd->finger_minh;
4505 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4506 dx = ev->cur.canvas.x - x;
4507 dy = ev->cur.canvas.y - y;
4512 if (adx < 0) adx = -dx;
4513 if (ady < 0) ady = -dy;
4514 if ((adx > minw) || (ady > minh))
4516 it->dragging = EINA_TRUE;
4517 /* Genlist is scrolled vertically, so reduce left or right case for accuracy. */
4518 if (adx > (ady * 2))
4521 evas_object_smart_callback_call
4522 (WIDGET(it), SIG_DRAG_START_LEFT, EO_OBJ(it));
4524 evas_object_smart_callback_call
4525 (WIDGET(it), SIG_DRAG_START_RIGHT, EO_OBJ(it));
4530 evas_object_smart_callback_call
4531 (WIDGET(it), SIG_DRAG_START_UP, EO_OBJ(it));
4533 evas_object_smart_callback_call
4534 (WIDGET(it), SIG_DRAG_START_DOWN, EO_OBJ(it));
4539 /* If item magic value is changed, do not call smart callback*/
4540 if (EINA_MAGIC_CHECK(it->base, ELM_WIDGET_ITEM_MAGIC))
4543 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, EO_OBJ(it));
4546 evas_object_unref(obj);
4551 _long_press_cb(void *data)
4553 Elm_Gen_Item *it = data;
4554 Elm_Object_Item *eo_it2;
4555 Elm_Genlist_Data *sd;
4559 sd = GL_IT(it)->wsd;
4560 it->long_timer = NULL;
4562 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()) ||
4563 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
4564 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
4565 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
4566 (sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
4569 if ((sd->reorder_mode) &&
4570 (GL_IT(it)->type != ELM_GENLIST_ITEM_GROUP) &&
4571 (!sd->key_down_item))
4573 if (elm_genlist_item_expanded_get(EO_OBJ(it)))
4575 elm_genlist_item_expanded_set(EO_OBJ(it), EINA_FALSE);
4577 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it2)
4579 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
4580 _item_unselect(it2);
4583 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
4584 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
4585 (EINA_FALSE, EINA_FALSE));
4587 if (TIZEN_PROFILE_WEARABLE)
4590 if (sd->decorate_all_mode)
4591 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
4595 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
4598 sd->reorder.it = it;
4599 _changed(sd->pan_obj);
4601 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, EO_OBJ(it));
4604 it->long_timer = NULL;
4605 return ECORE_CALLBACK_CANCEL;
4609 _gesture_do(void *data)
4611 Elm_Genlist_Data *sd = data;
4613 if ((sd->g_item) && (sd->g_type))
4615 if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_LEFT))
4616 evas_object_smart_callback_call
4617 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_LEFT, EO_OBJ(sd->g_item));
4618 else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_RIGHT))
4619 evas_object_smart_callback_call
4620 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_RIGHT, EO_OBJ(sd->g_item));
4621 else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_UP))
4622 evas_object_smart_callback_call
4623 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_UP, EO_OBJ(sd->g_item));
4624 else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_DOWN))
4625 evas_object_smart_callback_call
4626 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_DOWN, EO_OBJ(sd->g_item));
4627 else if (!strcmp(sd->g_type, SIG_MULTI_PINCH_OUT))
4628 evas_object_smart_callback_call
4629 (WIDGET(sd->g_item), SIG_MULTI_PINCH_OUT, EO_OBJ(sd->g_item));
4630 else if (!strcmp(sd->g_type, SIG_MULTI_PINCH_IN))
4631 evas_object_smart_callback_call
4632 (WIDGET(sd->g_item), SIG_MULTI_PINCH_IN, EO_OBJ(sd->g_item));
4633 else if (!strcmp(sd->g_type, SIG_SWIPE))
4634 evas_object_smart_callback_call
4635 (WIDGET(sd->g_item), SIG_SWIPE, EO_OBJ(sd->g_item));
4643 _item_mouse_down_cb(void *data,
4648 Evas_Event_Mouse_Down *ev = event_info;
4649 Elm_Gen_Item *it = data;
4650 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4653 if (ev->event_flags & EVAS_EVENT_FLAG_ON_SCROLL)
4657 elm_genlist_item_reorder_stop(EO_OBJ(sd->reorder.it));
4658 sd->reorder.it = NULL;
4659 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
4660 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set(sd->h_bounce, sd->v_bounce));
4665 if (ev->button != 1) return;
4666 // mouse down is activate only one finger
4667 if (evas_event_down_count_get(evas) != 1) return;
4669 if (GL_IT(it)->highlight_timer)
4670 ecore_timer_del(GL_IT(it)->highlight_timer);
4671 // FIXME: To prevent timing issue about select and highlight
4672 else if (!sd->multi && sd->highlighted_item &&
4673 (GL_IT(sd->highlighted_item)->highlight_timer))
4676 it->down = EINA_TRUE;
4678 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4679 it->dx = ev->canvas.x - x;
4680 it->dy = ev->canvas.y - y;
4682 GL_IT(it)->wsd->was_selected = it->selected;
4683 GL_IT(it)->highlight_timer = ecore_timer_add(ELM_ITEM_HIGHLIGHT_TIMER,
4684 _highlight_timer, it);
4685 if (it->long_timer) ecore_timer_del(it->long_timer);
4686 it->long_timer = ecore_timer_add(sd->longpress_timeout, _long_press_cb, it);
4688 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
4690 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, EO_OBJ(it));
4691 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, EO_OBJ(it));
4693 evas_object_smart_callback_call(WIDGET(it), SIG_PRESSED, EO_OBJ(it));
4697 _item_block_new(Elm_Genlist_Data *sd,
4702 itb = calloc(1, sizeof(Item_Block));
4703 if (!itb) return NULL;
4707 sd->blocks = eina_inlist_prepend(sd->blocks, EINA_INLIST_GET(itb));
4708 _item_block_position_update(sd->blocks, 0);
4712 sd->blocks = eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4713 itb->position_update = EINA_TRUE;
4714 if (sd->blocks != EINA_INLIST_GET(itb))
4717 ((Item_Block *)(EINA_INLIST_GET(itb)->prev))->position + 1;
4729 _item_block_add(Elm_Genlist_Data *sd,
4732 Item_Block *itb = NULL;
4733 if (GL_IT(it)->block) return EINA_TRUE;
4735 if (!GL_IT(it)->rel)
4740 itb = calloc(1, sizeof(Item_Block));
4741 if (!itb) return EINA_FALSE;
4743 if (!GL_IT(it)->rel->item->block)
4746 eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4747 itb->items = eina_list_append(itb->items, it);
4748 itb->position_update = EINA_TRUE;
4749 it->position = eina_list_count(itb->items);
4750 it->position_update = EINA_TRUE;
4752 if (sd->blocks != EINA_INLIST_GET(itb))
4756 (EINA_INLIST_GET(itb)->prev))->position + 1;
4767 tmp = eina_list_data_find_list(itb->items, GL_IT(it)->rel);
4768 if (GL_IT(it)->before)
4770 sd->blocks = eina_inlist_prepend_relative
4771 (sd->blocks, EINA_INLIST_GET(itb),
4772 EINA_INLIST_GET(GL_IT(it)->rel->item->block));
4774 eina_list_prepend_relative_list(itb->items, it, tmp);
4776 /* Update index from where we prepended */
4777 _item_position_update
4778 (eina_list_prev(tmp), GL_IT(it)->rel->position);
4779 _item_block_position_update
4780 (EINA_INLIST_GET(itb),
4781 GL_IT(it)->rel->item->block->position);
4785 sd->blocks = eina_inlist_append_relative
4786 (sd->blocks, EINA_INLIST_GET(itb),
4787 EINA_INLIST_GET(GL_IT(it)->rel->item->block));
4789 eina_list_append_relative_list(itb->items, it, tmp);
4791 /* Update block index from where we appended */
4792 _item_position_update
4793 (eina_list_next(tmp), GL_IT(it)->rel->position + 1);
4794 _item_block_position_update
4795 (EINA_INLIST_GET(itb),
4796 GL_IT(it)->rel->item->block->position + 1);
4802 if (GL_IT(it)->before)
4806 itb = (Item_Block *)(sd->blocks);
4807 if (itb->count >= sd->max_items_per_block)
4809 itb = _item_block_new(sd, EINA_TRUE);
4810 if (!itb) return EINA_FALSE;
4815 itb = _item_block_new(sd, EINA_TRUE);
4816 if (!itb) return EINA_FALSE;
4818 itb->items = eina_list_prepend(itb->items, it);
4819 _item_position_update(itb->items, 1);
4825 itb = (Item_Block *)(sd->blocks->last);
4826 if (itb->count >= sd->max_items_per_block)
4828 itb = _item_block_new(sd, EINA_FALSE);
4829 if (!itb) return EINA_FALSE;
4834 itb = _item_block_new(sd, EINA_FALSE);
4835 if (!itb) return EINA_FALSE;
4837 itb->items = eina_list_append(itb->items, it);
4838 it->position = eina_list_count(itb->items);
4847 if ((!GL_IT(it)->wsd->sorting) && (GL_IT(it)->rel->item->queued))
4849 /* NOTE: for a strange reason eina_list and eina_inlist
4850 don't have the same property on sorted insertion
4851 order, so the queue is not always ordered like the
4852 item list. This lead to issue where we depend on an
4853 item that is not yet created. As a quick work around,
4854 we reschedule the calc of the item and stop reordering
4855 the list to prevent any nasty issue to show up here.
4857 sd->queue = eina_list_append(sd->queue, it);
4858 sd->requeued = EINA_TRUE;
4859 GL_IT(it)->queued = EINA_TRUE;
4864 itb = GL_IT(it)->rel->item->block;
4865 if (!itb) goto newblock;
4866 tmp = eina_list_data_find_list(itb->items, GL_IT(it)->rel);
4867 if (GL_IT(it)->before)
4869 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4870 _item_position_update
4871 (eina_list_prev(tmp), GL_IT(it)->rel->position);
4875 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4876 _item_position_update
4877 (eina_list_next(tmp), GL_IT(it)->rel->position + 1);
4882 itb->calc_done = EINA_FALSE;
4883 sd->calc_done = EINA_FALSE;
4884 GL_IT(it)->block = itb;
4885 _changed(itb->sd->pan_obj);
4887 if (itb->count > itb->sd->max_items_per_block)
4892 Eina_Bool done = EINA_FALSE;
4894 newc = itb->count / 2;
4896 if (EINA_INLIST_GET(itb)->prev)
4898 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4900 if (itbp->count + newc < sd->max_items_per_block / 2)
4902 /* moving items to previous block */
4903 while ((itb->count > newc) && (itb->items))
4905 it2 = eina_list_data_get(itb->items);
4906 itb->items = eina_list_remove_list
4907 (itb->items, itb->items);
4910 itbp->items = eina_list_append(itbp->items, it2);
4911 it2->item->block = itbp;
4919 if (!done && EINA_INLIST_GET(itb)->next)
4921 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4923 if (itbn->count + newc < sd->max_items_per_block / 2)
4925 /* moving items to next block */
4926 while ((itb->count > newc) && (itb->items))
4930 l = eina_list_last(itb->items);
4931 it2 = eina_list_data_get(l);
4932 itb->items = eina_list_remove_list(itb->items, l);
4935 itbn->items = eina_list_prepend(itbn->items, it2);
4936 it2->item->block = itbn;
4946 /* moving items to new block */
4947 itb2 = calloc(1, sizeof(Item_Block));
4948 if (!itb2) return EINA_FALSE;
4951 eina_inlist_append_relative(sd->blocks, EINA_INLIST_GET(itb2),
4952 EINA_INLIST_GET(itb));
4953 itb2->calc_done = EINA_FALSE;
4954 while ((itb->count > newc) && (itb->items))
4958 l = eina_list_last(itb->items);
4960 itb->items = eina_list_remove_list(itb->items, l);
4963 itb2->items = eina_list_prepend(itb2->items, it2);
4964 it2->item->block = itb2;
4974 _item_min_calc(Elm_Gen_Item *it)
4976 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4977 Evas_Coord mw = 0, mh = 0;
4980 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
4981 (NULL, NULL, &vw, NULL));
4983 if ((it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) &&
4984 (sd->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
4986 mw = sd->finger_minw;
4987 mh = sd->finger_minh;
4990 if ((sd->mode == ELM_LIST_COMPRESS) && vw && mw < vw)
4993 //FIXME: Some widget such as entry, label need to have fixed width size before
4994 // min calculation to get proper height size by multiline.
4995 if (sd->realization_mode || GL_IT(it)->resized)
4996 evas_object_resize(VIEW(it), mw, mh);
4998 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
5000 if ((sd->mode != ELM_LIST_LIMIT) && vw && mw < vw)
5003 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5004 if (sd->homogeneous || it->itc->homogeneous)
5006 Size_Cache *size, *tmp;
5007 tmp = eina_hash_find(sd->size_caches, it->itc->item_style);
5009 eina_hash_del_by_key(sd->size_caches, it->itc->item_style);
5011 size = ELM_NEW(Size_Cache);
5014 eina_hash_add(sd->size_caches, it->itc->item_style, size);
5017 GL_IT(it)->w = GL_IT(it)->minw = mw;
5018 GL_IT(it)->h = GL_IT(it)->minh = mh;
5020 // FIXME: This is workaround for entry size issue.
5021 if (sd->realization_mode || GL_IT(it)->resized)
5023 GL_IT(it)->resized = EINA_FALSE;
5024 if (it->deco_all_view)
5025 evas_object_resize(it->deco_all_view, GL_IT(it)->w, GL_IT(it)->h);
5026 else if (GL_IT(it)->deco_it_view)
5027 evas_object_resize(GL_IT(it)->deco_it_view, GL_IT(it)->w, GL_IT(it)->h);
5029 evas_object_resize(VIEW(it), GL_IT(it)->w, GL_IT(it)->h);
5035 _item_calc(Elm_Gen_Item *it)
5037 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5038 Size_Cache *size = NULL;
5039 Evas_Coord p_minw, p_minh;
5041 if (GL_IT(it)->calc_done) return;
5043 p_minw = GL_IT(it)->minw;
5044 p_minh = GL_IT(it)->minh;
5046 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5047 if (sd->homogeneous || it->itc->homogeneous)
5048 size = eina_hash_find(sd->size_caches, it->itc->item_style);
5051 GL_IT(it)->w = GL_IT(it)->minw = size->minw;
5052 GL_IT(it)->h = GL_IT(it)->minh = size->minh;
5058 if (sd->realization_mode)
5060 _item_realize(it, EINA_FALSE);
5065 _item_realize(it, EINA_TRUE);
5067 _item_unrealize(it, EINA_TRUE);
5074 GL_IT(it)->calc_done = EINA_TRUE;
5075 if ((p_minw != GL_IT(it)->minw) || (p_minh != GL_IT(it)->minh))
5077 GL_IT(it)->block->calc_done = EINA_FALSE;
5078 sd->calc_done = EINA_FALSE;
5083 _item_process(Elm_Genlist_Data *sd,
5086 if (!_item_block_add(sd, it)) return EINA_FALSE;
5088 GL_IT(it)->calc_done = EINA_FALSE;
5095 _dummy_job(void *data)
5097 Elm_Genlist_Data *sd = data;
5098 sd->dummy_job = NULL;
5103 _queue_idle_enter(void *data)
5105 Elm_Genlist_Data *sd = data;
5110 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
5111 (NULL, NULL, &vw, NULL));
5112 if (!sd->queue || (vw <= 1))
5116 ecore_job_del(sd->dummy_job);
5117 sd->dummy_job = NULL;
5119 sd->queue_idle_enterer = NULL;
5120 return ECORE_CALLBACK_CANCEL;
5123 ft = ecore_animator_frametime_get()/2;
5124 t0 = ecore_time_get();
5125 for (n = 0; (sd->queue) && (n < ITEM_QUEUE_MAX); n++)
5130 it = eina_list_data_get(sd->queue);
5131 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
5132 GL_IT(it)->queued = EINA_FALSE;
5133 GL_IT(it)->resized = EINA_FALSE;
5134 if (!_item_process(sd, it)) continue;
5135 t = ecore_time_get();
5136 /* same as eina_inlist_count > 1 */
5137 if (sd->blocks && sd->blocks->next)
5139 if ((t - t0) > ft) break;
5143 _changed(sd->pan_obj);
5148 ecore_job_del(sd->dummy_job);
5149 sd->dummy_job = NULL;
5151 sd->queue_idle_enterer = NULL;
5152 return ECORE_CALLBACK_CANCEL;
5155 // Do not use smart_changed
5156 // Instead make any events (job, idler, etc.) to call idle enterer
5157 if (sd->dummy_job) ecore_job_del(sd->dummy_job);
5158 sd->dummy_job = ecore_job_add(_dummy_job, sd);
5160 return ECORE_CALLBACK_RENEW;
5164 _item_queue(Elm_Gen_Item *it,
5165 Eina_Compare_Cb cb EINA_UNUSED)
5167 if (GL_IT(it)->queued) return;
5169 GL_IT(it)->queued = EINA_TRUE;
5170 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5172 // FIXME: Below code occurs item unsorted result.
5173 // genlist already calculate items position by sd->items
5174 // so no need to requeue items by sorting insert.
5175 // if (cb && !sd->requeued)
5176 // sd->queue = eina_list_sorted_insert(sd->queue, cb, it);
5178 sd->queue = eina_list_append(sd->queue, it);
5180 if (sd->queue_idle_enterer)
5181 ecore_idle_enterer_del(sd->queue_idle_enterer);
5182 sd->queue_idle_enterer = ecore_idle_enterer_add(_queue_idle_enter, sd);
5186 _item_queue_direct(Elm_Gen_Item *it,
5189 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5191 // Processing items within viewport if items already exist.
5192 // This can prevent flickering issue when content size is changed.
5193 // This can fix the flickering issue when expanded item have subitems whose total height > vh
5194 if (!sd->queue && (sd->viewport_w > 1) &&
5195 ((sd->processed_sizes <= sd->viewport_h) || (GL_IT(it)->expanded_depth > 0)))
5197 #ifdef GENLIST_FX_SUPPORT
5198 if (sd->fx_mode)// && !it->item->is_prepend) // For support preppended items - hs619.choi@samsung.com
5200 sd->add_fx.items = eina_list_append(sd->add_fx.items, it);
5201 if (!sd->add_fx.anim)
5203 sd->add_fx.cnt = ANIM_CNT_MAX;
5204 sd->add_fx.anim = ecore_animator_add(_add_fx_anim, sd);
5208 _item_process(sd, it);
5209 sd->processed_sizes += GL_IT(it)->minh;
5211 _changed(sd->pan_obj);
5214 _item_queue(it, cb);
5217 /* If the application wants to know the relative item, use
5218 * elm_genlist_item_prev_get(it)*/
5220 _item_move_after(Elm_Gen_Item *it,
5221 Elm_Gen_Item *after)
5225 if (it == after) return;
5227 GL_IT(it)->wsd->items =
5228 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
5229 if (GL_IT(it)->block) _item_block_del(it);
5231 GL_IT(it)->wsd->items = eina_inlist_append_relative
5232 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
5235 GL_IT(it)->rel->item->rel_revs =
5236 eina_list_remove(GL_IT(it)->rel->item->rel_revs, it);
5237 GL_IT(it)->rel = after;
5238 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
5239 GL_IT(it)->before = EINA_FALSE;
5240 if (after->item->group_item) GL_IT(it)->group_item = after->item->group_item;
5242 if (GL_IT(it)->queued)
5244 GL_IT(it)->wsd->queue = eina_list_remove(GL_IT(it)->wsd->queue, it);
5245 GL_IT(it)->queued = EINA_FALSE;
5247 _item_queue_direct(it, NULL);
5249 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, EO_OBJ(it));
5252 /* If the application wants to know the relative item, use
5253 * elm_genlist_item_next_get(it)*/
5255 _item_move_before(Elm_Gen_Item *it,
5256 Elm_Gen_Item *before)
5259 if (!before) return;
5260 if (it == before) return;
5262 GL_IT(it)->wsd->items =
5263 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
5264 if (GL_IT(it)->block) _item_block_del(it);
5265 GL_IT(it)->wsd->items = eina_inlist_prepend_relative
5266 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
5269 GL_IT(it)->rel->item->rel_revs =
5270 eina_list_remove(GL_IT(it)->rel->item->rel_revs, it);
5271 GL_IT(it)->rel = before;
5272 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
5273 GL_IT(it)->before = EINA_TRUE;
5274 if (before->item->group_item)
5275 GL_IT(it)->group_item = before->item->group_item;
5276 _item_queue_direct(it, NULL);
5278 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, EO_OBJ(it));
5282 _item_mouse_up_cb(void *data,
5284 Evas_Object *obj EINA_UNUSED,
5287 Evas_Event_Mouse_Up *ev = event_info;
5288 Elm_Gen_Item *it = data;
5289 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5291 ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd);
5293 if (!it->down) return;
5294 it->down = EINA_FALSE;
5296 if (ev->button != 1) return;
5300 it->dragging = EINA_FALSE;
5301 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, EO_OBJ(it));
5303 // When the event is cancelled, need to initialize mouse flags and timers.
5304 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = EINA_TRUE;
5308 if (evas_event_down_count_get(evas) != 0)
5310 if (!GL_IT(it)->highlight_timer) _item_unhighlight(it, EINA_TRUE);
5315 ecore_timer_del(it->long_timer);
5316 it->long_timer = NULL;
5318 if (GL_IT(it)->highlight_timer)
5320 ecore_timer_del(GL_IT(it)->highlight_timer);
5321 GL_IT(it)->highlight_timer = NULL;
5322 // Because naviframe can drop the all evevents.
5323 // highlight it before select timer is called.
5324 if (evas_event_down_count_get(evas) == 0) _item_highlight(it);
5327 if (!sd->reorder.it && (evas_event_down_count_get(evas) == 0))
5329 // FIXME: if highlight mode is not used, mouse move cannot disable
5331 if ((sd->was_selected == it->selected) && (!sd->on_hold))
5333 if (wd->scroll_item_align_enable)
5335 const char *align = edje_object_data_get(VIEW(it), "align");
5336 if (!align || strcmp(align, "off"))
5338 if (it != sd->aligned_item)
5340 elm_genlist_item_bring_in(EO_OBJ(it), ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
5344 if (((sd->highlight && it->highlighted) || !sd->highlight) &&
5345 ((!wd->scroll_item_align_enable) || (it == sd->aligned_item)))
5346 GL_IT(it)->highlight_timer =
5347 ecore_timer_add(ITEM_SELECT_TIMER, _select_timer, it);
5348 else if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
5349 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
5352 Evas_Object *content;
5353 if (sd->focused_item != it)
5354 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
5356 sd->focused_content = NULL;
5357 EINA_LIST_FOREACH(it->content_objs, l, content)
5359 if (elm_widget_focused_object_get(content))
5360 sd->focused_content = content;
5365 else if (sd->reorder.it == it)
5367 if (TIZEN_PROFILE_WEARABLE)
5369 Elm_Gen_Item *it2, *it_max = NULL, *it_min = NULL;
5370 Evas_Coord r_y_scrl, it_y_max = -99999999, it_y_min = 99999999;
5372 if (!it->selected) _item_unhighlight(it, EINA_TRUE);
5373 r_y_scrl = GL_IT(it)->scrl_y;
5374 EINA_LIST_FREE(sd->reorder.move_items, it2)
5376 if (sd->reorder.it->parent != it2->parent)
5378 it2->item->reorder_offset = 0;
5381 Evas_Coord it_y = it2->item->scrl_y +
5382 it2->item->reorder_offset + (it2->item->h / 2) +
5383 it2->item->block->y;
5385 if ((it_y < r_y_scrl) &&
5391 else if ((it_y > r_y_scrl) &&
5397 it2->item->reorder_offset = 0;
5401 _item_move_after(it, it_max);
5402 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5406 _item_move_before(it, it_min);
5407 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5413 Elm_Gen_Item *moved_it = NULL;
5414 Elm_Gen_Item *ptr_it = sd->top_drawn_item;
5415 Elm_Gen_Item *last_it = NULL;
5416 Eina_Bool after = EINA_TRUE;
5418 if (!it->selected) _item_unhighlight(it, EINA_FALSE);
5424 if (ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y, GL_IT(it)->w, GL_IT(it)->h,
5425 GL_IT(ptr_it)->scrl_x, GL_IT(ptr_it)->scrl_y, GL_IT(ptr_it)->w, GL_IT(ptr_it)->h))
5427 if (GL_IT(it)->scrl_y < GL_IT(ptr_it)->scrl_y)
5434 if ((GL_IT(it)->scrl_y + GL_IT(it)->h) > (GL_IT(ptr_it)->scrl_y + GL_IT(ptr_it)->h))
5436 if ((GL_IT(it)->scrl_y + GL_IT(it)->h) == GL_IT(ptr_it)->scrl_y)
5444 ptr_it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(ptr_it)->next);
5449 if (GL_IT(it)->scrl_y > GL_IT(last_it)->scrl_y + GL_IT(last_it)->h)
5453 moved_it = sd->top_drawn_item;
5458 EINA_LIST_FREE(sd->reorder.move_items, ptr_it)
5460 ptr_it->item->reorder_offset = 0;
5465 _item_move_after(it, moved_it);
5466 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5470 _item_move_before(it, moved_it);
5471 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5474 sd->reorder.it = NULL;
5475 sd->reorder.dir = 0;
5476 if (sd->reorder.anim)
5478 ecore_animator_del(sd->reorder.anim);
5479 sd->reorder.anim = NULL;
5482 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5483 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
5484 (sd->h_bounce, sd->v_bounce));
5486 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_DISABLED, "elm");
5487 _changed(sd->pan_obj);
5489 sd->on_hold = EINA_FALSE; /* for checking need to start select timer */
5490 evas_object_smart_callback_call(WIDGET(it), SIG_RELEASED, EO_OBJ(it));
5494 _scroll_hold_timer_cb(void *data)
5496 Elm_Genlist_Data *sd = data;
5497 sd->scr_hold_timer = NULL;
5499 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5501 return ECORE_CALLBACK_CANCEL;
5505 _decorate_item_finished_signal_cb(void *data,
5507 const char *emission EINA_UNUSED,
5508 const char *source EINA_UNUSED)
5510 Elm_Gen_Item *it = data;
5512 if (!data || !obj) return;
5513 if ((!it->realized)) return;
5515 _decorate_item_unrealize(it);
5519 _item_update(Elm_Gen_Item *it)
5522 if (!it->realized) return;
5524 _view_clear(VIEW(it), &(it->content_objs));
5525 EINA_LIST_FREE(GL_IT(it)->flip_content_objs, c)
5527 _view_clear(GL_IT(it)->deco_it_view, &(GL_IT(it)->deco_it_contents));
5528 _view_clear(it->deco_all_view, &(GL_IT(it)->deco_all_contents));
5530 _view_inflate(VIEW(it), it, &(it->content_objs));
5533 _item_content_realize(it, VIEW(it), &(GL_IT(it)->flip_content_objs),
5535 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
5537 if (GL_IT(it)->wsd->decorate_all_mode)
5538 _view_inflate(it->deco_all_view, it, &(GL_IT(it)->deco_all_contents));
5539 else if (GL_IT(it)->deco_it_view)
5540 _view_inflate(GL_IT(it)->deco_it_view, it, &(GL_IT(it)->deco_it_contents));
5542 if (!TIZEN_PROFILE_WEARABLE)
5543 _banded_item_bg_add(it, VIEW(it));
5546 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
5548 if (GL_IT(it)->wsd->aligned_item == it)
5549 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
5551 edje_object_message_signal_process(VIEW(it));
5555 _item_block_calc(Item_Block *itb, Evas_Coord vw EINA_UNUSED, Evas_Coord vh)
5559 Evas_Coord minw = 9999999, minh = 0;
5560 int sum_item_height = 0;
5561 ELM_WIDGET_DATA_GET_OR_RETURN(itb->sd->obj, wsd);
5563 if (itb->calc_done) return;
5565 EINA_LIST_FOREACH(itb->items, l, it)
5567 if (it->want_hidden) continue;
5568 if (GL_IT(it)->updateme)
5574 GL_IT(it)->calc_done = EINA_FALSE;
5575 GL_IT(it)->updateme = EINA_FALSE;
5577 if (!GL_IT(it)->queued) _item_calc(it);
5579 if (wsd->scroll_item_align_enable)
5581 int vcenter = vh / 2;
5582 int icenter = GL_IT(it)->h / 2;
5583 if ((itb->y + sum_item_height < vcenter && itb->y + sum_item_height + GL_IT(it)->h > vcenter) &&
5584 (sum_item_height + icenter < vcenter - 1 || sum_item_height + icenter > vcenter + 1))
5586 int first_item_height = sum_item_height = vcenter - icenter;
5588 Elm_Object_Item *eo_prev = elm_genlist_item_prev_get(EO_OBJ(it));
5589 Elm_Gen_Item *prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
5592 minh = sum_item_height;
5595 if (eo_prev == elm_genlist_first_item_get(wsd->obj))
5597 GL_IT(prev)->h = GL_IT(prev)->minh = first_item_height;
5600 first_item_height -= GL_IT(prev)->h;
5601 prev->y = first_item_height;
5602 eo_prev = elm_genlist_item_prev_get(eo_prev);
5603 prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
5606 sum_item_height += GL_IT(it)->h;
5611 if (minw > GL_IT(it)->minw) minw = GL_IT(it)->minw;
5612 minh += GL_IT(it)->minh;
5613 if (GL_IT(it)->is_prepend)
5615 itb->sd->comp_y += GL_IT(it)->minh;
5616 GL_IT(it)->is_prepend = EINA_FALSE;
5621 itb->calc_done = EINA_TRUE;
5622 itb->position_update = EINA_FALSE;
5626 _scroll_animate_start_cb(Evas_Object *obj,
5627 void *data EINA_UNUSED)
5629 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5630 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
5634 _scroll_animate_stop_cb(Evas_Object *obj,
5635 void *data EINA_UNUSED)
5637 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5638 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
5640 //TIZEN_ONLY: Let the screen-reader know when scroll animation ends
5641 if (_elm_atspi_enabled())
5643 elm_interface_atspi_accessible_visible_data_changed_signal_emit(obj);
5649 _scroll_drag_start_cb(Evas_Object *obj,
5650 void *data EINA_UNUSED)
5652 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5653 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
5657 _scroll_timeout_cb(void *data)
5659 Elm_Genlist_Data *sd = data;
5661 sd->scr_timer = NULL;
5662 if (sd->queue && !sd->queue_idle_enterer)
5664 sd->queue_idle_enterer = ecore_idle_enterer_add(_queue_idle_enter, sd);
5665 if (sd->dummy_job) ecore_job_del(sd->dummy_job);
5666 sd->dummy_job = ecore_job_add(_dummy_job, sd);
5668 return ECORE_CALLBACK_CANCEL;
5672 _scroll_cb(Evas_Object *obj,
5673 void *data EINA_UNUSED)
5675 ELM_GENLIST_DATA_GET(obj, sd);
5677 if (sd->queue_idle_enterer)
5679 ecore_idle_enterer_del(sd->queue_idle_enterer);
5680 sd->queue_idle_enterer = NULL;
5683 ecore_job_del(sd->dummy_job);
5684 sd->dummy_job = NULL;
5687 if (sd->scr_timer) ecore_timer_del(sd->scr_timer);
5688 sd->scr_timer = ecore_timer_add(0.25, _scroll_timeout_cb, sd);
5690 evas_object_smart_callback_call(obj, SIG_SCROLL, NULL);
5694 _scroll_drag_stop_cb(Evas_Object *obj,
5695 void *data EINA_UNUSED)
5697 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_STOP, NULL);
5698 //TIZEN_ONLY: Let the screen-reader know when drag ends
5699 if (_elm_atspi_enabled())
5701 elm_interface_atspi_accessible_visible_data_changed_signal_emit(obj);
5707 _edge_left_cb(Evas_Object *obj,
5708 void *data EINA_UNUSED)
5710 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
5714 _edge_right_cb(Evas_Object *obj,
5715 void *data EINA_UNUSED)
5717 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
5721 _edge_top_cb(Evas_Object *obj,
5722 void *data EINA_UNUSED)
5724 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
5728 _edge_bottom_cb(Evas_Object *obj,
5729 void *data EINA_UNUSED)
5731 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
5735 _vbar_drag_cb(Evas_Object *obj,
5736 void *data EINA_UNUSED)
5738 evas_object_smart_callback_call(obj, SIG_VBAR_DRAG, NULL);
5742 _vbar_press_cb(Evas_Object *obj,
5743 void *data EINA_UNUSED)
5745 evas_object_smart_callback_call(obj, SIG_VBAR_PRESS, NULL);
5749 _vbar_unpress_cb(Evas_Object *obj,
5750 void *data EINA_UNUSED)
5752 evas_object_smart_callback_call(obj, SIG_VBAR_UNPRESS, NULL);
5756 _hbar_drag_cb(Evas_Object *obj,
5757 void *data EINA_UNUSED)
5759 evas_object_smart_callback_call(obj, SIG_HBAR_DRAG, NULL);
5763 _hbar_press_cb(Evas_Object *obj,
5764 void *data EINA_UNUSED)
5766 evas_object_smart_callback_call(obj, SIG_HBAR_PRESS, NULL);
5770 _hbar_unpress_cb(Evas_Object *obj,
5771 void *data EINA_UNUSED)
5773 evas_object_smart_callback_call(obj, SIG_HBAR_UNPRESS, NULL);
5777 _decorate_item_realize(Elm_Gen_Item *it)
5780 if (GL_IT(it)->deco_it_view || !it->itc->decorate_item_style) return;
5782 // Before adding & swallowing, delete it from smart member
5783 evas_object_smart_member_del(VIEW(it));
5785 GL_IT(it)->deco_it_view = _view_create(it, it->itc->decorate_item_style);
5786 edje_object_part_swallow
5787 (GL_IT(it)->deco_it_view,
5788 edje_object_data_get(GL_IT(it)->deco_it_view, "mode_part"), VIEW(it));
5789 _view_inflate(GL_IT(it)->deco_it_view, it, &(GL_IT(it)->deco_it_contents));
5791 snprintf(buf, sizeof(buf), "elm,state,%s,active",
5792 GL_IT(it)->wsd->decorate_it_type);
5793 edje_object_signal_emit(GL_IT(it)->deco_it_view, buf, "elm");
5794 edje_object_signal_emit(VIEW(it), buf, "elm");
5796 _item_mouse_callbacks_add(it, GL_IT(it)->deco_it_view);
5798 _item_mouse_callbacks_del(it, VIEW(it));
5802 // FIXME: difference from upstream
5804 _mouse_down_scroller(void *data,
5805 Evas *evas EINA_UNUSED,
5806 Evas_Object *obj EINA_UNUSED,
5807 void *event_info EINA_UNUSED)
5809 Widget_Data *wd = elm_widget_data_get(data);
5812 wd->drag_started = EINA_FALSE;
5816 _mouse_up_scroller(void *data,
5817 Evas *evas EINA_UNUSED,
5818 Evas_Object *obj EINA_UNUSED,
5819 void *event_info EINA_UNUSED)
5821 Widget_Data *wd = elm_widget_data_get(data);
5824 wd->drag_started = EINA_FALSE;
5828 _mouse_move_scroller(void *data,
5829 Evas *evas EINA_UNUSED,
5830 Evas_Object *obj EINA_UNUSED,
5833 Widget_Data *wd = elm_widget_data_get(data);
5834 Evas_Event_Mouse_Move *ev = event_info;
5835 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
5838 if (wd->drag_started) return;
5840 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
5841 dx = ev->cur.canvas.x - ev->prev.canvas.x;
5842 dy = ev->cur.canvas.y - ev->prev.canvas.y;
5845 if (adx < 0) adx = -dx;
5846 if (ady < 0) ady = -dy;
5847 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
5851 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
5852 wd->drag_started = EINA_TRUE;
5856 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
5857 wd->drag_started = EINA_TRUE;
5864 _size_cache_free(void *data)
5866 if (data) free(data);
5869 static Evas_Event_Flags
5870 _pinch_zoom_start_cb(void *data, void *event_info)
5872 Elm_Genlist_Data *sd = data;
5873 Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
5874 Elm_Object_Item *eo_it;
5876 eo_it = elm_genlist_at_xy_item_get(sd->obj, p->x, p->y, NULL);
5877 sd->g_item = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
5878 return EVAS_EVENT_FLAG_NONE;
5881 static Evas_Event_Flags
5882 _pinch_zoom_cb(void *data, void *event_info)
5884 Elm_Genlist_Data *sd = data;
5885 Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
5887 if (p->zoom > 1.0 + PINCH_ZOOM_TOLERANCE)
5888 sd->g_type = SIG_MULTI_PINCH_OUT;
5889 else if (p->zoom < 1.0 - PINCH_ZOOM_TOLERANCE)
5890 sd->g_type = SIG_MULTI_PINCH_IN;
5892 return EVAS_EVENT_FLAG_NONE;
5895 static Evas_Event_Flags
5896 _gesture_n_lines_start_cb(void *data , void *event_info)
5898 Elm_Genlist_Data *sd = data;
5899 Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5901 Elm_Object_Item *eo_it;
5903 x = (p->momentum.x1 + p->momentum.x2) / 2;
5904 y = (p->momentum.y1 + p->momentum.y2) / 2;
5906 eo_it = elm_genlist_at_xy_item_get(sd->obj, x, y, NULL);
5907 sd->g_item = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
5908 return EVAS_EVENT_FLAG_NONE;
5911 static Evas_Event_Flags
5912 _gesture_n_lines_cb(void *data , void *event_info)
5914 Elm_Genlist_Data *sd = data;
5915 Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5917 if (p->momentum.n < 2)
5918 return EVAS_EVENT_FLAG_NONE;
5920 Evas_Coord minw = 0, minh = 0;
5921 Evas_Coord x, y, off_x, off_y;
5922 Evas_Coord cur_x, cur_y, prev_x, prev_y;
5923 Elm_Gen_Item *down_it;
5924 Elm_Object_Item *eo_down_it;
5926 minw = sd->finger_minw;
5927 minh = sd->finger_minh;
5929 prev_x = prev_y = 0;
5931 cur_x = p->momentum.x1;
5932 cur_y = p->momentum.y1;
5934 eo_down_it = elm_genlist_at_xy_item_get(sd->obj, cur_x, cur_y, NULL);
5935 down_it = eo_data_scope_get(eo_down_it, ELM_GENLIST_ITEM_CLASS);
5938 evas_object_geometry_get(VIEW(down_it), &x, &y, NULL, NULL);
5939 prev_x = down_it->dx + x;
5940 prev_y = down_it->dy + y;
5942 off_x = abs(cur_x - prev_x);
5943 off_y = abs(cur_y - prev_y);
5945 if ((off_x > minw) || (off_y > minh))
5950 sd->g_type = SIG_MULTI_SWIPE_RIGHT;
5952 sd->g_type = SIG_MULTI_SWIPE_LEFT;
5957 sd->g_type = SIG_MULTI_SWIPE_DOWN;
5959 sd->g_type = SIG_MULTI_SWIPE_UP;
5963 return EVAS_EVENT_FLAG_NONE;
5966 static Evas_Event_Flags
5967 _gesture_n_flicks_cb(void *data , void *event_info)
5969 Elm_Genlist_Data *sd = data;
5970 Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5972 if (p->momentum.n == 1)
5973 sd->g_type = SIG_SWIPE;
5975 return EVAS_EVENT_FLAG_NONE;
5979 _elm_genlist_evas_object_smart_del(Eo *obj, Elm_Genlist_Data *sd)
5981 sd->no_cache = EINA_TRUE;
5982 elm_genlist_clear(obj);
5983 evas_event_callback_del_full(evas_object_evas_get(obj),
5984 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
5985 _evas_viewport_resize_cb, sd);
5986 if (sd->size_caches) eina_hash_free(sd->size_caches);
5987 if (sd->decorate_it_type) eina_stringshare_del(sd->decorate_it_type);
5988 if (sd->clipee) evas_object_del(sd->clipee);
5990 evas_object_del(sd->pan_obj);
5991 eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
5995 _elm_genlist_evas_object_smart_move(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y)
5997 Evas_Coord ox, oy, bg_x, bg_y;
5999 if (!TIZEN_PROFILE_WEARABLE)
6001 evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
6002 evas_object_geometry_get(sd->banded_bg_rect, &bg_x, &bg_y, NULL, NULL);
6005 eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
6006 evas_object_move(sd->hit_rect, x, y);
6008 if (!TIZEN_PROFILE_WEARABLE)
6009 evas_object_move(sd->banded_bg_rect, (bg_x + x - ox), (bg_y + y - oy));
6013 _elm_genlist_evas_object_smart_resize(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord w, Evas_Coord h)
6015 eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
6017 evas_object_resize(sd->hit_rect, w, h);
6021 _elm_genlist_evas_object_smart_member_add(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *member)
6023 eo_do_super(obj, MY_CLASS, evas_obj_smart_member_add(member));
6026 evas_object_raise(sd->hit_rect);
6031 _elm_genlist_elm_widget_access(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool acs)
6034 Elm_Object_Item *eo_it;
6036 l = elm_genlist_realized_items_get(obj);
6038 EINA_LIST_FREE(l, eo_it)
6040 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6041 _item_unrealize(it, EINA_FALSE);
6044 sd->is_access = acs;
6046 _changed(sd->pan_obj);
6047 evas_object_smart_callback_call(obj, SIG_ACCESS_CHANGED, NULL);
6051 _evas_viewport_resize_cb(void *d, Evas *e EINA_UNUSED, void *ei EINA_UNUSED)
6053 Elm_Genlist_Data *priv = d;
6054 _changed(priv->pan_obj);
6058 _elm_genlist_evas_object_smart_add(Eo *obj, Elm_Genlist_Data *priv)
6060 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
6061 Evas_Coord minw, minh;
6062 Elm_Genlist_Pan_Data *pan_data;
6064 eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
6065 elm_widget_sub_object_parent_add(obj);
6067 priv->finger_minw = 0;
6068 priv->finger_minh = 0;
6069 elm_coords_finger_size_adjust(1, &priv->finger_minw, 1, &priv->finger_minh);
6071 priv->size_caches = eina_hash_string_small_new(_size_cache_free);
6072 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
6073 evas_object_smart_member_add(priv->hit_rect, obj);
6074 elm_widget_sub_object_add(obj, priv->hit_rect);
6076 /* common scroller hit rectangle setup */
6077 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
6078 evas_object_show(priv->hit_rect);
6079 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
6081 elm_widget_can_focus_set(obj, EINA_TRUE);
6082 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
6084 elm_layout_theme_set(obj, "genlist", "base", elm_widget_style_get(obj));
6086 if (!TIZEN_PROFILE_WEARABLE)
6087 _banded_bg_state_check(obj, priv);
6089 /* interface's add() routine issued AFTER the object's smart_add() */
6090 eo_do(obj, elm_interface_scrollable_objects_set(wd->resize_obj, priv->hit_rect));
6092 eo_do(obj, elm_interface_scrollable_bounce_allow_set
6093 (EINA_FALSE, _elm_config->thumbscroll_bounce_enable));
6094 priv->v_bounce = _elm_config->thumbscroll_bounce_enable;
6097 elm_interface_scrollable_animate_start_cb_set(_scroll_animate_start_cb),
6098 elm_interface_scrollable_animate_stop_cb_set(_scroll_animate_stop_cb),
6099 elm_interface_scrollable_scroll_cb_set(_scroll_cb),
6100 elm_interface_scrollable_drag_start_cb_set(_scroll_drag_start_cb),
6101 elm_interface_scrollable_drag_stop_cb_set(_scroll_drag_stop_cb),
6102 elm_interface_scrollable_edge_left_cb_set(_edge_left_cb),
6103 elm_interface_scrollable_edge_right_cb_set(_edge_right_cb),
6104 elm_interface_scrollable_edge_top_cb_set(_edge_top_cb),
6105 elm_interface_scrollable_edge_bottom_cb_set(_edge_bottom_cb),
6106 elm_interface_scrollable_vbar_drag_cb_set(_vbar_drag_cb),
6107 elm_interface_scrollable_vbar_press_cb_set(_vbar_press_cb),
6108 elm_interface_scrollable_vbar_unpress_cb_set(_vbar_unpress_cb),
6109 elm_interface_scrollable_hbar_drag_cb_set(_hbar_drag_cb),
6110 elm_interface_scrollable_hbar_press_cb_set(_hbar_press_cb),
6111 elm_interface_scrollable_hbar_unpress_cb_set(_hbar_unpress_cb));
6113 eo_do(obj, elm_interface_scrollable_content_min_limit_cb_set(_elm_genlist_content_min_limit_cb));
6115 priv->mode = ELM_LIST_SCROLL;
6116 priv->max_items_per_block = MAX_ITEMS_PER_BLOCK;
6117 priv->item_cache_max = priv->max_items_per_block * 2;
6118 priv->longpress_timeout = _elm_config->longpress_timeout;
6119 priv->highlight = EINA_TRUE;
6120 priv->fx_mode = EINA_FALSE;
6121 priv->on_hold = EINA_FALSE;
6124 if (!TIZEN_PROFILE_WEARABLE)
6125 priv->top_drawn_item = NULL;
6127 priv->pan_obj = eo_add(MY_PAN_CLASS, evas_object_evas_get(obj));
6128 pan_data = eo_data_scope_get(priv->pan_obj, MY_PAN_CLASS);
6129 eo_data_ref(obj, NULL);
6131 pan_data->wobj = obj;
6133 pan_data->wsd = priv;
6136 // FIXME: difference from upstream
6137 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_DOWN,
6138 _mouse_down_scroller, obj);
6139 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_UP,
6140 _mouse_up_scroller, obj);
6141 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_MOVE,
6142 _mouse_move_scroller, obj);
6145 eo_do(obj, elm_interface_scrollable_extern_pan_set(priv->pan_obj));
6147 edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
6148 evas_object_size_hint_min_set(obj, minw, minh);
6150 _item_cache_all_free(priv);
6151 _mirrored_set(obj, elm_widget_mirrored_get(obj));
6153 const char *str = edje_object_data_get(wd->resize_obj,
6155 if ((str) && (!strcmp(str, "on")))
6156 elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
6158 elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
6159 priv->select_on_focus_enabled = EINA_FALSE;
6160 elm_widget_signal_callback_add(obj, "elm,action,focus_highlight,hide", "elm", _elm_genlist_focus_highlight_hide, obj);
6161 elm_widget_signal_callback_add(obj, "elm,action,focus_highlight,show", "elm", _elm_genlist_focus_highlight_show, obj);
6162 evas_event_callback_add(evas_object_evas_get(obj),
6163 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
6164 _evas_viewport_resize_cb, priv);
6166 priv->g_layer = elm_gesture_layer_add(obj);
6167 if (!priv->g_layer) ERR("elm_gesture_layer_add() failed");
6168 elm_gesture_layer_attach(priv->g_layer, priv->hit_rect);
6169 elm_gesture_layer_cb_set
6170 (priv->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_START,
6171 _pinch_zoom_start_cb, priv);
6172 elm_gesture_layer_cb_set
6173 (priv->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE,
6174 _pinch_zoom_cb, priv);
6176 elm_gesture_layer_cb_set
6177 (priv->g_layer, ELM_GESTURE_N_LINES, ELM_GESTURE_STATE_START,
6178 _gesture_n_lines_start_cb, priv);
6179 elm_gesture_layer_cb_set
6180 (priv->g_layer, ELM_GESTURE_N_LINES, ELM_GESTURE_STATE_MOVE,
6181 _gesture_n_lines_cb, priv);
6183 elm_gesture_layer_cb_set
6184 (priv->g_layer, ELM_GESTURE_N_FLICKS, ELM_GESTURE_STATE_START,
6185 _gesture_n_lines_start_cb, priv);
6186 elm_gesture_layer_cb_set
6187 (priv->g_layer, ELM_GESTURE_N_FLICKS, ELM_GESTURE_STATE_MOVE,
6188 _gesture_n_flicks_cb, priv);
6190 elm_layout_sizing_eval(obj);
6192 // TIZEN_ONLY(20150705): Genlist item align feature
6193 wd->scroll_item_align_enable = _elm_config->scroll_item_align_enable;
6194 wd->scroll_item_valign = _elm_config->scroll_item_valign;
6196 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
6197 (NULL, NULL, &priv->viewport_w, &priv->viewport_h));
6200 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
6201 //register/unregister access objects accordingly.
6202 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6204 _elm_genlist_elm_widget_screen_reader(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool is_screen_reader)
6207 Eina_Bool done = EINA_FALSE;
6208 Evas_Object *content = NULL;
6212 EINA_INLIST_FOREACH(sd->blocks, itb)
6217 EINA_LIST_FOREACH(itb->items, l, it)
6219 if (!it->realized || it->want_hidden) continue;
6220 if (is_screen_reader)
6222 elm_interface_atspi_accessible_added(EO_OBJ(it));
6223 elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
6224 EINA_LIST_FOREACH(it->content_objs, ll, content)
6226 if (eo_isa(content, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
6228 eo_do(content, elm_interface_atspi_accessible_parent_set(EO_OBJ(it)));
6229 elm_interface_atspi_accessible_children_changed_added_signal_emit(EO_OBJ(it), content);
6232 elm_interface_atspi_accessible_name_changed_signal_emit(EO_OBJ(it));
6236 elm_interface_atspi_accessible_removed(EO_OBJ(it));
6237 elm_interface_atspi_accessible_children_changed_del_signal_emit(sd->obj, EO_OBJ(it));
6241 else if (done) break;
6244 //TIZEN_ONLY(20161213): apply screen_reader_changed callback
6245 evas_object_smart_callback_call(obj, SIG_ATSPI_SCREEN_READER_CHANGED, &is_screen_reader);
6251 EOLIAN const Elm_Atspi_Action *
6252 _elm_genlist_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd EINA_UNUSED)
6254 /* Need to be implemented
6255 static Elm_Atspi_Action atspi_actions[] = {
6256 { "move,prior", "move", "prior", _key_action_move},
6257 { "move,next", "move", "next", _key_action_move},
6258 { "move,left", "move", "left", _key_action_move},
6259 { "move,right", "move", "right", _key_action_move},
6260 { "move,up", "move", "up", _key_action_move},
6261 { "move,up,multi", "move", "up_multi", _key_action_move},
6262 { "move,down", "move", "down", _key_action_move},
6263 { "move,down,multi", "move", "down_multi", _key_action_move},
6264 { "move,first", "move", "first", _key_action_move},
6265 { "move,last", "move", "last", _key_action_move},
6266 { "select", "select", NULL, _key_action_select},
6267 { "select,multi", "select", "multi", _key_action_select},
6268 { "escape", "escape", NULL, _key_action_escape},
6269 { NULL, NULL, NULL, NULL }
6271 return &atspi_actions[0];
6273 static Elm_Atspi_Action atspi_actions[] = {{NULL, NULL, NULL, NULL}};
6274 return &atspi_actions[0];
6278 elm_genlist_add(Evas_Object *parent)
6280 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
6281 Evas_Object *obj = eo_add(MY_CLASS, parent);
6286 _elm_genlist_eo_base_constructor(Eo *obj, Elm_Genlist_Data *sd)
6288 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
6292 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
6293 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
6294 elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST));
6299 EOLIAN static Evas_Object *
6300 _elm_genlist_item_elm_widget_item_part_content_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6302 Evas_Object *ret = NULL;
6303 if (it->deco_all_view)
6304 ret = edje_object_part_swallow_get(it->deco_all_view, part);
6305 else if (it->decorate_it_set)
6306 ret = edje_object_part_swallow_get(GL_IT(it)->deco_it_view, part);
6308 ret = edje_object_part_swallow_get(VIEW(it), part);
6312 EOLIAN static const char *
6313 _elm_genlist_item_elm_widget_item_part_text_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6315 if (!it->itc->func.text_get) return NULL;
6316 const char *ret = NULL;
6317 if (it->deco_all_view)
6318 ret = edje_object_part_text_get(it->deco_all_view, part);
6319 else if (it->decorate_it_set)
6320 ret = edje_object_part_text_get(GL_IT(it)->deco_it_view, part);
6322 ret = edje_object_part_text_get(VIEW(it), part);
6327 _elm_genlist_item_elm_widget_item_disable(Eo *eo_it, Elm_Gen_Item *it)
6334 if (it == GL_IT(it)->wsd->focused_item) elm_object_item_focus_set(EO_OBJ(it), EINA_FALSE);
6335 if (GL_IT(it)->highlight_timer)
6337 ecore_timer_del(GL_IT(it)->highlight_timer);
6338 GL_IT(it)->highlight_timer = NULL;
6342 ecore_timer_del(it->long_timer);
6343 it->long_timer = NULL;
6348 if (eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get()))
6350 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
6351 if (it->deco_all_view)
6352 edje_object_signal_emit
6353 (it->deco_all_view, SIGNAL_DISABLED, "elm");
6357 edje_object_signal_emit(VIEW(it), SIGNAL_ENABLED, "elm");
6358 if (it->deco_all_view)
6359 edje_object_signal_emit
6360 (it->deco_all_view, SIGNAL_ENABLED, "elm");
6362 EINA_LIST_FOREACH(it->content_objs, l, obj)
6363 elm_widget_disabled_set(obj, eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get()));
6368 _item_free(Elm_Gen_Item *it)
6371 Elm_Object_Item *eo_it2;
6372 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
6373 sd->processed_sizes -= GL_IT(it)->minh;
6374 if (sd->processed_sizes < 0) sd->processed_sizes = 0;
6376 eo_do(EO_OBJ(it), elm_wdg_item_pre_notify_del());
6377 if (it->tooltip.del_cb)
6378 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6380 #ifdef GENLIST_FX_SUPPORT
6381 sd->del_fx.items = eina_list_remove(sd->del_fx.items, it);
6382 sd->del_fx.pending_items = eina_list_remove(sd->del_fx.pending_items, it);
6383 sd->add_fx.items = eina_list_remove(sd->add_fx.items, it);
6387 GL_IT(it)->rel->item->rel_revs =
6388 eina_list_remove(GL_IT(it)->rel->item->rel_revs, it);
6389 if (GL_IT(it)->rel_revs)
6392 EINA_LIST_FREE(GL_IT(it)->rel_revs, tmp)
6394 if (tmp->item->queued && !(tmp->base)->on_deletion)
6396 GL_IT(tmp)->queued = EINA_FALSE;
6397 GL_IT(tmp)->resized = EINA_FALSE;
6398 sd->queue = eina_list_remove(sd->queue, tmp);
6399 _item_process(sd, tmp);
6401 tmp->item->rel = NULL;
6404 EINA_LIST_FOREACH_SAFE(it->item->items, l, ll, eo_it2)
6406 //elm_widget_item_del(it2);
6407 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6410 sd->reorder.move_items = eina_list_remove(sd->reorder.move_items, it);
6412 if (GL_IT(it)->block) _item_block_del(it);
6414 it->parent->item->items =
6415 eina_list_remove(it->parent->item->items, EO_OBJ(it));
6416 if (GL_IT(it)->queued)
6418 GL_IT(it)->queued = EINA_FALSE;
6419 sd->queue = eina_list_remove(sd->queue, it);
6421 if (sd->filter_queue && !it->filtered)
6423 l = eina_list_data_find_list(sd->filter_queue, it);
6424 if (l) sd->filter_queue = eina_list_remove_list(sd->filter_queue, l);
6426 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6427 sd->group_items = eina_list_remove(sd->group_items, it);
6431 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
6432 it->selected = EINA_FALSE;
6434 if (sd->show_item == it) sd->show_item = NULL;
6436 if ((sd->g_item) && (sd->g_item == it)) sd->g_item = NULL;
6437 if (sd->expanded_item == it) sd->expanded_item = NULL;
6438 if (sd->state) ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
6440 if (sd->last_selected_item == EO_OBJ(it))
6441 sd->last_selected_item = NULL;
6443 if (sd->realization_mode)
6446 EINA_LIST_FOREACH(GL_IT(it)->flip_content_objs, l, c)
6448 evas_object_event_callback_del_full(c,
6449 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6450 _changed_size_hints, it);
6452 EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, c)
6454 evas_object_event_callback_del_full(c,
6455 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6456 _changed_size_hints, it);
6458 EINA_LIST_FOREACH(it->content_objs, l, c)
6460 evas_object_event_callback_del_full(c,
6461 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6462 _changed_size_hints, it);
6466 if (sd->mode_item) sd->mode_item = NULL;
6467 if (it->selected) _item_unselect(it);
6468 if (it == sd->focused_item)
6472 if (!elm_widget_focus_get(WIDGET(it))) goto failed;
6474 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6475 find = _item_focusable_search(&tmp, 1);
6478 elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
6483 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6484 find = _item_focusable_search(&tmp, -1);
6487 elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
6492 elm_object_item_focus_set(EO_OBJ(it), EINA_FALSE);
6493 sd->focused_item = NULL;
6496 if (it == sd->key_down_item) sd->key_down_item = NULL;
6497 if (it == sd->highlighted_item) sd->highlighted_item = NULL;
6498 if (!TIZEN_PROFILE_WEARABLE)
6500 if (it == sd->top_drawn_item) sd->top_drawn_item = NULL;
6503 _item_unrealize(it, EINA_FALSE);
6505 if (sd->aligned_item == it) sd->aligned_item = NULL;
6507 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
6510 if (it->item->proxy)
6512 evas_object_smart_member_del(it->item->proxy);
6513 evas_object_del(it->item->proxy);
6516 if (it->itc->func.del)
6517 it->itc->func.del((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it));
6519 if (it->itc->refcount <= 1)
6523 EINA_INLIST_FOREACH_SAFE(sd->item_cache, l2, ic)
6525 if (it->itc == ic->item_class)
6526 _item_cache_free(sd, ic);
6530 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
6535 // TIZEN_ONLY(20150703) : banded color background feature. enabled only un-scrollable
6536 if (!TIZEN_PROFILE_WEARABLE)
6538 if (sd->banded_bg_rect && !sd->items)
6540 evas_object_smart_member_del(sd->banded_bg_rect);
6541 ELM_SAFE_FREE(sd->banded_bg_rect, evas_object_del);
6545 _changed(sd->pan_obj);
6548 EOLIAN static Eina_Bool
6549 _elm_genlist_item_elm_widget_item_del_pre(Eo *eo_it EINA_UNUSED,
6552 #ifdef GENLIST_FX_SUPPORT
6553 Elm_Genlist_Data *sd = it->item->wsd;
6554 Evas_Coord cvx, cvy, cvw, cvh;
6561 #ifdef GENLIST_FX_SUPPORT
6564 sd->add_fx.items = eina_list_remove(sd->add_fx.items, it);
6567 evas_output_viewport_get(evas_object_evas_get(sd->obj),
6568 &cvx, &cvy, &cvw, &cvh);
6569 if (!ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
6570 GL_IT(it)->w, GL_IT(it)->h,
6571 cvx, cvy, cvw, cvh))
6573 // Delete later, Above items in the viewport
6574 // Delete right now, below items in the viewport
6575 if (it->item->scrl_y < cvy)
6576 sd->del_fx.pending_items = eina_list_append(sd->del_fx.pending_items, it);
6580 _changed(sd->pan_obj);
6586 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
6587 else if (it->item->deco_it_view) evas_object_lower(it->item->deco_it_view);
6588 else if (VIEW(it)) evas_object_lower(VIEW(it));
6590 if (it->item->expanded_depth > 0)
6593 Elm_Object_Item *itt;
6594 EINA_LIST_FOREACH(it->item->items, l, itt)
6596 eo_do(itt, elm_wdg_item_del());
6599 sd->del_fx.items = eina_list_append(sd->del_fx.items, it);
6601 if (!sd->del_fx.anim)
6603 sd->del_fx.cnt = ANIM_CNT_MAX;
6604 sd->del_fx.anim = ecore_animator_add(_del_fx_anim, sd);
6606 _changed(sd->pan_obj);
6612 _elm_genlist_item_elm_widget_item_signal_emit(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char *emission, const char *source)
6616 WRN("item is not realized yet");
6619 edje_object_signal_emit
6620 (VIEW(it), emission, source);
6621 if (it->deco_all_view)
6622 edje_object_signal_emit
6623 (it->deco_all_view, emission, source);
6627 _elm_genlist_item_eo_base_constructor(Eo *eo_it, Elm_Gen_Item *it)
6629 eo_it = eo_do_super_ret(eo_it, ELM_GENLIST_ITEM_CLASS, eo_it, eo_constructor());
6631 it->base = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
6632 eo_do(eo_it, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST_ITEM));
6636 static Elm_Gen_Item *
6637 _elm_genlist_item_new(Elm_Genlist_Data *sd,
6638 const Elm_Genlist_Item_Class *itc,
6640 Elm_Object_Item *eo_parent,
6641 Elm_Genlist_Item_Type type,
6643 const void *func_data)
6648 if (!itc) return NULL;
6650 Eo *eo_it = eo_add(ELM_GENLIST_ITEM_CLASS, sd->obj);
6651 if (!eo_it) return NULL;
6652 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6655 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
6657 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6658 WIDGET_ITEM_DATA_SET(EO_OBJ(it), data);
6659 it->parent = parent;
6660 it->func.func = func;
6661 it->func.data = func_data;
6663 GL_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
6664 GL_IT(it)->wsd = sd;
6665 GL_IT(it)->type = type;
6669 if (GL_IT(it->parent)->type == ELM_GENLIST_ITEM_GROUP)
6670 GL_IT(it)->group_item = parent;
6671 else if (GL_IT(it->parent)->group_item)
6672 GL_IT(it)->group_item = GL_IT(it->parent)->group_item;
6674 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
6676 if (GL_IT(it2->parent)->type == ELM_GENLIST_ITEM_TREE) depth += 1;
6678 GL_IT(it)->expanded_depth = depth;
6685 _elm_genlist_item_compare(const void *data,
6688 const Elm_Gen_Item *it, *item1;
6690 it = ELM_GEN_ITEM_FROM_INLIST(data);
6691 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
6692 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6696 _elm_genlist_item_list_compare(const void *data,
6699 const Elm_Gen_Item *it = data;
6700 const Elm_Gen_Item *item1 = data1;
6702 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6705 EOLIAN static unsigned int
6706 _elm_genlist_items_count(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6708 return sd->item_count;
6712 _list_last_recursive(Eina_List *list)
6714 Eina_List *ll, *ll2;
6715 Elm_Object_Item *eo_it2;
6717 ll = eina_list_last(list);
6718 if (!ll) return NULL;
6721 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6723 if (it2->item->items)
6725 ll2 = _list_last_recursive(it2->item->items);
6735 EOLIAN static Elm_Object_Item*
6736 _elm_genlist_item_append(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
6740 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6744 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6745 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6746 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6749 it = _elm_genlist_item_new
6750 (sd, itc, data, eo_parent, type, func, func_data);
6751 if (!it) return NULL;
6755 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6756 sd->group_items = eina_list_append(sd->group_items, it);
6757 sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
6758 GL_IT(it)->rel = NULL;
6762 Elm_Object_Item *eo_it2 = NULL;
6763 Eina_List *ll = _list_last_recursive(it->parent->item->items);
6765 if (ll) eo_it2 = ll->data;
6766 it->parent->item->items =
6767 eina_list_append(it->parent->item->items, EO_OBJ(it));
6768 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6769 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6770 sd->items = eina_inlist_append_relative
6771 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6772 GL_IT(it)->rel = it2;
6773 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6775 GL_IT(it)->before = EINA_FALSE;
6776 _item_queue_direct(it, NULL);
6780 EOLIAN static Elm_Object_Item*
6781 _elm_genlist_item_prepend(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
6783 Elm_Gen_Item *it = NULL;
6785 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6788 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6789 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6790 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6791 /* first sub-item should allways be appended */
6792 if (!parent->item->items)
6793 return _elm_genlist_item_append(obj, sd, itc, data, eo_parent, type, func, func_data);
6795 it = _elm_genlist_item_new
6796 (sd, itc, data, eo_parent, type, func, func_data);
6798 if (!it) return NULL;
6800 if (sd->items) GL_IT(it)->is_prepend = EINA_TRUE;
6803 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6804 sd->group_items = eina_list_prepend(sd->group_items, it);
6805 sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
6806 GL_IT(it)->rel = NULL;
6810 Elm_Object_Item *eo_it2 = NULL;
6811 Eina_List *ll = it->parent->item->items;
6813 if (ll) eo_it2 = ll->data;
6814 it->parent->item->items =
6815 eina_list_prepend(it->parent->item->items, EO_OBJ(it));
6816 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6817 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6820 sd->items = eina_inlist_prepend_relative
6821 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6822 GL_IT(it)->rel = it2;
6823 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6826 GL_IT(it)->before = EINA_TRUE;
6827 _item_queue_direct(it, NULL);
6831 EOLIAN static Elm_Object_Item*
6832 _elm_genlist_item_insert_after(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Object_Item *eo_after, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
6834 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_after, NULL);
6835 ELM_GENLIST_ITEM_DATA_GET(eo_after, after_it);
6838 ELM_GENLIST_ITEM_CHECK_OR_RETURN(after_it, NULL);
6839 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(after_it), NULL);
6842 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6843 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6844 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6847 /* It makes no sense to insert after in an empty list with after !=
6848 * NULL, something really bad is happening in your app. */
6849 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6851 it = _elm_genlist_item_new
6852 (sd, itc, data, eo_parent, type, func, func_data);
6853 if (!it) return NULL;
6857 if ((GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) &&
6858 (GL_IT(after_it)->type == ELM_GENLIST_ITEM_GROUP))
6859 sd->group_items = eina_list_append_relative
6860 (sd->group_items, it, after_it);
6864 it->parent->item->items =
6865 eina_list_append_relative(it->parent->item->items, EO_OBJ(it), eo_after);
6867 sd->items = eina_inlist_append_relative
6868 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after_it));
6870 GL_IT(it)->rel = after_it;
6871 after_it->item->rel_revs = eina_list_append(after_it->item->rel_revs, it);
6872 GL_IT(it)->before = EINA_FALSE;
6873 _item_queue_direct(it, NULL);
6875 if (elm_genlist_item_next_get(eo_after) == EO_OBJ(sd->aligned_item))
6876 sd->aligned_item = NULL;
6880 EOLIAN static Elm_Object_Item*
6881 _elm_genlist_item_insert_before(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Object_Item *eo_before, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
6883 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_before, NULL);
6884 ELM_GENLIST_ITEM_DATA_GET(eo_before, before_it);
6887 ELM_GENLIST_ITEM_CHECK_OR_RETURN(before_it, NULL);
6888 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(before_it), NULL);
6891 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6892 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6893 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6896 /* It makes no sense to insert before in an empty list with before
6897 * != NULL, something really bad is happening in your app. */
6898 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6900 it = _elm_genlist_item_new
6901 (sd, itc, data, eo_parent, type, func, func_data);
6902 if (!it) return NULL;
6906 if ((GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) &&
6907 (GL_IT(before_it)->type == ELM_GENLIST_ITEM_GROUP))
6909 eina_list_prepend_relative(sd->group_items, it, before_it);
6913 it->parent->item->items =
6914 eina_list_prepend_relative(it->parent->item->items, EO_OBJ(it), eo_before);
6916 sd->items = eina_inlist_prepend_relative
6917 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before_it));
6919 GL_IT(it)->rel = before_it;
6920 before_it->item->rel_revs = eina_list_append(before_it->item->rel_revs, it);
6921 GL_IT(it)->before = EINA_TRUE;
6922 _item_queue_direct(it, NULL);
6924 if (before_it == sd->aligned_item)
6925 sd->aligned_item = NULL;
6930 EOLIAN static Elm_Object_Item*
6931 _elm_genlist_item_sorted_insert(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Genlist_Item_Type type, Eina_Compare_Cb comp, Evas_Smart_Cb func, const void *func_data)
6933 Elm_Gen_Item *rel = NULL;
6935 Elm_Object_Item *eo_it;
6939 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6940 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6941 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6944 it = _elm_genlist_item_new
6945 (sd, itc, data, eo_parent, type, func, func_data);
6946 if (!it) return NULL;
6949 sd->item_compare_cb = comp;
6953 Elm_Object_Item *eo_rel = NULL;
6957 l = eina_list_search_sorted_near_list
6958 (it->parent->item->items, _elm_genlist_item_list_compare, eo_it,
6963 eo_rel = eina_list_data_get(l);
6964 rel = eo_data_scope_get(eo_rel, ELM_GENLIST_ITEM_CLASS);
6966 if (cmp_result >= 0)
6968 it->parent->item->items = eina_list_prepend_relative_list
6969 (it->parent->item->items, eo_it, l);
6970 sd->items = eina_inlist_prepend_relative
6971 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6972 it->item->before = EINA_TRUE;
6974 else if (cmp_result < 0)
6976 it->parent->item->items = eina_list_append_relative_list
6977 (it->parent->item->items, eo_it, l);
6978 sd->items = eina_inlist_append_relative
6979 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6980 it->item->before = EINA_FALSE;
6981 it->item->is_prepend = EINA_TRUE;
6988 // ignoring the comparison
6989 it->parent->item->items = eina_list_prepend_relative_list
6990 (it->parent->item->items, eo_it, l);
6991 sd->items = eina_inlist_prepend_relative
6992 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6993 it->item->before = EINA_FALSE;
7000 sd->state = eina_inlist_sorted_state_new();
7001 eina_inlist_sorted_state_init(sd->state, sd->items);
7002 sd->requeued = EINA_FALSE;
7005 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
7006 sd->group_items = eina_list_append(sd->group_items, it);
7008 sd->items = eina_inlist_sorted_state_insert
7009 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
7012 if (EINA_INLIST_GET(it)->next)
7014 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
7015 GL_IT(it)->before = EINA_TRUE;
7016 GL_IT(it)->is_prepend = EINA_TRUE;
7018 else if (EINA_INLIST_GET(it)->prev)
7020 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7021 GL_IT(it)->before = EINA_FALSE;
7027 GL_IT(it)->rel = rel;
7028 rel->item->rel_revs = eina_list_append(rel->item->rel_revs, it);
7031 _item_queue_direct(it, _elm_genlist_item_list_compare);
7036 _elm_genlist_clear(Eo *obj, Elm_Genlist_Data *sd)
7040 eina_hash_free_buckets(sd->size_caches);
7041 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
7042 if (sd->key_down_item) sd->key_down_item = NULL;
7043 if (sd->mode_item) sd->mode_item = NULL;
7047 eina_inlist_sorted_state_free(sd->state);
7051 sd->filter_data = NULL;
7052 if (sd->filter_queue)
7053 ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
7054 ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
7055 ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
7057 // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
7058 // because sd->items can be modified inside elm_widget_item_del()
7061 it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
7062 //elm_widget_item_del(it);
7065 sd->reorder.it = NULL;
7066 sd->reorder.dir = 0;
7067 eina_list_free(sd->reorder.move_items);
7071 _item_cache_all_free(sd);
7075 sd->selected = eina_list_free(sd->selected);
7076 sd->selected = NULL;
7079 sd->show_item = NULL;
7088 evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
7089 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
7091 elm_layout_sizing_eval(obj);
7093 eo_do(sd->obj, elm_interface_scrollable_content_region_show(0, 0, 0, 0));
7097 ecore_job_del(sd->dummy_job);
7098 sd->dummy_job = NULL;
7100 if (sd->queue_idle_enterer)
7102 ecore_idle_enterer_del(sd->queue_idle_enterer);
7103 sd->queue_idle_enterer = NULL;
7105 if (sd->scr_hold_timer)
7107 ecore_timer_del(sd->scr_hold_timer);
7108 sd->scr_hold_timer = NULL;
7110 if (sd->reorder.anim)
7112 ecore_animator_del(sd->reorder.anim);
7113 sd->reorder.anim = NULL;
7117 ecore_timer_del(sd->scr_timer);
7118 sd->scr_timer = NULL;
7120 #ifdef GENLIST_FX_SUPPORT
7121 if (sd->del_fx.anim)
7123 ecore_animator_del(sd->del_fx.anim);
7124 sd->del_fx.anim = NULL;
7126 if (sd->add_fx.anim)
7128 ecore_animator_del(sd->add_fx.anim);
7129 sd->add_fx.anim = NULL;
7133 if (sd->queue) sd->queue = eina_list_free(sd->queue);
7134 if (sd->g_item) sd->g_item = NULL;
7135 if (sd->g_type) sd->g_type = NULL;
7137 if (!TIZEN_PROFILE_WEARABLE)
7139 if (sd->banded_bg_rect)
7141 evas_object_smart_member_del(sd->banded_bg_rect);
7142 ELM_SAFE_FREE(sd->banded_bg_rect, evas_object_del);
7148 _elm_genlist_multi_select_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool multi)
7150 sd->multi = !!multi;
7151 if (!sd->multi && sd->selected)
7154 Elm_Object_Item *eo_it;
7155 Elm_Object_Item *last = sd->selected->data;
7156 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
7159 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
7165 EOLIAN static Eina_Bool
7166 _elm_genlist_multi_select_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7172 _elm_genlist_multi_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Elm_Object_Multi_Select_Mode mode EINA_UNUSED)
7174 /* Need to be implemented
7175 if (mode >= ELM_OBJECT_MULTI_SELECT_MODE_MAX)
7178 if (sd->multi_select_mode != mode)
7179 sd->multi_select_mode = mode;
7184 EOLIAN static Elm_Object_Multi_Select_Mode
7185 _elm_genlist_multi_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
7187 // Need to be implemented
7188 //return sd->multi_select_mode;
7189 return ELM_OBJECT_MULTI_SELECT_MODE_DEFAULT;
7192 EOLIAN static Elm_Object_Item*
7193 _elm_genlist_selected_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7196 return sd->selected->data;
7201 EOLIAN static const Eina_List*
7202 _elm_genlist_selected_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7204 return sd->selected;
7207 EOLIAN static Eina_List*
7208 _elm_genlist_realized_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7211 Eina_List *list = NULL;
7212 Eina_Bool done = EINA_FALSE;
7214 EINA_INLIST_FOREACH(sd->blocks, itb)
7222 EINA_LIST_FOREACH(itb->items, l, it)
7224 if (it->realized) list = eina_list_append(list, EO_OBJ(it));
7235 EOLIAN static Elm_Object_Item *
7236 _elm_genlist_search_by_text_item_get(Eo *obj EINA_UNUSED,
7237 Elm_Genlist_Data *sd,
7238 Elm_Object_Item *item_to_search_from,
7239 const char *part_name,
7240 const char *pattern,
7241 Elm_Glob_Match_Flags flags)
7243 Elm_Gen_Item *it = NULL;
7245 Eina_Inlist *start = NULL;
7248 if (!pattern) return NULL;
7249 if (!sd->items) return NULL;
7251 if (flags & ELM_GLOB_MATCH_NO_ESCAPE) fnflags |= FNM_NOESCAPE;
7252 if (flags & ELM_GLOB_MATCH_PATH) fnflags |= FNM_PATHNAME;
7253 if (flags & ELM_GLOB_MATCH_PERIOD) fnflags |= FNM_PERIOD;
7255 if (flags & ELM_GLOB_MATCH_NOCASE) fnflags |= FNM_CASEFOLD;
7258 start = (item_to_search_from) ?
7259 EINA_INLIST_GET((Elm_Gen_Item *)eo_data_scope_get(item_to_search_from, ELM_GENLIST_ITEM_CLASS)) :
7261 EINA_INLIST_FOREACH(start, it)
7263 if (!it->itc->func.text_get) continue;
7264 str = it->itc->func.text_get((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), part_name);
7266 if (!fnmatch(pattern, str, fnflags))
7276 EOLIAN static Elm_Object_Item*
7277 _elm_genlist_at_xy_item_get(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y, int *posret)
7279 Evas_Coord ox, oy, ow, oh;
7283 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7285 EINA_INLIST_FOREACH(sd->blocks, itb)
7289 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->sd->pan_x,
7290 oy + itb->y - itb->sd->pan_y,
7291 sd->minw, itb->minh, x, y, 1, 1))
7293 EINA_LIST_FOREACH(itb->items, l, it)
7295 Evas_Coord itx, ity;
7297 itx = ox + itb->x + it->x - itb->sd->pan_x;
7298 ity = oy + itb->y + it->y - itb->sd->pan_y;
7299 if (ELM_RECTS_INTERSECT
7300 (itx, ity, GL_IT(it)->w, GL_IT(it)->h, x, y, 1, 1))
7304 if (y <= (ity + (GL_IT(it)->h / 4))) *posret = -1;
7305 else if (y >= (ity + GL_IT(it)->h - (GL_IT(it)->h / 4)))
7312 lasty = ity + GL_IT(it)->h;
7317 if (y > lasty) *posret = 1;
7324 EOLIAN static Elm_Object_Item*
7325 _elm_genlist_first_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7327 Elm_Gen_Item *tit, *it = NULL;
7329 EINA_INLIST_REVERSE_FOREACH(sd->items, tit) it = tit;
7334 EOLIAN static Elm_Object_Item*
7335 _elm_genlist_last_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7339 if (!sd->items) return NULL;
7341 it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
7345 EOLIAN static Elm_Object_Item *
7346 _elm_genlist_item_next_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7350 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
7354 if (it) return EO_OBJ(it);
7358 EOLIAN static Elm_Object_Item *
7359 _elm_genlist_item_prev_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7363 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7367 if (it) return EO_OBJ(it);
7371 EOLIAN static Elm_Object_Item *
7372 _elm_genlist_item_parent_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7374 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
7376 return EO_OBJ(it->parent);
7379 EOLIAN static unsigned int
7380 _elm_genlist_item_subitems_count(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
7382 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, 0);
7384 return eina_list_count(item->item->items);
7387 EOLIAN static const Eina_List *
7388 _elm_genlist_item_subitems_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
7390 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
7392 return item->item->items;
7396 _elm_genlist_item_subitems_clear(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7398 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7400 Elm_Object_Item *eo_it2;
7402 EINA_LIST_FOREACH_SAFE(GL_IT(it)->items, l, ll, eo_it2)
7403 eo_do(eo_it2, elm_wdg_item_del());
7407 _elm_genlist_item_selected_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
7410 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7413 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get())) return;
7414 // FIXME: This API has highlight/unhighlith feature also..
7416 if (selected) _item_highlight(it);
7417 else _item_unhighlight(it, EINA_TRUE);
7419 selected = !!selected;
7420 if (it->selected == selected) return;
7422 if (selected) _item_select(it);
7423 else _item_unselect(it);
7426 EOLIAN static Eina_Bool
7427 _elm_genlist_item_selected_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7429 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7431 return it->selected;
7435 _elm_genlist_item_expanded_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool expanded)
7437 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7439 expanded = !!expanded;
7440 if (GL_IT(it)->expanded == expanded) return;
7441 if (GL_IT(it)->type != ELM_GENLIST_ITEM_TREE) return;
7442 GL_IT(it)->expanded = expanded;
7443 GL_IT(it)->wsd->expanded_item = it;
7445 if (GL_IT(it)->expanded)
7448 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
7449 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, EO_OBJ(it));
7450 if (_elm_atspi_enabled())
7451 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_item);
7456 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACTED, "elm");
7457 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, EO_OBJ(it));
7458 if (_elm_atspi_enabled())
7459 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_item);
7463 EOLIAN static Eina_Bool
7464 _elm_genlist_item_expanded_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7466 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7468 return GL_IT(it)->expanded;
7472 _elm_genlist_item_expanded_depth_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7474 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, 0);
7476 return GL_IT(it)->expanded_depth;
7480 _elm_genlist_item_promote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7482 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7484 Elm_Object_Item *eo_first_item = elm_genlist_first_item_get(WIDGET(it));
7485 ELM_GENLIST_ITEM_DATA_GET(eo_first_item, first_item);
7486 _item_move_before(it, first_item);
7490 _elm_genlist_item_demote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7492 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7493 Elm_Object_Item *eo_last_item = elm_genlist_last_item_get(WIDGET(it));
7494 ELM_GENLIST_ITEM_DATA_GET(eo_last_item, last_item);
7495 _item_move_after(it, last_item);
7499 _elm_genlist_item_show(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
7501 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7503 if (it->want_hidden)
7505 WRN("Filter hided item cannot move to show");
7509 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7511 sd->bring_in = EINA_FALSE;
7512 sd->scroll_to_type = type;
7513 _changed(sd->pan_obj);
7517 _elm_genlist_item_bring_in(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
7519 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7521 if (it->want_hidden)
7523 WRN("Filter hided item cannot move to bring in");
7527 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7528 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wd);
7529 sd->bring_in = EINA_TRUE;
7530 sd->scroll_to_type = type;
7532 if (wd->scroll_item_align_enable)
7534 it = _adjust_item_align(it);
7535 sd->adjusted_item = sd->show_item = it;
7537 if (sd->aligned_item && sd->show_item != sd->aligned_item)
7538 edje_object_signal_emit(VIEW(sd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
7543 _changed(sd->pan_obj);
7547 _elm_genlist_item_all_contents_unset(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_List **l)
7549 Evas_Object *content;
7551 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7553 EINA_LIST_FREE (it->content_objs, content)
7555 evas_object_smart_member_del(content);
7556 // edje can be reused by item caching,
7557 // content should be un-swallowed from edje
7558 edje_object_part_unswallow(VIEW(it), content);
7559 evas_object_hide(content);
7560 if (l) *l = eina_list_append(*l, content);
7565 _elm_genlist_item_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7567 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7569 if (!GL_IT(it)->block) return;
7571 GL_IT(it)->updateme = EINA_TRUE;
7572 GL_IT(it)->block->calc_done = EINA_FALSE;
7573 GL_IT(it)->wsd->calc_done = EINA_FALSE;
7574 _changed(GL_IT(it)->wsd->pan_obj);
7578 _elm_genlist_item_fields_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
7580 Elm_Genlist_Item_Field_Type itf)
7582 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7584 if (!GL_IT(it)->block) return;
7586 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
7588 _item_text_realize(it, VIEW(it), parts);
7590 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
7592 _item_content_realize(it, VIEW(it), &it->content_objs, "contents", parts);
7595 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_content_objs,
7598 if (GL_IT(it)->deco_it_view)
7600 _item_content_realize(it, GL_IT(it)->deco_it_view,
7601 &GL_IT(it)->deco_it_contents,
7604 if (GL_IT(it)->wsd->decorate_all_mode)
7606 _item_content_realize(it, it->deco_all_view,
7607 &GL_IT(it)->deco_all_contents,
7612 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
7613 _item_state_realize(it, VIEW(it), parts);
7615 GL_IT(it)->calc_done = EINA_FALSE;
7616 GL_IT(it)->block->calc_done = EINA_FALSE;
7617 GL_IT(it)->wsd->calc_done = EINA_FALSE;
7618 _changed(GL_IT(it)->wsd->pan_obj);
7622 _elm_genlist_item_item_class_update(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
7623 const Elm_Genlist_Item_Class *itc)
7625 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7626 EINA_SAFETY_ON_NULL_RETURN(itc);
7627 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7630 if (!GL_IT(it)->block) return;
7632 // FIXME(160711): orignal edje object updated by _view_theme_update
7633 // cannot recieve signal emit properly. This edje bug must be fixed.
7634 _item_cache_all_free(sd);
7636 sd->no_cache = EINA_TRUE;
7637 _item_unrealize(it, EINA_FALSE);
7638 sd->no_cache = EINA_FALSE;
7639 _item_realize(it, EINA_FALSE);
7641 if (sd->aligned_item == it)
7642 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
7644 GL_IT(it)->calc_done = EINA_FALSE;
7645 GL_IT(it)->block->calc_done = EINA_FALSE;
7646 sd->calc_done = EINA_FALSE;
7648 _changed(sd->pan_obj);
7651 EOLIAN static const Elm_Genlist_Item_Class *
7652 _elm_genlist_item_item_class_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7654 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
7658 static Evas_Object *
7659 _elm_genlist_item_label_create(void *data,
7660 Evas_Object *obj EINA_UNUSED,
7661 Evas_Object *tooltip,
7662 void *it EINA_UNUSED)
7664 Evas_Object *label = elm_label_add(tooltip);
7669 elm_object_style_set(label, "tooltip");
7670 elm_object_text_set(label, data);
7676 _elm_genlist_item_label_del_cb(void *data,
7677 Evas_Object *obj EINA_UNUSED,
7678 void *event_info EINA_UNUSED)
7680 eina_stringshare_del(data);
7684 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
7687 eo_do(it, elm_wdg_item_tooltip_text_set(text));
7691 _elm_genlist_item_elm_widget_item_tooltip_text_set(Eo *eo_it, Elm_Gen_Item *it, const char *text)
7693 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7695 text = eina_stringshare_add(text);
7696 elm_genlist_item_tooltip_content_cb_set
7697 (eo_it, _elm_genlist_item_label_create, text,
7698 _elm_genlist_item_label_del_cb);
7702 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item,
7703 Elm_Tooltip_Item_Content_Cb func,
7705 Evas_Smart_Cb del_cb)
7707 eo_do(item, elm_wdg_item_tooltip_content_cb_set(func, data, del_cb));
7712 _elm_genlist_item_elm_widget_item_tooltip_content_cb_set(Eo *eo_it, Elm_Gen_Item *it,
7713 Elm_Tooltip_Item_Content_Cb func,
7715 Evas_Smart_Cb del_cb)
7717 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7719 if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
7722 if (it->tooltip.del_cb)
7723 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7725 it->tooltip.content_cb = func;
7726 it->tooltip.data = data;
7727 it->tooltip.del_cb = del_cb;
7731 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7732 elm_wdg_item_tooltip_content_cb_set
7733 (it->tooltip.content_cb, it->tooltip.data, NULL));
7735 elm_wdg_item_tooltip_style_set(it->tooltip.style),
7736 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
7741 elm_genlist_item_tooltip_unset(Elm_Object_Item *item)
7743 eo_do(item, elm_wdg_item_tooltip_unset());
7747 _elm_genlist_item_elm_widget_item_tooltip_unset(Eo *eo_it, Elm_Gen_Item *it)
7749 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7751 if ((VIEW(it)) && (it->tooltip.content_cb))
7752 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7753 elm_wdg_item_tooltip_unset());
7755 if (it->tooltip.del_cb)
7756 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7757 it->tooltip.del_cb = NULL;
7758 it->tooltip.content_cb = NULL;
7759 it->tooltip.data = NULL;
7760 it->tooltip.free_size = EINA_FALSE;
7761 if (it->tooltip.style)
7762 eo_do(eo_it, elm_wdg_item_tooltip_style_set(NULL));
7766 elm_genlist_item_tooltip_style_set(Elm_Object_Item *item,
7769 eo_do(item, elm_wdg_item_tooltip_style_set(style));
7773 _elm_genlist_item_elm_widget_item_tooltip_style_set(Eo *eo_it, Elm_Gen_Item *it,
7776 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7778 eina_stringshare_replace(&it->tooltip.style, style);
7779 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7780 elm_wdg_item_tooltip_style_set(style));
7784 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
7787 return eo_do_ret(it, style, elm_wdg_item_tooltip_style_get());
7790 EOLIAN static const char *
7791 _elm_genlist_item_elm_widget_item_tooltip_style_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7793 return it->tooltip.style;
7797 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *item,
7801 return eo_do_ret(item, ret, elm_wdg_item_tooltip_window_mode_set(disable));
7804 EOLIAN static Eina_Bool
7805 _elm_genlist_item_elm_widget_item_tooltip_window_mode_set(Eo *eo_it, Elm_Gen_Item *it,
7808 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7811 it->tooltip.free_size = disable;
7813 return eo_do_super_ret(eo_it, ELM_GENLIST_ITEM_CLASS, ret,
7814 elm_wdg_item_tooltip_window_mode_set(disable));
7820 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *eo_it)
7823 return eo_do_ret(eo_it, ret, elm_wdg_item_tooltip_window_mode_get());
7826 EOLIAN static Eina_Bool
7827 _elm_genlist_item_elm_widget_item_tooltip_window_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7829 return it->tooltip.free_size;
7833 elm_genlist_item_cursor_set(Elm_Object_Item *item,
7836 eo_do(item, elm_wdg_item_cursor_set(cursor));
7840 _elm_genlist_item_elm_widget_item_cursor_set(Eo *eo_it, Elm_Gen_Item *it,
7843 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7844 eina_stringshare_replace(&it->mouse_cursor, cursor);
7845 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7846 elm_wdg_item_cursor_set(cursor));
7850 elm_genlist_item_cursor_get(const Elm_Object_Item *eo_it)
7853 return eo_do_ret(eo_it, cursor, elm_wdg_item_cursor_get());
7857 elm_genlist_item_cursor_unset(Elm_Object_Item *item)
7859 eo_do(item, elm_wdg_item_cursor_unset());
7863 _elm_genlist_item_elm_widget_item_cursor_unset(Eo *eo_it, Elm_Gen_Item *it)
7865 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7867 if (!it->mouse_cursor) return;
7869 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7870 elm_wdg_item_cursor_unset());
7872 ELM_SAFE_FREE(it->mouse_cursor, eina_stringshare_del);
7876 elm_genlist_item_cursor_style_set(Elm_Object_Item *eo_it,
7879 eo_do(eo_it, elm_wdg_item_cursor_style_set(style));
7883 elm_genlist_item_cursor_style_get(const Elm_Object_Item *eo_it)
7886 return eo_do_ret( eo_it, style, elm_wdg_item_cursor_style_get());
7890 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *eo_it,
7891 Eina_Bool engine_only)
7893 eo_do(eo_it, elm_wdg_item_cursor_engine_only_set(engine_only));
7897 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *eo_it)
7900 return eo_do_ret( eo_it, ret, elm_wdg_item_cursor_engine_only_get());
7904 _elm_genlist_item_index_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7908 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, -1);
7910 EINA_INLIST_FOREACH(GL_IT(it)->wsd->items, tmp)
7912 if (tmp == it) break;
7919 _elm_genlist_mode_set(Eo *obj, Elm_Genlist_Data *sd, Elm_List_Mode mode)
7921 if (sd->mode == mode) return;
7924 if (sd->mode == ELM_LIST_LIMIT)
7926 sd->scr_minw = EINA_TRUE;
7927 sd->scr_minh = EINA_FALSE;
7929 else if (sd->mode == ELM_LIST_EXPAND)
7931 sd->scr_minw = EINA_TRUE;
7932 sd->scr_minh = EINA_TRUE;
7936 sd->scr_minw = EINA_FALSE;
7937 sd->scr_minh = EINA_FALSE;
7940 elm_layout_sizing_eval(obj);
7943 EOLIAN static Elm_List_Mode
7944 _elm_genlist_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7950 elm_genlist_bounce_set(Evas_Object *obj,
7954 ELM_GENLIST_CHECK(obj);
7955 eo_do(obj, elm_interface_scrollable_bounce_allow_set(h_bounce, v_bounce));
7959 _elm_genlist_elm_interface_scrollable_bounce_allow_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool h_bounce, Eina_Bool v_bounce)
7961 sd->h_bounce = !!h_bounce;
7962 sd->v_bounce = !!v_bounce;
7964 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_bounce_allow_set
7965 (sd->h_bounce, sd->v_bounce));
7966 //sd->s_iface->bounce_allow_set(obj, sd->h_bounce, sd->v_bounce);
7970 elm_genlist_bounce_get(const Evas_Object *obj,
7971 Eina_Bool *h_bounce,
7972 Eina_Bool *v_bounce)
7974 ELM_GENLIST_CHECK(obj);
7975 eo_do( obj, elm_interface_scrollable_bounce_allow_get
7976 (h_bounce, v_bounce));
7980 _elm_genlist_elm_interface_scrollable_bounce_allow_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
7982 if (h_bounce) *h_bounce = sd->h_bounce;
7983 if (v_bounce) *v_bounce = sd->v_bounce;
7987 _elm_genlist_homogeneous_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool homogeneous)
7989 sd->homogeneous = !!homogeneous;
7992 EOLIAN static Eina_Bool
7993 _elm_genlist_homogeneous_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7995 return sd->homogeneous;
7999 _elm_genlist_block_count_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, int count)
8001 EINA_SAFETY_ON_TRUE_RETURN(count < 1);
8003 sd->max_items_per_block = count;
8004 sd->item_cache_max = sd->max_items_per_block * 2;
8005 _item_cache_all_free(sd);
8009 _elm_genlist_block_count_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8011 return sd->max_items_per_block;
8015 _filter_item_internal(Elm_Gen_Item *it)
8017 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8018 if (sd->filter_data && it->itc->func.filter_get)
8020 if (!it->itc->func.filter_get(
8021 (void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)),
8022 WIDGET(it), sd->filter_data))
8024 it->want_hidden = EINA_TRUE;
8025 if (sd->show_item == it) sd->show_item = NULL;
8026 GL_IT(it)->block->calc_done = EINA_FALSE;
8027 sd->calc_done = EINA_FALSE;
8030 sd->filtered_count++;
8032 it->filtered = EINA_TRUE;
8033 sd->processed_count++;
8037 _item_filtered_get(Elm_Gen_Item *it)
8040 if (!it) return EINA_FALSE;
8041 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8044 l = eina_list_data_find_list(sd->filter_queue, it);
8046 sd->filter_queue = eina_list_remove_list(sd->filter_queue, l);
8047 l = eina_list_data_find_list(sd->queue, it);
8050 sd->queue = eina_list_remove_list(sd->queue, l);
8051 GL_IT(it)->queued = EINA_FALSE;
8052 GL_IT(it)->resized = EINA_FALSE;
8053 _item_process(sd, it);
8056 _filter_item_internal(it);
8057 GL_IT(it)->block->calc_done = EINA_FALSE;
8058 sd->calc_done = EINA_FALSE;
8059 _changed(sd->pan_obj);
8061 if (!it->want_hidden) return EINA_TRUE;
8066 _filter_queue_process(Elm_Genlist_Data *sd)
8069 Elm_Gen_Item *it, *first;
8072 t0 = ecore_time_get();
8073 for (n = 0; ((sd->filter_queue) && (sd->processed_count < ITEM_QUEUE_MAX)); n++)
8075 first = it = eina_list_data_get(sd->filter_queue);
8076 //FIXME: This is added as a fail safe code for items not yet processed.
8077 while (it && it->item->queued)
8079 if ((ecore_time_get() - t0) > (ecore_animator_frametime_get()))
8081 sd->filter_queue = eina_list_remove_list
8082 (sd->filter_queue, sd->filter_queue);
8083 sd->filter_queue = eina_list_append(sd->filter_queue, it);
8084 it = eina_list_data_get(sd->filter_queue);
8086 //Do not iterate more than one loop
8087 if (it == first) return n;
8089 sd->filter_queue = eina_list_remove_list(sd->filter_queue, sd->filter_queue);
8092 _filter_item_internal(it);
8093 GL_IT(it)->block->calc_done = EINA_FALSE;
8095 sd->calc_done = EINA_FALSE;
8096 _changed(sd->pan_obj);
8097 if ((ecore_time_get() - t0) > (ecore_animator_frametime_get()))
8099 //At least 1 item is filtered by this time, so return n+1 for first loop
8108 _filter_process(void *data,
8111 Elm_Genlist_Data *sd = data;
8113 if (_filter_queue_process(sd) > 0) *wakeup = EINA_TRUE;
8114 if (!sd->filter_queue) return ECORE_CALLBACK_CANCEL;
8115 return ECORE_CALLBACK_RENEW;
8119 _item_filter_enterer(void *data)
8121 Eina_Bool wakeup = EINA_FALSE;
8122 ELM_GENLIST_DATA_GET(data, sd);
8123 Eina_Bool ok = _filter_process(sd, &wakeup);
8126 if (sd->dummy_job) ecore_job_del(sd->dummy_job);
8127 sd->dummy_job = ecore_job_add(_dummy_job, sd);
8129 if (ok == ECORE_CALLBACK_CANCEL)
8133 ecore_job_del(sd->dummy_job);
8134 sd->dummy_job = NULL;
8136 sd->queue_idle_enterer = NULL;
8137 evas_object_smart_callback_call((Evas_Object *)data, SIG_FILTER_DONE, NULL);
8144 _elm_genlist_filter_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, void *filter_data)
8150 if (sd->filter_queue)
8151 ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
8152 ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
8153 ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
8154 sd->filtered_count = 0;
8155 sd->processed_count = 0;
8156 sd->filter = EINA_TRUE;
8157 sd->filter_data = filter_data;
8159 EINA_INLIST_FOREACH(sd->blocks, itb)
8163 EINA_LIST_FOREACH(itb->items, l, it)
8165 it->filtered = EINA_FALSE;
8166 it->want_hidden = EINA_FALSE;
8168 _filter_item_internal(it);
8170 sd->filter_queue = eina_list_append(sd->filter_queue, it);
8172 itb->calc_done = EINA_FALSE;
8173 sd->calc_done = EINA_FALSE;
8177 EINA_LIST_FOREACH(itb->items, l, it)
8179 it->filtered = EINA_FALSE;
8180 it->want_hidden = EINA_FALSE;
8181 sd->filter_queue = eina_list_append(sd->filter_queue, it);
8185 _changed(sd->pan_obj);
8187 sd->queue_filter_enterer = ecore_idle_enterer_add(_item_filter_enterer,
8192 _filter_iterator_next(Elm_Genlist_Filter *iter, void **data)
8194 if (!iter->current) return EINA_FALSE;
8196 while (iter->current)
8198 item = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->current, Elm_Gen_Item);
8199 iter->current = iter->current->next;
8200 if (_item_filtered_get(item))
8203 *data = EO_OBJ(item);
8212 _filter_iterator_free(Elm_Genlist_Filter *iter)
8217 static Evas_Object *
8218 _filter_iterator_get_container(Elm_Genlist_Filter *iter)
8220 Elm_Gen_Item *it = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->head, Elm_Gen_Item);
8224 EOLIAN Eina_Iterator *
8225 _elm_genlist_filter_iterator_new(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8227 Elm_Genlist_Filter *iter;
8228 iter = calloc(1, sizeof (Elm_Genlist_Filter));
8229 if (!iter) return NULL;
8231 iter->head = sd->items;
8232 iter->current = sd->items;
8234 iter->iterator.version = EINA_ITERATOR_VERSION;
8235 iter->iterator.next = FUNC_ITERATOR_NEXT(_filter_iterator_next);
8236 iter->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
8237 _filter_iterator_get_container);
8238 iter->iterator.free = FUNC_ITERATOR_FREE(_filter_iterator_free);
8240 EINA_MAGIC_SET(&iter->iterator, EINA_MAGIC_ITERATOR);
8242 return &iter->iterator;
8246 _elm_genlist_longpress_timeout_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, double timeout)
8248 sd->longpress_timeout = timeout;
8251 EOLIAN static double
8252 _elm_genlist_longpress_timeout_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8254 return sd->longpress_timeout;
8258 elm_genlist_scroller_policy_set(Evas_Object *obj,
8259 Elm_Scroller_Policy policy_h,
8260 Elm_Scroller_Policy policy_v)
8262 ELM_GENLIST_CHECK(obj);
8263 eo_do(obj, elm_interface_scrollable_policy_set(policy_h, policy_v));
8267 _elm_genlist_elm_interface_scrollable_policy_set(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v)
8269 ELM_GENLIST_CHECK(obj);
8271 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
8272 (policy_v >= ELM_SCROLLER_POLICY_LAST))
8275 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_set(policy_h, policy_v));
8279 elm_genlist_scroller_policy_get(const Evas_Object *obj,
8280 Elm_Scroller_Policy *policy_h,
8281 Elm_Scroller_Policy *policy_v)
8283 ELM_GENLIST_CHECK(obj);
8284 eo_do( obj, elm_interface_scrollable_policy_get(policy_h, policy_v));
8288 _elm_genlist_elm_interface_scrollable_policy_get(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED, Elm_Scroller_Policy *policy_h, Elm_Scroller_Policy *policy_v)
8290 Elm_Scroller_Policy s_policy_h, s_policy_v;
8292 ELM_GENLIST_CHECK(obj);
8294 eo_do((Eo *)obj, elm_interface_scrollable_policy_get(&s_policy_h, &s_policy_v));
8295 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
8296 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
8300 _elm_genlist_realized_items_update(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED)
8303 Elm_Object_Item *eo_it;
8305 ELM_GENLIST_CHECK(obj);
8307 list = elm_genlist_realized_items_get(obj);
8308 EINA_LIST_FREE(list, eo_it)
8309 elm_genlist_item_update(eo_it);
8313 _elm_genlist_item_decorate_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8314 const char *decorate_it_type,
8315 Eina_Bool decorate_it_set)
8317 Elm_Genlist_Data *sd;
8320 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8321 sd = GL_IT(it)->wsd;
8323 if (!decorate_it_type) return;
8324 if (eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get())) return;
8325 if (sd->decorate_all_mode) return;
8327 if ((sd->mode_item == it) &&
8328 (!strcmp(decorate_it_type, sd->decorate_it_type)) &&
8331 if (!it->itc->decorate_item_style) return;
8332 it->decorate_it_set = decorate_it_set;
8335 if (((sd->decorate_it_type)
8336 && (strcmp(decorate_it_type, sd->decorate_it_type))) ||
8337 (decorate_it_set) || ((it == sd->mode_item) && (!decorate_it_set)))
8339 char buf[1024], buf2[1024];
8341 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8342 if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
8343 sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
8345 snprintf(buf, sizeof(buf), "elm,state,%s,passive", sd->decorate_it_type);
8346 edje_object_signal_emit(GL_IT(it)->deco_it_view, buf, "elm");
8347 edje_object_signal_emit(VIEW(it), buf, "elm");
8349 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished",
8350 sd->decorate_it_type);
8351 edje_object_signal_callback_add(GL_IT(it)->deco_it_view, buf2,
8353 _decorate_item_finished_signal_cb, it);
8354 sd->mode_item = NULL;
8357 eina_stringshare_replace(&sd->decorate_it_type, decorate_it_type);
8358 if (decorate_it_set)
8361 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8362 if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
8363 sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
8365 _decorate_item_realize(it);
8369 EOLIAN static const char *
8370 _elm_genlist_item_decorate_mode_get(Eo *eo_i EINA_UNUSED, Elm_Gen_Item *i)
8372 ELM_GENLIST_ITEM_CHECK_OR_RETURN(i, NULL);
8373 return GL_IT(i)->wsd->decorate_it_type;
8376 EOLIAN static Elm_Object_Item *
8377 _elm_genlist_decorated_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8379 return EO_OBJ(sd->mode_item);
8382 EOLIAN static Eina_Bool
8383 _elm_genlist_decorate_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8385 return sd->decorate_all_mode;
8389 _elm_genlist_decorate_mode_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool decorated)
8391 Elm_Object_Item *eo_it;
8394 decorated = !!decorated;
8395 if (sd->decorate_all_mode == decorated) return;
8396 // decorate_all_mode should be set first
8397 // because content_get func. will be called after this
8398 // and user can check whether deocrate_all_mode is enabeld.
8399 sd->decorate_all_mode = decorated;
8401 list = elm_genlist_realized_items_get(obj);
8402 EINA_LIST_FREE(list, eo_it)
8404 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8406 if (!sd->decorate_all_mode)
8408 _decorate_all_item_unrealize(it);
8410 else if (it->itc->decorate_all_item_style)
8412 _decorate_all_item_realize(it, EINA_TRUE);
8414 _access_widget_item_register(it);
8416 _changed(sd->pan_obj);
8420 _elm_genlist_reorder_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool reorder_mode)
8423 Elm_Object_Item *eo_it;
8425 if (sd->reorder_mode == !!reorder_mode) return;
8426 sd->reorder_mode = !!reorder_mode;
8428 list = elm_genlist_realized_items_get(obj);
8429 EINA_LIST_FREE(list, eo_it)
8431 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8432 if (sd->reorder_mode)
8434 edje_object_signal_emit
8435 (VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
8436 if (it->deco_all_view)
8437 edje_object_signal_emit
8438 (it->deco_all_view, SIGNAL_REORDER_MODE_SET, "elm");
8442 edje_object_signal_emit
8443 (VIEW(it), SIGNAL_REORDER_MODE_UNSET, "elm");
8444 if (it->deco_all_view)
8445 edje_object_signal_emit
8446 (it->deco_all_view, SIGNAL_REORDER_MODE_UNSET, "elm");
8451 EOLIAN static Eina_Bool
8452 _elm_genlist_reorder_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8454 return sd->reorder_mode;
8457 EOLIAN static Elm_Genlist_Item_Type
8458 _elm_genlist_item_type_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8460 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
8462 return GL_IT(it)->type;
8465 EAPI Elm_Genlist_Item_Class *
8466 elm_genlist_item_class_new(void)
8468 Elm_Genlist_Item_Class *itc = ELM_NEW(Elm_Genlist_Item_Class);
8469 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
8471 itc->version = CLASS_ALLOCATED;
8473 itc->delete_me = EINA_FALSE;
8474 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
8475 itc->homogeneous = EINA_FALSE;
8482 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
8484 if (itc && (itc->version == CLASS_ALLOCATED))
8486 itc->delete_me = EINA_TRUE;
8487 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
8497 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
8499 if (itc && (itc->version == CLASS_ALLOCATED))
8502 if (itc->refcount == 0) itc->refcount--;
8507 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
8509 if (itc && (itc->version == CLASS_ALLOCATED))
8511 if (itc->refcount > 0) itc->refcount--;
8512 if (itc->delete_me && (!itc->refcount))
8513 elm_genlist_item_class_free(itc);
8518 _elm_genlist_item_flip_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool flip)
8520 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8523 if (it->flipped == flip) return;
8528 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_content_objs,
8531 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
8532 if (GL_IT(it)->wsd->decorate_all_mode)
8533 edje_object_signal_emit
8534 (it->deco_all_view, SIGNAL_FLIP_ENABLED, "elm");
8539 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_DISABLED, "elm");
8540 if (GL_IT(it)->wsd->decorate_all_mode)
8541 edje_object_signal_emit
8542 (it->deco_all_view, SIGNAL_FLIP_DISABLED, "elm");
8544 EINA_LIST_FREE(GL_IT(it)->flip_content_objs, c)
8547 // FIXME: update texts should be done by app?
8548 _item_text_realize(it, VIEW(it), NULL);
8550 _access_widget_item_register(it);
8553 EOLIAN static Eina_Bool
8554 _elm_genlist_item_flip_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8556 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
8562 _elm_genlist_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Elm_Object_Select_Mode mode)
8564 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (sd->select_mode == mode))
8567 sd->select_mode = mode;
8569 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8570 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
8573 Elm_Object_Item *eo_it;
8574 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
8576 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8580 if (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
8583 EINA_INLIST_FOREACH(sd->items, it)
8585 if (!GL_IT(it)->block) continue;
8586 GL_IT(it)->calc_done = EINA_FALSE;
8587 GL_IT(it)->block->calc_done = EINA_FALSE;
8588 sd->calc_done = EINA_FALSE;
8589 _changed(sd->pan_obj);
8594 EOLIAN static Elm_Object_Select_Mode
8595 _elm_genlist_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8597 return sd->select_mode;
8601 _elm_genlist_highlight_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool highlight)
8603 sd->highlight = !!highlight;
8606 EOLIAN static Eina_Bool
8607 _elm_genlist_highlight_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8609 return sd->highlight;
8613 _elm_genlist_item_select_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8614 Elm_Object_Select_Mode mode)
8616 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8618 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (it->select_mode == mode))
8621 it->select_mode = mode;
8623 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8624 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
8627 if (GL_IT(it)->block && it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
8629 GL_IT(it)->calc_done = EINA_FALSE;
8630 GL_IT(it)->block->calc_done = EINA_FALSE;
8631 GL_IT(it)->wsd->calc_done = EINA_FALSE;
8632 _changed(GL_IT(it)->wsd->pan_obj);
8636 EOLIAN static Elm_Object_Select_Mode
8637 _elm_genlist_item_select_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8639 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
8641 return it->select_mode;
8644 EOLIAN Elm_Atspi_State_Set
8645 _elm_genlist_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_it, Elm_Gen_Item *it EINA_UNUSED)
8647 Elm_Atspi_State_Set ret;
8650 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
8652 eo_do(eo_it, sel = elm_obj_genlist_item_selected_get());
8654 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTABLE);
8657 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTED);
8659 if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_TREE)
8661 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDABLE);
8662 if (elm_genlist_item_expanded_get(eo_it))
8663 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8664 //TIZEN_ONLY(20160606): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8666 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8669 //TIZEN_ONLY(20160608): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8670 else if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_GROUP)
8672 if (elm_genlist_item_expanded_get(eo_it))
8673 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8675 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8683 _elm_genlist_item_elm_interface_atspi_accessible_name_get(Eo *eo_it,
8688 char *accessible_name;
8689 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_name_get());
8690 if (ret) return ret;
8692 buf = eina_strbuf_new();
8694 if (it->itc->func.text_get)
8700 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
8702 EINA_LIST_FREE(texts, key)
8704 char *str_markup = it->itc->func.text_get
8705 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
8706 char *str_utf8 = _elm_util_mkup_to_text(str_markup);
8710 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
8711 eina_strbuf_append(buf, str_utf8);
8717 accessible_name = eina_strbuf_string_steal(buf);
8718 eina_strbuf_free(buf);
8720 eina_stringshare_del(it->base->accessible_name);
8721 it->base->accessible_name = eina_stringshare_add(accessible_name);
8722 free(accessible_name);
8723 return it->base->accessible_name;
8727 _elm_genlist_item_elm_interface_atspi_accessible_children_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8729 Eina_List *ret = NULL;
8734 parts = elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "contents"));
8736 EINA_LIST_FREE(parts, key)
8739 part = edje_object_part_swallow_get(VIEW(it), key);
8740 if (part && eo_isa(part, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
8742 ret = eina_list_append(ret, part);
8743 eo_do(part, elm_interface_atspi_accessible_parent_set(eo_it));
8751 ///////////////////////////////////////////////////////////////////////////////
8752 //TIZEN ONLY:(20150623): Region show on item elements fixed
8753 //Grab and clear highlight on genlist items
8754 ///////////////////////////////////////////////////////////////////////////////
8755 EOLIAN static Eina_Bool
8756 _elm_genlist_item_elm_interface_atspi_component_highlight_grab(Eo *eo_it, Elm_Gen_Item *it)
8758 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8760 if (!TIZEN_PROFILE_WEARABLE)
8762 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
8763 eo_do_super(EO_OBJ(it), ELM_GENLIST_ITEM_CLASS, elm_interface_atspi_component_highlight_grab());
8768 // if item is realized check if in viewport
8771 Evas_Coord wy, wh, y, h;
8772 evas_object_geometry_get(WIDGET(it), NULL, &wy, NULL, &wh);
8773 evas_object_geometry_get(VIEW(it), NULL, &y, NULL, &h);
8774 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8775 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
8778 else // if item is not realized we should search if we are over or below viewport
8780 Eina_List *realized = elm_genlist_realized_items_get(WIDGET(it));
8783 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
8784 eina_list_free(realized);
8788 elm_object_accessibility_highlight_set(EO_OBJ(it), EINA_TRUE);
8789 ///TIZEN_ONLY(20170717) : expose highlight information on atspi
8790 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
8793 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
8794 // If you call eo_do_super, then you do NOT have to call smart callback.
8795 evas_object_smart_callback_call(WIDGET(it), "atspi,highlighted", EO_OBJ(it));
8802 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8803 sd->currently_highlighted_item = it;
8808 if (!TIZEN_PROFILE_WEARABLE)
8810 //TIZEN_ONLY(20170724): grab highlight using unrealized item
8811 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
8814 sd->atspi_item_to_highlight = it;//it will be highlighted when realized
8817 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8818 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
8824 EOLIAN static Eina_Bool
8825 _elm_genlist_item_elm_interface_atspi_component_highlight_clear(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8827 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8828 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8829 if(sd->currently_highlighted_item == it)
8830 sd->currently_highlighted_item = NULL;
8832 if (sd->atspi_item_to_highlight == it)
8833 sd->atspi_item_to_highlight = NULL;
8834 elm_object_accessibility_highlight_set(EO_OBJ(it), EINA_FALSE);
8835 ///TIZEN_ONLY(20170717) : expose highlight information on atspi
8836 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
8839 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8840 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
8842 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
8843 // If you call eo_do_super, then you do NOT have to call smart callback.
8844 evas_object_smart_callback_call(WIDGET(it), "atspi,unhighlighted", EO_OBJ(it));
8849 ///////////////////////////////////////////////////////////////////////////////
8852 _elm_genlist_tree_effect_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enabled EINA_UNUSED)
8854 // Need to implemented
8855 //sd->tree_effect_enabled = !!enabled;
8858 EOLIAN static Eina_Bool
8859 _elm_genlist_tree_effect_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
8865 _elm_genlist_focus_on_selection_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enabled)
8867 // Need to Implemented
8868 //sd->focus_on_selection_enabled = !!enabled;
8871 EOLIAN static Eina_Bool
8872 _elm_genlist_focus_on_selection_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
8874 // Need to Implemented
8875 //return sd->focus_on_selection_enabled;
8879 EAPI Elm_Object_Item *
8880 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth)
8882 Elm_Gen_Item *it = NULL;
8886 ELM_GENLIST_CHECK(obj) NULL;
8887 ELM_GENLIST_DATA_GET(obj, sd);
8889 if (!sd->items) return NULL;
8891 a = eina_inlist_accessor_new(sd->items);
8892 if (!a) return NULL;
8893 if (eina_accessor_data_get(a, nth, &data))
8894 it = ELM_GEN_ITEM_FROM_INLIST(data);
8895 eina_accessor_free(a);
8900 elm_genlist_fx_mode_set(Evas_Object *obj, Eina_Bool mode)
8902 ELM_GENLIST_CHECK(obj);
8903 ELM_GENLIST_DATA_GET(obj, sd);
8910 elm_genlist_fx_mode_get(const Evas_Object *obj)
8912 ELM_GENLIST_CHECK(obj) EINA_FALSE;
8913 ELM_GENLIST_DATA_GET(obj, sd);
8919 elm_genlist_item_hide_set(const Elm_Object_Item *eo_item EINA_UNUSED, Eina_Bool hide EINA_UNUSED)
8921 WRN("This API is deprecated, please use filter_set instead of this");
8925 elm_genlist_item_hide_get(const Elm_Object_Item *eo_item EINA_UNUSED)
8927 WRN("This API is deprecated, please use filter_set instead of this");
8931 ///////////////////////////////////////////////////////////////////////////////
8932 //TIZEN ONLY:(20150126): its not decided whether deprecated or not to give away
8933 ///////////////////////////////////////////////////////////////////////////////
8935 elm_genlist_realization_mode_set(Evas_Object *obj, Eina_Bool realization_mode)
8937 ELM_GENLIST_CHECK(obj);
8938 ELM_GENLIST_DATA_GET(obj, sd);
8940 if (sd->realization_mode == realization_mode) return;
8941 sd->realization_mode = realization_mode;
8945 elm_genlist_realization_mode_get(Evas_Object *obj)
8947 ELM_GENLIST_CHECK(obj) EINA_FALSE;
8948 ELM_GENLIST_DATA_GET(obj, sd);
8950 return sd->realization_mode;
8952 ///////////////////////////////////////////////////////////////////////////////
8955 elm_genlist_item_reorder_start(Elm_Object_Item *eo_item)
8957 ELM_GENLIST_ITEM_DATA_GET(eo_item, it);
8958 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8959 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
8961 sd->reorder.it = it;
8963 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8964 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
8965 (EINA_FALSE, EINA_FALSE));
8966 //sd->s_iface->hold_set(sd->obj, EINA_TRUE);
8967 //sd->s_iface->bounce_allow_set(sd->obj, EINA_FALSE, EINA_FALSE);
8968 sd->reorder_force = EINA_TRUE;
8972 elm_genlist_item_reorder_stop(Elm_Object_Item *eo_item)
8974 ELM_GENLIST_ITEM_DATA_GET(eo_item, it);
8975 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8976 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
8978 sd->reorder_force = EINA_FALSE;
8982 _elm_genlist_class_constructor(Eo_Class *klass)
8984 if (_elm_config->access_mode)
8985 _elm_genlist_smart_focus_next_enable = EINA_TRUE;
8987 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
8991 _elm_genlist_elm_interface_atspi_accessible_children_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8993 Eina_List *ret = NULL;
8996 EINA_INLIST_FOREACH(sd->items, it)
8997 ret = eina_list_append(ret, EO_OBJ(it));
9002 EOLIAN Elm_Atspi_State_Set
9003 _elm_genlist_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED)
9005 Elm_Atspi_State_Set ret;
9007 eo_do_super(obj, ELM_GENLIST_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
9009 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MANAGES_DESCENDANTS);
9011 if (elm_genlist_multi_select_get(obj))
9012 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MULTISELECTABLE);
9018 _elm_genlist_elm_interface_atspi_selection_selected_children_count_get(Eo *objm EINA_UNUSED, Elm_Genlist_Data *pd)
9020 return eina_list_count(pd->selected);
9024 _elm_genlist_elm_interface_atspi_selection_selected_child_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_idx)
9026 return eina_list_nth(pd->selected, child_idx);
9030 _elm_genlist_elm_interface_atspi_selection_child_select(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9033 if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
9035 EINA_INLIST_FOREACH(pd->items, item)
9037 if (child_index-- == 0)
9039 elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
9048 _elm_genlist_elm_interface_atspi_selection_selected_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9053 EINA_LIST_FOREACH(pd->selected, l, item)
9055 if (child_index-- == 0)
9057 elm_genlist_item_selected_set(item, EINA_FALSE);
9065 _elm_genlist_elm_interface_atspi_selection_is_child_selected(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9069 EINA_INLIST_FOREACH(pd->items, item)
9071 if (child_index-- == 0)
9073 return elm_genlist_item_selected_get(EO_OBJ(item));
9080 _elm_genlist_elm_interface_atspi_selection_all_children_select(Eo *obj, Elm_Genlist_Data *pd)
9084 if (!elm_genlist_multi_select_get(obj))
9087 EINA_INLIST_FOREACH(pd->items, item)
9088 elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
9094 _elm_genlist_elm_interface_atspi_selection_clear(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd)
9096 return _all_items_deselect(pd);
9100 _elm_genlist_elm_interface_atspi_selection_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9103 if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
9105 EINA_INLIST_FOREACH(pd->items, item)
9107 if (child_index-- == 0)
9109 elm_genlist_item_selected_set(EO_OBJ(item), EINA_FALSE);
9117 // TIZEN only (20150914) : Accessibility: updated highlight change during genlist and list scroll
9118 static int _is_item_in_viewport(int viewport_y, int viewport_h, int obj_y, int obj_h)
9120 if (obj_y + obj_h <= viewport_y)
9122 else if (obj_y >= viewport_y + viewport_h)
9128 _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)
9130 if (!_elm_atspi_enabled())
9132 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
9136 int old_x, old_y, delta_y;
9137 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_get(&old_x,&old_y));
9138 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
9139 delta_y = old_y - y;
9141 //check if highlighted item is genlist descendant
9142 Evas_Object * highlighted_obj = _elm_object_accessibility_currently_highlighted_get();
9143 if (eo_isa(highlighted_obj, ELM_WIDGET_ITEM_CLASS))
9145 Elm_Widget_Item_Data *id = eo_data_scope_get(highlighted_obj, ELM_WIDGET_ITEM_CLASS);
9146 highlighted_obj = id->view;
9149 Evas_Object * parent = highlighted_obj;
9150 if (eo_isa(highlighted_obj, ELM_WIDGET_CLASS))
9152 while ((parent = elm_widget_parent_get(parent)))
9156 else if (eo_isa(highlighted_obj, EDJE_OBJECT_CLASS))
9158 while ((parent = evas_object_smart_parent_get(parent)))
9162 // TIZEN_ONLY(20160805): set _accessibility_currently_highlighted_obj to NULL in object delete callback
9165 WRN("Improper highlighted object: %p", highlighted_obj);
9172 int obj_x, obj_y, w, h, hx, hy, hw, hh;
9173 evas_object_geometry_get(obj, &obj_x, &obj_y, &w, &h);
9175 evas_object_geometry_get(highlighted_obj, &hx, &hy, &hw, &hh);
9177 Elm_Gen_Item * next_previous_item = NULL;
9178 int viewport_position_result = _is_item_in_viewport(obj_y, h, hy, hh);
9179 //only highlight if move direction is correct
9180 //sometimes highlighted item is brought in and it does not fit viewport
9181 //however content goes to the viewport position so soon it will
9182 //meet _is_item_in_viewport condition
9183 if ((viewport_position_result < 0 && delta_y > 0) ||
9184 (viewport_position_result > 0 && delta_y < 0))
9187 Eina_List *realized_items = elm_genlist_realized_items_get(obj);
9190 Eina_Bool traverse_direction = viewport_position_result > 0;
9191 l = traverse_direction ? realized_items: eina_list_last(realized_items);
9195 item = eina_list_data_get(l);
9196 ELM_GENLIST_ITEM_DATA_GET(item, it_data);
9197 next_previous_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it_data));
9198 evas_object_geometry_get(VIEW(next_previous_item), &hx, &hy, &hw, &hh);
9199 if (_is_item_in_viewport(obj_y, h, hy, hh) == 0)
9202 next_previous_item = NULL;
9204 l = traverse_direction ? eina_list_next(l): eina_list_prev(l);
9207 if (next_previous_item)
9209 elm_object_accessibility_highlight_set(EO_OBJ(next_previous_item), EINA_TRUE);
9210 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(next_previous_item), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
9214 // Tizen only (20150914)
9215 #include "elm_genlist.eo.c"
9216 #include "elm_genlist_item.eo.c"