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