feat(anim_timeline): add anim's completed_cb support (#6085)

This commit is contained in:
TridentTD
2024-05-09 17:32:59 +08:00
committed by GitHub
parent 2b717a32fd
commit b44bcaee17
2 changed files with 218 additions and 3 deletions
+80 -2
View File
@@ -22,6 +22,8 @@
typedef struct {
lv_anim_t anim;
uint32_t start_time;
uint8_t is_started : 1;
uint8_t is_completed : 1;
} lv_anim_timeline_dsc_t;
/*Data of anim_timeline*/
@@ -90,6 +92,13 @@ uint32_t lv_anim_timeline_start(lv_anim_timeline_t * at)
uint32_t end = at->reverse ? 0 : playtime;
uint32_t duration = end > start ? end - start : start - end;
if((!at->reverse && at->act_time == 0) || (at->reverse && at->act_time == playtime)) {
for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) {
at->anim_dsc[i].is_started = 0;
at->anim_dsc[i].is_completed = 0;
}
}
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_var(&a, at);
@@ -161,30 +170,99 @@ uint16_t lv_anim_timeline_get_progress(lv_anim_timeline_t * at)
static void anim_timeline_set_act_time(lv_anim_timeline_t * at, uint32_t act_time)
{
at->act_time = act_time;
bool anim_timeline_is_started = (lv_anim_get(at, anim_timeline_exec_cb) != NULL);
for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) {
lv_anim_t * a = &(at->anim_dsc[i].anim);
lv_anim_timeline_dsc_t * anim_dsc = &(at->anim_dsc[i]);
lv_anim_t * a = &(anim_dsc->anim);
if(a->exec_cb == NULL && a->custom_exec_cb == NULL) {
continue;
}
uint32_t start_time = at->anim_dsc[i].start_time;
uint32_t start_time = anim_dsc->start_time;
int32_t value = 0;
if(act_time < start_time && a->early_apply) {
if(anim_timeline_is_started) {
if(at->reverse) {
if(!anim_dsc->is_started && a->start_cb) a->start_cb(a);
anim_dsc->is_started = 1;
}
else {
anim_dsc->is_started = 0;
}
}
value = a->start_value;
if(a->exec_cb) a->exec_cb(a->var, value);
if(a->custom_exec_cb) a->custom_exec_cb(a, value);
if(anim_timeline_is_started) {
if(at->reverse) {
if(!anim_dsc->is_completed && a->completed_cb) a->completed_cb(a);
anim_dsc->is_completed = 1;
}
else {
anim_dsc->is_completed = 0;
}
}
}
else if(act_time >= start_time && act_time <= (start_time + a->duration)) {
if(anim_timeline_is_started) {
if(!anim_dsc->is_started && a->start_cb) a->start_cb(a);
anim_dsc->is_started = 1;
}
a->act_time = act_time - start_time;
value = a->path_cb(a);
if(a->exec_cb) a->exec_cb(a->var, value);
if(a->custom_exec_cb) a->custom_exec_cb(a, value);
if(anim_timeline_is_started) {
if(at->reverse) {
if(act_time == start_time) {
if(!anim_dsc->is_completed && a->completed_cb) a->completed_cb(a);
anim_dsc->is_completed = 1;
}
else {
anim_dsc->is_completed = 0;
}
}
else {
if(act_time == (start_time + a->duration)) {
if(!anim_dsc->is_completed && a->completed_cb) a->completed_cb(a);
anim_dsc->is_completed = 1;
}
else {
anim_dsc->is_completed = 0;
}
}
}
}
else if(act_time > start_time + a->duration) {
if(anim_timeline_is_started) {
if(at->reverse) {
anim_dsc->is_started = 0;
}
else {
if(!anim_dsc->is_started && a->start_cb) a->start_cb(a);
anim_dsc->is_started = 1;
}
}
value = a->end_value;
if(a->exec_cb) a->exec_cb(a->var, value);
if(a->custom_exec_cb) a->custom_exec_cb(a, value);
if(anim_timeline_is_started) {
if(at->reverse) {
anim_dsc->is_completed = 0;
}
else {
if(!anim_dsc->is_completed && a->completed_cb) a->completed_cb(a);
anim_dsc->is_completed = 1;
}
}
}
}
}
+138 -1
View File
@@ -7,6 +7,11 @@
static lv_anim_timeline_t * anim_timeline;
static uint32_t anim1_start_called;
static uint32_t anim2_start_called;
static uint32_t anim1_completed_called;
static uint32_t anim2_completed_called;
void setUp(void)
{
/* Function run before every test */
@@ -18,7 +23,6 @@ void tearDown(void)
/* Function run after every test */
if(anim_timeline) lv_anim_timeline_delete(anim_timeline);
lv_obj_clean(lv_screen_active());
}
void test_anim_timeline_progress_1(void)
@@ -322,4 +326,137 @@ void test_anim_timeline_reverse(void)
TEST_ASSERT_EQUAL(20, lv_obj_get_x(obj));
}
void anim1_exec_cb(void * var, int32_t v)
{
LV_UNUSED(var);
printf("[anim1] %d\n", v);
}
void anim1_start(lv_anim_t * a)
{
LV_UNUSED(a);
printf("[anim1] start\n");
anim1_start_called++;
}
void anim1_completed(lv_anim_t * a)
{
LV_UNUSED(a);
printf("[anim1] completed\n");
anim1_completed_called++;
}
void anim2_exec_cb(void * var, int32_t v)
{
LV_UNUSED(var);
printf(" [anim2] %d\n", v);
}
void anim2_start(lv_anim_t * a)
{
LV_UNUSED(a);
printf(" [anim2] start\n");
anim2_start_called++;
}
void anim2_completed(lv_anim_t * a)
{
LV_UNUSED(a);
printf(" [anim2] completed\n");
anim2_completed_called++;
}
void test_anim_timeline_with_anim_start_cb_and_completed_cb(void)
{
lv_anim_t anim1;
lv_anim_t anim2;
lv_anim_init(&anim1);
lv_anim_set_values(&anim1, 0, 1024);
lv_anim_set_duration(&anim1, 300);
lv_anim_set_exec_cb(&anim1, anim1_exec_cb);
lv_anim_set_start_cb(&anim1, anim1_start);
lv_anim_set_completed_cb(&anim1, anim1_completed);
anim1_start_called = 0;
anim1_completed_called = 0;
lv_memcpy(&anim2, &anim1, sizeof(anim1));
lv_anim_set_duration(&anim2, 300);
lv_anim_set_path_cb(&anim2, lv_anim_path_overshoot);
lv_anim_set_exec_cb(&anim2, anim2_exec_cb);
lv_anim_set_start_cb(&anim2, anim2_start);
lv_anim_set_completed_cb(&anim2, anim2_completed);
anim2_start_called = 0;
anim2_completed_called = 0;
anim_timeline = lv_anim_timeline_create();
lv_anim_timeline_add(anim_timeline, 0, &anim1);
lv_anim_timeline_add(anim_timeline, 200, &anim2);
lv_anim_timeline_set_progress(anim_timeline, 0);
lv_anim_timeline_start(anim_timeline);
lv_refr_now(NULL);
/* |----- Reverse ------|
* |-----anim1-----| |--anim1 rvs--|
* |----anim2----| |--anim2 rvs--|
*
* 0 200 300 500 600 800 900 1100
*/
lv_test_wait(20); /*Wait 20 ms*/
TEST_ASSERT_EQUAL(1, anim1_start_called);
TEST_ASSERT_EQUAL(0, anim1_completed_called);
TEST_ASSERT_EQUAL(0, anim2_start_called);
TEST_ASSERT_EQUAL(0, anim2_completed_called);
lv_test_wait(200); /*Now we are at 220ms */
TEST_ASSERT_EQUAL(1, anim1_start_called);
TEST_ASSERT_EQUAL(0, anim1_completed_called);
TEST_ASSERT_EQUAL(1, anim2_start_called);
TEST_ASSERT_EQUAL(0, anim2_completed_called);
lv_test_wait(100); /*Now we are at 320ms */
TEST_ASSERT_EQUAL(1, anim1_start_called);
TEST_ASSERT_EQUAL(1, anim1_completed_called);
TEST_ASSERT_EQUAL(1, anim2_start_called);
TEST_ASSERT_EQUAL(0, anim2_completed_called);
lv_test_wait(200); /*Now we are at 520ms */
TEST_ASSERT_EQUAL(1, anim1_start_called);
TEST_ASSERT_EQUAL(1, anim1_completed_called);
TEST_ASSERT_EQUAL(1, anim2_start_called);
TEST_ASSERT_EQUAL(1, anim2_completed_called);
lv_test_wait(80); /*Now we are at 600ms */
anim1_start_called = 0;
anim1_completed_called = 0;
anim2_start_called = 0;
anim2_completed_called = 0;
lv_anim_timeline_set_reverse(anim_timeline, true);
lv_anim_timeline_set_progress(anim_timeline, LV_ANIM_TIMELINE_PROGRESS_MAX);
lv_anim_timeline_start(anim_timeline);
lv_test_wait(20); /*Now we are at 620ms */
TEST_ASSERT_EQUAL(0, anim1_start_called);
TEST_ASSERT_EQUAL(0, anim1_completed_called);
TEST_ASSERT_EQUAL(1, anim2_start_called);
TEST_ASSERT_EQUAL(0, anim2_completed_called);
lv_test_wait(200); /*Now we are at 820ms */
TEST_ASSERT_EQUAL(1, anim1_start_called);
TEST_ASSERT_EQUAL(0, anim1_completed_called);
TEST_ASSERT_EQUAL(1, anim2_start_called);
TEST_ASSERT_EQUAL(0, anim2_completed_called);
lv_test_wait(100); /*Now we are at 920ms */
TEST_ASSERT_EQUAL(1, anim1_start_called);
TEST_ASSERT_EQUAL(0, anim1_completed_called);
TEST_ASSERT_EQUAL(1, anim2_start_called);
TEST_ASSERT_EQUAL(1, anim2_completed_called);
lv_test_wait(200); /*Now we are at 1120ms */
TEST_ASSERT_EQUAL(1, anim1_start_called);
TEST_ASSERT_EQUAL(1, anim1_completed_called);
TEST_ASSERT_EQUAL(1, anim2_start_called);
TEST_ASSERT_EQUAL(1, anim2_completed_called);
}
#endif