summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <cedric.bail@free.fr>2019-01-03 14:54:18 -0800
committerCedric BAIL <cedric.bail@free.fr>2019-01-30 12:06:11 -0800
commit1dadeac05e14d2ba50b3bb430fe386d7a50a9d56 (patch)
tree4949f513c92dfa8465dbc6dd3daa90fa87389a98
parent95a9cc90d1ce646c541bdb2c08caf9de4ecf0881 (diff)
downloadefl-1dadeac05e14d2ba50b3bb430fe386d7a50a9d56.tar.gz
ecore: add an index property on Efl.Model_Composite and handle children_slice_get.
This will enable inheriting class to not have to implement as much code. This patch fix also all class that use Efl.Model_Composite and its test. Reviewed-by: SangHyeon Jade Lee <sh10233.lee@samsung.com> Differential Revision: https://phab.enlightenment.org/D7654
-rw-r--r--src/Makefile_Ecore.am2
-rw-r--r--src/lib/ecore/Ecore_Eo.h2
-rw-r--r--src/lib/ecore/efl_model_composite.c140
-rw-r--r--src/lib/ecore/efl_model_composite.eo23
-rw-r--r--src/lib/ecore/efl_model_composite_boolean.c189
-rw-r--r--src/lib/ecore/efl_model_composite_boolean.eo3
-rw-r--r--src/lib/ecore/efl_model_composite_boolean_children.eo23
-rw-r--r--src/lib/ecore/efl_model_composite_selection.c369
-rw-r--r--src/lib/ecore/efl_model_composite_selection.eo1
-rw-r--r--src/lib/ecore/efl_model_composite_selection_children.eo9
-rw-r--r--src/lib/ecore/meson.build2
-rw-r--r--src/tests/efl/efl_test_model_composite.c7
12 files changed, 337 insertions, 433 deletions
diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am
index 364bac41d6..2cbc5a13d2 100644
--- a/src/Makefile_Ecore.am
+++ b/src/Makefile_Ecore.am
@@ -47,9 +47,7 @@ ecore_eolian_files_public = \
lib/ecore/efl_model_container.eo \
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 \
lib/ecore/efl_model_composite.eo \
lib/ecore/efl_model_view.eo
diff --git a/src/lib/ecore/Ecore_Eo.h b/src/lib/ecore/Ecore_Eo.h
index f8d8626848..d0a6bc0b9f 100644
--- a/src/lib/ecore/Ecore_Eo.h
+++ b/src/lib/ecore/Ecore_Eo.h
@@ -115,9 +115,7 @@ EAPI Eo *efl_main_loop_get(void);
#include "efl_model_container_item.eo.h"
#include "efl_model_composite.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"
#include "efl_model_view.eo.h"
/**
diff --git a/src/lib/ecore/efl_model_composite.c b/src/lib/ecore/efl_model_composite.c
index 2803675b36..9beb6ac3fd 100644
--- a/src/lib/ecore/efl_model_composite.c
+++ b/src/lib/ecore/efl_model_composite.c
@@ -10,11 +10,18 @@
#include "efl_model_composite.eo.h"
+#define _CHILD_INDEX "child.index"
+
typedef struct _Efl_Model_Composite_Data Efl_Model_Composite_Data;
struct _Efl_Model_Composite_Data
{
Efl_Model *source;
+
+ unsigned int index;
+
+ Eina_Bool need_index : 1;
+ Eina_Bool set_index : 1;
};
static void
@@ -47,8 +54,39 @@ _efl_model_composite_efl_object_finalize(Eo *obj, Efl_Model_Composite_Data *pd)
}
static void
+_efl_model_composite_index_set(Eo *obj EINA_UNUSED, Efl_Model_Composite_Data *pd, unsigned int index)
+{
+ if (pd->set_index || !pd->source)
+ return ;
+ pd->index = index;
+ pd->set_index = EINA_TRUE;
+}
+
+static unsigned int
+_efl_model_composite_index_get(const Eo *obj, Efl_Model_Composite_Data *pd)
+{
+ Eina_Value *fetch = NULL;
+ unsigned int r = 0xFFFFFFFF;
+
+ if (pd->set_index)
+ return pd->index;
+ if (pd->need_index)
+ return 0xFFFFFFFF;
+
+ fetch = efl_model_property_get(obj, _CHILD_INDEX);
+ if (!eina_value_uint_convert(fetch, &r))
+ return 0xFFFFFFFF;
+ eina_value_free(fetch);
+
+ return r;
+}
+
+static void
_efl_model_composite_efl_ui_view_model_set(Eo *obj EINA_UNUSED, Efl_Model_Composite_Data *pd, Efl_Model *model)
{
+ Eina_Iterator *properties;
+ const char *property;
+
if (pd->source != NULL)
{
ERR("Source already set for composite model. It can only be set once.");
@@ -60,6 +98,19 @@ _efl_model_composite_efl_ui_view_model_set(Eo *obj EINA_UNUSED, Efl_Model_Compos
efl_event_callback_forwarder_priority_add(model, EFL_MODEL_EVENT_CHILD_REMOVED, EFL_CALLBACK_PRIORITY_BEFORE, obj);
efl_event_callback_forwarder_priority_add(model, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, EFL_CALLBACK_PRIORITY_BEFORE, obj);
efl_event_callback_forwarder_priority_add(model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, EFL_CALLBACK_PRIORITY_BEFORE, obj);
+
+ pd->need_index = EINA_TRUE;
+
+ properties = efl_model_properties_get(pd->source);
+ EINA_ITERATOR_FOREACH(properties, property)
+ {
+ if (!strcmp(property, _CHILD_INDEX))
+ {
+ pd->need_index = EINA_FALSE;
+ break;
+ }
+ }
+ eina_iterator_free(properties);
}
static Efl_Model *
@@ -69,9 +120,18 @@ _efl_model_composite_efl_ui_view_model_get(const Eo *obj EINA_UNUSED, Efl_Model_
}
static Eina_Future *
-_efl_model_composite_efl_model_property_set(Eo *obj EINA_UNUSED, Efl_Model_Composite_Data *pd,
+_efl_model_composite_efl_model_property_set(Eo *obj, Efl_Model_Composite_Data *pd,
const char *property, Eina_Value *value)
{
+ if (pd->need_index && !strcmp(property, _CHILD_INDEX))
+ {
+ if (pd->set_index || !pd->source)
+ return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_READ_ONLY);
+ if (!eina_value_uint_convert(value, &pd->index))
+ return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_UNKNOWN);
+ pd->set_index = EINA_TRUE;
+ return efl_loop_future_resolved(obj, eina_value_uint_init(pd->index));
+ }
return efl_model_property_set(pd->source, property, value);
}
@@ -79,12 +139,27 @@ static Eina_Value *
_efl_model_composite_efl_model_property_get(const Eo *obj EINA_UNUSED, Efl_Model_Composite_Data *pd,
const char *property)
{
+ if (pd->need_index && !strcmp(property, _CHILD_INDEX))
+ {
+ if (pd->set_index)
+ return eina_value_uint_new(pd->index);
+ return eina_value_error_new(EAGAIN);
+ }
return efl_model_property_get(pd->source, property);
}
static Eina_Iterator *
_efl_model_composite_efl_model_properties_get(const Eo *obj EINA_UNUSED, Efl_Model_Composite_Data *pd)
{
+ if (pd->need_index)
+ {
+ static const char *composite_properties[] = {
+ _CHILD_INDEX
+ };
+
+ return eina_multi_iterator_new(efl_model_properties_get(pd->source),
+ EINA_C_ARRAY_ITERATOR_NEW(composite_properties));
+ }
return efl_model_properties_get(pd->source);
}
@@ -94,13 +169,72 @@ _efl_model_composite_efl_model_children_count_get(const Eo *obj EINA_UNUSED, Efl
return efl_model_children_count_get(pd->source);
}
+typedef struct _Efl_Model_Composite_Slice_Request Efl_Model_Composite_Slice_Request;
+struct _Efl_Model_Composite_Slice_Request
+{
+ const Efl_Class *self;
+ Eo *parent;
+ unsigned int start;
+};
+
+static Eina_Value
+_efl_model_composite_then(Eo *o EINA_UNUSED, void *data, const Eina_Value v)
+{
+ Efl_Model_Composite_Slice_Request *req = data;
+ unsigned int i, len;
+ Eina_Value r = EINA_VALUE_EMPTY;
+ Eo *target = NULL;
+
+ eina_value_array_setup(&r, EINA_VALUE_TYPE_OBJECT, 4);
+
+ EINA_VALUE_ARRAY_FOREACH(&v, len, i, target)
+ {
+ Eo *composite;
+
+ // First set the Model to be used as a source so that we the newly object
+ // can know if it needs to retain the information regarding its index.
+ composite = efl_add(req->self, req->parent,
+ efl_ui_view_model_set(efl_added, target),
+ efl_model_composite_index_set(efl_added, req->start + i));
+
+ eina_value_array_append(&r, composite);
+ }
+
+ return r;
+}
+
+static void
+_efl_model_composite_clean(Eo *o EINA_UNUSED, void *data, const Eina_Future *dead_future EINA_UNUSED)
+{
+ Efl_Model_Composite_Slice_Request *req = data;
+
+ efl_unref(req->parent);
+ free(data);
+}
+
static Eina_Future *
-_efl_model_composite_efl_model_children_slice_get(Eo *obj EINA_UNUSED,
+_efl_model_composite_efl_model_children_slice_get(Eo *obj,
Efl_Model_Composite_Data *pd,
unsigned int start,
unsigned int count)
{
- return efl_model_children_slice_get(pd->source, start, count);
+ Efl_Model_Composite_Slice_Request *req;
+ Eina_Future *f;
+
+ f = efl_model_children_slice_get(pd->source, start, count);
+ if (!f) return NULL;
+
+ req = malloc(sizeof (Efl_Model_Composite_Slice_Request));
+ if (!req) return efl_loop_future_rejected(obj, ENOMEM);
+
+ req->self = efl_class_get(obj);
+ req->parent = efl_ref(obj);
+ req->start = start;
+
+ return efl_future_then(obj, f, .success_type = EINA_VALUE_TYPE_ARRAY,
+ .success = _efl_model_composite_then,
+ .free = _efl_model_composite_clean,
+ .data = req);
}
static Efl_Object *
diff --git a/src/lib/ecore/efl_model_composite.eo b/src/lib/ecore/efl_model_composite.eo
index d353a2e9f4..a1baad1b99 100644
--- a/src/lib/ecore/efl_model_composite.eo
+++ b/src/lib/ecore/efl_model_composite.eo
@@ -1,6 +1,24 @@
class Efl.Model_Composite extends Efl.Model_Loop implements Efl.Ui.View
{
- [[Efl model for all composite class which provide a unified API to set source of data]]
+ [[Efl model for all composite class which provide a unified API to set source of data.
+
+ This class also provide an @Efl.Model.property "$child.index" that match the value of @.index.]]
+ methods {
+ @property index {
+ [[Position of this object in the parent model.]]
+ set {
+ [[Set the index. It can only be set before the object is finalized,
+ but after the Model it compose is set and only if that Model does
+ not provide an index already.]]
+ }
+ get {
+ [[Get the index. It will only work after the object has been finalized.]]
+ }
+ values {
+ index: uint; [[Index of the object in the parent model. The index is uniq and start from zero.]]
+ }
+ }
+ }
implements {
Efl.Object.destructor;
Efl.Object.finalize;
@@ -12,4 +30,7 @@ class Efl.Model_Composite extends Efl.Model_Loop implements Efl.Ui.View
Efl.Model.child_add;
Efl.Model.child_del;
}
+ constructors {
+ .index;
+ }
}
diff --git a/src/lib/ecore/efl_model_composite_boolean.c b/src/lib/ecore/efl_model_composite_boolean.c
index 2db0bc768e..5cfa96150a 100644
--- a/src/lib/ecore/efl_model_composite_boolean.c
+++ b/src/lib/ecore/efl_model_composite_boolean.c
@@ -4,15 +4,14 @@
#include <Efl_Core.h>
-#include "efl_model_composite_boolean_children.eo.h"
#include "efl_model_composite_private.h"
typedef struct _Efl_Model_Composite_Boolean_Data Efl_Model_Composite_Boolean_Data;
-typedef struct _Efl_Model_Composite_Boolean_Children_Data Efl_Model_Composite_Boolean_Children_Data;
typedef struct _Efl_Model_Composite_Boolean_Value Efl_Model_Composite_Boolean_Value;
struct _Efl_Model_Composite_Boolean_Data
{
+ Efl_Model_Composite_Boolean_Data *parent;
Eina_Hash *values;
};
@@ -29,127 +28,92 @@ struct _Efl_Model_Composite_Boolean_Value
Eina_Bool default_value;
};
-struct _Efl_Model_Composite_Boolean_Children_Data
-{
- Efl_Model_Composite_Boolean_Data *parent;
- unsigned int index;
-};
-
-/**************** efl_mmodel_composite_boolean_children **************/
-
-static void
-_efl_model_composite_boolean_children_index_set(Eo *obj EINA_UNUSED,
- Efl_Model_Composite_Boolean_Children_Data *pd,
- unsigned int index)
-{
- if (pd->parent) // This is set during finalize
- return ;
-
- pd->index = index;
-}
-
-static unsigned int
-_efl_model_composite_boolean_children_index_get(const Eo *obj EINA_UNUSED,
- Efl_Model_Composite_Boolean_Children_Data *pd)
-{
- return pd->index;
-}
-
-static Efl_Object *
-_efl_model_composite_boolean_children_efl_object_finalize(Eo *obj,
- Efl_Model_Composite_Boolean_Children_Data *pd)
-{
- Eo *parent;
-
- parent = efl_parent_get(obj);
- if (!parent) return NULL;
- pd->parent = efl_data_scope_get(parent, EFL_MODEL_COMPOSITE_BOOLEAN_CLASS);
-
- return obj;
-}
-
static Eina_Iterator *
-_efl_model_composite_boolean_children_efl_model_properties_get(const Eo *obj,
- Efl_Model_Composite_Boolean_Children_Data *pd)
+_efl_model_composite_boolean_efl_model_properties_get(const Eo *obj,
+ Efl_Model_Composite_Boolean_Data *pd)
{
EFL_MODEL_COMPOSITE_PROPERTIES_SUPER(props,
- obj, EFL_MODEL_COMPOSITE_BOOLEAN_CHILDREN_CLASS,
- eina_hash_iterator_key_new(pd->parent->values),
- "child.index");
+ obj, EFL_MODEL_COMPOSITE_BOOLEAN_CLASS,
+ eina_hash_iterator_key_new(pd->parent->values));
return props;
}
static Eina_Value *
-_efl_model_composite_boolean_children_efl_model_property_get(const Eo *obj,
- Efl_Model_Composite_Boolean_Children_Data *pd,
- const char *property)
+_efl_model_composite_boolean_efl_model_property_get(const Eo *obj,
+ Efl_Model_Composite_Boolean_Data *pd,
+ const char *property)
{
Efl_Model_Composite_Boolean_Value *v;
Eina_Stringshare *s;
Eina_Bool flag;
+ unsigned int index;
if (property == NULL) return NULL;
- if (strcmp(property, "child.index") == 0)
- return eina_value_uint_new(pd->index);
+ // If we do not have a parent set that his a COMPOSITE_BOOLEAN, then we should just forward up the call
+ if (!pd->parent)
+ return efl_model_property_get(efl_super(obj, EFL_MODEL_COMPOSITE_BOOLEAN_CLASS), property);
+
+ // Check if this is requesting a defined boolean property
+ // Property are defined and their value are stored on the parent COMPOSITE_BOOLEAN
s = eina_stringshare_add(property);
v = eina_hash_find(pd->parent->values, s);
eina_stringshare_del(s);
- if (!v)
- return efl_model_property_get(efl_super(obj, EFL_MODEL_COMPOSITE_BOOLEAN_CHILDREN_CLASS),
- property);
+ if (!v) // Not a property handle by this object, forward
+ return efl_model_property_get(efl_super(obj, EFL_MODEL_COMPOSITE_BOOLEAN_CLASS), property);
+
+ index = efl_model_composite_index_get(obj);
// As an optimization we do optimistically allocate the boolean array
// Better would be to have a sparse boolean array
- if ((pd->index >> 3) >= v->buffer_count)
+ if ((index >> 3) >= v->buffer_count)
flag = v->default_value;
else
- flag = v->buffer[pd->index >> 3] & (((unsigned char)1) << (pd->index & 0x7));
+ flag = v->buffer[index >> 3] & (((unsigned char)1) << (index & 0x7));
return eina_value_bool_new(!!flag);
}
static Eina_Future *
-_efl_model_composite_boolean_children_efl_model_property_set(Eo *obj,
- Efl_Model_Composite_Boolean_Children_Data *pd,
- const char *property, Eina_Value *value)
+_efl_model_composite_boolean_efl_model_property_set(Eo *obj,
+ Efl_Model_Composite_Boolean_Data *pd,
+ const char *property, Eina_Value *value)
{
Efl_Model_Composite_Boolean_Value *v;
Eina_Stringshare *s;
- Eina_Value b = EINA_VALUE_EMPTY;
Eina_Bool flag;
+ unsigned int index;
if (!property)
return efl_loop_future_rejected(obj,
EFL_MODEL_ERROR_UNKNOWN);
- if (strcmp(property, "child.index") == 0)
- return efl_loop_future_rejected(obj,
- EFL_MODEL_ERROR_READ_ONLY);
+ // If we do not have a parent set that his a COMPOSITE_BOOLEAN, then we should just forward up the call
+ if (!pd->parent)
+ return efl_model_property_set(efl_super(obj, EFL_MODEL_COMPOSITE_BOOLEAN_CLASS),
+ property, value);
+
+ // Check if this is requesting a defined boolean property
+ // Property are defined and their value are stored on the parent COMPOSITE_BOOLEAN
s = eina_stringshare_add(property);
v = eina_hash_find(pd->parent->values, s);
eina_stringshare_del(s);
if (!v)
- return efl_model_property_set(efl_super(obj, EFL_MODEL_COMPOSITE_BOOLEAN_CHILDREN_CLASS),
+ return efl_model_property_set(efl_super(obj, EFL_MODEL_COMPOSITE_BOOLEAN_CLASS),
property, value);
- eina_value_setup(&b, EINA_VALUE_TYPE_BOOL);
- if (!eina_value_convert(value, &b))
- return efl_loop_future_rejected(obj,
- EFL_MODEL_ERROR_UNKNOWN);
- if (!eina_value_get(value, &flag))
- return efl_loop_future_rejected(obj,
- EFL_MODEL_ERROR_UNKNOWN);
+ if (!eina_value_bool_convert(value, &flag))
+ return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_UNKNOWN);
- eina_value_flush(&b);
+ index = efl_model_composite_index_get(obj);
// We are optimistically allocating the boolean buffer now.
// Aligning it on 64bits
- if (v->buffer_count < (((pd->index) >> 3) | 0x7) + 1)
+ if (v->buffer_count < (((index) >> 3) | 0x7) + 1)
{
- unsigned int rcount = (((pd->index | 0xF) >> 3) | 0x7) + 1;
+ unsigned int rcount = (((index | 0xF) >> 3) | 0x7) + 1;
unsigned char *tmp;
tmp = realloc(v->buffer, rcount);
@@ -161,9 +125,9 @@ _efl_model_composite_boolean_children_efl_model_property_set(Eo *obj,
// It is assumed that during slice get the buffer is properly sized
if (flag)
- v->buffer[pd->index >> 3] |= ((unsigned char)1) << (pd->index & 0x7);
+ v->buffer[index >> 3] |= ((unsigned char)1) << (index & 0x7);
else
- v->buffer[pd->index >> 3] &= ~(((unsigned char)1) << (pd->index & 0x7));
+ v->buffer[index >> 3] &= ~(((unsigned char)1) << (index & 0x7));
// Calling "properties,changed" event
efl_model_properties_changed(obj, property);
@@ -172,49 +136,6 @@ _efl_model_composite_boolean_children_efl_model_property_set(Eo *obj,
return efl_loop_future_resolved(obj, eina_value_bool_init(!!flag));
}
-/**************** efl_model_composite_boolean **************/
-typedef struct _Efl_Model_Slice_Request Efl_Model_Slice_Request;
-struct _Efl_Model_Slice_Request
-{
- Eo *parent;
- unsigned int start;
-};
-
-static Eina_Value
-_efl_model_composite_boolean_then(Eo *o EINA_UNUSED, void *data, const Eina_Value v)
-{
- Efl_Model_Slice_Request *req = data;
- unsigned int i, len;
- Eina_Value r = EINA_VALUE_EMPTY;
- Eo *target = NULL;
-
- eina_value_array_setup(&r, EINA_VALUE_TYPE_OBJECT, 4);
-
- EINA_VALUE_ARRAY_FOREACH(&v, len, i, target)
- {
- Eo *composite;
-
- // It would have been nice if I could have just overriden the object
- // function, but this would allow only one composite model
- composite = efl_add(EFL_MODEL_COMPOSITE_BOOLEAN_CHILDREN_CLASS, req->parent,
- efl_model_composite_boolean_children_index_set(efl_added, req->start + i),
- efl_ui_view_model_set(efl_added, target));
-
- eina_value_array_append(&r, composite);
- }
-
- return r;
-}
-
-static void
-_efl_model_composite_boolean_clean(Eo *o EINA_UNUSED, void *data, const Eina_Future *dead_future EINA_UNUSED)
-{
- Efl_Model_Slice_Request *req = data;
-
- efl_unref(req->parent);
- free(req);
-}
-
static void
_boolean_value_free(void *data)
{
@@ -233,11 +154,17 @@ _boolean_value_free(void *data)
static Eo *
_efl_model_composite_boolean_efl_object_constructor(Eo *obj, Efl_Model_Composite_Boolean_Data *pd)
{
+ Eo *parent;
obj = efl_constructor(efl_super(obj, EFL_MODEL_COMPOSITE_BOOLEAN_CLASS));
if (!obj) return NULL;
pd->values = eina_hash_stringshared_new(_boolean_value_free);
+ // Only add a reference to the parent if it is actually a COMPOSITE_BOOLEAN_CLASS
+ // The root typically doesn't have any boolean property, only its child do
+ parent = efl_parent_get(obj);
+ if (efl_isa(parent, EFL_MODEL_COMPOSITE_BOOLEAN_CLASS))
+ pd->parent = efl_data_scope_get(parent, EFL_MODEL_COMPOSITE_BOOLEAN_CLASS);
return obj;
}
@@ -280,28 +207,4 @@ _efl_model_composite_boolean_boolean_del(Eo *obj EINA_UNUSED,
eina_stringshare_del(s);
}
-static Eina_Future *
-_efl_model_composite_boolean_efl_model_children_slice_get(Eo *obj,
- Efl_Model_Composite_Boolean_Data *pd EINA_UNUSED,
- unsigned int start, unsigned int count)
-{
- Efl_Model_Slice_Request *req;
- Eina_Future *f;
-
- f = efl_model_children_slice_get(efl_super(obj, EFL_MODEL_COMPOSITE_BOOLEAN_CLASS),
- start, count);
-
- req = malloc(sizeof (Efl_Model_Slice_Request));
- if (!req) return efl_loop_future_rejected(obj,
- ENOMEM);
- req->parent = efl_ref(obj);
- req->start = start;
-
- return efl_future_then(obj, f, .success_type = EINA_VALUE_TYPE_ARRAY,
- .success = _efl_model_composite_boolean_then,
- .free = _efl_model_composite_boolean_clean,
- .data = req);
-}
-
#include "efl_model_composite_boolean.eo.c"
-#include "efl_model_composite_boolean_children.eo.c"
diff --git a/src/lib/ecore/efl_model_composite_boolean.eo b/src/lib/ecore/efl_model_composite_boolean.eo
index 47c7e3cfb6..8bbc664b52 100644
--- a/src/lib/ecore/efl_model_composite_boolean.eo
+++ b/src/lib/ecore/efl_model_composite_boolean.eo
@@ -17,8 +17,9 @@ class Efl.Model_Composite_Boolean extends Efl.Model_Composite
}
}
implements {
+ Efl.Model.properties { get; }
+ Efl.Model.property { get; set; }
Efl.Object.constructor;
Efl.Object.destructor;
- Efl.Model.children_slice_get;
}
}
diff --git a/src/lib/ecore/efl_model_composite_boolean_children.eo b/src/lib/ecore/efl_model_composite_boolean_children.eo
deleted file mode 100644
index d06a9cc424..0000000000
--- a/src/lib/ecore/efl_model_composite_boolean_children.eo
+++ /dev/null
@@ -1,23 +0,0 @@
-class Efl.Model_Composite_Boolean_Children extends Efl.Model_Composite
-{
- [[Efl model composite boolean children class]]
- methods {
- @property index {
- [[Position of children in the parent model.]]
- set {
- [[Set the index. It can only be set before the object is finalized.]]
- }
- get {
- [[Get the index.]]
- }
- values {
- index: uint; [[The index of the child in the parent model.]]
- }
- }
- }
- implements {
- Efl.Model.properties { get; }
- Efl.Model.property { get; set; }
- Efl.Object.finalize;
- }
-}
diff --git a/src/lib/ecore/efl_model_composite_selection.c b/src/lib/ecore/efl_model_composite_selection.c
index 18db24cfc3..3bcd7b4829 100644
--- a/src/lib/ecore/efl_model_composite_selection.c
+++ b/src/lib/ecore/efl_model_composite_selection.c
@@ -12,30 +12,32 @@
#include "efl_model_composite_private.h"
typedef struct _Efl_Model_Composite_Selection_Data Efl_Model_Composite_Selection_Data;
-typedef struct _Efl_Model_Composite_Selection_Children_Data Efl_Model_Composite_Selection_Children_Data;
struct _Efl_Model_Composite_Selection_Data
{
+ Efl_Model_Composite_Selection_Data *parent;
unsigned long last;
Eina_Bool exclusive : 1;
Eina_Bool none : 1;
};
-struct _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_Model_Composite_Selection_Data *pd)
{
+ Eo *parent;
+
obj = efl_constructor(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS));
efl_model_composite_boolean_add(obj, "selected", EINA_FALSE);
pd->last = -1;
+ parent = efl_parent_get(obj);
+ if (efl_isa(parent, EFL_MODEL_COMPOSITE_SELECTION_CLASS))
+ pd->parent = efl_data_scope_get(parent, EFL_MODEL_COMPOSITE_SELECTION_CLASS);
+
return obj;
}
@@ -43,14 +45,12 @@ static Eina_Value
_commit_change(Eo *child, void *data EINA_UNUSED, const Eina_Value v)
{
Efl_Model_Composite_Selection_Data *pd;
- Eina_Value *vc = NULL;
Eina_Value *selected = NULL;
Eina_Bool selflag = EINA_FALSE;
if (v.type == EINA_VALUE_TYPE_ERROR)
goto on_error;
- vc = efl_model_property_get(child, "Child.index");
selected = efl_model_property_get(child, "selected");
pd = efl_data_scope_get(efl_parent_get(child), EFL_MODEL_COMPOSITE_SELECTION_CLASS);
@@ -61,7 +61,7 @@ _commit_change(Eo *child, void *data EINA_UNUSED, const Eina_Value v)
{
// select case
pd->none = EINA_FALSE;
- eina_value_ulong_get(vc, &pd->last);
+ pd->last = efl_model_composite_index_get(child);
efl_event_callback_call(child, EFL_MODEL_COMPOSITE_SELECTION_EVENT_SELECTED, child);
}
else
@@ -69,7 +69,7 @@ _commit_change(Eo *child, void *data EINA_UNUSED, const Eina_Value v)
// unselect case
unsigned long last;
- eina_value_ulong_get(vc, &last);
+ last = efl_model_composite_index_get(child);
if (pd->last == last)
{
pd->last = 0;
@@ -79,7 +79,6 @@ _commit_change(Eo *child, void *data EINA_UNUSED, const Eina_Value v)
}
on_error:
- eina_value_free(vc);
eina_value_free(selected);
return v;
}
@@ -180,78 +179,6 @@ _unselect_slice_then(Eo *obj EINA_UNUSED,
return v;
}
-static Eina_Iterator *
-_efl_model_composite_selection_efl_model_properties_get(const Eo *obj,
- Efl_Model_Composite_Selection_Data *pd EINA_UNUSED)
-{
- EFL_MODEL_COMPOSITE_PROPERTIES_SUPER(props,
- obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS,
- NULL,
- "selected", "exclusive");
- return props;
-}
-
-static Eina_Future *
-_efl_model_composite_selection_efl_model_property_set(Eo *obj,
- Efl_Model_Composite_Selection_Data *pd,
- const char *property, Eina_Value *value)
-{
- Eina_Value vf = EINA_VALUE_EMPTY;
-
- if (!strcmp("exclusive", property))
- {
- Eina_Bool exclusive = pd->exclusive;
- Eina_Bool changed;
-
- vf = eina_value_bool_init(exclusive);
- eina_value_convert(value, &vf);
- eina_value_bool_get(&vf, &exclusive);
-
- changed = (!pd->exclusive != !exclusive);
- pd->exclusive = !!exclusive;
-
- if (changed) efl_model_properties_changed(obj, "exclusive");
-
- return efl_loop_future_resolved(obj, vf);
- }
-
- if (!strcmp("selected", property))
- {
- Eina_Value vl = EINA_VALUE_EMPTY;
- unsigned long l = 0;
- Eina_Bool success = EINA_TRUE;
-
- vl = eina_value_ulong_init(0);
- success &= eina_value_convert(value, &vl);
- success &= eina_value_ulong_get(&vl, &l);
- if (!success)
- return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_INCORRECT_VALUE);
-
- return efl_future_then(obj, efl_model_children_slice_get(obj, l, 1),
- .success = _select_slice_then,
- .success_type = EINA_VALUE_TYPE_ARRAY);
- }
-
- return efl_model_property_set(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS),
- property, value);
-}
-
-static Eina_Value *
-_efl_model_composite_selection_efl_model_property_get(const Eo *obj, Efl_Model_Composite_Selection_Data *pd, const char *property)
-{
- if (!strcmp("exclusive", property))
- return eina_value_bool_new(pd->exclusive);
- if (!strcmp("selected", property))
- {
- if (pd->none)
- return eina_value_error_new(EFL_MODEL_ERROR_INCORRECT_VALUE);
- else
- return eina_value_ulong_new(pd->last);
- }
-
- return efl_model_property_get(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS), property);
-}
-
static Eina_Value
_regenerate_error(void *data,
const Eina_Value v,
@@ -282,17 +209,6 @@ _untangle_array(void *data EINA_UNUSED,
return va;
}
-static Eina_Iterator *
-_efl_model_composite_selection_children_efl_model_properties_get(const Eo *obj,
- Efl_Model_Composite_Selection_Children_Data *pd EINA_UNUSED)
-{
- EFL_MODEL_COMPOSITE_PROPERTIES_SUPER(props,
- obj, EFL_MODEL_COMPOSITE_SELECTION_CHILDREN_CLASS,
- NULL,
- "selected");
- return props;
-}
-
static Eina_Value
_untangle_error(void *data, Eina_Error err)
{
@@ -304,7 +220,7 @@ _untangle_error(void *data, Eina_Error err)
// where we could end up here.
Eina_Error *error = calloc(1, sizeof (Eina_Error));
- f = efl_model_property_set(efl_super(child, EFL_MODEL_COMPOSITE_SELECTION_CHILDREN_CLASS),
+ f = efl_model_property_set(efl_super(child, EFL_MODEL_COMPOSITE_SELECTION_CLASS),
"selected", eina_value_bool_new(EINA_FALSE));
// Once this is done, we need to repropagate the error
*error = err;
@@ -313,178 +229,141 @@ _untangle_error(void *data, Eina_Error err)
return eina_future_as_value(f);
}
+static Eina_Iterator *
+_efl_model_composite_selection_efl_model_properties_get(const Eo *obj,
+ Efl_Model_Composite_Selection_Data *pd EINA_UNUSED)
+{
+ EFL_MODEL_COMPOSITE_PROPERTIES_SUPER(props,
+ obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS,
+ NULL,
+ "self.selected", "child.selected", "exclusive");
+ return props;
+}
+
static Eina_Future *
-_efl_model_composite_selection_children_efl_model_property_set(Eo *obj,
- Efl_Model_Composite_Selection_Children_Data *pd EINA_UNUSED,
- const char *property, Eina_Value *value)
+_efl_model_composite_selection_efl_model_property_set(Eo *obj,
+ Efl_Model_Composite_Selection_Data *pd,
+ const char *property, Eina_Value *value)
{
- Eina_Value *ve = NULL;
- Eina_Value *vb = NULL;
- Eina_Value lvb = EINA_VALUE_EMPTY;
- Eina_Bool success = EINA_TRUE;
- Eina_Bool exclusive = EINA_FALSE;
- Eina_Bool prevflag = EINA_FALSE, newflag = EINA_FALSE;
- Eina_Future *chain;
-
- if (strcmp("selected", property))
- return efl_model_property_set(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CHILDREN_CLASS),
- property, value);
-
- vb = efl_model_property_get(obj, "selected");
- success &= eina_value_bool_get(vb, &prevflag);
- eina_value_free(vb);
-
- lvb = eina_value_bool_init(prevflag);
- success &= eina_value_convert(value, &lvb);
- success &= eina_value_bool_get(&lvb, &newflag);
- eina_value_flush(&lvb);
-
- if (!success)
- return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_INCORRECT_VALUE);
-
- // Nothing changed
- if (newflag == prevflag)
- return efl_loop_future_resolved(obj,
- eina_value_bool_init(newflag));
-
- ve = efl_model_property_get(efl_parent_get(obj), "exclusive");
- eina_value_bool_get(ve, &exclusive);
- eina_value_free(ve);
-
- // First store the new value in the boolean model we inherit from
- chain = efl_model_property_set(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CHILDREN_CLASS),
- "selected", value);
-
- // Now act !
- if (exclusive)
+ Eina_Value vf = EINA_VALUE_EMPTY;
+
+ if (!strcmp("exclusive", property))
{
- // We are here either, because we weren't and are after this call
- // or because we were selected and are not anymore. In the later case,
- // there is nothing special to do, just normal commit change will do.
- if (!newflag)
- {
- Efl_Model_Composite_Selection_Data *ppd;
- Eina_Value *index;
- unsigned int i = 0;
+ Eina_Bool exclusive = pd->exclusive;
+ Eina_Bool changed;
- index = efl_model_property_get(obj, "child.index");
- if (!eina_value_uint_get(index, &i))
- goto commit_change;
+ vf = eina_value_bool_init(exclusive);
+ eina_value_convert(value, &vf);
+ eina_value_bool_get(&vf, &exclusive);
- ppd = efl_data_scope_get(efl_parent_get(obj), EFL_MODEL_COMPOSITE_SELECTION_CLASS);
- if (ppd->last == i && !newflag)
- ppd->none = EINA_TRUE;
- }
- else
- {
- Eo *parent;
- Eina_Value *vs;
- unsigned long selected = 0;
+ changed = (!pd->exclusive != !exclusive);
+ pd->exclusive = !!exclusive;
- // In this case we need to first unselect the previously selected one
- // and then commit the change to this one.
+ if (changed) efl_model_properties_changed(obj, "exclusive");
- // Fetch the one to unselect
- vs = efl_model_property_get(efl_parent_get(obj), "selected");
- // Check if there was any selected
- if (eina_value_type_get(vs) == EINA_VALUE_TYPE_ERROR)
- {
- eina_value_free(vs);
- goto commit_change;
- }
- success = eina_value_ulong_get(vs, &selected);
- eina_value_free(vs);
-
- if (!success)
- return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_INCORRECT_VALUE);
-
- // There was, need to unselect the previous one along setting the new value
- parent = efl_parent_get(obj);
- chain = eina_future_all(chain,
- efl_future_then(parent, efl_model_children_slice_get(parent, selected, 1),
- .success = _unselect_slice_then,
- .success_type = EINA_VALUE_TYPE_ARRAY));
-
- chain = eina_future_then_easy(chain,
- .success_type = EINA_VALUE_TYPE_ARRAY,
- .success = _untangle_array,
- .data = obj,
- .error = _untangle_error);
- }
+ return efl_loop_future_resolved(obj, vf);
}
- commit_change:
- return efl_future_then(obj, chain,
- .success = _commit_change);
-}
+ if (!strcmp("child.selected", property))
+ {
+ unsigned long l = 0;
-typedef struct _Selection_Children_Request Selection_Children_Request;
-struct _Selection_Children_Request
-{
- Efl_Model *parent;
+ if (!eina_value_ulong_convert(value, &l))
+ return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_INCORRECT_VALUE);
- unsigned int start;
-};
+ return efl_future_then(obj, efl_model_children_slice_get(obj, l, 1),
+ .success = _select_slice_then,
+ .success_type = EINA_VALUE_TYPE_ARRAY);
+ }
-static Eina_Value
-_slice_get(Eo *o EINA_UNUSED,
- void *data,
- const Eina_Value v)
-{
- Selection_Children_Request *req = data;
- unsigned int length, it;
- Eo *composited = NULL;
- Eina_Value r = EINA_VALUE_EMPTY;
+ if (pd->parent && !strcmp("self.selected", property))
+ {
+ Eina_Bool prevflag = EINA_FALSE, newflag = EINA_FALSE;
+ Eina_Bool exclusive = EINA_FALSE;
+ Eina_Bool success;
+ Eina_Value *prev;
+ Eina_Future *chain;
- eina_value_array_setup(&r, EINA_VALUE_TYPE_OBJECT, 4);
+ prev = efl_model_property_get(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS), "selected");
+ success = eina_value_bool_get(prev, &prevflag);
+ success &= eina_value_bool_convert(value, &newflag);
- EINA_VALUE_ARRAY_FOREACH(&v, length, it, composited)
- {
- Eo *compositing;
+ if (!success) return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_INCORRECT_VALUE);
- compositing = efl_add(EFL_MODEL_COMPOSITE_SELECTION_CHILDREN_CLASS, req->parent,
- efl_model_composite_boolean_children_index_set(efl_added, req->start + it),
- efl_ui_view_model_set(efl_added, composited));
- eina_value_array_append(&r, compositing);
- }
+ // Nothing changed
+ if (newflag == prevflag)
+ return efl_loop_future_resolved(obj, eina_value_bool_init(newflag));
- return r;
-}
+ exclusive = pd->parent->exclusive;
-static void
-_slice_clean(Eo *o EINA_UNUSED,
- void *data,
- const Eina_Future *dead_future EINA_UNUSED)
-{
- Selection_Children_Request *req = data;
+ // First store the new value in the boolean model we inherit from
+ chain = efl_model_property_set(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS),
+ "selected", value);
- efl_unref(req->parent);
- free(req);
-}
+ // Now act !
+ if (exclusive)
+ {
+ // We are here either, because we weren't and are after this call
+ // or because we were selected and are not anymore. In the later case,
+ // there is nothing special to do, just normal commit change will do.
+ if (!newflag)
+ {
+ unsigned int i;
-static Eina_Future *
-_efl_model_composite_selection_efl_model_children_slice_get(Eo *obj,
- Efl_Model_Composite_Selection_Data *pd EINA_UNUSED,
- unsigned int start, unsigned int count)
-{
- Selection_Children_Request *req;
- Eina_Future *f;
+ i = efl_model_composite_index_get(obj);
+ if (pd->parent->last == i && !newflag)
+ pd->parent->none = EINA_TRUE;
+ }
+ else
+ {
+ Eo *parent;
+ unsigned long selected = 0;
+
+ // In this case we need to first unselect the previously selected one
+ // and then commit the change to this one.
+ selected = pd->parent->last;
+
+ // There was, need to unselect the previous one along setting the new value
+ parent = efl_parent_get(obj);
+ chain = eina_future_all(chain,
+ efl_future_then(parent, efl_model_children_slice_get(parent, selected, 1),
+ .success = _unselect_slice_then,
+ .success_type = EINA_VALUE_TYPE_ARRAY));
+ chain = eina_future_then_easy(chain,
+ .success_type = EINA_VALUE_TYPE_ARRAY,
+ .success = _untangle_array,
+ .data = obj,
+ .error = _untangle_error);
+ }
+ }
- req = calloc(1, sizeof (Selection_Children_Request));
- if (!req) return efl_loop_future_rejected(obj, ENOMEM);
- req->parent = efl_ref(obj);
- req->start = start;
+ return efl_future_then(obj, chain, .success = _commit_change);
+ }
- // NOTE: We do jump on purpose EFL_MODEL_COMPOSITE_BOOLEAN_CLASS here
- f = efl_model_children_slice_get(efl_super(obj, EFL_MODEL_COMPOSITE_BOOLEAN_CLASS),
- start, count);
+ return efl_model_property_set(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS),
+ property, value);
+}
- return efl_future_then(obj, f,
- .success_type = EINA_VALUE_TYPE_ARRAY,
- .success = _slice_get,
- .free = _slice_clean,
- .data = req);
+static Eina_Value *
+_efl_model_composite_selection_efl_model_property_get(const Eo *obj, Efl_Model_Composite_Selection_Data *pd, const char *property)
+{
+ if (!strcmp("exclusive", property))
+ return eina_value_bool_new(pd->exclusive);
+ // Last selected child
+ if (!strcmp("child.selected", property))
+ {
+ if (pd->none)
+ return eina_value_error_new(EFL_MODEL_ERROR_INCORRECT_VALUE);
+ else
+ return eina_value_ulong_new(pd->last);
+ }
+ // Redirect to are we ourself selected
+ if (pd->parent && !strcmp("self.selected", property))
+ {
+ return efl_model_property_get(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS), "selected");
+ }
+
+ return efl_model_property_get(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS), property);
}
#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
index 35ecc270af..699154a78b 100644
--- a/src/lib/ecore/efl_model_composite_selection.eo
+++ b/src/lib/ecore/efl_model_composite_selection.eo
@@ -3,7 +3,6 @@ class Efl.Model_Composite_Selection extends Efl.Model_Composite_Boolean
[[Efl model composite selection class]]
implements {
Efl.Object.constructor;
- Efl.Model.children_slice_get;
Efl.Model.property { get; set; }
Efl.Model.properties { get; }
}
diff --git a/src/lib/ecore/efl_model_composite_selection_children.eo b/src/lib/ecore/efl_model_composite_selection_children.eo
deleted file mode 100644
index ce59ea2b16..0000000000
--- a/src/lib/ecore/efl_model_composite_selection_children.eo
+++ /dev/null
@@ -1,9 +0,0 @@
-class Efl.Model_Composite_Selection_Children extends Efl.Model_Composite_Boolean_Children
-{
- [[Efl model composite selection children class]]
- implements {
- Efl.Model.property { set; }
- Efl.Model.properties { get; }
- }
- /* FIXME: emitting Efl.Model_Composite_Selection.Selected. Use a default selection event! */
-}
diff --git a/src/lib/ecore/meson.build b/src/lib/ecore/meson.build
index 6fc4b2c38f..537a16dbc6 100644
--- a/src/lib/ecore/meson.build
+++ b/src/lib/ecore/meson.build
@@ -72,9 +72,7 @@ pub_eo_files = [
'efl_model_container.eo',
'efl_model_container_item.eo',
'efl_model_composite_boolean.eo',
- 'efl_model_composite_boolean_children.eo',
'efl_model_composite_selection.eo',
- 'efl_model_composite_selection_children.eo',
'efl_model_composite.eo',
'efl_model_view.eo'
]
diff --git a/src/tests/efl/efl_test_model_composite.c b/src/tests/efl/efl_test_model_composite.c
index 315c34ac5f..f48127acb4 100644
--- a/src/tests/efl/efl_test_model_composite.c
+++ b/src/tests/efl/efl_test_model_composite.c
@@ -80,17 +80,22 @@ _selection_children_slice_get_then(void *data EINA_UNUSED,
{
Eina_Value *p_int = NULL;
Eina_Value *p_bool = NULL;
+ Eina_Value *p_index = NULL;
int v_int = 0;
+ unsigned int index = 0;
Eina_Bool v_bool = EINA_FALSE;
p_bool = efl_model_property_get(child, "selected");
p_int = efl_model_property_get(child, "test_p_int");
+ p_index = efl_model_property_get(child, "child.index");
eina_value_get(p_bool, &v_bool);
eina_value_get(p_int, &v_int);
+ fail_if(!eina_value_uint_convert(p_index, &index));
fail_if(v_bool != base_selections[i]);
fail_if(v_int != base_ints[i]);
+ ck_assert_int_eq(i, index);
}
ecore_main_loop_quit();
@@ -165,7 +170,7 @@ EFL_START_TEST(efl_test_model_composite_selection)
model = efl_add_ref(EFL_MODEL_COMPOSITE_SELECTION_CLASS, efl_main_loop_get(),
efl_ui_view_model_set(efl_added, base_model));
ck_assert(!!model);
- future = efl_model_property_set(model, "selected", eina_value_int_new(2));
+ future = efl_model_property_set(model, "child.selected", eina_value_int_new(2));
eina_future_then(future, _wait_propagate, NULL, NULL);
ecore_main_loop_begin();