mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
minor API updates
This commit is contained in:
parent
bba22bfa55
commit
4891f803fc
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**********************
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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*/
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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`.
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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`
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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])
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user