forked from enlightenment/efl
Compare commits
9 Commits
master
...
devs/bu5hm
Author | SHA1 | Date |
---|---|---|
Marcel Hollerbach | 3e9e03403d | |
Marcel Hollerbach | 774b4ff24b | |
Marcel Hollerbach | 9d1a693d29 | |
Marcel Hollerbach | a50c30a8bc | |
Marcel Hollerbach | 1587f0ce46 | |
Marcel Hollerbach | 91a279e560 | |
Marcel Hollerbach | d6a62c36ae | |
Marcel Hollerbach | 9cd1a27987 | |
Marcel Hollerbach | a2bd17b736 |
|
@ -208,4 +208,5 @@ collections {
|
|||
#include "edc/efl/tab_bar.edc"
|
||||
#include "edc/efl/tab_page.edc"
|
||||
#include "edc/efl/item_container.edc"
|
||||
#include "edc/efl/group_item.edc"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
|
||||
|
||||
group { "efl/group_item"; nomouse; program_source: "efl";
|
||||
images.image: "shadow_square_tiny.png" COMP;
|
||||
images.image: "bevel_out.png" COMP;
|
||||
images.image: "horizontal_separated_bar_small_glow.png" COMP;
|
||||
|
||||
parts {
|
||||
image { "shadow_vbar";
|
||||
desc { "default";
|
||||
rel1.offset: -3 -2;
|
||||
rel1.to: "base_vbar";
|
||||
rel2.offset: 2 4;
|
||||
rel2.to: "base_vbar";
|
||||
image.normal: "shadow_square_tiny.png";
|
||||
image.border: 6 6 6 6;
|
||||
fill.smooth: 0;
|
||||
}
|
||||
}
|
||||
image { "base_vbar";
|
||||
desc { "default";
|
||||
image.normal: "vgrad_med_lighter.png";
|
||||
fill.smooth: 0;
|
||||
min: 5 13;
|
||||
TILED_HORIZ(120)
|
||||
}
|
||||
}
|
||||
image { "bevel_vbar";
|
||||
desc { "default";
|
||||
rel1.to: "base_vbar";
|
||||
rel2.to: "base_vbar";
|
||||
image.normal: "bevel_out.png";
|
||||
image.border: 1 1 1 1;
|
||||
image.middle: 0;
|
||||
fill.smooth: 0;
|
||||
min: 5 5;
|
||||
}
|
||||
}
|
||||
|
||||
text { "efl.text";
|
||||
effect: SHADOW BOTTOM;
|
||||
scale;
|
||||
desc { "default";
|
||||
rel1.offset: 2 3;
|
||||
rel1.relative: 1.0 0.0;
|
||||
rel1.to_x: "efl.icon";
|
||||
rel2.offset: -3 -3;
|
||||
rel2.relative: 0.0 1.0;
|
||||
rel2.to_x: "efl.extra";
|
||||
color: FN_COL_DEFAULT;
|
||||
color_class: "list_group_item";
|
||||
text { font: FNBD; size: 10;
|
||||
min: 1 1;
|
||||
ellipsis: -1;
|
||||
align: 0.0 0.5;
|
||||
text_class: "list_group_item";
|
||||
}
|
||||
link.base: "efl,state,enabled";
|
||||
}
|
||||
desc { "disabled";
|
||||
inherit: "default";
|
||||
color: FN_COL_DISABLE;
|
||||
color_class: "list_group_item_disabled";
|
||||
link.base: "efl,state,disabled";
|
||||
}
|
||||
}
|
||||
swallow { "pad"; mouse;
|
||||
desc { "default";
|
||||
fixed: 1 0;
|
||||
align: 0.0 0.5;
|
||||
rel1.offset: 2 2;
|
||||
rel2.relative: 0.0 1.0;
|
||||
rel2.offset: 2 -3;
|
||||
}
|
||||
}
|
||||
swallow { "efl.icon"; mouse;
|
||||
desc { "default";
|
||||
fixed: 1 0;
|
||||
align: 0.0 0.5;
|
||||
rel1.to_x: "pad";
|
||||
rel1.relative: 1.0 0.0;
|
||||
rel1.offset: -1 2;
|
||||
rel2.to_x: "pad";
|
||||
rel2.relative: 1.0 1.0;
|
||||
rel2.offset: -1 -3;
|
||||
}
|
||||
}
|
||||
swallow { "efl.extra"; mouse;
|
||||
desc { "default";
|
||||
fixed: 1 0;
|
||||
align: 1.0 0.5;
|
||||
rel1.offset: -3 2;
|
||||
rel1.relative: 1.0 0.0;
|
||||
rel2.offset: -3 -3;
|
||||
}
|
||||
}
|
||||
image { "bar";
|
||||
desc { "default";
|
||||
image.normal: "horizontal_separated_bar_small_glow.png";
|
||||
image.border: 4 4 4 4;
|
||||
fill.smooth: 0;
|
||||
fixed: 0 1;
|
||||
rel1.relative: 0.0 1.0;
|
||||
rel1.offset: -3 -6;
|
||||
rel2.offset: 2 3;
|
||||
link.base: "efl,state,enabled";
|
||||
}
|
||||
desc { "disabled";
|
||||
inherit: "default";
|
||||
color: 255 255 255 64;
|
||||
link.base: "efl,state,disabled";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -156,7 +156,7 @@ elementary_test_src = [
|
|||
'test_gesture_framework.c',
|
||||
'test_ui_tab_pager.c',
|
||||
'test_ui_relative_layout.c',
|
||||
'test_ui_item_container.c',
|
||||
'test_ui_collection.c',
|
||||
'test_ui_items.c',
|
||||
'test_ui_frame.c',
|
||||
'test.h'
|
||||
|
|
|
@ -86,7 +86,7 @@ _widget_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
|
|||
}
|
||||
|
||||
static void
|
||||
_add_item(Efl_Ui_Collection *c)
|
||||
_add_item(Efl_Ui_Collection *c, Eo *cont)
|
||||
{
|
||||
Efl_Class *itc = efl_key_data_get(c, "__item_class");
|
||||
char buf[PATH_MAX];
|
||||
|
@ -126,7 +126,7 @@ _add_item(Efl_Ui_Collection *c)
|
|||
efl_gfx_hint_size_min_set(il, EINA_SIZE2D(100, 180));
|
||||
else
|
||||
efl_gfx_hint_size_min_set(il, EINA_SIZE2D(40, 40+(i%2)*40));
|
||||
efl_pack_end(c, il);
|
||||
efl_pack_end(cont, il);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -138,7 +138,7 @@ _remove_all_cb(void *data, const Efl_Event *ev EINA_UNUSED)
|
|||
static void
|
||||
_add_one_item(void *data, const Efl_Event *ev EINA_UNUSED)
|
||||
{
|
||||
_add_item(data);
|
||||
_add_item(data, data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -146,7 +146,7 @@ _add_thousend_items(void *data, const Efl_Event *ev EINA_UNUSED)
|
|||
{
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
{
|
||||
_add_item(data);
|
||||
_add_item(data, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,9 +158,9 @@ _select_value_cb(void *data, const Efl_Event *ev)
|
|||
efl_ui_select_mode_set(c, efl_ui_radio_group_selected_value_get(ev->object));
|
||||
}
|
||||
|
||||
void create_item_container_ui(Efl_Ui_Position_Manager_Entity *manager, const Efl_Class *item, const char *name)
|
||||
void create_item_container_ui(const Efl_Class *collection_class, const Efl_Class *item, const char *name)
|
||||
{
|
||||
Efl_Ui_Win *win, *o, *tbl, *item_container, *bx;
|
||||
Efl_Ui_Win *win, *o, *tbl, *item_container, *bx, *git;
|
||||
Match_Content_Ctx *ctx = calloc(1, sizeof(*ctx));
|
||||
|
||||
win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
|
||||
|
@ -170,14 +170,28 @@ void create_item_container_ui(Efl_Ui_Position_Manager_Entity *manager, const Efl
|
|||
tbl = efl_add(EFL_UI_TABLE_CLASS, win);
|
||||
efl_content_set(win, tbl);
|
||||
|
||||
item_container = o = efl_add(EFL_UI_COLLECTION_CLASS, win,
|
||||
efl_ui_collection_position_manager_set(efl_added, manager));
|
||||
item_container = o = efl_add(collection_class, win);
|
||||
efl_key_data_set(o, "__item_class", item);
|
||||
efl_event_callback_add(o, EFL_EVENT_DEL, _widget_del_cb, ctx);
|
||||
for (int i = 0; i < 2000; ++i)
|
||||
for (int i = 0; i < 200; ++i)
|
||||
{
|
||||
_add_item(o);
|
||||
_add_item(o, o);
|
||||
}
|
||||
for (int j = 0; j < 5; ++j)
|
||||
{
|
||||
Eina_Strbuf *buf = eina_strbuf_new();
|
||||
|
||||
eina_strbuf_append_printf(buf, "Group #%d", j);
|
||||
git = efl_add(EFL_UI_GROUP_ITEM_CLASS, o);
|
||||
efl_text_set(git, eina_strbuf_release(buf));
|
||||
efl_pack_end(o, git);
|
||||
efl_gfx_hint_size_min_set(git, EINA_SIZE2D(40, 40+40));
|
||||
for (int i = 0; i < 200; ++i)
|
||||
{
|
||||
_add_item(o, git);
|
||||
}
|
||||
}
|
||||
|
||||
efl_pack_table(tbl, o, 1, 0, 1, 12);
|
||||
ctx->c = o;
|
||||
|
||||
|
@ -278,12 +292,12 @@ void test_efl_ui_collection_grid(void *data EINA_UNUSED,
|
|||
Evas_Object *obj EINA_UNUSED,
|
||||
void *event_info EINA_UNUSED)
|
||||
{
|
||||
create_item_container_ui(efl_new(EFL_UI_POSITION_MANAGER_GRID_CLASS), EFL_UI_GRID_DEFAULT_ITEM_CLASS, "Efl.Ui.Item_Container Grid");
|
||||
create_item_container_ui(EFL_UI_GRID_CLASS, EFL_UI_GRID_DEFAULT_ITEM_CLASS, "Efl.Ui.Grid");
|
||||
}
|
||||
|
||||
void test_efl_ui_collection_list(void *data EINA_UNUSED,
|
||||
Evas_Object *obj EINA_UNUSED,
|
||||
void *event_info EINA_UNUSED)
|
||||
{
|
||||
create_item_container_ui(efl_new(EFL_UI_POSITION_MANAGER_LIST_CLASS), EFL_UI_LIST_DEFAULT_ITEM_CLASS, "Efl.Ui.Item_Container List");
|
||||
create_item_container_ui(EFL_UI_LIST_CLASS, EFL_UI_LIST_DEFAULT_ITEM_CLASS, "Efl.Ui.List");
|
||||
}
|
|
@ -84,4 +84,13 @@ void test_efl_ui_item(void *data EINA_UNUSED,
|
|||
efl_gfx_hint_size_min_set(o, EINA_SIZE2D(40, 40));
|
||||
efl_ui_widget_disabled_set(o, EINA_TRUE);
|
||||
efl_pack_end(box, o);
|
||||
|
||||
o = _item_add(box, EFL_UI_GROUP_ITEM_CLASS, 5);
|
||||
efl_gfx_hint_size_min_set(o, EINA_SIZE2D(40, 40+40));
|
||||
efl_pack_end(box, o);
|
||||
|
||||
o = _item_add(box, EFL_UI_GROUP_ITEM_CLASS, 6);
|
||||
efl_gfx_hint_size_min_set(o, EINA_SIZE2D(40, 40));
|
||||
efl_ui_widget_disabled_set(o, EINA_TRUE);
|
||||
efl_pack_end(box, o);
|
||||
}
|
||||
|
|
|
@ -182,6 +182,8 @@ EAPI void efl_ui_focus_relation_free(Efl_Ui_Focus_Relations *rel);
|
|||
# include <efl_ui_layout_part_text.eo.h>
|
||||
# include <efl_ui_layout_part_table.eo.h>
|
||||
# include <efl_ui_item.eo.h>
|
||||
# include <efl_ui_default_item.eo.h>
|
||||
# include <efl_ui_group_item.eo.h>
|
||||
# include <efl_ui_win_part.eo.h>
|
||||
# include <efl_ui_bg.eo.h>
|
||||
# include <efl_ui_box.eo.h>
|
||||
|
@ -268,7 +270,8 @@ typedef Eo Efl_Ui_Spotlight_Indicator;
|
|||
# include <efl_ui_text_alert_popup.eo.h>
|
||||
# include <efl_ui_anchor_popup.eo.h>
|
||||
# include <efl_ui_popup_part_backwall.eo.h>
|
||||
|
||||
# include <efl_ui_grid.eo.h>
|
||||
# include <efl_ui_list.eo.h>
|
||||
/**
|
||||
* Initialize Elementary
|
||||
*
|
||||
|
|
|
@ -330,10 +330,6 @@ typedef Eo Efl_Ui_Focus_Manager;
|
|||
# include <efl_ui_slider.eo.h>
|
||||
# include <efl_ui_slider_interval.eo.h>
|
||||
# include <efl_ui_layout_factory.eo.h>
|
||||
# include <efl_ui_item_part_text.eo.h>
|
||||
# include <efl_ui_item_part_icon.eo.h>
|
||||
# include <efl_ui_item_part_extra.eo.h>
|
||||
# include <efl_ui_item_part_content.eo.h>
|
||||
# include <efl_ui_item.eo.h>
|
||||
# include <efl_ui_list_default_item.eo.h>
|
||||
# include <efl_ui_list_placeholder_item.eo.h>
|
||||
|
|
|
@ -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*
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "elementary_config.h"
|
||||
#endif
|
||||
|
||||
#define EFL_UI_LIST_DEFAULT_ITEM_PROTECTED
|
||||
#define EFL_PART_PROTECTED
|
||||
|
||||
#include <Elementary.h>
|
||||
|
||||
#include "elm_priv.h"
|
||||
#include "elm_part_helper.h"
|
||||
|
||||
#define MY_CLASS EFL_UI_DEFAULT_ITEM_CLASS
|
||||
#define MY_CLASS_PFX efl_ui_default_item
|
||||
|
||||
#define MY_CLASS_NAME "Efl.Ui.Default_Item"
|
||||
|
||||
ELM_PART_TEXT_DEFAULT_GET(efl_ui_default_item, "efl.text")
|
||||
ELM_PART_TEXT_DEFAULT_IMPLEMENT(efl_ui_default_item, void)
|
||||
ELM_PART_MARKUP_DEFAULT_IMPLEMENT(efl_ui_default_item, void)
|
||||
ELM_PART_CONTENT_DEFAULT_GET(efl_ui_default_item, "efl.icon")
|
||||
ELM_PART_CONTENT_DEFAULT_IMPLEMENT(efl_ui_default_item, void)
|
||||
|
||||
EOLIAN static Efl_Object *
|
||||
_efl_ui_default_item_efl_part_part_get(const Eo *obj, void *pd EINA_UNUSED, const char *part)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
|
||||
if (eina_streq(part, "text"))
|
||||
return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_TEXT_CLASS, obj, "efl.text");
|
||||
else if (eina_streq(part, "icon"))
|
||||
return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_CONTENT_CLASS, obj, "efl.icon");
|
||||
else if (eina_streq(part, "extra"))
|
||||
return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_CONTENT_CLASS, obj, "efl.extra");
|
||||
|
||||
return efl_part_get(efl_super(obj, MY_CLASS), part);
|
||||
}
|
||||
|
||||
|
||||
#define EFL_UI_DEFAULT_ITEM_EXTRA_OPS \
|
||||
ELM_PART_TEXT_DEFAULT_OPS(efl_ui_default_item), \
|
||||
ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_default_item)
|
||||
|
||||
#include "efl_ui_default_item.eo.c"
|
|
@ -0,0 +1,32 @@
|
|||
abstract @beta Efl.Ui.Default_Item extends Efl.Ui.Item implements
|
||||
Efl.Text,
|
||||
Efl.Text_Markup,
|
||||
Efl.Ui.L10n,
|
||||
Efl.Content
|
||||
{
|
||||
[[Default Item Class.
|
||||
|
||||
This class defines the standard parts of casual efl items.
|
||||
The details about placement or item layout preferences are left to the extending classes.
|
||||
Every text property related changes are mirrored to the text part. Content changes are mirrored to the content part.
|
||||
|
||||
]]
|
||||
data: null;
|
||||
parts {
|
||||
text: Efl.Ui.Layout_Part_Text; [[The text part for default item.
|
||||
text part is the caption of the item.]]
|
||||
icon: Efl.Ui.Layout_Part_Content; [[The icon content part for default item.
|
||||
icon part is the main content of item.]]
|
||||
end: Efl.Ui.Layout_Part_Content; [[The extra content part for default item.
|
||||
extra part is the spare content of item.
|
||||
you can swallow small badge widget such as check, radio.]]
|
||||
}
|
||||
implements {
|
||||
Efl.Text.text { get; set; }
|
||||
Efl.Text_Markup.markup { get; set; }
|
||||
Efl.Ui.L10n.l10n_text { get; set; }
|
||||
Efl.Content.content { get; set; }
|
||||
Efl.Content.content_unset;
|
||||
Efl.Part.part_get;
|
||||
}
|
||||
}
|
|
@ -16,50 +16,16 @@
|
|||
#define MY_CLASS_NAME "Efl.Ui.Grid_Default_Item"
|
||||
|
||||
EOLIAN static Efl_Object *
|
||||
_efl_ui_grid_default_item_efl_object_finalize(Eo *obj, void *pd EINA_UNUSED)
|
||||
_efl_ui_grid_default_item_efl_object_constructor(Eo *obj, void *pd EINA_UNUSED)
|
||||
{
|
||||
Eo *eo;
|
||||
eo = efl_finalize(efl_super(obj, MY_CLASS));
|
||||
ELM_WIDGET_DATA_GET_OR_RETURN(eo, wd, eo);
|
||||
Eina_Error theme_apply = efl_ui_layout_theme_set(obj, "grid_item", NULL, NULL);
|
||||
|
||||
if (theme_apply == EFL_UI_THEME_APPLY_ERROR_GENERIC)
|
||||
CRI("Default Item(%p) failed to set theme [efl/grid_item]!", eo);
|
||||
eo = efl_constructor(efl_super(obj, MY_CLASS));
|
||||
|
||||
if (!elm_widget_theme_klass_get(obj))
|
||||
elm_widget_theme_klass_set(obj, "grid_item");
|
||||
|
||||
return eo;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_grid_default_item_efl_object_destructor(Eo *obj, void *pd EINA_UNUSED)
|
||||
{
|
||||
efl_destructor(efl_super(obj, MY_CLASS));
|
||||
}
|
||||
|
||||
/* Efl.Part */
|
||||
|
||||
ELM_PART_TEXT_DEFAULT_GET(efl_ui_grid_default_item, "efl.text")
|
||||
ELM_PART_TEXT_DEFAULT_IMPLEMENT(efl_ui_grid_default_item, void)
|
||||
ELM_PART_MARKUP_DEFAULT_IMPLEMENT(efl_ui_grid_default_item, void)
|
||||
ELM_PART_CONTENT_DEFAULT_GET(efl_ui_grid_default_item, "efl.icon")
|
||||
ELM_PART_CONTENT_DEFAULT_IMPLEMENT(efl_ui_grid_default_item, void)
|
||||
|
||||
EOLIAN static Efl_Object *
|
||||
_efl_ui_grid_default_item_efl_part_part_get(const Eo *obj, void *wd EINA_UNUSED, const char *part)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
|
||||
if (eina_streq(part, "text"))
|
||||
return ELM_PART_IMPLEMENT(EFL_UI_ITEM_PART_TEXT_CLASS, obj, "efl.text");
|
||||
else if (eina_streq(part, "icon"))
|
||||
return ELM_PART_IMPLEMENT(EFL_UI_ITEM_PART_ICON_CLASS, obj, "efl.icon");
|
||||
else if (eina_streq(part, "extra"))
|
||||
return ELM_PART_IMPLEMENT(EFL_UI_ITEM_PART_EXTRA_CLASS, obj, "efl.extra");
|
||||
|
||||
return efl_part_get(efl_super(obj, MY_CLASS), part);
|
||||
}
|
||||
/* Efl.Part end */
|
||||
|
||||
/* Internal EO APIs and hidden overrides */
|
||||
#define EFL_UI_GRID_DEFAULT_ITEM_EXTRA_OPS \
|
||||
ELM_PART_TEXT_DEFAULT_OPS(efl_ui_grid_default_item), \
|
||||
ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_grid_default_item)
|
||||
|
||||
#include "efl_ui_grid_default_item.eo.c"
|
||||
|
|
|
@ -1,33 +1,9 @@
|
|||
|
||||
class @beta Efl.Ui.Grid_Default_Item extends Efl.Ui.Item implements
|
||||
Efl.Text,
|
||||
Efl.Text_Markup,
|
||||
Efl.Ui.L10n,
|
||||
Efl.Content
|
||||
class @beta Efl.Ui.Grid_Default_Item extends Efl.Ui.Default_Item
|
||||
{
|
||||
[[Grid Default Item class.
|
||||
This class need to be sub object of list widget.
|
||||
Text and contents can be set using @Efl.Text,
|
||||
@Efl.Content or @Efl.Part.]]
|
||||
[[Grid Default Item class.]]
|
||||
data: null;
|
||||
parts {
|
||||
text: Efl.Ui.Item_Part_Text; [[The text part for grid default item.
|
||||
text part is the caption of grid item.]]
|
||||
icon: Efl.Ui.Item_Part_Icon; [[The icon content part for grid default item.
|
||||
icon part is the main content of grid item.]]
|
||||
end: Efl.Ui.Item_Part_Extra; [[The extra content part for grid default item.
|
||||
extra part is the spare content of grid item.
|
||||
you can swallow small badge widget such as check, radio.]]
|
||||
}
|
||||
implements {
|
||||
//Efl.Object
|
||||
Efl.Object.finalize;
|
||||
Efl.Object.destructor;
|
||||
Efl.Text.text { get; set; }
|
||||
Efl.Text_Markup.markup { get; set; }
|
||||
Efl.Ui.L10n.l10n_text { get; set; }
|
||||
Efl.Content.content { get; set; }
|
||||
Efl.Content.content_unset;
|
||||
Efl.Part.part_get;
|
||||
Efl.Object.constructor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,303 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "elementary_config.h"
|
||||
#endif
|
||||
|
||||
#define EFL_UI_LIST_DEFAULT_ITEM_PROTECTED
|
||||
#define EFL_PART_PROTECTED
|
||||
|
||||
#include <Elementary.h>
|
||||
|
||||
#include "elm_priv.h"
|
||||
#include "elm_part_helper.h"
|
||||
|
||||
#define MY_CLASS EFL_UI_GROUP_ITEM_CLASS
|
||||
#define MY_CLASS_PFX efl_ui_group_item
|
||||
|
||||
#define MY_CLASS_NAME "Efl.Ui.Grid_Default_Item"
|
||||
|
||||
|
||||
typedef struct {
|
||||
Eina_List *registered_items;
|
||||
} Efl_Ui_Group_Item_Data;
|
||||
|
||||
EOLIAN static Efl_Object*
|
||||
_efl_ui_group_item_efl_object_constructor(Eo *obj, Efl_Ui_Group_Item_Data *pd EINA_UNUSED)
|
||||
{
|
||||
if (!elm_widget_theme_klass_get(obj))
|
||||
elm_widget_theme_klass_set(obj, "group_item");
|
||||
|
||||
return efl_constructor(efl_super(obj, MY_CLASS));
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_group_item_efl_object_invalidate(Eo *obj, Efl_Ui_Group_Item_Data *pd EINA_UNUSED)
|
||||
{
|
||||
efl_pack_clear(obj);
|
||||
efl_invalidate(efl_super(obj, MY_CLASS));
|
||||
}
|
||||
|
||||
static void _unregister_item(Eo *obj EINA_UNUSED, Efl_Ui_Group_Item_Data *pd, Efl_Gfx_Entity *subobj);
|
||||
|
||||
static void
|
||||
_invalidate(void *data, const Efl_Event *ev)
|
||||
{
|
||||
Efl_Ui_Group_Item_Data *pd = efl_data_scope_safe_get(data, MY_CLASS);
|
||||
if (!pd) return;
|
||||
_unregister_item(data, pd, ev->object);
|
||||
}
|
||||
|
||||
static void
|
||||
_register_item(Eo *obj, Efl_Ui_Group_Item_Data *pd, Efl_Gfx_Entity *subobj)
|
||||
{
|
||||
efl_ui_item_parent_set(subobj, obj);
|
||||
efl_event_callback_add(subobj, EFL_EVENT_INVALIDATE, _invalidate, obj);
|
||||
pd->registered_items = eina_list_append(pd->registered_items, subobj);
|
||||
}
|
||||
|
||||
static void
|
||||
_unregister_item(Eo *obj EINA_UNUSED, Efl_Ui_Group_Item_Data *pd, Efl_Gfx_Entity *subobj)
|
||||
{
|
||||
efl_ui_item_container_set(subobj, NULL);
|
||||
efl_event_callback_del(subobj, EFL_EVENT_INVALIDATE, _invalidate, obj);
|
||||
pd->registered_items = eina_list_remove(pd->registered_items, subobj);
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_ui_group_item_efl_pack_pack_clear(Eo *obj EINA_UNUSED, Efl_Ui_Group_Item_Data *pd)
|
||||
{
|
||||
Eo *item;
|
||||
|
||||
while(pd->registered_items)
|
||||
{
|
||||
item = eina_list_data_get(pd->registered_items);
|
||||
efl_del(item);
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_ui_group_item_efl_pack_unpack_all(Eo *obj, Efl_Ui_Group_Item_Data *pd)
|
||||
{
|
||||
Eo *item;
|
||||
Eo *container = efl_ui_item_container_get(obj);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(container, EINA_FALSE);
|
||||
|
||||
EINA_LIST_FREE(pd->registered_items, item)
|
||||
{
|
||||
efl_pack_unpack(container, item);
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_ui_group_item_efl_pack_unpack(Eo *obj, Efl_Ui_Group_Item_Data *pd, Efl_Gfx_Entity *subobj)
|
||||
{
|
||||
Eo *container = efl_ui_item_container_get(obj);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(container, EINA_FALSE);
|
||||
|
||||
if (!efl_pack_unpack(container, subobj))
|
||||
return EINA_FALSE;
|
||||
|
||||
_unregister_item(obj, pd, subobj);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
#define HANDLE_REG_CALL(cond) \
|
||||
if (!(cond)) \
|
||||
{ \
|
||||
_unregister_item(obj, pd, subobj); \
|
||||
return EINA_FALSE; \
|
||||
} \
|
||||
return EINA_TRUE;
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_ui_group_item_efl_pack_pack(Eo *obj, Efl_Ui_Group_Item_Data *pd EINA_UNUSED, Efl_Gfx_Entity *subobj)
|
||||
{
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(subobj == obj, EINA_FALSE);
|
||||
return efl_pack_end(obj, subobj);
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_ui_group_item_efl_pack_linear_pack_end(Eo *obj, Efl_Ui_Group_Item_Data *pd, Efl_Gfx_Entity *subobj)
|
||||
{
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(subobj == obj, EINA_FALSE);
|
||||
Eo *container = efl_ui_item_container_get(obj);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(container, EINA_FALSE);
|
||||
int group_index = efl_pack_index_get(container, obj);
|
||||
|
||||
_register_item(obj, pd, subobj);
|
||||
HANDLE_REG_CALL(efl_pack_at(container, subobj, group_index + eina_list_count(pd->registered_items) + 1));
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_ui_group_item_efl_pack_linear_pack_begin(Eo *obj, Efl_Ui_Group_Item_Data *pd, Efl_Gfx_Entity *subobj)
|
||||
{
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(subobj == obj, EINA_FALSE);
|
||||
Eo *container = efl_ui_item_container_get(obj);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(container, EINA_FALSE);
|
||||
int group_index = efl_pack_index_get(container, obj);
|
||||
|
||||
_register_item(obj, pd, subobj);
|
||||
HANDLE_REG_CALL(efl_pack_at(container, subobj, group_index + 1));
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_ui_group_item_efl_pack_linear_pack_before(Eo *obj, Efl_Ui_Group_Item_Data *pd EINA_UNUSED, Efl_Gfx_Entity *subobj, const Efl_Gfx_Entity *existing)
|
||||
{
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(subobj == obj, EINA_FALSE);
|
||||
Eo *container = efl_ui_item_container_get(obj);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(container, EINA_FALSE);
|
||||
|
||||
//FIXME, maybe we should check if existing is really part of this group
|
||||
_register_item(obj, pd, subobj);
|
||||
HANDLE_REG_CALL(efl_pack_before(container, subobj, existing));
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_ui_group_item_efl_pack_linear_pack_after(Eo *obj, Efl_Ui_Group_Item_Data *pd EINA_UNUSED, Efl_Gfx_Entity *subobj, const Efl_Gfx_Entity *existing)
|
||||
{
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(subobj == obj, EINA_FALSE);
|
||||
Eo *container = efl_ui_item_container_get(obj);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(container, EINA_FALSE);
|
||||
|
||||
//FIXME, maybe we should check if existing is really part of this group
|
||||
_register_item(obj, pd, subobj);
|
||||
HANDLE_REG_CALL(efl_pack_after(container, subobj, existing));
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_ui_group_item_efl_pack_linear_pack_at(Eo *obj, Efl_Ui_Group_Item_Data *pd, Efl_Gfx_Entity *subobj, int index)
|
||||
{
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(subobj == obj, EINA_FALSE);
|
||||
Eo *container = efl_ui_item_container_get(obj);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(container, EINA_FALSE);
|
||||
int group_index = efl_pack_index_get(container, obj);
|
||||
|
||||
int count = eina_list_count(pd->registered_items);
|
||||
|
||||
if (index < -count)
|
||||
return efl_pack_begin(obj, subobj);
|
||||
|
||||
if (index >= count)
|
||||
return efl_pack_end(obj, subobj);
|
||||
|
||||
if (index < 0)
|
||||
index += count;
|
||||
|
||||
_register_item(obj, pd, subobj);
|
||||
HANDLE_REG_CALL(efl_pack_at(container, subobj, group_index + 1 + index));
|
||||
}
|
||||
|
||||
EOLIAN static Efl_Gfx_Entity*
|
||||
_efl_ui_group_item_efl_pack_linear_pack_unpack_at(Eo *obj, Efl_Ui_Group_Item_Data *pd, int index)
|
||||
{
|
||||
Eo *result, *container = efl_ui_item_container_get(obj);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(container, NULL);
|
||||
int group_index = efl_pack_index_get(container, obj);
|
||||
int count = eina_list_count(pd->registered_items);
|
||||
|
||||
if (index <= -count)
|
||||
index = 0;
|
||||
else if (index >= count)
|
||||
index = eina_list_count(pd->registered_items);
|
||||
else if (index < 0)
|
||||
index += count;
|
||||
|
||||
result = efl_pack_unpack_at(container, group_index + 1 + index);
|
||||
if (result)
|
||||
_unregister_item(obj, pd, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
EOLIAN static int
|
||||
_efl_ui_group_item_efl_pack_linear_pack_index_get(Eo *obj, Efl_Ui_Group_Item_Data *pd, const Efl_Gfx_Entity *subobj)
|
||||
{
|
||||
Eo *container = efl_ui_item_container_get(obj);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(container, -1);
|
||||
int first_index = efl_pack_index_get(container, obj) + 1;
|
||||
int subobj_index = efl_pack_index_get(container, subobj);
|
||||
|
||||
if (subobj_index == -1) return -1;
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(first_index <= subobj_index && subobj_index < (first_index + (int)eina_list_count(pd->registered_items)), -1);
|
||||
|
||||
return subobj_index - (first_index);
|
||||
}
|
||||
|
||||
EOLIAN static Efl_Gfx_Entity*
|
||||
_efl_ui_group_item_efl_pack_linear_pack_content_get(Eo *obj, Efl_Ui_Group_Item_Data *pd EINA_UNUSED, int index)
|
||||
{
|
||||
Eo *container = efl_ui_item_container_get(obj);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(container, NULL);
|
||||
int group_index = efl_pack_index_get(container, obj);
|
||||
|
||||
int count = eina_list_count(pd->registered_items);
|
||||
|
||||
if (index <= -count)
|
||||
return eina_list_data_get(pd->registered_items);
|
||||
|
||||
if (index >= count)
|
||||
return eina_list_last_data_get(pd->registered_items);
|
||||
|
||||
if (index < 0)
|
||||
index += count;
|
||||
|
||||
|
||||
return efl_pack_content_get(container, group_index + 1 + index);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Eina_Iterator iterator;
|
||||
unsigned int current;
|
||||
unsigned int max;
|
||||
Eo *container;
|
||||
} Efl_Ui_Group_Item_Iterator;
|
||||
|
||||
static Eina_Bool
|
||||
_next_item(Efl_Ui_Group_Item_Iterator *it, void **data)
|
||||
{
|
||||
if (it->current >= it->max) return EINA_FALSE;
|
||||
|
||||
*data = efl_pack_content_get(it->container, it->current);
|
||||
it->current++;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Iterator*
|
||||
_efl_ui_group_item_efl_container_content_iterate(Eo *obj, Efl_Ui_Group_Item_Data *pd EINA_UNUSED)
|
||||
{
|
||||
Eo *container = efl_ui_item_container_get(obj);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(container, NULL);
|
||||
Efl_Ui_Group_Item_Iterator *it;
|
||||
|
||||
it = calloc(1, sizeof (Efl_Ui_Group_Item_Iterator));
|
||||
if (!it) return NULL;
|
||||
|
||||
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
|
||||
|
||||
it->current = efl_pack_index_get(container, obj) + 1;
|
||||
it->max = it->current + eina_list_count(pd->registered_items);
|
||||
it->container = container;
|
||||
|
||||
it->iterator.version = EINA_ITERATOR_VERSION;
|
||||
it->iterator.next = FUNC_ITERATOR_NEXT(_next_item);
|
||||
it->iterator.get_container = NULL;
|
||||
it->iterator.free = FUNC_ITERATOR_FREE(free);
|
||||
|
||||
return &it->iterator;
|
||||
}
|
||||
|
||||
EOLIAN static int
|
||||
_efl_ui_group_item_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Group_Item_Data *pd)
|
||||
{
|
||||
return eina_list_count(pd->registered_items);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#include "efl_ui_group_item.eo.c"
|
|
@ -0,0 +1,22 @@
|
|||
class @beta Efl.Ui.Group_Item extends Efl.Ui.Default_Item implements Efl.Pack_Linear
|
||||
{
|
||||
[[Group item for grids and lists]]
|
||||
implements {
|
||||
Efl.Object.constructor;
|
||||
Efl.Object.invalidate;
|
||||
Efl.Pack.pack_clear;
|
||||
Efl.Pack.unpack_all;
|
||||
Efl.Pack.unpack;
|
||||
Efl.Pack.pack;
|
||||
Efl.Pack_Linear.pack_end;
|
||||
Efl.Pack_Linear.pack_begin;
|
||||
Efl.Pack_Linear.pack_before;
|
||||
Efl.Pack_Linear.pack_after;
|
||||
Efl.Pack_Linear.pack_at;
|
||||
Efl.Pack_Linear.pack_unpack_at;
|
||||
Efl.Pack_Linear.pack_index_get;
|
||||
Efl.Pack_Linear.pack_content_get;
|
||||
Efl.Container.content_iterate;
|
||||
Efl.Container.content_count;
|
||||
}
|
||||
}
|
|
@ -2,150 +2,24 @@
|
|||
# include "elementary_config.h"
|
||||
#endif
|
||||
|
||||
#define EFL_ACCESS_PROTECTED
|
||||
#define EFL_UI_WIDGET_PART_BG_PROTECTED
|
||||
|
||||
#include <Elementary.h>
|
||||
|
||||
#include "elm_priv.h"
|
||||
#include "efl_ui_item_private.h"
|
||||
//part
|
||||
#include "efl_ui_item_part_text.eo.h"
|
||||
#include "efl_ui_item_part_icon.eo.h"
|
||||
#include "efl_ui_item_part_extra.eo.h"
|
||||
#include "efl_ui_item_part_content.eo.h"
|
||||
#include "elm_part_helper.h"
|
||||
|
||||
#define MY_CLASS EFL_UI_ITEM_CLASS
|
||||
#define MY_CLASS_PFX efl_ui_item
|
||||
|
||||
#define MY_CLASS_NAME "Efl.Ui.Item"
|
||||
|
||||
/* Efl.Part */
|
||||
EOLIAN static void
|
||||
_efl_ui_item_part_text_efl_text_text_set(Eo *obj, void *pd EINA_UNUSED, const char *text)
|
||||
{
|
||||
Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
|
||||
efl_text_set(efl_part(efl_super(wd->obj, MY_CLASS), wd->part), text);
|
||||
|
||||
efl_canvas_group_change(wd->obj);
|
||||
}
|
||||
|
||||
EOLIAN static const char*
|
||||
_efl_ui_item_part_text_efl_text_text_get(const Eo *obj, void *pd EINA_UNUSED)
|
||||
{
|
||||
Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
|
||||
return efl_text_get(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_item_part_text_efl_text_markup_markup_set(Eo *obj, void *pd EINA_UNUSED, const char *markup)
|
||||
{
|
||||
Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
|
||||
efl_text_markup_set(efl_part(efl_super(wd->obj, MY_CLASS), wd->part), markup);
|
||||
|
||||
efl_canvas_group_change(obj);
|
||||
}
|
||||
|
||||
EOLIAN static const char*
|
||||
_efl_ui_item_part_text_efl_text_markup_markup_get(const Eo *obj, void *pd EINA_UNUSED)
|
||||
{
|
||||
Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
|
||||
return efl_text_markup_get(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
|
||||
}
|
||||
|
||||
EOLIAN static const char *
|
||||
_efl_ui_item_part_text_efl_ui_l10n_l10n_text_get(const Eo *obj, void *_pd EINA_UNUSED, const char **domain)
|
||||
{
|
||||
Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
|
||||
return elm_widget_part_translatable_text_get(pd->obj, pd->part, domain);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_item_part_text_efl_ui_l10n_l10n_text_set(Eo *obj, void *_pd EINA_UNUSED, const char *text, const char *domain)
|
||||
{
|
||||
Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
|
||||
elm_widget_part_translatable_text_set(pd->obj, pd->part, text, domain);
|
||||
}
|
||||
#include "efl_ui_item_part_text.eo.c"
|
||||
|
||||
/* Efl.Ui.List_Default_Item_Part_Icon */
|
||||
|
||||
Eina_Bool
|
||||
_efl_ui_item_part_icon_efl_content_content_set(Eo *obj, void *pd EINA_UNUSED, Efl_Gfx_Entity *content)
|
||||
{
|
||||
Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
|
||||
return efl_content_set(efl_part(efl_super(wd->obj, MY_CLASS), wd->part), content);
|
||||
}
|
||||
|
||||
Efl_Gfx_Entity *
|
||||
_efl_ui_item_part_icon_efl_content_content_get(const Eo *obj, void *pd EINA_UNUSED)
|
||||
{
|
||||
Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
|
||||
return efl_content_get(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
|
||||
}
|
||||
|
||||
Efl_Gfx_Entity *
|
||||
_efl_ui_item_part_icon_efl_content_content_unset(Eo *obj, void *pd EINA_UNUSED)
|
||||
{
|
||||
Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
|
||||
return efl_content_unset(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
|
||||
}
|
||||
#include "efl_ui_item_part_icon.eo.c"
|
||||
|
||||
Eina_Bool
|
||||
_efl_ui_item_part_extra_efl_content_content_set(Eo *obj, void *pd EINA_UNUSED, Efl_Gfx_Entity *content)
|
||||
{
|
||||
Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
|
||||
return efl_content_set(efl_part(efl_super(wd->obj, MY_CLASS), wd->part), content);
|
||||
}
|
||||
|
||||
Efl_Gfx_Entity *
|
||||
_efl_ui_item_part_extra_efl_content_content_get(const Eo *obj, void *pd EINA_UNUSED)
|
||||
{
|
||||
Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
|
||||
return efl_content_get(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
|
||||
}
|
||||
|
||||
Efl_Gfx_Entity *
|
||||
_efl_ui_item_part_extra_efl_content_content_unset(Eo *obj, void *pd EINA_UNUSED)
|
||||
{
|
||||
Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
|
||||
return efl_content_unset(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
|
||||
}
|
||||
#include "efl_ui_item_part_extra.eo.c"
|
||||
|
||||
Eina_Bool
|
||||
_efl_ui_item_part_content_efl_content_content_set(Eo *obj, void *pd EINA_UNUSED, Efl_Gfx_Entity *content)
|
||||
{
|
||||
Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
|
||||
return efl_content_set(efl_part(efl_super(wd->obj, MY_CLASS), wd->part), content);
|
||||
}
|
||||
|
||||
Efl_Gfx_Entity *
|
||||
_efl_ui_item_part_content_efl_content_content_get(const Eo *obj, void *pd EINA_UNUSED)
|
||||
{
|
||||
Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
|
||||
return efl_content_get(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
|
||||
}
|
||||
|
||||
Efl_Gfx_Entity *
|
||||
_efl_ui_item_part_content_efl_content_content_unset(Eo *obj, void *pd EINA_UNUSED)
|
||||
{
|
||||
Elm_Part_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
|
||||
return efl_content_unset(efl_part(efl_super(wd->obj, MY_CLASS), wd->part));
|
||||
}
|
||||
#include "efl_ui_item_part_content.eo.c"
|
||||
/* Efl.Part */
|
||||
|
||||
static void
|
||||
_item_select(Eo *obj, Efl_Ui_Item_Data *pd)
|
||||
{
|
||||
Efl_Ui_Select_Mode m;
|
||||
|
||||
if (pd->parent)
|
||||
if (pd->container)
|
||||
{
|
||||
m = efl_ui_select_mode_get(pd->parent);
|
||||
m = efl_ui_select_mode_get(pd->container);
|
||||
if (m == EFL_UI_SELECT_MODE_NONE || (pd->selected && m != EFL_UI_SELECT_MODE_SINGLE_ALWAYS))
|
||||
return;
|
||||
}
|
||||
|
@ -245,7 +119,7 @@ _efl_ui_item_efl_object_destructor(Eo *obj, Efl_Ui_Item_Data *pd EINA_UNUSED)
|
|||
EOLIAN static int
|
||||
_efl_ui_item_index_get(const Eo *obj, Efl_Ui_Item_Data *pd)
|
||||
{
|
||||
return efl_pack_index_get(pd->parent, obj);
|
||||
return efl_pack_index_get(pd->container, obj);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
|
@ -268,15 +142,48 @@ _efl_ui_item_efl_ui_selectable_selected_get(const Eo *obj EINA_UNUSED, Efl_Ui_It
|
|||
EOLIAN static void
|
||||
_efl_ui_item_container_set(Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd, Efl_Ui_Widget *container)
|
||||
{
|
||||
pd->parent = container;
|
||||
pd->container = container;
|
||||
if (!pd->container)
|
||||
{
|
||||
pd->parent = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
EOLIAN static Efl_Ui_Widget*
|
||||
_efl_ui_item_container_get(const Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd)
|
||||
{
|
||||
return pd->container;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_item_item_parent_set(Eo *obj, Efl_Ui_Item_Data *pd, Efl_Ui_Item *parent)
|
||||
{
|
||||
if (pd->parent)
|
||||
{
|
||||
ERR("Parent is already set on object %p", obj);
|
||||
return;
|
||||
}
|
||||
if (efl_invalidated_get(obj) || efl_invalidating_get(obj))
|
||||
{
|
||||
ERR("Parent cannot be set during invalidate");
|
||||
return;
|
||||
}
|
||||
if (pd->container)
|
||||
{
|
||||
ERR("Parent must be set before adding the object to the container");
|
||||
return;
|
||||
}
|
||||
pd->parent = parent;
|
||||
}
|
||||
|
||||
|
||||
EOLIAN static Efl_Ui_Item*
|
||||
_efl_ui_item_item_parent_get(const Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd)
|
||||
{
|
||||
return pd->parent;
|
||||
}
|
||||
|
||||
|
||||
#include "efl_ui_item.eo.c"
|
||||
#include "efl_ui_selectable.eo.c"
|
||||
#include "efl_ui_multi_selectable.eo.c"
|
||||
|
|
|
@ -40,6 +40,15 @@ abstract @beta Efl.Ui.Item extends Efl.Ui.Layout_Base implements Efl.Ui.Selectab
|
|||
container : Efl.Ui.Widget; [[The container this item is in.]]
|
||||
}
|
||||
}
|
||||
@property item_parent {
|
||||
[[The parent of the item.
|
||||
|
||||
This property expresses a tree structure of items. If the parent is NULL the item is added in the root level of the content. The item parent can only be set once, when the object is invalidated, the item parent is set to NULL and still cannot be reset.
|
||||
]]
|
||||
values {
|
||||
parent : Efl.Ui.Item;
|
||||
}
|
||||
}
|
||||
}
|
||||
implements {
|
||||
Efl.Object.constructor;
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
class @beta Efl.Ui.Item_Part_Content extends Efl.Ui.Layout_Part implements Efl.Content
|
||||
{
|
||||
[[Item internal content part class]]
|
||||
data: null;
|
||||
implements {
|
||||
Efl.Content.content { get; set; }
|
||||
Efl.Content.content_unset;
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
class @beta Efl.Ui.Item_Part_Extra extends Efl.Ui.Layout_Part implements Efl.Content
|
||||
{
|
||||
[[Item internal content of extra part class]]
|
||||
data: null;
|
||||
implements {
|
||||
Efl.Content.content { get; set; }
|
||||
Efl.Content.content_unset;
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
class @beta Efl.Ui.Item_Part_Icon extends Efl.Ui.Layout_Part implements Efl.Content
|
||||
{
|
||||
[[Item internal content of icon part class]]
|
||||
data: null;
|
||||
implements {
|
||||
Efl.Content.content { get; set; }
|
||||
Efl.Content.content_unset;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
class @beta Efl.Ui.Item_Part_Text extends Efl.Ui.Layout_Part implements
|
||||
Efl.Text, Efl.Text_Markup, Efl.Ui.L10n
|
||||
{
|
||||
[[Item internal text part class]]
|
||||
data: null;
|
||||
implements {
|
||||
Efl.Text.text { set; get; }
|
||||
Efl.Text_Markup.markup { get; set; }
|
||||
Efl.Ui.L10n.l10n_text { get; set; }
|
||||
}
|
||||
}
|
|
@ -6,7 +6,8 @@
|
|||
typedef struct _Efl_Ui_Item_Data
|
||||
{
|
||||
// Eo Objects
|
||||
Eo *parent; /* Parent Widget */
|
||||
Eo *container; /* Parent Widget */
|
||||
Efl_Ui_Item *parent;
|
||||
|
||||
// Boolean Data
|
||||
Eina_Bool selected : 1; /* State for item selected */
|
||||
|
|
|
@ -16,47 +16,15 @@
|
|||
#define MY_CLASS_NAME "Efl.Ui.List_Default_Item"
|
||||
|
||||
EOLIAN static Efl_Object *
|
||||
_efl_ui_list_default_item_efl_object_finalize(Eo *obj, void *pd EINA_UNUSED)
|
||||
_efl_ui_list_default_item_efl_object_constructor(Eo *obj, void *pd EINA_UNUSED)
|
||||
{
|
||||
Eo *eo;
|
||||
eo = efl_finalize(efl_super(obj, MY_CLASS));
|
||||
ELM_WIDGET_DATA_GET_OR_RETURN(eo, wd, eo);
|
||||
Eina_Error theme_apply_ret = efl_ui_layout_theme_set(obj, "list_item", NULL, NULL);
|
||||
|
||||
if (theme_apply_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC)
|
||||
CRI("Default Item(%p) failed to set theme [efl/list_item]!", eo);
|
||||
eo = efl_constructor(efl_super(obj, MY_CLASS));
|
||||
|
||||
if (!elm_widget_theme_klass_get(obj))
|
||||
elm_widget_theme_klass_set(obj, "list_item");
|
||||
|
||||
return eo;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_list_default_item_efl_object_destructor(Eo *obj, void *pd EINA_UNUSED)
|
||||
{
|
||||
efl_destructor(efl_super(obj, MY_CLASS));
|
||||
}
|
||||
|
||||
ELM_PART_TEXT_DEFAULT_GET(efl_ui_list_default_item, "efl.text")
|
||||
ELM_PART_TEXT_DEFAULT_IMPLEMENT(efl_ui_list_default_item, void)
|
||||
ELM_PART_MARKUP_DEFAULT_IMPLEMENT(efl_ui_list_default_item, void)
|
||||
ELM_PART_CONTENT_DEFAULT_GET(efl_ui_list_default_item, "efl.icon")
|
||||
ELM_PART_CONTENT_DEFAULT_IMPLEMENT(efl_ui_list_default_item, void)
|
||||
|
||||
EOLIAN static Efl_Object *
|
||||
_efl_ui_list_default_item_efl_part_part_get(const Eo *obj, void *wd EINA_UNUSED, const char *part)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
|
||||
if (eina_streq(part, "text"))
|
||||
return ELM_PART_IMPLEMENT(EFL_UI_ITEM_PART_TEXT_CLASS, obj, "efl.text");
|
||||
else if (eina_streq(part, "icon"))
|
||||
return ELM_PART_IMPLEMENT(EFL_UI_ITEM_PART_ICON_CLASS, obj, "efl.icon");
|
||||
else if (eina_streq(part, "extra"))
|
||||
return ELM_PART_IMPLEMENT(EFL_UI_ITEM_PART_EXTRA_CLASS, obj, "efl.extra");
|
||||
|
||||
return efl_part_get(efl_super(obj, MY_CLASS), part);
|
||||
}
|
||||
|
||||
/* Internal EO APIs and hidden overrides */
|
||||
#define EFL_UI_LIST_DEFAULT_ITEM_EXTRA_OPS \
|
||||
ELM_PART_TEXT_DEFAULT_OPS(efl_ui_list_default_item), \
|
||||
ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_list_default_item)
|
||||
|
||||
#include "efl_ui_list_default_item.eo.c"
|
||||
|
|
|
@ -1,30 +1,9 @@
|
|||
|
||||
class @beta Efl.Ui.List_Default_Item extends Efl.Ui.Item implements
|
||||
Efl.Text,
|
||||
Efl.Text_Markup,
|
||||
Efl.Content
|
||||
class @beta Efl.Ui.List_Default_Item extends Efl.Ui.Default_Item
|
||||
{
|
||||
[[List Default Item class.
|
||||
This class need to be sub object of list widget.
|
||||
text and contents can be appliable by efl_text,
|
||||
efl_content or efl_part APIs.]]
|
||||
[[List Default Item class.]]
|
||||
data: null;
|
||||
parts {
|
||||
text: Efl.Ui.Item_Part_Text; [[The text part for list default item.]]
|
||||
icon: Efl.Ui.Item_Part_Icon; [[The icon content part for list default item.
|
||||
icon part is the left-side content of list item.]]
|
||||
extra: Efl.Ui.Item_Part_Extra; [[The extra content part for list default item.
|
||||
extra part is the right-side content of list item.]]
|
||||
}
|
||||
implements {
|
||||
//Efl.Object
|
||||
Efl.Object.finalize;
|
||||
Efl.Object.destructor;
|
||||
Efl.Text.text { get; set; }
|
||||
Efl.Text_Markup.markup { get; set; }
|
||||
Efl.Ui.L10n.l10n_text { get; set; }
|
||||
Efl.Content.content { get; set; }
|
||||
Efl.Content.content_unset;
|
||||
Efl.Part.part_get;
|
||||
Efl.Object.constructor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ _efl_ui_list_placeholder_item_efl_part_part_get(const Eo *obj, void *wd EINA_UNU
|
|||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
|
||||
if (eina_streq(part, "content"))
|
||||
return ELM_PART_IMPLEMENT(EFL_UI_ITEM_PART_CONTENT_CLASS, obj, "efl.content");
|
||||
return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_CONTENT_CLASS, obj, "efl.content");
|
||||
|
||||
return efl_part_get(efl_super(obj, MY_CLASS), part);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ class @beta Efl.Ui.List_Placeholder_Item extends Efl.Ui.Item implements Efl.Cont
|
|||
any kind of container.]]
|
||||
data: null;
|
||||
parts {
|
||||
content: Efl.Ui.Item_Part_Content; [[the content part for list placeholder item.
|
||||
content: Efl.Ui.Layout_Part_Content; [[the content part for list placeholder item.
|
||||
the content part is empty slot for user customizing.
|
||||
fill the place with container widget such as layout, box, table.]]
|
||||
}
|
||||
|
|
|
@ -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[buffer_id].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
|
||||
|
|
|
@ -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]]
|
||||
}
|
||||
|
|
|
@ -12,37 +12,432 @@
|
|||
#define MY_DATA_GET(obj, pd) \
|
||||
Efl_Ui_Position_Manager_Grid_Data *pd = efl_data_scope_get(obj, MY_CLASS);
|
||||
|
||||
typedef struct {
|
||||
unsigned int start_id, end_id;
|
||||
} Vis_Segment;
|
||||
|
||||
typedef struct {
|
||||
Api_Callback min_size, object;
|
||||
unsigned int size;
|
||||
unsigned int groups;
|
||||
Eina_Rect viewport;
|
||||
Eina_Vector2 scroll_position;
|
||||
Efl_Ui_Layout_Orientation dir;
|
||||
struct {
|
||||
unsigned int start_id, end_id;
|
||||
} prev_run;
|
||||
Vis_Segment prev_run;
|
||||
Eina_Size2D max_min_size;
|
||||
Eina_Size2D last_viewport_size;
|
||||
Eina_Size2D prev_min_size;
|
||||
struct {
|
||||
int columns;
|
||||
int rows;
|
||||
} current_display_table;
|
||||
|
||||
Eina_Inarray *group_cache;
|
||||
Eina_Bool group_cache_dirty;
|
||||
int *size_cache;
|
||||
Eina_Bool size_cache_dirty;
|
||||
Eo *last_group;
|
||||
Eina_Future *rebuild_absolut_size;
|
||||
} Efl_Ui_Position_Manager_Grid_Data;
|
||||
|
||||
typedef struct {
|
||||
Eina_Bool real_group;
|
||||
Eina_Size2D group_header_size;
|
||||
int items;
|
||||
} Group_Cache_Line;
|
||||
|
||||
static void
|
||||
_group_cache_require(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd)
|
||||
{
|
||||
unsigned int i;
|
||||
const int len = 100;
|
||||
Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[len];
|
||||
Group_Cache_Line line = { 0 };
|
||||
|
||||
if (!pd->group_cache_dirty)
|
||||
return;
|
||||
|
||||
pd->group_cache_dirty = EINA_FALSE;
|
||||
if (pd->group_cache)
|
||||
eina_inarray_free(pd->group_cache);
|
||||
pd->group_cache = eina_inarray_new(sizeof(Group_Cache_Line), 10);
|
||||
|
||||
for (i = 0; i < pd->size; ++i)
|
||||
{
|
||||
int buffer_id = i % len;
|
||||
|
||||
if (buffer_id == 0)
|
||||
{
|
||||
EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, i, len, NULL, size_buffer) > 0);
|
||||
}
|
||||
|
||||
if (size_buffer[buffer_id].group == EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_GROUP)
|
||||
{
|
||||
eina_inarray_push(pd->group_cache, &line);
|
||||
line.real_group = EINA_TRUE;
|
||||
line.group_header_size = size_buffer[buffer_id].size;
|
||||
line.items = 1;
|
||||
}
|
||||
else if (size_buffer[buffer_id].group == EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_PART_OF_GROUP ||
|
||||
(!line.real_group && size_buffer[buffer_id].group == EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_NO_GROUP))
|
||||
{
|
||||
line.items ++;
|
||||
}
|
||||
else if (size_buffer[buffer_id].group == EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_NO_GROUP && line.real_group)
|
||||
{
|
||||
eina_inarray_push(pd->group_cache, &line);
|
||||
line.real_group = EINA_FALSE;
|
||||
line.group_header_size = EINA_SIZE2D(0, 0);
|
||||
line.items = 0;
|
||||
}
|
||||
}
|
||||
eina_inarray_push(pd->group_cache, &line);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_group_cache_invalidate(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd)
|
||||
{
|
||||
pd->group_cache_dirty = EINA_TRUE;
|
||||
pd->size_cache_dirty = EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_size_cache_require(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd)
|
||||
{
|
||||
if (!pd->size_cache_dirty) return;
|
||||
|
||||
_group_cache_require(obj, pd);
|
||||
|
||||
pd->size_cache_dirty = EINA_FALSE;
|
||||
if (pd->size_cache)
|
||||
free(pd->size_cache);
|
||||
pd->size_cache = calloc(sizeof(int), eina_inarray_count(pd->group_cache));
|
||||
|
||||
for (unsigned int i = 0; i < eina_inarray_count(pd->group_cache); ++i)
|
||||
{
|
||||
Group_Cache_Line *line = eina_inarray_nth(pd->group_cache, i);
|
||||
int header_out = 0;
|
||||
if (line->real_group)
|
||||
header_out = 1;
|
||||
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
pd->size_cache[i] = line->group_header_size.h +
|
||||
(ceil(
|
||||
(double)(line->items - header_out)/ /* the number of real items in the group (- the group item) */
|
||||
(int)(pd->viewport.w/pd->max_min_size.w))) /* devided by the number of items per row */
|
||||
*pd->max_min_size.h;
|
||||
else
|
||||
pd->size_cache[i] = (ceil((double)(line->items - header_out)/
|
||||
(int)((pd->viewport.h-line->group_header_size.h)/pd->max_min_size.h)))*pd->max_min_size.w;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_size_cache_invalidate(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd)
|
||||
{
|
||||
pd->size_cache_dirty = EINA_TRUE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int resulting_id;
|
||||
int consumed_space;
|
||||
} Search_Result;
|
||||
|
||||
static inline Search_Result
|
||||
_search_id(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, int relevant_space_size)
|
||||
{
|
||||
int consumed_space = 0;
|
||||
int consumed_groups = -1;
|
||||
int consumed_ids = 0;
|
||||
int sub_ids = 0;
|
||||
Search_Result res;
|
||||
|
||||
//first we search how many blocks we can skip
|
||||
for (unsigned int i = 0; i < eina_inarray_count(pd->group_cache); ++i)
|
||||
{
|
||||
Group_Cache_Line *line = eina_inarray_nth(pd->group_cache, i);
|
||||
if (consumed_space + pd->size_cache[i] > relevant_space_size)
|
||||
break;
|
||||
consumed_space += pd->size_cache[i];
|
||||
consumed_groups = i;
|
||||
consumed_ids += line->items;
|
||||
}
|
||||
Group_Cache_Line *line = NULL;
|
||||
if (consumed_groups > -1 && consumed_groups + 1 < (int)eina_inarray_count(pd->group_cache))
|
||||
line = eina_inarray_nth(pd->group_cache, consumed_groups + 1);
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
{
|
||||
//now we have relevant_space_size - consumed_space left maybe we are searching the group item
|
||||
|
||||
if (line && line->real_group)
|
||||
{
|
||||
if (consumed_space + line->group_header_size.h > relevant_space_size)
|
||||
{
|
||||
res.resulting_id = consumed_ids;
|
||||
res.consumed_space = consumed_space;
|
||||
return res;
|
||||
}
|
||||
else
|
||||
{
|
||||
consumed_space += line->group_header_size.h;
|
||||
consumed_ids += 1;
|
||||
}
|
||||
}
|
||||
//now we need to locate at which id we are starting
|
||||
int space_top = relevant_space_size - consumed_space;
|
||||
consumed_space += floor(space_top/pd->max_min_size.h)*pd->max_min_size.h;
|
||||
sub_ids = floor(space_top/pd->max_min_size.h)*(pd->viewport.w/pd->max_min_size.w);
|
||||
}
|
||||
else
|
||||
{
|
||||
int header_height = 0;
|
||||
if (line && line->real_group)
|
||||
{
|
||||
header_height = line->group_header_size.h;
|
||||
}
|
||||
//now we need to locate at which id we are starting
|
||||
const int space_left = relevant_space_size - consumed_space;
|
||||
consumed_space += floor(space_left/pd->max_min_size.w)*pd->max_min_size.w;
|
||||
sub_ids = floor(space_left/pd->max_min_size.w)*((pd->viewport.h-header_height)/pd->max_min_size.h);
|
||||
if (line && line->real_group &&
|
||||
sub_ids > 0) /* if we are in the first row, we need the group item to be visible, otherwise, we need to add that to the consumed ids */
|
||||
{
|
||||
sub_ids += 1;
|
||||
}
|
||||
}
|
||||
res.resulting_id = consumed_ids + sub_ids;
|
||||
res.consumed_space = consumed_space;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
_search_start_end(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, int relevant_viewport, int relevant_space_size, unsigned int step, Vis_Segment *cur, int *consumed_space)
|
||||
{
|
||||
Search_Result start = _search_id(obj, pd, MAX(relevant_space_size, 0));
|
||||
Search_Result end = _search_id(obj, pd, MAX(relevant_space_size, 0)+relevant_viewport+step*2);
|
||||
cur->start_id = MIN(MAX(start.resulting_id, 0), (int)pd->size);
|
||||
cur->end_id = MAX(MIN(end.resulting_id, (int)pd->size), 0);
|
||||
|
||||
*consumed_space = start.consumed_space;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int relevant_space_size;
|
||||
int consumed_space;
|
||||
Vis_Segment new;
|
||||
Eo *floating_group;
|
||||
Eina_Size2D floating_size;
|
||||
Eo *placed_item;
|
||||
} Item_Position_Context;
|
||||
|
||||
|
||||
static inline void
|
||||
_place_grid_item(Eina_Rect *geom, Efl_Ui_Position_Manager_Grid_Data *pd, int x, int y)
|
||||
{
|
||||
geom->x += x*pd->max_min_size.w;
|
||||
geom->y += y*pd->max_min_size.h;
|
||||
geom->size = pd->max_min_size;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_position_items_vertical(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, Item_Position_Context *ctx)
|
||||
{
|
||||
Eina_Position2D start = pd->viewport.pos;
|
||||
unsigned int i;
|
||||
const int len = 100;
|
||||
int columns, last_block_start = ctx->new.start_id;
|
||||
Efl_Ui_Position_Manager_Batch_Entity_Access obj_buffer[len];
|
||||
|
||||
if (!pd->viewport.w || !pd->viewport.h) return;
|
||||
|
||||
start.y -= (ctx->relevant_space_size - ctx->consumed_space);
|
||||
columns = pd->viewport.w/pd->max_min_size.w;
|
||||
|
||||
for (i = ctx->new.start_id; i < ctx->new.end_id; ++i)
|
||||
{
|
||||
int buffer_id = (i-ctx->new.start_id) % len;
|
||||
if (buffer_id == 0)
|
||||
{
|
||||
int tmp_group;
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->object, i, len, &tmp_group, obj_buffer) > 0);
|
||||
if (tmp_group != -1 && i == ctx->new.start_id)
|
||||
{
|
||||
Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[1];
|
||||
Efl_Ui_Position_Manager_Batch_Entity_Access obj_buffer[1];
|
||||
EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, tmp_group, 1, NULL, size_buffer) != 0);
|
||||
EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->object, tmp_group, 1, NULL, obj_buffer) != 0);
|
||||
ctx->floating_group = obj_buffer[0].entity;
|
||||
ctx->floating_size.h = size_buffer[0].size.h;
|
||||
ctx->floating_size.w = pd->viewport.w;
|
||||
}
|
||||
}
|
||||
Eina_Rect geom;
|
||||
geom.pos = start;
|
||||
int x = (i - last_block_start)%columns;
|
||||
int y = (i - last_block_start)/columns;
|
||||
|
||||
if (obj_buffer[buffer_id].entity == pd->last_group)
|
||||
pd->last_group = NULL;
|
||||
|
||||
if (obj_buffer[buffer_id].group == EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_GROUP)
|
||||
{
|
||||
Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[1];
|
||||
EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, i, 1, NULL, size_buffer) == 1);
|
||||
|
||||
if (x != 0)
|
||||
y += 1;
|
||||
|
||||
last_block_start = i + 1;
|
||||
start.y += size_buffer[0].size.h + y*pd->max_min_size.h;
|
||||
|
||||
geom.size = pd->viewport.size;
|
||||
geom.h = size_buffer[0].size.h;
|
||||
geom.y += y*pd->max_min_size.h;
|
||||
if (!ctx->placed_item)
|
||||
ctx->placed_item = obj_buffer[buffer_id].entity;
|
||||
}
|
||||
else
|
||||
{
|
||||
_place_grid_item(&geom, pd, x, y);
|
||||
}
|
||||
|
||||
efl_gfx_entity_geometry_set(obj_buffer[buffer_id].entity, geom);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_position_items_horizontal(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, Item_Position_Context *ctx)
|
||||
{
|
||||
Eina_Position2D start = pd->viewport.pos;
|
||||
unsigned int i;
|
||||
const int len = 100;
|
||||
int columns, last_block_start = ctx->new.start_id;
|
||||
Efl_Ui_Position_Manager_Batch_Entity_Access obj_buffer[len];
|
||||
|
||||
if (!pd->viewport.w || !pd->viewport.h) return;
|
||||
|
||||
start.x -= (ctx->relevant_space_size - ctx->consumed_space);
|
||||
columns = (pd->viewport.h)/pd->max_min_size.h;
|
||||
|
||||
for (i = ctx->new.start_id; i < ctx->new.end_id; ++i)
|
||||
{
|
||||
int buffer_id = (i-ctx->new.start_id) % len;
|
||||
if (buffer_id == 0)
|
||||
{
|
||||
int tmp_group;
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->object, i, len, &tmp_group, obj_buffer) > 0);
|
||||
if (tmp_group != -1 && i == ctx->new.start_id && pd->dir != EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
{
|
||||
Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[1];
|
||||
Efl_Ui_Position_Manager_Batch_Entity_Access obj_buffer[1];
|
||||
EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, tmp_group, 1, NULL, size_buffer) != 0);
|
||||
EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->object, tmp_group, 1, NULL, obj_buffer) != 0);
|
||||
start.y += size_buffer[0].size.h;
|
||||
columns = (pd->viewport.h - size_buffer[0].size.h)/pd->max_min_size.h;
|
||||
ctx->floating_group = obj_buffer[0].entity;
|
||||
ctx->floating_size.h = size_buffer[0].size.h;
|
||||
ctx->floating_size.w = pd->viewport.w;
|
||||
}
|
||||
}
|
||||
Eina_Rect geom;
|
||||
geom.pos = start;
|
||||
|
||||
int x = (i - last_block_start)/columns;
|
||||
int y = (i - last_block_start)%columns;
|
||||
|
||||
if (obj_buffer[buffer_id].entity == pd->last_group)
|
||||
pd->last_group = NULL;
|
||||
|
||||
if (obj_buffer[buffer_id].group == EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_GROUP)
|
||||
{
|
||||
Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[1];
|
||||
EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, i, 1, NULL, size_buffer) == 1);
|
||||
|
||||
last_block_start = i + 1;
|
||||
start.y = pd->viewport.y + size_buffer[0].size.h;
|
||||
start.x += x*pd->max_min_size.w;
|
||||
|
||||
geom.size.h = size_buffer[0].size.h;
|
||||
geom.size.w = pd->viewport.w;
|
||||
geom.x += x*pd->max_min_size.w;
|
||||
geom.y = pd->viewport.y;
|
||||
|
||||
columns = (pd->viewport.h - size_buffer[0].size.h)/pd->max_min_size.h;
|
||||
if (!ctx->placed_item)
|
||||
ctx->placed_item = obj_buffer[buffer_id].entity;
|
||||
}
|
||||
else
|
||||
{
|
||||
_place_grid_item(&geom, pd, x, y);
|
||||
}
|
||||
efl_gfx_entity_geometry_set(obj_buffer[buffer_id].entity, geom);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_position_group_items(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, Item_Position_Context *ctx)
|
||||
{
|
||||
//floating group is not yet positioned, in case it is there, we need to position it there
|
||||
Eina_Rect geom;
|
||||
|
||||
if (!ctx->floating_group && pd->last_group)
|
||||
{
|
||||
efl_gfx_entity_visible_set(pd->last_group, EINA_FALSE);
|
||||
pd->last_group = NULL;
|
||||
}
|
||||
|
||||
if (ctx->floating_group)
|
||||
{
|
||||
geom.pos = pd->viewport.pos;
|
||||
geom.size = ctx->floating_size;
|
||||
|
||||
if (ctx->placed_item)
|
||||
{
|
||||
Eina_Rect placed = efl_gfx_entity_geometry_get(ctx->placed_item);
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
{
|
||||
geom.y = MIN(geom.y, placed.y-geom.h);
|
||||
}
|
||||
else
|
||||
{
|
||||
geom.x = MIN(geom.x, placed.x-geom.w);
|
||||
}
|
||||
}
|
||||
|
||||
if (pd->last_group != ctx->floating_group)
|
||||
{
|
||||
efl_gfx_entity_visible_set(pd->last_group, EINA_FALSE);
|
||||
pd->last_group = ctx->floating_group;
|
||||
}
|
||||
|
||||
efl_gfx_entity_visible_set(ctx->floating_group, EINA_TRUE);
|
||||
efl_gfx_stack_raise_to_top(ctx->floating_group);
|
||||
efl_gfx_entity_geometry_set(ctx->floating_group, geom);
|
||||
}
|
||||
else if (ctx->placed_item)
|
||||
{
|
||||
Eina_Rect placed = efl_gfx_entity_geometry_get(ctx->placed_item);
|
||||
|
||||
placed.x = MAX(placed.x, pd->viewport.x);
|
||||
placed.y = MAX(placed.y, pd->viewport.y);
|
||||
efl_gfx_entity_geometry_set(ctx->placed_item, placed);
|
||||
efl_gfx_stack_raise_to_top(ctx->placed_item);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_reposition_content(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd)
|
||||
{
|
||||
Eina_Size2D space_size;
|
||||
int relevant_space_size, relevant_viewport;
|
||||
unsigned int start_id, end_id, step;
|
||||
const int len = 100;
|
||||
Efl_Gfx_Entity *obj_buffer[len];
|
||||
int relevant_space_size, relevant_viewport, consumed_space;
|
||||
Vis_Segment cur;
|
||||
unsigned int step;
|
||||
Efl_Ui_Position_Manager_Range_Update ev;
|
||||
Item_Position_Context ctx;
|
||||
|
||||
if (!pd->size) return;
|
||||
if (pd->max_min_size.w <= 0 || pd->max_min_size.h <= 0) return;
|
||||
if (pd->current_display_table.columns <= 0 || pd->current_display_table.rows <= 0) return;
|
||||
if (!eina_inarray_count(pd->group_cache)) return;
|
||||
|
||||
//space size contains the amount of space that is outside the viewport (either to the top or to the left)
|
||||
space_size.w = (MAX(pd->last_viewport_size.w - pd->viewport.w, 0))*pd->scroll_position.x;
|
||||
|
@ -60,62 +455,45 @@ _reposition_content(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd)
|
|||
relevant_viewport = pd->viewport.w;
|
||||
step = pd->max_min_size.w;
|
||||
}
|
||||
start_id = MIN((MAX(relevant_space_size,0) / step)*pd->current_display_table.columns, pd->size);
|
||||
end_id = MIN((((MAX(relevant_space_size,0) + relevant_viewport + step) / step)*pd->current_display_table.columns)+1, pd->size);
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN(start_id <= end_id);
|
||||
EINA_SAFETY_ON_FALSE_RETURN(start_id <= pd->size);
|
||||
if (!_search_start_end(obj, pd, relevant_viewport, relevant_space_size, step, &cur, &consumed_space))
|
||||
return;
|
||||
|
||||
//to performance optimize the whole widget, we are setting the objects that are outside the viewport to visibility false
|
||||
//The code below ensures that things outside the viewport are always hidden, and things inside the viewport are visible
|
||||
if (end_id < pd->prev_run.start_id || start_id > pd->prev_run.end_id)
|
||||
if (cur.end_id < pd->prev_run.start_id || cur.start_id > pd->prev_run.end_id)
|
||||
{
|
||||
//it is important to first make the segment visible here, and then hide the rest
|
||||
//otherwise we get a state where item_container has 0 subchildren, which triggers a lot of focus logic.
|
||||
vis_change_segment(&pd->object, start_id, end_id, EINA_TRUE);
|
||||
vis_change_segment(&pd->object, cur.start_id, cur.end_id, EINA_TRUE);
|
||||
vis_change_segment(&pd->object, pd->prev_run.start_id, pd->prev_run.end_id, EINA_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
vis_change_segment(&pd->object, pd->prev_run.start_id, start_id, (pd->prev_run.start_id > start_id));
|
||||
vis_change_segment(&pd->object, pd->prev_run.end_id, end_id, (pd->prev_run.end_id < end_id));
|
||||
vis_change_segment(&pd->object, pd->prev_run.start_id, cur.start_id, (pd->prev_run.start_id > cur.start_id));
|
||||
vis_change_segment(&pd->object, pd->prev_run.end_id, cur.end_id, (pd->prev_run.end_id < cur.end_id));
|
||||
}
|
||||
|
||||
for (unsigned int i = start_id; i < end_id; ++i)
|
||||
ctx.new = cur;
|
||||
ctx.consumed_space = consumed_space;
|
||||
ctx.relevant_space_size = relevant_space_size;
|
||||
ctx.floating_group = NULL;
|
||||
ctx.placed_item = NULL;
|
||||
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
{
|
||||
Eina_Rect geom;
|
||||
Efl_Gfx_Entity *ent;
|
||||
int buffer_id = (i-start_id) % len;
|
||||
geom.size = pd->max_min_size;
|
||||
geom.pos = pd->viewport.pos;
|
||||
|
||||
if (buffer_id == 0)
|
||||
{
|
||||
EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->object, i, len, obj_buffer) > 0);
|
||||
}
|
||||
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
{
|
||||
geom.x += pd->max_min_size.w*(i%pd->current_display_table.columns);
|
||||
geom.y += pd->max_min_size.h*(i/pd->current_display_table.columns);
|
||||
geom.y -= (relevant_space_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
geom.x += pd->max_min_size.w*(i/pd->current_display_table.columns);
|
||||
geom.y += pd->max_min_size.h*(i%pd->current_display_table.columns);
|
||||
geom.x -= (relevant_space_size);
|
||||
}
|
||||
|
||||
ent = ((Efl_Gfx_Entity**)obj_buffer)[buffer_id];
|
||||
|
||||
//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);
|
||||
_position_items_vertical(obj, pd, &ctx);
|
||||
_position_group_items(obj, pd, &ctx);
|
||||
}
|
||||
if (pd->prev_run.start_id != start_id || pd->prev_run.end_id != end_id)
|
||||
else
|
||||
{
|
||||
ev.start_id = pd->prev_run.start_id = start_id;
|
||||
ev.end_id = pd->prev_run.end_id = end_id;
|
||||
_position_items_horizontal(obj, pd, &ctx);
|
||||
_position_group_items(obj, pd, &ctx);
|
||||
}
|
||||
|
||||
if (pd->prev_run.start_id != cur.start_id || pd->prev_run.end_id != cur.end_id)
|
||||
{
|
||||
ev.start_id = pd->prev_run.start_id = cur.start_id;
|
||||
ev.end_id = pd->prev_run.end_id = cur.end_id;
|
||||
efl_event_callback_call(obj, EFL_UI_POSITION_MANAGER_ENTITY_EVENT_VISIBLE_RANGE_CHANGED, &ev);
|
||||
}
|
||||
}
|
||||
|
@ -123,44 +501,27 @@ _reposition_content(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd)
|
|||
static inline void
|
||||
_flush_abs_size(Eo *obj, Efl_Ui_Position_Manager_Grid_Data *pd)
|
||||
{
|
||||
int minor, major;
|
||||
Eina_Size2D vp_size;
|
||||
int sum_of_cache = 0;
|
||||
|
||||
if (!pd->size) return;
|
||||
if (pd->max_min_size.w <= 0 || pd->max_min_size.h <= 0) return;
|
||||
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
_size_cache_require(obj, pd);
|
||||
for (unsigned int i = 0; i < eina_inarray_count(pd->group_cache); ++i)
|
||||
{
|
||||
major = pd->viewport.w/pd->max_min_size.w;
|
||||
pd->current_display_table.columns = major;
|
||||
}
|
||||
else
|
||||
{
|
||||
major = pd->viewport.h/pd->max_min_size.h;
|
||||
pd->current_display_table.columns = major;
|
||||
sum_of_cache += pd->size_cache[i];
|
||||
}
|
||||
|
||||
if (major <= 0) return;
|
||||
minor = ceil((double)pd->size/(double)major);
|
||||
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
pd->current_display_table.rows = minor;
|
||||
else
|
||||
pd->current_display_table.rows = minor;
|
||||
|
||||
/*
|
||||
* calculate how much size we need with major in the given orientation.
|
||||
* The
|
||||
*/
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
{
|
||||
vp_size.w = pd->viewport.w;
|
||||
vp_size.h = minor*pd->max_min_size.h;
|
||||
vp_size.h = sum_of_cache;
|
||||
}
|
||||
else
|
||||
{
|
||||
vp_size.h = pd->viewport.h;
|
||||
vp_size.w = minor*pd->max_min_size.w;
|
||||
vp_size.w = sum_of_cache;
|
||||
}
|
||||
if (vp_size.h != pd->last_viewport_size.h || vp_size.w != pd->last_viewport_size.w)
|
||||
{
|
||||
|
@ -208,6 +569,7 @@ _efl_ui_position_manager_grid_efl_ui_position_manager_entity_data_access_set(Eo
|
|||
EOLIAN static void
|
||||
_efl_ui_position_manager_grid_efl_ui_position_manager_entity_viewport_set(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, Eina_Rect viewport)
|
||||
{
|
||||
_size_cache_invalidate(obj, pd);
|
||||
pd->viewport = viewport;
|
||||
_flush_abs_size(obj, pd);
|
||||
_reposition_content(obj, pd);
|
||||
|
@ -221,53 +583,74 @@ _efl_ui_position_manager_grid_efl_ui_position_manager_entity_scroll_position_set
|
|||
_reposition_content(obj, pd);
|
||||
}
|
||||
|
||||
static Eina_Value
|
||||
_rebuild_job_cb(void *data, Eina_Value v EINA_UNUSED, const Eina_Future *f EINA_UNUSED)
|
||||
{
|
||||
MY_DATA_GET(data, pd);
|
||||
|
||||
if (!efl_alive_get(data)) return EINA_VALUE_EMPTY;
|
||||
|
||||
_flush_abs_size(data, pd);
|
||||
_reposition_content(data, pd);
|
||||
pd->rebuild_absolut_size = NULL;
|
||||
|
||||
return EINA_VALUE_EMPTY;
|
||||
}
|
||||
|
||||
static void
|
||||
_schedule_recalc_abs_size(Eo *obj, Efl_Ui_Position_Manager_Grid_Data *pd)
|
||||
{
|
||||
if (pd->rebuild_absolut_size) return;
|
||||
|
||||
pd->rebuild_absolut_size = efl_loop_job(efl_app_main_get());
|
||||
eina_future_then(pd->rebuild_absolut_size, _rebuild_job_cb, obj);
|
||||
}
|
||||
|
||||
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]);
|
||||
_group_cache_invalidate(obj, pd);
|
||||
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
|
||||
_schedule_recalc_abs_size(obj, pd);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_ui_position_manager_grid_efl_ui_position_manager_entity_item_removed(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, int removed_index EINA_UNUSED, Efl_Gfx_Entity *subobj EINA_UNUSED)
|
||||
{
|
||||
//we ignore here that we might loose the item giving the current max min size
|
||||
EINA_SAFETY_ON_FALSE_RETURN(pd->size > 0);
|
||||
pd->size --;
|
||||
_group_cache_invalidate(obj, pd);
|
||||
pd->prev_run.start_id = MIN(pd->prev_run.start_id, pd->size);
|
||||
pd->prev_run.end_id = MIN(pd->prev_run.end_id, pd->size);
|
||||
//we ignore here that we might loose the item giving the current max min size
|
||||
_flush_abs_size(obj, pd);
|
||||
_reposition_content(obj, pd); //FIXME we might can skip that
|
||||
_schedule_recalc_abs_size(obj, pd);
|
||||
efl_gfx_entity_visible_set(subobj, EINA_TRUE);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
_size_cache_invalidate(obj, pd);
|
||||
_flush_min_size(obj, pd);
|
||||
_flush_abs_size(obj, pd);
|
||||
_reposition_content(obj, pd); //FIXME we could check if this is needed or not
|
||||
_schedule_recalc_abs_size(obj, pd);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
|
@ -292,38 +675,69 @@ _efl_ui_position_manager_grid_efl_ui_position_manager_entity_position_single_ite
|
|||
Eina_Rect geom;
|
||||
Eina_Size2D space_size;
|
||||
unsigned int relevant_space_size;
|
||||
unsigned int group_consumed_size = 0;
|
||||
unsigned int group_consumed_ids = 0;
|
||||
Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[1];
|
||||
|
||||
if (!pd->size) return EINA_RECT(0, 0, 0, 0);
|
||||
if (pd->max_min_size.w <= 0 || pd->max_min_size.h <= 0) return EINA_RECT(0, 0, 0, 0);
|
||||
if (pd->current_display_table.columns <= 0 || pd->current_display_table.rows <= 0) return EINA_RECT(0, 0, 0, 0);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(_fill_buffer(&pd->min_size, idx, 1, NULL, size_buffer) == 1, EINA_RECT_EMPTY());
|
||||
|
||||
_size_cache_require(obj, pd);
|
||||
_flush_abs_size(obj, pd);
|
||||
|
||||
//space size contains the amount of space that is outside the viewport (either to the top or to the left)
|
||||
space_size.w = (MAX(pd->last_viewport_size.w - pd->viewport.w, 0))*pd->scroll_position.x;
|
||||
space_size.h = (MAX(pd->last_viewport_size.h - pd->viewport.h, 0))*pd->scroll_position.y;
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(space_size.w >= 0 && space_size.h >= 0, EINA_RECT(0, 0, 0, 0));
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
{
|
||||
relevant_space_size = space_size.h;
|
||||
}
|
||||
relevant_space_size = space_size.h;
|
||||
else
|
||||
{
|
||||
relevant_space_size = space_size.w;
|
||||
}
|
||||
relevant_space_size = space_size.w;
|
||||
|
||||
geom.size = pd->max_min_size;
|
||||
geom.pos = pd->viewport.pos;
|
||||
|
||||
for (unsigned int i = 0; i < eina_inarray_count(pd->group_cache); ++i)
|
||||
{
|
||||
Group_Cache_Line *line = eina_inarray_nth(pd->group_cache, i);
|
||||
if ((int)group_consumed_ids + line->items > idx)
|
||||
break;
|
||||
|
||||
group_consumed_size += pd->size_cache[i];
|
||||
group_consumed_ids += line->items;
|
||||
if (line->real_group && idx == (int)group_consumed_ids + 1)
|
||||
{
|
||||
geom.y = (relevant_space_size - group_consumed_size);
|
||||
geom.size = size_buffer[0].size;
|
||||
|
||||
return geom;
|
||||
}
|
||||
else if (line->real_group)
|
||||
group_consumed_size += line->group_header_size.h;
|
||||
}
|
||||
|
||||
if (idx > 0)
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(group_consumed_ids < (unsigned int)idx, EINA_RECT(0, 0, 0, 0));
|
||||
else if (idx == 0)
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(group_consumed_ids == 0, EINA_RECT(0, 0, 0, 0));
|
||||
|
||||
int columns = pd->viewport.w/pd->max_min_size.w;
|
||||
int sub_pos_id = idx - group_consumed_ids;
|
||||
int x = (sub_pos_id)%columns;
|
||||
int y = (sub_pos_id)/columns;
|
||||
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
{
|
||||
geom.x += pd->max_min_size.w*(idx%pd->current_display_table.columns);
|
||||
geom.y += pd->max_min_size.h*(idx/pd->current_display_table.columns);
|
||||
geom.y -= (relevant_space_size);
|
||||
geom.y -= relevant_space_size;
|
||||
geom.x += pd->max_min_size.w*x;
|
||||
geom.y += group_consumed_size;
|
||||
geom.y += pd->max_min_size.h*y;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
geom.x += pd->max_min_size.w*(idx/pd->current_display_table.columns);
|
||||
/*geom.x += pd->max_min_size.w*(idx/pd->current_display_table.columns);
|
||||
geom.y += pd->max_min_size.h*(idx%pd->current_display_table.columns);
|
||||
geom.x -= (relevant_space_size);
|
||||
geom.x -= (relevant_space_size);*/
|
||||
}
|
||||
|
||||
return geom;
|
||||
|
@ -344,10 +758,10 @@ _efl_ui_position_manager_grid_efl_ui_position_manager_entity_relative_item(Eo *o
|
|||
new_id -= 1;
|
||||
break;
|
||||
case EFL_UI_FOCUS_DIRECTION_UP:
|
||||
new_id -= pd->current_display_table.columns;
|
||||
//FIXME
|
||||
break;
|
||||
case EFL_UI_FOCUS_DIRECTION_DOWN:
|
||||
new_id += pd->current_display_table.columns;
|
||||
//FIXME
|
||||
break;
|
||||
default:
|
||||
new_id = -1;
|
||||
|
|
|
@ -13,6 +13,11 @@
|
|||
#define MY_DATA_GET(obj, pd) \
|
||||
Efl_Ui_Position_Manager_List_Data *pd = efl_data_scope_get(obj, MY_CLASS);
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned int start_id, end_id;
|
||||
} Vis_Segment;
|
||||
|
||||
typedef struct {
|
||||
Api_Callback min_size, object;
|
||||
unsigned int size;
|
||||
|
@ -24,9 +29,8 @@ typedef struct {
|
|||
int *size_cache;
|
||||
int average_item_size;
|
||||
int maximum_min_size;
|
||||
struct {
|
||||
unsigned int start_id, end_id;
|
||||
} prev_run;
|
||||
Vis_Segment prev_run;
|
||||
Efl_Gfx_Entity *last_group;
|
||||
} Efl_Ui_Position_Manager_List_Data;
|
||||
|
||||
/*
|
||||
|
@ -42,7 +46,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 +71,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)
|
||||
{
|
||||
|
@ -132,16 +136,174 @@ recalc_absolut_size(Eo *obj, Efl_Ui_Position_Manager_List_Data *pd)
|
|||
efl_event_callback_call(obj, EFL_UI_POSITION_MANAGER_ENTITY_EVENT_CONTENT_MIN_SIZE_CHANGED, &min_size);
|
||||
}
|
||||
|
||||
static inline Vis_Segment
|
||||
_search_visual_segment(Eo *obj, Efl_Ui_Position_Manager_List_Data *pd, int relevant_space_size, int relevant_viewport)
|
||||
{
|
||||
Vis_Segment cur;
|
||||
//based on the average item size, we jump somewhere into the sum cache.
|
||||
//After beeing in there, we are walking back, until we have less space then viewport size
|
||||
cur.start_id = MIN((unsigned int)(relevant_space_size / pd->average_item_size), pd->size);
|
||||
for (; cache_access(obj, pd, cur.start_id) >= relevant_space_size && cur.start_id > 0; cur.start_id --) { }
|
||||
|
||||
//starting on the start id, we are walking down until the sum of elements is bigger than the lower part of the viewport.
|
||||
cur.end_id = cur.start_id;
|
||||
for (; cur.end_id <= pd->size && cache_access(obj, pd, cur.end_id) <= relevant_space_size + relevant_viewport ; cur.end_id ++) { }
|
||||
cur.end_id = MAX(cur.end_id, cur.start_id + 1);
|
||||
cur.end_id = MIN(cur.end_id, pd->size);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("space_size %d : starting point : %d : cached_space_starting_point %d end point : %d cache_space_end_point %d\n", space_size.h, cur.start_id, pd->size_cache[cur.start_id], cur.end_id, pd->size_cache[cur.end_id]);
|
||||
#endif
|
||||
if (relevant_space_size > 0)
|
||||
EINA_SAFETY_ON_FALSE_GOTO(cache_access(obj, pd, cur.start_id) <= relevant_space_size, err);
|
||||
if (cur.end_id != pd->size)
|
||||
EINA_SAFETY_ON_FALSE_GOTO(cache_access(obj, pd, cur.end_id) >= relevant_space_size + relevant_viewport, err);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(cur.start_id <= cur.end_id, err);
|
||||
|
||||
return cur;
|
||||
|
||||
err:
|
||||
cur.start_id = cur.end_id = 0;
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_visual_segment_swap(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd, Vis_Segment new, Vis_Segment old)
|
||||
{
|
||||
if (new.end_id <= old.start_id || new.start_id >= old.end_id)
|
||||
{
|
||||
//it is important to first make the segment visible here, and then hide the rest
|
||||
//otherwise we get a state where item_container has 0 subchildren, which triggers a lot of focus logic.
|
||||
vis_change_segment(&pd->object, new.start_id, new.end_id, EINA_TRUE);
|
||||
vis_change_segment(&pd->object, old.start_id, old.end_id, EINA_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
vis_change_segment(&pd->object, old.start_id, new.start_id, (old.start_id > new.start_id));
|
||||
vis_change_segment(&pd->object, old.end_id, new.end_id, (old.end_id < new.end_id));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_position_items(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd, Vis_Segment new, int relevant_space_size)
|
||||
{
|
||||
int group_id = -1;
|
||||
Efl_Gfx_Entity *first_group = NULL, *first_fully_visual_group = NULL;
|
||||
Eina_Size2D first_group_size;
|
||||
Eina_Rect geom;
|
||||
const int len = 100;
|
||||
Efl_Ui_Position_Manager_Batch_Size_Access size_buffer[len];
|
||||
Efl_Ui_Position_Manager_Batch_Entity_Access obj_buffer[len];
|
||||
unsigned int i;
|
||||
|
||||
//placement of the plain items
|
||||
geom = pd->viewport;
|
||||
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
geom.y -= (relevant_space_size - cache_access(obj, pd, new.start_id));
|
||||
else
|
||||
geom.x -= (relevant_space_size - cache_access(obj, pd, new.start_id));
|
||||
|
||||
for (i = new.start_id; i < new.end_id; ++i)
|
||||
{
|
||||
Eina_Size2D size;
|
||||
Efl_Gfx_Entity *ent = NULL;
|
||||
int buffer_id = (i-new.start_id) % len;
|
||||
|
||||
if (buffer_id == 0)
|
||||
{
|
||||
int tmp_group;
|
||||
int res1, res2;
|
||||
|
||||
res1 = _fill_buffer(&pd->object, i, len, &tmp_group, 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);
|
||||
|
||||
if (i == new.start_id)
|
||||
{
|
||||
if (tmp_group > 0)
|
||||
group_id = tmp_group;
|
||||
else if (obj_buffer[0].group == EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_GROUP)
|
||||
group_id = i;
|
||||
}
|
||||
}
|
||||
|
||||
size = size_buffer[buffer_id].size;
|
||||
ent = obj_buffer[buffer_id].entity;
|
||||
|
||||
if (ent == pd->last_group)
|
||||
{
|
||||
pd->last_group = NULL;
|
||||
}
|
||||
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
geom.h = size.h;
|
||||
else
|
||||
geom.w = size.w;
|
||||
|
||||
if (!first_fully_visual_group && obj_buffer[buffer_id].group == EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_GROUP &&
|
||||
eina_spans_intersect(geom.x, geom.w, pd->viewport.x, pd->viewport.w) &&
|
||||
eina_spans_intersect(geom.y, geom.h, pd->viewport.y, pd->viewport.h))
|
||||
{
|
||||
first_fully_visual_group = obj_buffer[buffer_id].entity;
|
||||
}
|
||||
|
||||
if (ent)
|
||||
efl_gfx_entity_geometry_set(ent, geom);
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
geom.y += size.h;
|
||||
else
|
||||
geom.x += size.w;
|
||||
}
|
||||
//Now place group items
|
||||
|
||||
if (group_id > 0)
|
||||
{
|
||||
EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->object, group_id, 1, NULL, obj_buffer) == 1);
|
||||
EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(&pd->min_size, group_id, 1, NULL, size_buffer) == 1);
|
||||
first_group = obj_buffer[0].entity;
|
||||
first_group_size = size_buffer[0].size;
|
||||
}
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
first_group_size.w = pd->viewport.w;
|
||||
else
|
||||
first_group_size.h = pd->viewport.h;
|
||||
|
||||
//if there is a new group item, display the new one, and hide the old one
|
||||
if (first_group != pd->last_group)
|
||||
{
|
||||
efl_gfx_entity_visible_set(pd->last_group, EINA_FALSE);
|
||||
efl_gfx_stack_raise_to_top(first_group);
|
||||
pd->last_group = first_group;
|
||||
}
|
||||
//we have to set the visibility again here, as changing the visual segments might overwrite our visibility state
|
||||
efl_gfx_entity_visible_set(first_group, EINA_TRUE);
|
||||
|
||||
//in case there is another group item coming in, the new group item (which is placed as normal item) moves the group item to the top
|
||||
Eina_Position2D first_group_pos = EINA_POSITION2D(pd->viewport.x, pd->viewport.y);
|
||||
if (first_fully_visual_group && first_fully_visual_group != first_group)
|
||||
{
|
||||
Eina_Position2D first_visual_group;
|
||||
first_visual_group = efl_gfx_entity_position_get(first_fully_visual_group);
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
first_group_pos.y = MIN(first_group_pos.y, first_visual_group.y - first_group_size.h);
|
||||
else
|
||||
first_group_pos.x = MIN(first_group_pos.x, first_visual_group.x - first_group_size.w);
|
||||
}
|
||||
|
||||
efl_gfx_entity_position_set(first_group, first_group_pos);
|
||||
efl_gfx_entity_size_set(first_group, first_group_size);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
position_content(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd)
|
||||
{
|
||||
Eina_Rect geom;
|
||||
Eina_Size2D space_size;
|
||||
unsigned int start_id = 0, end_id = 0, i;
|
||||
Vis_Segment cur;
|
||||
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_Range_Update ev;
|
||||
|
||||
if (!pd->size) return;
|
||||
|
@ -162,82 +324,17 @@ position_content(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd)
|
|||
relevant_viewport = pd->viewport.w;
|
||||
}
|
||||
|
||||
//based on the average item size, we jump somewhere into the sum cache.
|
||||
//After beeing in there, we are walking back, until we have less space then viewport size
|
||||
start_id = MIN((unsigned int)(relevant_space_size / pd->average_item_size), pd->size);
|
||||
for (; cache_access(obj, pd, start_id) >= relevant_space_size && start_id > 0; start_id --) { }
|
||||
|
||||
//starting on the start id, we are walking down until the sum of elements is bigger than the lower part of the viewport.
|
||||
end_id = start_id;
|
||||
for (; end_id <= pd->size && cache_access(obj, pd, end_id) <= relevant_space_size + relevant_viewport ; end_id ++) { }
|
||||
end_id = MAX(end_id, start_id + 1);
|
||||
end_id = MIN(end_id, pd->size);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("space_size %d : starting point : %d : cached_space_starting_point %d end point : %d cache_space_end_point %d\n", space_size.h, start_id, pd->size_cache[start_id], end_id, pd->size_cache[end_id]);
|
||||
#endif
|
||||
if (relevant_space_size > 0)
|
||||
EINA_SAFETY_ON_FALSE_RETURN(cache_access(obj, pd, start_id) <= relevant_space_size);
|
||||
if (end_id != pd->size)
|
||||
EINA_SAFETY_ON_FALSE_RETURN(cache_access(obj, pd, end_id) >= relevant_space_size + relevant_viewport);
|
||||
EINA_SAFETY_ON_FALSE_RETURN(start_id <= end_id);
|
||||
|
||||
cur = _search_visual_segment(obj, pd, relevant_space_size, relevant_viewport);
|
||||
//to performance optimize the whole widget, we are setting the objects that are outside the viewport to visibility false
|
||||
//The code below ensures that things outside the viewport are always hidden, and things inside the viewport are visible
|
||||
if (end_id <= pd->prev_run.start_id || start_id >= pd->prev_run.end_id)
|
||||
_visual_segment_swap(obj, pd, cur, pd->prev_run);
|
||||
|
||||
_position_items(obj, pd, cur, relevant_space_size);
|
||||
|
||||
if (pd->prev_run.start_id != cur.start_id || pd->prev_run.end_id != cur.end_id)
|
||||
{
|
||||
//it is important to first make the segment visible here, and then hide the rest
|
||||
//otherwise we get a state where item_container has 0 subchildren, which triggers a lot of focus logic.
|
||||
vis_change_segment(&pd->object, start_id, end_id, EINA_TRUE);
|
||||
vis_change_segment(&pd->object, pd->prev_run.start_id, pd->prev_run.end_id, EINA_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
vis_change_segment(&pd->object, pd->prev_run.start_id, start_id, (pd->prev_run.start_id > start_id));
|
||||
vis_change_segment(&pd->object, pd->prev_run.end_id, end_id, (pd->prev_run.end_id < end_id));
|
||||
}
|
||||
|
||||
geom = pd->viewport;
|
||||
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
geom.y -= (relevant_space_size - cache_access(obj, pd, start_id));
|
||||
else
|
||||
geom.x -= (relevant_space_size - cache_access(obj, pd, start_id));
|
||||
|
||||
for (i = start_id; i < end_id; ++i)
|
||||
{
|
||||
Eina_Size2D size;
|
||||
Efl_Gfx_Entity *ent = NULL;
|
||||
int buffer_id = (i-start_id) % len;
|
||||
|
||||
if (buffer_id == 0)
|
||||
{
|
||||
int res1, res2;
|
||||
|
||||
res1 = _fill_buffer(&pd->object, i, len, obj_buffer);
|
||||
res2 = _fill_buffer(&pd->min_size, i, len, 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];
|
||||
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
geom.h = size.h;
|
||||
else
|
||||
geom.w = size.w;
|
||||
if (ent)
|
||||
efl_gfx_entity_geometry_set(ent, geom);
|
||||
if (pd->dir == EFL_UI_LAYOUT_ORIENTATION_VERTICAL)
|
||||
geom.y += size.h;
|
||||
else
|
||||
geom.x += size.w;
|
||||
}
|
||||
if (pd->prev_run.start_id != start_id || pd->prev_run.end_id != end_id)
|
||||
{
|
||||
ev.start_id = pd->prev_run.start_id = start_id;
|
||||
ev.end_id = pd->prev_run.end_id = end_id;
|
||||
ev.start_id = pd->prev_run.start_id = cur.start_id;
|
||||
ev.end_id = pd->prev_run.end_id = cur.end_id;
|
||||
efl_event_callback_call(obj, EFL_UI_POSITION_MANAGER_ENTITY_EVENT_VISIBLE_RANGE_CHANGED, &ev);
|
||||
}
|
||||
|
||||
|
@ -333,7 +430,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 +450,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)
|
||||
{
|
||||
|
|
|
@ -116,11 +116,9 @@ pub_eo_files = [
|
|||
'efl_ui_list_view.eo',
|
||||
'efl_ui_list_view_model.eo',
|
||||
'efl_ui_list_view_pan.eo',
|
||||
'efl_ui_item_part_text.eo',
|
||||
'efl_ui_item_part_icon.eo',
|
||||
'efl_ui_item_part_extra.eo',
|
||||
'efl_ui_item_part_content.eo',
|
||||
'efl_ui_item.eo',
|
||||
'efl_ui_default_item.eo',
|
||||
'efl_ui_group_item.eo',
|
||||
'efl_ui_list_default_item.eo',
|
||||
'efl_ui_list_placeholder_item.eo',
|
||||
'efl_ui_list.eo',
|
||||
|
@ -895,6 +893,8 @@ elementary_src = [
|
|||
'efl_ui_focus_util.c',
|
||||
'elm_widget_item_static_focus.c',
|
||||
'efl_ui_item.c',
|
||||
'efl_ui_default_item.c',
|
||||
'efl_ui_group_item.c',
|
||||
'efl_ui_list_default_item.c',
|
||||
'efl_ui_list_placeholder_item.c',
|
||||
'efl_ui_list.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)
|
||||
|
|
|
@ -6,6 +6,21 @@
|
|||
#include "efl_ui_spec_suite.h"
|
||||
#include "suite_helpers.h"
|
||||
|
||||
|
||||
Efl_Ui_Widget*
|
||||
efl_test_parent_get(Eo *obj)
|
||||
{
|
||||
if (efl_isa(widget, EFL_UI_GROUP_ITEM_CLASS))
|
||||
{
|
||||
return efl_ui_item_parent_get(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
return efl_ui_widget_parent_get(obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
efl_test_container_content_equal(Efl_Ui_Widget **wid, unsigned int len)
|
||||
{
|
||||
|
|
|
@ -137,7 +137,7 @@ EFL_START_TEST(unpack1)
|
|||
_setup_std_pack(wid);
|
||||
|
||||
ck_assert_int_eq(efl_pack_unpack(widget, wid[2]), EINA_TRUE);
|
||||
ck_assert_ptr_ne(efl_ui_widget_parent_get(wid[2]), widget);
|
||||
ck_assert_ptr_ne(efl_test_parent_get(wid[2]), widget);
|
||||
ck_assert_int_eq(efl_ref_count(wid[2]), 1);
|
||||
efl_test_container_content_equal(wid, 2);
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ EFL_START_TEST(pack1)
|
|||
for (i = 0; i < sizeof(wid)/sizeof(Efl_Ui_Widget*); ++i)
|
||||
{
|
||||
ck_assert_int_eq(efl_ref_count(wid[i]), 1);
|
||||
ck_assert_ptr_eq(efl_ui_widget_parent_get(wid[i]), widget);
|
||||
ck_assert_ptr_eq(efl_test_parent_get(wid[i]), widget);
|
||||
}
|
||||
|
||||
efl_test_container_content_equal(wid, 3);
|
||||
|
@ -292,6 +292,7 @@ EFL_END_TEST
|
|||
void
|
||||
efl_pack_behavior_test(TCase *tc)
|
||||
{
|
||||
tcase_add_test(tc, pack2);
|
||||
tcase_add_test(tc, base2);
|
||||
tcase_add_test(tc, pack_clear1);
|
||||
tcase_add_test(tc, pack_clear2);
|
||||
|
@ -301,7 +302,6 @@ efl_pack_behavior_test(TCase *tc)
|
|||
tcase_add_test(tc, unpack2);
|
||||
tcase_add_test(tc, unpack3);
|
||||
tcase_add_test(tc, pack1);
|
||||
tcase_add_test(tc, pack2);
|
||||
tcase_add_test(tc, pack3);
|
||||
tcase_add_test(tc, evt_content_added);
|
||||
tcase_add_test(tc, evt_content_removed);
|
||||
|
|
|
@ -9,10 +9,11 @@
|
|||
|
||||
/* spec-meta-start
|
||||
{"test-interface":"Efl.Pack_Linear",
|
||||
"test-widgets": ["Efl.Ui.Box", "Efl.Ui.Grid", "Efl.Ui.Spotlight.Container", "Efl.Ui.List"],
|
||||
"test-widgets": ["Efl.Ui.Box", "Efl.Ui.Grid", "Efl.Ui.Spotlight.Container", "Efl.Ui.List", "Efl.Ui.Group_Item" ],
|
||||
"custom-mapping" : {
|
||||
"Efl.Ui.Grid" : "EFL_UI_GRID_DEFAULT_ITEM_CLASS",
|
||||
"Efl.Ui.List" : "EFL_UI_LIST_DEFAULT_ITEM_CLASS"
|
||||
"Efl.Ui.List" : "EFL_UI_LIST_DEFAULT_ITEM_CLASS",
|
||||
"Efl.Ui.Group_Item" : "EFL_UI_LIST_DEFAULT_ITEM_CLASS"
|
||||
}
|
||||
}
|
||||
spec-meta-end */
|
||||
|
@ -46,7 +47,7 @@ EFL_START_TEST(pack_begin1)
|
|||
for (int i = 2; i >= 0; i--)
|
||||
{
|
||||
efl_pack_begin(widget, wid[i]);
|
||||
ck_assert_ptr_eq(efl_ui_widget_parent_get(wid[i]), widget);
|
||||
ck_assert_ptr_eq(efl_test_parent_get(wid[i]), widget);
|
||||
}
|
||||
_ordering_equals(wid, 3);
|
||||
efl_pack_begin(widget, inv);
|
||||
|
@ -65,7 +66,7 @@ EFL_START_TEST(pack_begin2)
|
|||
for (int i = 2; i >= 0; i--)
|
||||
{
|
||||
efl_pack_begin(widget, wid[i]);
|
||||
ck_assert_ptr_eq(efl_ui_widget_parent_get(wid[i]), widget);
|
||||
ck_assert_ptr_eq(efl_test_parent_get(wid[i]), widget);
|
||||
}
|
||||
|
||||
EXPECT_ERROR_START;
|
||||
|
@ -85,7 +86,7 @@ EFL_START_TEST(pack_end1)
|
|||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
efl_pack_end(widget, wid[i]);
|
||||
ck_assert_ptr_eq(efl_ui_widget_parent_get(wid[i]), widget);
|
||||
ck_assert_ptr_eq(efl_test_parent_get(wid[i]), widget);
|
||||
}
|
||||
|
||||
_ordering_equals(wid, 3);
|
||||
|
@ -105,7 +106,7 @@ EFL_START_TEST(pack_end2)
|
|||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
efl_pack_end(widget, wid[i]);
|
||||
ck_assert_ptr_eq(efl_ui_widget_parent_get(wid[i]), widget);
|
||||
ck_assert_ptr_eq(efl_test_parent_get(wid[i]), widget);
|
||||
}
|
||||
|
||||
EXPECT_ERROR_START;
|
||||
|
@ -126,13 +127,13 @@ EFL_START_TEST(pack_before1)
|
|||
efl_pack_end(widget, wid[i]);
|
||||
|
||||
ck_assert_int_eq(efl_pack_before(widget, inv, wid[0]), EINA_TRUE);
|
||||
ck_assert_ptr_eq(efl_ui_widget_parent_get(inv), widget);
|
||||
ck_assert_ptr_eq(efl_test_parent_get(inv), widget);
|
||||
Efl_Ui_Widget *wid2[] = {inv, wid[0], wid[1], wid[2]};
|
||||
_ordering_equals(wid2, 4);
|
||||
efl_pack_unpack(widget, inv);
|
||||
|
||||
ck_assert_int_eq(efl_pack_before(widget, inv, wid[2]), EINA_TRUE);
|
||||
ck_assert_ptr_eq(efl_ui_widget_parent_get(inv), widget);
|
||||
ck_assert_ptr_eq(efl_test_parent_get(inv), widget);
|
||||
Efl_Ui_Widget *wid3[] = {wid[0], wid[1], inv, wid[2]};
|
||||
_ordering_equals(wid3, 4);
|
||||
}
|
||||
|
@ -149,7 +150,7 @@ EFL_START_TEST(pack_before2)
|
|||
efl_pack_end(widget, wid[i]);
|
||||
|
||||
ck_assert_int_eq(efl_pack_before(widget, inv, wid[0]), EINA_TRUE);
|
||||
ck_assert_ptr_eq(efl_ui_widget_parent_get(inv), widget);
|
||||
ck_assert_ptr_eq(efl_test_parent_get(inv), widget);
|
||||
Efl_Ui_Widget *wid2[] = {inv, wid[0], wid[1], wid[2]};
|
||||
_ordering_equals(wid2, 4);
|
||||
|
||||
|
@ -170,13 +171,13 @@ EFL_START_TEST(pack_after1)
|
|||
efl_pack_end(widget, wid[i]);
|
||||
|
||||
ck_assert_int_eq(efl_pack_after(widget, inv, wid[0]), EINA_TRUE);
|
||||
ck_assert_ptr_eq(efl_ui_widget_parent_get(inv), widget);
|
||||
ck_assert_ptr_eq(efl_test_parent_get(inv), widget);
|
||||
Efl_Ui_Widget *wid2[] = {wid[0], inv, wid[1], wid[2]};
|
||||
_ordering_equals(wid2, 4);
|
||||
efl_pack_unpack(widget, inv);
|
||||
|
||||
ck_assert_int_eq(efl_pack_after(widget, inv, wid[2]), EINA_TRUE);
|
||||
ck_assert_ptr_eq(efl_ui_widget_parent_get(inv), widget);
|
||||
ck_assert_ptr_eq(efl_test_parent_get(inv), widget);
|
||||
Efl_Ui_Widget *wid3[] = {wid[0], wid[1], wid[2], inv};
|
||||
_ordering_equals(wid3, 4);
|
||||
}
|
||||
|
@ -193,7 +194,7 @@ EFL_START_TEST(pack_after2)
|
|||
efl_pack_end(widget, wid[i]);
|
||||
|
||||
ck_assert_int_eq(efl_pack_after(widget, inv, wid[0]), EINA_TRUE);
|
||||
ck_assert_ptr_eq(efl_ui_widget_parent_get(inv), widget);
|
||||
ck_assert_ptr_eq(efl_test_parent_get(inv), widget);
|
||||
Efl_Ui_Widget *wid2[] = {wid[0], inv, wid[1], wid[2]};
|
||||
_ordering_equals(wid2, 4);
|
||||
|
||||
|
@ -216,7 +217,7 @@ EFL_START_TEST(pack_at1)
|
|||
efl_pack_end(widget, wid[i]);
|
||||
|
||||
efl_pack_at(widget, inv, x);
|
||||
ck_assert_ptr_eq(efl_ui_widget_parent_get(inv), widget);
|
||||
ck_assert_ptr_eq(efl_test_parent_get(inv), widget);
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
|
@ -247,7 +248,7 @@ EFL_START_TEST(pack_at2)
|
|||
efl_pack_end(widget, wid[i]);
|
||||
|
||||
ck_assert_int_eq(efl_pack_at(widget, inv, x), EINA_TRUE);
|
||||
ck_assert_ptr_eq(efl_ui_widget_parent_get(inv), widget);
|
||||
ck_assert_ptr_eq(efl_test_parent_get(inv), widget);
|
||||
|
||||
EXPECT_ERROR_START;
|
||||
ck_assert_int_eq(efl_pack_at(widget, inv, x - 1), EINA_FALSE);
|
||||
|
@ -281,9 +282,9 @@ EFL_START_TEST(pack_at3)
|
|||
efl_pack_end(widget, wid[i]);
|
||||
|
||||
ck_assert_int_eq(efl_pack_at(widget, inv,-100000), EINA_TRUE);
|
||||
ck_assert_ptr_eq(efl_ui_widget_parent_get(inv), widget);
|
||||
ck_assert_ptr_eq(efl_test_parent_get(inv), widget);
|
||||
ck_assert_int_eq(efl_pack_at(widget, inv2, 100000), EINA_TRUE);
|
||||
ck_assert_ptr_eq(efl_ui_widget_parent_get(inv2), widget);
|
||||
ck_assert_ptr_eq(efl_test_parent_get(inv2), widget);
|
||||
Efl_Ui_Widget *wid2[] = {inv, wid[0], wid[1], wid[2], inv2};
|
||||
_ordering_equals(wid2, 5);
|
||||
}
|
||||
|
@ -377,15 +378,27 @@ EFL_START_TEST(pack_unpack_at3)
|
|||
efl_pack_end(widget, wid[i]);
|
||||
ck_assert_ptr_eq(efl_pack_unpack_at(widget, x), wid[(3+x)%3]);
|
||||
ck_assert_int_eq(efl_content_count(widget), 2);
|
||||
ck_assert_ptr_ne(efl_ui_widget_parent_get(wid[(3+x)%3]), widget);
|
||||
ck_assert_ptr_ne(efl_test_parent_get(wid[(3+x)%3]), widget);
|
||||
efl_pack_unpack_all(widget);
|
||||
}
|
||||
}
|
||||
EFL_END_TEST
|
||||
|
||||
void
|
||||
object_setup(void)
|
||||
{
|
||||
if (efl_isa(widget, EFL_UI_GROUP_ITEM_CLASS))
|
||||
{
|
||||
Efl_Ui_Collection *collection = efl_add(EFL_UI_GRID_CLASS, win);
|
||||
efl_content_set(win, collection);
|
||||
efl_pack_end(collection, widget);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
efl_pack_linear_behavior_test(TCase *tc)
|
||||
{
|
||||
tcase_add_checked_fixture(tc, object_setup, NULL);
|
||||
tcase_add_test(tc, pack_begin1);
|
||||
tcase_add_test(tc, pack_begin2);
|
||||
tcase_add_test(tc, pack_end1);
|
||||
|
|
|
@ -25,6 +25,7 @@ void efl_ui_selectable_behavior_test(TCase *tc);
|
|||
|
||||
void efl_test_container_content_equal(Efl_Ui_Widget **wid, unsigned int len);
|
||||
void efl_test_container_expect_evt_content_added(Efl_Ui_Widget *widget, const Efl_Event_Description *ev, Eina_Bool *flag, void *event_data);
|
||||
Efl_Ui_Widget* efl_test_parent_get(Eo *obj);
|
||||
|
||||
Eo* create_test_widget(void);
|
||||
|
||||
|
|
Loading…
Reference in New Issue