summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaehyun Cho <jae_hyun.cho@samsung.com>2017-04-25 14:34:28 +0900
committerJaehyun Cho <jae_hyun.cho@samsung.com>2017-06-30 17:28:34 +0900
commitb361f082991ed0bb141f5c0c48c40a347c47a1e8 (patch)
treec4581211811c97720fb0dcc8a71272ce3eb8a030
parentbc754f2d965954d2c4d1a8f9a6174c67c5d2182b (diff)
downloadefl-b361f082991ed0bb141f5c0c48c40a347c47a1e8.tar.gz
efl_animation: Implement animation function
-rw-r--r--src/lib/evas/Evas_Common.h5
-rw-r--r--src/lib/evas/canvas/efl_animation.c133
-rw-r--r--src/lib/evas/canvas/efl_animation.eo8
-rw-r--r--src/lib/evas/canvas/efl_animation_alpha.c8
-rw-r--r--src/lib/evas/canvas/efl_animation_rotate.c8
-rw-r--r--src/lib/evas/canvas/efl_animation_scale.c8
-rw-r--r--src/lib/evas/canvas/efl_animation_translate.c8
-rw-r--r--src/lib/evas/canvas/efl_animation_types.eot11
-rw-r--r--src/lib/evas/canvas/evas_object_main.c174
9 files changed, 344 insertions, 19 deletions
diff --git a/src/lib/evas/Evas_Common.h b/src/lib/evas/Evas_Common.h
index 090992646b..2c2e24ebb0 100644
--- a/src/lib/evas/Evas_Common.h
+++ b/src/lib/evas/Evas_Common.h
@@ -3329,6 +3329,11 @@ EAPI const Eina_List *evas_font_path_global_list(void) EINA_WARN_UNUSED_R
*/
EAPI void evas_font_reinit(void);
+struct _Efl_Animation_Animate_Event_Info
+{
+ double progress;
+};
+
/**
* @}
*/
diff --git a/src/lib/evas/canvas/efl_animation.c b/src/lib/evas/canvas/efl_animation.c
index 408774ddf3..e1c8dfaaed 100644
--- a/src/lib/evas/canvas/efl_animation.c
+++ b/src/lib/evas/canvas/efl_animation.c
@@ -2,6 +2,7 @@
#include "evas_common_private.h"
#include "evas_private.h"
+#include <Ecore.h>
#define MY_CLASS EFL_ANIMATION_CLASS
#define MY_CLASS_NAME efl_class_name_get(MY_CLASS)
@@ -18,6 +19,9 @@
} \
} while (0)
+#define EFL_ANIMATION_DATA_GET(o, pd) \
+ Evas_Object_Animation_Data *pd = efl_data_scope_get(o, EFL_ANIMATION_CLASS)
+
struct _Evas_Object_Animation_Data
{
/*
@@ -30,18 +34,43 @@ struct _Evas_Object_Animation_Data
* int current_loop; //Default value is 1
* Eina_Bool is_reverse;
*/
+ Ecore_Animator *animator;
+
+ struct
+ {
+ double begin;
+ double current;
+ } time;
+
Eo *target;
+ double progress;
double duration;
Eina_Bool deleted : 1;
+ Eina_Bool cancelled : 1;
+ Eina_Bool ended : 1;
};
+static void
+_target_del_cb(void *data, const Efl_Event *event EINA_UNUSED)
+{
+ Eo *eo_obj = data;
+
+ EFL_ANIMATION_CHECK_OR_RETURN(eo_obj);
+ EFL_ANIMATION_DATA_GET(eo_obj, pd);
+
+ pd->target = NULL;
+ efl_animation_cancel(eo_obj);
+}
+
EOLIAN static void
_efl_animation_target_set(Eo *eo_obj, Evas_Object_Animation_Data *pd, Evas_Object *target)
{
EFL_ANIMATION_CHECK_OR_RETURN(eo_obj);
+ efl_event_callback_add(target, EFL_EVENT_DEL, _target_del_cb, eo_obj);
+
pd->target = target;
}
@@ -80,38 +109,134 @@ _efl_animation_is_deleted(Eo *eo_obj, Evas_Object_Animation_Data *pd)
return pd->deleted;
}
+static Eina_Bool
+_animator_cb(void *data)
+{
+ Eo *eo_obj = data;
+ EFL_ANIMATION_DATA_GET(eo_obj, pd);
+
+ if (pd->cancelled) goto end;
+
+ double elapsed_time, duration;
+
+ pd->time.current = ecore_loop_time_get();
+ elapsed_time = pd->time.current - pd->time.begin;
+ duration = pd->duration;
+ if (elapsed_time > duration)
+ elapsed_time = duration;
+
+ if (duration <= 0.0) goto end;
+
+ pd->progress = elapsed_time / duration;
+
+ Efl_Animation_Animate_Event_Info event_info;
+ event_info.progress = pd->progress;
+
+ efl_event_callback_call(eo_obj, EFL_ANIMATION_EVENT_ANIMATE, &event_info);
+
+ /* Not end. Keep going. */
+ if (elapsed_time < duration) return ECORE_CALLBACK_RENEW;
+
+end:
+ pd->ended = EINA_TRUE;
+ pd->animator = NULL;
+
+ efl_event_callback_call(eo_obj, EFL_ANIMATION_EVENT_END, NULL);
+
+ //FIXME: Delete animation here
+ return ECORE_CALLBACK_CANCEL;
+}
+
EOLIAN static Eina_Bool
-_efl_animation_start(Eo *eo_obj, Evas_Object_Animation_Data *pd EINA_UNUSED)
+_efl_animation_start(Eo *eo_obj, Evas_Object_Animation_Data *pd)
{
EFL_ANIMATION_CHECK_OR_RETURN(eo_obj, EINA_FALSE);
+ if (pd->duration <= 0.0)
+ return EINA_FALSE;
+
+ pd->cancelled = EINA_FALSE;
+ pd->ended = EINA_FALSE;
+
+ ecore_animator_del(pd->animator);
+ pd->animator = NULL;
+
+ pd->time.begin = ecore_loop_time_get();
+ pd->animator = ecore_animator_add(_animator_cb, eo_obj);
+
+ _animator_cb(eo_obj);
+
return EINA_TRUE;
}
EOLIAN static Eina_Bool
-_efl_animation_cancel(Eo *eo_obj, Evas_Object_Animation_Data *pd EINA_UNUSED)
+_efl_animation_cancel(Eo *eo_obj, Evas_Object_Animation_Data *pd)
{
EFL_ANIMATION_CHECK_OR_RETURN(eo_obj, EINA_FALSE);
+ pd->cancelled = EINA_TRUE;
+
+ if (pd->animator)
+ {
+ pd->ended = EINA_TRUE;
+
+ ecore_animator_del(pd->animator);
+ pd->animator = NULL;
+
+ efl_event_callback_call(eo_obj, EFL_ANIMATION_EVENT_END, NULL);
+ }
+
return EINA_TRUE;
}
+EOLIAN static Efl_Animation_State
+_efl_animation_state_get(Eo *eo_obj, Evas_Object_Animation_Data *pd)
+{
+ EFL_ANIMATION_CHECK_OR_RETURN(eo_obj, EFL_ANIMATION_STATE_DELETED);
+
+ if (pd->animator)
+ return EFL_ANIMATION_STATE_RUNNING;
+ else
+ return EFL_ANIMATION_STATE_STOPPED;
+}
+
EOLIAN static Efl_Object *
_efl_animation_efl_object_constructor(Eo *eo_obj, Evas_Object_Animation_Data *pd)
{
eo_obj = efl_constructor(efl_super(eo_obj, MY_CLASS));
- pd->duration = 0.0;
+ pd->time.begin = 0.0;
+ pd->time.current = 0.0;
+
pd->target = NULL;
+ pd->progress = 0.0;
+ pd->duration = 0.0;
+
pd->deleted = EINA_FALSE;
+ pd->cancelled = EINA_FALSE;
+ pd->ended = EINA_FALSE;
return eo_obj;
}
EOLIAN static void
-_efl_animation_efl_object_destructor(Eo *eo_obj, Evas_Object_Animation_Data *pd EINA_UNUSED)
+_efl_animation_efl_object_destructor(Eo *eo_obj, Evas_Object_Animation_Data *pd)
{
+ pd->deleted = EINA_TRUE;
+
+ if (pd->animator)
+ {
+ ecore_animator_del(pd->animator);
+ pd->animator = NULL;
+ pd->ended = EINA_TRUE;
+
+ efl_event_callback_call(eo_obj, EFL_ANIMATION_EVENT_END, NULL);
+ }
+
+ if (pd->target)
+ efl_event_callback_del(pd->target, EFL_EVENT_DEL, _target_del_cb, eo_obj);
+
efl_destructor(efl_super(eo_obj, MY_CLASS));
}
diff --git a/src/lib/evas/canvas/efl_animation.eo b/src/lib/evas/canvas/efl_animation.eo
index 27e349193a..e80d93ecf0 100644
--- a/src/lib/evas/canvas/efl_animation.eo
+++ b/src/lib/evas/canvas/efl_animation.eo
@@ -36,9 +36,17 @@ abstract Efl.Animation (Efl.Object)
[[Cancel animation.]]
return: bool; [[$true on success, $false otherwise]]
}
+ state_get {
+ [[Get the state of animation]]
+ return: Efl.Animation.State; [[Animation state]]
+ }
}
implements {
Efl.Object.constructor;
Efl.Object.destructor;
}
+ events {
+ animate; [[Animation is animated.]]
+ end; [[Animation ended]]
+ }
}
diff --git a/src/lib/evas/canvas/efl_animation_alpha.c b/src/lib/evas/canvas/efl_animation_alpha.c
index 8ddafd5361..a490c35648 100644
--- a/src/lib/evas/canvas/efl_animation_alpha.c
+++ b/src/lib/evas/canvas/efl_animation_alpha.c
@@ -49,6 +49,12 @@ _efl_animation_alpha_alpha_get(Eo *eo_obj EINA_UNUSED, Evas_Object_Animation_Alp
*to_alpha = pd->to.alpha;
}
+static void
+_animate_cb(void *data, const Efl_Event *event)
+{
+ Efl_Animation_Animate_Event_Info *event_info = event->info;
+}
+
EOLIAN static Efl_Object *
_efl_animation_alpha_efl_object_constructor(Eo *eo_obj, Evas_Object_Animation_Alpha_Data *pd)
{
@@ -57,6 +63,8 @@ _efl_animation_alpha_efl_object_constructor(Eo *eo_obj, Evas_Object_Animation_Al
pd->from.alpha = 1.0;
pd->to.alpha = 1.0;
+ efl_event_callback_add(eo_obj, EFL_ANIMATION_EVENT_ANIMATE, _animate_cb, NULL);
+
return eo_obj;
}
diff --git a/src/lib/evas/canvas/efl_animation_rotate.c b/src/lib/evas/canvas/efl_animation_rotate.c
index da6e9961e1..4dd0ab0e54 100644
--- a/src/lib/evas/canvas/efl_animation_rotate.c
+++ b/src/lib/evas/canvas/efl_animation_rotate.c
@@ -119,6 +119,12 @@ _efl_animation_rotate_absolute_pivot_get(Eo *eo_obj, Evas_Object_Animation_Rotat
*pivot_z = pd->abs_pivot.z;
}
+static void
+_animate_cb(void *data, const Efl_Event *event)
+{
+ Efl_Animation_Animate_Event_Info *event_info = event->info;
+}
+
EOLIAN static Efl_Object *
_efl_animation_rotate_efl_object_constructor(Eo *eo_obj, Evas_Object_Animation_Rotate_Data *pd)
{
@@ -137,6 +143,8 @@ _efl_animation_rotate_efl_object_constructor(Eo *eo_obj, Evas_Object_Animation_R
pd->use_rel_pivot = EINA_TRUE;
+ efl_event_callback_add(eo_obj, EFL_ANIMATION_EVENT_ANIMATE, _animate_cb, NULL);
+
return eo_obj;
}
diff --git a/src/lib/evas/canvas/efl_animation_scale.c b/src/lib/evas/canvas/efl_animation_scale.c
index 74f8de84b0..3fe0d3b4d9 100644
--- a/src/lib/evas/canvas/efl_animation_scale.c
+++ b/src/lib/evas/canvas/efl_animation_scale.c
@@ -121,6 +121,12 @@ _efl_animation_scale_scale_z_get(Eo *eo_obj, Evas_Object_Animation_Scale_Data *p
*to_z = pd->to.scale_z;
}
+static void
+_animate_cb(void *data, const Efl_Event *event)
+{
+ Efl_Animation_Animate_Event_Info *event_info = event->info;
+}
+
EOLIAN static Efl_Object *
_efl_animation_scale_efl_object_constructor(Eo *eo_obj, Evas_Object_Animation_Scale_Data *pd)
{
@@ -130,6 +136,8 @@ _efl_animation_scale_efl_object_constructor(Eo *eo_obj, Evas_Object_Animation_Sc
pd->from.scale_y = 1.0;
pd->from.scale_z = 1.0;
+ efl_event_callback_add(eo_obj, EFL_ANIMATION_EVENT_ANIMATE, _animate_cb, NULL);
+
return eo_obj;
}
diff --git a/src/lib/evas/canvas/efl_animation_translate.c b/src/lib/evas/canvas/efl_animation_translate.c
index 84bad4dfb9..5b09effb45 100644
--- a/src/lib/evas/canvas/efl_animation_translate.c
+++ b/src/lib/evas/canvas/efl_animation_translate.c
@@ -230,6 +230,12 @@ _efl_animation_translate_coordinate_z_get(Eo *eo_obj, Evas_Object_Animation_Tran
*to_z = pd->to.z;
}
+static void
+_animate_cb(void *data, const Efl_Event *event)
+{
+ Efl_Animation_Animate_Event_Info *event_info = event->info;
+}
+
EOLIAN static Efl_Object *
_efl_animation_translate_efl_object_constructor(Eo *eo_obj, Evas_Object_Animation_Translate_Data *pd)
{
@@ -251,6 +257,8 @@ _efl_animation_translate_efl_object_constructor(Eo *eo_obj, Evas_Object_Animatio
pd->to.y = 0;
pd->to.z = 0;
+ efl_event_callback_add(eo_obj, EFL_ANIMATION_EVENT_ANIMATE, _animate_cb, NULL);
+
return eo_obj;
}
diff --git a/src/lib/evas/canvas/efl_animation_types.eot b/src/lib/evas/canvas/efl_animation_types.eot
index fed4c64e5f..6415e8cbaa 100644
--- a/src/lib/evas/canvas/efl_animation_types.eot
+++ b/src/lib/evas/canvas/efl_animation_types.eot
@@ -10,3 +10,14 @@ enum Efl.Animation.Event_Type
clicked, [["clicked" event type]]
count [[total count of event type]]
}
+
+enum Efl.Animation.State
+{
+ [[Animation state]]
+
+ running = 0, [[running state]]
+ stopped, [[stopped state]]
+ deleted [[deleted state]]
+}
+
+struct Efl.Animation.Animate_Event_Info; [[Information of animate event]]
diff --git a/src/lib/evas/canvas/evas_object_main.c b/src/lib/evas/canvas/evas_object_main.c
index 76eb2b71eb..ef635fb84f 100644
--- a/src/lib/evas/canvas/evas_object_main.c
+++ b/src/lib/evas/canvas/evas_object_main.c
@@ -51,6 +51,12 @@ typedef struct _Event_Animation
Efl_Animation *anim;
} Event_Animation;
+typedef struct _Hide_Anim_Data
+{
+ Eina_Bool anim_started;
+ Eina_Bool anim_ended;
+} Hide_Anim_Data;
+
static Eina_Bool
_init_cow(void)
{
@@ -1062,6 +1068,20 @@ _efl_animation_event_type_get(const char *event_str)
return -1;
}
+static void
+_all_animations_cancel(Eo *eo_obj)
+{
+ Efl_Animation_Event_Type event_type;
+ for (event_type = EFL_ANIMATION_EVENT_TYPE_SHOW;
+ event_type < EFL_ANIMATION_EVENT_TYPE_COUNT; event_type++)
+ {
+ Efl_Animation *anim = efl_canvas_object_event_animation_get(eo_obj,
+ event_type);
+ if (anim)
+ efl_animation_cancel(anim);
+ }
+}
+
EOLIAN static Eina_Bool
_efl_canvas_object_efl_object_event_callback_call(Eo *eo_obj,
Evas_Object_Protected_Data *obj EINA_UNUSED,
@@ -1080,7 +1100,10 @@ _efl_canvas_object_efl_object_event_callback_call(Eo *eo_obj,
Efl_Animation *anim =
efl_canvas_object_event_animation_get(eo_obj, event_type);
if (anim)
- efl_animation_start(anim);
+ {
+ _all_animations_cancel(eo_obj);
+ efl_animation_start(anim);
+ }
}
}
@@ -1106,7 +1129,10 @@ _efl_canvas_object_efl_object_event_callback_legacy_call(Eo *eo_obj,
Efl_Animation *anim =
efl_canvas_object_event_animation_get(eo_obj, event_type);
if (anim)
- efl_animation_start(anim);
+ {
+ _all_animations_cancel(eo_obj);
+ efl_animation_start(anim);
+ }
}
}
@@ -1129,6 +1155,15 @@ _efl_canvas_object_efl_object_destructor(Eo *eo_obj, Evas_Object_Protected_Data
int event_id;
edata = efl_data_scope_get(evas_object_evas_get(eo_obj), EVAS_CANVAS_CLASS);
+
+ //Unset event animations
+ efl_canvas_object_event_animation_set(eo_obj, EFL_ANIMATION_EVENT_TYPE_SHOW,
+ NULL);
+ efl_canvas_object_event_animation_set(eo_obj, EFL_ANIMATION_EVENT_TYPE_HIDE,
+ NULL);
+ efl_canvas_object_event_animation_set(eo_obj,
+ EFL_ANIMATION_EVENT_TYPE_CLICKED,
+ NULL);
evas_object_hide(eo_obj);
if (obj->events) EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
@@ -1772,6 +1807,41 @@ evas_object_hide(Evas_Object *eo_obj)
efl_gfx_visible_set(eo_obj, EINA_FALSE);
}
+static void _animation_intercept_hide(void *data, Evas_Object *eo_obj);
+
+static void
+_animation_hide_end_cb(void *data, const Efl_Event *event)
+{
+ Hide_Anim_Data *hide_anim_data = data;
+
+ hide_anim_data->anim_ended = EINA_TRUE;
+
+ Eo *eo_obj = efl_animation_target_get(event->object);
+ _animation_intercept_hide(hide_anim_data, eo_obj);
+
+ hide_anim_data->anim_started = EINA_FALSE;
+ hide_anim_data->anim_ended = EINA_FALSE;
+}
+
+static void
+_animation_intercept_hide(void *data, Evas_Object *eo_obj)
+{
+ Hide_Anim_Data *hide_anim_data = data;
+
+ Efl_Animation *anim =
+ efl_canvas_object_event_animation_get(eo_obj,
+ EFL_ANIMATION_EVENT_TYPE_HIDE);
+ if (anim && !hide_anim_data->anim_started && !hide_anim_data->anim_ended)
+ {
+ hide_anim_data->anim_started = EINA_TRUE;
+
+ _all_animations_cancel(eo_obj);
+ efl_animation_start(anim);
+ }
+ else
+ efl_gfx_visible_set(eo_obj, EINA_FALSE);
+}
+
EAPI Eina_Bool
evas_object_visible_get(const Evas_Object *obj)
{
@@ -1818,18 +1888,15 @@ _show(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
efl_canvas_object_event_animation_get(eo_obj,
EFL_ANIMATION_EVENT_TYPE_SHOW);
if (anim)
- efl_animation_start(anim);
+ {
+ _all_animations_cancel(eo_obj);
+ efl_animation_start(anim);
+ }
}
static void
_hide(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
{
- Efl_Animation *anim =
- efl_canvas_object_event_animation_get(eo_obj,
- EFL_ANIMATION_EVENT_TYPE_HIDE);
- if (anim)
- efl_animation_start(anim);
-
if (obj->is_smart && obj->smart.smart && obj->smart.smart->smart_class->hide)
{
obj->smart.smart->smart_class->hide(eo_obj);
@@ -2755,8 +2822,23 @@ _efl_animation_event_type_is_valid(Efl_Animation_Event_Type event)
return EINA_TRUE;
}
+static void
+_anim_del_cb(void *data, const Efl_Event *event)
+{
+ Eo *eo_obj = data;
+ Efl_Animation *anim = event->object;
+ Efl_Animation_Event_Type event_type;
+
+ for (event_type = EFL_ANIMATION_EVENT_TYPE_SHOW;
+ event_type < EFL_ANIMATION_EVENT_TYPE_COUNT; event_type++)
+ {
+ if (anim == efl_canvas_object_event_animation_get(eo_obj, event_type))
+ efl_canvas_object_event_animation_set(eo_obj, event_type, NULL);
+ }
+}
+
EOLIAN void
-_efl_canvas_object_event_animation_set(Eo *eo_obj EINA_UNUSED,
+_efl_canvas_object_event_animation_set(Eo *eo_obj,
Evas_Object_Protected_Data *pd,
Efl_Animation_Event_Type event_type,
Efl_Animation *animation)
@@ -2765,13 +2847,75 @@ _efl_canvas_object_event_animation_set(Eo *eo_obj EINA_UNUSED,
return;
Event_Animation *event_anim = eina_array_data_get(pd->event_anims, event_type);
- if (event_anim && event_anim->anim)
+ if (!event_anim) return;
+
+ Efl_Animation *cur_anim = event_anim->anim;
+ Efl_Animation *new_anim = animation;
+
+ //Unset for current event animation
+ if (cur_anim)
+ {
+ Eo *prev_target =
+ efl_animation_target_get(cur_anim);
+
+ //Deallocate memory and Unset callbacks for Hide event
+ if (event_type == EFL_ANIMATION_EVENT_TYPE_HIDE)
+ {
+ Hide_Anim_Data *hide_anim_data
+ = evas_object_intercept_hide_callback_del(prev_target,
+ _animation_intercept_hide);
+ if (hide_anim_data)
+ {
+ efl_event_callback_del(cur_anim, EFL_ANIMATION_EVENT_END,
+ _animation_hide_end_cb,
+ hide_anim_data);
+
+ if (hide_anim_data->anim_started &&
+ !hide_anim_data->anim_ended)
+ efl_gfx_visible_set(prev_target, EINA_FALSE);
+
+ free(hide_anim_data);
+ }
+ }
+
+ //Unset callback
+ efl_event_callback_del(cur_anim, EFL_EVENT_DEL,
+ _anim_del_cb, prev_target);
+
+ //Stop animation
+ efl_animation_cancel(cur_anim);
+ }
+
+ //Replace current event animation with new event animation
+ event_anim->anim = new_anim;
+
+ //Set for new event animation
+ if (new_anim)
{
- //Stop current animation
- efl_animation_cancel(event_anim->anim);
+ //Set target object for the given animation
+ Eo *target = efl_animation_target_get(new_anim);
+ if (!target)
+ target = eo_obj;
+ efl_animation_target_set(new_anim, target);
+
+ //Allocate memory and Set callbacks for Hide event
+ if (event_type == EFL_ANIMATION_EVENT_TYPE_HIDE)
+ {
+ Hide_Anim_Data *hide_anim_data = calloc(1, sizeof(Hide_Anim_Data));
+ hide_anim_data->anim_started = EINA_FALSE;
+ hide_anim_data->anim_ended = EINA_FALSE;
+
+ evas_object_intercept_hide_callback_add(target,
+ _animation_intercept_hide,
+ hide_anim_data);
+
+ efl_event_callback_add(new_anim, EFL_ANIMATION_EVENT_END,
+ _animation_hide_end_cb,
+ hide_anim_data);
+ }
- //Set new animation
- event_anim->anim = animation;
+ //Set callback
+ efl_event_callback_add(new_anim, EFL_EVENT_DEL, _anim_del_cb, target);
}
}