evas: add an unique name for each Efl.VG.Base object and make it possible to find...
authorCedric BAIL <cedric@osg.samsung.com>
Fri, 5 Jun 2015 08:54:13 +0000 (10:54 +0200)
committerCedric BAIL <cedric@osg.samsung.com>
Fri, 21 Aug 2015 14:40:31 +0000 (16:40 +0200)
src/lib/evas/canvas/efl_vg_base.eo
src/lib/evas/canvas/efl_vg_container.eo
src/lib/evas/canvas/evas_vg_container.c
src/lib/evas/canvas/evas_vg_node.c
src/lib/evas/canvas/evas_vg_private.h
src/lib/evas/canvas/evas_vg_root_node.c

index 1946464..1567f5a 100644 (file)
@@ -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.
index 0c954e2..19a7b30 100644 (file)
@@ -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<Efl.VG.Base *>*), eina_iterator_free) @warn_unused;
+      }
+   }
    implements {
       Eo.Base.constructor;
       Eo.Base.destructor;
index f3ee7c9..e311260 100644 (file)
@@ -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)
 {
index b1c8cbb..b54b7ba 100644 (file)
@@ -277,6 +277,49 @@ _efl_vg_base_eo_base_destructor(Eo *obj, Efl_VG_Base_Data *pd)
 }
 
 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,
                                 Eo *parent)
@@ -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);
index af4912a..cc5222f 100644 (file)
@@ -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
index 0f06d46..6e50cdb 100644 (file)
@@ -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;