summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/elementary/themes/edc/efl/list.edc4
-rw-r--r--src/Makefile_Elementary.am15
-rw-r--r--src/examples/elementary.mk6
-rw-r--r--src/examples/elementary/.gitignore1
-rw-r--r--src/examples/elementary/efl_ui_list_view_example_1.c4
-rw-r--r--src/examples/elementary/efl_ui_list_view_example_2.c2
-rw-r--r--src/examples/elementary/efl_ui_list_view_example_3.c16
-rw-r--r--src/examples/elementary/view_tree_example_1.c129
-rw-r--r--src/lib/elementary/Elementary.h9
-rw-r--r--src/lib/elementary/efl_ui_tree_factory.c169
-rw-r--r--src/lib/elementary/efl_ui_tree_factory.eo33
-rw-r--r--src/lib/elementary/efl_ui_tree_view.c1159
-rw-r--r--src/lib/elementary/efl_ui_tree_view.eo96
-rw-r--r--src/lib/elementary/efl_ui_tree_view_layouter.c722
-rw-r--r--src/lib/elementary/efl_ui_tree_view_layouter.eo10
-rw-r--r--src/lib/elementary/efl_ui_tree_view_model.eo70
-rw-r--r--src/lib/elementary/efl_ui_tree_view_pan.eo12
-rw-r--r--src/lib/elementary/efl_ui_tree_view_private.h73
-rw-r--r--src/lib/elementary/efl_ui_tree_view_relayout.eo30
-rw-r--r--src/lib/elementary/efl_ui_tree_view_seg_array.c474
-rw-r--r--src/lib/elementary/efl_ui_tree_view_seg_array.eo63
-rw-r--r--src/lib/elementary/efl_ui_tree_view_seg_array.h38
-rw-r--r--src/lib/elementary/efl_ui_tree_view_seg_array_depth_model.c78
-rw-r--r--src/lib/elementary/efl_ui_tree_view_seg_array_depth_model.eo11
24 files changed, 3211 insertions, 13 deletions
diff --git a/data/elementary/themes/edc/efl/list.edc b/data/elementary/themes/edc/efl/list.edc
index ca3c5b47ff..a551f1c7aa 100644
--- a/data/elementary/themes/edc/efl/list.edc
+++ b/data/elementary/themes/edc/efl/list.edc
@@ -6,6 +6,10 @@ group { "efl/list_view";
6 inherit: "efl/list"; 6 inherit: "efl/list";
7} 7}
8 8
9group { "efl/tree_view";
10 inherit: "efl/list";
11}
12
9group { "efl/list_item"; 13group { "efl/list_item";
10 data.item: "selectraise" "on"; 14 data.item: "selectraise" "on";
11 data.item: "focusraise" "on"; 15 data.item: "focusraise" "on";
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index 0c75466680..ff5d6fbcf3 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -82,6 +82,14 @@ elm_public_eolian_files = \
82 lib/elementary/efl_ui_list_view_pan.eo \ 82 lib/elementary/efl_ui_list_view_pan.eo \
83 lib/elementary/efl_ui_list_view_seg_array.eo \ 83 lib/elementary/efl_ui_list_view_seg_array.eo \
84 lib/elementary/efl_ui_list_view_relayout.eo \ 84 lib/elementary/efl_ui_list_view_relayout.eo \
85 lib/elementary/efl_ui_tree_view.eo \
86 lib/elementary/efl_ui_tree_view_model.eo \
87 lib/elementary/efl_ui_tree_view_pan.eo \
88 lib/elementary/efl_ui_tree_view_seg_array.eo \
89 lib/elementary/efl_ui_tree_view_seg_array_depth_model.eo \
90 lib/elementary/efl_ui_tree_view_relayout.eo \
91 lib/elementary/efl_ui_tree_view_layouter.eo \
92 lib/elementary/efl_ui_tree_factory.eo \
85 lib/elementary/efl_ui_item.eo \ 93 lib/elementary/efl_ui_item.eo \
86 lib/elementary/efl_ui_list_item.eo \ 94 lib/elementary/efl_ui_list_item.eo \
87 lib/elementary/efl_ui_list_default_item_part_icon.eo \ 95 lib/elementary/efl_ui_list_default_item_part_icon.eo \
@@ -425,6 +433,7 @@ includesunstable_HEADERS = \
425 lib/elementary/efl_ui_grid_private.h \ 433 lib/elementary/efl_ui_grid_private.h \
426 lib/elementary/efl_ui_list_view_private.h \ 434 lib/elementary/efl_ui_list_view_private.h \
427 lib/elementary/efl_ui_list_view_seg_array.h \ 435 lib/elementary/efl_ui_list_view_seg_array.h \
436 lib/elementary/efl_ui_tree_view_private.h \
428 lib/elementary/elm_widget_web.h \ 437 lib/elementary/elm_widget_web.h \
429 lib/elementary/efl_ui_clock.h \ 438 lib/elementary/efl_ui_clock.h \
430 lib/elementary/elm_code.h \ 439 lib/elementary/elm_code.h \
@@ -655,6 +664,7 @@ includesub_HEADERS = \
655 lib/elementary/efl_ui_video.h \ 664 lib/elementary/efl_ui_video.h \
656 lib/elementary/efl_ui_video_eo.h \ 665 lib/elementary/efl_ui_video_eo.h \
657 lib/elementary/efl_ui_video_legacy.h \ 666 lib/elementary/efl_ui_video_legacy.h \
667 lib/elementary/efl_ui_tree_view_seg_array.h \
658 lib/elementary/elm_view_list.h \ 668 lib/elementary/elm_view_list.h \
659 lib/elementary/elm_view_form.h \ 669 lib/elementary/elm_view_form.h \
660 lib/elementary/elm_web.h \ 670 lib/elementary/elm_web.h \
@@ -858,6 +868,11 @@ lib_elementary_libelementary_la_SOURCES = \
858 lib/elementary/efl_ui_list_view.c \ 868 lib/elementary/efl_ui_list_view.c \
859 lib/elementary/efl_ui_list_view_precise_layouter.c \ 869 lib/elementary/efl_ui_list_view_precise_layouter.c \
860 lib/elementary/efl_ui_list_view_seg_array.c \ 870 lib/elementary/efl_ui_list_view_seg_array.c \
871 lib/elementary/efl_ui_tree_factory.c \
872 lib/elementary/efl_ui_tree_view.c \
873 lib/elementary/efl_ui_tree_view_layouter.c \
874 lib/elementary/efl_ui_tree_view_seg_array.c \
875 lib/elementary/efl_ui_tree_view_seg_array_depth_model.c \
861 lib/elementary/efl_ui_layout_factory.c \ 876 lib/elementary/efl_ui_layout_factory.c \
862 lib/elementary/efl_ui_scroller.c \ 877 lib/elementary/efl_ui_scroller.c \
863 lib/elementary/efl_ui_scroll_manager.c \ 878 lib/elementary/efl_ui_scroll_manager.c \
diff --git a/src/examples/elementary.mk b/src/examples/elementary.mk
index 0d817258dc..a83795b4bc 100644
--- a/src/examples/elementary.mk
+++ b/src/examples/elementary.mk
@@ -125,7 +125,8 @@ elementary/efl_ui_list_view_example_2.c \
125elementary/efl_ui_list_view_example_3.c \ 125elementary/efl_ui_list_view_example_3.c \
126elementary/efl_canvas_layout_text.c \ 126elementary/efl_canvas_layout_text.c \
127elementary/efl_ui_theme_example_01.c \ 127elementary/efl_ui_theme_example_01.c \
128elementary/efl_ui_theme_example_02.c 128elementary/efl_ui_theme_example_02.c \
129elementary/view_tree_example_1.c
129 130
130ELM_SRCS += \ 131ELM_SRCS += \
131elementary/bg_cxx_example_01.cc \ 132elementary/bg_cxx_example_01.cc \
@@ -344,7 +345,8 @@ elementary/efl_ui_list_view_example_2 \
344elementary/efl_ui_list_view_example_3 \ 345elementary/efl_ui_list_view_example_3 \
345elementary/efl_canvas_layout_text \ 346elementary/efl_canvas_layout_text \
346elementary/efl_ui_theme_example_01 \ 347elementary/efl_ui_theme_example_01 \
347elementary/efl_ui_theme_example_02 348elementary/efl_ui_theme_example_02 \
349elementary/view_tree_example_1
348#benchmark3d 350#benchmark3d
349#sphere-hunter 351#sphere-hunter
350 352
diff --git a/src/examples/elementary/.gitignore b/src/examples/elementary/.gitignore
index 54d71c14a0..213241b859 100644
--- a/src/examples/elementary/.gitignore
+++ b/src/examples/elementary/.gitignore
@@ -63,6 +63,7 @@
63/list_example_02 63/list_example_02
64/list_example_03 64/list_example_03
65/efl_ui_list_example_1 65/efl_ui_list_example_1
66/view_tree_example_1
66/efl_ui_view_list_example_1 67/efl_ui_view_list_example_1
67/efl_ui_view_list_example_2 68/efl_ui_view_list_example_2
68/efl_ui_view_list_example_3 69/efl_ui_view_list_example_3
diff --git a/src/examples/elementary/efl_ui_list_view_example_1.c b/src/examples/elementary/efl_ui_list_view_example_1.c
index dc300264aa..3decb4ae5c 100644
--- a/src/examples/elementary/efl_ui_list_view_example_1.c
+++ b/src/examples/elementary/efl_ui_list_view_example_1.c
@@ -22,7 +22,7 @@ const char *styles[] = {
22char edj_path[PATH_MAX]; 22char edj_path[PATH_MAX];
23 23
24static void 24static void
25_realized_cb(void *data EINA_UNUSED, const Efl_Event *event) 25_realized_cb(void *data, const Efl_Event *event)
26{ 26{
27 Efl_Ui_List_View_Item_Event *ie = event->info; 27 Efl_Ui_List_View_Item_Event *ie = event->info;
28 if (!ie->layout) return; 28 if (!ie->layout) return;
@@ -69,7 +69,7 @@ _make_model(Evas_Object *win)
69} 69}
70 70
71EAPI_MAIN int 71EAPI_MAIN int
72elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) 72elm_main(int argc, char **argv)
73{ 73{
74 Efl_Ui_Factory *factory; 74 Efl_Ui_Factory *factory;
75 Evas_Object *win, *li; 75 Evas_Object *win, *li;
diff --git a/src/examples/elementary/efl_ui_list_view_example_2.c b/src/examples/elementary/efl_ui_list_view_example_2.c
index ca56f37d33..c624cade19 100644
--- a/src/examples/elementary/efl_ui_list_view_example_2.c
+++ b/src/examples/elementary/efl_ui_list_view_example_2.c
@@ -15,7 +15,7 @@
15#define EFL_MODEL_TEST_FILENAME_PATH "/tmp" 15#define EFL_MODEL_TEST_FILENAME_PATH "/tmp"
16 16
17EAPI_MAIN int 17EAPI_MAIN int
18elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) 18elm_main(int argc, char **argv)
19{ 19{
20 Efl_Ui_Layout_Factory *factory; 20 Efl_Ui_Layout_Factory *factory;
21 Efl_Ui_Image_Factory *imgf; 21 Efl_Ui_Image_Factory *imgf;
diff --git a/src/examples/elementary/efl_ui_list_view_example_3.c b/src/examples/elementary/efl_ui_list_view_example_3.c
index eaf5dc975a..46d5ca5813 100644
--- a/src/examples/elementary/efl_ui_list_view_example_3.c
+++ b/src/examples/elementary/efl_ui_list_view_example_3.c
@@ -66,7 +66,7 @@ _focused(void *data, const Efl_Event *event)
66} 66}
67 67
68static void 68static void
69_bt_add_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) 69_bt_add_clicked(void *data, Evas_Object *obj, void *event_info)
70{ 70{
71 Priv_Data *priv = (Priv_Data*)data; 71 Priv_Data *priv = (Priv_Data*)data;
72 Eina_Value vtext, value; 72 Eina_Value vtext, value;
@@ -90,7 +90,7 @@ _bt_add_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_
90} 90}
91 91
92static void 92static void
93_bt_del_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) 93_bt_del_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
94{ 94{
95 Priv_Data *priv = (Priv_Data*)data; 95 Priv_Data *priv = (Priv_Data*)data;
96 Eo *child = NULL; 96 Eo *child = NULL;
@@ -110,35 +110,35 @@ _bt_del_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_
110} 110}
111 111
112static void 112static void
113_bt_none_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) 113_bt_none_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
114{ 114{
115 Evas_Object *li = data; 115 Evas_Object *li = data;
116 efl_ui_list_view_select_mode_set(li, ELM_OBJECT_SELECT_MODE_NONE); 116 efl_ui_list_view_select_mode_set(li, ELM_OBJECT_SELECT_MODE_NONE);
117} 117}
118 118
119static void 119static void
120_bt_donly_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) 120_bt_donly_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
121{ 121{
122 Evas_Object *li = data; 122 Evas_Object *li = data;
123 efl_ui_list_view_select_mode_set(li, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); 123 efl_ui_list_view_select_mode_set(li, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
124} 124}
125 125
126static void 126static void
127_bt_default_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) 127_bt_default_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
128{ 128{
129 Evas_Object *li = data; 129 Evas_Object *li = data;
130 efl_ui_list_view_select_mode_set(li, ELM_OBJECT_SELECT_MODE_DEFAULT); 130 efl_ui_list_view_select_mode_set(li, ELM_OBJECT_SELECT_MODE_DEFAULT);
131} 131}
132 132
133static void 133static void
134_bt_set_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) 134_bt_set_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
135{ 135{
136 Priv_Data *priv = data; 136 Priv_Data *priv = data;
137 efl_ui_view_model_set(priv->list2, priv->model); 137 efl_ui_view_model_set(priv->list2, priv->model);
138} 138}
139 139
140static void 140static void
141_bt_unset_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) 141_bt_unset_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
142{ 142{
143 Evas_Object *li = data; 143 Evas_Object *li = data;
144 efl_ui_view_model_set(li, NULL); 144 efl_ui_view_model_set(li, NULL);
@@ -201,7 +201,7 @@ _make_model()
201} 201}
202 202
203EAPI_MAIN int 203EAPI_MAIN int
204elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) 204elm_main(int argc, char **argv)
205{ 205{
206 Priv_Data *priv; 206 Priv_Data *priv;
207 Evas_Object *win, *bx, *vbx, *bt; 207 Evas_Object *win, *bx, *vbx, *bt;
diff --git a/src/examples/elementary/view_tree_example_1.c b/src/examples/elementary/view_tree_example_1.c
new file mode 100644
index 0000000000..fe39a6d81e
--- /dev/null
+++ b/src/examples/elementary/view_tree_example_1.c
@@ -0,0 +1,129 @@
1// gcc -o tree_view_example_1 tree_view_example_1.c `pkg-config --cflags --libs elementary`
2
3#ifdef HAVE_CONFIG_H
4# include "config.h"
5#else
6# define EFL_BETA_API_SUPPORT 1
7# define EFL_EO_API_SUPPORT 1
8#endif
9
10#include <Elementary.h>
11#include <Efl.h>
12#include <Eio.h>
13#include <stdio.h>
14#include <time.h>
15
16#define NUM_ITEMS 20
17
18static void
19_realized_cb(void *data EINA_UNUSED, const Efl_Event *event)
20{
21 char *depth, *name;
22 Eina_Value *vd, *vn;
23 Efl_Ui_Tree_View_Item_Event *ie = event->info;
24 if (!ie->child) return;
25
26 vd = efl_model_property_get(ie->child, "depth");
27 vn = efl_model_property_get(ie->child, "name");
28 depth = eina_value_to_string(vd);
29 name = eina_value_to_string(vn);
30 eina_value_free(vd);
31 eina_value_free(vn);
32
33 printf("realize item=%s depth=%s\n", name, depth);
34 free(name);
35 free(depth);
36}
37
38static Efl_Model*
39_child_add(Efl_Model_Item *parent, Eina_Value *value, const char *msg)
40{
41 Efl_Model_Item *model;
42
43 model = efl_model_child_add(parent);
44 if (model)
45 {
46 eina_value_set(value, msg);
47 efl_model_property_set(model, "name", value);
48 }
49
50 return model;
51}
52
53static void
54_children_add(Efl_Model_Item *parent, Eina_Value *value, int n, const char *msg)
55{
56 char msgbuf[256];
57 char buff[256];
58 int i;
59
60 if (!parent) return;
61 snprintf(msgbuf, sizeof(msgbuf), " %s - %%i", msg);
62
63 for (i = 0; i < n; ++i)
64 {
65 snprintf(buff, sizeof(buff), msgbuf, i);
66 _children_add(_child_add(parent, value, buff), value, i, buff);
67 }
68}
69
70static Efl_Model*
71_make_model(Evas_Object *win)
72{
73 Efl_Model_Item *root, *child;
74 Eina_Value vtext;
75 unsigned int i;
76
77 srand(time(NULL));
78 eina_value_setup(&vtext, EINA_VALUE_TYPE_STRING);
79 root = efl_add(EFL_MODEL_ITEM_CLASS, win);
80 char buf[256];
81
82 for (i = 0; i < (NUM_ITEMS); ++i)
83 {
84 snprintf(buf, sizeof(buf), "Item # %i", i);
85 child = _child_add(root, &vtext, buf);
86 snprintf(buf, sizeof(buf), "|-> Item # %i", i);
87 _children_add(child, &vtext, 5, buf);
88 }
89
90 eina_value_flush(&vtext);
91 return root;
92}
93
94EAPI_MAIN int
95elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
96{
97 Efl_Ui_Layout_Factory *factory;
98 Evas_Object *win;
99 Eo *model, *tree;
100
101 win = elm_win_util_standard_add("viewtree", "ViewTree");
102 elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
103
104 elm_win_autodel_set(win, EINA_TRUE);
105
106 model = _make_model(win);
107 factory = efl_add(EFL_UI_TREE_FACTORY_CLASS, win,
108 efl_ui_layout_factory_theme_config(efl_added, "list_item", NULL, "default"));
109 efl_ui_model_connect(factory, "efl.text", "name");
110
111 tree = efl_add(EFL_UI_TREE_VIEW_CLASS, win);
112 efl_ui_tree_view_layout_factory_set(tree, factory);
113 efl_ui_view_model_set(tree, model);
114
115 evas_object_size_hint_weight_set(tree, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
116 evas_object_size_hint_align_set(tree, EVAS_HINT_FILL, EVAS_HINT_FILL);
117 efl_event_callback_add(tree, EFL_UI_TREE_VIEW_EVENT_ITEM_REALIZED, _realized_cb, NULL);
118
119 elm_win_resize_object_add(win, tree);
120
121 //showall
122 evas_object_show(tree);
123 evas_object_resize(win, 320, 320);
124 evas_object_show(win);
125
126 elm_run();
127 return 0;
128}
129ELM_MAIN()
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index 9bd33c4feb..a6e5f50ce3 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -327,6 +327,7 @@ typedef Eo Efl_Ui_Focus_Manager;
327# include <efl_ui_slider.eo.h> 327# include <efl_ui_slider.eo.h>
328# include <efl_ui_slider_interval.eo.h> 328# include <efl_ui_slider_interval.eo.h>
329# include <efl_ui_layout_factory.eo.h> 329# include <efl_ui_layout_factory.eo.h>
330# include <efl_ui_tree_factory.eo.h>
330# include <efl_ui_item.eo.h> 331# include <efl_ui_item.eo.h>
331# include <efl_ui_list_item.eo.h> 332# include <efl_ui_list_item.eo.h>
332# include <efl_ui_list_default_item_part_icon.eo.h> 333# include <efl_ui_list_default_item_part_icon.eo.h>
@@ -346,6 +347,14 @@ typedef Eo Efl_Ui_Focus_Manager;
346# include <efl_ui_list_view_relayout.eo.h> 347# include <efl_ui_list_view_relayout.eo.h>
347# include <efl_ui_list_view.eo.h> 348# include <efl_ui_list_view.eo.h>
348# include <efl_ui_list_view_pan.eo.h> 349# include <efl_ui_list_view_pan.eo.h>
350# include <efl_ui_tree_view_seg_array.h>
351# include <efl_ui_tree_view_seg_array.eo.h>
352# include <efl_ui_tree_view_seg_array_depth_model.eo.h>
353# include <efl_ui_tree_view_model.eo.h>
354# include <efl_ui_tree_view_relayout.eo.h>
355# include <efl_ui_tree_view_layouter.eo.h>
356# include <efl_ui_tree_view.eo.h>
357# include <efl_ui_tree_view_pan.eo.h>
349# include <efl_ui_pan.eo.h> 358# include <efl_ui_pan.eo.h>
350# include <efl_ui_scroll_manager.eo.h> 359# include <efl_ui_scroll_manager.eo.h>
351# include <efl_ui_scroller.eo.h> 360# include <efl_ui_scroller.eo.h>
diff --git a/src/lib/elementary/efl_ui_tree_factory.c b/src/lib/elementary/efl_ui_tree_factory.c
new file mode 100644
index 0000000000..3ab9cb78c8
--- /dev/null
+++ b/src/lib/elementary/efl_ui_tree_factory.c
@@ -0,0 +1,169 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#include <Elementary.h>
6#include "elm_priv.h"
7
8#define MY_CLASS EFL_UI_TREE_FACTORY_CLASS
9#define MY_CLASS_NAME "Efl.Ui.Tree_Factory"
10
11typedef struct _Efl_Ui_Tree_Factory_Data
12{
13 Eina_Hash *connects;
14 Eina_Hash *factory_connects;
15 Eina_Stringshare *klass;
16 Eina_Stringshare *group;
17 Eina_Stringshare *def_style;
18 Eina_Stringshare *exp_style;
19} Efl_Ui_Tree_Factory_Data;
20
21static Eina_Bool
22_model_connect(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data, void *fdata)
23{
24 Eo *layout = fdata;
25 Eina_Stringshare *name = key;
26 Eina_Stringshare *property = data;
27
28 efl_ui_model_connect(layout, name, property);
29 return EINA_TRUE;
30}
31
32static Eina_Bool
33_factory_model_connect(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data, void *fdata)
34{
35 Eo *layout = fdata;
36 Eina_Stringshare *name = key;
37 Efl_Ui_Factory *factory = data;
38
39 efl_ui_factory_model_connect(layout, name, factory);
40 return EINA_TRUE;
41}
42
43EOLIAN static Eo *
44_efl_ui_tree_factory_efl_object_constructor(Eo *obj, Efl_Ui_Tree_Factory_Data *pd)
45{
46 obj = efl_constructor(efl_super(obj, MY_CLASS));
47
48 pd->connects = eina_hash_stringshared_new(EINA_FREE_CB(eina_stringshare_del));
49 pd->factory_connects = eina_hash_stringshared_new(EINA_FREE_CB(efl_unref));
50
51 return obj;
52}
53
54EOLIAN static void
55_efl_ui_tree_factory_efl_object_destructor(Eo *obj, Efl_Ui_Tree_Factory_Data *pd)
56{
57 eina_stringshare_del(pd->klass);
58 eina_stringshare_del(pd->group);
59 eina_stringshare_del(pd->def_style);
60 eina_stringshare_del(pd->exp_style);
61
62 eina_hash_free(pd->connects);
63 eina_hash_free(pd->factory_connects);
64
65 efl_destructor(efl_super(obj, MY_CLASS));
66}
67
68EOLIAN static Eina_Future *
69_efl_ui_tree_factory_efl_ui_factory_create(Eo *obj, Efl_Ui_Tree_Factory_Data *pd
70 , Efl_Model *model, Efl_Gfx_Entity *parent)
71{
72 Eina_Value r;
73 Efl_Gfx_Entity *layout;
74 Efl_Ui_Tree_Factory_Item_Event evt;
75 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
76
77 Eina_Stringshare *style = pd->def_style;
78 evt.model = model;
79 evt.expandable = EINA_FALSE;
80 efl_event_callback_call(obj, EFL_UI_TREE_FACTORY_EVENT_ITEM_CREATE, &evt);
81
82 if (pd->exp_style && (evt.expandable || efl_model_children_count_get(model)))
83 style = pd->exp_style;
84
85 layout = efl_add(EFL_UI_LAYOUT_CLASS, parent,
86 efl_ui_view_model_set(efl_added, model),
87 efl_ui_layout_theme_set(efl_added, pd->klass, pd->group, style));
88
89 eina_hash_foreach(pd->connects, _model_connect, layout);
90 eina_hash_foreach(pd->factory_connects, _factory_model_connect, layout);
91
92 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, 0);
93 evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
94
95 r = eina_value_object_init(layout);
96
97 return eina_future_resolved(efl_loop_future_scheduler_get(obj), r);
98}
99
100EOLIAN static void
101_efl_ui_tree_factory_efl_ui_factory_release(Eo *obj EINA_UNUSED, Efl_Ui_Tree_Factory_Data *pd EINA_UNUSED, Efl_Gfx_Entity *layout)
102{
103 efl_ui_view_model_set(layout, NULL);
104 efl_del(layout);
105}
106
107EOLIAN static void
108_efl_ui_tree_factory_efl_ui_factory_model_connect(Eo *obj EINA_UNUSED, Efl_Ui_Tree_Factory_Data *pd
109 , const char *name, Efl_Ui_Factory *factory)
110{
111 Eina_Stringshare *ss_name;
112 Efl_Ui_Factory *f_old;
113 ss_name = eina_stringshare_add(name);
114
115 if (factory == NULL)
116 {
117 eina_hash_del(pd->factory_connects, ss_name, NULL);
118 eina_stringshare_del(ss_name);
119 return;
120 }
121
122 f_old = eina_hash_set(pd->factory_connects, ss_name, efl_ref(factory));
123 if (f_old)
124 {
125 efl_unref(f_old);
126 eina_stringshare_del(ss_name);
127 }
128}
129
130EOLIAN static void
131_efl_ui_tree_factory_efl_ui_model_connect_connect(Eo *obj EINA_UNUSED, Efl_Ui_Tree_Factory_Data *pd
132 , const char *name, const char *property)
133{
134 Eina_Stringshare *ss_name, *ss_prop, *ss_old;
135 ss_name = eina_stringshare_add(name);
136
137 if (property == NULL)
138 {
139 eina_hash_del(pd->connects, ss_name, NULL);
140 eina_stringshare_del(ss_name);
141 return;
142 }
143
144 ss_prop = eina_stringshare_add(property);
145 ss_old = eina_hash_set(pd->connects, ss_name, ss_prop);
146 if (ss_old)
147 {
148 eina_stringshare_del(ss_old);
149 eina_stringshare_del(ss_name);
150 }
151}
152
153
154EOLIAN static void
155_efl_ui_tree_factory_efl_ui_layout_factory_theme_config(Eo *obj EINA_UNUSED, Efl_Ui_Tree_Factory_Data *pd
156 , const char *klass, const char *group, const char *style)
157{
158 eina_stringshare_replace(&pd->klass, klass);
159 eina_stringshare_replace(&pd->group, group);
160 eina_stringshare_replace(&pd->def_style, style);
161}
162
163EOLIAN static void
164_efl_ui_tree_factory_expandable_style_set(Eo *obj EINA_UNUSED, Efl_Ui_Tree_Factory_Data *pd, const char *style)
165{
166 eina_stringshare_replace(&pd->exp_style, style);
167}
168
169#include "efl_ui_tree_factory.eo.c"
diff --git a/src/lib/elementary/efl_ui_tree_factory.eo b/src/lib/elementary/efl_ui_tree_factory.eo
new file mode 100644
index 0000000000..9bb9a38fb8
--- /dev/null
+++ b/src/lib/elementary/efl_ui_tree_factory.eo
@@ -0,0 +1,33 @@
1import elm_general;
2
3struct Efl.Ui.Tree_Factory_Item_Event
4{
5 model: Efl.Model;
6 expandable: bool;
7}
8
9class Efl.Ui.Tree_Factory (Efl.Ui.Layout_Factory)
10{
11 [[Efl Ui Tree Factory class]]
12 methods {
13 @property expandable_style {
14 [[Style used to expandable itens]]
15 set {}
16 values {
17 style: string; [[The style to use.]]
18 }
19 }
20 }
21 events {
22 item,create : Efl.Ui.Tree_Factory_Item_Event;
23 }
24 implements {
25 Efl.Object.constructor;
26 Efl.Object.destructor;
27 Efl.Ui.Factory.create;
28 Efl.Ui.Factory.release;
29 Efl.Ui.Factory.model_connect;
30 Efl.Ui.Model.Connect.connect;
31 Efl.Ui.Layout_Factory.theme_config;
32 }
33}
diff --git a/src/lib/elementary/efl_ui_tree_view.c b/src/lib/elementary/efl_ui_tree_view.c
new file mode 100644
index 0000000000..ea66461cb4
--- /dev/null
+++ b/src/lib/elementary/efl_ui_tree_view.c
@@ -0,0 +1,1159 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4#define EFL_ACCESS_OBJECT_PROTECTED
5#define EFL_ACCESS_SELECTION_PROTECTED
6#define EFL_UI_SCROLL_MANAGER_PROTECTED
7#define EFL_UI_SCROLLBAR_PROTECTED
8#define EFL_UI_SCROLLBAR_BETA
9#define EFL_UI_FOCUS_COMPOSITION_PROTECTED
10#define EFL_UI_WIDGET_FOCUS_MANAGER_PROTECTED
11
12#include <Elementary.h>
13#include "elm_priv.h"
14#include "efl_ui_tree_view_private.h"
15
16#define MY_CLASS EFL_UI_TREE_VIEW_CLASS
17#define MY_CLASS_NAME "Efl.Ui.Tree_View"
18
19#define MY_PAN_CLASS EFL_UI_TREE_VIEW_PAN_CLASS
20
21#define SELECTED_PROP "selected"
22
23static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
24static Eina_Bool _key_action_select(Evas_Object *obj, const char *params);
25static Eina_Bool _key_action_escape(Evas_Object *obj, const char *params);
26
27static const Elm_Action key_actions[] = {
28 {"move", _key_action_move},
29 {"select", _key_action_select},
30 {"escape", _key_action_escape},
31 {NULL, NULL}
32};
33
34typedef struct _Tree_View_Slice_Callback_Data
35{
36 Efl_Ui_Tree_View_Data *private;
37 Efl_Ui_Tree_View_Item *parent_item;
38 Eina_Future *future;
39 int first;
40} Tree_View_Slice_Callback_Data;
41
42static Eina_Bool
43_key_action_move(Evas_Object *obj EINA_UNUSED, const char *params EINA_UNUSED)
44{
45 return EINA_FALSE;
46}
47
48static Eina_Bool
49_key_action_select(Evas_Object *obj, const char *params EINA_UNUSED)
50{
51 Efl_Ui_Focus_Object *focused = efl_ui_focus_manager_focus_get(obj);
52
53 if (!focused) return EINA_FALSE;
54
55//TODO expanded actions
56 return EINA_FALSE;
57}
58
59static Eina_Bool
60_key_action_escape(Evas_Object *obj, const char *params EINA_UNUSED)
61{
62 efl_ui_focus_manager_reset_history(obj);
63 return EINA_TRUE;
64}
65
66void _efl_ui_tree_view_item_select_set(Efl_Ui_Tree_View_Item*, Eina_Bool);
67static void _layout(Efl_Ui_Tree_View_Data* pd);
68
69EOLIAN static void
70_efl_ui_tree_view_pan_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Pan_Data *psd)
71{
72 evas_object_smart_changed(psd->wobj);
73}
74
75EOLIAN static void
76_efl_ui_tree_view_pan_efl_ui_pan_pan_position_set(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Pan_Data *psd, Eina_Position2D pos)
77{
78 if ((pos.x == psd->gmt.x) && (pos.y == psd->gmt.y)) return;
79
80 psd->gmt.x = pos.x;
81 psd->gmt.y = pos.y;
82
83 efl_event_callback_call(obj, EFL_UI_PAN_EVENT_POSITION_CHANGED, NULL);
84 evas_object_smart_changed(psd->wobj);
85}
86
87EOLIAN static Eina_Position2D
88_efl_ui_tree_view_pan_efl_ui_pan_pan_position_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Pan_Data *psd)
89{
90 return psd->gmt.pos;
91}
92
93EOLIAN static Eina_Position2D
94_efl_ui_tree_view_pan_efl_ui_pan_pan_position_max_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Pan_Data *psd)
95{
96 EFL_UI_TREE_VIEW_DATA_GET(psd->wobj, pd);
97 Eina_Rect vgmt = {};
98 Eina_Size2D min = {};
99
100 vgmt = efl_ui_scrollable_viewport_geometry_get(pd->scrl_mgr);
101 min = efl_ui_tree_view_model_min_size_get(psd->wobj);
102
103 min.w = min.w - vgmt.w;
104 if (min.w < 0) min.w = 0;
105 min.h = min.h - vgmt.h;
106 if (min.h < 0) min.h = 0;
107
108 return EINA_POSITION2D(min.w, min.h);
109}
110
111EOLIAN static Eina_Position2D
112_efl_ui_tree_view_pan_efl_ui_pan_pan_position_min_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Pan_Data *psd EINA_UNUSED)
113{
114 return EINA_POSITION2D(0, 0);
115}
116
117EOLIAN static Eina_Size2D
118_efl_ui_tree_view_pan_efl_ui_pan_content_size_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Pan_Data *psd)
119{
120 return efl_ui_tree_view_model_min_size_get(psd->wobj);
121}
122
123EOLIAN static void
124_efl_ui_tree_view_pan_efl_object_destructor(Eo *obj, Efl_Ui_Tree_View_Pan_Data *psd EINA_UNUSED)
125{
126 efl_destructor(efl_super(obj, MY_PAN_CLASS));
127}
128
129#include "efl_ui_tree_view_pan.eo.c"
130
131EOLIAN static void
132_efl_ui_tree_view_efl_ui_scrollable_interactive_content_pos_set(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *psd, Eina_Position2D pos)
133{
134 efl_ui_scrollable_content_pos_set(psd->scrl_mgr, pos);
135}
136
137EOLIAN static Eina_Position2D
138_efl_ui_tree_view_efl_ui_scrollable_interactive_content_pos_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *psd)
139{
140 return efl_ui_scrollable_content_pos_get(psd->scrl_mgr);
141}
142
143EOLIAN static Eina_Size2D
144_efl_ui_tree_view_efl_ui_scrollable_interactive_content_size_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *psd)
145{
146 return efl_ui_scrollable_content_size_get(psd->scrl_mgr);
147}
148
149EOLIAN static Eina_Rect
150_efl_ui_tree_view_efl_ui_scrollable_interactive_viewport_geometry_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *psd)
151{
152 return efl_ui_scrollable_viewport_geometry_get(psd->scrl_mgr);
153}
154
155EOLIAN static void
156_efl_ui_tree_view_efl_ui_scrollable_interactive_scroll(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *psd, Eina_Rect rect, Eina_Bool animation)
157{
158 efl_ui_scrollable_scroll(psd->scrl_mgr, rect, animation);
159}
160
161static Eina_Bool
162_efl_model_properties_has(Efl_Model *model, Eina_Stringshare *propfind)
163{
164 Eina_Iterator *properties;
165 const char *property;
166 Eina_Bool ret = EINA_FALSE;
167
168 EINA_SAFETY_ON_NULL_RETURN_VAL(model, EINA_FALSE);
169 EINA_SAFETY_ON_NULL_RETURN_VAL(propfind, EINA_FALSE);
170
171 properties = efl_model_properties_get(model);
172
173 EINA_ITERATOR_FOREACH(properties, property)
174 {
175 if (property == propfind ||
176 !strcmp(property, propfind))
177 {
178 ret = EINA_TRUE;
179 break;
180 }
181 }
182 eina_iterator_free(properties);
183
184 return ret;
185}
186
187static void
188_list_element_focused(void *data EINA_UNUSED, const Efl_Event *ev)
189{
190 Eina_Rect geom;
191 Eina_Position2D pos;
192 Efl_Ui_Focus_Object *focused = efl_ui_focus_manager_focus_get(ev->object);
193
194 if (!focused) return;
195
196 EFL_UI_TREE_VIEW_DATA_GET(ev->object, pd);
197 geom = efl_ui_focus_object_focus_geometry_get(focused);
198 pos = efl_ui_scrollable_content_pos_get(pd->scrl_mgr);
199
200 geom.x += pos.x;
201 geom.y += pos.y;
202 efl_ui_scrollable_scroll(ev->object, geom, EINA_TRUE);
203}
204
205static void
206_on_item_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info)
207{
208 Evas_Event_Mouse_Down *ev = event_info;
209 Efl_Ui_Tree_View_Item *item = data;
210
211 if (ev->button != 1) return;
212 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
213
214 _efl_ui_tree_view_item_select_set(item, EINA_TRUE);
215}
216
217EOLIAN static void
218_efl_ui_tree_view_efl_gfx_entity_position_set(Eo *obj, Efl_Ui_Tree_View_Data *pd, Eina_Position2D pos)
219{
220 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_MOVE, 0, pos.x, pos.y))
221 return;
222
223 efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
224 evas_object_smart_changed(pd->obj);
225}
226
227EOLIAN static void
228_efl_ui_tree_view_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_Tree_View_Data *pd, Eina_Size2D size)
229{
230 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_RESIZE, 0, size.w, size.h))
231 return;
232
233 efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), size);
234
235 evas_object_smart_changed(pd->obj);
236}
237
238EOLIAN static void
239_efl_ui_tree_view_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *pd)
240{
241 _layout(pd);
242}
243
244EOLIAN static void
245_efl_ui_tree_view_efl_canvas_group_group_member_add(Eo *obj, Efl_Ui_Tree_View_Data *pd EINA_UNUSED, Evas_Object *member)
246{
247 efl_canvas_group_member_add(efl_super(obj, MY_CLASS), member);
248}
249
250//Scrollable Implement
251static void
252_efl_ui_tree_view_bar_read_and_update(Eo *obj)
253{
254 EFL_UI_TREE_VIEW_DATA_GET(obj, pd);
255 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
256 double vx, vy;
257
258 edje_object_part_drag_value_get
259 (wd->resize_obj, "efl.dragable.vbar", NULL, &vy);
260 edje_object_part_drag_value_get
261 (wd->resize_obj, "efl.dragable.hbar", &vx, NULL);
262
263 efl_ui_scrollbar_bar_position_set(pd->scrl_mgr, vx, vy);
264
265 efl_canvas_group_change(pd->pan_obj);
266}
267
268static void
269_efl_ui_tree_view_reload_cb(void *data,
270 Evas_Object *obj EINA_UNUSED,
271 const char *emission EINA_UNUSED,
272 const char *source EINA_UNUSED)
273{
274 EFL_UI_TREE_VIEW_DATA_GET(data, pd);
275
276 efl_ui_scrollbar_bar_visibility_update(pd->scrl_mgr);
277}
278
279static void
280_efl_ui_tree_view_vbar_drag_cb(void *data,
281 Evas_Object *obj EINA_UNUSED,
282 const char *emission EINA_UNUSED,
283 const char *source EINA_UNUSED)
284{
285 _efl_ui_tree_view_bar_read_and_update(data);
286
287 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
288 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_DRAG, &type);
289}
290
291static void
292_efl_ui_tree_view_vbar_press_cb(void *data,
293 Evas_Object *obj EINA_UNUSED,
294 const char *emission EINA_UNUSED,
295 const char *source EINA_UNUSED)
296{
297 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
298 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_PRESS, &type);
299}
300
301static void
302_efl_ui_tree_view_vbar_unpress_cb(void *data,
303 Evas_Object *obj EINA_UNUSED,
304 const char *emission EINA_UNUSED,
305 const char *source EINA_UNUSED)
306{
307 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
308 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_UNPRESS, &type);
309}
310
311static void
312_efl_ui_tree_view_edje_drag_start_cb(void *data,
313 Evas_Object *obj EINA_UNUSED,
314 const char *emission EINA_UNUSED,
315 const char *source EINA_UNUSED)
316{
317 EFL_UI_TREE_VIEW_DATA_GET(data, pd);
318
319 _efl_ui_tree_view_bar_read_and_update(data);
320
321 pd->scrl_freeze = efl_ui_scrollable_scroll_freeze_get(pd->scrl_mgr);
322 efl_ui_scrollable_scroll_freeze_set(pd->scrl_mgr, EINA_TRUE);
323 efl_event_callback_call(data, EFL_UI_EVENT_SCROLL_DRAG_START, NULL);
324}
325
326static void
327_efl_ui_tree_view_edje_drag_stop_cb(void *data,
328 Evas_Object *obj EINA_UNUSED,
329 const char *emission EINA_UNUSED,
330 const char *source EINA_UNUSED)
331{
332 EFL_UI_TREE_VIEW_DATA_GET(data, pd);
333
334 _efl_ui_tree_view_bar_read_and_update(data);
335
336 efl_ui_scrollable_scroll_freeze_set(pd->scrl_mgr, pd->scrl_freeze);
337 efl_event_callback_call(data, EFL_UI_EVENT_SCROLL_DRAG_STOP, NULL);
338}
339
340static void
341_efl_ui_tree_view_edje_drag_cb(void *data,
342 Evas_Object *obj EINA_UNUSED,
343 const char *emission EINA_UNUSED,
344 const char *source EINA_UNUSED)
345{
346 _efl_ui_tree_view_bar_read_and_update(data);
347}
348
349static void
350_efl_ui_tree_view_hbar_drag_cb(void *data,
351 Evas_Object *obj EINA_UNUSED,
352 const char *emission EINA_UNUSED,
353 const char *source EINA_UNUSED)
354{
355 _efl_ui_tree_view_bar_read_and_update(data);
356
357 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
358 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_DRAG, &type);
359}
360
361static void
362_efl_ui_tree_view_hbar_press_cb(void *data,
363 Evas_Object *obj EINA_UNUSED,
364 const char *emission EINA_UNUSED,
365 const char *source EINA_UNUSED)
366{
367 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
368 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_PRESS, &type);
369}
370
371static void
372_efl_ui_tree_view_hbar_unpress_cb(void *data,
373 Evas_Object *obj EINA_UNUSED,
374 const char *emission EINA_UNUSED,
375 const char *source EINA_UNUSED)
376{
377 Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
378 efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_UNPRESS, &type);
379}
380
381EOLIAN static void
382_efl_ui_tree_view_efl_ui_scrollbar_bar_mode_set(Eo *obj EINA_UNUSED,
383 Efl_Ui_Tree_View_Data *pd,
384 Efl_Ui_Scrollbar_Mode hmode,
385 Efl_Ui_Scrollbar_Mode vmode)
386{
387 efl_ui_scrollbar_bar_mode_set(pd->scrl_mgr, hmode, vmode);
388}
389
390EOLIAN static void
391_efl_ui_tree_view_efl_ui_scrollbar_bar_mode_get(Eo const *obj EINA_UNUSED,
392 Efl_Ui_Tree_View_Data *pd,
393 Efl_Ui_Scrollbar_Mode *hmode,
394 Efl_Ui_Scrollbar_Mode *vmode)
395{
396 efl_ui_scrollbar_bar_mode_get(pd->scrl_mgr, hmode, vmode);
397}
398
399static void
400_efl_ui_tree_view_bar_size_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
401{
402 Eo *obj = data;
403 EFL_UI_TREE_VIEW_DATA_GET(obj, pd);
404 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
405
406 double width = 0.0, height = 0.0;
407
408 efl_ui_scrollbar_bar_size_get(pd->scrl_mgr, &width, &height);
409
410 edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.hbar", width, 1.0);
411 edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.vbar", 1.0, height);
412}
413
414static void
415_efl_ui_tree_view_bar_pos_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
416{
417 Eo *obj = data;
418 EFL_UI_TREE_VIEW_DATA_GET(obj, pd);
419 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
420
421 double posx = 0.0, posy = 0.0;
422
423 efl_ui_scrollbar_bar_position_get(pd->scrl_mgr, &posx, &posy);
424
425 edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.hbar", posx, 0.0);
426 edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.vbar", 0.0, posy);
427}
428
429static void
430_efl_ui_tree_view_bar_show_cb(void *data, const Efl_Event *event)
431{
432 Eo *obj = data;
433 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
434 Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info);
435
436 if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL)
437 edje_object_signal_emit(wd->resize_obj, "efl,action,show,hbar", "efl");
438 else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL)
439 edje_object_signal_emit(wd->resize_obj, "efl,action,show,vbar", "efl");
440}
441
442static void
443_efl_ui_tree_view_bar_hide_cb(void *data, const Efl_Event *event)
444{
445 Eo *obj = data;
446 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
447 Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info);
448
449 if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL)
450 edje_object_signal_emit(wd->resize_obj, "efl,action,hide,hbar", "efl");
451 else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL)
452 edje_object_signal_emit(wd->resize_obj, "efl,action,hide,vbar", "efl");
453}
454
455EOLIAN static Eina_Bool
456_efl_ui_tree_view_efl_layout_signal_signal_callback_add(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *sd EINA_UNUSED,
457 const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data)
458{
459 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
460 return efl_layout_signal_callback_add(wd->resize_obj, emission, source, func_cb, data);
461}
462
463EOLIAN static Eina_Bool
464_efl_ui_tree_view_efl_layout_signal_signal_callback_del(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *sd EINA_UNUSED,
465 const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data)
466{
467 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
468 return efl_layout_signal_callback_del(wd->resize_obj, emission, source, func_cb, data);
469}
470
471static void
472_efl_ui_tree_view_edje_object_attach(Eo *obj)
473{
474 efl_layout_signal_callback_add
475 (obj, "reload", "efl",
476 _efl_ui_tree_view_reload_cb, obj);
477 //Vertical bar
478 efl_layout_signal_callback_add
479 (obj, "drag", "efl.dragable.vbar",
480 _efl_ui_tree_view_vbar_drag_cb, obj);
481 efl_layout_signal_callback_add
482 (obj, "drag,set", "efl.dragable.vbar",
483 _efl_ui_tree_view_edje_drag_cb, obj);
484 efl_layout_signal_callback_add
485 (obj, "drag,start", "efl.dragable.vbar",
486 _efl_ui_tree_view_edje_drag_start_cb, obj);
487 efl_layout_signal_callback_add
488 (obj, "drag,stop", "efl.dragable.vbar",
489 _efl_ui_tree_view_edje_drag_stop_cb, obj);
490 efl_layout_signal_callback_add
491 (obj, "drag,step", "efl.dragable.vbar",
492 _efl_ui_tree_view_edje_drag_cb, obj);
493 efl_layout_signal_callback_add
494 (obj, "drag,page", "efl.dragable.vbar",
495 _efl_ui_tree_view_edje_drag_cb, obj);
496 efl_layout_signal_callback_add
497 (obj, "efl,vbar,press", "efl",
498 _efl_ui_tree_view_vbar_press_cb, obj);
499 efl_layout_signal_callback_add
500 (obj, "efl,vbar,unpress", "efl",
501 _efl_ui_tree_view_vbar_unpress_cb, obj);
502
503 //Horizontal bar
504 efl_layout_signal_callback_add
505 (obj, "drag", "efl.dragable.hbar",
506 _efl_ui_tree_view_hbar_drag_cb, obj);
507 efl_layout_signal_callback_add
508 (obj, "drag,set", "efl.dragable.hbar",
509 _efl_ui_tree_view_edje_drag_cb, obj);
510 efl_layout_signal_callback_add
511 (obj, "drag,start", "efl.dragable.hbar",
512 _efl_ui_tree_view_edje_drag_start_cb, obj);
513 efl_layout_signal_callback_add
514 (obj, "drag,stop", "efl.dragable.hbar",
515 _efl_ui_tree_view_edje_drag_stop_cb, obj);
516 efl_layout_signal_callback_add
517 (obj, "drag,step", "efl.dragable.hbar",
518 _efl_ui_tree_view_edje_drag_cb, obj);
519 efl_layout_signal_callback_add
520 (obj, "drag,page", "efl.dragable.hbar",
521 _efl_ui_tree_view_edje_drag_cb, obj);
522 efl_layout_signal_callback_add
523 (obj, "efl,hbar,press", "efl",
524 _efl_ui_tree_view_hbar_press_cb, obj);
525 efl_layout_signal_callback_add
526 (obj, "efl,hbar,unpress", "efl",
527 _efl_ui_tree_view_hbar_unpress_cb, obj);
528}
529
530static void
531_efl_ui_tree_view_edje_object_detach(Evas_Object *obj)
532{
533 efl_layout_signal_callback_del
534 (obj, "reload", "efl", _efl_ui_tree_view_reload_cb, obj);
535 //Vertical bar
536 efl_layout_signal_callback_del
537 (obj, "drag", "efl.dragable.vbar",
538 _efl_ui_tree_view_vbar_drag_cb, obj);
539 efl_layout_signal_callback_del
540 (obj, "drag,set", "efl.dragable.vbar",
541 _efl_ui_tree_view_edje_drag_cb, obj);
542 efl_layout_signal_callback_del
543 (obj, "drag,start", "efl.dragable.vbar",
544 _efl_ui_tree_view_edje_drag_start_cb, obj);
545 efl_layout_signal_callback_del
546 (obj, "drag,stop", "efl.dragable.vbar",
547 _efl_ui_tree_view_edje_drag_stop_cb, obj);
548 efl_layout_signal_callback_del
549 (obj, "drag,step", "efl.dragable.vbar",
550 _efl_ui_tree_view_edje_drag_cb, obj);
551 efl_layout_signal_callback_del
552 (obj, "drag,page", "efl.dragable.vbar",
553 _efl_ui_tree_view_edje_drag_cb, obj);
554 efl_layout_signal_callback_del
555 (obj, "efl,vbar,press", "efl",
556 _efl_ui_tree_view_vbar_press_cb, obj);
557 efl_layout_signal_callback_del
558 (obj, "efl,vbar,unpress", "efl",
559 _efl_ui_tree_view_vbar_unpress_cb, obj);
560
561 //Horizontal bar
562 efl_layout_signal_callback_del
563 (obj, "drag", "efl.dragable.hbar",
564 _efl_ui_tree_view_hbar_drag_cb, obj);
565 efl_layout_signal_callback_del
566 (obj, "drag,set", "efl.dragable.hbar",
567 _efl_ui_tree_view_edje_drag_cb, obj);
568 efl_layout_signal_callback_del
569 (obj, "drag,start", "efl.dragable.hbar",
570 _efl_ui_tree_view_edje_drag_start_cb, obj);
571 efl_layout_signal_callback_del
572 (obj, "drag,stop", "efl.dragable.hbar",
573 _efl_ui_tree_view_edje_drag_stop_cb, obj);
574 efl_layout_signal_callback_del
575 (obj, "drag,step", "efl.dragable.hbar",
576 _efl_ui_tree_view_edje_drag_cb, obj);
577 efl_layout_signal_callback_del
578 (obj, "drag,page", "efl.dragable.hbar",
579 _efl_ui_tree_view_edje_drag_cb, obj);
580 efl_layout_signal_callback_del
581 (obj, "efl,hbar,press", "efl",
582 _efl_ui_tree_view_hbar_press_cb, obj);
583 efl_layout_signal_callback_del
584 (obj, "efl,hbar,unpress", "efl",
585 _efl_ui_tree_view_hbar_unpress_cb, obj);
586}
587
588EOLIAN static void
589_efl_ui_tree_view_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Tree_View_Data *pd)
590{
591 Efl_Ui_Tree_View_Pan_Data *pan_data;
592 Eina_Size2D min = {};
593 Eina_Bool bounce = _elm_config->thumbscroll_bounce_enable;
594 Evas_Object *o;
595
596 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
597
598 efl_canvas_group_add(efl_super(obj, MY_CLASS));
599 elm_widget_sub_object_parent_add(obj);
600
601 elm_widget_can_focus_set(obj, EINA_TRUE);
602
603 if (!elm_layout_theme_set(obj, "tree_view", "base", elm_widget_style_get(obj)))
604 CRI("Failed to set layout!");
605
606 pd->pan_obj = efl_add(MY_PAN_CLASS, obj);
607 pd->scrl_mgr = efl_add(EFL_UI_SCROLL_MANAGER_CLASS, obj,
608 efl_ui_mirrored_set(efl_added, efl_ui_mirrored_get(obj)),
609 efl_ui_scroll_manager_pan_set(efl_added, pd->pan_obj));
610 pan_data = efl_data_scope_get(pd->pan_obj, MY_PAN_CLASS);
611 pan_data->wobj = obj;
612
613 efl_ui_scrollable_bounce_enabled_set(pd->scrl_mgr, bounce, bounce);
614
615 edje_object_part_swallow(wd->resize_obj, "efl.content", pd->pan_obj);
616 edje_object_freeze(wd->resize_obj);
617 o = (Evas_Object *)edje_object_part_object_get(wd->resize_obj, "efl.dragable.vbar");
618 edje_object_thaw(wd->resize_obj);
619 efl_gfx_stack_raise((Eo *)o);
620
621 efl_gfx_entity_visible_set(pd->pan_obj, EINA_TRUE);
622
623 efl_access_object_access_type_set(obj, EFL_ACCESS_TYPE_DISABLED);
624
625 edje_object_size_min_calc(wd->resize_obj, &min.w, &min.h);
626 efl_gfx_size_hint_restricted_min_set(obj, min);
627
628 efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED,
629 _efl_ui_tree_view_bar_size_changed_cb, obj);
630 efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED,
631 _efl_ui_tree_view_bar_pos_changed_cb, obj);
632 efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW,
633 _efl_ui_tree_view_bar_show_cb, obj);
634 efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE,
635 _efl_ui_tree_view_bar_hide_cb, obj);
636
637 _efl_ui_tree_view_edje_object_attach(obj);
638
639 elm_layout_sizing_eval(obj);
640}
641
642EOLIAN static void
643_efl_ui_tree_view_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Tree_View_Data *pd)
644{
645 efl_ui_tree_view_relayout_model_set(pd->layouter, NULL);
646 ELM_SAFE_FREE(pd->pan_obj, efl_del);
647 efl_canvas_group_del(efl_super(obj, MY_CLASS));
648}
649
650EOLIAN static Efl_Ui_Focus_Manager*
651_efl_ui_tree_view_efl_ui_widget_focus_manager_focus_manager_create(Eo *obj EINA_UNUSED,
652 Efl_Ui_Tree_View_Data *pd EINA_UNUSED, Efl_Ui_Focus_Object *root)
653{
654 if (!pd->manager)
655 pd->manager = efl_add(EFL_UI_FOCUS_MANAGER_CALC_CLASS, obj,
656 efl_ui_focus_manager_root_set(efl_added, root));
657
658 return pd->manager;
659}
660
661EOLIAN static Eo *
662_efl_ui_tree_view_efl_object_finalize(Eo *obj, Efl_Ui_Tree_View_Data *pd)
663{
664
665 if (!pd->factory)
666 {
667 pd->factory = efl_new(EFL_UI_LAYOUT_FACTORY_CLASS);
668 efl_ui_layout_factory_theme_config(pd->factory, "list_item", NULL, "default");
669 }
670
671 if(!pd->layouter)
672 {
673 pd->layouter = efl_new(EFL_UI_TREE_VIEW_LAYOUTER_CLASS);
674 if (pd->model)
675 efl_ui_tree_view_relayout_model_set(pd->layouter, pd->model);
676 }
677 return obj;
678}
679
680EOLIAN static Eo *
681_efl_ui_tree_view_efl_object_constructor(Eo *obj, Efl_Ui_Tree_View_Data *pd)
682{
683 obj = efl_constructor(efl_super(obj, MY_CLASS));
684 pd->obj = obj;
685 efl_canvas_object_type_set(obj, MY_CLASS_NAME);
686 efl_access_object_role_set(obj, EFL_ACCESS_ROLE_LIST);
687
688 pd->segarray = efl_new(EFL_UI_TREE_VIEW_SEG_ARRAY_CLASS,
689 efl_ui_tree_view_seg_array_setup(efl_added, 32));
690
691 efl_ui_focus_composition_custom_manager_set(obj, obj);
692 efl_ui_focus_composition_logical_mode_set(obj, EINA_TRUE);
693
694 efl_event_callback_add(obj, EFL_UI_FOCUS_MANAGER_EVENT_FOCUS_CHANGED,
695 _list_element_focused, NULL);
696 return obj;
697}
698
699EOLIAN static void
700_efl_ui_tree_view_efl_object_destructor(Eo *obj, Efl_Ui_Tree_View_Data *pd)
701{
702 efl_event_callback_del(obj, EFL_UI_FOCUS_MANAGER_EVENT_FOCUS_CHANGED,
703 _list_element_focused, NULL);
704
705 _efl_ui_tree_view_edje_object_detach(obj);
706 efl_ui_tree_view_seg_array_flush(pd->segarray);
707
708 efl_replace(&pd->model, NULL);
709 efl_replace(&pd->layouter, NULL);
710 efl_replace(&pd->factory, NULL);
711 efl_replace(&pd->segarray, NULL);
712
713 efl_destructor(efl_super(obj, MY_CLASS));
714}
715
716EOLIAN static void
717_efl_ui_tree_view_layout_factory_set(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *pd, Efl_Ui_Factory *factory)
718{
719 if (pd->factory == factory)
720 return;
721
722 efl_replace(&pd->factory, factory);
723}
724
725EOLIAN static Efl_Ui_Factory *
726_efl_ui_tree_view_layout_factory_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *pd)
727{
728 return pd->factory;
729}
730
731EOLIAN static void
732_efl_ui_tree_view_efl_ui_view_model_set(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *pd, Efl_Model *model)
733{
734 if (pd->model == model)
735 return;
736
737 if (pd->model)
738 {
739 if (pd->layouter)
740 efl_ui_tree_view_relayout_model_set(pd->layouter, NULL);
741 efl_ui_tree_view_seg_array_flush(pd->segarray);
742 }
743
744 efl_replace(&pd->model, model);
745
746 if (pd->model && pd->layouter)
747 efl_ui_tree_view_relayout_model_set(pd->layouter, pd->model);
748
749 evas_object_smart_changed(pd->obj);
750}
751
752EOLIAN static Efl_Model *
753_efl_ui_tree_view_efl_ui_view_model_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *pd)
754{
755 return pd->model;
756}
757
758EOLIAN int
759_efl_ui_tree_view_efl_access_selection_selected_children_count_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *pd)
760{
761 return eina_list_count(pd->selected_items);
762}
763
764EOLIAN Eo*
765_efl_ui_tree_view_efl_access_selection_selected_child_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *pd, int child_index)
766{
767 if(child_index < (int) eina_list_count(pd->selected_items))
768 {
769 Efl_Ui_Tree_View_Item* items = eina_list_nth(pd->selected_items, child_index);
770 return items[child_index].layout;
771 }
772 else
773 return NULL;
774}
775
776EOLIAN Eina_Bool
777_efl_ui_tree_view_efl_access_selection_child_select(Eo *obj EINA_UNUSED,
778 Efl_Ui_Tree_View_Data *pd EINA_UNUSED, int child_index EINA_UNUSED)
779{
780 return EINA_FALSE;
781}
782
783EOLIAN Eina_Bool
784_efl_ui_tree_view_efl_access_selection_selected_child_deselect(Eo *obj EINA_UNUSED,
785 Efl_Ui_Tree_View_Data *pd EINA_UNUSED, int child_index EINA_UNUSED)
786{
787 return EINA_FALSE;
788}
789
790EOLIAN Eina_Bool
791_efl_ui_tree_view_efl_access_selection_is_child_selected(Eo *obj EINA_UNUSED,
792 Efl_Ui_Tree_View_Data *pd EINA_UNUSED, int child_index EINA_UNUSED)
793{
794 return EINA_FALSE;
795}
796
797EOLIAN Eina_Bool
798_efl_ui_tree_view_efl_access_selection_all_children_select(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *pd EINA_UNUSED)
799{
800 return EINA_TRUE;
801}
802
803EOLIAN Eina_Bool
804_efl_ui_tree_view_efl_access_selection_access_selection_clear(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *pd EINA_UNUSED)
805{
806 return EINA_TRUE;
807}
808
809EOLIAN Eina_Bool
810_efl_ui_tree_view_efl_access_selection_child_deselect(Eo *obj EINA_UNUSED,
811 Efl_Ui_Tree_View_Data *pd EINA_UNUSED, int child_index EINA_UNUSED)
812{
813 return EINA_FALSE;
814}
815
816static Eina_Value
817_expand_children_slice_then(void * data, Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
818{
819 Efl_Ui_Tree_View_Data *pd;
820 Efl_Model *children;
821 Tree_View_Slice_Callback_Data *slice = data;
822 unsigned int i, len;
823
824 if (!slice || eina_value_type_get(&v) == EINA_VALUE_TYPE_ERROR)
825 goto on_error;
826
827 pd = slice->private;
828 if (eina_value_type_get(&v) == EINA_VALUE_TYPE_OBJECT)
829 {
830 children = eina_value_object_get(&v);
831 efl_ui_tree_view_seg_array_insert(pd->segarray, slice->parent_item, 0, children);
832 }
833 else if (eina_value_type_get(&v) == EINA_VALUE_TYPE_ARRAY)
834 {
835 EINA_VALUE_ARRAY_FOREACH(&v, len, i, children)
836 {
837 unsigned int idx = 0 + i;
838 efl_ui_tree_view_seg_array_insert(pd->segarray, slice->parent_item, idx, children);
839 }
840 }
841 else
842 {
843 ERR ("_expand_children_slice_then");
844 }
845 slice->future = NULL;
846
847 efl_ui_tree_view_relayout_layout_do(pd->layouter, pd->obj, pd->segarray_first, pd->segarray);
848 on_error:
849 free(slice);
850 return v;
851}
852
853void
854_efl_ui_tree_view_item_select_set(Efl_Ui_Tree_View_Item *item, Eina_Bool selected)
855{
856 Eina_Stringshare *sprop;
857 assert(item != NULL);
858 assert(item->model != NULL);
859
860 selected = !!selected;
861
862 sprop = eina_stringshare_add(SELECTED_PROP);
863
864 if (_efl_model_properties_has(item->model, sprop))
865 {
866 Eina_Value v;
867 eina_value_setup(&v, EINA_VALUE_TYPE_UCHAR);
868 eina_value_set(&v, selected);
869 efl_model_property_set(item->model, sprop, &v);
870 eina_value_flush(&v);
871 }
872 eina_stringshare_del(sprop);
873}
874
875EOLIAN static void
876_efl_ui_tree_view_relayout_set(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *pd, Efl_Ui_Tree_View_Relayout *layouter)
877{
878 if (pd->layouter == layouter)
879 return;
880
881 efl_replace(&pd->layouter, layouter);
882
883 if (pd->model && pd->layouter)
884 efl_ui_tree_view_relayout_model_set(pd->layouter, pd->model);
885}
886
887EOLIAN static Efl_Ui_Tree_View_Relayout *
888_efl_ui_tree_view_relayout_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *pd)
889{
890 return pd->layouter;
891}
892
893EOLIAN static void
894_efl_ui_tree_view_show_root_set(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *pd, Eina_Bool showroot)
895{
896 pd->show_root = showroot;
897}
898
899EOLIAN static Eina_Bool
900_efl_ui_tree_view_show_root_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *pd)
901{
902 return pd->show_root;
903}
904
905static void
906_layout(Efl_Ui_Tree_View_Data *pd)
907{
908 if (!pd->model)
909 return;
910
911 efl_ui_tree_view_relayout_layout_do(pd->layouter, pd->obj, pd->segarray_first, pd->segarray);
912}
913
914static Eina_Value
915_children_slice_then(void * data, Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
916{
917 Efl_Ui_Tree_View_Data *pd = data;
918 Efl_Model *children;
919 unsigned int i, len;
920
921 if (eina_value_type_get(&v) == EINA_VALUE_TYPE_ERROR)
922 goto on_error;
923
924 if (eina_value_type_get(&v) == EINA_VALUE_TYPE_OBJECT)
925 {
926 children = eina_value_object_get(&v);
927 efl_ui_tree_view_seg_array_insert(pd->segarray, NULL, pd->slice.start, children);
928 }
929 else if (eina_value_type_get(&v) == EINA_VALUE_TYPE_ARRAY)
930 {
931 EINA_VALUE_ARRAY_FOREACH(&v, len, i, children)
932 {
933 unsigned int idx = pd->slice.start + i;
934
935 efl_ui_tree_view_seg_array_insert(pd->segarray, NULL, idx, children);
936 }
937 }
938
939 pd->segarray_first = pd->slice.start;
940 pd->slice.start = pd->slice.count = 0;
941 pd->slice.future = NULL;
942
943 efl_ui_tree_view_relayout_layout_do(pd->layouter, pd->obj, pd->segarray_first, pd->segarray);
944 on_error:
945 return v;
946}
947
948/* EFL UI TREE MODEL INTERFACE */
949EOLIAN static Eina_Size2D
950_efl_ui_tree_view_efl_ui_tree_view_model_min_size_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *pd)
951{
952 return pd->min;
953}
954
955EOLIAN static void
956_efl_ui_tree_view_efl_ui_tree_view_model_min_size_set(Eo *obj, Efl_Ui_Tree_View_Data *pd, Eina_Size2D min)
957{
958 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
959
960 pd->min.w = min.w;
961 pd->min.h = min.h;
962
963 evas_object_size_hint_min_set(wd->resize_obj, pd->min.w, pd->min.h);
964 efl_event_callback_call(pd->pan_obj, EFL_UI_PAN_EVENT_CONTENT_CHANGED, NULL);
965}
966
967EOLIAN static void
968_efl_ui_tree_view_efl_ui_focus_composition_prepare(Eo *obj, Efl_Ui_Tree_View_Data *pd)
969{
970 Eina_List *order = efl_ui_tree_view_relayout_elements_get(pd->layouter);
971 efl_ui_focus_composition_elements_set(obj, order);
972}
973
974EOLIAN Eina_List*
975_efl_ui_tree_view_efl_access_object_access_children_get(const Eo *obj, Efl_Ui_Tree_View_Data *pd)
976{
977 Eina_List *ret = NULL, *ret2 = NULL;
978
979 ret = efl_ui_tree_view_relayout_elements_get(pd->layouter);
980 ret2 = efl_access_object_access_children_get(efl_super(obj, EFL_UI_TREE_VIEW_CLASS));
981
982 return eina_list_merge(ret, ret2);
983}
984
985EOLIAN static Eina_Bool
986_efl_ui_tree_view_efl_ui_widget_focus_state_apply(Eo *obj, Efl_Ui_Tree_View_Data *pd EINA_UNUSED, Efl_Ui_Widget_Focus_State current_state, Efl_Ui_Widget_Focus_State *configured_state, Efl_Ui_Widget *redirect EINA_UNUSED)
987{
988 return efl_ui_widget_focus_state_apply(efl_super(obj, MY_CLASS), current_state, configured_state, obj);
989}
990
991typedef struct _Efl_Ui_Tree_View_Layout_Item_Tracking Efl_Ui_Tree_View_Layout_Item_Tracking;
992struct _Efl_Ui_Tree_View_Layout_Item_Tracking
993{
994 Efl_Ui_Tree_View_Item *item;
995 Eo *obj;
996 Efl_Ui_Tree_View_Data *pd;
997};
998
999static Eina_Value
1000_content_created(void *data, const Eina_Value value)
1001{
1002 Efl_Ui_Tree_View_Item_Event evt;
1003 Efl_Ui_Tree_View_Layout_Item_Tracking *tracking = data;
1004 Efl_Ui_Tree_View_Item *item = tracking->item;
1005 Efl_Ui_Tree_View_Data *pd = tracking->pd;
1006 Eo *obj = tracking->obj;
1007
1008 eina_value_pget(&value, &item->layout);
1009
1010 evas_object_smart_member_add(item->layout, pd->pan_obj);
1011 evas_object_event_callback_add(item->layout, EVAS_CALLBACK_MOUSE_UP, _on_item_mouse_up, item);
1012
1013 if (_elm_config->atspi_mode)
1014 {
1015 efl_access_added(item->layout);
1016 efl_access_children_changed_added_signal_emit(obj, item->layout);
1017 }
1018
1019 evt.child = item->model;
1020 evt.layout = item->layout;
1021 evt.index = EFL_UI_TREE_VIEW_SEG_ARRAY_POS_GET(item);
1022 efl_event_callback_call(obj, EFL_UI_TREE_VIEW_EVENT_ITEM_REALIZED, &evt);
1023
1024 item->layout_request = NULL;
1025 efl_ui_tree_view_relayout_content_created(pd->layouter, item);
1026
1027 efl_ui_focus_composition_dirty(obj);
1028 evas_object_show(item->layout);
1029
1030 return value;
1031}
1032
1033static void
1034_clean_request(void *data, const Eina_Future *dead_future EINA_UNUSED)
1035{
1036 Efl_Ui_Tree_View_Layout_Item_Tracking *tracking = data;
1037
1038 tracking->item->layout_request = NULL;
1039 free(tracking);
1040}
1041
1042EOLIAN static Efl_Ui_Tree_View_Item *
1043_efl_ui_tree_view_efl_ui_tree_view_model_realize(Eo *obj, Efl_Ui_Tree_View_Data *pd, Efl_Ui_Tree_View_Item *item)
1044{
1045
1046 Efl_Ui_Tree_View_Layout_Item_Tracking *tracking;
1047 EINA_SAFETY_ON_NULL_RETURN_VAL(item->model, item);
1048
1049 if (item->layout_request) eina_future_cancel(item->layout_request);
1050
1051 tracking = calloc(1, sizeof (Efl_Ui_Tree_View_Layout_Item_Tracking));
1052 if (!tracking) return item;
1053
1054 tracking->item = item;
1055 tracking->obj = obj;
1056 tracking->pd = pd;
1057
1058 item->layout_request = efl_ui_factory_create(pd->factory, item->model, obj);
1059 item->layout_request = efl_future_then(obj, item->layout_request);
1060 item->layout_request = eina_future_then_from_desc(item->layout_request,
1061 eina_future_cb_easy(.success = _content_created,
1062 .success_type = EINA_VALUE_TYPE_OBJECT,
1063 .data = tracking,
1064 .free = _clean_request));
1065 return item;
1066}
1067
1068EOLIAN static void
1069_efl_ui_tree_view_efl_ui_tree_view_model_unrealize(Eo *obj, Efl_Ui_Tree_View_Data *pd, Efl_Ui_Tree_View_Item *item)
1070{
1071 Efl_Ui_Tree_View_Item_Event evt;
1072 EINA_SAFETY_ON_NULL_RETURN(item);
1073
1074 if (!item->layout)
1075 return;
1076
1077 // First check if the item has been fully realized
1078 if (item->layout_request)
1079 {
1080 eina_future_cancel(item->layout_request);
1081 return ;
1082 }
1083
1084 evas_object_event_callback_del_full(item->layout, EVAS_CALLBACK_MOUSE_UP, _on_item_mouse_up, item);
1085 if (elm_object_focus_allow_get(item->layout))
1086 {
1087 if (efl_ui_focus_object_focus_get(item->layout))
1088 efl_ui_focus_object_focus_set(item->layout, EINA_FALSE);
1089 efl_ui_focus_manager_calc_unregister(obj, item->layout);
1090 }
1091 evas_object_hide(item->layout);
1092 evas_object_move(item->layout, -9999, -9999);
1093
1094 evt.child = item->model;
1095 evt.layout = item->layout;
1096 evt.index = EFL_UI_TREE_VIEW_SEG_ARRAY_POS_GET(item);
1097 efl_event_callback_call(obj, EFL_UI_TREE_VIEW_EVENT_ITEM_UNREALIZED, &evt);
1098
1099 efl_ui_factory_release(pd->factory, item->layout);
1100 evas_object_smart_member_del(item->layout);
1101 item->layout = NULL;
1102}
1103
1104EOLIAN static void
1105_efl_ui_tree_view_efl_ui_tree_view_model_expand(Eo *obj, Efl_Ui_Tree_View_Data *pd, Efl_Ui_Tree_View_Item *item, int first, int count)
1106{
1107 Tree_View_Slice_Callback_Data *slice;
1108 Eina_Future *f;
1109
1110 if (item->expanded) return;
1111
1112 item->expanded = EINA_TRUE;
1113 slice = calloc(1, sizeof(Tree_View_Slice_Callback_Data));
1114 slice->private = pd;
1115 slice->parent_item = item;
1116 slice->first = first;
1117 f = efl_model_children_slice_get(item->model, first, count);
1118 f = eina_future_then(f, _expand_children_slice_then, slice);
1119 slice->future = efl_future_then(obj, f);
1120}
1121
1122EOLIAN static void
1123_efl_ui_tree_view_efl_ui_tree_view_model_contract(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *pd EINA_UNUSED, Efl_Ui_Tree_View_Item *item EINA_UNUSED)
1124{
1125 //TODO
1126}
1127
1128EOLIAN static void
1129_efl_ui_tree_view_efl_ui_tree_view_model_load_range_set(Eo* obj, Efl_Ui_Tree_View_Data* pd, int first, int count)
1130{
1131 if (pd->slice.future) return ; //FIXME: why ignore a new range set?
1132
1133 pd->slice.start = first;
1134 pd->slice.count = count;
1135
1136 if (efl_model_children_count_get(pd->model))
1137 {
1138 Eina_Future *f = efl_model_children_slice_get(pd->model, first, count);
1139 f = eina_future_then(f, _children_slice_then, pd);
1140 pd->slice.future = efl_future_then(obj, f);
1141 }
1142}
1143
1144EOLIAN static int
1145_efl_ui_tree_view_efl_ui_tree_view_model_model_size_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Data *pd)
1146{
1147 return efl_model_children_count_get(pd->model);
1148}
1149
1150ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(efl_ui_tree_view, Efl_Ui_Tree_View_Data)
1151
1152/* Internal EO APIs and hidden overrides */
1153
1154#define EFL_UI_TREE_VIEW_EXTRA_OPS \
1155 EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_tree_view)
1156
1157#include "efl_ui_tree_view.eo.c"
1158#include "efl_ui_tree_view_relayout.eo.c"
1159#include "efl_ui_tree_view_model.eo.c"
diff --git a/src/lib/elementary/efl_ui_tree_view.eo b/src/lib/elementary/efl_ui_tree_view.eo
new file mode 100644
index 0000000000..065932d4ad
--- /dev/null
+++ b/src/lib/elementary/efl_ui_tree_view.eo
@@ -0,0 +1,96 @@
1import elm_general;
2
3struct Efl.Ui.Tree_View_Item_Event
4{
5 layout: Efl.Ui.Layout;
6 child: Efl.Model;
7 index: int; [[index of the item in thee layout]]
8 depth: int; [[depth of the item in tree layout]]
9}
10
11class Efl.Ui.Tree_View (Efl.Ui.Layout, Efl.Ui.View, Efl.Ui.Scrollable_Interactive, Efl.Ui.Scrollbar,
12 Efl.Access.Widget.Action, Efl.Access.Selection, Efl.Ui.Focus.Composition, Efl.Ui.Focus.Manager_Sub,
13 Efl.Ui.Clickable, Efl.Ui.Selectable, Efl.Ui.Tree_View_Model, Efl.Ui.Widget_Focus_Manager)
14{
15 methods {
16 @property relayout {
17 get {}
18 set {}
19 values {
20 object: Efl.Ui.Tree_View_Relayout;
21 }
22 }
23 @property layout_factory {
24 [[Treeview layout factory set.]]
25 set {}
26 get {}
27 values {
28 factory: Efl.Ui.Factory; [[The factory.]]
29 }
30 }
31 @property show_root {
32 get {
33 [[Get if root is visible.]]
34 }
35 set {
36 [[Enable/Disable root visiblity.]]
37 }
38 values {
39 show: bool; [[Default is Disabled.]]
40 }
41 }
42 }
43 events {
44 item,realized : Efl.Ui.Tree_View_Item_Event;
45 item,unrealized : Efl.Ui.Tree_View_Item_Event;
46 item,focused : Efl.Ui.Tree_View_Item_Event;
47 item,unfocused : Efl.Ui.Tree_View_Item_Event;
48 item,selected : Efl.Ui.Tree_View_Item_Event;
49 item,unselected : Efl.Ui.Tree_View_Item_Event;
50 item,expanded : Efl.Ui.Tree_View_Item_Event;
51 item,unexpanded : Efl.Ui.Tree_View_Item_Event;
52 }
53
54 implements {
55 Efl.Object.constructor;
56 Efl.Object.finalize;
57 Efl.Object.destructor;
58 Efl.Gfx.Entity.position { set; }
59 Efl.Gfx.Entity.size { set; }
60 // Smart obj
61 Efl.Canvas.Group.group_member_add;
62 Efl.Canvas.Group.group_calculate;
63
64 Efl.Ui.Tree_View_Model.load_range { set;}
65 Efl.Ui.Tree_View_Model.realize;
66 Efl.Ui.Tree_View_Model.unrealize;
67 Efl.Ui.Tree_View_Model.expand;
68 Efl.Ui.Tree_View_Model.contract;
69 Efl.Ui.Tree_View_Model.model_size { get; }
70 Efl.Ui.Tree_View_Model.min_size { get; set; }
71
72 // Widget
73 Efl.Ui.Widget_Focus_Manager.focus_manager_create;
74 Efl.Ui.Widget.widget_event;
75 Efl.Ui.Widget.focus_state_apply;
76 Efl.Ui.Focus.Composition.prepare;
77 Efl.Ui.View.model { get; set; }
78
79 Efl.Ui.Scrollable_Interactive.viewport_geometry { get; }
80 Efl.Ui.Scrollable_Interactive.content_pos { get; set; }
81 Efl.Ui.Scrollable_Interactive.content_size { get; }
82 Efl.Ui.Scrollable_Interactive.scroll;
83 Efl.Ui.Scrollbar.bar_mode { get; set; }
84 Efl.Layout.Signal.signal_callback_add;
85 Efl.Layout.Signal.signal_callback_del;
86 Efl.Access.Object.access_children { get; }
87 Efl.Access.Selection.selected_children_count { get; }
88 Efl.Access.Selection.selected_child { get; }
89 Efl.Access.Selection.selected_child_deselect;
90 Efl.Access.Selection.child_select;
91 Efl.Access.Selection.child_deselect;
92 Efl.Access.Selection.is_child_selected;
93 Efl.Access.Selection.all_children_select;
94 Efl.Access.Selection.access_selection_clear;
95 }
96}
diff --git a/src/lib/elementary/efl_ui_tree_view_layouter.c b/src/lib/elementary/efl_ui_tree_view_layouter.c
new file mode 100644
index 0000000000..e97b0f1a5f
--- /dev/null
+++ b/src/lib/elementary/efl_ui_tree_view_layouter.c
@@ -0,0 +1,722 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#include <Elementary.h>
6
7#include <assert.h>
8
9#include "elm_priv.h"
10#include "efl_ui_tree_view_seg_array.h"
11
12#define MY_CLASS EFL_UI_TREE_VIEW_LAYOUTER_CLASS
13
14typedef struct _Efl_Ui_Tree_View_Layouter_Data
15{
16 Efl_Ui_Tree_View_Seg_Array *segarray;
17 Efl_Ui_Tree_View_Model *modeler;
18 Ecore_Job *calc_job;
19 Efl_Model* model;
20 Eina_Size2D min;
21 int count_total;
22 int count_segarray;
23
24 Eina_Bool initialized : 1;
25 Eina_Bool recalc : 1;
26 Eina_Bool resize : 1;
27} Efl_Ui_Tree_View_Layouter_Data;
28
29typedef struct _Efl_Ui_Tree_View_Layouter_Node_Data
30{
31 Eina_Size2D min;
32 Eina_Size2D size;
33 Eina_Bool realized : 1;
34 Eina_Bool expanded : 1;
35} Efl_Ui_Tree_View_Layouter_Node_Data;
36
37typedef struct _Efl_Ui_Tree_View_Layouter_Callback_Data
38{
39 Efl_Ui_Tree_View_Layouter_Data *pd;
40 Efl_Ui_Tree_View_Item *item;
41} Efl_Ui_Tree_View_Layouter_Callback_Data;
42
43typedef struct _Request Request;
44struct _Request
45{
46 Efl_Ui_Tree_View_Layouter_Data *pd;
47 unsigned int index;
48};
49
50typedef struct _Draw_Data
51{
52 Eina_Rect vgmt;
53 Eina_Position2D spos;
54 int extra;
55 int rounding;
56 double cur_pos;
57} Draw_Data;
58
59#include "efl_ui_tree_view_layouter.eo.h"
60
61static void
62_item_size_calc(Efl_Ui_Tree_View_Layouter_Data *pd, Efl_Ui_Tree_View_Item* item)
63{
64 int boxx, boxy, boxw, boxh, boxl, boxr, boxt, boxb, pad[4];
65 double align[2];
66 Eina_Size2D max;
67
68 efl_gfx_size_hint_margin_get(item->layout, &pad[0], &pad[1], &pad[2], &pad[3]);
69 evas_object_geometry_get(pd->modeler, &boxx, &boxy, &boxw, &boxh);
70 efl_gfx_size_hint_margin_get(pd->modeler, &boxl, &boxr, &boxt, &boxb);
71 efl_gfx_size_hint_align_get(item->layout, &align[0], &align[1]);
72 max = efl_gfx_size_hint_max_get(item->layout);
73
74 // box outer margin
75 boxw -= boxl + boxr;
76 boxh -= boxt + boxb;
77 boxx += boxl;
78 boxy += boxt;
79
80 if (align[0] < 0) align[0] = -1;
81 if (align[1] < 0) align[1] = -1;
82 if (align[0] > 1) align[0] = 1;
83 if (align[1] > 1) align[1] = 1;
84
85 if (max.w <= 0) max.w = INT_MAX;
86 if (max.h <= 0) max.h = INT_MAX;
87 if (max.w < item->min.w) max.w = item->min.w;
88 if (max.h < item->min.h) max.h = item->min.h;
89
90 // horizontally
91 if (max.w < INT_MAX)
92 {
93 item->size.w = MIN(MAX(item->min.w - pad[0] - pad[1], max.w), boxw);
94 item->pos.x = boxx + pad[0];
95 }
96 else if (align[0] < 0)
97 {
98 // fill x
99 item->size.w = boxw - pad[0] - pad[1];
100 item->pos.x = boxx + pad[0];
101 }
102 else
103 {
104 item->size.w = item->min.w - pad[0] - pad[1];
105 item->pos.x = boxx + ((boxw - item->size.w) * align[0]) + pad[0];
106 }
107
108 // vertically
109 if (max.h < INT_MAX)
110 {
111 item->size.h = MIN(MAX(item->min.h - pad[2] - pad[3], max.h), boxh);
112 item->pos.y = boxy + pad[2];
113 }
114 else if (align[1] < 0)
115 {
116 // fill y
117 item->size.h = item->min.h - pad[2] - pad[3];
118 item->pos.y = boxy + pad[2];
119 }
120 else
121 {
122 item->size.h = item->min.h - pad[2] - pad[3];
123 item->pos.y = boxy + ((item->min.h - item->size.h) * align[1]) + pad[2];
124 }
125}
126
127static void
128_node_size_fix(Efl_Ui_Tree_View_Item* item, int sizediff)
129{
130 Efl_Ui_Tree_View_Layouter_Node_Data *nodedata;
131 Efl_Ui_Tree_View_Seg_Array_Node *node;
132 Efl_Ui_Tree_View_Item *parent;
133
134 if (!item || !item->parent)
135 return;
136
137 parent = item->parent;
138 node = parent->tree_node;
139 if (node && node->layout_data)
140 {
141 nodedata = node->layout_data;
142 nodedata->min.h += sizediff;
143 }
144
145 parent->children_min.h += sizediff;
146 if (parent->children_min.h < 0) parent->children_min.h = 0;
147
148 _node_size_fix(parent, sizediff);
149}
150
151static void
152_item_min_calc(Efl_Ui_Tree_View_Layouter_Data *pd, Efl_Ui_Tree_View_Item* item
153 , Eina_Size2D min, Efl_Ui_Tree_View_Seg_Array_Node *itemnode
154 , Efl_Ui_Tree_View_Seg_Array *segarray)
155{
156 EINA_SAFETY_ON_NULL_RETURN(pd);
157 EINA_SAFETY_ON_NULL_RETURN(item);
158 EINA_SAFETY_ON_NULL_RETURN(itemnode);
159 Efl_Ui_Tree_View_Layouter_Node_Data *nodedata = itemnode->layout_data;
160 Efl_Ui_Tree_View_Item *litem;
161 int i, pad[4];
162
163 efl_gfx_size_hint_margin_get(item->layout, &pad[0], &pad[1], &pad[2], &pad[3]);
164 min.w += pad[0] + pad[1];
165 min.h += pad[2] + pad[3];
166
167 if (item->min.h == min.h && item->min.w == min.w)
168 return;
169
170 pd->min.h += min.h - item->min.h;
171 nodedata->min.h += min.h - item->min.h;
172
173 if (nodedata->min.w <= min.w)
174 nodedata->min.w = min.w;
175 else if (nodedata->min.w == item->min.w)
176 {
177 nodedata->min.w = 0;
178 for (i = 0; i != itemnode->length; ++i)
179 {
180 litem = (Efl_Ui_Tree_View_Item *)itemnode->pointers[i];
181 if (nodedata->min.w < litem->min.w)
182 nodedata->min.w = litem->min.w;
183 if (item->min.w == litem->min.w)
184 break;
185 }
186 }
187
188 if (pd->min.w <= min.w)
189 pd->min.w = min.w;
190 else if (pd->min.w == item->min.w)
191 {
192 Efl_Ui_Tree_View_Seg_Array_Node *node2;
193 Eina_Accessor *nodes = efl_ui_tree_view_seg_array_node_accessor_get(segarray);
194 pd->min.w = min.w;
195
196 EINA_ACCESSOR_FOREACH(nodes, i, node2)
197 {
198 Efl_Ui_Tree_View_Layouter_Node_Data *nodedata2 = node2->layout_data;
199 if (pd->min.w < nodedata2->min.w)
200 pd->min.w = nodedata2->min.w;
201
202 if (item->min.w == nodedata2->min.w)
203 break;
204 }
205 eina_accessor_free(nodes);
206 }
207
208 _node_size_fix(item, (min.h - item->min.h));
209
210 item->min.w = min.w;
211 item->min.h = min.h;
212 _item_size_calc(pd, item);
213}
214
215static void
216_on_item_size_hint_change(void *data, Evas *e EINA_UNUSED,
217 Evas_Object *obj, void *event_info EINA_UNUSED)
218{
219 Efl_Ui_Tree_View_Layouter_Callback_Data *cb_data = data;
220 EINA_SAFETY_ON_NULL_RETURN(cb_data);
221 Efl_Ui_Tree_View_Layouter_Data *pd = cb_data->pd;
222 EINA_SAFETY_ON_NULL_RETURN(pd);
223 Efl_Ui_Tree_View_Item *item = cb_data->item;;
224 EINA_SAFETY_ON_NULL_RETURN(item);
225 Efl_Ui_Tree_View_Seg_Array_Node *node = item->tree_node;
226 EINA_SAFETY_ON_NULL_RETURN(node);
227 Efl_Ui_Tree_View_Layouter_Node_Data *nodedata = node->layout_data;
228 EINA_SAFETY_ON_NULL_RETURN(nodedata);
229
230 Eina_Size2D min = efl_gfx_size_hint_combined_min_get(obj);
231 if (item->parent)
232 {
233 Efl_Ui_Tree_View_Item *parent = item->parent;
234 _item_min_calc(pd, item, min, node, parent->segarray);
235 }
236 else
237 _item_min_calc(pd, item, min, node, pd->segarray);
238
239 if (!nodedata->realized)
240 free(evas_object_event_callback_del(item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change));
241}
242
243static Eina_Value
244_children_get(void *data, Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
245{
246 Efl_Model *children;
247 unsigned int i, len;
248 Request *r = data;
249
250 if (eina_value_type_get(&v) == EINA_VALUE_TYPE_ERROR)
251 goto on_error;
252
253 if (eina_value_type_get(&v) == EINA_VALUE_TYPE_OBJECT)
254 {
255 children = eina_value_object_get(&v);
256 efl_ui_tree_view_seg_array_insert(r->pd->segarray, NULL, r->index, children);
257 }
258 else if (eina_value_type_get(&v) == EINA_VALUE_TYPE_ARRAY)
259 {
260 EINA_VALUE_ARRAY_FOREACH(&v, len, i, children)
261 {
262 unsigned int idx = r->index + i;
263 efl_ui_tree_view_seg_array_insert(r->pd->segarray, NULL, idx, children);
264 }
265 }
266
267 r->pd->recalc = EINA_TRUE;
268 evas_object_smart_changed(r->pd->modeler);
269
270 on_error:
271 free(r);
272 return v;
273}
274
275static void
276_on_modeler_resize(void *data, Evas *e EINA_UNUSED,
277 Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
278{
279 Efl_Ui_Tree_View_Layouter_Data *pd = data;
280 pd->resize = EINA_TRUE;
281}
282
283static void
284_child_added_cb(void *data, const Efl_Event *event)
285{
286 Efl_Model_Children_Event* evt = event->info;
287 Efl_Ui_Tree_View_Layouter_Data *pd = data;
288 Eina_Future *f;
289 Request *r;
290
291 r = calloc(1, sizeof (Request));
292 if (!r) return;
293
294 r->index = evt->index;
295 r->pd = pd;
296
297 f = efl_model_children_slice_get(pd->model, evt->index, 1);
298 f = eina_future_then(f, _children_get, r);
299}
300
301static void
302_node_realize(Efl_Ui_Tree_View_Layouter_Data *pd, Efl_Ui_Tree_View_Seg_Array_Node *node)
303{
304 Efl_Ui_Tree_View_Item* item;
305 Efl_Ui_Tree_View_Layouter_Node_Data *nodedata = node->layout_data;
306 int i;
307
308 EINA_SAFETY_ON_NULL_RETURN(nodedata);
309 if (nodedata->realized)
310 return;
311
312 nodedata->realized = EINA_TRUE;
313
314 for (i = 0; i != node->length; ++i)
315 {
316 item = (Efl_Ui_Tree_View_Item *)node->pointers[i];
317 efl_ui_tree_view_model_realize(pd->modeler, item);
318 }
319}
320
321void
322_node_unrealize(Efl_Ui_Tree_View_Layouter_Data *pd, Efl_Ui_Tree_View_Seg_Array_Node *node, Eina_Bool is_free)
323{
324 Efl_Ui_Tree_View_Seg_Array_Node *s_node;
325 Efl_Ui_Tree_View_Layouter_Node_Data *nodedata;
326 Efl_Ui_Tree_View_Item* item;
327 int i, j;
328
329 EINA_SAFETY_ON_NULL_RETURN(node);
330 EINA_SAFETY_ON_NULL_RETURN(node->layout_data);
331
332 nodedata = node->layout_data;
333 if (!nodedata->realized)
334 return;
335
336 nodedata->realized = EINA_FALSE;
337 for (i = 0; i != node->length; ++i)
338 {
339 item = (Efl_Ui_Tree_View_Item *)node->pointers[i];
340 if (item->expanded && item->segarray)
341 {
342 Eina_Accessor *nodes = efl_ui_tree_view_seg_array_node_accessor_get(item->segarray);
343 EINA_ACCESSOR_FOREACH(nodes, j, s_node)
344 {
345 _node_unrealize(pd, s_node, is_free);
346 }
347 eina_accessor_free(nodes);
348 }
349
350 if (item->layout)
351 {
352 free(evas_object_event_callback_del(item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change));
353 efl_ui_tree_view_model_unrealize(pd->modeler, item);
354 }
355 }
356
357 if (is_free)
358 {
359 free(node->layout_data);
360 node->layout_data = NULL;
361 }
362}
363
364static void
365_child_count_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
366{
367 Efl_Ui_Tree_View_Layouter_Data *pd = data;
368 pd->count_total = efl_model_children_count_get(pd->model);
369 if (pd->count_total)
370 efl_event_callback_del(pd->model, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, _child_count_changed_cb, pd);
371}
372
373static Eina_Bool
374_initilize(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Layouter_Data *pd, Efl_Ui_Tree_View_Model *modeler)
375{
376 if (pd->initialized)
377 return EINA_TRUE;
378
379 efl_replace(&pd->modeler, modeler);
380
381 if (!pd->model || !pd->modeler)
382 return EINA_FALSE;
383
384 pd->recalc = EINA_TRUE;
385 pd->initialized = EINA_TRUE;
386
387 efl_ui_tree_view_model_load_range_set(pd->modeler, 0, pd->count_total); // load all
388 efl_event_callback_add(pd->model, EFL_MODEL_EVENT_CHILD_ADDED, _child_added_cb, pd);
389
390 evas_object_event_callback_add(pd->modeler, EVAS_CALLBACK_RESIZE, _on_modeler_resize, pd);
391 pd->min.w = 0;
392 pd->min.h = 0;
393
394 return EINA_TRUE;
395}
396
397static void
398_finalize(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Layouter_Data *pd)
399{
400 Efl_Ui_Tree_View_Seg_Array_Node* node;
401 int i;
402
403 if (pd->segarray)
404 {
405 Eina_Accessor *nodes = efl_ui_tree_view_seg_array_node_accessor_get(pd->segarray);
406 EINA_ACCESSOR_FOREACH(nodes, i, node)
407 {
408 _node_unrealize(pd, node, EINA_TRUE);
409 }
410 eina_accessor_free(nodes);
411 }
412
413 if (pd->model)
414 {
415 efl_event_callback_del(pd->model, EFL_MODEL_EVENT_CHILD_ADDED, _child_added_cb, pd);
416 pd->count_total = 0;
417 }
418
419 if (pd->modeler)
420 {
421 evas_object_event_callback_del_full(pd->modeler, EVAS_CALLBACK_RESIZE, _on_modeler_resize, pd);
422 efl_ui_tree_view_model_min_size_set(pd->modeler, pd->min);
423 }
424
425 pd->min.w = 0;
426 pd->min.h = 0;
427 efl_replace(&pd->modeler, NULL);
428 efl_replace(&pd->segarray, NULL);
429 pd->initialized = EINA_FALSE;
430 pd->recalc = EINA_TRUE;
431}
432
433static void
434_calc_range(Efl_Ui_Tree_View_Layouter_Data *pd, Efl_Ui_Tree_View_Seg_Array *segarray, Evas_Coord cur_pos)
435{
436 Efl_Ui_Tree_View_Layouter_Node_Data *nodedata;
437 Efl_Ui_Tree_View_Seg_Array_Node *node;
438 Eina_Position2D spos;
439 Evas_Coord ny;
440 Eina_Rect vgmt;
441 int i;
442
443 vgmt = efl_ui_scrollable_viewport_geometry_get(pd->modeler);
444 spos = efl_ui_scrollable_content_pos_get(pd->modeler);
445 ny = spos.y - (vgmt.h / 2);
446 if (ny < 0) spos.y = 0;
447 else spos.y = ny;
448 vgmt.h *= 2;
449
450 Eina_Accessor *nodes = efl_ui_tree_view_seg_array_node_accessor_get(segarray);
451 EINA_ACCESSOR_FOREACH(nodes, i, node)
452 {
453 nodedata = node->layout_data;
454 if (!nodedata || !nodedata->min.h)
455 continue;
456
457 if ((cur_pos > spos.y || nodedata->min.h + cur_pos > spos.y) && (cur_pos < (spos.y + vgmt.h) || nodedata->min.h + cur_pos < spos.y + vgmt.h))
458 _node_realize(pd, node);
459 else
460 _node_unrealize(pd, node, EINA_FALSE);
461
462 cur_pos += nodedata->min.h;
463 }
464 eina_accessor_free(nodes);
465}
466
467static void
468_calc_size_segarray(Efl_Ui_Tree_View_Layouter_Data* pd, Efl_Ui_Tree_View_Seg_Array *segarray)
469{
470 EINA_SAFETY_ON_NULL_RETURN(pd);
471 EINA_SAFETY_ON_NULL_RETURN(segarray);
472 Efl_Ui_Tree_View_Seg_Array_Node *node;
473 Efl_Ui_Tree_View_Item *item;
474 int i, j = 0, count;
475
476 Eina_Accessor *nodes = efl_ui_tree_view_seg_array_node_accessor_get(segarray);
477 while (eina_accessor_data_get(nodes, j, (void **)&node))
478 {
479 ++j;
480 if (!node->layout_data)
481 node->layout_data = calloc(1, sizeof(Efl_Ui_Tree_View_Layouter_Node_Data));
482
483 if (j == 1)
484 {
485 Efl_Ui_Tree_View_Layouter_Node_Data *nodedata = node->layout_data;
486 nodedata->realized = EINA_TRUE;
487 }
488
489 for (i = 0; i != node->length; ++i)
490 {
491 item = (Efl_Ui_Tree_View_Item *)node->pointers[i];
492 EINA_SAFETY_ON_NULL_RETURN(item);
493
494 // cache size of new items
495 if ((item->min.w == 0) && (item->min.h == 0) && !item->layout)
496 efl_ui_tree_view_model_realize(pd->modeler, item);
497
498 count = efl_model_children_count_get(item->model);
499 if (count && !item->expanded)
500 {
501 efl_ui_tree_view_model_expand(pd->modeler, item, 0, count);
502 }
503 else if (item->expanded && item->segarray)
504 {
505 _calc_size_segarray (pd, item->segarray);
506 }
507 }
508 }
509 eina_accessor_free(nodes);
510}
511
512static void
513_calc_size_job(void *data)
514{
515 Efl_Ui_Tree_View_Layouter_Data *pd;
516 Eo *obj = data;
517 /* double start_time = ecore_time_get(); */
518
519 EINA_SAFETY_ON_NULL_RETURN(data);
520 pd = efl_data_scope_get(obj, MY_CLASS);
521 if (EINA_UNLIKELY(!pd)) return;
522
523 _calc_size_segarray(pd, pd->segarray);
524
525 pd->calc_job = NULL;
526 pd->recalc = EINA_FALSE;
527
528 evas_object_smart_changed(pd->modeler);
529}
530
531EOLIAN static Efl_Object *
532_efl_ui_tree_view_layouter_efl_object_constructor(Eo *obj, Efl_Ui_Tree_View_Layouter_Data *pd)
533{
534 obj = efl_constructor(efl_super(obj, MY_CLASS));
535 pd->initialized = EINA_FALSE;
536
537 return obj;
538}
539
540EOLIAN static void
541_efl_ui_tree_view_layouter_efl_ui_tree_view_relayout_content_created(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Layouter_Data *pd, Efl_Ui_Tree_View_Item *item)
542{
543 Efl_Ui_Tree_View_Layouter_Callback_Data *cb_data;
544 EINA_SAFETY_ON_NULL_RETURN(item);
545 EINA_SAFETY_ON_NULL_RETURN(item->layout);
546 Efl_Ui_Tree_View_Seg_Array_Node *node = item->tree_node;
547 Efl_Ui_Tree_View_Layouter_Node_Data *nodedata = node->layout_data;
548
549 Eina_Size2D min = efl_gfx_size_hint_combined_min_get(item->layout);
550 _item_min_calc(pd, item, min, node, pd->segarray);
551
552 if (min.w && min.h && !nodedata->realized)
553 {
554 efl_ui_tree_view_model_unrealize(pd->modeler, item);
555 return;
556 }
557
558 cb_data = calloc(1, sizeof(Efl_Ui_Tree_View_Layouter_Callback_Data));
559 cb_data->pd = pd;
560 cb_data->item = item;
561 evas_object_event_callback_add(item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change, cb_data);
562
563 _item_size_calc(pd, item);
564}
565
566EOLIAN static Eina_List *
567_efl_ui_tree_view_layouter_efl_ui_tree_view_relayout_elements_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Layouter_Data *pd)
568{
569 Eina_List *elements_order = NULL;
570 Efl_Ui_Tree_View_Item* item;
571 Efl_Ui_Tree_View_Seg_Array_Node *items_node;
572 int i, j;
573
574 Eina_Accessor *nodes = efl_ui_tree_view_seg_array_node_accessor_get(pd->segarray);
575 EINA_ACCESSOR_FOREACH(nodes, i, items_node)
576 {
577 Efl_Ui_Tree_View_Layouter_Node_Data *nodedata = items_node->layout_data;
578 if (!nodedata || !nodedata->realized)
579 continue;
580
581 for (j = 0; j != items_node->length; ++j)
582 {
583 item = (Efl_Ui_Tree_View_Item *)items_node->pointers[j];
584 if (item->layout)
585 elements_order = eina_list_append(elements_order, item->layout);
586 }
587 }
588 eina_accessor_free(nodes);
589 return elements_order;
590}
591
592EOLIAN static void
593_efl_ui_tree_view_layouter_efl_ui_tree_view_relayout_model_set(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Layouter_Data *pd, Efl_Model *model)
594{
595 _finalize(obj, pd);
596
597 efl_replace(&pd->model, model);
598 if (pd->model)
599 {
600 pd->count_total = efl_model_children_count_get(pd->model);
601 if (pd->count_total && pd->modeler)
602 efl_ui_tree_view_model_load_range_set(pd->modeler, 0, pd->count_total); // load all
603 else
604 efl_event_callback_add(pd->model, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, _child_count_changed_cb, pd);
605 }
606}
607
608static void
609_node_draw(Efl_Ui_Tree_View_Layouter_Data *pd, Efl_Ui_Tree_View_Seg_Array *segarray, Draw_Data *drawdata)
610{
611 Efl_Ui_Tree_View_Seg_Array_Node *items_node;
612 Efl_Ui_Tree_View_Item* item;
613 int i, j;
614
615 _calc_range(pd, segarray, drawdata->cur_pos);
616
617 Eina_Accessor *nodes = efl_ui_tree_view_seg_array_node_accessor_get(segarray);
618 EINA_SAFETY_ON_NULL_RETURN(nodes);
619 EINA_ACCESSOR_FOREACH(nodes, i, items_node)
620 {
621 Efl_Ui_Tree_View_Layouter_Node_Data *nodedata = items_node->layout_data;
622 if (!nodedata) continue;
623
624 if (nodedata->realized)
625 for (j = 0; j != items_node->length;++j)
626 {
627 double x, y, w, h;
628 double weight_x, weight_y;
629 item = (Efl_Ui_Tree_View_Item *)items_node->pointers[j];
630 EINA_SAFETY_ON_NULL_RETURN(item);
631
632 if (item->layout)
633 {
634 if (pd->resize)
635 _item_size_calc(pd, item);
636
637 efl_gfx_size_hint_weight_get(item->layout, &weight_x, &weight_y);
638 // extra rounding up (compensate cumulative error)
639 if ((i == (pd->count_total - 1)) && (drawdata->cur_pos - floor(drawdata->cur_pos) >= 0.5))
640 drawdata->rounding = 1;
641
642 x = item->pos.x;
643 y = item->pos.y + drawdata->cur_pos;
644 w = item->size.w;
645 h = item->size.h + drawdata->rounding + weight_y * drawdata->extra;
646 drawdata->cur_pos += h;
647
648 if (w < pd->min.w) w = pd->min.w;
649 if (w > drawdata->vgmt.w) w = drawdata->vgmt.w;
650
651 evas_object_geometry_set(item->layout, (x + 0 - drawdata->spos.x), (y + 0 - drawdata->spos.y), w, h);
652 }
653 else
654 {
655 drawdata->cur_pos += item->size.h;
656 }
657
658 if (item->expanded && item->segarray)
659 _node_draw(pd, item->segarray, drawdata);
660 }
661 else
662 drawdata->cur_pos += nodedata->min.h;
663 }
664 eina_accessor_free(nodes);
665}
666
667static void
668_efl_ui_tree_view_relayout_layout_do(Efl_Ui_Tree_View_Layouter_Data *pd)
669{
670 int boxx, boxy, boxw, boxh;
671 int boxl = 0, boxr = 0, boxt = 0, boxb = 0;
672 Draw_Data drawdata;
673 memset(&drawdata, 0, sizeof(drawdata));
674
675 evas_object_geometry_get(pd->modeler, &boxx, &boxy, &boxw, &boxh);
676 efl_gfx_size_hint_margin_get(pd->modeler, &boxl, &boxr, &boxt, &boxb);
677
678 // box outer margin
679 boxw -= boxl + boxr;
680 boxh -= boxt + boxb;
681 boxx += boxl;
682 boxy += boxt;
683
684 drawdata.extra = boxh - pd->min.h;
685 if (drawdata.extra < 0) drawdata.extra = 0;
686
687 efl_ui_tree_view_model_min_size_set(pd->modeler, pd->min);
688 drawdata.vgmt = efl_ui_scrollable_viewport_geometry_get(pd->modeler);
689 drawdata.spos = efl_ui_scrollable_content_pos_get(pd->modeler);
690
691 _node_draw(pd, pd->segarray, &drawdata);
692 pd->resize = EINA_FALSE;
693}
694
695EOLIAN static void
696_efl_ui_tree_view_layouter_efl_ui_tree_view_relayout_layout_do
697 (Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Layouter_Data *pd
698 , Efl_Ui_Tree_View_Model *modeler, int first EINA_UNUSED, Efl_Ui_Tree_View_Seg_Array *segarray)
699{
700 int count;
701
702 if (!_initilize(obj, pd, modeler))
703 return;
704
705 efl_replace(&pd->segarray, segarray);
706 if (!pd->segarray)
707 return;
708
709 count = efl_ui_tree_view_seg_array_count(pd->segarray);
710
711 if ((pd->recalc && count > 0) || pd->count_segarray != count)
712 {
713 // cache size of new items
714 pd->count_segarray = count;
715 ecore_job_del(pd->calc_job);
716 pd->calc_job = ecore_job_add(_calc_size_job, obj);
717 return;
718 }
719 _efl_ui_tree_view_relayout_layout_do(pd);
720}
721
722#include "efl_ui_tree_view_layouter.eo.c"
diff --git a/src/lib/elementary/efl_ui_tree_view_layouter.eo b/src/lib/elementary/efl_ui_tree_view_layouter.eo
new file mode 100644
index 0000000000..5826ec37a8
--- /dev/null
+++ b/src/lib/elementary/efl_ui_tree_view_layouter.eo
@@ -0,0 +1,10 @@
1class Efl.Ui.Tree_View_Layouter (Efl.Object, Efl.Ui.Tree_View_Relayout)
2{
3 implements {
4 Efl.Object.constructor;
5 Efl.Ui.Tree_View_Relayout.layout_do;
6 Efl.Ui.Tree_View_Relayout.content_created;
7 Efl.Ui.Tree_View_Relayout.model { set; }
8 Efl.Ui.Tree_View_Relayout.elements { get; }
9 }
10}
diff --git a/src/lib/elementary/efl_ui_tree_view_model.eo b/src/lib/elementary/efl_ui_tree_view_model.eo
new file mode 100644
index 0000000000..be2fe0acd3
--- /dev/null
+++ b/src/lib/elementary/efl_ui_tree_view_model.eo
@@ -0,0 +1,70 @@
1struct Efl.Ui.Tree_View_Item {
2 layout: Efl.Ui.Layout;
3 layout_request: future<Efl.Ui.Layout>;
4 model: Efl.Model;
5 linearized_offset: int; [[model index]]
6 shallow_offset: int;
7 depth: int;
8 children_count: int; [[ Number of indirect children ]]
9 children_min: Eina.Size2D;
10 children_size: Eina.Size2D;
11 parent: void_ptr; [[Efl.Ui.Tree_View_Item parent]]
12 tree_node: void_ptr;
13 segarray: Efl.Ui.Tree_View_Seg_Array;
14 expanded: bool;
15 min: Eina.Size2D;
16 size: Eina.Size2D;
17 pos: Eina.Position2D;
18}
19
20struct @extern Efl.Ui.Tree_View_Seg_Array_Node; [[ ]]
21
22interface Efl.Ui.Tree_View_Model (Efl.Ui.Direction, Efl.Gfx.Entity, Efl.Ui.Scrollable_Interactive)
23{
24 methods {
25 @property load_range {
26 set {}
27 values {
28 first: int;
29 count: int;
30 }
31 }
32 realize {
33 params {
34 item: ptr(Efl.Ui.Tree_View_Item);
35 }
36 return: ptr(Efl.Ui.Tree_View_Item);
37 }
38 unrealize {
39 params {
40 item: ptr(Efl.Ui.Tree_View_Item);
41 }
42 }
43 expand {
44 params {
45 item: ptr(Efl.Ui.Tree_View_Item);
46 first: int;
47 count: int;
48 }
49 }
50 contract {
51 params {
52 item: ptr(Efl.Ui.Tree_View_Item);
53 }
54 }
55 @property model_size {
56 get {}
57 values {
58 s: int;
59 }
60 }
61 @property min_size {
62 [[Minimal content size.]]
63 set {}
64 get {}
65 values {
66 min: Eina.Size2D;
67 }
68 }
69 }
70}
diff --git a/src/lib/elementary/efl_ui_tree_view_pan.eo b/src/lib/elementary/efl_ui_tree_view_pan.eo
new file mode 100644
index 0000000000..823d89f0e9
--- /dev/null
+++ b/src/lib/elementary/efl_ui_tree_view_pan.eo
@@ -0,0 +1,12 @@
1class Efl.Ui.Tree_View_Pan (Efl.Ui.Pan)
2{
3 [[Elementary Efl_Ui_Tree_View pan class]]
4 implements {
5 Efl.Object.destructor;
6 Efl.Ui.Pan.content_size { get; }
7 Efl.Ui.Pan.pan_position { get; set; }
8 Efl.Ui.Pan.pan_position_min { get; }
9 Efl.Ui.Pan.pan_position_max { get; }
10 Efl.Canvas.Group.group_calculate;
11 }
12}
diff --git a/src/lib/elementary/efl_ui_tree_view_private.h b/src/lib/elementary/efl_ui_tree_view_private.h
new file mode 100644
index 0000000000..bb99f1253f
--- /dev/null
+++ b/src/lib/elementary/efl_ui_tree_view_private.h
@@ -0,0 +1,73 @@
1#ifndef EFL_UI_TREE_VIEW_PRIVATE_H
2#define EFL_UI_TREE_VIEW_PRIVATE_H
3
4#ifdef HAVE_CONFIG_H
5# include "elementary_config.h"
6#endif
7
8#include <Elementary.h>
9#include "elm_priv.h"
10
11#include "efl_ui_tree_view.eo.h"
12#include "efl_ui_tree_view_layouter.eo.h"
13
14#include <assert.h>
15
16typedef struct _Efl_Ui_Tree_View_Data Efl_Ui_Tree_View_Data;
17#include "efl_ui_tree_view_seg_array.h"
18
19struct _Efl_Ui_Tree_View_Data
20{
21 Eo *obj;
22 Eo *scrl_mgr;
23 Efl_Ui_Tree_View_Pan *pan_obj;
24 Efl_Model *model;
25
26 struct {
27 Eina_Future *future;
28
29 int start;
30 int count;
31 } slice;
32
33 Efl_Ui_Layout_Factory *factory;
34 Eina_List *selected_items;
35 Efl_Ui_Focus_Manager *manager;
36 Efl_Ui_Tree_View_Relayout *layouter;
37 Efl_Ui_Tree_View_Seg_Array *segarray;
38 int segarray_first;
39
40 Eina_Size2D min;
41 Eina_Bool scrl_freeze : 1;
42 Eina_Bool show_root: 1;
43};
44
45typedef struct _Efl_Ui_Tree_View_Pan_Data Efl_Ui_Tree_View_Pan_Data;
46struct _Efl_Ui_Tree_View_Pan_Data
47{
48 Eo *wobj;
49 Eina_Rect gmt;
50};
51
52#define EFL_UI_TREE_VIEW_DATA_GET(o, ptr) \
53 Efl_Ui_Tree_View_Data * ptr = efl_data_scope_get(o, EFL_UI_TREE_VIEW_CLASS)
54
55#define EFL_UI_TREE_VIEW_DATA_GET_OR_RETURN(o, ptr) \
56 EFL_UI_TREE_VIEW_DATA_GET(o, ptr); \
57 if (EINA_UNLIKELY(!ptr)) \
58 { \
59 ERR("No widget data for object %p (%s)", \
60 o, evas_object_type_get(o)); \
61 return; \
62 }
63
64#define EFL_UI_TREE_VIEW_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
65 EFL_UI_TREE_VIEW_DATA_GET(o, ptr); \
66 if (EINA_UNLIKELY(!ptr)) \
67 { \
68 ERR("No widget data for object %p (%s)", \
69 o, evas_object_type_get(o)); \
70 return val; \
71 }
72
73#endif
diff --git a/src/lib/elementary/efl_ui_tree_view_relayout.eo b/src/lib/elementary/efl_ui_tree_view_relayout.eo
new file mode 100644
index 0000000000..28b520f296
--- /dev/null
+++ b/src/lib/elementary/efl_ui_tree_view_relayout.eo
@@ -0,0 +1,30 @@
1interface Efl.Ui.Tree_View_Relayout (Efl.Interface)
2{
3 methods {
4 layout_do {
5 params {
6 modeler: Efl.Ui.Tree_View_Model;
7 first: int;
8 children: Efl.Ui.Tree_View_Seg_Array;
9 }
10 }
11 content_created {
12 params {
13 item: ptr(Efl.Ui.Tree_View_Item);
14 }
15 }
16 @property model {
17 [[Model that is/will be ]]
18 set {}
19 values {
20 model: Efl.Model; [[Efl model]]
21 }
22 }
23 @property elements {
24 get {}
25 values {
26 elements: list<Efl.Gfx.Entity>; [[The order to use]]
27 }
28 }
29 }
30}
diff --git a/src/lib/elementary/efl_ui_tree_view_seg_array.c b/src/lib/elementary/efl_ui_tree_view_seg_array.c
new file mode 100644
index 0000000000..674c59c5a9
--- /dev/null
+++ b/src/lib/elementary/efl_ui_tree_view_seg_array.c
@@ -0,0 +1,474 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#include <Efl.h>
6#include <assert.h>
7
8#include <Elementary.h>
9#include "elm_priv.h"
10
11#define MY_CLASS EFL_UI_TREE_VIEW_SEG_ARRAY_CLASS
12#define MY_CLASS_NAME "Efl.Ui.Tree_View_Seg_Array"
13
14#include "efl_ui_tree_view_seg_array.h"
15
16static int _shallow_search_lookup_cb(Eina_Rbtree const* rbtree, const void* key, int length EINA_UNUSED, void* data EINA_UNUSED)
17{
18 Efl_Ui_Tree_View_Seg_Array_Node const* node = (void const*)rbtree;
19 int index = *(int*)key;
20 if (index < node->shallow_first_index)
21 {
22 return 1;
23 }
24 else if (index < node->shallow_first_index + node->length)
25 {
26 return 0;
27 }
28 else
29 {
30 return -1;
31 }
32}
33
34static Eina_Rbtree_Direction _shallow_rbtree_compare(Efl_Ui_Tree_View_Seg_Array_Node const* left,
35 Efl_Ui_Tree_View_Seg_Array_Node const* right, void* data EINA_UNUSED)
36{
37 if (left->shallow_first_index < right->shallow_first_index)
38 return EINA_RBTREE_LEFT;
39 else
40 return EINA_RBTREE_RIGHT;
41}
42
43static void
44_free_node(Efl_Ui_Tree_View_Seg_Array_Node* node, void* data EINA_UNUSED)
45{
46 int i = 0;
47
48 while (i < node->length)
49 {
50 Efl_Ui_Tree_View_Item* item = node->pointers[i];
51 if (item->segarray)
52 {
53 efl_ui_tree_view_seg_array_flush(item->segarray);
54 efl_unref(item->segarray);
55 }
56 efl_unref(item->model);
57 free(item);
58 ++i;
59 }
60
61 free(node);
62}
63
64static Efl_Ui_Tree_View_Seg_Array_Node*
65_alloc_node(Efl_Ui_Tree_View_Seg_Array_Data* pd, int shallow_first_index, int linearized_first_index)
66{
67 Efl_Ui_Tree_View_Seg_Array_Node* node;
68 node = calloc(1, sizeof(Efl_Ui_Tree_View_Seg_Array_Node) + pd->step_size*sizeof(Efl_Ui_Tree_View_Item*));
69 node->linearized_first_index = linearized_first_index;
70 node->shallow_first_index = shallow_first_index;
71 node->max = pd->step_size;
72 node->pd = pd;
73 pd->root = (void*)eina_rbtree_inline_insert(EINA_RBTREE_GET(pd->root), EINA_RBTREE_GET(node),
74 EINA_RBTREE_CMP_NODE_CB(&_shallow_rbtree_compare), NULL);
75 pd->node_count++;
76 return node;
77}
78
79EOLIAN static void
80_efl_ui_tree_view_seg_array_flush(Eo* obj EINA_UNUSED, Efl_Ui_Tree_View_Seg_Array_Data *pd)
81{
82 if (pd->root)
83 eina_rbtree_delete(EINA_RBTREE_GET(pd->root), EINA_RBTREE_FREE_CB(_free_node), NULL);
84
85 pd->root = NULL;
86 pd->node_count = 0;
87 pd->count = 0;
88}
89
90static Efl_Ui_Tree_View_Item* _create_item_partial(Efl_Model* model, Efl_Ui_Tree_View_Item* parent)
91{
92 Eina_Value *v;
93 Efl_Ui_Tree_View_Item* item;
94
95 item = calloc(1, sizeof(Efl_Ui_Tree_View_Item));
96 item->parent = parent;
97 item->depth = 1;
98
99 if (parent)
100 item->depth += parent->depth;
101
102 v = eina_value_uint_new(item->depth);
103 item->model = efl_new(EFL_UI_TREE_VIEW_SEG_ARRAY_DEPTH_MODEL_CLASS,
104 efl_ui_view_model_set(efl_added, model),
105 efl_model_property_set(efl_added, "depth", v));
106 eina_value_free(v);
107
108 return item;
109}
110
111EOLIAN static Efl_Ui_Tree_View_Item*
112_efl_ui_tree_view_seg_array_remove(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Seg_Array_Data *pd EINA_UNUSED, int index EINA_UNUSED)
113{
114 return NULL;
115}
116
117static void
118_efl_ui_tree_view_seg_array_insert_at_node(Efl_Ui_Tree_View_Seg_Array_Data* pd, int shallow_index, Efl_Ui_Tree_View_Item* item, Efl_Ui_Tree_View_Seg_Array_Node* node)
119{
120 Efl_Ui_Tree_View_Seg_Array_Node* before_node;
121 int shallow_index_pred, pos = 0;
122 Eina_Iterator* iterator;
123
124 assert (item->shallow_offset == 0);
125 assert (item->linearized_offset == 0);
126
127 if (node && node->length != node->max && (shallow_index - node->shallow_first_index) <= node->length)
128 {
129 assert(node->length != node->max);
130
131 pos = shallow_index - node->shallow_first_index;
132 item->tree_node = node;
133 item->shallow_offset = pos;
134
135 assert(pos == node->length);
136 if (pos < node->length)
137 memmove(&node->pointers[pos], &node->pointers[pos+1], sizeof(node->pointers[pos])*(node->length - pos));
138
139 node->pointers[pos] = item;
140 if (pos)
141 item->linearized_offset = node->pointers[pos-1]->linearized_offset + node->pointers[pos-1]->children_count + 1;
142
143 node->length++;
144 }
145 else
146 {
147 node = _alloc_node(pd, shallow_index, 0u);
148 node->pointers[0] = item;
149 node->length++;
150 item->shallow_offset = 0;
151 item->tree_node = node;
152
153 shallow_index_pred = shallow_index ? shallow_index - 1 : 0;
154
155 before_node = (void*)eina_rbtree_inline_lookup(EINA_RBTREE_GET(pd->root),
156 &shallow_index_pred, sizeof(shallow_index_pred),
157 &_shallow_search_lookup_cb, NULL);
158 if (before_node == node)
159 {
160 node->linearized_first_index = 0u;
161 assert (node->shallow_first_index == 0);
162 }
163 else
164 {
165 assert (node->shallow_first_index > before_node->shallow_first_index);
166 assert (node->shallow_first_index == before_node->shallow_first_index
167 + before_node->pointers[before_node->length-1]->shallow_offset + 1);
168 node->linearized_first_index = before_node->linearized_first_index;
169 if (before_node->length)
170 node->linearized_first_index += before_node->pointers[before_node->length-1]->linearized_offset
171 + before_node->pointers[before_node->length-1]->children_count + 1;
172 }
173 }
174
175 int i = node->linearized_first_index;
176 iterator = eina_rbtree_iterator_infix((void*)pd->root);
177 while (eina_iterator_next(iterator, (void**)&node))
178 if (node->linearized_first_index > i)
179 {
180 node->shallow_first_index++;
181 node->linearized_first_index++;
182 }
183 eina_iterator_free(iterator);
184 pd->count++;
185}
186
187EOLIAN static void
188_efl_ui_tree_view_seg_array_fix_offset (Efl_Ui_Tree_View_Item* current)
189{
190 Efl_Ui_Tree_View_Seg_Array_Node *node;
191 Efl_Ui_Tree_View_Item* item;
192 Eina_Iterator* iterator;
193 int i;
194 EINA_SAFETY_ON_NULL_RETURN(current);
195
196 // need to fix size
197 current->children_count++;
198 node = current->tree_node;
199
200 EINA_SAFETY_ON_NULL_RETURN(node);
201 EINA_SAFETY_ON_NULL_RETURN(node->pd);
202
203 i = current->shallow_offset + 1;
204 while (i < node->length)
205 {
206 item = node->pointers[i];
207 item->linearized_offset++;
208 i++;
209 }
210
211 i = node->linearized_first_index;
212 iterator = eina_rbtree_iterator_infix((void*)node->pd->root);
213 while (eina_iterator_next(iterator, (void**)&node))
214 if (node->linearized_first_index > i)
215 node->linearized_first_index++;
216
217 eina_iterator_free(iterator);
218 if (current->parent)
219 _efl_ui_tree_view_seg_array_fix_offset(current->parent);
220}
221
222EOLIAN static void
223_efl_ui_tree_view_seg_array_insert(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Seg_Array_Data* pd, Efl_Ui_Tree_View_Item* parent, int shallow_index, Efl_Model* model)
224{
225 Efl_Ui_Tree_View_Seg_Array_Node *next, *node = NULL;
226 Efl_Ui_Tree_View_Seg_Array_Data* priv = pd;
227 Efl_Ui_Tree_View_Item* item;
228 Eina_Iterator* iterator;
229
230 item = _create_item_partial(model, parent);
231
232 if (parent)
233 {
234 if (!parent->segarray)
235 parent->segarray = efl_new(EFL_UI_TREE_VIEW_SEG_ARRAY_CLASS,
236 efl_ui_tree_view_seg_array_setup(efl_added, pd->step_size));
237
238 _efl_ui_tree_view_seg_array_fix_offset (parent);
239 pd->count++;
240 priv = efl_data_scope_get(parent->segarray, EFL_UI_TREE_VIEW_SEG_ARRAY_CLASS);
241 }
242
243 iterator = eina_rbtree_iterator_infix((void*)priv->root);
244 while (eina_iterator_next(iterator, (void**)&next))
245 {
246 if (next->shallow_first_index > shallow_index)
247 break;
248 node = next;
249 }
250 eina_iterator_free(iterator);
251
252 _efl_ui_tree_view_seg_array_insert_at_node(priv, shallow_index, item, node);
253}
254
255EOLIAN static int
256_efl_ui_tree_view_seg_array_count(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Seg_Array_Data* pd)
257{
258 return pd->count;
259}
260
261typedef struct _Efl_Ui_Tree_View_Segarray_Eina_Accessor_Shallow
262{
263 Eina_Accessor vtable;
264 Efl_Ui_Tree_View_Seg_Array_Data* segarray;
265} Efl_Ui_Tree_View_Segarray_Eina_Accessor_Shallow;
266
267static Eina_Bool
268_efl_ui_tree_view_seg_array_accessor_shallow_get_at(Efl_Ui_Tree_View_Segarray_Eina_Accessor_Shallow* acc,
269 int idx, void** data)
270{
271 Efl_Ui_Tree_View_Seg_Array_Node* node;
272 node = (void*)eina_rbtree_inline_lookup(EINA_RBTREE_GET(acc->segarray->root),
273 &idx, sizeof(idx), &_shallow_search_lookup_cb, NULL);
274 if (node && (node->shallow_first_index <= idx && node->shallow_first_index + node->length > idx))
275 {
276 int i = idx - node->shallow_first_index;
277 Efl_Ui_Tree_View_Item* item = node->pointers[i];
278 *data = item;
279 return EINA_TRUE;
280 }
281 return EINA_FALSE;
282}
283
284EOLIAN static void
285_efl_ui_tree_view_seg_array_setup(Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Seg_Array_Data *pd, int size)
286{
287 pd->step_size = size;
288}
289
290EOLIAN static Eo *
291_efl_ui_tree_view_seg_array_efl_object_constructor(Eo *obj, Efl_Ui_Tree_View_Seg_Array_Data *pd EINA_UNUSED)
292{
293 obj = efl_constructor(efl_super(obj, MY_CLASS));
294
295 return obj;
296}
297
298EOLIAN static void
299_efl_ui_tree_view_seg_array_efl_object_destructor(Eo *obj, Efl_Ui_Tree_View_Seg_Array_Data *pd)
300{
301 if (pd->root)
302 eina_rbtree_delete(EINA_RBTREE_GET(pd->root), EINA_RBTREE_FREE_CB(_free_node), NULL);
303
304 pd->root = NULL;
305 efl_destructor(efl_super(obj, MY_CLASS));
306}
307
308static void*
309_efl_ui_tree_view_seg_array_accessor_shallow_get_container(Efl_Ui_Tree_View_Segarray_Eina_Accessor_Shallow* acc EINA_UNUSED)
310{
311 return NULL;
312}
313
314static void
315_efl_ui_tree_view_seg_array_accessor_shallow_free(Efl_Ui_Tree_View_Segarray_Eina_Accessor_Shallow* acc EINA_UNUSED)
316{
317 free(acc);
318}
319
320static Eina_Bool
321_efl_ui_tree_view_seg_array_accessor_shallow_lock(Efl_Ui_Tree_View_Segarray_Eina_Accessor_Shallow* acc EINA_UNUSED)
322{
323 return EINA_FALSE;
324}
325
326static Eina_Bool
327_efl_ui_tree_view_seg_array_accessor_shallow_unlock(Efl_Ui_Tree_View_Segarray_Eina_Accessor_Shallow* acc EINA_UNUSED)
328{
329 return EINA_FALSE;
330}
331
332static Eina_Accessor*
333_efl_ui_tree_view_seg_array_accessor_shallow_clone(Efl_Ui_Tree_View_Segarray_Eina_Accessor_Shallow* acc EINA_UNUSED)
334{
335 return &acc->vtable;
336}
337
338static void
339_efl_ui_tree_view_seg_array_accessor_shallow_setup(Efl_Ui_Tree_View_Segarray_Eina_Accessor_Shallow* acc, Efl_Ui_Tree_View_Seg_Array_Data* segarray)
340{
341 EINA_MAGIC_SET(&acc->vtable, EINA_MAGIC_ACCESSOR);
342 acc->vtable.version = EINA_ACCESSOR_VERSION;
343 acc->vtable.get_at = FUNC_ACCESSOR_GET_AT(_efl_ui_tree_view_seg_array_accessor_shallow_get_at);
344 acc->vtable.get_container = FUNC_ACCESSOR_GET_CONTAINER(_efl_ui_tree_view_seg_array_accessor_shallow_get_container);
345 acc->vtable.free = FUNC_ACCESSOR_FREE(_efl_ui_tree_view_seg_array_accessor_shallow_free);
346 acc->vtable.lock = FUNC_ACCESSOR_LOCK(_efl_ui_tree_view_seg_array_accessor_shallow_lock);
347 acc->vtable.unlock = FUNC_ACCESSOR_LOCK(_efl_ui_tree_view_seg_array_accessor_shallow_unlock);
348 acc->vtable.clone = FUNC_ACCESSOR_CLONE(_efl_ui_tree_view_seg_array_accessor_shallow_clone);
349 acc->segarray = segarray;
350}
351
352EOLIAN static Eina_Accessor*
353_efl_ui_tree_view_seg_array_shallow_accessor_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Seg_Array_Data* pd)
354{
355 Efl_Ui_Tree_View_Segarray_Eina_Accessor_Shallow* acc = calloc(1, sizeof(Efl_Ui_Tree_View_Segarray_Eina_Accessor_Shallow));
356 _efl_ui_tree_view_seg_array_accessor_shallow_setup(acc, pd);
357 return &acc->vtable;
358}
359
360EOLIAN static Eina_Accessor*
361_efl_ui_tree_view_seg_array_linearized_accessor_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Seg_Array_Data* pd EINA_UNUSED)
362{
363 return efl_ui_tree_view_seg_array_shallow_accessor_get (obj);
364}
365
366typedef struct _Efl_Ui_Tree_View_Segarray_Node_Accessor
367{
368 Eina_Accessor vtable;
369 Efl_Ui_Tree_View_Seg_Array_Data* segarray;
370 Eina_Iterator* pre_iterator;
371 Efl_Ui_Tree_View_Seg_Array_Node* current_node;
372 int current_index;
373} Efl_Ui_Tree_View_Segarray_Node_Accessor;
374
375static Eina_Bool
376_efl_ui_tree_view_seg_array_node_accessor_get_at(Efl_Ui_Tree_View_Segarray_Node_Accessor* acc,
377 int idx, void** data)
378{
379 if (idx == acc->current_index && acc->current_node)
380 {
381 (*data) = acc->current_node;
382 }
383 else
384 {
385 if (acc->current_index >= idx || !acc->current_node)
386 {
387 eina_iterator_free(acc->pre_iterator);
388 acc->pre_iterator = NULL;
389 acc->current_node = NULL;
390 acc->current_index = -1;
391 }
392
393 if (!acc->pre_iterator)
394 acc->pre_iterator = eina_rbtree_iterator_infix((void*)acc->segarray->root);
395
396 for (;acc->current_index != idx;++acc->current_index)
397 {
398 if (!eina_iterator_next(acc->pre_iterator, (void**)&acc->current_node))
399 {
400 --acc->current_index;
401 return EINA_FALSE;
402 }
403 }
404
405 (*data) = acc->current_node;
406 return EINA_TRUE;
407 }
408 return EINA_FALSE;
409}
410
411static void*
412_efl_ui_tree_view_seg_array_node_accessor_get_container(Efl_Ui_Tree_View_Segarray_Node_Accessor* acc EINA_UNUSED)
413{
414 return NULL;
415}
416
417static void
418_efl_ui_tree_view_seg_array_node_accessor_free(Efl_Ui_Tree_View_Segarray_Node_Accessor* acc EINA_UNUSED)
419{
420 if (acc->pre_iterator)
421 eina_iterator_free(acc->pre_iterator);
422 free(acc);
423}
424
425static Eina_Bool
426_efl_ui_tree_view_seg_array_node_accessor_lock(Efl_Ui_Tree_View_Segarray_Node_Accessor* acc EINA_UNUSED)
427{
428 return EINA_FALSE;
429}
430
431static Eina_Bool
432_efl_ui_tree_view_seg_array_node_accessor_unlock(Efl_Ui_Tree_View_Segarray_Node_Accessor* acc EINA_UNUSED)
433{
434 return EINA_FALSE;
435}
436
437static Eina_Accessor*
438_efl_ui_tree_view_seg_array_node_accessor_clone(Efl_Ui_Tree_View_Segarray_Node_Accessor* acc EINA_UNUSED)
439{
440 return &acc->vtable;
441}
442
443static void
444_efl_ui_tree_view_seg_array_node_accessor_setup(Efl_Ui_Tree_View_Segarray_Node_Accessor* acc, Efl_Ui_Tree_View_Seg_Array_Data* segarray)
445{
446 EINA_MAGIC_SET(&acc->vtable, EINA_MAGIC_ACCESSOR);
447 acc->vtable.version = EINA_ACCESSOR_VERSION;
448 acc->vtable.get_at = FUNC_ACCESSOR_GET_AT(_efl_ui_tree_view_seg_array_node_accessor_get_at);
449 acc->vtable.get_container = FUNC_ACCESSOR_GET_CONTAINER(_efl_ui_tree_view_seg_array_node_accessor_get_container);
450 acc->vtable.free = FUNC_ACCESSOR_FREE(_efl_ui_tree_view_seg_array_node_accessor_free);
451 acc->vtable.lock = FUNC_ACCESSOR_LOCK(_efl_ui_tree_view_seg_array_node_accessor_lock);
452 acc->vtable.unlock = FUNC_ACCESSOR_LOCK(_efl_ui_tree_view_seg_array_node_accessor_unlock);
453 acc->vtable.clone = FUNC_ACCESSOR_CLONE(_efl_ui_tree_view_seg_array_node_accessor_clone);
454 acc->segarray = segarray;
455 acc->pre_iterator = NULL;
456 acc->current_index = -1;
457 acc->current_node = NULL;
458}
459
460EOLIAN static Eina_Accessor*
461_efl_ui_tree_view_seg_array_node_accessor_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tree_View_Seg_Array_Data* pd)
462{
463 Efl_Ui_Tree_View_Segarray_Node_Accessor* acc = calloc(1, sizeof(Efl_Ui_Tree_View_Segarray_Node_Accessor));
464 _efl_ui_tree_view_seg_array_node_accessor_setup(acc, pd);
465 return &acc->vtable;
466}
467
468int efl_ui_tree_view_item_index_get(Efl_Ui_Tree_View_Item* item)
469{
470 Efl_Ui_Tree_View_Seg_Array_Node* node = item->tree_node;
471 return item->shallow_offset + node->shallow_first_index;
472}
473
474#include "efl_ui_tree_view_seg_array.eo.c"
diff --git a/src/lib/elementary/efl_ui_tree_view_seg_array.eo b/src/lib/elementary/efl_ui_tree_view_seg_array.eo
new file mode 100644
index 0000000000..81873c5a8c
--- /dev/null
+++ b/src/lib/elementary/efl_ui_tree_view_seg_array.eo
@@ -0,0 +1,63 @@
1import efl_ui_tree_view_model;
2
3class Efl.Ui.Tree_View_Seg_Array (Efl.Object)
4{
5 methods {
6 @property shallow_accessor {
7 get {
8 [[ Get a Seg_Array List items accessor ]]
9 }
10 values {
11 acc: accessor<ptr(Efl.Ui.Tree_View_Item)>;
12 }
13 }
14 @property linearized_accessor {
15 get {
16 [[ Get a Seg_Array List items accessor ]]
17 }
18 values {
19 acc: accessor<ptr(Efl.Ui.Tree_View_Item)>;
20 }
21 }
22 @property node_accessor {
23 get {
24 [[ Get a Seg_Array node accessor ]]
25 }
26 values {
27 acc: accessor<ptr(Efl.Ui.Tree_View_Seg_Array_Node)>;
28 }
29 }
30 count {
31 [[ Get the number of items in Seg_Array tree ]]
32 return: int;
33 }
34 setup {
35 [[ Configure a step of Seg_Array tree, this is the max node size ]]
36 params {
37 @in initial_step_size: int;
38 }
39 }
40 flush {
41 [[ flush the Seg_Array tree ]]
42 }
43 insert {
44 [[ Insert a new model in Seg_Array tree at index position ]]
45 params {
46 @in parent: ptr(Efl.Ui.Tree_View_Item);
47 @in index: int;
48 @in model: Efl.Model;
49 }
50 }
51 remove {
52 [[ Remove the item at index position in Seg_Array tree ]]
53 params {
54 @in index: int;
55 }
56 return: ptr(Efl.Ui.Tree_View_Item) @owned;
57 }
58 }
59 implements {
60 Efl.Object.constructor;
61 Efl.Object.destructor;
62 }
63}
diff --git a/src/lib/elementary/efl_ui_tree_view_seg_array.h b/src/lib/elementary/efl_ui_tree_view_seg_array.h
new file mode 100644
index 0000000000..e3abb054e0
--- /dev/null
+++ b/src/lib/elementary/efl_ui_tree_view_seg_array.h
@@ -0,0 +1,38 @@
1#ifndef EFL_UI_TREE_SEG_ARRAY_H
2#define EFL_UI_TREE_SEG_ARRAY_H
3
4#include <Elementary.h>
5
6typedef struct _Efl_Ui_Tree_View_Item Efl_Ui_Tree_View_Item;
7typedef struct _Efl_Ui_Tree_View_Seg_Array_Node Efl_Ui_Tree_View_Seg_Array_Node;
8
9typedef struct _Efl_Ui_Tree_View_Seg_Array_Data
10{
11 Efl_Ui_Tree_View_Seg_Array_Node *root;
12
13 int step_size;
14 int node_count;
15 int count;
16} Efl_Ui_Tree_View_Seg_Array_Data;
17
18struct _Efl_Ui_Tree_View_Seg_Array_Node
19{
20 EINA_RBTREE;
21
22 int length;
23 int max;
24 int linearized_first_index, shallow_first_index;
25
26 void* layout_data;
27 Efl_Ui_Tree_View_Seg_Array_Data *pd;
28 Efl_Ui_Tree_View_Item* pointers[0];
29};
30
31
32#define EFL_UI_TREE_VIEW_SEG_ARRAY_POS_GET(_item) \
33 _item->shallow_offset + ((Efl_Ui_Tree_View_Seg_Array_Node*)_item->tree_node)->shallow_first_index
34
35#define EFL_UI_TREE_VIEW_SEG_ARRAY_LINEAR_POS_GET(_item) \
36 _item->linearized_offset + ((Efl_Ui_Tree_View_Seg_Array_Node*)_item->tree_node)->linearized_first_index
37
38#endif
diff --git a/src/lib/elementary/efl_ui_tree_view_seg_array_depth_model.c b/src/lib/elementary/efl_ui_tree_view_seg_array_depth_model.c
new file mode 100644
index 0000000000..49209a1e48
--- /dev/null
+++ b/src/lib/elementary/efl_ui_tree_view_seg_array_depth_model.c
@@ -0,0 +1,78 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#include "Eina.h"
6#include <Efl.h>
7#include <Ecore.h>
8#include "Eo.h"
9#include <assert.h>
10
11#define MY_CLASS EFL_UI_TREE_VIEW_SEG_ARRAY_DEPTH_MODEL_CLASS
12#define MY_CLASS_NAME "Efl.Ui.Tree_View_Seg_Array_Depth_Model"
13
14#include "efl_ui_tree_view_seg_array_depth_model.eo.h"
15#include "efl_model_accessor_view_private.h"
16#include "efl_model_composite_private.h"
17
18typedef struct _Efl_Ui_Tree_View_Seg_Array_Depth_Model_Data
19{
20 unsigned int depth;
21 Eina_Bool readonly;
22
23} Efl_Ui_Tree_View_Seg_Array_Depth_Model_Data;
24
25EOLIAN static Efl_Object *
26_efl_ui_tree_view_seg_array_depth_model_efl_object_constructor(Eo *obj, Efl_Ui_Tree_View_Seg_Array_Depth_Model_Data *pd)
27{
28 obj = efl_constructor(efl_super(obj, MY_CLASS));
29 pd->readonly = EINA_FALSE;
30
31 return obj;
32}
33
34EOLIAN static Efl_Object *
35_efl_ui_tree_view_seg_array_depth_model_efl_object_finalize(Eo *obj, Efl_Ui_Tree_View_Seg_Array_Depth_Model_Data *pd)
36{
37 pd->readonly = EINA_TRUE;
38
39 return obj;
40}
41
42EOLIAN static Eina_Value *
43_efl_ui_tree_view_seg_array_depth_model_efl_model_property_get(const Eo *obj,
44 Efl_Ui_Tree_View_Seg_Array_Depth_Model_Data *pd,
45 const char *property)
46{
47 if (strcmp("depth", property))
48 return efl_model_property_get(efl_super(obj, MY_CLASS), property);
49
50 return eina_value_uint_new(pd->depth);
51}
52
53EOLIAN static Eina_Future *
54_efl_ui_tree_view_seg_array_depth_model_efl_model_property_set(Eo *obj,
55 Efl_Ui_Tree_View_Seg_Array_Depth_Model_Data *pd,
56 const char *property, Eina_Value *value)
57{
58 if (strcmp("depth", property))
59 return efl_model_property_set(efl_super(obj, MY_CLASS), property, value);
60
61 if (!pd->readonly && eina_value_uint_get(value, &pd->depth))
62 return efl_loop_future_resolved(obj, eina_value_uint_init(pd->depth));
63 else
64 return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_READ_ONLY);
65}
66
67static Eina_Iterator *
68_efl_ui_tree_view_seg_array_depth_model_efl_model_properties_get(const Eo *obj,
69 Efl_Ui_Tree_View_Seg_Array_Depth_Model_Data *pd EINA_UNUSED)
70{
71 EFL_MODEL_COMPOSITE_PROPERTIES_SUPER(props,
72 obj, MY_CLASS,
73 NULL,
74 "depth");
75 return props;
76}
77
78#include "efl_ui_tree_view_seg_array_depth_model.eo.c"
diff --git a/src/lib/elementary/efl_ui_tree_view_seg_array_depth_model.eo b/src/lib/elementary/efl_ui_tree_view_seg_array_depth_model.eo
new file mode 100644
index 0000000000..e01ae1773b
--- /dev/null
+++ b/src/lib/elementary/efl_ui_tree_view_seg_array_depth_model.eo
@@ -0,0 +1,11 @@
1import efl_ui_tree_view_model;
2
3class Efl.Ui.Tree_View_Seg_Array_Depth_Model (Efl.Model_Composite)
4{
5 implements {
6 Efl.Object.constructor;
7 Efl.Object.finalize;
8 Efl.Model.properties { get; }
9 Efl.Model.property { get; set; }
10 }
11}