efl_ui_focus_manager_calc: focus a child if a logical is focused

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.
This commit is contained in:
Marcel Hollerbach 2017-10-09 13:06:47 +02:00
parent fdfc112f04
commit 282883ff9c
3 changed files with 71 additions and 3 deletions

View 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]]

View 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)

View 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);
}