ecore: properly handle CHILD_ADDED and CHILD_REMOVED from source for Efl.CompositeModel

Before this patch we were directly sending this event on the Efl.CompositeModel, but they
actually might contain an Efl.Model in the event child field. That Efl.Model wouldn't have
been converted before to an Efl.CompositeModel exposing incoherence from the user of
the object point of view. This patch fix that behavior.

Reviewed-by: Marcel Hollerbach <mail@marcel-hollerbach.de>
Differential Revision: https://phab.enlightenment.org/D8661
This commit is contained in:
Cedric BAIL 2019-04-18 13:37:28 -07:00
parent 13b230029d
commit 78563a395e
1 changed files with 64 additions and 28 deletions

View File

@ -45,21 +45,18 @@ _children_indexed_key(const Efl_Composite_Model_Data *node,
return node->index - *key;
}
static void
_efl_composite_model_efl_object_destructor(Eo *obj, Efl_Composite_Model_Data *pd)
static Efl_Model *
_efl_composite_lookup(const Efl_Class *self, Eo *parent, Efl_Model *view, unsigned int index)
{
if (pd->source)
{
efl_event_callback_forwarder_del(pd->source, EFL_MODEL_EVENT_CHILD_ADDED, obj);
efl_event_callback_forwarder_del(pd->source, EFL_MODEL_EVENT_CHILD_REMOVED, obj);
efl_event_callback_forwarder_del(pd->source, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, obj);
efl_event_callback_forwarder_del(pd->source, EFL_MODEL_EVENT_PROPERTIES_CHANGED, obj);
EFL_COMPOSITE_LOOKUP_RETURN(remember, parent, view, "_efl.composite_model");
efl_unref(pd->source);
pd->source = NULL;
}
remember = efl_add_ref(self, parent,
efl_ui_view_model_set(efl_added, view),
efl_composite_model_index_set(efl_added, index),
efl_loop_model_volatile_make(efl_added));
if (!remember) return NULL;
efl_destructor(efl_super(obj, EFL_COMPOSITE_MODEL_CLASS));
EFL_COMPOSITE_REMEMBER_RETURN(remember, view);
}
static void
@ -155,6 +152,44 @@ _efl_composite_model_index_get(const Eo *obj, Efl_Composite_Model_Data *pd)
return r;
}
static void
_efl_composite_model_child_added(void *data, const Efl_Event *event)
{
Efl_Composite_Model_Data *pd = data;
Efl_Model_Children_Event *ev = event->info;
Efl_Model_Children_Event cev = { 0 };
cev.index = ev->index;
if (ev->child)
cev.child = _efl_composite_lookup(efl_class_get(pd->self),
pd->self, ev->child, ev->index);
efl_event_callback_call(pd->self, EFL_MODEL_EVENT_CHILD_ADDED, &cev);
efl_unref(cev.child);
}
static void
_efl_composite_model_child_removed(void *data, const Efl_Event *event)
{
Efl_Composite_Model_Data *pd = data;
Efl_Model_Children_Event *ev = event->info;
Efl_Model_Children_Event cev = { 0 };
cev.index = ev->index;
if (ev->child)
cev.child = _efl_composite_lookup(efl_class_get(pd->self),
pd->self, ev->child, ev->index);
efl_event_callback_call(pd->self, EFL_MODEL_EVENT_CHILD_REMOVED, &cev);
efl_unref(cev.child);
}
EFL_CALLBACKS_ARRAY_DEFINE(composite_callbacks,
{ EFL_MODEL_EVENT_CHILD_ADDED, _efl_composite_model_child_added },
{ EFL_MODEL_EVENT_CHILD_REMOVED, _efl_composite_model_child_removed });
static void
_efl_composite_model_efl_ui_view_model_set(Eo *obj EINA_UNUSED, Efl_Composite_Model_Data *pd, Efl_Model *model)
{
@ -168,8 +203,7 @@ _efl_composite_model_efl_ui_view_model_set(Eo *obj EINA_UNUSED, Efl_Composite_Mo
}
pd->source = efl_ref(model);
efl_event_callback_forwarder_priority_add(model, EFL_MODEL_EVENT_CHILD_ADDED, EFL_CALLBACK_PRIORITY_BEFORE, obj);
efl_event_callback_forwarder_priority_add(model, EFL_MODEL_EVENT_CHILD_REMOVED, EFL_CALLBACK_PRIORITY_BEFORE, obj);
efl_event_callback_array_add(model, composite_callbacks(), pd);
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);
@ -252,20 +286,6 @@ struct _Efl_Composite_Model_Slice_Request
unsigned int dummy_need;
};
static Efl_Model *
_efl_composite_lookup(const Efl_Class *self, Eo *parent, Efl_Model *view, unsigned int index)
{
EFL_COMPOSITE_LOOKUP_RETURN(remember, parent, view, "_efl.composite_model");
remember = efl_add_ref(self, parent,
efl_ui_view_model_set(efl_added, view),
efl_composite_model_index_set(efl_added, index),
efl_loop_model_volatile_make(efl_added));
if (!remember) return NULL;
EFL_COMPOSITE_REMEMBER_RETURN(remember, view);
}
static Eina_Value
_efl_composite_model_then(Eo *o EINA_UNUSED, void *data, const Eina_Value v)
{
@ -401,4 +421,20 @@ _efl_composite_model_efl_model_child_del(Eo *obj EINA_UNUSED,
efl_model_child_del(pd->source, child);
}
static void
_efl_composite_model_efl_object_destructor(Eo *obj, Efl_Composite_Model_Data *pd)
{
if (pd->source)
{
efl_event_callback_array_del(pd->source, composite_callbacks(), pd);
efl_event_callback_forwarder_del(pd->source, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, obj);
efl_event_callback_forwarder_del(pd->source, EFL_MODEL_EVENT_PROPERTIES_CHANGED, obj);
efl_unref(pd->source);
pd->source = NULL;
}
efl_destructor(efl_super(obj, EFL_COMPOSITE_MODEL_CLASS));
}
#include "efl_composite_model.eo.c"