diff --git a/examples/widgets/meter/lv_example_meter_1.c b/examples/widgets/meter/lv_example_meter_1.c index 1fdaea987..9f47538a4 100644 --- a/examples/widgets/meter/lv_example_meter_1.c +++ b/examples/widgets/meter/lv_example_meter_1.c @@ -15,6 +15,7 @@ void lv_example_meter_1(void) { meter = lv_meter_create(lv_scr_act()); lv_obj_center(meter); + lv_obj_set_size(meter, 200, 200); /*Add a scale first*/ lv_meter_scale_t * scale = lv_meter_add_scale(meter); diff --git a/examples/widgets/meter/lv_example_meter_2.c b/examples/widgets/meter/lv_example_meter_2.c index ef3c24935..1caf68759 100644 --- a/examples/widgets/meter/lv_example_meter_2.c +++ b/examples/widgets/meter/lv_example_meter_2.c @@ -16,6 +16,7 @@ void lv_example_meter_2(void) { meter = lv_meter_create(lv_scr_act()); lv_obj_center(meter); + lv_obj_set_size(meter, 200, 200); /*Remove the circle from the middle*/ lv_obj_remove_style(meter, NULL, LV_PART_INDICATOR); diff --git a/examples/widgets/meter/lv_example_meter_4.c b/examples/widgets/meter/lv_example_meter_4.c index 7580cc840..03b841e15 100644 --- a/examples/widgets/meter/lv_example_meter_4.c +++ b/examples/widgets/meter/lv_example_meter_4.c @@ -7,12 +7,14 @@ void lv_example_meter_4(void) { lv_obj_t * meter = lv_meter_create(lv_scr_act()); - lv_obj_center(meter); /*Remove the background and the circle from the middle*/ lv_obj_remove_style(meter, NULL, LV_PART_MAIN); lv_obj_remove_style(meter, NULL, LV_PART_INDICATOR); + lv_obj_set_size(meter, 200, 200); + lv_obj_center(meter); + /*Add a scale first with no ticks.*/ lv_meter_scale_t * scale = lv_meter_add_scale(meter); lv_meter_set_scale_ticks(meter, scale, 0, 0, 0, lv_color_black()); diff --git a/src/widgets/lv_meter.c b/src/widgets/lv_meter.c index 638ee13a0..d4fe2b11b 100644 --- a/src/widgets/lv_meter.c +++ b/src/widgets/lv_meter.c @@ -33,7 +33,6 @@ static void lv_meter_event(const lv_obj_class_t * class_p, lv_event_t * e); static void draw_arcs(lv_obj_t * obj, const lv_area_t * clip_area, const lv_area_t * scale_area); static void draw_ticks_and_labels(lv_obj_t * obj, const lv_area_t * clip_area, const lv_area_t * scale_area); static void draw_needles(lv_obj_t * obj, const lv_area_t * clip_area, const lv_area_t * scale_area); -static lv_meter_scale_t * get_scale_of_indic(lv_obj_t * obj, lv_meter_indicator_t * indic); static void inv_arc(lv_obj_t * obj, lv_meter_indicator_t * indic, int32_t old_value, int32_t new_value); static void inv_line(lv_obj_t * obj, lv_meter_indicator_t * indic, int32_t value); @@ -74,7 +73,6 @@ lv_meter_scale_t * lv_meter_add_scale(lv_obj_t * obj) LV_ASSERT_MALLOC(scale); lv_memset_00(scale, sizeof(lv_meter_scale_t)); - _lv_ll_init(&scale->indicator_ll, sizeof(lv_meter_indicator_t)); scale->angle_range = 270; scale->rotation = 90 + (360 - scale->angle_range) / 2; scale->min = 0; @@ -121,9 +119,11 @@ void lv_meter_set_scale_range(lv_obj_t * obj, lv_meter_scale_t * scale, int32_t lv_meter_indicator_t * lv_meter_add_needle_line(lv_obj_t * obj, lv_meter_scale_t * scale, uint16_t width, lv_color_t color, int16_t r_mod) { - lv_meter_indicator_t * indic = _lv_ll_ins_head(&scale->indicator_ll); + lv_meter_t * meter = (lv_meter_t *)obj; + lv_meter_indicator_t * indic = _lv_ll_ins_head(&meter->indicator_ll); LV_ASSERT_MALLOC(indic); lv_memset_00(indic, sizeof(lv_meter_indicator_t)); + indic->scale = scale; indic->opa = LV_OPA_COVER; indic->type = LV_METER_INDICATOR_TYPE_NEEDLE_LINE; @@ -137,9 +137,11 @@ lv_meter_indicator_t * lv_meter_add_needle_line(lv_obj_t * obj, lv_meter_scale_t lv_meter_indicator_t * lv_meter_add_needle_img(lv_obj_t * obj, lv_meter_scale_t * scale, const void * src, lv_coord_t pivot_x, lv_coord_t pivot_y) { - lv_meter_indicator_t * indic = _lv_ll_ins_head(&scale->indicator_ll); + lv_meter_t * meter = (lv_meter_t *)obj; + lv_meter_indicator_t * indic = _lv_ll_ins_head(&meter->indicator_ll); LV_ASSERT_MALLOC(indic); lv_memset_00(indic, sizeof(lv_meter_indicator_t)); + indic->scale = scale; indic->opa = LV_OPA_COVER; indic->type = LV_METER_INDICATOR_TYPE_NEEDLE_IMG; @@ -153,9 +155,11 @@ lv_meter_indicator_t * lv_meter_add_needle_img(lv_obj_t * obj, lv_meter_scale_t lv_meter_indicator_t * lv_meter_add_arc(lv_obj_t * obj, lv_meter_scale_t * scale, uint16_t width, lv_color_t color, int16_t r_mod) { - lv_meter_indicator_t * indic = _lv_ll_ins_head(&scale->indicator_ll); + lv_meter_t * meter = (lv_meter_t *)obj; + lv_meter_indicator_t * indic = _lv_ll_ins_head(&meter->indicator_ll); LV_ASSERT_MALLOC(indic); lv_memset_00(indic, sizeof(lv_meter_indicator_t)); + indic->scale = scale; indic->opa = LV_OPA_COVER; indic->type = LV_METER_INDICATOR_TYPE_ARC; @@ -169,9 +173,11 @@ lv_meter_indicator_t * lv_meter_add_arc(lv_obj_t * obj, lv_meter_scale_t * scale lv_meter_indicator_t * lv_meter_add_scale_lines(lv_obj_t * obj, lv_meter_scale_t * scale, lv_color_t color_start, lv_color_t color_end, bool local, int16_t width_mod) { - lv_meter_indicator_t * indic = _lv_ll_ins_head(&scale->indicator_ll); + lv_meter_t * meter = (lv_meter_t *)obj; + lv_meter_indicator_t * indic = _lv_ll_ins_head(&meter->indicator_ll); LV_ASSERT_MALLOC(indic); lv_memset_00(indic, sizeof(lv_meter_indicator_t)); + indic->scale = scale; indic->opa = LV_OPA_COVER; indic->type = LV_METER_INDICATOR_TYPE_SCALE_LINES; @@ -254,6 +260,7 @@ static void lv_meter_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) lv_meter_t * meter = (lv_meter_t *)obj; _lv_ll_init(&meter->scale_ll, sizeof(lv_meter_scale_t)); + _lv_ll_init(&meter->indicator_ll, sizeof(lv_meter_indicator_t)); LV_TRACE_OBJ_CREATE("finished"); } @@ -262,19 +269,8 @@ static void lv_meter_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) { LV_UNUSED(class_p); lv_meter_t * meter = (lv_meter_t *)obj; - lv_meter_scale_t * scale; - scale = _lv_ll_get_head(&meter->scale_ll); - while(scale) { - lv_meter_indicator_t * indicator = _lv_ll_get_head(&scale->indicator_ll); - while(indicator) { - _lv_ll_remove(&scale->indicator_ll, indicator); - lv_mem_free(indicator); - indicator = _lv_ll_get_head(&scale->indicator_ll); - } - _lv_ll_remove(&meter->scale_ll, scale); - lv_mem_free(scale); - scale = _lv_ll_get_head(&meter->scale_ll); - } + _lv_ll_clear(&meter->indicator_ll); + _lv_ll_clear(&meter->scale_ll); } @@ -328,21 +324,20 @@ static void draw_arcs(lv_obj_t * obj, const lv_area_t * clip_area, const lv_area scale_center.x = scale_area->x1 + r_out; scale_center.y = scale_area->y1 + r_out; - lv_meter_scale_t * scale; - _LV_LL_READ_BACK(&meter->scale_ll, scale) { - lv_opa_t opa_main = lv_obj_get_style_opa(obj, LV_PART_MAIN); - lv_meter_indicator_t * indic; - _LV_LL_READ_BACK(&scale->indicator_ll, indic) { - if(indic->type != LV_METER_INDICATOR_TYPE_ARC) continue; + lv_opa_t opa_main = lv_obj_get_style_opa(obj, LV_PART_MAIN); + lv_meter_indicator_t * indic; + _LV_LL_READ_BACK(&meter->indicator_ll, indic) { + if(indic->type != LV_METER_INDICATOR_TYPE_ARC) continue; - arc_dsc.color = indic->type_data.arc.color; - arc_dsc.width = indic->type_data.arc.width; - arc_dsc.opa = indic->opa > LV_OPA_MAX ? opa_main : (opa_main * indic->opa) >> 8; + arc_dsc.color = indic->type_data.arc.color; + arc_dsc.width = indic->type_data.arc.width; + arc_dsc.opa = indic->opa > LV_OPA_MAX ? opa_main : (opa_main * indic->opa) >> 8; - int32_t start_angle = lv_map(indic->start_value, scale->min, scale->max, scale->rotation, scale->rotation + scale->angle_range); - int32_t end_angle = lv_map(indic->end_value, scale->min, scale->max, scale->rotation, scale->rotation + scale->angle_range); - lv_draw_arc(scale_center.x, scale_center.y, r_out + indic->type_data.arc.r_mod, start_angle, end_angle, clip_area, &arc_dsc); - } + lv_meter_scale_t * scale = indic->scale; + + int32_t start_angle = lv_map(indic->start_value, scale->min, scale->max, scale->rotation, scale->rotation + scale->angle_range); + int32_t end_angle = lv_map(indic->end_value, scale->min, scale->max, scale->rotation, scale->rotation + scale->angle_range); + lv_draw_arc(scale_center.x, scale_center.y, r_out + indic->type_data.arc.r_mod, start_angle, end_angle, clip_area, &arc_dsc); } } @@ -431,7 +426,7 @@ static void draw_ticks_and_labels(lv_obj_t * obj, const lv_area_t * clip_area, c lv_coord_t line_width = line_width_ori; lv_meter_indicator_t * indic; - _LV_LL_READ_BACK(&scale->indicator_ll, indic) { + _LV_LL_READ_BACK(&meter->indicator_ll, indic) { if(indic->type != LV_METER_INDICATOR_TYPE_SCALE_LINES) continue; if(value_of_line >= indic->start_value && value_of_line <= indic->end_value) { line_width += indic->type_data.scale_lines.width_mod; @@ -542,8 +537,6 @@ static void draw_needles(lv_obj_t * obj, const lv_area_t * clip_area, const lv_a { lv_meter_t * meter = (lv_meter_t *)obj; - lv_meter_scale_t * scale; - lv_coord_t r_edge = lv_area_get_width(scale_area) / 2; lv_point_t scale_center; scale_center.x = scale_area->x1 + r_edge; @@ -559,61 +552,43 @@ static void draw_needles(lv_obj_t * obj, const lv_area_t * clip_area, const lv_a img_dsc.antialias = 1; lv_opa_t opa_main = lv_obj_get_style_opa(obj, LV_PART_MAIN); - _LV_LL_READ_BACK(&meter->scale_ll, scale) { - lv_meter_indicator_t * indic; - _LV_LL_READ_BACK(&scale->indicator_ll, indic) { - if(indic->type == LV_METER_INDICATOR_TYPE_NEEDLE_LINE) { - int32_t angle = lv_map(indic->end_value, scale->min, scale->max, scale->rotation, scale->rotation + scale->angle_range); - lv_coord_t r_out = r_edge + scale->r_mod + indic->type_data.needle_line.r_mod; - lv_point_t p_end; - p_end.y = (lv_trigo_sin(angle) * (r_out)) / LV_TRIGO_SIN_MAX + scale_center.y; - p_end.x = (lv_trigo_cos(angle) * (r_out)) / LV_TRIGO_SIN_MAX + scale_center.x; - line_dsc.color = indic->type_data.needle_line.color; - line_dsc.width = indic->type_data.needle_line.width; - line_dsc.opa = indic->opa > LV_OPA_MAX ? opa_main : (opa_main * indic->opa) >> 8; - lv_draw_line(&scale_center, &p_end, clip_area, &line_dsc); - } - else if(indic->type == LV_METER_INDICATOR_TYPE_NEEDLE_IMG) { - if(indic->type_data.needle_img.src == NULL) continue; + lv_meter_indicator_t * indic; + _LV_LL_READ_BACK(&meter->indicator_ll, indic) { + lv_meter_scale_t * scale = indic->scale; + if(indic->type == LV_METER_INDICATOR_TYPE_NEEDLE_LINE) { + int32_t angle = lv_map(indic->end_value, scale->min, scale->max, scale->rotation, scale->rotation + scale->angle_range); + lv_coord_t r_out = r_edge + scale->r_mod + indic->type_data.needle_line.r_mod; + lv_point_t p_end; + p_end.y = (lv_trigo_sin(angle) * (r_out)) / LV_TRIGO_SIN_MAX + scale_center.y; + p_end.x = (lv_trigo_cos(angle) * (r_out)) / LV_TRIGO_SIN_MAX + scale_center.x; + line_dsc.color = indic->type_data.needle_line.color; + line_dsc.width = indic->type_data.needle_line.width; + line_dsc.opa = indic->opa > LV_OPA_MAX ? opa_main : (opa_main * indic->opa) >> 8; + lv_draw_line(&scale_center, &p_end, clip_area, &line_dsc); + } + else if(indic->type == LV_METER_INDICATOR_TYPE_NEEDLE_IMG) { + if(indic->type_data.needle_img.src == NULL) continue; - int32_t angle = lv_map(indic->end_value, scale->min, scale->max, scale->rotation, scale->rotation + scale->angle_range); - lv_img_header_t info; - lv_img_decoder_get_info(indic->type_data.needle_img.src, &info); - lv_area_t a; - a.x1 = scale_center.x - indic->type_data.needle_img.pivot.x; - a.y1 = scale_center.y - indic->type_data.needle_img.pivot.y; - a.x2 = a.x1 + info.w - 1; - a.y2 = a.y1 + info.h - 1; + int32_t angle = lv_map(indic->end_value, scale->min, scale->max, scale->rotation, scale->rotation + scale->angle_range); + lv_img_header_t info; + lv_img_decoder_get_info(indic->type_data.needle_img.src, &info); + lv_area_t a; + a.x1 = scale_center.x - indic->type_data.needle_img.pivot.x; + a.y1 = scale_center.y - indic->type_data.needle_img.pivot.y; + a.x2 = a.x1 + info.w - 1; + a.y2 = a.y1 + info.h - 1; - img_dsc.opa = indic->opa > LV_OPA_MAX ? opa_main : (opa_main * indic->opa) >> 8; - img_dsc.pivot.x = indic->type_data.needle_img.pivot.x; - img_dsc.pivot.y = indic->type_data.needle_img.pivot.y; - angle = angle * 10; - if(angle > 3600) angle -= 3600; - img_dsc.angle = angle; - lv_draw_img(&a, clip_area, indic->type_data.needle_img.src, &img_dsc); - } + img_dsc.opa = indic->opa > LV_OPA_MAX ? opa_main : (opa_main * indic->opa) >> 8; + img_dsc.pivot.x = indic->type_data.needle_img.pivot.x; + img_dsc.pivot.y = indic->type_data.needle_img.pivot.y; + angle = angle * 10; + if(angle > 3600) angle -= 3600; + img_dsc.angle = angle; + lv_draw_img(&a, clip_area, indic->type_data.needle_img.src, &img_dsc); } } } -static lv_meter_scale_t * get_scale_of_indic(lv_obj_t * obj, lv_meter_indicator_t * indic) -{ - lv_meter_t * meter = (lv_meter_t *)obj; - - lv_meter_scale_t * scale; - - _LV_LL_READ_BACK(&meter->scale_ll, scale) { - lv_meter_indicator_t * ind; - _LV_LL_READ_BACK(&scale->indicator_ll, ind) { - if(ind == indic) return scale; - } - } - - return NULL; -} - - static void inv_arc(lv_obj_t * obj, lv_meter_indicator_t * indic, int32_t old_value, int32_t new_value) { bool rounded = lv_obj_get_style_arc_rounded(obj, LV_PART_ITEMS); @@ -628,7 +603,7 @@ static void inv_arc(lv_obj_t * obj, lv_meter_indicator_t * indic, int32_t old_va r_out += indic->type_data.arc.r_mod; - lv_meter_scale_t * scale = get_scale_of_indic(obj, indic); + lv_meter_scale_t * scale = indic->scale; int32_t start_angle = lv_map(old_value, scale->min, scale->max, scale->rotation, scale->angle_range + scale->rotation); int32_t end_angle = lv_map(new_value, scale->min, scale->max, scale->rotation, scale->angle_range + scale->rotation); @@ -648,7 +623,7 @@ static void inv_line(lv_obj_t * obj, lv_meter_indicator_t * indic, int32_t value scale_center.x = scale_area.x1 + r_out; scale_center.y = scale_area.y1 + r_out; - lv_meter_scale_t * scale = get_scale_of_indic(obj, indic); + lv_meter_scale_t * scale = indic->scale; if(indic->type == LV_METER_INDICATOR_TYPE_NEEDLE_LINE) { int32_t angle = lv_map(value, scale->min, scale->max, scale->rotation, scale->rotation + scale->angle_range); diff --git a/src/widgets/lv_meter.h b/src/widgets/lv_meter.h index 8000b837c..69c97f5d2 100644 --- a/src/widgets/lv_meter.h +++ b/src/widgets/lv_meter.h @@ -27,6 +27,27 @@ extern "C" { * TYPEDEFS **********************/ +typedef struct { + lv_color_t tick_color; + uint16_t tick_cnt; + uint16_t tick_length; + uint16_t tick_width; + + lv_color_t tick_major_color; + uint16_t tick_major_nth; + uint16_t tick_major_length; + uint16_t tick_major_width; + + int16_t label_gap; + int16_t label_color; + + int32_t min; + int32_t max; + int16_t r_mod; + uint16_t angle_range; + int16_t rotation; +}lv_meter_scale_t; + typedef enum { LV_METER_INDICATOR_TYPE_NEEDLE_IMG, LV_METER_INDICATOR_TYPE_NEEDLE_LINE, @@ -35,6 +56,7 @@ typedef enum { }lv_meter_indicator_type_t; typedef struct { + lv_meter_scale_t * scale; lv_meter_indicator_type_t type; lv_opa_t opa; int32_t start_value; @@ -64,33 +86,12 @@ typedef struct { } type_data; }lv_meter_indicator_t; -typedef struct { - lv_ll_t indicator_ll; - - lv_color_t tick_color; - uint16_t tick_cnt; - uint16_t tick_length; - uint16_t tick_width; - - lv_color_t tick_major_color; - uint16_t tick_major_nth; - uint16_t tick_major_length; - uint16_t tick_major_width; - - int16_t label_gap; - int16_t label_color; - - int32_t min; - int32_t max; - int16_t r_mod; - uint16_t angle_range; - int16_t rotation; -}lv_meter_scale_t; /*Data of line meter*/ typedef struct { lv_obj_t obj; lv_ll_t scale_ll; + lv_ll_t indicator_ll; } lv_meter_t; extern const lv_obj_class_t lv_meter_class;