From f1ad1559b7e1ec8e913d95d07de81e42d0434096 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Sat, 23 Feb 2019 12:57:13 +0100 Subject: [PATCH] efl_ui_stack: use direct events instead of event_animation event_animation of efl_canvas_object, is a little problem, we need to explictly turn it off, to do a visual state manipulation, just to attach the animation again. Further more, the animation objects are stored in static fields, which are not bound to the object. Which means, when two Efl.Ui.Stack objects are running in parrallel, the animation will look a little bit wacky, since the object is detached before the animation is ended. ref T7555 Reviewed-by: Mike Blumenkrantz Differential Revision: https://phab.enlightenment.org/D8008 --- src/lib/elementary/efl_ui_stack.c | 184 ++++++++++------------ src/lib/elementary/efl_ui_stack_private.h | 16 +- 2 files changed, 91 insertions(+), 109 deletions(-) diff --git a/src/lib/elementary/efl_ui_stack.c b/src/lib/elementary/efl_ui_stack.c index e4e4ed364a..45f0bed6d4 100644 --- a/src/lib/elementary/efl_ui_stack.c +++ b/src/lib/elementary/efl_ui_stack.c @@ -40,15 +40,6 @@ _show_content_without_anim(Efl_Ui_Stack *obj, Evas_Object *content) efl_event_callback_call(obj, EFL_UI_STACK_EVENT_LOADED, &loaded_info); - Efl_Canvas_Animation *orig_show_anim = - efl_canvas_object_event_animation_get(content, - EFL_GFX_ENTITY_EVENT_SHOW); - - if (orig_show_anim) - efl_canvas_object_event_animation_set(content, - EFL_GFX_ENTITY_EVENT_SHOW, - NULL); - evas_object_raise(content); /* efl_ui_widget_resize_object_set() calls efl_gfx_entity_visible_set() * internally. @@ -56,10 +47,6 @@ _show_content_without_anim(Efl_Ui_Stack *obj, Evas_Object *content) * setting animation and efl_gfx_entity_visible_set() is not called. */ efl_ui_widget_resize_object_set(obj, content); - if (orig_show_anim) - efl_canvas_object_event_animation_set(content, - EFL_GFX_ENTITY_EVENT_SHOW, - orig_show_anim); //Activated Event Efl_Ui_Stack_Event_Activated activated_info; activated_info.content = content; @@ -70,20 +57,7 @@ _show_content_without_anim(Efl_Ui_Stack *obj, Evas_Object *content) static void _hide_content_without_anim(Efl_Ui_Stack *obj EINA_UNUSED, Evas_Object *content) { - Efl_Canvas_Animation *orig_hide_anim = - efl_canvas_object_event_animation_get(content, - EFL_GFX_ENTITY_EVENT_HIDE); - - if (orig_hide_anim) - efl_canvas_object_event_animation_set(content, - EFL_GFX_ENTITY_EVENT_HIDE, NULL); - efl_gfx_entity_visible_set(content, EINA_FALSE); - - if (orig_hide_anim) - efl_canvas_object_event_animation_set(content, - EFL_GFX_ENTITY_EVENT_HIDE, - orig_hide_anim); } static void @@ -98,7 +72,7 @@ _content_del_cb(void *data, const Efl_Event *event EINA_UNUSED) } static Content_Data * -_content_data_new(Eo *obj, Eo *content) +_content_data_new(Eo *obj EINA_UNUSED, Eo *content) { Content_Data *cd = calloc(1, sizeof(Content_Data)); if (!cd) @@ -107,7 +81,6 @@ _content_data_new(Eo *obj, Eo *content) return NULL; } - cd->stack = obj; cd->content = content; efl_event_callback_add(cd->content, EFL_EVENT_DEL, _content_del_cb, cd); @@ -129,106 +102,92 @@ _content_data_del(Content_Data *cd) static void _anim_started_cb(void *data EINA_UNUSED, const Efl_Event *event) { - efl_canvas_object_freeze_events_set(event->object, EINA_TRUE); - - efl_event_callback_del(event->object, EFL_CANVAS_OBJECT_EVENT_ANIM_STARTED, - _anim_started_cb, NULL); + efl_canvas_object_freeze_events_set(efl_animation_player_target_get(event->object), EINA_TRUE); } -static void -_anim_ended_cb(void *data, const Efl_Event *event) +static Evas_Object* +_end_anim(Transit_Data *td) { - Transit_Data *td = data; - Efl_Canvas_Object_Animation_Event *anim_event = event->info; - - //Unset animation because originally there is no animation. - if (!td->orig_anim) - efl_canvas_object_event_animation_set(event->object, - anim_event->event_desc, NULL); - - efl_canvas_object_freeze_events_set(event->object, - td->freeze_events); + Efl_Canvas_Object *content = td->cd->content; + efl_canvas_object_freeze_events_set(content, td->freeze_events); td->cd->on_pushing = EINA_FALSE; td->cd->on_popping = EINA_FALSE; + free(td); - if (anim_event->event_desc == EFL_GFX_ENTITY_EVENT_SHOW) - { - //Activated Event - Efl_Ui_Stack_Event_Activated activated_info; - activated_info.content = event->object; - efl_event_callback_call(td->cd->stack, - EFL_UI_STACK_EVENT_ACTIVATED, - &activated_info); - } - else - { - _announce_hiding(NULL, event->object); - } - - efl_event_callback_del(event->object, EFL_CANVAS_OBJECT_EVENT_ANIM_ENDED, - _anim_ended_cb, data); - free(data); + return content; } static void -_show_content_with_anim(Efl_Ui_Stack *obj, Content_Data *cd) +_hide_anim_ended_cb(void *data, const Efl_Event *event EINA_UNUSED) { - Efl_Canvas_Animation *orig_show_anim = - efl_canvas_object_event_animation_get(cd->content, - EFL_GFX_ENTITY_EVENT_SHOW); + Efl_Ui_Stack_Data *pd = efl_data_scope_safe_get(data, EFL_UI_STACK_CLASS); + Efl_Canvas_Object *content; - //Show with animation - if (!orig_show_anim) - efl_canvas_object_event_animation_set(cd->content, - EFL_GFX_ENTITY_EVENT_SHOW, - show_anim); + content = _end_anim(pd->hide_td); + pd->hide_td = NULL; + efl_gfx_entity_visible_set(content, EINA_FALSE); + _announce_hiding(data, content); +} + +static void +_show_anim_ended_cb(void *data, const Efl_Event *event EINA_UNUSED) +{ + Efl_Ui_Stack_Data *pd = efl_data_scope_safe_get(data, EFL_UI_STACK_CLASS); + Efl_Canvas_Object *content; + + content = _end_anim(pd->show_td); + pd->show_td = NULL; + //Activated Event + Efl_Ui_Stack_Event_Activated activated_info; + activated_info.content = content; + efl_event_callback_call(data, + EFL_UI_STACK_EVENT_ACTIVATED, + &activated_info); +} + +static void +_show_content_with_anim(Efl_Ui_Stack *obj, Efl_Ui_Stack_Data *pd, Content_Data *cd) +{ + //immidiatly stop hiding animation + efl_player_stop(pd->show); + if (pd->show_td) + EINA_SAFETY_ERROR("td is set but it should not"); + + //attach new content target + efl_animation_player_target_set(pd->show, cd->content); Transit_Data *td = calloc(1, sizeof(Transit_Data)); td->cd = cd; - td->orig_anim = !!(orig_show_anim); td->freeze_events = efl_canvas_object_freeze_events_get(cd->content); - - efl_event_callback_add(cd->content, - EFL_CANVAS_OBJECT_EVENT_ANIM_STARTED, - _anim_started_cb, NULL); - efl_event_callback_add(cd->content, - EFL_CANVAS_OBJECT_EVENT_ANIM_ENDED, - _anim_ended_cb, td); + pd->show_td = td; /* efl_ui_widget_resize_object_set() calls efl_gfx_entity_visible_set() * internally. * Therefore, efl_ui_widget_resize_object_set() is called after * setting animation and efl_gfx_entity_visible_set() is not called. */ efl_ui_widget_resize_object_set(obj, cd->content); + efl_player_start(pd->show); } static void -_hide_content_with_anim(Efl_Ui_Stack *obj EINA_UNUSED, Content_Data *cd) +_hide_content_with_anim(Efl_Ui_Stack *obj EINA_UNUSED, Efl_Ui_Stack_Data *pd, Content_Data *cd) { - Efl_Canvas_Animation *orig_hide_anim = - efl_canvas_object_event_animation_get(cd->content, - EFL_GFX_ENTITY_EVENT_HIDE); - //Hide with animation. - if (!orig_hide_anim) - efl_canvas_object_event_animation_set(cd->content, - EFL_GFX_ENTITY_EVENT_HIDE, - hide_anim); + //immidiatly stop hiding animation + efl_player_stop(pd->hide); + if (pd->hide_td) + EINA_SAFETY_ERROR("td is set but it should not"); + + //attach new content target + efl_animation_player_target_set(pd->hide, cd->content); Transit_Data *td = calloc(1, sizeof(Transit_Data)); td->cd = cd; - td->orig_anim = !!(orig_hide_anim); td->freeze_events = efl_canvas_object_freeze_events_get(cd->content); + pd->hide_td = td; - efl_event_callback_add(cd->content, - EFL_CANVAS_OBJECT_EVENT_ANIM_STARTED, - _anim_started_cb, NULL); - efl_event_callback_add(cd->content, - EFL_CANVAS_OBJECT_EVENT_ANIM_ENDED, - _anim_ended_cb, td); - - efl_gfx_entity_visible_set(cd->content, EINA_FALSE); + efl_player_start(pd->hide); } EOLIAN static void @@ -287,7 +246,7 @@ _efl_ui_stack_push(Eo *obj, Efl_Ui_Stack_Data *pd, Eo *content) { top_cd->on_pushing = EINA_TRUE; - _hide_content_with_anim(obj, top_cd); + _hide_content_with_anim(obj, pd, top_cd); } } @@ -298,7 +257,7 @@ _efl_ui_stack_push(Eo *obj, Efl_Ui_Stack_Data *pd, Eo *content) /* Apply transition to new content. * Show new content with animation. */ - _show_content_with_anim(obj, cd); + _show_content_with_anim(obj, pd, cd); } static void @@ -344,7 +303,7 @@ _efl_ui_stack_pop(Eo *obj, Efl_Ui_Stack_Data *pd) efl_event_callback_add(top_content, EFL_GFX_ENTITY_EVENT_HIDE, _pop_content_hide_cb, top_cd); - _hide_content_with_anim(obj, top_cd); + _hide_content_with_anim(obj, pd, top_cd); } } @@ -364,7 +323,7 @@ _efl_ui_stack_pop(Eo *obj, Efl_Ui_Stack_Data *pd) /* Apply transition to previous content. * Show previous content with animation. */ - _show_content_with_anim(obj, prev_cd); + _show_content_with_anim(obj, pd, prev_cd); } return NULL; @@ -673,24 +632,45 @@ _efl_ui_stack_top(Eo *obj EINA_UNUSED, Efl_Ui_Stack_Data *pd) return cd->content; } +EFL_CALLBACKS_ARRAY_DEFINE(_anim_show_event_cb, + {EFL_ANIMATION_PLAYER_EVENT_STARTED, _anim_started_cb}, + {EFL_ANIMATION_PLAYER_EVENT_ENDED, _show_anim_ended_cb}, +) + +EFL_CALLBACKS_ARRAY_DEFINE(_anim_hide_event_cb, + {EFL_ANIMATION_PLAYER_EVENT_STARTED, _anim_started_cb}, + {EFL_ANIMATION_PLAYER_EVENT_ENDED, _hide_anim_ended_cb}, +) + EOLIAN static Eo * _efl_ui_stack_efl_object_constructor(Eo *obj, Efl_Ui_Stack_Data *pd EINA_UNUSED) { + Efl_Canvas_Animation *sh, *hi; obj = efl_constructor(efl_super(obj, MY_CLASS)); efl_canvas_object_type_set(obj, MY_CLASS_NAME); //Default Show Animation - show_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, obj); + sh = show_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, obj); efl_animation_alpha_set(show_anim, 0.0, 1.0); efl_animation_duration_set(show_anim, 0.5); efl_animation_final_state_keep_set(show_anim, EINA_TRUE); + pd->show = efl_add(EFL_CANVAS_ANIMATION_PLAYER_CLASS, obj); + efl_animation_player_animation_set(pd->show, sh); + efl_player_play_set(pd->show, EINA_FALSE); + efl_event_callback_array_add(pd->show, _anim_show_event_cb(), obj); + //Default Hide Animation - hide_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, obj); + hi = hide_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, obj); efl_animation_alpha_set(hide_anim, 1.0, 0.0); efl_animation_duration_set(hide_anim, 0.5); efl_animation_final_state_keep_set(hide_anim, EINA_TRUE); + pd->hide = efl_add(EFL_CANVAS_ANIMATION_PLAYER_CLASS, obj); + efl_animation_player_animation_set(pd->hide, hi); + efl_player_play_set(pd->hide, EINA_FALSE); + efl_event_callback_array_add(pd->hide, _anim_hide_event_cb(), obj); + return obj; } diff --git a/src/lib/elementary/efl_ui_stack_private.h b/src/lib/elementary/efl_ui_stack_private.h index dc67451d58..b6b32f8e6e 100644 --- a/src/lib/elementary/efl_ui_stack_private.h +++ b/src/lib/elementary/efl_ui_stack_private.h @@ -1,18 +1,12 @@ #ifndef EFL_UI_WIDGET_STACK_H #define EFL_UI_WIDGET_STACK_H -typedef struct _Efl_Ui_Stack_Data Efl_Ui_Stack_Data; -struct _Efl_Ui_Stack_Data -{ - Eina_Inlist *stack; /* the last item is the top item */ -}; typedef struct _Content_Data Content_Data; struct _Content_Data { EINA_INLIST; - Eo *stack; Eo *content; Eina_Bool on_pushing : 1; Eina_Bool on_popping : 1; @@ -23,8 +17,16 @@ typedef struct _Transit_Data Transit_Data; struct _Transit_Data { Content_Data *cd; - Eina_Bool orig_anim; Eina_Bool freeze_events; }; +typedef struct _Efl_Ui_Stack_Data Efl_Ui_Stack_Data; +struct _Efl_Ui_Stack_Data +{ + Eina_Inlist *stack; /* the last item is the top item */ + Efl_Canvas_Animation_Player *hide, *show; + Transit_Data *show_td, *hide_td; + +}; + #endif