efl_ui_focus_manager: select the widget with the smallest distance
authorMarcel Hollerbach <marcel-hollerbach@t-online.de>
Thu, 20 Apr 2017 08:15:53 +0000 (10:15 +0200)
committerMarcel Hollerbach <marcel-hollerbach@t-online.de>
Thu, 20 Apr 2017 12:38:59 +0000 (14:38 +0200)
this improves the correctness-feeling when moving focus through a
elementary application.

src/lib/elementary/efl_ui_focus_manager.c

index 41a5beeb1cb5aa5a9aba21e5ba027768cbed2427..abed31ad966eff9c5e5296a91f8e18057dd60c70 100644 (file)
@@ -916,6 +916,16 @@ _no_history_element(Eina_Hash *node_hash)
    return upper;
 }
 
+static void
+_get_middle(Evas_Object *obj, Eina_Vector2 *elem)
+{
+   Eina_Rectangle geom;
+
+   evas_object_geometry_get(obj, &geom.x, &geom.y, &geom.w, &geom.h);
+   elem->x = geom.x + geom.w/2;
+   elem->y = geom.y + geom.h/2;
+}
+
 static Node*
 _coords_movement(Efl_Ui_Focus_Manager_Data *pd, Node *upper, Efl_Ui_Focus_Direction direction)
 {
@@ -932,9 +942,30 @@ _coords_movement(Efl_Ui_Focus_Manager_Data *pd, Node *upper, Efl_Ui_Focus_Direct
           }
      }
 
-   //if we havent found anything in the history, just use the first partner ... we have to start somewhere
-   //FIXME maybe decide coordinate wise?
-   return eina_list_data_get(G(upper).directions[direction].partners);
+   //if we havent found anything in the history, use the widget with the smallest distance
+   {
+      Eina_List *lst = G(upper).directions[direction].partners;
+      Eina_List *n;
+      Node *node, *min = NULL;
+      Eina_Vector2 elem, other;
+      float min_distance = 0.0;
+
+
+      _get_middle(upper->focusable, &elem);
+
+      EINA_LIST_FOREACH(lst, n, node)
+        {
+           _get_middle(node->focusable, &other);
+           float tmp = eina_vector2_distance_get(&other, &elem);
+           if (!min || tmp < min_distance)
+             {
+                min = node;
+                min_distance = tmp;
+             }
+        }
+      candidate = min;
+   }
+   return candidate;
 }
 
 
@@ -1380,4 +1411,4 @@ _efl_ui_focus_manager_logical_end(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Data
   return child ? child->focusable : NULL;
 }
 
-#include "efl_ui_focus_manager.eo.c"
\ No newline at end of file
+#include "efl_ui_focus_manager.eo.c"