new_style: integrate label

This commit is contained in:
Gabor Kiss-Vamosi
2019-12-19 22:44:18 +01:00
parent 446a318e6e
commit 374657c1be
9 changed files with 1039 additions and 861 deletions

View File

@@ -1229,6 +1229,11 @@ void lv_obj_set_style_opa(lv_obj_t * obj, lv_style_property_t prop, lv_opa_t opa
lv_style_set_opa(&obj->style_dsc.local, prop, opa);
}
void lv_obj_set_style_ptr(lv_obj_t * obj, lv_style_property_t prop, void * p)
{
lv_style_set_ptr(&obj->style_dsc.local, prop, p);
}
void lv_obj_add_style_class(lv_obj_t * obj, uint8_t type, lv_style_t * style)
{
lv_style_classes_t * class = lv_mem_alloc(sizeof(lv_style_classes_t));
@@ -1258,6 +1263,8 @@ void lv_obj_refresh_style(lv_obj_t * obj, uint8_t type)
lv_obj_invalidate(obj);
obj->signal_cb(obj, LV_SIGNAL_STYLE_CHG, &type);
lv_obj_invalidate(obj);
refresh_children_style(obj, type)
}
/**
@@ -2072,7 +2079,7 @@ lv_style_value_t lv_obj_get_style_value(const lv_obj_t * obj, uint8_t type, lv_s
const lv_obj_t * parent = obj;
while(parent) {
lv_style_dsc_t * dsc = lv_obj_get_style(obj, type);
lv_style_dsc_t * dsc = lv_obj_get_style(parent, type);
if(dsc == NULL) continue;
int16_t weight_act;
@@ -2131,7 +2138,7 @@ lv_color_t lv_obj_get_style_color(const lv_obj_t * obj, uint8_t type, lv_style_p
const lv_obj_t * parent = obj;
while(parent) {
lv_style_dsc_t * dsc = lv_obj_get_style(obj, type);
lv_style_dsc_t * dsc = lv_obj_get_style(parent, type);
if(dsc == NULL) continue;
int16_t weight_act;
lv_color_t value_act;
@@ -2169,6 +2176,12 @@ lv_color_t lv_obj_get_style_color(const lv_obj_t * obj, uint8_t type, lv_style_p
if(weight >= 0) return value;
prop = prop & (~LV_STYLE_STATE_MASK);
switch(prop) {
case LV_STYLE_TEXT_COLOR:
return LV_COLOR_BLACK;
}
return LV_COLOR_WHITE;
}
@@ -2183,7 +2196,7 @@ lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t type, lv_style_prope
const lv_obj_t * parent = obj;
while(parent) {
lv_style_dsc_t * dsc = lv_obj_get_style(obj, type);
lv_style_dsc_t * dsc = lv_obj_get_style(parent, type);
if(dsc == NULL) continue;
int16_t weight_act;
@@ -2205,7 +2218,7 @@ lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t type, lv_style_prope
weight_act = lv_style_get_opa(classes->style, prop, &value_act);
/*On perfect match return the value immediately*/
if(weight_act == weight_goal) {
return weight_act;
return value_act;
}
/*If the found ID is better the current candidate then use it*/
else if(weight_act >= weight) {
@@ -2225,6 +2238,67 @@ lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t type, lv_style_prope
return LV_OPA_COVER;
}
void * lv_obj_get_style_ptr(const lv_obj_t * obj, uint8_t type, lv_style_property_t prop)
{
lv_style_attr_t attr;
attr.full = prop >> 8;
int16_t weight_goal = attr.bits.state;
int16_t weight = -1;
void * value;
const lv_obj_t * parent = obj;
while(parent) {
lv_style_dsc_t * dsc = lv_obj_get_style(parent, type);
if(dsc == NULL) continue;
int16_t weight_act;
void * value_act;
weight_act = lv_style_get_ptr(&dsc->local, prop, &value_act);
/*On perfect match return the value immediately*/
if(weight_act == weight_goal) {
return value_act;
}
/*If the found ID is better the current candidate then use it*/
else if(weight_act >= weight) {
weight = weight_act;
value = value_act;
}
const lv_style_classes_t * classes = obj->style_dsc.classes;
while(classes) {
weight_act = lv_style_get_ptr(classes->style, prop, &value_act);
/*On perfect match return the value immediately*/
if(weight_act == weight_goal) {
return value_act;
}
/*If the found ID is better the current candidate then use it*/
else if(weight_act >= weight) {
weight = weight_act;
value = value_act;
}
classes = classes->next;
}
if(attr.bits.inherit == 0) break;
parent = lv_obj_get_parent(parent);
}
if(weight >= 0) return value;
prop = prop & (~LV_STYLE_STATE_MASK);
switch(prop) {
case LV_STYLE_FONT:
return LV_FONT_DEFAULT;
}
return NULL;
}
/*-----------------
* Attribute get
*----------------*/
@@ -2402,7 +2476,14 @@ bool lv_obj_is_protected(const lv_obj_t * obj, uint8_t prot)
lv_obj_state_t lv_obj_get_state(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->state;
uint8_t state = 0;
const lv_obj_t * parent = obj;
while(parent) {
state |= parent->state;
parent = lv_obj_get_parent(parent);
}
return state;
}
/**
@@ -2601,10 +2682,8 @@ static void lv_obj_del_async_cb(void * obj)
*/
void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t type, lv_obj_state_t state, lv_draw_rect_dsc_t * draw_dsc)
{
lv_style_state_t style_state = state << LV_STYLE_STATE_POS;
lv_draw_rect_dsc_init(draw_dsc);
draw_dsc->radius = lv_obj_get_style_value(obj, type, LV_STYLE_RADIUS | style_state);
draw_dsc->bg_color = lv_obj_get_style_color(obj, type, LV_STYLE_BG_COLOR | style_state);
@@ -2619,6 +2698,16 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t type, lv_obj_state_t stat
}
}
void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint8_t type, lv_obj_state_t state, lv_draw_label_dsc_t * draw_dsc)
{
lv_style_state_t style_state = state << LV_STYLE_STATE_POS;
draw_dsc->color = lv_obj_get_style_color(obj, type, LV_STYLE_TEXT_COLOR| style_state);
draw_dsc->font = lv_obj_get_style_ptr(obj, type, LV_STYLE_FONT | style_state);
}
/**
* Handle the drawing related tasks of the base objects.
* @param obj pointer to an object
@@ -2667,6 +2756,7 @@ static lv_design_res_t lv_obj_design(lv_obj_t * obj, const lv_area_t * clip_area
}
else if(mode == LV_DESIGN_DRAW_MAIN) {
lv_draw_rect_dsc_t draw_dsc;
lv_draw_rect_dsc_init(&draw_dsc);
lv_obj_init_draw_rect_dsc(obj, LV_OBJ_STYLE_MAIN, lv_obj_get_state(obj), &draw_dsc);
lv_draw_rect(&obj->coords, clip_area, &draw_dsc, lv_obj_get_opa_scale(obj));
@@ -2780,19 +2870,14 @@ static void report_style_mod_core(void * style_p, lv_obj_t * obj)
* because the NULL styles are inherited from the parent
* @param obj pointer to an object
*/
static void refresh_children_style(lv_obj_t * obj)
static void refresh_children_style(lv_obj_t * obj, uint8_t type)
{
// lv_obj_t * child = lv_obj_get_child(obj, NULL);
// while(child != NULL) {
// if(child->style_p == NULL) {
// refresh_children_style(child); /*Check children too*/
// lv_obj_refresh_style(child); /*Notify the child about the style change*/
// } else if(child->style_p->glass) {
// /*Children with 'glass' parent might be effected if their class == NULL*/
// refresh_children_style(child);
// }
// child = lv_obj_get_child(obj, child);
// }
lv_obj_t * child = lv_obj_get_child(obj, NULL);
while(child != NULL) {
refresh_children_style(child); /*Check children too*/
lv_obj_refresh_style(child); /*Notify the child about the style change*/
child = lv_obj_get_child(obj, child);
}
}
/**

View File

@@ -470,6 +470,8 @@ void lv_obj_set_style_value(lv_obj_t * obj, lv_style_property_t prop, lv_style_v
void lv_obj_set_style_opa(lv_obj_t * obj, lv_style_property_t prop, lv_opa_t opa);
void lv_obj_set_style_ptr(lv_obj_t * obj, lv_style_property_t prop, void * p);
void lv_obj_add_style_class(lv_obj_t * obj, uint8_t type, lv_style_t * style);
/**
* Notify an object about its style is modified
@@ -829,6 +831,7 @@ lv_color_t lv_obj_get_style_color(const lv_obj_t * obj, uint8_t type, lv_style_p
lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t type, lv_style_property_t prop);
void * lv_obj_get_style_ptr(const lv_obj_t * obj, uint8_t type, lv_style_property_t prop);
///**
// * Get the style pointer of an object (if NULL get style of the parent)
// * @param obj pointer to an object
@@ -1036,6 +1039,8 @@ lv_res_t lv_obj_handle_get_type_signal(lv_obj_type_t * buf, const char * name);
*/
void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t type, lv_obj_state_t state, lv_draw_rect_dsc_t * draw_dsc);
void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint8_t type, lv_obj_state_t state, lv_draw_label_dsc_t * draw_dsc);
/**********************
* MACROS
**********************/

View File

@@ -165,6 +165,34 @@ void lv_style_set_opa(lv_style_t * style, lv_style_property_t prop, lv_opa_t opa
memcpy(style->map + style->size - sizeof(lv_opa_t), &opa, sizeof(lv_opa_t));
}
void lv_style_set_ptr(lv_style_t * style, lv_style_property_t prop, void * p)
{
int32_t id = get_property_index(style, prop);
/*The property already exists but not sure it's state is the same*/
if(id >= 0) {
lv_style_attr_t attr_found;
lv_style_attr_t attr_goal;
attr_found.full = *(style->map + id + 1);
attr_goal.full = (prop >> 8) & 0xFFU;
if(attr_found.bits.state == attr_goal.bits.state) {
memcpy(style->map + id + sizeof(lv_style_property_t), &p, sizeof(void *));
return;
}
}
/*Add new property if not exists yet*/
style->size += sizeof(lv_style_property_t) + sizeof(void *);
style->map = lv_mem_realloc(style->map, style->size);
LV_ASSERT_MEM(style->map);
if(style == NULL) return;
memcpy(style->map + style->size - (sizeof(lv_style_property_t) + sizeof(void *)), &prop, sizeof(lv_style_property_t));
memcpy(style->map + style->size - sizeof(void *), &p, sizeof(void *));
}
/**
* Get the a property from a style.
* Take into account the style state and return the property which matches the best.
@@ -227,6 +255,25 @@ int16_t lv_style_get_color(const lv_style_t * style, lv_style_property_t prop, l
}
}
int16_t lv_style_get_ptr(const lv_style_t * style, lv_style_property_t prop, void ** res)
{
int32_t id = get_property_index(style, prop);
if(id < 0) {
return -1;
} else {
memcpy(res, &style->map[id + sizeof(lv_style_property_t)], sizeof(void*));
lv_style_attr_t attr_act;
attr_act.full = style->map[id + 1];
lv_style_attr_t attr_goal;
attr_goal.full = (prop >> 8) & 0xFF;
return attr_act.bits.state & attr_goal.bits.state;
}
}
/**
* Mix two styles according to a given ratio
* @param start start style

View File

@@ -58,7 +58,7 @@ typedef uint8_t lv_grad_dir_t;
#define LV_STYLE_ID_MASK 0x00FF
#define LV_STYLE_ATTR_NONE 0
#define LV_STYLE_ATTR_INHERIT (1 << 8)
#define LV_STYLE_ATTR_INHERIT (1 << 7)
typedef union {
struct {
@@ -104,8 +104,14 @@ enum {
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_COLOR, 0x4, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_OPA, 0x4, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_NONE),
// LV_STYLE_PROP_INIT(LV_STYLE_TEXT_COLOR, 0x40, LV_STYLE_ATTR_TYPE_COLOR),
// LV_STYLE_PROP_INIT(LV_STYLE_LINE_COLOR, 0x50, LV_STYLE_ATTR_TYPE_COLOR),
LV_STYLE_PROP_INIT(LV_STYLE_LETTER_SPACE, 0x5, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_INHERIT),
LV_STYLE_PROP_INIT(LV_STYLE_LINE_SPACE, 0x5, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_INHERIT),
LV_STYLE_PROP_INIT(LV_STYLE_BLEND_MODE, 0x5, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_TEXT_COLOR, 0x5, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_INHERIT),
LV_STYLE_PROP_INIT(LV_STYLE_TEXT_OPA, 0x5, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_FONT, 0x5, LV_STYLE_ID_PTR + 0, LV_STYLE_ATTR_INHERIT),
// LV_STYLE_PROP_INIT(LV_STYLE_LINE_COLOR, 0x50, LV_STYLE_ATTR_TYPE_COLOR),
// LV_STYLE_PROP_INIT(LV_STYLE_IMG_COLOR, 0x60, LV_STYLE_ATTR_TYPE_COLOR),
};
@@ -191,11 +197,13 @@ void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t *
void lv_style_set_value(lv_style_t * style, lv_style_property_t prop, lv_style_value_t value);
void lv_style_set_color(lv_style_t * style, lv_style_property_t prop, lv_color_t color);
void lv_style_set_opa(lv_style_t * style, lv_style_property_t prop, lv_opa_t opa);
void lv_style_set_ptr(lv_style_t * style, lv_style_property_t prop, void * p);
int16_t lv_style_get_value(const lv_style_t * style, lv_style_property_t prop, lv_style_value_t * res);
int16_t lv_style_get_opa(const lv_style_t * style, lv_style_property_t prop, lv_opa_t * res);
int16_t lv_style_get_color(const lv_style_t * style, lv_style_property_t prop, lv_color_t * res);
int16_t lv_style_get_ptr(const lv_style_t * style, lv_style_property_t prop, void ** res);
#if LV_USE_ANIMATION

File diff suppressed because it is too large Load Diff

View File

@@ -25,12 +25,20 @@ extern "C" {
* TYPEDEFS
**********************/
typedef struct
{
uint16_t start;
uint16_t end;
}lv_draw_label_txt_sel_t;
typedef struct {
lv_color_t color;
lv_color_t sel_color;
const lv_font_t * font;
lv_opa_t opa;
lv_style_value_t line_space;
lv_style_value_t letter_space;
uint16_t sel_start;
uint16_t sel_end;
lv_coord_t ofs_x;
lv_coord_t ofs_y;
lv_bidi_dir_t bidi_dir;
lv_txt_flag_t flag;
}lv_draw_label_dsc_t;
/** Store some info to speed up drawing of very large texts
* It takes a lot of time to get the first visible character because
@@ -53,6 +61,8 @@ typedef struct {
* GLOBAL PROTOTYPES
**********************/
void lv_draw_label_dsc_init(lv_draw_label_dsc_t * dsc);
/**
* Write a text
* @param coords coordinates of the label
@@ -65,9 +75,8 @@ typedef struct {
* @param sel_start start index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
* @param bidi_dir base direction of the text
*/
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale,
const char * txt, lv_txt_flag_t flag, lv_point_t * offset, lv_draw_label_txt_sel_t * sel,
lv_draw_label_hint_t * hint, lv_bidi_dir_t bidi_dir);
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, lv_draw_label_dsc_t * dsc,
const char * txt, lv_opa_t opa_scale, lv_draw_label_hint_t * hint);
/**********************
* MACROS

View File

@@ -452,9 +452,10 @@ static lv_design_res_t lv_btn_design(lv_obj_t * btn, const lv_area_t * clip_area
}
#else
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
lv_draw_rect_dsc_t draw_dsc;
lv_obj_state_t state = lv_obj_get_state(btn);
lv_draw_rect_dsc_t draw_dsc;
lv_draw_rect_dsc_init(&draw_dsc);
lv_obj_init_draw_rect_dsc(btn, LV_OBJ_STYLE_MAIN, state, &draw_dsc);
lv_draw_rect(&btn->coords, clip_area, &draw_dsc, lv_obj_get_opa_scale(btn));

View File

@@ -113,8 +113,8 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)
#endif
#if LV_LABEL_TEXT_SEL
ext->txt_sel.start = LV_DRAW_LABEL_NO_TXT_SEL;
ext->txt_sel.end = LV_DRAW_LABEL_NO_TXT_SEL;
ext->sel_start = LV_DRAW_LABEL_NO_TXT_SEL;
ext->sel_end = LV_DRAW_LABEL_NO_TXT_SEL;
#endif
ext->dot.tmp_ptr = NULL;
ext->dot_tmp_alloc = 0;
@@ -127,7 +127,6 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)
lv_obj_set_click(new_label, false);
lv_label_set_long_mode(new_label, LV_LABEL_LONG_EXPAND);
lv_label_set_text(new_label, "Text");
lv_label_set_style(new_label, LV_LABEL_STYLE_MAIN, NULL); /*Inherit parent's style*/
}
/*Copy 'copy' if not NULL*/
else {
@@ -159,7 +158,7 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)
ext->dot_end = copy_ext->dot_end;
/*Refresh the style with new signal function*/
lv_obj_refresh_style(new_label);
// lv_obj_refresh_style(new_label);
}
LV_LOG_INFO("label created");
@@ -450,7 +449,7 @@ void lv_label_set_text_sel_start(lv_obj_t * label, uint16_t index)
#if LV_LABEL_TEXT_SEL
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
ext->txt_sel.start = index;
ext->sel_start = index;
lv_obj_invalidate(label);
#else
(void)label; /*Unused*/
@@ -464,7 +463,7 @@ void lv_label_set_text_sel_end(lv_obj_t * label, uint16_t index)
#if LV_LABEL_TEXT_SEL
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
ext->txt_sel.end = index;
ext->sel_end = index;
lv_obj_invalidate(label);
#else
(void)label; /*Unused*/
@@ -592,8 +591,9 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t char_id, lv_point_
uint32_t line_start = 0;
uint32_t new_line_start = 0;
lv_coord_t max_w = lv_obj_get_width(label);
const lv_style_t * style = lv_obj_get_style(label);
const lv_font_t * font = style->text.font;
const lv_font_t * font = lv_obj_get_style_ptr(label, LV_LABEL_STYLE_MAIN, LV_STYLE_FONT);
lv_style_value_t line_space = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_LINE_SPACE);
lv_style_value_t letter_space = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_LETTER_SPACE);
lv_coord_t letter_height = lv_font_get_line_height(font);
lv_coord_t y = 0;
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
@@ -614,18 +614,18 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t char_id, lv_point_
/*Search the line of the index letter */;
while(txt[new_line_start] != '\0') {
new_line_start += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag);
new_line_start += lv_txt_get_next_line(&txt[line_start], font, letter_space, max_w, flag);
if(byte_id < new_line_start || txt[new_line_start] == '\0')
break; /*The line of 'index' letter begins at 'line_start'*/
y += letter_height + style->text.line_space;
y += letter_height + line_space;
line_start = new_line_start;
}
/*If the last character is line break then go to the next line*/
if(byte_id > 0) {
if((txt[byte_id - 1] == '\n' || txt[byte_id - 1] == '\r') && txt[byte_id] == '\0') {
y += letter_height + style->text.line_space;
y += letter_height + line_space;
line_start = byte_id;
}
}
@@ -655,18 +655,18 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t char_id, lv_point_
/*Calculate the x coordinate*/
lv_coord_t x = lv_txt_get_width(bidi_txt, visual_byte_pos, font, style->text.letter_space, flag);
lv_coord_t x = lv_txt_get_width(bidi_txt, visual_byte_pos, font, letter_space, flag);
if(char_id != line_start) x += style->text.letter_space;
if(char_id != line_start) x += letter_space;
if(align == LV_LABEL_ALIGN_CENTER) {
lv_coord_t line_w;
line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag);
line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, 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(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag);
line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, letter_space, flag);
x += lv_obj_get_width(label) - line_w;
}
@@ -695,8 +695,9 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
uint32_t line_start = 0;
uint32_t new_line_start = 0;
lv_coord_t max_w = lv_obj_get_width(label);
const lv_style_t * style = lv_obj_get_style(label);
const lv_font_t * font = style->text.font;
const lv_font_t * font = lv_obj_get_style_ptr(label, LV_LABEL_STYLE_MAIN, LV_STYLE_FONT);
lv_style_value_t line_space = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_LINE_SPACE);
lv_style_value_t letter_space = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_LETTER_SPACE);
lv_coord_t letter_height = lv_font_get_line_height(font);
lv_coord_t y = 0;
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
@@ -717,7 +718,7 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
/*Search the line of the index letter */;
while(txt[line_start] != '\0') {
new_line_start += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag);
new_line_start += lv_txt_get_next_line(&txt[line_start], font, letter_space, max_w, flag);
if(pos->y <= y + letter_height) {
/*The line is found (stored in 'line_start')*/
@@ -728,7 +729,7 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
if(letter != '\n' && txt[new_line_start] == '\0' ) new_line_start++;
break;
}
y += letter_height + style->text.line_space;
y += letter_height + line_space;
line_start = new_line_start;
}
@@ -746,12 +747,12 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
lv_coord_t x = 0;
if(align == LV_LABEL_ALIGN_CENTER) {
lv_coord_t line_w;
line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag);
line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, 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(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag);
line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, letter_space, flag);
x += lv_obj_get_width(label) - line_w;
}
@@ -784,7 +785,7 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
i = i_act;
break;
}
x += style->text.letter_space;
x += letter_space;
i_act = i;
}
}
@@ -813,7 +814,7 @@ uint16_t lv_label_get_text_sel_start(const lv_obj_t * label)
#if LV_LABEL_TEXT_SEL
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
return ext->txt_sel.start;
return ext->sel_start;
#else
(void)label; /*Unused*/
@@ -832,7 +833,7 @@ uint16_t lv_label_get_text_sel_end(const lv_obj_t * label)
#if LV_LABEL_TEXT_SEL
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
return ext->txt_sel.end;
return ext->sel_end;
#else
(void)label; /*Unused*/
return LV_LABEL_TEXT_SEL_OFF;
@@ -855,8 +856,9 @@ bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos)
uint32_t line_start = 0;
uint32_t new_line_start = 0;
lv_coord_t max_w = lv_obj_get_width(label);
const lv_style_t * style = lv_obj_get_style(label);
const lv_font_t * font = style->text.font;
const lv_font_t * font = lv_obj_get_style_ptr(label, LV_LABEL_STYLE_MAIN, LV_STYLE_FONT);
lv_style_value_t line_space = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_LINE_SPACE);
lv_style_value_t letter_space = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_LETTER_SPACE);
lv_coord_t letter_height = lv_font_get_line_height(font);
lv_coord_t y = 0;
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
@@ -873,10 +875,10 @@ bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos)
/*Search the line of the index letter */;
while(txt[line_start] != '\0') {
new_line_start += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag);
new_line_start += lv_txt_get_next_line(&txt[line_start], font, letter_space, max_w, flag);
if(pos->y <= y + letter_height) break; /*The line is found (stored in 'line_start')*/
y += letter_height + style->text.line_space;
y += letter_height + line_space;
line_start = new_line_start;
}
@@ -886,12 +888,12 @@ bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos)
lv_coord_t last_x = 0;
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);
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, 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);
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, letter_space, flag);
x += lv_obj_get_width(label) - line_w;
}
@@ -923,15 +925,28 @@ bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos)
i = i_current;
break;
}
x += style->text.letter_space;
x += letter_space;
i_current = i;
}
}
int32_t max_diff = lv_font_get_glyph_width(font, letter, letter_next) + style->text.letter_space + 1;
return (pos->x >= (last_x - style->text.letter_space) && pos->x <= (last_x + max_diff));
int32_t max_diff = lv_font_get_glyph_width(font, letter, letter_next) + letter_space + 1;
return (pos->x >= (last_x - letter_space) && pos->x <= (last_x + max_diff));
}
lv_style_dsc_t * lv_label_get_style(lv_obj_t * label, uint8_t type)
{
lv_style_dsc_t * style_dsc_p;
switch(type) {
case LV_LABEL_STYLE_MAIN:
style_dsc_p = &label->style_dsc;
break;
default:
style_dsc_p = NULL;
}
return style_dsc_p;
}
/*=====================
* Other functions
*====================*/
@@ -1029,28 +1044,32 @@ static lv_design_res_t lv_label_design(lv_obj_t * label, const lv_area_t * clip_
return LV_DESIGN_RES_NOT_COVER;
else if(mode == LV_DESIGN_DRAW_MAIN) {
lv_area_t coords;
const lv_style_t * style = lv_obj_get_style(label);
const lv_font_t * font = lv_obj_get_style_ptr(label, LV_LABEL_STYLE_MAIN, LV_STYLE_FONT);
lv_style_value_t line_space = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_LINE_SPACE);
lv_style_value_t letter_space = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_LETTER_SPACE);
lv_opa_t opa_scale = lv_obj_get_opa_scale(label);
lv_obj_get_coords(label, &coords);
#if LV_USE_GROUP
lv_group_t * g = lv_obj_get_group(label);
if(lv_group_get_focused(g) == label) {
lv_draw_rect(&coords, clip_area, style, opa_scale);
}
#endif
lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
lv_obj_state_t state = lv_obj_get_state(label);
if(ext->body_draw) {
lv_area_t bg;
lv_obj_get_coords(label, &bg);
bg.x1 -= style->body.padding.left;
bg.x2 += style->body.padding.right;
bg.y1 -= style->body.padding.top;
bg.y2 += style->body.padding.bottom;
lv_draw_rect(&bg, clip_area, style, lv_obj_get_opa_scale(label));
lv_coord_t left = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_PAD_LEFT);
lv_coord_t right = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_PAD_RIGHT);
lv_coord_t top = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_PAD_TOP);
lv_coord_t bottom = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_PAD_BOTTOM);
bg.x1 -= left;
bg.x2 += right;
bg.y1 -= top;
bg.y2 += bottom;
lv_draw_rect_dsc_t draw_rect_dsc;
lv_draw_rect_dsc_init(&draw_rect_dsc);
lv_obj_init_draw_rect_dsc(label, LV_LABEL_STYLE_MAIN, state, &draw_rect_dsc);
lv_draw_rect(&bg, clip_area, &draw_rect_dsc, lv_obj_get_opa_scale(label));
}
lv_label_align_t align = lv_label_get_align(label);
@@ -1066,7 +1085,7 @@ static lv_design_res_t lv_label_design(lv_obj_t * label, const lv_area_t * clip_
if((ext->long_mode == LV_LABEL_LONG_SROLL || ext->long_mode == LV_LABEL_LONG_SROLL_CIRC) &&
(ext->align == LV_LABEL_ALIGN_CENTER || ext->align == LV_LABEL_ALIGN_RIGHT)) {
lv_point_t size;
lv_txt_get_size(&size, ext->text, style->text.font, style->text.letter_space, style->text.line_space,
lv_txt_get_size(&size, ext->text, font, letter_space, line_space,
LV_COORD_MAX, flag);
if(size.x > lv_obj_get_width(label)) {
flag &= ~LV_TXT_FLAG_RIGHT;
@@ -1082,33 +1101,39 @@ static lv_design_res_t lv_label_design(lv_obj_t * label, const lv_area_t * clip_
/*Just for compatibility*/
lv_draw_label_hint_t * hint = NULL;
#endif
lv_draw_label_txt_sel_t sel;
sel.start = lv_label_get_text_sel_start(label);
sel.end = lv_label_get_text_sel_end(label);
lv_draw_label(&coords, clip_area, style, opa_scale, ext->text, flag, &ext->offset, &sel, hint, lv_obj_get_base_dir(label));
lv_draw_label_dsc_t label_draw_dsc;
lv_draw_label_dsc_init(&label_draw_dsc);
label_draw_dsc.sel_start = lv_label_get_text_sel_start(label);
label_draw_dsc.sel_end = lv_label_get_text_sel_end(label);
label_draw_dsc.ofs_x = ext->offset.x;
label_draw_dsc.ofs_y = ext->offset.y;
label_draw_dsc.flag = flag;
lv_obj_init_draw_label_dsc(label, LV_LABEL_STYLE_MAIN, state, &label_draw_dsc);
lv_draw_label(&coords, clip_area, &label_draw_dsc, ext->text, opa_scale, hint);
if(ext->long_mode == LV_LABEL_LONG_SROLL_CIRC) {
lv_point_t size;
lv_txt_get_size(&size, ext->text, style->text.font, style->text.letter_space, style->text.line_space,
lv_txt_get_size(&size, ext->text, font, letter_space, line_space,
LV_COORD_MAX, flag);
lv_point_t ofs;
/*Draw the text again next to the original to make an circular effect */
if(size.x > lv_obj_get_width(label)) {
ofs.x = ext->offset.x + size.x +
lv_font_get_glyph_width(style->text.font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT;
ofs.y = ext->offset.y;
label_draw_dsc.ofs_x = ext->offset.x + size.x +
lv_font_get_glyph_width(font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT;
label_draw_dsc.ofs_y = ext->offset.y;
lv_draw_label(&coords, clip_area, style, opa_scale, ext->text, flag, &ofs, &sel, NULL, lv_obj_get_base_dir(label));
lv_draw_label(&coords, clip_area, &label_draw_dsc, ext->text, opa_scale, hint);
}
/*Draw the text again below the original to make an circular effect */
if(size.y > lv_obj_get_height(label)) {
ofs.x = ext->offset.x;
ofs.y = ext->offset.y + size.y + lv_font_get_line_height(style->text.font);
lv_draw_label(&coords, clip_area, style, opa_scale, ext->text, flag, &ofs, &sel, NULL, lv_obj_get_base_dir(label));
label_draw_dsc.ofs_x = ext->offset.x;
label_draw_dsc.ofs_y = ext->offset.y + size.y + lv_font_get_line_height(font);
lv_draw_label(&coords, clip_area, &label_draw_dsc, ext->text, opa_scale, hint);
}
}
}
@@ -1127,6 +1152,13 @@ static lv_res_t lv_label_signal(lv_obj_t * label, lv_signal_t sign, void * param
{
lv_res_t res;
if(sign == LV_SIGNAL_GET_STYLE) {
uint8_t ** type_p = param;
lv_style_dsc_t ** style_dsc_p = param;
*style_dsc_p = lv_label_get_style(label, **type_p);
return LV_RES_OK;
}
/* Include the ancient signal function */
res = ancestor_signal(label, sign, param);
if(res != LV_RES_OK) return res;
@@ -1152,12 +1184,14 @@ static lv_res_t lv_label_signal(lv_obj_t * label, lv_signal_t sign, void * param
}
} else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
if(ext->body_draw) {
const lv_style_t * style = lv_label_get_style(label, LV_LABEL_STYLE_MAIN);
label->ext_draw_pad = LV_MATH_MAX(label->ext_draw_pad, style->body.padding.left);
label->ext_draw_pad = LV_MATH_MAX(label->ext_draw_pad, style->body.padding.right);
label->ext_draw_pad = LV_MATH_MAX(label->ext_draw_pad, style->body.padding.top);
label->ext_draw_pad = LV_MATH_MAX(label->ext_draw_pad, style->body.padding.bottom);
lv_coord_t left = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_PAD_LEFT);
lv_coord_t right = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_PAD_RIGHT);
lv_coord_t top = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_PAD_TOP);
lv_coord_t bottom = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_PAD_BOTTOM);
label->ext_draw_pad = LV_MATH_MAX(label->ext_draw_pad, left);
label->ext_draw_pad = LV_MATH_MAX(label->ext_draw_pad, right);
label->ext_draw_pad = LV_MATH_MAX(label->ext_draw_pad, top);
label->ext_draw_pad = LV_MATH_MAX(label->ext_draw_pad, bottom);
}
}
else if(sign == LV_SIGNAL_BASE_DIR_CHG) {
@@ -1190,8 +1224,9 @@ static void lv_label_refr_text(lv_obj_t * label)
#endif
lv_coord_t max_w = lv_obj_get_width(label);
const lv_style_t * style = lv_obj_get_style(label);
const lv_font_t * font = style->text.font;
const lv_font_t * font = lv_obj_get_style_ptr(label, LV_LABEL_STYLE_MAIN, LV_STYLE_FONT);
lv_style_value_t line_space = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_LINE_SPACE);
lv_style_value_t letter_space = lv_obj_get_style_value(label, LV_LABEL_STYLE_MAIN, LV_STYLE_LETTER_SPACE);
/*If the width will be expanded set the max length to very big */
if(ext->long_mode == LV_LABEL_LONG_EXPAND) {
@@ -1203,7 +1238,7 @@ static void lv_label_refr_text(lv_obj_t * label)
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;
lv_txt_get_size(&size, ext->text, font, style->text.letter_space, style->text.line_space, max_w, flag);
lv_txt_get_size(&size, ext->text, font, letter_space, line_space, max_w, flag);
/*Set the full size in expand mode*/
if(ext->long_mode == LV_LABEL_LONG_EXPAND) {
@@ -1220,7 +1255,7 @@ static void lv_label_refr_text(lv_obj_t * label)
anim.ready_cb = NULL;
anim.path_cb = lv_anim_path_linear;
anim.playback_pause =
(((lv_font_get_glyph_width(style->text.font, ' ', ' ') + style->text.letter_space) * 1000) /
(((lv_font_get_glyph_width(font, ' ', ' ') + letter_space) * 1000) /
ext->anim_speed) *
LV_LABEL_WAIT_CHAR_COUNT;
anim.repeat_pause = anim.playback_pause;
@@ -1261,7 +1296,7 @@ static void lv_label_refr_text(lv_obj_t * label)
anim.var = label;
anim.repeat = 1;
anim.playback = 0;
anim.act_time = -(((lv_font_get_glyph_width(style->text.font, ' ', ' ') + style->text.letter_space) * 1000) /
anim.act_time = -(((lv_font_get_glyph_width(font, ' ', ' ') + letter_space) * 1000) /
ext->anim_speed) *
LV_LABEL_WAIT_CHAR_COUNT;
anim.ready_cb = NULL;
@@ -1315,12 +1350,12 @@ static void lv_label_refr_text(lv_obj_t * label)
} else {
lv_point_t p;
p.x = lv_obj_get_width(label) -
(lv_font_get_glyph_width(style->text.font, '.', '.') + style->text.letter_space) *
(lv_font_get_glyph_width(font, '.', '.') + letter_space) *
LV_LABEL_DOT_NUM; /*Shrink with dots*/
p.y = lv_obj_get_height(label);
p.y -= p.y %
(lv_font_get_line_height(style->text.font) + style->text.line_space); /*Round down to the last line*/
p.y -= style->text.line_space; /*Trim the last line space*/
(lv_font_get_line_height(font) + line_space); /*Round down to the last line*/
p.y -= line_space; /*Trim the last line space*/
uint32_t letter_id = lv_label_get_letter_on(label, &p);
/*Save letters under the dots and replace them with dots*/

View File

@@ -91,7 +91,8 @@ typedef struct
#endif
#if LV_LABEL_TEXT_SEL
lv_draw_label_txt_sel_t txt_sel;
uint16_t sel_start;
uint16_t sel_end;
#endif
lv_label_long_mode_t long_mode : 3; /*Determinate what to do with the long texts*/
@@ -108,6 +109,7 @@ typedef struct
enum {
LV_LABEL_STYLE_MAIN,
};
typedef uint8_t lv_label_style_t;
/**********************
@@ -194,18 +196,6 @@ void lv_label_set_body_draw(lv_obj_t * label, bool en);
*/
void lv_label_set_anim_speed(lv_obj_t * label, uint16_t anim_speed);
/**
* Set the style of an label
* @param label pointer to an label object
* @param type which style should be get (can be only `LV_LABEL_STYLE_MAIN`)
* @param style pointer to a style
*/
static inline void lv_label_set_style(lv_obj_t * label, lv_label_style_t type, const lv_style_t * style)
{
(void)type; /*Unused*/
lv_obj_set_style(label, style);
}
/**
* @brief Set the selection start index.
* @param label pointer to a label object.
@@ -292,18 +282,6 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos);
*/
bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos);
/**
* Get the style of an label object
* @param label pointer to an label object
* @param type which style should be get (can be only `LV_LABEL_STYLE_MAIN`)
* @return pointer to the label's style
*/
static inline const lv_style_t * lv_label_get_style(const lv_obj_t * label, lv_label_style_t type)
{
(void)type; /*Unused*/
return lv_obj_get_style(label);
}
/**
* @brief Get the selection start index.
* @param label pointer to a label object.
@@ -318,6 +296,9 @@ uint16_t lv_label_get_text_sel_start(const lv_obj_t * label);
*/
uint16_t lv_label_get_text_sel_end(const lv_obj_t * label);
lv_style_dsc_t * lv_label_get_style(lv_obj_t * label, uint8_t type);
/*=====================
* Other functions
*====================*/