bu5hm4n pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=18194f343ee00000d579513b5de01fc0081a4996

commit 18194f343ee00000d579513b5de01fc0081a4996
Author: Marcel Hollerbach <[email protected]>
Date:   Sun Oct 15 15:35:42 2017 +0200

    elm_gengrid: implement item-content-focus
    
     #finally
    
    For now we focus the widgets of a item, the item content can be cycled
    by tab / Ctrl + tab. up/down/right/left are for now handled by gengrid
    and move the focused item (everything else feels super weird with
    multiple contents in a item)
    
    ref T6181
---
 src/Makefile_Elementary.am                         |  2 +
 .../elementary/efl_ui_focus_parent_provider_gen.c  | 70 ++++++++++++++++++++++
 .../elementary/efl_ui_focus_parent_provider_gen.eo | 17 ++++++
 src/lib/elementary/elm_gengrid.c                   | 56 ++++++++++++++++-
 src/lib/elementary/elm_gengrid.eo                  |  5 +-
 src/lib/elementary/elm_gengrid_item.eo             |  2 +-
 src/lib/elementary/elm_widget_gengrid.h            |  3 +
 7 files changed, 150 insertions(+), 5 deletions(-)

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 <Elementary.h>
+#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<Elm.Widget, Elm.Widget.Item>;
+         }
+      }
+      @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 <Elementary.h>
 #include <Elementary_Cursor.h>
 #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;

-- 


Reply via email to