efl_ui/layout: add mechanism for deferring versioned theme signals

Summary:
the theme version isn't available until the theme has been applied, so
we can create an array of all the pending signals and defer them until
such time as we get a theme or destroy the object

this is internal and can be reworked at a later time as needed

ref T8231

Depends on D10157

Reviewers: cedric

Reviewed By: cedric

Subscribers: cedric, #reviewers, #committers

Tags: #efl

Maniphest Tasks: T8231

Differential Revision: https://phab.enlightenment.org/D10164
This commit is contained in:
Mike Blumenkrantz 2019-09-25 17:55:29 -04:00
parent 75c8fd1cc2
commit f24ce654c0
2 changed files with 47 additions and 0 deletions

View File

@ -70,6 +70,13 @@ static const char *_efl_ui_layout_swallow_parts[] = {
NULL
};
typedef struct _Deferred_Version_Signal
{
Eina_Stringshare *old_sig;
Eina_Stringshare *new_sig;
unsigned int version_threshold;
} Deferred_Version_Signal;
typedef struct _Efl_Ui_Layout_Factory_Tracking Efl_Ui_Layout_Factory_Tracking;
struct _Efl_Ui_Layout_Factory_Tracking
@ -222,6 +229,19 @@ _efl_ui_layout_subobjs_calc_set(Eo *obj, Eina_Bool set)
sd->calc_subobjs = !!set;
}
static void
_defer_version_signal(Efl_Ui_Layout_Data *sd, Eina_Stringshare *old_sig, Eina_Stringshare *new_sig, unsigned int version_threshold)
{
Deferred_Version_Signal dvs;
if (!sd->deferred_signals)
sd->deferred_signals = eina_inarray_new(sizeof(Deferred_Version_Signal), 5);
EINA_SAFETY_ON_NULL_RETURN(sd->deferred_signals);
dvs.old_sig = old_sig;
dvs.new_sig = new_sig;
dvs.version_threshold = version_threshold;
eina_inarray_push(sd->deferred_signals, &dvs);
}
/* common content cases for layout objects: icon and text */
static inline void
_signals_emit(Eo *obj,
@ -563,6 +583,21 @@ _efl_ui_layout_base_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Layout_Data *sd)
}
}
}
if (sd->deferred_signals)
{
do
{
Deferred_Version_Signal *dvs = eina_inarray_pop(sd->deferred_signals);
if (sd->version < dvs->version_threshold)
efl_layout_signal_emit(sd->obj, dvs->old_sig, "efl");
else
efl_layout_signal_emit(sd->obj, dvs->new_sig, "efl");
eina_stringshare_del(dvs->old_sig);
eina_stringshare_del(dvs->new_sig);
} while (eina_inarray_count(sd->deferred_signals));
ELM_SAFE_FREE(sd->deferred_signals, eina_inarray_free);
}
if (!version)
{
snprintf(buf, sizeof(buf), "%d%d", EFL_VERSION_MAJOR, EFL_VERSION_MINOR);
@ -903,6 +938,17 @@ _efl_ui_layout_base_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Layout_Data *sd)
sd->connect.signals = NULL;
eina_hash_free(sd->connect.factories);
sd->connect.factories = NULL;
if (sd->deferred_signals)
{
do
{
Deferred_Version_Signal *dvs = eina_inarray_pop(sd->deferred_signals);
eina_stringshare_del(dvs->old_sig);
eina_stringshare_del(dvs->new_sig);
} while (eina_inarray_count(sd->deferred_signals));
ELM_SAFE_FREE(sd->deferred_signals, eina_inarray_free);
}
/* let's make our Edje object the *last* to be processed, since it
* may (smart) parent other sub objects here */

View File

@ -53,6 +53,7 @@ typedef struct _Efl_Ui_Layout_Data
Eina_List *subs; /**< List of Elm_Layout_Sub_Object_Data structs, to hold the actual sub objects such as text, content and the children of box and table. */
Eina_List *edje_signals; /**< The list of edje signal callbacks. */
Eina_List *parts_cursors; /**< The list of cursor names of layout parts. This is a list of Elm_Layout_Sub_Object_Cursor struct. */
Eina_Inarray *deferred_signals; /**< signals which were generated during construction */
struct {
Eina_Hash *properties; /**< The list of properties connected to layout parts. */