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:
Liam 2024-05-16 05:59:12 -04:00 committed by GitHub
parent 5f5e8d74ac
commit caf18564ba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 101 additions and 18 deletions

View File

@ -115,7 +115,7 @@ struct _lv_font_t {
/*Pointer to the font in a font pack (must have the same line height)*/ /*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 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 subpx : 2; /**< An element of `lv_font_subpx_t`*/
uint8_t kerning : 1; /**< An element of `lv_font_kerning_t`*/ uint8_t kerning : 1; /**< An element of `lv_font_kerning_t`*/

View File

@ -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_indev_t * indev = lv_indev_active();
lv_point_t p; lv_point_t p;
lv_indev_get_vect(indev, &p); lv_indev_get_vect(indev, &p);
transform_vect_recursive(obj, &p); transform_vect_recursive(obj, &p);
if(p.y) { if(p.y) {
lv_obj_t * label = get_label(obj); 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; roller->moved = 1;
} }
} }
@ -463,26 +462,28 @@ static void draw_main(lv_event_t * e)
lv_obj_t * label = get_label(obj); lv_obj_t * label = get_label(obj);
/*Get the size of the "selected text"*/ /*Get the size of the "selected text"*/
lv_point_t res_p; lv_point_t label_sel_size;
lv_text_get_size(&res_p, lv_label_get_text(label), label_dsc.font, label_dsc.letter_space, label_dsc.line_space, lv_text_get_size(&label_sel_size, lv_label_get_text(label), label_dsc.font, label_dsc.letter_space,
lv_obj_get_width(obj), LV_TEXT_FLAG_EXPAND); label_dsc.line_space, lv_obj_get_width(obj), LV_TEXT_FLAG_EXPAND);
/*Move the selected label proportionally with the background label*/ /*Move the selected label proportionally with the background label*/
int32_t roller_h = lv_obj_get_height(obj); 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); 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*/ /*Apply the proportional position to the selected text*/
res_p.y -= corr;
int32_t label_sel_y = roller_h / 2 + obj->coords.y1; int32_t label_sel_y = roller_h / 2 + obj->coords.y1;
label_sel_y += (label_y_prop * res_p.y) >> 14; label_sel_y += ((label_sel_size.y - corr) * label_y_prop) >> 14;
label_sel_y -= corr; label_sel_y -= corr / 2;
int32_t bwidth = lv_obj_get_style_border_width(obj, LV_PART_MAIN); 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); 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.x1 = obj->coords.x1 + pleft + bwidth;
label_sel_area.y1 = label_sel_y; label_sel_area.y1 = label_sel_y;
label_sel_area.x2 = obj->coords.x2 - pright - bwidth; 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; label_dsc.flag |= LV_TEXT_FLAG_EXPAND;
const lv_area_t clip_area_ori = layer->_clip_area; 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_t label_draw_dsc;
lv_draw_label_dsc_init(&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_obj_init_draw_label_dsc(roller, LV_PART_MAIN, &label_draw_dsc);
lv_layer_t * layer = lv_event_get_layer(e); lv_layer_t * layer = lv_event_get_layer(e);
/*If the roller has shadow or outline it has some ext. draw size /*If the roller has shadow or outline it has some ext. draw size

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -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)); // 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 #endif