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