efl_ui_focus_manager: handle redirect managers in a better way

This commit is contained in:
Marcel Hollerbach 2016-12-07 20:12:11 +01:00
parent b53f3edd15
commit 0f2657983f
2 changed files with 86 additions and 32 deletions

View File

@ -942,6 +942,37 @@ _logical_movement(Efl_Ui_Focus_Manager_Data *pd EINA_UNUSED, Node *upper, Efl_Ui
return result; return result;
} }
static Efl_Ui_Focus_Object*
_request_move(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Data *pd, Efl_Ui_Focus_Direction direction, Node *upper)
{
Node *dir = NULL;
upper = eina_list_last_data_get(pd->focus_stack);
if (!upper)
{
upper = _no_history_element(pd->node_hash);
if (upper)
return upper->focusable;
return NULL;
}
#ifdef DEBUG
_debug_node(upper);
#endif
if (direction == EFL_UI_FOCUS_DIRECTION_PREV
|| direction == EFL_UI_FOCUS_DIRECTION_NEXT)
dir = _logical_movement(pd, upper, direction);
else
dir = _coords_movement(pd, upper, direction);
//return the widget
if (dir)
return dir->focusable;
else
return NULL;
}
EOLIAN static Efl_Ui_Focus_Object* EOLIAN static Efl_Ui_Focus_Object*
_efl_ui_focus_manager_request_move(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Data *pd, Efl_Ui_Focus_Direction direction) _efl_ui_focus_manager_request_move(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Data *pd, Efl_Ui_Focus_Direction direction)
{ {
@ -953,32 +984,19 @@ _efl_ui_focus_manager_request_move(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Dat
return efl_ui_focus_manager_request_move(pd->redirect, direction); return efl_ui_focus_manager_request_move(pd->redirect, direction);
else else
{ {
Node *upper = NULL, *dir = NULL; Node *upper = NULL;
upper = eina_list_last_data_get(pd->focus_stack); upper = eina_list_last_data_get(pd->focus_stack);
if (!upper) if (!upper)
{ {
upper = _no_history_element(pd->node_hash); upper = _no_history_element(pd->node_hash);
if (upper) if (upper)
return upper->focusable; return upper->focusable;
return NULL; return NULL;
}
} return _request_move(obj, pd, direction, upper);
#ifdef DEBUG
_debug_node(upper);
#endif
if (direction == EFL_UI_FOCUS_DIRECTION_PREV
|| direction == EFL_UI_FOCUS_DIRECTION_NEXT)
dir = _logical_movement(pd, upper, direction);
else
dir = _coords_movement(pd, upper, direction);
//return the widget
if (dir)
return dir->focusable;
else
return NULL;
} }
} }
@ -1022,24 +1040,46 @@ _efl_ui_focus_manager_focus(Eo *obj, Efl_Ui_Focus_Manager_Data *pd, Efl_Ui_Focus
EOLIAN static Efl_Ui_Focus_Object* EOLIAN static Efl_Ui_Focus_Object*
_efl_ui_focus_manager_move(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Data *pd, Efl_Ui_Focus_Direction direction) _efl_ui_focus_manager_move(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Data *pd, Efl_Ui_Focus_Direction direction)
{ {
Efl_Ui_Focus_Object *candidate; Efl_Ui_Focus_Object *candidate = NULL;
EINA_SAFETY_ON_FALSE_RETURN_VAL(DIRECTION_CHECK(direction), NULL); EINA_SAFETY_ON_FALSE_RETURN_VAL(DIRECTION_CHECK(direction), NULL);
if (pd->redirect) if (pd->redirect)
{ {
candidate = efl_ui_focus_manager_move(pd->redirect, direction); Efl_Ui_Focus_Object *old_candidate = NULL;
if (!candidate) candidate = efl_ui_focus_manager_move(pd->redirect, direction);
efl_ui_focus_manager_redirect_set(obj, NULL); old_candidate = efl_ui_focus_manager_focused(pd->redirect);
}
if (!pd->redirect) if (!candidate)
{
Efl_Ui_Focus_Object *new_candidate = NULL;
Node *n;
//there is no candidate check if we have something for that direction
new_candidate = NULL;
n = eina_hash_find(pd->node_hash, &old_candidate);
if (n)
new_candidate = _request_move(obj, pd, direction, n);
if (new_candidate)
{
//redirect does not have smth. but we do have.
efl_ui_focus_manager_redirect_set(obj, NULL);
efl_ui_focus_manager_focus(obj, new_candidate);
}
}
}
else
{ {
candidate = efl_ui_focus_manager_request_move(obj, direction); candidate = efl_ui_focus_manager_request_move(obj, direction);
if (candidate) if (candidate)
efl_ui_focus_manager_focus(obj, candidate); efl_ui_focus_manager_focus(obj, candidate);
} }
#ifdef DEBUG #ifdef DEBUG
printf("Focus, MOVE %s %s\n", DEBUG_TUPLE(candidate)); printf("Focus, MOVE %s %s\n", DEBUG_TUPLE(candidate));
#endif #endif
@ -1058,9 +1098,7 @@ _efl_ui_focus_manager_root_set(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Data *p
} }
node = _register(obj, pd, root, NULL); node = _register(obj, pd, root, NULL);
node->type = NODE_TYPE_ONLY_LOGICAL;
//listen to changes
efl_event_callback_array_add(node->focusable, focusable_node(), obj);
pd->root = node; pd->root = node;
} }
@ -1101,6 +1139,18 @@ _convert(Eina_List *node_list)
return par; return par;
} }
EOLIAN static Efl_Ui_Focus_Object*
_efl_ui_focus_manager_focused(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Data *pd)
{
Node *upper = NULL;
upper = eina_list_last_data_get(pd->focus_stack);
if (!upper)
return NULL;
return upper->focusable;
}
EOLIAN static Efl_Ui_Focus_Relations* EOLIAN static Efl_Ui_Focus_Relations*
_efl_ui_focus_manager_fetch(Eo *obj, Efl_Ui_Focus_Manager_Data *pd, Efl_Ui_Focus_Object *child) _efl_ui_focus_manager_fetch(Eo *obj, Efl_Ui_Focus_Manager_Data *pd, Efl_Ui_Focus_Object *child)
{ {

View File

@ -111,6 +111,10 @@ class Efl.Ui.Focus.Manager (Efl.Object) {
focus : Efl.Ui.Focus.Object @nonull; focus : Efl.Ui.Focus.Object @nonull;
} }
} }
focused {
[[Return the current focused element of this manager]]
return : Efl.Ui.Focus.Object;
}
@property redirect { @property redirect {
[[Add a another manager to serve the move requests. [[Add a another manager to serve the move requests.