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,
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 evas_object_smart_calculate(box);
84 sd->level_active[level] = 0;
88 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
90 const char *txt = NULL;
92 Elm_Index_Item *it = (Elm_Index_Item *)data;
93 ELM_INDEX_ITEM_CHECK_OR_RETURN(it, NULL);
95 txt = elm_widget_access_info_get(obj);
96 if (!txt) txt = it->letter;
97 if (txt) return strdup(txt);
103 _access_widget_item_activate_cb(void *data __UNUSED__,
104 Evas_Object *part_obj __UNUSED__,
107 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
111 _access_widget_item_register(Elm_Index_Item *it)
115 _elm_access_widget_item_register((Elm_Widget_Item *)it);
117 ai = _elm_access_object_get(it->base.access_obj);
119 _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("Index Item"));
120 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
121 _elm_access_activate_callback_set
122 (ai, _access_widget_item_activate_cb, NULL);
126 _omit_calc(void *data, int num_of_items, int max_num_of_items)
128 Elm_Index_Smart_Data *sd = data;
129 int max_group_num, num_of_extra_items, i, g, size, sum, start;
130 int *group_pos, *omit_info;
133 if ((max_num_of_items < 3) || (num_of_items <= max_num_of_items)) return;
135 if (sd->group_num > 0)
136 start = sd->show_group + sd->default_num;
138 max_group_num = (max_num_of_items - 1) / 2;
139 num_of_extra_items = num_of_items - max_num_of_items;
141 group_pos = (int *)malloc(sizeof(int) * max_group_num);
142 omit_info = (int *)malloc(sizeof(int) * max_num_of_items);
144 if (num_of_extra_items >= max_group_num)
147 for (i = 0; i < max_group_num; i++)
155 size = max_num_of_items / (num_of_extra_items + 1);
157 for (i = 0; i < num_of_extra_items; i++)
163 for (i = 0; i < max_num_of_items; i++)
165 for (i = 0; i < num_of_extra_items; i++)
166 omit_info[group_pos[i % max_group_num]]++;
169 for (i = 0; i < max_num_of_items; i++)
171 if (omit_info[i] > 1)
173 o = (Elm_Index_Omit *)malloc(sizeof(Elm_Index_Omit));
174 o->offset = sum + start;
175 o->count = omit_info[i];
176 sd->omit = eina_list_append(sd->omit, o);
185 // FIXME: always have index filled
187 _index_box_auto_fill(Evas_Object *obj,
191 int i = 0, max_num_of_items = 0, num_of_items = 0, g = 0, skip = 0;
194 Elm_Index_Item *it, *head = NULL, *last_it = NULL, *next_it = NULL;
195 Evas_Coord mw, mh, ih;
199 ELM_INDEX_DATA_GET(obj, sd);
201 if (sd->level_active[level]) return;
203 edje_object_part_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.index.0", NULL, NULL, NULL, &ih);
205 rtl = elm_widget_mirrored_get(obj);
207 EINA_LIST_FREE(sd->omit, om)
210 EINA_LIST_FOREACH(sd->items, l, it)
213 it->omitted = eina_list_free(it->omitted);
214 if (it->head) it->head = NULL;
217 if (sd->omit_enabled)
219 o = edje_object_add(evas_object_evas_get(obj));
220 elm_widget_theme_object_set
221 (obj, o, "index", "item/vertical",
222 elm_widget_style_get(obj));
224 edje_object_size_min_restricted_calc(o, NULL, &mh, 0, 0);
226 EINA_LIST_FOREACH(sd->items, l, it)
227 if (it->level == level && it->priority == sd->show_group)
231 max_num_of_items = ih / mh;
233 max_num_of_items -= (sd->group_num + sd->default_num - 1);
235 _omit_calc(sd, num_of_items, max_num_of_items);
238 om = eina_list_nth(sd->omit, g);
239 EINA_LIST_FOREACH(sd->items, l, it)
241 const char *stacking;
243 if (it->level != level) continue;
245 /** when index has more than one group,
246 * one group is shown completely and other groups are represented by one item
248 if (it->priority != -1)
250 // for groups of higher priority, the first item represents the group
251 if (it->priority < sd->show_group)
253 if (last_it && (last_it->priority == it->priority)) continue;
255 // for groups of lower priority, the last item represents the group
256 else if (it->priority > sd->show_group)
258 l = eina_list_next(l);
261 next_it = eina_list_data_get(l);
262 l = eina_list_prev(l);
263 if (next_it->priority == it->priority) continue;
268 if ((om) && (i == om->offset))
274 head->omitted = eina_list_append(head->omitted, it);
275 om = eina_list_nth(sd->omit, ++g);
284 head->omitted = eina_list_append(head->omitted, it);
289 o = edje_object_add(evas_object_evas_get(obj));
291 edje_object_mirrored_set(VIEW(it), rtl);
296 elm_widget_theme_object_set
297 (obj, o, "index", "item_odd/horizontal",
298 elm_widget_style_get(obj));
300 elm_widget_theme_object_set
301 (obj, o, "index", "item/horizontal",
302 elm_widget_style_get(obj));
307 elm_widget_theme_object_set
308 (obj, o, "index", "item_odd/vertical",
309 elm_widget_style_get(obj));
311 elm_widget_theme_object_set
312 (obj, o, "index", "item/vertical",
313 elm_widget_style_get(obj));
317 edje_object_part_text_escaped_set(o, "elm.text", "*");
319 edje_object_part_text_escaped_set(o, "elm.text", it->letter);
320 edje_object_size_min_restricted_calc(o, &mw, &mh, 0, 0);
321 evas_object_size_hint_min_set(o, mw, mh);
322 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
323 evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
324 elm_widget_sub_object_add(obj, o);
325 evas_object_box_append(box, o);
326 stacking = edje_object_data_get(o, "stacking");
330 if (!strcmp(stacking, "below")) evas_object_lower(o);
331 else if (!strcmp(stacking, "above"))
332 evas_object_raise(o);
340 if ((it->level == 0) && (_elm_config->access_mode))
341 _access_widget_item_register(it);
346 // TIZEN ONLY adjust the last item's theme according to winset gui
348 edje_object_signal_emit(VIEW(last_it), "elm,last,item", "elm");
351 evas_object_smart_calculate(box);
352 sd->level_active[level] = 1;
356 _priority_change_job(void *data)
358 ELM_INDEX_DATA_GET(data, sd);
359 Elm_Object_Item *selected_it;
361 sd->priority_change = NULL;
362 sd->show_group = sd->next_group;
363 _index_box_clear(data, sd->bx[0], 0);
364 _index_box_auto_fill(data, sd->bx[0], 0);
366 selected_it = elm_index_selected_item_get(data, sd->level);
367 if (selected_it) elm_index_item_selected_set(selected_it, EINA_FALSE);
371 _priority_up_cb(void *data)
373 _priority_change_job(data);
374 elm_layout_signal_emit(data, "elm,priority,up", "elm");
376 return ECORE_CALLBACK_CANCEL;
380 _priority_down_cb(void *data)
382 _priority_change_job(data);
383 elm_layout_signal_emit(data, "elm,priority,down", "elm");
385 return ECORE_CALLBACK_CANCEL;
389 _index_priority_change(void *data, Elm_Index_Item *it)
391 ELM_INDEX_DATA_GET(data, sd);
393 if (sd->priority_change)
395 ecore_timer_del(sd->priority_change);
396 sd->priority_change = NULL;
399 if ((it->priority != -1) && (it->priority != sd->show_group))
401 sd->next_group = it->priority;
402 if (it->priority < sd->show_group)
403 sd->priority_change = ecore_timer_add(0.3, _priority_up_cb, data);
405 sd->priority_change = ecore_timer_add(0.3, _priority_down_cb, data);
410 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
412 ELM_INDEX_DATA_GET(obj, sd);
415 edje_object_mirrored_set(ELM_WIDGET_DATA(sd)->resize_obj, rtl);
419 _access_activate_cb(void *data,
420 Evas_Object *part_obj __UNUSED__,
421 Elm_Object_Item *item __UNUSED__)
424 ELM_INDEX_DATA_GET(data, sd);
426 it = eina_list_nth(sd->items, 0);
427 _elm_access_highlight_set(it->base.access_obj, EINA_FALSE);
428 sd->index_focus = EINA_TRUE;
432 _access_index_register(Evas_Object *obj)
436 elm_widget_can_focus_set(obj, EINA_TRUE);
438 ao = _elm_access_edje_object_part_object_register
439 (obj, elm_layout_edje_get(obj), "access");
440 ai = _elm_access_object_get(ao);
443 (ai, ELM_ACCESS_TYPE, E_("Index"));
444 _elm_access_activate_callback_set
445 (ai, _access_activate_cb, obj);
449 _elm_index_smart_theme(Evas_Object *obj)
451 Evas_Coord minw = 0, minh = 0;
454 ELM_INDEX_DATA_GET(obj, sd);
456 _index_box_clear(obj, sd->bx[0], 0);
457 _index_box_clear(obj, sd->bx[1], 1);
460 eina_stringshare_replace(&ELM_LAYOUT_DATA(sd)->group, "base/horizontal");
463 eina_stringshare_replace(&ELM_LAYOUT_DATA(sd)->group, "base/vertical");
464 _mirrored_set(obj, elm_widget_mirrored_get(obj));
467 if (!ELM_WIDGET_CLASS(_elm_index_parent_sc)->theme(obj)) return EINA_FALSE;
469 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
470 evas_object_size_hint_min_set(sd->event[0], minw, minh);
472 if (edje_object_part_exists
473 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.index.1"))
477 sd->bx[1] = evas_object_box_add(evas_object_evas_get(obj));
478 evas_object_box_layout_set
479 (sd->bx[1], _box_custom_layout, sd, NULL);
480 elm_widget_sub_object_add(obj, sd->bx[1]);
482 elm_layout_content_set(obj, "elm.swallow.index.1", sd->bx[1]);
486 evas_object_del(sd->bx[1]);
489 if (edje_object_part_exists
490 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.event.1"))
495 evas_object_rectangle_add(evas_object_evas_get(obj));
496 evas_object_color_set(sd->event[1], 0, 0, 0, 0);
497 elm_widget_sub_object_add(obj, sd->event[1]);
499 elm_layout_content_set(obj, "elm.swallow.event.1", sd->event[1]);
500 evas_object_size_hint_min_set(sd->event[1], minw, minh);
502 else if (sd->event[1])
504 evas_object_del(sd->event[1]);
507 edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
509 elm_layout_sizing_eval(obj);
510 _index_box_auto_fill(obj, sd->bx[0], 0);
512 if (sd->autohide_disabled)
514 if (sd->level == 1) _index_box_auto_fill(obj, sd->bx[1], 1);
515 elm_layout_signal_emit(obj, "elm,state,active", "elm");
517 else elm_layout_signal_emit(obj, "elm,state,inactive", "elm");
519 it = (Elm_Index_Item *)elm_index_selected_item_get(obj, sd->level);
523 edje_object_signal_emit(VIEW(it->head), "elm,state,active", "elm");
525 edje_object_signal_emit(VIEW(it), "elm,state,active", "elm");
529 if (_elm_config->access_mode)
531 elm_index_autohide_disabled_set(obj, EINA_TRUE);
532 elm_layout_signal_emit(obj, "elm,access,state,active", "elm");
533 _access_index_register(obj);
540 _elm_index_smart_sizing_eval(Evas_Object *obj)
542 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
544 ELM_INDEX_DATA_GET(obj, sd);
546 edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
547 evas_object_size_hint_min_set(obj, minw, minh);
548 evas_object_size_hint_max_set(obj, maxw, maxh);
552 _item_del_pre_hook(Elm_Object_Item *it)
554 ELM_INDEX_DATA_GET(WIDGET(it), sd);
556 _item_free((Elm_Index_Item *)it);
557 _index_box_clear(WIDGET(it), sd->bx[sd->level], sd->level);
562 static Elm_Index_Item *
563 _item_new(Evas_Object *obj,
570 ELM_INDEX_DATA_GET(obj, sd);
572 it = elm_widget_item_new(obj, Elm_Index_Item);
573 if (!it) return NULL;
575 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
576 if (letter) it->letter = eina_stringshare_add(letter);
578 it->base.data = data;
579 it->level = sd->level;
585 static Elm_Index_Item *
586 _item_find(Evas_Object *obj,
592 ELM_INDEX_DATA_GET(obj, sd);
594 EINA_LIST_FOREACH(sd->items, l, it)
595 if (it->base.data == data) return it;
601 _delay_change_cb(void *data)
603 Elm_Object_Item *item;
605 ELM_INDEX_DATA_GET(data, sd);
608 item = elm_index_selected_item_get(data, sd->level);
611 evas_object_smart_callback_call(data, SIG_DELAY_CHANGED, item);
612 _index_priority_change(data, (Elm_Index_Item *)item);
615 return ECORE_CALLBACK_CANCEL;
619 _sel_eval(Evas_Object *obj,
623 Evas_Coord x, y, w, h, bx, by, bw, bh, xx, yy;
624 Elm_Index_Item *it, *it_closest, *it_last, *om_closest;
625 char *label = NULL, *last = NULL;
629 int i, j, size, dh, dx, dy;
631 ELM_INDEX_DATA_GET(obj, sd);
633 for (i = 0; i <= sd->level; i++)
639 evas_object_geometry_get(sd->bx[i], &bx, &by, &bw, &bh);
641 EINA_LIST_FOREACH(sd->items, l, it)
643 if (it->level != i) continue;
644 if (it->level != sd->level)
660 evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
665 x = (x * x) + (y * y);
666 if ((x < dist) || (!it_closest))
669 cdv = (double)(xx - bx) / (double)bw;
671 cdv = (double)(yy - by) / (double)bh;
677 if ((i == 0) && (sd->level == 0))
678 edje_object_part_drag_value_set
679 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.index.1", cdv, cdv);
681 if (it_closest && it_closest->omitted)
684 size = eina_list_count(it->omitted);
685 evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
689 printf("too many index items to omit\n"); //FIXME
692 for (j = 0; j < size; j++)
695 yy = y + (dh * j) + (dh / 2);
698 dx = (dx * dx) + (dy * dy);
699 if ((dx < dist) || (!om_closest))
701 om_closest = eina_list_nth(it->omitted, j);
708 if (om_closest) om_closest->selected = 1;
709 else if (it_closest) it_closest->selected = 1;
711 if (it_closest != it_last)
715 const char *stacking, *selectraise;
720 if (it->head != it_closest) it = it->head;
725 edje_object_signal_emit
726 (VIEW(it), "elm,state,inactive", "elm");
727 stacking = edje_object_data_get(VIEW(it), "stacking");
728 selectraise = edje_object_data_get(VIEW(it), "selectraise");
729 if ((selectraise) && (!strcmp(selectraise, "on")))
731 if ((stacking) && (!strcmp(stacking, "below")))
732 evas_object_lower(VIEW(it));
738 const char *selectraise;
742 if (!((it_last) && (it_last->head) && (it_last->head == it_closest)))
744 edje_object_signal_emit(VIEW(it), "elm,state,active", "elm");
745 selectraise = edje_object_data_get(VIEW(it), "selectraise");
746 if ((selectraise) && (!strcmp(selectraise, "on")))
747 evas_object_raise(VIEW(it));
751 evas_object_smart_callback_call
752 (obj, SIG_CHANGED, om_closest);
754 evas_object_smart_callback_call
755 (obj, SIG_CHANGED, it);
756 if (sd->delay) ecore_timer_del(sd->delay);
757 sd->delay = ecore_timer_add(sd->delay_change_time,
758 _delay_change_cb, obj);
763 if (om_closest) it = om_closest;
764 else it = it_closest;
765 if (!last && it->letter) last = strdup(it->letter);
768 if (!label && last) label = strdup(last);
773 label = realloc(label, strlen(label) +
780 if (it->letter) last = strdup(it->letter);
784 if (!label) label = strdup("");
785 if (!last) last = strdup("");
787 elm_layout_text_set(obj, "elm.text.body", label);
788 elm_layout_text_set(obj, "elm.text", last);
795 _on_mouse_wheel(void *data __UNUSED__,
797 Evas_Object *o __UNUSED__,
798 void *event_info __UNUSED__)
803 _on_mouse_down(void *data,
805 Evas_Object *o __UNUSED__,
808 Evas_Event_Mouse_Down *ev = event_info;
811 ELM_INDEX_DATA_GET(data, sd);
813 if (ev->button != 1) return;
815 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, &x, &y, &w, NULL);
816 sd->dx = ev->canvas.x - x;
817 sd->dy = ev->canvas.y - y;
818 if (!sd->autohide_disabled)
820 _index_box_clear(data, sd->bx[1], 1);
821 elm_layout_signal_emit(data, "elm,state,active", "elm");
823 _sel_eval(data, ev->canvas.x, ev->canvas.y);
824 edje_object_part_drag_value_set
825 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.pointer",
826 (!elm_object_mirrored_get(data)) ? sd->dx : (sd->dx - w), sd->dy);
827 if (sd->items && !sd->indicator_disabled)
828 elm_layout_signal_emit(data, "elm,indicator,state,active", "elm");
832 _on_mouse_up(void *data,
834 Evas_Object *o __UNUSED__,
837 Evas_Event_Mouse_Up *ev = event_info;
838 Elm_Object_Item *item;
839 Elm_Index_Item *id_item;
841 ELM_INDEX_DATA_GET(data, sd);
843 if (ev->button != 1) return;
845 item = elm_index_selected_item_get(data, sd->level);
848 evas_object_smart_callback_call(data, SIG_SELECTED, item);
849 id_item = (Elm_Index_Item *)item;
851 id_item->func((void *)id_item->base.data, WIDGET(id_item), id_item);
853 if (!sd->autohide_disabled)
854 elm_layout_signal_emit(data, "elm,state,inactive", "elm");
856 elm_layout_signal_emit(data, "elm,state,level,0", "elm");
857 if (sd->items && !sd->indicator_disabled)
858 elm_layout_signal_emit(data, "elm,indicator,state,inactive", "elm");
862 _on_mouse_move(void *data,
864 Evas_Object *o __UNUSED__,
867 Evas_Event_Mouse_Move *ev = event_info;
868 Evas_Coord minw = 0, minh = 0, x, y, dx, adx, w;
871 ELM_INDEX_DATA_GET(data, sd);
873 if (!sd->down) return;
874 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
875 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, &x, &y, &w, NULL);
876 x = ev->cur.canvas.x - x;
877 y = ev->cur.canvas.y - y;
880 if (adx < 0) adx = -dx;
881 edje_object_part_drag_value_set
882 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.pointer",
883 (!edje_object_mirrored_get(ELM_WIDGET_DATA(sd)->resize_obj)) ?
892 snprintf(buf, sizeof(buf), "elm,state,level,%i", sd->level);
893 elm_layout_signal_emit(data, buf, "elm");
894 evas_object_smart_callback_call(data, SIG_LEVEL_UP, NULL);
902 snprintf(buf, sizeof(buf), "elm,state,level,%i", sd->level);
903 elm_layout_signal_emit(data, buf, "elm");
904 evas_object_smart_callback_call(data, SIG_LEVEL_DOWN, NULL);
908 _sel_eval(data, ev->cur.canvas.x, ev->cur.canvas.y);
912 _index_resize_cb(void *data,
914 Evas_Object *obj __UNUSED__,
915 void *event_info __UNUSED__)
917 ELM_INDEX_DATA_GET_OR_RETURN(data, sd);
919 if (!sd->omit_enabled) return;
923 _index_box_clear(data, sd->bx[0], 0);
924 _index_box_auto_fill(data, sd->bx[0], 0);
926 it = (Elm_Index_Item *)elm_index_selected_item_get(obj, sd->level);
930 edje_object_signal_emit(VIEW(it->head), "elm,state,active", "elm");
932 edje_object_signal_emit(VIEW(it), "elm,state,active", "elm");
937 _elm_index_smart_add(Evas_Object *obj)
940 Evas_Coord minw, minh;
942 EVAS_SMART_DATA_ALLOC(obj, Elm_Index_Smart_Data);
944 ELM_WIDGET_CLASS(_elm_index_parent_sc)->base.add(obj);
947 (obj, "index", "base/vertical", elm_widget_style_get(obj));
949 o = evas_object_rectangle_add(evas_object_evas_get(obj));
951 evas_object_color_set(o, 0, 0, 0, 0);
953 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
954 evas_object_size_hint_min_set(o, minw, minh);
955 elm_layout_content_set(obj, "elm.swallow.event.0", o);
956 elm_widget_sub_object_add(obj, o);
958 evas_object_event_callback_add
959 (obj, EVAS_CALLBACK_RESIZE, _index_resize_cb, obj);
960 evas_object_event_callback_add
961 (o, EVAS_CALLBACK_MOUSE_WHEEL, _on_mouse_wheel, obj);
962 evas_object_event_callback_add
963 (o, EVAS_CALLBACK_MOUSE_DOWN, _on_mouse_down, obj);
964 evas_object_event_callback_add
965 (o, EVAS_CALLBACK_MOUSE_UP, _on_mouse_up, obj);
966 evas_object_event_callback_add
967 (o, EVAS_CALLBACK_MOUSE_MOVE, _on_mouse_move, obj);
969 if (edje_object_part_exists
970 (ELM_WIDGET_DATA(priv)->resize_obj, "elm.swallow.event.1"))
972 o = evas_object_rectangle_add(evas_object_evas_get(obj));
974 evas_object_color_set(o, 0, 0, 0, 0);
975 evas_object_size_hint_min_set(o, minw, minh);
976 elm_layout_content_set(obj, "elm.swallow.event.1", o);
977 elm_widget_sub_object_add(obj, o);
980 priv->bx[0] = evas_object_box_add(evas_object_evas_get(obj));
981 evas_object_box_layout_set(priv->bx[0], _box_custom_layout, priv, NULL);
982 elm_widget_sub_object_add(obj, priv->bx[0]);
983 elm_layout_content_set(obj, "elm.swallow.index.0", priv->bx[0]);
984 evas_object_show(priv->bx[0]);
986 priv->delay_change_time = INDEX_DELAY_CHANGE_TIME;
987 priv->omit_enabled = 1;
989 if (edje_object_part_exists
990 (ELM_WIDGET_DATA(priv)->resize_obj, "elm.swallow.index.1"))
992 priv->bx[1] = evas_object_box_add(evas_object_evas_get(obj));
993 evas_object_box_layout_set
994 (priv->bx[1], _box_custom_layout, priv, NULL);
995 elm_widget_sub_object_add(obj, priv->bx[1]);
996 elm_layout_content_set(obj, "elm.swallow.index.1", priv->bx[1]);
997 evas_object_show(priv->bx[1]);
1000 _mirrored_set(obj, elm_widget_mirrored_get(obj));
1001 elm_layout_sizing_eval(obj);
1002 elm_widget_can_focus_set(obj, EINA_FALSE);
1005 if (_elm_config->access_mode)
1007 elm_index_autohide_disabled_set(obj, EINA_TRUE);
1008 elm_layout_signal_emit(obj, "elm,access,state,active", "elm");
1009 _access_index_register(obj);
1014 _elm_index_smart_del(Evas_Object *obj)
1019 ELM_INDEX_DATA_GET(obj, sd);
1023 it = sd->items->data;
1024 elm_widget_item_del(it);
1027 EINA_LIST_FREE(sd->omit, o)
1030 if (sd->delay) ecore_timer_del(sd->delay);
1032 ELM_WIDGET_CLASS(_elm_index_parent_sc)->base.del(obj);
1036 _elm_index_smart_focus_next(const Evas_Object *obj,
1037 Elm_Focus_Direction dir,
1040 Eina_List *items = NULL;
1041 Eina_List *l = NULL;
1047 ELM_INDEX_CHECK(obj) EINA_FALSE;
1048 ELM_INDEX_DATA_GET(obj, sd);
1050 if (!sd->autohide_disabled)
1051 elm_layout_signal_emit((Evas_Object *)obj, "elm,state,active", "elm");
1053 po = (Evas_Object *)edje_object_part_object_get
1054 (elm_layout_edje_get(obj), "access");
1055 ao = evas_object_data_get(po, "_part_access_obj");
1056 items = eina_list_append(items, ao);
1058 if (sd->index_focus)
1060 EINA_LIST_FOREACH(sd->items, l, it)
1062 if (it->level != 0) continue;
1063 items = eina_list_append(items, it->base.access_obj);
1067 ret = elm_widget_focus_list_next_get
1068 (obj, items, eina_list_data_get, dir, next);
1072 sd->index_focus = EINA_FALSE;
1074 Evas_Object *it_access_obj = eina_list_nth(items, eina_list_count(items) - 1);
1076 items = eina_list_free(items);
1077 items = eina_list_append(items, it_access_obj);
1078 items = eina_list_append(items, ao);
1080 ret = elm_widget_focus_list_next_get(obj, items, eina_list_data_get, dir, next);
1082 // to hide index item, if there is nothing to focus on autohide disalbe mode
1083 if (!sd->autohide_disabled)
1084 elm_layout_signal_emit((Evas_Object *)obj, "elm,state,inactive", "elm");
1091 _access_obj_process(Evas_Object *obj, Eina_Bool is_access)
1096 ELM_INDEX_DATA_GET(obj, sd);
1098 EINA_LIST_FOREACH(sd->items, l, it)
1100 if (it->level != 0) continue;
1101 if (is_access) _access_widget_item_register(it);
1102 else _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
1107 elm_index_autohide_disabled_set(obj, EINA_TRUE);
1108 elm_layout_signal_emit(obj, "elm,access,state,active", "elm");
1109 _access_index_register(obj);
1113 // opposition of _access_index_register();
1114 if (!sd->autohide_disabled)
1115 elm_index_autohide_disabled_set(obj, EINA_FALSE);
1116 elm_layout_signal_emit(obj, "elm,access,state,inactive", "elm");
1117 elm_widget_can_focus_set(obj, EINA_FALSE);
1118 _elm_access_edje_object_part_object_unregister
1119 (obj, elm_layout_edje_get(obj), "access");
1124 _access_hook(Evas_Object *obj, Eina_Bool is_access)
1126 ELM_INDEX_CHECK(obj);
1127 ELM_INDEX_DATA_GET(obj, sd);
1130 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
1131 _elm_index_smart_focus_next;
1133 ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
1134 _access_obj_process(obj, is_access);
1138 _elm_index_smart_set_user(Elm_Index_Smart_Class *sc)
1140 ELM_WIDGET_CLASS(sc)->base.add = _elm_index_smart_add;
1141 ELM_WIDGET_CLASS(sc)->base.del = _elm_index_smart_del;
1143 ELM_WIDGET_CLASS(sc)->theme = _elm_index_smart_theme;
1144 ELM_WIDGET_CLASS(sc)->translate = _elm_index_smart_translate;
1146 /* not a 'focus chain manager' */
1147 ELM_WIDGET_CLASS(sc)->focus_next = NULL;
1148 ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
1150 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_index_smart_sizing_eval;
1152 if (_elm_config->access_mode)
1153 ELM_WIDGET_CLASS(sc)->focus_next = _elm_index_smart_focus_next;
1155 ELM_WIDGET_CLASS(sc)->access = _access_hook;
1158 EAPI const Elm_Index_Smart_Class *
1159 elm_index_smart_class_get(void)
1161 static Elm_Index_Smart_Class _sc =
1162 ELM_INDEX_SMART_CLASS_INIT_NAME_VERSION(ELM_INDEX_SMART_NAME);
1163 static const Elm_Index_Smart_Class *class = NULL;
1164 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
1169 _elm_index_smart_set(&_sc);
1170 esc->callbacks = _smart_callbacks;
1177 elm_index_add(Evas_Object *parent)
1181 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
1183 obj = elm_widget_add(_elm_index_smart_class_new(), parent);
1184 if (!obj) return NULL;
1186 if (!elm_widget_sub_object_add(parent, obj))
1187 ERR("could not add %p as sub object of %p", obj, parent);
1193 elm_index_autohide_disabled_set(Evas_Object *obj,
1196 ELM_INDEX_CHECK(obj);
1197 ELM_INDEX_DATA_GET(obj, sd);
1199 disabled = !!disabled;
1200 if (sd->autohide_disabled == disabled) return;
1201 sd->autohide_disabled = disabled;
1203 if (sd->autohide_disabled)
1205 _index_box_clear(obj, sd->bx[1], 1);
1206 elm_layout_signal_emit(obj, "elm,state,active", "elm");
1209 elm_layout_signal_emit(obj, "elm,state,inactive", "elm");
1211 //FIXME: Should be update indicator based on the indicator visiblility
1215 elm_index_autohide_disabled_get(const Evas_Object *obj)
1217 ELM_INDEX_CHECK(obj) EINA_FALSE;
1218 ELM_INDEX_DATA_GET(obj, sd);
1220 return sd->autohide_disabled;
1224 elm_index_item_level_set(Evas_Object *obj,
1227 ELM_INDEX_CHECK(obj);
1228 ELM_INDEX_DATA_GET(obj, sd);
1230 if (sd->level == level) return;
1235 elm_index_item_level_get(const Evas_Object *obj)
1237 ELM_INDEX_CHECK(obj) 0;
1238 ELM_INDEX_DATA_GET(obj, sd);
1243 //FIXME: Should update indicator based on the autohidden status & indicator visiblility
1245 elm_index_item_selected_set(Elm_Object_Item *it,
1248 Elm_Index_Item *it_sel, *it_last;
1249 Evas_Object *obj = WIDGET(it);
1251 ELM_INDEX_ITEM_CHECK_OR_RETURN(it);
1252 ELM_INDEX_DATA_GET(obj, sd);
1254 selected = !!selected;
1255 it_sel = (Elm_Index_Item *)it;
1256 if (it_sel->selected == selected) return;
1260 it_last = (Elm_Index_Item *)elm_index_selected_item_get(obj, sd->level);
1264 it_last->selected = 0;
1266 edje_object_signal_emit(VIEW(it_last->head), "elm,state,inactive", "elm");
1268 edje_object_signal_emit(VIEW(it_last), "elm,state,inactive", "elm");
1270 it_sel->selected = 1;
1272 edje_object_signal_emit(VIEW(it_sel->head), "elm,state,active", "elm");
1274 edje_object_signal_emit(VIEW(it_sel), "elm,state,active", "elm");
1276 evas_object_smart_callback_call
1277 (obj, SIG_CHANGED, it);
1278 evas_object_smart_callback_call
1279 (obj, SIG_SELECTED, it);
1280 if (sd->delay) ecore_timer_del(sd->delay);
1281 sd->delay = ecore_timer_add(sd->delay_change_time,
1282 _delay_change_cb, obj);
1286 it_sel->selected = 0;
1288 edje_object_signal_emit(VIEW(it_sel->head), "elm,state,inactive", "elm");
1290 edje_object_signal_emit(VIEW(it_sel), "elm,state,inactive", "elm");
1294 EAPI Elm_Object_Item *
1295 elm_index_selected_item_get(const Evas_Object *obj,
1301 ELM_INDEX_CHECK(obj) NULL;
1302 ELM_INDEX_DATA_GET(obj, sd);
1304 EINA_LIST_FOREACH(sd->items, l, it)
1306 if ((it->selected) && (it->level == level))
1307 return (Elm_Object_Item *)it;
1313 EAPI Elm_Object_Item *
1314 elm_index_item_append(Evas_Object *obj,
1321 ELM_INDEX_CHECK(obj) NULL;
1322 ELM_INDEX_DATA_GET(obj, sd);
1324 it = _item_new(obj, letter, func, data);
1325 if (!it) return NULL;
1327 sd->items = eina_list_append(sd->items, it);
1328 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1330 return (Elm_Object_Item *)it;
1333 EAPI Elm_Object_Item *
1334 elm_index_item_prepend(Evas_Object *obj,
1341 ELM_INDEX_CHECK(obj) NULL;
1342 ELM_INDEX_DATA_GET(obj, sd);
1344 it = _item_new(obj, letter, func, data);
1345 if (!it) return NULL;
1347 sd->items = eina_list_prepend(sd->items, it);
1348 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1350 return (Elm_Object_Item *)it;
1353 EINA_DEPRECATED EAPI Elm_Object_Item *
1354 elm_index_item_prepend_relative(Evas_Object *obj,
1357 const Elm_Object_Item *relative)
1359 return elm_index_item_insert_before
1360 (obj, (Elm_Object_Item *)relative, letter, NULL, item);
1363 EAPI Elm_Object_Item *
1364 elm_index_item_insert_after(Evas_Object *obj,
1365 Elm_Object_Item *after,
1372 ELM_INDEX_CHECK(obj) NULL;
1373 ELM_INDEX_DATA_GET(obj, sd);
1375 if (!after) return elm_index_item_append(obj, letter, func, data);
1377 it = _item_new(obj, letter, func, data);
1378 if (!it) return NULL;
1380 sd->items = eina_list_append_relative(sd->items, it, after);
1381 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1383 return (Elm_Object_Item *)it;
1386 EAPI Elm_Object_Item *
1387 elm_index_item_insert_before(Evas_Object *obj,
1388 Elm_Object_Item *before,
1395 ELM_INDEX_CHECK(obj) NULL;
1396 ELM_INDEX_DATA_GET(obj, sd);
1398 if (!before) return elm_index_item_prepend(obj, letter, func, data);
1400 it = _item_new(obj, letter, func, data);
1401 if (!it) return NULL;
1403 sd->items = eina_list_prepend_relative(sd->items, it, before);
1404 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1406 return (Elm_Object_Item *)it;
1409 EAPI Elm_Object_Item *
1410 elm_index_item_sorted_insert(Evas_Object *obj,
1414 Eina_Compare_Cb cmp_func,
1415 Eina_Compare_Cb cmp_data_func)
1421 ELM_INDEX_CHECK(obj) NULL;
1422 ELM_INDEX_DATA_GET(obj, sd);
1424 if (!(sd->items)) return elm_index_item_append(obj, letter, func, data);
1426 it = _item_new(obj, letter, func, data);
1427 if (!it) return NULL;
1429 lnear = eina_list_search_sorted_near_list(sd->items, cmp_func, it, &cmp);
1431 sd->items = eina_list_append_relative_list(sd->items, it, lnear);
1433 sd->items = eina_list_prepend_relative_list(sd->items, it, lnear);
1436 /* If cmp_data_func is not provided, append a duplicated item */
1438 sd->items = eina_list_append_relative_list(sd->items, it, lnear);
1441 Elm_Index_Item *p_it = eina_list_data_get(lnear);
1442 if (cmp_data_func(p_it->base.data, it->base.data) >= 0)
1443 p_it->base.data = it->base.data;
1444 elm_widget_item_del(it);
1448 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1450 if (!it) return NULL;
1451 return (Elm_Object_Item *)it;
1454 EAPI Elm_Object_Item *
1455 elm_index_item_find(Evas_Object *obj,
1458 ELM_INDEX_CHECK(obj) NULL;
1460 return (Elm_Object_Item *)_item_find(obj, data);
1464 elm_index_item_clear(Evas_Object *obj)
1467 Eina_List *l, *clear = NULL;
1469 ELM_INDEX_CHECK(obj);
1470 ELM_INDEX_DATA_GET(obj, sd);
1472 _index_box_clear(obj, sd->bx[sd->level], sd->level);
1473 EINA_LIST_FOREACH(sd->items, l, it)
1475 if (it->level != sd->level) continue;
1476 clear = eina_list_append(clear, it);
1478 EINA_LIST_FREE (clear, it)
1479 elm_widget_item_del(it);
1483 _sort_cb(const void *d1, const void *d2)
1485 Elm_Index_Item *it1 = d1, *it2 = d2;
1486 if (it1->priority <= it2->priority) return -1;
1491 elm_index_level_go(Evas_Object *obj,
1492 int level __UNUSED__)
1494 ELM_INDEX_CHECK(obj);
1495 ELM_INDEX_DATA_GET(obj, sd);
1501 sd->items = eina_list_sort(sd->items, 0, EINA_COMPARE_CB(_sort_cb));
1503 sd->default_num = 0;
1505 sd->show_group = -1;
1507 EINA_LIST_FOREACH(sd->items, l, it)
1509 if (it->priority == -1) sd->default_num++;
1510 if (it->priority != prev)
1512 if (prev == -1) sd->show_group = it->priority;
1514 prev = it->priority;
1518 _index_box_clear(obj, sd->bx[0], 0);
1519 _index_box_auto_fill(obj, sd->bx[0], 0);
1522 _index_box_clear(obj, sd->bx[1], 1);
1523 _index_box_auto_fill(obj, sd->bx[1], 1);
1528 elm_index_indicator_disabled_set(Evas_Object *obj,
1531 ELM_INDEX_CHECK(obj);
1532 ELM_INDEX_DATA_GET(obj, sd);
1534 disabled = !!disabled;
1535 if (sd->indicator_disabled == disabled) return;
1536 sd->indicator_disabled = disabled;
1537 if (!sd->items) return;
1539 elm_layout_signal_emit(obj, "elm,indicator,state,inactive", "elm");
1541 elm_layout_signal_emit(obj, "elm,indicator,state,active", "elm");
1545 elm_index_indicator_disabled_get(const Evas_Object *obj)
1547 ELM_INDEX_CHECK(obj) EINA_FALSE;
1548 ELM_INDEX_DATA_GET(obj, sd);
1550 return sd->indicator_disabled;
1554 elm_index_item_letter_get(const Elm_Object_Item *it)
1556 ELM_INDEX_ITEM_CHECK_OR_RETURN(it, NULL);
1558 return ((Elm_Index_Item *)it)->letter;
1562 elm_index_horizontal_set(Evas_Object *obj,
1563 Eina_Bool horizontal)
1565 ELM_INDEX_CHECK(obj);
1566 ELM_INDEX_DATA_GET(obj, sd);
1568 horizontal = !!horizontal;
1569 if (horizontal == sd->horizontal) return;
1571 sd->horizontal = horizontal;
1573 sd->omit_enabled = EINA_FALSE;
1574 _elm_index_smart_theme(obj);
1578 elm_index_horizontal_get(const Evas_Object *obj)
1580 ELM_INDEX_CHECK(obj) EINA_FALSE;
1581 ELM_INDEX_DATA_GET(obj, sd);
1583 return sd->horizontal;
1587 elm_index_delay_change_time_set(Evas_Object *obj, double delay_change_time)
1589 ELM_INDEX_CHECK(obj);
1590 ELM_INDEX_DATA_GET(obj, sd);
1592 sd->delay_change_time = delay_change_time;
1596 elm_index_delay_change_time_get(const Evas_Object *obj)
1598 ELM_INDEX_CHECK(obj) 0.0;
1599 ELM_INDEX_DATA_GET(obj, sd);
1601 return sd->delay_change_time;
1605 elm_index_omit_enabled_set(Evas_Object *obj,
1608 ELM_INDEX_CHECK(obj);
1609 ELM_INDEX_DATA_GET(obj, sd);
1611 if (sd->horizontal) return;
1613 enabled = !!enabled;
1614 if (sd->omit_enabled == enabled) return;
1615 sd->omit_enabled = enabled;
1617 _index_box_clear(obj, sd->bx[0], 0);
1618 _index_box_auto_fill(obj, sd->bx[0], 0);
1621 _index_box_clear(obj, sd->bx[1], 1);
1622 _index_box_auto_fill(obj, sd->bx[1], 1);
1627 elm_index_omit_enabled_get(const Evas_Object *obj)
1629 ELM_INDEX_CHECK(obj) EINA_FALSE;
1630 ELM_INDEX_DATA_GET(obj, sd);
1632 return sd->omit_enabled;
1636 elm_index_item_priority_set(Elm_Object_Item *it, int priority)
1638 ELM_INDEX_ITEM_CHECK(it);
1641 WRN("priority value should be greater than or equal to -1.");
1644 ((Elm_Index_Item *)it)->priority = priority;