feat(anim): add lv_anim_set_get_value_cb

This commit is contained in:
Gabor Kiss-Vamosi
2021-03-01 13:52:39 +01:00
parent b35c67c8b6
commit 90d0eec5ae
4 changed files with 84 additions and 48 deletions

View File

@@ -228,10 +228,10 @@ void lv_obj_get_scroll_end(struct _lv_obj_t * obj, lv_point_t * end)
{
lv_anim_t * a;
a = lv_anim_get(obj, scroll_x_anim);
end->x = a ? -a->end : lv_obj_get_scroll_x(obj);
end->x = a ? -a->end_value : lv_obj_get_scroll_x(obj);
a = lv_anim_get(obj, scroll_y_anim);
end->y = a ? -a->end : lv_obj_get_scroll_y(obj);
end->y = a ? -a->end_value : lv_obj_get_scroll_y(obj);
}
/*=====================

View File

@@ -79,8 +79,8 @@ void lv_anim_init(lv_anim_t * a)
{
lv_memset_00(a, sizeof(lv_anim_t));
a->time = 500;
a->start = 0;
a->end = 100;
a->start_value = 0;
a->end_value = 100;
lv_memcpy_small(&a->path, &lv_anim_path_def, sizeof(lv_anim_path_cb_t));
a->repeat_cnt = 1;
a->early_apply = 1;
@@ -112,7 +112,13 @@ void lv_anim_start(lv_anim_t * a)
/*Set the start value*/
if(new_anim->early_apply) {
if(new_anim->exec_cb && new_anim->var) new_anim->exec_cb(new_anim->var, new_anim->start);
if(new_anim->get_value_cb) {
int32_t v_ofs = new_anim->get_value_cb(a->var);
new_anim->start_value += v_ofs;
new_anim->end_value += v_ofs;
}
if(new_anim->exec_cb && new_anim->var) new_anim->exec_cb(new_anim->var, new_anim->start_value);
}
/* Creating an animation changed the linked list.
@@ -251,9 +257,9 @@ int32_t lv_anim_path_linear(const lv_anim_path_t * path, const lv_anim_t * a)
/* 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 = step * (a->end_value - a->start_value);
new_value = new_value >> LV_ANIM_RES_SHIFT;
new_value += a->start;
new_value += a->start_value;
return new_value;
}
@@ -270,12 +276,12 @@ int32_t lv_anim_path_ease_in(const lv_anim_path_t * path, const lv_anim_t * a)
/*Calculate the current step*/
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 step = lv_bezier3(t, 0, 50, 100, 1024);
int32_t new_value;
new_value = step * (a->end - a->start);
new_value = step * (a->end_value - a->start_value);
new_value = new_value >> 10;
new_value += a->start;
new_value += a->start_value;
return new_value;
}
@@ -291,12 +297,12 @@ int32_t lv_anim_path_ease_out(const lv_anim_path_t * path, const lv_anim_t * a)
/*Calculate the current step*/
uint32_t t = lv_map(a->act_time, 0, a->time, 0, 1024);
int32_t step = lv_bezier3(t, 0, 1023, 1023, 1024);
int32_t step = lv_bezier3(t, 0, 900, 950, 1024);
int32_t new_value;
new_value = step * (a->end - a->start);
new_value = step * (a->end_value - a->start_value);
new_value = new_value >> 10;
new_value += a->start;
new_value += a->start_value;
return new_value;
}
@@ -312,12 +318,12 @@ int32_t lv_anim_path_ease_in_out(const lv_anim_path_t * path, const lv_anim_t *
/*Calculate the current step*/
uint32_t t = lv_map(a->act_time, 0, a->time, 0, 1024);
int32_t step = lv_bezier3(t, 0, 100, 924, 1024);
int32_t step = lv_bezier3(t, 0, 50, 952, 1024);
int32_t new_value;
new_value = step * (a->end - a->start);
new_value = step * (a->end_value - a->start_value);
new_value = new_value >> 10;
new_value += a->start;
new_value += a->start_value;
return new_value;
}
@@ -337,9 +343,9 @@ int32_t lv_anim_path_overshoot(const lv_anim_path_t * path, const lv_anim_t * a)
int32_t step = lv_bezier3(t, 0, 1000, 1300, 1024);
int32_t new_value;
new_value = step * (a->end - a->start);
new_value = step * (a->end_value - a->start_value);
new_value = new_value >> 10;
new_value += a->start;
new_value += a->start_value;
return new_value;
}
@@ -356,7 +362,7 @@ int32_t lv_anim_path_bounce(const lv_anim_path_t * path, const lv_anim_t * a)
/*Calculate the current step*/
uint32_t t = lv_map(a->act_time, 0, a->time, 0, 1024);
int32_t diff = (a->end - a->start);
int32_t diff = (a->end_value - a->start_value);
/*3 bounces has 5 parts: 3 down and 2 up. One part is t / 5 long*/
@@ -397,7 +403,7 @@ int32_t lv_anim_path_bounce(const lv_anim_path_t * path, const lv_anim_t * a)
int32_t new_value;
new_value = step * diff;
new_value = new_value >> 10;
new_value = a->end - new_value;
new_value = a->end_value - new_value;
return new_value;
}
@@ -413,9 +419,9 @@ int32_t lv_anim_path_step(const lv_anim_path_t * path, const lv_anim_t * a)
LV_UNUSED(path);
if(a->act_time >= a->time)
return a->end;
return a->end_value;
else
return a->start;
return a->start_value;
}
/**********************
@@ -450,6 +456,11 @@ static void anim_task(lv_timer_t * param)
/*The animation will run now for the first time. Call `start_cb`*/
int32_t new_act_time = a->act_time + elaps;
if(a->act_time <= 0 && new_act_time >= 0) {
if(a->early_apply == 0 && a->get_value_cb) {
int32_t v_ofs = a->get_value_cb(a->var);
a->start_value += v_ofs;
a->end_value += v_ofs;
}
if(a->start_cb) a->start_cb(a);
}
a->act_time += elaps;
@@ -460,8 +471,8 @@ static void anim_task(lv_timer_t * param)
if(a->path.cb) new_value = a->path.cb(&a->path, a);
else new_value = lv_anim_path_linear(&a->path, a);
if(new_value != a->current) {
a->current = new_value;
if(new_value != a->current_value) {
a->current_value = new_value;
/*Apply the calculated value*/
if(a->exec_cb) a->exec_cb(a->var, new_value);
}
@@ -525,9 +536,9 @@ static void anim_ready_handler(lv_anim_t * a)
a->playback_now = a->playback_now == 0 ? 1 : 0;
/*Swap the start and end values*/
int32_t tmp;
tmp = a->start;
a->start = a->end;
a->end = tmp;
tmp = a->start_value;
a->start_value = a->end_value;
a->end_value = tmp;
a->time = a->playback_now == 0 ? a->time_orig : a->playback_time;
}

View File

@@ -64,19 +64,23 @@ typedef void (*lv_anim_ready_cb_t)(struct _lv_anim_t *);
/** Callback to call when the animation really stars (considering `delay`)*/
typedef void (*lv_anim_start_cb_t)(struct _lv_anim_t *);
/** Callback used when the animation values are relative to get the current value*/
typedef int32_t (*lv_anim_get_value_cb_t)(void *);
/** 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_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*/
lv_anim_get_value_cb_t get_value_cb; /**< Get the current value in relative mode*/
#if LV_USE_USER_DATA
void * 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 start_value; /**< Start value*/
int32_t current_value; /**< Current value */
int32_t end_value; /**< End value*/
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*/
@@ -160,9 +164,9 @@ static inline void lv_anim_set_delay(lv_anim_t * a, uint32_t delay)
*/
static inline void lv_anim_set_values(lv_anim_t * a, int32_t start, int32_t end)
{
a->start = start;
a->current = start;
a->end = end;
a->start_value = start;
a->current_value = start;
a->end_value = end;
}
/**
@@ -198,6 +202,17 @@ static inline void lv_anim_set_start_cb(lv_anim_t * a, lv_anim_ready_cb_t start_
a->start_cb = start_cb;
}
/**
* Set a function to use the current value of the variable and make start and end value
* relative the the returned current value.
* @param a pointer to an initialized `lv_anim_t` variable
* @param get_value_cb a function call when the animation starts
*/
static inline void lv_anim_set_get_value_cb(lv_anim_t * a, lv_anim_get_value_cb_t get_value_cb)
{
a->get_value_cb = get_value_cb;
}
/**
* Set a function call when the animation is ready
* @param a pointer to an initialized `lv_anim_t` variable
@@ -207,7 +222,6 @@ static inline void lv_anim_set_ready_cb(lv_anim_t * a, lv_anim_ready_cb_t ready_
{
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
@@ -248,6 +262,17 @@ static inline void lv_anim_set_repeat_delay(lv_anim_t * a, uint32_t delay)
a->repeat_delay = delay;
}
/**
* Set a whether the animation's should be applied immediately or only when the delay expired.
* @param a pointer to an initialized `lv_anim_t` variable
* @param en true: apply the start value immediately in `lv_anim_start`;
* false: apply the start value only when `delay` ms is elapsed and the animations really starts
*/
static inline void lv_anim_set_early_apply(lv_anim_t * a, bool en)
{
a->early_apply = en;
}
/**
* Create an animation
* @param a an initialized 'anim_t' variable. Not required after call.

View File

@@ -916,7 +916,7 @@ static void lv_label_refr_text(lv_obj_t * obj)
if(size.x > lv_area_get_width(&txt_coords)) {
lv_anim_set_values(&a, 0, lv_area_get_width(&txt_coords) - size.x);
lv_anim_set_exec_cb(&a, set_ofs_x_anim);
lv_anim_set_time(&a, lv_anim_speed_to_time(anim_speed, a.start, a.end));
lv_anim_set_time(&a, lv_anim_speed_to_time(anim_speed, a.start_value, a.end_value));
lv_anim_set_playback_time(&a, a.time);
lv_anim_t * anim_cur = lv_anim_get(obj, set_ofs_x_anim);
@@ -933,9 +933,9 @@ static void lv_label_refr_text(lv_obj_t * obj)
a.playback_now = 1;
/*Swap the start and end values*/
int32_t tmp;
tmp = a.start;
a.start = a.end;
a.end = tmp;
tmp = a.start_value;
a.start_value = a.end_value;
a.end_value = tmp;
}
}
@@ -951,7 +951,7 @@ static void lv_label_refr_text(lv_obj_t * obj)
if(size.y > lv_area_get_height(&txt_coords) && hor_anim == false) {
lv_anim_set_values(&a, 0, lv_area_get_height(&txt_coords) - size.y - (lv_font_get_line_height(font)));
lv_anim_set_exec_cb(&a, set_ofs_y_anim);
lv_anim_set_time(&a, lv_anim_speed_to_time(anim_speed, a.start, a.end));
lv_anim_set_time(&a, lv_anim_speed_to_time(anim_speed, a.start_value, a.end_value));
lv_anim_set_playback_time(&a, a.time);
lv_anim_t * anim_cur = lv_anim_get(obj, set_ofs_y_anim);
@@ -968,9 +968,9 @@ static void lv_label_refr_text(lv_obj_t * obj)
a.playback_now = 1;
/*Swap the start and end values*/
int32_t tmp;
tmp = a.start;
a.start = a.end;
a.end = tmp;
tmp = a.start_value;
a.start_value = a.end_value;
a.end_value = tmp;
}
}
@@ -995,7 +995,7 @@ static void lv_label_refr_text(lv_obj_t * obj)
if(size.x > lv_area_get_width(&txt_coords)) {
lv_anim_set_values(&a, 0, -size.x - lv_font_get_glyph_width(font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT);
lv_anim_set_exec_cb(&a, set_ofs_x_anim);
lv_anim_set_time(&a, lv_anim_speed_to_time(anim_speed, a.start, a.end));
lv_anim_set_time(&a, lv_anim_speed_to_time(anim_speed, a.start_value, a.end_value));
lv_anim_t * anim_cur = lv_anim_get(obj, set_ofs_x_anim);
int32_t act_time = anim_cur ? anim_cur->act_time : 0;
@@ -1016,7 +1016,7 @@ static void lv_label_refr_text(lv_obj_t * obj)
if(size.y > lv_area_get_height(&txt_coords) && hor_anim == false) {
lv_anim_set_values(&a, 0, -size.y - (lv_font_get_line_height(font)));
lv_anim_set_exec_cb(&a, set_ofs_y_anim);
lv_anim_set_time(&a, lv_anim_speed_to_time(anim_speed, a.start, a.end));
lv_anim_set_time(&a, lv_anim_speed_to_time(anim_speed, a.start_value, a.end_value));
lv_anim_t * anim_cur = lv_anim_get(obj, set_ofs_y_anim);
int32_t act_time = anim_cur ? anim_cur->act_time : 0;