integrate image drawing + slider, sw

This commit is contained in:
Gabor Kiss-Vamosi
2019-12-31 22:13:32 +01:00
parent 9b757d30fc
commit b4ee25e9cc
20 changed files with 900 additions and 1315 deletions

View File

@@ -20,6 +20,7 @@
/*********************
* DEFINES
*********************/
#define LV_GROUP_NUM ((1 << LV_GROUP_ID_MAX) - 1)
/**********************
* TYPEDEFS
@@ -39,6 +40,7 @@ static void obj_to_foreground(lv_obj_t * obj);
/**********************
* STATIC VARIABLES
**********************/
static lv_group_t groups[LV_GROUP_NUM];
/**********************
* MACROS
@@ -53,57 +55,19 @@ static void obj_to_foreground(lv_obj_t * obj);
*/
void lv_group_init(void)
{
lv_ll_init(&LV_GC_ROOT(_lv_group_ll), sizeof(lv_group_t));
}
memset(groups, 0x00, sizeof(groups));
/**
* Create a new object group
* @return pointer to the new object group
*/
lv_group_t * lv_group_create(void)
{
lv_group_t * group = lv_ll_ins_head(&LV_GC_ROOT(_lv_group_ll));
LV_ASSERT_MEM(group);
if(group == NULL) return NULL;
lv_ll_init(&group->obj_ll, sizeof(lv_obj_t *));
group->obj_focus = NULL;
group->frozen = 0;
group->focus_cb = NULL;
group->click_focus = 1;
group->editing = 0;
group->refocus_policy = LV_GROUP_REFOCUS_POLICY_PREV;
group->wrap = 1;
#if LV_USE_USER_DATA
memset(&group->user_data, 0, sizeof(lv_group_user_data_t));
#endif
return group;
}
/**
* Delete a group object
* @param group pointer to a group
*/
void lv_group_del(lv_group_t * group)
{
/*Defocus the the currently focused object*/
if(group->obj_focus != NULL) {
(*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
lv_obj_invalidate(*group->obj_focus);
uint8_t i;
for(i = 0; i < LV_GROUP_NUM; i++) {
lv_ll_init(&groups[i].obj_ll, sizeof(lv_obj_t *));
groups[i].obj_focus = NULL;
groups[i].frozen = 0;
groups[i].focus_cb = NULL;
groups[i].click_focus = 1;
groups[i].editing = 0;
groups[i].refocus_policy = LV_GROUP_REFOCUS_POLICY_PREV;
groups[i].wrap = 1;
}
/*Remove the objects from the group*/
lv_obj_t ** obj;
LV_LL_READ(group->obj_ll, obj)
{
(*obj)->group_p = NULL;
}
lv_ll_clear(&(group->obj_ll));
lv_ll_remove(&LV_GC_ROOT(_lv_group_ll), group);
lv_mem_free(group);
}
/**

View File

@@ -56,10 +56,7 @@ typedef struct _lv_group_t
lv_ll_t obj_ll; /**< Linked list to store the objects in the group */
lv_obj_t ** obj_focus; /**< The object in focus*/
lv_group_style_mod_cb_t style_mod_cb; /**< A function to modifies the style of the focused object*/
lv_group_style_mod_cb_t style_mod_edit_cb; /**< A function which modifies the style of the edited object*/
lv_group_focus_cb_t focus_cb; /**< A function to call when a new object is focused (optional)*/
lv_style_t style_tmp; /**< Stores the modified style of the focused object */
#if LV_USE_USER_DATA
lv_group_user_data_t user_data;
#endif

View File

@@ -773,7 +773,7 @@ static void indev_proc_press(lv_indev_proc_t * proc)
proc->types.pointer.drag_in_prog = 0;
proc->types.pointer.drag_sum.x = 0;
proc->types.pointer.drag_sum.y = 0;
proc->types.pointer.drag_dir = LV_DRAG_DIR_NONE;
proc->types.pointer.drag_dir = LV_DRAG_DIR_BOTH;
proc->types.pointer.vect.x = 0;
proc->types.pointer.vect.y = 0;
@@ -1016,7 +1016,7 @@ static void indev_proc_reset_query_handler(lv_indev_t * indev)
indev->proc.longpr_rep_timestamp = 0;
indev->proc.types.pointer.drag_sum.x = 0;
indev->proc.types.pointer.drag_sum.y = 0;
indev->proc.types.pointer.drag_dir = LV_DRAG_DIR_NONE;
indev->proc.types.pointer.drag_dir = LV_DRAG_DIR_BOTH;
indev->proc.types.pointer.drag_throw_vect.x = 0;
indev->proc.types.pointer.drag_throw_vect.y = 0;
indev->proc.reset_query = 0;

View File

@@ -129,6 +129,11 @@ void lv_init(void)
}
#if LV_ENABLE_GC || !LV_MEM_CUSTOM
/**
* Deinit the 'lv' library
* Currently only implemented when not using custom allocators, or GC is enabled.
*/
void lv_deinit(void)
{
lv_gc_clear_roots();
@@ -256,8 +261,6 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
new_obj->base_dir = LV_BIDI_DIR_LTR;
#endif
new_obj->reserved = 0;
new_obj->ext_attr = NULL;
lv_style_dsc_init(&new_obj->style_dsc);
@@ -1241,22 +1244,16 @@ void lv_obj_refresh_style(lv_obj_t * obj, uint8_t part)
*/
void lv_obj_report_style_mod(lv_style_t * style)
{
// LV_ASSERT_STYLE(style);
//
// lv_disp_t * d = lv_disp_get_next(NULL);
//
// while(d) {
// lv_obj_t * i;
// LV_LL_READ(d->scr_ll, i)
// {
// if(i->style_p == style || style == NULL) {
// lv_obj_refresh_style(i);
// }
//
// report_style_mod_core(style, i);
// }
// d = lv_disp_get_next(d);
// }
lv_disp_t * d = lv_disp_get_next(NULL);
while(d) {
lv_obj_t * i;
LV_LL_READ(d->scr_ll, i)
{
report_style_mod_core(style, i);
}
d = lv_disp_get_next(d);
}
}
/*-----------------
@@ -2895,6 +2892,25 @@ void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint8_t part, lv_draw_label_dsc_
}
}
void lv_obj_init_draw_img_dsc(lv_obj_t * obj, uint8_t part, lv_draw_img_dsc_t * draw_dsc)
{
draw_dsc->angle = 0;
draw_dsc->zoom = LV_IMG_ZOOM_NONE;
draw_dsc->pivot.x = lv_area_get_width(&obj->coords) / 2;
draw_dsc->pivot.y = lv_area_get_height(&obj->coords) / 2;
draw_dsc->opa = lv_obj_get_style_opa(obj, part, LV_STYLE_IMAGE_OPA);
if(draw_dsc->opa <= LV_OPA_MIN) return;
lv_opa_t opa_scale = lv_obj_get_style_opa(obj, part, LV_STYLE_OPA_SCALE);
if(opa_scale < LV_OPA_MAX) {
draw_dsc->opa = (uint16_t)((uint16_t)draw_dsc->opa * opa_scale) >> 8;
}
if(draw_dsc->opa <= LV_OPA_MIN) return;
draw_dsc->overlay_opa = lv_obj_get_style_opa(obj, part, LV_STYLE_OVERLAY_OPA);
draw_dsc->overlay_color = lv_obj_get_style_color(obj, part, LV_STYLE_OVERLAY_COLOR);
draw_dsc->blend_mode = lv_obj_get_style_value(obj, part, LV_STYLE_IMAGE_BLEND_MODE);
}
/**
* Handle the drawing related tasks of the base objects.
* @param obj pointer to an object
@@ -3000,7 +3016,9 @@ 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_USE_GROUP
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;
@@ -3011,6 +3029,7 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
} else if(sign == LV_SIGNAL_DEFOCUS) {
lv_obj_clear_state(obj, LV_OBJ_STATE_FOCUS | LV_OBJ_STATE_EDIT);
}
#endif
return res;
}
@@ -3037,21 +3056,40 @@ static void refresh_children_position(lv_obj_t * obj, lv_coord_t x_diff, lv_coor
/**
* Refresh the style of all children of an object. (Called recursively)
* @param style_p refresh objects only with this style_dsc.
* @param style 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)
static void report_style_mod_core(void * style, lv_obj_t * obj)
{
// lv_obj_t * i;
// LV_LL_READ(obj->child_ll, i)
// {
// if(i->style.local == style_p || style_p == NULL) {
// refresh_children_style(i);
// lv_obj_refresh_style(i);
// }
//
// report_style_mod_core(style_p, i);
// }
uint8_t part_sub;
for(part_sub = 0; part_sub != LV_OBJ_PART_ALL; part_sub++) {
lv_style_dsc_t * dsc = lv_obj_get_style(obj, part_sub);
if(dsc == NULL) break;
if(&dsc->local == style) {
lv_obj_refresh_style(obj, part_sub);
/* Two local style can't have the same pointer
* so there won't be an other match*/
return;
}
uint8_t ci;
for(ci = 0; ci < dsc->class_cnt; ci++) {
lv_style_t * class = lv_style_dsc_get_class(dsc, ci);
if(class == style) {
lv_obj_refresh_style(obj, part_sub);
/*It's enough to handle once (if duplicated)*/
break;
}
}
}
lv_obj_t * child = lv_obj_get_child(obj, NULL);
while(child) {
report_style_mod_core(style, child);
child = lv_obj_get_child(obj, child);
}
}
/**

View File

@@ -225,37 +225,37 @@ typedef struct _lv_obj_t
void * ext_attr; /**< Object type specific extended data*/
lv_style_dsc_t style_dsc;
#if LV_USE_GROUP != 0
void * group_p; /**< Pointer to the group of the object*/
#endif
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
uint8_t ext_click_pad_hor; /**< Extra click padding in horizontal direction */
uint8_t ext_click_pad_ver; /**< Extra click padding in vertical direction */
#endif
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
lv_area_t ext_click_pad; /**< Extra click padding area. */
#endif
/*Attributes and states*/
uint8_t click : 1; /**< 1: Can be pressed by an input device*/
uint8_t drag : 1; /**< 1: Enable the dragging*/
uint8_t drag_throw : 1; /**< 1: Enable throwing with drag*/
uint8_t drag_parent : 1; /**< 1: Parent will be dragged instead*/
uint8_t hidden : 1; /**< 1: Object is hidden*/
uint8_t top : 1; /**< 1: If the object or its children is clicked it goes to the foreground*/
uint8_t parent_event : 1; /**< 1: Send the object's events to the parent too. */
lv_drag_dir_t drag_dir : 3; /**< Which directions the object can be dragged in */
lv_bidi_dir_t base_dir : 2; /**< Base direction of texts related to this object */
uint8_t adv_hittest : 1; /**< 1: Use advanced hit-testing (slower) */
uint8_t reserved : 2; /**< Reserved for future use*/
uint8_t protect; /**< Automatically happening actions can be prevented. 'OR'ed values from
`lv_protect_t`*/
uint8_t state;
lv_coord_t ext_draw_pad; /**< EXTtend the size in every direction for drawing. */
/*Attributes and states*/
uint8_t click :1; /**< 1: Can be pressed by an input device*/
uint8_t drag :1; /**< 1: Enable the dragging*/
uint8_t drag_throw :1; /**< 1: Enable throwing with drag*/
uint8_t drag_parent :1; /**< 1: Parent will be dragged instead*/
uint8_t hidden :1; /**< 1: Object is hidden*/
uint8_t top :1; /**< 1: If the object or its children is clicked it goes to the foreground*/
uint8_t parent_event :1; /**< 1: Send the object's events to the parent too. */
uint8_t adv_hittest :1; /**< 1: Use advanced hit-testing (slower) */
lv_drag_dir_t drag_dir :2; /**< Which directions the object can be dragged in */
lv_bidi_dir_t base_dir :2; /**< Base direction of texts related to this object */
#if LV_USE_GROUP != 0
uint8_t group_id :LV_GROUP_ID_MAX;
#endif
uint8_t protect; /**< Automatically happening actions can be prevented.
'OR'ed values from `lv_protect_t`*/
uint8_t state;
#if LV_USE_OBJ_REALIGN
lv_realign_t realign; /**< Information about the last call to ::lv_obj_align. */
#endif
@@ -298,7 +298,7 @@ void lv_init(void);
/**
* Deinit the 'lv' library
* Currently only implemented when not using custorm allocators, or GC is enabled.
* Currently only implemented when not using custom allocators, or GC is enabled.
*/
#if LV_ENABLE_GC || !LV_MEM_CUSTOM
void lv_deinit(void);
@@ -1075,6 +1075,7 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t type, lv_draw_rect_dsc_t
void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint8_t type, lv_draw_label_dsc_t * draw_dsc);
void lv_obj_init_draw_img_dsc(lv_obj_t * obj, uint8_t part, lv_draw_img_dsc_t * draw_dsc);
/**********************
* MACROS
**********************/

View File

@@ -61,7 +61,14 @@ void lv_style_init(lv_style_t * style)
{
style->map = NULL;
style->size = 0;
style->used_groups = 0;
}
void lv_style_copy(lv_style_t * style_dest, const lv_style_t * style_src)
{
lv_style_init(style_dest);
style_dest->map = lv_mem_alloc(style_src->size);
memcpy(style_dest->map, style_src->map, style_src->size);
style_dest->size = style_src->size;
}
void lv_style_dsc_init(lv_style_dsc_t * style_dsc)
@@ -142,17 +149,6 @@ void lv_style_reset(lv_style_t * style)
lv_mem_free(style->map);
style->map = NULL;
style->size = 0;
style->used_groups = 0;
}
/**
* Copy a style to an other
* @param dest pointer to the destination style
* @param src pointer to the source style
*/
void lv_style_copy(lv_style_t * dest, const lv_style_t * src)
{
memcpy(dest, src, sizeof(lv_style_t));
}
void lv_style_set_value(lv_style_t * style, lv_style_property_t prop, lv_style_value_t value)
@@ -180,10 +176,6 @@ void lv_style_set_value(lv_style_t * style, lv_style_property_t prop, lv_style_v
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));
/*Set that group is used this style*/
uint16_t group = (prop >> 4) & 0xF;
style->used_groups |= 1 << group;
}
void lv_style_set_color(lv_style_t * style, lv_style_property_t prop, lv_color_t color)
@@ -211,10 +203,6 @@ void lv_style_set_color(lv_style_t * style, lv_style_property_t prop, lv_color_t
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));
/*Set that group is used this style*/
uint16_t group = (prop >> 4) & 0xF;
style->used_groups |= 1 << group;
}
void lv_style_set_opa(lv_style_t * style, lv_style_property_t prop, lv_opa_t opa)
@@ -242,10 +230,6 @@ void lv_style_set_opa(lv_style_t * style, lv_style_property_t prop, lv_opa_t opa
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));
/*Set that group is used this style*/
uint16_t group = (prop >> 4) & 0xF;
style->used_groups |= 1 << group;
}
void lv_style_set_ptr(lv_style_t * style, lv_style_property_t prop, void * p)
@@ -273,10 +257,6 @@ void lv_style_set_ptr(lv_style_t * style, lv_style_property_t prop, void * p)
memcpy(style->map + style->size - (sizeof(lv_style_property_t) + sizeof(void *)), &prop, sizeof(lv_style_property_t));
memcpy(style->map + style->size - sizeof(void *), &p, sizeof(void *));
/*Set that group is used this style*/
uint16_t group = (prop >> 4) & 0xF;
style->used_groups |= 1 << group;
}
@@ -361,59 +341,6 @@ int16_t lv_style_get_ptr(const lv_style_t * style, lv_style_property_t prop, voi
}
}
/**
* Mix two styles according to a given ratio
* @param start start style
* @param end end style
* @param res store the result style here
* @param ratio the ratio of mix [0..256]; 0: `start` style; 256: `end` style
*/
void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res, uint16_t ratio)
{
// STYLE_ATTR_MIX(body.opa, ratio);
// STYLE_ATTR_MIX(body.radius, ratio);
// STYLE_ATTR_MIX(body.border.width, ratio);
// STYLE_ATTR_MIX(body.border.opa, ratio);
// STYLE_ATTR_MIX(body.shadow.width, ratio);
// STYLE_ATTR_MIX(body.shadow.offset.x, ratio);
// STYLE_ATTR_MIX(body.shadow.offset.y, ratio);
// STYLE_ATTR_MIX(body.shadow.spread, ratio);
// STYLE_ATTR_MIX(body.padding.left, ratio);
// STYLE_ATTR_MIX(body.padding.right, ratio);
// STYLE_ATTR_MIX(body.padding.top, ratio);
// STYLE_ATTR_MIX(body.padding.bottom, ratio);
// STYLE_ATTR_MIX(body.padding.inner, ratio);
// STYLE_ATTR_MIX(text.line_space, ratio);
// STYLE_ATTR_MIX(text.letter_space, ratio);
// STYLE_ATTR_MIX(text.opa, ratio);
// STYLE_ATTR_MIX(line.width, ratio);
// STYLE_ATTR_MIX(line.opa, ratio);
// STYLE_ATTR_MIX(image.intense, ratio);
// STYLE_ATTR_MIX(image.opa, ratio);
//
// lv_opa_t opa = ratio == STYLE_MIX_MAX ? LV_OPA_COVER : ratio;
//
// res->body.main_color = lv_color_mix(end->body.main_color, start->body.main_color, opa);
// res->body.grad_color = lv_color_mix(end->body.grad_color, start->body.grad_color, opa);
// res->body.border.color = lv_color_mix(end->body.border.color, start->body.border.color, opa);
// res->body.shadow.color = lv_color_mix(end->body.shadow.color, start->body.shadow.color, opa);
// res->text.color = lv_color_mix(end->text.color, start->text.color, opa);
// res->image.color = lv_color_mix(end->image.color, start->image.color, opa);
// res->line.color = lv_color_mix(end->line.color, start->line.color, opa);
//
// if(ratio < (STYLE_MIX_MAX >> 1)) {
// res->body.border.part = start->body.border.part;
// res->glass = start->glass;
// res->text.font = start->text.font;
// res->line.rounded = start->line.rounded;
// } else {
// res->body.border.part = end->body.border.part;
// res->glass = end->glass;
// res->text.font = end->text.font;
// res->line.rounded = end->line.rounded;
// }
}
#if LV_USE_ANIMATION
void lv_style_anim_init(lv_anim_t * a)
@@ -426,25 +353,25 @@ void lv_style_anim_init(lv_anim_t * a)
a->ready_cb = style_animation_common_end_cb;
lv_style_anim_dsc_t * dsc;
dsc = lv_mem_alloc(sizeof(lv_style_anim_dsc_t));
LV_ASSERT_MEM(dsc);
if(dsc == NULL) return;
dsc->ready_cb = NULL;
dsc->style_anim = NULL;
lv_style_copy(&dsc->style_start, &lv_style_plain);
lv_style_copy(&dsc->style_end, &lv_style_plain);
lv_style_init(&dsc->style_start);
lv_style_init(&dsc->style_end);
a->var = (void *)dsc;
}
void lv_style_anim_set_styles(lv_anim_t * a, lv_style_t * to_anim, const lv_style_t * start, const lv_style_t * end)
{
lv_style_anim_dsc_t * dsc = a->var;
dsc->style_anim = to_anim;
memcpy(&dsc->style_start, start, sizeof(lv_style_t));
memcpy(&dsc->style_end, end, sizeof(lv_style_t));
memcpy(dsc->style_anim, start, sizeof(lv_style_t));
lv_style_copy(&dsc->style_start, start);
lv_style_copy(&dsc->style_end, end);
}
#endif
/**********************
@@ -453,40 +380,15 @@ 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)
{
static uint32_t stat[256];
static uint32_t s = 0;
uint8_t id_to_find = prop & 0xFF;
lv_style_attr_t attr;
attr.full = (prop >> 8) & 0xFF;
stat[id_to_find]++;
// if(s > 1000) {
// printf("\n\n");
// s = 0;
// uint32_t i;
// for(i = 0; i < 256; i++) {
// if(stat[i] == 0) continue;
// printf("%02x;%d;\n", i, stat[i]);
// }
// }
int16_t weight = -1;
int16_t id_guess = -1;
uint16_t group = (id_to_find >> 4) & 0xF;
if((style->used_groups & (1 << group)) == 0) return id_guess;
size_t i = 0;
while(i < style->size) {
// s++;
// printf("style search:%d\n", s);
lv_style_attr_t attr_act;
attr_act.full = style->map[i + 1];
if(style->map[i] == id_to_find) {
@@ -519,6 +421,7 @@ static inline int32_t get_property_index(const lv_style_t * style, lv_style_prop
}
#if LV_USE_ANIMATION
/**
* Used by the style animations to set the values of a style according to start and end style.
* @param dsc the 'animated variable' set by lv_style_anim_create()
@@ -530,7 +433,77 @@ static void style_animator(lv_style_anim_dsc_t * dsc, lv_anim_value_t val)
const lv_style_t * end = &dsc->style_end;
lv_style_t * act = dsc->style_anim;
lv_style_mix(start, end, act, val);
size_t i = 0;
lv_style_property_t prop_act;
while(i < start->size) {
prop_act = start->map[i] + (start->map[i + 1] << 8);
/*Value*/
if((start->map[i] & 0xF) < LV_STYLE_ID_COLOR) {
lv_style_value_t v1;
memcpy(&v1, &start->map[i + sizeof(lv_style_property_t)], sizeof(lv_style_value_t));
int16_t res2;
lv_style_value_t v2;
res2 = lv_style_get_value(end, prop_act, &v2);
if(res2 >= 0) {
lv_style_value_t vres = v1 + ((int32_t)((int32_t)(v2-v1) * val) >> 8);
lv_style_set_value(act, prop_act, vres);
}
i+= sizeof(lv_style_value_t);
}
/*Color*/
else if((start->map[i] & 0xF) < LV_STYLE_ID_OPA) {
lv_color_t color1;
memcpy(&color1, &start->map[i + sizeof(lv_style_property_t)], sizeof(lv_color_t));
int16_t res2;
lv_color_t color2;
res2 = lv_style_get_color(end, prop_act, &color2);
if(res2 >= 0) {
lv_color_t color_res = val == 256 ? color2 : lv_color_mix(color2, color1, (lv_opa_t)val);
lv_style_set_color(act, prop_act, color_res);
}
i+= sizeof(lv_color_t);
}
/*Opa*/
else if((start->map[i] & 0xF) < LV_STYLE_ID_PTR) {
lv_opa_t opa1;
memcpy(&opa1, &start->map[i + sizeof(lv_style_property_t)], sizeof(lv_opa_t));
int16_t res2;
lv_opa_t opa2;
res2 = lv_style_get_opa(end, prop_act, &opa2);
if(res2 >= 0) {
lv_opa_t opa_res = opa1 + ((uint16_t)((uint16_t)(opa2 - opa1) * val) >> 8);
lv_style_set_opa(act, prop_act, opa_res);
}
i+= sizeof(lv_opa_t);
}
else {
void * p1;
memcpy(p1, &start->map[i + sizeof(lv_style_property_t)], sizeof(void *));
int16_t res2;
void * p2;
res2 = lv_style_get_ptr(end, prop_act, &p2);
if(res2 >= 0) {
if(val > 128) lv_style_set_ptr(act, prop_act, p2);
else if(val > 128) lv_style_set_ptr(act, prop_act, p1);
}
i+= sizeof(void*);
}
i += sizeof(lv_style_property_t);
}
lv_obj_report_style_mod(dsc->style_anim);
}

View File

@@ -150,9 +150,7 @@ typedef uint16_t lv_style_state_t;
typedef struct {
uint8_t * map;
uint16_t used_groups;
uint16_t size :9;
uint16_t reserved :7;
}lv_style_t;
typedef int16_t lv_style_value_t;
@@ -229,10 +227,11 @@ typedef struct {
/** Data structure for style animations. */
typedef struct
{
lv_style_t style_start; /*Save not only pointers because can be same as 'style_anim' then it
will be modified too*/
lv_style_t style_start; /* Save not only pointers because can be same as 'style_anim' and
then it would be modified too*/
lv_style_t style_end;
lv_style_t * style_anim;
lv_style_property_t * prop_list;
lv_anim_ready_cb_t ready_cb;
} lv_style_anim_dsc_t;
#endif

View File

@@ -25,12 +25,12 @@
/**********************
* STATIC PROTOTYPES
**********************/
static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mask, const void * src,
const lv_style_t * style, uint16_t angle, lv_point_t * pivot, uint16_t zoom, bool antialaias, lv_opa_t opa_scale);
static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mask, lv_draw_img_dsc_t * draw_dsc, const void * src);
static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area, const uint8_t * map_p, lv_opa_t opa,
bool chroma_key, bool alpha_byte, const lv_style_t * style, uint16_t angle, lv_point_t * pivot, uint16_t zoom, bool antialaias);
static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area, const uint8_t * map_p, lv_draw_img_dsc_t * draw_dsc,
bool chroma_key, bool alpha_byte);
void show_error(const lv_area_t * coords, const lv_area_t * clip_area, const char * msg);
/**********************
* STATIC VARIABLES
**********************/
@@ -43,6 +43,15 @@ static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area,
* GLOBAL FUNCTIONS
**********************/
void lv_draw_img_dsc_init(lv_draw_img_dsc_t * dsc)
{
memset(dsc, 0x00, sizeof(lv_draw_img_dsc_t));
dsc->opa = LV_OPA_COVER;
dsc->zoom = LV_IMG_ZOOM_NONE;
dsc->antialias = LV_ANTIALIAS;
}
/**
* Draw an image
* @param coords the coordinates of the image
@@ -54,25 +63,22 @@ static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area,
* @param antialias anti-alias transformations (rotate, zoom) or not
* @param opa_scale scale down all opacities by the factor
*/
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_style_t * style,
uint16_t angle, lv_point_t * center, uint16_t zoom, bool antialias, lv_opa_t opa_scale)
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, lv_draw_img_dsc_t * dsc)
{
// if(src == NULL) {
// LV_LOG_WARN("Image draw: src is NULL");
// lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
// lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR);
// return;
// }
//
// lv_res_t res;
// res = lv_img_draw_core(coords, mask, src, style, angle, center, zoom, antialias, opa_scale);
//
// if(res == LV_RES_INV) {
// LV_LOG_WARN("Image draw error");
// lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
// lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR);
// return;
// }
if(src == NULL) {
LV_LOG_WARN("Image draw: src is NULL");
show_error(coords, mask, "No\ndata");
return;
}
lv_res_t res;
res = lv_img_draw_core(coords, mask, src, dsc);
if(res == LV_RES_INV) {
LV_LOG_WARN("Image draw error");
show_error(coords, mask, "No\ndata");
return;
}
}
/**
@@ -191,127 +197,124 @@ lv_img_src_t lv_img_src_get_type(const void * src)
* STATIC FUNCTIONS
**********************/
static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mask, const void * src,
const lv_style_t * style, uint16_t angle, lv_point_t * pivot, uint16_t zoom, bool antialias, lv_opa_t opa_scale)
static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mask, lv_draw_img_dsc_t * draw_dsc, const void * src)
{
// lv_opa_t opa =
// opa_scale == LV_OPA_COVER ? style->image.opa : (uint16_t)((uint16_t)style->image.opa * opa_scale) >> 8;
//
// lv_img_cache_entry_t * cdsc = lv_img_cache_open(src, style);
//
// if(cdsc == NULL) return LV_RES_INV;
//
// bool chroma_keyed = lv_img_cf_is_chroma_keyed(cdsc->dec_dsc.header.cf);
// bool alpha_byte = lv_img_cf_has_alpha(cdsc->dec_dsc.header.cf);
//
// if(cdsc->dec_dsc.error_msg != NULL) {
// LV_LOG_WARN("Image draw error");
// lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
// lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR);
// }
// /* The decoder open could open the image and gave the entire uncompressed image.
// * Just draw it!*/
// else if(cdsc->dec_dsc.img_data) {
// lv_area_t map_area_rot;
// lv_area_copy(&map_area_rot, coords);
// if(angle || zoom != LV_IMG_ZOOM_NONE) {
// /*Get the exact area which is required to show the rotated image*/
// lv_coord_t pivot_x = lv_area_get_width(coords) / 2 + coords->x1;
// lv_coord_t pivot_y = lv_area_get_height(coords) / 2 + coords->y1;
//
// if (pivot){
// pivot_x = pivot->x + coords->x1;
// pivot_y = pivot->y + coords->y1;
// }
// lv_coord_t w = lv_area_get_width(coords);
// lv_coord_t w_zoom = (((w * zoom) >> 8) - w) / 2;
// lv_coord_t h = lv_area_get_height(coords);
// lv_coord_t h_zoom = (((h * zoom) >> 8) - h) / 2;
//
// lv_area_t norm;
// norm.x1 = coords->x1 - pivot_x - w_zoom;
// norm.y1 = coords->y1 - pivot_y - h_zoom;
// norm.x2 = coords->x2 - pivot_x + w_zoom;
// norm.y2 = coords->y2 - pivot_y + h_zoom;
//
// int16_t sinma = lv_trigo_sin(angle);
// int16_t cosma = lv_trigo_sin(angle + 90);
//
// lv_point_t lt;
// lv_point_t rt;
// lv_point_t lb;
// lv_point_t rb;
// lt.x = ((cosma * norm.x1 - sinma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_x;
// lt.y = ((sinma * norm.x1 + cosma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_y;
//
// rt.x = ((cosma * norm.x2 - sinma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_x;
// rt.y = ((sinma * norm.x2 + cosma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_y;
//
// lb.x = ((cosma * norm.x1 - sinma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_x;
// lb.y = ((sinma * norm.x1 + cosma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_y;
//
// rb.x = ((cosma * norm.x2 - sinma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_x;
// rb.y = ((sinma * norm.x2 + cosma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_y;
//
// map_area_rot.x1 = LV_MATH_MIN(LV_MATH_MIN(LV_MATH_MIN(lb.x, lt.x), rb.x), rt.x);
// map_area_rot.x2 = LV_MATH_MAX(LV_MATH_MAX(LV_MATH_MAX(lb.x, lt.x), rb.x), rt.x);
// map_area_rot.y1 = LV_MATH_MIN(LV_MATH_MIN(LV_MATH_MIN(lb.y, lt.y), rb.y), rt.y);
// map_area_rot.y2 = LV_MATH_MAX(LV_MATH_MAX(LV_MATH_MAX(lb.y, lt.y), rb.y), rt.y);
// }
//
// lv_area_t mask_com; /*Common area of mask and coords*/
// bool union_ok;
// union_ok = lv_area_intersect(&mask_com, mask, &map_area_rot);
// if(union_ok == false) {
// return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn
// successfully.*/
// }
//
// lv_draw_map(coords, &mask_com, cdsc->dec_dsc.img_data, opa, chroma_keyed, alpha_byte, style, angle, pivot, zoom, antialias);
// }
// /* The whole uncompressed image is not available. Try to read it line-by-line*/
// else {
// lv_area_t mask_com; /*Common area of mask and coords*/
// bool union_ok;
// union_ok = lv_area_intersect(&mask_com, mask, coords);
// if(union_ok == false) {
// return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn
// successfully.*/
// }
//
// lv_coord_t width = lv_area_get_width(&mask_com);
//
// uint8_t * buf = lv_mem_buf_get(lv_area_get_width(&mask_com) * LV_IMG_PX_SIZE_ALPHA_BYTE); /*+1 because of the possible alpha byte*/
//
// lv_area_t line;
// lv_area_copy(&line, &mask_com);
// lv_area_set_height(&line, 1);
// lv_coord_t x = mask_com.x1 - coords->x1;
// lv_coord_t y = mask_com.y1 - coords->y1;
// lv_coord_t row;
// lv_res_t read_res;
// for(row = mask_com.y1; row <= mask_com.y2; row++) {
// lv_area_t mask_line;
// union_ok = lv_area_intersect(&mask_line, mask, &line);
// if(union_ok == false) continue;
//
// read_res = lv_img_decoder_read_line(&cdsc->dec_dsc, x, y, width, buf);
// if(read_res != LV_RES_OK) {
// lv_img_decoder_close(&cdsc->dec_dsc);
// LV_LOG_WARN("Image draw can't read the line");
// lv_mem_buf_release(buf);
// return LV_RES_INV;
// }
//
//
// lv_draw_map(&line, &mask_line, buf, opa, chroma_keyed, alpha_byte, style, 0, NULL, LV_IMG_ZOOM_NONE, false);
// line.y1++;
// line.y2++;
// y++;
// }
// lv_mem_buf_release(buf);
// }
//
if(draw_dsc->opa <= LV_OPA_MIN) return LV_RES_OK;
lv_img_cache_entry_t * cdsc = lv_img_cache_open(src, draw_dsc->overlay_color);
if(cdsc == NULL) return LV_RES_INV;
bool chroma_keyed = lv_img_cf_is_chroma_keyed(cdsc->dec_dsc.header.cf);
bool alpha_byte = lv_img_cf_has_alpha(cdsc->dec_dsc.header.cf);
if(cdsc->dec_dsc.error_msg != NULL) {
LV_LOG_WARN("Image draw error");
show_error(coords, mask, cdsc->dec_dsc.error_msg);
}
/* The decoder open could open the image and gave the entire uncompressed image.
* Just draw it!*/
else if(cdsc->dec_dsc.img_data) {
lv_area_t map_area_rot;
lv_area_copy(&map_area_rot, coords);
if(draw_dsc->angle || draw_dsc->zoom != LV_IMG_ZOOM_NONE) {
/*Get the exact area which is required to show the rotated image*/
lv_coord_t pivot_x = lv_area_get_width(coords) / 2 + coords->x1;
lv_coord_t pivot_y = lv_area_get_height(coords) / 2 + coords->y1;
pivot_x = draw_dsc->pivot.x + coords->x1;
pivot_y = draw_dsc->pivot.y + coords->y1;
lv_coord_t w = lv_area_get_width(coords);
lv_coord_t w_zoom = (((w * draw_dsc->zoom) >> 8) - w) / 2;
lv_coord_t h = lv_area_get_height(coords);
lv_coord_t h_zoom = (((h * draw_dsc->zoom) >> 8) - h) / 2;
lv_area_t norm;
norm.x1 = coords->x1 - pivot_x - w_zoom;
norm.y1 = coords->y1 - pivot_y - h_zoom;
norm.x2 = coords->x2 - pivot_x + w_zoom;
norm.y2 = coords->y2 - pivot_y + h_zoom;
int16_t sinma = lv_trigo_sin(draw_dsc->angle);
int16_t cosma = lv_trigo_sin(draw_dsc->angle + 90);
lv_point_t lt;
lv_point_t rt;
lv_point_t lb;
lv_point_t rb;
lt.x = ((cosma * norm.x1 - sinma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_x;
lt.y = ((sinma * norm.x1 + cosma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_y;
rt.x = ((cosma * norm.x2 - sinma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_x;
rt.y = ((sinma * norm.x2 + cosma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_y;
lb.x = ((cosma * norm.x1 - sinma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_x;
lb.y = ((sinma * norm.x1 + cosma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_y;
rb.x = ((cosma * norm.x2 - sinma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_x;
rb.y = ((sinma * norm.x2 + cosma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_y;
map_area_rot.x1 = LV_MATH_MIN(LV_MATH_MIN(LV_MATH_MIN(lb.x, lt.x), rb.x), rt.x);
map_area_rot.x2 = LV_MATH_MAX(LV_MATH_MAX(LV_MATH_MAX(lb.x, lt.x), rb.x), rt.x);
map_area_rot.y1 = LV_MATH_MIN(LV_MATH_MIN(LV_MATH_MIN(lb.y, lt.y), rb.y), rt.y);
map_area_rot.y2 = LV_MATH_MAX(LV_MATH_MAX(LV_MATH_MAX(lb.y, lt.y), rb.y), rt.y);
}
lv_area_t mask_com; /*Common area of mask and coords*/
bool union_ok;
union_ok = lv_area_intersect(&mask_com, mask, &map_area_rot);
if(union_ok == false) {
return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn
successfully.*/
}
lv_draw_map(coords, &mask_com, cdsc->dec_dsc.img_data, draw_dsc, chroma_keyed, alpha_byte);
}
/* The whole uncompressed image is not available. Try to read it line-by-line*/
else {
lv_area_t mask_com; /*Common area of mask and coords*/
bool union_ok;
union_ok = lv_area_intersect(&mask_com, mask, coords);
if(union_ok == false) {
return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn
successfully.*/
}
lv_coord_t width = lv_area_get_width(&mask_com);
uint8_t * buf = lv_mem_buf_get(lv_area_get_width(&mask_com) * LV_IMG_PX_SIZE_ALPHA_BYTE); /*+1 because of the possible alpha byte*/
lv_area_t line;
lv_area_copy(&line, &mask_com);
lv_area_set_height(&line, 1);
lv_coord_t x = mask_com.x1 - coords->x1;
lv_coord_t y = mask_com.y1 - coords->y1;
lv_coord_t row;
lv_res_t read_res;
for(row = mask_com.y1; row <= mask_com.y2; row++) {
lv_area_t mask_line;
union_ok = lv_area_intersect(&mask_line, mask, &line);
if(union_ok == false) continue;
read_res = lv_img_decoder_read_line(&cdsc->dec_dsc, x, y, width, buf);
if(read_res != LV_RES_OK) {
lv_img_decoder_close(&cdsc->dec_dsc);
LV_LOG_WARN("Image draw can't read the line");
lv_mem_buf_release(buf);
return LV_RES_INV;
}
lv_draw_map(&line, &mask_line, buf, draw_dsc, chroma_keyed, alpha_byte);
line.y1++;
line.y2++;
y++;
}
lv_mem_buf_release(buf);
}
return LV_RES_OK;
}
@@ -329,190 +332,194 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas
* @param zoom zoom factor
* @param antialias anti-alias transformations (rotate, zoom) or not
*/
static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area, const uint8_t * map_p, lv_opa_t opa,
bool chroma_key, bool alpha_byte, const lv_style_t * style, uint16_t angle, lv_point_t * pivot, uint16_t zoom, bool antialaias)
static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area, const uint8_t * map_p, lv_draw_img_dsc_t * draw_dsc, bool chroma_key, bool alpha_byte)
{
//
// if(opa < LV_OPA_MIN) return;
// if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
//
// /* Use the clip area as draw area*/
// lv_area_t draw_area;
// lv_area_copy(&draw_area, clip_area);
//
// lv_disp_t * disp = lv_refr_get_disp_refreshing();
// lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
// const lv_area_t * disp_area = &vdb->area;
//
// /* Now `draw_area` has absolute coordinates.
// * Make it relative to `disp_area` to simplify draw to `disp_buf`*/
// draw_area.x1 -= disp_area->x1;
// draw_area.y1 -= disp_area->y1;
// draw_area.x2 -= disp_area->x1;
// draw_area.y2 -= disp_area->y1;
//
// uint8_t other_mask_cnt = lv_draw_mask_get_cnt();
//
// /*The simplest case just copy the pixels into the VDB*/
// if(other_mask_cnt == 0 && angle == 0 && zoom == LV_IMG_ZOOM_NONE &&
// chroma_key == false && alpha_byte == false &&
// opa == LV_OPA_COVER && style->image.intense == LV_OPA_TRANSP) {
// lv_blend_map(clip_area, map_area, (lv_color_t *)map_p, NULL, LV_DRAW_MASK_RES_FULL_COVER, LV_OPA_COVER, style->image.blend_mode);
// }
// /*In the other cases every pixel need to be checked one-by-one*/
// else {
// /*The pixel size in byte is different if an alpha byte is added too*/
// uint8_t px_size_byte = alpha_byte ? LV_IMG_PX_SIZE_ALPHA_BYTE : sizeof(lv_color_t);
//
// /*Build the image and a mask line-by-line*/
// uint32_t mask_buf_size = lv_area_get_size(&draw_area) > LV_HOR_RES_MAX ? LV_HOR_RES_MAX : lv_area_get_size(&draw_area);
// lv_color_t * map2 = lv_mem_buf_get(mask_buf_size * sizeof(lv_color_t));
// lv_opa_t * mask_buf = lv_mem_buf_get(mask_buf_size);
//
// /*Go to the first displayed pixel of the map*/
// lv_coord_t map_w = lv_area_get_width(map_area);
// lv_coord_t map_h = lv_area_get_height(map_area);
// const uint8_t * map_buf_tmp = map_p;
// map_buf_tmp += map_w * (draw_area.y1 - (map_area->y1 - disp_area->y1)) * px_size_byte;
// map_buf_tmp += (draw_area.x1 - (map_area->x1 - disp_area->x1)) * px_size_byte;
//
// lv_color_t c;
// lv_color_t chroma_keyed_color = LV_COLOR_TRANSP;
// uint32_t px_i = 0;
// uint32_t px_i_start;
//
// const uint8_t * map_px;
//
// lv_area_t blend_area;
// blend_area.x1 = draw_area.x1 + disp_area->x1;
// blend_area.x2 = blend_area.x1 + lv_area_get_width(&draw_area) - 1;
// blend_area.y1 = disp_area->y1 + draw_area.y1;
// blend_area.y2 = blend_area.y1;
//
// /*Prepare the `mask_buf`if there are other masks*/
// if(other_mask_cnt) {
// memset(mask_buf, 0xFF, mask_buf_size);
// }
//
//
// bool transform = angle != 0 || zoom != LV_IMG_ZOOM_NONE ? true : false;
// lv_img_transform_dsc_t trans_dsc;
// memset(&trans_dsc, 0, sizeof(lv_img_transform_dsc_t));
// if(transform) {
// lv_img_cf_t cf = LV_IMG_CF_TRUE_COLOR;
// if(alpha_byte) cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
// else if(chroma_key) cf = LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED;
//
//
// trans_dsc.cfg.angle = angle;
// trans_dsc.cfg.zoom = zoom;
// trans_dsc.cfg.src = map_p;
// trans_dsc.cfg.src_w = map_w;
// trans_dsc.cfg.src_h = map_h;
// trans_dsc.cfg.cf = cf;
// trans_dsc.cfg.pivot_x = map_w / 2;
// trans_dsc.cfg.pivot_y = map_h / 2;
// if (pivot){
// trans_dsc.cfg.pivot_x = pivot->x;
// trans_dsc.cfg.pivot_y = pivot->y;
// }
// trans_dsc.cfg.color = style->image.color;
// trans_dsc.cfg.antialias = antialaias;
//
// lv_img_buf_transform_init(&trans_dsc);
// }
//
// lv_draw_mask_res_t mask_res;
// mask_res = (alpha_byte || chroma_key || angle) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER;
// lv_coord_t x;
// lv_coord_t y;
// for(y = 0; y < lv_area_get_height(&draw_area); y++) {
// map_px = map_buf_tmp;
// px_i_start = px_i;
//
// for(x = 0; x < lv_area_get_width(&draw_area); x++, map_px += px_size_byte, px_i++) {
//
// if(transform == false) {
// if(alpha_byte) {
// lv_opa_t px_opa = map_px[LV_IMG_PX_SIZE_ALPHA_BYTE - 1];
// mask_buf[px_i] = px_opa;
// if(px_opa < LV_OPA_MIN) continue;
// } else {
// mask_buf[px_i] = LV_OPA_COVER;
// }
//
//#if LV_COLOR_DEPTH == 8
// c.full = map_px[0];
//#elif LV_COLOR_DEPTH == 16
// c.full = map_px[0] + (map_px[1] << 8);
//#elif LV_COLOR_DEPTH == 32
// c.full = *((uint32_t*)map_px);
//#endif
// if (chroma_key) {
// if(c.full == chroma_keyed_color.full) {
// mask_buf[px_i] = LV_OPA_TRANSP;
// continue;
// }
// }
// } else {
// /*Rotate*/
// bool ret;
// lv_coord_t rot_x = x + (disp_area->x1 + draw_area.x1) - map_area->x1;
// lv_coord_t rot_y = y + (disp_area->y1 + draw_area.y1) - map_area->y1;
// ret = lv_img_buf_transform(&trans_dsc, rot_x, rot_y);
// if(ret == false) {
// mask_buf[px_i] = LV_OPA_TRANSP;
// continue;
// } else {
// mask_buf[px_i] = trans_dsc.res.opa;
// c.full = trans_dsc.res.color.full;
// }
// }
//
// if(style->image.intense != 0) {
// c = lv_color_mix(style->image.color, c, style->image.intense);
// }
//
// map2[px_i].full = c.full;
// }
//
// /*Apply the masks if any*/
// if(other_mask_cnt) {
// lv_draw_mask_res_t mask_res_sub;
// mask_res_sub = lv_draw_mask_apply(mask_buf + px_i_start, draw_area.x1 + vdb->area.x1, y + draw_area.y1 + vdb->area.y1, lv_area_get_width(&draw_area));
// if(mask_res_sub == LV_DRAW_MASK_RES_FULL_TRANSP) {
// memset(mask_buf + px_i_start, 0x00, lv_area_get_width(&draw_area));
// mask_res = LV_DRAW_MASK_RES_CHANGED;
// } else if(mask_res_sub == LV_DRAW_MASK_RES_CHANGED) {
// mask_res = LV_DRAW_MASK_RES_CHANGED;
// }
// }
//
// map_buf_tmp += map_w * px_size_byte;
// if(px_i + lv_area_get_width(&draw_area) < mask_buf_size) {
// blend_area.y2 ++;
// } else {
// lv_blend_map(clip_area, &blend_area, map2, mask_buf, mask_res, opa, style->image.blend_mode);
//
// blend_area.y1 = blend_area.y2 + 1;
// blend_area.y2 = blend_area.y1;
//
// px_i = 0;
// mask_res = (alpha_byte || chroma_key || angle) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER;
//
// /*Prepare the `mask_buf`if there are other masks*/
// if(other_mask_cnt) {
// memset(mask_buf, 0xFF, mask_buf_size);
// }
// }
// }
// /*Flush the last part*/
// if(blend_area.y1 != blend_area.y2) {
// blend_area.y2--;
// lv_blend_map(clip_area, &blend_area, map2, mask_buf, mask_res, opa, style->image.blend_mode);
// }
//
// lv_mem_buf_release(mask_buf);
// lv_mem_buf_release(map2);
// }
/* Use the clip area as draw area*/
lv_area_t draw_area;
lv_area_copy(&draw_area, clip_area);
lv_disp_t * disp = lv_refr_get_disp_refreshing();
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
const lv_area_t * disp_area = &vdb->area;
/* Now `draw_area` has absolute coordinates.
* Make it relative to `disp_area` to simplify draw to `disp_buf`*/
draw_area.x1 -= disp_area->x1;
draw_area.y1 -= disp_area->y1;
draw_area.x2 -= disp_area->x1;
draw_area.y2 -= disp_area->y1;
uint8_t other_mask_cnt = lv_draw_mask_get_cnt();
/*The simplest case just copy the pixels into the VDB*/
if(other_mask_cnt == 0 && draw_dsc->angle == 0 && draw_dsc->zoom == LV_IMG_ZOOM_NONE &&
chroma_key == false && alpha_byte == false &&
draw_dsc->opa == LV_OPA_COVER && draw_dsc->overlay_opa == LV_OPA_TRANSP) {
lv_blend_map(clip_area, map_area, (lv_color_t *)map_p, NULL, LV_DRAW_MASK_RES_FULL_COVER, LV_OPA_COVER, draw_dsc->blend_mode);
}
/*In the other cases every pixel need to be checked one-by-one*/
else {
/*The pixel size in byte is different if an alpha byte is added too*/
uint8_t px_size_byte = alpha_byte ? LV_IMG_PX_SIZE_ALPHA_BYTE : sizeof(lv_color_t);
/*Build the image and a mask line-by-line*/
uint32_t mask_buf_size = lv_area_get_size(&draw_area) > LV_HOR_RES_MAX ? LV_HOR_RES_MAX : lv_area_get_size(&draw_area);
lv_color_t * map2 = lv_mem_buf_get(mask_buf_size * sizeof(lv_color_t));
lv_opa_t * mask_buf = lv_mem_buf_get(mask_buf_size);
/*Go to the first displayed pixel of the map*/
lv_coord_t map_w = lv_area_get_width(map_area);
lv_coord_t map_h = lv_area_get_height(map_area);
const uint8_t * map_buf_tmp = map_p;
map_buf_tmp += map_w * (draw_area.y1 - (map_area->y1 - disp_area->y1)) * px_size_byte;
map_buf_tmp += (draw_area.x1 - (map_area->x1 - disp_area->x1)) * px_size_byte;
lv_color_t c;
lv_color_t chroma_keyed_color = LV_COLOR_TRANSP;
uint32_t px_i = 0;
uint32_t px_i_start;
const uint8_t * map_px;
lv_area_t blend_area;
blend_area.x1 = draw_area.x1 + disp_area->x1;
blend_area.x2 = blend_area.x1 + lv_area_get_width(&draw_area) - 1;
blend_area.y1 = disp_area->y1 + draw_area.y1;
blend_area.y2 = blend_area.y1;
/*Prepare the `mask_buf`if there are other masks*/
if(other_mask_cnt) {
memset(mask_buf, 0xFF, mask_buf_size);
}
bool transform = draw_dsc->angle != 0 || draw_dsc->zoom != LV_IMG_ZOOM_NONE ? true : false;
lv_img_transform_dsc_t trans_dsc;
memset(&trans_dsc, 0, sizeof(lv_img_transform_dsc_t));
if(transform) {
lv_img_cf_t cf = LV_IMG_CF_TRUE_COLOR;
if(alpha_byte) cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
else if(chroma_key) cf = LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED;
trans_dsc.cfg.angle = draw_dsc->angle;
trans_dsc.cfg.zoom = draw_dsc->zoom;
trans_dsc.cfg.src = map_p;
trans_dsc.cfg.src_w = map_w;
trans_dsc.cfg.src_h = map_h;
trans_dsc.cfg.cf = cf;
trans_dsc.cfg.pivot_x = draw_dsc->pivot.x;
trans_dsc.cfg.pivot_y = draw_dsc->pivot.y;
trans_dsc.cfg.color = draw_dsc->overlay_color;
trans_dsc.cfg.antialias = draw_dsc->antialias;
lv_img_buf_transform_init(&trans_dsc);
}
lv_draw_mask_res_t mask_res;
mask_res = (alpha_byte || chroma_key || draw_dsc->angle) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER;
lv_coord_t x;
lv_coord_t y;
for(y = 0; y < lv_area_get_height(&draw_area); y++) {
map_px = map_buf_tmp;
px_i_start = px_i;
for(x = 0; x < lv_area_get_width(&draw_area); x++, map_px += px_size_byte, px_i++) {
if(transform == false) {
if(alpha_byte) {
lv_opa_t px_opa = map_px[LV_IMG_PX_SIZE_ALPHA_BYTE - 1];
mask_buf[px_i] = px_opa;
if(px_opa < LV_OPA_MIN) continue;
} else {
mask_buf[px_i] = LV_OPA_COVER;
}
#if LV_COLOR_DEPTH == 8
c.full = map_px[0];
#elif LV_COLOR_DEPTH == 16
c.full = map_px[0] + (map_px[1] << 8);
#elif LV_COLOR_DEPTH == 32
c.full = *((uint32_t*)map_px);
#endif
if (chroma_key) {
if(c.full == chroma_keyed_color.full) {
mask_buf[px_i] = LV_OPA_TRANSP;
continue;
}
}
} else {
/*Rotate*/
bool ret;
lv_coord_t rot_x = x + (disp_area->x1 + draw_area.x1) - map_area->x1;
lv_coord_t rot_y = y + (disp_area->y1 + draw_area.y1) - map_area->y1;
ret = lv_img_buf_transform(&trans_dsc, rot_x, rot_y);
if(ret == false) {
mask_buf[px_i] = LV_OPA_TRANSP;
continue;
} else {
mask_buf[px_i] = trans_dsc.res.opa;
c.full = trans_dsc.res.color.full;
}
}
if(draw_dsc->overlay_opa != 0) {
c = lv_color_mix(draw_dsc->overlay_color, c, draw_dsc->overlay_opa);
}
map2[px_i].full = c.full;
}
/*Apply the masks if any*/
if(other_mask_cnt) {
lv_draw_mask_res_t mask_res_sub;
mask_res_sub = lv_draw_mask_apply(mask_buf + px_i_start, draw_area.x1 + vdb->area.x1, y + draw_area.y1 + vdb->area.y1, lv_area_get_width(&draw_area));
if(mask_res_sub == LV_DRAW_MASK_RES_FULL_TRANSP) {
memset(mask_buf + px_i_start, 0x00, lv_area_get_width(&draw_area));
mask_res = LV_DRAW_MASK_RES_CHANGED;
} else if(mask_res_sub == LV_DRAW_MASK_RES_CHANGED) {
mask_res = LV_DRAW_MASK_RES_CHANGED;
}
}
map_buf_tmp += map_w * px_size_byte;
if(px_i + lv_area_get_width(&draw_area) < mask_buf_size) {
blend_area.y2 ++;
} else {
lv_blend_map(clip_area, &blend_area, map2, mask_buf, mask_res, draw_dsc->opa, draw_dsc->blend_mode);
blend_area.y1 = blend_area.y2 + 1;
blend_area.y2 = blend_area.y1;
px_i = 0;
mask_res = (alpha_byte || chroma_key || draw_dsc->angle) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER;
/*Prepare the `mask_buf`if there are other masks*/
if(other_mask_cnt) {
memset(mask_buf, 0xFF, mask_buf_size);
}
}
}
/*Flush the last part*/
if(blend_area.y1 != blend_area.y2) {
blend_area.y2--;
lv_blend_map(clip_area, &blend_area, map2, mask_buf, mask_res, draw_dsc->opa, draw_dsc->blend_mode);
}
lv_mem_buf_release(mask_buf);
lv_mem_buf_release(map2);
}
}
void show_error(const lv_area_t * coords, const lv_area_t * clip_area, const char * msg)
{
lv_draw_rect_dsc_t rect_dsc;
lv_draw_rect_dsc_init(&rect_dsc);
rect_dsc.bg_color = LV_COLOR_WHITE;
lv_draw_rect(coords, clip_area, &rect_dsc);
lv_draw_label_dsc_t label_dsc;
lv_draw_label_dsc_init(&label_dsc);
lv_draw_label(coords, clip_area, &label_dsc, msg, NULL);
}

View File

@@ -29,11 +29,26 @@ extern "C" {
* TYPEDEFS
**********************/
typedef struct {
lv_opa_t opa;
uint16_t angle;
lv_point_t pivot;
uint16_t zoom;
lv_opa_t overlay_opa;
lv_color_t overlay_color;
lv_blend_mode_t blend_mode;
uint8_t antialias :1;
} lv_draw_img_dsc_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_draw_img_dsc_init(lv_draw_img_dsc_t * dsc);
/**
* Draw an image
* @param coords the coordinates of the image
@@ -45,8 +60,7 @@ extern "C" {
* @param antialias anti-alias transformations (rotate, zoom) or not
* @param opa_scale scale down all opacities by the factor
*/
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_style_t * style,
uint16_t angle, lv_point_t * center, uint16_t zoom, bool antialaias, lv_opa_t opa_scale);
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, lv_draw_img_dsc_t * dsc);
/**
* Get the type of an image source

View File

@@ -52,11 +52,10 @@ typedef uint8_t lv_indev_state_t;
enum {
LV_DRAG_DIR_NONE = 0x0, /**< Both directions are disabled */
LV_DRAG_DIR_HOR = 0x1, /**< Object can be dragged horizontally. */
LV_DRAG_DIR_VER = 0x2, /**< Object can be dragged vertically. */
LV_DRAG_DIR_BOTH = 0x3, /**< Object can be dragged in all directions. */
LV_DRAG_DIR_ONE = 0x4, /**< Object can be dragged only one direction (the first move). */
LV_DRAG_DIR_HOR = 0x0, /**< Object can be dragged horizontally. */
LV_DRAG_DIR_VER = 0x1, /**< Object can be dragged vertically. */
LV_DRAG_DIR_BOTH = 0x2, /**< Object can be dragged in all directions. */
LV_DRAG_DIR_ONE = 0x3, /**< Object can be dragged only one direction (the first move). */
};
typedef uint8_t lv_drag_dir_t;

View File

@@ -34,11 +34,10 @@
**********************/
static lv_design_res_t lv_bar_design(lv_obj_t * bar, const lv_area_t * clip_area, lv_design_mode_t mode);
static lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param);
static lv_style_dsc_t * lv_bar_get_style(lv_obj_t * bar, uint8_t part);
static void draw_bg(lv_obj_t * bar, const lv_area_t * clip_area, lv_design_mode_t mode, lv_opa_t opa);
static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area, lv_design_mode_t mode, lv_opa_t opa);
static void draw_bg(lv_obj_t * bar, const lv_area_t * clip_area);
static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area);
#if LV_USE_ANIMATION
static void lv_bar_set_value_with_anim(lv_obj_t * bar, int16_t new_value, int16_t *value_ptr, lv_bar_anim_t *anim_info, lv_anim_enable_t en);
@@ -97,24 +96,21 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy)
lv_bar_init_anim(new_bar, &ext->start_value_anim);
#endif
ext->type = LV_BAR_TYPE_NORMAL;
ext->style_indic = &lv_style_pretty_color;
lv_style_dsc_init(&ext->style_indic);
lv_obj_set_signal_cb(new_bar, lv_bar_signal);
lv_obj_set_design_cb(new_bar, lv_bar_design);
/*Init the new bar object*/
if(copy == NULL) {
lv_obj_set_click(new_bar, false);
lv_obj_set_size(new_bar, LV_DPI * 2, LV_DPI / 4);
lv_bar_set_value(new_bar, ext->cur_value, false);
lv_theme_t * th = lv_theme_get_current();
if(th) {
lv_bar_set_style(new_bar, LV_BAR_STYLE_BG, th->style.bar.bg);
lv_bar_set_style(new_bar, LV_BAR_STYLE_INDIC, th->style.bar.indic);
} else {
lv_obj_set_style(new_bar, &lv_style_pretty);
}
_ot(new_bar, LV_BAR_PART_BG, BAR);
_ot(new_bar, LV_BAR_PART_INDIC, BAR_INDIC);
} else {
lv_bar_ext_t * ext_copy = lv_obj_get_ext_attr(copy);
ext->min_value = ext_copy->min_value;
@@ -124,7 +120,7 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy)
ext->style_indic = ext_copy->style_indic;
ext->type = ext_copy->type;
/*Refresh the style with new signal function*/
lv_obj_refresh_style(new_bar);
lv_obj_refresh_style(new_bar, LV_OBJ_PART_ALL);
lv_bar_set_value(new_bar, ext->cur_value, false);
}
@@ -254,27 +250,6 @@ void lv_bar_set_anim_time(lv_obj_t * bar, uint16_t anim_time)
#endif
}
/**
* Set a style of a bar
* @param bar pointer to a bar object
* @param type which style should be set
* @param style pointer to a style
*/
void lv_bar_set_style(lv_obj_t * bar, lv_bar_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(bar, LV_OBJX_NAME);
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
switch(type) {
case LV_BAR_STYLE_BG: lv_obj_set_style(bar, style); break;
case LV_BAR_STYLE_INDIC:
ext->style_indic = style;
lv_obj_refresh_ext_draw_pad(bar);
break;
}
}
/*=====================
* Getter functions
*====================*/
@@ -374,27 +349,6 @@ uint16_t lv_bar_get_anim_time(const lv_obj_t * bar)
#endif
}
/**
* Get a style of a bar
* @param bar pointer to a bar object
* @param type which style should be get
* @return style pointer to a style
*/
const lv_style_t * lv_bar_get_style(const lv_obj_t * bar, lv_bar_style_t type)
{
LV_ASSERT_OBJ(bar, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
switch(type) {
case LV_BAR_STYLE_BG: style = lv_obj_get_style(bar); break;
case LV_BAR_STYLE_INDIC: style = ext->style_indic; break;
default: style = NULL; break;
}
return style;
}
/**********************
* STATIC FUNCTIONS
@@ -416,22 +370,8 @@ static lv_design_res_t lv_bar_design(lv_obj_t * bar, const lv_area_t * clip_area
/*Return false if the object is not covers the mask area*/
return ancestor_design_f(bar, clip_area, mode);
} else if(mode == LV_DESIGN_DRAW_MAIN) {
lv_opa_t opa_scale = lv_obj_get_opa_scale(bar);
draw_bg(bar, clip_area, mode, opa_scale);
draw_indic(bar, clip_area, mode, opa_scale);
#if LV_USE_GROUP
/*Draw the border*/
if(lv_obj_is_focused(bar)) {
const lv_style_t * style_bg = lv_bar_get_style(bar, LV_BAR_STYLE_BG);
lv_style_t style_tmp;
lv_style_copy(&style_tmp, style_bg);
style_tmp.body.opa = LV_OPA_TRANSP;
style_tmp.body.shadow.width = 0;
lv_draw_rect(&bar->coords, clip_area, &style_tmp, opa_scale);
}
#endif
draw_bg(bar, clip_area);
draw_indic(bar, clip_area);
} else if(mode == LV_DESIGN_DRAW_POST) {
@@ -439,32 +379,18 @@ static lv_design_res_t lv_bar_design(lv_obj_t * bar, const lv_area_t * clip_area
return LV_DESIGN_RES_OK;
}
static void draw_bg(lv_obj_t * bar, const lv_area_t * clip_area, lv_design_mode_t mode, lv_opa_t opa)
static void draw_bg(lv_obj_t * bar, const lv_area_t * clip_area)
{
/*Simply draw the background*/
lv_draw_rect_dsc_t draw_dsc;
lv_draw_rect_dsc_init(&draw_dsc);
lv_obj_init_draw_rect_dsc(bar, LV_BAR_PART_BG, &draw_dsc);
lv_draw_rect(&bar->coords, clip_area, &draw_dsc);
const lv_style_t * style_bg = lv_bar_get_style(bar, LV_BAR_STYLE_BG);
#if LV_USE_GROUP == 0
/*Simply draw the background*/
lv_draw_rect(&bar->coords, clip_area, style_bg, opa);
#else
/* Draw the borders later if the bar is focused.
* At value = 100% the indicator can cover to whole background and the focused style won't
* be visible*/
if(lv_obj_is_focused(bar)) {
lv_style_t style_tmp;
lv_style_copy(&style_tmp, style_bg);
style_tmp.body.border.width = 0;
lv_draw_rect(&bar->coords, clip_area, &style_tmp, opa);
} else {
lv_draw_rect(&bar->coords, clip_area, style_bg, opa);
}
#endif
}
static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area, lv_design_mode_t mode, lv_opa_t opa)
static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area)
{
(void) mode; /*Unused*/
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
lv_coord_t objw = lv_obj_get_width(bar);
@@ -484,15 +410,17 @@ static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area, lv_design_mo
#endif
/*Calculate the indicator area*/
lv_area_copy(&ext->indic_area, &bar->coords);
const lv_style_t * style_indic = lv_bar_get_style(bar, LV_BAR_STYLE_INDIC);
const lv_style_t * style_bg = lv_bar_get_style(bar, LV_BAR_STYLE_BG);
lv_style_value_t bg_left = lv_obj_get_style_value(bar, LV_BAR_PART_BG, LV_STYLE_PAD_LEFT);
lv_style_value_t bg_right = lv_obj_get_style_value(bar, LV_BAR_PART_BG, LV_STYLE_PAD_RIGHT);
lv_style_value_t bg_top = lv_obj_get_style_value(bar, LV_BAR_PART_BG, LV_STYLE_PAD_TOP);
lv_style_value_t bg_bottom = lv_obj_get_style_value(bar, LV_BAR_PART_BG, LV_STYLE_PAD_BOTTOM);
/*Respect padding and minimum width/height too*/
ext->indic_area.x1 += style_indic->body.padding.left;
ext->indic_area.x2 -= style_indic->body.padding.right;
ext->indic_area.y1 += style_indic->body.padding.top;
ext->indic_area.y2 -= style_indic->body.padding.bottom;
lv_area_copy(&ext->indic_area, &bar->coords);
ext->indic_area.x1 += bg_left;
ext->indic_area.x2 -= bg_right;
ext->indic_area.y1 += bg_top;
ext->indic_area.y2 -= bg_bottom;
if(hor && lv_area_get_height(&ext->indic_area) < LV_BAR_SIZE_MIN) {
ext->indic_area.y1 = bar->coords.y1 + (objh / 2) - (LV_BAR_SIZE_MIN / 2);
@@ -570,46 +498,59 @@ static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area, lv_design_mo
/*Do not draw a zero length indicator*/
if(!sym && indic_length == 0) return;
lv_style_t style_indic_tmp;
lv_style_copy(&style_indic_tmp, style_indic);
uint16_t bg_radius = style_bg->body.radius;
uint16_t bg_radius = lv_obj_get_style_value(bar, LV_BAR_PART_BG, LV_STYLE_RADIUS);
lv_coord_t short_side = LV_MATH_MIN(objw, objh);
if(bg_radius > short_side >> 1) bg_radius = short_side >> 1;
/*Draw only the shadow*/
lv_draw_rect_dsc_t draw_indic_dsc;
lv_draw_rect_dsc_init(&draw_indic_dsc);
lv_obj_init_draw_rect_dsc(bar, LV_BAR_PART_INDIC, &draw_indic_dsc);
/* Draw only the shadow if the indicator is long enough.
* The radius of the bg and the indicator can make a strange shape where
* it'd be very difficult to draw shadow. */
if((hor && lv_area_get_width(&ext->indic_area) > bg_radius * 2) ||
(!hor && lv_area_get_height(&ext->indic_area) > bg_radius * 2)) {
style_indic_tmp.body.opa = LV_OPA_TRANSP;
style_indic_tmp.body.border.width = 0;
lv_draw_rect(&ext->indic_area, clip_area, &style_indic_tmp, opa);
lv_opa_t bg_opa = draw_indic_dsc.bg_opa;
lv_opa_t border_opa = draw_indic_dsc.border_opa;
draw_indic_dsc.bg_opa = LV_OPA_TRANSP;
draw_indic_dsc.border_opa = LV_OPA_TRANSP;
lv_draw_rect(&ext->indic_area, clip_area, &draw_indic_dsc);
draw_indic_dsc.bg_opa = bg_opa;
draw_indic_dsc.border_opa = border_opa;
}
lv_draw_mask_radius_param_t mask_bg_param;
lv_draw_mask_radius_init(&mask_bg_param, &bar->coords, style_bg->body.radius, false);
lv_draw_mask_radius_init(&mask_bg_param, &bar->coords, bg_radius, false);
int16_t mask_bg_id = lv_draw_mask_add(&mask_bg_param, NULL);
/*Draw_only the background*/
style_indic_tmp.body.shadow.width = 0;
style_indic_tmp.body.opa = style_indic->body.opa;
lv_opa_t shadow_opa = draw_indic_dsc.shadow_opa;
lv_opa_t border_opa = draw_indic_dsc.border_opa;
draw_indic_dsc.border_opa = LV_OPA_TRANSP;
draw_indic_dsc.shadow_opa = LV_OPA_TRANSP;
/*Get the max possible indicator area. The gradient should be applied on this*/
lv_area_t mask_indic_max_area;
lv_area_copy(&mask_indic_max_area, &bar->coords);
mask_indic_max_area.x1 += style_indic->body.padding.left;
mask_indic_max_area.y1 += style_indic->body.padding.top;
mask_indic_max_area.x2 -= style_indic->body.padding.right;
mask_indic_max_area.y2 -= style_indic->body.padding.bottom;
mask_indic_max_area.x1 += bg_left;
mask_indic_max_area.y1 += bg_top;
mask_indic_max_area.x2 -= bg_right;
mask_indic_max_area.y2 -= bg_bottom;
/*Create a mask to the current indicator area to see only this part from the whole gradient.*/
lv_draw_mask_radius_param_t mask_indic_param;
lv_draw_mask_radius_init(&mask_indic_param, &ext->indic_area, style_indic->body.radius, false);
lv_draw_mask_radius_init(&mask_indic_param, &ext->indic_area, draw_indic_dsc.radius, false);
int16_t mask_indic_id = lv_draw_mask_add(&mask_indic_param, NULL);
lv_draw_rect(&mask_indic_max_area, clip_area, &style_indic_tmp, opa);
lv_draw_rect(&mask_indic_max_area, clip_area, &draw_indic_dsc);
draw_indic_dsc.border_opa = border_opa;
draw_indic_dsc.shadow_opa = shadow_opa;
/*Draw the border*/
style_indic_tmp.body.border.width = style_indic->body.border.width;
style_indic_tmp.body.opa = LV_OPA_TRANSP;
lv_draw_rect(&ext->indic_area, clip_area, &style_indic_tmp, opa);
draw_indic_dsc.bg_opa = LV_OPA_TRANSP;
draw_indic_dsc.shadow_opa = LV_OPA_TRANSP;
lv_draw_rect(&ext->indic_area, clip_area, &draw_indic_dsc);
lv_draw_mask_remove_id(mask_indic_id);
lv_draw_mask_remove_id(mask_bg_id);
@@ -627,25 +568,40 @@ static lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param)
{
lv_res_t res;
if(sign == LV_SIGNAL_GET_STYLE) {
uint8_t ** type_p = param;
lv_style_dsc_t ** style_dsc_p = param;
*style_dsc_p = lv_bar_get_style(bar, **type_p);
return LV_RES_OK;
}
/* Include the ancient signal function */
res = ancestor_signal(bar, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
const lv_style_t * style_indic = lv_bar_get_style(bar, LV_BAR_STYLE_INDIC);
const lv_style_t * style_bg = lv_bar_get_style(bar, LV_BAR_STYLE_BG);
lv_style_value_t bg_sh_width = lv_obj_get_style_value(bar, LV_BAR_PART_BG, LV_STYLE_SHADOW_WIDTH);
lv_style_value_t bg_sh_spread = lv_obj_get_style_value(bar, LV_BAR_PART_BG, LV_STYLE_SHADOW_SPREAD);
lv_style_value_t bg_sh_ofs_x = lv_obj_get_style_value(bar, LV_BAR_PART_BG, LV_STYLE_SHADOW_OFFSET_X);
lv_style_value_t bg_sh_ofs_y = lv_obj_get_style_value(bar, LV_BAR_PART_BG, LV_STYLE_SHADOW_OFFSET_Y);
lv_coord_t bg_size = style_bg->body.shadow.width + style_bg->body.shadow.spread;
bg_size += LV_MATH_MAX(LV_MATH_ABS(style_bg->body.shadow.offset.x), LV_MATH_ABS(style_bg->body.shadow.offset.y));
lv_coord_t bg_size = bg_sh_width + bg_sh_spread;
bg_size += LV_MATH_MAX(LV_MATH_ABS(bg_sh_ofs_x), LV_MATH_ABS(bg_sh_ofs_y));
lv_coord_t indic_size = style_indic->body.shadow.width + style_indic->body.shadow.spread;
indic_size += LV_MATH_MAX(LV_MATH_ABS(style_indic->body.shadow.offset.x), LV_MATH_ABS(style_indic->body.shadow.offset.y));
lv_style_value_t indic_sh_width = lv_obj_get_style_value(bar, LV_BAR_PART_INDIC, LV_STYLE_SHADOW_WIDTH);
lv_style_value_t indic_sh_spread = lv_obj_get_style_value(bar, LV_BAR_PART_INDIC, LV_STYLE_SHADOW_SPREAD);
lv_style_value_t indic_sh_ofs_x = lv_obj_get_style_value(bar, LV_BAR_PART_INDIC, LV_STYLE_SHADOW_OFFSET_X);
lv_style_value_t indic_sh_ofs_y = lv_obj_get_style_value(bar, LV_BAR_PART_INDIC, LV_STYLE_SHADOW_OFFSET_Y);
lv_coord_t indic_size = indic_sh_width + indic_sh_spread;
indic_size += LV_MATH_MAX(LV_MATH_ABS(indic_sh_ofs_x), LV_MATH_ABS(indic_sh_ofs_y));
bar->ext_draw_pad = LV_MATH_MAX(bar->ext_draw_pad, bg_size);
bar->ext_draw_pad = LV_MATH_MAX(bar->ext_draw_pad, indic_size);
if(style_indic->body.shadow.width > bar->ext_draw_pad) bar->ext_draw_pad = style_indic->body.shadow.width;
}
if(sign == LV_SIGNAL_CLEANUP) {
@@ -659,6 +615,27 @@ static lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param)
return res;
}
static lv_style_dsc_t * lv_bar_get_style(lv_obj_t * bar, uint8_t part)
{
LV_ASSERT_OBJ(bar, LV_OBJX_NAME);
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
lv_style_dsc_t * style_dsc_p;
switch(part) {
case LV_BAR_PART_BG:
style_dsc_p = &bar->style_dsc;
break;
case LV_BAR_PART_INDIC:
style_dsc_p = &ext->style_indic;
break;
default:
style_dsc_p = NULL;
}
return style_dsc_p;
}
#if LV_USE_ANIMATION
static void lv_bar_anim(lv_bar_anim_t * var, lv_anim_value_t value)
{

View File

@@ -65,15 +65,15 @@ typedef struct
lv_bar_anim_t start_value_anim;
#endif
uint8_t type : 2; /*Type of bar*/
const lv_style_t * style_indic; /*Style of the indicator*/
lv_style_dsc_t style_indic; /*Style of the indicator*/
} lv_bar_ext_t;
/** Bar styles. */
/** Bar parts */
enum {
LV_BAR_STYLE_BG, /** Bar background style. */
LV_BAR_STYLE_INDIC, /** Bar fill area style. */
LV_BAR_PART_BG, /** Bar background style. */
LV_BAR_PART_INDIC, /** Bar fill area style. */
};
typedef uint8_t lv_bar_style_t;
typedef uint8_t lv_bar_part_t;
/**********************
* GLOBAL PROTOTYPES
@@ -129,14 +129,6 @@ void lv_bar_set_type(lv_obj_t * bar, lv_bar_type_t type);
*/
void lv_bar_set_anim_time(lv_obj_t * bar, uint16_t anim_time);
/**
* Set a style of a bar
* @param bar pointer to a bar object
* @param type which style should be set
* @param style pointer to a style
*/
void lv_bar_set_style(lv_obj_t * bar, lv_bar_style_t type, const lv_style_t * style);
/*=====================
* Getter functions
*====================*/
@@ -183,14 +175,6 @@ lv_bar_type_t lv_bar_get_type(lv_obj_t * bar);
*/
uint16_t lv_bar_get_anim_time(const lv_obj_t * bar);
/**
* Get a style of a bar
* @param bar pointer to a bar object
* @param type which style should be get
* @return style pointer to a style
*/
const lv_style_t * lv_bar_get_style(const lv_obj_t * bar, lv_bar_style_t type);
/**********************
* MACROS
**********************/

View File

@@ -30,7 +30,7 @@
**********************/
static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param);
static lv_design_res_t lv_btnm_design(lv_obj_t * btnm, const lv_area_t * clip_area, lv_design_mode_t mode);
static lv_style_dsc_t * lv_btnm_get_style(lv_obj_t * btnm, uint8_t type);
static lv_style_dsc_t * lv_btnm_get_style(lv_obj_t * btnm, uint8_t part);
static uint8_t get_button_width(lv_btnm_ctrl_t ctrl_bits);
static bool button_is_hidden(lv_btnm_ctrl_t ctrl_bits);
@@ -953,7 +953,7 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
return res;
}
static lv_style_dsc_t * lv_btnm_get_style(lv_obj_t * btnm, uint8_t type)
static lv_style_dsc_t * lv_btnm_get_style(lv_obj_t * btnm, uint8_t part)
{
LV_ASSERT_OBJ(btnm, LV_OBJX_NAME);
@@ -961,7 +961,7 @@ static lv_style_dsc_t * lv_btnm_get_style(lv_obj_t * btnm, uint8_t type)
lv_style_dsc_t * style_dsc_p;
switch(type) {
switch(part) {
case LV_BTNM_PART_MAIN:
style_dsc_p = &btnm->style_dsc;
break;

View File

@@ -372,36 +372,6 @@ lv_coord_t lv_page_get_fit_height(lv_obj_t * page)
return lv_obj_get_height(page) - bg_top - bg_bottom - scrl_top - scrl_bottom;
}
static lv_style_dsc_t * lv_page_get_style(lv_obj_t * page, uint8_t type)
{
LV_ASSERT_OBJ(page, LV_OBJX_NAME);
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
lv_style_dsc_t * style_dsc_p;
switch(type) {
case LV_PAGE_PART_BG:
style_dsc_p = &page->style_dsc;
break;
case LV_PAGE_PART_SCRL:
style_dsc_p = lv_obj_get_style(ext->scrl, LV_CONT_PART_MAIN);
break;
case LV_PAGE_PART_SCRL_BAR:
style_dsc_p = &ext->sb.style;
break;
#if LV_USE_ANIMATION
case LV_PAGE_STYLE_EDGE_FLASH:
style_dsc_p = &ext->edge_flash.style;
break;
#endif
default:
style_dsc_p = NULL;
}
return style_dsc_p;
}
/*=====================
* Other functions
*====================*/
@@ -757,20 +727,21 @@ static lv_design_res_t lv_page_design(lv_obj_t * page, const lv_area_t * clip_ar
if(ext->edge_flash.left_ip || ext->edge_flash.right_ip || ext->edge_flash.top_ip ||
ext->edge_flash.bottom_ip) {
lv_style_t flash_style;
lv_style_copy(&flash_style, ext->edge_flash.style);
flash_style.body.radius = LV_RADIUS_CIRCLE;
uint32_t opa = (flash_style.body.opa * ext->edge_flash.state) / LV_PAGE_END_FLASH_SIZE;
flash_style.body.opa = opa;
lv_draw_rect(&flash_area, clip_area, &flash_style, lv_obj_get_opa_scale(page));
lv_draw_rect_dsc_t edge_draw_dsc;
lv_draw_rect_dsc_init(&edge_draw_dsc);
lv_obj_init_draw_rect_dsc(page, LV_PAGE_PART_EDGE_FLASH, &edge_draw_dsc);
edge_draw_dsc.radius = LV_RADIUS_CIRCLE;
uint32_t opa = (edge_draw_dsc.bg_opa * ext->edge_flash.state) / LV_PAGE_END_FLASH_SIZE;
edge_draw_dsc.bg_opa = opa;
lv_draw_rect(&flash_area, clip_area, &edge_draw_dsc);
}
}
if(style->body.corner_mask) {
#endif
if(lv_obj_get_style_value(page, LV_PAGE_PART_BG, LV_STYLE_BG_CLIP_CORNER)) {
void * param = lv_draw_mask_remove_custom(page + 8);
lv_mem_buf_release(param);
}
#endif
}
return LV_DESIGN_RES_OK;
@@ -1093,6 +1064,37 @@ static void scrl_def_event_cb(lv_obj_t * scrl, lv_event_t event)
/*clang-format on*/
}
static lv_style_dsc_t * lv_page_get_style(lv_obj_t * page, uint8_t type)
{
LV_ASSERT_OBJ(page, LV_OBJX_NAME);
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
lv_style_dsc_t * style_dsc_p;
switch(type) {
case LV_PAGE_PART_BG:
style_dsc_p = &page->style_dsc;
break;
case LV_PAGE_PART_SCRL:
style_dsc_p = lv_obj_get_style(ext->scrl, LV_CONT_PART_MAIN);
break;
case LV_PAGE_PART_SCRL_BAR:
style_dsc_p = &ext->sb.style;
break;
#if LV_USE_ANIMATION
case LV_PAGE_PART_EDGE_FLASH:
style_dsc_p = &ext->edge_flash.style;
break;
#endif
default:
style_dsc_p = NULL;
}
return style_dsc_p;
}
/**
* Refresh the position and size of the scroll bars.
* @param page pointer to a page object

View File

@@ -32,6 +32,7 @@
**********************/
static lv_design_res_t lv_slider_design(lv_obj_t * slider, const lv_area_t * clip_area, lv_design_mode_t mode);
static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param);
static lv_style_dsc_t * lv_slider_get_style(lv_obj_t * slider, uint8_t part);
static void lv_slider_position_knob(lv_obj_t * slider, lv_area_t * knob_area, lv_coord_t knob_size, bool hor);
static void lv_slider_draw_knob(lv_obj_t * slider, const lv_area_t * knob_area, const lv_area_t * clip_area);
@@ -76,7 +77,7 @@ lv_obj_t * lv_slider_create(lv_obj_t * par, const lv_obj_t * copy)
}
/*Initialize the allocated 'ext' */
ext->style_knob = &lv_style_pretty;
lv_style_dsc_init(&ext->style_knob);
ext->value_to_set = NULL;
ext->dragging = false;
ext->img_knob = NULL;
@@ -90,22 +91,11 @@ lv_obj_t * lv_slider_create(lv_obj_t * par, const lv_obj_t * copy)
lv_obj_set_click(new_slider, true);
lv_obj_set_protect(new_slider, LV_PROTECT_PRESS_LOST);
/*Set the default styles*/
lv_theme_t * th = lv_theme_get_current();
if(th) {
lv_slider_set_style(new_slider, LV_SLIDER_STYLE_BG, th->style.slider.bg);
lv_slider_set_style(new_slider, LV_SLIDER_STYLE_INDIC, th->style.slider.indic);
lv_slider_set_style(new_slider, LV_SLIDER_STYLE_KNOB, th->style.slider.knob);
} else {
lv_slider_set_style(new_slider, LV_SLIDER_STYLE_KNOB, ext->style_knob);
}
_ot(new_slider, LV_SLIDER_PART_KNOB, SLIDER_KNOB);
}
/*Copy an existing slider*/
else {
lv_slider_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
ext->style_knob = copy_ext->style_knob;
/*Refresh the style with new signal function*/
lv_obj_refresh_style(new_slider);
// lv_slider_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
}
LV_LOG_INFO("slider created");
@@ -134,29 +124,6 @@ void lv_slider_set_knob_img(lv_obj_t * slider, const void * img_src)
lv_obj_invalidate(slider);
}
/**
* Set a style of a slider
* @param slider pointer to a slider object
* @param type which style should be set
* @param style pointer to a style
*/
void lv_slider_set_style(lv_obj_t * slider, lv_slider_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(slider, LV_OBJX_NAME);
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);
switch(type) {
case LV_SLIDER_STYLE_BG: lv_bar_set_style(slider, LV_BAR_STYLE_BG, style); break;
case LV_SLIDER_STYLE_INDIC: lv_bar_set_style(slider, LV_BAR_STYLE_INDIC, style); break;
case LV_SLIDER_STYLE_KNOB:
ext->style_knob = style;
lv_obj_refresh_ext_draw_pad(slider);
lv_obj_invalidate(slider);
break;
}
}
/*=====================
* Getter functions
*====================*/
@@ -199,29 +166,6 @@ const void * lv_slider_get_knob_img(lv_obj_t * slider, const void * img_src)
return ext->img_knob;
}
/**
* Get a style of a slider
* @param slider pointer to a slider object
* @param type which style should be get
* @return style pointer to a style
*/
const lv_style_t * lv_slider_get_style(const lv_obj_t * slider, lv_slider_style_t type)
{
LV_ASSERT_OBJ(slider, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);
switch(type) {
case LV_SLIDER_STYLE_BG: style = lv_bar_get_style(slider, LV_BAR_STYLE_BG); break;
case LV_SLIDER_STYLE_INDIC: style = lv_bar_get_style(slider, LV_BAR_STYLE_INDIC); break;
case LV_SLIDER_STYLE_KNOB: style = ext->style_knob; break;
default: style = NULL; break;
}
return style;
}
/**********************
* STATIC FUNCTIONS
**********************/
@@ -321,6 +265,13 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
{
lv_res_t res;
if(sign == LV_SIGNAL_GET_STYLE) {
uint8_t ** type_p = param;
lv_style_dsc_t ** style_dsc_p = param;
*style_dsc_p = lv_slider_get_style(slider, **type_p);
return LV_RES_OK;
}
/* Include the ancient signal function */
res = ancestor_signal(slider, sign, param);
if(res != LV_RES_OK) return res;
@@ -357,18 +308,23 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
lv_coord_t w = lv_obj_get_width(slider);
lv_coord_t h = lv_obj_get_height(slider);
const lv_style_t * indic_style = lv_slider_get_style(slider, LV_SLIDER_STYLE_INDIC);
lv_style_value_t bg_left = lv_obj_get_style_value(slider, LV_SLIDER_PART_BG, LV_STYLE_PAD_LEFT);
lv_style_value_t bg_right = lv_obj_get_style_value(slider, LV_SLIDER_PART_BG, LV_STYLE_PAD_RIGHT);
lv_style_value_t bg_top = lv_obj_get_style_value(slider, LV_SLIDER_PART_BG, LV_STYLE_PAD_TOP);
lv_style_value_t bg_bottom = lv_obj_get_style_value(slider, LV_SLIDER_PART_BG, LV_STYLE_PAD_BOTTOM);
int32_t range = ext->bar.max_value - ext->bar.min_value;
int16_t new_value = 0, real_max_value = ext->bar.max_value, real_min_value = ext->bar.min_value;
if(w >= h) {
lv_coord_t indic_w = w - indic_style->body.padding.left - indic_style->body.padding.right;
new_value = p.x - (slider->coords.x1 + indic_style->body.padding.left); /*Make the point relative to the indicator*/
lv_coord_t indic_w = w - bg_left - bg_right;
new_value = p.x - (slider->coords.x1 + bg_left); /*Make the point relative to the indicator*/
new_value = (new_value * range) / indic_w;
new_value += ext->bar.min_value;
} else {
lv_coord_t indic_h = h - indic_style->body.padding.bottom - indic_style->body.padding.top;
new_value = p.y - (slider->coords.y2 + indic_style->body.padding.bottom); /*Make the point relative to the indicator*/
lv_coord_t indic_h = h - bg_bottom - bg_top;
new_value = p.y - (slider->coords.y2 + bg_bottom); /*Make the point relative to the indicator*/
new_value = (-new_value * range) / indic_h;
new_value += ext->bar.min_value;
@@ -412,18 +368,22 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
slider->signal_cb(slider, LV_SIGNAL_REFR_EXT_DRAW_PAD, NULL);
}
} else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
const lv_style_t * bg_style = lv_slider_get_style(slider, LV_SLIDER_STYLE_BG);
const lv_style_t * indic_style = lv_slider_get_style(slider, LV_SLIDER_STYLE_INDIC);
const lv_style_t * knob_style = lv_slider_get_style(slider, LV_SLIDER_STYLE_KNOB);
lv_style_value_t knob_left = lv_obj_get_style_value(slider, LV_SLIDER_PART_KNOB, LV_STYLE_PAD_LEFT);
lv_style_value_t knob_right = lv_obj_get_style_value(slider, LV_SLIDER_PART_KNOB, LV_STYLE_PAD_RIGHT);
lv_style_value_t knob_top = lv_obj_get_style_value(slider, LV_SLIDER_PART_KNOB, LV_STYLE_PAD_TOP);
lv_style_value_t knob_bottom = lv_obj_get_style_value(slider, LV_SLIDER_PART_KNOB, LV_STYLE_PAD_BOTTOM);
/* The smaller size is the knob diameter*/
lv_coord_t knob_size = LV_MATH_MIN(lv_obj_get_width(slider), lv_obj_get_height(slider)) >> 1;
knob_size += LV_MATH_MAX(
LV_MATH_MAX(knob_style->body.padding.left, knob_style->body.padding.right),
LV_MATH_MAX(knob_style->body.padding.bottom,knob_style->body.padding.top));
knob_size += LV_MATH_MAX(LV_MATH_MAX(knob_left, knob_right), LV_MATH_MAX(knob_bottom,knob_top));
knob_size += knob_style->body.shadow.width + knob_style->body.shadow.spread;
knob_size += LV_MATH_MAX(LV_MATH_ABS(knob_style->body.shadow.offset.x), LV_MATH_ABS(knob_style->body.shadow.offset.y));
lv_style_value_t knob_sh_width = lv_obj_get_style_value(slider, LV_SLIDER_PART_KNOB, LV_STYLE_SHADOW_WIDTH);
lv_style_value_t knob_sh_spread = lv_obj_get_style_value(slider, LV_SLIDER_PART_KNOB, LV_STYLE_SHADOW_SPREAD);
lv_style_value_t knob_sh_ox = lv_obj_get_style_value(slider, LV_SLIDER_PART_KNOB, LV_STYLE_SHADOW_OFFSET_X);
lv_style_value_t knob_sh_oy = lv_obj_get_style_value(slider, LV_SLIDER_PART_KNOB, LV_STYLE_SHADOW_OFFSET_Y);
knob_size += knob_sh_width + knob_sh_spread;
knob_size += LV_MATH_MAX(LV_MATH_ABS(knob_sh_ox), LV_MATH_ABS(knob_sh_oy));
if(ext->img_knob) {
lv_img_header_t info;
@@ -437,12 +397,21 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
}
}
lv_style_value_t bg_sh_width = lv_obj_get_style_value(slider, LV_SLIDER_PART_BG, LV_STYLE_SHADOW_WIDTH);
lv_style_value_t bg_sh_spread = lv_obj_get_style_value(slider, LV_SLIDER_PART_BG, LV_STYLE_SHADOW_SPREAD);
lv_style_value_t bg_sh_ox = lv_obj_get_style_value(slider, LV_SLIDER_PART_BG, LV_STYLE_SHADOW_OFFSET_X);
lv_style_value_t bg_sh_oy = lv_obj_get_style_value(slider, LV_SLIDER_PART_BG, LV_STYLE_SHADOW_OFFSET_Y);
lv_coord_t bg_size = bg_style->body.shadow.width + bg_style->body.shadow.spread;
bg_size += LV_MATH_MAX(LV_MATH_ABS(bg_style->body.shadow.offset.x), LV_MATH_ABS(bg_style->body.shadow.offset.y));
lv_coord_t bg_size = bg_sh_width + bg_sh_spread;
bg_size += LV_MATH_MAX(LV_MATH_ABS(bg_sh_ox), LV_MATH_ABS(bg_sh_oy));
lv_coord_t indic_size = indic_style->body.shadow.width + indic_style->body.shadow.spread;
indic_size += LV_MATH_MAX(LV_MATH_ABS(indic_style->body.shadow.offset.x), LV_MATH_ABS(indic_style->body.shadow.offset.y));
lv_style_value_t indic_sh_width = lv_obj_get_style_value(slider, LV_SLIDER_PART_INDIC, LV_STYLE_SHADOW_WIDTH);
lv_style_value_t indic_sh_spread = lv_obj_get_style_value(slider, LV_SLIDER_PART_INDIC, LV_STYLE_SHADOW_SPREAD);
lv_style_value_t indic_sh_ox = lv_obj_get_style_value(slider, LV_SLIDER_PART_INDIC, LV_STYLE_SHADOW_OFFSET_X);
lv_style_value_t indic_sh_oy = lv_obj_get_style_value(slider, LV_SLIDER_PART_INDIC, LV_STYLE_SHADOW_OFFSET_Y);
lv_coord_t indic_size = indic_sh_width + indic_sh_spread;
indic_size += LV_MATH_MAX(LV_MATH_ABS(indic_sh_ox), LV_MATH_ABS(indic_sh_oy));
slider->ext_draw_pad = LV_MATH_MAX(slider->ext_draw_pad, knob_size);
slider->ext_draw_pad = LV_MATH_MAX(slider->ext_draw_pad, indic_size);
@@ -468,9 +437,33 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
return res;
}
static lv_style_dsc_t * lv_slider_get_style(lv_obj_t * slider, uint8_t part)
{
LV_ASSERT_OBJ(slider, LV_OBJX_NAME);
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);
lv_style_dsc_t * style_dsc_p;
switch(part) {
case LV_SLIDER_PART_BG:
style_dsc_p = &slider->style_dsc;
break;
case LV_SLIDER_PART_INDIC:
style_dsc_p = &ext->bar.style_indic;
break;
case LV_SLIDER_PART_KNOB:
style_dsc_p = &ext->style_knob;
break;
default:
style_dsc_p = NULL;
}
return style_dsc_p;
}
static void lv_slider_position_knob(lv_obj_t * slider, lv_area_t * knob_area, lv_coord_t knob_size, bool hor)
{
const lv_style_t * style_knob = lv_slider_get_style(slider, LV_SLIDER_STYLE_KNOB);
if(hor) {
knob_area->x1 -= (knob_size >> 1);
@@ -484,19 +477,27 @@ static void lv_slider_position_knob(lv_obj_t * slider, lv_area_t * knob_area, lv
knob_area->x2 = slider->coords.x2;
}
lv_style_value_t knob_left = lv_obj_get_style_value(slider, LV_SLIDER_PART_KNOB, LV_STYLE_PAD_LEFT);
lv_style_value_t knob_right = lv_obj_get_style_value(slider, LV_SLIDER_PART_KNOB, LV_STYLE_PAD_RIGHT);
lv_style_value_t knob_top = lv_obj_get_style_value(slider, LV_SLIDER_PART_KNOB, LV_STYLE_PAD_TOP);
lv_style_value_t knob_bottom = lv_obj_get_style_value(slider, LV_SLIDER_PART_KNOB, LV_STYLE_PAD_BOTTOM);
/*Apply the paddings on the knob area*/
knob_area->x1 -= style_knob->body.padding.left;
knob_area->x2 += style_knob->body.padding.right;
knob_area->y1 -= style_knob->body.padding.top;
knob_area->y2 += style_knob->body.padding.bottom;
knob_area->x1 -= knob_left;
knob_area->x2 += knob_right;
knob_area->y1 -= knob_top;
knob_area->y2 += knob_bottom;
}
static void lv_slider_draw_knob(lv_obj_t * slider, const lv_area_t * knob_area, const lv_area_t * clip_area) {
static void lv_slider_draw_knob(lv_obj_t * slider, const lv_area_t * knob_area, const lv_area_t * clip_area)
{
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);
const lv_style_t * style_knob = lv_slider_get_style(slider, LV_SLIDER_STYLE_KNOB);
lv_opa_t opa_scale = lv_obj_get_opa_scale(slider);
lv_draw_rect(knob_area, clip_area, style_knob, opa_scale);
lv_draw_rect_dsc_t knob_rect_dsc;
lv_draw_rect_dsc_init(&knob_rect_dsc);
lv_obj_init_draw_rect_dsc(slider, LV_SLIDER_PART_KNOB, &knob_rect_dsc);
lv_draw_rect(knob_area, clip_area, &knob_rect_dsc);
if(ext->img_knob) {
lv_res_t res;
@@ -511,7 +512,10 @@ static void lv_slider_draw_knob(lv_obj_t * slider, const lv_area_t * knob_area,
a.x2 = info.w - 1 + x_ofs;
a.y2 = info.h - 1 + y_ofs;
lv_draw_img(&a, clip_area, ext->img_knob, style_knob, 0, NULL, LV_IMG_ZOOM_NONE, false, opa_scale);
lv_draw_img_dsc_t knob_img_dsc;
lv_draw_img_dsc_init(&knob_img_dsc);
lv_obj_init_draw_img_dsc(slider, LV_SLIDER_PART_KNOB, &knob_img_dsc);
lv_draw_img(&a, clip_area, ext->img_knob, &knob_img_dsc);
} else {
LV_LOG_WARN("lv_slider_design: can't get knob image info")
}

View File

@@ -44,7 +44,7 @@ typedef struct
{
lv_bar_ext_t bar; /*Ext. of ancestor*/
/*New data for this type */
const lv_style_t * style_knob; /*Style of the knob*/
lv_style_dsc_t style_knob; /*Style of the knob*/
lv_area_t left_knob_area;
lv_area_t right_knob_area;
int16_t *value_to_set; /* Which bar value to set */
@@ -54,9 +54,9 @@ typedef struct
/** Built-in styles of slider*/
enum {
LV_SLIDER_STYLE_BG, /** Slider background style. */
LV_SLIDER_STYLE_INDIC, /** Slider indicator (filled area) style. */
LV_SLIDER_STYLE_KNOB, /** Slider knob style. */
LV_SLIDER_PART_BG, /** Slider background style. */
LV_SLIDER_PART_INDIC, /** Slider indicator (filled area) style. */
LV_SLIDER_PART_KNOB, /** Slider knob style. */
};
typedef uint8_t lv_slider_style_t;
@@ -143,14 +143,6 @@ static inline void lv_slider_set_type(lv_obj_t * slider, lv_slider_type_t type)
lv_bar_set_type(slider, LV_BAR_TYPE_CUSTOM);
}
/**
* Set a style of a slider
* @param slider pointer to a slider object
* @param type which style should be set
* @param style pointer to a style
*/
void lv_slider_set_style(lv_obj_t * slider, lv_slider_style_t type, const lv_style_t * style);
/*=====================
* Getter functions
*====================*/
@@ -232,14 +224,6 @@ static inline lv_slider_type_t lv_slider_get_type(lv_obj_t * slider)
return LV_SLIDER_TYPE_NORMAL;
}
/**
* Get a style of a slider
* @param slider pointer to a slider object
* @param type which style should be get
* @return style pointer to a style
*/
const lv_style_t * lv_slider_get_style(const lv_obj_t * slider, lv_slider_style_t type);
/**********************
* MACROS
**********************/

View File

@@ -33,14 +33,14 @@
/**********************
* STATIC PROTOTYPES
**********************/
static lv_design_res_t lv_sw_design(lv_obj_t * slider, const lv_area_t * clip_area, lv_design_mode_t mode);
static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param);
static lv_style_dsc_t * lv_sw_get_style(lv_obj_t * sw, uint8_t part);
static lv_style_dsc_t * lv_sw_get_style(lv_obj_t * sw, uint8_t part);
/**********************
* STATIC VARIABLES
**********************/
static lv_signal_cb_t ancestor_signal;
static lv_design_cb_t ancestor_design;
/**********************
* MACROS
@@ -61,13 +61,12 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy)
LV_LOG_TRACE("switch create started");
/*Create the ancestor of switch*/
lv_obj_t * new_sw = lv_bar_create(par, copy);
lv_obj_t * new_sw = lv_slider_create(par, copy);
LV_ASSERT_MEM(new_sw);
if(new_sw == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_sw);
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_sw);
/*Allocate the switch type specific extended data*/
lv_sw_ext_t * ext = lv_obj_allocate_ext_attr(new_sw, sizeof(lv_sw_ext_t));
@@ -79,42 +78,28 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy)
/*Initialize the allocated 'ext' */
ext->changed = 0;
ext->style_knob_off = &lv_style_pretty;
ext->style_knob_on = &lv_style_pretty;
ext->img_knob_off = NULL;
ext->img_knob_on = NULL;
/*The signal and design functions are not copied so set them here*/
lv_obj_set_signal_cb(new_sw, lv_sw_signal);
lv_obj_set_design_cb(new_sw, lv_sw_design);
/*Init the new switch switch*/
if(copy == NULL) {
lv_obj_set_click(new_sw, true);
lv_obj_set_protect(new_sw, LV_PROTECT_PRESS_LOST);
lv_obj_set_size(new_sw, 2 * LV_DPI / 3, LV_DPI / 3);
lv_bar_set_range(new_sw, 0, LV_SW_MAX_VALUE);
lv_slider_set_range(new_sw, 0, 1);
_ot(new_sw, LV_SW_PART_KNOB, SW_KNOB);
/*Set the default styles*/
lv_theme_t * th = lv_theme_get_current();
if(th) {
lv_sw_set_style(new_sw, LV_SW_STYLE_BG, th->style.sw.bg);
lv_sw_set_style(new_sw, LV_SW_STYLE_INDIC, th->style.sw.indic);
lv_sw_set_style(new_sw, LV_SW_STYLE_KNOB_OFF, th->style.sw.knob_off);
lv_sw_set_style(new_sw, LV_SW_STYLE_KNOB_ON, th->style.sw.knob_on);
} else {
/*Let the slider' style*/
}
}
/*Copy an existing switch*/
else {
lv_sw_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
ext->style_knob_off = copy_ext->style_knob_off;
ext->style_knob_on = copy_ext->style_knob_on;
// lv_sw_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
// ext->style_knob_off = copy_ext->style_knob_off;
// ext->style_knob_on = copy_ext->style_knob_on;
}
/*Refresh the style with new signal function*/
lv_obj_refresh_style(new_sw);
LV_LOG_INFO("switch created");
@@ -139,8 +124,8 @@ void lv_sw_on(lv_obj_t * sw, lv_anim_enable_t anim)
#endif
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
ext->state = 1;
lv_bar_set_value(sw, LV_SW_MAX_VALUE, anim);
lv_obj_invalidate(sw);
lv_slider_set_value(sw, 1, anim);
lv_obj_set_state(sw, LV_OBJ_STATE_CHECKED);
}
/**
@@ -158,7 +143,7 @@ void lv_sw_off(lv_obj_t * sw, lv_anim_enable_t anim)
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
ext->state = 0;
lv_bar_set_value(sw, 0, anim);
lv_obj_invalidate(sw);
lv_obj_clear_state(sw, LV_OBJ_STATE_CHECKED);
}
/**
@@ -184,210 +169,14 @@ bool lv_sw_toggle(lv_obj_t * sw, lv_anim_enable_t anim)
return !state;
}
/**
* Set an image to display on the knob of the switch when it's in OFF state
* @param sw pointer to a switch object
* @param img_src pointer to an `lv_img_dsc_t` variable or a path to an image
* (not an `lv_img` object)
*/
void lv_sw_set_knob_off_img(lv_obj_t * sw, const void * img_src)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
ext->img_knob_off = img_src;
lv_obj_refresh_ext_draw_pad(sw);
lv_obj_invalidate(sw);
}
/**
* Set an image to display on the knob of the switch when it's in ON state
* @param sw pointer to a switch object
* @param img_src pointer to an `lv_img_dsc_t` variable or a path to an image
* (not an `lv_img` object)
*/
void lv_sw_set_knob_on_img(lv_obj_t * sw, const void * img_src)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
ext->img_knob_on = img_src;
lv_obj_refresh_ext_draw_pad(sw);
lv_obj_invalidate(sw);
}
/**
* Set a style of a switch
* @param sw pointer to a switch object
* @param type which style should be set
* @param style pointer to a style
*/
void lv_sw_set_style(lv_obj_t * sw, lv_sw_style_t type, const lv_style_t * style)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
switch(type) {
case LV_SW_STYLE_BG: lv_bar_set_style(sw, LV_BAR_STYLE_BG, style); break;
case LV_SW_STYLE_INDIC: lv_bar_set_style(sw, LV_BAR_STYLE_INDIC, style); break;
case LV_SW_STYLE_KNOB_OFF:
ext->style_knob_off = style;
lv_obj_refresh_ext_draw_pad(sw);
lv_obj_invalidate(sw);
break;
case LV_SW_STYLE_KNOB_ON:
ext->style_knob_on = style;
lv_obj_refresh_ext_draw_pad(sw);
lv_obj_invalidate(sw);
break;
}
}
/*=====================
* Getter functions
*====================*/
/**
* Get an image to display on the knob of the switch when it's in OFF state
* @param sw pointer to a switch object
* @return the image source: pointer to an `lv_img_dsc_t` variable or a path to an image
* (not an `lv_img` object)
*/
const void * lv_slider_get_knob_off_img(lv_obj_t * sw, const void * img_src)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
return ext->img_knob_off;
}
/**
* Get an image to display on the knob of the switch when it's in ON state
* @param sw pointer to a switch object
* @return the image source: pointer to an `lv_img_dsc_t` variable or a path to an image
* (not an `lv_img` object)
*/
const void * lv_slider_get_knob_on_img(lv_obj_t * sw, const void * img_src)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
return ext->img_knob_on;
}
/**
* Get a style of a switch
* @param sw pointer to a switch object
* @param type which style should be get
* @return style pointer to a style
*/
const lv_style_t * lv_sw_get_style(const lv_obj_t * sw, lv_sw_style_t type)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
const lv_style_t * style = NULL;
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
switch(type) {
case LV_SW_STYLE_BG: style = lv_bar_get_style(sw, LV_BAR_STYLE_BG); break;
case LV_SW_STYLE_INDIC: style = lv_bar_get_style(sw, LV_BAR_STYLE_INDIC); break;
case LV_SW_STYLE_KNOB_OFF: style = ext->style_knob_off; break;
case LV_SW_STYLE_KNOB_ON: style = ext->style_knob_on; break;
default: style = NULL; break;
}
return style;
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Handle the drawing related tasks of the sliders
* @param sw pointer to an object
* @param clip_area the object will be drawn only in this area
* @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area
* (return 'true' if yes)
* LV_DESIGN_DRAW: draw the object (always return 'true')
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
* @param return an element of `lv_design_res_t`
*/
static lv_design_res_t lv_sw_design(lv_obj_t * sw, const lv_area_t * clip_area, lv_design_mode_t mode)
{
/*Return false if the object is not covers the mask_p area*/
if(mode == LV_DESIGN_COVER_CHK) {
return LV_DESIGN_RES_NOT_COVER;
}
/*Draw the object*/
else if(mode == LV_DESIGN_DRAW_MAIN) {
/*The ancestor design function will draw the background and the indicator.
* It also sets ext->bar.indic_area*/
ancestor_design(sw, clip_area, mode);
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
lv_opa_t opa_scale = lv_obj_get_opa_scale(sw);
const lv_style_t * style_knob = lv_sw_get_style(sw, ext->state ?
LV_SW_STYLE_KNOB_ON : LV_SW_STYLE_KNOB_OFF);
const lv_style_t * style_indic = lv_sw_get_style(sw, LV_SW_STYLE_INDIC);
lv_coord_t objw = lv_obj_get_width(sw);
lv_coord_t objh = lv_obj_get_height(sw);
lv_coord_t indic_maxw = objw - style_indic->body.padding.left - style_indic->body.padding.right;
lv_coord_t knob_size = objh;
lv_coord_t indic_p = (lv_area_get_width(&ext->bar.indic_area) * 256) / (indic_maxw);
lv_area_t knob_area;
knob_area.x2 = ext->bar.indic_area.x2;
knob_area.x2 += (knob_size * (256 - indic_p)) >> 8;
if(knob_area.x2 < sw->coords.x1 + knob_size) knob_area.x2 = sw->coords.x1 + knob_size;
knob_area.x1 = knob_area.x2 - knob_size;
knob_area.y1 = sw->coords.y1;
knob_area.y2 = sw->coords.y2;
knob_area.x1 -= style_knob->body.padding.left;
knob_area.x2 += style_knob->body.padding.right;
knob_area.y1 -= style_knob->body.padding.top;
knob_area.y2 += style_knob->body.padding.bottom;
lv_draw_rect(&knob_area, clip_area, style_knob, opa_scale);
const void * img = ext->state ? ext->img_knob_on : ext->img_knob_off;
if(img) {
lv_res_t res;
lv_img_header_t info;
res = lv_img_decoder_get_info(img, &info);
if(res == LV_RES_OK) {
lv_coord_t x_ofs = knob_area.x1 + (lv_area_get_width(&knob_area) - info.w) / 2;
lv_coord_t y_ofs = knob_area.y1 + (lv_area_get_height(&knob_area) - info.h) / 2;
lv_area_t a;
a.x1 = x_ofs;
a.y1 = y_ofs;
a.x2 = info.w - 1 + x_ofs;
a.y2 = info.h - 1 + y_ofs;
lv_draw_img(&a, clip_area, img, style_knob, 0, NULL, LV_IMG_ZOOM_NONE, false, opa_scale);
} else {
LV_LOG_WARN("lv_slider_design: can't get knob image info")
}
}
}
/*Post draw when the children are drawn*/
else if(mode == LV_DESIGN_DRAW_POST) {
return ancestor_design(sw, clip_area, mode);
}
return LV_DESIGN_RES_OK;
}
/**
* Signal function of the switch
* @param sw pointer to a switch object
@@ -398,6 +187,14 @@ static lv_design_res_t lv_sw_design(lv_obj_t * sw, const lv_area_t * clip_area,
static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param)
{
lv_res_t res;
if(sign == LV_SIGNAL_GET_STYLE) {
uint8_t ** type_p = param;
lv_style_dsc_t ** style_dsc_p = param;
*style_dsc_p = lv_sw_get_style(sw, **type_p);
return LV_RES_OK;
}
if(sign == LV_SIGNAL_GET_TYPE) {
res = ancestor_signal(sw, sign, param);
if(res != LV_RES_OK) return res;
@@ -421,148 +218,37 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param)
lv_indev_get_point(indev, &p);
ext->start_x = p.x;
}
ext->slided = 0;
ext->changed = 0;
} else if(sign == LV_SIGNAL_PRESSING) {
/*See if the switch was slid (moved at least a little)*/
lv_indev_t * indev = lv_indev_get_act();
lv_point_t p;
if(indev) {
lv_indev_get_point(indev, &p);
if(LV_MATH_ABS(p.x - ext->start_x) > indev->driver.drag_limit) ext->slided = 1;
/*If slid set the value accordingly*/
if(ext->slided) {
lv_coord_t w = lv_obj_get_width(sw);
const lv_style_t * indic_style = lv_sw_get_style(sw, LV_SW_STYLE_INDIC);
int16_t new_val = 0;
lv_coord_t indic_w = w - indic_style->body.padding.left - indic_style->body.padding.right;
int32_t range = ext->bar.max_value - ext->bar.min_value;
new_val = p.x - (sw->coords.x1 + indic_style->body.padding.left); /*Make the point relative to the indicator*/
new_val = (new_val * range) / indic_w;
new_val += ext->bar.min_value;
if(new_val < ext->bar.min_value) new_val = ext->bar.min_value;
else if(new_val > ext->bar.max_value) new_val = ext->bar.max_value;
/*If explicitly changed (by slide) don't need to be toggled on release*/
int16_t threshold = LV_SW_MAX_VALUE / 2;
if((new_val < threshold && ext->bar.cur_value > threshold) ||
(new_val > threshold && ext->bar.cur_value < threshold)) {
ext->changed = 1;
}
if(new_val != ext->bar.cur_value) {
ext->bar.cur_value = new_val;
lv_obj_invalidate(sw);
}
}
}
if(ext->state != ext->slider.bar.cur_value) ext->changed = 1;
} else if(sign == LV_SIGNAL_PRESS_LOST) {
if(lv_sw_get_state(sw)) lv_sw_on(sw, LV_ANIM_ON);
else lv_sw_off(sw, LV_ANIM_ON);
} else if(sign == LV_SIGNAL_RELEASED) {
/*If not dragged then toggle the switch*/
if(ext->changed == 0) {
int32_t state;
if(lv_sw_get_state(sw)) {
lv_sw_off(sw, LV_ANIM_ON);
state = 0;
} else {
lv_sw_on(sw, LV_ANIM_ON);
state = 1;
}
res = lv_event_send(sw, LV_EVENT_VALUE_CHANGED, &state);
if(res != LV_RES_OK) return res;
}
/*If the switch was dragged then calculate the new state based on the current position*/
else {
int16_t v = lv_bar_get_value(sw);
int32_t state;
if(v > LV_SW_MAX_VALUE / 2) {
lv_sw_on(sw, LV_ANIM_ON);
state = 1;
} else {
lv_sw_off(sw, LV_ANIM_ON);
state = 0;
}
res = lv_event_send(sw, LV_EVENT_VALUE_CHANGED, &state);
if(res != LV_RES_OK) return res;
if(ext->slider.bar.cur_value != 0) lv_sw_on(sw, LV_ANIM_ON);
else lv_sw_off(sw, LV_ANIM_ON);
}
res = lv_event_send(sw, LV_EVENT_VALUE_CHANGED, NULL);
if(res != LV_RES_OK) return res;
} else if(sign == LV_SIGNAL_CONTROL) {
char c = *((char *)param);
uint32_t state;
if(c == LV_KEY_RIGHT || c == LV_KEY_UP) {
lv_bar_set_value(sw, LV_SW_MAX_VALUE, LV_ANIM_ON);
state = 1;
res = lv_event_send(sw, LV_EVENT_VALUE_CHANGED, &state);
if(res != LV_RES_OK) return res;
} else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) {
lv_bar_set_value(sw, 0, LV_ANIM_ON);
state = 0;
res = lv_event_send(sw, LV_EVENT_VALUE_CHANGED, &state);
if(res != LV_RES_OK) return res;
}
}
else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
const lv_style_t * bg_style = lv_sw_get_style(sw, LV_SW_STYLE_BG);
const lv_style_t * indic_style = lv_sw_get_style(sw, LV_SW_STYLE_INDIC);
const lv_style_t * knob_on_style = lv_sw_get_style(sw, LV_SW_STYLE_KNOB_OFF);
const lv_style_t * knob_off_style = lv_sw_get_style(sw, LV_SW_STYLE_KNOB_ON);
/* The smaller size is the knob diameter*/
lv_coord_t knob_on_size = LV_MATH_MIN(lv_obj_get_width(sw), lv_obj_get_height(sw)) >> 1;
knob_on_size += LV_MATH_MAX(
LV_MATH_MAX(knob_on_style->body.padding.left, knob_on_style->body.padding.right),
LV_MATH_MAX(knob_on_style->body.padding.bottom, knob_on_style->body.padding.top));
knob_on_size += knob_on_style->body.shadow.width + knob_on_style->body.shadow.spread;
knob_on_size += LV_MATH_MAX(LV_MATH_ABS(knob_on_style->body.shadow.offset.x), LV_MATH_ABS(knob_on_style->body.shadow.offset.y));
if(ext->img_knob_on) {
lv_img_header_t info;
lv_res_t res;
res = lv_img_decoder_get_info(ext->img_knob_on, &info);
if(res == LV_RES_OK) {
knob_on_size = LV_MATH_MAX(knob_on_size, info.w / 2);
knob_on_size = LV_MATH_MAX(knob_on_size, info.h / 2);
} else {
LV_LOG_WARN("slider signal (LV_SIGNAL_REFR_EXT_DRAW_PAD): can't get knob image info")
}
}
lv_coord_t knob_off_size = LV_MATH_MIN(lv_obj_get_width(sw), lv_obj_get_height(sw)) >> 1;
knob_off_size += LV_MATH_MAX(
LV_MATH_MAX(knob_off_style->body.padding.left, knob_off_style->body.padding.right),
LV_MATH_MAX(knob_off_style->body.padding.bottom, knob_off_style->body.padding.top));
knob_off_size += knob_off_style->body.shadow.width + knob_off_style->body.shadow.spread;
knob_off_size += LV_MATH_MAX(LV_MATH_ABS(knob_off_style->body.shadow.offset.x), LV_MATH_ABS(knob_off_style->body.shadow.offset.y));
if(ext->img_knob_off) {
lv_img_header_t info;
lv_res_t res;
res = lv_img_decoder_get_info(ext->img_knob_off, &info);
if(res == LV_RES_OK) {
knob_off_size = LV_MATH_MAX(knob_off_size, info.w / 2);
knob_off_size = LV_MATH_MAX(knob_off_size, info.h / 2);
} else {
LV_LOG_WARN("slider signal (LV_SIGNAL_REFR_EXT_DRAW_PAD): can't get knob image info")
}
}
lv_coord_t bg_size = bg_style->body.shadow.width + bg_style->body.shadow.spread;
bg_size += LV_MATH_MAX(LV_MATH_ABS(bg_style->body.shadow.offset.x), LV_MATH_ABS(bg_style->body.shadow.offset.y));
lv_coord_t indic_size = indic_style->body.shadow.width + indic_style->body.shadow.spread;
indic_size += LV_MATH_MAX(LV_MATH_ABS(indic_style->body.shadow.offset.x), LV_MATH_ABS(indic_style->body.shadow.offset.y));
sw->ext_draw_pad = LV_MATH_MAX(sw->ext_draw_pad, knob_on_size);
sw->ext_draw_pad = LV_MATH_MAX(sw->ext_draw_pad, knob_off_size);
sw->ext_draw_pad = LV_MATH_MAX(sw->ext_draw_pad, bg_size);
sw->ext_draw_pad = LV_MATH_MAX(sw->ext_draw_pad, indic_size);
if(c == LV_KEY_RIGHT || c == LV_KEY_UP) lv_sw_on(sw, LV_ANIM_ON);
else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) lv_sw_off(sw, LV_ANIM_ON);
res = lv_event_send(sw, LV_EVENT_VALUE_CHANGED, NULL);
if(res != LV_RES_OK) return res;
}
else if(sign == LV_SIGNAL_GET_EDITABLE) {
bool * editable = (bool *)param;
@@ -572,4 +258,27 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param)
return res;
}
static lv_style_dsc_t * lv_sw_get_style(lv_obj_t * sw, uint8_t part)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
lv_style_dsc_t * style_dsc_p;
switch(part) {
case LV_SW_PART_BG:
style_dsc_p = &sw->style_dsc;
break;
case LV_SW_PART_INDIC:
style_dsc_p = &ext->slider.bar.style_indic;
break;
case LV_SW_PART_KNOB:
style_dsc_p = &ext->slider.style_knob;
break;
default:
style_dsc_p = NULL;
}
return style_dsc_p;
}
#endif

View File

@@ -23,12 +23,11 @@ extern "C" {
#endif
#include "../lv_core/lv_obj.h"
#include "lv_bar.h"
#include "lv_slider.h"
/*********************
* DEFINES
*********************/
#define LV_SW_MAX_VALUE 100
/**********************
* TYPEDEFS
@@ -36,28 +35,23 @@ extern "C" {
/*Data of switch*/
typedef struct
{
lv_bar_ext_t bar; /*Ext. of ancestor*/
lv_slider_ext_t slider; /*Ext. of ancestor*/
/*New data for this type */
const lv_style_t * style_knob_off; /**< Style of the knob when the switch is OFF*/
const lv_style_t * style_knob_on; /**< Style of the knob when the switch is ON (NULL to use the same as OFF)*/
const void * img_knob_off; /**< Image to display when the switch is OFF*/
const void * img_knob_on; /**< Image to display when the switch is ON*/
lv_coord_t start_x;
uint8_t changed :1; /*Indicates the switch state explicitly changed by drag*/
uint8_t slided :1;
uint8_t state :1; /*The current state*/
} lv_sw_ext_t;
/**
* Switch styles.
* Switch parts.
*/
enum {
LV_SW_STYLE_BG, /**< Switch background. */
LV_SW_STYLE_INDIC, /**< Switch fill area. */
LV_SW_STYLE_KNOB_OFF, /**< Switch knob (when off). */
LV_SW_STYLE_KNOB_ON, /**< Switch knob (when on). */
LV_SW_PART_BG, /**< Switch background. */
LV_SW_PART_INDIC, /**< Switch fill area. */
LV_SW_PART_KNOB, /**< Switch knob (when off). */
};
typedef uint8_t lv_sw_style_t;
typedef uint8_t lv_sw_part_t;
/**********************
* GLOBAL PROTOTYPES
@@ -98,12 +92,12 @@ void lv_sw_off(lv_obj_t * sw, lv_anim_enable_t anim);
bool lv_sw_toggle(lv_obj_t * sw, lv_anim_enable_t anim);
/**
* Set an image to display on the knob of the switch when it's in OFF state
* Set an image to display on the knob of the switch.
* @param sw pointer to a switch object
* @param img_src pointer to an `lv_img_dsc_t` variable or a path to an image
* (not an `lv_img` object)
*/
void lv_sw_set_knob_off_img(lv_obj_t * sw, const void * img_src);
void lv_sw_set_knob_img(lv_obj_t * sw, const void * img_src);
/**
* Set an image to display on the knob of the switch when it's in ON state
@@ -123,14 +117,6 @@ static inline void lv_sw_set_anim_time(lv_obj_t * sw, uint16_t anim_time)
{
lv_bar_set_anim_time(sw, anim_time);
}
/**
* Set a style of a switch
* @param sw pointer to a switch object
* @param type which style should be set
* @param style pointer to a style
*/
void lv_sw_set_style(lv_obj_t * sw, lv_sw_style_t type, const lv_style_t * style);
/*=====================
* Getter functions
@@ -171,16 +157,6 @@ static inline uint16_t lv_sw_get_anim_time(const lv_obj_t * sw)
return lv_bar_get_anim_time(sw);
}
/**
* Get a style of a switch
* @param sw pointer to a switch object
* @param type which style should be get
* @return style pointer to a style
*/
const lv_style_t * lv_sw_get_style(const lv_obj_t * sw, lv_sw_style_t type);
/**********************
* MACROS
**********************/

View File

@@ -53,10 +53,20 @@ typedef enum {
LV_THEME_LABEL_TITLE,
LV_THEME_LABEL_HINT,
LV_THEME_BTNM,
LV_THEME_BTNM_BTN,
LV_THEME_BAR,
LV_THEME_BAR_INDIC,
LV_THEME_SLIDER,
LV_THEME_SLIDER_INDIC,
LV_THEME_SLIDER_KNOB,
LV_THEME_SW,
LV_THEME_SW_INDIC,
LV_THEME_SW_KNOB,
}lv_theme_style_t;
typedef struct {

View File

@@ -30,18 +30,16 @@ static lv_theme_t theme;
static lv_style_t scr;
static lv_style_t transp;
static lv_style_t def;
static lv_style_t bg;
static lv_style_t panel; /*General fancy background (e.g. to chart or ta)*/
static lv_style_t sb;
static lv_style_t btn;
static lv_style_t sb;
#if LV_USE_BAR
static lv_style_t bar_bg, bar_indic;
static lv_style_t bar_indic;
#endif
#if LV_USE_SLIDER
static lv_style_t slider_knob;
static lv_style_t knob;
#endif
#if LV_USE_LMETER
@@ -52,10 +50,6 @@ static lv_style_t lmeter_bg;
static lv_style_t ddlist_bg, ddlist_sel;
#endif
#if LV_USE_BTNM
static lv_style_t btnm_bg, btnm_rel, btnm_pr, btnm_trel, btnm_ina;
#endif
/**********************
* MACROS
**********************/
@@ -67,10 +61,9 @@ static lv_style_t btnm_bg, btnm_rel, btnm_pr, btnm_trel, btnm_ina;
static void basic_init(void)
{
lv_style_init(&scr);
lv_style_set_color(&scr, LV_STYLE_BG_COLOR, LV_COLOR_MAKE(0xF0, 0x90, 0x20));
lv_style_set_color(&scr, LV_STYLE_BG_COLOR, LV_COLOR_MAKE(0x20, 0x20, 0x20));
lv_style_set_color(&scr, LV_STYLE_TEXT_COLOR , LV_COLOR_WHITE);
lv_style_init(&transp);
lv_style_set_value(&transp, LV_STYLE_BG_OPA, LV_OPA_TRANSP);
lv_style_set_value(&transp, LV_STYLE_BORDER_WIDTH, 0);
@@ -209,36 +202,12 @@ static void label_init(void)
static void bar_init(void)
{
#if LV_USE_BAR
lv_style_copy(&bar_bg, &def);
bar_bg.body.opa = LV_OPA_30;
bar_bg.body.radius = LV_RADIUS_CIRCLE;
bar_bg.body.main_color = LV_COLOR_WHITE;
bar_bg.body.grad_color = LV_COLOR_SILVER;
bar_bg.body.border.width = 2;
bar_bg.body.border.color = LV_COLOR_SILVER;
bar_bg.body.border.opa = LV_OPA_20;
bar_bg.body.padding.left = 0;
bar_bg.body.padding.right = 0;
bar_bg.body.padding.top = LV_DPI / 10;
bar_bg.body.padding.bottom = LV_DPI / 10;
bar_bg.body.padding.inner = 0;
lv_style_copy(&bar_indic, &def);
bar_indic.body.radius = LV_RADIUS_CIRCLE;
bar_indic.body.border.width = 2;
bar_indic.body.border.color = LV_COLOR_SILVER;
bar_indic.body.border.opa = LV_OPA_70;
bar_indic.body.padding.left = 0;
bar_indic.body.padding.right = 0;
bar_indic.body.padding.top = 0;
bar_indic.body.padding.bottom = 0;
bar_indic.body.shadow.width = LV_DPI / 20;
bar_indic.body.shadow.color = lv_color_hsv_to_rgb(_hue, 20, 90);
bar_indic.body.main_color = lv_color_hsv_to_rgb(_hue, 40, 80);
bar_indic.body.grad_color = lv_color_hsv_to_rgb(_hue, 40, 80);
theme.style.bar.bg = &bar_bg;
theme.style.bar.indic = &bar_indic;
lv_style_init(&bar_indic);
lv_style_set_color(&bar_indic, LV_STYLE_BG_COLOR, LV_COLOR_BLUE);
lv_style_set_value(&bar_indic, LV_STYLE_PAD_TOP, LV_DPI/20);
lv_style_set_value(&bar_indic, LV_STYLE_PAD_BOTTOM, LV_DPI/20);
lv_style_set_value(&bar_indic, LV_STYLE_PAD_LEFT, LV_DPI/20);
lv_style_set_value(&bar_indic, LV_STYLE_PAD_RIGHT, LV_DPI/20);
#endif
}
@@ -292,54 +261,20 @@ static void led_init(void)
static void slider_init(void)
{
#if LV_USE_SLIDER != 0
lv_style_copy(&slider_knob, &def);
slider_knob.body.opa = LV_OPA_60;
slider_knob.body.radius = LV_RADIUS_CIRCLE;
slider_knob.body.main_color = LV_COLOR_WHITE;
slider_knob.body.grad_color = LV_COLOR_SILVER;
slider_knob.body.border.width = 1;
slider_knob.body.border.color = LV_COLOR_GRAY;
slider_knob.body.border.opa = LV_OPA_50;
slider_knob.body.padding.left = LV_DPI/25;
slider_knob.body.padding.right = LV_DPI/25;
slider_knob.body.padding.top = LV_DPI/25;
slider_knob.body.padding.bottom = LV_DPI/25;
lv_style_init(&knob);
lv_style_set_color(&knob, LV_STYLE_BG_COLOR, LV_COLOR_RED);
lv_style_set_value(&knob, LV_STYLE_PAD_TOP, LV_DPI/20);
lv_style_set_value(&knob, LV_STYLE_PAD_BOTTOM, LV_DPI/20);
lv_style_set_value(&knob, LV_STYLE_PAD_LEFT, LV_DPI/20);
lv_style_set_value(&knob, LV_STYLE_PAD_RIGHT, LV_DPI/20);
theme.style.slider.bg = &bar_bg;
theme.style.slider.indic = &bar_indic;
theme.style.slider.knob = &slider_knob;
#endif
}
static void sw_init(void)
{
#if LV_USE_SW != 0
static lv_style_t sw_bg, sw_indic, sw_knob;
lv_style_copy(&sw_bg, &bar_bg);
sw_bg.body.opa = LV_OPA_COVER;
sw_bg.body.padding.left = -2;
sw_bg.body.padding.right = -2;
sw_bg.body.padding.top = -2;
sw_bg.body.padding.bottom = -2;
sw_bg.body.main_color = lv_color_hex3(0x666);
sw_bg.body.grad_color = lv_color_hex3(0x999);
sw_bg.body.border.width = 2;
sw_bg.body.border.opa = LV_OPA_50;
lv_style_copy(&sw_indic, &bar_indic);
sw_indic.body.shadow.width = LV_DPI / 20;
sw_indic.body.padding.left = 0;
sw_indic.body.padding.right = 0;
sw_indic.body.padding.top = 0;
sw_indic.body.padding.bottom = 0;
lv_style_copy(&sw_knob, &slider_knob);
sw_knob.body.opa = LV_OPA_80;
theme.style.sw.bg = &sw_bg;
theme.style.sw.indic = &sw_indic;
theme.style.sw.knob_off = &sw_knob;
theme.style.sw.knob_on = &sw_knob;
#endif
}
@@ -879,10 +814,22 @@ lv_style_t * lv_theme_alien_get_style(lv_theme_style_t name)
return &transp;
case LV_THEME_PANEL:
return &panel;
case LV_THEME_BTN:
return &btn;
case LV_THEME_BTNM:
return &panel;
case LV_THEME_BTNM_BTN:
return &btn;
case LV_THEME_BAR:
return &panel;
case LV_THEME_BAR_INDIC:
return &bar_indic;
case LV_THEME_SLIDER:
return &panel;
case LV_THEME_SLIDER_INDIC:
return &bar_indic;
case LV_THEME_SLIDER_KNOB:
return &knob;
}
return NULL;