summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2019-11-07 11:24:21 +0100
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2019-11-20 09:58:24 +0100
commitfa93893548858b83055e95c9e334f3d5875958be (patch)
tree36685a87de79e8d573dd9ec7aba5ceaca710dbfb
parent9bb2df996642f046f79466cff8fefcd43d28921e (diff)
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
-rw-r--r--src/examples/evas/efl-canvas-animation.c179
-rw-r--r--src/examples/evas/meson.build1
-rw-r--r--src/lib/evas/Evas_Eo.h2
-rw-r--r--src/lib/evas/canvas/efl_canvas_object.eo2
-rw-r--r--src/lib/evas/canvas/efl_canvas_object_animation.c197
-rw-r--r--src/lib/evas/canvas/efl_canvas_object_animation.eo60
-rw-r--r--src/lib/evas/canvas/meson.build2
-rw-r--r--src/tests/evas/evas_test_object.c158
8 files changed, 599 insertions, 2 deletions
diff --git a/src/examples/evas/efl-canvas-animation.c b/src/examples/evas/efl-canvas-animation.c
new file mode 100644
index 0000000..2cc2355
--- /dev/null
+++ b/src/examples/evas/efl-canvas-animation.c
@@ -0,0 +1,179 @@
1/**
2 * Example of animation in efl canvas
3 *
4 * You'll need at least one engine built for it (excluding the buffer
5 * one). See stdout/stderr for output.
6 *
7 */
8
9#ifdef HAVE_CONFIG_H
10#include "config.h"
11#endif
12
13#include <Ecore.h>
14#include <Ecore_Evas.h>
15
16#include <stdlib.h>
17#include <stdio.h>
18#include <string.h>
19
20#define WIDTH (640)
21#define HEIGHT (480)
22
23struct example_data
24{
25 Ecore_Evas *ee;
26 Evas *evas;
27 Evas_Object *bg, *scale;
28 double current_speed;
29};
30
31static struct example_data d;
32
33static Evas_Object * /* new rectangle to be put in the box */
34_new_rectangle_add(Evas *e)
35{
36 Efl_Canvas_Rectangle *rect = efl_add(EFL_CANVAS_RECTANGLE_CLASS, e);
37
38 efl_gfx_entity_size_set(rect, EINA_SIZE2D(10, 10));
39 efl_gfx_color_set(rect, 0, 255, 0, 255);
40 efl_gfx_entity_visible_set(rect, EINA_TRUE);
41
42 return rect;
43}
44
45/* use the following commands to interact with this example - 'h' is
46 * the key for help */
47static void
48_on_keydown(void *data EINA_UNUSED, const Efl_Event *ev)
49{
50 if (strcmp(efl_input_key_sym_get(ev->info) , "r") == 0)
51 {
52 Efl_Canvas_Animation *animation = efl_canvas_object_animation_get(d.scale);
53 double current_pos = efl_canvas_object_animation_progress_get(d.scale);
54 d.current_speed *= -1;
55 efl_canvas_object_animation_start(d.scale, animation, d.current_speed, 1.0 - current_pos);
56 }
57 if (strcmp(efl_input_key_sym_get(ev->info), "p") == 0)
58 {
59 efl_canvas_object_animation_pause_set(d.scale, !efl_canvas_object_animation_pause_get(d.scale));
60 }
61}
62
63static void
64_on_delete(Ecore_Evas *ee EINA_UNUSED)
65{
66 ecore_main_loop_quit();
67}
68
69static void /* adjust canvas' contents on resizes */
70_canvas_resize_cb(Ecore_Evas *ee)
71{
72 int w, h;
73
74 ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
75
76 efl_gfx_entity_geometry_set(d.bg, EINA_RECT(0, 0, w, h));
77}
78
79static void
80print_help(void)
81{
82 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");
83}
84
85int
86main(void)
87{
88 if (!ecore_evas_init())
89 return EXIT_FAILURE;
90
91 /* this will give you a window with an Evas canvas under the first
92 * engine available */
93 d.ee = ecore_evas_new(NULL, 0, 0, WIDTH, HEIGHT, NULL);
94 if (!d.ee)
95 goto panic;
96
97 print_help();
98
99 ecore_evas_name_class_set(d.ee, "Evas Animation example", "Evas Animation Example");
100 ecore_evas_callback_delete_request_set(d.ee, _on_delete);
101 ecore_evas_callback_resize_set(d.ee, _canvas_resize_cb);
102 ecore_evas_show(d.ee);
103
104 d.evas = ecore_evas_get(d.ee);
105
106 d.bg = _new_rectangle_add(d.evas);
107 efl_gfx_color_set(d.bg, 255, 255, 255, 255);
108 efl_gfx_entity_visible_set(d.bg, EINA_TRUE);
109 efl_canvas_object_key_focus_set(d.bg, EINA_TRUE);
110 efl_event_callback_add(d.bg, EFL_EVENT_KEY_DOWN, _on_keydown, NULL);
111
112 _canvas_resize_cb(d.ee);
113
114 Evas_Object *scale_rect = _new_rectangle_add(d.evas);
115 efl_gfx_entity_geometry_set(scale_rect, EINA_RECT(50, 50, 50, 50));
116 efl_canvas_object_animation_start(scale_rect,
117 efl_new(EFL_CANVAS_ANIMATION_SCALE_CLASS,
118 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)),
119 efl_animation_start_delay_set(efl_added, 5.0),
120 efl_animation_duration_set(efl_added, 2.0),
121 efl_animation_repeat_count_set(efl_added, EFL_ANIMATION_REPEAT_INFINITE)
122 ),
123 1.0, 0.0);
124
125 Evas_Object *scale_rect2 = _new_rectangle_add(d.evas);
126 efl_gfx_entity_geometry_set(scale_rect2, EINA_RECT(50, 200, 50, 50));
127 efl_canvas_object_animation_start(scale_rect2,
128 efl_new(EFL_CANVAS_ANIMATION_SCALE_CLASS,
129 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)),
130 efl_animation_duration_set(efl_added, 2.0),
131 efl_animation_repeat_count_set(efl_added, EFL_ANIMATION_REPEAT_INFINITE),
132 efl_animation_repeat_mode_set(efl_added, EFL_CANVAS_ANIMATION_REPEAT_MODE_REVERSE)
133 ),
134 1.0, 0.0);
135
136 Evas_Object *scale_rect3 = _new_rectangle_add(d.evas);
137 efl_gfx_entity_geometry_set(scale_rect3, EINA_RECT(50, 350, 50, 50));
138 efl_canvas_object_animation_start(scale_rect3,
139 efl_new(EFL_CANVAS_ANIMATION_SCALE_CLASS,
140 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)),
141 efl_animation_duration_set(efl_added, 2.0),
142 efl_animation_repeat_count_set(efl_added, 3),
143 efl_animation_repeat_mode_set(efl_added, EFL_CANVAS_ANIMATION_REPEAT_MODE_REVERSE)
144 ),
145 1.0, 0.0);
146
147 Evas_Object *scale_rect4 = _new_rectangle_add(d.evas);
148 efl_gfx_entity_geometry_set(scale_rect4, EINA_RECT(200, 50, 50, 50));
149 efl_canvas_object_animation_start(scale_rect4,
150 efl_new(EFL_CANVAS_ANIMATION_SCALE_CLASS,
151 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)),
152 efl_animation_duration_set(efl_added, 2.0),
153 efl_animation_final_state_keep_set(efl_added, EINA_TRUE)
154 ),
155 1.0, 0.0);
156
157
158 Evas_Object *scale_rect5 = d.scale = _new_rectangle_add(d.evas);
159 efl_gfx_color_set(scale_rect5, 255, 0, 0, 255);
160 efl_gfx_entity_geometry_set(scale_rect5, EINA_RECT(200, 200, 50, 50));
161 efl_canvas_object_animation_start(scale_rect5,
162 efl_new(EFL_CANVAS_ANIMATION_SCALE_CLASS,
163 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)),
164 efl_animation_duration_set(efl_added, 5.0),
165 efl_animation_repeat_count_set(efl_added, EFL_ANIMATION_REPEAT_INFINITE)
166 ),
167 1.0, 0.0);
168 d.current_speed = 1.0;
169
170 ecore_main_loop_begin();
171 ecore_evas_shutdown();
172 return 0;
173
174panic:
175 fprintf(stderr, "error: Requires at least one Evas engine built and linked"
176 " to ecore-evas for this example to run properly.\n");
177 return -2;
178}
179
diff --git a/src/examples/evas/meson.build b/src/examples/evas/meson.build
index 659f9a5..93539e7 100644
--- a/src/examples/evas/meson.build
+++ b/src/examples/evas/meson.build
@@ -50,6 +50,7 @@ examples = [
50 'evas-vg-batman', 50 'evas-vg-batman',
51 'evas-vg-simple', 51 'evas-vg-simple',
52 'evas-vg-json', 52 'evas-vg-json',
53 'efl-canvas-animation',
53] 54]
54 55
55foreach example : examples 56foreach example : examples
diff --git a/src/lib/evas/Evas_Eo.h b/src/lib/evas/Evas_Eo.h
index 5a725cc..13ecde5 100644
--- a/src/lib/evas/Evas_Eo.h
+++ b/src/lib/evas/Evas_Eo.h
@@ -223,7 +223,7 @@ struct _Efl_Canvas_Object_Animation_Event
223#include "gesture/efl_gesture_events.eo.h" 223#include "gesture/efl_gesture_events.eo.h"
224 224
225#include "canvas/efl_canvas_object.eo.h" 225#include "canvas/efl_canvas_object.eo.h"
226 226#include "canvas/efl_canvas_object_animation.eo.h"
227#include "canvas/efl_canvas_animation.eo.h" 227#include "canvas/efl_canvas_animation.eo.h"
228#include "canvas/efl_canvas_animation_alpha.eo.h" 228#include "canvas/efl_canvas_animation_alpha.eo.h"
229#include "canvas/efl_canvas_animation_rotate.eo.h" 229#include "canvas/efl_canvas_animation_rotate.eo.h"
diff --git a/src/lib/evas/canvas/efl_canvas_object.eo b/src/lib/evas/canvas/efl_canvas_object.eo
index 785c496..dbee3db 100644
--- a/src/lib/evas/canvas/efl_canvas_object.eo
+++ b/src/lib/evas/canvas/efl_canvas_object.eo
@@ -11,7 +11,7 @@ struct Efl.Event_Animator_Tick {
11 11
12abstract Efl.Canvas.Object extends Efl.Loop_Consumer implements Efl.Gfx.Entity, Efl.Gfx.Color, Efl.Gfx.Stack, 12abstract Efl.Canvas.Object extends Efl.Loop_Consumer implements Efl.Gfx.Entity, Efl.Gfx.Color, Efl.Gfx.Stack,
13 Efl.Input.Interface, Efl.Gfx.Hint, 13 Efl.Input.Interface, Efl.Gfx.Hint,
14 Efl.Gfx.Mapping, Efl.Canvas.Pointer, Efl.Gesture.Events 14 Efl.Gfx.Mapping, Efl.Canvas.Pointer, Efl.Gesture.Events, Efl.Canvas.Object_Animation
15{ 15{
16 [[Efl canvas object abstract class 16 [[Efl canvas object abstract class
17 17
diff --git a/src/lib/evas/canvas/efl_canvas_object_animation.c b/src/lib/evas/canvas/efl_canvas_object_animation.c
new file mode 100644
index 0000000..b86912d
--- /dev/null
+++ b/src/lib/evas/canvas/efl_canvas_object_animation.c
@@ -0,0 +1,197 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "evas_common_private.h"
6#include "evas_private.h"
7#include "efl_canvas_object_animation.eo.h"
8#include <Ecore.h>
9
10#define MY_CLASS EFL_CANVAS_OBJECT_ANIMATION_MIXIN
11
12
13typedef struct
14{
15 Efl_Canvas_Animation *animation;
16 double speed;
17 double progress;
18 double run_start_time;
19 double start_pos;
20 int remaining_repeats;
21 Efl_Loop_Timer *timer;
22 Eina_Bool pause_state : 1;
23} Efl_Canvas_Object_Animation_Indirect_Data;
24
25typedef struct
26{
27 Efl_Canvas_Object_Animation_Indirect_Data *in;
28} Efl_Canvas_Object_Animation_Data;
29
30static void _end(Efl_Canvas_Object_Animation *obj, Efl_Canvas_Object_Animation_Data *pd);
31
32
33static void
34_animator_cb(void *data, const Efl_Event *ev EINA_UNUSED)
35{
36 Eo *obj = data;
37 Efl_Canvas_Object_Animation_Data *pd = efl_data_scope_get(obj, MY_CLASS);
38 double duration, elapsed_time, vector, current;
39
40 EINA_SAFETY_ON_NULL_RETURN(pd->in);
41 current = ecore_loop_time_get();
42 EINA_SAFETY_ON_FALSE_RETURN(pd->in->run_start_time <= current);
43
44 duration = efl_animation_duration_get(pd->in->animation) / pd->in->speed;
45 elapsed_time = current - pd->in->run_start_time;
46 vector = elapsed_time / duration;
47
48 /* When animation player starts, _animator_cb() is called immediately so
49 * both elapsed time and progress are 0.0.
50 * Since it is the beginning of the animation if progress is 0.0, the
51 * following codes for animation should be executed. */
52 if (pd->in->speed < 0.0)
53 vector += 1.0;
54 pd->in->progress = CLAMP(0.0, vector, 1.0);
55
56 /* The previously applied map effect should be reset before applying the
57 * current map effect. Otherwise, the incrementally added map effects
58 * increase numerical error. */
59 efl_gfx_mapping_reset(obj);
60 efl_animation_apply(pd->in->animation, pd->in->progress, obj);
61
62 efl_event_callback_call(obj, EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_PROGRESS_UPDATED, &pd->in->progress);
63
64 //Not end. Keep going.
65 if ((pd->in->speed < 0 && EINA_DBL_EQ(pd->in->progress, 0)) ||
66 (pd->in->speed > 0 && EINA_DBL_EQ(pd->in->progress, 1.0)))
67 {
68 //Repeat animation
69 if ((efl_animation_repeat_count_get(pd->in->animation) == EFL_ANIMATION_REPEAT_INFINITE) ||
70 (pd->in->remaining_repeats > 0))
71 {
72 pd->in->remaining_repeats--;
73
74 if (efl_animation_repeat_mode_get(pd->in->animation) == EFL_CANVAS_ANIMATION_REPEAT_MODE_REVERSE)
75 pd->in->speed *= -1;
76
77 pd->in->run_start_time = current;
78 }
79 else
80 {
81 efl_canvas_object_animation_stop(obj);
82 }
83 }
84}
85
86static void
87_end(Efl_Canvas_Object_Animation *obj, Efl_Canvas_Object_Animation_Data *pd)
88{
89 EINA_SAFETY_ON_NULL_RETURN(pd->in);
90 efl_event_callback_del(obj, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _animator_cb, obj);
91}
92
93static void
94_start(Efl_Canvas_Object_Animation *obj, Efl_Canvas_Object_Animation_Data *pd, double delay)
95{
96 EINA_SAFETY_ON_NULL_RETURN(pd->in);
97 pd->in->run_start_time = ecore_loop_time_get() - efl_animation_duration_get(pd->in->animation)*delay;
98 efl_event_callback_add(obj, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _animator_cb, obj);
99 _animator_cb(obj, NULL);
100}
101
102static Eina_Value
103_start_fcb(Eo *o, void *data EINA_UNUSED, const Eina_Value v)
104{
105 Efl_Canvas_Object_Animation_Data *pd = efl_data_scope_safe_get(o, MY_CLASS);
106 if (!pd->in) return v; //animation was stopped before anything started
107 _start(o, pd, pd->in->start_pos);
108 return v;
109}
110
111EOLIAN static Efl_Canvas_Animation*
112_efl_canvas_object_animation_animation_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Object_Animation_Data *pd)
113{
114 if (!pd->in) return NULL;
115 return pd->in->animation;
116}
117
118EOLIAN static double
119_efl_canvas_object_animation_animation_progress_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Object_Animation_Data *pd)
120{
121 if (pd->in && pd->in->animation)
122 return (pd->in->speed < 0) ? fabs(1.0 - pd->in->progress) : pd->in->progress;
123 else
124 return -1.0;
125}
126
127EOLIAN static void
128_efl_canvas_object_animation_animation_pause_set(Eo *obj, Efl_Canvas_Object_Animation_Data *pd, Eina_Bool pause)
129{
130 EINA_SAFETY_ON_NULL_RETURN(pd->in);
131
132 if (pd->in->pause_state == pause) return;
133
134 if (pause)
135 _end(obj, pd);
136 else
137 _start(obj, pd,(pd->in->speed < 0) ? 1.0 - pd->in->progress : pd->in->progress);
138 pd->in->pause_state = pause;
139}
140
141EOLIAN static Eina_Bool
142_efl_canvas_object_animation_animation_pause_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Object_Animation_Data *pd)
143{
144 if (!pd->in) return EINA_FALSE;
145
146 return pd->in->pause_state;
147}
148
149EOLIAN static void
150_efl_canvas_object_animation_animation_start(Eo *obj, Efl_Canvas_Object_Animation_Data *pd, Efl_Canvas_Animation *animation, double speed, double start_pos)
151{
152 Efl_Canvas_Object_Animation_Indirect_Data *in;
153 if (pd->in && pd->in->animation)
154 efl_canvas_object_animation_stop(obj);
155 EINA_SAFETY_ON_FALSE_RETURN(!pd->in);
156 in = pd->in = calloc(1, sizeof(Efl_Canvas_Object_Animation_Indirect_Data));
157
158 EINA_SAFETY_ON_NULL_RETURN(animation);
159 EINA_SAFETY_ON_FALSE_RETURN(start_pos >= 0.0 && start_pos <= 1.0);
160 EINA_SAFETY_ON_FALSE_RETURN(!EINA_DBL_EQ(speed, 0.0));
161 EINA_SAFETY_ON_FALSE_RETURN(efl_playable_seekable_get(animation));
162
163 in->pause_state = EINA_FALSE;
164 in->animation = efl_ref(animation);
165 in->remaining_repeats = efl_animation_repeat_count_get(animation); // -1 because one run is already going on
166 in->speed = speed;
167 in->start_pos = start_pos;
168 efl_event_callback_call(obj, EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_CHANGED, in->animation);
169
170 if (efl_animation_start_delay_get(animation) > 0.0)
171 {
172 Eina_Future *f = efl_loop_timeout(efl_loop_get(obj), efl_animation_start_delay_get(animation));
173
174 efl_future_then(obj, f, .success = _start_fcb);
175 }
176 else
177 _start(obj, pd, start_pos);
178}
179
180EOLIAN static void
181_efl_canvas_object_animation_animation_stop(Eo *obj, Efl_Canvas_Object_Animation_Data *pd)
182{
183 if (!pd->in) return;
184
185 if (!efl_animation_final_state_keep_get(pd->in->animation))
186 efl_gfx_mapping_reset(obj);
187 _end(obj, pd);
188 efl_unref(pd->in->animation);
189 pd->in->animation = NULL;
190
191 efl_event_callback_call(obj, EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_CHANGED, pd->in->animation);
192
193 free(pd->in);
194 pd->in = NULL;
195}
196
197#include "efl_canvas_object_animation.eo.c"
diff --git a/src/lib/evas/canvas/efl_canvas_object_animation.eo b/src/lib/evas/canvas/efl_canvas_object_animation.eo
new file mode 100644
index 0000000..49146a6
--- /dev/null
+++ b/src/lib/evas/canvas/efl_canvas_object_animation.eo
@@ -0,0 +1,60 @@
1mixin @beta Efl.Canvas.Object_Animation requires Efl.Object
2{
3 methods {
4 @property animation {
5 [[The animation that is currently played on the canvas object.
6
7 $null in case that there is no animation running.]]
8 get {
9
10 }
11 values {
12 animation : Efl.Canvas.Animation; [[The animation which is currently applied on this object.]]
13 }
14 }
15 @property animation_progress {
16 [[The current progress of the animation, between 0.0 and 1.0.
17
18 Even if the animation is going backwards (speed < 0.0). the progress will still go from 0.0 to 1.0.
19
20 If there is no animation going on, this will return -1.0.
21 ]]
22 get {
23
24 }
25 values {
26 progress : double; [[The progress the animation applying is currently in.]]
27 }
28 }
29 @property animation_pause {
30 [[Pause the animation
31
32 The animation will not be unset. When $pause is unset, the animation will be resumed at the same progress it has right now.
33 ]]
34 values {
35 pause : bool;
36 }
37 }
38 animation_start {
39 [[Start a new animation.
40
41 If there is a animation going on, this is stopped. The previous @.animation object will be replaced. The lifetime is adjusted accordingly.
42 ]]
43 params {
44 animation : Efl.Canvas.Animation @move; [[The animation to start. When not needed anymore, the reference that was passed is given up.]]
45 speed : double; [[The speed of the playback. `1.0` is normal playback. Negative values mean backward playback.]]
46 starting_progress : double; [[The progress to start, must be between 0.0 and 1.0.]]
47 }
48 }
49 animation_stop {
50 [[Stop the animation.
51
52 After this call, @.animation will return $null. The reference that was taken during @.animation_start will be given up on.
53 ]]
54 }
55 }
56 events {
57 animation,changed: Efl.Canvas.Animation; [[The animation object got changed.]]
58 animation_progress,updated : double; [[The animation progress got changed.]]
59 }
60}
diff --git a/src/lib/evas/canvas/meson.build b/src/lib/evas/canvas/meson.build
index 1edaeca..c13d333 100644
--- a/src/lib/evas/canvas/meson.build
+++ b/src/lib/evas/canvas/meson.build
@@ -56,6 +56,7 @@ pub_eo_files = [
56 'efl_gfx_mapping.eo', 56 'efl_gfx_mapping.eo',
57 'efl_canvas_event_grabber.eo', 57 'efl_canvas_event_grabber.eo',
58 'efl_canvas_text.eo', 58 'efl_canvas_text.eo',
59 'efl_canvas_object_animation.eo',
59] 60]
60 61
61evas_canvas_eo_files = pub_eo_files 62evas_canvas_eo_files = pub_eo_files
@@ -207,6 +208,7 @@ evas_src += files([
207 'evas_canvas3d_primitive.c', 208 'evas_canvas3d_primitive.c',
208 'evas_canvas3d_node_callback.h', 209 'evas_canvas3d_node_callback.h',
209 'evas_canvas3d_eet.c', 210 'evas_canvas3d_eet.c',
211 'efl_canvas_object_animation.c',
210 ]) 212 ])
211 213
212evas_include_directories += include_directories('.') 214evas_include_directories += include_directories('.')
diff --git a/src/tests/evas/evas_test_object.c b/src/tests/evas/evas_test_object.c
index d2de52a..7024488 100644
--- a/src/tests/evas/evas_test_object.c
+++ b/src/tests/evas/evas_test_object.c
@@ -5,10 +5,17 @@
5#include <stdio.h> 5#include <stdio.h>
6 6
7#include <Evas.h> 7#include <Evas.h>
8#define EFL_LOOP_PROTECTED //needed to set the loop time, we need that to simulate time passing for animation,tick
9#include <Ecore.h>
8 10
9#include "evas_suite.h" 11#include "evas_suite.h"
10#include "evas_tests_helpers.h" 12#include "evas_tests_helpers.h"
11 13
14static int called_changed;
15static Efl_Canvas_Animation *animation_changed_ev;
16static int called_running;
17static double animation_running_position;
18
12EFL_START_TEST(evas_object_various) 19EFL_START_TEST(evas_object_various)
13{ 20{
14 Evas *evas = EVAS_TEST_INIT_EVAS(); 21 Evas *evas = EVAS_TEST_INIT_EVAS();
@@ -51,8 +58,159 @@ EFL_START_TEST(evas_object_freeze_events)
51} 58}
52EFL_END_TEST 59EFL_END_TEST
53 60
61EFL_START_TEST(evas_object_animation_simple)
62{
63 Evas *evas = EVAS_TEST_INIT_EVAS();
64 Evas_Object *obj = evas_object_rectangle_add(evas);
65 Efl_Canvas_Animation *animation = efl_add(EFL_CANVAS_ANIMATION_CLASS, evas);
66
67 ck_assert_ptr_eq(efl_canvas_object_animation_get(obj) , NULL);
68 ck_assert(EINA_DBL_EQ(efl_canvas_object_animation_progress_get(obj), -1.0));
69
70 efl_canvas_object_animation_start(obj, animation, 1.0, 0.0);
71 ck_assert_ptr_eq(efl_canvas_object_animation_get(obj) , animation);
72 ck_assert(EINA_DBL_EQ(efl_canvas_object_animation_progress_get(obj), 0.0));
73
74 efl_canvas_object_animation_stop(obj);
75 ck_assert_ptr_eq(efl_canvas_object_animation_get(obj) , NULL);
76 ck_assert(EINA_DBL_EQ(efl_canvas_object_animation_progress_get(obj), -1.0));
77
78 efl_canvas_object_animation_start(obj, animation, 1.0, 0.0);
79 efl_canvas_object_animation_stop(obj);
80
81 efl_canvas_object_animation_start(obj, animation, -1.0, 1.0);
82 efl_canvas_object_animation_stop(obj);
83 efl_canvas_object_animation_stop(obj);
84}
85EFL_END_TEST
86
87EFL_START_TEST(evas_object_animation_progress)
88{
89 Evas *evas = EVAS_TEST_INIT_EVAS();
90 Evas_Object *obj = evas_object_rectangle_add(evas);
91 Efl_Canvas_Animation *animation = efl_add(EFL_CANVAS_ANIMATION_CLASS, evas, efl_animation_duration_set(efl_added, 1.0));
92
93 efl_canvas_object_animation_start(obj, animation, 1.0, 0.0);
94 efl_loop_time_set(efl_main_loop_get(), efl_loop_time_get(efl_main_loop_get()) + 0.5);
95 efl_event_callback_call(obj, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, NULL);
96 ck_assert(EINA_DBL_EQ(efl_canvas_object_animation_progress_get(obj), 0.5));
97 efl_canvas_object_animation_stop(obj);
98}
99EFL_END_TEST
100
101static inline void
102_simulate_time_passing(Eo *obj, double start, double jump)
103{
104 efl_loop_time_set(efl_main_loop_get(), start + jump);
105 efl_event_callback_call(obj, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, NULL);
106}
107
108static inline void
109_simulate_assert_time_passing(Eo *obj, double start, double jump, double expected_position)
110{
111 _simulate_time_passing(obj, start, jump);
112 ck_assert_int_eq((efl_canvas_object_animation_progress_get(obj)-expected_position)*10000, 0);
113}
114
115EFL_START_TEST(evas_object_animation_pause)
116{
117 Evas *evas = EVAS_TEST_INIT_EVAS();
118 Evas_Object *obj = evas_object_rectangle_add(evas);
119 double start = efl_loop_time_get(efl_main_loop_get());
120 Efl_Canvas_Animation *animation = efl_add(EFL_CANVAS_ANIMATION_CLASS, evas, efl_animation_duration_set(efl_added, 1.0));
121
122 efl_canvas_object_animation_start(obj, animation, 1.0, 0.0);
123
124 _simulate_assert_time_passing(obj, start, 0.2, 0.2);
125 efl_canvas_object_animation_pause_set(obj, EINA_TRUE);
126
127 _simulate_assert_time_passing(obj, start, 0.5, 0.2);
128 efl_canvas_object_animation_pause_set(obj, EINA_FALSE);
129
130 _simulate_assert_time_passing(obj, start, 0.7, 0.4);
131 efl_canvas_object_animation_stop(obj);
132}
133EFL_END_TEST
134
135EFL_START_TEST(evas_object_animation_error)
136{
137 Evas *evas = EVAS_TEST_INIT_EVAS();
138 Evas_Object *obj = evas_object_rectangle_add(evas);
139 Efl_Canvas_Animation *animation = efl_add(EFL_CANVAS_ANIMATION_CLASS, evas);
140 EXPECT_ERROR_START;
141 efl_canvas_object_animation_start(obj, NULL, 1.0, 0.0);
142 EXPECT_ERROR_END;
143
144 EXPECT_ERROR_START;
145 efl_canvas_object_animation_start(obj, animation, 0.0, 0.0);
146 EXPECT_ERROR_END;
147 efl_canvas_object_animation_stop(obj);
148
149 EXPECT_ERROR_START;
150 efl_canvas_object_animation_start(obj, animation, 1.0, 2.0);
151 EXPECT_ERROR_END;
152 efl_canvas_object_animation_stop(obj);
153
154 EXPECT_ERROR_START;
155 efl_canvas_object_animation_start(obj, animation, 1.0, -1.0);
156 EXPECT_ERROR_END;
157 efl_canvas_object_animation_stop(obj);
158}
159EFL_END_TEST
160
161static void
162_anim_changed_cb(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED)
163{
164 animation_changed_ev = event->info;
165 called_changed ++;
166}
167
168static void
169_anim_running_cb(void *data EINA_UNUSED, const Efl_Event *event)
170{
171 animation_running_position = *((double*) event->info);
172 called_running ++;
173}
174
175EFL_CALLBACKS_ARRAY_DEFINE(animation_stats_cb,
176 {EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_CHANGED, _anim_changed_cb },
177 {EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_PROGRESS_UPDATED, _anim_running_cb },
178)
179
180EFL_START_TEST(evas_object_animation_events)
181{
182 Evas *evas = EVAS_TEST_INIT_EVAS();
183 Evas_Object *obj = evas_object_rectangle_add(evas);
184 double start = efl_loop_time_get(efl_main_loop_get());
185 Efl_Canvas_Animation *animation = efl_add(EFL_CANVAS_ANIMATION_CLASS, evas, efl_animation_duration_set(efl_added, 1.0));
186
187 efl_event_callback_array_add(obj, animation_stats_cb(), NULL);
188
189 efl_canvas_object_animation_start(obj, animation, 1.0, 0.0);
190
191 ck_assert_int_eq(called_changed, 1);
192 ck_assert_ptr_eq(animation_changed_ev, animation);
193 ck_assert_int_eq(called_running, 1);
194 ck_assert(EINA_DBL_EQ(animation_running_position, 0.0));
195
196 _simulate_time_passing(obj, start, 1.0);
197
198 ck_assert_int_eq(called_changed, 2);
199 ck_assert_ptr_eq(animation_changed_ev, NULL);
200 ck_assert_int_eq(called_running, 2);
201 ck_assert(EINA_DBL_EQ(animation_running_position, 1.0));
202 ck_assert_ptr_eq(efl_canvas_object_animation_get(obj), NULL);
203 ck_assert(EINA_DBL_EQ(efl_canvas_object_animation_progress_get(obj), -1.0));
204}
205EFL_END_TEST
206
54void evas_test_object(TCase *tc) 207void evas_test_object(TCase *tc)
55{ 208{
56 tcase_add_test(tc, evas_object_various); 209 tcase_add_test(tc, evas_object_various);
57 tcase_add_test(tc, evas_object_freeze_events); 210 tcase_add_test(tc, evas_object_freeze_events);
211 tcase_add_test(tc, evas_object_animation_simple);
212 tcase_add_test(tc, evas_object_animation_progress);
213 tcase_add_test(tc, evas_object_animation_pause);
214 tcase_add_test(tc, evas_object_animation_error);
215 tcase_add_test(tc, evas_object_animation_events);
58} 216}