From 878e3d33343e112e205e3a1dbcb30fd610f0b99e Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 19 Aug 2022 14:39:56 +0200 Subject: [PATCH] feat(roller): remove LV_ROLLER_INF_PAGES and calculate it dynamically fixes #3214 --- lv_conf_template.h | 3 --- src/lv_conf_internal.h | 35 +++++++++++++--------------------- src/widgets/roller/lv_roller.c | 29 +++++++++++++++++----------- src/widgets/roller/lv_roller.h | 2 ++ 4 files changed, 33 insertions(+), 36 deletions(-) diff --git a/lv_conf_template.h b/lv_conf_template.h index dd001d4cc..f73649b91 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -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*/ diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index ea0db716e..04df97edd 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -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 diff --git a/src/widgets/roller/lv_roller.c b/src/widgets/roller/lv_roller.c index b3a6dcf18..5a4f24fa2 100644 --- a/src/widgets/roller/lv_roller.c +++ b/src/widgets/roller/lv_roller.c @@ -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); diff --git a/src/widgets/roller/lv_roller.h b/src/widgets/roller/lv_roller.h index 10ef0a7f9..6ea178530 100644 --- a/src/widgets/roller/lv_roller.h +++ b/src/widgets/roller/lv_roller.h @@ -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;