efl_ui_focus_composition: add fields for manager and parent

the manager objects are build on the assertion that registered elements
are returning the manager they are registered on if
efl_ui_focus_object_manager_get is called.
This commit is contained in:
Marcel Hollerbach 2018-04-23 15:23:17 +02:00
parent a61f254f19
commit d7011b52e7
5 changed files with 89 additions and 2 deletions

View File

@ -43,6 +43,12 @@ _state_apply(Eo *obj, Efl_Ui_Focus_Composition_Data *pd)
safed = eina_list_append(safed, o);
else
efl_ui_focus_manager_calc_unregister(manager, o);
if (efl_isa(o, EFL_UI_FOCUS_COMPOSITION_ADAPTER_CLASS))
{
efl_ui_focus_composition_adapter_focus_manager_parent_set(o, NULL);
efl_ui_focus_composition_adapter_focus_manager_object_set(o, NULL);
}
}
pd->registered_targets = safed;
@ -54,6 +60,13 @@ _state_apply(Eo *obj, Efl_Ui_Focus_Composition_Data *pd)
efl_ui_focus_manager_calc_register(manager, o, obj, NULL);
else
efl_ui_focus_manager_calc_register_logical(manager, o, obj, NULL);
if (efl_isa(o, EFL_UI_FOCUS_COMPOSITION_ADAPTER_CLASS))
{
efl_ui_focus_composition_adapter_focus_manager_parent_set(o, obj);
efl_ui_focus_composition_adapter_focus_manager_object_set(o, manager);
}
pd->registered_targets = eina_list_append(pd->registered_targets, o);
}
@ -194,6 +207,8 @@ _efl_ui_focus_composition_logical_mode_get(const Eo *obj EINA_UNUSED, Efl_Ui_Foc
typedef struct {
Evas_Object *object;
Efl_Ui_Focus_Manager *manager;
Efl_Ui_Focus_Object *parent;
} Efl_Ui_Focus_Composition_Adapter_Data;
static void
@ -258,5 +273,29 @@ _efl_ui_focus_composition_adapter_efl_object_destructor(Eo *obj, Efl_Ui_Focus_Co
efl_destructor(efl_super(obj, EFL_UI_FOCUS_COMPOSITION_ADAPTER_CLASS));
}
EOLIAN static void
_efl_ui_focus_composition_adapter_focus_manager_object_set(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Composition_Adapter_Data *pd, Efl_Ui_Focus_Manager *v)
{
pd->manager = v;
}
EOLIAN static void
_efl_ui_focus_composition_adapter_focus_manager_parent_set(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Composition_Adapter_Data *pd, Efl_Ui_Focus_Object *parent)
{
pd->parent = parent;
}
EOLIAN static Efl_Ui_Focus_Object*
_efl_ui_focus_composition_adapter_efl_ui_focus_object_focus_parent_get(const Eo *obj EINA_UNUSED, Efl_Ui_Focus_Composition_Adapter_Data *pd)
{
return pd->parent;
}
EOLIAN static Efl_Ui_Focus_Manager*
_efl_ui_focus_composition_adapter_efl_ui_focus_object_focus_manager_get(const Eo *obj EINA_UNUSED, Efl_Ui_Focus_Composition_Adapter_Data *pd)
{
return pd->manager;
}
#include "efl_ui_focus_composition_adapter.eo.c"

View File

@ -8,9 +8,23 @@ class Efl.Ui.Focus.Composition.Adapter (Efl.Object, Efl.Ui.Focus.Object)
v : Efl.Canvas.Object; [[EFL canvas object]]
}
}
@property focus_manager_object {
set {}
values {
v : Efl.Ui.Focus.Manager;
}
}
@property focus_manager_parent {
set {}
values {
parent : Efl.Ui.Focus.Object;
}
}
}
implements {
Efl.Ui.Focus.Object.focus_geometry {get;}
Efl.Ui.Focus.Object.focus_parent {get;}
Efl.Ui.Focus.Object.focus_manager {get;}
Efl.Ui.Focus.Object.focus {set;}
Efl.Object.destructor;
}

View File

@ -10,6 +10,7 @@
#define MY_CLASS EFL_UI_FOCUS_LAYER_MIXIN
typedef struct {
Efl_Ui_Focus_Object *old_focus;
Efl_Ui_Focus_Manager *registered_manager;
Efl_Ui_Focus_Manager *manager;
Eina_Bool cycle;
@ -107,20 +108,42 @@ _efl_ui_focus_layer_enable_set(Eo *obj, Efl_Ui_Focus_Layer_Data *pd, Eina_Bool v
v = EINA_FALSE;
if (v)
{
Efl_Ui_Focus_Manager *manager;
pd->registered_manager = elm_widget_top_get(obj);
manager = efl_ui_focus_util_active_manager(EFL_UI_FOCUS_UTIL_CLASS, pd->registered_manager);
efl_ui_focus_manager_calc_register_logical(pd->registered_manager, obj, efl_ui_focus_manager_root_get(pd->registered_manager), obj);
_publish_state_change(obj, NULL, NULL);
pd->old_focus = efl_ui_focus_manager_focus_get(manager);
efl_ui_focus_manager_focus_set(pd->manager, obj);
}
else
{
Eina_Bool fallback = EINA_TRUE;
Eo *omanager = pd->registered_manager, *oobj = efl_ui_focus_manager_root_get(omanager);
if (!pd->registered_manager) return;
if (efl_ui_focus_manager_redirect_get(pd->registered_manager) == obj)
//restore old focus
if (pd->old_focus)
{
Efl_Ui_Focus_Manager *manager;
manager = efl_ui_focus_object_focus_manager_get(pd->old_focus);
if (manager)
{
efl_ui_focus_manager_focus_set(manager, pd->old_focus);
fallback = EINA_FALSE;
}
}
pd->old_focus = NULL;
if (fallback && efl_ui_focus_manager_redirect_get(pd->registered_manager) == obj)
efl_ui_focus_manager_redirect_set(pd->registered_manager, NULL);
efl_ui_focus_manager_calc_unregister(pd->registered_manager, obj);

View File

@ -2,6 +2,7 @@
# include "elementary_config.h"
#endif
#define EFL_UI_FOCUS_COMPOSITION_ADAPTER_PROTECTED
#define EFL_UI_FOCUS_OBJECT_PROTECTED
#include <Elementary.h>
@ -43,12 +44,19 @@ _state_eval(Eo *obj, Efl_Ui_Focus_Manager_Root_Focus_Data *pd)
none_logical = !!efl_ui_focus_manager_request_subchild(obj, root);
if (none_logical)
pd->rect_registered = EINA_FALSE;
{
pd->rect_registered = EINA_FALSE;
efl_ui_focus_composition_adapter_focus_manager_parent_set(pd->rect, NULL);
efl_ui_focus_composition_adapter_focus_manager_object_set(pd->rect, NULL);
}
else
{
efl_ui_focus_manager_calc_register(obj, pd->rect, pd->root, NULL);
pd->rect_registered = EINA_TRUE;
efl_ui_focus_composition_adapter_focus_manager_parent_set(pd->rect, pd->root);
efl_ui_focus_composition_adapter_focus_manager_object_set(pd->rect, obj);
if (focused)
efl_ui_focus_manager_focus_set(obj, pd->rect);

View File

@ -2,6 +2,7 @@
# include "elementary_config.h"
#endif
#define EFL_UI_FOCUS_COMPOSITION_ADAPTER_PROTECTED
#define ELM_WIDGET_ITEM_PROTECTED
#define MY_CLASS ELM_WIDGET_ITEM_STATIC_FOCUS_CLASS
@ -67,6 +68,8 @@ _elm_widget_item_static_focus_efl_ui_focus_object_prepare_logical_none_recursive
{
// parent has to stay the object, since this is used to get the item of a adapter
pd->adapter = efl_add(EFL_UI_FOCUS_COMPOSITION_ADAPTER_CLASS, obj);
efl_ui_focus_composition_adapter_focus_manager_parent_set(pd->adapter, wpd->widget);
efl_ui_focus_composition_adapter_focus_manager_object_set(pd->adapter, wpd->widget);
efl_wref_add(pd->adapter, &pd->adapter);
efl_ui_focus_manager_calc_register(wpd->widget, pd->adapter, obj, NULL);
}