genlist: re-focus on genlist in item focus set when sub-object was focused
[platform/upstream/elementary.git] / src / mobile_lib / elm_genlist.c
1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #include <fnmatch.h>
6
7 #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
8 //TIZEN_ONLY(20160329): genlist: enhance accessibility scroll & highlight (30d9a6012e629cd9ea60eae8d576f3ebb94ada86)
9 #define ELM_INTERFACE_ATSPI_COMPONENT_PROTECTED
10 //
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
15
16 #include <Elementary.h>
17 #include <Elementary_Cursor.h>
18
19 #include "elm_priv.h"
20 #include "elm_widget_genlist.h"
21 #include "elm_interface_scrollable.h"
22
23 #define MY_PAN_CLASS ELM_GENLIST_PAN_CLASS
24
25 #define MY_PAN_CLASS_NAME "Elm_Genlist_Pan"
26 #define MY_PAN_CLASS_NAME_LEGACY "elm_genlist_pan"
27
28 #define MY_CLASS ELM_GENLIST_CLASS
29
30 #define MY_CLASS_NAME "Elm_Genlist"
31 #define MY_CLASS_NAME_LEGACY "elm_genlist"
32
33 // internally allocated
34 #define CLASS_ALLOCATED     0x3a70f11f
35
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
49 #define FLICK_GAP 30
50
51 #define ERR_ABORT(_msg)                         \
52    do {                                         \
53         ERR(_msg);                              \
54         if (getenv("ELM_ERROR_ABORT")) abort(); \
55    } while (0)
56
57 #define GL_IT(_it) (_it->item)
58
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)))) \
62
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", "")
120
121 ELM_PRIV_GENLIST_SIGNALS(ELM_PRIV_STATIC_VARIABLE_DECLARE);
122
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, ""},
133        //
134        //TIZEN_ONLY(20170724): grab highlight using unrealized item
135        {SIG_WIDGET_ATSPI_HIGHLIGHTED, ""},
136        //
137        {NULL, NULL}
138 };
139
140 #undef ELM_PRIV_GENLIST_SIGNALS
141
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";
159 //TIZEN ONLY
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";
168
169 typedef enum
170 {
171    FOCUS_DIR_UP = 0,
172    FOCUS_DIR_DOWN,
173    FOCUS_DIR_LEFT,
174    FOCUS_DIR_RIGHT
175 } Focus_Dir;
176
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);
181
182 static void _item_edje_callbacks_add(Elm_Gen_Item *it);
183 static void _item_edje_callbacks_del(Elm_Gen_Item *it);
184
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);
193
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);
209
210 typedef struct _Size_Cache {
211      Evas_Coord minw;
212      Evas_Coord minh;
213 } Size_Cache;
214
215
216 // TIZEN ONLY : for banded ux
217 static void
218 _banded_item_bg_add(Elm_Gen_Item *it, Evas_Object *target)
219 {
220    char buf[256];
221    const char *bg_area;
222    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
223
224    if (sd->banded_bg_on)
225      {
226         bg_area = edje_object_data_get(VIEW(it), "banded_bg_area");
227
228         if (bg_area && !GL_IT(it)->banded_bg)
229           {
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);
232
233              snprintf(buf, sizeof(buf), "elm,state,%s,visible", bg_area);
234              edje_object_signal_emit(VIEW(it), buf, "elm");
235           }
236      }
237
238   if (!sd->banded_bg_rect)
239     {
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);
243        else
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);
250     }
251 }
252
253 static void
254 _banded_bg_state_check(Eo *obj, Elm_Genlist_Data *sd)
255 {
256    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
257
258    const char *banded_bg = edje_object_data_get(wd->resize_obj, "banded_bg");
259
260    if (banded_bg && !strcmp("on", banded_bg))
261      sd->banded_bg_on = EINA_TRUE;
262    else
263      sd->banded_bg_on = EINA_FALSE;
264 }
265
266 static void
267 _banded_item_bg_color_change(Elm_Gen_Item *it, Eina_Bool highlight)
268 {
269    if (GL_IT(it)->banded_bg)
270      {
271         int alpha = 255 * (1 - 0.04 * GL_IT(it)->banded_color_index);
272         int color = 250;
273
274         if (highlight)
275           alpha *= HIGHLIGHT_ALPHA_MAX;
276
277         color = (color * alpha) / 255;
278         evas_object_color_set(GL_IT(it)->banded_bg, color, color, color, alpha);
279      }
280 }
281
282 static void
283 _banded_item_bg_index_color_set(Elm_Gen_Item *it_top, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
284 {
285    if (!it_top) return;
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;
289    int sign = 1;
290    Eina_List *l;
291
292    if (!sd->banded_bg_on || !next->realized) return;
293
294    item_count = eina_list_count(l = elm_genlist_realized_items_get(WIDGET(it_top)));
295    eina_list_free(l);
296
297    while ((i < item_count) && (next))
298      {
299         if (!next->realized || next->want_hidden)
300           {
301              prev = next;
302              next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
303              continue;
304           }
305
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))
308           break;
309         else
310           {
311              if ((prev) &&
312                  ((GL_IT(prev)->type == ELM_GENLIST_ITEM_GROUP) ||
313                   (prev->itc->item_style && !strncmp("group", prev->itc->item_style, 5))))
314                j = j - sign;
315
316              if (GL_IT(next)->banded_bg)
317                {
318                   GL_IT(next)->banded_color_index = j;
319                   _banded_item_bg_color_change(next, next->highlighted);
320                }
321           }
322
323         prev = next;
324         next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
325
326         j = j + sign;
327         if ((j < 0) || (j > (BANDED_MAX_ITEMS - 1)))
328           {
329              sign = -sign;
330              j += (sign * 2);
331           }
332         i = i + 1;
333      }
334 }
335
336 static void
337 _item_content_free(Evas_Object *content)
338 {
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
345    // solved.
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);
349 }
350
351 static void
352 _item_cache_free(Elm_Genlist_Data *sd, Item_Cache *ic)
353 {
354    Evas_Object *c;
355    if (!ic) return;
356
357    if (ic->base_view) evas_object_del(ic->base_view);
358    ic->item_class = NULL;
359    EINA_LIST_FREE(ic->contents, c)
360      {
361         _item_content_free(c);
362      }
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
366    free(ic);
367 }
368
369 static void
370 _item_cache_all_free(Elm_Genlist_Data *sd)
371 {
372    // It would be better not to use
373    // EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
374    while (sd->item_cache)
375      {
376         Item_Cache *ic = EINA_INLIST_CONTAINER_GET(sd->item_cache->last, Item_Cache);
377         _item_cache_free(sd, ic);
378      }
379    sd->item_cache = NULL;
380    sd->item_cache_count = 0;
381 }
382
383 static void
384 _item_cache_push(Elm_Gen_Item *it, Eina_List *contents)
385 {
386    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
387    Item_Cache *ic = NULL;
388    Evas_Object *content;
389
390    if (sd->no_cache)
391      {
392         if (VIEW(it)) evas_object_del(VIEW(it));
393         VIEW(it) = NULL;
394         EINA_LIST_FREE(contents, content)
395           {
396              _item_content_free(content);
397           }
398         return;
399      }
400
401    if (sd->item_cache_count >= sd->item_cache_max)
402      {
403         ic = EINA_INLIST_CONTAINER_GET(sd->item_cache->last, Item_Cache);
404         _item_cache_free(sd, ic);
405      }
406
407    ic = ELM_NEW(Item_Cache);
408    if (!ic)
409      {
410         if (VIEW(it)) evas_object_del(VIEW(it));
411         VIEW(it) = NULL;
412         EINA_LIST_FREE(contents, content)
413           {
414              _item_content_free(content);
415           }
416         return;
417      }
418    // set item's state as default before pushing item into cache.
419    edje_object_signal_emit(VIEW(it), SIGNAL_DEFAULT, "elm");
420
421    edje_object_mirrored_set(VIEW(it),
422                             elm_widget_mirrored_get(WIDGET(it)));
423    edje_object_scale_set(VIEW(it),
424                          elm_widget_scale_get(WIDGET(it))
425                          * elm_config_scale_get());
426
427    ic->base_view = VIEW(it);
428    ic->multiline = GL_IT(it)->multiline;
429    ic->item_class = it->itc;
430    ic->contents = contents;
431    evas_object_hide(ic->base_view);
432    evas_object_move(ic->base_view, -9999, -9999);
433
434    sd->item_cache = eina_inlist_prepend(sd->item_cache, EINA_INLIST_GET(ic));
435    sd->item_cache_count++;
436
437    VIEW(it) = NULL;
438 }
439
440 static Eina_Bool
441 _item_cache_pop(Elm_Gen_Item *it)
442 {
443    Item_Cache *ic = NULL;
444    Eina_Inlist *l;
445    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
446
447    if (!it->itc) return EINA_FALSE;
448
449    EINA_INLIST_FOREACH_SAFE(sd->item_cache, l, ic)
450      {
451         if (it->itc && ic->item_class &&
452             (it->itc == ic->item_class))
453           {
454              sd->item_cache =
455                 eina_inlist_remove(sd->item_cache, EINA_INLIST_GET(ic));
456              sd->item_cache_count--;
457
458              VIEW(it) = ic->base_view;
459              GL_IT(it)->multiline = ic->multiline;
460
461              eina_list_free(ic->contents);
462              ic->contents = NULL;
463              free(ic);
464              return EINA_TRUE;
465           }
466      }
467    return EINA_FALSE;
468 }
469
470 // TIZEN_ONLY(20150828) : to prevent unnecessary genlist rendering
471 // _changed is called instead of evas_object_smart_changed API.
472 static void
473 _changed(Evas_Object *pan_obj)
474 {
475    Elm_Genlist_Pan_Data *psd = eo_data_scope_get(pan_obj, MY_PAN_CLASS);
476    Elm_Genlist_Data *sd = psd->wsd;
477
478    if (sd->viewport_w > 1) evas_object_smart_changed(pan_obj);
479 }
480 //
481
482 EOLIAN static void
483 _elm_genlist_pan_elm_pan_pos_set(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord x, Evas_Coord y)
484 {
485    if ((x == psd->wsd->pan_x) && (y == psd->wsd->pan_y)) return;
486
487    if (y > psd->wsd->pan_y) psd->wsd->dir = 1;
488    else psd->wsd->dir = -1;
489    psd->wsd->pan_x = x;
490    psd->wsd->pan_y = y;
491
492    _changed(obj);
493 }
494
495 EOLIAN static void
496 _elm_genlist_pan_elm_pan_pos_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y)
497 {
498    if (x) *x = psd->wsd->pan_x;
499    if (y) *y = psd->wsd->pan_y;
500 }
501
502 // TIZEN_ONLY(20150705): genlist item align feature
503 static Elm_Gen_Item *
504 _elm_genlist_pos_adjust_xy_item_get(const Evas_Object *obj,
505                                     Evas_Coord x,
506                                     Evas_Coord y)
507 {
508    Item_Block *itb;
509
510    ELM_GENLIST_CHECK(obj) NULL;
511    ELM_GENLIST_DATA_GET(obj, sd);
512
513    EINA_INLIST_FOREACH(sd->blocks, itb)
514      {
515         Eina_List *l = NULL;
516         Elm_Gen_Item *it;
517         if (!ELM_RECTS_INTERSECT(itb->x - sd->pan_x,
518                                  itb->y - sd->pan_y,
519                                  sd->minw, itb->minh, x, y, 1, 1))
520           continue;
521         EINA_LIST_FOREACH(itb->items, l, it)
522           {
523              Evas_Coord itx, ity, itw, ith;
524
525              itx = itb->x + it->x - sd->pan_x;
526              ity = itb->y + it->y - sd->pan_y;
527
528              itw = (GL_IT(it)->w ? GL_IT(it)->w : sd->minw);
529              ith = GL_IT(it)->minh;
530
531              if (ELM_RECTS_INTERSECT(itx, ity, itw, ith, x, y, 1, 1))
532                return it;
533           }
534      }
535
536    return NULL;
537 }
538
539 static Elm_Gen_Item *
540 _adjust_item_align(Elm_Gen_Item *it)
541 {
542    if (!it) return NULL;
543    int loop_count = 0;
544    int direction;
545    Elm_Gen_Item *adjust_item = it;
546    Elm_Object_Item *eo_item = NULL;
547    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
548
549    ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(adjust_item), wd, NULL);
550
551    if (!wd || !(wd->scroll_item_align_enable)) return it;
552    if (!sd || !sd->aligned_item || (it == sd->aligned_item)) return it;
553
554    direction = GL_IT(adjust_item)->scrl_y - GL_IT(sd->aligned_item)->scrl_y;
555    while (adjust_item && loop_count < 10)
556      {
557         const char *align = NULL;
558         if (!VIEW(adjust_item))
559           {
560              _item_realize(adjust_item, EINA_TRUE);
561              align = edje_object_data_get(VIEW(adjust_item), "align");
562              _item_unrealize(adjust_item, EINA_TRUE);
563           }
564         else
565           align = edje_object_data_get(VIEW(adjust_item), "align");
566
567         if (align && !strcmp(align, "off"))
568           {
569              if (direction < 0)
570                eo_item = elm_genlist_item_prev_get(EO_OBJ(adjust_item));
571              else
572                eo_item = elm_genlist_item_next_get(EO_OBJ(adjust_item));
573              adjust_item = eo_data_scope_get(eo_item, ELM_GENLIST_ITEM_CLASS);
574           }
575         else
576              break;
577         ++loop_count;
578      }
579
580    if (adjust_item) return adjust_item;
581
582    adjust_item = it;
583    while (adjust_item && loop_count < 10)
584      {
585         const char *align = NULL;
586         if (!VIEW(adjust_item))
587           {
588              _item_realize(adjust_item, EINA_TRUE);
589              align = edje_object_data_get(VIEW(adjust_item), "align");
590              _item_unrealize(adjust_item, EINA_TRUE);
591           }
592         else
593           align = edje_object_data_get(VIEW(adjust_item), "align");
594
595         if (align && !strcmp(align, "off"))
596           {
597              if (direction > 0)
598                eo_item = elm_genlist_item_prev_get(EO_OBJ(adjust_item));
599              else
600                eo_item = elm_genlist_item_next_get(EO_OBJ(adjust_item));
601              adjust_item = eo_data_scope_get(eo_item, ELM_GENLIST_ITEM_CLASS);
602           }
603         else
604              break;
605         ++loop_count;
606      }
607
608    if (!adjust_item)
609      adjust_item = it;
610
611    return adjust_item;
612 }
613
614 EOLIAN static void
615 _elm_genlist_pan_elm_pan_pos_adjust(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *x EINA_UNUSED, Evas_Coord *y)
616 {
617    ELM_WIDGET_DATA_GET_OR_RETURN(psd->wobj, wd);
618    Elm_Genlist_Data *sd = psd->wsd;
619
620    if (!(wd->scroll_item_align_enable)) return;
621
622    if (!y) return;
623
624    Elm_Object_Item *eo_it;
625    Evas_Coord vw, vh;
626    Evas_Coord cx = 0, cy = 0;
627    Evas_Coord it_y, it_h;
628    Evas_Coord yy = *y;
629
630    eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
631          (NULL, NULL, &vw, &vh));
632    if (!strcmp(wd->scroll_item_valign, "center"))
633      {
634         cx = (vw / 2);
635         cy = (vh / 2) - yy;
636      }
637
638    sd->adjusted_item = _elm_genlist_pos_adjust_xy_item_get(sd->obj, cx, cy);
639
640    if ((abs(*y) > FLICK_GAP) && (sd->adjusted_item == sd->aligned_item))
641      {
642         Elm_Gen_Item *adjusted_item = NULL;
643         if (*y < 0)
644           eo_it = elm_genlist_item_next_get(EO_OBJ(sd->adjusted_item));
645         else
646           eo_it = elm_genlist_item_prev_get(EO_OBJ(sd->adjusted_item));
647         adjusted_item = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
648         if (adjusted_item)
649           sd->adjusted_item = adjusted_item;
650      }
651    sd->adjusted_item = _adjust_item_align(sd->adjusted_item);
652    if (!sd->adjusted_item) return;
653
654    cy += psd->wsd->pan_y;
655    it_y = sd->adjusted_item->y + GL_IT(sd->adjusted_item)->block->y;
656    it_h = GL_IT(sd->adjusted_item)->h;
657
658    if (GL_IT(sd->adjusted_item)->h <= vh)
659      {
660         it_h = it_y + (it_h / 2);
661         *y += (cy - it_h);
662      }
663    else
664      {
665         int it_b_y = it_y + it_h;
666         int half_vh = vh/2;
667         if (it_y <= cy && it_y >= cy - half_vh)
668           {
669              *y -= half_vh - (cy - it_y);
670           }
671        else if (it_b_y >= cy && it_b_y <= cy  + half_vh)
672           {
673              *y += half_vh - (it_b_y - cy);
674           }
675      }
676
677    if (!*y && !sd->unhighlighted)
678      sd->adjusted_item = NULL;
679    else
680      evas_object_smart_changed(sd->pan_obj);
681 }
682 //
683
684 EOLIAN static void
685 _elm_genlist_pan_elm_pan_pos_max_get(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y)
686 {
687    Evas_Coord ow, oh;
688
689    evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
690    ow = psd->wsd->minw - ow;
691    if (ow < 0) ow = 0;
692    oh = psd->wsd->minh - oh;
693    if (oh < 0) oh = 0;
694    if (x) *x = ow;
695    if (y) *y = oh;
696 }
697
698 EOLIAN static void
699 _elm_genlist_pan_elm_pan_pos_min_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *_pd EINA_UNUSED, Evas_Coord *x,Evas_Coord *y)
700 {
701    if (x) *x = 0;
702    if (y) *y = 0;
703 }
704
705 EOLIAN static void
706 _elm_genlist_pan_elm_pan_content_size_get(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *w, Evas_Coord *h)
707 {
708    if (w) *w = psd->wsd->minw;
709    if (h) *h = psd->wsd->minh;
710 }
711
712 EOLIAN static void
713 _elm_genlist_pan_evas_object_smart_del(Eo *obj, Elm_Genlist_Pan_Data *psd)
714 {
715    ecore_job_del(psd->resize_job);
716
717    eo_do_super(obj, MY_PAN_CLASS, evas_obj_smart_del());
718 }
719
720 EOLIAN static void
721 _elm_genlist_pan_evas_object_smart_move(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord _gen_param2 EINA_UNUSED,
722 Evas_Coord _gen_param3 EINA_UNUSED)
723 {
724    psd->wsd->dir = 0;
725    _changed(obj);
726 }
727
728 EOLIAN static void
729 _elm_genlist_pan_evas_object_smart_resize(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord w, Evas_Coord h)
730 {
731    if ((w > 1 || h > 1))
732      {
733         if (psd->wsd->queue && !psd->wsd->queue_idle_enterer)
734           {
735              psd->wsd->queue_idle_enterer = ecore_idle_enterer_add(_queue_idle_enter, psd->wsd);
736           }
737      }
738    if (psd->wsd->mode == ELM_LIST_COMPRESS &&
739        psd->wsd->prev_viewport_w != w)
740      {
741         Item_Block *itb;
742         ELM_WIDGET_DATA_GET_OR_RETURN(psd->wsd->obj, wd);
743         EINA_INLIST_FOREACH(psd->wsd->blocks, itb)
744           {
745              Eina_List *l;
746              Elm_Gen_Item *it;
747              EINA_LIST_FOREACH(itb->items, l, it)
748                {
749                   if (!wd->scroll_item_align_enable && !GL_IT(it)->multiline) continue;
750                   if (GL_IT(it)->wsd->realization_mode)
751                     {
752                        GL_IT(it)->calc_done = EINA_FALSE;
753                        GL_IT(it)->block->calc_done = EINA_FALSE;
754                     }
755                   else
756                     {
757                        GL_IT(it)->resized = EINA_TRUE;
758                        if (it->realized)
759                          {
760                             GL_IT(it)->calc_done = EINA_FALSE;
761                             GL_IT(it)->block->calc_done = EINA_FALSE;
762                          }
763                        else _item_queue(it, NULL);
764                     }
765                }
766           }
767         psd->wsd->prev_viewport_w = w;
768      }
769    psd->wsd->viewport_w = w;
770    psd->wsd->viewport_h = h;
771
772    psd->wsd->calc_done = EINA_FALSE;
773    _changed(obj);
774 }
775
776 static void
777 _item_text_realize(Elm_Gen_Item *it,
778                    Evas_Object *target,
779                    const char *parts)
780 {
781    char buf[256];
782
783    if (it->itc->func.text_get)
784      {
785         Eina_List *source;
786         const char *key;
787
788         source = elm_widget_stringlist_get
789            (edje_object_data_get(target, "texts"));
790         EINA_LIST_FREE(source, key)
791           {
792              if (parts && fnmatch(parts, key, FNM_PERIOD))
793                continue;
794
795              char *s = it->itc->func.text_get
796                  ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
797
798              if (s)
799                {
800                   edje_object_part_text_escaped_set(target, key, s);
801                   free(s);
802
803                   snprintf(buf, sizeof(buf), "elm,state,%s,visible", key);
804                   edje_object_signal_emit(target, buf, "elm");
805                }
806              else
807                {
808                   edje_object_part_text_set(target, key, "");
809                   snprintf(buf, sizeof(buf), "elm,state,%s,hidden", key);
810                   edje_object_signal_emit(target, buf, "elm");
811                }
812           }
813         edje_object_message_signal_process(target);
814         if (_elm_atspi_enabled())
815           elm_interface_atspi_accessible_name_changed_signal_emit(EO_OBJ(it));
816      }
817 }
818
819 static void
820 _changed_size_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
821 {
822    Elm_Gen_Item *it = data;
823    GL_IT(it)->calc_done = EINA_FALSE;
824    GL_IT(it)->block->calc_done = EINA_FALSE;
825    GL_IT(it)->wsd->calc_done = EINA_FALSE;
826    _changed(GL_IT(it)->wsd->pan_obj);
827 }
828
829 // FIXME: There are applications which do not use elm_win as top widget.
830 // This is workaround! Those could not use focus!
831 /*
832 static Eina_Bool _focus_enabled(Evas_Object *obj)
833 {
834    if (!elm_widget_focus_get(obj)) return EINA_FALSE;
835
836    const Evas_Object *win = elm_widget_top_get(obj);
837    const char *type = evas_object_type_get(win);
838
839    if (type && !strcmp(type, "elm_win"))
840      {
841         return elm_win_focus_highlight_enabled_get(win);
842      }
843    return EINA_FALSE;
844 }
845 */
846
847 static void
848 _widget_calculate_recursive(Eo *obj)
849 {
850    Elm_Widget_Smart_Data *pd = NULL;
851    Eina_List *l;
852    Evas_Object *child;
853
854    if (!eo_isa(obj, ELM_WIDGET_CLASS)) return;
855
856    pd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
857    if (!pd) return;
858
859    if (!evas_object_smart_need_recalculate_get(obj) &&
860        !evas_object_smart_need_recalculate_get(pd->resize_obj))
861      return;
862
863    EINA_LIST_FOREACH(pd->subobjs, l, child)
864      _widget_calculate_recursive(child);
865
866    evas_object_smart_calculate(obj);
867 }
868
869 static void
870 _item_content_realize(Elm_Gen_Item *it,
871                       Evas_Object *target,
872                       Eina_List **contents,
873                       const char *src,
874                       const char *parts)
875 {
876    Eina_Bool tmp;
877    Evas_Object *content;
878    char buf[256];
879    Eina_List *source;
880    const char *key;
881
882    if (!parts)
883      {
884         EINA_LIST_FREE(*contents, content)
885            _item_content_free(content);
886      }
887    if ((!it->itc->func.content_get) &&
888       ((it->itc->version < 3) || (!it->itc->func.reusable_content_get))) return;
889
890    source = elm_widget_stringlist_get(edje_object_data_get(target, src));
891
892    EINA_LIST_FREE(source, key)
893      {
894         if (parts && fnmatch(parts, key, FNM_PERIOD))
895           continue;
896
897         Evas_Object *old = NULL;
898         old = edje_object_part_swallow_get(target, key);
899
900         // Reuse content by popping from the cache
901         content = NULL;
902         if (it->itc->version >= 3 && it->itc->func.reusable_content_get)
903           content = it->itc->func.reusable_content_get(
904              (void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key, old);
905         if (!content)
906           {
907              // Call the content get
908              if (it->itc->func.content_get)
909                content = it->itc->func.content_get
910                    ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
911              if (!content)
912                {
913                   snprintf(buf, sizeof(buf), "elm,state,%s,hidden", key);
914                   edje_object_signal_emit(target, buf, "elm");
915                   goto out;
916                }
917           }
918         if (content != old)
919           {
920              // FIXME: Genlist item doesn't update its size when the size of
921              // content is changed, so deferred calculation for content should
922              // be performed before realization.
923              if (eo_isa(content, ELM_WIDGET_CLASS))
924                {
925                   ELM_WIDGET_DATA_GET_OR_RETURN(content, wd);
926
927                   // FIXME : Layout need sizing eval before group calculate
928                   if (eo_class_get(content) == ELM_LAYOUT_CLASS)
929                     eo_do(content, elm_obj_layout_sizing_eval());
930
931                   _widget_calculate_recursive(content);
932                }
933
934              if (!edje_object_part_swallow(target, key, content))
935                {
936                   ERR("%s (%p) can not be swallowed into %s",
937                       evas_object_type_get(content), content, key);
938                   evas_object_del(content);
939                   goto out;
940                }
941              elm_widget_sub_object_add(WIDGET(it), content);
942           }
943         *contents = eina_list_append(*contents, content);
944
945         if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()))
946           elm_widget_disabled_set(content, EINA_TRUE);
947
948         if (GL_IT(it)->wsd->realization_mode)
949           {
950              evas_object_event_callback_add
951                 (content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
952                  _changed_size_hints, it);
953           }
954
955         snprintf(buf, sizeof(buf), "elm,state,%s,visible", key);
956         edje_object_signal_emit(target, buf, "elm");
957
958         // If content object is focused,
959         // genlist item should be focused.
960         if (elm_widget_focused_object_get(content))
961           {
962              if (GL_IT(it)->wsd->focused_item != it)
963                elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
964
965              GL_IT(it)->wsd->focused_content = content;
966           }
967 out:
968         if (old && content != old)
969           {
970              *contents = eina_list_remove(*contents, old);
971              _item_content_free(old);
972           }
973      }
974 }
975
976 static void
977 _item_state_realize(Elm_Gen_Item *it,
978                     Evas_Object *target,
979                     const char *parts)
980 {
981    if (it->itc->func.state_get)
982      {
983         Eina_List *src;
984         const char *key;
985         char buf[4096];
986
987         src = elm_widget_stringlist_get
988            (edje_object_data_get(target, "states"));
989         EINA_LIST_FREE(src, key)
990           {
991              if (parts && fnmatch(parts, key, FNM_PERIOD))
992                continue;
993
994              Eina_Bool on = it->itc->func.state_get
995                  ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
996
997              if (on)
998                {
999                   snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1000                   edje_object_signal_emit(target, buf, "elm");
1001                }
1002              else
1003                {
1004                   snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
1005                   edje_object_signal_emit(target, buf, "elm");
1006                }
1007           }
1008      }
1009 }
1010
1011 static void
1012 _view_theme_update(Elm_Gen_Item *it, Evas_Object *view, const char *style)
1013 {
1014    char buf[1024];
1015    const char *key;
1016    Eina_List *l;
1017
1018    snprintf(buf, sizeof(buf), "item/%s", style ? : "default");
1019
1020    Elm_Theme_Apply th_ret =
1021       elm_widget_theme_object_set(WIDGET(it), view, "genlist", buf,
1022                                   elm_widget_style_get(WIDGET(it)));
1023    if (th_ret == ELM_THEME_APPLY_FAILED)
1024      {
1025         ERR("%s is not a valid genlist item style. "
1026             "Automatically falls back into default style.",
1027             style);
1028         elm_widget_theme_object_set
1029           (WIDGET(it), view, "genlist", "item/default", "default");
1030      }
1031
1032    edje_object_mirrored_set(view, elm_widget_mirrored_get(WIDGET(it)));
1033    edje_object_scale_set(view, elm_widget_scale_get(WIDGET(it))
1034                          * elm_config_scale_get());
1035
1036    GL_IT(it)->multiline = EINA_FALSE;
1037    Eina_List *txts = elm_widget_stringlist_get
1038       (edje_object_data_get(view, "texts"));
1039    EINA_LIST_FOREACH(txts, l, key)
1040      {
1041         const Evas_Object *txt_obj = NULL;
1042         const char *type = NULL;
1043         txt_obj = edje_object_part_object_get(view, key);
1044         if (txt_obj) type =  evas_object_type_get(txt_obj);
1045         if (!type) continue;
1046         if (type && strcmp(type, "textblock")) continue;
1047
1048         const Evas_Textblock_Style *tb_style =
1049            evas_object_textblock_style_get(txt_obj);
1050         if (tb_style)
1051           {
1052              const char *str = evas_textblock_style_get(tb_style);
1053              if (str)
1054                {
1055                   if (strstr(str, "wrap="))
1056                     {
1057                        GL_IT(it)->multiline = EINA_TRUE;
1058                        break;
1059                     }
1060                }
1061           }
1062      }
1063    eina_list_free(txts);
1064 }
1065
1066 static Evas_Object *
1067 _view_create(Elm_Gen_Item *it, const char *style)
1068 {
1069    Evas_Object *view = edje_object_add(evas_object_evas_get(WIDGET(it)));
1070    evas_object_smart_member_add(view, GL_IT(it)->wsd->pan_obj);
1071    elm_widget_sub_object_add(WIDGET(it), view);
1072    edje_object_scale_set(view, elm_widget_scale_get(WIDGET(it)) *
1073                          elm_config_scale_get());
1074
1075    _view_theme_update(it, view, style);
1076    return view;
1077 }
1078
1079 static void
1080 _view_clear(Evas_Object *view, Eina_List **contents)
1081 {
1082    if (!view) return;
1083    const char *part;
1084    Evas_Object *c;
1085    Eina_List *texts  = elm_widget_stringlist_get
1086      (edje_object_data_get(view, "texts"));
1087    EINA_LIST_FREE(texts, part)
1088      edje_object_part_text_set(view, part, NULL);
1089
1090    if (contents)
1091      {
1092         EINA_LIST_FREE(*contents, c)
1093            _item_content_free(c);
1094      }
1095 }
1096
1097 static void
1098 _view_inflate(Evas_Object *view, Elm_Gen_Item *it, Eina_List **contents)
1099 {
1100    if (!view) return;
1101    _item_text_realize(it, view, NULL);
1102    if (contents) _item_content_realize(it, view, contents, "contents", NULL);
1103    _item_state_realize(it, view, NULL);
1104 }
1105
1106 static void
1107 _elm_genlist_item_index_update(Elm_Gen_Item *it)
1108 {
1109    if (it->position_update || GL_IT(it)->block->position_update)
1110      {
1111         evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, EO_OBJ(it));
1112         it->position_update = EINA_FALSE;
1113      }
1114 }
1115
1116 static char *
1117 _access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
1118 {
1119    char *ret;
1120    Eina_Strbuf *buf;
1121
1122    Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1123    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1124
1125    buf = eina_strbuf_new();
1126
1127    if (it->itc->func.text_get)
1128      {
1129         Eina_List *texts;
1130         const char *key;
1131
1132         texts =
1133            elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1134
1135         EINA_LIST_FREE(texts, key)
1136           {
1137              char *s = it->itc->func.text_get
1138                 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
1139
1140              s = _elm_util_mkup_to_text(s);
1141
1142              if (s)
1143                {
1144                   if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
1145                   eina_strbuf_append(buf, s);
1146                   free(s);
1147                }
1148           }
1149      }
1150
1151    ret = eina_strbuf_string_steal(buf);
1152    eina_strbuf_free(buf);
1153    return ret;
1154 }
1155
1156 static char *
1157 _access_state_cb(void *data, Evas_Object *obj EINA_UNUSED)
1158 {
1159    Elm_Gen_Item *it = (Elm_Gen_Item *)data;
1160    Eina_Bool ret;
1161    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
1162
1163    if (eo_do_ret(EO_OBJ(it), ret,  elm_wdg_item_disabled_get()))
1164      return strdup(E_("Disabled"));
1165
1166    return NULL;
1167 }
1168
1169 static void
1170 _access_activate_cb(void *data,
1171                     Evas_Object *part_obj EINA_UNUSED,
1172                     Elm_Object_Item *item EINA_UNUSED)
1173 {
1174    Elm_Gen_Item *it = data;
1175    Evas_Object *parent = WIDGET(it);
1176
1177    while (parent)
1178      {
1179         if (evas_object_freeze_events_get(parent)) return;
1180         parent = evas_object_smart_parent_get(parent);
1181      }
1182
1183    _item_select(it);
1184 }
1185
1186 static void
1187 _access_widget_item_register(Elm_Gen_Item *it)
1188 {
1189    Elm_Access_Info *ai;
1190    Eina_List *orders = NULL;
1191    Eina_List *l = NULL;
1192    Evas_Object *c, *child, *ret;
1193    Eina_List *listn, *ln;
1194    Eina_List *texts, *contents;
1195
1196    if (!_elm_config->access_mode) return;
1197
1198    /* access: unregister item which have no text and content */
1199    texts  = elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1200    contents  = elm_widget_stringlist_get(edje_object_data_get(VIEW(it),
1201                                                               "contents"));
1202    if (!texts && !contents) return;
1203    eina_list_free(texts);
1204    eina_list_free(contents);
1205
1206    _elm_access_widget_item_unregister(it->base);
1207    // FIXME: if item->view is not it->item->deco_all_view!!
1208    if (it->deco_all_view)
1209      {
1210         Evas_Object *acc = elm_access_object_register
1211            (it->deco_all_view, WIDGET(it));
1212         it->base->access_obj = acc;
1213      }
1214    else
1215      {
1216         _elm_access_widget_item_register(it->base);
1217      }
1218
1219    ai = _elm_access_info_get(eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_access_object_get()));
1220    _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1221    _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
1222    _elm_access_activate_callback_set(ai, _access_activate_cb, it);
1223
1224    elm_object_item_access_order_unset(EO_OBJ(it));
1225    if (it->flipped)
1226      {
1227         EINA_LIST_FOREACH(GL_IT(it)->flip_content_objs, l, c)
1228           {
1229              if (elm_widget_can_focus_get(c))
1230                {
1231                   orders = eina_list_append(orders, c);
1232                }
1233           }
1234      }
1235    else
1236      {
1237         if (it->deco_all_view)
1238           {
1239              EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, c)
1240                {
1241                   if (elm_widget_can_focus_get(c))
1242                     {
1243                        orders = eina_list_append(orders, c);
1244                     }
1245                }
1246           }
1247         EINA_LIST_FOREACH(it->content_objs, l, c)
1248           {
1249              if (elm_widget_can_focus_get(c))
1250                {
1251                   /*FIXME The below change is done to push datetime's access objects
1252                     like date field and time field in to genlist focus list to get focus.*/
1253                   listn = elm_widget_can_focus_child_list_get(c);
1254                   if (listn)
1255                     {
1256                        EINA_LIST_FOREACH(listn, ln, child)
1257                          {
1258                             orders = eina_list_append(orders, child);
1259                          }
1260                     }
1261                   else
1262                     {
1263                        orders = eina_list_append(orders, c);
1264                     }
1265                }
1266           }
1267      }
1268    if (orders)
1269       elm_object_item_access_order_set(EO_OBJ(it), orders);
1270 }
1271
1272 static void
1273 _item_unrealize(Elm_Gen_Item *it,
1274                 Eina_Bool calc)
1275 {
1276    Evas_Object *content;
1277    Eina_List *cache = NULL;
1278
1279    if (!it->realized) return;
1280
1281    if (GL_IT(it)->wsd->reorder.it == it)
1282      {
1283         WRN("reordering item should not be unrealized");
1284      }
1285
1286    if (!calc)
1287      {
1288         evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, EO_OBJ(it));
1289         _elm_access_widget_item_unregister(it->base);
1290         elm_object_item_access_order_unset(EO_OBJ(it));
1291         //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
1292         if (_elm_atspi_enabled())
1293           {
1294              elm_interface_atspi_accessible_removed(EO_OBJ(it));
1295              elm_interface_atspi_accessible_children_changed_del_signal_emit(GL_IT(it)->wsd->obj, EO_OBJ(it));
1296           }
1297         //
1298      }
1299
1300    Eina_List *l;
1301    Elm_Widget_Item_Signal_Data *wisd;
1302    EINA_LIST_FOREACH(it->base->signals, l, wisd)
1303      {
1304         eo_do(EO_OBJ(it), elm_wdg_item_signal_callback_del
1305               (wisd->emission, wisd->source, (Elm_Object_Item_Signal_Cb)wisd->func));
1306      }
1307
1308    _decorate_item_unrealize(it);
1309    _decorate_all_item_unrealize(it);
1310
1311    _item_edje_callbacks_del(it);
1312
1313    _item_mouse_callbacks_del(it, VIEW(it));
1314    if (!calc && it->item->proxy)
1315      {
1316         evas_object_image_source_visible_set(it->item->proxy, EINA_TRUE);
1317         evas_object_smart_member_del(it->item->proxy);
1318         evas_object_del(it->item->proxy);
1319         it->item->proxy = NULL;
1320      }
1321
1322    EINA_LIST_FREE(GL_IT(it)->flip_content_objs, content)
1323     evas_object_del(content);
1324    if (it->spacer) evas_object_del(it->spacer);
1325    _view_clear(VIEW(it), NULL);
1326
1327 // TIZEN ONLY : for banded ux
1328    if (!TIZEN_PROFILE_WEARABLE)
1329      {
1330         if (GL_IT(it)->banded_bg)
1331           ELM_SAFE_FREE(GL_IT(it)->banded_bg, evas_object_del);
1332         if (GL_IT(it)->wsd->banded_bg_on)
1333           {
1334              if (it->item->banded_anim) ecore_animator_del(it->item->banded_anim);
1335              it->item->banded_anim = NULL;
1336           }
1337      }
1338
1339    if (GL_IT(it)->highlight_timer)
1340      {
1341         ecore_timer_del(GL_IT(it)->highlight_timer);
1342         GL_IT(it)->highlight_timer = NULL;
1343      }
1344    if (it->long_timer)
1345      {
1346         ecore_timer_del(it->long_timer);
1347         it->long_timer = NULL;
1348      }
1349    /* trackt */
1350    eo_do(EO_OBJ(it), elm_wdg_item_track_cancel());
1351 //TIZEN_ONLY(20161013): clean up elm color class feature
1352    if (it->base->color_classes)
1353      edje_object_color_class_clear(VIEW(it));
1354 //
1355    EINA_LIST_FREE(it->content_objs, content)
1356      {
1357         if (it->itc->version >= 3 && it->itc->func.reusable_content_get)
1358           {
1359              // Unfocus content object for initialization.
1360              if (GL_IT(it)->wsd->focused_content == content)
1361                {
1362                   elm_object_focus_set(content, EINA_FALSE);
1363                   GL_IT(it)->wsd->focused_content = NULL;
1364                }
1365              if (elm_widget_disabled_get(content))
1366                elm_widget_disabled_set(content, EINA_FALSE);
1367
1368              cache = eina_list_append(cache, content);
1369           }
1370         else
1371           {
1372              if (GL_IT(it)->wsd->focused_content == content)
1373                GL_IT(it)->wsd->focused_content = NULL;
1374              elm_object_focus_set(content, EINA_FALSE);
1375              evas_object_del(content);
1376           }
1377      }
1378
1379      _item_cache_push(it, cache);
1380
1381    it->realized = EINA_FALSE;
1382 }
1383
1384 static void
1385 _item_block_unrealize(Item_Block *itb)
1386 {
1387    Elm_Gen_Item *it;
1388    const Eina_List *l, *ll;
1389    Evas_Object *content;
1390    Eina_Bool unrealize = EINA_TRUE;
1391
1392    // Do not check itb->realized
1393    // because it->item->block can be changed
1394
1395    EINA_LIST_FOREACH(itb->items, l, it)
1396      {
1397         if (!(((GL_IT(it)->wsd->reorder_force) || (GL_IT(it)->wsd->reorder_mode))
1398               && (GL_IT(it)->wsd->reorder.it == it))
1399                && !it->flipped && it->realized)
1400           {
1401              /* FIXME: when content is on focused and unrealize item,
1402                 focus is set to other object and scroll will be bring in */
1403              if (_elm_config->access_mode)
1404                {
1405                   EINA_LIST_FOREACH(it->content_objs, ll, content)
1406                     {
1407                        if (elm_object_focus_get(content))
1408                          {
1409                             unrealize = EINA_FALSE;
1410                             break;
1411                          }
1412                     }
1413                }
1414              if (unrealize)
1415                _item_unrealize(it, EINA_FALSE);
1416              unrealize = EINA_TRUE;
1417           }
1418      }
1419    itb->realized = EINA_FALSE;
1420 }
1421
1422 static void
1423 _calc(void *data)
1424 {
1425    Elm_Genlist_Data *sd = data;
1426    Item_Block *itb;
1427    Evas_Coord minw = 99999999, minh = 0, vw = 0, vh = 0, current_minh = 0;
1428    Evas_Coord processed_size = sd->minh;
1429    int cnt = 0;
1430
1431    if (sd->calc_done) return;
1432
1433 // TIZEN_ONLY(20150828) : Calculate item which position on viewport area
1434    while (sd->queue &&
1435           ((sd->viewport_h > processed_size) || (cnt < MAX_ITEMS_PER_BLOCK)))
1436      {
1437         Elm_Gen_Item *tmp;
1438         tmp = eina_list_data_get(sd->queue);
1439         sd->queue = eina_list_remove_list(sd->queue, sd->queue);
1440         if (!_item_process(sd, tmp)) continue;
1441         processed_size += GL_IT(tmp)->minh;
1442         tmp->item->queued = EINA_FALSE;
1443         cnt++;
1444      }
1445 //
1446    eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
1447          (NULL, NULL, &vw, &vh));
1448    EINA_INLIST_FOREACH(sd->blocks, itb)
1449      {
1450         itb->x = 0;
1451         itb->y = minh;
1452         _item_block_calc(itb, vw, vh);
1453         if (minw > itb->minw) minw = itb->minw;
1454         minh += itb->minh;
1455      }
1456
1457    if ((sd->mode == ELM_LIST_COMPRESS) && (minw > vw))
1458       minw = vw;
1459    else if (minw < vw) minw = vw;
1460
1461    if ((minw != sd->minw) || (minh != sd->minh))
1462      {
1463         Eina_Bool load_done = EINA_FALSE;
1464
1465         current_minh = sd->minh;
1466         sd->minw = minw;
1467         sd->minh = minh;
1468         if (!sd->queue && (minh != current_minh)) load_done = EINA_TRUE;
1469         elm_layout_sizing_eval(sd->obj);
1470         evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
1471         if (load_done)
1472           evas_object_smart_callback_call(sd->obj, SIG_LOADED, NULL);
1473         sd->processed_sizes = 0;
1474      }
1475    sd->dir = 0;
1476    sd->calc_done = EINA_TRUE;
1477 }
1478
1479 EOLIAN static void
1480 _elm_genlist_elm_layout_sizing_eval(Eo *obj, Elm_Genlist_Data *sd)
1481 {
1482    Evas_Coord minw = 0, minh = 0, maxw = -1, maxh = -1;
1483
1484    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1485
1486    if (sd->on_sub_del) return;;
1487
1488    evas_object_size_hint_min_get(obj, &minw, NULL);
1489    evas_object_size_hint_max_get(obj, &maxw, &maxh);
1490    edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
1491
1492    if (sd->scr_minw)
1493      {
1494         maxw = -1;
1495         minw = minw + sd->minw;
1496      }
1497    if (sd->scr_minh)
1498      {
1499         maxh = -1;
1500         minh = minh + sd->minh;
1501      }
1502
1503    if ((maxw > 0) && (minw > maxw))
1504      minw = maxw;
1505    if ((maxh > 0) && (minh > maxh))
1506      minh = maxh;
1507
1508    evas_object_size_hint_min_set(obj, minw, minh);
1509    evas_object_size_hint_max_set(obj, maxw, maxh);
1510 }
1511
1512 static void
1513 _elm_genlist_content_min_limit_cb(Evas_Object *obj,
1514                                Eina_Bool w,
1515                                Eina_Bool h)
1516 {
1517    ELM_GENLIST_DATA_GET(obj, sd);
1518
1519    if ((sd->mode == ELM_LIST_LIMIT) ||
1520        (sd->mode == ELM_LIST_EXPAND)) return;
1521    sd->scr_minw = !!w;
1522    sd->scr_minh = !!h;
1523
1524    elm_layout_sizing_eval(obj);
1525 }
1526
1527 static void
1528 _focus_bg_show(Elm_Gen_Item *it)
1529 {
1530    Evas_Coord w;
1531    Evas_Coord h = 0, rectangle_h = GL_IT(it)->h;
1532    ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wd);
1533    const Evas_Object *top, *bottom;
1534    Evas_Object *rectangle;
1535    const char *focus_bg;
1536
1537    if (!VIEW(it)) return;
1538    focus_bg = edje_object_data_get(VIEW(it), "focus_bg");
1539    if (focus_bg && !strcmp(focus_bg, "off")) return;
1540
1541    evas_object_geometry_get(wd->resize_obj, NULL, NULL, &w, NULL);
1542    top = edje_object_part_object_get(VIEW(it), "elm.padding.focus_bg.top");
1543    bottom = edje_object_part_object_get(VIEW(it), "elm.padding.focus_bg.bottom");
1544
1545    if (top && bottom)
1546      {
1547         evas_object_geometry_get(top, NULL, NULL, NULL, &h);
1548         rectangle_h -= h;
1549         evas_object_geometry_get(bottom, NULL, NULL, NULL, &h);
1550         rectangle_h -= h;
1551      }
1552
1553    rectangle = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
1554    evas_object_size_hint_min_set(rectangle, w, rectangle_h);
1555    evas_object_size_hint_max_set(rectangle, w, rectangle_h);
1556    evas_object_color_set(rectangle, 0, 0, 0, 0);
1557    elm_object_part_content_set(wd->obj, "focus_bg_size", rectangle);
1558
1559    edje_object_signal_emit(wd->resize_obj, SIGNAL_FOCUS_BG_SHOW, "elm");
1560 }
1561
1562 static void
1563 _item_position(Elm_Gen_Item *it,
1564                Evas_Object *view,
1565                Evas_Coord it_x,
1566                Evas_Coord it_y)
1567 {
1568    if (!it) return;
1569    if (!view) return;
1570
1571    Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0;
1572    Evas_Coord ix = 0, iy = 0, iw = 0, ih = 0;
1573    Elm_Gen_Item *target = it;
1574    Elm_Genlist_Data *sd = GL_IT(target)->wsd;
1575    ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(target), wsd);
1576
1577    ix = it_x;
1578    iy = it_y;
1579    iw = GL_IT(target)->w;
1580    ih = GL_IT(target)->h;
1581
1582    evas_object_resize(view, iw, ih);
1583    evas_object_move(view, ix, iy);
1584    evas_object_show(view);
1585
1586    if (wsd->scroll_item_align_enable)
1587      {
1588         int color = 0;
1589         int pre_multiplied_color = 0;
1590         int resize_width = 0;
1591         int resize_hight = 0;
1592         float ratio = 0.0;
1593         double scale = 0.0;
1594         double move_v[4] = {0.49, 0.99, 0.45, 1.0};
1595         double scale_v[4] = {0.49, 0.14, 1, 0.63};
1596
1597         evas_object_geometry_get(wsd->obj, &ox, &oy, &ow, &oh);
1598         int g_center = oy + oh / 2;
1599         int i_center = GL_IT(target)->scrl_y + GL_IT(target)->h / 2;
1600
1601         if (target->item->proxy && !ELM_RECTS_INTERSECT(ix, iy, iw, ih, ox, oy, ow, oh))
1602           evas_object_hide(target->item->proxy);
1603         else
1604           {
1605              const char *vi_effect = edje_object_data_get(VIEW(target), "vi_effect");
1606              if (vi_effect && !strcmp(vi_effect, "on"))
1607                {
1608                   ratio = (float)abs(g_center - i_center) / (float)((oh / 2) + ih / 2);
1609                   color = DIMED_ITEM_COLOR + ((255 - DIMED_ITEM_COLOR) * (1.0 - ratio));
1610                   double scale_p = ecore_animator_pos_map_n(ratio, ECORE_POS_MAP_CUBIC_BEZIER, 4, scale_v);
1611                   scale = elm_config_scale_get() - (scale_p * ALIGNED_ITEM_SCALE_FACTOR);
1612
1613                   resize_width = GL_IT(target)->w * (scale / elm_config_scale_get());
1614                   if (!((iw - resize_width) % 2))
1615                     iw = resize_width;
1616                   else
1617                     iw = resize_width + 1;
1618                   ix = GL_IT(target)->scrl_x + (GL_IT(target)->w - iw) / 2;
1619                   resize_hight = GL_IT(target)->h * (scale / elm_config_scale_get());
1620
1621                   if (!((ih - resize_hight) % 2))
1622                     ih = resize_hight;
1623                   else
1624                     ih = resize_hight + 1;
1625
1626                   if (i_center < g_center)
1627                     {
1628                        double move_p = ecore_animator_pos_map_n(ratio, ECORE_POS_MAP_CUBIC_BEZIER, 4, move_v);
1629                        iy = GL_IT(target)->scrl_y + move_p * (GL_IT(target)->h - ih);
1630                     }
1631                   else
1632                     iy = GL_IT(target)->scrl_y;
1633
1634                   const char *dim = edje_object_data_get(view, "dim");
1635                   if (!dim || (dim && !strcmp(dim, "on")))
1636                     {
1637                        pre_multiplied_color = 255 * color >> 8;
1638                        if (!elm_object_item_disabled_get(EO_OBJ(target)))
1639                          evas_object_color_set(target->item->proxy, pre_multiplied_color, pre_multiplied_color, pre_multiplied_color, color);
1640                        else
1641                          evas_object_color_set(target->item->proxy, 255, 255, 255, 255);
1642                     }
1643                }
1644              evas_object_move(target->item->proxy, ix, iy);
1645              evas_object_resize(target->item->proxy, iw, ih);
1646              evas_object_show(target->item->proxy);
1647
1648              if (!sd->on_hold &&
1649                  ELM_RECTS_INTERSECT(GL_IT(target)->scrl_x, GL_IT(target)->scrl_y,
1650                                      GL_IT(target)->w, GL_IT(target)->h,
1651                                      ox, g_center - CENTER_CHECK_GAP,
1652                                      ow, CENTER_CHECK_GAP * 2))
1653                {
1654                   if ((sd->adjusted_item == target) &&
1655                       ((sd->adjusted_item != sd->aligned_item) || (sd->unhighlighted)))
1656                     {
1657                        edje_object_signal_emit(VIEW(sd->adjusted_item), SIGNAL_ITEM_HIGHLIGHTED, "elm");
1658
1659                        if (sd->aligned_item && sd->adjusted_item != sd->aligned_item)
1660                          edje_object_signal_emit(VIEW(sd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
1661                        sd->aligned_item = sd->adjusted_item;
1662                        sd->unhighlighted = EINA_FALSE;
1663                     }
1664
1665                   if (sd->adjusted_item == target &&
1666                       sd->aligned_item == sd->adjusted_item &&
1667                       ((i_center >= g_center && i_center < g_center + 10) ||
1668                        (i_center <= g_center && i_center > g_center - 10)))
1669                     {
1670                        sd->adjusted_item = NULL;
1671                        _focus_bg_show(sd->aligned_item);
1672                     }
1673                }
1674           }
1675      }
1676 }
1677
1678 static void
1679 _item_all_position(Elm_Gen_Item *it,
1680                    Evas_Coord it_x,
1681                    Evas_Coord it_y)
1682 {
1683    if (!it) return;
1684
1685    if (it->deco_all_view)
1686      _item_position(it, it->deco_all_view, it_x, it_y);
1687    else if (GL_IT(it)->deco_it_view)
1688      _item_position(it, GL_IT(it)->deco_it_view, it_x, it_y);
1689    else
1690      _item_position(it, VIEW(it), it_x, it_y);
1691 }
1692
1693 static void
1694 _decorate_item_unrealize(Elm_Gen_Item *it)
1695 {
1696    if (!GL_IT(it)->deco_it_view) return;
1697
1698    edje_object_part_unswallow(GL_IT(it)->deco_it_view, VIEW(it));
1699    _view_clear(GL_IT(it)->deco_it_view, &(GL_IT(it)->deco_it_contents));
1700    evas_object_del(GL_IT(it)->deco_it_view);
1701    GL_IT(it)->deco_it_view = NULL;
1702
1703    _item_mouse_callbacks_add(it, VIEW(it));
1704    evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
1705 }
1706
1707 static void
1708 _decorate_all_item_realize(Elm_Gen_Item *it, Eina_Bool effect)
1709 {
1710    Eina_Bool ret;
1711    if (it->deco_all_view || !it->itc->decorate_all_item_style) return;
1712
1713    // Before adding & swallowing, delete it from smart member
1714    evas_object_smart_member_del(VIEW(it));
1715
1716    it->deco_all_view = _view_create(it, it->itc->decorate_all_item_style);
1717    _view_inflate(it->deco_all_view, it, &(GL_IT(it)->deco_all_contents));
1718    edje_object_part_swallow
1719       (it->deco_all_view, "elm.swallow.decorate.content", VIEW(it));
1720    evas_object_show(it->deco_all_view);
1721
1722    if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()))
1723      edje_object_signal_emit(it->deco_all_view, SIGNAL_DISABLED, "elm");
1724    if (it->selected)
1725      edje_object_signal_emit(it->deco_all_view, SIGNAL_HIGHLIGHTED, "elm");
1726    if (GL_IT(it)->wsd->reorder_force ||
1727        GL_IT(it)->wsd->reorder_mode)
1728      edje_object_signal_emit
1729        (it->deco_all_view, SIGNAL_REORDER_MODE_SET, "elm");
1730
1731    if (effect)
1732      {
1733         edje_object_signal_emit(VIEW(it),
1734                                 SIGNAL_DECORATE_ENABLED_EFFECT, "elm");
1735         edje_object_signal_emit(it->deco_all_view,
1736                                 SIGNAL_DECORATE_ENABLED_EFFECT, "elm");
1737      }
1738    else
1739      {
1740         edje_object_signal_emit(VIEW(it), SIGNAL_DECORATE_ENABLED, "elm");
1741         edje_object_signal_emit(it->deco_all_view,
1742                                 SIGNAL_DECORATE_ENABLED,"elm");
1743      }
1744    if (it->flipped)
1745      edje_object_signal_emit(it->deco_all_view, SIGNAL_FLIP_ENABLED, "elm");
1746
1747    _item_mouse_callbacks_add(it, it->deco_all_view);
1748    _item_mouse_callbacks_del(it, VIEW(it));
1749 }
1750
1751 static void
1752 _expand_toggle_signal_cb(void *data,
1753                          Evas_Object *obj EINA_UNUSED,
1754                          const char *emission EINA_UNUSED,
1755                          const char *source EINA_UNUSED)
1756 {
1757    Elm_Gen_Item *it = data;
1758
1759    if (GL_IT(it)->expanded)
1760      evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, EO_OBJ(it));
1761    else
1762      evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, EO_OBJ(it));
1763 }
1764
1765 static void
1766 _expand_signal_cb(void *data,
1767                   Evas_Object *obj EINA_UNUSED,
1768                   const char *emission EINA_UNUSED,
1769                   const char *source EINA_UNUSED)
1770 {
1771    Elm_Gen_Item *it = data;
1772
1773    if (!GL_IT(it)->expanded)
1774      evas_object_smart_callback_call(WIDGET(it), SIG_EXPAND_REQUEST, EO_OBJ(it));
1775 }
1776
1777 static void
1778 _contract_signal_cb(void *data,
1779                     Evas_Object *obj EINA_UNUSED,
1780                     const char *emission EINA_UNUSED,
1781                     const char *source EINA_UNUSED)
1782 {
1783    Elm_Gen_Item *it = data;
1784
1785    if (GL_IT(it)->expanded)
1786      evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACT_REQUEST, EO_OBJ(it));
1787 }
1788
1789 static void
1790 _item_mouse_callbacks_add(Elm_Gen_Item *it,
1791                           Evas_Object *view)
1792 {
1793    evas_object_event_callback_add
1794      (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
1795    evas_object_event_callback_add
1796      (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
1797    evas_object_event_callback_add
1798       (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
1799 }
1800
1801 static void
1802 _item_mouse_callbacks_del(Elm_Gen_Item *it,
1803                           Evas_Object *view)
1804 {
1805    evas_object_event_callback_del_full
1806      (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
1807    evas_object_event_callback_del_full
1808      (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
1809    evas_object_event_callback_del_full
1810       (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
1811
1812 }
1813
1814 static void
1815 _item_edje_callbacks_add(Elm_Gen_Item *it)
1816 {
1817    edje_object_signal_callback_add
1818       (VIEW(it), "elm,action,expand,toggle", "elm",
1819        _expand_toggle_signal_cb, it);
1820    edje_object_signal_callback_add
1821       (VIEW(it), "elm,action,expand", "elm", _expand_signal_cb, it);
1822    edje_object_signal_callback_add
1823       (VIEW(it), "elm,action,contract", "elm", _contract_signal_cb, it);
1824 }
1825
1826 static void
1827 _item_edje_callbacks_del(Elm_Gen_Item *it)
1828 {
1829    edje_object_signal_callback_del_full(VIEW(it), "elm,action,expand,toggle",
1830                                         "elm", _expand_toggle_signal_cb, it);
1831    edje_object_signal_callback_del_full(VIEW(it), "elm,action,expand", "elm",
1832                                         _expand_signal_cb, it);
1833    edje_object_signal_callback_del_full(VIEW(it), "elm,action,contract", "elm",
1834                                         _contract_signal_cb, it);
1835 }
1836
1837 static void
1838 _item_realize(Elm_Gen_Item *it,
1839               Eina_Bool calc)
1840 {
1841    const char *treesize;
1842    Eina_Bool ret;
1843
1844    if (it->realized) return;
1845    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
1846    ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd);
1847
1848    it->realized = EINA_TRUE;
1849
1850    if (!_item_cache_pop(it))
1851      VIEW(it) = _view_create(it, it->itc->item_style);
1852
1853 //TIZEN_ONLY(20161013): clean up elm color class feature
1854    if (it->base->color_classes)
1855      _elm_widget_item_color_class_update(it->base);
1856 //
1857
1858    treesize = edje_object_data_get(VIEW(it), "treesize");
1859    if (treesize)
1860      {
1861         int tsize = atoi(treesize);
1862         if ((tsize > 0) &&
1863             it->parent &&
1864             (GL_IT(it->parent)->type == ELM_GENLIST_ITEM_TREE))
1865           {
1866              it->spacer =
1867                 evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1868              evas_object_color_set(it->spacer, 0, 0, 0, 0);
1869              evas_object_size_hint_min_set
1870                 (it->spacer, (GL_IT(it)->expanded_depth * tsize) *
1871                  elm_config_scale_get(), 1);
1872              edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1873           }
1874      }
1875    _view_inflate(VIEW(it), it, &it->content_objs);
1876    if (wd->scroll_item_align_enable && !calc)
1877      {
1878         const char *vi_effect = edje_object_data_get(VIEW(it), "vi_effect");
1879         if (vi_effect && !strcmp(vi_effect, "on"))
1880           {
1881              Evas_Object *clip = evas_object_clip_get(VIEW(it));
1882              const Eina_List *clipees = evas_object_clipees_get(clip);
1883              // FIXME: This clipee rect is prevent white rect generation by all clip unset.
1884              if ((eina_list_count(clipees) <= 2) && !sd->clipee)
1885                {
1886                   sd->clipee = evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1887                   evas_object_color_set(sd->clipee, 0, 0, 0, 0);
1888                   evas_object_clip_set(sd->clipee, clip);
1889                }
1890              if (!it->item->proxy)
1891                {
1892                   it->item->proxy = evas_object_image_filled_add(evas_object_evas_get(wd->obj));
1893                   evas_object_smart_member_add(it->item->proxy, sd->pan_obj);
1894                }
1895              evas_object_clip_set(it->item->proxy, evas_object_clip_get(sd->pan_obj));
1896              evas_object_clip_unset(VIEW(it));
1897              evas_object_image_source_set(it->item->proxy, VIEW(it));
1898              evas_object_image_source_visible_set(it->item->proxy, EINA_FALSE);
1899              evas_object_image_source_events_set(it->item->proxy, EINA_TRUE);
1900              evas_object_image_source_clip_set(it->item->proxy, EINA_FALSE);
1901              evas_object_size_hint_min_set(it->item->proxy, GL_IT(it)->w, GL_IT(it)->h);
1902              evas_object_repeat_events_set(it->item->proxy, EINA_TRUE);
1903           }
1904      }
1905
1906    _item_mouse_callbacks_add(it, VIEW(it));
1907    // Expand can be supported by only VIEW(it)
1908    _item_edje_callbacks_add(it);
1909
1910    if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()))
1911      edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
1912    else
1913      edje_object_signal_emit(VIEW(it), SIGNAL_ENABLED, "elm");
1914    if (it->selected)
1915      {
1916         if (!TIZEN_PROFILE_WEARABLE)
1917           {
1918              if (sd->banded_bg_on)
1919                _banded_item_bg_color_change(it, EINA_TRUE);
1920           }
1921         edje_object_signal_emit(VIEW(it), SIGNAL_HIGHLIGHTED, "elm");
1922         evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
1923      }
1924    if (GL_IT(it)->expanded)
1925      edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
1926    if (sd->reorder_force || sd->reorder_mode)
1927      edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
1928    if (GL_IT(it)->expanded_depth > 0)
1929      edje_object_signal_emit(VIEW(it), SIGNAL_BG_CHANGE, "elm");
1930    if (it->flipped)
1931      {
1932         _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_contents,
1933                               "flips", NULL);
1934         edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
1935      }
1936
1937    if (elm_widget_focus_highlight_enabled_get(WIDGET(it)) && (it == sd->focused_item))
1938      {
1939         edje_object_signal_emit(VIEW(it), SIGNAL_FOCUSED, "elm");
1940      }
1941    if (sd->decorate_all_mode && it->itc->decorate_all_item_style)
1942      {
1943         _decorate_all_item_realize(it, EINA_FALSE);
1944      }
1945    else if (it->decorate_it_set && it->itc->decorate_item_style &&
1946             (sd->mode_item == it))
1947      {
1948         _decorate_item_realize(it);
1949      }
1950    it->realized = EINA_TRUE;
1951    if (!calc)
1952      {
1953         _elm_genlist_item_index_update(it);
1954
1955         if (it->tooltip.content_cb)
1956           {
1957              eo_do(EO_OBJ(it),
1958                    elm_wdg_item_tooltip_content_cb_set(
1959                       it->tooltip.content_cb, it->tooltip.data, NULL),
1960                    elm_wdg_item_tooltip_style_set(it->tooltip.style),
1961                    elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
1962           }
1963         if (it->mouse_cursor)
1964            eo_do(EO_OBJ(it), elm_wdg_item_cursor_set(it->mouse_cursor));
1965
1966         //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
1967         if (_elm_atspi_enabled())
1968           {
1969              elm_interface_atspi_accessible_added(EO_OBJ(it));
1970              elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
1971           }
1972         //
1973         if (!TIZEN_PROFILE_WEARABLE)
1974           _banded_item_bg_add(it, VIEW(it));
1975
1976         // Register accessibility before realized callback
1977         // because user can customize accessibility.
1978         _access_widget_item_register(it);
1979         evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, EO_OBJ(it));
1980      }
1981    edje_object_message_signal_process(VIEW(it));
1982    if (it->deco_all_view)
1983       edje_object_message_signal_process(it->deco_all_view);
1984    if (GL_IT(it)->resized)
1985      {
1986         sd->queue = eina_list_remove(sd->queue, it);
1987         GL_IT(it)->queued = EINA_FALSE;
1988         GL_IT(it)->resized = EINA_FALSE;
1989         GL_IT(it)->calc_done = EINA_FALSE;
1990         GL_IT(it)->block->calc_done = EINA_FALSE;
1991         sd->calc_done = EINA_FALSE;
1992      }
1993    if (sd->atspi_item_to_highlight == it)
1994      {
1995         sd->atspi_item_to_highlight = NULL;
1996         elm_object_accessibility_highlight_set(EO_OBJ(it), EINA_TRUE);
1997         //TIZEN_ONLY(20170724): grab highlight using unrealized item
1998         elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it),
1999                                      ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
2000         evas_object_smart_callback_call(WIDGET(it),
2001           SIG_WIDGET_ATSPI_HIGHLIGHTED, EO_OBJ(it));
2002         //
2003      }
2004 }
2005
2006 static Eina_Bool
2007 _reorder_anim(void *data)
2008 {
2009    Eina_List *l;
2010    Elm_Gen_Item *it;
2011    Elm_Genlist_Data *sd = data;
2012    Evas_Coord oy, r_y, r_y_scrl, r_y_scrl_max, r_offset;
2013    evas_object_geometry_get(sd->pan_obj, NULL, &oy, NULL, NULL);
2014
2015    r_y = sd->reorder.it->y + sd->reorder.it->item->block->y;
2016    r_y_scrl = sd->reorder.it->item->scrl_y;
2017    r_y_scrl_max = r_y_scrl + sd->reorder.it->item->h;
2018
2019
2020    // FIXME: 1. Reorder animation time should be equal regardless of item's height
2021    //        2. All item have same animation speed in reordering.
2022    // To support 1 and 2, offset value is scaled to reorder item's height.
2023    r_offset = (Evas_Coord) (GL_IT(sd->reorder.it)->h / REORDER_ANIM_OFFSET);
2024    if (r_offset < REORDER_ANIM_OFFSET) r_offset = REORDER_ANIM_OFFSET;
2025
2026
2027    EINA_LIST_FOREACH(sd->reorder.move_items, l, it)
2028      {
2029         Evas_Coord it_y, it_y_scrl_center;
2030         it_y = it->y + GL_IT(it)->block->y;
2031         it_y_scrl_center = GL_IT(it)->scrl_y + (GL_IT(it)->h / 2);
2032
2033         if ((sd->reorder.dir == -1) && (r_y_scrl <= it_y_scrl_center))
2034            GL_IT(it)->reorder_offset += r_offset;
2035         else if ((sd->reorder.dir == 1) && (r_y_scrl_max >= it_y_scrl_center))
2036            GL_IT(it)->reorder_offset -= r_offset;
2037
2038         if (r_y > it_y)
2039           {
2040              if (sd->reorder.it->item->h < GL_IT(it)->reorder_offset)
2041                GL_IT(it)->reorder_offset = sd->reorder.it->item->h;
2042              else if (0 > GL_IT(it)->reorder_offset)
2043                GL_IT(it)->reorder_offset = 0;
2044           }
2045         else if (r_y < it_y)
2046           {
2047              if (-(sd->reorder.it->item->h) > GL_IT(it)->reorder_offset)
2048                GL_IT(it)->reorder_offset = -(sd->reorder.it->item->h);
2049              else if (0 < GL_IT(it)->reorder_offset)
2050                GL_IT(it)->reorder_offset = 0;
2051           }
2052      }
2053    if (!sd->reorder.move_items)
2054      {
2055         sd->reorder.anim = NULL;
2056         return ECORE_CALLBACK_CANCEL;
2057      }
2058
2059    _changed(sd->pan_obj);
2060    return ECORE_CALLBACK_RENEW;
2061 }
2062
2063 static int
2064 _reorder_space_get(Elm_Gen_Item *it)
2065 {
2066    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2067    Evas_Coord oy, r_y, it_y, r_y_scrl, r_y_scrl_max, it_y_center;
2068    evas_object_geometry_get(sd->pan_obj, NULL, &oy, NULL, NULL);
2069
2070    if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) return 0;
2071    if (sd->reorder.it->parent != it->parent) return 0;
2072
2073    r_y = sd->reorder.it->y + sd->reorder.it->item->block->y;
2074    it_y = it->y + GL_IT(it)->block->y;
2075
2076    r_y_scrl = sd->reorder.it->item->scrl_y;
2077    r_y_scrl_max = r_y_scrl + sd->reorder.it->item->h;
2078    it_y_center = it_y + (GL_IT(it)->h / 2) - sd->pan_y + oy;
2079
2080    if ((r_y > it_y) && (r_y_scrl <= it_y_center))
2081      {
2082         if (!eina_list_data_find(sd->reorder.move_items, it))
2083            sd->reorder.move_items = eina_list_append(sd->reorder.move_items, it);
2084         if (!sd->reorder.anim)
2085            sd->reorder.anim = ecore_animator_add(_reorder_anim,
2086                                                  GL_IT(it)->wsd);
2087      }
2088    else if ((r_y < it_y) && (r_y_scrl_max >= it_y_center))
2089      {
2090         if (!eina_list_data_find(sd->reorder.move_items, it))
2091            sd->reorder.move_items = eina_list_append(sd->reorder.move_items, it);
2092         if (!sd->reorder.anim)
2093            sd->reorder.anim = ecore_animator_add(_reorder_anim,
2094                                                  GL_IT(it)->wsd);
2095      }
2096    return GL_IT(it)->reorder_offset;
2097 }
2098
2099 static void
2100 _reorder_calc(Elm_Gen_Item *it, Elm_Genlist_Data *sd)
2101 {
2102    Elm_Gen_Item *git = NULL;
2103    Elm_Gen_Item *ngit = NULL;
2104
2105    Evas_Coord ox, oy, ow, oh;
2106    evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
2107
2108    // Do not cross the parent group items and
2109    // Do not exceeds viewport
2110    git = it->parent;
2111    ngit = eina_list_data_get(eina_list_next
2112                              (eina_list_data_find_list
2113                               (sd->group_items, git)));
2114    if (git && git->realized && (GL_IT(it)->scrl_y <= (GL_IT(git)->scrl_y + GL_IT(git)->h)))
2115      {
2116         GL_IT(it)->scrl_y = GL_IT(git)->scrl_y + GL_IT(git)->h;
2117      }
2118    else if (ngit && ngit->realized && (GL_IT(it)->scrl_y >= (GL_IT(ngit)->scrl_y - GL_IT(it)->h)))
2119      {
2120         GL_IT(it)->scrl_y = GL_IT(ngit)->scrl_y - GL_IT(ngit)->h;
2121      }
2122
2123    if (GL_IT(it)->scrl_y < oy)
2124      {
2125         GL_IT(it)->scrl_y = oy;
2126         eo_do((sd)->obj, elm_interface_scrollable_content_region_show(sd->pan_x, sd->pan_y
2127                                                                       - REORDER_FASTER, ow, oh));
2128      }
2129    else if (GL_IT(it)->scrl_y + GL_IT(it)->h > oy + oh)
2130      {
2131         GL_IT(it)->scrl_y = oy + oh - GL_IT(it)->h;
2132         eo_do((sd)->obj, elm_interface_scrollable_content_region_show(sd->pan_x, sd->pan_y
2133                                                                       + REORDER_FASTER, ow, oh));
2134      }
2135
2136    if (TIZEN_PROFILE_WEARABLE)
2137      {
2138         _item_all_position(it, GL_IT(it)->scrl_x - REORDERED_ITEM_OFFSET,
2139                            GL_IT(it)->scrl_y - REORDERED_ITEM_OFFSET);
2140      }
2141    else
2142      {
2143         _item_all_position(it, GL_IT(it)->scrl_x, GL_IT(it)->scrl_y - REORDERED_ITEM_OFFSET);
2144      }
2145
2146    if (it->deco_all_view)
2147       evas_object_raise(it->deco_all_view);
2148    else if (GL_IT(it)->deco_it_view)
2149       evas_object_raise(GL_IT(it)->deco_it_view);
2150    else
2151       evas_object_raise(VIEW(it));
2152 }
2153
2154 #ifdef GENLIST_FX_SUPPORT
2155 static Eina_Bool
2156 _add_fx_anim(void *data)
2157 {
2158    Elm_Genlist_Data *sd = data;
2159    Elm_Gen_Item *it;
2160
2161    sd->add_fx.cnt--;
2162
2163    _changed(sd->pan_obj);
2164    if (sd->add_fx.cnt <= 0)
2165      {
2166         while (sd->add_fx.items)
2167           {
2168              it = eina_list_data_get(sd->add_fx.items);
2169              sd->add_fx.items = eina_list_remove(sd->add_fx.items, it);
2170              if (it->deco_all_view)
2171                 evas_object_color_set(it->deco_all_view, 255, 255, 255, 255);
2172              else if (it->item->deco_it_view)
2173                 evas_object_color_set(it->item->deco_it_view, 255, 255, 255, 255);
2174              else if (VIEW(it))
2175                 evas_object_color_set(VIEW(it), 255, 255, 255, 255);
2176           }
2177         sd->add_fx.cnt = ANIM_CNT_MAX;
2178         sd->add_fx.anim = NULL;
2179         return ECORE_CALLBACK_CANCEL;
2180      }
2181    return ECORE_CALLBACK_RENEW;
2182 }
2183
2184 static int
2185 _add_fx_space_get(Elm_Gen_Item *it)
2186 {
2187    Elm_Gen_Item *itt;
2188    Elm_Genlist_Data *sd = it->item->wsd;
2189    Evas_Coord size = 0;
2190
2191    if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2192    else if (it->item->deco_it_view) evas_object_raise(it->item->deco_it_view);
2193    else if (VIEW(it)) evas_object_raise(VIEW(it));
2194
2195    itt = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
2196    while (itt && itt->realized)
2197      {
2198         if (eina_list_data_find_list(sd->add_fx.items, itt))
2199           {
2200              size += itt->item->minh;
2201           }
2202         itt = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(itt)->prev);
2203      }
2204    size = size * ((double)sd->add_fx.cnt/ANIM_CNT_MAX);
2205    return size;
2206 }
2207
2208 static Eina_Bool
2209 _del_fx_anim(void *data)
2210 {
2211    Elm_Genlist_Data *sd = data;
2212    Elm_Gen_Item *it;
2213
2214    sd->del_fx.cnt--;
2215
2216    _changed(sd->pan_obj);
2217    if (sd->del_fx.cnt <= 0)
2218      {
2219         while (sd->del_fx.pending_items)
2220           {
2221              it = eina_list_data_get(sd->del_fx.pending_items);
2222              sd->del_fx.pending_items = eina_list_remove(sd->del_fx.pending_items, it);
2223              _item_free(it);
2224           }
2225         while (sd->del_fx.items)
2226           {
2227              it = eina_list_data_get(sd->del_fx.items);
2228              sd->del_fx.items = eina_list_remove(sd->del_fx.items, it);
2229              if (it->deco_all_view)
2230                 evas_object_color_set(it->deco_all_view, 255, 255, 255, 255);
2231              else if (it->item->deco_it_view)
2232                 evas_object_color_set(it->item->deco_it_view, 255, 255, 255, 255);
2233              else if (VIEW(it))
2234                 evas_object_color_set(VIEW(it), 255, 255, 255, 255);
2235              _item_free(it);
2236           }
2237         sd->del_fx.cnt = ANIM_CNT_MAX;
2238         sd->del_fx.anim = NULL;
2239         return ECORE_CALLBACK_CANCEL;
2240      }
2241    return ECORE_CALLBACK_RENEW;
2242 }
2243
2244 static int
2245 _del_fx_space_get(Elm_Gen_Item *it)
2246 {
2247    Elm_Gen_Item *itt;
2248    Elm_Genlist_Data *sd = it->item->wsd;
2249    Evas_Coord size = 0;
2250
2251    if (it->deco_all_view) evas_object_raise(it->deco_all_view);
2252    else if (it->item->deco_it_view) evas_object_raise(it->item->deco_it_view);
2253    else if (VIEW(it)) evas_object_raise(VIEW(it));
2254    itt = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
2255    while (itt && itt->realized)
2256      {
2257         if (eina_list_data_find_list(sd->del_fx.items, itt))
2258           {
2259              size += itt->item->minh;
2260           }
2261         itt = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(itt)->prev);
2262      }
2263    size = size * (1 - ((double)sd->del_fx.cnt/ANIM_CNT_MAX));
2264    return size;
2265 }
2266 #endif
2267
2268 static void
2269 _item_block_realize(Item_Block *itb, Eina_Bool force)
2270 {
2271    Elm_Genlist_Data *sd = itb->sd;
2272    Elm_Gen_Item *it;
2273    Elm_Gen_Item *aligned_item = NULL;
2274    Elm_Gen_Item *top_drawn_item = NULL;
2275    const Eina_List *l, *ll;
2276    Evas_Object *content;
2277    Eina_Bool unrealize = EINA_TRUE;
2278    Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0, cvx = 0, cvy = 0, cvw = 0, cvh = 0;
2279    ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wsd);
2280
2281    // Do not check itb->realized
2282    // because it->item->block can be changed
2283
2284    evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
2285    evas_output_viewport_get(evas_object_evas_get(sd->obj),
2286                             &cvx, &cvy, &cvw, &cvh);
2287
2288    if (_elm_config->access_mode || _elm_atspi_enabled())
2289      {
2290         // If access is on, realize more items (3 times)
2291         cvy = cvy - cvh;
2292         cvh = cvh * 3;
2293      }
2294 #ifdef GENLIST_FX_SUPPORT
2295    else if (sd->del_fx.anim)
2296      {
2297         int size = 0;
2298         EINA_LIST_FOREACH(sd->del_fx.items, l, it)
2299           {
2300              size += it->item->minh;
2301           }
2302         cvh += size;
2303      }
2304    else if (sd->add_fx.anim)
2305      {
2306         int size = 0;
2307         EINA_LIST_FOREACH(sd->add_fx.items, l, it)
2308           {
2309              size += it->item->minh;
2310           }
2311         cvh += size;
2312      }
2313 #endif
2314
2315    if (sd->reorder.it)  _reorder_calc(sd->reorder.it, sd);
2316    EINA_LIST_FOREACH(itb->items, l, it)
2317      {
2318         if (sd->reorder.it == it) continue;
2319         if (!it->filtered) _item_filtered_get(it);
2320         if (it->want_hidden)
2321           {
2322              if (it->realized) evas_object_hide(VIEW(it));
2323              continue;
2324           }
2325         GL_IT(it)->scrl_x = it->x + itb->x - sd->pan_x + ox;
2326         GL_IT(it)->scrl_y = it->y + itb->y - sd->pan_y + oy;
2327         GL_IT(it)->w = sd->minw;
2328         GL_IT(it)->h = GL_IT(it)->minh;
2329
2330         if (!TIZEN_PROFILE_WEARABLE)
2331           {
2332              //Kiran only
2333              if (!top_drawn_item)
2334                {
2335                   if (GL_IT(it)->scrl_y <= oy && ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
2336                                                                      GL_IT(it)->w, GL_IT(it)->h, ox, oy, ow, oh))
2337                     {
2338                        top_drawn_item = it;
2339                        sd->top_drawn_item = top_drawn_item;
2340                     }
2341                }
2342           }
2343
2344         if (wsd->scroll_item_align_enable)
2345           {
2346              if (!sd->aligned_item)
2347                {
2348                   if (ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
2349                                           GL_IT(it)->w, GL_IT(it)->h,
2350                                           ox + ow / 2, oy + oh / 2, 1, 1))
2351                     aligned_item = sd->aligned_item = it;
2352                }
2353           }
2354         if (force || sd->realization_mode ||
2355             it->flipped ||
2356            (ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
2357                                  GL_IT(it)->w, GL_IT(it)->h,
2358                                  cvx, cvy, cvw, cvh)))
2359           {
2360              if (!it->realized) _item_realize(it, EINA_FALSE);
2361              if (sd->reorder.it)
2362                 GL_IT(it)->scrl_y += _reorder_space_get(it);
2363 #ifdef GENLIST_FX_SUPPORT
2364              if (sd->del_fx.anim && !eina_list_data_find(sd->del_fx.items, it))
2365                 it->item->scrl_y -= _del_fx_space_get(it);
2366              if (sd->add_fx.anim && !eina_list_data_find(sd->add_fx.items, it))
2367                 it->item->scrl_y -= _add_fx_space_get(it);
2368 #endif
2369
2370              _item_all_position(it, GL_IT(it)->scrl_x, GL_IT(it)->scrl_y);
2371           }
2372         else if (it->realized)
2373           {
2374              /* FIXME: when content is on focused and unrealize item,
2375                 focus is set to other object and scroll will be bring in */
2376              if (_elm_config->access_mode)
2377                {
2378                   EINA_LIST_FOREACH(it->content_objs, ll, content)
2379                     {
2380                        if (elm_object_focus_get(content))
2381                          {
2382                             unrealize = EINA_FALSE;
2383                             break;
2384                          }
2385                     }
2386                }
2387              if (unrealize)
2388                _item_unrealize(it, EINA_FALSE);
2389              unrealize = EINA_TRUE;
2390           }
2391      }
2392
2393    itb->realized = EINA_TRUE;
2394
2395    if (!TIZEN_PROFILE_WEARABLE)
2396      {
2397         if (sd->banded_bg_on)
2398           _banded_item_bg_index_color_set(sd->top_drawn_item, ox, oy, ow, oh);
2399      }
2400
2401    if (aligned_item)
2402      {
2403         edje_object_signal_emit(VIEW(aligned_item), SIGNAL_ITEM_HIGHLIGHTED, "elm");
2404         _focus_bg_show(aligned_item);
2405
2406         edje_object_message_signal_process(VIEW(sd->aligned_item));
2407      }
2408 }
2409
2410 // FIXME: Remove below macro after opensource is patched
2411 #define EINA_INLIST_REVERSE_FOREACH_FROM(list, it)                                \
2412    for (it = NULL, it = (list ? _EINA_INLIST_CONTAINER(it, list) : NULL); \
2413         it; it = (EINA_INLIST_GET(it)->prev ? _EINA_INLIST_CONTAINER(it, EINA_INLIST_GET(it)->prev) : NULL))
2414
2415 EOLIAN static void
2416 _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
2417 {
2418    Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
2419    Item_Block *itb;
2420
2421    evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
2422    evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
2423
2424    //FIXME: This is for optimizing genlist calculation after
2425    //       genlist sizing eval properly.
2426    if (ow <= 1) return;
2427
2428    _calc((void *)psd->wsd);
2429
2430    if (_elm_config->access_mode || _elm_atspi_enabled())
2431      {
2432         // If access is on, realize more items (3 times)
2433         cvy = cvy - cvh;
2434         cvh = cvh * 3;
2435      }
2436 #ifdef GENLIST_FX_SUPPORT
2437    else if (psd->wsd->del_fx.anim)
2438      {
2439         Eina_List *l;
2440         Elm_Gen_Item *it;
2441         int size = 0;
2442         EINA_LIST_FOREACH(psd->wsd->del_fx.items, l, it)
2443           {
2444              size += it->item->minh;
2445           }
2446         cvh += size;
2447      }
2448    else if (psd->wsd->add_fx.anim)
2449      {
2450         Eina_List *l;
2451         Elm_Gen_Item *it;
2452         int size = 0;
2453         EINA_LIST_FOREACH(psd->wsd->add_fx.items, l, it)
2454           {
2455              size += it->item->minh;
2456           }
2457         cvh += size;
2458      }
2459 #endif
2460
2461    // Belows are tweaks for performance
2462    // Block is not needed anymore because of below algorithm..
2463    // later, we should remove dirty block algorithm
2464    Eina_Inlist *start = NULL;
2465    Eina_List *realized_new = NULL;
2466    Eina_Bool flag = EINA_FALSE;
2467    if ((psd->wsd->blocks_realized) && (psd->wsd->dir == -1) &&
2468        (!_elm_config->access_mode) && (!_elm_atspi_enabled()))
2469      {
2470         start = EINA_INLIST_GET((Item_Block *)eina_list_data_get
2471                                (eina_list_last(psd->wsd->blocks_realized)));
2472         EINA_INLIST_REVERSE_FOREACH_FROM(start, itb)
2473           {
2474              Evas_Coord itb_x, itb_y, itb_w, itb_h;
2475              itb_x = itb->x - psd->wsd->pan_x + ox;
2476              itb_y = itb->y - psd->wsd->pan_y + oy;
2477              itb_w = psd->wsd->minw;
2478              itb_h = itb->minh;
2479              if (psd->wsd->realization_mode ||
2480                  ELM_RECTS_INTERSECT(itb_x, itb_y, itb_w, itb_h,
2481                                      cvx, cvy, cvw, cvh))
2482                {
2483                   flag = EINA_TRUE;
2484                   realized_new = eina_list_prepend(realized_new, itb);
2485                   _item_block_realize(itb, EINA_FALSE);
2486                }
2487              else
2488                {
2489                   _item_block_unrealize(itb);
2490                   if (flag) break;
2491                }
2492           }
2493      }
2494    else if ((psd->wsd->blocks_realized) && (psd->wsd->dir == 1) &&
2495             (!_elm_config->access_mode) && (!_elm_atspi_enabled()))
2496      {
2497         start = EINA_INLIST_GET((Item_Block *)eina_list_data_get
2498                                 (psd->wsd->blocks_realized));
2499         EINA_INLIST_FOREACH(start, itb)
2500           {
2501              Evas_Coord itb_x, itb_y, itb_w, itb_h;
2502              itb_x = itb->x - psd->wsd->pan_x + ox;
2503              itb_y = itb->y - psd->wsd->pan_y + oy;
2504              itb_w = psd->wsd->minw;
2505              itb_h = itb->minh;
2506              if (psd->wsd->realization_mode ||
2507                  ELM_RECTS_INTERSECT(itb_x, itb_y, itb_w, itb_h,
2508                                      cvx, cvy, cvw, cvh))
2509                {
2510                   flag = EINA_TRUE;
2511                   realized_new = eina_list_append(realized_new, itb);
2512                   _item_block_realize(itb, EINA_FALSE);
2513                }
2514              else
2515                {
2516                   _item_block_unrealize(itb);
2517                   if (flag) break;
2518                }
2519           }
2520      }
2521    else
2522      {
2523         if (!psd->wsd->show_item)
2524           {
2525               EINA_INLIST_FOREACH(psd->wsd->blocks, itb)
2526                 {
2527                    Evas_Coord itb_x, itb_y, itb_w, itb_h;
2528                    itb_x = itb->x - psd->wsd->pan_x + ox;
2529                    itb_y = itb->y - psd->wsd->pan_y + oy;
2530                    itb_w = psd->wsd->minw;
2531                    itb_h = itb->minh;
2532                    if (psd->wsd->realization_mode ||
2533                        ELM_RECTS_INTERSECT(itb_x, itb_y, itb_w, itb_h,
2534                                           cvx, cvy, cvw, cvh))
2535                      {
2536                         realized_new = eina_list_append(realized_new, itb);
2537                         _item_block_realize(itb, EINA_FALSE);
2538                      }
2539                    else
2540                      {
2541                         _item_block_unrealize(itb);
2542                      }
2543                 }
2544           }
2545      }
2546    eina_list_free(psd->wsd->blocks_realized);
2547    psd->wsd->blocks_realized = realized_new;
2548
2549 // TIZEN_ONLY(20150701) : banded color background feature. enabled only un-scrollable
2550    if (!TIZEN_PROFILE_WEARABLE)
2551      {
2552        if (psd->wsd->banded_bg_rect && !psd->wsd->reorder.it)
2553          {
2554             Evas_Coord bg_x, bg_y, bg_w, bg_h, svy, svh;
2555             Elm_Gen_Item *tmp = NULL, *prev = NULL;
2556
2557             tmp = ELM_GEN_ITEM_FROM_INLIST(psd->wsd->items->last);
2558
2559             while(tmp)
2560               {
2561                  if (tmp->want_hidden || !tmp->realized )
2562                    tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
2563                  else
2564                    break;
2565               }
2566             if (tmp)
2567               prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
2568
2569             while(prev)
2570               {
2571                  if(prev->want_hidden)
2572                    prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2573                  else
2574                    break;
2575               }
2576
2577             if (tmp)
2578               {
2579                  int index = 0;
2580
2581                  eo_do(psd->wsd->obj, elm_interface_scrollable_content_viewport_geometry_get
2582                        (NULL, &svy, NULL, &svh));
2583
2584                  bg_x = GL_IT(tmp)->scrl_x;
2585                  bg_y = GL_IT(tmp)->scrl_y + GL_IT(tmp)->h;
2586                  bg_w = GL_IT(tmp)->w;
2587                  bg_h = svy + svh - bg_y;
2588
2589                  evas_object_stack_below(psd->wsd->banded_bg_rect, VIEW(tmp));
2590                  evas_object_resize(psd->wsd->banded_bg_rect, bg_w, bg_h);
2591                  evas_object_move(psd->wsd->banded_bg_rect, bg_x, bg_y);
2592
2593                  //GET COLOR OF LAST ITEM AND SET NEXT COLOR TO BANDED BG RECT
2594                  if (psd->wsd->banded_bg_on)
2595                    {
2596                       if (!prev)
2597                          index = GL_IT(tmp)->banded_color_index + 1;
2598                       else
2599                         {
2600                            int sign = GL_IT(tmp)->banded_color_index - GL_IT(prev)->banded_color_index;
2601
2602                            if (!sign)
2603                              {
2604                                 prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2605
2606                                 while(prev)
2607                                   {
2608                                      if(prev->want_hidden)
2609                                         prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2610                                      else
2611                                         break;
2612                                   }
2613
2614                                 if (!prev)
2615                                   sign = 1;
2616                                 else
2617                                   sign = GL_IT(tmp)->banded_color_index - GL_IT(prev)->banded_color_index;
2618                              }
2619
2620                            index = GL_IT(tmp)->banded_color_index + sign;
2621
2622                            if (index < 0) index += 2;
2623                            else if (index >= BANDED_MAX_ITEMS)
2624                              index = BANDED_MAX_ITEMS - 2;
2625                         }
2626
2627                       int alpha = 255 * (1 - 0.04 * index);
2628                       int color = (250 * alpha) / 255;
2629
2630                       evas_object_color_set(psd->wsd->banded_bg_rect, color, color, color, alpha);
2631                    }
2632                  else
2633                    {
2634                       evas_object_color_set
2635                          (psd->wsd->banded_bg_rect, 0, 0, 0, 0);
2636                    }
2637
2638                  evas_object_show(psd->wsd->banded_bg_rect);
2639               }
2640          }
2641      }
2642 // TIZEN_ONLY
2643
2644    if (psd->wsd->comp_y)
2645      {
2646         psd->wsd->unhighlight_skip = EINA_TRUE;
2647         eo_do((psd->wsd)->obj, elm_interface_scrollable_content_region_show(psd->wsd->pan_x,
2648                                                                             psd->wsd->pan_y + psd->wsd->comp_y, ow, oh));
2649         psd->wsd->comp_y = 0;
2650         psd->wsd->unhighlight_skip = EINA_FALSE;
2651      }
2652    else if (psd->wsd->expanded_item &&
2653             GL_IT(psd->wsd->expanded_item)->calc_done)
2654      {
2655         Eina_List *l;
2656         Evas_Coord size = GL_IT(psd->wsd->expanded_item)->minh;
2657         Elm_Object_Item *eo_tmp;
2658         EINA_LIST_FOREACH(psd->wsd->expanded_item->item->items, l, eo_tmp)
2659           {
2660              ELM_GENLIST_ITEM_DATA_GET(eo_tmp, tmp);
2661              size += GL_IT(tmp)->minh;
2662           }
2663         if (size >= oh)
2664            elm_genlist_item_bring_in
2665              (EO_OBJ(psd->wsd->expanded_item),
2666               ELM_GENLIST_ITEM_SCROLLTO_TOP);
2667         else
2668           {
2669              eo_tmp = eina_list_data_get
2670                 (eina_list_last(psd->wsd->expanded_item->item->items));
2671
2672              if (eo_tmp)
2673                elm_genlist_item_bring_in(eo_tmp,
2674                                          ELM_GENLIST_ITEM_SCROLLTO_IN);
2675           }
2676         psd->wsd->expanded_item = NULL;
2677      }
2678    if (psd->wsd->show_item &&
2679        !psd->wsd->show_item->item->queued &&
2680        psd->wsd->show_item->item->calc_done &&
2681        psd->wsd->show_item->item->block->calc_done &&
2682        psd->wsd->calc_done)
2683      {
2684         Evas_Coord x, y, w, h;
2685         Elm_Gen_Item *it = psd->wsd->show_item;
2686         psd->wsd->show_item = NULL;
2687         x = it->x + GL_IT(it)->block->x + psd->wsd->pan_x;
2688         y = it->y + GL_IT(it)->block->y;
2689         w = ow;
2690         h = oh;
2691
2692         switch (psd->wsd->scroll_to_type)
2693           {
2694            case ELM_GENLIST_ITEM_SCROLLTO_IN:
2695               h = GL_IT(it)->h;
2696               break;
2697
2698            case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE:
2699               y = y - (oh / 2) + (GL_IT(it)->h / 2);
2700               break;
2701 // tizen_feature
2702            case ELM_GENLIST_ITEM_SCROLLTO_BOTTOM:
2703               y = y - oh + GL_IT(it)->h;
2704               break;
2705 ///
2706            default:
2707               break;
2708           }
2709         if (psd->wsd->bring_in)
2710           eo_do(WIDGET(it), elm_interface_scrollable_region_bring_in(x, y, w, h));
2711         else
2712           {
2713              if (psd->wsd->aligned_item && (psd->wsd->aligned_item != psd->wsd->adjusted_item))
2714                edje_object_signal_emit(VIEW(psd->wsd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
2715              psd->wsd->aligned_item = NULL;
2716              psd->wsd->unhighlight_skip = EINA_TRUE;
2717              eo_do(WIDGET(it), elm_interface_scrollable_content_region_show(x, y, ow, oh));
2718              psd->wsd->unhighlight_skip = EINA_FALSE;
2719           }
2720
2721         _changed(psd->wsd->pan_obj);
2722      }
2723 #ifdef GENLIST_FX_SUPPORT
2724    if (psd->wsd->add_fx.anim)
2725      {
2726         Eina_List *l;
2727         Elm_Gen_Item *it;
2728
2729         int alpha = 255 * (1 - ((double)psd->wsd->add_fx.cnt/ANIM_CNT_MAX));
2730         EINA_LIST_FOREACH(psd->wsd->add_fx.items, l, it)
2731           {
2732              if (!it->realized) continue;
2733              if (it->deco_all_view)
2734                 evas_object_color_set(it->deco_all_view, alpha, alpha, alpha, alpha);
2735              else if (it->item->deco_it_view)
2736                 evas_object_color_set(it->item->deco_it_view, alpha, alpha, alpha, alpha);
2737              else if (VIEW(it))
2738                 evas_object_color_set(VIEW(it), alpha, alpha, alpha, alpha);
2739           }
2740      }
2741    if (psd->wsd->del_fx.anim)
2742      {
2743         Eina_List *l;
2744         Elm_Gen_Item *it;
2745
2746         int alpha = 255 * ((double)psd->wsd->del_fx.cnt/ANIM_CNT_MAX);
2747         EINA_LIST_FOREACH(psd->wsd->del_fx.items, l, it)
2748           {
2749              if (it->deco_all_view)
2750                 evas_object_color_set(it->deco_all_view, alpha, alpha, alpha, alpha);
2751              else if (it->item->deco_it_view)
2752                 evas_object_color_set(it->item->deco_it_view, alpha, alpha, alpha, alpha);
2753              else if (VIEW(it))
2754                 evas_object_color_set(VIEW(it), alpha, alpha, alpha, alpha);
2755           }
2756      }
2757 #endif
2758    eo_do(psd->wobj, eo_event_callback_call
2759          (ELM_INTERFACE_SCROLLABLE_EVENT_CHANGED, NULL));
2760 }
2761
2762 EOLIAN static void
2763 _elm_genlist_pan_eo_base_destructor(Eo *obj, Elm_Genlist_Pan_Data *psd)
2764 {
2765    eo_data_unref(psd->wobj, psd->wsd);
2766    eo_do_super(obj, MY_PAN_CLASS, eo_destructor());
2767 }
2768
2769 EOLIAN static void
2770 _elm_genlist_pan_class_constructor(Eo_Class *klass)
2771 {
2772    evas_smart_legacy_type_register(MY_PAN_CLASS_NAME_LEGACY, klass);
2773 }
2774
2775 #include "elm_genlist_pan.eo.c"
2776
2777 //#ifdef ELM_FOCUSED_UI
2778 static Eina_Bool
2779 _item_multi_select_up(Elm_Genlist_Data *sd)
2780 {
2781    Elm_Object_Item *prev;
2782
2783    if (!sd->selected) return EINA_FALSE;
2784    if (!sd->multi) return EINA_FALSE;
2785
2786    prev = elm_genlist_item_prev_get(sd->last_selected_item);
2787    if (!prev) return EINA_TRUE;
2788
2789    if (elm_genlist_item_selected_get(prev))
2790      {
2791         elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2792         sd->last_selected_item = prev;
2793         elm_genlist_item_show
2794           (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2795      }
2796    else
2797      {
2798         elm_genlist_item_selected_set(prev, EINA_TRUE);
2799         elm_genlist_item_show(prev, ELM_GENLIST_ITEM_SCROLLTO_IN);
2800      }
2801    return EINA_TRUE;
2802 }
2803
2804 static Eina_Bool
2805 _item_multi_select_down(Elm_Genlist_Data *sd)
2806 {
2807    Elm_Object_Item *next;
2808
2809    if (!sd->selected) return EINA_FALSE;
2810    if (!sd->multi) return EINA_FALSE;
2811
2812    next = elm_genlist_item_next_get(sd->last_selected_item);
2813    if (!next) return EINA_TRUE;
2814
2815    if (elm_genlist_item_selected_get(next))
2816      {
2817         elm_genlist_item_selected_set(sd->last_selected_item, EINA_FALSE);
2818         sd->last_selected_item = next;
2819         elm_genlist_item_show
2820           (sd->last_selected_item, ELM_GENLIST_ITEM_SCROLLTO_IN);
2821      }
2822    else
2823      {
2824         elm_genlist_item_selected_set(next, EINA_TRUE);
2825         elm_genlist_item_show(next, ELM_GENLIST_ITEM_SCROLLTO_IN);
2826      }
2827
2828    return EINA_TRUE;
2829 }
2830
2831 static Eina_Bool
2832 _all_items_deselect(Elm_Genlist_Data *sd)
2833 {
2834    if (!sd->selected) return EINA_FALSE;
2835
2836    while (sd->selected)
2837      elm_genlist_item_selected_set(sd->selected->data, EINA_FALSE);
2838
2839    return EINA_TRUE;
2840 }
2841
2842 static Eina_Bool
2843 _item_single_select_up(Elm_Genlist_Data *sd)
2844 {
2845    Elm_Object_Item *eo_prev;
2846    Elm_Gen_Item *prev;
2847
2848    if (!sd->selected)
2849      {
2850         prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2851         while (prev)
2852           prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
2853      }
2854    else
2855      {
2856         eo_prev = elm_genlist_item_prev_get(sd->last_selected_item);
2857         prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
2858      }
2859
2860    if (!prev) return EINA_FALSE;
2861
2862    _all_items_deselect(sd);
2863
2864    elm_genlist_item_selected_set(EO_OBJ(prev), EINA_TRUE);
2865    elm_genlist_item_show(EO_OBJ(prev), ELM_GENLIST_ITEM_SCROLLTO_IN);
2866    return EINA_TRUE;
2867 }
2868
2869 static Eina_Bool
2870 _item_single_select_down(Elm_Genlist_Data *sd)
2871 {
2872    Elm_Object_Item *eo_next;
2873    Elm_Gen_Item *next;
2874
2875    if (!sd->selected)
2876      {
2877         next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2878         while (next)
2879           next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
2880      }
2881    else
2882      {
2883         eo_next = elm_genlist_item_next_get(sd->last_selected_item);
2884         next = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
2885      }
2886
2887    if (!next) return EINA_FALSE;
2888
2889    _all_items_deselect(sd);
2890
2891    elm_genlist_item_selected_set(EO_OBJ(next), EINA_TRUE);
2892    elm_genlist_item_show
2893      (EO_OBJ(next), ELM_GENLIST_ITEM_SCROLLTO_IN);
2894
2895    return EINA_TRUE;
2896 }
2897 //#endif
2898
2899 static void _item_unfocused(Elm_Gen_Item *it)
2900 {
2901    if (!it) return;
2902    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2903    if (!sd->focused_item || it != sd->focused_item) return;
2904
2905    edje_object_signal_emit
2906       (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
2907    if (sd->focused_item->deco_all_view)
2908       edje_object_signal_emit
2909          (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
2910    sd->focused_item = NULL;
2911    evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_UNFOCUSED, EO_OBJ(it));
2912 }
2913
2914 static void _item_focused(Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
2915 {
2916    Evas_Coord x, y, w, h, sx, sy, sw, sh;
2917    if (!it) return;
2918    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2919
2920    evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
2921    evas_object_geometry_get(sd->obj, &sx, &sy, &sw, &sh);
2922    if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
2923      {
2924         elm_genlist_item_bring_in(EO_OBJ(it), type);
2925      }
2926
2927    if (elm_widget_focus_highlight_enabled_get(sd->obj))
2928      {
2929         if (it->deco_all_view)
2930           edje_object_signal_emit
2931             (it->deco_all_view, SIGNAL_FOCUSED, "elm");
2932         else
2933           edje_object_signal_emit
2934             (VIEW(it), SIGNAL_FOCUSED, "elm");
2935      }
2936
2937    sd->focused_item = it;
2938    evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_FOCUSED, EO_OBJ(it));
2939    if (_elm_atspi_enabled())
2940      elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), EO_OBJ(it));
2941 }
2942
2943 static Eina_Bool
2944 _banded_item_highlight_anim(void *data, double pos)
2945 {
2946    Elm_Gen_Item *it = data;
2947    double frame = pos;
2948    double v[4] = {0.25, 0.46, 0.45, 1.00};
2949
2950    if (GL_IT(it)->banded_bg)
2951      {
2952         if (pos < 1.0)
2953           frame = ecore_animator_pos_map_n(pos, ECORE_POS_MAP_CUBIC_BEZIER, 4, v);
2954         else if (pos == 1)
2955           it->item->banded_anim = NULL;
2956
2957         if (it->highlighted)
2958           frame = HIGHLIGHT_ALPHA_MAX + (1.0 - HIGHLIGHT_ALPHA_MAX) * (1.0 - frame);
2959         else
2960           frame = HIGHLIGHT_ALPHA_MAX + (1.0 - HIGHLIGHT_ALPHA_MAX) * frame;
2961
2962         int alpha = 255 * frame * (1 - 0.04 * GL_IT(it)->banded_color_index);
2963         int color = 250;
2964
2965         color = (color * alpha) / 255;
2966         evas_object_color_set(GL_IT(it)->banded_bg, color, color, color, alpha);
2967      }
2968
2969    return EINA_TRUE;
2970 }
2971
2972 static void
2973 _item_highlight(Elm_Gen_Item *it)
2974 {
2975    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
2976    ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wsd);
2977    Eina_Bool ret;
2978
2979    if (!sd->highlight) return;
2980    if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get())) return;
2981    if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2982        (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ) ||
2983        (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
2984        (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
2985      return;
2986    if (it->highlighted) return;
2987    if (wsd->scroll_item_align_enable)
2988      {
2989         if (sd->aligned_item == it)
2990           edje_object_signal_emit(wsd->resize_obj, SIGNAL_HIGHLIGHTED, "elm");
2991         else
2992           return;
2993      }
2994
2995    it->highlighted = EINA_TRUE;
2996    sd->highlighted_item = it;
2997
2998    if (!it->realized) goto end;
2999
3000    if (!TIZEN_PROFILE_WEARABLE)
3001      {
3002         if (sd->banded_bg_on)
3003           {
3004              if (it->item->banded_anim) ecore_animator_del(it->item->banded_anim);
3005              it->item->banded_anim = ecore_animator_timeline_add(ELM_ITEM_HIGHLIGHT_TIMER, _banded_item_highlight_anim, it);
3006           }
3007      }
3008    if (it->deco_all_view)
3009      {
3010         edje_object_signal_emit(it->deco_all_view, SIGNAL_HIGHLIGHTED, "elm");
3011         edje_object_message_signal_process(it->deco_all_view);
3012      }
3013    edje_object_signal_emit(VIEW(it), SIGNAL_HIGHLIGHTED, "elm");
3014    edje_object_message_signal_process(VIEW(it));
3015
3016 //***************** TIZEN Only
3017 // If check or radio is used on genlist item, highlight it also.
3018    Eina_List *l;
3019    Evas_Object *content;
3020    if (sd->decorate_all_mode)
3021      {
3022         EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, content)
3023           {
3024              const char *type = elm_widget_type_get(content);
3025              if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3026                 elm_object_signal_emit(content, "elm,state,mouse,down", "elm");
3027           }
3028      }
3029    else
3030      {
3031         EINA_LIST_FOREACH(it->content_objs, l, content)
3032           {
3033              const char *type = elm_widget_type_get(content);
3034              if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3035                 elm_object_signal_emit(content, "elm,state,mouse,down", "elm");
3036           }
3037      }
3038 //****************************
3039 end:
3040    evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
3041    if (_elm_atspi_enabled())
3042      elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), EO_OBJ(it));
3043 }
3044
3045 static void
3046 _item_unhighlight(Elm_Gen_Item *it, Eina_Bool effect EINA_UNUSED)
3047 {
3048    ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wsd);
3049    if (!it->highlighted) return;
3050
3051    it->highlighted = EINA_FALSE;
3052    GL_IT(it)->wsd->highlighted_item = NULL;
3053
3054    if (!it->realized) goto end;
3055
3056    if (!TIZEN_PROFILE_WEARABLE)
3057      {
3058         if (GL_IT(it)->wsd->banded_bg_on && effect)
3059           {
3060              if (it->item->banded_anim) ecore_animator_del(it->item->banded_anim);
3061              it->item->banded_anim = ecore_animator_timeline_add(ELM_ITEM_HIGHLIGHT_TIMER, _banded_item_highlight_anim, it);
3062           }
3063         else
3064           {
3065              if (it->item->banded_anim) ELM_SAFE_FREE(it->item->banded_anim, ecore_animator_del);
3066              _banded_item_bg_color_change(it, EINA_FALSE);
3067           }
3068      }
3069    if (it->deco_all_view)
3070      edje_object_signal_emit(it->deco_all_view, SIGNAL_UNHIGHLIGHTED, "elm");
3071    edje_object_signal_emit(VIEW(it), SIGNAL_UNHIGHLIGHTED, "elm");
3072    if (wsd->scroll_item_align_enable)
3073      edje_object_signal_emit(wsd->resize_obj, SIGNAL_UNHIGHLIGHTED, "elm");
3074    else
3075      edje_object_signal_emit(VIEW(it), SIGNAL_UNHIGHLIGHTED, "elm");
3076 //******************** TIZEN Only
3077 // If check is used on genlist item, unhighlight it also.
3078    Eina_List *l;
3079    Evas_Object *content;
3080    if (GL_IT(it)->wsd->decorate_all_mode)
3081      {
3082         EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, content)
3083           {
3084              const char *type = elm_widget_type_get(content);
3085              if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3086                 elm_object_signal_emit(content, "elm,state,mouse,up", "elm");
3087           }
3088      }
3089    else
3090      {
3091         EINA_LIST_FOREACH(it->content_objs, l, content)
3092           {
3093              const char *type = elm_widget_type_get(content);
3094              if (type && (!strcmp(type, "elm_check") || (!strcmp(type, "elm_radio"))))
3095                 elm_object_signal_emit(content, "elm,state,mouse,up", "elm");
3096           }
3097      }
3098    //*******************************
3099 end:
3100    evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, EO_OBJ(it));
3101 }
3102
3103 static void
3104 _item_unselect(Elm_Gen_Item *it)
3105 {
3106    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
3107
3108    if (!it->selected) return;
3109
3110    it->selected = EINA_FALSE;
3111    sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
3112    _item_unhighlight(it, EINA_TRUE);
3113    evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, EO_OBJ(it));
3114 }
3115
3116 static void
3117 _item_select(Elm_Gen_Item *it)
3118 {
3119    Evas_Object *obj = WIDGET(it);
3120    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
3121    Eina_Bool ret;
3122    if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get())) return;
3123    if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3124        (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
3125        (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3126        (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
3127      return;
3128    if (sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS &&
3129        it->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS &&
3130        it->selected)
3131       return;
3132    if (!sd->multi)
3133      {
3134         const Eina_List *l, *ll;
3135         Elm_Object_Item *eo_it2;
3136         EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it2)
3137           if (eo_it2 != EO_OBJ(it))
3138             {
3139                ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
3140                _item_unselect(it2);
3141             }
3142      }
3143
3144    if (!it->selected)
3145      {
3146         sd->selected = eina_list_append(sd->selected, EO_OBJ(it));
3147         it->selected = EINA_TRUE;
3148      }
3149    sd->last_selected_item = EO_OBJ(it);
3150    _item_highlight(it);
3151
3152    if (sd->focused_content)
3153      {
3154         elm_object_focus_set(sd->focused_content, EINA_FALSE);
3155         evas_object_focus_set(obj, EINA_TRUE);
3156         sd->focused_content = NULL;
3157      }
3158
3159    sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3160    elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3161
3162    if (it->realized)
3163      {
3164         // FIXME: after evas_object_raise, mouse event callbacks(ex, UP, DOWN)
3165         // can be called again eventhough already received it.
3166         const char *selectraise = edje_object_data_get(VIEW(it), "selectraise");
3167         if ((selectraise) && (!strcmp(selectraise, "on")))
3168           {
3169              if (it->deco_all_view) evas_object_raise(it->deco_all_view);
3170              else evas_object_raise(VIEW(it));
3171              if ((GL_IT(it)->group_item) && (GL_IT(it)->group_item->realized))
3172                evas_object_raise(GL_IT(it)->VIEW(group_item));
3173           }
3174
3175         edje_object_signal_emit
3176            (VIEW(it), SIGNAL_CLICKED, "elm");
3177         edje_object_message_signal_process(VIEW(it));
3178      }
3179    evas_object_ref(obj);
3180    if (it->func.func) it->func.func((void *)it->func.data, obj, EO_OBJ(it));
3181    if (EINA_MAGIC_CHECK(it->base, ELM_WIDGET_ITEM_MAGIC))
3182       evas_object_smart_callback_call(obj, SIG_SELECTED, EO_OBJ(it));
3183    evas_object_unref(obj);
3184 }
3185
3186 static Eina_Bool
3187 _highlight_timer(void *data)
3188 {
3189    Elm_Gen_Item *it = data;
3190    GL_IT(it)->highlight_timer = NULL;
3191    _item_highlight(it);
3192    return EINA_FALSE;
3193 }
3194
3195 static Eina_Bool
3196 _select_timer(void *data)
3197 {
3198    Elm_Gen_Item *it = data;
3199    GL_IT(it)->highlight_timer = NULL;
3200
3201    if ((GL_IT(it)->wsd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS) ||
3202        (it->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS))
3203       _item_select(it);
3204    else
3205      {
3206         // TIZEN Only(20150708) : unselect when selected item is selected again
3207         // There need to be implemented 'SELECT_UNSELECT' mode in elm_config
3208         // select mode for support upsteam and TIZEN both.
3209         if (!it->selected) _item_select(it);
3210         else _item_unselect(it);
3211         //
3212      }
3213
3214    return EINA_FALSE;
3215 }
3216
3217 static Evas_Object
3218 *_item_focusable_content_search(Evas_Object *obj, Eina_List *l, int dir)
3219 {
3220    if ((dir != 1) && (dir != -1)) return NULL;
3221
3222    Evas_Object *next = NULL;
3223    Elm_Object_Item *next_item = NULL;
3224
3225    while (l)
3226      {
3227         next = eina_list_data_get(l);
3228         if (next && (elm_widget_can_focus_get(next) &&
3229                    (evas_object_visible_get(next))))
3230           break;
3231         else if (next && (elm_widget_child_can_focus_get(next)))
3232           {
3233              if (elm_widget_focused_object_get(next))
3234                break;
3235              else
3236                {
3237                   Evas_Object *child = next;
3238                   if ((dir == 1) &&
3239                       (elm_widget_focus_next_get(next, ELM_FOCUS_RIGHT, &child, &next_item)))
3240                     break;
3241                   else if ((dir == -1) &&
3242                            (elm_widget_focus_next_get(next, ELM_FOCUS_LEFT, &child, &next_item)))
3243                     break;
3244                }
3245           }
3246
3247         next = NULL;
3248         if (dir == 1) l = eina_list_next(l);
3249         else l = eina_list_prev(l);
3250      }
3251
3252      if (!next) next = obj;
3253
3254    return next;
3255 }
3256
3257 static Eina_Bool _item_focusable_search(Elm_Gen_Item **it, int dir)
3258 {
3259    if (!(*it)) return EINA_FALSE;
3260    if ((dir != 1) && (dir != -1)) return EINA_FALSE;
3261
3262    Elm_Gen_Item *tmp = *it;
3263
3264    while (tmp)
3265      {
3266         if (!elm_object_item_disabled_get(EO_OBJ(tmp)) &&
3267            (!tmp->want_hidden))
3268           {
3269              if ((tmp->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
3270                  (tmp->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3271                  (tmp->flipped))
3272                {
3273                   Evas_Object *obj = NULL;
3274                   Eina_List *contents = NULL;
3275                   if (tmp->flipped)
3276                     contents = GL_IT(tmp)->flip_content_objs;
3277                   else
3278                     {
3279                        contents = tmp->content_objs;
3280                        if (tmp->deco_all_view)
3281                          {
3282                             if (contents)
3283                               contents = GL_IT(tmp)->deco_all_contents;
3284                             else
3285                               contents = eina_list_merge(contents,
3286                                             GL_IT(tmp)->deco_all_contents);
3287                          }
3288                     }
3289
3290                   if (dir == 1)
3291                     obj = _item_focusable_content_search(NULL, contents, 1);
3292                   else
3293                     {
3294                        contents = eina_list_last(contents);
3295                        obj = _item_focusable_content_search(NULL, contents, -1);
3296                     }
3297
3298                   if (obj)
3299                     {
3300                        if (GL_IT(tmp)->wsd->focused_content)
3301                          elm_object_focus_set(GL_IT(tmp)->wsd->focused_content, EINA_FALSE);
3302                        GL_IT(tmp)->wsd->focused_content = obj;
3303                        elm_object_focus_set(obj, EINA_TRUE);
3304                        *it = tmp;
3305                        return EINA_TRUE;
3306                     }
3307                }
3308              if (GL_IT(tmp)->wsd->focused_content)
3309                {
3310                   elm_object_focus_set(GL_IT(tmp)->wsd->focused_content, EINA_FALSE);
3311                   evas_object_focus_set(WIDGET(tmp), EINA_TRUE);
3312                   GL_IT(tmp)->wsd->focused_content = NULL;
3313                }
3314              *it = tmp;
3315              return EINA_TRUE;
3316           }
3317         if (dir == 1)
3318           tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->next);
3319         else
3320           tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
3321      }
3322
3323    *it = NULL;
3324    return EINA_FALSE;
3325 }
3326
3327 static Eina_Bool _item_focus_next(Elm_Genlist_Data *sd, Focus_Dir dir)
3328 {
3329    Elm_Gen_Item *it = NULL;
3330    Elm_Gen_Item *old_focused = sd->focused_item;
3331    Evas_Object *old_content = sd->focused_content;
3332
3333    if (dir == FOCUS_DIR_DOWN || dir == FOCUS_DIR_UP)
3334      {
3335         Eina_Bool find_item;
3336
3337         if (dir == FOCUS_DIR_DOWN)
3338           {
3339              if (sd->focused_item)
3340                {
3341                   it = ELM_GEN_ITEM_FROM_INLIST
3342                      (EINA_INLIST_GET(sd->focused_item)->next);
3343                   elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3344                }
3345              else it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
3346              find_item = _item_focusable_search(&it, 1);
3347           }
3348         else if (dir == FOCUS_DIR_UP)
3349           {
3350              if (sd->focused_item)
3351                {
3352                   it = ELM_GEN_ITEM_FROM_INLIST
3353                      (EINA_INLIST_GET(sd->focused_item)->prev);
3354                   elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3355                }
3356              else it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
3357              find_item = _item_focusable_search(&it, -1);
3358           }
3359
3360         if (!it)
3361           {
3362              if (old_focused)
3363                {
3364                   if (old_content)
3365                     {
3366                        sd->focused_content = old_content;
3367                        elm_object_focus_set(old_content, EINA_TRUE);
3368                     }
3369                   else
3370                     {
3371                        sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3372                        elm_object_item_focus_set(EO_OBJ(old_focused), EINA_TRUE);
3373                     }
3374                }
3375              return EINA_FALSE;
3376           }
3377         else if (!find_item)
3378           return EINA_TRUE;
3379
3380         sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3381         elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3382      }
3383    else if (dir == FOCUS_DIR_LEFT || dir == FOCUS_DIR_RIGHT)
3384      {
3385         Evas_Object *obj = NULL;
3386         Eina_List *contents = NULL;
3387         Eina_List *l = NULL;
3388
3389         if (!sd->focused_item) return EINA_FALSE;
3390         if (sd->focused_item->flipped)
3391           contents = GL_IT(sd->focused_item)->flip_content_objs;
3392         else
3393           {
3394              contents = sd->focused_item->content_objs;
3395              if (sd->focused_item->deco_all_view)
3396                {
3397                   if (contents)
3398                     contents = GL_IT(sd->focused_item)->deco_all_contents;
3399                   else
3400                     contents = eina_list_merge(contents,
3401                                   GL_IT(sd->focused_item)->deco_all_contents);
3402                }
3403           }
3404
3405         if (sd->focused_content)
3406           {
3407              l = eina_list_data_find_list(contents,
3408                                           sd->focused_content);
3409              obj = sd->focused_content;
3410           }
3411
3412         if (dir == FOCUS_DIR_LEFT)
3413           {
3414              if ((l) && (eina_list_prev(l)))
3415                {
3416                   l = eina_list_prev(l);
3417                   obj = _item_focusable_content_search(obj, l, -1);
3418                   if (!obj) obj = sd->focused_content;
3419                }
3420              else if (!l)
3421                {
3422                   //search focused content is child of content
3423                   if (sd->focused_content)
3424                     l = eina_list_data_find_list(contents,
3425                                                  sd->focused_content);
3426                   if (!l) l = eina_list_last(contents);
3427                   obj = _item_focusable_content_search(obj, l, -1);
3428                }
3429              else obj = sd->focused_content;
3430           }
3431         else if (dir == FOCUS_DIR_RIGHT)
3432           {
3433              if ((l) && (eina_list_next(l)))
3434                {
3435                   l = eina_list_next(l);
3436                   obj = _item_focusable_content_search(obj, l, 1);
3437                   if (!obj) obj = sd->focused_content;
3438                }
3439              else if (!l)
3440                {
3441                   //search focused content is child of content
3442                   if (sd->focused_content)
3443                     l = eina_list_data_find_list(contents,
3444                                                  sd->focused_content);
3445                   if (!l) l = contents;
3446                   obj = _item_focusable_content_search(obj, l, 1);
3447                }
3448              else obj = sd->focused_content;
3449           }
3450
3451         if (obj)
3452           {
3453              sd->focused_content = obj;
3454              elm_object_focus_set(obj, EINA_TRUE);
3455           }
3456         else
3457           {
3458              sd->focused_content = NULL;
3459              return EINA_FALSE;
3460           }
3461      }
3462    else return EINA_FALSE;
3463
3464    return EINA_TRUE;
3465 }
3466
3467 //#ifdef ELM_FOCUSED_UI
3468 EOLIAN static Eina_Bool
3469 _elm_genlist_elm_widget_event(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *src EINA_UNUSED, Evas_Callback_Type type, void *event_info)
3470 {
3471    Evas_Coord x = 0;
3472    Evas_Coord y = 0;
3473    Evas_Coord v_w = 0;
3474    Evas_Coord v_h = 0;
3475    Evas_Coord step_x = 0;
3476    Evas_Coord step_y = 0;
3477    Evas_Coord page_x = 0;
3478    Evas_Coord page_y = 0;
3479    Evas_Event_Key_Down *ev = event_info;
3480    Evas_Coord pan_max_x = 0, pan_max_y = 0;
3481
3482    //ELM_GENLIST_DATA_GET(obj, sd);
3483
3484    // TIZEN ONLY(20131221) : When access mode, focused ui is disabled.
3485    if (_elm_config->access_mode) return EINA_FALSE;
3486
3487    if ((type != EVAS_CALLBACK_KEY_DOWN) && (type != EVAS_CALLBACK_KEY_UP))
3488      return EINA_FALSE;
3489    if (!sd->items) return EINA_FALSE;
3490    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
3491    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
3492
3493    eo_do(obj,
3494          elm_interface_scrollable_content_pos_get(&x, &y),
3495          elm_interface_scrollable_step_size_get(&step_x, &step_y),
3496          elm_interface_scrollable_page_size_get(&page_x, &page_y),
3497          elm_interface_scrollable_content_viewport_geometry_get
3498          (NULL, NULL, &v_w, &v_h));
3499
3500    if ((!strcmp(ev->keyname, "Left")) ||
3501        ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)) ||
3502        (!strcmp(ev->keyname, "Right")) ||
3503        ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)) ||
3504        (!strcmp(ev->keyname, "Up")) ||
3505        ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)) ||
3506        (!strcmp(ev->keyname, "Down")) ||
3507        ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)) ||
3508        (!strcmp(ev->keyname, "Home")) ||
3509        ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)) ||
3510        (!strcmp(ev->keyname, "End")) ||
3511        ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)) ||
3512        (!strcmp(ev->keyname, "Prior")) ||
3513        ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)) ||
3514        (!strcmp(ev->keyname, "Next")) ||
3515        ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
3516      {
3517         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3518         _elm_widget_focus_auto_show(obj);
3519      }
3520
3521    if ((!strcmp(ev->keyname, "Left")) ||
3522        ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
3523      {
3524         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3525         if (sd->select_on_focus_enabled) x -= step_x;
3526         else
3527           {
3528              if (_item_focus_next(sd, FOCUS_DIR_LEFT))
3529                {
3530                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3531                   return EINA_TRUE;
3532                }
3533              else
3534                return EINA_FALSE;
3535           }
3536      }
3537    else if ((!strcmp(ev->keyname, "Right")) ||
3538             ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
3539      {
3540         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3541         if (sd->select_on_focus_enabled) x += step_x;
3542         else
3543           {
3544              if (_item_focus_next(sd, FOCUS_DIR_RIGHT))
3545                {
3546                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3547                   return EINA_TRUE;
3548                }
3549              else
3550                return EINA_FALSE;
3551           }
3552      }
3553    else if ((!strcmp(ev->keyname, "Up")) ||
3554             ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
3555      {
3556         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3557         if (sd->select_on_focus_enabled)
3558           {
3559              if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
3560                   (_item_multi_select_up(sd))) || (_item_single_select_up(sd)))
3561                {
3562                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3563                   return EINA_TRUE;
3564                }
3565           }
3566         else
3567           {
3568              if (_item_focus_next(sd, FOCUS_DIR_UP))
3569                {
3570                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3571                   return EINA_TRUE;
3572                }
3573              else
3574                return EINA_FALSE;
3575           }
3576      }
3577    else if ((!strcmp(ev->keyname, "Down")) ||
3578             ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
3579      {
3580         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3581         if (sd->select_on_focus_enabled)
3582           {
3583              if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
3584                   (_item_multi_select_down(sd))) ||
3585                  (_item_single_select_down(sd)))
3586                {
3587                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3588                   return EINA_TRUE;
3589                }
3590           }
3591         else
3592           {
3593              if (_item_focus_next(sd, FOCUS_DIR_DOWN))
3594                {
3595                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3596                   return EINA_TRUE;
3597                }
3598              else
3599                return EINA_FALSE;
3600           }
3601      }
3602    else if ((!strcmp(ev->keyname, "Home")) ||
3603             ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
3604      {
3605         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3606         if (sd->select_on_focus_enabled)
3607           {
3608              Elm_Object_Item *it = elm_genlist_first_item_get(obj);
3609              elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
3610              elm_genlist_item_selected_set(it, EINA_TRUE);
3611              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3612           }
3613         else
3614           {
3615              elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3616              _item_focus_next(sd, FOCUS_DIR_DOWN);
3617              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3618           }
3619         return EINA_TRUE;
3620      }
3621    else if ((!strcmp(ev->keyname, "End")) ||
3622             ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
3623      {
3624         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3625         if (sd->select_on_focus_enabled)
3626           {
3627              Elm_Object_Item *it = elm_genlist_last_item_get(obj);
3628              elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
3629              elm_genlist_item_selected_set(it, EINA_TRUE);
3630           }
3631         else
3632           {
3633              elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
3634              sd->focused_item = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
3635              _item_focus_next(sd, FOCUS_DIR_UP);
3636           }
3637         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3638         return EINA_TRUE;
3639      }
3640    else if ((!strcmp(ev->keyname, "Prior")) ||
3641             ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
3642      {
3643         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3644         Elm_Gen_Item *it = sd->focused_item;
3645         Elm_Object_Item *eo_prev;
3646
3647         while (page_y <= v_h)
3648           {
3649              if (elm_genlist_item_prev_get(EO_OBJ(it)))
3650                {
3651                   eo_prev = elm_genlist_item_prev_get(EO_OBJ(it));
3652                   it = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
3653                }
3654              else break;
3655              page_y += GL_IT(it)->minh;
3656           }
3657         if (_item_focusable_search(&it, -1))
3658           {
3659              sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3660              elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3661           }
3662         else if (!it)
3663           {
3664              _item_focusable_search(&it, 1);
3665              sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3666              elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3667           }
3668
3669         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3670         return EINA_TRUE;
3671      }
3672    else if ((!strcmp(ev->keyname, "Next")) ||
3673             ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
3674      {
3675         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3676         Elm_Gen_Item *it = sd->focused_item;
3677         Elm_Object_Item *eo_next;
3678
3679         page_y = GL_IT(it)->minh;
3680
3681         while (page_y <= v_h)
3682           {
3683              if (elm_genlist_item_next_get(EO_OBJ(it)))
3684                {
3685                   eo_next = elm_genlist_item_next_get(EO_OBJ(it));
3686                   it = eo_data_scope_get(eo_next, ELM_GENLIST_ITEM_CLASS);
3687                }
3688              else break;
3689              page_y += GL_IT(it)->minh;
3690           }
3691         if (_item_focusable_search(&it, 1))
3692           {
3693              sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3694              elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3695           }
3696         else if(!it)
3697           {
3698              _item_focusable_search(&it, -1);
3699              sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3700              elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3701           }
3702
3703         sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP;
3704         elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3705
3706         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3707         return EINA_TRUE;
3708      }
3709    else if (!strcmp(ev->keyname, "Escape"))
3710      {
3711         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
3712         if (!_all_items_deselect(sd)) return EINA_FALSE;
3713         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3714         return EINA_TRUE;
3715      }
3716    else if (!strcmp(ev->keyname, "Return") ||
3717             !strcmp(ev->keyname, "KP_Enter") ||
3718             !strcmp(ev->keyname, "space"))
3719      {
3720
3721         if (type == EVAS_CALLBACK_KEY_DOWN && !sd->key_down_item)
3722           {
3723              if (sd->focused_item)
3724                {
3725                   sd->key_down_item = sd->focused_item;
3726
3727                   edje_object_signal_emit
3728                      (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
3729                   if (sd->focused_item->deco_all_view)
3730                     edje_object_signal_emit
3731                        (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
3732
3733                   _item_highlight(sd->key_down_item);
3734                   if (sd->key_down_item->long_timer)
3735                     ecore_timer_del(sd->key_down_item->long_timer);
3736                   sd->key_down_item->long_timer = ecore_timer_add
3737                                              (sd->longpress_timeout,
3738                                              _long_press_cb, sd->key_down_item);
3739                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3740                   evas_object_smart_callback_call(obj, SIG_ACTIVATED, EO_OBJ(sd->key_down_item));
3741                   return EINA_TRUE;
3742                }
3743              else return EINA_FALSE;
3744           }
3745         else if (type == EVAS_CALLBACK_KEY_UP && sd->key_down_item)
3746           {
3747              edje_object_signal_emit
3748                 (VIEW(sd->key_down_item), SIGNAL_FOCUSED, "elm");
3749              if (sd->key_down_item->deco_all_view)
3750                  edje_object_signal_emit
3751                     (sd->key_down_item->deco_all_view, SIGNAL_FOCUSED, "elm");
3752
3753              if (sd->key_down_item->long_timer)
3754                ecore_timer_del(sd->key_down_item->long_timer);
3755              sd->key_down_item->long_timer = NULL;
3756              if (GL_IT(sd->key_down_item)->highlight_timer)
3757                ecore_timer_del(GL_IT(sd->key_down_item)->highlight_timer);
3758              GL_IT(sd->key_down_item)->highlight_timer = ecore_timer_add
3759                   (ITEM_SELECT_TIMER, _select_timer, sd->key_down_item);
3760              sd->key_down_item = NULL;
3761              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3762              return EINA_TRUE;
3763           }
3764         else return EINA_FALSE;
3765      }
3766    else return EINA_FALSE;
3767
3768    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3769    eo_do(sd->pan_obj, elm_obj_pan_pos_max_get(&pan_max_x, &pan_max_y));
3770    if (x < 0) x = 0;
3771    if (x > pan_max_x) x = pan_max_x;
3772    if (y < 0) y = 0;
3773    if (y > pan_max_y) y = pan_max_y;
3774
3775    eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
3776
3777    return EINA_TRUE;
3778 }
3779 //#endif
3780
3781 /* This function disables the specific code of the layout sub object add.
3782  * Only the widget sub_object_add is called.
3783  */
3784 EOLIAN static Eina_Bool
3785 _elm_genlist_elm_layout_sub_object_add_enable(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
3786 {
3787    return EINA_FALSE;
3788 }
3789
3790 EOLIAN static Eina_Bool
3791 _elm_genlist_elm_widget_sub_object_add(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED, Evas_Object *sobj)
3792 {
3793    Eina_Bool int_ret = EINA_FALSE;
3794
3795    /* skipping layout's code, which registers size hint changing
3796     * callback on sub objects. this is here because items'
3797     * content_get() routines may change hints on the objects after
3798     * creation, thus issuing TOO MANY sizing_eval()'s here. they are
3799     * not needed at here anyway, so let's skip listening to those
3800     * hints changes */
3801
3802    eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_add(sobj));
3803    if (!int_ret) return EINA_FALSE;
3804
3805    //if (!parent_parent->sub_object_add(obj, sobj))
3806    //  return EINA_FALSE;
3807
3808    return EINA_TRUE;
3809 }
3810
3811 EOLIAN static Eina_Bool
3812 _elm_genlist_elm_widget_sub_object_del(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *sobj)
3813 {
3814    Eina_Bool int_ret = EINA_FALSE;
3815
3816    /* XXX: hack -- also skipping sizing recalculation on
3817     * sub-object-del. genlist's crazy code paths (like groups and
3818     * such) seem to issue a whole lot of deletions and Evas bitches
3819     * about too many recalculations */
3820    sd->on_sub_del = EINA_TRUE;
3821
3822    eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_del(sobj));
3823    if (!int_ret) return EINA_FALSE;
3824
3825    sd->on_sub_del = EINA_FALSE;
3826
3827    return EINA_TRUE;
3828 }
3829
3830 static void
3831 _elm_genlist_focus_highlight_show(void *data EINA_UNUSED,
3832                                   Evas_Object *obj,
3833                                   const char *emission EINA_UNUSED,
3834                                   const char *src EINA_UNUSED)
3835 {
3836    ELM_GENLIST_DATA_GET(obj, sd);
3837
3838    if (sd->focused_item)
3839      {
3840         if (!sd->focused_content)
3841           {
3842              Eina_Bool found = EINA_FALSE;
3843              Elm_Gen_Item *it = sd->focused_item;
3844              found = _item_focusable_search(&it, 1);
3845              if (found)
3846                {
3847                 sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3848                 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3849                }
3850           }
3851         else elm_object_focus_set(sd->focused_content, EINA_TRUE);
3852      }
3853 }
3854
3855 static void
3856 _elm_genlist_focus_highlight_hide(void *data EINA_UNUSED,
3857                                   Evas_Object *obj,
3858                                   const char *emission EINA_UNUSED,
3859                                   const char *src EINA_UNUSED)
3860 {
3861    ELM_GENLIST_DATA_GET(obj, sd);
3862    if (sd->focused_item)
3863      {
3864         // Do not use _item_unfocused because focus should be remained
3865         edje_object_signal_emit
3866            (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
3867         if (sd->focused_item->deco_all_view)
3868            edje_object_signal_emit
3869               (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
3870      }
3871 }
3872
3873 EOLIAN static void
3874 _elm_genlist_elm_widget_focus_highlight_geometry_get(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
3875 {
3876    Evas_Coord ox, oy, oh, ow, item_x = 0, item_y = 0, item_w = 0, item_h = 0;
3877    Elm_Gen_Item *focus_it;
3878
3879    evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
3880
3881    if (sd->focused_item)
3882      {
3883         focus_it = sd->focused_item;
3884         evas_object_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
3885         elm_widget_focus_highlight_focus_part_geometry_get(VIEW(focus_it), &item_x, &item_y, &item_w, &item_h);
3886      }
3887
3888    *x = item_x;
3889    *y = item_y;
3890    *w = item_w;
3891    *h = item_h;
3892
3893    if (item_y < oy)
3894      {
3895         *y = oy;
3896      }
3897    if (item_y > (oy + oh - item_h))
3898      {
3899         *y = oy + oh - item_h;
3900      }
3901
3902    if ((item_x + item_w) > (ox + ow))
3903      {
3904         *w = ow;
3905      }
3906    if (item_x < ox)
3907      {
3908         *x = ox;
3909      }
3910 }
3911
3912 EOLIAN static Eina_Bool
3913 _elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd, Elm_Object_Item *item EINA_UNUSED)
3914 {
3915    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
3916    Eina_Bool int_ret = EINA_FALSE;
3917
3918    eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_on_focus(NULL));
3919    if (!int_ret) return EINA_FALSE;
3920
3921    if ((sd->items) && (sd->selected) && (!sd->last_selected_item))
3922      sd->last_selected_item = eina_list_data_get(sd->selected);
3923
3924    if (sd->select_on_focus_enabled) return EINA_TRUE;
3925    if (elm_widget_focus_get(obj))
3926      {
3927         // Do nothing if on_focus is called by child's parent_focus
3928         if (!wd->is_focus_target) return EINA_TRUE;
3929
3930         if (sd->focused_item)
3931           {
3932              if (!sd->focused_content)
3933                {
3934                   Eina_Bool found = EINA_FALSE;
3935                   Elm_Gen_Item *it = sd->focused_item;
3936                   found = _item_focusable_search(&it, 1);
3937                   if (found)
3938                     {
3939                        sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
3940                        elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
3941                     }
3942                }
3943              else
3944                elm_object_focus_set(sd->focused_content, EINA_TRUE);
3945           }
3946         else
3947           {
3948              Item_Block *itb, *nib;
3949              EINA_INLIST_FOREACH(sd->blocks, itb)
3950                {
3951                   if (itb->realized)
3952                     {
3953                        Elm_Gen_Item *tmp = eina_list_data_get(itb->items);
3954                        while(tmp && tmp->item->block == itb)
3955                          {
3956                             if (tmp->realized)
3957                               {
3958                                  Elm_Gen_Item *old = tmp;
3959                                  Evas_Coord x, y, w, h, sx, sy, sw, sh;
3960                                  evas_object_geometry_get(VIEW(tmp), &x, &y, &w, &h);
3961                                  evas_object_geometry_get(obj, &sx, &sy, &sw, &sh);
3962                                  /* Item is included viewport and focusable */
3963                                  if ((ELM_RECTS_INCLUDE(sx, sy, sw, sh, x, y, w, h)) &&
3964                                      (_item_focusable_search(&tmp, 1)))
3965                                    {
3966                                       Eina_Bool include = EINA_TRUE;
3967                                       if (old != tmp && tmp->realized)
3968                                         {
3969                                            evas_object_geometry_get(VIEW(tmp), &x, &y, &w, &h);
3970                                            evas_object_geometry_get(obj, &sx, &sy, &sw, &sh);
3971                                            include = ELM_RECTS_INCLUDE(sx, sy, sw, sh, x, y, w, h);
3972                                         }
3973                                       else if (!tmp->realized) include = EINA_FALSE;
3974
3975                                       if (include)
3976                                         {
3977                                            elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
3978                                            return EINA_TRUE;
3979                                         }
3980                                    }
3981                               }
3982
3983                             if (!tmp) break;
3984                             tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->next);
3985                          }
3986
3987                        nib = EINA_INLIST_CONTAINER_GET(EINA_INLIST_GET(itb)->next, Item_Block);
3988                        if (!nib || !nib->realized) break;
3989                     }
3990                }
3991              if (!sd->focused_item) _item_focus_next(sd, FOCUS_DIR_DOWN);
3992           }
3993      }
3994    else
3995      {
3996         // when key down and not called key up
3997         // and focus is not on genlist, call select_timer forcely
3998         if (sd->key_down_item)
3999           {
4000              _select_timer(sd->key_down_item);
4001              sd->key_down_item = NULL;
4002           }
4003
4004         if (sd->focused_item)
4005           {
4006              if (sd->focused_content)
4007                {
4008                   //FIXME: when genlist contents loose their focus,
4009                   //       focus unset should automatically work.
4010                   elm_object_focus_set(sd->focused_content, EINA_FALSE);
4011                }
4012              // Do not use _item_unfocused because focus should be remained
4013              edje_object_signal_emit
4014                 (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
4015               if (sd->focused_item->deco_all_view)
4016                 edje_object_signal_emit
4017                    (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
4018           }
4019      }
4020
4021    return EINA_TRUE;
4022 }
4023
4024 EOLIAN static void
4025 _elm_genlist_item_elm_widget_item_focus_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool focused)
4026 {
4027    Evas_Object *obj = WIDGET(it);
4028    ELM_GENLIST_DATA_GET(obj, sd);
4029
4030    if (focused)
4031      {
4032         if (!elm_object_focus_get(obj))
4033           elm_object_focus_set(obj, EINA_TRUE);
4034
4035         if (!elm_widget_focus_get(obj))
4036           return;
4037
4038         if (sd->focused_content)
4039           {
4040              elm_object_focus_set(sd->focused_content, EINA_FALSE);
4041              sd->focused_content = NULL;
4042           }
4043
4044         if (it != sd->focused_item)
4045           {
4046              if (sd->focused_item)
4047                _item_unfocused(sd->focused_item);
4048              _item_focused(it, sd->focus_scrollto_type);
4049
4050              /* If item is not realized state, widget couldn't get focus_highlight data. */
4051              if (it->realized)
4052                {
4053                   _elm_widget_item_highlight_in_theme(obj, EO_OBJ(it));
4054                   _elm_widget_highlight_in_theme_update(obj);
4055                   _elm_widget_focus_highlight_start(obj);
4056                }
4057           }
4058      }
4059    else
4060      {
4061         if (!elm_widget_focus_get(obj))
4062           return;
4063         _item_unfocused(it);
4064      }
4065 }
4066
4067 EOLIAN static Eina_Bool
4068 _elm_genlist_item_elm_widget_item_focus_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
4069 {
4070    Evas_Object *obj = WIDGET(it);
4071    ELM_GENLIST_DATA_GET(obj, sd);
4072
4073    if (it == sd->focused_item)
4074      return EINA_TRUE;
4075
4076    return EINA_FALSE;
4077 }
4078
4079 EOLIAN static Elm_Object_Item*
4080 _elm_genlist_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
4081 {
4082    return EO_OBJ(sd->focused_item);
4083 }
4084
4085 static Eina_Bool _elm_genlist_smart_focus_next_enable = EINA_FALSE;
4086
4087 EOLIAN static Eina_Bool
4088 _elm_genlist_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
4089 {
4090    return _elm_genlist_smart_focus_next_enable;
4091 }
4092
4093 EOLIAN static Eina_Bool
4094 _elm_genlist_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Genlist_Data *_pd EINA_UNUSED)
4095 {
4096    return EINA_FALSE;
4097 }
4098
4099 EOLIAN static Eina_Bool
4100 _elm_genlist_elm_widget_focus_next(Eo *obj, Elm_Genlist_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
4101 {
4102    Eina_List *items = NULL;
4103    Item_Block *itb = NULL;
4104    Elm_Object_Item *eo_it = NULL;
4105
4106    if (!sd->blocks) return EINA_FALSE;
4107    if (!sd->is_access) return EINA_FALSE;
4108
4109    if (!elm_widget_highlight_get(obj))
4110      {
4111         if (ELM_FOCUS_PREVIOUS == dir)
4112           {
4113              eo_it = elm_genlist_last_item_get(obj);
4114              itb = EINA_INLIST_CONTAINER_GET(sd->blocks->last, Item_Block);
4115           }
4116         else if (ELM_FOCUS_NEXT == dir)
4117           {
4118              eo_it = elm_genlist_first_item_get(obj);
4119              itb = EINA_INLIST_CONTAINER_GET(sd->blocks, Item_Block);
4120           }
4121         else return EINA_FALSE;
4122
4123         if (eo_it && itb && itb->calc_done)
4124           {
4125              _item_block_realize(itb, EINA_TRUE);
4126              elm_genlist_item_show(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
4127           }
4128         else return EINA_FALSE;
4129      }
4130
4131    // FIXME: do not use realized items get
4132    // because of above forcing realization case.
4133    EINA_INLIST_FOREACH(sd->blocks, itb)
4134      {
4135         Eina_List *l;
4136         Elm_Gen_Item *it;
4137
4138         if (!itb->realized) continue;
4139
4140         EINA_LIST_FOREACH(itb->items, l, it)
4141           {
4142              Eina_List *ll;
4143              Evas_Object *c, *ret;
4144              Eina_List *orders;
4145
4146              if (!(it->realized)) continue;
4147
4148              if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_access_object_get()))
4149                 items = eina_list_append(items, eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_access_object_get()));
4150              else
4151                 items = eina_list_append(items, VIEW(it));
4152
4153              orders = (Eina_List *)elm_object_item_access_order_get(EO_OBJ(it));
4154              EINA_LIST_FOREACH(orders, ll, c)
4155                {
4156                   items = eina_list_append(items, c);
4157                }
4158           }
4159      }
4160
4161    return elm_widget_focus_list_next_get
4162             (obj, items, eina_list_data_get, dir, next, next_item);
4163 }
4164
4165 static void
4166 _mirrored_set(Evas_Object *obj,
4167               Eina_Bool rtl)
4168 {
4169    eo_do(obj, elm_interface_scrollable_mirrored_set(rtl));
4170 }
4171
4172 EOLIAN static Elm_Theme_Apply
4173 _elm_genlist_elm_widget_theme_apply(Eo *obj, Elm_Genlist_Data *sd)
4174 {
4175    Item_Block *itb;
4176    Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
4177    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wsd, ELM_THEME_APPLY_FAILED);
4178
4179    eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
4180    if (!int_ret) return ELM_THEME_APPLY_FAILED;
4181
4182    if (!TIZEN_PROFILE_WEARABLE)
4183      _banded_bg_state_check(obj, sd);
4184
4185    EINA_INLIST_FOREACH(sd->blocks, itb)
4186      {
4187         Eina_List *l;
4188         Elm_Gen_Item *it;
4189         EINA_LIST_FOREACH(itb->items, l, it)
4190           {
4191              if (it->realized)
4192                {
4193                   _item_unrealize(it, EINA_FALSE);
4194                   GL_IT(it)->calc_done = EINA_FALSE;
4195                   GL_IT(it)->block->calc_done = EINA_FALSE;
4196                }
4197              else _item_queue(it, NULL);
4198           }
4199      }
4200    sd->calc_done = EINA_FALSE;
4201    _item_cache_all_free(sd);
4202    eina_hash_free_buckets(sd->size_caches);
4203    elm_layout_sizing_eval(obj);
4204    _changed(sd->pan_obj);
4205
4206    if (wsd->scroll_item_align_enable && sd->aligned_item)
4207      elm_genlist_item_show(EO_OBJ(sd->aligned_item), ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
4208
4209    return int_ret;
4210 }
4211
4212 /* FIXME: take off later. maybe this show region coords belong in the
4213  * interface (new api functions, set/get)? */
4214 static void
4215 _show_region_hook(void *data,
4216                   Evas_Object *obj)
4217 {
4218    Evas_Coord x, y, w, h;
4219
4220    ELM_GENLIST_DATA_GET(data, sd);
4221
4222    elm_widget_show_region_get(obj, &x, &y, &w, &h);
4223    //x & y are screen coordinates, Add with pan coordinates
4224    x += sd->pan_x;
4225    y += sd->pan_y;
4226
4227    eo_do(obj, elm_interface_scrollable_content_region_show(x, y, w, h));
4228 }
4229
4230 EOLIAN static Eina_Bool
4231 _elm_genlist_elm_widget_translate(Eo *obj, Elm_Genlist_Data *sd)
4232 {
4233    Item_Block *itb;
4234
4235    // Before calling text_get, inform user first.
4236    evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
4237
4238    // FIXME: We should change item's height if lang is changed??
4239    EINA_INLIST_FOREACH(sd->blocks, itb)
4240      {
4241         Eina_List *l;
4242         Elm_Gen_Item *it;
4243         EINA_LIST_FOREACH(itb->items, l, it)
4244           {
4245              if (it->realized)
4246                {
4247                   elm_genlist_item_fields_update(EO_OBJ(it),
4248                                                  NULL,
4249                                                  ELM_GENLIST_ITEM_FIELD_TEXT);
4250                }
4251              else GL_IT(it)->calc_done = EINA_FALSE;
4252           }
4253         itb->calc_done = EINA_FALSE;
4254      }
4255
4256    eina_hash_free_buckets(sd->size_caches);
4257    sd->calc_done = EINA_FALSE;
4258
4259    return EINA_TRUE;
4260 }
4261
4262 EOLIAN static void
4263 _elm_genlist_elm_widget_item_loop_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enable EINA_UNUSED)
4264 {
4265    // Need to be implemented
4266    //sd->item_loop_enable = !!enable;
4267 }
4268
4269 EOLIAN static Eina_Bool
4270 _elm_genlist_elm_widget_item_loop_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
4271 {
4272    // Need to be implemented
4273    //return sd->item_loop_enable;
4274    return EINA_FALSE;
4275 }
4276
4277 static void
4278 _item_block_position_update(Eina_Inlist *list,
4279                             int idx)
4280 {
4281    Item_Block *tmp;
4282
4283    EINA_INLIST_FOREACH(list, tmp)
4284      {
4285         tmp->position = idx++;
4286         tmp->position_update = EINA_TRUE;
4287      }
4288 }
4289
4290 static void
4291 _item_position_update(Eina_List *list,
4292                       int idx)
4293 {
4294    Elm_Gen_Item *it;
4295    Eina_List *l;
4296
4297    EINA_LIST_FOREACH(list, l, it)
4298      {
4299         it->position = idx++;
4300         it->position_update = EINA_TRUE;
4301      }
4302 }
4303
4304 static void
4305 _item_block_merge(Item_Block *left,
4306                   Item_Block *right)
4307 {
4308    Eina_List *l;
4309    Elm_Gen_Item *it2;
4310
4311    EINA_LIST_FOREACH(right->items, l, it2)
4312      {
4313         it2->item->block = left;
4314         left->count++;
4315         left->calc_done = EINA_FALSE;
4316      }
4317    left->items = eina_list_merge(left->items, right->items);
4318 }
4319
4320 static void
4321 _item_block_del(Elm_Gen_Item *it)
4322 {
4323    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4324    Eina_Inlist *il;
4325    Item_Block *itb = GL_IT(it)->block;
4326    Eina_Bool block_changed = EINA_FALSE;
4327    Evas_Coord vh;
4328
4329    eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
4330       (NULL, NULL, NULL, &vh));
4331    if (sd->processed_sizes >= vh) sd->processed_sizes = 0;
4332
4333    itb->items = eina_list_remove(itb->items, it);
4334    itb->count--;
4335    itb->calc_done = EINA_FALSE;
4336    sd->calc_done = EINA_FALSE;
4337    _changed(sd->pan_obj);
4338    if (itb->count < 1)
4339      {
4340         Item_Block *itbn;
4341
4342         il = EINA_INLIST_GET(itb);
4343         itbn = (Item_Block *)(il->next);
4344         if (it->parent)
4345           it->parent->item->items =
4346             eina_list_remove(it->parent->item->items, EO_OBJ(it));
4347         else
4348           {
4349              _item_block_position_update(il->next, itb->position);
4350           }
4351         GL_IT(it)->wsd->blocks =
4352           eina_inlist_remove(GL_IT(it)->wsd->blocks, il);
4353         GL_IT(it)->wsd->blocks_realized = eina_list_remove
4354            (GL_IT(it)->wsd->blocks_realized, itb);
4355         free(itb);
4356         itb = NULL;
4357         if (itbn) itbn->calc_done = EINA_FALSE;
4358      }
4359    else
4360      {
4361         if (itb->count < (itb->sd->max_items_per_block / 2))
4362           {
4363              Item_Block *itbp;
4364              Item_Block *itbn;
4365
4366              il = EINA_INLIST_GET(itb);
4367              itbp = (Item_Block *)(il->prev);
4368              itbn = (Item_Block *)(il->next);
4369
4370              /* merge block with previous */
4371              if ((itbp) &&
4372                  ((itbp->count + itb->count) <
4373                   (itb->sd->max_items_per_block +
4374                    (itb->sd->max_items_per_block / 2))))
4375                {
4376                   _item_block_merge(itbp, itb);
4377                   _item_block_position_update
4378                     (EINA_INLIST_GET(itb)->next, itb->position);
4379                   GL_IT(it)->wsd->blocks = eina_inlist_remove
4380                       (GL_IT(it)->wsd->blocks, EINA_INLIST_GET(itb));
4381                   GL_IT(it)->wsd->blocks_realized = eina_list_remove
4382                      (GL_IT(it)->wsd->blocks_realized, itb);
4383                   free(itb);
4384                   block_changed = EINA_TRUE;
4385                }
4386              /* merge block with next */
4387              else if ((itbn) &&
4388                       ((itbn->count + itb->count) <
4389                        (itb->sd->max_items_per_block +
4390                         (itb->sd->max_items_per_block / 2))))
4391                {
4392                   _item_block_merge(itb, itbn);
4393                   _item_block_position_update
4394                     (EINA_INLIST_GET(itbn)->next, itbn->position);
4395                   GL_IT(it)->wsd->blocks =
4396                     eina_inlist_remove(GL_IT(it)->wsd->blocks,
4397                                        EINA_INLIST_GET(itbn));
4398                   GL_IT(it)->wsd->blocks_realized = eina_list_remove
4399                      (GL_IT(it)->wsd->blocks_realized, itbn);
4400                   free(itbn);
4401                   block_changed = EINA_TRUE;
4402                }
4403           }
4404      }
4405
4406    if (block_changed)
4407      {
4408         _changed(sd->pan_obj);
4409      }
4410
4411    GL_IT(it)->block = NULL;
4412 }
4413
4414 static void
4415 _decorate_all_item_unrealize(Elm_Gen_Item *it)
4416 {
4417    if (!it->deco_all_view) return;
4418
4419    edje_object_part_unswallow(it->deco_all_view, VIEW(it));
4420    _view_clear(it->deco_all_view, &(GL_IT(it)->deco_all_contents));
4421    evas_object_del(it->deco_all_view);
4422    it->deco_all_view = NULL;
4423
4424    edje_object_signal_emit(VIEW(it), SIGNAL_DECORATE_DISABLED, "elm");
4425
4426    _item_mouse_callbacks_add(it, VIEW(it));
4427    evas_object_smart_member_add(VIEW(it), GL_IT(it)->wsd->pan_obj);
4428 }
4429
4430
4431 static void
4432 _item_mouse_move_cb(void *data,
4433                     Evas *evas EINA_UNUSED,
4434                     Evas_Object *obj,
4435                     void *event_info)
4436 {
4437    Evas_Event_Mouse_Move *ev = event_info;
4438    Elm_Gen_Item *it = data;
4439    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4440
4441    if (!it->down) return;
4442
4443    if (((sd->reorder_force) || (sd->reorder_mode)) &&
4444        (sd->reorder.it == it) &&
4445        (!it->want_hidden))
4446      {
4447         Evas_Coord ox;
4448         evas_object_geometry_get(sd->pan_obj, &ox, NULL, NULL, NULL);
4449
4450         if ((ev->cur.canvas.y - it->dy) > GL_IT(it)->scrl_y)
4451            sd->reorder.dir = 1;
4452         else if ((ev->cur.canvas.y - it->dy) < GL_IT(it)->scrl_y)
4453            sd->reorder.dir = -1;
4454
4455         GL_IT(it)->scrl_x = it->x + GL_IT(it)->block->x - sd->pan_x + ox;
4456         GL_IT(it)->scrl_y = ev->cur.canvas.y - it->dy;
4457         GL_IT(it)->w = sd->minw;
4458         GL_IT(it)->h = GL_IT(it)->minh;
4459         _changed(sd->pan_obj);
4460      }
4461
4462    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
4463      {
4464         if (GL_IT(it)->highlight_timer)
4465           {
4466              ecore_timer_del(GL_IT(it)->highlight_timer);
4467              GL_IT(it)->highlight_timer = NULL;
4468           }
4469         else if (!it->selected) _item_unhighlight(it, EINA_FALSE);
4470
4471         if (it->long_timer)
4472           {
4473              ecore_timer_del(it->long_timer);
4474              it->long_timer = NULL;
4475           }
4476          sd->on_hold = EINA_TRUE; /* for checking need to start select timer */
4477      }
4478    //******************** TIZEN Only
4479    else
4480      {
4481         if (((sd->reorder_force) || (sd->reorder_mode)) &&
4482             (sd->reorder.it == it) && (!it->want_hidden))
4483           return;
4484         Evas_Coord x, y, w, h;
4485         evas_object_geometry_get(obj, &x, &y, &w, &h);
4486         if (ELM_RECTS_POINT_OUT(x, y, w, h, ev->cur.canvas.x, ev->cur.canvas.y))
4487           {
4488              if (it->long_timer)
4489                {
4490                   ecore_timer_del(it->long_timer);
4491                   it->long_timer = NULL;
4492                }
4493              if (GL_IT(it)->highlight_timer)
4494                {
4495                   ecore_timer_del(GL_IT(it)->highlight_timer);
4496                   GL_IT(it)->highlight_timer = NULL;
4497                }
4498              else if (!it->selected) _item_unhighlight(it, EINA_FALSE);
4499           }
4500      }
4501    //*******************************
4502
4503    evas_object_ref(obj);
4504
4505    if (!it->dragging)
4506      {
4507         Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
4508         minw = GL_IT(it)->wsd->finger_minw;
4509         minh = GL_IT(it)->wsd->finger_minh;
4510
4511         evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4512         dx = ev->cur.canvas.x - x;
4513         dy = ev->cur.canvas.y - y;
4514         dx = dx - it->dx;
4515         dy = dy - it->dy;
4516         adx = dx;
4517         ady = dy;
4518         if (adx < 0) adx = -dx;
4519         if (ady < 0) ady = -dy;
4520         if ((adx > minw) || (ady > minh))
4521           {
4522              it->dragging = EINA_TRUE;
4523              /* Genlist is scrolled vertically, so reduce left or right case for accuracy. */
4524              if (adx > (ady * 2))
4525                {
4526                   if (dx < 0)
4527                     evas_object_smart_callback_call
4528                        (WIDGET(it), SIG_DRAG_START_LEFT, EO_OBJ(it));
4529                   else
4530                     evas_object_smart_callback_call
4531                        (WIDGET(it), SIG_DRAG_START_RIGHT, EO_OBJ(it));
4532                }
4533              else
4534                {
4535                   if (dy < 0)
4536                     evas_object_smart_callback_call
4537                        (WIDGET(it), SIG_DRAG_START_UP, EO_OBJ(it));
4538                   else
4539                     evas_object_smart_callback_call
4540                        (WIDGET(it), SIG_DRAG_START_DOWN, EO_OBJ(it));
4541                }
4542           }
4543      }
4544
4545    /* If item magic value is changed, do not call smart callback*/
4546    if (EINA_MAGIC_CHECK(it->base, ELM_WIDGET_ITEM_MAGIC))
4547      {
4548         if (it->dragging)
4549           evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, EO_OBJ(it));
4550      }
4551
4552    evas_object_unref(obj);
4553
4554 }
4555
4556 static Eina_Bool
4557 _long_press_cb(void *data)
4558 {
4559    Elm_Gen_Item *it = data;
4560    Elm_Object_Item *eo_it2;
4561    Elm_Genlist_Data *sd;
4562    Eina_List *l, *ll;
4563    Eina_Bool ret;
4564
4565    sd = GL_IT(it)->wsd;
4566    it->long_timer = NULL;
4567
4568    if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()) ||
4569        (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
4570        (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
4571        (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
4572        (sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
4573      goto end;
4574
4575    if ((sd->reorder_mode) &&
4576        (GL_IT(it)->type != ELM_GENLIST_ITEM_GROUP) &&
4577        (!sd->key_down_item))
4578      {
4579         if (elm_genlist_item_expanded_get(EO_OBJ(it)))
4580           {
4581              elm_genlist_item_expanded_set(EO_OBJ(it), EINA_FALSE);
4582           }
4583         EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it2)
4584           {
4585              ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
4586              _item_unselect(it2);
4587           }
4588
4589         eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
4590         eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
4591                     (EINA_FALSE, EINA_FALSE));
4592
4593         if (TIZEN_PROFILE_WEARABLE)
4594           {
4595
4596              if (sd->decorate_all_mode)
4597                edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
4598           }
4599         else
4600           {
4601              edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_ENABLED, "elm");
4602           }
4603
4604         sd->reorder.it = it;
4605         _changed(sd->pan_obj);
4606      }
4607    evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, EO_OBJ(it));
4608
4609 end:
4610    it->long_timer = NULL;
4611    return ECORE_CALLBACK_CANCEL;
4612 }
4613
4614 void
4615 _gesture_do(void *data)
4616 {
4617    Elm_Genlist_Data *sd = data;
4618
4619    if ((sd->g_item) && (sd->g_type))
4620      {
4621         if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_LEFT))
4622                evas_object_smart_callback_call
4623              (WIDGET(sd->g_item), SIG_MULTI_SWIPE_LEFT, EO_OBJ(sd->g_item));
4624         else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_RIGHT))
4625                evas_object_smart_callback_call
4626              (WIDGET(sd->g_item), SIG_MULTI_SWIPE_RIGHT, EO_OBJ(sd->g_item));
4627         else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_UP))
4628                evas_object_smart_callback_call
4629              (WIDGET(sd->g_item), SIG_MULTI_SWIPE_UP, EO_OBJ(sd->g_item));
4630         else if (!strcmp(sd->g_type, SIG_MULTI_SWIPE_DOWN))
4631                evas_object_smart_callback_call
4632              (WIDGET(sd->g_item), SIG_MULTI_SWIPE_DOWN, EO_OBJ(sd->g_item));
4633         else if (!strcmp(sd->g_type, SIG_MULTI_PINCH_OUT))
4634           evas_object_smart_callback_call
4635              (WIDGET(sd->g_item), SIG_MULTI_PINCH_OUT, EO_OBJ(sd->g_item));
4636         else if (!strcmp(sd->g_type, SIG_MULTI_PINCH_IN))
4637           evas_object_smart_callback_call
4638              (WIDGET(sd->g_item), SIG_MULTI_PINCH_IN, EO_OBJ(sd->g_item));
4639         else if (!strcmp(sd->g_type, SIG_SWIPE))
4640           evas_object_smart_callback_call
4641              (WIDGET(sd->g_item), SIG_SWIPE, EO_OBJ(sd->g_item));
4642
4643         sd->g_item = NULL;
4644         sd->g_type = NULL;
4645      }
4646 }
4647
4648 static void
4649 _item_mouse_down_cb(void *data,
4650                     Evas *evas,
4651                     Evas_Object *obj,
4652                     void *event_info)
4653 {
4654    Evas_Event_Mouse_Down *ev = event_info;
4655    Elm_Gen_Item *it = data;
4656    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4657    Evas_Coord x, y;
4658
4659    if (ev->event_flags & EVAS_EVENT_FLAG_ON_SCROLL)
4660      {
4661         if (sd->reorder.it)
4662           {
4663              elm_genlist_item_reorder_stop(EO_OBJ(sd->reorder.it));
4664              sd->reorder.it = NULL;
4665              eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
4666              eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set(sd->h_bounce, sd->v_bounce));
4667           }
4668         return;
4669      }
4670
4671    if (ev->button != 1) return;
4672    // mouse down is activate only one finger
4673    if (evas_event_down_count_get(evas) != 1) return;
4674
4675    if (GL_IT(it)->highlight_timer)
4676      ecore_timer_del(GL_IT(it)->highlight_timer);
4677    // FIXME: To prevent timing issue about select and highlight
4678    else if (!sd->multi && sd->highlighted_item &&
4679             (GL_IT(sd->highlighted_item)->highlight_timer))
4680         return;
4681
4682    it->down = EINA_TRUE;
4683
4684    evas_object_geometry_get(obj, &x, &y, NULL, NULL);
4685    it->dx = ev->canvas.x - x;
4686    it->dy = ev->canvas.y - y;
4687
4688    GL_IT(it)->wsd->was_selected = it->selected;
4689    GL_IT(it)->highlight_timer = ecore_timer_add(ELM_ITEM_HIGHLIGHT_TIMER,
4690                                                _highlight_timer, it);
4691    if (it->long_timer) ecore_timer_del(it->long_timer);
4692    it->long_timer = ecore_timer_add(sd->longpress_timeout, _long_press_cb, it);
4693
4694    if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
4695      {
4696         evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, EO_OBJ(it));
4697         evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, EO_OBJ(it));
4698      }
4699    evas_object_smart_callback_call(WIDGET(it), SIG_PRESSED, EO_OBJ(it));
4700 }
4701
4702 static Item_Block *
4703 _item_block_new(Elm_Genlist_Data *sd,
4704                 Eina_Bool prepend)
4705 {
4706    Item_Block *itb;
4707
4708    itb = calloc(1, sizeof(Item_Block));
4709    if (!itb) return NULL;
4710    itb->sd = sd;
4711    if (prepend)
4712      {
4713         sd->blocks = eina_inlist_prepend(sd->blocks, EINA_INLIST_GET(itb));
4714         _item_block_position_update(sd->blocks, 0);
4715      }
4716    else
4717      {
4718         sd->blocks = eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4719         itb->position_update = EINA_TRUE;
4720         if (sd->blocks != EINA_INLIST_GET(itb))
4721           {
4722              itb->position =
4723                ((Item_Block *)(EINA_INLIST_GET(itb)->prev))->position + 1;
4724           }
4725         else
4726           {
4727              itb->position = 0;
4728           }
4729      }
4730
4731    return itb;
4732 }
4733
4734 static Eina_Bool
4735 _item_block_add(Elm_Genlist_Data *sd,
4736                 Elm_Gen_Item *it)
4737 {
4738    Item_Block *itb = NULL;
4739    if (GL_IT(it)->block) return EINA_TRUE;
4740
4741    if (!GL_IT(it)->rel)
4742      {
4743 newblock:
4744         if (GL_IT(it)->rel)
4745           {
4746              itb = calloc(1, sizeof(Item_Block));
4747              if (!itb) return EINA_FALSE;
4748              itb->sd = sd;
4749              if (!GL_IT(it)->rel->item->block)
4750                {
4751                   sd->blocks =
4752                     eina_inlist_append(sd->blocks, EINA_INLIST_GET(itb));
4753                   itb->items = eina_list_append(itb->items, it);
4754                   itb->position_update = EINA_TRUE;
4755                   it->position = eina_list_count(itb->items);
4756                   it->position_update = EINA_TRUE;
4757
4758                   if (sd->blocks != EINA_INLIST_GET(itb))
4759                     {
4760                        itb->position =
4761                          ((Item_Block *)
4762                           (EINA_INLIST_GET(itb)->prev))->position + 1;
4763                     }
4764                   else
4765                     {
4766                        itb->position = 0;
4767                     }
4768                }
4769              else
4770                {
4771                   Eina_List *tmp;
4772
4773                   tmp = eina_list_data_find_list(itb->items, GL_IT(it)->rel);
4774                   if (GL_IT(it)->before)
4775                     {
4776                        sd->blocks = eina_inlist_prepend_relative
4777                            (sd->blocks, EINA_INLIST_GET(itb),
4778                            EINA_INLIST_GET(GL_IT(it)->rel->item->block));
4779                        itb->items =
4780                          eina_list_prepend_relative_list(itb->items, it, tmp);
4781
4782                        /* Update index from where we prepended */
4783                        _item_position_update
4784                          (eina_list_prev(tmp), GL_IT(it)->rel->position);
4785                        _item_block_position_update
4786                          (EINA_INLIST_GET(itb),
4787                          GL_IT(it)->rel->item->block->position);
4788                     }
4789                   else
4790                     {
4791                        sd->blocks = eina_inlist_append_relative
4792                            (sd->blocks, EINA_INLIST_GET(itb),
4793                            EINA_INLIST_GET(GL_IT(it)->rel->item->block));
4794                        itb->items =
4795                          eina_list_append_relative_list(itb->items, it, tmp);
4796
4797                        /* Update block index from where we appended */
4798                        _item_position_update
4799                          (eina_list_next(tmp), GL_IT(it)->rel->position + 1);
4800                        _item_block_position_update
4801                          (EINA_INLIST_GET(itb),
4802                          GL_IT(it)->rel->item->block->position + 1);
4803                     }
4804                }
4805           }
4806         else
4807           {
4808              if (GL_IT(it)->before)
4809                {
4810                   if (sd->blocks)
4811                     {
4812                        itb = (Item_Block *)(sd->blocks);
4813                        if (itb->count >= sd->max_items_per_block)
4814                          {
4815                             itb = _item_block_new(sd, EINA_TRUE);
4816                             if (!itb) return EINA_FALSE;
4817                          }
4818                     }
4819                   else
4820                     {
4821                        itb = _item_block_new(sd, EINA_TRUE);
4822                        if (!itb) return EINA_FALSE;
4823                     }
4824                   itb->items = eina_list_prepend(itb->items, it);
4825                   _item_position_update(itb->items, 1);
4826                }
4827              else
4828                {
4829                   if (sd->blocks)
4830                     {
4831                        itb = (Item_Block *)(sd->blocks->last);
4832                        if (itb->count >= sd->max_items_per_block)
4833                          {
4834                             itb = _item_block_new(sd, EINA_FALSE);
4835                             if (!itb) return EINA_FALSE;
4836                          }
4837                     }
4838                   else
4839                     {
4840                        itb = _item_block_new(sd, EINA_FALSE);
4841                        if (!itb) return EINA_FALSE;
4842                     }
4843                   itb->items = eina_list_append(itb->items, it);
4844                   it->position = eina_list_count(itb->items);
4845                }
4846           }
4847      }
4848    else
4849      {
4850         Eina_List *tmp;
4851
4852 #if 0
4853         if ((!GL_IT(it)->wsd->sorting) && (GL_IT(it)->rel->item->queued))
4854           {
4855              /* NOTE: for a strange reason eina_list and eina_inlist
4856                 don't have the same property on sorted insertion
4857                 order, so the queue is not always ordered like the
4858                 item list.  This lead to issue where we depend on an
4859                 item that is not yet created. As a quick work around,
4860                 we reschedule the calc of the item and stop reordering
4861                 the list to prevent any nasty issue to show up here.
4862               */
4863              sd->queue = eina_list_append(sd->queue, it);
4864              sd->requeued = EINA_TRUE;
4865              GL_IT(it)->queued = EINA_TRUE;
4866
4867              return EINA_FALSE;
4868           }
4869 #endif
4870         itb = GL_IT(it)->rel->item->block;
4871         if (!itb) goto newblock;
4872         tmp = eina_list_data_find_list(itb->items, GL_IT(it)->rel);
4873         if (GL_IT(it)->before)
4874           {
4875              itb->items = eina_list_prepend_relative_list(itb->items, it, tmp);
4876              _item_position_update
4877                (eina_list_prev(tmp), GL_IT(it)->rel->position);
4878           }
4879         else
4880           {
4881              itb->items = eina_list_append_relative_list(itb->items, it, tmp);
4882              _item_position_update
4883                (eina_list_next(tmp), GL_IT(it)->rel->position + 1);
4884           }
4885      }
4886
4887    itb->count++;
4888    itb->calc_done = EINA_FALSE;
4889    sd->calc_done = EINA_FALSE;
4890    GL_IT(it)->block = itb;
4891    _changed(itb->sd->pan_obj);
4892
4893    if (itb->count > itb->sd->max_items_per_block)
4894      {
4895         int newc;
4896         Item_Block *itb2;
4897         Elm_Gen_Item *it2;
4898         Eina_Bool done = EINA_FALSE;
4899
4900         newc = itb->count / 2;
4901
4902         if (EINA_INLIST_GET(itb)->prev)
4903           {
4904              Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
4905
4906              if (itbp->count + newc < sd->max_items_per_block / 2)
4907                {
4908                   /* moving items to previous block */
4909                   while ((itb->count > newc) && (itb->items))
4910                     {
4911                        it2 = eina_list_data_get(itb->items);
4912                        itb->items = eina_list_remove_list
4913                            (itb->items, itb->items);
4914                        itb->count--;
4915
4916                        itbp->items = eina_list_append(itbp->items, it2);
4917                        it2->item->block = itbp;
4918                        itbp->count++;
4919                     }
4920
4921                   done = EINA_TRUE;
4922                }
4923           }
4924
4925         if (!done && EINA_INLIST_GET(itb)->next)
4926           {
4927              Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
4928
4929              if (itbn->count + newc < sd->max_items_per_block / 2)
4930                {
4931                   /* moving items to next block */
4932                   while ((itb->count > newc) && (itb->items))
4933                     {
4934                        Eina_List *l;
4935
4936                        l = eina_list_last(itb->items);
4937                        it2 = eina_list_data_get(l);
4938                        itb->items = eina_list_remove_list(itb->items, l);
4939                        itb->count--;
4940
4941                        itbn->items = eina_list_prepend(itbn->items, it2);
4942                        it2->item->block = itbn;
4943                        itbn->count++;
4944                     }
4945
4946                   done = EINA_TRUE;
4947                }
4948           }
4949
4950         if (!done)
4951           {
4952              /* moving items to new block */
4953              itb2 = calloc(1, sizeof(Item_Block));
4954              if (!itb2) return EINA_FALSE;
4955              itb2->sd = sd;
4956              sd->blocks =
4957                eina_inlist_append_relative(sd->blocks, EINA_INLIST_GET(itb2),
4958                                            EINA_INLIST_GET(itb));
4959              itb2->calc_done = EINA_FALSE;
4960              while ((itb->count > newc) && (itb->items))
4961                {
4962                   Eina_List *l;
4963
4964                   l = eina_list_last(itb->items);
4965                   it2 = l->data;
4966                   itb->items = eina_list_remove_list(itb->items, l);
4967                   itb->count--;
4968
4969                   itb2->items = eina_list_prepend(itb2->items, it2);
4970                   it2->item->block = itb2;
4971                   itb2->count++;
4972                }
4973           }
4974      }
4975
4976    return EINA_TRUE;
4977 }
4978
4979 static void
4980 _item_min_calc(Elm_Gen_Item *it)
4981 {
4982    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
4983    Evas_Coord mw = 0, mh = 0;
4984    Evas_Coord vw = 0;
4985
4986    eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
4987                (NULL, NULL, &vw, NULL));
4988
4989    if ((it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) &&
4990        (sd->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
4991      {
4992         mw = sd->finger_minw;
4993         mh = sd->finger_minh;
4994      }
4995
4996    if ((sd->mode == ELM_LIST_COMPRESS) && vw && mw < vw)
4997      mw = vw;
4998
4999    //FIXME: Some widget such as entry, label need to have fixed width size before
5000    // min calculation to get proper height size by multiline.
5001    if (sd->realization_mode || GL_IT(it)->resized)
5002      evas_object_resize(VIEW(it), mw, mh);
5003
5004    edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
5005
5006    if ((sd->mode != ELM_LIST_LIMIT) && vw && mw < vw)
5007      mw = vw;
5008
5009    // TIZEN ONLY(20160630): Support homogeneous mode in item class.
5010    if (sd->homogeneous || it->itc->homogeneous)
5011      {
5012         Size_Cache *size, *tmp;
5013         tmp = eina_hash_find(sd->size_caches, it->itc->item_style);
5014         if (tmp)
5015            eina_hash_del_by_key(sd->size_caches, it->itc->item_style);
5016
5017         size = ELM_NEW(Size_Cache);
5018         size->minw = mw;
5019         size->minh = mh;
5020         eina_hash_add(sd->size_caches, it->itc->item_style, size);
5021      }
5022
5023    GL_IT(it)->w = GL_IT(it)->minw = mw;
5024    GL_IT(it)->h = GL_IT(it)->minh = mh;
5025
5026    // FIXME: This is workaround for entry size issue.
5027    if (sd->realization_mode || GL_IT(it)->resized)
5028      {
5029         GL_IT(it)->resized = EINA_FALSE;
5030         if (it->deco_all_view)
5031           evas_object_resize(it->deco_all_view, GL_IT(it)->w, GL_IT(it)->h);
5032         else if (GL_IT(it)->deco_it_view)
5033           evas_object_resize(GL_IT(it)->deco_it_view, GL_IT(it)->w, GL_IT(it)->h);
5034         else
5035           evas_object_resize(VIEW(it), GL_IT(it)->w, GL_IT(it)->h);
5036      }
5037    //
5038 }
5039
5040 static void
5041 _item_calc(Elm_Gen_Item *it)
5042 {
5043    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5044    Size_Cache *size = NULL;
5045    Evas_Coord p_minw, p_minh;
5046
5047    if (GL_IT(it)->calc_done) return;
5048
5049    p_minw = GL_IT(it)->minw;
5050    p_minh = GL_IT(it)->minh;
5051
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);
5055    if (size)
5056      {
5057         GL_IT(it)->w = GL_IT(it)->minw = size->minw;
5058         GL_IT(it)->h = GL_IT(it)->minh = size->minh;
5059      }
5060    else
5061      {
5062         if (!it->realized)
5063           {
5064              if (sd->realization_mode)
5065                {
5066                   _item_realize(it, EINA_FALSE);
5067                   _item_min_calc(it);
5068                }
5069              else
5070                {
5071                   _item_realize(it, EINA_TRUE);
5072                   _item_min_calc(it);
5073                   _item_unrealize(it, EINA_TRUE);
5074                }
5075           }
5076         else
5077            _item_min_calc(it);
5078      }
5079
5080    GL_IT(it)->calc_done = EINA_TRUE;
5081    if ((p_minw != GL_IT(it)->minw) || (p_minh != GL_IT(it)->minh))
5082      {
5083         GL_IT(it)->block->calc_done = EINA_FALSE;
5084         sd->calc_done = EINA_FALSE;
5085      }
5086 }
5087
5088 static Eina_Bool
5089 _item_process(Elm_Genlist_Data *sd,
5090               Elm_Gen_Item *it)
5091 {
5092    if (!_item_block_add(sd, it)) return EINA_FALSE;
5093
5094    GL_IT(it)->calc_done = EINA_FALSE;
5095    _item_calc(it);
5096
5097    return EINA_TRUE;
5098 }
5099
5100 static void
5101 _dummy_job(void *data)
5102 {
5103    Elm_Genlist_Data *sd = data;
5104    sd->dummy_job = NULL;
5105    return;
5106 }
5107
5108 static Eina_Bool
5109 _queue_idle_enter(void *data)
5110 {
5111    Elm_Genlist_Data *sd = data;
5112    Evas_Coord vw = 0;
5113    int n;
5114    double ft, t0;
5115
5116    eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
5117                (NULL, NULL, &vw, NULL));
5118    if (!sd->queue || (vw <= 1))
5119      {
5120         if (sd->dummy_job)
5121           {
5122              ecore_job_del(sd->dummy_job);
5123              sd->dummy_job = NULL;
5124           }
5125         sd->queue_idle_enterer = NULL;
5126         return ECORE_CALLBACK_CANCEL;
5127      }
5128
5129    ft = ecore_animator_frametime_get()/2;
5130    t0 = ecore_time_get();
5131    for (n = 0; (sd->queue) && (n < ITEM_QUEUE_MAX); n++)
5132      {
5133         Elm_Gen_Item *it;
5134         double t;
5135
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)
5144           {
5145              if ((t - t0) > ft) break;
5146           }
5147      }
5148
5149    _changed(sd->pan_obj);
5150    if (!sd->queue)
5151      {
5152         if (sd->dummy_job)
5153           {
5154              ecore_job_del(sd->dummy_job);
5155              sd->dummy_job = NULL;
5156           }
5157         sd->queue_idle_enterer = NULL;
5158         return ECORE_CALLBACK_CANCEL;
5159      }
5160
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);
5165
5166    return ECORE_CALLBACK_RENEW;
5167 }
5168
5169 static void
5170 _item_queue(Elm_Gen_Item *it,
5171             Eina_Compare_Cb cb EINA_UNUSED)
5172 {
5173    if (GL_IT(it)->queued) return;
5174
5175    GL_IT(it)->queued = EINA_TRUE;
5176    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5177
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);
5183 //   else
5184      sd->queue = eina_list_append(sd->queue, it);
5185
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);
5189 }
5190
5191 static void
5192 _item_queue_direct(Elm_Gen_Item *it,
5193                    Eina_Compare_Cb cb)
5194 {
5195    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5196
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)))
5202      {
5203 #ifdef GENLIST_FX_SUPPORT
5204         if (sd->fx_mode)// && !it->item->is_prepend) // For support preppended items - hs619.choi@samsung.com
5205           {
5206               sd->add_fx.items = eina_list_append(sd->add_fx.items, it);
5207               if (!sd->add_fx.anim)
5208                 {
5209                    sd->add_fx.cnt = ANIM_CNT_MAX;
5210                    sd->add_fx.anim = ecore_animator_add(_add_fx_anim, sd);
5211                 }
5212            }
5213 #endif
5214         _item_process(sd, it);
5215         sd->processed_sizes += GL_IT(it)->minh;
5216
5217         _changed(sd->pan_obj);
5218         return;
5219      }
5220    _item_queue(it, cb);
5221 }
5222
5223 /* If the application wants to know the relative item, use
5224  * elm_genlist_item_prev_get(it)*/
5225 static void
5226 _item_move_after(Elm_Gen_Item *it,
5227                  Elm_Gen_Item *after)
5228 {
5229    if (!it) return;
5230    if (!after) return;
5231    if (it == after) return;
5232
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);
5236
5237    GL_IT(it)->wsd->items = eina_inlist_append_relative
5238       (GL_IT(it)->wsd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
5239
5240    if (GL_IT(it)->rel)
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;
5247
5248    if (GL_IT(it)->queued)
5249      {
5250         GL_IT(it)->wsd->queue = eina_list_remove(GL_IT(it)->wsd->queue, it);
5251         GL_IT(it)->queued = EINA_FALSE;
5252      }
5253    _item_queue_direct(it, NULL);
5254
5255    evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_AFTER, EO_OBJ(it));
5256 }
5257
5258 /* If the application wants to know the relative item, use
5259  * elm_genlist_item_next_get(it)*/
5260 static void
5261 _item_move_before(Elm_Gen_Item *it,
5262                   Elm_Gen_Item *before)
5263 {
5264    if (!it) return;
5265    if (!before) return;
5266    if (it == before) return;
5267
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));
5273
5274    if (GL_IT(it)->rel)
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);
5283
5284    evas_object_smart_callback_call(WIDGET(it), SIG_MOVED_BEFORE, EO_OBJ(it));
5285 }
5286
5287 static void
5288 _item_mouse_up_cb(void *data,
5289                   Evas *evas,
5290                   Evas_Object *obj EINA_UNUSED,
5291                   void *event_info)
5292 {
5293    Evas_Event_Mouse_Up *ev = event_info;
5294    Elm_Gen_Item *it = data;
5295    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
5296
5297    ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd);
5298
5299    if (!it->down) return;
5300    it->down = EINA_FALSE;
5301
5302    if (ev->button != 1) return;
5303
5304    if (it->dragging)
5305      {
5306         it->dragging = EINA_FALSE;
5307         evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, EO_OBJ(it));
5308      }
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;
5311
5312    _gesture_do(sd);
5313
5314    if (evas_event_down_count_get(evas) != 0)
5315      {
5316         if (!GL_IT(it)->highlight_timer) _item_unhighlight(it, EINA_TRUE);
5317      }
5318
5319    if (it->long_timer)
5320      {
5321         ecore_timer_del(it->long_timer);
5322         it->long_timer = NULL;
5323      }
5324    if (GL_IT(it)->highlight_timer)
5325      {
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);
5331      }
5332
5333    if (!sd->reorder.it && (evas_event_down_count_get(evas) == 0))
5334      {
5335         // FIXME: if highlight mode is not used, mouse move cannot disable
5336         // _item_select
5337         if ((sd->was_selected == it->selected) && (!sd->on_hold))
5338           {
5339              if (wd->scroll_item_align_enable)
5340                {
5341                   const char *align = edje_object_data_get(VIEW(it), "align");
5342                   if (!align || strcmp(align, "off"))
5343                     {
5344                        if (it != sd->aligned_item)
5345                          {
5346                             elm_genlist_item_bring_in(EO_OBJ(it), ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
5347                          }
5348                     }
5349                }
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))
5356                {
5357                   Eina_List *l;
5358                   Evas_Object *content;
5359                   if (sd->focused_item != it)
5360                     elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
5361
5362                   sd->focused_content = NULL;
5363                   EINA_LIST_FOREACH(it->content_objs, l, content)
5364                     {
5365                        if (elm_widget_focused_object_get(content))
5366                          sd->focused_content = content;
5367                     }
5368                }
5369           }
5370      }
5371    else if (sd->reorder.it == it)
5372      {
5373         if (TIZEN_PROFILE_WEARABLE)
5374           {
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;
5377
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)
5381                {
5382                   if (sd->reorder.it->parent != it2->parent)
5383                     {
5384                        it2->item->reorder_offset = 0;
5385                        continue;
5386                     }
5387                   Evas_Coord it_y = it2->item->scrl_y +
5388                      it2->item->reorder_offset + (it2->item->h / 2) +
5389                      it2->item->block->y;
5390
5391                   if ((it_y < r_y_scrl) &&
5392                       (it_y_max < it_y))
5393                     {
5394                        it_max = it2;
5395                        it_y_max = it_y;
5396                     }
5397                   else if ((it_y > r_y_scrl) &&
5398                            (it_y_min > it_y))
5399                     {
5400                        it_min = it2;
5401                        it_y_min = it_y;
5402                     }
5403                   it2->item->reorder_offset = 0;
5404                }
5405              if (it_max)
5406                {
5407                   _item_move_after(it, it_max);
5408                   evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5409                }
5410              else if (it_min)
5411                {
5412                   _item_move_before(it, it_min);
5413                   evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5414                }
5415           }
5416         else
5417           {
5418              //Kiran only
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;
5423
5424              if (!it->selected) _item_unhighlight(it, EINA_FALSE);
5425
5426              while (ptr_it)
5427                {
5428                   if (it != ptr_it)
5429                     {
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))
5432                          {
5433                             if (GL_IT(it)->scrl_y < GL_IT(ptr_it)->scrl_y)
5434                               after = EINA_FALSE;
5435                             moved_it = ptr_it;
5436                             break;
5437                          }
5438                        else
5439                          {
5440                             if ((GL_IT(it)->scrl_y + GL_IT(it)->h) > (GL_IT(ptr_it)->scrl_y + GL_IT(ptr_it)->h))
5441                               moved_it = ptr_it;
5442                             if ((GL_IT(it)->scrl_y + GL_IT(it)->h) == GL_IT(ptr_it)->scrl_y)
5443                               {
5444                                  after = EINA_FALSE;
5445                                  moved_it = ptr_it;
5446                               }
5447                          }
5448                     }
5449                   last_it = ptr_it;
5450                   ptr_it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(ptr_it)->next);
5451                }
5452
5453              if (!moved_it)
5454                {
5455                   if (GL_IT(it)->scrl_y > GL_IT(last_it)->scrl_y + GL_IT(last_it)->h)
5456                         moved_it = last_it;
5457                   else
5458                     {
5459                        moved_it = sd->top_drawn_item;
5460                        after = EINA_FALSE;
5461                     }
5462                }
5463
5464              EINA_LIST_FREE(sd->reorder.move_items, ptr_it)
5465                {
5466                   ptr_it->item->reorder_offset = 0;
5467                }
5468
5469              if (after)
5470                {
5471                   _item_move_after(it, moved_it);
5472                   evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5473                }
5474              else
5475                {
5476                  _item_move_before(it, moved_it);
5477                  evas_object_smart_callback_call(WIDGET(it), SIG_MOVED, EO_OBJ(it));
5478                }
5479           }
5480         sd->reorder.it = NULL;
5481         sd->reorder.dir = 0;
5482         if (sd->reorder.anim)
5483           {
5484              ecore_animator_del(sd->reorder.anim);
5485              sd->reorder.anim = NULL;
5486           }
5487
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));
5491
5492         edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_DISABLED, "elm");
5493         _changed(sd->pan_obj);
5494      }
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));
5497 }
5498
5499 static Eina_Bool
5500 _scroll_hold_timer_cb(void *data)
5501 {
5502    Elm_Genlist_Data *sd = data;
5503    sd->scr_hold_timer = NULL;
5504
5505    eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_FALSE));
5506
5507    return ECORE_CALLBACK_CANCEL;
5508 }
5509
5510 static void
5511 _decorate_item_finished_signal_cb(void *data,
5512                                   Evas_Object *obj,
5513                                   const char *emission EINA_UNUSED,
5514                                   const char *source EINA_UNUSED)
5515 {
5516    Elm_Gen_Item *it = data;
5517
5518    if (!data || !obj) return;
5519    if ((!it->realized)) return;
5520
5521    _decorate_item_unrealize(it);
5522 }
5523
5524 static void
5525 _item_update(Elm_Gen_Item *it)
5526 {
5527    Evas_Object *c;
5528    if (!it->realized) return;
5529
5530    _view_clear(VIEW(it), &(it->content_objs));
5531    EINA_LIST_FREE(GL_IT(it)->flip_content_objs, c)
5532      evas_object_del(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));
5535
5536    _view_inflate(VIEW(it), it, &(it->content_objs));
5537    if (it->flipped)
5538      {
5539         _item_content_realize(it, VIEW(it), &(GL_IT(it)->flip_content_objs),
5540                                "flips", NULL);
5541         edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
5542      }
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));
5547
5548    if (!TIZEN_PROFILE_WEARABLE)
5549      _banded_item_bg_add(it, VIEW(it));
5550
5551    if (it->selected)
5552       evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, EO_OBJ(it));
5553
5554    if (GL_IT(it)->wsd->aligned_item == it)
5555      edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
5556
5557    edje_object_message_signal_process(VIEW(it));
5558 }
5559
5560 static void
5561 _item_block_calc(Item_Block *itb, Evas_Coord vw EINA_UNUSED, Evas_Coord vh)
5562 {
5563    const Eina_List *l;
5564    Elm_Gen_Item *it;
5565    Evas_Coord minw = 9999999, minh = 0;
5566    int sum_item_height = 0;
5567    ELM_WIDGET_DATA_GET_OR_RETURN(itb->sd->obj, wsd);
5568
5569    if (itb->calc_done) return;
5570
5571    EINA_LIST_FOREACH(itb->items, l, it)
5572      {
5573         if (it->want_hidden) continue;
5574         if (GL_IT(it)->updateme)
5575           {
5576              if (it->realized)
5577                {
5578                   _item_update(it);
5579                }
5580              GL_IT(it)->calc_done = EINA_FALSE;
5581              GL_IT(it)->updateme = EINA_FALSE;
5582           }
5583         if (!GL_IT(it)->queued) _item_calc(it);
5584
5585         if (wsd->scroll_item_align_enable)
5586           {
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))
5591                {
5592                   int first_item_height = sum_item_height = vcenter - icenter;
5593
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);
5596
5597                   if (prev)
5598                     minh = sum_item_height;
5599                   while (prev)
5600                     {
5601                        if (eo_prev == elm_genlist_first_item_get(wsd->obj))
5602                          {
5603                             GL_IT(prev)->h = GL_IT(prev)->minh = first_item_height;
5604                             break;
5605                          }
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);
5610                     }
5611                }
5612              sum_item_height += GL_IT(it)->h;
5613           }
5614
5615         it->x = 0;
5616         it->y = minh;
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)
5620           {
5621              itb->sd->comp_y += GL_IT(it)->minh;
5622              GL_IT(it)->is_prepend = EINA_FALSE;
5623           }
5624      }
5625    itb->minw = minw;
5626    itb->minh = minh;
5627    itb->calc_done = EINA_TRUE;
5628    itb->position_update = EINA_FALSE;
5629 }
5630
5631 static void
5632 _scroll_animate_start_cb(Evas_Object *obj,
5633                          void *data EINA_UNUSED)
5634 {
5635    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5636    evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
5637 }
5638
5639 static void
5640 _scroll_animate_stop_cb(Evas_Object *obj,
5641                         void *data EINA_UNUSED)
5642 {
5643    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5644    evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
5645
5646    //TIZEN_ONLY: Let the screen-reader know when scroll animation ends
5647    if (_elm_atspi_enabled())
5648      {
5649         elm_interface_atspi_accessible_visible_data_changed_signal_emit(obj);
5650      }
5651    //
5652 }
5653
5654 static void
5655 _scroll_drag_start_cb(Evas_Object *obj,
5656                       void *data EINA_UNUSED)
5657 {
5658    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
5659    evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
5660 }
5661
5662 static Eina_Bool
5663 _scroll_timeout_cb(void *data)
5664 {
5665    Elm_Genlist_Data *sd = data;
5666
5667    sd->scr_timer = NULL;
5668    if (sd->queue && !sd->queue_idle_enterer)
5669      {
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);
5673      }
5674    return ECORE_CALLBACK_CANCEL;
5675 }
5676
5677 static void
5678 _scroll_cb(Evas_Object *obj,
5679            void *data EINA_UNUSED)
5680 {
5681    ELM_GENLIST_DATA_GET(obj, sd);
5682
5683    if (sd->queue_idle_enterer)
5684      {
5685         ecore_idle_enterer_del(sd->queue_idle_enterer);
5686         sd->queue_idle_enterer = NULL;
5687         if (sd->dummy_job)
5688           {
5689              ecore_job_del(sd->dummy_job);
5690              sd->dummy_job = NULL;
5691           }
5692      }
5693    if (sd->scr_timer) ecore_timer_del(sd->scr_timer);
5694    sd->scr_timer = ecore_timer_add(0.25, _scroll_timeout_cb, sd);
5695
5696    evas_object_smart_callback_call(obj, SIG_SCROLL, NULL);
5697 }
5698
5699 static void
5700 _scroll_drag_stop_cb(Evas_Object *obj,
5701                      void *data EINA_UNUSED)
5702 {
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())
5706      {
5707         elm_interface_atspi_accessible_visible_data_changed_signal_emit(obj);
5708      }
5709    //
5710 }
5711
5712 static void
5713 _edge_left_cb(Evas_Object *obj,
5714               void *data EINA_UNUSED)
5715 {
5716    evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
5717 }
5718
5719 static void
5720 _edge_right_cb(Evas_Object *obj,
5721                void *data EINA_UNUSED)
5722 {
5723    evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
5724 }
5725
5726 static void
5727 _edge_top_cb(Evas_Object *obj,
5728              void *data EINA_UNUSED)
5729 {
5730    evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
5731 }
5732
5733 static void
5734 _edge_bottom_cb(Evas_Object *obj,
5735                 void *data EINA_UNUSED)
5736 {
5737    evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
5738 }
5739
5740 static void
5741 _vbar_drag_cb(Evas_Object *obj,
5742                 void *data EINA_UNUSED)
5743 {
5744    evas_object_smart_callback_call(obj, SIG_VBAR_DRAG, NULL);
5745 }
5746
5747 static void
5748 _vbar_press_cb(Evas_Object *obj,
5749                 void *data EINA_UNUSED)
5750 {
5751    evas_object_smart_callback_call(obj, SIG_VBAR_PRESS, NULL);
5752 }
5753
5754 static void
5755 _vbar_unpress_cb(Evas_Object *obj,
5756                 void *data EINA_UNUSED)
5757 {
5758    evas_object_smart_callback_call(obj, SIG_VBAR_UNPRESS, NULL);
5759 }
5760
5761 static void
5762 _hbar_drag_cb(Evas_Object *obj,
5763                 void *data EINA_UNUSED)
5764 {
5765    evas_object_smart_callback_call(obj, SIG_HBAR_DRAG, NULL);
5766 }
5767
5768 static void
5769 _hbar_press_cb(Evas_Object *obj,
5770                 void *data EINA_UNUSED)
5771 {
5772    evas_object_smart_callback_call(obj, SIG_HBAR_PRESS, NULL);
5773 }
5774
5775 static void
5776 _hbar_unpress_cb(Evas_Object *obj,
5777                 void *data EINA_UNUSED)
5778 {
5779    evas_object_smart_callback_call(obj, SIG_HBAR_UNPRESS, NULL);
5780 }
5781
5782 static void
5783 _decorate_item_realize(Elm_Gen_Item *it)
5784 {
5785    char buf[1024];
5786    if (GL_IT(it)->deco_it_view || !it->itc->decorate_item_style) return;
5787
5788    // Before adding & swallowing, delete it from smart member
5789    evas_object_smart_member_del(VIEW(it));
5790
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));
5796
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");
5801
5802    _item_mouse_callbacks_add(it, GL_IT(it)->deco_it_view);
5803    // Redwood Only
5804    _item_mouse_callbacks_del(it, VIEW(it));
5805 }
5806
5807 #if 0
5808 // FIXME: difference from upstream
5809 static void
5810 _mouse_down_scroller(void        *data,
5811                      Evas        *evas EINA_UNUSED,
5812                      Evas_Object *obj EINA_UNUSED,
5813                      void        *event_info EINA_UNUSED)
5814 {
5815    Widget_Data *wd = elm_widget_data_get(data);
5816
5817    if (!wd) return;
5818    wd->drag_started = EINA_FALSE;
5819 }
5820
5821 static void
5822 _mouse_up_scroller(void        *data,
5823                    Evas        *evas EINA_UNUSED,
5824                    Evas_Object *obj EINA_UNUSED,
5825                    void        *event_info EINA_UNUSED)
5826 {
5827    Widget_Data *wd = elm_widget_data_get(data);
5828
5829    if (!wd) return;
5830    wd->drag_started = EINA_FALSE;
5831 }
5832
5833 static void
5834 _mouse_move_scroller(void        *data,
5835                      Evas        *evas EINA_UNUSED,
5836                      Evas_Object *obj EINA_UNUSED,
5837                      void        *event_info)
5838 {
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;
5842
5843    if (!wd) return;
5844    if (wd->drag_started) return;
5845
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;
5849    adx = dx;
5850    ady = dy;
5851    if (adx < 0) adx = -dx;
5852    if (ady < 0) ady = -dy;
5853    if (((ady < minh) && (ady > minh / 2)) && (ady > adx))
5854      {
5855         if (dy < 0)
5856           {
5857              evas_object_smart_callback_call(data, SIG_DRAG_START_UP, NULL);
5858              wd->drag_started = EINA_TRUE;
5859           }
5860         else
5861           {
5862              evas_object_smart_callback_call(data, SIG_DRAG_START_DOWN, NULL);
5863              wd->drag_started = EINA_TRUE;
5864           }
5865      }
5866 }
5867 #endif
5868
5869 static void
5870 _size_cache_free(void *data)
5871 {
5872    if (data) free(data);
5873 }
5874
5875 static Evas_Event_Flags
5876 _pinch_zoom_start_cb(void *data, void *event_info)
5877 {
5878    Elm_Genlist_Data *sd = data;
5879    Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
5880    Elm_Object_Item *eo_it;
5881
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;
5885 }
5886
5887 static Evas_Event_Flags
5888 _pinch_zoom_cb(void *data, void *event_info)
5889 {
5890    Elm_Genlist_Data *sd = data;
5891    Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
5892
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;
5897
5898    return EVAS_EVENT_FLAG_NONE;
5899 }
5900
5901 static Evas_Event_Flags
5902 _gesture_n_lines_start_cb(void *data , void *event_info)
5903 {
5904    Elm_Genlist_Data *sd = data;
5905    Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5906    Evas_Coord x,y;
5907    Elm_Object_Item *eo_it;
5908
5909    x = (p->momentum.x1 + p->momentum.x2) / 2;
5910    y = (p->momentum.y1 + p->momentum.y2) / 2;
5911
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;
5915 }
5916
5917 static Evas_Event_Flags
5918 _gesture_n_lines_cb(void *data , void *event_info)
5919 {
5920    Elm_Genlist_Data *sd = data;
5921    Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5922
5923    if (p->momentum.n < 2)
5924      return EVAS_EVENT_FLAG_NONE;
5925
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;
5931
5932    minw = sd->finger_minw;
5933    minh = sd->finger_minh;
5934
5935    prev_x = prev_y = 0;
5936
5937    cur_x = p->momentum.x1;
5938    cur_y = p->momentum.y1;
5939
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);
5942    if (down_it)
5943      {
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;
5947
5948         off_x = abs(cur_x - prev_x);
5949         off_y = abs(cur_y - prev_y);
5950
5951         if ((off_x > minw) || (off_y > minh))
5952           {
5953              if (off_x > off_y)
5954                {
5955                   if (cur_x > prev_x)
5956                     sd->g_type = SIG_MULTI_SWIPE_RIGHT;
5957                   else
5958                     sd->g_type = SIG_MULTI_SWIPE_LEFT;
5959                }
5960              else
5961                {
5962                   if (cur_y > prev_y)
5963                     sd->g_type = SIG_MULTI_SWIPE_DOWN;
5964                   else
5965                     sd->g_type = SIG_MULTI_SWIPE_UP;
5966                }
5967           }
5968      }
5969    return EVAS_EVENT_FLAG_NONE;
5970 }
5971
5972 static Evas_Event_Flags
5973 _gesture_n_flicks_cb(void *data , void *event_info)
5974 {
5975    Elm_Genlist_Data *sd = data;
5976    Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info;
5977
5978    if (p->momentum.n == 1)
5979       sd->g_type = SIG_SWIPE;
5980
5981    return EVAS_EVENT_FLAG_NONE;
5982 }
5983
5984 EOLIAN static void
5985 _elm_genlist_evas_object_smart_del(Eo *obj, Elm_Genlist_Data *sd)
5986 {
5987    sd->no_cache = EINA_TRUE;
5988    elm_genlist_clear(obj);
5989    evas_event_callback_del_full(evas_object_evas_get(obj),
5990                                 EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
5991                                 _evas_viewport_resize_cb, sd);
5992    if (sd->size_caches) eina_hash_free(sd->size_caches);
5993    if (sd->decorate_it_type) eina_stringshare_del(sd->decorate_it_type);
5994    if (sd->clipee) evas_object_del(sd->clipee);
5995
5996    evas_object_del(sd->pan_obj);
5997    eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
5998 }
5999
6000 EOLIAN static void
6001 _elm_genlist_evas_object_smart_move(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y)
6002 {
6003    Evas_Coord ox, oy, bg_x, bg_y;
6004
6005    if (!TIZEN_PROFILE_WEARABLE)
6006      {
6007         evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
6008         evas_object_geometry_get(sd->banded_bg_rect, &bg_x, &bg_y, NULL, NULL);
6009      }
6010
6011    eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
6012    evas_object_move(sd->hit_rect, x, y);
6013
6014    if (!TIZEN_PROFILE_WEARABLE)
6015      evas_object_move(sd->banded_bg_rect, (bg_x + x - ox), (bg_y + y - oy));
6016 }
6017
6018 EOLIAN static void
6019 _elm_genlist_evas_object_smart_resize(Eo *obj, Elm_Genlist_Data *sd, Evas_Coord w, Evas_Coord h)
6020 {
6021    eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
6022
6023    evas_object_resize(sd->hit_rect, w, h);
6024 }
6025
6026 EOLIAN static void
6027 _elm_genlist_evas_object_smart_member_add(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *member)
6028 {
6029    eo_do_super(obj, MY_CLASS, evas_obj_smart_member_add(member));
6030
6031    if (sd->hit_rect)
6032      evas_object_raise(sd->hit_rect);
6033 }
6034
6035
6036 EOLIAN static void
6037 _elm_genlist_elm_widget_access(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool acs)
6038 {
6039    Eina_List *l;
6040    Elm_Object_Item *eo_it;
6041
6042    l = elm_genlist_realized_items_get(obj);
6043
6044    EINA_LIST_FREE(l, eo_it)
6045      {
6046         ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6047         _item_unrealize(it, EINA_FALSE);
6048      }
6049
6050   sd->is_access = acs;
6051
6052    _changed(sd->pan_obj);
6053    evas_object_smart_callback_call(obj, SIG_ACCESS_CHANGED, NULL);
6054 }
6055
6056 static void
6057 _evas_viewport_resize_cb(void *d, Evas *e EINA_UNUSED, void *ei EINA_UNUSED)
6058 {
6059    Elm_Genlist_Data *priv = d;
6060    _changed(priv->pan_obj);
6061 }
6062
6063 EOLIAN static void
6064 _elm_genlist_evas_object_smart_add(Eo *obj, Elm_Genlist_Data *priv)
6065 {
6066    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
6067    Evas_Coord minw, minh;
6068    Elm_Genlist_Pan_Data *pan_data;
6069
6070    eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
6071    elm_widget_sub_object_parent_add(obj);
6072
6073    priv->finger_minw = 0;
6074    priv->finger_minh = 0;
6075    elm_coords_finger_size_adjust(1, &priv->finger_minw, 1, &priv->finger_minh);
6076
6077    priv->size_caches = eina_hash_string_small_new(_size_cache_free);
6078    priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
6079    evas_object_smart_member_add(priv->hit_rect, obj);
6080    elm_widget_sub_object_add(obj, priv->hit_rect);
6081
6082    /* common scroller hit rectangle setup */
6083    evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
6084    evas_object_show(priv->hit_rect);
6085    evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
6086
6087    elm_widget_can_focus_set(obj, EINA_TRUE);
6088    elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj);
6089
6090    elm_layout_theme_set(obj, "genlist", "base", elm_widget_style_get(obj));
6091
6092    if (!TIZEN_PROFILE_WEARABLE)
6093      _banded_bg_state_check(obj, priv);
6094
6095    /* interface's add() routine issued AFTER the object's smart_add() */
6096    eo_do(obj, elm_interface_scrollable_objects_set(wd->resize_obj, priv->hit_rect));
6097
6098    eo_do(obj, elm_interface_scrollable_bounce_allow_set
6099                (EINA_FALSE, _elm_config->thumbscroll_bounce_enable));
6100    priv->v_bounce = _elm_config->thumbscroll_bounce_enable;
6101
6102    eo_do(obj,
6103          elm_interface_scrollable_animate_start_cb_set(_scroll_animate_start_cb),
6104          elm_interface_scrollable_animate_stop_cb_set(_scroll_animate_stop_cb),
6105          elm_interface_scrollable_scroll_cb_set(_scroll_cb),
6106          elm_interface_scrollable_drag_start_cb_set(_scroll_drag_start_cb),
6107          elm_interface_scrollable_drag_stop_cb_set(_scroll_drag_stop_cb),
6108          elm_interface_scrollable_edge_left_cb_set(_edge_left_cb),
6109          elm_interface_scrollable_edge_right_cb_set(_edge_right_cb),
6110          elm_interface_scrollable_edge_top_cb_set(_edge_top_cb),
6111          elm_interface_scrollable_edge_bottom_cb_set(_edge_bottom_cb),
6112          elm_interface_scrollable_vbar_drag_cb_set(_vbar_drag_cb),
6113          elm_interface_scrollable_vbar_press_cb_set(_vbar_press_cb),
6114          elm_interface_scrollable_vbar_unpress_cb_set(_vbar_unpress_cb),
6115          elm_interface_scrollable_hbar_drag_cb_set(_hbar_drag_cb),
6116          elm_interface_scrollable_hbar_press_cb_set(_hbar_press_cb),
6117          elm_interface_scrollable_hbar_unpress_cb_set(_hbar_unpress_cb));
6118
6119    eo_do(obj, elm_interface_scrollable_content_min_limit_cb_set(_elm_genlist_content_min_limit_cb));
6120
6121    priv->mode = ELM_LIST_SCROLL;
6122    priv->max_items_per_block = MAX_ITEMS_PER_BLOCK;
6123    priv->item_cache_max = priv->max_items_per_block * 2;
6124    priv->longpress_timeout = _elm_config->longpress_timeout;
6125    priv->highlight = EINA_TRUE;
6126    priv->fx_mode = EINA_FALSE;
6127    priv->on_hold = EINA_FALSE;
6128
6129    //Kiran only
6130    if (!TIZEN_PROFILE_WEARABLE)
6131      priv->top_drawn_item = NULL;
6132
6133    priv->pan_obj = eo_add(MY_PAN_CLASS, evas_object_evas_get(obj));
6134    pan_data = eo_data_scope_get(priv->pan_obj, MY_PAN_CLASS);
6135    eo_data_ref(obj, NULL);
6136    //check this
6137    pan_data->wobj = obj;
6138    //
6139    pan_data->wsd = priv;
6140
6141 #if 0
6142    // FIXME: difference from upstream
6143    evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_DOWN,
6144                                   _mouse_down_scroller, obj);
6145    evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_UP,
6146                                   _mouse_up_scroller, obj);
6147    evas_object_event_callback_add(pan_obj, EVAS_CALLBACK_MOUSE_MOVE,
6148                                   _mouse_move_scroller, obj);
6149 #endif
6150
6151    eo_do(obj, elm_interface_scrollable_extern_pan_set(priv->pan_obj));
6152
6153    edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
6154    evas_object_size_hint_min_set(obj, minw, minh);
6155
6156    _item_cache_all_free(priv);
6157    _mirrored_set(obj, elm_widget_mirrored_get(obj));
6158
6159    const char *str = edje_object_data_get(wd->resize_obj,
6160                                           "focus_highlight");
6161    if ((str) && (!strcmp(str, "on")))
6162       elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
6163    else
6164       elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
6165    priv->select_on_focus_enabled = EINA_FALSE;
6166    elm_widget_signal_callback_add(obj, "elm,action,focus_highlight,hide", "elm", _elm_genlist_focus_highlight_hide, obj);
6167    elm_widget_signal_callback_add(obj, "elm,action,focus_highlight,show", "elm", _elm_genlist_focus_highlight_show, obj);
6168    evas_event_callback_add(evas_object_evas_get(obj),
6169                            EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
6170                            _evas_viewport_resize_cb, priv);
6171
6172    priv->g_layer = elm_gesture_layer_add(obj);
6173    if (!priv->g_layer) ERR("elm_gesture_layer_add() failed");
6174    elm_gesture_layer_attach(priv->g_layer, priv->hit_rect);
6175    elm_gesture_layer_cb_set
6176       (priv->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_START,
6177        _pinch_zoom_start_cb, priv);
6178    elm_gesture_layer_cb_set
6179       (priv->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE,
6180        _pinch_zoom_cb, priv);
6181
6182    elm_gesture_layer_cb_set
6183       (priv->g_layer, ELM_GESTURE_N_LINES, ELM_GESTURE_STATE_START,
6184        _gesture_n_lines_start_cb, priv);
6185    elm_gesture_layer_cb_set
6186       (priv->g_layer, ELM_GESTURE_N_LINES, ELM_GESTURE_STATE_MOVE,
6187        _gesture_n_lines_cb, priv);
6188
6189    elm_gesture_layer_cb_set
6190       (priv->g_layer, ELM_GESTURE_N_FLICKS, ELM_GESTURE_STATE_START,
6191        _gesture_n_lines_start_cb, priv);
6192    elm_gesture_layer_cb_set
6193       (priv->g_layer, ELM_GESTURE_N_FLICKS, ELM_GESTURE_STATE_MOVE,
6194        _gesture_n_flicks_cb, priv);
6195
6196    elm_layout_sizing_eval(obj);
6197
6198 // TIZEN_ONLY(20150705): Genlist item align feature
6199    wd->scroll_item_align_enable = _elm_config->scroll_item_align_enable;
6200    wd->scroll_item_valign = _elm_config->scroll_item_valign;
6201 //
6202    eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
6203                (NULL, NULL, &priv->viewport_w, &priv->viewport_h));
6204 }
6205
6206 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
6207 //register/unregister access objects accordingly.
6208 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6209 EOLIAN static void
6210 _elm_genlist_elm_widget_screen_reader(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool is_screen_reader)
6211 {
6212    Item_Block *itb;
6213    Eina_Bool done = EINA_FALSE;
6214    Evas_Object *content = NULL;
6215    Eina_List *l, *ll;
6216    Elm_Gen_Item *it;
6217
6218    EINA_INLIST_FOREACH(sd->blocks, itb)
6219      {
6220         if (itb->realized)
6221           {
6222              done = EINA_TRUE;
6223              EINA_LIST_FOREACH(itb->items, l, it)
6224                {
6225                   if (!it->realized || it->want_hidden) continue;
6226                   if (is_screen_reader)
6227                     {
6228                        elm_interface_atspi_accessible_added(EO_OBJ(it));
6229                        elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
6230                        EINA_LIST_FOREACH(it->content_objs, ll, content)
6231                          {
6232                             if (eo_isa(content, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
6233                               {
6234                                  eo_do(content, elm_interface_atspi_accessible_parent_set(EO_OBJ(it)));
6235                                  elm_interface_atspi_accessible_children_changed_added_signal_emit(EO_OBJ(it), content);
6236                               }
6237                          }
6238                        elm_interface_atspi_accessible_name_changed_signal_emit(EO_OBJ(it));
6239                     }
6240                   else
6241                     {
6242                        elm_interface_atspi_accessible_removed(EO_OBJ(it));
6243                        elm_interface_atspi_accessible_children_changed_del_signal_emit(sd->obj, EO_OBJ(it));
6244                     }
6245                }
6246           }
6247         else if (done) break;
6248      }
6249
6250    //TIZEN_ONLY(20161213): apply screen_reader_changed callback
6251    evas_object_smart_callback_call(obj, SIG_ATSPI_SCREEN_READER_CHANGED, &is_screen_reader);
6252    //
6253 }
6254 //
6255 //
6256
6257 EOLIAN const Elm_Atspi_Action *
6258 _elm_genlist_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd EINA_UNUSED)
6259 {
6260 /* Need to be implemented
6261    static Elm_Atspi_Action atspi_actions[] = {
6262           { "move,prior", "move", "prior", _key_action_move},
6263           { "move,next", "move", "next", _key_action_move},
6264           { "move,left", "move", "left", _key_action_move},
6265           { "move,right", "move", "right", _key_action_move},
6266           { "move,up", "move", "up", _key_action_move},
6267           { "move,up,multi", "move", "up_multi", _key_action_move},
6268           { "move,down", "move", "down", _key_action_move},
6269           { "move,down,multi", "move", "down_multi", _key_action_move},
6270           { "move,first", "move", "first", _key_action_move},
6271           { "move,last", "move", "last", _key_action_move},
6272           { "select", "select", NULL, _key_action_select},
6273           { "select,multi", "select", "multi", _key_action_select},
6274           { "escape", "escape", NULL, _key_action_escape},
6275           { NULL, NULL, NULL, NULL }
6276    };
6277    return &atspi_actions[0];
6278 */
6279    static Elm_Atspi_Action atspi_actions[] = {{NULL, NULL, NULL, NULL}};
6280    return &atspi_actions[0];
6281 }
6282
6283 EAPI Evas_Object *
6284 elm_genlist_add(Evas_Object *parent)
6285 {
6286    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
6287    Evas_Object *obj = eo_add(MY_CLASS, parent);
6288    return obj;
6289 }
6290
6291 EOLIAN static Eo *
6292 _elm_genlist_eo_base_constructor(Eo *obj, Elm_Genlist_Data *sd)
6293 {
6294    obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
6295    sd->obj = obj;
6296
6297    eo_do(obj,
6298          evas_obj_type_set(MY_CLASS_NAME_LEGACY),
6299          evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
6300          elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST));
6301    return obj;
6302 }
6303
6304
6305 EOLIAN static Evas_Object *
6306 _elm_genlist_item_elm_widget_item_part_content_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6307 {
6308    Evas_Object *ret = NULL;
6309    if (it->deco_all_view)
6310      ret = edje_object_part_swallow_get(it->deco_all_view, part);
6311    else if (it->decorate_it_set)
6312      ret = edje_object_part_swallow_get(GL_IT(it)->deco_it_view, part);
6313    if (!ret)
6314      ret = edje_object_part_swallow_get(VIEW(it), part);
6315    return ret;
6316 }
6317
6318 EOLIAN static const char *
6319 _elm_genlist_item_elm_widget_item_part_text_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char * part)
6320 {
6321    if (!it->itc->func.text_get) return NULL;
6322    const char *ret = NULL;
6323    if (it->deco_all_view)
6324      ret = edje_object_part_text_get(it->deco_all_view, part);
6325    else if (it->decorate_it_set)
6326      ret = edje_object_part_text_get(GL_IT(it)->deco_it_view, part);
6327    if (!ret)
6328      ret = edje_object_part_text_get(VIEW(it), part);
6329    return ret;
6330 }
6331
6332 EOLIAN static void
6333 _elm_genlist_item_elm_widget_item_disable(Eo *eo_it, Elm_Gen_Item *it)
6334 {
6335    Eina_List *l;
6336    Evas_Object *obj;
6337    Eina_Bool ret;
6338
6339    _item_unselect(it);
6340    if (it == GL_IT(it)->wsd->focused_item) elm_object_item_focus_set(EO_OBJ(it), EINA_FALSE);
6341    if (GL_IT(it)->highlight_timer)
6342      {
6343         ecore_timer_del(GL_IT(it)->highlight_timer);
6344         GL_IT(it)->highlight_timer = NULL;
6345      }
6346    if (it->long_timer)
6347      {
6348         ecore_timer_del(it->long_timer);
6349         it->long_timer = NULL;
6350      }
6351
6352    if (it->realized)
6353      {
6354         if (eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get()))
6355           {
6356              edje_object_signal_emit(VIEW(it), SIGNAL_DISABLED, "elm");
6357              if (it->deco_all_view)
6358                edje_object_signal_emit
6359                  (it->deco_all_view, SIGNAL_DISABLED, "elm");
6360           }
6361         else
6362           {
6363              edje_object_signal_emit(VIEW(it), SIGNAL_ENABLED, "elm");
6364              if (it->deco_all_view)
6365                edje_object_signal_emit
6366                  (it->deco_all_view, SIGNAL_ENABLED, "elm");
6367           }
6368         EINA_LIST_FOREACH(it->content_objs, l, obj)
6369           elm_widget_disabled_set(obj, eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get()));
6370      }
6371 }
6372
6373 static void
6374 _item_free(Elm_Gen_Item *it)
6375 {
6376    Eina_List *l, *ll;
6377    Elm_Object_Item *eo_it2;
6378    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
6379    sd->processed_sizes -= GL_IT(it)->minh;
6380    if (sd->processed_sizes < 0) sd->processed_sizes = 0;
6381
6382    eo_do(EO_OBJ(it), elm_wdg_item_pre_notify_del());
6383    if (it->tooltip.del_cb)
6384      it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
6385
6386 #ifdef GENLIST_FX_SUPPORT
6387    sd->del_fx.items = eina_list_remove(sd->del_fx.items, it);
6388    sd->del_fx.pending_items = eina_list_remove(sd->del_fx.pending_items, it);
6389    sd->add_fx.items = eina_list_remove(sd->add_fx.items, it);
6390 #endif
6391
6392    if (GL_IT(it)->rel)
6393      GL_IT(it)->rel->item->rel_revs =
6394         eina_list_remove(GL_IT(it)->rel->item->rel_revs, it);
6395    if (GL_IT(it)->rel_revs)
6396      {
6397         Elm_Gen_Item *tmp;
6398         EINA_LIST_FREE(GL_IT(it)->rel_revs, tmp)
6399           {
6400              if (tmp->item->queued && !(tmp->base)->on_deletion)
6401                {
6402                   GL_IT(tmp)->queued = EINA_FALSE;
6403                   GL_IT(tmp)->resized = EINA_FALSE;
6404                   sd->queue = eina_list_remove(sd->queue, tmp);
6405                   _item_process(sd, tmp);
6406                }
6407              tmp->item->rel = NULL;
6408           }
6409      }
6410    EINA_LIST_FOREACH_SAFE(it->item->items, l, ll, eo_it2)
6411      {
6412         //elm_widget_item_del(it2);
6413         ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6414         _item_free(it2);
6415      }
6416    sd->reorder.move_items = eina_list_remove(sd->reorder.move_items, it);
6417
6418    if (GL_IT(it)->block) _item_block_del(it);
6419    if (it->parent)
6420      it->parent->item->items =
6421         eina_list_remove(it->parent->item->items, EO_OBJ(it));
6422    if (GL_IT(it)->queued)
6423      {
6424         GL_IT(it)->queued = EINA_FALSE;
6425         sd->queue = eina_list_remove(sd->queue, it);
6426      }
6427    if (sd->filter_queue && !it->filtered)
6428      {
6429         l = eina_list_data_find_list(sd->filter_queue, it);
6430         if (l) sd->filter_queue = eina_list_remove_list(sd->filter_queue, l);
6431      }
6432    if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6433       sd->group_items = eina_list_remove(sd->group_items, it);
6434
6435    if (it->selected)
6436       {
6437          sd->selected = eina_list_remove(sd->selected, EO_OBJ(it));
6438          it->selected = EINA_FALSE;
6439       }
6440    if (sd->show_item == it) sd->show_item = NULL;
6441
6442    if ((sd->g_item) && (sd->g_item == it)) sd->g_item = NULL;
6443    if (sd->expanded_item == it) sd->expanded_item = NULL;
6444    if (sd->state) ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
6445
6446    if (sd->last_selected_item == EO_OBJ(it))
6447      sd->last_selected_item = NULL;
6448
6449    if (sd->realization_mode)
6450      {
6451         Evas_Object *c;
6452         EINA_LIST_FOREACH(GL_IT(it)->flip_content_objs, l, c)
6453           {
6454              evas_object_event_callback_del_full(c,
6455                                                  EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6456                                                  _changed_size_hints, it);
6457           }
6458         EINA_LIST_FOREACH(GL_IT(it)->deco_all_contents, l, c)
6459           {
6460              evas_object_event_callback_del_full(c,
6461                                                  EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6462                                                  _changed_size_hints, it);
6463           }
6464         EINA_LIST_FOREACH(it->content_objs, l, c)
6465           {
6466              evas_object_event_callback_del_full(c,
6467                                                  EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6468                                                  _changed_size_hints, it);
6469           }
6470      }
6471
6472    if (sd->mode_item) sd->mode_item = NULL;
6473    if (it->selected) _item_unselect(it);
6474    if (it == sd->focused_item)
6475      {
6476         Elm_Gen_Item *tmp;
6477         Eina_Bool find;
6478         if (!elm_widget_focus_get(WIDGET(it))) goto failed;
6479
6480         tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
6481         find = _item_focusable_search(&tmp, 1);
6482         if (find)
6483           {
6484              elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
6485              goto end;
6486           }
6487         else
6488           {
6489              tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
6490              find = _item_focusable_search(&tmp, -1);
6491              if (find)
6492                {
6493                   elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
6494                   goto end;
6495                }
6496           }
6497 failed:
6498         elm_object_item_focus_set(EO_OBJ(it), EINA_FALSE);
6499         sd->focused_item = NULL;
6500      }
6501 end:
6502    if (it == sd->key_down_item) sd->key_down_item = NULL;
6503    if (it == sd->highlighted_item) sd->highlighted_item = NULL;
6504    if (!TIZEN_PROFILE_WEARABLE)
6505      {
6506         if (it == sd->top_drawn_item) sd->top_drawn_item = NULL;
6507      }
6508
6509    _item_unrealize(it, EINA_FALSE);
6510
6511    if (sd->aligned_item == it) sd->aligned_item = NULL;
6512
6513    sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
6514    sd->item_count--;
6515
6516    if (it->item->proxy)
6517      {
6518         evas_object_smart_member_del(it->item->proxy);
6519         evas_object_del(it->item->proxy);
6520      }
6521
6522    if (it->itc->func.del)
6523      it->itc->func.del((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it));
6524
6525    if (it->itc->refcount <= 1)
6526      {
6527         Eina_Inlist *l2;
6528         Item_Cache *ic;
6529         EINA_INLIST_FOREACH_SAFE(sd->item_cache, l2, ic)
6530           {
6531              if (it->itc == ic->item_class)
6532                _item_cache_free(sd, ic);
6533           }
6534      }
6535
6536    elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc);
6537    free(GL_IT(it));
6538    GL_IT(it) = NULL;
6539    eo_del(EO_OBJ(it));
6540
6541 // TIZEN_ONLY(20150703) : banded color background feature. enabled only un-scrollable
6542    if (!TIZEN_PROFILE_WEARABLE)
6543      {
6544         if (sd->banded_bg_rect && !sd->items)
6545           {
6546              evas_object_smart_member_del(sd->banded_bg_rect);
6547              ELM_SAFE_FREE(sd->banded_bg_rect, evas_object_del);
6548           }
6549      }
6550
6551    _changed(sd->pan_obj);
6552 }
6553
6554 EOLIAN static Eina_Bool
6555 _elm_genlist_item_elm_widget_item_del_pre(Eo *eo_it EINA_UNUSED,
6556                                           Elm_Gen_Item *it)
6557 {
6558 #ifdef GENLIST_FX_SUPPORT
6559    Elm_Genlist_Data *sd = it->item->wsd;
6560    Evas_Coord cvx, cvy, cvw, cvh;
6561
6562    if (!sd->fx_mode)
6563      {
6564 #endif
6565         _item_free(it);
6566         return EINA_FALSE;
6567 #ifdef GENLIST_FX_SUPPORT
6568      }
6569
6570    sd->add_fx.items = eina_list_remove(sd->add_fx.items, it);
6571
6572    // Support FX Mode
6573    evas_output_viewport_get(evas_object_evas_get(sd->obj),
6574                             &cvx, &cvy, &cvw, &cvh);
6575    if (!ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
6576                            GL_IT(it)->w, GL_IT(it)->h,
6577                            cvx, cvy, cvw, cvh))
6578      {
6579         // Delete later, Above items in the viewport
6580         // Delete right now, below items in the viewport
6581         if (it->item->scrl_y < cvy)
6582            sd->del_fx.pending_items = eina_list_append(sd->del_fx.pending_items, it);
6583         else
6584           {
6585              _item_free(it);
6586              _changed(sd->pan_obj);
6587              return EINA_FALSE;
6588           }
6589      }
6590    else
6591      {
6592         if (it->deco_all_view) evas_object_lower(it->deco_all_view);
6593         else if (it->item->deco_it_view) evas_object_lower(it->item->deco_it_view);
6594         else if (VIEW(it)) evas_object_lower(VIEW(it));
6595
6596         if (it->item->expanded_depth > 0)
6597           {
6598              Eina_List *l;
6599              Elm_Object_Item *itt;
6600              EINA_LIST_FOREACH(it->item->items, l, itt)
6601                {
6602                   eo_do(itt, elm_wdg_item_del());
6603                }
6604           }
6605         sd->del_fx.items = eina_list_append(sd->del_fx.items, it);
6606      }
6607    if (!sd->del_fx.anim)
6608      {
6609         sd->del_fx.cnt = ANIM_CNT_MAX;
6610         sd->del_fx.anim = ecore_animator_add(_del_fx_anim, sd);
6611      }
6612    _changed(sd->pan_obj);
6613    return EINA_FALSE;
6614 #endif
6615 }
6616
6617 EOLIAN static void
6618 _elm_genlist_item_elm_widget_item_signal_emit(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, const char *emission, const char *source)
6619 {
6620    if (!it->realized)
6621      {
6622         WRN("item is not realized yet");
6623         return;
6624      }
6625    edje_object_signal_emit
6626       (VIEW(it), emission, source);
6627    if (it->deco_all_view)
6628      edje_object_signal_emit
6629        (it->deco_all_view, emission, source);
6630 }
6631
6632 EOLIAN static Eo *
6633 _elm_genlist_item_eo_base_constructor(Eo *eo_it, Elm_Gen_Item *it)
6634 {
6635    eo_it = eo_do_super_ret(eo_it, ELM_GENLIST_ITEM_CLASS, eo_it, eo_constructor());
6636
6637    it->base = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
6638    eo_do(eo_it, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST_ITEM));
6639    return eo_it;
6640 }
6641
6642 static Elm_Gen_Item *
6643 _elm_genlist_item_new(Elm_Genlist_Data *sd,
6644                       const Elm_Genlist_Item_Class *itc,
6645                       const void *data,
6646                       Elm_Object_Item *eo_parent,
6647                       Elm_Genlist_Item_Type type,
6648                       Evas_Smart_Cb func,
6649                       const void *func_data)
6650 {
6651    Elm_Gen_Item *it2;
6652    int depth = 0;
6653
6654    if (!itc) return NULL;
6655
6656    Eo *eo_it = eo_add(ELM_GENLIST_ITEM_CLASS, sd->obj);
6657    if (!eo_it) return NULL;
6658    ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
6659
6660    it->itc = itc;
6661    elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
6662
6663    ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6664    WIDGET_ITEM_DATA_SET(EO_OBJ(it), data);
6665    it->parent = parent;
6666    it->func.func = func;
6667    it->func.data = func_data;
6668
6669    GL_IT(it) = ELM_NEW(Elm_Gen_Item_Type);
6670    GL_IT(it)->wsd = sd;
6671    GL_IT(it)->type = type;
6672
6673    if (it->parent)
6674      {
6675         if (GL_IT(it->parent)->type == ELM_GENLIST_ITEM_GROUP)
6676           GL_IT(it)->group_item = parent;
6677         else if (GL_IT(it->parent)->group_item)
6678           GL_IT(it)->group_item = GL_IT(it->parent)->group_item;
6679      }
6680    for (it2 = it, depth = 0; it2->parent; it2 = it2->parent)
6681      {
6682         if (GL_IT(it2->parent)->type == ELM_GENLIST_ITEM_TREE) depth += 1;
6683      }
6684    GL_IT(it)->expanded_depth = depth;
6685    sd->item_count++;
6686
6687    return it;
6688 }
6689
6690 static int
6691 _elm_genlist_item_compare(const void *data,
6692                           const void *data1)
6693 {
6694    const Elm_Gen_Item *it, *item1;
6695
6696    it = ELM_GEN_ITEM_FROM_INLIST(data);
6697    item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
6698    return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6699 }
6700
6701 static int
6702 _elm_genlist_item_list_compare(const void *data,
6703                                const void *data1)
6704 {
6705    const Elm_Gen_Item *it = data;
6706    const Elm_Gen_Item *item1 = data1;
6707
6708    return GL_IT(it)->wsd->item_compare_cb(EO_OBJ(it), EO_OBJ(item1));
6709 }
6710
6711 EOLIAN static unsigned int
6712 _elm_genlist_items_count(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
6713 {
6714    return sd->item_count;
6715 }
6716
6717 static Eina_List *
6718 _list_last_recursive(Eina_List *list)
6719 {
6720    Eina_List *ll, *ll2;
6721    Elm_Object_Item *eo_it2;
6722
6723    ll = eina_list_last(list);
6724    if (!ll) return NULL;
6725
6726    eo_it2 = ll->data;
6727    ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6728
6729    if (it2->item->items)
6730      {
6731         ll2 = _list_last_recursive(it2->item->items);
6732         if (ll2)
6733           {
6734              return ll2;
6735           }
6736      }
6737
6738    return ll;
6739 }
6740
6741 EOLIAN static Elm_Object_Item*
6742 _elm_genlist_item_append(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
6743 {
6744    Elm_Gen_Item *it;
6745
6746    EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6747
6748    if (eo_parent)
6749      {
6750         ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6751         ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6752         EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6753      }
6754
6755    it = _elm_genlist_item_new
6756        (sd, itc, data, eo_parent, type, func, func_data);
6757    if (!it) return NULL;
6758
6759    if (!it->parent)
6760      {
6761         if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6762           sd->group_items = eina_list_append(sd->group_items, it);
6763         sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
6764         GL_IT(it)->rel = NULL;
6765      }
6766    else
6767      {
6768         Elm_Object_Item *eo_it2 = NULL;
6769         Eina_List *ll = _list_last_recursive(it->parent->item->items);
6770
6771         if (ll) eo_it2 = ll->data;
6772         it->parent->item->items =
6773           eina_list_append(it->parent->item->items, EO_OBJ(it));
6774         if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6775         ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6776         sd->items = eina_inlist_append_relative
6777           (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6778         GL_IT(it)->rel = it2;
6779         it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6780      }
6781    GL_IT(it)->before = EINA_FALSE;
6782    _item_queue_direct(it, NULL);
6783    return EO_OBJ(it);
6784 }
6785
6786 EOLIAN static Elm_Object_Item*
6787 _elm_genlist_item_prepend(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
6788 {
6789    Elm_Gen_Item *it = NULL;
6790
6791    EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
6792    if (eo_parent)
6793      {
6794         ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6795         ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6796         EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6797         /* first sub-item should allways be appended */
6798         if (!parent->item->items)
6799           return _elm_genlist_item_append(obj, sd, itc, data, eo_parent, type, func, func_data);
6800      }
6801    it = _elm_genlist_item_new
6802        (sd, itc, data, eo_parent, type, func, func_data);
6803
6804    if (!it) return NULL;
6805
6806    if (sd->items) GL_IT(it)->is_prepend = EINA_TRUE;
6807    if (!it->parent)
6808      {
6809         if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6810           sd->group_items = eina_list_prepend(sd->group_items, it);
6811         sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
6812         GL_IT(it)->rel = NULL;
6813      }
6814    else
6815      {
6816         Elm_Object_Item *eo_it2 = NULL;
6817         Eina_List *ll = it->parent->item->items;
6818
6819         if (ll) eo_it2 = ll->data;
6820         it->parent->item->items =
6821           eina_list_prepend(it->parent->item->items, EO_OBJ(it));
6822         if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
6823         ELM_GENLIST_ITEM_DATA_GET(eo_it2, it2);
6824         if (it2)
6825           {
6826              sd->items = eina_inlist_prepend_relative
6827                  (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6828              GL_IT(it)->rel = it2;
6829              it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6830           }
6831      }
6832    GL_IT(it)->before = EINA_TRUE;
6833    _item_queue_direct(it, NULL);
6834    return EO_OBJ(it);
6835 }
6836
6837 EOLIAN static Elm_Object_Item*
6838 _elm_genlist_item_insert_after(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Object_Item *eo_after, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
6839 {
6840    EINA_SAFETY_ON_NULL_RETURN_VAL(eo_after, NULL);
6841    ELM_GENLIST_ITEM_DATA_GET(eo_after, after_it);
6842    Elm_Gen_Item *it;
6843
6844    ELM_GENLIST_ITEM_CHECK_OR_RETURN(after_it, NULL);
6845    EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(after_it), NULL);
6846    if (eo_parent)
6847      {
6848         ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6849         ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6850         EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6851      }
6852
6853    /* It makes no sense to insert after in an empty list with after !=
6854     * NULL, something really bad is happening in your app. */
6855    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6856
6857    it = _elm_genlist_item_new
6858        (sd, itc, data, eo_parent, type, func, func_data);
6859    if (!it) return NULL;
6860
6861    if (!it->parent)
6862      {
6863         if ((GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) &&
6864             (GL_IT(after_it)->type == ELM_GENLIST_ITEM_GROUP))
6865           sd->group_items = eina_list_append_relative
6866               (sd->group_items, it, after_it);
6867      }
6868    else
6869      {
6870         it->parent->item->items =
6871           eina_list_append_relative(it->parent->item->items, EO_OBJ(it), eo_after);
6872      }
6873    sd->items = eina_inlist_append_relative
6874        (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after_it));
6875
6876    GL_IT(it)->rel = after_it;
6877    after_it->item->rel_revs = eina_list_append(after_it->item->rel_revs, it);
6878    GL_IT(it)->before = EINA_FALSE;
6879    _item_queue_direct(it, NULL);
6880
6881    if (elm_genlist_item_next_get(eo_after) == EO_OBJ(sd->aligned_item))
6882      sd->aligned_item = NULL;
6883    return EO_OBJ(it);
6884 }
6885
6886 EOLIAN static Elm_Object_Item*
6887 _elm_genlist_item_insert_before(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Object_Item *eo_before, Elm_Genlist_Item_Type type, Evas_Smart_Cb func, const void *func_data)
6888 {
6889    EINA_SAFETY_ON_NULL_RETURN_VAL(eo_before, NULL);
6890    ELM_GENLIST_ITEM_DATA_GET(eo_before, before_it);
6891    Elm_Gen_Item *it;
6892
6893    ELM_GENLIST_ITEM_CHECK_OR_RETURN(before_it, NULL);
6894    EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(before_it), NULL);
6895    if (eo_parent)
6896      {
6897         ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6898         ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6899         EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6900      }
6901
6902    /* It makes no sense to insert before in an empty list with before
6903     * != NULL, something really bad is happening in your app. */
6904    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->items, NULL);
6905
6906    it = _elm_genlist_item_new
6907        (sd, itc, data, eo_parent, type, func, func_data);
6908    if (!it) return NULL;
6909
6910    if (!it->parent)
6911      {
6912         if ((GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) &&
6913             (GL_IT(before_it)->type == ELM_GENLIST_ITEM_GROUP))
6914           sd->group_items =
6915             eina_list_prepend_relative(sd->group_items, it, before_it);
6916      }
6917    else
6918      {
6919         it->parent->item->items =
6920           eina_list_prepend_relative(it->parent->item->items, EO_OBJ(it), eo_before);
6921      }
6922    sd->items = eina_inlist_prepend_relative
6923        (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before_it));
6924
6925    GL_IT(it)->rel = before_it;
6926    before_it->item->rel_revs = eina_list_append(before_it->item->rel_revs, it);
6927    GL_IT(it)->before = EINA_TRUE;
6928    _item_queue_direct(it, NULL);
6929
6930    if (before_it == sd->aligned_item)
6931      sd->aligned_item = NULL;
6932
6933    return EO_OBJ(it);
6934 }
6935
6936 EOLIAN static Elm_Object_Item*
6937 _elm_genlist_item_sorted_insert(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Object_Item *eo_parent, Elm_Genlist_Item_Type type, Eina_Compare_Cb comp, Evas_Smart_Cb func, const void *func_data)
6938 {
6939    Elm_Gen_Item *rel = NULL;
6940    Elm_Gen_Item *it;
6941    Elm_Object_Item *eo_it;
6942
6943    if (eo_parent)
6944      {
6945         ELM_GENLIST_ITEM_DATA_GET(eo_parent, parent);
6946         ELM_GENLIST_ITEM_CHECK_OR_RETURN(parent, NULL);
6947         EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == WIDGET(parent), NULL);
6948      }
6949
6950    it = _elm_genlist_item_new
6951        (sd, itc, data, eo_parent, type, func, func_data);
6952    if (!it) return NULL;
6953    eo_it = EO_OBJ(it);
6954
6955    sd->item_compare_cb = comp;
6956
6957    if (it->parent)
6958      {
6959         Elm_Object_Item *eo_rel = NULL;
6960         Eina_List *l;
6961         int cmp_result;
6962
6963         l = eina_list_search_sorted_near_list
6964             (it->parent->item->items, _elm_genlist_item_list_compare, eo_it,
6965             &cmp_result);
6966
6967         if (l)
6968           {
6969              eo_rel = eina_list_data_get(l);
6970              rel = eo_data_scope_get(eo_rel, ELM_GENLIST_ITEM_CLASS);
6971
6972              if (cmp_result >= 0)
6973                {
6974                   it->parent->item->items = eina_list_prepend_relative_list
6975                       (it->parent->item->items, eo_it, l);
6976                   sd->items = eina_inlist_prepend_relative
6977                       (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6978                   it->item->before = EINA_TRUE;
6979                }
6980              else if (cmp_result < 0)
6981                {
6982                   it->parent->item->items = eina_list_append_relative_list
6983                       (it->parent->item->items, eo_it, l);
6984                   sd->items = eina_inlist_append_relative
6985                       (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6986                   it->item->before = EINA_FALSE;
6987                   it->item->is_prepend = EINA_TRUE;
6988                }
6989           }
6990         else
6991           {
6992              rel = it->parent;
6993
6994              // ignoring the comparison
6995              it->parent->item->items = eina_list_prepend_relative_list
6996                  (it->parent->item->items, eo_it, l);
6997              sd->items = eina_inlist_prepend_relative
6998                  (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6999              it->item->before = EINA_FALSE;
7000           }
7001      }
7002    else
7003      {
7004         if (!sd->state)
7005           {
7006              sd->state = eina_inlist_sorted_state_new();
7007              eina_inlist_sorted_state_init(sd->state, sd->items);
7008              sd->requeued = EINA_FALSE;
7009           }
7010
7011         if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
7012            sd->group_items = eina_list_append(sd->group_items, it);
7013
7014         sd->items = eina_inlist_sorted_state_insert
7015             (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
7016             sd->state);
7017
7018         if (EINA_INLIST_GET(it)->next)
7019           {
7020              rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
7021              GL_IT(it)->before = EINA_TRUE;
7022              GL_IT(it)->is_prepend = EINA_TRUE;
7023           }
7024         else if (EINA_INLIST_GET(it)->prev)
7025           {
7026              rel = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7027              GL_IT(it)->before = EINA_FALSE;
7028           }
7029      }
7030
7031    if (rel)
7032      {
7033         GL_IT(it)->rel = rel;
7034         rel->item->rel_revs = eina_list_append(rel->item->rel_revs, it);
7035      }
7036
7037    _item_queue_direct(it, _elm_genlist_item_list_compare);
7038    return eo_it;
7039 }
7040
7041 EOLIAN static void
7042 _elm_genlist_clear(Eo *obj, Elm_Genlist_Data *sd)
7043 {
7044    Elm_Gen_Item *it;
7045
7046    eina_hash_free_buckets(sd->size_caches);
7047    elm_object_item_focus_set(EO_OBJ(sd->focused_item), EINA_FALSE);
7048    if (sd->key_down_item) sd->key_down_item = NULL;
7049    if (sd->mode_item) sd->mode_item = NULL;
7050
7051    if (sd->state)
7052      {
7053         eina_inlist_sorted_state_free(sd->state);
7054         sd->state = NULL;
7055      }
7056
7057    sd->filter_data = NULL;
7058    if (sd->filter_queue)
7059      ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
7060    ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
7061    ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
7062
7063    // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE
7064    // because sd->items can be modified inside elm_widget_item_del()
7065    while (sd->items)
7066      {
7067         it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
7068         //elm_widget_item_del(it);
7069         _item_free(it);
7070      }
7071    sd->reorder.it = NULL;
7072    sd->reorder.dir = 0;
7073    eina_list_free(sd->reorder.move_items);
7074
7075    sd->items = NULL;
7076    sd->blocks = NULL;
7077    _item_cache_all_free(sd);
7078
7079    if (sd->selected)
7080      {
7081         sd->selected = eina_list_free(sd->selected);
7082         sd->selected = NULL;
7083      }
7084
7085    sd->show_item = NULL;
7086
7087    sd->pan_x = 0;
7088    sd->pan_y = 0;
7089    sd->minw = 0;
7090    sd->minh = 0;
7091
7092    if (sd->pan_obj)
7093      {
7094         evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
7095         evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
7096      }
7097    elm_layout_sizing_eval(obj);
7098
7099    eo_do(sd->obj, elm_interface_scrollable_content_region_show(0, 0, 0, 0));
7100
7101    if (sd->dummy_job)
7102      {
7103         ecore_job_del(sd->dummy_job);
7104         sd->dummy_job = NULL;
7105      }
7106    if (sd->queue_idle_enterer)
7107      {
7108         ecore_idle_enterer_del(sd->queue_idle_enterer);
7109         sd->queue_idle_enterer = NULL;
7110      }
7111    if (sd->scr_hold_timer)
7112      {
7113         ecore_timer_del(sd->scr_hold_timer);
7114         sd->scr_hold_timer = NULL;
7115      }
7116    if (sd->reorder.anim)
7117      {
7118         ecore_animator_del(sd->reorder.anim);
7119         sd->reorder.anim = NULL;
7120      }
7121    if (sd->scr_timer)
7122      {
7123         ecore_timer_del(sd->scr_timer);
7124         sd->scr_timer = NULL;
7125      }
7126 #ifdef GENLIST_FX_SUPPORT
7127    if (sd->del_fx.anim)
7128      {
7129         ecore_animator_del(sd->del_fx.anim);
7130         sd->del_fx.anim = NULL;
7131      }
7132    if (sd->add_fx.anim)
7133      {
7134         ecore_animator_del(sd->add_fx.anim);
7135         sd->add_fx.anim = NULL;
7136      }
7137 #endif
7138
7139    if (sd->queue) sd->queue = eina_list_free(sd->queue);
7140    if (sd->g_item) sd->g_item = NULL;
7141    if (sd->g_type) sd->g_type = NULL;
7142
7143    if (!TIZEN_PROFILE_WEARABLE)
7144      {
7145         if (sd->banded_bg_rect)
7146           {
7147              evas_object_smart_member_del(sd->banded_bg_rect);
7148              ELM_SAFE_FREE(sd->banded_bg_rect, evas_object_del);
7149           }
7150      }
7151 }
7152
7153 EOLIAN static void
7154 _elm_genlist_multi_select_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool multi)
7155 {
7156    sd->multi = !!multi;
7157    if (!sd->multi && sd->selected)
7158      {
7159         Eina_List *l, *ll;
7160         Elm_Object_Item *eo_it;
7161         Elm_Object_Item *last = sd->selected->data;
7162         EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
7163            if (last != eo_it)
7164              {
7165                 ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
7166                 _item_unselect(it);
7167              }
7168      }
7169 }
7170
7171 EOLIAN static Eina_Bool
7172 _elm_genlist_multi_select_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7173 {
7174    return sd->multi;
7175 }
7176
7177 EOLIAN static void
7178 _elm_genlist_multi_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Elm_Object_Multi_Select_Mode mode EINA_UNUSED)
7179 {
7180 /* Need to be implemented
7181    if (mode >= ELM_OBJECT_MULTI_SELECT_MODE_MAX)
7182      return;
7183
7184    if (sd->multi_select_mode != mode)
7185      sd->multi_select_mode = mode;
7186 */
7187    return;
7188 }
7189
7190 EOLIAN static Elm_Object_Multi_Select_Mode
7191 _elm_genlist_multi_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
7192 {
7193    // Need to be implemented
7194    //return sd->multi_select_mode;
7195    return ELM_OBJECT_MULTI_SELECT_MODE_DEFAULT;
7196 }
7197
7198 EOLIAN static Elm_Object_Item*
7199 _elm_genlist_selected_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7200 {
7201    if (sd->selected)
7202      return sd->selected->data;
7203
7204    return NULL;
7205 }
7206
7207 EOLIAN static const Eina_List*
7208 _elm_genlist_selected_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7209 {
7210    return sd->selected;
7211 }
7212
7213 EOLIAN static Eina_List*
7214 _elm_genlist_realized_items_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7215 {
7216    Item_Block *itb;
7217    Eina_List *list = NULL;
7218    Eina_Bool done = EINA_FALSE;
7219
7220    EINA_INLIST_FOREACH(sd->blocks, itb)
7221      {
7222         if (itb->realized)
7223           {
7224              Eina_List *l;
7225              Elm_Gen_Item *it;
7226
7227              done = EINA_TRUE;
7228              EINA_LIST_FOREACH(itb->items, l, it)
7229                {
7230                   if (it->realized) list = eina_list_append(list, EO_OBJ(it));
7231                }
7232           }
7233         else
7234           {
7235              if (done) break;
7236           }
7237      }
7238    return list;
7239 }
7240
7241 EOLIAN static Elm_Object_Item *
7242 _elm_genlist_search_by_text_item_get(Eo *obj EINA_UNUSED,
7243                                      Elm_Genlist_Data *sd,
7244                                      Elm_Object_Item *item_to_search_from,
7245                                      const char *part_name,
7246                                      const char *pattern,
7247                                      Elm_Glob_Match_Flags flags)
7248 {
7249    Elm_Gen_Item *it = NULL;
7250    char *str = NULL;
7251    Eina_Inlist *start = NULL;
7252    int fnflags = 0;
7253
7254    if (!pattern) return NULL;
7255    if (!sd->items) return NULL;
7256
7257    if (flags & ELM_GLOB_MATCH_NO_ESCAPE) fnflags |= FNM_NOESCAPE;
7258    if (flags & ELM_GLOB_MATCH_PATH) fnflags |= FNM_PATHNAME;
7259    if (flags & ELM_GLOB_MATCH_PERIOD) fnflags |= FNM_PERIOD;
7260 #ifdef FNM_CASEFOLD
7261    if (flags & ELM_GLOB_MATCH_NOCASE) fnflags |= FNM_CASEFOLD;
7262 #endif
7263
7264    start = (item_to_search_from) ?
7265    EINA_INLIST_GET((Elm_Gen_Item *)eo_data_scope_get(item_to_search_from, ELM_GENLIST_ITEM_CLASS)) :
7266    sd->items;
7267    EINA_INLIST_FOREACH(start, it)
7268      {
7269         if (!it->itc->func.text_get) continue;
7270         str = it->itc->func.text_get((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), part_name);
7271         if (!str) continue;
7272         if (!fnmatch(pattern, str, fnflags))
7273           {
7274              free(str);
7275              return EO_OBJ(it);
7276           }
7277         free(str);
7278      }
7279    return NULL;
7280 }
7281
7282 EOLIAN static Elm_Object_Item*
7283 _elm_genlist_at_xy_item_get(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Evas_Coord x, Evas_Coord y, int *posret)
7284 {
7285    Evas_Coord ox, oy, ow, oh;
7286    Evas_Coord lasty;
7287    Item_Block *itb;
7288
7289    evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
7290    lasty = oy;
7291    EINA_INLIST_FOREACH(sd->blocks, itb)
7292      {
7293         Eina_List *l;
7294         Elm_Gen_Item *it;
7295         if (!ELM_RECTS_INTERSECT(ox + itb->x - itb->sd->pan_x,
7296                                  oy + itb->y - itb->sd->pan_y,
7297                                  sd->minw, itb->minh, x, y, 1, 1))
7298           continue;
7299         EINA_LIST_FOREACH(itb->items, l, it)
7300           {
7301              Evas_Coord itx, ity;
7302
7303              itx = ox + itb->x + it->x - itb->sd->pan_x;
7304              ity = oy + itb->y + it->y - itb->sd->pan_y;
7305              if (ELM_RECTS_INTERSECT
7306                    (itx, ity, GL_IT(it)->w, GL_IT(it)->h, x, y, 1, 1))
7307                {
7308                   if (posret)
7309                     {
7310                        if (y <= (ity + (GL_IT(it)->h / 4))) *posret = -1;
7311                        else if (y >= (ity + GL_IT(it)->h - (GL_IT(it)->h / 4)))
7312                          *posret = 1;
7313                        else *posret = 0;
7314                     }
7315
7316                   return EO_OBJ(it);
7317                }
7318              lasty = ity + GL_IT(it)->h;
7319           }
7320      }
7321    if (posret)
7322      {
7323         if (y > lasty) *posret = 1;
7324         else *posret = -1;
7325      }
7326
7327    return NULL;
7328 }
7329
7330 EOLIAN static Elm_Object_Item*
7331 _elm_genlist_first_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7332 {
7333    Elm_Gen_Item *tit, *it = NULL;
7334
7335    EINA_INLIST_REVERSE_FOREACH(sd->items, tit) it = tit;
7336
7337    return EO_OBJ(it);
7338 }
7339
7340 EOLIAN static Elm_Object_Item*
7341 _elm_genlist_last_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7342 {
7343    Elm_Gen_Item *it;
7344
7345    if (!sd->items) return NULL;
7346
7347    it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
7348    return EO_OBJ(it);
7349 }
7350
7351 EOLIAN static Elm_Object_Item *
7352 _elm_genlist_item_next_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7353 {
7354    while (it)
7355      {
7356         it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
7357         if (it) break;
7358      }
7359
7360    if (it) return EO_OBJ(it);
7361    else return NULL;
7362 }
7363
7364 EOLIAN static Elm_Object_Item *
7365 _elm_genlist_item_prev_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7366 {
7367    while (it)
7368      {
7369         it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
7370         if (it) break;
7371      }
7372
7373    if (it) return EO_OBJ(it);
7374    else return NULL;
7375 }
7376
7377 EOLIAN static Elm_Object_Item *
7378 _elm_genlist_item_parent_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7379 {
7380    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
7381
7382    return EO_OBJ(it->parent);
7383 }
7384
7385 EOLIAN static unsigned int
7386 _elm_genlist_item_subitems_count(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
7387 {
7388    ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, 0);
7389
7390    return eina_list_count(item->item->items);
7391 }
7392
7393 EOLIAN static const Eina_List *
7394 _elm_genlist_item_subitems_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *item)
7395 {
7396    ELM_GENLIST_ITEM_CHECK_OR_RETURN(item, NULL);
7397
7398    return item->item->items;
7399 }
7400
7401 EOLIAN static void
7402 _elm_genlist_item_subitems_clear(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7403 {
7404    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7405    Eina_List *l, *ll;
7406    Elm_Object_Item *eo_it2;
7407
7408    EINA_LIST_FOREACH_SAFE(GL_IT(it)->items, l, ll, eo_it2)
7409      eo_do(eo_it2, elm_wdg_item_del());
7410 }
7411
7412 EOLIAN static void
7413 _elm_genlist_item_selected_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
7414       Eina_Bool selected)
7415 {
7416    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7417    Eina_Bool ret;
7418
7419    if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get())) return;
7420    // FIXME: This API has highlight/unhighlith feature also..
7421
7422    if (selected) _item_highlight(it);
7423    else _item_unhighlight(it, EINA_TRUE);
7424
7425    selected = !!selected;
7426    if (it->selected == selected) return;
7427
7428    if (selected) _item_select(it);
7429    else _item_unselect(it);
7430 }
7431
7432 EOLIAN static Eina_Bool
7433 _elm_genlist_item_selected_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7434 {
7435    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7436
7437    return it->selected;
7438 }
7439
7440 EOLIAN static void
7441 _elm_genlist_item_expanded_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool expanded)
7442 {
7443    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7444
7445    expanded = !!expanded;
7446    if (GL_IT(it)->expanded == expanded) return;
7447    if (GL_IT(it)->type != ELM_GENLIST_ITEM_TREE) return;
7448    GL_IT(it)->expanded = expanded;
7449    GL_IT(it)->wsd->expanded_item = it;
7450
7451    if (GL_IT(it)->expanded)
7452      {
7453         if (it->realized)
7454           edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
7455         evas_object_smart_callback_call(WIDGET(it), SIG_EXPANDED, EO_OBJ(it));
7456         if (_elm_atspi_enabled())
7457           elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_item);
7458      }
7459    else
7460      {
7461         if (it->realized)
7462           edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACTED, "elm");
7463         evas_object_smart_callback_call(WIDGET(it), SIG_CONTRACTED, EO_OBJ(it));
7464         if (_elm_atspi_enabled())
7465           elm_interface_atspi_accessible_active_descendant_changed_signal_emit(WIDGET(it), eo_item);
7466      }
7467 }
7468
7469 EOLIAN static Eina_Bool
7470 _elm_genlist_item_expanded_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7471 {
7472    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7473
7474    return GL_IT(it)->expanded;
7475 }
7476
7477 EOLIAN static int
7478 _elm_genlist_item_expanded_depth_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7479 {
7480    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, 0);
7481
7482    return GL_IT(it)->expanded_depth;
7483 }
7484
7485 EOLIAN static void
7486 _elm_genlist_item_promote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7487 {
7488    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7489
7490    Elm_Object_Item *eo_first_item = elm_genlist_first_item_get(WIDGET(it));
7491    ELM_GENLIST_ITEM_DATA_GET(eo_first_item, first_item);
7492    _item_move_before(it, first_item);
7493 }
7494
7495 EOLIAN static void
7496 _elm_genlist_item_demote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7497 {
7498    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7499    Elm_Object_Item *eo_last_item = elm_genlist_last_item_get(WIDGET(it));
7500    ELM_GENLIST_ITEM_DATA_GET(eo_last_item, last_item);
7501    _item_move_after(it, last_item);
7502 }
7503
7504 EOLIAN static void
7505 _elm_genlist_item_show(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
7506 {
7507    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7508
7509    if (it->want_hidden)
7510      {
7511         WRN("Filter hided item cannot move to show");
7512         return;
7513      }
7514
7515    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7516    sd->show_item = it;
7517    sd->bring_in = EINA_FALSE;
7518    sd->scroll_to_type = type;
7519    _changed(sd->pan_obj);
7520 }
7521
7522 EOLIAN static void
7523 _elm_genlist_item_bring_in(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Elm_Genlist_Item_Scrollto_Type type)
7524 {
7525    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7526
7527    if (it->want_hidden)
7528      {
7529         WRN("Filter hided item cannot move to bring in");
7530         return;
7531      }
7532
7533    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7534    ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wd);
7535    sd->bring_in = EINA_TRUE;
7536    sd->scroll_to_type = type;
7537
7538    if (wd->scroll_item_align_enable)
7539      {
7540         it = _adjust_item_align(it);
7541         sd->adjusted_item = sd->show_item = it;
7542
7543         if (sd->aligned_item && sd->show_item != sd->aligned_item)
7544           edje_object_signal_emit(VIEW(sd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
7545      }
7546    else
7547      sd->show_item = it;
7548
7549    _changed(sd->pan_obj);
7550 }
7551
7552 EOLIAN static void
7553 _elm_genlist_item_all_contents_unset(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_List **l)
7554 {
7555    Evas_Object *content;
7556
7557    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7558
7559    EINA_LIST_FREE (it->content_objs, content)
7560      {
7561         evas_object_smart_member_del(content);
7562         // edje can be reused by item caching,
7563         // content should be un-swallowed from edje
7564         edje_object_part_unswallow(VIEW(it), content);
7565         evas_object_hide(content);
7566         if (l) *l = eina_list_append(*l, content);
7567      }
7568 }
7569
7570 EOLIAN static void
7571 _elm_genlist_item_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7572 {
7573    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7574
7575    if (!GL_IT(it)->block) return;
7576
7577    GL_IT(it)->updateme = EINA_TRUE;
7578    GL_IT(it)->block->calc_done = EINA_FALSE;
7579    GL_IT(it)->wsd->calc_done = EINA_FALSE;
7580    _changed(GL_IT(it)->wsd->pan_obj);
7581 }
7582
7583 EOLIAN static void
7584 _elm_genlist_item_fields_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
7585                                const char *parts,
7586                                Elm_Genlist_Item_Field_Type itf)
7587 {
7588    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7589
7590    if (!GL_IT(it)->block) return;
7591
7592    if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
7593      {
7594         _item_text_realize(it, VIEW(it), parts);
7595      }
7596    if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_CONTENT))
7597      {
7598         _item_content_realize(it, VIEW(it), &it->content_objs, "contents", parts);
7599         if (it->flipped)
7600           {
7601               _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_content_objs,
7602                                      "flips", parts);
7603           }
7604         if (GL_IT(it)->deco_it_view)
7605           {
7606              _item_content_realize(it, GL_IT(it)->deco_it_view,
7607                                    &GL_IT(it)->deco_it_contents,
7608                                    "contents", parts);
7609           }
7610         if (GL_IT(it)->wsd->decorate_all_mode)
7611           {
7612              _item_content_realize(it, it->deco_all_view,
7613                                    &GL_IT(it)->deco_all_contents,
7614                                    "contents", parts);
7615           }
7616      }
7617
7618    if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_STATE))
7619      _item_state_realize(it, VIEW(it), parts);
7620
7621    GL_IT(it)->calc_done = EINA_FALSE;
7622    GL_IT(it)->block->calc_done = EINA_FALSE;
7623    GL_IT(it)->wsd->calc_done = EINA_FALSE;
7624     _changed(GL_IT(it)->wsd->pan_obj);
7625 }
7626
7627 EOLIAN static void
7628 _elm_genlist_item_item_class_update(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
7629                                    const Elm_Genlist_Item_Class *itc)
7630 {
7631    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7632    EINA_SAFETY_ON_NULL_RETURN(itc);
7633    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
7634    it->itc = itc;
7635
7636    if (!GL_IT(it)->block) return;
7637
7638    // FIXME(160711): orignal edje object updated by _view_theme_update
7639    // cannot recieve signal emit properly. This edje bug must be fixed.
7640    _item_cache_all_free(sd);
7641
7642    sd->no_cache = EINA_TRUE;
7643    _item_unrealize(it, EINA_FALSE);
7644    sd->no_cache = EINA_FALSE;
7645    _item_realize(it, EINA_FALSE);
7646
7647    if (sd->aligned_item == it)
7648      edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
7649
7650    GL_IT(it)->calc_done = EINA_FALSE;
7651    GL_IT(it)->block->calc_done = EINA_FALSE;
7652    sd->calc_done = EINA_FALSE;
7653
7654    _changed(sd->pan_obj);
7655 }
7656
7657 EOLIAN static const Elm_Genlist_Item_Class *
7658 _elm_genlist_item_item_class_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
7659 {
7660    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
7661    return it->itc;
7662 }
7663
7664 static Evas_Object *
7665 _elm_genlist_item_label_create(void *data,
7666                                Evas_Object *obj EINA_UNUSED,
7667                                Evas_Object *tooltip,
7668                                void *it EINA_UNUSED)
7669 {
7670    Evas_Object *label = elm_label_add(tooltip);
7671
7672    if (!label)
7673      return NULL;
7674
7675    elm_object_style_set(label, "tooltip");
7676    elm_object_text_set(label, data);
7677
7678    return label;
7679 }
7680
7681 static void
7682 _elm_genlist_item_label_del_cb(void *data,
7683                                Evas_Object *obj EINA_UNUSED,
7684                                void *event_info EINA_UNUSED)
7685 {
7686    eina_stringshare_del(data);
7687 }
7688
7689 EAPI void
7690 elm_genlist_item_tooltip_text_set(Elm_Object_Item *it,
7691                                   const char *text)
7692 {
7693    eo_do(it, elm_wdg_item_tooltip_text_set(text));
7694 }
7695
7696 EOLIAN static void
7697 _elm_genlist_item_elm_widget_item_tooltip_text_set(Eo *eo_it, Elm_Gen_Item *it, const char *text)
7698 {
7699    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7700
7701    text = eina_stringshare_add(text);
7702    elm_genlist_item_tooltip_content_cb_set
7703      (eo_it, _elm_genlist_item_label_create, text,
7704      _elm_genlist_item_label_del_cb);
7705 }
7706
7707 EAPI void
7708 elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item,
7709                                         Elm_Tooltip_Item_Content_Cb func,
7710                                         const void *data,
7711                                         Evas_Smart_Cb del_cb)
7712 {
7713    eo_do(item, elm_wdg_item_tooltip_content_cb_set(func, data, del_cb));
7714 }
7715
7716
7717 EOLIAN static void
7718 _elm_genlist_item_elm_widget_item_tooltip_content_cb_set(Eo *eo_it, Elm_Gen_Item *it,
7719                                         Elm_Tooltip_Item_Content_Cb func,
7720                                         const void *data,
7721                                         Evas_Smart_Cb del_cb)
7722 {
7723    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7724
7725    if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
7726      return;
7727
7728    if (it->tooltip.del_cb)
7729      it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7730
7731    it->tooltip.content_cb = func;
7732    it->tooltip.data = data;
7733    it->tooltip.del_cb = del_cb;
7734
7735    if (VIEW(it))
7736      {
7737         eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7738               elm_wdg_item_tooltip_content_cb_set
7739               (it->tooltip.content_cb, it->tooltip.data, NULL));
7740         eo_do(eo_it,
7741               elm_wdg_item_tooltip_style_set(it->tooltip.style),
7742               elm_wdg_item_tooltip_window_mode_set(it->tooltip.free_size));
7743      }
7744 }
7745
7746 EAPI void
7747 elm_genlist_item_tooltip_unset(Elm_Object_Item *item)
7748 {
7749    eo_do(item, elm_wdg_item_tooltip_unset());
7750 }
7751
7752 EOLIAN static void
7753 _elm_genlist_item_elm_widget_item_tooltip_unset(Eo *eo_it, Elm_Gen_Item *it)
7754 {
7755    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7756
7757    if ((VIEW(it)) && (it->tooltip.content_cb))
7758      eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7759            elm_wdg_item_tooltip_unset());
7760
7761    if (it->tooltip.del_cb)
7762      it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
7763    it->tooltip.del_cb = NULL;
7764    it->tooltip.content_cb = NULL;
7765    it->tooltip.data = NULL;
7766    it->tooltip.free_size = EINA_FALSE;
7767    if (it->tooltip.style)
7768      eo_do(eo_it, elm_wdg_item_tooltip_style_set(NULL));
7769 }
7770
7771 EAPI void
7772 elm_genlist_item_tooltip_style_set(Elm_Object_Item *item,
7773                                    const char *style)
7774 {
7775    eo_do(item, elm_wdg_item_tooltip_style_set(style));
7776 }
7777
7778 EOLIAN static void
7779 _elm_genlist_item_elm_widget_item_tooltip_style_set(Eo *eo_it, Elm_Gen_Item *it,
7780                                    const char *style)
7781 {
7782    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7783
7784    eina_stringshare_replace(&it->tooltip.style, style);
7785    if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7786          elm_wdg_item_tooltip_style_set(style));
7787 }
7788
7789 EAPI const char *
7790 elm_genlist_item_tooltip_style_get(const Elm_Object_Item *it)
7791 {
7792    const char *style;
7793    return eo_do_ret(it, style, elm_wdg_item_tooltip_style_get());
7794 }
7795
7796 EOLIAN static const char *
7797 _elm_genlist_item_elm_widget_item_tooltip_style_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7798 {
7799    return it->tooltip.style;
7800 }
7801
7802 EAPI Eina_Bool
7803 elm_genlist_item_tooltip_window_mode_set(Elm_Object_Item *item,
7804                                          Eina_Bool disable)
7805 {
7806    Eina_Bool ret;
7807    return eo_do_ret(item, ret, elm_wdg_item_tooltip_window_mode_set(disable));
7808 }
7809
7810 EOLIAN static Eina_Bool
7811 _elm_genlist_item_elm_widget_item_tooltip_window_mode_set(Eo *eo_it, Elm_Gen_Item *it,
7812                                    Eina_Bool disable)
7813 {
7814    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
7815    Eina_Bool ret;
7816
7817    it->tooltip.free_size = disable;
7818    if (VIEW(it))
7819       return eo_do_super_ret(eo_it, ELM_GENLIST_ITEM_CLASS, ret,
7820             elm_wdg_item_tooltip_window_mode_set(disable));
7821
7822    return EINA_TRUE;
7823 }
7824
7825 EAPI Eina_Bool
7826 elm_genlist_item_tooltip_window_mode_get(const Elm_Object_Item *eo_it)
7827 {
7828    Eina_Bool ret;
7829    return eo_do_ret(eo_it, ret, elm_wdg_item_tooltip_window_mode_get());
7830 }
7831
7832 EOLIAN static Eina_Bool
7833 _elm_genlist_item_elm_widget_item_tooltip_window_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7834 {
7835    return it->tooltip.free_size;
7836 }
7837
7838 EAPI void
7839 elm_genlist_item_cursor_set(Elm_Object_Item *item,
7840                             const char *cursor)
7841 {
7842    eo_do(item, elm_wdg_item_cursor_set(cursor));
7843 }
7844
7845 EOLIAN static void
7846 _elm_genlist_item_elm_widget_item_cursor_set(Eo *eo_it, Elm_Gen_Item *it,
7847                             const char *cursor)
7848 {
7849    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7850    eina_stringshare_replace(&it->mouse_cursor, cursor);
7851    if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7852          elm_wdg_item_cursor_set(cursor));
7853 }
7854
7855 EAPI const char *
7856 elm_genlist_item_cursor_get(const Elm_Object_Item *eo_it)
7857 {
7858    const char *cursor;
7859    return eo_do_ret(eo_it, cursor, elm_wdg_item_cursor_get());
7860 }
7861
7862 EAPI void
7863 elm_genlist_item_cursor_unset(Elm_Object_Item *item)
7864 {
7865    eo_do(item, elm_wdg_item_cursor_unset());
7866 }
7867
7868 EOLIAN static void
7869 _elm_genlist_item_elm_widget_item_cursor_unset(Eo *eo_it, Elm_Gen_Item *it)
7870 {
7871    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
7872
7873    if (!it->mouse_cursor) return;
7874
7875    if (VIEW(it)) eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS,
7876          elm_wdg_item_cursor_unset());
7877
7878    ELM_SAFE_FREE(it->mouse_cursor, eina_stringshare_del);
7879 }
7880
7881 EAPI void
7882 elm_genlist_item_cursor_style_set(Elm_Object_Item *eo_it,
7883                                   const char *style)
7884 {
7885    eo_do(eo_it, elm_wdg_item_cursor_style_set(style));
7886 }
7887
7888 EAPI const char *
7889 elm_genlist_item_cursor_style_get(const Elm_Object_Item *eo_it)
7890 {
7891    const char *style;
7892    return eo_do_ret( eo_it, style, elm_wdg_item_cursor_style_get());
7893 }
7894
7895 EAPI void
7896 elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *eo_it,
7897                                         Eina_Bool engine_only)
7898 {
7899    eo_do(eo_it, elm_wdg_item_cursor_engine_only_set(engine_only));
7900 }
7901
7902 EAPI Eina_Bool
7903 elm_genlist_item_cursor_engine_only_get(const Elm_Object_Item *eo_it)
7904 {
7905    Eina_Bool ret;
7906    return eo_do_ret( eo_it, ret, elm_wdg_item_cursor_engine_only_get());
7907 }
7908
7909 EOLIAN static int
7910 _elm_genlist_item_index_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
7911 {
7912    int cnt = 1;
7913    Elm_Gen_Item *tmp;
7914    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, -1);
7915
7916    EINA_INLIST_FOREACH(GL_IT(it)->wsd->items, tmp)
7917      {
7918         if (tmp == it) break;
7919         cnt++;
7920      }
7921    return cnt;
7922 }
7923
7924 EOLIAN static void
7925 _elm_genlist_mode_set(Eo *obj, Elm_Genlist_Data *sd, Elm_List_Mode mode)
7926 {
7927    if (sd->mode == mode) return;
7928    sd->mode = mode;
7929
7930    if (sd->mode == ELM_LIST_LIMIT)
7931      {
7932         sd->scr_minw = EINA_TRUE;
7933         sd->scr_minh = EINA_FALSE;
7934      }
7935    else if (sd->mode == ELM_LIST_EXPAND)
7936      {
7937         sd->scr_minw = EINA_TRUE;
7938         sd->scr_minh = EINA_TRUE;
7939      }
7940    else
7941      {
7942         sd->scr_minw = EINA_FALSE;
7943         sd->scr_minh = EINA_FALSE;
7944      }
7945
7946    elm_layout_sizing_eval(obj);
7947 }
7948
7949 EOLIAN static Elm_List_Mode
7950 _elm_genlist_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7951 {
7952    return sd->mode;
7953 }
7954
7955 EAPI void
7956 elm_genlist_bounce_set(Evas_Object *obj,
7957                        Eina_Bool h_bounce,
7958                        Eina_Bool v_bounce)
7959 {
7960    ELM_GENLIST_CHECK(obj);
7961    eo_do(obj, elm_interface_scrollable_bounce_allow_set(h_bounce, v_bounce));
7962 }
7963
7964 EOLIAN static void
7965 _elm_genlist_elm_interface_scrollable_bounce_allow_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool h_bounce, Eina_Bool v_bounce)
7966 {
7967    sd->h_bounce = !!h_bounce;
7968    sd->v_bounce = !!v_bounce;
7969
7970    eo_do_super(obj, MY_CLASS, elm_interface_scrollable_bounce_allow_set
7971          (sd->h_bounce, sd->v_bounce));
7972    //sd->s_iface->bounce_allow_set(obj, sd->h_bounce, sd->v_bounce);
7973 }
7974
7975 EAPI void
7976 elm_genlist_bounce_get(const Evas_Object *obj,
7977                        Eina_Bool *h_bounce,
7978                        Eina_Bool *v_bounce)
7979 {
7980    ELM_GENLIST_CHECK(obj);
7981    eo_do( obj, elm_interface_scrollable_bounce_allow_get
7982          (h_bounce, v_bounce));
7983 }
7984
7985 EOLIAN static void
7986 _elm_genlist_elm_interface_scrollable_bounce_allow_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
7987 {
7988    if (h_bounce) *h_bounce = sd->h_bounce;
7989    if (v_bounce) *v_bounce = sd->v_bounce;
7990 }
7991
7992 EOLIAN static void
7993 _elm_genlist_homogeneous_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool homogeneous)
7994 {
7995    sd->homogeneous = !!homogeneous;
7996 }
7997
7998 EOLIAN static Eina_Bool
7999 _elm_genlist_homogeneous_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8000 {
8001    return sd->homogeneous;
8002 }
8003
8004 EOLIAN static void
8005 _elm_genlist_block_count_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, int count)
8006 {
8007    EINA_SAFETY_ON_TRUE_RETURN(count < 1);
8008
8009    sd->max_items_per_block = count;
8010    sd->item_cache_max = sd->max_items_per_block * 2;
8011    _item_cache_all_free(sd);
8012 }
8013
8014 EOLIAN static int
8015 _elm_genlist_block_count_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8016 {
8017    return sd->max_items_per_block;
8018 }
8019
8020 static void
8021 _filter_item_internal(Elm_Gen_Item *it)
8022 {
8023    ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8024    if (sd->filter_data && it->itc->func.filter_get)
8025      {
8026         if (!it->itc->func.filter_get(
8027                (void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)),
8028                 WIDGET(it), sd->filter_data))
8029           {
8030              it->want_hidden = EINA_TRUE;
8031              if (sd->show_item == it) sd->show_item = NULL;
8032              GL_IT(it)->block->calc_done = EINA_FALSE;
8033              sd->calc_done = EINA_FALSE;
8034           }
8035         else
8036           sd->filtered_count++;
8037      }
8038    it->filtered = EINA_TRUE;
8039    sd->processed_count++;
8040 }
8041
8042 static Eina_Bool
8043 _item_filtered_get(Elm_Gen_Item *it)
8044 {
8045    Eina_List *l;
8046    if (!it) return EINA_FALSE;
8047    ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
8048    if (!it->filtered)
8049      {
8050         l = eina_list_data_find_list(sd->filter_queue, it);
8051         if (l)
8052           sd->filter_queue = eina_list_remove_list(sd->filter_queue, l);
8053         l = eina_list_data_find_list(sd->queue, it);
8054         if (l)
8055           {
8056              sd->queue = eina_list_remove_list(sd->queue, l);
8057              GL_IT(it)->queued = EINA_FALSE;
8058              GL_IT(it)->resized = EINA_FALSE;
8059              _item_process(sd, it);
8060           }
8061
8062         _filter_item_internal(it);
8063         GL_IT(it)->block->calc_done = EINA_FALSE;
8064         sd->calc_done = EINA_FALSE;
8065         _changed(sd->pan_obj);
8066    }
8067    if (!it->want_hidden) return EINA_TRUE;
8068    return EINA_FALSE;
8069 }
8070
8071 static int
8072 _filter_queue_process(Elm_Genlist_Data *sd)
8073 {
8074    int n = 0;
8075    Elm_Gen_Item *it, *first;
8076    double t0;
8077
8078    t0 = ecore_time_get();
8079    for (n = 0; ((sd->filter_queue) && (sd->processed_count < ITEM_QUEUE_MAX)); n++)
8080      {
8081         first = it = eina_list_data_get(sd->filter_queue);
8082         //FIXME: This is added as a fail safe code for items not yet processed.
8083         while (it && it->item->queued)
8084           {
8085              if ((ecore_time_get() - t0) > (ecore_animator_frametime_get()))
8086                return n;
8087              sd->filter_queue = eina_list_remove_list
8088                               (sd->filter_queue, sd->filter_queue);
8089              sd->filter_queue = eina_list_append(sd->filter_queue, it);
8090              it = eina_list_data_get(sd->filter_queue);
8091
8092              //Do not iterate more than one loop
8093              if (it == first) return n;
8094           }
8095         sd->filter_queue = eina_list_remove_list(sd->filter_queue, sd->filter_queue);
8096         if (it)
8097           {
8098              _filter_item_internal(it);
8099              GL_IT(it)->block->calc_done = EINA_FALSE;
8100           }
8101         sd->calc_done = EINA_FALSE;
8102         _changed(sd->pan_obj);
8103         if ((ecore_time_get() - t0) > (ecore_animator_frametime_get()))
8104           {
8105              //At least 1 item is filtered by this time, so return n+1 for first loop
8106              n++;
8107              break;
8108           }
8109      }
8110    return n;
8111 }
8112
8113 static Eina_Bool
8114 _filter_process(void *data,
8115               Eina_Bool *wakeup)
8116 {
8117    Elm_Genlist_Data *sd = data;
8118
8119    if (_filter_queue_process(sd) > 0) *wakeup = EINA_TRUE;
8120    if (!sd->filter_queue) return ECORE_CALLBACK_CANCEL;
8121    return ECORE_CALLBACK_RENEW;
8122 }
8123
8124 static Eina_Bool
8125 _item_filter_enterer(void *data)
8126 {
8127    Eina_Bool wakeup = EINA_FALSE;
8128    ELM_GENLIST_DATA_GET(data, sd);
8129    Eina_Bool ok = _filter_process(sd, &wakeup);
8130    if (wakeup)
8131      {
8132         if (sd->dummy_job) ecore_job_del(sd->dummy_job);
8133         sd->dummy_job = ecore_job_add(_dummy_job, sd);
8134      }
8135    if (ok == ECORE_CALLBACK_CANCEL)
8136      {
8137         if (sd->dummy_job)
8138           {
8139              ecore_job_del(sd->dummy_job);
8140              sd->dummy_job = NULL;
8141           }
8142         sd->queue_idle_enterer = NULL;
8143         evas_object_smart_callback_call((Evas_Object *)data, SIG_FILTER_DONE, NULL);
8144      }
8145
8146    return ok;
8147 }
8148
8149 EOLIAN void
8150 _elm_genlist_filter_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, void *filter_data)
8151 {
8152    Item_Block *itb;
8153    Eina_List *l;
8154    Elm_Gen_Item *it;
8155
8156    if (sd->filter_queue)
8157      ELM_SAFE_FREE(sd->queue_filter_enterer, ecore_idle_enterer_del);
8158    ELM_SAFE_FREE(sd->filter_queue, eina_list_free);
8159    ELM_SAFE_FREE(sd->filtered_list, eina_list_free);
8160    sd->filtered_count = 0;
8161    sd->processed_count = 0;
8162    sd->filter = EINA_TRUE;
8163    sd->filter_data = filter_data;
8164
8165    EINA_INLIST_FOREACH(sd->blocks, itb)
8166      {
8167         if (itb->realized)
8168           {
8169              EINA_LIST_FOREACH(itb->items, l, it)
8170                {
8171                   it->filtered = EINA_FALSE;
8172                   it->want_hidden = EINA_FALSE;
8173                   if (it->realized)
8174                     _filter_item_internal(it);
8175                   else
8176                     sd->filter_queue = eina_list_append(sd->filter_queue, it);
8177                }
8178             itb->calc_done = EINA_FALSE;
8179             sd->calc_done = EINA_FALSE;
8180          }
8181        else
8182          {
8183             EINA_LIST_FOREACH(itb->items, l, it)
8184               {
8185                  it->filtered = EINA_FALSE;
8186                  it->want_hidden = EINA_FALSE;
8187                  sd->filter_queue = eina_list_append(sd->filter_queue, it);
8188               }
8189          }
8190      }
8191    _changed(sd->pan_obj);
8192
8193    sd->queue_filter_enterer = ecore_idle_enterer_add(_item_filter_enterer,
8194                                                      sd->obj);
8195 }
8196
8197 static Eina_Bool
8198 _filter_iterator_next(Elm_Genlist_Filter *iter, void **data)
8199 {
8200    if (!iter->current) return EINA_FALSE;
8201    Elm_Gen_Item *item;
8202    while (iter->current)
8203      {
8204         item = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->current, Elm_Gen_Item);
8205         iter->current = iter->current->next;
8206         if (_item_filtered_get(item))
8207           {
8208              if (data)
8209                *data = EO_OBJ(item);
8210              return EINA_TRUE;
8211           }
8212      }
8213
8214    return EINA_FALSE;
8215 }
8216
8217 static void
8218 _filter_iterator_free(Elm_Genlist_Filter *iter)
8219 {
8220    free(iter);
8221 }
8222
8223 static Evas_Object *
8224 _filter_iterator_get_container(Elm_Genlist_Filter *iter)
8225 {
8226    Elm_Gen_Item *it = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->head, Elm_Gen_Item);
8227    return WIDGET(it);
8228 }
8229
8230 EOLIAN Eina_Iterator *
8231 _elm_genlist_filter_iterator_new(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8232 {
8233    Elm_Genlist_Filter *iter;
8234    iter = calloc(1, sizeof (Elm_Genlist_Filter));
8235    if (!iter) return NULL;
8236
8237    iter->head = sd->items;
8238    iter->current = sd->items;
8239
8240    iter->iterator.version = EINA_ITERATOR_VERSION;
8241    iter->iterator.next = FUNC_ITERATOR_NEXT(_filter_iterator_next);
8242    iter->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
8243                                     _filter_iterator_get_container);
8244    iter->iterator.free = FUNC_ITERATOR_FREE(_filter_iterator_free);
8245
8246    EINA_MAGIC_SET(&iter->iterator, EINA_MAGIC_ITERATOR);
8247
8248    return &iter->iterator;
8249 }
8250
8251 EOLIAN static void
8252 _elm_genlist_longpress_timeout_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, double timeout)
8253 {
8254    sd->longpress_timeout = timeout;
8255 }
8256
8257 EOLIAN static double
8258 _elm_genlist_longpress_timeout_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8259 {
8260    return sd->longpress_timeout;
8261 }
8262
8263 EAPI void
8264 elm_genlist_scroller_policy_set(Evas_Object *obj,
8265                                 Elm_Scroller_Policy policy_h,
8266                                 Elm_Scroller_Policy policy_v)
8267 {
8268    ELM_GENLIST_CHECK(obj);
8269    eo_do(obj, elm_interface_scrollable_policy_set(policy_h, policy_v));
8270 }
8271
8272 EOLIAN static void
8273 _elm_genlist_elm_interface_scrollable_policy_set(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v)
8274 {
8275    ELM_GENLIST_CHECK(obj);
8276
8277    if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
8278        (policy_v >= ELM_SCROLLER_POLICY_LAST))
8279      return;
8280
8281    eo_do_super(obj, MY_CLASS, elm_interface_scrollable_policy_set(policy_h, policy_v));
8282 }
8283
8284 EAPI void
8285 elm_genlist_scroller_policy_get(const Evas_Object *obj,
8286                                 Elm_Scroller_Policy *policy_h,
8287                                 Elm_Scroller_Policy *policy_v)
8288 {
8289    ELM_GENLIST_CHECK(obj);
8290    eo_do( obj, elm_interface_scrollable_policy_get(policy_h, policy_v));
8291 }
8292
8293 EOLIAN static void
8294 _elm_genlist_elm_interface_scrollable_policy_get(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED, Elm_Scroller_Policy *policy_h, Elm_Scroller_Policy *policy_v)
8295 {
8296    Elm_Scroller_Policy s_policy_h, s_policy_v;
8297
8298    ELM_GENLIST_CHECK(obj);
8299
8300    eo_do((Eo *)obj, elm_interface_scrollable_policy_get(&s_policy_h, &s_policy_v));
8301    if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
8302    if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
8303 }
8304
8305 EOLIAN static void
8306 _elm_genlist_realized_items_update(Eo *obj, Elm_Genlist_Data *_pd EINA_UNUSED)
8307 {
8308    Eina_List *list;
8309    Elm_Object_Item *eo_it;
8310
8311    ELM_GENLIST_CHECK(obj);
8312
8313    list = elm_genlist_realized_items_get(obj);
8314    EINA_LIST_FREE(list, eo_it)
8315      elm_genlist_item_update(eo_it);
8316 }
8317
8318 EOLIAN static void
8319 _elm_genlist_item_decorate_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8320                                    const char *decorate_it_type,
8321                                    Eina_Bool decorate_it_set)
8322 {
8323    Elm_Genlist_Data *sd;
8324    Eina_Bool ret;
8325
8326    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8327    sd = GL_IT(it)->wsd;
8328
8329    if (!decorate_it_type) return;
8330    if (eo_do_ret(eo_it, ret, elm_wdg_item_disabled_get())) return;
8331    if (sd->decorate_all_mode) return;
8332
8333    if ((sd->mode_item == it) &&
8334        (!strcmp(decorate_it_type, sd->decorate_it_type)) &&
8335        (decorate_it_set))
8336      return;
8337    if (!it->itc->decorate_item_style) return;
8338    it->decorate_it_set = decorate_it_set;
8339
8340    _item_unselect(it);
8341    if (((sd->decorate_it_type)
8342         && (strcmp(decorate_it_type, sd->decorate_it_type))) ||
8343        (decorate_it_set) || ((it == sd->mode_item) && (!decorate_it_set)))
8344      {
8345         char buf[1024], buf2[1024];
8346
8347         eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8348         if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
8349         sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
8350
8351         snprintf(buf, sizeof(buf), "elm,state,%s,passive", sd->decorate_it_type);
8352         edje_object_signal_emit(GL_IT(it)->deco_it_view, buf, "elm");
8353         edje_object_signal_emit(VIEW(it), buf, "elm");
8354
8355         snprintf(buf2, sizeof(buf2), "elm,state,%s,passive,finished",
8356                  sd->decorate_it_type);
8357         edje_object_signal_callback_add(GL_IT(it)->deco_it_view, buf2,
8358                                         "elm",
8359                                         _decorate_item_finished_signal_cb, it);
8360         sd->mode_item = NULL;
8361      }
8362
8363    eina_stringshare_replace(&sd->decorate_it_type, decorate_it_type);
8364    if (decorate_it_set)
8365      {
8366         sd->mode_item = it;
8367         eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8368         if (sd->scr_hold_timer) ecore_timer_del(sd->scr_hold_timer);
8369         sd->scr_hold_timer = ecore_timer_add(0.1, _scroll_hold_timer_cb, sd);
8370
8371         _decorate_item_realize(it);
8372      }
8373 }
8374
8375 EOLIAN static const char *
8376 _elm_genlist_item_decorate_mode_get(Eo *eo_i EINA_UNUSED, Elm_Gen_Item *i)
8377 {
8378    ELM_GENLIST_ITEM_CHECK_OR_RETURN(i, NULL);
8379    return GL_IT(i)->wsd->decorate_it_type;
8380 }
8381
8382 EOLIAN static Elm_Object_Item *
8383 _elm_genlist_decorated_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8384 {
8385    return EO_OBJ(sd->mode_item);
8386 }
8387
8388 EOLIAN static Eina_Bool
8389 _elm_genlist_decorate_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8390 {
8391    return sd->decorate_all_mode;
8392 }
8393
8394 EOLIAN static void
8395 _elm_genlist_decorate_mode_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool decorated)
8396 {
8397    Elm_Object_Item *eo_it;
8398    Eina_List *list;
8399
8400    decorated = !!decorated;
8401    if (sd->decorate_all_mode == decorated) return;
8402    // decorate_all_mode should be set first
8403    // because content_get func. will be called after this
8404    // and user can check whether deocrate_all_mode is enabeld.
8405    sd->decorate_all_mode = decorated;
8406
8407    list = elm_genlist_realized_items_get(obj);
8408    EINA_LIST_FREE(list, eo_it)
8409      {
8410         ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8411
8412         if (!sd->decorate_all_mode)
8413           {
8414              _decorate_all_item_unrealize(it);
8415           }
8416         else if (it->itc->decorate_all_item_style)
8417           {
8418              _decorate_all_item_realize(it, EINA_TRUE);
8419           }
8420         _access_widget_item_register(it);
8421      }
8422    _changed(sd->pan_obj);
8423 }
8424
8425 EOLIAN static void
8426 _elm_genlist_reorder_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool reorder_mode)
8427 {
8428    Eina_List *list;
8429    Elm_Object_Item *eo_it;
8430
8431    if (sd->reorder_mode == !!reorder_mode) return;
8432    sd->reorder_mode = !!reorder_mode;
8433
8434    list = elm_genlist_realized_items_get(obj);
8435    EINA_LIST_FREE(list, eo_it)
8436      {
8437         ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8438         if (sd->reorder_mode)
8439           {
8440              edje_object_signal_emit
8441                 (VIEW(it), SIGNAL_REORDER_MODE_SET, "elm");
8442              if (it->deco_all_view)
8443                 edje_object_signal_emit
8444                    (it->deco_all_view, SIGNAL_REORDER_MODE_SET, "elm");
8445           }
8446         else
8447           {
8448              edje_object_signal_emit
8449                 (VIEW(it), SIGNAL_REORDER_MODE_UNSET, "elm");
8450              if (it->deco_all_view)
8451                 edje_object_signal_emit
8452                    (it->deco_all_view, SIGNAL_REORDER_MODE_UNSET, "elm");
8453           }
8454      }
8455 }
8456
8457 EOLIAN static Eina_Bool
8458 _elm_genlist_reorder_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8459 {
8460    return sd->reorder_mode;
8461 }
8462
8463 EOLIAN static Elm_Genlist_Item_Type
8464 _elm_genlist_item_type_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8465 {
8466    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_GENLIST_ITEM_MAX);
8467
8468    return GL_IT(it)->type;
8469 }
8470
8471 EAPI Elm_Genlist_Item_Class *
8472 elm_genlist_item_class_new(void)
8473 {
8474    Elm_Genlist_Item_Class *itc = ELM_NEW(Elm_Genlist_Item_Class);
8475    EINA_SAFETY_ON_NULL_RETURN_VAL(itc, NULL);
8476
8477    itc->version = CLASS_ALLOCATED;
8478    itc->refcount = 1;
8479    itc->delete_me = EINA_FALSE;
8480    // TIZEN ONLY(20160630): Support homogeneous mode in item class.
8481    itc->homogeneous = EINA_FALSE;
8482    //
8483
8484    return itc;
8485 }
8486
8487 EAPI void
8488 elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc)
8489 {
8490    if (itc && (itc->version == CLASS_ALLOCATED))
8491      {
8492         itc->delete_me = EINA_TRUE;
8493         if (itc->refcount > 0) elm_genlist_item_class_unref(itc);
8494         else
8495           {
8496              itc->version = 0;
8497              free(itc);
8498           }
8499      }
8500 }
8501
8502 EAPI void
8503 elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc)
8504 {
8505    if (itc && (itc->version == CLASS_ALLOCATED))
8506      {
8507         itc->refcount++;
8508         if (itc->refcount == 0) itc->refcount--;
8509      }
8510 }
8511
8512 EAPI void
8513 elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc)
8514 {
8515    if (itc && (itc->version == CLASS_ALLOCATED))
8516      {
8517         if (itc->refcount > 0) itc->refcount--;
8518         if (itc->delete_me && (!itc->refcount))
8519           elm_genlist_item_class_free(itc);
8520      }
8521 }
8522
8523 EOLIAN static void
8524 _elm_genlist_item_flip_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool flip)
8525 {
8526    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8527
8528    flip = !!flip;
8529    if (it->flipped == flip) return;
8530    it->flipped = flip;
8531
8532    if (it->flipped)
8533      {
8534         _item_content_realize(it, VIEW(it), &GL_IT(it)->flip_content_objs,
8535                                  "flips", NULL);
8536
8537         edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_ENABLED, "elm");
8538         if (GL_IT(it)->wsd->decorate_all_mode)
8539            edje_object_signal_emit
8540               (it->deco_all_view, SIGNAL_FLIP_ENABLED, "elm");
8541      }
8542    else
8543      {
8544         Evas_Object *c;
8545         edje_object_signal_emit(VIEW(it), SIGNAL_FLIP_DISABLED, "elm");
8546         if (GL_IT(it)->wsd->decorate_all_mode)
8547            edje_object_signal_emit
8548               (it->deco_all_view, SIGNAL_FLIP_DISABLED, "elm");
8549
8550         EINA_LIST_FREE(GL_IT(it)->flip_content_objs, c)
8551            evas_object_del(c);
8552
8553         // FIXME: update texts should be done by app?
8554         _item_text_realize(it, VIEW(it), NULL);
8555      }
8556    _access_widget_item_register(it);
8557 }
8558
8559 EOLIAN static Eina_Bool
8560 _elm_genlist_item_flip_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8561 {
8562    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
8563
8564    return it->flipped;
8565 }
8566
8567 EOLIAN static void
8568 _elm_genlist_select_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Elm_Object_Select_Mode mode)
8569 {
8570    if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (sd->select_mode == mode))
8571      return;
8572
8573    sd->select_mode = mode;
8574
8575    if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8576        (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
8577      {
8578         Eina_List *l, *ll;
8579         Elm_Object_Item *eo_it;
8580         EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, eo_it)
8581           {
8582              ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
8583              _item_unselect(it);
8584           }
8585      }
8586    if (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
8587      {
8588         Elm_Gen_Item *it;
8589         EINA_INLIST_FOREACH(sd->items, it)
8590           {
8591              if (!GL_IT(it)->block) continue;
8592              GL_IT(it)->calc_done = EINA_FALSE;
8593              GL_IT(it)->block->calc_done = EINA_FALSE;
8594              sd->calc_done = EINA_FALSE;
8595              _changed(sd->pan_obj);
8596           }
8597      }
8598 }
8599
8600 EOLIAN static Elm_Object_Select_Mode
8601 _elm_genlist_select_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8602 {
8603    return sd->select_mode;
8604 }
8605
8606 EOLIAN static void
8607 _elm_genlist_highlight_mode_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool highlight)
8608 {
8609    sd->highlight = !!highlight;
8610 }
8611
8612 EOLIAN static Eina_Bool
8613 _elm_genlist_highlight_mode_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8614 {
8615    return sd->highlight;
8616 }
8617
8618 EOLIAN static void
8619 _elm_genlist_item_select_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
8620                                  Elm_Object_Select_Mode mode)
8621 {
8622    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8623
8624    if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (it->select_mode == mode))
8625      return;
8626
8627    it->select_mode = mode;
8628
8629    if ((it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
8630        (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
8631       _item_unselect(it);
8632
8633    if (GL_IT(it)->block && it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
8634      {
8635         GL_IT(it)->calc_done = EINA_FALSE;
8636         GL_IT(it)->block->calc_done = EINA_FALSE;
8637         GL_IT(it)->wsd->calc_done = EINA_FALSE;
8638         _changed(GL_IT(it)->wsd->pan_obj);
8639      }
8640 }
8641
8642 EOLIAN static Elm_Object_Select_Mode
8643 _elm_genlist_item_select_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8644 {
8645    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
8646
8647    return it->select_mode;
8648 }
8649
8650 EOLIAN Elm_Atspi_State_Set
8651 _elm_genlist_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_it, Elm_Gen_Item *it EINA_UNUSED)
8652 {
8653    Elm_Atspi_State_Set ret;
8654    Eina_Bool sel;
8655
8656    eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
8657
8658    eo_do(eo_it, sel = elm_obj_genlist_item_selected_get());
8659
8660    STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTABLE);
8661
8662    if (sel)
8663       STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTED);
8664
8665    if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_TREE)
8666      {
8667         STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDABLE);
8668         if (elm_genlist_item_expanded_get(eo_it))
8669            STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8670         //TIZEN_ONLY(20160606): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8671         else
8672            STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8673         //
8674      }
8675    //TIZEN_ONLY(20160608): In order to distinguish group item(TREE/GROUP) added STATE_TYPE_SET
8676    else if (elm_genlist_item_type_get(eo_it) == ELM_GENLIST_ITEM_GROUP)
8677      {
8678         if (elm_genlist_item_expanded_get(eo_it))
8679             STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EXPANDED);
8680          else
8681             STATE_TYPE_SET(ret, ELM_ATSPI_STATE_COLLAPSED);
8682      }
8683    //
8684
8685    return ret;
8686 }
8687
8688 EOLIAN const char*
8689 _elm_genlist_item_elm_interface_atspi_accessible_name_get(Eo *eo_it,
8690                                                           Elm_Gen_Item *it)
8691 {
8692    const char *ret;
8693    Eina_Strbuf *buf;
8694    char *accessible_name;
8695    eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_name_get());
8696    if (ret) return ret;
8697
8698    buf = eina_strbuf_new();
8699
8700    if (it->itc->func.text_get)
8701      {
8702         Eina_List *texts;
8703         const char *key;
8704
8705         texts =
8706            elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
8707
8708         EINA_LIST_FREE(texts, key)
8709           {
8710              char *str_markup = it->itc->func.text_get
8711                 ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
8712              char *str_utf8 = _elm_util_mkup_to_text(str_markup);
8713              free(str_markup);
8714              if (str_utf8)
8715                {
8716                   if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
8717                   eina_strbuf_append(buf, str_utf8);
8718                   free(str_utf8);
8719                }
8720           }
8721      }
8722
8723    accessible_name = eina_strbuf_string_steal(buf);
8724    eina_strbuf_free(buf);
8725
8726    eina_stringshare_del(it->base->accessible_name);
8727    it->base->accessible_name = eina_stringshare_add(accessible_name);
8728    free(accessible_name);
8729    return it->base->accessible_name;
8730 }
8731
8732 EOLIAN Eina_List*
8733 _elm_genlist_item_elm_interface_atspi_accessible_children_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8734 {
8735    Eina_List *ret = NULL;
8736    if (VIEW(it))
8737      {
8738         Eina_List *parts;
8739         const char *key;
8740         parts = elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "contents"));
8741
8742         EINA_LIST_FREE(parts, key)
8743           {
8744              Evas_Object *part;
8745              part = edje_object_part_swallow_get(VIEW(it), key);
8746              if (part && eo_isa(part, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
8747                {
8748                   ret = eina_list_append(ret, part);
8749                   eo_do(part, elm_interface_atspi_accessible_parent_set(eo_it));
8750                }
8751           }
8752      }
8753    return ret;
8754 }
8755
8756
8757 ///////////////////////////////////////////////////////////////////////////////
8758 //TIZEN ONLY:(20150623): Region show on item elements fixed
8759 //Grab and clear highlight on genlist items
8760 ///////////////////////////////////////////////////////////////////////////////
8761 EOLIAN static Eina_Bool
8762 _elm_genlist_item_elm_interface_atspi_component_highlight_grab(Eo *eo_it, Elm_Gen_Item *it)
8763 {
8764    ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8765
8766    if (!TIZEN_PROFILE_WEARABLE)
8767      {
8768         //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
8769         eo_do_super(EO_OBJ(it), ELM_GENLIST_ITEM_CLASS, elm_interface_atspi_component_highlight_grab());
8770         //
8771      }
8772    else
8773      {
8774         // if item is realized check if in viewport
8775         if (VIEW(it))
8776           {
8777              Evas_Coord wy, wh, y, h;
8778              evas_object_geometry_get(WIDGET(it), NULL, &wy, NULL, &wh);
8779              evas_object_geometry_get(VIEW(it), NULL, &y, NULL, &h);
8780              //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8781              elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
8782              //
8783            }
8784         else // if item is not realized we should search if we are over or below viewport
8785           {
8786              Eina_List *realized = elm_genlist_realized_items_get(WIDGET(it));
8787              if (realized)
8788                {
8789                   elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
8790                   eina_list_free(realized);
8791                }
8792           }
8793         if (VIEW(it))
8794            elm_object_accessibility_highlight_set(EO_OBJ(it), EINA_TRUE);
8795         ///TIZEN_ONLY(20170717) : expose highlight information on atspi
8796         elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
8797         ///
8798
8799         //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
8800         // If you call eo_do_super, then you do NOT have to call smart callback.
8801         evas_object_smart_callback_call(WIDGET(it), "atspi,highlighted", EO_OBJ(it));
8802         //
8803      }
8804
8805
8806    if (VIEW(it))
8807      {
8808         //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8809         sd->currently_highlighted_item = it;
8810         //
8811      }
8812    else
8813      {
8814        if (!TIZEN_PROFILE_WEARABLE)
8815          {
8816             //TIZEN_ONLY(20170724): grab highlight using unrealized item
8817             elm_genlist_item_bring_in(eo_it, ELM_GENLIST_ITEM_SCROLLTO_IN);
8818             //
8819          }
8820        sd->atspi_item_to_highlight = it;//it will be highlighted when realized
8821      }
8822
8823    //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8824    edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
8825    //
8826
8827    return EINA_TRUE;
8828 }
8829
8830 EOLIAN static Eina_Bool
8831 _elm_genlist_item_elm_interface_atspi_component_highlight_clear(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
8832 {
8833    ELM_GENLIST_DATA_GET(WIDGET(it), sd);
8834    //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8835    if(sd->currently_highlighted_item == it)
8836      sd->currently_highlighted_item = NULL;
8837    //
8838    if (sd->atspi_item_to_highlight == it)
8839        sd->atspi_item_to_highlight = NULL;
8840    elm_object_accessibility_highlight_set(EO_OBJ(it), EINA_FALSE);
8841 ///TIZEN_ONLY(20170717) : expose highlight information on atspi
8842    elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
8843 ///
8844
8845    //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
8846    edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
8847    //
8848    //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
8849    // If you call eo_do_super, then you do NOT have to call smart callback.
8850    evas_object_smart_callback_call(WIDGET(it), "atspi,unhighlighted", EO_OBJ(it));
8851    //
8852
8853    return EINA_TRUE;
8854 }
8855 ///////////////////////////////////////////////////////////////////////////////
8856
8857 EOLIAN static void
8858 _elm_genlist_tree_effect_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enabled EINA_UNUSED)
8859 {
8860    // Need to implemented
8861    //sd->tree_effect_enabled = !!enabled;
8862 }
8863
8864 EOLIAN static Eina_Bool
8865 _elm_genlist_tree_effect_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
8866 {
8867    return EINA_FALSE;
8868 }
8869
8870 EOLIAN static void
8871 _elm_genlist_focus_on_selection_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED, Eina_Bool enabled)
8872 {
8873    // Need to Implemented
8874    //sd->focus_on_selection_enabled = !!enabled;
8875 }
8876
8877 EOLIAN static Eina_Bool
8878 _elm_genlist_focus_on_selection_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd EINA_UNUSED)
8879 {
8880    // Need to Implemented
8881    //return sd->focus_on_selection_enabled;
8882    return EINA_FALSE;
8883 }
8884
8885 EAPI Elm_Object_Item *
8886 elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth)
8887 {
8888    Elm_Gen_Item *it = NULL;
8889    Eina_Accessor *a;
8890    void *data;
8891
8892    ELM_GENLIST_CHECK(obj) NULL;
8893    ELM_GENLIST_DATA_GET(obj, sd);
8894
8895    if (!sd->items) return NULL;
8896
8897    a = eina_inlist_accessor_new(sd->items);
8898    if (!a) return NULL;
8899    if (eina_accessor_data_get(a, nth, &data))
8900      it = ELM_GEN_ITEM_FROM_INLIST(data);
8901    eina_accessor_free(a);
8902    return EO_OBJ(it);
8903 }
8904
8905 EAPI void
8906 elm_genlist_fx_mode_set(Evas_Object *obj, Eina_Bool mode)
8907 {
8908    ELM_GENLIST_CHECK(obj);
8909    ELM_GENLIST_DATA_GET(obj, sd);
8910
8911    sd->fx_mode = mode;
8912    return;
8913 }
8914
8915 EAPI Eina_Bool
8916 elm_genlist_fx_mode_get(const Evas_Object *obj)
8917 {
8918    ELM_GENLIST_CHECK(obj) EINA_FALSE;
8919    ELM_GENLIST_DATA_GET(obj, sd);
8920
8921    return sd->fx_mode;
8922 }
8923
8924 EAPI void
8925 elm_genlist_item_hide_set(const Elm_Object_Item *eo_item EINA_UNUSED, Eina_Bool hide EINA_UNUSED)
8926 {
8927    WRN("This API is deprecated, please use filter_set instead of this");
8928 }
8929
8930 EAPI Eina_Bool
8931 elm_genlist_item_hide_get(const Elm_Object_Item *eo_item EINA_UNUSED)
8932 {
8933    WRN("This API is deprecated, please use filter_set instead of this");
8934    return EINA_FALSE;
8935 }
8936
8937 ///////////////////////////////////////////////////////////////////////////////
8938 //TIZEN ONLY:(20150126): its not decided whether deprecated or not to give away
8939 ///////////////////////////////////////////////////////////////////////////////
8940 EAPI void
8941 elm_genlist_realization_mode_set(Evas_Object *obj, Eina_Bool realization_mode)
8942 {
8943    ELM_GENLIST_CHECK(obj);
8944    ELM_GENLIST_DATA_GET(obj, sd);
8945
8946    if (sd->realization_mode == realization_mode) return;
8947    sd->realization_mode = realization_mode;
8948 }
8949
8950 EAPI Eina_Bool
8951 elm_genlist_realization_mode_get(Evas_Object *obj)
8952 {
8953    ELM_GENLIST_CHECK(obj) EINA_FALSE;
8954    ELM_GENLIST_DATA_GET(obj, sd);
8955
8956    return sd->realization_mode;
8957 }
8958 ///////////////////////////////////////////////////////////////////////////////
8959
8960 EAPI void
8961 elm_genlist_item_reorder_start(Elm_Object_Item *eo_item)
8962 {
8963    ELM_GENLIST_ITEM_DATA_GET(eo_item, it);
8964    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8965    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
8966
8967    sd->reorder.it = it;
8968
8969    eo_do(sd->obj, elm_interface_scrollable_hold_set(EINA_TRUE));
8970    eo_do(sd->obj, elm_interface_scrollable_bounce_allow_set
8971                (EINA_FALSE, EINA_FALSE));
8972    //sd->s_iface->hold_set(sd->obj, EINA_TRUE);
8973    //sd->s_iface->bounce_allow_set(sd->obj, EINA_FALSE, EINA_FALSE);
8974    sd->reorder_force = EINA_TRUE;
8975 }
8976
8977 EAPI void
8978 elm_genlist_item_reorder_stop(Elm_Object_Item *eo_item)
8979 {
8980    ELM_GENLIST_ITEM_DATA_GET(eo_item, it);
8981    ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
8982    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
8983
8984    sd->reorder_force = EINA_FALSE;
8985 }
8986
8987 EOLIAN static void
8988 _elm_genlist_class_constructor(Eo_Class *klass)
8989 {
8990    if (_elm_config->access_mode)
8991       _elm_genlist_smart_focus_next_enable = EINA_TRUE;
8992
8993    evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
8994 }
8995
8996 EOLIAN Eina_List*
8997 _elm_genlist_elm_interface_atspi_accessible_children_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
8998 {
8999    Eina_List *ret = NULL;
9000    Elm_Gen_Item *it;
9001
9002    EINA_INLIST_FOREACH(sd->items, it)
9003       ret = eina_list_append(ret, EO_OBJ(it));
9004
9005    return ret;
9006 }
9007
9008 EOLIAN Elm_Atspi_State_Set
9009 _elm_genlist_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED)
9010 {
9011    Elm_Atspi_State_Set ret;
9012
9013    eo_do_super(obj, ELM_GENLIST_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
9014
9015    STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MANAGES_DESCENDANTS);
9016
9017    if (elm_genlist_multi_select_get(obj))
9018      STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MULTISELECTABLE);
9019
9020    return ret;
9021 }
9022
9023 EOLIAN int
9024 _elm_genlist_elm_interface_atspi_selection_selected_children_count_get(Eo *objm EINA_UNUSED, Elm_Genlist_Data *pd)
9025 {
9026    return eina_list_count(pd->selected);
9027 }
9028
9029 EOLIAN Eo*
9030 _elm_genlist_elm_interface_atspi_selection_selected_child_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_idx)
9031 {
9032    return eina_list_nth(pd->selected, child_idx);
9033 }
9034
9035 EOLIAN Eina_Bool
9036 _elm_genlist_elm_interface_atspi_selection_child_select(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9037 {
9038    Elm_Gen_Item *item;
9039    if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
9040      {
9041         EINA_INLIST_FOREACH(pd->items, item)
9042           {
9043              if (child_index-- == 0)
9044                {
9045                   elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
9046                   return EINA_TRUE;
9047                }
9048           }
9049      }
9050    return EINA_FALSE;
9051 }
9052
9053 EOLIAN Eina_Bool
9054 _elm_genlist_elm_interface_atspi_selection_selected_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9055 {
9056    Eo *item;
9057    Eina_List *l;
9058
9059    EINA_LIST_FOREACH(pd->selected, l, item)
9060      {
9061         if (child_index-- == 0)
9062           {
9063              elm_genlist_item_selected_set(item, EINA_FALSE);
9064              return EINA_TRUE;
9065           }
9066      }
9067    return EINA_FALSE;
9068 }
9069
9070 EOLIAN Eina_Bool
9071 _elm_genlist_elm_interface_atspi_selection_is_child_selected(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9072 {
9073    Elm_Gen_Item *item;
9074
9075    EINA_INLIST_FOREACH(pd->items, item)
9076      {
9077         if (child_index-- == 0)
9078           {
9079              return elm_genlist_item_selected_get(EO_OBJ(item));
9080           }
9081      }
9082    return EINA_FALSE;
9083 }
9084
9085 EOLIAN Eina_Bool
9086 _elm_genlist_elm_interface_atspi_selection_all_children_select(Eo *obj, Elm_Genlist_Data *pd)
9087 {
9088    Elm_Gen_Item *item;
9089
9090    if (!elm_genlist_multi_select_get(obj))
9091      return EINA_FALSE;
9092
9093    EINA_INLIST_FOREACH(pd->items, item)
9094       elm_genlist_item_selected_set(EO_OBJ(item), EINA_TRUE);
9095
9096    return EINA_TRUE;
9097 }
9098
9099 EOLIAN Eina_Bool
9100 _elm_genlist_elm_interface_atspi_selection_clear(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd)
9101 {
9102    return _all_items_deselect(pd);
9103 }
9104
9105 EOLIAN Eina_Bool
9106 _elm_genlist_elm_interface_atspi_selection_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlist_Data *pd, int child_index)
9107 {
9108    Elm_Gen_Item *item;
9109    if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
9110      {
9111         EINA_INLIST_FOREACH(pd->items, item)
9112           {
9113              if (child_index-- == 0)
9114                {
9115                   elm_genlist_item_selected_set(EO_OBJ(item), EINA_FALSE);
9116                   return EINA_TRUE;
9117                }
9118           }
9119      }
9120    return EINA_FALSE;
9121 }
9122
9123 // TIZEN only (20150914) : Accessibility: updated highlight change during genlist and list scroll
9124 static int _is_item_in_viewport(int viewport_y, int viewport_h, int obj_y, int obj_h)
9125 {
9126    if (obj_y + obj_h <= viewport_y)
9127      return 1;
9128    else if (obj_y >= viewport_y + viewport_h)
9129      return -1;
9130    return 0;
9131 }
9132
9133 EOLIAN static void
9134 _elm_genlist_elm_interface_scrollable_content_pos_set(Eo *obj, Elm_Genlist_Data *sid EINA_UNUSED, Evas_Coord x, Evas_Coord y, Eina_Bool sig)
9135 {
9136    if (!_elm_atspi_enabled())
9137      {
9138        eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
9139        return;
9140      }
9141
9142    int old_x, old_y, delta_y;
9143    eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_get(&old_x,&old_y));
9144    eo_do_super(obj, MY_CLASS, elm_interface_scrollable_content_pos_set(x,y,sig));
9145    delta_y = old_y - y;
9146
9147    //check if highlighted item is genlist descendant
9148    Evas_Object * highlighted_obj = _elm_object_accessibility_currently_highlighted_get();
9149    if (eo_isa(highlighted_obj, ELM_WIDGET_ITEM_CLASS))
9150      {
9151         Elm_Widget_Item_Data *id = eo_data_scope_get(highlighted_obj, ELM_WIDGET_ITEM_CLASS);
9152         highlighted_obj = id->view;
9153      }
9154
9155    Evas_Object * parent = highlighted_obj;
9156    if (eo_isa(highlighted_obj, ELM_WIDGET_CLASS))
9157      {
9158         while ((parent = elm_widget_parent_get(parent)))
9159           if (parent == obj)
9160             break;
9161      }
9162    else if (eo_isa(highlighted_obj, EDJE_OBJECT_CLASS))
9163      {
9164         while ((parent = evas_object_smart_parent_get(parent)))
9165           if (parent == obj)
9166             break;
9167      }
9168    // TIZEN_ONLY(20160805): set _accessibility_currently_highlighted_obj to NULL in object delete callback
9169    else
9170      {
9171         WRN("Improper highlighted object: %p", highlighted_obj);
9172         return;
9173      }
9174    //
9175
9176    if (parent)
9177      {
9178         int obj_x, obj_y, w, h, hx, hy, hw, hh;
9179         evas_object_geometry_get(obj, &obj_x, &obj_y, &w, &h);
9180
9181         evas_object_geometry_get(highlighted_obj, &hx, &hy, &hw, &hh);
9182
9183         Elm_Gen_Item * next_previous_item = NULL;
9184         int viewport_position_result = _is_item_in_viewport(obj_y, h, hy, hh);
9185         //only highlight if move direction is correct
9186         //sometimes highlighted item is brought in and it does not fit viewport
9187         //however content goes to the viewport position so soon it will
9188         //meet _is_item_in_viewport condition
9189         if ((viewport_position_result < 0 && delta_y > 0) ||
9190            (viewport_position_result > 0 && delta_y < 0))
9191           {
9192
9193              Eina_List *realized_items = elm_genlist_realized_items_get(obj);
9194              Eo *item;
9195              Eina_List *l;
9196              Eina_Bool traverse_direction = viewport_position_result > 0;
9197              l = traverse_direction ? realized_items: eina_list_last(realized_items);
9198
9199              while(l)
9200                {
9201                   item = eina_list_data_get(l);
9202                   ELM_GENLIST_ITEM_DATA_GET(item, it_data);
9203                   next_previous_item = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it_data));
9204                   evas_object_geometry_get(VIEW(next_previous_item), &hx, &hy, &hw, &hh);
9205                   if (_is_item_in_viewport(obj_y, h, hy, hh) == 0)
9206                     break;
9207
9208                   next_previous_item = NULL;
9209
9210                   l = traverse_direction ? eina_list_next(l): eina_list_prev(l);
9211               }
9212           }
9213         if (next_previous_item)
9214           {
9215              elm_object_accessibility_highlight_set(EO_OBJ(next_previous_item), EINA_TRUE);
9216              elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(next_previous_item), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
9217           }
9218      }
9219 }
9220 // Tizen only (20150914)
9221 #include "elm_genlist.eo.c"
9222 #include "elm_genlist_item.eo.c"