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

fix(arc) fix arc invalidation again

realted to #2490
This commit is contained in:
Gabor Kiss-Vamosi 2021-09-09 11:24:31 +02:00
parent eb6ae52643
commit 5ced08001c

View File

@ -92,10 +92,19 @@ void lv_arc_set_start_angle(lv_obj_t * obj, uint16_t start)
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_arc_t * arc = (lv_arc_t *)obj;
inv_arc_area(obj, LV_MIN(arc->indic_angle_start >= 360 ? arc->indic_angle_start - 360 : arc->indic_angle_start, start),
LV_MAX(arc->indic_angle_start, start),
LV_PART_INDICATOR);
arc->indic_angle_start = start > 360 ? start - 360 : start;
if(start > 360) start -= 360;
int16_t old_delta = arc->indic_angle_end - arc->indic_angle_start;
int16_t new_delta = arc->indic_angle_end - start;
if(old_delta < 0) old_delta = 360 + old_delta;
if(new_delta < 0) new_delta = 360 + new_delta;
if(LV_ABS(new_delta - old_delta) > 180) lv_obj_invalidate(obj);
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);
arc->indic_angle_start = start;
}
/**
@ -107,11 +116,19 @@ void lv_arc_set_end_angle(lv_obj_t * obj, uint16_t end)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_arc_t * arc = (lv_arc_t *)obj;
if(end > 360) end -= 360;
inv_arc_area(obj, LV_MIN(arc->indic_angle_end, end),
LV_MAX(arc->indic_angle_end, end),
LV_PART_INDICATOR);
arc->indic_angle_end = end > 360 ? end - 360 : end;
int16_t old_delta = arc->indic_angle_end - arc->indic_angle_start;
int16_t new_delta = end - arc->indic_angle_start;
if(old_delta < 0) old_delta = 360 + old_delta;
if(new_delta < 0) new_delta = 360 + new_delta;
if(LV_ABS(new_delta - old_delta) > 180) lv_obj_invalidate(obj);
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);
arc->indic_angle_end = end;
}
/**
@ -122,17 +139,8 @@ void lv_arc_set_end_angle(lv_obj_t * obj, uint16_t end)
*/
void lv_arc_set_angles(lv_obj_t * obj, uint16_t start, uint16_t end)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_arc_t * arc = (lv_arc_t *)obj;
inv_arc_area(obj,arc->indic_angle_start, arc->indic_angle_end, LV_PART_INDICATOR);
if(start > 360) start -= 360;
if(end > 360) end -= 360;
arc->indic_angle_start = start;
arc->indic_angle_end = end;
inv_arc_area(obj,arc->indic_angle_start,arc->indic_angle_end, LV_PART_INDICATOR);
lv_arc_set_end_angle(obj, end);
lv_arc_set_start_angle(obj, start);
}
/**
@ -145,10 +153,19 @@ void lv_arc_set_bg_start_angle(lv_obj_t * obj, uint16_t start)
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_arc_t * arc = (lv_arc_t *)obj;
inv_arc_area(obj, LV_MIN(arc->bg_angle_start >= 360 ? arc->bg_angle_start - 360 : arc->bg_angle_start, start),
LV_MAX(arc->bg_angle_start, start),
LV_PART_INDICATOR);
arc->bg_angle_start = start > 360 ? start - 360 : start;
if(start > 360) start -= 360;
int16_t old_delta = arc->bg_angle_end - arc->bg_angle_start;
int16_t new_delta = arc->bg_angle_end - start;
if(old_delta < 0) old_delta = 360 + old_delta;
if(new_delta < 0) new_delta = 360 + new_delta;
if(LV_ABS(new_delta - old_delta) > 180) lv_obj_invalidate(obj);
else if(new_delta < old_delta) inv_arc_area(obj, arc->bg_angle_start, start, LV_PART_MAIN);
else if(old_delta < new_delta) inv_arc_area(obj, start, arc->bg_angle_start, LV_PART_MAIN);
arc->bg_angle_start = start;
value_update(obj);
}
@ -163,10 +180,20 @@ void lv_arc_set_bg_end_angle(lv_obj_t * obj, uint16_t end)
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_arc_t * arc = (lv_arc_t *)obj;
inv_arc_area(obj, LV_MIN(arc->bg_angle_end >= 360 ? arc->bg_angle_end - 360 : arc->bg_angle_end, end),
LV_MAX(arc->bg_angle_end, end),
LV_PART_INDICATOR);
arc->bg_angle_end = end > 360 ? end - 360 : end;
if(end > 360) end -= 360;
int16_t old_delta = arc->bg_angle_end - arc->bg_angle_start;
int16_t new_delta = end - arc->bg_angle_start;
if(old_delta < 0) old_delta = 360 + old_delta;
if(new_delta < 0) new_delta = 360 + new_delta;
if(LV_ABS(new_delta - old_delta) > 180) lv_obj_invalidate(obj);
else if(new_delta < old_delta) inv_arc_area(obj, end, arc->bg_angle_end, LV_PART_MAIN);
else if(old_delta < new_delta) inv_arc_area(obj, arc->bg_angle_end, end, LV_PART_MAIN);
arc->bg_angle_end = end;
value_update(obj);
}
@ -178,19 +205,8 @@ void lv_arc_set_bg_end_angle(lv_obj_t * obj, uint16_t end)
*/
void lv_arc_set_bg_angles(lv_obj_t * obj, uint16_t start, uint16_t end)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_arc_t * arc = (lv_arc_t *)obj;
inv_arc_area(obj,arc->bg_angle_start,arc->bg_angle_end, LV_PART_MAIN);
if(start > 360) start -= 360;
if(end > 360) end -= 360;
arc->bg_angle_start = start;
arc->bg_angle_end = end;
inv_arc_area(obj,arc->bg_angle_start,arc->bg_angle_end, LV_PART_MAIN);
value_update(obj);
lv_arc_set_bg_end_angle(obj, end);
lv_arc_set_bg_start_angle(obj, start);
}
/**
@ -255,11 +271,11 @@ void lv_arc_set_value(lv_obj_t * obj, int16_t value)
if(arc->value == value) return;
int16_t new_value;
new_value = value >arc->max_value ?arc->max_value : value;
new_value = new_value <arc->min_value ?arc->min_value : new_value;
new_value = value > arc->max_value ? arc->max_value : value;
new_value = new_value < arc->min_value ? arc->min_value : new_value;
if(arc->value == new_value) return;
arc->value = new_value;
arc->value = new_value;
value_update(obj);
}
@ -693,6 +709,9 @@ static void inv_arc_area(lv_obj_t * obj, uint16_t start_angle, uint16_t end_angl
if(start_angle == end_angle) return;
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;
@ -723,6 +742,9 @@ static void inv_arc_area(lv_obj_t * obj, uint16_t start_angle, uint16_t end_angl
start_angle += arc->rotation;
end_angle += arc->rotation;
if(start_angle > 360) start_angle -= 360;
if(end_angle > 360) end_angle -= 360;
lv_area_t inv_area;
lv_draw_arc_get_area(x, y, rout, start_angle, end_angle, w, rounded, &inv_area);
lv_obj_invalidate_area(obj, &inv_area);
@ -817,10 +839,14 @@ static void value_update(lv_obj_t * obj)
angle = lv_map(arc->value,arc->min_value,arc->max_value,arc->bg_angle_start, bg_end);
lv_arc_set_start_angle(obj, angle);
break;
default: /** LV_ARC_TYPE_NORMAL*/
case LV_ARC_MODE_NORMAL:
angle = lv_map(arc->value,arc->min_value,arc->max_value,arc->bg_angle_start, bg_end);
lv_arc_set_end_angle(obj, angle);
lv_arc_set_start_angle(obj,arc->bg_angle_start);
break;
default:
LV_LOG_WARN("Invalid mode: %d", arc->type);
return;
}
arc->last_angle = angle; /*Cache angle for slew rate limiting*/
}