diff --git a/src/lv_core/lv_disp.c b/src/lv_core/lv_disp.c index cf2f49d51d..bcb73829eb 100644 --- a/src/lv_core/lv_disp.c +++ b/src/lv_core/lv_disp.c @@ -54,7 +54,7 @@ lv_obj_t * lv_disp_get_scr_act(lv_disp_t * disp) * Make a screen active * @param scr pointer to a screen */ -void lv_disp_set_scr_act(lv_obj_t * scr) +void lv_disp_load_scr(lv_obj_t * scr) { lv_disp_t * d = lv_obj_get_disp(scr); diff --git a/src/lv_core/lv_disp.h b/src/lv_core/lv_disp.h index c0b0e0af10..3b9f01fcc4 100644 --- a/src/lv_core/lv_disp.h +++ b/src/lv_core/lv_disp.h @@ -40,7 +40,7 @@ lv_obj_t * lv_disp_get_scr_act(lv_disp_t * disp); * Make a screen active * @param scr pointer to a screen */ -void lv_disp_set_scr_act(lv_obj_t * scr); +void lv_disp_load_scr(lv_obj_t * scr); /** * Return with the top layer. (Same on every screen and it is above the normal screen layer) @@ -119,7 +119,7 @@ static inline lv_obj_t * lv_layer_sys(void) static inline void lv_scr_load(lv_obj_t * scr) { - lv_disp_set_scr_act(scr); + lv_disp_load_scr(scr); } /********************** diff --git a/src/lv_core/lv_group.c b/src/lv_core/lv_group.c index af3e1639a9..4de24d1d77 100644 --- a/src/lv_core/lv_group.c +++ b/src/lv_core/lv_group.c @@ -554,7 +554,7 @@ static void style_mod_def(lv_group_t * group, lv_style_t * style) style->body.border.opa = LV_OPA_COVER; style->body.border.color = LV_COLOR_ORANGE; - /*If not empty or has border then emphasis the border*/ + /*If not transparent or has border then emphasis the border*/ if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20; style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_ORANGE, LV_OPA_70); diff --git a/src/lv_core/lv_refr.c b/src/lv_core/lv_refr.c index a7c30188f9..40ef7c2c1e 100644 --- a/src/lv_core/lv_refr.c +++ b/src/lv_core/lv_refr.c @@ -562,8 +562,7 @@ static void lv_refr_vdb_flush(void) /*In double buffered mode wait until the other buffer is flushed before flushing the current * one*/ if(lv_disp_is_double_buf(disp_refr)) { - while(vdb->flushing) - ; + while(vdb->flushing); } vdb->flushing = 1; @@ -573,14 +572,7 @@ static void lv_refr_vdb_flush(void) if(disp->driver.flush_cb) disp->driver.flush_cb(&disp->driver, &vdb->area, vdb->buf_act); if(vdb->buf1 && vdb->buf2) { - if(vdb->buf_act == vdb->buf1) - vdb->buf_act = vdb->buf2; - else - vdb->buf_act = vdb->buf1; - - /*If the screen is transparent initialize it when the new VDB is selected*/ -#if LV_COLOR_SCREEN_TRANSP - memset(vdb[vdb_active].buf, 0x00, LV_VDB_SIZE_IN_BYTES); -#endif /*LV_COLOR_SCREEN_TRANSP*/ + if(vdb->buf_act == vdb->buf1) vdb->buf_act = vdb->buf2; + else vdb->buf_act = vdb->buf1; } } diff --git a/src/lv_draw/lv_draw_basic.c b/src/lv_draw/lv_draw_basic.c index 6dd45c2e2a..1693db4d1a 100644 --- a/src/lv_draw/lv_draw_basic.c +++ b/src/lv_draw/lv_draw_basic.c @@ -45,9 +45,7 @@ static void sw_mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t len static void sw_color_fill(lv_color_t * mem, lv_coord_t mem_width, const lv_area_t * fill_area, lv_color_t color, lv_opa_t opa); -#if LV_COLOR_SCREEN_TRANSP static inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa, lv_color_t fg_color, lv_opa_t fg_opa); -#endif /********************** * STATIC VARIABLES @@ -71,6 +69,7 @@ static inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa, */ void lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa) { + if(opa < LV_OPA_MIN) return; if(opa > LV_OPA_MAX) opa = LV_OPA_COVER; @@ -87,20 +86,27 @@ void lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t x -= vdb->area.x1; y -= vdb->area.y1; + if(disp->driver.set_px_cb) { disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, x, y, color, opa); } else { + bool scr_transp = false; + #if LV_COLOR_SCREEN_TRANSP + scr_transp = disp->driver.screen_transp; + #endif + lv_color_t * vdb_px_p = vdb->buf_act; vdb_px_p += y * vdb_width + x; -#if LV_COLOR_SCREEN_TRANSP == 0 - if(opa == LV_OPA_COVER) { - *vdb_px_p = color; + + if(scr_transp == false) { + if(opa == LV_OPA_COVER) { + *vdb_px_p = color; + } else { + *vdb_px_p = lv_color_mix(color, *vdb_px_p, opa); + } } else { - *vdb_px_p = lv_color_mix(color, *vdb_px_p, opa); + *vdb_px_p = color_mix_2_alpha(*vdb_px_p, (*vdb_px_p).ch.alpha, color, opa); } -#else - *vdb_px_p = color_mix_2_alpha(*vdb_px_p, (*vdb_px_p).alpha, color, opa); -#endif } } @@ -309,6 +315,11 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv uint16_t col_bit; col_bit = bit_ofs & 0x7; /* "& 0x7" equals to "% 8" just faster */ + bool scr_transp = false; +#if LV_COLOR_SCREEN_TRANSP + scr_transp = disp->driver.screen_transp; +#endif + for(row = row_start; row < row_end; row++) { bitmask = bitmask_init >> col_bit; for(col = col_start; col < col_end; col++) { @@ -328,11 +339,11 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv if(px_opa > LV_OPA_MAX) *vdb_buf_tmp = color; else if(px_opa > LV_OPA_MIN) { -#if LV_COLOR_SCREEN_TRANSP == 0 - *vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, px_opa); -#else - *vdb_buf_tmp = color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).alpha, color, px_opa); -#endif + if(scr_transp == false) { + *vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, px_opa); + } else { + *vdb_buf_tmp = color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).ch.alpha, color, px_opa); + } } } } @@ -414,6 +425,13 @@ void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p, const uint lv_coord_t row; lv_coord_t map_useful_w = lv_area_get_width(&masked_a); + + bool scr_transp = false; +#if LV_COLOR_SCREEN_TRANSP + scr_transp = disp->driver.screen_transp; +#endif + + /*The simplest case just copy the pixels into the VDB*/ if(chroma_key == false && alpha_byte == false && opa == LV_OPA_COVER && recolor_opa == LV_OPA_TRANSP) { @@ -449,6 +467,7 @@ void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p, const uint /*In the other cases every pixel need to be checked one-by-one*/ else { + lv_coord_t col; lv_color_t last_img_px = LV_COLOR_BLACK; lv_color_t recolored_px = lv_color_mix(recolor, last_img_px, recolor_opa); @@ -508,15 +527,17 @@ void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p, const uint } /*Normal native VDB write*/ else { + + if(opa_result == LV_OPA_COVER) vdb_buf_tmp[col] = px_color; else { -#if LV_COLOR_SCREEN_TRANSP == 0 - vdb_buf_tmp[col] = lv_color_mix(px_color, vdb_buf_tmp[col], opa_result); -#else - vdb_buf_tmp[col] = - color_mix_2_alpha(vdb_buf_tmp[col], vdb_buf_tmp[col].alpha, px_color, opa_result); -#endif + if(scr_transp == false) { + vdb_buf_tmp[col] = lv_color_mix(px_color, vdb_buf_tmp[col], opa_result); + } else { + vdb_buf_tmp[col] = + color_mix_2_alpha(vdb_buf_tmp[col], vdb_buf_tmp[col].ch.alpha, px_color, opa_result); + } } } } @@ -596,25 +617,27 @@ static void sw_color_fill(lv_color_t * mem, lv_coord_t mem_width, const lv_area_ } /*Calculate with alpha too*/ else { + bool scr_transp = false; + #if LV_COLOR_SCREEN_TRANSP + scr_transp = disp->driver.screen_transp; + #endif -#if LV_COLOR_SCREEN_TRANSP == 0 lv_color_t bg_tmp = LV_COLOR_BLACK; lv_color_t opa_tmp = lv_color_mix(color, bg_tmp, opa); -#endif for(row = fill_area->y1; row <= fill_area->y2; row++) { for(col = fill_area->x1; col <= fill_area->x2; col++) { -#if LV_COLOR_SCREEN_TRANSP == 0 - /*If the bg color changed recalculate the result color*/ - if(mem[col].full != bg_tmp.full) { - bg_tmp = mem[col]; - opa_tmp = lv_color_mix(color, bg_tmp, opa); + if(scr_transp == false) { + /*If the bg color changed recalculate the result color*/ + if(mem[col].full != bg_tmp.full) { + bg_tmp = mem[col]; + opa_tmp = lv_color_mix(color, bg_tmp, opa); + } + + mem[col] = opa_tmp; + + } else { + mem[col] = color_mix_2_alpha(mem[col], mem[col].ch.alpha, color, opa); } - - mem[col] = opa_tmp; - -#else - mem[col] = color_mix_2_alpha(mem[col], mem[col].alpha, color, opa); -#endif } mem += mem_width; } @@ -622,7 +645,6 @@ static void sw_color_fill(lv_color_t * mem, lv_coord_t mem_width, const lv_area_ } } -#if LV_COLOR_SCREEN_TRANSP /** * Mix two colors. Both color can have alpha value. It requires ARGB888 colors. @@ -634,8 +656,10 @@ static void sw_color_fill(lv_color_t * mem, lv_coord_t mem_width, const lv_area_ */ static inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa, lv_color_t fg_color, lv_opa_t fg_opa) { + +#if LV_COLOR_SCREEN_TRANSP /* Pick the foreground if it's fully opaque or the Background is fully transparent*/ - if(fg_opa == LV_OPA_COVER || bg_opa <= LV_OPA_MIN) { + if(fg_opa > LV_OPA_MAX|| bg_opa <= LV_OPA_MIN) { fg_color.ch.alpha = fg_opa; return fg_color; } @@ -660,8 +684,8 @@ static inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa, bg_color.full != bg_color_save.full) { fg_opa_save = fg_opa; bg_opa_save = bg_opa; - fg_color.full = fg_color_save.full; - bg_color.full = bg_color_save.full; + fg_color_save.full = fg_color.full; + bg_color_save.full = bg_color.full; /*Info: * https://en.wikipedia.org/wiki/Alpha_compositing#Analytical_derivation_of_the_over_operator*/ lv_opa_t alpha_res = 255 - ((uint16_t)((uint16_t)(255 - fg_opa) * (255 - bg_opa)) >> 8); @@ -675,6 +699,12 @@ static inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa, } return c; } -} +#else + (void)bg_color; /*Unused*/ + (void)fg_color; /*Unused*/ + (void)bg_opa; /*Unused*/ + (void)fg_opa; /*Unused*/ #endif /*LV_COLOR_SCREEN_TRANSP*/ +} + diff --git a/src/lv_draw/lv_draw_img.c b/src/lv_draw/lv_draw_img.c index a22348f2f9..6185863e1f 100644 --- a/src/lv_draw/lv_draw_img.c +++ b/src/lv_draw/lv_draw_img.c @@ -452,18 +452,18 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas if(cdsc == NULL) return LV_RES_INV; - bool chroma_keyed = lv_img_color_format_is_chroma_keyed(cdsc->dsc.header.cf); - bool alpha_byte = lv_img_color_format_has_alpha(cdsc->dsc.header.cf); + bool chroma_keyed = lv_img_color_format_is_chroma_keyed(cdsc->dec_dsc.header.cf); + bool alpha_byte = lv_img_color_format_has_alpha(cdsc->dec_dsc.header.cf); - if(cdsc->dsc.error_msg != NULL) { + if(cdsc->dec_dsc.error_msg != NULL) { LV_LOG_WARN("Image draw error"); lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER); - lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dsc.error_msg, LV_TXT_FLAG_NONE, NULL, -1, -1, NULL); + lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, -1, -1, NULL); } /* The decoder open could open the image and gave the entire uncompressed image. * Just draw it!*/ - else if(cdsc->dsc.img_data) { - lv_draw_map(coords, mask, cdsc->dsc.img_data, opa, chroma_keyed, alpha_byte, style->image.color, style->image.intense); + else if(cdsc->dec_dsc.img_data) { + lv_draw_map(coords, mask, cdsc->dec_dsc.img_data, opa, chroma_keyed, alpha_byte, style->image.color, style->image.intense); } /* The whole uncompressed image is not available. Try to read it line-by-line*/ else { @@ -482,9 +482,9 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas lv_coord_t row; lv_res_t read_res; for(row = mask_com.y1; row <= mask_com.y2; row++) { - read_res = lv_img_decoder_read_line(&cdsc->dsc, x, y, width, buf); + read_res = lv_img_decoder_read_line(&cdsc->dec_dsc, x, y, width, buf); if(read_res != LV_RES_OK) { - lv_img_decoder_close(&cdsc->dsc); + lv_img_decoder_close(&cdsc->dec_dsc); LV_LOG_WARN("Image draw can't read the line"); return LV_RES_INV; } diff --git a/src/lv_draw/lv_img_cache.c b/src/lv_draw/lv_img_cache.c index 033ae39e62..e464d02454 100644 --- a/src/lv_draw/lv_img_cache.c +++ b/src/lv_draw/lv_img_cache.c @@ -41,7 +41,7 @@ /********************** * STATIC VARIABLES **********************/ -static uint16_t slot_num; +static uint16_t entry_cnt; /********************** * MACROS @@ -61,7 +61,7 @@ static uint16_t slot_num; */ lv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * style) { - if(slot_num == 0) { + if(entry_cnt == 0) { LV_LOG_WARN("lv_img_cache_open: the cache size is 0"); return NULL; } @@ -70,7 +70,7 @@ lv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * st /*Decrement all lifes. Make the entries older*/ uint16_t i; - for(i = 0; i < slot_num; i++) { + for(i = 0; i < entry_cnt; i++) { if(cache[i].life > INT32_MIN + LV_IMG_CACHE_AGING) { cache[i].life -= LV_IMG_CACHE_AGING; } @@ -78,54 +78,59 @@ lv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * st /*Is the image cached?*/ lv_img_cache_entry_t * cached_src = NULL; - for(i = 0; i < slot_num; i++) { - if(cache[i].dsc.src == src) { + for(i = 0; i < entry_cnt; i++) { + if(cache[i].dec_dsc.src == src) { /* If opened increment its life. * Image difficult to open should live longer to keep avoid frequent their recaching. * Therefore increase `life` with `time_to_open`*/ cached_src = &cache[i]; - cached_src->life += cached_src->time_to_open * LV_IMG_CACHE_LIFE_GAIN ; + cached_src->life += cached_src->dec_dsc.time_to_open * LV_IMG_CACHE_LIFE_GAIN ; if(cached_src->life > LV_IMG_CACHE_LIFE_LIMIT) cached_src->life = LV_IMG_CACHE_LIFE_LIMIT; LV_LOG_TRACE("image draw: image found in the cache"); break; } } - /*The image is not cached then cache it now*/ if(cached_src == NULL) { /*Find an entry to reuse. Select the entry with the least life*/ cached_src = &cache[0]; - for(i = 1; i < slot_num; i++) { + for(i = 1; i < entry_cnt; i++) { if(cache[i].life < cached_src->life) { cached_src = &cache[i]; } } - /*Close the slot to reuse if it was opened (has a valid source)*/ - if(cached_src->dsc.src) { - lv_img_decoder_close(&cached_src->dsc); - LV_LOG_INFO("image draw: cache miss, close and reuse a slot"); + /*Close the decoder to reuse if it was opened (has a valid source)*/ + if(cached_src->dec_dsc.src) { + lv_img_decoder_close(&cached_src->dec_dsc); + LV_LOG_INFO("image draw: cache miss, close and reuse an entry"); } else { - LV_LOG_INFO("image draw: cache miss, cached in empty slot"); + LV_LOG_INFO("image draw: cache miss, cached to an empty entry"); } /*Open the image and measure the time to open*/ uint32_t t_start; t_start = lv_tick_get(); - lv_res_t open_res = lv_img_decoder_open(&cached_src->dsc, src, style); + cached_src->dec_dsc.time_to_open = 0; + lv_res_t open_res = lv_img_decoder_open(&cached_src->dec_dsc, src, style); if(open_res ==LV_RES_INV) { LV_LOG_WARN("Image draw cannot open the image resource"); - lv_img_decoder_close(&cached_src->dsc); - memset(&cached_src->dsc, 0, sizeof(lv_img_decoder_dsc_t)); + lv_img_decoder_close(&cached_src->dec_dsc); + memset(&cached_src->dec_dsc, 0, sizeof(lv_img_decoder_dsc_t)); memset(&cached_src, 0, sizeof(lv_img_cache_entry_t)); cached_src->life = INT32_MIN; /*Make the empty entry very "weak" to force its use */ return NULL; } cached_src->life = 0; - cached_src->time_to_open = lv_tick_elaps(t_start); - if(cached_src->time_to_open == 0) cached_src->time_to_open = 1; + + /*If `time_to_open` was not set in the open function set it here*/ + if(cached_src->dec_dsc.time_to_open == 0) { + cached_src->dec_dsc.time_to_open = lv_tick_elaps(t_start); + } + + if(cached_src->dec_dsc.time_to_open == 0) cached_src->dec_dsc.time_to_open = 1; } return cached_src; @@ -135,9 +140,9 @@ lv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * st * Set the number of images to be cached. * More cached images mean more opened image at same time which might mean more memory usage. * E.g. if 20 PNG or JPG images are open in the RAM they consume memory while opened in the cache. - * @param new_slot_num number of image to cache + * @param new_entry_cnt number of image to cache */ -void lv_img_cache_set_size(uint16_t new_slot_num) +void lv_img_cache_set_size(uint16_t new_entry_cnt) { if(LV_GC_ROOT(_lv_img_cache_array) != NULL) { /*Clean the cache before free it*/ @@ -146,18 +151,18 @@ void lv_img_cache_set_size(uint16_t new_slot_num) } /*Reallocate the cache*/ - LV_GC_ROOT(_lv_img_cache_array) = lv_mem_alloc(sizeof(lv_img_cache_entry_t) * new_slot_num); + LV_GC_ROOT(_lv_img_cache_array) = lv_mem_alloc(sizeof(lv_img_cache_entry_t) * new_entry_cnt); lv_mem_assert(LV_GC_ROOT(_lv_img_cache_array)); if(LV_GC_ROOT(_lv_img_cache_array) == NULL) { - slot_num = 0; + entry_cnt = 0; return; } - slot_num = new_slot_num; + entry_cnt = new_entry_cnt; /*Clean the cache*/ uint16_t i; - for(i = 0; i < slot_num; i++) { - memset(&LV_GC_ROOT(_lv_img_cache_array)[i].dsc, 0, sizeof(lv_img_decoder_dsc_t)); + for(i = 0; i < entry_cnt; i++) { + memset(&LV_GC_ROOT(_lv_img_cache_array)[i].dec_dsc, 0, sizeof(lv_img_decoder_dsc_t)); memset(&LV_GC_ROOT(_lv_img_cache_array)[i], 0, sizeof(lv_img_cache_entry_t)); } } @@ -173,13 +178,13 @@ void lv_img_cache_invalidate_src(const void * src) lv_img_cache_entry_t * cache = LV_GC_ROOT(_lv_img_cache_array); uint16_t i; - for(i = 0; i < slot_num; i++) { - if(cache[i].dsc.src == src || src == NULL) { - if(cache[i].dsc.src != NULL) { - lv_img_decoder_close(&cache[i].dsc); + for(i = 0; i < entry_cnt; i++) { + if(cache[i].dec_dsc.src == src || src == NULL) { + if(cache[i].dec_dsc.src != NULL) { + lv_img_decoder_close(&cache[i].dec_dsc); } - memset(&cache[i].dsc, 0, sizeof(lv_img_decoder_dsc_t)); + memset(&cache[i].dec_dsc, 0, sizeof(lv_img_decoder_dsc_t)); memset(&cache[i], 0, sizeof(lv_img_cache_entry_t)); } } diff --git a/src/lv_draw/lv_img_cache.h b/src/lv_draw/lv_img_cache.h index 34d6fef3d4..d7e377bf47 100644 --- a/src/lv_draw/lv_img_cache.h +++ b/src/lv_draw/lv_img_cache.h @@ -24,10 +24,7 @@ extern "C" { **********************/ typedef struct { - lv_img_decoder_dsc_t dsc; - - /* How much time did it take to open the image.*/ - uint32_t time_to_open; + lv_img_decoder_dsc_t dec_dsc; /* Count the cache entries's life. Add `time_tio_open` to `life` when the entry is used. * Decrement all lifes by one every in every `lv_img_cache_open`. diff --git a/src/lv_draw/lv_img_decoder.h b/src/lv_draw/lv_img_decoder.h index 5eb427848b..9e4045fd95 100644 --- a/src/lv_draw/lv_img_decoder.h +++ b/src/lv_draw/lv_img_decoder.h @@ -178,6 +178,10 @@ typedef struct _lv_img_decoder_dsc * MUST be set in `open` function*/ const uint8_t * img_data; + /** How much time did it take to open the image. [ms] + * If not set `lv_img_cache` will measure and set the time to open*/ + uint32_t time_to_open; + /**A text to display instead of the image when the image can't be opened. * Can be set in `open` function or set NULL. */ const char * error_msg; diff --git a/src/lv_hal/lv_hal_disp.c b/src/lv_hal/lv_hal_disp.c index 285613d0ca..2e8f238522 100644 --- a/src/lv_hal/lv_hal_disp.c +++ b/src/lv_hal/lv_hal_disp.c @@ -67,6 +67,11 @@ void lv_disp_drv_init(lv_disp_drv_t * driver) driver->antialiasing = true; #endif +#if LV_COLOR_SCREEN_TRANSP + driver->screen_transp = 1; +#endif + + #if LV_USE_GPU driver->mem_blend_cb = NULL; driver->mem_fill_cb = NULL; @@ -267,7 +272,9 @@ LV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_drv_t * disp_drv) /*If the screen is transparent initialize it when the flushing is ready*/ #if LV_COLOR_SCREEN_TRANSP - memset(vdb_buf, 0x00, LV_VDB_SIZE_IN_BYTES); + if(disp_drv->screen_transp) { + memset(disp_drv->buffer->buf_act, 0x00, disp_drv->buffer->size * sizeof(lv_color32_t)); + } #endif } diff --git a/src/lv_hal/lv_hal_disp.h b/src/lv_hal/lv_hal_disp.h index 5c4cdd3527..ccf3c738d1 100644 --- a/src/lv_hal/lv_hal_disp.h +++ b/src/lv_hal/lv_hal_disp.h @@ -72,6 +72,12 @@ typedef struct _disp_drv_t #endif uint32_t rotated : 1; /*1: turn the display by 90 degree.*/ +#if LV_COLOR_SCREEN_TRANSP + /**Handle if the the screen doesn't have a solid (opa == LV_OPA_COVER) background. + * Use only if required because it's slower.*/ + uint32_t screen_transp : 1; +#endif + /* MANDATORY: Write the internal buffer (VDB) to the display. 'lv_disp_flush_ready()' has to be * called when finished */ void (*flush_cb)(struct _disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p); @@ -218,12 +224,16 @@ lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp); */ bool lv_disp_get_antialiasing(lv_disp_t * disp); +//! @cond Doxygen_Suppress + /** * Call in the display driver's `flush_cb` function when the flushing is finished * @param disp_drv pointer to display driver in `flush_cb` where this function is called */ LV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_drv_t * disp_drv); +//! @endcond + /** * Get the next display. * @param disp pointer to the current display. NULL to initialize. diff --git a/src/lv_hal/lv_hal_tick.h b/src/lv_hal/lv_hal_tick.h index 7d6c0523ae..a4de881f5d 100644 --- a/src/lv_hal/lv_hal_tick.h +++ b/src/lv_hal/lv_hal_tick.h @@ -36,12 +36,16 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ +//! @cond Doxygen_Suppress + /** * You have to call this function periodically * @param tick_period the call period of this function in milliseconds */ LV_ATTRIBUTE_TICK_INC void lv_tick_inc(uint32_t tick_period); +//! @endcond + /** * Get the elapsed milliseconds since start up * @return the elapsed milliseconds diff --git a/src/lv_misc/lv_color.h b/src/lv_misc/lv_color.h index 4571fc306d..e5158ed0a9 100644 --- a/src/lv_misc/lv_color.h +++ b/src/lv_misc/lv_color.h @@ -40,7 +40,6 @@ extern "C" { #define LV_COLOR_WHITE LV_COLOR_MAKE(0xFF, 0xFF, 0xFF) #define LV_COLOR_SILVER LV_COLOR_MAKE(0xC0, 0xC0, 0xC0) #define LV_COLOR_GRAY LV_COLOR_MAKE(0x80, 0x80, 0x80) -#define LV_COLOR_LIGHT_GRAY LV_COLOR_MAKE(0xC0, 0xC0, 0xC0) #define LV_COLOR_BLACK LV_COLOR_MAKE(0x00, 0x00, 0x00) #define LV_COLOR_RED LV_COLOR_MAKE(0xFF, 0x00, 0x00) #define LV_COLOR_MAROON LV_COLOR_MAKE(0x80, 0x00, 0x00) diff --git a/src/lv_misc/lv_task.h b/src/lv_misc/lv_task.h index 8869445006..f5d5ce9a24 100644 --- a/src/lv_misc/lv_task.h +++ b/src/lv_misc/lv_task.h @@ -38,7 +38,7 @@ extern "C" { struct _lv_task_t; /** - * Tasks execte this type type of functions. + * Tasks execute this type type of functions. */ typedef void (*lv_task_cb_t)(struct _lv_task_t *); @@ -80,11 +80,15 @@ typedef struct _lv_task_t */ void lv_task_core_init(void); +//! @cond Doxygen_Suppress + /** * Call it periodically to handle lv_tasks. */ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void); +//! @endcond + /** * Create an "empty" task. It needs to initialzed with at least * `lv_task_set_cb` and `lv_task_set_period` diff --git a/src/lv_objx/lv_page.c b/src/lv_objx/lv_page.c index 23380aa2ca..dbd711ff91 100644 --- a/src/lv_objx/lv_page.c +++ b/src/lv_objx/lv_page.c @@ -423,13 +423,13 @@ bool lv_page_on_edge(lv_obj_t * page, lv_page_edge_t edge) lv_obj_get_coords(scrl, &scrl_coords); lv_obj_get_coords(page, &page_coords); - if(edge == LV_PAGE_EDGE_TOP && scrl_coords.y1 == page_coords.y1 + page_style->body.padding.top) + if((edge & LV_PAGE_EDGE_TOP) && scrl_coords.y1 == page_coords.y1 + page_style->body.padding.top) return true; - else if(edge == LV_PAGE_EDGE_BOTTOM && scrl_coords.y2 == page_coords.y2 - page_style->body.padding.bottom) + if((edge & LV_PAGE_EDGE_BOTTOM) && scrl_coords.y2 == page_coords.y2 - page_style->body.padding.bottom) return true; - else if(edge == LV_PAGE_EDGE_LEFT && scrl_coords.x1 == page_coords.x1 + page_style->body.padding.left) + if((edge & LV_PAGE_EDGE_LEFT) && scrl_coords.x1 == page_coords.x1 + page_style->body.padding.left) return true; - else if(edge == LV_PAGE_EDGE_RIGHT && scrl_coords.x2 == page_coords.x2 - page_style->body.padding.right) + if((edge & LV_PAGE_EDGE_RIGHT) && scrl_coords.x2 == page_coords.x2 - page_style->body.padding.right) return true; return false; @@ -940,6 +940,7 @@ static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, voi if(lv_obj_get_parent(page_parent) != NULL) { /*Do not propagate the scroll to a screen*/ page_ext->scroll_prop_ip = 1; + } } } diff --git a/src/lv_objx/lv_page.h b/src/lv_objx/lv_page.h index 686c4a8313..59b62d5ecc 100644 --- a/src/lv_objx/lv_page.h +++ b/src/lv_objx/lv_page.h @@ -51,10 +51,10 @@ typedef uint8_t lv_sb_mode_t; /*Edges: describes the four edges of the page*/ enum { - LV_PAGE_EDGE_LEFT = 0x0, - LV_PAGE_EDGE_TOP = 0x1, - LV_PAGE_EDGE_RIGHT = 0x2, - LV_PAGE_EDGE_BOTTOM = 0x3 + LV_PAGE_EDGE_LEFT = 0x1, + LV_PAGE_EDGE_TOP = 0x2, + LV_PAGE_EDGE_RIGHT = 0x4, + LV_PAGE_EDGE_BOTTOM = 0x8 }; typedef uint8_t lv_page_edge_t; diff --git a/src/lv_objx/lv_roller.c b/src/lv_objx/lv_roller.c index b184bfb3c1..6a11cfc0f3 100644 --- a/src/lv_objx/lv_roller.c +++ b/src/lv_objx/lv_roller.c @@ -107,7 +107,7 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy) /*Copy an existing roller*/ else { lv_roller_ext_t * copy_ext = lv_obj_get_ext_attr(copy); - ext->inf = copy_ext->inf; + ext->mode = copy_ext->mode; lv_obj_t * scrl = lv_page_get_scrl(new_roller); lv_ddlist_open(new_roller, false); @@ -130,13 +130,14 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy) * Set the options on a roller * @param roller pointer to roller object * @param options a string with '\n' separated options. E.g. "One\nTwo\nThree" + * @param mode `LV_ROLLER_MODE_NORMAL` or `LV_ROLLER_MODE_INFINITE` */ -void lv_roller_set_options(lv_obj_t * roller, const char * options, bool inf) +void lv_roller_set_options(lv_obj_t * roller, const char * options, lv_roller_mode_t mode) { lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller); - if(inf == false) { - ext->inf = 0; + if(mode == LV_ROLLER_MODE_NORMAL) { + ext->mode = LV_ROLLER_MODE_NORMAL; lv_ddlist_set_options(roller, options); /* Make sure the roller's height and the scrollable's height is refreshed. @@ -144,7 +145,7 @@ void lv_roller_set_options(lv_obj_t * roller, const char * options, bool inf) * that signal won't be called. (It called because LV_FIT_TIGHT hor fit)*/ refr_height(roller); } else { - ext->inf = 1; + ext->mode = LV_ROLLER_MODE_INIFINITE; uint32_t opt_len = strlen(options) + 1; /*+1 to add '\n' after option lists*/ char * opt_extra = lv_mem_alloc(opt_len * LV_ROLLER_INF_PAGES); @@ -238,7 +239,7 @@ void lv_roller_set_style(lv_obj_t * roller, lv_roller_style_t type, const lv_sty uint16_t lv_roller_get_selected(const lv_obj_t * roller) { lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller); - if(ext->inf) { + if(ext->mode == LV_ROLLER_MODE_INIFINITE) { uint16_t real_id_cnt = ext->ddlist.option_cnt / LV_ROLLER_INF_PAGES; return lv_ddlist_get_selected(roller) % real_id_cnt; } else { @@ -675,7 +676,7 @@ static void inf_normalize(void * scrl) lv_obj_t * roller = lv_obj_get_parent(roller_scrl); lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller); - if(ext->inf) { + if(ext->mode == LV_ROLLER_MODE_INIFINITE) { uint16_t real_id_cnt = ext->ddlist.option_cnt / LV_ROLLER_INF_PAGES; ext->ddlist.sel_opt_id = ext->ddlist.sel_opt_id % real_id_cnt; diff --git a/src/lv_objx/lv_roller.h b/src/lv_objx/lv_roller.h index ffc8b5163e..677a7dd153 100644 --- a/src/lv_objx/lv_roller.h +++ b/src/lv_objx/lv_roller.h @@ -37,12 +37,23 @@ extern "C" { /********************** * TYPEDEFS **********************/ + + +enum { + LV_ROLLER_MODE_NORMAL, + LV_ROLLER_MODE_INIFINITE, +}; + +typedef uint8_t lv_roller_mode_t; + + + /*Data of roller*/ typedef struct { lv_ddlist_ext_t ddlist; /*Ext. of ancestor*/ /*New data for this type */ - uint8_t inf : 1; /*Infinite*/ + lv_roller_mode_t mode : 1; } lv_roller_ext_t; enum { @@ -71,9 +82,9 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy); * Set the options on a roller * @param roller pointer to roller object * @param options a string with '\n' separated options. E.g. "One\nTwo\nThree" - * @param inf True: Loop through the options + * @param mode `LV_ROLLER_MODE_NORMAL` or `LV_ROLLER_MODE_INFINITE` */ -void lv_roller_set_options(lv_obj_t * roller, const char * options, bool inf); +void lv_roller_set_options(lv_obj_t * roller, const char * options, lv_roller_mode_t mode); /** * Set the align of the roller's options (left, right or center[default]) diff --git a/src/lv_objx/lv_spinbox.c b/src/lv_objx/lv_spinbox.c index 562b753952..8571f79be5 100644 --- a/src/lv_objx/lv_spinbox.c +++ b/src/lv_objx/lv_spinbox.c @@ -72,8 +72,9 @@ lv_obj_t * lv_spinbox_create(lv_obj_t * par, const lv_obj_t * copy) ext->range_max = 99999; ext->range_min = -99999; - lv_ta_set_cursor_type(new_spinbox, LV_CURSOR_BLOCK | LV_CURSOR_HIDDEN); /*hidden by default*/ + lv_ta_set_cursor_type(new_spinbox, LV_CURSOR_BLOCK); lv_ta_set_one_line(new_spinbox, true); + lv_ta_set_cursor_click_pos(new_spinbox, false); /*The signal and design functions are not copied so set them here*/ lv_obj_set_signal_cb(new_spinbox, lv_spinbox_signal); @@ -243,7 +244,7 @@ void lv_spinbox_step_next(lv_obj_t * spinbox) * Select next higher digit for edition * @param spinbox pointer to spinbox */ -void lv_spinbox_step_previous(lv_obj_t * spinbox) +void lv_spinbox_step_prev(lv_obj_t * spinbox) { lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox); int32_t step_limit; @@ -342,7 +343,7 @@ static lv_res_t lv_spinbox_signal(lv_obj_t * spinbox, lv_signal_t sign, void * p if(new_step >= ext->range_max) break; ext->step = new_step; } - lv_spinbox_step_previous(spinbox); + lv_spinbox_step_prev(spinbox); } } } @@ -359,7 +360,7 @@ static lv_res_t lv_spinbox_signal(lv_obj_t * spinbox, lv_signal_t sign, void * p if(indev_type == LV_INDEV_TYPE_ENCODER) lv_spinbox_decrement(spinbox); else - lv_spinbox_step_previous(spinbox); + lv_spinbox_step_prev(spinbox); } else if(c == LV_KEY_UP) { lv_spinbox_increment(spinbox); } else if(c == LV_KEY_DOWN) { diff --git a/src/lv_objx/lv_spinbox.h b/src/lv_objx/lv_spinbox.h index b5fcee0425..ea60169e3c 100644 --- a/src/lv_objx/lv_spinbox.h +++ b/src/lv_objx/lv_spinbox.h @@ -161,7 +161,7 @@ void lv_spinbox_step_next(lv_obj_t * spinbox); * Select next higher digit for edition by multiplying the step by 10 * @param spinbox pointer to spinbox */ -void lv_spinbox_step_previous(lv_obj_t * spinbox); +void lv_spinbox_step_prev(lv_obj_t * spinbox); /** * Increment spinbox value by one step diff --git a/src/lv_objx/lv_tileview.c b/src/lv_objx/lv_tileview.c index 01e9571eb8..5b01d215e4 100644 --- a/src/lv_objx/lv_tileview.c +++ b/src/lv_objx/lv_tileview.c @@ -91,7 +91,12 @@ lv_obj_t * lv_tileview_create(lv_obj_t * par, const lv_obj_t * copy) /*Init the new tileview*/ if(copy == NULL) { - lv_obj_set_size(new_tileview, LV_DPI * 3, LV_DPI * 3); + /* Set a size which fits into the parent. + * Don't use `par` directly because if the tileview is created on a page it is moved to the + * scrollable so the parent has changed */ + lv_obj_set_size(new_tileview, lv_obj_get_width_fit(lv_obj_get_parent(new_tileview)), + lv_obj_get_height_fit(lv_obj_get_parent(new_tileview))); + lv_obj_set_drag_throw(lv_page_get_scrl(new_tileview), false); lv_page_set_scrl_fit(new_tileview, LV_FIT_TIGHT); lv_obj_set_event_cb(ext->page.scrl, tileview_scrl_event_cb);