From b89bf8a1d358b84db2f019184a90997b18188ca8 Mon Sep 17 00:00:00 2001 From: Felix Biego <45796740+fbiego@users.noreply.github.com> Date: Mon, 23 Jun 2025 20:50:22 +0300 Subject: [PATCH] examples(scale): Compass style rotating scale (#8445) --- examples/widgets/lv_example_widgets.h | 1 + examples/widgets/scale/index.rst | 6 + examples/widgets/scale/lv_example_scale_12.c | 109 +++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 examples/widgets/scale/lv_example_scale_12.c diff --git a/examples/widgets/lv_example_widgets.h b/examples/widgets/lv_example_widgets.h index 1787a40bc3..233c0172f4 100644 --- a/examples/widgets/lv_example_widgets.h +++ b/examples/widgets/lv_example_widgets.h @@ -137,6 +137,7 @@ void lv_example_scale_8(void); void lv_example_scale_9(void); void lv_example_scale_10(void); void lv_example_scale_11(void); +void lv_example_scale_12(void); void lv_example_slider_1(void); void lv_example_slider_2(void); diff --git a/examples/widgets/scale/index.rst b/examples/widgets/scale/index.rst index 823add5d3c..98dcd9c534 100644 --- a/examples/widgets/scale/index.rst +++ b/examples/widgets/scale/index.rst @@ -64,6 +64,12 @@ A round scale style simulating a sunset/sunrise widget .. lv_example:: widgets/scale/lv_example_scale_11 :language: c +A round scale style simulating a compass +---------------------------------------- + +.. lv_example:: widgets/scale/lv_example_scale_12 + :language: c + Axis ticks and labels with scrolling on a chart ----------------------------------------------- .. lv_example:: widgets/chart/lv_example_chart_2 diff --git a/examples/widgets/scale/lv_example_scale_12.c b/examples/widgets/scale/lv_example_scale_12.c new file mode 100644 index 0000000000..760c387710 --- /dev/null +++ b/examples/widgets/scale/lv_example_scale_12.c @@ -0,0 +1,109 @@ +#include "../../lv_examples.h" +#if LV_USE_SCALE && LV_BUILD_EXAMPLES + +static lv_obj_t * scale; +static lv_obj_t * label; + +static const char * heading_to_cardinal(int32_t heading) +{ + /* Normalize heading to range [0, 360) */ + while(heading < 0) heading += 360; + while(heading >= 360) heading -= 360; + + if(heading < 23) return "N"; + else if(heading < 68) return "NE"; + else if(heading < 113) return "E"; + else if(heading < 158) return "SE"; + else if(heading < 203) return "S"; + else if(heading < 248) return "SW"; + else if(heading < 293) return "W"; + else if(heading < 338) return "NW"; + + return "N"; +} + +static void set_heading_value(void * obj, int32_t v) +{ + LV_UNUSED(obj); + lv_scale_set_rotation(scale, 270 - v); + lv_label_set_text_fmt(label, "%d°\n%s", v, heading_to_cardinal(v)); +} + +static void draw_event_cb(lv_event_t * e) +{ + lv_draw_task_t * draw_task = lv_event_get_draw_task(e); + lv_draw_dsc_base_t * base_dsc = (lv_draw_dsc_base_t *)lv_draw_task_get_draw_dsc(draw_task); + lv_draw_label_dsc_t * label_draw_dsc = lv_draw_task_get_label_dsc(draw_task); + lv_draw_line_dsc_t * line_draw_dsc = lv_draw_task_get_line_dsc(draw_task); + if(base_dsc->part == LV_PART_INDICATOR) { + if(label_draw_dsc) { + if(base_dsc->id1 == 0) { + label_draw_dsc->color = lv_palette_main(LV_PALETTE_RED); + } + } + if(line_draw_dsc) { + if(base_dsc->id1 == 60) { + line_draw_dsc->color = lv_palette_main(LV_PALETTE_RED); + } + } + } +} + +/** + * A round scale style simulating a compass + */ +void lv_example_scale_12(void) +{ + scale = lv_scale_create(lv_screen_active()); + + lv_obj_set_size(scale, 200, 200); + lv_scale_set_mode(scale, LV_SCALE_MODE_ROUND_INNER); + lv_obj_set_align(scale, LV_ALIGN_CENTER); + + lv_scale_set_total_tick_count(scale, 61); + lv_scale_set_major_tick_every(scale, 5); + + lv_obj_set_style_length(scale, 5, LV_PART_ITEMS); + lv_obj_set_style_length(scale, 10, LV_PART_INDICATOR); + lv_obj_set_style_line_width(scale, 3, LV_PART_INDICATOR); + lv_scale_set_range(scale, 0, 360); + + static const char * custom_labels[] = {"N", "30", "60", "E", "120", "150", "S", "210", "240", "W", "300", "330", NULL}; + lv_scale_set_text_src(scale, custom_labels); + + lv_scale_set_angle_range(scale, 360); + lv_scale_set_rotation(scale, 270); + + lv_obj_add_event_cb(scale, draw_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL); + lv_obj_add_flag(scale, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS); + + label = lv_label_create(lv_screen_active()); + lv_obj_set_width(label, 100); + lv_obj_set_align(label, LV_ALIGN_CENTER); + lv_label_set_text(label, "0°\nN"); + lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); + + set_heading_value(NULL, 0); + + lv_obj_t * symbol = lv_label_create(scale); + lv_obj_set_align(symbol, LV_ALIGN_TOP_MID); + lv_obj_set_y(symbol, 5); + lv_label_set_text(symbol, LV_SYMBOL_UP); + lv_obj_set_style_text_align(symbol, LV_TEXT_ALIGN_CENTER, 0); + lv_obj_set_style_text_color(symbol, lv_palette_main(LV_PALETTE_RED), 0); + + lv_anim_t anim_scale; + lv_anim_init(&anim_scale); + lv_anim_set_var(&anim_scale, scale); + lv_anim_set_exec_cb(&anim_scale, set_heading_value); + lv_anim_set_duration(&anim_scale, 5000); + lv_anim_set_repeat_delay(&anim_scale, 500); + lv_anim_set_repeat_count(&anim_scale, LV_ANIM_REPEAT_INFINITE); + lv_anim_set_reverse_duration(&anim_scale, 5000); + lv_anim_set_reverse_delay(&anim_scale, 500); + lv_anim_set_values(&anim_scale, 0, 360); + lv_anim_start(&anim_scale); + +} + +#endif