summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaehyun Cho <jae_hyun.cho@samsung.com>2017-08-30 18:17:18 +0900
committerJaehyun Cho <jae_hyun.cho@samsung.com>2017-09-27 11:22:27 +0900
commit66277bee12749f8d826f42cce167218f79ad1c8b (patch)
tree3f4735d257b78ae2d24be5366766a3ad46331596
parentde9228c9542fb8424f940526923dd0b94c30c7eb (diff)
downloadefl-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.c89
-rw-r--r--src/lib/evas/canvas/efl_animation_object.eo9
-rw-r--r--src/lib/evas/canvas/efl_animation_object_group.c15
-rw-r--r--src/lib/evas/canvas/efl_animation_object_group.eo1
-rw-r--r--src/lib/evas/canvas/efl_animation_object_private.h5
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;