mirror of
https://github.com/lvgl/lvgl.git
synced 2024-12-02 22:24:02 +08:00
fix(roller): set the position of the selected text correctly (#6083)
Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com>
This commit is contained in:
parent
5f5e8d74ac
commit
caf18564ba
@ -115,7 +115,7 @@ struct _lv_font_t {
|
||||
|
||||
/*Pointer to the font in a font pack (must have the same line height)*/
|
||||
int32_t line_height; /**< The real line height where any text fits*/
|
||||
int32_t base_line; /**< Base line measured from the top of the line_height*/
|
||||
int32_t base_line; /**< Base line measured from the bottom of the line_height*/
|
||||
uint8_t subpx : 2; /**< An element of `lv_font_subpx_t`*/
|
||||
uint8_t kerning : 1; /**< An element of `lv_font_kerning_t`*/
|
||||
|
||||
|
@ -321,11 +321,10 @@ static void lv_roller_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
||||
lv_indev_t * indev = lv_indev_active();
|
||||
lv_point_t p;
|
||||
lv_indev_get_vect(indev, &p);
|
||||
|
||||
transform_vect_recursive(obj, &p);
|
||||
if(p.y) {
|
||||
lv_obj_t * label = get_label(obj);
|
||||
lv_obj_set_y(label, lv_obj_get_y(label) + p.y);
|
||||
lv_obj_set_y(label, lv_obj_get_y_aligned(label) + p.y);
|
||||
roller->moved = 1;
|
||||
}
|
||||
}
|
||||
@ -463,26 +462,28 @@ static void draw_main(lv_event_t * e)
|
||||
lv_obj_t * label = get_label(obj);
|
||||
|
||||
/*Get the size of the "selected text"*/
|
||||
lv_point_t res_p;
|
||||
lv_text_get_size(&res_p, lv_label_get_text(label), label_dsc.font, label_dsc.letter_space, label_dsc.line_space,
|
||||
lv_obj_get_width(obj), LV_TEXT_FLAG_EXPAND);
|
||||
lv_point_t label_sel_size;
|
||||
lv_text_get_size(&label_sel_size, lv_label_get_text(label), label_dsc.font, label_dsc.letter_space,
|
||||
label_dsc.line_space, lv_obj_get_width(obj), LV_TEXT_FLAG_EXPAND);
|
||||
|
||||
/*Move the selected label proportionally with the background label*/
|
||||
int32_t roller_h = lv_obj_get_height(obj);
|
||||
int32_t label_y_prop = label->coords.y1 - (roller_h / 2 +
|
||||
obj->coords.y1); /*label offset from the middle line of the roller*/
|
||||
label_y_prop = (label_y_prop * 16384) / lv_obj_get_height(
|
||||
label); /*Proportional position from the middle line (upscaled by << 14)*/
|
||||
|
||||
/*Apply a correction with different line heights*/
|
||||
const lv_font_t * normal_label_font = lv_obj_get_style_text_font(obj, LV_PART_MAIN);
|
||||
int32_t corr = (label_dsc.font->line_height - normal_label_font->line_height) / 2;
|
||||
/*label offset from the middle line of the roller*/
|
||||
int32_t label_y_prop = (label->coords.y1 + normal_label_font->line_height / 2) - (roller_h / 2 + obj->coords.y1);
|
||||
|
||||
/*Proportional position from the middle line.
|
||||
*Will be 0 for the first option, and 1 for the last option (upscaled by << 14)*/
|
||||
label_y_prop = (label_y_prop << 14) / (lv_obj_get_height(label) - normal_label_font->line_height);
|
||||
|
||||
/*We don't want the selected label start and end exactly where the normal label is as
|
||||
*a larger font won't centered on selected area.*/
|
||||
int32_t corr = label_dsc.font->line_height;
|
||||
|
||||
/*Apply the proportional position to the selected text*/
|
||||
res_p.y -= corr;
|
||||
int32_t label_sel_y = roller_h / 2 + obj->coords.y1;
|
||||
label_sel_y += (label_y_prop * res_p.y) >> 14;
|
||||
label_sel_y -= corr;
|
||||
label_sel_y += ((label_sel_size.y - corr) * label_y_prop) >> 14;
|
||||
label_sel_y -= corr / 2;
|
||||
|
||||
int32_t bwidth = lv_obj_get_style_border_width(obj, LV_PART_MAIN);
|
||||
int32_t pleft = lv_obj_get_style_pad_left(obj, LV_PART_MAIN);
|
||||
@ -493,7 +494,7 @@ static void draw_main(lv_event_t * e)
|
||||
label_sel_area.x1 = obj->coords.x1 + pleft + bwidth;
|
||||
label_sel_area.y1 = label_sel_y;
|
||||
label_sel_area.x2 = obj->coords.x2 - pright - bwidth;
|
||||
label_sel_area.y2 = label_sel_area.y1 + res_p.y;
|
||||
label_sel_area.y2 = label_sel_area.y1 + label_sel_size.y;
|
||||
|
||||
label_dsc.flag |= LV_TEXT_FLAG_EXPAND;
|
||||
const lv_area_t clip_area_ori = layer->_clip_area;
|
||||
@ -514,7 +515,6 @@ static void draw_label(lv_event_t * e)
|
||||
lv_draw_label_dsc_t label_draw_dsc;
|
||||
lv_draw_label_dsc_init(&label_draw_dsc);
|
||||
lv_obj_init_draw_label_dsc(roller, LV_PART_MAIN, &label_draw_dsc);
|
||||
|
||||
lv_layer_t * layer = lv_event_get_layer(e);
|
||||
|
||||
/*If the roller has shadow or outline it has some ext. draw size
|
||||
|
BIN
tests/ref_imgs/widgets/roller_2.png
Normal file
BIN
tests/ref_imgs/widgets/roller_2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
BIN
tests/ref_imgs/widgets/roller_3.png
Normal file
BIN
tests/ref_imgs/widgets/roller_3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
@ -246,4 +246,87 @@ void test_roller_with_overlay_and_bubble_events_enabled(void)
|
||||
// TEST_ASSERT_NOT_EQUAL(0, lv_roller_get_selected(roller_mouse));
|
||||
//}
|
||||
|
||||
void test_roller_appearance(void)
|
||||
{
|
||||
/* use a number, a symbol, a high letter, a low letter */
|
||||
const char * opts =
|
||||
"0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg\n0@Tg";
|
||||
|
||||
lv_obj_add_flag(roller_mouse, LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
lv_obj_t * rollers[10] = {roller, roller_infinite};
|
||||
uint32_t i = 2;
|
||||
|
||||
/* a normal and infinite roller with the same size font for the main and selected parts */
|
||||
lv_obj_set_pos(roller, 20, 20);
|
||||
lv_roller_set_options(roller, opts, LV_PART_MAIN);
|
||||
lv_obj_set_pos(roller_infinite, 20, 200);
|
||||
lv_roller_set_options(roller_infinite, opts, LV_ROLLER_MODE_INFINITE);
|
||||
|
||||
/* a normal and infinite roller with slightly different size fonts for the main and selected parts */
|
||||
lv_obj_t * r = lv_roller_create(active_screen);
|
||||
lv_obj_set_pos(r, 130, 20);
|
||||
lv_roller_set_options(r, opts, LV_ROLLER_MODE_NORMAL);
|
||||
lv_obj_set_style_text_font(r, &lv_font_montserrat_16, LV_PART_MAIN);
|
||||
lv_obj_set_style_text_font(r, &lv_font_montserrat_24, LV_PART_SELECTED);
|
||||
rollers[i++] = r;
|
||||
r = lv_roller_create(active_screen);
|
||||
lv_obj_set_pos(r, 130, 200);
|
||||
lv_roller_set_options(r, opts, LV_ROLLER_MODE_INFINITE);
|
||||
lv_obj_set_style_text_font(r, &lv_font_montserrat_16, LV_PART_MAIN);
|
||||
lv_obj_set_style_text_font(r, &lv_font_montserrat_24, LV_PART_SELECTED);
|
||||
rollers[i++] = r;
|
||||
|
||||
/* same as previous pair but the fonts are swapped for the main and selected parts */
|
||||
r = lv_roller_create(active_screen);
|
||||
lv_obj_set_pos(r, 270, 20);
|
||||
lv_roller_set_options(r, opts, LV_ROLLER_MODE_NORMAL);
|
||||
lv_obj_set_style_text_font(r, &lv_font_montserrat_24, LV_PART_MAIN);
|
||||
lv_obj_set_style_text_font(r, &lv_font_montserrat_16, LV_PART_SELECTED);
|
||||
rollers[i++] = r;
|
||||
r = lv_roller_create(active_screen);
|
||||
lv_obj_set_pos(r, 270, 200);
|
||||
lv_roller_set_options(r, opts, LV_ROLLER_MODE_INFINITE);
|
||||
lv_obj_set_style_text_font(r, &lv_font_montserrat_24, LV_PART_MAIN);
|
||||
lv_obj_set_style_text_font(r, &lv_font_montserrat_16, LV_PART_SELECTED);
|
||||
rollers[i++] = r;
|
||||
|
||||
/* a normal and infinite roller with extremely different size fonts for the main and selected parts */
|
||||
r = lv_roller_create(active_screen);
|
||||
lv_obj_set_pos(r, 410, 20);
|
||||
lv_roller_set_options(r, opts, LV_ROLLER_MODE_NORMAL);
|
||||
lv_obj_set_style_text_font(r, &lv_font_montserrat_8, LV_PART_MAIN);
|
||||
lv_obj_set_style_text_font(r, &lv_font_montserrat_36, LV_PART_SELECTED);
|
||||
rollers[i++] = r;
|
||||
r = lv_roller_create(active_screen);
|
||||
lv_obj_set_pos(r, 410, 200);
|
||||
lv_roller_set_options(r, opts, LV_ROLLER_MODE_INFINITE);
|
||||
lv_obj_set_style_text_font(r, &lv_font_montserrat_8, LV_PART_MAIN);
|
||||
lv_obj_set_style_text_font(r, &lv_font_montserrat_36, LV_PART_SELECTED);
|
||||
rollers[i++] = r;
|
||||
|
||||
/* same as previous pair but the fonts are swapped for the main and selected parts */
|
||||
r = lv_roller_create(active_screen);
|
||||
lv_obj_set_pos(r, 580, 20);
|
||||
lv_roller_set_options(r, opts, LV_ROLLER_MODE_NORMAL);
|
||||
lv_obj_set_style_text_font(r, &lv_font_montserrat_36, LV_PART_MAIN);
|
||||
lv_obj_set_style_text_font(r, &lv_font_montserrat_8, LV_PART_SELECTED);
|
||||
rollers[i++] = r;
|
||||
r = lv_roller_create(active_screen);
|
||||
lv_obj_set_pos(r, 580, 200);
|
||||
lv_roller_set_options(r, opts, LV_ROLLER_MODE_INFINITE);
|
||||
lv_obj_set_style_text_font(r, &lv_font_montserrat_36, LV_PART_MAIN);
|
||||
lv_obj_set_style_text_font(r, &lv_font_montserrat_8, LV_PART_SELECTED);
|
||||
rollers[i++] = r;
|
||||
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/roller_2.png");
|
||||
|
||||
/* test that the selected label stays in sync with the main label for scrolling */
|
||||
for(i = 0; i < 10; i++) {
|
||||
lv_roller_set_selected(rollers[i], lv_roller_get_option_count(rollers[i]) - 1, LV_ANIM_OFF);
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/roller_3.png");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user