efl_ui_position_manager: pass on information about group ids
authorMarcel Hollerbach <mail@marcel-hollerbach.de>
Fri, 16 Aug 2019 12:06:46 +0000 (14:06 +0200)
committerWonki Kim <wonki_.kim@samsung.com>
Fri, 23 Aug 2019 08:49:15 +0000 (17:49 +0900)
every batched call will now contain the id of the first item, if the
conditions in the documentation are met.

ref T8115

Reviewed-by: Cedric BAIL <cedric.bail@free.fr>
Differential Revision: https://phab.enlightenment.org/D9586

src/lib/elementary/efl_ui_collection.c
src/lib/elementary/efl_ui_position_manager_common.h
src/lib/elementary/efl_ui_position_manager_entity.eo
src/lib/elementary/efl_ui_position_manager_grid.c
src/lib/elementary/efl_ui_position_manager_list.c
src/tests/elementary/efl_ui_test_position_manager_common.c

index 1889067..a7f42ef 100644 (file)
@@ -263,21 +263,40 @@ _efl_ui_collection_efl_ui_multi_selectable_selected_items_get(Eo *obj EINA_UNUSE
    return eina_list_iterator_new(pd->selected);
 }
 
-static int
+static inline void
+_fill_group_flag(Eo *item, Efl_Ui_Position_Manager_Batch_Group_State *flag)
+{
+   if (efl_isa(item, EFL_UI_GROUP_ITEM_CLASS))
+     *flag = EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_GROUP;
+   else if (efl_ui_item_parent_get(item))
+     *flag = EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_PART_OF_GROUP;
+   else
+     *flag = EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_NO_GROUP;
+}
+
+static Efl_Ui_Position_Manager_Batch_Result
 _size_accessor_get_at(void *data, int start_id, Eina_Rw_Slice memory)
 {
    Fast_Accessor *accessor = data;
    size_t i;
    const Eina_List *lst = _fast_accessor_get_at(accessor, start_id);
+   Efl_Ui_Position_Manager_Batch_Size_Access *sizes = memory.mem;
+   Efl_Ui_Position_Manager_Batch_Result result = {-1, 0};
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(lst, -1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(lst, result);
 
    for (i = 0; i < memory.len; ++i)
      {
-         Efl_Gfx_Entity *geom = eina_list_data_get(lst);
+         Efl_Gfx_Entity *geom = eina_list_data_get(lst), *parent;
          Eina_Size2D size = efl_gfx_hint_size_min_get(geom);
 
-         ((Eina_Size2D*)memory.mem)[i] = size;
+         parent = efl_ui_item_parent_get(geom);
+         sizes[i].size = size;
+         _fill_group_flag(geom, &sizes[i].group);
+         if (i == 0 && sizes[0].group != EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_GROUP && parent)
+           {
+              result.group_id = efl_pack_index_get(efl_ui_item_container_get(parent), parent);
+           }
          lst = eina_list_next(lst);
          if (!lst)
            {
@@ -285,22 +304,32 @@ _size_accessor_get_at(void *data, int start_id, Eina_Rw_Slice memory)
               break;
            }
      }
+   result.filled_items = i;
 
-   return i;
+   return result;
 }
 
-static int
+static Efl_Ui_Position_Manager_Batch_Result
 _obj_accessor_get_at(void *data, int start_id, Eina_Rw_Slice memory)
 {
    Fast_Accessor *accessor = data;
    size_t i;
    const Eina_List *lst = _fast_accessor_get_at(accessor, start_id);
+   Efl_Ui_Position_Manager_Batch_Entity_Access *objs = memory.mem;
+   Efl_Ui_Position_Manager_Batch_Result result = {-1, 0};
 
    for (i = 0; i < memory.len; ++i)
      {
-         Efl_Gfx_Entity *geom = eina_list_data_get(lst);
+         Efl_Gfx_Entity *geom = eina_list_data_get(lst), *parent;
+
+         parent = efl_ui_item_parent_get(geom);
+         objs[i].entity = geom;
+         _fill_group_flag(geom, &objs[i].group);
+         if (i == 0 && objs[0].group != EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_GROUP && parent)
+           {
+              result.group_id = efl_pack_index_get(efl_ui_item_container_get(parent), parent);
+           }
 
-         ((Efl_Gfx_Entity**)memory.mem)[i] = geom;
          lst = eina_list_next(lst);
          if (!lst)
            {
@@ -308,7 +337,9 @@ _obj_accessor_get_at(void *data, int start_id, Eina_Rw_Slice memory)
               break;
            }
      }
-   return i;
+   result.filled_items = i;
+
+   return result;
 }
 
 EOLIAN static Efl_Object*
index 7f84087..9c97f28 100644 (file)
@@ -12,20 +12,26 @@ typedef struct {
 } Api_Callback;
 
 static inline int
-_fill_buffer(Api_Callback *cb , int start_id, int len, void *data)
+_fill_buffer(Api_Callback *cb , int start_id, int len, int *group_id, void *data)
 {
+   Efl_Ui_Position_Manager_Batch_Result res;
    Eina_Rw_Slice slice;
    slice.mem = data;
    slice.len = len;
 
-   return cb->access(cb->data, start_id, slice);
+   res = cb->access(cb->data, start_id, slice);
+
+   if (group_id)
+     *group_id = res.group_id;
+
+   return res.filled_items;
 }
 
 static inline void
 vis_change_segment(Api_Callback *cb, int a, int b, Eina_Bool flag)
 {
    const int len = 50;
-   Efl_Gfx_Entity *data[len];
+   Efl_Ui_Position_Manager_Batch_Entity_Access data[len];
 
    if (a == b) return;
 
@@ -36,9 +42,9 @@ vis_change_segment(Api_Callback *cb, int a, int b, Eina_Bool flag)
 
         if (buffer_id == 0)
           {
-             EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(cb, MIN(a,b), len, data) >= 0);
+             EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(cb, MIN(a,b), len, NULL, data) >= 0);
           }
-        ent = data[i - MIN(a,b)];
+        ent = data[i - MIN(a,b)].entity;
         if (ent && !flag && (efl_ui_focus_object_focus_get(ent) || efl_ui_focus_object_child_focus_get(ent)))
           {
              //we should not make focused object invisible, rather move it to some parking lot
index fb3bb2d..4e58a6c 100644 (file)
@@ -1,25 +1,51 @@
 import efl_ui;
 
+enum Efl.Ui.Position_Manager.Batch_Group_State{
+  [[Enum expressing the group related state of a item.]]
+  no_group = 0, [[This item is not a group item and is not part of any group.]]
+  group = 1, [[This item is a group item.]]
+  part_of_group = 2 [[This item is part of a group.]]
+}
+
+struct Efl.Ui.Position_Manager.Batch_Entity_Access{
+  [[Struct that is getting filled by the object function callback.]]
+  entity : Efl.Gfx.Entity; [[The canvas object.]]
+  group : Efl.Ui.Position_Manager.Batch_Group_State; [[If this is a group item.]]
+}
+
+struct Efl.Ui.Position_Manager.Batch_Size_Access{
+  [[Struct that is getting filled by the size function callback.]]
+  size : Eina.Size2D; [[The size of the element.]]
+  group : Efl.Ui.Position_Manager.Batch_Group_State; [[If this is a group item.]]
+}
+
+struct Efl.Ui.Position_Manager.Batch_Result {
+   [[Struct that is returned by the function callbacks.]]
+   group_id : int; [[The group of the first item. If the first item is a group, or the first item does not have a group, -1 will be the id]]
+   filled_items : int; [[The number of items that are filled into the slice]]
+}
+
 function Efl.Ui.Position_Manager.Batch_Access_Entity {
-   [[ Function callback for getting a batch of items]]
+   [[ Function callback for getting a batch of items.]]
    params {
       start_id : int; [[The id of the first item to fetch]]
-      memory : rw_slice<Efl.Gfx.Entity>; [[The slice to fill the information in, the full slice will be filled if there are enough items]]
+      memory : rw_slice<Efl.Ui.Position_Manager.Batch_Entity_Access>; [[The slice to fill the information in, the full slice will be filled if there are enough items]]
    }
-   return: int; [[The number of filled elements in the slice]]
+   return: Efl.Ui.Position_Manager.Batch_Result; [[The returned stats of this function call.]]
 };
 
+
 function Efl.Ui.Position_Manager.Batch_Access_Size {
    [[ Function callback for getting sizes of a batch of items]]
    params {
       start_id : int; [[The id of the first item to fetch]]
-      memory : rw_slice<Efl.Gfx.Entity>; [[The slice to fill the information in, the full slice will be filled if there are enough items]]
+      memory : rw_slice<Efl.Ui.Position_Manager.Batch_Size_Access>; [[The slice to fill the information in, the full slice will be filled if there are enough items]]
    }
-   return: int; [[The number of filled elements in the slice]]
+   return: Efl.Ui.Position_Manager.Batch_Result; [[The returned stats of this function call]]
 };
 
 struct Efl.Ui.Position_Manager.Range_Update {
-   [[A struct containing the the updated range of visible items in this position manger]]
+   [[A struct containing the the updated range of visible items in this position manger.]]
    start_id : uint; [[The first item that is visible]]
    end_id : uint; [[The last item that is visible]]
 }
index 909f986..38b205c 100644 (file)
@@ -37,7 +37,7 @@ _reposition_content(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd)
    int relevant_space_size, relevant_viewport;
    unsigned int start_id, end_id, step;
    const int len = 100;
-   Efl_Gfx_Entity *obj_buffer[len];
+   Efl_Ui_Position_Manager_Batch_Entity_Access obj_buffer[len];
    Efl_Ui_Position_Manager_Range_Update ev;
 
    if (!pd->size) return;
@@ -91,7 +91,7 @@ _reposition_content(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd)
 
         if (buffer_id == 0)
           {
-             EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->object, i, len, obj_buffer) > 0);
+             EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->object, i, len, NULL, obj_buffer) > 0);
           }
 
         if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
@@ -107,7 +107,7 @@ _reposition_content(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd)
              geom.x -= (relevant_space_size);
           }
 
-        ent = ((Efl_Gfx_Entity**)obj_buffer)[buffer_id];
+        ent = obj_buffer[buffer_id].entity;
 
         //printf(">%d (%d, %d, %d, %d) %p\n", i, geom.x, geom.y, geom.w, geom.h, ent);
         efl_gfx_entity_geometry_set(ent, geom);
@@ -224,12 +224,12 @@ _efl_ui_position_manager_grid_efl_ui_position_manager_entity_scroll_position_set
 EOLIAN static void
 _efl_ui_position_manager_grid_efl_ui_position_manager_entity_item_added(Eo *obj, Efl_Ui_Position_Manager_Grid_Data *pd, int added_index, Efl_Gfx_Entity *subobj EINA_UNUSED)
 {
-   Eina_Size2D size[1];
+   Efl_Ui_Position_Manager_Batch_Size_Access size[1];
    pd->size ++;
 
    efl_gfx_entity_visible_set(subobj, EINA_FALSE);
-   EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, added_index, 1, &size) == 1);
-   _update_min_size(obj, pd, added_index, size[0]);
+   EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, added_index, 1, NULL, &size) == 1);
+   _update_min_size(obj, pd, added_index, size[0].size);
    _flush_min_size(obj, pd);
    _flush_abs_size(obj, pd);
    _reposition_content(obj, pd); //FIXME we might can skip that
@@ -253,16 +253,16 @@ EOLIAN static void
 _efl_ui_position_manager_grid_efl_ui_position_manager_entity_item_size_changed(Eo *obj, Efl_Ui_Position_Manager_Grid_Data *pd, int start_id, int end_id)
 {
    const int len = 50;
-   Eina_Size2D data[len];
+   Efl_Ui_Position_Manager_Batch_Size_Access data[len];
 
    for (int i = start_id; i <= end_id; ++i)
      {
         int buffer_id = (i-start_id) % len;
         if (buffer_id == 0)
           {
-             EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, start_id, len, data) >= 0);
+             EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, start_id, len, NULL, data) >= 0);
           }
-        _update_min_size(obj, pd, i, data[i-start_id]);
+        _update_min_size(obj, pd, i, data[i-start_id].size);
      }
 
    _flush_min_size(obj, pd);
index d3cd973..a4bebde 100644 (file)
@@ -42,7 +42,7 @@ cache_require(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd)
 {
    unsigned int i;
    const int len = 100;
-   Eina_Size2D size_buffer[100];
+   Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[100];
 
 
    if (pd->size_cache) return;
@@ -67,9 +67,9 @@ cache_require(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd)
 
         if (buffer_id == 0)
           {
-             EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, i, len, size_buffer) > 0);
+             EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, i, len, NULL, size_buffer) > 0);
           }
-       size = size_buffer[buffer_id];
+       size = size_buffer[buffer_id].size;
 
         if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
           {
@@ -140,8 +140,8 @@ position_content(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd)
    unsigned int start_id = 0, end_id = 0, i;
    int relevant_space_size, relevant_viewport;
    const int len = 100;
-   Eina_Size2D size_buffer[len];
-   Efl_Gfx_Entity *obj_buffer[len];
+   Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[len];
+   Efl_Ui_Position_Manager_Batch_Entity_Access obj_buffer[len];
    Efl_Ui_Position_Manager_Range_Update ev;
 
    if (!pd->size) return;
@@ -214,14 +214,14 @@ position_content(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd)
           {
              int res1, res2;
 
-             res1 = _fill_buffer(&pd->object, i, len, obj_buffer);
-             res2 = _fill_buffer(&pd->min_size, i, len, size_buffer);
+             res1 = _fill_buffer(&pd->object, i, len, NULL, obj_buffer);
+             res2 = _fill_buffer(&pd->min_size, i, len, NULL, size_buffer);
              EINA_SAFETY_ON_FALSE_RETURN(res1 == res2);
              EINA_SAFETY_ON_FALSE_RETURN(res2 > 0);
           }
 
-        size = size_buffer[buffer_id];
-        ent = obj_buffer[buffer_id];
+        size = size_buffer[buffer_id].size;
+        ent = obj_buffer[buffer_id].entity;
 
         if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
           geom.h = size.h;
@@ -333,7 +333,7 @@ _efl_ui_position_manager_list_efl_ui_position_manager_entity_position_single_ite
    Eina_Size2D space_size;
    int relevant_space_size;
    Eina_Size2D size;
-   Eina_Size2D size_buffer[1];
+   Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[1];
 
    if (!pd->size) return EINA_RECT(0,0,0,0);
 
@@ -353,9 +353,9 @@ _efl_ui_position_manager_list_efl_ui_position_manager_entity_position_single_ite
 
    geom = pd->viewport;
 
-   EINA_SAFETY_ON_FALSE_RETURN_VAL(_fill_buffer(&pd->min_size, idx, 1, size_buffer) == 1, EINA_RECT_EMPTY());
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(_fill_buffer(&pd->min_size, idx, 1, NULL, size_buffer) == 1, EINA_RECT_EMPTY());
 
-   size = size_buffer[0];
+   size = size_buffer[0].size;
 
    if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
      {
index ea89662..5901424 100644 (file)
@@ -25,33 +25,42 @@ item_container_teardown()
    win = NULL;
 }
 
-static int
+static Efl_Ui_Position_Manager_Batch_Result
 _size_accessor_get_at(void *data EINA_UNUSED, int start_id, Eina_Rw_Slice memory)
 {
    int i;
+   Efl_Ui_Position_Manager_Batch_Size_Access *sizes = memory.mem;
+   Efl_Ui_Position_Manager_Batch_Result result;
 
    for (i = start_id; i < (int)(MIN(start_id + memory.len, eina_inarray_count(arr_size))); ++i)
      {
-         Eina_Size2D *size = eina_inarray_nth(arr_size, i);
+        Eina_Size2D *size = eina_inarray_nth(arr_size, i);
 
-         ((Eina_Size2D*)memory.mem)[i - start_id] = *size;
+        sizes[i - start_id].size = *size;
+        sizes[i - start_id].group = 0;
      }
-   return i - start_id;
+   result.filled_items = i - start_id;
+   result.group_id = -1;
+   return result;
 }
 
-static int
+static Efl_Ui_Position_Manager_Batch_Result
 _obj_accessor_get_at(void *data EINA_UNUSED, int start_id, Eina_Rw_Slice memory)
 {
    int i;
+   Efl_Ui_Position_Manager_Batch_Entity_Access *objs = memory.mem;
+   Efl_Ui_Position_Manager_Batch_Result result;
 
    for (i = start_id; i < (int)(MIN(start_id + memory.len, eina_array_count(arr_obj))); ++i)
      {
          Efl_Gfx_Entity *geom = eina_array_data_get(arr_obj, i);
 
-         ((Efl_Gfx_Entity**)memory.mem)[i - start_id] = geom;
+         objs[i - start_id].entity = geom;
+         objs[i - start_id].group = 0;
      }
-
-   return i - start_id;
+   result.filled_items = i - start_id;
+   result.group_id = -1;
+   return result;
 }
 static void
 _initial_setup(void)