1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-21 06:53:01 +08:00

add obj and style state

This commit is contained in:
Gabor Kiss-Vamosi 2019-12-19 11:05:04 +01:00
parent 02ca70c691
commit 446a318e6e
7 changed files with 486 additions and 389 deletions

View File

@ -1231,7 +1231,7 @@ void lv_obj_set_style_opa(lv_obj_t * obj, lv_style_property_t prop, lv_opa_t opa
void lv_obj_add_style_class(lv_obj_t * obj, uint8_t type, lv_style_t * style)
{
lv_style_class_list_t * class = lv_mem_alloc(sizeof(lv_style_class_list_t));
lv_style_classes_t * class = lv_mem_alloc(sizeof(lv_style_classes_t));
lv_style_dsc_t * style_dsc = lv_obj_get_style(obj, type);
if(style_dsc == NULL) {
@ -1467,6 +1467,23 @@ void lv_obj_clear_protect(lv_obj_t * obj, uint8_t prot)
obj->protect &= prot;
}
void lv_obj_set_state(lv_obj_t * obj, lv_obj_state_t state)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->state |= state;
lv_obj_refresh_style(obj, LV_OBJ_STYLE_ALL);
}
void lv_obj_clear_state(lv_obj_t * obj, lv_obj_state_t state)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
state = (~state) & 0xFF;
obj->state &= state;
lv_obj_refresh_style(obj, LV_OBJ_STYLE_ALL);
}
/**
* Set a an event handler function for an object.
* Used by the user to react on event which happens with the object.
@ -2046,17 +2063,58 @@ lv_style_dsc_t * lv_obj_get_style(const lv_obj_t * obj, uint8_t type)
lv_style_value_t lv_obj_get_style_value(const lv_obj_t * obj, uint8_t type, lv_style_property_t prop)
{
lv_style_value_t value;
lv_res_t found;
found = get_style_prop_core(obj, type, prop, &value);
lv_style_attr_t attr;
attr.full = prop >> 8;
if(found == LV_RES_OK) return value;
else {
/*Default value*/
switch(prop) {
case LV_STYLE_BORDER_PART:
return LV_BORDER_PART_FULL;
int16_t weight_goal = attr.bits.state;
int16_t weight = -1;
lv_style_value_t value;
const lv_obj_t * parent = obj;
while(parent) {
lv_style_dsc_t * dsc = lv_obj_get_style(obj, type);
if(dsc == NULL) continue;
int16_t weight_act;
lv_style_value_t value_act;
weight_act = lv_style_get_value(&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_value(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_BORDER_PART:
return LV_BORDER_PART_FULL;
}
return 0;
@ -2064,79 +2122,109 @@ lv_style_value_t lv_obj_get_style_value(const lv_obj_t * obj, uint8_t type, lv_s
lv_color_t lv_obj_get_style_color(const lv_obj_t * obj, uint8_t type, lv_style_property_t prop)
{
lv_color_t color;
lv_res_t found;
found = get_style_prop_core(obj, type, prop, &color);
lv_style_attr_t attr;
attr.full = prop >> 8;
if(found == LV_RES_OK) return color;
else {
/*Default colors*/
int16_t weight_goal = attr.bits.state;
int16_t weight = -1;
lv_color_t value;
const lv_obj_t * parent = obj;
while(parent) {
lv_style_dsc_t * dsc = lv_obj_get_style(obj, type);
if(dsc == NULL) continue;
int16_t weight_act;
lv_color_t value_act;
weight_act = lv_style_get_color(&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_color(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;
return LV_COLOR_WHITE;
}
lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t type, lv_style_property_t prop)
{
lv_opa_t opa;
lv_res_t found;
found = get_style_prop_core(obj, type, prop, &opa);
lv_style_attr_t attr;
attr.full = prop >> 8;
if(found == LV_RES_OK) return opa;
else {
/*Default opa*/
int16_t weight_goal = attr.bits.state;
int16_t weight = -1;
lv_opa_t value;
const lv_obj_t * parent = obj;
while(parent) {
lv_style_dsc_t * dsc = lv_obj_get_style(obj, type);
if(dsc == NULL) continue;
int16_t weight_act;
lv_opa_t value_act;
weight_act = lv_style_get_opa(&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_opa(classes->style, prop, &value_act);
/*On perfect match return the value immediately*/
if(weight_act == weight_goal) {
return weight_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;
return LV_OPA_COVER;
}
//
///**
// * Get the style pointer of an object (if NULL get style of the parent)
// * @param obj pointer to an object
// * @return pointer to a style
// */
//const lv_style_t * lv_obj_get_style(const lv_obj_t * obj)
//{
// LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
//
// const lv_style_t * style_act = obj->style_p;
// if(style_act == NULL) {
// lv_obj_t * par = obj->par;
//
// while(par) {
// if(par->style_p) {
// if(par->style_p->glass == 0) {
//#if LV_USE_GROUP == 0
// style_act = par->style_p;
//#else
// /*If a parent is focused then use then focused style*/
// lv_group_t * g = lv_obj_get_group(par);
// if(lv_group_get_focused(g) == par) {
// style_act = lv_group_mod_style(g, par->style_p);
// } else {
// style_act = par->style_p;
// }
//#endif
// break;
// }
// }
// par = par->par;
// }
// }
//#if LV_USE_GROUP
// if(obj->group_p) {
// if(lv_group_get_focused(obj->group_p) == obj) {
// style_act = lv_group_mod_style(obj->group_p, style_act);
// }
// }
//#endif
//
// if(style_act == NULL) style_act = &lv_style_plain;
//
// return style_act;
//}
/*-----------------
* Attribute get
*----------------*/
@ -2311,6 +2399,12 @@ bool lv_obj_is_protected(const lv_obj_t * obj, uint8_t prot)
return (obj->protect & prot) == 0 ? false : true;
}
lv_obj_state_t lv_obj_get_state(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->state;
}
/**
* Get the signal function of an object
* @param obj pointer to an object
@ -2505,20 +2599,22 @@ static void lv_obj_del_async_cb(void * obj)
* @note Only the relevant fields will be set.
* E.g. if `border width == 0` the other border properties won't be evaluated.
*/
void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t type, lv_draw_rect_dsc_t * draw_dsc)
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);
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);
draw_dsc->bg_color = lv_obj_get_style_color(obj, type, LV_STYLE_BG_COLOR | style_state);
draw_dsc->border_width = lv_obj_get_style_value(obj, type, LV_STYLE_BORDER_WIDTH);
draw_dsc->border_width = lv_obj_get_style_value(obj, type, LV_STYLE_BORDER_WIDTH | style_state);
if(draw_dsc->border_width) {
draw_dsc->border_opa = lv_obj_get_style_opa(obj, type, LV_STYLE_BORDER_OPA);
draw_dsc->border_opa = lv_obj_get_style_opa(obj, type, LV_STYLE_BORDER_OPA | style_state);
if(draw_dsc->border_opa >= LV_OPA_MIN) {
draw_dsc->border_part = lv_obj_get_style_value(obj, type, LV_STYLE_BORDER_PART);
draw_dsc->border_color = lv_obj_get_style_color(obj, type, LV_STYLE_BORDER_COLOR);
draw_dsc->border_part = lv_obj_get_style_value(obj, type, LV_STYLE_BORDER_PART | style_state);
draw_dsc->border_color = lv_obj_get_style_color(obj, type, LV_STYLE_BORDER_COLOR | style_state);
}
}
}
@ -2571,7 +2667,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_obj_init_draw_rect_dsc(obj, LV_OBJ_STYLE_MAIN, &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));
if(lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_BG_CLIP_CORNER)) {
@ -2625,7 +2721,18 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
if(shadow > obj->ext_draw_pad) obj->ext_draw_pad = shadow;
} else if(sign == LV_SIGNAL_STYLE_CHG) {
lv_obj_refresh_ext_draw_pad(obj);
} else if(sign == LV_SIGNAL_FOCUS) {
if(lv_group_get_editing(lv_obj_get_group(obj))) {
uint8_t state = LV_OBJ_STATE_FOCUS;
state |= LV_OBJ_STATE_EDIT;
} else {
lv_obj_set_state(obj, LV_OBJ_STATE_FOCUS);
lv_obj_clear_state(obj, LV_OBJ_STATE_EDIT);
}
} else if(sign == LV_SIGNAL_DEFOCUS) {
lv_obj_clear_state(obj, LV_OBJ_STATE_FOCUS | LV_OBJ_STATE_EDIT);
}
return res;
}
@ -2649,37 +2756,6 @@ static void refresh_children_position(lv_obj_t * obj, lv_coord_t x_diff, lv_coor
}
}
static inline lv_res_t get_style_prop_core(const lv_obj_t * obj, uint8_t type, lv_style_property_t prop, void * out)
{
lv_style_dsc_t * dsc = lv_obj_get_style(obj, type);
if(dsc == NULL) return LV_RES_INV;
lv_res_t found = LV_RES_INV;
lv_style_attr_t attr;
attr.full= prop >> 8;
const lv_obj_t * parent = obj;
while(parent) {
found = lv_style_get_color(&dsc->local, prop, out);
if(found == LV_RES_OK) return LV_RES_OK;
const lv_style_class_list_t * classes = obj->style_dsc.classes;
while(classes) {
found = lv_style_get_color(classes->style, prop, out);
if(found == LV_RES_OK) return LV_RES_OK;
classes = classes->next;
}
if(attr.bits.inherit == 0) break;
parent = lv_obj_get_parent(parent);
}
return LV_RES_INV;
}
/**
* Refresh the style of all children of an object. (Called recursively)
* @param style_p refresh objects only with this style_dsc.

View File

@ -128,6 +128,7 @@ enum {
LV_SIGNAL_REFR_EXT_DRAW_PAD, /**< Object's extra padding has changed */
LV_SIGNAL_GET_TYPE, /**< LittlevGL needs to retrieve the object's type */
LV_SIGNAL_GET_STYLE, /**<Get the style of an object*/
LV_SIGNAL_GET_STATE, /**<Get the state of the object*/
/*Input device related*/
LV_SIGNAL_PRESSED, /**< The object has been pressed*/
@ -189,6 +190,31 @@ typedef struct
} lv_reailgn_t;
#endif
/*Protect some attributes (max. 8 bit)*/
enum {
LV_PROTECT_NONE = 0x00,
LV_PROTECT_CHILD_CHG = 0x01, /**< Disable the child change signal. Used by the library*/
LV_PROTECT_PARENT = 0x02, /**< Prevent automatic parent change (e.g. in lv_page)*/
LV_PROTECT_POS = 0x04, /**< Prevent automatic positioning (e.g. in lv_cont layout)*/
LV_PROTECT_FOLLOW = 0x08, /**< Prevent the object be followed in automatic ordering (e.g. in
lv_cont PRETTY layout)*/
LV_PROTECT_PRESS_LOST = 0x10, /**< If the `indev` was pressing this object but swiped out while
pressing do not search other object.*/
LV_PROTECT_CLICK_FOCUS = 0x20, /**< Prevent focusing the object by clicking on it*/
};
typedef uint8_t lv_protect_t;
enum {
LV_OBJ_STATE_CHECKED = (LV_STYLE_STATE_CHECKED >> LV_STYLE_STATE_POS),
LV_OBJ_STATE_FOCUS = (LV_STYLE_STATE_FOCUS >> LV_STYLE_STATE_POS),
LV_OBJ_STATE_EDIT = (LV_STYLE_STATE_EDIT >> LV_STYLE_STATE_POS),
LV_OBJ_STATE_HOVER = (LV_STYLE_STATE_HOVER >> LV_STYLE_STATE_POS),
LV_OBJ_STATE_PRESSED = (LV_STYLE_STATE_PRESSED >> LV_STYLE_STATE_POS),
LV_OBJ_STATE_DISABLED = (LV_STYLE_STATE_DISABLED >> LV_STYLE_STATE_POS),
};
typedef uint8_t lv_obj_state_t;
typedef struct _lv_obj_t
{
struct _lv_obj_t * par; /**< Pointer to the parent object*/
@ -230,6 +256,7 @@ typedef struct _lv_obj_t
uint8_t reserved : 3; /**< Reserved for future use*/
uint8_t protect; /**< Automatically happening actions can be prevented. 'OR'ed values from
`lv_protect_t`*/
uint8_t state;
lv_opa_t opa_scale; /**< Scale down the opacity by this factor. Effects all children as well*/
lv_coord_t ext_draw_pad; /**< EXTtend the size in every direction for drawing. */
@ -245,25 +272,12 @@ typedef struct _lv_obj_t
} lv_obj_t;
enum {
LV_OBJ_STYLE_MAIN
LV_OBJ_STYLE_MAIN,
LV_OBJ_STYLE_ALL = 0xFF,
};
typedef uint8_t lv_obj_style_t;
/*Protect some attributes (max. 8 bit)*/
enum {
LV_PROTECT_NONE = 0x00,
LV_PROTECT_CHILD_CHG = 0x01, /**< Disable the child change signal. Used by the library*/
LV_PROTECT_PARENT = 0x02, /**< Prevent automatic parent change (e.g. in lv_page)*/
LV_PROTECT_POS = 0x04, /**< Prevent automatic positioning (e.g. in lv_cont layout)*/
LV_PROTECT_FOLLOW = 0x08, /**< Prevent the object be followed in automatic ordering (e.g. in
lv_cont PRETTY layout)*/
LV_PROTECT_PRESS_LOST = 0x10, /**< If the `indev` was pressing this object but swiped out while
pressing do not search other object.*/
LV_PROTECT_CLICK_FOCUS = 0x20, /**< Prevent focusing the object by clicking on it*/
};
typedef uint8_t lv_protect_t;
/** Used by `lv_obj_get_type()`. The object's and its ancestor types are stored here*/
typedef struct
{
@ -914,6 +928,8 @@ uint8_t lv_obj_get_protect(const lv_obj_t * obj);
*/
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);
/**
* Get the signal function of an object
* @param obj pointer to an object
@ -1018,7 +1034,7 @@ lv_res_t lv_obj_handle_get_type_signal(lv_obj_type_t * buf, const char * name);
* @note Only the relevant fields will be set.
* E.g. if `border width == 0` the other border properties won't be evaluated.
*/
void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t type, lv_draw_rect_dsc_t * draw_dsc);
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);
/**********************
* MACROS

View File

@ -44,19 +44,6 @@ static void style_animation_common_end_cb(lv_anim_t * a);
/**********************
* STATIC VARIABLES
**********************/
//lv_style_t lv_style_scr;
//lv_style_t lv_style_transp;
//lv_style_t lv_style_transp_fit;
//lv_style_t lv_style_transp_tight;
//lv_style_t lv_style_plain;
//lv_style_t lv_style_plain_color;
//lv_style_t lv_style_pretty;
//lv_style_t lv_style_pretty_color;
//lv_style_t lv_style_btn_rel;
//lv_style_t lv_style_btn_pr;
//lv_style_t lv_style_btn_tgl_rel;
//lv_style_t lv_style_btn_tgl_pr;
//lv_style_t lv_style_btn_ina;
/**********************
* MACROS
@ -100,96 +87,143 @@ void lv_style_copy(lv_style_t * dest, const lv_style_t * src)
void lv_style_set_value(lv_style_t * style, lv_style_property_t prop, lv_style_value_t value)
{
int32_t id = get_property_index(style, prop);
/*If exists update the property*/
/*The property already exists but not sure it's state is the same*/
if(id >= 0) {
memcpy(style->map + id + sizeof(lv_style_property_t), &value, sizeof(lv_style_value_t));
}
/*Add new property if not exists yet*/
else {
style->size += sizeof(lv_style_property_t) + sizeof(lv_style_value_t);
style->map = lv_mem_realloc(style->map, style->size);
LV_ASSERT_MEM(style->map);
if(style->map == NULL) return;
lv_style_attr_t attr_found;
lv_style_attr_t attr_goal;
memcpy(style->map + style->size - (sizeof(lv_style_property_t) + sizeof(lv_style_value_t)), &prop, sizeof(lv_style_property_t));
memcpy(style->map + style->size - sizeof(lv_style_value_t), &value, sizeof(lv_style_value_t));
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), &value, sizeof(lv_style_value_t));
return;
}
}
/*Add new property if not exists yet*/
style->size += sizeof(lv_style_property_t) + sizeof(lv_style_value_t);
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(lv_style_value_t)), &prop, sizeof(lv_style_property_t));
memcpy(style->map + style->size - sizeof(lv_style_value_t), &value, sizeof(lv_style_value_t));
}
void lv_style_set_color(lv_style_t * style, lv_style_property_t prop, lv_color_t color)
{
int32_t id = get_property_index(style, prop);
/*If exists update the property*/
/*The property already exists but not sure it's state is the same*/
if(id >= 0) {
memcpy(style->map + id + sizeof(lv_style_property_t), &color, sizeof(lv_color_t));
}
/*Add new property if not exists yet*/
else {
style->size += sizeof(lv_style_property_t) + sizeof(lv_color_t);
style->map = lv_mem_realloc(style->map, style->size);
LV_ASSERT_MEM(style->map);
if(style == NULL) return;
lv_style_attr_t attr_found;
lv_style_attr_t attr_goal;
memcpy(style->map + style->size - (sizeof(lv_style_property_t) + sizeof(lv_color_t)), &prop, sizeof(lv_style_property_t));
memcpy(style->map + style->size - sizeof(lv_color_t), &color, sizeof(lv_color_t));
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), &color, sizeof(lv_color_t));
return;
}
}
/*Add new property if not exists yet*/
style->size += sizeof(lv_style_property_t) + sizeof(lv_color_t);
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(lv_color_t)), &prop, sizeof(lv_style_property_t));
memcpy(style->map + style->size - sizeof(lv_color_t), &color, sizeof(lv_color_t));
}
void lv_style_set_opa(lv_style_t * style, lv_style_property_t prop, lv_opa_t opa)
{
int32_t id = get_property_index(style, prop);
/*If exists update the property*/
/*The property already exists but not sure it's state is the same*/
if(id >= 0) {
memcpy(style->map + id + sizeof(lv_style_property_t), &opa, sizeof(lv_opa_t));
}
/*Add new property if not exists yet*/
else {
style->size += sizeof(lv_style_property_t) + sizeof(lv_opa_t);
style->map = lv_mem_realloc(style->map, style->size);
LV_ASSERT_MEM(style->map);
if(style == NULL) return;
lv_style_attr_t attr_found;
lv_style_attr_t attr_goal;
memcpy(style->map + style->size - (sizeof(lv_style_property_t) + sizeof(lv_opa_t)), &prop, sizeof(lv_style_property_t));
memcpy(style->map + style->size - sizeof(lv_opa_t), &opa, sizeof(lv_opa_t));
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), &opa, sizeof(lv_opa_t));
return;
}
}
/*Add new property if not exists yet*/
style->size += sizeof(lv_style_property_t) + sizeof(lv_opa_t);
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(lv_opa_t)), &prop, sizeof(lv_style_property_t));
memcpy(style->map + style->size - sizeof(lv_opa_t), &opa, sizeof(lv_opa_t));
}
lv_res_t lv_style_get_value(const lv_style_t * style, lv_style_property_t prop, lv_style_value_t * res)
/**
* Get the a property from a style.
* Take into account the style state and return the property which matches the best.
* @param style pointer to a style where to search
* @param prop the property, might contain ORed style states too
* @param res buffer to store the result
* @return the weight of the found property (how well it fits to the style state).
* Higher number is means better fit
* -1 if the not found (`res` will be undefined)
*/
int16_t lv_style_get_value(const lv_style_t * style, lv_style_property_t prop, lv_style_value_t * res)
{
int32_t id = get_property_index(style, prop);
if(id < 0) {
res = 0;
return LV_RES_INV;
return -1;
} else {
memcpy(res, &style->map[id + sizeof(lv_style_property_t)], sizeof(lv_style_value_t));
return LV_RES_OK;
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;
}
}
lv_res_t lv_style_get_opa(const lv_style_t * style, lv_style_property_t prop, lv_opa_t * res)
int16_t lv_style_get_opa(const lv_style_t * style, lv_style_property_t prop, lv_opa_t * res)
{
int32_t id = get_property_index(style, prop);
if(id < 0) {
res = 0;
return LV_RES_INV;
return -1;
} else {
memcpy(res, &style->map[id + sizeof(lv_style_property_t)], sizeof(lv_opa_t));
return LV_RES_OK;
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;
}
}
lv_res_t lv_style_get_color(const lv_style_t * style, lv_style_property_t prop, lv_color_t * res)
int16_t lv_style_get_color(const lv_style_t * style, lv_style_property_t prop, lv_color_t * res)
{
int32_t id = get_property_index(style, prop);
if(id < 0) {
res = 0;
return LV_RES_INV;
return -1;
} else {
memcpy(res, &style->map[id + sizeof(lv_style_property_t)], sizeof(lv_color_t));
return LV_RES_OK;
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;
}
}
@ -286,35 +320,43 @@ void lv_style_anim_set_styles(lv_anim_t * a, lv_style_t * to_anim, const lv_styl
static inline int32_t get_property_index(const lv_style_t * style, lv_style_property_t prop)
{
uint8_t id_to_find = prop & 0xFF;
lv_style_attr_t attr;
attr.full = (prop >> 8) & 0xFF;
int16_t weight = -1;
int16_t id_guess = -1;
size_t i = 0;
while(i < style->size) {
lv_style_attr_t attr_act;
attr_act.full = style->map[i + 1];
if(style->map[i] == id_to_find) {
return i;
} else {
lv_style_attr_t attr;
attr.full = style->map[i + 1];
switch(attr.bits.type) {
case LV_STYLE_ATTR_TYPE_VALUE:
i+= sizeof(lv_style_value_t);
break;
case LV_STYLE_ATTR_TYPE_OPA:
i+= sizeof(lv_opa_t);
break;
case LV_STYLE_ATTR_TYPE_COLOR:
i+= sizeof(lv_color_t);
break;
case LV_STYLE_ATTR_TYPE_PTR:
i+= sizeof(void*);
break;
/*If there the state has perfectly match return this property*/
if(attr_act.bits.state == attr.bits.state) {
return i;
}
/* Be sure the property not specifies other state the the requested.
* E.g. For HOVER+PRESS, HOVER only is OK, but HOVER+FOCUS not*/
else if((attr_act.bits.state & (~attr.bits.state)) == 0) {
/* Use this property if it describes better the requested state than the current candidate.
* E.g. for HOVER+FOCUS+PRESS prefer HOVER+FOCUS over FOCUS*/
if(attr_act.bits.state > weight) {
weight = attr_act.bits.state;
id_guess = i;
}
}
i += sizeof(lv_style_property_t);
}
/*Go to the next property*/
if((style->map[i] & 0xF) < LV_STYLE_ID_COLOR) i+= sizeof(lv_style_value_t);
else if((style->map[i] & 0xF) < LV_STYLE_ID_OPA) i+= sizeof(lv_color_t);
else if((style->map[i] & 0xF) < LV_STYLE_ID_PTR) i+= sizeof(lv_opa_t);
else i+= sizeof(void*);
i += sizeof(lv_style_property_t);
}
return -1;
return id_guess;
}
#if LV_USE_ANIMATION

View File

@ -53,71 +53,94 @@ enum {
typedef uint8_t lv_grad_dir_t;
#define LV_STYLE_PROP_INIT(name, id, attr) name = (id | ((attr) << 8))
#define LV_STYLE_PROP_INIT(name, group, id, attr) name = (((group << 4) + id) | ((attr) << 8))
#define LV_STYLE_ID_MASK 0x00FF
#define LV_STYLE_ATTR_TYPE_OPA (0 << 0)
#define LV_STYLE_ATTR_TYPE_VALUE (1 << 0)
#define LV_STYLE_ATTR_TYPE_COLOR (2 << 0)
#define LV_STYLE_ATTR_TYPE_PTR (3 << 0)
#define LV_STYLE_ATTR_INHERIT (1 << 3)
#define LV_STYLE_ATTR_FLAGS_MASK (0x7 << 5)
#define LV_STYLE_ATTR_NONE 0
#define LV_STYLE_ATTR_INHERIT (1 << 8)
typedef union {
struct {
uint8_t type :3;
uint8_t state :7; /* To which state the property refers to*/
uint8_t inherit :1; /*1: The property can be inherited*/
uint8_t cached :1; /*1: Not a real property of this style just cached from an other style*/
uint8_t reserved :3;
}bits;
uint8_t full;
}lv_style_attr_t;
#define LV_STYLE_ID_VALUE 0x0
#define LV_STYLE_ID_COLOR 0x6
#define LV_STYLE_ID_OPA 0xA
#define LV_STYLE_ID_PTR 0xE
enum {
LV_STYLE_PROP_INIT(LV_STYLE_RADIUS, 0x01, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_PAD_TOP, 0x04, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_PAD_BOTTOM, 0x05, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_PAD_LEFT, 0x06, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_PAD_RIGHT, 0x07, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_PAD_INNER, 0x09, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_BG_COLOR, 0x10, LV_STYLE_ATTR_TYPE_COLOR),
LV_STYLE_PROP_INIT(LV_STYLE_BG_OPA, 0x11, LV_STYLE_ATTR_TYPE_OPA),
LV_STYLE_PROP_INIT(LV_STYLE_BG_CLIP_CORNER, 0x12, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_BG_BLEND_MODE, 0x13, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_COLOR, 0x20, LV_STYLE_ATTR_TYPE_COLOR),
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_OPA, 0x21, LV_STYLE_ATTR_TYPE_OPA),
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_WIDTH, 0x22, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_PART, 0x23, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_BLEND_MODE, 0x24, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_WIDTH, 0x30, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_COLOR, 0x31, LV_STYLE_ATTR_TYPE_COLOR),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_OFFSET_X, 0x32, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_OFFSET_Y, 0x33, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_SPREAD, 0x34, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_OPA, 0x35, LV_STYLE_ATTR_TYPE_OPA),
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_IMG_COLOR, 0x60, LV_STYLE_ATTR_TYPE_COLOR),
LV_STYLE_PROP_INIT(LV_STYLE_RADIUS, 0x0, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_PAD_TOP, 0x1, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_PAD_BOTTOM, 0x1, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_PAD_LEFT, 0x1, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_PAD_RIGHT, 0x1, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_PAD_INNER, 0x1, LV_STYLE_ID_VALUE + 4, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_BG_CLIP_CORNER, 0x2, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_BG_BLEND_MODE, 0x2, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_BG_GRAD_DIR, 0x2, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_BG_COLOR, 0x2, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_BG_GRAD_COLOR, 0x2, LV_STYLE_ID_COLOR + 1, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_BG_OPA, 0x2, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_WIDTH, 0x3, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_PART, 0x3, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_BLEND_MODE, 0x3, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_COLOR, 0x3, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_OPA, 0x3, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_WIDTH, 0x4, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_OFFSET_X, 0x4, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_OFFSET_Y, 0x4, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_SPREAD, 0x4, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
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_IMG_COLOR, 0x60, LV_STYLE_ATTR_TYPE_COLOR),
};
typedef uint16_t lv_style_property_t;
#define LV_STYLE_STATE_POS 8
#define LV_STYLE_STATE_MASK 0x7F00
enum {
LV_STYLE_STATE_CHECKED = (1 << (0 + LV_STYLE_STATE_POS)),
LV_STYLE_STATE_FOCUS = (1 << (1 + LV_STYLE_STATE_POS)),
LV_STYLE_STATE_EDIT = (1 << (2 + LV_STYLE_STATE_POS)),
LV_STYLE_STATE_HOVER = (1 << (3 + LV_STYLE_STATE_POS)),
LV_STYLE_STATE_PRESSED = (1 << (4 + LV_STYLE_STATE_POS)),
LV_STYLE_STATE_DISABLED = (1 << (6 + LV_STYLE_STATE_POS)),
};
typedef uint16_t lv_style_state_t;
typedef struct {
uint8_t * map;
uint16_t used_groups;
uint16_t size;
uint16_t size :9;
uint16_t reserved :7;
}lv_style_t;
typedef struct _lv_style_class_list_t {
typedef struct _lv_style_classes_t {
lv_style_t * style;
struct _lv_style_class_list_t * next;
}lv_style_class_list_t;
struct _lv_style_classes_t * next;
}lv_style_classes_t;
typedef struct {
lv_style_t local;
lv_style_class_list_t * classes;
lv_style_classes_t * classes;
}lv_style_dsc_t;
@ -169,9 +192,11 @@ void lv_style_set_value(lv_style_t * style, lv_style_property_t prop, lv_style_v
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);
lv_res_t lv_style_get_value(const lv_style_t * style, lv_style_property_t prop, lv_style_value_t * res);
lv_res_t lv_style_get_opa(const lv_style_t * style, lv_style_property_t prop, lv_opa_t * res);
lv_res_t lv_style_get_color(const lv_style_t * style, lv_style_property_t prop, lv_color_t * res);
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);
#if LV_USE_ANIMATION

View File

@ -92,15 +92,8 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, const lv_obj_t * copy)
return NULL;
}
ext->state = LV_BTN_STATE_REL;
ext->styles[LV_BTN_STATE_REL] = &lv_style_btn_rel;
ext->styles[LV_BTN_STATE_PR] = &lv_style_btn_pr;
ext->styles[LV_BTN_STATE_TGL_REL] = &lv_style_btn_tgl_rel;
ext->styles[LV_BTN_STATE_TGL_PR] = &lv_style_btn_tgl_pr;
ext->styles[LV_BTN_STATE_INA] = &lv_style_btn_ina;
ext->toggle = 0;
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
ext->ink_in_time = 0;
ext->ink_wait_time = 0;
@ -122,29 +115,28 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, const lv_obj_t * copy)
/*Set the default styles*/
lv_theme_t * th = lv_theme_get_current();
if(th) {
lv_btn_set_style(new_btn, LV_BTN_STYLE_REL, th->style.btn.rel);
lv_btn_set_style(new_btn, LV_BTN_STYLE_PR, th->style.btn.pr);
lv_btn_set_style(new_btn, LV_BTN_STYLE_TGL_REL, th->style.btn.tgl_rel);
lv_btn_set_style(new_btn, LV_BTN_STYLE_TGL_PR, th->style.btn.tgl_pr);
lv_btn_set_style(new_btn, LV_BTN_STYLE_INA, th->style.btn.ina);
// lv_btn_set_style(new_btn, LV_BTN_STYLE_REL, th->style.btn.rel);
// lv_btn_set_style(new_btn, LV_BTN_STYLE_PR, th->style.btn.pr);
// lv_btn_set_style(new_btn, LV_BTN_STYLE_TGL_REL, th->style.btn.tgl_rel);
// lv_btn_set_style(new_btn, LV_BTN_STYLE_TGL_PR, th->style.btn.tgl_pr);
// lv_btn_set_style(new_btn, LV_BTN_STYLE_INA, th->style.btn.ina);
} else {
lv_obj_set_style(new_btn, ext->styles[LV_BTN_STATE_REL]);
// lv_obj_set_style(new_btn, ext->styles[LV_BTN_STATE_REL]);
}
}
/*Copy 'copy'*/
else {
lv_btn_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
ext->state = copy_ext->state;
ext->toggle = copy_ext->toggle;
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
ext->ink_in_time = copy_ext->ink_in_time;
ext->ink_wait_time = copy_ext->ink_wait_time;
ext->ink_out_time = copy_ext->ink_out_time;
#endif
memcpy((void*) ext->styles, copy_ext->styles, sizeof(ext->styles));
// memcpy((void*) ext->styles, copy_ext->styles, sizeof(ext->styles));
/*Refresh the style with new signal function*/
lv_obj_refresh_style(new_btn);
lv_obj_refresh_style(new_btn,LV_BTN_STYLE_MAIN);
}
LV_LOG_INFO("button created");
@ -179,10 +171,21 @@ void lv_btn_set_state(lv_obj_t * btn, lv_btn_state_t state)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
if(ext->state != state) {
ext->state = state;
lv_obj_set_style(btn, ext->styles[state]);
switch(state) {
case LV_BTN_STATE_REL:
lv_obj_clear_state(btn, LV_OBJ_STATE_PRESSED | LV_OBJ_STATE_CHECKED);
break;
case LV_BTN_STATE_PR:
lv_obj_clear_state(btn, LV_OBJ_STATE_CHECKED);
lv_obj_set_state(btn, LV_OBJ_STATE_PRESSED);
break;
case LV_BTN_STATE_TGL_REL:
lv_obj_set_state(btn, LV_OBJ_STATE_CHECKED);
lv_obj_clear_state(btn, LV_OBJ_STATE_PRESSED);
break;
case LV_BTN_STATE_TGL_PR:
lv_obj_set_state(btn, LV_OBJ_STATE_PRESSED | LV_OBJ_STATE_CHECKED);
break;
}
}
@ -194,13 +197,10 @@ void lv_btn_toggle(lv_obj_t * btn)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
switch(ext->state) {
case LV_BTN_STATE_REL: lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL); break;
case LV_BTN_STATE_PR: lv_btn_set_state(btn, LV_BTN_STATE_TGL_PR); break;
case LV_BTN_STATE_TGL_REL: lv_btn_set_state(btn, LV_BTN_STATE_REL); break;
case LV_BTN_STATE_TGL_PR: lv_btn_set_state(btn, LV_BTN_STATE_PR); break;
default: break;
if(lv_obj_get_state(btn) & LV_OBJ_STATE_CHECKED) {
lv_obj_clear_state(btn, LV_OBJ_STATE_CHECKED);
} else {
lv_obj_set_state(btn, LV_OBJ_STATE_CHECKED);
}
}
@ -265,30 +265,6 @@ void lv_btn_set_ink_out_time(lv_obj_t * btn, uint16_t time)
#endif
}
/**
* Set a style of a button
* @param btn pointer to a button object
* @param type which style should be set
* @param style pointer to a style
*/
void lv_btn_set_style(lv_obj_t * btn, lv_btn_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
switch(type) {
case LV_BTN_STYLE_REL: ext->styles[LV_BTN_STATE_REL] = style; break;
case LV_BTN_STYLE_PR: ext->styles[LV_BTN_STATE_PR] = style; break;
case LV_BTN_STYLE_TGL_REL: ext->styles[LV_BTN_STATE_TGL_REL] = style; break;
case LV_BTN_STYLE_TGL_PR: ext->styles[LV_BTN_STATE_TGL_PR] = style; break;
case LV_BTN_STYLE_INA: ext->styles[LV_BTN_STATE_INA] = style; break;
}
/*Refresh the object with the new style*/
lv_obj_set_style(btn, ext->styles[ext->state]);
}
/*=====================
* Getter functions
*====================*/
@ -302,8 +278,16 @@ lv_btn_state_t lv_btn_get_state(const lv_obj_t * btn)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
return ext->state;
lv_obj_state_t state = lv_obj_get_state(btn);
if(state & LV_OBJ_STATE_CHECKED) {
if(state & LV_OBJ_STATE_PRESSED) return LV_BTN_STATE_TGL_PR;
else return LV_BTN_STATE_TGL_REL;
} else {
if(state & LV_OBJ_STATE_PRESSED) return LV_BTN_STATE_PR;
else return LV_BTN_STATE_REL;
}
}
/**
@ -373,42 +357,18 @@ uint16_t lv_btn_get_ink_out_time(const lv_obj_t * btn)
#endif
}
/**
* Get a style of a button
* @param btn pointer to a button object
* @param type which style should be get
* @return style pointer to a style
*/
const lv_style_t * lv_btn_get_style(const lv_obj_t * btn, lv_btn_style_t type)
lv_style_dsc_t * lv_btn_get_style(lv_obj_t * cont, uint8_t type)
{
LV_ASSERT_OBJ(btn, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
lv_btn_state_t state = lv_btn_get_state(btn);
/* If the style of the current state is asked then return object style.
* If the button is focused then this style is updated by the group's
* `style_mod_cb` function */
if((type == LV_BTN_STYLE_REL && state == LV_BTN_STATE_REL) ||
(type == LV_BTN_STYLE_PR && state == LV_BTN_STATE_PR) ||
(type == LV_BTN_STYLE_TGL_REL && state == LV_BTN_STATE_TGL_REL) ||
(type == LV_BTN_STYLE_TGL_PR && state == LV_BTN_STATE_TGL_PR) ||
(type == LV_BTN_STYLE_INA && state == LV_BTN_STATE_INA)) {
style = lv_obj_get_style(btn);
} else {
switch(type) {
case LV_BTN_STYLE_REL: style = ext->styles[LV_BTN_STATE_REL]; break;
case LV_BTN_STYLE_PR: style = ext->styles[LV_BTN_STATE_PR]; break;
case LV_BTN_STYLE_TGL_REL: style = ext->styles[LV_BTN_STATE_TGL_REL]; break;
case LV_BTN_STYLE_TGL_PR: style = ext->styles[LV_BTN_STATE_TGL_PR]; break;
case LV_BTN_STYLE_INA: style = ext->styles[LV_BTN_STATE_INA]; break;
default: style = NULL; break;
}
lv_style_dsc_t * style_dsc_p;
switch(type) {
case LV_BTN_STYLE_MAIN:
style_dsc_p = &cont->style_dsc;
break;
default:
style_dsc_p = NULL;
}
return style;
return style_dsc_p;
}
/**********************
@ -491,7 +451,23 @@ static lv_design_res_t lv_btn_design(lv_obj_t * btn, const lv_area_t * clip_area
}
}
#else
ancestor_design(btn, clip_area, mode);
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_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));
if(lv_obj_get_style_value(btn, LV_OBJ_STYLE_MAIN, LV_STYLE_BG_CLIP_CORNER)) {
lv_draw_mask_radius_param_t * mp = lv_mem_buf_get(sizeof(lv_draw_mask_radius_param_t));
lv_coord_t r = lv_obj_get_style_value(btn, LV_OBJ_STYLE_MAIN, LV_STYLE_RADIUS);
lv_draw_mask_radius_init(mp, &btn->coords, r, false);
/*Add the mask and use `obj+8` as custom id. Don't use `obj` directly because it might be used by the user*/
lv_draw_mask_add(mp, btn + 8);
}
#endif
} else if(mode == LV_DESIGN_DRAW_POST) {
ancestor_design(btn, clip_area, mode);
@ -518,16 +494,16 @@ static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
bool tgl = lv_btn_get_toggle(btn);
lv_btn_state_t state = lv_btn_get_state(btn);
if(sign == LV_SIGNAL_PRESSED) {
/*Refresh the state*/
if(ext->state == LV_BTN_STATE_REL) {
if(state == LV_BTN_STATE_REL) {
lv_btn_set_state(btn, LV_BTN_STATE_PR);
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
ink_bg_state = LV_BTN_STATE_REL;
ink_top_state = LV_BTN_STATE_PR;
#endif
} else if(ext->state == LV_BTN_STATE_TGL_REL) {
} else if(state == LV_BTN_STATE_TGL_REL) {
lv_btn_set_state(btn, LV_BTN_STATE_TGL_PR);
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
ink_bg_state = LV_BTN_STATE_TGL_REL;
@ -567,16 +543,16 @@ static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
#endif
} else if(sign == LV_SIGNAL_PRESS_LOST) {
/*Refresh the state*/
if(ext->state == LV_BTN_STATE_PR)
if(state == LV_BTN_STATE_PR)
lv_btn_set_state(btn, LV_BTN_STATE_REL);
else if(ext->state == LV_BTN_STATE_TGL_PR)
else if(state == LV_BTN_STATE_TGL_PR)
lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
} else if(sign == LV_SIGNAL_PRESSING) {
/*When the button begins to drag revert pressed states to released*/
if(lv_indev_is_dragging(param) != false) {
if(ext->state == LV_BTN_STATE_PR)
if(state == LV_BTN_STATE_PR)
lv_btn_set_state(btn, LV_BTN_STATE_REL);
else if(ext->state == LV_BTN_STATE_TGL_PR)
else if(state == LV_BTN_STATE_TGL_PR)
lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
}
} else if(sign == LV_SIGNAL_RELEASED) {
@ -584,16 +560,16 @@ static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
*change state and run the action*/
if(lv_indev_is_dragging(param) == false) {
uint32_t toggled = 0;
if(ext->state == LV_BTN_STATE_PR && tgl == false) {
if(state == LV_BTN_STATE_PR && tgl == false) {
lv_btn_set_state(btn, LV_BTN_STATE_REL);
toggled = 0;
} else if(ext->state == LV_BTN_STATE_TGL_PR && tgl == false) {
} else if(state == LV_BTN_STATE_TGL_PR && tgl == false) {
lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
toggled = 1;
} else if(ext->state == LV_BTN_STATE_PR && tgl == true) {
} else if(state == LV_BTN_STATE_PR && tgl == true) {
lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
toggled = 1;
} else if(ext->state == LV_BTN_STATE_TGL_PR && tgl == true) {
} else if(state == LV_BTN_STATE_TGL_PR && tgl == true) {
lv_btn_set_state(btn, LV_BTN_STATE_REL);
toggled = 0;
}
@ -602,11 +578,10 @@ static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
res = lv_event_send(btn, LV_EVENT_VALUE_CHANGED, &toggled);
if(res != LV_RES_OK) return res;
}
} else { /*If dragged change back the state*/
if(ext->state == LV_BTN_STATE_PR) {
if(ext == LV_BTN_STATE_PR) {
lv_btn_set_state(btn, LV_BTN_STATE_REL);
} else if(ext->state == LV_BTN_STATE_TGL_PR) {
} else if(state == LV_BTN_STATE_TGL_PR) {
lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
}
}

View File

@ -66,44 +66,14 @@ typedef struct
/** Ext. of ancestor*/
lv_cont_ext_t cont;
/*New data for this type */
/**Styles in each state*/
const lv_style_t * styles[_LV_BTN_STATE_NUM];
#if LV_BTN_INK_EFFECT
/** [ms] Time of ink fill effect (0: disable ink effect)*/
uint16_t ink_in_time;
/** [ms] Wait before the ink disappears */
uint16_t ink_wait_time;
/** [ms] Time of ink disappearing*/
uint16_t ink_out_time;
#endif
/** Current state of the button from 'lv_btn_state_t' enum*/
lv_btn_state_t state : 3;
/** 1: Toggle enabled*/
uint8_t toggle : 1;
} lv_btn_ext_t;
/**Styles*/
enum {
/** Release style */
LV_BTN_STYLE_REL,
LV_BTN_STYLE_MAIN,
/**Pressed style*/
LV_BTN_STYLE_PR,
/** Toggle released style*/
LV_BTN_STYLE_TGL_REL,
/** Toggle pressed style */
LV_BTN_STYLE_TGL_PR,
/** Inactive style*/
LV_BTN_STYLE_INA,
};
typedef uint8_t lv_btn_style_t;
@ -308,13 +278,7 @@ uint16_t lv_btn_get_ink_wait_time(const lv_obj_t * btn);
*/
uint16_t lv_btn_get_ink_out_time(const lv_obj_t * btn);
/**
* Get style of a button.
* @param btn pointer to button object
* @param type which style should be get
* @return style pointer to the style
* */
const lv_style_t * lv_btn_get_style(const lv_obj_t * btn, lv_btn_style_t type);
lv_style_dsc_t * lv_btn_get_style(lv_obj_t * cont, uint8_t type);
/**********************
* MACROS

View File

@ -255,7 +255,6 @@ lv_style_dsc_t * lv_cont_get_style(lv_obj_t * cont, uint8_t type)
}
return style_dsc_p;
}
/**********************