diff --git a/lv_core/lv_style.h b/lv_core/lv_style.h index 49c8e9175..ff514b936 100644 --- a/lv_core/lv_style.h +++ b/lv_core/lv_style.h @@ -48,11 +48,14 @@ typedef enum typedef struct { - uint8_t glass :1; /*1: Do not inherit this style*/ + uint8_t glass :1; /*1: Do not inherit this style*/ struct { lv_color_t main_color; - lv_color_t grad_color; + union { + lv_color_t grad_color; /*`grad_color` will be removed in v6.0, use `aux_color` instead*/ + lv_color_t aux_color; + }; lv_coord_t radius; lv_coord_t thickness; /*Depending on the object type thickness of something*/ lv_opa_t opa; diff --git a/lv_draw/lv_draw_arc.c b/lv_draw/lv_draw_arc.c index fc762cfbf..a7454ba05 100644 --- a/lv_draw/lv_draw_arc.c +++ b/lv_draw/lv_draw_arc.c @@ -23,6 +23,8 @@ static uint16_t fast_atan2(int x, int y); static void ver_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color, lv_opa_t opa); static void hor_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color, lv_opa_t opa); +static bool deg_test_norm(uint16_t deg, uint16_t start, uint16_t end); +static bool deg_test_inv(uint16_t deg, uint16_t start, uint16_t end); /********************** * STATIC VARIABLES @@ -62,12 +64,17 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons lv_color_t color = style->body.main_color; lv_opa_t opa = style->body.opa; + + bool (*deg_test)(uint16_t, uint16_t, uint16_t); + if(start_angle <= end_angle) deg_test = deg_test_norm; + else deg_test = deg_test_inv; + // Good, may not be the fastest // Does not draw overlapping pixels - if ((270 >= start_angle) && (270 <= end_angle)) hor_line(center_x - r_out + 1, center_y, mask, thickness - 1, color, opa); // Left Middle - if ((90 >= start_angle) && (90 <= end_angle)) hor_line(center_x + r_in, center_y, mask, thickness - 1, color, opa); // Right Middle - if ((180 >= start_angle) && (180 <= end_angle)) ver_line(center_x, center_y - r_out + 1, mask, thickness - 1, color, opa); // Top Middle - if ((0 >= start_angle) && (0 <= end_angle)) ver_line(center_x, center_y + r_in, mask, thickness - 1, color, opa); // Bottom middle + if (deg_test(270, start_angle, end_angle)) hor_line(center_x - r_out + 1, center_y, mask, thickness - 1, color, opa); // Left Middle + if (deg_test(90, start_angle, end_angle)) hor_line(center_x + r_in, center_y, mask, thickness - 1, color, opa); // Right Middle + if (deg_test(180, start_angle, end_angle)) ver_line(center_x, center_y - r_out + 1, mask, thickness - 1, color, opa); // Top Middle + if (deg_test(0, start_angle, end_angle)) ver_line(center_x, center_y + r_in, mask, thickness - 1, color, opa); // Bottom middle uint32_t r_out_sqr = r_out * r_out; uint32_t r_in_sqr = r_in * r_in; @@ -90,25 +97,32 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons deg_base = fast_atan2(xi, yi) - 180; deg = 180 + deg_base; - if ((deg >= start_angle) && (deg <= end_angle)) { + if (deg_test(deg, start_angle, end_angle)) { if(x_start[0] == LV_COORD_MIN) x_start[0] = xi; - } else if(x_start[0] != LV_COORD_MIN && x_end[0] == LV_COORD_MIN) x_end[0] = xi - 1; + } else if(x_start[0] != LV_COORD_MIN && x_end[0] == LV_COORD_MIN) { + x_end[0] = xi - 1; + } - - deg = 360 - deg_base; //BSP_LCD_FastAtan2(x, -y); - if ((deg >= start_angle) && (deg <= end_angle)) { + deg = 360 - deg_base; + if (deg_test(deg, start_angle, end_angle)) { if(x_start[1] == LV_COORD_MIN) x_start[1] = xi; - } else if(x_start[1] != LV_COORD_MIN && x_end[1] == LV_COORD_MIN) x_end[1] = xi - 1; + } else if(x_start[1] != LV_COORD_MIN && x_end[1] == LV_COORD_MIN) { + x_end[1] = xi - 1; + } - deg = 180 - deg_base; //BSP_LCD_FastAtan2(-x, y); - if ((deg >= start_angle) && (deg <= end_angle)) { + deg = 180 - deg_base; + if (deg_test(deg, start_angle, end_angle)) { if(x_start[2] == LV_COORD_MIN) x_start[2] = xi; - } else if(x_start[2] != LV_COORD_MIN && x_end[2] == LV_COORD_MIN) x_end[2] = xi - 1; + } else if(x_start[2] != LV_COORD_MIN && x_end[2] == LV_COORD_MIN) { + x_end[2] = xi - 1; + } - deg = deg_base; //BSP_LCD_FastAtan2(-x, -y); - if ((deg >= start_angle) && (deg <= end_angle)) { + deg = deg_base; + if (deg_test(deg, start_angle, end_angle)) { if(x_start[3] == LV_COORD_MIN) x_start[3] = xi; - } else if(x_start[3] != LV_COORD_MIN && x_end[3] == LV_COORD_MIN) x_end[3] = xi - 1; + } else if(x_start[3] != LV_COORD_MIN && x_end[3] == LV_COORD_MIN) { + x_end[3] = xi - 1; + } if(r_act_sqr < r_in_sqr) break; /*No need to continue the iteration in x once we found the inner edge of the arc*/ } @@ -241,3 +255,17 @@ static void hor_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coor fill_fp(&area, mask, color, opa); } + +static bool deg_test_norm(uint16_t deg, uint16_t start, uint16_t end) +{ + if(deg >= start && deg <= end) return true; + else return false; +} + +static bool deg_test_inv(uint16_t deg, uint16_t start, uint16_t end) +{ + if(deg >= start || deg <= end) { + return true; + } + else return false; +} diff --git a/lv_misc/lv_anim.c b/lv_misc/lv_anim.c index 53f81b4f2..323693f80 100644 --- a/lv_misc/lv_anim.c +++ b/lv_misc/lv_anim.c @@ -14,11 +14,12 @@ #include "../lv_hal/lv_hal_tick.h" #include "lv_task.h" #include "lv_math.h" +#include "lv_trigo.h" /********************* * DEFINES *********************/ -#define LV_ANIM_RESOLUTION 1024 +#define LV_ANIM_RESOLUTION 1024 #define LV_ANIM_RES_SHIFT 10 /********************** @@ -136,12 +137,11 @@ int32_t lv_anim_path_linear(const lv_anim_t *a) /*Calculate the current step*/ uint16_t step; - if(a->time == a->act_time) step = LV_ANIM_RESOLUTION; /*Use the last value id the time fully elapsed*/ + if(a->time == a->act_time) step = LV_ANIM_RESOLUTION; /*Use the last value if the time fully elapsed*/ else step = (a->act_time * LV_ANIM_RESOLUTION) / a->time; - - /* Get the new value which will be proportional to the current element of 'path_p' - * and the 'start' and 'end' values*/ + /* Get the new value which will be proportional to `step` + * and the `start` and `end` values*/ int32_t new_value; new_value = (int32_t) step * (a->end - a->start); new_value = new_value >> LV_ANIM_RES_SHIFT; @@ -150,6 +150,35 @@ int32_t lv_anim_path_linear(const lv_anim_t *a) return new_value; } +/** + * Calculate the current value of an animation applying an "S" characteristic (cosine) + * @param a pointer to an animation + * @return the current value to set + */ +int32_t lv_anim_path_momentum(const lv_anim_t *a) +{ + /*Calculate the current step*/ + + int16_t angle; + if(a->time == a->act_time) angle = 180; + else angle = (int32_t)((int32_t)a->act_time * 180) / a->time; + + int32_t step = lv_trigo_sin(angle - 90) + LV_TRIGO_SIN_MAX; + + + /* Get the new value which will be proportional to `step` + * and the `start` and `end` values*/ + int32_t new_value; + new_value = (int32_t) step * (a->end - a->start); + new_value = new_value >> 16; + new_value += a->start; + + +// printf("angle: %d, val: %d\n", angle, new_value); + + return new_value; +} + /** * Calculate the current value of an animation applying step characteristic. * (Set end value on the end of the animation) diff --git a/lv_misc/lv_anim.h b/lv_misc/lv_anim.h index e69f98ec3..e35a129ee 100644 --- a/lv_misc/lv_anim.h +++ b/lv_misc/lv_anim.h @@ -108,6 +108,14 @@ uint16_t lv_anim_speed_to_time(uint16_t speed, int32_t start, int32_t end); */ int32_t lv_anim_path_linear(const lv_anim_t *a); + +/** + * Calculate the current value of an animation applying an "S" characteristic (cosine) + * @param a pointer to an animation + * @return the current value to set + */ +int32_t lv_anim_path_momentum(const lv_anim_t *a); + /** * Calculate the current value of an animation applying step characteristic. * (Set end value on the end of the animation) diff --git a/lv_misc/lv_txt.c b/lv_misc/lv_txt.c index 6e094a1a7..9361d9e15 100644 --- a/lv_misc/lv_txt.c +++ b/lv_misc/lv_txt.c @@ -203,7 +203,7 @@ lv_coord_t lv_txt_get_width(const char * txt, uint16_t length, /*Trim closing spaces. Important when the text is aligned to the middle */ for(i = length - 1; i > 0; i--) { - if(txt[i] == ' ') { + if(txt[i] == ' ' || txt[i] == '\n' || txt[i] == '\r') { width -= lv_font_get_width(font, txt[i]); width -= letter_space; } else { diff --git a/lv_objx/lv_arc.c b/lv_objx/lv_arc.c index 586224ce3..1ca8fb47e 100644 --- a/lv_objx/lv_arc.c +++ b/lv_objx/lv_arc.c @@ -76,7 +76,7 @@ lv_obj_t * lv_arc_create(lv_obj_t * par, lv_obj_t * copy) /*Init the new arc arc*/ if(copy == NULL) { - lv_arc_set_style(new_arc, &lv_style_plain_color); + lv_arc_set_style(new_arc, LV_ARC_STYLE_MAIN, &lv_style_plain_color); } /*Copy an existing arc*/ else { @@ -117,8 +117,8 @@ void lv_arc_set_angles(lv_obj_t * arc, uint16_t start, uint16_t end) if(start > 360) start = 360; if(end > 360) end = 360; - ext->angle_start = LV_MATH_MIN(start, end); - ext->angle_end = LV_MATH_MAX(start, end); + ext->angle_start = start; + ext->angle_end = end; lv_obj_invalidate(arc); } @@ -147,7 +147,7 @@ void lv_arc_set_style(lv_obj_t * arc, lv_arc_style_t type, lv_style_t *style) * @param arc pointer to an arc object * @return the start angle [0..360] */ -uint16_t lv_arc_get_angle_start(lv_obj_t * arc, uint16_t start, uint16_t end) +uint16_t lv_arc_get_angle_start(lv_obj_t * arc) { lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc); @@ -159,7 +159,7 @@ uint16_t lv_arc_get_angle_start(lv_obj_t * arc, uint16_t start, uint16_t end) * @param arc pointer to an arc object * @return the end angle [0..360] */ -uint16_t lv_arc_get_angle_end(lv_obj_t * arc, uint16_t start, uint16_t end) +uint16_t lv_arc_get_angle_end(lv_obj_t * arc) { lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc); diff --git a/lv_objx/lv_arc.h b/lv_objx/lv_arc.h index f6e6df6ea..959c41257 100644 --- a/lv_objx/lv_arc.h +++ b/lv_objx/lv_arc.h @@ -86,14 +86,14 @@ void lv_arc_set_style(lv_obj_t * arc, lv_arc_style_t type, lv_style_t *style); * @param arc pointer to an arc object * @return the start angle [0..360] */ -uint16_t lv_arc_get_angle_start(lv_obj_t * arc, uint16_t start, uint16_t end); +uint16_t lv_arc_get_angle_start(lv_obj_t * arc); /** * Get the end angles of an arc. * @param arc pointer to an arc object * @return the end angle [0..360] */ -uint16_t lv_arc_get_angle_end(lv_obj_t * arc, uint16_t start, uint16_t end); +uint16_t lv_arc_get_angle_end(lv_obj_t * arc); /** * Get style of a arc. diff --git a/lvgl.h b/lvgl.h index 7bfb55afc..b168a8d50 100644 --- a/lvgl.h +++ b/lvgl.h @@ -27,6 +27,7 @@ extern "C" { #include "lv_objx/lv_btn.h" #include "lv_objx/lv_img.h" +#include "lv_objx/lv_img.h" #include "lv_objx/lv_label.h" #include "lv_objx/lv_line.h" #include "lv_objx/lv_page.h" @@ -49,6 +50,8 @@ extern "C" { #include "lv_objx/lv_lmeter.h" #include "lv_objx/lv_sw.h" #include "lv_objx/lv_kb.h" +#include "lv_objx/lv_arc.h" +#include "lv_objx/lv_preload.h" #include "lv_objx/lv_calendar.h" /*********************