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-18 20:49:28 +0900 |
commit | 93947b3a954bb544e12f3f3a18dafe70dfe52b38 (patch) | |
tree | b3acc501d26d5c6e04a9ac9fa602983afc403f4a | |
parent | 6db65769458b0b1bf6413144051b94c52887c0e4 (diff) | |
download | efl-93947b3a954bb544e12f3f3a18dafe70dfe52b38.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_instance.c | 91 | ||||
-rw-r--r-- | src/lib/evas/canvas/efl_animation_instance.eo | 9 | ||||
-rw-r--r-- | src/lib/evas/canvas/efl_animation_instance_group.c | 15 | ||||
-rw-r--r-- | src/lib/evas/canvas/efl_animation_instance_group.eo | 1 | ||||
-rw-r--r-- | src/lib/evas/canvas/efl_animation_instance_private.h | 5 |
5 files changed, 112 insertions, 9 deletions
diff --git a/src/lib/evas/canvas/efl_animation_instance.c b/src/lib/evas/canvas/efl_animation_instance.c index ec07d95674..ca3df33cdd 100644 --- a/src/lib/evas/canvas/efl_animation_instance.c +++ b/src/lib/evas/canvas/efl_animation_instance.c @@ -152,6 +152,18 @@ _efl_animation_instance_target_state_reset(Eo *eo_obj, } EOLIAN static void +_efl_animation_instance_target_map_reset(Eo *eo_obj, + Efl_Animation_Instance_Data *pd) +{ + EFL_ANIMATION_INSTANCE_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_instance_final_state_keep_set(Eo *eo_obj, Efl_Animation_Instance_Data *pd, Eina_Bool keep_final_state) @@ -178,28 +190,42 @@ _animator_cb(void *data) Eo *eo_obj = data; EFL_ANIMATION_INSTANCE_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; Efl_Animation_Instance_Animate_Event_Info event_info; event_info.progress = pd->progress; //Reset previous animation effect before applying animation effect - efl_animation_instance_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_instance_target_map_reset(eo_obj); efl_animation_instance_progress_set(eo_obj, pd->progress); @@ -208,10 +234,12 @@ _animator_cb(void *data) &event_info); efl_event_callback_call(eo_obj, EFL_ANIMATION_INSTANCE_EVENT_ANIMATE, &event_info); - //Not end. Keep going. - if (elapsed_time < total_duration) return ECORE_CALLBACK_RENEW; + //Not end. Keep going. + 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 @@ -232,7 +260,12 @@ _start(Eo *eo_obj, Efl_Animation_Instance_Data *pd) //Save the current state of the target efl_animation_instance_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; @@ -254,6 +287,8 @@ _efl_animation_instance_start(Eo *eo_obj, { EFL_ANIMATION_INSTANCE_CHECK_OR_RETURN(eo_obj); + if (pd->is_paused) return; + _start(eo_obj, pd); } @@ -264,6 +299,7 @@ _efl_animation_instance_cancel(Eo *eo_obj, EFL_ANIMATION_INSTANCE_CHECK_OR_RETURN(eo_obj); pd->is_cancelled = EINA_TRUE; + pd->is_ended = EINA_TRUE; if (pd->animator) { @@ -278,6 +314,43 @@ _efl_animation_instance_cancel(Eo *eo_obj, } } +EOLIAN static void +_efl_animation_instance_pause(Eo *eo_obj, + Efl_Animation_Instance_Data *pd) +{ + EFL_ANIMATION_INSTANCE_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_instance_resume(Eo *eo_obj, + Efl_Animation_Instance_Data *pd) +{ + EFL_ANIMATION_INSTANCE_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_instance_efl_object_constructor(Eo *eo_obj, Efl_Animation_Instance_Data *pd) diff --git a/src/lib/evas/canvas/efl_animation_instance.eo b/src/lib/evas/canvas/efl_animation_instance.eo index e83e74d8f9..1a758fcf7e 100644 --- a/src/lib/evas/canvas/efl_animation_instance.eo +++ b/src/lib/evas/canvas/efl_animation_instance.eo @@ -11,6 +11,12 @@ abstract Efl.Animation.Instance (Efl.Object) cancel { [[Cancel animation.]] } + pause { + [[Pause animation.]] + } + resume { + [[Resume animation.]] + } is_deleted @protected { return: bool; [[$true if animation instance is deleted, $false otherwise.]] } @@ -20,6 +26,9 @@ abstract Efl.Animation.Instance (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_instance_group.c b/src/lib/evas/canvas/efl_animation_instance_group.c index dbf2b57112..cd27eb096d 100644 --- a/src/lib/evas/canvas/efl_animation_instance_group.c +++ b/src/lib/evas/canvas/efl_animation_instance_group.c @@ -168,6 +168,21 @@ _efl_animation_instance_group_efl_animation_instance_target_state_reset(Eo *eo_o } } +EOLIAN static void +_efl_animation_instance_group_efl_animation_instance_target_map_reset(Eo *eo_obj, + Efl_Animation_Instance_Group_Data *pd) +{ + EFL_ANIMATION_INSTANCE_GROUP_CHECK_OR_RETURN(eo_obj); + + Eina_List *l; + Efl_Animation_Instance *inst; + + EINA_LIST_FOREACH(pd->instances, l, inst) + { + efl_animation_instance_target_map_reset(inst); + } +} + /* Internal EO APIs */ EOAPI EFL_VOID_FUNC_BODYV(efl_animation_instance_group_instance_add, EFL_FUNC_CALL(animation), Efl_Animation_Instance *animation); diff --git a/src/lib/evas/canvas/efl_animation_instance_group.eo b/src/lib/evas/canvas/efl_animation_instance_group.eo index 4c702be5ab..4c6d4c8e38 100644 --- a/src/lib/evas/canvas/efl_animation_instance_group.eo +++ b/src/lib/evas/canvas/efl_animation_instance_group.eo @@ -9,5 +9,6 @@ abstract Efl.Animation.Instance.Group (Efl.Animation.Instance) Efl.Object.destructor; Efl.Animation.Instance.target_state_save; Efl.Animation.Instance.target_state_reset; + Efl.Animation.Instance.target_map_reset; } } diff --git a/src/lib/evas/canvas/efl_animation_instance_private.h b/src/lib/evas/canvas/efl_animation_instance_private.h index f0f726e27b..f2877c9d4f 100644 --- a/src/lib/evas/canvas/efl_animation_instance_private.h +++ b/src/lib/evas/canvas/efl_animation_instance_private.h @@ -23,6 +23,7 @@ typedef struct _Efl_Animation_Instance_Data { double begin; double current; + double pause_begin; } time; Efl_Canvas_Object *target; @@ -32,9 +33,13 @@ typedef struct _Efl_Animation_Instance_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_Instance_Data; |