From 58dd0bebaaca70cfdbb97d860a5637db1e52425d Mon Sep 17 00:00:00 2001 From: Jaehyun Cho Date: Fri, 25 Aug 2017 10:47:26 +0900 Subject: [PATCH] efl_animation: Add alpha animation object --- src/Makefile_Elementary.am | 1 + src/Makefile_Evas.am | 5 +- src/bin/elementary/Makefile.am | 1 + src/bin/elementary/test.c | 3 + src/bin/elementary/test_efl_anim_alpha.c | 132 +++++++++++++++++++++ src/lib/evas/Evas_Common.h | 7 ++ src/lib/evas/Evas_Eo.h | 1 + src/lib/evas/Evas_Internal.h | 5 + src/lib/evas/canvas/efl_animation_alpha.c | 23 ++++ src/lib/evas/canvas/efl_animation_alpha.eo | 1 + src/lib/evas/canvas/efl_animation_object_alpha.c | 90 ++++++++++++++ src/lib/evas/canvas/efl_animation_object_alpha.eo | 11 ++ .../canvas/efl_animation_object_alpha_private.h | 36 ++++++ 13 files changed, 315 insertions(+), 1 deletion(-) create mode 100644 src/bin/elementary/test_efl_anim_alpha.c create mode 100644 src/lib/evas/canvas/efl_animation_object_alpha.c create mode 100644 src/lib/evas/canvas/efl_animation_object_alpha.eo create mode 100644 src/lib/evas/canvas/efl_animation_object_alpha_private.h diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am index ee0113c..7e98233 100644 --- a/src/Makefile_Elementary.am +++ b/src/Makefile_Elementary.am @@ -797,6 +797,7 @@ bin/elementary/test_dayselector.c \ bin/elementary/test_disable.c \ bin/elementary/test_diskselector.c \ bin/elementary/test_dnd.c \ +bin/elementary/test_efl_anim_alpha.c \ bin/elementary/test_eio.c \ bin/elementary/test_entry.c \ bin/elementary/test_entry_anchor.c \ diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index c938821..8da2467 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -47,6 +47,7 @@ evas_eolian_pub_files = \ lib/evas/canvas/efl_animation.eo \ lib/evas/canvas/efl_animation_alpha.eo \ lib/evas/canvas/efl_animation_object.eo \ + lib/evas/canvas/efl_animation_object_alpha.eo \ $(NULL) evas_eolian_legacy_files = \ @@ -127,7 +128,8 @@ lib/evas/canvas/efl_canvas_surface.h \ lib/evas/common3d/primitives/primitive_common.h \ lib/evas/canvas/efl_animation_private.h \ lib/evas/canvas/efl_animation_alpha_private.h \ -lib/evas/canvas/efl_animation_object_private.h +lib/evas/canvas/efl_animation_object_private.h \ +lib/evas/canvas/efl_animation_object_alpha_private.h # Linebreak @@ -216,6 +218,7 @@ lib/evas/canvas/efl_input_focus.c \ lib/evas/canvas/efl_animation.c \ lib/evas/canvas/efl_animation_alpha.c \ lib/evas/canvas/efl_animation_object.c \ +lib/evas/canvas/efl_animation_object_alpha.c \ $(NULL) EXTRA_DIST2 += \ diff --git a/src/bin/elementary/Makefile.am b/src/bin/elementary/Makefile.am index cfbc619..5dc6479 100644 --- a/src/bin/elementary/Makefile.am +++ b/src/bin/elementary/Makefile.am @@ -32,6 +32,7 @@ test_3d.c \ test_access.c \ test_actionslider.c \ test_anim.c \ +test_efl_anim_alpha.c \ test_application_server.c \ test_bg.c \ test_box.c \ diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c index 7fc3d8a..215d3ec 100644 --- a/src/bin/elementary/test.c +++ b/src/bin/elementary/test.c @@ -322,6 +322,8 @@ void test_evas_map(void *data, Edje_Object *obj, void *event_info); void test_efl_gfx_map(void *data, Edje_Object *obj, void *event_info); void test_ui_textpath(void *data, Edje_Object *obj, void *event_info); +void test_efl_anim_alpha(void *data, Evas_Object *obj, void *event_info); + Evas_Object *win, *tbx; // TODO: refactoring void *tt; Eina_List *tests; @@ -790,6 +792,7 @@ add_tests: ADD_TEST(NULL, "Effects", "Flip Page", test_flip_page); ADD_TEST(NULL, "Effects", "Flip Page (EO API)", test_flip_page_eo); ADD_TEST(NULL, "Effects", "Animation", test_anim); + ADD_TEST(NULL, "Effects", "Efl Animation Alpha", test_efl_anim_alpha); //------------------------------// ADD_TEST(NULL, "Edje External", "ExtButton", test_external_button); diff --git a/src/bin/elementary/test_efl_anim_alpha.c b/src/bin/elementary/test_efl_anim_alpha.c new file mode 100644 index 0000000..e225ae3 --- /dev/null +++ b/src/bin/elementary/test_efl_anim_alpha.c @@ -0,0 +1,132 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif +#include + +typedef struct _App_Data +{ + Efl_Animation *show_anim; + Efl_Animation *hide_anim; + Efl_Animation_Object *anim_obj; + + Eina_Bool is_btn_visible; +} App_Data; + +static void +_anim_started_cb(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED) +{ + printf("Animation has been started!\n"); +} + +static void +_anim_ended_cb(void *data, const Efl_Event *event EINA_UNUSED) +{ + App_Data *ad = data; + + printf("Animation has been ended!\n"); + + ad->anim_obj = NULL; +} + +static void +_anim_running_cb(void *data EINA_UNUSED, const Efl_Event *event) +{ + Efl_Animation_Object_Running_Event_Info *event_info = event->info; + double progress = event_info->progress; + printf("Animation is running! Current progress(%lf)\n", progress); +} + +static void +_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + App_Data *ad = data; + + if (ad->anim_obj) + efl_animation_object_cancel(ad->anim_obj); + + ad->is_btn_visible = !(ad->is_btn_visible); + + if (ad->is_btn_visible) + { + //Create Animation Object from Animation + ad->anim_obj = efl_animation_object_create(ad->show_anim); + elm_object_text_set(obj, "Start Alpha Animation from 1.0 to 0.0"); + } + else + { + //Create Animation Object from Animation + ad->anim_obj = efl_animation_object_create(ad->hide_anim); + elm_object_text_set(obj, "Start Alpha Animation from 0.0 to 1.0"); + } + + //Register callback called when animation starts + efl_event_callback_add(ad->anim_obj, EFL_ANIMATION_OBJECT_EVENT_STARTED, _anim_started_cb, NULL); + + //Register callback called when animation ends + efl_event_callback_add(ad->anim_obj, EFL_ANIMATION_OBJECT_EVENT_ENDED, _anim_ended_cb, ad); + + //Register callback called while animation is executed + efl_event_callback_add(ad->anim_obj, EFL_ANIMATION_OBJECT_EVENT_RUNNING, _anim_running_cb, NULL); + + //Let Animation Object start animation + efl_animation_object_start(ad->anim_obj); +} + +static void +_win_del_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + App_Data *ad = data; + free(ad); +} + +void +test_efl_anim_alpha(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + App_Data *ad = calloc(1, sizeof(App_Data)); + if (!ad) return; + + Evas_Object *win = elm_win_add(NULL, "Efl Animation Alpha", ELM_WIN_BASIC); + elm_win_title_set(win, "Efl Animation Alpha"); + elm_win_autodel_set(win, EINA_TRUE); + evas_object_smart_callback_add(win, "delete,request", _win_del_cb, ad); + + //Button to be animated + Evas_Object *btn = elm_button_add(win); + elm_object_text_set(btn, "Button"); + evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_resize(btn, 200, 200); + evas_object_move(btn, 100, 50); + evas_object_show(btn); + + //Show Animation + Efl_Animation *show_anim = efl_add(EFL_ANIMATION_ALPHA_CLASS, NULL); + efl_animation_alpha_set(show_anim, 0.0, 1.0); + efl_animation_duration_set(show_anim, 1.0); + efl_animation_target_set(show_anim, btn); + efl_animation_final_state_keep_set(show_anim, EINA_TRUE); + + //Hide Animation + Efl_Animation *hide_anim = efl_add(EFL_ANIMATION_ALPHA_CLASS, NULL); + efl_animation_alpha_set(hide_anim, 1.0, 0.0); + efl_animation_duration_set(hide_anim, 1.0); + efl_animation_target_set(hide_anim, btn); + efl_animation_final_state_keep_set(hide_anim, EINA_TRUE); + + //Initialize App Data + ad->show_anim = show_anim; + ad->hide_anim = hide_anim; + ad->anim_obj = NULL; + ad->is_btn_visible = EINA_TRUE; + + //Button to start animation + Evas_Object *btn2 = elm_button_add(win); + elm_object_text_set(btn2, "Start Alpha Animation from 1.0 to 0.0"); + evas_object_smart_callback_add(btn2, "clicked", _btn_clicked_cb, ad); + evas_object_size_hint_weight_set(btn2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_resize(btn2, 200, 50); + evas_object_move(btn2, 100, 300); + evas_object_show(btn2); + + evas_object_resize(win, 400, 400); + evas_object_show(win); +} diff --git a/src/lib/evas/Evas_Common.h b/src/lib/evas/Evas_Common.h index e45bef8..6cbd287 100644 --- a/src/lib/evas/Evas_Common.h +++ b/src/lib/evas/Evas_Common.h @@ -3351,6 +3351,13 @@ typedef Eo Efl_Animation_Object; #endif +#ifndef _EFL_ANIMATION_OBJECT_ALPHA_EO_CLASS_TYPE +#define _EFL_ANIMATION_OBJECT_ALPHA_EO_CLASS_TYPE + +typedef Eo Efl_Animation_Object_Alpha; + +#endif + struct _Efl_Animation_Object_Running_Event_Info { double progress; diff --git a/src/lib/evas/Evas_Eo.h b/src/lib/evas/Evas_Eo.h index 2c23397..d806dea 100644 --- a/src/lib/evas/Evas_Eo.h +++ b/src/lib/evas/Evas_Eo.h @@ -58,6 +58,7 @@ #include "canvas/efl_animation.eo.h" #include "canvas/efl_animation_alpha.eo.h" #include "canvas/efl_animation_object.eo.h" +#include "canvas/efl_animation_object_alpha.eo.h" #endif /* EFL_EO_API_SUPPORT */ diff --git a/src/lib/evas/Evas_Internal.h b/src/lib/evas/Evas_Internal.h index c91defc..88cbded 100644 --- a/src/lib/evas/Evas_Internal.h +++ b/src/lib/evas/Evas_Internal.h @@ -97,6 +97,11 @@ EWAPI extern const Efl_Event_Description _EFL_ANIMATION_OBJECT_EVENT_PRE_STARTED #define EFL_ANIMATION_OBJECT_EVENT_PRE_STARTED (&(_EFL_ANIMATION_OBJECT_EVENT_PRE_STARTED)) /* Efl.Animation.Object END */ +/* Efl.Animation.Object.Alpha */ +EOAPI void efl_animation_object_alpha_set(Eo *obj, double from_alpha, double to_alpha); +EOAPI void efl_animation_object_alpha_get(const Eo *obj, double *from_alpha, double *to_alpha); +/* Efl.Animation.Object.Alpha END */ + #ifdef __cplusplus } #endif diff --git a/src/lib/evas/canvas/efl_animation_alpha.c b/src/lib/evas/canvas/efl_animation_alpha.c index 7bbcac1..c0148b6 100644 --- a/src/lib/evas/canvas/efl_animation_alpha.c +++ b/src/lib/evas/canvas/efl_animation_alpha.c @@ -26,6 +26,29 @@ _efl_animation_alpha_alpha_get(Eo *eo_obj EINA_UNUSED, *to_alpha = pd->to.alpha; } +EOLIAN static Efl_Animation_Object * +_efl_animation_alpha_efl_animation_object_create(Eo *eo_obj, + Efl_Animation_Alpha_Data *pd) +{ + EFL_ANIMATION_ALPHA_CHECK_OR_RETURN(eo_obj, NULL); + + Efl_Animation_Object_Alpha *anim_obj + = efl_add(EFL_ANIMATION_OBJECT_ALPHA_CLASS, NULL); + + Efl_Canvas_Object *target = efl_animation_target_get(eo_obj); + efl_animation_object_target_set(anim_obj, target); + + Eina_Bool state_keep = efl_animation_final_state_keep_get(eo_obj); + efl_animation_object_final_state_keep_set(anim_obj, state_keep); + + double duration = efl_animation_duration_get(eo_obj); + efl_animation_object_duration_set(anim_obj, duration); + + efl_animation_object_alpha_set(anim_obj, pd->from.alpha, pd->to.alpha); + + return anim_obj; +} + EOLIAN static Efl_Object * _efl_animation_alpha_efl_object_constructor(Eo *eo_obj, Efl_Animation_Alpha_Data *pd) diff --git a/src/lib/evas/canvas/efl_animation_alpha.eo b/src/lib/evas/canvas/efl_animation_alpha.eo index a037a9a..de1734a 100644 --- a/src/lib/evas/canvas/efl_animation_alpha.eo +++ b/src/lib/evas/canvas/efl_animation_alpha.eo @@ -18,5 +18,6 @@ class Efl.Animation.Alpha (Efl.Animation) } implements { Efl.Object.constructor; + Efl.Animation.object_create; } } diff --git a/src/lib/evas/canvas/efl_animation_object_alpha.c b/src/lib/evas/canvas/efl_animation_object_alpha.c new file mode 100644 index 0000000..f489b31 --- /dev/null +++ b/src/lib/evas/canvas/efl_animation_object_alpha.c @@ -0,0 +1,90 @@ +#include "efl_animation_object_alpha_private.h" + +EOLIAN static void +_efl_animation_object_alpha_alpha_set(Eo *eo_obj, + Efl_Animation_Object_Alpha_Data *pd, + double from_alpha, + double to_alpha) +{ + EFL_ANIMATION_OBJECT_ALPHA_CHECK_OR_RETURN(eo_obj); + + pd->from.alpha = from_alpha; + pd->to.alpha = to_alpha; +} + +EOLIAN static void +_efl_animation_object_alpha_alpha_get(Eo *eo_obj EINA_UNUSED, + Efl_Animation_Object_Alpha_Data *pd, + double *from_alpha, + double *to_alpha) +{ + EFL_ANIMATION_OBJECT_ALPHA_CHECK_OR_RETURN(eo_obj); + + if (from_alpha) + *from_alpha = pd->from.alpha; + if (to_alpha) + *to_alpha = pd->to.alpha; +} + +static void +_progress_set(Eo *eo_obj, double progress) +{ + EFL_ANIMATION_OBJECT_ALPHA_DATA_GET(eo_obj, pd); + + Efl_Canvas_Object *target = efl_animation_object_target_get(eo_obj); + if (!target) return; + + double alpha + = (pd->from.alpha * (1.0 - progress)) + (pd->to.alpha * progress); + + int r[4], g[4], b[4], a[4]; + int i; + for (i = 0; i < 4; i++) + efl_gfx_map_color_get(target, i, &r[i], &g[i], &b[i], &a[i]); + + for (i = 0; i < 4; i++) + { + r[i] = (int)(r[i] * alpha); + g[i] = (int)(g[i] * alpha); + b[i] = (int)(b[i] * alpha); + a[i] = (int)(a[i] * alpha); + efl_gfx_map_color_set(target, i, r[i], g[i], b[i], a[i]); + } +} + +EOLIAN static void +_efl_animation_object_alpha_efl_animation_object_progress_set(Eo *eo_obj, + Efl_Animation_Object_Alpha_Data *pd EINA_UNUSED, + double progress) +{ + EFL_ANIMATION_OBJECT_ALPHA_CHECK_OR_RETURN(eo_obj); + + if ((progress < 0.0) || (progress > 1.0)) return; + + _progress_set(eo_obj, progress); + + efl_animation_object_progress_set(efl_super(eo_obj, MY_CLASS), progress); +} + +EOLIAN static Efl_Object * +_efl_animation_object_alpha_efl_object_constructor(Eo *eo_obj, + Efl_Animation_Object_Alpha_Data *pd) +{ + eo_obj = efl_constructor(efl_super(eo_obj, MY_CLASS)); + + pd->from.alpha = 1.0; + pd->to.alpha = 1.0; + + return eo_obj; +} + +/* Internal EO APIs */ + +EOAPI EFL_VOID_FUNC_BODYV(efl_animation_object_alpha_set, EFL_FUNC_CALL(from_alpha, to_alpha), double from_alpha, double to_alpha); +EOAPI EFL_VOID_FUNC_BODYV_CONST(efl_animation_object_alpha_get, EFL_FUNC_CALL(from_alpha, to_alpha), double *from_alpha, double *to_alpha); + +#define EFL_ANIMATION_OBJECT_ALPHA_EXTRA_OPS \ + EFL_OBJECT_OP_FUNC(efl_animation_object_alpha_set, _efl_animation_object_alpha_alpha_set), \ + EFL_OBJECT_OP_FUNC(efl_animation_object_alpha_get, _efl_animation_object_alpha_alpha_get) + +#include "efl_animation_object_alpha.eo.c" diff --git a/src/lib/evas/canvas/efl_animation_object_alpha.eo b/src/lib/evas/canvas/efl_animation_object_alpha.eo new file mode 100644 index 0000000..8aa28b8 --- /dev/null +++ b/src/lib/evas/canvas/efl_animation_object_alpha.eo @@ -0,0 +1,11 @@ +import efl_animation_types; + +class Efl.Animation.Object.Alpha (Efl.Animation.Object) +{ + [[Efl alpha animation object class]] + data: Efl_Animation_Object_Alpha_Data; + implements { + Efl.Object.constructor; + Efl.Animation.Object.progress_set; + } +} diff --git a/src/lib/evas/canvas/efl_animation_object_alpha_private.h b/src/lib/evas/canvas/efl_animation_object_alpha_private.h new file mode 100644 index 0000000..a953107 --- /dev/null +++ b/src/lib/evas/canvas/efl_animation_object_alpha_private.h @@ -0,0 +1,36 @@ +#define EFL_ANIMATION_OBJECT_PROTECTED +#define EFL_ANIMATION_OBJECT_ALPHA_PROTECTED + +#include "evas_common_private.h" + +#define MY_CLASS EFL_ANIMATION_OBJECT_ALPHA_CLASS +#define MY_CLASS_NAME efl_class_name_get(MY_CLASS) + +#define MY_CLASS EFL_ANIMATION_OBJECT_ALPHA_CLASS +#define MY_CLASS_NAME efl_class_name_get(MY_CLASS) + +#define EFL_ANIMATION_OBJECT_ALPHA_CHECK_OR_RETURN(anim_obj, ...) \ + do { \ + if (!anim_obj) { \ + CRI("Efl_Animation_Object " # anim_obj " is NULL!"); \ + return __VA_ARGS__; \ + } \ + if (efl_animation_object_is_deleted(anim_obj)) { \ + ERR("Efl_Animation_Object " # anim_obj " has already been deleted!"); \ + return __VA_ARGS__; \ + } \ + } while (0) + +#define EFL_ANIMATION_OBJECT_ALPHA_DATA_GET(o, pd) \ + Efl_Animation_Object_Alpha_Data *pd = efl_data_scope_get(o, EFL_ANIMATION_OBJECT_ALPHA_CLASS) + +typedef struct _Efl_Animation_Object_Alpha_Property +{ + double alpha; +} Efl_Animation_Object_Alpha_Property; + +typedef struct _Efl_Animation_Object_Alpha_Data +{ + Efl_Animation_Object_Alpha_Property from; + Efl_Animation_Object_Alpha_Property to; +} Efl_Animation_Object_Alpha_Data; -- 2.7.4