Optimized Linear Focus Chain
authorTiago Rezende Campos Falcao <developer@tiagofalcao.com>
Wed, 6 Oct 2010 20:24:09 +0000 (20:24 +0000)
committerTiago Rezende Campos Falcao <developer@tiagofalcao.com>
Wed, 6 Oct 2010 20:24:09 +0000 (20:24 +0000)
Before, the focus_cycle try pass the focus to next, and try again if
need loop the objects. Now, the focus cycle return possible next
object and if is necessary loop or not to focus this returned object.

SVN revision: 53111

14 files changed:
src/bin/test_focus.c
src/lib/elm_box.c
src/lib/elm_bubble.c
src/lib/elm_flip.c
src/lib/elm_frame.c
src/lib/elm_layout.c
src/lib/elm_pager.c
src/lib/elm_panel.c
src/lib/elm_panes.c
src/lib/elm_scroller.c
src/lib/elm_table.c
src/lib/elm_widget.c
src/lib/elm_widget.h
src/lib/elm_win.c

index 2b6988b670d5fd9855d4b3f390d1029e439cf458..e0dd34df16fde4646d6483f80aa907c815e0b548 100644 (file)
@@ -321,37 +321,5 @@ test_focus(void *data, Evas_Object *obj, void *event_info)
                }
           }
      }
-
-     { //Panel
-        Evas_Object *panel = elm_panel_add(win);
-        elm_panel_orient_set(panel, ELM_PANEL_ORIENT_LEFT);
-        evas_object_size_hint_weight_set(panel, EVAS_HINT_EXPAND,
-                                         EVAS_HINT_EXPAND);
-        evas_object_size_hint_align_set(panel, EVAS_HINT_FILL, EVAS_HINT_FILL);
-        elm_win_resize_object_add(win, panel);
-        my_show(panel);
-        elm_panel_hidden_set(panel, EINA_TRUE);
-
-          {
-             Evas_Object *bx2 = elm_box_add(win);
-             evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND,
-                                              EVAS_HINT_EXPAND);
-             elm_panel_content_set(panel, bx2);
-             my_show(bx2);
-
-             for (i = 3; i; i--)
-               {
-                  Evas_Object *bt;
-                  bt = elm_button_add(win);
-                  elm_button_label_set(bt, "Panel");
-                  evas_object_size_hint_align_set(bt, EVAS_HINT_FILL,
-                                                  EVAS_HINT_FILL);
-                  evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND,
-                                                   EVAS_HINT_EXPAND);
-                  elm_box_pack_end(bx2, bt);
-                  my_show(bt);
-               }
-          }
-     }
 }
 
index 626f29c57da83d7b1ebac8dfecdca987ed8e2c86..9ac5d43cd8d455b84eb9e4b06a4349d2741778dc 100644 (file)
@@ -94,12 +94,11 @@ _elm_box_list_data_get(const Eina_List *list)
 }
 
 static Eina_Bool
-_elm_box_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circular)
+_elm_box_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    Eina_List *items;
    void *(*list_data_get) (const Eina_List *list);
-   Evas_Object *last_focused;
 
    if ((!wd) || (!wd->box))
      return EINA_FALSE;
@@ -122,10 +121,7 @@ _elm_box_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool c
         if (!items) return EINA_FALSE;
      }
 
-   last_focused = 
-     elm_widget_focus_cycle_next_get(obj, items, list_data_get, dir, circular);
-
-   return !!last_focused;
+   return elm_widget_focus_cycle_next_get(obj, items, list_data_get, dir, next);
 }
 
 static void
index 3700e5747ab4c9a7ebcfb881191eaf60ff3c4ca8..1aadfd1a8b3dd0a7864816970ba2640d6f730db8 100644 (file)
@@ -55,7 +55,7 @@ _theme_hook(Evas_Object *obj)
 }
 
 static Eina_Bool
-_elm_bubble_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circular)
+_elm_bubble_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    Evas_Object *cur;
@@ -66,7 +66,7 @@ _elm_bubble_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Boo
    cur = wd->content;
 
    /* Try Focus cycle in subitem */
-   return elm_widget_focus_cycle(cur, dir, circular);
+   return elm_widget_focus_cycle(cur, dir, next);
 }
 
 static void
index 07f4f5260af06118b1a1e2da8d15076193a5d845..75114f1488c2afebcb0a785afb848fc71da03a3a 100644 (file)
@@ -59,7 +59,7 @@ _theme_hook(Evas_Object *obj)
 }
 
 static Eina_Bool
-_elm_flip_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circular)
+_elm_flip_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
 
@@ -68,9 +68,9 @@ _elm_flip_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool
 
    /* Try Focus cycle in subitem */
    if (wd->state)
-     return elm_widget_focus_cycle(wd->front.content, dir, circular);
+     return elm_widget_focus_cycle(wd->front.content, dir, next);
    else
-     return elm_widget_focus_cycle(wd->back.content, dir, circular);
+     return elm_widget_focus_cycle(wd->back.content, dir, next);
 
 }
 
index fdb93740762595701dc4acf404dde616dc504eed..107e0411f8cbd11df4c4d6010fba094861ef1a10 100644 (file)
@@ -47,7 +47,7 @@ _theme_hook(Evas_Object *obj)
 }
 
 static Eina_Bool
-_elm_frame_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circular)
+_elm_frame_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    Evas_Object *cur;
@@ -58,7 +58,7 @@ _elm_frame_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool
    cur = wd->content;
 
    /* Try Focus cycle in subitem */
-   return elm_widget_focus_cycle(cur, dir, circular);
+   return elm_widget_focus_cycle(cur, dir, next);
 }
 
 static void
index 7124e1ed5c2fa67c237afcf48f12f97238c3585c..de8d5420cb11b94841b1f2f3f599467e40755df3 100644 (file)
@@ -93,12 +93,11 @@ _elm_layout_list_data_get(const Eina_List *list)
 }
 
 static Eina_Bool
-_elm_layout_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circular)
+_elm_layout_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    Eina_List *items;
    void *(*list_data_get) (const Eina_List *list);
-   Evas_Object *last_focused;
 
    if ((!wd) || (!wd->subs))
      return EINA_FALSE;
@@ -120,11 +119,8 @@ _elm_layout_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Boo
         if (!items) return EINA_FALSE;
      }
 
-   last_focused = elm_widget_focus_cycle_next_get(obj, items,
-                                                  list_data_get, dir,
-                                                  circular);
-
-   return !!last_focused;
+   return elm_widget_focus_cycle_next_get(obj, items, list_data_get, dir,
+                                          next);
 }
 
 static void
index 3a4e1fdbde018ecb64639b321c78e372d72d505d..29c8887b66c9dee6298a869d9035e91ca43dd907 100644 (file)
@@ -66,7 +66,7 @@ _theme_hook(Evas_Object *obj)
 }
 
 static Eina_Bool
-_elm_pager_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circular)
+_elm_pager_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    Evas_Object *cur;
@@ -77,7 +77,7 @@ _elm_pager_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool
    cur = wd->top->content;
 
    /* Try Focus cycle in subitem */
-   return elm_widget_focus_cycle(cur, dir, circular);
+   return elm_widget_focus_cycle(cur, dir, next);
 }
 
 static void
index 6200aecc0db858248f8e3346756102df74d90185..c6ce4a22c2a91a28d503a0a95ede6171d4fcf0d9 100644 (file)
@@ -78,7 +78,7 @@ _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
 }
 
 static Eina_Bool
-_elm_panel_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circular)
+_elm_panel_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    Evas_Object *cur;
@@ -89,14 +89,12 @@ _elm_panel_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool
    cur = wd->content;
 
    /* Try Focus cycle in subitem */
-   if ((!wd->hidden) && elm_widget_focus_cycle(cur, dir, circular))
-     return EINA_TRUE;
-   /* Ignore is previous focused */
-   if (elm_widget_focus_get(obj) && (!circular))
-     return EINA_FALSE;
-   /* Get Focus*/
-   elm_widget_focus_steal(obj);
-   return EINA_TRUE;
+   if (!wd->hidden)
+      return elm_widget_focus_cycle(cur, dir, next);
+
+   /* Return */
+   *next = obj;
+   return !elm_widget_focus_get(obj);
 }
 
 static void
index 5f4039f61a9af60b8b13aac4a4480b9fa8d7e1fa..392310fab78892329b9125141315cfc575f6b7d6 100644 (file)
@@ -70,7 +70,7 @@ _theme_hook(Evas_Object *obj)
 }
 
 static Eina_Bool
-_elm_panes_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circular)
+_elm_panes_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
 
@@ -80,7 +80,7 @@ _elm_panes_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool
    double w, h;
    edje_object_part_drag_value_get(wd->panes, "elm.bar", &w, &h);
    if ((wd->horizontal && ( h == 0.0 )) || ((!wd->horizontal) && ( w == 0.0 )))
-     return elm_widget_focus_cycle(wd->contents.right, dir, circular);
+     return elm_widget_focus_cycle(wd->contents.right, dir, next);
 
    Evas_Object *chain[2];
 
@@ -98,19 +98,30 @@ _elm_panes_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool
    else
      return EINA_FALSE;
 
-   unsigned int i;
-
-   for ( i = (unsigned int) elm_widget_focus_get(chain[1]); i < 2; i++ )
-     if (elm_widget_focus_cycle(chain[i], dir, EINA_FALSE))
-       return EINA_TRUE;
-
-   if (!circular)
-     return EINA_FALSE;
-
-   if (elm_widget_focus_cycle(chain[0], dir, EINA_TRUE))
-     return EINA_TRUE;
-
-   return elm_widget_focus_cycle(chain[1], dir, EINA_TRUE);
+   if (elm_widget_focus_get(chain[1]))
+     {
+        Evas_Object *to_focus;
+        if (elm_widget_focus_cycle(chain[1], dir, next))
+          return EINA_TRUE;
+        elm_widget_focus_cycle(chain[0], dir, &to_focus);
+        if (to_focus)
+          *next = to_focus;
+        return EINA_FALSE;
+     }
+   else
+     {
+        Evas_Object *to_focus;
+        if (elm_widget_focus_cycle(chain[0], dir, next))
+          return EINA_TRUE;
+        if (elm_widget_focus_cycle(chain[1], dir, &to_focus))
+          {
+             *next = to_focus;
+             return EINA_TRUE;
+          }
+        if (!(*next))
+          *next = to_focus;
+        return EINA_FALSE;
+     }
 }
 
 static void
index 500161f09f3fa06145e0f9bee6e73366baa1e611..20e77bef3f9acbc303ed3f071a1336445b61d06c 100644 (file)
@@ -198,7 +198,7 @@ _theme_hook(Evas_Object *obj)
 }
 
 static Eina_Bool
-_elm_scroller_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circular)
+_elm_scroller_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    Evas_Object *cur;
@@ -209,17 +209,12 @@ _elm_scroller_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_B
    cur = wd->content;
 
    /* Try Focus cycle in subitem */
-   if (elm_widget_focus_cycle(cur, dir, circular))
-     return EINA_TRUE;
-   /* Abort if content is focusable */
    if (elm_widget_can_focus_get(cur) || elm_widget_child_can_focus_get(cur))
-     return EINA_FALSE;
-   /* Ignore is previous focused */
-   if (elm_widget_focus_get(obj) && (!circular))
-     return EINA_FALSE;
-   /* Get Focus*/
-   elm_widget_focus_steal(obj);
-   return EINA_TRUE;
+      return elm_widget_focus_cycle(cur, dir, next);
+
+   /* Return */
+   *next = obj;
+   return !elm_widget_focus_get(obj);
 }
 
 static void
index 0b85c28feda7676b8a335f40b9e09edcf043e0bc..8c1e86f83dc50e451ad8b169e2f638935c184a86 100644 (file)
@@ -41,13 +41,12 @@ _del_hook(Evas_Object *obj)
 }
 
 static Eina_Bool
-_elm_table_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circular)
+_elm_table_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    Eina_List *items;
    void *(*list_data_get) (const Eina_List *list);
    Eina_List *(*list_free) (Eina_List *list);
-   Evas_Object *last_focused;
 
    if ((!wd) || (!wd->tbl))
      return EINA_FALSE;
@@ -71,14 +70,13 @@ _elm_table_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool
         if (!items) return EINA_FALSE;
      }
 
-   last_focused = elm_widget_focus_cycle_next_get(obj, items,
-                                                  list_data_get, dir,
-                                                  circular);
+   Eina_Bool ret = elm_widget_focus_cycle_next_get(obj, items, list_data_get,
+                                                   dir, next);
 
    if (list_free)
      items = list_free(items);
 
-   return !!last_focused;
+   return ret;
 }
 
 static void
index 303e87f7abfebb1e27b3a2ee15be4ba899dfcf54..d2fb120e6a3759013f466bea1d865ecc2837729c 100644 (file)
@@ -42,7 +42,7 @@ struct _Smart_Data
    void         (*changed_func) (Evas_Object *obj);
    Eina_Bool    (*focus_cycle_func) (Evas_Object *obj,
                                      Elm_Focus_Direction dir,
-                                     Eina_Bool circular);
+                                     Evas_Object **next);
    void         (*on_focus_func) (void *data, Evas_Object *obj);
    void          *on_focus_data;
    void         (*on_change_func) (void *data, Evas_Object *obj);
@@ -70,6 +70,11 @@ struct _Smart_Data
    Eina_Bool      highlight_ignore : 1;
    Eina_Bool      highlight_in_theme : 1;
    Eina_Bool      disabled : 1;
+
+   struct
+     {
+        Eina_List *custom_linear_chain;
+     } focus;
 };
 
 /* local subsystem functions */
@@ -400,7 +405,7 @@ elm_widget_theme(Evas_Object *obj)
 }
 
 EAPI void
-elm_widget_focus_cycle_hook_set(Evas_Object *obj, Eina_Bool (*func) (Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circular))
+elm_widget_focus_cycle_hook_set(Evas_Object *obj, Eina_Bool (*func) (Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next))
 {
    API_ENTRY return;
    sd->focus_cycle_func = func;
@@ -746,8 +751,12 @@ elm_widget_parent_event_propagate(Evas_Object *obj, Evas_Callback_Type type, voi
 }
 
 EAPI Eina_Bool
-elm_widget_focus_cycle(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circular)
+elm_widget_focus_cycle(Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
 {
+   if (!next)
+     return EINA_FALSE;
+   *next = NULL;
+
    API_ENTRY return EINA_FALSE;
 
    /* Ignore if disabled */
@@ -756,75 +765,94 @@ elm_widget_focus_cycle(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circ
 
    /* Try use hook */
    if (sd->focus_cycle_func)
-     return sd->focus_cycle_func(obj, dir, circular);
+     return sd->focus_cycle_func(obj, dir, next);
 
-   /* Ignore if previous focused*/
-   if ((!elm_widget_can_focus_get(obj)) || (elm_widget_focus_get(obj) && (!circular)))
+   if (!elm_widget_can_focus_get(obj))
      return EINA_FALSE;
 
-   /* Get focus*/
-   elm_widget_focus_steal(obj);
-   return EINA_TRUE;
+   /* Return */
+   *next = obj;
+   return !elm_widget_focus_get(obj);
 }
 
-EAPI Evas_Object *
-elm_widget_focus_cycle_next_get(Evas_Object *obj, Eina_List *items, void *(*list_data_get) (const Eina_List *list), Elm_Focus_Direction dir, Eina_Bool circular)
+EAPI Eina_Bool
+elm_widget_focus_cycle_next_get(Evas_Object *obj, Eina_List *items, void *(*list_data_get) (const Eina_List *list), Elm_Focus_Direction dir, Evas_Object **next)
 {
-   Eina_List *list = NULL;
-   Eina_List *l = NULL;
-   Evas_Object *cur = NULL;
    Eina_List *(*list_next) (const Eina_List *list);
-   Eina_Bool child_circular;
+
+   if (!next)
+     return EINA_FALSE;
+   *next = NULL;
 
    if (!items)
-     return NULL;
+     return EINA_FALSE;
 
    /* Direction */
    if (dir == ELM_FOCUS_PREVIOUS)
      {
-        list = eina_list_last(items);
+        items = eina_list_last(items);
         list_next = eina_list_prev;
      }
    else if (dir == ELM_FOCUS_NEXT)
      {
-        list = items;
+        items= items;
         list_next = eina_list_next;
      }
    else
-     return NULL;
+     return EINA_FALSE;
+
+   Eina_List *l = items;
 
    /* Recovery last focused sub item */
    if (elm_widget_focus_get(obj))
-     for (l = items; l; l = eina_list_next(l))
+     for (; l; l = list_next(l))
        {
-          cur = list_data_get(l);
+          Evas_Object *cur = list_data_get(l);
           if (elm_widget_focus_get(cur))
-            break;
+            {
+               break;
+            }
        }
 
+   Eina_List *start = l;
+   Evas_Object *to_focus = NULL;
+
    /* Interate sub items */
-   child_circular = EINA_FALSE;
-   do {
-        if (!l)
-          l = list;
+   /* Go to end of list */
+   for (;l; l = list_next(l))
+     {
+        Evas_Object *tmp = NULL;
+        Evas_Object *cur = list_data_get(l);
 
-        for (;l; l = list_next(l))
+        /* Try Focus cycle in subitem */
+        if (elm_widget_focus_cycle(cur, dir, &tmp))
           {
-             cur = list_data_get(l);
-
-             /* Try Focus cycle in subitem */
-             if (elm_widget_focus_cycle(cur, dir, child_circular))
-               break;
+             *next = tmp;
+             return EINA_TRUE;
           }
-        circular = circular && (!child_circular);
-        child_circular = !child_circular;
-   }
-   while ((!l) && circular);
+        else if (tmp && (!to_focus))
+          to_focus = tmp;
+     }
 
-   if (l)
-     return cur;
+   l = items;
 
-   return NULL;
+   /* Get First possible */
+   for (;l != start; l = list_next(l))
+     {
+        Evas_Object *tmp = NULL;
+        Evas_Object *cur = list_data_get(l);
+
+        /* Try Focus cycle in subitem */
+        elm_widget_focus_cycle(cur, dir, &tmp);
+        if (tmp)
+          {
+             *next = tmp;
+             return EINA_FALSE;
+          }
+     }
+
+   *next = to_focus;
+   return EINA_FALSE;
 }
 
 EAPI int
index 88eef521faf3d312acb162c65dca9b513cbb317c..573570ce06542c675f472bd037bede467f565dcc 100644 (file)
@@ -225,7 +225,7 @@ EAPI void             elm_widget_signal_emit_hook_set(Evas_Object *obj, void (*f
 EAPI void             elm_widget_signal_callback_add_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data));
 EAPI void             elm_widget_signal_callback_del_hook_set(Evas_Object *obj, void *(*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source)));
 EAPI void             elm_widget_theme(Evas_Object *obj);
-EAPI void             elm_widget_focus_cycle_hook_set(Evas_Object *obj, Eina_Bool (*func) (Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circular));
+EAPI void             elm_widget_focus_cycle_hook_set(Evas_Object *obj, Eina_Bool (*func) (Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next));
 EAPI void             elm_widget_on_focus_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data);
 EAPI void             elm_widget_on_change_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data);
 EAPI void             elm_widget_on_show_region_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data);
@@ -251,8 +251,8 @@ EAPI Evas_Object     *elm_widget_top_get(const Evas_Object *obj);
 EAPI Eina_Bool        elm_widget_is(const Evas_Object *obj);
 EAPI Evas_Object     *elm_widget_parent_widget_get(const Evas_Object *obj);
 EAPI Eina_Bool        elm_widget_parent_event_propagate(Evas_Object *obj, Evas_Callback_Type type, void *event_info);
-EAPI Eina_Bool        elm_widget_focus_cycle(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circular);
-EAPI Evas_Object     *elm_widget_focus_cycle_next_get(Evas_Object *obj, Eina_List *items, void *(*list_data_get) (const Eina_List *list), Elm_Focus_Direction dir, Eina_Bool circular);
+EAPI Eina_Bool        elm_widget_focus_cycle(Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next);
+EAPI Eina_Bool        elm_widget_focus_cycle_next_get(Evas_Object *obj, Eina_List *items, void *(*list_data_get) (const Eina_List *list), Elm_Focus_Direction dir, Evas_Object **next);
 EAPI int              elm_widget_focus_jump(Evas_Object *obj, int forward);
 EAPI void             elm_widget_focus_set(Evas_Object *obj, int first);
 EAPI void             elm_widget_focused_object_clear(Evas_Object *obj);
index bd5626147c70286e79dbaddc7d3fac89d53b7c3d..0b470eb02554639caa88364188ed17d37712ac21 100644 (file)
@@ -136,28 +136,25 @@ _elm_win_focus_out(Ecore_Evas *ee)
 }
 
 static Eina_Bool
-_elm_win_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circular __UNUSED__)
+_elm_win_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
 {
    Elm_Win *wd = elm_widget_data_get(obj);
    Eina_List *items;
    void *(*list_data_get) (const Eina_List *list);
-   Evas_Object *last_focused;
 
    if ((!wd) || (!wd->subobjs))
      return EINA_FALSE;
 
-   circular = EINA_TRUE;
-
    /* Focus chain */
    /* TODO: Change this to use other chain */
    items = wd->subobjs;
    list_data_get = eina_list_data_get;
 
-   last_focused = elm_widget_focus_cycle_next_get(obj, items,
-                                                      list_data_get, dir,
-                                                      circular);
+   elm_widget_focus_cycle_next_get(obj, items, list_data_get, dir, next);
 
-   return !!last_focused;
+   if (*next)
+     return EINA_TRUE;
+   return EINA_FALSE;
 }
 
 static Eina_Bool
@@ -168,10 +165,13 @@ _elm_win_event_cb(Evas_Object *obj, Evas_Object *src, Evas_Callback_Type type, v
         Evas_Event_Key_Down *ev = event_info;
         if (!strcmp(ev->keyname, "Tab"))
           {
+             Evas_Object *target;
              if(evas_key_modifier_is_set(ev->modifiers, "Shift"))
-               elm_widget_focus_cycle(obj, ELM_FOCUS_PREVIOUS, EINA_TRUE);
+               elm_widget_focus_cycle(obj, ELM_FOCUS_PREVIOUS, &target);
              else
-               elm_widget_focus_cycle(obj, ELM_FOCUS_NEXT, EINA_TRUE);
+               elm_widget_focus_cycle(obj, ELM_FOCUS_NEXT, &target);
+             if (target)
+               elm_widget_focus_steal(target);
              return EINA_TRUE;
           }
      }
@@ -2126,7 +2126,7 @@ _theme_hook(Evas_Object *obj)
 }
 
 static Eina_Bool
-_elm_inwin_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool circular __UNUSED__)
+_elm_inwin_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    Evas_Object *cur;
@@ -2137,7 +2137,10 @@ _elm_inwin_focus_cycle_hook(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool
    cur = wd->content;
 
    /* Try Focus cycle in subitem */
-   return elm_widget_focus_cycle(cur, dir, EINA_TRUE);
+   elm_widget_focus_cycle(cur, dir, next);
+   if (*next)
+     return EINA_TRUE;
+   return EINA_FALSE;
 }
 
 static void