diff options
author | Jaehyun Cho <jae_hyun.cho@samsung.com> | 2017-08-30 18:17:18 +0900 |
---|---|---|
committer | Jaehyun Cho <jae_hyun.cho@samsung.com> | 2017-09-27 11:22:27 +0900 |
commit | 66277bee12749f8d826f42cce167218f79ad1c8b (patch) | |
tree | 3f4735d257b78ae2d24be5366766a3ad46331596 | |
parent | de9228c9542fb8424f940526923dd0b94c30c7eb (diff) | |
download | efl-66277bee12749f8d826f42cce167218f79ad1c8b.tar.gz |
efl_animation: Add pause and resume methods
Add target_map_reset method to fix flicking issue when animation is
paused and resumed.
-rw-r--r-- | src/lib/evas/canvas/efl_animation_object.c | 89 | ||||
-rw-r--r-- | src/lib/evas/canvas/efl_animation_object.eo | 9 | ||||
-rw-r--r-- | src/lib/evas/canvas/efl_animation_object_group.c | 15 | ||||
-rw-r--r-- | src/lib/evas/canvas/efl_animation_object_group.eo | 1 | ||||
-rw-r--r-- | src/lib/evas/canvas/efl_animation_object_private.h | 5 |
5 files changed, 111 insertions, 8 deletions
diff --git a/src/lib/evas/canvas/efl_animation_object.c b/src/lib/evas/canvas/efl_animation_object.c index 73ff2fa141..8c8a488715 100644 --- a/src/lib/evas/canvas/efl_animation_object.c +++ b/src/lib/evas/canvas/efl_animation_object.c @@ -164,6 +164,18 @@ _efl_animation_object_target_state_reset(Eo *eo_obj, } EOLIAN static void +_efl_animation_object_target_map_reset(Eo *eo_obj, + Efl_Animation_Object_Data *pd) +{ + EFL_ANIMATION_OBJECT_CHECK_OR_RETURN(eo_obj); + + if (!pd->target) return; + + if (efl_gfx_map_has(pd->target)) + efl_gfx_map_reset(pd->target); +} + +EOLIAN static void _efl_animation_object_final_state_keep_set(Eo *eo_obj, Efl_Animation_Object_Data *pd, Eina_Bool keep_final_state) @@ -190,32 +202,48 @@ _animator_cb(void *data) Eo *eo_obj = data; EFL_ANIMATION_OBJECT_DATA_GET(eo_obj, pd); + if (pd->is_paused) + { + pd->animator = NULL; + return ECORE_CALLBACK_CANCEL; + } + if (pd->is_cancelled) goto end; - double elapsed_time, total_duration; + double paused_time = pd->paused_time; + + double total_duration = pd->total_duration; pd->time.current = ecore_loop_time_get(); - elapsed_time = pd->time.current - pd->time.begin; - total_duration = pd->total_duration; - if (elapsed_time > total_duration) - elapsed_time = total_duration; + double elapsed_time = pd->time.current - pd->time.begin; + + if ((elapsed_time - paused_time) > total_duration) + elapsed_time = total_duration + paused_time; if (total_duration < 0.0) goto end; if (total_duration == 0.0) pd->progress = 1.0; else - pd->progress = elapsed_time / total_duration; + pd->progress = (elapsed_time - paused_time) / total_duration; //Reset previous animation effect before applying animation effect - efl_animation_object_target_state_reset(eo_obj); + /* FIXME: When the target state is saved, it may not be finished to calculate + * target geometry. + * In this case, incorrect geometry is saved and the target moves to the + * incorrect position when animation is paused and resumed. + * As a result, flicking issue happens. + * To avoid the flicking issue, reset map only during animation. */ + efl_animation_object_target_map_reset(eo_obj); efl_animation_object_progress_set(eo_obj, pd->progress); //Not end. Keep going. - if (elapsed_time < total_duration) return ECORE_CALLBACK_RENEW; + if ((elapsed_time - paused_time) < total_duration) + return ECORE_CALLBACK_RENEW; end: + pd->is_ended = EINA_TRUE; pd->animator = NULL; //Reset the state of the target to the initial state @@ -236,7 +264,12 @@ _start(Eo *eo_obj, Efl_Animation_Object_Data *pd) //Save the current state of the target efl_animation_object_target_state_save(eo_obj); + pd->is_started = EINA_TRUE; pd->is_cancelled = EINA_FALSE; + pd->is_ended = EINA_FALSE; + pd->is_paused = EINA_FALSE; + + pd->paused_time = 0.0; ecore_animator_del(pd->animator); pd->animator = NULL; @@ -258,6 +291,8 @@ _efl_animation_object_start(Eo *eo_obj, { EFL_ANIMATION_OBJECT_CHECK_OR_RETURN(eo_obj); + if (pd->is_paused) return; + _start(eo_obj, pd); } @@ -268,6 +303,7 @@ _efl_animation_object_cancel(Eo *eo_obj, EFL_ANIMATION_OBJECT_CHECK_OR_RETURN(eo_obj); pd->is_cancelled = EINA_TRUE; + pd->is_ended = EINA_TRUE; if (pd->animator) { @@ -298,6 +334,43 @@ _efl_animation_object_progress_set(Eo *eo_obj, &event_info); } +EOLIAN static void +_efl_animation_object_pause(Eo *eo_obj, + Efl_Animation_Object_Data *pd) +{ + EFL_ANIMATION_OBJECT_CHECK_OR_RETURN(eo_obj); + + if (!pd->is_started) return; + if (pd->is_ended) return; + if (pd->is_paused) return; + + pd->is_paused = EINA_TRUE; + + ecore_animator_del(pd->animator); + pd->animator = NULL; + + pd->time.pause_begin = ecore_loop_time_get(); +} + +EOLIAN static void +_efl_animation_object_resume(Eo *eo_obj, + Efl_Animation_Object_Data *pd) +{ + EFL_ANIMATION_OBJECT_CHECK_OR_RETURN(eo_obj); + + if (!pd->is_started) return; + if (pd->is_ended) return; + if (!pd->is_paused) return; + + pd->is_paused = EINA_FALSE; + + pd->paused_time += (ecore_loop_time_get() - pd->time.pause_begin); + + pd->animator = ecore_animator_add(_animator_cb, eo_obj); + + _animator_cb(eo_obj); +} + EOLIAN static Efl_Object * _efl_animation_object_efl_object_constructor(Eo *eo_obj, Efl_Animation_Object_Data *pd) diff --git a/src/lib/evas/canvas/efl_animation_object.eo b/src/lib/evas/canvas/efl_animation_object.eo index 656940ae69..c798887481 100644 --- a/src/lib/evas/canvas/efl_animation_object.eo +++ b/src/lib/evas/canvas/efl_animation_object.eo @@ -11,6 +11,12 @@ class Efl.Animation.Object (Efl.Object) cancel { [[Cancel animation.]] } + pause { + [[Pause animation.]] + } + resume { + [[Resume animation.]] + } is_deleted @protected { return: bool; [[$true if animation object is deleted, $false otherwise.]] } @@ -20,6 +26,9 @@ class Efl.Animation.Object (Efl.Object) target_state_reset @protected { [[Reset the state of the target to the previously saved state.]] } + target_map_reset @protected { + [[Reset the map effect of the target.]] + } progress_set @protected { [[Display the moment of animation according to the given progress.]] params { diff --git a/src/lib/evas/canvas/efl_animation_object_group.c b/src/lib/evas/canvas/efl_animation_object_group.c index d3799b40ca..df3aca148c 100644 --- a/src/lib/evas/canvas/efl_animation_object_group.c +++ b/src/lib/evas/canvas/efl_animation_object_group.c @@ -169,6 +169,21 @@ _efl_animation_object_group_efl_animation_object_target_state_reset(Eo *eo_obj, } } +EOLIAN static void +_efl_animation_object_group_efl_animation_object_target_map_reset(Eo *eo_obj, + Efl_Animation_Object_Group_Data *pd) +{ + EFL_ANIMATION_OBJECT_GROUP_CHECK_OR_RETURN(eo_obj); + + Eina_List *l; + Efl_Animation_Object *anim_obj; + + EINA_LIST_FOREACH(pd->anim_objs, l, anim_obj) + { + efl_animation_object_target_map_reset(anim_obj); + } +} + /* Internal EO APIs */ EOAPI EFL_VOID_FUNC_BODYV(efl_animation_object_group_object_add, EFL_FUNC_CALL(anim_obj), Efl_Animation_Object *anim_obj); diff --git a/src/lib/evas/canvas/efl_animation_object_group.eo b/src/lib/evas/canvas/efl_animation_object_group.eo index cdde1ec78b..0ac0787294 100644 --- a/src/lib/evas/canvas/efl_animation_object_group.eo +++ b/src/lib/evas/canvas/efl_animation_object_group.eo @@ -9,5 +9,6 @@ abstract Efl.Animation.Object.Group (Efl.Animation.Object) Efl.Object.destructor; Efl.Animation.Object.target_state_save; Efl.Animation.Object.target_state_reset; + Efl.Animation.Object.target_map_reset; } } diff --git a/src/lib/evas/canvas/efl_animation_object_private.h b/src/lib/evas/canvas/efl_animation_object_private.h index 7b45dafe59..df05bf622c 100644 --- a/src/lib/evas/canvas/efl_animation_object_private.h +++ b/src/lib/evas/canvas/efl_animation_object_private.h @@ -22,6 +22,7 @@ typedef struct _Efl_Animation_Object_Data struct { double begin; double current; + double pause_begin; } time; Efl_Canvas_Object *target; @@ -31,9 +32,13 @@ typedef struct _Efl_Animation_Object_Data double duration; double total_duration; + double paused_time; Eina_Bool is_deleted : 1; + Eina_Bool is_started : 1; Eina_Bool is_cancelled : 1; + Eina_Bool is_ended : 1; + Eina_Bool is_paused : 1; Eina_Bool keep_final_state : 1; } Efl_Animation_Object_Data; |