feat(scale): mutiple line needles (#5937)
This commit is contained in:
@@ -116,6 +116,7 @@ void lv_example_scale_2(void);
|
|||||||
void lv_example_scale_3(void);
|
void lv_example_scale_3(void);
|
||||||
void lv_example_scale_4(void);
|
void lv_example_scale_4(void);
|
||||||
void lv_example_scale_5(void);
|
void lv_example_scale_5(void);
|
||||||
|
void lv_example_scale_6(void);
|
||||||
|
|
||||||
void lv_example_slider_1(void);
|
void lv_example_slider_1(void);
|
||||||
void lv_example_slider_2(void);
|
void lv_example_slider_2(void);
|
||||||
|
|||||||
@@ -28,3 +28,9 @@ An scale with section and custom styling
|
|||||||
.. lv_example:: widgets/scale/lv_example_scale_5
|
.. lv_example:: widgets/scale/lv_example_scale_5
|
||||||
:language: c
|
:language: c
|
||||||
|
|
||||||
|
A round scale with multiple needles, resembling a clock
|
||||||
|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
|
.. lv_example:: widgets/scale/lv_example_scale_6
|
||||||
|
:language: c
|
||||||
|
|
||||||
|
|||||||
126
examples/widgets/scale/lv_example_scale_6.c
Normal file
126
examples/widgets/scale/lv_example_scale_6.c
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
#include "../../lv_examples.h"
|
||||||
|
#if LV_USE_SCALE && LV_BUILD_EXAMPLES
|
||||||
|
|
||||||
|
#if LV_USE_FLOAT
|
||||||
|
#define my_PRIprecise "f"
|
||||||
|
#else
|
||||||
|
#define my_PRIprecise LV_PRId32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static lv_obj_t * scale;
|
||||||
|
static lv_obj_t * minute_hand;
|
||||||
|
static lv_obj_t * hour_hand;
|
||||||
|
static lv_point_precise_t minute_hand_points[2];
|
||||||
|
static int32_t hour;
|
||||||
|
static int32_t minute;
|
||||||
|
|
||||||
|
static void timer_cb(lv_timer_t * timer)
|
||||||
|
{
|
||||||
|
LV_UNUSED(timer);
|
||||||
|
|
||||||
|
minute++;
|
||||||
|
if(minute > 59) {
|
||||||
|
minute = 0;
|
||||||
|
hour++;
|
||||||
|
if(hour > 11) {
|
||||||
|
hour = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the scale will store the needle line points in the existing
|
||||||
|
* point array if one was set with `lv_line_set_points_mutable`.
|
||||||
|
* Otherwise, it will allocate the needle line points.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* the scale will store the minute hand line points in `minute_hand_points` */
|
||||||
|
lv_scale_set_line_needle_value(scale, minute_hand, 60, minute);
|
||||||
|
/* log the points that were stored in the array */
|
||||||
|
LV_LOG_USER(
|
||||||
|
"minute hand points - "
|
||||||
|
"0: (%" my_PRIprecise ", %" my_PRIprecise "), "
|
||||||
|
"1: (%" my_PRIprecise ", %" my_PRIprecise ")",
|
||||||
|
minute_hand_points[0].x, minute_hand_points[0].y,
|
||||||
|
minute_hand_points[1].x, minute_hand_points[1].y
|
||||||
|
);
|
||||||
|
|
||||||
|
/* the scale will allocate the hour hand line points */
|
||||||
|
lv_scale_set_line_needle_value(scale, hour_hand, 40, hour * 5 + (minute / 12));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A round scale with multiple needles, resembing a clock
|
||||||
|
*/
|
||||||
|
void lv_example_scale_6(void)
|
||||||
|
{
|
||||||
|
scale = lv_scale_create(lv_screen_active());
|
||||||
|
|
||||||
|
lv_obj_set_size(scale, 150, 150);
|
||||||
|
lv_scale_set_mode(scale, LV_SCALE_MODE_ROUND_INNER);
|
||||||
|
lv_obj_set_style_bg_opa(scale, LV_OPA_60, 0);
|
||||||
|
lv_obj_set_style_bg_color(scale, lv_color_black(), 0);
|
||||||
|
lv_obj_set_style_radius(scale, LV_RADIUS_CIRCLE, 0);
|
||||||
|
lv_obj_set_style_clip_corner(scale, true, 0);
|
||||||
|
lv_obj_center(scale);
|
||||||
|
|
||||||
|
lv_scale_set_label_show(scale, true);
|
||||||
|
|
||||||
|
lv_scale_set_total_tick_count(scale, 61);
|
||||||
|
lv_scale_set_major_tick_every(scale, 5);
|
||||||
|
|
||||||
|
static const char * hour_ticks[] = {"12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", NULL};
|
||||||
|
lv_scale_set_text_src(scale, hour_ticks);
|
||||||
|
|
||||||
|
static lv_style_t indicator_style;
|
||||||
|
lv_style_init(&indicator_style);
|
||||||
|
|
||||||
|
/* Label style properties */
|
||||||
|
lv_style_set_text_font(&indicator_style, LV_FONT_DEFAULT);
|
||||||
|
lv_style_set_text_color(&indicator_style, lv_palette_main(LV_PALETTE_YELLOW));
|
||||||
|
|
||||||
|
/* Major tick properties */
|
||||||
|
lv_style_set_line_color(&indicator_style, lv_palette_main(LV_PALETTE_YELLOW));
|
||||||
|
lv_style_set_length(&indicator_style, 8); /* tick length */
|
||||||
|
lv_style_set_line_width(&indicator_style, 2); /* tick width */
|
||||||
|
lv_obj_add_style(scale, &indicator_style, LV_PART_INDICATOR);
|
||||||
|
|
||||||
|
/* Minor tick properties */
|
||||||
|
static lv_style_t minor_ticks_style;
|
||||||
|
lv_style_init(&minor_ticks_style);
|
||||||
|
lv_style_set_line_color(&minor_ticks_style, lv_palette_main(LV_PALETTE_YELLOW));
|
||||||
|
lv_style_set_length(&minor_ticks_style, 6); /* tick length */
|
||||||
|
lv_style_set_line_width(&minor_ticks_style, 2); /* tick width */
|
||||||
|
lv_obj_add_style(scale, &minor_ticks_style, LV_PART_ITEMS);
|
||||||
|
|
||||||
|
/* Main line properties */
|
||||||
|
static lv_style_t main_line_style;
|
||||||
|
lv_style_init(&main_line_style);
|
||||||
|
lv_style_set_arc_color(&main_line_style, lv_color_black());
|
||||||
|
lv_style_set_arc_width(&main_line_style, 5);
|
||||||
|
lv_obj_add_style(scale, &main_line_style, LV_PART_MAIN);
|
||||||
|
|
||||||
|
lv_scale_set_range(scale, 0, 60);
|
||||||
|
|
||||||
|
lv_scale_set_angle_range(scale, 360);
|
||||||
|
lv_scale_set_rotation(scale, 270);
|
||||||
|
|
||||||
|
minute_hand = lv_line_create(scale);
|
||||||
|
lv_line_set_points_mutable(minute_hand, minute_hand_points, 2);
|
||||||
|
|
||||||
|
lv_obj_set_style_line_width(minute_hand, 3, 0);
|
||||||
|
lv_obj_set_style_line_rounded(minute_hand, true, 0);
|
||||||
|
lv_obj_set_style_line_color(minute_hand, lv_color_white(), 0);
|
||||||
|
|
||||||
|
hour_hand = lv_line_create(scale);
|
||||||
|
|
||||||
|
lv_obj_set_style_line_width(hour_hand, 5, 0);
|
||||||
|
lv_obj_set_style_line_rounded(hour_hand, true, 0);
|
||||||
|
lv_obj_set_style_line_color(hour_hand, lv_palette_main(LV_PALETTE_RED), 0);
|
||||||
|
|
||||||
|
hour = 11;
|
||||||
|
minute = 5;
|
||||||
|
lv_timer_t * timer = lv_timer_create(timer_cb, 250, NULL);
|
||||||
|
lv_timer_ready(timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -27,6 +27,7 @@
|
|||||||
* STATIC PROTOTYPES
|
* STATIC PROTOTYPES
|
||||||
**********************/
|
**********************/
|
||||||
static void lv_line_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
static void lv_line_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
||||||
|
static void line_set_points(lv_obj_t * obj, const lv_point_precise_t points[], uint32_t point_num, bool mut);
|
||||||
static void lv_line_event(const lv_obj_class_t * class_p, lv_event_t * e);
|
static void lv_line_event(const lv_obj_class_t * class_p, lv_event_t * e);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
@@ -64,15 +65,12 @@ lv_obj_t * lv_line_create(lv_obj_t * parent)
|
|||||||
|
|
||||||
void lv_line_set_points(lv_obj_t * obj, const lv_point_precise_t points[], uint32_t point_num)
|
void lv_line_set_points(lv_obj_t * obj, const lv_point_precise_t points[], uint32_t point_num)
|
||||||
{
|
{
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
line_set_points(obj, points, point_num, false);
|
||||||
|
}
|
||||||
|
|
||||||
lv_line_t * line = (lv_line_t *)obj;
|
void lv_line_set_points_mutable(lv_obj_t * obj, lv_point_precise_t points[], uint32_t point_num)
|
||||||
line->point_array = points;
|
{
|
||||||
line->point_num = point_num;
|
line_set_points(obj, points, point_num, true);
|
||||||
|
|
||||||
lv_obj_refresh_self_size(obj);
|
|
||||||
|
|
||||||
lv_obj_invalidate(obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lv_line_set_y_invert(lv_obj_t * obj, bool en)
|
void lv_line_set_y_invert(lv_obj_t * obj, bool en)
|
||||||
@@ -91,6 +89,42 @@ void lv_line_set_y_invert(lv_obj_t * obj, bool en)
|
|||||||
* Getter functions
|
* Getter functions
|
||||||
*====================*/
|
*====================*/
|
||||||
|
|
||||||
|
const lv_point_precise_t * lv_line_get_points(lv_obj_t * obj)
|
||||||
|
{
|
||||||
|
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||||
|
|
||||||
|
lv_line_t * line = (lv_line_t *)obj;
|
||||||
|
return line->point_array.constant;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t lv_line_get_point_count(lv_obj_t * obj)
|
||||||
|
{
|
||||||
|
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||||
|
|
||||||
|
lv_line_t * line = (lv_line_t *)obj;
|
||||||
|
return line->point_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool lv_line_is_point_array_mutable(lv_obj_t * obj)
|
||||||
|
{
|
||||||
|
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||||
|
|
||||||
|
lv_line_t * line = (lv_line_t *)obj;
|
||||||
|
return line->point_array_is_mutable;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_point_precise_t * lv_line_get_points_mutable(lv_obj_t * obj)
|
||||||
|
{
|
||||||
|
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||||
|
|
||||||
|
lv_line_t * line = (lv_line_t *)obj;
|
||||||
|
if(!line->point_array_is_mutable) {
|
||||||
|
LV_LOG_WARN("the line point array is not mutable");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return line->point_array.mut;
|
||||||
|
}
|
||||||
|
|
||||||
bool lv_line_get_y_invert(const lv_obj_t * obj)
|
bool lv_line_get_y_invert(const lv_obj_t * obj)
|
||||||
{
|
{
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||||
@@ -112,14 +146,29 @@ static void lv_line_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
|||||||
lv_line_t * line = (lv_line_t *)obj;
|
lv_line_t * line = (lv_line_t *)obj;
|
||||||
|
|
||||||
line->point_num = 0;
|
line->point_num = 0;
|
||||||
line->point_array = NULL;
|
line->point_array.constant = NULL;
|
||||||
line->y_inv = 0;
|
line->y_inv = 0;
|
||||||
|
line->point_array_is_mutable = 0;
|
||||||
|
|
||||||
lv_obj_remove_flag(obj, LV_OBJ_FLAG_CLICKABLE);
|
lv_obj_remove_flag(obj, LV_OBJ_FLAG_CLICKABLE);
|
||||||
|
|
||||||
LV_TRACE_OBJ_CREATE("finished");
|
LV_TRACE_OBJ_CREATE("finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void line_set_points(lv_obj_t * obj, const lv_point_precise_t points[], uint32_t point_num, bool mut)
|
||||||
|
{
|
||||||
|
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||||
|
|
||||||
|
lv_line_t * line = (lv_line_t *)obj;
|
||||||
|
line->point_array.constant = points;
|
||||||
|
line->point_num = point_num;
|
||||||
|
line->point_array_is_mutable = mut;
|
||||||
|
|
||||||
|
lv_obj_refresh_self_size(obj);
|
||||||
|
|
||||||
|
lv_obj_invalidate(obj);
|
||||||
|
}
|
||||||
|
|
||||||
static inline lv_value_precise_t resolve_point_coord(lv_value_precise_t coord, int32_t max)
|
static inline lv_value_precise_t resolve_point_coord(lv_value_precise_t coord, int32_t max)
|
||||||
{
|
{
|
||||||
if(LV_COORD_IS_PCT((int32_t)coord)) {
|
if(LV_COORD_IS_PCT((int32_t)coord)) {
|
||||||
@@ -152,7 +201,7 @@ static void lv_line_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
|||||||
else if(code == LV_EVENT_GET_SELF_SIZE) {
|
else if(code == LV_EVENT_GET_SELF_SIZE) {
|
||||||
lv_line_t * line = (lv_line_t *)obj;
|
lv_line_t * line = (lv_line_t *)obj;
|
||||||
|
|
||||||
if(line->point_num == 0 || line->point_array == NULL) return;
|
if(line->point_num == 0 || line->point_array.constant == NULL) return;
|
||||||
|
|
||||||
lv_point_t * p = lv_event_get_param(e);
|
lv_point_t * p = lv_event_get_param(e);
|
||||||
int32_t w = 0;
|
int32_t w = 0;
|
||||||
@@ -160,12 +209,12 @@ static void lv_line_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
|||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
for(i = 0; i < line->point_num; i++) {
|
for(i = 0; i < line->point_num; i++) {
|
||||||
if(!LV_COORD_IS_PCT((int32_t)line->point_array[i].x)) {
|
if(!LV_COORD_IS_PCT((int32_t)line->point_array.constant[i].x)) {
|
||||||
w = (int32_t)LV_MAX(line->point_array[i].x, w);
|
w = (int32_t)LV_MAX(line->point_array.constant[i].x, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!LV_COORD_IS_PCT((int32_t)line->point_array[i].y)) {
|
if(!LV_COORD_IS_PCT((int32_t)line->point_array.constant[i].y)) {
|
||||||
h = (int32_t)LV_MAX(line->point_array[i].y, h);
|
h = (int32_t)LV_MAX(line->point_array.constant[i].y, h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +225,7 @@ static void lv_line_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
|||||||
lv_line_t * line = (lv_line_t *)obj;
|
lv_line_t * line = (lv_line_t *)obj;
|
||||||
lv_layer_t * layer = lv_event_get_layer(e);
|
lv_layer_t * layer = lv_event_get_layer(e);
|
||||||
|
|
||||||
if(line->point_num == 0 || line->point_array == NULL) return;
|
if(line->point_num == 0 || line->point_array.constant == NULL) return;
|
||||||
|
|
||||||
lv_area_t area;
|
lv_area_t area;
|
||||||
lv_obj_get_coords(obj, &area);
|
lv_obj_get_coords(obj, &area);
|
||||||
@@ -193,11 +242,11 @@ static void lv_line_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
|||||||
int32_t w = lv_obj_get_width(obj);
|
int32_t w = lv_obj_get_width(obj);
|
||||||
int32_t h = lv_obj_get_height(obj);
|
int32_t h = lv_obj_get_height(obj);
|
||||||
|
|
||||||
line_dsc.p1.x = resolve_point_coord(line->point_array[i].x, w) + x_ofs;
|
line_dsc.p1.x = resolve_point_coord(line->point_array.constant[i].x, w) + x_ofs;
|
||||||
line_dsc.p1.y = resolve_point_coord(line->point_array[i].y, h);
|
line_dsc.p1.y = resolve_point_coord(line->point_array.constant[i].y, h);
|
||||||
|
|
||||||
line_dsc.p2.x = resolve_point_coord(line->point_array[i + 1].x, w) + x_ofs;
|
line_dsc.p2.x = resolve_point_coord(line->point_array.constant[i + 1].x, w) + x_ofs;
|
||||||
line_dsc.p2.y = resolve_point_coord(line->point_array[i + 1].y, h);
|
line_dsc.p2.y = resolve_point_coord(line->point_array.constant[i + 1].y, h);
|
||||||
|
|
||||||
if(line->y_inv == 0) {
|
if(line->y_inv == 0) {
|
||||||
line_dsc.p1.y = line_dsc.p1.y + y_ofs;
|
line_dsc.p1.y = line_dsc.p1.y + y_ofs;
|
||||||
|
|||||||
@@ -27,9 +27,13 @@ extern "C" {
|
|||||||
/*Data of line*/
|
/*Data of line*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
lv_obj_t obj;
|
lv_obj_t obj;
|
||||||
const lv_point_precise_t * point_array; /**< Pointer to an array with the points of the line*/
|
union {
|
||||||
|
const lv_point_precise_t * constant;
|
||||||
|
lv_point_precise_t * mut;
|
||||||
|
} point_array; /**< Pointer to an array with the points of the line*/
|
||||||
uint32_t point_num; /**< Number of points in 'point_array'*/
|
uint32_t point_num; /**< Number of points in 'point_array'*/
|
||||||
uint32_t y_inv : 1; /**< 1: y == 0 will be on the bottom*/
|
uint32_t y_inv : 1; /**< 1: y == 0 will be on the bottom*/
|
||||||
|
uint32_t point_array_is_mutable : 1; /**< whether the point array is const or mutable*/
|
||||||
} lv_line_t;
|
} lv_line_t;
|
||||||
|
|
||||||
LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_line_class;
|
LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_line_class;
|
||||||
@@ -57,6 +61,14 @@ lv_obj_t * lv_line_create(lv_obj_t * parent);
|
|||||||
*/
|
*/
|
||||||
void lv_line_set_points(lv_obj_t * obj, const lv_point_precise_t points[], uint32_t point_num);
|
void lv_line_set_points(lv_obj_t * obj, const lv_point_precise_t points[], uint32_t point_num);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a non-const array of points. Identical to `lv_line_set_points` except the array may be retrieved by `lv_line_get_points_mutable`.
|
||||||
|
* @param obj pointer to a line object
|
||||||
|
* @param points a non-const array of points. Only the address is saved, so the array needs to be alive while the line exists.
|
||||||
|
* @param point_num number of points in 'point_a'
|
||||||
|
*/
|
||||||
|
void lv_line_set_points_mutable(lv_obj_t * obj, lv_point_precise_t points[], uint32_t point_num);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable (or disable) the y coordinate inversion.
|
* Enable (or disable) the y coordinate inversion.
|
||||||
* If enabled then y will be subtracted from the height of the object,
|
* If enabled then y will be subtracted from the height of the object,
|
||||||
@@ -70,6 +82,34 @@ void lv_line_set_y_invert(lv_obj_t * obj, bool en);
|
|||||||
* Getter functions
|
* Getter functions
|
||||||
*====================*/
|
*====================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the pointer to the array of points.
|
||||||
|
* @param obj pointer to a line object
|
||||||
|
* @return const pointer to the array of points
|
||||||
|
*/
|
||||||
|
const lv_point_precise_t * lv_line_get_points(lv_obj_t * obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of points in the array of points.
|
||||||
|
* @param obj pointer to a line object
|
||||||
|
* @return number of points in array of points
|
||||||
|
*/
|
||||||
|
uint32_t lv_line_get_point_count(lv_obj_t * obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the mutability of the stored point array pointer.
|
||||||
|
* @param obj pointer to a line object
|
||||||
|
* @return true: the point array pointer is mutable, false: constant
|
||||||
|
*/
|
||||||
|
bool lv_line_is_point_array_mutable(lv_obj_t * obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a pointer to the mutable array of points or NULL if it is not mutable
|
||||||
|
* @param obj pointer to a line object
|
||||||
|
* @return pointer to the array of points. NULL if not mutable.
|
||||||
|
*/
|
||||||
|
lv_point_precise_t * lv_line_get_points_mutable(lv_obj_t * obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the y inversion attribute
|
* Get the y inversion attribute
|
||||||
* @param obj pointer to a line object
|
* @param obj pointer to a line object
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ static void scale_store_section_line_tick_width_compensation(lv_obj_t * obj, con
|
|||||||
static void scale_build_custom_label_text(lv_obj_t * obj, lv_draw_label_dsc_t * label_dsc,
|
static void scale_build_custom_label_text(lv_obj_t * obj, lv_draw_label_dsc_t * label_dsc,
|
||||||
const uint16_t major_tick_idx);
|
const uint16_t major_tick_idx);
|
||||||
|
|
||||||
|
static void scale_free_line_needle_points_cb(lv_event_t * e);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
**********************/
|
**********************/
|
||||||
@@ -180,7 +182,7 @@ void lv_scale_set_line_needle_value(lv_obj_t * obj, lv_obj_t * needle_line, int3
|
|||||||
int32_t scale_width, scale_height;
|
int32_t scale_width, scale_height;
|
||||||
int32_t actual_needle_length;
|
int32_t actual_needle_length;
|
||||||
int32_t needle_length_x, needle_length_y;
|
int32_t needle_length_x, needle_length_y;
|
||||||
static lv_point_precise_t needle_line_points[2];
|
lv_point_precise_t * needle_line_points = NULL;
|
||||||
|
|
||||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||||
lv_scale_t * scale = (lv_scale_t *)obj;
|
lv_scale_t * scale = (lv_scale_t *)obj;
|
||||||
@@ -224,12 +226,35 @@ void lv_scale_set_line_needle_value(lv_obj_t * obj, lv_obj_t * needle_line, int3
|
|||||||
needle_length_x = (actual_needle_length * lv_trigo_cos(scale->rotation + angle)) >> LV_TRIGO_SHIFT;
|
needle_length_x = (actual_needle_length * lv_trigo_cos(scale->rotation + angle)) >> LV_TRIGO_SHIFT;
|
||||||
needle_length_y = (actual_needle_length * lv_trigo_sin(scale->rotation + angle)) >> LV_TRIGO_SHIFT;
|
needle_length_y = (actual_needle_length * lv_trigo_sin(scale->rotation + angle)) >> LV_TRIGO_SHIFT;
|
||||||
|
|
||||||
|
if(lv_line_is_point_array_mutable(needle_line) && lv_line_get_point_count(needle_line) >= 2) {
|
||||||
|
needle_line_points = lv_line_get_points_mutable(needle_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(needle_line_points == NULL) {
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t line_event_cnt = lv_obj_get_event_count(needle_line);
|
||||||
|
for(i = 0; i < line_event_cnt; i--) {
|
||||||
|
lv_event_dsc_t * dsc = lv_obj_get_event_dsc(needle_line, i);
|
||||||
|
if(lv_event_dsc_get_cb(dsc) == scale_free_line_needle_points_cb) {
|
||||||
|
needle_line_points = lv_event_dsc_get_user_data(dsc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(needle_line_points == NULL) {
|
||||||
|
needle_line_points = lv_malloc(sizeof(lv_point_precise_t) * 2);
|
||||||
|
LV_ASSERT_MALLOC(needle_line_points);
|
||||||
|
if(needle_line_points == NULL) return;
|
||||||
|
lv_obj_add_event_cb(needle_line, scale_free_line_needle_points_cb, LV_EVENT_DELETE, needle_line_points);
|
||||||
|
}
|
||||||
|
|
||||||
needle_line_points[0].x = scale_width / 2;
|
needle_line_points[0].x = scale_width / 2;
|
||||||
needle_line_points[0].y = scale_height / 2;
|
needle_line_points[0].y = scale_height / 2;
|
||||||
needle_line_points[1].x = scale_width / 2 + needle_length_x;
|
needle_line_points[1].x = scale_width / 2 + needle_length_x;
|
||||||
needle_line_points[1].y = scale_height / 2 + needle_length_y;
|
needle_line_points[1].y = scale_height / 2 + needle_length_y;
|
||||||
|
|
||||||
lv_line_set_points(needle_line, needle_line_points, 2);
|
lv_line_set_points_mutable(needle_line, needle_line_points, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lv_scale_set_image_needle_value(lv_obj_t * obj, lv_obj_t * needle_img, int32_t value)
|
void lv_scale_set_image_needle_value(lv_obj_t * obj, lv_obj_t * needle_img, int32_t value)
|
||||||
@@ -1441,4 +1466,10 @@ static void scale_store_section_line_tick_width_compensation(lv_obj_t * obj, con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void scale_free_line_needle_points_cb(lv_event_t * e)
|
||||||
|
{
|
||||||
|
lv_point_precise_t * needle_line_points = lv_event_get_user_data(e);
|
||||||
|
lv_free(needle_line_points);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -165,7 +165,9 @@ void lv_scale_set_rotation(lv_obj_t * obj, int32_t rotation);
|
|||||||
/**
|
/**
|
||||||
* Point the needle to the corresponding value through the line
|
* Point the needle to the corresponding value through the line
|
||||||
* @param obj pointer to a scale object
|
* @param obj pointer to a scale object
|
||||||
* @param needle_line needle_line of the scale
|
* @param needle_line needle_line of the scale. The line points will be allocated and
|
||||||
|
* managed by the scale unless the line point array was previously set
|
||||||
|
* using `lv_line_set_points_mutable`.
|
||||||
* @param needle_length length of the needle
|
* @param needle_length length of the needle
|
||||||
* needle_length>0 needle_length=needle_length;
|
* needle_length>0 needle_length=needle_length;
|
||||||
* needle_length<0 needle_length=radius-|needle_length|;
|
* needle_length<0 needle_length=radius-|needle_length|;
|
||||||
|
|||||||
@@ -23,9 +23,8 @@ void tearDown(void)
|
|||||||
|
|
||||||
void test_line_should_have_valid_documented_default_values(void)
|
void test_line_should_have_valid_documented_default_values(void)
|
||||||
{
|
{
|
||||||
lv_line_t * line_ptr = (lv_line_t *) line;
|
TEST_ASSERT_EQUAL_UINT16(default_point_num, lv_line_get_point_count(line));
|
||||||
TEST_ASSERT_EQUAL_UINT16(default_point_num, line_ptr->point_num);
|
TEST_ASSERT_NULL(lv_line_get_points(line));
|
||||||
TEST_ASSERT_NULL(line_ptr->point_array);
|
|
||||||
TEST_ASSERT_FALSE(lv_line_get_y_invert(line));
|
TEST_ASSERT_FALSE(lv_line_get_y_invert(line));
|
||||||
TEST_ASSERT_FALSE(lv_obj_has_flag(line, LV_OBJ_FLAG_CLICKABLE));
|
TEST_ASSERT_FALSE(lv_obj_has_flag(line, LV_OBJ_FLAG_CLICKABLE));
|
||||||
/* line doesn't have any points, so it's 0,0 in size */
|
/* line doesn't have any points, so it's 0,0 in size */
|
||||||
@@ -145,4 +144,21 @@ void test_line_dash_gap(void)
|
|||||||
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/line_2.png");
|
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/line_2.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_line_point_array_getters_and_setters(void)
|
||||||
|
{
|
||||||
|
const lv_point_precise_t points[3] = {{10, 20}, {30, 40}, {50, 60}};
|
||||||
|
lv_line_set_points(line, points, 3);
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(3, lv_line_get_point_count(line));
|
||||||
|
TEST_ASSERT_FALSE(lv_line_is_point_array_mutable(line));
|
||||||
|
TEST_ASSERT_EQUAL_PTR(points, lv_line_get_points(line));
|
||||||
|
TEST_ASSERT_NULL(lv_line_get_points_mutable(line));
|
||||||
|
|
||||||
|
lv_point_precise_t points_mutable[2] = {{10, 20}, {30, 40}};
|
||||||
|
lv_line_set_points_mutable(line, points_mutable, 2);
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(2, lv_line_get_point_count(line));
|
||||||
|
TEST_ASSERT_TRUE(lv_line_is_point_array_mutable(line));
|
||||||
|
TEST_ASSERT_EQUAL_PTR(points_mutable, lv_line_get_points(line));
|
||||||
|
TEST_ASSERT_EQUAL_PTR(points_mutable, lv_line_get_points_mutable(line));
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -364,4 +364,43 @@ void test_scale_range(void)
|
|||||||
TEST_ASSERT_EQUAL(max_range, lv_scale_get_range_max_value(scale));
|
TEST_ASSERT_EQUAL(max_range, lv_scale_get_range_max_value(scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_scale_set_line_needle_value(void)
|
||||||
|
{
|
||||||
|
lv_obj_t * scale = lv_scale_create(lv_screen_active());
|
||||||
|
lv_scale_set_mode(scale, LV_SCALE_MODE_ROUND_INNER);
|
||||||
|
|
||||||
|
lv_obj_t * line = lv_line_create(scale);
|
||||||
|
|
||||||
|
/* test the scale alocating the array */
|
||||||
|
lv_scale_set_line_needle_value(scale, line, 50, 35);
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(2, lv_line_get_point_count(line));
|
||||||
|
const lv_point_precise_t * allocated_points_array = lv_line_get_points(line);
|
||||||
|
TEST_ASSERT_NOT_NULL(allocated_points_array);
|
||||||
|
TEST_ASSERT_TRUE(lv_line_is_point_array_mutable(line));
|
||||||
|
TEST_ASSERT_EQUAL_PTR(allocated_points_array, lv_line_get_points_mutable(line));
|
||||||
|
|
||||||
|
/* test the scale using the line's pre-set mutable array */
|
||||||
|
lv_point_precise_t provided_points_array[2] = {{-100, -100}, {-100, -100}};
|
||||||
|
lv_line_set_points_mutable(line, provided_points_array, 2);
|
||||||
|
lv_scale_set_line_needle_value(scale, line, 20, 20);
|
||||||
|
TEST_ASSERT(
|
||||||
|
provided_points_array[0].x != -100 || provided_points_array[0].y != -100
|
||||||
|
|| provided_points_array[1].x != -100 || provided_points_array[1].y != -100
|
||||||
|
);
|
||||||
|
TEST_ASSERT_EQUAL_PTR(provided_points_array, lv_line_get_points_mutable(line));
|
||||||
|
|
||||||
|
provided_points_array[0].x = -100;
|
||||||
|
provided_points_array[0].y = -100;
|
||||||
|
provided_points_array[1].x = -100;
|
||||||
|
provided_points_array[1].y = -100;
|
||||||
|
/* set the line array to an immutable one. The scale will switch back to its allocated one */
|
||||||
|
lv_line_set_points(line, provided_points_array, 2); /* immutable setter */
|
||||||
|
lv_scale_set_line_needle_value(scale, line, 10, 30);
|
||||||
|
TEST_ASSERT_EQUAL_PTR(allocated_points_array, lv_line_get_points_mutable(line));
|
||||||
|
TEST_ASSERT(
|
||||||
|
provided_points_array[0].x == -100 && provided_points_array[0].y == -100
|
||||||
|
&& provided_points_array[1].x == -100 && provided_points_array[1].y == -100
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user