mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
bidi: fix btnm, kb, ta, table behaviour in RTL context
This commit is contained in:
parent
c747f29664
commit
6f001958ce
@ -43,8 +43,10 @@ static uint32_t char_change_to_pair(uint32_t letter);
|
||||
|
||||
void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir)
|
||||
{
|
||||
printf("\nInput str: \"%s\"\n", str_in);
|
||||
|
||||
if(base_dir == LV_BIDI_DIR_AUTO) base_dir = lv_bidi_detect_base_dir(str_in);
|
||||
|
||||
printf("\nInput str: \"%s\"\n", str_in);
|
||||
|
||||
uint32_t par_start = 0;
|
||||
uint32_t par_len;
|
||||
@ -68,9 +70,6 @@ void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir
|
||||
str_out[par_start] = '\0';
|
||||
|
||||
printf("\nOutput str: \"%s\"\n", str_out);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
lv_bidi_dir_t lv_bidi_detect_base_dir(const char * txt)
|
||||
@ -86,7 +85,8 @@ lv_bidi_dir_t lv_bidi_detect_base_dir(const char * txt)
|
||||
}
|
||||
|
||||
/*If there were no strong char earlier return with the default base dir */
|
||||
return LV_BIDI_BASE_DIR_DEF;
|
||||
if(LV_BIDI_BASE_DIR_DEF == LV_BIDI_DIR_AUTO) return LV_BIDI_DIR_LTR;
|
||||
else return LV_BIDI_BASE_DIR_DEF;
|
||||
}
|
||||
|
||||
lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter)
|
||||
|
@ -644,7 +644,6 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo
|
||||
}
|
||||
/*Draw the object*/
|
||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
|
||||
ancestor_design_f(btnm, mask, mode);
|
||||
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
|
||||
@ -665,6 +664,10 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo
|
||||
lv_txt_flag_t txt_flag = LV_TXT_FLAG_NONE;
|
||||
|
||||
if(ext->recolor) txt_flag = LV_TXT_FLAG_RECOLOR;
|
||||
#if LV_USE_BIDI
|
||||
char * bidi_buf = lv_mem_alloc(64);
|
||||
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(btnm);
|
||||
#endif
|
||||
|
||||
for(btn_i = 0; btn_i < ext->btn_cnt; btn_i++, txt_i++) {
|
||||
/*Search the next valid text in the map*/
|
||||
@ -734,9 +737,24 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo
|
||||
area_tmp.x2 = area_tmp.x1 + txt_size.x;
|
||||
area_tmp.y2 = area_tmp.y1 + txt_size.y;
|
||||
|
||||
#if LV_USE_BIDI == 0
|
||||
lv_draw_label(&area_tmp, mask, btn_style, opa_scale, ext->map_p[txt_i], txt_flag, NULL, -1, -1, NULL);
|
||||
#else
|
||||
uint32_t txt_len = strlen(ext->map_p[txt_i]) + 1;
|
||||
if(txt_len > lv_mem_get_size(bidi_buf)) {
|
||||
bidi_buf = lv_mem_realloc(bidi_buf, txt_len);
|
||||
}
|
||||
|
||||
lv_bidi_process(ext->map_p[txt_i], bidi_buf, base_dir);
|
||||
lv_draw_label(&area_tmp, mask, btn_style, opa_scale, bidi_buf, txt_flag, NULL, -1, -1, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LV_USE_BIDI
|
||||
lv_mem_free(bidi_buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -395,7 +395,7 @@ void lv_kb_def_event_cb(lv_obj_t * kb, lv_event_t event)
|
||||
/*Add the characters to the text area if set*/
|
||||
if(ext->ta == NULL) return;
|
||||
|
||||
if(strcmp(txt, "Enter") == 0)
|
||||
if(strcmp(txt, LV_SYMBOL_NEW_LINE) == 0)
|
||||
lv_ta_add_char(ext->ta, '\n');
|
||||
else if(strcmp(txt, LV_SYMBOL_LEFT) == 0)
|
||||
lv_ta_cursor_left(ext->ta);
|
||||
|
@ -182,16 +182,7 @@ void lv_label_set_text(lv_obj_t * label, const char * text)
|
||||
|
||||
/*If text is NULL then refresh */
|
||||
if(text == NULL) {
|
||||
#if LV_USE_BIDI == 0
|
||||
lv_label_refr_text(label);
|
||||
#else
|
||||
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(label);
|
||||
if(base_dir == LV_BIDI_DIR_AUTO) base_dir = lv_bidi_detect_base_dir(ext->text_ori);
|
||||
|
||||
lv_bidi_process(ext->text_ori, ext->text, base_dir);
|
||||
lv_label_refr_text(label);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -208,11 +199,6 @@ void lv_label_set_text(lv_obj_t * label, const char * text)
|
||||
if(ext->text != NULL && ext->static_txt == 0) {
|
||||
lv_mem_free(ext->text);
|
||||
ext->text = NULL;
|
||||
|
||||
#if LV_USE_BIDI
|
||||
lv_mem_free(ext->text_ori);
|
||||
ext->text_ori = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
ext->text = lv_mem_alloc(len);
|
||||
@ -222,16 +208,8 @@ void lv_label_set_text(lv_obj_t * label, const char * text)
|
||||
#if LV_USE_BIDI == 0
|
||||
strcpy(ext->text, text);
|
||||
#else
|
||||
ext->text_ori = lv_mem_alloc(len);
|
||||
LV_ASSERT_MEM(ext->text_ori);
|
||||
if(ext->text_ori == NULL) return;
|
||||
|
||||
strcpy(ext->text_ori, text);
|
||||
|
||||
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(label);
|
||||
if(base_dir == LV_BIDI_DIR_AUTO) base_dir = lv_bidi_detect_base_dir(text);
|
||||
|
||||
lv_bidi_process(ext->text_ori, ext->text, base_dir);
|
||||
lv_bidi_process(text, ext->text, base_dir);
|
||||
#endif
|
||||
/*Now the text is dynamically allocated*/
|
||||
ext->static_txt = 0;
|
||||
@ -622,7 +600,10 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t
|
||||
|
||||
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;
|
||||
if(ext->align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;
|
||||
|
||||
lv_label_align_t align = lv_label_get_align(label);
|
||||
if(align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;
|
||||
if(align == LV_LABEL_ALIGN_RIGHT) flag |= LV_TXT_FLAG_RIGHT;
|
||||
|
||||
/*If the width will be expanded the set the max length to very big */
|
||||
if(ext->long_mode == LV_LABEL_LONG_EXPAND) {
|
||||
@ -654,12 +635,12 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t
|
||||
|
||||
if(index != line_start) x += style->text.letter_space;
|
||||
|
||||
if(ext->align == LV_LABEL_ALIGN_CENTER) {
|
||||
if(align == LV_LABEL_ALIGN_CENTER) {
|
||||
lv_coord_t line_w;
|
||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);
|
||||
x += lv_obj_get_width(label) / 2 - line_w / 2;
|
||||
|
||||
} else if(ext->align == LV_LABEL_ALIGN_RIGHT) {
|
||||
} else if(align == LV_LABEL_ALIGN_RIGHT) {
|
||||
lv_coord_t line_w;
|
||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);
|
||||
|
||||
@ -694,7 +675,10 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
|
||||
|
||||
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;
|
||||
if(ext->align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;
|
||||
|
||||
lv_label_align_t align = lv_label_get_align(label);
|
||||
if(align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;
|
||||
if(align == LV_LABEL_ALIGN_RIGHT) flag |= LV_TXT_FLAG_RIGHT;
|
||||
|
||||
/*If the width will be expanded set the max length to very big */
|
||||
if(ext->long_mode == LV_LABEL_LONG_EXPAND) {
|
||||
@ -713,11 +697,16 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
|
||||
|
||||
/*Calculate the x coordinate*/
|
||||
lv_coord_t x = 0;
|
||||
if(ext->align == LV_LABEL_ALIGN_CENTER) {
|
||||
if(align == LV_LABEL_ALIGN_CENTER) {
|
||||
lv_coord_t line_w;
|
||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);
|
||||
x += lv_obj_get_width(label) / 2 - line_w / 2;
|
||||
}
|
||||
else if(align == LV_LABEL_ALIGN_RIGHT) {
|
||||
lv_coord_t line_w;
|
||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);
|
||||
x += lv_obj_get_width(label) - line_w;
|
||||
}
|
||||
|
||||
lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT;
|
||||
|
||||
@ -1192,11 +1181,12 @@ static void lv_label_refr_text(lv_obj_t * label)
|
||||
/*In roll inf. mode keep the size but start offset animations*/
|
||||
else if(ext->long_mode == LV_LABEL_LONG_SROLL_CIRC) {
|
||||
#if LV_USE_ANIMATION
|
||||
lv_label_align_t align = lv_label_get_align(label);
|
||||
|
||||
lv_anim_t anim;
|
||||
anim.var = label;
|
||||
anim.repeat = 1;
|
||||
anim.playback = 0;
|
||||
anim.start = 0;
|
||||
anim.act_time = -(((lv_font_get_glyph_width(style->text.font, ' ', ' ') + style->text.letter_space) * 1000) /
|
||||
ext->anim_speed) *
|
||||
LV_LABEL_WAIT_CHAR_COUNT;
|
||||
@ -1207,7 +1197,14 @@ static void lv_label_refr_text(lv_obj_t * label)
|
||||
|
||||
bool hor_anim = false;
|
||||
if(size.x > lv_obj_get_width(label)) {
|
||||
anim.end = -size.x - lv_font_get_glyph_width(font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT;
|
||||
if(align == LV_LABEL_ALIGN_RIGHT) {
|
||||
anim.end = 0;
|
||||
anim.start = -size.x - lv_font_get_glyph_width(font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT;
|
||||
} else {
|
||||
anim.start = 0;
|
||||
anim.end = -size.x - lv_font_get_glyph_width(font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT;
|
||||
}
|
||||
|
||||
anim.exec_cb = (lv_anim_exec_xcb_t)lv_label_set_offset_x;
|
||||
anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);
|
||||
lv_anim_create(&anim);
|
||||
@ -1219,7 +1216,14 @@ static void lv_label_refr_text(lv_obj_t * label)
|
||||
}
|
||||
|
||||
if(size.y > lv_obj_get_height(label) && hor_anim == false) {
|
||||
anim.end = -size.y - (lv_font_get_line_height(font));
|
||||
if(align == LV_LABEL_ALIGN_RIGHT) {
|
||||
anim.end = 0;
|
||||
anim.start = -size.y - (lv_font_get_line_height(font));
|
||||
} else {
|
||||
anim.start = 0;
|
||||
anim.end = -size.y - (lv_font_get_line_height(font));
|
||||
}
|
||||
|
||||
anim.exec_cb = (lv_anim_exec_xcb_t)lv_label_set_offset_y;
|
||||
anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);
|
||||
lv_anim_create(&anim);
|
||||
|
@ -71,10 +71,6 @@ typedef struct
|
||||
/*New data for this type */
|
||||
char * text; /*Text of the label*/
|
||||
|
||||
#if LV_USE_BIDI
|
||||
char * text_ori; /*The original text. With BiDi `text` stores the characters in "bidi" ordered text*/
|
||||
#endif
|
||||
|
||||
union
|
||||
{
|
||||
char * tmp_ptr; /* Pointer to the allocated memory containing the character which are replaced by dots (Handled
|
||||
|
@ -1850,53 +1850,53 @@ static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_
|
||||
lv_indev_get_vect(click_source, &vect_act);
|
||||
|
||||
if(point_act.x < 0 || point_act.y < 0) return; /*Ignore event from keypad*/
|
||||
lv_point_t relative_position;
|
||||
relative_position.x = point_act.x - label_coords.x1;
|
||||
relative_position.y = point_act.y - label_coords.y1;
|
||||
lv_point_t rel_pos;
|
||||
rel_pos.x = point_act.x - label_coords.x1;
|
||||
rel_pos.y = point_act.y - label_coords.y1;
|
||||
|
||||
lv_coord_t label_width = lv_obj_get_width(ext->label);
|
||||
|
||||
uint16_t index_of_char_at_position;
|
||||
uint16_t char_id_at_click;
|
||||
|
||||
#if LV_LABEL_TEXT_SEL
|
||||
lv_label_ext_t * ext_label = lv_obj_get_ext_attr(ext->label);
|
||||
bool click_outside_label;
|
||||
/*Check if the click happened on the left side of the area outside the label*/
|
||||
if(relative_position.x < 0) {
|
||||
index_of_char_at_position = 0;
|
||||
if(rel_pos.x < 0) {
|
||||
char_id_at_click = 0;
|
||||
click_outside_label = true;
|
||||
}
|
||||
/*Check if the click happened on the right side of the area outside the label*/
|
||||
else if(relative_position.x >= label_width) {
|
||||
index_of_char_at_position = LV_TA_CURSOR_LAST;
|
||||
else if(rel_pos.x >= label_width) {
|
||||
char_id_at_click = LV_TA_CURSOR_LAST;
|
||||
click_outside_label = true;
|
||||
} else {
|
||||
index_of_char_at_position = lv_label_get_letter_on(ext->label, &relative_position);
|
||||
click_outside_label = !lv_label_is_char_under_pos(ext->label, &relative_position);
|
||||
char_id_at_click = lv_label_get_letter_on(ext->label, &rel_pos);
|
||||
click_outside_label = !lv_label_is_char_under_pos(ext->label, &rel_pos);
|
||||
}
|
||||
|
||||
if(ext->text_sel_en) {
|
||||
if(!ext->text_sel_in_prog && !click_outside_label && sign == LV_SIGNAL_PRESSED) {
|
||||
/*Input device just went down. Store the selection start position*/
|
||||
ext->tmp_sel_start = index_of_char_at_position;
|
||||
ext->tmp_sel_start = char_id_at_click;
|
||||
ext->tmp_sel_end = LV_LABEL_TEXT_SEL_OFF;
|
||||
ext->text_sel_in_prog = 1;
|
||||
lv_obj_set_drag(lv_page_get_scrl(ta), false);
|
||||
} else if(ext->text_sel_in_prog && sign == LV_SIGNAL_PRESSING) {
|
||||
/*Input device may be moving. Store the end position */
|
||||
ext->tmp_sel_end = index_of_char_at_position;
|
||||
ext->tmp_sel_end = char_id_at_click;
|
||||
} else if(ext->text_sel_in_prog && (sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_RELEASED)) {
|
||||
/*Input device is released. Check if anything was selected.*/
|
||||
lv_obj_set_drag(lv_page_get_scrl(ta), true);
|
||||
}
|
||||
}
|
||||
|
||||
if(ext->text_sel_in_prog || sign == LV_SIGNAL_PRESSED) lv_ta_set_cursor_pos(ta, index_of_char_at_position);
|
||||
if(ext->text_sel_in_prog || sign == LV_SIGNAL_PRESSED) lv_ta_set_cursor_pos(ta, char_id_at_click);
|
||||
|
||||
if(ext->text_sel_in_prog) {
|
||||
/*If the selected area has changed then update the real values and*/
|
||||
/*invalidate the text area.*/
|
||||
|
||||
/*Invalidate the text area.*/
|
||||
if(ext->tmp_sel_start > ext->tmp_sel_end) {
|
||||
if(ext_label->txt_sel_start != ext->tmp_sel_end || ext_label->txt_sel_end != ext->tmp_sel_start) {
|
||||
ext_label->txt_sel_start = ext->tmp_sel_end;
|
||||
@ -1923,17 +1923,17 @@ static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_
|
||||
}
|
||||
#else
|
||||
/*Check if the click happened on the left side of the area outside the label*/
|
||||
if(relative_position.x < 0) {
|
||||
index_of_char_at_position = 0;
|
||||
if(rel_pos.x < 0) {
|
||||
char_id_at_click = 0;
|
||||
}
|
||||
/*Check if the click happened on the right side of the area outside the label*/
|
||||
else if(relative_position.x >= label_width) {
|
||||
index_of_char_at_position = LV_TA_CURSOR_LAST;
|
||||
else if(rel_pos.x >= label_width) {
|
||||
char_id_at_click = LV_TA_CURSOR_LAST;
|
||||
} else {
|
||||
index_of_char_at_position = lv_label_get_letter_on(ext->label, &relative_position);
|
||||
char_id_at_click = lv_label_get_letter_on(ext->label, &rel_pos);
|
||||
}
|
||||
|
||||
if(sign == LV_SIGNAL_PRESSED) lv_ta_set_cursor_pos(ta, index_of_char_at_position);
|
||||
if(sign == LV_SIGNAL_PRESSED) lv_ta_set_cursor_pos(ta, char_id_at_click);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -151,7 +151,11 @@ void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const
|
||||
}
|
||||
/*Initialize the format byte*/
|
||||
else {
|
||||
format.s.align = LV_LABEL_ALIGN_LEFT;
|
||||
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(table);
|
||||
if(base_dir == LV_BIDI_DIR_LTR) format.s.align = LV_LABEL_ALIGN_LEFT;
|
||||
else if(base_dir == LV_BIDI_DIR_RTL) format.s.align = LV_LABEL_ALIGN_RIGHT;
|
||||
else if(base_dir == LV_BIDI_DIR_AUTO) format.s.align = lv_bidi_detect_base_dir(txt);
|
||||
|
||||
format.s.right_merge = 0;
|
||||
format.s.type = 0;
|
||||
format.s.crop = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user