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