evas: Add internal API to make smart obj (un)clipped
authorJean-Philippe Andre <jp.andre@samsung.com>
Fri, 1 Sep 2017 03:30:49 +0000 (12:30 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Wed, 13 Sep 2017 00:57:05 +0000 (09:57 +0900)
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
src/lib/emotion/emotion_smart.c
src/lib/evas/Evas_Internal.h
src/lib/evas/canvas/efl_canvas_group_clipped.eo
src/lib/evas/canvas/efl_canvas_object_event_grabber.c
src/lib/evas/canvas/evas_object_smart.c
src/lib/evas/canvas/evas_object_smart_clipped.c

index d4983199f70f0505f01c5a02bb3f25bb871485a3..e2947eb5eee93fb942d9c44892f6093161409bcc 100644 (file)
@@ -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);
index 9850c80090ddc9b2649f1ce8516773c5149c6727..5b2dbf21394091dec8de6e31a3c3383134cedd3e 100644 (file)
@@ -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);
 
index 28702ef65cdf5816d4e7c6ea915a9401f9e37b0f..b4eb056e2302273518565cc52cfb3dadd01643d4 100644 (file)
@@ -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);
index 39f669ca0458e7007ae424d2defcb87c7699b8a0..f121dce562e6679967524883f78376f44b2426cb 100644 (file)
@@ -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; }
index 3ea7a056ec8054c3b5ab24587875e1fe4055ef0c..18dc8c3e6d4902e0dcc3dd53eaa4a147e2cecc6c 100644 (file)
@@ -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);
index 760298e5be4fb13eda70e14612c9a143fb540f32..4b3623ef9e561754ad055895c1717d762f4ba10b 100644 (file)
@@ -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"
index 23345df4344b59c3567191d8d530a4c311144300..2ad359716b5e0f37f52cb70ce5f1777df5e4c907 100644 (file)
@@ -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)
 {