diff --git a/docs/overview/object.md b/docs/overview/object.md index 7761859fc..e532890fc 100644 --- a/docs/overview/object.md +++ b/docs/overview/object.md @@ -164,8 +164,9 @@ Read the [Layer overview](/overview/layer) section to learn more about layers. A new screen can be loaded with animation by using `lv_scr_load_anim(scr, transition_type, time, delay, auto_del)`. The following transition types exist: - `LV_SCR_LOAD_ANIM_NONE` Switch immediately after `delay` milliseconds - `LV_SCR_LOAD_ANIM_OVER_LEFT/RIGHT/TOP/BOTTOM` Move the new screen over the current towards the given direction +- `LV_SCR_LOAD_ANIM_OUT_LEFT/RIGHT/TOP/BOTTOM` Move out the old screen over the current towards the given direction - `LV_SCR_LOAD_ANIM_MOVE_LEFT/RIGHT/TOP/BOTTOM` Move both the current and new screens towards the given direction -- `LV_SCR_LOAD_ANIM_FADE_ON` Fade the new screen over the old screen +- `LV_SCR_LOAD_ANIM_FADE_IN/OUT` Fade the new screen over the old screen, or vice versa Setting `auto_del` to `true` will automatically delete the old screen when the animation is finished. diff --git a/src/core/lv_disp.c b/src/core/lv_disp.c index 2806c4e7b..030e4bc71 100644 --- a/src/core/lv_disp.c +++ b/src/core/lv_disp.c @@ -27,6 +27,7 @@ static void opa_scale_anim(void * obj, int32_t v); static void set_x_anim(void * obj, int32_t v); static void set_y_anim(void * obj, int32_t v); static void scr_anim_ready(lv_anim_t * a); +static bool is_out_anim(lv_scr_load_anim_t a); /********************** * STATIC VARIABLES @@ -252,6 +253,7 @@ void lv_scr_load_anim(lv_obj_t * new_scr, lv_scr_load_anim_t anim_type, uint32_t d->prev_scr = NULL; } + d->draw_prev_over_act = is_out_anim(anim_type); d->del_prev = auto_del; /*Be sure there is no other animation on the screens*/ @@ -328,11 +330,30 @@ void lv_scr_load_anim(lv_obj_t * new_scr, lv_scr_load_anim_t anim_type, uint32_t lv_anim_set_exec_cb(&a_old, set_y_anim); lv_anim_set_values(&a_old, 0, lv_disp_get_ver_res(d)); break; - - case LV_SCR_LOAD_ANIM_FADE_ON: + case LV_SCR_LOAD_ANIM_FADE_IN: lv_anim_set_exec_cb(&a_new, opa_scale_anim); lv_anim_set_values(&a_new, LV_OPA_TRANSP, LV_OPA_COVER); break; + case LV_SCR_LOAD_ANIM_FADE_OUT: + lv_anim_set_exec_cb(&a_old, opa_scale_anim); + lv_anim_set_values(&a_old, LV_OPA_COVER, LV_OPA_TRANSP); + break; + case LV_SCR_LOAD_ANIM_OUT_LEFT: + lv_anim_set_exec_cb(&a_old, set_x_anim); + lv_anim_set_values(&a_old, 0, -lv_disp_get_hor_res(d)); + break; + case LV_SCR_LOAD_ANIM_OUT_RIGHT: + lv_anim_set_exec_cb(&a_old, set_x_anim); + lv_anim_set_values(&a_old, 0, lv_disp_get_hor_res(d)); + break; + case LV_SCR_LOAD_ANIM_OUT_TOP: + lv_anim_set_exec_cb(&a_old, set_y_anim); + lv_anim_set_values(&a_old, 0, -lv_disp_get_ver_res(d)); + break; + case LV_SCR_LOAD_ANIM_OUT_BOTTOM: + lv_anim_set_exec_cb(&a_old, set_y_anim); + lv_anim_set_values(&a_old, 0, lv_disp_get_ver_res(d)); + break; } lv_event_send(act_scr, LV_EVENT_SCREEN_UNLOAD_START, NULL); @@ -449,6 +470,16 @@ static void scr_anim_ready(lv_anim_t * a) if(d->prev_scr && d->del_prev) lv_obj_del(d->prev_scr); d->prev_scr = NULL; + d->draw_prev_over_act = false; d->scr_to_load = NULL; lv_obj_remove_local_style_prop(a->var, LV_STYLE_OPA, 0); } + +static bool is_out_anim(lv_scr_load_anim_t anim_type) +{ + return anim_type == LV_SCR_LOAD_ANIM_FADE_OUT || + anim_type == LV_SCR_LOAD_ANIM_OUT_LEFT || + anim_type == LV_SCR_LOAD_ANIM_OUT_RIGHT || + anim_type == LV_SCR_LOAD_ANIM_OUT_TOP || + anim_type == LV_SCR_LOAD_ANIM_OUT_BOTTOM; +} \ No newline at end of file diff --git a/src/core/lv_disp.h b/src/core/lv_disp.h index 01766b345..9c718f3a6 100644 --- a/src/core/lv_disp.h +++ b/src/core/lv_disp.h @@ -35,7 +35,13 @@ typedef enum { LV_SCR_LOAD_ANIM_MOVE_RIGHT, LV_SCR_LOAD_ANIM_MOVE_TOP, LV_SCR_LOAD_ANIM_MOVE_BOTTOM, - LV_SCR_LOAD_ANIM_FADE_ON, + LV_SCR_LOAD_ANIM_FADE_IN, + LV_SCR_LOAD_ANIM_FADE_ON = LV_SCR_LOAD_ANIM_FADE_IN, /*For backward compatibility*/ + LV_SCR_LOAD_ANIM_FADE_OUT, + LV_SCR_LOAD_ANIM_OUT_LEFT, + LV_SCR_LOAD_ANIM_OUT_RIGHT, + LV_SCR_LOAD_ANIM_OUT_TOP, + LV_SCR_LOAD_ANIM_OUT_BOTTOM, } lv_scr_load_anim_t; /********************** diff --git a/src/core/lv_indev.c b/src/core/lv_indev.c index 3348bd6be..58e9d85db 100644 --- a/src/core/lv_indev.c +++ b/src/core/lv_indev.c @@ -75,14 +75,15 @@ void lv_indev_read_timer_cb(lv_timer_t * timer) /*Handle reset query before processing the point*/ indev_proc_reset_query_handler(indev_act); - if(indev_act->proc.disabled) return; + if(indev_act->proc.disabled || + indev_act->driver->disp->prev_scr != NULL) return; /*Input disabled or screen animation active*/ bool continue_reading; do { /*Read the data*/ _lv_indev_read(indev_act, &data); continue_reading = data.continue_reading; - /*The active object might deleted even in the read function*/ + /*The active object might be deleted even in the read function*/ indev_proc_reset_query_handler(indev_act); indev_obj_act = NULL; diff --git a/src/core/lv_indev.h b/src/core/lv_indev.h index 80c793977..5d0158766 100644 --- a/src/core/lv_indev.h +++ b/src/core/lv_indev.h @@ -35,7 +35,11 @@ extern "C" { */ void lv_indev_read_timer_cb(lv_timer_t * timer); - +/** + * Enable or disable an input device (default enabled) + * @param indev pointer to an input device + * @param en true to enable, false to disable + */ void lv_indev_enable(lv_indev_t * indev, bool en); /** diff --git a/src/core/lv_refr.c b/src/core/lv_refr.c index 5e6ef555a..9ed1845c4 100644 --- a/src/core/lv_refr.c +++ b/src/core/lv_refr.c @@ -668,14 +668,27 @@ static void lv_refr_area_part(lv_draw_ctx_t * draw_ctx) lv_draw_rect(draw_ctx, &dsc, draw_ctx->buf_area); } } - /*Refresh the previous screen if any*/ - if(disp_refr->prev_scr) { - if(top_prev_scr == NULL) top_prev_scr = disp_refr->prev_scr; - lv_refr_obj_and_children(draw_ctx, top_prev_scr); - } - if(top_act_scr == NULL) top_act_scr = disp_refr->act_scr; - lv_refr_obj_and_children(draw_ctx, top_act_scr); + if(disp_refr->draw_prev_over_act) { + if(top_act_scr == NULL) top_act_scr = disp_refr->act_scr; + lv_refr_obj_and_children(draw_ctx, top_act_scr); + + /*Refresh the previous screen if any*/ + if(disp_refr->prev_scr) { + if(top_prev_scr == NULL) top_prev_scr = disp_refr->prev_scr; + lv_refr_obj_and_children(draw_ctx, top_prev_scr); + } + } + else { + /*Refresh the previous screen if any*/ + if(disp_refr->prev_scr) { + if(top_prev_scr == NULL) top_prev_scr = disp_refr->prev_scr; + lv_refr_obj_and_children(draw_ctx, top_prev_scr); + } + + if(top_act_scr == NULL) top_act_scr = disp_refr->act_scr; + lv_refr_obj_and_children(draw_ctx, top_act_scr); + } /*Also refresh top and sys layer unconditionally*/ lv_refr_obj_and_children(draw_ctx, lv_disp_get_layer_top(disp_refr)); diff --git a/src/hal/lv_hal_disp.h b/src/hal/lv_hal_disp.h index 8400f3c06..61f25c9ba 100644 --- a/src/hal/lv_hal_disp.h +++ b/src/hal/lv_hal_disp.h @@ -170,6 +170,8 @@ typedef struct _lv_disp_t { struct _lv_obj_t * top_layer; /**< @see lv_disp_get_layer_top*/ struct _lv_obj_t * sys_layer; /**< @see lv_disp_get_layer_sys*/ uint32_t screen_cnt; +uint8_t draw_prev_over_act : + 1; /**< 1: Draw previous screen over active screen*/ uint8_t del_prev : 1; /**< 1: Automatically delete the previous screen when the screen load animation is ready*/ uint8_t rendering_in_progress : 1; /**< 1: The current screen rendering is in progress*/