efl_ui_animation_view: introduce a new widget for controlling vector animation.

Summary:
This is a new convenient ui control that designed to load vector resources
-svg, json-, and control animations if it supports.

Please turn on evas-loaders-json in meson options,
if you'd like to use Lottie Animation.

Co-authored-by: JunsuChoi <jsuya.choi@samsung.com>

@feature

Reviewers: #committers, jsuya, zmike, bu5hm4n

Reviewed By: #committers, bu5hm4n

Subscribers: zmike, bu5hm4n, cedric, #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D9451
This commit is contained in:
Hermet Park 2019-08-21 17:39:43 +09:00
parent 5f4c9a4458
commit 8900cf0715
13 changed files with 1868 additions and 0 deletions

View File

@ -209,6 +209,7 @@ EAPI void efl_ui_focus_relation_free(Efl_Ui_Focus_Relations *rel);
# include <efl_ui_text_async.eo.h>
# endif
# include <efl_ui_animation_view.h>
# include <efl_ui_clock.h>
# include <efl_ui_image_factory.eo.h>
# include <efl_ui_video.h>

View File

@ -212,6 +212,7 @@ typedef Eo Efl_Ui_Focus_Manager;
#include <elm_button.h>
#include <elm_cache.h>
#include <elm_calendar.h>
#include <efl_ui_animation_view.h>
#include <efl_ui_calendar.h>
#include <elm_check.h>
#include <elm_clock.h>
@ -350,6 +351,7 @@ typedef Eo Efl_Ui_Focus_Manager;
# include <efl_ui_dnd.eo.h>
# include <efl_ui_dnd_container.eo.h>
# include <efl_ui_relative_layout.eo.h>
# include <efl_ui_animation_view.eo.h>
# include <efl_ui_tab_bar.eo.h>
# include <efl_ui_tab_page.eo.h>
# include <efl_ui_tab_page_part_tab.eo.h>

View File

@ -0,0 +1,735 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#define EFL_ACCESS_OBJECT_PROTECTED
#include <Elementary.h>
#include "elm_priv.h"
#include "efl_ui_animation_view_private.h"
#define MY_CLASS EFL_UI_ANIMATION_VIEW_CLASS
#define MY_CLASS_NAME "Efl_Ui_Animation_View"
#define MY_CLASS_NAME_LEGACY "efl_ui_animation_view"
static const char SIG_FOCUSED[] = "focused";
static const char SIG_UNFOCUSED[] = "unfocused";
static const char SIG_PLAY_START[] = "play,start";
static const char SIG_PLAY_REPEAT[] = "play,repeat";
static const char SIG_PLAY_DONE[] = "play,done";
static const char SIG_PLAY_PAUSE[] = "play,pause";
static const char SIG_PLAY_RESUME[] = "play,resume";
static const char SIG_PLAY_STOP[] = "play,stop";
static const char SIG_PLAY_UPDATE[] = "play,update";
/* smart callbacks coming from Efl_Ui_Animation_View objects: */
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
{SIG_FOCUSED, ""},
{SIG_UNFOCUSED, ""},
{SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
{SIG_PLAY_START, ""},
{SIG_PLAY_REPEAT, ""},
{SIG_PLAY_DONE, ""},
{SIG_PLAY_PAUSE, ""},
{SIG_PLAY_RESUME, ""},
{SIG_PLAY_STOP, ""},
{NULL, NULL}
};
static void
_sizing_eval(Eo *obj, void *data)
{
Efl_Ui_Animation_View_Data *pd = data;
if (!efl_file_loaded_get(obj)) return;
double hw,hh;
efl_gfx_hint_weight_get(obj, &hw, &hh);
Eina_Size2D size = efl_canvas_vg_object_default_size_get(pd->vg);
Eina_Size2D min = {-1, -1};
if (hw == 0) min.w = size.w;
if (hh == 0) min.h = size.h;
efl_gfx_hint_size_min_set(obj, min);
}
static void
_size_hint_event_cb(void *data, const Efl_Event *event)
{
_sizing_eval(event->object, data);
}
static void
_transit_go_facade(Eo* obj, Efl_Ui_Animation_View_Data *pd)
{
pd->repeat_times = 0;
if (pd->play_back)
pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK;
else
pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY;
evas_object_smart_callback_call(obj, SIG_PLAY_START, NULL);
if (pd->transit) elm_transit_go(pd->transit);
}
static Eina_Bool
_visible_check(Eo *obj)
{
if (!efl_gfx_entity_visible_get(obj)) return EINA_FALSE;
//TODO: Check Smart parents visibilities?
Eina_Size2D size = efl_gfx_entity_size_get(obj);
if (size.w == 0 || size.h == 0) return EINA_FALSE;
Evas_Coord output_w, output_h;
evas_output_size_get(evas_object_evas_get(obj), &output_w, &output_h);
Eina_Position2D pos = efl_gfx_entity_position_get(obj);
//Outside viewport
if ((pos.x + size.w < 0) || (pos.x > output_w) ||
(pos.y + size.h < 0) || (pos.y > output_h))
return EINA_FALSE;
//Inside viewport
return EINA_TRUE;
}
static void
_auto_play(Eo *obj, Efl_Ui_Animation_View_Data *pd, Eina_Bool vis)
{
if (!pd->auto_play || !pd->transit) return;
//Resume Animation
if (vis)
{
if (pd->state == EFL_UI_ANIMATION_VIEW_STATE_PAUSE && pd->auto_play_pause)
{
elm_transit_paused_set(pd->transit, EINA_FALSE);
if (pd->play_back)
pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK;
else
pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY;
pd->auto_play_pause = EINA_FALSE;
evas_object_smart_callback_call(obj, SIG_PLAY_RESUME, NULL);
}
}
//Pause Animation
else
{
if ((pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY) ||
(pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK))
{
elm_transit_paused_set(pd->transit, EINA_TRUE);
pd->state = EFL_UI_ANIMATION_VIEW_STATE_PAUSE;
pd->auto_play_pause = EINA_TRUE;
evas_object_smart_callback_call(obj, SIG_PLAY_PAUSE, NULL);
}
}
}
static void
_transit_del_cb(Elm_Transit_Effect *effect, Elm_Transit *transit)
{
Eo *obj = (Eo *) effect;
EFL_UI_ANIMATION_VIEW_DATA_GET(obj, pd);
if (!pd) return;
if ((pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY && pd->progress == 1) ||
(pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK && pd->progress == 0))
evas_object_smart_callback_call(obj, SIG_PLAY_DONE, NULL);
if (pd->transit != transit) return;
Efl_Ui_Animation_View_State prev_state = pd->state;
pd->state = EFL_UI_ANIMATION_VIEW_STATE_STOP;
pd->transit = NULL;
pd->auto_play_pause = EINA_FALSE;
if (prev_state != EFL_UI_ANIMATION_VIEW_STATE_STOP)
{
evas_object_smart_callback_call(obj, SIG_PLAY_STOP, NULL);
pd->progress = 0;
}
}
static void
_transit_cb(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress)
{
Eo *obj = (Eo *) effect;
EFL_UI_ANIMATION_VIEW_DATA_GET(obj, pd);
if (!pd || !pd->vg)
{
ERR("Vector Object is removed in wrong way!, Efl_Ui_Animation_View = %p", obj);
elm_transit_del(transit);
return;
}
if (pd->play_back)
{
pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK;
progress = 1 - progress;
}
else pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY;
pd->progress = progress;
int minframe = (pd->frame_cnt - 1) * pd->min_progress;
int maxframe = (pd->frame_cnt - 1) * pd->max_progress;
int update_frame = (int)((maxframe - minframe) * progress) + minframe;
int current_frame = evas_object_vg_animated_frame_get(pd->vg);
evas_object_vg_animated_frame_set(pd->vg, update_frame);
if (pd->auto_repeat)
{
int repeat_times = elm_transit_current_repeat_times_get(pd->transit);
if (pd->repeat_times != repeat_times)
{
evas_object_smart_callback_call(obj, SIG_PLAY_REPEAT, NULL);
pd->repeat_times = repeat_times;
}
}
//transit_cb is always called with a progress value 0 ~ 1.
//SIG_PLAY_UPDATE callback is called only when there is a real change.
if (update_frame != current_frame)
evas_object_smart_callback_call(obj, SIG_PLAY_UPDATE, NULL);
}
EOLIAN static void
_efl_ui_animation_view_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Animation_View_Data *priv)
{
efl_canvas_group_add(efl_super(obj, MY_CLASS));
elm_widget_sub_object_parent_add(obj);
// Create vg to render vector animation
Eo *vg = evas_object_vg_add(evas_object_evas_get(obj));
elm_widget_resize_object_set(obj, vg);
efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED, _size_hint_event_cb, priv);
priv->vg = vg;
priv->speed = 1;
priv->frame_duration = 0;
priv->min_progress = 0.0;
priv->max_progress = 1.0;
}
EOLIAN static void
_efl_ui_animation_view_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Animation_View_Data *pd EINA_UNUSED)
{
if (pd->transit)
{
Elm_Transit *transit = pd->transit;
pd->transit = NULL; //Skip perform transit_del_cb()
elm_transit_del(transit);
}
pd->state = EFL_UI_ANIMATION_VIEW_STATE_NOT_READY;
efl_canvas_group_del(efl_super(obj, MY_CLASS));
}
EOLIAN static void
_efl_ui_animation_view_efl_object_destructor(Eo *obj,
Efl_Ui_Animation_View_Data *pd EINA_UNUSED)
{
efl_destructor(efl_super(obj, MY_CLASS));
}
EOLIAN static Eo *
_efl_ui_animation_view_efl_object_constructor(Eo *obj,
Efl_Ui_Animation_View_Data *pd EINA_UNUSED)
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
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;
if (pd->transit)
elm_transit_duration_set(pd->transit, pd->frame_duration * (1/pd->speed));
}
static Eina_Bool
_ready_play(Eo *obj, Efl_Ui_Animation_View_Data *pd)
{
pd->auto_play_pause = EINA_FALSE;
pd->state = EFL_UI_ANIMATION_VIEW_STATE_STOP;
if (pd->transit) elm_transit_del(pd->transit);
pd->frame_cnt = (double) evas_object_vg_animated_frame_count_get(pd->vg);
pd->frame_duration = evas_object_vg_animated_frame_duration_get(pd->vg, 0, 0);
evas_object_vg_animated_frame_set(pd->vg, 0);
if (pd->frame_duration > 0)
{
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_effect_add(transit, _transit_cb, obj, _transit_del_cb);
elm_transit_progress_value_set(transit, pd->progress);
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;
}
return EINA_FALSE;
}
EOLIAN static void
_efl_ui_animation_view_efl_file_unload(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
{
pd->state = EFL_UI_ANIMATION_VIEW_STATE_NOT_READY;
pd->frame_cnt = 0;
pd->frame_duration = 0;
if (pd->transit) elm_transit_del(pd->transit);
}
EOLIAN static Eina_Error
_efl_ui_animation_view_efl_file_load(Eo *obj, Efl_Ui_Animation_View_Data *pd)
{
Eina_Error err;
Eina_Bool ret;
const char *file;
const char *key;
if (efl_file_loaded_get(obj)) return 0;
err = efl_file_load(efl_super(obj, MY_CLASS));
if (err) return err;
file = efl_file_get(obj);
key = efl_file_key_get(obj);
ret = efl_file_simple_load(pd->vg, file, key);
if (!ret)
{
efl_file_unload(obj);
return eina_error_get();
}
pd->progress = 0;
_sizing_eval(obj, pd);
if (!_ready_play(obj, pd)) return 1;
if (pd->auto_play)
{
_transit_go_facade(obj, pd);
if (!_visible_check(obj))
{
elm_transit_paused_set(pd->transit, EINA_TRUE);
pd->state = EFL_UI_ANIMATION_VIEW_STATE_PAUSE;
pd->auto_play_pause = EINA_TRUE;
evas_object_smart_callback_call(obj, SIG_PLAY_PAUSE, NULL);
}
}
return 0;
}
EOLIAN static void
_efl_ui_animation_view_efl_gfx_entity_position_set(Eo *obj,
Efl_Ui_Animation_View_Data *pd,
Eina_Position2D pos EINA_UNUSED)
{
if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_MOVE, 0, pos.x, pos.y))
return;
efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
_auto_play(obj, pd, _visible_check(obj));
}
EOLIAN static void
_efl_ui_animation_view_efl_gfx_entity_size_set(Eo *obj,
Efl_Ui_Animation_View_Data *pd,
Eina_Size2D size)
{
if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_RESIZE, 0, size.w, size.h))
return;
efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), size);
_sizing_eval(obj, pd);
_auto_play(obj, pd, _visible_check(obj));
}
EOLIAN static void
_efl_ui_animation_view_efl_gfx_entity_visible_set(Eo *obj,
Efl_Ui_Animation_View_Data *pd,
Eina_Bool vis)
{
if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_VISIBLE, 0, vis))
return;
efl_gfx_entity_visible_set(efl_super(obj, MY_CLASS), vis);
_auto_play(obj, pd, _visible_check(obj));
}
EOLIAN static void
_efl_ui_animation_view_efl_gfx_view_view_size_set(Eo *obj EINA_UNUSED,
Efl_Ui_Animation_View_Data *pd,
Eina_Size2D size)
{
Eina_Rect viewbox;
viewbox.x = viewbox.y =0;
viewbox.w = size.w;
viewbox.h = size.h;
efl_canvas_vg_object_viewbox_set(pd->vg, viewbox);
}
EOLIAN Eina_Size2D
_efl_ui_animation_view_efl_gfx_view_view_size_get(const Eo *obj EINA_UNUSED,
Efl_Ui_Animation_View_Data *pd)
{
Eina_Rect viewbox = efl_canvas_vg_object_viewbox_get(pd->vg);
return EINA_SIZE2D(viewbox.w, viewbox.h);
}
EOLIAN static void
_efl_ui_animation_view_auto_repeat_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, Eina_Bool auto_repeat)
{
if (pd->auto_repeat == auto_repeat) return;
pd->auto_repeat = auto_repeat;
if (pd->transit)
{
if (auto_repeat) elm_transit_repeat_times_set(pd->transit, -1);
else elm_transit_repeat_times_set(pd->transit, 0);
}
}
EOLIAN static Eina_Bool
_efl_ui_animation_view_auto_repeat_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
{
return pd->auto_repeat;
}
EOLIAN static void
_efl_ui_animation_view_auto_play_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd,
Eina_Bool auto_play)
{
pd->auto_play = auto_play;
if (!auto_play) pd->auto_play_pause = EINA_FALSE;
}
EOLIAN static Eina_Bool
_efl_ui_animation_view_auto_play_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
{
return pd->auto_play;
}
EOLIAN static Eina_Bool
_efl_ui_animation_view_play(Eo *obj, Efl_Ui_Animation_View_Data *pd)
{
if (pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY) return EINA_FALSE;
Eina_Bool rewind = EINA_FALSE;
if (pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK) rewind = EINA_TRUE;
pd->play_back = EINA_FALSE;
pd->auto_play_pause = EINA_FALSE;
if (!efl_file_loaded_get(obj)) return EINA_FALSE;
if (!pd->transit && !_ready_play(obj, pd)) return EINA_FALSE;
if (pd->state == EFL_UI_ANIMATION_VIEW_STATE_STOP)
_transit_go_facade(obj, pd);
else if (rewind)
elm_transit_progress_value_set(pd->transit, pd->progress);
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_efl_ui_animation_view_stop(Eo *obj, Efl_Ui_Animation_View_Data *pd)
{
if (!pd->transit) return EINA_FALSE;
if ((pd->state == EFL_UI_ANIMATION_VIEW_STATE_NOT_READY) ||
(pd->state == EFL_UI_ANIMATION_VIEW_STATE_STOP))
return EINA_FALSE;
evas_object_vg_animated_frame_set(pd->vg, 0);
pd->progress = 0;
pd->state = EFL_UI_ANIMATION_VIEW_STATE_STOP;
evas_object_smart_callback_call(obj, SIG_PLAY_STOP, NULL);
elm_transit_del(pd->transit);
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_efl_ui_animation_view_pause(Eo *obj, Efl_Ui_Animation_View_Data *pd)
{
if (!pd->transit) return EINA_FALSE;
if ((pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY) ||
(pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK))
{
elm_transit_paused_set(pd->transit, EINA_TRUE);
pd->state = EFL_UI_ANIMATION_VIEW_STATE_PAUSE;
pd->auto_play_pause = EINA_FALSE;
evas_object_smart_callback_call(obj, SIG_PLAY_PAUSE, NULL);
return EINA_TRUE;
}
return EINA_FALSE;
}
EOLIAN static Eina_Bool
_efl_ui_animation_view_resume(Eo *obj, Efl_Ui_Animation_View_Data *pd)
{
if (!pd->transit) return EINA_FALSE;
if (pd->state == EFL_UI_ANIMATION_VIEW_STATE_PAUSE)
{
elm_transit_paused_set(pd->transit, EINA_FALSE);
if (pd->play_back)
pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK;
else
pd->state = EFL_UI_ANIMATION_VIEW_STATE_PLAY;
pd->auto_play_pause = EINA_FALSE;
evas_object_smart_callback_call(obj, SIG_PLAY_RESUME, NULL);
return EINA_TRUE;
}
return EINA_FALSE;
}
EOLIAN static Eina_Bool
_efl_ui_animation_view_play_back(Eo *obj, Efl_Ui_Animation_View_Data *pd)
{
if (pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK) return EINA_FALSE;
Eina_Bool rewind = EINA_FALSE;
if (pd->state == EFL_UI_ANIMATION_VIEW_STATE_PLAY) rewind = EINA_TRUE;
pd->play_back = EINA_TRUE;
pd->auto_play_pause = EINA_FALSE;
if (!efl_file_loaded_get(obj)) return EINA_FALSE;
if (!pd->transit && !_ready_play(obj, pd)) return EINA_FALSE;
if (pd->state == EFL_UI_ANIMATION_VIEW_STATE_STOP)
{
if (pd->progress == 0) pd->progress = 1.0;
_transit_go_facade(obj, pd);
}
else if (rewind)
elm_transit_progress_value_set(pd->transit, 1 - pd->progress);
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_efl_ui_animation_view_speed_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, double speed)
{
if (speed <= 0) return EINA_FALSE;
pd->speed = speed;
if (pd->transit)
elm_transit_duration_set(pd->transit, pd->frame_duration * (1/pd->speed));
return EINA_TRUE;
}
EOLIAN static void
_efl_ui_animation_view_progress_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, double progress)
{
if (progress < 0) progress = 0;
else if (progress > 1) progress = 1;
if (pd->progress == progress) return;
pd->progress = progress;
if (pd->frame_cnt > 0)
evas_object_vg_animated_frame_set(pd->vg, (int) ((pd->frame_cnt - 1) * progress));
if (pd->transit)
{
if (pd->play_back)
elm_transit_progress_value_set(pd->transit, 1 - progress);
else
elm_transit_progress_value_set(pd->transit, progress);
}
}
EOLIAN static double
_efl_ui_animation_view_progress_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
{
return pd->progress;
}
EOLIAN static void
_efl_ui_animation_view_frame_set(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd, int frame_num)
{
efl_ui_animation_view_progress_set(obj, (double) frame_num / (double) (evas_object_vg_animated_frame_count_get(pd->vg) - 1));
}
EOLIAN static int
_efl_ui_animation_view_frame_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
{
double progress = (pd->progress * (pd->max_progress - pd->min_progress)) + pd->min_progress;
return (int) ((double) (evas_object_vg_animated_frame_count_get(pd->vg) - 1) * progress);
}
EOLIAN static double
_efl_ui_animation_view_speed_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
{
return pd->speed;
}
EOLIAN static double
_efl_ui_animation_view_duration_time_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
{
return pd->frame_duration;
}
EOLIAN static Eina_Size2D
_efl_ui_animation_view_default_view_size_get(const Eo *obj EINA_UNUSED,
Efl_Ui_Animation_View_Data *pd EINA_UNUSED)
{
return efl_canvas_vg_object_default_size_get(pd->vg);
}
EOLIAN static Efl_Ui_Animation_View_State
_efl_ui_animation_view_state_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
{
return pd->state;
}
EOLIAN static Eina_Bool
_efl_ui_animation_view_is_playing_back(Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
{
return pd->play_back;
}
EOLIAN static int
_efl_ui_animation_view_frame_count_get(const Eo *obj EINA_UNUSED, Efl_Ui_Animation_View_Data *pd)
{
return efl_gfx_frame_controller_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)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
return elm_legacy_add(MY_CLASS, parent);
}
EAPI Eina_Bool
elm_animation_view_file_set(Elm_Animation_View *obj, const char *file, const char *key)
{
return efl_file_simple_load(obj, file, key);
}
EAPI Elm_Animation_View_State
elm_animation_view_state_get(Elm_Animation_View *obj)
{
return efl_ui_animation_view_state_get(obj);
}
/* Internal EO APIs and hidden overrides */
#define EFL_UI_ANIMATION_VIEW_EXTRA_OPS \
EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_animation_view)
#include "efl_ui_animation_view_eo.legacy.c"
#include "efl_ui_animation_view.eo.c"

View File

@ -0,0 +1,281 @@
enum Efl.Ui.Animation_View_State
{
not_ready, [[Animation is not ready to play. (Probably, it didn't file set yet or failed to read file.]]
play, [[Animation is on playing. see @Efl.Ui.Animation_View.play]]
play_back, [[Animation is on playing back (rewinding). see @Efl.Ui.Animation_View.play_back]]
pause, [[Animation has been paused. To continue animation, call @Efl.Ui.Animation_View.resume. see @Efl.Ui.Animation_View.pause]]
stop [[Animation view successfully loaded a file then readied for playing. Otherwise after finished animation or stopped forcely by request. see @Efl.Ui.Animation_View.stop]]
}
class @beta Efl.Ui.Animation_View extends Efl.Ui.Widget implements Efl.Gfx.View, Efl.File
{
[[Elementary Animation view class.
Animation view is designed to show and play animation of
vector graphics based content. It hides all efl_canvas_vg details
but just open an API to read vector data from file. Also, it implements
details of animation control methods of Vector.
Vector data could contain static or animatable vector elements including
animation infomation. Currently approved vector data file format is svg, json and eet.
Only json(known for Lottie file as well) and eet could contains animation infomation,
currently Animation_View is supporting.
]]
event_prefix: efl_ui_animation_view;
methods {
@property auto_play {
[[Animation will be started automatically when it's possible.
If @.auto_play is $true, animation will be started when it's readied.
The condition of $auto play is when animation view opened file successfully,
yet to play it plus when the object is visible.
If animation view is disabled, invisible,
it turns to pause state then resume animation when it's visible again.
$true Enable auto play mode, disable otherwise.
Warning: This auto play will be only affected to the next animation source.
So must be called before setting animation file.
]]
set {
}
get {
}
values {
auto_play: bool; [[Auto play mode, Default value is $false]]
}
}
@property auto_repeat {
[[Turn on/off animation looping.
If @.auto_repeat is $true, it repeats animation when animation frame is reached to
end. This auto repeat mode is valid to both play and play_back cases.
$true Enable auto play mode, disable otherwise.
]]
set {
}
get {
}
values {
auto_repeat: bool; [[Loop mode, Defalut is $false.]]
}
}
@property speed {
[[Control animation speed.
Control animation speed by multiplying $speed value. If you want to play
animation double-time faster, you can give $speed 2. If you want to play
animation double-time slower, you can give $speed 0.5.
$true when it's successful. $false otherwise.
Warning: speed must be greater than zero.
]]
set {
return: bool;
}
get {
}
values {
speed: double; [[ Speed factor. Default value is 1.0]]
}
}
@property duration_time {
[[Get the duration of animation in seconds.
This API returns total duration time of current animation in the seconds.
If current animation source isn't animatable, it returns zero.
]]
get {
}
values {
frame_duration: double; [[duration time in the seconds]]
}
}
@property progress {
[[Set current progress position of animation view object.
When you required to jump on a certain frame instantly,
you can change current position by using this API.
Warning: The range of progress is 0 ~ 1.
]]
set {
}
get {
}
values {
progress: double; [[Progress position. Value must be 0 ~ 1.]]
}
}
@property frame {
[[Number of current frame.
Ranges from 0 to @.frame_count - 1.
]]
set {
}
get {
}
values {
frame_num: int; [[Current frame number.]]
}
}
play {
[[Play animation one time instantly when it's available.
If current keyframe is on a certain position by playing back, this will
play forward from there.
Warning: Play request will be ignored if animation source is not set yet or
animation is paused state or it's already on playing.
]]
return: bool; [[$true when it's successful. $false otherwise.]]
}
play_back {
[[Play back animation one time instantly when it's available.
If current keyframe is on a certain position by playing, this will
play backward from there.
Warning: Play back request will be ignored if animation source is not set yet or
animation is paused state or it's already on playing back.
]]
return: bool; [[$true when it's successful. $false otherwise.]]
}
pause {
[[Pause current animation instantly.
Once animation is paused, animation view must get resume to play continue again.
Warning: Animation must be on playing or playing back status.
]]
return: bool; [[$true when it's successful. $false otherwise.]]
}
resume {
[[Resume paused animation to continue animation.
Warning: This resume must be called on animation paused status.
]]
return: bool; [[$true when it's successful. $false otherwise.]]
}
stop {
[[Stop playing animation.
Stop animation instatly regardless of it's status and reset to
show first frame of animation. Even though current animation is paused,
the animation status will be stopped.
]]
return: bool; [[$true when it's successful. $false otherwise.]]
}
@property default_view_size {
[[The default view size that specified from vector resource.
]]
get {
}
values {
size: Eina.Size2D;
}
}
@property state {
[[Current animation view state.
see @Efl.Ui.Animation_View_State
]]
get{
}
values {
state: Efl.Ui.Animation_View_State; [[Current animation view state]]
}
}
is_playing_back {
[[Returns the status whether current animation is on playing forward or backward.
warning: If animation view is not on playing, it will return $false.
]]
return: bool; [[$true, if animation on playing back, $false otherwise.]]
}
@property frame_count {
[[The index of end frame of the animation view, if it's animated.
note : frame number starts with 0.
]]
get {
}
values {
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 {
}
get {
}
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 {
}
get {
}
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 {
}
get {
}
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 {
}
get {
}
values {
max_frame: int; [[The maximum frame for play. Value must be @.min_frame ~ (@.frame_count - 1)]]
}
}
}
implements {
Efl.Object.constructor;
Efl.Object.destructor;
Efl.File.load;
Efl.File.unload;
Efl.Gfx.Entity.visible { set; }
Efl.Gfx.Entity.position { set; }
Efl.Gfx.Entity.size { set; }
Efl.Gfx.View.view_size { set; get; }
}
events {
play,start: void; [[Called when animation is just started]]
play,repeat: void; [[Called when animation is just repeated]]
play,done: void; [[Called when animation is just finished]]
play,pause: void; [[Called when animation is just paused]]
play,resume: void; [[Called when animation is just resumed]]
play,stop: void; [[Called when animation is just stopped]]
play,update: void; [[Called when animation is just updated]]
}
}

View File

@ -0,0 +1,33 @@
/**
* @defgroup Elm_Animation_View Animation View
* @ingroup Elementary
*
* Animation_View widget is designed to show and play animation of
* vector graphics based content. It hides all efl_canvas_vg details
* but just open an API to read vector data from file. Also, it implements
* details of animation control methods of Vector.
*
* Vector data could contain static or animatable vector elements including
* animation infomation. Currently approved vector data file format is svg, json and eet.
* Only json(known for Lottie file as well) and eet could contains animation infomation,
* currently Animation_View is supporting.
*
* This widget emits the following signals, besides the ones sent from Animation View.
* @li "play,start": animation is just started.
* @li "play,repeat": animation is just repeated.
* @li "play,done": animation is just finished.
* @li "play,pause": animation is just paused.
* @li "play,resume": animation is just resumed.
* @li "play,stop": animation is just stopped.
* @li "play,update": animation is updated to the next frame.
*
*/
/**
* @ingroup Elm_Animation_View
*/
#ifndef EFL_NOLEGACY_API_SUPPORT
#include "efl_ui_animation_view_legacy.h"
#endif
/**
* @}
*/

View File

@ -0,0 +1,162 @@
EAPI void
elm_animation_view_auto_play_set(Efl_Ui_Animation_View *obj, Eina_Bool auto_play)
{
efl_ui_animation_view_auto_play_set(obj, auto_play);
}
EAPI Eina_Bool
elm_animation_view_auto_play_get(const Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_auto_play_get(obj);
}
EAPI void
elm_animation_view_auto_repeat_set(Efl_Ui_Animation_View *obj, Eina_Bool auto_repeat)
{
efl_ui_animation_view_auto_repeat_set(obj, auto_repeat);
}
EAPI Eina_Bool
elm_animation_view_auto_repeat_get(const Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_auto_repeat_get(obj);
}
EAPI Eina_Bool
elm_animation_view_speed_set(Efl_Ui_Animation_View *obj, double speed)
{
return efl_ui_animation_view_speed_set(obj, speed);
}
EAPI double
elm_animation_view_speed_get(const Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_speed_get(obj);
}
EAPI double
elm_animation_view_duration_time_get(const Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_duration_time_get(obj);
}
EAPI void
elm_animation_view_progress_set(Efl_Ui_Animation_View *obj, double progress)
{
efl_ui_animation_view_progress_set(obj, progress);
}
EAPI double
elm_animation_view_progress_get(const Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_progress_get(obj);
}
EAPI void
elm_animation_view_frame_set(Efl_Ui_Animation_View *obj, int frame_num)
{
efl_ui_animation_view_frame_set(obj, frame_num);
}
EAPI int
elm_animation_view_frame_get(const Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_frame_get(obj);
}
EAPI Eina_Bool
elm_animation_view_play(Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_play(obj);
}
EAPI Eina_Bool
elm_animation_view_play_back(Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_play_back(obj);
}
EAPI Eina_Bool
elm_animation_view_pause(Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_pause(obj);
}
EAPI Eina_Bool
elm_animation_view_resume(Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_resume(obj);
}
EAPI Eina_Bool
elm_animation_view_stop(Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_stop(obj);
}
EAPI Eina_Size2D
elm_animation_view_default_size_get(const Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_default_view_size_get(obj);
}
EAPI Eina_Bool
elm_animation_view_is_playing_back(Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_is_playing_back(obj);
}
EAPI int
elm_animation_view_frame_count_get(const Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_frame_count_get(obj);
}
EAPI void
elm_animation_view_min_progress_set(Efl_Ui_Animation_View *obj, double min_progress)
{
efl_ui_animation_view_min_progress_set(obj, min_progress);
}
EAPI double
elm_animation_view_min_progress_get(const Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_min_progress_get(obj);
}
EAPI void
elm_animation_view_max_progress_set(Efl_Ui_Animation_View *obj, double max_progress)
{
efl_ui_animation_view_max_progress_set(obj, max_progress);
}
EAPI double
elm_animation_view_max_progress_get(const Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_max_progress_get(obj);
}
EAPI void
elm_animation_view_min_frame_set(Efl_Ui_Animation_View *obj, int min_frame)
{
efl_ui_animation_view_min_frame_set(obj, min_frame);
}
EAPI int
elm_animation_view_min_frame_get(const Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_min_frame_get(obj);
}
EAPI void
elm_animation_view_max_frame_set(Efl_Ui_Animation_View *obj, int max_frame)
{
efl_ui_animation_view_max_frame_set(obj, max_frame);
}
EAPI int
elm_animation_view_max_frame_get(const Efl_Ui_Animation_View *obj)
{
return efl_ui_animation_view_max_frame_get(obj);
}

View File

@ -0,0 +1,517 @@
#ifndef _EFL_UI_ANIMATION_VIEW_EO_LEGACY_H_
#define _EFL_UI_ANIMATION_VIEW_EO_LEGACY_H_
#ifndef _ELM_ANIMATION_VIEW_EO_CLASS_TYPE
#define _ELM_ANIMATION_VIEW_EO_CLASS_TYPE
typedef Eo Elm_Animation_View;
#endif
#ifndef _ELM_ANIMATION_VIEW_EO_TYPES
#define _ELM_ANIMATION_VIEW_EO_TYPES
/**
* @brief Defines the state of animation view
*
* @ingroup Elm_Animation_View
*/
typedef enum
{
ELM_ANIMATION_VIEW_STATE_NOT_READY = 0, /**< Animation is not ready to
* play. (Probably, it didn't file
* set yet or failed to read file.
*
* @since 1.23 */
ELM_ANIMATION_VIEW_STATE_PLAY, /**< Animation is on playing. see
* @ref elm_animation_view_play
*
* @since 1.23 */
ELM_ANIMATION_VIEW_STATE_PLAY_BACK, /**< Animation is on playing back
* (rewinding). see
* @ref elm_animation_view_play_back
*
* @since 1.23 */
ELM_ANIMATION_VIEW_STATE_PAUSE, /**< Animation has been paused. To continue
* animation, call
* @ref elm_animation_view_resume. see
* @ref elm_animation_view_pause
*
* @since 1.23 */
ELM_ANIMATION_VIEW_STATE_STOP /**< Animation view successfully loaded a
* file then readied for playing. Otherwise
* after finished animation or stopped
* forcely by request. see
* @ref elm_animation_view_stop
*
* @since 1.23 */
} Elm_Animation_View_State;
#endif
/**
* @brief Animation will be started automatically when it's possible.
*
* If @ref elm_animation_view_auto_play_get is @c true, animation will be
* started when it's readied. The condition of @c auto play is when animation
* view opened file successfully, yet to play it plus when the object is
* visible. If animation view is disabled, invisible, it turns to pause state
* then resume animation when it's visible again.
*
* @warning This auto play will be only affected to the next animation source.
* So must be called before setting animation file
*
* Set auto play mode of an animation view object. @c true Enable auto play
* mode, disable otherwise
*
* @param[in] obj The object.
* @param[in] auto_play Auto play mode, Default value is @c false
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI void elm_animation_view_auto_play_set(Elm_Animation_View *obj, Eina_Bool auto_play);
/**
* @brief Animation will be started automatically when it's possible.
*
* If @ref elm_animation_view_auto_play_get is @c true, animation will be
* started when it's readied. The condition of @c auto play is when animation
* view opened file successfully, yet to play it plus when the object is
* visible. If animation view is disabled, invisible, it turns to pause state
* then resume animation when it's visible again.
*
* @warning This auto play will be only affected to the next animation source.
* So must be called before setting animation file
*
* Returns auto play mode of an animation view object.
*
* @param[in] obj The object.
*
* @return Auto play mode, Default value is @c false
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI Eina_Bool elm_animation_view_auto_play_get(const Elm_Animation_View *obj);
/**
* @brief Turn on/off animation looping.
*
* If @ref elm_animation_view_auto_repeat_get is @c true, it repeats animation
* when animation frame is reached to end. This auto repeat mode is valid to
* both play and play_back cases.
*
* Enable loop mode if @c true, disable otherwise.
*
* @param[in] obj The object.
* @param[in] auto_repeat Loop mode, Defalut is @c false.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI void elm_animation_view_auto_repeat_set(Elm_Animation_View *obj, Eina_Bool auto_repeat);
/**
* @brief Turn on/off animation looping.
*
* If @ref elm_animation_view_auto_repeat_get is @c true, it repeats animation
* when animation frame is reached to end. This auto repeat mode is valid to
* both play and play_back cases.
*
* Returns auto repeat mode of an animation view object.
*
* @param[in] obj The object.
*
* @return Loop mode, Defalut is @c false.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI Eina_Bool elm_animation_view_auto_repeat_get(const Elm_Animation_View *obj);
/**
* @brief Control animation speed.
*
* Control animation speed by multiplying @c speed value. If you want to play
* animation double-time faster, you can give @c speed 2. If you want to play
* animation double-time slower, you can give @c speed 0.5.
*
* @warning speed must be greater than zero.
*
* @param[in] obj The object.
* @param[in] speed Speed factor. Default value is 1.0
*
* @return @c true when it's successful. @c false otherwise.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI Eina_Bool elm_animation_view_speed_set(Elm_Animation_View *obj, double speed);
/**
* @brief Control animation speed.
*
* Control animation speed by multiplying @c speed value. If you want to play
* animation double-time faster, you can give @c speed 2. If you want to play
* animation double-time slower, you can give @c speed 0.5.
*
* @warning speed must be greater than zero.
*
* Returns current animation speed of an animation view object.
*
* @param[in] obj The object.
*
* @return Speed factor. Default value is 1.0
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI double elm_animation_view_speed_get(const Elm_Animation_View *obj);
/**
* @brief Get the duration of animation in seconds.
*
* This API returns total duration time of current animation in the seconds. If
* current animation source isn't animatable, it returns zero.
*
* Returns current duration of an animation in seconds.
*
* @param[in] obj The object.
*
* @return duration time in the seconds
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI double elm_animation_view_duration_time_get(const Elm_Animation_View *obj);
/**
* @brief Set current progress position of animation view object.
*
* When you required to jump on a certain frame instantly, you can change
* current position by using this API.
*
* @warning The range of progress is 0 ~ 1.
*
* Set the current progress position of an animation view object.
*
* @param[in] obj The object.
* @param[in] progress Progress position. Value must be 0 ~ 1.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI void elm_animation_view_progress_set(Elm_Animation_View *obj, double progress);
/**
* @brief Set current progress position of animation view object.
*
* When you required to jump on a certain frame instantly, you can change
* current position by using this API.
*
* @warning The range of progress is 0 ~ 1.
*
* Returns current progress position of an animation view object.
*
* @param[in] obj The object.
*
* @return Progress position. Value must be 0 ~ 1.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI double elm_animation_view_progress_get(const Elm_Animation_View *obj);
/**
* @brief Number of current frame.
*
* Ranges from 0 to @ref elm_animation_view_frame_count_get - 1.
*
* Set the current frame of an animation view object.
*
* @param[in] obj The object.
* @param[in] frame_num Current frame number.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI void elm_animation_view_frame_set(Elm_Animation_View *obj, int frame_num);
/**
* @brief Number of current frame.
*
* Ranges from 0 to @ref elm_animation_view_frame_count_get - 1.
*
* Returns the current frame of an animation view object.
*
* @param[in] obj The object.
*
* @return Current frame number.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI int elm_animation_view_frame_get(const Elm_Animation_View *obj);
/**
* @brief Play animation one time instantly when it's available.
*
* If current keyframe is on a certain position by playing back, this will play
* forward from there.
*
* @warning Play request will be ignored if animation source is not set yet or
* animation is paused state or it's already on playing.
*
* @param[in] obj The object.
*
* @return @c true when it's successful. @c false otherwise.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI Eina_Bool elm_animation_view_play(Elm_Animation_View *obj);
/**
* @brief Play back animation one time instantly when it's available.
*
* If current keyframe is on a certain position by playing, this will play
* backward from there.
*
* @warning Play back request will be ignored if animation source is not set
* yet or animation is paused state or it's already on playing back.
*
* @param[in] obj The object.
*
* @return @c true when it's successful. @c false otherwise.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI Eina_Bool elm_animation_view_play_back(Elm_Animation_View *obj);
/**
* @brief Pause current animation instantly.
*
* Once animation is paused, animation view must get resume to play continue
* again.
*
* @warning Animation must be on playing or playing back status.
*
* @param[in] obj The object.
*
* @return @c true when it's successful. @c false otherwise.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI Eina_Bool elm_animation_view_pause(Elm_Animation_View *obj);
/**
* @brief Resume paused animation to continue animation.
*
* @warning This resume must be called on animation paused status.
*
* @param[in] obj The object.
*
* @return @c true when it's successful. @c false otherwise.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI Eina_Bool elm_animation_view_resume(Elm_Animation_View *obj);
/**
* @brief Stop playing animation.
*
* Stop animation instatly regardless of it's status and reset to show first
* frame of animation. Even though current animation is paused, the animation
* status will be stopped.
*
* @param[in] obj The object.
*
* @return @c true when it's successful. @c false otherwise.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI Eina_Bool elm_animation_view_stop(Elm_Animation_View *obj);
/** Get the default view size that specified from vector resource.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI Eina_Size2D elm_animation_view_default_size_get(const Elm_Animation_View *obj);
/**
* @brief Returns the status whether current animation is on playing forward or
* backward. warning: If animation view is not on playing, it will return
* @c false.
*
* @param[in] obj The object.
*
* @return @c true, if animation on playing back, @c false otherwise.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI Eina_Bool elm_animation_view_is_playing_back(Elm_Animation_View *obj);
/**
* @brief Get the index of end frame of the animation view, if it's animated.
* note : frame number starts with 0.
*
* @param[in] obj The object.
*
* @return The number of frames. 0, if it's not animated.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI int elm_animation_view_frame_count_get(const Elm_Animation_View *obj);
/**
* @brief The start progress of the play. Default value is 0.
*
* Set start progress of an animation object.
*
* @param[in] obj The object.
* @param[in] min_progress The minimum progress. Value must be 0 ~ 1.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI void elm_animation_view_min_progress_set(Elm_Animation_View *obj, double min_progress);
/**
* @brief The start progress of the play. Default value is 0.
*
* Returns start progress of an animation object.
*
* @param[in] obj The object.
*
* @return The minimum progress. Value must be 0 ~ 1.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI double elm_animation_view_min_progress_get(const Elm_Animation_View *obj);
/**
* @brief The last progress of the play. Default value is 1.
*
* Set last progress of an animation object.
*
* @param[in] obj The object.
* @param[in] max_progress The maximum progress. Value must be 0 ~ 1.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI void elm_animation_view_max_progress_set(Elm_Animation_View *obj, double max_progress);
/**
* @brief The last progress of the play. Default value is 1.
*
* Returns last progress of an animation object.
*
* @param[in] obj The object.
*
* @return The maximum progress. Value must be 0 ~ 1.
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI double elm_animation_view_max_progress_get(const Elm_Animation_View *obj);
/**
* @brief The start frame of the play. Default value is 0.
*
* Set minimum frame of an animation object.
*
* @param[in] obj The object.
* @param[in] min_frame The minimum frame for play. Value must be 0 ~
* @ref elm_animation_view_max_frame_get
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI void elm_animation_view_min_frame_set(Elm_Animation_View *obj, int min_frame);
/**
* @brief The start frame of the play. Default value is 0.
*
* Returns minimum frame of an animation object.
*
* @param[in] obj The object.
*
* @return The minimum frame for play. Value must be 0 ~
* @ref elm_animation_view_max_frame_get
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI int elm_animation_view_min_frame_get(const Elm_Animation_View *obj);
/**
* @brief The last frame of the play. Default value is
* @ref elm_animation_view_frame_count_get - 1
*
* Set maximum frame of an animation object.
*
* @param[in] obj The object.
* @param[in] max_frame The maximum frame for play. Value must be
* @ref elm_animation_view_min_frame_get ~ (@ref elm_animation_view_frame_count_get - 1)
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI void elm_animation_view_max_frame_set(Elm_Animation_View *obj, int max_frame);
/**
* @brief The last frame of the play. Default value is
* @ref elm_animation_view_frame_count_get - 1
*
* Returns maximum frame of an animation object.
*
* @param[in] obj The object.
*
* @return The maximum frame for play. Value must be
* @ref elm_animation_view_min_frame_get ~ (@ref elm_animation_view_frame_count_get - 1)
*
* @since 1.23
*
* @ingroup Elm_Animation_View
*/
EAPI int elm_animation_view_max_frame_get(const Elm_Animation_View *obj);
#endif

View File

@ -0,0 +1,49 @@
#include "efl_ui_animation_view_eo.legacy.h"
/**
* Add a new animation view widget to the parent's canvas
*
* @param parent The parent object
* @return The new animation view object or @c NULL if it failed to create.
*
* @ingroup Elm_Animation_View
*
* @since 1.23
*/
EAPI Elm_Animation_View *elm_animation_view_add(Evas_Object *parent);
/**
*
* Set the source file from where an vector object must fetch the real
* vector data (it may be one of json, svg, eet files).
*
* If the file supports multiple data stored in it (as Eet files do),
* you can specify the key to be used as the index of the vector in
* this file.
*
* @param[in] file The vector file path.
* @param[in] key The vector key in @p file (if its an Eet one), or @c
NULL, otherwise.
*
* @return @c EINA_TRUE if it's succeed to read file, @c EINA_FALSE otherwise.
*
* @ingroup Elm_Animation_View
*
* @since 1.23
*/
EAPI Eina_Bool elm_animation_view_file_set(Elm_Animation_View *obj, const char *file, const char *key);
/**
* @brief Get current animation view state.
*
* @return Current animation view state
*
* @see Elm_Animation_View_State
*
* @ingroup Elm_Animation_View
*
* @since 1.23
*/
EAPI Elm_Animation_View_State elm_animation_view_state_get(Elm_Animation_View *obj);

View File

@ -0,0 +1,41 @@
#ifndef EFL_UI_ANIMATION_VIEW_PRIVATE_H
#define EFL_UI_ANIMATION_VIEW_PRIVATE_H
#include "Elementary.h"
#include "efl_ui_animation_view.eo.h"
typedef struct _Efl_Ui_Animation_View_Data Efl_Ui_Animation_View_Data;
struct _Efl_Ui_Animation_View_Data
{
Eo* vg; //Evas_Object_Vg
Efl_Ui_Animation_View_State state;
Elm_Transit *transit;
Eina_Stringshare *file;
double speed;
double progress;
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;
Eina_Bool auto_play_pause: 1;
Eina_Bool auto_repeat : 1;
};
#define EFL_UI_ANIMATION_VIEW_DATA_GET(o, sd) \
Efl_Ui_Animation_View_Data * sd = efl_data_scope_safe_get(o, EFL_UI_ANIMATION_VIEW_CLASS)
#define EFL_UI_ANIMATION_VIEW_DATA_GET_OR_RETURN(o, ptr) \
EFL_UI_ANIMATION_VIEW_DATA_GET(o, ptr); \
if (EINA_UNLIKELY(!ptr)) \
{ \
ERR("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
#endif

View File

@ -38,6 +38,7 @@ endforeach
pub_eo_files = [
'efl_ui_widget.eo',
'efl_ui_animation_view.eo',
'efl_ui_bg.eo',
'efl_ui_button.eo',
'efl_ui_calendar.eo',
@ -298,6 +299,7 @@ elementary_headers_unstable = [
'efl_ui_widget_flip.h',
'elm_widget_flipselector.h',
'efl_ui_widget_frame.h',
'efl_ui_animation_view_private.h',
'elm_widget_gengrid.h',
'elm_widget_genlist.h',
'elm_widget_glview.h',
@ -402,6 +404,8 @@ elementary_pub_headers = [
'elc_naviframe_common.h',
'elc_popup.h',
'elc_popup_legacy.h',
'efl_ui_animation_view.h',
'efl_ui_animation_view_legacy.h',
'elm_access.h',
'elm_actionslider.h',
'elm_actionslider_legacy.h',
@ -591,6 +595,7 @@ elementary_pub_headers = [
'elm_win_legacy.h',
'elm_helper.h',
'elm_part_helper.h',
'efl_ui_animation_view_eo.legacy.h',
'efl_ui_bg_eo.legacy.h',
'efl_ui_bg_legacy_eo.legacy.h',
'efl_ui_button_eo.legacy.h',
@ -730,6 +735,7 @@ elementary_src = [
'elc_popup.c',
'elc_scrolled_entry.c',
'elm_access.c',
'efl_ui_animation_view.c',
'elm_actionslider.c',
'elm_atspi_app_object.c',
'elm_atspi_bridge.c',

View File

@ -0,0 +1,39 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#include <Efl_Ui.h>
#include "efl_ui_spec_suite.h"
#include "suite_helpers.h"
/* spec-meta-start
{"test-interface":"Efl.Gfx.View",
"test-widgets": ["Efl.Ui.Animation_View"]}
spec-meta-end */
EFL_START_TEST(view_size)
{
#define TUPLE_CHECK(W, H) \
do { \
Eina_Size2D sz; \
efl_gfx_view_size_set(widget, EINA_SIZE2D(W, H)); \
sz = efl_gfx_view_size_get(widget); \
ck_assert(W == sz.w); \
ck_assert(H == sz.h); \
} while(0);
TUPLE_CHECK(100, 100);
TUPLE_CHECK(100, 200);
TUPLE_CHECK(200, 100);
TUPLE_CHECK(800, 700);
TUPLE_CHECK(10, 50);
#undef TUPLE_CHECK
}
EFL_END_TEST
void
efl_gfx_view_behavior_test(TCase *tc)
{
tcase_add_test(tc, view_size);
}

View File

@ -14,6 +14,7 @@ void efl_pack_behavior_test(TCase *tc);
void efl_pack_linear_behavior_test(TCase *tc);
void efl_content_behavior_test(TCase *tc);
void efl_gfx_arrangement_behavior_test(TCase *tc);
void efl_gfx_view_behavior_test(TCase *tc);
void efl_ui_clickable_behavior_test(TCase *tc);
void efl_ui_format_behavior_test(TCase *tc);
void efl_ui_range_display_behavior_test(TCase *tc);

View File

@ -11,6 +11,7 @@ efl_ui_suite_behavior_test_files = files([
'efl_test_single_selectable.c',
'efl_test_multi_selectable.c',
'efl_test_selectable.c',
'efl_test_gfx_view.c',
])
efl_ui_suite_behavior_src = files([