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