From 28eeccdf6144e110f0091d9239d6c7fb485f2bcb Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Tue, 29 Jan 2019 18:59:51 +0900 Subject: [PATCH] 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 --- src/lib/elementary/efl_ui_animation_view.c | 95 ++++++++++++++++++- src/lib/elementary/efl_ui_animation_view.eo | 65 +++++++++++++ .../efl_ui_animation_view_private.h | 2 + 3 files changed, 160 insertions(+), 2 deletions(-) diff --git a/src/lib/elementary/efl_ui_animation_view.c b/src/lib/elementary/efl_ui_animation_view.c index ba80700342..1a562c903b 100644 --- a/src/lib/elementary/efl_ui_animation_view.c +++ b/src/lib/elementary/efl_ui_animation_view.c @@ -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) { diff --git a/src/lib/elementary/efl_ui_animation_view.eo b/src/lib/elementary/efl_ui_animation_view.eo index 4b4d750a4e..b1ec1e6c26 100644 --- a/src/lib/elementary/efl_ui_animation_view.eo +++ b/src/lib/elementary/efl_ui_animation_view.eo @@ -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; diff --git a/src/lib/elementary/efl_ui_animation_view_private.h b/src/lib/elementary/efl_ui_animation_view_private.h index 0585b694c5..183d076dc6 100644 --- a/src/lib/elementary/efl_ui_animation_view_private.h +++ b/src/lib/elementary/efl_ui_animation_view_private.h @@ -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;