1 /**
2  * @file anim.h
3  *
4  */
5 
6 #ifndef ANIM_H
7 #define ANIM_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 /*********************
14  *      INCLUDES
15  *********************/
16 #include "../lv_conf_internal.h"
17 
18 #include <stdint.h>
19 #include <stdbool.h>
20 #include <string.h>
21 #include "lv_mem.h"
22 
23 /*********************
24  *      DEFINES
25  *********************/
26 
27 /**********************
28  *      TYPEDEFS
29  **********************/
30 
31 /** Can be used to indicate if animations are enabled or disabled in a case*/
32 enum {
33     LV_ANIM_OFF,
34     LV_ANIM_ON,
35 };
36 
37 typedef uint8_t lv_anim_enable_t;
38 
39 /** Type of the animated value*/
40 typedef lv_coord_t lv_anim_value_t;
41 
42 #if LV_USE_ANIMATION
43 
44 #define LV_ANIM_REPEAT_INFINITE      0xFFFF
45 
46 
47 struct _lv_anim_t;
48 struct _lv_anim_path_t;
49 /** Get the current value during an animation*/
50 typedef lv_anim_value_t (*lv_anim_path_cb_t)(const struct _lv_anim_path_t *, const struct _lv_anim_t *);
51 
52 typedef struct _lv_anim_path_t {
53     lv_anim_path_cb_t cb;
54     void * user_data;
55 } lv_anim_path_t;
56 
57 
58 
59 /** Generic prototype of "animator" functions.
60  * First parameter is the variable to animate.
61  * Second parameter is the value to set.
62  * Compatible with `lv_xxx_set_yyy(obj, value)` functions
63  * The `x` in `_xcb_t` means its not a fully generic prototype because
64  * it doesn't receive `lv_anim_t *` as its first argument*/
65 typedef void (*lv_anim_exec_xcb_t)(void *, lv_anim_value_t);
66 
67 /** Same as `lv_anim_exec_xcb_t` but receives `lv_anim_t *` as the first parameter.
68  * It's more consistent but less convenient. Might be used by binding generator functions.*/
69 typedef void (*lv_anim_custom_exec_cb_t)(struct _lv_anim_t *, lv_anim_value_t);
70 
71 /** Callback to call when the animation is ready*/
72 typedef void (*lv_anim_ready_cb_t)(struct _lv_anim_t *);
73 
74 /** Callback to call when the animation really stars (considering `delay`)*/
75 typedef void (*lv_anim_start_cb_t)(struct _lv_anim_t *);
76 
77 /** Describes an animation*/
78 typedef struct _lv_anim_t {
79     void * var;                  /**<Variable to animate*/
80     lv_anim_exec_xcb_t exec_cb;   /**< Function to execute to animate*/
81     lv_anim_start_cb_t start_cb; /**< Call it when the animation is starts (considering `delay`)*/
82     lv_anim_ready_cb_t ready_cb; /**< Call it when the animation is ready*/
83     lv_anim_path_t path;         /**< Describe the path (curve) of animations*/
84     int32_t start;               /**< Start value*/
85     int32_t current;             /**< Current value */
86     int32_t end;                 /**< End value*/
87     int32_t time;               /**< Animation time in ms*/
88     int32_t act_time;            /**< Current time in animation. Set to negative to make delay.*/
89     uint32_t playback_delay;     /**< Wait before play back*/
90     uint32_t playback_time;      /**< Duration of playback animation*/
91     uint32_t repeat_delay;       /**< Wait before repeat*/
92     uint16_t repeat_cnt;         /**< Repeat count for the animation*/
93     uint8_t early_apply  : 1;    /**< 1: Apply start value immediately even is there is `delay` */
94 #if LV_USE_USER_DATA
95     lv_anim_user_data_t user_data; /**< Custom user data*/
96 #endif
97 
98     /*Animation system use these - user shouldn't set*/
99     uint32_t time_orig;
100     uint8_t playback_now : 1; /**< Play back is in progress*/
101     uint32_t has_run : 1;     /**< Indicates the animation has run in this round*/
102 } lv_anim_t;
103 
104 
105 /**********************
106  * GLOBAL PROTOTYPES
107  **********************/
108 
109 /**
110  * Init. the animation module
111  */
112 void _lv_anim_core_init(void);
113 
114 /**
115  * Initialize an animation variable.
116  * E.g.:
117  * lv_anim_t a;
118  * lv_anim_init(&a);
119  * lv_anim_set_...(&a);
120  * @param a pointer to an `lv_anim_t` variable to initialize
121  */
122 void lv_anim_init(lv_anim_t * a);
123 
124 /**
125  * Set a variable to animate
126  * @param a pointer to an initialized `lv_anim_t` variable
127  * @param var pointer to a variable to animate
128  */
lv_anim_set_var(lv_anim_t * a,void * var)129 static inline void lv_anim_set_var(lv_anim_t * a, void * var)
130 {
131     a->var     = var;
132 }
133 
134 /**
135  * Set a function to animate `var`
136  * @param a pointer to an initialized `lv_anim_t` variable
137  * @param exec_cb a function to execute during animation
138  *                LittelvGL's built-in functions can be used.
139  *                E.g. lv_obj_set_x
140  */
lv_anim_set_exec_cb(lv_anim_t * a,lv_anim_exec_xcb_t exec_cb)141 static inline void lv_anim_set_exec_cb(lv_anim_t * a, lv_anim_exec_xcb_t exec_cb)
142 {
143     a->exec_cb = exec_cb;
144 }
145 
146 /**
147  * Set the duration of an animation
148  * @param a pointer to an initialized `lv_anim_t` variable
149  * @param duration duration of the animation in milliseconds
150  */
lv_anim_set_time(lv_anim_t * a,uint32_t duration)151 static inline void lv_anim_set_time(lv_anim_t * a, uint32_t duration)
152 {
153     a->time     = duration;
154 }
155 
156 /**
157  * Set a delay before starting the animation
158  * @param a pointer to an initialized `lv_anim_t` variable
159  * @param delay delay before the animation in milliseconds
160  */
lv_anim_set_delay(lv_anim_t * a,uint32_t delay)161 static inline void lv_anim_set_delay(lv_anim_t * a, uint32_t delay)
162 {
163     a->act_time = -(int32_t)(delay);
164 }
165 
166 /**
167  * Set the start and end values of an animation
168  * @param a pointer to an initialized `lv_anim_t` variable
169  * @param start the start value
170  * @param end the end value
171  */
lv_anim_set_values(lv_anim_t * a,lv_anim_value_t start,lv_anim_value_t end)172 static inline void lv_anim_set_values(lv_anim_t * a, lv_anim_value_t start, lv_anim_value_t end)
173 {
174     a->start = start;
175     a->current = start;
176     a->end   = end;
177 }
178 
179 /**
180  * Similar to `lv_anim_set_exec_cb` but `lv_anim_custom_exec_cb_t` receives
181  * `lv_anim_t * ` as its first parameter instead of `void *`.
182  * This function might be used when LVGL is binded to other languages because
183  * it's more consistent to have `lv_anim_t *` as first parameter.
184  * The variable to animate can be stored in the animation's `user_sata`
185  * @param a pointer to an initialized `lv_anim_t` variable
186  * @param exec_cb a function to execute.
187  */
lv_anim_set_custom_exec_cb(lv_anim_t * a,lv_anim_custom_exec_cb_t exec_cb)188 static inline void lv_anim_set_custom_exec_cb(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb)
189 {
190     a->var     = a;
191     a->exec_cb = (lv_anim_exec_xcb_t)exec_cb;
192 }
193 
194 /**
195  * Set the path (curve) of the animation.
196  * @param a pointer to an initialized `lv_anim_t` variable
197  * @param path_cb a function the get the current value of the animation.
198  *                The built in functions starts with `lv_anim_path_...`
199  */
lv_anim_set_path(lv_anim_t * a,const lv_anim_path_t * path)200 static inline void lv_anim_set_path(lv_anim_t * a, const lv_anim_path_t * path)
201 {
202     _lv_memcpy_small(&a->path, path, sizeof(lv_anim_path_t));
203 }
204 
205 
206 /**
207  * Set a function call when the animation really starts (considering `delay`)
208  * @param a pointer to an initialized `lv_anim_t` variable
209  * @param start_cb a function call when the animation starts
210  */
lv_anim_set_start_cb(lv_anim_t * a,lv_anim_ready_cb_t start_cb)211 static inline void lv_anim_set_start_cb(lv_anim_t * a, lv_anim_ready_cb_t start_cb)
212 {
213     a->start_cb = start_cb;
214 }
215 
216 /**
217  * Set a function call when the animation is ready
218  * @param a pointer to an initialized `lv_anim_t` variable
219  * @param ready_cb a function call when the animation is ready
220  */
lv_anim_set_ready_cb(lv_anim_t * a,lv_anim_ready_cb_t ready_cb)221 static inline void lv_anim_set_ready_cb(lv_anim_t * a, lv_anim_ready_cb_t ready_cb)
222 {
223     a->ready_cb = ready_cb;
224 }
225 
226 /**
227  * Make the animation to play back to when the forward direction is ready
228  * @param a pointer to an initialized `lv_anim_t` variable
229  * @param time the duration of the playback animation in in milliseconds. 0: disable playback
230  */
lv_anim_set_playback_time(lv_anim_t * a,uint16_t time)231 static inline void lv_anim_set_playback_time(lv_anim_t * a, uint16_t time)
232 {
233     a->playback_time = time;
234 }
235 
236 /**
237  * Make the animation to play back to when the forward direction is ready
238  * @param a pointer to an initialized `lv_anim_t` variable
239  * @param delay delay in milliseconds before starting the playback animation.
240  */
lv_anim_set_playback_delay(lv_anim_t * a,uint16_t delay)241 static inline void lv_anim_set_playback_delay(lv_anim_t * a, uint16_t delay)
242 {
243     a->playback_delay = delay;
244 }
245 
246 /**
247  * Make the animation repeat itself.
248  * @param a pointer to an initialized `lv_anim_t` variable
249  * @param cnt repeat count or `LV_ANIM_REPEAT_INFINITE` for infinite repetition. 0: to disable repetition.
250  */
lv_anim_set_repeat_count(lv_anim_t * a,uint16_t cnt)251 static inline void lv_anim_set_repeat_count(lv_anim_t * a, uint16_t cnt)
252 {
253     a->repeat_cnt       = cnt;
254 }
255 
256 /**
257  * Set a delay before repeating the animation.
258  * @param a pointer to an initialized `lv_anim_t` variable
259  * @param delay delay in milliseconds before repeating the animation.
260  */
lv_anim_set_repeat_delay(lv_anim_t * a,uint16_t delay)261 static inline void lv_anim_set_repeat_delay(lv_anim_t * a, uint16_t delay)
262 {
263     a->repeat_delay = delay;
264 }
265 
266 /**
267  * Create an animation
268  * @param a an initialized 'anim_t' variable. Not required after call.
269  */
270 void lv_anim_start(lv_anim_t * a);
271 
272 /**
273  * Initialize an animation path
274  * @param path pointer to path
275  */
lv_anim_path_init(lv_anim_path_t * path)276 static inline void lv_anim_path_init(lv_anim_path_t * path)
277 {
278     _lv_memset_00(path, sizeof(lv_anim_path_t));
279 }
280 
281 /**
282  * Set a callback for a path
283  * @param path pointer to an initialized path
284  * @param cb the callback
285  */
lv_anim_path_set_cb(lv_anim_path_t * path,lv_anim_path_cb_t cb)286 static inline void lv_anim_path_set_cb(lv_anim_path_t * path, lv_anim_path_cb_t cb)
287 {
288     path->cb = cb;
289 }
290 
291 /**
292  * Set a user data for a path
293  * @param path pointer to an initialized path
294  * @param user_data pointer to the user data
295  */
lv_anim_path_set_user_data(lv_anim_path_t * path,void * user_data)296 static inline void lv_anim_path_set_user_data(lv_anim_path_t * path, void * user_data)
297 {
298     path->user_data = user_data;
299 }
300 
301 /**
302  * Get a delay before starting the animation
303  * @param a pointer to an initialized `lv_anim_t` variable
304  * @return delay before the animation in milliseconds
305  */
lv_anim_get_delay(lv_anim_t * a)306 static inline int32_t lv_anim_get_delay(lv_anim_t * a)
307 {
308     return -a->act_time;
309 }
310 
311 /**
312  * Delete an animation of a variable with a given animator function
313  * @param var pointer to variable
314  * @param exec_cb a function pointer which is animating 'var',
315  *           or NULL to ignore it and delete all the animations of 'var
316  * @return true: at least 1 animation is deleted, false: no animation is deleted
317  */
318 bool lv_anim_del(void * var, lv_anim_exec_xcb_t exec_cb);
319 
320 
321 /**
322  * Get the animation of a variable and its `exec_cb`.
323  * @param var pointer to variable
324  * @param exec_cb a function pointer which is animating 'var',
325  *           or NULL to delete all the animations of 'var'
326  * @return pointer to the animation.
327  */
328 lv_anim_t * lv_anim_get(void * var, lv_anim_exec_xcb_t exec_cb);
329 
330 /**
331  * Delete an animation by getting the animated variable from `a`.
332  * Only animations with `exec_cb` will be deleted.
333  * This function exists because it's logical that all anim. functions receives an
334  * `lv_anim_t` as their first parameter. It's not practical in C but might make
335  * the API more consequent and makes easier to generate bindings.
336  * @param a pointer to an animation.
337  * @param exec_cb a function pointer which is animating 'var',
338  *           or NULL to ignore it and delete all the animations of 'var
339  * @return true: at least 1 animation is deleted, false: no animation is deleted
340  */
lv_anim_custom_del(lv_anim_t * a,lv_anim_custom_exec_cb_t exec_cb)341 static inline bool lv_anim_custom_del(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb)
342 {
343     return lv_anim_del(a->var, (lv_anim_exec_xcb_t)exec_cb);
344 }
345 
346 /**
347  * Get the number of currently running animations
348  * @return the number of running animations
349  */
350 uint16_t lv_anim_count_running(void);
351 
352 /**
353  * Calculate the time of an animation with a given speed and the start and end values
354  * @param speed speed of animation in unit/sec
355  * @param start start value of the animation
356  * @param end end value of the animation
357  * @return the required time [ms] for the animation with the given parameters
358  */
359 uint16_t lv_anim_speed_to_time(uint16_t speed, lv_anim_value_t start, lv_anim_value_t end);
360 
361 /**
362  * Manually refresh the state of the animations.
363  * Useful to make the animations running in a blocking process where
364  * `lv_task_handler` can't run for a while.
365  * Shouldn't be used directly because it is called in `lv_refr_now()`.
366  */
367 void lv_anim_refr_now(void);
368 
369 /**
370  * Calculate the current value of an animation applying linear characteristic
371  * @param a pointer to an animation
372  * @return the current value to set
373  */
374 lv_anim_value_t lv_anim_path_linear(const lv_anim_path_t * path, const lv_anim_t * a);
375 
376 /**
377  * Calculate the current value of an animation slowing down the start phase
378  * @param a pointer to an animation
379  * @return the current value to set
380  */
381 lv_anim_value_t lv_anim_path_ease_in(const lv_anim_path_t * path, const lv_anim_t * a);
382 
383 /**
384  * Calculate the current value of an animation slowing down the end phase
385  * @param a pointer to an animation
386  * @return the current value to set
387  */
388 lv_anim_value_t lv_anim_path_ease_out(const lv_anim_path_t * path, const lv_anim_t * a);
389 
390 /**
391  * Calculate the current value of an animation applying an "S" characteristic (cosine)
392  * @param a pointer to an animation
393  * @return the current value to set
394  */
395 lv_anim_value_t lv_anim_path_ease_in_out(const lv_anim_path_t * path, const lv_anim_t * a);
396 
397 /**
398  * Calculate the current value of an animation with overshoot at the end
399  * @param a pointer to an animation
400  * @return the current value to set
401  */
402 lv_anim_value_t lv_anim_path_overshoot(const lv_anim_path_t * path, const lv_anim_t * a);
403 
404 /**
405  * Calculate the current value of an animation with 3 bounces
406  * @param a pointer to an animation
407  * @return the current value to set
408  */
409 lv_anim_value_t lv_anim_path_bounce(const lv_anim_path_t * path, const lv_anim_t * a);
410 
411 /**
412  * Calculate the current value of an animation applying step characteristic.
413  * (Set end value on the end of the animation)
414  * @param a pointer to an animation
415  * @return the current value to set
416  */
417 lv_anim_value_t lv_anim_path_step(const lv_anim_path_t * path, const lv_anim_t * a);
418 
419 /**********************
420  *   GLOBAL VARIABLES
421  **********************/
422 extern const lv_anim_path_t lv_anim_path_def;
423 
424 /**********************
425  *      MACROS
426  **********************/
427 
428 #endif /*LV_USE_ANIMATION == 0*/
429 
430 #ifdef __cplusplus
431 } /* extern "C" */
432 #endif
433 
434 #endif /*LV_ANIM_H*/
435