From 6ffe76186b18ea551cb8c53e6808810ed6841b6e Mon Sep 17 00:00:00 2001 From: Jaehyun Cho Date: Fri, 18 Aug 2017 12:02:33 +0900 Subject: efl_animation: Implement reverse_initial_state_set for repeat_mode --- src/lib/evas/Evas_Internal.h | 1 + src/lib/evas/canvas/efl_animation_instance.c | 12 +++ .../canvas/efl_animation_instance_group_parallel.c | 84 +++++++++++++------- .../efl_animation_instance_group_sequential.c | 91 ++++++++++++++-------- 4 files changed, 126 insertions(+), 62 deletions(-) diff --git a/src/lib/evas/Evas_Internal.h b/src/lib/evas/Evas_Internal.h index 1d3a37cd8c..9331e77fb8 100644 --- a/src/lib/evas/Evas_Internal.h +++ b/src/lib/evas/Evas_Internal.h @@ -113,6 +113,7 @@ EOAPI Eina_Bool efl_animation_instance_is_deleted(Eo *obj); EOAPI void efl_animation_instance_member_start(Eo *obj); EOAPI void efl_animation_instance_reverse_member_start(Eo *obj); +EOAPI void efl_animation_instance_reverse_initial_state_set(Eo *obj); EOAPI void efl_animation_instance_map_reset(Eo *obj); diff --git a/src/lib/evas/canvas/efl_animation_instance.c b/src/lib/evas/canvas/efl_animation_instance.c index 2d8da7c7e5..2e8426eb21 100644 --- a/src/lib/evas/canvas/efl_animation_instance.c +++ b/src/lib/evas/canvas/efl_animation_instance.c @@ -468,6 +468,15 @@ _efl_animation_instance_reverse_member_start(Eo *eo_obj, _start(eo_obj, pd); } +EOLIAN static void +_efl_animation_instance_reverse_initial_state_set(Eo *eo_obj, + Evas_Object_Animation_Instance_Data *pd) +{ + EFL_ANIMATION_INSTANCE_CHECK_OR_RETURN(eo_obj); + + if (!pd->ended) return; +} + EOLIAN static void _efl_animation_instance_start_delay_set(Eo *eo_obj, Evas_Object_Animation_Instance_Data *pd, @@ -656,6 +665,8 @@ EOAPI EFL_VOID_FUNC_BODY(efl_animation_instance_member_start); EOAPI EFL_VOID_FUNC_BODY(efl_animation_instance_reverse_member_start); +EOAPI EFL_VOID_FUNC_BODY(efl_animation_instance_reverse_initial_state_set); + EOAPI EFL_VOID_FUNC_BODY(efl_animation_instance_map_reset); EOAPI EFL_VOID_FUNC_BODY(efl_animation_instance_final_state_show); @@ -683,6 +694,7 @@ EWAPI const Efl_Event_Description _EFL_ANIMATION_INSTANCE_EVENT_POST_END = EFL_OBJECT_OP_FUNC(efl_animation_instance_is_deleted, _efl_animation_instance_is_deleted), \ EFL_OBJECT_OP_FUNC(efl_animation_instance_member_start, _efl_animation_instance_member_start), \ EFL_OBJECT_OP_FUNC(efl_animation_instance_reverse_member_start, _efl_animation_instance_reverse_member_start), \ + EFL_OBJECT_OP_FUNC(efl_animation_instance_reverse_initial_state_set, _efl_animation_instance_reverse_initial_state_set), \ EFL_OBJECT_OP_FUNC(efl_animation_instance_map_reset, _efl_animation_instance_map_reset), \ EFL_OBJECT_OP_FUNC(efl_animation_instance_final_state_show, NULL) diff --git a/src/lib/evas/canvas/efl_animation_instance_group_parallel.c b/src/lib/evas/canvas/efl_animation_instance_group_parallel.c index 47d300e52c..08174c836f 100644 --- a/src/lib/evas/canvas/efl_animation_instance_group_parallel.c +++ b/src/lib/evas/canvas/efl_animation_instance_group_parallel.c @@ -33,6 +33,7 @@ struct _Evas_Object_Animation_Instance_Group_Parallel_Data Eina_Bool started : 1; Eina_Bool reverse_started : 1; + Eina_Bool ended : 1; Eina_Bool paused : 1; Eina_Bool is_group_member : 1; Eina_Bool direction_forward : 1; @@ -210,6 +211,8 @@ _post_end_cb(void *data, const Efl_Event *event) return; } + pd->ended = EINA_TRUE; + efl_event_callback_call(eo_obj, EFL_ANIMATION_INSTANCE_EVENT_END, NULL); //post end event is supported within class only (protected event) efl_event_callback_call(eo_obj, EFL_ANIMATION_INSTANCE_EVENT_POST_END, @@ -266,6 +269,14 @@ _parallel_animation_start(Eo *eo_obj, } else { + /* reverse_initial_state_set() should be called for all instances before + * calling reverse_member_start() + */ + EINA_LIST_REVERSE_FOREACH(instances, l, inst) + { + efl_animation_instance_reverse_initial_state_set(inst); + } + EINA_LIST_REVERSE_FOREACH(instances, l, inst) { //Data should be registered before animation instance starts @@ -281,6 +292,7 @@ _init_start(Eo *eo_obj, Evas_Object_Animation_Instance_Group_Parallel_Data *pd) pd->animate_inst_index = 0; pd->started = EINA_TRUE; + pd->ended = EINA_FALSE; pd->remaining_repeat_count = efl_animation_instance_repeat_count_get(eo_obj); @@ -288,36 +300,7 @@ _init_start(Eo *eo_obj, Evas_Object_Animation_Instance_Group_Parallel_Data *pd) pd->finished_inst_list = NULL; if (pd->reverse_started) - { - Eina_List *instances = - efl_animation_instance_group_instances_get(eo_obj); - pd->finished_inst_list = eina_list_clone(instances); - - Eina_List *l; - Eina_List *l_next; - Efl_Animation_Instance *inst; - /* The finished instances should be removed from the - * finished instance list because the finished instances - * will be animated from the next animation frmae by - * calling reverse_member_start(). - * However, group animation instances may have more than - * one member animation instances. So the member - * animation instances except the last member animation - * instance should be remained as finished instances. - */ - EINA_LIST_FOREACH_SAFE(pd->finished_inst_list, l, l_next, inst) - { - const char *inst_class = efl_class_name_get(inst); - const char *group_class = "Efl.Animation.Instance.Group"; - int class_len = strlen(group_class); - if (!inst_class || strncmp(inst_class, group_class, class_len)) - { - pd->finished_inst_list = - eina_list_remove_list(pd->finished_inst_list, l); - } - } - pd->direction_forward = EINA_FALSE; - } + pd->direction_forward = EINA_FALSE; else pd->direction_forward = EINA_TRUE; @@ -417,6 +400,46 @@ _efl_animation_instance_group_parallel_efl_animation_instance_reverse_member_sta _start(eo_obj, pd); } +EOLIAN static void +_efl_animation_instance_group_parallel_efl_animation_instance_reverse_initial_state_set(Eo *eo_obj, + Evas_Object_Animation_Instance_Group_Parallel_Data *pd) +{ + EFL_ANIMATION_INSTANCE_GROUP_PARALLEL_CHECK_OR_RETURN(eo_obj); + + if (!pd->ended) return; + + Eina_List *instances = + efl_animation_instance_group_instances_get(eo_obj); + pd->finished_inst_list = eina_list_clone(instances); + + Eina_List *l; + Eina_List *l_next; + Efl_Animation_Instance *inst; + /* The finished instances should be removed from the + * finished instance list because the finished instances + * will be animated from the next animation frmae by + * calling reverse_member_start(). + * However, group animation instances may have more than + * one member animation instances. So the member + * animation instances except the last member animation + * instance should be remained as finished instances. + */ + EINA_LIST_FOREACH_SAFE(pd->finished_inst_list, l, l_next, inst) + { + const char *inst_class = efl_class_name_get(inst); + const char *group_class = "Efl.Animation.Instance.Group"; + int class_len = strlen(group_class); + if (!inst_class || strncmp(inst_class, group_class, class_len)) + { + pd->finished_inst_list = + eina_list_remove_list(pd->finished_inst_list, l); + } + + //Set initial state of repeat reverse to the instance + efl_animation_instance_reverse_initial_state_set(inst); + } +} + EOLIAN static void _efl_animation_instance_group_parallel_efl_animation_instance_start_delay_set(Eo *eo_obj, Evas_Object_Animation_Instance_Group_Parallel_Data *pd, @@ -550,6 +573,7 @@ _efl_animation_instance_group_parallel_efl_animation_instance_group_instance_del #define EFL_ANIMATION_INSTANCE_GROUP_PARALLEL_EXTRA_OPS \ EFL_OBJECT_OP_FUNC(efl_animation_instance_member_start, _efl_animation_instance_group_parallel_efl_animation_instance_member_start), \ EFL_OBJECT_OP_FUNC(efl_animation_instance_reverse_member_start, _efl_animation_instance_group_parallel_efl_animation_instance_reverse_member_start), \ + EFL_OBJECT_OP_FUNC(efl_animation_instance_reverse_initial_state_set, _efl_animation_instance_group_parallel_efl_animation_instance_reverse_initial_state_set), \ EFL_OBJECT_OP_FUNC(efl_animation_instance_final_state_show, _efl_animation_instance_group_parallel_efl_animation_instance_final_state_show), \ EFL_OBJECT_OP_FUNC(efl_animation_instance_group_instance_add, _efl_animation_instance_group_parallel_efl_animation_instance_group_instance_add), \ EFL_OBJECT_OP_FUNC(efl_animation_instance_group_instance_del, _efl_animation_instance_group_parallel_efl_animation_instance_group_instance_del), \ diff --git a/src/lib/evas/canvas/efl_animation_instance_group_sequential.c b/src/lib/evas/canvas/efl_animation_instance_group_sequential.c index c488296035..312dd09ca4 100644 --- a/src/lib/evas/canvas/efl_animation_instance_group_sequential.c +++ b/src/lib/evas/canvas/efl_animation_instance_group_sequential.c @@ -33,6 +33,7 @@ struct _Evas_Object_Animation_Instance_Group_Sequential_Data Eina_Bool started : 1; Eina_Bool reverse_started : 1; + Eina_Bool ended : 1; Eina_Bool paused : 1; Eina_Bool is_group_member : 1; Eina_Bool direction_forward : 1; @@ -245,6 +246,8 @@ _post_end_cb(void *data, const Efl_Event *event) goto next_start; } + pd->ended = EINA_TRUE; + efl_event_callback_call(eo_obj, EFL_ANIMATION_INSTANCE_EVENT_END, NULL); //post end event is supported within class only (protected event) efl_event_callback_call(eo_obj, EFL_ANIMATION_INSTANCE_EVENT_POST_END, @@ -292,58 +295,34 @@ _index_animation_start(Eo *eo_obj, int index, Eina_Bool direction_forward) if (direction_forward) efl_animation_instance_member_start(inst); else - efl_animation_instance_reverse_member_start(inst); + { + efl_animation_instance_reverse_initial_state_set(inst); + efl_animation_instance_reverse_member_start(inst); + } } static void _init_start(Eo *eo_obj, Evas_Object_Animation_Instance_Group_Sequential_Data *pd) { pd->started = EINA_TRUE; + pd->ended = EINA_FALSE; pd->remaining_repeat_count = efl_animation_instance_repeat_count_get(eo_obj); - eina_list_free(pd->finished_inst_list); - pd->finished_inst_list = NULL; - if (pd->reverse_started) { Eina_List *instances = efl_animation_instance_group_instances_get(eo_obj); - pd->finished_inst_list = eina_list_clone(instances); - - /* The last finished instance should be removed from the - * finished instance list because the last finished - * instance will be animated from the next animation - * frame by calling reverse_member_start(). - * However, group animation instances may have more than - * one member animation instances. So the member - * animation instances except the last member animation - * instance should be remained as finished instances. - */ - Efl_Animation_Instance *last_inst = NULL; - Eina_List *last_inst_list = - eina_list_last(pd->finished_inst_list); - if (last_inst_list) - last_inst = eina_list_data_get(last_inst_list); - - if (last_inst) - { - const char *inst_class = efl_class_name_get(last_inst); - const char *group_class = "Efl.Animation.Instance.Group"; - int class_len = strlen(group_class); - if (!inst_class || strncmp(inst_class, group_class, class_len)) - { - pd->finished_inst_list = - eina_list_remove(pd->finished_inst_list, last_inst); - } - } pd->current_index = eina_list_count(instances) - 1; pd->direction_forward = EINA_FALSE; } else { + eina_list_free(pd->finished_inst_list); + pd->finished_inst_list = NULL; + pd->current_index = 0; pd->direction_forward = EINA_TRUE; @@ -445,6 +424,53 @@ _efl_animation_instance_group_sequential_efl_animation_instance_reverse_member_s _start(eo_obj, pd); } +EOLIAN static void +_efl_animation_instance_group_sequential_efl_animation_instance_reverse_initial_state_set(Eo *eo_obj, + Evas_Object_Animation_Instance_Group_Sequential_Data *pd) +{ + EFL_ANIMATION_INSTANCE_GROUP_SEQUENTIAL_CHECK_OR_RETURN(eo_obj); + + if (!pd->ended) return; + + /* The last finished instance should be removed from the + * finished instance list because the last finished + * instance will be animated from the next animation + * frame by calling reverse_member_start(). + * However, group animation instances may have more than + * one member animation instances. So the member + * animation instances except the last member animation + * instance should be remained as finished instances. + */ + Efl_Animation_Instance *last_inst = NULL; + + Eina_List *instances = + efl_animation_instance_group_instances_get(eo_obj); + + eina_list_free(pd->finished_inst_list); + pd->finished_inst_list = eina_list_clone(instances); + + Eina_List *last_inst_list = + eina_list_last(pd->finished_inst_list); + if (last_inst_list) + last_inst = eina_list_data_get(last_inst_list); + + if (last_inst) + { + const char *inst_class = efl_class_name_get(last_inst); + const char *group_class = "Efl.Animation.Instance.Group"; + int class_len = strlen(group_class); + if (!inst_class || strncmp(inst_class, group_class, class_len)) + { + pd->finished_inst_list = + eina_list_remove(pd->finished_inst_list, last_inst); + } + + //Set initial state of repeat reverse to the last instance + efl_animation_instance_reverse_initial_state_set(last_inst); + } +} + + EOLIAN static void _efl_animation_instance_group_sequential_efl_animation_instance_start_delay_set(Eo *eo_obj, Evas_Object_Animation_Instance_Group_Sequential_Data *pd, @@ -578,6 +604,7 @@ _efl_animation_instance_group_sequential_efl_animation_instance_final_state_show #define EFL_ANIMATION_INSTANCE_GROUP_SEQUENTIAL_EXTRA_OPS \ EFL_OBJECT_OP_FUNC(efl_animation_instance_member_start, _efl_animation_instance_group_sequential_efl_animation_instance_member_start), \ EFL_OBJECT_OP_FUNC(efl_animation_instance_reverse_member_start, _efl_animation_instance_group_sequential_efl_animation_instance_reverse_member_start), \ + EFL_OBJECT_OP_FUNC(efl_animation_instance_reverse_initial_state_set, _efl_animation_instance_group_sequential_efl_animation_instance_reverse_initial_state_set), \ EFL_OBJECT_OP_FUNC(efl_animation_instance_final_state_show, _efl_animation_instance_group_sequential_efl_animation_instance_final_state_show), \ EFL_OBJECT_OP_FUNC(efl_animation_instance_group_instance_add, _efl_animation_instance_group_sequential_efl_animation_instance_group_instance_add), \ EFL_OBJECT_OP_FUNC(efl_animation_instance_group_instance_del, _efl_animation_instance_group_sequential_efl_animation_instance_group_instance_del), \ -- cgit v1.2.1