mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03: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_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 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);
|
||||
@ -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_in_anim_ready(lv_anim_t * a);
|
||||
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
|
||||
@ -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_style_selector_t selector = part | obj->state;
|
||||
lv_style_value_t value_act = { .ptr = NULL };
|
||||
lv_style_res_t found;
|
||||
|
||||
/*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, part, prop, &value_act);
|
||||
found = get_selector_style_prop(obj, selector, 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);
|
||||
}
|
||||
|
||||
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,
|
||||
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];
|
||||
}
|
||||
|
||||
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 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 bool skip_trans = obj->skip_trans;
|
||||
int32_t weight = -1;
|
||||
@ -1140,3 +1102,75 @@ static bool style_has_flag(const lv_style_t * style, uint32_t flag)
|
||||
}
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @param obj pointer to an object
|
||||
|
@ -117,4 +117,27 @@ void test_style_replacement(void)
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user