elementary: rework Efl.Ui.Factory to have another additional stage during releasing of items.

Reviewed-by: Marcel Hollerbach <mail@marcel-hollerbach.de>
Differential Revision: https://phab.enlightenment.org/D9954
This commit is contained in:
Cedric Bail 2019-09-15 20:52:50 -07:00 committed by Marcel Hollerbach
parent 892c26f906
commit 0a99fb87bb
3 changed files with 61 additions and 5 deletions

View File

@ -39,5 +39,6 @@ interface @beta Efl.Ui.Factory extends Efl.Ui.Property_Bind, Efl.Ui.Factory_Bind
item,building: Efl.Gfx.Entity; [[Event triggered when an item has processed @Efl.Object.finalize, but before all the factory are done building it.
Note: if the @Efl.Ui.Factory does keep a cache of object, this will be called when object are pulled out of the cache.]]
item,created: Efl.Gfx.Entity; [[Event triggered when an item has been successfully created by the factory and is about to be used by an @Efl.Ui.View.]]
item,releasing: Efl.Gfx.Entity; [[Event triggered when an item is being released by the @Efl.Ui.Factory. It must be assumed that after this call, the object can be recycle to another @Efl.Ui.View and there can be more than one call for the same item.]]
}
}

View File

@ -136,6 +136,7 @@ _efl_ui_caching_factory_create_then(Eo *model, void *data, const Eina_Value v)
_efl_ui_caching_factory_remove(r->pd, eina_list_data_find(r->pd->cache, w), w);
efl_ui_view_model_set(w, model);
efl_event_callback_call(r->factory, EFL_UI_FACTORY_EVENT_ITEM_BUILDING, w);
return eina_value_object_init(w);
}
@ -356,7 +357,7 @@ _efl_ui_caching_factory_efl_ui_factory_release(Eo *obj,
// Change parent, disconnect the object and make it invisible
efl_gfx_entity_visible_set(ui_view, EINA_FALSE);
efl_ui_view_model_set(ui_view, NULL);
efl_event_callback_call(obj, EFL_UI_FACTORY_EVENT_ITEM_RELEASING, ui_view);
// Add to the cache
pd->cache = eina_list_prepend(pd->cache, ui_view);

View File

@ -90,9 +90,28 @@ static void
_efl_ui_widget_factory_constructing(void *data EINA_UNUSED, const Efl_Event *ev)
{
Efl_Gfx_Entity *ui_view = ev->info;
const Efl_Model *model;
Eina_Value *width, *height;
/* NOP */
(void)(ui_view);
model = efl_ui_view_model_get(ui_view);
// Fetch min size from model if available to avoid recalculcating it
width = efl_model_property_get(model, "self.width");
height = efl_model_property_get(model, "self.height");
if (eina_value_type_get(width) != EINA_VALUE_TYPE_ERROR &&
eina_value_type_get(height) != EINA_VALUE_TYPE_ERROR)
{
Eina_Size2D s;
if (!eina_value_int_convert(width, &s.w)) s.w = 0;
if (!eina_value_int_convert(height, &s.h)) s.h = 0;
/* efl_event_freeze(ui_view); */
efl_key_data_set(ui_view, "efl.ui.widget.factory.size_set", (void*)EINA_TRUE);
efl_gfx_hint_size_min_set(ui_view, s);
}
eina_value_free(width);
eina_value_free(height);
}
@ -109,6 +128,10 @@ _efl_ui_widget_factory_building(void *data, const Efl_Event *ev)
model = efl_ui_view_model_get(ui_view);
// Check property size only if not checked yet
if (!efl_key_data_get(ui_view, "efl.ui.widget.factory.size_check"))
_efl_ui_widget_factory_constructing(data, ev);
// Bind all property before the object is finalize
it = eina_hash_iterator_data_new(pd->parts);
EINA_ITERATOR_FOREACH(it, bpd)
@ -152,9 +175,37 @@ _efl_ui_widget_factory_building(void *data, const Efl_Event *ev)
eina_value_free(property);
}
static void
_efl_ui_widget_factory_releasing(void *data, const Efl_Event *ev)
{
Efl_Ui_Widget_Factory_Data *pd = data;
Efl_Gfx_Entity *ui_view = ev->info;
Efl_Ui_Bind_Part_Data *bpd;
Eina_Iterator *it;
efl_key_data_set(ui_view, "efl.ui.widget.factory.size_set", NULL);
efl_key_data_set(ui_view, "efl.ui.widget.factory.size_check", NULL);
// Bind all property before the object is finalize
it = eina_hash_iterator_data_new(pd->parts);
EINA_ITERATOR_FOREACH(it, bpd)
{
Efl_Ui_Property_Bind_Data *bppd;
Eina_List *l;
EINA_LIST_FOREACH(bpd->properties, l, bppd)
efl_ui_property_bind(efl_part(ui_view, bpd->part),
bppd->part_property, NULL);
}
eina_iterator_free(it);
efl_ui_view_model_set(ui_view, NULL);
}
EFL_CALLBACKS_ARRAY_DEFINE(item_callbacks,
{ EFL_UI_FACTORY_EVENT_ITEM_CONSTRUCTING, _efl_ui_widget_factory_constructing },
{ EFL_UI_FACTORY_EVENT_ITEM_BUILDING, _efl_ui_widget_factory_building })
{ EFL_UI_FACTORY_EVENT_ITEM_BUILDING, _efl_ui_widget_factory_building },
{ EFL_UI_FACTORY_EVENT_ITEM_RELEASING, _efl_ui_widget_factory_releasing })
static Eo *
_efl_ui_widget_factory_efl_object_constructor(Efl_Ui_Widget_Factory *obj,
@ -273,10 +324,13 @@ alloc_array_error:
}
static void
_efl_ui_widget_factory_efl_ui_factory_release(Eo *obj EINA_UNUSED,
_efl_ui_widget_factory_efl_ui_factory_release(Eo *obj,
Efl_Ui_Widget_Factory_Data *pd EINA_UNUSED,
Efl_Gfx_Entity *ui_view)
{
// There might be multiple call to releasing on the same object as every factory in the
// inheritance chain can decide to keep it for a time
efl_event_callback_call(obj, EFL_UI_FACTORY_EVENT_ITEM_RELEASING, ui_view);
// We do not cache or track this item, just get rid of them asap
efl_del(ui_view);
}