mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
Merge 3cec3964ddd04dd6a3bd1d812ead1b86e6f1d474 into dev
This commit is contained in:
commit
c94ce67015
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file lv_anim.c
|
||||
* @file anim.c
|
||||
*
|
||||
*/
|
||||
|
||||
@ -33,14 +33,13 @@
|
||||
**********************/
|
||||
static void anim_task(lv_task_t * param);
|
||||
static void anim_mark_list_change(void);
|
||||
static void anim_ready_handler(lv_anim_t * a);
|
||||
static bool anim_ready_handler(lv_anim_t * a);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static uint32_t last_task_run;
|
||||
static bool anim_list_changed;
|
||||
static bool anim_run_round;
|
||||
static lv_task_t * _lv_anim_task;
|
||||
const lv_anim_path_t lv_anim_path_def = {.cb = lv_anim_path_linear};
|
||||
|
||||
@ -58,6 +57,7 @@ const lv_anim_path_t lv_anim_path_def = {.cb = lv_anim_path_linear};
|
||||
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();
|
||||
_lv_anim_task = lv_task_create(anim_task, LV_DISP_DEF_REFR_PERIOD, LV_ANIM_TASK_PRIO, NULL);
|
||||
anim_mark_list_change(); /*Turn off the animation task*/
|
||||
anim_list_changed = false; /*The list has not actually changed*/
|
||||
@ -93,7 +93,7 @@ void lv_anim_start(lv_anim_t * a)
|
||||
|
||||
/*If the list is empty the anim task was suspended and it's last run measure is invalid*/
|
||||
if(_lv_ll_is_empty(&LV_GC_ROOT(_lv_anim_ll))) {
|
||||
last_task_run = lv_tick_get();
|
||||
last_task_run = lv_tick_get() - 1;
|
||||
}
|
||||
|
||||
/*Add the new animation to the animation linked list*/
|
||||
@ -103,7 +103,6 @@ void lv_anim_start(lv_anim_t * a)
|
||||
|
||||
/*Initialize the animation descriptor*/
|
||||
a->time_orig = a->time;
|
||||
a->run_round = anim_run_round;
|
||||
_lv_memcpy(new_anim, a, sizeof(lv_anim_t));
|
||||
|
||||
/*Set the start value*/
|
||||
@ -188,10 +187,12 @@ uint16_t lv_anim_count_running(void)
|
||||
* @param end end value of the animation
|
||||
* @return the required time [ms] for the animation with the given parameters
|
||||
*/
|
||||
uint32_t lv_anim_speed_to_time(uint32_t speed, lv_anim_value_t start, lv_anim_value_t end)
|
||||
uint16_t lv_anim_speed_to_time(uint16_t speed, lv_anim_value_t start, lv_anim_value_t end)
|
||||
{
|
||||
uint32_t d = LV_MATH_ABS(start - end);
|
||||
uint32_t time = (d * 1000) / speed;
|
||||
int32_t d = LV_MATH_ABS((int32_t)start - end);
|
||||
uint32_t time = (int32_t)((int32_t)(d * 1000) / speed);
|
||||
|
||||
if(time > UINT16_MAX) time = UINT16_MAX;
|
||||
|
||||
if(time == 0) {
|
||||
time++;
|
||||
@ -221,16 +222,22 @@ lv_anim_value_t lv_anim_path_linear(const lv_anim_path_t * path, const lv_anim_t
|
||||
LV_UNUSED(path);
|
||||
|
||||
/*Calculate the current step*/
|
||||
int32_t step = _lv_map(a->act_time, 0, a->time, 0, LV_ANIM_RESOLUTION);
|
||||
uint32_t step;
|
||||
if(a->time == a->act_time) {
|
||||
step = LV_ANIM_RESOLUTION; /*Use the last value if the time fully elapsed*/
|
||||
}
|
||||
else {
|
||||
step = ((int32_t)a->act_time * LV_ANIM_RESOLUTION) / a->time;
|
||||
}
|
||||
|
||||
/* Get the new value which will be proportional to `step`
|
||||
* and the `start` and `end` values*/
|
||||
int32_t new_value;
|
||||
new_value = step * (a->end - a->start);
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
new_value = new_value >> LV_ANIM_RES_SHIFT;
|
||||
new_value += a->start;
|
||||
|
||||
return new_value;
|
||||
return (lv_anim_value_t)new_value;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -243,16 +250,20 @@ lv_anim_value_t lv_anim_path_ease_in(const lv_anim_path_t * path, const lv_anim_
|
||||
LV_UNUSED(path);
|
||||
|
||||
/*Calculate the current step*/
|
||||
uint32_t t;
|
||||
if(a->time == a->act_time)
|
||||
t = 1024;
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
uint32_t t = _lv_map(a->act_time, 0, a->time, 0, 1024);
|
||||
int32_t step = _lv_bezier3(t, 0, 1, 1, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = step * (a->end - a->start);
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
new_value = new_value >> 10;
|
||||
new_value += a->start;
|
||||
|
||||
return new_value;
|
||||
return (lv_anim_value_t)new_value;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -266,15 +277,20 @@ lv_anim_value_t lv_anim_path_ease_out(const lv_anim_path_t * path, const lv_anim
|
||||
|
||||
/*Calculate the current step*/
|
||||
|
||||
uint32_t t = _lv_map(a->act_time, 0, a->time, 0, 1024);
|
||||
uint32_t t;
|
||||
if(a->time == a->act_time)
|
||||
t = 1024;
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = _lv_bezier3(t, 0, 1023, 1023, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = step * (a->end - a->start);
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
new_value = new_value >> 10;
|
||||
new_value += a->start;
|
||||
|
||||
return new_value;
|
||||
return (lv_anim_value_t)new_value;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -288,15 +304,20 @@ lv_anim_value_t lv_anim_path_ease_in_out(const lv_anim_path_t * path, const lv_a
|
||||
|
||||
/*Calculate the current step*/
|
||||
|
||||
uint32_t t = _lv_map(a->act_time, 0, a->time, 0, 1024);
|
||||
uint32_t t;
|
||||
if(a->time == a->act_time)
|
||||
t = 1024;
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = _lv_bezier3(t, 0, 100, 924, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = step * (a->end - a->start);
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
new_value = new_value >> 10;
|
||||
new_value += a->start;
|
||||
|
||||
return new_value;
|
||||
return (lv_anim_value_t)new_value;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -310,15 +331,20 @@ lv_anim_value_t lv_anim_path_overshoot(const lv_anim_path_t * path, const lv_ani
|
||||
|
||||
/*Calculate the current step*/
|
||||
|
||||
uint32_t t = _lv_map(a->act_time, 0, a->time, 0, 1024);
|
||||
uint32_t t;
|
||||
if(a->time == a->act_time)
|
||||
t = 1024;
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
int32_t step = _lv_bezier3(t, 0, 1000, 1300, 1024);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = step * (a->end - a->start);
|
||||
new_value = (int32_t)step * (a->end - a->start);
|
||||
new_value = new_value >> 10;
|
||||
new_value += a->start;
|
||||
|
||||
return new_value;
|
||||
return (lv_anim_value_t)new_value;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -331,8 +357,12 @@ lv_anim_value_t lv_anim_path_bounce(const lv_anim_path_t * path, const lv_anim_t
|
||||
LV_UNUSED(path);
|
||||
|
||||
/*Calculate the current step*/
|
||||
int32_t t;
|
||||
if(a->time == a->act_time)
|
||||
t = 1024;
|
||||
else
|
||||
t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;
|
||||
|
||||
uint32_t t = _lv_map(a->act_time, 0, a->time, 0, 1024);
|
||||
int32_t diff = (a->end - a->start);
|
||||
|
||||
/*3 bounces has 5 parts: 3 down and 2 up. One part is t / 5 long*/
|
||||
@ -361,21 +391,24 @@ lv_anim_value_t lv_anim_path_bounce(const lv_anim_path_t * path, const lv_anim_t
|
||||
t = 1024 - t;
|
||||
diff = diff / 40;
|
||||
}
|
||||
else {
|
||||
else if(t >= 921 && t <= 1024) {
|
||||
/*Fall back*/
|
||||
t -= 921;
|
||||
t = t * 10; /*to [0..1024] range*/
|
||||
diff = diff / 40;
|
||||
}
|
||||
|
||||
if(t > 1024) t = 1024;
|
||||
if(t < 0) t = 0;
|
||||
|
||||
int32_t step = _lv_bezier3(t, 1024, 800, 500, 0);
|
||||
|
||||
int32_t new_value;
|
||||
new_value = step * diff;
|
||||
new_value = (int32_t)step * diff;
|
||||
new_value = new_value >> 10;
|
||||
new_value = a->end - new_value;
|
||||
|
||||
return new_value;
|
||||
return (lv_anim_value_t)new_value;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -406,12 +439,14 @@ static void anim_task(lv_task_t * param)
|
||||
{
|
||||
(void)param;
|
||||
|
||||
lv_anim_t * a;
|
||||
_LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a) {
|
||||
a->has_run = 0;
|
||||
}
|
||||
|
||||
uint32_t elaps = lv_tick_elaps(last_task_run);
|
||||
|
||||
/*Flip the run round*/
|
||||
anim_run_round = anim_run_round ? false : true;
|
||||
|
||||
lv_anim_t * a = _lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
a = _lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
|
||||
while(a != NULL) {
|
||||
/*It can be set by `lv_anim_del()` typically in `end_cb`. If set then an animation delete
|
||||
@ -420,8 +455,8 @@ static void anim_task(lv_task_t * param)
|
||||
*/
|
||||
anim_list_changed = false;
|
||||
|
||||
if(a->run_round != anim_run_round) {
|
||||
a->run_round = anim_run_round; /*The list readying might be reset so need to know which anim has run already*/
|
||||
if(!a->has_run) {
|
||||
a->has_run = 1; /*The list readying might be reset so need to know which anim has run already*/
|
||||
|
||||
/*The animation will run now for the first time. Call `start_cb`*/
|
||||
int32_t new_act_time = a->act_time + elaps;
|
||||
@ -464,8 +499,9 @@ static void anim_task(lv_task_t * param)
|
||||
* Called when an animation is ready to do the necessary thinks
|
||||
* e.g. repeat, play back, delete etc.
|
||||
* @param a pointer to an animation descriptor
|
||||
*/
|
||||
static void anim_ready_handler(lv_anim_t * a)
|
||||
* @return true: animation delete occurred and the `LV_GC_ROOT(_lv_anim_ll)` has changed
|
||||
* */
|
||||
static bool anim_ready_handler(lv_anim_t * a)
|
||||
{
|
||||
/*In the end of a forward anim decrement repeat cnt.*/
|
||||
if(a->playback_now == 0 && a->repeat_cnt > 0 && a->repeat_cnt != LV_ANIM_REPEAT_INFINITE) {
|
||||
@ -508,6 +544,8 @@ static void anim_ready_handler(lv_anim_t * a)
|
||||
a->time = a->playback_now == 0 ? a->time_orig : a->playback_time;
|
||||
}
|
||||
}
|
||||
|
||||
return anim_list_changed;
|
||||
}
|
||||
static void anim_mark_list_change(void)
|
||||
{
|
||||
|
@ -1,10 +1,10 @@
|
||||
/**
|
||||
* @file lv_anim.h
|
||||
* @file anim.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_ANIM_H
|
||||
#define LV_ANIM_H
|
||||
#ifndef ANIM_H
|
||||
#define ANIM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -37,7 +37,7 @@ enum {
|
||||
typedef uint8_t lv_anim_enable_t;
|
||||
|
||||
/** Type of the animated value*/
|
||||
typedef int32_t lv_anim_value_t;
|
||||
typedef lv_coord_t lv_anim_value_t;
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
@ -74,28 +74,28 @@ typedef void (*lv_anim_start_cb_t)(struct _lv_anim_t *);
|
||||
/** Describes an animation*/
|
||||
typedef struct _lv_anim_t {
|
||||
void * var; /**<Variable to animate*/
|
||||
lv_anim_exec_xcb_t exec_cb; /**< Function to execute to animate*/
|
||||
lv_anim_exec_xcb_t exec_cb; /**< Function to execute to animate*/
|
||||
lv_anim_start_cb_t start_cb; /**< Call it when the animation is starts (considering `delay`)*/
|
||||
lv_anim_ready_cb_t ready_cb; /**< Call it when the animation is ready*/
|
||||
#if LV_USE_USER_DATA
|
||||
lv_anim_user_data_t user_data; /**< Custom user data*/
|
||||
#endif
|
||||
lv_anim_path_t path; /**< Describe the path (curve) of animations*/
|
||||
int32_t start; /**< Start value*/
|
||||
int32_t current; /**< Current value */
|
||||
int32_t end; /**< End value*/
|
||||
int32_t time; /**< Animation time in ms*/
|
||||
int32_t time; /**< Animation time in ms*/
|
||||
int32_t act_time; /**< Current time in animation. Set to negative to make delay.*/
|
||||
uint32_t playback_delay; /**< Wait before play back*/
|
||||
uint32_t playback_time; /**< Duration of playback animation*/
|
||||
uint32_t repeat_delay; /**< Wait before repeat*/
|
||||
uint16_t repeat_cnt; /**< Repeat count for the animation*/
|
||||
uint8_t early_apply : 1; /**< 1: Apply start value immediately even is there is `delay` */
|
||||
#if LV_USE_USER_DATA
|
||||
lv_anim_user_data_t user_data; /**< Custom user data*/
|
||||
#endif
|
||||
|
||||
/*Animation system use these - user shouldn't set*/
|
||||
uint8_t playback_now : 1; /**< Play back is in progress*/
|
||||
uint8_t run_round : 1; /**< Indicates the animation has run in this round*/
|
||||
uint32_t time_orig;
|
||||
uint8_t playback_now : 1; /**< Play back is in progress*/
|
||||
uint32_t has_run : 1; /**< Indicates the animation has run in this round*/
|
||||
} lv_anim_t;
|
||||
|
||||
/**********************
|
||||
@ -124,7 +124,7 @@ void lv_anim_init(lv_anim_t * a);
|
||||
*/
|
||||
static inline void lv_anim_set_var(lv_anim_t * a, void * var)
|
||||
{
|
||||
a->var = var;
|
||||
a->var = var;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -146,7 +146,7 @@ static inline void lv_anim_set_exec_cb(lv_anim_t * a, lv_anim_exec_xcb_t exec_cb
|
||||
*/
|
||||
static inline void lv_anim_set_time(lv_anim_t * a, uint32_t duration)
|
||||
{
|
||||
a->time = duration;
|
||||
a->time = duration;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -169,7 +169,7 @@ static inline void lv_anim_set_values(lv_anim_t * a, lv_anim_value_t start, lv_a
|
||||
{
|
||||
a->start = start;
|
||||
a->current = start;
|
||||
a->end = end;
|
||||
a->end = end;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,8 +190,8 @@ static inline void lv_anim_set_custom_exec_cb(lv_anim_t * a, lv_anim_custom_exec
|
||||
/**
|
||||
* Set the path (curve) of the animation.
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param path a function the get the current value of the animation.
|
||||
* The built in functions starts with `lv_anim_path_...`
|
||||
* @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(lv_anim_t * a, const lv_anim_path_t * path)
|
||||
{
|
||||
@ -223,7 +223,7 @@ static inline void lv_anim_set_ready_cb(lv_anim_t * a, lv_anim_ready_cb_t ready_
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param time the duration of the playback animation in in milliseconds. 0: disable playback
|
||||
*/
|
||||
static inline void lv_anim_set_playback_time(lv_anim_t * a, uint32_t time)
|
||||
static inline void lv_anim_set_playback_time(lv_anim_t * a, uint16_t time)
|
||||
{
|
||||
a->playback_time = time;
|
||||
}
|
||||
@ -233,7 +233,7 @@ static inline void lv_anim_set_playback_time(lv_anim_t * a, uint32_t time)
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param delay delay in milliseconds before starting the playback animation.
|
||||
*/
|
||||
static inline void lv_anim_set_playback_delay(lv_anim_t * a, uint32_t delay)
|
||||
static inline void lv_anim_set_playback_delay(lv_anim_t * a, uint16_t delay)
|
||||
{
|
||||
a->playback_delay = delay;
|
||||
}
|
||||
@ -245,7 +245,7 @@ static inline void lv_anim_set_playback_delay(lv_anim_t * a, uint32_t delay)
|
||||
*/
|
||||
static inline void lv_anim_set_repeat_count(lv_anim_t * a, uint16_t cnt)
|
||||
{
|
||||
a->repeat_cnt = cnt;
|
||||
a->repeat_cnt = cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -253,7 +253,7 @@ static inline void lv_anim_set_repeat_count(lv_anim_t * a, uint16_t cnt)
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param delay delay in milliseconds before repeating the animation.
|
||||
*/
|
||||
static inline void lv_anim_set_repeat_delay(lv_anim_t * a, uint32_t delay)
|
||||
static inline void lv_anim_set_repeat_delay(lv_anim_t * a, uint16_t delay)
|
||||
{
|
||||
a->repeat_delay = delay;
|
||||
}
|
||||
@ -298,7 +298,7 @@ static inline void lv_anim_path_set_user_data(lv_anim_path_t * path, void * user
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @return delay before the animation in milliseconds
|
||||
*/
|
||||
static inline uint32_t lv_anim_get_delay(lv_anim_t * a)
|
||||
static inline int32_t lv_anim_get_delay(lv_anim_t * a)
|
||||
{
|
||||
return -a->act_time;
|
||||
}
|
||||
@ -350,7 +350,7 @@ uint16_t lv_anim_count_running(void);
|
||||
* @param end end value of the animation
|
||||
* @return the required time [ms] for the animation with the given parameters
|
||||
*/
|
||||
uint32_t lv_anim_speed_to_time(uint32_t speed, lv_anim_value_t start, lv_anim_value_t end);
|
||||
uint16_t lv_anim_speed_to_time(uint16_t speed, lv_anim_value_t start, lv_anim_value_t end);
|
||||
|
||||
/**
|
||||
* Manually refresh the state of the animations.
|
||||
|
Loading…
x
Reference in New Issue
Block a user