From f5a56789e062a47d0cf5141953c5d8a6071eecdf Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Fri, 1 Sep 2017 12:30:49 +0900 Subject: [PATCH] evas: Add internal API to make smart obj (un)clipped Introduction to the problem: - Efl.Canvas.Group has a method member_add() to add sub objects. - Efl.Canvas.Group (simple smart object) does NOT actually delete the objects on deletion. But: - Efl.Canvas.Group.Clipped is a direct subclass and WILL delete the sub objects on deletion. Semantically, all smart objects (at least in EO and Elementary) will own and delete sub objects automatically. Some exceptions are: - Edje object (smart clipped) does not delete swallowed objects. Edje object is a "clipped" smart object but it pops out all swallowed children before getting deleted. - Evas box/table/grid also pop out their children before deletion. Those classes are all legacy & internal only. - Elm.Widget will "manually" delete all its sub objects at deletion, as it inherits from Efl.Canvas.Group but basically takes full ownership of the sub objects. Note that member_add shouldn't be used on a widget, the widgets do it themselves. Also, smart clipped objects are much more convenient to use as they will handle some things for you: color, visibility, moving and ownership. So, the API member_add needs to be marked as own(). But right now Efl.Canvas.Group does not own. Thus, here's the plan: - Mark clipped objects as such with an internal API - Merge clipped smart object features directly inside the standard smart object. - Get rid of Efl.Canvas.Group.Clipped entirely and watch all hell break loose. Ref T5301 --- src/lib/elementary/elm_widget.c | 1 + src/lib/emotion/emotion_smart.c | 1 + src/lib/evas/Evas_Internal.h | 1 + .../evas/canvas/efl_canvas_group_clipped.eo | 3 +++ .../canvas/efl_canvas_object_event_grabber.c | 1 + src/lib/evas/canvas/evas_object_smart.c | 23 +++++++++++++------ .../evas/canvas/evas_object_smart_clipped.c | 9 ++++++++ 7 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/lib/elementary/elm_widget.c b/src/lib/elementary/elm_widget.c index d4983199f7..e2947eb5ee 100644 --- a/src/lib/elementary/elm_widget.c +++ b/src/lib/elementary/elm_widget.c @@ -6183,6 +6183,7 @@ _elm_widget_efl_object_constructor(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSE Eo *parent = NULL; sd->on_create = EINA_TRUE; + efl_canvas_group_unclipped_set(obj, EINA_TRUE); obj = efl_constructor(efl_super(obj, MY_CLASS)); efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY); evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks); diff --git a/src/lib/emotion/emotion_smart.c b/src/lib/emotion/emotion_smart.c index 9850c80090..5b2dbf2139 100644 --- a/src/lib/emotion/emotion_smart.c +++ b/src/lib/emotion/emotion_smart.c @@ -254,6 +254,7 @@ emotion_object_add(Evas *evas) EOLIAN static Eo * _efl_canvas_video_efl_object_constructor(Eo *obj, Efl_Canvas_Video_Data *pd EINA_UNUSED) { + efl_canvas_group_unclipped_set(obj, EINA_TRUE); obj = efl_constructor(efl_super(obj, MY_CLASS)); efl_canvas_object_type_set(obj, E_OBJ_NAME); diff --git a/src/lib/evas/Evas_Internal.h b/src/lib/evas/Evas_Internal.h index 28702ef65c..b4eb056e23 100644 --- a/src/lib/evas/Evas_Internal.h +++ b/src/lib/evas/Evas_Internal.h @@ -53,6 +53,7 @@ EOAPI void efl_canvas_object_legacy_ctor(Eo *obj); EOAPI void efl_canvas_object_type_set(Eo *obj, const char *type); EOAPI void efl_canvas_group_add(Eo *obj); EOAPI void efl_canvas_group_del(Eo *obj); +EOAPI void efl_canvas_group_unclipped_set(Eo *obj, Eina_Bool unclipped); EOAPI void *efl_input_legacy_info_get(const Eo *obj); EOAPI Eo *efl_input_instance_get(const Eo *obj, Efl_Object *owner, void **priv); diff --git a/src/lib/evas/canvas/efl_canvas_group_clipped.eo b/src/lib/evas/canvas/efl_canvas_group_clipped.eo index 39f669ca04..f121dce562 100644 --- a/src/lib/evas/canvas/efl_canvas_group_clipped.eo +++ b/src/lib/evas/canvas/efl_canvas_group_clipped.eo @@ -1,8 +1,11 @@ +/* FIXME: This class needs to disappear and its functionality merged into + * standard smart objects (Efl.Canvas.Group). */ abstract Efl.Canvas.Group.Clipped (Efl.Canvas.Group) { [[Internal class representing a canvas object group with a clipper.]] data: Evas_Object_Smart_Clipped_Data; implements { + Efl.Object.constructor; Efl.Gfx.color { set; } Efl.Gfx.visible { set; } Efl.Gfx.position { set; } diff --git a/src/lib/evas/canvas/efl_canvas_object_event_grabber.c b/src/lib/evas/canvas/efl_canvas_object_event_grabber.c index 3ea7a056ec..18dc8c3e6d 100644 --- a/src/lib/evas/canvas/efl_canvas_object_event_grabber.c +++ b/src/lib/evas/canvas/efl_canvas_object_event_grabber.c @@ -320,6 +320,7 @@ _efl_canvas_object_event_grabber_efl_object_constructor(Eo *eo_obj, Efl_Object_E { Evas_Object_Protected_Data *obj; + efl_canvas_group_unclipped_set(eo_obj, EINA_TRUE); eo_obj = efl_constructor(efl_super(eo_obj, MY_CLASS)); efl_canvas_object_type_set(eo_obj, MY_CLASS_NAME_LEGACY); obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); diff --git a/src/lib/evas/canvas/evas_object_smart.c b/src/lib/evas/canvas/evas_object_smart.c index 760298e5be..4b3623ef9e 100644 --- a/src/lib/evas/canvas/evas_object_smart.c +++ b/src/lib/evas/canvas/evas_object_smart.c @@ -50,6 +50,7 @@ struct _Evas_Smart_Data Eina_Bool need_recalculate : 1; Eina_Bool update_boundingbox_needed : 1; Eina_Bool group_del_called : 1; + Eina_Bool unclipped : 1; /* If true, NOT a smart_clipped object */ }; typedef struct @@ -613,13 +614,10 @@ evas_object_smart_add(Evas *eo_e, Evas_Smart *s) } EOLIAN static Eo * -_efl_canvas_group_efl_object_constructor(Eo *eo_obj, Evas_Smart_Data *class_data EINA_UNUSED) +_efl_canvas_group_efl_object_constructor(Eo *eo_obj, Evas_Smart_Data *sd) { - Evas_Smart_Data *smart; - - smart = class_data; - smart->object = eo_obj; - smart->inherit_paragraph_direction = EINA_TRUE; + sd->object = eo_obj; + sd->inherit_paragraph_direction = EINA_TRUE; eo_obj = efl_constructor(efl_super(eo_obj, MY_CLASS)); evas_object_smart_init(eo_obj); @@ -1666,14 +1664,25 @@ _efl_canvas_group_efl_canvas_object_paragraph_direction_get(Eo *eo_obj EINA_UNUS return o->paragraph_direction; } +/* Internal EO */ +static void +_efl_canvas_group_group_unclipped_set(Eo *eo_obj EINA_UNUSED, Evas_Smart_Data *sd, Eina_Bool unclipped) +{ + // We must call this function BEFORE the constructor (yes, it's hacky) + EINA_SAFETY_ON_FALSE_RETURN(!sd->object); + sd->unclipped = !!unclipped; +} + /* Internal EO APIs */ EOAPI EFL_VOID_FUNC_BODY(efl_canvas_group_add) EOAPI EFL_VOID_FUNC_BODY(efl_canvas_group_del) +EOAPI EFL_VOID_FUNC_BODYV(efl_canvas_group_unclipped_set, EFL_FUNC_CALL(enable), Eina_Bool enable) #define EFL_CANVAS_GROUP_EXTRA_OPS \ EFL_OBJECT_OP_FUNC(efl_canvas_group_add, _efl_canvas_group_group_add), \ - EFL_OBJECT_OP_FUNC(efl_canvas_group_del, _efl_canvas_group_group_del) + EFL_OBJECT_OP_FUNC(efl_canvas_group_del, _efl_canvas_group_group_del), \ + EFL_OBJECT_OP_FUNC(efl_canvas_group_unclipped_set, _efl_canvas_group_group_unclipped_set) #include "canvas/efl_canvas_group.eo.c" diff --git a/src/lib/evas/canvas/evas_object_smart_clipped.c b/src/lib/evas/canvas/evas_object_smart_clipped.c index 23345df434..2ad359716b 100644 --- a/src/lib/evas/canvas/evas_object_smart_clipped.c +++ b/src/lib/evas/canvas/evas_object_smart_clipped.c @@ -209,6 +209,15 @@ _efl_canvas_group_clipped_efl_canvas_group_group_member_del(Eo *eo_obj, Evas_Obj efl_canvas_group_member_del(efl_super(eo_obj, MY_CLASS), member); } +EOLIAN static Eo * +_efl_canvas_group_clipped_efl_object_constructor(Eo *eo_obj, Evas_Object_Smart_Clipped_Data *obj EINA_UNUSED) +{ + // Setting this flag before the parent constructor on purpose. + efl_canvas_group_unclipped_set(eo_obj, EINA_FALSE); + return efl_constructor(efl_super(eo_obj, MY_CLASS)); +} + +/* Legacy only */ EAPI void evas_object_smart_clipped_smart_set(Evas_Smart_Class *sc) { -- 2.34.1