efl_ui_position_manager: pass on information about group ids

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
This commit is contained in:
Marcel Hollerbach 2019-08-16 14:06:46 +02:00
parent f0b24631c0
commit e2b859bdae
6 changed files with 121 additions and 49 deletions

View 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*

View 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

View 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]]
}

View 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);

View 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)
{

View 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)