typedef struct _Event_Animation
{
- Efl_Animation *anim;
- Efl_Animation_Object *anim_obj;
-} Event_Animation;
+ EINA_INLIST;
-typedef struct _Hide_Anim_Data
-{
- Efl_Canvas_Object *target;
- Eina_Bool anim_started;
- Eina_Bool anim_ended;
-} Hide_Anim_Data;
+ const Efl_Event_Description *desc;
+
+ Efl_Animation *anim;
+ Efl_Animation_Object *anim_obj;
+
+ Eina_Bool hide_anim_started : 1;
+ Eina_Bool hide_anim_ended : 1;
+} Event_Animation;
static Eina_Bool
_init_cow(void)
return pdata;
}
+static void _animation_intercept_hide(void *data, Evas_Object *eo_obj);
+
+static void
+_animation_hide_end_cb(void *data, const Efl_Event *event EINA_UNUSED)
+{
+ Event_Animation *event_anim = data;
+
+ event_anim->hide_anim_ended = EINA_TRUE;
+
+ //Animation Object is automatically deleted when animation is ended.
+ event_anim->anim_obj = NULL;
+
+ Evas_Object *target = efl_animation_target_get(event_anim->anim);
+ _animation_intercept_hide(event_anim, target);
+
+ event_anim->hide_anim_started = EINA_FALSE;
+ event_anim->hide_anim_ended = EINA_FALSE;
+}
+
+static void _all_animation_objects_cancel(Evas_Object_Protected_Data *obj);
+
static void
-_init_event_anims(Evas_Object_Protected_Data *obj)
+_animation_intercept_hide(void *data, Evas_Object *eo_obj)
{
- obj->event_anims = eina_array_new(EFL_ANIMATION_EVENT_TYPE_COUNT);
+ Event_Animation *event_anim = data;
+ Evas_Object_Protected_Data *obj = EVAS_OBJECT_DATA_SAFE_GET(eo_obj);
- int i;
- for (i = 0; i < EFL_ANIMATION_EVENT_TYPE_COUNT; i++)
+ if (event_anim->anim &&
+ !event_anim->hide_anim_started && !event_anim->hide_anim_ended)
{
- Event_Animation *event_anims = calloc(1, sizeof(Event_Animation));
- eina_array_push(obj->event_anims, event_anims);
+ event_anim->hide_anim_started = EINA_TRUE;
+
+ _all_animation_objects_cancel(obj);
+
+ //Create animation object to start animation
+ event_anim->anim_obj = efl_animation_object_create(event_anim->anim);
+
+ efl_event_callback_add(event_anim->anim_obj,
+ EFL_ANIMATION_OBJECT_EVENT_ENDED,
+ _animation_hide_end_cb,
+ event_anim);
+
+ //Start animation
+ efl_animation_object_start(event_anim->anim_obj);
}
+ else
+ efl_gfx_visible_set(eo_obj, EINA_FALSE);
}
static void
-_free_event_anims(Evas_Object_Protected_Data *obj)
+_event_anim_free(Event_Animation *event_anim)
{
- int i;
- for (i = 0; i < EFL_ANIMATION_EVENT_TYPE_COUNT; i++)
+ if (event_anim->anim)
{
- Event_Animation *event_anims = eina_array_pop(obj->event_anims);
- if (event_anims) free(event_anims);
+ //Deallocate memory and Unset callbacks for Hide event
+ if (event_anim->desc == EFL_GFX_EVENT_HIDE)
+ {
+ Efl_Canvas_Object *target =
+ efl_animation_target_get(event_anim->anim);
+
+ evas_object_intercept_hide_callback_del(target,
+ _animation_intercept_hide);
+
+ if (event_anim->hide_anim_started &&
+ !event_anim->hide_anim_ended)
+ efl_gfx_visible_set(target, EINA_FALSE);
+ }
}
- eina_array_free(obj->event_anims);
- obj->event_anims = NULL;
+ if (event_anim->anim_obj)
+ {
+ efl_del(event_anim->anim_obj);
+ event_anim->anim_obj = NULL;
+ }
+
+ free(event_anim);
}
EOLIAN static Eo *
obj->data_3d = eina_cow_alloc(evas_object_3d_cow);
obj->mask = eina_cow_alloc(evas_object_mask_cow);
obj->events = eina_cow_alloc(evas_object_events_cow);
- _init_event_anims(obj);
+ obj->event_anims = NULL;
evas_object_inject(eo_obj, obj, evas);
evas_object_callback_init(eo_obj, obj);
eina_cow_free(evas_object_3d_cow, (const Eina_Cow_Data**) &obj->data_3d);
eina_cow_free(evas_object_mask_cow, (const Eina_Cow_Data**) &obj->mask);
eina_cow_free(evas_object_events_cow, (const Eina_Cow_Data**) &obj->events);
- _free_event_anims(obj);
+
+ //Free event animations
+ while (obj->event_anims)
+ {
+ Event_Animation *event_anim =
+ EINA_INLIST_CONTAINER_GET(obj->event_anims, Event_Animation);
+
+ obj->event_anims =
+ eina_inlist_remove(obj->event_anims, obj->event_anims);
+
+ _event_anim_free(event_anim);
+ }
+
efl_data_unref(eo_obj, obj->private_data);
obj->private_data = NULL;
}
static Eina_Bool
-_efl_animation_event_type_is_inform_call(Efl_Animation_Event_Type event)
+_efl_animation_event_type_is_inform_call(const Efl_Event_Description *desc)
{
- if ((event == EFL_ANIMATION_EVENT_TYPE_SHOW) ||
- (event == EFL_ANIMATION_EVENT_TYPE_HIDE))
+ if ((desc == EFL_GFX_EVENT_SHOW) || (desc == EFL_GFX_EVENT_HIDE) ||
+ (desc == EFL_GFX_EVENT_MOVE) || (desc == EFL_GFX_EVENT_RESIZE) ||
+ (desc == EFL_GFX_EVENT_CHANGE_SIZE_HINTS))
return EINA_TRUE;
return EINA_FALSE;
}
-//These macros are matched to Efl_Animation_Event_Type enum values.
-#define EFL_ANIMATION_EVENT_TYPE_SHOW_STR "show"
-#define EFL_ANIMATION_EVENT_TYPE_HIDE_STR "hide"
-#define EFL_ANIMATION_EVENT_TYPE_CLICKED_STR "clicked"
-
-static Efl_Animation_Event_Type
-_efl_animation_event_type_get(const char *event_str)
+static Event_Animation *
+_event_animation_find(Evas_Object_Protected_Data *obj,
+ const Efl_Event_Description *desc)
{
- if (!event_str) return -1;
-
- if (!strncmp(event_str, EFL_ANIMATION_EVENT_TYPE_SHOW_STR,
- strlen(EFL_ANIMATION_EVENT_TYPE_SHOW_STR)))
- return EFL_ANIMATION_EVENT_TYPE_SHOW;
-
- else if (!strncmp(event_str, EFL_ANIMATION_EVENT_TYPE_HIDE_STR,
- strlen(EFL_ANIMATION_EVENT_TYPE_HIDE_STR)))
- return EFL_ANIMATION_EVENT_TYPE_HIDE;
-
- else if (!strncmp(event_str, EFL_ANIMATION_EVENT_TYPE_CLICKED_STR,
- strlen(EFL_ANIMATION_EVENT_TYPE_CLICKED_STR)))
- return EFL_ANIMATION_EVENT_TYPE_CLICKED;
-
- return -1;
-}
-
-static Eina_Bool
-_efl_animation_event_type_is_valid(Efl_Animation_Event_Type event)
-{
- if ((event < 0) || (event >= EFL_ANIMATION_EVENT_TYPE_COUNT))
- return EINA_FALSE;
-
- return EINA_TRUE;
+ Event_Animation *event_anim;
+ EINA_INLIST_FOREACH(obj->event_anims, event_anim)
+ {
+ if (event_anim->desc == desc)
+ return event_anim;
+ }
+ return NULL;
}
static Efl_Animation_Object *
-_event_animation_object_get(Eo *eo_obj, Efl_Animation_Event_Type event_type)
+_event_animation_object_get(Evas_Object_Protected_Data *obj,
+ const Efl_Event_Description *desc)
{
- Evas_Object_Protected_Data *pd = efl_data_scope_get(eo_obj, MY_CLASS);
- if (!pd) return NULL;
-
- if (!_efl_animation_event_type_is_valid(event_type))
- return NULL;
-
- Event_Animation *event_anim = eina_array_data_get(pd->event_anims,
- event_type);
+ Event_Animation *event_anim = _event_animation_find(obj, desc);
if (event_anim && event_anim->anim_obj)
return event_anim->anim_obj;
}
static void
-_all_animation_objects_cancel(Eo *eo_obj)
+_all_animation_objects_cancel(Evas_Object_Protected_Data *obj)
{
- Efl_Animation_Event_Type event_type;
- for (event_type = EFL_ANIMATION_EVENT_TYPE_SHOW;
- event_type < EFL_ANIMATION_EVENT_TYPE_COUNT; event_type++)
+ if (obj->event_anims)
{
- Efl_Animation_Object *anim_obj =
- _event_animation_object_get(eo_obj, event_type);
- if (anim_obj)
- efl_animation_object_cancel(anim_obj);
+ Event_Animation *event_anim;
+ EINA_INLIST_FOREACH(obj->event_anims, event_anim)
+ {
+ if (event_anim && event_anim->anim_obj)
+ {
+ efl_animation_object_cancel(event_anim->anim_obj);
+ event_anim->anim_obj = NULL;
+ }
+ }
}
}
+static void
+_animation_end_cb(void *data, const Efl_Event *event EINA_UNUSED)
+{
+ Event_Animation *event_anim = data;
+
+ //Animation Object is automatically deleted when animation is ended.
+ event_anim->anim_obj = NULL;
+}
+
EOLIAN static Eina_Bool
_efl_canvas_object_efl_object_event_callback_call(Eo *eo_obj,
- Evas_Object_Protected_Data *obj EINA_UNUSED,
+ Evas_Object_Protected_Data *obj,
const Efl_Event_Description *desc,
void *event_info)
{
if (_is_event_blocked(eo_obj, desc, event_info)) return EINA_FALSE;
//Start animation corresponding to the current event
- if (desc && desc->name)
+ if (desc)
{
- Efl_Animation_Event_Type event_type =
- _efl_animation_event_type_get(desc->name);
-
- if (!_efl_animation_event_type_is_inform_call(event_type))
+ if (!_efl_animation_event_type_is_inform_call(desc))
{
- Efl_Animation_Object *anim_obj =
- _event_animation_object_get(eo_obj, event_type);
- if (anim_obj)
+ Event_Animation *event_anim = _event_animation_find(obj, desc);
+ if (event_anim)
{
- _all_animation_objects_cancel(eo_obj);
- efl_animation_object_start(anim_obj);
+ _all_animation_objects_cancel(obj);
+
+ //Create animation object to start animation
+ event_anim->anim_obj =
+ efl_animation_object_create(event_anim->anim);
+
+ efl_event_callback_add(event_anim->anim_obj,
+ EFL_ANIMATION_OBJECT_EVENT_ENDED,
+ _animation_end_cb,
+ event_anim);
+
+ //Start animation
+ efl_animation_object_start(event_anim->anim_obj);
}
}
}
EOLIAN static Eina_Bool
_efl_canvas_object_efl_object_event_callback_legacy_call(Eo *eo_obj,
- Evas_Object_Protected_Data *obj EINA_UNUSED,
+ Evas_Object_Protected_Data *obj,
const Efl_Event_Description *desc,
void *event_info)
{
if (_is_event_blocked(eo_obj, desc, event_info)) return EINA_FALSE;
//Start animation corresponding to the current event
- if (desc && desc->name)
+ if (desc)
{
- Efl_Animation_Event_Type event_type =
- _efl_animation_event_type_get(desc->name);
-
- if (!_efl_animation_event_type_is_inform_call(event_type))
+ if (!_efl_animation_event_type_is_inform_call(desc))
{
- Efl_Animation_Object *anim_obj =
- _event_animation_object_get(eo_obj, event_type);
- if (anim_obj)
+ Event_Animation *event_anim = _event_animation_find(obj, desc);
+ if (event_anim)
{
- _all_animation_objects_cancel(eo_obj);
- efl_animation_object_start(anim_obj);
+ _all_animation_objects_cancel(obj);
+
+ //Create animation object to start animation
+ event_anim->anim_obj =
+ efl_animation_object_create(event_anim->anim);
+
+ efl_event_callback_add(event_anim->anim_obj,
+ EFL_ANIMATION_OBJECT_EVENT_ENDED,
+ _animation_end_cb,
+ event_anim);
+
+ //Start animation
+ efl_animation_object_start(event_anim->anim_obj);
}
}
}
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)
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 EINA_UNUSED)
-{
- Hide_Anim_Data *hide_anim_data = data;
-
- hide_anim_data->anim_ended = EINA_TRUE;
-
- _animation_intercept_hide(hide_anim_data, hide_anim_data->target);
-
- 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_Object *anim_obj =
- _event_animation_object_get(eo_obj, EFL_ANIMATION_EVENT_TYPE_HIDE);
- if (anim_obj && !hide_anim_data->anim_started && !hide_anim_data->anim_ended)
- {
- hide_anim_data->anim_started = EINA_TRUE;
-
- _all_animation_objects_cancel(eo_obj);
- efl_animation_object_start(anim_obj);
- }
- else
- efl_gfx_visible_set(eo_obj, EINA_FALSE);
-}
-
EAPI Eina_Bool
evas_object_visible_get(const Evas_Object *obj)
{
evas_object_update_bounding_box(eo_obj, obj, NULL);
evas_object_inform_call_show(eo_obj);
- //Start animation
- Efl_Animation_Object *anim_obj =
- _event_animation_object_get(eo_obj, EFL_ANIMATION_EVENT_TYPE_SHOW);
- if (anim_obj)
+ Event_Animation *event_anim = _event_animation_find(obj, EFL_GFX_EVENT_SHOW);
+ if (event_anim)
{
- _all_animation_objects_cancel(eo_obj);
- efl_animation_object_start(anim_obj);
+ _all_animation_objects_cancel(obj);
+
+ //Create animation object to start animation
+ event_anim->anim_obj =
+ efl_animation_object_create(event_anim->anim);
+
+ efl_event_callback_add(event_anim->anim_obj,
+ EFL_ANIMATION_OBJECT_EVENT_ENDED,
+ _animation_end_cb,
+ event_anim);
+
+ //Start animation
+ efl_animation_object_start(event_anim->anim_obj);
}
}
EOLIAN void
_efl_canvas_object_event_animation_set(Eo *eo_obj,
Evas_Object_Protected_Data *pd,
- Efl_Animation_Event_Type event_type,
+ const Efl_Event_Description *desc,
Efl_Animation *animation)
{
- if (!_efl_animation_event_type_is_valid(event_type))
- return;
-
- // This may happen if the object never was fully created.
- if (!pd->event_anims) return;
+ Event_Animation *event_anim = _event_animation_find(pd, desc);
- Event_Animation *event_anim =
- eina_array_data_get(pd->event_anims, event_type);
- if (!event_anim) return;
-
- Efl_Animation *cur_anim = event_anim->anim;
- Efl_Animation_Object *cur_anim_obj = event_anim->anim_obj;
-
- //Unset for current event animation
- if (cur_anim)
+ if (event_anim)
{
- Efl_Canvas_Object *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_obj,
- EFL_ANIMATION_OBJECT_EVENT_ENDED,
- _animation_hide_end_cb,
- hide_anim_data);
+ if (event_anim->anim == animation)
+ return;
- if (hide_anim_data->anim_started &&
- !hide_anim_data->anim_ended)
- efl_gfx_visible_set(prev_target, EINA_FALSE);
+ pd->event_anims =
+ eina_inlist_remove(pd->event_anims, EINA_INLIST_GET(event_anim));
- free(hide_anim_data);
- }
- }
-
- //Stop animation
- efl_animation_object_cancel(cur_anim_obj);
-
- /* Delete current animation object because animation object is
- * created in efl_canvas_object_event_animation_set(). */
- efl_del(cur_anim_obj);
+ _event_anim_free(event_anim);
}
- Efl_Animation *new_anim = animation;
- Efl_Animation_Object *new_anim_obj = NULL;
-
- //Set for new event animation
- if (new_anim)
- {
- //Set target object for the given animation
- Efl_Canvas_Object *target = efl_animation_target_get(new_anim);
- if (!target)
- target = eo_obj;
- efl_animation_target_set(new_anim, target);
+ if (!animation) return;
- new_anim_obj = efl_animation_object_create(new_anim);
+ event_anim = calloc(1, sizeof(Event_Animation));
- /* Event animation object should not be deleted after animation is
- * cancelled or finished */
- efl_animation_object_auto_del_set(new_anim_obj, EINA_FALSE);
+ //Set target object for the given animation
+ Efl_Canvas_Object *target = efl_animation_target_get(animation);
+ if (!target)
+ target = eo_obj;
+ efl_animation_target_set(animation, 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->target = target;
- 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_obj,
- EFL_ANIMATION_OBJECT_EVENT_ENDED,
- _animation_hide_end_cb,
- hide_anim_data);
- }
+ //Set callback for Hide event
+ if (desc == EFL_GFX_EVENT_HIDE)
+ {
+ evas_object_intercept_hide_callback_add(target,
+ _animation_intercept_hide,
+ event_anim);
}
- //Replace current event animation with new event animation
- event_anim->anim = new_anim;
- event_anim->anim_obj = new_anim_obj;
+ event_anim->desc = desc;
+ event_anim->anim = animation;
+ event_anim->anim_obj = NULL;
+ event_anim->hide_anim_started = EINA_FALSE;
+ event_anim->hide_anim_ended = EINA_FALSE;
+
+ pd->event_anims =
+ eina_inlist_append(pd->event_anims, EINA_INLIST_GET(event_anim));
}
EOLIAN Efl_Animation *
_efl_canvas_object_event_animation_get(Eo *eo_obj EINA_UNUSED,
Evas_Object_Protected_Data *pd,
- Efl_Animation_Event_Type event_type)
+ const Efl_Event_Description *desc)
{
- if (!_efl_animation_event_type_is_valid(event_type))
- return NULL;
-
- Event_Animation *event_anim = eina_array_data_get(pd->event_anims,
- event_type);
+ Event_Animation *event_anim = _event_animation_find(pd, desc);
if (event_anim && event_anim->anim)
- return event_anim->anim;
+ return event_anim->anim_obj;
return NULL;
}
* animation is cancelled and show operation is proceeded. */
Eina_Bool
_efl_canvas_object_event_animation_is_running(Eo *eo_obj,
- Efl_Animation_Event_Type event)
+ const Efl_Event_Description *desc)
{
- if (_event_animation_object_get(eo_obj, event))
+ Evas_Object_Protected_Data *obj = EVAS_OBJECT_DATA_SAFE_GET(eo_obj);
+
+ if (_event_animation_object_get(obj, desc))
return EINA_TRUE;
return EINA_FALSE;
void
_efl_canvas_object_event_animation_cancel(Eo *eo_obj)
{
- _all_animation_objects_cancel(eo_obj);
+ Evas_Object_Protected_Data *obj = EVAS_OBJECT_DATA_SAFE_GET(eo_obj);
+
+ _all_animation_objects_cancel(obj);
}