forked from enlightenment/efl
ecore: Add efl_model_copmosite_selection model
This commit is contained in:
parent
743f52a05b
commit
df9f2e0772
|
@ -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 \
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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"
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
|
@ -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)
|
||||
{
|
||||
eina_accessor_free(acc->real_accessor);
|
||||
_bool_children_cache_array_free(acc->bool_children_cache);
|
||||
acc->bool_children_cache = NULL;
|
||||
}
|
||||
|
||||
if (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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
@ -78,6 +79,45 @@ _property_get_then(void *data, Efl_Event const *event)
|
|||
#undef _value_get_and_compare
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue