mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
feat(style) add 'inherit' and 'initial' CSS properties (#3390)
Fixes #3086
This commit is contained in:
parent
03c43d95ad
commit
9a48de0f8b
@ -84,6 +84,23 @@ Inheritance is applied only if the given property is not set in the object's sty
|
|||||||
In this case, if the property is inheritable, the property's value will be searched in the parents until an object specifies a value for the property. The parents will use their own state to determine the value.
|
In this case, if the property is inheritable, the property's value will be searched in the parents until an object specifies a value for the property. The parents will use their own state to determine the value.
|
||||||
So if a button is pressed, and the text color comes from here, the pressed text color will be used.
|
So if a button is pressed, and the text color comes from here, the pressed text color will be used.
|
||||||
|
|
||||||
|
## Forced value inheritance/default value
|
||||||
|
Sometimes you may want to force a child object to use the parent's value for a given style property. To do this you can use
|
||||||
|
one of the following (depending on what type of style you're using):
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* regular style */
|
||||||
|
lv_style_set_prop_meta(&style, LV_STYLE_TEXT_COLOR, LV_STYLE_PROP_META_INHERIT);
|
||||||
|
/* local style */
|
||||||
|
lv_obj_set_local_style_prop_meta(child, LV_STYLE_TEXT_COLOR, LV_STYLE_PROP_META_INHERIT, LV_PART_MAIN);
|
||||||
|
```
|
||||||
|
|
||||||
|
This acts like a value has been set on the style, so setting the value of the property afterwards will remove the flag.
|
||||||
|
|
||||||
|
You may also want to force the default value of a property to be used, without needing to hardcode it in your application.
|
||||||
|
To do this you can use the same API but with `LV_STYLE_PROP_META_INITIAL` instead. In future versions of LVGL, this
|
||||||
|
will use the value based upon the current theme, but for now it just selects the internal default regardless of theme.
|
||||||
|
|
||||||
|
|
||||||
## Parts
|
## Parts
|
||||||
Objects can be composed of *parts* which may each have their own styles.
|
Objects can be composed of *parts* which may each have their own styles.
|
||||||
|
@ -882,7 +882,7 @@ static void lv_obj_set_state(lv_obj_t * obj, lv_state_t new_state)
|
|||||||
if(obj_style->is_trans) continue;
|
if(obj_style->is_trans) continue;
|
||||||
|
|
||||||
lv_style_value_t v;
|
lv_style_value_t v;
|
||||||
if(lv_style_get_prop_inlined(obj_style->style, LV_STYLE_TRANSITION, &v) == false) continue;
|
if(lv_style_get_prop_inlined(obj_style->style, LV_STYLE_TRANSITION, &v) != LV_STYLE_RES_FOUND) continue;
|
||||||
const lv_style_transition_dsc_t * tr = v.ptr;
|
const lv_style_transition_dsc_t * tr = v.ptr;
|
||||||
|
|
||||||
/*Add the props to the set if not added yet or added but with smaller weight*/
|
/*Add the props to the set if not added yet or added but with smaller weight*/
|
||||||
|
@ -44,7 +44,7 @@ typedef enum {
|
|||||||
**********************/
|
**********************/
|
||||||
static lv_style_t * get_local_style(lv_obj_t * obj, lv_style_selector_t selector);
|
static lv_style_t * get_local_style(lv_obj_t * obj, lv_style_selector_t selector);
|
||||||
static _lv_obj_style_t * get_trans_style(lv_obj_t * obj, uint32_t part);
|
static _lv_obj_style_t * get_trans_style(lv_obj_t * obj, uint32_t part);
|
||||||
static bool get_prop_core(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, lv_style_value_t * v);
|
static lv_style_res_t get_prop_core(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, lv_style_value_t * v);
|
||||||
static void report_style_change_core(void * style, lv_obj_t * obj);
|
static void report_style_change_core(void * style, lv_obj_t * obj);
|
||||||
static void refresh_children_style(lv_obj_t * obj);
|
static void refresh_children_style(lv_obj_t * obj);
|
||||||
static bool trans_del(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, trans_t * tr_limit);
|
static bool trans_del(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, trans_t * tr_limit);
|
||||||
@ -176,7 +176,7 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_selector_t selector, lv_style
|
|||||||
|
|
||||||
bool is_layout_refr = lv_style_prop_has_flag(prop, LV_STYLE_PROP_LAYOUT_REFR);
|
bool is_layout_refr = lv_style_prop_has_flag(prop, LV_STYLE_PROP_LAYOUT_REFR);
|
||||||
bool is_ext_draw = lv_style_prop_has_flag(prop, LV_STYLE_PROP_EXT_DRAW);
|
bool is_ext_draw = lv_style_prop_has_flag(prop, LV_STYLE_PROP_EXT_DRAW);
|
||||||
bool is_inherit = lv_style_prop_has_flag(prop, LV_STYLE_PROP_INHERIT);
|
bool is_inheritable = lv_style_prop_has_flag(prop, LV_STYLE_PROP_INHERIT);
|
||||||
bool is_layer_refr = lv_style_prop_has_flag(prop, LV_STYLE_PROP_LAYER_REFR);
|
bool is_layer_refr = lv_style_prop_has_flag(prop, LV_STYLE_PROP_LAYER_REFR);
|
||||||
|
|
||||||
if(is_layout_refr) {
|
if(is_layout_refr) {
|
||||||
@ -208,7 +208,7 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_selector_t selector, lv_style
|
|||||||
}
|
}
|
||||||
lv_obj_invalidate(obj);
|
lv_obj_invalidate(obj);
|
||||||
|
|
||||||
if(prop == LV_STYLE_PROP_ANY || (is_inherit && (is_ext_draw || is_layout_refr))) {
|
if(prop == LV_STYLE_PROP_ANY || (is_inheritable && (is_ext_draw || is_layout_refr))) {
|
||||||
if(part != LV_PART_SCROLLBAR) {
|
if(part != LV_PART_SCROLLBAR) {
|
||||||
refresh_children_style(obj);
|
refresh_children_style(obj);
|
||||||
}
|
}
|
||||||
@ -223,15 +223,15 @@ void lv_obj_enable_style_refresh(bool en)
|
|||||||
lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop)
|
lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop)
|
||||||
{
|
{
|
||||||
lv_style_value_t value_act;
|
lv_style_value_t value_act;
|
||||||
bool inherit = lv_style_prop_has_flag(prop, LV_STYLE_PROP_INHERIT);
|
bool inheritable = lv_style_prop_has_flag(prop, LV_STYLE_PROP_INHERIT);
|
||||||
bool found = false;
|
lv_style_res_t found = LV_STYLE_RES_NOT_FOUND;
|
||||||
while(obj) {
|
while(obj) {
|
||||||
found = get_prop_core(obj, part, prop, &value_act);
|
found = get_prop_core(obj, part, prop, &value_act);
|
||||||
if(found) break;
|
if(found == LV_STYLE_RES_FOUND) break;
|
||||||
if(!inherit) break;
|
if(!inheritable) break;
|
||||||
|
|
||||||
/*If not found, check the `MAIN` style first*/
|
/*If not found, check the `MAIN` style first*/
|
||||||
if(part != LV_PART_MAIN) {
|
if(found != LV_STYLE_RES_INHERIT && part != LV_PART_MAIN) {
|
||||||
part = LV_PART_MAIN;
|
part = LV_PART_MAIN;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -240,7 +240,7 @@ lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, lv_part_t part, lv_
|
|||||||
obj = lv_obj_get_parent(obj);
|
obj = lv_obj_get_parent(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!found) {
|
if(found != LV_STYLE_RES_FOUND) {
|
||||||
if(part == LV_PART_MAIN && (prop == LV_STYLE_WIDTH || prop == LV_STYLE_HEIGHT)) {
|
if(part == LV_PART_MAIN && (prop == LV_STYLE_WIDTH || prop == LV_STYLE_HEIGHT)) {
|
||||||
const lv_obj_class_t * cls = obj->class_p;
|
const lv_obj_class_t * cls = obj->class_p;
|
||||||
while(cls) {
|
while(cls) {
|
||||||
@ -275,8 +275,16 @@ void lv_obj_set_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_
|
|||||||
lv_obj_refresh_style(obj, selector, prop);
|
lv_obj_refresh_style(obj, selector, prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lv_obj_set_local_style_prop_meta(lv_obj_t * obj, lv_style_prop_t prop, uint16_t meta,
|
||||||
|
lv_style_selector_t selector)
|
||||||
|
{
|
||||||
|
lv_style_t * style = get_local_style(obj, selector);
|
||||||
|
lv_style_set_prop_meta(style, prop, meta);
|
||||||
|
lv_obj_refresh_style(obj, selector, prop);
|
||||||
|
}
|
||||||
|
|
||||||
lv_res_t lv_obj_get_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t * value,
|
|
||||||
|
lv_style_res_t lv_obj_get_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t * value,
|
||||||
lv_style_selector_t selector)
|
lv_style_selector_t selector)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
@ -287,7 +295,7 @@ lv_res_t lv_obj_get_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return LV_RES_INV;
|
return LV_STYLE_RES_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lv_obj_remove_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_selector_t selector)
|
bool lv_obj_remove_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_selector_t selector)
|
||||||
@ -556,7 +564,7 @@ static _lv_obj_style_t * get_trans_style(lv_obj_t * obj, lv_style_selector_t se
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool get_prop_core(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, lv_style_value_t * v)
|
static lv_style_res_t get_prop_core(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, lv_style_value_t * v)
|
||||||
{
|
{
|
||||||
uint8_t group = 1 << _lv_style_get_prop_group(prop);
|
uint8_t group = 1 << _lv_style_get_prop_group(prop);
|
||||||
int32_t weight = -1;
|
int32_t weight = -1;
|
||||||
@ -565,7 +573,7 @@ static bool get_prop_core(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t
|
|||||||
lv_style_value_t value_tmp;
|
lv_style_value_t value_tmp;
|
||||||
bool skip_trans = obj->skip_trans;
|
bool skip_trans = obj->skip_trans;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
bool found;
|
lv_style_res_t found;
|
||||||
for(i = 0; i < obj->style_cnt; i++) {
|
for(i = 0; i < obj->style_cnt; i++) {
|
||||||
_lv_obj_style_t * obj_style = &obj->styles[i];
|
_lv_obj_style_t * obj_style = &obj->styles[i];
|
||||||
if(obj_style->is_trans == false) break;
|
if(obj_style->is_trans == false) break;
|
||||||
@ -576,9 +584,12 @@ static bool get_prop_core(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t
|
|||||||
if(part_act != part) continue;
|
if(part_act != part) continue;
|
||||||
if((obj_style->style->has_group & group) == 0) continue;
|
if((obj_style->style->has_group & group) == 0) continue;
|
||||||
found = lv_style_get_prop(obj_style->style, prop, &value_tmp);
|
found = lv_style_get_prop(obj_style->style, prop, &value_tmp);
|
||||||
if(found) {
|
if(found == LV_STYLE_RES_FOUND) {
|
||||||
*v = value_tmp;
|
*v = value_tmp;
|
||||||
return true;
|
return LV_STYLE_RES_FOUND;
|
||||||
|
}
|
||||||
|
else if(found == LV_STYLE_RES_INHERIT) {
|
||||||
|
return LV_STYLE_RES_INHERIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,23 +609,26 @@ static bool get_prop_core(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t
|
|||||||
|
|
||||||
found = lv_style_get_prop(obj_style->style, prop, &value_tmp);
|
found = lv_style_get_prop(obj_style->style, prop, &value_tmp);
|
||||||
|
|
||||||
if(found) {
|
if(found == LV_STYLE_RES_FOUND) {
|
||||||
if(state_act == state) {
|
if(state_act == state) {
|
||||||
*v = value_tmp;
|
*v = value_tmp;
|
||||||
return true;
|
return LV_STYLE_RES_FOUND;
|
||||||
}
|
}
|
||||||
if(weight < state_act) {
|
if(weight < state_act) {
|
||||||
weight = state_act;
|
weight = state_act;
|
||||||
*v = value_tmp;
|
*v = value_tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(found == LV_STYLE_RES_INHERIT) {
|
||||||
|
return LV_STYLE_RES_INHERIT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(weight >= 0) {
|
if(weight >= 0) {
|
||||||
*v = value_tmp;
|
*v = value_tmp;
|
||||||
return true;
|
return LV_STYLE_RES_FOUND;
|
||||||
}
|
}
|
||||||
else return false;
|
else return LV_STYLE_RES_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -140,7 +140,10 @@ lv_style_value_t lv_obj_get_style_prop(const struct _lv_obj_t * obj, lv_part_t p
|
|||||||
void lv_obj_set_local_style_prop(struct _lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t value,
|
void lv_obj_set_local_style_prop(struct _lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t value,
|
||||||
lv_style_selector_t selector);
|
lv_style_selector_t selector);
|
||||||
|
|
||||||
lv_res_t lv_obj_get_local_style_prop(struct _lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t * value,
|
void lv_obj_set_local_style_prop_meta(struct _lv_obj_t * obj, lv_style_prop_t prop, uint16_t meta,
|
||||||
|
lv_style_selector_t selector);
|
||||||
|
|
||||||
|
lv_style_res_t lv_obj_get_local_style_prop(struct _lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t * value,
|
||||||
lv_style_selector_t selector);
|
lv_style_selector_t selector);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -600,8 +600,7 @@ void lv_obj_set_style_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selec
|
|||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_OPA, v, selector);
|
lv_obj_set_local_style_prop(obj, LV_STYLE_OPA, v, selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lv_obj_set_style_color_filter_dsc(struct _lv_obj_t * obj, const lv_color_filter_dsc_t * value,
|
void lv_obj_set_style_color_filter_dsc(struct _lv_obj_t * obj, const lv_color_filter_dsc_t * value, lv_style_selector_t selector)
|
||||||
lv_style_selector_t selector)
|
|
||||||
{
|
{
|
||||||
lv_style_value_t v = {
|
lv_style_value_t v = {
|
||||||
.ptr = value
|
.ptr = value
|
||||||
@ -641,8 +640,7 @@ void lv_obj_set_style_anim_speed(struct _lv_obj_t * obj, uint32_t value, lv_styl
|
|||||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ANIM_SPEED, v, selector);
|
lv_obj_set_local_style_prop(obj, LV_STYLE_ANIM_SPEED, v, selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lv_obj_set_style_transition(struct _lv_obj_t * obj, const lv_style_transition_dsc_t * value,
|
void lv_obj_set_style_transition(struct _lv_obj_t * obj, const lv_style_transition_dsc_t * value, lv_style_selector_t selector)
|
||||||
lv_style_selector_t selector)
|
|
||||||
{
|
{
|
||||||
lv_style_value_t v = {
|
lv_style_value_t v = {
|
||||||
.ptr = value
|
.ptr = value
|
||||||
|
@ -162,8 +162,7 @@ static inline lv_color_t lv_obj_get_style_bg_grad_color(const struct _lv_obj_t *
|
|||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_bg_grad_color_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
static inline lv_color_t lv_obj_get_style_bg_grad_color_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
||||||
{
|
{
|
||||||
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_COLOR));
|
||||||
LV_STYLE_BG_GRAD_COLOR));
|
|
||||||
return v.color;
|
return v.color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,8 +216,7 @@ static inline lv_color_t lv_obj_get_style_bg_img_recolor(const struct _lv_obj_t
|
|||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_bg_img_recolor_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
static inline lv_color_t lv_obj_get_style_bg_img_recolor_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
||||||
{
|
{
|
||||||
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMG_RECOLOR));
|
||||||
LV_STYLE_BG_IMG_RECOLOR));
|
|
||||||
return v.color;
|
return v.color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,8 +240,7 @@ static inline lv_color_t lv_obj_get_style_border_color(const struct _lv_obj_t *
|
|||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_border_color_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
static inline lv_color_t lv_obj_get_style_border_color_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
||||||
{
|
{
|
||||||
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_COLOR));
|
||||||
LV_STYLE_BORDER_COLOR));
|
|
||||||
return v.color;
|
return v.color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,8 +282,7 @@ static inline lv_color_t lv_obj_get_style_outline_color(const struct _lv_obj_t *
|
|||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_outline_color_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
static inline lv_color_t lv_obj_get_style_outline_color_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
||||||
{
|
{
|
||||||
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_COLOR));
|
||||||
LV_STYLE_OUTLINE_COLOR));
|
|
||||||
return v.color;
|
return v.color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,8 +330,7 @@ static inline lv_color_t lv_obj_get_style_shadow_color(const struct _lv_obj_t *
|
|||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_shadow_color_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
static inline lv_color_t lv_obj_get_style_shadow_color_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
||||||
{
|
{
|
||||||
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_COLOR));
|
||||||
LV_STYLE_SHADOW_COLOR));
|
|
||||||
return v.color;
|
return v.color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,8 +354,7 @@ static inline lv_color_t lv_obj_get_style_img_recolor(const struct _lv_obj_t * o
|
|||||||
|
|
||||||
static inline lv_color_t lv_obj_get_style_img_recolor_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
static inline lv_color_t lv_obj_get_style_img_recolor_filtered(const struct _lv_obj_t * obj, uint32_t part)
|
||||||
{
|
{
|
||||||
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_IMG_RECOLOR));
|
||||||
LV_STYLE_IMG_RECOLOR));
|
|
||||||
return v.color;
|
return v.color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,8 +508,7 @@ static inline lv_opa_t lv_obj_get_style_opa(const struct _lv_obj_t * obj, uint32
|
|||||||
return (lv_opa_t)v.num;
|
return (lv_opa_t)v.num;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const lv_color_filter_dsc_t * lv_obj_get_style_color_filter_dsc(const struct _lv_obj_t * obj,
|
static inline const lv_color_filter_dsc_t * lv_obj_get_style_color_filter_dsc(const struct _lv_obj_t * obj, uint32_t part)
|
||||||
uint32_t part)
|
|
||||||
{
|
{
|
||||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_COLOR_FILTER_DSC);
|
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_COLOR_FILTER_DSC);
|
||||||
return (const lv_color_filter_dsc_t *)v.ptr;
|
return (const lv_color_filter_dsc_t *)v.ptr;
|
||||||
@ -644,14 +637,12 @@ void lv_obj_set_style_text_align(struct _lv_obj_t * obj, lv_text_align_t value,
|
|||||||
void lv_obj_set_style_radius(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
void lv_obj_set_style_radius(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector);
|
||||||
void lv_obj_set_style_clip_corner(struct _lv_obj_t * obj, bool value, lv_style_selector_t selector);
|
void lv_obj_set_style_clip_corner(struct _lv_obj_t * obj, bool value, lv_style_selector_t selector);
|
||||||
void lv_obj_set_style_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
void lv_obj_set_style_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||||
void lv_obj_set_style_color_filter_dsc(struct _lv_obj_t * obj, const lv_color_filter_dsc_t * value,
|
void lv_obj_set_style_color_filter_dsc(struct _lv_obj_t * obj, const lv_color_filter_dsc_t * value, lv_style_selector_t selector);
|
||||||
lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_color_filter_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
void lv_obj_set_style_color_filter_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||||
void lv_obj_set_style_anim(struct _lv_obj_t * obj, const lv_anim_t * value, lv_style_selector_t selector);
|
void lv_obj_set_style_anim(struct _lv_obj_t * obj, const lv_anim_t * value, lv_style_selector_t selector);
|
||||||
void lv_obj_set_style_anim_time(struct _lv_obj_t * obj, uint32_t value, lv_style_selector_t selector);
|
void lv_obj_set_style_anim_time(struct _lv_obj_t * obj, uint32_t value, lv_style_selector_t selector);
|
||||||
void lv_obj_set_style_anim_speed(struct _lv_obj_t * obj, uint32_t value, lv_style_selector_t selector);
|
void lv_obj_set_style_anim_speed(struct _lv_obj_t * obj, uint32_t value, lv_style_selector_t selector);
|
||||||
void lv_obj_set_style_transition(struct _lv_obj_t * obj, const lv_style_transition_dsc_t * value,
|
void lv_obj_set_style_transition(struct _lv_obj_t * obj, const lv_style_transition_dsc_t * value, lv_style_selector_t selector);
|
||||||
lv_style_selector_t selector);
|
|
||||||
void lv_obj_set_style_blend_mode(struct _lv_obj_t * obj, lv_blend_mode_t value, lv_style_selector_t selector);
|
void lv_obj_set_style_blend_mode(struct _lv_obj_t * obj, lv_blend_mode_t value, lv_style_selector_t selector);
|
||||||
void lv_obj_set_style_layout(struct _lv_obj_t * obj, uint16_t value, lv_style_selector_t selector);
|
void lv_obj_set_style_layout(struct _lv_obj_t * obj, uint16_t value, lv_style_selector_t selector);
|
||||||
void lv_obj_set_style_base_dir(struct _lv_obj_t * obj, lv_base_dir_t value, lv_style_selector_t selector);
|
void lv_obj_set_style_base_dir(struct _lv_obj_t * obj, lv_base_dir_t value, lv_style_selector_t selector);
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include "lv_style.h"
|
#include "lv_style.h"
|
||||||
#include "../misc/lv_gc.h"
|
#include "../misc/lv_gc.h"
|
||||||
#include "../misc/lv_mem.h"
|
#include "../misc/lv_mem.h"
|
||||||
|
#include "lv_assert.h"
|
||||||
|
#include "lv_types.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
@ -22,6 +24,13 @@
|
|||||||
* STATIC PROTOTYPES
|
* STATIC PROTOTYPES
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
|
static void lv_style_set_prop_internal(lv_style_t * style, lv_style_prop_t prop_and_meta, lv_style_value_t value,
|
||||||
|
void (*value_adjustment_helper)(lv_style_prop_t, lv_style_value_t, uint16_t *, lv_style_value_t *));
|
||||||
|
static void lv_style_set_prop_helper(lv_style_prop_t prop, lv_style_value_t value, uint16_t * prop_storage,
|
||||||
|
lv_style_value_t * value_storage);
|
||||||
|
static void lv_style_set_prop_meta_helper(lv_style_prop_t prop, lv_style_value_t value, uint16_t * prop_storage,
|
||||||
|
lv_style_value_t * value_storage);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* GLOBAL VARIABLES
|
* GLOBAL VARIABLES
|
||||||
**********************/
|
**********************/
|
||||||
@ -128,6 +137,7 @@ uint32_t _lv_style_custom_prop_flag_lookup_table_size = 0;
|
|||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
static uint16_t last_custom_prop_id = (uint16_t)_LV_STYLE_LAST_BUILT_IN_PROP;
|
static uint16_t last_custom_prop_id = (uint16_t)_LV_STYLE_LAST_BUILT_IN_PROP;
|
||||||
|
static const lv_style_value_t null_style_value = { .num = 0 };
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
@ -155,7 +165,7 @@ void lv_style_reset(lv_style_t * style)
|
|||||||
{
|
{
|
||||||
LV_ASSERT_STYLE(style);
|
LV_ASSERT_STYLE(style);
|
||||||
|
|
||||||
if(style->is_const) {
|
if(style->prop1 == LV_STYLE_PROP_ANY) {
|
||||||
LV_LOG_ERROR("Cannot reset const style");
|
LV_LOG_ERROR("Cannot reset const style");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -171,14 +181,22 @@ lv_style_prop_t lv_style_register_prop(uint8_t flag)
|
|||||||
{
|
{
|
||||||
if(LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table) == NULL) {
|
if(LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table) == NULL) {
|
||||||
_lv_style_custom_prop_flag_lookup_table_size = 0;
|
_lv_style_custom_prop_flag_lookup_table_size = 0;
|
||||||
|
last_custom_prop_id = (uint16_t)_LV_STYLE_LAST_BUILT_IN_PROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(((last_custom_prop_id + 1) & LV_STYLE_PROP_META_MASK) != 0) {
|
||||||
|
LV_LOG_ERROR("No more custom property IDs available");
|
||||||
|
return LV_STYLE_PROP_INV;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate the lookup table if it's not yet available.
|
* Allocate the lookup table if it's not yet available.
|
||||||
*/
|
*/
|
||||||
uint8_t required_size = (last_custom_prop_id + 1 - _LV_STYLE_LAST_BUILT_IN_PROP);
|
size_t required_size = (last_custom_prop_id + 1 - _LV_STYLE_LAST_BUILT_IN_PROP);
|
||||||
if(_lv_style_custom_prop_flag_lookup_table_size < required_size) {
|
if(_lv_style_custom_prop_flag_lookup_table_size < required_size) {
|
||||||
/* Round required_size up to the nearest 32-byte value */
|
/* Round required_size up to the nearest 32-byte value */
|
||||||
required_size = (required_size + 31) & ~31;
|
required_size = (required_size + 31) & ~31;
|
||||||
|
LV_ASSERT_MSG(required_size > 0, "required size has become 0?");
|
||||||
uint8_t * old_p = LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table);
|
uint8_t * old_p = LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table);
|
||||||
uint8_t * new_p = lv_mem_realloc(old_p, required_size * sizeof(uint8_t));
|
uint8_t * new_p = lv_mem_realloc(old_p, required_size * sizeof(uint8_t));
|
||||||
if(new_p == NULL) {
|
if(new_p == NULL) {
|
||||||
@ -204,7 +222,7 @@ bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop)
|
|||||||
{
|
{
|
||||||
LV_ASSERT_STYLE(style);
|
LV_ASSERT_STYLE(style);
|
||||||
|
|
||||||
if(style->is_const) {
|
if(style->prop1 == LV_STYLE_PROP_ANY) {
|
||||||
LV_LOG_ERROR("Cannot remove prop from const style");
|
LV_LOG_ERROR("Cannot remove prop from const style");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -212,7 +230,7 @@ bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop)
|
|||||||
if(style->prop_cnt == 0) return false;
|
if(style->prop_cnt == 0) return false;
|
||||||
|
|
||||||
if(style->prop_cnt == 1) {
|
if(style->prop_cnt == 1) {
|
||||||
if(style->prop1 == prop) {
|
if(LV_STYLE_PROP_ID_MASK(style->prop1) == prop) {
|
||||||
style->prop1 = LV_STYLE_PROP_INV;
|
style->prop1 = LV_STYLE_PROP_INV;
|
||||||
style->prop_cnt = 0;
|
style->prop_cnt = 0;
|
||||||
return true;
|
return true;
|
||||||
@ -224,7 +242,7 @@ bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop)
|
|||||||
uint16_t * old_props = (uint16_t *)tmp;
|
uint16_t * old_props = (uint16_t *)tmp;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
for(i = 0; i < style->prop_cnt; i++) {
|
for(i = 0; i < style->prop_cnt; i++) {
|
||||||
if(old_props[i] == prop) {
|
if(LV_STYLE_PROP_ID_MASK(old_props[i]) == prop) {
|
||||||
lv_style_value_t * old_values = (lv_style_value_t *)style->v_p.values_and_props;
|
lv_style_value_t * old_values = (lv_style_value_t *)style->v_p.values_and_props;
|
||||||
|
|
||||||
if(style->prop_cnt == 2) {
|
if(style->prop_cnt == 2) {
|
||||||
@ -263,78 +281,15 @@ bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop)
|
|||||||
|
|
||||||
void lv_style_set_prop(lv_style_t * style, lv_style_prop_t prop, lv_style_value_t value)
|
void lv_style_set_prop(lv_style_t * style, lv_style_prop_t prop, lv_style_value_t value)
|
||||||
{
|
{
|
||||||
LV_ASSERT_STYLE(style);
|
lv_style_set_prop_internal(style, prop, value, lv_style_set_prop_helper);
|
||||||
|
|
||||||
if(style->is_const) {
|
|
||||||
LV_LOG_ERROR("Cannot set property of constant style");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(style->prop_cnt > 1) {
|
|
||||||
uint8_t * tmp = style->v_p.values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
|
|
||||||
uint16_t * props = (uint16_t *)tmp;
|
|
||||||
int32_t i;
|
|
||||||
for(i = style->prop_cnt - 1; i >= 0; i--) {
|
|
||||||
if(props[i] == prop) {
|
|
||||||
lv_style_value_t * values = (lv_style_value_t *)style->v_p.values_and_props;
|
|
||||||
values[i] = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size = (style->prop_cnt + 1) * (sizeof(lv_style_value_t) + sizeof(uint16_t));
|
|
||||||
uint8_t * values_and_props = lv_mem_realloc(style->v_p.values_and_props, size);
|
|
||||||
if(values_and_props == NULL) return;
|
|
||||||
style->v_p.values_and_props = values_and_props;
|
|
||||||
|
|
||||||
tmp = values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
|
|
||||||
props = (uint16_t *)tmp;
|
|
||||||
/*Shift all props to make place for the value before them*/
|
|
||||||
for(i = style->prop_cnt - 1; i >= 0; i--) {
|
|
||||||
props[i + sizeof(lv_style_value_t) / sizeof(uint16_t)] = props[i];
|
|
||||||
}
|
|
||||||
style->prop_cnt++;
|
|
||||||
|
|
||||||
/*Go to the new position wit the props*/
|
|
||||||
tmp = values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
|
|
||||||
props = (uint16_t *)tmp;
|
|
||||||
lv_style_value_t * values = (lv_style_value_t *)values_and_props;
|
|
||||||
|
|
||||||
/*Set the new property and value*/
|
|
||||||
props[style->prop_cnt - 1] = prop;
|
|
||||||
values[style->prop_cnt - 1] = value;
|
|
||||||
}
|
|
||||||
else if(style->prop_cnt == 1) {
|
|
||||||
if(style->prop1 == prop) {
|
|
||||||
style->v_p.value1 = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
size_t size = (style->prop_cnt + 1) * (sizeof(lv_style_value_t) + sizeof(uint16_t));
|
|
||||||
uint8_t * values_and_props = lv_mem_alloc(size);
|
|
||||||
if(values_and_props == NULL) return;
|
|
||||||
lv_style_value_t value_tmp = style->v_p.value1;
|
|
||||||
style->v_p.values_and_props = values_and_props;
|
|
||||||
style->prop_cnt++;
|
|
||||||
|
|
||||||
uint8_t * tmp = values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
|
|
||||||
uint16_t * props = (uint16_t *)tmp;
|
|
||||||
lv_style_value_t * values = (lv_style_value_t *)values_and_props;
|
|
||||||
props[0] = style->prop1;
|
|
||||||
props[1] = prop;
|
|
||||||
values[0] = value_tmp;
|
|
||||||
values[1] = value;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
style->prop_cnt = 1;
|
|
||||||
style->prop1 = prop;
|
|
||||||
style->v_p.value1 = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t group = _lv_style_get_prop_group(prop);
|
|
||||||
style->has_group |= 1 << group;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_res_t lv_style_get_prop(const lv_style_t * style, lv_style_prop_t prop, lv_style_value_t * value)
|
void lv_style_set_prop_meta(lv_style_t * style, lv_style_prop_t prop, uint16_t meta)
|
||||||
|
{
|
||||||
|
lv_style_set_prop_internal(style, prop | meta, null_style_value, lv_style_set_prop_meta_helper);
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_style_res_t lv_style_get_prop(const lv_style_t * style, lv_style_prop_t prop, lv_style_value_t * value)
|
||||||
{
|
{
|
||||||
return lv_style_get_prop_inlined(style, prop, value);
|
return lv_style_get_prop_inlined(style, prop, value);
|
||||||
}
|
}
|
||||||
@ -439,3 +394,92 @@ uint8_t _lv_style_prop_lookup_flags(lv_style_prop_t prop)
|
|||||||
/**********************
|
/**********************
|
||||||
* STATIC FUNCTIONS
|
* STATIC FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
|
static void lv_style_set_prop_helper(lv_style_prop_t prop, lv_style_value_t value, uint16_t * prop_storage,
|
||||||
|
lv_style_value_t * value_storage)
|
||||||
|
{
|
||||||
|
*prop_storage = prop;
|
||||||
|
*value_storage = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lv_style_set_prop_meta_helper(lv_style_prop_t prop, lv_style_value_t value, uint16_t * prop_storage,
|
||||||
|
lv_style_value_t * value_storage)
|
||||||
|
{
|
||||||
|
LV_UNUSED(value);
|
||||||
|
LV_UNUSED(value_storage);
|
||||||
|
*prop_storage = prop; /* meta is OR-ed into the prop ID already */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lv_style_set_prop_internal(lv_style_t * style, lv_style_prop_t prop_and_meta, lv_style_value_t value,
|
||||||
|
void (*value_adjustment_helper)(lv_style_prop_t, lv_style_value_t, uint16_t *, lv_style_value_t *))
|
||||||
|
{
|
||||||
|
LV_ASSERT_STYLE(style);
|
||||||
|
|
||||||
|
if(style->prop1 == LV_STYLE_PROP_ANY) {
|
||||||
|
LV_LOG_ERROR("Cannot set property of constant style");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_style_prop_t prop_id = LV_STYLE_PROP_ID_MASK(prop_and_meta);
|
||||||
|
|
||||||
|
if(style->prop_cnt > 1) {
|
||||||
|
uint8_t * tmp = style->v_p.values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
|
||||||
|
uint16_t * props = (uint16_t *)tmp;
|
||||||
|
int32_t i;
|
||||||
|
for(i = style->prop_cnt - 1; i >= 0; i--) {
|
||||||
|
if(LV_STYLE_PROP_ID_MASK(props[i]) == prop_id) {
|
||||||
|
lv_style_value_t * values = (lv_style_value_t *)style->v_p.values_and_props;
|
||||||
|
value_adjustment_helper(prop_and_meta, value, &props[i], &values[i]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size = (style->prop_cnt + 1) * (sizeof(lv_style_value_t) + sizeof(uint16_t));
|
||||||
|
uint8_t * values_and_props = lv_mem_realloc(style->v_p.values_and_props, size);
|
||||||
|
if(values_and_props == NULL) return;
|
||||||
|
style->v_p.values_and_props = values_and_props;
|
||||||
|
|
||||||
|
tmp = values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
|
||||||
|
props = (uint16_t *)tmp;
|
||||||
|
/*Shift all props to make place for the value before them*/
|
||||||
|
for(i = style->prop_cnt - 1; i >= 0; i--) {
|
||||||
|
props[i + sizeof(lv_style_value_t) / sizeof(uint16_t)] = props[i];
|
||||||
|
}
|
||||||
|
style->prop_cnt++;
|
||||||
|
|
||||||
|
/*Go to the new position wit the props*/
|
||||||
|
tmp = values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
|
||||||
|
props = (uint16_t *)tmp;
|
||||||
|
lv_style_value_t * values = (lv_style_value_t *)values_and_props;
|
||||||
|
|
||||||
|
/*Set the new property and value*/
|
||||||
|
value_adjustment_helper(prop_and_meta, value, &props[style->prop_cnt - 1], &values[style->prop_cnt - 1]);
|
||||||
|
}
|
||||||
|
else if(style->prop_cnt == 1) {
|
||||||
|
if(LV_STYLE_PROP_ID_MASK(style->prop1) == prop_id) {
|
||||||
|
value_adjustment_helper(prop_and_meta, value, &style->prop1, &style->v_p.value1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t size = (style->prop_cnt + 1) * (sizeof(lv_style_value_t) + sizeof(uint16_t));
|
||||||
|
uint8_t * values_and_props = lv_mem_alloc(size);
|
||||||
|
if(values_and_props == NULL) return;
|
||||||
|
lv_style_value_t value_tmp = style->v_p.value1;
|
||||||
|
style->v_p.values_and_props = values_and_props;
|
||||||
|
style->prop_cnt++;
|
||||||
|
|
||||||
|
uint8_t * tmp = values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
|
||||||
|
uint16_t * props = (uint16_t *)tmp;
|
||||||
|
lv_style_value_t * values = (lv_style_value_t *)values_and_props;
|
||||||
|
props[0] = style->prop1;
|
||||||
|
values[0] = value_tmp;
|
||||||
|
value_adjustment_helper(prop_and_meta, value, &props[1], &values[1]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
style->prop_cnt = 1;
|
||||||
|
value_adjustment_helper(prop_and_meta, value, &style->prop1, &style->v_p.value1);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t group = _lv_style_get_prop_group(prop_id);
|
||||||
|
style->has_group |= 1 << group;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -50,9 +50,9 @@ extern "C" {
|
|||||||
LV_EXPORT_CONST_INT(LV_IMG_ZOOM_NONE);
|
LV_EXPORT_CONST_INT(LV_IMG_ZOOM_NONE);
|
||||||
|
|
||||||
#if LV_USE_ASSERT_STYLE
|
#if LV_USE_ASSERT_STYLE
|
||||||
#define LV_STYLE_CONST_INIT(var_name, prop_array) const lv_style_t var_name = { .sentinel = LV_STYLE_SENTINEL_VALUE, .v_p = { .const_props = prop_array }, .has_group = 0xFF, .is_const = 1 }
|
#define LV_STYLE_CONST_INIT(var_name, prop_array) const lv_style_t var_name = { .sentinel = LV_STYLE_SENTINEL_VALUE, .v_p = { .const_props = prop_array }, .has_group = 0xFF, .prop1 = LV_STYLE_PROP_ANY }
|
||||||
#else
|
#else
|
||||||
#define LV_STYLE_CONST_INIT(var_name, prop_array) const lv_style_t var_name = { .v_p = { .const_props = prop_array }, .has_group = 0xFF, .is_const = 1 }
|
#define LV_STYLE_CONST_INIT(var_name, prop_array) const lv_style_t var_name = { .v_p = { .const_props = prop_array }, .has_group = 0xFF, .prop1 = LV_STYLE_PROP_ANY }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** On simple system, don't waste resources on gradients */
|
/** On simple system, don't waste resources on gradients */
|
||||||
@ -60,6 +60,11 @@ LV_EXPORT_CONST_INT(LV_IMG_ZOOM_NONE);
|
|||||||
#define LV_GRADIENT_MAX_STOPS 2
|
#define LV_GRADIENT_MAX_STOPS 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define LV_STYLE_PROP_META_INHERIT 0x8000
|
||||||
|
#define LV_STYLE_PROP_META_INITIAL 0x4000
|
||||||
|
#define LV_STYLE_PROP_META_MASK (LV_STYLE_PROP_META_INHERIT | LV_STYLE_PROP_META_INITIAL)
|
||||||
|
|
||||||
|
#define LV_STYLE_PROP_ID_MASK(prop) ((lv_style_prop_t)((prop) & ~LV_STYLE_PROP_META_MASK))
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
@ -264,9 +269,18 @@ typedef enum {
|
|||||||
_LV_STYLE_LAST_BUILT_IN_PROP = 111,
|
_LV_STYLE_LAST_BUILT_IN_PROP = 111,
|
||||||
_LV_STYLE_NUM_BUILT_IN_PROPS = _LV_STYLE_LAST_BUILT_IN_PROP + 1,
|
_LV_STYLE_NUM_BUILT_IN_PROPS = _LV_STYLE_LAST_BUILT_IN_PROP + 1,
|
||||||
|
|
||||||
LV_STYLE_PROP_ANY = 0xFFFF
|
LV_STYLE_PROP_ANY = 0xFFFF,
|
||||||
|
_LV_STYLE_PROP_CONST = 0xFFFF /* magic value for const styles */
|
||||||
} lv_style_prop_t;
|
} lv_style_prop_t;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
LV_STYLE_RES_NOT_FOUND,
|
||||||
|
LV_STYLE_RES_FOUND,
|
||||||
|
LV_STYLE_RES_INHERIT
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef uint8_t lv_style_res_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Descriptor for style transitions
|
* Descriptor for style transitions
|
||||||
*/
|
*/
|
||||||
@ -305,8 +319,7 @@ typedef struct {
|
|||||||
const lv_style_const_prop_t * const_props;
|
const lv_style_const_prop_t * const_props;
|
||||||
} v_p;
|
} v_p;
|
||||||
|
|
||||||
uint16_t prop1 : 15;
|
uint16_t prop1;
|
||||||
uint16_t is_const : 1;
|
|
||||||
uint8_t has_group;
|
uint8_t has_group;
|
||||||
uint8_t prop_cnt;
|
uint8_t prop_cnt;
|
||||||
} lv_style_t;
|
} lv_style_t;
|
||||||
@ -370,16 +383,13 @@ bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop);
|
|||||||
void lv_style_set_prop(lv_style_t * style, lv_style_prop_t prop, lv_style_value_t value);
|
void lv_style_set_prop(lv_style_t * style, lv_style_prop_t prop, lv_style_value_t value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of a property
|
* Set a special meta state for a property in a style.
|
||||||
* @param style pointer to a style
|
* This function shouldn't be used directly by the user.
|
||||||
* @param prop the ID of a property
|
* @param style pointer to style
|
||||||
* @param value pointer to a `lv_style_value_t` variable to store the value
|
* @param prop the ID of a property (e.g. `LV_STYLE_BG_COLOR`)
|
||||||
* @return LV_RES_INV: the property wasn't found in the style (`value` is unchanged)
|
* @param meta the meta value to attach to the property in the style
|
||||||
* LV_RES_OK: the property was fond, and `value` is set accordingly
|
|
||||||
* @note For performance reasons there are no sanity check on `style`
|
|
||||||
*/
|
*/
|
||||||
lv_res_t lv_style_get_prop(const lv_style_t * style, lv_style_prop_t prop, lv_style_value_t * value);
|
void lv_style_set_prop_meta(lv_style_t * style, lv_style_prop_t prop, uint16_t meta);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of a property
|
* Get the value of a property
|
||||||
@ -389,42 +399,8 @@ lv_res_t lv_style_get_prop(const lv_style_t * style, lv_style_prop_t prop, lv_st
|
|||||||
* @return LV_RES_INV: the property wasn't found in the style (`value` is unchanged)
|
* @return LV_RES_INV: the property wasn't found in the style (`value` is unchanged)
|
||||||
* LV_RES_OK: the property was fond, and `value` is set accordingly
|
* LV_RES_OK: the property was fond, and `value` is set accordingly
|
||||||
* @note For performance reasons there are no sanity check on `style`
|
* @note For performance reasons there are no sanity check on `style`
|
||||||
* @note This function is the same as ::lv_style_get_prop but inlined. Use it only on performance critical places
|
|
||||||
*/
|
*/
|
||||||
static inline lv_res_t lv_style_get_prop_inlined(const lv_style_t * style, lv_style_prop_t prop,
|
lv_style_res_t lv_style_get_prop(const lv_style_t * style, lv_style_prop_t prop, lv_style_value_t * value);
|
||||||
lv_style_value_t * value)
|
|
||||||
{
|
|
||||||
if(style->is_const) {
|
|
||||||
const lv_style_const_prop_t * const_prop;
|
|
||||||
for(const_prop = style->v_p.const_props; const_prop->prop != LV_STYLE_PROP_INV; const_prop++) {
|
|
||||||
if(const_prop->prop == prop) {
|
|
||||||
*value = const_prop->value;
|
|
||||||
return LV_RES_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return LV_RES_INV;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(style->prop_cnt == 0) return LV_RES_INV;
|
|
||||||
|
|
||||||
if(style->prop_cnt > 1) {
|
|
||||||
uint8_t * tmp = style->v_p.values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
|
|
||||||
uint16_t * props = (uint16_t *)tmp;
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < style->prop_cnt; i++) {
|
|
||||||
if(props[i] == prop) {
|
|
||||||
lv_style_value_t * values = (lv_style_value_t *)style->v_p.values_and_props;
|
|
||||||
*value = values[i];
|
|
||||||
return LV_RES_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(style->prop1 == prop) {
|
|
||||||
*value = style->v_p.value1;
|
|
||||||
return LV_RES_OK;
|
|
||||||
}
|
|
||||||
return LV_RES_INV;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize a transition descriptor.
|
* Initialize a transition descriptor.
|
||||||
@ -449,6 +425,64 @@ void lv_style_transition_dsc_init(lv_style_transition_dsc_t * tr, const lv_style
|
|||||||
*/
|
*/
|
||||||
lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop);
|
lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of a property
|
||||||
|
* @param style pointer to a style
|
||||||
|
* @param prop the ID of a property
|
||||||
|
* @param value pointer to a `lv_style_value_t` variable to store the value
|
||||||
|
* @return LV_RES_INV: the property wasn't found in the style (`value` is unchanged)
|
||||||
|
* LV_RES_OK: the property was fond, and `value` is set accordingly
|
||||||
|
* @note For performance reasons there are no sanity check on `style`
|
||||||
|
* @note This function is the same as ::lv_style_get_prop but inlined. Use it only on performance critical places
|
||||||
|
*/
|
||||||
|
static inline lv_style_res_t lv_style_get_prop_inlined(const lv_style_t * style, lv_style_prop_t prop,
|
||||||
|
lv_style_value_t * value)
|
||||||
|
{
|
||||||
|
if(style->prop1 == LV_STYLE_PROP_ANY) {
|
||||||
|
const lv_style_const_prop_t * const_prop;
|
||||||
|
for(const_prop = style->v_p.const_props; const_prop->prop != LV_STYLE_PROP_INV; const_prop++) {
|
||||||
|
lv_style_prop_t prop_id = LV_STYLE_PROP_ID_MASK(const_prop->prop);
|
||||||
|
if(prop_id == prop) {
|
||||||
|
if(const_prop->prop & LV_STYLE_PROP_META_INHERIT)
|
||||||
|
return LV_STYLE_RES_INHERIT;
|
||||||
|
*value = (const_prop->prop & LV_STYLE_PROP_META_INITIAL) ? lv_style_prop_get_default(prop_id) : const_prop->value;
|
||||||
|
return LV_STYLE_RES_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return LV_STYLE_RES_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(style->prop_cnt == 0) return LV_STYLE_RES_NOT_FOUND;
|
||||||
|
|
||||||
|
if(style->prop_cnt > 1) {
|
||||||
|
uint8_t * tmp = style->v_p.values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
|
||||||
|
uint16_t * props = (uint16_t *)tmp;
|
||||||
|
uint32_t i;
|
||||||
|
for(i = 0; i < style->prop_cnt; i++) {
|
||||||
|
lv_style_prop_t prop_id = LV_STYLE_PROP_ID_MASK(props[i]);
|
||||||
|
if(prop_id == prop) {
|
||||||
|
if(props[i] & LV_STYLE_PROP_META_INHERIT)
|
||||||
|
return LV_STYLE_RES_INHERIT;
|
||||||
|
if(props[i] & LV_STYLE_PROP_META_INITIAL)
|
||||||
|
*value = lv_style_prop_get_default(prop_id);
|
||||||
|
else {
|
||||||
|
lv_style_value_t * values = (lv_style_value_t *)style->v_p.values_and_props;
|
||||||
|
*value = values[i];
|
||||||
|
}
|
||||||
|
return LV_STYLE_RES_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(LV_STYLE_PROP_ID_MASK(style->prop1) == prop) {
|
||||||
|
if(style->prop1 & LV_STYLE_PROP_META_INHERIT)
|
||||||
|
return LV_STYLE_RES_INHERIT;
|
||||||
|
*value = (style->prop1 & LV_STYLE_PROP_META_INITIAL) ? lv_style_prop_get_default(LV_STYLE_PROP_ID_MASK(
|
||||||
|
style->prop1)) : style->v_p.value1;
|
||||||
|
return LV_STYLE_RES_FOUND;
|
||||||
|
}
|
||||||
|
return LV_STYLE_RES_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a style is empty (has no properties)
|
* Checks if a style is empty (has no properties)
|
||||||
* @param style pointer to a style
|
* @param style pointer to a style
|
||||||
|
@ -70,4 +70,40 @@ void test_custom_prop_ids(void)
|
|||||||
TEST_ASSERT_EQUAL(_lv_style_custom_prop_flag_lookup_table_size, 96);
|
TEST_ASSERT_EQUAL(_lv_style_custom_prop_flag_lookup_table_size, 96);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_inherit_meta(void)
|
||||||
|
{
|
||||||
|
lv_obj_t * parent = lv_obj_create(lv_scr_act());
|
||||||
|
lv_obj_t * child = lv_obj_create(parent);
|
||||||
|
lv_obj_t * grandchild = lv_label_create(child);
|
||||||
|
lv_obj_set_style_text_color(parent, lv_color_hex(0xff0000), LV_PART_MAIN);
|
||||||
|
lv_obj_set_local_style_prop_meta(child, LV_STYLE_TEXT_COLOR, LV_STYLE_PROP_META_INHERIT, LV_PART_MAIN);
|
||||||
|
TEST_ASSERT_EQUAL_HEX(lv_color_hex(0xff0000).full, lv_obj_get_style_text_color(grandchild, LV_PART_MAIN).full);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_id_meta_overrun(void)
|
||||||
|
{
|
||||||
|
/* Test that property ID registration is blocked once the ID reaches into the meta bits */
|
||||||
|
lv_style_prop_t prop_id;
|
||||||
|
do {
|
||||||
|
prop_id = lv_style_register_prop(0);
|
||||||
|
if(prop_id != LV_STYLE_PROP_INV) {
|
||||||
|
TEST_ASSERT_EQUAL(0, prop_id & LV_STYLE_PROP_META_MASK);
|
||||||
|
}
|
||||||
|
} while(prop_id != LV_STYLE_PROP_INV);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_inherit_meta_with_lower_precedence_style(void)
|
||||||
|
{
|
||||||
|
lv_obj_t * parent = lv_obj_create(lv_scr_act());
|
||||||
|
lv_obj_t * child = lv_obj_create(parent);
|
||||||
|
lv_obj_t * grandchild = lv_label_create(child);
|
||||||
|
lv_obj_set_style_text_color(parent, lv_color_hex(0xff0000), LV_PART_MAIN);
|
||||||
|
lv_style_t style;
|
||||||
|
lv_style_init(&style);
|
||||||
|
lv_style_set_text_color(&style, lv_color_hex(0xffffff));
|
||||||
|
lv_obj_set_local_style_prop_meta(child, LV_STYLE_TEXT_COLOR, LV_STYLE_PROP_META_INHERIT, LV_PART_MAIN);
|
||||||
|
lv_obj_add_style(child, &style, LV_PART_MAIN);
|
||||||
|
TEST_ASSERT_EQUAL_HEX(lv_color_hex(0xff0000).full, lv_obj_get_style_text_color(grandchild, LV_PART_MAIN).full);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user