Text Area (lv_textarea)
Overview
The Text Area is a Base Widget with a Label (lv_label) and a cursor on it. Text or characters can be added to it. Long lines are wrapped and when the text becomes long enough, the Text Area can be scrolled.
One-line mode and password modes are supported.
Parts and Styles
LV_PART_MAIN
The background of the Text Area; uses the typical background style properties and the text related style properties includingtext_align
to align the text to the left, right or center.LV_PART_SCROLLBAR
The scrollbar that is shown when the text is longer than its height.LV_PART_SELECTED
Determines the style of the selected text. Onlytext_color
andbg_color
style properties can be used.bg_color
should be set directly on the label of the Text Area.LV_PART_CURSOR
Marks the position where the characters are inserted. The cursor's area is always the bounding box of the current character. A block cursor can be created by adding a background color and background opacity toLV_PART_CURSOR
's style. To create a "bar" cursor leave the cursor transparent and set a left border. Theanim_time
style property sets the cursor's blink time.LV_PART_TEXTAREA_PLACEHOLDER
Unique to Text Area; allows styling the placeholder text.
Usage
Adding text
You can insert text or characters to the current cursor's position with:
lv_textarea_add_char(textarea, 'c')
lv_textarea_add_text(textarea, "insert this text")
To add wide characters like 'á'
, 'ß'
or CJK characters, use
lv_textarea_add_text(textarea, "á").
lv_textarea_set_text(textarea, "New text") replaces all existing text with "New text".
Placeholder text
Placeholder text is text that is displayed when the Text Area is empty. This can be a handy way to provide the end user with a hint about what to type there.
Specify placeholder text using lv_textarea_set_placeholder_text(textarea, "Placeholder text").
Delete character
To delete the character to the left of the current cursor position, use lv_textarea_delete_char(textarea).
To delete to the right, use lv_textarea_delete_char_forward(textarea)
Moving the cursor
The cursor position can be modified programmatically using
lv_textarea_set_cursor_pos(textarea, corsor_pos) where cursor_pos
is
the zero-based index of the character the cursor should be placed in front of.
LV_TEXTAREA_CURSOR_LAST
can be passed to mean "after the
last character"
You can move the cursor one character-position (or line) at a time with
lv_textarea_cursor_right(textarea)
lv_textarea_cursor_left(textarea)
lv_textarea_cursor_up(textarea)
lv_textarea_cursor_down(textarea)
If lv_textarea_set_cursor_click_pos(textarea, true) is applied, the cursor will jump to the position where the Text Area was clicked.
Hiding the cursor
The cursor is normally always visible. It it can be a good idea to style it
to be visible only in LV_STATE_FOCUSED
state. See Styles
for more information about how to do this.
One-line mode
The Text Area can be configured to keep all text on a single line with lv_textarea_set_one_line(textarea, true). In this mode:
the height is set automatically to show only one line,
line break characters are ignored, and
word wrap is disabled.
Password mode
The Text Area supports password mode which can be enabled with lv_textarea_set_password_mode(textarea, true).
By default, if the •
(Bullet,
U+2022)
character exists in the font, the entered characters are converted to it after
a configurable delay after each new character is entered. If •
does not
exist in the font, *
will be used. You can override the default
"masking" character with lv_textarea_set_password_bullet(textarea, str)
where str
is a NUL-terminated C string. Example:
lv_textarea_set_password_bullet(textarea, "x");
In password mode lv_textarea_get_text(textarea) returns the actual text entered, not the bullet characters.
The visibility time can be adjusted with LV_TEXTAREA_DEF_PWD_SHOW_TIME
in lv_conf.h
.
Accepted characters
You can set a list of accepted characters with
lv_textarea_set_accepted_chars(textarea, list) where list
is a
pointer to a NUL-terminated string, or NULL to accept all characters. Characters
entered not in this list will be ignored.
lv_textarea_set_accepted_chars(textarea, "0123456789.+-");
Max text length
The maximum number of characters can be limited using lv_textarea_set_max_length(textarea, max_char_num).
Very long text
If the text in the Text Area is very long (e.g. > 20k characters), scrolling and
drawing might be slow. However, by setting LV_LABEL_LONG_TXT_HINT
in
lv_conf.h
to a non-zero value, the performance with long text is significantly
improved. It does this by saving some additional information about the current
vertical position of the text shown. With this mode configured, scrolling and drawing
is as fast as with "normal" short text. The cost is 12 extra bytes per label in RAM.
This value is set to 1
by default. If you do not use long text, you can save
12 bytes per label by setting it to 0
.
Selecting text
If LV_LABEL_TEXT_SELECTION
is set to a non-zero value in lv_conf.h
,
some additional functionality (and 8 bytes per label) are added to Label Widgets
and Text Area Widgets, and text-selection functionality is automated in Text Area
Widgets. (If you do not use selected text in your application, you can save 8 bytes
per label in RAM by setting that macro to equate to 0
.)
Any part of the text can be selected if enabled with
lv_textarea_set_text_selection(textarea, true). This works much like
when you select text on your PC with your mouse. If you pass false
to this
function to disable text-selection, any text selected at the time of the call will be
de-selected.
If you need to programmatically deal with selected text, in addition to the
lv_textarea_set_text_selection(textarea, enable) function, the following
is your tool set for doing so. (ta_label
is a pointer to the Text Area's
Label retrieved with ta_label = lv_textarea_get_label(textarea);
.)
lv_textarea_get_text_selection(textarea) tells whether text selection is enabled.
lv_textarea_text_is_selected(textarea) tells whether any text is currently selected.
lv_textarea_clear_selection(textarea) clears current text selection.
lv_label_set_text_selection_start(ta_label, index) where
index
is the zero-based index of the first character of the selected text. PassLV_DRAW_LABEL_NO_TXT_SEL
to specify no text selected.lv_label_set_text_selection_end(ta_label, index) where
index
is the zero-based index of the character just after the selected text. PassLV_DRAW_LABEL_NO_TXT_SEL
to specify no text selected.lv_label_get_text_selection_start(ta_label) zero-based index of the first character of the selected text.
LV_DRAW_LABEL_NO_TXT_SEL
indicates no text selected.lv_label_get_text_selection_end(ta_label) zero-based index of the character just after the selected text.
LV_DRAW_LABEL_NO_TXT_SEL
indicates no text selected.
Normally you won't need these since Text Area automates the text selection process, but if you do need to change the selection programmatically, the above are your tools to do so.
Events
LV_EVENT_INSERT
Sent right before a character or text is inserted. The event parameter is the text about to be inserted. lv_textarea_set_insert_replace(textarea, "New text") can be called from within that event to replace the text to be inserted. The contents of the buffer passed must be survive long enough for the call to lv_timer_handler() that is driving the event to return (after which the Text Area's label will have copied the text). So it should not be a local buffer (created on the stack) where its contents will be destroyed before that happens. Passing""
means "do not insert anything".LV_EVENT_VALUE_CHANGED
Sent when the content of the Text Area has changed.LV_EVENT_READY
Sent whenLV_KEY_ENTER
is pressed (or sent) to a one-line Text Area.
Further Reading
Learn more about Base-Widget Events emitted by all Widgets.
Learn more about Events.
Keys
LV_KEY_UP/DOWN/LEFT/RIGHT
Move the cursorAny character
Add the character to the current cursor position
Further Reading
Learn more about Keys.
Example
Simple Text area
C code
View on GitHub#include "../../lv_examples.h"
#if LV_USE_TEXTAREA && LV_BUILD_EXAMPLES
static void textarea_event_handler(lv_event_t * e)
{
lv_obj_t * ta = lv_event_get_target(e);
LV_UNUSED(ta);
LV_LOG_USER("Enter was pressed. The current text is: %s", lv_textarea_get_text(ta));
}
static void btnm_event_handler(lv_event_t * e)
{
lv_obj_t * obj = lv_event_get_target(e);
lv_obj_t * ta = lv_event_get_user_data(e);
const char * txt = lv_buttonmatrix_get_button_text(obj, lv_buttonmatrix_get_selected_button(obj));
if(lv_strcmp(txt, LV_SYMBOL_BACKSPACE) == 0) lv_textarea_delete_char(ta);
else if(lv_strcmp(txt, LV_SYMBOL_NEW_LINE) == 0) lv_obj_send_event(ta, LV_EVENT_READY, NULL);
else lv_textarea_add_text(ta, txt);
}
void lv_example_textarea_1(void)
{
lv_obj_t * ta = lv_textarea_create(lv_screen_active());
lv_textarea_set_one_line(ta, true);
lv_obj_align(ta, LV_ALIGN_TOP_MID, 0, 10);
lv_obj_add_event_cb(ta, textarea_event_handler, LV_EVENT_READY, ta);
lv_obj_add_state(ta, LV_STATE_FOCUSED); /*To be sure the cursor is visible*/
static const char * btnm_map[] = {"1", "2", "3", "\n",
"4", "5", "6", "\n",
"7", "8", "9", "\n",
LV_SYMBOL_BACKSPACE, "0", LV_SYMBOL_NEW_LINE, ""
};
lv_obj_t * btnm = lv_buttonmatrix_create(lv_screen_active());
lv_obj_set_size(btnm, 200, 150);
lv_obj_align(btnm, LV_ALIGN_BOTTOM_MID, 0, -10);
lv_obj_add_event_cb(btnm, btnm_event_handler, LV_EVENT_VALUE_CHANGED, ta);
lv_obj_remove_flag(btnm, LV_OBJ_FLAG_CLICK_FOCUSABLE); /*To keep the text area focused on button clicks*/
lv_buttonmatrix_set_map(btnm, btnm_map);
}
#endif
Text area with password field
C code
View on GitHub#include "../../lv_examples.h"
#if LV_USE_TEXTAREA && LV_USE_KEYBOARD && LV_BUILD_EXAMPLES
static void ta_event_cb(lv_event_t * e);
static lv_obj_t * kb;
void lv_example_textarea_2(void)
{
/*Create the password box*/
lv_obj_t * pwd_ta = lv_textarea_create(lv_screen_active());
lv_textarea_set_text(pwd_ta, "");
lv_textarea_set_password_mode(pwd_ta, true);
lv_textarea_set_one_line(pwd_ta, true);
lv_obj_set_width(pwd_ta, lv_pct(40));
lv_obj_set_pos(pwd_ta, 5, 20);
lv_obj_add_event_cb(pwd_ta, ta_event_cb, LV_EVENT_ALL, NULL);
/*Create a label and position it above the text box*/
lv_obj_t * pwd_label = lv_label_create(lv_screen_active());
lv_label_set_text(pwd_label, "Password:");
lv_obj_align_to(pwd_label, pwd_ta, LV_ALIGN_OUT_TOP_LEFT, 0, 0);
/*Create the one-line mode text area*/
lv_obj_t * text_ta = lv_textarea_create(lv_screen_active());
lv_textarea_set_one_line(text_ta, true);
lv_textarea_set_password_mode(text_ta, false);
lv_obj_set_width(text_ta, lv_pct(40));
lv_obj_add_event_cb(text_ta, ta_event_cb, LV_EVENT_ALL, NULL);
lv_obj_align(text_ta, LV_ALIGN_TOP_RIGHT, -5, 20);
/*Create a label and position it above the text box*/
lv_obj_t * oneline_label = lv_label_create(lv_screen_active());
lv_label_set_text(oneline_label, "Text:");
lv_obj_align_to(oneline_label, text_ta, LV_ALIGN_OUT_TOP_LEFT, 0, 0);
/*Create a keyboard*/
kb = lv_keyboard_create(lv_screen_active());
lv_obj_set_size(kb, LV_HOR_RES, LV_VER_RES / 2);
lv_keyboard_set_textarea(kb, pwd_ta); /*Focus it on one of the text areas to start*/
/*The keyboard will show Arabic characters if they are enabled */
#if LV_USE_ARABIC_PERSIAN_CHARS && LV_FONT_DEJAVU_16_PERSIAN_HEBREW
lv_obj_set_style_text_font(kb, &lv_font_dejavu_16_persian_hebrew, 0);
lv_obj_set_style_text_font(text_ta, &lv_font_dejavu_16_persian_hebrew, 0);
lv_obj_set_style_text_font(pwd_ta, &lv_font_dejavu_16_persian_hebrew, 0);
#endif
}
static void ta_event_cb(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * ta = lv_event_get_target(e);
if(code == LV_EVENT_CLICKED || code == LV_EVENT_FOCUSED) {
/*Focus on the clicked text area*/
if(kb != NULL) lv_keyboard_set_textarea(kb, ta);
}
else if(code == LV_EVENT_READY) {
LV_LOG_USER("Ready, current text: %s", lv_textarea_get_text(ta));
}
}
#endif
Text auto-formatting
C code
View on GitHub#include "../../lv_examples.h"
#if LV_USE_TEXTAREA && LV_USE_KEYBOARD && LV_BUILD_EXAMPLES
static void ta_event_cb(lv_event_t * e);
static lv_obj_t * kb;
/**
* Automatically format text like a clock. E.g. "12:34"
* Add the ':' automatically.
*/
void lv_example_textarea_3(void)
{
/*Create the text area*/
lv_obj_t * ta = lv_textarea_create(lv_screen_active());
lv_obj_add_event_cb(ta, ta_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
lv_textarea_set_accepted_chars(ta, "0123456789:");
lv_textarea_set_max_length(ta, 5);
lv_textarea_set_one_line(ta, true);
lv_textarea_set_text(ta, "");
/*Create a keyboard*/
kb = lv_keyboard_create(lv_screen_active());
lv_obj_set_size(kb, LV_HOR_RES, LV_VER_RES / 2);
lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_NUMBER);
lv_keyboard_set_textarea(kb, ta);
}
static void ta_event_cb(lv_event_t * e)
{
lv_obj_t * ta = lv_event_get_target(e);
const char * txt = lv_textarea_get_text(ta);
if(txt[0] >= '0' && txt[0] <= '9' &&
txt[1] >= '0' && txt[1] <= '9' &&
txt[2] != ':') {
lv_textarea_set_cursor_pos(ta, 2);
lv_textarea_add_char(ta, ':');
}
}
#endif