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-18 20:49:28 +0900
commit93947b3a954bb544e12f3f3a18dafe70dfe52b38 (patch)
treeb3acc501d26d5c6e04a9ac9fa602983afc403f4a
parent6db65769458b0b1bf6413144051b94c52887c0e4 (diff)
downloadefl-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.c91
-rw-r--r--src/lib/evas/canvas/efl_animation_instance.eo9
-rw-r--r--src/lib/evas/canvas/efl_animation_instance_group.c15
-rw-r--r--src/lib/evas/canvas/efl_animation_instance_group.eo1
-rw-r--r--src/lib/evas/canvas/efl_animation_instance_private.h5
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;