From d595324a8dbccabf80d13d8f22e59c6166b4c2b6 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Fri, 5 Jun 2015 10:54:13 +0200 Subject: [PATCH] evas: add an unique name for each Efl.VG.Base object and make it possible to find it from parent. --- src/lib/evas/canvas/efl_vg_base.eo | 45 ++++++++++++++------ src/lib/evas/canvas/efl_vg_container.eo | 11 +++++ src/lib/evas/canvas/evas_vg_container.c | 23 +++++++++++ src/lib/evas/canvas/evas_vg_node.c | 55 ++++++++++++++++++++++++- src/lib/evas/canvas/evas_vg_private.h | 4 ++ src/lib/evas/canvas/evas_vg_root_node.c | 13 ++++-- 6 files changed, 133 insertions(+), 18 deletions(-) diff --git a/src/lib/evas/canvas/efl_vg_base.eo b/src/lib/evas/canvas/efl_vg_base.eo index 19464646d6..1567f5adcb 100644 --- a/src/lib/evas/canvas/efl_vg_base.eo +++ b/src/lib/evas/canvas/efl_vg_base.eo @@ -3,6 +3,27 @@ abstract Efl.VG.Base (Eo.Base, Efl.Gfx.Base, Efl.Gfx.Stack) eo_prefix: efl_vg; legacy_prefix: evas_vg_node; methods { + @property name { + set { + /*@ + Set an unique name from the parent point of view. @c NULL means + no name. + @since 1.15 + */ + } + get { + /*@ + Get an unique name from the parent point of view . @c NULL means + no name. When set a parent after the name what defined, it might + be forced back to NULL if the parent already has a node of that + name. + @since 1.15 + */ + } + values { + name: const(char) *; + } + } @property transformation { set { [[Sets the transformation matrix to be used for this node object. @@ -40,21 +61,21 @@ abstract Efl.VG.Base (Eo.Base, Efl.Gfx.Base, Efl.Gfx.Stack) } @property mask { set { - } - get { - } - values { - m: Efl_VG *; - } + } + get { + } + values { + m: Efl_VG *; + } } /* quality { set { - } - get { - } - values { - Evas_VG_Quality q; - } + } + get { + } + values { + Evas_VG_Quality q; + } } */ bounds_get { [[Give the bounding box in screen coordinate as being drawn. diff --git a/src/lib/evas/canvas/efl_vg_container.eo b/src/lib/evas/canvas/efl_vg_container.eo index 0c954e2696..19a7b30cca 100644 --- a/src/lib/evas/canvas/efl_vg_container.eo +++ b/src/lib/evas/canvas/efl_vg_container.eo @@ -1,6 +1,17 @@ class Efl.VG.Container (Efl.VG.Base) { legacy_prefix: evas_vg_container; + methods { + child_get { + params { + @in name: const(char)*; + } + return: Efl.VG.Base *; + } + children_get { + return: free(own(iterator*), eina_iterator_free) @warn_unused; + } + } implements { Eo.Base.constructor; Eo.Base.destructor; diff --git a/src/lib/evas/canvas/evas_vg_container.c b/src/lib/evas/canvas/evas_vg_container.c index f3ee7c9962..e31126015b 100644 --- a/src/lib/evas/canvas/evas_vg_container.c +++ b/src/lib/evas/canvas/evas_vg_container.c @@ -31,6 +31,8 @@ _efl_vg_container_eo_base_constructor(Eo *obj, { Efl_VG_Base_Data *nd; + pd->names = eina_hash_stringshared_new(NULL); + obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor()); nd = eo_data_scope_get(obj, EFL_VG_BASE_CLASS); @@ -45,6 +47,9 @@ _efl_vg_container_eo_base_destructor(Eo *obj, Efl_VG_Container_Data *pd EINA_UNUSED) { eo_do_super(obj, MY_CLASS, eo_destructor()); + + eina_hash_free(pd->names); + pd->names = NULL; } static void @@ -74,6 +79,24 @@ _efl_vg_container_efl_vg_base_bounds_get(Eo *obj EINA_UNUSED, } } +static Efl_VG_Base * +_efl_vg_container_child_get(Eo *obj EINA_UNUSED, Efl_VG_Container_Data *pd, const char *name) +{ + const char *tmp = eina_stringshare_add(name); + Efl_VG_Base *r; + + r = eina_hash_find(pd->names, tmp); + eina_stringshare_del(tmp); + + return r; +} + +static Eina_Iterator * +_efl_vg_container_children_get(Eo *obj EINA_UNUSED, Efl_VG_Container_Data *pd) +{ + return eina_list_iterator_new(pd->children); +} + EAPI Efl_VG* evas_vg_container_add(Efl_VG *parent) { diff --git a/src/lib/evas/canvas/evas_vg_node.c b/src/lib/evas/canvas/evas_vg_node.c index b1c8cbb5f7..b54b7ba771 100644 --- a/src/lib/evas/canvas/evas_vg_node.c +++ b/src/lib/evas/canvas/evas_vg_node.c @@ -276,6 +276,49 @@ _efl_vg_base_eo_base_destructor(Eo *obj, Efl_VG_Base_Data *pd) eo_do_super(obj, MY_CLASS, eo_destructor()); } +static void +_efl_vg_base_name_insert(Eo *obj, Efl_VG_Base_Data *pd, Efl_VG_Container_Data *cd) +{ + Eo *set; + + if (!pd->name) return ; + + set = eina_hash_find(cd->names, pd->name); + if (set == obj) return ; + + if (set) + { + eina_stringshare_del(pd->name); + pd->name = NULL; + } + else + { + eina_hash_direct_add(cd->names, pd->name, obj); + } +} + +static void +_efl_vg_base_name_set(Eo *obj, Efl_VG_Base_Data *pd, const char *name) +{ + Efl_VG_Container_Data *cd = NULL; + Eo *parent = NULL; + + if (_efl_vg_base_parent_checked_get(obj, &parent, &cd)) + { + if (pd->name) eina_hash_del(cd->names, pd->name, obj); + } + + eina_stringshare_replace(&pd->name, name); + + if (cd) _efl_vg_base_name_insert(obj, pd, cd); +} + +static const char * +_efl_vg_base_name_get(Eo *obj EINA_UNUSED, Efl_VG_Base_Data *pd) +{ + return pd->name; +} + static void _efl_vg_base_eo_base_parent_set(Eo *obj, Efl_VG_Base_Data *pd EINA_UNUSED, @@ -308,11 +351,19 @@ _efl_vg_base_eo_base_parent_set(Eo *obj, // FIXME: this may become slow with to much object if (old_cd) - old_cd->children = eina_list_remove(old_cd->children, obj); + { + old_cd->children = eina_list_remove(old_cd->children, obj); + + if (pd->name) eina_hash_del(old_cd->names, pd->name, obj); + } eo_do_super(obj, MY_CLASS, eo_parent_set(parent)); if (cd) - cd->children = eina_list_append(cd->children, obj); + { + cd->children = eina_list_append(cd->children, obj); + + _efl_vg_base_name_insert(obj, pd, cd); + } _efl_vg_base_changed(old_parent); _efl_vg_base_changed(obj); diff --git a/src/lib/evas/canvas/evas_vg_private.h b/src/lib/evas/canvas/evas_vg_private.h index af4912ae72..cc5222f8f3 100644 --- a/src/lib/evas/canvas/evas_vg_private.h +++ b/src/lib/evas/canvas/evas_vg_private.h @@ -9,6 +9,8 @@ typedef struct _Efl_VG_Gradient_Data Efl_VG_Gradient_Data; struct _Efl_VG_Base_Data { + const char *name; + Eina_Matrix3 *m; Efl_VG *mask; Ector_Renderer *renderer; @@ -26,6 +28,8 @@ struct _Efl_VG_Base_Data struct _Efl_VG_Container_Data { Eina_List *children; + + Eina_Hash *names; }; struct _Efl_VG_Gradient_Data diff --git a/src/lib/evas/canvas/evas_vg_root_node.c b/src/lib/evas/canvas/evas_vg_root_node.c index 0f06d46fe7..6e50cdb430 100644 --- a/src/lib/evas/canvas/evas_vg_root_node.c +++ b/src/lib/evas/canvas/evas_vg_root_node.c @@ -73,17 +73,22 @@ _efl_vg_root_node_eo_base_constructor(Eo *obj, Efl_VG_Base_Data *nd; Eo *parent; + // We are copying here the code of the vg container to make it possible to + // enforce that the root node is the only one to attach to an Evas_Object_VG + cd = eo_data_scope_get(obj, EFL_VG_CONTAINER_CLASS); + cd->children = NULL; + cd->names = eina_hash_stringshared_new(NULL); + // Nice little hack, jump over parent constructor in Efl_VG_Root obj = eo_do_super_ret(obj, EFL_VG_BASE_CLASS, obj, eo_constructor()); - eo_do(obj, parent = eo_parent_get()); + eo_do(obj, + parent = eo_parent_get(), + efl_vg_name_set("root")); if (!eo_isa(parent, EVAS_VG_CLASS)) { ERR("Parent of VG_ROOT_NODE must be a VG_CLASS"); return NULL; } - cd = eo_data_scope_get(obj, EFL_VG_CONTAINER_CLASS); - cd->children = NULL; - nd = eo_data_scope_get(obj, EFL_VG_BASE_CLASS); nd->render_pre = _evas_vg_root_node_render_pre; nd->data = cd;