diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am index 11ad8c3e98..6d59b91886 100644 --- a/src/Makefile_Elementary.am +++ b/src/Makefile_Elementary.am @@ -157,6 +157,7 @@ elm_private_eolian_files = \ lib/elementary/elm_calendar_item.eo \ lib/elementary/efl_ui_focus_parent_provider.eo \ lib/elementary/efl_ui_focus_parent_provider_standard.eo \ + lib/elementary/efl_ui_focus_parent_provider_gen.eo \ $(NULL) # Legacy classes - not part of public EO API @@ -712,6 +713,7 @@ lib_elementary_libelementary_la_SOURCES = \ lib/elementary/efl_ui_focus_composition.c \ lib/elementary/efl_ui_focus_parent_provider.c \ lib/elementary/efl_ui_focus_parent_provider_standard.c \ + lib/elementary/efl_ui_focus_parent_provider_gen.c \ $(NULL) diff --git a/src/lib/elementary/efl_ui_focus_parent_provider_gen.c b/src/lib/elementary/efl_ui_focus_parent_provider_gen.c new file mode 100644 index 0000000000..b93271bfc6 --- /dev/null +++ b/src/lib/elementary/efl_ui_focus_parent_provider_gen.c @@ -0,0 +1,70 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif + +#include +#include "elm_priv.h" +#include "efl_ui_focus_parent_provider_gen.eo.h" + +typedef struct { + Eina_Hash *map; + Elm_Widget *container; + Efl_Ui_Focus_Parent_Provider *provider; +} Efl_Ui_Focus_Parent_Provider_Gen_Data; + +EOLIAN static void +_efl_ui_focus_parent_provider_gen_content_item_map_set(Eo *obj, Efl_Ui_Focus_Parent_Provider_Gen_Data *pd, Eina_Hash *map) +{ + EINA_SAFETY_ON_TRUE_RETURN(efl_finalized_get(obj)); + + pd->map = map; +} + +EOLIAN static Eina_Hash* +_efl_ui_focus_parent_provider_gen_content_item_map_get(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Parent_Provider_Gen_Data *pd) +{ + return pd->map; +} + +EOLIAN static void +_efl_ui_focus_parent_provider_gen_container_set(Eo *obj, Efl_Ui_Focus_Parent_Provider_Gen_Data *pd, Elm_Widget *container) +{ + EINA_SAFETY_ON_TRUE_RETURN(efl_finalized_get(obj)); + + pd->container = container; + + EINA_SAFETY_ON_NULL_RETURN(efl_parent_get(pd->container)); + + pd->provider = efl_provider_find(efl_parent_get(pd->container), EFL_UI_FOCUS_PARENT_PROVIDER_INTERFACE); +} + +EOLIAN static Elm_Widget* +_efl_ui_focus_parent_provider_gen_container_get(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Parent_Provider_Gen_Data *pd) +{ + return pd->container; +} + + +EOLIAN static Efl_Ui_Focus_Object* +_efl_ui_focus_parent_provider_gen_efl_ui_focus_parent_provider_find_logical_parent(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Parent_Provider_Gen_Data *pd EINA_UNUSED, Efl_Ui_Focus_Object *widget) +{ + //first check if this item is in the map + Elm_Widget_Item *item; + + item = eina_hash_find(pd->map, &widget); + + efl_ui_focus_composition_elements_flush(pd->container); + + // We dont have a map entry + if (!item) + { + return efl_ui_focus_parent_provider_find_logical_parent(pd->provider, widget); + } + else + { + return item; + } +} + + +#include "efl_ui_focus_parent_provider_gen.eo.c" diff --git a/src/lib/elementary/efl_ui_focus_parent_provider_gen.eo b/src/lib/elementary/efl_ui_focus_parent_provider_gen.eo new file mode 100644 index 0000000000..a863b629fe --- /dev/null +++ b/src/lib/elementary/efl_ui_focus_parent_provider_gen.eo @@ -0,0 +1,17 @@ +class Efl.Ui.Focus.Parent_Provider.Gen(Efl.Object, Efl.Ui.Focus.Parent_Provider) { + methods { + @property content_item_map { + values { + map : hash; + } + } + @property container { + values { + container : Elm.Widget; + } + } + } + implements { + Efl.Ui.Focus.Parent_Provider.find_logical_parent; + } +} diff --git a/src/lib/elementary/elm_gengrid.c b/src/lib/elementary/elm_gengrid.c index 00448cf0fa..cd6b27d353 100644 --- a/src/lib/elementary/elm_gengrid.c +++ b/src/lib/elementary/elm_gengrid.c @@ -6,12 +6,14 @@ #define EFL_ACCESS_SELECTION_PROTECTED #define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED #define ELM_WIDGET_ITEM_PROTECTED +#define EFL_UI_FOCUS_COMPOSITION_PROTECTED #include #include #include "elm_priv.h" #include "elm_widget_gengrid.h" #include "elm_interface_scrollable.h" +#include "efl_ui_focus_parent_provider_gen.eo.h" #define MY_PAN_CLASS ELM_GENGRID_PAN_CLASS @@ -1021,6 +1023,7 @@ _item_content_realize(Elm_Gen_Item *it, Evas_Object *content; Eina_List *source; const char *key; + ELM_GENGRID_DATA_GET(it->base->widget, sd); if (!parts) { @@ -1050,6 +1053,7 @@ _item_content_realize(Elm_Gen_Item *it, ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key); if (!content) goto out; } + eina_hash_add(sd->content_item_map, &content, it->base->eo_obj); *contents = eina_list_append(*contents, content); if (!edje_object_part_swallow(target, key, content)) { @@ -1177,6 +1181,7 @@ _elm_gengrid_item_all_contents_unset(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Evas_Object *content; ELM_GENGRID_ITEM_CHECK_OR_RETURN(it); + ELM_GENGRID_DATA_GET(it->base->widget, sd); EINA_LIST_FREE (it->contents, content) { @@ -1186,6 +1191,8 @@ _elm_gengrid_item_all_contents_unset(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, edje_object_part_unswallow(VIEW(it), content); evas_object_hide(content); if (l) *l = eina_list_append(*l, content); + + eina_hash_del_by_key(sd->content_item_map, &content); } } @@ -1413,9 +1420,11 @@ static Eina_List * _content_cache_add(Elm_Gen_Item *it, Eina_List **cache) { Evas_Object *content = NULL; + ELM_GENGRID_DATA_GET(it->base->widget, sd); EINA_LIST_FREE(it->contents, content) { *cache = eina_list_append(*cache, content); + eina_hash_del_by_key(sd->content_item_map, &content); } return *cache; @@ -3831,18 +3840,18 @@ _elm_gengrid_item_elm_widget_item_focus_set(Eo *eo_it, Elm_Gen_Item *it, Eina_Bo if (focused) { sd->last_focused_item = eo_it; + if (!elm_object_focus_get(obj)) elm_object_focus_set(obj, EINA_TRUE); - if (!elm_widget_focus_get(obj)) - return; - if (eo_it != sd->focused_item) { if (sd->focused_item) _elm_gengrid_item_unfocused(sd->focused_item); _elm_gengrid_item_focused(eo_it); } + + efl_ui_focus_manager_focus_set(obj, eo_it); } else { @@ -4028,6 +4037,8 @@ _elm_gengrid_item_new(Elm_Gengrid_Data *sd, (!strcmp(it->itc->item_style, "group_index")); sd->item_count++; + efl_ui_focus_composition_dirty(sd->obj); + return it; } @@ -4221,6 +4232,14 @@ elm_gengrid_add(Evas_Object *parent) EOLIAN static Eo * _elm_gengrid_efl_object_constructor(Eo *obj, Elm_Gengrid_Data *sd) { + sd->content_item_map = eina_hash_pointer_new(NULL); + sd->provider = efl_add(EFL_UI_FOCUS_PARENT_PROVIDER_GEN_CLASS, obj, + efl_ui_focus_parent_provider_gen_container_set(efl_added, obj), + efl_ui_focus_parent_provider_gen_content_item_map_set(efl_added, sd->content_item_map)); + + efl_ui_focus_composition_custom_manager_set(obj, obj); + efl_ui_focus_composition_logical_mode_set(obj, EINA_TRUE); + obj = efl_constructor(efl_super(obj, MY_CLASS)); sd->obj = obj; @@ -5661,6 +5680,37 @@ _elm_gengrid_efl_access_selection_child_deselect(Eo *obj EINA_UNUSED, Elm_Gengri return EINA_FALSE; } +EOLIAN static Efl_Object* +_elm_gengrid_efl_object_provider_find(Eo *obj, Elm_Gengrid_Data *pd, const Efl_Object *klass) +{ + if (klass == EFL_UI_FOCUS_PARENT_PROVIDER_INTERFACE) + return pd->provider; + return efl_provider_find(efl_super(obj, ELM_GENGRID_CLASS), klass); +} + +EOLIAN static void +_elm_gengrid_efl_ui_focus_composition_prepare(Eo *obj, Elm_Gengrid_Data *pd) +{ + Elm_Gen_Item *item; + Eina_List *order = NULL; + + EINA_INLIST_FOREACH(pd->items, item) + { + if (item->base->disabled) + continue; + + order = eina_list_append(order, item->base->eo_obj); + } + + efl_ui_focus_composition_elements_set(obj, order); +} + +EOLIAN static Eina_Bool +_elm_gengrid_elm_widget_focus_state_apply(Eo *obj, Elm_Gengrid_Data *pd EINA_UNUSED, Elm_Widget_Focus_State current_state, Elm_Widget_Focus_State *configured_state, Elm_Widget *redirect EINA_UNUSED) +{ + return elm_obj_widget_focus_state_apply(efl_super(obj, MY_CLASS), current_state, configured_state, obj); +} + /* Standard widget overrides */ ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(elm_gengrid, Elm_Gengrid_Data) diff --git a/src/lib/elementary/elm_gengrid.eo b/src/lib/elementary/elm_gengrid.eo index dfec8a0f9f..43191b46fb 100644 --- a/src/lib/elementary/elm_gengrid.eo +++ b/src/lib/elementary/elm_gengrid.eo @@ -10,7 +10,7 @@ enum Elm.Gengrid.Reorder_Type swap [[Swap reorder type]] } -class Elm.Gengrid (Efl.Ui.Layout, Elm.Interface_Scrollable, +class Elm.Gengrid (Efl.Ui.Layout, Efl.Ui.Focus.Composition, Elm.Interface_Scrollable, Efl.Ui.Clickable, Elm.Interface.Atspi_Widget_Action, Efl.Access.Selection) { @@ -544,6 +544,7 @@ class Elm.Gengrid (Efl.Ui.Layout, Elm.Interface_Scrollable, implements { class.constructor; Efl.Object.constructor; + Efl.Object.provider_find; Efl.Gfx.position { set; } Efl.Gfx.size { set; } Efl.Canvas.Group.group_member_add; @@ -568,6 +569,8 @@ class Elm.Gengrid (Efl.Ui.Layout, Elm.Interface_Scrollable, Efl.Access.Selection.is_child_selected; Efl.Access.Selection.all_children_select; Efl.Access.Selection.clear; + Efl.Ui.Focus.Composition.prepare; + Elm.Widget.focus_state_apply; } events { realized; [[Called when gengrid realized]] diff --git a/src/lib/elementary/elm_gengrid_item.eo b/src/lib/elementary/elm_gengrid_item.eo index 3bda536ee2..2f5fd3e74a 100644 --- a/src/lib/elementary/elm_gengrid_item.eo +++ b/src/lib/elementary/elm_gengrid_item.eo @@ -25,7 +25,7 @@ enum Elm.Gengrid.Item.Field_Type } -class Elm.Gengrid.Item(Elm.Widget.Item) +class Elm.Gengrid.Item(Elm.Widget.Item, Efl.Ui.Focus.Object) { [[Elementary gengrid item class]] legacy_prefix: elm_gengrid_item; diff --git a/src/lib/elementary/elm_widget_gengrid.h b/src/lib/elementary/elm_widget_gengrid.h index d9cc692c82..004cf6cc59 100644 --- a/src/lib/elementary/elm_widget_gengrid.h +++ b/src/lib/elementary/elm_widget_gengrid.h @@ -50,6 +50,9 @@ struct _Elm_Gengrid_Data Elm_Object_Item *bring_in_it; Elm_Gengrid_Item_Scrollto_Type scroll_to_type; + Eina_Hash *content_item_map; + Eo *provider; + Ecore_Job *calc_job; int walking; int item_width, item_height;