257 lines
9.4 KiB
C
257 lines
9.4 KiB
C
#include "efl_animation_object_group_parallel_private.h"
|
|
|
|
/* Add member object data and append the data to the member object data list.
|
|
* The member object data contains the repeated count of the member object.
|
|
*/
|
|
static void
|
|
_member_anim_obj_data_add(Efl_Animation_Object_Group_Parallel_Data *pd,
|
|
Efl_Animation_Object *anim_obj,
|
|
int repeated_count)
|
|
{
|
|
Member_Object_Data *member_anim_obj_data =
|
|
calloc(1, sizeof(Member_Object_Data));
|
|
|
|
if (!member_anim_obj_data) return;
|
|
|
|
member_anim_obj_data->anim_obj = anim_obj;
|
|
member_anim_obj_data->repeated_count = repeated_count;
|
|
|
|
pd->member_anim_obj_data_list =
|
|
eina_list_append(pd->member_anim_obj_data_list, member_anim_obj_data);
|
|
}
|
|
|
|
/* Find the member object data which contains the repeated count of the member
|
|
* object. */
|
|
static Member_Object_Data *
|
|
_member_anim_obj_data_find(Efl_Animation_Object_Group_Parallel_Data *pd,
|
|
Efl_Animation_Object *anim_obj)
|
|
{
|
|
Eina_List *l;
|
|
Member_Object_Data *member_anim_obj_data = NULL;
|
|
EINA_LIST_FOREACH(pd->member_anim_obj_data_list, l, member_anim_obj_data)
|
|
{
|
|
if (member_anim_obj_data->anim_obj == anim_obj)
|
|
break;
|
|
}
|
|
|
|
return member_anim_obj_data;
|
|
}
|
|
|
|
/* Delete member object data and remove the data from the member object data
|
|
* list.
|
|
* The member object data contains the repeated count of the member object.
|
|
*/
|
|
static void
|
|
_member_anim_obj_data_del(Efl_Animation_Object_Group_Parallel_Data *pd,
|
|
Efl_Animation_Object *anim_obj)
|
|
{
|
|
Member_Object_Data *member_anim_obj_data = _member_anim_obj_data_find(pd, anim_obj);
|
|
if (member_anim_obj_data)
|
|
{
|
|
pd->member_anim_obj_data_list =
|
|
eina_list_remove(pd->member_anim_obj_data_list, member_anim_obj_data);
|
|
free(member_anim_obj_data);
|
|
}
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_animation_object_group_parallel_efl_animation_object_group_object_add(Eo *eo_obj,
|
|
Efl_Animation_Object_Group_Parallel_Data *pd,
|
|
Efl_Animation_Object *anim_obj)
|
|
{
|
|
if (!anim_obj) return;
|
|
|
|
efl_animation_object_group_object_add(efl_super(eo_obj, MY_CLASS), anim_obj);
|
|
|
|
/* Add member object data and append the data to the member object data
|
|
* list. */
|
|
_member_anim_obj_data_add(pd, anim_obj, 0);
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_animation_object_group_parallel_efl_animation_object_group_object_del(Eo *eo_obj,
|
|
Efl_Animation_Object_Group_Parallel_Data *pd EINA_UNUSED,
|
|
Efl_Animation_Object *anim_obj)
|
|
{
|
|
if (!anim_obj) return;
|
|
|
|
efl_animation_object_group_object_del(efl_super(eo_obj, MY_CLASS), anim_obj);
|
|
|
|
/* Delete member object data and remove the data from the member object
|
|
* data list. */
|
|
_member_anim_obj_data_del(pd, anim_obj);
|
|
}
|
|
|
|
EOLIAN static double
|
|
_efl_animation_object_group_parallel_efl_animation_object_total_duration_get(Eo *eo_obj,
|
|
Efl_Animation_Object_Group_Parallel_Data *pd EINA_UNUSED)
|
|
{
|
|
Eina_List *anim_objs = efl_animation_object_group_objects_get(eo_obj);
|
|
if (!anim_objs) return 0.0;
|
|
|
|
double total_duration = 0.0;
|
|
Eina_List *l;
|
|
Efl_Animation *anim_obj;
|
|
EINA_LIST_FOREACH(anim_objs, l, anim_obj)
|
|
{
|
|
double child_total_duration =
|
|
efl_animation_object_total_duration_get(anim_obj);
|
|
|
|
double start_delay = efl_animation_object_start_delay_get(anim_obj);
|
|
if (start_delay > 0.0)
|
|
child_total_duration += start_delay;
|
|
|
|
int child_repeat_count =
|
|
efl_animation_object_repeat_count_get(anim_obj);
|
|
if (child_repeat_count > 0)
|
|
child_total_duration *= (child_repeat_count + 1);
|
|
|
|
if (child_total_duration > total_duration)
|
|
total_duration = child_total_duration;
|
|
}
|
|
return total_duration;
|
|
}
|
|
|
|
//Set how many times the given object has been repeated.
|
|
static void
|
|
_repeated_count_set(Efl_Animation_Object_Group_Parallel_Data *pd,
|
|
Efl_Animation_Object *anim_obj,
|
|
int repeated_count)
|
|
{
|
|
|
|
Member_Object_Data *member_anim_obj_data =
|
|
_member_anim_obj_data_find(pd, anim_obj);
|
|
if (!member_anim_obj_data) return;
|
|
|
|
member_anim_obj_data->repeated_count = repeated_count;
|
|
}
|
|
|
|
//Get how many times the given object has been repeated.
|
|
static int
|
|
_repeated_count_get(Efl_Animation_Object_Group_Parallel_Data *pd,
|
|
Efl_Animation_Object *anim_obj)
|
|
{
|
|
Member_Object_Data *member_anim_obj_data =
|
|
_member_anim_obj_data_find(pd, anim_obj);
|
|
if (!member_anim_obj_data) return 0;
|
|
|
|
return member_anim_obj_data->repeated_count;
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_animation_object_group_parallel_efl_animation_object_progress_set(Eo *eo_obj,
|
|
Efl_Animation_Object_Group_Parallel_Data *pd,
|
|
double progress)
|
|
{
|
|
if ((progress < 0.0) || (progress > 1.0)) return;
|
|
|
|
Eina_List *anim_objs = efl_animation_object_group_objects_get(eo_obj);
|
|
if (!anim_objs) return;
|
|
|
|
double group_total_duration =
|
|
efl_animation_object_total_duration_get(eo_obj);
|
|
|
|
double elapsed_time = progress * group_total_duration;
|
|
|
|
Eina_List *l;
|
|
Efl_Animation_Object *anim_obj;
|
|
EINA_LIST_FOREACH(anim_objs, l, anim_obj)
|
|
{
|
|
double total_duration =
|
|
efl_animation_object_total_duration_get(anim_obj);
|
|
double start_delay = efl_animation_object_start_delay_get(anim_obj);
|
|
double anim_obj_progress;
|
|
|
|
Eina_Bool start_repeat = EINA_FALSE;
|
|
|
|
if (total_duration == 0.0)
|
|
anim_obj_progress = 1.0;
|
|
else
|
|
{
|
|
double elapsed_time_without_delay;
|
|
|
|
//If object is repeated, then recalculate progress.
|
|
int repeated_count = _repeated_count_get(pd, anim_obj);
|
|
if (repeated_count > 0)
|
|
elapsed_time_without_delay =
|
|
(elapsed_time - ((total_duration + start_delay) * repeated_count)) - start_delay;
|
|
else
|
|
elapsed_time_without_delay = elapsed_time - start_delay;
|
|
|
|
//Object should not start to wait for start delay time.
|
|
if (elapsed_time_without_delay < 0.0) continue;
|
|
|
|
anim_obj_progress = elapsed_time_without_delay / total_duration;
|
|
|
|
if (anim_obj_progress > 1.0)
|
|
anim_obj_progress = 1.0;
|
|
|
|
//Animation has been finished.
|
|
if (anim_obj_progress == 1.0)
|
|
{
|
|
/* If object is finished and it should be repeated, then
|
|
* increate the repeated count to recalculate progress. */
|
|
int repeat_count =
|
|
efl_animation_object_repeat_count_get(anim_obj);
|
|
if (repeat_count > 0)
|
|
{
|
|
repeated_count = _repeated_count_get(pd, anim_obj);
|
|
if (repeated_count < repeat_count)
|
|
{
|
|
repeated_count++;
|
|
_repeated_count_set(pd, anim_obj, repeated_count);
|
|
|
|
start_repeat = EINA_TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* If object is repeated with reverse mode, then the progress value
|
|
* should be modified as (1.0 - progress). */
|
|
Efl_Animation_Object_Repeat_Mode repeat_mode
|
|
= efl_animation_object_repeat_mode_get(anim_obj);
|
|
if (repeat_mode == EFL_ANIMATION_OBJECT_REPEAT_MODE_REVERSE)
|
|
{
|
|
int repeated_count = _repeated_count_get(pd, anim_obj);
|
|
if (repeated_count > 0)
|
|
{
|
|
if ((((repeated_count % 2) == 1) && (!start_repeat)) ||
|
|
(((repeated_count % 2) == 0) && (start_repeat)))
|
|
anim_obj_progress = 1.0 - anim_obj_progress;
|
|
}
|
|
}
|
|
|
|
//Apply interpolator
|
|
Efl_Interpolator *group_interp =
|
|
efl_animation_object_interpolator_get(eo_obj);
|
|
|
|
/* If group interpolator exists, then the group interpolator has been
|
|
* already applied. So it is not needed to apply interpolator again. */
|
|
if (!group_interp)
|
|
{
|
|
Efl_Interpolator *interpolator =
|
|
efl_animation_object_interpolator_get(anim_obj);
|
|
if (interpolator)
|
|
{
|
|
anim_obj_progress =
|
|
efl_interpolator_interpolate(interpolator,
|
|
anim_obj_progress);
|
|
}
|
|
}
|
|
|
|
efl_animation_object_progress_set(anim_obj, anim_obj_progress);
|
|
}
|
|
|
|
efl_animation_object_progress_set(efl_super(eo_obj, MY_CLASS), progress);
|
|
}
|
|
|
|
/* Internal EO APIs */
|
|
|
|
#define EFL_ANIMATION_OBJECT_GROUP_PARALLEL_EXTRA_OPS \
|
|
EFL_OBJECT_OP_FUNC(efl_animation_object_group_object_add, _efl_animation_object_group_parallel_efl_animation_object_group_object_add), \
|
|
EFL_OBJECT_OP_FUNC(efl_animation_object_group_object_del, _efl_animation_object_group_parallel_efl_animation_object_group_object_del), \
|
|
EFL_OBJECT_OP_FUNC(efl_animation_object_total_duration_get, _efl_animation_object_group_parallel_efl_animation_object_total_duration_get)
|
|
|
|
#include "efl_animation_object_group_parallel.eo.c"
|