bu5hm4n pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=0d507830773d8153b4189b954c3aea508d7a62ea
commit 0d507830773d8153b4189b954c3aea508d7a62ea Author: Marcel Hollerbach <[email protected]> Date: Tue Nov 21 23:41:17 2017 +0100 efl_ui_focus_manager: move preparing of the manager to its own api with this some imlpementations can decide if they want to fallback to some older focused item once they need to prepare themself for this call. --- src/lib/elementary/efl_ui_focus_manager.eo | 7 +++ src/lib/elementary/efl_ui_focus_manager_calc.c | 74 ++++++++++++------------- src/lib/elementary/efl_ui_focus_manager_calc.eo | 1 + 3 files changed, 43 insertions(+), 39 deletions(-) diff --git a/src/lib/elementary/efl_ui_focus_manager.eo b/src/lib/elementary/efl_ui_focus_manager.eo index 5dc0e25583..85e87b2a64 100644 --- a/src/lib/elementary/efl_ui_focus_manager.eo +++ b/src/lib/elementary/efl_ui_focus_manager.eo @@ -148,6 +148,13 @@ interface Efl.Ui.Focus.Manager { pop_history_stack { [[Removes the most upper history element, and gives the focus to the next one below]] } + setup_on_first_touch { + [[Called when this manager is set as redirect]] + params { + direction : Efl.Ui.Focus.Direction; [[The direction in which this should be setup]] + entry : Efl.Ui.Focus.Object; [[The object that caused this manager to be redirect]] + } + } } events { redirect,changed : Efl.Ui.Focus.Manager; [[Emitted when the redirect diff --git a/src/lib/elementary/efl_ui_focus_manager_calc.c b/src/lib/elementary/efl_ui_focus_manager_calc.c index 4e61fa1472..834472c5eb 100644 --- a/src/lib/elementary/efl_ui_focus_manager_calc.c +++ b/src/lib/elementary/efl_ui_focus_manager_calc.c @@ -921,6 +921,12 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_redirect_set(Eo *obj, Efl_Ui_Foc } efl_event_callback_call(obj, EFL_UI_FOCUS_MANAGER_EVENT_REDIRECT_CHANGED , old_manager); + + //just set the root of the new redirect as focused, so it is in a known state + if (redirect) + { + efl_ui_focus_manager_setup_on_first_touch(redirect, EFL_UI_FOCUS_DIRECTION_LAST, NULL); + } } EOLIAN static Efl_Ui_Focus_Manager * @@ -1435,57 +1441,46 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_focus_set(Eo *obj, Efl_Ui_Focus_ //now check if this is also a listener object if (redirect_manager) { - efl_ui_focus_manager_reset_history(pd->redirect); - - //first set the redirect + //set the redirect efl_ui_focus_manager_redirect_set(obj, redirect_manager); - - if (type == NODE_TYPE_ONLY_LOGICAL) - { - //focus the root to just get the next regular element - //FIXME it would be good to make that depending on the focus move directions - //so we can take the last regular item in the logical tree for the PREVIOUS move - Efl_Ui_Focus_Object *root; - - root = efl_ui_focus_manager_root_get(redirect_manager); - efl_ui_focus_manager_focus_set(redirect_manager, root); - } - else - { - //or just focus the focusable itself in the other manager - efl_ui_focus_manager_focus_set(redirect_manager, focusable); - } - } } -static void -_followup_previous_direction(Eo *obj) +EOLIAN static void +_efl_ui_focus_manager_calc_efl_ui_focus_manager_setup_on_first_touch(Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd, Efl_Ui_Focus_Direction direction, Efl_Ui_Focus_Object *entry) { - Efl_Ui_Focus_Manager *rec_manager; - rec_manager = efl_ui_focus_manager_redirect_get(obj); - if (rec_manager) + printf("SETUP\n"); + if (direction == EFL_UI_FOCUS_DIRECTION_PREVIOUS && entry) { Efl_Ui_Focus_Manager_Logical_End_Detail last; - efl_ui_focus_manager_reset_history(rec_manager); - - do { - last = efl_ui_focus_manager_logical_end(rec_manager); - EINA_SAFETY_ON_NULL_RETURN(last.element); - efl_ui_focus_manager_focus_set(rec_manager, last.element); + Efl_Ui_Focus_Manager *rec_manager = obj; + do + { + last = efl_ui_focus_manager_logical_end(rec_manager); + EINA_SAFETY_ON_NULL_RETURN(last.element); + efl_ui_focus_manager_focus_set(rec_manager, last.element); - rec_manager = efl_ui_focus_manager_redirect_get(rec_manager); - } while (!last.is_regular_end); + rec_manager = efl_ui_focus_manager_redirect_get(rec_manager); + } + while (!last.is_regular_end); } + else if (DIRECTION_IS_2D(direction) && entry) + efl_ui_focus_manager_focus_set(obj, entry); + else + efl_ui_focus_manager_focus_set(obj, pd->root->focusable); } + EOLIAN static Efl_Ui_Focus_Object* _efl_ui_focus_manager_calc_efl_ui_focus_manager_move(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Calc_Data *pd, Efl_Ui_Focus_Direction direction) { Efl_Ui_Focus_Object *candidate = NULL; + Efl_Ui_Focus_Manager *early, *late; EINA_SAFETY_ON_FALSE_RETURN_VAL(DIRECTION_CHECK(direction), NULL); + early = efl_ui_focus_manager_redirect_get(obj); + if (pd->redirect) { Efl_Ui_Focus_Object *old_candidate = NULL; @@ -1505,10 +1500,6 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_move(Eo *obj EINA_UNUSED, Efl_Ui if (new_candidate) efl_ui_focus_manager_focus_set(obj, new_candidate); - //for the case that this caused a redirect to be set AND we had a candidate, make sure we setup the other direction correctly - if (direction == ELM_FOCUS_PREVIOUS && new_candidate) - _followup_previous_direction(obj); - candidate = new_candidate; } else @@ -1540,11 +1531,16 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_move(Eo *obj EINA_UNUSED, Efl_Ui if (candidate) { efl_ui_focus_manager_focus_set(obj, candidate); - if (direction == ELM_FOCUS_PREVIOUS && candidate) - _followup_previous_direction(obj); } } + late = efl_ui_focus_manager_redirect_get(obj); + + if (early != late) + { + //this is a new manager, we have to init its case! + efl_ui_focus_manager_setup_on_first_touch(pd->redirect, direction, candidate); + } return candidate; } diff --git a/src/lib/elementary/efl_ui_focus_manager_calc.eo b/src/lib/elementary/efl_ui_focus_manager_calc.eo index 0a8b4e73c5..e5e49bb109 100644 --- a/src/lib/elementary/efl_ui_focus_manager_calc.eo +++ b/src/lib/elementary/efl_ui_focus_manager_calc.eo @@ -101,6 +101,7 @@ class Efl.Ui.Focus.Manager.Calc (Efl.Object, Efl.Ui.Focus.Manager) { Efl.Ui.Focus.Manager.logical_end; Efl.Ui.Focus.Manager.reset_history; Efl.Ui.Focus.Manager.pop_history_stack; + Efl.Ui.Focus.Manager.setup_on_first_touch; Efl.Object.constructor; Efl.Object.finalize; Efl.Object.provider_find; --
