From 1a591d4946328d30c6a88071fd1978e49e93cde0 Mon Sep 17 00:00:00 2001 From: Gabor Date: Sat, 1 Oct 2016 00:25:10 +0200 Subject: [PATCH] Near all text area functions are added --- lv_draw/lv_draw.c | 4 +- lv_misc/text.c | 6 ++- lv_misc/text.h | 2 +- lv_objx/lv_label.c | 73 ++++++++++++++++++++++++++------ lv_objx/lv_label.h | 1 + lv_objx/lv_rect.c | 3 ++ lv_objx/lv_ta.c | 101 +++++++++++++++++++++++++++++++++++++++++---- lv_objx/lv_ta.h | 4 ++ 8 files changed, 168 insertions(+), 26 deletions(-) diff --git a/lv_draw/lv_draw.c b/lv_draw/lv_draw.c index f54636cf4..bc68bbf1f 100644 --- a/lv_draw/lv_draw.c +++ b/lv_draw/lv_draw.c @@ -123,7 +123,7 @@ void lv_draw_label(const area_t * cords_p,const area_t * mask_p, /*Align the line to middle if enabled*/ if(labels_p->mid != 0) { - line_length = txt_get_length(&txt[line_start], line_end - line_start, + line_length = txt_get_width(&txt[line_start], line_end - line_start, font_p, labels_p->letter_space); pos.x += (w - line_length) / 2; } @@ -144,7 +144,7 @@ void lv_draw_label(const area_t * cords_p,const area_t * mask_p, pos.x = cords_p->x1; /*Align to middle*/ if(labels_p->mid != 0) { - line_length = txt_get_length(&txt[line_start], line_end - line_start, + line_length = txt_get_width(&txt[line_start], line_end - line_start, font_p, labels_p->letter_space); pos.x += (w - line_length) / 2; } diff --git a/lv_misc/text.c b/lv_misc/text.c index babc61cfc..7538ff546 100644 --- a/lv_misc/text.c +++ b/lv_misc/text.c @@ -53,7 +53,9 @@ uint16_t txt_get_next_line(const char * txt, const font_t * font_p, /*Check for new line chars*/ if(txt[i] == '\n' || txt[i] == '\r') { /*Handle \n\r and \r\n as well*/ - if(txt[i + 1] == '\n' || txt[i + 1] == '\r') { + if(txt[i] == '\n' && txt[i + 1] == '\r') { + i++; + } else if(txt[i] == '\r' && txt[i + 1] == '\n') { i++; } return i+1; /*Return with the first letter of the next line*/ @@ -95,7 +97,7 @@ uint16_t txt_get_next_line(const char * txt, const font_t * font_p, * @param letter_space letter sapce * @return length of a char_num long text */ -cord_t txt_get_length(const char * txt, uint16_t char_num, +cord_t txt_get_width(const char * txt, uint16_t char_num, const font_t * font_p, uint16_t letter_space) { uint16_t i; diff --git a/lv_misc/text.h b/lv_misc/text.h index abd40b89a..b13b923d4 100644 --- a/lv_misc/text.h +++ b/lv_misc/text.h @@ -26,7 +26,7 @@ * GLOBAL PROTOTYPES **********************/ uint16_t txt_get_next_line(const char * txt, const font_t * font_p, uint16_t letter_space, cord_t max_l); -cord_t txt_get_length(const char * txt, uint16_t char_num, const font_t * font_p, uint16_t letter_space); +cord_t txt_get_width(const char * txt, uint16_t char_num, const font_t * font_p, uint16_t letter_space); /********************** * MACROS diff --git a/lv_objx/lv_label.c b/lv_objx/lv_label.c index 1d2db8623..b378a9ae8 100644 --- a/lv_objx/lv_label.c +++ b/lv_objx/lv_label.c @@ -186,7 +186,7 @@ void lv_label_set_text(lv_obj_t * obj_dp, const char * text) /*If no fix width then calc. the longest line */ if(ext_p->fixw == false) { - act_line_length = txt_get_length(&text[line_start], new_line_start - line_start, + act_line_length = txt_get_width(&text[line_start], new_line_start - line_start, font_p, labels_p->letter_space); if(act_line_length > longest_line) { longest_line = act_line_length; @@ -273,8 +273,7 @@ void lv_label_get_letter_pos(lv_obj_t * obj_dp, uint16_t index, point_t * pos_p) } /*Search the line of the index letter */; - while (text[line_start] != '\0') - { + while (text[line_start] != '\0') { new_line_start += txt_get_next_line(&text[line_start], font_p, labels_p->letter_space, max_length); if(index < new_line_start) break; /*Lines of index letter begins at 'line_start'*/ @@ -284,20 +283,68 @@ void lv_label_get_letter_pos(lv_obj_t * obj_dp, uint16_t index, point_t * pos_p) /*Calculate the x coordinate*/ cord_t x = 0; - /*TODO handle 'mid'*/ - //if(labels_p->mid == 0) - { - uint32_t i; - for(i = line_start; i < index; i++) { - x += font_get_width(font_p, text[i]) + labels_p->line_space; - } + uint32_t i; + for(i = line_start; i < index; i++) { + x += font_get_width(font_p, text[i]) + labels_p->letter_space; + } + + if(labels_p->mid != 0) { + cord_t line_w; + line_w = txt_get_width(&text[line_start], new_line_start - line_start, + font_p, labels_p->letter_space); + x += lv_obj_get_width(obj_dp) / 2 - line_w / 2; } - pos_p->x = x + obj_dp->cords.x1; - pos_p->y = y + obj_dp->cords.y1; + pos_p->x = x; + pos_p->y = y; } +uint16_t lv_label_get_letter_on(lv_obj_t * obj_dp, point_t * pos_p) +{ + const char * text = lv_label_get_text(obj_dp); + lv_label_ext_t * ext_p = lv_obj_get_ext(obj_dp); + uint32_t line_start = 0; + uint32_t new_line_start = 0; + cord_t max_length = lv_obj_get_width(obj_dp); + lv_labels_t * labels_p = lv_obj_get_style(obj_dp); + const font_t * font_p = font_get(labels_p->font); + uint8_t letter_height = font_get_height(font_p); + cord_t y = 0; + + /*If the fix width is not enabled the set the max length to very big */ + if(ext_p->fixw == 0) { + max_length = LV_CORD_MAX; + } + + /*Search the line of the index letter */; + while (text[line_start] != '\0') { + new_line_start += txt_get_next_line(&text[line_start], font_p, labels_p->letter_space, max_length); + if(pos_p->y <= y + letter_height + labels_p->line_space) break; /*The line is found ('line_start')*/ + y += letter_height + labels_p->line_space; + line_start = new_line_start; + } + + /*Calculate the x coordinate*/ + cord_t x = 0; + if(labels_p->mid != 0) { + cord_t line_w; + line_w = txt_get_width(&text[line_start], new_line_start - line_start, + font_p, labels_p->letter_space); + x += lv_obj_get_width(obj_dp) / 2 - line_w / 2; + } + + uint32_t i; + for(i = line_start; i < new_line_start-1; i++) { + x += font_get_width(font_p, text[i]) + labels_p->letter_space; + if(pos_p->x <= x) break; + + } + + + return i; +} + /** * Return with a pointer to a built-in style and/or copy it to a variable * @param style a style name from lv_labels_builtin_t enum @@ -353,7 +400,7 @@ static bool lv_label_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_m if(mode == LV_DESIGN_COVER_CHK) return false; /*TEST: draw a background for the label*/ - /*lv_vfill(&obj_dp->cords, mask_p, COLOR_LIME, OPA_COVER);*/ + /*lv_vfill(&obj_dp->cords, mask_p, COLOR_LIME, OPA_COVER); */ area_t cords; lv_obj_get_cords(obj_dp, &cords); diff --git a/lv_objx/lv_label.h b/lv_objx/lv_label.h index d8d497d3c..6ef27c26d 100644 --- a/lv_objx/lv_label.h +++ b/lv_objx/lv_label.h @@ -60,6 +60,7 @@ void lv_label_set_fixw(lv_obj_t * obj_dp, bool fixw); const char * lv_label_get_text(lv_obj_t* obj_dp); bool lv_label_get_fixw(lv_obj_t * obj_dp); void lv_label_get_letter_pos(lv_obj_t * obj_dp, uint16_t index, point_t * pos_p); +uint16_t lv_label_get_letter_on(lv_obj_t * obj_dp, point_t * pos_p); lv_labels_t * lv_labels_get(lv_labels_builtin_t style, lv_labels_t * copy_p); diff --git a/lv_objx/lv_rect.c b/lv_objx/lv_rect.c index b7c4efc76..8687a3919 100644 --- a/lv_objx/lv_rect.c +++ b/lv_objx/lv_rect.c @@ -96,6 +96,7 @@ lv_obj_t* lv_rect_create(lv_obj_t* par_dp, lv_obj_t * copy_dp) lv_rect_ext_t * ori_rect_ext = lv_obj_get_ext(copy_dp); rect_ext_dp->hfit_en = ori_rect_ext->hfit_en; rect_ext_dp->vfit_en = ori_rect_ext->vfit_en; + rect_ext_dp->layout = ori_rect_ext->layout; } return new_obj_dp; @@ -573,7 +574,9 @@ void lv_rect_refr_autofit(lv_obj_t * obj_dp) rect_cords.y2 = obj_dp->cords.y2; } + lv_obj_inv(obj_dp); area_cpy(&obj_dp->cords, &rect_cords); + lv_obj_inv(obj_dp); /*Notify the object about its new coordinates*/ obj_dp->signal_f(obj_dp, LV_SIGNAL_CORD_CHG, &ori); diff --git a/lv_objx/lv_ta.c b/lv_objx/lv_ta.c index 88ee6b1ee..a6b9daf07 100644 --- a/lv_objx/lv_ta.c +++ b/lv_objx/lv_ta.c @@ -31,6 +31,7 @@ static bool lv_ta_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode **********************/ static lv_tas_t lv_tas_def = { /*Create a default style*/ }; + lv_design_f_t ancestor_design_f; /********************** @@ -71,8 +72,10 @@ lv_obj_t* lv_ta_create(lv_obj_t* par_dp, lv_obj_t * copy_dp) /*Init the new text area object*/ if(copy_dp == NULL) { ext_dp->label_dp = lv_label_create(new_obj_dp, NULL); - lv_label_set_text(ext_dp->label_dp, "Abc def xyz\n\n\n\n\n\n\n\n\n\n\n\nghi\n\n\n\n\n\n\n\n\n\n123\n\n\n\n\n\n\n\n\n\n456\n\n\n\n\n\n789"); - lv_obj_set_style(ext_dp->label_dp, lv_labels_get(LV_LABELS_TXT, NULL)); + lv_label_set_text(ext_dp->label_dp, "0123456789 abcdef\nABCDEF\nG\nHIJKLM\n\nnopqrs"); + //lv_obj_set_style(ext_dp->label_dp, lv_labels_get(LV_LABELS_TXT, NULL)); + // lv_label_set_fixw(ext_dp->label_dp, true); + lv_obj_set_width_us(ext_dp->label_dp, 200); } /*Copy an existing object*/ else { @@ -115,15 +118,97 @@ bool lv_ta_signal(lv_obj_t* obj_dp, lv_signal_t sign, void * param) * Setter functions *====================*/ +void lv_ta_add_char(lv_obj_t * obj_dp, char c) +{ + lv_ta_ext_t * ta_dp = lv_obj_get_ext(obj_dp); + + char buf[LV_TA_MAX_LENGTH]; + const char * label_txt = lv_label_get_text(ta_dp->label_dp); + + memcpy(buf, label_txt, ta_dp->cursor_pos); + buf[ta_dp->cursor_pos] = c; + memcpy(buf+ta_dp->cursor_pos+1, label_txt+ta_dp->cursor_pos, strlen(label_txt) - ta_dp->cursor_pos + 1); + + lv_label_set_text(ta_dp->label_dp, buf); + + lv_ta_set_cursor_pos(obj_dp, lv_ta_get_cursor_pos(obj_dp) + 1); +} + +void lv_ta_add_text(lv_obj_t * obj_dp, const char * txt) +{ + lv_ta_ext_t * ta_dp = lv_obj_get_ext(obj_dp); + + char buf[LV_TA_MAX_LENGTH]; + const char * label_txt = lv_label_get_text(ta_dp->label_dp); + uint16_t label_len = strlen(label_txt); + uint16_t txt_len = strlen(txt); + + memcpy(buf, label_txt, ta_dp->cursor_pos); + memcpy(buf+ta_dp->cursor_pos, txt, txt_len); + memcpy(buf+ta_dp->cursor_pos + txt_len, label_txt+ta_dp->cursor_pos, label_len - ta_dp->cursor_pos + 1); + + lv_label_set_text(ta_dp->label_dp, buf); + + lv_ta_set_cursor_pos(obj_dp, lv_ta_get_cursor_pos(obj_dp) + txt_len); +} + +void lv_ta_del(lv_obj_t * obj_dp) +{ + lv_ta_ext_t * ta_dp = lv_obj_get_ext(obj_dp); + uint16_t cur_pos = ta_dp->cursor_pos; + + if(cur_pos == 0) return; + + char buf[LV_TA_MAX_LENGTH]; + const char * label_txt = lv_label_get_text(ta_dp->label_dp); + uint16_t label_len = strlen(label_txt); + memcpy(buf, label_txt, cur_pos - 1); + memcpy(buf+cur_pos - 1, label_txt + cur_pos, label_len - cur_pos + 1); + + lv_label_set_text(ta_dp->label_dp, buf); + + lv_ta_set_cursor_pos(obj_dp, lv_ta_get_cursor_pos(obj_dp) - 1); +} + void lv_ta_set_cursor_pos(lv_obj_t * obj_dp, uint16_t pos) { - lv_ta_ext_t * ta_dp = lv_obj_get_ext(obj_dp); ta_dp->cursor_pos = pos; lv_obj_inv(obj_dp); } +void lv_ta_cursor_down(lv_obj_t * obj_dp) +{ + lv_ta_ext_t * ta_dp = lv_obj_get_ext(obj_dp); + point_t pos; + + lv_label_get_letter_pos(ta_dp->label_dp, lv_ta_get_cursor_pos(obj_dp), &pos); + + lv_labels_t * labels_p = lv_obj_get_style(ta_dp->label_dp); + const font_t * font_p = font_get(labels_p->font); + pos.y += font_get_height(font_p) + labels_p->line_space + 1; + + uint16_t new_cur_pos = lv_label_get_letter_on(ta_dp->label_dp, &pos); + + lv_ta_set_cursor_pos(obj_dp, new_cur_pos); +} + +void lv_ta_cursor_up(lv_obj_t * obj_dp) +{ + lv_ta_ext_t * ta_dp = lv_obj_get_ext(obj_dp); + point_t pos; + + lv_label_get_letter_pos(ta_dp->label_dp, lv_ta_get_cursor_pos(obj_dp), &pos); + + lv_labels_t * labels_p = lv_obj_get_style(ta_dp->label_dp); + const font_t * font_p = font_get(labels_p->font); + pos.y -= font_get_height(font_p) + labels_p->line_space - 1; + + uint16_t new_cur_pos = lv_label_get_letter_on(ta_dp->label_dp, &pos); + + lv_ta_set_cursor_pos(obj_dp, new_cur_pos); +} /*===================== * Getter functions *====================*/ @@ -189,11 +274,11 @@ static bool lv_ta_design(lv_obj_t* obj_dp, const area_t * mask_p, lv_design_mode lv_label_get_letter_pos(ta_dp->label_dp, cur_pos, &letter_pos); area_t cur_area; - lv_labels_t * label_p = lv_obj_get_style(ta_dp->label_dp); - cur_area.x1 = letter_pos.x; - cur_area.y1 = letter_pos.y; - cur_area.x2 = letter_pos.x + 4; - cur_area.y2 = letter_pos.y + font_get_height(font_get(label_p->font)); + lv_labels_t * labels_p = lv_obj_get_style(ta_dp->label_dp); + cur_area.x1 = letter_pos.x + ta_dp->label_dp->cords.x1 - 2; + cur_area.y1 = letter_pos.y + ta_dp->label_dp->cords.y1; + cur_area.x2 = letter_pos.x + ta_dp->label_dp->cords.x1 + 2; + cur_area.y2 = letter_pos.y + ta_dp->label_dp->cords.y1 + font_get_height(font_get(labels_p->font)); lv_rects_t rects; lv_rects_get(LV_RECTS_DEF, &rects); diff --git a/lv_objx/lv_ta.h b/lv_objx/lv_ta.h index 245c1953a..0ed49415e 100644 --- a/lv_objx/lv_ta.h +++ b/lv_objx/lv_ta.h @@ -56,7 +56,11 @@ bool lv_ta_signal(lv_obj_t* obj_dp, lv_signal_t sign, void * param); lv_tas_t * lv_tas_get(lv_tas_builtin_t style, lv_tas_t * copy_p); void lv_ta_add_char(lv_obj_t * obj_dp, char c); +void lv_ta_add_text(lv_obj_t * obj_dp, const char * txt); +void lv_ta_del(lv_obj_t * obj_dp); void lv_ta_set_cursor_pos(lv_obj_t * obj_dp, uint16_t pos); +void lv_ta_cursor_down(lv_obj_t * obj_dp); +void lv_ta_cursor_up(lv_obj_t * obj_dp); const char * lv_ta_get_txt(lv_obj_t obj_dp);