Efl.Ui.Animation_View: Implement Min/Max_Progress/Frame_Set/Get

Summary:
Implements APIs to set the range when playing.
If we set progress or frame's min and max, it will play within the set value.
keyframe sets the value based on min/max, not the whole frame.

void efl_ui_animation_view_min_progress_set(Eo *obj, double min_progress);
double efl_ui_animation_view_min_progress_get(const Eo *obj);
void efl_ui_animation_view_max_progress_set(Eo *obj, double max_progress);
double efl_ui_animation_view_max_progress_get(const Eo *obj);
void efl_ui_animation_view_min_frame_set(Eo *obj, int min_frame);
int efl_ui_animation_view_min_frame_get(const Eo *obj);
void efl_ui_animation_view_max_frame_set(Eo *obj, int max_frame);
int efl_ui_animation_view_max_frame_get(const Eo *obj);

Test Plan:
Evas_Object *anim_view = elm_animation_view_add(win);
elm_animation_view_auto_repeat_set(anim_view, 1);
elm_animation_view_file_set(anim_view, "a.json", NULL);
elm_animation_view_play(anim_view);
evas_object_show(anim_view);

evas_object_size_hint_align_set(anim_view, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(anim_view, 1, 1);

elm_animation_view_min_progress_set(anim_view, 0.3);
elm_animation_view_max_progress_set(anim_view, 0.8);

//or
elm_animation_view_min_frame_set(anim_view, 5);
elm_animation_view_max_frame_set(anim_view, 15);

Reviewers: Hermet

Subscribers: cedric, smohanty, #reviewers, SanghyeonLee, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D7818
This commit is contained in:
junsu choi 2019-01-29 18:59:51 +09:00 committed by Hermet Park
parent d3ec5efdea
commit 28eeccdf61
3 changed files with 160 additions and 2 deletions

View File

@ -170,7 +170,9 @@ _transit_cb(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress)
else pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY;
pd->keyframe = progress;
evas_object_vg_animated_frame_set(pd->vg, (int) ((pd->frame_cnt - 1) * progress));
int minframe = (pd->frame_cnt - 1) * pd->min_progress;
int maxframe = (pd->frame_cnt - 1) * pd->max_progress;
evas_object_vg_animated_frame_set(pd->vg, (int)((maxframe - minframe) * progress) + minframe);
if (pd->auto_repeat)
{
@ -199,6 +201,8 @@ _efl_ui_animation_view_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Animation_View
priv->vg = vg;
priv->speed = 1;
priv->frame_duration = 0;
priv->min_progress = 0.0;
priv->max_progress = 1.0;
}
EOLIAN static void
@ -233,6 +237,18 @@ _efl_ui_animation_view_efl_object_constructor(Eo *obj,
return obj;
}
static void
_update_frame_duration(Efl_Ui_Animation_View_Data *pd)
{
int frame_count = evas_object_vg_animated_frame_count_get(pd->vg);
int min_frame = (frame_count - 1) * pd->min_progress;
int max_frame = (frame_count - 1) * pd->max_progress;
double frame_rate = round((double)frame_count / evas_object_vg_animated_frame_duration_get(pd->vg, 0, 0));
pd->frame_duration = (double)(max_frame - min_frame) / frame_rate;
elm_transit_duration_set(pd->transit, pd->frame_duration * (1/pd->speed));
}
static Eina_Bool
_ready_play(Efl_Ui_Animation_View_Data *pd)
{
@ -250,11 +266,14 @@ _ready_play(Efl_Ui_Animation_View_Data *pd)
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, pd->vg);
if (pd->auto_repeat) elm_transit_repeat_times_set(transit, -1);
elm_transit_duration_set(transit, pd->frame_duration * (1/pd->speed));
elm_transit_effect_add(transit, _transit_cb, pd, _transit_del_cb);
elm_transit_progress_value_set(transit, pd->keyframe);
elm_transit_objects_final_state_keep_set(transit, EINA_TRUE);
pd->transit = transit;
if (pd->min_progress != 0.0 || pd->max_progress != 1.0)
_update_frame_duration(pd);
else
elm_transit_duration_set(transit, pd->frame_duration * (1/pd->speed));
return EINA_TRUE;
}
@ -561,6 +580,78 @@ _efl_ui_animation_view_frame_count_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animati
return evas_object_vg_animated_frame_count_get(pd->vg);
}
EOLIAN static void
_efl_ui_animation_view_min_progress_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, double min_progress)
{
if (min_progress < 0.0 || min_progress > 1.0 || min_progress > pd->max_progress) return;
pd->min_progress = min_progress;
_update_frame_duration(pd);
}
EOLIAN static double
_efl_ui_animation_view_min_progress_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
{
return pd->min_progress;
}
EOLIAN static void
_efl_ui_animation_view_max_progress_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, double max_progress)
{
if (max_progress < 0.0 || max_progress > 1.0 || max_progress < pd->min_progress) return;
pd->max_progress = max_progress;
_update_frame_duration(pd);
}
EOLIAN static double
_efl_ui_animation_view_max_progress_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
{
return pd->max_progress;
}
EOLIAN static void
_efl_ui_animation_view_min_frame_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, int min_frame)
{
int frame_count = evas_object_vg_animated_frame_count_get(pd->vg);
if (min_frame < 0) min_frame = 0;
else
{
int max_frame = (frame_count - 1) * pd->max_progress;
if (min_frame > max_frame) min_frame = max_frame;
}
pd->min_progress = (double)min_frame / (double)(frame_count - 1);
_update_frame_duration(pd);
}
EOLIAN static int
_efl_ui_animation_view_min_frame_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
{
return pd->min_progress * (evas_object_vg_animated_frame_count_get(pd->vg) - 1);
}
EOLIAN static void
_efl_ui_animation_view_max_frame_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, int max_frame)
{
int frame_count = evas_object_vg_animated_frame_count_get(pd->vg);
if (max_frame > frame_count - 1) max_frame = frame_count - 1;
else
{
int min_frame = (frame_count - 1) * pd->min_progress;
if (min_frame > max_frame) max_frame = min_frame;
}
pd->max_progress = (double)max_frame / (double)(frame_count - 1);
_update_frame_duration(pd);
}
EOLIAN static int
_efl_ui_animation_view_max_frame_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
{
return pd->max_progress * (evas_object_vg_animated_frame_count_get(pd->vg) - 1);
}
EAPI Elm_Animation_View*
elm_animation_view_add(Evas_Object *parent)
{

View File

@ -188,6 +188,71 @@ class Efl.Ui.Animation_View extends Efl.Ui.Widget implements Efl.Gfx.View, Efl.F
frame_count: int; [[ The number of frames. 0, if it's not animated.]]
}
}
@property min_progress {
[[ The start progress of the play.
Default value is 0.
]]
set {
[[Set start progress of an animation object.
@since 1.22]]
}
get {
[[Returns start progress of an animation object.
@since 1.22]]
}
values {
min_progress: double; [[ The minimum progress. Value must be 0 ~ 1. ]]
}
}
@property max_progress {
[[ The last progress of the play.
Default value is 1.
]]
set {
[[Set last progress of an animation object.
@since 1.22]]
}
get {
[[Returns last progress of an animation object.
@since 1.22]]
}
values {
max_progress: double; [[ The maximum progress. Value must be 0 ~ 1. ]]
}
}
@property min_frame {
[[ The start frame of the play.
Default value is 0.
]]
set {
[[Set minimum frame of an animation object.
@since 1.22]]
}
get {
[[Returns minimum frame of an animation object.
@since 1.22]]
}
values {
min_frame: int; [[ The minimum frame for play. Value must be 0 ~ @.max_frame ]]
}
}
@property max_frame {
[[ The last frame of the play.
Default value is @.frame_count - 1
]]
set {
[[Set maximum frame of an animation object.
@since 1.22]]
}
get {
[[Returns maximum frame of an animation object.
@since 1.22]]
}
values {
max_frame: int; [[ The maximum frame for play. Value must be @.min_frame ~ (@.frame_count - 1) ]]
}
}
}
implements {
Efl.Object.constructor;

View File

@ -18,6 +18,8 @@ struct _Efl_Ui_Animation_View_Data
double frame_cnt;
int repeat_times;
double frame_duration;
double min_progress;
double max_progress;
Eina_Bool play_back : 1;
Eina_Bool auto_play : 1;