diff --git a/src/lib/elementary/efl_ui_collection.c b/src/lib/elementary/efl_ui_collection.c index 1889067a5e..a7f42ef3a8 100644 --- a/src/lib/elementary/efl_ui_collection.c +++ b/src/lib/elementary/efl_ui_collection.c @@ -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* diff --git a/src/lib/elementary/efl_ui_position_manager_common.h b/src/lib/elementary/efl_ui_position_manager_common.h index 7f84087b00..9c97f2832f 100644 --- a/src/lib/elementary/efl_ui_position_manager_common.h +++ b/src/lib/elementary/efl_ui_position_manager_common.h @@ -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 diff --git a/src/lib/elementary/efl_ui_position_manager_entity.eo b/src/lib/elementary/efl_ui_position_manager_entity.eo index fb3bb2d14a..4e58a6ce1c 100644 --- a/src/lib/elementary/efl_ui_position_manager_entity.eo +++ b/src/lib/elementary/efl_ui_position_manager_entity.eo @@ -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; [[The slice to fill the information in, the full slice will be filled if there are enough items]] + memory : rw_slice; [[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; [[The slice to fill the information in, the full slice will be filled if there are enough items]] + memory : rw_slice; [[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]] } diff --git a/src/lib/elementary/efl_ui_position_manager_grid.c b/src/lib/elementary/efl_ui_position_manager_grid.c index 909f986f3e..38b205c414 100644 --- a/src/lib/elementary/efl_ui_position_manager_grid.c +++ b/src/lib/elementary/efl_ui_position_manager_grid.c @@ -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); diff --git a/src/lib/elementary/efl_ui_position_manager_list.c b/src/lib/elementary/efl_ui_position_manager_list.c index d3cd973a06..a4bebde2d6 100644 --- a/src/lib/elementary/efl_ui_position_manager_list.c +++ b/src/lib/elementary/efl_ui_position_manager_list.c @@ -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) { diff --git a/src/tests/elementary/efl_ui_test_position_manager_common.c b/src/tests/elementary/efl_ui_test_position_manager_common.c index ea89662837..5901424dc1 100644 --- a/src/tests/elementary/efl_ui_test_position_manager_common.c +++ b/src/tests/elementary/efl_ui_test_position_manager_common.c @@ -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)