1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

fix(disp): make lv_scr_load work better with lv_scr_load_anim and auto_del = true

related to: https://forum.lvgl.io/t/crash-when-delete-a-screen-by-using-lv-obj-del/8930
This commit is contained in:
Gabor Kiss-Vamosi 2022-05-23 16:42:14 +02:00
parent c63d12f6da
commit 52287fd64a

View File

@ -21,7 +21,7 @@
/**********************
* STATIC PROTOTYPES
**********************/
static void scr_load_internal(lv_obj_t * scr);
static void scr_load_anim_start(lv_anim_t * a);
static void opa_scale_anim(void * obj, int32_t v);
static void set_x_anim(void * obj, int32_t v);
@ -81,20 +81,7 @@ lv_obj_t * lv_disp_get_scr_prev(lv_disp_t * disp)
*/
void lv_disp_load_scr(lv_obj_t * scr)
{
lv_disp_t * d = lv_obj_get_disp(scr);
if(!d) return; /*Shouldn't happen, just to be sure*/
lv_obj_t * old_scr = d->act_scr;
if(d->act_scr) lv_event_send(old_scr, LV_EVENT_SCREEN_UNLOAD_START, NULL);
if(d->act_scr) lv_event_send(scr, LV_EVENT_SCREEN_LOAD_START, NULL);
d->act_scr = scr;
if(d->act_scr) lv_event_send(scr, LV_EVENT_SCREEN_LOADED, NULL);
if(d->act_scr) lv_event_send(old_scr, LV_EVENT_SCREEN_UNLOADED, NULL);
lv_obj_invalidate(scr);
lv_scr_load_anim(scr, LV_SCR_LOAD_ANIM_NONE, 0, 0, false);
}
/**
@ -240,7 +227,7 @@ void lv_scr_load_anim(lv_obj_t * new_scr, lv_scr_load_anim_t anim_type, uint32_t
/*If an other screen load animation is in progress
*make target screen loaded immediately. */
if(d->scr_to_load && act_scr != d->scr_to_load) {
lv_disp_load_scr(d->scr_to_load);
scr_load_internal(d->scr_to_load);
lv_anim_del(d->scr_to_load, NULL);
lv_obj_set_pos(d->scr_to_load, 0, 0);
lv_obj_remove_local_style_prop(d->scr_to_load, LV_STYLE_OPA, 0);
@ -271,6 +258,13 @@ void lv_scr_load_anim(lv_obj_t * new_scr, lv_scr_load_anim_t anim_type, uint32_t
lv_obj_remove_local_style_prop(new_scr, LV_STYLE_OPA, 0);
lv_obj_remove_local_style_prop(lv_scr_act(), LV_STYLE_OPA, 0);
/*Shortcut for immediate load*/
if(time == 0 && delay == 0) {
scr_load_internal(new_scr);
return;
}
lv_anim_t a_new;
lv_anim_init(&a_new);
lv_anim_set_var(&a_new, new_scr);
@ -365,7 +359,6 @@ void lv_scr_load_anim(lv_obj_t * new_scr, lv_scr_load_anim_t anim_type, uint32_t
lv_anim_start(&a_new);
lv_anim_start(&a_old);
}
/**
@ -441,6 +434,24 @@ lv_timer_t * _lv_disp_get_refr_timer(lv_disp_t * disp)
* STATIC FUNCTIONS
**********************/
static void scr_load_internal(lv_obj_t * scr)
{
lv_disp_t * d = lv_obj_get_disp(scr);
if(!d) return; /*Shouldn't happen, just to be sure*/
lv_obj_t * old_scr = d->act_scr;
if(d->act_scr) lv_event_send(old_scr, LV_EVENT_SCREEN_UNLOAD_START, NULL);
if(d->act_scr) lv_event_send(scr, LV_EVENT_SCREEN_LOAD_START, NULL);
d->act_scr = scr;
if(d->act_scr) lv_event_send(scr, LV_EVENT_SCREEN_LOADED, NULL);
if(d->act_scr) lv_event_send(old_scr, LV_EVENT_SCREEN_UNLOADED, NULL);
lv_obj_invalidate(scr);
}
static void scr_load_anim_start(lv_anim_t * a)
{
lv_disp_t * d = lv_obj_get_disp(a->var);
@ -478,6 +489,7 @@ static void scr_anim_ready(lv_anim_t * a)
d->draw_prev_over_act = false;
d->scr_to_load = NULL;
lv_obj_remove_local_style_prop(a->var, LV_STYLE_OPA, 0);
lv_obj_invalidate(d->act_scr);
}
static bool is_out_anim(lv_scr_load_anim_t anim_type)
@ -487,4 +499,4 @@ static bool is_out_anim(lv_scr_load_anim_t anim_type)
anim_type == LV_SCR_LOAD_ANIM_OUT_RIGHT ||
anim_type == LV_SCR_LOAD_ANIM_OUT_TOP ||
anim_type == LV_SCR_LOAD_ANIM_OUT_BOTTOM;
}
}