From 73b0317087cb617ba0f245f95828239e48421b04 Mon Sep 17 00:00:00 2001 From: Zapta Date: Thu, 17 Jun 2021 19:52:39 -0700 Subject: [PATCH] Patched LVGL 7.11.0 to support chart minor division lines and added them in two screens. --- platformio/lib/lvgl.7.11.0/lvgl.h | 4 +- .../lib/lvgl.7.11.0/src/lv_widgets/lv_chart.c | 40 +++++++++++++++++-- .../lib/lvgl.7.11.0/src/lv_widgets/lv_chart.h | 5 +++ platformio/src/ui/osciloscope_screen.cpp | 8 ++-- platformio/src/ui/phase_screen.cpp | 4 +- platformio/src/ui/ui.cpp | 17 ++++++-- platformio/src/ui/ui.h | 1 + 7 files changed, 66 insertions(+), 13 deletions(-) diff --git a/platformio/lib/lvgl.7.11.0/lvgl.h b/platformio/lib/lvgl.7.11.0/lvgl.h index 4aa1d7e..689b302 100644 --- a/platformio/lib/lvgl.7.11.0/lvgl.h +++ b/platformio/lib/lvgl.7.11.0/lvgl.h @@ -16,7 +16,9 @@ extern "C" { #define LVGL_VERSION_MAJOR 7 #define LVGL_VERSION_MINOR 11 #define LVGL_VERSION_PATCH 0 -#define LVGL_VERSION_INFO "" +// Patches: +// June 2021 zapta - Added to lv_chart specification of minor division lines. +#define LVGL_VERSION_INFO "7.11.0.patched" /********************* * INCLUDES diff --git a/platformio/lib/lvgl.7.11.0/src/lv_widgets/lv_chart.c b/platformio/lib/lvgl.7.11.0/src/lv_widgets/lv_chart.c index edff8aa..a8b6ea4 100644 --- a/platformio/lib/lvgl.7.11.0/src/lv_widgets/lv_chart.c +++ b/platformio/lib/lvgl.7.11.0/src/lv_widgets/lv_chart.c @@ -108,6 +108,12 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy) ext->hdiv_cnt = LV_CHART_HDIV_DEF; ext->vdiv_cnt = LV_CHART_VDIV_DEF; + // Patch(zapta): Lines whose index has a set bit here use + // an alternative line specification. Used to draw minor + // division lines. + ext->hdiv_minor_div_lines_mask = 0; + ext->vdiv_minor_div_lines_mask = 0; + // ext->point_cnt = LV_CHART_PNUM_DEF; ext->type = LV_CHART_TYPE_LINE; ext->update_mode = LV_CHART_UPDATE_MODE_SHIFT; @@ -147,6 +153,8 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy) ext->type = ext_copy->type; ext->hdiv_cnt = ext_copy->hdiv_cnt; ext->vdiv_cnt = ext_copy->vdiv_cnt; + ext->hdiv_minor_div_lines_mask = ext_copy->hdiv_minor_div_lines_mask; + ext->vdiv_minor_div_lines_mask = ext_copy->vdiv_minor_div_lines_mask; ext->point_cnt = ext_copy->point_cnt; _lv_memcpy_small(ext->ymin, ext_copy->ymin, sizeof(ext->ymin)); _lv_memcpy_small(ext->ymax, ext_copy->ymax, sizeof(ext->ymax)); @@ -312,6 +320,20 @@ void lv_chart_set_div_line_count(lv_obj_t * chart, uint8_t hdiv, uint8_t vdiv) lv_obj_invalidate(chart); } +// Patch(zapta): Allows to specify division lines with alternative color, width, +// etc. +void lv_chart_set_minor_div_lines_masks(lv_obj_t * chart, uint32_t hdiv_mask, uint32_t vdiv_mask) +{ + LV_ASSERT_OBJ(chart, LV_OBJX_NAME); + + lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); + + ext->hdiv_minor_div_lines_mask = hdiv_mask; + ext->vdiv_minor_div_lines_mask = vdiv_mask; + + lv_obj_invalidate(chart); +} + /** * Set the minimal and maximal y values on an axis * @param chart pointer to a graph background object @@ -1070,6 +1092,14 @@ static void draw_series_bg(lv_obj_t * chart, const lv_area_t * series_area, cons lv_coord_t x_ofs = series_area->x1; lv_coord_t y_ofs = series_area->y1; + // Patch(zapta): For minor division line specification we use + // the line specification from that chart's BG part. + lv_draw_line_dsc_t minor_line_dsc; + lv_draw_line_dsc_init(&minor_line_dsc); + lv_obj_init_draw_line_dsc(chart, LV_CHART_PART_BG, &minor_line_dsc); + // + + // Normal division line specification comes from the series BG part. lv_draw_line_dsc_t line_dsc; lv_draw_line_dsc_init(&line_dsc); lv_obj_init_draw_line_dsc(chart, LV_CHART_PART_SERIES_BG, &line_dsc); @@ -1088,10 +1118,12 @@ static void draw_series_bg(lv_obj_t * chart, const lv_area_t * series_area, cons p1.x = 0 + x_ofs; p2.x = w - 1 + x_ofs; for(div_i = div_i_start; div_i <= div_i_end; div_i++) { - p1.y = (int32_t)((int32_t)(h - line_dsc.width) * div_i) / (ext->hdiv_cnt + 1); + const bool is_minor = ext->hdiv_minor_div_lines_mask & (1u << div_i); + lv_draw_line_dsc_t* const l_dsc = is_minor ? &minor_line_dsc : &line_dsc; + p1.y = (int32_t)((int32_t)(h - l_dsc->width) * div_i) / (ext->hdiv_cnt + 1); p1.y += y_ofs; p2.y = p1.y; - lv_draw_line(&p1, &p2, clip_area, &line_dsc); + lv_draw_line(&p1, &p2, clip_area, l_dsc); } } @@ -1109,10 +1141,12 @@ static void draw_series_bg(lv_obj_t * chart, const lv_area_t * series_area, cons p1.y = 0 + y_ofs; p2.y = h + y_ofs - 1; for(div_i = div_i_start; div_i <= div_i_end; div_i++) { + const bool is_minor_line = ext->vdiv_minor_div_lines_mask & (1u << div_i); + lv_draw_line_dsc_t* const l_dsc = is_minor_line ? &minor_line_dsc : &line_dsc; p1.x = (int32_t)((int32_t)(w - line_dsc.width) * div_i) / (ext->vdiv_cnt + 1); p1.x += x_ofs; p2.x = p1.x; - lv_draw_line(&p1, &p2, clip_area, &line_dsc); + lv_draw_line(&p1, &p2, clip_area, l_dsc); } } } diff --git a/platformio/lib/lvgl.7.11.0/src/lv_widgets/lv_chart.h b/platformio/lib/lvgl.7.11.0/src/lv_widgets/lv_chart.h index 2b1ea07..f372f82 100644 --- a/platformio/lib/lvgl.7.11.0/src/lv_widgets/lv_chart.h +++ b/platformio/lib/lvgl.7.11.0/src/lv_widgets/lv_chart.h @@ -118,6 +118,9 @@ typedef struct { lv_chart_axis_cfg_t x_axis; lv_chart_axis_cfg_t secondary_y_axis; uint8_t update_mode : 1; + // Patch(zapta): Masks for identifying minor division lines. + uint32_t hdiv_minor_div_lines_mask; + uint32_t vdiv_minor_div_lines_mask; } lv_chart_ext_t; /*Parts of the chart*/ @@ -196,6 +199,8 @@ void lv_chart_hide_series(lv_obj_t * chart, lv_chart_series_t * series, bool hid */ void lv_chart_set_div_line_count(lv_obj_t * chart, uint8_t hdiv, uint8_t vdiv); +void lv_chart_set_minor_div_lines_masks(lv_obj_t * chart, uint32_t hdiv_mask, uint32_t vdiv_mask); + /** * Set the minimal and maximal y values on an axis * @param chart pointer to a graph background object diff --git a/platformio/src/ui/osciloscope_screen.cpp b/platformio/src/ui/osciloscope_screen.cpp index a334efe..5b8b257 100644 --- a/platformio/src/ui/osciloscope_screen.cpp +++ b/platformio/src/ui/osciloscope_screen.cpp @@ -7,15 +7,15 @@ static const ui::ChartAxisConfigs kAxisConfigsNormal{ .y_range = {.min = -2500, .max = 2500}, - .x = {.labels = "0\n5ms\n10ms\n15ms\n20ms", .num_ticks = 5, .dividers = 3}, - .y = {.labels = "2.5A\n0\n-2.5A", .num_ticks = 3, .dividers = 1}}; + .x = {.labels = "0\n5ms\n10ms\n15ms\n20ms", .num_ticks = 5, .dividers = 19, .minor_div_lines_mask = 0xf7bde}, + .y = {.labels = "2.5A\n0\n-2.5A", .num_ticks = 3, .dividers = 9, .minor_div_lines_mask = 0x03de}}; static const ui::ChartAxisConfigs kAxisConfigsAlternative{ .y_range = {.min = -2500, .max = 2500}, .x = {.labels = "0\n20ms\n40ms\n60ms\n80ms\n100ms", .num_ticks = 6, - .dividers = 4}, - .y = {.labels = "2.5A\n0\n-2.5A", .num_ticks = 3, .dividers = 1}}; + .dividers = 19, .minor_div_lines_mask = 0xeeeee}, + .y = {.labels = "2.5A\n0\n-2.5A", .num_ticks = 3, .dividers = 9, .minor_div_lines_mask = 0x03de}}; void OsciloscopeScreen::setup(uint8_t screen_num) { ui::create_screen(&screen_); diff --git a/platformio/src/ui/phase_screen.cpp b/platformio/src/ui/phase_screen.cpp index 4113366..cffa56c 100644 --- a/platformio/src/ui/phase_screen.cpp +++ b/platformio/src/ui/phase_screen.cpp @@ -10,8 +10,8 @@ static lv_point_t points[analyzer::kCaptureBufferSize]; static const ui::ChartAxisConfigs kAxisConfigs{ .y_range = {.min = -2500, .max = 2500}, - .x = {.labels = "-2.5A\n0\n2.5A", .num_ticks = 3, .dividers = 1}, - .y = {.labels = "2.5A\n0\n-2.5A", .num_ticks = 3, .dividers = 1}}; + .x = {.labels = "-2.5A\n0\n2.5A", .num_ticks = 3, .dividers = 9, .minor_div_lines_mask = 0x03de}, + .y = {.labels = "2.5A\n0\n-2.5A", .num_ticks = 3, .dividers = 9, .minor_div_lines_mask = 0x03de}}; void PhaseScreen::setup(uint8_t screen_num) { ui::create_screen(&screen_); diff --git a/platformio/src/ui/ui.cpp b/platformio/src/ui/ui.cpp index 9a39d36..b3f526f 100644 --- a/platformio/src/ui/ui.cpp +++ b/platformio/src/ui/ui.cpp @@ -117,17 +117,22 @@ static void common_lv_chart_bg_style(lv_style_t* bg_style) { static void init_chart_styles() { // Background style lv_style_init(&chart_styles.bg); - common_lv_chart_bg_style(&chart_styles.bg); + // Patch(zapta): Specifciation of minor division lines. + lv_style_set_line_color(&chart_styles.bg, LV_STATE_DEFAULT, + LV_COLOR_MAKE(0x20, 0x20, 0x20)); // dark gray + lv_style_set_line_width(&chart_styles.bg, LV_STATE_DEFAULT, 1); - // Series style + + // Series style (graph) lv_style_init(&chart_styles.series); lv_style_set_size(&chart_styles.series, LV_STATE_DEFAULT, 0); lv_style_set_line_width(&chart_styles.series, LV_STATE_DEFAULT, 2); - // Series bg style + // Series bg style (grid lines) lv_style_init(&chart_styles.series_bg); lv_style_set_line_dash_gap(&chart_styles.series_bg, LV_STATE_DEFAULT, 0); + lv_style_set_line_width(&chart_styles.series_bg, LV_STATE_DEFAULT, 1); lv_style_set_line_color(&chart_styles.series_bg, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x00, 0x40, 0x00)); // dark green } @@ -138,6 +143,11 @@ static void init_polar_chart_styles() { common_lv_chart_bg_style(&polar_chart_styles.bg); + // Patch(zapta): Specifciation of minor division lines. + lv_style_set_line_color(&polar_chart_styles.bg, LV_STATE_DEFAULT, + LV_COLOR_MAKE(0x20, 0x20, 0x20)); // dark gray + lv_style_set_line_width(&polar_chart_styles.bg, LV_STATE_DEFAULT, 1); + // Series bg style (grid) lv_style_init(&polar_chart_styles.series_bg); lv_style_set_line_dash_gap(&polar_chart_styles.series_bg, LV_STATE_DEFAULT, @@ -372,6 +382,7 @@ void set_chart_scale(lv_obj_t* lv_chart, const ChartAxisConfigs& axis_configs) { // include the frame. lv_chart_set_div_line_count(lv_chart, axis_configs.y.dividers, axis_configs.x.dividers); + lv_chart_set_minor_div_lines_masks(lv_chart, axis_configs.y.minor_div_lines_mask, axis_configs.x.minor_div_lines_mask); lv_chart_set_y_tick_length(lv_chart, 0, 0); lv_chart_set_x_tick_length(lv_chart, 0, 0); diff --git a/platformio/src/ui/ui.h b/platformio/src/ui/ui.h index 70654da..774820b 100644 --- a/platformio/src/ui/ui.h +++ b/platformio/src/ui/ui.h @@ -85,6 +85,7 @@ struct ChartAxisConfig { uint8_t num_ticks = 0; // Vertical or horizontal internal grid lines. uint8_t dividers; + uint32_t minor_div_lines_mask = 0; bool is_enabled() const { return num_ticks > 0 && labels != nullptr; } };