diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index f786ee0a8..64b39748f 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -90,7 +90,7 @@ void lv_init(void) lv_font_init(); #if LV_USE_ANIMATION - lv_anim_init(); + lv_anim_core_init(); #endif #if LV_USE_GROUP diff --git a/src/lv_core/lv_style.c b/src/lv_core/lv_style.c index ea6b3bb59..2d6b67fda 100644 --- a/src/lv_core/lv_style.c +++ b/src/lv_core/lv_style.c @@ -26,16 +26,6 @@ /********************** * TYPEDEFS **********************/ -#if LV_USE_ANIMATION -typedef struct -{ - lv_style_t style_start; /*Save not only pointers because can be same as 'style_anim' then it - will be modified too*/ - lv_style_t style_end; - lv_style_t * style_anim; - lv_anim_ready_cb_t ready_cb; -} lv_style_anim_dsc_t; -#endif /********************** * STATIC PROTOTYPES @@ -286,44 +276,38 @@ void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * #if LV_USE_ANIMATION -/** - * Create an animation from a pre-configured 'lv_style_anim_t' variable - * @param anim pointer to a pre-configured 'lv_style_anim_t' variable (will be copied) - * @return pointer to a descriptor. Really this variable will be animated. (Can be used in - * `lv_anim_del(dsc, NULL)`) - */ -void * lv_style_anim_create(lv_style_anim_t * anim) + +void lv_style_anim_init(lv_anim_t * a) { - lv_style_anim_dsc_t * dsc; - dsc = lv_mem_alloc(sizeof(lv_style_anim_dsc_t)); - lv_mem_assert(dsc); - if(dsc == NULL) return NULL; + lv_anim_init(a); + a->start = 0; + a->end = STYLE_MIX_MAX; + a->exec_cb = (lv_anim_exec_cb_t)style_animator; + a->path_cb = lv_anim_path_linear; + a->ready_cb = style_animation_common_end_cb; - dsc->style_anim = anim->style_anim; - memcpy(&dsc->style_start, anim->style_start, sizeof(lv_style_t)); - memcpy(&dsc->style_end, anim->style_end, sizeof(lv_style_t)); - memcpy(dsc->style_anim, anim->style_start, sizeof(lv_style_t)); - dsc->ready_cb = anim->ready_cb; + lv_style_anim_dsc_t * dsc; + dsc = lv_mem_alloc(sizeof(lv_style_anim_dsc_t)); + lv_mem_assert(dsc); + if(dsc == NULL) return; + dsc->ready_cb = NULL; + dsc->style_anim = NULL; + lv_style_copy(&dsc->style_start, &lv_style_plain); + lv_style_copy(&dsc->style_end, &lv_style_plain); - lv_anim_t a; - a.var = (void *)dsc; - a.start = 0; - a.end = STYLE_MIX_MAX; - a.exec_cb = (lv_anim_exec_cb_t)style_animator; - a.path_cb = lv_anim_path_linear; - a.ready_cb = style_animation_common_end_cb; - a.act_time = anim->act_time; - a.time = anim->time; - a.playback = anim->playback; - a.playback_pause = anim->playback_pause; - a.repeat = anim->repeat; - a.repeat_pause = anim->repeat_pause; + a->var = (void *)dsc; - lv_anim_create(&a); - - return dsc; } +void lv_style_anim_set_styles(lv_anim_t * a, lv_style_t * to_anim, const lv_style_t * start, const lv_style_t * end) +{ + + lv_style_anim_dsc_t * dsc = a->var; + dsc->style_anim = to_anim; + memcpy(&dsc->style_start, start, sizeof(lv_style_t)); + memcpy(&dsc->style_end, end, sizeof(lv_style_t)); + memcpy(dsc->style_anim, start, sizeof(lv_style_t)); +} #endif /********************** * STATIC FUNCTIONS diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 4f4ac19b4..a4d5b6f8e 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -112,41 +112,12 @@ typedef struct #if LV_USE_ANIMATION typedef struct { - const lv_style_t * style_start; /*Pointer to the starting style*/ - const lv_style_t * style_end; /*Pointer to the destination style*/ - lv_style_t * style_anim; /*Pointer to a style to animate*/ - lv_anim_ready_cb_t ready_cb; /*Call it when the animation is ready (NULL if unused)*/ - int16_t time; /*Animation time in ms*/ - int16_t act_time; /*Current time in animation. Set to negative to make delay.*/ - uint16_t playback_pause; /*Wait before play back*/ - uint16_t repeat_pause; /*Wait before repeat*/ -#if LV_USE_USER_DATA_SINGLE - lv_anim_user_data_t user_data; /*Custom user data*/ -#endif - -#if LV_USE_USER_DATA_MULTI - lv_anim_user_data_t ready_user_data; -#endif - - uint8_t playback : 1; /*When the animation is ready play it back*/ - uint8_t repeat : 1; /*Repeat the animation infinitely*/ -} lv_style_anim_t; - -/* Example initialization -lv_style_anim_t a; -a.style_anim = &style_to_anim; -a.style_start = &style_1; -a.style_end = &style_2; -a.act_time = 0; -a.time = 1000; -a.playback = 0; -a.playback_pause = 0; -a.repeat = 0; -a.repeat_pause = 0; -a.ready_cb = NULL; -a.user_data = NULL; -lv_style_anim_create(&a); - */ + lv_style_t style_start; /*Save not only pointers because can be same as 'style_anim' then it + will be modified too*/ + lv_style_t style_end; + lv_style_t * style_anim; + lv_anim_ready_cb_t ready_cb; +} lv_style_anim_dsc_t; #endif /********************** @@ -178,12 +149,124 @@ void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * #if LV_USE_ANIMATION /** - * Create an animation from a pre-configured 'lv_style_anim_t' variable - * @param anim pointer to a pre-configured 'lv_style_anim_t' variable (will be copied) - * @return pointer to a descriptor. Really this variable will be animated. (Can be used in - * `lv_anim_del(dsc, NULL)`) + * Initialize an animation variable. + * E.g.: + * lv_anim_t a; + * lv_style_anim__init(&a); + * lv_style_anim_set_...(&a); + * lv_style_anim_create(&a); + * @param a pointer to an `lv_anim_t` variable to initialize */ -void * lv_style_anim_create(lv_style_anim_t * anim); +void lv_style_anim_init(lv_anim_t * a); + +/** + * + * @param a pointer to an initialized `lv_anim_t` variable + * @param to_anim pointer to the style to animate + * @param start pointer to a style to animate from (start value) + * @param end pointer to a style to animate to (end value) + */ +void lv_style_anim_set_styles(lv_anim_t * a, lv_style_t * to_anim, const lv_style_t * start, const lv_style_t * end); + +/** + * Set the duration and delay of an animation + * @param a pointer to an initialized `lv_anim_t` variable + * @param duration duration of the animation in milliseconds + * @param delay delay before the animation in milliseconds + */ +static inline void lv_style_anim_set_time(lv_anim_t * a, uint16_t duration, uint16_t delay) +{ + lv_anim_set_time(a, duration, delay); +} + +/** + * Set a function call when the animation is ready + * @param a pointer to an initialized `lv_anim_t` variable + * @param ready_cb a function call when the animation is ready + */ +static inline void lv_style_anim_set_ready_cb(lv_anim_t * a, lv_anim_ready_cb_t ready_cb) +{ + lv_style_anim_dsc_t * dsc = a->var; + dsc->ready_cb = ready_cb; +} + +/** + * Make the animation to play back to when the forward direction is ready + * @param a pointer to an initialized `lv_anim_t` variable + * @param wait_time time in milliseconds to wait before starting the back direction + */ +static inline void lv_style_anim_set_playback(lv_anim_t * a, uint16_t wait_time) +{ + lv_anim_set_playback(a, wait_time); +} + +/** + * Disable playback. (Disabled after `lv_anim_init()`) + * @param a pointer to an initialized `lv_anim_t` variable + */ +static inline void lv_style_anim_clear_playback(lv_anim_t * a) +{ + lv_anim_clear_playback(a); +} + +/** + * Make the animation to start again when ready. + * @param a pointer to an initialized `lv_anim_t` variable + * @param wait_time time in milliseconds to wait before starting the animation again + */ +static inline void lv_style_anim_set_repeat(lv_anim_t * a, uint16_t wait_time) +{ + lv_anim_set_repeat(a, wait_time); +} + +/** + * Disable repeat. (Disabled after `lv_anim_init()`) + * @param a pointer to an initialized `lv_anim_t` variable + */ +static inline void lv_style_anim_clear_repeat(lv_anim_t * a) +{ + lv_anim_clear_repeat(a); +} + +/** + * Set a user specific data for the animation + * @param a pointer to an initialized `lv_anim_t` variable + * @param user_data the user data + */ +static inline void lv_style_anim_set_user_data(lv_anim_t * a, lv_anim_user_data_t user_data) +{ + lv_anim_set_user_data(a, user_data); +} + +/** + * Get the user data + * @param a pointer to an initialized `lv_anim_t` variable + * @return the user data + */ +static inline lv_anim_user_data_t lv_style_anim_get_user_data(lv_anim_t * a) +{ + return lv_anim_get_user_data(a); +} + +/** + * Get pointer to the user data + * @param a pointer to an initialized `lv_anim_t` variable + * @return pointer to the user data + */ +static inline lv_anim_user_data_t * lv_style_anim_get_user_data_ptr(lv_anim_t * a) +{ + return lv_style_anim_get_user_data_ptr(a); +} + +/** + * Create an animation + * @param a an initialized 'anim_t' variable. Not required after call. + */ +static inline void lv_style_anim_create(lv_anim_t * a) +{ + return lv_anim_create(a); +} + #endif /************************* diff --git a/src/lv_misc/lv_anim.c b/src/lv_misc/lv_anim.c index ef2d6696c..77251a40c 100644 --- a/src/lv_misc/lv_anim.c +++ b/src/lv_misc/lv_anim.c @@ -53,7 +53,7 @@ static bool anim_list_changed; /** * Init. the animation module */ -void lv_anim_init(void) +void lv_anim_core_init(void) { lv_ll_init(&LV_GC_ROOT(_lv_anim_ll), sizeof(lv_anim_t)); last_task_run = lv_tick_get(); @@ -61,15 +61,30 @@ void lv_anim_init(void) } /** - * Create an animation - * @param anim_p an initialized 'anim_t' variable. Not required after call. + * Initialize an animation variable. + * E.g.: + * lv_anim_t a; + * lv_anim_init(&a); + * lv_anim_set_...(&a); + * lv_anim_craete(&a); + * @param a pointer to an `lv_anim_t` variable to initialize */ -void lv_anim_create(lv_anim_t * anim_p) +void lv_anim_init(lv_anim_t * a) +{ + memset(a, 0, sizeof(lv_anim_t)); + a->time = 500; + a->end = 100; +} +/** + * Create an animation + * @param a an initialized 'anim_t' variable. Not required after call. + */ +void lv_anim_create(lv_anim_t * a) { LV_LOG_TRACE("animation create started") /* Do not let two animations for the same 'var' with the same 'fp'*/ - if(anim_p->exec_cb != NULL) - lv_anim_del(anim_p->var, anim_p->exec_cb); /*fp == NULL would delete all animations of var*/ + if(a->exec_cb != NULL) + lv_anim_del(a->var, a->exec_cb); /*fp == NULL would delete all animations of var*/ /*Add the new animation to the animation linked list*/ lv_anim_t * new_anim = lv_ll_ins_head(&LV_GC_ROOT(_lv_anim_ll)); @@ -77,8 +92,8 @@ void lv_anim_create(lv_anim_t * anim_p) if(new_anim == NULL) return; /*Initialize the animation descriptor*/ - anim_p->playback_now = 0; - memcpy(new_anim, anim_p, sizeof(lv_anim_t)); + a->playback_now = 0; + memcpy(new_anim, a, sizeof(lv_anim_t)); /*Set the start value*/ if(new_anim->exec_cb != NULL) new_anim->exec_cb(new_anim->var, new_anim->start); diff --git a/src/lv_misc/lv_anim.h b/src/lv_misc/lv_anim.h index 95444d60b..77e50b8b4 100644 --- a/src/lv_misc/lv_anim.h +++ b/src/lv_misc/lv_anim.h @@ -23,6 +23,7 @@ extern "C" { #include #include +#include /********************* * DEFINES @@ -32,19 +33,28 @@ extern "C" { * TYPEDEFS **********************/ -typedef int16_t lv_anim_value_t; /*Type of the animated value*/ - struct _lv_anim_t; -/*Generic prototype of "animator" functions*/ +/*Type of the animated value*/ +typedef int16_t lv_anim_value_t; + +/* Generic prototype of "animator" functions. + * First parameter is the variable to animate. + * Second parameter is the value to set. + * Compatible with `lv_xxx_set_yyy(obj, value)` functions*/ typedef void (*lv_anim_exec_cb_t)(void *, lv_anim_value_t); -/*Get the current value in an animation*/ +/* Same as `lv_anim_exec_cb_t` but receives `lv_anim_t *` as the first parameter. + * It's more consistent but less convenient. Might be used by binding generator functions.*/ +typedef void (*lv_anim_custom_exec_cb_t)(struct _lv_anim_t *, lv_anim_value_t); + +/*Get the current value during an animation*/ typedef lv_anim_value_t (*lv_anim_path_cb_t)(const struct _lv_anim_t *); -/*Callback for animation ready*/ +/*Callback to call when the animation is ready*/ typedef void (*lv_anim_ready_cb_t)(struct _lv_anim_t *); +/*Describe an animation*/ typedef struct _lv_anim_t { void * var; /*Variable to animate*/ @@ -71,26 +81,9 @@ typedef struct _lv_anim_t uint8_t repeat : 1; /*Repeat the animation infinitely*/ /*Animation system use these - user shouldn't set*/ uint8_t playback_now : 1; /*Play back is in progress*/ - uint32_t has_run : 1; /*Indicates the animation has run it this round*/ + uint32_t has_run : 1; /*Indicates the animation has run in this round*/ } lv_anim_t; -/*Example initialization -lv_anim_t a; -a.var = obj; -a.start = lv_obj_get_height(obj); -a.end = new_height; -a.exec_cb = (lv_anim_exec_cb_t)lv_obj_set_height; -a.path_cb = lv_anim_path_linear; -a.ready_cb = NULL; -a.act_time = 0; -a.time = 200; -a.playback = 0; -a.playback_pause = 0; -a.repeat = 0; -a.repeat_pause = 0; -a.user_data = NULL; -lv_anim_create(&a); - */ /********************** * GLOBAL PROTOTYPES **********************/ @@ -98,13 +91,174 @@ lv_anim_create(&a); /** * Init. the animation module */ -void lv_anim_init(void); +void lv_anim_core_init(void); + +/** + * Initialize an animation variable. + * E.g.: + * lv_anim_t a; + * lv_anim_init(&a); + * lv_anim_set_...(&a); + * lv_anim_create(&a); + * @param a pointer to an `lv_anim_t` variable to initialize + */ +void lv_anim_init(lv_anim_t * a); + +/** + * Set a variable to animate + * @param a pointer to an initialized `lv_anim_t` variable + * @param var pointer to a variable to animate + */ +static inline void lv_anim_set_var(lv_anim_t * a, void * var) +{ + a->var = var; +} + +/** + * Set the duration and delay of an animation + * @param a pointer to an initialized `lv_anim_t` variable + * @param duration duration of the animation in milliseconds + * @param delay delay before the animation in milliseconds + */ +static inline void lv_anim_set_time(lv_anim_t * a, uint16_t duration, uint16_t delay) +{ + a->time = duration; + a->act_time = -delay; +} + +/** + * Set the start and end values of an animation + * @param a pointer to an initialized `lv_anim_t` variable + * @param start the start value + * @param end the end value + */ +static inline void lv_anim_set_values(lv_anim_t * a, lv_anim_value_t start, lv_anim_value_t end) +{ + a->start = start; + a->end = end; +} + +/** + * Set a function to execute by the aniamtion + * @param a pointer to an initialized `lv_anim_t` variable + * @param exec_cb a function to execute. + * LittelvGL's built-in functions can be used. + * E.g. lv_obj_set_x + */ +static inline void lv_anim_set_exec_cb(lv_anim_t * a, lv_anim_exec_cb_t exec_cb) +{ + a->exec_cb = exec_cb; +} + +/** + * The same as `lv_anim_set_exec_cb` but `lv_anim_custom_exec_cb_t` receives + * `lv_anim_t * ` as its first parameter instead of `void *`. + * This function might be used when LittlevGL is binded to other languages because + * it's more consistent to have `lv_anim_t *` as first parameter. + * @param a pointer to an initialized `lv_anim_t` variable + * @param exec_cb a function to execute. + */ +static inline void lv_anim_set_custom_exec_cb(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) +{ + a->exec_cb = (lv_anim_exec_cb_t)exec_cb; +} + +/** + * Set the path (curve) of the animation. + * @param a pointer to an initialized `lv_anim_t` variable + * @param path_cb a function the get the current value of the animation. + * The built in functions starts with `lv_anim_path_...` + */ +static inline void lv_anim_set_path_cb(lv_anim_t * a, lv_anim_path_cb_t path_cb) +{ + a->path_cb = path_cb; +} + +/** + * Set a function call when the animation is ready + * @param a pointer to an initialized `lv_anim_t` variable + * @param ready_cb a function call when the animation is ready + */ +static inline void lv_anim_set_ready_cb(lv_anim_t * a, lv_anim_ready_cb_t ready_cb) +{ + a->ready_cb = ready_cb; +} + +/** + * Make the animation to play back to when the forward direction is ready + * @param a pointer to an initialized `lv_anim_t` variable + * @param wait_time time in milliseconds to wait before starting the back direction + */ +static inline void lv_anim_set_playback(lv_anim_t * a, uint16_t wait_time) +{ + a->playback = 1; + a->playback_pause = wait_time; +} + +/** + * Disable playback. (Disabled after `lv_anim_init()`) + * @param a pointer to an initialized `lv_anim_t` variable + */ +static inline void lv_anim_clear_playback(lv_anim_t * a) +{ + a->playback = 0; +} + +/** + * Make the animation to start again when ready. + * @param a pointer to an initialized `lv_anim_t` variable + * @param wait_time time in milliseconds to wait before starting the animation again + */ +static inline void lv_anim_set_repeat(lv_anim_t * a, uint16_t wait_time) +{ + a->repeat = 1; + a->repeat_pause = wait_time; +} + +/** + * Disable repeat. (Disabled after `lv_anim_init()`) + * @param a pointer to an initialized `lv_anim_t` variable + */ +static inline void lv_anim_clear_repeat(lv_anim_t * a) +{ + a->repeat = 0; +} + +/** + * Set a user specific data for the animation + * @param a pointer to an initialized `lv_anim_t` variable + * @param user_data the user data + */ +static inline void lv_anim_set_user_data(lv_anim_t * a, lv_anim_user_data_t user_data) +{ + memcpy(&a->user_data, &user_data, sizeof(user_data)); +} + +/** + * Get the user data + * @param a pointer to an initialized `lv_anim_t` variable + * @return the user data + */ +static inline lv_anim_user_data_t lv_anim_get_user_data(lv_anim_t * a) +{ + return a->user_data; +} + +/** + * Get pointer to the user data + * @param a pointer to an initialized `lv_anim_t` variable + * @return pointer to the user data + */ +static inline lv_anim_user_data_t * lv_anim_get_user_data_ptr(lv_anim_t * a) +{ + return &a->user_data; +} /** * Create an animation - * @param anim_p an initialized 'anim_t' variable. Not required after call. + * @param a an initialized 'anim_t' variable. Not required after call. */ -void lv_anim_create(lv_anim_t * anim_p); +void lv_anim_create(lv_anim_t * a); /** * Delete an animation for a variable with a given animatior function