1 #include <Elementary.h>
4 #include "elm_widget_index.h"
6 EAPI const char ELM_INDEX_SMART_NAME[] = "elm_index";
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[] = {
15 {SIG_DELAY_CHANGED, ""},
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);
27 _item_free(Elm_Index_Item *it)
29 ELM_INDEX_DATA_GET(WIDGET(it), sd);
31 sd->items = eina_list_remove(sd->items, it);
34 eina_stringshare_del(it->letter);
40 _box_custom_layout(Evas_Object *o,
41 Evas_Object_Box_Data *priv,
44 Elm_Index_Smart_Data *sd = data;
46 _els_box_layout(o, priv, sd->horizontal, 1, 0);
50 _index_box_clear(Evas_Object *obj,
51 Evas_Object *box __UNUSED__,
57 ELM_INDEX_DATA_GET(obj, sd);
59 if (!sd->level_active[level]) return;
61 EINA_LIST_FOREACH(sd->items, l, it)
63 if (!VIEW(it)) continue;
64 if (it->level != level) continue;
66 evas_object_del(VIEW(it));
70 sd->level_active[level] = 0;
74 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
76 const char *txt = NULL;
78 Elm_Index_Item *it = (Elm_Index_Item *)data;
79 ELM_INDEX_ITEM_CHECK_OR_RETURN(it, NULL);
81 txt = elm_widget_access_info_get(obj);
82 if (!txt) txt = it->letter;
83 if (txt) return strdup(txt);
89 _access_widget_item_register(Elm_Index_Item *it)
93 _elm_access_widget_item_register((Elm_Widget_Item *)it);
95 ai = _elm_access_object_get(it->base.access_obj);
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);
102 _omit_calc(void *data, int num_of_items, int max_num_of_items)
104 Elm_Index_Smart_Data *sd = data;
105 int max_group_num, num_of_extra_items, i, g, size, sum;
107 Elm_Index_Item *it, *it2;
110 EINA_LIST_FREE(sd->omit, o)
113 EINA_LIST_FOREACH(sd->items, l, it)
116 it->omitted = eina_list_free(it->omitted);
117 if (it->head) it->head = NULL;
120 if (max_num_of_items < 3 || num_of_items <= max_num_of_items) return;
122 max_group_num = (max_num_of_items - 1) / 2;
123 num_of_extra_items = num_of_items - max_num_of_items;
125 int group_pos[max_group_num];
126 int omit_info[max_num_of_items];
128 if (num_of_extra_items >= max_group_num)
131 for (i = 0; i < max_group_num; i++)
139 size = max_num_of_items / (num_of_extra_items + 1);
141 for (i = 0; i < num_of_extra_items; i++)
147 for (i = 0; i < max_num_of_items; i++)
149 for (i = 0; i < num_of_extra_items; i++)
150 omit_info[group_pos[i % max_group_num]]++;
154 for (i = 0; i < max_num_of_items; i++)
156 if (omit_info[i] > 1)
158 o = (Elm_Index_Omit *)malloc(sizeof(Elm_Index_Omit));
160 o->count = omit_info[i];
161 sd->omit = eina_list_append(sd->omit, o);
168 // FIXME: always have index filled
170 _index_box_auto_fill(Evas_Object *obj,
174 int i = 0, max_num_of_items = 0, num_of_items = 0, g = 0, skip = 0;
177 Elm_Index_Item *it, *head;
178 Evas_Coord mw, mh, ih, vh;
180 Evas_Object *o_odd, *o_even;
182 ELM_INDEX_DATA_GET(obj, sd);
184 if (sd->level_active[level]) return;
186 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, NULL, NULL, NULL, &ih);
188 rtl = elm_widget_mirrored_get(obj);
190 o_odd = edje_object_add(evas_object_evas_get(obj));
191 o_even = edje_object_add(evas_object_evas_get(obj));
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));
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;
206 EINA_LIST_FOREACH(sd->items, l, it)
208 if (it->level == level) num_of_items++;
212 max_num_of_items = ih / mh;
214 _omit_calc(sd, num_of_items, max_num_of_items);
217 om = eina_list_nth(sd->omit, g);
218 EINA_LIST_FOREACH(sd->items, l, it)
221 const char *stacking;
223 if (it->level != level) continue;
225 if (om && i == om->offset)
231 head->omitted = eina_list_append(head->omitted, it);
232 om = eina_list_nth(sd->omit, ++g);
241 head->omitted = eina_list_append(head->omitted, it);
246 o = edje_object_add(evas_object_evas_get(obj));
248 edje_object_mirrored_set(VIEW(it), rtl);
253 elm_widget_theme_object_set
254 (obj, o, "index", "item_odd/horizontal",
255 elm_widget_style_get(obj));
257 elm_widget_theme_object_set
258 (obj, o, "index", "item/horizontal",
259 elm_widget_style_get(obj));
264 elm_widget_theme_object_set
265 (obj, o, "index", "item_odd/vertical",
266 elm_widget_style_get(obj));
268 elm_widget_theme_object_set
269 (obj, o, "index", "item/vertical",
270 elm_widget_style_get(obj));
274 edje_object_part_text_escaped_set(o, "elm.text", "*");
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");
287 if (!strcmp(stacking, "below")) evas_object_lower(o);
288 else if (!strcmp(stacking, "above"))
289 evas_object_raise(o);
297 if ((it->level == 0) &&
298 (_elm_config->access_mode == ELM_ACCESS_MODE_ON))
299 _access_widget_item_register(it);
302 evas_object_smart_calculate(box);
303 sd->level_active[level] = 1;
307 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
309 ELM_INDEX_DATA_GET(obj, sd);
312 edje_object_mirrored_set(ELM_WIDGET_DATA(sd)->resize_obj, rtl);
316 _elm_index_smart_theme(Evas_Object *obj)
318 Evas_Coord minw = 0, minh = 0;
322 ELM_INDEX_DATA_GET(obj, sd);
324 _index_box_clear(obj, sd->bx[0], 0);
325 _index_box_clear(obj, sd->bx[1], 1);
328 eina_stringshare_replace(&ELM_LAYOUT_DATA(sd)->group, "base/horizontal");
331 eina_stringshare_replace(&ELM_LAYOUT_DATA(sd)->group, "base/vertical");
332 _mirrored_set(obj, elm_widget_mirrored_get(obj));
335 if (!ELM_WIDGET_CLASS(_elm_index_parent_sc)->theme(obj)) return EINA_FALSE;
337 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
338 evas_object_size_hint_min_set(sd->event[0], minw, minh);
340 if (edje_object_part_exists
341 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.index.1"))
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]);
350 elm_layout_content_set(obj, "elm.swallow.index.1", sd->bx[1]);
354 evas_object_del(sd->bx[1]);
357 if (edje_object_part_exists
358 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.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]);
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);
370 else if (sd->event[1])
372 evas_object_del(sd->event[1]);
375 edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
377 elm_layout_sizing_eval(obj);
378 _index_box_auto_fill(obj, sd->bx[0], 0);
380 if (sd->autohide_disabled)
382 if (sd->level == 1) _index_box_auto_fill(obj, sd->bx[1], 1);
383 elm_layout_signal_emit(obj, "elm,state,active", "elm");
385 else elm_layout_signal_emit(obj, "elm,state,inactive", "elm");
387 EINA_LIST_FOREACH(sd->items, l, it)
390 edje_object_signal_emit(VIEW(it), "elm,state,active", "elm");
397 _elm_index_smart_sizing_eval(Evas_Object *obj)
399 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
401 ELM_INDEX_DATA_GET(obj, sd);
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);
409 _item_del_pre_hook(Elm_Object_Item *it)
411 ELM_INDEX_DATA_GET(WIDGET(it), sd);
413 _item_free((Elm_Index_Item *)it);
414 _index_box_clear(WIDGET(it), sd->bx[sd->level], sd->level);
419 static Elm_Index_Item *
420 _item_new(Evas_Object *obj,
427 ELM_INDEX_DATA_GET(obj, sd);
429 it = elm_widget_item_new(obj, Elm_Index_Item);
430 if (!it) return NULL;
432 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
433 if (letter) it->letter = eina_stringshare_add(letter);
435 it->base.data = data;
436 it->level = sd->level;
441 static Elm_Index_Item *
442 _item_find(Evas_Object *obj,
448 ELM_INDEX_DATA_GET(obj, sd);
450 EINA_LIST_FOREACH(sd->items, l, it)
451 if (it->base.data == data) return it;
457 _delay_change(void *data)
459 Elm_Object_Item *item;
461 ELM_INDEX_DATA_GET(data, sd);
464 item = elm_index_selected_item_get(data, sd->level);
465 if (item) evas_object_smart_callback_call(data, SIG_DELAY_CHANGED, item);
467 return ECORE_CALLBACK_CANCEL;
471 _sel_eval(Evas_Object *obj,
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;
481 int i, j, size, dh, dx, dy;
483 ELM_INDEX_DATA_GET(obj, sd);
485 for (i = 0; i <= sd->level; i++)
491 evas_object_geometry_get(sd->bx[i], &bx, &by, &bw, &bh);
493 EINA_LIST_FOREACH(sd->items, l, it)
495 if (it->level != i) continue;
496 if (it->level != sd->level)
512 evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
517 x = (x * x) + (y * y);
518 if ((x < dist) || (!it_closest))
521 cdv = (double)(xx - bx) / (double)bw;
523 cdv = (double)(yy - by) / (double)bh;
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);
533 if (it_closest && it_closest->omitted)
536 size = eina_list_count(it->omitted);
537 evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
541 printf("too many index items to omit\n"); // omit mode not possible
544 for (j = 0; j < size; j++)
547 yy = y + (dh * j) + (dh / 2);
550 dx = (dx * dx) + (dy * dy);
551 if ((dx < dist) || (!om_closest))
553 om_closest = eina_list_nth(it->omitted, j);
560 if (om_closest) om_closest->selected = 1;
561 else if (it_closest) it_closest->selected = 1;
563 if (it_closest != it_last)
567 const char *stacking, *selectraise;
572 if (it->head != it_closest) it = it->head;
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")))
583 if ((stacking) && (!strcmp(stacking, "below")))
584 evas_object_lower(VIEW(it));
590 const char *selectraise;
594 if (!(it_last && it_last->head && it_last->head == it_closest))
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));
602 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
606 buf = eina_strbuf_new();
609 eina_strbuf_append_printf(buf, "index item %s clicked", om_closest->letter);
611 eina_strbuf_append_printf(buf, "index item %s clicked", it->letter);
612 ret = eina_strbuf_string_steal(buf);
613 eina_strbuf_free(buf);
615 _elm_access_highlight_set(it->base.access_obj);
616 _elm_access_say(ret);
620 evas_object_smart_callback_call
621 (obj, SIG_CHANGED, (void *)om_closest);
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);
631 if (om_closest) it = om_closest;
632 else it = it_closest;
633 if (!last && it->letter) last = strdup(it->letter);
636 if (!label && last) label = strdup(last);
641 label = realloc(label, strlen(label) +
648 if (it->letter) last = strdup(it->letter);
652 if (!label) label = strdup("");
653 if (!last) last = strdup("");
655 elm_layout_text_set(obj, "elm.text.body", label);
656 elm_layout_text_set(obj, "elm.text", last);
663 _on_mouse_wheel(void *data __UNUSED__,
665 Evas_Object *o __UNUSED__,
666 void *event_info __UNUSED__)
671 _on_mouse_down(void *data,
673 Evas_Object *o __UNUSED__,
676 Evas_Event_Mouse_Down *ev = event_info;
679 ELM_INDEX_DATA_GET(data, sd);
681 if (ev->button != 1) return;
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)
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");
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");
701 _on_mouse_up(void *data,
703 Evas_Object *o __UNUSED__,
706 Evas_Event_Mouse_Up *ev = event_info;
707 Elm_Object_Item *item;
708 Elm_Index_Item *id_item;
710 ELM_INDEX_DATA_GET(data, sd);
712 if (ev->button != 1) return;
714 item = elm_index_selected_item_get(data, sd->level);
717 evas_object_smart_callback_call(data, SIG_SELECTED, item);
718 id_item = (Elm_Index_Item *)item;
720 id_item->func((void *)id_item->base.data, WIDGET(id_item), id_item);
722 if (!sd->autohide_disabled)
723 elm_layout_signal_emit(data, "elm,state,inactive", "elm");
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");
731 _on_mouse_move(void *data,
733 Evas_Object *o __UNUSED__,
736 Evas_Event_Mouse_Move *ev = event_info;
737 Evas_Coord minw = 0, minh = 0, x, y, dx, adx, w;
740 ELM_INDEX_DATA_GET(data, sd);
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;
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)) ?
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);
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);
777 _sel_eval(data, ev->cur.canvas.x, ev->cur.canvas.y);
781 _on_mouse_in_access(void *data,
783 Evas_Object *o __UNUSED__,
784 void *event_info __UNUSED__)
786 ELM_INDEX_DATA_GET(data, sd);
788 if (sd->down) return;
790 if (!sd->autohide_disabled)
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");
799 _on_mouse_move_access(void *data,
801 Evas_Object *o __UNUSED__,
805 Evas_Event_Mouse_Down *ev = event_info;
806 Elm_Index_Item *it, *it_closest;
809 Evas_Coord x, y, w, h, xx, yy;
811 ELM_INDEX_DATA_GET(data, sd);
816 EINA_LIST_FOREACH(sd->items, l, it)
818 evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
821 x = ev->canvas.x - xx;
822 y = ev->canvas.y - yy;
823 x = (x * x) + (y * y);
824 if ((x < dist) || (!it_closest))
832 _elm_access_highlight_set(it_closest->base.access_obj);
836 _on_mouse_out_access(void *data,
838 Evas_Object *o __UNUSED__,
839 void *event_info __UNUSED__)
841 ELM_INDEX_DATA_GET(data, sd);
843 if (!sd->autohide_disabled)
844 elm_layout_signal_emit(data, "elm,state,inactive", "elm");
848 _access_index_register(Evas_Object *obj)
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");
855 (_elm_access_object_get(ao), ELM_ACCESS_TYPE, E_("Index"));
859 _index_resize_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
861 ELM_INDEX_DATA_GET_OR_RETURN(data, sd);
863 if (sd->horizontal) return;
868 _index_box_clear(data, sd->bx[0], 0);
869 _index_box_auto_fill(data, sd->bx[0], 0);
871 if (sd->autohide_disabled)
872 elm_layout_signal_emit(data, "elm,state,active", "elm");
874 EINA_LIST_FOREACH(sd->items, l, it)
877 edje_object_signal_emit(VIEW(it), "elm,state,active", "elm");
882 _elm_index_smart_add(Evas_Object *obj)
885 Evas_Coord minw, minh;
887 EVAS_SMART_DATA_ALLOC(obj, Elm_Index_Smart_Data);
889 ELM_WIDGET_CLASS(_elm_index_parent_sc)->base.add(obj);
891 priv->indicator_disabled = EINA_FALSE;
892 priv->horizontal = EINA_FALSE;
893 priv->autohide_disabled = EINA_FALSE;
896 (obj, "index", "base/vertical", elm_widget_style_get(obj));
898 o = evas_object_rectangle_add(evas_object_evas_get(obj));
900 evas_object_color_set(o, 0, 0, 0, 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);
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);
920 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
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);
930 if (edje_object_part_exists
931 (ELM_WIDGET_DATA(priv)->resize_obj, "elm.swallow.event.1"))
933 o = evas_object_rectangle_add(evas_object_evas_get(obj));
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);
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]);
947 if (edje_object_part_exists
948 (ELM_WIDGET_DATA(priv)->resize_obj, "elm.swallow.index.1"))
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]);
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!!
963 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
964 _access_index_register(obj);
968 _elm_index_smart_del(Evas_Object *obj)
973 ELM_INDEX_DATA_GET(obj, sd);
977 it = sd->items->data;
979 elm_widget_item_del(it);
982 EINA_LIST_FREE(sd->omit, o)
985 if (sd->delay) ecore_timer_del(sd->delay);
987 ELM_WIDGET_CLASS(_elm_index_parent_sc)->base.del(obj);
991 _elm_index_smart_focus_next(const Evas_Object *obj,
992 Elm_Focus_Direction dir,
995 Eina_List *items = NULL;
1001 ELM_INDEX_CHECK(obj) EINA_FALSE;
1002 ELM_INDEX_DATA_GET(obj, sd);
1004 if (!sd->autohide_disabled)
1005 elm_layout_signal_emit((Evas_Object *)obj, "elm,state,active", "elm");
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);
1012 EINA_LIST_FOREACH(sd->items, l, it)
1014 if (it->level != 0) continue;
1015 items = eina_list_append(items, it->base.access_obj);
1019 ret = elm_widget_focus_list_next_get
1020 (obj, items, eina_list_data_get, dir, next);
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");
1030 _access_obj_process(Evas_Object *obj, Eina_Bool is_access)
1035 ELM_INDEX_DATA_GET(obj, sd);
1037 EINA_LIST_FOREACH(sd->items, l, it)
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);
1046 _access_index_register(obj);
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);
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");
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);
1072 _access_hook(Evas_Object *obj, Eina_Bool is_access)
1074 ELM_INDEX_CHECK(obj);
1075 ELM_INDEX_DATA_GET(obj, sd);
1078 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
1079 _elm_index_smart_focus_next;
1081 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
1082 _access_obj_process(obj, is_access);
1086 _elm_index_smart_set_user(Elm_Index_Smart_Class *sc)
1088 ELM_WIDGET_CLASS(sc)->base.add = _elm_index_smart_add;
1089 ELM_WIDGET_CLASS(sc)->base.del = _elm_index_smart_del;
1091 ELM_WIDGET_CLASS(sc)->theme = _elm_index_smart_theme;
1093 /* not a 'focus chain manager' */
1094 ELM_WIDGET_CLASS(sc)->focus_next = NULL;
1095 ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
1097 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_index_smart_sizing_eval;
1099 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
1100 ELM_WIDGET_CLASS(sc)->focus_next = _elm_index_smart_focus_next;
1102 ELM_WIDGET_CLASS(sc)->access = _access_hook;
1105 EAPI const Elm_Index_Smart_Class *
1106 elm_index_smart_class_get(void)
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;
1116 _elm_index_smart_set(&_sc);
1117 esc->callbacks = _smart_callbacks;
1124 elm_index_add(Evas_Object *parent)
1128 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
1130 obj = elm_widget_add(_elm_index_smart_class_new(), parent);
1131 if (!obj) return NULL;
1133 if (!elm_widget_sub_object_add(parent, obj))
1134 ERR("could not add %p as sub object of %p", obj, parent);
1140 elm_index_autohide_disabled_set(Evas_Object *obj,
1143 ELM_INDEX_CHECK(obj);
1144 ELM_INDEX_DATA_GET(obj, sd);
1146 disabled = !!disabled;
1147 if (sd->autohide_disabled == disabled) return;
1148 sd->autohide_disabled = disabled;
1150 if (sd->autohide_disabled)
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");
1157 elm_layout_signal_emit(obj, "elm,state,inactive", "elm");
1159 //FIXME: Should be update indicator based on the indicator visiblility
1163 elm_index_autohide_disabled_get(const Evas_Object *obj)
1165 ELM_INDEX_CHECK(obj) EINA_FALSE;
1166 ELM_INDEX_DATA_GET(obj, sd);
1168 return sd->autohide_disabled;
1172 elm_index_item_level_set(Evas_Object *obj,
1175 ELM_INDEX_CHECK(obj);
1176 ELM_INDEX_DATA_GET(obj, sd);
1178 if (sd->level == level) return;
1183 elm_index_item_level_get(const Evas_Object *obj)
1185 ELM_INDEX_CHECK(obj) 0;
1186 ELM_INDEX_DATA_GET(obj, sd);
1192 elm_index_item_selected_set(Elm_Object_Item *it,
1195 Evas_Coord x, y, w, h;
1197 ELM_INDEX_ITEM_CHECK_OR_RETURN(it);
1199 //FIXME: Should be update indicator based on the autohidden status
1200 //& indicator visiblility
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");
1208 else _sel_eval(WIDGET(it), -99999, -9999);
1211 EAPI Elm_Object_Item *
1212 elm_index_selected_item_get(const Evas_Object *obj,
1218 ELM_INDEX_CHECK(obj) NULL;
1219 ELM_INDEX_DATA_GET(obj, sd);
1221 EINA_LIST_FOREACH(sd->items, l, it)
1223 if ((it->selected) && (it->level == level))
1224 return (Elm_Object_Item *)it;
1230 EAPI Elm_Object_Item *
1231 elm_index_item_append(Evas_Object *obj,
1238 ELM_INDEX_CHECK(obj) NULL;
1239 ELM_INDEX_DATA_GET(obj, sd);
1241 it = _item_new(obj, letter, func, data);
1242 if (!it) return NULL;
1244 sd->items = eina_list_append(sd->items, it);
1245 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1247 return (Elm_Object_Item *)it;
1250 EAPI Elm_Object_Item *
1251 elm_index_item_prepend(Evas_Object *obj,
1258 ELM_INDEX_CHECK(obj) NULL;
1259 ELM_INDEX_DATA_GET(obj, sd);
1261 it = _item_new(obj, letter, func, data);
1262 if (!it) return NULL;
1264 sd->items = eina_list_prepend(sd->items, it);
1265 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1267 return (Elm_Object_Item *)it;
1270 EINA_DEPRECATED EAPI Elm_Object_Item *
1271 elm_index_item_prepend_relative(Evas_Object *obj,
1274 const Elm_Object_Item *relative)
1276 return elm_index_item_insert_before
1277 (obj, (Elm_Object_Item *)relative, letter, NULL, item);
1280 EAPI Elm_Object_Item *
1281 elm_index_item_insert_after(Evas_Object *obj,
1282 Elm_Object_Item *after,
1289 ELM_INDEX_CHECK(obj) NULL;
1290 ELM_INDEX_DATA_GET(obj, sd);
1292 if (!after) return elm_index_item_append(obj, letter, func, data);
1294 it = _item_new(obj, letter, func, data);
1295 if (!it) return NULL;
1297 sd->items = eina_list_append_relative(sd->items, it, after);
1298 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1300 return (Elm_Object_Item *)it;
1303 EAPI Elm_Object_Item *
1304 elm_index_item_insert_before(Evas_Object *obj,
1305 Elm_Object_Item *before,
1312 ELM_INDEX_CHECK(obj) NULL;
1313 ELM_INDEX_DATA_GET(obj, sd);
1315 if (!before) return elm_index_item_prepend(obj, letter, func, data);
1317 it = _item_new(obj, letter, func, data);
1318 if (!it) return NULL;
1320 sd->items = eina_list_prepend_relative(sd->items, it, before);
1321 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1323 return (Elm_Object_Item *)it;
1326 EAPI Elm_Object_Item *
1327 elm_index_item_sorted_insert(Evas_Object *obj,
1331 Eina_Compare_Cb cmp_func,
1332 Eina_Compare_Cb cmp_data_func)
1338 ELM_INDEX_CHECK(obj) NULL;
1339 ELM_INDEX_DATA_GET(obj, sd);
1341 if (!(sd->items)) return elm_index_item_append(obj, letter, func, data);
1343 it = _item_new(obj, letter, func, data);
1344 if (!it) return NULL;
1346 lnear = eina_list_search_sorted_near_list(sd->items, cmp_func, it, &cmp);
1348 sd->items = eina_list_append_relative_list(sd->items, it, lnear);
1350 sd->items = eina_list_prepend_relative_list(sd->items, it, lnear);
1353 /* If cmp_data_func is not provided, append a duplicated item */
1355 sd->items = eina_list_append_relative_list(sd->items, it, lnear);
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;
1362 elm_widget_item_del(it);
1366 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1368 if (!it) return NULL;
1369 return (Elm_Object_Item *)it;
1372 EAPI Elm_Object_Item *
1373 elm_index_item_find(Evas_Object *obj,
1376 ELM_INDEX_CHECK(obj) NULL;
1378 return (Elm_Object_Item *)_item_find(obj, data);
1382 elm_index_item_clear(Evas_Object *obj)
1385 Eina_List *l, *clear = NULL;
1387 ELM_INDEX_CHECK(obj);
1388 ELM_INDEX_DATA_GET(obj, sd);
1390 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1391 EINA_LIST_FOREACH(sd->items, l, it)
1393 if (it->level != sd->level) continue;
1394 clear = eina_list_append(clear, it);
1396 EINA_LIST_FREE (clear, it)
1399 elm_widget_item_del(it);
1404 elm_index_level_go(Evas_Object *obj,
1405 int level __UNUSED__)
1407 ELM_INDEX_CHECK(obj);
1408 ELM_INDEX_DATA_GET(obj, sd);
1410 _index_box_auto_fill(obj, sd->bx[0], 0);
1411 if (sd->level == 1) _index_box_auto_fill(obj, sd->bx[1], 1);
1415 elm_index_indicator_disabled_set(Evas_Object *obj,
1418 ELM_INDEX_CHECK(obj);
1419 ELM_INDEX_DATA_GET(obj, sd);
1421 disabled = !!disabled;
1422 if (sd->indicator_disabled == disabled) return;
1423 sd->indicator_disabled = disabled;
1424 if (!sd->items) return;
1426 elm_layout_signal_emit(obj, "elm,indicator,state,inactive", "elm");
1428 elm_layout_signal_emit(obj, "elm,indicator,state,active", "elm");
1432 elm_index_indicator_disabled_get(const Evas_Object *obj)
1434 ELM_INDEX_CHECK(obj) EINA_FALSE;
1435 ELM_INDEX_DATA_GET(obj, sd);
1437 return sd->indicator_disabled;
1441 elm_index_item_letter_get(const Elm_Object_Item *it)
1443 ELM_INDEX_ITEM_CHECK_OR_RETURN(it, NULL);
1445 return ((Elm_Index_Item *)it)->letter;
1449 elm_index_horizontal_set(Evas_Object *obj,
1450 Eina_Bool horizontal)
1452 ELM_INDEX_CHECK(obj);
1453 ELM_INDEX_DATA_GET(obj, sd);
1455 horizontal = !!horizontal;
1456 if (horizontal == sd->horizontal) return;
1458 sd->horizontal = horizontal;
1459 _elm_index_smart_theme(obj);
1463 elm_index_horizontal_get(const Evas_Object *obj)
1465 ELM_INDEX_CHECK(obj) EINA_FALSE;
1466 ELM_INDEX_DATA_GET(obj, sd);
1468 return sd->horizontal;