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