focus: change the focus don't stay to scroller.
authorJaehwan Kim <jae.hwan.kim@samsung.com>
Fri, 25 Sep 2015 06:34:34 +0000 (15:34 +0900)
committerJaehwan Kim <jae.hwan.kim@samsung.com>
Fri, 25 Sep 2015 06:45:03 +0000 (15:45 +0900)
The focus go to scroller only when it needs.
If the focusable object isn't in the current viewport of the scroller,
the scroller should have the focus.
If not, the focus move to the focusable object in the scroller.

@feature.

legacy/elementary/src/lib/elm_scroller.c
legacy/elementary/src/lib/elm_scroller.eo

index 59c9a4a..1b5011c 100644 (file)
@@ -180,23 +180,9 @@ _key_action_move(Evas_Object *obj, const char *params)
 
         if (r && new_focus)
           {
-             Evas_Coord l_x = 0;
-             Evas_Coord l_y = 0;
-             Evas_Coord l_w = 0;
-             Evas_Coord l_h = 0;
-
-             evas_object_geometry_get(new_focus, &f_x, &f_y, &f_w, &f_h);
-             l_x = f_x - c_x - step_x;
-             l_y = f_y - c_y - step_y;
-             l_w = f_w + (step_x * 2);
-             l_h = f_h + (step_y * 2);
-
-             if (ELM_RECTS_INTERSECT(x, y, v_w, v_h, l_x, l_y, l_w, l_h))
-               {
-                  elm_widget_focus_steal(new_focus, new_focus_item);
-                  eina_list_free(can_focus_list);
-                  return EINA_TRUE;
-               }
+             elm_widget_focus_steal(new_focus, new_focus_item);
+             eina_list_free(can_focus_list);
+             return EINA_TRUE;
           }
      }
 
@@ -435,13 +421,33 @@ _elm_scroller_elm_widget_focus_next(Eo *obj EINA_UNUSED, Elm_Scroller_Data *sd,
      }
 
    /* Try focus cycle in subitem */
-   if (elm_widget_focus_get(obj))
+   if ((elm_widget_can_focus_get(cur)) ||
+       (elm_widget_child_can_focus_get(cur)))
      {
-        if ((elm_widget_can_focus_get(cur)) ||
-            (elm_widget_child_can_focus_get(cur)))
-          {
-             return elm_widget_focus_next_get(cur, dir, next, next_item);
-          }
+        Eina_Bool ret = EINA_FALSE;
+        Evas_Coord x = 0, y = 0;
+        Evas_Coord v_w = 0, v_h = 0;
+        Evas_Coord c_x = 0, c_y = 0;
+        Evas_Coord f_x = 0, f_y = 0, f_w = 0, f_h = 0;
+        Evas_Coord l_x = 0, l_y = 0, l_w = 0, l_h = 0;
+        Evas_Coord step_x = 0, step_y = 0;
+
+        ret =  elm_widget_focus_next_get(cur, dir, next, next_item);
+
+        eo_do(obj,
+              elm_interface_scrollable_content_pos_get(&x, &y),
+              elm_interface_scrollable_step_size_get(&step_x, &step_y),
+              elm_interface_scrollable_content_viewport_geometry_get
+              (NULL, NULL, &v_w, &v_h));
+        evas_object_geometry_get(sd->content, &c_x, &c_y, NULL, NULL);
+        evas_object_geometry_get(*next, &f_x, &f_y, &f_w, &f_h);
+        l_x = f_x - c_x - step_x;
+        l_y = f_y - c_y - step_y;
+        l_w = f_w + (step_x * 2);
+        l_h = f_h + (step_y * 2);
+
+        if (!ret || ELM_RECTS_INTERSECT(x, y, v_w, v_h, l_x, l_y, l_w, l_h))
+          return ret;
      }
 
    /* Return */
@@ -453,7 +459,64 @@ _elm_scroller_elm_widget_focus_next(Eo *obj EINA_UNUSED, Elm_Scroller_Data *sd,
 EOLIAN static Eina_Bool
 _elm_scroller_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Scroller_Data *_pd EINA_UNUSED)
 {
-   return EINA_FALSE;
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_elm_scroller_elm_widget_focus_direction(Eo *obj, Elm_Scroller_Data *sd, const Evas_Object *base, double degree, Evas_Object **direction, Elm_Object_Item **direction_item, double *weight)
+{
+   Evas_Object *cur;
+
+   if (!sd->content) return EINA_FALSE;
+
+   cur = sd->content;
+
+   /* access */
+   if (_elm_config->access_mode)
+     {
+        if ((elm_widget_can_focus_get(cur)) ||
+            (elm_widget_child_can_focus_get(cur)))
+          {
+             return elm_widget_focus_direction_get(cur, base, degree, direction, direction_item, weight);
+          }
+
+        return EINA_FALSE;
+     }
+
+   /* Try focus cycle in subitem */
+   if ((elm_widget_can_focus_get(cur)) ||
+       (elm_widget_child_can_focus_get(cur)))
+     {
+        Eina_Bool ret = EINA_FALSE;
+        Evas_Coord x = 0, y = 0;
+        Evas_Coord v_w = 0, v_h = 0;
+        Evas_Coord c_x = 0, c_y = 0;
+        Evas_Coord f_x = 0, f_y = 0, f_w = 0, f_h = 0;
+        Evas_Coord l_x = 0, l_y = 0, l_w = 0, l_h = 0;
+        Evas_Coord step_x = 0, step_y = 0;
+
+        ret = elm_widget_focus_direction_get(cur, base, degree, direction, direction_item, weight);
+
+        eo_do(obj,
+              elm_interface_scrollable_content_pos_get(&x, &y),
+              elm_interface_scrollable_step_size_get(&step_x, &step_y),
+              elm_interface_scrollable_content_viewport_geometry_get
+              (NULL, NULL, &v_w, &v_h));
+        evas_object_geometry_get(sd->content, &c_x, &c_y, NULL, NULL);
+        evas_object_geometry_get(*direction, &f_x, &f_y, &f_w, &f_h);
+        l_x = f_x - c_x - step_x;
+        l_y = f_y - c_y - step_y;
+        l_w = f_w + (step_x * 2);
+        l_h = f_h + (step_y * 2);
+
+        if (!ret || ELM_RECTS_INTERSECT(x, y, v_w, v_h, l_x, l_y, l_w, l_h))
+          return ret;
+     }
+
+   /* Return */
+   *direction = (Evas_Object *)obj;
+
+   return !elm_widget_focus_get(obj);
 }
 
 static void
index 17263e8..3dfacc6 100644 (file)
@@ -103,6 +103,7 @@ class Elm.Scroller (Elm.Layout, Elm_Interface_Scrollable,
       Elm.Widget.focus_next_manager_is;
       Elm.Widget.focus_direction_manager_is;
       Elm.Widget.focus_next;
+      Elm.Widget.focus_direction;
       Elm.Widget.sub_object_del;
       Elm.Widget.event;
       Elm.Container.content_get;