1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

feat(needle): add needle support (#4938)

Signed-off-by: lhdjply <lhdjply@126.com>
This commit is contained in:
lhdjply 2023-12-06 17:51:09 +08:00 committed by GitHub
parent de77e77882
commit 7dc792f6dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 191 additions and 16 deletions

View File

@ -854,7 +854,7 @@ static void analytics_create(lv_obj_t * parent)
lv_label_set_text(mbps_unit_label, "Mbps");
lv_anim_init(&a);
lv_anim_set_values(&a, 0, 60);
lv_anim_set_values(&a, 10, 60);
lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
lv_anim_set_exec_cb(&a, scale3_anim_cb);
lv_anim_set_var(&a, needle);
@ -1617,9 +1617,8 @@ static void scale3_anim_cb(void * var, int32_t v)
{
LV_UNUSED(var);
int32_t angle = lv_map(v, 0, 60, 1350, 3600);
lv_obj_t * needle = lv_obj_get_child(scale3, 0);
lv_image_set_rotation(needle, angle);
lv_scale_set_image_needle_value(scale3, needle, v);
lv_obj_t * label = lv_obj_get_child(scale3, 1);
lv_label_set_text_fmt(label, "%"LV_PRId32, v);

View File

@ -1,27 +1,98 @@
#include "../../lv_examples.h"
#if LV_USE_SCALE && LV_BUILD_EXAMPLES
LV_IMAGE_DECLARE(img_hand);
lv_obj_t * needle_line;
lv_obj_t * needle_img;
static void set_needle_line_value(void * obj, int32_t v)
{
lv_scale_set_line_needle_value(obj, needle_line, 60, v);
}
static void set_needle_img_value(void * obj, int32_t v)
{
lv_scale_set_image_needle_value(obj, needle_img, v);
}
/**
* A simple round scale
*/
void lv_example_scale_3(void)
{
lv_obj_t * 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_COVER, 0);
lv_obj_set_style_bg_color(scale, lv_palette_lighten(LV_PALETTE_RED, 5), 0);
lv_obj_set_style_radius(scale, LV_RADIUS_CIRCLE, 0);
lv_obj_center(scale);
lv_obj_t * scale_line = lv_scale_create(lv_screen_active());
lv_scale_set_label_show(scale, true);
lv_obj_set_size(scale_line, 150, 150);
lv_scale_set_mode(scale_line, LV_SCALE_MODE_ROUND_INNER);
lv_obj_set_style_bg_opa(scale_line, LV_OPA_COVER, 0);
lv_obj_set_style_bg_color(scale_line, lv_palette_lighten(LV_PALETTE_RED, 5), 0);
lv_obj_set_style_radius(scale_line, LV_RADIUS_CIRCLE, 0);
lv_obj_set_style_clip_corner(scale_line, true, 0);
lv_obj_align(scale_line, LV_ALIGN_LEFT_MID, LV_PCT(5), 0);
lv_scale_set_total_tick_count(scale, 31);
lv_scale_set_major_tick_every(scale, 5);
lv_scale_set_label_show(scale_line, true);
lv_scale_set_major_tick_length(scale, 10);
lv_scale_set_minor_tick_length(scale, 5);
lv_scale_set_range(scale, 10, 40);
lv_scale_set_total_tick_count(scale_line, 31);
lv_scale_set_major_tick_every(scale_line, 5);
lv_scale_set_major_tick_length(scale_line, 10);
lv_scale_set_minor_tick_length(scale_line, 5);
lv_scale_set_range(scale_line, 10, 40);
lv_scale_set_round_props(scale_line, 270, 135);
needle_line = lv_line_create(scale_line);
lv_obj_set_style_line_width(needle_line, 6, LV_PART_MAIN);
lv_obj_set_style_line_rounded(needle_line, true, LV_PART_MAIN);
lv_anim_t anim_scale_line;
lv_anim_init(&anim_scale_line);
lv_anim_set_var(&anim_scale_line, scale_line);
lv_anim_set_exec_cb(&anim_scale_line, set_needle_line_value);
lv_anim_set_time(&anim_scale_line, 1000);
lv_anim_set_repeat_count(&anim_scale_line, LV_ANIM_REPEAT_INFINITE);
lv_anim_set_playback_time(&anim_scale_line, 1000);
lv_anim_set_values(&anim_scale_line, 10, 40);
lv_anim_start(&anim_scale_line);
lv_obj_t * scale_img = lv_scale_create(lv_screen_active());
lv_obj_set_size(scale_img, 150, 150);
lv_scale_set_mode(scale_img, LV_SCALE_MODE_ROUND_INNER);
lv_obj_set_style_bg_opa(scale_img, LV_OPA_COVER, 0);
lv_obj_set_style_bg_color(scale_img, lv_palette_lighten(LV_PALETTE_RED, 5), 0);
lv_obj_set_style_radius(scale_img, LV_RADIUS_CIRCLE, 0);
lv_obj_set_style_clip_corner(scale_img, true, 0);
lv_obj_align(scale_img, LV_ALIGN_RIGHT_MID, LV_PCT(-5), 0);
lv_scale_set_label_show(scale_img, true);
lv_scale_set_total_tick_count(scale_img, 31);
lv_scale_set_major_tick_every(scale_img, 5);
lv_scale_set_major_tick_length(scale_img, 10);
lv_scale_set_minor_tick_length(scale_img, 5);
lv_scale_set_range(scale_img, 10, 40);
lv_scale_set_round_props(scale_img, 270, 135);
/* image must point to the right. E.g. -O------>*/
needle_img = lv_img_create(scale_img);
lv_image_set_src(needle_img, &img_hand);
lv_obj_align(needle_img, LV_ALIGN_CENTER, 47, -2);
lv_image_set_pivot(needle_img, 3, 4);
lv_anim_t anim_scale_img;
lv_anim_init(&anim_scale_img);
lv_anim_set_var(&anim_scale_img, scale_img);
lv_anim_set_exec_cb(&anim_scale_img, set_needle_img_value);
lv_anim_set_time(&anim_scale_img, 1000);
lv_anim_set_repeat_count(&anim_scale_img, LV_ANIM_REPEAT_INFINITE);
lv_anim_set_playback_time(&anim_scale_img, 1000);
lv_anim_set_values(&anim_scale_img, 10, 40);
lv_anim_start(&anim_scale_img);
}
#endif

View File

@ -182,6 +182,88 @@ void lv_scale_set_round_props(lv_obj_t * obj, uint32_t angle_range, int32_t rota
lv_obj_invalidate(obj);
}
void lv_scale_set_line_needle_value(lv_obj_t * obj, lv_obj_t * needle_line, int32_t needle_length,
int32_t value)
{
int32_t angle;
int32_t scale_width, scale_height;
int32_t actual_needle_length;
int32_t needle_length_x, needle_length_y;
static lv_point_precise_t needle_line_points[2];
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_scale_t * scale = (lv_scale_t *)obj;
if((scale->mode != LV_SCALE_MODE_ROUND_INNER) &&
(scale->mode != LV_SCALE_MODE_ROUND_OUTER)) {
return;
}
lv_obj_align(needle_line, LV_ALIGN_TOP_LEFT, 0, 0);
scale_width = lv_obj_get_style_width(obj, LV_PART_MAIN);
scale_height = lv_obj_get_style_height(obj, LV_PART_MAIN);
if(scale_width != scale_height) {
return;
}
if(needle_length >= scale_width / 2) {
actual_needle_length = scale_width / 2;
}
else if(needle_length >= 0) {
actual_needle_length = needle_length;
}
else if(needle_length + scale_width / 2 < 0) {
actual_needle_length = 0;
}
else {
actual_needle_length = scale_width / 2 + needle_length;
}
if(value < scale->range_min) {
angle = 0;
}
else if(value > scale->range_max) {
angle = scale->angle_range;
}
else {
angle = scale->angle_range * (value - scale->range_min) / (scale->range_max - scale->range_min);
}
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_line_points[0].x = scale_width / 2;
needle_line_points[0].y = scale_height / 2;
needle_line_points[1].x = scale_width / 2 + needle_length_x;
needle_line_points[1].y = scale_height / 2 + needle_length_y;
lv_line_set_points(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)
{
int32_t angle;
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_scale_t * scale = (lv_scale_t *)obj;
if((scale->mode != LV_SCALE_MODE_ROUND_INNER) &&
(scale->mode != LV_SCALE_MODE_ROUND_OUTER)) {
return;
}
if(value < scale->range_min) {
angle = 0;
}
else if(value > scale->range_max) {
angle = scale->angle_range;
}
else {
angle = scale->angle_range * (value - scale->range_min) / (scale->range_max - scale->range_min);
}
lv_image_set_rotation(needle_img, (scale->rotation + angle) * 10);
}
void lv_scale_set_text_src(lv_obj_t * obj, const char * txt_src[])
{
LV_ASSERT_OBJ(obj, MY_CLASS);

View File

@ -18,6 +18,8 @@ extern "C" {
#if LV_USE_SCALE != 0
#include "../../core/lv_obj.h"
#include "../line/lv_line.h"
#include "../image/lv_image.h"
/*********************
* DEFINES
@ -169,6 +171,27 @@ void lv_scale_set_range(lv_obj_t * obj, int32_t min, int32_t max);
*/
void lv_scale_set_round_props(lv_obj_t * obj, uint32_t angle_range, int32_t rotation);
/**
* Point the needle to the corresponding value through the line
* @param obj pointer to a scale object
* @param needle_line needle_line of the scale
* @param needle_length length of the needle
* needle_length>0 needle_length=needle_length;
* needle_length<0 needle_length=radius-|needle_length|;
* @param value needle to point to the corresponding value
*/
void lv_scale_set_line_needle_value(lv_obj_t * obj, lv_obj_t * needle_line, int32_t needle_length,
int32_t value);
/**
* Point the needle to the corresponding value through the image,
image must point to the right. E.g. -O------>
* @param obj pointer to a scale object
* @param needle_img needle_img of the scale
* @param value needle to point to the corresponding value
*/
void lv_scale_set_image_needle_value(lv_obj_t * obj, lv_obj_t * needle_img, int32_t value);
/**
* Set custom text source for major ticks labels
* @param obj pointer to a scale object