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