From 1386edf2fbd01a4398355f4ecc5800bb5fcc5d0e Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 20 May 2021 12:04:06 +0200 Subject: [PATCH] fix(bidi) fix tabview, textarea, label, btnmatrix, roller, dropdown with RTL base direction --- examples/layouts/flex/lv_example_flex_6.c | 3 ++- examples/scroll/lv_example_scroll_2.c | 3 +++ .../widgets/tabview/lv_example_tabview_1.c | 3 ++- .../widgets/textarea/lv_example_textarea_1.c | 4 +++- .../widgets/textarea/lv_example_textarea_2.c | 1 + src/core/lv_obj_draw.c | 4 ++-- src/core/lv_obj_scroll.c | 22 ++++++++++++++----- src/extra/layouts/flex/lv_flex.c | 2 +- src/extra/widgets/tabview/lv_tabview.c | 8 ++++++- src/misc/lv_txt.h | 2 +- src/widgets/lv_btnmatrix.c | 8 +++++-- src/widgets/lv_dropdown.c | 3 +++ src/widgets/lv_label.c | 10 +++++++++ src/widgets/lv_roller.c | 3 +++ src/widgets/lv_textarea.c | 9 ++++++-- 15 files changed, 68 insertions(+), 17 deletions(-) diff --git a/examples/layouts/flex/lv_example_flex_6.c b/examples/layouts/flex/lv_example_flex_6.c index e90370d32..bfb2b0416 100644 --- a/examples/layouts/flex/lv_example_flex_6.c +++ b/examples/layouts/flex/lv_example_flex_6.c @@ -11,7 +11,7 @@ void lv_example_flex_6(void) lv_obj_set_style_base_dir(cont, LV_BASE_DIR_RTL, 0); lv_obj_set_size(cont, 300, 220); lv_obj_center(cont); - lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW_WRAP); + lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN_WRAP); uint32_t i; for(i = 0; i < 20; i++) { @@ -23,4 +23,5 @@ void lv_example_flex_6(void) lv_obj_center(label); } } + #endif diff --git a/examples/scroll/lv_example_scroll_2.c b/examples/scroll/lv_example_scroll_2.c index c39c15c08..239243f78 100644 --- a/examples/scroll/lv_example_scroll_2.c +++ b/examples/scroll/lv_example_scroll_2.c @@ -19,6 +19,8 @@ static void sw_event_cb(lv_event_t * e) */ void lv_example_scroll_2(void) { + lv_obj_set_style_base_dir(lv_scr_act(), LV_BASE_DIR_RTL, 0); + lv_obj_t * panel = lv_obj_create(lv_scr_act()); lv_obj_set_size(panel, 280, 150); lv_obj_set_scroll_snap_x(panel, LV_SCROLL_SNAP_CENTER); @@ -40,6 +42,7 @@ void lv_example_scroll_2(void) lv_obj_center(label); } + lv_obj_update_snap(panel, LV_ANIM_ON); #if LV_USE_SWITCH diff --git a/examples/widgets/tabview/lv_example_tabview_1.c b/examples/widgets/tabview/lv_example_tabview_1.c index 17fc82e48..a9747023d 100644 --- a/examples/widgets/tabview/lv_example_tabview_1.c +++ b/examples/widgets/tabview/lv_example_tabview_1.c @@ -3,6 +3,7 @@ void lv_example_tabview_1(void) { + lv_obj_set_style_base_dir(lv_scr_act(), LV_BASE_DIR_RTL, 0); /*Create a Tab view object*/ lv_obj_t *tabview; tabview = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, 50); @@ -36,7 +37,7 @@ void lv_example_tabview_1(void) label = lv_label_create(tab3); lv_label_set_text(label, "Third tab"); - lv_obj_scroll_to_view_recursive(label, LV_ANIM_ON); +// lv_obj_scroll_to_view_recursive(label, LV_ANIM_ON); } #endif diff --git a/examples/widgets/textarea/lv_example_textarea_1.c b/examples/widgets/textarea/lv_example_textarea_1.c index cf7570972..f250c59ff 100644 --- a/examples/widgets/textarea/lv_example_textarea_1.c +++ b/examples/widgets/textarea/lv_example_textarea_1.c @@ -21,8 +21,10 @@ static void btnm_event_handler(lv_event_t * e) void lv_example_textarea_1(void) { +// lv_obj_set_style_base_dir(lv_scr_act(), LV_BASE_DIR_RTL, 0); lv_obj_t * ta = lv_textarea_create(lv_scr_act()); - lv_textarea_set_one_line(ta, true); +// lv_textarea_set_one_line(ta, true); + lv_textarea_set_text(ta, "Hey"); 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*/ diff --git a/examples/widgets/textarea/lv_example_textarea_2.c b/examples/widgets/textarea/lv_example_textarea_2.c index 0a915caa9..c26643738 100644 --- a/examples/widgets/textarea/lv_example_textarea_2.c +++ b/examples/widgets/textarea/lv_example_textarea_2.c @@ -7,6 +7,7 @@ static lv_obj_t * kb; void lv_example_textarea_2(void) { + lv_obj_set_style_base_dir(lv_scr_act(), LV_BASE_DIR_RTL, 0); /*Create the password box*/ lv_obj_t * pwd_ta = lv_textarea_create(lv_scr_act()); lv_textarea_set_text(pwd_ta, ""); diff --git a/src/core/lv_obj_draw.c b/src/core/lv_obj_draw.c index b0f35f9d5..c498756c0 100644 --- a/src/core/lv_obj_draw.c +++ b/src/core/lv_obj_draw.c @@ -201,14 +201,14 @@ void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint32_t part, lv_draw_label_dsc draw_dsc->font = lv_obj_get_style_text_font(obj, part); -#if LV_USE_BIDI == 0 +#if LV_USE_BIDI draw_dsc->bidi_dir = lv_obj_get_style_base_dir(obj, LV_PART_MAIN); #endif draw_dsc->align = lv_obj_get_style_text_align(obj, part); if(draw_dsc->align == LV_TEXT_ALIGN_AUTO) { if(draw_dsc->bidi_dir == LV_BASE_DIR_RTL) draw_dsc->align = LV_TEXT_ALIGN_RIGHT; - draw_dsc->align = LV_TEXT_ALIGN_LEFT; + else draw_dsc->align = LV_TEXT_ALIGN_LEFT; } } diff --git a/src/core/lv_obj_scroll.c b/src/core/lv_obj_scroll.c index a6dfed0e3..66832b479 100644 --- a/src/core/lv_obj_scroll.c +++ b/src/core/lv_obj_scroll.c @@ -185,6 +185,8 @@ lv_coord_t lv_obj_get_scroll_left(lv_obj_t * obj) if(x1 != LV_COORD_MAX) { child_res = x1; child_res = (obj->coords.x1 + pad_left + border_width) - child_res; + } else { + child_res = LV_COORD_MIN; } lv_coord_t self_w = lv_obj_get_self_width(obj); @@ -301,12 +303,22 @@ void lv_obj_scroll_to_x(lv_obj_t * obj, lv_coord_t x, lv_anim_enable_t anim_en) lv_anim_del(obj, scroll_x_anim); /*Don't let scroll more then naturally possible by the size of the content*/ - if(x < 0) x = 0; - if(x > 0) { - lv_coord_t scroll_max = lv_obj_get_scroll_left(obj) + lv_obj_get_scroll_right(obj); - if(scroll_max < 0) scroll_max = 0; + if(lv_obj_get_style_base_dir(obj, LV_PART_MAIN) != LV_BASE_DIR_RTL) { + if(x < 0) x = 0; + if(x > 0) { + lv_coord_t scroll_max = lv_obj_get_scroll_left(obj) + lv_obj_get_scroll_right(obj); + if(scroll_max < 0) scroll_max = 0; - if(x > scroll_max) x = scroll_max; + if(x > scroll_max) x = scroll_max; + } + } else { + if(x > 0) x = 0; + if(x < 0) { + lv_coord_t scroll_max = lv_obj_get_scroll_left(obj) + lv_obj_get_scroll_right(obj); + if(scroll_max < 0) scroll_max = 0; + + if(x < -scroll_max) x = -scroll_max; + } } lv_coord_t scroll_x = lv_obj_get_scroll_x(obj); diff --git a/src/extra/layouts/flex/lv_flex.c b/src/extra/layouts/flex/lv_flex.c index becced659..365a80ccb 100644 --- a/src/extra/layouts/flex/lv_flex.c +++ b/src/extra/layouts/flex/lv_flex.c @@ -353,7 +353,7 @@ static void children_repos(lv_obj_t * cont, flex_t * f, int32_t item_first_id, i lv_coord_t place_gap = 0; place_content(f->main_place, max_main_size, t->track_main_size, t->item_cnt, &main_pos, &place_gap); - if(f->row && rtl) main_pos += t->track_main_size; +// if(f->row && rtl) main_pos += t->track_main_size; lv_obj_t * item = lv_obj_get_child(cont, item_first_id); /*Reposition the children*/ diff --git a/src/extra/widgets/tabview/lv_tabview.c b/src/extra/widgets/tabview/lv_tabview.c index b49a72103..220816de6 100644 --- a/src/extra/widgets/tabview/lv_tabview.c +++ b/src/extra/widgets/tabview/lv_tabview.c @@ -129,7 +129,11 @@ void lv_tabview_set_act(lv_obj_t * obj, uint32_t id, lv_anim_enable_t anim_en) if(cont == NULL) return; lv_coord_t gap = lv_obj_get_style_pad_column(cont, LV_PART_MAIN); lv_coord_t w = lv_obj_get_content_width(obj); - lv_obj_scroll_to_x(cont, id * (gap + w), anim_en); + if(lv_obj_get_style_base_dir(obj, LV_PART_MAIN) != LV_BASE_DIR_RTL) { + lv_obj_scroll_to_x(cont, id * (gap + w), anim_en); + } else { + lv_obj_scroll_to_x(cont, (gap + w) * (-id - 1), anim_en); + } lv_obj_t * btns = lv_tabview_get_tab_btns(obj); lv_btnmatrix_set_btn_ctrl(btns, id, LV_BTNMATRIX_CTRL_CHECKED); @@ -279,6 +283,8 @@ static void cont_scroll_end_event_cb(lv_event_t * e) lv_coord_t w = lv_obj_get_content_width(cont); lv_coord_t t = (p.x + w/ 2) / w; + + if(lv_obj_get_style_base_dir(tv, LV_PART_MAIN) == LV_BASE_DIR_RTL) t = -t; if(t < 0) t = 0; lv_tabview_set_act(tv, t, LV_ANIM_ON); lv_event_send(tv, LV_EVENT_VALUE_CHANGED, NULL); diff --git a/src/misc/lv_txt.h b/src/misc/lv_txt.h index c12bd1769..e9a097e9a 100644 --- a/src/misc/lv_txt.h +++ b/src/misc/lv_txt.h @@ -57,10 +57,10 @@ typedef uint8_t lv_text_cmd_state_t; /** Label align policy*/ enum { + LV_TEXT_ALIGN_AUTO, /**< Align text auto*/ LV_TEXT_ALIGN_LEFT, /**< Align text to left*/ LV_TEXT_ALIGN_CENTER, /**< Align text to center*/ LV_TEXT_ALIGN_RIGHT, /**< Align text to right*/ - LV_TEXT_ALIGN_AUTO, /**< Align text auto*/ }; typedef uint8_t lv_text_align_t; diff --git a/src/widgets/lv_btnmatrix.c b/src/widgets/lv_btnmatrix.c index 7c6212bdb..9b0645235 100644 --- a/src/widgets/lv_btnmatrix.c +++ b/src/widgets/lv_btnmatrix.c @@ -156,18 +156,22 @@ void lv_btnmatrix_set_map(lv_obj_t * obj, const char * map[]) for(btn = 0; btn < btn_cnt; btn++, btn_tot_i++, txt_tot_i++) { uint32_t btn_u = get_button_width(btnm->ctrl_bits[btn_tot_i]); - lv_coord_t btn_x1 = pleft + (max_w_no_gap * row_unit_cnt) / unit_cnt + btn * pcol; - lv_coord_t btn_x2 = pleft + (max_w_no_gap * (row_unit_cnt + btn_u)) / unit_cnt + btn * pcol - 1; + lv_coord_t btn_x1 = (max_w_no_gap * row_unit_cnt) / unit_cnt + btn * pcol; + lv_coord_t btn_x2 = (max_w_no_gap * (row_unit_cnt + btn_u)) / unit_cnt + btn * pcol - 1; /*If RTL start from the right*/ if(base_dir == LV_BASE_DIR_RTL) { lv_coord_t tmp = btn_x1; btn_x1 = btn_x2; btn_x2 = tmp; + btn_x1 = max_w - btn_x1; btn_x2 = max_w - btn_x2; } + btn_x1 += pleft; + btn_x2 += pleft; + lv_area_set(&btnm->button_areas[btn_tot_i], btn_x1, row_y1, btn_x2, row_y2); row_unit_cnt += btn_u; diff --git a/src/widgets/lv_dropdown.c b/src/widgets/lv_dropdown.c index e855a8e39..081683899 100644 --- a/src/widgets/lv_dropdown.c +++ b/src/widgets/lv_dropdown.c @@ -489,6 +489,9 @@ void lv_dropdown_open(lv_obj_t * dropdown_obj) } lv_text_align_t align = lv_obj_get_style_text_align(label, LV_PART_MAIN); + if(align == LV_TEXT_ALIGN_AUTO && lv_obj_get_style_base_dir(label, LV_PART_MAIN) == LV_BASE_DIR_RTL) align = LV_TEXT_ALIGN_RIGHT; + else align = LV_TEXT_ALIGN_LEFT; + switch(align) { default: case LV_TEXT_ALIGN_LEFT: diff --git a/src/widgets/lv_label.c b/src/widgets/lv_label.c index 1c5f21f7b..c7898ece2 100644 --- a/src/widgets/lv_label.c +++ b/src/widgets/lv_label.c @@ -290,6 +290,8 @@ void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t const char * txt = lv_label_get_text(obj); lv_text_align_t align = lv_obj_get_style_text_align(obj, LV_PART_MAIN); + if(align == LV_TEXT_ALIGN_AUTO && lv_obj_get_style_base_dir(obj, LV_PART_MAIN) == LV_BASE_DIR_RTL) align = LV_TEXT_ALIGN_RIGHT; + else align = LV_TEXT_ALIGN_LEFT; if(txt[0] == '\0') { pos->y = 0; @@ -424,6 +426,8 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in) if(lv_obj_get_style_width(obj, LV_PART_MAIN) == LV_SIZE_CONTENT && !obj->w_layout) flag |= LV_TEXT_FLAG_FIT; lv_text_align_t align = lv_obj_get_style_text_align(obj, LV_PART_MAIN); + if(align == LV_TEXT_ALIGN_AUTO && lv_obj_get_style_base_dir(obj, LV_PART_MAIN) == LV_BASE_DIR_RTL) align = LV_TEXT_ALIGN_RIGHT; + else align = LV_TEXT_ALIGN_LEFT; /*Search the line of the index letter*/; while(txt[line_start] != '\0') { @@ -535,6 +539,9 @@ bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) lv_coord_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); lv_coord_t letter_height = lv_font_get_line_height(font); lv_text_align_t align = lv_obj_get_style_text_align(obj, LV_PART_MAIN); + if(align == LV_TEXT_ALIGN_AUTO && lv_obj_get_style_base_dir(obj, LV_PART_MAIN) == LV_BASE_DIR_RTL) align = LV_TEXT_ALIGN_RIGHT; + else align = LV_TEXT_ALIGN_LEFT; + lv_coord_t y = 0; lv_text_flag_t flag = LV_TEXT_FLAG_NONE; @@ -797,6 +804,9 @@ static void draw_main(lv_event_t * e) lv_obj_get_content_coords(obj, &txt_coords); lv_text_align_t align = lv_obj_get_style_text_align(obj, LV_PART_MAIN); + if(align == LV_TEXT_ALIGN_AUTO && lv_obj_get_style_base_dir(obj, LV_PART_MAIN) == LV_BASE_DIR_RTL) align = LV_TEXT_ALIGN_RIGHT; + else align = LV_TEXT_ALIGN_LEFT; + lv_text_flag_t flag = LV_TEXT_FLAG_NONE; if(label->recolor != 0) flag |= LV_TEXT_FLAG_RECOLOR; if(label->expand != 0) flag |= LV_TEXT_FLAG_EXPAND; diff --git a/src/widgets/lv_roller.c b/src/widgets/lv_roller.c index 21b9d7723..4099964e5 100644 --- a/src/widgets/lv_roller.c +++ b/src/widgets/lv_roller.c @@ -574,6 +574,9 @@ static void refr_position(lv_obj_t * obj, lv_anim_enable_t anim_en) if(label == NULL) return; lv_text_align_t align = lv_obj_get_style_text_align(label, LV_PART_MAIN); + if(align == LV_TEXT_ALIGN_AUTO && lv_obj_get_style_base_dir(obj, LV_PART_MAIN) == LV_BASE_DIR_RTL) align = LV_TEXT_ALIGN_RIGHT; + else align = LV_TEXT_ALIGN_LEFT; + switch(align) { case LV_TEXT_ALIGN_CENTER: lv_obj_set_x(label, (lv_obj_get_content_width(obj) - lv_obj_get_width(label)) / 2); diff --git a/src/widgets/lv_textarea.c b/src/widgets/lv_textarea.c index 427be7817..1d72dc0d2 100644 --- a/src/widgets/lv_textarea.c +++ b/src/widgets/lv_textarea.c @@ -813,6 +813,8 @@ static void lv_textarea_constructor(const lv_obj_class_t * class_p, lv_obj_t * o ta->placeholder_txt = NULL; ta->label = lv_label_create(obj); + lv_obj_set_style_bg_color(ta->label, lv_color_hex(0x226699), 0); + lv_obj_set_style_bg_opa(ta->label, 200, 0); lv_obj_set_width(ta->label, lv_pct(100)); lv_label_set_text(ta->label, ""); lv_obj_add_flag(obj, LV_OBJ_FLAG_SCROLL_ON_FOCUS); @@ -1070,9 +1072,12 @@ static void refr_cursor_area(lv_obj_t * obj) lv_point_t letter_pos; lv_label_get_letter_pos(ta->label, cur_pos, &letter_pos); + lv_text_align_t align = lv_obj_get_style_text_align(ta->label, LV_PART_MAIN); + if(align == LV_TEXT_ALIGN_AUTO && lv_obj_get_style_base_dir(obj, LV_PART_MAIN) == LV_BASE_DIR_RTL) align = LV_TEXT_ALIGN_RIGHT; + else align = LV_TEXT_ALIGN_LEFT; + /*If the cursor is out of the text (most right) draw it to the next line*/ - if(letter_pos.x + ta->label->coords.x1 + letter_w > ta->label->coords.x2 && ta->one_line == 0 && - lv_obj_get_style_text_align(ta->label, LV_PART_MAIN) != LV_TEXT_ALIGN_RIGHT) { + if(letter_pos.x + ta->label->coords.x1 + letter_w > ta->label->coords.x2 && ta->one_line == 0 && align != LV_TEXT_ALIGN_RIGHT) { letter_pos.x = 0; letter_pos.y += letter_h + line_space;