forked from enlightenment/efl
ecore: refactor and migrate efl.model.composite.selection to the new efl.model API.
This commit is contained in:
parent
9211fd73a7
commit
741a6c4126
|
@ -10,227 +10,447 @@
|
|||
#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_Data Efl_Model_Composite_Selection_Data;
|
||||
typedef struct _Efl_Model_Composite_Selection_Children_Data Efl_Model_Composite_Selection_Children_Data;
|
||||
|
||||
typedef struct _Efl_Model_Composite_Selection_Children_Data
|
||||
struct _Efl_Model_Composite_Selection_Data
|
||||
{
|
||||
Efl_Model_Composite_Selection_Data* pd;
|
||||
} Efl_Model_Composite_Selection_Children_Data;
|
||||
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 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;
|
||||
obj = efl_constructor(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS));
|
||||
|
||||
efl_model_composite_boolean_add(obj, "selected", EINA_FALSE);
|
||||
|
||||
pd->last = -1;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/***************************/
|
||||
static void _select_property_failed(void* data, Efl_Event const* event)
|
||||
static Eina_Value
|
||||
_commit_change(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
|
||||
{
|
||||
Efl_Promise* promise = data;
|
||||
Efl_Future_Event_Failure* fail = event->info;
|
||||
efl_promise_failed_set(promise, fail->error);
|
||||
efl_unref(promise);
|
||||
}
|
||||
Efl_Model_Composite_Selection_Data *pd;
|
||||
Efl_Model *child = data;
|
||||
Eina_Value *vc = NULL;
|
||||
Eina_Value *selected = NULL;
|
||||
Eina_Bool selflag = EINA_FALSE;
|
||||
|
||||
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);
|
||||
}
|
||||
if (v.type == EINA_VALUE_TYPE_ERROR)
|
||||
goto on_error;
|
||||
|
||||
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;
|
||||
vc = efl_model_property_get(child, "Child.index");
|
||||
selected = efl_model_property_get(child, "selected");
|
||||
|
||||
if (!eina_accessor_data_get(accessor, 0, (void **)&child)) return;
|
||||
|
||||
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));
|
||||
}
|
||||
pd = efl_data_scope_get(efl_parent_get(child), EFL_MODEL_COMPOSITE_SELECTION_CLASS);
|
||||
if (!pd) goto on_error;
|
||||
|
||||
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(const 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))
|
||||
eina_value_bool_get(selected, &selflag);
|
||||
if (selflag)
|
||||
{
|
||||
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);
|
||||
// select case
|
||||
pd->none = EINA_FALSE;
|
||||
eina_value_ulong_get(vc, &pd->last);
|
||||
efl_event_callback_call(child, EFL_MODEL_COMPOSITE_SELECTION_EVENT_SELECTED, child);
|
||||
}
|
||||
else
|
||||
{
|
||||
// unselect case
|
||||
unsigned long last;
|
||||
|
||||
if(v && pd->pd->is_exclusive)
|
||||
eina_value_ulong_get(vc, &last);
|
||||
if (pd->last == last)
|
||||
{
|
||||
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, efl_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;
|
||||
}
|
||||
pd->last = 0;
|
||||
pd->none = EINA_TRUE;
|
||||
}
|
||||
efl_event_callback_call(child, EFL_MODEL_COMPOSITE_SELECTION_EVENT_UNSELECTED, child);
|
||||
}
|
||||
|
||||
on_error:
|
||||
eina_value_free(vc);
|
||||
eina_value_free(selected);
|
||||
return v;
|
||||
}
|
||||
|
||||
static Eina_Value
|
||||
_clear_child(void *data,
|
||||
const Eina_Value v,
|
||||
const Eina_Future *dead_future EINA_UNUSED)
|
||||
{
|
||||
Efl_Model *child = data;
|
||||
|
||||
efl_del(child);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static Efl_Model *
|
||||
_select_child_get(const Eina_Value *array, unsigned int idx)
|
||||
{
|
||||
Efl_Model *ret = NULL;
|
||||
|
||||
if (eina_value_type_get(array) != EINA_VALUE_TYPE_ARRAY)
|
||||
return NULL;
|
||||
|
||||
if (idx >= eina_value_array_count(array))
|
||||
return NULL;
|
||||
|
||||
eina_value_array_get(array, idx, &ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Eina_Future *
|
||||
_check_child_change(Efl_Model *child, Eina_Bool value)
|
||||
{
|
||||
Eina_Future *r = NULL;
|
||||
Eina_Value *prev;
|
||||
Eina_Bool prevflag = EINA_FALSE;
|
||||
|
||||
prev = efl_model_property_get(child, "selected");
|
||||
eina_value_bool_get(prev, &prevflag);
|
||||
eina_value_free(prev);
|
||||
|
||||
if (prevflag & value)
|
||||
{
|
||||
r = eina_future_resolved(efl_loop_future_scheduler_get(child),
|
||||
eina_value_bool_init(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
r = efl_model_property_set(child, "selected", eina_value_bool_new(!!value));
|
||||
r = eina_future_then(r, _commit_change, child);
|
||||
r = eina_future_then(r, _clear_child, child);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static Eina_Future *
|
||||
_select_child(Efl_Model *child)
|
||||
{
|
||||
return _check_child_change(child, EINA_TRUE);
|
||||
}
|
||||
|
||||
static Eina_Future *
|
||||
_unselect_child(Efl_Model *child)
|
||||
{
|
||||
return _check_child_change(child, EINA_FALSE);
|
||||
}
|
||||
|
||||
static Eina_Value
|
||||
_select_slice_then(void *data EINA_UNUSED,
|
||||
const Eina_Value v,
|
||||
const Eina_Future *dead_future EINA_UNUSED)
|
||||
{
|
||||
Efl_Model *child = NULL;
|
||||
Eina_Future *r;
|
||||
|
||||
child = _select_child_get(&v, 0);
|
||||
if (!child) goto on_error;
|
||||
|
||||
r = _select_child(child);
|
||||
return eina_future_as_value(r);
|
||||
|
||||
on_error:
|
||||
return v;
|
||||
}
|
||||
|
||||
static Eina_Value
|
||||
_unselect_slice_then(void *data EINA_UNUSED,
|
||||
const Eina_Value v,
|
||||
const Eina_Future *dead_future EINA_UNUSED)
|
||||
{
|
||||
Efl_Model *child = NULL;
|
||||
Eina_Future *r;
|
||||
|
||||
child = _select_child_get(&v, 0);
|
||||
if (!child) goto on_error;
|
||||
|
||||
r = _unselect_child(child);
|
||||
return eina_future_as_value(r);
|
||||
|
||||
on_error:
|
||||
return v;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
vf = eina_value_bool_init(exclusive);
|
||||
eina_value_convert(value, &vf);
|
||||
eina_value_bool_get(&vf, &exclusive);
|
||||
|
||||
pd->exclusive = !!exclusive;
|
||||
|
||||
return eina_future_resolved(efl_loop_future_scheduler_get(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 eina_future_rejected(efl_loop_future_scheduler_get(obj), EFL_MODEL_ERROR_INCORRECT_VALUE);
|
||||
|
||||
return efl_future_Eina_FutureXXX_then(obj,
|
||||
eina_future_then(efl_model_children_slice_get(obj, l, 1),
|
||||
_select_slice_then, obj));
|
||||
}
|
||||
|
||||
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,
|
||||
const Eina_Future *dead_future EINA_UNUSED)
|
||||
{
|
||||
Eina_Error *error = data;
|
||||
Eina_Value r = v;
|
||||
|
||||
if (v.type == EINA_VALUE_TYPE_ERROR)
|
||||
goto cleanup;
|
||||
|
||||
r = eina_value_error_init(*error);
|
||||
|
||||
cleanup:
|
||||
free(error);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static Eina_Value
|
||||
_untangle_array(void *data,
|
||||
const Eina_Value v,
|
||||
const Eina_Future *dead_future EINA_UNUSED)
|
||||
{
|
||||
Efl_Model *child = data;
|
||||
Eina_Value va = EINA_VALUE_EMPTY;
|
||||
Eina_Future *f;
|
||||
|
||||
if (v.type == EINA_VALUE_TYPE_ERROR)
|
||||
{
|
||||
// We need to roll back the change, which means in this
|
||||
// case to unselect this child as this is the only case
|
||||
// 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),
|
||||
"selected", eina_value_bool_new(EINA_FALSE));
|
||||
// Once this is done, we need to repropagate the error
|
||||
eina_value_error_get(&v, error);
|
||||
f = eina_future_then(f, _regenerate_error, error);
|
||||
|
||||
return eina_future_as_value(f);
|
||||
}
|
||||
|
||||
// Only return the commit change, not the result of the unselect
|
||||
eina_value_array_get(&v, 0, &va);
|
||||
return va;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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 eina_future_rejected(efl_loop_future_scheduler_get(obj), EFL_MODEL_ERROR_INCORRECT_VALUE);
|
||||
|
||||
// Nothing changed
|
||||
if (newflag == prevflag)
|
||||
return eina_future_resolved(efl_loop_future_scheduler_get(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)
|
||||
{
|
||||
// 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;
|
||||
|
||||
index = efl_model_property_get(obj, "child.index");
|
||||
if (!eina_value_uint_get(index, &i))
|
||||
goto commit_change;
|
||||
|
||||
ppd = efl_data_scope_get(efl_parent_get(obj), EFL_MODEL_COMPOSITE_SELECTION_CLASS);
|
||||
if (ppd->last == i && !newflag)
|
||||
ppd->none = EINA_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Eina_Value *vs;
|
||||
unsigned long selected = 0;
|
||||
Eina_Bool success;
|
||||
|
||||
// In this case we need to first unselect the previously selected one
|
||||
// and then commit the change to this one.
|
||||
|
||||
// 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 eina_future_rejected(efl_loop_future_scheduler_get(obj),
|
||||
EFL_MODEL_ERROR_INCORRECT_VALUE);
|
||||
|
||||
// There was, need to unselect the previous one along setting the new value
|
||||
chain = eina_future_all(chain,
|
||||
eina_future_then(efl_model_children_slice_get(efl_parent_get(obj), selected, 1),
|
||||
_unselect_slice_then, NULL));
|
||||
|
||||
chain = eina_future_then(chain, _untangle_array, obj);
|
||||
}
|
||||
}
|
||||
|
||||
return efl_model_property_set(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CHILDREN_CLASS),
|
||||
property, value);
|
||||
commit_change:
|
||||
chain = eina_future_then(chain, _commit_change, obj);
|
||||
|
||||
return efl_future_Eina_FutureXXX_then(obj, chain);
|
||||
}
|
||||
|
||||
static Eo* _construct_children(void* pdata, Eo* child)
|
||||
typedef struct _Selection_Children_Request Selection_Children_Request;
|
||||
struct _Selection_Children_Request
|
||||
{
|
||||
Efl_Model_Composite_Selection_Data* pd = pdata;
|
||||
Eo* new_child = efl_add_ref(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;
|
||||
Efl_Model *parent;
|
||||
|
||||
unsigned int start;
|
||||
};
|
||||
|
||||
static Eina_Value
|
||||
_slice_get(void *data,
|
||||
const Eina_Value v,
|
||||
const Eina_Future *dead_future EINA_UNUSED)
|
||||
{
|
||||
Selection_Children_Request *req = data;
|
||||
unsigned int length, it;
|
||||
Eo *composited = NULL;
|
||||
Eina_Value r = EINA_VALUE_EMPTY;
|
||||
|
||||
if (v.type == EINA_VALUE_TYPE_ERROR)
|
||||
goto error;
|
||||
|
||||
eina_value_array_setup(&r, EINA_VALUE_TYPE_OBJECT, 4);
|
||||
|
||||
EINA_VALUE_ARRAY_FOREACH(&v, length, it, composited)
|
||||
{
|
||||
Eo *compositing;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
error:
|
||||
efl_unref(req->parent);
|
||||
free(req);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void _composited_children_slice_get_then(void* data, Efl_Event const* event)
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
Selection_Children_Request *req;
|
||||
Eina_Future *f;
|
||||
|
||||
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);
|
||||
req = calloc(1, sizeof (Selection_Children_Request));
|
||||
if (!req) return eina_future_rejected(efl_loop_future_scheduler_get(obj), ENOMEM);
|
||||
req->parent = efl_ref(obj);
|
||||
req->start = start;
|
||||
|
||||
// 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);
|
||||
f = eina_future_then(f, _slice_get, req);
|
||||
|
||||
return efl_future_Eina_FutureXXX_then(obj, f);
|
||||
}
|
||||
|
||||
#include "efl_model_composite_selection.eo.c"
|
||||
|
|
|
@ -1,23 +1,13 @@
|
|||
class Efl.Model_Composite_Selection (Efl.Model_Composite_Boolean)
|
||||
{
|
||||
[[Efl model composite selection class]]
|
||||
methods {
|
||||
select {
|
||||
[[Select composition]]
|
||||
params {
|
||||
idx: int; [[Index]]
|
||||
}
|
||||
return: future<any_value>; [[Future on the selected composition]]
|
||||
}
|
||||
@property exclusive_selection {
|
||||
[[Exclusive Selection property]]
|
||||
values {
|
||||
exclusive: bool; [[$true is selection is exclusive, $flase otherwise]]
|
||||
}
|
||||
}
|
||||
}
|
||||
implements {
|
||||
Efl.Object.constructor;
|
||||
Efl.Model.children_slice_get;
|
||||
Efl.Model.property { get; set; }
|
||||
}
|
||||
events {
|
||||
selected;
|
||||
unselected;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class Efl.Model_Composite_Selection_Children (Efl.Object, Efl.Model)
|
||||
class Efl.Model_Composite_Selection_Children (Efl.Model_Composite_Boolean_Children)
|
||||
{
|
||||
[[Efl model composite selection children class]]
|
||||
implements {
|
||||
Efl.Model.property_set;
|
||||
Efl.Model.property { set; }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue