mirror of
https://github.com/lvgl/lvgl.git
synced 2026-06-04 06:42:54 +08:00
feat(textarea): only send one event when updating text (#9852)
Arduino Lint / lint (push) Has been cancelled
Build Examples with C++ Compiler / build-examples (push) Has been cancelled
MicroPython CI / Build esp32 port (push) Has been cancelled
MicroPython CI / Build rp2 port (push) Has been cancelled
MicroPython CI / Build stm32 port (push) Has been cancelled
MicroPython CI / Build unix port (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_NORMAL_8BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_SDL - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build ESP IDF ESP32S3 (push) Has been cancelled
C/C++ CI / Run tests with 32bit build (push) Has been cancelled
C/C++ CI / Run tests with 64bit build (push) Has been cancelled
BOM Check / bom-check (push) Has been cancelled
Verify that lv_conf_internal.h matches repository state / verify-conf-internal (push) Has been cancelled
Verify GDB constants are up-to-date / verify-gdb-consts (push) Has been cancelled
Verify the widget property name / verify-property-name (push) Has been cancelled
Verify code formatting / verify-formatting (push) Has been cancelled
Compare file templates with file names / template-check (push) Has been cancelled
Build docs / build-and-deploy (push) Has been cancelled
Test API JSON generator / Test API JSON (push) Has been cancelled
Install LVGL using CMake / build-examples (push) Has been cancelled
Check Makefile / Build using Makefile (push) Has been cancelled
Check Makefile for UEFI / Build using Makefile for UEFI (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/benchmark_results_comment/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/filter_docker_logs/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/serialize_results/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 32b - lv_conf_perf32b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 64b - lv_conf_perf64b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Save PR Number (push) Has been cancelled
Hardware Performance Test / Hardware Performance Benchmark (push) Has been cancelled
Hardware Performance Test / HW Benchmark - Save PR Number (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_32B - Ubuntu (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_64B - Ubuntu (push) Has been cancelled
Port repo release update / run-release-branch-updater (push) Has been cancelled
Verify Font License / verify-font-license (push) Has been cancelled
Verify Kconfig / verify-kconfig (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
Arduino Lint / lint (push) Has been cancelled
Build Examples with C++ Compiler / build-examples (push) Has been cancelled
MicroPython CI / Build esp32 port (push) Has been cancelled
MicroPython CI / Build rp2 port (push) Has been cancelled
MicroPython CI / Build stm32 port (push) Has been cancelled
MicroPython CI / Build unix port (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_NORMAL_8BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_SDL - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build ESP IDF ESP32S3 (push) Has been cancelled
C/C++ CI / Run tests with 32bit build (push) Has been cancelled
C/C++ CI / Run tests with 64bit build (push) Has been cancelled
BOM Check / bom-check (push) Has been cancelled
Verify that lv_conf_internal.h matches repository state / verify-conf-internal (push) Has been cancelled
Verify GDB constants are up-to-date / verify-gdb-consts (push) Has been cancelled
Verify the widget property name / verify-property-name (push) Has been cancelled
Verify code formatting / verify-formatting (push) Has been cancelled
Compare file templates with file names / template-check (push) Has been cancelled
Build docs / build-and-deploy (push) Has been cancelled
Test API JSON generator / Test API JSON (push) Has been cancelled
Install LVGL using CMake / build-examples (push) Has been cancelled
Check Makefile / Build using Makefile (push) Has been cancelled
Check Makefile for UEFI / Build using Makefile for UEFI (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/benchmark_results_comment/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/filter_docker_logs/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/serialize_results/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 32b - lv_conf_perf32b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 64b - lv_conf_perf64b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Save PR Number (push) Has been cancelled
Hardware Performance Test / Hardware Performance Benchmark (push) Has been cancelled
Hardware Performance Test / HW Benchmark - Save PR Number (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_32B - Ubuntu (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_64B - Ubuntu (push) Has been cancelled
Port repo release update / run-release-branch-updater (push) Has been cancelled
Verify Font License / verify-font-license (push) Has been cancelled
Verify Kconfig / verify-kconfig (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
@@ -65,7 +65,9 @@ static void auto_hide_characters(lv_obj_t * obj);
|
|||||||
static void auto_hide_characters_cancel(lv_obj_t * obj);
|
static void auto_hide_characters_cancel(lv_obj_t * obj);
|
||||||
static inline bool is_valid_but_non_printable_char(const uint32_t letter);
|
static inline bool is_valid_but_non_printable_char(const uint32_t letter);
|
||||||
static void lv_textarea_scroll_to_cusor_pos(lv_obj_t * obj, int32_t pos);
|
static void lv_textarea_scroll_to_cusor_pos(lv_obj_t * obj, int32_t pos);
|
||||||
|
static lv_result_t add_char(lv_obj_t * obj, uint32_t c);
|
||||||
|
static void add_text(lv_obj_t * obj, const char * txt);
|
||||||
|
static void set_cursor_pos_internal(lv_obj_t * obj, int32_t pos);
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
**********************/
|
**********************/
|
||||||
@@ -183,72 +185,11 @@ lv_obj_t * lv_textarea_create(lv_obj_t * parent)
|
|||||||
void lv_textarea_add_char(lv_obj_t * obj, uint32_t c)
|
void lv_textarea_add_char(lv_obj_t * obj, uint32_t c)
|
||||||
{
|
{
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||||
|
lv_result_t res = add_char(obj, c);
|
||||||
lv_textarea_t * ta = (lv_textarea_t *)obj;
|
if(res != LV_RESULT_OK) {
|
||||||
|
|
||||||
if(ta->one_line && (c == '\n' || c == '\r')) {
|
|
||||||
LV_LOG_INFO("Text area: line break ignored in one-line mode");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t u32_buf[2];
|
|
||||||
u32_buf[0] = c;
|
|
||||||
u32_buf[1] = 0;
|
|
||||||
|
|
||||||
const char * letter_buf = (char *)&u32_buf;
|
|
||||||
|
|
||||||
uint32_t c2 = c;
|
|
||||||
#if LV_BIG_ENDIAN_SYSTEM
|
|
||||||
if(c != 0) while(*letter_buf == 0) ++letter_buf;
|
|
||||||
|
|
||||||
/*The byte order may or may not need to be swapped here to get correct c_uni below,
|
|
||||||
since lv_textarea_add_text is ordering bytes correctly before calling lv_textarea_add_char.
|
|
||||||
Assume swapping is needed if MSB is zero. May not be foolproof. */
|
|
||||||
if((c != 0) && ((c & 0xff000000) == 0)) {
|
|
||||||
c2 = ((c >> 24) & 0xff) | /*move byte 3 to byte 0*/
|
|
||||||
((c << 8) & 0xff0000) | /*move byte 1 to byte 2*/
|
|
||||||
((c >> 8) & 0xff00) | /*move byte 2 to byte 1*/
|
|
||||||
((c << 24) & 0xff000000); /*byte 0 to byte 3*/
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
lv_result_t res = insert_handler(obj, letter_buf);
|
|
||||||
if(res != LV_RESULT_OK) return;
|
|
||||||
|
|
||||||
uint32_t c_uni = lv_text_encoded_next((const char *)&c2, NULL);
|
|
||||||
|
|
||||||
if(char_is_accepted(obj, c_uni) == false) {
|
|
||||||
LV_LOG_INFO("Character is not accepted by the text area (too long text or not in the accepted list)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ta->pwd_mode) pwd_char_hider(obj); /*Make sure all the current text contains only '*'*/
|
|
||||||
|
|
||||||
/*If the textarea is empty, invalidate it to hide the placeholder*/
|
|
||||||
if(ta->placeholder_txt) {
|
|
||||||
const char * txt = lv_label_get_text(ta->label);
|
|
||||||
if(txt[0] == '\0') lv_obj_invalidate(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_label_ins_text(ta->label, ta->cursor.pos, letter_buf); /*Insert the character*/
|
|
||||||
lv_textarea_clear_selection(obj); /*Clear selection*/
|
|
||||||
|
|
||||||
if(ta->pwd_mode) {
|
|
||||||
/*+2: the new char + \0*/
|
|
||||||
size_t realloc_size = lv_strlen(ta->pwd_tmp) + lv_strlen(letter_buf) + 1;
|
|
||||||
ta->pwd_tmp = lv_realloc(ta->pwd_tmp, realloc_size);
|
|
||||||
LV_ASSERT_MALLOC(ta->pwd_tmp);
|
|
||||||
if(ta->pwd_tmp == NULL) return;
|
|
||||||
|
|
||||||
lv_text_ins(ta->pwd_tmp, ta->cursor.pos, (const char *)letter_buf);
|
|
||||||
|
|
||||||
/*Auto hide characters*/
|
|
||||||
auto_hide_characters(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Move the cursor after the new character*/
|
|
||||||
lv_textarea_set_cursor_pos(obj, lv_textarea_get_cursor_pos(obj) + 1);
|
lv_textarea_set_cursor_pos(obj, lv_textarea_get_cursor_pos(obj) + 1);
|
||||||
|
|
||||||
lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL);
|
lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,11 +204,7 @@ void lv_textarea_add_text(lv_obj_t * obj, const char * txt)
|
|||||||
|
|
||||||
/*Add the character one-by-one if not all characters are accepted or there is character limit.*/
|
/*Add the character one-by-one if not all characters are accepted or there is character limit.*/
|
||||||
if(lv_textarea_get_accepted_chars(obj) || lv_textarea_get_max_length(obj)) {
|
if(lv_textarea_get_accepted_chars(obj) || lv_textarea_get_max_length(obj)) {
|
||||||
uint32_t i = 0;
|
add_text(obj, txt);
|
||||||
while(txt[i] != '\0') {
|
|
||||||
uint32_t c = lv_text_encoded_next(txt, &i);
|
|
||||||
lv_textarea_add_char(obj, lv_text_unicode_to_encoded(c));
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,11 +313,7 @@ void lv_textarea_set_text(lv_obj_t * obj, const char * txt)
|
|||||||
if(ta->pwd_mode) {
|
if(ta->pwd_mode) {
|
||||||
ta->pwd_tmp[0] = '\0'; /*Clear the password too*/
|
ta->pwd_tmp[0] = '\0'; /*Clear the password too*/
|
||||||
}
|
}
|
||||||
uint32_t i = 0;
|
add_text(obj, txt);
|
||||||
while(txt[i] != '\0') {
|
|
||||||
uint32_t c = lv_text_encoded_next(txt, &i);
|
|
||||||
lv_textarea_add_char(obj, lv_text_unicode_to_encoded(c));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lv_label_set_text(ta->label, txt);
|
lv_label_set_text(ta->label, txt);
|
||||||
@@ -401,8 +334,6 @@ void lv_textarea_set_text(lv_obj_t * obj, const char * txt)
|
|||||||
|
|
||||||
pwd_char_hider(obj);
|
pwd_char_hider(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lv_textarea_set_placeholder_text(lv_obj_t * obj, const char * txt)
|
void lv_textarea_set_placeholder_text(lv_obj_t * obj, const char * txt)
|
||||||
@@ -437,17 +368,7 @@ void lv_textarea_set_placeholder_text(lv_obj_t * obj, const char * txt)
|
|||||||
void lv_textarea_set_cursor_pos(lv_obj_t * obj, int32_t pos)
|
void lv_textarea_set_cursor_pos(lv_obj_t * obj, int32_t pos)
|
||||||
{
|
{
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||||
|
set_cursor_pos_internal(obj, pos);
|
||||||
lv_textarea_t * ta = (lv_textarea_t *)obj;
|
|
||||||
if((uint32_t)ta->cursor.pos == (uint32_t)pos) return;
|
|
||||||
|
|
||||||
uint32_t len = lv_text_get_encoded_length(lv_label_get_text(ta->label));
|
|
||||||
|
|
||||||
if(pos < 0) pos = len + pos;
|
|
||||||
|
|
||||||
if(pos > (int32_t)len || pos == LV_TEXTAREA_CURSOR_LAST) pos = len;
|
|
||||||
|
|
||||||
ta->cursor.pos = pos;
|
|
||||||
|
|
||||||
/*Position the label to make the cursor visible*/
|
/*Position the label to make the cursor visible*/
|
||||||
lv_obj_update_layout(obj);
|
lv_obj_update_layout(obj);
|
||||||
@@ -1530,4 +1451,117 @@ static void lv_textarea_scroll_to_cusor_pos(lv_obj_t * obj, int32_t pos)
|
|||||||
refr_cursor_area(obj);
|
refr_cursor_area(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_cursor_pos_internal(lv_obj_t * obj, int32_t pos)
|
||||||
|
{
|
||||||
|
lv_textarea_t * ta = (lv_textarea_t *)obj;
|
||||||
|
if((uint32_t)ta->cursor.pos == (uint32_t)pos) return;
|
||||||
|
|
||||||
|
uint32_t len = lv_text_get_encoded_length(lv_label_get_text(ta->label));
|
||||||
|
|
||||||
|
if(pos < 0) pos = len + pos;
|
||||||
|
|
||||||
|
if(pos > (int32_t)len || pos == LV_TEXTAREA_CURSOR_LAST) pos = len;
|
||||||
|
|
||||||
|
ta->cursor.pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_text(lv_obj_t * obj, const char * txt)
|
||||||
|
{
|
||||||
|
lv_textarea_t * ta = (lv_textarea_t *)obj;
|
||||||
|
uint32_t i = 0;
|
||||||
|
bool text_changed = false;
|
||||||
|
while(txt[i] != '\0') {
|
||||||
|
uint32_t c = lv_text_encoded_next(txt, &i);
|
||||||
|
lv_result_t res = add_char(obj, lv_text_unicode_to_encoded(c));
|
||||||
|
if(res != LV_RESULT_OK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
set_cursor_pos_internal(obj, ta->cursor.pos + 1);
|
||||||
|
text_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!text_changed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_obj_update_layout(obj);
|
||||||
|
lv_textarea_scroll_to_cusor_pos(obj, ta->cursor.pos);
|
||||||
|
refr_cursor_area(obj);
|
||||||
|
/*Move the cursor after the new character*/
|
||||||
|
lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
static lv_result_t add_char(lv_obj_t * obj, uint32_t c)
|
||||||
|
{
|
||||||
|
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||||
|
|
||||||
|
lv_textarea_t * ta = (lv_textarea_t *)obj;
|
||||||
|
|
||||||
|
if(ta->one_line && (c == '\n' || c == '\r')) {
|
||||||
|
LV_LOG_INFO("Text area: line break ignored in one-line mode");
|
||||||
|
return LV_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t u32_buf[2];
|
||||||
|
u32_buf[0] = c;
|
||||||
|
u32_buf[1] = 0;
|
||||||
|
|
||||||
|
const char * letter_buf = (char *)&u32_buf;
|
||||||
|
|
||||||
|
uint32_t c2 = c;
|
||||||
|
#if LV_BIG_ENDIAN_SYSTEM
|
||||||
|
if(c != 0) while(*letter_buf == 0) ++letter_buf;
|
||||||
|
|
||||||
|
/*The byte order may or may not need to be swapped here to get correct c_uni below,
|
||||||
|
since lv_textarea_add_text is ordering bytes correctly before calling lv_textarea_add_char.
|
||||||
|
Assume swapping is needed if MSB is zero. May not be foolproof. */
|
||||||
|
if((c != 0) && ((c & 0xff000000) == 0)) {
|
||||||
|
c2 = ((c >> 24) & 0xff) | /*move byte 3 to byte 0*/
|
||||||
|
((c << 8) & 0xff0000) | /*move byte 1 to byte 2*/
|
||||||
|
((c >> 8) & 0xff00) | /*move byte 2 to byte 1*/
|
||||||
|
((c << 24) & 0xff000000); /*byte 0 to byte 3*/
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
lv_result_t res = insert_handler(obj, letter_buf);
|
||||||
|
if(res != LV_RESULT_OK) return res;
|
||||||
|
|
||||||
|
uint32_t c_uni = lv_text_encoded_next((const char *)&c2, NULL);
|
||||||
|
|
||||||
|
if(char_is_accepted(obj, c_uni) == false) {
|
||||||
|
LV_LOG_INFO("Character is not accepted by the text area (too long text or not in the accepted list)");
|
||||||
|
return LV_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ta->pwd_mode) pwd_char_hider(obj); /*Make sure all the current text contains only '*'*/
|
||||||
|
|
||||||
|
/*If the textarea is empty, invalidate it to hide the placeholder*/
|
||||||
|
if(ta->placeholder_txt) {
|
||||||
|
const char * txt = lv_label_get_text(ta->label);
|
||||||
|
if(txt[0] == '\0') lv_obj_invalidate(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to allocate memory for pwd mode first, if we fail we don't insert the character either*/
|
||||||
|
if(ta->pwd_mode) {
|
||||||
|
/*+2: the new char + \0*/
|
||||||
|
size_t realloc_size = lv_strlen(ta->pwd_tmp) + lv_strlen(letter_buf) + 1;
|
||||||
|
char * pwd_tmp = lv_realloc(ta->pwd_tmp, realloc_size);
|
||||||
|
LV_ASSERT_MALLOC(pwd_tmp);
|
||||||
|
if(!pwd_tmp) return LV_RESULT_INVALID;
|
||||||
|
ta->pwd_tmp = pwd_tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
lv_label_ins_text(ta->label, ta->cursor.pos, letter_buf); /*Insert the character*/
|
||||||
|
lv_textarea_clear_selection(obj); /*Clear selection*/
|
||||||
|
|
||||||
|
if(ta->pwd_mode) {
|
||||||
|
lv_text_ins(ta->pwd_tmp, ta->cursor.pos, (const char *)letter_buf);
|
||||||
|
|
||||||
|
/*Auto hide characters*/
|
||||||
|
auto_hide_characters(obj);
|
||||||
|
}
|
||||||
|
return LV_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -233,4 +233,85 @@ void test_textarea_properties(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t event_count;
|
||||||
|
static void event_counter_cb(lv_event_t * e)
|
||||||
|
{
|
||||||
|
LV_UNUSED(e);
|
||||||
|
event_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_textarea_set_text_should_emit_value_changed_event_only_once(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
const char * accepted_list = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ!,";
|
||||||
|
const char * text = "Hello, World!";
|
||||||
|
const uint32_t text_len = 13U; /* strlen("Hello, World!") */
|
||||||
|
|
||||||
|
/* Test 1: with accepted_chars set */
|
||||||
|
event_count = 0;
|
||||||
|
lv_textarea_set_accepted_chars(textarea, accepted_list);
|
||||||
|
lv_obj_add_event_cb(textarea, event_counter_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
||||||
|
|
||||||
|
lv_textarea_set_text(textarea, text);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_STRING(text, lv_textarea_get_text(textarea));
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(1U, event_count);
|
||||||
|
|
||||||
|
/* Test 2: with max_length set to exactly the text length — if set_text
|
||||||
|
* doesn't clear before re-adding chars, char_is_accepted sees the buffer
|
||||||
|
* as already full and rejects every character, leaving the textarea empty */
|
||||||
|
lv_obj_clean(active_screen);
|
||||||
|
textarea = lv_textarea_create(active_screen);
|
||||||
|
|
||||||
|
event_count = 0;
|
||||||
|
lv_textarea_set_max_length(textarea, text_len);
|
||||||
|
lv_obj_add_event_cb(textarea, event_counter_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
||||||
|
|
||||||
|
lv_textarea_set_text(textarea, text);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_STRING(text, lv_textarea_get_text(textarea));
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(1U, event_count);
|
||||||
|
|
||||||
|
/* Test 3: with both accepted_chars and max_length set */
|
||||||
|
lv_obj_clean(active_screen);
|
||||||
|
textarea = lv_textarea_create(active_screen);
|
||||||
|
|
||||||
|
event_count = 0;
|
||||||
|
lv_textarea_set_accepted_chars(textarea, accepted_list);
|
||||||
|
lv_textarea_set_max_length(textarea, text_len);
|
||||||
|
lv_obj_add_event_cb(textarea, event_counter_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
||||||
|
|
||||||
|
lv_textarea_set_text(textarea, text);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_STRING(text, lv_textarea_get_text(textarea));
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(1U, event_count);
|
||||||
|
|
||||||
|
/* Test 4: empty string — no characters to add, no event */
|
||||||
|
lv_obj_clean(active_screen);
|
||||||
|
textarea = lv_textarea_create(active_screen);
|
||||||
|
|
||||||
|
event_count = 0;
|
||||||
|
lv_textarea_set_accepted_chars(textarea, accepted_list);
|
||||||
|
lv_textarea_set_max_length(textarea, text_len);
|
||||||
|
lv_obj_add_event_cb(textarea, event_counter_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
||||||
|
|
||||||
|
lv_textarea_set_text(textarea, "");
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_STRING("", lv_textarea_get_text(textarea));
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(0U, event_count);
|
||||||
|
|
||||||
|
/* Test 5: all characters rejected by accepted_chars — no characters added, no event */
|
||||||
|
lv_obj_clean(active_screen);
|
||||||
|
textarea = lv_textarea_create(active_screen);
|
||||||
|
|
||||||
|
event_count = 0;
|
||||||
|
lv_textarea_set_accepted_chars(textarea, accepted_list);
|
||||||
|
lv_obj_add_event_cb(textarea, event_counter_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
||||||
|
|
||||||
|
lv_textarea_set_text(textarea, "123"); /* digits not in accepted_list */
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_STRING("", lv_textarea_get_text(textarea));
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(0U, event_count);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user