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")) return;
1542 evas_object_geometry_get(wd->resize_obj, NULL, NULL, &w, NULL);
1543 top = edje_object_part_object_get(VIEW(it), "elm.padding.focus_bg.top");
1544 bottom = edje_object_part_object_get(VIEW(it), "elm.padding.focus_bg.bottom");
1548 evas_object_geometry_get(top, NULL, NULL, NULL, &h);
1550 evas_object_geometry_get(bottom, NULL, NULL, NULL, &h);
1554 rectangle = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
1555 evas_object_size_hint_min_set(rectangle, w, rectangle_h);
1556 evas_object_size_hint_max_set(rectangle, w, rectangle_h);
1557 evas_object_color_set(rectangle, 0, 0, 0, 0);
1558 elm_object_part_content_set(wd->obj, "focus_bg_size", rectangle);
1560 edje_object_signal_emit(wd->resize_obj, SIGNAL_FOCUS_BG_SHOW, "elm");
1564 _item_position(Elm_Gen_Item *it,
1572 Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0;
1573 Evas_Coord ix = 0, iy = 0, iw = 0, ih = 0;
1574 Elm_Gen_Item *target = it;
1575 Elm_Genlist_Data *sd = GL_IT(target)->wsd;
1576 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(target), wsd);
1580 iw = GL_IT(target)->w;
1581 ih = GL_IT(target)->h;
1583 evas_object_resize(view, iw, ih);
1584 evas_object_move(view, ix, iy);
1585 evas_object_show(view);
1587 if (wsd->scroll_item_align_enable)
1590 int pre_multiplied_color = 0;
1591 int resize_width = 0;
1592 int resize_hight = 0;
1595 double move_v[4] = {0.49, 0.99, 0.45, 1.0};
1596 double scale_v[4] = {0.49, 0.14, 1, 0.63};
1598 evas_object_geometry_get(wsd->obj, &ox, &oy, &ow, &oh);
1599 int g_center = oy + oh / 2;
1600 int i_center = GL_IT(target)->scrl_y + GL_IT(target)->h / 2;
1602 if (target->item->proxy && !ELM_RECTS_INTERSECT(ix, iy, iw, ih, ox, oy, ow, oh))
1603 evas_object_hide(target->item->proxy);
1606 const char *vi_effect = edje_object_data_get(VIEW(target), "vi_effect");
1607 if (vi_effect && !strcmp(vi_effect, "on"))
1609 ratio = (float)abs(g_center - i_center) / (float)((oh / 2) + ih / 2);
1610 color = DIMED_ITEM_COLOR + ((255 - DIMED_ITEM_COLOR) * (1.0 - ratio));
1611 double scale_p = ecore_animator_pos_map_n(ratio, ECORE_POS_MAP_CUBIC_BEZIER, 4, scale_v);
1612 scale = elm_config_scale_get() - (scale_p * ALIGNED_ITEM_SCALE_FACTOR);
1614 resize_width = GL_IT(target)->w * (scale / elm_config_scale_get());
1615 if (!((iw - resize_width) % 2))
1618 iw = resize_width + 1;
1619 ix = GL_IT(target)->scrl_x + (GL_IT(target)->w - iw) / 2;
1620 resize_hight = GL_IT(target)->h * (scale / elm_config_scale_get());
1622 if (!((ih - resize_hight) % 2))
1625 ih = resize_hight + 1;
1627 if (i_center < g_center)
1629 double move_p = ecore_animator_pos_map_n(ratio, ECORE_POS_MAP_CUBIC_BEZIER, 4, move_v);
1630 iy = GL_IT(target)->scrl_y + move_p * (GL_IT(target)->h - ih);
1633 iy = GL_IT(target)->scrl_y;
1635 const char *dim = edje_object_data_get(view, "dim");
1636 if (!dim || (dim && !strcmp(dim, "on")))
1638 pre_multiplied_color = 255 * color >> 8;
1639 if (!elm_object_item_disabled_get(EO_OBJ(target)))
1640 evas_object_color_set(target->item->proxy, pre_multiplied_color, pre_multiplied_color, pre_multiplied_color, color);
1642 evas_object_color_set(target->item->proxy, 255, 255, 255, 255);
1645 evas_object_move(target->item->proxy, ix, iy);
1646 evas_object_resize(target->item->proxy, iw, ih);
1647 evas_object_show(target->item->proxy);
1650 ELM_RECTS_INTERSECT(GL_IT(target)->scrl_x, GL_IT(target)->scrl_y,
1651 GL_IT(target)->w, GL_IT(target)->h,
1652 ox, g_center - CENTER_CHECK_GAP,
1653 ow, CENTER_CHECK_GAP * 2))
1655 if ((sd->adjusted_item == target) &&
1656 ((sd->adjusted_item != sd->aligned_item) || (sd->unhighlighted)))
1658 edje_object_signal_emit(VIEW(sd->adjusted_item), SIGNAL_ITEM_HIGHLIGHTED, "elm");
1660 if (sd->aligned_item && sd->adjusted_item != sd->aligned_item)
1661 edje_object_signal_emit(VIEW(sd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
1662 sd->aligned_item = sd->adjusted_item;
1663 sd->unhighlighted = EINA_FALSE;
1666 if (sd->adjusted_item == target &&
1667 sd->aligned_item == sd->adjusted_item &&
1668 ((i_center >= g_center && i_center < g_center + 10) ||
1669 (i_center <= g_center && i_center > g_center - 10)))
1671 sd->adjusted_item = NULL;
1672 _focus_bg_show(sd->aligned_item);
1680 _item_all_position(Elm_Gen_Item *it,
1686 if (it->deco_all_view)
1687 _item_position(it, it->deco_all_view, it_x, it_y);
1688 else if (GL_IT(it)->deco_it_view)
1689 _item_position(it, GL_IT(it)->deco_it_view, it_x, it_y);
1691 _item_position(it, VIEW(it), it_x, it_y);
1695 _decorate_item_unrealize(Elm_Gen_Item *it)
1697 if (!GL_IT(it)->deco_it_view) return;
1699 edje_object_part_unswallow(GL_IT(it)->deco_it_view, VIEW(it));
1700 _view_clear(GL_IT(it)->deco_it_view, &(GL_IT(it)->deco_it_contents));
1701 evas_object_del(GL_IT(it)->deco_it_view);
1702 GL_IT(it)->deco_it_view = NULL;
1704 _item_mouse_callbacks_add(it, VIEW(it));
1705 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
1709 _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect)
1712 if (it->deco_all_view || !it->itc->decorate_all_item_style) return;
1714 // Before adding & swallowing, delete it from smart member
1715 evas_object_smart_member_del(VIEW(it));
1717 it->deco_all_view = _view_create(it, it->itc->decorate_all_item_style);
1718 _view_inflate(it->deco_all_view, it, &(GL_IT(it)->deco_all_contents));
1719 edje_object_part_swallow
1720 (it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
1721 evas_object_show(it->deco_all_view);
1723 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()))
1724 edje_object_signal_emit(it->deco_all_view, SIGNAL_DISABLED, "elm");
1726 edje_object_signal_emit(it->deco_all_view, SIGNAL_HIGHLIGHTED, "elm");
1727 if (GL_IT(it)->wsd->reorder_force ||
1728 GL_IT(it)->wsd->reorder_mode)
1729 edje_object_signal_emit
1730 (it->deco_all_view, SIGNAL_REORDER_MODE_SET, "elm");
1734 edje_object_signal_emit(VIEW(it),
1735 SIGNAL_DECORATE_ENABLED_EFFECT, "elm");
1736 edje_object_signal_emit(it->deco_all_view,
1737 SIGNAL_DECORATE_ENABLED_EFFECT, "elm");
1741 edje_object_signal_emit(VIEW(it), SIGNAL_DECORATE_ENABLED, "elm");
1742 edje_object_signal_emit(it->deco_all_view,
1743 SIGNAL_DECORATE_ENABLED,"elm");
1746 edje_object_signal_emit(it->deco_all_view, SIGNAL_FLIP_ENABLED, "elm");
1748 _item_mouse_callbacks_add(it, it->deco_all_view);
1749 _item_mouse_callbacks_del(it, VIEW(it));
1753 _expand_toggle_signal_cb(void *data,
1754 Evas_Object *obj EINA_UNUSED,
1755 const char *emission EINA_UNUSED,
1756 const char *source EINA_UNUSED)
1758 Elm_Gen_Item *it = data;
1760 if (GL_IT(it)->expanded)
1761 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, EO_OBJ(it));
1763 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, EO_OBJ(it));
1767 _expand_signal_cb(void *data,
1768 Evas_Object *obj EINA_UNUSED,
1769 const char *emission EINA_UNUSED,
1770 const char *source EINA_UNUSED)
1772 Elm_Gen_Item *it = data;
1774 if (!GL_IT(it)->expanded)
1775 evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, EO_OBJ(it));
1779 _contract_signal_cb(void *data,
1780 Evas_Object *obj EINA_UNUSED,
1781 const char *emission EINA_UNUSED,
1782 const char *source EINA_UNUSED)
1784 Elm_Gen_Item *it = data;
1786 if (GL_IT(it)->expanded)
1787 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, EO_OBJ(it));
1791 _item_mouse_callbacks_add(Elm_Gen_Item *it,
1794 evas_object_event_callback_add
1795 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
1796 evas_object_event_callback_add
1797 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
1798 evas_object_event_callback_add
1799 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
1803 _item_mouse_callbacks_del(Elm_Gen_Item *it,
1806 evas_object_event_callback_del_full
1807 (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
1808 evas_object_event_callback_del_full
1809 (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
1810 evas_object_event_callback_del_full
1811 (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
1816 _item_edje_callbacks_add(Elm_Gen_Item *it)
1818 edje_object_signal_callback_add
1819 (VIEW(it), "elm,action,expand,toggle", "elm",
1820 _expand_toggle_signal_cb, it);
1821 edje_object_signal_callback_add
1822 (VIEW(it), "elm,action,expand", "elm", _expand_signal_cb, it);
1823 edje_object_signal_callback_add
1824 (VIEW(it), "elm,action,contract", "elm", _contract_signal_cb, it);
1828 _item_edje_callbacks_del(Elm_Gen_Item *it)
1830 edje_object_signal_callback_del_full(VIEW(it), "elm,action,expand,toggle",
1831 "elm", _expand_toggle_signal_cb, it);
1832 edje_object_signal_callback_del_full(VIEW(it), "elm,action,expand", "elm",
1833 _expand_signal_cb, it);
1834 edje_object_signal_callback_del_full(VIEW(it), "elm,action,contract", "elm",
1835 _contract_signal_cb, it);
1839 _item_realize(Elm_Gen_Item *it,
1842 const char *treesize;
1845 if (it->realized) return;
1846 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
1847 ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd);
1849 it->realized = EINA_TRUE;
1851 if (!_item_cache_pop(it))
1852 VIEW(it) = _view_create(it, it->itc->item_style);
1854 //TIZEN_ONLY(20161013): clean up elm color class feature
1855 if (it->base->color_classes)
1856 _elm_widget_item_color_class_update(it->base);
1859 treesize = edje_object_data_get(VIEW(it), "treesize");
1862 int tsize = atoi(treesize);
1865 (GL_IT(it->parent)->type == ELM_GENLIST_ITEM_TREE))
1868 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1869 evas_object_color_set(it->spacer, 0, 0, 0, 0);
1870 evas_object_size_hint_min_set
1871 (it->spacer, (GL_IT(it)->expanded_depth * tsize) *
1872 elm_config_scale_get(), 1);
1873 edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1876 _view_inflate(VIEW(it), it, &it->content_objs);
1877 if (wd->scroll_item_align_enable && !calc)
1879 const char *vi_effect = edje_object_data_get(VIEW(it), "vi_effect");
1880 if (vi_effect && !strcmp(vi_effect, "on"))
1882 Evas_Object *clip = evas_object_clip_get(VIEW(it));
1883 if (clip) evas_object_data_set(VIEW(it), "view,clip", clip);
1884 else clip = evas_object_data_get(VIEW(it), "view,clip");
1886 if (!it->item->proxy)
1888 it->item->proxy = evas_object_image_filled_add(evas_object_evas_get(wd->obj));
1889 evas_object_smart_member_add(it->item->proxy, sd->pan_obj);
1891 evas_object_clip_set(it->item->proxy, clip);
1892 if (evas_object_clip_get(VIEW(it))) evas_object_clip_unset(VIEW(it));
1893 evas_object_image_source_set(it->item->proxy, VIEW(it));
1894 evas_object_image_source_visible_set(it->item->proxy, EINA_FALSE);
1895 evas_object_image_source_events_set(it->item->proxy, EINA_TRUE);
1896 evas_object_image_source_clip_set(it->item->proxy, EINA_FALSE);
1897 evas_object_size_hint_min_set(it->item->proxy, GL_IT(it)->w, GL_IT(it)->h);
1898 evas_object_repeat_events_set(it->item->proxy, EINA_TRUE);
1902 _item_mouse_callbacks_add(it, VIEW(it));
1903 // Expand can be supported by only VIEW(it)
1904 _item_edje_callbacks_add(it);
1906 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()))
1907 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
1909 edje_object_signal_emit(VIEW(it), SIGNAL_ENABLED, "elm");
1912 if (!TIZEN_PROFILE_WEARABLE)
1914 if (sd->banded_bg_on)
1915 _banded_item_bg_color_change(it, EINA_TRUE);
1917 edje_object_signal_emit(VIEW(it), SIGNAL_HIGHLIGHTED, "elm");
1918 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
1920 if (GL_IT(it)->expanded)
1921 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
1922 if (sd->reorder_force || sd->reorder_mode)
1923 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
1924 if (GL_IT(it)->expanded_depth > 0)
1925 edje_object_signal_emit(VIEW(it), SIGNAL_BG_CHANGE, "elm");
1928 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_contents,
1930 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
1933 if (elm_widget_focus_highlight_enabled_get(WIDGET(it)) && (it == sd->focused_item))
1935 edje_object_signal_emit(VIEW(it), SIGNAL_FOCUSED, "elm");
1937 if (sd->decorate_all_mode && it->itc->decorate_all_item_style)
1939 _decorate_all_item_realize(it, EINA_FALSE);
1941 else if (it->decorate_it_set && it->itc->decorate_item_style &&
1942 (sd->mode_item == it))
1944 _decorate_item_realize(it);
1946 it->realized = EINA_TRUE;
1949 _elm_genlist_item_index_update(it);
1951 if (it->tooltip.content_cb)
1954 elm_wdg_item_tooltip_content_cb_set(
1955 it->tooltip.content_cb, it->tooltip.data, NULL),
1956 elm_wdg_item_tooltip_style_set(it->tooltip.style),
1957 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
1959 if (it->mouse_cursor)
1960 eo_do(EO_OBJ(it), elm_wdg_item_cursor_set(it->mouse_cursor));
1962 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
1963 if (_elm_atspi_enabled())
1965 elm_interface_atspi_accessible_added(EO_OBJ(it));
1966 elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
1969 if (!TIZEN_PROFILE_WEARABLE)
1970 _banded_item_bg_add(it, VIEW(it));
1972 // Register accessibility before realized callback
1973 // because user can customize accessibility.
1974 _access_widget_item_register(it);
1975 evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, EO_OBJ(it));
1977 edje_object_message_signal_process(VIEW(it));
1978 if (it->deco_all_view)
1979 edje_object_message_signal_process(it->deco_all_view);
1980 if (GL_IT(it)->resized)
1982 sd->queue = eina_list_remove(sd->queue, it);
1983 GL_IT(it)->queued = EINA_FALSE;
1984 GL_IT(it)->resized = EINA_FALSE;
1985 GL_IT(it)->calc_done = EINA_FALSE;
1986 GL_IT(it)->block->calc_done = EINA_FALSE;
1987 sd->calc_done = EINA_FALSE;
1989 if (sd->atspi_item_to_highlight == it)
1991 sd->atspi_item_to_highlight = NULL;
1992 elm_object_accessibility_highlight_set(EO_OBJ(it), EINA_TRUE);
1993 //TIZEN_ONLY(20170724): grab highlight using unrealized item
1994 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it),
1995 ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
1996 evas_object_smart_callback_call(WIDGET(it),
1997 SIG_WIDGET_ATSPI_HIGHLIGHTED, EO_OBJ(it));
2003 _reorder_anim(void *data)
2007 Elm_Genlist_Data *sd = data;
2008 Evas_Coord oy, r_y, r_y_scrl, r_y_scrl_max, r_offset;
2009 evas_object_geometry_get(sd->pan_obj, NULL, &oy, NULL, NULL);
2011 r_y = sd->reorder.it->y + sd->reorder.it->item->block->y;
2012 r_y_scrl = sd->reorder.it->item->scrl_y;
2013 r_y_scrl_max = r_y_scrl + sd->reorder.it->item->h;
2016 // FIXME: 1. Reorder animation time should be equal regardless of item's height
2017 // 2. All item have same animation speed in reordering.
2018 // To support 1 and 2, offset value is scaled to reorder item's height.
2019 r_offset = (Evas_Coord) (GL_IT(sd->reorder.it)->h / REORDER_ANIM_OFFSET);
2020 if (r_offset < REORDER_ANIM_OFFSET) r_offset = REORDER_ANIM_OFFSET;
2023 EINA_LIST_FOREACH(sd->reorder.move_items, l, it)
2025 Evas_Coord it_y, it_y_scrl_center;
2026 it_y = it->y + GL_IT(it)->block->y;
2027 it_y_scrl_center = GL_IT(it)->scrl_y + (GL_IT(it)->h / 2);
2029 if ((sd->reorder.dir == -1) && (r_y_scrl <= it_y_scrl_center))
2030 GL_IT(it)->reorder_offset += r_offset;
2031 else if ((sd->reorder.dir == 1) && (r_y_scrl_max >= it_y_scrl_center))
2032 GL_IT(it)->reorder_offset -= r_offset;
2036 if (sd->reorder.it->item->h < GL_IT(it)->reorder_offset)
2037 GL_IT(it)->reorder_offset = sd->reorder.it->item->h;
2038 else if (0 > GL_IT(it)->reorder_offset)
2039 GL_IT(it)->reorder_offset = 0;
2041 else if (r_y < it_y)
2043 if (-(sd->reorder.it->item->h) > GL_IT(it)->reorder_offset)
2044 GL_IT(it)->reorder_offset = -(sd->reorder.it->item->h);
2045 else if (0 < GL_IT(it)->reorder_offset)
2046 GL_IT(it)->reorder_offset = 0;
2049 if (!sd->reorder.move_items)
2051 sd->reorder.anim = NULL;
2052 return ECORE_CALLBACK_CANCEL;
2055 _changed(sd->pan_obj);
2056 return ECORE_CALLBACK_RENEW;
2060 _reorder_space_get(Elm_Gen_Item *it)
2062 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2063 Evas_Coord oy, r_y, it_y, r_y_scrl, r_y_scrl_max, it_y_center;
2064 evas_object_geometry_get(sd->pan_obj, NULL, &oy, NULL, NULL);
2066 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) return 0;
2067 if (sd->reorder.it->parent != it->parent) return 0;
2069 r_y = sd->reorder.it->y + sd->reorder.it->item->block->y;
2070 it_y = it->y + GL_IT(it)->block->y;
2072 r_y_scrl = sd->reorder.it->item->scrl_y;
2073 r_y_scrl_max = r_y_scrl + sd->reorder.it->item->h;
2074 it_y_center = it_y + (GL_IT(it)->h / 2) - sd->pan_y + oy;
2076 if ((r_y > it_y) && (r_y_scrl <= it_y_center))
2078 if (!eina_list_data_find(sd->reorder.move_items, it))
2079 sd->reorder.move_items = eina_list_append(sd->reorder.move_items, it);
2080 if (!sd->reorder.anim)
2081 sd->reorder.anim = ecore_animator_add(_reorder_anim,
2084 else if ((r_y < it_y) && (r_y_scrl_max >= it_y_center))
2086 if (!eina_list_data_find(sd->reorder.move_items, it))
2087 sd->reorder.move_items = eina_list_append(sd->reorder.move_items, it);
2088 if (!sd->reorder.anim)
2089 sd->reorder.anim = ecore_animator_add(_reorder_anim,
2092 return GL_IT(it)->reorder_offset;
2096 _reorder_calc(Elm_Gen_Item *it, Elm_Genlist_Data *sd)
2098 Elm_Gen_Item *git = NULL;
2099 Elm_Gen_Item *ngit = NULL;
2101 Evas_Coord ox, oy, ow, oh;
2102 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
2104 // Do not cross the parent group items and
2105 // Do not exceeds viewport
2107 ngit = eina_list_data_get(eina_list_next
2108 (eina_list_data_find_list
2109 (sd->group_items, git)));
2110 if (git && git->realized && (GL_IT(it)->scrl_y <= (GL_IT(git)->scrl_y + GL_IT(git)->h)))
2112 GL_IT(it)->scrl_y = GL_IT(git)->scrl_y + GL_IT(git)->h;
2114 else if (ngit && ngit->realized && (GL_IT(it)->scrl_y >= (GL_IT(ngit)->scrl_y - GL_IT(it)->h)))
2116 GL_IT(it)->scrl_y = GL_IT(ngit)->scrl_y - GL_IT(ngit)->h;
2119 if (GL_IT(it)->scrl_y < oy)
2121 GL_IT(it)->scrl_y = oy;
2122 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(sd->pan_x, sd->pan_y
2123 - REORDER_FASTER, ow, oh));
2125 else if (GL_IT(it)->scrl_y + GL_IT(it)->h > oy + oh)
2127 GL_IT(it)->scrl_y = oy + oh - GL_IT(it)->h;
2128 eo_do((sd)->obj, elm_interface_scrollable_content_region_show(sd->pan_x, sd->pan_y
2129 + REORDER_FASTER, ow, oh));
2132 if (TIZEN_PROFILE_WEARABLE)
2134 _item_all_position(it, GL_IT(it)->scrl_x - REORDERED_ITEM_OFFSET,
2135 GL_IT(it)->scrl_y - REORDERED_ITEM_OFFSET);
2139 _item_all_position(it, GL_IT(it)->scrl_x, GL_IT(it)->scrl_y - REORDERED_ITEM_OFFSET);
2142 if (it->deco_all_view)
2143 evas_object_raise(it->deco_all_view);
2144 else if (GL_IT(it)->deco_it_view)
2145 evas_object_raise(GL_IT(it)->deco_it_view);
2147 evas_object_raise(VIEW(it));
2150 #ifdef GENLIST_FX_SUPPORT
2152 _add_fx_anim(void *data)
2154 Elm_Genlist_Data *sd = data;
2159 _changed(sd->pan_obj);
2160 if (sd->add_fx.cnt <= 0)
2162 while (sd->add_fx.items)
2164 it = eina_list_data_get(sd->add_fx.items);
2165 sd->add_fx.items = eina_list_remove(sd->add_fx.items, it);
2166 if (it->deco_all_view)
2167 evas_object_color_set(it->deco_all_view, 255, 255, 255, 255);
2168 else if (it->item->deco_it_view)
2169 evas_object_color_set(it->item->deco_it_view, 255, 255, 255, 255);
2171 evas_object_color_set(VIEW(it), 255, 255, 255, 255);
2173 sd->add_fx.cnt = ANIM_CNT_MAX;
2174 sd->add_fx.anim = NULL;
2175 return ECORE_CALLBACK_CANCEL;
2177 return ECORE_CALLBACK_RENEW;
2181 _add_fx_space_get(Elm_Gen_Item *it)
2184 Elm_Genlist_Data *sd = it->item->wsd;
2185 Evas_Coord size = 0;
2187 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2188 else if (it->item->deco_it_view) evas_object_raise(it->item->deco_it_view);
2189 else if (VIEW(it)) evas_object_raise(VIEW(it));
2191 itt = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
2192 while (itt && itt->realized)
2194 if (eina_list_data_find_list(sd->add_fx.items, itt))
2196 size += itt->item->minh;
2198 itt = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(itt)->prev);
2200 size = size * ((double)sd->add_fx.cnt/ANIM_CNT_MAX);
2205 _del_fx_anim(void *data)
2207 Elm_Genlist_Data *sd = data;
2212 _changed(sd->pan_obj);
2213 if (sd->del_fx.cnt <= 0)
2215 while (sd->del_fx.pending_items)
2217 it = eina_list_data_get(sd->del_fx.pending_items);
2218 sd->del_fx.pending_items = eina_list_remove(sd->del_fx.pending_items, it);
2221 while (sd->del_fx.items)
2223 it = eina_list_data_get(sd->del_fx.items);
2224 sd->del_fx.items = eina_list_remove(sd->del_fx.items, it);
2225 if (it->deco_all_view)
2226 evas_object_color_set(it->deco_all_view, 255, 255, 255, 255);
2227 else if (it->item->deco_it_view)
2228 evas_object_color_set(it->item->deco_it_view, 255, 255, 255, 255);
2230 evas_object_color_set(VIEW(it), 255, 255, 255, 255);
2233 sd->del_fx.cnt = ANIM_CNT_MAX;
2234 sd->del_fx.anim = NULL;
2235 return ECORE_CALLBACK_CANCEL;
2237 return ECORE_CALLBACK_RENEW;
2241 _del_fx_space_get(Elm_Gen_Item *it)
2244 Elm_Genlist_Data *sd = it->item->wsd;
2245 Evas_Coord size = 0;
2247 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2248 else if (it->item->deco_it_view) evas_object_raise(it->item->deco_it_view);
2249 else if (VIEW(it)) evas_object_raise(VIEW(it));
2250 itt = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
2251 while (itt && itt->realized)
2253 if (eina_list_data_find_list(sd->del_fx.items, itt))
2255 size += itt->item->minh;
2257 itt = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(itt)->prev);
2259 size = size * (1 - ((double)sd->del_fx.cnt/ANIM_CNT_MAX));
2265 _item_block_realize(Item_Block *itb, Eina_Bool force)
2267 Elm_Genlist_Data *sd = itb->sd;
2269 Elm_Gen_Item *aligned_item = NULL;
2270 Elm_Gen_Item *top_drawn_item = NULL;
2271 const Eina_List *l, *ll;
2272 Evas_Object *content;
2273 Eina_Bool unrealize = EINA_TRUE;
2274 Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0, cvx = 0, cvy = 0, cvw = 0, cvh = 0;
2275 ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wsd);
2277 // Do not check itb->realized
2278 // because it->item->block can be changed
2280 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
2281 evas_output_viewport_get(evas_object_evas_get(sd->obj),
2282 &cvx, &cvy, &cvw, &cvh);
2284 if (_elm_config->access_mode || _elm_atspi_enabled())
2286 // If access is on, realize more items (3 times)
2290 #ifdef GENLIST_FX_SUPPORT
2291 else if (sd->del_fx.anim)
2294 EINA_LIST_FOREACH(sd->del_fx.items, l, it)
2296 size += it->item->minh;
2300 else if (sd->add_fx.anim)
2303 EINA_LIST_FOREACH(sd->add_fx.items, l, it)
2305 size += it->item->minh;
2311 if (sd->reorder.it) _reorder_calc(sd->reorder.it, sd);
2312 EINA_LIST_FOREACH(itb->items, l, it)
2314 if (sd->reorder.it == it) continue;
2315 if (!it->filtered) _item_filtered_get(it);
2316 if (it->want_hidden)
2318 if (it->realized) evas_object_hide(VIEW(it));
2321 GL_IT(it)->scrl_x = it->x + itb->x - sd->pan_x + ox;
2322 GL_IT(it)->scrl_y = it->y + itb->y - sd->pan_y + oy;
2323 GL_IT(it)->w = sd->minw;
2324 GL_IT(it)->h = GL_IT(it)->minh;
2326 if (!TIZEN_PROFILE_WEARABLE)
2329 if (!top_drawn_item)
2331 if (GL_IT(it)->scrl_y <= oy && ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
2332 GL_IT(it)->w, GL_IT(it)->h, ox, oy, ow, oh))
2334 top_drawn_item = it;
2335 sd->top_drawn_item = top_drawn_item;
2340 if (wsd->scroll_item_align_enable)
2342 if (!sd->aligned_item)
2344 if (ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
2345 GL_IT(it)->w, GL_IT(it)->h,
2346 ox + ow / 2, oy + oh / 2, 1, 1))
2347 aligned_item = sd->aligned_item = it;
2350 if (force || sd->realization_mode ||
2352 (ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
2353 GL_IT(it)->w, GL_IT(it)->h,
2354 cvx, cvy, cvw, cvh)))
2356 if (!it->realized) _item_realize(it, EINA_FALSE);
2358 GL_IT(it)->scrl_y += _reorder_space_get(it);
2359 #ifdef GENLIST_FX_SUPPORT
2360 if (sd->del_fx.anim && !eina_list_data_find(sd->del_fx.items, it))
2361 it->item->scrl_y -= _del_fx_space_get(it);
2362 if (sd->add_fx.anim && !eina_list_data_find(sd->add_fx.items, it))
2363 it->item->scrl_y -= _add_fx_space_get(it);
2366 _item_all_position(it, GL_IT(it)->scrl_x, GL_IT(it)->scrl_y);
2368 else if (it->realized)
2370 /* FIXME: when content is on focused and unrealize item,
2371 focus is set to other object and scroll will be bring in */
2372 if (_elm_config->access_mode)
2374 EINA_LIST_FOREACH(it->content_objs, ll, content)
2376 if (elm_object_focus_get(content))
2378 unrealize = EINA_FALSE;
2384 _item_unrealize(it, EINA_FALSE);
2385 unrealize = EINA_TRUE;
2389 itb->realized = EINA_TRUE;
2391 if (!TIZEN_PROFILE_WEARABLE)
2393 if (sd->banded_bg_on)
2394 _banded_item_bg_index_color_set(sd->top_drawn_item, ox, oy, ow, oh);
2399 edje_object_signal_emit(VIEW(aligned_item), SIGNAL_ITEM_HIGHLIGHTED, "elm");
2400 _focus_bg_show(aligned_item);
2402 edje_object_message_signal_process(VIEW(sd->aligned_item));
2406 // FIXME: Remove below macro after opensource is patched
2407 #define EINA_INLIST_REVERSE_FOREACH_FROM(list, it) \
2408 for (it = NULL, it = (list ? _EINA_INLIST_CONTAINER(it, list) : NULL); \
2409 it; it = (EINA_INLIST_GET(it)->prev ? _EINA_INLIST_CONTAINER(it, EINA_INLIST_GET(it)->prev) : NULL))
2412 _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
2414 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2417 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2418 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2420 //FIXME: This is for optimizing genlist calculation after
2421 // genlist sizing eval properly.
2422 if (ow <= 1) return;
2424 _calc((void *)psd->wsd);
2426 if (_elm_config->access_mode || _elm_atspi_enabled())
2428 // If access is on, realize more items (3 times)
2432 #ifdef GENLIST_FX_SUPPORT
2433 else if (psd->wsd->del_fx.anim)
2438 EINA_LIST_FOREACH(psd->wsd->del_fx.items, l, it)
2440 size += it->item->minh;
2444 else if (psd->wsd->add_fx.anim)
2449 EINA_LIST_FOREACH(psd->wsd->add_fx.items, l, it)
2451 size += it->item->minh;
2457 // Belows are tweaks for performance
2458 // Block is not needed anymore because of below algorithm..
2459 // later, we should remove dirty block algorithm
2460 Eina_Inlist *start = NULL;
2461 Eina_List *realized_new = NULL;
2462 Eina_Bool flag = EINA_FALSE;
2463 if ((psd->wsd->blocks_realized) && (psd->wsd->dir == -1) &&
2464 (!_elm_config->access_mode) && (!_elm_atspi_enabled()))
2466 start = EINA_INLIST_GET((Item_Block *)eina_list_data_get
2467 (eina_list_last(psd->wsd->blocks_realized)));
2468 EINA_INLIST_REVERSE_FOREACH_FROM(start, itb)
2470 Evas_Coord itb_x, itb_y, itb_w, itb_h;
2471 itb_x = itb->x - psd->wsd->pan_x + ox;
2472 itb_y = itb->y - psd->wsd->pan_y + oy;
2473 itb_w = psd->wsd->minw;
2475 if (psd->wsd->realization_mode ||
2476 ELM_RECTS_INTERSECT(itb_x, itb_y, itb_w, itb_h,
2477 cvx, cvy, cvw, cvh))
2480 realized_new = eina_list_prepend(realized_new, itb);
2481 _item_block_realize(itb, EINA_FALSE);
2485 _item_block_unrealize(itb);
2490 else if ((psd->wsd->blocks_realized) && (psd->wsd->dir == 1) &&
2491 (!_elm_config->access_mode) && (!_elm_atspi_enabled()))
2493 start = EINA_INLIST_GET((Item_Block *)eina_list_data_get
2494 (psd->wsd->blocks_realized));
2495 EINA_INLIST_FOREACH(start, itb)
2497 Evas_Coord itb_x, itb_y, itb_w, itb_h;
2498 itb_x = itb->x - psd->wsd->pan_x + ox;
2499 itb_y = itb->y - psd->wsd->pan_y + oy;
2500 itb_w = psd->wsd->minw;
2502 if (psd->wsd->realization_mode ||
2503 ELM_RECTS_INTERSECT(itb_x, itb_y, itb_w, itb_h,
2504 cvx, cvy, cvw, cvh))
2507 realized_new = eina_list_append(realized_new, itb);
2508 _item_block_realize(itb, EINA_FALSE);
2512 _item_block_unrealize(itb);
2519 if (!psd->wsd->show_item)
2521 EINA_INLIST_FOREACH(psd->wsd->blocks, itb)
2523 Evas_Coord itb_x, itb_y, itb_w, itb_h;
2524 itb_x = itb->x - psd->wsd->pan_x + ox;
2525 itb_y = itb->y - psd->wsd->pan_y + oy;
2526 itb_w = psd->wsd->minw;
2528 if (psd->wsd->realization_mode ||
2529 ELM_RECTS_INTERSECT(itb_x, itb_y, itb_w, itb_h,
2530 cvx, cvy, cvw, cvh))
2532 realized_new = eina_list_append(realized_new, itb);
2533 _item_block_realize(itb, EINA_FALSE);
2537 _item_block_unrealize(itb);
2542 eina_list_free(psd->wsd->blocks_realized);
2543 psd->wsd->blocks_realized = realized_new;
2545 // TIZEN_ONLY(20150701) : banded color background feature. enabled only un-scrollable
2546 if (!TIZEN_PROFILE_WEARABLE)
2548 if (psd->wsd->banded_bg_rect && !psd->wsd->reorder.it)
2550 Evas_Coord bg_x, bg_y, bg_w, bg_h, svy, svh;
2551 Elm_Gen_Item *tmp = NULL, *prev = NULL;
2553 tmp = ELM_GEN_ITEM_FROM_INLIST(psd->wsd->items->last);
2557 if (tmp->want_hidden || !tmp->realized )
2558 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
2563 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
2567 if(prev->want_hidden)
2568 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2577 eo_do(psd->wsd->obj, elm_interface_scrollable_content_viewport_geometry_get
2578 (NULL, &svy, NULL, &svh));
2580 bg_x = GL_IT(tmp)->scrl_x;
2581 bg_y = GL_IT(tmp)->scrl_y + GL_IT(tmp)->h;
2582 bg_w = GL_IT(tmp)->w;
2583 bg_h = svy + svh - bg_y;
2585 evas_object_stack_below(psd->wsd->banded_bg_rect, VIEW(tmp));
2586 evas_object_resize(psd->wsd->banded_bg_rect, bg_w, bg_h);
2587 evas_object_move(psd->wsd->banded_bg_rect, bg_x, bg_y);
2589 //GET COLOR OF LAST ITEM AND SET NEXT COLOR TO BANDED BG RECT
2590 if (psd->wsd->banded_bg_on)
2593 index = GL_IT(tmp)->banded_color_index + 1;
2596 int sign = GL_IT(tmp)->banded_color_index - GL_IT(prev)->banded_color_index;
2600 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2604 if(prev->want_hidden)
2605 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2613 sign = GL_IT(tmp)->banded_color_index - GL_IT(prev)->banded_color_index;
2616 index = GL_IT(tmp)->banded_color_index + sign;
2618 if (index < 0) index += 2;
2619 else if (index >= BANDED_MAX_ITEMS)
2620 index = BANDED_MAX_ITEMS - 2;
2623 int alpha = 255 * (1 - 0.04 * index);
2624 int color = (250 * alpha) / 255;
2626 evas_object_color_set(psd->wsd->banded_bg_rect, color, color, color, alpha);
2630 evas_object_color_set
2631 (psd->wsd->banded_bg_rect, 0, 0, 0, 0);
2634 evas_object_show(psd->wsd->banded_bg_rect);
2640 if (psd->wsd->comp_y)
2642 psd->wsd->unhighlight_skip = EINA_TRUE;
2643 eo_do((psd->wsd)->obj, elm_interface_scrollable_content_region_show(psd->wsd->pan_x,
2644 psd->wsd->pan_y + psd->wsd->comp_y, ow, oh));
2645 psd->wsd->comp_y = 0;
2646 psd->wsd->unhighlight_skip = EINA_FALSE;
2648 else if (psd->wsd->expanded_item &&
2649 GL_IT(psd->wsd->expanded_item)->calc_done)
2652 Evas_Coord size = GL_IT(psd->wsd->expanded_item)->minh;
2653 Elm_Object_Item *eo_tmp;
2654 EINA_LIST_FOREACH(psd->wsd->expanded_item->item->items, l, eo_tmp)
2656 ELM_GENLIST_ITEM_DATA_GET(eo_tmp, tmp);
2657 size += GL_IT(tmp)->minh;
2660 elm_genlist_item_bring_in
2661 (EO_OBJ(psd->wsd->expanded_item),
2662 ELM_GENLIST_ITEM_SCROLLTO_TOP);
2665 eo_tmp = eina_list_data_get
2666 (eina_list_last(psd->wsd->expanded_item->item->items));
2669 elm_genlist_item_bring_in(eo_tmp,
2670 ELM_GENLIST_ITEM_SCROLLTO_IN);
2672 psd->wsd->expanded_item = NULL;
2674 if (psd->wsd->show_item &&
2675 !psd->wsd->show_item->item->queued &&
2676 psd->wsd->show_item->item->calc_done &&
2677 psd->wsd->show_item->item->block->calc_done &&
2678 psd->wsd->calc_done)
2680 Evas_Coord x, y, w, h;
2681 Elm_Gen_Item *it = psd->wsd->show_item;
2682 psd->wsd->show_item = NULL;
2683 x = it->x + GL_IT(it)->block->x + psd->wsd->pan_x;
2684 y = it->y + GL_IT(it)->block->y;
2688 switch (psd->wsd->scroll_to_type)
2690 case ELM_GENLIST_ITEM_SCROLLTO_IN:
2694 case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2695 y = y - (oh / 2) + (GL_IT(it)->h / 2);
2698 case ELM_GENLIST_ITEM_SCROLLTO_BOTTOM:
2699 y = y - oh + GL_IT(it)->h;
2705 if (psd->wsd->bring_in)
2706 eo_do(WIDGET(it), elm_interface_scrollable_region_bring_in(x, y, w, h));
2709 if (psd->wsd->aligned_item && (psd->wsd->aligned_item != psd->wsd->adjusted_item))
2710 edje_object_signal_emit(VIEW(psd->wsd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
2711 psd->wsd->aligned_item = NULL;
2712 psd->wsd->unhighlight_skip = EINA_TRUE;
2713 eo_do(WIDGET(it), elm_interface_scrollable_content_region_show(x, y, ow, oh));
2714 psd->wsd->unhighlight_skip = EINA_FALSE;
2717 _changed(psd->wsd->pan_obj);
2719 #ifdef GENLIST_FX_SUPPORT
2720 if (psd->wsd->add_fx.anim)
2725 int alpha = 255 * (1 - ((double)psd->wsd->add_fx.cnt/ANIM_CNT_MAX));
2726 EINA_LIST_FOREACH(psd->wsd->add_fx.items, l, it)
2728 if (!it->realized) continue;
2729 if (it->deco_all_view)
2730 evas_object_color_set(it->deco_all_view, alpha, alpha, alpha, alpha);
2731 else if (it->item->deco_it_view)
2732 evas_object_color_set(it->item->deco_it_view, alpha, alpha, alpha, alpha);
2734 evas_object_color_set(VIEW(it), alpha, alpha, alpha, alpha);
2737 if (psd->wsd->del_fx.anim)
2742 int alpha = 255 * ((double)psd->wsd->del_fx.cnt/ANIM_CNT_MAX);
2743 EINA_LIST_FOREACH(psd->wsd->del_fx.items, l, it)
2745 if (it->deco_all_view)
2746 evas_object_color_set(it->deco_all_view, alpha, alpha, alpha, alpha);
2747 else if (it->item->deco_it_view)
2748 evas_object_color_set(it->item->deco_it_view, alpha, alpha, alpha, alpha);
2750 evas_object_color_set(VIEW(it), alpha, alpha, alpha, alpha);
2754 eo_do(psd->wobj, eo_event_callback_call
2755 (ELM_INTERFACE_SCROLLABLE_EVENT_CHANGED, NULL));
2759 _elm_genlist_pan_eo_base_destructor(Eo *obj, Elm_Genlist_Pan_Data *psd)
2761 eo_data_unref(psd->wobj, psd->wsd);
2762 eo_do_super(obj, MY_PAN_CLASS, eo_destructor());
2766 _elm_genlist_pan_class_constructor(Eo_Class *klass)
2768 evas_smart_legacy_type_register(MY_PAN_CLASS_NAME_LEGACY, klass);
2771 #include "elm_genlist_pan.eo.c"
2773 //#ifdef ELM_FOCUSED_UI
2775 _item_multi_select_up(Elm_Genlist_Data *sd)
2777 Elm_Object_Item *prev;
2779 if (!sd->selected) return EINA_FALSE;
2780 if (!sd->multi) return EINA_FALSE;
2782 prev = elm_genlist_item_prev_get(sd->last_selected_item);
2783 if (!prev) return EINA_TRUE;
2785 if (elm_genlist_item_selected_get(prev))
2787 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2788 sd->last_selected_item = prev;
2789 elm_genlist_item_show
2790 (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2794 elm_genlist_item_selected_set(prev, EINA_TRUE);
2795 elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
2801 _item_multi_select_down(Elm_Genlist_Data *sd)
2803 Elm_Object_Item *next;
2805 if (!sd->selected) return EINA_FALSE;
2806 if (!sd->multi) return EINA_FALSE;
2808 next = elm_genlist_item_next_get(sd->last_selected_item);
2809 if (!next) return EINA_TRUE;
2811 if (elm_genlist_item_selected_get(next))
2813 elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2814 sd->last_selected_item = next;
2815 elm_genlist_item_show
2816 (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2820 elm_genlist_item_selected_set(next, EINA_TRUE);
2821 elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
2828 _all_items_deselect(Elm_Genlist_Data *sd)
2830 if (!sd->selected) return EINA_FALSE;
2832 while (sd->selected)
2833 elm_genlist_item_selected_set(sd->selected->data, EINA_FALSE);
2839 _item_single_select_up(Elm_Genlist_Data *sd)
2841 Elm_Object_Item *eo_prev;
2846 prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2848 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2852 eo_prev = elm_genlist_item_prev_get(sd->last_selected_item);
2853 prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
2856 if (!prev) return EINA_FALSE;
2858 _all_items_deselect(sd);
2860 elm_genlist_item_selected_set(EO_OBJ(prev), EINA_TRUE);
2861 elm_genlist_item_show(EO_OBJ(prev), ELM_GENLIST_ITEM_SCROLLTO_IN);
2866 _item_single_select_down(Elm_Genlist_Data *sd)
2868 Elm_Object_Item *eo_next;
2873 next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2875 next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2879 eo_next = elm_genlist_item_next_get(sd->last_selected_item);
2880 next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2883 if (!next) return EINA_FALSE;
2885 _all_items_deselect(sd);
2887 elm_genlist_item_selected_set(EO_OBJ(next), EINA_TRUE);
2888 elm_genlist_item_show
2889 (EO_OBJ(next), ELM_GENLIST_ITEM_SCROLLTO_IN);
2895 static void _item_unfocused(Elm_Gen_Item *it)
2898 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2899 if (!sd->focused_item || it != sd->focused_item) return;
2901 edje_object_signal_emit
2902 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
2903 if (sd->focused_item->deco_all_view)
2904 edje_object_signal_emit
2905 (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
2906 sd->focused_item = NULL;
2907 evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_UNFOCUSED, EO_OBJ(it));
2910 static void _item_focused(Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
2912 Evas_Coord x, y, w, h, sx, sy, sw, sh;
2914 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2916 evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
2917 evas_object_geometry_get(sd->obj, &sx, &sy, &sw, &sh);
2918 if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
2920 elm_genlist_item_bring_in(EO_OBJ(it), type);
2923 if (elm_widget_focus_highlight_enabled_get(sd->obj))
2925 if (it->deco_all_view)
2926 edje_object_signal_emit
2927 (it->deco_all_view, SIGNAL_FOCUSED, "elm");
2929 edje_object_signal_emit
2930 (VIEW(it), SIGNAL_FOCUSED, "elm");
2933 sd->focused_item = it;
2934 evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_FOCUSED, EO_OBJ(it));
2935 if (_elm_atspi_enabled())
2936 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), EO_OBJ(it));
2940 _banded_item_highlight_anim(void *data, double pos)
2942 Elm_Gen_Item *it = data;
2944 double v[4] = {0.25, 0.46, 0.45, 1.00};
2946 if (GL_IT(it)->banded_bg)
2949 frame = ecore_animator_pos_map_n(pos, ECORE_POS_MAP_CUBIC_BEZIER, 4, v);
2951 it->item->banded_anim = NULL;
2953 if (it->highlighted)
2954 frame = HIGHLIGHT_ALPHA_MAX + (1.0 - HIGHLIGHT_ALPHA_MAX) * (1.0 - frame);
2956 frame = HIGHLIGHT_ALPHA_MAX + (1.0 - HIGHLIGHT_ALPHA_MAX) * frame;
2958 int alpha = 255 * frame * (1 - 0.04 * GL_IT(it)->banded_color_index);
2961 color = (color * alpha) / 255;
2962 evas_object_color_set(GL_IT(it)->banded_bg, color, color, color, alpha);
2969 _item_highlight(Elm_Gen_Item *it)
2971 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2972 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wsd);
2975 if (!sd->highlight) return;
2976 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get())) return;
2977 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2978 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ) ||
2979 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2980 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
2982 if (it->highlighted) return;
2983 if (wsd->scroll_item_align_enable)
2985 if (sd->aligned_item == it)
2986 edje_object_signal_emit(wsd->resize_obj, SIGNAL_HIGHLIGHTED, "elm");
2991 it->highlighted = EINA_TRUE;
2992 sd->highlighted_item = it;
2994 if (!it->realized) goto end;
2996 if (!TIZEN_PROFILE_WEARABLE)
2998 if (sd->banded_bg_on)
3000 if (it->item->banded_anim) ecore_animator_del(it->item->banded_anim);
3001 it->item->banded_anim = ecore_animator_timeline_add(ELM_ITEM_HIGHLIGHT_TIMER, _banded_item_highlight_anim, it);
3004 if (it->deco_all_view)
3006 edje_object_signal_emit(it->deco_all_view, SIGNAL_HIGHLIGHTED, "elm");
3007 edje_object_message_signal_process(it->deco_all_view);
3009 edje_object_signal_emit(VIEW(it), SIGNAL_HIGHLIGHTED, "elm");
3010 edje_object_message_signal_process(VIEW(it));
3012 //***************** TIZEN Only
3013 // If check or radio is used on genlist item, highlight it also.
3015 Evas_Object *content;
3016 if (sd->decorate_all_mode)
3018 EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, content)
3020 const char *type = elm_widget_type_get(content);
3021 if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3022 elm_object_signal_emit(content, "elm,state,mouse,down", "elm");
3027 EINA_LIST_FOREACH(it->content_objs, l, content)
3029 const char *type = elm_widget_type_get(content);
3030 if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3031 elm_object_signal_emit(content, "elm,state,mouse,down", "elm");
3034 //****************************
3036 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
3037 if (_elm_atspi_enabled())
3038 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), EO_OBJ(it));
3042 _item_unhighlight(Elm_Gen_Item *it, Eina_Bool effect EINA_UNUSED)
3044 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wsd);
3045 if (!it->highlighted) return;
3047 it->highlighted = EINA_FALSE;
3048 GL_IT(it)->wsd->highlighted_item = NULL;
3050 if (!it->realized) goto end;
3052 if (!TIZEN_PROFILE_WEARABLE)
3054 if (GL_IT(it)->wsd->banded_bg_on && effect)
3056 if (it->item->banded_anim) ecore_animator_del(it->item->banded_anim);
3057 it->item->banded_anim = ecore_animator_timeline_add(ELM_ITEM_HIGHLIGHT_TIMER, _banded_item_highlight_anim, it);
3061 if (it->item->banded_anim) ELM_SAFE_FREE(it->item->banded_anim, ecore_animator_del);
3062 _banded_item_bg_color_change(it, EINA_FALSE);
3065 if (it->deco_all_view)
3066 edje_object_signal_emit(it->deco_all_view, SIGNAL_UNHIGHLIGHTED, "elm");
3067 edje_object_signal_emit(VIEW(it), SIGNAL_UNHIGHLIGHTED, "elm");
3068 if (wsd->scroll_item_align_enable)
3069 edje_object_signal_emit(wsd->resize_obj, SIGNAL_UNHIGHLIGHTED, "elm");
3071 edje_object_signal_emit(VIEW(it), SIGNAL_UNHIGHLIGHTED, "elm");
3072 //******************** TIZEN Only
3073 // If check is used on genlist item, unhighlight it also.
3075 Evas_Object *content;
3076 if (GL_IT(it)->wsd->decorate_all_mode)
3078 EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, content)
3080 const char *type = elm_widget_type_get(content);
3081 if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3082 elm_object_signal_emit(content, "elm,state,mouse,up", "elm");
3087 EINA_LIST_FOREACH(it->content_objs, l, content)
3089 const char *type = elm_widget_type_get(content);
3090 if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3091 elm_object_signal_emit(content, "elm,state,mouse,up", "elm");
3094 //*******************************
3096 evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, EO_OBJ(it));
3100 _item_unselect(Elm_Gen_Item *it)
3102 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
3104 if (!it->selected) return;
3106 it->selected = EINA_FALSE;
3107 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
3108 _item_unhighlight(it, EINA_TRUE);
3109 evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, EO_OBJ(it));
3113 _item_select(Elm_Gen_Item *it)
3115 Evas_Object *obj = WIDGET(it);
3116 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
3118 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get())) return;
3119 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3120 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
3121 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3122 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
3124 if (sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS &&
3125 it->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS &&
3130 const Eina_List *l, *ll;
3131 Elm_Object_Item *eo_it2;
3132 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it2)
3133 if (eo_it2 != EO_OBJ(it))
3135 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
3136 _item_unselect(it2);
3142 sd->selected = eina_list_append(sd->selected, EO_OBJ(it));
3143 it->selected = EINA_TRUE;
3145 sd->last_selected_item = EO_OBJ(it);
3146 _item_highlight(it);
3148 if (sd->focused_content)
3150 elm_object_focus_set(sd->focused_content, EINA_FALSE);
3151 evas_object_focus_set(obj, EINA_TRUE);
3152 sd->focused_content = NULL;
3155 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3156 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3160 // FIXME: after evas_object_raise, mouse event callbacks(ex, UP, DOWN)
3161 // can be called again eventhough already received it.
3162 const char *selectraise = edje_object_data_get(VIEW(it), "selectraise");
3163 if ((selectraise) && (!strcmp(selectraise, "on")))
3165 if (it->deco_all_view) evas_object_raise(it->deco_all_view);
3166 else evas_object_raise(VIEW(it));
3167 if ((GL_IT(it)->group_item) && (GL_IT(it)->group_item->realized))
3168 evas_object_raise(GL_IT(it)->VIEW(group_item));
3171 edje_object_signal_emit
3172 (VIEW(it), SIGNAL_CLICKED, "elm");
3173 edje_object_message_signal_process(VIEW(it));
3175 evas_object_ref(obj);
3176 if (it->func.func) it->func.func((void *)it->func.data, obj, EO_OBJ(it));
3177 if (EINA_MAGIC_CHECK(it->base, ELM_WIDGET_ITEM_MAGIC))
3178 evas_object_smart_callback_call(obj, SIG_SELECTED, EO_OBJ(it));
3179 evas_object_unref(obj);
3183 _highlight_timer(void *data)
3185 Elm_Gen_Item *it = data;
3186 GL_IT(it)->highlight_timer = NULL;
3187 _item_highlight(it);
3192 _select_timer(void *data)
3194 Elm_Gen_Item *it = data;
3195 GL_IT(it)->highlight_timer = NULL;
3197 if ((GL_IT(it)->wsd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS) ||
3198 (it->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS))
3202 // TIZEN Only(20150708) : unselect when selected item is selected again
3203 // There need to be implemented 'SELECT_UNSELECT' mode in elm_config
3204 // select mode for support upsteam and TIZEN both.
3205 if (!it->selected) _item_select(it);
3206 else _item_unselect(it);
3214 *_item_focusable_content_search(Evas_Object *obj, Eina_List *l, int dir)
3216 if ((dir != 1) && (dir != -1)) return NULL;
3218 Evas_Object *next = NULL;
3219 Elm_Object_Item *next_item = NULL;
3223 next = eina_list_data_get(l);
3224 if (next && (elm_widget_can_focus_get(next) &&
3225 (evas_object_visible_get(next))))
3227 else if (next && (elm_widget_child_can_focus_get(next)))
3229 if (elm_widget_focused_object_get(next))
3233 Evas_Object *child = next;
3235 (elm_widget_focus_next_get(next, ELM_FOCUS_RIGHT, &child, &next_item)))
3237 else if ((dir == -1) &&
3238 (elm_widget_focus_next_get(next, ELM_FOCUS_LEFT, &child, &next_item)))
3244 if (dir == 1) l = eina_list_next(l);
3245 else l = eina_list_prev(l);
3248 if (!next) next = obj;
3253 static Eina_Bool _item_focusable_search(Elm_Gen_Item **it, int dir)
3255 if (!(*it)) return EINA_FALSE;
3256 if ((dir != 1) && (dir != -1)) return EINA_FALSE;
3258 Elm_Gen_Item *tmp = *it;
3262 if (!elm_object_item_disabled_get(EO_OBJ(tmp)) &&
3263 (!tmp->want_hidden))
3265 if ((tmp->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
3266 (tmp->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3269 Evas_Object *obj = NULL;
3270 Eina_List *contents = NULL;
3272 contents = GL_IT(tmp)->flip_content_objs;
3275 contents = tmp->content_objs;
3276 if (tmp->deco_all_view)
3279 contents = GL_IT(tmp)->deco_all_contents;
3281 contents = eina_list_merge(contents,
3282 GL_IT(tmp)->deco_all_contents);
3287 obj = _item_focusable_content_search(NULL, contents, 1);
3290 contents = eina_list_last(contents);
3291 obj = _item_focusable_content_search(NULL, contents, -1);
3296 if (GL_IT(tmp)->wsd->focused_content)
3297 elm_object_focus_set(GL_IT(tmp)->wsd->focused_content, EINA_FALSE);
3298 GL_IT(tmp)->wsd->focused_content = obj;
3299 elm_object_focus_set(obj, EINA_TRUE);
3304 if (GL_IT(tmp)->wsd->focused_content)
3306 elm_object_focus_set(GL_IT(tmp)->wsd->focused_content, EINA_FALSE);
3307 evas_object_focus_set(WIDGET(tmp), EINA_TRUE);
3308 GL_IT(tmp)->wsd->focused_content = NULL;
3314 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->next);
3316 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
3323 static Eina_Bool _item_focus_next(Elm_Genlist_Data *sd, Focus_Dir dir)
3325 Elm_Gen_Item *it = NULL;
3326 Elm_Gen_Item *old_focused = sd->focused_item;
3327 Evas_Object *old_content = sd->focused_content;
3329 if (dir == FOCUS_DIR_DOWN || dir == FOCUS_DIR_UP)
3331 Eina_Bool find_item;
3333 if (dir == FOCUS_DIR_DOWN)
3335 if (sd->focused_item)
3337 it = ELM_GEN_ITEM_FROM_INLIST
3338 (EINA_INLIST_GET(sd->focused_item)->next);
3339 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3341 else it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
3342 find_item = _item_focusable_search(&it, 1);
3344 else if (dir == FOCUS_DIR_UP)
3346 if (sd->focused_item)
3348 it = ELM_GEN_ITEM_FROM_INLIST
3349 (EINA_INLIST_GET(sd->focused_item)->prev);
3350 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3352 else it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
3353 find_item = _item_focusable_search(&it, -1);
3362 sd->focused_content = old_content;
3363 elm_object_focus_set(old_content, EINA_TRUE);
3367 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3368 elm_object_item_focus_set(EO_OBJ(old_focused), EINA_TRUE);
3373 else if (!find_item)
3376 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3377 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3379 else if (dir == FOCUS_DIR_LEFT || dir == FOCUS_DIR_RIGHT)
3381 Evas_Object *obj = NULL;
3382 Eina_List *contents = NULL;
3383 Eina_List *l = NULL;
3385 if (!sd->focused_item) return EINA_FALSE;
3386 if (sd->focused_item->flipped)
3387 contents = GL_IT(sd->focused_item)->flip_content_objs;
3390 contents = sd->focused_item->content_objs;
3391 if (sd->focused_item->deco_all_view)
3394 contents = GL_IT(sd->focused_item)->deco_all_contents;
3396 contents = eina_list_merge(contents,
3397 GL_IT(sd->focused_item)->deco_all_contents);
3401 if (sd->focused_content)
3403 l = eina_list_data_find_list(contents,
3404 sd->focused_content);
3405 obj = sd->focused_content;
3408 if (dir == FOCUS_DIR_LEFT)
3410 if ((l) && (eina_list_prev(l)))
3412 l = eina_list_prev(l);
3413 obj = _item_focusable_content_search(obj, l, -1);
3414 if (!obj) obj = sd->focused_content;
3418 //search focused content is child of content
3419 if (sd->focused_content)
3420 l = eina_list_data_find_list(contents,
3421 sd->focused_content);
3422 if (!l) l = eina_list_last(contents);
3423 obj = _item_focusable_content_search(obj, l, -1);
3425 else obj = sd->focused_content;
3427 else if (dir == FOCUS_DIR_RIGHT)
3429 if ((l) && (eina_list_next(l)))
3431 l = eina_list_next(l);
3432 obj = _item_focusable_content_search(obj, l, 1);
3433 if (!obj) obj = sd->focused_content;
3437 //search focused content is child of content
3438 if (sd->focused_content)
3439 l = eina_list_data_find_list(contents,
3440 sd->focused_content);
3441 if (!l) l = contents;
3442 obj = _item_focusable_content_search(obj, l, 1);
3444 else obj = sd->focused_content;
3449 sd->focused_content = obj;
3450 elm_object_focus_set(obj, EINA_TRUE);
3454 sd->focused_content = NULL;
3458 else return EINA_FALSE;
3463 //#ifdef ELM_FOCUSED_UI
3464 EOLIAN static Eina_Bool
3465 _elm_genlist_elm_widget_event(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *src EINA_UNUSED, Evas_Callback_Type type, void *event_info)
3471 Evas_Coord step_x = 0;
3472 Evas_Coord step_y = 0;
3473 Evas_Coord page_x = 0;
3474 Evas_Coord page_y = 0;
3475 Evas_Event_Key_Down *ev = event_info;
3476 Evas_Coord pan_max_x = 0, pan_max_y = 0;
3478 //ELM_GENLIST_DATA_GET(obj, sd);
3480 // TIZEN ONLY(20131221) : When access mode, focused ui is disabled.
3481 if (_elm_config->access_mode) return EINA_FALSE;
3483 if ((type != EVAS_CALLBACK_KEY_DOWN) && (type != EVAS_CALLBACK_KEY_UP))
3485 if (!sd->items) return EINA_FALSE;
3486 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
3487 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
3490 elm_interface_scrollable_content_pos_get(&x, &y),
3491 elm_interface_scrollable_step_size_get(&step_x, &step_y),
3492 elm_interface_scrollable_page_size_get(&page_x, &page_y),
3493 elm_interface_scrollable_content_viewport_geometry_get
3494 (NULL, NULL, &v_w, &v_h));
3496 if ((!strcmp(ev->keyname, "Left")) ||
3497 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)) ||
3498 (!strcmp(ev->keyname, "Right")) ||
3499 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)) ||
3500 (!strcmp(ev->keyname, "Up")) ||
3501 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)) ||
3502 (!strcmp(ev->keyname, "Down")) ||
3503 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)) ||
3504 (!strcmp(ev->keyname, "Home")) ||
3505 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)) ||
3506 (!strcmp(ev->keyname, "End")) ||
3507 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)) ||
3508 (!strcmp(ev->keyname, "Prior")) ||
3509 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)) ||
3510 (!strcmp(ev->keyname, "Next")) ||
3511 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
3513 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3514 _elm_widget_focus_auto_show(obj);
3517 if ((!strcmp(ev->keyname, "Left")) ||
3518 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
3520 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3521 if (sd->select_on_focus_enabled) x -= step_x;
3524 if (_item_focus_next(sd, FOCUS_DIR_LEFT))
3526 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3533 else if ((!strcmp(ev->keyname, "Right")) ||
3534 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
3536 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3537 if (sd->select_on_focus_enabled) x += step_x;
3540 if (_item_focus_next(sd, FOCUS_DIR_RIGHT))
3542 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3549 else if ((!strcmp(ev->keyname, "Up")) ||
3550 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
3552 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3553 if (sd->select_on_focus_enabled)
3555 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
3556 (_item_multi_select_up(sd))) || (_item_single_select_up(sd)))
3558 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3564 if (_item_focus_next(sd, FOCUS_DIR_UP))
3566 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3573 else if ((!strcmp(ev->keyname, "Down")) ||
3574 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
3576 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3577 if (sd->select_on_focus_enabled)
3579 if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
3580 (_item_multi_select_down(sd))) ||
3581 (_item_single_select_down(sd)))
3583 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3589 if (_item_focus_next(sd, FOCUS_DIR_DOWN))
3591 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3598 else if ((!strcmp(ev->keyname, "Home")) ||
3599 ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
3601 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3602 if (sd->select_on_focus_enabled)
3604 Elm_Object_Item *it = elm_genlist_first_item_get(obj);
3605 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
3606 elm_genlist_item_selected_set(it, EINA_TRUE);
3607 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3611 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3612 _item_focus_next(sd, FOCUS_DIR_DOWN);
3613 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3617 else if ((!strcmp(ev->keyname, "End")) ||
3618 ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
3620 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3621 if (sd->select_on_focus_enabled)
3623 Elm_Object_Item *it = elm_genlist_last_item_get(obj);
3624 elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
3625 elm_genlist_item_selected_set(it, EINA_TRUE);
3629 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3630 sd->focused_item = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
3631 _item_focus_next(sd, FOCUS_DIR_UP);
3633 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3636 else if ((!strcmp(ev->keyname, "Prior")) ||
3637 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
3639 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3640 Elm_Gen_Item *it = sd->focused_item;
3641 Elm_Object_Item *eo_prev;
3643 while (page_y <= v_h)
3645 if (elm_genlist_item_prev_get(EO_OBJ(it)))
3647 eo_prev = elm_genlist_item_prev_get(EO_OBJ(it));
3648 it = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
3651 page_y += GL_IT(it)->minh;
3653 if (_item_focusable_search(&it, -1))
3655 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3656 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3660 _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);
3665 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3668 else if ((!strcmp(ev->keyname, "Next")) ||
3669 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
3671 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3672 Elm_Gen_Item *it = sd->focused_item;
3673 Elm_Object_Item *eo_next;
3675 page_y = GL_IT(it)->minh;
3677 while (page_y <= v_h)
3679 if (elm_genlist_item_next_get(EO_OBJ(it)))
3681 eo_next = elm_genlist_item_next_get(EO_OBJ(it));
3682 it = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
3685 page_y += GL_IT(it)->minh;
3687 if (_item_focusable_search(&it, 1))
3689 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3690 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3694 _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);
3699 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3700 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3702 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3705 else if (!strcmp(ev->keyname, "Escape"))
3707 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3708 if (!_all_items_deselect(sd)) return EINA_FALSE;
3709 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3712 else if (!strcmp(ev->keyname, "Return") ||
3713 !strcmp(ev->keyname, "KP_Enter") ||
3714 !strcmp(ev->keyname, "space"))
3717 if (type == EVAS_CALLBACK_KEY_DOWN && !sd->key_down_item)
3719 if (sd->focused_item)
3721 sd->key_down_item = sd->focused_item;
3723 edje_object_signal_emit
3724 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
3725 if (sd->focused_item->deco_all_view)
3726 edje_object_signal_emit
3727 (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
3729 _item_highlight(sd->key_down_item);
3730 if (sd->key_down_item->long_timer)
3731 ecore_timer_del(sd->key_down_item->long_timer);
3732 sd->key_down_item->long_timer = ecore_timer_add
3733 (sd->longpress_timeout,
3734 _long_press_cb, sd->key_down_item);
3735 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3736 evas_object_smart_callback_call(obj, SIG_ACTIVATED, EO_OBJ(sd->key_down_item));
3739 else return EINA_FALSE;
3741 else if (type == EVAS_CALLBACK_KEY_UP && sd->key_down_item)
3743 edje_object_signal_emit
3744 (VIEW(sd->key_down_item), SIGNAL_FOCUSED, "elm");
3745 if (sd->key_down_item->deco_all_view)
3746 edje_object_signal_emit
3747 (sd->key_down_item->deco_all_view, SIGNAL_FOCUSED, "elm");
3749 if (sd->key_down_item->long_timer)
3750 ecore_timer_del(sd->key_down_item->long_timer);
3751 sd->key_down_item->long_timer = NULL;
3752 if (GL_IT(sd->key_down_item)->highlight_timer)
3753 ecore_timer_del(GL_IT(sd->key_down_item)->highlight_timer);
3754 GL_IT(sd->key_down_item)->highlight_timer = ecore_timer_add
3755 (ITEM_SELECT_TIMER, _select_timer, sd->key_down_item);
3756 sd->key_down_item = NULL;
3757 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3760 else return EINA_FALSE;
3762 else return EINA_FALSE;
3764 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3765 eo_do(sd->pan_obj, elm_obj_pan_pos_max_get(&pan_max_x, &pan_max_y));
3767 if (x > pan_max_x) x = pan_max_x;
3769 if (y > pan_max_y) y = pan_max_y;
3771 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
3777 /* This function disables the specific code of the layout sub object add.
3778 * Only the widget sub_object_add is called.
3780 EOLIAN static Eina_Bool
3781 _elm_genlist_elm_layout_sub_object_add_enable(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3786 EOLIAN static Eina_Bool
3787 _elm_genlist_elm_widget_sub_object_add(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED, Evas_Object *sobj)
3789 Eina_Bool int_ret = EINA_FALSE;
3791 /* skipping layout's code, which registers size hint changing
3792 * callback on sub objects. this is here because items'
3793 * content_get() routines may change hints on the objects after
3794 * creation, thus issuing TOO MANY sizing_eval()'s here. they are
3795 * not needed at here anyway, so let's skip listening to those
3798 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_add(sobj));
3799 if (!int_ret) return EINA_FALSE;
3801 //if (!parent_parent->sub_object_add(obj, sobj))
3802 // return EINA_FALSE;
3807 EOLIAN static Eina_Bool
3808 _elm_genlist_elm_widget_sub_object_del(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *sobj)
3810 Eina_Bool int_ret = EINA_FALSE;
3812 /* XXX: hack -- also skipping sizing recalculation on
3813 * sub-object-del. genlist's crazy code paths (like groups and
3814 * such) seem to issue a whole lot of deletions and Evas bitches
3815 * about too many recalculations */
3816 sd->on_sub_del = EINA_TRUE;
3818 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_del(sobj));
3819 if (!int_ret) return EINA_FALSE;
3821 sd->on_sub_del = EINA_FALSE;
3827 _elm_genlist_focus_highlight_show(void *data EINA_UNUSED,
3829 const char *emission EINA_UNUSED,
3830 const char *src EINA_UNUSED)
3832 ELM_GENLIST_DATA_GET(obj, sd);
3834 if (sd->focused_item)
3836 if (!sd->focused_content)
3838 Eina_Bool found = EINA_FALSE;
3839 Elm_Gen_Item *it = sd->focused_item;
3840 found = _item_focusable_search(&it, 1);
3843 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3844 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3847 else elm_object_focus_set(sd->focused_content, EINA_TRUE);
3852 _elm_genlist_focus_highlight_hide(void *data EINA_UNUSED,
3854 const char *emission EINA_UNUSED,
3855 const char *src EINA_UNUSED)
3857 ELM_GENLIST_DATA_GET(obj, sd);
3858 if (sd->focused_item)
3860 // Do not use _item_unfocused because focus should be remained
3861 edje_object_signal_emit
3862 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
3863 if (sd->focused_item->deco_all_view)
3864 edje_object_signal_emit
3865 (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
3870 _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)
3872 Evas_Coord ox, oy, oh, ow, item_x = 0, item_y = 0, item_w = 0, item_h = 0;
3873 Elm_Gen_Item *focus_it;
3875 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
3877 if (sd->focused_item)
3879 focus_it = sd->focused_item;
3880 evas_object_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
3881 elm_widget_focus_highlight_focus_part_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
3893 if (item_y > (oy + oh - item_h))
3895 *y = oy + oh - item_h;
3898 if ((item_x + item_w) > (ox + ow))
3908 EOLIAN static Eina_Bool
3909 _elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd, Elm_Object_Item *item EINA_UNUSED)
3911 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
3912 Eina_Bool int_ret = EINA_FALSE;
3914 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_on_focus(NULL));
3915 if (!int_ret) return EINA_FALSE;
3917 if ((sd->items) && (sd->selected) && (!sd->last_selected_item))
3918 sd->last_selected_item = eina_list_data_get(sd->selected);
3920 if (sd->select_on_focus_enabled) return EINA_TRUE;
3921 if (elm_widget_focus_get(obj))
3923 // Do nothing if on_focus is called by child's parent_focus
3924 if (!wd->is_focus_target) return EINA_TRUE;
3926 if (sd->focused_item)
3928 if (!sd->focused_content)
3930 Eina_Bool found = EINA_FALSE;
3931 Elm_Gen_Item *it = sd->focused_item;
3932 found = _item_focusable_search(&it, 1);
3935 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3936 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3940 elm_object_focus_set(sd->focused_content, EINA_TRUE);
3944 Item_Block *itb, *nib;
3945 EINA_INLIST_FOREACH(sd->blocks, itb)
3949 Elm_Gen_Item *tmp = eina_list_data_get(itb->items);
3950 while(tmp && tmp->item->block == itb)
3954 Elm_Gen_Item *old = tmp;
3955 Evas_Coord x, y, w, h, sx, sy, sw, sh;
3956 evas_object_geometry_get(VIEW(tmp), &x, &y, &w, &h);
3957 evas_object_geometry_get(obj, &sx, &sy, &sw, &sh);
3958 /* Item is included viewport and focusable */
3959 if ((ELM_RECTS_INCLUDE(sx, sy, sw, sh, x, y, w, h)) &&
3960 (_item_focusable_search(&tmp, 1)))
3962 Eina_Bool include = EINA_TRUE;
3963 if (old != tmp && tmp->realized)
3965 evas_object_geometry_get(VIEW(tmp), &x, &y, &w, &h);
3966 evas_object_geometry_get(obj, &sx, &sy, &sw, &sh);
3967 include = ELM_RECTS_INCLUDE(sx, sy, sw, sh, x, y, w, h);
3969 else if (!tmp->realized) include = EINA_FALSE;
3973 elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
3980 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->next);
3983 nib = EINA_INLIST_CONTAINER_GET(EINA_INLIST_GET(itb)->next, Item_Block);
3984 if (!nib || !nib->realized) break;
3987 if (!sd->focused_item) _item_focus_next(sd, FOCUS_DIR_DOWN);
3992 // when key down and not called key up
3993 // and focus is not on genlist, call select_timer forcely
3994 if (sd->key_down_item)
3996 _select_timer(sd->key_down_item);
3997 sd->key_down_item = NULL;
4000 if (sd->focused_item)
4002 if (sd->focused_content)
4004 //FIXME: when genlist contents loose their focus,
4005 // focus unset should automatically work.
4006 elm_object_focus_set(sd->focused_content, EINA_FALSE);
4008 // Do not use _item_unfocused because focus should be remained
4009 edje_object_signal_emit
4010 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
4011 if (sd->focused_item->deco_all_view)
4012 edje_object_signal_emit
4013 (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
4021 _elm_genlist_item_elm_widget_item_focus_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool focused)
4023 Evas_Object *obj = WIDGET(it);
4024 ELM_GENLIST_DATA_GET(obj, sd);
4028 if (!elm_object_focus_get(obj))
4029 elm_object_focus_set(obj, EINA_TRUE);
4031 if (!elm_widget_focus_get(obj))
4034 if (sd->focused_content)
4036 elm_object_focus_set(sd->focused_content, EINA_FALSE);
4037 sd->focused_content = NULL;
4040 if (it != sd->focused_item)
4042 if (sd->focused_item)
4043 _item_unfocused(sd->focused_item);
4044 _item_focused(it, sd->focus_scrollto_type);
4046 /* If item is not realized state, widget couldn't get focus_highlight data. */
4049 _elm_widget_item_highlight_in_theme(obj, EO_OBJ(it));
4050 _elm_widget_highlight_in_theme_update(obj);
4051 _elm_widget_focus_highlight_start(obj);
4057 if (!elm_widget_focus_get(obj))
4059 _item_unfocused(it);
4063 EOLIAN static Eina_Bool
4064 _elm_genlist_item_elm_widget_item_focus_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
4066 Evas_Object *obj = WIDGET(it);
4067 ELM_GENLIST_DATA_GET(obj, sd);
4069 if (it == sd->focused_item)
4075 EOLIAN static Elm_Object_Item*
4076 _elm_genlist_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
4078 return EO_OBJ(sd->focused_item);
4081 static Eina_Bool _elm_genlist_smart_focus_next_enable = EINA_FALSE;
4083 EOLIAN static Eina_Bool
4084 _elm_genlist_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
4086 return _elm_genlist_smart_focus_next_enable;
4089 EOLIAN static Eina_Bool
4090 _elm_genlist_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
4095 EOLIAN static Eina_Bool
4096 _elm_genlist_elm_widget_focus_next(Eo *obj, Elm_Genlist_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
4098 Eina_List *items = NULL;
4099 Item_Block *itb = NULL;
4100 Elm_Object_Item *eo_it = NULL;
4102 if (!sd->blocks) return EINA_FALSE;
4103 if (!sd->is_access) return EINA_FALSE;
4105 if (!elm_widget_highlight_get(obj))
4107 if (ELM_FOCUS_PREVIOUS == dir)
4109 eo_it = elm_genlist_last_item_get(obj);
4110 itb = EINA_INLIST_CONTAINER_GET(sd->blocks->last, Item_Block);
4112 else if (ELM_FOCUS_NEXT == dir)
4114 eo_it = elm_genlist_first_item_get(obj);
4115 itb = EINA_INLIST_CONTAINER_GET(sd->blocks, Item_Block);
4117 else return EINA_FALSE;
4119 if (eo_it && itb && itb->calc_done)
4121 _item_block_realize(itb, EINA_TRUE);
4122 elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
4124 else return EINA_FALSE;
4127 // FIXME: do not use realized items get
4128 // because of above forcing realization case.
4129 EINA_INLIST_FOREACH(sd->blocks, itb)
4134 if (!itb->realized) continue;
4136 EINA_LIST_FOREACH(itb->items, l, it)
4139 Evas_Object *c, *ret;
4142 if (!(it->realized)) continue;
4144 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_access_object_get()))
4145 items = eina_list_append(items, eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_access_object_get()));
4147 items = eina_list_append(items, VIEW(it));
4149 orders = (Eina_List *)elm_object_item_access_order_get(EO_OBJ(it));
4150 EINA_LIST_FOREACH(orders, ll, c)
4152 items = eina_list_append(items, c);
4157 return elm_widget_focus_list_next_get
4158 (obj, items, eina_list_data_get, dir, next, next_item);
4162 _mirrored_set(Evas_Object *obj,
4165 eo_do(obj, elm_interface_scrollable_mirrored_set(rtl));
4168 EOLIAN static Elm_Theme_Apply
4169 _elm_genlist_elm_widget_theme_apply(Eo *obj, Elm_Genlist_Data *sd)
4172 Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
4173 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wsd, ELM_THEME_APPLY_FAILED);
4175 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
4176 if (!int_ret) return ELM_THEME_APPLY_FAILED;
4178 if (!TIZEN_PROFILE_WEARABLE)
4179 _banded_bg_state_check(obj, sd);
4181 EINA_INLIST_FOREACH(sd->blocks, itb)
4185 EINA_LIST_FOREACH(itb->items, l, it)
4189 _item_unrealize(it, EINA_FALSE);
4190 GL_IT(it)->calc_done = EINA_FALSE;
4191 GL_IT(it)->block->calc_done = EINA_FALSE;
4193 else _item_queue(it, NULL);
4196 sd->calc_done = EINA_FALSE;
4197 _item_cache_all_free(sd);
4198 eina_hash_free_buckets(sd->size_caches);
4199 elm_layout_sizing_eval(obj);
4200 _changed(sd->pan_obj);
4202 if (wsd->scroll_item_align_enable && sd->aligned_item)
4203 elm_genlist_item_show(EO_OBJ(sd->aligned_item), ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
4208 /* FIXME: take off later. maybe this show region coords belong in the
4209 * interface (new api functions, set/get)? */
4211 _show_region_hook(void *data,
4214 Evas_Coord x, y, w, h;
4216 ELM_GENLIST_DATA_GET(data, sd);
4218 elm_widget_show_region_get(obj, &x, &y, &w, &h);
4219 //x & y are screen coordinates, Add with pan coordinates
4223 eo_do(obj, elm_interface_scrollable_content_region_show(x, y, w, h));
4226 EOLIAN static Eina_Bool
4227 _elm_genlist_elm_widget_translate(Eo *obj, Elm_Genlist_Data *sd)
4231 // Before calling text_get, inform user first.
4232 evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
4234 // FIXME: We should change item's height if lang is changed??
4235 EINA_INLIST_FOREACH(sd->blocks, itb)
4239 EINA_LIST_FOREACH(itb->items, l, it)
4243 elm_genlist_item_fields_update(EO_OBJ(it),
4245 ELM_GENLIST_ITEM_FIELD_TEXT |
4246 ELM_GENLIST_ITEM_FIELD_CONTENT);
4248 else GL_IT(it)->calc_done = EINA_FALSE;
4250 itb->calc_done = EINA_FALSE;
4253 eina_hash_free_buckets(sd->size_caches);
4254 sd->calc_done = EINA_FALSE;
4260 _elm_genlist_elm_widget_item_loop_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enable EINA_UNUSED)
4262 // Need to be implemented
4263 //sd->item_loop_enable = !!enable;
4266 EOLIAN static Eina_Bool
4267 _elm_genlist_elm_widget_item_loop_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
4269 // Need to be implemented
4270 //return sd->item_loop_enable;
4275 _item_block_position_update(Eina_Inlist *list,
4280 EINA_INLIST_FOREACH(list, tmp)
4282 tmp->position = idx++;
4283 tmp->position_update = EINA_TRUE;
4288 _item_position_update(Eina_List *list,
4294 EINA_LIST_FOREACH(list, l, it)
4296 it->position = idx++;
4297 it->position_update = EINA_TRUE;
4302 _item_block_merge(Item_Block *left,
4308 EINA_LIST_FOREACH(right->items, l, it2)
4310 it2->item->block = left;
4312 left->calc_done = EINA_FALSE;
4314 left->items = eina_list_merge(left->items, right->items);
4318 _item_block_del(Elm_Gen_Item *it)
4320 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4322 Item_Block *itb = GL_IT(it)->block;
4323 Eina_Bool block_changed = EINA_FALSE;
4326 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
4327 (NULL, NULL, NULL, &vh));
4328 if (sd->processed_sizes >= vh) sd->processed_sizes = 0;
4330 itb->items = eina_list_remove(itb->items, it);
4332 itb->calc_done = EINA_FALSE;
4333 sd->calc_done = EINA_FALSE;
4334 _changed(sd->pan_obj);
4339 il = EINA_INLIST_GET(itb);
4340 itbn = (Item_Block *)(il->next);
4342 it->parent->item->items =
4343 eina_list_remove(it->parent->item->items, EO_OBJ(it));
4346 _item_block_position_update(il->next, itb->position);
4348 GL_IT(it)->wsd->blocks =
4349 eina_inlist_remove(GL_IT(it)->wsd->blocks, il);
4350 GL_IT(it)->wsd->blocks_realized = eina_list_remove
4351 (GL_IT(it)->wsd->blocks_realized, itb);
4354 if (itbn) itbn->calc_done = EINA_FALSE;
4358 if (itb->count < (itb->sd->max_items_per_block / 2))
4363 il = EINA_INLIST_GET(itb);
4364 itbp = (Item_Block *)(il->prev);
4365 itbn = (Item_Block *)(il->next);
4367 /* merge block with previous */
4369 ((itbp->count + itb->count) <
4370 (itb->sd->max_items_per_block +
4371 (itb->sd->max_items_per_block / 2))))
4373 _item_block_merge(itbp, itb);
4374 _item_block_position_update
4375 (EINA_INLIST_GET(itb)->next, itb->position);
4376 GL_IT(it)->wsd->blocks = eina_inlist_remove
4377 (GL_IT(it)->wsd->blocks, EINA_INLIST_GET(itb));
4378 GL_IT(it)->wsd->blocks_realized = eina_list_remove
4379 (GL_IT(it)->wsd->blocks_realized, itb);
4381 block_changed = EINA_TRUE;
4383 /* merge block with next */
4385 ((itbn->count + itb->count) <
4386 (itb->sd->max_items_per_block +
4387 (itb->sd->max_items_per_block / 2))))
4389 _item_block_merge(itb, itbn);
4390 _item_block_position_update
4391 (EINA_INLIST_GET(itbn)->next, itbn->position);
4392 GL_IT(it)->wsd->blocks =
4393 eina_inlist_remove(GL_IT(it)->wsd->blocks,
4394 EINA_INLIST_GET(itbn));
4395 GL_IT(it)->wsd->blocks_realized = eina_list_remove
4396 (GL_IT(it)->wsd->blocks_realized, itbn);
4398 block_changed = EINA_TRUE;
4405 _changed(sd->pan_obj);
4408 GL_IT(it)->block = NULL;
4412 _decorate_all_item_unrealize(Elm_Gen_Item *it)
4414 if (!it->deco_all_view) return;
4416 edje_object_part_unswallow(it->deco_all_view, VIEW(it));
4417 _view_clear(it->deco_all_view, &(GL_IT(it)->deco_all_contents));
4418 evas_object_del(it->deco_all_view);
4419 it->deco_all_view = NULL;
4421 edje_object_signal_emit(VIEW(it), SIGNAL_DECORATE_DISABLED, "elm");
4423 _item_mouse_callbacks_add(it, VIEW(it));
4424 evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
4429 _item_mouse_move_cb(void *data,
4430 Evas *evas EINA_UNUSED,
4434 Evas_Event_Mouse_Move *ev = event_info;
4435 Elm_Gen_Item *it = data;
4436 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4438 if (!it->down) return;
4440 if (((sd->reorder_force) || (sd->reorder_mode)) &&
4441 (sd->reorder.it == it) &&
4445 evas_object_geometry_get(sd->pan_obj, &ox, NULL, NULL, NULL);
4447 if ((ev->cur.canvas.y - it->dy) > GL_IT(it)->scrl_y)
4448 sd->reorder.dir = 1;
4449 else if ((ev->cur.canvas.y - it->dy) < GL_IT(it)->scrl_y)
4450 sd->reorder.dir = -1;
4452 GL_IT(it)->scrl_x = it->x + GL_IT(it)->block->x - sd->pan_x + ox;
4453 GL_IT(it)->scrl_y = ev->cur.canvas.y - it->dy;
4454 GL_IT(it)->w = sd->minw;
4455 GL_IT(it)->h = GL_IT(it)->minh;
4456 _changed(sd->pan_obj);
4459 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4461 if (GL_IT(it)->highlight_timer)
4463 ecore_timer_del(GL_IT(it)->highlight_timer);
4464 GL_IT(it)->highlight_timer = NULL;
4466 else if (!it->selected) _item_unhighlight(it, EINA_FALSE);
4470 ecore_timer_del(it->long_timer);
4471 it->long_timer = NULL;
4473 sd->on_hold = EINA_TRUE; /* for checking need to start select timer */
4475 //******************** TIZEN Only
4478 if (((sd->reorder_force) || (sd->reorder_mode)) &&
4479 (sd->reorder.it == it) && (!it->want_hidden))
4481 Evas_Coord x, y, w, h;
4482 evas_object_geometry_get(obj, &x, &y, &w, &h);
4483 if (ELM_RECTS_POINT_OUT(x, y, w, h, ev->cur.canvas.x, ev->cur.canvas.y))
4487 ecore_timer_del(it->long_timer);
4488 it->long_timer = NULL;
4490 if (GL_IT(it)->highlight_timer)
4492 ecore_timer_del(GL_IT(it)->highlight_timer);
4493 GL_IT(it)->highlight_timer = NULL;
4495 else if (!it->selected) _item_unhighlight(it, EINA_FALSE);
4498 //*******************************
4500 evas_object_ref(obj);
4504 Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
4505 minw = GL_IT(it)->wsd->finger_minw;
4506 minh = GL_IT(it)->wsd->finger_minh;
4508 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4509 dx = ev->cur.canvas.x - x;
4510 dy = ev->cur.canvas.y - y;
4515 if (adx < 0) adx = -dx;
4516 if (ady < 0) ady = -dy;
4517 if ((adx > minw) || (ady > minh))
4519 it->dragging = EINA_TRUE;
4520 /* Genlist is scrolled vertically, so reduce left or right case for accuracy. */
4521 if (adx > (ady * 2))
4524 evas_object_smart_callback_call
4525 (WIDGET(it), SIG_DRAG_START_LEFT, EO_OBJ(it));
4527 evas_object_smart_callback_call
4528 (WIDGET(it), SIG_DRAG_START_RIGHT, EO_OBJ(it));
4533 evas_object_smart_callback_call
4534 (WIDGET(it), SIG_DRAG_START_UP, EO_OBJ(it));
4536 evas_object_smart_callback_call
4537 (WIDGET(it), SIG_DRAG_START_DOWN, EO_OBJ(it));
4542 /* If item magic value is changed, do not call smart callback*/
4543 if (EINA_MAGIC_CHECK(it->base, ELM_WIDGET_ITEM_MAGIC))
4546 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, EO_OBJ(it));
4549 evas_object_unref(obj);
4554 _long_press_cb(void *data)
4556 Elm_Gen_Item *it = data;
4557 Elm_Object_Item *eo_it2;
4558 Elm_Genlist_Data *sd;
4562 sd = GL_IT(it)->wsd;
4563 it->long_timer = NULL;
4565 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()) ||
4566 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
4567 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
4568 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
4569 (sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
4572 if ((sd->reorder_mode) &&
4573 (GL_IT(it)->type != ELM_GENLIST_ITEM_GROUP) &&
4574 (!sd->key_down_item))
4576 if (elm_genlist_item_expanded_get(EO_OBJ(it)))
4578 elm_genlist_item_expanded_set(EO_OBJ(it), EINA_FALSE);
4580 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it2)
4582 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
4583 _item_unselect(it2);
4586 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
4587 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
4588 (EINA_FALSE, EINA_FALSE));
4590 if (TIZEN_PROFILE_WEARABLE)
4593 if (sd->decorate_all_mode)
4594 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
4598 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
4601 sd->reorder.it = it;
4602 _changed(sd->pan_obj);
4604 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, EO_OBJ(it));
4607 it->long_timer = NULL;
4608 return ECORE_CALLBACK_CANCEL;
4612 _gesture_do(void *data)
4614 Elm_Genlist_Data *sd = data;
4616 if ((sd->g_item) && (sd->g_type))
4618 if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_LEFT))
4619 evas_object_smart_callback_call
4620 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_LEFT, EO_OBJ(sd->g_item));
4621 else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_RIGHT))
4622 evas_object_smart_callback_call
4623 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_RIGHT, EO_OBJ(sd->g_item));
4624 else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_UP))
4625 evas_object_smart_callback_call
4626 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_UP, EO_OBJ(sd->g_item));
4627 else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_DOWN))
4628 evas_object_smart_callback_call
4629 (WIDGET(sd->g_item), SIG_MULTI_SWIPE_DOWN, EO_OBJ(sd->g_item));
4630 else if (!strcmp(sd->g_type, SIG_MULTI_PINCH_OUT))
4631 evas_object_smart_callback_call
4632 (WIDGET(sd->g_item), SIG_MULTI_PINCH_OUT, EO_OBJ(sd->g_item));
4633 else if (!strcmp(sd->g_type, SIG_MULTI_PINCH_IN))
4634 evas_object_smart_callback_call
4635 (WIDGET(sd->g_item), SIG_MULTI_PINCH_IN, EO_OBJ(sd->g_item));
4636 else if (!strcmp(sd->g_type, SIG_SWIPE))
4637 evas_object_smart_callback_call
4638 (WIDGET(sd->g_item), SIG_SWIPE, EO_OBJ(sd->g_item));
4646 _item_mouse_down_cb(void *data,
4651 Evas_Event_Mouse_Down *ev = event_info;
4652 Elm_Gen_Item *it = data;
4653 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4656 if (ev->event_flags & EVAS_EVENT_FLAG_ON_SCROLL)
4660 elm_genlist_item_reorder_stop(EO_OBJ(sd->reorder.it));
4661 sd->reorder.it = NULL;
4662 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
4663 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set(sd->h_bounce, sd->v_bounce));
4668 if (ev->button != 1) return;
4669 // mouse down is activate only one finger
4670 if (evas_event_down_count_get(evas) != 1) return;
4672 if (GL_IT(it)->highlight_timer)
4673 ecore_timer_del(GL_IT(it)->highlight_timer);
4674 // FIXME: To prevent timing issue about select and highlight
4675 else if (!sd->multi && sd->highlighted_item &&
4676 (GL_IT(sd->highlighted_item)->highlight_timer))
4679 it->down = EINA_TRUE;
4681 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4682 it->dx = ev->canvas.x - x;
4683 it->dy = ev->canvas.y - y;
4685 GL_IT(it)->wsd->was_selected = it->selected;
4686 GL_IT(it)->highlight_timer = ecore_timer_add(ELM_ITEM_HIGHLIGHT_TIMER,
4687 _highlight_timer, it);
4688 if (it->long_timer) ecore_timer_del(it->long_timer);
4689 it->long_timer = ecore_timer_add(sd->longpress_timeout, _long_press_cb, it);
4691 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
4693 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, EO_OBJ(it));
4694 evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, EO_OBJ(it));
4696 evas_object_smart_callback_call(WIDGET(it), SIG_PRESSED, EO_OBJ(it));
4700 _item_block_new(Elm_Genlist_Data *sd,
4705 itb = calloc(1, sizeof(Item_Block));
4706 if (!itb) return NULL;
4710 sd->blocks = eina_inlist_prepend(sd->blocks, EINA_INLIST_GET(itb));
4711 _item_block_position_update(sd->blocks, 0);
4715 sd->blocks = eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4716 itb->position_update = EINA_TRUE;
4717 if (sd->blocks != EINA_INLIST_GET(itb))
4720 ((Item_Block *)(EINA_INLIST_GET(itb)->prev))->position + 1;
4732 _item_block_add(Elm_Genlist_Data *sd,
4735 Item_Block *itb = NULL;
4736 if (GL_IT(it)->block) return EINA_TRUE;
4738 if (!GL_IT(it)->rel)
4743 itb = calloc(1, sizeof(Item_Block));
4744 if (!itb) return EINA_FALSE;
4746 if (!GL_IT(it)->rel->item->block)
4749 eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4750 itb->items = eina_list_append(itb->items, it);
4751 itb->position_update = EINA_TRUE;
4752 it->position = eina_list_count(itb->items);
4753 it->position_update = EINA_TRUE;
4755 if (sd->blocks != EINA_INLIST_GET(itb))
4759 (EINA_INLIST_GET(itb)->prev))->position + 1;
4770 tmp = eina_list_data_find_list(itb->items, GL_IT(it)->rel);
4771 if (GL_IT(it)->before)
4773 sd->blocks = eina_inlist_prepend_relative
4774 (sd->blocks, EINA_INLIST_GET(itb),
4775 EINA_INLIST_GET(GL_IT(it)->rel->item->block));
4777 eina_list_prepend_relative_list(itb->items, it, tmp);
4779 /* Update index from where we prepended */
4780 _item_position_update
4781 (eina_list_prev(tmp), GL_IT(it)->rel->position);
4782 _item_block_position_update
4783 (EINA_INLIST_GET(itb),
4784 GL_IT(it)->rel->item->block->position);
4788 sd->blocks = eina_inlist_append_relative
4789 (sd->blocks, EINA_INLIST_GET(itb),
4790 EINA_INLIST_GET(GL_IT(it)->rel->item->block));
4792 eina_list_append_relative_list(itb->items, it, tmp);
4794 /* Update block index from where we appended */
4795 _item_position_update
4796 (eina_list_next(tmp), GL_IT(it)->rel->position + 1);
4797 _item_block_position_update
4798 (EINA_INLIST_GET(itb),
4799 GL_IT(it)->rel->item->block->position + 1);
4805 if (GL_IT(it)->before)
4809 itb = (Item_Block *)(sd->blocks);
4810 if (itb->count >= sd->max_items_per_block)
4812 itb = _item_block_new(sd, EINA_TRUE);
4813 if (!itb) return EINA_FALSE;
4818 itb = _item_block_new(sd, EINA_TRUE);
4819 if (!itb) return EINA_FALSE;
4821 itb->items = eina_list_prepend(itb->items, it);
4822 _item_position_update(itb->items, 1);
4828 itb = (Item_Block *)(sd->blocks->last);
4829 if (itb->count >= sd->max_items_per_block)
4831 itb = _item_block_new(sd, EINA_FALSE);
4832 if (!itb) return EINA_FALSE;
4837 itb = _item_block_new(sd, EINA_FALSE);
4838 if (!itb) return EINA_FALSE;
4840 itb->items = eina_list_append(itb->items, it);
4841 it->position = eina_list_count(itb->items);
4850 if ((!GL_IT(it)->wsd->sorting) && (GL_IT(it)->rel->item->queued))
4852 /* NOTE: for a strange reason eina_list and eina_inlist
4853 don't have the same property on sorted insertion
4854 order, so the queue is not always ordered like the
4855 item list. This lead to issue where we depend on an
4856 item that is not yet created. As a quick work around,
4857 we reschedule the calc of the item and stop reordering
4858 the list to prevent any nasty issue to show up here.
4860 sd->queue = eina_list_append(sd->queue, it);
4861 sd->requeued = EINA_TRUE;
4862 GL_IT(it)->queued = EINA_TRUE;
4867 itb = GL_IT(it)->rel->item->block;
4868 if (!itb) goto newblock;
4869 tmp = eina_list_data_find_list(itb->items, GL_IT(it)->rel);
4870 if (GL_IT(it)->before)
4872 itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4873 _item_position_update
4874 (eina_list_prev(tmp), GL_IT(it)->rel->position);
4878 itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4879 _item_position_update
4880 (eina_list_next(tmp), GL_IT(it)->rel->position + 1);
4885 itb->calc_done = EINA_FALSE;
4886 sd->calc_done = EINA_FALSE;
4887 GL_IT(it)->block = itb;
4888 _changed(itb->sd->pan_obj);
4890 if (itb->count > itb->sd->max_items_per_block)
4895 Eina_Bool done = EINA_FALSE;
4897 newc = itb->count / 2;
4899 if (EINA_INLIST_GET(itb)->prev)
4901 Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4903 if (itbp->count + newc < sd->max_items_per_block / 2)
4905 /* moving items to previous block */
4906 while ((itb->count > newc) && (itb->items))
4908 it2 = eina_list_data_get(itb->items);
4909 itb->items = eina_list_remove_list
4910 (itb->items, itb->items);
4913 itbp->items = eina_list_append(itbp->items, it2);
4914 it2->item->block = itbp;
4922 if (!done && EINA_INLIST_GET(itb)->next)
4924 Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4926 if (itbn->count + newc < sd->max_items_per_block / 2)
4928 /* moving items to next block */
4929 while ((itb->count > newc) && (itb->items))
4933 l = eina_list_last(itb->items);
4934 it2 = eina_list_data_get(l);
4935 itb->items = eina_list_remove_list(itb->items, l);
4938 itbn->items = eina_list_prepend(itbn->items, it2);
4939 it2->item->block = itbn;
4949 /* moving items to new block */
4950 itb2 = calloc(1, sizeof(Item_Block));
4951 if (!itb2) return EINA_FALSE;
4954 eina_inlist_append_relative(sd->blocks, EINA_INLIST_GET(itb2),
4955 EINA_INLIST_GET(itb));
4956 itb2->calc_done = EINA_FALSE;
4957 while ((itb->count > newc) && (itb->items))
4961 l = eina_list_last(itb->items);
4963 itb->items = eina_list_remove_list(itb->items, l);
4966 itb2->items = eina_list_prepend(itb2->items, it2);
4967 it2->item->block = itb2;
4977 _item_min_calc(Elm_Gen_Item *it)
4979 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4980 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wd);
4981 Evas_Coord mw = 0, mh = 0;
4984 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
4985 (NULL, NULL, &vw, NULL));
4987 if ((it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) &&
4988 (sd->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
4990 mw = sd->finger_minw;
4991 mh = sd->finger_minh;
4994 if ((sd->mode == ELM_LIST_COMPRESS) && vw && mw < vw)
4997 //FIXME: Some widget such as entry, label need to have fixed width size before
4998 // min calculation to get proper height size by multiline.
4999 if (sd->realization_mode || GL_IT(it)->resized)
5000 evas_object_resize(VIEW(it), mw, mh);
5002 edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
5004 if ((sd->mode != ELM_LIST_LIMIT) && vw && mw < vw)
5007 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5008 if (sd->homogeneous || it->itc->homogeneous)
5010 Size_Cache *size, *tmp;
5011 tmp = eina_hash_find(sd->size_caches, it->itc->item_style);
5013 eina_hash_del_by_key(sd->size_caches, it->itc->item_style);
5015 size = ELM_NEW(Size_Cache);
5018 eina_hash_add(sd->size_caches, it->itc->item_style, size);
5021 GL_IT(it)->w = GL_IT(it)->minw = mw;
5022 GL_IT(it)->h = GL_IT(it)->minh = mh;
5024 // FIXME: This is workaround for entry size issue.
5025 if (sd->realization_mode || GL_IT(it)->resized)
5027 GL_IT(it)->resized = EINA_FALSE;
5028 if (it->deco_all_view)
5029 evas_object_resize(it->deco_all_view, GL_IT(it)->w, GL_IT(it)->h);
5030 else if (GL_IT(it)->deco_it_view)
5031 evas_object_resize(GL_IT(it)->deco_it_view, GL_IT(it)->w, GL_IT(it)->h);
5033 evas_object_resize(VIEW(it), GL_IT(it)->w, GL_IT(it)->h);
5036 if (wd->scroll_item_align_enable && (sd->aligned_item == it))
5037 _focus_bg_show(sd->aligned_item);
5041 _item_calc(Elm_Gen_Item *it)
5043 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5044 Size_Cache *size = NULL;
5045 Evas_Coord p_minw, p_minh;
5047 if (GL_IT(it)->calc_done) return;
5049 p_minw = GL_IT(it)->minw;
5050 p_minh = GL_IT(it)->minh;
5052 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5053 if (sd->homogeneous || it->itc->homogeneous)
5054 size = eina_hash_find(sd->size_caches, it->itc->item_style);
5057 GL_IT(it)->w = GL_IT(it)->minw = size->minw;
5058 GL_IT(it)->h = GL_IT(it)->minh = size->minh;
5064 if (sd->realization_mode)
5066 _item_realize(it, EINA_FALSE);
5071 _item_realize(it, EINA_TRUE);
5073 _item_unrealize(it, EINA_TRUE);
5080 GL_IT(it)->calc_done = EINA_TRUE;
5081 if ((p_minw != GL_IT(it)->minw) || (p_minh != GL_IT(it)->minh))
5083 GL_IT(it)->block->calc_done = EINA_FALSE;
5084 sd->calc_done = EINA_FALSE;
5089 _item_process(Elm_Genlist_Data *sd,
5092 if (!_item_block_add(sd, it)) return EINA_FALSE;
5094 GL_IT(it)->calc_done = EINA_FALSE;
5101 _dummy_job(void *data)
5103 Elm_Genlist_Data *sd = data;
5104 sd->dummy_job = NULL;
5109 _queue_idle_enter(void *data)
5111 Elm_Genlist_Data *sd = data;
5116 eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
5117 (NULL, NULL, &vw, NULL));
5118 if (!sd->queue || (vw <= 1))
5122 ecore_job_del(sd->dummy_job);
5123 sd->dummy_job = NULL;
5125 sd->queue_idle_enterer = NULL;
5126 return ECORE_CALLBACK_CANCEL;
5129 ft = ecore_animator_frametime_get()/2;
5130 t0 = ecore_time_get();
5131 for (n = 0; (sd->queue) && (n < ITEM_QUEUE_MAX); n++)
5136 it = eina_list_data_get(sd->queue);
5137 sd->queue = eina_list_remove_list(sd->queue, sd->queue);
5138 GL_IT(it)->queued = EINA_FALSE;
5139 GL_IT(it)->resized = EINA_FALSE;
5140 if (!_item_process(sd, it)) continue;
5141 t = ecore_time_get();
5142 /* same as eina_inlist_count > 1 */
5143 if (sd->blocks && sd->blocks->next)
5145 if ((t - t0) > ft) break;
5149 _changed(sd->pan_obj);
5154 ecore_job_del(sd->dummy_job);
5155 sd->dummy_job = NULL;
5157 sd->queue_idle_enterer = NULL;
5158 return ECORE_CALLBACK_CANCEL;
5161 // Do not use smart_changed
5162 // Instead make any events (job, idler, etc.) to call idle enterer
5163 if (sd->dummy_job) ecore_job_del(sd->dummy_job);
5164 sd->dummy_job = ecore_job_add(_dummy_job, sd);
5166 return ECORE_CALLBACK_RENEW;
5170 _item_queue(Elm_Gen_Item *it,
5171 Eina_Compare_Cb cb EINA_UNUSED)
5173 if (GL_IT(it)->queued) return;
5175 GL_IT(it)->queued = EINA_TRUE;
5176 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5178 // FIXME: Below code occurs item unsorted result.
5179 // genlist already calculate items position by sd->items
5180 // so no need to requeue items by sorting insert.
5181 // if (cb && !sd->requeued)
5182 // sd->queue = eina_list_sorted_insert(sd->queue, cb, it);
5184 sd->queue = eina_list_append(sd->queue, it);
5186 if (sd->queue_idle_enterer)
5187 ecore_idle_enterer_del(sd->queue_idle_enterer);
5188 sd->queue_idle_enterer = ecore_idle_enterer_add(_queue_idle_enter, sd);
5192 _item_queue_direct(Elm_Gen_Item *it,
5195 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5197 // Processing items within viewport if items already exist.
5198 // This can prevent flickering issue when content size is changed.
5199 // This can fix the flickering issue when expanded item have subitems whose total height > vh
5200 if (!sd->queue && (sd->viewport_w > 1) &&
5201 ((sd->processed_sizes <= sd->viewport_h) || (GL_IT(it)->expanded_depth > 0)))
5203 #ifdef GENLIST_FX_SUPPORT
5204 if (sd->fx_mode)// && !it->item->is_prepend) // For support preppended items - hs619.choi@samsung.com
5206 sd->add_fx.items = eina_list_append(sd->add_fx.items, it);
5207 if (!sd->add_fx.anim)
5209 sd->add_fx.cnt = ANIM_CNT_MAX;
5210 sd->add_fx.anim = ecore_animator_add(_add_fx_anim, sd);
5214 _item_process(sd, it);
5215 sd->processed_sizes += GL_IT(it)->minh;
5217 _changed(sd->pan_obj);
5220 _item_queue(it, cb);
5223 /* If the application wants to know the relative item, use
5224 * elm_genlist_item_prev_get(it)*/
5226 _item_move_after(Elm_Gen_Item *it,
5227 Elm_Gen_Item *after)
5231 if (it == after) return;
5233 GL_IT(it)->wsd->items =
5234 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
5235 if (GL_IT(it)->block) _item_block_del(it);
5237 GL_IT(it)->wsd->items = eina_inlist_append_relative
5238 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
5241 GL_IT(it)->rel->item->rel_revs =
5242 eina_list_remove(GL_IT(it)->rel->item->rel_revs, it);
5243 GL_IT(it)->rel = after;
5244 after->item->rel_revs = eina_list_append(after->item->rel_revs, it);
5245 GL_IT(it)->before = EINA_FALSE;
5246 if (after->item->group_item) GL_IT(it)->group_item = after->item->group_item;
5248 if (GL_IT(it)->queued)
5250 GL_IT(it)->wsd->queue = eina_list_remove(GL_IT(it)->wsd->queue, it);
5251 GL_IT(it)->queued = EINA_FALSE;
5253 _item_queue_direct(it, NULL);
5255 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, EO_OBJ(it));
5258 /* If the application wants to know the relative item, use
5259 * elm_genlist_item_next_get(it)*/
5261 _item_move_before(Elm_Gen_Item *it,
5262 Elm_Gen_Item *before)
5265 if (!before) return;
5266 if (it == before) return;
5268 GL_IT(it)->wsd->items =
5269 eina_inlist_remove(GL_IT(it)->wsd->items, EINA_INLIST_GET(it));
5270 if (GL_IT(it)->block) _item_block_del(it);
5271 GL_IT(it)->wsd->items = eina_inlist_prepend_relative
5272 (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
5275 GL_IT(it)->rel->item->rel_revs =
5276 eina_list_remove(GL_IT(it)->rel->item->rel_revs, it);
5277 GL_IT(it)->rel = before;
5278 before->item->rel_revs = eina_list_append(before->item->rel_revs, it);
5279 GL_IT(it)->before = EINA_TRUE;
5280 if (before->item->group_item)
5281 GL_IT(it)->group_item = before->item->group_item;
5282 _item_queue_direct(it, NULL);
5284 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, EO_OBJ(it));
5288 _item_mouse_up_cb(void *data,
5290 Evas_Object *obj EINA_UNUSED,
5293 Evas_Event_Mouse_Up *ev = event_info;
5294 Elm_Gen_Item *it = data;
5295 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5297 ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd);
5299 if (!it->down) return;
5300 it->down = EINA_FALSE;
5302 if (ev->button != 1) return;
5306 it->dragging = EINA_FALSE;
5307 evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, EO_OBJ(it));
5309 // When the event is cancelled, need to initialize mouse flags and timers.
5310 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = EINA_TRUE;
5314 if (evas_event_down_count_get(evas) != 0)
5316 if (!GL_IT(it)->highlight_timer) _item_unhighlight(it, EINA_TRUE);
5321 ecore_timer_del(it->long_timer);
5322 it->long_timer = NULL;
5324 if (GL_IT(it)->highlight_timer)
5326 ecore_timer_del(GL_IT(it)->highlight_timer);
5327 GL_IT(it)->highlight_timer = NULL;
5328 // Because naviframe can drop the all evevents.
5329 // highlight it before select timer is called.
5330 if (evas_event_down_count_get(evas) == 0) _item_highlight(it);
5333 if (!sd->reorder.it && (evas_event_down_count_get(evas) == 0))
5335 // FIXME: if highlight mode is not used, mouse move cannot disable
5337 if ((sd->was_selected == it->selected) && (!sd->on_hold))
5339 if (wd->scroll_item_align_enable)
5341 const char *align = edje_object_data_get(VIEW(it), "align");
5342 if (!align || strcmp(align, "off"))
5344 if (it != sd->aligned_item)
5346 elm_genlist_item_bring_in(EO_OBJ(it), ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
5350 if (((sd->highlight && it->highlighted) || !sd->highlight) &&
5351 ((!wd->scroll_item_align_enable) || (it == sd->aligned_item)))
5352 GL_IT(it)->highlight_timer =
5353 ecore_timer_add(ITEM_SELECT_TIMER, _select_timer, it);
5354 else if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
5355 (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
5358 Evas_Object *content;
5359 if (sd->focused_item != it)
5360 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
5362 sd->focused_content = NULL;
5363 EINA_LIST_FOREACH(it->content_objs, l, content)
5365 if (elm_widget_focused_object_get(content))
5366 sd->focused_content = content;
5371 else if (sd->reorder.it == it)
5373 if (TIZEN_PROFILE_WEARABLE)
5375 Elm_Gen_Item *it2, *it_max = NULL, *it_min = NULL;
5376 Evas_Coord r_y_scrl, it_y_max = -99999999, it_y_min = 99999999;
5378 if (!it->selected) _item_unhighlight(it, EINA_TRUE);
5379 r_y_scrl = GL_IT(it)->scrl_y;
5380 EINA_LIST_FREE(sd->reorder.move_items, it2)
5382 if (sd->reorder.it->parent != it2->parent)
5384 it2->item->reorder_offset = 0;
5387 Evas_Coord it_y = it2->item->scrl_y +
5388 it2->item->reorder_offset + (it2->item->h / 2) +
5389 it2->item->block->y;
5391 if ((it_y < r_y_scrl) &&
5397 else if ((it_y > r_y_scrl) &&
5403 it2->item->reorder_offset = 0;
5407 _item_move_after(it, it_max);
5408 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5412 _item_move_before(it, it_min);
5413 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5419 Elm_Gen_Item *moved_it = NULL;
5420 Elm_Gen_Item *ptr_it = sd->top_drawn_item;
5421 Elm_Gen_Item *last_it = NULL;
5422 Eina_Bool after = EINA_TRUE;
5424 if (!it->selected) _item_unhighlight(it, EINA_FALSE);
5430 if (ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y, GL_IT(it)->w, GL_IT(it)->h,
5431 GL_IT(ptr_it)->scrl_x, GL_IT(ptr_it)->scrl_y, GL_IT(ptr_it)->w, GL_IT(ptr_it)->h))
5433 if (GL_IT(it)->scrl_y < GL_IT(ptr_it)->scrl_y)
5440 if ((GL_IT(it)->scrl_y + GL_IT(it)->h) > (GL_IT(ptr_it)->scrl_y + GL_IT(ptr_it)->h))
5442 if ((GL_IT(it)->scrl_y + GL_IT(it)->h) == GL_IT(ptr_it)->scrl_y)
5450 ptr_it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(ptr_it)->next);
5455 if (GL_IT(it)->scrl_y > GL_IT(last_it)->scrl_y + GL_IT(last_it)->h)
5459 moved_it = sd->top_drawn_item;
5464 EINA_LIST_FREE(sd->reorder.move_items, ptr_it)
5466 ptr_it->item->reorder_offset = 0;
5471 _item_move_after(it, moved_it);
5472 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5476 _item_move_before(it, moved_it);
5477 evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5480 sd->reorder.it = NULL;
5481 sd->reorder.dir = 0;
5482 if (sd->reorder.anim)
5484 ecore_animator_del(sd->reorder.anim);
5485 sd->reorder.anim = NULL;
5488 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5489 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
5490 (sd->h_bounce, sd->v_bounce));
5492 edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_DISABLED, "elm");
5493 _changed(sd->pan_obj);
5495 sd->on_hold = EINA_FALSE; /* for checking need to start select timer */
5496 evas_object_smart_callback_call(WIDGET(it), SIG_RELEASED, EO_OBJ(it));
5500 _scroll_hold_timer_cb(void *data)
5502 Elm_Genlist_Data *sd = data;
5503 sd->scr_hold_timer = NULL;
5505 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5507 return ECORE_CALLBACK_CANCEL;
5511 _decorate_item_finished_signal_cb(void *data,
5513 const char *emission EINA_UNUSED,
5514 const char *source EINA_UNUSED)
5516 Elm_Gen_Item *it = data;
5518 if (!data || !obj) return;
5519 if ((!it->realized)) return;
5521 _decorate_item_unrealize(it);
5525 _item_update(Elm_Gen_Item *it)
5528 if (!it->realized) return;
5530 _view_clear(VIEW(it), &(it->content_objs));
5531 EINA_LIST_FREE(GL_IT(it)->flip_content_objs, c)
5533 _view_clear(GL_IT(it)->deco_it_view, &(GL_IT(it)->deco_it_contents));
5534 _view_clear(it->deco_all_view, &(GL_IT(it)->deco_all_contents));
5536 _view_inflate(VIEW(it), it, &(it->content_objs));
5539 _item_content_realize(it, VIEW(it), &(GL_IT(it)->flip_content_objs),
5541 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
5543 if (GL_IT(it)->wsd->decorate_all_mode)
5544 _view_inflate(it->deco_all_view, it, &(GL_IT(it)->deco_all_contents));
5545 else if (GL_IT(it)->deco_it_view)
5546 _view_inflate(GL_IT(it)->deco_it_view, it, &(GL_IT(it)->deco_it_contents));
5548 if (!TIZEN_PROFILE_WEARABLE)
5549 _banded_item_bg_add(it, VIEW(it));
5552 evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
5554 if (GL_IT(it)->wsd->aligned_item == it)
5555 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
5557 edje_object_message_signal_process(VIEW(it));
5561 _item_block_calc(Item_Block *itb, Evas_Coord vw EINA_UNUSED, Evas_Coord vh)
5565 Evas_Coord minw = 9999999, minh = 0;
5566 int sum_item_height = 0;
5567 ELM_WIDGET_DATA_GET_OR_RETURN(itb->sd->obj, wsd);
5569 if (itb->calc_done) return;
5571 EINA_LIST_FOREACH(itb->items, l, it)
5573 if (it->want_hidden) continue;
5574 if (GL_IT(it)->updateme)
5580 GL_IT(it)->calc_done = EINA_FALSE;
5581 GL_IT(it)->updateme = EINA_FALSE;
5583 if (!GL_IT(it)->queued) _item_calc(it);
5585 if (wsd->scroll_item_align_enable)
5587 int vcenter = vh / 2;
5588 int icenter = GL_IT(it)->h / 2;
5589 if ((itb->y + sum_item_height < vcenter && itb->y + sum_item_height + GL_IT(it)->h > vcenter) &&
5590 (sum_item_height + icenter < vcenter - 1 || sum_item_height + icenter > vcenter + 1))
5592 int first_item_height = sum_item_height = vcenter - icenter;
5594 Elm_Object_Item *eo_prev = elm_genlist_item_prev_get(EO_OBJ(it));
5595 Elm_Gen_Item *prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
5598 minh = sum_item_height;
5601 if (eo_prev == elm_genlist_first_item_get(wsd->obj))
5603 GL_IT(prev)->h = GL_IT(prev)->minh = first_item_height;
5606 first_item_height -= GL_IT(prev)->h;
5607 prev->y = first_item_height;
5608 eo_prev = elm_genlist_item_prev_get(eo_prev);
5609 prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
5612 sum_item_height += GL_IT(it)->h;
5617 if (minw > GL_IT(it)->minw) minw = GL_IT(it)->minw;
5618 minh += GL_IT(it)->minh;
5619 if (GL_IT(it)->is_prepend)
5621 itb->sd->comp_y += GL_IT(it)->minh;
5622 GL_IT(it)->is_prepend = EINA_FALSE;
5627 itb->calc_done = EINA_TRUE;
5628 itb->position_update = EINA_FALSE;
5632 _scroll_animate_start_cb(Evas_Object *obj,
5633 void *data EINA_UNUSED)
5635 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5636 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
5640 _scroll_animate_stop_cb(Evas_Object *obj,
5641 void *data EINA_UNUSED)
5643 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5644 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
5646 //TIZEN_ONLY: Let the screen-reader know when scroll animation ends
5647 if (_elm_atspi_enabled())
5649 elm_interface_atspi_accessible_visible_data_changed_signal_emit(obj);
5655 _scroll_drag_start_cb(Evas_Object *obj,
5656 void *data EINA_UNUSED)
5658 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5659 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
5663 _scroll_timeout_cb(void *data)
5665 Elm_Genlist_Data *sd = data;
5667 sd->scr_timer = NULL;
5668 if (sd->queue && !sd->queue_idle_enterer)
5670 sd->queue_idle_enterer = ecore_idle_enterer_add(_queue_idle_enter, sd);
5671 if (sd->dummy_job) ecore_job_del(sd->dummy_job);
5672 sd->dummy_job = ecore_job_add(_dummy_job, sd);
5674 return ECORE_CALLBACK_CANCEL;
5678 _scroll_cb(Evas_Object *obj,
5679 void *data EINA_UNUSED)
5681 ELM_GENLIST_DATA_GET(obj, sd);
5683 if (sd->queue_idle_enterer)
5685 ecore_idle_enterer_del(sd->queue_idle_enterer);
5686 sd->queue_idle_enterer = NULL;
5689 ecore_job_del(sd->dummy_job);
5690 sd->dummy_job = NULL;
5693 if (sd->scr_timer) ecore_timer_del(sd->scr_timer);
5694 sd->scr_timer = ecore_timer_add(0.25, _scroll_timeout_cb, sd);
5696 evas_object_smart_callback_call(obj, SIG_SCROLL, NULL);
5700 _scroll_drag_stop_cb(Evas_Object *obj,
5701 void *data EINA_UNUSED)
5703 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_STOP, NULL);
5704 //TIZEN_ONLY: Let the screen-reader know when drag ends
5705 if (_elm_atspi_enabled())
5707 elm_interface_atspi_accessible_visible_data_changed_signal_emit(obj);
5713 _edge_left_cb(Evas_Object *obj,
5714 void *data EINA_UNUSED)
5716 evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
5720 _edge_right_cb(Evas_Object *obj,
5721 void *data EINA_UNUSED)
5723 evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
5727 _edge_top_cb(Evas_Object *obj,
5728 void *data EINA_UNUSED)
5730 evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
5734 _edge_bottom_cb(Evas_Object *obj,
5735 void *data EINA_UNUSED)
5737 evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
5741 _vbar_drag_cb(Evas_Object *obj,
5742 void *data EINA_UNUSED)
5744 evas_object_smart_callback_call(obj, SIG_VBAR_DRAG, NULL);
5748 _vbar_press_cb(Evas_Object *obj,
5749 void *data EINA_UNUSED)
5751 evas_object_smart_callback_call(obj, SIG_VBAR_PRESS, NULL);
5755 _vbar_unpress_cb(Evas_Object *obj,
5756 void *data EINA_UNUSED)
5758 evas_object_smart_callback_call(obj, SIG_VBAR_UNPRESS, NULL);
5762 _hbar_drag_cb(Evas_Object *obj,
5763 void *data EINA_UNUSED)
5765 evas_object_smart_callback_call(obj, SIG_HBAR_DRAG, NULL);
5769 _hbar_press_cb(Evas_Object *obj,
5770 void *data EINA_UNUSED)
5772 evas_object_smart_callback_call(obj, SIG_HBAR_PRESS, NULL);
5776 _hbar_unpress_cb(Evas_Object *obj,
5777 void *data EINA_UNUSED)
5779 evas_object_smart_callback_call(obj, SIG_HBAR_UNPRESS, NULL);
5783 _decorate_item_realize(Elm_Gen_Item *it)
5786 if (GL_IT(it)->deco_it_view || !it->itc->decorate_item_style) return;
5788 // Before adding & swallowing, delete it from smart member
5789 evas_object_smart_member_del(VIEW(it));
5791 GL_IT(it)->deco_it_view = _view_create(it, it->itc->decorate_item_style);
5792 edje_object_part_swallow
5793 (GL_IT(it)->deco_it_view,
5794 edje_object_data_get(GL_IT(it)->deco_it_view, "mode_part"), VIEW(it));
5795 _view_inflate(GL_IT(it)->deco_it_view, it, &(GL_IT(it)->deco_it_contents));
5797 snprintf(buf, sizeof(buf), "elm,state,%s,active",
5798 GL_IT(it)->wsd->decorate_it_type);
5799 edje_object_signal_emit(GL_IT(it)->deco_it_view, buf, "elm");
5800 edje_object_signal_emit(VIEW(it), buf, "elm");
5802 _item_mouse_callbacks_add(it, GL_IT(it)->deco_it_view);
5804 _item_mouse_callbacks_del(it, VIEW(it));
5808 // FIXME: difference from upstream
5810 _mouse_down_scroller(void *data,
5811 Evas *evas EINA_UNUSED,
5812 Evas_Object *obj EINA_UNUSED,
5813 void *event_info EINA_UNUSED)
5815 Widget_Data *wd = elm_widget_data_get(data);
5818 wd->drag_started = EINA_FALSE;
5822 _mouse_up_scroller(void *data,
5823 Evas *evas EINA_UNUSED,
5824 Evas_Object *obj EINA_UNUSED,
5825 void *event_info EINA_UNUSED)
5827 Widget_Data *wd = elm_widget_data_get(data);
5830 wd->drag_started = EINA_FALSE;
5834 _mouse_move_scroller(void *data,
5835 Evas *evas EINA_UNUSED,
5836 Evas_Object *obj EINA_UNUSED,
5839 Widget_Data *wd = elm_widget_data_get(data);
5840 Evas_Event_Mouse_Move *ev = event_info;
5841 Evas_Coord minw = 0, minh = 0, dx, dy, adx, ady;
5844 if (wd->drag_started) return;
5846 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
5847 dx = ev->cur.canvas.x - ev->prev.canvas.x;
5848 dy = ev->cur.canvas.y - ev->prev.canvas.y;
5851 if (adx < 0) adx = -dx;
5852 if (ady < 0) ady = -dy;
5853 if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
5857 evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
5858 wd->drag_started = EINA_TRUE;
5862 evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
5863 wd->drag_started = EINA_TRUE;
5870 _size_cache_free(void *data)
5872 if (data) free(data);
5875 static Evas_Event_Flags
5876 _pinch_zoom_start_cb(void *data, void *event_info)
5878 Elm_Genlist_Data *sd = data;
5879 Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
5880 Elm_Object_Item *eo_it;
5882 eo_it = elm_genlist_at_xy_item_get(sd->obj, p->x, p->y, NULL);
5883 sd->g_item = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
5884 return EVAS_EVENT_FLAG_NONE;
5887 static Evas_Event_Flags
5888 _pinch_zoom_cb(void *data, void *event_info)
5890 Elm_Genlist_Data *sd = data;
5891 Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
5893 if (p->zoom > 1.0 + PINCH_ZOOM_TOLERANCE)
5894 sd->g_type = SIG_MULTI_PINCH_OUT;
5895 else if (p->zoom < 1.0 - PINCH_ZOOM_TOLERANCE)
5896 sd->g_type = SIG_MULTI_PINCH_IN;
5898 return EVAS_EVENT_FLAG_NONE;
5901 static Evas_Event_Flags
5902 _gesture_n_lines_start_cb(void *data , void *event_info)
5904 Elm_Genlist_Data *sd = data;
5905 Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5907 Elm_Object_Item *eo_it;
5909 x = (p->momentum.x1 + p->momentum.x2) / 2;
5910 y = (p->momentum.y1 + p->momentum.y2) / 2;
5912 eo_it = elm_genlist_at_xy_item_get(sd->obj, x, y, NULL);
5913 sd->g_item = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
5914 return EVAS_EVENT_FLAG_NONE;
5917 static Evas_Event_Flags
5918 _gesture_n_lines_cb(void *data , void *event_info)
5920 Elm_Genlist_Data *sd = data;
5921 Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5923 if (p->momentum.n < 2)
5924 return EVAS_EVENT_FLAG_NONE;
5926 Evas_Coord minw = 0, minh = 0;
5927 Evas_Coord x, y, off_x, off_y;
5928 Evas_Coord cur_x, cur_y, prev_x, prev_y;
5929 Elm_Gen_Item *down_it;
5930 Elm_Object_Item *eo_down_it;
5932 minw = sd->finger_minw;
5933 minh = sd->finger_minh;
5935 prev_x = prev_y = 0;
5937 cur_x = p->momentum.x1;
5938 cur_y = p->momentum.y1;
5940 eo_down_it = elm_genlist_at_xy_item_get(sd->obj, cur_x, cur_y, NULL);
5941 down_it = eo_data_scope_get(eo_down_it, ELM_GENLIST_ITEM_CLASS);
5944 evas_object_geometry_get(VIEW(down_it), &x, &y, NULL, NULL);
5945 prev_x = down_it->dx + x;
5946 prev_y = down_it->dy + y;
5948 off_x = abs(cur_x - prev_x);
5949 off_y = abs(cur_y - prev_y);
5951 if ((off_x > minw) || (off_y > minh))
5956 sd->g_type = SIG_MULTI_SWIPE_RIGHT;
5958 sd->g_type = SIG_MULTI_SWIPE_LEFT;
5963 sd->g_type = SIG_MULTI_SWIPE_DOWN;
5965 sd->g_type = SIG_MULTI_SWIPE_UP;
5969 return EVAS_EVENT_FLAG_NONE;
5972 static Evas_Event_Flags
5973 _gesture_n_flicks_cb(void *data , void *event_info)
5975 Elm_Genlist_Data *sd = data;
5976 Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5978 if (p->momentum.n == 1)
5979 sd->g_type = SIG_SWIPE;
5981 return EVAS_EVENT_FLAG_NONE;
5985 _elm_genlist_evas_object_smart_del(Eo *obj, Elm_Genlist_Data *sd)
5987 sd->no_cache = EINA_TRUE;
5988 elm_genlist_clear(obj);
5989 evas_event_callback_del_full(evas_object_evas_get(obj),
5990 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
5991 _evas_viewport_resize_cb, sd);
5992 if (sd->size_caches) eina_hash_free(sd->size_caches);
5993 if (sd->decorate_it_type) eina_stringshare_del(sd->decorate_it_type);
5995 evas_object_del(sd->pan_obj);
5996 eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
6000 _elm_genlist_evas_object_smart_move(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y)
6002 Evas_Coord ox, oy, bg_x, bg_y;
6004 if (!TIZEN_PROFILE_WEARABLE)
6006 evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
6007 evas_object_geometry_get(sd->banded_bg_rect, &bg_x, &bg_y, NULL, NULL);
6010 eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
6011 evas_object_move(sd->hit_rect, x, y);
6013 if (!TIZEN_PROFILE_WEARABLE)
6014 evas_object_move(sd->banded_bg_rect, (bg_x + x - ox), (bg_y + y - oy));
6018 _elm_genlist_evas_object_smart_resize(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord w, Evas_Coord h)
6020 eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
6022 evas_object_resize(sd->hit_rect, w, h);
6026 _elm_genlist_evas_object_smart_member_add(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *member)
6028 eo_do_super(obj, MY_CLASS, evas_obj_smart_member_add(member));
6031 evas_object_raise(sd->hit_rect);
6036 _elm_genlist_elm_widget_access(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool acs)
6039 Elm_Object_Item *eo_it;
6041 l = elm_genlist_realized_items_get(obj);
6043 EINA_LIST_FREE(l, eo_it)
6045 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6046 _item_unrealize(it, EINA_FALSE);
6049 sd->is_access = acs;
6051 _changed(sd->pan_obj);
6052 evas_object_smart_callback_call(obj, SIG_ACCESS_CHANGED, NULL);
6056 _evas_viewport_resize_cb(void *d, Evas *e EINA_UNUSED, void *ei EINA_UNUSED)
6058 Elm_Genlist_Data *priv = d;
6059 _changed(priv->pan_obj);
6063 _elm_genlist_evas_object_smart_add(Eo *obj, Elm_Genlist_Data *priv)
6065 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
6066 Evas_Coord minw, minh;
6067 Elm_Genlist_Pan_Data *pan_data;
6069 eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
6070 elm_widget_sub_object_parent_add(obj);
6072 priv->finger_minw = 0;
6073 priv->finger_minh = 0;
6074 elm_coords_finger_size_adjust(1, &priv->finger_minw, 1, &priv->finger_minh);
6076 priv->size_caches = eina_hash_string_small_new(_size_cache_free);
6077 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
6078 evas_object_smart_member_add(priv->hit_rect, obj);
6079 elm_widget_sub_object_add(obj, priv->hit_rect);
6081 /* common scroller hit rectangle setup */
6082 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
6083 evas_object_show(priv->hit_rect);
6084 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
6086 elm_widget_can_focus_set(obj, EINA_TRUE);
6087 elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
6089 elm_layout_theme_set(obj, "genlist", "base", elm_widget_style_get(obj));
6091 if (!TIZEN_PROFILE_WEARABLE)
6092 _banded_bg_state_check(obj, priv);
6094 /* interface's add() routine issued AFTER the object's smart_add() */
6095 eo_do(obj, elm_interface_scrollable_objects_set(wd->resize_obj, priv->hit_rect));
6097 eo_do(obj, elm_interface_scrollable_bounce_allow_set
6098 (EINA_FALSE, _elm_config->thumbscroll_bounce_enable));
6099 priv->v_bounce = _elm_config->thumbscroll_bounce_enable;
6102 elm_interface_scrollable_animate_start_cb_set(_scroll_animate_start_cb),
6103 elm_interface_scrollable_animate_stop_cb_set(_scroll_animate_stop_cb),
6104 elm_interface_scrollable_scroll_cb_set(_scroll_cb),
6105 elm_interface_scrollable_drag_start_cb_set(_scroll_drag_start_cb),
6106 elm_interface_scrollable_drag_stop_cb_set(_scroll_drag_stop_cb),
6107 elm_interface_scrollable_edge_left_cb_set(_edge_left_cb),
6108 elm_interface_scrollable_edge_right_cb_set(_edge_right_cb),
6109 elm_interface_scrollable_edge_top_cb_set(_edge_top_cb),
6110 elm_interface_scrollable_edge_bottom_cb_set(_edge_bottom_cb),
6111 elm_interface_scrollable_vbar_drag_cb_set(_vbar_drag_cb),
6112 elm_interface_scrollable_vbar_press_cb_set(_vbar_press_cb),
6113 elm_interface_scrollable_vbar_unpress_cb_set(_vbar_unpress_cb),
6114 elm_interface_scrollable_hbar_drag_cb_set(_hbar_drag_cb),
6115 elm_interface_scrollable_hbar_press_cb_set(_hbar_press_cb),
6116 elm_interface_scrollable_hbar_unpress_cb_set(_hbar_unpress_cb));
6118 eo_do(obj, elm_interface_scrollable_content_min_limit_cb_set(_elm_genlist_content_min_limit_cb));
6120 priv->mode = ELM_LIST_SCROLL;
6121 priv->max_items_per_block = MAX_ITEMS_PER_BLOCK;
6122 priv->item_cache_max = priv->max_items_per_block * 2;
6123 priv->longpress_timeout = _elm_config->longpress_timeout;
6124 priv->highlight = EINA_TRUE;
6125 priv->fx_mode = EINA_FALSE;
6126 priv->on_hold = EINA_FALSE;
6129 if (!TIZEN_PROFILE_WEARABLE)
6130 priv->top_drawn_item = NULL;
6132 priv->pan_obj = eo_add(MY_PAN_CLASS, evas_object_evas_get(obj));
6133 pan_data = eo_data_scope_get(priv->pan_obj, MY_PAN_CLASS);
6134 eo_data_ref(obj, NULL);
6136 pan_data->wobj = obj;
6138 pan_data->wsd = priv;
6141 // FIXME: difference from upstream
6142 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_DOWN,
6143 _mouse_down_scroller, obj);
6144 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_UP,
6145 _mouse_up_scroller, obj);
6146 evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_MOVE,
6147 _mouse_move_scroller, obj);
6150 eo_do(obj, elm_interface_scrollable_extern_pan_set(priv->pan_obj));
6152 edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
6153 evas_object_size_hint_min_set(obj, minw, minh);
6155 _item_cache_all_free(priv);
6156 _mirrored_set(obj, elm_widget_mirrored_get(obj));
6158 const char *str = edje_object_data_get(wd->resize_obj,
6160 if ((str) && (!strcmp(str, "on")))
6161 elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
6163 elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
6164 priv->select_on_focus_enabled = EINA_FALSE;
6165 elm_widget_signal_callback_add(obj, "elm,action,focus_highlight,hide", "elm", _elm_genlist_focus_highlight_hide, obj);
6166 elm_widget_signal_callback_add(obj, "elm,action,focus_highlight,show", "elm", _elm_genlist_focus_highlight_show, obj);
6167 evas_event_callback_add(evas_object_evas_get(obj),
6168 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
6169 _evas_viewport_resize_cb, priv);
6171 priv->g_layer = elm_gesture_layer_add(obj);
6172 if (!priv->g_layer) ERR("elm_gesture_layer_add() failed");
6173 elm_gesture_layer_attach(priv->g_layer, priv->hit_rect);
6174 elm_gesture_layer_cb_set
6175 (priv->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_START,
6176 _pinch_zoom_start_cb, priv);
6177 elm_gesture_layer_cb_set
6178 (priv->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE,
6179 _pinch_zoom_cb, priv);
6181 elm_gesture_layer_cb_set
6182 (priv->g_layer, ELM_GESTURE_N_LINES, ELM_GESTURE_STATE_START,
6183 _gesture_n_lines_start_cb, priv);
6184 elm_gesture_layer_cb_set
6185 (priv->g_layer, ELM_GESTURE_N_LINES, ELM_GESTURE_STATE_MOVE,
6186 _gesture_n_lines_cb, priv);
6188 elm_gesture_layer_cb_set
6189 (priv->g_layer, ELM_GESTURE_N_FLICKS, ELM_GESTURE_STATE_START,
6190 _gesture_n_lines_start_cb, priv);
6191 elm_gesture_layer_cb_set
6192 (priv->g_layer, ELM_GESTURE_N_FLICKS, ELM_GESTURE_STATE_MOVE,
6193 _gesture_n_flicks_cb, priv);
6195 elm_layout_sizing_eval(obj);
6197 // TIZEN_ONLY(20150705): Genlist item align feature
6198 wd->scroll_item_align_enable = _elm_config->scroll_item_align_enable;
6199 wd->scroll_item_valign = _elm_config->scroll_item_valign;
6201 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
6202 (NULL, NULL, &priv->viewport_w, &priv->viewport_h));
6205 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
6206 //register/unregister access objects accordingly.
6207 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6209 _elm_genlist_elm_widget_screen_reader(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool is_screen_reader)
6212 Eina_Bool done = EINA_FALSE;
6213 Evas_Object *content = NULL;
6217 EINA_INLIST_FOREACH(sd->blocks, itb)
6222 EINA_LIST_FOREACH(itb->items, l, it)
6224 if (!it->realized || it->want_hidden) continue;
6225 if (is_screen_reader)
6227 elm_interface_atspi_accessible_added(EO_OBJ(it));
6228 elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
6229 EINA_LIST_FOREACH(it->content_objs, ll, content)
6231 if (eo_isa(content, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
6233 eo_do(content, elm_interface_atspi_accessible_parent_set(EO_OBJ(it)));
6234 elm_interface_atspi_accessible_children_changed_added_signal_emit(EO_OBJ(it), content);
6237 elm_interface_atspi_accessible_name_changed_signal_emit(EO_OBJ(it));
6241 elm_interface_atspi_accessible_removed(EO_OBJ(it));
6242 elm_interface_atspi_accessible_children_changed_del_signal_emit(sd->obj, EO_OBJ(it));
6246 else if (done) break;
6249 //TIZEN_ONLY(20161213): apply screen_reader_changed callback
6250 evas_object_smart_callback_call(obj, SIG_ATSPI_SCREEN_READER_CHANGED, &is_screen_reader);
6256 EOLIAN const Elm_Atspi_Action *
6257 _elm_genlist_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd EINA_UNUSED)
6259 /* Need to be implemented
6260 static Elm_Atspi_Action atspi_actions[] = {
6261 { "move,prior", "move", "prior", _key_action_move},
6262 { "move,next", "move", "next", _key_action_move},
6263 { "move,left", "move", "left", _key_action_move},
6264 { "move,right", "move", "right", _key_action_move},
6265 { "move,up", "move", "up", _key_action_move},
6266 { "move,up,multi", "move", "up_multi", _key_action_move},
6267 { "move,down", "move", "down", _key_action_move},
6268 { "move,down,multi", "move", "down_multi", _key_action_move},
6269 { "move,first", "move", "first", _key_action_move},
6270 { "move,last", "move", "last", _key_action_move},
6271 { "select", "select", NULL, _key_action_select},
6272 { "select,multi", "select", "multi", _key_action_select},
6273 { "escape", "escape", NULL, _key_action_escape},
6274 { NULL, NULL, NULL, NULL }
6276 return &atspi_actions[0];
6278 static Elm_Atspi_Action atspi_actions[] = {{NULL, NULL, NULL, NULL}};
6279 return &atspi_actions[0];
6283 elm_genlist_add(Evas_Object *parent)
6285 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
6286 Evas_Object *obj = eo_add(MY_CLASS, parent);
6291 _elm_genlist_eo_base_constructor(Eo *obj, Elm_Genlist_Data *sd)
6293 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
6297 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
6298 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
6299 elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST));
6304 EOLIAN static Evas_Object *
6305 _elm_genlist_item_elm_widget_item_part_content_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6307 Evas_Object *ret = NULL;
6308 if (it->deco_all_view)
6309 ret = edje_object_part_swallow_get(it->deco_all_view, part);
6310 else if (it->decorate_it_set)
6311 ret = edje_object_part_swallow_get(GL_IT(it)->deco_it_view, part);
6313 ret = edje_object_part_swallow_get(VIEW(it), part);
6317 EOLIAN static const char *
6318 _elm_genlist_item_elm_widget_item_part_text_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6320 if (!it->itc->func.text_get) return NULL;
6321 const char *ret = NULL;
6322 if (it->deco_all_view)
6323 ret = edje_object_part_text_get(it->deco_all_view, part);
6324 else if (it->decorate_it_set)
6325 ret = edje_object_part_text_get(GL_IT(it)->deco_it_view, part);
6327 ret = edje_object_part_text_get(VIEW(it), part);
6332 _elm_genlist_item_elm_widget_item_disable(Eo *eo_it, Elm_Gen_Item *it)
6339 if (it == GL_IT(it)->wsd->focused_item) elm_object_item_focus_set(EO_OBJ(it), EINA_FALSE);
6340 if (GL_IT(it)->highlight_timer)
6342 ecore_timer_del(GL_IT(it)->highlight_timer);
6343 GL_IT(it)->highlight_timer = NULL;
6347 ecore_timer_del(it->long_timer);
6348 it->long_timer = NULL;
6353 if (eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get()))
6355 edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
6356 if (it->deco_all_view)
6357 edje_object_signal_emit
6358 (it->deco_all_view, SIGNAL_DISABLED, "elm");
6362 edje_object_signal_emit(VIEW(it), SIGNAL_ENABLED, "elm");
6363 if (it->deco_all_view)
6364 edje_object_signal_emit
6365 (it->deco_all_view, SIGNAL_ENABLED, "elm");
6367 EINA_LIST_FOREACH(it->content_objs, l, obj)
6368 elm_widget_disabled_set(obj, eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get()));
6373 _item_free(Elm_Gen_Item *it)
6376 Elm_Object_Item *eo_it2;
6377 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
6378 sd->processed_sizes -= GL_IT(it)->minh;
6379 if (sd->processed_sizes < 0) sd->processed_sizes = 0;
6381 eo_do(EO_OBJ(it), elm_wdg_item_pre_notify_del());
6382 if (it->tooltip.del_cb)
6383 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6385 #ifdef GENLIST_FX_SUPPORT
6386 sd->del_fx.items = eina_list_remove(sd->del_fx.items, it);
6387 sd->del_fx.pending_items = eina_list_remove(sd->del_fx.pending_items, it);
6388 sd->add_fx.items = eina_list_remove(sd->add_fx.items, it);
6392 GL_IT(it)->rel->item->rel_revs =
6393 eina_list_remove(GL_IT(it)->rel->item->rel_revs, it);
6394 if (GL_IT(it)->rel_revs)
6397 EINA_LIST_FREE(GL_IT(it)->rel_revs, tmp)
6399 if (tmp->item->queued && !(tmp->base)->on_deletion)
6401 GL_IT(tmp)->queued = EINA_FALSE;
6402 GL_IT(tmp)->resized = EINA_FALSE;
6403 sd->queue = eina_list_remove(sd->queue, tmp);
6404 _item_process(sd, tmp);
6406 tmp->item->rel = NULL;
6409 EINA_LIST_FOREACH_SAFE(it->item->items, l, ll, eo_it2)
6411 //elm_widget_item_del(it2);
6412 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6415 sd->reorder.move_items = eina_list_remove(sd->reorder.move_items, it);
6417 if (GL_IT(it)->block) _item_block_del(it);
6419 it->parent->item->items =
6420 eina_list_remove(it->parent->item->items, EO_OBJ(it));
6421 if (GL_IT(it)->queued)
6423 GL_IT(it)->queued = EINA_FALSE;
6424 sd->queue = eina_list_remove(sd->queue, it);
6426 if (sd->filter_queue && !it->filtered)
6428 l = eina_list_data_find_list(sd->filter_queue, it);
6429 if (l) sd->filter_queue = eina_list_remove_list(sd->filter_queue, l);
6431 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6432 sd->group_items = eina_list_remove(sd->group_items, it);
6436 sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
6437 it->selected = EINA_FALSE;
6439 if (sd->show_item == it) sd->show_item = NULL;
6441 if ((sd->g_item) && (sd->g_item == it)) sd->g_item = NULL;
6442 if (sd->expanded_item == it) sd->expanded_item = NULL;
6443 if (sd->state) ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
6445 if (sd->last_selected_item == EO_OBJ(it))
6446 sd->last_selected_item = NULL;
6448 if (sd->realization_mode)
6451 EINA_LIST_FOREACH(GL_IT(it)->flip_content_objs, l, c)
6453 evas_object_event_callback_del_full(c,
6454 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6455 _changed_size_hints, it);
6457 EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, c)
6459 evas_object_event_callback_del_full(c,
6460 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6461 _changed_size_hints, it);
6463 EINA_LIST_FOREACH(it->content_objs, l, c)
6465 evas_object_event_callback_del_full(c,
6466 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6467 _changed_size_hints, it);
6471 if (sd->mode_item) sd->mode_item = NULL;
6472 if (it->selected) _item_unselect(it);
6473 if (it == sd->focused_item)
6477 if (!elm_widget_focus_get(WIDGET(it))) goto failed;
6479 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6480 find = _item_focusable_search(&tmp, 1);
6483 elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
6488 tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6489 find = _item_focusable_search(&tmp, -1);
6492 elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
6497 elm_object_item_focus_set(EO_OBJ(it), EINA_FALSE);
6498 sd->focused_item = NULL;
6501 if (it == sd->key_down_item) sd->key_down_item = NULL;
6502 if (it == sd->highlighted_item) sd->highlighted_item = NULL;
6503 if (!TIZEN_PROFILE_WEARABLE)
6505 if (it == sd->top_drawn_item) sd->top_drawn_item = NULL;
6508 _item_unrealize(it, EINA_FALSE);
6510 if (sd->aligned_item == it) sd->aligned_item = NULL;
6512 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
6515 if (it->item->proxy)
6517 evas_object_smart_member_del(it->item->proxy);
6518 evas_object_del(it->item->proxy);
6521 if (it->itc->func.del)
6522 it->itc->func.del((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it));
6524 if (it->itc->refcount <= 1)
6528 EINA_INLIST_FOREACH_SAFE(sd->item_cache, l2, ic)
6530 if (it->itc == ic->item_class)
6531 _item_cache_free(sd, ic);
6535 elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
6540 // TIZEN_ONLY(20150703) : banded color background feature. enabled only un-scrollable
6541 if (!TIZEN_PROFILE_WEARABLE)
6543 if (sd->banded_bg_rect && !sd->items)
6545 evas_object_smart_member_del(sd->banded_bg_rect);
6546 ELM_SAFE_FREE(sd->banded_bg_rect, evas_object_del);
6550 _changed(sd->pan_obj);
6553 EOLIAN static Eina_Bool
6554 _elm_genlist_item_elm_widget_item_del_pre(Eo *eo_it EINA_UNUSED,
6557 #ifdef GENLIST_FX_SUPPORT
6558 Elm_Genlist_Data *sd = it->item->wsd;
6559 Evas_Coord cvx, cvy, cvw, cvh;
6566 #ifdef GENLIST_FX_SUPPORT
6569 sd->add_fx.items = eina_list_remove(sd->add_fx.items, it);
6572 evas_output_viewport_get(evas_object_evas_get(sd->obj),
6573 &cvx, &cvy, &cvw, &cvh);
6574 if (!ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
6575 GL_IT(it)->w, GL_IT(it)->h,
6576 cvx, cvy, cvw, cvh))
6578 // Delete later, Above items in the viewport
6579 // Delete right now, below items in the viewport
6580 if (it->item->scrl_y < cvy)
6581 sd->del_fx.pending_items = eina_list_append(sd->del_fx.pending_items, it);
6585 _changed(sd->pan_obj);
6591 if (it->deco_all_view) evas_object_lower(it->deco_all_view);
6592 else if (it->item->deco_it_view) evas_object_lower(it->item->deco_it_view);
6593 else if (VIEW(it)) evas_object_lower(VIEW(it));
6595 if (it->item->expanded_depth > 0)
6598 Elm_Object_Item *itt;
6599 EINA_LIST_FOREACH(it->item->items, l, itt)
6601 eo_do(itt, elm_wdg_item_del());
6604 sd->del_fx.items = eina_list_append(sd->del_fx.items, it);
6606 if (!sd->del_fx.anim)
6608 sd->del_fx.cnt = ANIM_CNT_MAX;
6609 sd->del_fx.anim = ecore_animator_add(_del_fx_anim, sd);
6611 _changed(sd->pan_obj);
6617 _elm_genlist_item_elm_widget_item_signal_emit(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char *emission, const char *source)
6621 WRN("item is not realized yet");
6624 edje_object_signal_emit
6625 (VIEW(it), emission, source);
6626 if (it->deco_all_view)
6627 edje_object_signal_emit
6628 (it->deco_all_view, emission, source);
6632 _elm_genlist_item_eo_base_constructor(Eo *eo_it, Elm_Gen_Item *it)
6634 eo_it = eo_do_super_ret(eo_it, ELM_GENLIST_ITEM_CLASS, eo_it, eo_constructor());
6636 it->base = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
6637 eo_do(eo_it, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST_ITEM));
6641 static Elm_Gen_Item *
6642 _elm_genlist_item_new(Elm_Genlist_Data *sd,
6643 const Elm_Genlist_Item_Class *itc,
6645 Elm_Object_Item *eo_parent,
6646 Elm_Genlist_Item_Type type,
6648 const void *func_data)
6653 if (!itc) return NULL;
6655 Eo *eo_it = eo_add(ELM_GENLIST_ITEM_CLASS, sd->obj);
6656 if (!eo_it) return NULL;
6657 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6660 elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
6662 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6663 WIDGET_ITEM_DATA_SET(EO_OBJ(it), data);
6664 it->parent = parent;
6665 it->func.func = func;
6666 it->func.data = func_data;
6668 GL_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
6669 GL_IT(it)->wsd = sd;
6670 GL_IT(it)->type = type;
6674 if (GL_IT(it->parent)->type == ELM_GENLIST_ITEM_GROUP)
6675 GL_IT(it)->group_item = parent;
6676 else if (GL_IT(it->parent)->group_item)
6677 GL_IT(it)->group_item = GL_IT(it->parent)->group_item;
6679 for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
6681 if (GL_IT(it2->parent)->type == ELM_GENLIST_ITEM_TREE) depth += 1;
6683 GL_IT(it)->expanded_depth = depth;
6690 _elm_genlist_item_compare(const void *data,
6693 const Elm_Gen_Item *it, *item1;
6695 it = ELM_GEN_ITEM_FROM_INLIST(data);
6696 item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
6697 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6701 _elm_genlist_item_list_compare(const void *data,
6704 const Elm_Gen_Item *it = data;
6705 const Elm_Gen_Item *item1 = data1;
6707 return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6710 EOLIAN static unsigned int
6711 _elm_genlist_items_count(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6713 return sd->item_count;
6717 _list_last_recursive(Eina_List *list)
6719 Eina_List *ll, *ll2;
6720 Elm_Object_Item *eo_it2;
6722 ll = eina_list_last(list);
6723 if (!ll) return NULL;
6726 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6728 if (it2->item->items)
6730 ll2 = _list_last_recursive(it2->item->items);
6740 EOLIAN static Elm_Object_Item*
6741 _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)
6745 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6749 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6750 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6751 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6754 it = _elm_genlist_item_new
6755 (sd, itc, data, eo_parent, type, func, func_data);
6756 if (!it) return NULL;
6760 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6761 sd->group_items = eina_list_append(sd->group_items, it);
6762 sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
6763 GL_IT(it)->rel = NULL;
6767 Elm_Object_Item *eo_it2 = NULL;
6768 Eina_List *ll = _list_last_recursive(it->parent->item->items);
6770 if (ll) eo_it2 = ll->data;
6771 it->parent->item->items =
6772 eina_list_append(it->parent->item->items, EO_OBJ(it));
6773 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6774 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6775 sd->items = eina_inlist_append_relative
6776 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6777 GL_IT(it)->rel = it2;
6778 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6780 GL_IT(it)->before = EINA_FALSE;
6781 _item_queue_direct(it, NULL);
6785 EOLIAN static Elm_Object_Item*
6786 _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)
6788 Elm_Gen_Item *it = NULL;
6790 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6793 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6794 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6795 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6796 /* first sub-item should allways be appended */
6797 if (!parent->item->items)
6798 return _elm_genlist_item_append(obj, sd, itc, data, eo_parent, type, func, func_data);
6800 it = _elm_genlist_item_new
6801 (sd, itc, data, eo_parent, type, func, func_data);
6803 if (!it) return NULL;
6805 if (sd->items) GL_IT(it)->is_prepend = EINA_TRUE;
6808 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6809 sd->group_items = eina_list_prepend(sd->group_items, it);
6810 sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
6811 GL_IT(it)->rel = NULL;
6815 Elm_Object_Item *eo_it2 = NULL;
6816 Eina_List *ll = it->parent->item->items;
6818 if (ll) eo_it2 = ll->data;
6819 it->parent->item->items =
6820 eina_list_prepend(it->parent->item->items, EO_OBJ(it));
6821 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6822 ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6825 sd->items = eina_inlist_prepend_relative
6826 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6827 GL_IT(it)->rel = it2;
6828 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6831 GL_IT(it)->before = EINA_TRUE;
6832 _item_queue_direct(it, NULL);
6836 EOLIAN static Elm_Object_Item*
6837 _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)
6839 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_after, NULL);
6840 ELM_GENLIST_ITEM_DATA_GET(eo_after, after_it);
6843 ELM_GENLIST_ITEM_CHECK_OR_RETURN(after_it, NULL);
6844 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(after_it), NULL);
6847 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6848 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6849 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6852 /* It makes no sense to insert after in an empty list with after !=
6853 * NULL, something really bad is happening in your app. */
6854 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6856 it = _elm_genlist_item_new
6857 (sd, itc, data, eo_parent, type, func, func_data);
6858 if (!it) return NULL;
6862 if ((GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) &&
6863 (GL_IT(after_it)->type == ELM_GENLIST_ITEM_GROUP))
6864 sd->group_items = eina_list_append_relative
6865 (sd->group_items, it, after_it);
6869 it->parent->item->items =
6870 eina_list_append_relative(it->parent->item->items, EO_OBJ(it), eo_after);
6872 sd->items = eina_inlist_append_relative
6873 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after_it));
6875 GL_IT(it)->rel = after_it;
6876 after_it->item->rel_revs = eina_list_append(after_it->item->rel_revs, it);
6877 GL_IT(it)->before = EINA_FALSE;
6878 _item_queue_direct(it, NULL);
6880 if (elm_genlist_item_next_get(eo_after) == EO_OBJ(sd->aligned_item))
6881 sd->aligned_item = NULL;
6885 EOLIAN static Elm_Object_Item*
6886 _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)
6888 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_before, NULL);
6889 ELM_GENLIST_ITEM_DATA_GET(eo_before, before_it);
6892 ELM_GENLIST_ITEM_CHECK_OR_RETURN(before_it, NULL);
6893 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(before_it), NULL);
6896 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6897 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6898 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6901 /* It makes no sense to insert before in an empty list with before
6902 * != NULL, something really bad is happening in your app. */
6903 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6905 it = _elm_genlist_item_new
6906 (sd, itc, data, eo_parent, type, func, func_data);
6907 if (!it) return NULL;
6911 if ((GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) &&
6912 (GL_IT(before_it)->type == ELM_GENLIST_ITEM_GROUP))
6914 eina_list_prepend_relative(sd->group_items, it, before_it);
6918 it->parent->item->items =
6919 eina_list_prepend_relative(it->parent->item->items, EO_OBJ(it), eo_before);
6921 sd->items = eina_inlist_prepend_relative
6922 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before_it));
6924 GL_IT(it)->rel = before_it;
6925 before_it->item->rel_revs = eina_list_append(before_it->item->rel_revs, it);
6926 GL_IT(it)->before = EINA_TRUE;
6927 _item_queue_direct(it, NULL);
6929 if (before_it == sd->aligned_item)
6930 sd->aligned_item = NULL;
6935 EOLIAN static Elm_Object_Item*
6936 _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)
6938 Elm_Gen_Item *rel = NULL;
6940 Elm_Object_Item *eo_it;
6944 ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6945 ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6946 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6949 it = _elm_genlist_item_new
6950 (sd, itc, data, eo_parent, type, func, func_data);
6951 if (!it) return NULL;
6954 sd->item_compare_cb = comp;
6958 Elm_Object_Item *eo_rel = NULL;
6962 l = eina_list_search_sorted_near_list
6963 (it->parent->item->items, _elm_genlist_item_list_compare, eo_it,
6968 eo_rel = eina_list_data_get(l);
6969 rel = eo_data_scope_get(eo_rel, ELM_GENLIST_ITEM_CLASS);
6971 if (cmp_result >= 0)
6973 it->parent->item->items = eina_list_prepend_relative_list
6974 (it->parent->item->items, eo_it, l);
6975 sd->items = eina_inlist_prepend_relative
6976 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6977 it->item->before = EINA_TRUE;
6979 else if (cmp_result < 0)
6981 it->parent->item->items = eina_list_append_relative_list
6982 (it->parent->item->items, eo_it, l);
6983 sd->items = eina_inlist_append_relative
6984 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6985 it->item->before = EINA_FALSE;
6986 it->item->is_prepend = EINA_TRUE;
6993 // ignoring the comparison
6994 it->parent->item->items = eina_list_prepend_relative_list
6995 (it->parent->item->items, eo_it, l);
6996 sd->items = eina_inlist_prepend_relative
6997 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6998 it->item->before = EINA_FALSE;
7005 sd->state = eina_inlist_sorted_state_new();
7006 eina_inlist_sorted_state_init(sd->state, sd->items);
7007 sd->requeued = EINA_FALSE;
7010 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
7011 sd->group_items = eina_list_append(sd->group_items, it);
7013 sd->items = eina_inlist_sorted_state_insert
7014 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
7017 if (EINA_INLIST_GET(it)->next)
7019 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
7020 GL_IT(it)->before = EINA_TRUE;
7021 GL_IT(it)->is_prepend = EINA_TRUE;
7023 else if (EINA_INLIST_GET(it)->prev)
7025 rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7026 GL_IT(it)->before = EINA_FALSE;
7032 GL_IT(it)->rel = rel;
7033 rel->item->rel_revs = eina_list_append(rel->item->rel_revs, it);
7036 _item_queue_direct(it, _elm_genlist_item_list_compare);
7041 _elm_genlist_clear(Eo *obj, Elm_Genlist_Data *sd)
7045 eina_hash_free_buckets(sd->size_caches);
7046 elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
7047 if (sd->key_down_item) sd->key_down_item = NULL;
7048 if (sd->mode_item) sd->mode_item = NULL;
7052 eina_inlist_sorted_state_free(sd->state);
7056 sd->filter_data = NULL;
7057 if (sd->filter_queue)
7058 ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
7059 ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
7060 ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
7062 // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
7063 // because sd->items can be modified inside elm_widget_item_del()
7066 it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
7067 //elm_widget_item_del(it);
7070 sd->reorder.it = NULL;
7071 sd->reorder.dir = 0;
7072 eina_list_free(sd->reorder.move_items);
7076 _item_cache_all_free(sd);
7080 sd->selected = eina_list_free(sd->selected);
7081 sd->selected = NULL;
7084 sd->show_item = NULL;
7093 evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
7094 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
7096 elm_layout_sizing_eval(obj);
7098 eo_do(sd->obj, elm_interface_scrollable_content_region_show(0, 0, 0, 0));
7102 ecore_job_del(sd->dummy_job);
7103 sd->dummy_job = NULL;
7105 if (sd->queue_idle_enterer)
7107 ecore_idle_enterer_del(sd->queue_idle_enterer);
7108 sd->queue_idle_enterer = NULL;
7110 if (sd->scr_hold_timer)
7112 ecore_timer_del(sd->scr_hold_timer);
7113 sd->scr_hold_timer = NULL;
7115 if (sd->reorder.anim)
7117 ecore_animator_del(sd->reorder.anim);
7118 sd->reorder.anim = NULL;
7122 ecore_timer_del(sd->scr_timer);
7123 sd->scr_timer = NULL;
7125 #ifdef GENLIST_FX_SUPPORT
7126 if (sd->del_fx.anim)
7128 ecore_animator_del(sd->del_fx.anim);
7129 sd->del_fx.anim = NULL;
7131 if (sd->add_fx.anim)
7133 ecore_animator_del(sd->add_fx.anim);
7134 sd->add_fx.anim = NULL;
7138 if (sd->queue) sd->queue = eina_list_free(sd->queue);
7139 if (sd->g_item) sd->g_item = NULL;
7140 if (sd->g_type) sd->g_type = NULL;
7142 if (!TIZEN_PROFILE_WEARABLE)
7144 if (sd->banded_bg_rect)
7146 evas_object_smart_member_del(sd->banded_bg_rect);
7147 ELM_SAFE_FREE(sd->banded_bg_rect, evas_object_del);
7153 _elm_genlist_multi_select_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool multi)
7155 sd->multi = !!multi;
7156 if (!sd->multi && sd->selected)
7159 Elm_Object_Item *eo_it;
7160 Elm_Object_Item *last = sd->selected->data;
7161 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
7164 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
7170 EOLIAN static Eina_Bool
7171 _elm_genlist_multi_select_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7177 _elm_genlist_multi_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Elm_Object_Multi_Select_Mode mode EINA_UNUSED)
7179 /* Need to be implemented
7180 if (mode >= ELM_OBJECT_MULTI_SELECT_MODE_MAX)
7183 if (sd->multi_select_mode != mode)
7184 sd->multi_select_mode = mode;
7189 EOLIAN static Elm_Object_Multi_Select_Mode
7190 _elm_genlist_multi_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
7192 // Need to be implemented
7193 //return sd->multi_select_mode;
7194 return ELM_OBJECT_MULTI_SELECT_MODE_DEFAULT;
7197 EOLIAN static Elm_Object_Item*
7198 _elm_genlist_selected_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7201 return sd->selected->data;
7206 EOLIAN static const Eina_List*
7207 _elm_genlist_selected_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7209 return sd->selected;
7212 EOLIAN static Eina_List*
7213 _elm_genlist_realized_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7216 Eina_List *list = NULL;
7217 Eina_Bool done = EINA_FALSE;
7219 EINA_INLIST_FOREACH(sd->blocks, itb)
7227 EINA_LIST_FOREACH(itb->items, l, it)
7229 if (it->realized) list = eina_list_append(list, EO_OBJ(it));
7240 EOLIAN static Elm_Object_Item *
7241 _elm_genlist_search_by_text_item_get(Eo *obj EINA_UNUSED,
7242 Elm_Genlist_Data *sd,
7243 Elm_Object_Item *item_to_search_from,
7244 const char *part_name,
7245 const char *pattern,
7246 Elm_Glob_Match_Flags flags)
7248 Elm_Gen_Item *it = NULL;
7250 Eina_Inlist *start = NULL;
7253 if (!pattern) return NULL;
7254 if (!sd->items) return NULL;
7256 if (flags & ELM_GLOB_MATCH_NO_ESCAPE) fnflags |= FNM_NOESCAPE;
7257 if (flags & ELM_GLOB_MATCH_PATH) fnflags |= FNM_PATHNAME;
7258 if (flags & ELM_GLOB_MATCH_PERIOD) fnflags |= FNM_PERIOD;
7260 if (flags & ELM_GLOB_MATCH_NOCASE) fnflags |= FNM_CASEFOLD;
7263 start = (item_to_search_from) ?
7264 EINA_INLIST_GET((Elm_Gen_Item *)eo_data_scope_get(item_to_search_from, ELM_GENLIST_ITEM_CLASS)) :
7266 EINA_INLIST_FOREACH(start, it)
7268 if (!it->itc->func.text_get) continue;
7269 str = it->itc->func.text_get((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), part_name);
7271 if (!fnmatch(pattern, str, fnflags))
7281 EOLIAN static Elm_Object_Item*
7282 _elm_genlist_at_xy_item_get(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y, int *posret)
7284 Evas_Coord ox, oy, ow, oh;
7288 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7290 EINA_INLIST_FOREACH(sd->blocks, itb)
7294 if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->sd->pan_x,
7295 oy + itb->y - itb->sd->pan_y,
7296 sd->minw, itb->minh, x, y, 1, 1))
7298 EINA_LIST_FOREACH(itb->items, l, it)
7300 Evas_Coord itx, ity;
7302 itx = ox + itb->x + it->x - itb->sd->pan_x;
7303 ity = oy + itb->y + it->y - itb->sd->pan_y;
7304 if (ELM_RECTS_INTERSECT
7305 (itx, ity, GL_IT(it)->w, GL_IT(it)->h, x, y, 1, 1))
7309 if (y <= (ity + (GL_IT(it)->h / 4))) *posret = -1;
7310 else if (y >= (ity + GL_IT(it)->h - (GL_IT(it)->h / 4)))
7317 lasty = ity + GL_IT(it)->h;
7322 if (y > lasty) *posret = 1;
7329 EOLIAN static Elm_Object_Item*
7330 _elm_genlist_first_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7332 Elm_Gen_Item *tit, *it = NULL;
7334 EINA_INLIST_REVERSE_FOREACH(sd->items, tit) it = tit;
7339 EOLIAN static Elm_Object_Item*
7340 _elm_genlist_last_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7344 if (!sd->items) return NULL;
7346 it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
7350 EOLIAN static Elm_Object_Item *
7351 _elm_genlist_item_next_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7355 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
7359 if (it) return EO_OBJ(it);
7363 EOLIAN static Elm_Object_Item *
7364 _elm_genlist_item_prev_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7368 it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7372 if (it) return EO_OBJ(it);
7376 EOLIAN static Elm_Object_Item *
7377 _elm_genlist_item_parent_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7379 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
7381 return EO_OBJ(it->parent);
7384 EOLIAN static unsigned int
7385 _elm_genlist_item_subitems_count(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
7387 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, 0);
7389 return eina_list_count(item->item->items);
7392 EOLIAN static const Eina_List *
7393 _elm_genlist_item_subitems_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
7395 ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
7397 return item->item->items;
7401 _elm_genlist_item_subitems_clear(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7403 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7405 Elm_Object_Item *eo_it2;
7407 EINA_LIST_FOREACH_SAFE(GL_IT(it)->items, l, ll, eo_it2)
7408 eo_do(eo_it2, elm_wdg_item_del());
7412 _elm_genlist_item_selected_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
7415 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7418 if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get())) return;
7419 // FIXME: This API has highlight/unhighlith feature also..
7421 if (selected) _item_highlight(it);
7422 else _item_unhighlight(it, EINA_TRUE);
7424 selected = !!selected;
7425 if (it->selected == selected) return;
7427 if (selected) _item_select(it);
7428 else _item_unselect(it);
7431 EOLIAN static Eina_Bool
7432 _elm_genlist_item_selected_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7434 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7436 return it->selected;
7440 _elm_genlist_item_expanded_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool expanded)
7442 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7444 expanded = !!expanded;
7445 if (GL_IT(it)->expanded == expanded) return;
7446 if (GL_IT(it)->type != ELM_GENLIST_ITEM_TREE) return;
7447 GL_IT(it)->expanded = expanded;
7448 GL_IT(it)->wsd->expanded_item = it;
7450 if (GL_IT(it)->expanded)
7453 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
7454 evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, EO_OBJ(it));
7455 if (_elm_atspi_enabled())
7456 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_item);
7461 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACTED, "elm");
7462 evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, EO_OBJ(it));
7463 if (_elm_atspi_enabled())
7464 elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_item);
7468 EOLIAN static Eina_Bool
7469 _elm_genlist_item_expanded_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7471 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7473 return GL_IT(it)->expanded;
7477 _elm_genlist_item_expanded_depth_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7479 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, 0);
7481 return GL_IT(it)->expanded_depth;
7485 _elm_genlist_item_promote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7487 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7489 Elm_Object_Item *eo_first_item = elm_genlist_first_item_get(WIDGET(it));
7490 ELM_GENLIST_ITEM_DATA_GET(eo_first_item, first_item);
7491 _item_move_before(it, first_item);
7495 _elm_genlist_item_demote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7497 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7498 Elm_Object_Item *eo_last_item = elm_genlist_last_item_get(WIDGET(it));
7499 ELM_GENLIST_ITEM_DATA_GET(eo_last_item, last_item);
7500 _item_move_after(it, last_item);
7504 _elm_genlist_item_show(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
7506 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7508 if (it->want_hidden)
7510 WRN("Filter hided item cannot move to show");
7514 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7516 sd->bring_in = EINA_FALSE;
7517 sd->scroll_to_type = type;
7518 _changed(sd->pan_obj);
7522 _elm_genlist_item_bring_in(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
7524 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7526 if (it->want_hidden)
7528 WRN("Filter hided item cannot move to bring in");
7532 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7533 ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wd);
7534 sd->bring_in = EINA_TRUE;
7535 sd->scroll_to_type = type;
7537 if (wd->scroll_item_align_enable)
7539 it = _adjust_item_align(it);
7540 sd->adjusted_item = sd->show_item = it;
7542 if (sd->aligned_item && sd->show_item != sd->aligned_item)
7543 edje_object_signal_emit(VIEW(sd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
7548 _changed(sd->pan_obj);
7552 _elm_genlist_item_all_contents_unset(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_List **l)
7554 Evas_Object *content;
7556 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7558 EINA_LIST_FREE (it->content_objs, content)
7560 evas_object_smart_member_del(content);
7561 // edje can be reused by item caching,
7562 // content should be un-swallowed from edje
7563 edje_object_part_unswallow(VIEW(it), content);
7564 evas_object_hide(content);
7565 if (l) *l = eina_list_append(*l, content);
7570 _elm_genlist_item_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7572 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7574 if (!GL_IT(it)->block) return;
7576 GL_IT(it)->updateme = EINA_TRUE;
7577 GL_IT(it)->block->calc_done = EINA_FALSE;
7578 GL_IT(it)->wsd->calc_done = EINA_FALSE;
7579 _changed(GL_IT(it)->wsd->pan_obj);
7583 _elm_genlist_item_fields_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
7585 Elm_Genlist_Item_Field_Type itf)
7587 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7589 if (!GL_IT(it)->block) return;
7591 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
7593 _item_text_realize(it, VIEW(it), parts);
7595 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
7597 _item_content_realize(it, VIEW(it), &it->content_objs, "contents", parts);
7600 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_content_objs,
7603 if (GL_IT(it)->deco_it_view)
7605 _item_content_realize(it, GL_IT(it)->deco_it_view,
7606 &GL_IT(it)->deco_it_contents,
7609 if (GL_IT(it)->wsd->decorate_all_mode)
7611 _item_content_realize(it, it->deco_all_view,
7612 &GL_IT(it)->deco_all_contents,
7617 if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
7618 _item_state_realize(it, VIEW(it), parts);
7620 GL_IT(it)->calc_done = EINA_FALSE;
7621 GL_IT(it)->block->calc_done = EINA_FALSE;
7622 GL_IT(it)->wsd->calc_done = EINA_FALSE;
7623 _changed(GL_IT(it)->wsd->pan_obj);
7627 _elm_genlist_item_item_class_update(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
7628 const Elm_Genlist_Item_Class *itc)
7630 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7631 EINA_SAFETY_ON_NULL_RETURN(itc);
7632 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7635 if (!GL_IT(it)->block) return;
7637 // FIXME(160711): orignal edje object updated by _view_theme_update
7638 // cannot recieve signal emit properly. This edje bug must be fixed.
7639 _item_cache_all_free(sd);
7641 sd->no_cache = EINA_TRUE;
7642 _item_unrealize(it, EINA_FALSE);
7643 sd->no_cache = EINA_FALSE;
7644 _item_realize(it, EINA_FALSE);
7646 if (sd->aligned_item == it)
7647 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
7649 GL_IT(it)->calc_done = EINA_FALSE;
7650 GL_IT(it)->block->calc_done = EINA_FALSE;
7651 sd->calc_done = EINA_FALSE;
7653 _changed(sd->pan_obj);
7656 EOLIAN static const Elm_Genlist_Item_Class *
7657 _elm_genlist_item_item_class_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7659 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
7663 static Evas_Object *
7664 _elm_genlist_item_label_create(void *data,
7665 Evas_Object *obj EINA_UNUSED,
7666 Evas_Object *tooltip,
7667 void *it EINA_UNUSED)
7669 Evas_Object *label = elm_label_add(tooltip);
7674 elm_object_style_set(label, "tooltip");
7675 elm_object_text_set(label, data);
7681 _elm_genlist_item_label_del_cb(void *data,
7682 Evas_Object *obj EINA_UNUSED,
7683 void *event_info EINA_UNUSED)
7685 eina_stringshare_del(data);
7689 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
7692 eo_do(it, elm_wdg_item_tooltip_text_set(text));
7696 _elm_genlist_item_elm_widget_item_tooltip_text_set(Eo *eo_it, Elm_Gen_Item *it, const char *text)
7698 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7700 text = eina_stringshare_add(text);
7701 elm_genlist_item_tooltip_content_cb_set
7702 (eo_it, _elm_genlist_item_label_create, text,
7703 _elm_genlist_item_label_del_cb);
7707 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item,
7708 Elm_Tooltip_Item_Content_Cb func,
7710 Evas_Smart_Cb del_cb)
7712 eo_do(item, elm_wdg_item_tooltip_content_cb_set(func, data, del_cb));
7717 _elm_genlist_item_elm_widget_item_tooltip_content_cb_set(Eo *eo_it, Elm_Gen_Item *it,
7718 Elm_Tooltip_Item_Content_Cb func,
7720 Evas_Smart_Cb del_cb)
7722 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7724 if ((it->tooltip.content_cb != func) || (it->tooltip.data != data))
7726 if (it->tooltip.del_cb)
7727 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7729 it->tooltip.content_cb = func;
7730 it->tooltip.data = data;
7731 it->tooltip.del_cb = del_cb;
7736 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7737 elm_wdg_item_tooltip_content_cb_set
7738 (it->tooltip.content_cb, it->tooltip.data, NULL));
7740 elm_wdg_item_tooltip_style_set(it->tooltip.style),
7741 elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
7746 elm_genlist_item_tooltip_unset(Elm_Object_Item *item)
7748 eo_do(item, elm_wdg_item_tooltip_unset());
7752 _elm_genlist_item_elm_widget_item_tooltip_unset(Eo *eo_it, Elm_Gen_Item *it)
7754 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7756 if ((VIEW(it)) && (it->tooltip.content_cb))
7757 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7758 elm_wdg_item_tooltip_unset());
7760 if (it->tooltip.del_cb)
7761 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7762 it->tooltip.del_cb = NULL;
7763 it->tooltip.content_cb = NULL;
7764 it->tooltip.data = NULL;
7765 it->tooltip.free_size = EINA_FALSE;
7766 if (it->tooltip.style)
7767 eo_do(eo_it, elm_wdg_item_tooltip_style_set(NULL));
7771 elm_genlist_item_tooltip_style_set(Elm_Object_Item *item,
7774 eo_do(item, elm_wdg_item_tooltip_style_set(style));
7778 _elm_genlist_item_elm_widget_item_tooltip_style_set(Eo *eo_it, Elm_Gen_Item *it,
7781 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7783 eina_stringshare_replace(&it->tooltip.style, style);
7784 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7785 elm_wdg_item_tooltip_style_set(style));
7789 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
7792 return eo_do_ret(it, style, elm_wdg_item_tooltip_style_get());
7795 EOLIAN static const char *
7796 _elm_genlist_item_elm_widget_item_tooltip_style_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7798 return it->tooltip.style;
7802 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *item,
7806 return eo_do_ret(item, ret, elm_wdg_item_tooltip_window_mode_set(disable));
7809 EOLIAN static Eina_Bool
7810 _elm_genlist_item_elm_widget_item_tooltip_window_mode_set(Eo *eo_it, Elm_Gen_Item *it,
7813 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7816 it->tooltip.free_size = disable;
7818 return eo_do_super_ret(eo_it, ELM_GENLIST_ITEM_CLASS, ret,
7819 elm_wdg_item_tooltip_window_mode_set(disable));
7825 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *eo_it)
7828 return eo_do_ret(eo_it, ret, elm_wdg_item_tooltip_window_mode_get());
7831 EOLIAN static Eina_Bool
7832 _elm_genlist_item_elm_widget_item_tooltip_window_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7834 return it->tooltip.free_size;
7838 elm_genlist_item_cursor_set(Elm_Object_Item *item,
7841 eo_do(item, elm_wdg_item_cursor_set(cursor));
7845 _elm_genlist_item_elm_widget_item_cursor_set(Eo *eo_it, Elm_Gen_Item *it,
7848 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7849 eina_stringshare_replace(&it->mouse_cursor, cursor);
7850 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7851 elm_wdg_item_cursor_set(cursor));
7855 elm_genlist_item_cursor_get(const Elm_Object_Item *eo_it)
7858 return eo_do_ret(eo_it, cursor, elm_wdg_item_cursor_get());
7862 elm_genlist_item_cursor_unset(Elm_Object_Item *item)
7864 eo_do(item, elm_wdg_item_cursor_unset());
7868 _elm_genlist_item_elm_widget_item_cursor_unset(Eo *eo_it, Elm_Gen_Item *it)
7870 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7872 if (!it->mouse_cursor) return;
7874 if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7875 elm_wdg_item_cursor_unset());
7877 ELM_SAFE_FREE(it->mouse_cursor, eina_stringshare_del);
7881 elm_genlist_item_cursor_style_set(Elm_Object_Item *eo_it,
7884 eo_do(eo_it, elm_wdg_item_cursor_style_set(style));
7888 elm_genlist_item_cursor_style_get(const Elm_Object_Item *eo_it)
7891 return eo_do_ret( eo_it, style, elm_wdg_item_cursor_style_get());
7895 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *eo_it,
7896 Eina_Bool engine_only)
7898 eo_do(eo_it, elm_wdg_item_cursor_engine_only_set(engine_only));
7902 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *eo_it)
7905 return eo_do_ret( eo_it, ret, elm_wdg_item_cursor_engine_only_get());
7909 _elm_genlist_item_index_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7913 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, -1);
7915 EINA_INLIST_FOREACH(GL_IT(it)->wsd->items, tmp)
7917 if (tmp == it) break;
7924 _elm_genlist_mode_set(Eo *obj, Elm_Genlist_Data *sd, Elm_List_Mode mode)
7926 if (sd->mode == mode) return;
7929 if (sd->mode == ELM_LIST_LIMIT)
7931 sd->scr_minw = EINA_TRUE;
7932 sd->scr_minh = EINA_FALSE;
7934 else if (sd->mode == ELM_LIST_EXPAND)
7936 sd->scr_minw = EINA_TRUE;
7937 sd->scr_minh = EINA_TRUE;
7941 sd->scr_minw = EINA_FALSE;
7942 sd->scr_minh = EINA_FALSE;
7945 elm_layout_sizing_eval(obj);
7948 EOLIAN static Elm_List_Mode
7949 _elm_genlist_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7955 elm_genlist_bounce_set(Evas_Object *obj,
7959 ELM_GENLIST_CHECK(obj);
7960 eo_do(obj, elm_interface_scrollable_bounce_allow_set(h_bounce, v_bounce));
7964 _elm_genlist_elm_interface_scrollable_bounce_allow_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool h_bounce, Eina_Bool v_bounce)
7966 sd->h_bounce = !!h_bounce;
7967 sd->v_bounce = !!v_bounce;
7969 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_bounce_allow_set
7970 (sd->h_bounce, sd->v_bounce));
7971 //sd->s_iface->bounce_allow_set(obj, sd->h_bounce, sd->v_bounce);
7975 elm_genlist_bounce_get(const Evas_Object *obj,
7976 Eina_Bool *h_bounce,
7977 Eina_Bool *v_bounce)
7979 ELM_GENLIST_CHECK(obj);
7980 eo_do( obj, elm_interface_scrollable_bounce_allow_get
7981 (h_bounce, v_bounce));
7985 _elm_genlist_elm_interface_scrollable_bounce_allow_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
7987 if (h_bounce) *h_bounce = sd->h_bounce;
7988 if (v_bounce) *v_bounce = sd->v_bounce;
7992 _elm_genlist_homogeneous_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool homogeneous)
7994 sd->homogeneous = !!homogeneous;
7997 EOLIAN static Eina_Bool
7998 _elm_genlist_homogeneous_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8000 return sd->homogeneous;
8004 _elm_genlist_block_count_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, int count)
8006 EINA_SAFETY_ON_TRUE_RETURN(count < 1);
8008 sd->max_items_per_block = count;
8009 sd->item_cache_max = sd->max_items_per_block * 2;
8010 _item_cache_all_free(sd);
8014 _elm_genlist_block_count_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8016 return sd->max_items_per_block;
8020 _filter_item_internal(Elm_Gen_Item *it)
8022 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8023 if (sd->filter_data && it->itc->func.filter_get)
8025 if (!it->itc->func.filter_get(
8026 (void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)),
8027 WIDGET(it), sd->filter_data))
8029 it->want_hidden = EINA_TRUE;
8030 if (sd->show_item == it) sd->show_item = NULL;
8031 GL_IT(it)->block->calc_done = EINA_FALSE;
8032 sd->calc_done = EINA_FALSE;
8035 sd->filtered_count++;
8037 it->filtered = EINA_TRUE;
8038 sd->processed_count++;
8042 _item_filtered_get(Elm_Gen_Item *it)
8045 if (!it) return EINA_FALSE;
8046 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8049 l = eina_list_data_find_list(sd->filter_queue, it);
8051 sd->filter_queue = eina_list_remove_list(sd->filter_queue, l);
8052 l = eina_list_data_find_list(sd->queue, it);
8055 sd->queue = eina_list_remove_list(sd->queue, l);
8056 GL_IT(it)->queued = EINA_FALSE;
8057 GL_IT(it)->resized = EINA_FALSE;
8058 _item_process(sd, it);
8061 _filter_item_internal(it);
8062 GL_IT(it)->block->calc_done = EINA_FALSE;
8063 sd->calc_done = EINA_FALSE;
8064 _changed(sd->pan_obj);
8066 if (!it->want_hidden) return EINA_TRUE;
8071 _filter_queue_process(Elm_Genlist_Data *sd)
8074 Elm_Gen_Item *it, *first;
8077 t0 = ecore_time_get();
8078 for (n = 0; ((sd->filter_queue) && (sd->processed_count < ITEM_QUEUE_MAX)); n++)
8080 first = it = eina_list_data_get(sd->filter_queue);
8081 //FIXME: This is added as a fail safe code for items not yet processed.
8082 while (it && it->item->queued)
8084 if ((ecore_time_get() - t0) > (ecore_animator_frametime_get()))
8086 sd->filter_queue = eina_list_remove_list
8087 (sd->filter_queue, sd->filter_queue);
8088 sd->filter_queue = eina_list_append(sd->filter_queue, it);
8089 it = eina_list_data_get(sd->filter_queue);
8091 //Do not iterate more than one loop
8092 if (it == first) return n;
8094 sd->filter_queue = eina_list_remove_list(sd->filter_queue, sd->filter_queue);
8097 _filter_item_internal(it);
8098 GL_IT(it)->block->calc_done = EINA_FALSE;
8100 sd->calc_done = EINA_FALSE;
8101 _changed(sd->pan_obj);
8102 if ((ecore_time_get() - t0) > (ecore_animator_frametime_get()))
8104 //At least 1 item is filtered by this time, so return n+1 for first loop
8113 _filter_process(void *data,
8116 Elm_Genlist_Data *sd = data;
8118 if (_filter_queue_process(sd) > 0) *wakeup = EINA_TRUE;
8119 if (!sd->filter_queue) return ECORE_CALLBACK_CANCEL;
8120 return ECORE_CALLBACK_RENEW;
8124 _item_filter_enterer(void *data)
8126 Eina_Bool wakeup = EINA_FALSE;
8127 ELM_GENLIST_DATA_GET(data, sd);
8128 Eina_Bool ok = _filter_process(sd, &wakeup);
8131 if (sd->dummy_job) ecore_job_del(sd->dummy_job);
8132 sd->dummy_job = ecore_job_add(_dummy_job, sd);
8134 if (ok == ECORE_CALLBACK_CANCEL)
8138 ecore_job_del(sd->dummy_job);
8139 sd->dummy_job = NULL;
8141 sd->queue_idle_enterer = NULL;
8142 evas_object_smart_callback_call((Evas_Object *)data, SIG_FILTER_DONE, NULL);
8149 _elm_genlist_filter_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, void *filter_data)
8155 if (sd->filter_queue)
8156 ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
8157 ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
8158 ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
8159 sd->filtered_count = 0;
8160 sd->processed_count = 0;
8161 sd->filter = EINA_TRUE;
8162 sd->filter_data = filter_data;
8164 EINA_INLIST_FOREACH(sd->blocks, itb)
8168 EINA_LIST_FOREACH(itb->items, l, it)
8170 it->filtered = EINA_FALSE;
8171 it->want_hidden = EINA_FALSE;
8173 _filter_item_internal(it);
8175 sd->filter_queue = eina_list_append(sd->filter_queue, it);
8177 itb->calc_done = EINA_FALSE;
8178 sd->calc_done = EINA_FALSE;
8182 EINA_LIST_FOREACH(itb->items, l, it)
8184 it->filtered = EINA_FALSE;
8185 it->want_hidden = EINA_FALSE;
8186 sd->filter_queue = eina_list_append(sd->filter_queue, it);
8190 _changed(sd->pan_obj);
8192 sd->queue_filter_enterer = ecore_idle_enterer_add(_item_filter_enterer,
8197 _filter_iterator_next(Elm_Genlist_Filter *iter, void **data)
8199 if (!iter->current) return EINA_FALSE;
8201 while (iter->current)
8203 item = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->current, Elm_Gen_Item);
8204 iter->current = iter->current->next;
8205 if (_item_filtered_get(item))
8208 *data = EO_OBJ(item);
8217 _filter_iterator_free(Elm_Genlist_Filter *iter)
8222 static Evas_Object *
8223 _filter_iterator_get_container(Elm_Genlist_Filter *iter)
8225 Elm_Gen_Item *it = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->head, Elm_Gen_Item);
8229 EOLIAN Eina_Iterator *
8230 _elm_genlist_filter_iterator_new(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8232 Elm_Genlist_Filter *iter;
8233 iter = calloc(1, sizeof (Elm_Genlist_Filter));
8234 if (!iter) return NULL;
8236 iter->head = sd->items;
8237 iter->current = sd->items;
8239 iter->iterator.version = EINA_ITERATOR_VERSION;
8240 iter->iterator.next = FUNC_ITERATOR_NEXT(_filter_iterator_next);
8241 iter->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
8242 _filter_iterator_get_container);
8243 iter->iterator.free = FUNC_ITERATOR_FREE(_filter_iterator_free);
8245 EINA_MAGIC_SET(&iter->iterator, EINA_MAGIC_ITERATOR);
8247 return &iter->iterator;
8251 _elm_genlist_longpress_timeout_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, double timeout)
8253 sd->longpress_timeout = timeout;
8256 EOLIAN static double
8257 _elm_genlist_longpress_timeout_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8259 return sd->longpress_timeout;
8263 elm_genlist_scroller_policy_set(Evas_Object *obj,
8264 Elm_Scroller_Policy policy_h,
8265 Elm_Scroller_Policy policy_v)
8267 ELM_GENLIST_CHECK(obj);
8268 eo_do(obj, elm_interface_scrollable_policy_set(policy_h, policy_v));
8272 _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)
8274 ELM_GENLIST_CHECK(obj);
8276 if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
8277 (policy_v >= ELM_SCROLLER_POLICY_LAST))
8280 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_set(policy_h, policy_v));
8284 elm_genlist_scroller_policy_get(const Evas_Object *obj,
8285 Elm_Scroller_Policy *policy_h,
8286 Elm_Scroller_Policy *policy_v)
8288 ELM_GENLIST_CHECK(obj);
8289 eo_do( obj, elm_interface_scrollable_policy_get(policy_h, policy_v));
8293 _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)
8295 Elm_Scroller_Policy s_policy_h, s_policy_v;
8297 ELM_GENLIST_CHECK(obj);
8299 eo_do((Eo *)obj, elm_interface_scrollable_policy_get(&s_policy_h, &s_policy_v));
8300 if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
8301 if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
8305 _elm_genlist_realized_items_update(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED)
8308 Elm_Object_Item *eo_it;
8310 ELM_GENLIST_CHECK(obj);
8312 list = elm_genlist_realized_items_get(obj);
8313 EINA_LIST_FREE(list, eo_it)
8314 elm_genlist_item_update(eo_it);
8318 _elm_genlist_item_decorate_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8319 const char *decorate_it_type,
8320 Eina_Bool decorate_it_set)
8322 Elm_Genlist_Data *sd;
8325 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8326 sd = GL_IT(it)->wsd;
8328 if (!decorate_it_type) return;
8329 if (eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get())) return;
8330 if (sd->decorate_all_mode) return;
8332 if ((sd->mode_item == it) &&
8333 (!strcmp(decorate_it_type, sd->decorate_it_type)) &&
8336 if (!it->itc->decorate_item_style) return;
8337 it->decorate_it_set = decorate_it_set;
8340 if (((sd->decorate_it_type)
8341 && (strcmp(decorate_it_type, sd->decorate_it_type))) ||
8342 (decorate_it_set) || ((it == sd->mode_item) && (!decorate_it_set)))
8344 char buf[1024], buf2[1024];
8346 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8347 if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
8348 sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
8350 snprintf(buf, sizeof(buf), "elm,state,%s,passive", sd->decorate_it_type);
8351 edje_object_signal_emit(GL_IT(it)->deco_it_view, buf, "elm");
8352 edje_object_signal_emit(VIEW(it), buf, "elm");
8354 snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished",
8355 sd->decorate_it_type);
8356 edje_object_signal_callback_add(GL_IT(it)->deco_it_view, buf2,
8358 _decorate_item_finished_signal_cb, it);
8359 sd->mode_item = NULL;
8362 eina_stringshare_replace(&sd->decorate_it_type, decorate_it_type);
8363 if (decorate_it_set)
8366 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8367 if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
8368 sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
8370 _decorate_item_realize(it);
8374 EOLIAN static const char *
8375 _elm_genlist_item_decorate_mode_get(Eo *eo_i EINA_UNUSED, Elm_Gen_Item *i)
8377 ELM_GENLIST_ITEM_CHECK_OR_RETURN(i, NULL);
8378 return GL_IT(i)->wsd->decorate_it_type;
8381 EOLIAN static Elm_Object_Item *
8382 _elm_genlist_decorated_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8384 return EO_OBJ(sd->mode_item);
8387 EOLIAN static Eina_Bool
8388 _elm_genlist_decorate_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8390 return sd->decorate_all_mode;
8394 _elm_genlist_decorate_mode_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool decorated)
8396 Elm_Object_Item *eo_it;
8399 decorated = !!decorated;
8400 if (sd->decorate_all_mode == decorated) return;
8401 // decorate_all_mode should be set first
8402 // because content_get func. will be called after this
8403 // and user can check whether deocrate_all_mode is enabeld.
8404 sd->decorate_all_mode = decorated;
8406 list = elm_genlist_realized_items_get(obj);
8407 EINA_LIST_FREE(list, eo_it)
8409 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8411 if (!sd->decorate_all_mode)
8413 _decorate_all_item_unrealize(it);
8415 else if (it->itc->decorate_all_item_style)
8417 _decorate_all_item_realize(it, EINA_TRUE);
8419 _access_widget_item_register(it);
8421 _changed(sd->pan_obj);
8425 _elm_genlist_reorder_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool reorder_mode)
8428 Elm_Object_Item *eo_it;
8430 if (sd->reorder_mode == !!reorder_mode) return;
8431 sd->reorder_mode = !!reorder_mode;
8433 list = elm_genlist_realized_items_get(obj);
8434 EINA_LIST_FREE(list, eo_it)
8436 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8437 if (sd->reorder_mode)
8439 edje_object_signal_emit
8440 (VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
8441 if (it->deco_all_view)
8442 edje_object_signal_emit
8443 (it->deco_all_view, SIGNAL_REORDER_MODE_SET, "elm");
8447 edje_object_signal_emit
8448 (VIEW(it), SIGNAL_REORDER_MODE_UNSET, "elm");
8449 if (it->deco_all_view)
8450 edje_object_signal_emit
8451 (it->deco_all_view, SIGNAL_REORDER_MODE_UNSET, "elm");
8456 EOLIAN static Eina_Bool
8457 _elm_genlist_reorder_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8459 return sd->reorder_mode;
8462 EOLIAN static Elm_Genlist_Item_Type
8463 _elm_genlist_item_type_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8465 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
8467 return GL_IT(it)->type;
8470 EAPI Elm_Genlist_Item_Class *
8471 elm_genlist_item_class_new(void)
8473 Elm_Genlist_Item_Class *itc = ELM_NEW(Elm_Genlist_Item_Class);
8474 EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
8476 itc->version = CLASS_ALLOCATED;
8478 itc->delete_me = EINA_FALSE;
8479 // TIZEN ONLY(20160630): Support homogeneous mode in item class.
8480 itc->homogeneous = EINA_FALSE;
8487 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
8489 if (itc && (itc->version == CLASS_ALLOCATED))
8491 itc->delete_me = EINA_TRUE;
8492 if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
8502 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
8504 if (itc && (itc->version == CLASS_ALLOCATED))
8507 if (itc->refcount == 0) itc->refcount--;
8512 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
8514 if (itc && (itc->version == CLASS_ALLOCATED))
8516 if (itc->refcount > 0) itc->refcount--;
8517 if (itc->delete_me && (!itc->refcount))
8518 elm_genlist_item_class_free(itc);
8523 _elm_genlist_item_flip_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool flip)
8525 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8528 if (it->flipped == flip) return;
8533 _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_content_objs,
8536 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
8537 if (GL_IT(it)->wsd->decorate_all_mode)
8538 edje_object_signal_emit
8539 (it->deco_all_view, SIGNAL_FLIP_ENABLED, "elm");
8544 edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_DISABLED, "elm");
8545 if (GL_IT(it)->wsd->decorate_all_mode)
8546 edje_object_signal_emit
8547 (it->deco_all_view, SIGNAL_FLIP_DISABLED, "elm");
8549 EINA_LIST_FREE(GL_IT(it)->flip_content_objs, c)
8552 // FIXME: update texts should be done by app?
8553 _item_text_realize(it, VIEW(it), NULL);
8555 _access_widget_item_register(it);
8558 EOLIAN static Eina_Bool
8559 _elm_genlist_item_flip_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8561 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
8567 _elm_genlist_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Elm_Object_Select_Mode mode)
8569 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (sd->select_mode == mode))
8572 sd->select_mode = mode;
8574 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8575 (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
8578 Elm_Object_Item *eo_it;
8579 EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
8581 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8585 if (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
8588 EINA_INLIST_FOREACH(sd->items, it)
8590 if (!GL_IT(it)->block) continue;
8591 GL_IT(it)->calc_done = EINA_FALSE;
8592 GL_IT(it)->block->calc_done = EINA_FALSE;
8593 sd->calc_done = EINA_FALSE;
8594 _changed(sd->pan_obj);
8599 EOLIAN static Elm_Object_Select_Mode
8600 _elm_genlist_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8602 return sd->select_mode;
8606 _elm_genlist_highlight_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool highlight)
8608 sd->highlight = !!highlight;
8611 EOLIAN static Eina_Bool
8612 _elm_genlist_highlight_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8614 return sd->highlight;
8618 _elm_genlist_item_select_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8619 Elm_Object_Select_Mode mode)
8621 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8623 if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (it->select_mode == mode))
8626 it->select_mode = mode;
8628 if ((it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8629 (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
8632 if (GL_IT(it)->block && it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
8634 GL_IT(it)->calc_done = EINA_FALSE;
8635 GL_IT(it)->block->calc_done = EINA_FALSE;
8636 GL_IT(it)->wsd->calc_done = EINA_FALSE;
8637 _changed(GL_IT(it)->wsd->pan_obj);
8641 EOLIAN static Elm_Object_Select_Mode
8642 _elm_genlist_item_select_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8644 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
8646 return it->select_mode;
8649 EOLIAN Elm_Atspi_State_Set
8650 _elm_genlist_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_it, Elm_Gen_Item *it EINA_UNUSED)
8652 Elm_Atspi_State_Set ret;
8655 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
8657 eo_do(eo_it, sel = elm_obj_genlist_item_selected_get());
8659 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTABLE);
8662 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTED);
8664 if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_TREE)
8666 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDABLE);
8667 if (elm_genlist_item_expanded_get(eo_it))
8668 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8669 //TIZEN_ONLY(20160606): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8671 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8674 //TIZEN_ONLY(20160608): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8675 else if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_GROUP)
8677 if (elm_genlist_item_expanded_get(eo_it))
8678 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8680 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8688 _elm_genlist_item_elm_interface_atspi_accessible_name_get(Eo *eo_it,
8693 char *accessible_name;
8694 eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_name_get());
8695 if (ret) return ret;
8697 buf = eina_strbuf_new();
8699 if (it->itc->func.text_get)
8705 elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
8707 EINA_LIST_FREE(texts, key)
8709 char *str_markup = it->itc->func.text_get
8710 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
8711 char *str_utf8 = _elm_util_mkup_to_text(str_markup);
8715 if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
8716 eina_strbuf_append(buf, str_utf8);
8722 accessible_name = eina_strbuf_string_steal(buf);
8723 eina_strbuf_free(buf);
8725 eina_stringshare_del(it->base->accessible_name);
8726 it->base->accessible_name = eina_stringshare_add(accessible_name);
8727 free(accessible_name);
8728 return it->base->accessible_name;
8732 _elm_genlist_item_elm_interface_atspi_accessible_children_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8734 Eina_List *ret = NULL;
8739 parts = elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "contents"));
8741 EINA_LIST_FREE(parts, key)
8744 part = edje_object_part_swallow_get(VIEW(it), key);
8745 if (part && eo_isa(part, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
8747 ret = eina_list_append(ret, part);
8748 eo_do(part, elm_interface_atspi_accessible_parent_set(eo_it));
8756 ///////////////////////////////////////////////////////////////////////////////
8757 //TIZEN ONLY:(20150623): Region show on item elements fixed
8758 //Grab and clear highlight on genlist items
8759 ///////////////////////////////////////////////////////////////////////////////
8760 EOLIAN static Eina_Bool
8761 _elm_genlist_item_elm_interface_atspi_component_highlight_grab(Eo *eo_it, Elm_Gen_Item *it)
8763 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8765 if (!TIZEN_PROFILE_WEARABLE)
8767 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
8768 eo_do_super(EO_OBJ(it), ELM_GENLIST_ITEM_CLASS, elm_interface_atspi_component_highlight_grab());
8773 // TIZEN_ONLY(20171011) : atspi : Do not center align when genlist item is highlighted in wearable profile
8774 //FIXME : First, last item is called centered because it may not have a proxy image.
8775 // This part will be revised in the next version.
8776 Eina_List *realized = elm_genlist_realized_items_get(WIDGET(it));
8777 if (VIEW(it) || realized)
8779 Elm_Object_Item *first_it = elm_genlist_first_item_get(WIDGET(it));
8780 Elm_Object_Item *last_it = elm_genlist_last_item_get(WIDGET(it));
8781 if (first_it == eo_it || last_it == eo_it)
8782 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
8784 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
8787 eina_list_free(realized);
8791 elm_object_accessibility_highlight_set(EO_OBJ(it), EINA_TRUE);
8792 ///TIZEN_ONLY(20170717) : expose highlight information on atspi
8793 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
8796 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
8797 // If you call eo_do_super, then you do NOT have to call smart callback.
8798 evas_object_smart_callback_call(WIDGET(it), "atspi,highlighted", EO_OBJ(it));
8805 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8806 sd->currently_highlighted_item = it;
8811 if (!TIZEN_PROFILE_WEARABLE)
8813 //TIZEN_ONLY(20170724): grab highlight using unrealized item
8814 elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
8817 sd->atspi_item_to_highlight = it;//it will be highlighted when realized
8820 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8821 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
8827 EOLIAN static Eina_Bool
8828 _elm_genlist_item_elm_interface_atspi_component_highlight_clear(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8830 ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8831 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8832 if(sd->currently_highlighted_item == it)
8833 sd->currently_highlighted_item = NULL;
8835 if (sd->atspi_item_to_highlight == it)
8836 sd->atspi_item_to_highlight = NULL;
8837 elm_object_accessibility_highlight_set(EO_OBJ(it), EINA_FALSE);
8838 ///TIZEN_ONLY(20170717) : expose highlight information on atspi
8839 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
8842 //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8843 edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
8845 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
8846 // If you call eo_do_super, then you do NOT have to call smart callback.
8847 evas_object_smart_callback_call(WIDGET(it), "atspi,unhighlighted", EO_OBJ(it));
8852 ///////////////////////////////////////////////////////////////////////////////
8855 _elm_genlist_tree_effect_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enabled EINA_UNUSED)
8857 // Need to implemented
8858 //sd->tree_effect_enabled = !!enabled;
8861 EOLIAN static Eina_Bool
8862 _elm_genlist_tree_effect_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
8868 _elm_genlist_focus_on_selection_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enabled EINA_UNUSED)
8870 // Need to Implemented
8871 sd->focus_on_selection_enabled = !!enabled;
8874 EOLIAN static Eina_Bool
8875 _elm_genlist_focus_on_selection_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
8877 // Need to Implemented
8878 return sd->focus_on_selection_enabled;
8881 EAPI Elm_Object_Item *
8882 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth)
8884 Elm_Gen_Item *it = NULL;
8888 ELM_GENLIST_CHECK(obj) NULL;
8889 ELM_GENLIST_DATA_GET(obj, sd);
8891 if (!sd->items) return NULL;
8893 a = eina_inlist_accessor_new(sd->items);
8894 if (!a) return NULL;
8895 if (eina_accessor_data_get(a, nth, &data))
8896 it = ELM_GEN_ITEM_FROM_INLIST(data);
8897 eina_accessor_free(a);
8902 elm_genlist_fx_mode_set(Evas_Object *obj, Eina_Bool mode)
8904 ELM_GENLIST_CHECK(obj);
8905 ELM_GENLIST_DATA_GET(obj, sd);
8912 elm_genlist_fx_mode_get(const Evas_Object *obj)
8914 ELM_GENLIST_CHECK(obj) EINA_FALSE;
8915 ELM_GENLIST_DATA_GET(obj, sd);
8921 elm_genlist_item_hide_set(const Elm_Object_Item *eo_item EINA_UNUSED, Eina_Bool hide EINA_UNUSED)
8923 WRN("This API is deprecated, please use filter_set instead of this");
8927 elm_genlist_item_hide_get(const Elm_Object_Item *eo_item EINA_UNUSED)
8929 WRN("This API is deprecated, please use filter_set instead of this");
8933 ///////////////////////////////////////////////////////////////////////////////
8934 //TIZEN ONLY:(20150126): its not decided whether deprecated or not to give away
8935 ///////////////////////////////////////////////////////////////////////////////
8937 elm_genlist_realization_mode_set(Evas_Object *obj, Eina_Bool realization_mode)
8939 ELM_GENLIST_CHECK(obj);
8940 ELM_GENLIST_DATA_GET(obj, sd);
8942 if (sd->realization_mode == realization_mode) return;
8943 sd->realization_mode = realization_mode;
8947 elm_genlist_realization_mode_get(Evas_Object *obj)
8949 ELM_GENLIST_CHECK(obj) EINA_FALSE;
8950 ELM_GENLIST_DATA_GET(obj, sd);
8952 return sd->realization_mode;
8954 ///////////////////////////////////////////////////////////////////////////////
8957 elm_genlist_item_reorder_start(Elm_Object_Item *eo_item)
8959 ELM_GENLIST_ITEM_DATA_GET(eo_item, it);
8960 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8961 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
8963 sd->reorder.it = it;
8965 eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8966 eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
8967 (EINA_FALSE, EINA_FALSE));
8968 //sd->s_iface->hold_set(sd->obj, EINA_TRUE);
8969 //sd->s_iface->bounce_allow_set(sd->obj, EINA_FALSE, EINA_FALSE);
8970 sd->reorder_force = EINA_TRUE;
8974 elm_genlist_item_reorder_stop(Elm_Object_Item *eo_item)
8976 ELM_GENLIST_ITEM_DATA_GET(eo_item, it);
8977 ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8978 Elm_Genlist_Data *sd = GL_IT(it)->wsd;
8980 sd->reorder_force = EINA_FALSE;
8984 _elm_genlist_class_constructor(Eo_Class *klass)
8986 if (_elm_config->access_mode)
8987 _elm_genlist_smart_focus_next_enable = EINA_TRUE;
8989 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
8993 _elm_genlist_elm_interface_atspi_accessible_children_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8995 Eina_List *ret = NULL;
8998 EINA_INLIST_FOREACH(sd->items, it)
8999 ret = eina_list_append(ret, EO_OBJ(it));
9004 EOLIAN Elm_Atspi_State_Set
9005 _elm_genlist_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED)
9007 Elm_Atspi_State_Set ret;
9009 eo_do_super(obj, ELM_GENLIST_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
9011 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MANAGES_DESCENDANTS);
9013 if (elm_genlist_multi_select_get(obj))
9014 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MULTISELECTABLE);
9020 _elm_genlist_elm_interface_atspi_selection_selected_children_count_get(Eo *objm EINA_UNUSED, Elm_Genlist_Data *pd)
9022 return eina_list_count(pd->selected);
9026 _elm_genlist_elm_interface_atspi_selection_selected_child_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_idx)
9028 return eina_list_nth(pd->selected, child_idx);
9032 _elm_genlist_elm_interface_atspi_selection_child_select(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9035 if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
9037 EINA_INLIST_FOREACH(pd->items, item)
9039 if (child_index-- == 0)
9041 elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
9050 _elm_genlist_elm_interface_atspi_selection_selected_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9055 EINA_LIST_FOREACH(pd->selected, l, item)
9057 if (child_index-- == 0)
9059 elm_genlist_item_selected_set(item, EINA_FALSE);
9067 _elm_genlist_elm_interface_atspi_selection_is_child_selected(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9071 EINA_INLIST_FOREACH(pd->items, item)
9073 if (child_index-- == 0)
9075 return elm_genlist_item_selected_get(EO_OBJ(item));
9082 _elm_genlist_elm_interface_atspi_selection_all_children_select(Eo *obj, Elm_Genlist_Data *pd)
9086 if (!elm_genlist_multi_select_get(obj))
9089 EINA_INLIST_FOREACH(pd->items, item)
9090 elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
9096 _elm_genlist_elm_interface_atspi_selection_clear(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd)
9098 return _all_items_deselect(pd);
9102 _elm_genlist_elm_interface_atspi_selection_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9105 if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
9107 EINA_INLIST_FOREACH(pd->items, item)
9109 if (child_index-- == 0)
9111 elm_genlist_item_selected_set(EO_OBJ(item), EINA_FALSE);
9119 // TIZEN only (20150914) : Accessibility: updated highlight change during genlist and list scroll
9120 static int _is_item_in_viewport(int viewport_y, int viewport_h, int obj_y, int obj_h)
9122 if (obj_y + obj_h <= viewport_y)
9124 else if (obj_y >= viewport_y + viewport_h)
9130 _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)
9132 if (!_elm_atspi_enabled())
9134 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
9138 int old_x, old_y, delta_y;
9139 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_get(&old_x,&old_y));
9140 eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
9141 delta_y = old_y - y;
9143 //check if highlighted item is genlist descendant
9144 Evas_Object * highlighted_obj = _elm_object_accessibility_currently_highlighted_get();
9145 if (eo_isa(highlighted_obj, ELM_WIDGET_ITEM_CLASS))
9147 Elm_Widget_Item_Data *id = eo_data_scope_get(highlighted_obj, ELM_WIDGET_ITEM_CLASS);
9148 highlighted_obj = id->view;
9151 Evas_Object * parent = highlighted_obj;
9152 if (eo_isa(highlighted_obj, ELM_WIDGET_CLASS))
9154 while ((parent = elm_widget_parent_get(parent)))
9158 else if (eo_isa(highlighted_obj, EDJE_OBJECT_CLASS))
9160 while ((parent = evas_object_smart_parent_get(parent)))
9164 // TIZEN_ONLY(20160805): set _accessibility_currently_highlighted_obj to NULL in object delete callback
9167 WRN("Improper highlighted object: %p", highlighted_obj);
9174 int obj_x, obj_y, w, h, hx, hy, hw, hh;
9175 evas_object_geometry_get(obj, &obj_x, &obj_y, &w, &h);
9177 evas_object_geometry_get(highlighted_obj, &hx, &hy, &hw, &hh);
9179 Elm_Gen_Item * next_previous_item = NULL;
9180 int viewport_position_result = _is_item_in_viewport(obj_y, h, hy, hh);
9181 //only highlight if move direction is correct
9182 //sometimes highlighted item is brought in and it does not fit viewport
9183 //however content goes to the viewport position so soon it will
9184 //meet _is_item_in_viewport condition
9185 if ((viewport_position_result < 0 && delta_y > 0) ||
9186 (viewport_position_result > 0 && delta_y < 0))
9189 Eina_List *realized_items = elm_genlist_realized_items_get(obj);
9192 Eina_Bool traverse_direction = viewport_position_result > 0;
9193 l = traverse_direction ? realized_items: eina_list_last(realized_items);
9197 item = eina_list_data_get(l);
9198 ELM_GENLIST_ITEM_DATA_GET(item, it_data);
9199 next_previous_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it_data));
9200 evas_object_geometry_get(VIEW(next_previous_item), &hx, &hy, &hw, &hh);
9201 if (_is_item_in_viewport(obj_y, h, hy, hh) == 0)
9204 next_previous_item = NULL;
9206 l = traverse_direction ? eina_list_next(l): eina_list_prev(l);
9209 if (next_previous_item)
9211 elm_object_accessibility_highlight_set(EO_OBJ(next_previous_item), EINA_TRUE);
9212 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(next_previous_item), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
9216 // Tizen only (20150914)
9217 #include "elm_genlist.eo.c"
9218 #include "elm_genlist_item.eo.c"