Update LittleVGL from 6.1.1 to 6.1.2. It fixes a memory leak when a screen used 2 lv_img objects (occured in Clock).

This commit is contained in:
JF 2020-05-17 09:27:36 +02:00
parent d58f57b1b5
commit 9753967d8a
40 changed files with 379 additions and 167 deletions

View File

@ -1,6 +1,6 @@
{
"name": "lvgl",
"version": "6.1.1",
"version": "v6.1.2",
"keywords": "graphics, gui, embedded, littlevgl",
"description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.",
"repository":

View File

@ -9,7 +9,7 @@
/*********************
* INCLUDES
*********************/
#include "lv_port_disp_templ.h"
#include "lv_port_disp_template.h"
/*********************
* DEFINES
@ -26,8 +26,9 @@ static void disp_init(void);
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
#if LV_USE_GPU
static void gpu_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa);
static void gpu_fill(lv_color_t * dest, uint32_t length, lv_color_t color);
static void gpu_blend(lv_disp_drv_t * disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa);
static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
const lv_area_t * fill_area, lv_color_t color);
#endif
/**********************
@ -112,10 +113,10 @@ void lv_port_disp_init(void)
/*Optionally add functions to access the GPU. (Only in buffered mode, LV_VDB_SIZE != 0)*/
/*Blend two color array using opacity*/
disp_drv.gpu_blend = gpu_blend;
disp_drv.gpu_blend_cb = gpu_blend;
/*Fill a memory array with a color*/
disp_drv.gpu_fill = gpu_fill;
disp_drv.gpu_fill_cb = gpu_fill;
#endif
/*Finally register the driver*/
@ -151,7 +152,7 @@ static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_colo
/* IMPORTANT!!!
* Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(disp);
lv_disp_flush_ready(disp_drv);
}
@ -171,11 +172,11 @@ static void gpu_blend(lv_disp_drv_t * disp_drv, lv_color_t * dest, const lv_colo
/* If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color
* It can be used only in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/
static void gpu_fill_cb(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
const lv_area_t * fill_area, lv_color_t color);
static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
const lv_area_t * fill_area, lv_color_t color)
{
/*It's an example code which should be done by your GPU*/
uint32_t x, y;
int32_t x, y;
dest_buf += dest_width * fill_area->y1; /*Go to the first line*/
for(y = fill_area->y1; y < fill_area->y2; y++) {

View File

@ -9,7 +9,7 @@
/*********************
* INCLUDES
*********************/
#include "lv_port_fs_templ.h"
#include "lv_port_fs_template.h"
/*********************
* DEFINES
@ -85,30 +85,30 @@ void lv_port_fs_init(void)
*--------------------------------------------------*/
/* Add a simple drive to open images */
lv_fs_drv_t fs_drv; /*A driver descriptor*/
memset(&fs_drv, 0, sizeof(lv_fs_drv_t)); /*Initialization*/
lv_fs_drv_t fs_drv;
lv_fs_drv_init(&fs_drv);
/*Set up fields...*/
fs_drv.file_size = sizeof(file_t);
fs_drv.letter = 'P';
fs_drv.open = fs_open;
fs_drv.close = fs_close;
fs_drv.read = fs_read;
fs_drv.write = fs_write;
fs_drv.seek = fs_seek;
fs_drv.tell = fs_tell;
fs_drv.free = fs_free;
fs_drv.size = fs_size;
fs_drv.remove = fs_remove;
fs_drv.rename = fs_rename;
fs_drv.trunc = fs_trunc;
fs_drv.open_cb = fs_open;
fs_drv.close_cb = fs_close;
fs_drv.read_cb = fs_read;
fs_drv.write_cb = fs_write;
fs_drv.seek_cb = fs_seek;
fs_drv.tell_cb = fs_tell;
fs_drv.free_space_cb = fs_free;
fs_drv.size_cb = fs_size;
fs_drv.remove_cb = fs_remove;
fs_drv.rename_cb = fs_rename;
fs_drv.trunc_cb = fs_trunc;
fs_drv.rddir_size = sizeof(dir_t);
fs_drv.dir_close = fs_dir_close;
fs_drv.dir_open = fs_dir_open;
fs_drv.dir_read = fs_dir_read;
fs_drv.dir_close_cb = fs_dir_close;
fs_drv.dir_open_cb = fs_dir_open;
fs_drv.dir_read_cb = fs_dir_read;
lv_fs_add_drv(&fs_drv);
lv_fs_drv_register(&fs_drv);
}
/**********************
@ -315,7 +315,7 @@ static lv_fs_res_t fs_rename (lv_fs_drv_t * drv, const char * oldname, const cha
* @param free_p pointer to store the free size [kB]
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_free (uint32_t * total_p, uint32_t * free_p)
static lv_fs_res_t fs_free (lv_fs_drv_t * drv, uint32_t * total_p, uint32_t * free_p)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;

View File

@ -9,7 +9,7 @@
/*********************
* INCLUDES
*********************/
#include "lv_port_indev_templ.h"
#include "lv_port_indev_template.h"
/*********************
* DEFINES

View File

@ -724,7 +724,7 @@ CITE_BIB_FILES =
# messages are off.
# The default value is: NO.
QUIET = NO
QUIET = YES
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
@ -733,14 +733,14 @@ QUIET = NO
# Tip: Turn warnings on while writing the documentation.
# The default value is: YES.
WARNINGS = YES
WARNINGS = NO
# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
# will automatically be disabled.
# The default value is: YES.
WARN_IF_UNDOCUMENTED = YES
WARN_IF_UNDOCUMENTED = NO
# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
# potential errors in the documentation, such as not documenting some parameters
@ -748,7 +748,7 @@ WARN_IF_UNDOCUMENTED = YES
# markup commands wrongly.
# The default value is: YES.
WARN_IF_DOC_ERROR = YES
WARN_IF_DOC_ERROR = NO
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
# are documented, but have no documentation for their parameters or return

View File

@ -49,7 +49,7 @@ void lv_debug_log_error(const char * msg, uint64_t value);
{ \
if(!(expr)) { \
LV_LOG_ERROR(__func__); \
lv_debug_log_error(msg, (uint64_t)value); \
lv_debug_log_error(msg, (uint64_t)((uintptr_t)value)); \
while(1); \
} \
}

View File

@ -121,6 +121,20 @@ void lv_init(void)
LV_LOG_INFO("lv_init ready");
}
#if LV_ENABLE_GC || !LV_MEM_CUSTOM
void lv_deinit(void)
{
lv_gc_clear_roots();
#if LV_USE_LOG
lv_log_register_print_cb(NULL);
#endif
lv_disp_set_default(NULL);
lv_mem_deinit();
lv_initialized = false;
LV_LOG_INFO("lv_deinit done");
}
#endif
/*--------------------
* Create and delete
*-------------------*/
@ -507,10 +521,12 @@ void lv_obj_clean(lv_obj_t * obj)
}
/**
* Mark the object as invalid therefore its current position will be redrawn by 'lv_refr_task'
* Mark an area of an object as invalid.
* This area will be redrawn by 'lv_refr_task'
* @param obj pointer to an object
* @param area the area to redraw
*/
void lv_obj_invalidate(const lv_obj_t * obj)
void lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
@ -521,31 +537,56 @@ void lv_obj_invalidate(const lv_obj_t * obj)
lv_disp_t * disp = lv_obj_get_disp(obj_scr);
if(obj_scr == lv_disp_get_scr_act(disp) || obj_scr == lv_disp_get_layer_top(disp) ||
obj_scr == lv_disp_get_layer_sys(disp)) {
/*Truncate recursively to the parents*/
lv_area_t area_trunc;
lv_obj_t * par = lv_obj_get_parent(obj);
bool union_ok = true;
/*Start with the original coordinates*/
lv_coord_t ext_size = obj->ext_draw_pad;
lv_area_copy(&area_trunc, &obj->coords);
area_trunc.x1 -= ext_size;
area_trunc.y1 -= ext_size;
area_trunc.x2 += ext_size;
area_trunc.y2 += ext_size;
/*Check through all parents*/
/*Truncate the area to the object*/
lv_area_t obj_coords;
lv_coord_t ext_size = obj->ext_draw_pad;
lv_area_copy(&obj_coords, &obj->coords);
obj_coords.x1 -= ext_size;
obj_coords.y1 -= ext_size;
obj_coords.x2 += ext_size;
obj_coords.y2 += ext_size;
bool is_common;
lv_area_t area_trunc;
is_common = lv_area_intersect(&area_trunc, area, &obj_coords);
if(is_common == false) return; /*The area is not on the object*/
/*Truncate recursively to the parents*/
lv_obj_t * par = lv_obj_get_parent(obj);
while(par != NULL) {
union_ok = lv_area_intersect(&area_trunc, &area_trunc, &par->coords);
if(union_ok == false) break; /*If no common parts with parent break;*/
is_common = lv_area_intersect(&area_trunc, &area_trunc, &par->coords);
if(is_common == false) break; /*If no common parts with parent break;*/
if(lv_obj_get_hidden(par)) return; /*If the parent is hidden then the child is hidden and won't be drawn*/
par = lv_obj_get_parent(par);
}
if(union_ok) lv_inv_area(disp, &area_trunc);
if(is_common) lv_inv_area(disp, &area_trunc);
}
}
/**
* Mark the object as invalid therefore its current position will be redrawn by 'lv_refr_task'
* @param obj pointer to an object
*/
void lv_obj_invalidate(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
/*Truncate the area to the object*/
lv_area_t obj_coords;
lv_coord_t ext_size = obj->ext_draw_pad;
lv_area_copy(&obj_coords, &obj->coords);
obj_coords.x1 -= ext_size;
obj_coords.y1 -= ext_size;
obj_coords.x2 += ext_size;
obj_coords.y2 += ext_size;
lv_obj_invalidate_area(obj, &obj_coords);
}
/*=====================
* Setter functions
*====================*/
@ -1458,7 +1499,9 @@ lv_res_t lv_event_send(lv_obj_t * obj, lv_event_t event, const void * data)
*/
lv_res_t lv_event_send_func(lv_event_cb_t event_xcb, lv_obj_t * obj, lv_event_t event, const void * data)
{
if(obj != NULL) {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
}
/* Build a simple linked list from the objects used in the events
* It's important to know if an this object was deleted by a nested event

View File

@ -269,6 +269,15 @@ typedef struct
*/
void lv_init(void);
/**
* Deinit the 'lv' library
* Currently only implemented when not using custorm allocators, or GC is enabled.
*/
#if LV_ENABLE_GC || !LV_MEM_CUSTOM
void lv_deinit(void);
#endif
/*--------------------
* Create and delete
*-------------------*/
@ -303,6 +312,15 @@ void lv_obj_del_async(struct _lv_obj_t *obj);
*/
void lv_obj_clean(lv_obj_t * obj);
/**
* Mark an area of an object as invalid.
* This area will be redrawn by 'lv_refr_task'
* @param obj pointer to an object
* @param area the area to redraw
*/
void lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area);
/**
* Mark the object as invalid therefore its current position will be redrawn by 'lv_refr_task'
* @param obj pointer to an object

View File

@ -179,6 +179,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
char *bidi_txt = lv_draw_get_buf(line_end - line_start + 1);
lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, bidi_dir, NULL, 0);
#else
(void)bidi_dir;
const char *bidi_txt = txt + line_start;
#endif

View File

@ -85,7 +85,7 @@ lv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * st
bool match = false;
lv_img_src_t src_type = lv_img_src_get_type(cache[i].dec_dsc.src);
if(src_type == LV_IMG_SRC_VARIABLE) {
if(cache[i].dec_dsc.src == src) match = true;
if(cache[i].dec_dsc.src == src && cache[i].dec_dsc.style == style) match = true;
} else if(src_type == LV_IMG_SRC_FILE) {
if(strcmp(cache[i].dec_dsc.src, src) == 0) match = true;
}

View File

@ -509,6 +509,7 @@ void lv_img_decoder_built_in_close(lv_img_decoder_t * decoder, lv_img_decoder_ds
}
#endif
if(user_data->palette) lv_mem_free(user_data->palette);
if(user_data->opa) lv_mem_free(user_data->opa);
lv_mem_free(user_data);

View File

@ -75,7 +75,7 @@ typedef struct _lv_font_struct
/*Pointer to the font in a font pack (must have the same line height)*/
uint8_t line_height; /**< The real line height where any text fits*/
uint8_t base_line; /**< Base line measured from the top of the line_height*/
int8_t base_line; /**< Base line measured from the top of the line_height*/
uint8_t subpx :2; /**< An element of `lv_font_subpx_t`*/
void * dsc; /**< Store implementation specific or run_time data or caching here*/
#if LV_USE_USER_DATA

View File

@ -257,7 +257,7 @@ static int8_t get_kern_value(const lv_font_t * font, uint32_t gid_left, uint32_t
/*Kern classes*/
const lv_font_fmt_txt_kern_classes_t * kdsc = fdsc->kern_dsc;
uint8_t left_class = kdsc->left_class_mapping[gid_left];
uint8_t right_class = kdsc->left_class_mapping[gid_right];
uint8_t right_class = kdsc->right_class_mapping[gid_right];
/* If class = 0, kerning not exist for that glyph
* else got the value form `class_pair_values` 2D array*/
@ -475,5 +475,5 @@ static uint8_t rle_next(void)
*/
static int32_t unicode_list_compare(const void * ref, const void * element)
{
return (*(uint16_t *)ref) - (*(uint16_t *)element);
return ((int32_t)(*(uint16_t *)ref)) - ((int32_t)(*(uint16_t *)element));
}

View File

@ -12,12 +12,12 @@ extern "C" {
#endif
/* In the font converter use this list as range:
61441, 61448, 61451, 61452, 61452, 61453, 61457, 61459, 61461, 61465,
61468, 61473, 61478, 61479, 61480, 61502, 61512, 61515, 61516, 61517,
61521, 61522, 61523, 61524, 61543, 61544, 61550, 61552, 61553, 61556,
61559, 61560, 61561, 61563, 61587, 61589, 61636, 61637, 61639, 61671,
61674, 61683, 61724, 61732, 61787, 61931, 62016, 62017, 62018, 62019,
62020, 62087, 62099, 62212, 62189, 62810, 63426, 63650
61441, 61448, 61451, 61452, 61453, 61457, 61459, 61461, 61465, 61468,
61473, 61478, 61479, 61480, 61502, 61512, 61515, 61516, 61517, 61521,
61522, 61523, 61524, 61543, 61544, 61550, 61552, 61553, 61556, 61559,
61560, 61561, 61563, 61587, 61589, 61636, 61637, 61639, 61671, 61674,
61683, 61724, 61732, 61787, 61931, 62016, 62017, 62018, 62019, 62020,
62087, 62099, 62212, 62189, 62810, 63426, 63650
*/
#define LV_SYMBOL_AUDIO "\xef\x80\x81" /*61441, 0xF001*/
@ -93,7 +93,6 @@ enum {
_LV_STR_SYMBOL_CLOSE,
_LV_STR_SYMBOL_POWER,
_LV_STR_SYMBOL_SETTINGS,
_LV_STR_SYMBOL_TRASH,
_LV_STR_SYMBOL_HOME,
_LV_STR_SYMBOL_DOWNLOAD,
_LV_STR_SYMBOL_DRIVE,
@ -113,6 +112,8 @@ enum {
_LV_STR_SYMBOL_RIGHT,
_LV_STR_SYMBOL_PLUS,
_LV_STR_SYMBOL_MINUS,
_LV_STR_SYMBOL_EYE_OPEN,
_LV_STR_SYMBOL_EYE_CLOSE,
_LV_STR_SYMBOL_WARNING,
_LV_STR_SYMBOL_SHUFFLE,
_LV_STR_SYMBOL_UP,
@ -125,6 +126,7 @@ enum {
_LV_STR_SYMBOL_COPY,
_LV_STR_SYMBOL_SAVE,
_LV_STR_SYMBOL_CHARGE,
_LV_STR_SYMBOL_PASTE,
_LV_STR_SYMBOL_BELL,
_LV_STR_SYMBOL_KEYBOARD,
_LV_STR_SYMBOL_GPS,
@ -135,7 +137,12 @@ enum {
_LV_STR_SYMBOL_BATTERY_2,
_LV_STR_SYMBOL_BATTERY_1,
_LV_STR_SYMBOL_BATTERY_EMPTY,
_LV_STR_SYMBOL_USB,
_LV_STR_SYMBOL_BLUETOOTH,
_LV_STR_SYMBOL_TRASH,
_LV_STR_SYMBOL_BACKSPACE,
_LV_STR_SYMBOL_SD_CARD,
_LV_STR_SYMBOL_NEW_LINE,
_LV_STR_SYMBOL_DUMMY,
};

View File

@ -127,6 +127,7 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
memset(&disp->inv_area_joined, 0, sizeof(disp->inv_area_joined));
memset(&disp->inv_areas, 0, sizeof(disp->inv_areas));
lv_ll_init(&disp->scr_ll, sizeof(lv_obj_t));
disp->last_activity_time = 0;
if(disp_def == NULL) disp_def = disp;

View File

@ -148,9 +148,11 @@ bool lv_bidi_letter_is_neutral(uint32_t letter)
uint16_t lv_bidi_get_logical_pos(const char * str_in, char **bidi_txt, uint32_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos, bool *is_rtl)
{
uint32_t pos_conv_len = get_txt_len(str_in, len);
void *buf = lv_draw_get_buf(len + pos_conv_len * sizeof(uint16_t));
uint32_t txt_buf_size = len + 1;
txt_buf_size = (txt_buf_size + 3) & (~0x3);
void *buf = lv_draw_get_buf(txt_buf_size + pos_conv_len * sizeof(uint16_t));
if (bidi_txt) *bidi_txt = buf;
uint16_t *pos_conv_buf = (uint16_t*) ((char*)buf + len);
uint16_t *pos_conv_buf = (uint16_t*) ((char*)buf + txt_buf_size);
lv_bidi_process_paragraph(str_in, bidi_txt? *bidi_txt: NULL, len, base_dir, pos_conv_buf, pos_conv_len);
if (is_rtl) *is_rtl = IS_RTL_POS(pos_conv_buf[visual_pos]);
return GET_POS(pos_conv_buf[visual_pos]);
@ -159,9 +161,11 @@ uint16_t lv_bidi_get_logical_pos(const char * str_in, char **bidi_txt, uint32_t
uint16_t lv_bidi_get_visual_pos(const char * str_in, char **bidi_txt, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos, bool *is_rtl)
{
uint32_t pos_conv_len = get_txt_len(str_in, len);
void *buf = lv_draw_get_buf(len + pos_conv_len * sizeof(uint16_t));
uint32_t txt_buf_size = len + 1;
txt_buf_size = (txt_buf_size + 3) & (~0x3);
void *buf = lv_draw_get_buf(txt_buf_size + pos_conv_len * sizeof(uint16_t));
if (bidi_txt) *bidi_txt = buf;
uint16_t *pos_conv_buf = (uint16_t*) ((char*)buf + len);
uint16_t *pos_conv_buf = (uint16_t*) ((char*)buf + txt_buf_size);
lv_bidi_process_paragraph(str_in, bidi_txt? *bidi_txt: NULL, len, base_dir, pos_conv_buf, pos_conv_len);
for (uint16_t i = 0; i < pos_conv_len; i++){
if (GET_POS(pos_conv_buf[i]) == logical_pos){

View File

@ -104,9 +104,9 @@ enum {
# define LV_COLOR_GET_B1(c) (c).ch.blue
# define LV_COLOR_GET_A1(c) 1
# define LV_COLOR_SET_R8(c, v) (c).ch.red = (uint8_t)((v) & 0x7);
# define LV_COLOR_SET_G8(c, v) (c).ch.green = (uint8_t)((v) & 0x7);
# define LV_COLOR_SET_B8(c, v) (c).ch.blue = (uint8_t)((v) & 0x3);
# define LV_COLOR_SET_R8(c, v) (c).ch.red = (uint8_t)(v) & 0x7U;
# define LV_COLOR_SET_G8(c, v) (c).ch.green = (uint8_t)(v) & 0x7U;
# define LV_COLOR_SET_B8(c, v) (c).ch.blue = (uint8_t)(v) & 0x3U;
# define LV_COLOR_SET_A8(c, v) do {} while(0)
# define LV_COLOR_GET_R8(c) (c).ch.red
@ -114,10 +114,10 @@ enum {
# define LV_COLOR_GET_B8(c) (c).ch.blue
# define LV_COLOR_GET_A8(c) 0xFF
# define LV_COLOR_SET_R16(c, v) (c).ch.red = (uint8_t)(((uint8_t)(v)) & 0x1F);
# define LV_COLOR_SET_G16(c, v) (c).ch.green = (uint8_t)((v) & 0x3F);
# define LV_COLOR_SET_R16(c, v) (c).ch.red = (uint8_t)(v) & 0x1FU;
# define LV_COLOR_SET_G16(c, v) (c).ch.green = (uint8_t)(v) & 0x3FU;
# define LV_COLOR_SET_G16_SWAP(c, v) {(c).ch.green_h = (uint8_t)(((v) >> 3) & 0x7); (c).ch.green_l = (uint8_t)((v) & 0x7);}
# define LV_COLOR_SET_B16(c, v) (c).ch.blue = (uint8_t)((v) & 0x1F);
# define LV_COLOR_SET_B16(c, v) (c).ch.blue = (uint8_t)(v) & 0x1FU;
# define LV_COLOR_SET_A16(c, v) do {} while(0)
# define LV_COLOR_GET_R16(c) (c).ch.red
@ -344,7 +344,6 @@ static inline uint8_t lv_color_to8(lv_color_t color)
static inline uint16_t lv_color_to16(lv_color_t color)
{
#if LV_COLOR_DEPTH == 1
if(color.full == 0)
return 0;
@ -374,8 +373,6 @@ static inline uint16_t lv_color_to16(lv_color_t color)
LV_COLOR_SET_B16(ret, LV_COLOR_GET_B(color) >> 3); /* 8 - 5 = 3*/
return ret.full;
#endif
return 0;
}
static inline uint32_t lv_color_to32(lv_color_t color)
@ -464,14 +461,14 @@ static inline uint8_t lv_color_brightness(lv_color_t color)
/* The most simple macro to create a color from R,G and B values */
#if LV_COLOR_DEPTH == 1
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){.full = (b8 >> 7 | g8 >> 7 | r8 >> 7)})
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){.full = (uint8_t)((b8 >> 7) | (g8 >> 7) | (r8 >> 7))})
#elif LV_COLOR_DEPTH == 8
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 6, g8 >> 5, r8 >> 5}})
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{(uint8_t)((b8 >> 6) & 0x3U), (uint8_t)((g8 >> 5) & 0x7U), (uint8_t)((r8 >> 5) & 0x7U)}})
#elif LV_COLOR_DEPTH == 16
#if LV_COLOR_16_SWAP == 0
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 3, g8 >> 2, r8 >> 3}})
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{(uint16_t)((b8 >> 3) & 0x1FU), (uint16_t)((g8 >> 2) & 0x3FU), (uint16_t)((r8 >> 3) & 0x1FU)}})
#else
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{g8 >> 5, r8 >> 3, b8 >> 3, (g8 >> 2) & 0x7}})
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{(uint16_t)((g8 >> 5) & 0x7U), (uint16_t)((r8 >> 3) & 0x1FU), (uint16_t)((b8 >> 3) & 0x1FU), (uint16_t)((g8 >> 2) & 0x7U)}})
#endif
#elif LV_COLOR_DEPTH == 32
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8, g8, r8, 0xff}}) /*Fix 0xff alpha*/

View File

@ -8,6 +8,11 @@
*********************/
#include "lv_gc.h"
#include "string.h"
#if defined(LV_GC_INCLUDE)
#include LV_GC_INCLUDE
#endif /* LV_ENABLE_GC */
/*********************
* DEFINES
@ -35,6 +40,12 @@ LV_ROOTS
* GLOBAL FUNCTIONS
**********************/
void lv_gc_clear_roots(void)
{
#define LV_CLEAR_ROOT(root_type, root_name) memset(&LV_GC_ROOT(root_name), 0, sizeof(LV_GC_ROOT(root_name)));
LV_ITERATE_ROOTS(LV_CLEAR_ROOT)
}
/**********************
* STATIC FUNCTIONS
**********************/

View File

@ -30,21 +30,21 @@ extern "C" {
* DEFINES
*********************/
#define LV_GC_ROOTS(prefix) \
prefix lv_ll_t _lv_task_ll; /*Linked list to store the lv_tasks*/ \
prefix lv_ll_t _lv_disp_ll; /*Linked list of screens*/ \
prefix lv_ll_t _lv_indev_ll; /*Linked list of screens*/ \
prefix lv_ll_t _lv_drv_ll; \
prefix lv_ll_t _lv_file_ll; \
prefix lv_ll_t _lv_anim_ll; \
prefix lv_ll_t _lv_group_ll; \
prefix lv_ll_t _lv_img_defoder_ll; \
prefix lv_img_cache_entry_t * _lv_img_cache_array; \
prefix void * _lv_task_act; \
prefix void * _lv_draw_buf;
#define LV_ITERATE_ROOTS(f) \
f(lv_ll_t, _lv_task_ll) /*Linked list to store the lv_tasks*/ \
f(lv_ll_t, _lv_disp_ll) /*Linked list of screens*/ \
f(lv_ll_t, _lv_indev_ll) /*Linked list of screens*/ \
f(lv_ll_t, _lv_drv_ll) \
f(lv_ll_t, _lv_file_ll) \
f(lv_ll_t, _lv_anim_ll) \
f(lv_ll_t, _lv_group_ll) \
f(lv_ll_t, _lv_img_defoder_ll) \
f(lv_img_cache_entry_t*, _lv_img_cache_array) \
f(void*, _lv_task_act) \
f(void*, _lv_draw_buf)
#define LV_NO_PREFIX
#define LV_ROOTS LV_GC_ROOTS(LV_NO_PREFIX)
#define LV_DEFINE_ROOT(root_type, root_name) root_type root_name;
#define LV_ROOTS LV_ITERATE_ROOTS(LV_DEFINE_ROOT)
#if LV_ENABLE_GC == 1
#if LV_MEM_CUSTOM != 1
@ -52,7 +52,8 @@ extern "C" {
#endif /* LV_MEM_CUSTOM */
#else /* LV_ENABLE_GC */
#define LV_GC_ROOT(x) x
LV_GC_ROOTS(extern)
#define LV_EXTERN_ROOT(root_type, root_name) extern root_type root_name;
LV_ITERATE_ROOTS(LV_EXTERN_ROOT)
#endif /* LV_ENABLE_GC */
/**********************
@ -63,6 +64,8 @@ LV_GC_ROOTS(extern)
* GLOBAL PROTOTYPES
**********************/
void lv_gc_clear_roots(void);
/**********************
* MACROS
**********************/

View File

@ -22,6 +22,11 @@ extern "C" {
#define LV_MATH_MAX(a, b) ((a) > (b) ? (a) : (b))
#define LV_MATH_ABS(x) ((x) > 0 ? (x) : (-(x)))
#define LV_IS_SIGNED(t) (((t)(-1)) < ((t) 0))
#define LV_UMAX_OF(t) (((0x1ULL << ((sizeof(t) * 8ULL) - 1ULL)) - 1ULL) | (0xFULL << ((sizeof(t) * 8ULL) - 4ULL)))
#define LV_SMAX_OF(t) (((0x1ULL << ((sizeof(t) * 8ULL) - 1ULL)) - 1ULL) | (0x7ULL << ((sizeof(t) * 8ULL) - 4ULL)))
#define LV_MAX_OF(t) ((unsigned long) (LV_IS_SIGNED(t) ? LV_SMAX_OF(t) : LV_UMAX_OF(t)))
#define LV_TRIGO_SIN_MAX 32767
#define LV_TRIGO_SHIFT 15 /**< >> LV_TRIGO_SHIFT to normalize*/

View File

@ -23,7 +23,7 @@
#define LV_MEM_ADD_JUNK 0
#endif
#ifdef LV_MEM_ENV64
#ifdef LV_ARCH_64
#define MEM_UNIT uint64_t
#else
#define MEM_UNIT uint32_t
@ -102,6 +102,21 @@ void lv_mem_init(void)
#endif
}
/**
* Clean up the memory buffer which frees all the allocated memories.
* @note It work only if `LV_MEM_CUSTOM == 0`
*/
void lv_mem_deinit(void)
{
#if LV_MEM_CUSTOM == 0
memset(work_mem, 0x00, (LV_MEM_SIZE / sizeof(MEM_UNIT)) * sizeof(MEM_UNIT));
lv_mem_ent_t * full = (lv_mem_ent_t *)work_mem;
full->header.s.used = 0;
/*The total mem size id reduced by the first header and the close patterns */
full->header.s.d_size = LV_MEM_SIZE - sizeof(lv_mem_header_t);
#endif
}
/**
* Allocate a memory dynamically
* @param size size of the memory to allocate in bytes
@ -113,7 +128,7 @@ void * lv_mem_alloc(size_t size)
return &zero_mem;
}
#ifdef LV_MEM_ENV64
#ifdef LV_ARCH_64
/*Round the size up to 8*/
if(size & 0x7) {
size = size & (~0x7);
@ -262,7 +277,7 @@ void * lv_mem_realloc(void * data_p, size_t new_size)
#else /* LV_ENABLE_GC */
void * lv_mem_realloc(void * data_p, uint32_t new_size)
void * lv_mem_realloc(void * data_p, size_t new_size)
{
void * new_p = LV_MEM_CUSTOM_REALLOC(data_p, new_size);
if(new_p == NULL) LV_LOG_WARN("Couldn't allocate memory");
@ -432,7 +447,7 @@ static void * ent_alloc(lv_mem_ent_t * e, size_t size)
*/
static void ent_trunc(lv_mem_ent_t * e, size_t size)
{
#ifdef LV_MEM_ENV64
#ifdef LV_ARCH_64
/*Round the size up to 8*/
if(size & 0x7) {
size = size & (~0x7);
@ -456,11 +471,11 @@ static void ent_trunc(lv_mem_ent_t * e, size_t size)
uint8_t * e_data = &e->first_data;
lv_mem_ent_t * after_new_e = (lv_mem_ent_t *)&e_data[size];
after_new_e->header.s.used = 0;
after_new_e->header.s.d_size = e->header.s.d_size - size - sizeof(lv_mem_header_t);
after_new_e->header.s.d_size = (uint32_t)e->header.s.d_size - size - sizeof(lv_mem_header_t);
}
/* Set the new size for the original entry */
e->header.s.d_size = size;
e->header.s.d_size = (uint32_t)size;
}
#endif

View File

@ -55,6 +55,12 @@ typedef struct
*/
void lv_mem_init(void);
/**
* Clean up the memory buffer which frees all the allocated memories.
* @note It work only if `LV_MEM_CUSTOM == 0`
*/
void lv_mem_deinit(void);
/**
* Allocate a memory dynamically
* @param size size of the memory to allocate in bytes

View File

@ -8,6 +8,7 @@
*********************/
#include "lv_txt.h"
#include "lv_math.h"
#include "lv_log.h"
/*********************
* DEFINES
@ -108,8 +109,14 @@ void lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t *
/*Calc. the height and longest line*/
while(text[line_start] != '\0') {
new_line_start += lv_txt_get_next_line(&text[line_start], font, letter_space, max_width, flag);
if ((unsigned long)size_res->y + (unsigned long)letter_height + (unsigned long)line_space > LV_MAX_OF(lv_coord_t)) {
LV_LOG_WARN("lv_txt_get_size: integer overflow while calculating text height");
return;
} else {
size_res->y += letter_height;
size_res->y += line_space;
}
/*Calculate the the longest line*/
act_line_length = lv_txt_get_width(&text[line_start], new_line_start - line_start, font, letter_space, flag);
@ -118,7 +125,7 @@ void lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t *
line_start = new_line_start;
}
/*Ma ke the text one line taller if the last character is '\n' or '\r'*/
/*Make the text one line taller if the last character is '\n' or '\r'*/
if((line_start != 0) && (text[line_start - 1] == '\n' || text[line_start - 1] == '\r')) {
size_res->y += letter_height + line_space;
}
@ -200,8 +207,12 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font,
letter_w = lv_font_get_glyph_width(font, letter, letter_next);
cur_w += letter_w;
if(letter_w > 0) {
cur_w += letter_space;
}
/* Test if this character fits within max_width */
if(break_index == NO_BREAK_FOUND && cur_w > max_width) {
if(break_index == NO_BREAK_FOUND && (cur_w - letter_space) > max_width) {
break_index = i;
break_letter_count = word_len - 1;
/* break_index is now pointing at the character that doesn't fit */
@ -219,9 +230,6 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font,
/* Update the output width */
if( word_w_ptr != NULL && break_index == NO_BREAK_FOUND ) *word_w_ptr = cur_w;
if(letter_w > 0) {
cur_w += letter_space;
}
i = i_next;
i_next = i_next_next;

View File

@ -18,7 +18,7 @@ extern "C" {
* DEFINES
*********************/
// Check windows
#ifdef __WIN64
#ifdef _WIN64
#define LV_ARCH_64
#endif

View File

@ -815,7 +815,8 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
} else if(sign == LV_SIGNAL_RELEASED) {
if(ext->btn_id_pr != LV_BTNM_BTN_NONE) {
/*Toggle the button if enabled*/
if(button_is_tgl_enabled(ext->ctrl_bits[ext->btn_id_pr])) {
if(button_is_tgl_enabled(ext->ctrl_bits[ext->btn_id_pr]) &&
!button_is_inactive(ext->ctrl_bits[ext->btn_id_pr])) {
if(button_get_tgl_state(ext->ctrl_bits[ext->btn_id_pr])) {
ext->ctrl_bits[ext->btn_id_pr] &= (~LV_BTNM_CTRL_TGL_STATE);
} else {
@ -863,8 +864,9 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
lv_indev_type_t indev_type = lv_indev_get_type(indev);
/*If not focused by an input device assume the last input device*/
if(indev_type == LV_INDEV_TYPE_NONE) {
indev_type = lv_indev_get_type(lv_indev_get_next(NULL));
if(indev == NULL) {
indev = lv_indev_get_next(NULL);
indev_type = lv_indev_get_type(indev);
}
if(indev_type == LV_INDEV_TYPE_POINTER) {
@ -1082,7 +1084,7 @@ static void invalidate_button_area(const lv_obj_t * btnm, uint16_t btn_idx)
btn_area.x2 += btnm_area.x1;
btn_area.y2 += btnm_area.y1;
lv_inv_area(lv_obj_get_disp(btnm), &btn_area);
lv_obj_invalidate_area(btnm, &btn_area);
}
/**

View File

@ -816,7 +816,7 @@ static void lv_chart_draw_div(lv_obj_t * chart, const lv_area_t * mask)
}
p1.x = 0 + x_ofs;
p2.x = w + x_ofs;
p2.x = w - 1 + x_ofs;
for(div_i = div_i_start; div_i <= div_i_end; div_i++) {
p1.y = (int32_t)((int32_t)(h - style->line.width) * div_i) / (ext->hdiv_cnt + 1);
p1.y += y_ofs;
@ -836,7 +836,7 @@ static void lv_chart_draw_div(lv_obj_t * chart, const lv_area_t * mask)
}
p1.y = 0 + y_ofs;
p2.y = h + y_ofs;
p2.y = h + y_ofs - 1;
for(div_i = div_i_start; div_i <= div_i_end; div_i++) {
p1.x = (int32_t)((int32_t)(w - style->line.width) * div_i) / (ext->vdiv_cnt + 1);
p1.x += x_ofs;
@ -951,7 +951,7 @@ static void lv_chart_draw_points(lv_obj_t * chart, const lv_area_t * mask)
y_tmp = (int32_t)((int32_t)ser->points[p_act] - ext->ymin) * h;
y_tmp = y_tmp / (ext->ymax - ext->ymin);
cir_a.y1 = h - y_tmp + y_ofs;
cir_a.y1 = h - y_tmp + y_ofs - 1;
cir_a.y2 = cir_a.y1 + style_point.body.radius;
cir_a.y1 -= style_point.body.radius;
@ -1496,13 +1496,13 @@ static void lv_chart_inv_lines(lv_obj_t * chart, uint16_t i)
if(i < ext->point_cnt - 1) {
coords.x1 = ((w * i) / (ext->point_cnt - 1)) + x_ofs - ext->series.width;
coords.x2 = ((w * (i + 1)) / (ext->point_cnt - 1)) + x_ofs + ext->series.width;
lv_inv_area(lv_obj_get_disp(chart), &coords);
lv_obj_invalidate_area(chart, &coords);
}
if(i > 0) {
coords.x1 = ((w * (i - 1)) / (ext->point_cnt - 1)) + x_ofs - ext->series.width;
coords.x2 = ((w * i) / (ext->point_cnt - 1)) + x_ofs + ext->series.width;
lv_inv_area(lv_obj_get_disp(chart), &coords);
lv_obj_invalidate_area(chart, &coords);
}
}
}

View File

@ -750,7 +750,7 @@ static void invalidate_indic(lv_obj_t * cpicker)
{
lv_area_t indic_area = get_indic_area(cpicker);
lv_inv_area(lv_obj_get_disp(cpicker), &indic_area);
lv_obj_invalidate_area(cpicker, &indic_area);
}
static lv_area_t get_indic_area(lv_obj_t * cpicker)

View File

@ -775,6 +775,7 @@ static lv_res_t lv_ddlist_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void *
/* Include the ancient signal function */
res = ancestor_scrl_signal(scrl, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, "");
lv_obj_t * ddlist = lv_obj_get_parent(scrl);
@ -806,6 +807,10 @@ static lv_res_t release_handler(lv_obj_t * ddlist)
{
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
/*Only deal with clickable drop down lists*/
if(!lv_obj_get_click(ddlist))
return LV_RES_OK;
if(ext->opened == 0) { /*Open the list*/
ext->opened = 1;
lv_obj_set_drag(lv_page_get_scrl(ddlist), true);

View File

@ -193,7 +193,7 @@ uint8_t lv_gauge_get_label_count(const lv_obj_t * gauge);
* @param gauge pointer to a gauge object
* @return number of the scale units
*/
static inline uint8_t lv_gauge_get_line_count(const lv_obj_t * gauge)
static inline uint16_t lv_gauge_get_line_count(const lv_obj_t * gauge)
{
return lv_lmeter_get_line_count(gauge);
}

View File

@ -355,6 +355,9 @@ static bool lv_img_design(lv_obj_t * img, const lv_area_t * mask, lv_design_mode
if(ext->cf == LV_IMG_CF_TRUE_COLOR || ext->cf == LV_IMG_CF_RAW) cover = lv_area_is_in(mask, &img->coords);
const lv_style_t * style = lv_img_get_style(img, LV_IMG_STYLE_MAIN);
if(style->image.opa < LV_OPA_MAX) return false;
return cover;
} else if(mode == LV_DESIGN_DRAW_MAIN) {
if(ext->h == 0 || ext->w == 0) return true;

View File

@ -308,7 +308,6 @@ void lv_label_set_array_text(lv_obj_t * label, const char * array, uint16_t size
void lv_label_set_static_text(lv_obj_t * label, const char * text)
{
LV_ASSERT_OBJ(label, LV_OBJX_NAME);
LV_ASSERT_STR(text);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
if(ext->static_txt == 0 && ext->text != NULL) {
@ -1303,10 +1302,18 @@ static void lv_label_refr_text(lv_obj_t * label)
p.y -= style->text.line_space; /*Trim the last line space*/
uint32_t letter_id = lv_label_get_letter_on(label, &p);
/*Save letters under the dots and replace them with dots*/
uint32_t i;
/*Be sure there is space for the dots*/
size_t txt_len = strlen(ext->text);
uint32_t byte_id = lv_txt_encoded_get_byte_id(ext->text, letter_id);
while(byte_id + LV_LABEL_DOT_NUM > txt_len) {
byte_id -= lv_txt_encoded_size(&ext->text[byte_id]);
letter_id--;
}
/*Save letters under the dots and replace them with dots*/
uint32_t byte_id_ori = byte_id;
uint32_t i;
uint8_t len = 0;
for(i = 0; i <= LV_LABEL_DOT_NUM; i++) {
len += lv_txt_encoded_size(&ext->text[byte_id]);

View File

@ -179,6 +179,13 @@ lv_obj_t * lv_list_add_btn(lv_obj_t * list, const void * img_src, const char * t
{
LV_ASSERT_OBJ(list, LV_OBJX_NAME);
lv_obj_t * last_btn = lv_list_get_prev_btn(list, NULL);
/*The coordinates may changed due to autofit so revert them at the end*/
lv_coord_t pos_x_ori = lv_obj_get_x(list);
lv_coord_t pos_y_ori = lv_obj_get_y(list);
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
ext->size++;
/*Create a list element with the image an the text*/
@ -197,7 +204,22 @@ lv_obj_t * lv_list_add_btn(lv_obj_t * list, const void * img_src, const char * t
lv_page_glue_obj(liste, true);
lv_btn_set_layout(liste, LV_LAYOUT_ROW_M);
lv_layout_t list_layout = lv_list_get_layout(list);
bool layout_ver = false;
if(list_layout == LV_LAYOUT_COL_M || list_layout == LV_LAYOUT_COL_L || list_layout == LV_LAYOUT_COL_R) {
layout_ver = true;
}
if(layout_ver) {
lv_btn_set_fit2(liste, LV_FIT_FLOOD, LV_FIT_TIGHT);
} else {
lv_coord_t w = last_btn ? lv_obj_get_width(last_btn) : (LV_DPI * 3) / 2;
lv_btn_set_fit2(liste, LV_FIT_NONE, LV_FIT_TIGHT);
lv_obj_set_width(liste, w);
}
lv_obj_set_protect(liste, LV_PROTECT_PRESS_LOST);
lv_obj_set_signal_cb(liste, lv_list_btn_signal);
@ -233,6 +255,8 @@ lv_obj_t * lv_list_add_btn(lv_obj_t * list, const void * img_src, const char * t
}
#endif
lv_obj_set_pos(list, pos_x_ori, pos_y_ori);
return liste;
}
@ -399,16 +423,23 @@ void lv_list_set_style(lv_obj_t * list, lv_list_style_t type, const lv_style_t *
while(btn != NULL) {
/*If a column layout set the buttons' width to list width*/
if(layout == LV_LAYOUT_COL_M || layout == LV_LAYOUT_COL_L || layout == LV_LAYOUT_COL_R) {
lv_btn_set_fit2(list, LV_FIT_FLOOD, LV_FIT_TIGHT);
lv_btn_set_fit2(btn, LV_FIT_FLOOD, LV_FIT_TIGHT);
}
/*If a row layout set the buttons' width according to the content*/
else if (layout == LV_LAYOUT_ROW_M || layout == LV_LAYOUT_ROW_T || layout == LV_LAYOUT_ROW_B) {
lv_btn_set_fit(list, LV_FIT_TIGHT);
lv_btn_set_fit(btn, LV_FIT_TIGHT);
}
btn = lv_list_get_prev_btn(list, btn);
}
if(layout == LV_LAYOUT_COL_M || layout == LV_LAYOUT_COL_L || layout == LV_LAYOUT_COL_R) {
lv_page_set_scrl_fit2(list, LV_FIT_FLOOD, LV_FIT_TIGHT);
} else if (layout == LV_LAYOUT_ROW_M || layout == LV_LAYOUT_ROW_T || layout == LV_LAYOUT_ROW_B) {
lv_page_set_scrl_fit2(list, LV_FIT_TIGHT, LV_FIT_TIGHT);
lv_cont_set_fit2(list, LV_FIT_NONE, LV_FIT_TIGHT);
}
lv_page_set_scrl_layout(list, layout);
}

View File

@ -150,16 +150,16 @@ lv_obj_t * lv_page_create(lv_obj_t * par, const lv_obj_t * copy)
ext->scrl = lv_cont_create(new_page, copy_ext->scrl);
lv_obj_set_signal_cb(ext->scrl, lv_page_scrollable_signal);
lv_page_set_sb_mode(new_page, copy_ext->sb.mode);
/* Add the signal function only if 'scrolling' is created
* because everything has to be ready before any signal is received*/
lv_obj_set_signal_cb(new_page, lv_page_signal);
lv_obj_set_design_cb(new_page, lv_page_design);
lv_page_set_style(new_page, LV_PAGE_STYLE_BG, lv_page_get_style(copy, LV_PAGE_STYLE_BG));
lv_page_set_style(new_page, LV_PAGE_STYLE_SCRL, lv_page_get_style(copy, LV_PAGE_STYLE_SCRL));
lv_page_set_style(new_page, LV_PAGE_STYLE_SB, lv_page_get_style(copy, LV_PAGE_STYLE_SB));
/* Add the signal function only if 'scrolling' is created
* because everything has to be ready before any signal is received*/
lv_obj_set_signal_cb(new_page, lv_page_signal);
lv_obj_set_design_cb(new_page, lv_page_design);
lv_page_set_sb_mode(new_page, copy_ext->sb.mode);
/*Refresh the style with new signal function*/
lv_obj_refresh_style(new_page);
@ -828,6 +828,7 @@ static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param)
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
lv_obj_t * child;
if(sign == LV_SIGNAL_CHILD_CHG) { /*Automatically move children to the scrollable object*/
if(ext->scrl == NULL) return LV_RES_OK;
const lv_style_t * style_bg = lv_page_get_style(page, LV_PAGE_STYLE_BG);
const lv_style_t * style_scrl = lv_page_get_style(page, LV_PAGE_STYLE_SCRL);
lv_fit_t fit_left = lv_page_get_scrl_fit_left(page);
@ -1073,7 +1074,6 @@ static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, voi
/*Hide scrollbars if required*/
if(page_ext->sb.mode == LV_SB_MODE_DRAG) {
lv_disp_t * disp = lv_obj_get_disp(page);
lv_area_t sb_area_tmp;
if(page_ext->sb.hor_draw) {
lv_area_copy(&sb_area_tmp, &page_ext->sb.hor_area);
@ -1081,7 +1081,7 @@ static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, voi
sb_area_tmp.y1 += page->coords.y1;
sb_area_tmp.x2 += page->coords.x1;
sb_area_tmp.y2 += page->coords.y1;
lv_inv_area(disp, &sb_area_tmp);
lv_obj_invalidate_area(page, &sb_area_tmp);
page_ext->sb.hor_draw = 0;
}
if(page_ext->sb.ver_draw) {
@ -1090,10 +1090,12 @@ static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, voi
sb_area_tmp.y1 += page->coords.y1;
sb_area_tmp.x2 += page->coords.x1;
sb_area_tmp.y2 += page->coords.y1;
lv_inv_area(disp, &sb_area_tmp);
lv_obj_invalidate_area(page, &sb_area_tmp);
page_ext->sb.ver_draw = 0;
}
}
} else if(sign == LV_SIGNAL_CLEANUP) {
page_ext->scrl = NULL;
}
return res;
@ -1150,7 +1152,6 @@ static void lv_page_sb_refresh(lv_obj_t * page)
}
/*Invalidate the current (old) scrollbar areas*/
lv_disp_t * disp = lv_obj_get_disp(page);
lv_area_t sb_area_tmp;
if(ext->sb.hor_draw != 0) {
lv_area_copy(&sb_area_tmp, &ext->sb.hor_area);
@ -1158,7 +1159,7 @@ static void lv_page_sb_refresh(lv_obj_t * page)
sb_area_tmp.y1 += page->coords.y1;
sb_area_tmp.x2 += page->coords.x1;
sb_area_tmp.y2 += page->coords.y1;
lv_inv_area(disp, &sb_area_tmp);
lv_obj_invalidate_area(page, &sb_area_tmp);
}
if(ext->sb.ver_draw != 0) {
lv_area_copy(&sb_area_tmp, &ext->sb.ver_area);
@ -1166,7 +1167,7 @@ static void lv_page_sb_refresh(lv_obj_t * page)
sb_area_tmp.y1 += page->coords.y1;
sb_area_tmp.x2 += page->coords.x1;
sb_area_tmp.y2 += page->coords.y1;
lv_inv_area(disp, &sb_area_tmp);
lv_obj_invalidate_area(page, &sb_area_tmp);
}
if(ext->sb.mode == LV_SB_MODE_DRAG && lv_indev_is_dragging(lv_indev_get_act()) == false) {
@ -1228,7 +1229,7 @@ static void lv_page_sb_refresh(lv_obj_t * page)
sb_area_tmp.y1 += page->coords.y1;
sb_area_tmp.x2 += page->coords.x1;
sb_area_tmp.y2 += page->coords.y1;
lv_inv_area(disp, &sb_area_tmp);
lv_obj_invalidate_area(page, &sb_area_tmp);
}
if(ext->sb.ver_draw != 0) {
lv_area_copy(&sb_area_tmp, &ext->sb.ver_area);
@ -1236,7 +1237,7 @@ static void lv_page_sb_refresh(lv_obj_t * page)
sb_area_tmp.y1 += page->coords.y1;
sb_area_tmp.x2 += page->coords.x1;
sb_area_tmp.y2 += page->coords.y1;
lv_inv_area(disp, &sb_area_tmp);
lv_obj_invalidate_area(page, &sb_area_tmp);
}
}

View File

@ -149,8 +149,9 @@ void lv_roller_set_options(lv_obj_t * roller, const char * options, lv_roller_mo
/* Make sure the roller's height and the scrollable's height is refreshed.
* They are refreshed in `LV_SIGNAL_COORD_CHG` but if the new options has the same width
* that signal won't be called. (It called because LV_FIT_TIGHT hor fit)*/
* that signal won't be called. (It's called because of LV_FIT_TIGHT hor fit)*/
refr_height(roller);
refr_position(roller, LV_ANIM_OFF);
} else {
ext->mode = LV_ROLLER_MODE_INIFINITE;
@ -508,6 +509,7 @@ static lv_res_t lv_roller_scrl_signal(lv_obj_t * roller_scrl, lv_signal_t sign,
/* Include the ancient signal function */
res = ancestor_scrl_signal(roller_scrl, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_indev_t * indev = lv_indev_get_act();
int32_t id = -1;

View File

@ -405,11 +405,15 @@ static void lv_spinbox_updatevalue(lv_obj_t * spinbox)
char buf[LV_SPINBOX_MAX_DIGIT_COUNT + 8];
memset(buf, 0, sizeof(buf));
char * buf_p = buf;
uint8_t cur_shift_left = 0;
if (ext->range_min < 0) { // hide sign if there are only positive values
/*Add the sign*/
(*buf_p) = ext->value >= 0 ? '+' : '-';
buf_p++;
} else {
/*Cursor need shift to left*/
cur_shift_left++;
}
int32_t i;
@ -467,7 +471,7 @@ static void lv_spinbox_updatevalue(lv_obj_t * spinbox)
if(cur_pos > intDigits) cur_pos++; /*Skip teh decimal point*/
cur_pos += ext->digit_padding_left;
cur_pos += (ext->digit_padding_left - cur_shift_left);
lv_ta_set_cursor_pos(spinbox, cur_pos);
}

View File

@ -275,6 +275,13 @@ uint16_t lv_sw_get_anim_time(const lv_obj_t * sw)
*/
static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param)
{
lv_res_t res;
if(sign == LV_SIGNAL_GET_TYPE) {
res = ancestor_signal(sw, sign, param);
if(res != LV_RES_OK) return res;
return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
}
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
/*Save the current (old) value before slider signal modifies it. It will be required in the
@ -289,12 +296,9 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param)
lv_event_cb_t event_cb = sw->event_cb;
sw->event_cb = NULL;
lv_res_t res;
/* Include the ancient signal function */
res = ancestor_signal(sw, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
sw->event_cb = event_cb;

View File

@ -484,7 +484,9 @@ void lv_ta_set_text(lv_obj_t * ta, const char * txt)
if(lv_ta_get_accepted_chars(ta) || lv_ta_get_max_length(ta)) {
lv_label_set_text(ext->label, "");
lv_ta_set_cursor_pos(ta, LV_TA_CURSOR_LAST);
if(ext->pwd_mode != 0) {
ext->pwd_tmp[0] = '\0'; /*Clear the password too*/
}
uint32_t i = 0;
while(txt[i] != '\0') {
uint32_t c = lv_txt_encoded_next(txt, &i);
@ -731,6 +733,7 @@ void lv_ta_set_one_line(lv_obj_t * ta, bool en)
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
if(ext->one_line == en) return;
lv_label_align_t old_align = lv_label_get_align(ext->label);
if(en) {
const lv_style_t * style_ta = lv_obj_get_style(ta);
@ -758,7 +761,8 @@ void lv_ta_set_one_line(lv_obj_t * ta, bool en)
}
placeholder_update(ta);
refr_cursor_area(ta);
/* `refr_cursor_area` is called at the end of lv_ta_set_text_align */
lv_ta_set_text_align(ta, old_align);
}
/**
@ -943,6 +947,7 @@ void lv_ta_set_cursor_blink_time(lv_obj_t * ta, uint16_t time)
a.path_cb = lv_anim_path_step;
lv_anim_create(&a);
} else {
lv_anim_del(ta, (lv_anim_exec_xcb_t)cursor_blink_anim);
ext->cursor.state = 1;
}
#else
@ -1589,14 +1594,13 @@ static void cursor_blink_anim(lv_obj_t * ta, lv_anim_value_t show)
if(show != ext->cursor.state) {
ext->cursor.state = show == 0 ? 0 : 1;
if(ext->cursor.type != LV_CURSOR_NONE && (ext->cursor.type & LV_CURSOR_HIDDEN) == 0) {
lv_disp_t * disp = lv_obj_get_disp(ta);
lv_area_t area_tmp;
lv_area_copy(&area_tmp, &ext->cursor.area);
area_tmp.x1 += ext->label->coords.x1;
area_tmp.y1 += ext->label->coords.y1;
area_tmp.x2 += ext->label->coords.x1;
area_tmp.y2 += ext->label->coords.y1;
lv_inv_area(disp, &area_tmp);
lv_obj_invalidate_area(ta, &area_tmp);
}
}
}
@ -1791,14 +1795,13 @@ static void refr_cursor_area(lv_obj_t * ta)
}
/*Save the new area*/
lv_disp_t * disp = lv_obj_get_disp(ta);
lv_area_t area_tmp;
lv_area_copy(&area_tmp, &ext->cursor.area);
area_tmp.x1 += ext->label->coords.x1;
area_tmp.y1 += ext->label->coords.y1;
area_tmp.x2 += ext->label->coords.x1;
area_tmp.y2 += ext->label->coords.y1;
lv_inv_area(disp, &area_tmp);
lv_obj_invalidate_area(ta, &area_tmp);
lv_area_copy(&ext->cursor.area, &cur_area);
@ -1807,7 +1810,7 @@ static void refr_cursor_area(lv_obj_t * ta)
area_tmp.y1 += ext->label->coords.y1;
area_tmp.x2 += ext->label->coords.x1;
area_tmp.y2 += ext->label->coords.y1;
lv_inv_area(disp, &area_tmp);
lv_obj_invalidate_area(ta, &area_tmp);
}
static void placeholder_update(lv_obj_t * ta)

View File

@ -114,8 +114,17 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy)
/* Set a size which fits into the parent.
* Don't use `par` directly because if the tabview is created on a page it is moved to the
* scrollable so the parent has changed */
lv_obj_set_size(new_tabview, lv_obj_get_width_fit(lv_obj_get_parent(new_tabview)),
lv_obj_get_height_fit(lv_obj_get_parent(new_tabview)));
lv_coord_t w;
lv_coord_t h;
if(par) {
w = lv_obj_get_width_fit(lv_obj_get_parent(new_tabview));
h = lv_obj_get_height_fit(lv_obj_get_parent(new_tabview));
} else {
w = lv_disp_get_hor_res(NULL);
h = lv_disp_get_ver_res(NULL);
}
lv_obj_set_size(new_tabview, w, h);
ext->content = lv_cont_create(new_tabview, NULL);
ext->btns = lv_btnm_create(new_tabview, NULL);
@ -914,12 +923,14 @@ static void tabpage_pressing_handler(lv_obj_t * tabview, lv_obj_t * tabpage)
p = ((tabpage->coords.x1 - tabview->coords.x1) * (indic_size + tabs_style->body.padding.inner)) /
lv_obj_get_width(tabview);
{
uint16_t id = ext->tab_cur;
if(lv_obj_get_base_dir(tabview) == LV_BIDI_DIR_RTL) {
id = (ext->tab_cnt - (id + 1));
}
lv_obj_set_x(ext->indic, indic_size * id + tabs_style->body.padding.inner * id +
indic_style->body.padding.left - p);
}
break;
case LV_TABVIEW_BTNS_POS_LEFT:
case LV_TABVIEW_BTNS_POS_RIGHT:

View File

@ -97,8 +97,17 @@ lv_obj_t * lv_tileview_create(lv_obj_t * par, const lv_obj_t * copy)
/* 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_coord_t w;
lv_coord_t h;
if(par) {
w = lv_obj_get_width_fit(lv_obj_get_parent(new_tileview));
h = lv_obj_get_height_fit(lv_obj_get_parent(new_tileview));
} else {
w = lv_disp_get_hor_res(NULL);
h = lv_disp_get_ver_res(NULL);
}
lv_obj_set_size(new_tileview, w, h);
lv_obj_set_drag_throw(lv_page_get_scrl(new_tileview), false);
lv_page_set_scrl_fit(new_tileview, LV_FIT_TIGHT);
@ -216,6 +225,7 @@ void lv_tileview_set_tile_act(lv_obj_t * tileview, lv_coord_t x, lv_coord_t y, l
for(tile_id = 0; tile_id < ext->valid_pos_cnt; tile_id++) {
if(ext->valid_pos[tile_id].x == x && ext->valid_pos[tile_id].y == y) {
valid = true;
break;
}
}
@ -486,9 +496,9 @@ static void tileview_scrl_event_cb(lv_obj_t * scrl, lv_event_t event)
lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);
if(lv_indev_is_dragging(indev) && (ext->drag_hor || ext->drag_ver)) {
indev->proc.types.pointer.drag_in_prog = 0;
drag_end_handler(tileview);
}
drag_end_handler(tileview);
}
}

View File

@ -75,10 +75,18 @@ lv_obj_t * lv_win_create(lv_obj_t * par, const lv_obj_t * copy)
/* Set a size which fits into the parent.
* Don't use `par` directly because if the window is created on a page it is moved to the
* scrollable so the parent has changed */
lv_obj_set_size(new_win, lv_obj_get_width_fit(lv_obj_get_parent(new_win)),
lv_obj_get_height_fit(lv_obj_get_parent(new_win)));
lv_coord_t w;
lv_coord_t h;
if(par) {
w = lv_obj_get_width_fit(lv_obj_get_parent(new_win));
h = lv_obj_get_height_fit(lv_obj_get_parent(new_win));
} else {
w = lv_disp_get_hor_res(NULL);
h = lv_disp_get_ver_res(NULL);
}
lv_obj_set_size(new_win, w, h);
lv_obj_set_pos(new_win, 0, 0);
lv_obj_set_style(new_win, &lv_style_pretty);
ext->page = lv_page_create(new_win, NULL);