mirror of
https://github.com/lvgl/lvgl.git
synced 2026-08-17 09:42:19 +08:00
feat(label): add lv_label_set_max_lines() (#10143)
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
extern const lv_property_name_t lv_dropdown_property_names[9];
|
||||
extern const lv_property_name_t lv_image_property_names[11];
|
||||
extern const lv_property_name_t lv_keyboard_property_names[4];
|
||||
extern const lv_property_name_t lv_label_property_names[4];
|
||||
extern const lv_property_name_t lv_label_property_names[5];
|
||||
extern const lv_property_name_t lv_led_property_names[2];
|
||||
extern const lv_property_name_t lv_line_property_names[1];
|
||||
extern const lv_property_name_t lv_menu_property_names[2];
|
||||
|
||||
@@ -58,8 +58,9 @@ typedef enum {
|
||||
enum _lv_property_label_id_t {
|
||||
LV_PROPERTY_ID(LABEL, TEXT, LV_PROPERTY_TYPE_TEXT, 0),
|
||||
LV_PROPERTY_ID(LABEL, LONG_MODE, LV_PROPERTY_TYPE_INT, 1),
|
||||
LV_PROPERTY_ID(LABEL, TEXT_SELECTION_START, LV_PROPERTY_TYPE_INT, 2),
|
||||
LV_PROPERTY_ID(LABEL, TEXT_SELECTION_END, LV_PROPERTY_TYPE_INT, 3),
|
||||
LV_PROPERTY_ID(LABEL, MAX_LINES, LV_PROPERTY_TYPE_INT, 2),
|
||||
LV_PROPERTY_ID(LABEL, TEXT_SELECTION_START, LV_PROPERTY_TYPE_INT, 3),
|
||||
LV_PROPERTY_ID(LABEL, TEXT_SELECTION_END, LV_PROPERTY_TYPE_INT, 4),
|
||||
LV_PROPERTY_LABEL_END,
|
||||
};
|
||||
#endif
|
||||
@@ -136,6 +137,14 @@ void lv_label_set_text_static(lv_obj_t * obj, const char * text);
|
||||
*/
|
||||
void lv_label_set_long_mode(lv_obj_t * obj, lv_label_long_mode_t long_mode);
|
||||
|
||||
/**
|
||||
* Set the maximum number of lines that the label should display in
|
||||
* `LV_LABEL_LONG_MODE_WRAP` and `LV_LABEL_LONG_MODE_DOTS` mode.
|
||||
* @param obj pointer to a label object
|
||||
* @param lines number of lines to display (unlimited if not positive)
|
||||
*/
|
||||
void lv_label_set_max_lines(lv_obj_t * obj, int32_t lines);
|
||||
|
||||
/**
|
||||
* Set where text selection should start
|
||||
* @param obj pointer to a label object
|
||||
@@ -189,6 +198,13 @@ char * lv_label_get_text(const lv_obj_t * obj);
|
||||
*/
|
||||
lv_label_long_mode_t lv_label_get_long_mode(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the maximum number of lines that a label should display
|
||||
* @param obj pointer to a label object
|
||||
* @return the maximum number of lines, if positive
|
||||
*/
|
||||
int32_t lv_label_get_max_lines(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the relative x and y coordinates of a letter
|
||||
* @param obj pointer to a label object
|
||||
|
||||
@@ -29,6 +29,10 @@ class LVLabel(LVObject):
|
||||
"""Offset where bytes have been replaced with dots"""
|
||||
return int(self._wv.safe_field("dot_begin", 0))
|
||||
|
||||
@property
|
||||
def max_lines(self):
|
||||
return int(self._wv.safe_field("max_lines", 0))
|
||||
|
||||
@property
|
||||
def sel_start(self):
|
||||
return int(self._wv.safe_field("sel_start", 0))
|
||||
@@ -88,6 +92,7 @@ class LVLabel(LVObject):
|
||||
d["text"] = self.text
|
||||
d["translation_tag"] = self.translation_tag
|
||||
d["dot_begin"] = self.dot_begin
|
||||
d["max_lines"] = self.max_lines
|
||||
d["sel_start"] = self.sel_start
|
||||
d["sel_end"] = self.sel_end
|
||||
d["size_cache"] = self.size_cache
|
||||
|
||||
@@ -76,6 +76,11 @@ static const lv_property_ops_t lv_label_properties[] = {
|
||||
.setter = lv_label_set_long_mode,
|
||||
.getter = lv_label_get_long_mode,
|
||||
},
|
||||
{
|
||||
.id = LV_PROPERTY_LABEL_MAX_LINES,
|
||||
.setter = lv_label_set_max_lines,
|
||||
.getter = lv_label_get_max_lines,
|
||||
},
|
||||
{
|
||||
.id = LV_PROPERTY_LABEL_TEXT_SELECTION_START,
|
||||
.setter = lv_label_set_text_selection_start,
|
||||
@@ -225,6 +230,14 @@ void lv_label_set_long_mode(lv_obj_t * obj, lv_label_long_mode_t long_mode)
|
||||
lv_label_mark_need_refr_text(obj);
|
||||
}
|
||||
|
||||
void lv_label_set_max_lines(lv_obj_t * obj, int32_t lines)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
lv_label_t * label = (lv_label_t *)obj;
|
||||
label->max_lines = lines;
|
||||
lv_label_refr_text(obj);
|
||||
}
|
||||
|
||||
void lv_label_set_text_selection_start(lv_obj_t * obj, uint32_t index)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
@@ -284,6 +297,13 @@ lv_label_long_mode_t lv_label_get_long_mode(const lv_obj_t * obj)
|
||||
return label->long_mode;
|
||||
}
|
||||
|
||||
int32_t lv_label_get_max_lines(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
const lv_label_t * label = (const lv_label_t *)obj;
|
||||
return label->max_lines;
|
||||
}
|
||||
|
||||
void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t * pos)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
@@ -840,6 +860,11 @@ static void lv_label_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
||||
lv_text_get_size_attributes(&label->size_cache, label->text, font, &attributes);
|
||||
lv_label_set_dots(obj, dot_begin);
|
||||
|
||||
if(label->max_lines > 0) {
|
||||
label->size_cache.y = LV_MIN(label->size_cache.y,
|
||||
lv_font_get_line_height(font) * label->max_lines + line_space * (label->max_lines - 1));
|
||||
}
|
||||
|
||||
lv_text_leading_trim_t leading_trim =
|
||||
lv_obj_get_style_text_leading_trim(obj, LV_PART_MAIN);
|
||||
if(leading_trim != LV_TEXT_LEADING_TRIM_NONE) {
|
||||
|
||||
@@ -36,6 +36,7 @@ struct _lv_label_t {
|
||||
#endif /*LV_USE_TRANSLATION*/
|
||||
char dot[LV_LABEL_DOT_NUM + 1]; /**< Bytes that have been replaced with dots */
|
||||
uint32_t dot_begin; /**< Offset where bytes have been replaced with dots */
|
||||
int32_t max_lines;
|
||||
|
||||
#if LV_LABEL_LONG_TXT_HINT
|
||||
lv_draw_label_hint_t hint;
|
||||
|
||||
@@ -14,8 +14,9 @@
|
||||
* Generated code from properties.py
|
||||
*/
|
||||
/* *INDENT-OFF* */
|
||||
const lv_property_name_t lv_label_property_names[4] = {
|
||||
const lv_property_name_t lv_label_property_names[5] = {
|
||||
{"long_mode", LV_PROPERTY_LABEL_LONG_MODE,},
|
||||
{"max_lines", LV_PROPERTY_LABEL_MAX_LINES,},
|
||||
{"text", LV_PROPERTY_LABEL_TEXT,},
|
||||
{"text_selection_end", LV_PROPERTY_LABEL_TEXT_SELECTION_END,},
|
||||
{"text_selection_start", LV_PROPERTY_LABEL_TEXT_SELECTION_START,},
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
@@ -773,6 +773,34 @@ void test_label_long_mode_clip(void)
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT(buf);
|
||||
}
|
||||
|
||||
void test_label_max_lines(void)
|
||||
{
|
||||
lv_obj_clean(lv_screen_active());
|
||||
lv_obj_t * parent = lv_obj_create(lv_screen_active());
|
||||
lv_obj_set_size(parent, LV_PCT(100), LV_PCT(100));
|
||||
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_flex_align(parent, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||
lv_obj_set_style_text_line_space(parent, 10, LV_PART_MAIN);
|
||||
|
||||
const char * texts[] = {
|
||||
"Fits in single line",
|
||||
"Length such that exactly three lines will be needed for this text",
|
||||
"Text\nwith line breaks\nwhere display will need more than three lines",
|
||||
};
|
||||
|
||||
for(int i = 0; i < 3; i++) {
|
||||
lv_obj_t * test_label = lv_label_create(parent);
|
||||
lv_obj_set_width(test_label, 200);
|
||||
lv_obj_set_style_bg_color(test_label, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN);
|
||||
lv_obj_set_style_bg_opa(test_label, LV_OPA_100, LV_PART_MAIN);
|
||||
lv_label_set_long_mode(test_label, LV_LABEL_LONG_MODE_DOTS);
|
||||
lv_label_set_text(test_label, texts[i]);
|
||||
lv_label_set_max_lines(test_label, 3);
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/label_max_lines.png");
|
||||
}
|
||||
|
||||
void test_label_wrap_mode_clip(void)
|
||||
{
|
||||
lv_obj_clean(lv_screen_active());
|
||||
|
||||
Reference in New Issue
Block a user