Tizen 2.1 base
[framework/uifw/elementary.git] / src / lib / elm_index.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include "els_box.h"
4 #include "elm_widget_index.h"
5
6 EAPI const char ELM_INDEX_SMART_NAME[] = "elm_index";
7
8 static const char SIG_CHANGED[] = "changed";
9 static const char SIG_DELAY_CHANGED[] = "delay,changed";
10 static const char SIG_SELECTED[] = "selected";
11 static const char SIG_LEVEL_UP[] = "level,up";
12 static const char SIG_LEVEL_DOWN[] = "level,down";
13 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
14    {SIG_CHANGED, ""},
15    {SIG_DELAY_CHANGED, ""},
16    {SIG_SELECTED, ""},
17    {SIG_LEVEL_UP, ""},
18    {SIG_LEVEL_DOWN, ""},
19    {NULL, NULL}
20 };
21
22 EVAS_SMART_SUBCLASS_NEW
23   (ELM_INDEX_SMART_NAME, _elm_index, Elm_Index_Smart_Class,
24   Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
25
26 static void
27 _item_free(Elm_Index_Item *it)
28 {
29    ELM_INDEX_DATA_GET(WIDGET(it), sd);
30
31    sd->items = eina_list_remove(sd->items, it);
32    if (it->letter) 
33      {
34         eina_stringshare_del(it->letter);
35         it->letter = NULL;
36      }
37 }
38
39 static void
40 _box_custom_layout(Evas_Object *o,
41                    Evas_Object_Box_Data *priv,
42                    void *data)
43 {
44    Elm_Index_Smart_Data *sd = data;
45
46    _els_box_layout(o, priv, sd->horizontal, 1, 0);
47 }
48
49 static void
50 _index_box_clear(Evas_Object *obj,
51                  Evas_Object *box __UNUSED__,
52                  int level)
53 {
54    Eina_List *l;
55    Elm_Index_Item *it;
56
57    ELM_INDEX_DATA_GET(obj, sd);
58
59    if (!sd->level_active[level]) return;
60
61    EINA_LIST_FOREACH(sd->items, l, it)
62      {
63         if (!VIEW(it)) continue;
64         if (it->level != level) continue;
65
66         evas_object_del(VIEW(it));
67         VIEW(it) = NULL;
68      }
69
70    sd->level_active[level] = 0;
71 }
72
73 static char *
74 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
75 {
76    const char *txt = NULL;
77
78    Elm_Index_Item *it = (Elm_Index_Item *)data;
79    ELM_INDEX_ITEM_CHECK_OR_RETURN(it, NULL);
80
81    txt = elm_widget_access_info_get(obj);
82    if (!txt) txt = it->letter;
83    if (txt) return strdup(txt);
84
85    return NULL;
86 }
87
88 static void
89 _access_widget_item_register(Elm_Index_Item *it)
90 {
91    Elm_Access_Info *ai;
92
93    _elm_access_widget_item_register((Elm_Widget_Item *)it);
94
95    ai = _elm_access_object_get(it->base.access_obj);
96
97    _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("Index Item"));
98    _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
99 }
100
101 static void
102 _omit_calc(void *data, int num_of_items, int max_num_of_items)
103 {
104    Elm_Index_Smart_Data *sd = data;
105    int max_group_num, num_of_extra_items, i, g, size, sum;
106    Elm_Index_Omit *o;
107    Elm_Index_Item *it, *it2;
108    Eina_List *l;
109
110    EINA_LIST_FREE(sd->omit, o)
111       free(o);
112
113    EINA_LIST_FOREACH(sd->items, l, it)
114      {
115         if (it->omitted)
116           it->omitted = eina_list_free(it->omitted);
117         if (it->head) it->head = NULL;
118      }
119
120    if (max_num_of_items < 3 || num_of_items <= max_num_of_items) return;
121
122    max_group_num = (max_num_of_items - 1) / 2;
123    num_of_extra_items = num_of_items - max_num_of_items;
124
125    int group_pos[max_group_num];
126    int omit_info[max_num_of_items];
127
128    if (num_of_extra_items >= max_group_num)
129      {
130         g = 1;
131         for (i = 0; i < max_group_num; i++)
132           {
133              group_pos[i] = g;
134              g += 2;
135           }
136      }
137    else
138      {
139         size = max_num_of_items / (num_of_extra_items + 1);
140         g = size;
141         for (i = 0; i < num_of_extra_items; i++)
142           {
143              group_pos[i] = g;
144              g += size;
145           }
146      }
147    for (i = 0; i < max_num_of_items; i++)
148      omit_info[i] = 1;
149    for (i = 0; i < num_of_extra_items; i++)
150      omit_info[group_pos[i % max_group_num]]++;
151
152    g = 0;
153    sum = 0;
154    for (i = 0; i < max_num_of_items; i++)
155      {
156         if (omit_info[i] > 1)
157           {
158              o = (Elm_Index_Omit *)malloc(sizeof(Elm_Index_Omit));
159              o->offset = sum;
160              o->count = omit_info[i];
161              sd->omit = eina_list_append(sd->omit, o);
162              g++;
163           }
164         sum += omit_info[i];
165      }
166 }
167
168 // FIXME: always have index filled
169 static void
170 _index_box_auto_fill(Evas_Object *obj,
171                      Evas_Object *box,
172                      int level)
173 {
174    int i = 0, max_num_of_items = 0, num_of_items = 0, g = 0, skip = 0;
175    Eina_List *l;
176    Eina_Bool rtl;
177    Elm_Index_Item *it, *head;
178    Evas_Coord mw, mh, ih, vh;
179    Elm_Index_Omit *om;
180    Evas_Object *o_odd, *o_even;
181
182    ELM_INDEX_DATA_GET(obj, sd);
183
184    if (sd->level_active[level]) return;
185
186    evas_object_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, NULL, NULL, NULL, &ih);
187
188    rtl = elm_widget_mirrored_get(obj);
189
190    o_odd = edje_object_add(evas_object_evas_get(obj));
191    o_even = edje_object_add(evas_object_evas_get(obj));
192
193    if (!sd->horizontal)
194      {
195         elm_widget_theme_object_set
196            (obj, o_odd, "index", "item_odd/vertical",
197             elm_widget_style_get(obj));
198         elm_widget_theme_object_set
199            (obj, o_even, "index", "item/vertical",
200             elm_widget_style_get(obj));
201
202         edje_object_size_min_restricted_calc(o_odd, NULL, &mh, 0, 0);
203         edje_object_size_min_restricted_calc(o_even, NULL, &vh, 0, 0);
204         if (vh > mh) mh = vh;
205
206         EINA_LIST_FOREACH(sd->items, l, it)
207           {
208              if (it->level == level) num_of_items++;
209           }
210
211         if (mh != 0)
212           max_num_of_items = ih / mh;
213
214         _omit_calc(sd, num_of_items, max_num_of_items);
215      }
216
217    om = eina_list_nth(sd->omit, g);
218    EINA_LIST_FOREACH(sd->items, l, it)
219      {
220         Evas_Object *o;
221         const char *stacking;
222
223         if (it->level != level) continue;
224
225         if (om && i == om->offset)
226           {
227              skip = om->count;
228              skip--;
229              head = it;
230              it->head = head;
231              head->omitted = eina_list_append(head->omitted, it);
232              om = eina_list_nth(sd->omit, ++g);
233           }
234         else if (skip > 0)
235           {
236              skip--;
237              i++;
238              if (head)
239                {
240                   it->head = head;
241                   head->omitted = eina_list_append(head->omitted, it);
242                }
243              continue;
244           }
245
246         o = edje_object_add(evas_object_evas_get(obj));
247         VIEW(it) = o;
248         edje_object_mirrored_set(VIEW(it), rtl);
249
250         if (sd->horizontal)
251           {
252              if (i & 0x1)
253                elm_widget_theme_object_set
254                  (obj, o, "index", "item_odd/horizontal",
255                  elm_widget_style_get(obj));
256              else
257                elm_widget_theme_object_set
258                  (obj, o, "index", "item/horizontal",
259                  elm_widget_style_get(obj));
260           }
261         else
262           {
263              if (i & 0x1)
264                elm_widget_theme_object_set
265                  (obj, o, "index", "item_odd/vertical",
266                  elm_widget_style_get(obj));
267              else
268                elm_widget_theme_object_set
269                  (obj, o, "index", "item/vertical",
270                  elm_widget_style_get(obj));
271           }
272
273         if (skip > 0)
274           edje_object_part_text_escaped_set(o, "elm.text", "*");
275         else
276           edje_object_part_text_escaped_set(o, "elm.text", it->letter);
277         edje_object_size_min_restricted_calc(o, &mw, &mh, 0, 0);
278         evas_object_size_hint_min_set(o, mw, mh);
279         evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
280         evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
281         elm_widget_sub_object_add(obj, o);
282         evas_object_box_append(box, o);
283         stacking = edje_object_data_get(o, "stacking");
284
285         if (stacking)
286           {
287              if (!strcmp(stacking, "below")) evas_object_lower(o);
288              else if (!strcmp(stacking, "above"))
289                evas_object_raise(o);
290           }
291
292         evas_object_show(o);
293
294         i++;
295
296         // ACCESS
297         if ((it->level == 0) &&
298             (_elm_config->access_mode == ELM_ACCESS_MODE_ON))
299           _access_widget_item_register(it);
300      }
301
302    evas_object_smart_calculate(box);
303    sd->level_active[level] = 1;
304 }
305
306 static void
307 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
308 {
309    ELM_INDEX_DATA_GET(obj, sd);
310
311    if (!sd->horizontal)
312      edje_object_mirrored_set(ELM_WIDGET_DATA(sd)->resize_obj, rtl);
313 }
314
315 static Eina_Bool
316 _elm_index_smart_theme(Evas_Object *obj)
317 {
318    Evas_Coord minw = 0, minh = 0;
319    Eina_List *l;
320    Elm_Index_Item *it;
321
322    ELM_INDEX_DATA_GET(obj, sd);
323
324    _index_box_clear(obj, sd->bx[0], 0);
325    _index_box_clear(obj, sd->bx[1], 1);
326
327    if (sd->horizontal)
328      eina_stringshare_replace(&ELM_LAYOUT_DATA(sd)->group, "base/horizontal");
329    else
330      {
331         eina_stringshare_replace(&ELM_LAYOUT_DATA(sd)->group, "base/vertical");
332         _mirrored_set(obj, elm_widget_mirrored_get(obj));
333      }
334
335    if (!ELM_WIDGET_CLASS(_elm_index_parent_sc)->theme(obj)) return EINA_FALSE;
336
337    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
338    evas_object_size_hint_min_set(sd->event[0], minw, minh);
339
340    if (edje_object_part_exists
341          (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.index.1"))
342      {
343         if (!sd->bx[1])
344           {
345              sd->bx[1] = evas_object_box_add(evas_object_evas_get(obj));
346              evas_object_box_layout_set
347                (sd->bx[1], _box_custom_layout, sd, NULL);
348              elm_widget_sub_object_add(obj, sd->bx[1]);
349           }
350         elm_layout_content_set(obj, "elm.swallow.index.1", sd->bx[1]);
351      }
352    else if (sd->bx[1])
353      {
354         evas_object_del(sd->bx[1]);
355         sd->bx[1] = NULL;
356      }
357    if (edje_object_part_exists
358          (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.event.1"))
359      {
360         if (!sd->event[1])
361           {
362              sd->event[1] =
363                evas_object_rectangle_add(evas_object_evas_get(obj));
364              evas_object_color_set(sd->event[1], 0, 0, 0, 0);
365              elm_widget_sub_object_add(obj, sd->event[1]);
366           }
367         elm_layout_content_set(obj, "elm.swallow.event.1", sd->event[1]);
368         evas_object_size_hint_min_set(sd->event[1], minw, minh);
369      }
370    else if (sd->event[1])
371      {
372         evas_object_del(sd->event[1]);
373         sd->event[1] = NULL;
374      }
375    edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
376
377    elm_layout_sizing_eval(obj);
378    _index_box_auto_fill(obj, sd->bx[0], 0);
379
380    if (sd->autohide_disabled)
381      {
382         if (sd->level == 1) _index_box_auto_fill(obj, sd->bx[1], 1);
383         elm_layout_signal_emit(obj, "elm,state,active", "elm");
384      }
385    else elm_layout_signal_emit(obj, "elm,state,inactive", "elm");
386
387    EINA_LIST_FOREACH(sd->items, l, it)
388      {
389         if (it->selected)
390          edje_object_signal_emit(VIEW(it), "elm,state,active", "elm");
391      }
392
393    return EINA_TRUE;
394 }
395
396 static void
397 _elm_index_smart_sizing_eval(Evas_Object *obj)
398 {
399    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
400
401    ELM_INDEX_DATA_GET(obj, sd);
402
403    edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
404    evas_object_size_hint_min_set(obj, minw, minh);
405    evas_object_size_hint_max_set(obj, maxw, maxh);
406 }
407
408 static Eina_Bool
409 _item_del_pre_hook(Elm_Object_Item *it)
410 {
411    ELM_INDEX_DATA_GET(WIDGET(it), sd);
412
413    _item_free((Elm_Index_Item *)it);
414    _index_box_clear(WIDGET(it), sd->bx[sd->level], sd->level);
415
416    return EINA_TRUE;
417 }
418
419 static Elm_Index_Item *
420 _item_new(Evas_Object *obj,
421           const char *letter,
422           Evas_Smart_Cb func,
423           const void *data)
424 {
425    Elm_Index_Item *it;
426
427    ELM_INDEX_DATA_GET(obj, sd);
428
429    it = elm_widget_item_new(obj, Elm_Index_Item);
430    if (!it) return NULL;
431
432    elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
433    if (letter) it->letter = eina_stringshare_add(letter);
434    it->func = func;
435    it->base.data = data;
436    it->level = sd->level;
437
438    return it;
439 }
440
441 static Elm_Index_Item *
442 _item_find(Evas_Object *obj,
443            const void *data)
444 {
445    Eina_List *l;
446    Elm_Index_Item *it;
447
448    ELM_INDEX_DATA_GET(obj, sd);
449
450    EINA_LIST_FOREACH(sd->items, l, it)
451      if (it->base.data == data) return it;
452
453    return NULL;
454 }
455
456 static Eina_Bool
457 _delay_change(void *data)
458 {
459    Elm_Object_Item *item;
460
461    ELM_INDEX_DATA_GET(data, sd);
462
463    sd->delay = NULL;
464    item = elm_index_selected_item_get(data, sd->level);
465    if (item) evas_object_smart_callback_call(data, SIG_DELAY_CHANGED, item);
466
467    return ECORE_CALLBACK_CANCEL;
468 }
469
470 static void
471 _sel_eval(Evas_Object *obj,
472           Evas_Coord evx,
473           Evas_Coord evy)
474 {
475    Evas_Coord x, y, w, h, bx, by, bw, bh, xx, yy;
476    Elm_Index_Item *it, *it_closest, *it_last, *om_closest;
477    char *label = NULL, *last = NULL;
478    double cdv = 0.5;
479    Evas_Coord dist;
480    Eina_List *l;
481    int i, j, size, dh, dx, dy;
482
483    ELM_INDEX_DATA_GET(obj, sd);
484
485    for (i = 0; i <= sd->level; i++)
486      {
487         it_last = NULL;
488         it_closest = NULL;
489         om_closest = NULL;
490         dist = 0x7fffffff;
491         evas_object_geometry_get(sd->bx[i], &bx, &by, &bw, &bh);
492
493         EINA_LIST_FOREACH(sd->items, l, it)
494           {
495              if (it->level != i) continue;
496              if (it->level != sd->level)
497                {
498                   if (it->selected)
499                     {
500                        it_closest = it;
501                        break;
502                     }
503                   continue;
504                }
505              if (it->selected)
506                {
507                   it_last = it;
508                   it->selected = 0;
509                }
510              if (VIEW(it))
511                {
512                   evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
513                   xx = x + (w / 2);
514                   yy = y + (h / 2);
515                   x = evx - xx;
516                   y = evy - yy;
517                   x = (x * x) + (y * y);
518                   if ((x < dist) || (!it_closest))
519                     {
520                        if (sd->horizontal)
521                          cdv = (double)(xx - bx) / (double)bw;
522                        else
523                          cdv = (double)(yy - by) / (double)bh;
524                        it_closest = it;
525                        dist = x;
526                     }
527                }
528           }
529         if ((i == 0) && (sd->level == 0))
530           edje_object_part_drag_value_set
531             (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.index.1", cdv, cdv);
532
533         if (it_closest && it_closest->omitted)
534           {
535              it = it_closest;
536              size = eina_list_count(it->omitted);
537              evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
538              dist = 0x7fffffff;
539              dh = h / size;
540              if (dh == 0)
541                printf("too many index items to omit\n"); // omit mode not possible
542              else
543                {
544                   for (j = 0; j < size; j++)
545                     {
546                        xx = x + (w / 2);
547                        yy = y + (dh * j) + (dh / 2);
548                        dx = evx - xx;
549                        dy = evy - yy;
550                        dx = (dx * dx) + (dy * dy);
551                        if ((dx < dist) || (!om_closest))
552                          {
553                             om_closest = eina_list_nth(it->omitted, j);
554                             dist = dx;
555                          }
556                     }
557                }
558           }
559
560         if (om_closest) om_closest->selected = 1;
561         else if (it_closest) it_closest->selected = 1;
562
563         if (it_closest != it_last)
564           {
565              if (it_last)
566                {
567                   const char *stacking, *selectraise;
568
569                   it = it_last;
570                   if (it->head)
571                     {
572                        if (it->head != it_closest) it = it->head;
573                        else it = NULL;
574                     }
575                   if (it)
576                     {
577                        edje_object_signal_emit
578                           (VIEW(it), "elm,state,inactive", "elm");
579                        stacking = edje_object_data_get(VIEW(it), "stacking");
580                        selectraise = edje_object_data_get(VIEW(it), "selectraise");
581                        if ((selectraise) && (!strcmp(selectraise, "on")))
582                          {
583                             if ((stacking) && (!strcmp(stacking, "below")))
584                               evas_object_lower(VIEW(it));
585                          }
586                     }
587                }
588              if (it_closest)
589                {
590                   const char *selectraise;
591
592                   it = it_closest;
593
594                   if (!(it_last && it_last->head && it_last->head == it_closest))
595                     {
596                        edje_object_signal_emit(VIEW(it), "elm,state,active", "elm");
597                        selectraise = edje_object_data_get(VIEW(it), "selectraise");
598                        if ((selectraise) && (!strcmp(selectraise, "on")))
599                          evas_object_raise(VIEW(it));
600                     }
601                   // ACCESS
602                   if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
603                     {
604                        char *ret;
605                        Eina_Strbuf *buf;
606                        buf = eina_strbuf_new();
607
608                        if (om_closest)
609                          eina_strbuf_append_printf(buf, "index item %s clicked", om_closest->letter);
610                        else
611                          eina_strbuf_append_printf(buf, "index item %s clicked", it->letter);
612                        ret = eina_strbuf_string_steal(buf);
613                        eina_strbuf_free(buf);
614
615                        _elm_access_highlight_set(it->base.access_obj);
616                        _elm_access_say(ret);
617                     }
618
619                   if (om_closest)
620                     evas_object_smart_callback_call
621                        (obj, SIG_CHANGED, (void *)om_closest);
622                   else
623                     evas_object_smart_callback_call
624                        (obj, SIG_CHANGED, (void *)it);
625                   if (sd->delay) ecore_timer_del(sd->delay);
626                   sd->delay = ecore_timer_add(0.2, _delay_change, obj);
627                }
628           }
629         if (it_closest)
630           {
631              if (om_closest) it = om_closest;
632              else it = it_closest;
633              if (!last && it->letter) last = strdup(it->letter);
634              else
635                {
636                   if (!label && last) label = strdup(last);
637                   else
638                     {
639                        if (label && last)
640                          {
641                             label = realloc(label, strlen(label) +
642                                             strlen(last) + 1);
643                             if (!label) return;
644                             strcat(label, last);
645                          }
646                     }
647                   free(last);
648                   if (it->letter) last = strdup(it->letter);
649                }
650           }
651      }
652    if (!label) label = strdup("");
653    if (!last) last = strdup("");
654
655    elm_layout_text_set(obj, "elm.text.body", label);
656    elm_layout_text_set(obj, "elm.text", last);
657
658    free(label);
659    free(last);
660 }
661
662 static void
663 _on_mouse_wheel(void *data __UNUSED__,
664                 Evas *e __UNUSED__,
665                 Evas_Object *o __UNUSED__,
666                 void *event_info __UNUSED__)
667 {
668 }
669
670 static void
671 _on_mouse_down(void *data,
672                Evas *e __UNUSED__,
673                Evas_Object *o __UNUSED__,
674                void *event_info)
675 {
676    Evas_Event_Mouse_Down *ev = event_info;
677    Evas_Coord x, y, w;
678
679    ELM_INDEX_DATA_GET(data, sd);
680
681    if (ev->button != 1) return;
682    sd->down = 1;
683    evas_object_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, &x, &y, &w, NULL);
684    sd->dx = ev->canvas.x - x;
685    sd->dy = ev->canvas.y - y;
686    if (!sd->autohide_disabled)
687      {
688         _index_box_clear(data, sd->bx[1], 1);
689         _index_box_auto_fill(data, sd->bx[0], 0);
690         elm_layout_signal_emit(data, "elm,state,active", "elm");
691      }
692    _sel_eval(data, ev->canvas.x, ev->canvas.y);
693    edje_object_part_drag_value_set
694      (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.pointer",
695      (!elm_object_mirrored_get(data)) ? sd->dx : (sd->dx - w), sd->dy);
696    if (sd->items && !sd->indicator_disabled)
697      elm_layout_signal_emit(data, "elm,indicator,state,active", "elm");
698 }
699
700 static void
701 _on_mouse_up(void *data,
702              Evas *e __UNUSED__,
703              Evas_Object *o __UNUSED__,
704              void *event_info)
705 {
706    Evas_Event_Mouse_Up *ev = event_info;
707    Elm_Object_Item *item;
708    Elm_Index_Item *id_item;
709
710    ELM_INDEX_DATA_GET(data, sd);
711
712    if (ev->button != 1) return;
713    sd->down = 0;
714    item = elm_index_selected_item_get(data, sd->level);
715    if (item)
716      {
717         evas_object_smart_callback_call(data, SIG_SELECTED, item);
718         id_item = (Elm_Index_Item *)item;
719         if (id_item->func)
720           id_item->func((void *)id_item->base.data, WIDGET(id_item), id_item);
721      }
722    if (!sd->autohide_disabled)
723      elm_layout_signal_emit(data, "elm,state,inactive", "elm");
724
725    elm_layout_signal_emit(data, "elm,state,level,0", "elm");
726    if (sd->items && !sd->indicator_disabled)
727      elm_layout_signal_emit(data, "elm,indicator,state,inactive", "elm");
728 }
729
730 static void
731 _on_mouse_move(void *data,
732                Evas *e __UNUSED__,
733                Evas_Object *o __UNUSED__,
734                void *event_info)
735 {
736    Evas_Event_Mouse_Move *ev = event_info;
737    Evas_Coord minw = 0, minh = 0, x, y, dx, adx, w;
738    char buf[1024];
739
740    ELM_INDEX_DATA_GET(data, sd);
741
742    if (!sd->down) return;
743    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
744    evas_object_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, &x, &y, &w, NULL);
745    x = ev->cur.canvas.x - x;
746    y = ev->cur.canvas.y - y;
747    dx = x - sd->dx;
748    adx = dx;
749    if (adx < 0) adx = -dx;
750    edje_object_part_drag_value_set
751      (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.pointer",
752      (!edje_object_mirrored_get(ELM_WIDGET_DATA(sd)->resize_obj)) ?
753      x : (x - w), y);
754    if (!sd->horizontal)
755      {
756         if (adx > minw)
757           {
758              if (!sd->level)
759                {
760                   sd->level = 1;
761                   snprintf(buf, sizeof(buf), "elm,state,level,%i", sd->level);
762                   elm_layout_signal_emit(data, buf, "elm");
763                   evas_object_smart_callback_call(data, SIG_LEVEL_UP, NULL);
764                }
765           }
766         else
767           {
768              if (sd->level == 1)
769                {
770                   sd->level = 0;
771                   snprintf(buf, sizeof(buf), "elm,state,level,%i", sd->level);
772                   elm_layout_signal_emit(data, buf, "elm");
773                   evas_object_smart_callback_call(data, SIG_LEVEL_DOWN, NULL);
774                }
775           }
776      }
777    _sel_eval(data, ev->cur.canvas.x, ev->cur.canvas.y);
778 }
779
780 static void
781 _on_mouse_in_access(void *data,
782                     Evas *e __UNUSED__,
783                     Evas_Object *o __UNUSED__,
784                     void *event_info __UNUSED__)
785 {
786    ELM_INDEX_DATA_GET(data, sd);
787
788    if (sd->down) return;
789
790    if (!sd->autohide_disabled)
791      {
792         _index_box_clear(data, sd->bx[1], 1);
793         _index_box_auto_fill(data, sd->bx[0], 0);
794         elm_layout_signal_emit(data, "elm,state,active", "elm");
795      }
796 }
797
798 static void
799 _on_mouse_move_access(void *data,
800                       Evas *e __UNUSED__,
801                       Evas_Object *o __UNUSED__,
802                       void *event_info)
803 {
804
805    Evas_Event_Mouse_Down *ev = event_info;
806    Elm_Index_Item *it, *it_closest;
807    Eina_List *l;
808    Evas_Coord dist = 0;
809    Evas_Coord x, y, w, h, xx, yy;
810
811    ELM_INDEX_DATA_GET(data, sd);
812
813    it_closest = NULL;
814    dist = 0x7fffffff;
815
816    EINA_LIST_FOREACH(sd->items, l, it)
817      {
818         evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
819         xx = x + (w / 2);
820         yy = y + (h / 2);
821         x = ev->canvas.x - xx;
822         y = ev->canvas.y - yy;
823         x = (x * x) + (y * y);
824         if ((x < dist) || (!it_closest))
825           {
826              it_closest = it;
827              dist = x;
828           }
829      }
830
831    if (it_closest)
832      _elm_access_highlight_set(it_closest->base.access_obj);
833 }
834
835 static void
836 _on_mouse_out_access(void *data,
837                       Evas *e __UNUSED__,
838                       Evas_Object *o __UNUSED__,
839                       void *event_info __UNUSED__)
840 {
841    ELM_INDEX_DATA_GET(data, sd);
842
843    if (!sd->autohide_disabled)
844      elm_layout_signal_emit(data, "elm,state,inactive", "elm");
845 }
846
847 static void
848 _access_index_register(Evas_Object *obj)
849 {
850    Evas_Object *ao;
851    elm_widget_can_focus_set(obj, EINA_TRUE);
852    ao = _elm_access_edje_object_part_object_register
853               (obj, elm_layout_edje_get(obj), "access");
854    _elm_access_text_set
855      (_elm_access_object_get(ao), ELM_ACCESS_TYPE, E_("Index"));
856 }
857
858 static void
859 _index_resize_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
860 {
861    ELM_INDEX_DATA_GET_OR_RETURN(data, sd);
862
863    if (sd->horizontal) return;
864
865    Eina_List *l;
866    Elm_Index_Item *it;
867
868    _index_box_clear(data, sd->bx[0], 0);
869    _index_box_auto_fill(data, sd->bx[0], 0);
870
871    if (sd->autohide_disabled)
872      elm_layout_signal_emit(data, "elm,state,active", "elm");
873
874    EINA_LIST_FOREACH(sd->items, l, it)
875      {
876         if (it->selected)
877           edje_object_signal_emit(VIEW(it), "elm,state,active", "elm");
878      }
879 }
880
881 static void
882 _elm_index_smart_add(Evas_Object *obj)
883 {
884    Evas_Object *o;
885    Evas_Coord minw, minh;
886
887    EVAS_SMART_DATA_ALLOC(obj, Elm_Index_Smart_Data);
888
889    ELM_WIDGET_CLASS(_elm_index_parent_sc)->base.add(obj);
890
891    priv->indicator_disabled = EINA_FALSE;
892    priv->horizontal = EINA_FALSE;
893    priv->autohide_disabled = EINA_FALSE;
894
895    elm_layout_theme_set
896      (obj, "index", "base/vertical", elm_widget_style_get(obj));
897
898    o = evas_object_rectangle_add(evas_object_evas_get(obj));
899    priv->event[0] = o;
900    evas_object_color_set(o, 0, 0, 0, 0);
901    minw = minh = 0;
902    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
903    evas_object_size_hint_min_set(o, minw, minh);
904    elm_layout_content_set(obj, "elm.swallow.event.0", o);
905    elm_widget_sub_object_add(obj, o);
906
907    evas_object_event_callback_add
908      (obj, EVAS_CALLBACK_RESIZE, _index_resize_cb, obj);
909    evas_object_event_callback_add
910      (o, EVAS_CALLBACK_MOUSE_WHEEL, _on_mouse_wheel, obj);
911    evas_object_event_callback_add
912      (o, EVAS_CALLBACK_MOUSE_DOWN, _on_mouse_down, obj);
913    evas_object_event_callback_add
914      (o, EVAS_CALLBACK_MOUSE_UP, _on_mouse_up, obj);
915    evas_object_event_callback_add
916      (o, EVAS_CALLBACK_MOUSE_MOVE, _on_mouse_move, obj);
917
918
919    // ACCESS
920    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
921      {
922         evas_object_event_callback_add
923           (o, EVAS_CALLBACK_MOUSE_IN, _on_mouse_in_access, obj);
924         evas_object_event_callback_add
925           (o, EVAS_CALLBACK_MOUSE_MOVE, _on_mouse_move_access, obj);
926         evas_object_event_callback_add
927           (o, EVAS_CALLBACK_MOUSE_OUT, _on_mouse_out_access, obj);
928     }
929
930    if (edje_object_part_exists
931          (ELM_WIDGET_DATA(priv)->resize_obj, "elm.swallow.event.1"))
932      {
933         o = evas_object_rectangle_add(evas_object_evas_get(obj));
934         priv->event[1] = o;
935         evas_object_color_set(o, 0, 0, 0, 0);
936         evas_object_size_hint_min_set(o, minw, minh);
937         elm_layout_content_set(obj, "elm.swallow.event.1", o);
938         elm_widget_sub_object_add(obj, o);
939      }
940
941    priv->bx[0] = evas_object_box_add(evas_object_evas_get(obj));
942    evas_object_box_layout_set(priv->bx[0], _box_custom_layout, priv, NULL);
943    elm_widget_sub_object_add(obj, priv->bx[0]);
944    elm_layout_content_set(obj, "elm.swallow.index.0", priv->bx[0]);
945    evas_object_show(priv->bx[0]);
946
947    if (edje_object_part_exists
948          (ELM_WIDGET_DATA(priv)->resize_obj, "elm.swallow.index.1"))
949      {
950         priv->bx[1] = evas_object_box_add(evas_object_evas_get(obj));
951         evas_object_box_layout_set
952           (priv->bx[1], _box_custom_layout, priv, NULL);
953         elm_widget_sub_object_add(obj, priv->bx[1]);
954         elm_layout_content_set(obj, "elm.swallow.index.1", priv->bx[1]);
955         evas_object_show(priv->bx[1]);
956      }
957
958    _mirrored_set(obj, elm_widget_mirrored_get(obj));
959    elm_layout_sizing_eval(obj);
960    elm_widget_can_focus_set(obj, EINA_FALSE);  // check!!
961
962    // ACCESS
963    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
964      _access_index_register(obj);
965 }
966
967 static void
968 _elm_index_smart_del(Evas_Object *obj)
969 {
970    Elm_Index_Item *it;
971    Elm_Index_Omit *o;
972
973    ELM_INDEX_DATA_GET(obj, sd);
974
975    while (sd->items)
976      {
977         it = sd->items->data;
978         _item_free(it);
979         elm_widget_item_del(it);
980      }
981
982    EINA_LIST_FREE(sd->omit, o)
983       free(o);
984
985    if (sd->delay) ecore_timer_del(sd->delay);
986
987    ELM_WIDGET_CLASS(_elm_index_parent_sc)->base.del(obj);
988 }
989
990 static Eina_Bool
991 _elm_index_smart_focus_next(const Evas_Object *obj,
992                             Elm_Focus_Direction dir,
993                             Evas_Object **next)
994 {
995    Eina_List *items = NULL;
996    Eina_List *l = NULL;
997    Elm_Index_Item *it;
998    Evas_Object *ao;
999    Evas_Object *po;
1000
1001    ELM_INDEX_CHECK(obj) EINA_FALSE;
1002    ELM_INDEX_DATA_GET(obj, sd);
1003
1004    if (!sd->autohide_disabled)
1005      elm_layout_signal_emit((Evas_Object *)obj, "elm,state,active", "elm");
1006
1007    po = (Evas_Object *)edje_object_part_object_get
1008               (elm_layout_edje_get(obj), "access");
1009    ao = evas_object_data_get(po, "_part_access_obj");
1010    items = eina_list_append(items, ao);
1011
1012    EINA_LIST_FOREACH(sd->items, l, it)
1013      {
1014         if (it->level != 0) continue;
1015         items = eina_list_append(items, it->base.access_obj);
1016      }
1017
1018    Eina_Bool ret;
1019    ret = elm_widget_focus_list_next_get
1020             (obj, items, eina_list_data_get, dir, next);
1021
1022    // to hide index item, if there is nothing to focus on autohide disalbe mode
1023    if ((!sd->autohide_disabled) && (!ret))
1024      elm_layout_signal_emit((Evas_Object *)obj, "elm,state,inactive", "elm");
1025
1026    return ret;
1027 }
1028
1029 static void
1030 _access_obj_process(Evas_Object *obj, Eina_Bool is_access)
1031 {
1032    Eina_List *l;
1033    Elm_Index_Item *it;
1034
1035    ELM_INDEX_DATA_GET(obj, sd);
1036
1037    EINA_LIST_FOREACH(sd->items, l, it)
1038      {
1039         if (it->level != 0) continue;
1040         if (is_access) _access_widget_item_register(it);
1041         else _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
1042      }
1043
1044    if (is_access)
1045      {
1046         _access_index_register(obj);
1047
1048         evas_object_event_callback_add
1049           (sd->event[0], EVAS_CALLBACK_MOUSE_IN, _on_mouse_in_access, obj);
1050         evas_object_event_callback_add
1051           (sd->event[0], EVAS_CALLBACK_MOUSE_MOVE, _on_mouse_move_access, obj);
1052         evas_object_event_callback_add
1053           (sd->event[0], EVAS_CALLBACK_MOUSE_OUT, _on_mouse_out_access, obj);
1054      }
1055    else
1056      {
1057         // opposition of  _access_index_register();
1058         elm_widget_can_focus_set(obj, EINA_FALSE);
1059         _elm_access_edje_object_part_object_unregister
1060              (obj, elm_layout_edje_get(obj), "access");
1061
1062         evas_object_event_callback_del_full
1063           (sd->event[0], EVAS_CALLBACK_MOUSE_IN, _on_mouse_in_access, obj);
1064         evas_object_event_callback_del_full
1065           (sd->event[0], EVAS_CALLBACK_MOUSE_MOVE, _on_mouse_move_access, obj);
1066         evas_object_event_callback_del_full
1067           (sd->event[0], EVAS_CALLBACK_MOUSE_OUT, _on_mouse_out_access, obj);
1068      }
1069 }
1070
1071 static void
1072 _access_hook(Evas_Object *obj, Eina_Bool is_access)
1073 {
1074    ELM_INDEX_CHECK(obj);
1075    ELM_INDEX_DATA_GET(obj, sd);
1076
1077    if (is_access)
1078      ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
1079      _elm_index_smart_focus_next;
1080    else
1081      ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
1082    _access_obj_process(obj, is_access);
1083 }
1084
1085 static void
1086 _elm_index_smart_set_user(Elm_Index_Smart_Class *sc)
1087 {
1088    ELM_WIDGET_CLASS(sc)->base.add = _elm_index_smart_add;
1089    ELM_WIDGET_CLASS(sc)->base.del = _elm_index_smart_del;
1090
1091    ELM_WIDGET_CLASS(sc)->theme = _elm_index_smart_theme;
1092
1093    /* not a 'focus chain manager' */
1094    ELM_WIDGET_CLASS(sc)->focus_next = NULL;
1095    ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
1096
1097    ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_index_smart_sizing_eval;
1098
1099    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
1100      ELM_WIDGET_CLASS(sc)->focus_next = _elm_index_smart_focus_next;
1101
1102    ELM_WIDGET_CLASS(sc)->access = _access_hook;
1103 }
1104
1105 EAPI const Elm_Index_Smart_Class *
1106 elm_index_smart_class_get(void)
1107 {
1108    static Elm_Index_Smart_Class _sc =
1109      ELM_INDEX_SMART_CLASS_INIT_NAME_VERSION(ELM_INDEX_SMART_NAME);
1110    static const Elm_Index_Smart_Class *class = NULL;
1111    Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
1112
1113    if (class)
1114      return class;
1115
1116    _elm_index_smart_set(&_sc);
1117    esc->callbacks = _smart_callbacks;
1118    class = &_sc;
1119
1120    return class;
1121 }
1122
1123 EAPI Evas_Object *
1124 elm_index_add(Evas_Object *parent)
1125 {
1126    Evas_Object *obj;
1127
1128    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
1129
1130    obj = elm_widget_add(_elm_index_smart_class_new(), parent);
1131    if (!obj) return NULL;
1132
1133    if (!elm_widget_sub_object_add(parent, obj))
1134      ERR("could not add %p as sub object of %p", obj, parent);
1135
1136    return obj;
1137 }
1138
1139 EAPI void
1140 elm_index_autohide_disabled_set(Evas_Object *obj,
1141                                 Eina_Bool disabled)
1142 {
1143    ELM_INDEX_CHECK(obj);
1144    ELM_INDEX_DATA_GET(obj, sd);
1145
1146    disabled = !!disabled;
1147    if (sd->autohide_disabled == disabled) return;
1148    sd->autohide_disabled = disabled;
1149    sd->level = 0;
1150    if (sd->autohide_disabled)
1151      {
1152         _index_box_clear(obj, sd->bx[1], 1);
1153         _index_box_auto_fill(obj, sd->bx[0], 0);
1154         elm_layout_signal_emit(obj, "elm,state,active", "elm");
1155      }
1156    else
1157      elm_layout_signal_emit(obj, "elm,state,inactive", "elm");
1158
1159    //FIXME: Should be update indicator based on the indicator visiblility
1160 }
1161
1162 EAPI Eina_Bool
1163 elm_index_autohide_disabled_get(const Evas_Object *obj)
1164 {
1165    ELM_INDEX_CHECK(obj) EINA_FALSE;
1166    ELM_INDEX_DATA_GET(obj, sd);
1167
1168    return sd->autohide_disabled;
1169 }
1170
1171 EAPI void
1172 elm_index_item_level_set(Evas_Object *obj,
1173                          int level)
1174 {
1175    ELM_INDEX_CHECK(obj);
1176    ELM_INDEX_DATA_GET(obj, sd);
1177
1178    if (sd->level == level) return;
1179    sd->level = level;
1180 }
1181
1182 EAPI int
1183 elm_index_item_level_get(const Evas_Object *obj)
1184 {
1185    ELM_INDEX_CHECK(obj) 0;
1186    ELM_INDEX_DATA_GET(obj, sd);
1187
1188    return sd->level;
1189 }
1190
1191 EAPI void
1192 elm_index_item_selected_set(Elm_Object_Item *it,
1193                             Eina_Bool selected)
1194 {
1195    Evas_Coord x, y, w, h;
1196
1197    ELM_INDEX_ITEM_CHECK_OR_RETURN(it);
1198
1199    //FIXME: Should be update indicator based on the autohidden status
1200    //& indicator visiblility
1201
1202    if (selected)
1203      {
1204         evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
1205         _sel_eval(WIDGET(it), x + (w / 2), y + (h / 2));
1206         edje_object_signal_emit(VIEW(it), "elm,state,active", "elm");
1207      }
1208    else _sel_eval(WIDGET(it), -99999, -9999);
1209 }
1210
1211 EAPI Elm_Object_Item *
1212 elm_index_selected_item_get(const Evas_Object *obj,
1213                             int level)
1214 {
1215    Eina_List *l;
1216    Elm_Index_Item *it;
1217
1218    ELM_INDEX_CHECK(obj) NULL;
1219    ELM_INDEX_DATA_GET(obj, sd);
1220
1221    EINA_LIST_FOREACH(sd->items, l, it)
1222      {
1223         if ((it->selected) && (it->level == level))
1224           return (Elm_Object_Item *)it;
1225      }
1226
1227    return NULL;
1228 }
1229
1230 EAPI Elm_Object_Item *
1231 elm_index_item_append(Evas_Object *obj,
1232                       const char *letter,
1233                       Evas_Smart_Cb func,
1234                       const void *data)
1235 {
1236    Elm_Index_Item *it;
1237
1238    ELM_INDEX_CHECK(obj) NULL;
1239    ELM_INDEX_DATA_GET(obj, sd);
1240
1241    it = _item_new(obj, letter, func, data);
1242    if (!it) return NULL;
1243
1244    sd->items = eina_list_append(sd->items, it);
1245    _index_box_clear(obj, sd->bx[sd->level], sd->level);
1246
1247    return (Elm_Object_Item *)it;
1248 }
1249
1250 EAPI Elm_Object_Item *
1251 elm_index_item_prepend(Evas_Object *obj,
1252                        const char *letter,
1253                        Evas_Smart_Cb func,
1254                        const void *data)
1255 {
1256    Elm_Index_Item *it;
1257
1258    ELM_INDEX_CHECK(obj) NULL;
1259    ELM_INDEX_DATA_GET(obj, sd);
1260
1261    it = _item_new(obj, letter, func, data);
1262    if (!it) return NULL;
1263
1264    sd->items = eina_list_prepend(sd->items, it);
1265    _index_box_clear(obj, sd->bx[sd->level], sd->level);
1266
1267    return (Elm_Object_Item *)it;
1268 }
1269
1270 EINA_DEPRECATED EAPI Elm_Object_Item *
1271 elm_index_item_prepend_relative(Evas_Object *obj,
1272                                 const char *letter,
1273                                 const void *item,
1274                                 const Elm_Object_Item *relative)
1275 {
1276    return elm_index_item_insert_before
1277             (obj, (Elm_Object_Item *)relative, letter, NULL, item);
1278 }
1279
1280 EAPI Elm_Object_Item *
1281 elm_index_item_insert_after(Evas_Object *obj,
1282                             Elm_Object_Item *after,
1283                             const char *letter,
1284                             Evas_Smart_Cb func,
1285                             const void *data)
1286 {
1287    Elm_Index_Item *it;
1288
1289    ELM_INDEX_CHECK(obj) NULL;
1290    ELM_INDEX_DATA_GET(obj, sd);
1291
1292    if (!after) return elm_index_item_append(obj, letter, func, data);
1293
1294    it = _item_new(obj, letter, func, data);
1295    if (!it) return NULL;
1296
1297    sd->items = eina_list_append_relative(sd->items, it, after);
1298    _index_box_clear(obj, sd->bx[sd->level], sd->level);
1299
1300    return (Elm_Object_Item *)it;
1301 }
1302
1303 EAPI Elm_Object_Item *
1304 elm_index_item_insert_before(Evas_Object *obj,
1305                              Elm_Object_Item *before,
1306                              const char *letter,
1307                              Evas_Smart_Cb func,
1308                              const void *data)
1309 {
1310    Elm_Index_Item *it;
1311
1312    ELM_INDEX_CHECK(obj) NULL;
1313    ELM_INDEX_DATA_GET(obj, sd);
1314
1315    if (!before) return elm_index_item_prepend(obj, letter, func, data);
1316
1317    it = _item_new(obj, letter, func, data);
1318    if (!it) return NULL;
1319
1320    sd->items = eina_list_prepend_relative(sd->items, it, before);
1321    _index_box_clear(obj, sd->bx[sd->level], sd->level);
1322
1323    return (Elm_Object_Item *)it;
1324 }
1325
1326 EAPI Elm_Object_Item *
1327 elm_index_item_sorted_insert(Evas_Object *obj,
1328                              const char *letter,
1329                              Evas_Smart_Cb func,
1330                              const void *data,
1331                              Eina_Compare_Cb cmp_func,
1332                              Eina_Compare_Cb cmp_data_func)
1333 {
1334    Elm_Index_Item *it;
1335    Eina_List *lnear;
1336    int cmp;
1337
1338    ELM_INDEX_CHECK(obj) NULL;
1339    ELM_INDEX_DATA_GET(obj, sd);
1340
1341    if (!(sd->items)) return elm_index_item_append(obj, letter, func, data);
1342
1343    it = _item_new(obj, letter, func, data);
1344    if (!it) return NULL;
1345
1346    lnear = eina_list_search_sorted_near_list(sd->items, cmp_func, it, &cmp);
1347    if (cmp < 0)
1348      sd->items = eina_list_append_relative_list(sd->items, it, lnear);
1349    else if (cmp > 0)
1350      sd->items = eina_list_prepend_relative_list(sd->items, it, lnear);
1351    else
1352      {
1353         /* If cmp_data_func is not provided, append a duplicated item */
1354         if (!cmp_data_func)
1355           sd->items = eina_list_append_relative_list(sd->items, it, lnear);
1356         else
1357           {
1358              Elm_Index_Item *p_it = eina_list_data_get(lnear);
1359              if (cmp_data_func(p_it->base.data, it->base.data) >= 0)
1360                p_it->base.data = it->base.data;
1361              _item_free(it);
1362              elm_widget_item_del(it);
1363              it = NULL;
1364           }
1365      }
1366    _index_box_clear(obj, sd->bx[sd->level], sd->level);
1367
1368    if (!it) return NULL;
1369    return (Elm_Object_Item *)it;
1370 }
1371
1372 EAPI Elm_Object_Item *
1373 elm_index_item_find(Evas_Object *obj,
1374                     const void *data)
1375 {
1376    ELM_INDEX_CHECK(obj) NULL;
1377
1378    return (Elm_Object_Item *)_item_find(obj, data);
1379 }
1380
1381 EAPI void
1382 elm_index_item_clear(Evas_Object *obj)
1383 {
1384    Elm_Index_Item *it;
1385    Eina_List *l, *clear = NULL;
1386
1387    ELM_INDEX_CHECK(obj);
1388    ELM_INDEX_DATA_GET(obj, sd);
1389
1390    _index_box_clear(obj, sd->bx[sd->level], sd->level);
1391    EINA_LIST_FOREACH(sd->items, l, it)
1392      {
1393         if (it->level != sd->level) continue;
1394         clear = eina_list_append(clear, it);
1395      }
1396    EINA_LIST_FREE (clear, it)
1397      {
1398         _item_free(it);
1399         elm_widget_item_del(it);
1400      }
1401 }
1402
1403 EAPI void
1404 elm_index_level_go(Evas_Object *obj,
1405                    int level __UNUSED__)
1406 {
1407    ELM_INDEX_CHECK(obj);
1408    ELM_INDEX_DATA_GET(obj, sd);
1409
1410    _index_box_auto_fill(obj, sd->bx[0], 0);
1411    if (sd->level == 1) _index_box_auto_fill(obj, sd->bx[1], 1);
1412 }
1413
1414 EAPI void
1415 elm_index_indicator_disabled_set(Evas_Object *obj,
1416                                  Eina_Bool disabled)
1417 {
1418    ELM_INDEX_CHECK(obj);
1419    ELM_INDEX_DATA_GET(obj, sd);
1420
1421    disabled = !!disabled;
1422    if (sd->indicator_disabled == disabled) return;
1423    sd->indicator_disabled = disabled;
1424    if (!sd->items) return;
1425    if (disabled)
1426      elm_layout_signal_emit(obj, "elm,indicator,state,inactive", "elm");
1427    else
1428      elm_layout_signal_emit(obj, "elm,indicator,state,active", "elm");
1429 }
1430
1431 EAPI Eina_Bool
1432 elm_index_indicator_disabled_get(const Evas_Object *obj)
1433 {
1434    ELM_INDEX_CHECK(obj) EINA_FALSE;
1435    ELM_INDEX_DATA_GET(obj, sd);
1436
1437    return sd->indicator_disabled;
1438 }
1439
1440 EAPI const char *
1441 elm_index_item_letter_get(const Elm_Object_Item *it)
1442 {
1443    ELM_INDEX_ITEM_CHECK_OR_RETURN(it, NULL);
1444
1445    return ((Elm_Index_Item *)it)->letter;
1446 }
1447
1448 EAPI void
1449 elm_index_horizontal_set(Evas_Object *obj,
1450                          Eina_Bool horizontal)
1451 {
1452    ELM_INDEX_CHECK(obj);
1453    ELM_INDEX_DATA_GET(obj, sd);
1454
1455    horizontal = !!horizontal;
1456    if (horizontal == sd->horizontal) return;
1457
1458    sd->horizontal = horizontal;
1459    _elm_index_smart_theme(obj);
1460 }
1461
1462 EAPI Eina_Bool
1463 elm_index_horizontal_get(const Evas_Object *obj)
1464 {
1465    ELM_INDEX_CHECK(obj) EINA_FALSE;
1466    ELM_INDEX_DATA_GET(obj, sd);
1467
1468    return sd->horizontal;
1469 }