From 97265254e6ebb52f334a6d3e623681edb0399160 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Fri, 4 Nov 2016 17:43:40 +0100 Subject: [PATCH] elm_widget: make it a efl_ui_focus_object it will register based on it can_focus flag --- src/lib/elementary/elm_widget.c | 103 ++++++++++++++++++++++++++++++- src/lib/elementary/elm_widget.eo | 5 +- src/lib/elementary/elm_widget.h | 3 + 3 files changed, 109 insertions(+), 2 deletions(-) diff --git a/src/lib/elementary/elm_widget.c b/src/lib/elementary/elm_widget.c index 7521ebdec7..44f2f7eb11 100644 --- a/src/lib/elementary/elm_widget.c +++ b/src/lib/elementary/elm_widget.c @@ -199,6 +199,24 @@ elm_widget_focus_highlight_enabled_get(const Evas_Object *obj) return EINA_FALSE; } +static void +_focus_state_eval(Eo *obj, Elm_Widget_Smart_Data *pd) +{ + if (pd->can_focus && !pd->focus.manager) + { + pd->focus.manager = efl_ui_focus_user_manager_get(obj); + if (pd->focus.manager != obj) + efl_ui_focus_manager_register(pd->focus.manager, obj, pd->focus.manager, NULL); + else + pd->focus.manager = NULL; + } + else if (!pd->can_focus && pd->focus.manager) + { + efl_ui_focus_manager_unregister(pd->focus.manager, obj); + pd->focus.manager = NULL; + } +} + /** * @internal * @@ -1470,6 +1488,8 @@ _elm_widget_can_focus_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool can_focu } efl_event_callback_array_del(obj, focus_callbacks(), NULL); } + if (efl_finalized_get(obj)) + _focus_state_eval(obj, sd); } EOLIAN static Eina_Bool @@ -3866,11 +3886,30 @@ _elm_widget_theme_object_set(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *ed return ret; } +static void +_convert(Efl_Dbg_Info *info, Eina_List *ptr_list) +{ + Eina_List *n; + void *p; + int i = 0; + + EINA_LIST_FOREACH(ptr_list, n, p) + { + char name[100]; + + snprintf(name, sizeof(name), "Candidate %d", i); + + EFL_DBG_INFO_APPEND(info, name, EINA_VALUE_TYPE_UINT64, p); + i++; + } +} + EOLIAN static void _elm_widget_efl_object_dbg_info_get(Eo *eo_obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Efl_Dbg_Info *root) { efl_dbg_info_get(efl_super(eo_obj, MY_CLASS), root); - Efl_Dbg_Info *group = EFL_DBG_INFO_LIST_APPEND(root, MY_CLASS_NAME); + Efl_Ui_Focus_Relations *rel = NULL; + Efl_Dbg_Info *focus, *group = EFL_DBG_INFO_LIST_APPEND(root, MY_CLASS_NAME); EFL_DBG_INFO_APPEND(group, "Wid-Type", EINA_VALUE_TYPE_STRING, elm_widget_type_get(eo_obj)); EFL_DBG_INFO_APPEND(group, "Style", EINA_VALUE_TYPE_STRING, elm_widget_style_get(eo_obj)); @@ -3880,12 +3919,36 @@ _elm_widget_efl_object_dbg_info_get(Eo *eo_obj, Elm_Widget_Smart_Data *_pd EINA_ evas_object_scale_get(eo_obj)); EFL_DBG_INFO_APPEND(group, "Has focus", EINA_VALUE_TYPE_CHAR, elm_object_focus_get(eo_obj)); + EFL_DBG_INFO_APPEND(group, "Can focus", EINA_VALUE_TYPE_CHAR, + elm_widget_can_focus_get(eo_obj)); EFL_DBG_INFO_APPEND(group, "Disabled", EINA_VALUE_TYPE_CHAR, elm_widget_disabled_get(eo_obj)); EFL_DBG_INFO_APPEND(group, "Mirrored", EINA_VALUE_TYPE_CHAR, elm_widget_mirrored_get(eo_obj)); EFL_DBG_INFO_APPEND(group, "Automatic mirroring", EINA_VALUE_TYPE_CHAR, elm_widget_mirrored_automatic_get(eo_obj)); + + + rel = efl_ui_focus_manager_fetch(_pd->focus.manager, eo_obj); + if (rel) + { + focus = EFL_DBG_INFO_LIST_APPEND(group, "Focus"); + + EFL_DBG_INFO_APPEND(focus, "Next", EINA_VALUE_TYPE_UINT64 , rel->next); + EFL_DBG_INFO_APPEND(focus, "Prev", EINA_VALUE_TYPE_UINT64 , rel->prev); + +#define ADD_PTR_LIST(name) \ + Efl_Dbg_Info* name = EFL_DBG_INFO_LIST_APPEND(focus, " "#name" "); \ + _convert(name, rel->name); + + ADD_PTR_LIST(top) + ADD_PTR_LIST(down) + ADD_PTR_LIST(right) + ADD_PTR_LIST(left) + +#undef ADD_PTR_LIST + + } } EAPI Eina_Bool @@ -5821,9 +5884,23 @@ _elm_widget_efl_object_constructor(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSE sd->on_create = EINA_FALSE; elm_interface_atspi_accessible_role_set(obj, ELM_ATSPI_ROLE_UNKNOWN); + return obj; } +EOLIAN static Efl_Object* +_elm_widget_efl_object_finalize(Eo *obj, Elm_Widget_Smart_Data *pd) +{ + Eo *eo; + + eo = efl_finalize(efl_super(obj, MY_CLASS)); + + _focus_state_eval(obj, pd); + + return eo; +} + + EOLIAN static void _elm_widget_efl_object_destructor(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED) { @@ -6090,5 +6167,29 @@ _elm_widget_efl_object_provider_find(Eo *obj, Elm_Widget_Smart_Data *pd, const E } +EOLIAN static Efl_Ui_Focus_Manager* +_elm_widget_efl_ui_focus_user_manager_get(Eo *obj, Elm_Widget_Smart_Data *pd) +{ + Evas_Object *parent = obj; + + do + { + if (efl_isa(parent, EFL_UI_FOCUS_MANAGER_CLASS)) + return parent; + } + while((parent = elm_widget_parent_get(parent))); + + ERR("Failed to find manager object"); + return NULL; +} + +EOLIAN static void +_elm_widget_efl_ui_focus_object_geometry_get(Eo *obj, Elm_Widget_Smart_Data *pd, Eina_Rectangle *rect) +{ + if (!rect) return; + + return efl_gfx_geometry_get(obj, &rect->x , &rect->y, &rect->w, &rect->h); +} + #include "elm_widget_item.eo.c" #include "elm_widget.eo.c" diff --git a/src/lib/elementary/elm_widget.eo b/src/lib/elementary/elm_widget.eo index 006d8a6f20..814b3f41ee 100644 --- a/src/lib/elementary/elm_widget.eo +++ b/src/lib/elementary/elm_widget.eo @@ -29,7 +29,7 @@ struct Elm.Tooltip; [[Elementary tooltip]] struct Elm.Cursor; [[Elementary cursor]] struct @extern Elm.Theme; [[Elementary theme]] -abstract Elm.Widget (Efl.Canvas.Group, Elm.Interface.Atspi_Accessible, Elm.Interface.Atspi_Component) +abstract Elm.Widget (Efl.Canvas.Group, Elm.Interface.Atspi_Accessible, Elm.Interface.Atspi_Component, Efl.Ui.Focus.User, Efl.Ui.Focus.Object) { [[Elementary widget abstract class]] legacy_prefix: elm_widget; @@ -828,6 +828,7 @@ abstract Elm.Widget (Efl.Canvas.Group, Elm.Interface.Atspi_Accessible, Elm.Inter implements { class.constructor; Efl.Object.constructor; + Efl.Object.finalize; Efl.Object.destructor; Efl.Object.dbg_info_get; Efl.Object.provider_find; @@ -849,6 +850,8 @@ abstract Elm.Widget (Efl.Canvas.Group, Elm.Interface.Atspi_Accessible, Elm.Inter Elm.Interface.Atspi_Accessible.parent { get; } Elm.Interface.Atspi_Accessible.attributes { get; } Elm.Interface.Atspi_Component.focus_grab; + Efl.Ui.Focus.User.manager.get; + Efl.Ui.Focus.Object.geometry_get; } events { moved; [[Called when widget moved]] diff --git a/src/lib/elementary/elm_widget.h b/src/lib/elementary/elm_widget.h index 8115111345..3d14e8840c 100644 --- a/src/lib/elementary/elm_widget.h +++ b/src/lib/elementary/elm_widget.h @@ -456,6 +456,9 @@ typedef struct _Elm_Widget_Smart_Data Eina_Bool on_create : 1; /**< This is true when the widget is on creation(general widget constructor). */ Eina_Bool on_destroy: 1; /**< This is true when the widget is on destruction(general widget destructor). */ Eina_Bool provider_lookup : 1; /**< This is true when efl_provider_find is currently walking the tree */ + struct { + Efl_Ui_Focus_Manager *manager; + } focus; } Elm_Widget_Smart_Data; /**