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");
420 edje_object_message_signal_process(VIEW(it));
422 edje_object_mirrored_set(VIEW(it),
423 elm_widget_mirrored_get(WIDGET(it)));
424 edje_object_scale_set(VIEW(it),
425 elm_widget_scale_get(WIDGET(it))
426 * elm_config_scale_get());
428 ic->base_view = VIEW(it);
429 ic->multiline = GL_IT(it)->multiline;
430 ic->item_class = it->itc;
431 ic->contents = contents;
432 evas_object_hide(ic->base_view);
433 evas_object_move(ic->base_view, -9999, -9999);
435 sd->item_cache = eina_inlist_prepend(sd->item_cache, EINA_INLIST_GET(ic));
436 sd->item_cache_count++;
442 _item_cache_pop(Elm_Gen_Item *it)
444 Item_Cache *ic = NULL;
446 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
448 if (!it->itc) return EINA_FALSE;
450 EINA_INLIST_FOREACH_SAFE(sd->item_cache, l, ic)
452 if (it->itc && ic->item_class &&
453 (it->itc == ic->item_class))
456 eina_inlist_remove(sd->item_cache, EINA_INLIST_GET(ic));
457 sd->item_cache_count--;
459 VIEW(it) = ic->base_view;
460 GL_IT(it)->multiline = ic->multiline;
462 eina_list_free(ic->contents);
471 // TIZEN_ONLY(20150828) : to prevent unnecessary genlist rendering
472 // _changed is called instead of evas_object_smart_changed API.
474 _changed(Evas_Object *pan_obj)
476 Elm_Genlist_Pan_Data *psd = eo_data_scope_get(pan_obj, MY_PAN_CLASS);
477 Elm_Genlist_Data *sd = psd->wsd;
479 if (sd->viewport_w > 1) evas_object_smart_changed(pan_obj);
484 _elm_genlist_pan_elm_pan_pos_set(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord x, Evas_Coord y)
486 if ((x == psd->wsd->pan_x) && (y == psd->wsd->pan_y)) return;
488 if (y > psd->wsd->pan_y) psd->wsd->dir = 1;
489 else psd->wsd->dir = -1;
497 _elm_genlist_pan_elm_pan_pos_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y)
499 if (x) *x = psd->wsd->pan_x;
500 if (y) *y = psd->wsd->pan_y;
503 // TIZEN_ONLY(20150705): genlist item align feature
504 static Elm_Gen_Item *
505 _elm_genlist_pos_adjust_xy_item_get(const Evas_Object *obj,
511 ELM_GENLIST_CHECK(obj) NULL;
512 ELM_GENLIST_DATA_GET(obj, sd);
514 EINA_INLIST_FOREACH(sd->blocks, itb)
518 if (!ELM_RECTS_INTERSECT(itb->x - sd->pan_x,
520 sd->minw, itb->minh, x, y, 1, 1))
522 EINA_LIST_FOREACH(itb->items, l, it)
524 Evas_Coord itx, ity, itw, ith;
526 itx = itb->x + it->x - sd->pan_x;
527 ity = itb->y + it->y - sd->pan_y;
529 itw = (GL_IT(it)->w ? GL_IT(it)->w : sd->minw);
530 ith = GL_IT(it)->minh;
532 if (ELM_RECTS_INTERSECT(itx, ity, itw, ith, x, y, 1, 1))
540 static Elm_Gen_Item *
541 _adjust_item_align(Elm_Gen_Item *it)
543 if (!it) return NULL;
546 Elm_Gen_Item *adjust_item = it;
547 Elm_Object_Item *eo_item = NULL;
548 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
550 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(adjust_item), wd, NULL);
552 if (!wd || !(wd->scroll_item_align_enable)) return it;
553 if (!sd || !sd->aligned_item || (it == sd->aligned_item)) return it;
555 direction = GL_IT(adjust_item)->scrl_y - GL_IT(sd->aligned_item)->scrl_y;
556 while (adjust_item && loop_count < 10)
558 const char *align = NULL;
559 if (!VIEW(adjust_item))
561 _item_realize(adjust_item, EINA_TRUE);
562 align = edje_object_data_get(VIEW(adjust_item), "align");
563 _item_unrealize(adjust_item, EINA_TRUE);
566 align = edje_object_data_get(VIEW(adjust_item), "align");
568 if (align && !strcmp(align, "off"))
571 eo_item = elm_genlist_item_prev_get(EO_OBJ(adjust_item));
573 eo_item = elm_genlist_item_next_get(EO_OBJ(adjust_item));
574 adjust_item = eo_data_scope_get(eo_item, ELM_GENLIST_ITEM_CLASS);
581 if (adjust_item) return adjust_item;
584 while (adjust_item && loop_count < 10)
586 const char *align = NULL;
587 if (!VIEW(adjust_item))
589 _item_realize(adjust_item, EINA_TRUE);
590 align = edje_object_data_get(VIEW(adjust_item), "align");
591 _item_unrealize(adjust_item, EINA_TRUE);
594 align = edje_object_data_get(VIEW(adjust_item), "align");
596 if (align && !strcmp(align, "off"))
599 eo_item = elm_genlist_item_prev_get(EO_OBJ(adjust_item));
601 eo_item = elm_genlist_item_next_get(EO_OBJ(adjust_item));
602 adjust_item = eo_data_scope_get(eo_item, ELM_GENLIST_ITEM_CLASS);
616 _elm_genlist_pan_elm_pan_pos_adjust(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *x EINA_UNUSED, Evas_Coord *y)
618 ELM_WIDGET_DATA_GET_OR_RETURN(psd->wobj, wd);
619 Elm_Genlist_Data *sd = psd->wsd;
621 if (!(wd->scroll_item_align_enable)) return;
625 Elm_Object_Item *eo_it;
627 Evas_Coord cx = 0, cy = 0;
628 Evas_Coord it_y, it_h;
631 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
632 (NULL, NULL, &vw, &vh));
633 if (!strcmp(wd->scroll_item_valign, "center"))
639 sd->adjusted_item = _elm_genlist_pos_adjust_xy_item_get(sd->obj, cx, cy);
641 if ((abs(*y) > FLICK_GAP) && (sd->adjusted_item == sd->aligned_item))
643 Elm_Gen_Item *adjusted_item = NULL;
645 eo_it = elm_genlist_item_next_get(EO_OBJ(sd->adjusted_item));
647 eo_it = elm_genlist_item_prev_get(EO_OBJ(sd->adjusted_item));
648 adjusted_item = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
650 sd->adjusted_item = adjusted_item;
652 sd->adjusted_item = _adjust_item_align(sd->adjusted_item);
653 if (!sd->adjusted_item) return;
655 cy += psd->wsd->pan_y;
656 it_y = sd->adjusted_item->y + GL_IT(sd->adjusted_item)->block->y;
657 it_h = GL_IT(sd->adjusted_item)->h;
659 if (GL_IT(sd->adjusted_item)->h <= vh)
661 it_h = it_y + (it_h / 2);
666 int it_b_y = it_y + it_h;
668 if (it_y <= cy && it_y >= cy - half_vh)
670 *y -= half_vh - (cy - it_y);
672 else if (it_b_y >= cy && it_b_y <= cy + half_vh)
674 *y += half_vh - (it_b_y - cy);
678 if (!*y && !sd->unhighlighted)
679 sd->adjusted_item = NULL;
681 evas_object_smart_changed(sd->pan_obj);
686 _elm_genlist_pan_elm_pan_pos_max_get(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y)
690 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
691 ow = psd->wsd->minw - ow;
693 oh = psd->wsd->minh - oh;
700 _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)
707 _elm_genlist_pan_elm_pan_content_size_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *w, Evas_Coord *h)
709 if (w) *w = psd->wsd->minw;
710 if (h) *h = psd->wsd->minh;
714 _elm_genlist_pan_evas_object_smart_del(Eo *obj, Elm_Genlist_Pan_Data *psd)
716 ecore_job_del(psd->resize_job);
718 eo_do_super(obj, MY_PAN_CLASS, evas_obj_smart_del());
722 _elm_genlist_pan_evas_object_smart_move(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord _gen_param2 EINA_UNUSED,
723 Evas_Coord _gen_param3 EINA_UNUSED)
730 _elm_genlist_pan_evas_object_smart_resize(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord w, Evas_Coord h)
732 if ((w > 1 || h > 1))
734 if (psd->wsd->queue && !psd->wsd->queue_idle_enterer)
736 psd->wsd->queue_idle_enterer = ecore_idle_enterer_add(_queue_idle_enter, psd->wsd);
739 if (psd->wsd->mode == ELM_LIST_COMPRESS &&
740 psd->wsd->prev_viewport_w != w)
743 ELM_WIDGET_DATA_GET_OR_RETURN(psd->wsd->obj, wd);
744 EINA_INLIST_FOREACH(psd->wsd->blocks, itb)
748 EINA_LIST_FOREACH(itb->items, l, it)
750 if (!wd->scroll_item_align_enable && !GL_IT(it)->multiline) continue;
751 if (GL_IT(it)->wsd->realization_mode)
753 GL_IT(it)->calc_done = EINA_FALSE;
754 GL_IT(it)->block->calc_done = EINA_FALSE;
758 GL_IT(it)->resized = EINA_TRUE;
761 GL_IT(it)->calc_done = EINA_FALSE;
762 GL_IT(it)->block->calc_done = EINA_FALSE;
764 else _item_queue(it, NULL);
768 psd->wsd->prev_viewport_w = w;
770 psd->wsd->viewport_w = w;
771 psd->wsd->viewport_h = h;
773 psd->wsd->calc_done = EINA_FALSE;
778 _item_text_realize(Elm_Gen_Item *it,
784 if (it->itc->func.text_get)
789 source = elm_widget_stringlist_get
790 (edje_object_data_get(target, "texts"));
791 EINA_LIST_FREE(source, key)
793 if (parts && fnmatch(parts, key, FNM_PERIOD))
796 char *s = it->itc->func.text_get
797 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
801 edje_object_part_text_escaped_set(target, key, s);
804 snprintf(buf, sizeof(buf), "elm,state,%s,visible", key);
805 edje_object_signal_emit(target, buf, "elm");
809 edje_object_part_text_set(target, key, "");
810 snprintf(buf, sizeof(buf), "elm,state,%s,hidden", key);
811 edje_object_signal_emit(target, buf, "elm");
814 edje_object_message_signal_process(target);
815 if (_elm_atspi_enabled())
816 elm_interface_atspi_accessible_name_changed_signal_emit(EO_OBJ(it));
821 _changed_size_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
823 Elm_Gen_Item *it = data;
824 GL_IT(it)->calc_done = EINA_FALSE;
825 GL_IT(it)->block->calc_done = EINA_FALSE;
826 GL_IT(it)->wsd->calc_done = EINA_FALSE;
827 _changed(GL_IT(it)->wsd->pan_obj);
830 // FIXME: There are applications which do not use elm_win as top widget.
831 // This is workaround! Those could not use focus!
833 static Eina_Bool _focus_enabled(Evas_Object *obj)
835 if (!elm_widget_focus_get(obj)) return EINA_FALSE;
837 const Evas_Object *win = elm_widget_top_get(obj);
838 const char *type = evas_object_type_get(win);
840 if (type && !strcmp(type, "elm_win"))
842 return elm_win_focus_highlight_enabled_get(win);
849 _widget_calculate_recursive(Eo *obj)
851 Elm_Widget_Smart_Data *pd = NULL;
855 if (!eo_isa(obj, ELM_WIDGET_CLASS)) return;
857 pd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
860 if (!evas_object_smart_need_recalculate_get(obj) &&
861 !evas_object_smart_need_recalculate_get(pd->resize_obj))
864 EINA_LIST_FOREACH(pd->subobjs, l, child)
865 _widget_calculate_recursive(child);
867 evas_object_smart_calculate(obj);
871 _item_content_realize(Elm_Gen_Item *it,
873 Eina_List **contents,
878 Evas_Object *content;
885 EINA_LIST_FREE(*contents, content)
886 _item_content_free(content);
888 if ((!it->itc->func.content_get) &&
889 ((it->itc->version < 3) || (!it->itc->func.reusable_content_get))) return;
891 source = elm_widget_stringlist_get(edje_object_data_get(target, src));
893 EINA_LIST_FREE(source, key)
895 if (parts && fnmatch(parts, key, FNM_PERIOD))
898 Evas_Object *old = NULL;
899 old = edje_object_part_swallow_get(target, key);
901 // Reuse content by popping from the cache
903 if (it->itc->version >= 3 && it->itc->func.reusable_content_get)
904 content = it->itc->func.reusable_content_get(
905 (void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key, old);
908 // Call the content get
909 if (it->itc->func.content_get)
910 content = it->itc->func.content_get
911 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
914 snprintf(buf, sizeof(buf), "elm,state,%s,hidden", key);
915 edje_object_signal_emit(target, buf, "elm");
921 // FIXME: Genlist item doesn't update its size when the size of
922 // content is changed, so deferred calculation for content should
923 // be performed before realization.
924 if (eo_isa(content, ELM_WIDGET_CLASS))
926 ELM_WIDGET_DATA_GET_OR_RETURN(content, wd);
928 // FIXME : Layout need sizing eval before group calculate
929 if (eo_class_get(content) == ELM_LAYOUT_CLASS)
930 eo_do(content, elm_obj_layout_sizing_eval());
932 _widget_calculate_recursive(content);
935 if (!edje_object_part_swallow(target, key, content))
937 ERR("%s (%p) can not be swallowed into %s",
938 evas_object_type_get(content), content, key);
939 evas_object_del(content);
942 elm_widget_sub_object_add(WIDGET(it), content);
944 *contents = eina_list_append(*contents, content);
946 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()))
947 elm_widget_disabled_set(content, EINA_TRUE);
949 if (GL_IT(it)->wsd->realization_mode)
951 evas_object_event_callback_add
952 (content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
953 _changed_size_hints, it);
956 snprintf(buf, sizeof(buf), "elm,state,%s,visible", key);
957 edje_object_signal_emit(target, buf, "elm");
959 // If content object is focused,
960 // genlist item should be focused.
961 if (elm_widget_focused_object_get(content))
963 if (GL_IT(it)->wsd->focused_item != it)
964 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
966 GL_IT(it)->wsd->focused_content = content;
969 if (old && content != old)
971 *contents = eina_list_remove(*contents, old);
972 _item_content_free(old);
978 _item_state_realize(Elm_Gen_Item *it,
982 if (it->itc->func.state_get)
988 src = elm_widget_stringlist_get
989 (edje_object_data_get(target, "states"));
990 EINA_LIST_FREE(src, key)
992 if (parts && fnmatch(parts, key, FNM_PERIOD))
995 Eina_Bool on = it->itc->func.state_get
996 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
1000 snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1001 edje_object_signal_emit(target, buf, "elm");
1005 snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1006 edje_object_signal_emit(target, buf, "elm");
1013 _view_theme_update(Elm_Gen_Item *it, Evas_Object *view, const char *style)
1019 snprintf(buf, sizeof(buf), "item/%s", style ? : "default");
1021 Elm_Theme_Apply th_ret =
1022 elm_widget_theme_object_set(WIDGET(it), view, "genlist", buf,
1023 elm_widget_style_get(WIDGET(it)));
1024 if (th_ret == ELM_THEME_APPLY_FAILED)
1026 ERR("%s is not a valid genlist item style. "
1027 "Automatically falls back into default style.",
1029 elm_widget_theme_object_set
1030 (WIDGET(it), view, "genlist", "item/default", "default");
1033 edje_object_mirrored_set(view, elm_widget_mirrored_get(WIDGET(it)));
1034 edje_object_scale_set(view, elm_widget_scale_get(WIDGET(it))
1035 * elm_config_scale_get());
1037 GL_IT(it)->multiline = EINA_FALSE;
1038 Eina_List *txts = elm_widget_stringlist_get
1039 (edje_object_data_get(view, "texts"));
1040 EINA_LIST_FOREACH(txts, l, key)
1042 const Evas_Object *txt_obj = NULL;
1043 const char *type = NULL;
1044 txt_obj = edje_object_part_object_get(view, key);
1045 if (txt_obj) type = evas_object_type_get(txt_obj);
1046 if (!type) continue;
1047 if (type && strcmp(type, "textblock")) continue;
1049 const Evas_Textblock_Style *tb_style =
1050 evas_object_textblock_style_get(txt_obj);
1053 const char *str = evas_textblock_style_get(tb_style);
1056 if (strstr(str, "wrap="))
1058 GL_IT(it)->multiline = EINA_TRUE;
1064 eina_list_free(txts);
1067 static Evas_Object *
1068 _view_create(Elm_Gen_Item *it, const char *style)
1070 Evas_Object *view = edje_object_add(evas_object_evas_get(WIDGET(it)));
1071 evas_object_smart_member_add(view, GL_IT(it)->wsd->pan_obj);
1072 elm_widget_sub_object_add(WIDGET(it), view);
1073 edje_object_scale_set(view, elm_widget_scale_get(WIDGET(it)) *
1074 elm_config_scale_get());
1076 _view_theme_update(it, view, style);
1081 _view_clear(Evas_Object *view, Eina_List **contents)
1086 Eina_List *texts = elm_widget_stringlist_get
1087 (edje_object_data_get(view, "texts"));
1088 EINA_LIST_FREE(texts, part)
1089 edje_object_part_text_set(view, part, NULL);
1093 EINA_LIST_FREE(*contents, c)
1094 _item_content_free(c);
1099 _view_inflate(Evas_Object *view, Elm_Gen_Item *it, Eina_List **contents)
1102 _item_text_realize(it, view, NULL);
1103 if (contents) _item_content_realize(it, view, contents, "contents", NULL);
1104 _item_state_realize(it, view, NULL);
1108 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1110 if (it->position_update || GL_IT(it)->block->position_update)
1112 evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, EO_OBJ(it));
1113 it->position_update = EINA_FALSE;
1118 _access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
1123 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1124 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1126 buf = eina_strbuf_new();
1128 if (it->itc->func.text_get)
1134 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1136 EINA_LIST_FREE(texts, key)
1138 char *s = it->itc->func.text_get
1139 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
1141 s = _elm_util_mkup_to_text(s);
1145 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
1146 eina_strbuf_append(buf, s);
1152 ret = eina_strbuf_string_steal(buf);
1153 eina_strbuf_free(buf);
1158 _access_state_cb(void *data, Evas_Object *obj EINA_UNUSED)
1160 Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1162 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1164 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()))
1165 return strdup(E_("Disabled"));
1171 _access_activate_cb(void *data,
1172 Evas_Object *part_obj EINA_UNUSED,
1173 Elm_Object_Item *item EINA_UNUSED)
1175 Elm_Gen_Item *it = data;
1176 Evas_Object *parent = WIDGET(it);
1180 if (evas_object_freeze_events_get(parent)) return;
1181 parent = evas_object_smart_parent_get(parent);
1188 _access_widget_item_register(Elm_Gen_Item *it)
1190 Elm_Access_Info *ai;
1191 Eina_List *orders = NULL;
1192 Eina_List *l = NULL;
1193 Evas_Object *c, *child, *ret;
1194 Eina_List *listn, *ln;
1195 Eina_List *texts, *contents;
1197 if (!_elm_config->access_mode) return;
1199 /* access: unregister item which have no text and content */
1200 texts = elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1201 contents = elm_widget_stringlist_get(edje_object_data_get(VIEW(it),
1203 if (!texts && !contents) return;
1204 eina_list_free(texts);
1205 eina_list_free(contents);
1207 _elm_access_widget_item_unregister(it->base);
1208 // FIXME: if item->view is not it->item->deco_all_view!!
1209 if (it->deco_all_view)
1211 Evas_Object *acc = elm_access_object_register
1212 (it->deco_all_view, WIDGET(it));
1213 it->base->access_obj = acc;
1217 _elm_access_widget_item_register(it->base);
1220 ai = _elm_access_info_get(eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_access_object_get()));
1221 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1222 _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
1223 _elm_access_activate_callback_set(ai, _access_activate_cb, it);
1225 elm_object_item_access_order_unset(EO_OBJ(it));
1228 EINA_LIST_FOREACH(GL_IT(it)->flip_content_objs, l, c)
1230 if (elm_widget_can_focus_get(c))
1232 orders = eina_list_append(orders, c);
1238 if (it->deco_all_view)
1240 EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, c)
1242 if (elm_widget_can_focus_get(c))
1244 orders = eina_list_append(orders, c);
1248 EINA_LIST_FOREACH(it->content_objs, l, c)
1250 if (elm_widget_can_focus_get(c))
1252 /*FIXME The below change is done to push datetime's access objects
1253 like date field and time field in to genlist focus list to get focus.*/
1254 listn = elm_widget_can_focus_child_list_get(c);
1257 EINA_LIST_FOREACH(listn, ln, child)
1259 orders = eina_list_append(orders, child);
1264 orders = eina_list_append(orders, c);
1270 elm_object_item_access_order_set(EO_OBJ(it), orders);
1274 _item_unrealize(Elm_Gen_Item *it,
1277 Evas_Object *content;
1278 Eina_List *cache = NULL;
1280 if (!it->realized) return;
1282 if (GL_IT(it)->wsd->reorder.it == it)
1284 WRN("reordering item should not be unrealized");
1289 evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, EO_OBJ(it));
1290 _elm_access_widget_item_unregister(it->base);
1291 elm_object_item_access_order_unset(EO_OBJ(it));
1292 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
1293 if (_elm_atspi_enabled())
1295 elm_interface_atspi_accessible_removed(EO_OBJ(it));
1296 elm_interface_atspi_accessible_children_changed_del_signal_emit(GL_IT(it)->wsd->obj, EO_OBJ(it));
1302 Elm_Widget_Item_Signal_Data *wisd;
1303 EINA_LIST_FOREACH(it->base->signals, l, wisd)
1305 eo_do(EO_OBJ(it), elm_wdg_item_signal_callback_del
1306 (wisd->emission, wisd->source, (Elm_Object_Item_Signal_Cb)wisd->func));
1309 _decorate_item_unrealize(it);
1310 _decorate_all_item_unrealize(it);
1312 _item_edje_callbacks_del(it);
1314 _item_mouse_callbacks_del(it, VIEW(it));
1315 if (!calc && it->item->proxy)
1317 evas_object_image_source_visible_set(it->item->proxy, EINA_TRUE);
1318 evas_object_smart_member_del(it->item->proxy);
1319 evas_object_del(it->item->proxy);
1320 it->item->proxy = NULL;
1323 EINA_LIST_FREE(GL_IT(it)->flip_content_objs, content)
1324 evas_object_del(content);
1325 if (it->spacer) evas_object_del(it->spacer);
1326 _view_clear(VIEW(it), NULL);
1328 // TIZEN ONLY : for banded ux
1329 if (!TIZEN_PROFILE_WEARABLE)
1331 if (GL_IT(it)->banded_bg)
1332 ELM_SAFE_FREE(GL_IT(it)->banded_bg, evas_object_del);
1333 if (GL_IT(it)->wsd->banded_bg_on)
1335 if (it->item->banded_anim) ecore_animator_del(it->item->banded_anim);
1336 it->item->banded_anim = NULL;
1340 if (GL_IT(it)->highlight_timer)
1342 ecore_timer_del(GL_IT(it)->highlight_timer);
1343 GL_IT(it)->highlight_timer = NULL;
1347 ecore_timer_del(it->long_timer);
1348 it->long_timer = NULL;
1351 eo_do(EO_OBJ(it), elm_wdg_item_track_cancel());
1352 //TIZEN_ONLY(20161013): clean up elm color class feature
1353 if (it->base->color_classes)
1354 edje_object_color_class_clear(VIEW(it));
1356 EINA_LIST_FREE(it->content_objs, content)
1358 if (it->itc->version >= 3 && it->itc->func.reusable_content_get)
1360 // Unfocus content object for initialization.
1361 if (GL_IT(it)->wsd->focused_content == content)
1363 elm_object_focus_set(content, EINA_FALSE);
1364 GL_IT(it)->wsd->focused_content = NULL;
1366 if (elm_widget_disabled_get(content))
1367 elm_widget_disabled_set(content, EINA_FALSE);
1369 cache = eina_list_append(cache, content);
1373 if (GL_IT(it)->wsd->focused_content == content)
1374 GL_IT(it)->wsd->focused_content = NULL;
1375 elm_object_focus_set(content, EINA_FALSE);
1376 evas_object_del(content);
1380 _item_cache_push(it, cache);
1382 it->realized = EINA_FALSE;
1386 _item_block_unrealize(Item_Block *itb)
1389 const Eina_List *l, *ll;
1390 Evas_Object *content;
1391 Eina_Bool unrealize = EINA_TRUE;
1393 // Do not check itb->realized
1394 // because it->item->block can be changed
1396 EINA_LIST_FOREACH(itb->items, l, it)
1398 if (!(((GL_IT(it)->wsd->reorder_force) || (GL_IT(it)->wsd->reorder_mode))
1399 && (GL_IT(it)->wsd->reorder.it == it))
1400 && !it->flipped && it->realized)
1402 /* FIXME: when content is on focused and unrealize item,
1403 focus is set to other object and scroll will be bring in */
1404 if (_elm_config->access_mode)
1406 EINA_LIST_FOREACH(it->content_objs, ll, content)
1408 if (elm_object_focus_get(content))
1410 unrealize = EINA_FALSE;
1416 _item_unrealize(it, EINA_FALSE);
1417 unrealize = EINA_TRUE;
1420 itb->realized = EINA_FALSE;
1426 Elm_Genlist_Data *sd = data;
1428 Evas_Coord minw = 99999999, minh = 0, vw = 0, vh = 0, current_minh = 0;
1429 Evas_Coord processed_size = sd->minh;
1432 if (sd->calc_done) return;
1434 // TIZEN_ONLY(20150828) : Calculate item which position on viewport area
1436 ((sd->viewport_h > processed_size) && (cnt < MAX_ITEMS_PER_BLOCK)))
1439 tmp = eina_list_data_get(sd->queue);
1440 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
1441 if (!_item_process(sd, tmp)) continue;
1442 processed_size += GL_IT(tmp)->minh;
1443 tmp->item->queued = EINA_FALSE;
1447 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
1448 (NULL, NULL, &vw, &vh));
1449 EINA_INLIST_FOREACH(sd->blocks, itb)
1453 _item_block_calc(itb, vw, vh);
1454 if (minw > itb->minw) minw = itb->minw;
1458 if ((sd->mode == ELM_LIST_COMPRESS) && (minw > vw))
1460 else if (minw < vw) minw = vw;
1462 if ((minw != sd->minw) || (minh != sd->minh))
1464 Eina_Bool load_done = EINA_FALSE;
1466 current_minh = sd->minh;
1469 if (!sd->queue && (minh != current_minh)) load_done = EINA_TRUE;
1470 elm_layout_sizing_eval(sd->obj);
1471 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
1473 evas_object_smart_callback_call(sd->obj, SIG_LOADED, NULL);
1474 sd->processed_sizes = 0;
1477 sd->calc_done = EINA_TRUE;
1481 _elm_genlist_elm_layout_sizing_eval(Eo *obj, Elm_Genlist_Data *sd)
1483 Evas_Coord minw = 0, minh = 0, maxw = -1, maxh = -1;
1485 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1487 if (sd->on_sub_del) return;;
1489 evas_object_size_hint_min_get(obj, &minw, NULL);
1490 evas_object_size_hint_max_get(obj, &maxw, &maxh);
1491 edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
1496 minw = minw + sd->minw;
1501 minh = minh + sd->minh;
1504 if ((maxw > 0) && (minw > maxw))
1506 if ((maxh > 0) && (minh > maxh))
1509 evas_object_size_hint_min_set(obj, minw, minh);
1510 evas_object_size_hint_max_set(obj, maxw, maxh);
1514 _elm_genlist_content_min_limit_cb(Evas_Object *obj,
1518 ELM_GENLIST_DATA_GET(obj, sd);
1520 if ((sd->mode == ELM_LIST_LIMIT) ||
1521 (sd->mode == ELM_LIST_EXPAND)) return;
1525 elm_layout_sizing_eval(obj);
1529 _focus_bg_show(Elm_Gen_Item *it)
1532 Evas_Coord h = 0, rectangle_h = GL_IT(it)->h;
1533 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wd);
1534 const Evas_Object *top, *bottom;
1535 Evas_Object *rectangle;
1536 const char *focus_bg;
1538 if (!VIEW(it)) return;
1539 focus_bg = edje_object_data_get(VIEW(it), "focus_bg");
1540 if (focus_bg && !strcmp(focus_bg, "off"))
1542 edje_object_signal_emit(wd->resize_obj, SIGNAL_FOCUS_BG_HIDE, "elm");
1546 evas_object_geometry_get(wd->resize_obj, NULL, NULL, &w, NULL);
1547 top = edje_object_part_object_get(VIEW(it), "elm.padding.focus_bg.top");
1548 bottom = edje_object_part_object_get(VIEW(it), "elm.padding.focus_bg.bottom");
1552 evas_object_geometry_get(top, NULL, NULL, NULL, &h);
1554 evas_object_geometry_get(bottom, NULL, NULL, NULL, &h);
1558 rectangle = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
1559 evas_object_size_hint_min_set(rectangle, w, rectangle_h);
1560 evas_object_size_hint_max_set(rectangle, w, rectangle_h);
1561 evas_object_color_set(rectangle, 0, 0, 0, 0);
1562 elm_object_part_content_set(wd->obj, "focus_bg_size", rectangle);
1564 edje_object_signal_emit(wd->resize_obj, SIGNAL_FOCUS_BG_SHOW, "elm");
1568 _item_position(Elm_Gen_Item *it,
1576 Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0;
1577 Evas_Coord ix = 0, iy = 0, iw = 0, ih = 0;
1578 Elm_Gen_Item *target = it;
1579 Elm_Genlist_Data *sd = GL_IT(target)->wsd;
1580 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(target), wsd);
1584 iw = GL_IT(target)->w;
1585 ih = GL_IT(target)->h;
1587 evas_object_resize(view, iw, ih);
1588 evas_object_move(view, ix, iy);
1589 evas_object_show(view);
1591 if (wsd->scroll_item_align_enable)
1594 int pre_multiplied_color = 0;
1595 int resize_width = 0;
1596 int resize_hight = 0;
1599 double move_v[4] = {0.49, 0.99, 0.45, 1.0};
1600 double scale_v[4] = {0.49, 0.14, 1, 0.63};
1602 evas_object_geometry_get(wsd->obj, &ox, &oy, &ow, &oh);
1603 int g_center = oy + oh / 2;
1604 int i_center = GL_IT(target)->scrl_y + GL_IT(target)->h / 2;
1606 if (target->item->proxy && !ELM_RECTS_INTERSECT(ix, iy, iw, ih, ox, oy, ow, oh))
1607 evas_object_hide(target->item->proxy);
1610 const char *vi_effect = edje_object_data_get(VIEW(target), "vi_effect");
1611 if (vi_effect && !strcmp(vi_effect, "on"))
1613 ratio = (float)abs(g_center - i_center) / (float)((oh / 2) + ih / 2);
1614 color = DIMED_ITEM_COLOR + ((255 - DIMED_ITEM_COLOR) * (1.0 - ratio));
1615 double scale_p = ecore_animator_pos_map_n(ratio, ECORE_POS_MAP_CUBIC_BEZIER, 4, scale_v);
1616 scale = elm_config_scale_get() - (scale_p * ALIGNED_ITEM_SCALE_FACTOR);
1618 resize_width = GL_IT(target)->w * (scale / elm_config_scale_get());
1619 if (!((iw - resize_width) % 2))
1622 iw = resize_width + 1;
1623 ix = GL_IT(target)->scrl_x + (GL_IT(target)->w - iw) / 2;
1624 resize_hight = GL_IT(target)->h * (scale / elm_config_scale_get());
1626 if (!((ih - resize_hight) % 2))
1629 ih = resize_hight + 1;
1631 if (i_center < g_center)
1633 double move_p = ecore_animator_pos_map_n(ratio, ECORE_POS_MAP_CUBIC_BEZIER, 4, move_v);
1634 iy = GL_IT(target)->scrl_y + move_p * (GL_IT(target)->h - ih);
1637 iy = GL_IT(target)->scrl_y;
1639 const char *dim = edje_object_data_get(view, "dim");
1640 if (!dim || (dim && !strcmp(dim, "on")))
1642 pre_multiplied_color = 255 * color >> 8;
1643 if (!elm_object_item_disabled_get(EO_OBJ(target)))
1644 evas_object_color_set(target->item->proxy, pre_multiplied_color, pre_multiplied_color, pre_multiplied_color, color);
1646 evas_object_color_set(target->item->proxy, 255, 255, 255, 255);
1649 evas_object_move(target->item->proxy, ix, iy);
1650 evas_object_resize(target->item->proxy, iw, ih);
1651 evas_object_show(target->item->proxy);
1654 ELM_RECTS_INTERSECT(GL_IT(target)->scrl_x, GL_IT(target)->scrl_y,
1655 GL_IT(target)->w, GL_IT(target)->h,
1656 ox, g_center - CENTER_CHECK_GAP,
1657 ow, CENTER_CHECK_GAP * 2))
1659 if ((sd->adjusted_item == target) &&
1660 ((sd->adjusted_item != sd->aligned_item) || (sd->unhighlighted)))
1662 edje_object_signal_emit(VIEW(sd->adjusted_item), SIGNAL_ITEM_HIGHLIGHTED, "elm");
1664 if (sd->aligned_item && sd->adjusted_item != sd->aligned_item)
1665 edje_object_signal_emit(VIEW(sd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
1666 sd->aligned_item = sd->adjusted_item;
1667 sd->unhighlighted = EINA_FALSE;
1670 if (sd->adjusted_item == target &&
1671 sd->aligned_item == sd->adjusted_item &&
1672 ((i_center >= g_center && i_center < g_center + 10) ||
1673 (i_center <= g_center && i_center > g_center - 10)))
1675 sd->adjusted_item = NULL;
1676 _focus_bg_show(sd->aligned_item);
1684 _item_all_position(Elm_Gen_Item *it,
1690 if (it->deco_all_view)
1691 _item_position(it, it->deco_all_view, it_x, it_y);
1692 else if (GL_IT(it)->deco_it_view)
1693 _item_position(it, GL_IT(it)->deco_it_view, it_x, it_y);
1695 _item_position(it, VIEW(it), it_x, it_y);
1699 _decorate_item_unrealize(Elm_Gen_Item *it)
1701 if (!GL_IT(it)->deco_it_view) return;
1703 edje_object_part_unswallow(GL_IT(it)->deco_it_view, VIEW(it));
1704 _view_clear(GL_IT(it)->deco_it_view, &(GL_IT(it)->deco_it_contents));
1705 evas_object_del(GL_IT(it)->deco_it_view);
1706 GL_IT(it)->deco_it_view = NULL;
1708 _item_mouse_callbacks_add(it, VIEW(it));
1709 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
1713 _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect)
1716 if (it->deco_all_view || !it->itc->decorate_all_item_style) return;
1718 // Before adding & swallowing, delete it from smart member
1719 evas_object_smart_member_del(VIEW(it));
1721 it->deco_all_view = _view_create(it, it->itc->decorate_all_item_style);
1722 _view_inflate(it->deco_all_view, it, &(GL_IT(it)->deco_all_contents));
1723 edje_object_part_swallow
1724 (it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
1725 evas_object_show(it->deco_all_view);
1727 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()))
1728 edje_object_signal_emit(it->deco_all_view, SIGNAL_DISABLED, "elm");
1730 edje_object_signal_emit(it->deco_all_view, SIGNAL_HIGHLIGHTED, "elm");
1731 if (GL_IT(it)->wsd->reorder_force ||
1732 GL_IT(it)->wsd->reorder_mode)
1733 edje_object_signal_emit
1734 (it->deco_all_view, SIGNAL_REORDER_MODE_SET, "elm");
1738 edje_object_signal_emit(VIEW(it),
1739 SIGNAL_DECORATE_ENABLED_EFFECT, "elm");
1740 edje_object_signal_emit(it->deco_all_view,
1741 SIGNAL_DECORATE_ENABLED_EFFECT, "elm");
1745 edje_object_signal_emit(VIEW(it), SIGNAL_DECORATE_ENABLED, "elm");
1746 edje_object_signal_emit(it->deco_all_view,
1747 SIGNAL_DECORATE_ENABLED,"elm");
1750 edje_object_signal_emit(it->deco_all_view, SIGNAL_FLIP_ENABLED, "elm");
1752 _item_mouse_callbacks_add(it, it->deco_all_view);
1753 _item_mouse_callbacks_del(it, VIEW(it));
1757 _expand_toggle_signal_cb(void *data,
1758 Evas_Object *obj EINA_UNUSED,
1759 const char *emission EINA_UNUSED,
1760 const char *source EINA_UNUSED)
1762 Elm_Gen_Item *it = data;
1764 if (GL_IT(it)->expanded)
1765 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, EO_OBJ(it));
1767 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, EO_OBJ(it));
1771 _expand_signal_cb(void *data,
1772 Evas_Object *obj EINA_UNUSED,
1773 const char *emission EINA_UNUSED,
1774 const char *source EINA_UNUSED)
1776 Elm_Gen_Item *it = data;
1778 if (!GL_IT(it)->expanded)
1779 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, EO_OBJ(it));
1783 _contract_signal_cb(void *data,
1784 Evas_Object *obj EINA_UNUSED,
1785 const char *emission EINA_UNUSED,
1786 const char *source EINA_UNUSED)
1788 Elm_Gen_Item *it = data;
1790 if (GL_IT(it)->expanded)
1791 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, EO_OBJ(it));
1795 _item_mouse_callbacks_add(Elm_Gen_Item *it,
1798 evas_object_event_callback_add
1799 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
1800 evas_object_event_callback_add
1801 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
1802 evas_object_event_callback_add
1803 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
1807 _item_mouse_callbacks_del(Elm_Gen_Item *it,
1810 evas_object_event_callback_del_full
1811 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
1812 evas_object_event_callback_del_full
1813 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
1814 evas_object_event_callback_del_full
1815 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
1820 _item_edje_callbacks_add(Elm_Gen_Item *it)
1822 edje_object_signal_callback_add
1823 (VIEW(it), "elm,action,expand,toggle", "elm",
1824 _expand_toggle_signal_cb, it);
1825 edje_object_signal_callback_add
1826 (VIEW(it), "elm,action,expand", "elm", _expand_signal_cb, it);
1827 edje_object_signal_callback_add
1828 (VIEW(it), "elm,action,contract", "elm", _contract_signal_cb, it);
1832 _item_edje_callbacks_del(Elm_Gen_Item *it)
1834 edje_object_signal_callback_del_full(VIEW(it), "elm,action,expand,toggle",
1835 "elm", _expand_toggle_signal_cb, it);
1836 edje_object_signal_callback_del_full(VIEW(it), "elm,action,expand", "elm",
1837 _expand_signal_cb, it);
1838 edje_object_signal_callback_del_full(VIEW(it), "elm,action,contract", "elm",
1839 _contract_signal_cb, it);
1843 _item_realize(Elm_Gen_Item *it,
1846 const char *treesize;
1849 if (it->realized) return;
1850 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
1851 ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd);
1853 it->realized = EINA_TRUE;
1855 if (!_item_cache_pop(it))
1856 VIEW(it) = _view_create(it, it->itc->item_style);
1858 //TIZEN_ONLY(20161013): clean up elm color class feature
1859 if (it->base->color_classes)
1860 _elm_widget_item_color_class_update(it->base);
1863 treesize = edje_object_data_get(VIEW(it), "treesize");
1866 int tsize = atoi(treesize);
1869 (GL_IT(it->parent)->type == ELM_GENLIST_ITEM_TREE))
1872 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1873 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1874 evas_object_size_hint_min_set
1875 (it->spacer, (GL_IT(it)->expanded_depth * tsize) *
1876 elm_config_scale_get(), 1);
1877 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1880 _view_inflate(VIEW(it), it, &it->content_objs);
1881 if (wd->scroll_item_align_enable && !calc)
1883 const char *vi_effect = edje_object_data_get(VIEW(it), "vi_effect");
1884 if (vi_effect && !strcmp(vi_effect, "on"))
1886 Evas_Object *clip = evas_object_clip_get(VIEW(it));
1887 if (clip) evas_object_data_set(VIEW(it), "view,clip", clip);
1888 else clip = evas_object_data_get(VIEW(it), "view,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, clip);
1896 if (evas_object_clip_get(VIEW(it))) 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;
2420 ELM_WIDGET_DATA_GET_OR_RETURN(psd->wsd->obj, wd);
2422 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2423 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2425 //FIXME: This is for optimizing genlist calculation after
2426 // genlist sizing eval properly.
2427 if (ow <= 1) return;
2429 _calc((void *)psd->wsd);
2431 if (_elm_config->access_mode || _elm_atspi_enabled())
2433 // If access is on, realize more items (3 times)
2437 #ifdef GENLIST_FX_SUPPORT
2438 else if (psd->wsd->del_fx.anim)
2443 EINA_LIST_FOREACH(psd->wsd->del_fx.items, l, it)
2445 size += it->item->minh;
2449 else if (psd->wsd->add_fx.anim)
2454 EINA_LIST_FOREACH(psd->wsd->add_fx.items, l, it)
2456 size += it->item->minh;
2462 // Belows are tweaks for performance
2463 // Block is not needed anymore because of below algorithm..
2464 // later, we should remove dirty block algorithm
2465 Eina_Inlist *start = NULL;
2466 Eina_List *realized_new = NULL;
2467 Eina_Bool flag = EINA_FALSE;
2468 if ((psd->wsd->blocks_realized) && (psd->wsd->dir == -1) &&
2469 (!_elm_config->access_mode) && (!_elm_atspi_enabled()))
2471 start = EINA_INLIST_GET((Item_Block *)eina_list_data_get
2472 (eina_list_last(psd->wsd->blocks_realized)));
2473 EINA_INLIST_REVERSE_FOREACH_FROM(start, itb)
2475 Evas_Coord itb_x, itb_y, itb_w, itb_h;
2476 itb_x = itb->x - psd->wsd->pan_x + ox;
2477 itb_y = itb->y - psd->wsd->pan_y + oy;
2478 itb_w = psd->wsd->minw;
2480 if (psd->wsd->realization_mode ||
2481 ELM_RECTS_INTERSECT(itb_x, itb_y, itb_w, itb_h,
2482 cvx, cvy, cvw, cvh))
2485 realized_new = eina_list_prepend(realized_new, itb);
2486 _item_block_realize(itb, EINA_FALSE);
2490 _item_block_unrealize(itb);
2495 else if ((psd->wsd->blocks_realized) && (psd->wsd->dir == 1) &&
2496 (!_elm_config->access_mode) && (!_elm_atspi_enabled()))
2498 start = EINA_INLIST_GET((Item_Block *)eina_list_data_get
2499 (psd->wsd->blocks_realized));
2500 EINA_INLIST_FOREACH(start, itb)
2502 Evas_Coord itb_x, itb_y, itb_w, itb_h;
2503 itb_x = itb->x - psd->wsd->pan_x + ox;
2504 itb_y = itb->y - psd->wsd->pan_y + oy;
2505 itb_w = psd->wsd->minw;
2507 if (psd->wsd->realization_mode ||
2508 ELM_RECTS_INTERSECT(itb_x, itb_y, itb_w, itb_h,
2509 cvx, cvy, cvw, cvh))
2512 realized_new = eina_list_append(realized_new, itb);
2513 _item_block_realize(itb, EINA_FALSE);
2517 _item_block_unrealize(itb);
2524 if (!psd->wsd->show_item)
2526 EINA_INLIST_FOREACH(psd->wsd->blocks, itb)
2528 Evas_Coord itb_x, itb_y, itb_w, itb_h;
2529 itb_x = itb->x - psd->wsd->pan_x + ox;
2530 itb_y = itb->y - psd->wsd->pan_y + oy;
2531 itb_w = psd->wsd->minw;
2533 if (psd->wsd->realization_mode ||
2534 ELM_RECTS_INTERSECT(itb_x, itb_y, itb_w, itb_h,
2535 cvx, cvy, cvw, cvh))
2537 realized_new = eina_list_append(realized_new, itb);
2538 _item_block_realize(itb, EINA_FALSE);
2542 _item_block_unrealize(itb);
2547 eina_list_free(psd->wsd->blocks_realized);
2548 psd->wsd->blocks_realized = realized_new;
2550 // TIZEN_ONLY(20150701) : banded color background feature. enabled only un-scrollable
2551 if (!TIZEN_PROFILE_WEARABLE)
2553 if (psd->wsd->banded_bg_rect && !psd->wsd->reorder.it)
2555 Evas_Coord bg_x, bg_y, bg_w, bg_h, svy, svh;
2556 Elm_Gen_Item *tmp = NULL, *prev = NULL;
2558 tmp = ELM_GEN_ITEM_FROM_INLIST(psd->wsd->items->last);
2562 if (tmp->want_hidden || !tmp->realized )
2563 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
2568 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
2572 if(prev->want_hidden)
2573 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2582 eo_do(psd->wsd->obj, elm_interface_scrollable_content_viewport_geometry_get
2583 (NULL, &svy, NULL, &svh));
2585 bg_x = GL_IT(tmp)->scrl_x;
2586 bg_y = GL_IT(tmp)->scrl_y + GL_IT(tmp)->h;
2587 bg_w = GL_IT(tmp)->w;
2588 bg_h = svy + svh - bg_y;
2590 evas_object_stack_below(psd->wsd->banded_bg_rect, VIEW(tmp));
2591 evas_object_resize(psd->wsd->banded_bg_rect, bg_w, bg_h);
2592 evas_object_move(psd->wsd->banded_bg_rect, bg_x, bg_y);
2594 //GET COLOR OF LAST ITEM AND SET NEXT COLOR TO BANDED BG RECT
2595 if (psd->wsd->banded_bg_on)
2598 index = GL_IT(tmp)->banded_color_index + 1;
2601 int sign = GL_IT(tmp)->banded_color_index - GL_IT(prev)->banded_color_index;
2605 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2609 if(prev->want_hidden)
2610 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2618 sign = GL_IT(tmp)->banded_color_index - GL_IT(prev)->banded_color_index;
2621 index = GL_IT(tmp)->banded_color_index + sign;
2623 if (index < 0) index += 2;
2624 else if (index >= BANDED_MAX_ITEMS)
2625 index = BANDED_MAX_ITEMS - 2;
2628 int alpha = 255 * (1 - 0.04 * index);
2629 int color = (250 * alpha) / 255;
2631 evas_object_color_set(psd->wsd->banded_bg_rect, color, color, color, alpha);
2635 evas_object_color_set
2636 (psd->wsd->banded_bg_rect, 0, 0, 0, 0);
2639 evas_object_show(psd->wsd->banded_bg_rect);
2645 if (psd->wsd->comp_y)
2647 psd->wsd->unhighlight_skip = EINA_TRUE;
2648 eo_do((psd->wsd)->obj, elm_interface_scrollable_content_region_show(psd->wsd->pan_x,
2649 psd->wsd->pan_y + psd->wsd->comp_y, ow, oh));
2650 psd->wsd->comp_y = 0;
2651 psd->wsd->unhighlight_skip = EINA_FALSE;
2653 else if (psd->wsd->expanded_item &&
2654 GL_IT(psd->wsd->expanded_item)->calc_done)
2657 Evas_Coord size = GL_IT(psd->wsd->expanded_item)->minh;
2658 Elm_Object_Item *eo_tmp;
2659 EINA_LIST_FOREACH(psd->wsd->expanded_item->item->items, l, eo_tmp)
2661 ELM_GENLIST_ITEM_DATA_GET(eo_tmp, tmp);
2662 size += GL_IT(tmp)->minh;
2665 elm_genlist_item_bring_in
2666 (EO_OBJ(psd->wsd->expanded_item),
2667 ELM_GENLIST_ITEM_SCROLLTO_TOP);
2670 eo_tmp = eina_list_data_get
2671 (eina_list_last(psd->wsd->expanded_item->item->items));
2674 elm_genlist_item_bring_in(eo_tmp,
2675 ELM_GENLIST_ITEM_SCROLLTO_IN);
2677 psd->wsd->expanded_item = NULL;
2679 if (psd->wsd->show_item &&
2680 !psd->wsd->show_item->item->queued &&
2681 psd->wsd->show_item->item->calc_done &&
2682 psd->wsd->show_item->item->block->calc_done &&
2683 psd->wsd->calc_done)
2685 Evas_Coord x, y, w, h;
2686 Elm_Gen_Item *it = psd->wsd->show_item;
2687 psd->wsd->show_item = NULL;
2688 x = it->x + GL_IT(it)->block->x + psd->wsd->pan_x;
2689 y = it->y + GL_IT(it)->block->y;
2693 switch (psd->wsd->scroll_to_type)
2695 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2699 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2700 y = y - (oh / 2) + (GL_IT(it)->h / 2);
2703 case ELM_GENLIST_ITEM_SCROLLTO_BOTTOM:
2704 y = y - oh + GL_IT(it)->h;
2710 if (psd->wsd->bring_in)
2711 eo_do(WIDGET(it), elm_interface_scrollable_region_bring_in(x, y, w, h));
2714 if (psd->wsd->aligned_item && (psd->wsd->aligned_item != psd->wsd->adjusted_item))
2715 edje_object_signal_emit(VIEW(psd->wsd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
2716 edje_object_signal_emit(wd->resize_obj, SIGNAL_FOCUS_BG_HIDE, "elm");
2717 psd->wsd->aligned_item = NULL;
2718 psd->wsd->unhighlight_skip = EINA_TRUE;
2719 eo_do(WIDGET(it), elm_interface_scrollable_content_region_show(x, y, ow, oh));
2720 psd->wsd->unhighlight_skip = EINA_FALSE;
2723 _changed(psd->wsd->pan_obj);
2725 #ifdef GENLIST_FX_SUPPORT
2726 if (psd->wsd->add_fx.anim)
2731 int alpha = 255 * (1 - ((double)psd->wsd->add_fx.cnt/ANIM_CNT_MAX));
2732 EINA_LIST_FOREACH(psd->wsd->add_fx.items, l, it)
2734 if (!it->realized) continue;
2735 if (it->deco_all_view)
2736 evas_object_color_set(it->deco_all_view, alpha, alpha, alpha, alpha);
2737 else if (it->item->deco_it_view)
2738 evas_object_color_set(it->item->deco_it_view, alpha, alpha, alpha, alpha);
2740 evas_object_color_set(VIEW(it), alpha, alpha, alpha, alpha);
2743 if (psd->wsd->del_fx.anim)
2748 int alpha = 255 * ((double)psd->wsd->del_fx.cnt/ANIM_CNT_MAX);
2749 EINA_LIST_FOREACH(psd->wsd->del_fx.items, l, it)
2751 if (it->deco_all_view)
2752 evas_object_color_set(it->deco_all_view, alpha, alpha, alpha, alpha);
2753 else if (it->item->deco_it_view)
2754 evas_object_color_set(it->item->deco_it_view, alpha, alpha, alpha, alpha);
2756 evas_object_color_set(VIEW(it), alpha, alpha, alpha, alpha);
2760 eo_do(psd->wobj, eo_event_callback_call
2761 (ELM_INTERFACE_SCROLLABLE_EVENT_CHANGED, NULL));
2765 _elm_genlist_pan_eo_base_destructor(Eo *obj, Elm_Genlist_Pan_Data *psd)
2767 eo_data_unref(psd->wobj, psd->wsd);
2768 eo_do_super(obj, MY_PAN_CLASS, eo_destructor());
2772 _elm_genlist_pan_class_constructor(Eo_Class *klass)
2774 evas_smart_legacy_type_register(MY_PAN_CLASS_NAME_LEGACY, klass);
2777 #include "elm_genlist_pan.eo.c"
2779 //#ifdef ELM_FOCUSED_UI
2781 _item_multi_select_up(Elm_Genlist_Data *sd)
2783 Elm_Object_Item *prev;
2785 if (!sd->selected) return EINA_FALSE;
2786 if (!sd->multi) return EINA_FALSE;
2788 prev = elm_genlist_item_prev_get(sd->last_selected_item);
2789 if (!prev) return EINA_TRUE;
2791 if (elm_genlist_item_selected_get(prev))
2793 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2794 sd->last_selected_item = prev;
2795 elm_genlist_item_show
2796 (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2800 elm_genlist_item_selected_set(prev, EINA_TRUE);
2801 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
2807 _item_multi_select_down(Elm_Genlist_Data *sd)
2809 Elm_Object_Item *next;
2811 if (!sd->selected) return EINA_FALSE;
2812 if (!sd->multi) return EINA_FALSE;
2814 next = elm_genlist_item_next_get(sd->last_selected_item);
2815 if (!next) return EINA_TRUE;
2817 if (elm_genlist_item_selected_get(next))
2819 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2820 sd->last_selected_item = next;
2821 elm_genlist_item_show
2822 (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2826 elm_genlist_item_selected_set(next, EINA_TRUE);
2827 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
2834 _all_items_deselect(Elm_Genlist_Data *sd)
2836 if (!sd->selected) return EINA_FALSE;
2838 while (sd->selected)
2839 elm_genlist_item_selected_set(sd->selected->data, EINA_FALSE);
2845 _item_single_select_up(Elm_Genlist_Data *sd)
2847 Elm_Object_Item *eo_prev;
2852 prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2854 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2858 eo_prev = elm_genlist_item_prev_get(sd->last_selected_item);
2859 prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
2862 if (!prev) return EINA_FALSE;
2864 _all_items_deselect(sd);
2866 elm_genlist_item_selected_set(EO_OBJ(prev), EINA_TRUE);
2867 elm_genlist_item_show(EO_OBJ(prev), ELM_GENLIST_ITEM_SCROLLTO_IN);
2872 _item_single_select_down(Elm_Genlist_Data *sd)
2874 Elm_Object_Item *eo_next;
2879 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2881 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2885 eo_next = elm_genlist_item_next_get(sd->last_selected_item);
2886 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2889 if (!next) return EINA_FALSE;
2891 _all_items_deselect(sd);
2893 elm_genlist_item_selected_set(EO_OBJ(next), EINA_TRUE);
2894 elm_genlist_item_show
2895 (EO_OBJ(next), ELM_GENLIST_ITEM_SCROLLTO_IN);
2901 static void _item_unfocused(Elm_Gen_Item *it)
2904 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2905 if (!sd->focused_item || it != sd->focused_item) return;
2907 edje_object_signal_emit
2908 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
2909 if (sd->focused_item->deco_all_view)
2910 edje_object_signal_emit
2911 (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
2912 sd->focused_item = NULL;
2913 evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_UNFOCUSED, EO_OBJ(it));
2916 static void _item_focused(Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
2918 Evas_Coord x, y, w, h, sx, sy, sw, sh;
2920 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2922 evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
2923 evas_object_geometry_get(sd->obj, &sx, &sy, &sw, &sh);
2924 if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
2926 elm_genlist_item_bring_in(EO_OBJ(it), type);
2929 if (elm_widget_focus_highlight_enabled_get(sd->obj))
2931 if (it->deco_all_view)
2932 edje_object_signal_emit
2933 (it->deco_all_view, SIGNAL_FOCUSED, "elm");
2935 edje_object_signal_emit
2936 (VIEW(it), SIGNAL_FOCUSED, "elm");
2939 sd->focused_item = it;
2940 evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_FOCUSED, EO_OBJ(it));
2941 if (_elm_atspi_enabled())
2942 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), EO_OBJ(it));
2946 _banded_item_highlight_anim(void *data, double pos)
2948 Elm_Gen_Item *it = data;
2950 double v[4] = {0.25, 0.46, 0.45, 1.00};
2952 if (GL_IT(it)->banded_bg)
2955 frame = ecore_animator_pos_map_n(pos, ECORE_POS_MAP_CUBIC_BEZIER, 4, v);
2957 it->item->banded_anim = NULL;
2959 if (it->highlighted)
2960 frame = HIGHLIGHT_ALPHA_MAX + (1.0 - HIGHLIGHT_ALPHA_MAX) * (1.0 - frame);
2962 frame = HIGHLIGHT_ALPHA_MAX + (1.0 - HIGHLIGHT_ALPHA_MAX) * frame;
2964 int alpha = 255 * frame * (1 - 0.04 * GL_IT(it)->banded_color_index);
2967 color = (color * alpha) / 255;
2968 evas_object_color_set(GL_IT(it)->banded_bg, color, color, color, alpha);
2975 _item_highlight(Elm_Gen_Item *it)
2977 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2978 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wsd);
2981 if (!sd->highlight) return;
2982 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get())) return;
2983 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2984 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ) ||
2985 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2986 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
2988 if (it->highlighted) return;
2989 if (wsd->scroll_item_align_enable)
2991 if (sd->aligned_item == it)
2992 edje_object_signal_emit(wsd->resize_obj, SIGNAL_HIGHLIGHTED, "elm");
2997 it->highlighted = EINA_TRUE;
2998 sd->highlighted_item = it;
3000 if (!it->realized) goto end;
3002 if (!TIZEN_PROFILE_WEARABLE)
3004 if (sd->banded_bg_on)
3006 if (it->item->banded_anim) ecore_animator_del(it->item->banded_anim);
3007 it->item->banded_anim = ecore_animator_timeline_add(ELM_ITEM_HIGHLIGHT_TIMER, _banded_item_highlight_anim, it);
3010 if (it->deco_all_view)
3012 edje_object_signal_emit(it->deco_all_view, SIGNAL_HIGHLIGHTED, "elm");
3013 edje_object_message_signal_process(it->deco_all_view);
3015 edje_object_signal_emit(VIEW(it), SIGNAL_HIGHLIGHTED, "elm");
3016 edje_object_message_signal_process(VIEW(it));
3018 //***************** TIZEN Only
3019 // If check or radio is used on genlist item, highlight it also.
3021 Evas_Object *content;
3022 if (sd->decorate_all_mode)
3024 EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, content)
3026 const char *type = elm_widget_type_get(content);
3027 if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3028 elm_object_signal_emit(content, "elm,state,mouse,down", "elm");
3033 EINA_LIST_FOREACH(it->content_objs, l, content)
3035 const char *type = elm_widget_type_get(content);
3036 if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3037 elm_object_signal_emit(content, "elm,state,mouse,down", "elm");
3040 //****************************
3042 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
3043 if (_elm_atspi_enabled())
3044 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), EO_OBJ(it));
3048 _item_unhighlight(Elm_Gen_Item *it, Eina_Bool effect EINA_UNUSED)
3050 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wsd);
3051 if (!it->highlighted) return;
3053 it->highlighted = EINA_FALSE;
3054 GL_IT(it)->wsd->highlighted_item = NULL;
3056 if (!it->realized) goto end;
3058 if (!TIZEN_PROFILE_WEARABLE)
3060 if (GL_IT(it)->wsd->banded_bg_on && effect)
3062 if (it->item->banded_anim) ecore_animator_del(it->item->banded_anim);
3063 it->item->banded_anim = ecore_animator_timeline_add(ELM_ITEM_HIGHLIGHT_TIMER, _banded_item_highlight_anim, it);
3067 if (it->item->banded_anim) ELM_SAFE_FREE(it->item->banded_anim, ecore_animator_del);
3068 _banded_item_bg_color_change(it, EINA_FALSE);
3071 if (it->deco_all_view)
3072 edje_object_signal_emit(it->deco_all_view, SIGNAL_UNHIGHLIGHTED, "elm");
3073 edje_object_signal_emit(VIEW(it), SIGNAL_UNHIGHLIGHTED, "elm");
3074 if (wsd->scroll_item_align_enable)
3075 edje_object_signal_emit(wsd->resize_obj, SIGNAL_UNHIGHLIGHTED, "elm");
3077 edje_object_signal_emit(VIEW(it), SIGNAL_UNHIGHLIGHTED, "elm");
3078 //******************** TIZEN Only
3079 // If check is used on genlist item, unhighlight it also.
3081 Evas_Object *content;
3082 if (GL_IT(it)->wsd->decorate_all_mode)
3084 EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, content)
3086 const char *type = elm_widget_type_get(content);
3087 if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3088 elm_object_signal_emit(content, "elm,state,mouse,up", "elm");
3093 EINA_LIST_FOREACH(it->content_objs, l, content)
3095 const char *type = elm_widget_type_get(content);
3096 if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3097 elm_object_signal_emit(content, "elm,state,mouse,up", "elm");
3100 //*******************************
3102 evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, EO_OBJ(it));
3106 _item_unselect(Elm_Gen_Item *it)
3108 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
3110 if (!it->selected) return;
3112 it->selected = EINA_FALSE;
3113 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
3114 _item_unhighlight(it, EINA_TRUE);
3115 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, EO_OBJ(it));
3119 _item_select(Elm_Gen_Item *it)
3121 Evas_Object *obj = WIDGET(it);
3122 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
3124 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get())) return;
3125 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3126 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
3127 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3128 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
3130 if (sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS &&
3131 it->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS &&
3136 const Eina_List *l, *ll;
3137 Elm_Object_Item *eo_it2;
3138 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it2)
3139 if (eo_it2 != EO_OBJ(it))
3141 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
3142 _item_unselect(it2);
3148 sd->selected = eina_list_append(sd->selected, EO_OBJ(it));
3149 it->selected = EINA_TRUE;
3151 sd->last_selected_item = EO_OBJ(it);
3152 _item_highlight(it);
3154 if (sd->focused_content)
3156 elm_object_focus_set(sd->focused_content, EINA_FALSE);
3157 evas_object_focus_set(obj, EINA_TRUE);
3158 sd->focused_content = NULL;
3161 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3162 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3166 // FIXME: after evas_object_raise, mouse event callbacks(ex, UP, DOWN)
3167 // can be called again eventhough already received it.
3168 const char *selectraise = edje_object_data_get(VIEW(it), "selectraise");
3169 if ((selectraise) && (!strcmp(selectraise, "on")))
3171 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
3172 else evas_object_raise(VIEW(it));
3173 if ((GL_IT(it)->group_item) && (GL_IT(it)->group_item->realized))
3174 evas_object_raise(GL_IT(it)->VIEW(group_item));
3177 edje_object_signal_emit
3178 (VIEW(it), SIGNAL_CLICKED, "elm");
3179 edje_object_message_signal_process(VIEW(it));
3181 evas_object_ref(obj);
3182 if (it->func.func) it->func.func((void *)it->func.data, obj, EO_OBJ(it));
3183 if (EINA_MAGIC_CHECK(it->base, ELM_WIDGET_ITEM_MAGIC))
3184 evas_object_smart_callback_call(obj, SIG_SELECTED, EO_OBJ(it));
3185 evas_object_unref(obj);
3189 _highlight_timer(void *data)
3191 Elm_Gen_Item *it = data;
3192 GL_IT(it)->highlight_timer = NULL;
3193 _item_highlight(it);
3198 _select_timer(void *data)
3200 Elm_Gen_Item *it = data;
3201 GL_IT(it)->highlight_timer = NULL;
3203 if ((GL_IT(it)->wsd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS) ||
3204 (it->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS))
3208 // TIZEN Only(20150708) : unselect when selected item is selected again
3209 // There need to be implemented 'SELECT_UNSELECT' mode in elm_config
3210 // select mode for support upsteam and TIZEN both.
3211 if (!it->selected) _item_select(it);
3212 else _item_unselect(it);
3220 *_item_focusable_content_search(Evas_Object *obj, Eina_List *l, int dir)
3222 if ((dir != 1) && (dir != -1)) return NULL;
3224 Evas_Object *next = NULL;
3225 Elm_Object_Item *next_item = NULL;
3229 next = eina_list_data_get(l);
3230 if (next && (elm_widget_can_focus_get(next) &&
3231 (evas_object_visible_get(next))))
3233 else if (next && (elm_widget_child_can_focus_get(next)))
3235 if (elm_widget_focused_object_get(next))
3239 Evas_Object *child = next;
3241 (elm_widget_focus_next_get(next, ELM_FOCUS_RIGHT, &child, &next_item)))
3243 else if ((dir == -1) &&
3244 (elm_widget_focus_next_get(next, ELM_FOCUS_LEFT, &child, &next_item)))
3250 if (dir == 1) l = eina_list_next(l);
3251 else l = eina_list_prev(l);
3254 if (!next) next = obj;
3259 static Eina_Bool _item_focusable_search(Elm_Gen_Item **it, int dir)
3261 if (!(*it)) return EINA_FALSE;
3262 if ((dir != 1) && (dir != -1)) return EINA_FALSE;
3264 Elm_Gen_Item *tmp = *it;
3268 if (!elm_object_item_disabled_get(EO_OBJ(tmp)) &&
3269 (!tmp->want_hidden))
3271 if ((tmp->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
3272 (tmp->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3275 Evas_Object *obj = NULL;
3276 Eina_List *contents = NULL;
3278 contents = GL_IT(tmp)->flip_content_objs;
3281 contents = tmp->content_objs;
3282 if (tmp->deco_all_view)
3285 contents = GL_IT(tmp)->deco_all_contents;
3287 contents = eina_list_merge(contents,
3288 GL_IT(tmp)->deco_all_contents);
3293 obj = _item_focusable_content_search(NULL, contents, 1);
3296 contents = eina_list_last(contents);
3297 obj = _item_focusable_content_search(NULL, contents, -1);
3302 if (GL_IT(tmp)->wsd->focused_content)
3303 elm_object_focus_set(GL_IT(tmp)->wsd->focused_content, EINA_FALSE);
3304 GL_IT(tmp)->wsd->focused_content = obj;
3305 elm_object_focus_set(obj, EINA_TRUE);
3310 if (GL_IT(tmp)->wsd->focused_content)
3312 elm_object_focus_set(GL_IT(tmp)->wsd->focused_content, EINA_FALSE);
3313 evas_object_focus_set(WIDGET(tmp), EINA_TRUE);
3314 GL_IT(tmp)->wsd->focused_content = NULL;
3320 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->next);
3322 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
3329 static Eina_Bool _item_focus_next(Elm_Genlist_Data *sd, Focus_Dir dir)
3331 Elm_Gen_Item *it = NULL;
3332 Elm_Gen_Item *old_focused = sd->focused_item;
3333 Evas_Object *old_content = sd->focused_content;
3335 if (dir == FOCUS_DIR_DOWN || dir == FOCUS_DIR_UP)
3337 Eina_Bool find_item;
3339 if (dir == FOCUS_DIR_DOWN)
3341 if (sd->focused_item)
3343 it = ELM_GEN_ITEM_FROM_INLIST
3344 (EINA_INLIST_GET(sd->focused_item)->next);
3345 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3347 else it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
3348 find_item = _item_focusable_search(&it, 1);
3350 else if (dir == FOCUS_DIR_UP)
3352 if (sd->focused_item)
3354 it = ELM_GEN_ITEM_FROM_INLIST
3355 (EINA_INLIST_GET(sd->focused_item)->prev);
3356 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3358 else it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
3359 find_item = _item_focusable_search(&it, -1);
3368 sd->focused_content = old_content;
3369 elm_object_focus_set(old_content, EINA_TRUE);
3373 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3374 elm_object_item_focus_set(EO_OBJ(old_focused), EINA_TRUE);
3379 else if (!find_item)
3382 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3383 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3385 else if (dir == FOCUS_DIR_LEFT || dir == FOCUS_DIR_RIGHT)
3387 Evas_Object *obj = NULL;
3388 Eina_List *contents = NULL;
3389 Eina_List *l = NULL;
3391 if (!sd->focused_item) return EINA_FALSE;
3392 if (sd->focused_item->flipped)
3393 contents = GL_IT(sd->focused_item)->flip_content_objs;
3396 contents = sd->focused_item->content_objs;
3397 if (sd->focused_item->deco_all_view)
3400 contents = GL_IT(sd->focused_item)->deco_all_contents;
3402 contents = eina_list_merge(contents,
3403 GL_IT(sd->focused_item)->deco_all_contents);
3407 if (sd->focused_content)
3409 l = eina_list_data_find_list(contents,
3410 sd->focused_content);
3411 obj = sd->focused_content;
3414 if (dir == FOCUS_DIR_LEFT)
3416 if ((l) && (eina_list_prev(l)))
3418 l = eina_list_prev(l);
3419 obj = _item_focusable_content_search(obj, l, -1);
3420 if (!obj) obj = sd->focused_content;
3424 //search focused content is child of content
3425 if (sd->focused_content)
3426 l = eina_list_data_find_list(contents,
3427 sd->focused_content);
3428 if (!l) l = eina_list_last(contents);
3429 obj = _item_focusable_content_search(obj, l, -1);
3431 else obj = sd->focused_content;
3433 else if (dir == FOCUS_DIR_RIGHT)
3435 if ((l) && (eina_list_next(l)))
3437 l = eina_list_next(l);
3438 obj = _item_focusable_content_search(obj, l, 1);
3439 if (!obj) obj = sd->focused_content;
3443 //search focused content is child of content
3444 if (sd->focused_content)
3445 l = eina_list_data_find_list(contents,
3446 sd->focused_content);
3447 if (!l) l = contents;
3448 obj = _item_focusable_content_search(obj, l, 1);
3450 else obj = sd->focused_content;
3455 sd->focused_content = obj;
3456 elm_object_focus_set(obj, EINA_TRUE);
3460 sd->focused_content = NULL;
3464 else return EINA_FALSE;
3469 //#ifdef ELM_FOCUSED_UI
3470 EOLIAN static Eina_Bool
3471 _elm_genlist_elm_widget_event(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *src EINA_UNUSED, Evas_Callback_Type type, void *event_info)
3477 Evas_Coord step_x = 0;
3478 Evas_Coord step_y = 0;
3479 Evas_Coord page_x = 0;
3480 Evas_Coord page_y = 0;
3481 Evas_Event_Key_Down *ev = event_info;
3482 Evas_Coord pan_max_x = 0, pan_max_y = 0;
3484 //ELM_GENLIST_DATA_GET(obj, sd);
3486 // TIZEN ONLY(20131221) : When access mode, focused ui is disabled.
3487 if (_elm_config->access_mode) return EINA_FALSE;
3489 if ((type != EVAS_CALLBACK_KEY_DOWN) && (type != EVAS_CALLBACK_KEY_UP))
3491 if (!sd->items) return EINA_FALSE;
3492 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
3493 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
3496 elm_interface_scrollable_content_pos_get(&x, &y),
3497 elm_interface_scrollable_step_size_get(&step_x, &step_y),
3498 elm_interface_scrollable_page_size_get(&page_x, &page_y),
3499 elm_interface_scrollable_content_viewport_geometry_get
3500 (NULL, NULL, &v_w, &v_h));
3502 if ((!strcmp(ev->keyname, "Left")) ||
3503 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)) ||
3504 (!strcmp(ev->keyname, "Right")) ||
3505 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)) ||
3506 (!strcmp(ev->keyname, "Up")) ||
3507 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)) ||
3508 (!strcmp(ev->keyname, "Down")) ||
3509 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)) ||
3510 (!strcmp(ev->keyname, "Home")) ||
3511 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)) ||
3512 (!strcmp(ev->keyname, "End")) ||
3513 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)) ||
3514 (!strcmp(ev->keyname, "Prior")) ||
3515 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)) ||
3516 (!strcmp(ev->keyname, "Next")) ||
3517 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
3519 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3520 _elm_widget_focus_auto_show(obj);
3523 if ((!strcmp(ev->keyname, "Left")) ||
3524 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
3526 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3527 if (sd->select_on_focus_enabled) x -= step_x;
3530 if (_item_focus_next(sd, FOCUS_DIR_LEFT))
3532 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3539 else if ((!strcmp(ev->keyname, "Right")) ||
3540 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
3542 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3543 if (sd->select_on_focus_enabled) x += step_x;
3546 if (_item_focus_next(sd, FOCUS_DIR_RIGHT))
3548 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3555 else if ((!strcmp(ev->keyname, "Up")) ||
3556 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
3558 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3559 if (sd->select_on_focus_enabled)
3561 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
3562 (_item_multi_select_up(sd))) || (_item_single_select_up(sd)))
3564 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3570 if (_item_focus_next(sd, FOCUS_DIR_UP))
3572 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3579 else if ((!strcmp(ev->keyname, "Down")) ||
3580 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
3582 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3583 if (sd->select_on_focus_enabled)
3585 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
3586 (_item_multi_select_down(sd))) ||
3587 (_item_single_select_down(sd)))
3589 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3595 if (_item_focus_next(sd, FOCUS_DIR_DOWN))
3597 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3604 else if ((!strcmp(ev->keyname, "Home")) ||
3605 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
3607 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3608 if (sd->select_on_focus_enabled)
3610 Elm_Object_Item *it = elm_genlist_first_item_get(obj);
3611 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
3612 elm_genlist_item_selected_set(it, EINA_TRUE);
3613 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3617 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3618 _item_focus_next(sd, FOCUS_DIR_DOWN);
3619 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3623 else if ((!strcmp(ev->keyname, "End")) ||
3624 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
3626 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3627 if (sd->select_on_focus_enabled)
3629 Elm_Object_Item *it = elm_genlist_last_item_get(obj);
3630 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
3631 elm_genlist_item_selected_set(it, EINA_TRUE);
3635 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3636 sd->focused_item = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
3637 _item_focus_next(sd, FOCUS_DIR_UP);
3639 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3642 else if ((!strcmp(ev->keyname, "Prior")) ||
3643 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
3645 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3646 Elm_Gen_Item *it = sd->focused_item;
3647 Elm_Object_Item *eo_prev;
3649 while (page_y <= v_h)
3651 if (elm_genlist_item_prev_get(EO_OBJ(it)))
3653 eo_prev = elm_genlist_item_prev_get(EO_OBJ(it));
3654 it = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
3657 page_y += GL_IT(it)->minh;
3659 if (_item_focusable_search(&it, -1))
3661 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3662 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3666 _item_focusable_search(&it, 1);
3667 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3668 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3671 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3674 else if ((!strcmp(ev->keyname, "Next")) ||
3675 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
3677 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3678 Elm_Gen_Item *it = sd->focused_item;
3679 Elm_Object_Item *eo_next;
3681 page_y = GL_IT(it)->minh;
3683 while (page_y <= v_h)
3685 if (elm_genlist_item_next_get(EO_OBJ(it)))
3687 eo_next = elm_genlist_item_next_get(EO_OBJ(it));
3688 it = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
3691 page_y += GL_IT(it)->minh;
3693 if (_item_focusable_search(&it, 1))
3695 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3696 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3700 _item_focusable_search(&it, -1);
3701 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3702 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3705 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3706 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3708 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3711 else if (!strcmp(ev->keyname, "Escape"))
3713 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3714 if (!_all_items_deselect(sd)) return EINA_FALSE;
3715 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3718 else if (!strcmp(ev->keyname, "Return") ||
3719 !strcmp(ev->keyname, "KP_Enter") ||
3720 !strcmp(ev->keyname, "space"))
3723 if (type == EVAS_CALLBACK_KEY_DOWN && !sd->key_down_item)
3725 if (sd->focused_item)
3727 sd->key_down_item = sd->focused_item;
3729 edje_object_signal_emit
3730 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
3731 if (sd->focused_item->deco_all_view)
3732 edje_object_signal_emit
3733 (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
3735 _item_highlight(sd->key_down_item);
3736 if (sd->key_down_item->long_timer)
3737 ecore_timer_del(sd->key_down_item->long_timer);
3738 sd->key_down_item->long_timer = ecore_timer_add
3739 (sd->longpress_timeout,
3740 _long_press_cb, sd->key_down_item);
3741 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3742 evas_object_smart_callback_call(obj, SIG_ACTIVATED, EO_OBJ(sd->key_down_item));
3745 else return EINA_FALSE;
3747 else if (type == EVAS_CALLBACK_KEY_UP && sd->key_down_item)
3749 edje_object_signal_emit
3750 (VIEW(sd->key_down_item), SIGNAL_FOCUSED, "elm");
3751 if (sd->key_down_item->deco_all_view)
3752 edje_object_signal_emit
3753 (sd->key_down_item->deco_all_view, SIGNAL_FOCUSED, "elm");
3755 if (sd->key_down_item->long_timer)
3756 ecore_timer_del(sd->key_down_item->long_timer);
3757 sd->key_down_item->long_timer = NULL;
3758 if (GL_IT(sd->key_down_item)->highlight_timer)
3759 ecore_timer_del(GL_IT(sd->key_down_item)->highlight_timer);
3760 GL_IT(sd->key_down_item)->highlight_timer = ecore_timer_add
3761 (ITEM_SELECT_TIMER, _select_timer, sd->key_down_item);
3762 sd->key_down_item = NULL;
3763 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3766 else return EINA_FALSE;
3768 else return EINA_FALSE;
3770 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3771 eo_do(sd->pan_obj, elm_obj_pan_pos_max_get(&pan_max_x, &pan_max_y));
3773 if (x > pan_max_x) x = pan_max_x;
3775 if (y > pan_max_y) y = pan_max_y;
3777 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
3783 /* This function disables the specific code of the layout sub object add.
3784 * Only the widget sub_object_add is called.
3786 EOLIAN static Eina_Bool
3787 _elm_genlist_elm_layout_sub_object_add_enable(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3792 EOLIAN static Eina_Bool
3793 _elm_genlist_elm_widget_sub_object_add(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED, Evas_Object *sobj)
3795 Eina_Bool int_ret = EINA_FALSE;
3797 /* skipping layout's code, which registers size hint changing
3798 * callback on sub objects. this is here because items'
3799 * content_get() routines may change hints on the objects after
3800 * creation, thus issuing TOO MANY sizing_eval()'s here. they are
3801 * not needed at here anyway, so let's skip listening to those
3804 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_add(sobj));
3805 if (!int_ret) return EINA_FALSE;
3807 //if (!parent_parent->sub_object_add(obj, sobj))
3808 // return EINA_FALSE;
3813 EOLIAN static Eina_Bool
3814 _elm_genlist_elm_widget_sub_object_del(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *sobj)
3816 Eina_Bool int_ret = EINA_FALSE;
3818 /* XXX: hack -- also skipping sizing recalculation on
3819 * sub-object-del. genlist's crazy code paths (like groups and
3820 * such) seem to issue a whole lot of deletions and Evas bitches
3821 * about too many recalculations */
3822 sd->on_sub_del = EINA_TRUE;
3824 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_del(sobj));
3825 if (!int_ret) return EINA_FALSE;
3827 sd->on_sub_del = EINA_FALSE;
3833 _elm_genlist_focus_highlight_show(void *data EINA_UNUSED,
3835 const char *emission EINA_UNUSED,
3836 const char *src EINA_UNUSED)
3838 ELM_GENLIST_DATA_GET(obj, sd);
3840 if (sd->focused_item)
3842 if (!sd->focused_content)
3844 Eina_Bool found = EINA_FALSE;
3845 Elm_Gen_Item *it = sd->focused_item;
3846 found = _item_focusable_search(&it, 1);
3849 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3850 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3853 else elm_object_focus_set(sd->focused_content, EINA_TRUE);
3858 _elm_genlist_focus_highlight_hide(void *data EINA_UNUSED,
3860 const char *emission EINA_UNUSED,
3861 const char *src EINA_UNUSED)
3863 ELM_GENLIST_DATA_GET(obj, sd);
3864 if (sd->focused_item)
3866 // Do not use _item_unfocused because focus should be remained
3867 edje_object_signal_emit
3868 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
3869 if (sd->focused_item->deco_all_view)
3870 edje_object_signal_emit
3871 (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
3876 _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)
3878 Evas_Coord ox, oy, oh, ow, item_x = 0, item_y = 0, item_w = 0, item_h = 0;
3879 Elm_Gen_Item *focus_it;
3881 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
3883 if (sd->focused_item)
3885 focus_it = sd->focused_item;
3886 evas_object_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
3887 elm_widget_focus_highlight_focus_part_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
3899 if (item_y > (oy + oh - item_h))
3901 *y = oy + oh - item_h;
3904 if ((item_x + item_w) > (ox + ow))
3914 EOLIAN static Eina_Bool
3915 _elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd, Elm_Object_Item *item EINA_UNUSED)
3917 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
3918 Eina_Bool int_ret = EINA_FALSE;
3920 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_on_focus(NULL));
3921 if (!int_ret) return EINA_FALSE;
3923 if ((sd->items) && (sd->selected) && (!sd->last_selected_item))
3924 sd->last_selected_item = eina_list_data_get(sd->selected);
3926 if (sd->select_on_focus_enabled) return EINA_TRUE;
3927 if (elm_widget_focus_get(obj))
3929 // Do nothing if on_focus is called by child's parent_focus
3930 if (!wd->is_focus_target) return EINA_TRUE;
3932 if (sd->focused_item)
3934 if (!sd->focused_content)
3936 Eina_Bool found = EINA_FALSE;
3937 Elm_Gen_Item *it = sd->focused_item;
3938 found = _item_focusable_search(&it, 1);
3941 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3942 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3946 elm_object_focus_set(sd->focused_content, EINA_TRUE);
3950 Item_Block *itb, *nib;
3951 EINA_INLIST_FOREACH(sd->blocks, itb)
3955 Elm_Gen_Item *tmp = eina_list_data_get(itb->items);
3956 while(tmp && tmp->item->block == itb)
3960 Elm_Gen_Item *old = tmp;
3961 Evas_Coord x, y, w, h, sx, sy, sw, sh;
3962 evas_object_geometry_get(VIEW(tmp), &x, &y, &w, &h);
3963 evas_object_geometry_get(obj, &sx, &sy, &sw, &sh);
3964 /* Item is included viewport and focusable */
3965 if ((ELM_RECTS_INCLUDE(sx, sy, sw, sh, x, y, w, h)) &&
3966 (_item_focusable_search(&tmp, 1)))
3968 Eina_Bool include = EINA_TRUE;
3969 if (old != tmp && tmp->realized)
3971 evas_object_geometry_get(VIEW(tmp), &x, &y, &w, &h);
3972 evas_object_geometry_get(obj, &sx, &sy, &sw, &sh);
3973 include = ELM_RECTS_INCLUDE(sx, sy, sw, sh, x, y, w, h);
3975 else if (!tmp->realized) include = EINA_FALSE;
3979 elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
3986 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->next);
3989 nib = EINA_INLIST_CONTAINER_GET(EINA_INLIST_GET(itb)->next, Item_Block);
3990 if (!nib || !nib->realized) break;
3993 if (!sd->focused_item) _item_focus_next(sd, FOCUS_DIR_DOWN);
3998 // when key down and not called key up
3999 // and focus is not on genlist, call select_timer forcely
4000 if (sd->key_down_item)
4002 _select_timer(sd->key_down_item);
4003 sd->key_down_item = NULL;
4006 if (sd->focused_item)
4008 if (sd->focused_content)
4010 //FIXME: when genlist contents loose their focus,
4011 // focus unset should automatically work.
4012 elm_object_focus_set(sd->focused_content, EINA_FALSE);
4014 // Do not use _item_unfocused because focus should be remained
4015 edje_object_signal_emit
4016 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
4017 if (sd->focused_item->deco_all_view)
4018 edje_object_signal_emit
4019 (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
4027 _elm_genlist_item_elm_widget_item_focus_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool focused)
4029 Evas_Object *obj = WIDGET(it);
4030 ELM_GENLIST_DATA_GET(obj, sd);
4034 if (!elm_object_focus_get(obj))
4035 elm_object_focus_set(obj, EINA_TRUE);
4037 if (!elm_widget_focus_get(obj))
4040 if (sd->focused_content)
4042 elm_object_focus_set(sd->focused_content, EINA_FALSE);
4043 sd->focused_content = NULL;
4046 if (it != sd->focused_item)
4048 if (sd->focused_item)
4049 _item_unfocused(sd->focused_item);
4050 _item_focused(it, sd->focus_scrollto_type);
4052 /* If item is not realized state, widget couldn't get focus_highlight data. */
4055 _elm_widget_item_highlight_in_theme(obj, EO_OBJ(it));
4056 _elm_widget_highlight_in_theme_update(obj);
4057 _elm_widget_focus_highlight_start(obj);
4063 if (!elm_widget_focus_get(obj))
4065 _item_unfocused(it);
4069 EOLIAN static Eina_Bool
4070 _elm_genlist_item_elm_widget_item_focus_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
4072 Evas_Object *obj = WIDGET(it);
4073 ELM_GENLIST_DATA_GET(obj, sd);
4075 if (it == sd->focused_item)
4081 EOLIAN static Elm_Object_Item*
4082 _elm_genlist_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
4084 return EO_OBJ(sd->focused_item);
4087 static Eina_Bool _elm_genlist_smart_focus_next_enable = EINA_FALSE;
4089 EOLIAN static Eina_Bool
4090 _elm_genlist_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
4092 return _elm_genlist_smart_focus_next_enable;
4095 EOLIAN static Eina_Bool
4096 _elm_genlist_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
4101 EOLIAN static Eina_Bool
4102 _elm_genlist_elm_widget_focus_next(Eo *obj, Elm_Genlist_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
4104 Eina_List *items = NULL;
4105 Item_Block *itb = NULL;
4106 Elm_Object_Item *eo_it = NULL;
4108 if (!sd->blocks) return EINA_FALSE;
4109 if (!sd->is_access) return EINA_FALSE;
4111 if (!elm_widget_highlight_get(obj))
4113 if (ELM_FOCUS_PREVIOUS == dir)
4115 eo_it = elm_genlist_last_item_get(obj);
4116 itb = EINA_INLIST_CONTAINER_GET(sd->blocks->last, Item_Block);
4118 else if (ELM_FOCUS_NEXT == dir)
4120 eo_it = elm_genlist_first_item_get(obj);
4121 itb = EINA_INLIST_CONTAINER_GET(sd->blocks, Item_Block);
4123 else return EINA_FALSE;
4125 if (eo_it && itb && itb->calc_done)
4127 _item_block_realize(itb, EINA_TRUE);
4128 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
4130 else return EINA_FALSE;
4133 // FIXME: do not use realized items get
4134 // because of above forcing realization case.
4135 EINA_INLIST_FOREACH(sd->blocks, itb)
4140 if (!itb->realized) continue;
4142 EINA_LIST_FOREACH(itb->items, l, it)
4145 Evas_Object *c, *ret;
4148 if (!(it->realized)) continue;
4150 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_access_object_get()))
4151 items = eina_list_append(items, eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_access_object_get()));
4153 items = eina_list_append(items, VIEW(it));
4155 orders = (Eina_List *)elm_object_item_access_order_get(EO_OBJ(it));
4156 EINA_LIST_FOREACH(orders, ll, c)
4158 items = eina_list_append(items, c);
4163 return elm_widget_focus_list_next_get
4164 (obj, items, eina_list_data_get, dir, next, next_item);
4168 _mirrored_set(Evas_Object *obj,
4171 eo_do(obj, elm_interface_scrollable_mirrored_set(rtl));
4174 EOLIAN static Elm_Theme_Apply
4175 _elm_genlist_elm_widget_theme_apply(Eo *obj, Elm_Genlist_Data *sd)
4178 Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
4179 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wsd, ELM_THEME_APPLY_FAILED);
4181 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
4182 if (!int_ret) return ELM_THEME_APPLY_FAILED;
4184 if (!TIZEN_PROFILE_WEARABLE)
4185 _banded_bg_state_check(obj, sd);
4187 EINA_INLIST_FOREACH(sd->blocks, itb)
4191 EINA_LIST_FOREACH(itb->items, l, it)
4195 _item_unrealize(it, EINA_FALSE);
4196 GL_IT(it)->calc_done = EINA_FALSE;
4197 GL_IT(it)->block->calc_done = EINA_FALSE;
4199 else _item_queue(it, NULL);
4202 sd->calc_done = EINA_FALSE;
4203 _item_cache_all_free(sd);
4204 eina_hash_free_buckets(sd->size_caches);
4205 elm_layout_sizing_eval(obj);
4206 _changed(sd->pan_obj);
4208 edje_object_signal_emit(wsd->resize_obj, SIGNAL_FOCUS_BG_HIDE, "elm");
4210 if (wsd->scroll_item_align_enable && sd->aligned_item)
4211 elm_genlist_item_show(EO_OBJ(sd->aligned_item), ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
4216 /* FIXME: take off later. maybe this show region coords belong in the
4217 * interface (new api functions, set/get)? */
4219 _show_region_hook(void *data,
4222 Evas_Coord x, y, w, h;
4224 ELM_GENLIST_DATA_GET(data, sd);
4226 elm_widget_show_region_get(obj, &x, &y, &w, &h);
4227 //x & y are screen coordinates, Add with pan coordinates
4231 eo_do(obj, elm_interface_scrollable_content_region_show(x, y, w, h));
4234 EOLIAN static Eina_Bool
4235 _elm_genlist_elm_widget_translate(Eo *obj, Elm_Genlist_Data *sd)
4239 // Before calling text_get, inform user first.
4240 evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
4242 // FIXME: We should change item's height if lang is changed??
4243 EINA_INLIST_FOREACH(sd->blocks, itb)
4247 EINA_LIST_FOREACH(itb->items, l, it)
4251 elm_genlist_item_fields_update(EO_OBJ(it),
4253 ELM_GENLIST_ITEM_FIELD_TEXT |
4254 ELM_GENLIST_ITEM_FIELD_CONTENT);
4256 else GL_IT(it)->calc_done = EINA_FALSE;
4258 itb->calc_done = EINA_FALSE;
4261 eina_hash_free_buckets(sd->size_caches);
4262 sd->calc_done = EINA_FALSE;
4268 _elm_genlist_elm_widget_item_loop_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enable EINA_UNUSED)
4270 // Need to be implemented
4271 //sd->item_loop_enable = !!enable;
4274 EOLIAN static Eina_Bool
4275 _elm_genlist_elm_widget_item_loop_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
4277 // Need to be implemented
4278 //return sd->item_loop_enable;
4283 _item_block_position_update(Eina_Inlist *list,
4288 EINA_INLIST_FOREACH(list, tmp)
4290 tmp->position = idx++;
4291 tmp->position_update = EINA_TRUE;
4296 _item_position_update(Eina_List *list,
4302 EINA_LIST_FOREACH(list, l, it)
4304 it->position = idx++;
4305 it->position_update = EINA_TRUE;
4310 _item_block_merge(Item_Block *left,
4316 EINA_LIST_FOREACH(right->items, l, it2)
4318 it2->item->block = left;
4320 left->calc_done = EINA_FALSE;
4322 left->items = eina_list_merge(left->items, right->items);
4326 _item_block_del(Elm_Gen_Item *it)
4328 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4330 Item_Block *itb = GL_IT(it)->block;
4331 Eina_Bool block_changed = EINA_FALSE;
4334 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
4335 (NULL, NULL, NULL, &vh));
4336 if (sd->processed_sizes >= vh) sd->processed_sizes = 0;
4338 itb->items = eina_list_remove(itb->items, it);
4340 itb->calc_done = EINA_FALSE;
4341 sd->calc_done = EINA_FALSE;
4342 _changed(sd->pan_obj);
4347 il = EINA_INLIST_GET(itb);
4348 itbn = (Item_Block *)(il->next);
4350 it->parent->item->items =
4351 eina_list_remove(it->parent->item->items, EO_OBJ(it));
4354 _item_block_position_update(il->next, itb->position);
4356 GL_IT(it)->wsd->blocks =
4357 eina_inlist_remove(GL_IT(it)->wsd->blocks, il);
4358 GL_IT(it)->wsd->blocks_realized = eina_list_remove
4359 (GL_IT(it)->wsd->blocks_realized, itb);
4362 if (itbn) itbn->calc_done = EINA_FALSE;
4366 if (itb->count < (itb->sd->max_items_per_block / 2))
4371 il = EINA_INLIST_GET(itb);
4372 itbp = (Item_Block *)(il->prev);
4373 itbn = (Item_Block *)(il->next);
4375 /* merge block with previous */
4377 ((itbp->count + itb->count) <
4378 (itb->sd->max_items_per_block +
4379 (itb->sd->max_items_per_block / 2))))
4381 _item_block_merge(itbp, itb);
4382 _item_block_position_update
4383 (EINA_INLIST_GET(itb)->next, itb->position);
4384 GL_IT(it)->wsd->blocks = eina_inlist_remove
4385 (GL_IT(it)->wsd->blocks, EINA_INLIST_GET(itb));
4386 GL_IT(it)->wsd->blocks_realized = eina_list_remove
4387 (GL_IT(it)->wsd->blocks_realized, itb);
4389 block_changed = EINA_TRUE;
4391 /* merge block with next */
4393 ((itbn->count + itb->count) <
4394 (itb->sd->max_items_per_block +
4395 (itb->sd->max_items_per_block / 2))))
4397 _item_block_merge(itb, itbn);
4398 _item_block_position_update
4399 (EINA_INLIST_GET(itbn)->next, itbn->position);
4400 GL_IT(it)->wsd->blocks =
4401 eina_inlist_remove(GL_IT(it)->wsd->blocks,
4402 EINA_INLIST_GET(itbn));
4403 GL_IT(it)->wsd->blocks_realized = eina_list_remove
4404 (GL_IT(it)->wsd->blocks_realized, itbn);
4406 block_changed = EINA_TRUE;
4413 _changed(sd->pan_obj);
4416 GL_IT(it)->block = NULL;
4420 _decorate_all_item_unrealize(Elm_Gen_Item *it)
4422 if (!it->deco_all_view) return;
4424 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
4425 _view_clear(it->deco_all_view, &(GL_IT(it)->deco_all_contents));
4426 evas_object_del(it->deco_all_view);
4427 it->deco_all_view = NULL;
4429 edje_object_signal_emit(VIEW(it), SIGNAL_DECORATE_DISABLED, "elm");
4431 _item_mouse_callbacks_add(it, VIEW(it));
4432 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
4437 _item_mouse_move_cb(void *data,
4438 Evas *evas EINA_UNUSED,
4442 Evas_Event_Mouse_Move *ev = event_info;
4443 Elm_Gen_Item *it = data;
4444 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4446 if (!it->down) return;
4448 if (((sd->reorder_force) || (sd->reorder_mode)) &&
4449 (sd->reorder.it == it) &&
4453 evas_object_geometry_get(sd->pan_obj, &ox, NULL, NULL, NULL);
4455 if ((ev->cur.canvas.y - it->dy) > GL_IT(it)->scrl_y)
4456 sd->reorder.dir = 1;
4457 else if ((ev->cur.canvas.y - it->dy) < GL_IT(it)->scrl_y)
4458 sd->reorder.dir = -1;
4460 GL_IT(it)->scrl_x = it->x + GL_IT(it)->block->x - sd->pan_x + ox;
4461 GL_IT(it)->scrl_y = ev->cur.canvas.y - it->dy;
4462 GL_IT(it)->w = sd->minw;
4463 GL_IT(it)->h = GL_IT(it)->minh;
4464 _changed(sd->pan_obj);
4467 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4469 if (GL_IT(it)->highlight_timer)
4471 ecore_timer_del(GL_IT(it)->highlight_timer);
4472 GL_IT(it)->highlight_timer = NULL;
4474 else if (!it->selected) _item_unhighlight(it, EINA_FALSE);
4478 ecore_timer_del(it->long_timer);
4479 it->long_timer = NULL;
4481 sd->on_hold = EINA_TRUE; /* for checking need to start select timer */
4483 //******************** TIZEN Only
4486 if (((sd->reorder_force) || (sd->reorder_mode)) &&
4487 (sd->reorder.it == it) && (!it->want_hidden))
4489 Evas_Coord x, y, w, h;
4490 evas_object_geometry_get(obj, &x, &y, &w, &h);
4491 if (ELM_RECTS_POINT_OUT(x, y, w, h, ev->cur.canvas.x, ev->cur.canvas.y))
4495 ecore_timer_del(it->long_timer);
4496 it->long_timer = NULL;
4498 if (GL_IT(it)->highlight_timer)
4500 ecore_timer_del(GL_IT(it)->highlight_timer);
4501 GL_IT(it)->highlight_timer = NULL;
4503 else if (!it->selected) _item_unhighlight(it, EINA_FALSE);
4506 //*******************************
4508 evas_object_ref(obj);
4512 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
4513 minw = GL_IT(it)->wsd->finger_minw;
4514 minh = GL_IT(it)->wsd->finger_minh;
4516 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4517 dx = ev->cur.canvas.x - x;
4518 dy = ev->cur.canvas.y - y;
4523 if (adx < 0) adx = -dx;
4524 if (ady < 0) ady = -dy;
4525 if ((adx > minw) || (ady > minh))
4527 it->dragging = EINA_TRUE;
4528 /* Genlist is scrolled vertically, so reduce left or right case for accuracy. */
4529 if (adx > (ady * 2))
4532 evas_object_smart_callback_call
4533 (WIDGET(it), SIG_DRAG_START_LEFT, EO_OBJ(it));
4535 evas_object_smart_callback_call
4536 (WIDGET(it), SIG_DRAG_START_RIGHT, EO_OBJ(it));
4541 evas_object_smart_callback_call
4542 (WIDGET(it), SIG_DRAG_START_UP, EO_OBJ(it));
4544 evas_object_smart_callback_call
4545 (WIDGET(it), SIG_DRAG_START_DOWN, EO_OBJ(it));
4550 /* If item magic value is changed, do not call smart callback*/
4551 if (EINA_MAGIC_CHECK(it->base, ELM_WIDGET_ITEM_MAGIC))
4554 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, EO_OBJ(it));
4557 evas_object_unref(obj);
4562 _long_press_cb(void *data)
4564 Elm_Gen_Item *it = data;
4565 Elm_Object_Item *eo_it2;
4566 Elm_Genlist_Data *sd;
4570 sd = GL_IT(it)->wsd;
4571 it->long_timer = NULL;
4573 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()) ||
4574 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
4575 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
4576 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
4577 (sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
4580 if ((sd->reorder_mode) &&
4581 (GL_IT(it)->type != ELM_GENLIST_ITEM_GROUP) &&
4582 (!sd->key_down_item))
4584 if (elm_genlist_item_expanded_get(EO_OBJ(it)))
4586 elm_genlist_item_expanded_set(EO_OBJ(it), EINA_FALSE);
4588 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it2)
4590 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
4591 _item_unselect(it2);
4594 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
4595 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
4596 (EINA_FALSE, EINA_FALSE));
4598 if (TIZEN_PROFILE_WEARABLE)
4601 if (sd->decorate_all_mode)
4602 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
4606 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
4609 sd->reorder.it = it;
4610 _changed(sd->pan_obj);
4612 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, EO_OBJ(it));
4615 it->long_timer = NULL;
4616 return ECORE_CALLBACK_CANCEL;
4620 _gesture_do(void *data)
4622 Elm_Genlist_Data *sd = data;
4624 if ((sd->g_item) && (sd->g_type))
4626 if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_LEFT))
4627 evas_object_smart_callback_call
4628 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_LEFT, EO_OBJ(sd->g_item));
4629 else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_RIGHT))
4630 evas_object_smart_callback_call
4631 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_RIGHT, EO_OBJ(sd->g_item));
4632 else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_UP))
4633 evas_object_smart_callback_call
4634 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_UP, EO_OBJ(sd->g_item));
4635 else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_DOWN))
4636 evas_object_smart_callback_call
4637 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_DOWN, EO_OBJ(sd->g_item));
4638 else if (!strcmp(sd->g_type, SIG_MULTI_PINCH_OUT))
4639 evas_object_smart_callback_call
4640 (WIDGET(sd->g_item), SIG_MULTI_PINCH_OUT, EO_OBJ(sd->g_item));
4641 else if (!strcmp(sd->g_type, SIG_MULTI_PINCH_IN))
4642 evas_object_smart_callback_call
4643 (WIDGET(sd->g_item), SIG_MULTI_PINCH_IN, EO_OBJ(sd->g_item));
4644 else if (!strcmp(sd->g_type, SIG_SWIPE))
4645 evas_object_smart_callback_call
4646 (WIDGET(sd->g_item), SIG_SWIPE, EO_OBJ(sd->g_item));
4654 _item_mouse_down_cb(void *data,
4659 Evas_Event_Mouse_Down *ev = event_info;
4660 Elm_Gen_Item *it = data;
4661 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4664 if (ev->event_flags & EVAS_EVENT_FLAG_ON_SCROLL)
4668 elm_genlist_item_reorder_stop(EO_OBJ(sd->reorder.it));
4669 sd->reorder.it = NULL;
4670 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
4671 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set(sd->h_bounce, sd->v_bounce));
4676 if (ev->button != 1) return;
4677 // mouse down is activate only one finger
4678 if (evas_event_down_count_get(evas) != 1) return;
4680 if (GL_IT(it)->highlight_timer)
4681 ecore_timer_del(GL_IT(it)->highlight_timer);
4682 // FIXME: To prevent timing issue about select and highlight
4683 else if (!sd->multi && sd->highlighted_item &&
4684 (GL_IT(sd->highlighted_item)->highlight_timer))
4687 it->down = EINA_TRUE;
4689 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4690 it->dx = ev->canvas.x - x;
4691 it->dy = ev->canvas.y - y;
4693 GL_IT(it)->wsd->was_selected = it->selected;
4694 GL_IT(it)->highlight_timer = ecore_timer_add(ELM_ITEM_HIGHLIGHT_TIMER,
4695 _highlight_timer, it);
4696 if (it->long_timer) ecore_timer_del(it->long_timer);
4697 it->long_timer = ecore_timer_add(sd->longpress_timeout, _long_press_cb, it);
4699 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
4701 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, EO_OBJ(it));
4702 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, EO_OBJ(it));
4704 evas_object_smart_callback_call(WIDGET(it), SIG_PRESSED, EO_OBJ(it));
4708 _item_block_new(Elm_Genlist_Data *sd,
4713 itb = calloc(1, sizeof(Item_Block));
4714 if (!itb) return NULL;
4718 sd->blocks = eina_inlist_prepend(sd->blocks, EINA_INLIST_GET(itb));
4719 _item_block_position_update(sd->blocks, 0);
4723 sd->blocks = eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4724 itb->position_update = EINA_TRUE;
4725 if (sd->blocks != EINA_INLIST_GET(itb))
4728 ((Item_Block *)(EINA_INLIST_GET(itb)->prev))->position + 1;
4740 _item_block_add(Elm_Genlist_Data *sd,
4743 Item_Block *itb = NULL;
4744 if (GL_IT(it)->block) return EINA_TRUE;
4746 if (!GL_IT(it)->rel)
4751 itb = calloc(1, sizeof(Item_Block));
4752 if (!itb) return EINA_FALSE;
4754 if (!GL_IT(it)->rel->item->block)
4757 eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4758 itb->items = eina_list_append(itb->items, it);
4759 itb->position_update = EINA_TRUE;
4760 it->position = eina_list_count(itb->items);
4761 it->position_update = EINA_TRUE;
4763 if (sd->blocks != EINA_INLIST_GET(itb))
4767 (EINA_INLIST_GET(itb)->prev))->position + 1;
4778 tmp = eina_list_data_find_list(itb->items, GL_IT(it)->rel);
4779 if (GL_IT(it)->before)
4781 sd->blocks = eina_inlist_prepend_relative
4782 (sd->blocks, EINA_INLIST_GET(itb),
4783 EINA_INLIST_GET(GL_IT(it)->rel->item->block));
4785 eina_list_prepend_relative_list(itb->items, it, tmp);
4787 /* Update index from where we prepended */
4788 _item_position_update
4789 (eina_list_prev(tmp), GL_IT(it)->rel->position);
4790 _item_block_position_update
4791 (EINA_INLIST_GET(itb),
4792 GL_IT(it)->rel->item->block->position);
4796 sd->blocks = eina_inlist_append_relative
4797 (sd->blocks, EINA_INLIST_GET(itb),
4798 EINA_INLIST_GET(GL_IT(it)->rel->item->block));
4800 eina_list_append_relative_list(itb->items, it, tmp);
4802 /* Update block index from where we appended */
4803 _item_position_update
4804 (eina_list_next(tmp), GL_IT(it)->rel->position + 1);
4805 _item_block_position_update
4806 (EINA_INLIST_GET(itb),
4807 GL_IT(it)->rel->item->block->position + 1);
4813 if (GL_IT(it)->before)
4817 itb = (Item_Block *)(sd->blocks);
4818 if (itb->count >= sd->max_items_per_block)
4820 itb = _item_block_new(sd, EINA_TRUE);
4821 if (!itb) return EINA_FALSE;
4826 itb = _item_block_new(sd, EINA_TRUE);
4827 if (!itb) return EINA_FALSE;
4829 itb->items = eina_list_prepend(itb->items, it);
4830 _item_position_update(itb->items, 1);
4836 itb = (Item_Block *)(sd->blocks->last);
4837 if (itb->count >= sd->max_items_per_block)
4839 itb = _item_block_new(sd, EINA_FALSE);
4840 if (!itb) return EINA_FALSE;
4845 itb = _item_block_new(sd, EINA_FALSE);
4846 if (!itb) return EINA_FALSE;
4848 itb->items = eina_list_append(itb->items, it);
4849 it->position = eina_list_count(itb->items);
4858 if ((!GL_IT(it)->wsd->sorting) && (GL_IT(it)->rel->item->queued))
4860 /* NOTE: for a strange reason eina_list and eina_inlist
4861 don't have the same property on sorted insertion
4862 order, so the queue is not always ordered like the
4863 item list. This lead to issue where we depend on an
4864 item that is not yet created. As a quick work around,
4865 we reschedule the calc of the item and stop reordering
4866 the list to prevent any nasty issue to show up here.
4868 sd->queue = eina_list_append(sd->queue, it);
4869 sd->requeued = EINA_TRUE;
4870 GL_IT(it)->queued = EINA_TRUE;
4875 itb = GL_IT(it)->rel->item->block;
4876 if (!itb) goto newblock;
4877 tmp = eina_list_data_find_list(itb->items, GL_IT(it)->rel);
4878 if (GL_IT(it)->before)
4880 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4881 _item_position_update
4882 (eina_list_prev(tmp), GL_IT(it)->rel->position);
4886 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4887 _item_position_update
4888 (eina_list_next(tmp), GL_IT(it)->rel->position + 1);
4893 itb->calc_done = EINA_FALSE;
4894 sd->calc_done = EINA_FALSE;
4895 GL_IT(it)->block = itb;
4896 _changed(itb->sd->pan_obj);
4898 if (itb->count > itb->sd->max_items_per_block)
4903 Eina_Bool done = EINA_FALSE;
4905 newc = itb->count / 2;
4907 if (EINA_INLIST_GET(itb)->prev)
4909 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4911 if (itbp->count + newc < sd->max_items_per_block / 2)
4913 /* moving items to previous block */
4914 while ((itb->count > newc) && (itb->items))
4916 it2 = eina_list_data_get(itb->items);
4917 itb->items = eina_list_remove_list
4918 (itb->items, itb->items);
4921 itbp->items = eina_list_append(itbp->items, it2);
4922 it2->item->block = itbp;
4930 if (!done && EINA_INLIST_GET(itb)->next)
4932 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4934 if (itbn->count + newc < sd->max_items_per_block / 2)
4936 /* moving items to next block */
4937 while ((itb->count > newc) && (itb->items))
4941 l = eina_list_last(itb->items);
4942 it2 = eina_list_data_get(l);
4943 itb->items = eina_list_remove_list(itb->items, l);
4946 itbn->items = eina_list_prepend(itbn->items, it2);
4947 it2->item->block = itbn;
4957 /* moving items to new block */
4958 itb2 = calloc(1, sizeof(Item_Block));
4959 if (!itb2) return EINA_FALSE;
4962 eina_inlist_append_relative(sd->blocks, EINA_INLIST_GET(itb2),
4963 EINA_INLIST_GET(itb));
4964 itb2->calc_done = EINA_FALSE;
4965 while ((itb->count > newc) && (itb->items))
4969 l = eina_list_last(itb->items);
4971 itb->items = eina_list_remove_list(itb->items, l);
4974 itb2->items = eina_list_prepend(itb2->items, it2);
4975 it2->item->block = itb2;
4985 _item_min_calc(Elm_Gen_Item *it)
4987 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4988 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wd);
4989 Evas_Coord mw = 0, mh = 0;
4992 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
4993 (NULL, NULL, &vw, NULL));
4995 if ((it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) &&
4996 (sd->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
4998 mw = sd->finger_minw;
4999 mh = sd->finger_minh;
5002 if ((sd->mode == ELM_LIST_COMPRESS) && vw && mw < vw)
5005 //FIXME: Some widget such as entry, label need to have fixed width size before
5006 // min calculation to get proper height size by multiline.
5007 if (sd->realization_mode || GL_IT(it)->resized)
5008 evas_object_resize(VIEW(it), mw, mh);
5010 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
5012 if ((sd->mode != ELM_LIST_LIMIT) && vw && mw < vw)
5015 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5016 if (sd->homogeneous || it->itc->homogeneous)
5018 Size_Cache *size, *tmp;
5019 tmp = eina_hash_find(sd->size_caches, it->itc->item_style);
5021 eina_hash_del_by_key(sd->size_caches, it->itc->item_style);
5023 size = ELM_NEW(Size_Cache);
5026 eina_hash_add(sd->size_caches, it->itc->item_style, size);
5029 GL_IT(it)->w = GL_IT(it)->minw = mw;
5030 GL_IT(it)->h = GL_IT(it)->minh = mh;
5032 // FIXME: This is workaround for entry size issue.
5033 if (sd->realization_mode || GL_IT(it)->resized)
5035 GL_IT(it)->resized = EINA_FALSE;
5036 if (it->deco_all_view)
5037 evas_object_resize(it->deco_all_view, GL_IT(it)->w, GL_IT(it)->h);
5038 else if (GL_IT(it)->deco_it_view)
5039 evas_object_resize(GL_IT(it)->deco_it_view, GL_IT(it)->w, GL_IT(it)->h);
5041 evas_object_resize(VIEW(it), GL_IT(it)->w, GL_IT(it)->h);
5044 if (wd->scroll_item_align_enable && (sd->aligned_item == it))
5045 _focus_bg_show(sd->aligned_item);
5049 _item_calc(Elm_Gen_Item *it)
5051 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5052 Size_Cache *size = NULL;
5053 Evas_Coord p_minw, p_minh;
5055 if (GL_IT(it)->calc_done) return;
5057 p_minw = GL_IT(it)->minw;
5058 p_minh = GL_IT(it)->minh;
5060 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5061 if (sd->homogeneous || it->itc->homogeneous)
5062 size = eina_hash_find(sd->size_caches, it->itc->item_style);
5065 GL_IT(it)->w = GL_IT(it)->minw = size->minw;
5066 GL_IT(it)->h = GL_IT(it)->minh = size->minh;
5072 if (sd->realization_mode)
5074 _item_realize(it, EINA_FALSE);
5079 _item_realize(it, EINA_TRUE);
5081 _item_unrealize(it, EINA_TRUE);
5088 GL_IT(it)->calc_done = EINA_TRUE;
5089 if ((p_minw != GL_IT(it)->minw) || (p_minh != GL_IT(it)->minh))
5091 GL_IT(it)->block->calc_done = EINA_FALSE;
5092 sd->calc_done = EINA_FALSE;
5097 _item_process(Elm_Genlist_Data *sd,
5100 if (!_item_block_add(sd, it)) return EINA_FALSE;
5102 GL_IT(it)->calc_done = EINA_FALSE;
5109 _dummy_job(void *data)
5111 Elm_Genlist_Data *sd = data;
5112 sd->dummy_job = NULL;
5117 _queue_idle_enter(void *data)
5119 Elm_Genlist_Data *sd = data;
5124 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
5125 (NULL, NULL, &vw, NULL));
5126 if (!sd->queue || (vw <= 1))
5130 ecore_job_del(sd->dummy_job);
5131 sd->dummy_job = NULL;
5133 sd->queue_idle_enterer = NULL;
5134 return ECORE_CALLBACK_CANCEL;
5137 ft = ecore_animator_frametime_get()/2;
5138 t0 = ecore_time_get();
5139 for (n = 0; (sd->queue) && (n < ITEM_QUEUE_MAX); n++)
5144 it = eina_list_data_get(sd->queue);
5145 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
5146 GL_IT(it)->queued = EINA_FALSE;
5147 GL_IT(it)->resized = EINA_FALSE;
5148 if (!_item_process(sd, it)) continue;
5149 t = ecore_time_get();
5150 /* same as eina_inlist_count > 1 */
5151 if (sd->blocks && sd->blocks->next)
5153 if ((t - t0) > ft) break;
5157 _changed(sd->pan_obj);
5162 ecore_job_del(sd->dummy_job);
5163 sd->dummy_job = NULL;
5165 sd->queue_idle_enterer = NULL;
5166 return ECORE_CALLBACK_CANCEL;
5169 // Do not use smart_changed
5170 // Instead make any events (job, idler, etc.) to call idle enterer
5171 if (sd->dummy_job) ecore_job_del(sd->dummy_job);
5172 sd->dummy_job = ecore_job_add(_dummy_job, sd);
5174 return ECORE_CALLBACK_RENEW;
5178 _item_queue(Elm_Gen_Item *it,
5179 Eina_Compare_Cb cb EINA_UNUSED)
5181 if (GL_IT(it)->queued) return;
5183 GL_IT(it)->queued = EINA_TRUE;
5184 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5186 // FIXME: Below code occurs item unsorted result.
5187 // genlist already calculate items position by sd->items
5188 // so no need to requeue items by sorting insert.
5189 // if (cb && !sd->requeued)
5190 // sd->queue = eina_list_sorted_insert(sd->queue, cb, it);
5192 sd->queue = eina_list_append(sd->queue, it);
5194 if (sd->queue_idle_enterer)
5195 ecore_idle_enterer_del(sd->queue_idle_enterer);
5196 sd->queue_idle_enterer = ecore_idle_enterer_add(_queue_idle_enter, sd);
5200 _item_queue_direct(Elm_Gen_Item *it,
5203 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5205 // Processing items within viewport if items already exist.
5206 // This can prevent flickering issue when content size is changed.
5207 // This can fix the flickering issue when expanded item have subitems whose total height > vh
5208 if (!sd->queue && (sd->viewport_w > 1) &&
5209 ((sd->processed_sizes <= sd->viewport_h) || (GL_IT(it)->expanded_depth > 0)))
5211 #ifdef GENLIST_FX_SUPPORT
5212 if (sd->fx_mode)// && !it->item->is_prepend) // For support preppended items - hs619.choi@samsung.com
5214 sd->add_fx.items = eina_list_append(sd->add_fx.items, it);
5215 if (!sd->add_fx.anim)
5217 sd->add_fx.cnt = ANIM_CNT_MAX;
5218 sd->add_fx.anim = ecore_animator_add(_add_fx_anim, sd);
5222 _item_process(sd, it);
5223 sd->processed_sizes += GL_IT(it)->minh;
5225 _changed(sd->pan_obj);
5228 _item_queue(it, cb);
5231 /* If the application wants to know the relative item, use
5232 * elm_genlist_item_prev_get(it)*/
5234 _item_move_after(Elm_Gen_Item *it,
5235 Elm_Gen_Item *after)
5239 if (it == after) return;
5241 GL_IT(it)->wsd->items =
5242 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
5243 if (GL_IT(it)->block) _item_block_del(it);
5245 GL_IT(it)->wsd->items = eina_inlist_append_relative
5246 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
5249 GL_IT(it)->rel->item->rel_revs =
5250 eina_list_remove(GL_IT(it)->rel->item->rel_revs, it);
5251 GL_IT(it)->rel = after;
5252 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
5253 GL_IT(it)->before = EINA_FALSE;
5254 if (after->item->group_item) GL_IT(it)->group_item = after->item->group_item;
5256 if (GL_IT(it)->queued)
5258 GL_IT(it)->wsd->queue = eina_list_remove(GL_IT(it)->wsd->queue, it);
5259 GL_IT(it)->queued = EINA_FALSE;
5261 _item_queue_direct(it, NULL);
5263 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, EO_OBJ(it));
5266 /* If the application wants to know the relative item, use
5267 * elm_genlist_item_next_get(it)*/
5269 _item_move_before(Elm_Gen_Item *it,
5270 Elm_Gen_Item *before)
5273 if (!before) return;
5274 if (it == before) return;
5276 GL_IT(it)->wsd->items =
5277 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
5278 if (GL_IT(it)->block) _item_block_del(it);
5279 GL_IT(it)->wsd->items = eina_inlist_prepend_relative
5280 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
5283 GL_IT(it)->rel->item->rel_revs =
5284 eina_list_remove(GL_IT(it)->rel->item->rel_revs, it);
5285 GL_IT(it)->rel = before;
5286 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
5287 GL_IT(it)->before = EINA_TRUE;
5288 if (before->item->group_item)
5289 GL_IT(it)->group_item = before->item->group_item;
5290 _item_queue_direct(it, NULL);
5292 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, EO_OBJ(it));
5296 _item_mouse_up_cb(void *data,
5298 Evas_Object *obj EINA_UNUSED,
5301 Evas_Event_Mouse_Up *ev = event_info;
5302 Elm_Gen_Item *it = data;
5303 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5305 ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd);
5307 if (!it->down) return;
5308 it->down = EINA_FALSE;
5310 if (ev->button != 1) return;
5314 it->dragging = EINA_FALSE;
5315 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, EO_OBJ(it));
5317 // When the event is cancelled, need to initialize mouse flags and timers.
5318 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = EINA_TRUE;
5322 if (evas_event_down_count_get(evas) != 0)
5324 if (!GL_IT(it)->highlight_timer) _item_unhighlight(it, EINA_TRUE);
5329 ecore_timer_del(it->long_timer);
5330 it->long_timer = NULL;
5332 if (GL_IT(it)->highlight_timer)
5334 ecore_timer_del(GL_IT(it)->highlight_timer);
5335 GL_IT(it)->highlight_timer = NULL;
5336 // Because naviframe can drop the all evevents.
5337 // highlight it before select timer is called.
5338 if (evas_event_down_count_get(evas) == 0) _item_highlight(it);
5341 if (!sd->reorder.it && (evas_event_down_count_get(evas) == 0))
5343 // FIXME: if highlight mode is not used, mouse move cannot disable
5345 if ((sd->was_selected == it->selected) && (!sd->on_hold))
5347 if (wd->scroll_item_align_enable)
5349 const char *align = edje_object_data_get(VIEW(it), "align");
5350 if (!align || strcmp(align, "off"))
5352 if (it != sd->aligned_item)
5354 elm_genlist_item_bring_in(EO_OBJ(it), ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
5358 if (((sd->highlight && it->highlighted) || !sd->highlight) &&
5359 ((!wd->scroll_item_align_enable) || (it == sd->aligned_item)))
5360 GL_IT(it)->highlight_timer =
5361 ecore_timer_add(ITEM_SELECT_TIMER, _select_timer, it);
5362 else if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
5363 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
5366 Evas_Object *content;
5367 if (sd->focused_item != it)
5368 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
5370 sd->focused_content = NULL;
5371 EINA_LIST_FOREACH(it->content_objs, l, content)
5373 if (elm_widget_focused_object_get(content))
5374 sd->focused_content = content;
5379 else if (sd->reorder.it == it)
5381 if (TIZEN_PROFILE_WEARABLE)
5383 Elm_Gen_Item *it2, *it_max = NULL, *it_min = NULL;
5384 Evas_Coord r_y_scrl, it_y_max = -99999999, it_y_min = 99999999;
5386 if (!it->selected) _item_unhighlight(it, EINA_TRUE);
5387 r_y_scrl = GL_IT(it)->scrl_y;
5388 EINA_LIST_FREE(sd->reorder.move_items, it2)
5390 if (sd->reorder.it->parent != it2->parent)
5392 it2->item->reorder_offset = 0;
5395 Evas_Coord it_y = it2->item->scrl_y +
5396 it2->item->reorder_offset + (it2->item->h / 2) +
5397 it2->item->block->y;
5399 if ((it_y < r_y_scrl) &&
5405 else if ((it_y > r_y_scrl) &&
5411 it2->item->reorder_offset = 0;
5415 _item_move_after(it, it_max);
5416 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5420 _item_move_before(it, it_min);
5421 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5427 Elm_Gen_Item *moved_it = NULL;
5428 Elm_Gen_Item *ptr_it = sd->top_drawn_item;
5429 Elm_Gen_Item *last_it = NULL;
5430 Eina_Bool after = EINA_TRUE;
5432 if (!it->selected) _item_unhighlight(it, EINA_FALSE);
5438 if (ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y, GL_IT(it)->w, GL_IT(it)->h,
5439 GL_IT(ptr_it)->scrl_x, GL_IT(ptr_it)->scrl_y, GL_IT(ptr_it)->w, GL_IT(ptr_it)->h))
5441 if (GL_IT(it)->scrl_y < GL_IT(ptr_it)->scrl_y)
5448 if ((GL_IT(it)->scrl_y + GL_IT(it)->h) > (GL_IT(ptr_it)->scrl_y + GL_IT(ptr_it)->h))
5450 if ((GL_IT(it)->scrl_y + GL_IT(it)->h) == GL_IT(ptr_it)->scrl_y)
5458 ptr_it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(ptr_it)->next);
5463 if (GL_IT(it)->scrl_y > GL_IT(last_it)->scrl_y + GL_IT(last_it)->h)
5467 moved_it = sd->top_drawn_item;
5472 EINA_LIST_FREE(sd->reorder.move_items, ptr_it)
5474 ptr_it->item->reorder_offset = 0;
5479 _item_move_after(it, moved_it);
5480 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5484 _item_move_before(it, moved_it);
5485 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5488 sd->reorder.it = NULL;
5489 sd->reorder.dir = 0;
5490 if (sd->reorder.anim)
5492 ecore_animator_del(sd->reorder.anim);
5493 sd->reorder.anim = NULL;
5496 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5497 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
5498 (sd->h_bounce, sd->v_bounce));
5500 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_DISABLED, "elm");
5501 _changed(sd->pan_obj);
5503 sd->on_hold = EINA_FALSE; /* for checking need to start select timer */
5504 evas_object_smart_callback_call(WIDGET(it), SIG_RELEASED, EO_OBJ(it));
5508 _scroll_hold_timer_cb(void *data)
5510 Elm_Genlist_Data *sd = data;
5511 sd->scr_hold_timer = NULL;
5513 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5515 return ECORE_CALLBACK_CANCEL;
5519 _decorate_item_finished_signal_cb(void *data,
5521 const char *emission EINA_UNUSED,
5522 const char *source EINA_UNUSED)
5524 Elm_Gen_Item *it = data;
5526 if (!data || !obj) return;
5527 if ((!it->realized)) return;
5529 _decorate_item_unrealize(it);
5533 _item_update(Elm_Gen_Item *it)
5536 if (!it->realized) return;
5538 _view_clear(VIEW(it), &(it->content_objs));
5539 EINA_LIST_FREE(GL_IT(it)->flip_content_objs, c)
5541 _view_clear(GL_IT(it)->deco_it_view, &(GL_IT(it)->deco_it_contents));
5542 _view_clear(it->deco_all_view, &(GL_IT(it)->deco_all_contents));
5544 _view_inflate(VIEW(it), it, &(it->content_objs));
5547 _item_content_realize(it, VIEW(it), &(GL_IT(it)->flip_content_objs),
5549 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
5551 if (GL_IT(it)->wsd->decorate_all_mode)
5552 _view_inflate(it->deco_all_view, it, &(GL_IT(it)->deco_all_contents));
5553 else if (GL_IT(it)->deco_it_view)
5554 _view_inflate(GL_IT(it)->deco_it_view, it, &(GL_IT(it)->deco_it_contents));
5556 if (!TIZEN_PROFILE_WEARABLE)
5557 _banded_item_bg_add(it, VIEW(it));
5560 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
5562 if (GL_IT(it)->wsd->aligned_item == it)
5563 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
5565 edje_object_message_signal_process(VIEW(it));
5569 _item_block_calc(Item_Block *itb, Evas_Coord vw EINA_UNUSED, Evas_Coord vh)
5573 Evas_Coord minw = 9999999, minh = 0;
5574 int sum_item_height = 0;
5575 ELM_WIDGET_DATA_GET_OR_RETURN(itb->sd->obj, wsd);
5577 if (itb->calc_done) return;
5579 EINA_LIST_FOREACH(itb->items, l, it)
5581 if (it->want_hidden) continue;
5582 if (GL_IT(it)->updateme)
5588 GL_IT(it)->calc_done = EINA_FALSE;
5589 GL_IT(it)->updateme = EINA_FALSE;
5591 if (!GL_IT(it)->queued) _item_calc(it);
5593 if (wsd->scroll_item_align_enable)
5595 int vcenter = vh / 2;
5596 int icenter = GL_IT(it)->h / 2;
5597 if ((itb->y + sum_item_height < vcenter && itb->y + sum_item_height + GL_IT(it)->h > vcenter) &&
5598 (sum_item_height + icenter < vcenter - 1 || sum_item_height + icenter > vcenter + 1))
5600 int first_item_height = sum_item_height = vcenter - icenter;
5602 Elm_Object_Item *eo_prev = elm_genlist_item_prev_get(EO_OBJ(it));
5603 Elm_Gen_Item *prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
5606 minh = sum_item_height;
5609 if (eo_prev == elm_genlist_first_item_get(wsd->obj))
5611 GL_IT(prev)->h = GL_IT(prev)->minh = first_item_height;
5614 first_item_height -= GL_IT(prev)->h;
5615 prev->y = first_item_height;
5616 eo_prev = elm_genlist_item_prev_get(eo_prev);
5617 prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
5620 sum_item_height += GL_IT(it)->h;
5625 if (minw > GL_IT(it)->minw) minw = GL_IT(it)->minw;
5626 minh += GL_IT(it)->minh;
5627 if (GL_IT(it)->is_prepend)
5629 itb->sd->comp_y += GL_IT(it)->minh;
5630 GL_IT(it)->is_prepend = EINA_FALSE;
5635 itb->calc_done = EINA_TRUE;
5636 itb->position_update = EINA_FALSE;
5640 _scroll_animate_start_cb(Evas_Object *obj,
5641 void *data EINA_UNUSED)
5643 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5644 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
5645 if (wd->scroll_item_align_enable)
5647 edje_object_signal_emit(wd->resize_obj, SIGNAL_FOCUS_BG_HIDE, "elm");
5652 _scroll_animate_stop_cb(Evas_Object *obj,
5653 void *data EINA_UNUSED)
5655 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5656 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
5658 //TIZEN_ONLY: Let the screen-reader know when scroll animation ends
5659 if (_elm_atspi_enabled())
5661 elm_interface_atspi_accessible_visible_data_changed_signal_emit(obj);
5667 _scroll_drag_start_cb(Evas_Object *obj,
5668 void *data EINA_UNUSED)
5670 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5671 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
5672 if (wd->scroll_item_align_enable)
5674 edje_object_signal_emit(wd->resize_obj, SIGNAL_FOCUS_BG_HIDE, "elm");
5679 _scroll_timeout_cb(void *data)
5681 Elm_Genlist_Data *sd = data;
5683 sd->scr_timer = NULL;
5684 if (sd->queue && !sd->queue_idle_enterer)
5686 sd->queue_idle_enterer = ecore_idle_enterer_add(_queue_idle_enter, sd);
5687 if (sd->dummy_job) ecore_job_del(sd->dummy_job);
5688 sd->dummy_job = ecore_job_add(_dummy_job, sd);
5690 return ECORE_CALLBACK_CANCEL;
5694 _scroll_cb(Evas_Object *obj,
5695 void *data EINA_UNUSED)
5697 ELM_GENLIST_DATA_GET(obj, sd);
5699 if (sd->queue_idle_enterer)
5701 ecore_idle_enterer_del(sd->queue_idle_enterer);
5702 sd->queue_idle_enterer = NULL;
5705 ecore_job_del(sd->dummy_job);
5706 sd->dummy_job = NULL;
5709 if (sd->scr_timer) ecore_timer_del(sd->scr_timer);
5710 sd->scr_timer = ecore_timer_add(0.25, _scroll_timeout_cb, sd);
5712 evas_object_smart_callback_call(obj, SIG_SCROLL, NULL);
5716 _scroll_drag_stop_cb(Evas_Object *obj,
5717 void *data EINA_UNUSED)
5719 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_STOP, NULL);
5720 //TIZEN_ONLY: Let the screen-reader know when drag ends
5721 if (_elm_atspi_enabled())
5723 elm_interface_atspi_accessible_visible_data_changed_signal_emit(obj);
5729 _edge_left_cb(Evas_Object *obj,
5730 void *data EINA_UNUSED)
5732 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
5736 _edge_right_cb(Evas_Object *obj,
5737 void *data EINA_UNUSED)
5739 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
5743 _edge_top_cb(Evas_Object *obj,
5744 void *data EINA_UNUSED)
5746 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
5750 _edge_bottom_cb(Evas_Object *obj,
5751 void *data EINA_UNUSED)
5753 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
5757 _vbar_drag_cb(Evas_Object *obj,
5758 void *data EINA_UNUSED)
5760 evas_object_smart_callback_call(obj, SIG_VBAR_DRAG, NULL);
5764 _vbar_press_cb(Evas_Object *obj,
5765 void *data EINA_UNUSED)
5767 evas_object_smart_callback_call(obj, SIG_VBAR_PRESS, NULL);
5771 _vbar_unpress_cb(Evas_Object *obj,
5772 void *data EINA_UNUSED)
5774 evas_object_smart_callback_call(obj, SIG_VBAR_UNPRESS, NULL);
5778 _hbar_drag_cb(Evas_Object *obj,
5779 void *data EINA_UNUSED)
5781 evas_object_smart_callback_call(obj, SIG_HBAR_DRAG, NULL);
5785 _hbar_press_cb(Evas_Object *obj,
5786 void *data EINA_UNUSED)
5788 evas_object_smart_callback_call(obj, SIG_HBAR_PRESS, NULL);
5792 _hbar_unpress_cb(Evas_Object *obj,
5793 void *data EINA_UNUSED)
5795 evas_object_smart_callback_call(obj, SIG_HBAR_UNPRESS, NULL);
5799 _decorate_item_realize(Elm_Gen_Item *it)
5802 if (GL_IT(it)->deco_it_view || !it->itc->decorate_item_style) return;
5804 // Before adding & swallowing, delete it from smart member
5805 evas_object_smart_member_del(VIEW(it));
5807 GL_IT(it)->deco_it_view = _view_create(it, it->itc->decorate_item_style);
5808 edje_object_part_swallow
5809 (GL_IT(it)->deco_it_view,
5810 edje_object_data_get(GL_IT(it)->deco_it_view, "mode_part"), VIEW(it));
5811 _view_inflate(GL_IT(it)->deco_it_view, it, &(GL_IT(it)->deco_it_contents));
5813 snprintf(buf, sizeof(buf), "elm,state,%s,active",
5814 GL_IT(it)->wsd->decorate_it_type);
5815 edje_object_signal_emit(GL_IT(it)->deco_it_view, buf, "elm");
5816 edje_object_signal_emit(VIEW(it), buf, "elm");
5818 _item_mouse_callbacks_add(it, GL_IT(it)->deco_it_view);
5820 _item_mouse_callbacks_del(it, VIEW(it));
5824 // FIXME: difference from upstream
5826 _mouse_down_scroller(void *data,
5827 Evas *evas EINA_UNUSED,
5828 Evas_Object *obj EINA_UNUSED,
5829 void *event_info EINA_UNUSED)
5831 Widget_Data *wd = elm_widget_data_get(data);
5834 wd->drag_started = EINA_FALSE;
5838 _mouse_up_scroller(void *data,
5839 Evas *evas EINA_UNUSED,
5840 Evas_Object *obj EINA_UNUSED,
5841 void *event_info EINA_UNUSED)
5843 Widget_Data *wd = elm_widget_data_get(data);
5846 wd->drag_started = EINA_FALSE;
5850 _mouse_move_scroller(void *data,
5851 Evas *evas EINA_UNUSED,
5852 Evas_Object *obj EINA_UNUSED,
5855 Widget_Data *wd = elm_widget_data_get(data);
5856 Evas_Event_Mouse_Move *ev = event_info;
5857 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
5860 if (wd->drag_started) return;
5862 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
5863 dx = ev->cur.canvas.x - ev->prev.canvas.x;
5864 dy = ev->cur.canvas.y - ev->prev.canvas.y;
5867 if (adx < 0) adx = -dx;
5868 if (ady < 0) ady = -dy;
5869 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
5873 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
5874 wd->drag_started = EINA_TRUE;
5878 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
5879 wd->drag_started = EINA_TRUE;
5886 _size_cache_free(void *data)
5888 if (data) free(data);
5891 static Evas_Event_Flags
5892 _pinch_zoom_start_cb(void *data, void *event_info)
5894 Elm_Genlist_Data *sd = data;
5895 Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
5896 Elm_Object_Item *eo_it;
5898 eo_it = elm_genlist_at_xy_item_get(sd->obj, p->x, p->y, NULL);
5899 sd->g_item = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
5900 return EVAS_EVENT_FLAG_NONE;
5903 static Evas_Event_Flags
5904 _pinch_zoom_cb(void *data, void *event_info)
5906 Elm_Genlist_Data *sd = data;
5907 Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
5909 if (p->zoom > 1.0 + PINCH_ZOOM_TOLERANCE)
5910 sd->g_type = SIG_MULTI_PINCH_OUT;
5911 else if (p->zoom < 1.0 - PINCH_ZOOM_TOLERANCE)
5912 sd->g_type = SIG_MULTI_PINCH_IN;
5914 return EVAS_EVENT_FLAG_NONE;
5917 static Evas_Event_Flags
5918 _gesture_n_lines_start_cb(void *data , void *event_info)
5920 Elm_Genlist_Data *sd = data;
5921 Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5923 Elm_Object_Item *eo_it;
5925 x = (p->momentum.x1 + p->momentum.x2) / 2;
5926 y = (p->momentum.y1 + p->momentum.y2) / 2;
5928 eo_it = elm_genlist_at_xy_item_get(sd->obj, x, y, NULL);
5929 sd->g_item = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
5930 return EVAS_EVENT_FLAG_NONE;
5933 static Evas_Event_Flags
5934 _gesture_n_lines_cb(void *data , void *event_info)
5936 Elm_Genlist_Data *sd = data;
5937 Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5939 if (p->momentum.n < 2)
5940 return EVAS_EVENT_FLAG_NONE;
5942 Evas_Coord minw = 0, minh = 0;
5943 Evas_Coord x, y, off_x, off_y;
5944 Evas_Coord cur_x, cur_y, prev_x, prev_y;
5945 Elm_Gen_Item *down_it;
5946 Elm_Object_Item *eo_down_it;
5948 minw = sd->finger_minw;
5949 minh = sd->finger_minh;
5951 prev_x = prev_y = 0;
5953 cur_x = p->momentum.x1;
5954 cur_y = p->momentum.y1;
5956 eo_down_it = elm_genlist_at_xy_item_get(sd->obj, cur_x, cur_y, NULL);
5957 down_it = eo_data_scope_get(eo_down_it, ELM_GENLIST_ITEM_CLASS);
5960 evas_object_geometry_get(VIEW(down_it), &x, &y, NULL, NULL);
5961 prev_x = down_it->dx + x;
5962 prev_y = down_it->dy + y;
5964 off_x = abs(cur_x - prev_x);
5965 off_y = abs(cur_y - prev_y);
5967 if ((off_x > minw) || (off_y > minh))
5972 sd->g_type = SIG_MULTI_SWIPE_RIGHT;
5974 sd->g_type = SIG_MULTI_SWIPE_LEFT;
5979 sd->g_type = SIG_MULTI_SWIPE_DOWN;
5981 sd->g_type = SIG_MULTI_SWIPE_UP;
5985 return EVAS_EVENT_FLAG_NONE;
5988 static Evas_Event_Flags
5989 _gesture_n_flicks_cb(void *data , void *event_info)
5991 Elm_Genlist_Data *sd = data;
5992 Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5994 if (p->momentum.n == 1)
5995 sd->g_type = SIG_SWIPE;
5997 return EVAS_EVENT_FLAG_NONE;
6001 _elm_genlist_evas_object_smart_del(Eo *obj, Elm_Genlist_Data *sd)
6003 sd->no_cache = EINA_TRUE;
6004 elm_genlist_clear(obj);
6005 evas_event_callback_del_full(evas_object_evas_get(obj),
6006 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
6007 _evas_viewport_resize_cb, sd);
6008 if (sd->size_caches) eina_hash_free(sd->size_caches);
6009 if (sd->decorate_it_type) eina_stringshare_del(sd->decorate_it_type);
6011 evas_object_del(sd->pan_obj);
6012 eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
6016 _elm_genlist_evas_object_smart_move(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y)
6018 Evas_Coord ox, oy, bg_x, bg_y;
6020 if (!TIZEN_PROFILE_WEARABLE)
6022 evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
6023 evas_object_geometry_get(sd->banded_bg_rect, &bg_x, &bg_y, NULL, NULL);
6026 eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
6027 evas_object_move(sd->hit_rect, x, y);
6029 if (!TIZEN_PROFILE_WEARABLE)
6030 evas_object_move(sd->banded_bg_rect, (bg_x + x - ox), (bg_y + y - oy));
6034 _elm_genlist_evas_object_smart_resize(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord w, Evas_Coord h)
6036 eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
6038 evas_object_resize(sd->hit_rect, w, h);
6042 _elm_genlist_evas_object_smart_member_add(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *member)
6044 eo_do_super(obj, MY_CLASS, evas_obj_smart_member_add(member));
6047 evas_object_raise(sd->hit_rect);
6052 _elm_genlist_elm_widget_access(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool acs)
6055 Elm_Object_Item *eo_it;
6057 l = elm_genlist_realized_items_get(obj);
6059 EINA_LIST_FREE(l, eo_it)
6061 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6062 _item_unrealize(it, EINA_FALSE);
6065 sd->is_access = acs;
6067 _changed(sd->pan_obj);
6068 evas_object_smart_callback_call(obj, SIG_ACCESS_CHANGED, NULL);
6072 _evas_viewport_resize_cb(void *d, Evas *e EINA_UNUSED, void *ei EINA_UNUSED)
6074 Elm_Genlist_Data *priv = d;
6075 _changed(priv->pan_obj);
6079 _elm_genlist_evas_object_smart_add(Eo *obj, Elm_Genlist_Data *priv)
6081 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
6082 Evas_Coord minw, minh;
6083 Elm_Genlist_Pan_Data *pan_data;
6085 eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
6086 elm_widget_sub_object_parent_add(obj);
6088 priv->finger_minw = 0;
6089 priv->finger_minh = 0;
6090 elm_coords_finger_size_adjust(1, &priv->finger_minw, 1, &priv->finger_minh);
6092 priv->size_caches = eina_hash_string_small_new(_size_cache_free);
6093 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
6094 evas_object_smart_member_add(priv->hit_rect, obj);
6095 elm_widget_sub_object_add(obj, priv->hit_rect);
6097 /* common scroller hit rectangle setup */
6098 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
6099 evas_object_show(priv->hit_rect);
6100 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
6102 elm_widget_can_focus_set(obj, EINA_TRUE);
6103 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
6105 elm_layout_theme_set(obj, "genlist", "base", elm_widget_style_get(obj));
6107 if (!TIZEN_PROFILE_WEARABLE)
6108 _banded_bg_state_check(obj, priv);
6110 /* interface's add() routine issued AFTER the object's smart_add() */
6111 eo_do(obj, elm_interface_scrollable_objects_set(wd->resize_obj, priv->hit_rect));
6113 eo_do(obj, elm_interface_scrollable_bounce_allow_set
6114 (EINA_FALSE, _elm_config->thumbscroll_bounce_enable));
6115 priv->v_bounce = _elm_config->thumbscroll_bounce_enable;
6118 elm_interface_scrollable_animate_start_cb_set(_scroll_animate_start_cb),
6119 elm_interface_scrollable_animate_stop_cb_set(_scroll_animate_stop_cb),
6120 elm_interface_scrollable_scroll_cb_set(_scroll_cb),
6121 elm_interface_scrollable_drag_start_cb_set(_scroll_drag_start_cb),
6122 elm_interface_scrollable_drag_stop_cb_set(_scroll_drag_stop_cb),
6123 elm_interface_scrollable_edge_left_cb_set(_edge_left_cb),
6124 elm_interface_scrollable_edge_right_cb_set(_edge_right_cb),
6125 elm_interface_scrollable_edge_top_cb_set(_edge_top_cb),
6126 elm_interface_scrollable_edge_bottom_cb_set(_edge_bottom_cb),
6127 elm_interface_scrollable_vbar_drag_cb_set(_vbar_drag_cb),
6128 elm_interface_scrollable_vbar_press_cb_set(_vbar_press_cb),
6129 elm_interface_scrollable_vbar_unpress_cb_set(_vbar_unpress_cb),
6130 elm_interface_scrollable_hbar_drag_cb_set(_hbar_drag_cb),
6131 elm_interface_scrollable_hbar_press_cb_set(_hbar_press_cb),
6132 elm_interface_scrollable_hbar_unpress_cb_set(_hbar_unpress_cb));
6134 eo_do(obj, elm_interface_scrollable_content_min_limit_cb_set(_elm_genlist_content_min_limit_cb));
6136 priv->mode = ELM_LIST_SCROLL;
6137 priv->max_items_per_block = MAX_ITEMS_PER_BLOCK;
6138 priv->item_cache_max = priv->max_items_per_block * 2;
6139 priv->longpress_timeout = _elm_config->longpress_timeout;
6140 priv->highlight = EINA_TRUE;
6141 priv->fx_mode = EINA_FALSE;
6142 priv->on_hold = EINA_FALSE;
6145 if (!TIZEN_PROFILE_WEARABLE)
6146 priv->top_drawn_item = NULL;
6148 priv->pan_obj = eo_add(MY_PAN_CLASS, evas_object_evas_get(obj));
6149 pan_data = eo_data_scope_get(priv->pan_obj, MY_PAN_CLASS);
6150 eo_data_ref(obj, NULL);
6152 pan_data->wobj = obj;
6154 pan_data->wsd = priv;
6157 // FIXME: difference from upstream
6158 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_DOWN,
6159 _mouse_down_scroller, obj);
6160 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_UP,
6161 _mouse_up_scroller, obj);
6162 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_MOVE,
6163 _mouse_move_scroller, obj);
6166 eo_do(obj, elm_interface_scrollable_extern_pan_set(priv->pan_obj));
6168 edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
6169 evas_object_size_hint_min_set(obj, minw, minh);
6171 _item_cache_all_free(priv);
6172 _mirrored_set(obj, elm_widget_mirrored_get(obj));
6174 const char *str = edje_object_data_get(wd->resize_obj,
6176 if ((str) && (!strcmp(str, "on")))
6177 elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
6179 elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
6180 priv->select_on_focus_enabled = EINA_FALSE;
6181 elm_widget_signal_callback_add(obj, "elm,action,focus_highlight,hide", "elm", _elm_genlist_focus_highlight_hide, obj);
6182 elm_widget_signal_callback_add(obj, "elm,action,focus_highlight,show", "elm", _elm_genlist_focus_highlight_show, obj);
6183 evas_event_callback_add(evas_object_evas_get(obj),
6184 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
6185 _evas_viewport_resize_cb, priv);
6187 priv->g_layer = elm_gesture_layer_add(obj);
6188 if (!priv->g_layer) ERR("elm_gesture_layer_add() failed");
6189 elm_gesture_layer_attach(priv->g_layer, priv->hit_rect);
6190 elm_gesture_layer_cb_set
6191 (priv->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_START,
6192 _pinch_zoom_start_cb, priv);
6193 elm_gesture_layer_cb_set
6194 (priv->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE,
6195 _pinch_zoom_cb, priv);
6197 elm_gesture_layer_cb_set
6198 (priv->g_layer, ELM_GESTURE_N_LINES, ELM_GESTURE_STATE_START,
6199 _gesture_n_lines_start_cb, priv);
6200 elm_gesture_layer_cb_set
6201 (priv->g_layer, ELM_GESTURE_N_LINES, ELM_GESTURE_STATE_MOVE,
6202 _gesture_n_lines_cb, priv);
6204 elm_gesture_layer_cb_set
6205 (priv->g_layer, ELM_GESTURE_N_FLICKS, ELM_GESTURE_STATE_START,
6206 _gesture_n_lines_start_cb, priv);
6207 elm_gesture_layer_cb_set
6208 (priv->g_layer, ELM_GESTURE_N_FLICKS, ELM_GESTURE_STATE_MOVE,
6209 _gesture_n_flicks_cb, priv);
6211 elm_layout_sizing_eval(obj);
6213 // TIZEN_ONLY(20150705): Genlist item align feature
6214 wd->scroll_item_align_enable = _elm_config->scroll_item_align_enable;
6215 wd->scroll_item_valign = _elm_config->scroll_item_valign;
6217 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
6218 (NULL, NULL, &priv->viewport_w, &priv->viewport_h));
6221 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
6222 //register/unregister access objects accordingly.
6223 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6225 _elm_genlist_elm_widget_screen_reader(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool is_screen_reader)
6228 Eina_Bool done = EINA_FALSE;
6229 Evas_Object *content = NULL;
6233 EINA_INLIST_FOREACH(sd->blocks, itb)
6238 EINA_LIST_FOREACH(itb->items, l, it)
6240 if (!it->realized || it->want_hidden) continue;
6241 if (is_screen_reader)
6243 elm_interface_atspi_accessible_added(EO_OBJ(it));
6244 elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
6245 EINA_LIST_FOREACH(it->content_objs, ll, content)
6247 if (eo_isa(content, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
6249 eo_do(content, elm_interface_atspi_accessible_parent_set(EO_OBJ(it)));
6250 elm_interface_atspi_accessible_children_changed_added_signal_emit(EO_OBJ(it), content);
6253 elm_interface_atspi_accessible_name_changed_signal_emit(EO_OBJ(it));
6257 elm_interface_atspi_accessible_removed(EO_OBJ(it));
6258 elm_interface_atspi_accessible_children_changed_del_signal_emit(sd->obj, EO_OBJ(it));
6262 else if (done) break;
6265 //TIZEN_ONLY(20161213): apply screen_reader_changed callback
6266 evas_object_smart_callback_call(obj, SIG_ATSPI_SCREEN_READER_CHANGED, &is_screen_reader);
6272 EOLIAN const Elm_Atspi_Action *
6273 _elm_genlist_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd EINA_UNUSED)
6275 /* Need to be implemented
6276 static Elm_Atspi_Action atspi_actions[] = {
6277 { "move,prior", "move", "prior", _key_action_move},
6278 { "move,next", "move", "next", _key_action_move},
6279 { "move,left", "move", "left", _key_action_move},
6280 { "move,right", "move", "right", _key_action_move},
6281 { "move,up", "move", "up", _key_action_move},
6282 { "move,up,multi", "move", "up_multi", _key_action_move},
6283 { "move,down", "move", "down", _key_action_move},
6284 { "move,down,multi", "move", "down_multi", _key_action_move},
6285 { "move,first", "move", "first", _key_action_move},
6286 { "move,last", "move", "last", _key_action_move},
6287 { "select", "select", NULL, _key_action_select},
6288 { "select,multi", "select", "multi", _key_action_select},
6289 { "escape", "escape", NULL, _key_action_escape},
6290 { NULL, NULL, NULL, NULL }
6292 return &atspi_actions[0];
6294 static Elm_Atspi_Action atspi_actions[] = {{NULL, NULL, NULL, NULL}};
6295 return &atspi_actions[0];
6299 elm_genlist_add(Evas_Object *parent)
6301 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
6302 Evas_Object *obj = eo_add(MY_CLASS, parent);
6307 _elm_genlist_eo_base_constructor(Eo *obj, Elm_Genlist_Data *sd)
6309 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
6313 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
6314 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
6315 elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST));
6320 EOLIAN static Evas_Object *
6321 _elm_genlist_item_elm_widget_item_part_content_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6323 Evas_Object *ret = NULL;
6324 if (it->deco_all_view)
6325 ret = edje_object_part_swallow_get(it->deco_all_view, part);
6326 else if (it->decorate_it_set)
6327 ret = edje_object_part_swallow_get(GL_IT(it)->deco_it_view, part);
6329 ret = edje_object_part_swallow_get(VIEW(it), part);
6333 EOLIAN static const char *
6334 _elm_genlist_item_elm_widget_item_part_text_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6336 if (!it->itc->func.text_get) return NULL;
6337 const char *ret = NULL;
6338 if (it->deco_all_view)
6339 ret = edje_object_part_text_get(it->deco_all_view, part);
6340 else if (it->decorate_it_set)
6341 ret = edje_object_part_text_get(GL_IT(it)->deco_it_view, part);
6343 ret = edje_object_part_text_get(VIEW(it), part);
6348 _elm_genlist_item_elm_widget_item_disable(Eo *eo_it, Elm_Gen_Item *it)
6355 if (it == GL_IT(it)->wsd->focused_item) elm_object_item_focus_set(EO_OBJ(it), EINA_FALSE);
6356 if (GL_IT(it)->highlight_timer)
6358 ecore_timer_del(GL_IT(it)->highlight_timer);
6359 GL_IT(it)->highlight_timer = NULL;
6363 ecore_timer_del(it->long_timer);
6364 it->long_timer = NULL;
6369 if (eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get()))
6371 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
6372 if (it->deco_all_view)
6373 edje_object_signal_emit
6374 (it->deco_all_view, SIGNAL_DISABLED, "elm");
6378 edje_object_signal_emit(VIEW(it), SIGNAL_ENABLED, "elm");
6379 if (it->deco_all_view)
6380 edje_object_signal_emit
6381 (it->deco_all_view, SIGNAL_ENABLED, "elm");
6383 EINA_LIST_FOREACH(it->content_objs, l, obj)
6384 elm_widget_disabled_set(obj, eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get()));
6389 _item_free(Elm_Gen_Item *it)
6392 Elm_Object_Item *eo_it2;
6393 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
6394 sd->processed_sizes -= GL_IT(it)->minh;
6395 if (sd->processed_sizes < 0) sd->processed_sizes = 0;
6397 eo_do(EO_OBJ(it), elm_wdg_item_pre_notify_del());
6398 if (it->tooltip.del_cb)
6399 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6401 #ifdef GENLIST_FX_SUPPORT
6402 sd->del_fx.items = eina_list_remove(sd->del_fx.items, it);
6403 sd->del_fx.pending_items = eina_list_remove(sd->del_fx.pending_items, it);
6404 sd->add_fx.items = eina_list_remove(sd->add_fx.items, it);
6408 GL_IT(it)->rel->item->rel_revs =
6409 eina_list_remove(GL_IT(it)->rel->item->rel_revs, it);
6410 if (GL_IT(it)->rel_revs)
6413 EINA_LIST_FREE(GL_IT(it)->rel_revs, tmp)
6415 if (tmp->item->queued && !(tmp->base)->on_deletion)
6417 GL_IT(tmp)->queued = EINA_FALSE;
6418 GL_IT(tmp)->resized = EINA_FALSE;
6419 sd->queue = eina_list_remove(sd->queue, tmp);
6420 _item_process(sd, tmp);
6422 tmp->item->rel = NULL;
6425 EINA_LIST_FOREACH_SAFE(it->item->items, l, ll, eo_it2)
6427 //elm_widget_item_del(it2);
6428 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6431 sd->reorder.move_items = eina_list_remove(sd->reorder.move_items, it);
6433 if (GL_IT(it)->block) _item_block_del(it);
6435 it->parent->item->items =
6436 eina_list_remove(it->parent->item->items, EO_OBJ(it));
6437 if (GL_IT(it)->queued)
6439 GL_IT(it)->queued = EINA_FALSE;
6440 sd->queue = eina_list_remove(sd->queue, it);
6442 if (sd->filter_queue && !it->filtered)
6444 l = eina_list_data_find_list(sd->filter_queue, it);
6445 if (l) sd->filter_queue = eina_list_remove_list(sd->filter_queue, l);
6447 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6448 sd->group_items = eina_list_remove(sd->group_items, it);
6452 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
6453 it->selected = EINA_FALSE;
6455 if (sd->show_item == it) sd->show_item = NULL;
6457 if ((sd->g_item) && (sd->g_item == it)) sd->g_item = NULL;
6458 if (sd->expanded_item == it) sd->expanded_item = NULL;
6459 if (sd->state) ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
6461 if (sd->last_selected_item == EO_OBJ(it))
6462 sd->last_selected_item = NULL;
6464 if (sd->realization_mode)
6467 EINA_LIST_FOREACH(GL_IT(it)->flip_content_objs, l, c)
6469 evas_object_event_callback_del_full(c,
6470 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6471 _changed_size_hints, it);
6473 EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, c)
6475 evas_object_event_callback_del_full(c,
6476 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6477 _changed_size_hints, it);
6479 EINA_LIST_FOREACH(it->content_objs, l, c)
6481 evas_object_event_callback_del_full(c,
6482 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6483 _changed_size_hints, it);
6487 if (sd->mode_item) sd->mode_item = NULL;
6488 if (it->selected) _item_unselect(it);
6489 if (it == sd->focused_item)
6493 if (!elm_widget_focus_get(WIDGET(it))) goto failed;
6495 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6496 find = _item_focusable_search(&tmp, 1);
6499 elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
6504 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6505 find = _item_focusable_search(&tmp, -1);
6508 elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
6513 elm_object_item_focus_set(EO_OBJ(it), EINA_FALSE);
6514 sd->focused_item = NULL;
6517 if (it == sd->key_down_item) sd->key_down_item = NULL;
6518 if (it == sd->highlighted_item) sd->highlighted_item = NULL;
6519 if (!TIZEN_PROFILE_WEARABLE)
6521 if (it == sd->top_drawn_item) sd->top_drawn_item = NULL;
6524 _item_unrealize(it, EINA_FALSE);
6526 if (sd->aligned_item == it) sd->aligned_item = NULL;
6528 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
6531 if (it->item->proxy)
6533 evas_object_smart_member_del(it->item->proxy);
6534 evas_object_del(it->item->proxy);
6537 if (it->itc->func.del)
6538 it->itc->func.del((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it));
6540 if (it->itc->refcount <= 1)
6544 EINA_INLIST_FOREACH_SAFE(sd->item_cache, l2, ic)
6546 if (it->itc == ic->item_class)
6547 _item_cache_free(sd, ic);
6551 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
6556 // TIZEN_ONLY(20150703) : banded color background feature. enabled only un-scrollable
6557 if (!TIZEN_PROFILE_WEARABLE)
6559 if (sd->banded_bg_rect && !sd->items)
6561 evas_object_smart_member_del(sd->banded_bg_rect);
6562 ELM_SAFE_FREE(sd->banded_bg_rect, evas_object_del);
6566 _changed(sd->pan_obj);
6569 EOLIAN static Eina_Bool
6570 _elm_genlist_item_elm_widget_item_del_pre(Eo *eo_it EINA_UNUSED,
6573 #ifdef GENLIST_FX_SUPPORT
6574 Elm_Genlist_Data *sd = it->item->wsd;
6575 Evas_Coord cvx, cvy, cvw, cvh;
6582 #ifdef GENLIST_FX_SUPPORT
6585 sd->add_fx.items = eina_list_remove(sd->add_fx.items, it);
6588 evas_output_viewport_get(evas_object_evas_get(sd->obj),
6589 &cvx, &cvy, &cvw, &cvh);
6590 if (!ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
6591 GL_IT(it)->w, GL_IT(it)->h,
6592 cvx, cvy, cvw, cvh))
6594 // Delete later, Above items in the viewport
6595 // Delete right now, below items in the viewport
6596 if (it->item->scrl_y < cvy)
6597 sd->del_fx.pending_items = eina_list_append(sd->del_fx.pending_items, it);
6601 _changed(sd->pan_obj);
6607 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
6608 else if (it->item->deco_it_view) evas_object_lower(it->item->deco_it_view);
6609 else if (VIEW(it)) evas_object_lower(VIEW(it));
6611 if (it->item->expanded_depth > 0)
6614 Elm_Object_Item *itt;
6615 EINA_LIST_FOREACH(it->item->items, l, itt)
6617 eo_do(itt, elm_wdg_item_del());
6620 sd->del_fx.items = eina_list_append(sd->del_fx.items, it);
6622 if (!sd->del_fx.anim)
6624 sd->del_fx.cnt = ANIM_CNT_MAX;
6625 sd->del_fx.anim = ecore_animator_add(_del_fx_anim, sd);
6627 _changed(sd->pan_obj);
6633 _elm_genlist_item_elm_widget_item_signal_emit(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char *emission, const char *source)
6637 WRN("item is not realized yet");
6640 edje_object_signal_emit
6641 (VIEW(it), emission, source);
6642 if (it->deco_all_view)
6643 edje_object_signal_emit
6644 (it->deco_all_view, emission, source);
6648 _elm_genlist_item_eo_base_constructor(Eo *eo_it, Elm_Gen_Item *it)
6650 eo_it = eo_do_super_ret(eo_it, ELM_GENLIST_ITEM_CLASS, eo_it, eo_constructor());
6652 it->base = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
6653 eo_do(eo_it, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST_ITEM));
6657 static Elm_Gen_Item *
6658 _elm_genlist_item_new(Elm_Genlist_Data *sd,
6659 const Elm_Genlist_Item_Class *itc,
6661 Elm_Object_Item *eo_parent,
6662 Elm_Genlist_Item_Type type,
6664 const void *func_data)
6669 if (!itc) return NULL;
6671 Eo *eo_it = eo_add(ELM_GENLIST_ITEM_CLASS, sd->obj);
6672 if (!eo_it) return NULL;
6673 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6676 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
6678 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6679 WIDGET_ITEM_DATA_SET(EO_OBJ(it), data);
6680 it->parent = parent;
6681 it->func.func = func;
6682 it->func.data = func_data;
6684 GL_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
6685 GL_IT(it)->wsd = sd;
6686 GL_IT(it)->type = type;
6690 if (GL_IT(it->parent)->type == ELM_GENLIST_ITEM_GROUP)
6691 GL_IT(it)->group_item = parent;
6692 else if (GL_IT(it->parent)->group_item)
6693 GL_IT(it)->group_item = GL_IT(it->parent)->group_item;
6695 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
6697 if (GL_IT(it2->parent)->type == ELM_GENLIST_ITEM_TREE) depth += 1;
6699 GL_IT(it)->expanded_depth = depth;
6706 _elm_genlist_item_compare(const void *data,
6709 const Elm_Gen_Item *it, *item1;
6711 it = ELM_GEN_ITEM_FROM_INLIST(data);
6712 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
6713 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6717 _elm_genlist_item_list_compare(const void *data,
6720 const Elm_Gen_Item *it = data;
6721 const Elm_Gen_Item *item1 = data1;
6723 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6726 EOLIAN static unsigned int
6727 _elm_genlist_items_count(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6729 return sd->item_count;
6733 _list_last_recursive(Eina_List *list)
6735 Eina_List *ll, *ll2;
6736 Elm_Object_Item *eo_it2;
6738 ll = eina_list_last(list);
6739 if (!ll) return NULL;
6742 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6744 if (it2->item->items)
6746 ll2 = _list_last_recursive(it2->item->items);
6756 EOLIAN static Elm_Object_Item*
6757 _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)
6761 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6765 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6766 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6767 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6770 it = _elm_genlist_item_new
6771 (sd, itc, data, eo_parent, type, func, func_data);
6772 if (!it) return NULL;
6776 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6777 sd->group_items = eina_list_append(sd->group_items, it);
6778 sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
6779 GL_IT(it)->rel = NULL;
6783 Elm_Object_Item *eo_it2 = NULL;
6784 Eina_List *ll = _list_last_recursive(it->parent->item->items);
6786 if (ll) eo_it2 = ll->data;
6787 it->parent->item->items =
6788 eina_list_append(it->parent->item->items, EO_OBJ(it));
6789 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6790 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6791 sd->items = eina_inlist_append_relative
6792 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6793 GL_IT(it)->rel = it2;
6794 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6796 GL_IT(it)->before = EINA_FALSE;
6797 _item_queue_direct(it, NULL);
6801 EOLIAN static Elm_Object_Item*
6802 _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)
6804 Elm_Gen_Item *it = NULL;
6806 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6809 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6810 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6811 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6812 /* first sub-item should allways be appended */
6813 if (!parent->item->items)
6814 return _elm_genlist_item_append(obj, sd, itc, data, eo_parent, type, func, func_data);
6816 it = _elm_genlist_item_new
6817 (sd, itc, data, eo_parent, type, func, func_data);
6819 if (!it) return NULL;
6821 if (sd->items) GL_IT(it)->is_prepend = EINA_TRUE;
6824 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6825 sd->group_items = eina_list_prepend(sd->group_items, it);
6826 sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
6827 GL_IT(it)->rel = NULL;
6831 Elm_Object_Item *eo_it2 = NULL;
6832 Eina_List *ll = it->parent->item->items;
6834 if (ll) eo_it2 = ll->data;
6835 it->parent->item->items =
6836 eina_list_prepend(it->parent->item->items, EO_OBJ(it));
6837 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6838 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6841 sd->items = eina_inlist_prepend_relative
6842 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6843 GL_IT(it)->rel = it2;
6844 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6847 GL_IT(it)->before = EINA_TRUE;
6848 _item_queue_direct(it, NULL);
6852 EOLIAN static Elm_Object_Item*
6853 _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)
6855 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_after, NULL);
6856 ELM_GENLIST_ITEM_DATA_GET(eo_after, after_it);
6859 ELM_GENLIST_ITEM_CHECK_OR_RETURN(after_it, NULL);
6860 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(after_it), NULL);
6863 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6864 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6865 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6868 /* It makes no sense to insert after in an empty list with after !=
6869 * NULL, something really bad is happening in your app. */
6870 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6872 it = _elm_genlist_item_new
6873 (sd, itc, data, eo_parent, type, func, func_data);
6874 if (!it) return NULL;
6878 if ((GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) &&
6879 (GL_IT(after_it)->type == ELM_GENLIST_ITEM_GROUP))
6880 sd->group_items = eina_list_append_relative
6881 (sd->group_items, it, after_it);
6885 it->parent->item->items =
6886 eina_list_append_relative(it->parent->item->items, EO_OBJ(it), eo_after);
6888 sd->items = eina_inlist_append_relative
6889 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after_it));
6891 GL_IT(it)->rel = after_it;
6892 after_it->item->rel_revs = eina_list_append(after_it->item->rel_revs, it);
6893 GL_IT(it)->before = EINA_FALSE;
6894 _item_queue_direct(it, NULL);
6896 if (elm_genlist_item_next_get(eo_after) == EO_OBJ(sd->aligned_item))
6897 sd->aligned_item = NULL;
6901 EOLIAN static Elm_Object_Item*
6902 _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)
6904 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_before, NULL);
6905 ELM_GENLIST_ITEM_DATA_GET(eo_before, before_it);
6908 ELM_GENLIST_ITEM_CHECK_OR_RETURN(before_it, NULL);
6909 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(before_it), NULL);
6912 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6913 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6914 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6917 /* It makes no sense to insert before in an empty list with before
6918 * != NULL, something really bad is happening in your app. */
6919 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6921 it = _elm_genlist_item_new
6922 (sd, itc, data, eo_parent, type, func, func_data);
6923 if (!it) return NULL;
6927 if ((GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) &&
6928 (GL_IT(before_it)->type == ELM_GENLIST_ITEM_GROUP))
6930 eina_list_prepend_relative(sd->group_items, it, before_it);
6934 it->parent->item->items =
6935 eina_list_prepend_relative(it->parent->item->items, EO_OBJ(it), eo_before);
6937 sd->items = eina_inlist_prepend_relative
6938 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before_it));
6940 GL_IT(it)->rel = before_it;
6941 before_it->item->rel_revs = eina_list_append(before_it->item->rel_revs, it);
6942 GL_IT(it)->before = EINA_TRUE;
6943 _item_queue_direct(it, NULL);
6945 if (before_it == sd->aligned_item)
6946 sd->aligned_item = NULL;
6951 EOLIAN static Elm_Object_Item*
6952 _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)
6954 Elm_Gen_Item *rel = NULL;
6956 Elm_Object_Item *eo_it;
6960 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6961 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6962 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6965 it = _elm_genlist_item_new
6966 (sd, itc, data, eo_parent, type, func, func_data);
6967 if (!it) return NULL;
6970 sd->item_compare_cb = comp;
6974 Elm_Object_Item *eo_rel = NULL;
6978 l = eina_list_search_sorted_near_list
6979 (it->parent->item->items, _elm_genlist_item_list_compare, eo_it,
6984 eo_rel = eina_list_data_get(l);
6985 rel = eo_data_scope_get(eo_rel, ELM_GENLIST_ITEM_CLASS);
6987 if (cmp_result >= 0)
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_TRUE;
6995 else if (cmp_result < 0)
6997 it->parent->item->items = eina_list_append_relative_list
6998 (it->parent->item->items, eo_it, l);
6999 sd->items = eina_inlist_append_relative
7000 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
7001 it->item->before = EINA_FALSE;
7002 it->item->is_prepend = EINA_TRUE;
7009 // ignoring the comparison
7010 it->parent->item->items = eina_list_prepend_relative_list
7011 (it->parent->item->items, eo_it, l);
7012 sd->items = eina_inlist_prepend_relative
7013 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
7014 it->item->before = EINA_FALSE;
7021 sd->state = eina_inlist_sorted_state_new();
7022 eina_inlist_sorted_state_init(sd->state, sd->items);
7023 sd->requeued = EINA_FALSE;
7026 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
7027 sd->group_items = eina_list_append(sd->group_items, it);
7029 sd->items = eina_inlist_sorted_state_insert
7030 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
7033 if (EINA_INLIST_GET(it)->next)
7035 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
7036 GL_IT(it)->before = EINA_TRUE;
7037 GL_IT(it)->is_prepend = EINA_TRUE;
7039 else if (EINA_INLIST_GET(it)->prev)
7041 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7042 GL_IT(it)->before = EINA_FALSE;
7048 GL_IT(it)->rel = rel;
7049 rel->item->rel_revs = eina_list_append(rel->item->rel_revs, it);
7052 _item_queue_direct(it, _elm_genlist_item_list_compare);
7057 _elm_genlist_clear(Eo *obj, Elm_Genlist_Data *sd)
7061 eina_hash_free_buckets(sd->size_caches);
7062 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
7063 if (sd->key_down_item) sd->key_down_item = NULL;
7064 if (sd->mode_item) sd->mode_item = NULL;
7068 eina_inlist_sorted_state_free(sd->state);
7072 sd->filter_data = NULL;
7073 if (sd->filter_queue)
7074 ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
7075 ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
7076 ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
7078 // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
7079 // because sd->items can be modified inside elm_widget_item_del()
7082 it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
7083 //elm_widget_item_del(it);
7086 sd->reorder.it = NULL;
7087 sd->reorder.dir = 0;
7088 eina_list_free(sd->reorder.move_items);
7092 _item_cache_all_free(sd);
7096 sd->selected = eina_list_free(sd->selected);
7097 sd->selected = NULL;
7100 sd->show_item = NULL;
7109 evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
7110 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
7112 elm_layout_sizing_eval(obj);
7114 eo_do(sd->obj, elm_interface_scrollable_content_region_show(0, 0, 0, 0));
7118 ecore_job_del(sd->dummy_job);
7119 sd->dummy_job = NULL;
7121 if (sd->queue_idle_enterer)
7123 ecore_idle_enterer_del(sd->queue_idle_enterer);
7124 sd->queue_idle_enterer = NULL;
7126 if (sd->scr_hold_timer)
7128 ecore_timer_del(sd->scr_hold_timer);
7129 sd->scr_hold_timer = NULL;
7131 if (sd->reorder.anim)
7133 ecore_animator_del(sd->reorder.anim);
7134 sd->reorder.anim = NULL;
7138 ecore_timer_del(sd->scr_timer);
7139 sd->scr_timer = NULL;
7141 #ifdef GENLIST_FX_SUPPORT
7142 if (sd->del_fx.anim)
7144 ecore_animator_del(sd->del_fx.anim);
7145 sd->del_fx.anim = NULL;
7147 if (sd->add_fx.anim)
7149 ecore_animator_del(sd->add_fx.anim);
7150 sd->add_fx.anim = NULL;
7154 if (sd->queue) sd->queue = eina_list_free(sd->queue);
7155 if (sd->g_item) sd->g_item = NULL;
7156 if (sd->g_type) sd->g_type = NULL;
7158 if (!TIZEN_PROFILE_WEARABLE)
7160 if (sd->banded_bg_rect)
7162 evas_object_smart_member_del(sd->banded_bg_rect);
7163 ELM_SAFE_FREE(sd->banded_bg_rect, evas_object_del);
7169 _elm_genlist_multi_select_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool multi)
7171 sd->multi = !!multi;
7172 if (!sd->multi && sd->selected)
7175 Elm_Object_Item *eo_it;
7176 Elm_Object_Item *last = sd->selected->data;
7177 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
7180 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
7186 EOLIAN static Eina_Bool
7187 _elm_genlist_multi_select_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7193 _elm_genlist_multi_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Elm_Object_Multi_Select_Mode mode EINA_UNUSED)
7195 /* Need to be implemented
7196 if (mode >= ELM_OBJECT_MULTI_SELECT_MODE_MAX)
7199 if (sd->multi_select_mode != mode)
7200 sd->multi_select_mode = mode;
7205 EOLIAN static Elm_Object_Multi_Select_Mode
7206 _elm_genlist_multi_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
7208 // Need to be implemented
7209 //return sd->multi_select_mode;
7210 return ELM_OBJECT_MULTI_SELECT_MODE_DEFAULT;
7213 EOLIAN static Elm_Object_Item*
7214 _elm_genlist_selected_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7217 return sd->selected->data;
7222 EOLIAN static const Eina_List*
7223 _elm_genlist_selected_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7225 return sd->selected;
7228 EOLIAN static Eina_List*
7229 _elm_genlist_realized_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7232 Eina_List *list = NULL;
7233 Eina_Bool done = EINA_FALSE;
7235 EINA_INLIST_FOREACH(sd->blocks, itb)
7243 EINA_LIST_FOREACH(itb->items, l, it)
7245 if (it->realized) list = eina_list_append(list, EO_OBJ(it));
7256 EOLIAN static Elm_Object_Item *
7257 _elm_genlist_search_by_text_item_get(Eo *obj EINA_UNUSED,
7258 Elm_Genlist_Data *sd,
7259 Elm_Object_Item *item_to_search_from,
7260 const char *part_name,
7261 const char *pattern,
7262 Elm_Glob_Match_Flags flags)
7264 Elm_Gen_Item *it = NULL;
7266 Eina_Inlist *start = NULL;
7269 if (!pattern) return NULL;
7270 if (!sd->items) return NULL;
7272 if (flags & ELM_GLOB_MATCH_NO_ESCAPE) fnflags |= FNM_NOESCAPE;
7273 if (flags & ELM_GLOB_MATCH_PATH) fnflags |= FNM_PATHNAME;
7274 if (flags & ELM_GLOB_MATCH_PERIOD) fnflags |= FNM_PERIOD;
7276 if (flags & ELM_GLOB_MATCH_NOCASE) fnflags |= FNM_CASEFOLD;
7279 start = (item_to_search_from) ?
7280 EINA_INLIST_GET((Elm_Gen_Item *)eo_data_scope_get(item_to_search_from, ELM_GENLIST_ITEM_CLASS)) :
7282 EINA_INLIST_FOREACH(start, it)
7284 if (!it->itc->func.text_get) continue;
7285 str = it->itc->func.text_get((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), part_name);
7287 if (!fnmatch(pattern, str, fnflags))
7297 EOLIAN static Elm_Object_Item*
7298 _elm_genlist_at_xy_item_get(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y, int *posret)
7300 Evas_Coord ox, oy, ow, oh;
7304 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7306 EINA_INLIST_FOREACH(sd->blocks, itb)
7310 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->sd->pan_x,
7311 oy + itb->y - itb->sd->pan_y,
7312 sd->minw, itb->minh, x, y, 1, 1))
7314 EINA_LIST_FOREACH(itb->items, l, it)
7316 Evas_Coord itx, ity;
7318 itx = ox + itb->x + it->x - itb->sd->pan_x;
7319 ity = oy + itb->y + it->y - itb->sd->pan_y;
7320 if (ELM_RECTS_INTERSECT
7321 (itx, ity, GL_IT(it)->w, GL_IT(it)->h, x, y, 1, 1))
7325 if (y <= (ity + (GL_IT(it)->h / 4))) *posret = -1;
7326 else if (y >= (ity + GL_IT(it)->h - (GL_IT(it)->h / 4)))
7333 lasty = ity + GL_IT(it)->h;
7338 if (y > lasty) *posret = 1;
7345 EOLIAN static Elm_Object_Item*
7346 _elm_genlist_first_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7348 Elm_Gen_Item *tit, *it = NULL;
7350 EINA_INLIST_REVERSE_FOREACH(sd->items, tit) it = tit;
7355 EOLIAN static Elm_Object_Item*
7356 _elm_genlist_last_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7360 if (!sd->items) return NULL;
7362 it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
7366 EOLIAN static Elm_Object_Item *
7367 _elm_genlist_item_next_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7371 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
7375 if (it) return EO_OBJ(it);
7379 EOLIAN static Elm_Object_Item *
7380 _elm_genlist_item_prev_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7384 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7388 if (it) return EO_OBJ(it);
7392 EOLIAN static Elm_Object_Item *
7393 _elm_genlist_item_parent_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7395 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
7397 return EO_OBJ(it->parent);
7400 EOLIAN static unsigned int
7401 _elm_genlist_item_subitems_count(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
7403 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, 0);
7405 return eina_list_count(item->item->items);
7408 EOLIAN static const Eina_List *
7409 _elm_genlist_item_subitems_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
7411 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
7413 return item->item->items;
7417 _elm_genlist_item_subitems_clear(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7419 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7421 Elm_Object_Item *eo_it2;
7423 EINA_LIST_FOREACH_SAFE(GL_IT(it)->items, l, ll, eo_it2)
7424 eo_do(eo_it2, elm_wdg_item_del());
7428 _elm_genlist_item_selected_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
7431 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7434 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get())) return;
7435 // FIXME: This API has highlight/unhighlith feature also..
7437 if (selected) _item_highlight(it);
7438 else _item_unhighlight(it, EINA_TRUE);
7440 selected = !!selected;
7441 if (it->selected == selected) return;
7443 if (selected) _item_select(it);
7444 else _item_unselect(it);
7447 EOLIAN static Eina_Bool
7448 _elm_genlist_item_selected_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7450 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7452 return it->selected;
7456 _elm_genlist_item_expanded_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool expanded)
7458 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7460 expanded = !!expanded;
7461 if (GL_IT(it)->expanded == expanded) return;
7462 if (GL_IT(it)->type != ELM_GENLIST_ITEM_TREE) return;
7463 GL_IT(it)->expanded = expanded;
7464 GL_IT(it)->wsd->expanded_item = it;
7466 if (GL_IT(it)->expanded)
7469 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
7470 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, EO_OBJ(it));
7471 if (_elm_atspi_enabled())
7472 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_item);
7477 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACTED, "elm");
7478 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, EO_OBJ(it));
7479 if (_elm_atspi_enabled())
7480 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_item);
7484 EOLIAN static Eina_Bool
7485 _elm_genlist_item_expanded_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7487 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7489 return GL_IT(it)->expanded;
7493 _elm_genlist_item_expanded_depth_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7495 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, 0);
7497 return GL_IT(it)->expanded_depth;
7501 _elm_genlist_item_promote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7503 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7505 Elm_Object_Item *eo_first_item = elm_genlist_first_item_get(WIDGET(it));
7506 ELM_GENLIST_ITEM_DATA_GET(eo_first_item, first_item);
7507 _item_move_before(it, first_item);
7511 _elm_genlist_item_demote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7513 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7514 Elm_Object_Item *eo_last_item = elm_genlist_last_item_get(WIDGET(it));
7515 ELM_GENLIST_ITEM_DATA_GET(eo_last_item, last_item);
7516 _item_move_after(it, last_item);
7520 _elm_genlist_item_show(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
7522 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7524 if (it->want_hidden)
7526 WRN("Filter hided item cannot move to show");
7530 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7532 sd->bring_in = EINA_FALSE;
7533 sd->scroll_to_type = type;
7534 _changed(sd->pan_obj);
7538 _elm_genlist_item_bring_in(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
7540 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7542 if (it->want_hidden)
7544 WRN("Filter hided item cannot move to bring in");
7548 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7549 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wd);
7550 sd->bring_in = EINA_TRUE;
7551 sd->scroll_to_type = type;
7553 if (wd->scroll_item_align_enable)
7555 it = _adjust_item_align(it);
7556 sd->adjusted_item = sd->show_item = it;
7558 if (sd->aligned_item && sd->show_item != sd->aligned_item)
7559 edje_object_signal_emit(VIEW(sd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
7564 _changed(sd->pan_obj);
7568 _elm_genlist_item_all_contents_unset(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_List **l)
7570 Evas_Object *content;
7572 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7574 EINA_LIST_FREE (it->content_objs, content)
7576 evas_object_smart_member_del(content);
7577 // edje can be reused by item caching,
7578 // content should be un-swallowed from edje
7579 edje_object_part_unswallow(VIEW(it), content);
7580 evas_object_hide(content);
7581 if (l) *l = eina_list_append(*l, content);
7586 _elm_genlist_item_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7588 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7590 if (!GL_IT(it)->block) return;
7592 GL_IT(it)->updateme = EINA_TRUE;
7593 GL_IT(it)->block->calc_done = EINA_FALSE;
7594 GL_IT(it)->wsd->calc_done = EINA_FALSE;
7595 _changed(GL_IT(it)->wsd->pan_obj);
7599 _elm_genlist_item_fields_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
7601 Elm_Genlist_Item_Field_Type itf)
7603 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7605 if (!GL_IT(it)->block) return;
7607 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
7609 _item_text_realize(it, VIEW(it), parts);
7611 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
7613 _item_content_realize(it, VIEW(it), &it->content_objs, "contents", parts);
7616 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_content_objs,
7619 if (GL_IT(it)->deco_it_view)
7621 _item_content_realize(it, GL_IT(it)->deco_it_view,
7622 &GL_IT(it)->deco_it_contents,
7625 if (GL_IT(it)->wsd->decorate_all_mode)
7627 _item_content_realize(it, it->deco_all_view,
7628 &GL_IT(it)->deco_all_contents,
7633 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
7634 _item_state_realize(it, VIEW(it), parts);
7636 GL_IT(it)->calc_done = EINA_FALSE;
7637 GL_IT(it)->block->calc_done = EINA_FALSE;
7638 GL_IT(it)->wsd->calc_done = EINA_FALSE;
7639 _changed(GL_IT(it)->wsd->pan_obj);
7643 _elm_genlist_item_item_class_update(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
7644 const Elm_Genlist_Item_Class *itc)
7646 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7647 EINA_SAFETY_ON_NULL_RETURN(itc);
7648 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7651 if (!GL_IT(it)->block) return;
7653 // FIXME(160711): orignal edje object updated by _view_theme_update
7654 // cannot recieve signal emit properly. This edje bug must be fixed.
7655 _item_cache_all_free(sd);
7657 sd->no_cache = EINA_TRUE;
7658 _item_unrealize(it, EINA_FALSE);
7659 sd->no_cache = EINA_FALSE;
7660 _item_realize(it, EINA_FALSE);
7662 if (sd->aligned_item == it)
7663 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
7665 GL_IT(it)->calc_done = EINA_FALSE;
7666 GL_IT(it)->block->calc_done = EINA_FALSE;
7667 sd->calc_done = EINA_FALSE;
7669 _changed(sd->pan_obj);
7672 EOLIAN static const Elm_Genlist_Item_Class *
7673 _elm_genlist_item_item_class_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7675 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
7679 static Evas_Object *
7680 _elm_genlist_item_label_create(void *data,
7681 Evas_Object *obj EINA_UNUSED,
7682 Evas_Object *tooltip,
7683 void *it EINA_UNUSED)
7685 Evas_Object *label = elm_label_add(tooltip);
7690 elm_object_style_set(label, "tooltip");
7691 elm_object_text_set(label, data);
7697 _elm_genlist_item_label_del_cb(void *data,
7698 Evas_Object *obj EINA_UNUSED,
7699 void *event_info EINA_UNUSED)
7701 eina_stringshare_del(data);
7705 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
7708 eo_do(it, elm_wdg_item_tooltip_text_set(text));
7712 _elm_genlist_item_elm_widget_item_tooltip_text_set(Eo *eo_it, Elm_Gen_Item *it, const char *text)
7714 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7716 text = eina_stringshare_add(text);
7717 elm_genlist_item_tooltip_content_cb_set
7718 (eo_it, _elm_genlist_item_label_create, text,
7719 _elm_genlist_item_label_del_cb);
7723 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item,
7724 Elm_Tooltip_Item_Content_Cb func,
7726 Evas_Smart_Cb del_cb)
7728 eo_do(item, elm_wdg_item_tooltip_content_cb_set(func, data, del_cb));
7733 _elm_genlist_item_elm_widget_item_tooltip_content_cb_set(Eo *eo_it, Elm_Gen_Item *it,
7734 Elm_Tooltip_Item_Content_Cb func,
7736 Evas_Smart_Cb del_cb)
7738 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7740 if ((it->tooltip.content_cb != func) || (it->tooltip.data != data))
7742 if (it->tooltip.del_cb)
7743 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7745 it->tooltip.content_cb = func;
7746 it->tooltip.data = data;
7747 it->tooltip.del_cb = del_cb;
7752 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7753 elm_wdg_item_tooltip_content_cb_set
7754 (it->tooltip.content_cb, it->tooltip.data, NULL));
7756 elm_wdg_item_tooltip_style_set(it->tooltip.style),
7757 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
7762 elm_genlist_item_tooltip_unset(Elm_Object_Item *item)
7764 eo_do(item, elm_wdg_item_tooltip_unset());
7768 _elm_genlist_item_elm_widget_item_tooltip_unset(Eo *eo_it, Elm_Gen_Item *it)
7770 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7772 if ((VIEW(it)) && (it->tooltip.content_cb))
7773 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7774 elm_wdg_item_tooltip_unset());
7776 if (it->tooltip.del_cb)
7777 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7778 it->tooltip.del_cb = NULL;
7779 it->tooltip.content_cb = NULL;
7780 it->tooltip.data = NULL;
7781 it->tooltip.free_size = EINA_FALSE;
7782 if (it->tooltip.style)
7783 eo_do(eo_it, elm_wdg_item_tooltip_style_set(NULL));
7787 elm_genlist_item_tooltip_style_set(Elm_Object_Item *item,
7790 eo_do(item, elm_wdg_item_tooltip_style_set(style));
7794 _elm_genlist_item_elm_widget_item_tooltip_style_set(Eo *eo_it, Elm_Gen_Item *it,
7797 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7799 eina_stringshare_replace(&it->tooltip.style, style);
7800 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7801 elm_wdg_item_tooltip_style_set(style));
7805 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
7808 return eo_do_ret(it, style, elm_wdg_item_tooltip_style_get());
7811 EOLIAN static const char *
7812 _elm_genlist_item_elm_widget_item_tooltip_style_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7814 return it->tooltip.style;
7818 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *item,
7822 return eo_do_ret(item, ret, elm_wdg_item_tooltip_window_mode_set(disable));
7825 EOLIAN static Eina_Bool
7826 _elm_genlist_item_elm_widget_item_tooltip_window_mode_set(Eo *eo_it, Elm_Gen_Item *it,
7829 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7832 it->tooltip.free_size = disable;
7834 return eo_do_super_ret(eo_it, ELM_GENLIST_ITEM_CLASS, ret,
7835 elm_wdg_item_tooltip_window_mode_set(disable));
7841 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *eo_it)
7844 return eo_do_ret(eo_it, ret, elm_wdg_item_tooltip_window_mode_get());
7847 EOLIAN static Eina_Bool
7848 _elm_genlist_item_elm_widget_item_tooltip_window_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7850 return it->tooltip.free_size;
7854 elm_genlist_item_cursor_set(Elm_Object_Item *item,
7857 eo_do(item, elm_wdg_item_cursor_set(cursor));
7861 _elm_genlist_item_elm_widget_item_cursor_set(Eo *eo_it, Elm_Gen_Item *it,
7864 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7865 eina_stringshare_replace(&it->mouse_cursor, cursor);
7866 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7867 elm_wdg_item_cursor_set(cursor));
7871 elm_genlist_item_cursor_get(const Elm_Object_Item *eo_it)
7874 return eo_do_ret(eo_it, cursor, elm_wdg_item_cursor_get());
7878 elm_genlist_item_cursor_unset(Elm_Object_Item *item)
7880 eo_do(item, elm_wdg_item_cursor_unset());
7884 _elm_genlist_item_elm_widget_item_cursor_unset(Eo *eo_it, Elm_Gen_Item *it)
7886 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7888 if (!it->mouse_cursor) return;
7890 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7891 elm_wdg_item_cursor_unset());
7893 ELM_SAFE_FREE(it->mouse_cursor, eina_stringshare_del);
7897 elm_genlist_item_cursor_style_set(Elm_Object_Item *eo_it,
7900 eo_do(eo_it, elm_wdg_item_cursor_style_set(style));
7904 elm_genlist_item_cursor_style_get(const Elm_Object_Item *eo_it)
7907 return eo_do_ret( eo_it, style, elm_wdg_item_cursor_style_get());
7911 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *eo_it,
7912 Eina_Bool engine_only)
7914 eo_do(eo_it, elm_wdg_item_cursor_engine_only_set(engine_only));
7918 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *eo_it)
7921 return eo_do_ret( eo_it, ret, elm_wdg_item_cursor_engine_only_get());
7925 _elm_genlist_item_index_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7929 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, -1);
7931 EINA_INLIST_FOREACH(GL_IT(it)->wsd->items, tmp)
7933 if (tmp == it) break;
7940 _elm_genlist_mode_set(Eo *obj, Elm_Genlist_Data *sd, Elm_List_Mode mode)
7942 if (sd->mode == mode) return;
7945 if (sd->mode == ELM_LIST_LIMIT)
7947 sd->scr_minw = EINA_TRUE;
7948 sd->scr_minh = EINA_FALSE;
7950 else if (sd->mode == ELM_LIST_EXPAND)
7952 sd->scr_minw = EINA_TRUE;
7953 sd->scr_minh = EINA_TRUE;
7957 sd->scr_minw = EINA_FALSE;
7958 sd->scr_minh = EINA_FALSE;
7961 elm_layout_sizing_eval(obj);
7964 EOLIAN static Elm_List_Mode
7965 _elm_genlist_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7971 elm_genlist_bounce_set(Evas_Object *obj,
7975 ELM_GENLIST_CHECK(obj);
7976 eo_do(obj, elm_interface_scrollable_bounce_allow_set(h_bounce, v_bounce));
7980 _elm_genlist_elm_interface_scrollable_bounce_allow_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool h_bounce, Eina_Bool v_bounce)
7982 sd->h_bounce = !!h_bounce;
7983 sd->v_bounce = !!v_bounce;
7985 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_bounce_allow_set
7986 (sd->h_bounce, sd->v_bounce));
7987 //sd->s_iface->bounce_allow_set(obj, sd->h_bounce, sd->v_bounce);
7991 elm_genlist_bounce_get(const Evas_Object *obj,
7992 Eina_Bool *h_bounce,
7993 Eina_Bool *v_bounce)
7995 ELM_GENLIST_CHECK(obj);
7996 eo_do( obj, elm_interface_scrollable_bounce_allow_get
7997 (h_bounce, v_bounce));
8001 _elm_genlist_elm_interface_scrollable_bounce_allow_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
8003 if (h_bounce) *h_bounce = sd->h_bounce;
8004 if (v_bounce) *v_bounce = sd->v_bounce;
8008 _elm_genlist_homogeneous_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool homogeneous)
8010 sd->homogeneous = !!homogeneous;
8013 EOLIAN static Eina_Bool
8014 _elm_genlist_homogeneous_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8016 return sd->homogeneous;
8020 _elm_genlist_block_count_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, int count)
8022 EINA_SAFETY_ON_TRUE_RETURN(count < 1);
8024 sd->max_items_per_block = count;
8025 sd->item_cache_max = sd->max_items_per_block * 2;
8026 _item_cache_all_free(sd);
8030 _elm_genlist_block_count_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8032 return sd->max_items_per_block;
8036 _filter_item_internal(Elm_Gen_Item *it)
8038 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8039 if (sd->filter_data && it->itc->func.filter_get)
8041 if (!it->itc->func.filter_get(
8042 (void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)),
8043 WIDGET(it), sd->filter_data))
8045 it->want_hidden = EINA_TRUE;
8046 if (sd->show_item == it) sd->show_item = NULL;
8047 GL_IT(it)->block->calc_done = EINA_FALSE;
8048 sd->calc_done = EINA_FALSE;
8051 sd->filtered_count++;
8053 it->filtered = EINA_TRUE;
8054 sd->processed_count++;
8058 _item_filtered_get(Elm_Gen_Item *it)
8061 if (!it) return EINA_FALSE;
8062 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8065 l = eina_list_data_find_list(sd->filter_queue, it);
8067 sd->filter_queue = eina_list_remove_list(sd->filter_queue, l);
8068 l = eina_list_data_find_list(sd->queue, it);
8071 sd->queue = eina_list_remove_list(sd->queue, l);
8072 GL_IT(it)->queued = EINA_FALSE;
8073 GL_IT(it)->resized = EINA_FALSE;
8074 _item_process(sd, it);
8077 _filter_item_internal(it);
8078 GL_IT(it)->block->calc_done = EINA_FALSE;
8079 sd->calc_done = EINA_FALSE;
8080 _changed(sd->pan_obj);
8082 if (!it->want_hidden) return EINA_TRUE;
8087 _filter_queue_process(Elm_Genlist_Data *sd)
8090 Elm_Gen_Item *it, *first;
8093 t0 = ecore_time_get();
8094 for (n = 0; ((sd->filter_queue) && (sd->processed_count < ITEM_QUEUE_MAX)); n++)
8096 first = it = eina_list_data_get(sd->filter_queue);
8097 //FIXME: This is added as a fail safe code for items not yet processed.
8098 while (it && it->item->queued)
8100 if ((ecore_time_get() - t0) > (ecore_animator_frametime_get()))
8102 sd->filter_queue = eina_list_remove_list
8103 (sd->filter_queue, sd->filter_queue);
8104 sd->filter_queue = eina_list_append(sd->filter_queue, it);
8105 it = eina_list_data_get(sd->filter_queue);
8107 //Do not iterate more than one loop
8108 if (it == first) return n;
8110 sd->filter_queue = eina_list_remove_list(sd->filter_queue, sd->filter_queue);
8113 _filter_item_internal(it);
8114 GL_IT(it)->block->calc_done = EINA_FALSE;
8116 sd->calc_done = EINA_FALSE;
8117 _changed(sd->pan_obj);
8118 if ((ecore_time_get() - t0) > (ecore_animator_frametime_get()))
8120 //At least 1 item is filtered by this time, so return n+1 for first loop
8129 _filter_process(void *data,
8132 Elm_Genlist_Data *sd = data;
8134 if (_filter_queue_process(sd) > 0) *wakeup = EINA_TRUE;
8135 if (!sd->filter_queue) return ECORE_CALLBACK_CANCEL;
8136 return ECORE_CALLBACK_RENEW;
8140 _item_filter_enterer(void *data)
8142 Eina_Bool wakeup = EINA_FALSE;
8143 ELM_GENLIST_DATA_GET(data, sd);
8144 Eina_Bool ok = _filter_process(sd, &wakeup);
8147 if (sd->dummy_job) ecore_job_del(sd->dummy_job);
8148 sd->dummy_job = ecore_job_add(_dummy_job, sd);
8150 if (ok == ECORE_CALLBACK_CANCEL)
8154 ecore_job_del(sd->dummy_job);
8155 sd->dummy_job = NULL;
8157 sd->queue_idle_enterer = NULL;
8158 evas_object_smart_callback_call((Evas_Object *)data, SIG_FILTER_DONE, NULL);
8165 _elm_genlist_filter_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, void *filter_data)
8171 if (sd->filter_queue)
8172 ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
8173 ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
8174 ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
8175 sd->filtered_count = 0;
8176 sd->processed_count = 0;
8177 sd->filter = EINA_TRUE;
8178 sd->filter_data = filter_data;
8180 EINA_INLIST_FOREACH(sd->blocks, itb)
8184 EINA_LIST_FOREACH(itb->items, l, it)
8186 it->filtered = EINA_FALSE;
8187 it->want_hidden = EINA_FALSE;
8189 _filter_item_internal(it);
8191 sd->filter_queue = eina_list_append(sd->filter_queue, it);
8193 itb->calc_done = EINA_FALSE;
8194 sd->calc_done = EINA_FALSE;
8198 EINA_LIST_FOREACH(itb->items, l, it)
8200 it->filtered = EINA_FALSE;
8201 it->want_hidden = EINA_FALSE;
8202 sd->filter_queue = eina_list_append(sd->filter_queue, it);
8206 _changed(sd->pan_obj);
8208 sd->queue_filter_enterer = ecore_idle_enterer_add(_item_filter_enterer,
8213 _filter_iterator_next(Elm_Genlist_Filter *iter, void **data)
8215 if (!iter->current) return EINA_FALSE;
8217 while (iter->current)
8219 item = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->current, Elm_Gen_Item);
8220 iter->current = iter->current->next;
8221 if (_item_filtered_get(item))
8224 *data = EO_OBJ(item);
8233 _filter_iterator_free(Elm_Genlist_Filter *iter)
8238 static Evas_Object *
8239 _filter_iterator_get_container(Elm_Genlist_Filter *iter)
8241 Elm_Gen_Item *it = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->head, Elm_Gen_Item);
8245 EOLIAN Eina_Iterator *
8246 _elm_genlist_filter_iterator_new(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8248 Elm_Genlist_Filter *iter;
8249 iter = calloc(1, sizeof (Elm_Genlist_Filter));
8250 if (!iter) return NULL;
8252 iter->head = sd->items;
8253 iter->current = sd->items;
8255 iter->iterator.version = EINA_ITERATOR_VERSION;
8256 iter->iterator.next = FUNC_ITERATOR_NEXT(_filter_iterator_next);
8257 iter->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
8258 _filter_iterator_get_container);
8259 iter->iterator.free = FUNC_ITERATOR_FREE(_filter_iterator_free);
8261 EINA_MAGIC_SET(&iter->iterator, EINA_MAGIC_ITERATOR);
8263 return &iter->iterator;
8267 _elm_genlist_longpress_timeout_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, double timeout)
8269 sd->longpress_timeout = timeout;
8272 EOLIAN static double
8273 _elm_genlist_longpress_timeout_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8275 return sd->longpress_timeout;
8279 elm_genlist_scroller_policy_set(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_set(policy_h, policy_v));
8288 _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)
8290 ELM_GENLIST_CHECK(obj);
8292 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
8293 (policy_v >= ELM_SCROLLER_POLICY_LAST))
8296 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_set(policy_h, policy_v));
8300 elm_genlist_scroller_policy_get(const Evas_Object *obj,
8301 Elm_Scroller_Policy *policy_h,
8302 Elm_Scroller_Policy *policy_v)
8304 ELM_GENLIST_CHECK(obj);
8305 eo_do( obj, elm_interface_scrollable_policy_get(policy_h, policy_v));
8309 _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)
8311 Elm_Scroller_Policy s_policy_h, s_policy_v;
8313 ELM_GENLIST_CHECK(obj);
8315 eo_do((Eo *)obj, elm_interface_scrollable_policy_get(&s_policy_h, &s_policy_v));
8316 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
8317 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
8321 _elm_genlist_realized_items_update(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED)
8324 Elm_Object_Item *eo_it;
8326 ELM_GENLIST_CHECK(obj);
8328 list = elm_genlist_realized_items_get(obj);
8329 EINA_LIST_FREE(list, eo_it)
8330 elm_genlist_item_update(eo_it);
8334 _elm_genlist_item_decorate_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8335 const char *decorate_it_type,
8336 Eina_Bool decorate_it_set)
8338 Elm_Genlist_Data *sd;
8341 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8342 sd = GL_IT(it)->wsd;
8344 if (!decorate_it_type) return;
8345 if (eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get())) return;
8346 if (sd->decorate_all_mode) return;
8348 if ((sd->mode_item == it) &&
8349 (!strcmp(decorate_it_type, sd->decorate_it_type)) &&
8352 if (!it->itc->decorate_item_style) return;
8353 it->decorate_it_set = decorate_it_set;
8356 if (((sd->decorate_it_type)
8357 && (strcmp(decorate_it_type, sd->decorate_it_type))) ||
8358 (decorate_it_set) || ((it == sd->mode_item) && (!decorate_it_set)))
8360 char buf[1024], buf2[1024];
8362 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8363 if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
8364 sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
8366 snprintf(buf, sizeof(buf), "elm,state,%s,passive", sd->decorate_it_type);
8367 edje_object_signal_emit(GL_IT(it)->deco_it_view, buf, "elm");
8368 edje_object_signal_emit(VIEW(it), buf, "elm");
8370 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished",
8371 sd->decorate_it_type);
8372 edje_object_signal_callback_add(GL_IT(it)->deco_it_view, buf2,
8374 _decorate_item_finished_signal_cb, it);
8375 sd->mode_item = NULL;
8378 eina_stringshare_replace(&sd->decorate_it_type, decorate_it_type);
8379 if (decorate_it_set)
8382 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8383 if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
8384 sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
8386 _decorate_item_realize(it);
8390 EOLIAN static const char *
8391 _elm_genlist_item_decorate_mode_get(Eo *eo_i EINA_UNUSED, Elm_Gen_Item *i)
8393 ELM_GENLIST_ITEM_CHECK_OR_RETURN(i, NULL);
8394 return GL_IT(i)->wsd->decorate_it_type;
8397 EOLIAN static Elm_Object_Item *
8398 _elm_genlist_decorated_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8400 return EO_OBJ(sd->mode_item);
8403 EOLIAN static Eina_Bool
8404 _elm_genlist_decorate_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8406 return sd->decorate_all_mode;
8410 _elm_genlist_decorate_mode_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool decorated)
8412 Elm_Object_Item *eo_it;
8415 decorated = !!decorated;
8416 if (sd->decorate_all_mode == decorated) return;
8417 // decorate_all_mode should be set first
8418 // because content_get func. will be called after this
8419 // and user can check whether deocrate_all_mode is enabeld.
8420 sd->decorate_all_mode = decorated;
8422 list = elm_genlist_realized_items_get(obj);
8423 EINA_LIST_FREE(list, eo_it)
8425 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8427 if (!sd->decorate_all_mode)
8429 _decorate_all_item_unrealize(it);
8431 else if (it->itc->decorate_all_item_style)
8433 _decorate_all_item_realize(it, EINA_TRUE);
8435 _access_widget_item_register(it);
8437 _changed(sd->pan_obj);
8441 _elm_genlist_reorder_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool reorder_mode)
8444 Elm_Object_Item *eo_it;
8446 if (sd->reorder_mode == !!reorder_mode) return;
8447 sd->reorder_mode = !!reorder_mode;
8449 list = elm_genlist_realized_items_get(obj);
8450 EINA_LIST_FREE(list, eo_it)
8452 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8453 if (sd->reorder_mode)
8455 edje_object_signal_emit
8456 (VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
8457 if (it->deco_all_view)
8458 edje_object_signal_emit
8459 (it->deco_all_view, SIGNAL_REORDER_MODE_SET, "elm");
8463 edje_object_signal_emit
8464 (VIEW(it), SIGNAL_REORDER_MODE_UNSET, "elm");
8465 if (it->deco_all_view)
8466 edje_object_signal_emit
8467 (it->deco_all_view, SIGNAL_REORDER_MODE_UNSET, "elm");
8472 EOLIAN static Eina_Bool
8473 _elm_genlist_reorder_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8475 return sd->reorder_mode;
8478 EOLIAN static Elm_Genlist_Item_Type
8479 _elm_genlist_item_type_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8481 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
8483 return GL_IT(it)->type;
8486 EAPI Elm_Genlist_Item_Class *
8487 elm_genlist_item_class_new(void)
8489 Elm_Genlist_Item_Class *itc = ELM_NEW(Elm_Genlist_Item_Class);
8490 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
8492 itc->version = CLASS_ALLOCATED;
8494 itc->delete_me = EINA_FALSE;
8495 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
8496 itc->homogeneous = EINA_FALSE;
8503 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
8505 if (itc && (itc->version == CLASS_ALLOCATED))
8507 itc->delete_me = EINA_TRUE;
8508 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
8518 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
8520 if (itc && (itc->version == CLASS_ALLOCATED))
8523 if (itc->refcount == 0) itc->refcount--;
8528 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
8530 if (itc && (itc->version == CLASS_ALLOCATED))
8532 if (itc->refcount > 0) itc->refcount--;
8533 if (itc->delete_me && (!itc->refcount))
8534 elm_genlist_item_class_free(itc);
8539 _elm_genlist_item_flip_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool flip)
8541 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8544 if (it->flipped == flip) return;
8549 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_content_objs,
8552 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
8553 if (GL_IT(it)->wsd->decorate_all_mode)
8554 edje_object_signal_emit
8555 (it->deco_all_view, SIGNAL_FLIP_ENABLED, "elm");
8560 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_DISABLED, "elm");
8561 if (GL_IT(it)->wsd->decorate_all_mode)
8562 edje_object_signal_emit
8563 (it->deco_all_view, SIGNAL_FLIP_DISABLED, "elm");
8565 EINA_LIST_FREE(GL_IT(it)->flip_content_objs, c)
8568 // FIXME: update texts should be done by app?
8569 _item_text_realize(it, VIEW(it), NULL);
8571 _access_widget_item_register(it);
8574 EOLIAN static Eina_Bool
8575 _elm_genlist_item_flip_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8577 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
8583 _elm_genlist_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Elm_Object_Select_Mode mode)
8585 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (sd->select_mode == mode))
8588 sd->select_mode = mode;
8590 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8591 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
8594 Elm_Object_Item *eo_it;
8595 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
8597 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8601 if (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
8604 EINA_INLIST_FOREACH(sd->items, it)
8606 if (!GL_IT(it)->block) continue;
8607 GL_IT(it)->calc_done = EINA_FALSE;
8608 GL_IT(it)->block->calc_done = EINA_FALSE;
8609 sd->calc_done = EINA_FALSE;
8610 _changed(sd->pan_obj);
8615 EOLIAN static Elm_Object_Select_Mode
8616 _elm_genlist_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8618 return sd->select_mode;
8622 _elm_genlist_highlight_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool highlight)
8624 sd->highlight = !!highlight;
8627 EOLIAN static Eina_Bool
8628 _elm_genlist_highlight_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8630 return sd->highlight;
8634 _elm_genlist_item_select_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8635 Elm_Object_Select_Mode mode)
8637 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8639 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (it->select_mode == mode))
8642 it->select_mode = mode;
8644 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8645 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
8648 if (GL_IT(it)->block && it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
8650 GL_IT(it)->calc_done = EINA_FALSE;
8651 GL_IT(it)->block->calc_done = EINA_FALSE;
8652 GL_IT(it)->wsd->calc_done = EINA_FALSE;
8653 _changed(GL_IT(it)->wsd->pan_obj);
8657 EOLIAN static Elm_Object_Select_Mode
8658 _elm_genlist_item_select_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8660 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
8662 return it->select_mode;
8665 EOLIAN Elm_Atspi_State_Set
8666 _elm_genlist_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_it, Elm_Gen_Item *it EINA_UNUSED)
8668 Elm_Atspi_State_Set ret;
8671 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
8673 eo_do(eo_it, sel = elm_obj_genlist_item_selected_get());
8675 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTABLE);
8678 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTED);
8680 if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_TREE)
8682 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDABLE);
8683 if (elm_genlist_item_expanded_get(eo_it))
8684 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8685 //TIZEN_ONLY(20160606): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8687 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8690 //TIZEN_ONLY(20160608): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8691 else if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_GROUP)
8693 if (elm_genlist_item_expanded_get(eo_it))
8694 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8696 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8704 _elm_genlist_item_elm_interface_atspi_accessible_name_get(Eo *eo_it,
8709 char *accessible_name;
8710 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_name_get());
8711 if (ret) return ret;
8713 buf = eina_strbuf_new();
8715 if (it->itc->func.text_get)
8721 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
8723 EINA_LIST_FREE(texts, key)
8725 char *str_markup = it->itc->func.text_get
8726 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
8727 char *str_utf8 = _elm_util_mkup_to_text(str_markup);
8731 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
8732 eina_strbuf_append(buf, str_utf8);
8738 accessible_name = eina_strbuf_string_steal(buf);
8739 eina_strbuf_free(buf);
8741 eina_stringshare_del(it->base->accessible_name);
8742 it->base->accessible_name = eina_stringshare_add(accessible_name);
8743 free(accessible_name);
8744 return it->base->accessible_name;
8748 _elm_genlist_item_elm_interface_atspi_accessible_children_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8750 Eina_List *ret = NULL;
8755 parts = elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "contents"));
8757 EINA_LIST_FREE(parts, key)
8760 part = edje_object_part_swallow_get(VIEW(it), key);
8761 if (part && eo_isa(part, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
8763 ret = eina_list_append(ret, part);
8764 eo_do(part, elm_interface_atspi_accessible_parent_set(eo_it));
8772 ///////////////////////////////////////////////////////////////////////////////
8773 //TIZEN ONLY:(20150623): Region show on item elements fixed
8774 //Grab and clear highlight on genlist items
8775 ///////////////////////////////////////////////////////////////////////////////
8776 EOLIAN static Eina_Bool
8777 _elm_genlist_item_elm_interface_atspi_component_highlight_grab(Eo *eo_it, Elm_Gen_Item *it)
8779 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8781 if (!TIZEN_PROFILE_WEARABLE)
8783 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
8784 eo_do_super(EO_OBJ(it), ELM_GENLIST_ITEM_CLASS, elm_interface_atspi_component_highlight_grab());
8789 // TIZEN_ONLY(20171011) : atspi : Do not center align when genlist item is highlighted in wearable profile
8790 //FIXME : First, last item is called centered because it may not have a proxy image.
8791 // This part will be revised in the next version.
8792 Eina_List *realized = elm_genlist_realized_items_get(WIDGET(it));
8793 if (VIEW(it) || realized)
8795 Elm_Object_Item *first_it = elm_genlist_first_item_get(WIDGET(it));
8796 Elm_Object_Item *last_it = elm_genlist_last_item_get(WIDGET(it));
8797 if (first_it == eo_it || last_it == eo_it)
8798 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
8800 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
8803 eina_list_free(realized);
8807 elm_object_accessibility_highlight_set(EO_OBJ(it), EINA_TRUE);
8808 ///TIZEN_ONLY(20170717) : expose highlight information on atspi
8809 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
8812 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
8813 // If you call eo_do_super, then you do NOT have to call smart callback.
8814 evas_object_smart_callback_call(WIDGET(it), "atspi,highlighted", EO_OBJ(it));
8821 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8822 sd->currently_highlighted_item = it;
8827 if (!TIZEN_PROFILE_WEARABLE)
8829 //TIZEN_ONLY(20170724): grab highlight using unrealized item
8830 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
8833 sd->atspi_item_to_highlight = it;//it will be highlighted when realized
8836 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8837 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
8843 EOLIAN static Eina_Bool
8844 _elm_genlist_item_elm_interface_atspi_component_highlight_clear(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8846 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8847 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8848 if(sd->currently_highlighted_item == it)
8849 sd->currently_highlighted_item = NULL;
8851 if (sd->atspi_item_to_highlight == it)
8852 sd->atspi_item_to_highlight = NULL;
8853 elm_object_accessibility_highlight_set(EO_OBJ(it), EINA_FALSE);
8854 ///TIZEN_ONLY(20170717) : expose highlight information on atspi
8855 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
8858 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8859 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
8861 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
8862 // If you call eo_do_super, then you do NOT have to call smart callback.
8863 evas_object_smart_callback_call(WIDGET(it), "atspi,unhighlighted", EO_OBJ(it));
8868 ///////////////////////////////////////////////////////////////////////////////
8871 _elm_genlist_tree_effect_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enabled EINA_UNUSED)
8873 // Need to implemented
8874 //sd->tree_effect_enabled = !!enabled;
8877 EOLIAN static Eina_Bool
8878 _elm_genlist_tree_effect_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
8884 _elm_genlist_focus_on_selection_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enabled EINA_UNUSED)
8886 // Need to Implemented
8887 sd->focus_on_selection_enabled = !!enabled;
8890 EOLIAN static Eina_Bool
8891 _elm_genlist_focus_on_selection_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
8893 // Need to Implemented
8894 return sd->focus_on_selection_enabled;
8897 EAPI Elm_Object_Item *
8898 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth)
8900 Elm_Gen_Item *it = NULL;
8904 ELM_GENLIST_CHECK(obj) NULL;
8905 ELM_GENLIST_DATA_GET(obj, sd);
8907 if (!sd->items) return NULL;
8909 a = eina_inlist_accessor_new(sd->items);
8910 if (!a) return NULL;
8911 if (eina_accessor_data_get(a, nth, &data))
8912 it = ELM_GEN_ITEM_FROM_INLIST(data);
8913 eina_accessor_free(a);
8918 elm_genlist_fx_mode_set(Evas_Object *obj, Eina_Bool mode)
8920 ELM_GENLIST_CHECK(obj);
8921 ELM_GENLIST_DATA_GET(obj, sd);
8928 elm_genlist_fx_mode_get(const Evas_Object *obj)
8930 ELM_GENLIST_CHECK(obj) EINA_FALSE;
8931 ELM_GENLIST_DATA_GET(obj, sd);
8937 elm_genlist_item_hide_set(const Elm_Object_Item *eo_item EINA_UNUSED, Eina_Bool hide EINA_UNUSED)
8939 WRN("This API is deprecated, please use filter_set instead of this");
8943 elm_genlist_item_hide_get(const Elm_Object_Item *eo_item EINA_UNUSED)
8945 WRN("This API is deprecated, please use filter_set instead of this");
8949 ///////////////////////////////////////////////////////////////////////////////
8950 //TIZEN ONLY:(20150126): its not decided whether deprecated or not to give away
8951 ///////////////////////////////////////////////////////////////////////////////
8953 elm_genlist_realization_mode_set(Evas_Object *obj, Eina_Bool realization_mode)
8955 ELM_GENLIST_CHECK(obj);
8956 ELM_GENLIST_DATA_GET(obj, sd);
8958 if (sd->realization_mode == realization_mode) return;
8959 sd->realization_mode = realization_mode;
8963 elm_genlist_realization_mode_get(Evas_Object *obj)
8965 ELM_GENLIST_CHECK(obj) EINA_FALSE;
8966 ELM_GENLIST_DATA_GET(obj, sd);
8968 return sd->realization_mode;
8970 ///////////////////////////////////////////////////////////////////////////////
8973 elm_genlist_item_reorder_start(Elm_Object_Item *eo_item)
8975 ELM_GENLIST_ITEM_DATA_GET(eo_item, it);
8976 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8977 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
8979 sd->reorder.it = it;
8981 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8982 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
8983 (EINA_FALSE, EINA_FALSE));
8984 //sd->s_iface->hold_set(sd->obj, EINA_TRUE);
8985 //sd->s_iface->bounce_allow_set(sd->obj, EINA_FALSE, EINA_FALSE);
8986 sd->reorder_force = EINA_TRUE;
8990 elm_genlist_item_reorder_stop(Elm_Object_Item *eo_item)
8992 ELM_GENLIST_ITEM_DATA_GET(eo_item, it);
8993 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8994 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
8996 sd->reorder_force = EINA_FALSE;
9000 _elm_genlist_class_constructor(Eo_Class *klass)
9002 if (_elm_config->access_mode)
9003 _elm_genlist_smart_focus_next_enable = EINA_TRUE;
9005 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
9009 _elm_genlist_elm_interface_atspi_accessible_children_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
9011 Eina_List *ret = NULL;
9014 EINA_INLIST_FOREACH(sd->items, it)
9015 ret = eina_list_append(ret, EO_OBJ(it));
9020 EOLIAN Elm_Atspi_State_Set
9021 _elm_genlist_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED)
9023 Elm_Atspi_State_Set ret;
9025 eo_do_super(obj, ELM_GENLIST_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
9027 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MANAGES_DESCENDANTS);
9029 if (elm_genlist_multi_select_get(obj))
9030 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MULTISELECTABLE);
9036 _elm_genlist_elm_interface_atspi_selection_selected_children_count_get(Eo *objm EINA_UNUSED, Elm_Genlist_Data *pd)
9038 return eina_list_count(pd->selected);
9042 _elm_genlist_elm_interface_atspi_selection_selected_child_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_idx)
9044 return eina_list_nth(pd->selected, child_idx);
9048 _elm_genlist_elm_interface_atspi_selection_child_select(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9051 if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
9053 EINA_INLIST_FOREACH(pd->items, item)
9055 if (child_index-- == 0)
9057 elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
9066 _elm_genlist_elm_interface_atspi_selection_selected_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9071 EINA_LIST_FOREACH(pd->selected, l, item)
9073 if (child_index-- == 0)
9075 elm_genlist_item_selected_set(item, EINA_FALSE);
9083 _elm_genlist_elm_interface_atspi_selection_is_child_selected(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9087 EINA_INLIST_FOREACH(pd->items, item)
9089 if (child_index-- == 0)
9091 return elm_genlist_item_selected_get(EO_OBJ(item));
9098 _elm_genlist_elm_interface_atspi_selection_all_children_select(Eo *obj, Elm_Genlist_Data *pd)
9102 if (!elm_genlist_multi_select_get(obj))
9105 EINA_INLIST_FOREACH(pd->items, item)
9106 elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
9112 _elm_genlist_elm_interface_atspi_selection_clear(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd)
9114 return _all_items_deselect(pd);
9118 _elm_genlist_elm_interface_atspi_selection_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9121 if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
9123 EINA_INLIST_FOREACH(pd->items, item)
9125 if (child_index-- == 0)
9127 elm_genlist_item_selected_set(EO_OBJ(item), EINA_FALSE);
9135 // TIZEN only (20150914) : Accessibility: updated highlight change during genlist and list scroll
9136 static int _is_item_in_viewport(int viewport_y, int viewport_h, int obj_y, int obj_h)
9138 if (obj_y + obj_h <= viewport_y)
9140 else if (obj_y >= viewport_y + viewport_h)
9146 _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)
9148 if (!_elm_atspi_enabled())
9150 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
9154 int old_x, old_y, delta_y;
9155 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_get(&old_x,&old_y));
9156 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
9157 delta_y = old_y - y;
9159 //check if highlighted item is genlist descendant
9160 Evas_Object * highlighted_obj = _elm_object_accessibility_currently_highlighted_get();
9161 if (eo_isa(highlighted_obj, ELM_WIDGET_ITEM_CLASS))
9163 Elm_Widget_Item_Data *id = eo_data_scope_get(highlighted_obj, ELM_WIDGET_ITEM_CLASS);
9164 highlighted_obj = id->view;
9167 Evas_Object * parent = highlighted_obj;
9168 if (eo_isa(highlighted_obj, ELM_WIDGET_CLASS))
9170 while ((parent = elm_widget_parent_get(parent)))
9174 else if (eo_isa(highlighted_obj, EDJE_OBJECT_CLASS))
9176 while ((parent = evas_object_smart_parent_get(parent)))
9180 // TIZEN_ONLY(20160805): set _accessibility_currently_highlighted_obj to NULL in object delete callback
9183 WRN("Improper highlighted object: %p", highlighted_obj);
9190 int obj_x, obj_y, w, h, hx, hy, hw, hh;
9191 evas_object_geometry_get(obj, &obj_x, &obj_y, &w, &h);
9193 evas_object_geometry_get(highlighted_obj, &hx, &hy, &hw, &hh);
9195 Elm_Gen_Item * next_previous_item = NULL;
9196 int viewport_position_result = _is_item_in_viewport(obj_y, h, hy, hh);
9197 //only highlight if move direction is correct
9198 //sometimes highlighted item is brought in and it does not fit viewport
9199 //however content goes to the viewport position so soon it will
9200 //meet _is_item_in_viewport condition
9201 if ((viewport_position_result < 0 && delta_y > 0) ||
9202 (viewport_position_result > 0 && delta_y < 0))
9205 Eina_List *realized_items = elm_genlist_realized_items_get(obj);
9208 Eina_Bool traverse_direction = viewport_position_result > 0;
9209 l = traverse_direction ? realized_items: eina_list_last(realized_items);
9213 item = eina_list_data_get(l);
9214 ELM_GENLIST_ITEM_DATA_GET(item, it_data);
9215 next_previous_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it_data));
9216 evas_object_geometry_get(VIEW(next_previous_item), &hx, &hy, &hw, &hh);
9217 if (_is_item_in_viewport(obj_y, h, hy, hh) == 0)
9220 next_previous_item = NULL;
9222 l = traverse_direction ? eina_list_next(l): eina_list_prev(l);
9225 if (next_previous_item)
9227 elm_object_accessibility_highlight_set(EO_OBJ(next_previous_item), EINA_TRUE);
9228 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(next_previous_item), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
9232 // Tizen only (20150914)
9233 #include "elm_genlist.eo.c"
9234 #include "elm_genlist_item.eo.c"