efl_ui_focus_manager_calc: focus a child if a logical is focused
authorMarcel Hollerbach <marcel-hollerbach@t-online.de>
Mon, 9 Oct 2017 11:06:47 +0000 (13:06 +0200)
committerMarcel Hollerbach <marcel-hollerbach@t-online.de>
Mon, 9 Oct 2017 11:10:51 +0000 (13:10 +0200)
If you call focus_set(m, o) where o is a logical child, then the focus
will go to any none logical child of o, or if there is nothing in the
children of o, then the focus will remain on the now focused element.

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

index 62142e3..aeb7627 100644 (file)
@@ -69,7 +69,10 @@ interface Efl.Ui.Focus.Manager {
             return : Efl.Ui.Focus.Object; [[Next object to focus]]
         }
         @property focus {
-            [[The element which is currently focused by this manager]]
+            [[The element which is currently focused by this manager
+
+              For the case focus is a logical child, then the item will go to the next none logical element. If there is none, focus will stay where it is right now.
+            ]]
 
             values {
                 focus : Efl.Ui.Focus.Object @nonull; [[Focused element]]
index d6066bb..500eb0f 100644 (file)
@@ -1215,8 +1215,37 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_focus_set(Eo *obj, Efl_Ui_Focus_
 
    if (node->type == NODE_TYPE_ONLY_LOGICAL && !node->redirect_manager && pd->root != node)
      {
-        ERR(" %p is logical, cannot be focused", obj);
-        return;
+        Node *target = NULL;
+
+        F_DBG(" %p is logical, fetching the next subnode that is either a redirect or a regular", obj);
+
+        //important! if there are no children _next would return the parent of node which will exceed the limit of children of node
+        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);
+          }
+
+        //check if we have found anything
+        if (target)
+          {
+             node = target;
+          }
+        else
+          {
+             ERR("Could not fetch a node located at %p", node->focusable);
+             return;
+          }
      }
 
    if (pd->redirect)
index ab6c7f5..8eb732b 100644 (file)
@@ -331,6 +331,41 @@ START_TEST(order_check)
    elm_shutdown();
 }
 END_TEST
+
+START_TEST(logical_shift)
+{
+   Efl_Ui_Focus_Manager *m;
+
+   elm_init(1, NULL);
+
+   TEST_OBJ_NEW(root, 0, 0, 10, 10);
+   TEST_OBJ_NEW(child, 0, 0, 10, 10);
+   TEST_OBJ_NEW(sub, 0, 0, 10, 10);
+   TEST_OBJ_NEW(sub_sub, 0, 0, 10, 10);
+   TEST_OBJ_NEW(sub_child, 0, 0, 10, 10);
+
+   m = efl_add(EFL_UI_FOCUS_MANAGER_CALC_CLASS, NULL,
+    efl_ui_focus_manager_root_set(efl_added, root)
+   );
+
+   efl_ui_focus_manager_calc_register(m, child, root, NULL);
+   efl_ui_focus_manager_calc_register_logical(m, sub, root, NULL);
+   efl_ui_focus_manager_calc_register_logical(m, sub_sub, sub, NULL);
+   efl_ui_focus_manager_calc_register(m, sub_child, sub, NULL);
+
+   efl_ui_focus_manager_focus_set(m, root);
+   ck_assert_ptr_eq(efl_ui_focus_manager_focus_get(m), child);
+
+   efl_ui_focus_manager_focus_set(m, sub);
+   ck_assert_ptr_eq(efl_ui_focus_manager_focus_get(m), sub_child);
+
+   efl_ui_focus_manager_focus_set(m, sub_sub);
+   ck_assert_ptr_eq(efl_ui_focus_manager_focus_get(m), sub_child);
+
+   elm_shutdown();
+}
+END_TEST
+
 void elm_test_focus(TCase *tc)
 {
     tcase_add_test(tc, focus_register_twice);
@@ -343,4 +378,5 @@ void elm_test_focus(TCase *tc)
     tcase_add_test(tc, redirect_param);
     tcase_add_test(tc, invalid_args_check);
     tcase_add_test(tc, order_check);
+    tcase_add_test(tc, logical_shift);
 }