seoz pushed a commit to branch master.

http://git.enlightenment.org/core/elementary.git/commit/?id=0a9fe5fb4da5e83551df2dfdee2e90f3fda3facc

commit 0a9fe5fb4da5e83551df2dfdee2e90f3fda3facc
Author: Amitesh Singh <[email protected]>
Date:   Mon Mar 24 00:22:32 2014 +0900

    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
---
 data/themes/edc/elm/toolbar.edc |   3 +-
 src/bin/test.c                  |   2 +
 src/bin/test_toolbar.c          | 169 ++++++++++++++++++
 src/lib/elm_toolbar.c           | 372 +++++++++++++++++++++++++++++++++++-----
 src/lib/elm_toolbar.h           |   4 +
 src/lib/elm_widget_toolbar.h    |   5 +-
 6 files changed, 513 insertions(+), 42 deletions(-)

diff --git a/data/themes/edc/elm/toolbar.edc b/data/themes/edc/elm/toolbar.edc
index e3c4d9b..f0cb0a7 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";
 // === item: standard default item
 group { name: "elm/toolbar/item/default";
    data.item: "transition_animation_on" "1";
-   
+   data.item: "focusraise" "on";
+
    images.image: "shadow_inset_bevels.png" COMP;
    images.image: "shadow_angled_in_sides.png" COMP;
    images.image: "horizontal_separated_bar_small_glow.png" COMP;
diff --git a/src/bin/test.c b/src/bin/test.c
index bc5db8a..1dd840c 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);
 void test_toolbar7(void *data, Evas_Object *obj, void *event_info);
 void test_toolbar8(void *data, Evas_Object *obj, void *event_info);
 void test_toolbar_vertical(void *data, Evas_Object *obj, void *event_info);
+void test_toolbar_focus(void *data, Evas_Object *obj, void *event_info);
 void test_hoversel(void *data, Evas_Object *obj, void *event_info);
 void test_hoversel_focus(void *data, Evas_Object *obj, void *event_info);
 void test_list(void *data, Evas_Object *obj, void *event_info);
@@ -610,6 +611,7 @@ add_tests:
    ADD_TEST(NULL, "Toolbars", "Toolbar 7", test_toolbar7);
    ADD_TEST(NULL, "Toolbars", "Toolbar 8", test_toolbar8);
    ADD_TEST(NULL, "Toolbars", "Toolbar Vertical", test_toolbar_vertical);
+   ADD_TEST(NULL, "Toolbars", "Toolbar Focus", test_toolbar_focus);
 
    //------------------------------//
    ADD_TEST(NULL, "Lists - List", "List", test_list);
diff --git a/src/bin/test_toolbar.c b/src/bin/test_toolbar.c
index 433d188..44723b9 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_
    evas_object_resize(win, 420, 250);
    evas_object_show(win);
 }
+
+static void
+_item_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
+{
+   printf("%s: %p\n", (char *)data, event_info);
+}
+
+static void
+_test_toolbar_focus_focus_highlight_check_changed(void *data, Evas_Object *obj,
+                                                  void *event_info EINA_UNUSED)
+{
+   elm_win_focus_highlight_enabled_set(data,
+                                       elm_check_state_get(obj));
+}
+
+static void
+_test_toolbar_focus_focus_animate_check_changed(void *data, Evas_Object *obj,
+                                                void *event_info EINA_UNUSED)
+{
+   elm_win_focus_highlight_animate_set(data,
+                                       elm_check_state_get(obj));
+}
+
+static void
+_toolbar_focus_key_down_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED,
+                           Evas_Object *obj EINA_UNUSED, void *event_info)
+{
+   Evas_Event_Key_Down *ev = event_info;
+   printf("\n=== Key Down : %s ===\n", ev->keyname);
+}
+
+static Ecore_Timer *timer = NULL;
+static void
+_test_toolbar_focus_win_del_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED,
+                               Evas_Object *obj EINA_UNUSED,
+                               void *event_info EINA_UNUSED)
+{
+   ecore_timer_del(timer);
+   timer = NULL;
+}
+
+static Eina_Bool
+_focus_timer_cb(void *data)
+{
+   Elm_Object_Item *it = data;
+   elm_object_item_focus_set(it, EINA_TRUE);
+   timer = NULL;
+
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_test_toolbar_focus_item_set_btn_cb(void *data EINA_UNUSED, Evas_Object *obj 
EINA_UNUSED,
+                                    void *event_info EINA_UNUSED)
+{
+   ecore_timer_del(timer);
+   timer = ecore_timer_add(1.5, _focus_timer_cb, data);
+}
+
+void
+test_toolbar_focus(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void 
*event_info EINA_UNUSED)
+{
+   Evas_Object *win, *bx, *toolbar, *fr, *btn, *bx_opt, *chk;
+   Elm_Object_Item *tb_it, *it_3;
+
+   win = elm_win_util_standard_add("toolbar-focus", "Toolbar Focus");
+   elm_win_autodel_set(win, EINA_TRUE);
+   evas_object_event_callback_add(win, EVAS_CALLBACK_DEL,
+                                  _test_toolbar_focus_win_del_cb, NULL);
+   elm_win_focus_highlight_enabled_set(win, EINA_TRUE);
+   elm_win_focus_highlight_animate_set(win, EINA_TRUE);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   btn = elm_button_add(win);
+   elm_object_text_set(btn, "Up");
+   elm_box_pack_end(bx, btn);
+   evas_object_show(btn);
+
+   toolbar = elm_toolbar_add(win);
+   elm_toolbar_shrink_mode_set(toolbar, ELM_TOOLBAR_SHRINK_SCROLL);
+   evas_object_size_hint_align_set(toolbar, EVAS_HINT_FILL, 0.0);
+   elm_toolbar_item_append(toolbar, "document-print", "Print", NULL, NULL);
+   elm_toolbar_item_append(toolbar, "folder-new", "Folder", NULL, NULL);
+   it_3 = elm_toolbar_item_append(toolbar, "clock", "Clock", NULL, NULL);
+   elm_toolbar_item_append(toolbar, "refresh", "Update", NULL, NULL);
+   elm_toolbar_item_append(toolbar, "folder-new", "Folder", NULL, NULL);
+   elm_toolbar_item_append(toolbar, "clock", "Clock", NULL, NULL);
+   tb_it = elm_toolbar_item_append(toolbar, "document-print", "Print", NULL, 
NULL);
+   elm_object_item_disabled_set(tb_it, EINA_TRUE);
+   elm_toolbar_item_append(toolbar, "folder-new", "Folder", NULL, NULL);
+   elm_toolbar_item_append(toolbar, "refresh", "Update", NULL, NULL);
+   elm_toolbar_item_append(toolbar, "folder-new", "Folder", NULL, NULL);
+   elm_toolbar_item_append(toolbar, "clock", "Clock", NULL, NULL);
+   elm_toolbar_item_append(toolbar, "document-print", "Print", NULL, NULL);
+   elm_toolbar_item_append(toolbar, "folder-new", "Folder", NULL, NULL);
+   elm_toolbar_item_append(toolbar, "refresh", "Update", NULL, NULL);
+   elm_toolbar_item_append(toolbar, "folder-new", "Folder", NULL, NULL);
+   elm_box_pack_end(bx, toolbar);
+   evas_object_show(toolbar);
+   evas_object_smart_callback_add(toolbar, "clicked", _item_cb, "clicked");
+   evas_object_smart_callback_add(toolbar, "item,focused", _item_cb, 
"item,focused");
+   evas_object_smart_callback_add(toolbar, "item,unfocused", _item_cb, 
"item,unfcoused");
+   evas_object_event_callback_add(toolbar, EVAS_CALLBACK_KEY_DOWN, 
_toolbar_focus_key_down_cb, NULL);
+
+   btn = elm_button_add(win);
+   elm_object_text_set(btn, "Down");
+   elm_box_pack_end(bx, btn);
+   evas_object_show(btn);
+
+   //Options
+   fr = elm_frame_add(bx);
+   elm_object_text_set(fr, "Options");
+   evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, fr);
+   evas_object_show(fr);
+
+   bx_opt = elm_box_add(fr);
+   elm_box_horizontal_set(bx_opt, EINA_TRUE);
+   elm_object_content_set(fr, bx_opt);
+   evas_object_show(bx_opt);
+
+   chk = elm_check_add(bx_opt);
+   elm_object_text_set(chk, "Focus Highlight");
+   elm_check_state_set(chk, EINA_TRUE);
+   evas_object_size_hint_weight_set(chk, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx_opt, chk);
+   evas_object_show(chk);
+   evas_object_smart_callback_add(chk, "changed",
+                                  
_test_toolbar_focus_focus_highlight_check_changed,
+                                  win);
+
+   chk = elm_check_add(bx_opt);
+   elm_object_text_set(chk, "Focus Animation");
+   elm_check_state_set(chk, EINA_TRUE);
+   evas_object_size_hint_weight_set(chk, EVAS_HINT_EXPAND, 0.0);
+   elm_box_pack_end(bx_opt, chk);
+   evas_object_show(chk);
+   evas_object_smart_callback_add(chk, "changed",
+                                  
_test_toolbar_focus_focus_animate_check_changed,
+                                  win);
+   fr = elm_frame_add(bx);
+   elm_object_text_set(fr, "Focus");
+   evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, fr);
+   evas_object_show(fr);
+
+   bx_opt = elm_box_add(fr);
+   elm_object_content_set(fr, bx_opt);
+   evas_object_show(bx_opt);
+
+   btn = elm_button_add(bx_opt);
+   elm_object_text_set(btn, "Set focus to 3rd toolbar item after 1.5 
seconds.");
+   evas_object_size_hint_weight_set(btn, 0.0, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx_opt, btn);
+   evas_object_show(btn);
+   evas_object_smart_callback_add(btn, "clicked",
+                                  _test_toolbar_focus_item_set_btn_cb,
+                                  it_3);
+
+   evas_object_resize(win, 420, 200);
+   evas_object_show(win);
+}
diff --git a/src/lib/elm_toolbar.c b/src/lib/elm_toolbar.c
index 5463339..e5ea35a 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";
 static const char SIG_CLICKED[] = "clicked";
 static const char SIG_LONGPRESSED[] = "longpressed";
 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
+static const char SIG_ITEM_FOCUSED[] = "item,focused";
+static const char SIG_ITEM_UNFOCUSED[] = "item,unfocused";
 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
    {SIG_SCROLL, ""},
    {SIG_SCROLL_ANIM_START, ""},
@@ -35,6 +37,8 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = {
    {SIG_CLICKED, ""},
    {SIG_LONGPRESSED, ""},
    {SIG_CLICKED_DOUBLE, ""},
+   {SIG_ITEM_FOCUSED, ""},
+   {SIG_ITEM_UNFOCUSED, ""},
    {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
    {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
    {SIG_WIDGET_FOCUSED, ""}, /**< handled by elm_widget */
@@ -577,46 +581,158 @@ _resize_job(void *data)
 }
 
 static void
+_elm_toolbar_item_focused(Elm_Toolbar_Item *it)
+{
+   Evas_Object *obj = WIDGET(it);
+   ELM_TOOLBAR_DATA_GET(obj, sd);
+   const char *focus_raise;
+
+   if ((!sd) || (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
+       (it == sd->focused_item))
+     return;
+
+   sd->focused_item = it;
+   elm_toolbar_item_show((Elm_Object_Item *)it, ELM_TOOLBAR_ITEM_SCROLLTO_IN);
+   if (elm_widget_focus_highlight_enabled_get(obj))
+     {
+        edje_object_signal_emit
+           (VIEW(it), "elm,state,focused", "elm");
+     }
+   edje_object_signal_emit
+      (VIEW(it), "elm,highlight,on", "elm");
+   focus_raise = edje_object_data_get(VIEW(it), "focusraise");
+   if ((focus_raise) && (!strcmp(focus_raise, "on")))
+     evas_object_raise(VIEW(it));
+   evas_object_smart_callback_call
+      (obj, SIG_ITEM_FOCUSED, it);
+}
+
+static void
+_elm_toolbar_item_unfocused(Elm_Toolbar_Item *it)
+{
+   Evas_Object *obj = WIDGET(it);
+   ELM_TOOLBAR_DATA_GET(obj, sd);
+
+   if ((!sd) || !sd->focused_item ||
+       (it != sd->focused_item))
+     return;
+   if (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
+     return;
+   sd->prev_focused_item = it;
+   if (elm_widget_focus_highlight_enabled_get(obj))
+     {
+        edje_object_signal_emit
+           (VIEW(sd->focused_item), "elm,state,unfocused", "elm");
+     }
+   edje_object_signal_emit
+      (VIEW(it), "elm,highlight,off", "elm");
+   sd->focused_item = NULL;
+   evas_object_smart_callback_call
+      (obj, SIG_ITEM_UNFOCUSED, it);
+}
+
+/*
+ * This function searches the nearest visible item based on the given item.
+ * If the given item is in the toolbar viewport, this returns the given item.
+ * Or this searches other items and checks the nearest fully visible item
+ * according to the given item's position.
+ */
+static Elm_Object_Item *
+_elm_toolbar_nearest_visible_item_get(Evas_Object *obj, Elm_Object_Item *it)
+{
+   Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0; // toolbar viewport geometry
+   Evas_Coord ix = 0, iy = 0, iw = 0, ih = 0; // given item geometry
+   Evas_Coord cx = 0, cy = 0, cw = 0, ch = 0; // candidate item geometry
+   Eina_List *item_list = NULL;
+   Elm_Object_Item *item = NULL;
+   ELM_TOOLBAR_DATA_GET(obj, sd);
+
+   if (!it) return NULL;
+
+   evas_object_geometry_get(obj, &vx, &vy, &vw, &vh);
+   evas_object_geometry_get(VIEW(it), &ix, &iy, &iw, &ih);
+
+   if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, ix, iy, iw, ih))
+     return it;
+
+   item_list = evas_object_box_children_get(sd->bx);
+
+   if ((sd->vertical && (iy < vy)) ||
+       (!sd->vertical && (iw < vw)))
+     {
+        while ((item_list = eina_list_next(item_list)))
+          {
+             item = eina_list_data_get(item_list);
+             evas_object_geometry_get(VIEW(item), &cx, &cy, &cw, &ch);
+             if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, cx, cy, cw, ch))
+               return item;
+          }
+     }
+   else
+     {
+        while ((item_list = eina_list_prev(item_list)))
+          {
+             item = eina_list_data_get(item_list);
+             evas_object_geometry_get(VIEW(item), &cx, &cy, &cw, &ch);
+             if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, cx, cy, cw, ch))
+               return item;
+          }
+     }
+   return NULL;
+}
+
+static void
 _elm_toolbar_smart_on_focus(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
 {
    Eina_Bool *ret = va_arg(*list, Eina_Bool *);
    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
    ELM_TOOLBAR_DATA_GET(obj, sd);
    Eina_Bool int_ret = EINA_FALSE;
+   Elm_Object_Item *it = NULL;
 
    eo_do_super(obj, MY_CLASS, elm_obj_widget_on_focus(&int_ret));
    if (!int_ret) return;
+   if (!sd->items) return;
 
-   if (elm_widget_focus_get(obj))
-     evas_object_focus_set(wd->resize_obj, EINA_TRUE);
-   else
+   if (elm_widget_focus_get(obj) && !sd->mouse_down)
      {
-        if (sd->highlighted_item)
+        if (sd->last_focused_item)
+          it = (Elm_Object_Item *)sd->last_focused_item;
+        else
+          it = (Elm_Object_Item *)ELM_TOOLBAR_ITEM_FROM_INLIST(sd->items);
+        if (it)
           {
-             edje_object_signal_emit(VIEW(sd->highlighted_item), 
"elm,highlight,off", "elm");
-             sd->highlighted_item = NULL;
+             it = _elm_toolbar_nearest_visible_item_get(obj, it);
+             _elm_toolbar_item_focused((Elm_Toolbar_Item *)it);
           }
+        evas_object_focus_set(wd->resize_obj, EINA_TRUE);
+     }
+   else
+     {
+        sd->prev_focused_item = sd->focused_item;
+        sd->last_focused_item = sd->focused_item;
+        if (sd->focused_item)
+          _elm_toolbar_item_unfocused(sd->focused_item);
         evas_object_focus_set(wd->resize_obj, EINA_FALSE);
      }
-
    if (ret) *ret = EINA_TRUE;
 }
 
 static Elm_Toolbar_Item *
-_highlight_next_item_get(Evas_Object *obj, Evas_Object *box, Eina_Bool reverse)
+_focus_next_item_get(Evas_Object *obj, Eina_Bool reverse)
 {
    ELM_TOOLBAR_DATA_GET(obj, sd);
    Eina_List *list = NULL;
    Elm_Toolbar_Item *it = NULL;
    Evas_Object *it_obj = NULL;
 
-   list = evas_object_box_children_get(box);
+   list = evas_object_box_children_get(sd->bx);
    if (reverse)
      list = eina_list_reverse(list);
 
-   if (sd->highlighted_item)
+   if (sd->focused_item)
      {
-        list = eina_list_data_find_list(list, VIEW(sd->highlighted_item));
+        list = eina_list_data_find_list(list, VIEW(sd->focused_item));
         if (list) list = eina_list_next(list);
      }
    it_obj = eina_list_data_get(list);
@@ -642,6 +758,67 @@ _highlight_next_item_get(Evas_Object *obj, Evas_Object 
*box, Eina_Bool reverse)
 }
 
 static void
+_item_focus_set_hook(Elm_Object_Item *it, Eina_Bool focused)
+{
+   ELM_TOOLBAR_ITEM_CHECK(it);
+   Evas_Object *obj = WIDGET(it);
+   ELM_TOOLBAR_DATA_GET(obj, sd);
+
+   if (focused)
+     {
+        if (!elm_object_focus_get(obj))
+          elm_object_focus_set(obj, EINA_TRUE);
+        if (it != (Elm_Object_Item *)sd->focused_item)
+          {
+             if (sd->focused_item)
+               _elm_toolbar_item_unfocused(sd->focused_item);
+             _elm_toolbar_item_focused((Elm_Toolbar_Item *)it);
+          }
+     }
+   else
+     {
+        if (it)
+          _elm_toolbar_item_unfocused((Elm_Toolbar_Item *)it);
+     }
+   _elm_widget_focus_highlight_start(obj);
+}
+
+static Eina_Bool
+_item_focus_get_hook(Elm_Object_Item *it)
+{
+   ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
+   Evas_Object *obj = WIDGET(it);
+   ELM_TOOLBAR_CHECK(obj) EINA_FALSE;
+   ELM_TOOLBAR_DATA_GET(obj, sd);
+
+   if (it == (Elm_Object_Item *)sd->focused_item)
+     return EINA_TRUE;
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+_item_focused_next( Evas_Object *obj,
+                   Eina_Bool reverse,
+                   Elm_Focus_Direction dir)
+{
+   ELM_TOOLBAR_DATA_GET(obj, sd);
+   Elm_Toolbar_Item *next_focused_item;
+
+   next_focused_item = _focus_next_item_get(obj, reverse);
+   if (!next_focused_item)
+     return EINA_FALSE;
+
+   if ((!sd->vertical && (dir == ELM_FOCUS_LEFT || dir == ELM_FOCUS_RIGHT))
+         || (sd->vertical && (dir == ELM_FOCUS_UP || dir == ELM_FOCUS_DOWN)))
+   {
+      elm_object_item_focus_set((Elm_Object_Item *)next_focused_item, 
EINA_TRUE);
+      return EINA_TRUE;
+   }
+   _elm_widget_focus_highlight_start(obj);
+   return EINA_FALSE;
+}
+
+static void
 _elm_toolbar_smart_event(Eo *obj, void *_pd, va_list *list)
 {
    Evas_Object *src = va_arg(*list, Evas_Object *);
@@ -654,9 +831,6 @@ _elm_toolbar_smart_event(Eo *obj, void *_pd, va_list *list)
    (void) src;
    (void) type;
 
-   Elm_Toolbar_Item *it = NULL;
-   Evas_Coord x, y, w, h;
-
    if (elm_widget_disabled_get(obj)) return;
    if (type != EVAS_CALLBACK_KEY_DOWN) return;
    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)
        (!strcmp(ev->key, "KP_Enter")) ||
        (!strcmp(ev->key, "space")))
      {
-        if (sd->highlighted_item)
-          _item_select(sd->highlighted_item);
+         if (sd->focused_item)
+           _item_select(sd->focused_item);
 
         goto success;
      }
    else if ((!strcmp(ev->key, "Left")) ||
             ((!strcmp(ev->key, "KP_Left")) && !ev->string))
      {
-        if (!sd->vertical)
-          it = _highlight_next_item_get(obj, sd->bx, EINA_TRUE);
+        if (_item_focused_next(obj, EINA_TRUE, ELM_FOCUS_LEFT))
+          {
+             goto success;
+          }
         else
-          return;
+          {
+             if (ret) *ret = EINA_FALSE;
+             return;
+          }
      }
    else if ((!strcmp(ev->key, "Right")) ||
             ((!strcmp(ev->key, "KP_Right")) && !ev->string))
      {
-        if (!sd->vertical)
-          it = _highlight_next_item_get(obj, sd->bx, EINA_FALSE);
+        if (_item_focused_next(obj, EINA_FALSE, ELM_FOCUS_RIGHT))
+          {
+             goto success;
+          }
         else
-          return;
+          {
+             if (ret) *ret = EINA_FALSE;
+             return;
+          }
      }
    else if ((!strcmp(ev->key, "Up")) ||
             ((!strcmp(ev->key, "KP_Up")) && !ev->string))
      {
-        if (sd->vertical)
-          it = _highlight_next_item_get(obj, sd->bx, EINA_TRUE);
+        if (_item_focused_next(obj, EINA_TRUE, ELM_FOCUS_UP))
+          {
+             goto success;
+          }
         else
-          return;
+          {
+             if (ret) *ret = EINA_FALSE;
+             return;
+          }
      }
    else if ((!strcmp(ev->key, "Down")) ||
             ((!strcmp(ev->key, "KP_Down")) && !ev->string))
      {
-        if (sd->vertical)
-          it = _highlight_next_item_get(obj, sd->bx, EINA_FALSE);
+        if (_item_focused_next(obj, EINA_FALSE, ELM_FOCUS_DOWN))
+          {
+             goto success;
+          }
         else
-          return;
+          {
+             if (ret) *ret = EINA_FALSE;
+             return;
+          }
      }
 
-   if (!it)
-     return;
-
-   if (sd->highlighted_item)
-     edje_object_signal_emit(VIEW(sd->highlighted_item), "elm,highlight,off", 
"elm");
-   sd->highlighted_item = it;
-   edje_object_signal_emit(VIEW(sd->highlighted_item), "elm,highlight,on", 
"elm");
-
-   if (_elm_toolbar_item_coordinates_calc(
-         sd->highlighted_item, ELM_TOOLBAR_ITEM_SCROLLTO_IN, &x, &y, &w, &h))
-     eo_do(obj, elm_interface_scrollable_region_bring_in(x, y, w, h));
-
 success:
    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
    if (ret) *ret = EINA_TRUE;
@@ -907,6 +1089,7 @@ static void
 _item_del(Elm_Toolbar_Item *it)
 {
    Elm_Toolbar_Item_State *it_state;
+   ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
 
    _item_unselect(it);
 
@@ -931,6 +1114,13 @@ _item_del(Elm_Toolbar_Item *it)
         evas_object_del(it->icon);
      }
 
+   if (sd->focused_item == it)
+     sd->focused_item = NULL;
+   if (sd->last_focused_item == it)
+     sd->last_focused_item = NULL;
+   if (sd->prev_focused_item == it)
+     sd->prev_focused_item = NULL;
+
    evas_object_del(it->object);
    //TODO: See if checking for sd->menu_parent is necessary before
    //deleting menu
@@ -1139,6 +1329,20 @@ _sizing_eval(Evas_Object *obj)
 }
 
 static void
+_elm_toolbar_highlight_in_theme(Evas_Object *obj)
+{
+   const char *fh;
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+   fh = edje_object_data_get
+       (wd->resize_obj, "focus_highlight");
+   if ((fh) && (!strcmp(fh, "on")))
+     elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
+   else
+     elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
+}
+
+static void
 _elm_toolbar_smart_theme(Eo *obj, void *_pd, va_list *list)
 {
    Elm_Toolbar_Item *it;
@@ -1188,6 +1392,7 @@ _elm_toolbar_smart_theme(Eo *obj, void *_pd, va_list 
*list)
    if (sd->more_item)
      _item_theme_hook(obj, sd->more_item, scale, sd->icon_size);
 
+   _elm_toolbar_highlight_in_theme(obj);
    _sizing_eval(obj);
 
    if (ret) *ret = EINA_TRUE;
@@ -1856,6 +2061,7 @@ _mouse_down_cb(Elm_Toolbar_Item *it,
    if (ev->button != 1) return;
    if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
      evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
+   sd->mouse_down = EINA_TRUE;
    sd->long_press = EINA_FALSE;
    if (sd->long_timer)
      ecore_timer_interval_set
@@ -1877,7 +2083,11 @@ _mouse_up_cb(Elm_Toolbar_Item *it,
    ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
 
    if (ev->button != 1) return;
+   sd->mouse_down = EINA_FALSE;
    ELM_SAFE_FREE(sd->long_timer, ecore_timer_del);
+   if ((!elm_object_item_disabled_get((Elm_Object_Item *)it)) &&
+       (sd->focused_item != it))
+     elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
    evas_object_event_callback_del_full
      (VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
      (Evas_Object_Event_Cb)_mouse_move_cb, it);
@@ -2089,6 +2299,8 @@ _item_new(Evas_Object *obj,
    elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
    elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
    elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
+   elm_widget_item_focus_set_hook_set(it, _item_focus_set_hook);
+   elm_widget_item_focus_get_hook_set(it, _item_focus_get_hook);
 
    it->label = eina_stringshare_add(label);
    it->prio.visible = 1;
@@ -2570,6 +2782,7 @@ _elm_toolbar_smart_add(Eo *obj, void *_pd, va_list *list 
EINA_UNUSED)
      (priv->bx, EVAS_CALLBACK_RESIZE, _resize_cb, obj);
    elm_toolbar_icon_order_lookup_set(obj, ELM_ICON_LOOKUP_THEME_FDO);
 
+   _elm_toolbar_highlight_in_theme(obj);
    _sizing_eval(obj);
 }
 
@@ -2717,6 +2930,74 @@ _elm_toolbar_smart_access(Eo *obj EINA_UNUSED, void 
*_pd, va_list *list)
    _access_obj_process(sd, _elm_toolbar_smart_focus_next_enable);
 }
 
+static void
+_elm_toolbar_coordinates_adjust(Elm_Toolbar_Item *it,
+                                Evas_Coord *x,
+                                Evas_Coord *y,
+                                Evas_Coord *w,
+                                Evas_Coord *h)
+{
+   ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
+
+   Evas_Coord ix, iy, iw, ih, vx, vy, vw, vh;
+
+   evas_object_geometry_get(sd->hit_rect, &vx, &vy, &vw, &vh);
+   evas_object_geometry_get(VIEW(it), &ix, &iy, &iw, &ih);
+   *x = ix;
+   *y = iy;
+   *w = iw;
+   *h = ih;
+   if (sd->vertical)
+     {
+        //TODO: Enhance it later.
+        if ((ix < vx) || (ix + iw) > (vx + vw) || (iy + ih) > (vy + vh))
+          *y = iy - ih;
+        else if (iy < vy)
+          *y = iy + ih;
+     }
+   else
+     {
+        //TODO: Enhance it later.
+        if ((iy < vy) || (ix + iw) > (vx + vw) || (iy + ih) > (vy + vh))
+          *x = ix - iw;
+        else if (ix < vx)
+          *x = ix + iw;
+     }
+}
+
+static void
+_elm_toolbar_focus_highlight_geometry_get(Eo *obj EINA_UNUSED, void *_pd, 
va_list *list)
+{
+   Evas_Coord *x = va_arg(*list, Evas_Coord *);
+   Evas_Coord *y = va_arg(*list, Evas_Coord *);
+   Evas_Coord *w = va_arg(*list, Evas_Coord *);
+   Evas_Coord *h = va_arg(*list, Evas_Coord *);
+   Eina_Bool is_next = va_arg(*list, int);
+
+   Elm_Toolbar_Smart_Data *sd = _pd;
+
+   if (is_next)
+     {
+        if (sd->focused_item)
+          {
+             _elm_toolbar_coordinates_adjust
+                (sd->focused_item, x, y, w, h);
+             elm_widget_focus_highlight_focus_part_geometry_get
+                (VIEW(sd->focused_item), x, y, w, h);
+          }
+     }
+   else
+     {
+        if (sd->prev_focused_item)
+          {
+             _elm_toolbar_coordinates_adjust
+                (sd->prev_focused_item, x, y, w, h);
+             elm_widget_focus_highlight_focus_part_geometry_get
+                (VIEW(sd->prev_focused_item), x, y, w, h);
+          }
+     }
+}
+
 EAPI Evas_Object *
 elm_toolbar_add(Evas_Object *parent)
 {
@@ -3951,6 +4232,15 @@ elm_toolbar_item_bring_in(Elm_Object_Item *it, 
Elm_Toolbar_Item_Scrollto_Type ty
 }
 
 static void
+_elm_toolbar_focused_item_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list)
+{
+   Elm_Object_Item **ret = va_arg(*list, Elm_Object_Item **);
+   Elm_Toolbar_Smart_Data *sd = _pd;
+
+   if (ret) *ret = (Elm_Object_Item *)sd->focused_item;
+}
+
+static void
 _class_constructor(Eo_Class *klass)
 {
    const Eo_Op_Func_Description func_desc[] = {
@@ -3969,6 +4259,8 @@ _class_constructor(Eo_Class *klass)
         
EO_OP_FUNC(ELM_OBJ_WIDGET_ID(ELM_OBJ_WIDGET_SUB_ID_FOCUS_NEXT_MANAGER_IS), 
_elm_toolbar_smart_focus_next_manager_is),
         EO_OP_FUNC(ELM_OBJ_WIDGET_ID(ELM_OBJ_WIDGET_SUB_ID_FOCUS_NEXT), 
_elm_toolbar_smart_focus_next),
         EO_OP_FUNC(ELM_OBJ_WIDGET_ID(ELM_OBJ_WIDGET_SUB_ID_ACCESS), 
_elm_toolbar_smart_access),
+        
EO_OP_FUNC(ELM_OBJ_WIDGET_ID(ELM_OBJ_WIDGET_SUB_ID_FOCUS_HIGHLIGHT_GEOMETRY_GET),
 _elm_toolbar_focus_highlight_geometry_get),
+        EO_OP_FUNC(ELM_OBJ_WIDGET_ID(ELM_OBJ_WIDGET_SUB_ID_FOCUSED_ITEM_GET), 
_elm_toolbar_focused_item_get),
 
         EO_OP_FUNC(ELM_OBJ_TOOLBAR_ID(ELM_OBJ_TOOLBAR_SUB_ID_ICON_SIZE_SET), 
_icon_size_set),
         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 818ba88..d80deda 100644
--- a/src/lib/elm_toolbar.h
+++ b/src/lib/elm_toolbar.h
@@ -31,6 +31,8 @@
  * - @c "language,changed" - when the program language changes.
  * - @c "focused" - When the toolbar has received focus. (since 1.8)
  * - @c "unfocused" - When the toolbar has lost focus. (since 1.8)
+ * - @c "item,focused" - When the toolbar item has received focus. (since 1.10)
+ * - @c "item,unfocused" - When the toolbar item has lost focus. (since 1.10)
  *
  * Available styles for it:
  * - @c "default"
@@ -48,6 +50,8 @@
  * @li @ref elm_object_item_part_content_set
  * @li @ref elm_object_item_part_content_get
  * @li @ref elm_object_item_part_content_unset
+ * @li @ref elm_object_item_focus_set
+ * @li @ref elm_object_item_focus_get
  *
  * List of examples:
  * @li @ref toolbar_example_01
diff --git a/src/lib/elm_widget_toolbar.h b/src/lib/elm_widget_toolbar.h
index 9c731ea..381dba3 100644
--- a/src/lib/elm_widget_toolbar.h
+++ b/src/lib/elm_widget_toolbar.h
@@ -29,7 +29,9 @@ struct _Elm_Toolbar_Smart_Data
    Eina_Inlist                          *items;
    Elm_Toolbar_Item                     *more_item;
    Elm_Toolbar_Item                     *selected_item; /**< a selected item 
by mouse click, return key, api, and etc. */
-   Elm_Toolbar_Item                     *highlighted_item; /**< a highlighted 
item by keypard arrow */
+   Elm_Toolbar_Item                     *focused_item; /**< a focused item by 
keypad arrow or mouse. This is set to NULL if widget looses focus. */
+   Elm_Toolbar_Item                     *prev_focused_item; /**< previous 
focused item by keypad arrow or mouse. */
+   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. */
    Elm_Toolbar_Item                     *reorder_empty, *reorder_item;
    Elm_Toolbar_Shrink_Mode               shrink_mode;
    Elm_Icon_Lookup_Order                 lookup_order;
@@ -49,6 +51,7 @@ struct _Elm_Toolbar_Smart_Data
    Eina_Bool                             delete_me : 1;
    Eina_Bool                             reorder_mode : 1;
    Eina_Bool                             transverse_expanded : 1;
+   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. */
 };
 
 struct _Elm_Toolbar_Item

-- 


Reply via email to