efl_ui_focus_manager: new api
authorMarcel Hollerbach <marcel@osg.samsung.com>
Fri, 20 Oct 2017 14:31:05 +0000 (16:31 +0200)
committerMarcel Hollerbach <marcel@osg.samsung.com>
Fri, 20 Oct 2017 15:21:57 +0000 (17:21 +0200)
Can be used to fetch a focusable widget that has child as parent.

src/lib/elementary/efl_ui_focus_manager.eo
src/lib/elementary/efl_ui_focus_manager_calc.c
src/lib/elementary/efl_ui_focus_manager_calc.eo

index 1cad0c4..f382d55 100644 (file)
@@ -106,6 +106,18 @@ interface Efl.Ui.Focus.Manager {
                     this manager object.]]
             }
         }
+        request_subchild {
+            [[Returns a widget that can receive focus
+
+              The returned widget is in a child of the passed param.
+              Its garanteed that child will not be prepared once again,
+              so you can call this function out of a prepare call.
+            ]]
+              params {
+                 child : Efl.Ui.Focus.Object;
+              }
+              return : Efl.Ui.Focus.Object;
+        }
         fetch {
             [[This will fetch the data from a registered node.
 
index 24680bc..a254566 100644 (file)
@@ -1097,13 +1097,10 @@ _prev_item(Node *node)
 }
 
 static Node*
-_next(Node *node)
+_next_unprepare_node(Node *node)
 {
    Node *n;
 
-   //prepare the node itself so if there are probebly no children, then they are here.
-   efl_ui_focus_object_prepare_logical(node->focusable);
-
    //Case 1 we are having children
    //But only enter the children if it does NOT have a redirect manager
    if (T(node).children && !node->redirect_manager)
@@ -1145,6 +1142,15 @@ _next(Node *node)
 }
 
 static Node*
+_next(Node *node)
+{
+   //prepare the node itself so if there are probebly no children, then they are here.
+   efl_ui_focus_object_prepare_logical(node->focusable);
+
+   return _next_unprepare_node(node);
+}
+
+static Node*
 _prev(Node *node)
 {
    Node *n = NULL;
@@ -1272,7 +1278,32 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_request_move(Eo *obj EINA_UNUSED
      }
 }
 
+static Node*
+_request_subchild(Node *node)
+{
+   //important! if there are no children _next would return the parent of node which will exceed the limit of children of node
+   Node *target = NULL;
 
+   if (node->tree.children)
+     {
+        target = node;
+
+        //try to find a child that is not logical or has a redirect manager
+        while (target && target->type == NODE_TYPE_ONLY_LOGICAL && !target->redirect_manager)
+          {
+             if (target != node)
+               efl_ui_focus_object_prepare_logical(target->focusable);
+
+             target = _next_unprepare_node(target);
+             //abort if we are exceeding the childrens of node
+             if (target == node) target = NULL;
+          }
+
+        F_DBG("Found node %p", target);
+     }
+
+   return target;
+}
 
 EOLIAN static void
 _efl_ui_focus_manager_calc_efl_ui_focus_manager_focus_set(Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd, Efl_Ui_Focus_Object *focus)
@@ -1296,20 +1327,8 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_focus_set(Eo *obj, Efl_Ui_Focus_
 
         //important! if there are no children _next would return the parent of node which will exceed the limit of children of node
         efl_ui_focus_object_prepare_logical(node->focusable);
-        if (node->tree.children)
-          {
-             target = node;
 
-             //try to find a child that is not logical or has a redirect manager
-             while (target && target->type == NODE_TYPE_ONLY_LOGICAL && !target->redirect_manager)
-               {
-                  target = _next(target);
-                  //abort if we are exceeding the childrens of node
-                  if (target == node) target = NULL;
-               }
-
-             F_DBG("Found node %p", target);
-          }
+        target = _request_subchild(node);
 
         //check if we have found anything
         if (target)
@@ -1619,5 +1638,17 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_pop_history_stack(Eo *obj EINA_U
   if (last) efl_ui_focus_object_focus_set(last->focusable, EINA_TRUE);
 }
 
+EOLIAN static Efl_Ui_Focus_Object*
+_efl_ui_focus_manager_calc_efl_ui_focus_manager_request_subchild(Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd, Efl_Ui_Focus_Object *child_obj)
+{
+   Node *child, *target;
+
+   child = node_get(obj, pd, child_obj);
+   target = _request_subchild(child);
+
+   if (target) return target->focusable;
+   return NULL;
+}
+
 
 #include "efl_ui_focus_manager_calc.eo.c"
index d911dbf..0a8b4e7 100644 (file)
@@ -96,6 +96,7 @@ class Efl.Ui.Focus.Manager.Calc (Efl.Object, Efl.Ui.Focus.Manager) {
         Efl.Ui.Focus.Manager.redirect {set; get;}
         Efl.Ui.Focus.Manager.border_elements {get;}
         Efl.Ui.Focus.Manager.root {set; get;}
+        Efl.Ui.Focus.Manager.request_subchild;
         Efl.Ui.Focus.Manager.fetch;
         Efl.Ui.Focus.Manager.logical_end;
         Efl.Ui.Focus.Manager.reset_history;