summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmitesh Singh <amitesh.sh@samsung.com>2014-03-24 00:22:32 +0900
committerDaniel Juyung Seo <seojuyung2@gmail.com>2014-03-24 00:22:32 +0900
commit0a9fe5fb4da5e83551df2dfdee2e90f3fda3facc (patch)
treedf3929216d780335594a78b437195c03591b1894
parent2cf854752f5dd8462609b2766325359286548b62 (diff)
toolbar: implemented widget item focus feature.
Summary: 1. Added "item,focused" and "item,unfocused" smart callbacks. 2. Added _elm_toolbar_focus_highlight_geometry_get(). 3. Implemented elm_object_item_focus_set() and elm_object_item_focus_get(). 4. Implemented elm_object_focused_item_get() 5. Ported _elm_toolbar_nearest_visible_item_get from cc827fef6. 6. Added Test Case "Toolbar Focus". @feature Test Plan: elementary_test->Toolbar Item Focus Reviewers: seoz, woohyun, raster CC: nirajkr, raster Differential Revision: https://phab.enlightenment.org/D555
-rw-r--r--data/themes/edc/elm/toolbar.edc3
-rw-r--r--src/bin/test.c2
-rw-r--r--src/bin/test_toolbar.c169
-rw-r--r--src/lib/elm_toolbar.c372
-rw-r--r--src/lib/elm_toolbar.h4
-rw-r--r--src/lib/elm_widget_toolbar.h5
6 files changed, 513 insertions, 42 deletions
diff --git a/data/themes/edc/elm/toolbar.edc b/data/themes/edc/elm/toolbar.edc
index e3c4d9be6..f0cb0a76e 100644
--- a/data/themes/edc/elm/toolbar.edc
+++ b/data/themes/edc/elm/toolbar.edc
@@ -366,7 +366,8 @@ group { name: "elm/toolbar/base/default";
366// === item: standard default item 366// === item: standard default item
367group { name: "elm/toolbar/item/default"; 367group { name: "elm/toolbar/item/default";
368 data.item: "transition_animation_on" "1"; 368 data.item: "transition_animation_on" "1";
369 369 data.item: "focusraise" "on";
370
370 images.image: "shadow_inset_bevels.png" COMP; 371 images.image: "shadow_inset_bevels.png" COMP;
371 images.image: "shadow_angled_in_sides.png" COMP; 372 images.image: "shadow_angled_in_sides.png" COMP;
372 images.image: "horizontal_separated_bar_small_glow.png" COMP; 373 images.image: "horizontal_separated_bar_small_glow.png" COMP;
diff --git a/src/bin/test.c b/src/bin/test.c
index bc5db8a9b..1dd840c2c 100644
--- a/src/bin/test.c
+++ b/src/bin/test.c
@@ -72,6 +72,7 @@ void test_toolbar6(void *data, Evas_Object *obj, void *event_info);
72void test_toolbar7(void *data, Evas_Object *obj, void *event_info); 72void test_toolbar7(void *data, Evas_Object *obj, void *event_info);
73void test_toolbar8(void *data, Evas_Object *obj, void *event_info); 73void test_toolbar8(void *data, Evas_Object *obj, void *event_info);
74void test_toolbar_vertical(void *data, Evas_Object *obj, void *event_info); 74void test_toolbar_vertical(void *data, Evas_Object *obj, void *event_info);
75void test_toolbar_focus(void *data, Evas_Object *obj, void *event_info);
75void test_hoversel(void *data, Evas_Object *obj, void *event_info); 76void test_hoversel(void *data, Evas_Object *obj, void *event_info);
76void test_hoversel_focus(void *data, Evas_Object *obj, void *event_info); 77void test_hoversel_focus(void *data, Evas_Object *obj, void *event_info);
77void test_list(void *data, Evas_Object *obj, void *event_info); 78void test_list(void *data, Evas_Object *obj, void *event_info);
@@ -610,6 +611,7 @@ add_tests:
610 ADD_TEST(NULL, "Toolbars", "Toolbar 7", test_toolbar7); 611 ADD_TEST(NULL, "Toolbars", "Toolbar 7", test_toolbar7);
611 ADD_TEST(NULL, "Toolbars", "Toolbar 8", test_toolbar8); 612 ADD_TEST(NULL, "Toolbars", "Toolbar 8", test_toolbar8);
612 ADD_TEST(NULL, "Toolbars", "Toolbar Vertical", test_toolbar_vertical); 613 ADD_TEST(NULL, "Toolbars", "Toolbar Vertical", test_toolbar_vertical);
614 ADD_TEST(NULL, "Toolbars", "Toolbar Focus", test_toolbar_focus);
613 615
614 //------------------------------// 616 //------------------------------//
615 ADD_TEST(NULL, "Lists - List", "List", test_list); 617 ADD_TEST(NULL, "Lists - List", "List", test_list);
diff --git a/src/bin/test_toolbar.c b/src/bin/test_toolbar.c
index 433d18819..44723b9b6 100644
--- a/src/bin/test_toolbar.c
+++ b/src/bin/test_toolbar.c
@@ -1047,3 +1047,172 @@ test_toolbar8(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_
1047 evas_object_resize(win, 420, 250); 1047 evas_object_resize(win, 420, 250);
1048 evas_object_show(win); 1048 evas_object_show(win);
1049} 1049}
1050
1051static void
1052_item_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
1053{
1054 printf("%s: %p\n", (char *)data, event_info);
1055}
1056
1057static void
1058_test_toolbar_focus_focus_highlight_check_changed(void *data, Evas_Object *obj,
1059 void *event_info EINA_UNUSED)
1060{
1061 elm_win_focus_highlight_enabled_set(data,
1062 elm_check_state_get(obj));
1063}
1064
1065static void
1066_test_toolbar_focus_focus_animate_check_changed(void *data, Evas_Object *obj,
1067 void *event_info EINA_UNUSED)
1068{
1069 elm_win_focus_highlight_animate_set(data,
1070 elm_check_state_get(obj));
1071}
1072
1073static void
1074_toolbar_focus_key_down_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED,
1075 Evas_Object *obj EINA_UNUSED, void *event_info)
1076{
1077 Evas_Event_Key_Down *ev = event_info;
1078 printf("\n=== Key Down : %s ===\n", ev->keyname);
1079}
1080
1081static Ecore_Timer *timer = NULL;
1082static void
1083_test_toolbar_focus_win_del_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED,
1084 Evas_Object *obj EINA_UNUSED,
1085 void *event_info EINA_UNUSED)
1086{
1087 ecore_timer_del(timer);
1088 timer = NULL;
1089}
1090
1091static Eina_Bool
1092_focus_timer_cb(void *data)
1093{
1094 Elm_Object_Item *it = data;
1095 elm_object_item_focus_set(it, EINA_TRUE);
1096 timer = NULL;
1097
1098 return ECORE_CALLBACK_CANCEL;
1099}
1100
1101static void
1102_test_toolbar_focus_item_set_btn_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
1103 void *event_info EINA_UNUSED)
1104{
1105 ecore_timer_del(timer);
1106 timer = ecore_timer_add(1.5, _focus_timer_cb, data);
1107}
1108
1109void
1110test_toolbar_focus(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
1111{
1112 Evas_Object *win, *bx, *toolbar, *fr, *btn, *bx_opt, *chk;
1113 Elm_Object_Item *tb_it, *it_3;
1114
1115 win = elm_win_util_standard_add("toolbar-focus", "Toolbar Focus");
1116 elm_win_autodel_set(win, EINA_TRUE);
1117 evas_object_event_callback_add(win, EVAS_CALLBACK_DEL,
1118 _test_toolbar_focus_win_del_cb, NULL);
1119 elm_win_focus_highlight_enabled_set(win, EINA_TRUE);
1120 elm_win_focus_highlight_animate_set(win, EINA_TRUE);
1121
1122 bx = elm_box_add(win);
1123 evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1124 elm_win_resize_object_add(win, bx);
1125 evas_object_show(bx);
1126
1127 btn = elm_button_add(win);
1128 elm_object_text_set(btn, "Up");
1129 elm_box_pack_end(bx, btn);
1130 evas_object_show(btn);
1131
1132 toolbar = elm_toolbar_add(win);
1133 elm_toolbar_shrink_mode_set(toolbar, ELM_TOOLBAR_SHRINK_SCROLL);
1134 evas_object_size_hint_align_set(toolbar, EVAS_HINT_FILL, 0.0);
1135 elm_toolbar_item_append(toolbar, "document-print", "Print", NULL, NULL);
1136 elm_toolbar_item_append(toolbar, "folder-new", "Folder", NULL, NULL);
1137 it_3 = elm_toolbar_item_append(toolbar, "clock", "Clock", NULL, NULL);
1138 elm_toolbar_item_append(toolbar, "refresh", "Update", NULL, NULL);
1139 elm_toolbar_item_append(toolbar, "folder-new", "Folder", NULL, NULL);
1140 elm_toolbar_item_append(toolbar, "clock", "Clock", NULL, NULL);
1141 tb_it = elm_toolbar_item_append(toolbar, "document-print", "Print", NULL, NULL);
1142 elm_object_item_disabled_set(tb_it, EINA_TRUE);
1143 elm_toolbar_item_append(toolbar, "folder-new", "Folder", NULL, NULL);
1144 elm_toolbar_item_append(toolbar, "refresh", "Update", NULL, NULL);
1145 elm_toolbar_item_append(toolbar, "folder-new", "Folder", NULL, NULL);
1146 elm_toolbar_item_append(toolbar, "clock", "Clock", NULL, NULL);
1147 elm_toolbar_item_append(toolbar, "document-print", "Print", NULL, NULL);
1148 elm_toolbar_item_append(toolbar, "folder-new", "Folder", NULL, NULL);
1149 elm_toolbar_item_append(toolbar, "refresh", "Update", NULL, NULL);
1150 elm_toolbar_item_append(toolbar, "folder-new", "Folder", NULL, NULL);
1151 elm_box_pack_end(bx, toolbar);
1152 evas_object_show(toolbar);
1153 evas_object_smart_callback_add(toolbar, "clicked", _item_cb, "clicked");
1154 evas_object_smart_callback_add(toolbar, "item,focused", _item_cb, "item,focused");
1155 evas_object_smart_callback_add(toolbar, "item,unfocused", _item_cb, "item,unfcoused");
1156 evas_object_event_callback_add(toolbar, EVAS_CALLBACK_KEY_DOWN, _toolbar_focus_key_down_cb, NULL);
1157
1158 btn = elm_button_add(win);
1159 elm_object_text_set(btn, "Down");
1160 elm_box_pack_end(bx, btn);
1161 evas_object_show(btn);
1162
1163 //Options
1164 fr = elm_frame_add(bx);
1165 elm_object_text_set(fr, "Options");
1166 evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, 0.0);
1167 evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL);
1168 elm_box_pack_end(bx, fr);
1169 evas_object_show(fr);
1170
1171 bx_opt = elm_box_add(fr);
1172 elm_box_horizontal_set(bx_opt, EINA_TRUE);
1173 elm_object_content_set(fr, bx_opt);
1174 evas_object_show(bx_opt);
1175
1176 chk = elm_check_add(bx_opt);
1177 elm_object_text_set(chk, "Focus Highlight");
1178 elm_check_state_set(chk, EINA_TRUE);
1179 evas_object_size_hint_weight_set(chk, EVAS_HINT_EXPAND, 0.0);
1180 elm_box_pack_end(bx_opt, chk);
1181 evas_object_show(chk);
1182 evas_object_smart_callback_add(chk, "changed",
1183 _test_toolbar_focus_focus_highlight_check_changed,
1184 win);
1185
1186 chk = elm_check_add(bx_opt);
1187 elm_object_text_set(chk, "Focus Animation");
1188 elm_check_state_set(chk, EINA_TRUE);
1189 evas_object_size_hint_weight_set(chk, EVAS_HINT_EXPAND, 0.0);
1190 elm_box_pack_end(bx_opt, chk);
1191 evas_object_show(chk);
1192 evas_object_smart_callback_add(chk, "changed",
1193 _test_toolbar_focus_focus_animate_check_changed,
1194 win);
1195 fr = elm_frame_add(bx);
1196 elm_object_text_set(fr, "Focus");
1197 evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, 0.0);
1198 evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL);
1199 elm_box_pack_end(bx, fr);
1200 evas_object_show(fr);
1201
1202 bx_opt = elm_box_add(fr);
1203 elm_object_content_set(fr, bx_opt);
1204 evas_object_show(bx_opt);
1205
1206 btn = elm_button_add(bx_opt);
1207 elm_object_text_set(btn, "Set focus to 3rd toolbar item after 1.5 seconds.");
1208 evas_object_size_hint_weight_set(btn, 0.0, EVAS_HINT_EXPAND);
1209 evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
1210 elm_box_pack_end(bx_opt, btn);
1211 evas_object_show(btn);
1212 evas_object_smart_callback_add(btn, "clicked",
1213 _test_toolbar_focus_item_set_btn_cb,
1214 it_3);
1215
1216 evas_object_resize(win, 420, 200);
1217 evas_object_show(win);
1218}
diff --git a/src/lib/elm_toolbar.c b/src/lib/elm_toolbar.c
index 546333931..e5ea35aa6 100644
--- a/src/lib/elm_toolbar.c
+++ b/src/lib/elm_toolbar.c
@@ -26,6 +26,8 @@ static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
26static const char SIG_CLICKED[] = "clicked"; 26static const char SIG_CLICKED[] = "clicked";
27static const char SIG_LONGPRESSED[] = "longpressed"; 27static const char SIG_LONGPRESSED[] = "longpressed";
28static const char SIG_CLICKED_DOUBLE[] = "clicked,double"; 28static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
29static const char SIG_ITEM_FOCUSED[] = "item,focused";
30static const char SIG_ITEM_UNFOCUSED[] = "item,unfocused";
29static const Evas_Smart_Cb_Description _smart_callbacks[] = { 31static const Evas_Smart_Cb_Description _smart_callbacks[] = {
30 {SIG_SCROLL, ""}, 32 {SIG_SCROLL, ""},
31 {SIG_SCROLL_ANIM_START, ""}, 33 {SIG_SCROLL_ANIM_START, ""},
@@ -35,6 +37,8 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = {
35 {SIG_CLICKED, ""}, 37 {SIG_CLICKED, ""},
36 {SIG_LONGPRESSED, ""}, 38 {SIG_LONGPRESSED, ""},
37 {SIG_CLICKED_DOUBLE, ""}, 39 {SIG_CLICKED_DOUBLE, ""},
40 {SIG_ITEM_FOCUSED, ""},
41 {SIG_ITEM_UNFOCUSED, ""},
38 {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */ 42 {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
39 {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */ 43 {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
40 {SIG_WIDGET_FOCUSED, ""}, /**< handled by elm_widget */ 44 {SIG_WIDGET_FOCUSED, ""}, /**< handled by elm_widget */
@@ -577,46 +581,158 @@ _resize_job(void *data)
577} 581}
578 582
579static void 583static void
584_elm_toolbar_item_focused(Elm_Toolbar_Item *it)
585{
586 Evas_Object *obj = WIDGET(it);
587 ELM_TOOLBAR_DATA_GET(obj, sd);
588 const char *focus_raise;
589
590 if ((!sd) || (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
591 (it == sd->focused_item))
592 return;
593
594 sd->focused_item = it;
595 elm_toolbar_item_show((Elm_Object_Item *)it, ELM_TOOLBAR_ITEM_SCROLLTO_IN);
596 if (elm_widget_focus_highlight_enabled_get(obj))
597 {
598 edje_object_signal_emit
599 (VIEW(it), "elm,state,focused", "elm");
600 }
601 edje_object_signal_emit
602 (VIEW(it), "elm,highlight,on", "elm");
603 focus_raise = edje_object_data_get(VIEW(it), "focusraise");
604 if ((focus_raise) && (!strcmp(focus_raise, "on")))
605 evas_object_raise(VIEW(it));
606 evas_object_smart_callback_call
607 (obj, SIG_ITEM_FOCUSED, it);
608}
609
610static void
611_elm_toolbar_item_unfocused(Elm_Toolbar_Item *it)
612{
613 Evas_Object *obj = WIDGET(it);
614 ELM_TOOLBAR_DATA_GET(obj, sd);
615
616 if ((!sd) || !sd->focused_item ||
617 (it != sd->focused_item))
618 return;
619 if (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
620 return;
621 sd->prev_focused_item = it;
622 if (elm_widget_focus_highlight_enabled_get(obj))
623 {
624 edje_object_signal_emit
625 (VIEW(sd->focused_item), "elm,state,unfocused", "elm");
626 }
627 edje_object_signal_emit
628 (VIEW(it), "elm,highlight,off", "elm");
629 sd->focused_item = NULL;
630 evas_object_smart_callback_call
631 (obj, SIG_ITEM_UNFOCUSED, it);
632}
633
634/*
635 * This function searches the nearest visible item based on the given item.
636 * If the given item is in the toolbar viewport, this returns the given item.
637 * Or this searches other items and checks the nearest fully visible item
638 * according to the given item's position.
639 */
640static Elm_Object_Item *
641_elm_toolbar_nearest_visible_item_get(Evas_Object *obj, Elm_Object_Item *it)
642{
643 Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0; // toolbar viewport geometry
644 Evas_Coord ix = 0, iy = 0, iw = 0, ih = 0; // given item geometry
645 Evas_Coord cx = 0, cy = 0, cw = 0, ch = 0; // candidate item geometry
646 Eina_List *item_list = NULL;
647 Elm_Object_Item *item = NULL;
648 ELM_TOOLBAR_DATA_GET(obj, sd);
649
650 if (!it) return NULL;
651
652 evas_object_geometry_get(obj, &vx, &vy, &vw, &vh);
653 evas_object_geometry_get(VIEW(it), &ix, &iy, &iw, &ih);
654
655 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, ix, iy, iw, ih))
656 return it;
657
658 item_list = evas_object_box_children_get(sd->bx);
659
660 if ((sd->vertical && (iy < vy)) ||
661 (!sd->vertical && (iw < vw)))
662 {
663 while ((item_list = eina_list_next(item_list)))
664 {
665 item = eina_list_data_get(item_list);
666 evas_object_geometry_get(VIEW(item), &cx, &cy, &cw, &ch);
667 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, cx, cy, cw, ch))
668 return item;
669 }
670 }
671 else
672 {
673 while ((item_list = eina_list_prev(item_list)))
674 {
675 item = eina_list_data_get(item_list);
676 evas_object_geometry_get(VIEW(item), &cx, &cy, &cw, &ch);
677 if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, cx, cy, cw, ch))
678 return item;
679 }
680 }
681 return NULL;
682}
683
684static void
580_elm_toolbar_smart_on_focus(Eo *obj, void *_pd EINA_UNUSED, va_list *list) 685_elm_toolbar_smart_on_focus(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
581{ 686{
582 Eina_Bool *ret = va_arg(*list, Eina_Bool *); 687 Eina_Bool *ret = va_arg(*list, Eina_Bool *);
583 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); 688 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
584 ELM_TOOLBAR_DATA_GET(obj, sd); 689 ELM_TOOLBAR_DATA_GET(obj, sd);
585 Eina_Bool int_ret = EINA_FALSE; 690 Eina_Bool int_ret = EINA_FALSE;
691 Elm_Object_Item *it = NULL;
586 692
587 eo_do_super(obj, MY_CLASS, elm_obj_widget_on_focus(&int_ret)); 693 eo_do_super(obj, MY_CLASS, elm_obj_widget_on_focus(&int_ret));
588 if (!int_ret) return; 694 if (!int_ret) return;
695 if (!sd->items) return;
589 696
590 if (elm_widget_focus_get(obj)) 697 if (elm_widget_focus_get(obj) && !sd->mouse_down)
591 evas_object_focus_set(wd->resize_obj, EINA_TRUE);
592 else
593 { 698 {
594 if (sd->highlighted_item) 699 if (sd->last_focused_item)
700 it = (Elm_Object_Item *)sd->last_focused_item;
701 else
702 it = (Elm_Object_Item *)ELM_TOOLBAR_ITEM_FROM_INLIST(sd->items);
703 if (it)
595 { 704 {
596 edje_object_signal_emit(VIEW(sd->highlighted_item), "elm,highlight,off", "elm"); 705 it = _elm_toolbar_nearest_visible_item_get(obj, it);
597 sd->highlighted_item = NULL; 706 _elm_toolbar_item_focused((Elm_Toolbar_Item *)it);
598 } 707 }
708 evas_object_focus_set(wd->resize_obj, EINA_TRUE);
709 }
710 else
711 {
712 sd->prev_focused_item = sd->focused_item;
713 sd->last_focused_item = sd->focused_item;
714 if (sd->focused_item)
715 _elm_toolbar_item_unfocused(sd->focused_item);
599 evas_object_focus_set(wd->resize_obj, EINA_FALSE); 716 evas_object_focus_set(wd->resize_obj, EINA_FALSE);
600 } 717 }
601
602 if (ret) *ret = EINA_TRUE; 718 if (ret) *ret = EINA_TRUE;
603} 719}
604 720
605static Elm_Toolbar_Item * 721static Elm_Toolbar_Item *
606_highlight_next_item_get(Evas_Object *obj, Evas_Object *box, Eina_Bool reverse) 722_focus_next_item_get(Evas_Object *obj, Eina_Bool reverse)
607{ 723{
608 ELM_TOOLBAR_DATA_GET(obj, sd); 724 ELM_TOOLBAR_DATA_GET(obj, sd);
609 Eina_List *list = NULL; 725 Eina_List *list = NULL;
610 Elm_Toolbar_Item *it = NULL; 726 Elm_Toolbar_Item *it = NULL;
611 Evas_Object *it_obj = NULL; 727 Evas_Object *it_obj = NULL;
612 728
613 list = evas_object_box_children_get(box); 729 list = evas_object_box_children_get(sd->bx);
614 if (reverse) 730 if (reverse)
615 list = eina_list_reverse(list); 731 list = eina_list_reverse(list);
616 732
617 if (sd->highlighted_item) 733 if (sd->focused_item)
618 { 734 {
619 list = eina_list_data_find_list(list, VIEW(sd->highlighted_item)); 735 list = eina_list_data_find_list(list, VIEW(sd->focused_item));
620 if (list) list = eina_list_next(list); 736 if (list) list = eina_list_next(list);
621 } 737 }
622 it_obj = eina_list_data_get(list); 738 it_obj = eina_list_data_get(list);
@@ -642,6 +758,67 @@ _highlight_next_item_get(Evas_Object *obj, Evas_Object *box, Eina_Bool reverse)
642} 758}
643 759
644static void 760static void
761_item_focus_set_hook(Elm_Object_Item *it, Eina_Bool focused)
762{
763 ELM_TOOLBAR_ITEM_CHECK(it);
764 Evas_Object *obj = WIDGET(it);
765 ELM_TOOLBAR_DATA_GET(obj, sd);
766
767 if (focused)
768 {
769 if (!elm_object_focus_get(obj))
770 elm_object_focus_set(obj, EINA_TRUE);
771 if (it != (Elm_Object_Item *)sd->focused_item)
772 {
773 if (sd->focused_item)
774 _elm_toolbar_item_unfocused(sd->focused_item);
775 _elm_toolbar_item_focused((Elm_Toolbar_Item *)it);
776 }
777 }
778 else
779 {
780 if (it)
781 _elm_toolbar_item_unfocused((Elm_Toolbar_Item *)it);
782 }
783 _elm_widget_focus_highlight_start(obj);
784}
785
786static Eina_Bool
787_item_focus_get_hook(Elm_Object_Item *it)
788{
789 ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
790 Evas_Object *obj = WIDGET(it);
791 ELM_TOOLBAR_CHECK(obj) EINA_FALSE;
792 ELM_TOOLBAR_DATA_GET(obj, sd);
793
794 if (it == (Elm_Object_Item *)sd->focused_item)
795 return EINA_TRUE;
796 return EINA_FALSE;
797}
798
799static Eina_Bool
800_item_focused_next( Evas_Object *obj,
801 Eina_Bool reverse,
802 Elm_Focus_Direction dir)
803{
804 ELM_TOOLBAR_DATA_GET(obj, sd);
805 Elm_Toolbar_Item *next_focused_item;
806
807 next_focused_item = _focus_next_item_get(obj, reverse);
808 if (!next_focused_item)
809 return EINA_FALSE;
810
811 if ((!sd->vertical && (dir == ELM_FOCUS_LEFT || dir == ELM_FOCUS_RIGHT))
812 || (sd->vertical && (dir == ELM_FOCUS_UP || dir == ELM_FOCUS_DOWN)))
813 {
814 elm_object_item_focus_set((Elm_Object_Item *)next_focused_item, EINA_TRUE);
815 return EINA_TRUE;
816 }
817 _elm_widget_focus_highlight_start(obj);
818 return EINA_FALSE;
819}
820
821static void
645_elm_toolbar_smart_event(Eo *obj, void *_pd, va_list *list) 822_elm_toolbar_smart_event(Eo *obj, void *_pd, va_list *list)
646{ 823{
647 Evas_Object *src = va_arg(*list, Evas_Object *); 824 Evas_Object *src = va_arg(*list, Evas_Object *);
@@ -654,9 +831,6 @@ _elm_toolbar_smart_event(Eo *obj, void *_pd, va_list *list)
654 (void) src; 831 (void) src;
655 (void) type; 832 (void) type;
656 833
657 Elm_Toolbar_Item *it = NULL;
658 Evas_Coord x, y, w, h;
659
660 if (elm_widget_disabled_get(obj)) return; 834 if (elm_widget_disabled_get(obj)) return;
661 if (type != EVAS_CALLBACK_KEY_DOWN) return; 835 if (type != EVAS_CALLBACK_KEY_DOWN) return;
662 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return; 836 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
@@ -666,56 +840,64 @@ _elm_toolbar_smart_event(Eo *obj, void *_pd, va_list *list)
666 (!strcmp(ev->key, "KP_Enter")) || 840 (!strcmp(ev->key, "KP_Enter")) ||
667 (!strcmp(ev->key, "space"))) 841 (!strcmp(ev->key, "space")))
668 { 842 {
669 if (sd->highlighted_item) 843 if (sd->focused_item)
670 _item_select(sd->highlighted_item); 844 _item_select(sd->focused_item);
671 845
672 goto success; 846 goto success;
673 } 847 }
674 else if ((!strcmp(ev->key, "Left")) || 848 else if ((!strcmp(ev->key, "Left")) ||
675 ((!strcmp(ev->key, "KP_Left")) && !ev->string)) 849 ((!strcmp(ev->key, "KP_Left")) && !ev->string))
676 { 850 {
677 if (!sd->vertical) 851 if (_item_focused_next(obj, EINA_TRUE, ELM_FOCUS_LEFT))
678 it = _highlight_next_item_get(obj, sd->bx, EINA_TRUE); 852 {
853 goto success;
854 }
679 else 855 else
680 return; 856 {
857 if (ret) *ret = EINA_FALSE;
858 return;
859 }
681 } 860 }
682 else if ((!strcmp(ev->key, "Right")) || 861 else if ((!strcmp(ev->key, "Right")) ||
683 ((!strcmp(ev->key, "KP_Right")) && !ev->string)) 862 ((!strcmp(ev->key, "KP_Right")) && !ev->string))
684 { 863 {
685 if (!sd->vertical) 864 if (_item_focused_next(obj, EINA_FALSE, ELM_FOCUS_RIGHT))
686 it = _highlight_next_item_get(obj, sd->bx, EINA_FALSE); 865 {
866 goto success;
867 }
687 else 868 else
688 return; 869 {
870 if (ret) *ret = EINA_FALSE;
871 return;
872 }
689 } 873 }
690 else if ((!strcmp(ev->key, "Up")) || 874 else if ((!strcmp(ev->key, "Up")) ||
691 ((!strcmp(ev->key, "KP_Up")) && !ev->string)) 875 ((!strcmp(ev->key, "KP_Up")) && !ev->string))
692 { 876 {
693 if (sd->vertical) 877 if (_item_focused_next(obj, EINA_TRUE, ELM_FOCUS_UP))
694 it = _highlight_next_item_get(obj, sd->bx, EINA_TRUE); 878 {
879 goto success;
880 }
695 else 881 else
696 return; 882 {
883 if (ret) *ret = EINA_FALSE;
884 return;
885 }
697 } 886 }
698 else if ((!strcmp(ev->key, "Down")) || 887 else if ((!strcmp(ev->key, "Down")) ||
699 ((!strcmp(ev->key, "KP_Down")) && !ev->string)) 888 ((!strcmp(ev->key, "KP_Down")) && !ev->string))
700 { 889 {
701 if (sd->vertical) 890 if (_item_focused_next(obj, EINA_FALSE, ELM_FOCUS_DOWN))
702 it = _highlight_next_item_get(obj, sd->bx, EINA_FALSE); 891 {
892 goto success;
893 }
703 else 894 else
704 return; 895 {
896 if (ret) *ret = EINA_FALSE;
897 return;
898 }
705 } 899 }
706 900
707 if (!it)
708 return;
709
710 if (sd->highlighted_item)
711 edje_object_signal_emit(VIEW(sd->highlighted_item), "elm,highlight,off", "elm");
712 sd->highlighted_item = it;
713 edje_object_signal_emit(VIEW(sd->highlighted_item), "elm,highlight,on", "elm");
714
715 if (_elm_toolbar_item_coordinates_calc(
716 sd->highlighted_item, ELM_TOOLBAR_ITEM_SCROLLTO_IN, &x, &y, &w, &h))
717 eo_do(obj, elm_interface_scrollable_region_bring_in(x, y, w, h));
718
719success: 901success:
720 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; 902 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
721 if (ret) *ret = EINA_TRUE; 903 if (ret) *ret = EINA_TRUE;
@@ -907,6 +1089,7 @@ static void
907_item_del(Elm_Toolbar_Item *it) 1089_item_del(Elm_Toolbar_Item *it)
908{ 1090{
909 Elm_Toolbar_Item_State *it_state; 1091 Elm_Toolbar_Item_State *it_state;
1092 ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
910 1093
911 _item_unselect(it); 1094 _item_unselect(it);
912 1095
@@ -931,6 +1114,13 @@ _item_del(Elm_Toolbar_Item *it)
931 evas_object_del(it->icon); 1114 evas_object_del(it->icon);
932 } 1115 }
933 1116
1117 if (sd->focused_item == it)
1118 sd->focused_item = NULL;
1119 if (sd->last_focused_item == it)
1120 sd->last_focused_item = NULL;
1121 if (sd->prev_focused_item == it)
1122 sd->prev_focused_item = NULL;
1123
934 evas_object_del(it->object); 1124 evas_object_del(it->object);
935 //TODO: See if checking for sd->menu_parent is necessary before 1125 //TODO: See if checking for sd->menu_parent is necessary before
936 //deleting menu 1126 //deleting menu
@@ -1139,6 +1329,20 @@ _sizing_eval(Evas_Object *obj)
1139} 1329}
1140 1330
1141static void 1331static void
1332_elm_toolbar_highlight_in_theme(Evas_Object *obj)
1333{
1334 const char *fh;
1335 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1336
1337 fh = edje_object_data_get
1338 (wd->resize_obj, "focus_highlight");
1339 if ((fh) && (!strcmp(fh, "on")))
1340 elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
1341 else
1342 elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
1343}
1344
1345static void
1142_elm_toolbar_smart_theme(Eo *obj, void *_pd, va_list *list) 1346_elm_toolbar_smart_theme(Eo *obj, void *_pd, va_list *list)
1143{ 1347{
1144 Elm_Toolbar_Item *it; 1348 Elm_Toolbar_Item *it;
@@ -1188,6 +1392,7 @@ _elm_toolbar_smart_theme(Eo *obj, void *_pd, va_list *list)
1188 if (sd->more_item) 1392 if (sd->more_item)
1189 _item_theme_hook(obj, sd->more_item, scale, sd->icon_size); 1393 _item_theme_hook(obj, sd->more_item, scale, sd->icon_size);
1190 1394
1395 _elm_toolbar_highlight_in_theme(obj);
1191 _sizing_eval(obj); 1396 _sizing_eval(obj);
1192 1397
1193 if (ret) *ret = EINA_TRUE; 1398 if (ret) *ret = EINA_TRUE;
@@ -1856,6 +2061,7 @@ _mouse_down_cb(Elm_Toolbar_Item *it,
1856 if (ev->button != 1) return; 2061 if (ev->button != 1) return;
1857 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK) 2062 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1858 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it); 2063 evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
2064 sd->mouse_down = EINA_TRUE;
1859 sd->long_press = EINA_FALSE; 2065 sd->long_press = EINA_FALSE;
1860 if (sd->long_timer) 2066 if (sd->long_timer)
1861 ecore_timer_interval_set 2067 ecore_timer_interval_set
@@ -1877,7 +2083,11 @@ _mouse_up_cb(Elm_Toolbar_Item *it,
1877 ELM_TOOLBAR_DATA_GET(WIDGET(it), sd); 2083 ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
1878 2084
1879 if (ev->button != 1) return; 2085 if (ev->button != 1) return;
2086 sd->mouse_down = EINA_FALSE;
1880 ELM_SAFE_FREE(sd->long_timer, ecore_timer_del); 2087 ELM_SAFE_FREE(sd->long_timer, ecore_timer_del);
2088 if ((!elm_object_item_disabled_get((Elm_Object_Item *)it)) &&
2089 (sd->focused_item != it))
2090 elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
1881 evas_object_event_callback_del_full 2091 evas_object_event_callback_del_full
1882 (VIEW(it), EVAS_CALLBACK_MOUSE_MOVE, 2092 (VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
1883 (Evas_Object_Event_Cb)_mouse_move_cb, it); 2093 (Evas_Object_Event_Cb)_mouse_move_cb, it);
@@ -2089,6 +2299,8 @@ _item_new(Evas_Object *obj,
2089 elm_widget_item_content_set_hook_set(it, _item_content_set_hook); 2299 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
2090 elm_widget_item_content_get_hook_set(it, _item_content_get_hook); 2300 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
2091 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook); 2301 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
2302 elm_widget_item_focus_set_hook_set(it, _item_focus_set_hook);
2303 elm_widget_item_focus_get_hook_set(it, _item_focus_get_hook);
2092 2304
2093 it->label = eina_stringshare_add(label); 2305 it->label = eina_stringshare_add(label);
2094 it->prio.visible = 1; 2306 it->prio.visible = 1;
@@ -2570,6 +2782,7 @@ _elm_toolbar_smart_add(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
2570 (priv->bx, EVAS_CALLBACK_RESIZE, _resize_cb, obj); 2782 (priv->bx, EVAS_CALLBACK_RESIZE, _resize_cb, obj);
2571 elm_toolbar_icon_order_lookup_set(obj, ELM_ICON_LOOKUP_THEME_FDO); 2783 elm_toolbar_icon_order_lookup_set(obj, ELM_ICON_LOOKUP_THEME_FDO);
2572 2784
2785 _elm_toolbar_highlight_in_theme(obj);
2573 _sizing_eval(obj); 2786 _sizing_eval(obj);
2574} 2787}
2575 2788
@@ -2717,6 +2930,74 @@ _elm_toolbar_smart_access(Eo *obj EINA_UNUSED, void *_pd, va_list *list)
2717 _access_obj_process(sd, _elm_toolbar_smart_focus_next_enable); 2930 _access_obj_process(sd, _elm_toolbar_smart_focus_next_enable);
2718} 2931}
2719 2932
2933static void
2934_elm_toolbar_coordinates_adjust(Elm_Toolbar_Item *it,
2935 Evas_Coord *x,
2936 Evas_Coord *y,
2937 Evas_Coord *w,
2938 Evas_Coord *h)
2939{
2940 ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
2941
2942 Evas_Coord ix, iy, iw, ih, vx, vy, vw, vh;
2943
2944 evas_object_geometry_get(sd->hit_rect, &vx, &vy, &vw, &vh);
2945 evas_object_geometry_get(VIEW(it), &ix, &iy, &iw, &ih);
2946 *x = ix;
2947 *y = iy;
2948 *w = iw;
2949 *h = ih;
2950 if (sd->vertical)
2951 {
2952 //TODO: Enhance it later.
2953 if ((ix < vx) || (ix + iw) > (vx + vw) || (iy + ih) > (vy + vh))
2954 *y = iy - ih;
2955 else if (iy < vy)
2956 *y = iy + ih;
2957 }
2958 else
2959 {
2960 //TODO: Enhance it later.
2961 if ((iy < vy) || (ix + iw) > (vx + vw) || (iy + ih) > (vy + vh))
2962 *x = ix - iw;
2963 else if (ix < vx)
2964 *x = ix + iw;
2965 }
2966}
2967
2968static void
2969_elm_toolbar_focus_highlight_geometry_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list)
2970{
2971 Evas_Coord *x = va_arg(*list, Evas_Coord *);
2972 Evas_Coord *y = va_arg(*list, Evas_Coord *);
2973 Evas_Coord *w = va_arg(*list, Evas_Coord *);
2974 Evas_Coord *h = va_arg(*list, Evas_Coord *);
2975 Eina_Bool is_next = va_arg(*list, int);
2976
2977 Elm_Toolbar_Smart_Data *sd = _pd;
2978
2979 if (is_next)
2980 {
2981 if (sd->focused_item)
2982 {
2983 _elm_toolbar_coordinates_adjust
2984 (sd->focused_item, x, y, w, h);
2985 elm_widget_focus_highlight_focus_part_geometry_get
2986 (VIEW(sd->focused_item), x, y, w, h);
2987 }
2988 }
2989 else
2990 {
2991 if (sd->prev_focused_item)
2992 {
2993 _elm_toolbar_coordinates_adjust
2994 (sd->prev_focused_item, x, y, w, h);
2995 elm_widget_focus_highlight_focus_part_geometry_get
2996 (VIEW(sd->prev_focused_item), x, y, w, h);
2997 }
2998 }
2999}
3000
2720EAPI Evas_Object * 3001EAPI Evas_Object *
2721elm_toolbar_add(Evas_Object *parent) 3002elm_toolbar_add(Evas_Object *parent)
2722{ 3003{
@@ -3951,6 +4232,15 @@ elm_toolbar_item_bring_in(Elm_Object_Item *it, Elm_Toolbar_Item_Scrollto_Type ty
3951} 4232}
3952 4233
3953static void 4234static void
4235_elm_toolbar_focused_item_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list)
4236{
4237 Elm_Object_Item **ret = va_arg(*list, Elm_Object_Item **);
4238 Elm_Toolbar_Smart_Data *sd = _pd;
4239
4240 if (ret) *ret = (Elm_Object_Item *)sd->focused_item;
4241}
4242
4243static void
3954_class_constructor(Eo_Class *klass) 4244_class_constructor(Eo_Class *klass)
3955{ 4245{
3956 const Eo_Op_Func_Description func_desc[] = { 4246 const Eo_Op_Func_Description func_desc[] = {
@@ -3969,6 +4259,8 @@ _class_constructor(Eo_Class *klass)
3969 EO_OP_FUNC(ELM_OBJ_WIDGET_ID(ELM_OBJ_WIDGET_SUB_ID_FOCUS_NEXT_MANAGER_IS), _elm_toolbar_smart_focus_next_manager_is), 4259 EO_OP_FUNC(ELM_OBJ_WIDGET_ID(ELM_OBJ_WIDGET_SUB_ID_FOCUS_NEXT_MANAGER_IS), _elm_toolbar_smart_focus_next_manager_is),
3970 EO_OP_FUNC(ELM_OBJ_WIDGET_ID(ELM_OBJ_WIDGET_SUB_ID_FOCUS_NEXT), _elm_toolbar_smart_focus_next), 4260 EO_OP_FUNC(ELM_OBJ_WIDGET_ID(ELM_OBJ_WIDGET_SUB_ID_FOCUS_NEXT), _elm_toolbar_smart_focus_next),
3971 EO_OP_FUNC(ELM_OBJ_WIDGET_ID(ELM_OBJ_WIDGET_SUB_ID_ACCESS), _elm_toolbar_smart_access), 4261 EO_OP_FUNC(ELM_OBJ_WIDGET_ID(ELM_OBJ_WIDGET_SUB_ID_ACCESS), _elm_toolbar_smart_access),
4262 EO_OP_FUNC(ELM_OBJ_WIDGET_ID(ELM_OBJ_WIDGET_SUB_ID_FOCUS_HIGHLIGHT_GEOMETRY_GET), _elm_toolbar_focus_highlight_geometry_get),
4263 EO_OP_FUNC(ELM_OBJ_WIDGET_ID(ELM_OBJ_WIDGET_SUB_ID_FOCUSED_ITEM_GET), _elm_toolbar_focused_item_get),
3972 4264
3973 EO_OP_FUNC(ELM_OBJ_TOOLBAR_ID(ELM_OBJ_TOOLBAR_SUB_ID_ICON_SIZE_SET), _icon_size_set), 4265 EO_OP_FUNC(ELM_OBJ_TOOLBAR_ID(ELM_OBJ_TOOLBAR_SUB_ID_ICON_SIZE_SET), _icon_size_set),
3974 EO_OP_FUNC(ELM_OBJ_TOOLBAR_ID(ELM_OBJ_TOOLBAR_SUB_ID_ICON_SIZE_GET), _icon_size_get), 4266 EO_OP_FUNC(ELM_OBJ_TOOLBAR_ID(ELM_OBJ_TOOLBAR_SUB_ID_ICON_SIZE_GET), _icon_size_get),
diff --git a/src/lib/elm_toolbar.h b/src/lib/elm_toolbar.h
index 818ba883a..d80deda62 100644
--- a/src/lib/elm_toolbar.h
+++ b/src/lib/elm_toolbar.h
@@ -31,6 +31,8 @@
31 * - @c "language,changed" - when the program language changes. 31 * - @c "language,changed" - when the program language changes.
32 * - @c "focused" - When the toolbar has received focus. (since 1.8) 32 * - @c "focused" - When the toolbar has received focus. (since 1.8)
33 * - @c "unfocused" - When the toolbar has lost focus. (since 1.8) 33 * - @c "unfocused" - When the toolbar has lost focus. (since 1.8)
34 * - @c "item,focused" - When the toolbar item has received focus. (since 1.10)
35 * - @c "item,unfocused" - When the toolbar item has lost focus. (since 1.10)
34 * 36 *
35 * Available styles for it: 37 * Available styles for it:
36 * - @c "default" 38 * - @c "default"
@@ -48,6 +50,8 @@
48 * @li @ref elm_object_item_part_content_set 50 * @li @ref elm_object_item_part_content_set
49 * @li @ref elm_object_item_part_content_get 51 * @li @ref elm_object_item_part_content_get
50 * @li @ref elm_object_item_part_content_unset 52 * @li @ref elm_object_item_part_content_unset
53 * @li @ref elm_object_item_focus_set
54 * @li @ref elm_object_item_focus_get
51 * 55 *
52 * List of examples: 56 * List of examples:
53 * @li @ref toolbar_example_01 57 * @li @ref toolbar_example_01
diff --git a/src/lib/elm_widget_toolbar.h b/src/lib/elm_widget_toolbar.h
index 9c731eab8..381dba32a 100644
--- a/src/lib/elm_widget_toolbar.h
+++ b/src/lib/elm_widget_toolbar.h
@@ -29,7 +29,9 @@ struct _Elm_Toolbar_Smart_Data
29 Eina_Inlist *items; 29 Eina_Inlist *items;
30 Elm_Toolbar_Item *more_item; 30 Elm_Toolbar_Item *more_item;
31 Elm_Toolbar_Item *selected_item; /**< a selected item by mouse click, return key, api, and etc. */ 31 Elm_Toolbar_Item *selected_item; /**< a selected item by mouse click, return key, api, and etc. */
32 Elm_Toolbar_Item *highlighted_item; /**< a highlighted item by keypard arrow */ 32 Elm_Toolbar_Item *focused_item; /**< a focused item by keypad arrow or mouse. This is set to NULL if widget looses focus. */
33 Elm_Toolbar_Item *prev_focused_item; /**< previous focused item by keypad arrow or mouse. */
34 Elm_Toolbar_Item *last_focused_item; /**< This records the last focused item when widget looses focus. This is required to set the focus on last focused item when widgets gets focus. */
33 Elm_Toolbar_Item *reorder_empty, *reorder_item; 35 Elm_Toolbar_Item *reorder_empty, *reorder_item;
34 Elm_Toolbar_Shrink_Mode shrink_mode; 36 Elm_Toolbar_Shrink_Mode shrink_mode;
35 Elm_Icon_Lookup_Order lookup_order; 37 Elm_Icon_Lookup_Order lookup_order;
@@ -49,6 +51,7 @@ struct _Elm_Toolbar_Smart_Data
49 Eina_Bool delete_me : 1; 51 Eina_Bool delete_me : 1;
50 Eina_Bool reorder_mode : 1; 52 Eina_Bool reorder_mode : 1;
51 Eina_Bool transverse_expanded : 1; 53 Eina_Bool transverse_expanded : 1;
54 Eina_Bool mouse_down : 1; /**< a flag that mouse is down on the toolbar at the moment. This flag is set to true on mouse and reset to false on mouse up. */
52}; 55};
53 56
54struct _Elm_Toolbar_Item 57struct _Elm_Toolbar_Item