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

new_style: implement generic style set/get functions

This commit is contained in:
Gabor Kiss-Vamosi 2019-12-17 09:20:40 +01:00
parent a101e9a3e5
commit 02ca70c691
8 changed files with 268 additions and 200 deletions

View File

@ -51,6 +51,7 @@ typedef struct _lv_event_temp_data
* STATIC PROTOTYPES
**********************/
static void refresh_children_position(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff);
static inline lv_res_t get_style_prop_core(const lv_obj_t * obj, uint8_t type, lv_style_property_t prop, void * out);
static void report_style_mod_core(void * style_p, lv_obj_t * obj);
static void refresh_children_style(lv_obj_t * obj);
static void delete_children(lv_obj_t * obj);
@ -189,9 +190,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
if(th) {
// new_obj->style_p = th->style.scr;
} else {
lv_style_init(&new_obj->style_local);
new_obj->style_chain.style = &new_obj->style_local;
new_obj->style_chain.next = NULL;
lv_style_dsc_init(&new_obj->style_dsc);
}
/*Init. user date*/
@ -283,9 +282,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
if(th) {
// new_obj->style_p = th->style.panel;
} else {
lv_style_init(&new_obj->style_local);
new_obj->style_chain.style = &new_obj->style_local;
new_obj->style_chain.next = NULL;
lv_style_dsc_init(&new_obj->style_dsc);
}
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
@ -1219,40 +1216,47 @@ void lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t left, lv_coord_t right
void lv_obj_set_style_color(lv_obj_t * obj, lv_style_property_t prop, lv_color_t color)
{
lv_style_set_color(&obj->style_local, prop, color);
lv_style_set_color(&obj->style_dsc.local, prop, color);
}
void lv_obj_set_style_value(lv_obj_t * obj, lv_style_property_t prop, lv_style_value_t value)
{
lv_style_set_value(&obj->style_local, prop, value);
lv_style_set_value(&obj->style_dsc.local, prop, value);
}
void lv_obj_set_style_opa(lv_obj_t * obj, lv_style_property_t prop, lv_opa_t opa)
{
lv_style_set_opa(&obj->style_local, prop, opa);
lv_style_set_opa(&obj->style_dsc.local, prop, opa);
}
void lv_obj_add_style_class(lv_obj_t * obj, lv_style_t * style)
void lv_obj_add_style_class(lv_obj_t * obj, uint8_t type, lv_style_t * style)
{
lv_obj_style_chian_t * s = lv_mem_alloc(sizeof(lv_obj_style_chian_t));
s->style = style;
lv_style_class_list_t * class = lv_mem_alloc(sizeof(lv_style_class_list_t));
/* Insert the class after the first item.
* (The first style is the local style, and the newest class should came after it.)*/
s->next = obj->style_chain.next;
obj->style_chain.next = s;
lv_style_dsc_t * style_dsc = lv_obj_get_style(obj, type);
if(style_dsc == NULL) {
LV_LOG_WARN("lv_obj_add_style_class: can't find style with `type`");
return;
}
class->style = style;
/* Insert the class to the first place.*/
class->next = style_dsc->classes;
style_dsc->classes = class;
lv_obj_refresh_style(obj, type);
}
/**
* Notify an object about its style is modified
* @param obj pointer to an object
*/
void lv_obj_refresh_style(lv_obj_t * obj)
void lv_obj_refresh_style(lv_obj_t * obj, uint8_t type)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_invalidate(obj);
obj->signal_cb(obj, LV_SIGNAL_STYLE_CHG, NULL);
obj->signal_cb(obj, LV_SIGNAL_STYLE_CHG, &type);
lv_obj_invalidate(obj);
}
@ -1579,12 +1583,16 @@ void lv_obj_set_signal_cb(lv_obj_t * obj, lv_signal_cb_t signal_cb)
* Send an event to the object
* @param obj pointer to an object
* @param event the type of the event from `lv_event_t`.
* @return LV_RES_OK or LV_RES_INV
*/
void lv_signal_send(lv_obj_t * obj, lv_signal_t signal, void * param)
lv_res_t lv_signal_send(lv_obj_t * obj, lv_signal_t signal, void * param)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
if(obj->signal_cb) obj->signal_cb(obj, signal, param);
lv_res_t res = LV_RES_OK;
if(obj->signal_cb) res = obj->signal_cb(obj, signal, param);
return res;
}
/**
@ -1811,8 +1819,8 @@ void lv_obj_get_inner_coords(const lv_obj_t * obj, lv_area_t * coords_p)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_border_part_t part = lv_obj_get_style_value(obj, LV_STYLE_BORDER_PART);
lv_coord_t w = lv_obj_get_style_value(obj, LV_STYLE_BORDER_WIDTH);
lv_border_part_t part = lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_BORDER_PART);
lv_coord_t w = lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_BORDER_WIDTH);
if(part & LV_BORDER_PART_LEFT) coords_p->x1 += w;
@ -1894,8 +1902,8 @@ lv_coord_t lv_obj_get_width_fit(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_style_value_t left = lv_obj_get_style_value(obj, LV_STYLE_PAD_LEFT);
lv_style_value_t right = lv_obj_get_style_value(obj, LV_STYLE_PAD_RIGHT);
lv_style_value_t left = lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_PAD_LEFT);
lv_style_value_t right = lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_PAD_RIGHT);
return lv_obj_get_width(obj) - left - right;
}
@ -1909,8 +1917,8 @@ lv_coord_t lv_obj_get_height_fit(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_style_value_t top = lv_obj_get_style_value(obj, LV_STYLE_PAD_TOP);
lv_style_value_t bottom = lv_obj_get_style_value(obj, LV_STYLE_PAD_BOTTOM);
lv_style_value_t top = lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_PAD_TOP);
lv_style_value_t bottom = lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_PAD_BOTTOM);
return lv_obj_get_height(obj) - top - bottom;
}
@ -2024,85 +2032,59 @@ lv_coord_t lv_obj_get_ext_draw_pad(const lv_obj_t * obj)
* Appearance get
*---------------*/
lv_style_value_t lv_obj_get_style_value(const lv_obj_t * obj, lv_style_property_t prop)
lv_style_dsc_t * lv_obj_get_style(const lv_obj_t * obj, uint8_t type)
{
lv_res_t found = LV_RES_INV;
lv_style_value_t res;
void * p = &type;
lv_res_t res;
res = lv_signal_send((lv_obj_t*)obj, LV_SIGNAL_GET_STYLE, &p);
lv_style_attr_t attr;
attr.full= prop >> 8;
if(res != LV_RES_OK) return NULL;
const lv_obj_t * parent = obj;
while(parent) {
const lv_obj_style_chian_t * chain = &obj->style_chain;
while(chain) {
found = lv_style_get_value(chain->style, prop, &res);
if(found == LV_RES_OK) {
return res;
}
chain = chain->next;
}
return p;
}
if(attr.bits.inherit == 0) break;
parent = lv_obj_get_parent(parent);
}
switch(prop) {
case LV_STYLE_BORDER_PART:
return LV_BORDER_PART_FULL;
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);
if(found == LV_RES_OK) return value;
else {
/*Default value*/
switch(prop) {
case LV_STYLE_BORDER_PART:
return LV_BORDER_PART_FULL;
}
}
return 0;
}
lv_color_t lv_obj_get_style_color(const lv_obj_t * obj, lv_style_property_t prop)
lv_color_t lv_obj_get_style_color(const lv_obj_t * obj, uint8_t type, lv_style_property_t prop)
{
lv_res_t found = LV_RES_INV;
lv_color_t res;
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;
const lv_obj_t * parent = obj;
while(parent) {
const lv_obj_style_chian_t * chain = &obj->style_chain;
while(chain) {
found = lv_style_get_color(chain->style, prop, &res);
if(found == LV_RES_OK) {
return res;
}
chain = chain->next;
}
if(attr.bits.inherit == 0) break;
parent = lv_obj_get_parent(parent);
if(found == LV_RES_OK) return color;
else {
/*Default colors*/
}
return LV_COLOR_WHITE;
}
lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, lv_style_property_t prop)
lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t type, lv_style_property_t prop)
{
lv_res_t found = LV_RES_INV;
lv_opa_t res;
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;
const lv_obj_t * parent = obj;
while(parent) {
const lv_obj_style_chian_t * chain = &obj->style_chain;
while(chain) {
found = lv_style_get_opa(chain->style, prop, &res);
if(found == LV_RES_OK) {
return res;
}
chain = chain->next;
}
if(attr.bits.inherit == 0) break;
parent = lv_obj_get_parent(parent);
if(found == LV_RES_OK) return opa;
else {
/*Default opa*/
}
return LV_OPA_COVER;
@ -2518,24 +2500,25 @@ static void lv_obj_del_async_cb(void * obj)
/**
* Initialize a rectangle descriptor from an object's styles
* @param obj pointer to an object
* @param chain an extra style chain to evaluate before processing the object's styles
* @param dsc the descriptor the initialize
* @param type type of style. E.g. `LV_OBJ_STYLE_MAIN`, `LV_BTN_STYLE_REL` or `LV_PAGE_STYLE_SCRL`
* @param draw_dsc the descriptor the initialize
* @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, lv_obj_style_chian_t * chain, lv_draw_rect_dsc_t * dsc)
void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t type, lv_draw_rect_dsc_t * draw_dsc)
{
lv_draw_rect_dsc_init(dsc);
dsc->radius = lv_obj_get_style_value(obj, LV_STYLE_RADIUS);
dsc->bg_color = lv_obj_get_style_color(obj, LV_STYLE_BG_COLOR);
lv_draw_rect_dsc_init(draw_dsc);
draw_dsc->radius = lv_obj_get_style_value(obj, type, LV_STYLE_RADIUS);
dsc->border_width = lv_obj_get_style_value(obj, LV_STYLE_BORDER_WIDTH);
if(dsc->border_width) {
dsc->border_opa = lv_obj_get_style_opa(obj, LV_STYLE_BORDER_OPA);
if(dsc->border_opa >= LV_OPA_MIN) {
dsc->border_part = lv_obj_get_style_value(obj, LV_STYLE_BORDER_PART);
dsc->border_color = lv_obj_get_style_color(obj, LV_STYLE_BORDER_COLOR);
draw_dsc->bg_color = lv_obj_get_style_color(obj, type, LV_STYLE_BG_COLOR);
draw_dsc->border_width = lv_obj_get_style_value(obj, type, LV_STYLE_BORDER_WIDTH);
if(draw_dsc->border_width) {
draw_dsc->border_opa = lv_obj_get_style_opa(obj, type, LV_STYLE_BORDER_OPA);
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);
}
}
}
@ -2555,17 +2538,17 @@ static lv_design_res_t lv_obj_design(lv_obj_t * obj, const lv_area_t * clip_area
/*Most trivial test. Is the mask fully IN the object? If no it surely doesn't cover it*/
if(lv_area_is_in(clip_area, &obj->coords) == false) return LV_DESIGN_RES_NOT_COVER;
if(lv_obj_get_style_value(obj, LV_STYLE_BG_BLEND_MODE) != LV_BLEND_MODE_NORMAL) return LV_DESIGN_RES_NOT_COVER;
if(lv_obj_get_style_value(obj, LV_STYLE_BORDER_BLEND_MODE) != LV_BLEND_MODE_NORMAL) return LV_DESIGN_RES_NOT_COVER;
if(lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_BG_BLEND_MODE) != LV_BLEND_MODE_NORMAL) return LV_DESIGN_RES_NOT_COVER;
if(lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_BORDER_BLEND_MODE) != LV_BLEND_MODE_NORMAL) return LV_DESIGN_RES_NOT_COVER;
if(lv_obj_get_style_value(obj, LV_STYLE_BG_CLIP_CORNER)) return LV_DESIGN_RES_MASKED;
if(lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_BG_CLIP_CORNER)) return LV_DESIGN_RES_MASKED;
/*Can cover the area only if fully solid (no opacity)*/
if(lv_obj_get_style_opa(obj, LV_STYLE_BG_OPA) < LV_OPA_MAX) return LV_DESIGN_RES_NOT_COVER;
if(lv_obj_get_style_opa(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_BG_OPA) < LV_OPA_MAX) return LV_DESIGN_RES_NOT_COVER;
/* Because of the radius it is not sure the area is covered
* Check the areas where there is no radius*/
lv_coord_t r = lv_obj_get_style_value(obj, LV_STYLE_RADIUS);
lv_coord_t r = lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_RADIUS);
if(r == LV_RADIUS_CIRCLE) return LV_DESIGN_RES_NOT_COVER;
@ -2588,13 +2571,13 @@ 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, NULL, &draw_dsc);
lv_obj_init_draw_rect_dsc(obj, LV_OBJ_STYLE_MAIN, &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_STYLE_BG_CLIP_CORNER)) {
if(lv_obj_get_style_value(obj, 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(obj, LV_STYLE_RADIUS);
lv_coord_t r = lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_RADIUS);
lv_draw_mask_radius_init(mp, &obj->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*/
@ -2602,8 +2585,8 @@ static lv_design_res_t lv_obj_design(lv_obj_t * obj, const lv_area_t * clip_area
}
}
else if(mode == LV_DESIGN_DRAW_POST) {
// const lv_style_t * style = lv_obj_get_style(obj);
if(lv_obj_get_style_value(obj, LV_STYLE_BG_CLIP_CORNER)) {
// const lv_style_t * style_dsc = lv_obj_get_style(obj);
if(lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_BG_CLIP_CORNER)) {
lv_draw_mask_radius_param_t * param = lv_draw_mask_remove_custom(obj + 8);
lv_mem_buf_release(param);
}
@ -2621,7 +2604,12 @@ static lv_design_res_t lv_obj_design(lv_obj_t * obj, const lv_area_t * clip_area
*/
static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
{
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_GET_STYLE) {
lv_style_dsc_t ** style_dsc_p = param;
*style_dsc_p = &obj->style_dsc;
return LV_RES_OK;
}
else if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_res_t res = LV_RES_OK;
@ -2629,9 +2617,10 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
/*Return 'invalid' if the child change signal is not enabled*/
if(lv_obj_is_protected(obj, LV_PROTECT_CHILD_CHG) != false) res = LV_RES_INV;
} else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
lv_coord_t shadow = (lv_obj_get_style_value(obj, LV_STYLE_SHADOW_WIDTH) >> 1) + 1;
shadow += lv_obj_get_style_value(obj, LV_STYLE_SHADOW_SPREAD);
shadow += LV_MATH_MAX(LV_MATH_ABS(lv_obj_get_style_value(obj, LV_STYLE_SHADOW_OFFSET_X)), LV_MATH_ABS(lv_obj_get_style_value(obj, LV_STYLE_SHADOW_OFFSET_Y)));
lv_coord_t shadow = (lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_SHADOW_WIDTH) >> 1) + 1;
shadow += lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_SHADOW_SPREAD);
shadow += LV_MATH_MAX(LV_MATH_ABS(lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_SHADOW_OFFSET_X)),
LV_MATH_ABS(lv_obj_get_style_value(obj, LV_OBJ_STYLE_MAIN, LV_STYLE_SHADOW_OFFSET_Y)));
if(shadow > obj->ext_draw_pad) obj->ext_draw_pad = shadow;
} else if(sign == LV_SIGNAL_STYLE_CHG) {
@ -2660,9 +2649,40 @@ 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.
* @param style_p refresh objects only with this style_dsc.
* @param obj pointer to an object
*/
static void report_style_mod_core(void * style_p, lv_obj_t * obj)
@ -2692,7 +2712,7 @@ static void refresh_children_style(lv_obj_t * obj)
// refresh_children_style(child); /*Check children too*/
// lv_obj_refresh_style(child); /*Notify the child about the style change*/
// } else if(child->style_p->glass) {
// /*Children with 'glass' parent might be effected if their style == NULL*/
// /*Children with 'glass' parent might be effected if their class == NULL*/
// refresh_children_style(child);
// }
// child = lv_obj_get_child(obj, child);

View File

@ -30,6 +30,7 @@ extern "C" {
#include "../lv_misc/lv_log.h"
#include "../lv_misc/lv_bidi.h"
#include "../lv_hal/lv_hal.h"
#include "../lv_draw/lv_draw_rect.h"
/*********************
* DEFINES
@ -46,9 +47,9 @@ extern "C" {
#define LV_MAX_ANCESTOR_NUM 8
#define LV_EXT_CLICK_AREA_OFF 0
#define LV_EXT_CLICK_AREA_TINY 1
#define LV_EXT_CLICK_AREA_FULL 2
#define LV_EXT_CLICK_AREA_OFF 0
#define LV_EXT_CLICK_AREA_TINY 1
#define LV_EXT_CLICK_AREA_FULL 2
/**********************
* TYPEDEFS
@ -126,6 +127,7 @@ enum {
LV_SIGNAL_BASE_DIR_CHG, /**<The base dir has changed*/
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*/
/*Input device related*/
LV_SIGNAL_PRESSED, /**< The object has been pressed*/
@ -187,11 +189,6 @@ typedef struct
} lv_reailgn_t;
#endif
typedef struct _lv_obj_style_chian_t {
lv_style_t * style;
struct _lv_obj_style_chian_t * next;
}lv_obj_style_chian_t;
typedef struct _lv_obj_t
{
struct _lv_obj_t * par; /**< Pointer to the parent object*/
@ -204,8 +201,7 @@ typedef struct _lv_obj_t
lv_design_cb_t design_cb; /**< Object type specific design function*/
void * ext_attr; /**< Object type specific extended data*/
lv_style_t style_local;
lv_obj_style_chian_t style_chain;
lv_style_dsc_t style_dsc;
#if LV_USE_GROUP != 0
void * group_p; /**< Pointer to the group of the object*/
@ -248,6 +244,12 @@ typedef struct _lv_obj_t
} lv_obj_t;
enum {
LV_OBJ_STYLE_MAIN
};
typedef uint8_t lv_obj_style_t;
/*Protect some attributes (max. 8 bit)*/
enum {
LV_PROTECT_NONE = 0x00,
@ -454,11 +456,12 @@ void lv_obj_set_style_value(lv_obj_t * obj, lv_style_property_t prop, lv_style_v
void lv_obj_set_style_opa(lv_obj_t * obj, lv_style_property_t prop, lv_opa_t opa);
void lv_obj_add_style_class(lv_obj_t * obj, uint8_t type, lv_style_t * style);
/**
* Notify an object about its style is modified
* @param obj pointer to an object
*/
void lv_obj_refresh_style(lv_obj_t * obj);
void lv_obj_refresh_style(lv_obj_t * obj, uint8_t type);
/**
* Notify all object if a style is modified
@ -604,12 +607,14 @@ const void * lv_event_get_data(void);
*/
void lv_obj_set_signal_cb(lv_obj_t * obj, lv_signal_cb_t signal_cb);
/**
* Send an event to the object
* @param obj pointer to an object
* @param event the type of the event from `lv_event_t`.
* @return LV_RES_OK or LV_RES_INV
*/
void lv_signal_send(lv_obj_t * obj, lv_signal_t signal, void * param);
lv_res_t lv_signal_send(lv_obj_t * obj, lv_signal_t signal, void * param);
/**
* Set a new design function for an object
@ -802,11 +807,13 @@ lv_coord_t lv_obj_get_ext_draw_pad(const lv_obj_t * obj);
* Appearance get
*---------------*/
lv_style_value_t lv_obj_get_style_value(const lv_obj_t * obj, lv_style_property_t prop);
lv_style_dsc_t * lv_obj_get_style(const lv_obj_t * obj, uint8_t type);
lv_color_t lv_obj_get_style_color(const lv_obj_t * obj, lv_style_property_t prop);
lv_style_value_t lv_obj_get_style_value(const lv_obj_t * obj, uint8_t type, lv_style_property_t prop);
lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, lv_style_property_t prop);
lv_color_t lv_obj_get_style_color(const lv_obj_t * obj, uint8_t type, lv_style_property_t prop);
lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t type, lv_style_property_t prop);
///**
// * Get the style pointer of an object (if NULL get style of the parent)
@ -1001,6 +1008,18 @@ bool lv_obj_is_focused(const lv_obj_t * obj);
*/
lv_res_t lv_obj_handle_get_type_signal(lv_obj_type_t * buf, const char * name);
/**
* Initialize a rectangle descriptor from an object's styles
* @param obj pointer to an object
* @param type type of style. E.g. `LV_OBJ_STYLE_MAIN`, `LV_BTN_STYLE_REL` or `LV_PAGE_STYLE_SCRL`
* @param draw_dsc the descriptor the initialize
* @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);
/**********************
* MACROS
**********************/

View File

@ -435,7 +435,7 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
/*If no better children check this object*/
if(found_p == NULL) {
if(lv_obj_get_style_value(obj, LV_STYLE_BG_OPA) == LV_OPA_COVER && design_res == LV_DESIGN_RES_COVER &&
if(design_res == LV_DESIGN_RES_COVER &&
lv_obj_get_opa_scale(obj) == LV_OPA_COVER) {
found_p = obj;
}

View File

@ -81,6 +81,12 @@ void lv_style_init(lv_style_t * style)
style->used_groups = 0;
}
void lv_style_dsc_init(lv_style_dsc_t * style_dsc)
{
lv_style_init(&style_dsc->local);
style_dsc->classes = NULL;
}
/**
* Copy a style to an other
* @param dest pointer to the destination style

View File

@ -81,6 +81,7 @@ enum {
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),
@ -109,6 +110,17 @@ typedef struct {
uint16_t size;
}lv_style_t;
typedef struct _lv_style_class_list_t {
lv_style_t * style;
struct _lv_style_class_list_t * next;
}lv_style_class_list_t;
typedef struct {
lv_style_t local;
lv_style_class_list_t * classes;
}lv_style_dsc_t;
typedef int16_t lv_style_value_t;
#if LV_USE_ANIMATION
@ -135,6 +147,8 @@ void lv_style_built_in_init(void);
void lv_style_init(lv_style_t * style);
void lv_style_dsc_init(lv_style_dsc_t * style_dsc);
/**
* Copy a style to an other
* @param dest pointer to the destination style

View File

@ -17,18 +17,20 @@ extern "C" {
/*********************
* DEFINES
*********************/
// Check windows
/* Check windows*/
#ifdef __WIN64
#define LV_ARCH_64
#endif
// Check GCC
/* Check GCC */
#ifdef __GNUC__
#if defined(__x86_64__) || defined(__ppc64__)
#define LV_ARCH_64
#endif
#endif
#define LV_UNUNSED(x) (void)x;
/**********************
* TYPEDEFS
**********************/

View File

@ -99,9 +99,9 @@ lv_obj_t * lv_cont_create(lv_obj_t * par, const lv_obj_t * copy)
if(par != NULL) {
lv_theme_t * th = lv_theme_get_current();
if(th) {
lv_cont_set_style(new_cont, LV_CONT_STYLE_MAIN, th->style.cont);
// lv_cont_set_style(new_cont, LV_CONT_STYLE_MAIN, th->style_dsc.cont);
} else {
lv_cont_set_style(new_cont, LV_CONT_STYLE_MAIN, &lv_style_pretty);
// lv_cont_set_style(new_cont, LV_CONT_STYLE_MAIN, &lv_style_pretty);
}
}
}
@ -115,7 +115,7 @@ lv_obj_t * lv_cont_create(lv_obj_t * par, const lv_obj_t * copy)
ext->layout = copy_ext->layout;
/*Refresh the style with new signal function*/
lv_obj_refresh_style(new_cont);
lv_obj_refresh_style(new_cont, LV_CONT_STYLE_MAIN);
}
LV_LOG_INFO("container created");
@ -242,6 +242,22 @@ lv_fit_t lv_cont_get_fit_bottom(const lv_obj_t * cont)
return ext->fit_bottom;
}
lv_style_dsc_t * lv_cont_get_style(lv_obj_t * cont, uint8_t type)
{
lv_style_dsc_t * style_dsc_p;
switch(type) {
case LV_CONT_STYLE_MAIN:
style_dsc_p = &cont->style_dsc;
break;
default:
style_dsc_p = NULL;
}
return style_dsc_p;
}
/**********************
* STATIC FUNCTIONS
**********************/
@ -255,6 +271,14 @@ lv_fit_t lv_cont_get_fit_bottom(const lv_obj_t * cont)
*/
static lv_res_t lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param)
{
if(sign == LV_SIGNAL_GET_STYLE) {
uint8_t ** type_p = param;
lv_style_dsc_t ** style_dsc_p = param;
*style_dsc_p = lv_cont_get_style(cont, **type_p);
return LV_RES_OK;
}
lv_res_t res;
/* Include the ancient signal function */
@ -281,7 +305,6 @@ static lv_res_t lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param)
return res;
}
/**
* Refresh the layout of a container
* @param cont pointer to an object which layout should be refreshed
@ -314,17 +337,21 @@ static void lv_cont_refr_layout(lv_obj_t * cont)
*/
static void lv_cont_layout_col(lv_obj_t * cont)
{
lv_coord_t left = lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_LEFT);
lv_coord_t right = lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_RIGHT);
lv_coord_t top = lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_TOP);
lv_coord_t inner = lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_INNER);
lv_layout_t type = lv_cont_get_layout(cont);
lv_obj_t * child;
/*Adjust margin and get the alignment type*/
lv_align_t align;
const lv_style_t * style = lv_obj_get_style(cont);
lv_coord_t hpad_corr;
switch(type) {
case LV_LAYOUT_COL_L:
hpad_corr = style->body.padding.left;
hpad_corr = left;
align = LV_ALIGN_IN_TOP_LEFT;
break;
case LV_LAYOUT_COL_M:
@ -332,7 +359,7 @@ static void lv_cont_layout_col(lv_obj_t * cont)
align = LV_ALIGN_IN_TOP_MID;
break;
case LV_LAYOUT_COL_R:
hpad_corr = -style->body.padding.right;
hpad_corr = -right;
align = LV_ALIGN_IN_TOP_RIGHT;
break;
default:
@ -345,13 +372,13 @@ static void lv_cont_layout_col(lv_obj_t * cont)
* an unnecessary child change signals could be sent*/
lv_obj_set_protect(cont, LV_PROTECT_CHILD_CHG);
/* Align the children */
lv_coord_t last_cord = style->body.padding.top;
lv_coord_t last_cord = top;
LV_LL_READ_BACK(cont->child_ll, child)
{
if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;
lv_obj_align(child, cont, align, hpad_corr, last_cord);
last_cord += lv_obj_get_height(child) + style->body.padding.inner;
last_cord += lv_obj_get_height(child) + inner;
}
lv_obj_clear_protect(cont, LV_PROTECT_CHILD_CHG);
@ -363,17 +390,17 @@ static void lv_cont_layout_col(lv_obj_t * cont)
*/
static void lv_cont_layout_row(lv_obj_t * cont)
{
lv_layout_t type = lv_cont_get_layout(cont);
lv_obj_t * child;
/*Adjust margin and get the alignment type*/
lv_align_t align;
const lv_style_t * style = lv_obj_get_style(cont);
lv_coord_t vpad_corr;
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(cont);
switch(type) {
case LV_LAYOUT_ROW_T:
vpad_corr = style->body.padding.top;
vpad_corr = lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_TOP);
align = base_dir == LV_BIDI_DIR_RTL ? LV_ALIGN_IN_TOP_RIGHT : LV_ALIGN_IN_TOP_LEFT;
break;
case LV_LAYOUT_ROW_M:
@ -381,7 +408,7 @@ static void lv_cont_layout_row(lv_obj_t * cont)
align = base_dir == LV_BIDI_DIR_RTL ? LV_ALIGN_IN_RIGHT_MID: LV_ALIGN_IN_LEFT_MID;
break;
case LV_LAYOUT_ROW_B:
vpad_corr = -style->body.padding.bottom;
vpad_corr = -lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_BOTTOM);;
align = base_dir == LV_BIDI_DIR_RTL ? LV_ALIGN_IN_BOTTOM_RIGHT: LV_ALIGN_IN_BOTTOM_LEFT;
break;
default:
@ -396,19 +423,19 @@ static void lv_cont_layout_row(lv_obj_t * cont)
/* Align the children */
lv_coord_t last_cord;
if(base_dir == LV_BIDI_DIR_RTL) last_cord = style->body.padding.right;
else last_cord = style->body.padding.left;
if(base_dir == LV_BIDI_DIR_RTL) last_cord = lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_RIGHT);
else last_cord = lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_LEFT);
lv_coord_t inner = lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_INNER);
LV_LL_READ_BACK(cont->child_ll, child)
{
if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;
// last_cord -= lv_obj_get_width(child);
if(base_dir == LV_BIDI_DIR_RTL) lv_obj_align(child, cont, align, -last_cord, vpad_corr);
else lv_obj_align(child, cont, align, last_cord, vpad_corr);
last_cord += lv_obj_get_width(child) + style->body.padding.inner;
last_cord += lv_obj_get_width(child) + inner;
}
lv_obj_clear_protect(cont, LV_PROTECT_CHILD_CHG);
@ -421,20 +448,20 @@ static void lv_cont_layout_row(lv_obj_t * cont)
static void lv_cont_layout_center(lv_obj_t * cont)
{
lv_obj_t * child;
const lv_style_t * style = lv_obj_get_style(cont);
uint32_t obj_num = 0;
lv_coord_t h_tot = 0;
lv_coord_t inner = lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_INNER);
LV_LL_READ(cont->child_ll, child)
{
if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;
h_tot += lv_obj_get_height(child) + style->body.padding.inner;
h_tot += lv_obj_get_height(child) + inner;
obj_num++;
}
if(obj_num == 0) return;
h_tot -= style->body.padding.inner;
h_tot -= inner;
/* Disable child change action because the children will be moved a lot
* an unnecessary child change signals could be sent*/
@ -447,7 +474,7 @@ static void lv_cont_layout_center(lv_obj_t * cont)
if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;
lv_obj_align(child, cont, LV_ALIGN_CENTER, 0, last_cord + lv_obj_get_height(child) / 2);
last_cord += lv_obj_get_height(child) + style->body.padding.inner;
last_cord += lv_obj_get_height(child) + inner;
}
lv_obj_clear_protect(cont, LV_PROTECT_CHILD_CHG);
@ -463,9 +490,8 @@ static void lv_cont_layout_pretty(lv_obj_t * cont)
lv_obj_t * child_rs; /* Row starter child */
lv_obj_t * child_rc; /* Row closer child */
lv_obj_t * child_tmp; /* Temporary child */
const lv_style_t * style = lv_obj_get_style(cont);
lv_coord_t w_obj = lv_obj_get_width(cont);
lv_coord_t act_y = style->body.padding.top;
lv_coord_t act_y = lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_TOP);
/* Disable child change action because the children will be moved a lot
* an unnecessary child change signals could be sent*/
@ -473,12 +499,14 @@ static void lv_cont_layout_pretty(lv_obj_t * cont)
if(child_rs == NULL) return; /*Return if no child*/
lv_obj_set_protect(cont, LV_PROTECT_CHILD_CHG);
lv_coord_t left = lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_LEFT);
lv_coord_t right = lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_RIGHT);
lv_coord_t inner = lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_INNER);
child_rc = child_rs; /*Initially the the row starter and closer is the same*/
while(child_rs != NULL) {
lv_coord_t h_row = 0;
lv_coord_t w_row =
style->body.padding.left + style->body.padding.right; /*The width is at least the left+right hpad*/
lv_coord_t w_row = left + right; /*The width is at least the left+right pad*/
uint32_t obj_num = 0;
/*Find the row closer object and collect some data*/
@ -493,7 +521,7 @@ static void lv_cont_layout_pretty(lv_obj_t * cont)
}
break;
}
w_row += lv_obj_get_width(child_rc) + style->body.padding.inner; /*Add the object width + opad*/
w_row += lv_obj_get_width(child_rc) + inner; /*Add the object width + opad*/
h_row = LV_MATH_MAX(h_row, lv_obj_get_height(child_rc)); /*Search the highest object*/
obj_num++;
if(lv_obj_is_protected(child_rc, LV_PROTECT_FOLLOW))
@ -527,9 +555,9 @@ static void lv_cont_layout_pretty(lv_obj_t * cont)
}
/* Align the children (from child_rs to child_rc)*/
else {
w_row -= style->body.padding.inner * obj_num;
w_row -= inner * obj_num;
lv_coord_t new_opad = (w_obj - w_row) / (obj_num - 1);
lv_coord_t act_x = style->body.padding.left; /*x init*/
lv_coord_t act_x = left; /*x init*/
child_tmp = child_rs;
while(child_tmp != NULL) {
if(lv_obj_get_hidden(child_tmp) == false && lv_obj_is_protected(child_tmp, LV_PROTECT_POS) == false) {
@ -543,7 +571,7 @@ static void lv_cont_layout_pretty(lv_obj_t * cont)
}
if(child_rc == NULL) break;
act_y += style->body.padding.inner + h_row; /*y increment*/
act_y += inner + h_row; /*y increment*/
child_rs = lv_ll_get_prev(&cont->child_ll, child_rc); /*Go to the next object*/
child_rc = child_rs;
}
@ -557,27 +585,28 @@ static void lv_cont_layout_pretty(lv_obj_t * cont)
static void lv_cont_layout_grid(lv_obj_t * cont)
{
lv_obj_t * child;
const lv_style_t * style = lv_obj_get_style(cont);
lv_coord_t w_tot = lv_obj_get_width(cont);
lv_coord_t w_obj = lv_obj_get_width(lv_obj_get_child(cont, NULL));
lv_coord_t w_fit = lv_obj_get_width_fit(cont);
lv_coord_t h_obj = lv_obj_get_height(lv_obj_get_child(cont, NULL));
uint16_t obj_row = (w_fit) / (w_obj + style->body.padding.inner); /*Obj. num. in a row*/
lv_coord_t inner = lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_INNER);
uint16_t obj_row = (w_fit) / (w_obj + inner); /*Obj. num. in a row*/
lv_coord_t x_ofs;
if(obj_row > 1) {
x_ofs = w_obj + (w_fit - (obj_row * w_obj)) / (obj_row - 1);
} else {
x_ofs = w_tot / 2 - w_obj / 2;
}
lv_coord_t y_ofs = h_obj + style->body.padding.inner;
lv_coord_t y_ofs = h_obj + inner;
/* Disable child change action because the children will be moved a lot
* an unnecessary child change signals could be sent*/
lv_obj_set_protect(cont, LV_PROTECT_CHILD_CHG);
/* Align the children */
lv_coord_t act_x = style->body.padding.left;
lv_coord_t act_y = style->body.padding.top;
lv_coord_t left = lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_LEFT);
lv_coord_t act_x = left;
lv_coord_t act_y = lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_TOP);
uint16_t obj_cnt = 0;
LV_LL_READ_BACK(cont->child_ll, child)
{
@ -593,7 +622,7 @@ static void lv_cont_layout_grid(lv_obj_t * cont)
if(obj_cnt >= obj_row) {
obj_cnt = 0;
act_x = style->body.padding.left;
act_x = left;
act_y += y_ofs;
}
}
@ -616,17 +645,15 @@ static void lv_cont_refr_autofit(lv_obj_t * cont)
lv_area_t tight_area;
lv_area_t ori;
const lv_style_t * style = lv_obj_get_style(cont);
lv_obj_t * child_i;
lv_obj_t * par = lv_obj_get_parent(cont);
const lv_style_t * par_style = lv_obj_get_style(par);
lv_area_t flood_area;
lv_area_copy(&flood_area, &par->coords);
flood_area.x1 += par_style->body.padding.left;
flood_area.x2 -= par_style->body.padding.right;
flood_area.y1 += par_style->body.padding.top;
flood_area.y2 -= par_style->body.padding.bottom;
flood_area.x1 += lv_obj_get_style_value(par, LV_OBJ_STYLE_MAIN, LV_STYLE_PAD_LEFT);
flood_area.x2 -= lv_obj_get_style_value(par, LV_OBJ_STYLE_MAIN, LV_STYLE_PAD_RIGHT);
flood_area.y1 += lv_obj_get_style_value(par, LV_OBJ_STYLE_MAIN, LV_STYLE_PAD_TOP);
flood_area.y2 -= lv_obj_get_style_value(par, LV_OBJ_STYLE_MAIN, LV_STYLE_PAD_BOTTOM);
/*Search the side coordinates of the children*/
lv_obj_get_coords(cont, &ori);
@ -649,10 +676,10 @@ static void lv_cont_refr_autofit(lv_obj_t * cont)
tight_area.y2 = LV_MATH_MAX(tight_area.y2, child_i->coords.y2);
}
tight_area.x1 -= style->body.padding.left;
tight_area.x2 += style->body.padding.right;
tight_area.y1 -= style->body.padding.top;
tight_area.y2 += style->body.padding.bottom;
tight_area.x1 -= lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_LEFT);
tight_area.x2 += lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_RIGHT);
tight_area.y1 -= lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_TOP);
tight_area.y2 += lv_obj_get_style_value(cont, LV_CONT_STYLE_MAIN, LV_STYLE_PAD_BOTTOM);
}
lv_area_t new_area;

View File

@ -134,18 +134,6 @@ static inline void lv_cont_set_fit(lv_obj_t * cont, lv_fit_t fit)
lv_cont_set_fit4(cont, fit, fit, fit, fit);
}
/**
* Set the style of a container
* @param cont pointer to a container object
* @param type which style should be set (can be only `LV_CONT_STYLE_MAIN`)
* @param style pointer to the new style
*/
static inline void lv_cont_set_style(lv_obj_t * cont, lv_cont_style_t type, const lv_style_t * style)
{
(void)type; /*Unused*/
lv_obj_set_style(cont, style);
}
/*=====================
* Getter functions
*====================*/
@ -185,17 +173,9 @@ lv_fit_t lv_cont_get_fit_top(const lv_obj_t * cont);
*/
lv_fit_t lv_cont_get_fit_bottom(const lv_obj_t * cont);
/**
* Get the style of a container
* @param cont pointer to a container object
* @param type which style should be get (can be only `LV_CONT_STYLE_MAIN`)
* @return pointer to the container's style
*/
static inline const lv_style_t * lv_cont_get_style(const lv_obj_t * cont, lv_cont_style_t type)
{
(void)type; /*Unused*/
return lv_obj_get_style(cont);
}
lv_style_dsc_t * lv_cont_get_style(lv_obj_t * cont, uint8_t type);
/**********************
* MACROS