From 5bb1653991eee08afefb686c03b8168c70b329aa Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 14 Jun 2019 16:04:15 +0200 Subject: [PATCH] label hint: comments and formatting --- src/lv_draw/lv_draw_label.c | 15 ++++++++++----- src/lv_draw/lv_draw_label.h | 15 +++++++++++++-- src/lv_objx/lv_label.c | 15 ++++++++++++--- src/lv_objx/lv_label.h | 2 ++ src/lv_objx/lv_ta.c | 31 ++++++++++++++++++++++++++++++- src/lv_objx/lv_ta.h | 15 +++++++++++++++ 6 files changed, 82 insertions(+), 11 deletions(-) diff --git a/src/lv_draw/lv_draw_label.c b/src/lv_draw/lv_draw_label.c index 968ed1be2..95ff2a9ec 100644 --- a/src/lv_draw/lv_draw_label.c +++ b/src/lv_draw/lv_draw_label.c @@ -13,6 +13,7 @@ * DEFINES *********************/ #define LABEL_RECOLOR_PAR_LENGTH 6 +#define LV_LABEL_HINT_UPDATE_TH 1024 /*Update the "hint" if the label's y coordinates have changed more then this*/ /********************** * TYPEDEFS @@ -87,12 +88,17 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st uint32_t line_start = 0; int32_t last_line_start = -1; - if(hint) { - if(LV_MATH_ABS(hint->coord_y - coords->y1) > 50) { + + /*Check the hint to use the cached info*/ + if(hint && y_ofs == 0) { + /*If the label changed too much recalculate the hint.*/ + if(LV_MATH_ABS(hint->coord_y - coords->y1) > LV_LABEL_HINT_UPDATE_TH - 2 * line_height) { hint->line_start = -1; } last_line_start = hint->line_start; } + + /*Use the hint if it's valid*/ if(last_line_start >= 0) { line_start = last_line_start; pos.y += hint->y; @@ -107,12 +113,11 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st line_end += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag); pos.y += line_height; -// if(pos.y + line_height <= 0 && pos.y + 2 * line_height > 0 && hint_saved == false) { - if(pos.y >= -100 && hint->line_start < 0) { + /*Save at the threshold coordinate*/ + if(pos.y >= -LV_LABEL_HINT_UPDATE_TH && hint->line_start < 0) { hint->line_start = line_start; hint->y = pos.y - coords->y1; hint->coord_y = coords->y1; - printf("in : %d, %d, %d\n", hint->line_start, hint->y, hint->coord_y); } if(txt[line_start] == '\0') return; diff --git a/src/lv_draw/lv_draw_label.h b/src/lv_draw/lv_draw_label.h index 7083244ec..ebc66d430 100644 --- a/src/lv_draw/lv_draw_label.h +++ b/src/lv_draw/lv_draw_label.h @@ -22,10 +22,21 @@ extern "C" { /********************** * TYPEDEFS **********************/ -typedef struct -{ + +/* Store some info to speed up drawing of very large texts + * It takes a lot of time to get the first visible character because + * all the previous characters needs to be checked to calculate the positions. + * This structure stores an earlier (e.g. at -1000 px) coordinate and the index of that line. + * Therefore the calculations can start from here.*/ +typedef struct { + /*Index of the line at `y` coordinate*/ int32_t line_start; + + /*Give the `y` coordinate of the first letter at `line start` index. Relative to the label's coordinates*/ int32_t y; + + /*The 'y1' coordinate of the label when the hint was saved. + * Used to invalidate the hint if the label has moved too much. */ int32_t coord_y; }lv_draw_label_hint_t; diff --git a/src/lv_objx/lv_label.c b/src/lv_objx/lv_label.c index 413913c5d..9ec0a550d 100644 --- a/src/lv_objx/lv_label.c +++ b/src/lv_objx/lv_label.c @@ -11,7 +11,6 @@ #include "../lv_core/lv_obj.h" #include "../lv_core/lv_group.h" -#include "../lv_draw/lv_draw.h" #include "../lv_misc/lv_color.h" #include "../lv_misc/lv_math.h" @@ -24,6 +23,7 @@ #endif #define LV_LABEL_DOT_END_INV 0xFFFF +#define LV_LABEL_HINT_HEIGHT_LIMIT 1024 /*Enable "hint" to buffer info about labels larger than this. (Speed up their drawing)*/ /********************** * TYPEDEFS @@ -50,7 +50,6 @@ static void lv_label_dot_tmp_free(lv_obj_t * label); * STATIC VARIABLES **********************/ static lv_signal_cb_t ancestor_signal; -lv_draw_label_hint_t hint = {.line_start = -1}; /********************** * MACROS @@ -96,6 +95,11 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy) #endif ext->offset.x = 0; ext->offset.y = 0; + + ext->hint.line_start = -1; + ext->hint.coord_y = 0; + ext->hint.y = 0; + #if LV_LABEL_TEXT_SEL ext->txt_sel_start = LV_LABEL_TEXT_SEL_OFF; ext->txt_sel_end = LV_LABEL_TEXT_SEL_OFF; @@ -845,8 +849,11 @@ static bool lv_label_design(lv_obj_t * label, const lv_area_t * mask, lv_design_ } } + lv_draw_label_hint_t * hint = &ext->hint; + if(ext->long_mode == LV_LABEL_LONG_ROLL_CIRC || lv_obj_get_height(label) < LV_LABEL_HINT_HEIGHT_LIMIT) hint = NULL; + lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ext->offset, - lv_label_get_text_sel_start(label), lv_label_get_text_sel_end(label), &hint); + lv_label_get_text_sel_start(label), lv_label_get_text_sel_end(label), hint); if(ext->long_mode == LV_LABEL_LONG_ROLL_CIRC) { lv_point_t size; @@ -941,6 +948,8 @@ static void lv_label_refr_text(lv_obj_t * label) if(ext->text == NULL) return; + ext->hint.line_start = -1; /*The hint is invalid if the text changes*/ + lv_coord_t max_w = lv_obj_get_width(label); const lv_style_t * style = lv_obj_get_style(label); const lv_font_t * font = style->text.font; diff --git a/src/lv_objx/lv_label.h b/src/lv_objx/lv_label.h index 4a7c8c8ad..2d505c3d1 100644 --- a/src/lv_objx/lv_label.h +++ b/src/lv_objx/lv_label.h @@ -25,6 +25,7 @@ extern "C" { #include "../lv_font/lv_font.h" #include "../lv_font/lv_symbol_def.h" #include "../lv_misc/lv_txt.h" +#include "../lv_draw/lv_draw.h" /********************* * DEFINES @@ -72,6 +73,7 @@ typedef struct uint16_t dot_end; /*The text end position in dot mode (Handled by the library)*/ lv_point_t offset; /*Text draw position offset*/ + lv_draw_label_hint_t hint; /*Used to buffer info about large text*/ #if LV_USE_ANIMATION uint16_t anim_speed; /*Speed of scroll and roll animation in px/sec unit*/ #endif diff --git a/src/lv_objx/lv_ta.c b/src/lv_objx/lv_ta.c index ee1279764..68db1af48 100644 --- a/src/lv_objx/lv_ta.c +++ b/src/lv_objx/lv_ta.c @@ -107,6 +107,7 @@ lv_obj_t * lv_ta_create(lv_obj_t * par, const lv_obj_t * copy) ext->cursor.style = NULL; ext->cursor.blink_time = LV_TA_DEF_CURSOR_BLINK_TIME; ext->cursor.pos = 0; + ext->cursor.click_pos = 1; ext->cursor.type = LV_CURSOR_LINE; ext->cursor.valid_x = 0; ext->one_line = 0; @@ -617,6 +618,17 @@ void lv_ta_set_cursor_type(lv_obj_t * ta, lv_cursor_type_t cur_type) refr_cursor_area(ta); } +/** + * Enable/Disable the positioning of the the cursor by clicking the text on the text area. + * @param ta pointer to a text area object + * @param en true: enable click positions; false: disable + */ +void lv_ta_set_cursor_click_pos(lv_obj_t * ta, bool en) +{ + lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta); + ext->cursor.click_pos = en ? 1 : 0; +} + /** * Enable/Disable password mode * @param ta pointer to a text area object @@ -941,6 +953,17 @@ lv_cursor_type_t lv_ta_get_cursor_type(const lv_obj_t * ta) return ext->cursor.type; } +/** + * Get whether the cursor click positioning is enabled or not. + * @param ta pointer to a text area object + * @return true: enable click positions; false: disable + */ +bool lv_ta_get_cursor_click_pos(lv_obj_t * ta) +{ + lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta); + return ext->cursor.click_pos ? true : false; +} + /** * Get the password mode attribute * @param ta pointer to a text area object @@ -1586,6 +1609,8 @@ static void get_cursor_style(lv_obj_t * ta, lv_style_t * style_res) static void refr_cursor_area(lv_obj_t * ta) { lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta); + + const lv_style_t * label_style = lv_obj_get_style(ext->label); lv_style_t cur_style; @@ -1707,14 +1732,18 @@ static void placeholder_update(lv_obj_t * ta) static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_indev_t * click_source) { + if(click_source == NULL) return; + lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta); + if(ext->cursor.click_pos == 0) return; + if(ext->cursor.type == LV_CURSOR_NONE) return; + if(lv_indev_get_type(click_source) == LV_INDEV_TYPE_KEYPAD || lv_indev_get_type(click_source) == LV_INDEV_TYPE_ENCODER) { return; } - lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta); lv_area_t label_coords; lv_obj_get_coords(ext->label, &label_coords); diff --git a/src/lv_objx/lv_ta.h b/src/lv_objx/lv_ta.h index cb2c1ca8c..08ef34c9c 100644 --- a/src/lv_objx/lv_ta.h +++ b/src/lv_objx/lv_ta.h @@ -76,6 +76,7 @@ typedef struct uint16_t txt_byte_pos; /* Byte index of the letter after (on) the cursor*/ lv_cursor_type_t type : 4; /* Shape of the cursor*/ uint8_t state : 1; /*Cursor is visible now or not (Handled by the library)*/ + uint8_t click_pos :1; /*1: Enable positioning the cursor by clicking the text area*/ } cursor; #if LV_LABEL_TEXT_SEL uint16_t tmp_sel_start; /*Temporary value*/ @@ -173,6 +174,13 @@ void lv_ta_set_cursor_pos(lv_obj_t * ta, int16_t pos); */ void lv_ta_set_cursor_type(lv_obj_t * ta, lv_cursor_type_t cur_type); +/** + * Enable/Disable the positioning of the the cursor by clicking the text on the text area. + * @param ta pointer to a text area object + * @param en true: enable click positions; false: disable + */ +void lv_ta_set_cursor_click_pos(lv_obj_t * ta, bool en); + /** * Enable/Disable password mode * @param ta pointer to a text area object @@ -319,6 +327,13 @@ uint16_t lv_ta_get_cursor_pos(const lv_obj_t * ta); */ lv_cursor_type_t lv_ta_get_cursor_type(const lv_obj_t * ta); +/** + * Get whether the cursor click positioning is enabled or not. + * @param ta pointer to a text area object + * @return true: enable click positions; false: disable + */ +bool lv_ta_get_cursor_click_pos(lv_obj_t * ta); + /** * Get the password mode attribute * @param ta pointer to a text area object