1 #include <Elementary.h>
4 #include "elm_widget_index.h"
6 EAPI const char ELM_INDEX_SMART_NAME[] = "elm_index";
8 #define INDEX_DELAY_CHANGE_TIME 0.2
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";
17 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
19 {SIG_DELAY_CHANGED, ""},
23 {SIG_LANG_CHANGED, ""},
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);
32 _elm_index_smart_translate(Evas_Object *obj)
34 evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
39 _item_free(Elm_Index_Item *it)
41 ELM_INDEX_DATA_GET(WIDGET(it), sd);
43 sd->items = eina_list_remove(sd->items, it);
46 it->omitted = eina_list_free(it->omitted);
49 eina_stringshare_del(it->letter);
53 _box_custom_layout(Evas_Object *o,
54 Evas_Object_Box_Data *priv,
57 Elm_Index_Smart_Data *sd = data;
59 _els_box_layout(o, priv, sd->horizontal, 1, 0);
63 _index_box_clear(Evas_Object *obj,
64 Evas_Object *box __UNUSED__,
70 ELM_INDEX_DATA_GET(obj, sd);
72 if (!sd->level_active[level]) return;
74 EINA_LIST_FOREACH(sd->items, l, it)
76 if (!VIEW(it)) continue;
77 if (it->level != level) continue;
79 evas_object_del(VIEW(it));
83 sd->level_active[level] = 0;
87 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
89 const char *txt = NULL;
91 Elm_Index_Item *it = (Elm_Index_Item *)data;
92 ELM_INDEX_ITEM_CHECK_OR_RETURN(it, NULL);
94 txt = elm_widget_access_info_get(obj);
95 if (!txt) txt = it->letter;
96 if (txt) return strdup(txt);
102 _access_widget_item_activate_cb(void *data __UNUSED__,
103 Evas_Object *part_obj __UNUSED__,
106 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
110 _access_widget_item_register(Elm_Index_Item *it)
114 _elm_access_widget_item_register((Elm_Widget_Item *)it);
116 ai = _elm_access_object_get(it->base.access_obj);
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);
125 _omit_calc(void *data, int num_of_items, int max_num_of_items)
127 Elm_Index_Smart_Data *sd = data;
128 int max_group_num, num_of_extra_items, i, g, size, sum, *group_pos, *omit_info;
133 EINA_LIST_FREE(sd->omit, o)
136 EINA_LIST_FOREACH(sd->items, l, it)
139 it->omitted = eina_list_free(it->omitted);
140 if (it->head) it->head = NULL;
143 if ((max_num_of_items < 3) || (num_of_items <= max_num_of_items)) return;
145 max_group_num = (max_num_of_items - 1) / 2;
146 num_of_extra_items = num_of_items - max_num_of_items;
148 group_pos = (int *)malloc(sizeof(int) * max_group_num);
149 omit_info = (int *)malloc(sizeof(int) * max_num_of_items);
151 if (num_of_extra_items >= max_group_num)
154 for (i = 0; i < max_group_num; i++)
162 size = max_num_of_items / (num_of_extra_items + 1);
164 for (i = 0; i < num_of_extra_items; i++)
170 for (i = 0; i < max_num_of_items; i++)
172 for (i = 0; i < num_of_extra_items; i++)
173 omit_info[group_pos[i % max_group_num]]++;
176 for (i = 0; i < max_num_of_items; i++)
178 if (omit_info[i] > 1)
180 o = (Elm_Index_Omit *)malloc(sizeof(Elm_Index_Omit));
182 o->count = omit_info[i];
183 sd->omit = eina_list_append(sd->omit, o);
192 // FIXME: always have index filled
194 _index_box_auto_fill(Evas_Object *obj,
198 int i = 0, max_num_of_items = 0, num_of_items = 0, g = 0, skip = 0;
201 Elm_Index_Item *it, *head = NULL;
202 Evas_Coord mw, mh, ih;
206 ELM_INDEX_DATA_GET(obj, sd);
208 if (sd->level_active[level]) return;
210 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, NULL, NULL, NULL, &ih);
212 rtl = elm_widget_mirrored_get(obj);
214 if (sd->omit_enabled)
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));
221 edje_object_size_min_restricted_calc(o, NULL, &mh, 0, 0);
223 EINA_LIST_FOREACH(sd->items, l, it)
224 if (it->level == level) num_of_items++;
227 max_num_of_items = ih / mh;
229 _omit_calc(sd, num_of_items, max_num_of_items);
232 om = eina_list_nth(sd->omit, g);
233 EINA_LIST_FOREACH(sd->items, l, it)
235 const char *stacking;
237 if (it->level != level) continue;
239 if ((om) && (i == om->offset))
245 head->omitted = eina_list_append(head->omitted, it);
246 om = eina_list_nth(sd->omit, ++g);
255 head->omitted = eina_list_append(head->omitted, it);
260 o = edje_object_add(evas_object_evas_get(obj));
262 edje_object_mirrored_set(VIEW(it), rtl);
267 elm_widget_theme_object_set
268 (obj, o, "index", "item_odd/horizontal",
269 elm_widget_style_get(obj));
271 elm_widget_theme_object_set
272 (obj, o, "index", "item/horizontal",
273 elm_widget_style_get(obj));
278 elm_widget_theme_object_set
279 (obj, o, "index", "item_odd/vertical",
280 elm_widget_style_get(obj));
282 elm_widget_theme_object_set
283 (obj, o, "index", "item/vertical",
284 elm_widget_style_get(obj));
288 edje_object_part_text_escaped_set(o, "elm.text", "*");
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");
301 if (!strcmp(stacking, "below")) evas_object_lower(o);
302 else if (!strcmp(stacking, "above"))
303 evas_object_raise(o);
311 if ((it->level == 0) && (_elm_config->access_mode))
312 _access_widget_item_register(it);
315 // TIZEN ONLY adjust the last item's theme according to winset gui
318 it = eina_list_nth(sd->items, i - 1);
319 edje_object_signal_emit(VIEW(it), "elm,last,item", "elm");
323 evas_object_smart_calculate(box);
324 sd->level_active[level] = 1;
328 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
330 ELM_INDEX_DATA_GET(obj, sd);
333 edje_object_mirrored_set(ELM_WIDGET_DATA(sd)->resize_obj, rtl);
337 _access_activate_cb(void *data,
338 Evas_Object *part_obj __UNUSED__,
339 Elm_Object_Item *item __UNUSED__)
342 ELM_INDEX_DATA_GET(data, sd);
344 it = eina_list_nth(sd->items, 0);
345 _elm_access_highlight_set(it->base.access_obj);
346 sd->index_focus = EINA_TRUE;
350 _access_index_register(Evas_Object *obj)
354 elm_widget_can_focus_set(obj, EINA_TRUE);
356 ao = _elm_access_edje_object_part_object_register
357 (obj, elm_layout_edje_get(obj), "access");
358 ai = _elm_access_object_get(ao);
361 (ai, ELM_ACCESS_TYPE, E_("Index"));
362 _elm_access_activate_callback_set
363 (ai, _access_activate_cb, obj);
367 _elm_index_smart_theme(Evas_Object *obj)
369 Evas_Coord minw = 0, minh = 0;
372 ELM_INDEX_DATA_GET(obj, sd);
374 _index_box_clear(obj, sd->bx[0], 0);
375 _index_box_clear(obj, sd->bx[1], 1);
378 eina_stringshare_replace(&ELM_LAYOUT_DATA(sd)->group, "base/horizontal");
381 eina_stringshare_replace(&ELM_LAYOUT_DATA(sd)->group, "base/vertical");
382 _mirrored_set(obj, elm_widget_mirrored_get(obj));
385 if (!ELM_WIDGET_CLASS(_elm_index_parent_sc)->theme(obj)) return EINA_FALSE;
387 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
388 evas_object_size_hint_min_set(sd->event[0], minw, minh);
390 if (edje_object_part_exists
391 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.index.1"))
395 sd->bx[1] = evas_object_box_add(evas_object_evas_get(obj));
396 evas_object_box_layout_set
397 (sd->bx[1], _box_custom_layout, sd, NULL);
398 elm_widget_sub_object_add(obj, sd->bx[1]);
400 elm_layout_content_set(obj, "elm.swallow.index.1", sd->bx[1]);
404 evas_object_del(sd->bx[1]);
407 if (edje_object_part_exists
408 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.event.1"))
413 evas_object_rectangle_add(evas_object_evas_get(obj));
414 evas_object_color_set(sd->event[1], 0, 0, 0, 0);
415 elm_widget_sub_object_add(obj, sd->event[1]);
417 elm_layout_content_set(obj, "elm.swallow.event.1", sd->event[1]);
418 evas_object_size_hint_min_set(sd->event[1], minw, minh);
420 else if (sd->event[1])
422 evas_object_del(sd->event[1]);
425 edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
427 elm_layout_sizing_eval(obj);
428 _index_box_auto_fill(obj, sd->bx[0], 0);
430 if (sd->autohide_disabled)
432 if (sd->level == 1) _index_box_auto_fill(obj, sd->bx[1], 1);
433 elm_layout_signal_emit(obj, "elm,state,active", "elm");
435 else elm_layout_signal_emit(obj, "elm,state,inactive", "elm");
437 it = (Elm_Index_Item *)elm_index_selected_item_get(obj, sd->level);
441 edje_object_signal_emit(VIEW(it->head), "elm,state,active", "elm");
443 edje_object_signal_emit(VIEW(it), "elm,state,active", "elm");
447 if (_elm_config->access_mode)
449 elm_index_autohide_disabled_set(obj, EINA_TRUE);
450 elm_layout_signal_emit(obj, "elm,access,state,active", "elm");
451 _access_index_register(obj);
458 _elm_index_smart_sizing_eval(Evas_Object *obj)
460 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
462 ELM_INDEX_DATA_GET(obj, sd);
464 edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
465 evas_object_size_hint_min_set(obj, minw, minh);
466 evas_object_size_hint_max_set(obj, maxw, maxh);
470 _item_del_pre_hook(Elm_Object_Item *it)
472 ELM_INDEX_DATA_GET(WIDGET(it), sd);
474 _item_free((Elm_Index_Item *)it);
475 _index_box_clear(WIDGET(it), sd->bx[sd->level], sd->level);
480 static Elm_Index_Item *
481 _item_new(Evas_Object *obj,
488 ELM_INDEX_DATA_GET(obj, sd);
490 it = elm_widget_item_new(obj, Elm_Index_Item);
491 if (!it) return NULL;
493 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
494 if (letter) it->letter = eina_stringshare_add(letter);
496 it->base.data = data;
497 it->level = sd->level;
502 static Elm_Index_Item *
503 _item_find(Evas_Object *obj,
509 ELM_INDEX_DATA_GET(obj, sd);
511 EINA_LIST_FOREACH(sd->items, l, it)
512 if (it->base.data == data) return it;
518 _delay_change_cb(void *data)
520 Elm_Object_Item *item;
522 ELM_INDEX_DATA_GET(data, sd);
525 item = elm_index_selected_item_get(data, sd->level);
526 if (item) evas_object_smart_callback_call(data, SIG_DELAY_CHANGED, item);
528 return ECORE_CALLBACK_CANCEL;
532 _sel_eval(Evas_Object *obj,
536 Evas_Coord x, y, w, h, bx, by, bw, bh, xx, yy;
537 Elm_Index_Item *it, *it_closest, *it_last, *om_closest;
538 char *label = NULL, *last = NULL;
542 int i, j, size, dh, dx, dy;
544 ELM_INDEX_DATA_GET(obj, sd);
546 for (i = 0; i <= sd->level; i++)
552 evas_object_geometry_get(sd->bx[i], &bx, &by, &bw, &bh);
554 EINA_LIST_FOREACH(sd->items, l, it)
556 if (it->level != i) continue;
557 if (it->level != sd->level)
573 evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
578 x = (x * x) + (y * y);
579 if ((x < dist) || (!it_closest))
582 cdv = (double)(xx - bx) / (double)bw;
584 cdv = (double)(yy - by) / (double)bh;
590 if ((i == 0) && (sd->level == 0))
591 edje_object_part_drag_value_set
592 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.index.1", cdv, cdv);
594 if (it_closest && it_closest->omitted)
597 size = eina_list_count(it->omitted);
598 evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
602 printf("too many index items to omit\n"); //FIXME
605 for (j = 0; j < size; j++)
608 yy = y + (dh * j) + (dh / 2);
611 dx = (dx * dx) + (dy * dy);
612 if ((dx < dist) || (!om_closest))
614 om_closest = eina_list_nth(it->omitted, j);
621 if (om_closest) om_closest->selected = 1;
622 else if (it_closest) it_closest->selected = 1;
624 if (it_closest != it_last)
628 const char *stacking, *selectraise;
633 if (it->head != it_closest) it = it->head;
638 edje_object_signal_emit
639 (VIEW(it), "elm,state,inactive", "elm");
640 stacking = edje_object_data_get(VIEW(it), "stacking");
641 selectraise = edje_object_data_get(VIEW(it), "selectraise");
642 if ((selectraise) && (!strcmp(selectraise, "on")))
644 if ((stacking) && (!strcmp(stacking, "below")))
645 evas_object_lower(VIEW(it));
651 const char *selectraise;
655 if (!((it_last) && (it_last->head) && (it_last->head == it_closest)))
657 edje_object_signal_emit(VIEW(it), "elm,state,active", "elm");
658 selectraise = edje_object_data_get(VIEW(it), "selectraise");
659 if ((selectraise) && (!strcmp(selectraise, "on")))
660 evas_object_raise(VIEW(it));
664 evas_object_smart_callback_call
665 (obj, SIG_CHANGED, om_closest);
667 evas_object_smart_callback_call
668 (obj, SIG_CHANGED, it);
669 if (sd->delay) ecore_timer_del(sd->delay);
670 sd->delay = ecore_timer_add(sd->delay_change_time,
671 _delay_change_cb, obj);
676 if (om_closest) it = om_closest;
677 else it = it_closest;
678 if (!last && it->letter) last = strdup(it->letter);
681 if (!label && last) label = strdup(last);
686 label = realloc(label, strlen(label) +
693 if (it->letter) last = strdup(it->letter);
697 if (!label) label = strdup("");
698 if (!last) last = strdup("");
700 elm_layout_text_set(obj, "elm.text.body", label);
701 elm_layout_text_set(obj, "elm.text", last);
708 _on_mouse_wheel(void *data __UNUSED__,
710 Evas_Object *o __UNUSED__,
711 void *event_info __UNUSED__)
716 _on_mouse_down(void *data,
718 Evas_Object *o __UNUSED__,
721 Evas_Event_Mouse_Down *ev = event_info;
724 ELM_INDEX_DATA_GET(data, sd);
726 if (ev->button != 1) return;
728 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, &x, &y, &w, NULL);
729 sd->dx = ev->canvas.x - x;
730 sd->dy = ev->canvas.y - y;
731 if (!sd->autohide_disabled)
733 _index_box_clear(data, sd->bx[1], 1);
734 elm_layout_signal_emit(data, "elm,state,active", "elm");
736 _sel_eval(data, ev->canvas.x, ev->canvas.y);
737 edje_object_part_drag_value_set
738 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.pointer",
739 (!elm_object_mirrored_get(data)) ? sd->dx : (sd->dx - w), sd->dy);
740 if (sd->items && !sd->indicator_disabled)
741 elm_layout_signal_emit(data, "elm,indicator,state,active", "elm");
745 _on_mouse_up(void *data,
747 Evas_Object *o __UNUSED__,
750 Evas_Event_Mouse_Up *ev = event_info;
751 Elm_Object_Item *item;
752 Elm_Index_Item *id_item;
754 ELM_INDEX_DATA_GET(data, sd);
756 if (ev->button != 1) return;
758 item = elm_index_selected_item_get(data, sd->level);
761 evas_object_smart_callback_call(data, SIG_SELECTED, item);
762 id_item = (Elm_Index_Item *)item;
764 id_item->func((void *)id_item->base.data, WIDGET(id_item), id_item);
766 if (!sd->autohide_disabled)
767 elm_layout_signal_emit(data, "elm,state,inactive", "elm");
769 elm_layout_signal_emit(data, "elm,state,level,0", "elm");
770 if (sd->items && !sd->indicator_disabled)
771 elm_layout_signal_emit(data, "elm,indicator,state,inactive", "elm");
775 _on_mouse_move(void *data,
777 Evas_Object *o __UNUSED__,
780 Evas_Event_Mouse_Move *ev = event_info;
781 Evas_Coord minw = 0, minh = 0, x, y, dx, adx, w;
784 ELM_INDEX_DATA_GET(data, sd);
786 if (!sd->down) return;
787 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
788 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, &x, &y, &w, NULL);
789 x = ev->cur.canvas.x - x;
790 y = ev->cur.canvas.y - y;
793 if (adx < 0) adx = -dx;
794 edje_object_part_drag_value_set
795 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.pointer",
796 (!edje_object_mirrored_get(ELM_WIDGET_DATA(sd)->resize_obj)) ?
805 snprintf(buf, sizeof(buf), "elm,state,level,%i", sd->level);
806 elm_layout_signal_emit(data, buf, "elm");
807 evas_object_smart_callback_call(data, SIG_LEVEL_UP, NULL);
815 snprintf(buf, sizeof(buf), "elm,state,level,%i", sd->level);
816 elm_layout_signal_emit(data, buf, "elm");
817 evas_object_smart_callback_call(data, SIG_LEVEL_DOWN, NULL);
821 _sel_eval(data, ev->cur.canvas.x, ev->cur.canvas.y);
825 _index_resize_cb(void *data,
827 Evas_Object *obj __UNUSED__,
828 void *event_info __UNUSED__)
830 ELM_INDEX_DATA_GET_OR_RETURN(data, sd);
832 if (!sd->omit_enabled) return;
836 _index_box_clear(data, sd->bx[0], 0);
837 _index_box_auto_fill(data, sd->bx[0], 0);
839 it = (Elm_Index_Item *)elm_index_selected_item_get(obj, sd->level);
843 edje_object_signal_emit(VIEW(it->head), "elm,state,active", "elm");
845 edje_object_signal_emit(VIEW(it), "elm,state,active", "elm");
850 _elm_index_smart_add(Evas_Object *obj)
853 Evas_Coord minw, minh;
855 EVAS_SMART_DATA_ALLOC(obj, Elm_Index_Smart_Data);
857 ELM_WIDGET_CLASS(_elm_index_parent_sc)->base.add(obj);
860 (obj, "index", "base/vertical", elm_widget_style_get(obj));
862 o = evas_object_rectangle_add(evas_object_evas_get(obj));
864 evas_object_color_set(o, 0, 0, 0, 0);
866 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
867 evas_object_size_hint_min_set(o, minw, minh);
868 elm_layout_content_set(obj, "elm.swallow.event.0", o);
869 elm_widget_sub_object_add(obj, o);
871 evas_object_event_callback_add
872 (obj, EVAS_CALLBACK_RESIZE, _index_resize_cb, obj);
873 evas_object_event_callback_add
874 (o, EVAS_CALLBACK_MOUSE_WHEEL, _on_mouse_wheel, obj);
875 evas_object_event_callback_add
876 (o, EVAS_CALLBACK_MOUSE_DOWN, _on_mouse_down, obj);
877 evas_object_event_callback_add
878 (o, EVAS_CALLBACK_MOUSE_UP, _on_mouse_up, obj);
879 evas_object_event_callback_add
880 (o, EVAS_CALLBACK_MOUSE_MOVE, _on_mouse_move, obj);
882 if (edje_object_part_exists
883 (ELM_WIDGET_DATA(priv)->resize_obj, "elm.swallow.event.1"))
885 o = evas_object_rectangle_add(evas_object_evas_get(obj));
887 evas_object_color_set(o, 0, 0, 0, 0);
888 evas_object_size_hint_min_set(o, minw, minh);
889 elm_layout_content_set(obj, "elm.swallow.event.1", o);
890 elm_widget_sub_object_add(obj, o);
893 priv->bx[0] = evas_object_box_add(evas_object_evas_get(obj));
894 evas_object_box_layout_set(priv->bx[0], _box_custom_layout, priv, NULL);
895 elm_widget_sub_object_add(obj, priv->bx[0]);
896 elm_layout_content_set(obj, "elm.swallow.index.0", priv->bx[0]);
897 evas_object_show(priv->bx[0]);
899 priv->delay_change_time = INDEX_DELAY_CHANGE_TIME;
900 priv->omit_enabled = 1;
902 if (edje_object_part_exists
903 (ELM_WIDGET_DATA(priv)->resize_obj, "elm.swallow.index.1"))
905 priv->bx[1] = evas_object_box_add(evas_object_evas_get(obj));
906 evas_object_box_layout_set
907 (priv->bx[1], _box_custom_layout, priv, NULL);
908 elm_widget_sub_object_add(obj, priv->bx[1]);
909 elm_layout_content_set(obj, "elm.swallow.index.1", priv->bx[1]);
910 evas_object_show(priv->bx[1]);
913 _mirrored_set(obj, elm_widget_mirrored_get(obj));
914 elm_layout_sizing_eval(obj);
915 elm_widget_can_focus_set(obj, EINA_FALSE);
918 if (_elm_config->access_mode)
920 elm_index_autohide_disabled_set(obj, EINA_TRUE);
921 elm_layout_signal_emit(obj, "elm,access,state,active", "elm");
922 _access_index_register(obj);
927 _elm_index_smart_del(Evas_Object *obj)
932 ELM_INDEX_DATA_GET(obj, sd);
936 it = sd->items->data;
937 elm_widget_item_del(it);
940 EINA_LIST_FREE(sd->omit, o)
943 if (sd->delay) ecore_timer_del(sd->delay);
945 ELM_WIDGET_CLASS(_elm_index_parent_sc)->base.del(obj);
949 _elm_index_smart_focus_next(const Evas_Object *obj,
950 Elm_Focus_Direction dir,
953 Eina_List *items = NULL;
960 ELM_INDEX_CHECK(obj) EINA_FALSE;
961 ELM_INDEX_DATA_GET(obj, sd);
963 if (!sd->autohide_disabled)
964 elm_layout_signal_emit((Evas_Object *)obj, "elm,state,active", "elm");
966 po = (Evas_Object *)edje_object_part_object_get
967 (elm_layout_edje_get(obj), "access");
968 ao = evas_object_data_get(po, "_part_access_obj");
969 items = eina_list_append(items, ao);
973 EINA_LIST_FOREACH(sd->items, l, it)
975 if (it->level != 0) continue;
976 items = eina_list_append(items, it->base.access_obj);
980 ret = elm_widget_focus_list_next_get
981 (obj, items, eina_list_data_get, dir, next);
985 sd->index_focus = EINA_FALSE;
987 Evas_Object *it_access_obj = eina_list_nth(items, eina_list_count(items) - 1);
989 items = eina_list_free(items);
990 items = eina_list_append(items, it_access_obj);
991 items = eina_list_append(items, ao);
993 ret = elm_widget_focus_list_next_get(obj, items, eina_list_data_get, dir, next);
995 // to hide index item, if there is nothing to focus on autohide disalbe mode
996 if (!sd->autohide_disabled)
997 elm_layout_signal_emit((Evas_Object *)obj, "elm,state,inactive", "elm");
1004 _access_obj_process(Evas_Object *obj, Eina_Bool is_access)
1009 ELM_INDEX_DATA_GET(obj, sd);
1011 EINA_LIST_FOREACH(sd->items, l, it)
1013 if (it->level != 0) continue;
1014 if (is_access) _access_widget_item_register(it);
1015 else _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
1020 elm_index_autohide_disabled_set(obj, EINA_TRUE);
1021 elm_layout_signal_emit(obj, "elm,access,state,active", "elm");
1022 _access_index_register(obj);
1026 // opposition of _access_index_register();
1027 elm_index_autohide_disabled_set(obj, EINA_FALSE);
1028 elm_layout_signal_emit(obj, "elm,access,state,inactive", "elm");
1029 elm_widget_can_focus_set(obj, EINA_FALSE);
1030 _elm_access_edje_object_part_object_unregister
1031 (obj, elm_layout_edje_get(obj), "access");
1036 _access_hook(Evas_Object *obj, Eina_Bool is_access)
1038 ELM_INDEX_CHECK(obj);
1039 ELM_INDEX_DATA_GET(obj, sd);
1042 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
1043 _elm_index_smart_focus_next;
1045 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
1046 _access_obj_process(obj, is_access);
1050 _elm_index_smart_set_user(Elm_Index_Smart_Class *sc)
1052 ELM_WIDGET_CLASS(sc)->base.add = _elm_index_smart_add;
1053 ELM_WIDGET_CLASS(sc)->base.del = _elm_index_smart_del;
1055 ELM_WIDGET_CLASS(sc)->theme = _elm_index_smart_theme;
1056 ELM_WIDGET_CLASS(sc)->translate = _elm_index_smart_translate;
1058 /* not a 'focus chain manager' */
1059 ELM_WIDGET_CLASS(sc)->focus_next = NULL;
1060 ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
1062 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_index_smart_sizing_eval;
1064 if (_elm_config->access_mode)
1065 ELM_WIDGET_CLASS(sc)->focus_next = _elm_index_smart_focus_next;
1067 ELM_WIDGET_CLASS(sc)->access = _access_hook;
1070 EAPI const Elm_Index_Smart_Class *
1071 elm_index_smart_class_get(void)
1073 static Elm_Index_Smart_Class _sc =
1074 ELM_INDEX_SMART_CLASS_INIT_NAME_VERSION(ELM_INDEX_SMART_NAME);
1075 static const Elm_Index_Smart_Class *class = NULL;
1076 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
1081 _elm_index_smart_set(&_sc);
1082 esc->callbacks = _smart_callbacks;
1089 elm_index_add(Evas_Object *parent)
1093 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
1095 obj = elm_widget_add(_elm_index_smart_class_new(), parent);
1096 if (!obj) return NULL;
1098 if (!elm_widget_sub_object_add(parent, obj))
1099 ERR("could not add %p as sub object of %p", obj, parent);
1105 elm_index_autohide_disabled_set(Evas_Object *obj,
1108 ELM_INDEX_CHECK(obj);
1109 ELM_INDEX_DATA_GET(obj, sd);
1111 disabled = !!disabled;
1112 if (sd->autohide_disabled == disabled) return;
1113 sd->autohide_disabled = disabled;
1115 if (sd->autohide_disabled)
1117 _index_box_clear(obj, sd->bx[1], 1);
1118 elm_layout_signal_emit(obj, "elm,state,active", "elm");
1121 elm_layout_signal_emit(obj, "elm,state,inactive", "elm");
1123 //FIXME: Should be update indicator based on the indicator visiblility
1127 elm_index_autohide_disabled_get(const Evas_Object *obj)
1129 ELM_INDEX_CHECK(obj) EINA_FALSE;
1130 ELM_INDEX_DATA_GET(obj, sd);
1132 return sd->autohide_disabled;
1136 elm_index_item_level_set(Evas_Object *obj,
1139 ELM_INDEX_CHECK(obj);
1140 ELM_INDEX_DATA_GET(obj, sd);
1142 if (sd->level == level) return;
1147 elm_index_item_level_get(const Evas_Object *obj)
1149 ELM_INDEX_CHECK(obj) 0;
1150 ELM_INDEX_DATA_GET(obj, sd);
1155 //FIXME: Should update indicator based on the autohidden status & indicator visiblility
1157 elm_index_item_selected_set(Elm_Object_Item *it,
1160 Elm_Index_Item *it_sel, *it_last;
1161 Evas_Object *obj = WIDGET(it);
1163 ELM_INDEX_ITEM_CHECK_OR_RETURN(it);
1164 ELM_INDEX_DATA_GET(obj, sd);
1166 selected = !!selected;
1167 it_sel = (Elm_Index_Item *)it;
1168 if (it_sel->selected == selected) return;
1172 it_last = (Elm_Index_Item *)elm_index_selected_item_get(obj, sd->level);
1176 it_last->selected = 0;
1178 edje_object_signal_emit(VIEW(it_last->head), "elm,state,inactive", "elm");
1180 edje_object_signal_emit(VIEW(it_last), "elm,state,inactive", "elm");
1182 it_sel->selected = 1;
1184 edje_object_signal_emit(VIEW(it_sel->head), "elm,state,active", "elm");
1186 edje_object_signal_emit(VIEW(it_sel), "elm,state,active", "elm");
1188 evas_object_smart_callback_call
1189 (obj, SIG_CHANGED, it);
1190 evas_object_smart_callback_call
1191 (obj, SIG_SELECTED, it);
1192 if (sd->delay) ecore_timer_del(sd->delay);
1193 sd->delay = ecore_timer_add(sd->delay_change_time,
1194 _delay_change_cb, obj);
1198 it_sel->selected = 0;
1200 edje_object_signal_emit(VIEW(it_sel->head), "elm,state,inactive", "elm");
1202 edje_object_signal_emit(VIEW(it_sel), "elm,state,inactive", "elm");
1206 EAPI Elm_Object_Item *
1207 elm_index_selected_item_get(const Evas_Object *obj,
1213 ELM_INDEX_CHECK(obj) NULL;
1214 ELM_INDEX_DATA_GET(obj, sd);
1216 EINA_LIST_FOREACH(sd->items, l, it)
1218 if ((it->selected) && (it->level == level))
1219 return (Elm_Object_Item *)it;
1225 EAPI Elm_Object_Item *
1226 elm_index_item_append(Evas_Object *obj,
1233 ELM_INDEX_CHECK(obj) NULL;
1234 ELM_INDEX_DATA_GET(obj, sd);
1236 it = _item_new(obj, letter, func, data);
1237 if (!it) return NULL;
1239 sd->items = eina_list_append(sd->items, it);
1240 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1242 return (Elm_Object_Item *)it;
1245 EAPI Elm_Object_Item *
1246 elm_index_item_prepend(Evas_Object *obj,
1253 ELM_INDEX_CHECK(obj) NULL;
1254 ELM_INDEX_DATA_GET(obj, sd);
1256 it = _item_new(obj, letter, func, data);
1257 if (!it) return NULL;
1259 sd->items = eina_list_prepend(sd->items, it);
1260 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1262 return (Elm_Object_Item *)it;
1265 EINA_DEPRECATED EAPI Elm_Object_Item *
1266 elm_index_item_prepend_relative(Evas_Object *obj,
1269 const Elm_Object_Item *relative)
1271 return elm_index_item_insert_before
1272 (obj, (Elm_Object_Item *)relative, letter, NULL, item);
1275 EAPI Elm_Object_Item *
1276 elm_index_item_insert_after(Evas_Object *obj,
1277 Elm_Object_Item *after,
1284 ELM_INDEX_CHECK(obj) NULL;
1285 ELM_INDEX_DATA_GET(obj, sd);
1287 if (!after) return elm_index_item_append(obj, letter, func, data);
1289 it = _item_new(obj, letter, func, data);
1290 if (!it) return NULL;
1292 sd->items = eina_list_append_relative(sd->items, it, after);
1293 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1295 return (Elm_Object_Item *)it;
1298 EAPI Elm_Object_Item *
1299 elm_index_item_insert_before(Evas_Object *obj,
1300 Elm_Object_Item *before,
1307 ELM_INDEX_CHECK(obj) NULL;
1308 ELM_INDEX_DATA_GET(obj, sd);
1310 if (!before) return elm_index_item_prepend(obj, letter, func, data);
1312 it = _item_new(obj, letter, func, data);
1313 if (!it) return NULL;
1315 sd->items = eina_list_prepend_relative(sd->items, it, before);
1316 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1318 return (Elm_Object_Item *)it;
1321 EAPI Elm_Object_Item *
1322 elm_index_item_sorted_insert(Evas_Object *obj,
1326 Eina_Compare_Cb cmp_func,
1327 Eina_Compare_Cb cmp_data_func)
1333 ELM_INDEX_CHECK(obj) NULL;
1334 ELM_INDEX_DATA_GET(obj, sd);
1336 if (!(sd->items)) return elm_index_item_append(obj, letter, func, data);
1338 it = _item_new(obj, letter, func, data);
1339 if (!it) return NULL;
1341 lnear = eina_list_search_sorted_near_list(sd->items, cmp_func, it, &cmp);
1343 sd->items = eina_list_append_relative_list(sd->items, it, lnear);
1345 sd->items = eina_list_prepend_relative_list(sd->items, it, lnear);
1348 /* If cmp_data_func is not provided, append a duplicated item */
1350 sd->items = eina_list_append_relative_list(sd->items, it, lnear);
1353 Elm_Index_Item *p_it = eina_list_data_get(lnear);
1354 if (cmp_data_func(p_it->base.data, it->base.data) >= 0)
1355 p_it->base.data = it->base.data;
1356 elm_widget_item_del(it);
1360 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1362 if (!it) return NULL;
1363 return (Elm_Object_Item *)it;
1366 EAPI Elm_Object_Item *
1367 elm_index_item_find(Evas_Object *obj,
1370 ELM_INDEX_CHECK(obj) NULL;
1372 return (Elm_Object_Item *)_item_find(obj, data);
1376 elm_index_item_clear(Evas_Object *obj)
1379 Eina_List *l, *clear = NULL;
1381 ELM_INDEX_CHECK(obj);
1382 ELM_INDEX_DATA_GET(obj, sd);
1384 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1385 EINA_LIST_FOREACH(sd->items, l, it)
1387 if (it->level != sd->level) continue;
1388 clear = eina_list_append(clear, it);
1390 EINA_LIST_FREE (clear, it)
1391 elm_widget_item_del(it);
1395 elm_index_level_go(Evas_Object *obj,
1396 int level __UNUSED__)
1398 ELM_INDEX_CHECK(obj);
1399 ELM_INDEX_DATA_GET(obj, sd);
1401 _index_box_clear(obj, sd->bx[0], 0);
1402 _index_box_auto_fill(obj, sd->bx[0], 0);
1405 _index_box_clear(obj, sd->bx[1], 1);
1406 _index_box_auto_fill(obj, sd->bx[1], 1);
1411 elm_index_indicator_disabled_set(Evas_Object *obj,
1414 ELM_INDEX_CHECK(obj);
1415 ELM_INDEX_DATA_GET(obj, sd);
1417 disabled = !!disabled;
1418 if (sd->indicator_disabled == disabled) return;
1419 sd->indicator_disabled = disabled;
1420 if (!sd->items) return;
1422 elm_layout_signal_emit(obj, "elm,indicator,state,inactive", "elm");
1424 elm_layout_signal_emit(obj, "elm,indicator,state,active", "elm");
1428 elm_index_indicator_disabled_get(const Evas_Object *obj)
1430 ELM_INDEX_CHECK(obj) EINA_FALSE;
1431 ELM_INDEX_DATA_GET(obj, sd);
1433 return sd->indicator_disabled;
1437 elm_index_item_letter_get(const Elm_Object_Item *it)
1439 ELM_INDEX_ITEM_CHECK_OR_RETURN(it, NULL);
1441 return ((Elm_Index_Item *)it)->letter;
1445 elm_index_horizontal_set(Evas_Object *obj,
1446 Eina_Bool horizontal)
1448 ELM_INDEX_CHECK(obj);
1449 ELM_INDEX_DATA_GET(obj, sd);
1451 horizontal = !!horizontal;
1452 if (horizontal == sd->horizontal) return;
1454 sd->horizontal = horizontal;
1456 sd->omit_enabled = EINA_FALSE;
1457 _elm_index_smart_theme(obj);
1461 elm_index_horizontal_get(const Evas_Object *obj)
1463 ELM_INDEX_CHECK(obj) EINA_FALSE;
1464 ELM_INDEX_DATA_GET(obj, sd);
1466 return sd->horizontal;
1470 elm_index_delay_change_time_set(Evas_Object *obj, double delay_change_time)
1472 ELM_INDEX_CHECK(obj);
1473 ELM_INDEX_DATA_GET(obj, sd);
1475 sd->delay_change_time = delay_change_time;
1479 elm_index_delay_change_time_get(const Evas_Object *obj)
1481 ELM_INDEX_CHECK(obj) 0.0;
1482 ELM_INDEX_DATA_GET(obj, sd);
1484 return sd->delay_change_time;
1488 elm_index_omit_enabled_set(Evas_Object *obj,
1491 ELM_INDEX_CHECK(obj);
1492 ELM_INDEX_DATA_GET(obj, sd);
1494 if (sd->horizontal) return;
1496 enabled = !!enabled;
1497 if (sd->omit_enabled == enabled) return;
1498 sd->omit_enabled = enabled;
1500 _index_box_clear(obj, sd->bx[0], 0);
1501 _index_box_auto_fill(obj, sd->bx[0], 0);
1504 _index_box_clear(obj, sd->bx[1], 1);
1505 _index_box_auto_fill(obj, sd->bx[1], 1);
1510 elm_index_omit_enabled_get(const Evas_Object *obj)
1512 ELM_INDEX_CHECK(obj) EINA_FALSE;
1513 ELM_INDEX_DATA_GET(obj, sd);
1515 return sd->omit_enabled;