forked from enlightenment/efl
introduce efl_canvas_object_animation
this brings the animation to the canvas object. All the controls of the animation now do now require a player object anymore, you can just use the API that is directly on the Efl.Canvas.Object object. wip animation player replacement Differential Revision: https://phab.enlightenment.org/D10615
This commit is contained in:
parent
9bb2df9966
commit
fa93893548
|
@ -0,0 +1,179 @@
|
|||
/**
|
||||
* Example of animation in efl canvas
|
||||
*
|
||||
* You'll need at least one engine built for it (excluding the buffer
|
||||
* one). See stdout/stderr for output.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_Evas.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define WIDTH (640)
|
||||
#define HEIGHT (480)
|
||||
|
||||
struct example_data
|
||||
{
|
||||
Ecore_Evas *ee;
|
||||
Evas *evas;
|
||||
Evas_Object *bg, *scale;
|
||||
double current_speed;
|
||||
};
|
||||
|
||||
static struct example_data d;
|
||||
|
||||
static Evas_Object * /* new rectangle to be put in the box */
|
||||
_new_rectangle_add(Evas *e)
|
||||
{
|
||||
Efl_Canvas_Rectangle *rect = efl_add(EFL_CANVAS_RECTANGLE_CLASS, e);
|
||||
|
||||
efl_gfx_entity_size_set(rect, EINA_SIZE2D(10, 10));
|
||||
efl_gfx_color_set(rect, 0, 255, 0, 255);
|
||||
efl_gfx_entity_visible_set(rect, EINA_TRUE);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
/* use the following commands to interact with this example - 'h' is
|
||||
* the key for help */
|
||||
static void
|
||||
_on_keydown(void *data EINA_UNUSED, const Efl_Event *ev)
|
||||
{
|
||||
if (strcmp(efl_input_key_sym_get(ev->info) , "r") == 0)
|
||||
{
|
||||
Efl_Canvas_Animation *animation = efl_canvas_object_animation_get(d.scale);
|
||||
double current_pos = efl_canvas_object_animation_progress_get(d.scale);
|
||||
d.current_speed *= -1;
|
||||
efl_canvas_object_animation_start(d.scale, animation, d.current_speed, 1.0 - current_pos);
|
||||
}
|
||||
if (strcmp(efl_input_key_sym_get(ev->info), "p") == 0)
|
||||
{
|
||||
efl_canvas_object_animation_pause_set(d.scale, !efl_canvas_object_animation_pause_get(d.scale));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_on_delete(Ecore_Evas *ee EINA_UNUSED)
|
||||
{
|
||||
ecore_main_loop_quit();
|
||||
}
|
||||
|
||||
static void /* adjust canvas' contents on resizes */
|
||||
_canvas_resize_cb(Ecore_Evas *ee)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
|
||||
|
||||
efl_gfx_entity_geometry_set(d.bg, EINA_RECT(0, 0, w, h));
|
||||
}
|
||||
|
||||
static void
|
||||
print_help(void)
|
||||
{
|
||||
printf("evas-animation example\n Press r to reverse the animation of the red rect.\n Press p to pause the animation of the red rect.\n");
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
if (!ecore_evas_init())
|
||||
return EXIT_FAILURE;
|
||||
|
||||
/* this will give you a window with an Evas canvas under the first
|
||||
* engine available */
|
||||
d.ee = ecore_evas_new(NULL, 0, 0, WIDTH, HEIGHT, NULL);
|
||||
if (!d.ee)
|
||||
goto panic;
|
||||
|
||||
print_help();
|
||||
|
||||
ecore_evas_name_class_set(d.ee, "Evas Animation example", "Evas Animation Example");
|
||||
ecore_evas_callback_delete_request_set(d.ee, _on_delete);
|
||||
ecore_evas_callback_resize_set(d.ee, _canvas_resize_cb);
|
||||
ecore_evas_show(d.ee);
|
||||
|
||||
d.evas = ecore_evas_get(d.ee);
|
||||
|
||||
d.bg = _new_rectangle_add(d.evas);
|
||||
efl_gfx_color_set(d.bg, 255, 255, 255, 255);
|
||||
efl_gfx_entity_visible_set(d.bg, EINA_TRUE);
|
||||
efl_canvas_object_key_focus_set(d.bg, EINA_TRUE);
|
||||
efl_event_callback_add(d.bg, EFL_EVENT_KEY_DOWN, _on_keydown, NULL);
|
||||
|
||||
_canvas_resize_cb(d.ee);
|
||||
|
||||
Evas_Object *scale_rect = _new_rectangle_add(d.evas);
|
||||
efl_gfx_entity_geometry_set(scale_rect, EINA_RECT(50, 50, 50, 50));
|
||||
efl_canvas_object_animation_start(scale_rect,
|
||||
efl_new(EFL_CANVAS_ANIMATION_SCALE_CLASS,
|
||||
efl_animation_scale_set(efl_added, EINA_VECTOR2(1.0, 1.0), EINA_VECTOR2(3.0, 3.0), scale_rect, EINA_VECTOR2(0.5, 0.5)),
|
||||
efl_animation_start_delay_set(efl_added, 5.0),
|
||||
efl_animation_duration_set(efl_added, 2.0),
|
||||
efl_animation_repeat_count_set(efl_added, EFL_ANIMATION_REPEAT_INFINITE)
|
||||
),
|
||||
1.0, 0.0);
|
||||
|
||||
Evas_Object *scale_rect2 = _new_rectangle_add(d.evas);
|
||||
efl_gfx_entity_geometry_set(scale_rect2, EINA_RECT(50, 200, 50, 50));
|
||||
efl_canvas_object_animation_start(scale_rect2,
|
||||
efl_new(EFL_CANVAS_ANIMATION_SCALE_CLASS,
|
||||
efl_animation_scale_set(efl_added, EINA_VECTOR2(1.0, 1.0), EINA_VECTOR2(3.0, 3.0), scale_rect2, EINA_VECTOR2(0.5, 0.5)),
|
||||
efl_animation_duration_set(efl_added, 2.0),
|
||||
efl_animation_repeat_count_set(efl_added, EFL_ANIMATION_REPEAT_INFINITE),
|
||||
efl_animation_repeat_mode_set(efl_added, EFL_CANVAS_ANIMATION_REPEAT_MODE_REVERSE)
|
||||
),
|
||||
1.0, 0.0);
|
||||
|
||||
Evas_Object *scale_rect3 = _new_rectangle_add(d.evas);
|
||||
efl_gfx_entity_geometry_set(scale_rect3, EINA_RECT(50, 350, 50, 50));
|
||||
efl_canvas_object_animation_start(scale_rect3,
|
||||
efl_new(EFL_CANVAS_ANIMATION_SCALE_CLASS,
|
||||
efl_animation_scale_set(efl_added, EINA_VECTOR2(1.0, 1.0), EINA_VECTOR2(3.0, 3.0), scale_rect3, EINA_VECTOR2(0.5, 0.5)),
|
||||
efl_animation_duration_set(efl_added, 2.0),
|
||||
efl_animation_repeat_count_set(efl_added, 3),
|
||||
efl_animation_repeat_mode_set(efl_added, EFL_CANVAS_ANIMATION_REPEAT_MODE_REVERSE)
|
||||
),
|
||||
1.0, 0.0);
|
||||
|
||||
Evas_Object *scale_rect4 = _new_rectangle_add(d.evas);
|
||||
efl_gfx_entity_geometry_set(scale_rect4, EINA_RECT(200, 50, 50, 50));
|
||||
efl_canvas_object_animation_start(scale_rect4,
|
||||
efl_new(EFL_CANVAS_ANIMATION_SCALE_CLASS,
|
||||
efl_animation_scale_set(efl_added, EINA_VECTOR2(1.0, 1.0), EINA_VECTOR2(3.0, 3.0), scale_rect4, EINA_VECTOR2(0.5, 0.5)),
|
||||
efl_animation_duration_set(efl_added, 2.0),
|
||||
efl_animation_final_state_keep_set(efl_added, EINA_TRUE)
|
||||
),
|
||||
1.0, 0.0);
|
||||
|
||||
|
||||
Evas_Object *scale_rect5 = d.scale = _new_rectangle_add(d.evas);
|
||||
efl_gfx_color_set(scale_rect5, 255, 0, 0, 255);
|
||||
efl_gfx_entity_geometry_set(scale_rect5, EINA_RECT(200, 200, 50, 50));
|
||||
efl_canvas_object_animation_start(scale_rect5,
|
||||
efl_new(EFL_CANVAS_ANIMATION_SCALE_CLASS,
|
||||
efl_animation_scale_set(efl_added, EINA_VECTOR2(1.0, 1.0), EINA_VECTOR2(5.0, 5.0), scale_rect5, EINA_VECTOR2(0.5, 0.5)),
|
||||
efl_animation_duration_set(efl_added, 5.0),
|
||||
efl_animation_repeat_count_set(efl_added, EFL_ANIMATION_REPEAT_INFINITE)
|
||||
),
|
||||
1.0, 0.0);
|
||||
d.current_speed = 1.0;
|
||||
|
||||
ecore_main_loop_begin();
|
||||
ecore_evas_shutdown();
|
||||
return 0;
|
||||
|
||||
panic:
|
||||
fprintf(stderr, "error: Requires at least one Evas engine built and linked"
|
||||
" to ecore-evas for this example to run properly.\n");
|
||||
return -2;
|
||||
}
|
||||
|
|
@ -50,6 +50,7 @@ examples = [
|
|||
'evas-vg-batman',
|
||||
'evas-vg-simple',
|
||||
'evas-vg-json',
|
||||
'efl-canvas-animation',
|
||||
]
|
||||
|
||||
foreach example : examples
|
||||
|
|
|
@ -223,7 +223,7 @@ struct _Efl_Canvas_Object_Animation_Event
|
|||
#include "gesture/efl_gesture_events.eo.h"
|
||||
|
||||
#include "canvas/efl_canvas_object.eo.h"
|
||||
|
||||
#include "canvas/efl_canvas_object_animation.eo.h"
|
||||
#include "canvas/efl_canvas_animation.eo.h"
|
||||
#include "canvas/efl_canvas_animation_alpha.eo.h"
|
||||
#include "canvas/efl_canvas_animation_rotate.eo.h"
|
||||
|
|
|
@ -11,7 +11,7 @@ struct Efl.Event_Animator_Tick {
|
|||
|
||||
abstract Efl.Canvas.Object extends Efl.Loop_Consumer implements Efl.Gfx.Entity, Efl.Gfx.Color, Efl.Gfx.Stack,
|
||||
Efl.Input.Interface, Efl.Gfx.Hint,
|
||||
Efl.Gfx.Mapping, Efl.Canvas.Pointer, Efl.Gesture.Events
|
||||
Efl.Gfx.Mapping, Efl.Canvas.Pointer, Efl.Gesture.Events, Efl.Canvas.Object_Animation
|
||||
{
|
||||
[[Efl canvas object abstract class
|
||||
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "evas_common_private.h"
|
||||
#include "evas_private.h"
|
||||
#include "efl_canvas_object_animation.eo.h"
|
||||
#include <Ecore.h>
|
||||
|
||||
#define MY_CLASS EFL_CANVAS_OBJECT_ANIMATION_MIXIN
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Efl_Canvas_Animation *animation;
|
||||
double speed;
|
||||
double progress;
|
||||
double run_start_time;
|
||||
double start_pos;
|
||||
int remaining_repeats;
|
||||
Efl_Loop_Timer *timer;
|
||||
Eina_Bool pause_state : 1;
|
||||
} Efl_Canvas_Object_Animation_Indirect_Data;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Efl_Canvas_Object_Animation_Indirect_Data *in;
|
||||
} Efl_Canvas_Object_Animation_Data;
|
||||
|
||||
static void _end(Efl_Canvas_Object_Animation *obj, Efl_Canvas_Object_Animation_Data *pd);
|
||||
|
||||
|
||||
static void
|
||||
_animator_cb(void *data, const Efl_Event *ev EINA_UNUSED)
|
||||
{
|
||||
Eo *obj = data;
|
||||
Efl_Canvas_Object_Animation_Data *pd = efl_data_scope_get(obj, MY_CLASS);
|
||||
double duration, elapsed_time, vector, current;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(pd->in);
|
||||
current = ecore_loop_time_get();
|
||||
EINA_SAFETY_ON_FALSE_RETURN(pd->in->run_start_time <= current);
|
||||
|
||||
duration = efl_animation_duration_get(pd->in->animation) / pd->in->speed;
|
||||
elapsed_time = current - pd->in->run_start_time;
|
||||
vector = elapsed_time / duration;
|
||||
|
||||
/* When animation player starts, _animator_cb() is called immediately so
|
||||
* both elapsed time and progress are 0.0.
|
||||
* Since it is the beginning of the animation if progress is 0.0, the
|
||||
* following codes for animation should be executed. */
|
||||
if (pd->in->speed < 0.0)
|
||||
vector += 1.0;
|
||||
pd->in->progress = CLAMP(0.0, vector, 1.0);
|
||||
|
||||
/* The previously applied map effect should be reset before applying the
|
||||
* current map effect. Otherwise, the incrementally added map effects
|
||||
* increase numerical error. */
|
||||
efl_gfx_mapping_reset(obj);
|
||||
efl_animation_apply(pd->in->animation, pd->in->progress, obj);
|
||||
|
||||
efl_event_callback_call(obj, EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_PROGRESS_UPDATED, &pd->in->progress);
|
||||
|
||||
//Not end. Keep going.
|
||||
if ((pd->in->speed < 0 && EINA_DBL_EQ(pd->in->progress, 0)) ||
|
||||
(pd->in->speed > 0 && EINA_DBL_EQ(pd->in->progress, 1.0)))
|
||||
{
|
||||
//Repeat animation
|
||||
if ((efl_animation_repeat_count_get(pd->in->animation) == EFL_ANIMATION_REPEAT_INFINITE) ||
|
||||
(pd->in->remaining_repeats > 0))
|
||||
{
|
||||
pd->in->remaining_repeats--;
|
||||
|
||||
if (efl_animation_repeat_mode_get(pd->in->animation) == EFL_CANVAS_ANIMATION_REPEAT_MODE_REVERSE)
|
||||
pd->in->speed *= -1;
|
||||
|
||||
pd->in->run_start_time = current;
|
||||
}
|
||||
else
|
||||
{
|
||||
efl_canvas_object_animation_stop(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_end(Efl_Canvas_Object_Animation *obj, Efl_Canvas_Object_Animation_Data *pd)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(pd->in);
|
||||
efl_event_callback_del(obj, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _animator_cb, obj);
|
||||
}
|
||||
|
||||
static void
|
||||
_start(Efl_Canvas_Object_Animation *obj, Efl_Canvas_Object_Animation_Data *pd, double delay)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(pd->in);
|
||||
pd->in->run_start_time = ecore_loop_time_get() - efl_animation_duration_get(pd->in->animation)*delay;
|
||||
efl_event_callback_add(obj, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _animator_cb, obj);
|
||||
_animator_cb(obj, NULL);
|
||||
}
|
||||
|
||||
static Eina_Value
|
||||
_start_fcb(Eo *o, void *data EINA_UNUSED, const Eina_Value v)
|
||||
{
|
||||
Efl_Canvas_Object_Animation_Data *pd = efl_data_scope_safe_get(o, MY_CLASS);
|
||||
if (!pd->in) return v; //animation was stopped before anything started
|
||||
_start(o, pd, pd->in->start_pos);
|
||||
return v;
|
||||
}
|
||||
|
||||
EOLIAN static Efl_Canvas_Animation*
|
||||
_efl_canvas_object_animation_animation_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Object_Animation_Data *pd)
|
||||
{
|
||||
if (!pd->in) return NULL;
|
||||
return pd->in->animation;
|
||||
}
|
||||
|
||||
EOLIAN static double
|
||||
_efl_canvas_object_animation_animation_progress_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Object_Animation_Data *pd)
|
||||
{
|
||||
if (pd->in && pd->in->animation)
|
||||
return (pd->in->speed < 0) ? fabs(1.0 - pd->in->progress) : pd->in->progress;
|
||||
else
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_canvas_object_animation_animation_pause_set(Eo *obj, Efl_Canvas_Object_Animation_Data *pd, Eina_Bool pause)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(pd->in);
|
||||
|
||||
if (pd->in->pause_state == pause) return;
|
||||
|
||||
if (pause)
|
||||
_end(obj, pd);
|
||||
else
|
||||
_start(obj, pd,(pd->in->speed < 0) ? 1.0 - pd->in->progress : pd->in->progress);
|
||||
pd->in->pause_state = pause;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_canvas_object_animation_animation_pause_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Object_Animation_Data *pd)
|
||||
{
|
||||
if (!pd->in) return EINA_FALSE;
|
||||
|
||||
return pd->in->pause_state;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_canvas_object_animation_animation_start(Eo *obj, Efl_Canvas_Object_Animation_Data *pd, Efl_Canvas_Animation *animation, double speed, double start_pos)
|
||||
{
|
||||
Efl_Canvas_Object_Animation_Indirect_Data *in;
|
||||
if (pd->in && pd->in->animation)
|
||||
efl_canvas_object_animation_stop(obj);
|
||||
EINA_SAFETY_ON_FALSE_RETURN(!pd->in);
|
||||
in = pd->in = calloc(1, sizeof(Efl_Canvas_Object_Animation_Indirect_Data));
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(animation);
|
||||
EINA_SAFETY_ON_FALSE_RETURN(start_pos >= 0.0 && start_pos <= 1.0);
|
||||
EINA_SAFETY_ON_FALSE_RETURN(!EINA_DBL_EQ(speed, 0.0));
|
||||
EINA_SAFETY_ON_FALSE_RETURN(efl_playable_seekable_get(animation));
|
||||
|
||||
in->pause_state = EINA_FALSE;
|
||||
in->animation = efl_ref(animation);
|
||||
in->remaining_repeats = efl_animation_repeat_count_get(animation); // -1 because one run is already going on
|
||||
in->speed = speed;
|
||||
in->start_pos = start_pos;
|
||||
efl_event_callback_call(obj, EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_CHANGED, in->animation);
|
||||
|
||||
if (efl_animation_start_delay_get(animation) > 0.0)
|
||||
{
|
||||
Eina_Future *f = efl_loop_timeout(efl_loop_get(obj), efl_animation_start_delay_get(animation));
|
||||
|
||||
efl_future_then(obj, f, .success = _start_fcb);
|
||||
}
|
||||
else
|
||||
_start(obj, pd, start_pos);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_canvas_object_animation_animation_stop(Eo *obj, Efl_Canvas_Object_Animation_Data *pd)
|
||||
{
|
||||
if (!pd->in) return;
|
||||
|
||||
if (!efl_animation_final_state_keep_get(pd->in->animation))
|
||||
efl_gfx_mapping_reset(obj);
|
||||
_end(obj, pd);
|
||||
efl_unref(pd->in->animation);
|
||||
pd->in->animation = NULL;
|
||||
|
||||
efl_event_callback_call(obj, EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_CHANGED, pd->in->animation);
|
||||
|
||||
free(pd->in);
|
||||
pd->in = NULL;
|
||||
}
|
||||
|
||||
#include "efl_canvas_object_animation.eo.c"
|
|
@ -0,0 +1,60 @@
|
|||
mixin @beta Efl.Canvas.Object_Animation requires Efl.Object
|
||||
{
|
||||
methods {
|
||||
@property animation {
|
||||
[[The animation that is currently played on the canvas object.
|
||||
|
||||
$null in case that there is no animation running.]]
|
||||
get {
|
||||
|
||||
}
|
||||
values {
|
||||
animation : Efl.Canvas.Animation; [[The animation which is currently applied on this object.]]
|
||||
}
|
||||
}
|
||||
@property animation_progress {
|
||||
[[The current progress of the animation, between 0.0 and 1.0.
|
||||
|
||||
Even if the animation is going backwards (speed < 0.0). the progress will still go from 0.0 to 1.0.
|
||||
|
||||
If there is no animation going on, this will return -1.0.
|
||||
]]
|
||||
get {
|
||||
|
||||
}
|
||||
values {
|
||||
progress : double; [[The progress the animation applying is currently in.]]
|
||||
}
|
||||
}
|
||||
@property animation_pause {
|
||||
[[Pause the animation
|
||||
|
||||
The animation will not be unset. When $pause is unset, the animation will be resumed at the same progress it has right now.
|
||||
]]
|
||||
values {
|
||||
pause : bool;
|
||||
}
|
||||
}
|
||||
animation_start {
|
||||
[[Start a new animation.
|
||||
|
||||
If there is a animation going on, this is stopped. The previous @.animation object will be replaced. The lifetime is adjusted accordingly.
|
||||
]]
|
||||
params {
|
||||
animation : Efl.Canvas.Animation @move; [[The animation to start. When not needed anymore, the reference that was passed is given up.]]
|
||||
speed : double; [[The speed of the playback. `1.0` is normal playback. Negative values mean backward playback.]]
|
||||
starting_progress : double; [[The progress to start, must be between 0.0 and 1.0.]]
|
||||
}
|
||||
}
|
||||
animation_stop {
|
||||
[[Stop the animation.
|
||||
|
||||
After this call, @.animation will return $null. The reference that was taken during @.animation_start will be given up on.
|
||||
]]
|
||||
}
|
||||
}
|
||||
events {
|
||||
animation,changed: Efl.Canvas.Animation; [[The animation object got changed.]]
|
||||
animation_progress,updated : double; [[The animation progress got changed.]]
|
||||
}
|
||||
}
|
|
@ -56,6 +56,7 @@ pub_eo_files = [
|
|||
'efl_gfx_mapping.eo',
|
||||
'efl_canvas_event_grabber.eo',
|
||||
'efl_canvas_text.eo',
|
||||
'efl_canvas_object_animation.eo',
|
||||
]
|
||||
|
||||
evas_canvas_eo_files = pub_eo_files
|
||||
|
@ -207,6 +208,7 @@ evas_src += files([
|
|||
'evas_canvas3d_primitive.c',
|
||||
'evas_canvas3d_node_callback.h',
|
||||
'evas_canvas3d_eet.c',
|
||||
'efl_canvas_object_animation.c',
|
||||
])
|
||||
|
||||
evas_include_directories += include_directories('.')
|
||||
|
|
|
@ -5,10 +5,17 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <Evas.h>
|
||||
#define EFL_LOOP_PROTECTED //needed to set the loop time, we need that to simulate time passing for animation,tick
|
||||
#include <Ecore.h>
|
||||
|
||||
#include "evas_suite.h"
|
||||
#include "evas_tests_helpers.h"
|
||||
|
||||
static int called_changed;
|
||||
static Efl_Canvas_Animation *animation_changed_ev;
|
||||
static int called_running;
|
||||
static double animation_running_position;
|
||||
|
||||
EFL_START_TEST(evas_object_various)
|
||||
{
|
||||
Evas *evas = EVAS_TEST_INIT_EVAS();
|
||||
|
@ -51,8 +58,159 @@ EFL_START_TEST(evas_object_freeze_events)
|
|||
}
|
||||
EFL_END_TEST
|
||||
|
||||
EFL_START_TEST(evas_object_animation_simple)
|
||||
{
|
||||
Evas *evas = EVAS_TEST_INIT_EVAS();
|
||||
Evas_Object *obj = evas_object_rectangle_add(evas);
|
||||
Efl_Canvas_Animation *animation = efl_add(EFL_CANVAS_ANIMATION_CLASS, evas);
|
||||
|
||||
ck_assert_ptr_eq(efl_canvas_object_animation_get(obj) , NULL);
|
||||
ck_assert(EINA_DBL_EQ(efl_canvas_object_animation_progress_get(obj), -1.0));
|
||||
|
||||
efl_canvas_object_animation_start(obj, animation, 1.0, 0.0);
|
||||
ck_assert_ptr_eq(efl_canvas_object_animation_get(obj) , animation);
|
||||
ck_assert(EINA_DBL_EQ(efl_canvas_object_animation_progress_get(obj), 0.0));
|
||||
|
||||
efl_canvas_object_animation_stop(obj);
|
||||
ck_assert_ptr_eq(efl_canvas_object_animation_get(obj) , NULL);
|
||||
ck_assert(EINA_DBL_EQ(efl_canvas_object_animation_progress_get(obj), -1.0));
|
||||
|
||||
efl_canvas_object_animation_start(obj, animation, 1.0, 0.0);
|
||||
efl_canvas_object_animation_stop(obj);
|
||||
|
||||
efl_canvas_object_animation_start(obj, animation, -1.0, 1.0);
|
||||
efl_canvas_object_animation_stop(obj);
|
||||
efl_canvas_object_animation_stop(obj);
|
||||
}
|
||||
EFL_END_TEST
|
||||
|
||||
EFL_START_TEST(evas_object_animation_progress)
|
||||
{
|
||||
Evas *evas = EVAS_TEST_INIT_EVAS();
|
||||
Evas_Object *obj = evas_object_rectangle_add(evas);
|
||||
Efl_Canvas_Animation *animation = efl_add(EFL_CANVAS_ANIMATION_CLASS, evas, efl_animation_duration_set(efl_added, 1.0));
|
||||
|
||||
efl_canvas_object_animation_start(obj, animation, 1.0, 0.0);
|
||||
efl_loop_time_set(efl_main_loop_get(), efl_loop_time_get(efl_main_loop_get()) + 0.5);
|
||||
efl_event_callback_call(obj, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, NULL);
|
||||
ck_assert(EINA_DBL_EQ(efl_canvas_object_animation_progress_get(obj), 0.5));
|
||||
efl_canvas_object_animation_stop(obj);
|
||||
}
|
||||
EFL_END_TEST
|
||||
|
||||
static inline void
|
||||
_simulate_time_passing(Eo *obj, double start, double jump)
|
||||
{
|
||||
efl_loop_time_set(efl_main_loop_get(), start + jump);
|
||||
efl_event_callback_call(obj, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, NULL);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_simulate_assert_time_passing(Eo *obj, double start, double jump, double expected_position)
|
||||
{
|
||||
_simulate_time_passing(obj, start, jump);
|
||||
ck_assert_int_eq((efl_canvas_object_animation_progress_get(obj)-expected_position)*10000, 0);
|
||||
}
|
||||
|
||||
EFL_START_TEST(evas_object_animation_pause)
|
||||
{
|
||||
Evas *evas = EVAS_TEST_INIT_EVAS();
|
||||
Evas_Object *obj = evas_object_rectangle_add(evas);
|
||||
double start = efl_loop_time_get(efl_main_loop_get());
|
||||
Efl_Canvas_Animation *animation = efl_add(EFL_CANVAS_ANIMATION_CLASS, evas, efl_animation_duration_set(efl_added, 1.0));
|
||||
|
||||
efl_canvas_object_animation_start(obj, animation, 1.0, 0.0);
|
||||
|
||||
_simulate_assert_time_passing(obj, start, 0.2, 0.2);
|
||||
efl_canvas_object_animation_pause_set(obj, EINA_TRUE);
|
||||
|
||||
_simulate_assert_time_passing(obj, start, 0.5, 0.2);
|
||||
efl_canvas_object_animation_pause_set(obj, EINA_FALSE);
|
||||
|
||||
_simulate_assert_time_passing(obj, start, 0.7, 0.4);
|
||||
efl_canvas_object_animation_stop(obj);
|
||||
}
|
||||
EFL_END_TEST
|
||||
|
||||
EFL_START_TEST(evas_object_animation_error)
|
||||
{
|
||||
Evas *evas = EVAS_TEST_INIT_EVAS();
|
||||
Evas_Object *obj = evas_object_rectangle_add(evas);
|
||||
Efl_Canvas_Animation *animation = efl_add(EFL_CANVAS_ANIMATION_CLASS, evas);
|
||||
EXPECT_ERROR_START;
|
||||
efl_canvas_object_animation_start(obj, NULL, 1.0, 0.0);
|
||||
EXPECT_ERROR_END;
|
||||
|
||||
EXPECT_ERROR_START;
|
||||
efl_canvas_object_animation_start(obj, animation, 0.0, 0.0);
|
||||
EXPECT_ERROR_END;
|
||||
efl_canvas_object_animation_stop(obj);
|
||||
|
||||
EXPECT_ERROR_START;
|
||||
efl_canvas_object_animation_start(obj, animation, 1.0, 2.0);
|
||||
EXPECT_ERROR_END;
|
||||
efl_canvas_object_animation_stop(obj);
|
||||
|
||||
EXPECT_ERROR_START;
|
||||
efl_canvas_object_animation_start(obj, animation, 1.0, -1.0);
|
||||
EXPECT_ERROR_END;
|
||||
efl_canvas_object_animation_stop(obj);
|
||||
}
|
||||
EFL_END_TEST
|
||||
|
||||
static void
|
||||
_anim_changed_cb(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED)
|
||||
{
|
||||
animation_changed_ev = event->info;
|
||||
called_changed ++;
|
||||
}
|
||||
|
||||
static void
|
||||
_anim_running_cb(void *data EINA_UNUSED, const Efl_Event *event)
|
||||
{
|
||||
animation_running_position = *((double*) event->info);
|
||||
called_running ++;
|
||||
}
|
||||
|
||||
EFL_CALLBACKS_ARRAY_DEFINE(animation_stats_cb,
|
||||
{EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_CHANGED, _anim_changed_cb },
|
||||
{EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_PROGRESS_UPDATED, _anim_running_cb },
|
||||
)
|
||||
|
||||
EFL_START_TEST(evas_object_animation_events)
|
||||
{
|
||||
Evas *evas = EVAS_TEST_INIT_EVAS();
|
||||
Evas_Object *obj = evas_object_rectangle_add(evas);
|
||||
double start = efl_loop_time_get(efl_main_loop_get());
|
||||
Efl_Canvas_Animation *animation = efl_add(EFL_CANVAS_ANIMATION_CLASS, evas, efl_animation_duration_set(efl_added, 1.0));
|
||||
|
||||
efl_event_callback_array_add(obj, animation_stats_cb(), NULL);
|
||||
|
||||
efl_canvas_object_animation_start(obj, animation, 1.0, 0.0);
|
||||
|
||||
ck_assert_int_eq(called_changed, 1);
|
||||
ck_assert_ptr_eq(animation_changed_ev, animation);
|
||||
ck_assert_int_eq(called_running, 1);
|
||||
ck_assert(EINA_DBL_EQ(animation_running_position, 0.0));
|
||||
|
||||
_simulate_time_passing(obj, start, 1.0);
|
||||
|
||||
ck_assert_int_eq(called_changed, 2);
|
||||
ck_assert_ptr_eq(animation_changed_ev, NULL);
|
||||
ck_assert_int_eq(called_running, 2);
|
||||
ck_assert(EINA_DBL_EQ(animation_running_position, 1.0));
|
||||
ck_assert_ptr_eq(efl_canvas_object_animation_get(obj), NULL);
|
||||
ck_assert(EINA_DBL_EQ(efl_canvas_object_animation_progress_get(obj), -1.0));
|
||||
}
|
||||
EFL_END_TEST
|
||||
|
||||
void evas_test_object(TCase *tc)
|
||||
{
|
||||
tcase_add_test(tc, evas_object_various);
|
||||
tcase_add_test(tc, evas_object_freeze_events);
|
||||
tcase_add_test(tc, evas_object_animation_simple);
|
||||
tcase_add_test(tc, evas_object_animation_progress);
|
||||
tcase_add_test(tc, evas_object_animation_pause);
|
||||
tcase_add_test(tc, evas_object_animation_error);
|
||||
tcase_add_test(tc, evas_object_animation_events);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue