summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLarry Jr <larry.olj@gmail.com>2017-01-31 18:17:58 -0200
committerLarry Jr <larry.olj@gmail.com>2017-02-01 14:15:11 -0200
commit84e32acab1288ae2176217fdb6ce1ad57ae94a4f (patch)
treefe07c0f9394518e36132b303383a1ec9cf09e93b
parent928091bedbcb1bb3166f680bcd192ef32677fc3b (diff)
efl: Added efl_model and efl_ui_view classes
Efl.Model.Container and Efl.Model.Item to efl/interfaces are used to create Efl.Model objects with predefined property values. This is useful to any situation where we want an Efl.Model with explicit defined property values. Efl.Ui.View and Efl.Ui.Factory are used to connect Efl.Models with Widgets, Elm.Layout and Efl.Ui.Image has changed to use news interfaces
-rw-r--r--src/Makefile_Ecore.am7
-rw-r--r--src/Makefile_Efl.am34
-rw-r--r--src/Makefile_Elementary.am2
-rw-r--r--src/examples/elementary/Makefile.am2
-rw-r--r--src/examples/elementary/layout_model_connect.c176
-rw-r--r--src/lib/ecore/Ecore_Eo.h14
-rw-r--r--src/lib/ecore/efl_model_container.c298
-rw-r--r--src/lib/ecore/efl_model_container.eo60
-rw-r--r--src/lib/ecore/efl_model_container_item.c192
-rw-r--r--src/lib/ecore/efl_model_container_item.eo39
-rw-r--r--src/lib/ecore/efl_model_container_private.h32
-rw-r--r--src/lib/ecore/efl_model_item.c202
-rw-r--r--src/lib/ecore/efl_model_item.eo26
-rw-r--r--src/lib/efl/Efl.h5
-rw-r--r--src/lib/efl/Efl_Model_Common.h1
-rw-r--r--src/lib/efl/interfaces/efl_interfaces_main.c4
-rw-r--r--src/lib/efl/interfaces/efl_model_common.c6
-rw-r--r--src/lib/efl/interfaces/efl_ui_factory.eo19
-rw-r--r--src/lib/efl/interfaces/efl_ui_model_connect.eo11
-rw-r--r--src/lib/efl/interfaces/efl_ui_model_factory_connect.eo11
-rw-r--r--src/lib/efl/interfaces/efl_ui_view.eo12
-rw-r--r--src/lib/elementary/Elementary.h1
-rw-r--r--src/lib/elementary/efl_ui_image.c198
-rw-r--r--src/lib/elementary/efl_ui_image.eo5
-rw-r--r--src/lib/elementary/efl_ui_image_factory.c59
-rw-r--r--src/lib/elementary/efl_ui_image_factory.eo10
-rw-r--r--src/lib/elementary/efl_ui_widget_image.h5
-rw-r--r--src/lib/elementary/elm_layout.c320
-rw-r--r--src/lib/elementary/elm_layout.eo6
-rw-r--r--src/lib/elementary/elm_widget_layout.h4
-rw-r--r--src/lib/eo/eina_types.eot2
-rw-r--r--src/tests/efl/efl_suite.c51
-rw-r--r--src/tests/efl/efl_suite.h26
-rw-r--r--src/tests/efl/efl_test_model_container.c171
-rw-r--r--src/tests/elementary/elm_test_layout.c36
35 files changed, 2045 insertions, 2 deletions
diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am
index 7ebef696ce..3cb58b6b43 100644
--- a/src/Makefile_Ecore.am
+++ b/src/Makefile_Ecore.am
@@ -26,6 +26,9 @@ ecore_eolian_files_public = \
26ecore_eolian_files = \ 26ecore_eolian_files = \
27 $(ecore_eolian_files_public) \ 27 $(ecore_eolian_files_public) \
28 lib/ecore/efl_promise.eo \ 28 lib/ecore/efl_promise.eo \
29 lib/ecore/efl_model_item.eo \
30 lib/ecore/efl_model_container.eo \
31 lib/ecore/efl_model_container_item.eo \
29 $(ecore_eolian_files_legacy) 32 $(ecore_eolian_files_legacy)
30 33
31ecore_eolian_type_files = \ 34ecore_eolian_type_files = \
@@ -86,6 +89,10 @@ lib/ecore/efl_io_file.c \
86lib/ecore/efl_io_copier.c \ 89lib/ecore/efl_io_copier.c \
87lib/ecore/efl_io_buffered_stream.c \ 90lib/ecore/efl_io_buffered_stream.c \
88lib/ecore/efl_promise.c \ 91lib/ecore/efl_promise.c \
92lib/ecore/efl_model_item.c \
93lib/ecore/efl_model_container.c \
94lib/ecore/efl_model_container_item.c \
95lib/ecore/efl_model_container_private.h \
89lib/ecore/ecore_pipe.c \ 96lib/ecore/ecore_pipe.c \
90lib/ecore/ecore_poller.c \ 97lib/ecore/ecore_poller.c \
91lib/ecore/ecore_time.c \ 98lib/ecore/ecore_time.c \
diff --git a/src/Makefile_Efl.am b/src/Makefile_Efl.am
index 79f46611d0..faccdf5bac 100644
--- a/src/Makefile_Efl.am
+++ b/src/Makefile_Efl.am
@@ -43,6 +43,10 @@ efl_eolian_files = \
43 lib/efl/interfaces/efl_vpath_file_core.eo \ 43 lib/efl/interfaces/efl_vpath_file_core.eo \
44 lib/efl/interfaces/efl_ui_spin.eo \ 44 lib/efl/interfaces/efl_ui_spin.eo \
45 lib/efl/interfaces/efl_ui_progress.eo \ 45 lib/efl/interfaces/efl_ui_progress.eo \
46 lib/efl/interfaces/efl_ui_view.eo \
47 lib/efl/interfaces/efl_ui_model_connect.eo \
48 lib/efl/interfaces/efl_ui_factory.eo \
49 lib/efl/interfaces/efl_ui_model_factory_connect.eo \
46 lib/efl/interfaces/efl_screen.eo \ 50 lib/efl/interfaces/efl_screen.eo \
47 lib/efl/interfaces/efl_io_closer.eo \ 51 lib/efl/interfaces/efl_io_closer.eo \
48 lib/efl/interfaces/efl_io_positioner.eo \ 52 lib/efl/interfaces/efl_io_positioner.eo \
@@ -171,3 +175,33 @@ bin_efl_efl_debug_CPPFLAGS = -I$(top_builddir)/src/bin/efl @EINA_CFLAGS@ @ECORE_
171bin_efl_efl_debug_LDADD = @EFL_LIBS@ @USE_EINA_INTERNAL_LIBS@ @USE_ECORE_INTERNAL_LIBS@ @USE_ECORE_CON_INTERNAL_LIBS@ 175bin_efl_efl_debug_LDADD = @EFL_LIBS@ @USE_EINA_INTERNAL_LIBS@ @USE_ECORE_INTERNAL_LIBS@ @USE_ECORE_CON_INTERNAL_LIBS@
172bin_efl_efl_debug_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_ECORE_INTERNAL_LIBS@ @USE_ECORE_CON_INTERNAL_LIBS@ 176bin_efl_efl_debug_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_ECORE_INTERNAL_LIBS@ @USE_ECORE_CON_INTERNAL_LIBS@
173 177
178
179if EFL_ENABLE_TESTS
180
181check_PROGRAMS += tests/efl/efl_suite
182TESTS += tests/efl/efl_suite
183
184tests_efl_efl_suite_SOURCES = \
185tests/efl/efl_suite.c \
186tests/efl/efl_test_model_container.c \
187tests/efl/efl_suite.h
188
189tests_efl_efl_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
190-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/efl\" \
191-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/efl\" \
192@CHECK_CFLAGS@ \
193@ECORE_CFLAGS@ \
194@EFL_CFLAGS@
195
196
197tests_efl_efl_suite_LDADD = @CHECK_LIBS@ \
198@EFL_LIBS@ \
199@USE_EFL_LIBS@ \
200@USE_ECORE_LIBS@ -lecore
201
202tests_efl_efl_suite_DEPENDENCIES = \
203@USE_EFL_INTERNAL_LIBS@ \
204@USE_ECORE_INTERNAL_LIBS@
205
206endif
207
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index c3c685e11e..0f6973cae3 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -117,6 +117,7 @@ elm_public_eolian_files = \
117 lib/elementary/efl_ui_text_editable.eo \ 117 lib/elementary/efl_ui_text_editable.eo \
118 lib/elementary/efl_config_global.eo \ 118 lib/elementary/efl_config_global.eo \
119 lib/elementary/efl_ui_clock.eo \ 119 lib/elementary/efl_ui_clock.eo \
120 lib/elementary/efl_ui_image_factory.eo \
120 $(NULL) 121 $(NULL)
121 122
122# Private classes (not exposed or shipped) 123# Private classes (not exposed or shipped)
@@ -667,6 +668,7 @@ lib_elementary_libelementary_la_SOURCES = \
667 lib/elementary/efl_ui_text.c \ 668 lib/elementary/efl_ui_text.c \
668 lib/elementary/efl_ui_clock.c \ 669 lib/elementary/efl_ui_clock.c \
669 lib/elementary/efl_ui_clock_private.h \ 670 lib/elementary/efl_ui_clock_private.h \
671 lib/elementary/efl_ui_image_factory.c \
670 $(NULL) 672 $(NULL)
671 673
672 674
diff --git a/src/examples/elementary/Makefile.am b/src/examples/elementary/Makefile.am
index 6f7cd33d69..020f7076df 100644
--- a/src/examples/elementary/Makefile.am
+++ b/src/examples/elementary/Makefile.am
@@ -117,6 +117,7 @@ label_example_01.c \
117layout_example_01.c \ 117layout_example_01.c \
118layout_example_02.c \ 118layout_example_02.c \
119layout_example_03.c \ 119layout_example_03.c \
120layout_model_connect.c \
120list_example_01.c \ 121list_example_01.c \
121list_example_02.c \ 122list_example_02.c \
122list_example_03.c \ 123list_example_03.c \
@@ -318,6 +319,7 @@ label_example_01 \
318layout_example_01 \ 319layout_example_01 \
319layout_example_02 \ 320layout_example_02 \
320layout_example_03 \ 321layout_example_03 \
322layout_model_connect \
321list_example_01 \ 323list_example_01 \
322list_example_02 \ 324list_example_02 \
323list_example_03 \ 325list_example_03 \
diff --git a/src/examples/elementary/layout_model_connect.c b/src/examples/elementary/layout_model_connect.c
new file mode 100644
index 0000000000..012832c45b
--- /dev/null
+++ b/src/examples/elementary/layout_model_connect.c
@@ -0,0 +1,176 @@
1// gcc -o layout_model_connect layout_model_connect.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
15#define EFL_MODEL_TEST_FILENAME_PATH "/tmp"
16
17struct _Layout_Model_Data
18{
19 Eo *fileview;
20 Eo *model;
21 Evas_Object *label;
22 Evas_Object *entry;
23 Evas_Object *img;
24 Evas_Object *bt;
25};
26typedef struct _Layout_Model_Data Layout_Model_Data;
27
28static void
29_cleanup_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
30{
31 Layout_Model_Data *priv = (Layout_Model_Data*)data;
32 efl_unref(priv->fileview);
33 efl_unref(priv->model);
34}
35
36static void
37_list_selected_cb(void *data EINA_UNUSED, const Efl_Event *event)
38{
39 Layout_Model_Data *priv = data;
40 Eo *child = event->info;
41
42 printf("LIST selected model\n");
43 efl_ui_view_model_set(priv->label, child);
44 efl_ui_view_model_set(priv->entry, child);
45 efl_ui_view_model_set(priv->img, child);
46 efl_ui_view_model_set(priv->bt, child);
47}
48
49
50static void
51_update_cb(void *data, Evas_Object *obj, void *ev)
52{
53 Layout_Model_Data *priv = data;
54
55 const char *text = elm_object_text_get(priv->entry);
56 elm_layout_text_set(priv->label, "default", text);
57}
58
59static void
60_widget_init(Evas_Object *widget)
61{
62 evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
63 evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL);
64 evas_object_show(widget);
65}
66
67Evas_Object *
68_label_init(Evas_Object *win, Evas_Object *box, const char *text)
69{
70 Evas_Object *widget = elm_label_add(win);
71 elm_label_line_wrap_set(widget, ELM_WRAP_CHAR);
72 elm_object_text_set(widget, text);
73 elm_box_pack_end(box, widget);
74 evas_object_size_hint_weight_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL);
75 evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL);
76 evas_object_show(widget);
77
78 return widget;
79}
80
81
82static void
83_signal_cb(void *data,
84 Evas_Object *obj EINA_UNUSED,
85 const char *emission,
86 const char *source)
87{
88 printf(">> Signal callback emission='%s' source='%s'\n", emission, source);
89}
90
91EAPI_MAIN int
92elm_main(int argc, char **argv)
93{
94 Layout_Model_Data *priv;
95 Evas_Object *win, *panes, *bxr, *genlist;
96 Eo *img_factory;
97 char *dirname;
98
99 priv = alloca(sizeof(Layout_Model_Data));
100 memset(priv, 0, sizeof(Layout_Model_Data));
101
102 //win
103 win = elm_win_util_standard_add("viewlist", "Viewlist");
104 elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
105 elm_win_autodel_set(win, EINA_TRUE);
106
107 panes = elm_panes_add(win);
108 evas_object_size_hint_weight_set(panes, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
109 elm_win_resize_object_add(win, panes);
110
111 if (argv[1] != NULL) dirname = argv[1];
112 else dirname = EFL_MODEL_TEST_FILENAME_PATH;
113
114 priv->model = efl_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(efl_added, dirname));
115
116 genlist = elm_genlist_add(win);
117 priv->fileview = efl_add(ELM_VIEW_LIST_CLASS, NULL, elm_view_list_genlist_set(efl_added, genlist, ELM_GENLIST_ITEM_NONE, NULL));
118 elm_view_list_property_connect(priv->fileview, "filename", "elm.text");
119 elm_view_list_model_set(priv->fileview, priv->model);
120 _widget_init(genlist);
121 elm_object_part_content_set(panes, "left", genlist);
122 elm_obj_panes_content_left_size_set(panes, 0.3);
123 efl_event_callback_add(priv->fileview, ELM_VIEW_LIST_EVENT_MODEL_SELECTED, _list_selected_cb, priv);
124
125 bxr = elm_box_add(win);
126 _widget_init(bxr);
127 elm_object_part_content_set(panes, "right", bxr);
128
129 /*Label widget */
130
131 _label_init(win, bxr, "FILENAME:");
132 priv->label = _label_init(win, bxr, "");
133 efl_ui_model_connect(priv->label, "default", "path"); //connect "default" to "filename" property
134
135 /* Entry widget */
136 priv->entry = elm_entry_add(win);
137 efl_ui_model_connect(priv->entry, "elm.text", "path"); //connect "elm.text" to "path" property
138 elm_entry_single_line_set(priv->entry, EINA_TRUE);
139 elm_box_pack_end(bxr, priv->entry);
140 evas_object_size_hint_weight_set(priv->entry, EVAS_HINT_FILL, 0);
141 evas_object_size_hint_align_set(priv->entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
142 evas_object_show(priv->entry);
143
144 /* Button widget */
145 priv->bt = elm_button_add(win);
146 elm_box_pack_end(bxr, priv->bt);
147 elm_object_text_set(priv->bt, "update model");
148 evas_object_smart_callback_add(priv->bt, "clicked", _update_cb, priv);
149 edje_obj_signal_callback_add(priv->bt, "test*" , "*", _signal_cb, priv);
150 efl_ui_model_connect(priv->bt, "signal/test-%v", "size");
151 evas_object_show(priv->bt);
152
153 /* Image widget */
154 img_factory = efl_add(EFL_UI_IMAGE_FACTORY_CLASS, win);
155 efl_ui_model_connect(img_factory, "", "path"); //connect to "path" property
156 efl_ui_model_factory_connect(priv->bt, "icon", img_factory);
157
158 priv->img = efl_ui_factory_create(img_factory, NULL, win);
159 elm_box_pack_end(bxr, priv->img);
160 evas_object_size_hint_weight_set(priv->img, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
161 evas_object_size_hint_align_set(priv->img, EVAS_HINT_FILL, EVAS_HINT_FILL);
162 evas_object_show(priv->img);
163
164 evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _cleanup_cb, priv);
165 //showall
166 evas_object_resize(win, 800, 400);
167 evas_object_show(panes);
168 evas_object_show(win);
169
170 elm_run();
171 elm_shutdown();
172 ecore_shutdown();
173
174 return 0;
175}
176ELM_MAIN()
diff --git a/src/lib/ecore/Ecore_Eo.h b/src/lib/ecore/Ecore_Eo.h
index 1387afb344..1c29de392c 100644
--- a/src/lib/ecore/Ecore_Eo.h
+++ b/src/lib/ecore/Ecore_Eo.h
@@ -116,6 +116,20 @@ EAPI Efl_Future *efl_future_iterator_race(Eina_Iterator *it);
116 * @} 116 * @}
117 */ 117 */
118 118
119/**
120 * @ingroup Ecore_Model_Group
121 *
122 * @{
123 */
124
125#include "efl_model_item.eo.h"
126#include "efl_model_container.eo.h"
127#include "efl_model_container_item.eo.h"
128
129/**
130 * @}
131 */
132
119 133
120#ifdef __cplusplus 134#ifdef __cplusplus
121} 135}
diff --git a/src/lib/ecore/efl_model_container.c b/src/lib/ecore/efl_model_container.c
new file mode 100644
index 0000000000..69a5704353
--- /dev/null
+++ b/src/lib/ecore/efl_model_container.c
@@ -0,0 +1,298 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Efl.h>
6#include <Eina.h>
7#include <Eo.h>
8#include <Ecore.h>
9
10#include "efl_model_container_private.h"
11
12#define MY_CLASS EFL_MODEL_CONTAINER_CLASS
13
14void *
15_value_copy_alloc(void *v, const Eina_Value_Type *type)
16{
17 if (!v)
18 return v;
19
20 if (type == EINA_VALUE_TYPE_STRINGSHARE)
21 return (void*) eina_stringshare_ref(v);
22 else if (type == EINA_VALUE_TYPE_STRING)
23 return (void*) strdup(v);
24 else
25 {
26 void *ret = malloc(type->value_size);
27 memcpy(ret, v, type->value_size);
28 return ret;
29 }
30}
31
32void
33_value_free(void *v, const Eina_Value_Type *type)
34{
35 if (!v)
36 return;
37
38 if (type == EINA_VALUE_TYPE_STRINGSHARE)
39 return eina_stringshare_del(v);
40 else
41 free(v);
42}
43
44static void
45_values_free(Eina_Array *values, const Eina_Value_Type *type)
46{
47 unsigned int i;
48 void *v;
49 Eina_Array_Iterator it;
50 EINA_ARRAY_ITER_NEXT(values, i, v, it)
51 {
52 _value_free(v, type);
53 }
54 eina_array_free(values);
55}
56
57static Eina_Bool
58_stringshared_keys_free(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data EINA_UNUSED, void *fdata EINA_UNUSED)
59{
60 eina_stringshare_del(key);
61 return EINA_TRUE;
62}
63
64static void
65_property_data_free_cb(void *data)
66{
67 Child_Property_Data *cpd = data;
68 _values_free(cpd->property_values, cpd->property_type);
69 free(cpd);
70}
71
72static Efl_Object *
73_efl_model_container_efl_object_constructor(Eo *obj, Efl_Model_Container_Data *sd)
74{
75 obj = efl_constructor(efl_super(obj, MY_CLASS));
76 if (!obj)
77 return NULL;
78
79 sd->obj = obj;
80 sd->property_data = eina_hash_stringshared_new(_property_data_free_cb);
81 sd->defined_properties = eina_array_new(8);
82
83 return obj;
84}
85
86static void
87_efl_model_container_efl_object_destructor(Eo *obj, Efl_Model_Container_Data *sd)
88{
89 Efl_Model *child;
90
91 EINA_LIST_FREE(sd->children, child)
92 {
93 if (child)
94 {
95 efl_model_container_item_invalidate(child);
96 efl_parent_set(child, NULL);
97 }
98 }
99
100 eina_array_free(sd->defined_properties);
101
102 eina_hash_foreach(sd->property_data, _stringshared_keys_free, NULL);
103 eina_hash_free(sd->property_data);
104
105 efl_destructor(efl_super(obj, MY_CLASS));
106}
107
108static const Eina_Value_Type *
109_efl_model_container_child_property_value_type_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd, const char *property)
110{
111 Eina_Stringshare *sshared = eina_stringshare_add(property);
112 Child_Property_Data *cpd = eina_hash_find(sd->property_data, sshared);
113 eina_stringshare_del(sshared);
114 if (!cpd)
115 return NULL;
116
117 return cpd->property_type;
118}
119
120static Eina_Iterator *
121_efl_model_container_child_property_values_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd, const char *property)
122{
123 Eina_Stringshare *sshared = eina_stringshare_add(property);
124 Child_Property_Data *cpd = eina_hash_find(sd->property_data, sshared);
125 eina_stringshare_del(sshared);
126 if (!cpd)
127 return NULL;
128
129 return eina_array_iterator_new(cpd->property_values);
130}
131
132static Eina_Bool
133_efl_model_container_child_property_add(Eo *obj, Efl_Model_Container_Data *sd, const char *name, const Eina_Value_Type *type, Eina_Iterator *values)
134{
135 Eina_Array *arr = NULL;
136 void *data = NULL;
137 Eina_Stringshare *prop_name = NULL;
138 Child_Property_Data *cpd = NULL;
139 unsigned int i, in_count, children_count;
140
141 if (!type || !values)
142 {
143 EINA_LOG_WARN("Invalid input data");
144 eina_error_set(EFL_MODEL_ERROR_INCORRECT_VALUE);
145 return EINA_FALSE;
146 }
147
148 arr = eina_array_new(32);
149 if (!arr)
150 {
151 eina_error_set(EFL_MODEL_ERROR_UNKNOWN);
152 return EINA_FALSE;
153 }
154
155 EINA_ITERATOR_FOREACH(values, data)
156 {
157 void *new_data = _value_copy_alloc(data, type);
158 if ((data && !new_data) || !eina_array_push(arr, new_data))
159 {
160 if (new_data)
161 _value_free(new_data, type);
162 goto error;
163 }
164 }
165 eina_iterator_free(values);
166
167 prop_name = eina_stringshare_add(name);
168 cpd = eina_hash_find(sd->property_data, prop_name);
169 if (!cpd)
170 {
171 cpd = calloc(1, sizeof(Child_Property_Data));
172 if (!cpd)
173 goto error;
174
175 cpd->property_type = type;
176 cpd->property_values = arr;
177
178 if (!eina_array_push(sd->defined_properties, prop_name))
179 goto error;
180
181 if (!eina_hash_direct_add(sd->property_data, prop_name, cpd))
182 {
183 eina_array_pop(sd->defined_properties);
184 goto error;
185 }
186 }
187 else
188 {
189 eina_stringshare_del(prop_name);
190 _values_free(cpd->property_values, cpd->property_type);
191
192 cpd->property_type = type;
193 cpd->property_values = arr;
194 }
195
196 in_count = eina_array_count(arr);
197 children_count = eina_list_count(sd->children);
198
199 for (i = children_count; i < in_count; ++i)
200 {
201 Efl_Model_Children_Event cevt;
202 Efl_Model *child;
203
204 child = efl_add(EFL_MODEL_CONTAINER_ITEM_CLASS, obj,
205 efl_model_container_item_define(efl_added, sd, i));
206 sd->children = eina_list_append(sd->children, child);
207
208 cevt.child = child;
209 cevt.index = i;
210 efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILD_ADDED, &cevt);
211 }
212
213 if (in_count > children_count)
214 efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &in_count);
215
216 return EINA_TRUE;
217
218error:
219 if (prop_name)
220 eina_stringshare_del(prop_name);
221 if (cpd)
222 free(cpd);
223 if (arr)
224 _values_free(arr, type);
225 eina_error_set(EFL_MODEL_ERROR_UNKNOWN);
226 return EINA_FALSE;
227}
228
229static const Eina_Array *
230_efl_model_container_efl_model_properties_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED)
231{
232 return sd->defined_properties;
233}
234
235
236Efl_Future *
237_efl_model_container_efl_model_property_set(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED, const char *property EINA_UNUSED, const Eina_Value *value EINA_UNUSED)
238{
239 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
240 Efl_Future* future = efl_promise_future_get(promise);
241
242 efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
243 return future;
244}
245
246Efl_Future *
247_efl_model_container_efl_model_property_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED, const char *property EINA_UNUSED)
248{
249
250 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
251 Efl_Future* future = efl_promise_future_get(promise);
252
253 efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
254 return future;
255}
256
257static Efl_Future *
258_efl_model_container_efl_model_children_slice_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd, unsigned int start, unsigned int count)
259{
260 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
261 Efl_Future* future = efl_promise_future_get(promise);
262
263 Eina_Accessor* accessor = efl_model_list_slice(sd->children, start, count);
264 efl_promise_value_set(promise, accessor, (Eina_Free_Cb)&eina_accessor_free);
265
266 return future;
267}
268
269static Efl_Future *
270_efl_model_container_efl_model_children_count_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd)
271{
272 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
273 Efl_Future* future = efl_promise_future_get(promise);
274
275 unsigned int *count = calloc(1, sizeof(unsigned int));
276 *count = eina_list_count(sd->children);
277 efl_promise_value_set(promise, count, &free);
278
279 return future;
280}
281
282static Eo *
283_efl_model_container_efl_model_child_add(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED)
284{
285 EINA_LOG_WARN("child_add not supported by Efl.Model.Container");
286 eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED);
287
288 return NULL;
289}
290
291static void
292_efl_model_container_efl_model_child_del(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED, Eo *child EINA_UNUSED)
293{
294 EINA_LOG_WARN("child_del not supported by Efl.Model.Container");
295 eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED);
296}
297
298#include "efl_model_container.eo.c"
diff --git a/src/lib/ecore/efl_model_container.eo b/src/lib/ecore/efl_model_container.eo
new file mode 100644
index 0000000000..baee70735d
--- /dev/null
+++ b/src/lib/ecore/efl_model_container.eo
@@ -0,0 +1,60 @@
1import eina_types;
2
3class Efl.Model.Container (Efl.Object, Efl.Model)
4{
5 [[
6 Class used to create data models from Eina containers.
7
8 Each container supplied represent a series of property values, each item
9 being the property value for a child object (@Efl.Model.Container.Item).
10
11 The data in the given containers are copied and stored internally.
12
13 Several containers can be supplied, and the number of allocated children is
14 based on the container with the biggest size.
15 ]]
16 methods {
17 child_property_value_type_get {
18 [[Get the type of the given property.]]
19 params {
20 name: string; [[Property name]]
21 }
22 return: ptr(const(Eina.Value.Type)); [[Property type]]
23 }
24 child_property_values_get {
25 [[Get the values for the given property.]]
26 params {
27 name: string; [[Property name]]
28 }
29 return: free(own(iterator<void_ptr>), eina_iterator_free) @warn_unused;
30 [[The currently wrapped values]]
31 }
32 child_property_add {
33 [[Add the given property to child objects and supply the values.
34
35 Each item will represent the value of the given property in the
36 respective child within the data model.
37
38 New children objects are allocated as necessary.
39
40 Value type is required for compatibility with the @Efl.Model API.]]
41 params {
42 name: string; [[Property name]]
43 type: ptr(const(Eina.Value.Type)); [[Property type]]
44 values: own(iterator<const(void_ptr)>); [[Values to be added]]
45 }
46 return: bool; [[$true on success, $false otherwise]]
47 }
48 }
49 implements {
50 Efl.Object.constructor;
51 Efl.Object.destructor;
52 Efl.Model.properties { get; }
53 Efl.Model.property_set;
54 Efl.Model.property_get;
55 Efl.Model.child_add;
56 Efl.Model.child_del;
57 Efl.Model.children_slice_get;
58 Efl.Model.children_count_get;
59 }
60}
diff --git a/src/lib/ecore/efl_model_container_item.c b/src/lib/ecore/efl_model_container_item.c
new file mode 100644
index 0000000000..945c0c9ce0
--- /dev/null
+++ b/src/lib/ecore/efl_model_container_item.c
@@ -0,0 +1,192 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Efl.h>
6#include <Ecore.h>
7
8#include "efl_model_container_private.h"
9
10#define MY_CLASS EFL_MODEL_CONTAINER_ITEM_CLASS
11
12static void
13_item_value_free_cb(void *data)
14{
15 eina_value_free(data);
16}
17
18EOLIAN static void
19_efl_model_container_item_define(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd, void *parent_data, unsigned int index)
20{
21 sd->parent_data = parent_data;
22 sd->index = index;
23}
24
25EOLIAN static void
26_efl_model_container_item_invalidate(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd)
27{
28 sd->parent_data = NULL;
29 sd->index = 0;
30}
31
32EOLIAN static const Eina_Array *
33_efl_model_container_item_efl_model_properties_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd)
34{
35 if (!sd->parent_data)
36 return NULL;
37
38 return sd->parent_data->defined_properties;
39}
40
41Efl_Future *
42_efl_model_container_item_efl_model_property_set(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd, const char *property, const Eina_Value *value)
43{
44 Eina_Stringshare *prop_name;
45 Child_Property_Data *cpd;
46 void *data, *new_data;
47 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
48 Efl_Future* future = efl_promise_future_get(promise);
49
50 if (!sd->parent_data)
51 {
52 efl_promise_failed_set(promise, EFL_MODEL_ERROR_INVALID_OBJECT);
53 return future;
54 }
55
56 prop_name = eina_stringshare_add(property);
57 cpd = eina_hash_find(sd->parent_data->property_data, prop_name);
58 eina_stringshare_del(prop_name);
59 if (!cpd || !cpd->property_values ||
60 sd->index >= eina_array_count_get(cpd->property_values))
61 {
62 efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
63 return future;
64 }
65
66 if (cpd->property_type != eina_value_type_get(value))
67 {
68 efl_promise_failed_set(promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
69 return future;
70 }
71
72 data = calloc(1, cpd->property_type->value_size);
73 if (!data || !eina_value_pget(value, data))
74 {
75 if (data)
76 free(data);
77 efl_promise_failed_set(promise, EFL_MODEL_ERROR_UNKNOWN);
78 return future;
79 }
80
81 new_data = _value_copy_alloc(data, cpd->property_type);
82 free(data);
83
84 _value_free(eina_array_data_get(cpd->property_values, sd->index), cpd->property_type);
85 eina_array_data_set(cpd->property_values, sd->index, new_data);
86
87 {
88 Eina_Value *v = eina_value_new(cpd->property_type);
89 if (v && eina_value_copy(value, v))
90 efl_promise_value_set(promise, v, _item_value_free_cb);
91 else
92 {
93 if (v)
94 eina_value_free(v);
95 efl_promise_failed_set(promise, EFL_MODEL_ERROR_UNKNOWN);
96 }
97 }
98
99 return future;
100}
101
102Efl_Future *
103_efl_model_container_item_efl_model_property_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd, const char *property)
104{
105 Eina_Stringshare *prop_name;
106 Child_Property_Data *cpd;
107 Eina_Value *value;
108 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
109 Efl_Future* future = efl_promise_future_get(promise);
110
111 if (!sd->parent_data)
112 {
113 efl_promise_failed_set(promise, EFL_MODEL_ERROR_INVALID_OBJECT);
114 return future;
115 }
116
117 prop_name = eina_stringshare_add(property);
118 cpd = eina_hash_find(sd->parent_data->property_data, prop_name);
119 eina_stringshare_del(prop_name);
120 if (!cpd || !cpd->property_values ||
121 sd->index >= eina_array_count_get(cpd->property_values))
122 {
123 efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
124 return future;
125 }
126
127 value = eina_value_new(cpd->property_type);
128 if (!value)
129 efl_promise_failed_set(promise, EFL_MODEL_ERROR_UNKNOWN);
130 else
131 {
132 Eina_Bool r = EINA_FALSE;
133 void *data = eina_array_data_get(cpd->property_values, sd->index);
134
135 if (cpd->property_type == EINA_VALUE_TYPE_STRINGSHARE ||
136 cpd->property_type == EINA_VALUE_TYPE_STRING)
137 r = eina_value_set(value, data);
138 else
139 r = eina_value_pset(value, data);
140
141 if (r)
142 efl_promise_value_set(promise, value, _item_value_free_cb);
143 else
144 {
145 efl_promise_failed_set(promise, EFL_MODEL_ERROR_UNKNOWN);
146 eina_value_free(value);
147 }
148 }
149 return future;
150}
151
152EOLIAN static Efl_Future *
153_efl_model_container_item_efl_model_children_slice_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd EINA_UNUSED, unsigned int start EINA_UNUSED, unsigned int count EINA_UNUSED)
154{
155 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
156 Efl_Future* future = efl_promise_future_get(promise);
157
158 efl_promise_value_set(promise, NULL, NULL);
159
160 return future;
161}
162
163EOLIAN static Efl_Future *
164_efl_model_container_item_efl_model_children_count_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd EINA_UNUSED)
165{
166 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
167 Efl_Future* future = efl_promise_future_get(promise);
168
169 unsigned int *count = calloc(1, sizeof(unsigned int));
170 *count = 0;
171 efl_promise_value_set(promise, count, &free);
172
173 return future;
174}
175
176EOLIAN static Eo *
177_efl_model_container_item_efl_model_child_add(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd EINA_UNUSED)
178{
179 EINA_LOG_WARN("child_add not supported by Efl.Model.Container.Item");
180 eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED);
181
182 return NULL;
183}
184
185EOLIAN static void
186_efl_model_container_item_efl_model_child_del(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd EINA_UNUSED, Eo *child EINA_UNUSED)
187{
188 EINA_LOG_WARN("child_del not supported by Efl.Model.Container.Item");
189 eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED);
190}
191
192#include "efl_model_container_item.eo.c"
diff --git a/src/lib/ecore/efl_model_container_item.eo b/src/lib/ecore/efl_model_container_item.eo
new file mode 100644
index 0000000000..94314357ad
--- /dev/null
+++ b/src/lib/ecore/efl_model_container_item.eo
@@ -0,0 +1,39 @@
1import eina_types;
2
3class Efl.Model.Container.Item (Efl.Object, Efl.Model)
4{
5 [[
6 Used as a child of @Efl.Model.Container.
7
8 Provides the @Efl.Model API for elements of @Efl.Model.Container.
9 Should not be used in another context, so do not manually create objects
10 of this class.
11 ]]
12 methods {
13 define {
14 [[Define @Efl.Model.Container.Item internal data.]]
15 params {
16 parent_data: void_ptr; [[Pointer to the private data of the
17 @Efl.Model.Container parent object.]]
18 index: uint; [[Index of this item within the @Efl.Model.Container
19 children.]]
20 }
21 }
22 invalidate {
23 [[Invalidate the object preventing it from using the given parent
24 data.]]
25 }
26 }
27 implements {
28 Efl.Model.properties { get; }
29 Efl.Model.property_set;
30 Efl.Model.property_get;
31 Efl.Model.child_add;
32 Efl.Model.child_del;
33 Efl.Model.children_slice_get;
34 Efl.Model.children_count_get;
35 }
36 constructors {
37 .define;
38 }
39}
diff --git a/src/lib/ecore/efl_model_container_private.h b/src/lib/ecore/efl_model_container_private.h
new file mode 100644
index 0000000000..0a0aad1be6
--- /dev/null
+++ b/src/lib/ecore/efl_model_container_private.h
@@ -0,0 +1,32 @@
1#ifndef EFL_MODEL_PRIVATE_H__
2# define EFL_MODEL_PRIVATE_H__
3
4typedef struct _Child_Property_Data Child_Property_Data;
5struct _Child_Property_Data
6{
7 const Eina_Value_Type *property_type;
8 Eina_Array *property_values;
9};
10
11typedef struct _Efl_Model_Container_Data Efl_Model_Container_Data;
12struct _Efl_Model_Container_Data
13{
14 Eo *obj;
15 Eina_Hash *property_data;
16 Eina_Array *defined_properties;
17 Eina_List *children;
18};
19
20
21typedef struct _Efl_Model_Container_Item_Data Efl_Model_Container_Item_Data;
22struct _Efl_Model_Container_Item_Data
23{
24 Efl_Model_Container_Data *parent_data;
25 unsigned int index;
26};
27
28void *_value_copy_alloc(void *v, const Eina_Value_Type *type);
29
30void _value_free(void *v, const Eina_Value_Type *type);
31
32#endif
diff --git a/src/lib/ecore/efl_model_item.c b/src/lib/ecore/efl_model_item.c
new file mode 100644
index 0000000000..d8566d9107
--- /dev/null
+++ b/src/lib/ecore/efl_model_item.c
@@ -0,0 +1,202 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Efl.h>
6#include <Ecore.h>
7
8#define MY_CLASS EFL_MODEL_ITEM_CLASS
9
10typedef struct _Efl_Model_Item_Data Efl_Model_Item_Data;
11struct _Efl_Model_Item_Data
12{
13 Eina_Hash *properties;
14 Eina_Array *defined_properties;
15 Eina_List *children;
16};
17
18static void
19_item_value_free_cb(void *data)
20{
21 eina_value_free(data);
22}
23
24static Eina_Bool
25_stringshared_keys_free(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data EINA_UNUSED, void *fdata EINA_UNUSED)
26{
27 eina_stringshare_del(key);
28 return EINA_TRUE;
29}
30
31static Efl_Object *
32_efl_model_item_efl_object_constructor(Eo *obj, Efl_Model_Item_Data *sd)
33{
34 obj = efl_constructor(efl_super(obj, MY_CLASS));
35 if (!obj)
36 return NULL;
37
38 sd->properties = eina_hash_stringshared_new(_item_value_free_cb);
39 sd->defined_properties = eina_array_new(8);
40
41 return obj;
42}
43
44static void
45_efl_model_item_efl_object_destructor(Eo *obj, Efl_Model_Item_Data *sd)
46{
47 Efl_Model *child;
48
49 EINA_LIST_FREE(sd->children, child)
50 {
51 if (child)
52 efl_parent_set(child, NULL);
53 }
54
55 eina_hash_foreach(sd->properties, _stringshared_keys_free, NULL);
56 eina_hash_free(sd->properties);
57
58 eina_array_free(sd->defined_properties);
59
60 efl_destructor(efl_super(obj, MY_CLASS));
61}
62
63EOLIAN static const Eina_Array *
64_efl_model_item_efl_model_properties_get(Eo *obj EINA_UNUSED, Efl_Model_Item_Data *sd)
65{
66 return sd->defined_properties;
67}
68
69
70static Efl_Future*
71_efl_model_item_efl_model_property_set(Eo *obj EINA_UNUSED, Efl_Model_Item_Data *sd, const char *property, const Eina_Value *value)
72{
73 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
74 Efl_Future* future = efl_promise_future_get(promise);
75
76 Eina_Stringshare *sshared = eina_stringshare_add(property);
77 Eina_Value *p_v = eina_hash_find(sd->properties, sshared);
78 if (p_v)
79 {
80 eina_stringshare_del(sshared);
81 if (!eina_value_copy(value, p_v))
82 goto err1;
83 }
84 else
85 {
86 if (!eina_array_push(sd->defined_properties, sshared))
87 goto err2;
88
89 p_v = eina_value_new(eina_value_type_get(value));
90 if (!p_v)
91 goto err3;
92
93 if (!eina_value_copy(value, p_v) ||
94 !eina_hash_direct_add(sd->properties, sshared, p_v))
95 goto err4;
96 }
97
98 efl_promise_value_set(promise, p_v, NULL);
99 return future;
100
101err4:
102 eina_value_free(p_v);
103err3:
104 eina_array_pop(sd->defined_properties);
105err2:
106 eina_stringshare_del(sshared);
107err1:
108 efl_promise_failed_set(promise, EFL_MODEL_ERROR_UNKNOWN);
109 return future;
110}
111
112static Efl_Future *
113_efl_model_item_efl_model_property_get(Eo *obj EINA_UNUSED, Efl_Model_Item_Data *sd, const char *property)
114{
115 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
116 Efl_Future *rfuture = efl_promise_future_get(promise);
117
118 Eina_Stringshare *sshare = eina_stringshare_add(property);
119 Eina_Value *p_v = eina_hash_find(sd->properties, sshare);
120 eina_stringshare_del(sshare);
121 if (p_v)
122 efl_promise_value_set(promise, p_v, NULL);
123 else
124 efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
125
126 return rfuture;
127}
128
129static Efl_Future *
130_efl_model_item_efl_model_children_slice_get(Eo *obj EINA_UNUSED, Efl_Model_Item_Data *sd, unsigned int start, unsigned int count)
131{
132 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
133 Efl_Future *rfuture = efl_promise_future_get(promise);
134
135 Eina_Accessor* accessor = efl_model_list_slice(sd->children, start, count);
136 efl_promise_value_set(promise, accessor, (Eina_Free_Cb)&eina_accessor_free);
137
138 return rfuture;
139}
140
141static Efl_Future *
142_efl_model_item_efl_model_children_count_get(Eo *obj EINA_UNUSED, Efl_Model_Item_Data *sd)
143{
144 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
145 Efl_Future *rfuture = efl_promise_future_get(promise);
146
147 unsigned int *count = calloc(1, sizeof(unsigned int));
148 *count = eina_list_count(sd->children);
149 efl_promise_value_set(promise, count, &free);
150
151 return rfuture;
152}
153
154static Eo *
155_efl_model_item_efl_model_child_add(Eo *obj, Efl_Model_Item_Data *sd)
156{
157 Efl_Model_Children_Event cevt;
158 Efl_Model *child = efl_add(EFL_MODEL_ITEM_CLASS, obj);
159 if (!child)
160 {
161 EINA_LOG_ERR("Could not allocate Efl.Model.Item");
162 eina_error_set(EFL_MODEL_ERROR_UNKNOWN);
163 return NULL;
164 }
165 sd->children = eina_list_append(sd->children, child);
166 cevt.child = child;
167 cevt.index = eina_list_count(sd->children);
168 efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILD_ADDED, &cevt);
169 efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &cevt.index);
170 return child;
171}
172
173static void
174_efl_model_item_efl_model_child_del(Eo *obj, Efl_Model_Item_Data *sd, Eo *child)
175{
176 Eina_List *l;
177 Efl_Model *data;
178 unsigned int i = 0;
179 EINA_LIST_FOREACH(sd->children, l, data)
180 {
181 if (data == child)
182 {
183 Efl_Model_Children_Event cevt;
184 sd->children = eina_list_remove_list(sd->children, l);
185
186 cevt.child = efl_ref(child);
187 cevt.index = i;
188
189 efl_parent_set(child, NULL);
190
191 efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILD_REMOVED, &cevt);
192 efl_unref(child);
193
194 i = eina_list_count(sd->children);
195 efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &i);
196 break;
197 }
198 ++i;
199 }
200}
201
202#include "efl_model_item.eo.c"
diff --git a/src/lib/ecore/efl_model_item.eo b/src/lib/ecore/efl_model_item.eo
new file mode 100644
index 0000000000..622cd249cb
--- /dev/null
+++ b/src/lib/ecore/efl_model_item.eo
@@ -0,0 +1,26 @@
1import eina_types;
2
3class Efl.Model.Item (Efl.Object, Efl.Model)
4{
5 [[
6 Generic model that allows any property to be manually set.
7 Also children of the same type can be added and deleted.
8
9 Intended to be used in scenarios where the user needs a manually defined
10 data model, like in tests.
11
12 It does not model anything in particular and does not affect anything else
13 in the system.
14 ]]
15 implements {
16 Efl.Object.constructor;
17 Efl.Object.destructor;
18 Efl.Model.properties { get; }
19 Efl.Model.property_set;
20 Efl.Model.property_get;
21 Efl.Model.child_add;
22 Efl.Model.child_del;
23 Efl.Model.children_slice_get;
24 Efl.Model.children_count_get;
25 }
26}
diff --git a/src/lib/efl/Efl.h b/src/lib/efl/Efl.h
index 0aac8377e5..147596828d 100644
--- a/src/lib/efl/Efl.h
+++ b/src/lib/efl/Efl.h
@@ -120,6 +120,11 @@ EAPI extern const Efl_Event_Description _EFL_GFX_PATH_CHANGED;
120 120
121#include "interfaces/efl_canvas.eo.h" 121#include "interfaces/efl_canvas.eo.h"
122 122
123#include "interfaces/efl_ui_view.eo.h"
124#include "interfaces/efl_ui_model_connect.eo.h"
125#include "interfaces/efl_ui_factory.eo.h"
126#include "interfaces/efl_ui_model_factory_connect.eo.h"
127
123/* Packing & containers */ 128/* Packing & containers */
124#include "interfaces/efl_container.eo.h" 129#include "interfaces/efl_container.eo.h"
125#include "interfaces/efl_pack.eo.h" 130#include "interfaces/efl_pack.eo.h"
diff --git a/src/lib/efl/Efl_Model_Common.h b/src/lib/efl/Efl_Model_Common.h
index 68de92a0a1..6a8c94a757 100644
--- a/src/lib/efl/Efl_Model_Common.h
+++ b/src/lib/efl/Efl_Model_Common.h
@@ -10,6 +10,7 @@ EAPI extern Eina_Error EFL_MODEL_ERROR_READ_ONLY;
10EAPI extern Eina_Error EFL_MODEL_ERROR_INIT_FAILED; 10EAPI extern Eina_Error EFL_MODEL_ERROR_INIT_FAILED;
11EAPI extern Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE; 11EAPI extern Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE;
12EAPI extern Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED; 12EAPI extern Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED;
13EAPI extern Eina_Error EFL_MODEL_ERROR_INVALID_OBJECT;
13 14
14/** 15/**
15 * @struct _Efl_Model_Children_Event 16 * @struct _Efl_Model_Children_Event
diff --git a/src/lib/efl/interfaces/efl_interfaces_main.c b/src/lib/efl/interfaces/efl_interfaces_main.c
index 4251ea3fe5..adde8b5082 100644
--- a/src/lib/efl/interfaces/efl_interfaces_main.c
+++ b/src/lib/efl/interfaces/efl_interfaces_main.c
@@ -55,6 +55,10 @@ EAPI const Efl_Event_Description _EFL_GFX_PATH_CHANGED =
55#include "interfaces/efl_ui_progress.eo.c" 55#include "interfaces/efl_ui_progress.eo.c"
56#include "interfaces/efl_ui_menu.eo.c" 56#include "interfaces/efl_ui_menu.eo.c"
57#include "interfaces/efl_ui_item.eo.c" 57#include "interfaces/efl_ui_item.eo.c"
58#include "interfaces/efl_ui_view.eo.c"
59#include "interfaces/efl_ui_model_connect.eo.c"
60#include "interfaces/efl_ui_factory.eo.c"
61#include "interfaces/efl_ui_model_factory_connect.eo.c"
58 62
59EAPI void 63EAPI void
60__efl_internal_init(void) 64__efl_internal_init(void)
diff --git a/src/lib/efl/interfaces/efl_model_common.c b/src/lib/efl/interfaces/efl_model_common.c
index afe6a040ce..07134d8bff 100644
--- a/src/lib/efl/interfaces/efl_model_common.c
+++ b/src/lib/efl/interfaces/efl_model_common.c
@@ -12,6 +12,7 @@ EAPI Eina_Error EFL_MODEL_ERROR_READ_ONLY = 0;
12EAPI Eina_Error EFL_MODEL_ERROR_INIT_FAILED = 0; 12EAPI Eina_Error EFL_MODEL_ERROR_INIT_FAILED = 0;
13EAPI Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED = 0; 13EAPI Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED = 0;
14EAPI Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE = 0; 14EAPI Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE = 0;
15EAPI Eina_Error EFL_MODEL_ERROR_INVALID_OBJECT = 0;
15 16
16static const char EFL_MODEL_ERROR_UNKNOWN_STR[] = "Unknown Error"; 17static const char EFL_MODEL_ERROR_UNKNOWN_STR[] = "Unknown Error";
17static const char EFL_MODEL_ERROR_NOT_SUPPORTED_STR[] = "Operation not supported"; 18static const char EFL_MODEL_ERROR_NOT_SUPPORTED_STR[] = "Operation not supported";
@@ -20,6 +21,8 @@ static const char EFL_MODEL_ERROR_READ_ONLY_STR[] = "Value read only";
20static const char EFL_MODEL_ERROR_INIT_FAILED_STR[] = "Init failed"; 21static const char EFL_MODEL_ERROR_INIT_FAILED_STR[] = "Init failed";
21static const char EFL_MODEL_ERROR_PERMISSION_DENIED_STR[] = "Permission denied"; 22static const char EFL_MODEL_ERROR_PERMISSION_DENIED_STR[] = "Permission denied";
22static const char EFL_MODEL_ERROR_INCORRECT_VALUE_STR[] = "Incorrect value"; 23static const char EFL_MODEL_ERROR_INCORRECT_VALUE_STR[] = "Incorrect value";
24static const char EFL_MODEL_ERROR_INVALID_OBJECT_STR[] = "Object is invalid";
25
23 26
24EAPI int 27EAPI int
25efl_model_init(void) 28efl_model_init(void)
@@ -45,6 +48,9 @@ efl_model_init(void)
45 EFL_MODEL_ERROR_PERMISSION_DENIED = eina_error_msg_static_register( 48 EFL_MODEL_ERROR_PERMISSION_DENIED = eina_error_msg_static_register(
46 EFL_MODEL_ERROR_PERMISSION_DENIED_STR); 49 EFL_MODEL_ERROR_PERMISSION_DENIED_STR);
47 50
51 EFL_MODEL_ERROR_INVALID_OBJECT = eina_error_msg_static_register(
52 EFL_MODEL_ERROR_INVALID_OBJECT_STR);
53
48 return EINA_TRUE; 54 return EINA_TRUE;
49} 55}
50 56
diff --git a/src/lib/efl/interfaces/efl_ui_factory.eo b/src/lib/efl/interfaces/efl_ui_factory.eo
new file mode 100644
index 0000000000..fc3e84baff
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_ui_factory.eo
@@ -0,0 +1,19 @@
1interface Efl.Ui.Factory (Efl.Ui.Model.Connect)
2{
3 methods {
4 create {
5 [[Create a UI object from the necessary properties in the specified model.]]
6 params {
7 model: Efl.Model;
8 parent: Efl.Canvas;
9 }
10 return: Efl.Canvas;
11 }
12 release {
13 [[Release a UI object and disconnec from models.]]
14 params {
15 ui_view: Efl.Canvas;
16 }
17 }
18 }
19}
diff --git a/src/lib/efl/interfaces/efl_ui_model_connect.eo b/src/lib/efl/interfaces/efl_ui_model_connect.eo
new file mode 100644
index 0000000000..42eb89e721
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_ui_model_connect.eo
@@ -0,0 +1,11 @@
1interface Efl.Ui.Model.Connect
2{
3 methods {
4 connect {
5 params {
6 name: string;
7 property: string;
8 }
9 }
10 }
11}
diff --git a/src/lib/efl/interfaces/efl_ui_model_factory_connect.eo b/src/lib/efl/interfaces/efl_ui_model_factory_connect.eo
new file mode 100644
index 0000000000..1330e5ad37
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_ui_model_factory_connect.eo
@@ -0,0 +1,11 @@
1interface Efl.Ui.Model.Factory.Connect
2{
3 methods {
4 connect {
5 params {
6 name: string;
7 factory: Efl.Ui.Factory;
8 }
9 }
10 }
11}
diff --git a/src/lib/efl/interfaces/efl_ui_view.eo b/src/lib/efl/interfaces/efl_ui_view.eo
new file mode 100644
index 0000000000..e5957ee445
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_ui_view.eo
@@ -0,0 +1,12 @@
1interface Efl.Ui.View ()
2{
3 methods {
4 @property model {
5 [[Model that is/will be ]]
6 get {} set {}
7 values {
8 model: Efl.Model;
9 }
10 }
11 }
12}
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index 8d6bb34b91..d917a572c0 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -265,6 +265,7 @@ EAPI extern Elm_Version *elm_version;
265# include <efl_ui_text.eo.h> 265# include <efl_ui_text.eo.h>
266# include <efl_ui_text_editable.eo.h> 266# include <efl_ui_text_editable.eo.h>
267# include <efl_ui_clock.eo.h> 267# include <efl_ui_clock.eo.h>
268# include <efl_ui_image_factory.eo.h>
268#endif 269#endif
269 270
270/* include deprecated calls last of all */ 271/* include deprecated calls last of all */
diff --git a/src/lib/elementary/efl_ui_image.c b/src/lib/elementary/efl_ui_image.c
index 1fecc682e4..0576fbb760 100644
--- a/src/lib/elementary/efl_ui_image.c
+++ b/src/lib/elementary/efl_ui_image.c
@@ -47,6 +47,8 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = {
47static Eina_Bool _key_action_activate(Evas_Object *obj, const char *params); 47static Eina_Bool _key_action_activate(Evas_Object *obj, const char *params);
48static Eina_Bool _efl_ui_image_smart_internal_file_set(Eo *obj, Efl_Ui_Image_Data *sd, const char *file, const Eina_File *f, const char *key); 48static Eina_Bool _efl_ui_image_smart_internal_file_set(Eo *obj, Efl_Ui_Image_Data *sd, const char *file, const Eina_File *f, const char *key);
49static void _efl_ui_image_remote_copier_cancel(Eo *obj, Efl_Ui_Image_Data *sd); 49static void _efl_ui_image_remote_copier_cancel(Eo *obj, Efl_Ui_Image_Data *sd);
50void _efl_ui_image_sizing_eval(Evas_Object *obj);
51static void _efl_ui_image_model_properties_changed_cb(void *data, const Efl_Event *event);
50 52
51static const Elm_Action key_actions[] = { 53static const Elm_Action key_actions[] = {
52 {"activate", _key_action_activate}, 54 {"activate", _key_action_activate},
@@ -566,6 +568,21 @@ _efl_ui_image_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Image_Data *sd)
566 if (sd->remote.copier) _efl_ui_image_remote_copier_cancel(obj, sd); 568 if (sd->remote.copier) _efl_ui_image_remote_copier_cancel(obj, sd);
567 if (sd->remote.binbuf) ELM_SAFE_FREE(sd->remote.binbuf, eina_binbuf_free); 569 if (sd->remote.binbuf) ELM_SAFE_FREE(sd->remote.binbuf, eina_binbuf_free);
568 ELM_SAFE_FREE(sd->remote.key, eina_stringshare_del); 570 ELM_SAFE_FREE(sd->remote.key, eina_stringshare_del);
571
572 if (sd->pfuture)
573 {
574 efl_future_cancel(sd->pfuture);
575 sd->pfuture = NULL;
576 }
577
578 if (sd->model)
579 {
580 efl_event_callback_del(sd->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
581 _efl_ui_image_model_properties_changed_cb, obj);
582 efl_unref(sd->model);
583 sd->model = NULL;
584 }
585
569 efl_canvas_group_del(efl_super(obj, MY_CLASS)); 586 efl_canvas_group_del(efl_super(obj, MY_CLASS));
570} 587}
571 588
@@ -1724,6 +1741,187 @@ _efl_ui_image_icon_get(Eo *obj EINA_UNUSED, Efl_Ui_Image_Data *sd)
1724 return sd->stdicon; 1741 return sd->stdicon;
1725} 1742}
1726 1743
1744static void
1745_prop_future_error_cb(void* data, Efl_Event const* event EINA_UNUSED)
1746{
1747 Eo *obj = data;
1748 EFL_UI_IMAGE_DATA_GET(obj, pd);
1749 pd->pfuture = NULL;
1750}
1751
1752static void
1753_prop_key_future_then_cb(void* data, Efl_Event const * event)
1754{
1755 Eo *obj = data;
1756 Eina_Accessor *acc = (Eina_Accessor *)((Efl_Future_Event_Success*)event->info)->value;
1757 Eina_Value *value;
1758 char *filename, *key;
1759
1760 EFL_UI_IMAGE_DATA_GET(obj, pd);
1761 pd->pfuture = NULL;
1762
1763 if (eina_accessor_data_get(acc, 0, (void **)&value) && value)
1764 {
1765 filename = eina_value_to_string(value);
1766 }
1767 else return;
1768
1769 if (eina_accessor_data_get(acc, 1, (void **)&value) && value)
1770 {
1771 key = eina_value_to_string(value);
1772 }
1773 else
1774 {
1775 free(filename);
1776 return;
1777 }
1778
1779 elm_image_file_set(obj, filename, key);
1780 free(filename);
1781 free(key);
1782}
1783
1784static void
1785_prop_future_then_cb(void* data, Efl_Event const * event)
1786{
1787 Eo *obj = data;
1788 Eina_Value *value = (Eina_Value*)((Efl_Future_Event_Success*)event->info)->value;
1789 char *text;
1790 EFL_UI_IMAGE_DATA_GET(obj, pd);
1791 pd->pfuture = NULL;
1792
1793 const Eina_Value_Type *vtype = eina_value_type_get(value);
1794
1795 if (vtype == EINA_VALUE_TYPE_STRING || vtype == EINA_VALUE_TYPE_STRINGSHARE)
1796 {
1797 eina_value_get(value, &text);
1798 if (pd->con_icon) efl_ui_image_icon_set(obj, text);
1799 else elm_image_file_set(obj, text, NULL);
1800 }
1801 else
1802 {
1803 text = eina_value_to_string(value);
1804 if (pd->con_icon) efl_ui_image_icon_set(obj, text);
1805 else elm_image_file_set(obj, text, NULL);
1806 free(text);
1807 }
1808}
1809
1810void
1811_update_viewmodel(Eo *obj, Efl_Ui_Image_Data *pd)
1812{
1813 if (pd->model && pd->prop_con)
1814 {
1815 if (pd->pfuture) efl_future_cancel(pd->pfuture);
1816
1817 pd->pfuture = efl_model_property_get(pd->model, pd->prop_con);
1818
1819 if (pd->prop_key)
1820 {
1821 const Eina_Array *properties;
1822 Eina_Array_Iterator it;
1823 char *property;
1824 unsigned int i = 0;
1825
1826 properties = efl_model_properties_get(pd->model);
1827 EINA_ARRAY_ITER_NEXT(properties, i, property, it)
1828 {
1829 if (strcmp(property, pd->prop_key) == 0)
1830 {
1831 Efl_Future *futures[2] = {NULL,};
1832 futures[0] = pd->pfuture;
1833 futures[1] = efl_model_property_get(pd->model, pd->prop_key);
1834 pd->pfuture = efl_future_all(futures[0], futures[1]);
1835 efl_future_then(pd->pfuture, &_prop_key_future_then_cb,
1836 &_prop_future_error_cb, NULL, obj);
1837 return;
1838 }
1839 }
1840 }
1841
1842 efl_future_then(pd->pfuture, &_prop_future_then_cb,
1843 &_prop_future_error_cb, NULL, obj);
1844 }
1845}
1846
1847static void
1848_efl_ui_image_model_properties_changed_cb(void *data, const Efl_Event *event)
1849{
1850 Efl_Model_Property_Event *evt = event->info;
1851 Eo *obj = data;
1852 EFL_UI_IMAGE_DATA_GET(obj, pd);
1853
1854 if (!evt->changed_properties)
1855 return;
1856
1857 if (pd->model && pd->prop_con)
1858 {
1859 Eina_Array_Iterator it;
1860 const char *prop;
1861 unsigned int i;
1862
1863 EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it)
1864 {
1865 if (!strcmp(pd->prop_con, prop) || (pd->prop_key && !strcmp(pd->prop_key, prop)))
1866 {
1867 _update_viewmodel(obj, pd);
1868 return;
1869 }
1870 }
1871 }
1872}
1873
1874EOLIAN static void
1875_efl_ui_image_efl_ui_view_model_set(Eo *obj, Efl_Ui_Image_Data *pd, Efl_Model *model)
1876{
1877 if (pd->model)
1878 {
1879 efl_event_callback_del(pd->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
1880 _efl_ui_image_model_properties_changed_cb, obj);
1881 efl_unref(pd->model);
1882 pd->model = NULL;
1883 }
1884
1885 if (model)
1886 {
1887 pd->model = model;
1888 efl_ref(pd->model);
1889 efl_event_callback_add(pd->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
1890 _efl_ui_image_model_properties_changed_cb, obj);
1891 }
1892
1893 _update_viewmodel(obj, pd);
1894}
1895
1896EOLIAN static Efl_Model *
1897_efl_ui_image_efl_ui_view_model_get(Eo *obj EINA_UNUSED, Efl_Ui_Image_Data *pd)
1898{
1899 return pd->model;
1900}
1901
1902EOLIAN static void
1903_efl_ui_image_efl_ui_model_connect_connect(Eo *obj, Efl_Ui_Image_Data *pd, const char *name, const char *property)
1904{
1905 if (strcmp(name, "filename") == 0)
1906 {
1907 pd->con_icon = EINA_FALSE;
1908 eina_stringshare_replace(&pd->prop_con, property);
1909 }
1910 else if (strcmp(name, "icon") == 0)
1911 {
1912 pd->con_icon = EINA_TRUE;
1913 eina_stringshare_replace(&pd->prop_con, property);
1914 eina_stringshare_replace(&pd->prop_key, NULL);
1915 }
1916 else if (strcmp(name, "key") == 0)
1917 {
1918 eina_stringshare_replace(&pd->prop_key, property);
1919 }
1920 else return;
1921
1922 _update_viewmodel(obj, pd);
1923}
1924
1727EAPI void 1925EAPI void
1728elm_image_smooth_set(Evas_Object *obj, Eina_Bool smooth) 1926elm_image_smooth_set(Evas_Object *obj, Eina_Bool smooth)
1729{ 1927{
diff --git a/src/lib/elementary/efl_ui_image.eo b/src/lib/elementary/efl_ui_image.eo
index 4bc05cbb71..d559f850fc 100644
--- a/src/lib/elementary/efl_ui_image.eo
+++ b/src/lib/elementary/efl_ui_image.eo
@@ -45,7 +45,8 @@ struct Efl.Ui.Image.Error
45class Efl.Ui.Image (Elm.Widget, Efl.Ui.Clickable, Efl.Ui.Draggable, 45class Efl.Ui.Image (Elm.Widget, Efl.Ui.Clickable, Efl.Ui.Draggable,
46 Efl.File, Efl.Image, Efl.Image.Load, Efl.Player, Efl.Gfx.View, 46 Efl.File, Efl.Image, Efl.Image.Load, Efl.Player, Efl.Gfx.View,
47 Elm.Interface.Atspi_Image, Elm.Interface.Atspi_Widget_Action, 47 Elm.Interface.Atspi_Image, Elm.Interface.Atspi_Widget_Action,
48 Edje.Object, Efl.Orientation, Efl.Flipable) 48 Edje.Object, Efl.Orientation, Efl.Flipable,
49 Efl.Ui.View, Efl.Ui.Model.Connect)
49{ 50{
50 [[ Efl UI image class]] 51 [[ Efl UI image class]]
51 event_prefix: efl_ui_image; 52 event_prefix: efl_ui_image;
@@ -143,6 +144,8 @@ class Efl.Ui.Image (Elm.Widget, Efl.Ui.Clickable, Efl.Ui.Draggable,
143 Efl.Canvas.Group.group_del; 144 Efl.Canvas.Group.group_del;
144 Efl.Canvas.Group.group_member_add; 145 Efl.Canvas.Group.group_member_add;
145 Efl.Ui.Draggable.drag_target { get; set; } 146 Efl.Ui.Draggable.drag_target { get; set; }
147 Efl.Ui.Model.Connect.connect;
148 Efl.Ui.View.model { get; set; }
146 Elm.Widget.theme_apply; 149 Elm.Widget.theme_apply;
147 Elm.Widget.widget_event; 150 Elm.Widget.widget_event;
148 Elm.Interface.Atspi_Image.extents { get; } 151 Elm.Interface.Atspi_Image.extents { get; }
diff --git a/src/lib/elementary/efl_ui_image_factory.c b/src/lib/elementary/efl_ui_image_factory.c
new file mode 100644
index 0000000000..a07d0e4f67
--- /dev/null
+++ b/src/lib/elementary/efl_ui_image_factory.c
@@ -0,0 +1,59 @@
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_IMAGE_FACTORY_CLASS
9#define MY_CLASS_NAME "Efl.Ui.Image_Factory"
10
11typedef struct _Efl_Ui_Image_Factory_Data
12{
13 Eina_Stringshare *property;
14} Efl_Ui_Image_Factory_Data;
15
16EOLIAN static Eo *
17_efl_ui_image_factory_efl_object_constructor(Eo *obj, Efl_Ui_Image_Factory_Data *pd)
18{
19 obj = efl_constructor(efl_super(obj, MY_CLASS));
20
21 pd->property = NULL;
22
23 return obj;
24}
25
26EOLIAN static void
27_efl_ui_image_factory_efl_object_destructor(Eo *obj EINA_UNUSED, Efl_Ui_Image_Factory_Data *pd)
28{
29 eina_stringshare_del(pd->property);
30 pd->property = NULL;
31
32 efl_destructor(efl_super(obj, MY_CLASS));
33}
34
35EOLIAN static Efl_Canvas *
36_efl_ui_image_factory_efl_ui_factory_create(Eo *obj EINA_UNUSED, Efl_Ui_Image_Factory_Data *pd, Efl_Model *model, Efl_Canvas *parent)
37{
38 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->property, NULL);
39 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
40 Efl_Canvas *ui_view = efl_add(EFL_UI_IMAGE_CLASS, parent);
41 efl_ui_view_model_set(ui_view, model);
42 efl_ui_model_connect(ui_view, "filename", pd->property);
43
44 return ui_view;
45}
46
47EOLIAN static void
48_efl_ui_image_factory_efl_ui_factory_release(Eo *obj EINA_UNUSED, Efl_Ui_Image_Factory_Data *pd EINA_UNUSED, Efl_Canvas *ui_view)
49{
50 efl_parent_set(ui_view, NULL);
51}
52
53EOLIAN static void
54_efl_ui_image_factory_efl_ui_model_connect_connect(Eo *obj EINA_UNUSED, Efl_Ui_Image_Factory_Data *pd, const char *name EINA_UNUSED, const char *property)
55{
56 eina_stringshare_replace(&pd->property, property);
57}
58
59#include "efl_ui_image_factory.eo.c"
diff --git a/src/lib/elementary/efl_ui_image_factory.eo b/src/lib/elementary/efl_ui_image_factory.eo
new file mode 100644
index 0000000000..bfc5c8abb7
--- /dev/null
+++ b/src/lib/elementary/efl_ui_image_factory.eo
@@ -0,0 +1,10 @@
1class Efl.Ui.Image.Factory (Efl.Object, Efl.Ui.Factory)
2{
3 implements {
4 Efl.Object.constructor;
5 Efl.Object.destructor;
6 Efl.Ui.Factory.create;
7 Efl.Ui.Factory.release;
8 Efl.Ui.Model.Connect.connect;
9 }
10}
diff --git a/src/lib/elementary/efl_ui_widget_image.h b/src/lib/elementary/efl_ui_widget_image.h
index 2afd87fab9..f1480f09e8 100644
--- a/src/lib/elementary/efl_ui_widget_image.h
+++ b/src/lib/elementary/efl_ui_widget_image.h
@@ -80,6 +80,10 @@ struct _Efl_Ui_Image_Data
80 80
81 const char *stdicon; 81 const char *stdicon;
82 82
83 Efl_Model *model;
84 Efl_Future *pfuture;
85 Eina_Stringshare *prop_con;
86 Eina_Stringshare *prop_key;
83 87
84 struct { 88 struct {
85 int requested_size; 89 int requested_size;
@@ -98,6 +102,7 @@ struct _Efl_Ui_Image_Data
98 Eina_Bool async_enable : 1; 102 Eina_Bool async_enable : 1;
99 Eina_Bool scale_up : 1; 103 Eina_Bool scale_up : 1;
100 Eina_Bool scale_down : 1; 104 Eina_Bool scale_down : 1;
105 Eina_Bool con_icon : 1;
101}; 106};
102 107
103/** 108/**
diff --git a/src/lib/elementary/elm_layout.c b/src/lib/elementary/elm_layout.c
index b5d2f56cb8..01311fa5f6 100644
--- a/src/lib/elementary/elm_layout.c
+++ b/src/lib/elementary/elm_layout.c
@@ -22,11 +22,14 @@
22#define MY_CLASS_NAME_LEGACY "elm_layout" 22#define MY_CLASS_NAME_LEGACY "elm_layout"
23 23
24Eo *_elm_layout_pack_proxy_get(Elm_Layout *obj, Edje_Part_Type type, const char *part); 24Eo *_elm_layout_pack_proxy_get(Elm_Layout *obj, Edje_Part_Type type, const char *part);
25static void _efl_model_properties_changed_cb(void *, const Efl_Event *);
25 26
26static const char SIG_THEME_CHANGED[] = "theme,changed"; 27static const char SIG_THEME_CHANGED[] = "theme,changed";
27const char SIG_LAYOUT_FOCUSED[] = "focused"; 28const char SIG_LAYOUT_FOCUSED[] = "focused";
28const char SIG_LAYOUT_UNFOCUSED[] = "unfocused"; 29const char SIG_LAYOUT_UNFOCUSED[] = "unfocused";
29 30
31const char SIGNAL_PREFIX[] = "signal/";
32
30/* smart callbacks coming from elm layout objects: */ 33/* smart callbacks coming from elm layout objects: */
31static const Evas_Smart_Cb_Description _smart_callbacks[] = { 34static const Evas_Smart_Cb_Description _smart_callbacks[] = {
32 {SIG_THEME_CHANGED, ""}, 35 {SIG_THEME_CHANGED, ""},
@@ -106,6 +109,13 @@ struct _Elm_Layout_Sub_Object_Cursor
106 Eina_Bool engine_only : 1; 109 Eina_Bool engine_only : 1;
107}; 110};
108 111
112typedef struct _Elm_Layout_Sub_Property_Future Elm_Layout_Sub_Property_Future;
113struct _Elm_Layout_Sub_Property_Future
114{
115 Elm_Layout_Smart_Data *pd;
116 Eina_Array *name_arr;
117};
118
109static void 119static void
110_on_sub_object_size_hint_change(void *data, 120_on_sub_object_size_hint_change(void *data,
111 Evas *e EINA_UNUSED, 121 Evas *e EINA_UNUSED,
@@ -793,6 +803,17 @@ _elm_layout_efl_canvas_group_group_del(Eo *obj, Elm_Layout_Smart_Data *sd)
793 free(esd); 803 free(esd);
794 } 804 }
795 805
806 if(sd->model)
807 {
808 efl_event_callback_del(sd->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, _efl_model_properties_changed_cb, sd);
809 efl_unref(sd->model);
810 sd->model = NULL;
811 }
812 eina_hash_free(sd->prop_connect);
813 sd->prop_connect = NULL;
814 eina_hash_free(sd->factories);
815 sd->factories = NULL;
816
796 eina_stringshare_del(sd->klass); 817 eina_stringshare_del(sd->klass);
797 eina_stringshare_del(sd->group); 818 eina_stringshare_del(sd->group);
798 819
@@ -1323,6 +1344,20 @@ _elm_layout_text_set(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, const
1323 sub_d->obj = _elm_access_edje_object_part_object_register 1344 sub_d->obj = _elm_access_edje_object_part_object_register
1324 (obj, elm_layout_edje_get(obj), part); 1345 (obj, elm_layout_edje_get(obj), part);
1325 1346
1347 if (sd->model && !sd->view_updated)
1348 {
1349 Eina_Stringshare *prop = eina_hash_find(sd->prop_connect, sub_d->part);
1350 if (prop)
1351 {
1352 Eina_Value v;
1353 eina_value_setup(&v, EINA_VALUE_TYPE_STRING);
1354 eina_value_set(&v, text);
1355 efl_model_property_set(sd->model, prop, &v);
1356 eina_value_flush(&v);
1357 }
1358 }
1359
1360 sd->view_updated = EINA_FALSE;
1326 return EINA_TRUE; 1361 return EINA_TRUE;
1327} 1362}
1328 1363
@@ -1896,6 +1931,291 @@ _elm_layout_efl_object_dbg_info_get(Eo *eo_obj, Elm_Layout_Smart_Data *_pd EINA_
1896 } 1931 }
1897} 1932}
1898 1933
1934static void
1935_prop_future_error_cb(void* data, Efl_Event const*event EINA_UNUSED)
1936{
1937 Elm_Layout_Sub_Property_Future *sub_pp = data;
1938 Eina_Array_Iterator iterator;
1939 Eina_Stringshare *name;
1940 unsigned int i = 0;
1941
1942 EINA_ARRAY_ITER_NEXT(sub_pp->name_arr, i, name, iterator)
1943 eina_stringshare_del(name);
1944
1945 eina_array_free(sub_pp->name_arr);
1946 free(sub_pp);
1947}
1948
1949static void
1950_view_update(Elm_Layout_Smart_Data *pd, const char *name, const char *property)
1951{
1952 const char *source;
1953 Eina_Strbuf *buf;
1954
1955 if (strncmp(SIGNAL_PREFIX, name, sizeof(SIGNAL_PREFIX) -1) != 0)
1956 {
1957 elm_layout_text_set(pd->obj, name, property);
1958 return;
1959 }
1960
1961 ELM_WIDGET_DATA_GET_OR_RETURN(pd->obj, wd);
1962 source = efl_class_name_get(efl_class_get(pd->model));
1963
1964 buf = eina_strbuf_new();
1965 eina_strbuf_append(buf, name);
1966 eina_strbuf_remove(buf, 0, sizeof(SIGNAL_PREFIX)-1);
1967 eina_strbuf_replace_all(buf, "%v", property);
1968
1969 edje_object_signal_emit(wd->resize_obj, eina_strbuf_string_get(buf), source);
1970 eina_strbuf_free(buf);
1971}
1972
1973static void
1974_prop_future_then_cb(void* data, Efl_Event const*event)
1975{
1976 Elm_Layout_Sub_Property_Future *sub_pp = data;
1977 Elm_Layout_Smart_Data *pd = sub_pp->pd;
1978 Eina_Accessor *value_acc = (Eina_Accessor *)((Efl_Future_Event_Success*)event->info)->value;
1979 Eina_Value *value;
1980 Eina_Stringshare *name;
1981 char *text;
1982 unsigned int i = 0;
1983 unsigned int acc_i = 0;
1984
1985 while (eina_accessor_data_get(value_acc, acc_i, (void **)&value))
1986 {
1987 const Eina_Value_Type *vtype = eina_value_type_get(value);
1988 name = eina_array_data_get(sub_pp->name_arr, i);
1989
1990 pd->view_updated = EINA_TRUE;
1991 if (vtype == EINA_VALUE_TYPE_STRING || vtype == EINA_VALUE_TYPE_STRINGSHARE)
1992 {
1993 eina_value_get(value, &text);
1994 _view_update(pd, name, text);
1995 }
1996 else
1997 {
1998 text = eina_value_to_string(value);
1999 _view_update(pd, name, text);
2000 free(text);
2001 }
2002 eina_stringshare_del(name);
2003 ++acc_i;
2004 }
2005 eina_array_free(sub_pp->name_arr);
2006 free(sub_pp);
2007}
2008
2009static void
2010_elm_layout_view_model_update(Elm_Layout_Smart_Data *pd)
2011{
2012 Elm_Layout_Sub_Property_Future *sub_pp;
2013 Efl_Future **future_arr, **f, *future_all;
2014 Eina_Hash_Tuple *tuple;
2015 Eina_Iterator *it_p;
2016 int size;
2017
2018 if (!pd->prop_connect) return;
2019
2020 size = eina_hash_population(pd->prop_connect);
2021 if (size == 0) return;
2022
2023 future_arr = alloca((size + 1) * sizeof(Efl_Future*));
2024 f = future_arr;
2025
2026 sub_pp = ELM_NEW(Elm_Layout_Sub_Property_Future);
2027 sub_pp->pd = pd;
2028 sub_pp->name_arr = eina_array_new(size);
2029
2030 it_p = eina_hash_iterator_tuple_new(pd->prop_connect);
2031 while (eina_iterator_next(it_p, (void **)&tuple))
2032 {
2033 *f = efl_model_property_get(pd->model, tuple->data);
2034 eina_array_push(sub_pp->name_arr, eina_stringshare_ref(tuple->key));
2035 f++;
2036 }
2037 eina_iterator_free(it_p);
2038 *f = NULL;
2039
2040 future_all = efl_future_iterator_all(eina_carray_iterator_new((void**)future_arr));
2041
2042 efl_future_then(future_all, &_prop_future_then_cb, &_prop_future_error_cb, NULL, sub_pp);
2043}
2044
2045static void
2046_efl_model_properties_changed_cb(void *data, const Efl_Event *event)
2047{
2048 Elm_Layout_Smart_Data *pd = data;
2049 Efl_Model_Property_Event *evt = event->info;
2050 Eina_Stringshare *ss_prop;
2051 Eina_Hash_Tuple *tuple;
2052 Eina_Array *names, *futures;
2053 Eina_Iterator *it_p;
2054 const char *prop;
2055 Eina_Array_Iterator it;
2056 unsigned int i;
2057
2058 if (!evt->changed_properties || !pd->prop_connect) return;
2059
2060 names = eina_array_new(1);
2061 futures = eina_array_new(1);
2062
2063 EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it)
2064 {
2065 ss_prop = eina_stringshare_add(prop);
2066 it_p = eina_hash_iterator_tuple_new(pd->prop_connect);
2067 while (eina_iterator_next(it_p, (void **)&tuple))
2068 {
2069 if (tuple->data == ss_prop)
2070 {
2071 eina_array_push(names, eina_stringshare_ref(tuple->key));
2072 eina_array_push(futures, efl_model_property_get(pd->model, prop));
2073 }
2074 }
2075 eina_iterator_free(it_p);
2076 eina_stringshare_del(ss_prop);
2077 }
2078
2079 if (eina_array_count(names))
2080 {
2081 Elm_Layout_Sub_Property_Future *sub_pp;
2082 Efl_Future *future_all;
2083
2084 sub_pp = ELM_NEW(Elm_Layout_Sub_Property_Future);
2085 sub_pp->pd = pd;
2086 sub_pp->name_arr = names;
2087
2088 future_all = efl_future_iterator_all(eina_array_iterator_new(futures));
2089 efl_future_then(future_all, &_prop_future_then_cb, &_prop_future_error_cb, NULL, sub_pp);
2090 }
2091 else
2092 eina_array_free(names);
2093
2094 eina_array_free(futures);
2095}
2096
2097EOLIAN static void
2098_elm_layout_efl_ui_view_model_set(Eo *obj EINA_UNUSED, Elm_Layout_Smart_Data *pd, Efl_Model *model)
2099{
2100 if (pd->model)
2101 {
2102 efl_event_callback_del(pd->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, _efl_model_properties_changed_cb, pd);
2103 efl_unref(pd->model);
2104 pd->model = NULL;
2105 }
2106
2107 if (model)
2108 {
2109 pd->model = model;
2110 efl_ref(pd->model);
2111 efl_event_callback_add(pd->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, _efl_model_properties_changed_cb, pd);
2112 }
2113
2114 if (pd->prop_connect)
2115 _elm_layout_view_model_update(pd);
2116
2117 if (pd->factories)
2118 {
2119 Eina_Hash_Tuple *tuple;
2120 Eina_Stringshare *name;
2121 Efl_Ui_Factory *factory;
2122 Efl_Canvas *content;
2123
2124 Eina_Iterator *it_p = eina_hash_iterator_tuple_new(pd->factories);
2125 while (eina_iterator_next(it_p, (void **)&tuple))
2126 {
2127 name = tuple->key;
2128 factory = tuple->data;
2129 content = elm_layout_content_get(pd->obj, name);
2130
2131 if (content && efl_isa(content, EFL_UI_VIEW_INTERFACE))
2132 {
2133 efl_ui_view_model_set(content, pd->model);
2134 }
2135 else
2136 {
2137 efl_ui_factory_release(factory, content);
2138 content = efl_ui_factory_create(factory, pd->model, pd->obj);
2139 elm_layout_content_set(pd->obj, name, content);
2140 }
2141 }
2142 eina_iterator_free(it_p);
2143 }
2144}
2145
2146EOLIAN static Efl_Model *
2147_elm_layout_efl_ui_view_model_get(Eo *obj EINA_UNUSED, Elm_Layout_Smart_Data *pd)
2148{
2149 return pd->model;
2150}
2151
2152EOLIAN static void
2153_elm_layout_efl_ui_model_connect_connect(Eo *obj EINA_UNUSED, Elm_Layout_Smart_Data *pd, const char *name, const char *property)
2154{
2155 EINA_SAFETY_ON_NULL_RETURN(name);
2156 Eina_Stringshare *ss_name, *ss_prop;
2157
2158 if (!_elm_layout_part_aliasing_eval(obj, pd, &name, EINA_TRUE))
2159 return;
2160
2161 ss_name = eina_stringshare_add(name);
2162 ss_prop = eina_stringshare_add(property);
2163 if (!pd->prop_connect)
2164 {
2165 pd->prop_connect = eina_hash_stringshared_new(EINA_FREE_CB(eina_stringshare_del));
2166 }
2167
2168 eina_stringshare_del(eina_hash_set(pd->prop_connect, ss_name, ss_prop));
2169
2170 if (pd->model)
2171 {
2172 Elm_Layout_Sub_Property_Future *sub_pp = ELM_NEW(Elm_Layout_Sub_Property_Future);
2173 Efl_Future *futures[2] = {NULL,};
2174 Efl_Future *future_all = NULL;
2175
2176 sub_pp->pd = pd;
2177 sub_pp->name_arr = eina_array_new(1);
2178 eina_array_push(sub_pp->name_arr, eina_stringshare_ref(ss_name));
2179 futures[0] = efl_model_property_get(pd->model, ss_prop);
2180
2181 future_all = efl_future_iterator_all(eina_carray_iterator_new((void**)futures));
2182 efl_future_then(future_all, &_prop_future_then_cb, &_prop_future_error_cb, NULL, sub_pp);
2183 }
2184}
2185
2186
2187EOLIAN static void
2188_elm_layout_efl_ui_model_factory_connect_connect(Eo *obj EINA_UNUSED, Elm_Layout_Smart_Data *pd,
2189 const char *name, Efl_Ui_Factory *factory)
2190{
2191 EINA_SAFETY_ON_NULL_RETURN(name);
2192 Eina_Stringshare *ss_name;
2193 Efl_Ui_Factory *old_factory;
2194 Evas_Object *new_ev, *old_ev;
2195
2196 if (!_elm_layout_part_aliasing_eval(obj, pd, &name, EINA_TRUE))
2197 return;
2198
2199 ss_name = eina_stringshare_add(name);
2200
2201 if (!pd->factories)
2202 pd->factories = eina_hash_stringshared_new(EINA_FREE_CB(efl_unref));
2203
2204 new_ev = efl_ui_factory_create(factory, pd->model, obj);
2205 EINA_SAFETY_ON_NULL_RETURN(new_ev);
2206
2207 old_factory = eina_hash_set(pd->factories, ss_name, efl_ref(factory));
2208 if (old_factory)
2209 {
2210 old_ev = elm_layout_content_get(obj, name);
2211 if (old_ev)
2212 efl_ui_factory_release(old_factory, old_ev);
2213 efl_unref(old_factory);
2214 }
2215
2216 elm_layout_content_set(obj, name, new_ev);
2217}
2218
1899EAPI Evas_Object * 2219EAPI Evas_Object *
1900elm_layout_add(Evas_Object *parent) 2220elm_layout_add(Evas_Object *parent)
1901{ 2221{
diff --git a/src/lib/elementary/elm_layout.eo b/src/lib/elementary/elm_layout.eo
index 37f1ad17a9..802f567050 100644
--- a/src/lib/elementary/elm_layout.eo
+++ b/src/lib/elementary/elm_layout.eo
@@ -17,7 +17,8 @@ struct Elm.Layout_Part_Alias_Description
17 real_part: string; [[Target part name for the alias set on Elm.Layout_Part_Proxies_Description::real_part. An example of usage would be "default" on that field, with "elm.content.swallow" on this one]] 17 real_part: string; [[Target part name for the alias set on Elm.Layout_Part_Proxies_Description::real_part. An example of usage would be "default" on that field, with "elm.content.swallow" on this one]]
18} 18}
19 19
20class Elm.Layout (Elm.Widget, Efl.Part, Efl.Container, Efl.File) 20class Elm.Layout (Elm.Widget, Efl.Part, Efl.Container, Efl.File,
21 Efl.Ui.View, Efl.Ui.Model.Connect, Efl.Ui.Model.Factory.Connect)
21{ 22{
22 [[Elementary layout class]] 23 [[Elementary layout class]]
23 legacy_prefix: elm_layout; 24 legacy_prefix: elm_layout;
@@ -355,6 +356,9 @@ class Elm.Layout (Elm.Widget, Efl.Part, Efl.Container, Efl.File)
355 Efl.Container.content { get; set; } 356 Efl.Container.content { get; set; }
356 Efl.Container.content_unset; 357 Efl.Container.content_unset;
357 Efl.Part.part; 358 Efl.Part.part;
359 Efl.Ui.View.model { get; set; }
360 Efl.Ui.Model.Connect.connect;
361 Efl.Ui.Model.Factory.Connect.connect;
358 } 362 }
359 events { 363 events {
360 theme,changed; [[Called when theme changed]] 364 theme,changed; [[Called when theme changed]]
diff --git a/src/lib/elementary/elm_widget_layout.h b/src/lib/elementary/elm_widget_layout.h
index b4a2ed5384..684a11906a 100644
--- a/src/lib/elementary/elm_widget_layout.h
+++ b/src/lib/elementary/elm_widget_layout.h
@@ -53,6 +53,9 @@ typedef struct _Elm_Layout_Smart_Data
53 Eina_List *subs; /**< List of Elm_Layout_Sub_Object_Data structs, to hold the actual sub objects such as text, content and the children of box and table. */ 53 Eina_List *subs; /**< List of Elm_Layout_Sub_Object_Data structs, to hold the actual sub objects such as text, content and the children of box and table. */
54 Eina_List *edje_signals; /**< The list of edje signal callbacks. */ 54 Eina_List *edje_signals; /**< The list of edje signal callbacks. */
55 Eina_List *parts_cursors; /**< The list of cursor names of layout parts. This is a list of Elm_Layout_Sub_Object_Cursor struct. */ 55 Eina_List *parts_cursors; /**< The list of cursor names of layout parts. This is a list of Elm_Layout_Sub_Object_Cursor struct. */
56 Eina_Hash *prop_connect; /**< The hash of properties connected to layout parts. */
57 Eina_Hash *factories; /**< The hash with parts connected to factories. */
58 Efl_Model *model; /**< The model */
56 const char *klass; /**< 1st identifier of an edje object group which is used in theme_set. klass and group are used together. */ 59 const char *klass; /**< 1st identifier of an edje object group which is used in theme_set. klass and group are used together. */
57 const char *group; /**< 2nd identifier of an edje object group which is used in theme_set. klass and group are used together. */ 60 const char *group; /**< 2nd identifier of an edje object group which is used in theme_set. klass and group are used together. */
58 int frozen; /**< Layout freeze counter */ 61 int frozen; /**< Layout freeze counter */
@@ -63,6 +66,7 @@ typedef struct _Elm_Layout_Smart_Data
63 Eina_Bool can_access : 1; /**< This is true when all text(including textblock) parts can be accessible by accessibility. */ 66 Eina_Bool can_access : 1; /**< This is true when all text(including textblock) parts can be accessible by accessibility. */
64 Eina_Bool destructed_is : 1; /**< This flag indicates if Elm_Layout destructor was called. This is needed to avoid unnecessary calculation of subobject deletion during layout object's deletion. */ 67 Eina_Bool destructed_is : 1; /**< This flag indicates if Elm_Layout destructor was called. This is needed to avoid unnecessary calculation of subobject deletion during layout object's deletion. */
65 Eina_Bool file_set : 1; /**< This flag indicates if Elm_Layout source is set from a file*/ 68 Eina_Bool file_set : 1; /**< This flag indicates if Elm_Layout source is set from a file*/
69 Eina_Bool view_updated : 1; /**< This flag indicates to Elm_Layout don't update model in text_set */
66} Elm_Layout_Smart_Data; 70} Elm_Layout_Smart_Data;
67 71
68/** 72/**
diff --git a/src/lib/eo/eina_types.eot b/src/lib/eo/eina_types.eot
index c1d2243b2f..1f97ff4a43 100644
--- a/src/lib/eo/eina_types.eot
+++ b/src/lib/eo/eina_types.eot
@@ -59,3 +59,5 @@ struct @extern Eina.Rw_Slice {
59 len: size; [[Length of the memory segment]] 59 len: size; [[Length of the memory segment]]
60 mem: void_ptr; [[Pointer to memory segment]] 60 mem: void_ptr; [[Pointer to memory segment]]
61} 61}
62
63struct @extern Eina.Value.Type;
diff --git a/src/tests/efl/efl_suite.c b/src/tests/efl/efl_suite.c
new file mode 100644
index 0000000000..653aac2201
--- /dev/null
+++ b/src/tests/efl/efl_suite.c
@@ -0,0 +1,51 @@
1/* EINA - EFL data type library
2 * Copyright (C) 2008 Cedric Bail
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#include <Eina.h>
24
25#include "efl_suite.h"
26#include "../efl_check.h"
27
28static const Efl_Test_Case etc[] = {
29 { "Efl_Model_Container", efl_test_case_model_container },
30 { NULL, NULL }
31};
32
33int
34main(int argc, char **argv)
35{
36 int failed_count;
37
38 if (!_efl_test_option_disp(argc, argv, etc))
39 return 0;
40
41 putenv("EFL_RUN_IN_TREE=1");
42
43 eina_init();
44
45 failed_count = _efl_suite_build_and_run(argc - 1, (const char **)argv + 1,
46 "Efl", etc);
47
48 eina_shutdown();
49
50 return (failed_count == 0) ? 0 : 255;
51}
diff --git a/src/tests/efl/efl_suite.h b/src/tests/efl/efl_suite.h
new file mode 100644
index 0000000000..d5a7caa9ec
--- /dev/null
+++ b/src/tests/efl/efl_suite.h
@@ -0,0 +1,26 @@
1/* EFL - EFL library
2 * Copyright (C) 2008 Cedric Bail
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef EFL_SUITE_H_
20#define EFL_SUITE_H_
21
22#include <check.h>
23
24void efl_test_case_model_container(TCase *tc);
25
26#endif /* EFL_SUITE_H_ */
diff --git a/src/tests/efl/efl_test_model_container.c b/src/tests/efl/efl_test_model_container.c
new file mode 100644
index 0000000000..5710ef2337
--- /dev/null
+++ b/src/tests/efl/efl_test_model_container.c
@@ -0,0 +1,171 @@
1/* EFL - EFL library
2 * Copyright (C) 2013 Cedric Bail
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#include "efl_suite.h"
24
25#include <Efl.h>
26#include <Ecore.h>
27
28typedef struct _Test_Container_Data {
29 int item_count;
30 Eina_Bool pass_flag;
31 Eina_Bool fail_flag;
32} Test_Container_Data;
33
34typedef struct _Test_Container_Item_Data {
35 Test_Container_Data* test_data;
36 unsigned int index;
37} Test_Container_Item_Data;
38
39const int base_int[7] = {10, 11, 12, 13, 14, 0, 16};
40const char * const base_str[7] = {"A", "B", "C", "D", "E", "", "GH"};
41
42static void
43_future_error_then(void *data EINA_UNUSED, Efl_Event const* event EINA_UNUSED)
44{
45 ck_abort_msg("Promise failed");
46}
47
48static void
49_container_property_get_then(void *data, Efl_Event const *event)
50{
51 Eina_Accessor *value_itt = (Eina_Accessor*)((Efl_Future_Event_Success*)event->info)->value;
52 Test_Container_Item_Data *test_item_data = data;
53 Eina_Value *value_int = NULL;
54 Eina_Value *value_str = NULL;
55 int cmp_int = 0;
56 const char *cmp_str = NULL;
57
58 test_item_data->test_data->item_count++;
59
60 if (!value_itt || !eina_accessor_data_get(value_itt, 0, (void**)&value_int) ||
61 !eina_accessor_data_get(value_itt, 1, (void**)&value_str))
62 {
63 test_item_data->test_data->fail_flag = EINA_TRUE;
64 ecore_main_loop_quit();
65 return;
66 }
67
68 eina_value_get(value_int, &cmp_int);
69 eina_value_get(value_str, &cmp_str);
70
71 if (cmp_int != base_int[test_item_data->index] ||
72 strcmp(cmp_str, base_str[test_item_data->index]) != 0)
73 {
74 test_item_data->test_data->fail_flag = EINA_TRUE;
75 }
76
77 if (test_item_data->test_data->item_count == 7)
78 {
79 test_item_data->test_data->pass_flag = EINA_TRUE;
80 }
81 ecore_main_loop_quit();
82}
83
84static void
85_children_slice_future_then(void *data, Efl_Event const *event)
86{
87 Eina_Accessor *children_accessor = (Eina_Accessor *)((Efl_Future_Event_Success*)event->info)->value;
88 unsigned int i = 0;
89 Efl_Model *child;
90
91 if (children_accessor)
92 {
93 EINA_ACCESSOR_FOREACH(children_accessor, i, child)
94 {
95 Efl_Future *futures[3] = {NULL,};
96 Efl_Future *future_all = NULL;
97 Test_Container_Item_Data *test_item_data = calloc(1, sizeof(Test_Container_Item_Data));
98
99 test_item_data->test_data = data;
100 test_item_data->index = i;
101
102 futures[0] = efl_model_property_get(child, "test_p_int");
103 futures[1] = efl_model_property_get(child, "test_p_str");
104
105 future_all = efl_future_all(futures[0], futures[1]);
106 efl_future_then(future_all, _container_property_get_then, _future_error_then, NULL, test_item_data);
107 }
108 }
109}
110
111
112START_TEST(efl_test_model_container_values)
113{
114 Efl_Model_Container* model;
115 Efl_Future *future;
116 Test_Container_Data test_data;
117 int **cmp_int;
118 const char **cmp_str;
119 int i;
120
121 fail_if(!ecore_init(), "ERROR: Cannot init Ecore!\n");
122 fail_if(!efl_object_init(), "ERROR: Cannot init EO!\n");
123
124 cmp_int = calloc(8, sizeof(int*));
125 cmp_str = calloc(8, sizeof(const char*));
126 for (i = 0; i < 7; ++i)
127 {
128 cmp_int[i] = calloc(1, sizeof(int));
129 *(cmp_int[i]) = base_int[i];
130 cmp_str[i] = strdup(base_str[i]);
131 }
132
133 model = efl_add(EFL_MODEL_CONTAINER_CLASS, NULL);
134
135 efl_model_container_child_property_add(model, "test_p_int", EINA_VALUE_TYPE_INT,
136 eina_carray_iterator_new((void**)cmp_int));
137
138 efl_model_container_child_property_add(model, "test_p_str", EINA_VALUE_TYPE_STRING,
139 eina_carray_iterator_new((void**)cmp_str));
140
141 for (i = 0; i < 7; ++i)
142 {
143 free(cmp_int[i]);
144 free((void*)cmp_str[i]);
145 }
146 free(cmp_int);
147 free(cmp_str);
148
149 future = efl_model_children_slice_get(model, 0, 0);
150
151 test_data.item_count = 0;
152 test_data.pass_flag = EINA_FALSE;
153 test_data.fail_flag = EINA_FALSE;
154
155 efl_future_then(future, _children_slice_future_then, _future_error_then, NULL, &test_data);
156
157 ecore_main_loop_iterate();
158
159 ck_assert(!!test_data.pass_flag);
160 ck_assert(!test_data.fail_flag);
161
162 ecore_shutdown();
163}
164END_TEST
165
166
167void
168efl_test_case_model_container(TCase *tc)
169{
170 tcase_add_test(tc, efl_test_model_container_values);
171}
diff --git a/src/tests/elementary/elm_test_layout.c b/src/tests/elementary/elm_test_layout.c
index b89be351c9..725ab602c4 100644
--- a/src/tests/elementary/elm_test_layout.c
+++ b/src/tests/elementary/elm_test_layout.c
@@ -57,8 +57,44 @@ START_TEST(elm_layout_swallows)
57} 57}
58END_TEST 58END_TEST
59 59
60START_TEST(elm_layout_model_connect)
61{
62 char buf[PATH_MAX];
63 Evas_Object *win, *ly;
64 Efl_Model_Item *model;
65 Eina_Value v;
66 const char *part_text;
67 const char text_value[] = "A random string for elm_layout_model_connect test";
68
69 elm_init(1, NULL);
70 win = elm_win_add(NULL, "layout", ELM_WIN_BASIC);
71
72 ly = efl_add(ELM_LAYOUT_CLASS, win);
73 snprintf(buf, sizeof(buf), "%s/objects/test.edj", ELM_TEST_DATA_DIR);
74 elm_layout_file_set(ly, buf, "layout");
75 evas_object_show(ly);
76
77 model = efl_add(EFL_MODEL_ITEM_CLASS, win);
78 ck_assert(!!eina_value_setup(&v, EINA_VALUE_TYPE_STRING));
79 ck_assert(!!eina_value_set(&v, text_value));
80 efl_model_property_set(model, "text_property", &v);
81
82 efl_ui_model_connect(ly, "text", "text_property");
83 efl_ui_view_model_set(ly, model);
84
85 ecore_main_loop_iterate_may_block(EINA_TRUE);
86
87 part_text = elm_layout_text_get(ly, "text");
88
89 ck_assert_str_eq(part_text, text_value);
90
91 elm_shutdown();
92}
93END_TEST
94
60void elm_test_layout(TCase *tc) 95void elm_test_layout(TCase *tc)
61{ 96{
62 tcase_add_test(tc, elm_atspi_role_get); 97 tcase_add_test(tc, elm_atspi_role_get);
63 tcase_add_test(tc, elm_layout_swallows); 98 tcase_add_test(tc, elm_layout_swallows);
99 tcase_add_test(tc, elm_layout_model_connect);
64} 100}