From 345f6882c9802dd9be55dfda5fe50c17e8c002b0 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 19 Jan 2022 14:02:11 +0100 Subject: [PATCH] fix(arc): fix knob invalidation --- src/widgets/lv_arc.c | 64 +++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/src/widgets/lv_arc.c b/src/widgets/lv_arc.c index 89aacfc2f..99ffb1f15 100644 --- a/src/widgets/lv_arc.c +++ b/src/widgets/lv_arc.c @@ -34,6 +34,7 @@ static void lv_arc_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); static void lv_arc_draw(lv_event_t * e); static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e); static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angle, lv_part_t part); +static void inv_knob_area(lv_obj_t * obj); static void get_center(lv_obj_t * obj, lv_point_t * center, lv_coord_t * arc_r); static void get_knob_area(lv_obj_t * arc, const lv_point_t * center, lv_coord_t r, lv_area_t * knob_area); static void value_update(lv_obj_t * arc); @@ -94,7 +95,11 @@ void lv_arc_set_start_angle(lv_obj_t * obj, uint16_t start) else if(new_delta < old_delta) inv_arc_area(obj, arc->indic_angle_start, start, LV_PART_INDICATOR); else if(old_delta < new_delta) inv_arc_area(obj, start, arc->indic_angle_start, LV_PART_INDICATOR); + inv_knob_area(obj); + arc->indic_angle_start = start; + + inv_knob_area(obj); } void lv_arc_set_end_angle(lv_obj_t * obj, uint16_t end) @@ -113,7 +118,11 @@ void lv_arc_set_end_angle(lv_obj_t * obj, uint16_t end) else if(new_delta < old_delta) inv_arc_area(obj, end, arc->indic_angle_end, LV_PART_INDICATOR); else if(old_delta < new_delta) inv_arc_area(obj, arc->indic_angle_end, end, LV_PART_INDICATOR); + inv_knob_area(obj); + arc->indic_angle_end = end; + + inv_knob_area(obj); } void lv_arc_set_angles(lv_obj_t * obj, uint16_t start, uint16_t end) @@ -626,6 +635,10 @@ static void lv_arc_draw(lv_event_t * e) static void inv_arc_area(lv_obj_t * obj, uint16_t start_angle, uint16_t end_angle, lv_part_t part) { LV_ASSERT_OBJ(obj, MY_CLASS); + + /*Skip this complicated invalidation if the arc is not visible*/ + if(lv_obj_is_visible(obj) == false) return; + lv_arc_t * arc = (lv_arc_t *)obj; if(start_angle == end_angle) return; @@ -633,44 +646,35 @@ static void inv_arc_area(lv_obj_t * obj, uint16_t start_angle, uint16_t end_angl if(start_angle > 360) start_angle -= 360; if(end_angle > 360) end_angle -= 360; - /*Skip this complicated invalidation if the arc is not visible*/ - if(lv_obj_is_visible(obj) == false) return; - - lv_coord_t left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); - lv_coord_t right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN); - lv_coord_t top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN); - lv_coord_t bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN); - lv_coord_t rout = (LV_MIN(lv_obj_get_width(obj) - left - right, lv_obj_get_height(obj) - top - bottom)) / 2; - lv_coord_t x = obj->coords.x1 + rout + left; - lv_coord_t y = obj->coords.y1 + rout + top; - lv_coord_t w = lv_obj_get_style_arc_width(obj, part); - lv_coord_t rounded = lv_obj_get_style_arc_rounded(obj, part); - - if(part == LV_PART_INDICATOR) { - lv_coord_t knob_extra_size = lv_obj_calculate_ext_draw_size(obj, LV_PART_KNOB); - - lv_coord_t knob_left = lv_obj_get_style_pad_left(obj, LV_PART_KNOB); - lv_coord_t knob_right = lv_obj_get_style_pad_right(obj, LV_PART_KNOB); - lv_coord_t knob_top = lv_obj_get_style_pad_top(obj, LV_PART_KNOB); - lv_coord_t knob_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_KNOB); - - knob_extra_size += LV_MAX4(knob_left, knob_right, knob_top, knob_bottom); - - w += knob_extra_size * 2 + 2; - rout += knob_extra_size + 2; - } - start_angle += arc->rotation; end_angle += arc->rotation; if(start_angle > 360) start_angle -= 360; if(end_angle > 360) end_angle -= 360; + lv_coord_t r; + lv_point_t c; + get_center(obj, &c, &r); + + lv_coord_t w = lv_obj_get_style_arc_width(obj, part); + lv_coord_t rounded = lv_obj_get_style_arc_rounded(obj, part); + lv_area_t inv_area; - lv_draw_arc_get_area(x, y, rout, start_angle, end_angle, w, rounded, &inv_area); + lv_draw_arc_get_area(c.x, c.y, r, start_angle, end_angle, w, rounded, &inv_area); lv_obj_invalidate_area(obj, &inv_area); } +static void inv_knob_area(lv_obj_t * obj) +{ + lv_point_t c; + lv_coord_t r; + get_center(obj, &c, &r); + + lv_area_t a; + get_knob_area(obj, &c, r, &a); + lv_obj_invalidate_area(obj, &a); +} + static void get_center(lv_obj_t * obj, lv_point_t * center, lv_coord_t * arc_r) { lv_coord_t left_bg = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); @@ -681,12 +685,10 @@ static void get_center(lv_obj_t * obj, lv_point_t * center, lv_coord_t * arc_r) lv_coord_t r = (LV_MIN(lv_obj_get_width(obj) - left_bg - right_bg, lv_obj_get_height(obj) - top_bg - bottom_bg)) / 2; - *arc_r = r; center->x = obj->coords.x1 + r + left_bg; center->y = obj->coords.y1 + r + top_bg; - lv_coord_t indic_width = lv_obj_get_style_arc_width(obj, LV_PART_INDICATOR); - r -= indic_width; + if(arc_r) *arc_r = r; } static void get_knob_area(lv_obj_t * obj, const lv_point_t * center, lv_coord_t r, lv_area_t * knob_area)