mirror of
https://github.com/lvgl/lvgl.git
synced 2026-09-22 03:05:41 +08:00
feat(anim_timeline): add anim's completed_cb support (#6085)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user