rework table and textarea

This commit is contained in:
Gabor Kiss-Vamosi
2020-09-30 06:12:29 +02:00
parent 06281e38cf
commit afc5475196
13 changed files with 286 additions and 560 deletions

View File

@@ -13,6 +13,7 @@
#include "../lv_misc/lv_debug.h"
#include "../lv_core/lv_group.h"
#include "../lv_core/lv_refr.h"
#include "../lv_core/lv_indev.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_misc/lv_anim.h"
@@ -46,10 +47,7 @@
* STATIC PROTOTYPES
**********************/
static lv_design_res_t lv_textarea_design(lv_obj_t * ta, const lv_area_t * clip_area, lv_design_mode_t mode);
static lv_design_res_t lv_textarea_scrollable_design(lv_obj_t * scrl, const lv_area_t * clip_area,
lv_design_mode_t mode);
static lv_res_t lv_textarea_signal(lv_obj_t * ta, lv_signal_t sign, void * param);
static lv_res_t lv_textarea_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, void * param);
static lv_style_list_t * lv_textarea_get_style(lv_obj_t * ta, uint8_t part);
#if LV_USE_ANIMATION
static void cursor_blink_anim(lv_obj_t * ta, lv_anim_value_t show);
@@ -61,6 +59,8 @@ static bool char_is_accepted(lv_obj_t * ta, uint32_t c);
static void refr_cursor_area(lv_obj_t * ta);
static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_indev_t * click_source);
static lv_res_t insert_handler(lv_obj_t * ta, const char * txt);
static void draw_placeholder(lv_obj_t * ta, const lv_area_t * clip_area);
static void draw_cursor(lv_obj_t * ta, const lv_area_t * clip_area);
/**********************
* STATIC VARIABLES
@@ -90,14 +90,12 @@ lv_obj_t * lv_textarea_create(lv_obj_t * par, const lv_obj_t * copy)
LV_LOG_TRACE("text area create started");
/*Create the ancestor object*/
lv_obj_t * ta = lv_page_create(par, copy);
lv_obj_t * ta = lv_obj_create(par, copy);
LV_ASSERT_MEM(ta);
if(ta == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(ta);
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(ta);
if(scrl_signal == NULL) scrl_signal = lv_obj_get_signal_cb(lv_page_get_scrollable(ta));
if(scrl_design == NULL) scrl_design = lv_obj_get_design_cb(lv_page_get_scrollable(ta));
/*Allocate the object type specific extended data*/
lv_textarea_ext_t * ext = lv_obj_allocate_ext_attr(ta, sizeof(lv_textarea_ext_t));
@@ -134,30 +132,19 @@ lv_obj_t * lv_textarea_create(lv_obj_t * par, const lv_obj_t * copy)
#endif
lv_obj_set_signal_cb(ta, lv_textarea_signal);
lv_obj_set_signal_cb(lv_page_get_scrollable(ta), lv_textarea_scrollable_signal);
lv_obj_set_design_cb(ta, lv_textarea_design);
/*Init the new text area object*/
if(copy == NULL) {
lv_page_set_scrollable_fit2(ta, LV_FIT_PARENT, LV_FIT_TIGHT);
ext->label = lv_label_create(ta, NULL);
lv_obj_set_design_cb(ext->page.scrl, lv_textarea_scrollable_design);
lv_label_set_long_mode(ext->label, LV_LABEL_LONG_BREAK);
lv_label_set_text(ext->label, "Text area");
lv_obj_set_click(ext->label, false);
lv_obj_set_size(ta, LV_TEXTAREA_DEF_WIDTH, LV_TEXTAREA_DEF_HEIGHT);
lv_textarea_set_scrollbar_mode(ta, LV_SCROLLBAR_MODE_DRAG);
lv_obj_reset_style_list(ta, LV_PAGE_PART_SCROLLABLE);
lv_theme_apply(ta, LV_THEME_TEXTAREA);
}
/*Copy an existing object*/
else {
lv_obj_set_design_cb(ext->page.scrl, lv_textarea_scrollable_design);
lv_textarea_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
ext->label = lv_label_create(ta, copy_ext->label);
ext->pwd_mode = copy_ext->pwd_mode;
@@ -188,7 +175,7 @@ lv_obj_t * lv_textarea_create(lv_obj_t * par, const lv_obj_t * copy)
if(copy_ext->one_line) lv_textarea_set_one_line(ta, true);
/*Refresh the style with new signal function*/
lv_obj_refresh_style(ta, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
_lv_obj_refresh_style(ta, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
}
#if LV_USE_ANIMATION
@@ -261,10 +248,6 @@ void lv_textarea_add_char(lv_obj_t * ta, uint32_t c)
}
/*If a new line was added it shouldn't show edge flash effect*/
bool edge_flash_en = lv_textarea_get_edge_flash(ta);
lv_textarea_set_edge_flash(ta, false);
if(ext->pwd_mode != 0) pwd_char_hider(ta); /*Make sure all the current text contains only '*'*/
/*If the textarea is empty, invalidate it to hide the placeholder*/
@@ -313,9 +296,6 @@ void lv_textarea_add_char(lv_obj_t * ta, uint32_t c)
/*Move the cursor after the new character*/
lv_textarea_set_cursor_pos(ta, lv_textarea_get_cursor_pos(ta) + 1);
/*Revert the original edge flash state*/
lv_textarea_set_edge_flash(ta, edge_flash_en);
lv_event_send(ta, LV_EVENT_VALUE_CHANGED, NULL);
}
@@ -346,10 +326,6 @@ void lv_textarea_add_text(lv_obj_t * ta, const char * txt)
lv_res_t res = insert_handler(ta, txt);
if(res != LV_RES_OK) return;
/*If a new line was added it shouldn't show edge flash effect*/
bool edge_flash_en = lv_textarea_get_edge_flash(ta);
lv_textarea_set_edge_flash(ta, false);
/*If the textarea is empty, invalidate it to hide the placeholder*/
if(ext->placeholder_txt) {
const char * txt_act = lv_label_get_text(ext->label);
@@ -395,9 +371,6 @@ void lv_textarea_add_text(lv_obj_t * ta, const char * txt)
/*Move the cursor after the new text*/
lv_textarea_set_cursor_pos(ta, lv_textarea_get_cursor_pos(ta) + _lv_txt_get_encoded_length(txt));
/*Revert the original edge flash state*/
lv_textarea_set_edge_flash(ta, edge_flash_en);
lv_event_send(ta, LV_EVENT_VALUE_CHANGED, NULL);
}
@@ -434,12 +407,6 @@ void lv_textarea_del_char(lv_obj_t * ta)
if(txt[0] == '\0') lv_obj_invalidate(ta);
}
/*Don't let 'width == 0' because cursor will not be visible*/
if(lv_obj_get_width(ext->label) == 0) {
lv_style_int_t border_width = lv_obj_get_style_border_width(ta, LV_TEXTAREA_PART_CURSOR);
lv_obj_set_width(ext->label, border_width == 0 ? 1 : border_width);
}
if(ext->pwd_mode != 0) {
uint32_t byte_pos = _lv_txt_encoded_get_byte_id(ext->pwd_tmp, ext->cursor.pos - 1);
_lv_txt_cut(ext->pwd_tmp, ext->cursor.pos - 1, _lv_txt_encoded_size(&ext->pwd_tmp[byte_pos]));
@@ -513,12 +480,6 @@ void lv_textarea_set_text(lv_obj_t * ta, const char * txt)
if(txt_act[0] == '\0') lv_obj_invalidate(ta);
}
/*Don't let 'width == 0' because the cursor will not be visible*/
if(lv_obj_get_width(ext->label) == 0) {
lv_style_int_t border_width = lv_obj_get_style_border_width(ta, LV_TEXTAREA_PART_CURSOR);
lv_obj_set_width(ext->label, border_width == 0 ? 1 : border_width);
}
if(ext->pwd_mode != 0) {
ext->pwd_tmp = lv_mem_realloc(ext->pwd_tmp, strlen(txt) + 1);
LV_ASSERT_MEM(ext->pwd_tmp);
@@ -619,9 +580,9 @@ void lv_textarea_set_cursor_pos(lv_obj_t * ta, int32_t pos)
/*Position the label to make the cursor visible*/
lv_obj_t * label_par = lv_obj_get_parent(ext->label);
lv_point_t cur_pos;
const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_BG);
lv_style_int_t top = lv_obj_get_style_pad_top(ta, LV_TEXTAREA_PART_BG);
lv_style_int_t bottom = lv_obj_get_style_pad_bottom(ta, LV_TEXTAREA_PART_BG);
const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_MAIN);
lv_style_int_t top = lv_obj_get_style_pad_top(ta, LV_TEXTAREA_PART_MAIN);
lv_style_int_t bottom = lv_obj_get_style_pad_bottom(ta, LV_TEXTAREA_PART_MAIN);
lv_area_t label_cords;
lv_area_t ta_cords;
lv_label_get_letter_pos(ext->label, pos, &cur_pos);
@@ -630,25 +591,25 @@ void lv_textarea_set_cursor_pos(lv_obj_t * ta, int32_t pos)
/*Check the top*/
lv_coord_t font_h = lv_font_get_line_height(font);
if(lv_obj_get_y(label_par) + cur_pos.y < 0) {
lv_obj_set_y(label_par, -cur_pos.y + top);
if(cur_pos.y < lv_obj_get_scroll_top(ta)) {
lv_obj_scroll_to_y(label_par, cur_pos.y, LV_ANIM_ON);
}
/*Check the bottom*/
if(label_cords.y1 + cur_pos.y + font_h + bottom > ta_cords.y2) {
lv_obj_set_y(label_par, -(cur_pos.y - lv_obj_get_height(ta) + font_h + top + bottom));
}
/*Check the left (use the font_h as general unit)*/
if(lv_obj_get_x(label_par) + cur_pos.x < font_h) {
lv_obj_set_x(label_par, -cur_pos.x + font_h);
}
lv_style_int_t right = lv_obj_get_style_pad_right(ta, LV_TEXTAREA_PART_BG);
lv_style_int_t left = lv_obj_get_style_pad_left(ta, LV_TEXTAREA_PART_BG);
/*Check the right (use the font_h as general unit)*/
if(label_cords.x1 + cur_pos.x + font_h + right > ta_cords.x2) {
lv_obj_set_x(label_par, -(cur_pos.x - lv_obj_get_width(ta) + font_h + left + right));
}
// /*Check the bottom*/
// if(label_cords.y1 + cur_pos.y + font_h + bottom > ta_cords.y2) {
// lv_obj_set_y(label_par, -(cur_pos.y - lv_obj_get_height(ta) + font_h + top + bottom));
// }
// /*Check the left (use the font_h as general unit)*/
// if(lv_obj_get_x(label_par) + cur_pos.x < font_h) {
// lv_obj_set_x(label_par, -cur_pos.x + font_h);
// }
//
// lv_style_int_t right = lv_obj_get_style_pad_right(ta, LV_TEXTAREA_PART_MAIN);
// lv_style_int_t left = lv_obj_get_style_pad_left(ta, LV_TEXTAREA_PART_MAIN);
// /*Check the right (use the font_h as general unit)*/
// if(label_cords.x1 + cur_pos.x + font_h + right > ta_cords.x2) {
// lv_obj_set_x(label_par, -(cur_pos.x - lv_obj_get_width(ta) + font_h + left + right));
// }
ext->cursor.valid_x = cur_pos.x;
@@ -757,27 +718,20 @@ void lv_textarea_set_one_line(lv_obj_t * ta, bool en)
lv_label_align_t old_align = lv_label_get_align(ext->label);
if(en) {
lv_style_int_t top = lv_obj_get_style_pad_top(ta, LV_TEXTAREA_PART_BG);
lv_style_int_t bottom = lv_obj_get_style_pad_bottom(ta, LV_TEXTAREA_PART_BG);
lv_style_int_t left = lv_obj_get_style_pad_left(ta, LV_TEXTAREA_PART_BG);
const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_BG);
const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_MAIN);
lv_coord_t font_h = lv_font_get_line_height(font);
ext->one_line = 1;
lv_page_set_scrollable_fit2(ta, LV_FIT_MAX, LV_FIT_PARENT);
lv_obj_set_height(ta, font_h + top + bottom);
lv_obj_set_content_height(ta, font_h);
lv_label_set_long_mode(ext->label, LV_LABEL_LONG_EXPAND);
lv_obj_set_pos(lv_page_get_scrollable(ta), left, top);
lv_obj_scroll_to(ta, 0, 0, LV_ANIM_OFF);
}
else {
lv_style_int_t top = lv_obj_get_style_pad_top(ta, LV_TEXTAREA_PART_BG);
lv_style_int_t left = lv_obj_get_style_pad_left(ta, LV_TEXTAREA_PART_BG);
ext->one_line = 0;
lv_page_set_scrollable_fit2(ta, LV_FIT_PARENT, LV_FIT_TIGHT);
lv_label_set_long_mode(ext->label, LV_LABEL_LONG_BREAK);
lv_obj_set_height(ta, LV_TEXTAREA_DEF_HEIGHT);
lv_obj_set_pos(lv_page_get_scrollable(ta), left, top);
lv_obj_scroll_to(ta, 0, 0, LV_ANIM_OFF);
}
/* `refr_cursor_area` is called at the end of lv_ta_set_text_align */
@@ -804,15 +758,13 @@ void lv_textarea_set_text_align(lv_obj_t * ta, lv_label_align_t align)
/*Normal left align. Just let the text expand*/
if(align == LV_LABEL_ALIGN_LEFT) {
lv_label_set_long_mode(label, LV_LABEL_LONG_EXPAND);
lv_page_set_scrollable_fit2(ta, LV_FIT_MAX, LV_FIT_PARENT);
lv_label_set_align(label, align);
}
/*Else use fix label width equal to the Text area width*/
else {
lv_label_set_long_mode(label, LV_LABEL_LONG_CROP);
lv_obj_set_width(label, lv_page_get_width_fit(ta));
lv_obj_set_width(label, lv_obj_get_width_fit(ta));
lv_label_set_align(label, align);
lv_page_set_scrollable_fit2(ta, LV_FIT_PARENT, LV_FIT_PARENT);
}
}
@@ -1227,8 +1179,8 @@ void lv_textarea_cursor_down(lv_obj_t * ta)
/*Increment the y with one line and keep the valid x*/
lv_style_int_t line_space = lv_obj_get_style_text_line_space(ta, LV_TEXTAREA_PART_BG);
const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_BG);
lv_style_int_t line_space = lv_obj_get_style_text_line_space(ta, LV_TEXTAREA_PART_MAIN);
const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_MAIN);
lv_coord_t font_h = lv_font_get_line_height(font);
pos.y += font_h + line_space + 1;
pos.x = ext->cursor.valid_x;
@@ -1259,8 +1211,8 @@ void lv_textarea_cursor_up(lv_obj_t * ta)
lv_label_get_letter_pos(ext->label, lv_textarea_get_cursor_pos(ta), &pos);
/*Decrement the y with one line and keep the valid x*/
lv_style_int_t line_space = lv_obj_get_style_text_line_space(ta, LV_TEXTAREA_PART_BG);
const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_BG);
lv_style_int_t line_space = lv_obj_get_style_text_line_space(ta, LV_TEXTAREA_PART_MAIN);
const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_MAIN);
lv_coord_t font_h = lv_font_get_line_height(font);
pos.y -= font_h + line_space - 1;
pos.x = ext->cursor.valid_x;
@@ -1295,103 +1247,16 @@ static lv_design_res_t lv_textarea_design(lv_obj_t * ta, const lv_area_t * clip_
else if(mode == LV_DESIGN_DRAW_MAIN) {
/*Draw the object*/
ancestor_design(ta, clip_area, mode);
draw_placeholder(ta, clip_area);
}
else if(mode == LV_DESIGN_DRAW_POST) {
ancestor_design(ta, clip_area, mode);
draw_cursor(ta, clip_area);
}
return LV_DESIGN_RES_OK;
}
/**
* An extended scrollable design of the page. Calls the normal design function and draws a cursor.
* @param scrl pointer to the scrollable part of the Text area
* @param clip_area the object will be drawn only in this area
* @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area
* (return 'true' if yes)
* LV_DESIGN_DRAW_MAIN: draw the object (always return 'true')
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
* @return return true/false, depends on 'mode'
*/
static lv_design_res_t lv_textarea_scrollable_design(lv_obj_t * scrl, const lv_area_t * clip_area,
lv_design_mode_t mode)
{
if(mode == LV_DESIGN_COVER_CHK) {
/*Return false if the object is not covers the mask_p area*/
return scrl_design(scrl, clip_area, mode);
}
else if(mode == LV_DESIGN_DRAW_MAIN) {
/*Draw the object*/
scrl_design(scrl, clip_area, mode);
}
else if(mode == LV_DESIGN_DRAW_POST) {
scrl_design(scrl, clip_area, mode);
lv_obj_t * ta = lv_obj_get_parent(scrl);
lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta);
const char * txt = lv_label_get_text(ext->label);
/*Draw the place holder*/
if(txt[0] == '\0' && ext->placeholder_txt && ext->placeholder_txt[0] != 0) {
lv_draw_label_dsc_t ph_dsc;
lv_draw_label_dsc_init(&ph_dsc);
lv_obj_init_draw_label_dsc(ta, LV_TEXTAREA_PART_PLACEHOLDER, &ph_dsc);
switch(lv_label_get_align(ext->label)) {
case LV_LABEL_ALIGN_CENTER:
ph_dsc.flag |= LV_TXT_FLAG_CENTER;
break;
case LV_LABEL_ALIGN_RIGHT:
ph_dsc.flag |= LV_TXT_FLAG_RIGHT;
break;
default:
break;
}
if(ext->one_line) ph_dsc.flag |= LV_TXT_FLAG_EXPAND;
lv_draw_label(&scrl->coords, clip_area, &ph_dsc, ext->placeholder_txt, NULL);
}
/*Draw the cursor*/
if(ext->cursor.hidden || ext->cursor.state == 0) {
return LV_DESIGN_RES_OK; /*The cursor is not visible now*/
}
lv_draw_rect_dsc_t cur_dsc;
lv_draw_rect_dsc_init(&cur_dsc);
lv_obj_init_draw_rect_dsc(ta, LV_TEXTAREA_PART_CURSOR, &cur_dsc);
/*Draw he cursor according to the type*/
lv_area_t cur_area;
lv_area_copy(&cur_area, &ext->cursor.area);
cur_area.x1 += ext->label->coords.x1;
cur_area.y1 += ext->label->coords.y1;
cur_area.x2 += ext->label->coords.x1;
cur_area.y2 += ext->label->coords.y1;
lv_draw_rect(&cur_area, clip_area, &cur_dsc);
char letter_buf[8] = {0};
_lv_memcpy(letter_buf, &txt[ext->cursor.txt_byte_pos], _lv_txt_encoded_size(&txt[ext->cursor.txt_byte_pos]));
if(cur_dsc.bg_opa == LV_OPA_COVER) {
lv_style_int_t left = lv_obj_get_style_pad_left(ta, LV_TEXTAREA_PART_CURSOR);
lv_style_int_t top = lv_obj_get_style_pad_top(ta, LV_TEXTAREA_PART_CURSOR);
cur_area.x1 += left;
cur_area.y1 += top;
lv_draw_label_dsc_t cur_label_dsc;
lv_draw_label_dsc_init(&cur_label_dsc);
lv_obj_init_draw_label_dsc(ta, LV_TEXTAREA_PART_CURSOR, &cur_label_dsc);
lv_draw_label(&cur_area, clip_area, &cur_label_dsc, letter_buf, NULL);
}
}
return LV_DESIGN_RES_OK;
}
/**
* Signal function of the text area
* @param ta pointer to a text area object
@@ -1402,41 +1267,38 @@ static lv_design_res_t lv_textarea_scrollable_design(lv_obj_t * scrl, const lv_a
static lv_res_t lv_textarea_signal(lv_obj_t * ta, lv_signal_t sign, void * param)
{
lv_res_t res;
if(sign == LV_SIGNAL_GET_STYLE) {
lv_get_style_info_t * info = param;
info->result = lv_textarea_get_style(ta, info->part);
if(info->result != NULL) return LV_RES_OK;
else return ancestor_signal(ta, sign, param);
}
else if(sign == LV_SIGNAL_GET_STATE_DSC) {
return ancestor_signal(ta, sign, param);
}
/* Include the ancient signal function */
res = ancestor_signal(ta, 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_textarea_ext_t * ext = lv_obj_get_ext_attr(ta);
if(sign == LV_SIGNAL_CLEANUP) {
if(sign == LV_SIGNAL_GET_TYPE) {
return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
}
else if(sign == LV_SIGNAL_GET_STYLE) {
lv_get_style_info_t * info = param;
info->result = lv_textarea_get_style(ta, info->part);
if(info->result != NULL) return LV_RES_OK;
}
else if(sign == LV_SIGNAL_CLEANUP) {
if(ext->pwd_tmp != NULL) lv_mem_free(ext->pwd_tmp);
if(ext->placeholder_txt != NULL) lv_mem_free(ext->placeholder_txt);
ext->pwd_tmp = NULL;
ext->placeholder_txt = NULL;
lv_obj_clean_style_list(ta, LV_TEXTAREA_PART_CURSOR);
lv_obj_clean_style_list(ta, LV_TEXTAREA_PART_PLACEHOLDER);
_lv_obj_reset_style_list_no_refr(ta, LV_TEXTAREA_PART_CURSOR);
_lv_obj_reset_style_list_no_refr(ta, LV_TEXTAREA_PART_PLACEHOLDER);
/* (The created label will be deleted automatically) */
}
else if(sign == LV_SIGNAL_STYLE_CHG) {
if(ext->label) {
if(ext->one_line) {
lv_style_int_t top = lv_obj_get_style_pad_top(ta, LV_TEXTAREA_PART_BG);
lv_style_int_t bottom = lv_obj_get_style_pad_bottom(ta, LV_TEXTAREA_PART_BG);
const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_BG);
lv_style_int_t top = lv_obj_get_style_pad_top(ta, LV_TEXTAREA_PART_MAIN);
lv_style_int_t bottom = lv_obj_get_style_pad_bottom(ta, LV_TEXTAREA_PART_MAIN);
const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_MAIN);
/*In one line mode refresh the Text Area height because 'vpad' can modify it*/
lv_coord_t font_h = lv_font_get_line_height(font);
@@ -1445,7 +1307,7 @@ static lv_res_t lv_textarea_signal(lv_obj_t * ta, lv_signal_t sign, void * param
}
else {
/*In not one line mode refresh the Label width because 'hpad' can modify it*/
lv_obj_set_width(ext->label, lv_page_get_width_fit(ta));
lv_obj_set_width(ext->label, lv_obj_get_width_fit(ta));
lv_obj_set_pos(ext->label, 0, 0); /*Be sure the Label is in the correct position*/
}
@@ -1457,7 +1319,7 @@ static lv_res_t lv_textarea_signal(lv_obj_t * ta, lv_signal_t sign, void * param
/*Set the label width according to the text area width*/
if(ext->label) {
if(lv_obj_get_width(ta) != lv_area_get_width(param) || lv_obj_get_height(ta) != lv_area_get_height(param)) {
lv_obj_set_width(ext->label, lv_page_get_width_fit(ta));
lv_obj_set_width(ext->label, lv_obj_get_width_fit(ta));
lv_obj_set_pos(ext->label, 0, 0);
lv_label_set_text(ext->label, NULL); /*Refresh the label*/
@@ -1504,57 +1366,6 @@ static lv_res_t lv_textarea_signal(lv_obj_t * ta, lv_signal_t sign, void * param
return res;
}
/**
* Signal function of the scrollable part of the text area
* @param scrl pointer to scrollable part of a text area object
* @param sign a signal type from lv_signal_t enum
* @param param pointer to a signal specific variable
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
*/
static lv_res_t lv_textarea_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, void * param)
{
lv_res_t res;
/* Include the ancient signal function */
res = 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 * ta = lv_obj_get_parent(scrl);
lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta);
if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
/*Set ext. size because the cursor might be out of this object*/
lv_style_int_t line_space = lv_obj_get_style_text_line_space(ta, LV_TEXTAREA_PART_BG);
const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_BG);
lv_coord_t font_h = lv_font_get_line_height(font);
scrl->ext_draw_pad = LV_MATH_MAX(scrl->ext_draw_pad, line_space + font_h);
}
else if(sign == LV_SIGNAL_COORD_CHG) {
/*Set the label width according to the text area width*/
if(ext->label) {
if(lv_obj_get_width(scrl) != lv_area_get_width(param) ||
lv_obj_get_height(scrl) != lv_area_get_height(param)) {
lv_obj_set_width(ext->label, lv_page_get_width_fit(ta));
lv_obj_set_pos(ext->label, 0, 0);
lv_label_set_text(ext->label, NULL); /*Refresh the label*/
refr_cursor_area(ta);
}
}
}
else if(sign == LV_SIGNAL_PRESSING || sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_PRESS_LOST ||
sign == LV_SIGNAL_RELEASED) {
update_cursor_position_on_click(ta, sign, (lv_indev_t *)param);
}
return res;
}
/**
* Get the style descriptor of a part of the object
* @param page pointer the object
@@ -1569,20 +1380,12 @@ static lv_style_list_t * lv_textarea_get_style(lv_obj_t * ta, uint8_t part)
lv_style_list_t * style_dsc_p;
switch(part) {
case LV_TEXTAREA_PART_BG:
case LV_TEXTAREA_PART_MAIN:
style_dsc_p = &ta->style_list;
break;
case LV_TEXTAREA_PART_SCROLLBAR:
style_dsc_p = &ext->page.scrlbar.style;
break;
case LV_TEXTAREA_PART_CURSOR:
style_dsc_p = &ext->cursor.style;
break;
#if LV_USE_ANIMATION
case LV_TEXTAREA_PART_EDGE_FLASH:
style_dsc_p = &ext->page.edge_flash.style;
break;
#endif
case LV_TEXTAREA_PART_PLACEHOLDER:
style_dsc_p = &ext->style_placeholder;
break;
@@ -1654,7 +1457,7 @@ static void pwd_char_hider(lv_obj_t * ta)
if(enc_len == 0) return;
/*If the textarea's font has "bullet" character use it else fallback to "*"*/
const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_BG);
const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_MAIN);
lv_font_glyph_dsc_t g;
bool has_bullet;
has_bullet = lv_font_get_glyph_dsc(font, &g, LV_TEXTAREA_PWD_BULLET_UNICODE, 0);
@@ -1715,8 +1518,8 @@ static void refr_cursor_area(lv_obj_t * ta)
{
lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta);
const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_BG);
lv_style_int_t line_space = lv_obj_get_style_text_line_space(ta, LV_TEXTAREA_PART_BG);
const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_MAIN);
lv_style_int_t line_space = lv_obj_get_style_text_line_space(ta, LV_TEXTAREA_PART_MAIN);
uint32_t cur_pos = lv_textarea_get_cursor_pos(ta);
const char * txt = lv_label_get_text(ext->label);
@@ -1796,7 +1599,6 @@ static void refr_cursor_area(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_textarea_ext_t * ext = lv_obj_get_ext_attr(ta);
@@ -1926,4 +1728,72 @@ static lv_res_t insert_handler(lv_obj_t * ta, const char * txt)
return LV_RES_OK;
}
static void draw_placeholder(lv_obj_t * ta, const lv_area_t * clip_area)
{
lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta);
const char * txt = lv_label_get_text(ext->label);
/*Draw the place holder*/
if(txt[0] == '\0' && ext->placeholder_txt && ext->placeholder_txt[0] != 0) {
lv_draw_label_dsc_t ph_dsc;
lv_draw_label_dsc_init(&ph_dsc);
lv_obj_init_draw_label_dsc(ta, LV_TEXTAREA_PART_PLACEHOLDER, &ph_dsc);
switch(lv_label_get_align(ext->label)) {
case LV_LABEL_ALIGN_CENTER:
ph_dsc.flag |= LV_TXT_FLAG_CENTER;
break;
case LV_LABEL_ALIGN_RIGHT:
ph_dsc.flag |= LV_TXT_FLAG_RIGHT;
break;
default:
break;
}
if(ext->one_line) ph_dsc.flag |= LV_TXT_FLAG_EXPAND;
lv_draw_label(&ta->coords, clip_area, &ph_dsc, ext->placeholder_txt, NULL);
}
}
static void draw_cursor(lv_obj_t * ta, const lv_area_t * clip_area)
{
lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta);
const char * txt = lv_label_get_text(ext->label);
/*Draw the cursor*/
if(ext->cursor.hidden || ext->cursor.state == 0) {
return; /*The cursor is not visible now*/
}
lv_draw_rect_dsc_t cur_dsc;
lv_draw_rect_dsc_init(&cur_dsc);
lv_obj_init_draw_rect_dsc(ta, LV_TEXTAREA_PART_CURSOR, &cur_dsc);
/*Draw he cursor according to the type*/
lv_area_t cur_area;
lv_area_copy(&cur_area, &ext->cursor.area);
cur_area.x1 += ext->label->coords.x1;
cur_area.y1 += ext->label->coords.y1;
cur_area.x2 += ext->label->coords.x1;
cur_area.y2 += ext->label->coords.y1;
lv_draw_rect(&cur_area, clip_area, &cur_dsc);
char letter_buf[8] = {0};
_lv_memcpy(letter_buf, &txt[ext->cursor.txt_byte_pos], _lv_txt_encoded_size(&txt[ext->cursor.txt_byte_pos]));
if(cur_dsc.bg_opa == LV_OPA_COVER) {
lv_style_int_t left = lv_obj_get_style_pad_left(ta, LV_TEXTAREA_PART_CURSOR);
lv_style_int_t top = lv_obj_get_style_pad_top(ta, LV_TEXTAREA_PART_CURSOR);
cur_area.x1 += left;
cur_area.y1 += top;
lv_draw_label_dsc_t cur_label_dsc;
lv_draw_label_dsc_init(&cur_label_dsc);
lv_obj_init_draw_label_dsc(ta, LV_TEXTAREA_PART_CURSOR, &cur_label_dsc);
lv_draw_label(&cur_area, clip_area, &cur_label_dsc, letter_buf, NULL);
}
}
#endif