1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

feat(roller): remove LV_ROLLER_INF_PAGES and calculate it dynamically

fixes #3214
This commit is contained in:
Gabor Kiss-Vamosi 2022-08-19 14:39:56 +02:00
parent bb7feb232f
commit 878e3d3334
4 changed files with 33 additions and 36 deletions

View File

@ -505,9 +505,6 @@
#define LV_USE_MSGBOX 1
#define LV_USE_ROLLER 1 /*Requires: lv_label*/
#if LV_USE_ROLLER
#define LV_ROLLER_INF_PAGES 7 /*Number of extra "pages" when the roller is infinite*/
#endif
#define LV_USE_SLIDER 1 /*Requires: lv_bar*/

View File

@ -309,7 +309,7 @@
#if LV_USE_DRAW_SW
/*Enable complex draw engine.
*Required to draw shadow, gradient, rounded corners, circles, arc, skew lines, image transformations or any masks*/
*Required to draw shadow, gradient, rounded corners, circles, arc, skew lines, image transformations or any masks*/
#ifndef LV_DRAW_SW_COMPLEX
#ifdef _LV_KCONFIG_PRESENT
#ifdef CONFIG_LV_DRAW_SW_COMPLEX
@ -323,9 +323,9 @@
#endif
/* If a widget has `style_opa < 255` (not `bg_opa`, `text_opa` etc) or not NORMAL blend mode
* it is buffered into a "simple" layer before rendering. The widget can be buffered in smaller chunks.
* "Transformed layers" (if `transform_angle/zoom` are set) use larger buffers
* and can't be drawn in chunks. */
* it is buffered into a "simple" layer before rendering. The widget can be buffered in smaller chunks.
* "Transformed layers" (if `transform_angle/zoom` are set) use larger buffers
* and can't be drawn in chunks. */
/*The target buffer size for simple layer chunks.*/
#ifndef LV_DRAW_SW_LAYER_SIMPLE_BUF_SIZE
@ -369,10 +369,10 @@
#endif
/*Default gradient buffer size.
*When LVGL calculates the gradient "maps" it can save them into a cache to avoid calculating them again.
*LV_DRAW_SW_GRADIENT_CACHE_DEF_SIZE sets the size of this cache in bytes.
*If the cache is too small the map will be allocated only while it's required for the drawing.
*0 mean no caching.*/
*When LVGL calculates the gradient "maps" it can save them into a cache to avoid calculating them again.
*LV_DRAW_SW_GRADIENT_CACHE_DEF_SIZE sets the size of this cache in bytes.
*If the cache is too small the map will be allocated only while it's required for the drawing.
*0 mean no caching.*/
#ifndef LV_DRAW_SW_GRADIENT_CACHE_DEF_SIZE
#ifdef CONFIG_LV_DRAW_SW_GRADIENT_CACHE_DEF_SIZE
#define LV_DRAW_SW_GRADIENT_CACHE_DEF_SIZE CONFIG_LV_DRAW_SW_GRADIENT_CACHE_DEF_SIZE
@ -382,8 +382,8 @@
#endif
/*Allow dithering the gradients (to achieve visual smooth color gradients on limited color depth display)
*LV_DRAW_SW_GRADIENT_DITHER implies allocating one or two more lines of the object's rendering surface
*The increase in memory consumption is (32 bits * object width) plus 24 bits * object width if using error diffusion */
*LV_DRAW_SW_GRADIENT_DITHER implies allocating one or two more lines of the object's rendering surface
*The increase in memory consumption is (32 bits * object width) plus 24 bits * object width if using error diffusion */
#ifndef LV_DRAW_SW_GRADIENT_DITHER
#ifdef CONFIG_LV_DRAW_SW_GRADIENT_DITHER
#define LV_DRAW_SW_GRADIENT_DITHER CONFIG_LV_DRAW_SW_GRADIENT_DITHER
@ -393,8 +393,8 @@
#endif
#if LV_DRAW_SW_GRADIENT_DITHER
/*Add support for error diffusion dithering.
*Error diffusion dithering gets a much better visual result, but implies more CPU consumption and memory when drawing.
*The increase in memory consumption is (24 bits * object's width)*/
*Error diffusion dithering gets a much better visual result, but implies more CPU consumption and memory when drawing.
*The increase in memory consumption is (24 bits * object's width)*/
#ifndef LV_DRAW_SW_GRADIENT_DITHER_ERROR_DIFFUSION
#ifdef CONFIG_LV_DRAW_SW_GRADIENT_DITHER_ERROR_DIFFUSION
#define LV_DRAW_SW_GRADIENT_DITHER_ERROR_DIFFUSION CONFIG_LV_DRAW_SW_GRADIENT_DITHER_ERROR_DIFFUSION
@ -585,7 +585,7 @@
#endif
/*1: Enable print timestamp;
*0: Disable print timestamp*/
*0: Disable print timestamp*/
#ifndef LV_LOG_USE_TIMESTAMP
#ifdef _LV_KCONFIG_PRESENT
#ifdef CONFIG_LV_LOG_USE_TIMESTAMP
@ -1697,15 +1697,6 @@
#define LV_USE_ROLLER 1 /*Requires: lv_label*/
#endif
#endif
#if LV_USE_ROLLER
#ifndef LV_ROLLER_INF_PAGES
#ifdef CONFIG_LV_ROLLER_INF_PAGES
#define LV_ROLLER_INF_PAGES CONFIG_LV_ROLLER_INF_PAGES
#else
#define LV_ROLLER_INF_PAGES 7 /*Number of extra "pages" when the roller is infinite*/
#endif
#endif
#endif
#ifndef LV_USE_SLIDER
#ifdef _LV_KCONFIG_PRESENT

View File

@ -20,6 +20,7 @@
*********************/
#define MY_CLASS &lv_roller_class
#define MY_CLASS_LABEL &lv_roller_label_class
#define EXTRA_INF_SIZE 1000 /*[px]: add the options multiple times until getting this height*/
/**********************
* TYPEDEFS
@ -119,20 +120,26 @@ void lv_roller_set_options(lv_obj_t * obj, const char * options, lv_roller_mode_
else {
roller->mode = LV_ROLLER_MODE_INFINITE;
const lv_font_t * font = lv_obj_get_style_text_font(obj, 0);
lv_coord_t normal_h = roller->option_cnt * (lv_font_get_line_height(font) + lv_obj_get_style_text_letter_space(obj, 0));
roller->inf_page_cnt = LV_CLAMP(3, EXTRA_INF_SIZE / normal_h, 15);
if(!roller->inf_page_cnt & 1) roller->inf_page_cnt++; /*Make it odd*/
LV_LOG_INFO("Using %d pages to make the roller look infinite", roller->inf_page_cnt);
size_t opt_len = strlen(options) + 1; /*+1 to add '\n' after option lists*/
char * opt_extra = lv_malloc(opt_len * LV_ROLLER_INF_PAGES);
char * opt_extra = lv_malloc(opt_len * roller->inf_page_cnt);
uint8_t i;
for(i = 0; i < LV_ROLLER_INF_PAGES; i++) {
for(i = 0; i < roller->inf_page_cnt; i++) {
strcpy(&opt_extra[opt_len * i], options);
opt_extra[opt_len * (i + 1) - 1] = '\n';
}
opt_extra[opt_len * LV_ROLLER_INF_PAGES - 1] = '\0';
opt_extra[opt_len * roller->inf_page_cnt - 1] = '\0';
lv_label_set_text(label, opt_extra);
lv_free(opt_extra);
roller->sel_opt_id = ((LV_ROLLER_INF_PAGES / 2) + 0) * roller->option_cnt;
roller->sel_opt_id = ((roller->inf_page_cnt / 2) + 0) * roller->option_cnt;
roller->option_cnt = roller->option_cnt * LV_ROLLER_INF_PAGES;
roller->option_cnt = roller->option_cnt * roller->inf_page_cnt;
inf_normalize(obj);
}
@ -161,7 +168,7 @@ void lv_roller_set_selected(lv_obj_t * obj, uint16_t sel_opt, lv_anim_enable_t a
/*In infinite mode interpret the new ID relative to the currently visible "page"*/
if(roller->mode == LV_ROLLER_MODE_INFINITE) {
uint32_t real_option_cnt = roller->option_cnt / LV_ROLLER_INF_PAGES;
uint32_t real_option_cnt = roller->option_cnt / roller->inf_page_cnt;
uint16_t current_page = roller->sel_opt_id / real_option_cnt;
/*Set by the user to e.g. 0, 1, 2, 3...
*Upscale the value to the current page*/
@ -213,7 +220,7 @@ uint16_t lv_roller_get_selected(const lv_obj_t * obj)
lv_roller_t * roller = (lv_roller_t *)obj;
if(roller->mode == LV_ROLLER_MODE_INFINITE) {
uint16_t real_id_cnt = roller->option_cnt / LV_ROLLER_INF_PAGES;
uint16_t real_id_cnt = roller->option_cnt / roller->inf_page_cnt;
return roller->sel_opt_id % real_id_cnt;
}
else {
@ -279,7 +286,7 @@ uint16_t lv_roller_get_option_cnt(const lv_obj_t * obj)
lv_roller_t * roller = (lv_roller_t *)obj;
if(roller->mode == LV_ROLLER_MODE_INFINITE) {
return roller->option_cnt / LV_ROLLER_INF_PAGES;
return roller->option_cnt / roller->inf_page_cnt;
}
else {
return roller->option_cnt;
@ -729,12 +736,12 @@ static void inf_normalize(lv_obj_t * obj)
lv_roller_t * roller = (lv_roller_t *)obj;
if(roller->mode == LV_ROLLER_MODE_INFINITE) {
uint16_t real_id_cnt = roller->option_cnt / LV_ROLLER_INF_PAGES;
uint16_t real_id_cnt = roller->option_cnt / roller->inf_page_cnt;
roller->sel_opt_id = roller->sel_opt_id % real_id_cnt;
roller->sel_opt_id += (LV_ROLLER_INF_PAGES / 2) * real_id_cnt; /*Select the middle page*/
roller->sel_opt_id += (roller->inf_page_cnt / 2) * real_id_cnt; /*Select the middle page*/
roller->sel_opt_id_ori = roller->sel_opt_id % real_id_cnt;
roller->sel_opt_id_ori += (LV_ROLLER_INF_PAGES / 2) * real_id_cnt; /*Select the middle page*/
roller->sel_opt_id_ori += (roller->inf_page_cnt / 2) * real_id_cnt; /*Select the middle page*/
/*Move to the new id*/
const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN);

View File

@ -45,8 +45,10 @@ typedef struct {
uint16_t option_cnt; /**< Number of options*/
uint16_t sel_opt_id; /**< Index of the current option*/
uint16_t sel_opt_id_ori; /**< Store the original index on focus*/
uint32_t inf_page_cnt; /**< Number of extra pages added to make the roller look infinite */
lv_roller_mode_t mode : 1;
uint32_t moved : 1;
} lv_roller_t;
extern const lv_obj_class_t lv_roller_class;