elementary: migrate Efl.Ui.List_View to use Efl.Ui.Collection_View.

Differential Revision: https://phab.enlightenment.org/D10035
This commit is contained in:
Cedric Bail 2019-09-19 11:19:56 -07:00
parent 2e1317baed
commit 78b69d45b5
16 changed files with 45 additions and 2623 deletions

View File

@ -14,39 +14,20 @@
#define NUM_ITEMS 400
const char *styles[] = {
"odd",
"even"
};
char edj_path[PATH_MAX];
static void
_realized_cb(void *data EINA_UNUSED, const Efl_Event *event)
{
Efl_Ui_List_View_Item_Event *ie = event->info;
if (!ie->layout) return;
Efl_Gfx_Entity *layout = event->info;
Efl_Ui_Layout *layout = ie->layout;
elm_object_focus_allow_set(layout, EINA_TRUE);
}
/*
static void
_unrealized_cb(void *data EINA_UNUSED, const Efl_Event *event)
{
Efl_Ui_List_View_Item_Event *ie = event->info;
efl_ui_view_model_set(ie->layout, NULL);
efl_del(ie->layout);
}
*/
static Efl_Model*
_make_model(Evas_Object *win)
{
Eina_Value vtext;
Efl_Generic_Model *model, *child;
unsigned int i, s;
unsigned int i;
char buf[256];
model = efl_add(EFL_GENERIC_MODEL_CLASS, win);
@ -54,10 +35,7 @@ _make_model(Evas_Object *win)
for (i = 0; i < (NUM_ITEMS); i++)
{
s = i%2;
child = efl_model_child_add(model);
eina_value_set(&vtext, styles[s]);
efl_model_property_set(child, "odd_style", &vtext);
snprintf(buf, sizeof(buf), "Item # %i", i);
eina_value_set(&vtext, buf);
@ -88,17 +66,13 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
factory = efl_add(EFL_UI_LAYOUT_FACTORY_CLASS, win);
efl_ui_widget_factory_item_class_set(factory, EFL_UI_LIST_DEFAULT_ITEM_CLASS);
efl_ui_property_bind(factory, "signal/efl,state,%v", "odd_style");
efl_ui_property_bind(factory, "signal/efl,state,%{selected;unselected}", "selected");
efl_ui_property_bind(factory, "efl.text", "title");
li = efl_add(EFL_UI_LIST_VIEW_CLASS, win
, efl_ui_list_view_layout_factory_set(efl_added, factory)
, efl_ui_view_model_set(efl_added, selmodel)
);
li = efl_add(EFL_UI_LIST_VIEW_CLASS, win,
efl_ui_collection_view_factory_set(efl_added, factory),
efl_ui_view_model_set(efl_added, selmodel));
efl_event_callback_add(li, EFL_UI_LIST_VIEW_EVENT_ITEM_REALIZED, _realized_cb, NULL);
// efl_event_callback_add(li, EFL_UI_LIST_VIEW_EVENT_ITEM_UNREALIZED, _unrealized_cb, NULL);
efl_event_callback_add(li, EFL_UI_COLLECTION_VIEW_EVENT_ITEM_REALIZED, _realized_cb, NULL);
elm_win_resize_object_add(win, li);
evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);

View File

@ -37,13 +37,12 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
efl_ui_property_bind(factory, "efl.text", "filename");
li = efl_add(EFL_UI_LIST_VIEW_CLASS, win);
efl_ui_list_view_layout_factory_set(li, factory);
efl_ui_collection_view_factory_set(li, factory);
efl_ui_view_model_set(li, model);
evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL);
imgf = efl_add(EFL_UI_IMAGE_FACTORY_CLASS, win);
efl_ui_property_bind(imgf, "", "path"); //connect to "path" property
efl_ui_factory_bind(factory, "efl.icon", imgf);

View File

@ -52,17 +52,15 @@ static void
_cleanup_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Priv_Data *priv = (Priv_Data*)data;
efl_unref(priv->model);
efl_del(priv->model);
}
static void
_focused(void *data, const Efl_Event *event)
_selected(void *data, const Efl_Event *event)
{
Priv_Data *priv = (Priv_Data*)data;
Evas_Object *focused = efl_ui_focus_manager_focus_get(event->object);
if (focused)
priv->selected = focused;
priv->selected = efl_ui_single_selectable_last_selected_get(event->object);
}
static void
@ -77,7 +75,7 @@ _bt_add_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_
child = efl_model_child_add(priv->model);
eina_value_set(&vtext, elm_object_text_get(priv->e_name));
efl_model_property_set(child, "name", &vtext);
efl_model_property_set(child, "filename", &vtext);
eina_value_set(&vtext, elm_object_text_get(priv->e_occ));
efl_model_property_set(child, "occupation", &vtext);
@ -95,7 +93,6 @@ _bt_del_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_
Priv_Data *priv = (Priv_Data*)data;
Eo *child = NULL;
//l = efl_ui_focus_manager_focus_get(priv->list1);
if(priv->selected)
{
printf("focused %p\n", priv->selected);
@ -113,21 +110,21 @@ static void
_bt_none_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Evas_Object *li = data;
efl_ui_list_view_select_mode_set(li, ELM_OBJECT_SELECT_MODE_NONE);
efl_ui_multi_selectable_async_select_mode_set(li, EFL_UI_SELECT_MODE_NONE);
}
static void
_bt_donly_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
_bt_donly_clicked(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Evas_Object *li = data;
efl_ui_list_view_select_mode_set(li, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
/* Evas_Object *li = data; */
/* efl_ui_multi_selectable_async_select_mode_set(li, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); */
}
static void
_bt_default_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Evas_Object *li = data;
efl_ui_list_view_select_mode_set(li, ELM_OBJECT_SELECT_MODE_DEFAULT);
efl_ui_multi_selectable_async_select_mode_set(li, EFL_UI_SELECT_MODE_SINGLE);
}
static void
@ -146,28 +143,21 @@ _bt_unset_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EIN
static void
_realized_1_cb(void *data EINA_UNUSED, const Efl_Event *event)
{
Efl_Ui_List_View_Item_Event *ie = event->info;
Efl_Gfx_Entity *layout = event->info;
evas_object_size_hint_weight_set(ie->layout, EVAS_HINT_EXPAND, 0);
evas_object_size_hint_align_set(ie->layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
efl_ui_property_bind(ie->layout, "efl.text", "name");
efl_ui_property_bind(ie->layout, "signal/efl,state,%v", "odd_style");
efl_ui_property_bind(layout, "efl.text", "filename");
}
static void
_realized_2_cb(void *data EINA_UNUSED, const Efl_Event *event)
{
Efl_Ui_List_View_Item_Event *ie = event->info;
printf("relized 2\n");
Efl_Gfx_Entity *layout = event->info;
elm_object_focus_allow_set(ie->layout, EINA_TRUE);
evas_object_size_hint_weight_set(ie->layout, EVAS_HINT_EXPAND, 0);
evas_object_size_hint_align_set(ie->layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
efl_ui_property_bind(ie->layout, "efl.text", "occupation");
efl_ui_property_bind(layout, "efl.text", "occupation");
}
static Efl_Model*
_make_model()
_make_model(void)
{
Eina_Value vtext, value;
Efl_Generic_Model *model, *child;
@ -182,11 +172,8 @@ _make_model()
{
child = efl_model_child_add(model);
i%2 ? eina_value_set(&vtext, "even") : eina_value_set(&vtext, "odd");
efl_model_property_set(child, "odd_style", &vtext);
eina_value_set(&vtext, texts[(i % len)]);
efl_model_property_set(child, "name", &vtext);
efl_model_property_set(child, "filename", &vtext);
eina_value_set(&vtext, subtexts[(i % len)]);
efl_model_property_set(child, "occupation", &vtext);
@ -226,21 +213,20 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
efl_ui_widget_factory_item_class_set(factory, EFL_UI_LIST_DEFAULT_ITEM_CLASS);
priv->list1 = efl_add(EFL_UI_LIST_VIEW_CLASS, win, efl_ui_view_model_set(efl_added, priv->model));
efl_event_callback_add(priv->list1, EFL_UI_LIST_VIEW_EVENT_ITEM_REALIZED, _realized_1_cb, priv);
efl_event_callback_add(priv->list1, EFL_UI_COLLECTION_VIEW_EVENT_ITEM_REALIZED, _realized_1_cb, priv);
evas_object_size_hint_weight_set(priv->list1, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(priv->list1, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(bx, priv->list1);
efl_ui_list_view_layout_factory_set(priv->list1, factory);
efl_ui_collection_view_factory_set(priv->list1, factory);
factory = efl_add(EFL_UI_LAYOUT_FACTORY_CLASS, win);
efl_ui_property_bind(factory, "efl.text", "filename");
efl_ui_property_bind(factory, "signal/efl,state,%v", "selected");
efl_ui_widget_factory_item_class_set(factory, EFL_UI_LIST_DEFAULT_ITEM_CLASS);
priv->list2 = efl_add(EFL_UI_LIST_VIEW_CLASS, win, efl_ui_view_model_set(efl_added, priv->model));
efl_event_callback_add(priv->list2, EFL_UI_LIST_VIEW_EVENT_ITEM_REALIZED, _realized_2_cb, priv->list2);
efl_event_callback_add(priv->list2, EFL_UI_COLLECTION_VIEW_EVENT_ITEM_REALIZED, _realized_2_cb, priv->list2);
evas_object_size_hint_weight_set(priv->list2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(priv->list2, EVAS_HINT_FILL, EVAS_HINT_FILL);
efl_ui_list_view_layout_factory_set(priv->list2, factory);
efl_ui_collection_view_factory_set(priv->list2, factory);
vbx = elm_box_add(win);
elm_box_pack_end(bx, vbx);
@ -313,7 +299,7 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
elm_box_pack_end(vbx, bt);
elm_box_pack_end(bx, priv->list2);
efl_event_callback_add(priv->list2, EFL_UI_FOCUS_MANAGER_EVENT_MANAGER_FOCUS_CHANGED, _focused ,priv);
efl_event_callback_add(priv->list2, EFL_UI_SINGLE_SELECTABLE_EVENT_SELECTION_CHANGED, _selected, priv);
evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _cleanup_cb, priv);

View File

@ -334,6 +334,7 @@ typedef Eo Efl_Ui_Spotlight_Indicator;
# include <efl_ui_list_view_model.eo.h>
# include <efl_ui_view_model.eo.h>
# include <efl_ui_collection_view.eo.h>
# include <efl_ui_list_view.eo.h>
# include <efl_ui_scroller.eo.h>
# include <efl_ui_pan.eo.h>

File diff suppressed because it is too large Load Diff

View File

@ -1,97 +1,17 @@
import elm_general;
struct @beta Efl.Ui.List_View_Item_Event
class @beta Efl.Ui.List_View extends Efl.Ui.Collection_View
{
[[Information related to item events.]] // TODO: This needs to be filled in.
layout: Efl.Ui.Layout; [[TBD]]
child: Efl.Model; [[TBD]]
index: int; [[TBD]]
}
class @beta Efl.Ui.List_View extends Efl.Ui.Layout_Base implements
Efl.Access.Widget.Action, Efl.Access.Selection,
Efl.Ui.Focus.Composition, Efl.Ui.Focus.Manager_Sub,
Efl.Ui.Container_Selectable, Efl.Ui.List_View_Model,
Efl.Ui.Widget_Focus_Manager
composites
Efl.Ui.Scrollable, Efl.Ui.Scrollbar
{
methods {
@property homogeneous {
[[When in homogeneous mode, all items have the same height and width.
Otherwise, each item's size is respected.
]]
get {
}
set {
}
values {
homogeneous: bool; [[Homogeneous mode setting. Default is $false.]]
}
}
@property select_mode {
[[Listview select mode.]]
get {}
set {}
values {
mode: Elm.Object.Select_Mode(Elm.Object.Select_Mode.max); [[The select mode.]]
}
}
@property default_style {
[[TBD]] // TODO: This needs to be filled in. Does not seem to be in use.
values {
style: stringshare; [[TBD]]
}
}
@property layout_factory {
[[Listview layout factory set.]]
set {}
values {
factory: Efl.Ui.Factory; [[The factory.]]
}
}
}
events {
item,realized : Efl.Ui.List_View_Item_Event;
item,unrealized : Efl.Ui.List_View_Item_Event;
item,focused : Efl.Ui.List_View_Item_Event;
item,unfocused : Efl.Ui.List_View_Item_Event;
item,highlighted : Efl.Ui.List_View_Item_Event;
item,unhighlighted : Efl.Ui.List_View_Item_Event;
}
[[A scrollable list of @Efl.Ui.Item objects, typically @Efl.Ui.List_Default_Item objects.
Items are added asynchronously by an @Efl.Ui.Factory from the definition of an @Efl.Model.
The orientation (vertical or horizontal) of the list can be set with
@Efl.Ui.Layout_Orientable.orientation.
Items inside this widget can be selected according to the @Efl.Ui.Multi_Selectable_Async.select_mode
policy, and the selection can be retrieved with @Efl.Ui.Multi_Selectable_Async.selected_iterator_new.
]]
data: null;
implements {
Efl.Object.constructor;
Efl.Object.finalize;
Efl.Object.destructor;
Efl.Gfx.Entity.position { set; }
Efl.Gfx.Entity.size { set; }
// Smart obj
Efl.Canvas.Group.group_member_add;
Efl.Canvas.Group.group_calculate;
Efl.Ui.List_View_Model.load_range { set;}
Efl.Ui.List_View_Model.realize;
Efl.Ui.List_View_Model.unrealize;
Efl.Ui.List_View_Model.model_size { get; }
Efl.Ui.List_View_Model.min_size { get; set; }
// Widget
Efl.Ui.Widget_Focus_Manager.focus_manager_create;
Efl.Ui.Widget.widget_input_event_handler;
Efl.Ui.Widget.focus_state_apply;
Efl.Ui.Focus.Composition.prepare;
Efl.Ui.View.model { get; set; }
Efl.Layout.Signal.signal_callback_add;
Efl.Layout.Signal.signal_callback_del;
Efl.Access.Object.access_children { get; }
Efl.Access.Selection.selected_children_count { get; }
Efl.Access.Selection.selected_child { get; }
Efl.Access.Selection.selected_child_deselect;
Efl.Access.Selection.child_select;
Efl.Access.Selection.child_deselect;
Efl.Access.Selection.is_child_selected;
Efl.Access.Selection.all_children_select;
Efl.Access.Selection.access_selection_clear;
}
}

View File

@ -1,41 +0,0 @@
import efl_ui_list_view_types;
interface @beta Efl.Ui.List_View_Model
{
methods {
@property load_range {
set {}
values {
first: int;
count: int;
}
}
realize {
params {
item: ptr(Efl.Ui.List_View_Layout_Item);
}
return: ptr(Efl.Ui.List_View_Layout_Item);
}
unrealize {
params {
item: ptr(Efl.Ui.List_View_Layout_Item);
}
}
@property model_size {
get {}
values {
s: int;
}
}
@property min_size {
[[Minimal content size.]]
set {}
get {}
values {
min: Eina.Size2D;
}
}
}
}

View File

@ -1,12 +0,0 @@
class @beta Efl.Ui.List_View_Pan extends Efl.Ui.Pan
{
[[Elementary Efl_Ui_List_View pan class]]
implements {
Efl.Object.destructor;
Efl.Ui.Pan.content_size { get; }
Efl.Ui.Pan.pan_position { get; set; }
Efl.Ui.Pan.pan_position_min { get; }
Efl.Ui.Pan.pan_position_max { get; }
Efl.Canvas.Group.group_calculate;
}
}

View File

@ -1,728 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#include <Elementary.h>
#include <assert.h>
#include "elm_priv.h"
#include "efl_ui_list_view_relayout.eo.h"
#include "efl_ui_list_view_seg_array.h"
#define MY_CLASS EFL_UI_LIST_VIEW_PRECISE_LAYOUTER_CLASS
typedef struct _Efl_Ui_List_View_Precise_Layouter_Data
{
Efl_Model* model;
Efl_Ui_List_View_Model *modeler;
Ecore_Job *calc_job;
Efl_Ui_List_View_Seg_Array *seg_array;
Eina_Size2D min;
unsigned int calc_progress;
int count_total;
Eina_Bool initialized : 1;
Eina_Bool recalc : 1;
Eina_Bool resize : 1;
} Efl_Ui_List_View_Precise_Layouter_Data;
typedef struct _Efl_Ui_List_View_Precise_Layouter_Node_Data
{
Eina_Size2D min;
Eina_Size2D size;
Eina_Bool realized;
} Efl_Ui_List_View_Precise_Layouter_Node_Data;
typedef struct _Efl_Ui_List_View_Precise_Layouter_Callback_Data
{
Efl_Ui_List_View_Precise_Layouter_Data *pd;
Efl_Ui_List_View_Layout_Item *item;
} Efl_Ui_List_View_Precise_Layouter_Callback_Data;
#include "efl_ui_list_view_precise_layouter.eo.h"
static void _efl_ui_list_view_relayout_layout_do(Efl_Ui_List_View_Precise_Layouter_Data *);
static Eina_Bool _initilize(Eo *, Efl_Ui_List_View_Precise_Layouter_Data*, Efl_Ui_List_View_Model*, Efl_Ui_List_View_Seg_Array*);
static void _finalize(Eo *, Efl_Ui_List_View_Precise_Layouter_Data*);
static void _node_realize(Efl_Ui_List_View_Precise_Layouter_Data*, Efl_Ui_List_View_Seg_Array_Node*);
static void _node_unrealize(Efl_Ui_List_View_Precise_Layouter_Data*, Efl_Ui_List_View_Seg_Array_Node*);
static void
_item_size_calc(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Layout_Item* item)
{
int boxx, boxy, boxw, boxh, boxl, boxr, boxt, boxb, pad[4];
double align[2];
Eina_Bool fill[2];
Eina_Size2D max;
efl_gfx_hint_margin_get(item->layout, &pad[0], &pad[1], &pad[2], &pad[3]);
evas_object_geometry_get(pd->modeler, &boxx, &boxy, &boxw, &boxh);
efl_gfx_hint_margin_get(pd->modeler, &boxl, &boxr, &boxt, &boxb);
efl_gfx_hint_align_get(item->layout, &align[0], &align[1]);
efl_gfx_hint_fill_get(item->layout, &fill[0], &fill[1]);
max = efl_gfx_hint_size_combined_max_get(item->layout);
// box outer margin
boxw -= boxl + boxr;
boxh -= boxt + boxb;
boxx += boxl;
boxy += boxt;
if (EINA_DBL_EQ(align[0], -1))
{
align[0] = 0.5;
fill[0] = EINA_TRUE;
}
else if (align[0] < 0)
{
align[0] = 0;
}
if (EINA_DBL_EQ(align[1], -1))
{
align[1] = 0.5;
fill[1] = EINA_TRUE;
}
else if (align[1] < 0)
{
align[1] = 0;
}
if (align[0] > 1) align[0] = 1;
if (align[1] > 1) align[1] = 1;
if (max.w <= 0) max.w = INT_MAX;
if (max.h <= 0) max.h = INT_MAX;
if (max.w < item->min.w) max.w = item->min.w;
if (max.h < item->min.h) max.h = item->min.h;
// horizontally
if (max.w < INT_MAX)
{
item->size.w = MIN(MAX(item->min.w - pad[0] - pad[1], max.w), boxw);
item->pos.x = boxx + pad[0];
}
else if (fill[0])
{
// fill x
item->size.w = boxw - pad[0] - pad[1];
item->pos.x = boxx + pad[0];
}
else
{
item->size.w = item->min.w - pad[0] - pad[1];
item->pos.x = boxx + ((boxw - item->size.w) * align[0]) + pad[0];
}
// vertically
if (max.h < INT_MAX)
{
item->size.h = MIN(MAX(item->min.h - pad[2] - pad[3], max.h), boxh);
item->pos.y = boxy + pad[2];
}
else if (fill[1])
{
// fill y
item->size.h = item->min.h - pad[2] - pad[3];
item->pos.y = boxy + pad[2];
}
else
{
item->size.h = item->min.h - pad[2] - pad[3];
item->pos.y = boxy + ((item->min.h - item->size.h) * align[1]) + pad[2];
}
}
static Eina_Size2D
_item_min_calc(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Layout_Item* item)
{
Efl_Ui_List_View_Seg_Array_Node *itemnode = item->tree_node;
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata;
Efl_Ui_List_View_Layout_Item *layout_item;
int i, pad[4];
Eina_Size2D min = efl_gfx_hint_size_combined_min_get(item->layout);
efl_gfx_hint_margin_get(item->layout, &pad[0], &pad[1], &pad[2], &pad[3]);
min.w += pad[0] + pad[1];
min.h += pad[2] + pad[3];
if (item->min.h == min.h && item->min.w == min.w)
return min;
EINA_SAFETY_ON_NULL_RETURN_VAL(itemnode, min);
EINA_SAFETY_ON_NULL_RETURN_VAL(itemnode->layout_data, min);
nodedata = itemnode->layout_data;
pd->min.h += min.h - item->min.h;
nodedata->min.h += min.h - item->min.h;
if (nodedata->min.w <= min.w)
nodedata->min.w = min.w;
else if (nodedata->min.w == item->min.w)
{
nodedata->min.w = 0;
for (i = 0; i != itemnode->length; ++i)
{
layout_item = (Efl_Ui_List_View_Layout_Item *)itemnode->pointers[i];
if (nodedata->min.w < layout_item->min.w)
nodedata->min.w = layout_item->min.w;
if (item->min.w == layout_item->min.w)
break;
}
}
if (pd->min.w <= min.w)
pd->min.w = min.w;
else if (pd->min.w == item->min.w)
{
Efl_Ui_List_View_Seg_Array_Node *node2;
Eina_Accessor *nodes = efl_ui_list_view_seg_array_node_accessor_get(pd->seg_array);
pd->min.w = min.w;
EINA_ACCESSOR_FOREACH(nodes, i, node2)
{
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata2 = node2->layout_data;
if (pd->min.w < nodedata2->min.w)
pd->min.w = nodedata2->min.w;
if (item->min.w == nodedata2->min.w)
break;
}
eina_accessor_free(nodes);
}
item->min.w = min.w;
item->min.h = min.h;
return item->min;
}
static void
_on_item_size_hint_change(void *data, Evas *e EINA_UNUSED,
Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Efl_Ui_List_View_Precise_Layouter_Callback_Data *cb_data = data;
Efl_Ui_List_View_Precise_Layouter_Data *pd = cb_data->pd;
Efl_Ui_List_View_Layout_Item *item = cb_data->item;;
Efl_Ui_List_View_Seg_Array_Node *node = item->tree_node;
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata = node->layout_data;
_item_min_calc(pd, item);
if (!nodedata->realized)
{
free(evas_object_event_callback_del(item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change));
efl_ui_list_view_model_unrealize(pd->modeler, item);
}
}
static void
_on_modeler_resize(void *data, Evas *e EINA_UNUSED,
Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Efl_Ui_List_View_Precise_Layouter_Data *pd = data;
pd->resize = EINA_TRUE;
}
typedef struct _Request Request;
struct _Request
{
Efl_Ui_List_View_Precise_Layouter_Data *pd;
unsigned int index;
};
static Eina_Value
_children_get(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
{
Request *r = data;
if (eina_value_type_get(&v) == EINA_VALUE_TYPE_ERROR)
goto on_error;
efl_ui_list_view_seg_array_insert_value(r->pd->seg_array, r->index, v);
r->pd->recalc = EINA_TRUE;
evas_object_smart_changed(r->pd->modeler);
on_error:
free(r);
return v;
}
static void
_child_added_cb(void *data, const Efl_Event *event)
{
Efl_Model_Children_Event* evt = event->info;
Efl_Ui_List_View_Precise_Layouter_Data *pd = data;
Eina_Future *f;
Request *r;
r = calloc(1, sizeof (Request));
if (!r) return;
r->index = evt->index;
r->pd = pd;
f = efl_model_children_slice_get(pd->model, evt->index, 1);
f = eina_future_then(f, _children_get, r, NULL);
}
static void
_child_removed_cb(void *data, const Efl_Event *event)
{
Efl_Model_Children_Event* evt = event->info;
Efl_Ui_List_View_Precise_Layouter_Data *pd = data;
Efl_Ui_List_View_Layout_Item *layout_item, *litem;
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata;
Efl_Ui_List_View_Seg_Array_Node *itemnode;
int i;
litem = efl_ui_list_view_seg_array_remove(pd->seg_array, evt->index);
if (!litem) return;
itemnode = litem->tree_node;
nodedata = itemnode->layout_data;
free(evas_object_event_callback_del(litem->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change));
pd->min.h -= litem->min.h;
nodedata->min.h -= litem->min.h;
if (nodedata->min.w == litem->min.w)
nodedata->min.w = 0;
for (i = 0; i != itemnode->length; ++i)
{
layout_item = (Efl_Ui_List_View_Layout_Item *)itemnode->pointers[i];
if (nodedata->min.w < layout_item->min.w)
nodedata->min.w = layout_item->min.w;
if (litem->min.w == layout_item->min.w)
{
nodedata->min.w = layout_item->min.w;
break;
}
}
if (pd->min.w == litem->min.w)
{
Efl_Ui_List_View_Seg_Array_Node *node2;
Eina_Accessor *nodes = efl_ui_list_view_seg_array_node_accessor_get(pd->seg_array);
pd->min.w = 0;
EINA_ACCESSOR_FOREACH(nodes, i, node2)
{
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata2 = node2->layout_data;
if (pd->min.w < nodedata2->min.w)
pd->min.w = nodedata2->min.w;
if (litem->min.w == nodedata2->min.w)
break;
}
eina_accessor_free(nodes);
}
efl_ui_list_view_model_unrealize(pd->modeler, litem);
free(litem);
pd->recalc = EINA_TRUE;
evas_object_smart_changed(pd->modeler);
}
static void
_child_count_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
{
Efl_Ui_List_View_Precise_Layouter_Data *pd = data;
pd->count_total = efl_model_children_count_get(pd->model);
if (pd->count_total)
efl_event_callback_del(pd->model, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, _child_count_changed_cb, pd);
}
static Eina_Bool
_initilize(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Model *modeler, Efl_Ui_List_View_Seg_Array *seg_array)
{
if(pd->initialized)
return EINA_TRUE;
efl_replace(&pd->modeler, modeler);
if(!pd->model || !pd->modeler)
return EINA_FALSE;
pd->recalc = EINA_TRUE;
pd->initialized = EINA_TRUE;
pd->seg_array = seg_array;
efl_ui_list_view_model_load_range_set(pd->modeler, 0, pd->count_total); // load all
efl_event_callback_add(pd->model, EFL_MODEL_EVENT_CHILD_ADDED, _child_added_cb, pd);
efl_event_callback_add(pd->model, EFL_MODEL_EVENT_CHILD_REMOVED, _child_removed_cb, pd);
evas_object_event_callback_add(modeler, EVAS_CALLBACK_RESIZE, _on_modeler_resize, pd);
pd->min.w = 0;
pd->min.h = 0;
return EINA_TRUE;
}
static void
_finalize(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd)
{
Efl_Ui_List_View_Seg_Array_Node* node;
int i = 0;
if (pd->model)
{
efl_event_callback_del(pd->model, EFL_MODEL_EVENT_CHILD_ADDED, _child_added_cb, pd);
efl_event_callback_del(pd->model, EFL_MODEL_EVENT_CHILD_REMOVED, _child_removed_cb, pd);
pd->count_total = 0;
}
if (pd->seg_array)
{
Eina_Accessor *nodes = efl_ui_list_view_seg_array_node_accessor_get(pd->seg_array);
EINA_ACCESSOR_FOREACH(nodes, i, node)
{
_node_unrealize(pd, node);
free(node->layout_data);
}
eina_accessor_free(nodes);
}
pd->min.w = 0;
pd->min.h = 0;
if (pd->modeler)
{
evas_object_event_callback_del_full(pd->modeler, EVAS_CALLBACK_RESIZE, _on_modeler_resize, pd);
efl_ui_list_view_model_min_size_set(pd->modeler, pd->min);
}
pd->seg_array = NULL;
efl_replace(&pd->modeler, NULL);
pd->initialized = EINA_FALSE;
pd->recalc = EINA_TRUE;
}
static void
_node_realize(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Seg_Array_Node *node)
{
Efl_Ui_List_View_Layout_Item* layout_item;
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata = node->layout_data;
int i;
EINA_SAFETY_ON_NULL_RETURN(nodedata);
if (nodedata->realized)
return;
nodedata->realized = EINA_TRUE;
for (i = 0; i != node->length; ++i)
{
layout_item = (Efl_Ui_List_View_Layout_Item *)node->pointers[i];
efl_ui_list_view_model_realize(pd->modeler, layout_item);
}
}
static void
_node_unrealize(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Seg_Array_Node *node)
{
Efl_Ui_List_View_Layout_Item* layout_item;
Efl_Ui_List_View_Precise_Layouter_Callback_Data *cb_data;
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata = node->layout_data;
int i;
EINA_SAFETY_ON_NULL_RETURN(nodedata);
if (!nodedata->realized)
return;
nodedata->realized = EINA_FALSE;
for (i = 0; i != node->length; ++i)
{
layout_item = (Efl_Ui_List_View_Layout_Item *)node->pointers[i];
if (layout_item->layout)
{
cb_data = evas_object_event_callback_del(layout_item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change);
free(cb_data);
efl_ui_list_view_model_unrealize(pd->modeler, layout_item);
}
}
}
static void
_calc_range(Efl_Ui_List_View_Precise_Layouter_Data *pd)
{
Efl_Ui_List_View_Seg_Array_Node *node;
Evas_Coord ch, ny;
Eina_Rect vgmt;
Eina_Position2D spos;
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata;
int i;
vgmt = efl_ui_scrollable_viewport_geometry_get(pd->modeler);
spos = efl_ui_scrollable_content_pos_get(pd->modeler);
ny = spos.y - (vgmt.h / 2);
if (ny < 0) spos.y = 0;
else spos.y = ny;
vgmt.h *= 2;
ch = 0;
Eina_Accessor *nodes = efl_ui_list_view_seg_array_node_accessor_get(pd->seg_array);
EINA_ACCESSOR_FOREACH(nodes, i, node)
{
nodedata = node->layout_data;
if (!nodedata || !nodedata->min.h)
continue;
if ((ch > spos.y || nodedata->min.h + ch > spos.y) && (ch < (spos.y + vgmt.h) || nodedata->min.h + ch < spos.y + vgmt.h))
_node_realize(pd, node);
else
_node_unrealize(pd, node);
ch += nodedata->min.h;
}
eina_accessor_free(nodes);
}
static void
_calc_size_job(void *data)
{
Efl_Ui_List_View_Precise_Layouter_Data *pd;
Efl_Ui_List_View_Seg_Array_Node *node;
Efl_Ui_List_View_Layout_Item *layout_item;
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata;
Eo *obj = data;
int i;
double start_time = ecore_time_get();
EINA_SAFETY_ON_NULL_RETURN(data);
pd = efl_data_scope_get(obj, MY_CLASS);
if (EINA_UNLIKELY(!pd)) return;
Eina_Accessor *nodes = efl_ui_list_view_seg_array_node_accessor_get(pd->seg_array);
while (eina_accessor_data_get(nodes, pd->calc_progress, (void **)&node))
{
pd->calc_progress++;
if (!node->layout_data)
node->layout_data = calloc(1, sizeof(Efl_Ui_List_View_Precise_Layouter_Node_Data));
nodedata = node->layout_data;
if (pd->calc_progress == 1)
nodedata->realized = EINA_TRUE;
for (i = 0; i != node->length; ++i)
{
layout_item = (Efl_Ui_List_View_Layout_Item *)node->pointers[i];
EINA_SAFETY_ON_NULL_RETURN(layout_item);
// cache size of new items
if ((layout_item->min.w == 0) && (layout_item->min.h == 0) && (!layout_item->layout))
efl_ui_list_view_model_realize(pd->modeler, layout_item);
}
if ( (ecore_time_get() - start_time ) > 0.01 )
{
ecore_job_del(pd->calc_job);
pd->calc_job = ecore_job_add(_calc_size_job, obj);
eina_accessor_free(nodes);
return;
}
}
eina_accessor_free(nodes);
pd->calc_progress = 0;
pd->calc_job = NULL;
pd->recalc = EINA_FALSE;
}
EOLIAN static Efl_Object *
_efl_ui_list_view_precise_layouter_efl_object_constructor(Eo *obj, Efl_Ui_List_View_Precise_Layouter_Data *pd)
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
pd->initialized = EINA_FALSE;
return obj;
}
EOLIAN static void
_efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_content_created(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Layout_Item *item)
{
Efl_Ui_List_View_Precise_Layouter_Callback_Data *cb_data;
EINA_SAFETY_ON_NULL_RETURN(item);
EINA_SAFETY_ON_NULL_RETURN(item->layout);
Efl_Ui_List_View_Seg_Array_Node *node = item->tree_node;
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata = node->layout_data;
Eina_Size2D min = _item_min_calc(pd, item);
if (min.w && min.h && !nodedata->realized)
{
efl_ui_list_view_model_unrealize(pd->modeler, item);
return;
}
cb_data = calloc(1, sizeof(Efl_Ui_List_View_Precise_Layouter_Callback_Data));
if (!cb_data) return;
cb_data->pd = pd;
cb_data->item = item;
evas_object_event_callback_add(item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change, cb_data);
_item_size_calc(pd, item);
}
EOLIAN static Eina_List *
_efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_elements_get(const Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd)
{
Eina_List *elements_order = NULL;
Efl_Ui_List_View_Layout_Item* layout_item;
Efl_Ui_List_View_Seg_Array_Node *items_node;
int i, j = 0;
Eina_Accessor *nodes = efl_ui_list_view_seg_array_node_accessor_get(pd->seg_array);
EINA_ACCESSOR_FOREACH(nodes, i, items_node)
{
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata = items_node->layout_data;
if (!nodedata || !nodedata->realized)
continue;
for (j = 0; j != items_node->length;++j)
{
layout_item = (Efl_Ui_List_View_Layout_Item *)items_node->pointers[j];
if (layout_item->layout)
elements_order = eina_list_append(elements_order, layout_item->layout);
}
}
eina_accessor_free(nodes);
return elements_order;
}
EOLIAN static void
_efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_model_set(Eo *obj, Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Model *model)
{
_finalize(obj, pd);
efl_replace(&pd->model, model);
if (pd->model)
{
pd->count_total = efl_model_children_count_get(pd->model);
if (pd->count_total && pd->modeler)
efl_ui_list_view_model_load_range_set(pd->modeler, 0, pd->count_total); // load all
else
efl_event_callback_add(pd->model, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, _child_count_changed_cb, pd);
}
}
static void
_efl_ui_list_view_relayout_layout_do(Efl_Ui_List_View_Precise_Layouter_Data *pd)
{
Eina_Rect vgmt;
Eina_Position2D spos;
double cur_pos = 0;
Efl_Ui_List_View_Layout_Item* layout_item;
Efl_Ui_List_View_Seg_Array_Node *items_node;
int i, j = 0;
int boxx, boxy, boxw, boxh, extra = 0, rounding = 0;
int boxl = 0, boxr = 0, boxt = 0, boxb = 0;
_calc_range(pd);
evas_object_geometry_get(pd->modeler, &boxx, &boxy, &boxw, &boxh);
efl_gfx_hint_margin_get(pd->modeler, &boxl, &boxr, &boxt, &boxb);
// box outer margin
boxw -= boxl + boxr;
boxh -= boxt + boxb;
boxx += boxl;
boxy += boxt;
// available space. if <0 we overflow
extra = boxh - pd->min.h;
if (extra < 0) extra = 0;
efl_ui_list_view_model_min_size_set(pd->modeler, pd->min);
vgmt = efl_ui_scrollable_viewport_geometry_get(pd->modeler);
spos = efl_ui_scrollable_content_pos_get(pd->modeler);
Eina_Accessor *nodes = efl_ui_list_view_seg_array_node_accessor_get(pd->seg_array);
EINA_ACCESSOR_FOREACH(nodes, i, items_node)
{
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata = items_node->layout_data;
if (!items_node->layout_data)
continue;
if (!nodedata->realized)
{
cur_pos += nodedata->min.h;
continue;
}
for (j = 0; j != items_node->length;++j)
{
layout_item = (Efl_Ui_List_View_Layout_Item *)items_node->pointers[j];
double x, y, w, h;
double weight_x, weight_y;
if (!(layout_item->min.w && layout_item->min.h))
continue;
// extra rounding up (compensate cumulative error)
if ((i == (pd->count_total - 1)) && (cur_pos - floor(cur_pos) >= 0.5))
rounding = 1;
if (layout_item->layout)
{
if (pd->resize)
_item_size_calc(pd, layout_item);
efl_gfx_hint_weight_get(layout_item->layout, &weight_x, &weight_y);
}
else
{
cur_pos += layout_item->size.h;
continue;
}
x = layout_item->pos.x;
y = layout_item->pos.y + cur_pos;
w = layout_item->size.w;
h = layout_item->size.h + rounding + weight_y * extra;
cur_pos += h;
if (w < pd->min.w) w = pd->min.w;
if (w > vgmt.w) w = vgmt.w;
evas_object_geometry_set(layout_item->layout, (x + 0 - spos.x), (y + 0 - spos.y), w, h);
}
}
eina_accessor_free(nodes);
pd->resize = EINA_FALSE;
}
EOLIAN static void
_efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_layout_do
(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd
, Efl_Ui_List_View_Model *modeler, int first EINA_UNUSED, Efl_Ui_List_View_Seg_Array *seg_array)
{
if (!_initilize(obj, pd, modeler, seg_array) || !pd->seg_array)
return;
if (!pd->calc_job && pd->recalc && efl_ui_list_view_seg_array_count(seg_array) > 0)
{
// cache size of new items
pd->calc_progress = 0;
pd->calc_job = ecore_job_add(_calc_size_job, obj);
return;
}
_efl_ui_list_view_relayout_layout_do(pd);
}
#include "efl_ui_list_view_precise_layouter.eo.c"

View File

@ -1,10 +0,0 @@
class @beta Efl.Ui.List_View_Precise_Layouter extends Efl.Object implements Efl.Ui.List_View_Relayout
{
implements {
Efl.Object.constructor;
Efl.Ui.List_View_Relayout.layout_do;
Efl.Ui.List_View_Relayout.content_created;
Efl.Ui.List_View_Relayout.model { set; }
Efl.Ui.List_View_Relayout.elements { get; }
}
}

View File

@ -1,78 +0,0 @@
#ifndef EFL_UI_LIST_VIEW_PRIVATE_H
#define EFL_UI_LIST_VIEW_PRIVATE_H
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#include <Elementary.h>
#include "efl_ui_list_view_relayout.eo.h"
#include "efl_ui_list_view_pan.eo.h"
#include "elm_priv.h"
typedef struct _Efl_Ui_List_View_Data Efl_Ui_List_View_Data;
int efl_ui_list_view_item_index_get(Efl_Ui_List_View_Layout_Item *item);
#include "efl_ui_list_view_seg_array.h"
struct _Efl_Ui_List_View_Data
{
Eo *obj;
Eo *scrl_mgr;
Efl_Ui_List_View_Pan *pan_obj;
Efl_Model *model;
Eina_Stringshare *style;
struct {
Eina_Future *future;
int start;
int count;
} slice;
Efl_Ui_Layout_Factory *factory;
Eina_List *selected_items;
Efl_Ui_Focus_Manager *manager;
Efl_Ui_List_View_Relayout *relayout;
Efl_Ui_List_View_Seg_Array *seg_array;
int seg_array_first;
Elm_Object_Select_Mode select_mode;
Eina_Size2D min;
Eina_Bool homogeneous : 1;
Eina_Bool scrl_freeze : 1;
};
typedef struct _Efl_Ui_List_View_Pan_Data Efl_Ui_List_View_Pan_Data;
struct _Efl_Ui_List_View_Pan_Data
{
Eo *wobj;
Eina_Rect gmt;
};
#define EFL_UI_LIST_VIEW_DATA_GET(o, ptr) \
Efl_Ui_List_View_Data * ptr = efl_data_scope_get(o, EFL_UI_LIST_VIEW_CLASS)
#define EFL_UI_LIST_VIEW_DATA_GET_OR_RETURN(o, ptr) \
EFL_UI_LIST_VIEW_DATA_GET(o, ptr); \
if (EINA_UNLIKELY(!ptr)) \
{ \
ERR("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#define EFL_UI_LIST_VIEW_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
EFL_UI_LIST_VIEW_DATA_GET(o, ptr); \
if (EINA_UNLIKELY(!ptr)) \
{ \
ERR("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#endif

View File

@ -1,30 +0,0 @@
interface @beta Efl.Ui.List_View_Relayout
{
methods {
layout_do {
params {
modeler: Efl.Ui.List_View_Model;
first: int;
children: ptr(Efl_Ui_List_View_Seg_Array);
}
}
content_created {
params {
item: ptr(Efl.Ui.List_View_Layout_Item);
}
}
@property model {
[[Model that is/will be ]]
set {}
values {
model: Efl.Model; [[Efl model]]
}
}
@property elements {
get {}
values {
elements: list<Efl.Gfx.Entity>; [[The order to use]]
}
}
}
}

View File

@ -1,477 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#include "elm_priv.h"
#include <assert.h>
#include "efl_ui_list_view_private.h"
#include "efl_ui_list_view_seg_array.h"
static int
_search_lookup_cb(Eina_Rbtree const* rbtree, const void* key, int length EINA_UNUSED, void* data EINA_UNUSED)
{
Efl_Ui_List_View_Seg_Array_Node const* node = (void const*)rbtree;
int index = *(int*)key;
if(index < node->first)
{
return 1;
}
else if(index < node->first + node->length)
{
return 0;
}
else
{
return -1;
}
}
static int
_insert_lookup_cb(Eina_Rbtree const* rbtree, const void* key, int length EINA_UNUSED, void* data EINA_UNUSED)
{
Efl_Ui_List_View_Seg_Array_Node const* node = (void const*)rbtree;
int index = *(int*)key;
if(index < node->first)
{
return 1;
}
else if(index < node->first + node->max)
{
return 0;
}
else
{
return -1;
}
}
static Eina_Rbtree_Direction
_rbtree_compare(Efl_Ui_List_View_Seg_Array_Node const* left,
Efl_Ui_List_View_Seg_Array_Node const* right, void* data EINA_UNUSED)
{
if(left->first < right->first)
return EINA_RBTREE_LEFT;
else
return EINA_RBTREE_RIGHT;
}
static void
_free_node(Efl_Ui_List_View_Seg_Array_Node* node, void* data EINA_UNUSED)
{
int i = 0;
while (i < node->length)
{
Efl_Ui_List_View_Layout_Item* item = node->pointers[i];
efl_unref(item->children);
free(item);
++i;
}
free(node);
}
static Efl_Ui_List_View_Seg_Array_Node*
_alloc_node(Efl_Ui_List_View_Seg_Array* pd, int first)
{
Efl_Ui_List_View_Seg_Array_Node* node;
node = calloc(1, sizeof(Efl_Ui_List_View_Seg_Array_Node) + pd->step_size*sizeof(Efl_Ui_List_View_Layout_Item*));
if (!node) return NULL;
node->first = first;
node->max = pd->step_size;
pd->root = (void*)eina_rbtree_inline_insert(EINA_RBTREE_GET(pd->root), EINA_RBTREE_GET(node),
EINA_RBTREE_CMP_NODE_CB(&_rbtree_compare), NULL);
pd->node_count++;
return node;
}
static Efl_Ui_List_View_Layout_Item*
_create_item_partial(Efl_Model* model)
{
Efl_Ui_List_View_Layout_Item* item = calloc(1, sizeof(Efl_Ui_List_View_Layout_Item));
if (!item) return NULL;
item->children = efl_ref(model);
return item;
}
static Efl_Ui_List_View_Layout_Item*
_create_item(Efl_Model* model, Efl_Ui_List_View_Seg_Array_Node* node, unsigned int index)
{
Efl_Ui_List_View_Layout_Item* item = _create_item_partial(model);
item->index_offset = index - node->first;
item->tree_node = node;
return item;
}
static void
_efl_ui_list_view_seg_array_insert_at_node(Efl_Ui_List_View_Seg_Array* pd, int index,
Efl_Ui_List_View_Layout_Item* item, Efl_Ui_List_View_Seg_Array_Node* node)
{
Eina_Iterator* iterator;
int pos;
if(node && node->length != node->max && (index - node->first) <= node->length)
{
pos = index - node->first;
item->tree_node = node;
item->index_offset = pos;
if(pos < node->length)
{
assert(node->length != node->max);
memmove(&node->pointers[pos], &node->pointers[pos+1], sizeof(node->pointers[pos])*(node->length - pos));
node->pointers[pos] = item;
node->length++;
}
else
{
assert(pos == node->length);
assert(node->length != node->max);
node->pointers[pos] = item;
node->length++;
}
}
else
{
node = _alloc_node(pd, index);
node->pointers[0] = item;
node->length++;
item->index_offset = 0;
item->tree_node = node;
}
node = (void*)EINA_RBTREE_GET(node)->son[EINA_RBTREE_LEFT];
iterator = eina_rbtree_iterator_infix((void*)node);
while(eina_iterator_next(iterator, (void**)&node))
{
node->first++;
}
eina_iterator_free(iterator);
}
static void
_efl_ui_list_view_seg_array_insert_object(Efl_Ui_List_View_Seg_Array *pd, unsigned int index, Efl_Model *children)
{
Efl_Ui_List_View_Seg_Array_Node *node;
node = (void*)eina_rbtree_inline_lookup(EINA_RBTREE_GET(pd->root),
&index, sizeof(index), &_insert_lookup_cb, NULL);
if (!node)
{
node = _alloc_node(pd, index);
}
assert(node->length < node->max);
node->pointers[node->length] = _create_item(children, node, index);
node->length++;
pd->count++;
}
typedef struct _Efl_Ui_List_View_Segarray_Eina_Accessor
{
Eina_Accessor vtable;
Efl_Ui_List_View_Seg_Array* seg_array;
} Efl_Ui_List_View_Segarray_Eina_Accessor;
static Eina_Bool
_efl_ui_list_view_seg_array_accessor_get_at(Efl_Ui_List_View_Segarray_Eina_Accessor* acc,
int idx, void** data)
{
Efl_Ui_List_View_Seg_Array_Node* node;
node = (void*)eina_rbtree_inline_lookup(EINA_RBTREE_GET(acc->seg_array->root),
&idx, sizeof(idx), &_search_lookup_cb, NULL);
if (node && (node->first <= idx && node->first + node->length > idx))
{
int i = idx - node->first;
Efl_Ui_List_View_Layout_Item* item = node->pointers[i];
*data = item;
return EINA_TRUE;
}
return EINA_FALSE;
}
static void*
_efl_ui_list_view_seg_array_accessor_get_container(Efl_Ui_List_View_Segarray_Eina_Accessor* acc EINA_UNUSED)
{
return NULL;
}
static void
_efl_ui_list_view_seg_array_accessor_free(Efl_Ui_List_View_Segarray_Eina_Accessor* acc EINA_UNUSED)
{
free(acc);
}
static Eina_Bool
_efl_ui_list_view_seg_array_accessor_lock(Efl_Ui_List_View_Segarray_Eina_Accessor* acc EINA_UNUSED)
{
return EINA_FALSE;
}
static Eina_Bool
_efl_ui_list_view_seg_array_accessor_unlock(Efl_Ui_List_View_Segarray_Eina_Accessor* acc EINA_UNUSED)
{
return EINA_FALSE;
}
static Eina_Accessor*
_efl_ui_list_view_seg_array_accessor_clone(Efl_Ui_List_View_Segarray_Eina_Accessor* acc EINA_UNUSED)
{
return &acc->vtable;
}
static void
_efl_ui_list_view_seg_array_accessor_setup(Efl_Ui_List_View_Segarray_Eina_Accessor* acc, Efl_Ui_List_View_Seg_Array* seg_array)
{
EINA_MAGIC_SET(&acc->vtable, EINA_MAGIC_ACCESSOR);
acc->vtable.version = EINA_ACCESSOR_VERSION;
acc->vtable.get_at = FUNC_ACCESSOR_GET_AT(_efl_ui_list_view_seg_array_accessor_get_at);
acc->vtable.get_container = FUNC_ACCESSOR_GET_CONTAINER(_efl_ui_list_view_seg_array_accessor_get_container);
acc->vtable.free = FUNC_ACCESSOR_FREE(_efl_ui_list_view_seg_array_accessor_free);
acc->vtable.lock = FUNC_ACCESSOR_LOCK(_efl_ui_list_view_seg_array_accessor_lock);
acc->vtable.unlock = FUNC_ACCESSOR_LOCK(_efl_ui_list_view_seg_array_accessor_unlock);
acc->vtable.clone = FUNC_ACCESSOR_CLONE(_efl_ui_list_view_seg_array_accessor_clone);
acc->seg_array = seg_array;
}
typedef struct _Efl_Ui_List_View_Segarray_Node_Accessor
{
Eina_Accessor vtable;
Efl_Ui_List_View_Seg_Array* seg_array;
Eina_Iterator* pre_iterator;
Efl_Ui_List_View_Seg_Array_Node* current_node;
int current_index;
} Efl_Ui_List_View_Segarray_Node_Accessor;
static Eina_Bool
_efl_ui_list_view_seg_array_node_accessor_get_at(Efl_Ui_List_View_Segarray_Node_Accessor* acc,
int idx, void** data)
{
if(idx == acc->current_index && acc->current_node)
{
(*data) = acc->current_node;
}
else
{
if(acc->current_index >= idx || !acc->current_node)
{
eina_iterator_free(acc->pre_iterator);
acc->pre_iterator = NULL;
acc->current_node = NULL;
acc->current_index = -1;
}
if(!acc->pre_iterator)
acc->pre_iterator = eina_rbtree_iterator_infix((void*)acc->seg_array->root);
for(;acc->current_index != idx;++acc->current_index)
{
if(!eina_iterator_next(acc->pre_iterator, (void**)&acc->current_node))
{
--acc->current_index;
return EINA_FALSE;
}
}
(*data) = acc->current_node;
return EINA_TRUE;
}
return EINA_FALSE;
}
static void*
_efl_ui_list_view_seg_array_node_accessor_get_container(Efl_Ui_List_View_Segarray_Node_Accessor* acc EINA_UNUSED)
{
return NULL;
}
static void
_efl_ui_list_view_seg_array_node_accessor_free(Efl_Ui_List_View_Segarray_Node_Accessor* acc EINA_UNUSED)
{
if (acc->pre_iterator)
eina_iterator_free(acc->pre_iterator);
free(acc);
}
static Eina_Bool
_efl_ui_list_view_seg_array_node_accessor_lock(Efl_Ui_List_View_Segarray_Node_Accessor* acc EINA_UNUSED)
{
return EINA_FALSE;
}
static Eina_Bool
_efl_ui_list_view_seg_array_node_accessor_unlock(Efl_Ui_List_View_Segarray_Node_Accessor* acc EINA_UNUSED)
{
return EINA_FALSE;
}
static Eina_Accessor*
_efl_ui_list_view_seg_array_node_accessor_clone(Efl_Ui_List_View_Segarray_Node_Accessor* acc EINA_UNUSED)
{
return &acc->vtable;
}
static void
_efl_ui_list_view_seg_array_node_accessor_setup(Efl_Ui_List_View_Segarray_Node_Accessor* acc, Efl_Ui_List_View_Seg_Array* seg_array)
{
EINA_MAGIC_SET(&acc->vtable, EINA_MAGIC_ACCESSOR);
acc->vtable.version = EINA_ACCESSOR_VERSION;
acc->vtable.get_at = FUNC_ACCESSOR_GET_AT(_efl_ui_list_view_seg_array_node_accessor_get_at);
acc->vtable.get_container = FUNC_ACCESSOR_GET_CONTAINER(_efl_ui_list_view_seg_array_node_accessor_get_container);
acc->vtable.free = FUNC_ACCESSOR_FREE(_efl_ui_list_view_seg_array_node_accessor_free);
acc->vtable.lock = FUNC_ACCESSOR_LOCK(_efl_ui_list_view_seg_array_node_accessor_lock);
acc->vtable.unlock = FUNC_ACCESSOR_LOCK(_efl_ui_list_view_seg_array_node_accessor_unlock);
acc->vtable.clone = FUNC_ACCESSOR_CLONE(_efl_ui_list_view_seg_array_node_accessor_clone);
acc->seg_array = seg_array;
acc->pre_iterator = NULL;
acc->current_index = -1;
acc->current_node = NULL;
}
/* External Functions */
Efl_Ui_List_View_Seg_Array *
efl_ui_list_view_seg_array_setup(int size)
{
Efl_Ui_List_View_Seg_Array *pd = calloc(1, sizeof(Efl_Ui_List_View_Seg_Array));
if (!pd) return NULL;
pd->step_size = size;
return pd;
}
void
efl_ui_list_view_seg_array_free(Efl_Ui_List_View_Seg_Array *pd)
{
if (pd->root)
eina_rbtree_delete(EINA_RBTREE_GET(pd->root), EINA_RBTREE_FREE_CB(_free_node), NULL);
pd->root = NULL;
free(pd);
}
void
efl_ui_list_view_seg_array_flush(Efl_Ui_List_View_Seg_Array *pd)
{
if (pd->root)
eina_rbtree_delete(EINA_RBTREE_GET(pd->root), EINA_RBTREE_FREE_CB(_free_node), NULL);
pd->root = NULL;
pd->node_count = 0;
pd->count = 0;
}
int
efl_ui_list_view_seg_array_count(Efl_Ui_List_View_Seg_Array* pd)
{
return pd->count;
}
void
efl_ui_list_view_seg_array_insert(Efl_Ui_List_View_Seg_Array* pd, int index, Efl_Model* model)
{
Efl_Ui_List_View_Seg_Array_Node* node, *next;
Efl_Ui_List_View_Layout_Item* item;
item = _create_item_partial(model);
node = (void*)eina_rbtree_inline_lookup(EINA_RBTREE_GET(pd->root),
&index, sizeof(index), &_insert_lookup_cb, NULL);
if(node)
{
next = (void*)EINA_RBTREE_GET(node)->son[EINA_RBTREE_LEFT];
if(next && next->first <= index)
_efl_ui_list_view_seg_array_insert_at_node(pd, index, item, next);
else
_efl_ui_list_view_seg_array_insert_at_node(pd, index, item, node);
}
else
_efl_ui_list_view_seg_array_insert_at_node(pd, index, item, NULL);
}
void
efl_ui_list_view_seg_array_insert_value(Efl_Ui_List_View_Seg_Array *pd, int first, Eina_Value v)
{
Efl_Model *children;
unsigned int i, len;
if (eina_value_type_get(&v) == EINA_VALUE_TYPE_OBJECT)
{
children = eina_value_object_get(&v);
_efl_ui_list_view_seg_array_insert_object(pd, first, children);
}
else if (eina_value_type_get(&v) == EINA_VALUE_TYPE_ARRAY)
{
EINA_VALUE_ARRAY_FOREACH(&v, len, i, children)
{
unsigned int idx = first + i;
_efl_ui_list_view_seg_array_insert_object(pd, idx, children);
}
}
else
{
printf("Unknow type !\n");
}
}
Efl_Ui_List_View_Layout_Item*
efl_ui_list_view_seg_array_remove(Efl_Ui_List_View_Seg_Array *pd, int index)
{
Efl_Ui_List_View_Seg_Array_Node *node;
Efl_Ui_List_View_Layout_Item *item, *rt;
Eina_Iterator* iterator;
int offset;
node = (void*)eina_rbtree_inline_lookup(EINA_RBTREE_GET(pd->root),
&index, sizeof(index), &_insert_lookup_cb, NULL);
if (!node) return NULL;
offset = index - node->first;
if (offset >= node->length) return NULL;
rt = node->pointers[offset];
pd->count--;
node->length--;
while (offset < node->length)
{
node->pointers[offset] = node->pointers[offset+1];
item = node->pointers[offset];
--item->index_offset;
++offset;
}
node = (void*)EINA_RBTREE_GET(node)->son[EINA_RBTREE_LEFT];
iterator = eina_rbtree_iterator_infix((void*)node);
while(eina_iterator_next(iterator, (void**)&node))
node->first--;
return rt;
}
Eina_Accessor*
efl_ui_list_view_seg_array_accessor_get(Efl_Ui_List_View_Seg_Array* pd)
{
Efl_Ui_List_View_Segarray_Eina_Accessor* acc = calloc(1, sizeof(Efl_Ui_List_View_Segarray_Eina_Accessor));
_efl_ui_list_view_seg_array_accessor_setup(acc, pd);
return &acc->vtable;
}
Eina_Accessor*
efl_ui_list_view_seg_array_node_accessor_get(Efl_Ui_List_View_Seg_Array* pd)
{
Efl_Ui_List_View_Segarray_Node_Accessor* acc = calloc(1, sizeof(Efl_Ui_List_View_Segarray_Node_Accessor));
_efl_ui_list_view_seg_array_node_accessor_setup(acc, pd);
return &acc->vtable;
}
int
efl_ui_list_view_item_index_get(Efl_Ui_List_View_Layout_Item* item)
{
Efl_Ui_List_View_Seg_Array_Node* node = item->tree_node;
return item->index_offset + node->first;
}

View File

@ -1,42 +0,0 @@
#ifndef EFL_UI_LIST_VIEW_SEG_ARRAY_H
#define EFL_UI_LIST_VIEW_SEG_ARRAY_H
typedef struct _Efl_Ui_List_View_SegArray_Node
{
EINA_RBTREE;
int length;
int max;
int first;
void* layout_data;
Efl_Ui_List_View_Layout_Item* pointers[0];
} Efl_Ui_List_View_Seg_Array_Node;
typedef struct _Efl_Ui_List_View_Seg_Array
{
Efl_Ui_List_View_Seg_Array_Node *root;
int step_size;
int node_count;
int count;
} Efl_Ui_List_View_Seg_Array;
Efl_Ui_List_View_Seg_Array * efl_ui_list_view_seg_array_setup(int size);
void efl_ui_list_view_seg_array_free(Efl_Ui_List_View_Seg_Array *seg_array);
void efl_ui_list_view_seg_array_flush(Efl_Ui_List_View_Seg_Array *seg_array);
int efl_ui_list_view_seg_array_count(Efl_Ui_List_View_Seg_Array* seg_array);
int efl_ui_list_view_item_index_get(Efl_Ui_List_View_Layout_Item* item);
void efl_ui_list_view_seg_array_insert(Efl_Ui_List_View_Seg_Array* seg_array, int index, Efl_Model* model);
void efl_ui_list_view_seg_array_insert_value(Efl_Ui_List_View_Seg_Array *seg_array, int first, Eina_Value value);
Efl_Ui_List_View_Layout_Item* efl_ui_list_view_seg_array_remove(Efl_Ui_List_View_Seg_Array *seg_array, int index);
Eina_Accessor* efl_ui_list_view_seg_array_accessor_get(Efl_Ui_List_View_Seg_Array* seg_array);
Eina_Accessor* efl_ui_list_view_seg_array_node_accessor_get(Efl_Ui_List_View_Seg_Array* seg_array);
#endif

View File

@ -1,12 +0,0 @@
struct @beta @free(free) Efl.Ui.List_View_Layout_Item {
layout: Efl.Ui.Layout;
layout_request: future<Efl.Ui.Layout>;
children: Efl.Model;
index_offset: int;
tree_node: void_ptr;
min: Eina.Size2D;
size: Eina.Size2D;
pos: Eina.Position2D;
}
struct @beta Efl_Ui_List_View_Seg_Array; [[TBD]]

View File

@ -111,8 +111,6 @@ pub_eo_files = [
'efl_ui_layout_part_bg.eo',
'efl_ui_layout_part_legacy.eo',
'efl_ui_list_view.eo',
'efl_ui_list_view_model.eo',
'efl_ui_list_view_pan.eo',
'efl_ui_item.eo',
'efl_ui_default_item.eo',
'efl_ui_group_item.eo',
@ -208,7 +206,6 @@ endforeach
pub_eo_types_files = [
'elm_general.eot',
'efl_ui.eot',
'efl_ui_list_view_types.eot',
'efl_ui_selection_types.eot',
'efl_ui_dnd_types.eot'
]
@ -236,8 +233,6 @@ priv_eo_files = [
'efl_ui_state_model.eo',
'efl_ui_selection_manager.eo',
'efl_datetime_manager.eo',
'efl_ui_list_view_precise_layouter.eo',
'efl_ui_list_view_relayout.eo',
'efl_ui_size_model.eo',
'efl_ui_homogeneous_model.eo',
'efl_ui_exact_model.eo',
@ -357,8 +352,6 @@ elementary_headers_unstable = [
'elm_widget_toolbar.h',
'efl_ui_video_private.h',
'efl_ui_item_private.h',
'efl_ui_list_view_private.h',
'efl_ui_list_view_seg_array.h',
'elm_widget_web.h',
'efl_ui_clock.h',
'elm_code.h',
@ -906,8 +899,6 @@ elementary_src = [
'efl_ui_grid_default_item.c',
'efl_ui_grid.c',
'efl_ui_list_view.c',
'efl_ui_list_view_precise_layouter.c',
'efl_ui_list_view_seg_array.c',
'efl_ui_layout_factory.c',
'efl_ui_scroller.c',
'efl_ui_scroll_manager.c',