forked from enlightenment/efl
elementary: migrate Efl.Ui.List_View to use Efl.Ui.Collection_View.
Differential Revision: https://phab.enlightenment.org/D10035
This commit is contained in:
parent
2e1317baed
commit
78b69d45b5
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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"
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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]]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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]]
|
|
@ -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',
|
||||
|
|
Loading…
Reference in New Issue