hermet pushed a commit to branch master.

http://git.enlightenment.org/core/elementary.git/commit/?id=e707aa3efb0b4a0b7d6169755075a9943793e4f5

commit e707aa3efb0b4a0b7d6169755075a9943793e4f5
Author: jiin.moon <jiin.m...@samsung.com>
Date:   Fri May 15 23:09:41 2015 +0900

    elementary: Create new widget for image masking
    
    Summary:
    For now, if apply image mask to smart obejct, masking does not work except 
to implement in edc file.
    @feature
    
    Reviewers: Jaehyun_Cho, Jaehyun, jpeg, raster, cedric, Hermet
    
    Subscribers: raster, jpeg, cedric
    
    Projects: #elementary
    
    Differential Revision: https://phab.enlightenment.org/D2055
---
 src/lib/Elementary.h.in      |   1 +
 src/lib/Makefile.am          |   6 ++
 src/lib/elm_clipper.c        | 225 +++++++++++++++++++++++++++++++++++++++++++
 src/lib/elm_clipper.eo       |  78 +++++++++++++++
 src/lib/elm_clipper.h        |  41 ++++++++
 src/lib/elm_clipper_eo.h     |  11 +++
 src/lib/elm_clipper_legacy.h |  12 +++
 src/lib/elm_widget_clipper.h |  66 +++++++++++++
 8 files changed, 440 insertions(+)

diff --git a/src/lib/Elementary.h.in b/src/lib/Elementary.h.in
index cd17bbf..87d9045 100644
--- a/src/lib/Elementary.h.in
+++ b/src/lib/Elementary.h.in
@@ -195,6 +195,7 @@ EAPI extern Elm_Version *elm_version;
 #include <elm_cache.h>
 #include <elm_calendar.h>
 #include <elm_check.h>
+#include <elm_clipper.h>
 #include <elm_clock.h>
 #include <elm_cnp.h>
 #include <elm_colorselector.h>
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 859b0ef..a488e76 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -48,6 +48,7 @@ elm_widget_bubble.h \
 elm_widget_button.h \
 elm_widget_calendar.h \
 elm_widget_check.h \
+elm_widget_clipper.h \
 elm_widget_clock.h \
 elm_widget_colorselector.h \
 elm_widget_conform.h \
@@ -177,6 +178,9 @@ elm_calendar_common.h \
 elm_check.h \
 elm_check_eo.h \
 elm_check_legacy.h \
+elm_clipper.h \
+elm_clipper_eo.h \
+elm_clipper_legacy.h \
 elm_clock.h \
 elm_clock_eo.h \
 elm_clock_legacy.h \
@@ -424,6 +428,7 @@ elm_bubble.c \
 elm_button.c \
 elm_calendar.c \
 elm_check.c \
+elm_clipper.c \
 elm_clock.c \
 elm_cnp.c \
 elm_colorselector.c \
@@ -545,6 +550,7 @@ elm_bubble.eo \
 elm_button.eo \
 elm_calendar.eo \
 elm_check.eo \
+elm_clipper.eo \
 elm_clock.eo \
 elm_colorselector.eo \
 elm_conformant.eo \
diff --git a/src/lib/elm_clipper.c b/src/lib/elm_clipper.c
new file mode 100644
index 0000000..374f9bf
--- /dev/null
+++ b/src/lib/elm_clipper.c
@@ -0,0 +1,225 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
+
+#include <Elementary.h>
+
+#include "elm_priv.h"
+#include "elm_widget_clipper.h"
+#include "elm_widget_container.h"
+
+#define MY_CLASS ELM_CLIPPER_CLASS
+
+#define MY_CLASS_NAME "Elm_Clipper"
+#define MY_CLASS_NAME_LEGACY "elm_clipper"
+
+static void
+_calc_region(Eo *obj)
+{
+   int x, y, w, h;
+   int calx1, caly1, calx2, caly2;
+
+   ELM_CLIPPER_DATA_GET(obj, sd);
+   evas_object_geometry_get(sd->content, &x, &y, &w, &h);
+
+   calx1 = (int)(w * sd->region_x1 + x);
+   caly1 = (int)(h * sd->region_y1 + y);
+
+   if (sd->region_x2 < sd->region_x1) calx2 = 0;
+   else calx2 = (int)(w * (sd->region_x2 - sd->region_x1));
+   if (sd->region_y2 < sd->region_y1) caly2 = 0;
+   else caly2 = (int)(h * (sd->region_y2 - sd->region_y1));
+
+   evas_object_move(sd->clipper, calx1, caly1);
+   evas_object_resize(sd->clipper, calx2, caly2);
+}
+
+EOLIAN static void
+_elm_clipper_clip_set(Eo *obj, Elm_Clipper_Data *sd, Evas_Object *clip)
+{
+   if (sd->clipper != clip)
+     {
+        if (sd->clipper)
+          {
+             elm_widget_sub_object_del(obj, sd->clipper);
+             if (sd->content) evas_object_clip_unset(sd->content);
+             sd->clipper = NULL;
+          }
+        if (clip)
+          {
+             elm_widget_sub_object_add(obj, clip);
+             evas_object_smart_member_add(clip, obj);
+             _calc_region(obj);
+             if (sd->content) evas_object_clip_set(sd->content, clip);
+             sd->clipper = clip;
+          }
+     }
+}
+
+EOLIAN static Evas_Object *
+_elm_clipper_clip_get(Eo *obj EINA_UNUSED, Elm_Clipper_Data *sd)
+{
+   return sd->clipper;
+}
+
+EOLIAN static void
+_elm_clipper_region_set(Eo *obj, Elm_Clipper_Data *sd, double x1, double y1, 
double x2, double y2)
+{
+   if (x2 < x1  || y2 < y1)
+     ERR("Clipper region x2/y2 should be greater than or equal to x1/y1!\n");
+
+   if (sd->region_x1 != x1 || sd->region_y1 != y1 ||
+       sd->region_x2 != x2 || sd->region_y2 != y2)
+     {
+        sd->region_x1 = x1;
+        sd->region_y1 = y1;
+        sd->region_x2 = x2;
+        sd->region_y2 = y2;
+        _calc_region(obj);
+     }
+}
+
+EOLIAN static void
+_elm_clipper_region_get(Eo *obj EINA_UNUSED, Elm_Clipper_Data *sd, double *x1, 
double *y1, double *x2, double *y2)
+{
+   if (x1) *x1 = sd->region_x1;
+   if (y1) *y1 = sd->region_y1;
+   if (x2) *x2 = sd->region_x2;
+   if (y2) *y2 = sd->region_y2;
+}
+
+EOLIAN static Eina_Bool
+_elm_clipper_elm_widget_sub_object_del(Eo *obj, Elm_Clipper_Data *sd, 
Evas_Object *sobj)
+{
+   Eina_Bool int_ret = EINA_FALSE;
+   eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_del(sobj));
+   if (!int_ret) return EINA_FALSE;
+   if (sobj == sd->content) evas_object_data_del(sobj, "_elm_leaveme");
+   evas_object_smart_member_del(sobj);
+   return EINA_TRUE;
+}
+
+EOLIAN static void
+_elm_clipper_evas_object_smart_resize(Eo *obj, Elm_Clipper_Data *sd 
EINA_UNUSED, Evas_Coord w, Evas_Coord h)
+{
+   eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
+   if(sd->content) evas_object_resize(sd->content, w, h);
+   _calc_region(obj);
+}
+
+EOLIAN static void
+_elm_clipper_evas_object_smart_move(Eo *obj, Elm_Clipper_Data *sd EINA_UNUSED, 
Evas_Coord x, Evas_Coord y)
+{
+   eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
+   evas_object_move(sd->content, x, y);
+   _calc_region(obj);
+}
+
+EOLIAN static void
+_elm_clipper_evas_object_smart_show(Eo *obj, Elm_Clipper_Data *sd)
+{
+   eo_do_super(obj, MY_CLASS, evas_obj_smart_show());
+   if(sd->content) evas_object_show(sd->content);
+   if(sd->clipper) evas_object_show(sd->clipper);
+
+}
+
+EOLIAN static void
+_elm_clipper_evas_object_smart_hide(Eo *obj, Elm_Clipper_Data *sd)
+{
+   eo_do_super(obj, MY_CLASS, evas_obj_smart_hide());
+   if(sd->content) evas_object_hide(sd->content);
+   if(sd->clipper) evas_object_hide(sd->clipper);
+}
+
+EOLIAN static Eina_Bool
+_elm_clipper_elm_container_content_set(Eo *obj, Elm_Clipper_Data *sd, const 
char *part, Evas_Object *content)
+{
+   if (part && strcmp(part, "default")) return EINA_FALSE;
+   if (sd->content != content)
+     {
+        if (sd->content)
+          {
+             elm_widget_sub_object_del(obj, sd->content);
+             sd->content = NULL;
+          }
+        if (content)
+          {
+             elm_widget_sub_object_add(content,obj);
+             evas_object_data_set(content, "_elm_leaveme", (void *)1);
+             evas_object_smart_member_add(content, obj);
+             _calc_region(obj);
+             if (sd->clipper) evas_object_clip_set(content, sd->clipper);
+             sd->content = content;
+          }
+     }
+   return EINA_TRUE;
+}
+
+EOLIAN static Evas_Object*
+_elm_clipper_elm_container_content_get(Eo *obj EINA_UNUSED, Elm_Clipper_Data 
*sd, const char *part)
+{
+   if (part && strcmp(part, "default")) return NULL;
+   return sd->content;
+}
+
+EOLIAN static Evas_Object*
+_elm_clipper_elm_container_content_unset(Eo *obj, Elm_Clipper_Data *sd, const 
char *part)
+{
+   Evas_Object *content;
+   if (part && strcmp(part, "default")) return NULL;
+   content = sd->content;
+   elm_widget_sub_object_del(obj, sd->content);
+   sd->content = NULL;
+   return content;
+}
+
+EOLIAN static void
+_elm_clipper_evas_object_smart_add(Eo *obj, Elm_Clipper_Data *priv)
+{
+   eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
+   elm_widget_sub_object_parent_add(obj);
+   elm_widget_can_focus_set(obj, EINA_FALSE);
+   priv->content = NULL;
+   priv->clipper = NULL;
+   priv->region_x1 = 0;
+   priv->region_y1 = 0;
+   priv->region_x2 = 1;
+   priv->region_y2 = 1;
+}
+
+EOLIAN static void
+_elm_clipper_evas_object_smart_del(Eo *obj, Elm_Clipper_Data *sd)
+{
+   eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
+   ELM_SAFE_FREE(sd->content, evas_object_del);
+   ELM_SAFE_FREE(sd->clipper, evas_object_del);
+   sd->content = NULL;
+   sd->clipper = NULL;
+}
+
+
+EAPI Evas_Object *
+elm_clipper_add(Evas_Object *parent)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
+   Evas_Object *obj = eo_add(MY_CLASS, parent);
+   return obj;
+}
+
+EOLIAN static void
+_elm_clipper_eo_base_constructor(Eo *obj, Elm_Clipper_Data *sd EINA_UNUSED)
+{
+   eo_do_super(obj, MY_CLASS, eo_constructor());
+   eo_do(obj, evas_obj_type_set(MY_CLASS_NAME_LEGACY));
+}
+
+static void
+_elm_clipper_class_constructor(Eo_Class *klass)
+{
+   evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
+}
+
+#include "elm_clipper.eo.c"
diff --git a/src/lib/elm_clipper.eo b/src/lib/elm_clipper.eo
new file mode 100644
index 0000000..fa31eb2
--- /dev/null
+++ b/src/lib/elm_clipper.eo
@@ -0,0 +1,78 @@
+class Elm.Clipper (Elm.Container)
+{
+   eo_prefix: elm_obj_clipper;
+   methods {
+      @property clip {
+         set {
+            /*@
+            @brief Set the clip object of the clipper
+
+            Sets the clip object for clipping
+
+            @note
+            Allow setting only an Evas_Object_Rectangle and an 
Evas_Object_Image as clip on 1.14
+
+            @since 1.15
+
+            @ingroup Clipper */
+         }
+         get {
+            /*@
+            @brief Get the mask object of the clipper
+
+            @see elm_clipper_mask_set()
+
+            @since 1.15
+
+            @ingroup Clipper */
+         }
+         values {
+            Evas_Object *mask;
+         }
+      }
+      @property region {
+         set {
+            /*@
+            @brief Set the region of the clipper
+
+            Sets the position and the size of the clipper on clipper object
+
+            @note The value should be normalized. (0 ~ 1)
+
+            @since 1.15
+
+            @ingroup Clipper */
+         }
+         get {
+            /*@
+            @brief Get the region of the clipper
+
+            @see elm_clipper_region_align_set()
+
+            @since 1.15
+
+            @ingroup Clipper */
+         }
+         values {
+            double x1; /*@ left edge of the clipper on elm_clipper widget */
+            double y1; /*@ top edge of the clipper on elm_clipper widget */
+            double x2; /*@ right edge of the clipper on elm_clipper widget */
+            double y2; /*@ bottom edge of the clipper on elm_clipper widget */
+         }
+      }
+   }
+   implements {
+      class.constructor;
+      Eo.Base.constructor;
+      Evas.Object_Smart.hide;
+      Evas.Object_Smart.show;
+      Evas.Object_Smart.move;
+      Evas.Object_Smart.add;
+      Evas.Object_Smart.del;
+      Evas.Object_Smart.resize;
+      Elm.Widget.sub_object_del;
+      Elm.Container.content_get;
+      Elm.Container.content_set;
+      Elm.Container.content_unset;
+   }
+}
diff --git a/src/lib/elm_clipper.h b/src/lib/elm_clipper.h
new file mode 100644
index 0000000..2ae4dd5
--- /dev/null
+++ b/src/lib/elm_clipper.h
@@ -0,0 +1,41 @@
+/**
+ * @defgroup Clipper Clipper
+ * @ingroup Elementary
+ *
+ * This widget display a clipped object.
+ * For this widget, need a clipper object and a content object.
+ * The content would be clipped out by the clipper.
+ * If clipper is not set, you would see the content without cuts
+ *
+ * The Evas_Object_Rectangle and the Evas_Object_Image object can be a clipper.
+ * A content can have only a clipper even if user set some objects as the 
clipper.
+ * 
+ * This widget can display a clipped object into many shapes according to the 
clipper.
+ * The shape of the clipped object be decided by pixel's transparency of the 
clipper object.
+ * If you want to cut out the content into a circle,
+ * the clipper's pixel should have non-zero as alpha value into the circle.
+ * In case of outside of the circle, should have zero as alpha value.
+ *
+ * This widget inherits from @ref elm-container-class,
+ * So you can use are:
+ *
+ * @li @ref elm_object_part_content_set
+ * @li @ref elm_object_part_content_get
+ * @li @ref elm_object_part_content_unset
+ *
+ * Default content parts of the clipper widget that you can use are:
+ * @li @c "default" - The content to be clipped off
+ *
+ * @{
+ */
+
+#ifdef EFL_EO_API_SUPPORT
+#include <elm_clipper_eo.h>
+#endif
+#ifndef EFL_NOLEGACY_API_SUPPORT
+#include <elm_clipper_legacy.h>
+#endif
+
+/**
+ * @}
+ */
diff --git a/src/lib/elm_clipper_eo.h b/src/lib/elm_clipper_eo.h
new file mode 100644
index 0000000..3b9a71c
--- /dev/null
+++ b/src/lib/elm_clipper_eo.h
@@ -0,0 +1,11 @@
+/**
+ * @ingroup Clipper
+ *
+ * @{
+ */
+
+#include "elm_clipper.eo.h"
+
+/**
+ * @}
+ */
diff --git a/src/lib/elm_clipper_legacy.h b/src/lib/elm_clipper_legacy.h
new file mode 100644
index 0000000..0972573
--- /dev/null
+++ b/src/lib/elm_clipper_legacy.h
@@ -0,0 +1,12 @@
+/**
+ * @brief Add a new clipper object to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ * @since 1.14
+ *
+ * @ingroup Clipper
+ */
+EAPI Evas_Object                 *elm_clipper_add(Evas_Object *parent);
+
+#include "elm_clipper.eo.legacy.h"
diff --git a/src/lib/elm_widget_clipper.h b/src/lib/elm_widget_clipper.h
new file mode 100644
index 0000000..08bb5e8
--- /dev/null
+++ b/src/lib/elm_widget_clipper.h
@@ -0,0 +1,66 @@
+#ifndef ELM_WIDGET_CLIPPER_H
+#define ELM_WIDGET_CLIPPER_H
+
+#include "Elementary.h"
+
+/* DO NOT USE THIS HEADER UNLESS YOU ARE PREPARED FOR BREAKING OF YOUR
+ * CODE. THIS IS ELEMENTARY'S INTERNAL WIDGET API (for now) AND IS NOT
+ * FINAL. CALL elm_widget_api_check(ELM_INTERNAL_API_VERSION) TO CHECK
+ * IT AT RUNTIME.
+ */
+
+/**
+ * @addtogroup Widget
+ * @{
+ *
+ * @section elm-clipper-class The Elementary Clipper Class
+ *
+ * Elementary, besides having the @ref Clipper widget, exposes its
+ * foundation -- the Elementary Clipper Class -- in order to create other
+ * widgets which are a clipper object with some more logic on top.
+ */
+
+
+/**
+ * Base widget smart data extended with clipper instance data.
+ */
+typedef struct _Elm_Clipper_Data Elm_Clipper_Data;
+struct _Elm_Clipper_Data
+{
+   Evas_Object *content, *clipper;
+   float region_x1;
+   float region_y1;
+   float region_x2;
+   float region_y2;
+};
+
+/**
+ * @}
+ */
+
+#define ELM_CLIPPER_DATA_GET(o, sd) \
+  Elm_Clipper_Data * sd = eo_data_scope_get(o, ELM_CLIPPER_CLASS)
+
+#define ELM_CLIPPER_DATA_GET_OR_RETURN(o, ptr)        \
+  ELM_CLIPPER_DATA_GET(o, ptr);                       \
+  if (EINA_UNLIKELY(!ptr))                           \
+    {                                                \
+       CRI("No widget data for object %p (%s)",      \
+           o, evas_object_type_get(o));              \
+       return;                                       \
+    }
+
+#define ELM_CLIPPER_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
+  ELM_CLIPPER_DATA_GET(o, ptr);                         \
+  if (EINA_UNLIKELY(!ptr))                             \
+    {                                                  \
+       CRI("No widget data for object %p (%s)",        \
+           o, evas_object_type_get(o));                \
+       return val;                                     \
+    }
+
+#define ELM_CLIPPER_CHECK(obj)                              \
+  if (EINA_UNLIKELY(!eo_isa((obj), ELM_CLIPPER_CLASS))) \
+    return
+
+#endif

-- 


Reply via email to