diff --git a/legacy/elementary/src/lib/Elementary.h.in b/legacy/elementary/src/lib/Elementary.h.in index cd17bbfd31..87d9045955 100644 --- a/legacy/elementary/src/lib/Elementary.h.in +++ b/legacy/elementary/src/lib/Elementary.h.in @@ -195,6 +195,7 @@ EAPI extern Elm_Version *elm_version; #include #include #include +#include #include #include #include diff --git a/legacy/elementary/src/lib/Makefile.am b/legacy/elementary/src/lib/Makefile.am index 859b0ef4eb..a488e76ab3 100644 --- a/legacy/elementary/src/lib/Makefile.am +++ b/legacy/elementary/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/legacy/elementary/src/lib/elm_clipper.c b/legacy/elementary/src/lib/elm_clipper.c new file mode 100644 index 0000000000..374f9bf57f --- /dev/null +++ b/legacy/elementary/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 + +#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/legacy/elementary/src/lib/elm_clipper.eo b/legacy/elementary/src/lib/elm_clipper.eo new file mode 100644 index 0000000000..fa31eb2ae8 --- /dev/null +++ b/legacy/elementary/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/legacy/elementary/src/lib/elm_clipper.h b/legacy/elementary/src/lib/elm_clipper.h new file mode 100644 index 0000000000..2ae4dd58fe --- /dev/null +++ b/legacy/elementary/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 +#endif +#ifndef EFL_NOLEGACY_API_SUPPORT +#include +#endif + +/** + * @} + */ diff --git a/legacy/elementary/src/lib/elm_clipper_eo.h b/legacy/elementary/src/lib/elm_clipper_eo.h new file mode 100644 index 0000000000..3b9a71cc0a --- /dev/null +++ b/legacy/elementary/src/lib/elm_clipper_eo.h @@ -0,0 +1,11 @@ +/** + * @ingroup Clipper + * + * @{ + */ + +#include "elm_clipper.eo.h" + +/** + * @} + */ diff --git a/legacy/elementary/src/lib/elm_clipper_legacy.h b/legacy/elementary/src/lib/elm_clipper_legacy.h new file mode 100644 index 0000000000..09725739f9 --- /dev/null +++ b/legacy/elementary/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/legacy/elementary/src/lib/elm_widget_clipper.h b/legacy/elementary/src/lib/elm_widget_clipper.h new file mode 100644 index 0000000000..08bb5e8d2a --- /dev/null +++ b/legacy/elementary/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