evas: add set function for root_node property.

Summary:
Currently user ask for the root_node from the evas_vg object and then attach its tree by setting the root node as parent.
With this change this process will be explicit. user has to set the root node to the evas_vg object and the object will take the ownership
of the tree. User can query the current vg_tree by root_node_get api.

Test Plan:
        Fixed the test app to reflects this change.

Reviewers: jpeg, cedric

Reviewed By: jpeg, cedric

Subscribers: cedric

Differential Revision: https://phab.enlightenment.org/D5347

Signed-off-by: Cedric Bail <cedric@osg.samsung.com>
This commit is contained in:
subhransu mohanty 2017-10-23 11:05:34 -07:00 committed by Cedric Bail
parent 74155b6e34
commit d267595557
10 changed files with 76 additions and 149 deletions

View File

@ -23,7 +23,6 @@ evas_canvas_eolian_pub_files = \
lib/evas/canvas/efl_vg.eo \
lib/evas/canvas/efl_vg_container.eo \
lib/evas/canvas/efl_vg_shape.eo \
lib/evas/canvas/efl_vg_root_node.eo \
lib/evas/canvas/efl_vg_gradient.eo \
lib/evas/canvas/efl_vg_gradient_radial.eo \
lib/evas/canvas/efl_vg_gradient_linear.eo \
@ -394,7 +393,6 @@ lib_evas_libevas_la_SOURCES += \
lib/evas/canvas/evas_object_vg.c \
lib/evas/canvas/evas_vg_node.c \
lib/evas/canvas/evas_vg_container.c \
lib/evas/canvas/evas_vg_root_node.c \
lib/evas/canvas/evas_vg_gradient.c \
lib/evas/canvas/evas_vg_gradient_linear.c \
lib/evas/canvas/evas_vg_gradient_radial.c \

View File

@ -57,6 +57,7 @@ static const char *batmans_path[] = {
static void
_on_delete(Ecore_Evas *ee EINA_UNUSED)
{
ecore_animator_del(animation);
ecore_main_loop_quit();
}
@ -141,7 +142,9 @@ main(void)
animation = ecore_animator_timeline_add(1, _animator, NULL);
root = evas_object_vg_root_node_get(vg);
root = evas_vg_container_add(NULL);
evas_object_vg_root_node_set(vg, root);
Eina_Matrix3 matrix;
eina_matrix3_identity(&matrix);

View File

@ -309,7 +309,7 @@ _1_basic_shape_test()
evas_object_event_callback_add(d.vg, EVAS_CALLBACK_KEY_DOWN, _basic_shape_key_handle, NULL);
puts(basic_shape_menu);
container = evas_vg_container_add(evas_object_vg_root_node_get(d.vg));
container = evas_vg_container_add(NULL);
// Line
shape = evas_vg_shape_add(container);
@ -406,6 +406,8 @@ _1_basic_shape_test()
evas_vg_node_color_set(new_shape, 0, 0, 200, 200);
evas_vg_node_origin_set(new_shape, 350, 450);
d.shape_list = eina_list_append(d.shape_list, new_shape);
evas_object_vg_root_node_set(d.vg, container);
}
// 2. Basic shape Test Case END
@ -487,9 +489,11 @@ _2_interpolation_test()
evas_vg_node_origin_set(shape, 150, 150);
d.shape_list = eina_list_append(d.shape_list, shape);
shape = evas_vg_shape_add(evas_object_vg_root_node_get(d.vg));
shape = evas_vg_shape_add(NULL);
evas_vg_node_origin_set(shape, 150, 150);
d.shape_list = eina_list_append(d.shape_list, shape);
evas_object_vg_root_node_set(d.vg, shape);
}
// 2. Interpolation Test Case END
@ -513,11 +517,13 @@ _main_menu()
// create the initial screen
d.vg = evas_object_vg_add(d.evas);
evas_object_show(d.vg);
shape = evas_vg_shape_add(evas_object_vg_root_node_get(d.vg));
shape = evas_vg_shape_add(NULL);
evas_vg_shape_append_svg_path(shape, batman);
evas_vg_node_color_set(shape, 10, 0, 0, 10);
evas_vg_node_origin_set(shape, 0, 100);
evas_object_vg_root_node_set(d.vg, shape);
_canvas_resize_cb(d.ee);
puts(main_menu);
}

View File

@ -3695,7 +3695,6 @@ _edje_svg_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *p3 EINA_U
{
int w, h;
int new_svg = -1;
Efl_VG *root_vg;
Eina_Matrix3 matrix;
Edje_Vector_Data *start, *end;
@ -3703,8 +3702,6 @@ _edje_svg_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *p3 EINA_U
if( (w == 0) || (h == 0)) return;
root_vg = evas_object_vg_root_node_get(ep->object);
if (ep->param2)
{
Edje_Part_Description_Vector *next_state = (Edje_Part_Description_Vector *)ep->param2->description;
@ -3751,7 +3748,7 @@ _edje_svg_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *p3 EINA_U
_edje_dupe_vector_data(ed, chosen_desc->vg.id, w, h, &ep->typedata.vector->cur);
efl_parent_set(ep->typedata.vector->cur.vg, root_vg);
evas_object_vg_root_node_set(ep->object, ep->typedata.vector->cur.vg);
}
}
}

View File

@ -1,9 +0,0 @@
class Efl.VG.Root_Node (Efl.VG.Container)
{
[[Efl vector graphics root node class]]
legacy_prefix: evas_vg_root_node;
implements {
Efl.Object.parent { set; }
Efl.Object.constructor;
}
}

View File

@ -2,7 +2,6 @@
#include "evas_private.h"
#include "evas_vg_private.h"
#include "efl_vg_root_node.eo.h"
#define MY_CLASS EVAS_VG_CLASS
@ -61,6 +60,19 @@ static const Evas_Object_Func object_func =
NULL
};
static void
_evas_vg_tree_changed(void *data, const Efl_Event *event EINA_UNUSED)
{
Evas_Object_Protected_Data *obj = data;
Evas_VG_Data *pd = efl_data_scope_get(obj->object, MY_CLASS);
if (pd->changed) return;
pd->changed = EINA_TRUE;
evas_object_change(obj->object, obj);
}
/* the actual api call to add a vector graphic object */
EAPI Evas_Object *
evas_object_vg_add(Evas *e)
@ -75,7 +87,32 @@ evas_object_vg_add(Evas *e)
Efl_VG *
_evas_vg_root_node_get(Eo *obj EINA_UNUSED, Evas_VG_Data *pd)
{
return pd->root;
return pd->vg_tree;
}
void
_evas_vg_root_node_set(Eo *obj EINA_UNUSED, Evas_VG_Data *pd, Efl_VG *root_node)
{
// if the same root is already set
if (pd->vg_tree == root_node)
return;
// detach/free the old root_node
if (pd->vg_tree)
efl_parent_set(pd->vg_tree, NULL);
pd->vg_tree = root_node;
if (pd->vg_tree)
{
// set the parent so that vg canvas can render it.
efl_parent_set(pd->vg_tree, pd->root);
}
// force a redraw
pd->changed = EINA_TRUE;
evas_object_change(obj, efl_data_scope_get(obj, EFL_CANVAS_OBJECT_CLASS));
}
static void
@ -101,7 +138,7 @@ _evas_vg_efl_object_destructor(Eo *eo_obj, Evas_VG_Data *pd)
efl_event_callback_del(e, EFL_CANVAS_EVENT_RENDER_POST, _cleanup_reference, pd);
efl_unref(pd->root);
efl_del(pd->root);
pd->root = NULL;
efl_destructor(efl_super(eo_obj, MY_CLASS));
}
@ -119,11 +156,12 @@ _evas_vg_efl_object_constructor(Eo *eo_obj, Evas_VG_Data *pd)
obj->type = o_type;
/* root node */
pd->root = efl_add(EFL_VG_ROOT_NODE_CLASS, eo_obj);
efl_ref(pd->root);
pd->root = efl_add(EFL_VG_CONTAINER_CLASS, NULL);
eina_array_step_set(&pd->cleanup, sizeof(pd->cleanup), 8);
efl_event_callback_add(pd->root, EFL_GFX_EVENT_CHANGED, _evas_vg_tree_changed, obj);
return eo_obj;
}
@ -212,6 +250,8 @@ evas_object_vg_render(Evas_Object *eo_obj EINA_UNUSED,
vd->root, NULL,
do_async);
obj->layer->evas->engine.func->ector_end(engine, context, ector, surface, vd->engine_data, do_async);
vd->changed = EINA_FALSE;
}
static void
@ -220,7 +260,6 @@ evas_object_vg_render_pre(Evas_Object *eo_obj,
void *type_private_data)
{
Evas_VG_Data *vd = type_private_data;
Efl_VG_Data *rnd;
int is_v, was_v;
Ector_Surface *s;
@ -254,23 +293,11 @@ evas_object_vg_render_pre(Evas_Object *eo_obj,
was_v = evas_object_was_visible(eo_obj,obj);
if (!(is_v | was_v)) goto done;
// FIXME: for now the walking Evas_VG_Node tree doesn't trigger any damage
// So just forcing it here if necessary
rnd = efl_data_scope_get(vd->root, EFL_VG_CLASS);
// Once the destructor has been called, root node will be zero
// and a full redraw is still necessary.
if (!rnd)
if (vd->changed)
{
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
goto done;
}
else if (rnd->changed)
{
rnd->changed = EINA_FALSE;
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
goto done;
}
if (is_v != was_v)
{

View File

@ -7,15 +7,18 @@ class Evas.VG (Efl.Canvas.Object, Efl.Gfx.Fill, Efl.Gfx.View)
@property root_node {
get {
[[Get the root node of the evas_object_vg.
Note: To manually create the shape object and show in the Vg
object canvas you must create the hierarchy and set the
parent as root node.
@since 1.14]]
}
set {
[[Set the root node of the evas_object_vg.
Note: To manually create the shape object and show in the Vg
object canvas you must create the hierarchy and set as root node.
It takes the ownership of the root node. ]]
}
values {
container: Efl.Object; [[Root node of the VG canvas.]] /* FIXME: Should be Efl.VG */
root: Efl.VG; [[Root node of the VG canvas.]]
}
}
}

View File

@ -2,7 +2,6 @@
#include "evas_private.h"
#include "evas_vg_private.h"
#include "efl_vg_root_node.eo.h"
#include <string.h>
#include <math.h>
@ -503,12 +502,9 @@ _efl_vg_root_parent_get(Eo *obj)
{
Eo *parent;
if (efl_isa(obj, EFL_VG_ROOT_NODE_CLASS))
return obj;
parent = efl_parent_get(obj);
if (!parent) return NULL;
if (!parent) return obj;
return _efl_vg_root_parent_get(parent);
}

View File

@ -12,14 +12,17 @@ typedef struct _Evas_VG_Data Evas_VG_Data;
struct _Evas_VG_Data
{
void *engine_data;
Efl_VG *root;
void *engine_data;
Efl_VG *root;
Efl_VG *vg_tree;
Eina_Rect fill;
unsigned int width, height;
Eina_Array cleanup;
Eina_Bool changed;
};
struct _Efl_VG_Data

View File

@ -1,97 +0,0 @@
#include "evas_common_private.h"
#include "evas_private.h"
#include "evas_vg_private.h"
#include "efl_vg_root_node.eo.h"
#include <string.h>
#define MY_CLASS EFL_VG_ROOT_NODE_CLASS
typedef struct _Efl_VG_Root_Node_Data Efl_VG_Root_Node_Data;
struct _Efl_VG_Root_Node_Data
{
Evas_Object *parent;
Evas_Object_Protected_Data *data;
};
static void
_evas_vg_root_node_render_pre(Eo *obj EINA_UNUSED,
Eina_Matrix3 *parent,
Ector_Surface *s,
void *data,
Efl_VG_Data *nd)
{
Efl_VG_Container_Data *pd = data;
Eina_List *l;
Eo *child;
EFL_VG_COMPUTE_MATRIX(current, parent, nd);
EINA_LIST_FOREACH(pd->children, l, child)
_evas_vg_render_pre(child, s, current);
}
static void
_evas_vg_root_node_changed(void *data, const Efl_Event *event)
{
Efl_VG_Root_Node_Data *pd = data;
Efl_VG_Data *bd = efl_data_scope_get(event->object, EFL_VG_CLASS);
if (bd->changed) return;
bd->changed = EINA_TRUE;
if (pd->parent) evas_object_change(pd->parent, pd->data);
}
static void
_efl_vg_root_node_efl_object_parent_set(Eo *obj,
Efl_VG_Root_Node_Data *pd,
Eo *parent)
{
// Nice little hack, jump over parent parent_set in Efl_VG_Root
efl_parent_set(efl_super(obj, EFL_VG_CLASS), parent);
if (parent && !efl_isa(parent, EVAS_VG_CLASS))
{
ERR("Parent of VG_ROOT_NODE must be a VG_CLASS");
}
else
{
pd->parent = parent;
pd->data = parent ? efl_data_scope_get(parent, EFL_CANVAS_OBJECT_CLASS) : NULL;
}
}
static Eo *
_efl_vg_root_node_efl_object_constructor(Eo *obj,
Efl_VG_Root_Node_Data *pd)
{
Efl_VG_Container_Data *cd;
Efl_VG_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 = efl_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 = efl_constructor(efl_super(obj, EFL_VG_CLASS));
parent = efl_parent_get(obj);
efl_vg_name_set(obj, "root");
if (!efl_isa(parent, EVAS_VG_CLASS)) {
ERR("Parent of VG_ROOT_NODE must be a VG_CLASS");
return NULL;
}
nd = efl_data_scope_get(obj, EFL_VG_CLASS);
nd->render_pre = _evas_vg_root_node_render_pre;
nd->data = cd;
efl_event_callback_add(obj, EFL_GFX_EVENT_CHANGED, _evas_vg_root_node_changed, pd);
return obj;
}
#include "efl_vg_root_node.eo.c"