mirror of
https://github.com/lvgl/lvgl.git
synced 2025-02-04 07:13:00 +08:00
feat(style): add API to check specific style property is set (#5055)
Signed-off-by: yushuailong1 <yushuailong1@xiaomi.com> Co-authored-by: yushuailong1 <yushuailong1@xiaomi.com>
This commit is contained in:
parent
6d57d71f41
commit
95e40c4652
@ -50,7 +50,8 @@ 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 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 lv_style_res_t get_prop_core(const lv_obj_t * obj, lv_style_selector_t selector, 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_delete(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, trans_t * tr_limit);
|
static bool trans_delete(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, trans_t * tr_limit);
|
||||||
@ -62,6 +63,8 @@ static void full_cache_refresh(lv_obj_t * obj, lv_part_t part);
|
|||||||
static void fade_anim_cb(void * obj, int32_t v);
|
static void fade_anim_cb(void * obj, int32_t v);
|
||||||
static void fade_in_anim_ready(lv_anim_t * a);
|
static void fade_in_anim_ready(lv_anim_t * a);
|
||||||
static bool style_has_flag(const lv_style_t * style, uint32_t flag);
|
static bool style_has_flag(const lv_style_t * style, uint32_t flag);
|
||||||
|
static lv_style_res_t get_selector_style_prop(const lv_obj_t * obj, lv_style_selector_t selector, lv_style_prop_t prop,
|
||||||
|
lv_style_value_t * value_act);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
@ -390,72 +393,29 @@ lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, lv_part_t part, lv_
|
|||||||
{
|
{
|
||||||
LV_ASSERT_NULL(obj)
|
LV_ASSERT_NULL(obj)
|
||||||
|
|
||||||
|
lv_style_selector_t selector = part | obj->state;
|
||||||
lv_style_value_t value_act = { .ptr = NULL };
|
lv_style_value_t value_act = { .ptr = NULL };
|
||||||
lv_style_res_t found;
|
lv_style_res_t found;
|
||||||
|
|
||||||
/*The happy path*/
|
found = get_selector_style_prop(obj, selector, prop, &value_act);
|
||||||
#if LV_OBJ_STYLE_CACHE
|
if(found == LV_STYLE_RES_FOUND) return value_act;
|
||||||
const uint32_t prop_shifted = STYLE_PROP_SHIFTED(prop);
|
|
||||||
if((part == LV_PART_MAIN ? obj->style_main_prop_is_set : obj->style_other_prop_is_set) & prop_shifted)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
found = get_prop_core(obj, part, prop, &value_act);
|
|
||||||
if(found == LV_STYLE_RES_FOUND) return value_act;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern const uint8_t _lv_style_builtin_prop_flag_lookup_table[];
|
|
||||||
bool inheritable = false;
|
|
||||||
if(prop < _LV_STYLE_NUM_BUILT_IN_PROPS) {
|
|
||||||
inheritable = _lv_style_builtin_prop_flag_lookup_table[prop] & LV_STYLE_PROP_FLAG_INHERITABLE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(_style_custom_prop_flag_lookup_table != NULL) {
|
|
||||||
inheritable = _style_custom_prop_flag_lookup_table[prop - _LV_STYLE_NUM_BUILT_IN_PROPS] &
|
|
||||||
LV_STYLE_PROP_FLAG_INHERITABLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(inheritable) {
|
|
||||||
/*If not found, check the `MAIN` style first, if already on the MAIN part go to the parent*/
|
|
||||||
if(part != LV_PART_MAIN) part = LV_PART_MAIN;
|
|
||||||
else obj = obj->parent;
|
|
||||||
|
|
||||||
while(obj) {
|
|
||||||
#if LV_OBJ_STYLE_CACHE
|
|
||||||
if(obj->style_main_prop_is_set & prop_shifted)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
found = get_prop_core(obj, part, prop, &value_act);
|
|
||||||
if(found == LV_STYLE_RES_FOUND) return value_act;
|
|
||||||
}
|
|
||||||
/*Check the parent too.*/
|
|
||||||
obj = obj->parent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/*Get the width and height from the class.
|
|
||||||
* WIDTH and HEIGHT are not inherited so add them in the `else` to skip checking them for inherited properties */
|
|
||||||
if(part == LV_PART_MAIN && (prop == LV_STYLE_WIDTH || prop == LV_STYLE_HEIGHT)) {
|
|
||||||
const lv_obj_class_t * cls = obj->class_p;
|
|
||||||
while(cls) {
|
|
||||||
if(prop == LV_STYLE_WIDTH) {
|
|
||||||
if(cls->width_def != 0) return (lv_style_value_t) {
|
|
||||||
.num = cls->width_def
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(cls->height_def != 0) return (lv_style_value_t) {
|
|
||||||
.num = cls->height_def
|
|
||||||
};
|
|
||||||
}
|
|
||||||
cls = cls->base_class;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return lv_style_prop_get_default_inlined(prop);
|
return lv_style_prop_get_default_inlined(prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool lv_obj_has_style_prop(const lv_obj_t * obj, lv_style_selector_t selector, lv_style_prop_t prop)
|
||||||
|
{
|
||||||
|
LV_ASSERT_NULL(obj)
|
||||||
|
|
||||||
|
lv_style_value_t value_act = { .ptr = NULL };
|
||||||
|
lv_style_res_t found;
|
||||||
|
|
||||||
|
found = get_selector_style_prop(obj, selector, prop, &value_act);
|
||||||
|
if(found == LV_STYLE_RES_FOUND) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void lv_obj_set_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t value,
|
void lv_obj_set_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)
|
||||||
{
|
{
|
||||||
@ -786,11 +746,13 @@ static _lv_obj_style_t * get_trans_style(lv_obj_t * obj, lv_style_selector_t se
|
|||||||
return &obj->styles[0];
|
return &obj->styles[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
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 lv_style_res_t get_prop_core(const lv_obj_t * obj, lv_style_selector_t selector, lv_style_prop_t prop,
|
||||||
|
lv_style_value_t * v)
|
||||||
{
|
{
|
||||||
|
|
||||||
const uint32_t group = (uint32_t)1 << _lv_style_get_prop_group(prop);
|
const uint32_t group = (uint32_t)1 << _lv_style_get_prop_group(prop);
|
||||||
const lv_state_t state = obj->state;
|
const lv_part_t part = lv_obj_style_get_selector_part(selector);
|
||||||
|
const lv_state_t state = lv_obj_style_get_selector_state(selector);
|
||||||
const lv_state_t state_inv = ~state;
|
const lv_state_t state_inv = ~state;
|
||||||
const bool skip_trans = obj->skip_trans;
|
const bool skip_trans = obj->skip_trans;
|
||||||
int32_t weight = -1;
|
int32_t weight = -1;
|
||||||
@ -1140,3 +1102,75 @@ static bool style_has_flag(const lv_style_t * style, uint32_t flag)
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static lv_style_res_t get_selector_style_prop(const lv_obj_t * obj, lv_style_selector_t selector, lv_style_prop_t prop,
|
||||||
|
lv_style_value_t * value_act)
|
||||||
|
{
|
||||||
|
lv_style_res_t found;
|
||||||
|
lv_part_t part = lv_obj_style_get_selector_part(selector);
|
||||||
|
|
||||||
|
/*The happy path*/
|
||||||
|
#if LV_OBJ_STYLE_CACHE
|
||||||
|
const uint32_t prop_shifted = STYLE_PROP_SHIFTED(prop);
|
||||||
|
if((part == LV_PART_MAIN ? obj->style_main_prop_is_set : obj->style_other_prop_is_set) & prop_shifted)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
found = get_prop_core(obj, selector, prop, value_act);
|
||||||
|
if(found == LV_STYLE_RES_FOUND) return LV_STYLE_RES_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const uint8_t _lv_style_builtin_prop_flag_lookup_table[];
|
||||||
|
bool inheritable = false;
|
||||||
|
if(prop < _LV_STYLE_NUM_BUILT_IN_PROPS) {
|
||||||
|
inheritable = _lv_style_builtin_prop_flag_lookup_table[prop] & LV_STYLE_PROP_FLAG_INHERITABLE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(_style_custom_prop_flag_lookup_table != NULL) {
|
||||||
|
inheritable = _style_custom_prop_flag_lookup_table[prop - _LV_STYLE_NUM_BUILT_IN_PROPS] &
|
||||||
|
LV_STYLE_PROP_FLAG_INHERITABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(inheritable) {
|
||||||
|
/*If not found, check the `MAIN` style first, if already on the MAIN part go to the parent*/
|
||||||
|
if(part != LV_PART_MAIN) part = LV_PART_MAIN;
|
||||||
|
else obj = obj->parent;
|
||||||
|
|
||||||
|
while(obj) {
|
||||||
|
#if LV_OBJ_STYLE_CACHE
|
||||||
|
if(obj->style_main_prop_is_set & prop_shifted)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
selector = part | obj->state;
|
||||||
|
found = get_prop_core(obj, selector, prop, value_act);
|
||||||
|
if(found == LV_STYLE_RES_FOUND) return LV_STYLE_RES_FOUND;
|
||||||
|
}
|
||||||
|
/*Check the parent too.*/
|
||||||
|
obj = obj->parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*Get the width and height from the class.
|
||||||
|
* WIDTH and HEIGHT are not inherited so add them in the `else` to skip checking them for inherited properties */
|
||||||
|
if(part == LV_PART_MAIN && (prop == LV_STYLE_WIDTH || prop == LV_STYLE_HEIGHT)) {
|
||||||
|
const lv_obj_class_t * cls = obj->class_p;
|
||||||
|
while(cls) {
|
||||||
|
if(prop == LV_STYLE_WIDTH) {
|
||||||
|
if(cls->width_def != 0) {
|
||||||
|
value_act->num = cls->width_def;
|
||||||
|
return LV_STYLE_RES_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(cls->height_def != 0) {
|
||||||
|
value_act->num = cls->height_def;
|
||||||
|
return LV_STYLE_RES_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cls = cls->base_class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return LV_STYLE_RES_NOT_FOUND;
|
||||||
|
}
|
@ -155,6 +155,15 @@ void lv_obj_enable_style_refresh(bool en);
|
|||||||
*/
|
*/
|
||||||
lv_style_value_t lv_obj_get_style_prop(const struct _lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop);
|
lv_style_value_t lv_obj_get_style_prop(const struct _lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an object has a specified style property for a given style selector.
|
||||||
|
* @param obj pointer to an object
|
||||||
|
* @param selector the style selector to be checked, defining the scope of the style to be examined.
|
||||||
|
* @param prop the property to be checked.
|
||||||
|
* @return true if the object has the specified selector and property, false otherwise.
|
||||||
|
*/
|
||||||
|
bool lv_obj_has_style_prop(const struct _lv_obj_t * obj, lv_style_selector_t selector, lv_style_prop_t prop);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set local style property on an object's part and state.
|
* Set local style property on an object's part and state.
|
||||||
* @param obj pointer to an object
|
* @param obj pointer to an object
|
||||||
|
@ -117,4 +117,27 @@ void test_style_replacement(void)
|
|||||||
lv_style_reset(&style_blue);
|
lv_style_reset(&style_blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_style_has_prop(void)
|
||||||
|
{
|
||||||
|
lv_style_t style;
|
||||||
|
lv_style_init(&style);
|
||||||
|
lv_style_set_outline_color(&style, lv_color_white());
|
||||||
|
|
||||||
|
/*Create object with style*/
|
||||||
|
lv_obj_t * obj = lv_obj_create(lv_screen_active());
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL(false, lv_obj_has_style_prop(obj, LV_PART_MAIN, LV_STYLE_OUTLINE_COLOR));
|
||||||
|
TEST_ASSERT_EQUAL(false, lv_obj_has_style_prop(obj, LV_PART_MAIN, LV_STYLE_OUTLINE_WIDTH));
|
||||||
|
TEST_ASSERT_EQUAL(false, lv_obj_has_style_prop(obj, LV_PART_INDICATOR, LV_STYLE_OUTLINE_COLOR));
|
||||||
|
|
||||||
|
lv_obj_add_style(obj, &style, LV_PART_MAIN);
|
||||||
|
lv_obj_set_style_outline_width(obj, 2, LV_PART_MAIN);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL(true, lv_obj_has_style_prop(obj, LV_PART_MAIN, LV_STYLE_OUTLINE_COLOR));
|
||||||
|
TEST_ASSERT_EQUAL(true, lv_obj_has_style_prop(obj, LV_PART_MAIN, LV_STYLE_OUTLINE_WIDTH));
|
||||||
|
TEST_ASSERT_EQUAL(false, lv_obj_has_style_prop(obj, LV_PART_INDICATOR, LV_STYLE_OUTLINE_COLOR));
|
||||||
|
|
||||||
|
lv_style_reset(&style);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user