aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2017-09-07 12:06:17 +0900
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2017-09-07 14:23:51 +0900
commitdf9f2e07722fa384cba09e934351e90f0d237009 (patch)
treefec9ee87313645c67c1883f7a0e4bf4282ae0bff
parentefl: Make models 0-based index, not 1-based (diff)
downloadefl-df9f2e07722fa384cba09e934351e90f0d237009.tar.gz
ecore: Add efl_model_copmosite_selection model
-rw-r--r--src/Makefile_Ecore.am4
-rw-r--r--src/Makefile_Efl.am2
-rw-r--r--src/lib/ecore/Ecore_Eo.h2
-rw-r--r--src/lib/ecore/efl_model_accessor_view.c133
-rw-r--r--src/lib/ecore/efl_model_accessor_view_private.h5
-rw-r--r--src/lib/ecore/efl_model_composite_boolean.c81
-rw-r--r--src/lib/ecore/efl_model_composite_boolean.eo15
-rw-r--r--src/lib/ecore/efl_model_composite_selection.c237
-rw-r--r--src/lib/ecore/efl_model_composite_selection.eo21
-rw-r--r--src/lib/ecore/efl_model_composite_selection_children.eo7
-rw-r--r--src/lib/ecore/efl_model_item.c2
-rw-r--r--src/tests/efl/efl_test_model_composite.c (renamed from src/tests/efl/efl_test_model_composite_boolean.c)111
12 files changed, 577 insertions, 43 deletions
diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am
index 4158ae5185..755d4bb0f8 100644
--- a/src/Makefile_Ecore.am
+++ b/src/Makefile_Ecore.am
@@ -30,6 +30,8 @@ ecore_eolian_files = \
lib/ecore/efl_model_container_item.eo \
lib/ecore/efl_model_composite_boolean.eo \
lib/ecore/efl_model_composite_boolean_children.eo \
+ lib/ecore/efl_model_composite_selection.eo \
+ lib/ecore/efl_model_composite_selection_children.eo \
$(ecore_eolian_files_legacy)
ecore_eolian_c = $(ecore_eolian_files:%.eo=%.eo.c)
@@ -90,6 +92,8 @@ lib/ecore/efl_model_container.c \
lib/ecore/efl_model_container_item.c \
lib/ecore/efl_model_container_private.h \
lib/ecore/efl_model_composite_boolean.c \
+lib/ecore/efl_model_composite_selection.c \
+lib/ecore/efl_model_accessor_view.c \
lib/ecore/ecore_pipe.c \
lib/ecore/ecore_poller.c \
lib/ecore/ecore_time.c \
diff --git a/src/Makefile_Efl.am b/src/Makefile_Efl.am
index 58601aabdd..25dde93a7c 100644
--- a/src/Makefile_Efl.am
+++ b/src/Makefile_Efl.am
@@ -193,7 +193,7 @@ TESTS += tests/efl/efl_suite
tests_efl_efl_suite_SOURCES = \
tests/efl/efl_suite.c \
tests/efl/efl_test_model_container.c \
-tests/efl/efl_test_model_composite_boolean.c \
+tests/efl/efl_test_model_composite.c \
tests/efl/efl_suite.h
tests_efl_efl_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
diff --git a/src/lib/ecore/Ecore_Eo.h b/src/lib/ecore/Ecore_Eo.h
index 502f6419ec..aadd2ba136 100644
--- a/src/lib/ecore/Ecore_Eo.h
+++ b/src/lib/ecore/Ecore_Eo.h
@@ -115,6 +115,8 @@ EAPI Efl_Future *efl_future_iterator_race(Eina_Iterator *it);
#include "efl_model_container_item.eo.h"
#include "efl_model_composite_boolean.eo.h"
#include "efl_model_composite_boolean_children.eo.h"
+#include "efl_model_composite_selection.eo.h"
+#include "efl_model_composite_selection_children.eo.h"
/**
* @}
diff --git a/src/lib/ecore/efl_model_accessor_view.c b/src/lib/ecore/efl_model_accessor_view.c
new file mode 100644
index 0000000000..2afe1dc8f3
--- /dev/null
+++ b/src/lib/ecore/efl_model_accessor_view.c
@@ -0,0 +1,133 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eina.h"
+#include "Eo.h"
+
+#include "efl_model_accessor_view_private.h"
+
+typedef struct _Efl_Model_Accessor
+{
+ Eina_Accessor vtable;
+ Eina_Accessor *real_accessor;
+ void *pdata;
+ Efl_Model_Accessor_View_Constructor_Cb cb;
+ Eina_Array *children;
+} Efl_Model_Accessor;
+
+static void
+_efl_model_accessor_setup(Efl_Model_Accessor *acc,
+ Eina_Accessor* real_accessor,
+ Efl_Model_Accessor_View_Constructor_Cb ctor,
+ void* pdata);
+
+static Eina_Bool
+_efl_model_acessor_get_at(Efl_Model_Accessor *acc, unsigned int idx, void **data)
+{
+ void* eo;
+ Eo *p;
+ Eo *child;
+
+ if(eina_accessor_data_get(acc->real_accessor, idx, &eo))
+ {
+ p = eo;
+ child = acc->cb(acc->pdata, p);
+ if(!acc->children)
+ {
+ acc->children = eina_array_new(32);
+ }
+ eina_array_push(acc->children, child);
+ *data = child;
+ return !!*data;
+ }
+ else
+ return EINA_FALSE;
+}
+
+static void *
+_efl_model_acessor_get_container(Efl_Model_Accessor *acc)
+{
+ return eina_accessor_container_get(acc->real_accessor);
+}
+
+static void
+_efl_model_acessor_free(Efl_Model_Accessor *acc)
+{
+ if (acc->real_accessor)
+ {
+ eina_accessor_free(acc->real_accessor);
+ acc->real_accessor = NULL;
+ }
+
+ if(acc->children)
+ {
+ unsigned i;
+ Eina_Array_Iterator iterator;
+ Eo* item;
+
+ EINA_ARRAY_ITER_NEXT(acc->children, i, item, iterator)
+ {
+ efl_del(item);
+ }
+ eina_array_free(acc->children);
+ acc->children = NULL;
+ }
+
+ free(acc);
+}
+
+static Eina_Bool
+_efl_model_acessor_lock(Efl_Model_Accessor *acc)
+{
+ return eina_accessor_lock(acc->real_accessor);
+}
+
+static Eina_Bool
+_efl_model_acessor_unlock(Efl_Model_Accessor *acc)
+{
+ return eina_accessor_unlock(acc->real_accessor);
+}
+
+static Efl_Model_Accessor *
+_efl_model_acessor_clone(Efl_Model_Accessor *acc EINA_UNUSED)
+{
+ Efl_Model_Accessor* accessor = calloc(1, sizeof(Efl_Model_Accessor));
+ _efl_model_accessor_setup(accessor, eina_accessor_clone(acc->real_accessor),
+ acc->cb, acc->pdata);
+ return accessor;
+}
+
+static void
+_efl_model_accessor_setup(Efl_Model_Accessor *acc,
+ Eina_Accessor* real_accessor,
+ Efl_Model_Accessor_View_Constructor_Cb ctor,
+ void* pdata)
+{
+ acc->vtable.version = EINA_ACCESSOR_VERSION;
+ acc->vtable.get_at = FUNC_ACCESSOR_GET_AT(_efl_model_acessor_get_at);
+ acc->vtable.get_container = FUNC_ACCESSOR_GET_CONTAINER(_efl_model_acessor_get_container);
+ acc->vtable.free = FUNC_ACCESSOR_FREE(_efl_model_acessor_free);
+
+ acc->vtable.lock = FUNC_ACCESSOR_LOCK(_efl_model_acessor_lock);
+ acc->vtable.unlock = FUNC_ACCESSOR_LOCK(_efl_model_acessor_unlock);
+
+ acc->vtable.clone = FUNC_ACCESSOR_CLONE(_efl_model_acessor_clone);
+
+ EINA_MAGIC_SET(&acc->vtable, EINA_MAGIC_ACCESSOR);
+
+ acc->real_accessor = real_accessor;
+ acc->cb = ctor;
+ acc->pdata = pdata;
+}
+
+Eina_Accessor* efl_model_accessor_view_new(Eina_Accessor* accessor,
+ Efl_Model_Accessor_View_Constructor_Cb ctor,
+ void* data)
+{
+ Efl_Model_Accessor* acc = calloc(1, sizeof(Efl_Model_Accessor));
+ _efl_model_accessor_setup(acc, accessor, ctor, data);
+ return &acc->vtable;
+}
+
+
diff --git a/src/lib/ecore/efl_model_accessor_view_private.h b/src/lib/ecore/efl_model_accessor_view_private.h
new file mode 100644
index 0000000000..c44f2ec3cb
--- /dev/null
+++ b/src/lib/ecore/efl_model_accessor_view_private.h
@@ -0,0 +1,5 @@
+
+typedef Eo*(*Efl_Model_Accessor_View_Constructor_Cb)(void* data, Eo* child);
+
+Eina_Accessor* efl_model_accessor_view_new(Eina_Accessor* accessor,
+ Efl_Model_Accessor_View_Constructor_Cb constructor, void* data);
diff --git a/src/lib/ecore/efl_model_composite_boolean.c b/src/lib/ecore/efl_model_composite_boolean.c
index 7ec344d05c..62107bbffc 100644
--- a/src/lib/ecore/efl_model_composite_boolean.c
+++ b/src/lib/ecore/efl_model_composite_boolean.c
@@ -18,7 +18,6 @@ typedef struct _Efl_Model_Hash_Value
typedef struct _Efl_Model_Composite_Boolean_Data
{
Efl_Model *composite_model;
- Eina_Array *bool_children_cache;
Eina_Array *empty_properties;
Eina_Hash *values; // [property_name, Efl_Model_Hash_Value*]
} Efl_Model_Composite_Boolean_Data;
@@ -39,8 +38,14 @@ typedef struct _Efl_Model_Accessor_Slice
Efl_Model_Composite_Boolean_Data *parent_pd;
Efl_Promise *promise;
unsigned int index;
+ Eina_Array *bool_children_cache;
} Efl_Model_Accessor_Slice;
+static void
+efl_model_accessor_slice_setup(Efl_Model_Accessor_Slice *acc,
+ Efl_Model *parent, Efl_Model_Composite_Boolean_Data *parent_pd, Efl_Promise *promise, int start);
+
+
static Eina_Value *
_value_clone(const Eina_Value *value)
{
@@ -66,7 +71,8 @@ _future_error_forward_cb(void *data, Efl_Event const *event)
static Eina_Bool
_bit_get(const unsigned char *bitstream, unsigned int idx)
{
- return (bitstream[idx / 8] >> (idx % 8)) & 1u;
+ Eina_Bool b = (bitstream[idx / 8] >> (idx % 8)) & 1u;
+ return b;
}
static void
@@ -160,8 +166,8 @@ _efl_model_composite_boolean_children_efl_model_property_get(Eo *obj EINA_UNUSED
Eina_Value *eina_value = eina_value_new(EINA_VALUE_TYPE_UCHAR);
if (hv->bits_count <= pd->index)
{
- unsigned char f = hv->default_value;
- eina_value_set(eina_value, f);
+ unsigned char f = hv->default_value;
+ eina_value_set(eina_value, f);
}
else
{
@@ -194,7 +200,7 @@ _efl_model_composite_boolean_children_efl_model_property_set(Eo *obj EINA_UNUSED
{
Eina_Bool flag = EINA_FALSE;
- if (eina_value_type_get(value) == EINA_VALUE_TYPE_UCHAR)
+ if (eina_value_type_get(value) != EINA_VALUE_TYPE_UCHAR)
{
efl_promise_failed_set(promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
return rfuture;
@@ -285,7 +291,7 @@ static Eina_Bool
efl_model_acessor_slice_get_at(Efl_Model_Accessor_Slice *acc, unsigned int idx, void **data)
{
Efl_Model *child_bool;
- Eina_Array *children_cache = acc->parent_pd->bool_children_cache;
+ Eina_Array *children_cache = acc->bool_children_cache;
/* NOTE: Efl.Model.Composite.Boolean must alloc the cache with the correct size
and NULL initialized. */
@@ -295,7 +301,7 @@ efl_model_acessor_slice_get_at(Efl_Model_Accessor_Slice *acc, unsigned int idx,
return EINA_FALSE;
}
- child_bool = eina_array_data_get(children_cache, idx);
+ child_bool = eina_array_data_get(children_cache, acc->index + idx);
if (!child_bool)
{
@@ -306,13 +312,13 @@ efl_model_acessor_slice_get_at(Efl_Model_Accessor_Slice *acc, unsigned int idx,
if (child)
{
- Efl_Model_Composite_Boolean_Children_Data *pd;
+ Efl_Model_Composite_Boolean_Children_Data *cpd;
child_bool = efl_add(EFL_MODEL_COMPOSITE_BOOLEAN_CHILDREN_CLASS, NULL);
- pd = efl_data_scope_get(child_bool, EFL_MODEL_COMPOSITE_BOOLEAN_CHILDREN_CLASS);
+ cpd = efl_data_scope_get(child_bool, EFL_MODEL_COMPOSITE_BOOLEAN_CHILDREN_CLASS);
- pd->parent_pd = acc->parent_pd;
- pd->composite_child = efl_ref(child);
- pd->index = acc->index++;
+ cpd->parent_pd = acc->parent_pd;
+ cpd->composite_child = efl_ref(child);
+ cpd->index = acc->index + idx;
eina_array_data_set(children_cache, idx, child_bool);
}
@@ -331,9 +337,15 @@ efl_model_acessor_slice_get_container(Efl_Model_Accessor_Slice *acc)
static void
efl_model_acessor_slice_free(Efl_Model_Accessor_Slice *acc)
{
- if (acc->real_accessor)
+ if (acc->bool_children_cache)
+ {
+ _bool_children_cache_array_free(acc->bool_children_cache);
+ acc->bool_children_cache = NULL;
+ }
+
+ if (acc->real_accessor)
{
- eina_accessor_free(acc->real_accessor);
+ /* eina_accessor_free(acc->real_accessor); */
acc->real_accessor = NULL;
}
@@ -364,12 +376,31 @@ efl_model_acessor_slice_unlock(Efl_Model_Accessor_Slice *acc)
static Efl_Model_Accessor_Slice *
efl_model_acessor_slice_clone(Efl_Model_Accessor_Slice *acc EINA_UNUSED)
{
- return NULL;
+ Efl_Model_Accessor_Slice* new_accessor = calloc(1, sizeof(Efl_Model_Accessor_Slice));
+ Eina_Array* children_cache;
+ unsigned i;
+ unsigned children_count = eina_array_count(acc->bool_children_cache);
+
+ efl_model_accessor_slice_setup(new_accessor, acc->parent, acc->parent_pd, NULL
+ , acc->index);
+ new_accessor->real_accessor = eina_accessor_clone(acc->real_accessor);
+
+ children_cache = eina_array_new(children_count);
+ for (i = 0 ; i < children_count; ++i)
+ {
+ // NOTE: eina_array_push do not accept NULL
+ eina_array_push(children_cache, (void*)0x01);
+ eina_array_data_set(children_cache, i, NULL);
+ }
+
+ new_accessor->bool_children_cache = children_cache;
+
+ return new_accessor;
}
static void
efl_model_accessor_slice_setup(Efl_Model_Accessor_Slice *acc,
- Efl_Model *parent, Efl_Model_Composite_Boolean_Data *parent_pd, Efl_Promise *promise)
+ Efl_Model *parent, Efl_Model_Composite_Boolean_Data *parent_pd, Efl_Promise *promise, int start)
{
acc->vtable.version = EINA_ACCESSOR_VERSION;
acc->vtable.get_at = FUNC_ACCESSOR_GET_AT(efl_model_acessor_slice_get_at);
@@ -386,6 +417,7 @@ efl_model_accessor_slice_setup(Efl_Model_Accessor_Slice *acc,
acc->parent = efl_ref(parent);
acc->parent_pd = parent_pd;
acc->promise = promise;
+ acc->index = start;
}
static void
@@ -413,8 +445,8 @@ _efl_model_composite_boolean_slice_then_cb(void *data, Efl_Event const *event)
Eina_Array *children_cache;
unsigned int i;
- if (slice_acc->parent_pd->bool_children_cache)
- _bool_children_cache_array_free(slice_acc->parent_pd->bool_children_cache);
+ if (slice_acc->bool_children_cache)
+ _bool_children_cache_array_free(slice_acc->bool_children_cache);
children_cache = eina_array_new(*children_count);
for (i = 0 ; i < *children_count; ++i)
@@ -424,7 +456,7 @@ _efl_model_composite_boolean_slice_then_cb(void *data, Efl_Event const *event)
eina_array_data_set(children_cache, i, NULL);
}
- slice_acc->parent_pd->bool_children_cache = children_cache;
+ slice_acc->bool_children_cache = children_cache;
efl_promise_value_set(slice_acc->promise, slice_acc, (Eina_Free_Cb)&eina_accessor_free);
}
@@ -460,11 +492,6 @@ efl_model_hash_value_free(void *p)
static void
_composite_model_data_reset(Efl_Model_Composite_Boolean_Data *pd)
{
- if (pd->bool_children_cache)
- {
- _bool_children_cache_array_free(pd->bool_children_cache);
- pd->bool_children_cache = NULL;
- }
if (pd->composite_model)
{
@@ -494,7 +521,7 @@ _efl_model_composite_boolean_efl_object_destructor(Eo *obj, Efl_Model_Composite_
}
static void
-_efl_model_composite_boolean_composite_model_set(Eo *obj EINA_UNUSED,
+_efl_model_composite_boolean_efl_ui_view_model_set(Eo *obj EINA_UNUSED,
Efl_Model_Composite_Boolean_Data *pd, Efl_Model *model)
{
if (pd->composite_model)
@@ -506,7 +533,7 @@ _efl_model_composite_boolean_composite_model_set(Eo *obj EINA_UNUSED,
}
static Efl_Model *
-_efl_model_composite_boolean_composite_model_get(Eo *obj EINA_UNUSED, Efl_Model_Composite_Boolean_Data *pd)
+_efl_model_composite_boolean_efl_ui_view_model_get(Eo *obj EINA_UNUSED, Efl_Model_Composite_Boolean_Data *pd)
{
return pd->composite_model;
}
@@ -586,7 +613,7 @@ _efl_model_composite_boolean_efl_model_children_slice_get(Eo *obj, Efl_Model_Com
composite_future = efl_future_all(futures[0], futures[1]);
accessor = calloc(1, sizeof(Efl_Model_Accessor_Slice));
- efl_model_accessor_slice_setup(accessor, obj, pd, promise);
+ efl_model_accessor_slice_setup(accessor, obj, pd, promise, start);
efl_future_then(composite_future, &_efl_model_composite_boolean_slice_then_cb,
&_efl_model_composite_boolean_slice_error_cb, NULL, accessor);
diff --git a/src/lib/ecore/efl_model_composite_boolean.eo b/src/lib/ecore/efl_model_composite_boolean.eo
index cdca17e998..bb7eacbb11 100644
--- a/src/lib/ecore/efl_model_composite_boolean.eo
+++ b/src/lib/ecore/efl_model_composite_boolean.eo
@@ -1,17 +1,7 @@
-class Efl.Model.Composite.Boolean (Efl.Object, Efl.Model)
+class Efl.Model.Composite.Boolean (Efl.Object, Efl.Model, Efl.Ui.View)
{
[[Efl model composite boolean class]]
methods {
- @property composite_model {
- [[Composite model]]
- set {
- }
- get {
- }
- values {
- model: Efl.Model; [[Efl model]]
- }
- }
property_add {
[[Adds property]]
params {
@@ -29,9 +19,10 @@ class Efl.Model.Composite.Boolean (Efl.Object, Efl.Model)
Efl.Model.children_count_get;
Efl.Model.child_add;
Efl.Model.child_del;
+ Efl.Ui.View.model { set; get; }
}
constructors {
- .composite_model;
+ Efl.Ui.View.model;
.property_add @optional;
}
}
diff --git a/src/lib/ecore/efl_model_composite_selection.c b/src/lib/ecore/efl_model_composite_selection.c
new file mode 100644
index 0000000000..8311f1c7b5
--- /dev/null
+++ b/src/lib/ecore/efl_model_composite_selection.c
@@ -0,0 +1,237 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eina.h"
+#include "Efl.h"
+#include <Ecore.h>
+#include "Eo.h"
+
+#include "efl_model_composite_selection.eo.h"
+#include "efl_model_accessor_view_private.h"
+
+typedef struct _Efl_Model_Composite_Selection_Data
+{
+ Efl_Model_Composite_Selection* obj;
+ struct {
+ Efl_Model* selected_child;
+ } exclusive_data;
+ Eina_Bool is_exclusive;
+
+} Efl_Model_Composite_Selection_Data;
+
+typedef struct _Efl_Model_Composite_Selection_Children_Data
+{
+ Efl_Model_Composite_Selection_Data* pd;
+} Efl_Model_Composite_Selection_Children_Data;
+
+static Eo*
+_efl_model_composite_selection_efl_object_constructor(Eo *obj,
+ Efl_Model_Composite_Selection_Data *pd EINA_UNUSED)
+{
+ efl_constructor(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS));
+ efl_model_composite_boolean_property_add(obj, "selected", EINA_FALSE);
+ pd->obj = obj;
+ return obj;
+}
+
+/***************************/
+static void _select_property_failed(void* data, Efl_Event const* event)
+{
+ Efl_Promise* promise = data;
+ Efl_Future_Event_Failure* fail = event->info;
+ efl_promise_failed_set(promise, fail->error);
+ efl_unref(promise);
+}
+
+static void _select_property_then(void* data, Efl_Event const* event EINA_UNUSED)
+{
+ Efl_Promise* promise = data;
+ Eina_Value* v = eina_value_new(EINA_VALUE_TYPE_UCHAR);
+ eina_value_set(v, EINA_TRUE);
+ efl_promise_value_set(promise, v, (Eina_Free_Cb)&eina_value_free);
+ efl_unref(promise);
+}
+
+static void _select_slice_then(void* data EINA_UNUSED, Efl_Event const* event)
+{
+ Efl_Future_Event_Success* success = event->info;
+ Eina_Accessor* accessor = eina_accessor_clone(success->value);
+ Eina_Value value;
+ Efl_Model* child;
+
+ eina_accessor_data_get(accessor, 0, (void**)&child);
+
+ eina_value_setup(&value, EINA_VALUE_TYPE_UCHAR);
+ eina_value_set(&value, EINA_TRUE);
+
+ efl_future_then(efl_model_property_set(child, "selected", &value),
+ _select_property_then, _select_property_failed, NULL, efl_ref(success->next));
+}
+
+static void _select_error(void* data EINA_UNUSED, Efl_Event const* event)
+{
+ Efl_Future_Event_Failure* fail = event->info;
+ efl_promise_failed_set(fail->next, fail->error);
+}
+
+/***************************/
+
+static Efl_Future*
+_efl_model_composite_selection_select(Eo *obj,
+ Efl_Model_Composite_Selection_Data *pd, int idx)
+{
+ return efl_future_then(efl_model_children_slice_get(obj, idx, 1),
+ &_select_slice_then,
+ &_select_error,
+ NULL, pd);
+}
+
+static void
+_efl_model_composite_selection_exclusive_selection_set(Eo *obj EINA_UNUSED,
+ Efl_Model_Composite_Selection_Data *pd, Eina_Bool exclusive)
+{
+ pd->is_exclusive = exclusive;
+}
+
+static Eina_Bool
+_efl_model_composite_selection_exclusive_selection_get(Eo *obj EINA_UNUSED,
+ Efl_Model_Composite_Selection_Data *pd)
+{
+ return pd->is_exclusive;
+}
+
+static void
+_exclusive_future_link_then_cb(void* data, Efl_Event const* event)
+{
+ Efl_Future_Event_Success *success = event->info;
+ efl_promise_value_set(data, success->value, NULL); // We would need to move the value
+ // Needs to set exclusive_child
+ efl_unref(data);
+}
+
+static void
+_exclusive_future_link_failed(void* data, Efl_Event const* event)
+{
+ Efl_Future_Event_Failure *failed = event->info;
+ efl_promise_failed_set(data, failed->error);
+ efl_unref(data);
+}
+
+static void
+_exclusive_unselected_then_cb(void* data, Efl_Event const* event)
+{
+ Efl_Future_Event_Success *success = event->info;
+ Eina_Value* true_value = eina_value_new(EINA_VALUE_TYPE_UCHAR);
+ eina_value_set(true_value, EINA_TRUE);
+ efl_future_then(efl_model_property_set(data, "selected", true_value),
+ _exclusive_future_link_then_cb, _exclusive_future_link_failed,
+ NULL, efl_ref(success->next));
+ efl_unref(data);
+}
+
+static void
+_exclusive_unselected_failed(void* data, Efl_Event const* event)
+{
+ Efl_Future_Event_Failure *failed = event->info;
+ efl_promise_failed_set(data, failed->error);
+ efl_unref(data);
+}
+
+static Efl_Future *
+_efl_model_composite_selection_children_efl_model_property_set(Eo *obj EINA_UNUSED,
+ Efl_Model_Composite_Selection_Children_Data *pd, const char *property, const Eina_Value *value)
+{
+ if(!strcmp("selected", property))
+ {
+ unsigned long v = EINA_FALSE;
+ if(eina_value_type_get(value) != EINA_VALUE_TYPE_ULONG)
+ {
+ Eina_Value to;
+ eina_value_setup(&to, EINA_VALUE_TYPE_ULONG);
+ if(eina_value_convert(value, &to))
+ eina_value_get(&to, &v);
+ eina_value_flush(&to);
+ }
+ else
+ eina_value_get(value, &v);
+
+ if(v && pd->pd->is_exclusive)
+ {
+ if(pd->pd->exclusive_data.selected_child)
+ {
+ // unset current selected
+ // set this child as current
+ // bookkeep this child as current selection
+ // return with future for this asynchronous task
+ Eina_Value* false_value = eina_value_new(EINA_VALUE_TYPE_UCHAR);
+ eina_value_set(false_value, EINA_FALSE);
+ return
+ efl_future_then(efl_model_property_set
+ (pd->pd->exclusive_data.selected_child,
+ property, false_value),
+ _exclusive_unselected_then_cb,
+ _exclusive_unselected_failed, NULL,
+ efl_ref(obj));
+ }
+ else
+ {
+ Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
+ Efl_Future *rfuture = efl_promise_future_get(promise);
+ Eina_Value* true_value = eina_value_new(EINA_VALUE_TYPE_UCHAR);
+ eina_value_set(true_value, EINA_TRUE);
+ efl_future_then(efl_model_property_set
+ (efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CHILDREN_CLASS),
+ "selected", true_value),
+ _exclusive_future_link_then_cb, _exclusive_future_link_failed,
+ NULL, efl_ref(promise));
+ return rfuture;
+ }
+ }
+ else
+ {
+
+ }
+ }
+
+ return efl_model_property_set(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CHILDREN_CLASS),
+ property, value);
+}
+
+static Eo* _construct_children(void* pdata, Eo* child)
+{
+ Efl_Model_Composite_Selection_Data* pd = pdata;
+ Eo* new_child = efl_add(EFL_MODEL_COMPOSITE_SELECTION_CHILDREN_CLASS, NULL);
+ Efl_Model_Composite_Selection_Children_Data* data = efl_data_scope_get
+ (new_child, EFL_MODEL_COMPOSITE_SELECTION_CHILDREN_CLASS);
+ data->pd = pd;
+ efl_composite_attach(new_child, efl_ref(child));
+ return new_child;
+}
+
+static void _composited_children_slice_get_then(void* data, Efl_Event const* event)
+{
+ Efl_Future_Event_Success* success = event->info;
+ Eina_Accessor* accessor = success->value;
+ efl_promise_value_set(success->next,
+ efl_model_accessor_view_new(eina_accessor_clone(accessor), &_construct_children,
+ data),
+ (Eina_Free_Cb)&eina_accessor_free);
+}
+static void _composited_children_slice_get_fail(void* data EINA_UNUSED, Efl_Event const* event)
+{
+ Efl_Future_Event_Failure* failure = event->info;
+ efl_promise_failed_set(failure->next, failure->error);
+}
+
+static Efl_Future *
+_efl_model_composite_selection_efl_model_children_slice_get(Eo *obj, Efl_Model_Composite_Selection_Data *pd, unsigned int start, unsigned int count)
+{
+ Efl_Future* composited_future = efl_model_children_slice_get
+ (efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS),start, count);
+ return efl_future_then(composited_future, &_composited_children_slice_get_then,
+ &_composited_children_slice_get_fail, NULL, pd);
+}
+
+#include "efl_model_composite_selection.eo.c"
+#include "efl_model_composite_selection_children.eo.c"
diff --git a/src/lib/ecore/efl_model_composite_selection.eo b/src/lib/ecore/efl_model_composite_selection.eo
new file mode 100644
index 0000000000..bccf0070ad
--- /dev/null
+++ b/src/lib/ecore/efl_model_composite_selection.eo
@@ -0,0 +1,21 @@
+class Efl.Model.Composite.Selection (Efl.Model.Composite.Boolean)
+{
+ [[Efl model composite selection class]]
+ methods {
+ select {
+ params {
+ idx: int;
+ }
+ return: future<eina.value>;
+ }
+ @property exclusive_selection {
+ values {
+ exclusive: bool;
+ }
+ }
+ }
+ implements {
+ Efl.Object.constructor;
+ Efl.Model.children_slice_get;
+ }
+}
diff --git a/src/lib/ecore/efl_model_composite_selection_children.eo b/src/lib/ecore/efl_model_composite_selection_children.eo
new file mode 100644
index 0000000000..2ea5c950ef
--- /dev/null
+++ b/src/lib/ecore/efl_model_composite_selection_children.eo
@@ -0,0 +1,7 @@
+class Efl.Model.Composite.Selection.Children (Efl.Object, Efl.Model)
+{
+ [[Efl model composite selection children class]]
+ implements {
+ Efl.Model.property_set;
+ }
+}
diff --git a/src/lib/ecore/efl_model_item.c b/src/lib/ecore/efl_model_item.c
index 5f61ee79e9..8afc0a77a4 100644
--- a/src/lib/ecore/efl_model_item.c
+++ b/src/lib/ecore/efl_model_item.c
@@ -169,9 +169,9 @@ _efl_model_item_efl_model_child_add(Eo *obj, Efl_Model_Item_Data *sd)
eina_error_set(EFL_MODEL_ERROR_UNKNOWN);
return NULL;
}
+ cevt.index = eina_list_count(sd->children);
sd->children = eina_list_append(sd->children, child);
cevt.child = child;
- cevt.index = eina_list_count(sd->children);
efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILD_ADDED, &cevt);
efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &cevt.index);
return child;
diff --git a/src/tests/efl/efl_test_model_composite_boolean.c b/src/tests/efl/efl_test_model_composite.c
index 2b94fa7aa0..a38e776746 100644
--- a/src/tests/efl/efl_test_model_composite_boolean.c
+++ b/src/tests/efl/efl_test_model_composite.c
@@ -39,6 +39,7 @@ typedef struct _Test_Child_Data
const int child_number = 3;
const int base_ints[] = { 41, 42, 43 };
+const Eina_Bool base_selections[] = { EINA_FALSE, EINA_FALSE, EINA_TRUE };
static void
_future_error_then(void *data EINA_UNUSED, Efl_Event const* event EINA_UNUSED)
@@ -79,6 +80,45 @@ _property_get_then(void *data, Efl_Event const *event)
}
static void
+_selection_property_get_then(void *data, Efl_Event const *event)
+{
+ Test_Child_Data *t = data;
+ Eina_Accessor *value_itt = (Eina_Accessor*)((Efl_Future_Event_Success*)event->info)->value;
+ int v_int = 0;
+ Eina_Bool v_bool = EINA_FALSE;
+
+
+#define EFL_TEST_value_get_and_compare(it, i, var, cmp) \
+ do { \
+ Eina_Value *vvv = NULL; \
+ if (!eina_accessor_data_get(it, i, (void **)&vvv) || !vvv || \
+ !eina_value_get(vvv, &var)) \
+ { \
+ fprintf(stderr, "Could not get value!\n"); fflush(stderr); \
+ ck_abort_msg("Could not get value"); \
+ return; \
+ } \
+ else if(var != cmp) \
+ { \
+ fprintf(stderr, "Value did not match!\n"); fflush(stderr); \
+ ck_abort_msg("Value did not match"); \
+ return; \
+ } \
+ else \
+ fprintf(stderr, "Value matched\n"); fflush(stderr); \
+ } while(0)
+
+ EFL_TEST_value_get_and_compare(value_itt, 0, v_bool, base_selections[t->idx]);
+ EFL_TEST_value_get_and_compare(value_itt, 1, v_int, base_ints[t->idx]);
+
+ t->tdata->child_count++;
+ if (t->tdata->child_count == 3)
+ t->tdata->success_flag = EINA_TRUE;
+
+#undef EFL_TEST_value_get_and_compare
+}
+
+static void
_children_slice_get_then(void *data, Efl_Event const* event)
{
Eina_Accessor *children = (Eina_Accessor *)((Efl_Future_Event_Success*)event->info)->value;
@@ -86,7 +126,6 @@ _children_slice_get_then(void *data, Efl_Event const* event)
Test_Child_Data *t;
unsigned int i = 0;
- fprintf(stderr, "OPAAAAAAa\n");
EINA_ACCESSOR_FOREACH(children, i, child)
{
Efl_Future *futures[3] = {NULL,};
@@ -105,6 +144,31 @@ _children_slice_get_then(void *data, Efl_Event const* event)
}
}
+static void
+_selection_children_slice_get_then(void *data, Efl_Event const* event)
+{
+ Eina_Accessor *children = (Eina_Accessor *)((Efl_Future_Event_Success*)event->info)->value;
+ Efl_Model *child;
+ Test_Child_Data *t;
+ unsigned int i = 0;
+
+ EINA_ACCESSOR_FOREACH(children, i, child)
+ {
+ Efl_Future *futures[2] = {NULL,};
+ Efl_Future *future_all = NULL;
+
+ futures[0] = efl_model_property_get(child, "selected");
+ futures[1] = efl_model_property_get(child, "test_p_int");
+
+ future_all = efl_future_all(futures[0], futures[1]);
+
+ t = calloc(1, sizeof(Test_Child_Data));
+ t->tdata = data;
+ t->idx = i;
+ efl_future_then(future_all, _selection_property_get_then, _future_error_then, NULL, t);
+ }
+}
+
START_TEST(efl_test_model_composite_boolean)
{
Efl_Model_Item *base_model, *child;
@@ -131,7 +195,7 @@ START_TEST(efl_test_model_composite_boolean)
}
model = efl_add(EFL_MODEL_COMPOSITE_BOOLEAN_CLASS, NULL,
- efl_model_composite_boolean_composite_model_set(efl_added, base_model),
+ efl_ui_view_model_set(efl_added, base_model),
efl_model_composite_boolean_property_add(efl_added, "test_p_true", EINA_TRUE),
efl_model_composite_boolean_property_add(efl_added, "test_p_false", EINA_FALSE));
ck_assert(!!model);
@@ -148,8 +212,51 @@ START_TEST(efl_test_model_composite_boolean)
}
END_TEST
+START_TEST(efl_test_model_composite_selection)
+{
+ Efl_Model_Item *base_model, *child;
+ int i;
+ Eina_Value v;
+ Efl_Model_Composite_Selection *model;
+ Test_Data *tdata;
+ Efl_Future *future;
+
+ fail_if(!ecore_init(), "ERROR: Cannot init Ecore!\n");
+ fail_if(!efl_object_init(), "ERROR: Cannot init EO!\n");
+
+ eina_value_setup(&v, EINA_VALUE_TYPE_INT);
+
+ base_model = efl_add(EFL_MODEL_ITEM_CLASS, NULL);
+ ck_assert(!!base_model);
+
+ for (i = 0; i < child_number; ++i)
+ {
+ child = efl_model_child_add(base_model);
+ ck_assert(!!child);
+ ck_assert(eina_value_set(&v, base_ints[i]));
+ efl_model_property_set(child, "test_p_int", &v);
+ }
+
+ model = efl_add(EFL_MODEL_COMPOSITE_SELECTION_CLASS, NULL,
+ efl_ui_view_model_set(efl_added, base_model));
+ ck_assert(!!model);
+ efl_model_composite_selection_select(model, 2);
+
+ tdata = calloc(1, sizeof(Test_Data));
+ future = efl_model_children_slice_get(model, 0, 0);
+ efl_future_then(future, _selection_children_slice_get_then, _future_error_then, NULL, tdata);
+
+ ecore_main_loop_iterate();
+
+ ck_assert(tdata->success_flag);
+
+ ecore_shutdown();
+}
+END_TEST
+
void
efl_test_case_model_composite_boolean(TCase *tc)
{
tcase_add_test(tc, efl_test_model_composite_boolean);
+ tcase_add_test(tc, efl_test_model_composite_selection);
}