diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am index f8c8b7ef84..8a6ced7d64 100644 --- a/src/Makefile_Elementary.am +++ b/src/Makefile_Elementary.am @@ -799,6 +799,7 @@ bin/elementary/test_diskselector.c \ bin/elementary/test_dnd.c \ bin/elementary/test_efl_anim_alpha.c \ bin/elementary/test_efl_anim_rotate.c \ +bin/elementary/test_efl_anim_scale.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 3fb44c2ce0..9af8fd173f 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -51,6 +51,7 @@ evas_eolian_pub_files = \ lib/evas/canvas/efl_animation_object.eo \ lib/evas/canvas/efl_animation_object_alpha.eo \ lib/evas/canvas/efl_animation_object_rotate.eo \ + lib/evas/canvas/efl_animation_object_scale.eo \ $(NULL) evas_eolian_legacy_files = \ @@ -135,7 +136,8 @@ lib/evas/canvas/efl_animation_rotate_private.h \ lib/evas/canvas/efl_animation_scale_private.h \ lib/evas/canvas/efl_animation_object_private.h \ lib/evas/canvas/efl_animation_object_alpha_private.h \ -lib/evas/canvas/efl_animation_object_rotate_private.h +lib/evas/canvas/efl_animation_object_rotate_private.h \ +lib/evas/canvas/efl_animation_object_scale_private.h # Linebreak @@ -228,6 +230,7 @@ lib/evas/canvas/efl_animation_scale.c \ lib/evas/canvas/efl_animation_object.c \ lib/evas/canvas/efl_animation_object_alpha.c \ lib/evas/canvas/efl_animation_object_rotate.c \ +lib/evas/canvas/efl_animation_object_scale.c \ $(NULL) EXTRA_DIST2 += \ diff --git a/src/bin/elementary/Makefile.am b/src/bin/elementary/Makefile.am index 9eb701ab7f..88c8ebebe3 100644 --- a/src/bin/elementary/Makefile.am +++ b/src/bin/elementary/Makefile.am @@ -34,6 +34,7 @@ test_actionslider.c \ test_anim.c \ test_efl_anim_alpha.c \ test_efl_anim_rotate.c \ +test_efl_anim_scale.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 265044c5e1..b070384901 100644 --- a/src/bin/elementary/test.c +++ b/src/bin/elementary/test.c @@ -326,6 +326,9 @@ void test_efl_anim_alpha(void *data, Evas_Object *obj, void *event_info); void test_efl_anim_rotate(void *data, Evas_Object *obj, void *event_info); void test_efl_anim_rotate_relative(void *data, Evas_Object *obj, void *event_info); void test_efl_anim_rotate_absolute(void *data, Evas_Object *obj, void *event_info); +void test_efl_anim_scale(void *data, Evas_Object *obj, void *event_info); +void test_efl_anim_scale_relative(void *data, Evas_Object *obj, void *event_info); +void test_efl_anim_scale_absolute(void *data, Evas_Object *obj, void *event_info); Evas_Object *win, *tbx; // TODO: refactoring void *tt; @@ -799,6 +802,9 @@ add_tests: ADD_TEST(NULL, "Effects", "Efl Animation Rotate", test_efl_anim_rotate); ADD_TEST(NULL, "Effects", "Efl Animation Rotate Relative", test_efl_anim_rotate_relative); ADD_TEST(NULL, "Effects", "Efl Animation Rotate Absolute", test_efl_anim_rotate_absolute); + ADD_TEST(NULL, "Effects", "Efl Animation Scale", test_efl_anim_scale); + ADD_TEST(NULL, "Effects", "Efl Animation Scale Relative", test_efl_anim_scale_relative); + ADD_TEST(NULL, "Effects", "Efl Animation Scale Absolute", test_efl_anim_scale_absolute); //------------------------------// ADD_TEST(NULL, "Edje External", "ExtButton", test_external_button); diff --git a/src/bin/elementary/test_efl_anim_scale.c b/src/bin/elementary/test_efl_anim_scale.c new file mode 100644 index 0000000000..02ba39c922 --- /dev/null +++ b/src/bin/elementary/test_efl_anim_scale.c @@ -0,0 +1,252 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif +#include + +typedef struct _App_Data +{ + Efl_Animation *scale_double_anim; + Efl_Animation *scale_half_anim; + Efl_Animation_Object *anim_obj; + + Eina_Bool is_btn_scaled; +} 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_scaled = !(ad->is_btn_scaled); + + if (ad->is_btn_scaled) + { + //Create Animation Object from Animation + ad->anim_obj = efl_animation_object_create(ad->scale_double_anim); + elm_object_text_set(obj, "Start Scale Animation to zoom out"); + } + else + { + //Create Animation Object from Animation + ad->anim_obj = efl_animation_object_create(ad->scale_half_anim); + elm_object_text_set(obj, "Start Scale Animation to zoom in"); + } + + //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_scale(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 Scale", ELM_WIN_BASIC); + elm_win_title_set(win, "Efl Animation Scale"); + 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, "Target"); + evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_resize(btn, 150, 150); + evas_object_move(btn, 125, 100); + evas_object_show(btn); + + //Scale Animation to zoom in + Efl_Animation *scale_double_anim = efl_add(EFL_ANIMATION_SCALE_CLASS, NULL); + efl_animation_scale_set(scale_double_anim, 1.0, 1.0, 2.0, 2.0, NULL, 0.5, 0.5); + efl_animation_duration_set(scale_double_anim, 1.0); + efl_animation_target_set(scale_double_anim, btn); + efl_animation_final_state_keep_set(scale_double_anim, EINA_TRUE); + + //Scale Animation to zoom out + Efl_Animation *scale_half_anim = efl_add(EFL_ANIMATION_SCALE_CLASS, NULL); + efl_animation_scale_set(scale_half_anim, 2.0, 2.0, 1.0, 1.0, NULL, 0.5, 0.5); + efl_animation_duration_set(scale_half_anim, 1.0); + efl_animation_target_set(scale_half_anim, btn); + efl_animation_final_state_keep_set(scale_half_anim, EINA_TRUE); + + //Initialize App Data + ad->scale_double_anim = scale_double_anim; + ad->scale_half_anim = scale_half_anim; + ad->anim_obj = NULL; + ad->is_btn_scaled = EINA_FALSE; + + //Button to start animation + Evas_Object *btn2 = elm_button_add(win); + elm_object_text_set(btn2, "Start Scale Animation to zoom in"); + 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, 300, 50); + evas_object_move(btn2, 50, 300); + evas_object_show(btn2); + + evas_object_resize(win, 400, 400); + evas_object_show(win); +} + +void +test_efl_anim_scale_relative(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 Relative Scale", ELM_WIN_BASIC); + elm_win_title_set(win, "Efl Animation Relative Scale"); + 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, "Target"); + evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_resize(btn, 150, 150); + evas_object_move(btn, 125, 100); + evas_object_show(btn); + + //Pivot to be center of the scaling + Evas_Object *pivot = elm_button_add(win); + elm_object_text_set(pivot, "Pivot"); + evas_object_size_hint_weight_set(pivot, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_resize(pivot, 50, 50); + evas_object_move(pivot, 350, 150); + evas_object_show(pivot); + + //Scale Animation to zoom in + Efl_Animation *scale_double_anim = efl_add(EFL_ANIMATION_SCALE_CLASS, NULL); + efl_animation_scale_set(scale_double_anim, 1.0, 1.0, 2.0, 2.0, pivot, 0.5, 0.5); + efl_animation_duration_set(scale_double_anim, 1.0); + efl_animation_target_set(scale_double_anim, btn); + efl_animation_final_state_keep_set(scale_double_anim, EINA_TRUE); + + //Scale Animation to zoom out + Efl_Animation *scale_half_anim = efl_add(EFL_ANIMATION_SCALE_CLASS, NULL); + efl_animation_scale_set(scale_half_anim, 2.0, 2.0, 1.0, 1.0, pivot, 0.5, 0.5); + efl_animation_duration_set(scale_half_anim, 1.0); + efl_animation_target_set(scale_half_anim, btn); + efl_animation_final_state_keep_set(scale_half_anim, EINA_TRUE); + + //Initialize App Data + ad->scale_double_anim = scale_double_anim; + ad->scale_half_anim = scale_half_anim; + ad->anim_obj = NULL; + ad->is_btn_scaled = EINA_FALSE; + + //Button to start animation + Evas_Object *btn2 = elm_button_add(win); + elm_object_text_set(btn2, "Start Scale Animation to zoom in"); + 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, 300, 50); + evas_object_move(btn2, 50, 300); + evas_object_show(btn2); + + evas_object_resize(win, 400, 400); + evas_object_show(win); +} + +void +test_efl_anim_scale_absolute(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 Absolute Scale", ELM_WIN_BASIC); + elm_win_title_set(win, "Efl Animation Absolute Scale"); + 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, "Target"); + evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_resize(btn, 150, 150); + evas_object_move(btn, 125, 100); + evas_object_show(btn); + + //Absolute coordinate (0, 0) to be center of the scaling + Evas_Object *abs_center = elm_button_add(win); + elm_object_text_set(abs_center, "(0, 0)"); + evas_object_size_hint_weight_set(abs_center, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_resize(abs_center, 50, 50); + evas_object_move(abs_center, 0, 0); + evas_object_show(abs_center); + + //Scale Animation to zoom in + Efl_Animation *scale_double_anim = efl_add(EFL_ANIMATION_SCALE_CLASS, NULL); + efl_animation_scale_absolute_set(scale_double_anim, 1.0, 1.0, 2.0, 2.0, 0, 0); + efl_animation_duration_set(scale_double_anim, 1.0); + efl_animation_target_set(scale_double_anim, btn); + efl_animation_final_state_keep_set(scale_double_anim, EINA_TRUE); + + //Scale Animation to zoom out + Efl_Animation *scale_half_anim = efl_add(EFL_ANIMATION_SCALE_CLASS, NULL); + efl_animation_scale_absolute_set(scale_half_anim, 2.0, 2.0, 1.0, 1.0, 0, 0); + efl_animation_duration_set(scale_half_anim, 1.0); + efl_animation_target_set(scale_half_anim, btn); + efl_animation_final_state_keep_set(scale_half_anim, EINA_TRUE); + + //Initialize App Data + ad->scale_double_anim = scale_double_anim; + ad->scale_half_anim = scale_half_anim; + ad->anim_obj = NULL; + ad->is_btn_scaled = EINA_FALSE; + + //Button to start animation + Evas_Object *btn2 = elm_button_add(win); + elm_object_text_set(btn2, "Start Scale Animation to zoom in"); + 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, 300, 50); + evas_object_move(btn2, 50, 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 d12e028145..ddf731727b 100644 --- a/src/lib/evas/Evas_Common.h +++ b/src/lib/evas/Evas_Common.h @@ -3379,6 +3379,13 @@ typedef Eo Efl_Animation_Object_Rotate; #endif +#ifndef _EFL_ANIMATION_OBJECT_SCALE_EO_CLASS_TYPE +#define _EFL_ANIMATION_OBJECT_SCALE_EO_CLASS_TYPE + +typedef Eo Efl_Animation_Object_Scale; + +#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 4a7e5e5399..a923f3aace 100644 --- a/src/lib/evas/Evas_Eo.h +++ b/src/lib/evas/Evas_Eo.h @@ -62,6 +62,7 @@ #include "canvas/efl_animation_object.eo.h" #include "canvas/efl_animation_object_alpha.eo.h" #include "canvas/efl_animation_object_rotate.eo.h" +#include "canvas/efl_animation_object_scale.eo.h" #endif /* EFL_EO_API_SUPPORT */ diff --git a/src/lib/evas/Evas_Internal.h b/src/lib/evas/Evas_Internal.h index 99cb769e9a..75e575e6f8 100644 --- a/src/lib/evas/Evas_Internal.h +++ b/src/lib/evas/Evas_Internal.h @@ -110,6 +110,14 @@ EOAPI void efl_animation_object_rotate_absolute_set(Eo *obj, double from_degree, EOAPI void efl_animation_object_rotate_absolute_get(const Eo *obj, double *from_degree, double *to_degree, int *cx, int *cy); /* Efl.Animation.Object.Rotate END */ +/* Efl.Animation.Object.Scale */ +EOAPI void efl_animation_object_scale_set(Eo *obj, double from_scale_x, double from_scale_y, double to_scale_x, double to_scale_y, Efl_Canvas_Object *pivot, double cx, double cy); +EOAPI void efl_animation_object_scale_get(const Eo *obj, double *from_scale_x, double *from_scale_y, double *to_scale_x, double *to_scale_y, Efl_Canvas_Object **pivot, double *cx, double *cy); + +EOAPI void efl_animation_object_scale_absolute_set(Eo *obj, double from_scale_x, double from_scale_y, double to_scale_x, double to_scale_y, int cx, int cy); +EOAPI void efl_animation_object_scale_absolute_get(const Eo *obj, double *from_scale_x, double *from_scale_y, double *to_scale_x, double *to_scale_y, int *cx, int *cy); +/* Efl.Animation.Object.Scale END */ + #ifdef __cplusplus } #endif diff --git a/src/lib/evas/canvas/efl_animation_object_scale.c b/src/lib/evas/canvas/efl_animation_object_scale.c new file mode 100644 index 0000000000..a84edc7c4c --- /dev/null +++ b/src/lib/evas/canvas/efl_animation_object_scale.c @@ -0,0 +1,282 @@ +#include "efl_animation_object_scale_private.h" + +EOLIAN static void +_efl_animation_object_scale_scale_set(Eo *eo_obj, + Efl_Animation_Object_Scale_Data *pd, + double from_scale_x, + double from_scale_y, + double to_scale_x, + double to_scale_y, + Efl_Canvas_Object *pivot, + double cx, + double cy) +{ + EFL_ANIMATION_OBJECT_SCALE_CHECK_OR_RETURN(eo_obj); + + pd->from.scale_x = from_scale_x; + pd->from.scale_y = from_scale_y; + + pd->to.scale_x = to_scale_x; + pd->to.scale_y = to_scale_y; + + pd->rel_pivot.obj = pivot; + pd->rel_pivot.cx = cx; + pd->rel_pivot.cy = cy; + + //Update absolute pivot based on relative pivot + Evas_Coord x = 0; + Evas_Coord y = 0; + Evas_Coord w = 0; + Evas_Coord h = 0; + + if (pivot) + evas_object_geometry_get(pivot, &x, &y, &w, &h); + else + { + Efl_Canvas_Object *target = efl_animation_object_target_get(eo_obj); + if (target) + evas_object_geometry_get(target, &x, &y, &w, &h); + } + + pd->abs_pivot.cx = x + (w * cx); + pd->abs_pivot.cy = y + (h * cy); + + pd->use_rel_pivot = EINA_TRUE; +} + +EOLIAN static void +_efl_animation_object_scale_scale_get(Eo *eo_obj, + Efl_Animation_Object_Scale_Data *pd, + double *from_scale_x, + double *from_scale_y, + double *to_scale_x, + double *to_scale_y, + Efl_Canvas_Object **pivot, + double *cx, + double *cy) +{ + EFL_ANIMATION_OBJECT_SCALE_CHECK_OR_RETURN(eo_obj); + + //Update relative pivot based on absolute pivot + if (!pd->use_rel_pivot) + { + Evas_Coord x = 0; + Evas_Coord y = 0; + Evas_Coord w = 0; + Evas_Coord h = 0; + + Efl_Canvas_Object *target = efl_animation_object_target_get(eo_obj); + if (target) + evas_object_geometry_get(target, &x, &y, &w, &h); + + if (w != 0) + pd->rel_pivot.cx = (double)(pd->abs_pivot.cx - x) / w; + else + pd->rel_pivot.cx = 0.0; + + if (h != 0) + pd->rel_pivot.cy = (double)(pd->abs_pivot.cy - y) / h; + else + pd->rel_pivot.cy = 0.0; + } + + if (from_scale_x) + *from_scale_x = pd->from.scale_x; + + if (from_scale_y) + *from_scale_y = pd->from.scale_y; + + if (to_scale_x) + *to_scale_x = pd->to.scale_x; + + if (to_scale_y) + *to_scale_y = pd->to.scale_y; + + if (pivot) + *pivot = pd->rel_pivot.obj; + + if (cx) + *cx = pd->rel_pivot.cx; + + if (cy) + *cy = pd->rel_pivot.cy; +} + +EOLIAN static void +_efl_animation_object_scale_scale_absolute_set(Eo *eo_obj, + Efl_Animation_Object_Scale_Data *pd, + double from_scale_x, + double from_scale_y, + double to_scale_x, + double to_scale_y, + Evas_Coord cx, + Evas_Coord cy) +{ + EFL_ANIMATION_OBJECT_SCALE_CHECK_OR_RETURN(eo_obj); + + pd->from.scale_x = from_scale_x; + pd->from.scale_y = from_scale_y; + + pd->to.scale_x = to_scale_x; + pd->to.scale_y = to_scale_y; + + pd->abs_pivot.cx = cx; + pd->abs_pivot.cy = cy; + + //Update relative pivot based on absolute pivot + Evas_Coord x = 0; + Evas_Coord y = 0; + Evas_Coord w = 0; + Evas_Coord h = 0; + + Efl_Canvas_Object *target = efl_animation_object_target_get(eo_obj); + if (target) + evas_object_geometry_get(target, &x, &y, &w, &h); + + pd->rel_pivot.obj = NULL; + + if (w != 0) + pd->rel_pivot.cx = (double)(cx - x) / w; + else + pd->rel_pivot.cx = 0.0; + + if (h != 0) + pd->rel_pivot.cy = (double)(cy - y) / h; + else + pd->rel_pivot.cy = 0.0; + + pd->use_rel_pivot = EINA_FALSE; +} + +EOLIAN static void +_efl_animation_object_scale_scale_absolute_get(Eo *eo_obj, + Efl_Animation_Object_Scale_Data *pd, + double *from_scale_x, + double *from_scale_y, + double *to_scale_x, + double *to_scale_y, + Evas_Coord *cx, + Evas_Coord *cy) +{ + EFL_ANIMATION_OBJECT_SCALE_CHECK_OR_RETURN(eo_obj); + + //Update absolute pivot based on relative pivot + if (pd->use_rel_pivot) + { + Evas_Coord x = 0; + Evas_Coord y = 0; + Evas_Coord w = 0; + Evas_Coord h = 0; + + if (pd->rel_pivot.obj) + evas_object_geometry_get(pd->rel_pivot.obj, &x, &y, &w, &h); + else + { + Efl_Canvas_Object *target + = efl_animation_object_target_get(eo_obj); + if (target) + evas_object_geometry_get(target, &x, &y, &w, &h); + } + + pd->abs_pivot.cx = x + (w * pd->rel_pivot.cx); + pd->abs_pivot.cy = y + (h * pd->rel_pivot.cy); + } + + if (from_scale_x) + *from_scale_x = pd->from.scale_x; + + if (from_scale_y) + *from_scale_y = pd->from.scale_y; + + if (to_scale_x) + *to_scale_x = pd->to.scale_x; + + if (to_scale_y) + *to_scale_y = pd->to.scale_y; + + if (cx) + *cx = pd->abs_pivot.cx; + + if (cy) + *cy = pd->abs_pivot.cy; +} + +static void +_progress_set(Eo *eo_obj, double progress) +{ + EFL_ANIMATION_OBJECT_SCALE_DATA_GET(eo_obj, pd); + + Efl_Canvas_Object *target = efl_animation_object_target_get(eo_obj); + if (!target) return; + + double scale_x = + (pd->from.scale_x * (1.0 - progress)) + (pd->to.scale_x * progress); + + double scale_y = + (pd->from.scale_y * (1.0 - progress)) + (pd->to.scale_y * progress); + + if (pd->use_rel_pivot) + { + efl_gfx_map_zoom(target, + scale_x, scale_y, + pd->rel_pivot.obj, + pd->rel_pivot.cx, pd->rel_pivot.cy); + } + else + { + efl_gfx_map_zoom_absolute(target, + scale_x, scale_y, + pd->abs_pivot.cx, pd->abs_pivot.cy); + } +} + +EOLIAN static void +_efl_animation_object_scale_efl_animation_object_progress_set(Eo *eo_obj, + Efl_Animation_Object_Scale_Data *pd EINA_UNUSED, + double progress) +{ + EFL_ANIMATION_OBJECT_SCALE_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_scale_efl_object_constructor(Eo *eo_obj, + Efl_Animation_Object_Scale_Data *pd) +{ + eo_obj = efl_constructor(efl_super(eo_obj, MY_CLASS)); + + pd->from.scale_x = 1.0; + pd->from.scale_y = 1.0; + + pd->rel_pivot.obj = NULL; + pd->rel_pivot.cx = 0.5; + pd->rel_pivot.cy = 0.5; + + pd->abs_pivot.cx = 0; + pd->abs_pivot.cy = 0; + + pd->use_rel_pivot = EINA_TRUE; + + return eo_obj; +} + +/* Internal EO APIs */ + +EOAPI EFL_VOID_FUNC_BODYV(efl_animation_object_scale_set, EFL_FUNC_CALL(from_scale_x, from_scale_y, to_scale_x, to_scale_y, pivot, cx, cy), double from_scale_x, double from_scale_y, double to_scale_x, double to_scale_y, Efl_Canvas_Object *pivot, double cx, double cy); +EOAPI EFL_VOID_FUNC_BODYV_CONST(efl_animation_object_scale_get, EFL_FUNC_CALL(from_scale_x, from_scale_y, to_scale_x, to_scale_y, pivot, cx, cy), double *from_scale_x, double *from_scale_y, double *to_scale_x, double *to_scale_y, Efl_Canvas_Object **pivot, double *cx, double *cy); + +EOAPI EFL_VOID_FUNC_BODYV(efl_animation_object_scale_absolute_set, EFL_FUNC_CALL(from_scale_x, from_scale_y, to_scale_x, to_scale_y, cx, cy), double from_scale_x, double from_scale_y, double to_scale_x, double to_scale_y, int cx, int cy); +EOAPI EFL_VOID_FUNC_BODYV_CONST(efl_animation_object_scale_absolute_get, EFL_FUNC_CALL(from_scale_x, from_scale_y, to_scale_x, to_scale_y, cx, cy), double *from_scale_x, double *from_scale_y, double *to_scale_x, double *to_scale_y, int *cx, int *cy); + +#define EFL_ANIMATION_OBJECT_SCALE_EXTRA_OPS \ + EFL_OBJECT_OP_FUNC(efl_animation_object_scale_set, _efl_animation_object_scale_scale_set), \ + EFL_OBJECT_OP_FUNC(efl_animation_object_scale_get, _efl_animation_object_scale_scale_get), \ + EFL_OBJECT_OP_FUNC(efl_animation_object_scale_absolute_set, _efl_animation_object_scale_scale_absolute_set), \ + EFL_OBJECT_OP_FUNC(efl_animation_object_scale_absolute_get, _efl_animation_object_scale_scale_absolute_get) + +#include "efl_animation_object_scale.eo.c" diff --git a/src/lib/evas/canvas/efl_animation_object_scale.eo b/src/lib/evas/canvas/efl_animation_object_scale.eo new file mode 100644 index 0000000000..1278fb0988 --- /dev/null +++ b/src/lib/evas/canvas/efl_animation_object_scale.eo @@ -0,0 +1,11 @@ +import efl_animation_types; + +class Efl.Animation.Object.Scale (Efl.Animation.Object) +{ + [[Efl scale animation object class]] + data: Efl_Animation_Object_Scale_Data; + implements { + Efl.Object.constructor; + Efl.Animation.Object.progress_set; + } +} diff --git a/src/lib/evas/canvas/efl_animation_object_scale_private.h b/src/lib/evas/canvas/efl_animation_object_scale_private.h new file mode 100644 index 0000000000..bfdae64bf9 --- /dev/null +++ b/src/lib/evas/canvas/efl_animation_object_scale_private.h @@ -0,0 +1,49 @@ +#define EFL_ANIMATION_OBJECT_PROTECTED +#define EFL_ANIMATION_OBJECT_SCALE_PROTECTED + +#include "evas_common_private.h" + +#define MY_CLASS EFL_ANIMATION_OBJECT_SCALE_CLASS +#define MY_CLASS_NAME efl_class_name_get(MY_CLASS) + +#define EFL_ANIMATION_OBJECT_SCALE_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_SCALE_DATA_GET(o, pd) \ + Efl_Animation_Object_Scale_Data *pd = efl_data_scope_get(o, EFL_ANIMATION_OBJECT_SCALE_CLASS) + +typedef struct _Efl_Animation_Object_Scale_Property +{ + double scale_x, scale_y; +} Efl_Animation_Object_Scale_Property; + +typedef struct _Efl_Animation_Object_Scale_Absolute_Pivot +{ + Evas_Coord cx, cy; +} Efl_Animation_Object_Scale_Absolute_Pivot; + +typedef struct _Efl_Animation_Object_Scale_Relative_Pivot +{ + Efl_Canvas_Object *obj; + double cx, cy; +} Efl_Animation_Object_Scale_Relative_Pivot; + +typedef struct _Efl_Animation_Object_Scale_Data +{ + Efl_Animation_Object_Scale_Property from; + Efl_Animation_Object_Scale_Property to; + + Efl_Animation_Object_Scale_Absolute_Pivot abs_pivot; + Efl_Animation_Object_Scale_Relative_Pivot rel_pivot; + + Eina_Bool use_rel_pivot; +} Efl_Animation_Object_Scale_Data; diff --git a/src/lib/evas/canvas/efl_animation_scale.c b/src/lib/evas/canvas/efl_animation_scale.c index 2b2d41198a..7dfed311c9 100644 --- a/src/lib/evas/canvas/efl_animation_scale.c +++ b/src/lib/evas/canvas/efl_animation_scale.c @@ -200,6 +200,43 @@ _efl_animation_scale_scale_absolute_get(Eo *eo_obj, *cy = pd->abs_pivot.cy; } +EOLIAN static Efl_Animation_Object * +_efl_animation_scale_efl_animation_object_create(Eo *eo_obj, + Efl_Animation_Scale_Data *pd) +{ + EFL_ANIMATION_SCALE_CHECK_OR_RETURN(eo_obj, NULL); + + Efl_Animation_Object_Scale *anim_obj + = efl_add(EFL_ANIMATION_OBJECT_SCALE_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); + + if (pd->use_rel_pivot) + { + efl_animation_object_scale_set(anim_obj, + pd->from.scale_x, pd->from.scale_y, + pd->to.scale_x, pd->to.scale_y, + pd->rel_pivot.obj, + pd->rel_pivot.cx, pd->rel_pivot.cy); + } + else + { + efl_animation_object_scale_absolute_set(anim_obj, + pd->from.scale_x, pd->from.scale_y, + pd->to.scale_x, pd->to.scale_y, + pd->abs_pivot.cx, pd->abs_pivot.cy); + } + + return anim_obj; +} + EOLIAN static Efl_Object * _efl_animation_scale_efl_object_constructor(Eo *eo_obj, Efl_Animation_Scale_Data *pd) diff --git a/src/lib/evas/canvas/efl_animation_scale.eo b/src/lib/evas/canvas/efl_animation_scale.eo index 28eb0e25e9..1bedd18c86 100644 --- a/src/lib/evas/canvas/efl_animation_scale.eo +++ b/src/lib/evas/canvas/efl_animation_scale.eo @@ -37,5 +37,6 @@ class Efl.Animation.Scale (Efl.Animation) } implements { Efl.Object.constructor; + Efl.Animation.object_create; } }