From aa5634dbcdd15c6c6dcbee58d7b00639457b1ada Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 1 Jan 2020 21:44:16 +0100 Subject: [PATCH] integrate lmeter and gauge --- src/lv_core/lv_obj.c | 24 +- src/lv_core/lv_obj.h | 3 + src/lv_core/lv_style.h | 9 +- src/lv_draw/lv_draw_line.c | 695 ++++++++++++++++----------------- src/lv_draw/lv_draw_line.h | 10 +- src/lv_objx/lv_gauge.c | 139 ++++--- src/lv_objx/lv_gauge.h | 16 +- src/lv_objx/lv_lmeter.c | 146 ++++--- src/lv_objx/lv_lmeter.h | 29 +- src/lv_objx/lv_page.c | 6 +- src/lv_objx/lv_tabview.c | 2 +- src/lv_themes/lv_theme.h | 5 + src/lv_themes/lv_theme_alien.c | 55 +-- 13 files changed, 577 insertions(+), 562 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 93d117dfd..a706516f3 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -2194,8 +2194,10 @@ lv_style_value_t lv_obj_get_style_value(const lv_obj_t * obj, uint8_t part, lv_s switch(prop) { case LV_STYLE_BORDER_PART: return LV_BORDER_SIDE_FULL; - case LV_STYLE_SCROLLBAR_WIDTH: - return LV_DPI/10; + case LV_STYLE_SIZE: + return LV_DPI / 10; + case LV_STYLE_SCALE_WIDTH: + return LV_DPI / 8; } return 0; @@ -2973,7 +2975,6 @@ void lv_obj_init_draw_img_dsc(lv_obj_t * obj, uint8_t part, lv_draw_img_dsc_t * } if(draw_dsc->opa <= LV_OPA_MIN) return; - draw_dsc->angle = 0; draw_dsc->zoom = LV_IMG_ZOOM_NONE; draw_dsc->pivot.x = lv_area_get_width(&obj->coords) / 2; @@ -2988,6 +2989,23 @@ void lv_obj_init_draw_img_dsc(lv_obj_t * obj, uint8_t part, lv_draw_img_dsc_t * draw_dsc->blend_mode = lv_obj_get_style_value(obj, part, LV_STYLE_IMAGE_BLEND_MODE); } +void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint8_t part, lv_draw_line_dsc_t * draw_dsc) +{ + 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->width = lv_obj_get_style_value(obj, part, LV_STYLE_LINE_WIDTH); + if(draw_dsc->width == 0) return; + + draw_dsc->color = lv_obj_get_style_color(obj, part, LV_STYLE_LINE_COLOR); + draw_dsc->blend_mode = lv_obj_get_style_value(obj, part, LV_STYLE_LINE_BLEND_MODE); +} + /** * Handle the drawing related tasks of the base objects. * @param obj pointer to an object diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index f649a992e..ffac51f2c 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -1079,6 +1079,9 @@ 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); + +void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint8_t part, lv_draw_line_dsc_t * draw_dsc); + /********************** * MACROS **********************/ diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index ad0a5d5fe..1f0f964a6 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -132,11 +132,14 @@ enum { LV_STYLE_PROP_INIT(LV_STYLE_OVERLAY_COLOR, 0x9, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_INHERIT), LV_STYLE_PROP_INIT(LV_STYLE_OVERLAY_OPA, 0x9, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_INHERIT), - LV_STYLE_PROP_INIT(LV_STYLE_SCROLLBAR_WIDTH, 0xA, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE), - - + LV_STYLE_PROP_INIT(LV_STYLE_SIZE, 0xA, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE), + LV_STYLE_PROP_INIT(LV_STYLE_SCALE_WIDTH, 0xA, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE), + LV_STYLE_PROP_INIT(LV_STYLE_SCALE_COLOR, 0xA, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE), + LV_STYLE_PROP_INIT(LV_STYLE_SCALE_GRAD_COLOR, 0xA, LV_STYLE_ID_COLOR + 1, LV_STYLE_ATTR_NONE), + LV_STYLE_PROP_INIT(LV_STYLE_SCALE_END_COLOR, 0xA, LV_STYLE_ID_COLOR + 2, LV_STYLE_ATTR_NONE), }; + typedef uint16_t lv_style_property_t; diff --git a/src/lv_draw/lv_draw_line.c b/src/lv_draw/lv_draw_line.c index 27b63412e..def2f1ece 100644 --- a/src/lv_draw/lv_draw_line.c +++ b/src/lv_draw/lv_draw_line.c @@ -1,349 +1,346 @@ -///**lip -// * @file lv_draw_line.c -// * -// */ -// -///********************* -// * INCLUDES -// *********************/ -//#include -//#include -//#include "lv_draw.h" -//#include "lv_draw_mask.h" -//#include "lv_draw_blend.h" -//#include "../lv_core/lv_refr.h" -//#include "../lv_misc/lv_math.h" -// -///********************* -// * DEFINES -// *********************/ -// -///********************** -// * TYPEDEFS -// **********************/ -// -///********************** -// * STATIC PROTOTYPES -// **********************/ -//static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, -// const lv_style_t * style, lv_opa_t opa_scale); -//static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, -// const lv_style_t * style, lv_opa_t opa_scale); -//static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, -// const lv_style_t * style, lv_opa_t opa_scale); -// -// -///********************** -// * STATIC VARIABLES -// **********************/ -// -///********************** -// * MACROS -// **********************/ -// -///********************** -// * GLOBAL FUNCTIONS -// **********************/ -// -///** -// * Draw a line -// * @param point1 first point of the line -// * @param point2 second point of the line -// * @param mask the line will be drawn only on this area -// * @param style pointer to a line's style -// * @param opa_scale scale down all opacities by the factor -// */ -//void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, -// const lv_style_t * style, lv_opa_t opa_scale) -//{ -// if(style->line.width == 0) return; -// if(point1->x == point2->x && point1->y == point2->y) return; -// -// lv_area_t clip_line; -// clip_line.x1 = LV_MATH_MIN(point1->x, point2->x) - style->line.width/2; -// clip_line.x2 = LV_MATH_MAX(point1->x, point2->x) + style->line.width/2; -// clip_line.y1 = LV_MATH_MIN(point1->y, point2->y) - style->line.width/2; -// clip_line.y2 = LV_MATH_MAX(point1->y, point2->y) + style->line.width/2; -// -// bool is_common; -// is_common = lv_area_intersect(&clip_line, &clip_line, clip); -// if(!is_common) return; -// -// if(point1->y == point2->y) draw_line_hor(point1, point2, &clip_line, style, opa_scale); -// else if(point1->x == point2->x) draw_line_ver(point1, point2, &clip_line, style, opa_scale); -// else draw_line_skew(point1, point2, &clip_line, style, opa_scale); -//} -// -///********************** -// * STATIC FUNCTIONS -// **********************/ -// -//static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, -// const lv_style_t * style, lv_opa_t opa_scale) -//{ -// lv_opa_t opa = style->line.opa; -// if(opa_scale != LV_OPA_COVER) opa = (opa * opa_scale) >> 8; -// -// 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; -// -// lv_coord_t w = style->line.width - 1; -// lv_coord_t w_half0 = w >> 1; -// lv_coord_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/ -// -// -// int16_t other_mask_cnt = lv_draw_mask_get_cnt(); -// -// lv_area_t draw_area; -// draw_area.x1 = LV_MATH_MIN(point1->x, point2->x); -// draw_area.x2 = LV_MATH_MAX(point1->x, point2->x) - 1; -// draw_area.y1 = point1->y - w_half1; -// draw_area.y2 = point1->y + w_half0; -// -// /*If there is no mask then simply draw a rectangle*/ -// if(other_mask_cnt == 0) { -// lv_blend_fill(clip, &draw_area, -// style->line.color, NULL, LV_DRAW_MASK_RES_FULL_COVER,opa, -// LV_BLEND_MODE_NORMAL); -// } -// /*If there other mask apply it*/ -// else { -// /* Get clipped fill area which is the real draw area. -// * It is always the same or inside `fill_area` */ -// bool is_common; -// is_common = lv_area_intersect(&draw_area, clip, &draw_area); -// if(!is_common) return; -// -// /* Now `draw_area` has absolute coordinates. -// * Make it relative to `disp_area` to simplify draw to `disp_buf`*/ -// draw_area.x1 -= vdb->area.x1; -// draw_area.y1 -= vdb->area.y1; -// draw_area.x2 -= vdb->area.x1; -// draw_area.y2 -= vdb->area.y1; -// -// lv_coord_t draw_area_w = lv_area_get_width(&draw_area); -// -// lv_area_t fill_area; -// fill_area.x1 = draw_area.x1 + disp_area->x1; -// fill_area.x2 = draw_area.x2 + disp_area->x1; -// fill_area.y1 = draw_area.y1 + disp_area->y1; -// fill_area.y2 = fill_area.y1; -// -// lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w); -// lv_coord_t h; -// lv_draw_mask_res_t mask_res; -// for(h = draw_area.y1; h <= draw_area.y2; h++) { -// memset(mask_buf, LV_OPA_COVER, draw_area_w); -// mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w); -// -// lv_blend_fill(clip, &fill_area, -// style->line.color, mask_buf, mask_res, style->line.opa, -// style->line.blend_mode); -// -// fill_area.y1++; -// fill_area.y2++; -// } -// lv_mem_buf_release(mask_buf); -// } -//} -// -// -//static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, -// const lv_style_t * style, lv_opa_t opa_scale) -//{ -// lv_opa_t opa = style->line.opa; -// if(opa_scale != LV_OPA_COVER) opa = (opa * opa_scale) >> 8; -// -// 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; -// -// lv_coord_t w = style->line.width - 1; -// lv_coord_t w_half0 = w >> 1; -// lv_coord_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/ -// -// -// int16_t other_mask_cnt = lv_draw_mask_get_cnt(); -// -// lv_area_t draw_area; -// draw_area.x1 = point1->x - w_half1; -// draw_area.x2 = point1->x + w_half0; -// draw_area.y1 = LV_MATH_MIN(point1->y, point2->y); -// draw_area.y2 = LV_MATH_MAX(point1->y, point2->y) - 1; -// -// /*If there is no mask then simply draw a rectangle*/ -// if(other_mask_cnt == 0) { -// -// lv_blend_fill(clip, &draw_area, -// style->line.color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, -// style->line.blend_mode); -// } -// /*If there other mask apply it*/ -// else { -// /* Get clipped fill area which is the real draw area. -// * It is always the same or inside `fill_area` */ -// bool is_common; -// is_common = lv_area_intersect(&draw_area, clip, &draw_area); -// if(!is_common) return; -// -// /* Now `draw_area` has absolute coordinates. -// * Make it relative to `disp_area` to simplify draw to `disp_buf`*/ -// draw_area.x1 -= vdb->area.x1; -// draw_area.y1 -= vdb->area.y1; -// draw_area.x2 -= vdb->area.x1; -// draw_area.y2 -= vdb->area.y1; -// -// lv_coord_t draw_area_w = lv_area_get_width(&draw_area); -// -// lv_area_t fill_area; -// fill_area.x1 = draw_area.x1 + disp_area->x1; -// fill_area.x2 = draw_area.x2 + disp_area->x1; -// fill_area.y1 = draw_area.y1 + disp_area->y1; -// fill_area.y2 = fill_area.y1; -// -// lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w); -// lv_coord_t h; -// lv_draw_mask_res_t mask_res; -// for(h = draw_area.y1; h <= draw_area.y2; h++) { -// memset(mask_buf, LV_OPA_COVER, draw_area_w); -// mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w); -// -// lv_blend_fill(clip, &fill_area, -// style->line.color, mask_buf, mask_res, style->line.opa, -// LV_BLEND_MODE_NORMAL); -// -// fill_area.y1++; -// fill_area.y2++; -// } -// lv_mem_buf_release(mask_buf); -// } -//} -// -// -//static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, -// const lv_style_t * style, lv_opa_t opa_scale) -//{ -// lv_opa_t opa = style->line.opa; -// if(opa_scale != LV_OPA_COVER) opa = (opa * opa_scale) >> 8; -// -// /*Keep the great y in p1*/ -// lv_point_t p1; -// lv_point_t p2; -// if(point1->y < point2->y) { -// p1.y = point1->y; -// p2.y = point2->y; -// p1.x = point1->x; -// p2.x = point2->x; -// } else { -// p1.y = point2->y; -// p2.y = point1->y; -// p1.x = point2->x; -// p2.x = point1->x; -// } -// -// lv_coord_t xdiff = p2.x - p1.x; -// lv_coord_t ydiff = p2.y - p1.y; -// bool flat = LV_MATH_ABS(xdiff) > LV_MATH_ABS(ydiff) ? true : false; -// -// static const uint8_t wcorr[] = { -// 128, 128, 128, 129, 129, 130, 130, 131, -// 132, 133, 134, 135, 137, 138, 140, 141, -// 143, 145, 147, 149, 151, 153, 155, 158, -// 160, 162, 165, 167, 170, 173, 175, 178, -// 181, -// }; -// -// lv_coord_t w = style->line.width; -// lv_coord_t wcorr_i = 0; -// if(flat) wcorr_i = (LV_MATH_ABS(ydiff) << 5) / LV_MATH_ABS(xdiff); -// else wcorr_i = (LV_MATH_ABS(xdiff) << 5) / LV_MATH_ABS(ydiff); -// -// w = (w * wcorr[wcorr_i]) >> 7; -// lv_coord_t w_half0 = w >> 1; -// lv_coord_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/ -// -// lv_area_t draw_area; -// draw_area.x1 = LV_MATH_MIN(p1.x, p2.x) - w; -// draw_area.x2 = LV_MATH_MAX(p1.x, p2.x) + w; -// draw_area.y1 = LV_MATH_MIN(p1.y, p2.y) - w; -// draw_area.y2 = LV_MATH_MAX(p1.y, p2.y) + w; -// -// /* Get the union of `coords` and `clip`*/ -// /* `clip` is already truncated to the `vdb` size -// * in 'lv_refr_area' function */ -// bool is_common = lv_area_intersect(&draw_area, &draw_area, clip); -// if(is_common == false) return; -// -// lv_draw_mask_line_param_t mask_left_param; -// lv_draw_mask_line_param_t mask_right_param; -// lv_draw_mask_line_param_t mask_top_param; -// lv_draw_mask_line_param_t mask_bottom_param; -// -// if(flat) { -// if(xdiff > 0) { -// lv_draw_mask_line_points_init(&mask_left_param, p1.x, p1.y - w_half0, p2.x, p2.y - w_half0, LV_DRAW_MASK_LINE_SIDE_LEFT); -// lv_draw_mask_line_points_init(&mask_right_param, p1.x, p1.y + w_half1, p2.x, p2.y + w_half1, LV_DRAW_MASK_LINE_SIDE_RIGHT); -// } else { -// lv_draw_mask_line_points_init(&mask_left_param, p1.x, p1.y + w_half1, p2.x, p2.y + w_half1, LV_DRAW_MASK_LINE_SIDE_LEFT); -// lv_draw_mask_line_points_init(&mask_right_param, p1.x, p1.y - w_half0, p2.x, p2.y - w_half0, LV_DRAW_MASK_LINE_SIDE_RIGHT); -// } -// } else { -// lv_draw_mask_line_points_init(&mask_left_param, p1.x + w_half1, p1.y, p2.x + w_half1, p2.y, LV_DRAW_MASK_LINE_SIDE_LEFT); -// lv_draw_mask_line_points_init(&mask_right_param, p1.x - w_half0, p1.y, p2.x - w_half0, p2.y, LV_DRAW_MASK_LINE_SIDE_RIGHT); -// } -// -// /*Use the normal vector for the endings*/ -// lv_draw_mask_line_points_init(&mask_top_param, p1.x, p1.y, p1.x - ydiff, p1.y + xdiff, LV_DRAW_MASK_LINE_SIDE_BOTTOM); -// lv_draw_mask_line_points_init(&mask_bottom_param, p2.x, p2.y,p2.x - ydiff, p2.y + xdiff, LV_DRAW_MASK_LINE_SIDE_TOP); -// -// int16_t mask_left_id = lv_draw_mask_add(&mask_left_param, NULL); -// int16_t mask_right_id = lv_draw_mask_add(&mask_right_param, NULL); -// int16_t mask_top_id = lv_draw_mask_add(&mask_top_param, NULL); -// int16_t mask_bottom_id = lv_draw_mask_add(&mask_bottom_param, NULL); -// -// 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; -// -// /*Store the coordinates of the `draw_a` relative to the VDB */ -// draw_area.x1 -= disp_area->x1; -// draw_area.y1 -= disp_area->y1; -// draw_area.x2 -= disp_area->x1; -// draw_area.y2 -= disp_area->y1; -// -// lv_coord_t draw_area_w = lv_area_get_width(&draw_area); -// -// /*Draw the background line by line*/ -// lv_coord_t h; -// lv_draw_mask_res_t mask_res; -// lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w); -// lv_area_t fill_area; -// fill_area.x1 = draw_area.x1 + disp_area->x1; -// fill_area.x2 = draw_area.x2 + disp_area->x1; -// fill_area.y1 = draw_area.y1 + disp_area->y1; -// fill_area.y2 = fill_area.y1; -// -// /*Fill the first row with 'color'*/ -// for(h = draw_area.y1; h <= draw_area.y2; h++) { -// memset(mask_buf, LV_OPA_COVER, draw_area_w); -// mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w); -// -// lv_blend_fill(clip, &fill_area, -// style->line.color, mask_buf, mask_res, opa, -// style->line.blend_mode); -// -// fill_area.y1++; -// fill_area.y2++; -// } -// -// lv_mem_buf_release(mask_buf); -// -// lv_draw_mask_remove_id(mask_left_id); -// lv_draw_mask_remove_id(mask_right_id); -// lv_draw_mask_remove_id(mask_top_id); -// lv_draw_mask_remove_id(mask_bottom_id); -//} +/**lip + * @file lv_draw_line.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include +#include +#include "lv_draw.h" +#include "lv_draw_mask.h" +#include "lv_draw_blend.h" +#include "../lv_core/lv_refr.h" +#include "../lv_misc/lv_math.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, lv_draw_line_dsc_t * dsc); +static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, lv_draw_line_dsc_t * dsc); +static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, lv_draw_line_dsc_t * dsc); + + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc) +{ + memset(dsc, 0x00, sizeof(lv_draw_line_dsc_t)); + dsc->width = 1; + dsc->opa = LV_OPA_COVER; +} + +/** + * Draw a line + * @param point1 first point of the line + * @param point2 second point of the line + * @param mask the line will be drawn only on this area + * @param style pointer to a line's style + * @param opa_scale scale down all opacities by the factor + */ +void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, lv_draw_line_dsc_t * dsc) +{ + if(dsc->width == 0) return; + if(point1->x == point2->x && point1->y == point2->y) return; + + lv_area_t clip_line; + clip_line.x1 = LV_MATH_MIN(point1->x, point2->x) - dsc->width/2; + clip_line.x2 = LV_MATH_MAX(point1->x, point2->x) + dsc->width/2; + clip_line.y1 = LV_MATH_MIN(point1->y, point2->y) - dsc->width/2; + clip_line.y2 = LV_MATH_MAX(point1->y, point2->y) + dsc->width/2; + + bool is_common; + is_common = lv_area_intersect(&clip_line, &clip_line, clip); + if(!is_common) return; + + if(point1->y == point2->y) draw_line_hor(point1, point2, &clip_line, dsc); + else if(point1->x == point2->x) draw_line_ver(point1, point2, &clip_line, dsc); + else draw_line_skew(point1, point2, &clip_line, dsc); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, lv_draw_line_dsc_t * dsc) +{ + lv_opa_t opa = dsc->opa; + + 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; + + lv_coord_t w = dsc->width - 1; + lv_coord_t w_half0 = w >> 1; + lv_coord_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/ + + + int16_t other_mask_cnt = lv_draw_mask_get_cnt(); + + lv_area_t draw_area; + draw_area.x1 = LV_MATH_MIN(point1->x, point2->x); + draw_area.x2 = LV_MATH_MAX(point1->x, point2->x) - 1; + draw_area.y1 = point1->y - w_half1; + draw_area.y2 = point1->y + w_half0; + + /*If there is no mask then simply draw a rectangle*/ + if(other_mask_cnt == 0) { + lv_blend_fill(clip, &draw_area, + dsc->color, NULL, LV_DRAW_MASK_RES_FULL_COVER,opa, + LV_BLEND_MODE_NORMAL); + } + /*If there other mask apply it*/ + else { + /* Get clipped fill area which is the real draw area. + * It is always the same or inside `fill_area` */ + bool is_common; + is_common = lv_area_intersect(&draw_area, clip, &draw_area); + if(!is_common) return; + + /* Now `draw_area` has absolute coordinates. + * Make it relative to `disp_area` to simplify draw to `disp_buf`*/ + draw_area.x1 -= vdb->area.x1; + draw_area.y1 -= vdb->area.y1; + draw_area.x2 -= vdb->area.x1; + draw_area.y2 -= vdb->area.y1; + + lv_coord_t draw_area_w = lv_area_get_width(&draw_area); + + lv_area_t fill_area; + fill_area.x1 = draw_area.x1 + disp_area->x1; + fill_area.x2 = draw_area.x2 + disp_area->x1; + fill_area.y1 = draw_area.y1 + disp_area->y1; + fill_area.y2 = fill_area.y1; + + lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w); + lv_coord_t h; + lv_draw_mask_res_t mask_res; + for(h = draw_area.y1; h <= draw_area.y2; h++) { + memset(mask_buf, LV_OPA_COVER, draw_area_w); + mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w); + + lv_blend_fill(clip, &fill_area, + dsc->color, mask_buf, mask_res, dsc->opa, + dsc->blend_mode); + + fill_area.y1++; + fill_area.y2++; + } + lv_mem_buf_release(mask_buf); + } +} + + +static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, lv_draw_line_dsc_t * dsc) +{ + lv_opa_t opa = dsc->opa; + + 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; + + lv_coord_t w = dsc->width - 1; + lv_coord_t w_half0 = w >> 1; + lv_coord_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/ + + + int16_t other_mask_cnt = lv_draw_mask_get_cnt(); + + lv_area_t draw_area; + draw_area.x1 = point1->x - w_half1; + draw_area.x2 = point1->x + w_half0; + draw_area.y1 = LV_MATH_MIN(point1->y, point2->y); + draw_area.y2 = LV_MATH_MAX(point1->y, point2->y) - 1; + + /*If there is no mask then simply draw a rectangle*/ + if(other_mask_cnt == 0) { + + lv_blend_fill(clip, &draw_area, + dsc->color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, + dsc->blend_mode); + } + /*If there other mask apply it*/ + else { + /* Get clipped fill area which is the real draw area. + * It is always the same or inside `fill_area` */ + bool is_common; + is_common = lv_area_intersect(&draw_area, clip, &draw_area); + if(!is_common) return; + + /* Now `draw_area` has absolute coordinates. + * Make it relative to `disp_area` to simplify draw to `disp_buf`*/ + draw_area.x1 -= vdb->area.x1; + draw_area.y1 -= vdb->area.y1; + draw_area.x2 -= vdb->area.x1; + draw_area.y2 -= vdb->area.y1; + + lv_coord_t draw_area_w = lv_area_get_width(&draw_area); + + lv_area_t fill_area; + fill_area.x1 = draw_area.x1 + disp_area->x1; + fill_area.x2 = draw_area.x2 + disp_area->x1; + fill_area.y1 = draw_area.y1 + disp_area->y1; + fill_area.y2 = fill_area.y1; + + lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w); + lv_coord_t h; + lv_draw_mask_res_t mask_res; + for(h = draw_area.y1; h <= draw_area.y2; h++) { + memset(mask_buf, LV_OPA_COVER, draw_area_w); + mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w); + + lv_blend_fill(clip, &fill_area, + dsc->color, mask_buf, mask_res, dsc->opa, + LV_BLEND_MODE_NORMAL); + + fill_area.y1++; + fill_area.y2++; + } + lv_mem_buf_release(mask_buf); + } +} + + +static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, lv_draw_line_dsc_t * dsc) +{ + lv_opa_t opa = dsc->opa; + + /*Keep the great y in p1*/ + lv_point_t p1; + lv_point_t p2; + if(point1->y < point2->y) { + p1.y = point1->y; + p2.y = point2->y; + p1.x = point1->x; + p2.x = point2->x; + } else { + p1.y = point2->y; + p2.y = point1->y; + p1.x = point2->x; + p2.x = point1->x; + } + + lv_coord_t xdiff = p2.x - p1.x; + lv_coord_t ydiff = p2.y - p1.y; + bool flat = LV_MATH_ABS(xdiff) > LV_MATH_ABS(ydiff) ? true : false; + + static const uint8_t wcorr[] = { + 128, 128, 128, 129, 129, 130, 130, 131, + 132, 133, 134, 135, 137, 138, 140, 141, + 143, 145, 147, 149, 151, 153, 155, 158, + 160, 162, 165, 167, 170, 173, 175, 178, + 181, + }; + + lv_coord_t w = dsc->width; + lv_coord_t wcorr_i = 0; + if(flat) wcorr_i = (LV_MATH_ABS(ydiff) << 5) / LV_MATH_ABS(xdiff); + else wcorr_i = (LV_MATH_ABS(xdiff) << 5) / LV_MATH_ABS(ydiff); + + w = (w * wcorr[wcorr_i]) >> 7; + lv_coord_t w_half0 = w >> 1; + lv_coord_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/ + + lv_area_t draw_area; + draw_area.x1 = LV_MATH_MIN(p1.x, p2.x) - w; + draw_area.x2 = LV_MATH_MAX(p1.x, p2.x) + w; + draw_area.y1 = LV_MATH_MIN(p1.y, p2.y) - w; + draw_area.y2 = LV_MATH_MAX(p1.y, p2.y) + w; + + /* Get the union of `coords` and `clip`*/ + /* `clip` is already truncated to the `vdb` size + * in 'lv_refr_area' function */ + bool is_common = lv_area_intersect(&draw_area, &draw_area, clip); + if(is_common == false) return; + + lv_draw_mask_line_param_t mask_left_param; + lv_draw_mask_line_param_t mask_right_param; + lv_draw_mask_line_param_t mask_top_param; + lv_draw_mask_line_param_t mask_bottom_param; + + if(flat) { + if(xdiff > 0) { + lv_draw_mask_line_points_init(&mask_left_param, p1.x, p1.y - w_half0, p2.x, p2.y - w_half0, LV_DRAW_MASK_LINE_SIDE_LEFT); + lv_draw_mask_line_points_init(&mask_right_param, p1.x, p1.y + w_half1, p2.x, p2.y + w_half1, LV_DRAW_MASK_LINE_SIDE_RIGHT); + } else { + lv_draw_mask_line_points_init(&mask_left_param, p1.x, p1.y + w_half1, p2.x, p2.y + w_half1, LV_DRAW_MASK_LINE_SIDE_LEFT); + lv_draw_mask_line_points_init(&mask_right_param, p1.x, p1.y - w_half0, p2.x, p2.y - w_half0, LV_DRAW_MASK_LINE_SIDE_RIGHT); + } + } else { + lv_draw_mask_line_points_init(&mask_left_param, p1.x + w_half1, p1.y, p2.x + w_half1, p2.y, LV_DRAW_MASK_LINE_SIDE_LEFT); + lv_draw_mask_line_points_init(&mask_right_param, p1.x - w_half0, p1.y, p2.x - w_half0, p2.y, LV_DRAW_MASK_LINE_SIDE_RIGHT); + } + + /*Use the normal vector for the endings*/ + lv_draw_mask_line_points_init(&mask_top_param, p1.x, p1.y, p1.x - ydiff, p1.y + xdiff, LV_DRAW_MASK_LINE_SIDE_BOTTOM); + lv_draw_mask_line_points_init(&mask_bottom_param, p2.x, p2.y,p2.x - ydiff, p2.y + xdiff, LV_DRAW_MASK_LINE_SIDE_TOP); + + int16_t mask_left_id = lv_draw_mask_add(&mask_left_param, NULL); + int16_t mask_right_id = lv_draw_mask_add(&mask_right_param, NULL); + int16_t mask_top_id = lv_draw_mask_add(&mask_top_param, NULL); + int16_t mask_bottom_id = lv_draw_mask_add(&mask_bottom_param, NULL); + + 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; + + /*Store the coordinates of the `draw_a` relative to the VDB */ + draw_area.x1 -= disp_area->x1; + draw_area.y1 -= disp_area->y1; + draw_area.x2 -= disp_area->x1; + draw_area.y2 -= disp_area->y1; + + lv_coord_t draw_area_w = lv_area_get_width(&draw_area); + + /*Draw the background line by line*/ + lv_coord_t h; + lv_draw_mask_res_t mask_res; + lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w); + lv_area_t fill_area; + fill_area.x1 = draw_area.x1 + disp_area->x1; + fill_area.x2 = draw_area.x2 + disp_area->x1; + fill_area.y1 = draw_area.y1 + disp_area->y1; + fill_area.y2 = fill_area.y1; + + /*Fill the first row with 'color'*/ + for(h = draw_area.y1; h <= draw_area.y2; h++) { + memset(mask_buf, LV_OPA_COVER, draw_area_w); + mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w); + + lv_blend_fill(clip, &fill_area, + dsc->color, mask_buf, mask_res, opa, + dsc->blend_mode); + + fill_area.y1++; + fill_area.y2++; + } + + lv_mem_buf_release(mask_buf); + + lv_draw_mask_remove_id(mask_left_id); + lv_draw_mask_remove_id(mask_right_id); + lv_draw_mask_remove_id(mask_top_id); + lv_draw_mask_remove_id(mask_bottom_id); +} diff --git a/src/lv_draw/lv_draw_line.h b/src/lv_draw/lv_draw_line.h index 208bd0510..54c91da3d 100644 --- a/src/lv_draw/lv_draw_line.h +++ b/src/lv_draw/lv_draw_line.h @@ -21,6 +21,12 @@ extern "C" { /********************** * TYPEDEFS **********************/ +typedef struct { + lv_color_t color; + lv_style_value_t width; + lv_opa_t opa; + lv_blend_mode_t blend_mode; +}lv_draw_line_dsc_t; /********************** * GLOBAL PROTOTYPES @@ -34,9 +40,9 @@ extern "C" { * @param style pointer to a line's style * @param opa_scale scale down all opacities by the factor */ -void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * mask, - const lv_style_t * style, lv_opa_t opa_scale); +void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * mask, lv_draw_line_dsc_t * dsc); +void lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc); /********************** * MACROS **********************/ diff --git a/src/lv_objx/lv_gauge.c b/src/lv_objx/lv_gauge.c index 2308f76f1..1dfb091f1 100644 --- a/src/lv_objx/lv_gauge.c +++ b/src/lv_objx/lv_gauge.c @@ -38,7 +38,8 @@ **********************/ static lv_design_res_t lv_gauge_design(lv_obj_t * gauge, const lv_area_t * clip_area, lv_design_mode_t mode); static lv_res_t lv_gauge_signal(lv_obj_t * gauge, lv_signal_t sign, void * param); -static void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask); +static lv_style_dsc_t * lv_gauge_get_style(lv_obj_t * gauge, uint8_t part); +static void lv_gauge_draw_labels(lv_obj_t * gauge, const lv_area_t * mask); static void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * clip_area); /********************** @@ -101,13 +102,10 @@ lv_obj_t * lv_gauge_create(lv_obj_t * par, const lv_obj_t * copy) lv_gauge_set_critical_value(new_gauge, 80); lv_obj_set_size(new_gauge, 2 * LV_DPI, 2 * LV_DPI); - /*Set the default styles*/ - lv_theme_t * th = lv_theme_get_current(); - if(th) { - lv_gauge_set_style(new_gauge, LV_GAUGE_STYLE_MAIN, th->style.gauge); - } else { - lv_gauge_set_style(new_gauge, LV_GAUGE_STYLE_MAIN, &lv_style_pretty_color); - } + lv_style_dsc_reset(&new_gauge->style_dsc); + _ot(new_gauge, LV_GAUGE_PART_MAIN, GAUGE); + _ot(new_gauge, LV_GAUGE_PART_STRONG, GAUGE_STRONG); + } /*Copy an existing gauge*/ else { @@ -120,7 +118,7 @@ lv_obj_t * lv_gauge_create(lv_obj_t * par, const lv_obj_t * copy) } ext->label_count = copy_ext->label_count; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(new_gauge); +// lv_obj_refresh_style(new_gauge); } LV_LOG_INFO("gauge created"); @@ -351,35 +349,21 @@ static lv_design_res_t lv_gauge_design(lv_obj_t * gauge, const lv_area_t * clip_ } /*Draw the object*/ else if(mode == LV_DESIGN_DRAW_MAIN) { - - /* Store the real pointer because of 'lv_group' - * If the object is in focus 'lv_obj_get_style()' will give a pointer to tmp style - * and to the real object style. It is important because of style change tricks below*/ - const lv_style_t * style_ori_p = gauge->style_p; - const lv_style_t * style = lv_obj_get_style(gauge); lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge); - - lv_gauge_draw_scale(gauge, clip_area); + lv_gauge_draw_labels(gauge, clip_area); /*Draw the ancestor line meter with max value to show the rainbow like line colors*/ uint16_t line_cnt_tmp = ext->lmeter.line_cnt; ancestor_design(gauge, clip_area, mode); /*To draw lines*/ - /*Temporally modify the line meter to draw longer lines where labels are*/ - lv_style_t style_tmp; - lv_style_copy(&style_tmp, style); + + lv_lmeter_draw_scale(gauge, clip_area, LV_GAUGE_PART_MAIN); + ext->lmeter.line_cnt = ext->label_count; /*Only to labels*/ - style_tmp.body.padding.left = style_tmp.body.padding.left * 2; /*Longer lines*/ - style_tmp.body.padding.right = style_tmp.body.padding.right * 2; /*Longer lines*/ - gauge->style_p = &style_tmp; - - ancestor_design(gauge, clip_area, mode); /*To draw lines*/ - + lv_lmeter_draw_scale(gauge, clip_area, LV_GAUGE_PART_STRONG); ext->lmeter.line_cnt = line_cnt_tmp; /*Restore the parameters*/ - gauge->style_p = style_ori_p; /*Restore the ORIGINAL style pointer*/ lv_gauge_draw_needle(gauge, clip_area); - } /*Post draw when the children are drawn*/ else if(mode == LV_DESIGN_DRAW_POST) { @@ -399,6 +383,12 @@ static lv_design_res_t lv_gauge_design(lv_obj_t * gauge, const lv_area_t * clip_ static lv_res_t lv_gauge_signal(lv_obj_t * gauge, 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_gauge_get_style(gauge, **type_p); + return LV_RES_OK; + } /* Include the ancient signal function */ res = ancestor_signal(gauge, sign, param); @@ -413,20 +403,45 @@ static lv_res_t lv_gauge_signal(lv_obj_t * gauge, lv_signal_t sign, void * param return res; } +/** + * Get the style descriptor of a part of the object + * @param page pointer the object + * @param part the part from `lv_gauge_part_t`. (LV_GAUGE_PART_...) + * @return pointer to the style descriptor of the specified part + */ +static lv_style_dsc_t * lv_gauge_get_style(lv_obj_t * gauge, uint8_t part) +{ + LV_ASSERT_OBJ(gauge, LV_OBJX_NAME); + lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge); + lv_style_dsc_t * style_dsc_p; + + switch(part) { + case LV_GAUGE_PART_MAIN: + style_dsc_p = &gauge->style_dsc; + break; + case LV_GAUGE_PART_STRONG: + style_dsc_p = &ext->style_strong; + break; + default: + style_dsc_p = NULL; + } + + return style_dsc_p; +} /** * Draw the scale on a gauge * @param gauge pointer to gauge object * @param mask mask of drawing */ -static void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask) +static void lv_gauge_draw_labels(lv_obj_t * gauge, const lv_area_t * mask) { char scale_txt[16]; lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge); - const lv_style_t * style = lv_obj_get_style(gauge); - lv_opa_t opa_scale = lv_obj_get_opa_scale(gauge); - lv_coord_t r = lv_obj_get_width(gauge) / 2 - (3 * style->body.padding.left) - style->body.padding.inner; + lv_style_value_t scale_width = lv_obj_get_style_value(gauge, LV_GAUGE_PART_STRONG, LV_STYLE_SCALE_WIDTH); + lv_style_value_t txt_pad = lv_obj_get_style_value(gauge, LV_GAUGE_PART_STRONG, LV_STYLE_PAD_INNER); + lv_coord_t r = lv_obj_get_width(gauge) / 2 - scale_width - txt_pad; lv_coord_t x_ofs = lv_obj_get_width(gauge) / 2 + gauge->coords.x1; lv_coord_t y_ofs = lv_obj_get_height(gauge) / 2 + gauge->coords.y1; int16_t scale_angle = lv_lmeter_get_scale_angle(gauge); @@ -435,6 +450,10 @@ static void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask) int16_t min = lv_gauge_get_min_value(gauge); int16_t max = lv_gauge_get_max_value(gauge); + lv_draw_label_dsc_t label_dsc; + lv_draw_label_dsc_init(&label_dsc); + lv_obj_init_draw_label_dsc(gauge, LV_GAUGE_PART_STRONG, &label_dsc); + uint8_t i; for(i = 0; i < label_num; i++) { /*Calculate the position a scale label*/ @@ -452,7 +471,7 @@ static void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask) lv_area_t label_cord; lv_point_t label_size; - lv_txt_get_size(&label_size, scale_txt, style->text.font, style->text.letter_space, style->text.line_space, + lv_txt_get_size(&label_size, scale_txt, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, LV_TXT_FLAG_NONE); /*Draw the label*/ @@ -461,7 +480,7 @@ static void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask) label_cord.x2 = label_cord.x1 + label_size.x; label_cord.y2 = label_cord.y1 + label_size.y; - lv_draw_label(&label_cord, mask, style, opa_scale, scale_txt, LV_TXT_FLAG_NONE, NULL, NULL, NULL, lv_obj_get_base_dir(gauge)); + lv_draw_label(&label_cord, mask, &label_dsc, scale_txt, NULL); } } /** @@ -471,12 +490,10 @@ static void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask) */ static void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * clip_area) { - lv_style_t style_needle; lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge); - const lv_style_t * style = lv_gauge_get_style(gauge, LV_GAUGE_STYLE_MAIN); - lv_opa_t opa_scale = lv_obj_get_opa_scale(gauge); - lv_coord_t r = lv_obj_get_width(gauge) / 2 - style->body.padding.left; + lv_style_value_t scale_width = lv_obj_get_style_value(gauge, LV_GAUGE_PART_STRONG, LV_STYLE_SCALE_WIDTH); + lv_coord_t r = lv_obj_get_width(gauge) / 2 - scale_width; lv_coord_t x_ofs = lv_obj_get_width(gauge) / 2 + gauge->coords.x1; lv_coord_t y_ofs = lv_obj_get_height(gauge) / 2 + gauge->coords.y1; uint16_t angle = lv_lmeter_get_scale_angle(gauge); @@ -487,9 +504,17 @@ static void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * clip_area) lv_point_t p_end; uint8_t i; - lv_style_copy(&style_needle, style); - if(ext->needle_colors != NULL) { - style_needle.image.intense = LV_OPA_COVER; + lv_draw_line_dsc_t line_dsc; + lv_draw_line_dsc_init(&line_dsc); + lv_obj_init_draw_line_dsc(gauge, LV_GAUGE_PART_MAIN, &line_dsc); + + lv_draw_img_dsc_t img_dsc; + if(ext->needle_img == NULL) { + lv_draw_img_dsc_init(&img_dsc); + lv_obj_init_draw_img_dsc(gauge, LV_GAUGE_PART_MAIN, &img_dsc); + img_dsc.recolor_opa = LV_OPA_COVER; + img_dsc.pivot.x = ext->needle_img_pivot.x; + img_dsc.pivot.y = ext->needle_img_pivot.y; } p_mid.x = x_ofs; @@ -506,10 +531,9 @@ static void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * clip_area) p_end.x = (lv_trigo_sin(needle_angle + 90) * r) / LV_TRIGO_SIN_MAX + x_ofs; /*Draw the needle with the corresponding color*/ - if(ext->needle_colors != NULL) - style_needle.line.color = ext->needle_colors[i]; + if(ext->needle_colors != NULL) line_dsc.color = ext->needle_colors[i]; - lv_draw_line(&p_mid, &p_end, clip_area, &style_needle, opa_scale); + lv_draw_line(&p_mid, &p_end, clip_area, &line_dsc); } /*Draw image*/ else { @@ -523,26 +547,25 @@ static void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * clip_area) a.y2 = a.y1 + info.h - 1; if(ext->needle_colors != NULL) - style_needle.image.color = ext->needle_colors[i]; + img_dsc.recolor = ext->needle_colors[i]; - lv_draw_img(&a, clip_area, ext->needle_img, &style_needle, needle_angle, &ext->needle_img_pivot, LV_IMG_ZOOM_NONE, true, opa_scale); + + img_dsc.angle = needle_angle; + lv_draw_img(&a, clip_area, ext->needle_img, &img_dsc); } } - /*Draw the needle middle area*/ - lv_style_t style_neddle_mid; - lv_style_copy(&style_neddle_mid, &lv_style_plain); - style_neddle_mid.body.main_color = style->body.border.color; - style_neddle_mid.body.grad_color = style->body.border.color; - style_neddle_mid.body.radius = LV_RADIUS_CIRCLE; + lv_draw_rect_dsc_t mid_dsc; + lv_draw_rect_dsc_init(&mid_dsc); + lv_obj_init_draw_rect_dsc(gauge, LV_GAUGE_PART_MAIN, &mid_dsc); + lv_style_value_t size = lv_obj_get_style_value(gauge, LV_GAUGE_PART_MAIN, LV_STYLE_SIZE) / 2; lv_area_t nm_cord; - nm_cord.x1 = x_ofs - style->body.radius; - nm_cord.y1 = y_ofs - style->body.radius; - nm_cord.x2 = x_ofs + style->body.radius; - nm_cord.y2 = y_ofs + style->body.radius; - - lv_draw_rect(&nm_cord, clip_area, &style_neddle_mid, lv_obj_get_opa_scale(gauge)); + nm_cord.x1 = x_ofs - size; + nm_cord.y1 = y_ofs - size; + nm_cord.x2 = x_ofs + size; + nm_cord.y2 = y_ofs + size; + lv_draw_rect(&nm_cord, clip_area, &mid_dsc); } #endif diff --git a/src/lv_objx/lv_gauge.h b/src/lv_objx/lv_gauge.h index 012cdfa4b..e787f176a 100644 --- a/src/lv_objx/lv_gauge.h +++ b/src/lv_objx/lv_gauge.h @@ -44,13 +44,15 @@ typedef struct const lv_color_t * needle_colors; /*Color of the needles (lv_color_t my_colors[needle_num])*/ const void * needle_img; lv_point_t needle_img_pivot; + lv_style_dsc_t style_strong; uint8_t needle_count; /*Number of needles*/ uint8_t label_count; /*Number of labels on the scale*/ } lv_gauge_ext_t; /*Styles*/ enum { - LV_GAUGE_STYLE_MAIN, + LV_GAUGE_PART_MAIN, + LV_GAUGE_PART_STRONG, }; typedef uint8_t lv_gauge_style_t; @@ -239,18 +241,6 @@ lv_coord_t lv_gauge_get_needle_img_pivot_x(lv_obj_t * gauge); */ lv_coord_t lv_gauge_get_needle_img_pivot_y(lv_obj_t * gauge); -/** - * Get the style of a gauge - * @param gauge pointer to a gauge object - * @param type which style should be get (can be only `LV_GAUGE_STYLE_MAIN`) - * @return pointer to the gauge's style - */ -static inline const lv_style_t * lv_gauge_get_style(const lv_obj_t * gauge, lv_gauge_style_t type) -{ - (void)type; /*Unused*/ - return lv_obj_get_style(gauge); -} - /********************** * MACROS **********************/ diff --git a/src/lv_objx/lv_lmeter.c b/src/lv_objx/lv_lmeter.c index c9c2268e3..595b86dbd 100644 --- a/src/lv_objx/lv_lmeter.c +++ b/src/lv_objx/lv_lmeter.c @@ -85,13 +85,8 @@ lv_obj_t * lv_lmeter_create(lv_obj_t * par, const lv_obj_t * copy) if(copy == NULL) { lv_obj_set_size(new_lmeter, LV_DPI, LV_DPI); - /*Set the default styles*/ - lv_theme_t * th = lv_theme_get_current(); - if(th) { - lv_lmeter_set_style(new_lmeter, LV_LMETER_STYLE_MAIN, th->style.lmeter); - } else { - lv_lmeter_set_style(new_lmeter, LV_LMETER_STYLE_MAIN, &lv_style_pretty_color); - } + lv_style_dsc_reset(lv_obj_get_style(new_lmeter, LV_LMETER_PART_MAIN)); + _ot(new_lmeter, LV_LMETER_PART_MAIN, LMETER); } /*Copy an existing line meter*/ else { @@ -102,8 +97,8 @@ lv_obj_t * lv_lmeter_create(lv_obj_t * par, const lv_obj_t * copy) ext->max_value = copy_ext->max_value; ext->cur_value = copy_ext->cur_value; - /*Refresh the style with new signal function*/ - lv_obj_refresh_style(new_lmeter); +// /*Refresh the style with new signal function*/ +// lv_obj_refresh_style(new_lmeter); } LV_LOG_INFO("line meter created"); @@ -273,9 +268,71 @@ uint16_t lv_lmeter_get_angle_offset(lv_obj_t * lmeter) return ext->angle_ofs; } +void lv_lmeter_draw_scale(lv_obj_t * lmeter, const lv_area_t * clip_area, uint8_t part) +{ + lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter); + + lv_coord_t r_out = lv_obj_get_width(lmeter) / 2; + lv_coord_t r_in = r_out - lv_obj_get_style_value(lmeter, part, LV_STYLE_SCALE_WIDTH); + if(r_in < 1) r_in = 1; + + lv_coord_t x_ofs = lv_obj_get_width(lmeter) / 2 + lmeter->coords.x1; + lv_coord_t y_ofs = lv_obj_get_height(lmeter) / 2 + lmeter->coords.y1; + int16_t angle_ofs = ext->angle_ofs + 90 + (360 - ext->scale_angle) / 2; + int16_t level = + (int32_t)((int32_t)(ext->cur_value - ext->min_value) * ext->line_cnt) / (ext->max_value - ext->min_value); + uint8_t i; + + lv_color_t main_color = lv_obj_get_style_color(lmeter, part, LV_STYLE_SCALE_COLOR); + lv_color_t grad_color = lv_obj_get_style_color(lmeter, part, LV_STYLE_SCALE_GRAD_COLOR); + lv_color_t ina_color = lv_obj_get_style_color(lmeter, part, LV_STYLE_SCALE_END_COLOR); + + lv_draw_line_dsc_t line_dsc; + lv_draw_line_dsc_init(&line_dsc); + lv_obj_init_draw_line_dsc(lmeter, part, &line_dsc); + + for(i = 0; i < ext->line_cnt; i++) { + /*Calculate the position a scale label*/ + int16_t angle = (i * ext->scale_angle) / (ext->line_cnt - 1) + angle_ofs; + + lv_coord_t y_out = (int32_t)((int32_t)lv_trigo_sin(angle) * r_out) >> (LV_TRIGO_SHIFT - 8); + lv_coord_t x_out = (int32_t)((int32_t)lv_trigo_sin(angle + 90) * r_out) >> (LV_TRIGO_SHIFT - 8); + lv_coord_t y_in = (int32_t)((int32_t)lv_trigo_sin(angle) * r_in) >> (LV_TRIGO_SHIFT - 8); + lv_coord_t x_in = (int32_t)((int32_t)lv_trigo_sin(angle + 90) * r_in) >> (LV_TRIGO_SHIFT - 8); + + /*Rounding*/ + if(x_out <= 0) x_out = (x_out + 127) >> 8; + else x_out = (x_out - 127) >> 8; + + if(x_in <= 0) x_in = (x_in + 127) >> 8; + else x_in = (x_in - 127) >> 8; + + if(y_out <= 0) y_out = (y_out + 127) >> 8; + else y_out = (y_out - 127) >> 8; + + if(y_in <= 0) y_in = (y_in + 127) >> 8; + else y_in = (y_in - 127) >> 8; + + lv_point_t p1; + lv_point_t p2; + + p2.x = x_in + x_ofs; + p2.y = y_in + y_ofs; + + p1.x = x_out + x_ofs; + p1.y = y_out + y_ofs; + + if(i >= level) line_dsc.color = ina_color; + else line_dsc.color = lv_color_mix(grad_color, main_color, (255 * i) / ext->line_cnt); + + lv_draw_line(&p1, &p2, clip_area, &line_dsc); + } +} + /********************** * STATIC FUNCTIONS **********************/ +#include /** * Handle the drawing related tasks of the line meters @@ -295,73 +352,7 @@ static lv_design_res_t lv_lmeter_design(lv_obj_t * lmeter, const lv_area_t * cli } /*Draw the object*/ else if(mode == LV_DESIGN_DRAW_MAIN) { - lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter); - const lv_style_t * style = lv_obj_get_style(lmeter); - lv_opa_t opa_scale = lv_obj_get_opa_scale(lmeter); - lv_style_t style_tmp; - lv_style_copy(&style_tmp, style); - -#if LV_USE_GROUP - lv_group_t * g = lv_obj_get_group(lmeter); - if(lv_group_get_focused(g) == lmeter) { - style_tmp.line.width += 1; - } -#endif - - lv_coord_t r_out = lv_obj_get_width(lmeter) / 2; - lv_coord_t r_in = r_out - style->body.padding.left; - if(r_in < 1) r_in = 1; - - lv_coord_t x_ofs = lv_obj_get_width(lmeter) / 2 + lmeter->coords.x1; - lv_coord_t y_ofs = lv_obj_get_height(lmeter) / 2 + lmeter->coords.y1; - int16_t angle_ofs = ext->angle_ofs + 90 + (360 - ext->scale_angle) / 2; - int16_t level = - (int32_t)((int32_t)(ext->cur_value - ext->min_value) * ext->line_cnt) / (ext->max_value - ext->min_value); - uint8_t i; - - style_tmp.line.color = style->body.main_color; - - for(i = 0; i < ext->line_cnt; i++) { - /*Calculate the position a scale label*/ - int16_t angle = (i * ext->scale_angle) / (ext->line_cnt - 1) + angle_ofs; - - lv_coord_t y_out = (int32_t)((int32_t)lv_trigo_sin(angle) * r_out) >> (LV_TRIGO_SHIFT - 8); - lv_coord_t x_out = (int32_t)((int32_t)lv_trigo_sin(angle + 90) * r_out) >> (LV_TRIGO_SHIFT - 8); - lv_coord_t y_in = (int32_t)((int32_t)lv_trigo_sin(angle) * r_in) >> (LV_TRIGO_SHIFT - 8); - lv_coord_t x_in = (int32_t)((int32_t)lv_trigo_sin(angle + 90) * r_in) >> (LV_TRIGO_SHIFT - 8); - - /*Rounding*/ - if(x_out <= 0) x_out = (x_out + 127) >> 8; - else x_out = (x_out - 127) >> 8; - - if(x_in <= 0) x_in = (x_in + 127) >> 8; - else x_in = (x_in - 127) >> 8; - - if(y_out <= 0) y_out = (y_out + 127) >> 8; - else y_out = (y_out - 127) >> 8; - - if(y_in <= 0) y_in = (y_in + 127) >> 8; - else y_in = (y_in - 127) >> 8; - - lv_point_t p1; - lv_point_t p2; - - p2.x = x_in + x_ofs; - p2.y = y_in + y_ofs; - - p1.x = x_out + x_ofs; - p1.y = y_out + y_ofs; - - if(i >= level) - style_tmp.line.color = style->line.color; - else { - style_tmp.line.color = - lv_color_mix(style->body.grad_color, style->body.main_color, (255 * i) / ext->line_cnt); - } - - lv_draw_line(&p1, &p2, clip_area, &style_tmp, opa_scale); - } - + lv_lmeter_draw_scale(lmeter, clip_area, LV_LMETER_PART_MAIN); } /*Post draw when the children are drawn*/ else if(mode == LV_DESIGN_DRAW_POST) { @@ -390,9 +381,6 @@ static lv_res_t lv_lmeter_signal(lv_obj_t * lmeter, lv_signal_t sign, void * par /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ } else if(sign == LV_SIGNAL_STYLE_CHG) { lv_obj_refresh_ext_draw_pad(lmeter); - } else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) { - const lv_style_t * style = lv_lmeter_get_style(lmeter, LV_LMETER_STYLE_MAIN); - lmeter->ext_draw_pad = LV_MATH_MAX(lmeter->ext_draw_pad, style->line.width); } return res; diff --git a/src/lv_objx/lv_lmeter.h b/src/lv_objx/lv_lmeter.h index bf6ce959e..685846389 100644 --- a/src/lv_objx/lv_lmeter.h +++ b/src/lv_objx/lv_lmeter.h @@ -41,9 +41,9 @@ typedef struct /*Styles*/ enum { - LV_LMETER_STYLE_MAIN, + LV_LMETER_PART_MAIN, }; -typedef uint8_t lv_lmeter_style_t; +typedef uint8_t lv_lmeter_part_t; /********************** * GLOBAL PROTOTYPES @@ -92,18 +92,6 @@ void lv_lmeter_set_scale(lv_obj_t * lmeter, uint16_t angle, uint16_t line_cnt); */ void lv_lmeter_set_angle_offset(lv_obj_t * lmeter, uint16_t angle); -/** - * Set the styles of a line meter - * @param lmeter pointer to a line meter object - * @param type which style should be set (can be only `LV_LMETER_STYLE_MAIN`) - * @param style set the style of the line meter - */ -static inline void lv_lmeter_set_style(lv_obj_t * lmeter, lv_lmeter_style_t type, lv_style_t * style) -{ - (void)type; /*Unused*/ - lv_obj_set_style(lmeter, style); -} - /*===================== * Getter functions *====================*/ @@ -150,17 +138,8 @@ uint16_t lv_lmeter_get_scale_angle(const lv_obj_t * lmeter); */ uint16_t lv_lmeter_get_angle_offset(lv_obj_t * lmeter); -/** - * Get the style of a line meter - * @param lmeter pointer to a line meter object - * @param type which style should be get (can be only `LV_LMETER_STYLE_MAIN`) - * @return pointer to the line meter's style - */ -static inline const lv_style_t * lv_lmeter_get_style(const lv_obj_t * lmeter, lv_lmeter_style_t type) -{ - (void)type; /*Unused*/ - return lv_obj_get_style(lmeter); -} + +void lv_lmeter_draw_scale(lv_obj_t * lmeter, const lv_area_t * clip_area, uint8_t part); /********************** * MACROS diff --git a/src/lv_objx/lv_page.c b/src/lv_objx/lv_page.c index 2e830b115..47b2036c4 100644 --- a/src/lv_objx/lv_page.c +++ b/src/lv_objx/lv_page.c @@ -757,7 +757,7 @@ static lv_design_res_t lv_page_design(lv_obj_t * page, const lv_area_t * clip_ar static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param) { lv_res_t res; - if(sign == LV_SIGNAL_GET_STYLE) { + if(sign == LV_SIGNAL_GET_STYLE) { uint8_t ** type_p = param; lv_style_dsc_t ** style_dsc_p = param; *style_dsc_p = lv_page_get_style(page, **type_p); @@ -824,7 +824,7 @@ static lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param) } else if(sign == LV_SIGNAL_STYLE_CHG) { ext->scrl->signal_cb(ext->scrl, LV_SIGNAL_CORD_CHG, &ext->scrl->coords); - lv_style_value_t sb_width = lv_obj_get_style_value(page, LV_PAGE_PART_SCRLBAR, LV_STYLE_SCROLLBAR_WIDTH); + lv_style_value_t sb_width = lv_obj_get_style_value(page, LV_PAGE_PART_SCRLBAR, LV_STYLE_SIZE); lv_area_set_height(&ext->sb.hor_area, sb_width); lv_area_set_width(&ext->sb.ver_area, sb_width); @@ -1114,7 +1114,7 @@ static void lv_page_sb_refresh(lv_obj_t * page) lv_coord_t obj_w = lv_obj_get_width(page); lv_coord_t obj_h = lv_obj_get_height(page); - lv_style_value_t sb_width = lv_obj_get_style_value(page, LV_PAGE_PART_SCRLBAR, LV_STYLE_SCROLLBAR_WIDTH); + lv_style_value_t sb_width = lv_obj_get_style_value(page, LV_PAGE_PART_SCRLBAR, LV_STYLE_SIZE); lv_style_value_t sb_right = lv_obj_get_style_value(page, LV_PAGE_PART_SCRLBAR, LV_STYLE_PAD_RIGHT); lv_style_value_t sb_bottom = lv_obj_get_style_value(page, LV_PAGE_PART_SCRLBAR, LV_STYLE_PAD_BOTTOM); diff --git a/src/lv_objx/lv_tabview.c b/src/lv_objx/lv_tabview.c index 928d20575..37025881b 100644 --- a/src/lv_objx/lv_tabview.c +++ b/src/lv_objx/lv_tabview.c @@ -810,7 +810,7 @@ static void refr_indic_size(lv_obj_t * tabview) lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview); lv_btnm_ext_t * btnm_ext = lv_obj_get_ext_attr(ext->btns); - lv_coord_t indic_size = 10; + lv_coord_t indic_size = lv_obj_get_style_value(tabview, LV_TABVIEW_PART_INDIC, LV_STYLE_SIZE); /*Set the indicator width/height*/ lv_coord_t indic_w; diff --git a/src/lv_themes/lv_theme.h b/src/lv_themes/lv_theme.h index 74a15ed0e..a3fa7bba7 100644 --- a/src/lv_themes/lv_theme.h +++ b/src/lv_themes/lv_theme.h @@ -87,6 +87,11 @@ typedef enum { LV_THEME_TABVIEW_TAB_BG, LV_THEME_TABVIEW_TAB_SCRL, LV_THEME_TABVIEW_TAB_SCRLBAR, + + LV_THEME_LMETER, + + LV_THEME_GAUGE, + LV_THEME_GAUGE_STRONG, }lv_theme_style_t; typedef struct { diff --git a/src/lv_themes/lv_theme_alien.c b/src/lv_themes/lv_theme_alien.c index 2be851ac0..d4b4d6e48 100644 --- a/src/lv_themes/lv_theme_alien.c +++ b/src/lv_themes/lv_theme_alien.c @@ -45,7 +45,12 @@ static lv_style_t knob; #endif #if LV_USE_LMETER -static lv_style_t lmeter_bg; +static lv_style_t lmeter; +#endif + +#if LV_USE_GAUGE +static lv_style_t gauge; +static lv_style_t gauge_strong; #endif #if LV_USE_DDLIST @@ -287,38 +292,30 @@ static void sw_init(void) static void lmeter_init(void) { #if LV_USE_LMETER != 0 - lv_style_copy(&lmeter_bg, &def); - lmeter_bg.body.main_color = lv_color_hsv_to_rgb(_hue, 10, 70); - lmeter_bg.body.grad_color = lv_color_hsv_to_rgb(_hue, 80, 80); - lmeter_bg.body.padding.left = LV_DPI / 8; /*Scale line length*/ - lmeter_bg.body.padding.right = LV_DPI / 8; /*Scale line length*/ - lmeter_bg.line.color = lv_color_hex3(0x222); - lmeter_bg.line.width = 2; - - theme.style.lmeter = &lmeter_bg; - + lv_style_init(&lmeter); + lv_style_set_color(&lmeter, LV_STYLE_SCALE_COLOR, LV_COLOR_AQUA); + lv_style_set_color(&lmeter, LV_STYLE_SCALE_GRAD_COLOR, LV_COLOR_NAVY); + lv_style_set_color(&lmeter, LV_STYLE_SCALE_END_COLOR, LV_COLOR_GRAY); + lv_style_set_value(&lmeter, LV_STYLE_LINE_WIDTH, 2); #endif } static void gauge_init(void) { #if LV_USE_GAUGE != 0 - static lv_style_t gauge_bg; - lv_style_copy(&gauge_bg, &def); - gauge_bg.body.main_color = lv_color_hsv_to_rgb(_hue, 10, 70); - gauge_bg.body.grad_color = gauge_bg.body.main_color; - gauge_bg.body.padding.left = LV_DPI / 16; /*Scale line length*/ - gauge_bg.body.padding.right = LV_DPI / 16; /*Scale line length*/ - gauge_bg.body.padding.top = LV_DPI / 10; /*Needle center size*/ - gauge_bg.body.padding.bottom = LV_DPI / 10; /*Needle center size*/ - gauge_bg.body.padding.inner = LV_DPI / 12; /*Label - scale distance*/ - gauge_bg.body.border.color = lv_color_hex3(0x777); - gauge_bg.line.color = lv_color_hsv_to_rgb(_hue, 80, 75); - gauge_bg.line.width = 2; - gauge_bg.text.color = lv_color_hsv_to_rgb(_hue, 10, 90); - gauge_bg.text.font = _font; + lv_style_init(&gauge); + lv_style_set_color(&gauge, LV_STYLE_SCALE_COLOR, LV_COLOR_AQUA); + lv_style_set_color(&gauge, LV_STYLE_SCALE_GRAD_COLOR, LV_COLOR_NAVY); + lv_style_set_color(&gauge, LV_STYLE_SCALE_END_COLOR, LV_COLOR_RED); + lv_style_set_value(&gauge, LV_STYLE_LINE_WIDTH, 2); - theme.style.gauge = &gauge_bg; + lv_style_init(&gauge_strong); + lv_style_set_color(&gauge_strong, LV_STYLE_SCALE_COLOR, LV_COLOR_AQUA); + lv_style_set_color(&gauge_strong, LV_STYLE_SCALE_GRAD_COLOR, LV_COLOR_NAVY); + lv_style_set_color(&gauge_strong, LV_STYLE_SCALE_END_COLOR, LV_COLOR_RED); + lv_style_set_value(&gauge_strong, LV_STYLE_LINE_WIDTH, 4); + lv_style_set_value(&gauge_strong, LV_STYLE_SCALE_WIDTH, LV_DPI/5); + lv_style_set_value(&gauge_strong, LV_STYLE_PAD_INNER, LV_DPI/10); #endif } @@ -718,6 +715,12 @@ lv_style_t * lv_theme_alien_get_style(lv_theme_style_t name) case LV_THEME_TABVIEW_BTNS: case LV_THEME_TABVIEW_BG_SCRL: return &btn; + case LV_THEME_LMETER: + return &lmeter; + case LV_THEME_GAUGE: + return &gauge; + case LV_THEME_GAUGE_STRONG: + return &gauge_strong; } return NULL;