From 93dacfdb8fe0f9d8da500d2b20bb959a1e1ef017 Mon Sep 17 00:00:00 2001 From: Giovanni Bauermeister Date: Sun, 25 May 2025 06:41:46 -0300 Subject: [PATCH] feat: add new lvgl examples (#8225) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gabor Kiss-Vamosi Co-authored-by: André Costa --- examples/styles/index.rst | 5 + examples/styles/lv_example_style.h | 1 + examples/styles/lv_example_style_19.c | 41 ++++ examples/widgets/arc/index.rst | 5 + examples/widgets/arc/lv_example_arc_3.c | 182 ++++++++++++++++++ examples/widgets/label/index.rst | 5 + examples/widgets/label/lv_example_label_6.c | 35 ++++ examples/widgets/lv_example_widgets.h | 5 + examples/widgets/scale/index.rst | 17 ++ examples/widgets/scale/lv_example_scale_10.c | 175 +++++++++++++++++ examples/widgets/scale/lv_example_scale_11.c | 129 +++++++++++++ examples/widgets/textarea/index.rst | 5 + .../widgets/textarea/lv_example_textarea_4.c | 51 +++++ 13 files changed, 656 insertions(+) create mode 100644 examples/styles/lv_example_style_19.c create mode 100644 examples/widgets/arc/lv_example_arc_3.c create mode 100644 examples/widgets/label/lv_example_label_6.c create mode 100644 examples/widgets/scale/lv_example_scale_10.c create mode 100644 examples/widgets/scale/lv_example_scale_11.c create mode 100644 examples/widgets/textarea/lv_example_textarea_4.c diff --git a/examples/styles/index.rst b/examples/styles/index.rst index 509daa6399..6fb7b0582e 100644 --- a/examples/styles/index.rst +++ b/examples/styles/index.rst @@ -107,3 +107,8 @@ Gradients for button background .. lv_example:: styles/lv_example_style_18 :language: c +Test between recolor style or full background modal +--------------------------------------------------- + +.. lv_example:: styles/lv_example_style_19 + :language: c diff --git a/examples/styles/lv_example_style.h b/examples/styles/lv_example_style.h index 699614c492..0253591886 100644 --- a/examples/styles/lv_example_style.h +++ b/examples/styles/lv_example_style.h @@ -43,6 +43,7 @@ void lv_example_style_15(void); void lv_example_style_16(void); void lv_example_style_17(void); void lv_example_style_18(void); +void lv_example_style_19(void); /********************** * MACROS diff --git a/examples/styles/lv_example_style_19.c b/examples/styles/lv_example_style_19.c new file mode 100644 index 0000000000..a3ed7fcafb --- /dev/null +++ b/examples/styles/lv_example_style_19.c @@ -0,0 +1,41 @@ +#include "../lv_examples.h" +#if LV_BUILD_EXAMPLES && LV_USE_SLIDER + +/** + * Test between a full background modal and a recolor modal + */ +void lv_example_style_19(void) +{ + /*Add lv_example_style_11 as background*/ + lv_example_style_11(); + + /* Set to 1 to enable recolor overlay instead of solid background */ +#if 0 + /* Apply a screen-wide tint using recolor (efficient overlay). + * This modifies the visual appearance by blending a semi-transparent color + * over existing content without creating additional objects. + * It’s lighter on performance compared to a full-size background object. */ + lv_obj_set_style_recolor(lv_screen_active(), lv_color_black(), 0); + lv_obj_set_style_recolor_opa(lv_screen_active(), LV_OPA_50, 0); +#else + /* Simulate a modal background by setting a semi-transparent black background + * on lv_layer_top(), the highest built-in layer. + * This method creates a new full-screen object and can consume more resources + * compared to recolor, especially when using images or gradients. */ + lv_obj_set_style_bg_color(lv_layer_top(), lv_color_black(), 0); + lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_50, 0); +#endif + + lv_obj_t * obj = lv_slider_create(lv_layer_top()); + lv_obj_center(obj); + + lv_refr_now(NULL); /*Update layouts and render*/ + + lv_obj_invalidate(lv_screen_active()); + + uint32_t t = lv_tick_get(); + lv_refr_now(NULL); /*Render only*/ + LV_LOG_USER("%u ms\n", lv_tick_elaps(t)); +} + +#endif diff --git a/examples/widgets/arc/index.rst b/examples/widgets/arc/index.rst index f13db9c63f..80abf16ddd 100644 --- a/examples/widgets/arc/index.rst +++ b/examples/widgets/arc/index.rst @@ -12,3 +12,8 @@ Loader with Arc .. lv_example:: widgets/arc/lv_example_arc_2 :language: c +Pie Chart with clickable slices using Arcs +------------------------------------------ + +.. lv_example:: widgets/arc/lv_example_arc_3 + :language: c diff --git a/examples/widgets/arc/lv_example_arc_3.c b/examples/widgets/arc/lv_example_arc_3.c new file mode 100644 index 0000000000..77550027ea --- /dev/null +++ b/examples/widgets/arc/lv_example_arc_3.c @@ -0,0 +1,182 @@ +#include "../../lv_examples.h" + +#if LV_USE_ARC && LV_BUILD_EXAMPLES + +#define CHART_SIZE 150 +#define SLICE_OFFSET 20 + +typedef struct { + int start_angle; + int end_angle; + int mid_angle; + lv_point_t home; + bool out; +} slice_info_t; + +typedef struct { + lv_obj_t * obj; + int start_x; + int start_y; + int end_x; + int end_y; +} slice_anim_data_t; + +static float angle_accum = 0.0f; +static slice_info_t * active_info = NULL; +static lv_obj_t * active_arc = NULL; + +static void anim_move_cb(void * var, int32_t v) +{ + slice_anim_data_t * d = (slice_anim_data_t *) var; + + int32_t x = d->start_x + ((d->end_x - d->start_x) * v) / 100; + int32_t y = d->start_y + ((d->end_y - d->start_y) * v) / 100; + lv_obj_set_pos(d->obj, x, y); +} + +static void anim_cleanup_cb(lv_anim_t * a) +{ + lv_free(a->var); +} + +static void arc_click_cb(lv_event_t * e) +{ + lv_obj_t * arc = lv_event_get_target_obj(e); + slice_info_t * info = (slice_info_t *)lv_event_get_user_data(e); + + int32_t x_off = (SLICE_OFFSET * lv_trigo_cos(info->mid_angle)) >> LV_TRIGO_SHIFT; + int32_t y_off = (SLICE_OFFSET * lv_trigo_sin(info->mid_angle)) >> LV_TRIGO_SHIFT; + + if(active_info && active_info != info && active_info->out) { + slice_anim_data_t * anim_back = (slice_anim_data_t *) lv_malloc(sizeof(slice_anim_data_t)); + anim_back->obj = active_arc; + anim_back->start_x = lv_obj_get_x(active_arc) - SLICE_OFFSET; + anim_back->start_y = lv_obj_get_y(active_arc) - SLICE_OFFSET; + anim_back->end_x = active_info->home.x; + anim_back->end_y = active_info->home.y; + + active_info->out = false; + + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, anim_back); + lv_anim_set_exec_cb(&a, anim_move_cb); + lv_anim_set_time(&a, 200); + lv_anim_set_values(&a, 0, 100); + lv_anim_set_deleted_cb(&a, anim_cleanup_cb); + lv_anim_start(&a); + } + + int target_x, target_y; + if(info->out) { + target_x = info->home.x; + target_y = info->home.y; + info->out = false; + active_info = NULL; + active_arc = NULL; + } + else { + target_x = info->home.x + x_off; + target_y = info->home.y + y_off; + info->out = true; + active_info = info; + active_arc = arc; + } + + slice_anim_data_t * anim_data = (slice_anim_data_t *) lv_malloc(sizeof(slice_anim_data_t)); + anim_data->obj = arc; + anim_data->start_x = lv_obj_get_x(arc) - SLICE_OFFSET; + anim_data->start_y = lv_obj_get_y(arc) - SLICE_OFFSET; + anim_data->end_x = target_x; + anim_data->end_y = target_y; + + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, anim_data); + lv_anim_set_exec_cb(&a, anim_move_cb); + lv_anim_set_time(&a, 200); + lv_anim_set_values(&a, 0, 100); + lv_anim_set_deleted_cb(&a, anim_cleanup_cb); + lv_anim_start(&a); +} + +static void create_slice(lv_obj_t * parent, int percentage, lv_color_t color) +{ + if(percentage <= 0) return; + + float slice_angle = (percentage * 360.0f) / 100.0f; + int start = (int)(angle_accum + 0.5f); + angle_accum += slice_angle; + int end = (int)(angle_accum + 0.5f); + if(end > 360) end = 360; + + lv_obj_t * arc = lv_arc_create(parent); + lv_obj_set_size(arc, CHART_SIZE, CHART_SIZE); + lv_obj_center(arc); + + lv_arc_set_mode(arc, LV_ARC_MODE_NORMAL); + lv_arc_set_bg_start_angle(arc, start); + lv_arc_set_bg_end_angle(arc, end); + + lv_obj_set_style_arc_width(arc, CHART_SIZE / 2, LV_PART_MAIN); + lv_obj_set_style_arc_width(arc, 0, LV_PART_INDICATOR); + + lv_obj_set_style_arc_color(arc, color, LV_PART_MAIN); + lv_obj_set_style_arc_rounded(arc, false, LV_PART_MAIN); + lv_obj_remove_style(arc, NULL, LV_PART_KNOB); + lv_obj_add_flag(arc, LV_OBJ_FLAG_ADV_HITTEST); + + lv_obj_t * label = lv_label_create(arc); + lv_label_set_text_fmt(label, "%d%%", percentage); + int mid_angle = start + ((end - start) / 2); + int radius = CHART_SIZE / 4; + int x_offset = (radius * lv_trigo_cos(mid_angle)) >> LV_TRIGO_SHIFT; + int y_offset = (radius * lv_trigo_sin(mid_angle)) >> LV_TRIGO_SHIFT; + + lv_obj_align(label, LV_ALIGN_CENTER, x_offset, y_offset); + + slice_info_t * info = (slice_info_t *) lv_malloc(sizeof(slice_info_t)); + info->start_angle = start; + info->end_angle = end; + info->mid_angle = mid_angle; + info->out = false; + info->home.x = lv_obj_get_x(arc); + info->home.y = lv_obj_get_y(arc); + lv_obj_add_event_cb(arc, arc_click_cb, LV_EVENT_CLICKED, info); +} + +void lv_example_arc_3(void) +{ + /* Root container: flex row */ + lv_obj_t * root = lv_obj_create(lv_screen_active()); + lv_obj_set_size(root, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + lv_obj_center(root); + lv_obj_set_flex_flow(root, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(root, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + lv_obj_set_style_pad_all(root, 0, LV_PART_MAIN); + lv_obj_set_style_border_width(root, 0, LV_PART_MAIN); + lv_obj_set_style_border_color(root, lv_palette_main(LV_PALETTE_RED), LV_PART_MAIN); + lv_obj_set_style_bg_opa(root, LV_OPA_TRANSP, LV_PART_MAIN); + lv_obj_remove_flag(root, LV_OBJ_FLAG_SCROLLABLE); + + /* Slices container */ + lv_obj_t * slices_container = lv_obj_create(root); + lv_obj_set_size(slices_container, CHART_SIZE + 2 * SLICE_OFFSET, CHART_SIZE + 2 * SLICE_OFFSET); + lv_obj_set_style_pad_all(slices_container, 0, LV_PART_MAIN); + lv_obj_set_style_margin_all(slices_container, 0, LV_PART_MAIN); + lv_obj_set_style_border_width(slices_container, 0, LV_PART_MAIN); + lv_obj_set_style_border_color(slices_container, lv_palette_main(LV_PALETTE_BLUE), LV_PART_MAIN); + lv_obj_set_style_bg_opa(slices_container, LV_OPA_TRANSP, LV_PART_MAIN); + lv_obj_remove_flag(slices_container, LV_OBJ_FLAG_SCROLLABLE); + + /* Create slices */ + angle_accum = 0.0f; + create_slice(slices_container, 12, lv_palette_main(LV_PALETTE_RED)); + create_slice(slices_container, 18, lv_palette_main(LV_PALETTE_BLUE)); + create_slice(slices_container, 26, lv_palette_main(LV_PALETTE_GREEN)); + create_slice(slices_container, 24, lv_palette_main(LV_PALETTE_ORANGE)); + create_slice(slices_container, 20, lv_palette_main(LV_PALETTE_BLUE_GREY)); +} + +#endif diff --git a/examples/widgets/label/index.rst b/examples/widgets/label/index.rst index 3e54bacced..fc1dc21708 100644 --- a/examples/widgets/label/index.rst +++ b/examples/widgets/label/index.rst @@ -29,3 +29,8 @@ Customize circular scrolling animation .. lv_example:: widgets/label/lv_example_label_5 :language: c +Monospace font +-------------- + +.. lv_example:: widgets/label/lv_example_label_6 + :language: c diff --git a/examples/widgets/label/lv_example_label_6.c b/examples/widgets/label/lv_example_label_6.c new file mode 100644 index 0000000000..fbd662be08 --- /dev/null +++ b/examples/widgets/label/lv_example_label_6.c @@ -0,0 +1,35 @@ +#include "../../lv_examples.h" +#if LV_USE_LABEL && LV_BUILD_EXAMPLES && LV_FONT_MONTSERRAT_20 + +static bool fix_w_get_glyph_dsc(const lv_font_t * font, lv_font_glyph_dsc_t * dsc, uint32_t letter, + uint32_t letter_next) +{ + bool ret = lv_font_get_glyph_dsc_fmt_txt(font, dsc, letter, letter_next); + if(!ret) return false; + + /* Set a fixed width */ + dsc->adv_w = 20; + dsc->ofs_x = (dsc->adv_w - dsc->box_w) / 2; + return true; +} + +void lv_example_label_6(void) +{ + /* Clone the original font and override its behavior */ + static lv_font_t mono_font; + mono_font = lv_font_montserrat_20; + mono_font.get_glyph_dsc = fix_w_get_glyph_dsc; + + /* Create a label with normal font */ + lv_obj_t * label1 = lv_label_create(lv_screen_active()); + lv_obj_set_style_text_font(label1, &lv_font_montserrat_20, 0); + lv_label_set_text(label1, "0123.Wabc"); + + /* Create a label with fixed-width glyph descriptor override */ + lv_obj_t * label2 = lv_label_create(lv_screen_active()); + lv_obj_set_y(label2, 30); + lv_obj_set_style_text_font(label2, &mono_font, 0); + lv_label_set_text(label2, "0123.Wabc"); +} + +#endif diff --git a/examples/widgets/lv_example_widgets.h b/examples/widgets/lv_example_widgets.h index 9cd80307b2..c86e3500be 100644 --- a/examples/widgets/lv_example_widgets.h +++ b/examples/widgets/lv_example_widgets.h @@ -29,6 +29,7 @@ void lv_example_animimg_1(void); void lv_example_arc_1(void); void lv_example_arc_2(void); +void lv_example_arc_3(void); void lv_example_bar_1(void); void lv_example_bar_2(void); @@ -94,6 +95,7 @@ void lv_example_label_2(void); void lv_example_label_3(void); void lv_example_label_4(void); void lv_example_label_5(void); +void lv_example_label_6(void); void lv_example_led_1(void); @@ -131,6 +133,8 @@ void lv_example_scale_6(void); void lv_example_scale_7(void); 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_slider_1(void); void lv_example_slider_2(void); @@ -155,6 +159,7 @@ void lv_example_tabview_2(void); void lv_example_textarea_1(void); void lv_example_textarea_2(void); void lv_example_textarea_3(void); +void lv_example_textarea_4(void); void lv_example_tileview_1(void); diff --git a/examples/widgets/scale/index.rst b/examples/widgets/scale/index.rst index 621d7d19e1..823add5d3c 100644 --- a/examples/widgets/scale/index.rst +++ b/examples/widgets/scale/index.rst @@ -51,3 +51,20 @@ A horizontal scale with labels rotated and translated .. lv_example:: widgets/scale/lv_example_scale_9 :language: c + +A round scale style simulating a Heart Rate monitor +--------------------------------------------------- + +.. lv_example:: widgets/scale/lv_example_scale_10 + :language: c + +A round scale style simulating a sunset/sunrise widget +------------------------------------------------------ + +.. lv_example:: widgets/scale/lv_example_scale_11 + :language: c + +Axis ticks and labels with scrolling on a chart +----------------------------------------------- +.. lv_example:: widgets/chart/lv_example_chart_2 + :language: c diff --git a/examples/widgets/scale/lv_example_scale_10.c b/examples/widgets/scale/lv_example_scale_10.c new file mode 100644 index 0000000000..b6a11152ac --- /dev/null +++ b/examples/widgets/scale/lv_example_scale_10.c @@ -0,0 +1,175 @@ +#include "../../lv_examples.h" +#if LV_USE_SCALE && LV_BUILD_EXAMPLES && LV_FONT_MONTSERRAT_40 && LV_FONT_MONTSERRAT_18 + +static int32_t hr_value = 98; +static int8_t hr_step = 1; +static lv_obj_t * needle_line = NULL; +static lv_obj_t * hr_value_label = NULL; +static lv_obj_t * bpm_label = NULL; +static lv_obj_t * scale = NULL; + +typedef struct { + lv_style_t items; + lv_style_t indicator; + lv_style_t main; +} section_styles_t; + +static section_styles_t zone1_styles; +static section_styles_t zone2_styles; +static section_styles_t zone3_styles; +static section_styles_t zone4_styles; +static section_styles_t zone5_styles; + +static lv_color_t get_hr_zone_color(int32_t hr) +{ + if(hr < 117) return lv_palette_main(LV_PALETTE_GREY); /* Zone 1 */ + else if(hr < 135) return lv_palette_main(LV_PALETTE_BLUE); /* Zone 2 */ + else if(hr < 158) return lv_palette_main(LV_PALETTE_GREEN); /* Zone 3 */ + else if(hr < 176) return lv_palette_main(LV_PALETTE_ORANGE); /* Zone 4 */ + else return lv_palette_main(LV_PALETTE_RED); /* Zone 5 */ +} + +static void hr_anim_timer_cb(lv_timer_t * timer) +{ + LV_UNUSED(timer); + + hr_value += hr_step; + + if(hr_value >= 195) { + hr_value = 195; + hr_step = -1; + } + else if(hr_value <= 98) { + hr_value = 98; + hr_step = 1; + } + + /* Update needle */ + lv_scale_set_line_needle_value(scale, needle_line, -8, hr_value); + + /* Update HR text */ + lv_label_set_text_fmt(hr_value_label, "%d", hr_value); + + /* Update text color based on zone */ + lv_color_t zone_color = get_hr_zone_color(hr_value); + lv_obj_set_style_text_color(hr_value_label, zone_color, 0); + lv_obj_set_style_text_color(bpm_label, zone_color, 0); +} + +static void init_section_styles(section_styles_t * styles, lv_color_t color) +{ + lv_style_init(&styles->items); + lv_style_set_line_color(&styles->items, color); + lv_style_set_line_width(&styles->items, 0); + + lv_style_init(&styles->indicator); + lv_style_set_line_color(&styles->indicator, color); + lv_style_set_line_width(&styles->indicator, 0); + + lv_style_init(&styles->main); + lv_style_set_arc_color(&styles->main, color); + lv_style_set_arc_width(&styles->main, 20); +} + +static void add_section(lv_obj_t * target_scale, + int32_t from, + int32_t to, + const section_styles_t * styles) +{ + lv_scale_section_t * sec = lv_scale_add_section(target_scale); + lv_scale_set_section_range(target_scale, sec, from, to); + lv_scale_set_section_style_items(target_scale, sec, &styles->items); + lv_scale_set_section_style_indicator(target_scale, sec, &styles->indicator); + lv_scale_set_section_style_main(target_scale, sec, &styles->main); +} + +void lv_example_scale_10(void) +{ + scale = lv_scale_create(lv_screen_active()); + lv_obj_center(scale); + lv_obj_set_size(scale, 200, 200); + + lv_scale_set_mode(scale, LV_SCALE_MODE_ROUND_INNER); + lv_scale_set_range(scale, 98, 195); + lv_scale_set_total_tick_count(scale, 15); + lv_scale_set_major_tick_every(scale, 3); + lv_scale_set_angle_range(scale, 280); + lv_scale_set_rotation(scale, 130); + lv_scale_set_label_show(scale, false); + + lv_obj_set_style_length(scale, 6, LV_PART_ITEMS); + lv_obj_set_style_length(scale, 10, LV_PART_INDICATOR); + lv_obj_set_style_arc_width(scale, 0, LV_PART_MAIN); + + /* Zone 1: (Grey) */ + init_section_styles(&zone1_styles, lv_palette_main(LV_PALETTE_GREY)); + add_section(scale, 98, 117, &zone1_styles); + + /* Zone 2: (Blue) */ + init_section_styles(&zone2_styles, lv_palette_main(LV_PALETTE_BLUE)); + add_section(scale, 117, 135, &zone2_styles); + + /* Zone 3: (Green) */ + init_section_styles(&zone3_styles, lv_palette_main(LV_PALETTE_GREEN)); + add_section(scale, 135, 158, &zone3_styles); + + /* Zone 4: (Orange) */ + init_section_styles(&zone4_styles, lv_palette_main(LV_PALETTE_ORANGE)); + add_section(scale, 158, 176, &zone4_styles); + + /* Zone 5: (Red) */ + init_section_styles(&zone5_styles, lv_palette_main(LV_PALETTE_RED)); + add_section(scale, 176, 195, &zone5_styles); + + needle_line = lv_line_create(scale); + + /* Optional styling */ + lv_obj_set_style_line_color(needle_line, lv_color_black(), LV_PART_MAIN); + lv_obj_set_style_line_width(needle_line, 12, LV_PART_MAIN); + lv_obj_set_style_length(needle_line, 20, LV_PART_MAIN); + lv_obj_set_style_line_rounded(needle_line, false, LV_PART_MAIN); + lv_obj_set_style_pad_right(needle_line, 50, LV_PART_MAIN); + + int32_t current_hr = 145; + + lv_scale_set_line_needle_value(scale, needle_line, 0, current_hr); + + lv_obj_t * circle = lv_obj_create(lv_scr_act()); + lv_obj_set_size(circle, 130, 130); + lv_obj_center(circle); + + lv_obj_set_style_radius(circle, LV_RADIUS_CIRCLE, 0); + + lv_obj_set_style_bg_color(circle, lv_obj_get_style_bg_color(lv_scr_act(), LV_PART_MAIN), 0); + lv_obj_set_style_bg_opa(circle, LV_OPA_COVER, 0); + lv_obj_set_style_border_width(circle, 0, LV_PART_MAIN); + + lv_obj_t * hr_container = lv_obj_create(circle); + lv_obj_center(hr_container); + lv_obj_set_size(hr_container, lv_pct(100), LV_SIZE_CONTENT); + lv_obj_set_style_bg_opa(hr_container, LV_OPA_TRANSP, 0); + lv_obj_set_style_border_width(hr_container, 0, 0); + lv_obj_set_layout(hr_container, LV_LAYOUT_FLEX); + lv_obj_set_flex_flow(hr_container, LV_FLEX_FLOW_COLUMN); + lv_obj_set_style_pad_all(hr_container, 0, LV_PART_MAIN); + lv_obj_set_style_pad_row(hr_container, 0, 0); + lv_obj_set_flex_align(hr_container, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + hr_value_label = lv_label_create(hr_container); + lv_label_set_text_fmt(hr_value_label, "%d", current_hr); + lv_obj_set_style_text_font(hr_value_label, &lv_font_montserrat_40, 0); + lv_obj_set_style_text_align(hr_value_label, LV_TEXT_ALIGN_CENTER, 0); + + bpm_label = lv_label_create(hr_container); + lv_label_set_text(bpm_label, "bpm"); + lv_obj_set_style_text_font(bpm_label, &lv_font_montserrat_18, 0); + lv_obj_set_style_text_align(bpm_label, LV_TEXT_ALIGN_CENTER, 0); + + lv_color_t zone_color = get_hr_zone_color(current_hr); + lv_obj_set_style_text_color(hr_value_label, zone_color, 0); + lv_obj_set_style_text_color(bpm_label, zone_color, 0); + + lv_timer_create(hr_anim_timer_cb, 80, NULL); +} + +#endif diff --git a/examples/widgets/scale/lv_example_scale_11.c b/examples/widgets/scale/lv_example_scale_11.c new file mode 100644 index 0000000000..a419d4f58d --- /dev/null +++ b/examples/widgets/scale/lv_example_scale_11.c @@ -0,0 +1,129 @@ +#include "../../lv_examples.h" +#if LV_USE_SCALE && LV_BUILD_EXAMPLES && LV_FONT_MONTSERRAT_12 && LV_FONT_MONTSERRAT_14 && LV_FONT_MONTSERRAT_16 && LV_FONT_MONTSERRAT_20 + +static void label_color_cb(lv_event_t * e) +{ + lv_draw_task_t * draw_task = lv_event_get_draw_task(e); + if(!draw_task) return; + + lv_draw_dsc_base_t * base_dsc = (lv_draw_dsc_base_t *)lv_draw_task_get_draw_dsc(draw_task); + if(!base_dsc || base_dsc->part != LV_PART_INDICATOR) return; + + lv_draw_label_dsc_t * label_dsc = lv_draw_task_get_label_dsc(draw_task); + if(!label_dsc || !label_dsc->text) return; + + const char * txt = label_dsc->text; + + if(lv_strcmp(txt, "06") == 0 || lv_strcmp(txt, "12") == 0 || + lv_strcmp(txt, "18") == 0 || lv_strcmp(txt, "24") == 0) { + label_dsc->color = lv_color_white(); + } + else { + label_dsc->color = lv_palette_darken(LV_PALETTE_GREY, 1); + } +} + +void lv_example_scale_11(void) +{ + lv_obj_t * bg = lv_obj_create(lv_screen_active()); + lv_obj_set_size(bg, 210, 210); + lv_obj_center(bg); + lv_obj_set_style_radius(bg, LV_RADIUS_CIRCLE, 0); + lv_obj_set_style_bg_color(bg, lv_palette_darken(LV_PALETTE_GREY, 4), 0); + lv_obj_set_style_bg_opa(bg, LV_OPA_COVER, 0); + lv_obj_remove_flag(bg, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_style_pad_all(bg, 0, LV_PART_MAIN); + + lv_obj_t * scale = lv_scale_create(bg); + lv_obj_center(scale); + lv_obj_set_size(scale, 150, 150); + lv_obj_set_style_arc_width(scale, 5, LV_PART_MAIN); + + lv_scale_set_mode(scale, LV_SCALE_MODE_ROUND_OUTER); + lv_scale_set_range(scale, 0, 24); + lv_scale_set_total_tick_count(scale, 25); + lv_scale_set_major_tick_every(scale, 1); + lv_scale_set_angle_range(scale, 360); + lv_scale_set_rotation(scale, 105); + lv_scale_set_label_show(scale, true); + lv_obj_set_style_text_font(scale, &lv_font_montserrat_12, LV_PART_INDICATOR); + lv_obj_set_style_pad_radial(scale, -6, LV_PART_INDICATOR); + + /*Rotate the labels of the ticks*/ + lv_obj_set_style_transform_rotation(scale, LV_SCALE_LABEL_ROTATE_MATCH_TICKS | LV_SCALE_LABEL_ROTATE_KEEP_UPRIGHT, + LV_PART_INDICATOR); + + /* Style for major ticks */ + static lv_style_t style_ticks; + lv_style_init(&style_ticks); + lv_style_set_line_color(&style_ticks, lv_palette_darken(LV_PALETTE_GREY, 1)); + lv_style_set_line_width(&style_ticks, 2); + lv_style_set_width(&style_ticks, 10); + lv_obj_add_style(scale, &style_ticks, LV_PART_INDICATOR); + + /* Style for NIGHT — blue */ + static lv_style_t style_night; + lv_style_init(&style_night); + lv_style_set_arc_color(&style_night, lv_palette_main(LV_PALETTE_BLUE)); + + /* Style for DAY — dark yellow */ + static lv_style_t style_day; + lv_style_init(&style_day); + lv_style_set_arc_color(&style_day, lv_palette_darken(LV_PALETTE_YELLOW, 3)); + + /* NIGHT section */ + lv_scale_section_t * section_night1 = lv_scale_add_section(scale); + lv_scale_set_section_range(scale, section_night1, 17, 5); + lv_scale_set_section_style_main(scale, section_night1, &style_night); + + /* DAY section */ + lv_scale_section_t * section_day = lv_scale_add_section(scale); + lv_scale_set_section_range(scale, section_day, 5, 17); + lv_scale_set_section_style_main(scale, section_day, &style_day); + + + static const char * hour_labels[] = { + "01", "02", "03", "04", "05", + "06", "07", "08", "09", "10", + "11", "12", "13", "14", "15", + "16", "17", "18", "19", "20", + "21", "22", "23", "24", + NULL + }; + lv_scale_set_text_src(scale, hour_labels); + + lv_obj_add_flag(scale, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS); + lv_obj_add_event_cb(scale, label_color_cb, LV_EVENT_DRAW_TASK_ADDED, NULL); + + lv_obj_t * today = lv_label_create(bg); + lv_label_set_text(today, "TODAY"); + lv_obj_set_style_text_font(today, &lv_font_montserrat_16, 0); + lv_obj_set_style_text_color(today, lv_color_white(), 0); + lv_obj_align(today, LV_ALIGN_TOP_MID, 0, 60); + + lv_obj_t * sunrise_lbl = lv_label_create(bg); + lv_label_set_text(sunrise_lbl, "SUNRISE"); + lv_obj_set_style_text_font(sunrise_lbl, &lv_font_montserrat_14, 0); + lv_obj_set_style_text_color(sunrise_lbl, lv_palette_main(LV_PALETTE_GREY), 0); + lv_obj_align(sunrise_lbl, LV_ALIGN_LEFT_MID, 37, -10); + + lv_obj_t * sunrise_time = lv_label_create(bg); + lv_label_set_text(sunrise_time, "6:43"); + lv_obj_set_style_text_font(sunrise_time, &lv_font_montserrat_20, 0); + lv_obj_set_style_text_color(sunrise_time, lv_color_white(), 0); + lv_obj_align_to(sunrise_time, sunrise_lbl, LV_ALIGN_OUT_BOTTOM_MID, 0, 2); + + lv_obj_t * sunset_lbl = lv_label_create(bg); + lv_label_set_text(sunset_lbl, "SUNSET"); + lv_obj_set_style_text_font(sunset_lbl, &lv_font_montserrat_14, 0); + lv_obj_set_style_text_color(sunset_lbl, lv_palette_main(LV_PALETTE_GREY), 0); + lv_obj_align(sunset_lbl, LV_ALIGN_RIGHT_MID, -37, -10); + + lv_obj_t * sunset_time = lv_label_create(bg); + lv_label_set_text(sunset_time, "17:37"); + lv_obj_set_style_text_font(sunset_time, &lv_font_montserrat_20, 0); + lv_obj_set_style_text_color(sunset_time, lv_color_white(), 0); + lv_obj_align_to(sunset_time, sunset_lbl, LV_ALIGN_OUT_BOTTOM_MID, 0, 2); +} + +#endif diff --git a/examples/widgets/textarea/index.rst b/examples/widgets/textarea/index.rst index b70275ad20..7bbe2d6561 100644 --- a/examples/widgets/textarea/index.rst +++ b/examples/widgets/textarea/index.rst @@ -18,3 +18,8 @@ Text auto-formatting .. lv_example:: widgets/textarea/lv_example_textarea_3 :language: c +Text area cursor styling +------------------------ + +.. lv_example:: widgets/textarea/lv_example_textarea_4 + :language: c diff --git a/examples/widgets/textarea/lv_example_textarea_4.c b/examples/widgets/textarea/lv_example_textarea_4.c new file mode 100644 index 0000000000..14851a9e80 --- /dev/null +++ b/examples/widgets/textarea/lv_example_textarea_4.c @@ -0,0 +1,51 @@ +#include "../../lv_examples.h" +#if LV_USE_TEXTAREA && LV_USE_KEYBOARD && LV_BUILD_EXAMPLES + +static void create_styled_textarea_cursor(const char * txt, lv_coord_t y_ofs, lv_style_t * cursor_style) +{ + lv_obj_t * ta = lv_textarea_create(lv_screen_active()); + lv_textarea_set_text(ta, txt); + lv_obj_set_width(ta, 280); + lv_obj_align(ta, LV_ALIGN_TOP_MID, 0, y_ofs); + lv_textarea_set_one_line(ta, true); + lv_obj_add_state(ta, LV_STATE_FOCUSED); + lv_obj_add_style(ta, cursor_style, LV_PART_CURSOR | LV_STATE_FOCUSED); + lv_textarea_set_cursor_pos(ta, 0); +} + +void lv_example_textarea_4(void) +{ + static lv_style_t style_simple, style_block, style_underline; + + /* Thin left bar cursor (simple) */ + lv_style_init(&style_simple); + lv_style_set_border_color(&style_simple, lv_palette_main(LV_PALETTE_RED)); + + /* Underline cursor */ + lv_style_init(&style_underline); + lv_style_set_bg_opa(&style_underline, LV_OPA_TRANSP); + lv_style_set_border_color(&style_underline, lv_palette_main(LV_PALETTE_BLUE)); + lv_style_set_border_side(&style_underline, LV_BORDER_SIDE_BOTTOM); + lv_style_set_pad_hor(&style_underline, 1); /* set width of cursor using pad */ + lv_style_set_border_width(&style_underline, 3); /* set thickness of underline cursor */ + + /* Full block cursor with many styles */ + lv_style_init(&style_block); + lv_style_set_bg_opa(&style_block, LV_OPA_COVER); + lv_style_set_bg_color(&style_block, lv_palette_main(LV_PALETTE_ORANGE)); + lv_style_set_bg_grad_color(&style_block, lv_palette_main(LV_PALETTE_YELLOW)); + lv_style_set_bg_grad_dir(&style_block, LV_GRAD_DIR_VER); + lv_style_set_border_color(&style_block, lv_palette_main(LV_PALETTE_RED)); + lv_style_set_border_side(&style_block, LV_BORDER_SIDE_FULL); + lv_style_set_border_width(&style_block, 1); + lv_style_set_radius(&style_block, 4); + lv_style_set_text_color(&style_block, lv_color_white()); + lv_style_set_pad_all(&style_block, 1); /* set width of cursor using pad */ + + /* Create 3 independent textareas, each with a unique styled cursor */ + create_styled_textarea_cursor("This is a simple red cursor", 10, &style_simple); + create_styled_textarea_cursor("This is an underline blue cursor", 110, &style_underline); + create_styled_textarea_cursor("This is a complex block cursor", 60, &style_block); +} + +#endif