felipealmeida pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=7e0f98a7940920540295c90cc7d1744ca6990e97

commit 7e0f98a7940920540295c90cc7d1744ca6990e97
Author: Larry Jr <[email protected]>
Date:   Fri Jan 19 15:27:26 2018 -0200

    elementary: efl_ui_list focus manager fix
    fixed focus changed with keyboard
    fixed scroll in focus
    fixed focus in example
---
 src/examples/elementary/efl_ui_list_example_3.c    |  5 +-
 src/lib/elementary/efl_ui_list.c                   | 72 ++++++++++++++++++++--
 src/lib/elementary/efl_ui_list.eo                  | 16 ++---
 src/lib/elementary/efl_ui_list_precise_layouter.c  | 33 +++++++++-
 src/lib/elementary/efl_ui_list_precise_layouter.eo |  1 +
 src/lib/elementary/efl_ui_list_relayout.eo         |  6 ++
 6 files changed, 113 insertions(+), 20 deletions(-)

diff --git a/src/examples/elementary/efl_ui_list_example_3.c 
b/src/examples/elementary/efl_ui_list_example_3.c
index 3b35ec3528..32d5b1951d 100644
--- a/src/examples/elementary/efl_ui_list_example_3.c
+++ b/src/examples/elementary/efl_ui_list_example_3.c
@@ -59,7 +59,10 @@ static void
 _focused(void *data, const Efl_Event *event)
 {
    Priv_Data *priv = (Priv_Data*)data;
-   priv->selected = efl_ui_focus_manager_focus_get(event->object);
+   Evas_Object *focused = efl_ui_focus_manager_focus_get(event->object);
+
+   if (focused)
+     priv->selected = focused;
 }
 
 static void
diff --git a/src/lib/elementary/efl_ui_list.c b/src/lib/elementary/efl_ui_list.c
index 11335b0f60..2d3f213126 100644
--- a/src/lib/elementary/efl_ui_list.c
+++ b/src/lib/elementary/efl_ui_list.c
@@ -1,15 +1,15 @@
 #ifdef HAVE_CONFIG_H
 # include "elementary_config.h"
 #endif
-#define ELM_ACCESS_PROTECTED
-#define ELM_ACCESS_WIDGET_ACTION_PROTECTED
+#define EFL_ACCESS_PROTECTED
+#define EFL_ACCESS_WIDGET_ACTION_PROTECTED
 #define EFL_ACCESS_SELECTION_PROTECTED
 #define EFL_UI_SCROLL_MANAGER_PROTECTED
 #define EFL_UI_SCROLLBAR_PROTECTED
 #define EFL_UI_SCROLLBAR_BETA
 #define EFL_GFX_SIZE_HINT_PROTECTED
 #define EFL_UI_LIST_PROTECTED
-
+#define EFL_UI_FOCUS_COMPOSITION_PROTECTED
 
 #include <Elementary.h>
 #include "efl_ui_list_private.h"
@@ -166,6 +166,24 @@ _efl_model_properties_has(Efl_Model *model, 
Eina_Stringshare *propfind)
 }
 
 static void
+_list_element_focused(void *data EINA_UNUSED, const Efl_Event *ev)
+{
+   Eina_Rect geom;
+   Eina_Position2D pos;
+   Efl_Ui_Focus_Object *focused = efl_ui_focus_manager_focus_get(ev->object);
+
+   if (!focused) return;
+
+   EFL_UI_LIST_DATA_GET(ev->object, pd);
+   geom = efl_ui_focus_object_focus_geometry_get(focused);
+   pos = efl_ui_scrollable_content_pos_get(pd->scrl_mgr);
+
+   geom.x += pos.x;
+   geom.y += pos.y;
+   efl_ui_scrollable_scroll(pd->scrl_mgr, geom, EINA_TRUE);
+}
+
+static void
 _on_item_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *o 
EINA_UNUSED, void *event_info)
 {
    Evas_Event_Mouse_Down *ev = event_info;
@@ -709,6 +727,11 @@ _efl_ui_list_efl_object_constructor(Eo *obj, 
Efl_Ui_List_Data *pd)
    efl_composite_attach(obj, manager);
    _efl_ui_focus_manager_redirect_events_add(manager, obj);
 
+   efl_event_callback_add(obj, EFL_UI_FOCUS_MANAGER_EVENT_FOCUSED, 
_list_element_focused, NULL);
+
+   efl_ui_focus_composition_custom_manager_set(obj, obj);
+   efl_ui_focus_composition_logical_mode_set(obj, EINA_TRUE);
+
    pd->style = eina_stringshare_add(elm_widget_style_get(obj));
 
    pd->factory = NULL;
@@ -847,7 +870,7 @@ _efl_ui_list_efl_access_selection_child_deselect(Eo *obj 
EINA_UNUSED, Efl_Ui_Lis
 static Eina_Bool
 _key_action_move(Evas_Object *obj EINA_UNUSED, const char *params EINA_UNUSED)
 {
-     return EINA_FALSE;
+   return EINA_FALSE;
 }
 
 static Eina_Bool
@@ -863,8 +886,6 @@ _key_action_escape(Evas_Object *obj, const char *params 
EINA_UNUSED)
    return EINA_TRUE;
 }
 
-ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(efl_ui_list, Efl_Ui_List_Data)
-
 void
 _efl_ui_list_item_select_set(Efl_Ui_List_LayoutItem *item, Eina_Bool selected)
 {
@@ -944,6 +965,30 @@ _efl_ui_list_efl_ui_list_model_min_size_set(Eo *obj, 
Efl_Ui_List_Data *pd, Eina_
    efl_event_callback_call(pd->pan_obj, EFL_UI_PAN_EVENT_CONTENT_CHANGED, 
NULL);
 }
 
+EOLIAN static void
+_efl_ui_list_efl_ui_focus_composition_prepare(Eo *obj, Efl_Ui_List_Data *pd)
+{
+   Eina_List *order = efl_ui_list_relayout_elements_get(pd->relayout);
+   efl_ui_focus_composition_elements_set(obj, order);
+}
+
+EOLIAN Eina_List*
+_efl_ui_list_efl_access_children_get(Eo *obj, Efl_Ui_List_Data *pd)
+{
+   Eina_List *ret = NULL, *ret2 = NULL;
+
+   ret = efl_ui_list_relayout_elements_get(pd->relayout);
+   ret2 = efl_access_children_get(efl_super(obj, EFL_UI_LIST_CLASS));
+
+   return eina_list_merge(ret, ret2);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_list_efl_ui_widget_focus_state_apply(Eo *obj, Efl_Ui_List_Data *pd 
EINA_UNUSED, Efl_Ui_Widget_Focus_State current_state, Efl_Ui_Widget_Focus_State 
*configured_state, Efl_Ui_Widget *redirect EINA_UNUSED)
+{
+   return efl_ui_widget_focus_state_apply(efl_super(obj, MY_CLASS), 
current_state, configured_state, obj);
+}
+
 EOLIAN static Efl_Ui_List_LayoutItem *
 _efl_ui_list_efl_ui_list_model_realize(Eo *obj, Efl_Ui_List_Data *pd, 
Efl_Ui_List_LayoutItem *item)
 {
@@ -954,10 +999,17 @@ _efl_ui_list_efl_ui_list_model_realize(Eo *obj, 
Efl_Ui_List_Data *pd, Efl_Ui_Lis
    evas_object_smart_member_add(item->layout, pd->pan_obj);
    evas_object_event_callback_add(item->layout, EVAS_CALLBACK_MOUSE_UP, 
_on_item_mouse_up, item);
 
+   if (_elm_config->atspi_mode)
+     {
+        efl_access_added(item->layout);
+        efl_access_children_changed_added_signal_emit(obj, item->layout);
+     }
+
    evt.child = item->children;
    evt.layout = item->layout;
    evt.index = efl_ui_list_item_index_get((Efl_Ui_List_Item *)item);
    efl_event_callback_call(obj, EFL_UI_LIST_EVENT_ITEM_REALIZED, &evt);
+   efl_ui_focus_composition_dirty(obj);
 
    evas_object_show(item->layout);
    return item;
@@ -970,6 +1022,12 @@ _efl_ui_list_efl_ui_list_model_unrealize(Eo *obj, 
Efl_Ui_List_Data *pd, Efl_Ui_L
    EINA_SAFETY_ON_NULL_RETURN(item->layout);
 
    evas_object_event_callback_del_full(item->layout, EVAS_CALLBACK_MOUSE_UP, 
_on_item_mouse_up, item);
+   if (elm_object_focus_allow_get(item->layout))
+     {
+        if (elm_object_focus_get(item->layout))
+          elm_object_focus_set(item->layout, EINA_FALSE);
+        efl_ui_focus_manager_calc_unregister(obj, item->layout);
+     }
    evas_object_hide(item->layout);
    evas_object_move(item->layout, -9999, -9999);
 
@@ -1001,6 +1059,8 @@ _efl_ui_list_efl_ui_list_model_size_get(Eo *obj 
EINA_UNUSED, Efl_Ui_List_Data *p
     return pd->item_count;
 }
 
+ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(efl_ui_list, Efl_Ui_List_Data)
+
 /* Internal EO APIs and hidden overrides */
 
 #define EFL_UI_LIST_EXTRA_OPS \
diff --git a/src/lib/elementary/efl_ui_list.eo 
b/src/lib/elementary/efl_ui_list.eo
index 64148ee5ff..9bab9e009c 100644
--- a/src/lib/elementary/efl_ui_list.eo
+++ b/src/lib/elementary/efl_ui_list.eo
@@ -7,7 +7,7 @@ struct Efl.Ui.List.Item_Event
    index: int;
 }
 class Efl.Ui.List (Efl.Ui.Layout, Efl.Ui.View, Efl.Ui.Scrollable.Interactive, 
Efl.Ui.Scrollbar,
-                Efl.Access.Widget.Action, Efl.Access.Selection,
+                Efl.Access.Widget.Action, Efl.Access.Selection, 
Efl.Ui.Focus.Composition, Efl.Ui.Focus.Manager.Sub,
                 Efl.Ui.Clickable, Efl.Ui.Selectable, Efl.Ui.List.Model)
 {
    methods {
@@ -77,19 +77,10 @@ class Efl.Ui.List (Efl.Ui.Layout, Efl.Ui.View, 
Efl.Ui.Scrollable.Interactive, Ef
       Efl.Ui.List.Model.min_size { get; set; }
 
       // Widget
-//      Elm.Widget.focus_next_manager_is;
-//      Elm.Widget.focus_direction_manager_is;
-//      Elm.Widget.focus_register;
-//      Elm.Widget.focus_next;
-//      Elm.Widget.on_focus_update;
-//      Elm.Widget.activate;
-//      Elm.Widget.focused_item { get; }
-//      Elm.Widget.focused_object { get; }
       Efl.Ui.Widget.focus_manager_create;
       Efl.Ui.Widget.widget_event;
-
-//      Efl.Ui.Focus.Manager.focus {set; }
-      //Efl.Ui.Layout.sizing_eval;
+      Efl.Ui.Widget.focus_state_apply;
+      Efl.Ui.Focus.Composition.prepare;
       Efl.Ui.View.model { get; set; }
 
       Efl.Ui.Scrollable.Interactive.viewport_geometry { get; }
@@ -101,6 +92,7 @@ class Efl.Ui.List (Efl.Ui.Layout, Efl.Ui.View, 
Efl.Ui.Scrollable.Interactive, Ef
 //      Elm.Interface.Atspi_Accessible.children { get; }
 //      Elm.Interface.Atspi_Widget.Action.elm_actions { get; }
 //      Efl.Access.Widget.Action.elm_actions { get; }
+      Efl.Access.children { get; }
       Efl.Access.Selection.selected_children_count { get; }
       Efl.Access.Selection.selected_child { get; }
       Efl.Access.Selection.selected_child_deselect;
diff --git a/src/lib/elementary/efl_ui_list_precise_layouter.c 
b/src/lib/elementary/efl_ui_list_precise_layouter.c
index 5ce58ea66c..774eb857ab 100644
--- a/src/lib/elementary/efl_ui_list_precise_layouter.c
+++ b/src/lib/elementary/efl_ui_list_precise_layouter.c
@@ -414,7 +414,7 @@ static void
 _calc_range(Efl_Ui_List_Precise_Layouter_Data *pd)
 {
    Efl_Ui_List_SegArray_Node *node;
-   Evas_Coord ch;
+   Evas_Coord ch, ny;
    Eina_Rect vgmt;
    Eina_Position2D spos;
    Efl_Ui_List_Precise_Layouter_Node_Data *nodedata;
@@ -423,6 +423,11 @@ _calc_range(Efl_Ui_List_Precise_Layouter_Data *pd)
    vgmt = efl_ui_scrollable_viewport_geometry_get(pd->modeler);
    spos = efl_ui_scrollable_content_pos_get(pd->modeler);
 
+   ny = spos.y - (vgmt.h / 2);
+   if (ny < 0) spos.y = 0;
+   else spos.y = ny;
+   vgmt.h *= 2;
+
    ch = 0;
    Eina_Accessor *nodes = efl_ui_list_segarray_node_accessor_get(pd->segarray);
    EINA_ACCESSOR_FOREACH(nodes, i, node)
@@ -518,6 +523,32 @@ _efl_ui_list_precise_layouter_efl_object_constructor(Eo 
*obj EINA_UNUSED, Efl_Ui
    return obj;
 }
 
+EOLIAN static Eina_List *
+_efl_ui_list_precise_layouter_efl_ui_list_relayout_elements_get(Eo *obj 
EINA_UNUSED, Efl_Ui_List_Precise_Layouter_Data *pd)
+{
+   Eina_List *elements_order = NULL;
+   Efl_Ui_List_LayoutItem* layout_item;
+   Efl_Ui_List_SegArray_Node *items_node;
+   int i, j = 0;
+
+   Eina_Accessor *nodes = efl_ui_list_segarray_node_accessor_get(pd->segarray);
+   EINA_ACCESSOR_FOREACH(nodes, i, items_node)
+     {
+        Efl_Ui_List_Precise_Layouter_Node_Data *nodedata = 
items_node->layout_data;
+        if (!nodedata || !nodedata->realized)
+            continue;
+
+        for(j = 0; j != items_node->length;++j)
+          {
+             layout_item = (Efl_Ui_List_LayoutItem *)items_node->pointers[j];
+             if (layout_item->layout)
+               elements_order = eina_list_append(elements_order, 
layout_item->layout);
+          }
+     }
+
+    return elements_order;
+}
+
 EOLIAN static void
 _efl_ui_list_precise_layouter_efl_ui_list_relayout_model_set(Eo *obj 
EINA_UNUSED, Efl_Ui_List_Precise_Layouter_Data *pd, Efl_Model *model)
 {
diff --git a/src/lib/elementary/efl_ui_list_precise_layouter.eo 
b/src/lib/elementary/efl_ui_list_precise_layouter.eo
index d6d276e4a4..47c5210145 100644
--- a/src/lib/elementary/efl_ui_list_precise_layouter.eo
+++ b/src/lib/elementary/efl_ui_list_precise_layouter.eo
@@ -4,5 +4,6 @@ class Efl.Ui.List.Precise_Layouter (Efl.Object, 
Efl.Ui.List.Relayout)
       Efl.Object.constructor;
       Efl.Ui.List.Relayout.layout_do;
       Efl.Ui.List.Relayout.model { set; }
+      Efl.Ui.List.Relayout.elements { get; }
    }
 }
diff --git a/src/lib/elementary/efl_ui_list_relayout.eo 
b/src/lib/elementary/efl_ui_list_relayout.eo
index 94daa479d5..22ba57fae3 100644
--- a/src/lib/elementary/efl_ui_list_relayout.eo
+++ b/src/lib/elementary/efl_ui_list_relayout.eo
@@ -19,5 +19,11 @@ interface Efl.Ui.List.Relayout (Efl.Interface)
             model: Efl.Model; [[Efl model]]
          }
       }
+      @property elements {
+         get {}
+         values {
+            elements: list<Efl.Gfx>; [[The order to use]]
+         }
+      }
    }
 }

-- 


Reply via email to