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

fix(meter) keep the creation order of indicator during drawing

Instead of drawing the indicators per scale
This commit is contained in:
Gabor Kiss-Vamosi 2021-04-29 10:11:21 +02:00
parent 1b93668df7
commit 9ff1cb7f1d
5 changed files with 89 additions and 109 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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());

View File

@ -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,23 +324,22 @@ 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) {
_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;
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);
}
}
}
static void draw_ticks_and_labels(lv_obj_t * obj, const lv_area_t * clip_area, const lv_area_t * scale_area)
{
@ -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,9 +552,9 @@ 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) {
_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;
@ -595,24 +588,6 @@ static void draw_needles(lv_obj_t * obj, const lv_area_t * clip_area, const lv_a
}
}
}
}
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)
{
@ -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);

View File

@ -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;