aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-12-13 17:44:17 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-12-13 19:17:47 +0900
commitc5b87e27f09a82228c61cd47714cc760ab01132c (patch)
treee087a79d7fbf3c9d68870bcbf35dcd3aa7f10f4b
parentevas: Fix potential crash with draw context (diff)
downloadefl-c5b87e27f09a82228c61cd47714cc760ab01132c.tar.gz
-rw-r--r--src/Makefile_Elementary.am1
-rw-r--r--src/bin/elementary/test.c11
-rw-r--r--src/bin/elementary/test_progressbar.c25
-rw-r--r--src/lib/elementary/Elementary.h1
-rw-r--r--src/lib/elementary/efl_ui_layout.c2
-rw-r--r--src/lib/elementary/efl_ui_widget_part_shadow.eo31
-rw-r--r--src/lib/elementary/elm_widget.c267
-rw-r--r--src/lib/elementary/elm_widget.eo3
-rw-r--r--src/lib/elementary/elm_widget.h1
-rw-r--r--src/lib/evas/canvas/efl_canvas_proxy.c3
10 files changed, 340 insertions, 5 deletions
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index 4c78215646..49e2d6818b 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -74,6 +74,7 @@ elm_public_eolian_files = \
lib/elementary/efl_ui_textpath_part.eo \
lib/elementary/efl_ui_widget_part.eo \
lib/elementary/efl_ui_widget_part_bg.eo \
+ lib/elementary/efl_ui_widget_part_shadow.eo \
lib/elementary/efl_ui_win_part.eo \
lib/elementary/efl_access.eo \
lib/elementary/efl_access_action.eo \
diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c
index 8a592ab7d2..f336c3eb70 100644
--- a/src/bin/elementary/test.c
+++ b/src/bin/elementary/test.c
@@ -507,11 +507,14 @@ _menu_create(const char *option_str)
elm_object_part_content_set(bt, "icon", ic);
evas_object_show(ic);
}
- else if (t->is_eo)
+ if (t->is_eo)
{
- ic = efl_add(EFL_UI_IMAGE_CLASS, win,
- efl_ui_image_icon_set(efl_added, "user-bookmarks"));
- elm_object_part_content_set(bt, "icon", ic);
+ Eo *shadow = efl_ref(efl_part(bt, "shadow"));
+ efl_gfx_color_set(shadow, 0, 128, 255, 255);
+ efl_ui_widget_part_shadow_offset_set(shadow, 0, 0);
+ efl_ui_widget_part_shadow_radius_set(shadow, 3, 3);
+ efl_ui_widget_part_shadow_grow_set(shadow, 2);
+ efl_unref(shadow);
}
elm_box_pack_end(tbx2, bt);
evas_object_show(bt);
diff --git a/src/bin/elementary/test_progressbar.c b/src/bin/elementary/test_progressbar.c
index 91282c0cde..1d2f325e5b 100644
--- a/src/bin/elementary/test_progressbar.c
+++ b/src/bin/elementary/test_progressbar.c
@@ -185,10 +185,28 @@ test_progressbar(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve
evas_object_show(pb);
pd->pb5 = pb;
+#define FILTER_CODE \
+ "a = buffer { 'alpha' }" \
+ "grow { 4, dst = a }" \
+ "blur { 20, src = a, color = 'red' }" \
+ "blur { 6, src = a, color = 'red' }" \
+ "blur { 6, src = input, color = 'orange' }" \
+ "blur { 2, src = input, color = 'cyan' }"
+
+#define FILTER2 \
+ "blend { ox = -8, oy = -5, color = color(255, 255, 255, 64) } " \
+ "blend { ox = 5, oy = 5, color = color(255, 255, 255, 64) } " \
+ "blend { ox = -2, oy = 8, color = color(255, 255, 255, 64) } " \
+
+ efl_gfx_filter_program_set(efl_part(pb, "shadow"), FILTER2, "blur");
+
ic2 = elm_icon_add(win);
elm_image_file_set(ic2, buf, NULL);
evas_object_size_hint_aspect_set(ic2, EVAS_ASPECT_CONTROL_HORIZONTAL, 1, 1);
+
+ efl_gfx_filter_program_set(efl_part(ic2, "shadow"), FILTER_CODE, "blur");
+
pb = elm_progressbar_add(win);
elm_progressbar_horizontal_set(pb, EINA_FALSE);
elm_object_text_set(pb, "Label");
@@ -213,6 +231,13 @@ test_progressbar(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve
evas_object_show(pb);
pd->pb7 = pb;
+ Eo *shadow = efl_ref(efl_part(pb, "shadow"));
+ efl_gfx_color_set(shadow, 0, 255, 255, 255);
+ efl_ui_widget_part_shadow_offset_set(shadow, 0, 0);
+ efl_ui_widget_part_shadow_radius_set(shadow, 10, 10);
+ efl_ui_widget_part_shadow_grow_set(shadow, 5);
+ efl_unref(shadow);
+
bt_bx = elm_box_add(win);
elm_box_horizontal_set(bt_bx, EINA_TRUE);
evas_object_size_hint_weight_set(bt_bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index 66b3c8fd14..b6b8654225 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -283,6 +283,7 @@ EAPI extern Elm_Version *elm_version;
# include <efl_config_global.eo.h>
# include <efl_ui_widget_part.eo.h>
# include <efl_ui_widget_part_bg.eo.h>
+# include <efl_ui_widget_part_shadow.eo.h>
# include <efl_ui_layout_part.eo.h>
# include <efl_ui_layout_part_box.eo.h>
# include <efl_ui_layout_part_content.eo.h>
diff --git a/src/lib/elementary/efl_ui_layout.c b/src/lib/elementary/efl_ui_layout.c
index 24fb83fd6c..8d47fe8dcc 100644
--- a/src/lib/elementary/efl_ui_layout.c
+++ b/src/lib/elementary/efl_ui_layout.c
@@ -2418,6 +2418,8 @@ _efl_ui_layout_efl_part_part(const Eo *obj, Efl_Ui_Layout_Data *sd EINA_UNUSED,
return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_BG_CLASS, obj, part);
}
+ else if (eina_streq(part, "shadow"))
+ return efl_part(efl_super(obj, MY_CLASS), part);
if (type >= EFL_CANVAS_LAYOUT_PART_TYPE_LAST)
{
diff --git a/src/lib/elementary/efl_ui_widget_part_shadow.eo b/src/lib/elementary/efl_ui_widget_part_shadow.eo
new file mode 100644
index 0000000000..9581658ad6
--- /dev/null
+++ b/src/lib/elementary/efl_ui_widget_part_shadow.eo
@@ -0,0 +1,31 @@
+class Efl.Ui.Widget.Part_Shadow (Efl.Ui.Widget.Part, Efl.Gfx, Efl.Gfx.Filter)
+{
+ data: null;
+ methods {
+ @property offset {
+ values {
+ ox: double;
+ oy: double;
+ }
+ }
+ @property radius {
+ values {
+ rx: double;
+ ry: double;
+ }
+ }
+ @property grow {
+ values {
+ radius: double;
+ }
+ }
+ }
+ implements {
+ Efl.Gfx.color { set; get; }
+ Efl.Gfx.Filter.filter_program { set; get; }
+ Efl.Gfx.Filter.filter_source { set; get; }
+ Efl.Gfx.Filter.filter_data { set; get; }
+ Efl.Gfx.Filter.filter_padding { get; }
+ Efl.Gfx.Filter.filter_state { set; get; }
+ }
+}
diff --git a/src/lib/elementary/elm_widget.c b/src/lib/elementary/elm_widget.c
index 83437d604b..9f363a2cbe 100644
--- a/src/lib/elementary/elm_widget.c
+++ b/src/lib/elementary/elm_widget.c
@@ -114,6 +114,7 @@ static void
_on_sub_obj_del(void *data, const Efl_Event *event);
static void _propagate_event(void *data, const Efl_Event *eo_event);
static void _elm_widget_focus_tree_unfocusable_handle(Eo *obj);
+static void _elm_widget_shadow_update(Elm_Widget *obj);
EFL_CALLBACKS_ARRAY_DEFINE(elm_widget_subitems_callbacks,
{ EFL_EVENT_DEL, _on_sub_obj_del });
@@ -795,6 +796,8 @@ _smart_reconfigure(Elm_Widget_Smart_Data *sd)
evas_object_move(sd->bg, sd->x, sd->y);
evas_object_resize(sd->bg, sd->w, sd->h);
}
+ if (sd->has_shadow)
+ _elm_widget_shadow_update(sd->obj);
}
EOLIAN static void
@@ -5625,6 +5628,268 @@ elm_widget_signal_callback_del(Eo *obj, const char *emission, const char *source
}
+/* Widget Shadow Begin */
+
+typedef struct _Widget_Shadow
+{
+ Eo *widget;
+ Eo *surface;
+ struct {
+ double rx, ry, ox, oy, grow;
+ int r, g, b, a;
+ } props;
+ Eina_Stringshare *code, *name;
+} Widget_Shadow;
+
+static void _widget_shadow_update(Widget_Shadow *shadow);
+
+static void
+_widget_shadow_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ Widget_Shadow *shadow = data;
+
+ efl_del(shadow->surface);
+ free(shadow);
+}
+
+static void
+_widget_shadow_event_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ Widget_Shadow *shadow = data;
+ _widget_shadow_update(shadow);
+}
+
+EFL_CALLBACKS_ARRAY_DEFINE(widget_shadow_cb,
+{ EFL_EVENT_DEL, _widget_shadow_del_cb },
+{ EFL_GFX_EVENT_MOVE, _widget_shadow_event_cb },
+{ EFL_GFX_EVENT_RESIZE, _widget_shadow_event_cb },
+{ EFL_GFX_EVENT_RESTACK, _widget_shadow_event_cb },
+{ EFL_GFX_EVENT_HIDE, _widget_shadow_event_cb },
+{ EFL_GFX_EVENT_SHOW, _widget_shadow_event_cb })
+
+static Widget_Shadow *
+_widget_shadow_part_get(Eo *part_obj)
+{
+ Elm_Part_Data *pd = efl_data_scope_get(part_obj, EFL_UI_WIDGET_PART_CLASS);
+ Widget_Shadow *shadow;
+ Eo *widget = pd->obj;
+
+ shadow = efl_key_data_get(widget, "__elm_shadow");
+ if (!shadow)
+ {
+ shadow = calloc(1, sizeof(*shadow));
+ shadow->widget = pd->obj;
+ efl_key_data_set(widget, "__elm_shadow", shadow);
+ efl_event_callback_array_add(widget, widget_shadow_cb(), shadow);
+ }
+ return shadow;
+}
+
+static void
+_widget_shadow_update(Widget_Shadow *ws)
+{
+ int l = 0, r = 0, t = 0, b = 0;
+ Eina_Rect srect, wrect, fill;
+ char filter[1024];
+
+#define FILTER_FMT \
+ "a = buffer { 'alpha' }" \
+ "grow { %f, dst = a }" \
+ "blur { src = a, rx = %f, ry = %f, color = color(%d,%d,%d,%d) }"
+
+ if (!ws->surface)
+ {
+ ws->surface = efl_add(EFL_CANVAS_PROXY_CLASS, ws->widget);
+ efl_gfx_fill_auto_set(ws->surface, 1);
+ efl_canvas_proxy_source_clip_set(ws->surface, EINA_FALSE);
+ efl_canvas_proxy_source_events_set(ws->surface, EINA_FALSE);
+ efl_canvas_proxy_source_set(ws->surface, ws->widget);
+ }
+
+ if (!ws->code)
+ {
+ snprintf(filter, sizeof(filter), FILTER_FMT,
+ ws->props.grow, ws->props.rx, ws->props.ry,
+ ws->props.r, ws->props.g, ws->props.b, ws->props.a);
+ }
+
+ efl_gfx_filter_program_set(ws->surface,
+ ws->code ? ws->code : filter,
+ ws->name ? ws->name : "shadow");
+ efl_gfx_filter_padding_get(ws->surface, &l, &r, &t, &b);
+
+ wrect = efl_gfx_geometry_get(ws->widget);
+ srect.x = wrect.x + (int) (-l + ws->props.ox);
+ srect.y = wrect.y + (int) (-t + ws->props.oy);
+ srect.w = wrect.w + (int) (l + r);
+ srect.h = wrect.h + (int) (t + b);
+ fill.size = wrect.size;
+ fill.x = 0;
+ fill.y = 0;
+
+ if ((!ws->props.a && !ws->code) ||
+ !efl_gfx_visible_get(ws->widget))
+ {
+ efl_gfx_visible_set(ws->surface, EINA_FALSE);
+ return;
+ }
+
+ efl_canvas_object_clip_set(ws->surface, efl_canvas_object_clip_get(ws->widget));
+ efl_canvas_group_member_add(efl_canvas_object_render_parent_get(ws->widget), ws->surface);
+ efl_gfx_geometry_set(ws->surface, srect);
+ efl_gfx_stack_below(ws->surface, ws->widget);
+ efl_gfx_visible_set(ws->surface, EINA_TRUE);
+}
+
+static void
+_elm_widget_shadow_update(Elm_Widget *obj)
+{
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ _widget_shadow_update(shadow);
+}
+
+EOLIAN static void
+_efl_ui_widget_part_shadow_offset_set(Eo *obj, void *_pd EINA_UNUSED, double ox, double oy)
+{
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ shadow->props.ox = ox;
+ shadow->props.oy = oy;
+ _widget_shadow_update(shadow);
+}
+
+EOLIAN static void
+_efl_ui_widget_part_shadow_offset_get(Eo *obj, void *_pd EINA_UNUSED, double *ox, double *oy)
+{
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ if (ox) *ox = shadow->props.ox;
+ if (oy) *oy = shadow->props.oy;
+}
+
+EOLIAN static void
+_efl_ui_widget_part_shadow_radius_set(Eo *obj, void *_pd EINA_UNUSED, double rx, double ry)
+{
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ shadow->props.rx = rx;
+ shadow->props.ry = ry;
+ _widget_shadow_update(shadow);
+}
+
+EOLIAN static void
+_efl_ui_widget_part_shadow_radius_get(Eo *obj, void *_pd EINA_UNUSED, double *rx, double *ry)
+{
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ if (rx) *rx = shadow->props.rx;
+ if (ry) *ry = shadow->props.ry;
+}
+
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_color_set(Eo *obj, void *_pd EINA_UNUSED, int r, int g, int b, int a)
+{
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ shadow->props.r = r;
+ shadow->props.g = g;
+ shadow->props.b = b;
+ shadow->props.a = a;
+ _widget_shadow_update(shadow);
+}
+
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_color_get(Eo *obj, void *_pd EINA_UNUSED, int *r, int *g, int *b, int *a)
+{
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ if (r) *r = shadow->props.r;
+ if (g) *g = shadow->props.g;
+ if (b) *b = shadow->props.b;
+ if (a) *a = shadow->props.a;
+}
+
+EOLIAN static void
+_efl_ui_widget_part_shadow_grow_set(Eo *obj, void *_pd EINA_UNUSED, double radius)
+{
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ shadow->props.grow = radius;
+ _widget_shadow_update(shadow);
+}
+
+EOLIAN static double
+_efl_ui_widget_part_shadow_grow_get(Eo *obj, void *_pd EINA_UNUSED)
+{
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ return shadow->props.grow;
+}
+
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_program_set(Eo *obj, void *_pd EINA_UNUSED, const char *code, const char *name)
+{
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ eina_stringshare_replace(&ws->code, code);
+ eina_stringshare_replace(&ws->name, name);
+ _widget_shadow_update(ws);
+}
+
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_program_get(Eo *obj, void *_pd EINA_UNUSED, const char **code, const char **name)
+{
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ efl_gfx_filter_program_get(ws->surface, code, name);
+}
+
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_source_set(Eo *obj, void *_pd EINA_UNUSED, const char *name, Efl_Gfx *source)
+{
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ _widget_shadow_update(ws);
+ efl_gfx_filter_source_set(ws->surface, name, source);
+}
+
+EOLIAN static Efl_Gfx *
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_source_get(Eo *obj, void *_pd EINA_UNUSED, const char *name)
+{
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ return efl_gfx_filter_source_get(ws->surface, name);
+}
+
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_data_set(Eo *obj, void *_pd EINA_UNUSED, const char *name, const char *value, Eina_Bool execute)
+{
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ _widget_shadow_update(ws);
+ efl_gfx_filter_data_set(ws->surface, name, value, execute);
+}
+
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_data_get(Eo *obj, void *_pd EINA_UNUSED, const char *name, const char **value, Eina_Bool *execute)
+{
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ efl_gfx_filter_data_get(ws->surface, name, value, execute);
+}
+
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_padding_get(Eo *obj, void *_pd EINA_UNUSED, int *l, int *r, int *t, int *b)
+{
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ efl_gfx_filter_padding_get(ws->surface, l, r, t, b);
+}
+
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_state_set(Eo *obj, void *_pd EINA_UNUSED, const char *cur_state, double cur_val, const char *next_state, double next_val, double pos)
+{
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ efl_gfx_filter_state_set(ws->surface, cur_state, cur_val, next_state, next_val, pos);
+}
+
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_state_get(Eo *obj, void *_pd EINA_UNUSED, const char **cur_state, double *cur_val, const char **next_state, double *next_val, double *pos)
+{
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ efl_gfx_filter_state_get(ws->surface, cur_state, cur_val, next_state, next_val, pos);
+}
+
+#include "efl_ui_widget_part_shadow.eo.c"
+
+/* Widget Shadow End */
+
+
/* Efl.Part implementation */
EOLIAN static Efl_Object *
@@ -5632,6 +5897,8 @@ _elm_widget_efl_part_part(const Eo *obj, Elm_Widget_Smart_Data *wd EINA_UNUSED,
{
if (eina_streq(part, "background"))
return ELM_PART_IMPLEMENT(EFL_UI_WIDGET_PART_BG_CLASS, obj, part);
+ else if (eina_streq(part, "shadow"))
+ return ELM_PART_IMPLEMENT(EFL_UI_WIDGET_PART_SHADOW_CLASS, obj, part);
return ELM_PART_IMPLEMENT(EFL_UI_WIDGET_PART_CLASS, obj, part);
}
diff --git a/src/lib/elementary/elm_widget.eo b/src/lib/elementary/elm_widget.eo
index 92071374b5..b8c093af06 100644
--- a/src/lib/elementary/elm_widget.eo
+++ b/src/lib/elementary/elm_widget.eo
@@ -570,6 +570,9 @@ abstract Elm.Widget (Efl.Canvas.Group, Efl.Access,
return: Efl.Ui.Focus.Manager; [[The focus manager.]]
}
}
+ parts {
+ shadow: Efl.Ui.Widget.Part_Shadow;
+ }
implements {
class.constructor;
Efl.Object.constructor;
diff --git a/src/lib/elementary/elm_widget.h b/src/lib/elementary/elm_widget.h
index 23e1a5ec4c..b7975a45da 100644
--- a/src/lib/elementary/elm_widget.h
+++ b/src/lib/elementary/elm_widget.h
@@ -465,6 +465,7 @@ typedef struct _Elm_Widget_Smart_Data
Eina_Bool on_destroy: 1; /**< This is true when the widget is on destruction(general widget destructor). */
Eina_Bool provider_lookup : 1; /**< This is true when efl_provider_find is currently walking the tree */
Eina_Bool legacy : 1; /**< Widget was created with a legacy API, not efl_add() */
+ Eina_Bool has_shadow : 1;
} Elm_Widget_Smart_Data;
typedef Elm_Widget_Smart_Data Efl_Ui_Widget_Data;
diff --git a/src/lib/evas/canvas/efl_canvas_proxy.c b/src/lib/evas/canvas/efl_canvas_proxy.c
index ab46ff391e..60049ecaaf 100644
--- a/src/lib/evas/canvas/efl_canvas_proxy.c
+++ b/src/lib/evas/canvas/efl_canvas_proxy.c
@@ -219,7 +219,8 @@ _evas_image_proxy_set(Evas_Object *eo_proxy, Evas_Object *eo_src)
Evas_Object_Protected_Data *proxy = efl_data_scope_get(eo_proxy, EFL_CANVAS_OBJECT_CLASS);
Evas_Image_Data *o = efl_data_scope_get(eo_proxy, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
- efl_file_set(eo_proxy, NULL, NULL);
+ if (o->legacy_type)
+ efl_file_set(eo_proxy, NULL, NULL);
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, proxy->proxy, Evas_Object_Proxy_Data, proxy_write)
proxy_write->is_proxy = EINA_TRUE;