Initialize Tizen 2.3
[framework/uifw/elementary.git] / wearable / src / lib / elm_gengrid.c
1 #include <Elementary.h>
2 #include <Elementary_Cursor.h>
3 #include "elm_priv.h"
4 #include "elm_widget_gengrid.h"
5
6 // internally allocated
7 #define CLASS_ALLOCATED     0x3a70f00f
8
9 /* --
10  * TODO:
11  * Handle non-homogeneous objects too.
12  */
13
14 #define PRELOAD             1
15 #define REORDER_EFFECT_TIME 0.5
16 #define FX_MOVE_TIME 0.5
17 #define ITEM_HIGHLIGHT_TIMER 0.1
18 #define ITEM_SELECT_TIMER 0.01  // This is needed for highlight effect when item is unhighlighted right after item is highlighted and selected
19
20 typedef enum
21 {
22    FOCUS_DIR_UP = 0,
23    FOCUS_DIR_DOWN,
24    FOCUS_DIR_LEFT,
25    FOCUS_DIR_RIGHT
26 } Focus_Dir;
27
28 EAPI const char ELM_GENGRID_SMART_NAME[] = "elm_gengrid";
29 EAPI const char ELM_GENGRID_PAN_SMART_NAME[] = "elm_gengrid_pan";
30
31 #define GG_IT(_it) (_it->item)
32
33 static const Evas_Smart_Interface *_smart_interfaces[] =
34 {
35    (Evas_Smart_Interface *)&ELM_SCROLLABLE_IFACE, NULL
36 };
37
38 static const char SIG_ACTIVATED[] = "activated";
39 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
40 static const char SIG_LONGPRESSED[] = "longpressed";
41 static const char SIG_SELECTED[] = "selected";
42 static const char SIG_UNSELECTED[] = "unselected";
43 static const char SIG_REALIZED[] = "realized";
44 static const char SIG_UNREALIZED[] = "unrealized";
45 static const char SIG_CHANGED[] = "changed";
46 static const char SIG_DRAG_START_UP[] = "drag,start,up";
47 static const char SIG_DRAG_START_DOWN[] = "drag,start,down";
48 static const char SIG_DRAG_START_LEFT[] = "drag,start,left";
49 static const char SIG_DRAG_START_RIGHT[] = "drag,start,right";
50 static const char SIG_DRAG_STOP[] = "drag,stop";
51 static const char SIG_DRAG[] = "drag";
52 static const char SIG_SCROLL[] = "scroll";
53 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
54 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
55 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
56 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
57 static const char SIG_EDGE_TOP[] = "edge,top";
58 static const char SIG_EDGE_BOTTOM[] = "edge,bottom";
59 static const char SIG_EDGE_LEFT[] = "edge,left";
60 static const char SIG_EDGE_RIGHT[] = "edge,right";
61 static const char SIG_MOVED[] = "moved";
62 static const char SIG_INDEX_UPDATE[] = "index,update";
63 static const char SIG_HIGHLIGHTED[] = "highlighted";
64 static const char SIG_UNHIGHLIGHTED[] = "unhighlighted";
65 static const char SIG_LANG_CHANGED[] = "language,changed";
66 static const char SIG_PRESSED[] = "pressed";
67 static const char SIG_RELEASED[] = "released";
68 static const char SIG_ITEM_FOCUSED[] = "item,focused";
69 static const char SIG_ITEM_UNFOCUSED[] = "item,unfocused";
70
71 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
72    {SIG_ACTIVATED, ""},
73    {SIG_CLICKED_DOUBLE, ""},
74    {SIG_LONGPRESSED, ""},
75    {SIG_SELECTED, ""},
76    {SIG_UNSELECTED, ""},
77    {SIG_REALIZED, ""},
78    {SIG_UNREALIZED, ""},
79    {SIG_CHANGED, ""},
80    {SIG_DRAG_START_UP, ""},
81    {SIG_DRAG_START_DOWN, ""},
82    {SIG_DRAG_START_LEFT, ""},
83    {SIG_DRAG_START_RIGHT, ""},
84    {SIG_DRAG_STOP, ""},
85    {SIG_DRAG, ""},
86    {SIG_SCROLL, ""},
87    {SIG_SCROLL_ANIM_START, ""},
88    {SIG_SCROLL_ANIM_STOP, ""},
89    {SIG_SCROLL_DRAG_START, ""},
90    {SIG_SCROLL_DRAG_STOP, ""},
91    {SIG_EDGE_TOP, ""},
92    {SIG_EDGE_BOTTOM, ""},
93    {SIG_EDGE_LEFT, ""},
94    {SIG_EDGE_RIGHT, ""},
95    {SIG_MOVED, ""},
96    {SIG_HIGHLIGHTED, ""},
97    {SIG_UNHIGHLIGHTED, ""},
98    {SIG_LANG_CHANGED, ""},
99    {SIG_PRESSED, ""},
100    {SIG_RELEASED, ""},
101    {SIG_ITEM_FOCUSED, ""},
102    {SIG_ITEM_UNFOCUSED, ""},
103    {NULL, NULL}
104 };
105
106 EVAS_SMART_SUBCLASS_IFACE_NEW
107   (ELM_GENGRID_SMART_NAME, _elm_gengrid, Elm_Gengrid_Smart_Class,
108   Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks,
109   _smart_interfaces);
110
111 ELM_INTERNAL_SMART_SUBCLASS_NEW
112   (ELM_GENGRID_PAN_SMART_NAME, _elm_gengrid_pan, Elm_Gengrid_Pan_Smart_Class,
113   Elm_Pan_Smart_Class, elm_pan_smart_class_get, NULL);
114
115 #if GENGRID_FX_SUPPORT
116 static Eina_Bool      _elm_gengrid_fx_capture(Evas_Object *obj, int level);
117 static void           _elm_gengrid_fx_play(Evas_Object *obj);
118 #endif
119
120 static void _gengrid_item_unfocused(Elm_Gen_Item *it);
121 static void
122 _elm_gengrid_pan_smart_pos_max_get(const Evas_Object *obj,
123                                    Evas_Coord *x,
124                                    Evas_Coord *y);
125 static void
126 _elm_gengrid_pan_smart_pos_min_get(const Evas_Object *obj,
127                                    Evas_Coord *x,
128                                    Evas_Coord *y);
129 static void
130 _view_theme_update(Elm_Gen_Item *it);
131
132 static void
133 _item_mouse_down_cb(void *data,
134                     Evas *evas,
135                     Evas_Object *obj,
136                     void *event_info);
137 static void
138 _item_mouse_up_cb(void *data,
139                   Evas *evas,
140                   Evas_Object *obj __UNUSED__,
141                   void *event_info);
142
143 static void
144 _item_mouse_move_cb(void *data,
145                     Evas *evas __UNUSED__,
146                     Evas_Object *obj,
147                     void *event_info);
148
149 static void
150 _item_select(Elm_Gen_Item *it);
151
152 static void
153 _item_unselect(Elm_Gen_Item *it);
154
155 static Eina_Bool
156 _elm_gengrid_smart_translate(Evas_Object *obj)
157 {
158    evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
159
160    return EINA_TRUE;
161 }
162
163 static void
164 _item_show_region(void *data)
165 {
166    Elm_Gengrid_Smart_Data *sd = data;
167    Evas_Coord cvw, cvh, it_xpos = 0, it_ypos = 0, col = 0, row = 0, minx = 0, miny = 0;
168    Evas_Coord vw = 0, vh = 0;
169    Elm_Gen_Item *it = NULL;
170
171 #if GENGRID_FX_SUPPORT
172    if (sd->fx_first_captured) return;
173 #endif
174    evas_object_geometry_get(sd->pan_obj, NULL, NULL, &cvw, &cvh);
175
176    if ((cvw != 0) && (cvh != 0))
177        {
178           int x = 0, y = 0;
179           if (sd->show_region)
180             it = sd->show_it;
181           else if (sd->bring_in)
182             it = sd->bring_in_it;
183
184           _elm_gengrid_pan_smart_pos_min_get(sd->pan_obj, &minx, &miny);
185
186           if (sd->horizontal && (sd->item_height > 0))
187             {
188                row = cvh / sd->item_height;
189                if (row <= 0) row = 1;
190                x = it->position / row;
191                if (x == 0) y = it->position;
192                else if (x > 0) y = it->position % x;
193                if (x >= 1)
194                  it_xpos = ((x - GG_IT(it)->prev_group) * sd->item_width)
195                     + (GG_IT(it)->prev_group * sd->group_item_width)
196                     + minx;
197                else it_xpos = minx;
198                  miny = miny + ((cvh - (sd->item_height * row))
199                     * GG_IT(it)->wsd->align_y);
200                it_ypos = y * sd->item_height + miny;
201
202                it->x = x;
203                it->y = y;
204             }
205           else if (sd->item_width > 0)
206             {
207                col = cvw / sd->item_width;
208                if (col <= 0) col = 1;
209                y = it->position / col;
210                  minx = minx + ((cvw - (sd->item_width * col))
211                     * GG_IT(it)->wsd->align_x);
212                if (y == 0) x = it->position;
213                else if (y > 0) x = it->position % y;
214                it_xpos = x * sd->item_width + minx;
215                if (y >= 1)
216                  it_ypos = ((y - GG_IT(it)->prev_group) * sd->item_height)
217                     + (GG_IT(it)->prev_group * sd->group_item_height)
218                     + miny;
219                else it_ypos = miny;
220
221                it->x = x;
222                it->y = y;
223             }
224
225           switch (sd->scroll_to_type)
226             {
227                case ELM_GENGRID_ITEM_SCROLLTO_TOP:
228                   sd->s_iface->content_viewport_size_get(WIDGET(it), &vw, &vh);
229                   break;
230                case ELM_GENGRID_ITEM_SCROLLTO_MIDDLE:
231                   sd->s_iface->content_viewport_size_get(WIDGET(it), &vw, &vh);
232                   it_xpos = it_xpos - ((vw - sd->item_width) / 2);
233                   it_ypos = it_ypos - ((vh - sd->item_height) / 2);
234                   break;
235                default:
236                   vw = sd->item_width;
237                   vh = sd->item_height;
238                   break;
239             }
240
241           if (sd->show_region)
242             {
243                sd->s_iface->content_region_show(WIDGET(it),
244                                            it_xpos, it_ypos, vw, vh);
245                sd->show_region = EINA_FALSE;
246             }
247           if (sd->bring_in)
248             {
249                sd->s_iface->region_bring_in(WIDGET(it),
250                                            it_xpos, it_ypos, vw, vh);
251                sd->bring_in = EINA_FALSE;
252             }
253        }
254 }
255
256 static void
257 _calc_job(void *data)
258 {
259    Elm_Gengrid_Smart_Data *sd = data;
260    Evas_Coord minw = 0, minh = 0, nmax = 0, cvw, cvh;
261    Elm_Gen_Item *it, *group_item = NULL;
262    int count_group = 0;
263    long count = 0;
264
265    sd->items_lost = 0;
266    sd->calc_job = NULL;
267
268    evas_object_geometry_get(sd->pan_obj, NULL, NULL, &cvw, &cvh);
269
270    if ((cvw != 0) || (cvh != 0))
271      {
272         if ((sd->horizontal) && (sd->item_height > 0))
273           nmax = cvh / sd->item_height;
274         else if (sd->item_width > 0)
275           nmax = cvw / sd->item_width;
276
277         if (nmax < 1)
278           nmax = 1;
279
280         EINA_INLIST_FOREACH(sd->items, it)
281           {
282              if (GG_IT(it)->prev_group != count_group)
283                GG_IT(it)->prev_group = count_group;
284              if (it->group)
285                {
286                   count = count % nmax;
287                   if (count)
288                     sd->items_lost += nmax - count;
289                   count_group++;
290                   if (count) count = 0;
291                   group_item = it;
292                }
293              else
294                {
295                   if (it->parent != group_item)
296                     it->parent = group_item;
297                   count++;
298                }
299           }
300         count = sd->item_count + sd->items_lost - count_group;
301         if (sd->horizontal)
302           {
303              minw = (ceil(count / (float)nmax) * sd->item_width) +
304                (count_group * sd->group_item_width);
305              minh = nmax * sd->item_height;
306           }
307         else
308           {
309              minw = nmax * sd->item_width;
310              minh = (ceil(count / (float)nmax) * sd->item_height) +
311                (count_group * sd->group_item_height);
312           }
313
314         if ((minw != sd->minw) || (minh != sd->minh))
315           {
316              sd->minh = minh;
317              sd->minw = minw;
318              evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
319           }
320
321         sd->nmax = nmax;
322         evas_object_smart_changed(sd->pan_obj);
323      }
324 }
325
326 static void
327 _elm_gengrid_pan_smart_add(Evas_Object *obj)
328 {
329    /* here just to allocate our extended data */
330    EVAS_SMART_DATA_ALLOC(obj, Elm_Gengrid_Pan_Smart_Data);
331
332    ELM_PAN_CLASS(_elm_gengrid_pan_parent_sc)->base.add(obj);
333 }
334
335 static void
336 _elm_gengrid_pan_smart_move(Evas_Object *obj,
337                             Evas_Coord x __UNUSED__,
338                             Evas_Coord y __UNUSED__)
339 {
340    ELM_GENGRID_PAN_DATA_GET(obj, psd);
341
342    if (psd->wsd->calc_job) ecore_job_del(psd->wsd->calc_job);
343    _calc_job(psd->wsd);
344 }
345
346 static void
347 _elm_gengrid_pan_smart_resize(Evas_Object *obj,
348                               Evas_Coord w,
349                               Evas_Coord h)
350 {
351    Evas_Coord ow, oh;
352
353    ELM_GENGRID_PAN_DATA_GET(obj, psd);
354
355    evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
356    if ((ow == w) && (oh == h)) return;
357    if (psd->wsd->calc_job) ecore_job_del(psd->wsd->calc_job);
358    psd->wsd->calc_job = ecore_job_add(_calc_job, psd->wsd);
359 }
360
361 static void
362 _item_unhighlight(Elm_Gen_Item *it)
363 {
364    if (!it->highlighted) return;
365
366    it->highlighted = EINA_FALSE;
367
368    edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
369 //******************** TIZEN Only
370 // If check is used on gengrid item, unhighlight it also.
371    Eina_List *l;
372    Evas_Object *content;
373    EINA_LIST_FOREACH(it->content_objs, l, content)
374      {
375         const char *type = elm_widget_type_get(content);
376         if (type && !strcmp(type, "elm_check"))
377            elm_object_signal_emit(content, "elm,state,mouse,up", "elm");
378      }
379    //*******************************
380    evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, it);
381 }
382
383 static void
384 _item_unselect(Elm_Gen_Item *it)
385 {
386    Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
387
388    if (!it->selected) return;
389    if (it->generation < sd->generation) return;
390
391    it->selected = EINA_FALSE;
392    sd->selected = eina_list_remove(sd->selected, it);
393    _item_unhighlight(it);
394    evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
395 }
396
397 static void
398 _item_highlight(Elm_Gen_Item *it)
399 {
400    Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
401
402    if (!sd->highlight) return;
403    if (elm_widget_item_disabled_get(it)) return;
404    if (it->generation < GG_IT(it)->wsd->generation) return;
405    if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
406        (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
407      return;
408    if (it->highlighted) return;
409
410    it->highlighted = EINA_TRUE;
411    edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
412    edje_object_message_signal_process(VIEW(it));
413
414 //***************** TIZEN Only
415 // If check is used on gengrid item, highlight it also.
416    Eina_List *l;
417    Evas_Object *content;
418    EINA_LIST_FOREACH(it->content_objs, l, content)
419      {
420         const char *type = elm_widget_type_get(content);
421         if (elm_widget_can_focus_get(content)) sd->focused_content = content;
422         if (type && !strcmp(type, "elm_check"))
423            elm_object_signal_emit(content, "elm,state,mouse,down", "elm");
424      }
425 //****************************
426    evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it);
427 }
428
429 static Eina_Bool
430 _highlight_timer(void *data)
431 {
432    Elm_Gen_Item *it = data;
433    it->item->highlight_timer = NULL;
434    _item_highlight(it);
435    return EINA_FALSE;
436 }
437
438 static Eina_Bool
439 _select_timer(void *data)
440 {
441    Elm_Gen_Item *it = data;
442    it->item->highlight_timer = NULL;
443
444    if ((GG_IT(it)->wsd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS) ||
445        (it->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS))
446       _item_select(it);
447    else
448      {
449         if (!it->selected)_item_select(it);
450         else _item_unselect(it);
451      }
452
453    return EINA_FALSE;
454 }
455
456 static void
457 _highlight_timer_disable(Elm_Gen_Item *it)
458 {
459    if (it->item->highlight_timer)
460      {
461         ecore_timer_del(it->item->highlight_timer);
462         it->item->highlight_timer = NULL;
463      }
464 }
465
466 static void
467 _item_text_realize(Elm_Gen_Item *it,
468                    Evas_Object *target,
469                    const char *parts)
470 {
471    if (it->itc->func.text_get)
472      {
473         Eina_List *source;
474         const char *key;
475
476         source =
477           elm_widget_stringlist_get(edje_object_data_get(target, "texts"));
478         EINA_LIST_FREE(source, key)
479            {
480               if (parts && fnmatch(parts, key, FNM_PERIOD))
481                  continue;
482
483               char *s = it->itc->func.text_get
484                   ((void *)it->base.data, WIDGET(it), key);
485
486               if (s)
487                 {
488                     edje_object_part_text_escaped_set(target, key, s);
489                     free(s);
490                 }
491               else
492                 {
493                      edje_object_part_text_set(target, key, "");
494                 }
495            }
496      }
497 }
498
499 static Eina_List *
500 _item_content_realize(Elm_Gen_Item *it,
501                       Evas_Object *target,
502                       Eina_List *contents,
503                       const char *src,
504                       const char *parts)
505 {
506    if (!parts)
507      {
508         Evas_Object *c;
509         EINA_LIST_FREE(it->content_objs, c)
510           evas_object_del(c);
511      }
512    if (it->itc->func.content_get)
513      {
514         const char *key;
515         Evas_Object *ic = NULL;
516         Eina_List *source;
517
518         source = elm_widget_stringlist_get
519            (edje_object_data_get(target, src));
520
521         EINA_LIST_FREE(source, key)
522           {
523              if (parts && fnmatch(parts, key, FNM_PERIOD))
524                continue;
525
526              Evas_Object *old = edje_object_part_swallow_get(target, key);
527              if (old)
528                {
529                   contents = eina_list_remove(contents, old);
530                   evas_object_del(old);
531                }
532
533              if (it->itc->func.content_get)
534                ic = it->itc->func.content_get
535                    ((void *)it->base.data, WIDGET(it), key);
536              if (ic)
537                {
538                   if (!edje_object_part_swallow(target, key, ic))
539                     {
540                       WRN("%s (%p) can not be swallowed into %s",
541                            evas_object_type_get(ic), ic, key);
542                        continue;
543
544                     }
545                   evas_object_show(ic);
546                   elm_widget_sub_object_add(WIDGET(it), ic);
547                   contents = eina_list_append(contents, ic);
548                }
549           }
550      }
551    return contents;
552 }
553
554 static void
555 _item_state_realize(Elm_Gen_Item *it,
556                     Evas_Object *target,
557                     const char *parts)
558 {
559    if (it->itc->func.state_get)
560      {
561         Eina_List *source;
562         const char *key;
563         char buf[4096];
564
565         source =
566             elm_widget_stringlist_get(edje_object_data_get(target, "states"));
567         EINA_LIST_FREE(source, key)
568           {
569              if (parts && fnmatch(parts, key, FNM_PERIOD))
570                continue;
571
572              Eina_Bool on = it->itc->func.state_get
573                  ((void *)it->base.data, WIDGET(it), key);
574
575              if (on)
576                {
577                    snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
578                    edje_object_signal_emit(target, buf, "elm");
579                 }
580              else
581                 {
582                    snprintf(buf, sizeof(buf), "elm,state,%s,passive", key);
583                    edje_object_signal_emit(target, buf, "elm");
584                 }
585            }
586      }
587 }
588
589 static void
590 _item_mouse_move_cb(void *data,
591                     Evas *evas __UNUSED__,
592                     Evas_Object *obj,
593                     void *event_info)
594 {
595    Elm_Gen_Item *it = data;
596    Evas_Event_Mouse_Move *ev = event_info;
597    Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
598    Evas_Coord ox, oy, ow, oh, it_scrl_x, it_scrl_y;
599    Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
600    if ((sd->reorder_mode) && (sd->reorder_it == it))
601      {
602         evas_object_geometry_get
603           (sd->pan_obj, &ox, &oy, &ow, &oh);
604         it_scrl_x = ev->cur.canvas.x - sd->reorder_it->dx;
605         it_scrl_y = ev->cur.canvas.y - sd->reorder_it->dy;
606
607         if (it_scrl_x < ox) sd->reorder_item_x = ox;
608         else if (it_scrl_x + sd->item_width > ox + ow)
609           sd->reorder_item_x = ox + ow - sd->item_width;
610         else sd->reorder_item_x = it_scrl_x;
611
612         if (it_scrl_y < oy) sd->reorder_item_y = oy;
613         else if (it_scrl_y + sd->item_height > oy + oh)
614           sd->reorder_item_y = oy + oh - sd->item_height;
615         else sd->reorder_item_y = it_scrl_y;
616
617         if (sd->calc_job)
618           ecore_job_del(sd->calc_job);
619         sd->calc_job = ecore_job_add(_calc_job, sd);
620      }
621
622    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
623      {
624         if (it->item->highlight_timer)
625           {
626              ecore_timer_del(it->item->highlight_timer);
627              it->item->highlight_timer = NULL;
628           }
629         else if (!it->selected) _item_unhighlight(it);
630
631         if (it->long_timer)
632           {
633              ecore_timer_del(it->long_timer);
634              it->long_timer = NULL;
635           }
636
637         if (!it->dragging)
638           {
639              elm_coords_finger_size_adjust(1, &minw, 1, &minh);
640
641              evas_object_geometry_get(obj, &x, &y, NULL, NULL);
642              dx = ev->cur.canvas.x - x;
643              dy = ev->cur.canvas.y - y;
644              dx = dx - it->dx;
645              dy = dy - it->dy;
646              adx = dx;
647              ady = dy;
648              if (adx < 0) adx = -dx;
649              if (ady < 0) ady = -dy;
650              if ((adx > minw) || (ady > minh))
651                {
652                   it->dragging = EINA_TRUE;
653                   if (adx > ady)
654                     {
655                        if (dx < 0)
656                           evas_object_smart_callback_call
657                              (WIDGET(it), SIG_DRAG_START_LEFT, it);
658                        else
659                           evas_object_smart_callback_call
660                              (WIDGET(it), SIG_DRAG_START_RIGHT, it);
661                     }
662                   else
663                     {
664                        if (dy < 0)
665                           evas_object_smart_callback_call
666                              (WIDGET(it), SIG_DRAG_START_UP, it);
667                        else
668                           evas_object_smart_callback_call
669                              (WIDGET(it), SIG_DRAG_START_DOWN, it);
670                     }
671                }
672           }
673         if (it->dragging)
674           evas_object_smart_callback_call(WIDGET(it), SIG_DRAG, it);
675      }
676 }
677
678 static Eina_Bool
679 _long_press_cb(void *data)
680 {
681    Elm_Gen_Item *it = data,*it2;
682    Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
683    Eina_List *l, *ll;
684
685    it->long_timer = NULL;
686
687    if (elm_widget_item_disabled_get(it) ||
688        (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
689        (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
690      return ECORE_CALLBACK_CANCEL;
691
692    if ((sd->reorder_mode) && (!sd->key_down))
693      {
694         sd->reorder_it = it;
695         EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2)
696           {
697              if (it != it2) _item_unselect(it2);
698           }
699         evas_object_raise(VIEW(it));
700         sd->s_iface->hold_set(WIDGET(it), EINA_TRUE);
701         sd->s_iface->bounce_allow_get
702           (WIDGET(it), &(GG_IT(it)->wsd->old_h_bounce),
703           &(GG_IT(it)->wsd->old_v_bounce));
704
705         sd->s_iface->bounce_allow_set(WIDGET(it), EINA_FALSE, EINA_FALSE);
706         edje_object_signal_emit(VIEW(it), "elm,state,reorder,enabled", "elm");
707      }
708
709    evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
710
711    return ECORE_CALLBACK_CANCEL;
712 }
713
714 static void
715 _item_mouse_down_cb(void *data,
716                     Evas *evas,
717                     Evas_Object *obj,
718                     void *event_info)
719 {
720    Evas_Event_Mouse_Down *ev = event_info;
721    Elm_Gen_Item *it = data;
722    Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
723    Evas_Coord x, y;
724
725    // FIXME: To prevent duplicated callback call
726    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
727
728    if (ev->button != 1) return;
729    // mouse down activate only one finger touched
730    if (evas_event_down_count_get(evas) != 1) return;
731
732    evas_object_geometry_get(obj, &x, &y, NULL, NULL);
733    it->dx = ev->canvas.x - x;
734    it->dy = ev->canvas.y - y;
735
736    sd->was_selected = it->selected;
737    if (it->item->highlight_timer) ecore_timer_del(it->item->highlight_timer);
738    it->item->highlight_timer = ecore_timer_add(ITEM_HIGHLIGHT_TIMER,
739                                                _highlight_timer, it);
740    if (it->long_timer) ecore_timer_del(it->long_timer);
741    it->long_timer = ecore_timer_add(sd->longpress_timeout, _long_press_cb, it);
742
743    if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
744      {
745         evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
746         evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
747      }
748    evas_object_smart_callback_call(WIDGET(it), SIG_PRESSED, it);
749 }
750
751 static void
752 _elm_gengrid_item_unrealize(Elm_Gen_Item *it,
753                             Eina_Bool calc)
754 {
755    Evas_Object *content;
756
757    if (!it->realized) return;
758    if (GG_IT(it)->wsd->reorder_it == it) return;
759 #if GENGRID_FX_SUPPORT
760    if ((GG_IT(it)->has_proxy_it) && (!GG_IT(it)->wsd->gengrid_clearing))
761      {
762         if (!eina_list_data_find(GG_IT(it)->wsd->pending_unrealized_items, it))
763           GG_IT(it)->wsd->pending_unrealized_items =
764              eina_list_append(GG_IT(it)->wsd->pending_unrealized_items, it);
765         return;
766      }
767 #endif
768    evas_event_freeze(evas_object_evas_get(WIDGET(it)));
769    if (!calc)
770      evas_object_smart_callback_call(WIDGET(it), SIG_UNREALIZED, it);
771    if (it->long_timer)
772      {
773         ecore_timer_del(it->long_timer);
774         it->long_timer = NULL;
775      }
776
777    elm_widget_stringlist_free(it->texts);
778    it->texts = NULL;
779    elm_widget_stringlist_free(it->contents);
780    it->contents = NULL;
781    elm_widget_stringlist_free(it->states);
782    it->states = NULL;
783    EINA_LIST_FREE (it->content_objs, content)
784      evas_object_del(content);
785
786    elm_widget_item_track_cancel(it);
787
788    evas_object_event_callback_del_full
789       (VIEW(it), EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
790    evas_object_event_callback_del_full
791       (VIEW(it), EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
792    evas_object_event_callback_del_full
793       (VIEW(it), EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
794
795    it->unrealize_cb(it);
796
797    it->realized = EINA_FALSE;
798    it->want_unrealize = EINA_FALSE;
799    evas_event_thaw(evas_object_evas_get(WIDGET(it)));
800    evas_event_thaw_eval(evas_object_evas_get(WIDGET(it)));
801 }
802
803 static void
804 _item_mouse_up_cb(void *data,
805                   Evas *evas,
806                   Evas_Object *obj __UNUSED__,
807                   void *event_info)
808 {
809    Evas_Event_Mouse_Up *ev = event_info;
810    Elm_Gen_Item *it = data;
811    Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
812
813    if (ev->button != 1) return;
814
815    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
816      {
817         if (it->dragging)
818           {
819              it ->dragging = EINA_FALSE;
820              evas_object_smart_callback_call(WIDGET(it), SIG_DRAG_STOP, it);
821           }
822      }
823    if (evas_event_down_count_get(evas) != 0)
824      {
825         if (!it->item->highlight_timer) _item_unhighlight(it);
826      }
827
828    if (it->long_timer)
829      {
830         ecore_timer_del(it->long_timer);
831         it->long_timer = NULL;
832      }
833    if (it->item->highlight_timer)
834      {
835         ecore_timer_del(it->item->highlight_timer);
836         it->item->highlight_timer = NULL;
837         // Because naviframe can drop the all evevents.
838         // highlight it before select timer is called.
839         if (evas_event_down_count_get(evas) == 0) _item_highlight(it);
840      }
841    if ((sd->reorder_mode) &&
842        (sd->reorder_it == it))
843      {
844         if (!it->selected) _item_unhighlight(it);
845         evas_object_smart_callback_call
846           (WIDGET(it), SIG_MOVED, sd->reorder_it);
847         sd->reorder_it = NULL;
848         sd->move_effect_enabled = EINA_FALSE;
849         if (sd->calc_job)
850           ecore_job_del(sd->calc_job);
851         sd->calc_job =
852           ecore_job_add(_calc_job, sd);
853
854         sd->s_iface->hold_set(WIDGET(it), EINA_FALSE);
855         sd->s_iface->bounce_allow_set
856           (WIDGET(it), GG_IT(it)->wsd->old_h_bounce,
857           GG_IT(it)->wsd->old_v_bounce);
858
859         edje_object_signal_emit(VIEW(it), "elm,state,reorder,disabled", "elm");
860      }
861    else if ((evas_event_down_count_get(evas) == 0) &&
862             !(ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD))
863      {
864         // FIXME: if highlight mode is not used, mouse move cannot disable
865         // _item_select
866         if ((sd->highlight && it->highlighted) || !sd->highlight)
867           {
868              if (sd->was_selected == it->selected)
869              it->item->highlight_timer =
870                 ecore_timer_add(ITEM_SELECT_TIMER, _select_timer, it);
871           }
872      }
873    evas_object_smart_callback_call(WIDGET(it), SIG_RELEASED, it);
874 }
875
876 static void
877 _elm_gengrid_item_index_update(Elm_Gen_Item *it)
878 {
879    if (it->position_update)
880      {
881         evas_object_smart_callback_call(WIDGET(it), SIG_INDEX_UPDATE, it);
882         it->position_update = EINA_FALSE;
883      }
884 }
885
886 static void
887 _item_unrealize_cb(Elm_Gen_Item *it)
888 {
889    evas_object_del(VIEW(it));
890    VIEW(it) = NULL;
891    evas_object_del(it->spacer);
892    it->spacer = NULL;
893 }
894
895 static char *
896 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
897 {
898    Elm_Gen_Item *it = (Elm_Gen_Item *)data;
899    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, NULL);
900
901    if (it->itc->func.text_get)
902      {
903         const Eina_List *l;
904         const char *key;
905
906         if (!(it->texts)) it->texts =
907           elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
908
909         EINA_LIST_FOREACH(it->texts, l, key)
910           {
911              char *s = it->itc->func.text_get
912                 ((void *)it->base.data, WIDGET(it), key);
913              return s;
914           }
915      }
916
917    return NULL;
918 }
919
920 static char *
921 _access_state_cb(void *data, Evas_Object *obj __UNUSED__)
922 {
923    Elm_Gen_Item *it = (Elm_Gen_Item *)data;
924    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, NULL);
925
926    if (it->base.disabled)
927      return strdup(E_("State: Disabled"));
928
929    return NULL;
930 }
931
932 static void
933 _access_on_highlight_cb(void *data)
934 {
935    Evas_Coord x, y, w, h;
936    Evas_Coord sx, sy, sw, sh;
937    Elm_Gen_Item *it = (Elm_Gen_Item *)data;
938    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
939
940    ELM_GENGRID_DATA_GET(it->base.widget, sd);
941
942    evas_object_geometry_get(it->base.view, &x, &y, &w, &h);
943
944    evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, &sx, &sy, &sw, &sh);
945    if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
946      elm_gengrid_item_bring_in((Elm_Object_Item *)it,
947                                ELM_GENGRID_ITEM_SCROLLTO_IN);
948 }
949
950 static void
951 _access_activate_cb(void *data __UNUSED__,
952                     Evas_Object *part_obj __UNUSED__,
953                     Elm_Object_Item *item)
954 {
955    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
956    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
957
958    if (!_elm_util_freeze_events_get(WIDGET(item)))
959       _item_select((Elm_Gen_Item *)item);
960 }
961
962 static void
963 _access_widget_item_register(Elm_Gen_Item *it)
964 {
965    Elm_Access_Info *ai;
966
967    _elm_access_widget_item_register((Elm_Widget_Item *)it);
968
969    ai = _elm_access_object_get(it->base.access_obj);
970
971    //Tinzen only: comment out type information & state information
972    //_elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("Gengrid Item"));
973    _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
974    //_elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
975    _elm_access_on_highlight_hook_set(ai, _access_on_highlight_cb, it);
976    _elm_access_activate_callback_set(ai, _access_activate_cb, it);
977 }
978
979 // FIXME: There are applications which do not use elm_win as top widget.
980 // This is workaround! Those could not use focus!
981 static Eina_Bool _focus_enabled(Evas_Object *obj)
982 {
983    if (!elm_widget_focus_get(obj)) return EINA_FALSE;
984
985    const Evas_Object *win = elm_widget_top_get(obj);
986    const char *type = evas_object_type_get(win);
987
988    if (type && !strcmp(type, "elm_win"))
989      {
990         return elm_win_focus_highlight_enabled_get(win);
991      }
992    return EINA_FALSE;
993 }
994
995 static void
996 _view_theme_update(Elm_Gen_Item *it)
997 {
998    char style[1024];
999
1000    snprintf(style, sizeof(style), "item/%s",
1001          it->itc->item_style ? it->itc->item_style : "default");
1002    elm_widget_theme_object_set(WIDGET(it), VIEW(it), "gengrid", style,
1003                             elm_widget_style_get(WIDGET(it)));
1004    edje_object_mirrored_set(VIEW(it), elm_widget_mirrored_get(WIDGET(it)));
1005    edje_object_scale_set
1006       (VIEW(it), elm_widget_scale_get(WIDGET(it)) * elm_config_scale_get());
1007 }
1008
1009 static void
1010 _item_realize(Elm_Gen_Item *it)
1011 {
1012    char buf[1024];
1013
1014    if ((it->realized) ||
1015        (it->generation < GG_IT(it)->wsd->generation))
1016      return;
1017
1018    VIEW(it) = edje_object_add(evas_object_evas_get(WIDGET(it)));
1019    evas_object_smart_member_add(VIEW(it), GG_IT(it)->wsd->pan_obj);
1020    elm_widget_sub_object_add(WIDGET(it), VIEW(it));
1021
1022    _view_theme_update(it);
1023    it->spacer =
1024      evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
1025    evas_object_color_set(it->spacer, 0, 0, 0, 0);
1026    elm_widget_sub_object_add(WIDGET(it), it->spacer);
1027    evas_object_size_hint_min_set(it->spacer, 2 * elm_config_scale_get(), 1);
1028    edje_object_part_swallow(VIEW(it), "elm.swallow.pad", it->spacer);
1029
1030    /* access */
1031    if (_elm_config->access_mode) _access_widget_item_register(it);
1032
1033    if (it->itc->func.text_get)
1034      {
1035         const Eina_List *l;
1036         const char *key;
1037
1038         it->texts =
1039           elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
1040         EINA_LIST_FOREACH(it->texts, l, key)
1041           {
1042              char *s = it->itc->func.text_get
1043                  ((void *)it->base.data, WIDGET(it), key);
1044              if (s)
1045                {
1046                   edje_object_part_text_escaped_set(VIEW(it), key, s);
1047                   free(s);
1048                }
1049           }
1050      }
1051
1052    if (it->itc->func.content_get)
1053      {
1054         const Eina_List *l;
1055         const char *key;
1056         Evas_Object *ic = NULL;
1057
1058         it->contents = elm_widget_stringlist_get
1059             (edje_object_data_get(VIEW(it), "contents"));
1060         EINA_LIST_FOREACH(it->contents, l, key)
1061           {
1062              if (it->itc->func.content_get)
1063                ic = it->itc->func.content_get
1064                    ((void *)it->base.data, WIDGET(it), key);
1065              if (ic)
1066                {
1067                   it->content_objs = eina_list_append(it->content_objs, ic);
1068                   edje_object_part_swallow(VIEW(it), key, ic);
1069                   evas_object_show(ic);
1070                   elm_widget_sub_object_add(WIDGET(it), ic);
1071                }
1072           }
1073      }
1074
1075    if (it->itc->func.state_get)
1076      {
1077         const Eina_List *l;
1078         const char *key;
1079
1080         it->states =
1081           elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "states"));
1082         EINA_LIST_FOREACH(it->states, l, key)
1083           {
1084              Eina_Bool on = it->itc->func.state_get
1085                  ((void *)it->base.data, WIDGET(it), l->data);
1086              if (on)
1087                {
1088                   snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
1089                   edje_object_signal_emit(VIEW(it), buf, "elm");
1090                }
1091           }
1092      }
1093
1094    if (it->group)
1095      {
1096         if ((!GG_IT(it)->wsd->group_item_width)
1097             && (!GG_IT(it)->wsd->group_item_height))
1098           {
1099              edje_object_size_min_restricted_calc
1100                (VIEW(it), &GG_IT(it)->wsd->group_item_width,
1101                &GG_IT(it)->wsd->group_item_height,
1102                GG_IT(it)->wsd->group_item_width,
1103                GG_IT(it)->wsd->group_item_height);
1104           }
1105      }
1106    else
1107      {
1108         if ((!GG_IT(it)->wsd->item_width)
1109             && (!GG_IT(it)->wsd->item_height))
1110           {
1111              edje_object_size_min_restricted_calc
1112                (VIEW(it), &GG_IT(it)->wsd->item_width,
1113                &GG_IT(it)->wsd->item_height,
1114                GG_IT(it)->wsd->item_width,
1115                GG_IT(it)->wsd->item_height);
1116              elm_coords_finger_size_adjust
1117                (1, &GG_IT(it)->wsd->item_width, 1,
1118                &GG_IT(it)->wsd->item_height);
1119           }
1120
1121         evas_object_event_callback_add
1122           (VIEW(it), EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
1123         evas_object_event_callback_add
1124           (VIEW(it), EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
1125
1126         evas_object_event_callback_add
1127           (VIEW(it), EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
1128
1129         _elm_gengrid_item_index_update(it);
1130
1131         if (it->selected)
1132           edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
1133
1134         if (_focus_enabled(ELM_WIDGET_DATA(GG_IT(it)->wsd)->obj))
1135           {
1136              if (GG_IT(it)->wsd->focused)
1137                 edje_object_signal_emit (VIEW(GG_IT(it)->wsd->focused), "elm,action,focus_highlight,show", "elm");
1138           }
1139         if (elm_widget_item_disabled_get(it))
1140           edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
1141      }
1142    evas_object_show(VIEW(it));
1143
1144    if (it->tooltip.content_cb)
1145      {
1146         elm_widget_item_tooltip_content_cb_set
1147           (it, it->tooltip.content_cb, it->tooltip.data, NULL);
1148         elm_widget_item_tooltip_style_set(it, it->tooltip.style);
1149         elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
1150      }
1151
1152    if (it->mouse_cursor)
1153      elm_widget_item_cursor_set(it, it->mouse_cursor);
1154
1155    it->realized = EINA_TRUE;
1156    it->want_unrealize = EINA_FALSE;
1157 }
1158
1159 static Eina_Bool
1160 _reorder_item_move_animator_cb(void *data)
1161 {
1162    Elm_Gen_Item *it = data;
1163    Evas_Coord dx, dy;
1164    double tt, t;
1165
1166    tt = REORDER_EFFECT_TIME;
1167    t = ((0.0 > (t = ecore_loop_time_get() -
1168                   GG_IT(it)->moving_effect_start_time)) ? 0.0 : t);
1169    dx = ((GG_IT(it)->tx - GG_IT(it)->ox) / 10)
1170      * elm_config_scale_get();
1171    dy = ((GG_IT(it)->ty - GG_IT(it)->oy) / 10)
1172      * elm_config_scale_get();
1173
1174    if (t <= tt)
1175      {
1176         GG_IT(it)->rx += (1 * sin((t / tt) * (M_PI / 2)) * dx);
1177         GG_IT(it)->ry += (1 * sin((t / tt) * (M_PI / 2)) * dy);
1178      }
1179    else
1180      {
1181         GG_IT(it)->rx += dx;
1182         GG_IT(it)->ry += dy;
1183      }
1184
1185    if (((dx > 0) && (GG_IT(it)->rx >= GG_IT(it)->tx)) ||
1186         ((dx <= 0) && (GG_IT(it)->rx <= GG_IT(it)->tx))
1187        || ((dy > 0) && (GG_IT(it)->ry >= GG_IT(it)->ty)) ||
1188            ((dy <= 0) && (GG_IT(it)->ry <= GG_IT(it)->ty)))
1189      {
1190         evas_object_move(VIEW(it), GG_IT(it)->tx, GG_IT(it)->ty);
1191         if (it->group)
1192           {
1193              Evas_Coord vw, vh;
1194
1195              evas_object_geometry_get
1196                (GG_IT(it)->wsd->pan_obj, NULL, NULL, &vw, &vh);
1197              if (GG_IT(it)->wsd->horizontal)
1198                evas_object_resize
1199                  (VIEW(it), GG_IT(it)->wsd->group_item_width, vh);
1200              else
1201                evas_object_resize
1202                  (VIEW(it), vw, GG_IT(it)->wsd->group_item_height);
1203           }
1204         else
1205           evas_object_resize(VIEW(it), GG_IT(it)->wsd->item_width,
1206                              GG_IT(it)->wsd->item_height);
1207         GG_IT(it)->moving = EINA_FALSE;
1208         GG_IT(it)->item_reorder_move_animator = NULL;
1209
1210         return ECORE_CALLBACK_CANCEL;
1211      }
1212
1213    evas_object_move(VIEW(it), GG_IT(it)->rx, GG_IT(it)->ry);
1214    if (it->group)
1215      {
1216         Evas_Coord vw, vh;
1217
1218         evas_object_geometry_get
1219           (GG_IT(it)->wsd->pan_obj, NULL, NULL, &vw, &vh);
1220         if (GG_IT(it)->wsd->horizontal)
1221           evas_object_resize
1222             (VIEW(it), GG_IT(it)->wsd->group_item_width, vh);
1223         else
1224           evas_object_resize
1225             (VIEW(it), vw, GG_IT(it)->wsd->group_item_height);
1226      }
1227    else
1228      evas_object_resize
1229        (VIEW(it), GG_IT(it)->wsd->item_width,
1230        GG_IT(it)->wsd->item_height);
1231
1232    return ECORE_CALLBACK_RENEW;
1233 }
1234
1235 static void
1236 _item_place(Elm_Gen_Item *it,
1237             Evas_Coord cx,
1238             Evas_Coord cy)
1239 {
1240    Evas_Coord x, y, ox, oy, cvx, cvy, cvw, cvh, iw, ih, ww;
1241    Evas_Coord tch, tcw, alignw = 0, alignh = 0, vw, vh;
1242    Eina_Bool reorder_item_move_forward = EINA_FALSE;
1243    Elm_Gengrid_Smart_Data *wsd;
1244    Eina_Bool was_realized;
1245    Elm_Gen_Item_Type *item;
1246    long items_count;
1247
1248    item = GG_IT(it);
1249    wsd = GG_IT(it)->wsd;
1250
1251    it->x = cx;
1252    it->y = cy;
1253
1254    evas_object_geometry_get(wsd->pan_obj, &ox, &oy, &vw, &vh);
1255
1256    /* Preload rows/columns at each side of the Gengrid */
1257    cvx = ox - PRELOAD * wsd->item_width;
1258    cvy = oy - PRELOAD * wsd->item_height;
1259    cvw = vw + 2 * PRELOAD * wsd->item_width;
1260    cvh = vh + 2 * PRELOAD * wsd->item_height;
1261
1262    alignh = 0;
1263    alignw = 0;
1264
1265    items_count = wsd->item_count -
1266      eina_list_count(wsd->group_items) + wsd->items_lost;
1267    if (wsd->horizontal)
1268      {
1269         int columns, items_visible = 0, items_row;
1270
1271         if (wsd->item_height > 0)
1272           items_visible = vh / wsd->item_height;
1273         if (items_visible < 1)
1274           items_visible = 1;
1275
1276         columns = items_count / items_visible;
1277         if (items_count % items_visible)
1278           columns++;
1279
1280         tcw = (wsd->item_width * columns) + (wsd->group_item_width *
1281                                              eina_list_count(wsd->group_items));
1282         alignw = (vw - tcw) * wsd->align_x;
1283
1284         items_row = items_visible;
1285         if ((unsigned int)items_row > wsd->item_count)
1286           items_row = wsd->item_count;
1287         if (wsd->filled && (unsigned int)wsd->nmax
1288             > (unsigned int)wsd->item_count)
1289           tch = wsd->nmax * wsd->item_height;
1290         else
1291           tch = items_row * wsd->item_height;
1292         alignh = (vh - tch) * wsd->align_y;
1293         it->position = items_row * cx + cy;
1294      }
1295    else
1296      {
1297         unsigned int rows, items_visible = 0, items_col;
1298
1299         if (wsd->item_width > 0)
1300           items_visible = vw / wsd->item_width;
1301         if (items_visible < 1)
1302           items_visible = 1;
1303
1304         rows = items_count / items_visible;
1305         if (items_count % items_visible)
1306           rows++;
1307
1308         tch = (wsd->item_height * rows) + (wsd->group_item_height *
1309                                            eina_list_count(wsd->group_items));
1310         alignh = (vh - tch) * wsd->align_y;
1311
1312         items_col = items_visible;
1313         if (items_col > wsd->item_count)
1314           items_col = wsd->item_count;
1315         if (wsd->filled && (unsigned int)wsd->nmax
1316             > (unsigned int)wsd->item_count)
1317           tcw = wsd->nmax * wsd->item_width;
1318         else
1319           tcw = items_col * wsd->item_width;
1320         alignw = (vw - tcw) * wsd->align_x;
1321         it->position = cx + items_col * cy;
1322      }
1323
1324    if (it->group)
1325      {
1326         if (wsd->horizontal)
1327           {
1328              x = (((cx - item->prev_group) * wsd->item_width)
1329                   + (item->prev_group * wsd->group_item_width)) -
1330                wsd->pan_x + ox + alignw;
1331              y = oy;
1332              iw = wsd->group_item_width;
1333              ih = vh;
1334           }
1335         else
1336           {
1337              x = ox;
1338              y = (((cy - item->prev_group) * wsd->item_height)
1339                   + (item->prev_group * wsd->group_item_height))
1340                - wsd->pan_y + oy + alignh;
1341              iw = vw;
1342              ih = wsd->group_item_height;
1343           }
1344         item->gx = x;
1345         item->gy = y;
1346      }
1347    else
1348      {
1349         if (wsd->horizontal)
1350           {
1351              x = (((cx - item->prev_group) * wsd->item_width)
1352                   + (item->prev_group * wsd->group_item_width)) -
1353                wsd->pan_x + ox + alignw;
1354              y = (cy * wsd->item_height) - wsd->pan_y + oy + alignh;
1355           }
1356         else
1357           {
1358              x = (cx * wsd->item_width) - wsd->pan_x + ox + alignw;
1359              y = (((cy - item->prev_group)
1360                    * wsd->item_height) + (item->prev_group *
1361                                           wsd->group_item_height)) -
1362                wsd->pan_y + oy + alignh;
1363           }
1364         if (elm_widget_mirrored_get(WIDGET(it))) /* Switch items side
1365                                                   * and componsate for
1366                                                   * pan_x when in RTL
1367                                                   * mode */
1368           {
1369              evas_object_geometry_get(WIDGET(it), NULL, NULL, &ww, NULL);
1370              x = ww - x - wsd->item_width - wsd->pan_x - wsd->pan_x;
1371           }
1372         iw = wsd->item_width;
1373         ih = wsd->item_height;
1374      }
1375
1376    was_realized = it->realized;
1377    if (ELM_RECTS_INTERSECT(x, y, iw, ih, cvx, cvy, cvw, cvh))
1378      {
1379         _item_realize(it);
1380         if (!was_realized)
1381           evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
1382         if (it->parent)
1383           {
1384              if (wsd->horizontal)
1385                {
1386                   if (it->parent->item->gx < ox)
1387                     {
1388                        it->parent->item->gx = x + wsd->item_width -
1389                          wsd->group_item_width;
1390                        if (it->parent->item->gx > ox)
1391                          it->parent->item->gx = ox;
1392                     }
1393                   it->parent->item->group_realized = EINA_TRUE;
1394                }
1395              else
1396                {
1397                   if (it->parent->item->gy < oy)
1398                     {
1399                        it->parent->item->gy = y + wsd->item_height -
1400                          wsd->group_item_height;
1401                        if (it->parent->item->gy > oy)
1402                          it->parent->item->gy = oy;
1403                     }
1404                   it->parent->item->group_realized = EINA_TRUE;
1405                }
1406           }
1407         if (wsd->reorder_mode)
1408           {
1409              if (wsd->reorder_it)
1410                {
1411                   if (item->moving) return;
1412
1413                   if (!wsd->move_effect_enabled)
1414                     {
1415                        item->ox = x;
1416                        item->oy = y;
1417                     }
1418                   if (wsd->reorder_it == it)
1419                     {
1420                        evas_object_move(VIEW(it), wsd->reorder_item_x,
1421                                         wsd->reorder_item_y);
1422                        evas_object_resize(VIEW(it), iw, ih);
1423                        return;
1424                     }
1425                   else
1426                     {
1427                        Evas_Coord nx, ny, nw, nh;
1428
1429                        if (wsd->move_effect_enabled)
1430                          {
1431                             if ((item->ox != x) || (item->oy != y))
1432                               if (((wsd->old_pan_x == wsd->pan_x)
1433                                    && (wsd->old_pan_y == wsd->pan_y))
1434                                   || ((wsd->old_pan_x != wsd->pan_x) &&
1435                                       !(item->ox - wsd->pan_x
1436                                         + wsd->old_pan_x == x)) ||
1437                                   ((wsd->old_pan_y != wsd->pan_y) &&
1438                                    !(item->oy - wsd->pan_y +
1439                                      wsd->old_pan_y == y)))
1440                                 {
1441                                    item->tx = x;
1442                                    item->ty = y;
1443                                    item->rx = item->ox;
1444                                    item->ry = item->oy;
1445                                    item->moving = EINA_TRUE;
1446                                    item->moving_effect_start_time =
1447                                      ecore_loop_time_get();
1448                                    if (item->item_reorder_move_animator)
1449                                      ecore_animator_del
1450                                        (item->item_reorder_move_animator);
1451                                    item->item_reorder_move_animator =
1452                                      ecore_animator_add
1453                                        (_reorder_item_move_animator_cb, it);
1454                                    return;
1455                                 }
1456                          }
1457
1458                        /* need fix here */
1459                        if (it->group)
1460                          {
1461                             if (wsd->horizontal)
1462                               {
1463                                  nx = x + (wsd->group_item_width / 2);
1464                                  ny = y;
1465                                  nw = 1;
1466                                  nh = vh;
1467                               }
1468                             else
1469                               {
1470                                  nx = x;
1471                                  ny = y + (wsd->group_item_height / 2);
1472                                  nw = vw;
1473                                  nh = 1;
1474                               }
1475                          }
1476                        else
1477                          {
1478                             nx = x + (wsd->item_width / 2);
1479                             ny = y + (wsd->item_height / 2);
1480                             nw = 1;
1481                             nh = 1;
1482                          }
1483
1484                        if (ELM_RECTS_INTERSECT
1485                              (wsd->reorder_item_x, wsd->reorder_item_y,
1486                              wsd->item_width, wsd->item_height,
1487                              nx, ny, nw, nh))
1488                          {
1489                             if (wsd->horizontal)
1490                               {
1491                                  if ((wsd->nmax * wsd->reorder_it->x +
1492                                       wsd->reorder_it->y) >
1493                                      (wsd->nmax * it->x + it->y))
1494                                    reorder_item_move_forward = EINA_TRUE;
1495                               }
1496                             else
1497                               {
1498                                  if ((wsd->nmax * wsd->reorder_it->y +
1499                                       wsd->reorder_it->x) >
1500                                      (wsd->nmax * it->y + it->x))
1501                                    reorder_item_move_forward = EINA_TRUE;
1502                               }
1503
1504                             wsd->items = eina_inlist_remove
1505                                 (wsd->items,
1506                                 EINA_INLIST_GET(wsd->reorder_it));
1507                             if (reorder_item_move_forward)
1508                               wsd->items = eina_inlist_prepend_relative
1509                                   (wsd->items,
1510                                   EINA_INLIST_GET(wsd->reorder_it),
1511                                   EINA_INLIST_GET(it));
1512                             else
1513                               wsd->items = eina_inlist_append_relative
1514                                   (wsd->items,
1515                                   EINA_INLIST_GET(wsd->reorder_it),
1516                                   EINA_INLIST_GET(it));
1517
1518                             wsd->reorder_item_changed = EINA_TRUE;
1519                             wsd->move_effect_enabled = EINA_TRUE;
1520                             if (wsd->calc_job)
1521                               ecore_job_del(wsd->calc_job);
1522                             wsd->calc_job =
1523                               ecore_job_add(_calc_job, wsd);
1524
1525                             return;
1526                          }
1527                     }
1528                }
1529              else if (item->item_reorder_move_animator)
1530                {
1531                   ecore_animator_del
1532                     (item->item_reorder_move_animator);
1533                   item->item_reorder_move_animator = NULL;
1534                   item->moving = EINA_FALSE;
1535                }
1536           }
1537 #if GENGRID_FX_SUPPORT
1538         GG_IT(it)->scrl_x = x;
1539         GG_IT(it)->scrl_y = y;
1540         GG_IT(it)->w = iw;
1541         GG_IT(it)->h = ih;
1542 #endif
1543         if (it->group) item->group_realized = EINA_TRUE;
1544         evas_object_move(VIEW(it), x, y);
1545         evas_object_resize(VIEW(it), iw, ih);
1546      }
1547    else
1548      {
1549         if (!it->group)
1550           _elm_gengrid_item_unrealize(it, EINA_FALSE);
1551         else
1552           item->group_realized = EINA_FALSE;
1553      }
1554 }
1555
1556 static void
1557 _group_item_place(Elm_Gengrid_Pan_Smart_Data *psd)
1558 {
1559    Evas_Coord iw, ih, vw, vh;
1560    Eina_Bool was_realized;
1561    Elm_Gen_Item *it;
1562    Eina_List *l;
1563
1564    evas_object_geometry_get(psd->wsd->pan_obj, NULL, NULL, &vw, &vh);
1565    if (psd->wsd->horizontal)
1566      {
1567         iw = psd->wsd->group_item_width;
1568         ih = vh;
1569      }
1570    else
1571      {
1572         iw = vw;
1573         ih = psd->wsd->group_item_height;
1574      }
1575    EINA_LIST_FOREACH(psd->wsd->group_items, l, it)
1576      {
1577         was_realized = it->realized;
1578         if (GG_IT(it)->group_realized)
1579           {
1580              _item_realize(it);
1581              if (!was_realized)
1582                evas_object_smart_callback_call(WIDGET(it), SIG_REALIZED, it);
1583              //Need to update the correct coordenates for group index fo fx use.
1584              GG_IT(it)->scrl_x = GG_IT(it)->gx;
1585              GG_IT(it)->scrl_y = GG_IT(it)->gy;
1586              evas_object_move
1587                (VIEW(it), GG_IT(it)->gx,
1588                GG_IT(it)->gy);
1589              evas_object_resize(VIEW(it), iw, ih);
1590              evas_object_raise(VIEW(it));
1591           }
1592         else
1593           _elm_gengrid_item_unrealize(it, EINA_FALSE);
1594      }
1595 }
1596
1597 static void
1598 _elm_gengrid_pan_smart_calculate(Evas_Object *obj)
1599 {
1600    Evas_Coord cx = 0, cy = 0;
1601    Elm_Gen_Item *it;
1602
1603    ELM_GENGRID_PAN_DATA_GET(obj, psd);
1604
1605 #if GENGRID_FX_SUPPORT
1606    if (psd->wsd->fx_playing) return;
1607 #endif
1608
1609    if (!psd->wsd->nmax) return;
1610
1611    psd->wsd->reorder_item_changed = EINA_FALSE;
1612
1613    EINA_INLIST_FOREACH(psd->wsd->items, it)
1614      {
1615         if (it->group)
1616           {
1617              if (psd->wsd->horizontal)
1618                {
1619                   if (cy)
1620                     {
1621                        cx++;
1622                        cy = 0;
1623                     }
1624                }
1625              else
1626                {
1627                   if (cx)
1628                     {
1629                        cx = 0;
1630                        cy++;
1631                     }
1632                }
1633           }
1634         _item_place(it, cx, cy);
1635         if (psd->wsd->reorder_item_changed) return;
1636         if (it->group)
1637           {
1638              if (psd->wsd->horizontal)
1639                {
1640                   cx++;
1641                   cy = 0;
1642                }
1643              else
1644                {
1645                   cx = 0;
1646                   cy++;
1647                }
1648           }
1649         else
1650           {
1651              if (psd->wsd->horizontal)
1652                {
1653                   cy = (cy + 1) % psd->wsd->nmax;
1654                   if (!cy) cx++;
1655                }
1656              else
1657                {
1658                   cx = (cx + 1) % psd->wsd->nmax;
1659                   if (!cx) cy++;
1660                }
1661           }
1662      }
1663    _group_item_place(psd);
1664
1665    if ((psd->wsd->reorder_mode) && (psd->wsd->reorder_it))
1666      {
1667         if (!psd->wsd->reorder_item_changed)
1668           {
1669              psd->wsd->old_pan_x = psd->wsd->pan_x;
1670              psd->wsd->old_pan_y = psd->wsd->pan_y;
1671           }
1672         psd->wsd->move_effect_enabled = EINA_FALSE;
1673      }
1674    evas_object_smart_callback_call
1675      (ELM_WIDGET_DATA(psd->wsd)->obj, SIG_CHANGED, NULL);
1676    if ((psd->wsd->show_region || psd->wsd->bring_in))
1677      _item_show_region(psd->wsd);
1678
1679 #if GENGRID_FX_SUPPORT
1680    psd->wsd->rendered = EINA_TRUE;
1681    if (psd->wsd->fx_mode)
1682      {
1683         if (_elm_gengrid_fx_capture(ELM_WIDGET_DATA(psd->wsd)->obj, 1))
1684           _elm_gengrid_fx_play(ELM_WIDGET_DATA(psd->wsd)->obj);
1685      }
1686 #endif
1687 }
1688
1689 static void
1690 _elm_gengrid_pan_smart_pos_set(Evas_Object *obj,
1691                                Evas_Coord x,
1692                                Evas_Coord y)
1693 {
1694    ELM_GENGRID_PAN_DATA_GET(obj, psd);
1695
1696    if ((x == psd->wsd->pan_x) && (y == psd->wsd->pan_y)) return;
1697    psd->wsd->pan_x = x;
1698    psd->wsd->pan_y = y;
1699    evas_object_smart_changed(obj);
1700 }
1701
1702 static void
1703 _elm_gengrid_pan_smart_pos_get(const Evas_Object *obj,
1704                                Evas_Coord *x,
1705                                Evas_Coord *y)
1706 {
1707    ELM_GENGRID_PAN_DATA_GET(obj, psd);
1708
1709    if (x) *x = psd->wsd->pan_x;
1710    if (y) *y = psd->wsd->pan_y;
1711 }
1712
1713 static void
1714 _elm_gengrid_pan_smart_content_size_get(const Evas_Object *obj,
1715                                         Evas_Coord *w,
1716                                         Evas_Coord *h)
1717 {
1718    ELM_GENGRID_PAN_DATA_GET(obj, psd);
1719
1720    if (w) *w = psd->wsd->minw;
1721    if (h) *h = psd->wsd->minh;
1722 }
1723
1724 static void
1725 _elm_gengrid_pan_smart_pos_max_get(const Evas_Object *obj,
1726                                    Evas_Coord *x,
1727                                    Evas_Coord *y)
1728 {
1729    Evas_Coord ow, oh;
1730
1731    ELM_GENGRID_PAN_DATA_GET(obj, psd);
1732
1733    evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
1734    if (x)
1735      *x = (ow < psd->wsd->minw) ? psd->wsd->minw - ow : 0;
1736    if (y)
1737      *y = (oh < psd->wsd->minh) ? psd->wsd->minh - oh : 0;
1738 }
1739
1740 static void
1741 _elm_gengrid_pan_smart_pos_min_get(const Evas_Object *obj,
1742                                    Evas_Coord *x,
1743                                    Evas_Coord *y)
1744 {
1745    Evas_Coord mx = 0, my = 0;
1746
1747    ELM_GENGRID_PAN_DATA_GET(obj, psd);
1748
1749    _elm_gengrid_pan_smart_pos_max_get(obj, &mx, &my);
1750    if (x)
1751      *x = -mx * psd->wsd->align_x;
1752    if (y)
1753      *y = -my * psd->wsd->align_y;
1754 }
1755
1756 static void
1757 _elm_gengrid_pan_smart_set_user(Elm_Gengrid_Pan_Smart_Class *sc)
1758 {
1759    ELM_PAN_CLASS(sc)->base.add = _elm_gengrid_pan_smart_add;
1760    ELM_PAN_CLASS(sc)->base.move = _elm_gengrid_pan_smart_move;
1761    ELM_PAN_CLASS(sc)->base.resize = _elm_gengrid_pan_smart_resize;
1762    ELM_PAN_CLASS(sc)->base.calculate = _elm_gengrid_pan_smart_calculate;
1763
1764    ELM_PAN_CLASS(sc)->pos_set = _elm_gengrid_pan_smart_pos_set;
1765    ELM_PAN_CLASS(sc)->pos_get = _elm_gengrid_pan_smart_pos_get;
1766    ELM_PAN_CLASS(sc)->pos_max_get = _elm_gengrid_pan_smart_pos_max_get;
1767    ELM_PAN_CLASS(sc)->pos_min_get = _elm_gengrid_pan_smart_pos_min_get;
1768    ELM_PAN_CLASS(sc)->content_size_get =
1769      _elm_gengrid_pan_smart_content_size_get;
1770
1771 }
1772
1773 static Eina_Bool
1774 _item_multi_select_left(Elm_Gengrid_Smart_Data *sd)
1775 {
1776    Elm_Object_Item *prev;
1777
1778    if (!sd->selected) return EINA_FALSE;
1779
1780    prev = elm_gengrid_item_prev_get(sd->last_selected_item);
1781    if (!prev) return EINA_TRUE;
1782
1783    if (elm_gengrid_item_selected_get(prev))
1784      {
1785         elm_gengrid_item_selected_set(sd->last_selected_item, EINA_FALSE);
1786         sd->last_selected_item = prev;
1787         elm_gengrid_item_show
1788           (sd->last_selected_item, ELM_GENGRID_ITEM_SCROLLTO_IN);
1789      }
1790    else
1791      {
1792         elm_gengrid_item_selected_set(prev, EINA_TRUE);
1793         elm_gengrid_item_show(prev, ELM_GENGRID_ITEM_SCROLLTO_IN);
1794      }
1795
1796    return EINA_TRUE;
1797 }
1798
1799 static Eina_Bool
1800 _item_multi_select_right(Elm_Gengrid_Smart_Data *sd)
1801 {
1802    Elm_Object_Item *next;
1803
1804    if (!sd->selected) return EINA_FALSE;
1805
1806    next = elm_gengrid_item_next_get(sd->last_selected_item);
1807    if (!next) return EINA_TRUE;
1808
1809    if (elm_gengrid_item_selected_get(next))
1810      {
1811         elm_gengrid_item_selected_set(sd->last_selected_item, EINA_FALSE);
1812         sd->last_selected_item = next;
1813         elm_gengrid_item_show
1814           (sd->last_selected_item, ELM_GENGRID_ITEM_SCROLLTO_IN);
1815      }
1816    else
1817      {
1818         elm_gengrid_item_selected_set(next, EINA_TRUE);
1819         elm_gengrid_item_show(next, ELM_GENGRID_ITEM_SCROLLTO_IN);
1820      }
1821
1822    return EINA_TRUE;
1823 }
1824
1825 static Eina_Bool
1826 _item_multi_select_up(Elm_Gengrid_Smart_Data *sd)
1827 {
1828    unsigned int i;
1829    Eina_Bool r = EINA_TRUE;
1830
1831    if (!sd->selected) return EINA_FALSE;
1832
1833    for (i = 0; (r) && (i < sd->nmax); i++)
1834      r &= _item_multi_select_left(sd);
1835
1836    return r;
1837 }
1838
1839 static Eina_Bool
1840 _item_multi_select_down(Elm_Gengrid_Smart_Data *sd)
1841 {
1842    unsigned int i;
1843    Eina_Bool r = EINA_TRUE;
1844
1845    if (!sd->selected) return EINA_FALSE;
1846
1847    for (i = 0; (r) && (i < sd->nmax); i++)
1848      r &= _item_multi_select_right(sd);
1849
1850    return r;
1851 }
1852
1853 static Eina_Bool
1854 _all_items_deselect(Elm_Gengrid_Smart_Data *sd)
1855 {
1856    if (!sd->selected) return EINA_FALSE;
1857
1858    while (sd->selected)
1859      elm_gengrid_item_selected_set
1860        ((Elm_Object_Item *)sd->selected->data, EINA_FALSE);
1861
1862    return EINA_TRUE;
1863 }
1864
1865 static Eina_Bool
1866 _item_single_select_up(Elm_Gengrid_Smart_Data *sd)
1867 {
1868    unsigned int i;
1869    Elm_Gen_Item *prev;
1870
1871    if (!sd->selected)
1872      {
1873         prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
1874         while ((prev) && (prev->generation < sd->generation))
1875           prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
1876         elm_gengrid_item_selected_set((Elm_Object_Item *)prev, EINA_TRUE);
1877         elm_gengrid_item_show
1878           ((Elm_Object_Item *)prev, ELM_GENGRID_ITEM_SCROLLTO_IN);
1879         return EINA_TRUE;
1880      }
1881    else
1882      prev = (Elm_Gen_Item *)elm_gengrid_item_prev_get(sd->last_selected_item);
1883
1884    if (!prev) return EINA_FALSE;
1885
1886    for (i = 1; i < sd->nmax; i++)
1887      {
1888         Elm_Object_Item *tmp =
1889           elm_gengrid_item_prev_get((Elm_Object_Item *)prev);
1890         if (!tmp) return EINA_FALSE;
1891         prev = (Elm_Gen_Item *)tmp;
1892      }
1893
1894    _all_items_deselect(sd);
1895
1896    elm_gengrid_item_selected_set((Elm_Object_Item *)prev, EINA_TRUE);
1897    elm_gengrid_item_show
1898      ((Elm_Object_Item *)prev, ELM_GENGRID_ITEM_SCROLLTO_IN);
1899    return EINA_TRUE;
1900 }
1901
1902 static Eina_Bool
1903 _item_single_select_down(Elm_Gengrid_Smart_Data *sd)
1904 {
1905    unsigned int i;
1906    Elm_Gen_Item *next;
1907
1908    if (!sd->selected)
1909      {
1910         next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
1911         while ((next) && (next->generation < sd->generation))
1912           next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
1913         elm_gengrid_item_selected_set((Elm_Object_Item *)next, EINA_TRUE);
1914         elm_gengrid_item_show
1915           ((Elm_Object_Item *)next, ELM_GENGRID_ITEM_SCROLLTO_IN);
1916         return EINA_TRUE;
1917      }
1918    else
1919      next = (Elm_Gen_Item *)elm_gengrid_item_next_get(sd->last_selected_item);
1920
1921    if (!next) return EINA_FALSE;
1922
1923    for (i = 1; i < sd->nmax; i++)
1924      {
1925         Elm_Object_Item *tmp =
1926           elm_gengrid_item_next_get((Elm_Object_Item *)next);
1927         if (!tmp) return EINA_FALSE;
1928         next = (Elm_Gen_Item *)tmp;
1929      }
1930
1931    _all_items_deselect(sd);
1932
1933    elm_gengrid_item_selected_set((Elm_Object_Item *)next, EINA_TRUE);
1934    elm_gengrid_item_show
1935      ((Elm_Object_Item *)next, ELM_GENGRID_ITEM_SCROLLTO_IN);
1936
1937    return EINA_TRUE;
1938 }
1939
1940 static Eina_Bool
1941 _item_single_select_left(Elm_Gengrid_Smart_Data *sd)
1942 {
1943    Elm_Gen_Item *prev;
1944
1945    if (!sd->selected)
1946      {
1947         prev = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
1948         while ((prev) && (prev->generation < sd->generation))
1949           prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
1950      }
1951    else
1952      prev = (Elm_Gen_Item *)elm_gengrid_item_prev_get(sd->last_selected_item);
1953
1954    if (!prev) return EINA_FALSE;
1955
1956    _all_items_deselect(sd);
1957
1958    elm_gengrid_item_selected_set((Elm_Object_Item *)prev, EINA_TRUE);
1959    elm_gengrid_item_show
1960      ((Elm_Object_Item *)prev, ELM_GENGRID_ITEM_SCROLLTO_IN);
1961
1962    return EINA_TRUE;
1963 }
1964
1965 static Eina_Bool
1966 _item_single_select_right(Elm_Gengrid_Smart_Data *sd)
1967 {
1968    Elm_Gen_Item *next;
1969
1970    if (!sd->selected)
1971      {
1972         next = ELM_GEN_ITEM_FROM_INLIST(sd->items);
1973         while ((next) && (next->generation < sd->generation))
1974           next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
1975      }
1976    else
1977      next = (Elm_Gen_Item *)elm_gengrid_item_next_get(sd->last_selected_item);
1978
1979    if (!next) return EINA_FALSE;
1980
1981    _all_items_deselect(sd);
1982
1983    elm_gengrid_item_selected_set((Elm_Object_Item *)next, EINA_TRUE);
1984    elm_gengrid_item_show
1985      ((Elm_Object_Item *)next, ELM_GENGRID_ITEM_SCROLLTO_IN);
1986
1987    return EINA_TRUE;
1988 }
1989
1990 static void _gengrid_item_unfocused(Elm_Gen_Item *it)
1991 {
1992    if (!it) return;
1993    Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
1994    if (!sd->focused) return;
1995
1996    if (sd->focused_content)
1997      {
1998         elm_object_focus_set(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
1999         elm_object_focus_set(ELM_WIDGET_DATA(sd)->obj, EINA_TRUE);
2000         sd->focused_content = NULL;
2001      }
2002    edje_object_signal_emit
2003       (VIEW(sd->focused), "elm,action,focus_highlight,hide", "elm");
2004
2005    if (it == sd->focused) sd->focused = NULL;
2006    evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_UNFOCUSED, it);
2007 }
2008
2009 static void _gengrid_item_focused(Elm_Gen_Item *it, Elm_Gengrid_Item_Scrollto_Type type)
2010 {
2011    if (!it) return;
2012    Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
2013    Evas_Coord x, y, w, h, sx, sy, sw, sh;
2014
2015    if (sd->focused && (it != sd->focused)) _gengrid_item_unfocused(sd->focused);
2016    evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
2017    evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, &sx, &sy, &sw, &sh);
2018    if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
2019      {
2020         elm_gengrid_item_bring_in((Elm_Object_Item *)it, type);
2021      }
2022
2023    if (_focus_enabled(ELM_WIDGET_DATA(sd)->obj))
2024      edje_object_signal_emit
2025        (VIEW(it), "elm,action,focus_highlight,show", "elm");
2026
2027    sd->focused = it;
2028    evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_FOCUSED, it);
2029 }
2030
2031 static Elm_Gen_Item *_gengrid_item_focusable_search(Elm_Gen_Item *it, int dir)
2032 {
2033    if (!it) return NULL;
2034    Elm_Gen_Item *tmp = it;
2035    Elm_Gengrid_Smart_Data *sd;
2036    sd = GG_IT(it)->wsd;
2037
2038    if (dir == 1)
2039      while (tmp && (tmp->generation <= sd->generation))
2040        {
2041           if (!elm_object_item_disabled_get((Elm_Object_Item *)tmp) &&
2042               ((tmp->select_mode == ELM_OBJECT_SELECT_MODE_DEFAULT) ||
2043                (tmp->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS)))
2044             break;
2045           tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->next);
2046        }
2047    else
2048      while (tmp && (tmp->generation <= sd->generation))
2049        {
2050           if (!elm_object_item_disabled_get((Elm_Object_Item *)tmp) &&
2051               ((tmp->select_mode == ELM_OBJECT_SELECT_MODE_DEFAULT) ||
2052                (tmp->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS)))
2053             break;
2054           tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
2055        }
2056
2057    return tmp;
2058 }
2059
2060 static Eina_Bool _gengrid_item_focused_next(Elm_Gengrid_Smart_Data *sd, Focus_Dir dir)
2061 {
2062    Elm_Gen_Item *it = NULL;
2063    Evas_Coord cvw, cvh, dist = 0;
2064    Elm_Gen_Item *old_focused = sd->focused;
2065    int i = 0;
2066
2067    evas_object_geometry_get(sd->pan_obj, NULL, NULL, &cvw, &cvh);
2068
2069    if (dir == FOCUS_DIR_DOWN || dir == FOCUS_DIR_UP)
2070      {
2071         if ((!sd->horizontal) && (sd->item_width > 0))
2072            dist = cvw / sd->item_width;
2073         else dist = 1;
2074         if (dist <= 0) dist = 1;
2075
2076         if (dir == FOCUS_DIR_DOWN)
2077           {
2078              if (sd->focused)
2079                {
2080                   it = sd->focused;
2081                   if (it->group) dist = 1;
2082                   for (i = 0; i < dist; i++)
2083                      {
2084                         it = ELM_GEN_ITEM_FROM_INLIST
2085                            (EINA_INLIST_GET(it)->next);
2086                         if (!it) break;
2087                         else if (it->group) break;
2088                      }
2089                   _gengrid_item_unfocused(sd->focused);
2090                }
2091              else it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2092              it = _gengrid_item_focusable_search(it, 1);
2093           }
2094         else if (dir == FOCUS_DIR_UP)
2095           {
2096              if (sd->focused)
2097                {
2098                   it = sd->focused;
2099                   if (it->group) dist = 1;
2100                   for (i = 0; i < dist; i++)
2101                      {
2102                         it = ELM_GEN_ITEM_FROM_INLIST
2103                            (EINA_INLIST_GET(it)->prev);
2104                         if (!it) break;
2105                         else if (it->group) break;
2106                      }
2107                   _gengrid_item_unfocused(sd->focused);
2108                }
2109              else it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2110              it = _gengrid_item_focusable_search(it, -1);
2111           }
2112         if (!it)
2113           {
2114              if (old_focused) _gengrid_item_focused(old_focused, ELM_GENGRID_ITEM_SCROLLTO_IN);
2115              return EINA_FALSE;
2116           }
2117         _gengrid_item_focused(it, ELM_GENGRID_ITEM_SCROLLTO_IN);
2118      }
2119    else if (dir == FOCUS_DIR_LEFT || dir == FOCUS_DIR_RIGHT)
2120      {
2121         if (sd->horizontal && (sd->item_height > 0))
2122            dist = cvh / sd->item_height;
2123         else dist = 1;
2124         if (dist <= 0) dist = 1;
2125
2126         if (dir == FOCUS_DIR_LEFT)
2127           {
2128              if (sd->focused)
2129                {
2130                   it = sd->focused;
2131                   for (i = 0; i < dist; i++)
2132                      {
2133                         it = ELM_GEN_ITEM_FROM_INLIST
2134                            (EINA_INLIST_GET(it)->prev);
2135                         if (!it) break;
2136                         else if (it->group) break;
2137                      }
2138                   _gengrid_item_unfocused(sd->focused);
2139                }
2140              else it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2141              it = _gengrid_item_focusable_search(it, -1);
2142           }
2143         else if (dir == FOCUS_DIR_RIGHT)
2144           {
2145              if (sd->focused)
2146                {
2147                   it = sd->focused;
2148                   for (i = 0; i < dist; i++)
2149                      {
2150                         it = ELM_GEN_ITEM_FROM_INLIST
2151                            (EINA_INLIST_GET(it)->next);
2152                         if (!it) break;
2153                         else if (it->group) break;
2154                      }
2155                   _gengrid_item_unfocused(sd->focused);
2156                }
2157              else it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2158              it = _gengrid_item_focusable_search(it, 1);
2159           }
2160         if (!it)
2161           {
2162              if (old_focused) _gengrid_item_focused(old_focused, ELM_GENGRID_ITEM_SCROLLTO_IN);
2163              return EINA_FALSE;
2164           }
2165         _gengrid_item_focused(it, ELM_GENGRID_ITEM_SCROLLTO_IN);
2166      }
2167    else return EINA_FALSE;
2168
2169    return EINA_TRUE;
2170 }
2171
2172 static Eina_Bool
2173 _elm_gengrid_smart_event(Evas_Object *obj,
2174                          Evas_Object *src __UNUSED__,
2175                          Evas_Callback_Type type,
2176                          void *event_info)
2177 {
2178    Evas_Coord x = 0;
2179    Evas_Coord y = 0;
2180    Evas_Coord v_w = 0;
2181    Evas_Coord v_h = 0;
2182    Evas_Coord step_x = 0;
2183    Evas_Coord step_y = 0;
2184    Evas_Coord page_x = 0;
2185    Evas_Coord page_y = 0;
2186    Evas_Event_Key_Down *ev = event_info;
2187
2188    ELM_GENGRID_DATA_GET(obj, sd);
2189
2190    if (type != EVAS_CALLBACK_KEY_DOWN && type != EVAS_CALLBACK_KEY_UP)
2191      return EINA_FALSE;
2192    if (!sd->items) return EINA_FALSE;
2193    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
2194    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
2195    if (!_focus_enabled(obj)) return EINA_FALSE;
2196
2197    sd->s_iface->content_pos_get(obj, &x, &y);
2198    sd->s_iface->step_size_get(obj, &step_x, &step_y);
2199    sd->s_iface->page_size_get(obj, &page_x, &page_y);
2200    sd->s_iface->content_viewport_size_get(obj, &v_w, &v_h);
2201
2202 #ifdef ELM_FOCUSED_UI
2203    if ((!strcmp(ev->keyname, "Left")) ||
2204        ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
2205      {
2206         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2207         if (sd->select_on_focus_enabled)
2208           {
2209              if ((sd->horizontal) &&
2210                       (((evas_key_modifier_is_set(ev->modifiers, "Shift"))
2211                       && (_item_multi_select_up(sd)))
2212                       || (_item_single_select_up(sd))))
2213                {
2214                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2215                   return EINA_TRUE;
2216                }
2217              else if ((!sd->horizontal) &&
2218                       (((evas_key_modifier_is_set(ev->modifiers, "Shift"))
2219                       && (_item_multi_select_left(sd)))
2220                       || (_item_single_select_left(sd))))
2221                {
2222                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2223                   return EINA_TRUE;
2224                }
2225              else
2226                {
2227                   x -= step_x;
2228                }
2229           }
2230         else
2231           {
2232              if (_gengrid_item_focused_next(sd, FOCUS_DIR_LEFT))
2233                {
2234                    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2235                    return EINA_TRUE;
2236                }
2237              else
2238                {
2239                   return EINA_FALSE;
2240                }
2241           }
2242         }
2243    else if ((!strcmp(ev->keyname, "Right")) ||
2244             ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
2245      {
2246         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2247         if (sd->select_on_focus_enabled)
2248           {
2249              if ((sd->horizontal) &&
2250                       (((evas_key_modifier_is_set(ev->modifiers, "Shift"))
2251                       && (_item_multi_select_down(sd)))
2252                       || (_item_single_select_down(sd))))
2253                {
2254                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2255                   return EINA_TRUE;
2256                }
2257              else if ((!sd->horizontal) &&
2258                       (((evas_key_modifier_is_set(ev->modifiers, "Shift"))
2259                       && (_item_multi_select_right(sd)))
2260                       || (_item_single_select_right(sd))))
2261                {
2262                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2263                   return EINA_TRUE;
2264                }
2265              else
2266                {
2267                   x += step_x;
2268                }
2269           }
2270         else
2271           {
2272              if (_gengrid_item_focused_next(sd, FOCUS_DIR_RIGHT))
2273                {
2274                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2275                   return EINA_TRUE;
2276                }
2277              else
2278                {
2279                   return EINA_FALSE;
2280                }
2281           }
2282      }
2283    else if ((!strcmp(ev->keyname, "Up")) ||
2284             ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
2285      {
2286         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2287         if (sd->select_on_focus_enabled)
2288           {
2289              if ((sd->horizontal) &&
2290                       (((evas_key_modifier_is_set(ev->modifiers, "Shift"))
2291                       && (_item_multi_select_left(sd)))
2292                       || (_item_single_select_left(sd))))
2293                {
2294                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2295                   return EINA_TRUE;
2296                }
2297              else if ((!sd->horizontal) &&
2298                       (((evas_key_modifier_is_set(ev->modifiers, "Shift"))
2299                       && (_item_multi_select_up(sd)))
2300                       || (_item_single_select_up(sd))))
2301                {
2302                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2303                   return EINA_TRUE;
2304                }
2305              else
2306                {
2307                   y -= step_y;
2308                }
2309           }
2310         else
2311           {
2312              if (_gengrid_item_focused_next(sd, FOCUS_DIR_UP))
2313                {
2314                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2315                   return EINA_TRUE;
2316                }
2317              else
2318                {
2319                   return EINA_FALSE;
2320                }
2321           }
2322      }
2323    else if ((!strcmp(ev->keyname, "Down")) ||
2324             ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
2325      {
2326         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2327         if (sd->select_on_focus_enabled)
2328           {
2329              if ((sd->horizontal) &&
2330                    (((evas_key_modifier_is_set(ev->modifiers, "Shift"))
2331                    && (_item_multi_select_right(sd)))
2332                    || (_item_single_select_right(sd))))
2333                {
2334                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2335                   return EINA_TRUE;
2336                }
2337              else if ((!sd->horizontal) &&
2338                       (((evas_key_modifier_is_set(ev->modifiers, "Shift"))
2339                       && (_item_multi_select_down(sd)))
2340                       || (_item_single_select_down(sd))))
2341                {
2342                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2343                   return EINA_TRUE;
2344                }
2345              else
2346                {
2347                   y += step_y;
2348                }
2349           }
2350         else
2351           {
2352              if (_gengrid_item_focused_next(sd, FOCUS_DIR_DOWN))
2353                {
2354                   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2355                   return EINA_TRUE;
2356                }
2357              else
2358                {
2359                   return EINA_FALSE;
2360                }
2361           }
2362      }
2363    else if ((!strcmp(ev->keyname, "Home")) ||
2364             ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
2365      {
2366         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2367         Elm_Object_Item *it = NULL;
2368         if (sd->select_on_focus_enabled)
2369           {
2370              it = elm_gengrid_first_item_get(obj);
2371              elm_gengrid_item_bring_in(it, ELM_GENGRID_ITEM_SCROLLTO_IN);
2372              elm_gengrid_item_selected_set(it, EINA_TRUE);
2373              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2374           }
2375         else
2376           {
2377              _gengrid_item_unfocused(sd->focused);
2378              _gengrid_item_focused_next(sd, FOCUS_DIR_DOWN);
2379              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2380           }
2381         return EINA_TRUE;
2382      }
2383    else if ((!strcmp(ev->keyname, "End")) ||
2384          ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
2385      {
2386         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2387         Elm_Object_Item *it = NULL;
2388         if (sd->select_on_focus_enabled)
2389           {
2390              it = elm_gengrid_last_item_get(obj);
2391              elm_gengrid_item_bring_in(it, ELM_GENGRID_ITEM_SCROLLTO_IN);
2392              elm_gengrid_item_selected_set(it, EINA_TRUE);
2393              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2394           }
2395         else
2396           {
2397              _gengrid_item_unfocused(sd->focused);
2398              sd->focused = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
2399              _gengrid_item_focused_next(sd, FOCUS_DIR_UP);
2400              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2401           }
2402         return EINA_TRUE;
2403      }
2404    else if ((!strcmp(ev->keyname, "Prior")) ||
2405          ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
2406      {
2407         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2408         Elm_Gen_Item *it = sd->focused;
2409         int before_pos = it->position;
2410         int after_pos = it->position;
2411
2412         if (sd->item_height > 0) page_y = v_h / sd->item_height;
2413         if (sd->item_width > 0) page_x = v_w / sd->item_width;
2414
2415         while ((before_pos - after_pos) < (page_x * page_y))
2416           {
2417              if (elm_gengrid_item_prev_get((Elm_Object_Item *) it))
2418                it = (Elm_Gen_Item *)
2419                        elm_gengrid_item_prev_get((Elm_Object_Item *) it);
2420              else break;
2421              after_pos = it->position;
2422           }
2423         if (_gengrid_item_focusable_search(it, 1))
2424           it = _gengrid_item_focusable_search(it, 1);
2425         else if (_gengrid_item_focusable_search(it, -1))
2426           it = _gengrid_item_focusable_search(it, -1);
2427
2428         _gengrid_item_focused(it, ELM_GENGRID_ITEM_SCROLLTO_TOP);
2429
2430         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2431         return EINA_TRUE;
2432      }
2433    else if ((!strcmp(ev->keyname, "Next")) ||
2434          ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
2435      {
2436         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2437         Elm_Gen_Item *it = sd->focused;
2438         int before_pos = it->position;
2439         int after_pos = it->position;
2440
2441         _gengrid_item_unfocused(sd->focused);
2442         if (sd->item_height > 0) page_y = v_h / sd->item_height;
2443         if (sd->item_width > 0) page_x = v_w / sd->item_width;
2444
2445          while ((after_pos - before_pos) < (page_x * page_y))
2446           {
2447              if (elm_gengrid_item_next_get((Elm_Object_Item *) it))
2448                it = (Elm_Gen_Item *)
2449                        elm_gengrid_item_next_get((Elm_Object_Item *) it);
2450              else break;
2451              after_pos = it->position;
2452           }
2453         if (_gengrid_item_focusable_search(it, -1))
2454           it = _gengrid_item_focusable_search(it, -1);
2455         else if (_gengrid_item_focusable_search(it, 1))
2456           it = _gengrid_item_focusable_search(it, 1);
2457
2458         _gengrid_item_focused(it, ELM_GENGRID_ITEM_SCROLLTO_TOP);
2459
2460         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2461         return EINA_TRUE;
2462      }
2463    else if (!strcmp(ev->keyname, "Escape"))
2464      {
2465         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2466         if (!_all_items_deselect(sd)) return EINA_FALSE;
2467         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2468         return EINA_TRUE;
2469      }
2470    else if (((!strcmp(ev->keyname, "Return")) ||
2471           (!strcmp(ev->keyname, "KP_Enter"))) &&
2472           sd->focused)
2473      {
2474         if (type == EVAS_CALLBACK_KEY_DOWN && !sd->key_down)
2475           {
2476              sd->key_down = sd->focused;
2477
2478              edje_object_signal_emit
2479                 (VIEW(sd->key_down), "elm,action,focus_highlight,hide", "elm");
2480
2481              _item_highlight(sd->key_down);
2482              if (sd->key_down->long_timer)
2483                ecore_timer_del(sd->key_down->long_timer);
2484              sd->key_down->long_timer = ecore_timer_add(sd->longpress_timeout,
2485                                                 _long_press_cb, sd->key_down);
2486              evas_object_smart_callback_call(obj, SIG_ACTIVATED, sd->key_down);
2487              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2488              return EINA_TRUE;
2489           }
2490         else if (type == EVAS_CALLBACK_KEY_UP && sd->key_down)
2491           {
2492              edje_object_signal_emit
2493                 (VIEW(sd->key_down), "elm,action,focus_highlight,show", "elm");
2494
2495              if (sd->key_down->long_timer)
2496                ecore_timer_del(sd->key_down->long_timer);
2497              sd->key_down->long_timer = NULL;
2498              if (GG_IT(sd->key_down)->highlight_timer)
2499                ecore_timer_del(GG_IT(sd->key_down)->highlight_timer);
2500              GG_IT(sd->key_down)->highlight_timer = ecore_timer_add
2501                   (ITEM_SELECT_TIMER, _select_timer, sd->key_down);
2502              sd->key_down = NULL;
2503              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2504              return EINA_TRUE;
2505           }
2506         else return EINA_FALSE;
2507      }
2508
2509    else return EINA_FALSE;
2510
2511    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2512    sd->s_iface->content_pos_set(obj, x, y, EINA_TRUE);
2513    return EINA_TRUE;
2514 #else
2515    return EINA_FALSE;
2516 #endif
2517 }
2518
2519 static void
2520 _elm_gengrid_focus_highlight_show(void *data __UNUSED__,
2521                                   Evas_Object *obj,
2522                                   const char *emission __UNUSED__,
2523                                   const char *src __UNUSED__)
2524 {
2525    ELM_GENGRID_DATA_GET(obj, sd);
2526    if (sd->focused) _gengrid_item_focused(sd->focused, ELM_GENGRID_ITEM_SCROLLTO_IN);
2527 }
2528
2529 static void
2530 _elm_gengrid_focus_highlight_hide(void *data __UNUSED__,
2531                                   Evas_Object *obj,
2532                                   const char *emission __UNUSED__,
2533                                   const char *src __UNUSED__)
2534 {
2535    ELM_GENGRID_DATA_GET(obj, sd);
2536    if (sd->focused)
2537      {
2538         // Do not use _gengrid_item_unfocused because focus should be remained
2539         edje_object_signal_emit
2540            (VIEW(sd->focused), "elm,action,focus_highlight,hide", "elm");
2541      }
2542 }
2543
2544 static Eina_Bool
2545 _elm_gengrid_smart_on_focus(Evas_Object *obj)
2546 {
2547    ELM_GENGRID_DATA_GET(obj, sd);
2548
2549    if (!ELM_WIDGET_CLASS(_elm_gengrid_parent_sc)->on_focus(obj))
2550      return EINA_FALSE;
2551
2552    if (elm_widget_focus_get(obj) && (sd->selected) &&
2553        (!sd->last_selected_item))
2554      sd->last_selected_item = eina_list_data_get(sd->selected);
2555
2556    if (sd->select_on_focus_enabled) return EINA_TRUE;
2557
2558    if (elm_widget_focus_get(obj))
2559      {
2560         if (_focus_enabled(obj))
2561           {
2562              if (sd->focused)
2563                 _gengrid_item_focused(sd->focused, ELM_GENGRID_ITEM_SCROLLTO_IN);
2564              else
2565                _gengrid_item_focused_next(sd, FOCUS_DIR_DOWN);
2566           }
2567      }
2568    else
2569      {
2570         // when key down and not called key up
2571         // and focus is not on genlist, call select_timer forcely
2572         if (sd->key_down)
2573           {
2574              _select_timer(sd->key_down);
2575              sd->key_down = NULL;
2576           }
2577
2578         if (sd->focused)
2579           {
2580              edje_object_signal_emit
2581                 (VIEW(sd->focused), "elm,action,focus_highlight,hide", "elm");
2582           }
2583      }
2584    return EINA_TRUE;
2585 }
2586
2587 static Eina_Bool
2588 _elm_gengrid_smart_on_focus_region(const Evas_Object *obj __UNUSED__,
2589                                  Evas_Coord *x,
2590                                  Evas_Coord *y,
2591                                  Evas_Coord *w,
2592                                  Evas_Coord *h)
2593 {
2594    //FIXME: Gengrid should not move region when first focus in,
2595    //But when focus by Keyboard or enforced focus set by
2596    //applications, region move should be possible.
2597    *x = 0;
2598    *y = 0;
2599    *w = 0;
2600    *h = 0;
2601
2602    return EINA_TRUE;
2603 }
2604
2605 static Eina_Bool
2606 _elm_gengrid_smart_focus_next(const Evas_Object *obj,
2607                            Elm_Focus_Direction dir,
2608                            Evas_Object **next)
2609 {
2610    Eina_List *items = NULL;
2611    Elm_Gen_Item *it;
2612
2613    ELM_GENGRID_CHECK(obj) EINA_FALSE;
2614    ELM_GENGRID_DATA_GET(obj, sd);
2615
2616    EINA_INLIST_FOREACH(sd->items, it)
2617      {
2618         if (it->realized)
2619           items = eina_list_append(items, it->base.access_obj);
2620      }
2621
2622    return elm_widget_focus_list_next_get
2623             (obj, items, eina_list_data_get, dir, next);
2624 }
2625
2626 static void
2627 _mirrored_set(Evas_Object *obj,
2628               Eina_Bool rtl)
2629 {
2630    Elm_Gen_Item *it;
2631
2632    ELM_GENGRID_DATA_GET(obj, sd);
2633
2634    sd->s_iface->mirrored_set(obj, rtl);
2635
2636    if (!sd->items) return;
2637    it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
2638
2639    while (it)
2640      {
2641         edje_object_mirrored_set(VIEW(it), rtl);
2642         elm_gengrid_item_update((Elm_Object_Item *)it);
2643         it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
2644      }
2645 }
2646
2647 static Eina_Bool
2648 _elm_gengrid_smart_theme(Evas_Object *obj)
2649 {
2650    if (!ELM_WIDGET_CLASS(_elm_gengrid_parent_sc)->theme(obj))
2651      return EINA_FALSE;
2652
2653    _mirrored_set(obj, elm_widget_mirrored_get(obj));
2654
2655    return EINA_TRUE;
2656 }
2657
2658 static void
2659 _item_position_update(Eina_Inlist *list,
2660                       int idx)
2661 {
2662    Elm_Gen_Item *it;
2663
2664    EINA_INLIST_FOREACH(list, it)
2665      {
2666         it->position = idx++;
2667         it->position_update = EINA_TRUE;
2668      }
2669 }
2670
2671 static void
2672 _elm_gengrid_item_del_not_serious(Elm_Gen_Item *it)
2673 {
2674    elm_widget_item_pre_notify_del(it);
2675    it->generation = GG_IT(it)->wsd->generation - 1; /* This means that the
2676                                                      * item is deleted */
2677
2678    if (it->walking > 0) return;
2679
2680    if (it->selected)
2681      GG_IT(it)->wsd->selected =
2682        eina_list_remove(GG_IT(it)->wsd->selected, it);
2683
2684    if (it->itc->func.del)
2685      it->itc->func.del((void *)it->base.data, WIDGET(it));
2686 }
2687
2688 static void
2689 _elm_gengrid_item_del_common(Elm_Gen_Item *it)
2690 {
2691 #if GENGRID_FX_SUPPORT
2692    if (!eina_list_data_find(GG_IT(it)->wsd->pending_del_items, it))
2693 #endif
2694       GG_IT(it)->wsd->items = eina_inlist_remove
2695          (GG_IT(it)->wsd->items, EINA_INLIST_GET(it));
2696
2697    if (it->tooltip.del_cb)
2698      it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
2699    GG_IT(it)->wsd->walking -= it->walking;
2700
2701    if (GG_IT(it)->wsd->focused == it) _gengrid_item_unfocused(it); //GG_IT(it)->wsd->focused = NULL;
2702    if (GG_IT(it)->wsd->key_down == it) GG_IT(it)->wsd->key_down = NULL;
2703
2704    if (it->item->highlight_timer)
2705      {
2706         ecore_timer_del(it->item->highlight_timer);
2707         it->item->highlight_timer = NULL;
2708      }
2709    if (it->long_timer)
2710      {
2711         ecore_timer_del(it->long_timer);
2712         it->long_timer = NULL;
2713      }
2714    if (it->group)
2715      GG_IT(it)->wsd->group_items =
2716         eina_list_remove(GG_IT(it)->wsd->group_items, it);
2717
2718    if (GG_IT(it)->wsd->state)
2719      {
2720         eina_inlist_sorted_state_free(GG_IT(it)->wsd->state);
2721         GG_IT(it)->wsd->state = NULL;
2722      }
2723    if (GG_IT(it)->wsd->calc_job) ecore_job_del(GG_IT(it)->wsd->calc_job);
2724    GG_IT(it)->wsd->calc_job =
2725       ecore_job_add(GG_IT(it)->wsd->calc_cb, GG_IT(it)->wsd);
2726
2727    if (GG_IT(it)->wsd->last_selected_item == (Elm_Object_Item *)it)
2728      GG_IT(it)->wsd->last_selected_item = NULL;
2729
2730    GG_IT(it)->wsd->item_count--;
2731 }
2732
2733 static void
2734 _elm_gengrid_item_del_serious(Elm_Gen_Item *it)
2735 {
2736    _elm_gengrid_item_del_not_serious(it);
2737    _elm_gengrid_item_del_common(it);
2738
2739    if ((it == GG_IT(it)->wsd->bring_in_it) && (GG_IT(it)->wsd->bring_in == EINA_TRUE))
2740      {
2741         GG_IT(it)->wsd->bring_in_it = NULL;
2742         GG_IT(it)->wsd->bring_in = EINA_FALSE;
2743      }
2744
2745    if ((it == GG_IT(it)->wsd->show_it) && (GG_IT(it)->wsd->show_region == EINA_TRUE))
2746      {
2747         GG_IT(it)->wsd->show_it = NULL;
2748         GG_IT(it)->wsd->show_region = EINA_FALSE;
2749      }
2750
2751    free(it->item);
2752    it->item = NULL;
2753 }
2754
2755 static void
2756 _item_del(Elm_Gen_Item *it)
2757 {
2758    Evas_Object *obj = WIDGET(it);
2759
2760    evas_event_freeze(evas_object_evas_get(obj));
2761 #if GENGRID_FX_SUPPORT
2762    GG_IT(it)->has_proxy_it = EINA_FALSE;
2763 #endif
2764    GG_IT(it)->wsd->selected = eina_list_remove(GG_IT(it)->wsd->selected, it);
2765    if (it->realized) _elm_gengrid_item_unrealize(it, EINA_FALSE);
2766    _elm_gengrid_item_del_serious(it);
2767    elm_gengrid_item_class_unref((Elm_Gengrid_Item_Class *)it->itc);
2768    evas_event_thaw(evas_object_evas_get(obj));
2769    evas_event_thaw_eval(evas_object_evas_get(obj));
2770 }
2771
2772 static void
2773 _scroll_animate_start_cb(Evas_Object *obj,
2774                          void *data __UNUSED__)
2775 {
2776    evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
2777 }
2778
2779 static void
2780 _scroll_animate_stop_cb(Evas_Object *obj,
2781                         void *data __UNUSED__)
2782 {
2783    evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
2784 }
2785
2786 static void
2787 _scroll_drag_start_cb(Evas_Object *obj,
2788                       void *data __UNUSED__)
2789 {
2790    evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
2791 }
2792
2793 static void
2794 _scroll_drag_stop_cb(Evas_Object *obj,
2795                      void *data __UNUSED__)
2796 {
2797    evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_STOP, NULL);
2798 }
2799
2800 static void
2801 _edge_left_cb(Evas_Object *obj,
2802               void *data __UNUSED__)
2803 {
2804    evas_object_smart_callback_call(obj, SIG_EDGE_LEFT, NULL);
2805 }
2806
2807 static void
2808 _edge_right_cb(Evas_Object *obj,
2809                void *data __UNUSED__)
2810 {
2811    evas_object_smart_callback_call(obj, SIG_EDGE_RIGHT, NULL);
2812 }
2813
2814 static void
2815 _edge_top_cb(Evas_Object *obj,
2816              void *data __UNUSED__)
2817 {
2818    evas_object_smart_callback_call(obj, SIG_EDGE_TOP, NULL);
2819 }
2820
2821 static void
2822 _edge_bottom_cb(Evas_Object *obj,
2823                 void *data __UNUSED__)
2824 {
2825    evas_object_smart_callback_call(obj, SIG_EDGE_BOTTOM, NULL);
2826 }
2827
2828 static void
2829 _scroll_cb(Evas_Object *obj,
2830            void *data __UNUSED__)
2831 {
2832    evas_object_smart_callback_call(obj, SIG_SCROLL, NULL);
2833 }
2834
2835 static int
2836 _elm_gengrid_item_compare(const void *data,
2837                           const void *data1)
2838 {
2839    Elm_Gen_Item *it, *item1;
2840    Eina_Compare_Cb cb = NULL;
2841    ptrdiff_t d;
2842
2843    it = ELM_GEN_ITEM_FROM_INLIST(data);
2844    item1 = ELM_GEN_ITEM_FROM_INLIST(data1);
2845    if (it && GG_IT(it)->wsd->item_compare_cb)
2846      cb = GG_IT(it)->wsd->item_compare_cb;
2847    else if (item1 && GG_IT(item1)->wsd->item_compare_cb)
2848      cb = GG_IT(item1)->wsd->item_compare_cb;
2849    if (cb && it && item1) return cb(it, item1);
2850    d = (char *)data - (char *)data1;
2851    if (d < 0) return -1;
2852    if (!d) return 0;
2853    return 1;
2854 }
2855
2856 static void
2857 _item_disable_hook(Elm_Object_Item *item)
2858 {
2859    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
2860
2861    if (it->generation < GG_IT(it)->wsd->generation) return;
2862
2863    _highlight_timer_disable(it);
2864    if (it == GG_IT(it)->wsd->focused) _gengrid_item_unfocused(it);
2865
2866    if (it->realized)
2867      {
2868         if (elm_widget_item_disabled_get(it))
2869           edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
2870         else
2871           edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm");
2872      }
2873 }
2874
2875 #if GENGRID_FX_SUPPORT
2876 static void
2877 _item_del_post_fx_process(Elm_Gen_Item *it)
2878 {
2879    Evas_Object *obj = WIDGET(it);
2880
2881    evas_event_freeze(evas_object_evas_get(obj));
2882
2883    GG_IT(it)->has_proxy_it = EINA_FALSE;
2884
2885    if (it->itc->func.del)
2886      it->itc->func.del((void *)it->base.data, WIDGET(it));
2887
2888    if (GG_IT(it)->wsd->calc_job) ecore_job_del(GG_IT(it)->wsd->calc_job);
2889    GG_IT(it)->wsd->calc_job =
2890       ecore_job_add(GG_IT(it)->wsd->calc_cb, GG_IT(it)->wsd);
2891
2892    if ((it == GG_IT(it)->wsd->bring_in_it) && (GG_IT(it)->wsd->bring_in == EINA_TRUE))
2893      {
2894         GG_IT(it)->wsd->bring_in_it = NULL;
2895         GG_IT(it)->wsd->bring_in = EINA_FALSE;
2896      }
2897
2898    if ((it == GG_IT(it)->wsd->show_it) && (GG_IT(it)->wsd->show_region == EINA_TRUE))
2899      {
2900         GG_IT(it)->wsd->show_it = NULL;
2901         GG_IT(it)->wsd->show_region = EINA_FALSE;
2902      }
2903
2904    free(it->item);
2905    it->item = NULL;
2906    elm_gengrid_item_class_unref((Elm_Gengrid_Item_Class *)it->itc);
2907    evas_event_thaw(evas_object_evas_get(obj));
2908    evas_event_thaw_eval(evas_object_evas_get(obj));
2909 }
2910
2911 static void
2912 _item_del_pre_fx_process(Elm_Gen_Item *it)
2913 {
2914    _elm_gengrid_fx_capture(ELM_WIDGET_DATA(GG_IT(it)->wsd)->obj, 0);
2915    if (!eina_list_data_find(GG_IT(it)->wsd->pending_del_items, it))
2916      {
2917         GG_IT(it)->wsd->pending_del_items = eina_list_append(GG_IT(it)->wsd->pending_del_items, it);
2918      }
2919
2920    evas_object_event_callback_del_full
2921       (VIEW(it), EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
2922    evas_object_event_callback_del_full
2923       (VIEW(it), EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
2924
2925    evas_object_event_callback_del_full
2926       (VIEW(it), EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
2927
2928    _highlight_timer_disable(it);
2929
2930    GG_IT(it)->wsd->items = eina_inlist_remove
2931       (GG_IT(it)->wsd->items, EINA_INLIST_GET(it));
2932
2933    if (it->realized) _elm_gengrid_item_unrealize(it, EINA_FALSE);
2934
2935    elm_widget_item_pre_notify_del(it);
2936    it->generation = GG_IT(it)->wsd->generation - 1; /* This means that the
2937                                                      * item is deleted */
2938    if (it->walking > 0) return;
2939
2940    if (it->selected)
2941      GG_IT(it)->wsd->selected =
2942        eina_list_remove(GG_IT(it)->wsd->selected, it);
2943
2944     _elm_gengrid_item_del_common(it);
2945 }
2946 #endif
2947
2948 //static void
2949 static Eina_Bool
2950 _item_del_pre_hook(Elm_Object_Item *item)
2951 {
2952    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
2953
2954 #if GENGRID_FX_SUPPORT
2955    if ((GG_IT(it)->wsd->fx_mode) && (!GG_IT(it)->wsd->gengrid_clearing))
2956      {
2957         _item_del_pre_fx_process(it);
2958         return EINA_FALSE;
2959      }
2960 #endif
2961    if (it->walking > 0)
2962      {
2963         _elm_gengrid_item_del_not_serious(it);
2964         return EINA_TRUE;
2965      }
2966
2967    _item_del(it);
2968    return EINA_TRUE;
2969 }
2970
2971 static Evas_Object *
2972 _item_content_get_hook(Elm_Gen_Item *it,
2973                        const char *part)
2974 {
2975    return edje_object_part_swallow_get(VIEW(it), part);
2976 }
2977
2978 static const char *
2979 _item_text_get_hook(Elm_Gen_Item *it,
2980                     const char *part)
2981 {
2982    if (!it->itc->func.text_get) return NULL;
2983    return edje_object_part_text_get(VIEW(it), part);
2984 }
2985
2986 static void
2987 _item_signal_emit_hook(Elm_Object_Item *it,
2988                        const char *emission,
2989                        const char *source)
2990 {
2991    edje_object_signal_emit(VIEW(it), emission, source);
2992 }
2993
2994 static void
2995 _elm_gengrid_clear(Evas_Object *obj,
2996                    Eina_Bool standby)
2997 {
2998    Eina_Inlist *next, *l;
2999    Elm_Gen_Item *it;
3000
3001    ELM_GENGRID_DATA_GET(obj, sd);
3002
3003    if (!standby) sd->generation++;
3004
3005    if (sd->state)
3006      {
3007         eina_inlist_sorted_state_free(sd->state);
3008         sd->state = NULL;
3009      }
3010
3011    if (sd->walking > 0)
3012      {
3013         sd->clear_me = EINA_TRUE;
3014         return;
3015      }
3016    evas_event_freeze(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
3017
3018 #if GENGRID_FX_SUPPORT
3019    Elm_Gen_FX_Item *fi;
3020    Proxy_Item *pi;
3021
3022    EINA_LIST_FREE(sd->capture_before_items, pi)
3023      {
3024         if (pi->proxy) evas_object_smart_member_del(pi->proxy);
3025         if (pi->proxy) evas_object_del(pi->proxy);
3026         free(pi);
3027      }
3028    EINA_LIST_FREE(sd->capture_after_items, pi)
3029      {
3030         if (pi->proxy) evas_object_smart_member_del(pi->proxy);
3031         if (pi->proxy) evas_object_del(pi->proxy);
3032         free(pi);
3033      }
3034    EINA_LIST_FREE(sd->fx_items, fi)
3035      {
3036         if (fi->trans) elm_transit_del(fi->trans);
3037         free(fi);
3038      }
3039    EINA_LIST_FREE (sd->pending_unrealized_items, it)
3040      {
3041         if ((it) && (GG_IT(it))) GG_IT(it)->has_proxy_it = EINA_FALSE;
3042         _elm_gengrid_item_unrealize(it, EINA_FALSE);
3043      }
3044    EINA_LIST_FREE (sd->pending_del_items, it)
3045      {
3046         _item_del_post_fx_process(it);
3047         elm_widget_item_free(it);
3048      }
3049    sd->gengrid_clearing = EINA_TRUE;
3050    sd->fx_playing = EINA_FALSE;
3051    sd->fx_first_captured = EINA_FALSE;
3052    sd->rendered = EINA_FALSE;
3053 #endif
3054
3055    for (l = sd->items, next = l ? l->next : NULL;
3056         l;
3057         l = next, next = next ? next->next : NULL)
3058      {
3059         it = ELM_GEN_ITEM_FROM_INLIST(l);
3060
3061         if (it->generation < sd->generation)
3062           {
3063              Elm_Gen_Item *itn = NULL;
3064
3065              if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
3066              if (itn) itn->walking++;  /* prevent early death of subitem */
3067              it->del_cb(it);
3068              elm_widget_item_free(it);
3069              if (itn) itn->walking--;
3070           }
3071      }
3072    sd->clear_me = EINA_FALSE;
3073    sd->pan_changed = EINA_TRUE;
3074    if (sd->calc_job)
3075      {
3076         ecore_job_del(sd->calc_job);
3077         sd->calc_job = NULL;
3078      }
3079
3080    if (sd->focused) sd->focused = NULL;
3081    if (sd->key_down) sd->key_down = NULL;
3082    if (sd->selected) sd->selected = eina_list_free(sd->selected);
3083    if (sd->clear_cb) sd->clear_cb(sd);
3084    sd->pan_x = 0;
3085    sd->pan_y = 0;
3086    sd->minw = 0;
3087    sd->minh = 0;
3088
3089    if (sd->pan_obj)
3090      {
3091         evas_object_size_hint_min_set(sd->pan_obj, sd->minw, sd->minh);
3092         evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
3093      }
3094    sd->s_iface->content_region_show(obj, 0, 0, 0, 0);
3095
3096 #if GENGRID_FX_SUPPORT
3097    sd->gengrid_clearing = EINA_FALSE;
3098 #endif
3099    evas_event_thaw(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
3100    evas_event_thaw_eval(evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj));
3101 }
3102
3103 static void
3104 _item_select(Elm_Gen_Item *it)
3105 {
3106    Evas_Object *obj = WIDGET(it);
3107    Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
3108    if (elm_widget_item_disabled_get(it)) return;
3109    if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
3110        (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
3111      return;
3112    if (sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS &&
3113        it->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS &&
3114        it->selected)
3115       return;
3116    if (!sd->multi)
3117      {
3118         const Eina_List *l, *ll;
3119         Elm_Gen_Item *it2;
3120         EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2)
3121           if (it2 != it) _item_unselect(it2);
3122      }
3123
3124    if (!it->selected)
3125      {
3126         sd->selected = eina_list_append(sd->selected, it);
3127         it->selected = EINA_TRUE;
3128      }
3129    sd->last_selected_item = (Elm_Object_Item *)it;
3130    _item_highlight(it);
3131    _gengrid_item_focused(it, ELM_GENGRID_ITEM_SCROLLTO_IN);
3132
3133    // FIXME: after evas_object_raise, mouse event callbacks(ex, UP, DOWN)
3134    // can be called again eventhough already received it.
3135    const char *selectraise = edje_object_data_get(VIEW(it), "selectraise");
3136    if ((selectraise) && (!strcmp(selectraise, "on")))
3137      {
3138         evas_object_raise(VIEW(it));
3139      }
3140
3141    evas_object_ref(obj);
3142    if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), it);
3143    if (EINA_MAGIC_CHECK((Elm_Widget_Item *)it, ELM_WIDGET_ITEM_MAGIC))
3144      {
3145         if (it->generation == sd->generation)
3146            evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
3147      }
3148    evas_object_unref(obj);
3149 }
3150
3151 static Elm_Gen_Item *
3152 _elm_gengrid_item_new(Elm_Gengrid_Smart_Data *sd,
3153                       const Elm_Gen_Item_Class *itc,
3154                       const void *data,
3155                       Evas_Smart_Cb func,
3156                       const void *func_data)
3157 {
3158    Elm_Gen_Item *it;
3159
3160    if (!itc) return NULL;
3161
3162    it = elm_widget_item_new(ELM_WIDGET_DATA(sd)->obj, Elm_Gen_Item);
3163    if (!it) return NULL;
3164
3165    it->generation = sd->generation;
3166    it->itc = itc;
3167    elm_gengrid_item_class_ref((Elm_Gengrid_Item_Class *)itc);
3168
3169    it->base.data = data;
3170    it->parent = NULL;
3171    it->func.func = func;
3172    it->func.data = func_data;
3173
3174    elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
3175    elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
3176    elm_widget_item_disable_hook_set(it, _item_disable_hook);
3177    elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
3178    elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
3179
3180    /* TEMPORARY */
3181    it->sel_cb = (Ecore_Cb)_item_select;
3182
3183    it->item = ELM_NEW(Elm_Gen_Item_Type);
3184
3185    GG_IT(it)->wsd = sd;
3186
3187    sd->item_count++;
3188    it->group = it->itc->item_style &&
3189      (!strncmp(it->itc->item_style, "group_index", 11));
3190
3191    it->del_cb = (Ecore_Cb)_item_del;
3192    it->highlight_cb = (Ecore_Cb)_item_highlight;
3193    it->unsel_cb = (Ecore_Cb)_item_unselect;
3194    it->unrealize_cb = (Ecore_Cb)_item_unrealize_cb;
3195
3196 #if GENGRID_FX_SUPPORT
3197    it->item->num = sd->item_count;
3198    if (sd->fx_mode)
3199      _elm_gengrid_fx_capture(ELM_WIDGET_DATA(sd)->obj, 0);
3200 #endif
3201
3202    return it;
3203 }
3204
3205 /* common layout sizing won't apply here */
3206 static void
3207 _elm_gengrid_smart_sizing_eval(Evas_Object *obj __UNUSED__)
3208 {
3209    return;  /* no-op */
3210 }
3211
3212 static void
3213 _elm_gengrid_smart_add(Evas_Object *obj)
3214 {
3215    EVAS_SMART_DATA_ALLOC(obj, Elm_Gengrid_Smart_Data);
3216
3217    ELM_WIDGET_CLASS(_elm_gengrid_parent_sc)->base.add(obj);
3218 }
3219
3220 static void
3221 _elm_gengrid_smart_del(Evas_Object *obj)
3222 {
3223    ELM_GENGRID_DATA_GET(obj, sd);
3224
3225    elm_gengrid_clear(obj);
3226    evas_object_del(sd->pan_obj);
3227    sd->pan_obj = NULL;
3228
3229    if (sd->calc_job) ecore_job_del(sd->calc_job);
3230
3231    ELM_WIDGET_CLASS(_elm_gengrid_parent_sc)->base.del(obj);
3232 }
3233
3234 static void
3235 _elm_gengrid_smart_move(Evas_Object *obj,
3236                         Evas_Coord x,
3237                         Evas_Coord y)
3238 {
3239    ELM_GENGRID_DATA_GET(obj, sd);
3240
3241    ELM_WIDGET_CLASS(_elm_gengrid_parent_sc)->base.move(obj, x, y);
3242
3243    evas_object_move(sd->hit_rect, x, y);
3244 }
3245
3246 static void
3247 _elm_gengrid_smart_resize(Evas_Object *obj,
3248                           Evas_Coord w,
3249                           Evas_Coord h)
3250 {
3251    ELM_GENGRID_DATA_GET(obj, sd);
3252
3253    ELM_WIDGET_CLASS(_elm_gengrid_parent_sc)->base.resize(obj, w, h);
3254
3255    evas_object_resize(sd->hit_rect, w, h);
3256 }
3257
3258 static void
3259 _elm_gengrid_smart_hide(Evas_Object *obj)
3260 {
3261    ELM_GENGRID_DATA_GET(obj, sd);
3262    Elm_Gen_Item *it;
3263
3264    ELM_WIDGET_CLASS(_elm_gengrid_parent_sc)->base.hide(obj);
3265
3266    evas_object_hide(sd->hit_rect);
3267
3268    EINA_INLIST_FOREACH(sd->items, it)
3269      {
3270         if (it->long_timer) ecore_timer_del(it->long_timer);
3271         it->long_timer = NULL;
3272      }
3273 }
3274
3275 static void
3276 _elm_gengrid_smart_member_add(Evas_Object *obj,
3277                               Evas_Object *member)
3278 {
3279    ELM_GENGRID_DATA_GET(obj, sd);
3280
3281    ELM_WIDGET_CLASS(_elm_gengrid_parent_sc)->base.member_add(obj, member);
3282
3283    if (sd->hit_rect)
3284      evas_object_raise(sd->hit_rect);
3285 }
3286
3287 static void
3288 _access_obj_process(Elm_Gengrid_Smart_Data * sd, Eina_Bool is_access)
3289 {
3290    Elm_Gen_Item *it;
3291
3292    EINA_INLIST_FOREACH(sd->items, it)
3293      {
3294         if (!it->realized) continue;
3295         if (is_access) _access_widget_item_register(it);
3296         else
3297           _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
3298
3299      }
3300 }
3301
3302 static void
3303 _access_hook(Evas_Object *obj, Eina_Bool is_access)
3304 {
3305    ELM_GENGRID_CHECK(obj);
3306    ELM_GENGRID_DATA_GET(obj, sd);
3307
3308    if (is_access)
3309      ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
3310      _elm_gengrid_smart_focus_next;
3311    else
3312      ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
3313
3314    _access_obj_process(sd, is_access);
3315 }
3316
3317 static void
3318 _elm_gengrid_smart_set_user(Elm_Gengrid_Smart_Class *sc)
3319 {
3320    ELM_WIDGET_CLASS(sc)->base.add = _elm_gengrid_smart_add;
3321    ELM_WIDGET_CLASS(sc)->base.del = _elm_gengrid_smart_del;
3322    ELM_WIDGET_CLASS(sc)->base.move = _elm_gengrid_smart_move;
3323    ELM_WIDGET_CLASS(sc)->base.resize = _elm_gengrid_smart_resize;
3324    ELM_WIDGET_CLASS(sc)->base.hide = _elm_gengrid_smart_hide;
3325    ELM_WIDGET_CLASS(sc)->base.member_add = _elm_gengrid_smart_member_add;
3326
3327    ELM_WIDGET_CLASS(sc)->on_focus = _elm_gengrid_smart_on_focus;
3328    ELM_WIDGET_CLASS(sc)->on_focus_region = _elm_gengrid_smart_on_focus_region;
3329    ELM_WIDGET_CLASS(sc)->theme = _elm_gengrid_smart_theme;
3330    ELM_WIDGET_CLASS(sc)->event = _elm_gengrid_smart_event;
3331
3332    /* not a 'focus chain manager' */
3333    ELM_WIDGET_CLASS(sc)->focus_next = NULL;
3334    ELM_WIDGET_CLASS(sc)->focus_direction_manager_is = NULL;
3335    ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
3336    ELM_WIDGET_CLASS(sc)->translate = _elm_gengrid_smart_translate;
3337
3338    ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_gengrid_smart_sizing_eval;
3339
3340    // ACCESS
3341    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
3342      ELM_WIDGET_CLASS(sc)->focus_next = _elm_gengrid_smart_focus_next;
3343    else
3344      ELM_WIDGET_CLASS(sc)->focus_next = NULL;
3345
3346    ELM_WIDGET_CLASS(sc)->access = _access_hook;
3347 }
3348
3349 EAPI const Elm_Gengrid_Smart_Class *
3350 elm_gengrid_smart_class_get(void)
3351 {
3352    static Elm_Gengrid_Smart_Class _sc =
3353      ELM_GENGRID_SMART_CLASS_INIT_NAME_VERSION(ELM_GENGRID_SMART_NAME);
3354    static const Elm_Gengrid_Smart_Class *class = NULL;
3355    Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
3356
3357    if (class)
3358      return class;
3359
3360    _elm_gengrid_smart_set(&_sc);
3361    esc->callbacks = _smart_callbacks;
3362    class = &_sc;
3363
3364    return class;
3365 }
3366
3367 EAPI Evas_Object *
3368 elm_gengrid_add(Evas_Object *parent)
3369 {
3370    Evas_Object *obj;
3371    Eina_Bool bounce = _elm_config->thumbscroll_bounce_enable;
3372    Elm_Gengrid_Pan_Smart_Data *pan_data;
3373
3374    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
3375
3376    obj = elm_widget_add(_elm_gengrid_smart_class_new(), parent);
3377    if (!obj) return NULL;
3378
3379    if (!elm_widget_sub_object_add(parent, obj))
3380      ERR("could not add %p as sub object of %p", obj, parent);
3381
3382    ELM_GENGRID_DATA_GET(obj, sd);
3383
3384    sd->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
3385    evas_object_smart_member_add(sd->hit_rect, obj);
3386    elm_widget_sub_object_add(obj, sd->hit_rect);
3387
3388    /* common scroller hit rectangle setup */
3389    evas_object_color_set(sd->hit_rect, 0, 0, 0, 0);
3390    evas_object_show(sd->hit_rect);
3391    evas_object_repeat_events_set(sd->hit_rect, EINA_TRUE);
3392
3393    elm_widget_can_focus_set(obj, EINA_TRUE);
3394
3395    sd->calc_cb = (Ecore_Cb)_calc_job;
3396
3397    sd->generation = 1;
3398
3399    elm_layout_theme_set(obj, "gengrid", "base", elm_widget_style_get(obj));
3400
3401    /* interface's add() routine issued AFTER the object's smart_add() */
3402    sd->s_iface = evas_object_smart_interface_get
3403        (obj, ELM_SCROLLABLE_IFACE_NAME);
3404
3405    sd->s_iface->objects_set
3406      (obj, ELM_WIDGET_DATA(sd)->resize_obj, sd->hit_rect);
3407
3408    sd->old_h_bounce = bounce;
3409    sd->old_v_bounce = bounce;
3410    sd->s_iface->bounce_allow_set(obj, bounce, bounce);
3411
3412    sd->s_iface->animate_start_cb_set(obj, _scroll_animate_start_cb);
3413    sd->s_iface->animate_stop_cb_set(obj, _scroll_animate_stop_cb);
3414    sd->s_iface->drag_start_cb_set(obj, _scroll_drag_start_cb);
3415    sd->s_iface->drag_stop_cb_set(obj, _scroll_drag_stop_cb);
3416    sd->s_iface->edge_left_cb_set(obj, _edge_left_cb);
3417    sd->s_iface->edge_right_cb_set(obj, _edge_right_cb);
3418    sd->s_iface->edge_top_cb_set(obj, _edge_top_cb);
3419    sd->s_iface->edge_bottom_cb_set(obj, _edge_bottom_cb);
3420    sd->s_iface->scroll_cb_set(obj, _scroll_cb);
3421
3422    sd->align_x = 0.5;
3423    sd->align_y = 0.5;
3424    sd->highlight = EINA_TRUE;
3425    sd->longpress_timeout = _elm_config->longpress_timeout;
3426
3427 #if GENGRID_FX_SUPPORT
3428    sd->fx_mode = EINA_TRUE;
3429    sd->rendered = EINA_FALSE;
3430    sd->fx_first_captured = EINA_FALSE;
3431    sd->fx_playing = EINA_FALSE;
3432    sd->gengrid_clearing = EINA_FALSE;
3433 #endif
3434
3435    sd->pan_obj = evas_object_smart_add
3436        (evas_object_evas_get(obj), _elm_gengrid_pan_smart_class_new());
3437    pan_data = evas_object_smart_data_get(sd->pan_obj);
3438    pan_data->wsd = sd;
3439
3440    sd->s_iface->extern_pan_set(obj, sd->pan_obj);
3441
3442    const char *str = edje_object_data_get(ELM_WIDGET_DATA(sd)->resize_obj,
3443                                           "focus_highlight");
3444    if ((str) && (!strcmp(str, "on")))
3445       elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
3446    else
3447       elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
3448    sd->select_on_focus_enabled = EINA_FALSE;
3449    elm_widget_signal_callback_add(obj, "elm,action,focus_highlight,hide", "elm", _elm_gengrid_focus_highlight_hide, obj);
3450    elm_widget_signal_callback_add(obj, "elm,action,focus_highlight,show", "elm", _elm_gengrid_focus_highlight_show, obj);
3451
3452    //Tizen Only: This should be removed when eo is applied.
3453    ELM_WIDGET_DATA_GET(obj, wsd);
3454    wsd->on_create = EINA_FALSE;
3455
3456    return obj;
3457 }
3458
3459 EAPI void
3460 elm_gengrid_item_size_set(Evas_Object *obj,
3461                           Evas_Coord w,
3462                           Evas_Coord h)
3463 {
3464    ELM_GENGRID_CHECK(obj);
3465    ELM_GENGRID_DATA_GET(obj, sd);
3466
3467    if ((sd->item_width == w) && (sd->item_height == h)) return;
3468    sd->item_width = w;
3469    sd->item_height = h;
3470    if (sd->calc_job) ecore_job_del(sd->calc_job);
3471    sd->calc_job = ecore_job_add(_calc_job, sd);
3472 }
3473
3474 EAPI void
3475 elm_gengrid_item_size_get(const Evas_Object *obj,
3476                           Evas_Coord *w,
3477                           Evas_Coord *h)
3478 {
3479    ELM_GENGRID_CHECK(obj);
3480    ELM_GENGRID_DATA_GET(obj, sd);
3481
3482    if (w) *w = sd->item_width;
3483    if (h) *h = sd->item_height;
3484 }
3485
3486 EAPI void
3487 elm_gengrid_group_item_size_set(Evas_Object *obj,
3488                                 Evas_Coord w,
3489                                 Evas_Coord h)
3490 {
3491    ELM_GENGRID_CHECK(obj);
3492    ELM_GENGRID_DATA_GET(obj, sd);
3493
3494    if ((sd->group_item_width == w) && (sd->group_item_height == h)) return;
3495    sd->group_item_width = w;
3496    sd->group_item_height = h;
3497    if (sd->calc_job) ecore_job_del(sd->calc_job);
3498    sd->calc_job = ecore_job_add(_calc_job, sd);
3499 }
3500
3501 EAPI void
3502 elm_gengrid_group_item_size_get(const Evas_Object *obj,
3503                                 Evas_Coord *w,
3504                                 Evas_Coord *h)
3505 {
3506    ELM_GENGRID_CHECK(obj);
3507    ELM_GENGRID_DATA_GET(obj, sd);
3508
3509    if (w) *w = sd->group_item_width;
3510    if (h) *h = sd->group_item_height;
3511 }
3512
3513 EAPI void
3514 elm_gengrid_align_set(Evas_Object *obj,
3515                       double align_x,
3516                       double align_y)
3517 {
3518    double old_h, old_y;
3519
3520    ELM_GENGRID_CHECK(obj);
3521    ELM_GENGRID_DATA_GET(obj, sd);
3522
3523    old_h = sd->align_x;
3524    old_y = sd->align_y;
3525
3526    if (align_x > 1.0)
3527      align_x = 1.0;
3528    else if (align_x < 0.0)
3529      align_x = 0.0;
3530    sd->align_x = align_x;
3531
3532    if (align_y > 1.0)
3533      align_y = 1.0;
3534    else if (align_y < 0.0)
3535      align_y = 0.0;
3536    sd->align_y = align_y;
3537
3538    if ((old_h != sd->align_x) || (old_y != sd->align_y))
3539      evas_object_smart_calculate(sd->pan_obj);
3540 }
3541
3542 EAPI void
3543 elm_gengrid_align_get(const Evas_Object *obj,
3544                       double *align_x,
3545                       double *align_y)
3546 {
3547    ELM_GENGRID_CHECK(obj);
3548    ELM_GENGRID_DATA_GET(obj, sd);
3549
3550    if (align_x) *align_x = sd->align_x;
3551    if (align_y) *align_y = sd->align_y;
3552 }
3553
3554 EAPI Elm_Object_Item *
3555 elm_gengrid_item_append(Evas_Object *obj,
3556                         const Elm_Gengrid_Item_Class *itc,
3557                         const void *data,
3558                         Evas_Smart_Cb func,
3559                         const void *func_data)
3560 {
3561    Elm_Gen_Item *it;
3562
3563    ELM_GENGRID_CHECK(obj) NULL;
3564    ELM_GENGRID_DATA_GET(obj, sd);
3565
3566    it = _elm_gengrid_item_new(sd, itc, data, func, func_data);
3567    if (!it) return NULL;
3568
3569    sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
3570    it->position = eina_inlist_count(sd->items);
3571    it->position_update = EINA_TRUE;
3572
3573    if (it->group)
3574      sd->group_items = eina_list_prepend(sd->group_items, it);
3575
3576    if (sd->calc_job) ecore_job_del(sd->calc_job);
3577    sd->calc_job = ecore_job_add(_calc_job, sd);
3578
3579    return (Elm_Object_Item *)it;
3580 }
3581
3582 EAPI Elm_Object_Item *
3583 elm_gengrid_item_prepend(Evas_Object *obj,
3584                          const Elm_Gengrid_Item_Class *itc,
3585                          const void *data,
3586                          Evas_Smart_Cb func,
3587                          const void *func_data)
3588 {
3589    Elm_Gen_Item *it;
3590
3591    ELM_GENGRID_CHECK(obj) NULL;
3592    ELM_GENGRID_DATA_GET(obj, sd);
3593
3594    it = _elm_gengrid_item_new(sd, itc, data, func, func_data);
3595    if (!it) return NULL;
3596
3597    sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
3598    _item_position_update(sd->items, 0);
3599
3600    if (it->group)
3601      sd->group_items = eina_list_append(sd->group_items, it);
3602
3603    if (sd->calc_job) ecore_job_del(sd->calc_job);
3604    sd->calc_job = ecore_job_add(_calc_job, sd);
3605
3606    return (Elm_Object_Item *)it;
3607 }
3608
3609 EAPI Elm_Object_Item *
3610 elm_gengrid_item_insert_before(Evas_Object *obj,
3611                                const Elm_Gengrid_Item_Class *itc,
3612                                const void *data,
3613                                Elm_Object_Item *relative,
3614                                Evas_Smart_Cb func,
3615                                const void *func_data)
3616 {
3617    Elm_Gen_Item *it;
3618    Eina_Inlist *tmp;
3619
3620    ELM_GENGRID_CHECK(obj) NULL;
3621    ELM_GENGRID_ITEM_CHECK_OR_RETURN(relative, NULL);
3622    ELM_GENGRID_DATA_GET(obj, sd);
3623
3624    it = _elm_gengrid_item_new(sd, itc, data, func, func_data);
3625    if (!it) return NULL;
3626    sd->items = eina_inlist_prepend_relative
3627        (sd->items, EINA_INLIST_GET(it),
3628        EINA_INLIST_GET((Elm_Gen_Item *)relative));
3629    tmp = eina_inlist_find(sd->items, EINA_INLIST_GET(it));
3630    _item_position_update(tmp, ((Elm_Gen_Item *)relative)->position);
3631
3632    if (it->group)
3633      sd->group_items = eina_list_append_relative
3634          (sd->group_items, it, ((Elm_Gen_Item *)relative)->parent);
3635
3636    if (sd->calc_job) ecore_job_del(sd->calc_job);
3637    sd->calc_job = ecore_job_add(_calc_job, sd);
3638
3639    return (Elm_Object_Item *)it;
3640 }
3641
3642 EAPI Elm_Object_Item *
3643 elm_gengrid_item_insert_after(Evas_Object *obj,
3644                               const Elm_Gengrid_Item_Class *itc,
3645                               const void *data,
3646                               Elm_Object_Item *relative,
3647                               Evas_Smart_Cb func,
3648                               const void *func_data)
3649 {
3650    Elm_Gen_Item *it;
3651    Eina_Inlist *tmp;
3652
3653    ELM_GENGRID_CHECK(obj) NULL;
3654    ELM_GENGRID_ITEM_CHECK_OR_RETURN(relative, NULL);
3655    ELM_GENGRID_DATA_GET(obj, sd);
3656
3657    it = _elm_gengrid_item_new(sd, itc, data, func, func_data);
3658    if (!it) return NULL;
3659    sd->items = eina_inlist_append_relative
3660        (sd->items, EINA_INLIST_GET(it),
3661        EINA_INLIST_GET((Elm_Gen_Item *)relative));
3662    tmp = eina_inlist_find(sd->items, EINA_INLIST_GET(it));
3663    _item_position_update(tmp, ((Elm_Gen_Item *)relative)->position + 1);
3664
3665    if (it->group)
3666      sd->group_items = eina_list_prepend_relative
3667          (sd->group_items, it, ((Elm_Gen_Item *)relative)->parent);
3668
3669    if (sd->calc_job) ecore_job_del(sd->calc_job);
3670    sd->calc_job = ecore_job_add(_calc_job, sd);
3671
3672    return (Elm_Object_Item *)it;
3673 }
3674
3675 EAPI Elm_Object_Item *
3676 elm_gengrid_item_sorted_insert(Evas_Object *obj,
3677                                const Elm_Gengrid_Item_Class *itc,
3678                                const void *data,
3679                                Eina_Compare_Cb comp,
3680                                Evas_Smart_Cb func,
3681                                const void *func_data)
3682 {
3683    Elm_Gen_Item *it;
3684
3685    ELM_GENGRID_CHECK(obj) NULL;
3686    ELM_GENGRID_DATA_GET(obj, sd);
3687
3688    it = _elm_gengrid_item_new(sd, itc, data, func, func_data);
3689    if (!it) return NULL;
3690
3691    if (!sd->state)
3692      {
3693         sd->state = eina_inlist_sorted_state_new();
3694         eina_inlist_sorted_state_init(sd->state, sd->items);
3695      }
3696
3697    sd->item_compare_cb = comp;
3698    sd->items = eina_inlist_sorted_state_insert
3699        (sd->items, EINA_INLIST_GET(it), _elm_gengrid_item_compare, sd->state);
3700    _item_position_update(sd->items, 0);
3701
3702    if (sd->calc_job) ecore_job_del(sd->calc_job);
3703    sd->calc_job = ecore_job_add(_calc_job, sd);
3704
3705    return (Elm_Object_Item *)it;
3706 }
3707
3708 EAPI void
3709 elm_gengrid_horizontal_set(Evas_Object *obj,
3710                            Eina_Bool horizontal)
3711 {
3712    ELM_GENGRID_CHECK(obj);
3713    ELM_GENGRID_DATA_GET(obj, sd);
3714
3715    horizontal = !!horizontal;
3716    if (horizontal == sd->horizontal) return;
3717    sd->horizontal = horizontal;
3718
3719    /* Update the items to conform to the new layout */
3720    if (sd->calc_job) ecore_job_del(sd->calc_job);
3721    sd->calc_job = ecore_job_add(_calc_job, sd);
3722 }
3723
3724 EAPI Eina_Bool
3725 elm_gengrid_horizontal_get(const Evas_Object *obj)
3726 {
3727    ELM_GENGRID_CHECK(obj) EINA_FALSE;
3728    ELM_GENGRID_DATA_GET(obj, sd);
3729
3730    return sd->horizontal;
3731 }
3732
3733 EAPI void
3734 elm_gengrid_clear(Evas_Object *obj)
3735 {
3736    ELM_GENGRID_CHECK(obj);
3737
3738    _elm_gengrid_clear(obj, EINA_FALSE);
3739 }
3740
3741 EINA_DEPRECATED EAPI const Evas_Object *
3742 elm_gengrid_item_object_get(const Elm_Object_Item *it)
3743 {
3744    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, NULL);
3745
3746    return VIEW(it);
3747 }
3748
3749 EAPI void
3750 elm_gengrid_item_update(Elm_Object_Item *item)
3751 {
3752    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
3753
3754    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
3755
3756    if (!it->realized) return;
3757    if (it->want_unrealize) return;
3758    if (!VIEW(it)) return;
3759
3760    const char *part;
3761    Evas_Object *c;
3762    Eina_List *texts = elm_widget_stringlist_get
3763      (edje_object_data_get(VIEW(it), "texts"));
3764    EINA_LIST_FREE(texts, part)
3765      edje_object_part_text_set(VIEW(it), part, NULL);
3766    EINA_LIST_FREE(it->content_objs, c)
3767       {
3768          // FIXME: For animation, befor del, processing edc.
3769          if (evas_object_smart_type_check(c, "elm_layout"))
3770            edje_object_message_signal_process(elm_layout_edje_get(c));
3771          // FIXME: If parent-child relationship was broken before 'ic'
3772          // is deleted, freeze_pop will not be called. ex) elm_slider
3773          // If layout is used instead of edje, this problme can be
3774          // solved.
3775          if (0 != elm_widget_scroll_freeze_get(c))
3776             elm_widget_scroll_freeze_pop(c);
3777          evas_object_del(c);
3778       }
3779
3780    _item_text_realize(it, VIEW(it), NULL);
3781    _item_state_realize(it, VIEW(it), NULL);
3782    it->content_objs = _item_content_realize(it, VIEW(it), it->content_objs, "contents", NULL);
3783    _item_state_realize(it, VIEW(it), NULL);
3784
3785    if (it->selected)
3786       edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
3787
3788    if (_focus_enabled(ELM_WIDGET_DATA(GG_IT(it)->wsd)->obj))
3789      {
3790         if (GG_IT(it)->wsd->focused)
3791            edje_object_signal_emit (VIEW(GG_IT(it)->wsd->focused), "elm,action,focus_highlight,show", "elm");
3792      }
3793    if (elm_widget_item_disabled_get(it))
3794       edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm");
3795 }
3796
3797 EAPI const Elm_Gengrid_Item_Class *
3798 elm_gengrid_item_item_class_get(const Elm_Object_Item *it)
3799 {
3800    Elm_Gen_Item *item = (Elm_Gen_Item *)it;
3801
3802    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, NULL);
3803
3804    if (item->generation < GG_IT(item)->wsd->generation) return NULL;
3805    return item->itc;
3806 }
3807
3808 EAPI void
3809 elm_gengrid_item_fields_update(Elm_Object_Item *item,
3810                                const char *parts,
3811                                Elm_Gengrid_Item_Field_Type itf)
3812 {
3813    ELM_GENGRID_ITEM_CHECK_OR_RETURN(item);
3814    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
3815
3816    if ((!itf) || (itf & ELM_GENGRID_ITEM_FIELD_TEXT))
3817      {
3818         _item_text_realize(it, VIEW(it), parts);
3819      }
3820    if ((!itf) || (itf & ELM_GENGRID_ITEM_FIELD_CONTENT))
3821      {
3822         it->content_objs = _item_content_realize
3823            (it, VIEW(it), it->content_objs, "contents", parts);
3824      }
3825    if ((!itf) || (itf & ELM_GENGRID_ITEM_FIELD_STATE))
3826      {
3827      _item_state_realize(it, VIEW(it), parts);
3828      }
3829 }
3830
3831 EAPI void
3832 elm_gengrid_item_item_class_update(Elm_Object_Item *item,
3833                                    const Elm_Gengrid_Item_Class *itc)
3834 {
3835    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
3836
3837    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
3838    EINA_SAFETY_ON_NULL_RETURN(itc);
3839
3840    if (it->generation < GG_IT(it)->wsd->generation) return;
3841    it->itc = itc;
3842    _view_theme_update(it);
3843    elm_gengrid_item_update(item);
3844 }
3845
3846 EAPI void
3847 elm_gengrid_item_pos_get(const Elm_Object_Item *it,
3848                          unsigned int *x,
3849                          unsigned int *y)
3850 {
3851    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
3852
3853    if (x) *x = ((Elm_Gen_Item *)it)->x;
3854    if (y) *y = ((Elm_Gen_Item *)it)->y;
3855 }
3856
3857 EAPI void
3858 elm_gengrid_multi_select_set(Evas_Object *obj,
3859                              Eina_Bool multi)
3860 {
3861    ELM_GENGRID_CHECK(obj);
3862    ELM_GENGRID_DATA_GET(obj, sd);
3863
3864    sd->multi = !!multi;
3865    if (!sd->multi && sd->selected)
3866      {
3867         Eina_List *l, *ll;
3868         Elm_Gen_Item *it;
3869         Elm_Gen_Item *last = sd->selected->data;
3870         EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it)
3871            if (last != it) _item_unselect(it);
3872      }
3873 }
3874
3875 EAPI Eina_Bool
3876 elm_gengrid_multi_select_get(const Evas_Object *obj)
3877 {
3878    ELM_GENGRID_CHECK(obj) EINA_FALSE;
3879    ELM_GENGRID_DATA_GET(obj, sd);
3880
3881    return sd->multi;
3882 }
3883
3884 EAPI Elm_Object_Item *
3885 elm_gengrid_selected_item_get(const Evas_Object *obj)
3886 {
3887    ELM_GENGRID_CHECK(obj) NULL;
3888    ELM_GENGRID_DATA_GET(obj, sd);
3889
3890    if (sd->selected) return sd->selected->data;
3891    return NULL;
3892 }
3893
3894 EAPI const Eina_List *
3895 elm_gengrid_selected_items_get(const Evas_Object *obj)
3896 {
3897    ELM_GENGRID_CHECK(obj) NULL;
3898    ELM_GENGRID_DATA_GET(obj, sd);
3899
3900    return sd->selected;
3901 }
3902
3903 EAPI void
3904 elm_gengrid_item_selected_set(Elm_Object_Item *item,
3905                               Eina_Bool selected)
3906 {
3907    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
3908    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
3909
3910    if ((it->generation < GG_IT(it)->wsd->generation) ||
3911        elm_widget_item_disabled_get(it))
3912      return;
3913    if (selected) _item_highlight(it);
3914    else _item_unhighlight(it);
3915
3916    if (it->selected == selected) return;
3917
3918    if (selected) _item_select(it);
3919    else _item_unselect(it);
3920 }
3921
3922 EAPI Eina_Bool
3923 elm_gengrid_item_selected_get(const Elm_Object_Item *it)
3924 {
3925    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
3926
3927    return ((Elm_Gen_Item *)it)->selected;
3928 }
3929
3930 EAPI Eina_List *
3931 elm_gengrid_realized_items_get(const Evas_Object *obj)
3932 {
3933    Eina_List *list = NULL;
3934    Elm_Gen_Item *it;
3935
3936    ELM_GENGRID_CHECK(obj) NULL;
3937    ELM_GENGRID_DATA_GET(obj, sd);
3938
3939    EINA_INLIST_FOREACH(sd->items, it)
3940      {
3941         if (it->realized) list = eina_list_append(list, (Elm_Object_Item *)it);
3942      }
3943    return list;
3944 }
3945
3946 EAPI void
3947 elm_gengrid_realized_items_update(Evas_Object *obj)
3948 {
3949    Eina_List *list, *l;
3950    Elm_Object_Item *it;
3951
3952    ELM_GENGRID_CHECK(obj);
3953
3954    list = elm_gengrid_realized_items_get(obj);
3955    EINA_LIST_FOREACH(list, l, it)
3956      elm_gengrid_item_update(it);
3957 }
3958
3959 static Evas_Object *
3960 _elm_gengrid_item_label_create(void *data,
3961                                Evas_Object *obj __UNUSED__,
3962                                Evas_Object *tooltip,
3963                                void *it   __UNUSED__)
3964 {
3965    Evas_Object *label = elm_label_add(tooltip);
3966    if (!label)
3967      return NULL;
3968    elm_object_style_set(label, "tooltip");
3969    elm_object_text_set(label, data);
3970    return label;
3971 }
3972
3973 static void
3974 _elm_gengrid_item_label_del_cb(void *data,
3975                                Evas_Object *obj __UNUSED__,
3976                                void *event_info __UNUSED__)
3977 {
3978    eina_stringshare_del(data);
3979 }
3980
3981 EAPI void
3982 elm_gengrid_item_tooltip_text_set(Elm_Object_Item *it,
3983                                   const char *text)
3984 {
3985    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
3986
3987    text = eina_stringshare_add(text);
3988    elm_gengrid_item_tooltip_content_cb_set
3989      (it, _elm_gengrid_item_label_create, text,
3990      _elm_gengrid_item_label_del_cb);
3991 }
3992
3993 EAPI void
3994 elm_gengrid_item_tooltip_content_cb_set(Elm_Object_Item *item,
3995                                         Elm_Tooltip_Item_Content_Cb func,
3996                                         const void *data,
3997                                         Evas_Smart_Cb del_cb)
3998 {
3999    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4000
4001    ELM_GENGRID_ITEM_CHECK_OR_GOTO(it, error);
4002
4003    if ((it->tooltip.content_cb == func) && (it->tooltip.data == data))
4004      return;
4005
4006    if (it->tooltip.del_cb)
4007      it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
4008    it->tooltip.content_cb = func;
4009    it->tooltip.data = data;
4010    it->tooltip.del_cb = del_cb;
4011    if (VIEW(it))
4012      {
4013         elm_widget_item_tooltip_content_cb_set
4014           (it, it->tooltip.content_cb, it->tooltip.data, NULL);
4015         elm_widget_item_tooltip_style_set(it, it->tooltip.style);
4016         elm_widget_item_tooltip_window_mode_set(it, it->tooltip.free_size);
4017      }
4018
4019    return;
4020
4021 error:
4022    if (del_cb) del_cb((void *)data, NULL, NULL);
4023 }
4024
4025 EAPI void
4026 elm_gengrid_item_tooltip_unset(Elm_Object_Item *item)
4027 {
4028    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4029
4030    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
4031
4032    if ((VIEW(it)) && (it->tooltip.content_cb))
4033      elm_widget_item_tooltip_unset(it);
4034
4035    if (it->tooltip.del_cb)
4036      it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
4037    it->tooltip.del_cb = NULL;
4038    it->tooltip.content_cb = NULL;
4039    it->tooltip.data = NULL;
4040    it->tooltip.free_size = EINA_FALSE;
4041    if (it->tooltip.style)
4042      elm_gengrid_item_tooltip_style_set(item, NULL);
4043 }
4044
4045 EAPI void
4046 elm_gengrid_item_tooltip_style_set(Elm_Object_Item *it,
4047                                    const char *style)
4048 {
4049    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
4050
4051    eina_stringshare_replace(&((Elm_Gen_Item *)it)->tooltip.style, style);
4052    if (VIEW(it)) elm_widget_item_tooltip_style_set(it, style);
4053 }
4054
4055 EAPI const char *
4056 elm_gengrid_item_tooltip_style_get(const Elm_Object_Item *it)
4057 {
4058    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, NULL);
4059
4060    return ((Elm_Gen_Item *)it)->tooltip.style;
4061 }
4062
4063 EAPI Eina_Bool
4064 elm_gengrid_item_tooltip_window_mode_set(Elm_Object_Item *it,
4065                                          Eina_Bool disable)
4066 {
4067    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4068
4069    ((Elm_Gen_Item *)it)->tooltip.free_size = disable;
4070    if (VIEW(it)) return elm_widget_item_tooltip_window_mode_set(it, disable);
4071
4072    return EINA_TRUE;
4073 }
4074
4075 EAPI Eina_Bool
4076 elm_gengrid_item_tooltip_window_mode_get(const Elm_Object_Item *it)
4077 {
4078    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
4079
4080    return ((Elm_Gen_Item *)it)->tooltip.free_size;
4081 }
4082
4083 EAPI void
4084 elm_gengrid_item_cursor_set(Elm_Object_Item *it,
4085                             const char *cursor)
4086 {
4087    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
4088
4089    eina_stringshare_replace(&((Elm_Gen_Item *)it)->mouse_cursor, cursor);
4090    if (VIEW(it)) elm_widget_item_cursor_set(it, cursor);
4091 }
4092
4093 EAPI const char *
4094 elm_gengrid_item_cursor_get(const Elm_Object_Item *it)
4095 {
4096    return elm_widget_item_cursor_get(it);
4097 }
4098
4099 EAPI void
4100 elm_gengrid_item_cursor_unset(Elm_Object_Item *item)
4101 {
4102    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4103
4104    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
4105    if (!it->mouse_cursor)
4106      return;
4107
4108    if (VIEW(it))
4109      elm_widget_item_cursor_unset(it);
4110
4111    eina_stringshare_del(it->mouse_cursor);
4112    it->mouse_cursor = NULL;
4113 }
4114
4115 EAPI void
4116 elm_gengrid_item_cursor_style_set(Elm_Object_Item *it,
4117                                   const char *style)
4118 {
4119    elm_widget_item_cursor_style_set(it, style);
4120 }
4121
4122 EAPI const char *
4123 elm_gengrid_item_cursor_style_get(const Elm_Object_Item *it)
4124 {
4125    return elm_widget_item_cursor_style_get(it);
4126 }
4127
4128 EAPI void
4129 elm_gengrid_item_cursor_engine_only_set(Elm_Object_Item *it,
4130                                         Eina_Bool engine_only)
4131 {
4132    elm_widget_item_cursor_engine_only_set(it, engine_only);
4133 }
4134
4135 EAPI Eina_Bool
4136 elm_gengrid_item_cursor_engine_only_get(const Elm_Object_Item *it)
4137 {
4138    return elm_widget_item_cursor_engine_only_get(it);
4139 }
4140
4141 EAPI void
4142 elm_gengrid_reorder_mode_set(Evas_Object *obj,
4143                              Eina_Bool reorder_mode)
4144 {
4145    ELM_GENGRID_CHECK(obj);
4146    ELM_GENGRID_DATA_GET(obj, sd);
4147
4148    sd->reorder_mode = !!reorder_mode;
4149 }
4150
4151 EAPI Eina_Bool
4152 elm_gengrid_reorder_mode_get(const Evas_Object *obj)
4153 {
4154    ELM_GENGRID_CHECK(obj) EINA_FALSE;
4155    ELM_GENGRID_DATA_GET(obj, sd);
4156
4157    return sd->reorder_mode;
4158 }
4159
4160 EAPI void
4161 elm_gengrid_bounce_set(Evas_Object *obj,
4162                        Eina_Bool h_bounce,
4163                        Eina_Bool v_bounce)
4164 {
4165    ELM_GENGRID_CHECK(obj);
4166    ELM_GENGRID_DATA_GET(obj, sd);
4167
4168    sd->s_iface->bounce_allow_set(obj, !!h_bounce, !!v_bounce);
4169 }
4170
4171 EAPI void
4172 elm_gengrid_bounce_get(const Evas_Object *obj,
4173                        Eina_Bool *h_bounce,
4174                        Eina_Bool *v_bounce)
4175 {
4176    ELM_GENGRID_CHECK(obj);
4177    ELM_GENGRID_DATA_GET(obj, sd);
4178
4179    sd->s_iface->bounce_allow_get(obj, h_bounce, v_bounce);
4180 }
4181
4182 EAPI void
4183 elm_gengrid_page_relative_set(Evas_Object *obj,
4184                               double h_pagerel,
4185                               double v_pagerel)
4186 {
4187    Evas_Coord pagesize_h;
4188    Evas_Coord pagesize_v;
4189
4190    ELM_GENGRID_CHECK(obj);
4191    ELM_GENGRID_DATA_GET(obj, sd);
4192
4193    sd->s_iface->paging_get(obj, NULL, NULL, &pagesize_h, &pagesize_v);
4194    sd->s_iface->paging_set
4195      (obj, h_pagerel, v_pagerel, pagesize_h, pagesize_v);
4196 }
4197
4198 EAPI void
4199 elm_gengrid_page_relative_get(const Evas_Object *obj,
4200                               double *h_pagerel,
4201                               double *v_pagerel)
4202 {
4203    ELM_GENGRID_CHECK(obj);
4204    ELM_GENGRID_DATA_GET(obj, sd);
4205
4206    sd->s_iface->paging_get(obj, h_pagerel, v_pagerel, NULL, NULL);
4207 }
4208
4209 EAPI void
4210 elm_gengrid_page_size_set(Evas_Object *obj,
4211                           Evas_Coord h_pagesize,
4212                           Evas_Coord v_pagesize)
4213 {
4214    double pagerel_h;
4215    double pagerel_v;
4216
4217    ELM_GENGRID_CHECK(obj);
4218    ELM_GENGRID_DATA_GET(obj, sd);
4219
4220    sd->s_iface->paging_get(obj, &pagerel_h, &pagerel_v, NULL, NULL);
4221    sd->s_iface->paging_set
4222      (obj, pagerel_h, pagerel_v, h_pagesize, v_pagesize);
4223 }
4224
4225 EAPI void
4226 elm_gengrid_current_page_get(const Evas_Object *obj,
4227                              int *h_pagenumber,
4228                              int *v_pagenumber)
4229 {
4230    ELM_GENGRID_CHECK(obj);
4231    ELM_GENGRID_DATA_GET(obj, sd);
4232
4233    sd->s_iface->current_page_get(obj, h_pagenumber, v_pagenumber);
4234 }
4235
4236 EAPI void
4237 elm_gengrid_last_page_get(const Evas_Object *obj,
4238                           int *h_pagenumber,
4239                           int *v_pagenumber)
4240 {
4241    ELM_GENGRID_CHECK(obj);
4242    ELM_GENGRID_DATA_GET(obj, sd);
4243
4244    sd->s_iface->last_page_get(obj, h_pagenumber, v_pagenumber);
4245 }
4246
4247 EAPI void
4248 elm_gengrid_page_show(const Evas_Object *obj,
4249                       int h_pagenumber,
4250                       int v_pagenumber)
4251 {
4252    ELM_GENGRID_CHECK(obj);
4253    ELM_GENGRID_DATA_GET(obj, sd);
4254
4255    sd->s_iface->page_show((Evas_Object *)obj, h_pagenumber, v_pagenumber);
4256 }
4257
4258 EAPI void
4259 elm_gengrid_page_bring_in(const Evas_Object *obj,
4260                           int h_pagenumber,
4261                           int v_pagenumber)
4262 {
4263    ELM_GENGRID_CHECK(obj);
4264    ELM_GENGRID_DATA_GET(obj, sd);
4265
4266    sd->s_iface->page_bring_in((Evas_Object *)obj, h_pagenumber, v_pagenumber);
4267 }
4268
4269 EAPI void
4270 elm_gengrid_longpress_timeout_set(Evas_Object *obj,
4271                                   double timeout)
4272 {
4273    ELM_GENGRID_CHECK(obj);
4274    ELM_GENGRID_DATA_GET(obj, sd);
4275
4276    sd->longpress_timeout = timeout;
4277 }
4278
4279 EAPI double
4280 elm_gengrid_longpress_timeout_get(const Evas_Object *obj)
4281 {
4282    ELM_GENGRID_CHECK(obj);
4283    ELM_GENGRID_DATA_GET(obj, sd);
4284
4285    return sd->longpress_timeout;
4286 }
4287
4288 EAPI void
4289 elm_gengrid_scroller_policy_set(Evas_Object *obj,
4290                                 Elm_Scroller_Policy policy_h,
4291                                 Elm_Scroller_Policy policy_v)
4292 {
4293    ELM_GENGRID_CHECK(obj);
4294    ELM_GENGRID_DATA_GET(obj, sd);
4295
4296    if ((policy_h >= ELM_SCROLLER_POLICY_LAST) ||
4297        (policy_v >= ELM_SCROLLER_POLICY_LAST))
4298      return;
4299
4300    sd->s_iface->policy_set(obj, policy_h, policy_v);
4301 }
4302
4303 EAPI void
4304 elm_gengrid_scroller_policy_get(const Evas_Object *obj,
4305                                 Elm_Scroller_Policy *policy_h,
4306                                 Elm_Scroller_Policy *policy_v)
4307 {
4308    Elm_Scroller_Policy s_policy_h, s_policy_v;
4309
4310    ELM_GENGRID_CHECK(obj);
4311    ELM_GENGRID_DATA_GET(obj, sd);
4312
4313    sd->s_iface->policy_get(obj, &s_policy_h, &s_policy_v);
4314    if (policy_h) *policy_h = (Elm_Scroller_Policy)s_policy_h;
4315    if (policy_v) *policy_v = (Elm_Scroller_Policy)s_policy_v;
4316 }
4317
4318 EAPI Elm_Object_Item *
4319 elm_gengrid_first_item_get(const Evas_Object *obj)
4320 {
4321    ELM_GENGRID_CHECK(obj) NULL;
4322    ELM_GENGRID_DATA_GET_OR_RETURN_VAL(obj, sd, NULL);
4323
4324    if (!sd->items) return NULL;
4325
4326    Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
4327
4328    while ((it) && (it->generation < sd->generation))
4329      it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4330
4331    return (Elm_Object_Item *)it;
4332 }
4333
4334 EAPI Elm_Object_Item *
4335 elm_gengrid_at_xy_item_get(const Evas_Object *obj,
4336                            Evas_Coord x,
4337                            Evas_Coord y,
4338                            int *xposret,
4339                            int *yposret)
4340 {
4341    ELM_GENGRID_CHECK(obj) NULL;
4342    ELM_GENGRID_DATA_GET_OR_RETURN_VAL(obj, sd, NULL);
4343
4344    Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
4345
4346    Evas_Coord l = 0, r = 0, t = 0, b = 0; /* left, right, top, bottom */
4347    Eina_Bool init = EINA_TRUE;
4348
4349    while ((it) && (it->generation < sd->generation))
4350      it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4351
4352    if (it)
4353      do
4354        {
4355           Evas_Coord itx, ity;
4356           Evas_Coord itw, ith;
4357           evas_object_geometry_get(VIEW(it), &itx, &ity, &itw, &ith);
4358
4359           /* Record leftmost, rightmost, top, bottom cords to set posret */
4360           if ((itw > 0) && (ith > 0) && (itx >= 0) && (ity >= 0))
4361             {  /* A scroller, ignore items in negative cords,or not rendered */
4362                if (init)
4363                  {
4364                     l = itx;
4365                     r = itx + itw;
4366                     t = ity;
4367                     b = ity + ith;
4368                     init = EINA_FALSE;
4369                  }
4370                else
4371                  {
4372                     if (itx < l)
4373                       l = itx;
4374                     if ((itx + itw) > r)
4375                       r = itx + itw;
4376                     if (ity < t)
4377                       t = ity;
4378                     if ((ity + ith) > b)
4379                       b = ity + ith;
4380                  }
4381             }
4382
4383           if (ELM_RECTS_INTERSECT
4384                 (itx, ity, itw, ith, x, y, 1, 1))
4385             {
4386                if (yposret)
4387                  {
4388                     if (y <= (ity + (ith / 4))) *yposret = -1;
4389                     else if (y >= (ity + ith - (ith / 4)))
4390                       *yposret = 1;
4391                     else *yposret = 0;
4392                  }
4393
4394                if (xposret)
4395                  {
4396                     if (x <= (itx + (itw / 4))) *xposret = -1;
4397                     else if (x >= (itx + itw - (itw / 4)))
4398                       *xposret = 1;
4399                     else *xposret = 0;
4400                  }
4401
4402                return (Elm_Object_Item *) it;
4403             }
4404
4405        } while ((it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next)));
4406
4407    /* No item found, tell the user if hit left/right/top/bottom of items */
4408    if (xposret)
4409      {
4410         *xposret = 0;
4411         if (x < l)
4412           *xposret = (-1);
4413         else if (x > r)
4414           *xposret = (1);
4415      }
4416
4417    if (yposret)
4418      {
4419         *yposret = 0;
4420         if (y < t)
4421           *yposret = (-1);
4422         else if (y > b)
4423           *yposret = (1);
4424      }
4425
4426    return NULL;
4427 }
4428
4429 EAPI Elm_Object_Item *
4430 elm_gengrid_last_item_get(const Evas_Object *obj)
4431 {
4432    ELM_GENGRID_CHECK(obj) NULL;
4433    ELM_GENGRID_DATA_GET_OR_RETURN_VAL(obj, sd, NULL);
4434
4435    if (!sd->items) return NULL;
4436
4437    Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
4438    while ((it) && (it->generation < sd->generation))
4439      it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4440
4441    return (Elm_Object_Item *)it;
4442 }
4443
4444 EAPI Elm_Object_Item *
4445 elm_gengrid_item_next_get(const Elm_Object_Item *item)
4446 {
4447    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4448
4449    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, NULL);
4450
4451    while (it)
4452      {
4453         it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
4454         if ((it) && (it->generation == GG_IT(it)->wsd->generation)) break;
4455      }
4456
4457    return (Elm_Object_Item *)it;
4458 }
4459
4460 EAPI Elm_Object_Item *
4461 elm_gengrid_item_prev_get(const Elm_Object_Item *item)
4462 {
4463    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4464
4465    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, NULL);
4466
4467    while (it)
4468      {
4469         it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
4470         if ((it) && (it->generation == GG_IT(it)->wsd->generation)) break;
4471      }
4472
4473    return (Elm_Object_Item *)it;
4474 }
4475
4476 EAPI void
4477 elm_gengrid_item_show(Elm_Object_Item *item,
4478                       Elm_Gengrid_Item_Scrollto_Type type)
4479 {
4480    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4481    Elm_Gengrid_Smart_Data *sd;
4482
4483    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
4484    sd = GG_IT(it)->wsd;
4485
4486    if ((it->generation < sd->generation)) return;
4487
4488    sd->show_region = EINA_TRUE;
4489    sd->show_it = it;
4490    sd->scroll_to_type = type;
4491
4492    if (sd->calc_job) ecore_job_del(sd->calc_job);
4493    sd->calc_job = ecore_job_add(_calc_job, sd);
4494 }
4495
4496 EAPI void
4497 elm_gengrid_item_bring_in(Elm_Object_Item *item,
4498                           Elm_Gengrid_Item_Scrollto_Type type)
4499 {
4500    Elm_Gengrid_Smart_Data *sd;
4501    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4502
4503    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
4504    sd = GG_IT(it)->wsd;
4505
4506    if (it->generation < sd->generation) return;
4507
4508    sd->bring_in = EINA_TRUE;
4509    sd->bring_in_it = it;
4510    sd->scroll_to_type = type;
4511
4512    if (sd->calc_job) ecore_job_del(sd->calc_job);
4513    sd->calc_job = ecore_job_add(_calc_job, sd);
4514 }
4515
4516 EAPI void
4517 elm_gengrid_filled_set(Evas_Object *obj,
4518                        Eina_Bool fill)
4519 {
4520    ELM_GENGRID_CHECK(obj);
4521    ELM_GENGRID_DATA_GET(obj, sd);
4522
4523    fill = !!fill;
4524    if (sd->filled != fill)
4525      sd->filled = fill;
4526 }
4527
4528 EAPI Eina_Bool
4529 elm_gengrid_filled_get(const Evas_Object *obj)
4530 {
4531    ELM_GENGRID_CHECK(obj) EINA_FALSE;
4532    ELM_GENGRID_DATA_GET(obj, sd);
4533
4534    return sd->filled;
4535 }
4536
4537 EAPI unsigned int
4538 elm_gengrid_items_count(const Evas_Object *obj)
4539 {
4540    ELM_GENGRID_CHECK(obj) 0;
4541    ELM_GENGRID_DATA_GET(obj, sd);
4542
4543    return sd->item_count;
4544 }
4545
4546 EAPI Elm_Gengrid_Item_Class *
4547 elm_gengrid_item_class_new(void)
4548 {
4549    Elm_Gengrid_Item_Class *itc;
4550
4551    itc = calloc(1, sizeof(Elm_Gengrid_Item_Class));
4552    if (!itc)
4553      return NULL;
4554    itc->version = CLASS_ALLOCATED;
4555    itc->refcount = 1;
4556    itc->delete_me = EINA_FALSE;
4557
4558    return itc;
4559 }
4560
4561 EAPI void
4562 elm_gengrid_item_class_free(Elm_Gengrid_Item_Class *itc)
4563 {
4564    if (!itc || (itc->version != CLASS_ALLOCATED)) return;
4565
4566    if (!itc->delete_me) itc->delete_me = EINA_TRUE;
4567    if (itc->refcount > 0) elm_gengrid_item_class_unref(itc);
4568    else
4569      {
4570         itc->version = 0;
4571         free(itc);
4572      }
4573 }
4574
4575 EAPI void
4576 elm_gengrid_item_class_ref(Elm_Gengrid_Item_Class *itc)
4577 {
4578    if (itc && (itc->version == CLASS_ALLOCATED))
4579      {
4580         itc->refcount++;
4581         if (itc->refcount == 0) itc->refcount--;
4582      }
4583 }
4584
4585 EAPI void
4586 elm_gengrid_item_class_unref(Elm_Gengrid_Item_Class *itc)
4587 {
4588    if (itc && (itc->version == CLASS_ALLOCATED))
4589      {
4590         if (itc->refcount > 0) itc->refcount--;
4591         if (itc->delete_me && (!itc->refcount))
4592           elm_gengrid_item_class_free(itc);
4593      }
4594 }
4595
4596 EAPI void
4597 elm_gengrid_select_mode_set(Evas_Object *obj,
4598                             Elm_Object_Select_Mode mode)
4599 {
4600    ELM_GENGRID_CHECK(obj);
4601    ELM_GENGRID_DATA_GET(obj, sd);
4602
4603    if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
4604      return;
4605
4606    if (sd->select_mode != mode)
4607      sd->select_mode = mode;
4608 }
4609
4610 EAPI Elm_Object_Select_Mode
4611 elm_gengrid_select_mode_get(const Evas_Object *obj)
4612 {
4613    ELM_GENGRID_CHECK(obj) ELM_OBJECT_SELECT_MODE_MAX;
4614    ELM_GENGRID_DATA_GET(obj, sd);
4615
4616    return sd->select_mode;
4617 }
4618
4619 EAPI void
4620 elm_gengrid_highlight_mode_set(Evas_Object *obj,
4621                                Eina_Bool highlight)
4622 {
4623    ELM_GENGRID_CHECK(obj);
4624    ELM_GENGRID_DATA_GET(obj, sd);
4625
4626    sd->highlight = !!highlight;
4627 }
4628
4629 EAPI Eina_Bool
4630 elm_gengrid_highlight_mode_get(const Evas_Object *obj)
4631 {
4632    ELM_GENGRID_CHECK(obj) EINA_FALSE;
4633    ELM_GENGRID_DATA_GET(obj, sd);
4634
4635    return sd->highlight;
4636 }
4637
4638 EAPI int
4639 elm_gengrid_item_index_get(const Elm_Object_Item *item)
4640 {
4641    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4642
4643    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, -1);
4644
4645    return it->position;
4646 }
4647
4648 EAPI void
4649 elm_gengrid_item_select_mode_set(Elm_Object_Item *item,
4650                                  Elm_Object_Select_Mode mode)
4651 {
4652    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4653
4654    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it);
4655
4656    if (it->generation < GG_IT(it)->wsd->generation) return;
4657    if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
4658      return;
4659
4660    if (it->select_mode != mode)
4661      it->select_mode = mode;
4662
4663    if (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
4664      elm_gengrid_item_update(item);
4665 }
4666
4667 EAPI Elm_Object_Select_Mode
4668 elm_gengrid_item_select_mode_get(const Elm_Object_Item *item)
4669 {
4670    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4671
4672    ELM_GENGRID_ITEM_CHECK_OR_RETURN(it, ELM_OBJECT_SELECT_MODE_MAX);
4673
4674    return it->select_mode;
4675 }
4676
4677 #if GENGRID_FX_SUPPORT
4678 EAPI void
4679 elm_gengrid_fx_mode_set(Evas_Object *obj, Eina_Bool mode)
4680 {
4681    ELM_GENGRID_CHECK(obj);
4682    ELM_GENGRID_DATA_GET(obj, sd);
4683
4684    sd->fx_mode = mode;
4685 }
4686
4687 EAPI Eina_Bool
4688 elm_gengrid_fx_mode_get(const Evas_Object *obj)
4689 {
4690    ELM_GENGRID_CHECK(obj) EINA_FALSE;
4691    ELM_GENGRID_DATA_GET(obj, sd);
4692
4693    return sd->fx_mode;
4694 }
4695
4696 static Proxy_Item *
4697 _elm_gengrid_proxy_item_new(const Elm_Object_Item *item)
4698 {
4699    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4700    if ((!it) || (!it->item)) return EINA_FALSE;
4701    int w, h;
4702
4703    Proxy_Item *pi = NULL;
4704    pi = calloc(1, sizeof(Proxy_Item));
4705    if (!pi) return NULL;
4706
4707    pi->proxy = evas_object_image_filled_add
4708       (evas_object_evas_get(ELM_WIDGET_DATA(GG_IT(it)->wsd)->obj));
4709    if (!pi->proxy)
4710      {
4711         free(pi);
4712         return NULL;
4713      }
4714    evas_object_clip_set(pi->proxy, evas_object_clip_get(GG_IT(it)->wsd->pan_obj));
4715    evas_object_smart_member_add(pi->proxy, GG_IT(it)->wsd->pan_obj);
4716    evas_object_hide(pi->proxy);
4717    evas_object_image_source_set(pi->proxy, VIEW(it));
4718
4719    GG_IT(it)->has_proxy_it = EINA_TRUE;
4720    pi->it = it;
4721    pi->num = it->item->num;
4722    pi->x = it->item->scrl_x;
4723    pi->y = it->item->scrl_y;
4724    pi->w = it->item->w;
4725    pi->h = it->item->h;
4726
4727    evas_object_geometry_get(VIEW(it), NULL, NULL, &w, &h);
4728
4729    if (w <= 0 || h <= 0)
4730      {
4731         evas_object_size_hint_min_get(VIEW(it), &w, &h);
4732         evas_object_size_hint_min_set(pi->proxy, w, h);
4733      }
4734    else evas_object_resize(pi->proxy, w, h);
4735
4736    return pi;
4737 }
4738
4739 static Eina_Bool
4740 _elm_gengrid_fx_capture(Evas_Object *obj, int level)
4741 {
4742    ELM_GENGRID_DATA_GET(obj, sd);
4743
4744    Elm_Gen_Item *it;
4745    Proxy_Item *pi;
4746    Evas_Coord ox, oy, ow, oh;
4747
4748    if ((!sd->rendered) || (sd->fx_playing)) return EINA_FALSE;
4749    if ((!level) && (sd->fx_first_captured)) return EINA_FALSE;
4750    if ((level) && (!sd->fx_first_captured)) return EINA_FALSE;
4751
4752    evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
4753
4754    if (!level)
4755      {
4756         sd->fx_first_captured = EINA_TRUE;
4757         EINA_LIST_FREE(sd->capture_before_items, pi)
4758           {
4759              if (pi->proxy) evas_object_smart_member_del(pi->proxy);
4760              if (pi->proxy) evas_object_del(pi->proxy);
4761              free(pi);
4762           }
4763      }
4764    else
4765      {
4766         EINA_LIST_FREE(sd->capture_after_items, pi)
4767           {
4768              if (pi->proxy) evas_object_smart_member_del(pi->proxy);
4769              if (pi->proxy) evas_object_del(pi->proxy);
4770              free(pi);
4771           }
4772      }
4773    EINA_INLIST_FOREACH(sd->items, it)
4774      {
4775         if (it->realized)
4776           {
4777              pi = _elm_gengrid_proxy_item_new((Elm_Object_Item *)it);
4778              if (!pi) continue;
4779              if (!level)
4780                sd->capture_before_items = eina_list_append(sd->capture_before_items, pi);
4781              else
4782                sd->capture_after_items = eina_list_append(sd->capture_after_items, pi);
4783           }
4784      }
4785    return EINA_TRUE;
4786 }
4787
4788 static Elm_Gen_FX_Item *
4789 _elm_gengrid_fx_item_find(const Elm_Object_Item *item)
4790 {
4791    Elm_Gen_Item *it = (Elm_Gen_Item *)item;
4792    if (!it) return EINA_FALSE;
4793
4794    Elm_Gengrid_Smart_Data *sd = GG_IT(it)->wsd;
4795    if (!sd) return NULL;
4796
4797    Elm_Gen_FX_Item *fi = NULL;
4798    Eina_List *l;
4799
4800    EINA_LIST_FOREACH(sd->fx_items, l, fi)
4801      {
4802         if (fi->it == it) return fi;
4803      }
4804    return NULL;
4805 }
4806
4807 static Elm_Gen_FX_Item *
4808 _elm_gengrid_fx_item_new(const Proxy_Item *pi)
4809 {
4810    if ((!pi) || (!pi->it)) return NULL;
4811
4812    Elm_Gen_FX_Item *fi = NULL;
4813    fi = calloc(1, sizeof(Elm_Gen_FX_Item));
4814    if (!fi) return NULL;
4815
4816    fi->it = pi->it;
4817    GG_IT(fi->it)->fi = fi;
4818    fi->proxy = pi->proxy;
4819    fi->num = pi->num;
4820    fi->from.x = fi->to.x = pi->x;
4821    fi->from.y = fi->to.y = pi->y;
4822    fi->from.w = fi->to.w = pi->w;
4823    fi->from.h = fi->to.h = pi->h;
4824    fi->update = EINA_FALSE;
4825
4826    return fi;
4827 }
4828
4829 EAPI void
4830 _elm_gengrid_fx_items_make(Evas_Object *obj)
4831 {
4832    ELM_GENGRID_CHECK(obj);
4833    ELM_GENGRID_DATA_GET(obj, sd);
4834
4835    Elm_Gen_FX_Item *fi;
4836    Proxy_Item *pi;
4837    Eina_List *l;
4838    Evas_Coord ox, oy, ow, oh;
4839
4840    evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
4841
4842    EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
4843      {
4844         fi = _elm_gengrid_fx_item_new(pi);
4845         if (fi) sd->fx_items = eina_list_append(sd->fx_items, fi);
4846      }
4847
4848    EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
4849      {
4850         fi = _elm_gengrid_fx_item_find((Elm_Object_Item *)pi->it);
4851
4852         if (fi)
4853           {
4854              fi->type = ELM_GEN_ITEM_FX_TYPE_SAME;
4855              fi->update = EINA_TRUE;
4856              fi->to.x = pi->x;
4857              fi->to.y = pi->y;
4858              fi->to.w = pi->w;
4859              fi->to.h = pi->h;
4860           }
4861         else
4862           {
4863              fi = _elm_gengrid_fx_item_new(pi);
4864              if (fi)
4865                {
4866                   fi->type = ELM_GEN_ITEM_FX_TYPE_ADD;
4867                   fi->update = EINA_TRUE;
4868                   sd->fx_items = eina_list_append(sd->fx_items, fi);
4869                }
4870           }
4871      }
4872
4873    EINA_LIST_FOREACH(sd->fx_items, l, fi)
4874      {
4875         if (!fi->update)
4876           {
4877              fi->type = ELM_GEN_ITEM_FX_TYPE_DEL;
4878              fi->update = EINA_TRUE;
4879           }
4880      }
4881 }
4882
4883 static void
4884 _item_fx_op(Elm_Transit_Effect *data, Elm_Transit *transit __UNUSED__, double progress __UNUSED__)
4885 {
4886    Elm_Gen_FX_Item *fi = data;
4887    evas_object_lower(fi->proxy);
4888    return;
4889 }
4890
4891 static void
4892 _item_fx_done(Elm_Transit_Effect *data, Elm_Transit *transit __UNUSED__)
4893 {
4894    Elm_Gen_FX_Item *fx_done_it = data;
4895    Elm_Gengrid_Smart_Data *sd;
4896
4897    if ((!fx_done_it) || (!fx_done_it->it)) return;
4898
4899    sd = GG_IT(fx_done_it->it)->wsd;
4900    if (!sd) return;
4901
4902    evas_object_image_source_visible_set(fx_done_it->proxy, EINA_TRUE);
4903    evas_object_lower(fx_done_it->proxy);
4904
4905    evas_object_move(VIEW(fx_done_it->it), fx_done_it->to.x, fx_done_it->to.y);
4906    GG_IT(fx_done_it->it)->has_proxy_it = EINA_FALSE;
4907
4908    evas_object_clip_unset(fx_done_it->proxy);
4909 }
4910
4911 static void
4912 _item_fx_del_cb(void *data, Elm_Transit *transit __UNUSED__)
4913 {
4914    Elm_Gen_FX_Item *fx_done_it = data;
4915    Elm_Gen_Item *it = NULL;
4916    Proxy_Item *pi = NULL;
4917    Eina_List *l;
4918    Elm_Gengrid_Smart_Data *sd;
4919    Eina_Bool has_del_it = EINA_FALSE;
4920
4921    if ((!fx_done_it) || (!fx_done_it->it)) return;
4922
4923    sd = GG_IT(fx_done_it->it)->wsd;
4924    if (!sd) return;
4925
4926    sd->fx_items = eina_list_remove(sd->fx_items, fx_done_it);
4927    free(fx_done_it);
4928
4929    if (!eina_list_count(sd->fx_items))
4930      {
4931         EINA_LIST_FREE (sd->pending_unrealized_items, it)
4932           {
4933              GG_IT(it)->has_proxy_it = EINA_FALSE;
4934              _elm_gengrid_item_unrealize(it, EINA_FALSE);
4935           }
4936
4937         EINA_LIST_FREE (sd->pending_del_items, it)
4938           {
4939              _item_del_post_fx_process(it);
4940              elm_widget_item_free(it);
4941              has_del_it = EINA_TRUE;
4942           }
4943         EINA_LIST_FOREACH(sd->capture_before_items, l, pi)
4944            evas_object_hide(pi->proxy);
4945         EINA_LIST_FOREACH(sd->capture_after_items, l, pi)
4946            evas_object_hide(pi->proxy);
4947
4948         sd->fx_playing = EINA_FALSE;
4949         sd->fx_first_captured = EINA_FALSE;
4950
4951         sd->pan_changed = EINA_TRUE;
4952         if (!has_del_it) evas_object_smart_changed(sd->pan_obj);
4953      }
4954 }
4955
4956 static void
4957 _elm_gengrid_fx_play(Evas_Object *obj)
4958 {
4959    ELM_GENGRID_CHECK(obj);
4960    ELM_GENGRID_DATA_GET(obj, sd);
4961
4962    Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
4963    Elm_Gen_FX_Item *fi;
4964    Eina_List *l;
4965
4966    if (!sd->fx_mode) return;
4967
4968    EINA_LIST_FREE(sd->fx_items, fi)
4969      {
4970         if (fi->trans) elm_transit_del(fi->trans);
4971         free(fi);
4972      }
4973
4974    _elm_gengrid_fx_items_make(obj);
4975    if (!eina_list_count(sd->fx_items)) return;
4976    sd->fx_playing = EINA_TRUE;
4977
4978    evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
4979    evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
4980
4981    EINA_LIST_FOREACH(sd->fx_items, l, fi)
4982      {
4983         if (!fi->proxy) continue;
4984
4985         if ((fi->from.y <= oy) || (fi->from.y + fi->from.h >= oy + oh))
4986           {
4987              evas_object_move(VIEW(fi->it), fi->to.x, fi->to.y);
4988           }
4989         else if ((fi->to.y <= oy) || (fi->to.y + fi->to.h >= oy + oh))
4990           {
4991              evas_object_move(VIEW(fi->it), fi->from.x, fi->from.y);
4992           }
4993
4994         evas_object_resize(fi->proxy, fi->to.w, fi->to.h);
4995         evas_object_show(fi->proxy);
4996
4997         fi->trans = elm_transit_add();
4998         elm_transit_object_add(fi->trans, fi->proxy);
4999         elm_transit_event_enabled_set(fi->trans, EINA_FALSE);
5000
5001         evas_object_image_source_visible_set(fi->proxy, EINA_FALSE);
5002         elm_transit_tween_mode_set(fi->trans, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
5003
5004         if (fi->type == ELM_GEN_ITEM_FX_TYPE_SAME)
5005           {
5006              evas_object_raise(fi->proxy);
5007              elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
5008           }
5009
5010         else if (fi->type == ELM_GEN_ITEM_FX_TYPE_ADD)
5011           {
5012              elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
5013              elm_transit_effect_color_add(fi->trans, 0, 0, 0, 0, 255, 255, 255, 255);
5014              elm_transit_effect_zoom_add(fi->trans, 0.5, 1.0);
5015           }
5016         else if (fi->type == ELM_GEN_ITEM_FX_TYPE_DEL)
5017           {
5018              elm_transit_effect_translation_add(fi->trans, fi->from.x, fi->from.y, fi->to.x, fi->to.y);
5019              elm_transit_effect_color_add(fi->trans, 255, 255, 255, 255, 0, 0, 0, 0);
5020              elm_transit_effect_zoom_add(fi->trans, 1.0, 0.5);
5021           }
5022         elm_transit_effect_add(fi->trans, _item_fx_op, fi, _item_fx_done);
5023         elm_transit_del_cb_set(fi->trans, _item_fx_del_cb, fi);
5024
5025         elm_transit_duration_set(fi->trans, FX_MOVE_TIME);
5026         elm_transit_objects_final_state_keep_set(fi->trans, EINA_FALSE);
5027         elm_transit_go(fi->trans);
5028      }
5029 }
5030 #endif