forked from enlightenment/efl
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 <michael.blumenkrantz@gmail.com> Differential Revision: https://phab.enlightenment.org/D8008
This commit is contained in:
parent
4ccbf201fb
commit
f1ad1559b7
|
@ -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,
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_LOADED,
|
||||||
&loaded_info);
|
&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);
|
evas_object_raise(content);
|
||||||
/* efl_ui_widget_resize_object_set() calls efl_gfx_entity_visible_set()
|
/* efl_ui_widget_resize_object_set() calls efl_gfx_entity_visible_set()
|
||||||
* internally.
|
* 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. */
|
* setting animation and efl_gfx_entity_visible_set() is not called. */
|
||||||
efl_ui_widget_resize_object_set(obj, content);
|
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
|
//Activated Event
|
||||||
Efl_Ui_Stack_Event_Activated activated_info;
|
Efl_Ui_Stack_Event_Activated activated_info;
|
||||||
activated_info.content = content;
|
activated_info.content = content;
|
||||||
|
@ -70,20 +57,7 @@ _show_content_without_anim(Efl_Ui_Stack *obj, Evas_Object *content)
|
||||||
static void
|
static void
|
||||||
_hide_content_without_anim(Efl_Ui_Stack *obj EINA_UNUSED, Evas_Object *content)
|
_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);
|
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
|
static void
|
||||||
|
@ -98,7 +72,7 @@ _content_del_cb(void *data, const Efl_Event *event EINA_UNUSED)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Content_Data *
|
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));
|
Content_Data *cd = calloc(1, sizeof(Content_Data));
|
||||||
if (!cd)
|
if (!cd)
|
||||||
|
@ -107,7 +81,6 @@ _content_data_new(Eo *obj, Eo *content)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cd->stack = obj;
|
|
||||||
cd->content = content;
|
cd->content = content;
|
||||||
|
|
||||||
efl_event_callback_add(cd->content, EFL_EVENT_DEL, _content_del_cb, cd);
|
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
|
static void
|
||||||
_anim_started_cb(void *data EINA_UNUSED, const Efl_Event *event)
|
_anim_started_cb(void *data EINA_UNUSED, const Efl_Event *event)
|
||||||
{
|
{
|
||||||
efl_canvas_object_freeze_events_set(event->object, EINA_TRUE);
|
efl_canvas_object_freeze_events_set(efl_animation_player_target_get(event->object), EINA_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
efl_event_callback_del(event->object, EFL_CANVAS_OBJECT_EVENT_ANIM_STARTED,
|
static Evas_Object*
|
||||||
_anim_started_cb, NULL);
|
_end_anim(Transit_Data *td)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_anim_ended_cb(void *data, const Efl_Event *event)
|
_hide_anim_ended_cb(void *data, const Efl_Event *event EINA_UNUSED)
|
||||||
{
|
{
|
||||||
Transit_Data *td = data;
|
Efl_Ui_Stack_Data *pd = efl_data_scope_safe_get(data, EFL_UI_STACK_CLASS);
|
||||||
Efl_Canvas_Object_Animation_Event *anim_event = event->info;
|
Efl_Canvas_Object *content;
|
||||||
|
|
||||||
//Unset animation because originally there is no animation.
|
content = _end_anim(pd->hide_td);
|
||||||
if (!td->orig_anim)
|
pd->hide_td = NULL;
|
||||||
efl_canvas_object_event_animation_set(event->object,
|
efl_gfx_entity_visible_set(content, EINA_FALSE);
|
||||||
anim_event->event_desc, NULL);
|
_announce_hiding(data, content);
|
||||||
|
}
|
||||||
|
|
||||||
efl_canvas_object_freeze_events_set(event->object,
|
static void
|
||||||
td->freeze_events);
|
_show_anim_ended_cb(void *data, const Efl_Event *event EINA_UNUSED)
|
||||||
|
|
||||||
td->cd->on_pushing = EINA_FALSE;
|
|
||||||
td->cd->on_popping = EINA_FALSE;
|
|
||||||
|
|
||||||
if (anim_event->event_desc == EFL_GFX_ENTITY_EVENT_SHOW)
|
|
||||||
{
|
{
|
||||||
|
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
|
//Activated Event
|
||||||
Efl_Ui_Stack_Event_Activated activated_info;
|
Efl_Ui_Stack_Event_Activated activated_info;
|
||||||
activated_info.content = event->object;
|
activated_info.content = content;
|
||||||
efl_event_callback_call(td->cd->stack,
|
efl_event_callback_call(data,
|
||||||
EFL_UI_STACK_EVENT_ACTIVATED,
|
EFL_UI_STACK_EVENT_ACTIVATED,
|
||||||
&activated_info);
|
&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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_show_content_with_anim(Efl_Ui_Stack *obj, Content_Data *cd)
|
_show_content_with_anim(Efl_Ui_Stack *obj, Efl_Ui_Stack_Data *pd, Content_Data *cd)
|
||||||
{
|
{
|
||||||
Efl_Canvas_Animation *orig_show_anim =
|
//immidiatly stop hiding animation
|
||||||
efl_canvas_object_event_animation_get(cd->content,
|
efl_player_stop(pd->show);
|
||||||
EFL_GFX_ENTITY_EVENT_SHOW);
|
if (pd->show_td)
|
||||||
|
EINA_SAFETY_ERROR("td is set but it should not");
|
||||||
|
|
||||||
//Show with animation
|
//attach new content target
|
||||||
if (!orig_show_anim)
|
efl_animation_player_target_set(pd->show, cd->content);
|
||||||
efl_canvas_object_event_animation_set(cd->content,
|
|
||||||
EFL_GFX_ENTITY_EVENT_SHOW,
|
|
||||||
show_anim);
|
|
||||||
|
|
||||||
Transit_Data *td = calloc(1, sizeof(Transit_Data));
|
Transit_Data *td = calloc(1, sizeof(Transit_Data));
|
||||||
td->cd = cd;
|
td->cd = cd;
|
||||||
td->orig_anim = !!(orig_show_anim);
|
|
||||||
td->freeze_events =
|
td->freeze_events =
|
||||||
efl_canvas_object_freeze_events_get(cd->content);
|
efl_canvas_object_freeze_events_get(cd->content);
|
||||||
|
pd->show_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_ui_widget_resize_object_set() calls efl_gfx_entity_visible_set()
|
/* efl_ui_widget_resize_object_set() calls efl_gfx_entity_visible_set()
|
||||||
* internally.
|
* internally.
|
||||||
* Therefore, efl_ui_widget_resize_object_set() is called after
|
* Therefore, efl_ui_widget_resize_object_set() is called after
|
||||||
* setting animation and efl_gfx_entity_visible_set() is not called. */
|
* setting animation and efl_gfx_entity_visible_set() is not called. */
|
||||||
efl_ui_widget_resize_object_set(obj, cd->content);
|
efl_ui_widget_resize_object_set(obj, cd->content);
|
||||||
|
efl_player_start(pd->show);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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 =
|
//immidiatly stop hiding animation
|
||||||
efl_canvas_object_event_animation_get(cd->content,
|
efl_player_stop(pd->hide);
|
||||||
EFL_GFX_ENTITY_EVENT_HIDE);
|
if (pd->hide_td)
|
||||||
//Hide with animation.
|
EINA_SAFETY_ERROR("td is set but it should not");
|
||||||
if (!orig_hide_anim)
|
|
||||||
efl_canvas_object_event_animation_set(cd->content,
|
//attach new content target
|
||||||
EFL_GFX_ENTITY_EVENT_HIDE,
|
efl_animation_player_target_set(pd->hide, cd->content);
|
||||||
hide_anim);
|
|
||||||
|
|
||||||
Transit_Data *td = calloc(1, sizeof(Transit_Data));
|
Transit_Data *td = calloc(1, sizeof(Transit_Data));
|
||||||
td->cd = cd;
|
td->cd = cd;
|
||||||
td->orig_anim = !!(orig_hide_anim);
|
|
||||||
td->freeze_events = efl_canvas_object_freeze_events_get(cd->content);
|
td->freeze_events = efl_canvas_object_freeze_events_get(cd->content);
|
||||||
|
pd->hide_td = td;
|
||||||
|
|
||||||
efl_event_callback_add(cd->content,
|
efl_player_start(pd->hide);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EOLIAN static void
|
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;
|
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.
|
/* Apply transition to new content.
|
||||||
* Show new content with animation. */
|
* Show new content with animation. */
|
||||||
_show_content_with_anim(obj, cd);
|
_show_content_with_anim(obj, pd, cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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,
|
efl_event_callback_add(top_content, EFL_GFX_ENTITY_EVENT_HIDE,
|
||||||
_pop_content_hide_cb, top_cd);
|
_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.
|
/* Apply transition to previous content.
|
||||||
* Show previous content with animation. */
|
* Show previous content with animation. */
|
||||||
_show_content_with_anim(obj, prev_cd);
|
_show_content_with_anim(obj, pd, prev_cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -673,24 +632,45 @@ _efl_ui_stack_top(Eo *obj EINA_UNUSED, Efl_Ui_Stack_Data *pd)
|
||||||
return cd->content;
|
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 *
|
EOLIAN static Eo *
|
||||||
_efl_ui_stack_efl_object_constructor(Eo *obj, Efl_Ui_Stack_Data *pd EINA_UNUSED)
|
_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));
|
obj = efl_constructor(efl_super(obj, MY_CLASS));
|
||||||
efl_canvas_object_type_set(obj, MY_CLASS_NAME);
|
efl_canvas_object_type_set(obj, MY_CLASS_NAME);
|
||||||
|
|
||||||
//Default Show Animation
|
//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_alpha_set(show_anim, 0.0, 1.0);
|
||||||
efl_animation_duration_set(show_anim, 0.5);
|
efl_animation_duration_set(show_anim, 0.5);
|
||||||
efl_animation_final_state_keep_set(show_anim, EINA_TRUE);
|
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
|
//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_alpha_set(hide_anim, 1.0, 0.0);
|
||||||
efl_animation_duration_set(hide_anim, 0.5);
|
efl_animation_duration_set(hide_anim, 0.5);
|
||||||
efl_animation_final_state_keep_set(hide_anim, EINA_TRUE);
|
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;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,12 @@
|
||||||
#ifndef EFL_UI_WIDGET_STACK_H
|
#ifndef EFL_UI_WIDGET_STACK_H
|
||||||
#define 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;
|
typedef struct _Content_Data Content_Data;
|
||||||
struct _Content_Data
|
struct _Content_Data
|
||||||
{
|
{
|
||||||
EINA_INLIST;
|
EINA_INLIST;
|
||||||
|
|
||||||
Eo *stack;
|
|
||||||
Eo *content;
|
Eo *content;
|
||||||
Eina_Bool on_pushing : 1;
|
Eina_Bool on_pushing : 1;
|
||||||
Eina_Bool on_popping : 1;
|
Eina_Bool on_popping : 1;
|
||||||
|
@ -23,8 +17,16 @@ typedef struct _Transit_Data Transit_Data;
|
||||||
struct _Transit_Data
|
struct _Transit_Data
|
||||||
{
|
{
|
||||||
Content_Data *cd;
|
Content_Data *cd;
|
||||||
Eina_Bool orig_anim;
|
|
||||||
Eina_Bool freeze_events;
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue