From e7b4bef8acdbbaa744dc77b5551f3c478e2f7012 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Wed, 20 Mar 2019 18:33:33 -0400 Subject: [PATCH 01/30] Add lv_btnm_set_one_toggle/lv_btnm_get_one_toggle functions --- src/lv_objx/lv_btnm.c | 46 +++++++++++++++++++++++++++++++++++++++++++ src/lv_objx/lv_btnm.h | 14 +++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/lv_objx/lv_btnm.c b/src/lv_objx/lv_btnm.c index a37eea9f9..541f04152 100644 --- a/src/lv_objx/lv_btnm.c +++ b/src/lv_objx/lv_btnm.c @@ -39,6 +39,7 @@ static uint16_t get_button_from_point(lv_obj_t * btnm, lv_point_t * p); static void allocate_btn_areas_and_controls(const lv_obj_t * btnm, const char ** map); static void invalidate_button_area(const lv_obj_t * btnm, uint16_t btn_idx); static bool maps_are_identical(const char ** map1, const char ** map2); +static void make_one_button_toggled(const lv_obj_t *btnm, uint16_t btn_idx); /********************** * STATIC VARIABLES @@ -87,6 +88,7 @@ lv_obj_t * lv_btnm_create(lv_obj_t * par, const lv_obj_t * copy) ext->ctrl_bits = NULL; ext->map_p = NULL; ext->recolor = 0; + ext->one_toggle = 0; ext->styles_btn[LV_BTN_STATE_REL] = &lv_style_btn_rel; ext->styles_btn[LV_BTN_STATE_PR] = &lv_style_btn_pr; ext->styles_btn[LV_BTN_STATE_TGL_REL] = &lv_style_btn_tgl_rel; @@ -401,6 +403,19 @@ void lv_btnm_set_btn_width(const lv_obj_t * btnm, uint16_t btn_id, uint8_t width lv_btnm_set_map(btnm, ext->map_p); } +/** + * Make the button matrix like a selector widget (only one button may be toggled at a time). + * @param btnm Button matrix object + * @param one_toggle Whether "one toggle" mode is enabled + */ +void lv_btnm_set_one_toggle(const lv_obj_t *btnm, bool one_toggle) { + lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); + ext->one_toggle = one_toggle; + + /*If more than one button is toggled only the first one should be*/ + make_one_button_toggled(btnm, 0); +} + /*===================== * Getter functions *====================*/ @@ -549,6 +564,17 @@ lv_style_t * lv_btnm_get_style(const lv_obj_t * btnm, lv_btnm_style_t type) return style; } +/** + * Find whether "one toggle" mode is enabled. + * @param btnm Button matrix object + * @return whether "one toggle" mode is enabled + */ +bool lv_btnm_get_one_toggle(const lv_obj_t *btnm) { + lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); + + return ext->one_toggle; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -739,6 +765,7 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) } else { ext->ctrl_bits[ext->btn_id_pr] |= LV_BTNM_CTRL_TGL_STATE; } + make_one_button_toggled(btnm, ext->btn_id_pr); } /*Invalidate to old pressed area*/; @@ -1034,5 +1061,24 @@ static bool maps_are_identical(const char ** map1, const char ** map2) return map1[i][0] == '\0' && map2[i][0] == '\0'; } +/** + * Enforces a single button being toggled on the button matrix. + * It simply clears the toggle flag on other buttons. + * @param btnm Button matrix object + * @param btn_idx Button that should remain toggled + */ +static void make_one_button_toggled(const lv_obj_t *btnm, uint16_t btn_idx) +{ + lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); + + uint16_t i = 0; + + for(i = 0; i < ext->btn_cnt; i++) { + if(i != btn_idx) { + ext->ctrl_bits[i] &= (~LV_BTNM_CTRL_TGL_STATE); + invalidate_button_area(btnm, i); + } + } +} #endif diff --git a/src/lv_objx/lv_btnm.h b/src/lv_objx/lv_btnm.h index 6cdc8f3fd..3b98db5ea 100644 --- a/src/lv_objx/lv_btnm.h +++ b/src/lv_objx/lv_btnm.h @@ -60,6 +60,7 @@ typedef struct uint16_t btn_id_pr; /*Index of the currently pressed button or LV_BTNM_BTN_NONE*/ uint16_t btn_id_act; /*Index of the active button (being pressed/released etc) or LV_BTNM_BTN_NONE */ uint8_t recolor :1; /*Enable button recoloring*/ + uint8_t one_toggle :1; /*Single button toggled at once*/ } lv_btnm_ext_t; enum { @@ -166,6 +167,12 @@ void lv_btnm_set_btn_ctrl_all(lv_obj_t * btnm, lv_btnm_ctrl_t ctrl, bool en); */ void lv_btnm_set_btn_width(const lv_obj_t * btnm, uint16_t btn_id, uint8_t width); +/** + * Make the button matrix like a selector widget (only one button may be toggled at a time). + * @param btnm Button matrix object + * @param one_toggle Whether "one toggle" mode is enabled + */ +void lv_btnm_set_one_toggle(const lv_obj_t *btnm, bool one_toggle); /*===================== * Getter functions @@ -233,6 +240,13 @@ bool lv_btnm_get_btn_ctrl(lv_obj_t * btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl) * @return style pointer to a style */ lv_style_t * lv_btnm_get_style(const lv_obj_t * btnm, lv_btnm_style_t type); + +/** + * Find whether "one toggle" mode is enabled. + * @param btnm Button matrix object + * @return whether "one toggle" mode is enabled + */ +bool lv_btnm_get_one_toggle(const lv_obj_t *btnm); /********************** * MACROS **********************/ From f5aa26f7e177ecac175662a54cded38548d65536 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Thu, 21 Mar 2019 13:42:03 -0400 Subject: [PATCH 02/30] Update one toggle feature based on review comments --- src/lv_objx/lv_btnm.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/lv_objx/lv_btnm.c b/src/lv_objx/lv_btnm.c index 541f04152..53bbf0782 100644 --- a/src/lv_objx/lv_btnm.c +++ b/src/lv_objx/lv_btnm.c @@ -765,7 +765,8 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) } else { ext->ctrl_bits[ext->btn_id_pr] |= LV_BTNM_CTRL_TGL_STATE; } - make_one_button_toggled(btnm, ext->btn_id_pr); + if(ext->one_toggle) + make_one_button_toggled(btnm, ext->btn_id_pr); } /*Invalidate to old pressed area*/; @@ -1069,16 +1070,13 @@ static bool maps_are_identical(const char ** map1, const char ** map2) */ static void make_one_button_toggled(const lv_obj_t *btnm, uint16_t btn_idx) { - lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); + /*Save whether the button was toggled*/ + bool was_toggled = lv_btnm_get_btn_ctrl(btnm, btn_idx, LV_BTNM_CTRL_TGL_STATE); - uint16_t i = 0; + lv_btnm_set_btn_ctrl_all(btnm, LV_BTNM_CTRL_TGL_STATE, false); - for(i = 0; i < ext->btn_cnt; i++) { - if(i != btn_idx) { - ext->ctrl_bits[i] &= (~LV_BTNM_CTRL_TGL_STATE); - invalidate_button_area(btnm, i); - } - } + if(was_toggled) + lv_btnm_set_btn_ctrl(btnm, btn_idx, LV_BTNM_CTRL_TGL_STATE, true); } #endif From 087ab979d6727fea653a3a1f3d1632bc1f00cec4 Mon Sep 17 00:00:00 2001 From: user-0 Date: Fri, 22 Mar 2019 17:24:40 +0200 Subject: [PATCH 03/30] Add support for chart axes ticks and value labels. Add support for chart axis X label. --- lv_objx/lv_chart.c | 309 +++++++++++++++++++++++++++++++++++++++++++++ lv_objx/lv_chart.h | 49 +++++++ 2 files changed, 358 insertions(+) diff --git a/lv_objx/lv_chart.c b/lv_objx/lv_chart.c index 0060c1499..fdb824ae4 100644 --- a/lv_objx/lv_chart.c +++ b/lv_objx/lv_chart.c @@ -20,6 +20,7 @@ #define LV_CHART_HDIV_DEF 3 #define LV_CHART_VDIV_DEF 5 #define LV_CHART_PNUM_DEF 10 +#define LV_CHART_AXIS_MARGIN 50 /********************** * TYPEDEFS @@ -35,6 +36,7 @@ static void lv_chart_draw_lines(lv_obj_t * chart, const lv_area_t * mask); static void lv_chart_draw_points(lv_obj_t * chart, const lv_area_t * mask); static void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask); static void lv_chart_draw_vertical_lines(lv_obj_t * chart, const lv_area_t * mask); +static void lv_chart_draw_axes(lv_obj_t * chart, const lv_area_t * mask); /********************** * STATIC VARIABLES @@ -45,6 +47,7 @@ static lv_signal_func_t ancestor_signal; /********************** * MACROS **********************/ +#define strlens(s) (s==NULL?0:strlen(s)) /********************** * GLOBAL FUNCTIONS @@ -81,6 +84,8 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy) ext->series.opa = LV_OPA_COVER; ext->series.dark = LV_OPA_50; ext->series.width = 2; + memset(&ext->x_axis, 0, sizeof(ext->x_axis)); + memset(&ext->y_axis, 0, sizeof(ext->y_axis)); if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_func(new_chart); if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_chart); @@ -109,6 +114,8 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy) ext->vdiv_cnt = ext_copy->vdiv_cnt; ext->point_cnt = ext_copy->point_cnt; ext->series.opa = ext_copy->series.opa; + ext->x_axis = ext_copy->x_axis; + ext->y_axis = ext_copy->y_axis; /*Refresh the style with new signal function*/ lv_obj_refresh_style(new_chart); @@ -387,6 +394,53 @@ void lv_chart_set_next(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y) lv_chart_refresh(chart); } +/** + * Set the x-axis label of a chart + * @param chart pointer to a chart object + * @param text pointer to the label text (not copied) + */ +void lv_chart_set_label(lv_obj_t* chart, const char* text) +{ + lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); + ext->x_axis.label = text; + lv_obj_refresh_ext_size(chart); +} + +/** + * Set the x/y-axis ticks of a chart + * @param chart pointer to a chart object + * @param list_of_values list of string values, terminated with \n, except the last + * @param num_tick_marks if list_of_values is NULL: total number of ticks per axis + * else step in ticks between two value labels + * @param label label to show for this axis (only X) + * @param options extra options + */ +void lv_chart_set_x_ticks( lv_obj_t* chart, + const char* list_of_values, + uint8_t num_tick_marks, + const char* label, + lv_chart_axis_options_t options) +{ + lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); + ext->x_axis.num_tick_marks = num_tick_marks; + ext->x_axis.list_of_values = list_of_values; + ext->x_axis.label = label; + ext->x_axis.options = options; +} + +void lv_chart_set_y_ticks( lv_obj_t* chart, + const char* list_of_values, + uint8_t num_tick_marks, + const char* label, + lv_chart_axis_options_t options) +{ + lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); + ext->y_axis.num_tick_marks = num_tick_marks; + ext->y_axis.list_of_values = list_of_values; + ext->y_axis.label = label; + ext->y_axis.options = options; +} + /*===================== * Getter functions *====================*/ @@ -490,6 +544,7 @@ static bool lv_chart_design(lv_obj_t * chart, const lv_area_t * mask, lv_design_ if(ext->type & LV_CHART_TYPE_COLUMN) lv_chart_draw_cols(chart, mask); if(ext->type & LV_CHART_TYPE_POINT) lv_chart_draw_points(chart, mask); if(ext->type & LV_CHART_TYPE_VERTICAL_LINE) lv_chart_draw_vertical_lines(chart, mask); + lv_chart_draw_axes(chart, mask); } return true; } @@ -522,6 +577,16 @@ static lv_res_t lv_chart_signal(lv_obj_t * chart, lv_signal_t sign, void * param if(buf->type[i] == NULL) break; } buf->type[i] = "lv_chart"; + } else if(sign == LV_SIGNAL_REFR_EXT_SIZE) { + /*Provide extra px draw area around the chart if needed*/ + lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); + + if( (ext->x_axis.list_of_values != NULL || ext->x_axis.num_tick_marks != 0) || + (ext->y_axis.list_of_values != NULL || ext->y_axis.num_tick_marks != 0) || + (ext->x_axis.label == NULL) ) + { /* Reserve some space for axis ticks and labels, predefined by the user */ + chart->ext_size += LV_CHART_AXIS_MARGIN; + } } return res; @@ -821,4 +886,248 @@ static void lv_chart_draw_vertical_lines(lv_obj_t * chart, const lv_area_t * mas } } } + +static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask) +{ + lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); + + if(ext->y_axis.list_of_values != NULL || ext->y_axis.num_tick_marks != 0) { + + const lv_style_t * style = lv_obj_get_style(chart); + lv_opa_t opa_scale = lv_obj_get_opa_scale(chart); + + uint8_t i,j; + uint8_t list_index; + uint8_t num_of_labels; + uint8_t num_scale_ticks; + uint8_t major_tick_len, minor_tick_len; + lv_point_t p1; + lv_point_t p2; + lv_coord_t x_ofs = chart->coords.x1; + lv_coord_t y_ofs = chart->coords.y1; + lv_coord_t h = lv_obj_get_height(chart); + lv_coord_t w = lv_obj_get_width(chart); + char buf[16+1]; /* up to 16 symbols per label + null terminator */ + + /* calculate the size of tick marks */ + major_tick_len = (int32_t)w / 15; + minor_tick_len = major_tick_len * 2/3; + + /* count the '\n'-s to determine the number of options */ + list_index = 0; + num_of_labels = 0; + if(ext->y_axis.list_of_values != NULL) + { + for(j = 0; ext->y_axis.list_of_values[j] != '\0'; j++) { + if(ext->y_axis.list_of_values[j] == '\n') + num_of_labels++; + } + + num_of_labels++; /* last option in the at row*/ + } + + /* we can't have string labels without ticks step, set to 1 if not specified */ + if(ext->y_axis.num_tick_marks == 0) + ext->y_axis.num_tick_marks = 1; + + /* calculate total number of ticks */ + if(num_of_labels < 2) + num_scale_ticks = ext->y_axis.num_tick_marks; + else + num_scale_ticks = (ext->y_axis.num_tick_marks * (num_of_labels - 1)); + + for(i = 0; i < (num_scale_ticks + 1); i++ ) { /* one extra loop - it may not exist in the list, empty label */ + /* first point of the tick */ + p1.x = 0 + x_ofs; + + /* second point of the tick */ + if( (num_of_labels != 0) && (i == 0 || i % ext->y_axis.num_tick_marks == 0) ) + p2.x = p1.x - major_tick_len; /* major tick */ + else + p2.x = p1.x - minor_tick_len; /* minor tick */ + + /* draw a line at moving y position */ + p2.y = p1.y = y_ofs + h - (int32_t)(((int32_t)h * i) / num_scale_ticks + 1) - __LV_CHART_AXIS_Y_TICK_OFFSET_FIX; + + if( i != num_scale_ticks ) + lv_draw_line(&p1, &p2, mask, style, opa_scale); + else + if( (ext->y_axis.options & LV_CHART_AXIS_DRAW_LAST_TICK) != 0 ) + lv_draw_line(&p1, &p2, mask, style, opa_scale); + + /* draw values if available */ + if (num_of_labels != 0) + { + /* add text only to major tick */ + if( i == 0 || i % ext->y_axis.num_tick_marks == 0 ) + { + /* search for tick string */ + j = 0; + while( ext->y_axis.list_of_values[list_index] != '\n' && + ext->y_axis.list_of_values[list_index] != '\0') + { + /* do not overflow the buffer, but move to the end of the current label */ + if(j < 16) + buf[j++] = ext->y_axis.list_of_values[list_index++]; + else + list_index++; + } + + /* this was a string, but not end of the list, so jump to the next string */ + if(ext->y_axis.list_of_values[list_index] == '\n') + list_index++; + + /* terminate the string */ + buf[j] = '\0'; + + /* reserve appropriate area */ + lv_point_t size; + lv_txt_get_size(&size, buf, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, LV_TXT_FLAG_CENTER); + + /* set the area at some distance of the major tick len left of the tick */ + lv_area_t a = {(p2.x - size.x - __LV_CHART_TO_LABEL_DISTANCE) , (p2.y - size.y/2), (p2.x - __LV_CHART_TO_LABEL_DISTANCE), (p2.y + size.y/2) }; + lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL); + } + } + } + } +} + +static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask) +{ + + lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); + + if(ext->x_axis.list_of_values != NULL || ext->x_axis.num_tick_marks != 0) { + + const lv_style_t * style = lv_obj_get_style(chart); + lv_opa_t opa_scale = lv_obj_get_opa_scale(chart); + + uint8_t i,j; + uint8_t list_index; + uint8_t num_of_labels; + uint8_t num_scale_ticks; + uint8_t major_tick_len, minor_tick_len; + lv_point_t p1; + lv_point_t p2; + lv_coord_t x_ofs = chart->coords.x1; + lv_coord_t y_ofs = chart->coords.y1; + lv_coord_t h = lv_obj_get_height(chart); + lv_coord_t w = lv_obj_get_width(chart); + char buf[16+1]; /* up to 16 symbols per label + null terminator */ + + /* calculate the size of tick marks */ + major_tick_len = (int32_t)w / 15; + minor_tick_len = major_tick_len * 2/3; + + /* count the '\n'-s to determine the number of options */ + list_index = 0; + num_of_labels = 0; + if(ext->x_axis.list_of_values != NULL) + { + for(j = 0; ext->x_axis.list_of_values[j] != '\0'; j++) { + if(ext->x_axis.list_of_values[j] == '\n') + num_of_labels++; + } + + num_of_labels++; /* last option in the at row*/ + } + + /* we can't have string labels without ticks step, set to 1 if not specified */ + if(ext->x_axis.num_tick_marks == 0) + ext->x_axis.num_tick_marks = 1; + + /* calculate total number of marks */ + if(num_of_labels < 2) + num_scale_ticks = ext->x_axis.num_tick_marks; + else + num_scale_ticks = (ext->x_axis.num_tick_marks * (num_of_labels - 1)); + + for(i = 0; i < (num_scale_ticks + 1); i++ ) { /* one extra loop - it may not exist in the list, empty label */ + /* first point of the tick */ + p1.y = h + y_ofs; + + /* second point of the tick */ + if( (num_of_labels != 0) && (i == 0 || i % ext->x_axis.num_tick_marks == 0) ) + p2.y = p1.y + major_tick_len; /* major tick */ + else + p2.y = p1.y + minor_tick_len; /* minor tick */ + + /* draw a line at moving x position */ + p2.x = p1.x = x_ofs + (int32_t)(((int32_t)w * i) / num_scale_ticks + 1) - __LV_CHART_AXIS_X_TICK_OFFSET_FIX; + + if( i != num_scale_ticks ) + lv_draw_line(&p1, &p2, mask, style, opa_scale); + else + if( (ext->x_axis.options & LV_CHART_AXIS_DRAW_LAST_TICK) != 0 ) + lv_draw_line(&p1, &p2, mask, style, opa_scale); + + /* draw values if available */ + if (num_of_labels != 0) + { + /* add text only to major tick */ + if( i == 0 || i % ext->x_axis.num_tick_marks == 0 ) + { + /* search for tick string */ + j = 0; + while( ext->x_axis.list_of_values[list_index] != '\n' && + ext->x_axis.list_of_values[list_index] != '\0') + { + /* do not overflow the buffer, but move to the end of the current label */ + if(j < 16) + buf[j++] = ext->x_axis.list_of_values[list_index++]; + else + list_index++; + } + + /* this was a string, but not end of the list, so jump to the next string */ + if(ext->x_axis.list_of_values[list_index] == '\n') + list_index++; + + /* terminate the string */ + buf[j] = '\0'; + + /* reserve appropriate area */ + lv_point_t size; + lv_txt_get_size(&size, buf, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, LV_TXT_FLAG_CENTER); + + /* set the area at some distance of the major tick len under of the tick */ + lv_area_t a = { (p2.x - size.x/2) , (p2.y + __LV_CHART_TO_LABEL_DISTANCE), (p2.x + size.x/2), (p2.y + size.y + __LV_CHART_TO_LABEL_DISTANCE) }; + lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL); + } + } + } + } +} + +static void lv_chart_draw_x_axis_label(lv_obj_t * chart, const lv_area_t * mask) +{ + + lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); + + if (ext->x_axis.label != NULL) + { + const lv_style_t * style = lv_obj_get_style(chart); + lv_opa_t opa_scale = lv_obj_get_opa_scale(chart); + lv_coord_t w = lv_obj_get_width(chart); + + lv_point_t size; + lv_txt_get_size(&size, ext->x_axis.label, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, LV_TXT_FLAG_CENTER); + + lv_area_t label_area; + label_area.x1 = chart->coords.x1 + w/2 - size.x/2; + label_area.y1 = chart->coords.y1 - __LV_CHART_TO_LABEL_DISTANCE - size.y/2; + label_area.x2 = label_area.x1 + size.x; + label_area.y2 = label_area.y1 + size.y/2; + + lv_draw_label(&label_area, mask, style, opa_scale, ext->x_axis.label, LV_TXT_FLAG_CENTER, NULL); + } +} + +static void lv_chart_draw_axes(lv_obj_t * chart, const lv_area_t * mask) +{ + lv_chart_draw_y_ticks(chart, mask); + lv_chart_draw_x_ticks(chart, mask); + lv_chart_draw_x_axis_label(chart, mask); +} #endif diff --git a/lv_objx/lv_chart.h b/lv_objx/lv_chart.h index baea9d0f4..a97fc704e 100644 --- a/lv_objx/lv_chart.h +++ b/lv_objx/lv_chart.h @@ -39,6 +39,25 @@ typedef struct uint16_t start_point; } lv_chart_series_t; +/*Data of chart */ +#define __LV_CHART_TO_LABEL_DISTANCE 4 +#define __LV_CHART_AXIS_X_TICK_OFFSET_FIX 1 +#define __LV_CHART_AXIS_Y_TICK_OFFSET_FIX 0 + +enum +{ + LV_CHART_AXIS_DRAW_LAST_TICK = 0x01 /* draw the last tick */ +}; +typedef uint8_t lv_chart_axis_options_t; + +typedef struct +{ + const char* list_of_values; + uint8_t num_tick_marks; + const char* label; + lv_chart_axis_options_t options; +} lv_chart_axis_cfg_t; + /*Data of chart */ typedef struct { @@ -51,6 +70,8 @@ typedef struct uint8_t vdiv_cnt; /*Number of vertical division lines*/ uint16_t point_cnt; /*Point number in a data line*/ uint8_t type :4; /*Line, column or point chart (from 'lv_chart_type_t')*/ + lv_chart_axis_cfg_t y_axis; + lv_chart_axis_cfg_t x_axis; struct { lv_coord_t width; /*Line width or point radius*/ uint8_t num; /*Number of data lines in dl_ll*/ @@ -190,6 +211,34 @@ static inline void lv_chart_set_style(lv_obj_t *chart, lv_style_t *style) lv_obj_set_style(chart, style); } +/** + * Set the x-axis label of a chart + * @param chart pointer to a chart object + * @param text pointer to the label text (not copied) + */ +void lv_chart_set_label(lv_obj_t* chart, const char* text); + +/** + * Set the x/y-axis ticks of a chart + * @param chart pointer to a chart object + * @param list_of_values list of string values, terminated with \n, except the last + * @param num_tick_marks if list_of_values is NULL: total number of ticks per axis + * else step in ticks between two value labels + * @param label label to show for this axis (only X) + * @param options extra options + */ +void lv_chart_set_x_ticks( lv_obj_t* chart, + const char* list_of_values, + uint8_t num_tick_marks, + const char* label, + lv_chart_axis_options_t options); + +void lv_chart_set_y_ticks( lv_obj_t* chart, + const char* list_of_values, + uint8_t num_tick_marks, + const char* label, + lv_chart_axis_options_t options); + /*===================== * Getter functions *====================*/ From 46d5debc7a679de622201ed19db257f70d46cc1c Mon Sep 17 00:00:00 2001 From: user-0 Date: Fri, 22 Mar 2019 19:20:58 +0200 Subject: [PATCH 04/30] FIXED: Add support for chart axes ticks and value labels / chart label. --- lv_objx/lv_chart.c | 33 +++++++++++++++++++-------------- lv_objx/lv_chart.h | 6 +----- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/lv_objx/lv_chart.c b/lv_objx/lv_chart.c index fdb824ae4..caa31135e 100644 --- a/lv_objx/lv_chart.c +++ b/lv_objx/lv_chart.c @@ -21,6 +21,12 @@ #define LV_CHART_VDIV_DEF 5 #define LV_CHART_PNUM_DEF 10 #define LV_CHART_AXIS_MARGIN 50 +#define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 16 +#define LV_CHART_AXIS_TO_LABEL_DISTANCE 4 +#define LV_CHART_AXIS_MAJOR_TICK_LEN_COE 1/15 +#define LV_CHART_AXIS_MINOR_TICK_LEN_COE 2/3 +#define LV_CHART_AXIS_X_TICK_OFFSET_FIX 1 +#define LV_CHART_AXIS_Y_TICK_OFFSET_FIX 0 /********************** * TYPEDEFS @@ -47,7 +53,6 @@ static lv_signal_func_t ancestor_signal; /********************** * MACROS **********************/ -#define strlens(s) (s==NULL?0:strlen(s)) /********************** * GLOBAL FUNCTIONS @@ -907,11 +912,11 @@ static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask) lv_coord_t y_ofs = chart->coords.y1; lv_coord_t h = lv_obj_get_height(chart); lv_coord_t w = lv_obj_get_width(chart); - char buf[16+1]; /* up to 16 symbols per label + null terminator */ + char buf[LV_CHART_AXIS_TICK_LABEL_MAX_LEN+1]; /* up to N symbols per label + null terminator */ /* calculate the size of tick marks */ - major_tick_len = (int32_t)w / 15; - minor_tick_len = major_tick_len * 2/3; + major_tick_len = (int32_t)w * LV_CHART_AXIS_MAJOR_TICK_LEN_COE; + minor_tick_len = major_tick_len * LV_CHART_AXIS_MINOR_TICK_LEN_COE; /* count the '\n'-s to determine the number of options */ list_index = 0; @@ -947,7 +952,7 @@ static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask) p2.x = p1.x - minor_tick_len; /* minor tick */ /* draw a line at moving y position */ - p2.y = p1.y = y_ofs + h - (int32_t)(((int32_t)h * i) / num_scale_ticks + 1) - __LV_CHART_AXIS_Y_TICK_OFFSET_FIX; + p2.y = p1.y = y_ofs + h - (int32_t)(((int32_t)h * i) / num_scale_ticks + 1) - LV_CHART_AXIS_Y_TICK_OFFSET_FIX; if( i != num_scale_ticks ) lv_draw_line(&p1, &p2, mask, style, opa_scale); @@ -967,7 +972,7 @@ static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask) ext->y_axis.list_of_values[list_index] != '\0') { /* do not overflow the buffer, but move to the end of the current label */ - if(j < 16) + if(j < LV_CHART_AXIS_TICK_LABEL_MAX_LEN) buf[j++] = ext->y_axis.list_of_values[list_index++]; else list_index++; @@ -985,7 +990,7 @@ static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask) lv_txt_get_size(&size, buf, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, LV_TXT_FLAG_CENTER); /* set the area at some distance of the major tick len left of the tick */ - lv_area_t a = {(p2.x - size.x - __LV_CHART_TO_LABEL_DISTANCE) , (p2.y - size.y/2), (p2.x - __LV_CHART_TO_LABEL_DISTANCE), (p2.y + size.y/2) }; + lv_area_t a = {(p2.x - size.x - LV_CHART_AXIS_TO_LABEL_DISTANCE) , (p2.y - size.y/2), (p2.x - LV_CHART_AXIS_TO_LABEL_DISTANCE), (p2.y + size.y/2) }; lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL); } } @@ -1014,11 +1019,11 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask) lv_coord_t y_ofs = chart->coords.y1; lv_coord_t h = lv_obj_get_height(chart); lv_coord_t w = lv_obj_get_width(chart); - char buf[16+1]; /* up to 16 symbols per label + null terminator */ + char buf[LV_CHART_AXIS_TICK_LABEL_MAX_LEN+1]; /* up to N symbols per label + null terminator */ /* calculate the size of tick marks */ - major_tick_len = (int32_t)w / 15; - minor_tick_len = major_tick_len * 2/3; + major_tick_len = (int32_t)w * LV_CHART_AXIS_MAJOR_TICK_LEN_COE; + minor_tick_len = major_tick_len * LV_CHART_AXIS_MINOR_TICK_LEN_COE; /* count the '\n'-s to determine the number of options */ list_index = 0; @@ -1054,7 +1059,7 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask) p2.y = p1.y + minor_tick_len; /* minor tick */ /* draw a line at moving x position */ - p2.x = p1.x = x_ofs + (int32_t)(((int32_t)w * i) / num_scale_ticks + 1) - __LV_CHART_AXIS_X_TICK_OFFSET_FIX; + p2.x = p1.x = x_ofs + (int32_t)(((int32_t)w * i) / num_scale_ticks + 1) - LV_CHART_AXIS_X_TICK_OFFSET_FIX; if( i != num_scale_ticks ) lv_draw_line(&p1, &p2, mask, style, opa_scale); @@ -1074,7 +1079,7 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask) ext->x_axis.list_of_values[list_index] != '\0') { /* do not overflow the buffer, but move to the end of the current label */ - if(j < 16) + if(j < LV_CHART_AXIS_TICK_LABEL_MAX_LEN) buf[j++] = ext->x_axis.list_of_values[list_index++]; else list_index++; @@ -1092,7 +1097,7 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask) lv_txt_get_size(&size, buf, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, LV_TXT_FLAG_CENTER); /* set the area at some distance of the major tick len under of the tick */ - lv_area_t a = { (p2.x - size.x/2) , (p2.y + __LV_CHART_TO_LABEL_DISTANCE), (p2.x + size.x/2), (p2.y + size.y + __LV_CHART_TO_LABEL_DISTANCE) }; + lv_area_t a = { (p2.x - size.x/2) , (p2.y + LV_CHART_AXIS_TO_LABEL_DISTANCE), (p2.x + size.x/2), (p2.y + size.y + LV_CHART_AXIS_TO_LABEL_DISTANCE) }; lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL); } } @@ -1116,7 +1121,7 @@ static void lv_chart_draw_x_axis_label(lv_obj_t * chart, const lv_area_t * mask) lv_area_t label_area; label_area.x1 = chart->coords.x1 + w/2 - size.x/2; - label_area.y1 = chart->coords.y1 - __LV_CHART_TO_LABEL_DISTANCE - size.y/2; + label_area.y1 = chart->coords.y1 - LV_CHART_AXIS_TO_LABEL_DISTANCE - size.y/2; label_area.x2 = label_area.x1 + size.x; label_area.y2 = label_area.y1 + size.y/2; diff --git a/lv_objx/lv_chart.h b/lv_objx/lv_chart.h index a97fc704e..c6914247f 100644 --- a/lv_objx/lv_chart.h +++ b/lv_objx/lv_chart.h @@ -39,11 +39,7 @@ typedef struct uint16_t start_point; } lv_chart_series_t; -/*Data of chart */ -#define __LV_CHART_TO_LABEL_DISTANCE 4 -#define __LV_CHART_AXIS_X_TICK_OFFSET_FIX 1 -#define __LV_CHART_AXIS_Y_TICK_OFFSET_FIX 0 - +/*Data of axis */ enum { LV_CHART_AXIS_DRAW_LAST_TICK = 0x01 /* draw the last tick */ From ee4e61ed68eeab28e0ff3be2389f5b9c580ae531 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 22 Mar 2019 13:23:55 -0400 Subject: [PATCH 05/30] Add bug report issue template --- .github/ISSUE_TEMPLATE/bug_report.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..db2b0be8c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,27 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** + +A clear and concise description of what the bug is. + +**To Reproduce** + +Please provide a small, independent code sample that can be used to reproduce the issue. Ideally this should work in the PC simulator unless the problem is specific to one platform. + +**Expected behavior** + +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Additional context** + +Add any other context about the problem here. From 2f86a67e7111ab30f72ef5ee515dbe1c81203423 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 22 Mar 2019 13:28:36 -0400 Subject: [PATCH 06/30] Add other issues template --- .github/ISSUE_TEMPLATE/all-other-issues.md | 14 +++++++++++ .github/ISSUE_TEMPLATE/bug_report.md | 27 ---------------------- 2 files changed, 14 insertions(+), 27 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/all-other-issues.md delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md diff --git a/.github/ISSUE_TEMPLATE/all-other-issues.md b/.github/ISSUE_TEMPLATE/all-other-issues.md new file mode 100644 index 000000000..ca92afed3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/all-other-issues.md @@ -0,0 +1,14 @@ +--- +name: All other issues +about: Describe this issue template's purpose here. +title: '' +labels: stale +assignees: '' + +--- + +# All enhancement requests or questions should be directed to the Forum. + + +We use GitHub issues for development related discussions. +Please use the [forum](https://forum.littlevgl.com/) to ask questions. diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index db2b0be8c..000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: '' -assignees: '' - ---- - -**Describe the bug** - -A clear and concise description of what the bug is. - -**To Reproduce** - -Please provide a small, independent code sample that can be used to reproduce the issue. Ideally this should work in the PC simulator unless the problem is specific to one platform. - -**Expected behavior** - -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Additional context** - -Add any other context about the problem here. From 73ab6b3e2fc809547d607cfa496eb256c7ee8d86 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Fri, 22 Mar 2019 13:57:35 -0400 Subject: [PATCH 07/30] Add back missing bug report template --- .github/ISSUE_TEMPLATE/bug_report.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..db2b0be8c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,27 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** + +A clear and concise description of what the bug is. + +**To Reproduce** + +Please provide a small, independent code sample that can be used to reproduce the issue. Ideally this should work in the PC simulator unless the problem is specific to one platform. + +**Expected behavior** + +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Additional context** + +Add any other context about the problem here. From 03b30708712d66e4f71322ceae7255639af7215d Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Fri, 22 Mar 2019 13:58:19 -0400 Subject: [PATCH 08/30] Update issue templates --- .github/ISSUE_TEMPLATE/all-other-issues.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/all-other-issues.md b/.github/ISSUE_TEMPLATE/all-other-issues.md index ca92afed3..b3f7a35e0 100644 --- a/.github/ISSUE_TEMPLATE/all-other-issues.md +++ b/.github/ISSUE_TEMPLATE/all-other-issues.md @@ -1,6 +1,6 @@ --- name: All other issues -about: Describe this issue template's purpose here. +about: Questions and enhancement requests should go to the forum. title: '' labels: stale assignees: '' From 22f84314a44f4ab7ceaf72035efa0eb69a95530e Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 22 Mar 2019 21:28:18 +0100 Subject: [PATCH 09/30] Rename bug_report.md to bug-report.md --- .github/ISSUE_TEMPLATE/{bug_report.md => bug-report.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{bug_report.md => bug-report.md} (100%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug-report.md similarity index 100% rename from .github/ISSUE_TEMPLATE/bug_report.md rename to .github/ISSUE_TEMPLATE/bug-report.md From 36b212d4dcb50f0abac24747fd6e671a4b166731 Mon Sep 17 00:00:00 2001 From: user-0 Date: Fri, 22 Mar 2019 22:49:09 +0200 Subject: [PATCH 10/30] TUNE: Add support for chart axes ticks and value labels / chart label. --- lv_objx/lv_chart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lv_objx/lv_chart.c b/lv_objx/lv_chart.c index caa31135e..182abeb21 100644 --- a/lv_objx/lv_chart.c +++ b/lv_objx/lv_chart.c @@ -1121,7 +1121,7 @@ static void lv_chart_draw_x_axis_label(lv_obj_t * chart, const lv_area_t * mask) lv_area_t label_area; label_area.x1 = chart->coords.x1 + w/2 - size.x/2; - label_area.y1 = chart->coords.y1 - LV_CHART_AXIS_TO_LABEL_DISTANCE - size.y/2; + label_area.y1 = chart->coords.y1 - LV_CHART_AXIS_TO_LABEL_DISTANCE - (style->text.font->h_px / 4) - size.y/2; label_area.x2 = label_area.x1 + size.x; label_area.y2 = label_area.y1 + size.y/2; From e32b40ecf119e7ddfc9038a6cd8d4232ba72f383 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Fri, 22 Mar 2019 19:08:21 -0400 Subject: [PATCH 11/30] Only start scrolling tabview horizontally if page is at edge --- src/lv_objx/lv_page.c | 27 +++++++++++++++++++++++++++ src/lv_objx/lv_page.h | 20 ++++++++++++++++++++ src/lv_objx/lv_tabview.c | 32 ++++++++++++++++++++++---------- 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/src/lv_objx/lv_page.c b/src/lv_objx/lv_page.c index 2979d5942..ecc2e7cab 100644 --- a/src/lv_objx/lv_page.c +++ b/src/lv_objx/lv_page.c @@ -387,6 +387,33 @@ lv_style_t * lv_page_get_style(const lv_obj_t * page, lv_page_style_t type) * Other functions *====================*/ +/** + * Find whether the page has been scrolled to a certain edge. + * @param page Page object + * @param edge Edge to check + * @return true if the page is on the specified edge + */ +bool lv_page_on_edge(lv_obj_t *page, lv_page_edge_t edge) { + lv_style_t * page_style = lv_obj_get_style(page); + lv_obj_t * scrl = lv_page_get_scrl(page); + lv_area_t page_coords; + lv_area_t scrl_coords; + + lv_obj_get_coords(scrl, &scrl_coords); + lv_obj_get_coords(page, &page_coords); + + if(edge == LV_PAGE_EDGE_TOP && scrl_coords.y1 == page_coords.y1 + page_style->body.padding.top) + return true; + else if(edge == LV_PAGE_EDGE_BOTTOM && scrl_coords.y2 == page_coords.y2 - page_style->body.padding.bottom) + return true; + else if(edge == LV_PAGE_EDGE_LEFT && scrl_coords.x1 == page_coords.x1 + page_style->body.padding.left) + return true; + else if(edge == LV_PAGE_EDGE_RIGHT && scrl_coords.x2 == page_coords.x2 - page_style->body.padding.right) + return true; + + return false; +} + /** * Glue the object to the page. After it the page can be moved (dragged) with this object too. * @param obj pointer to an object on a page diff --git a/src/lv_objx/lv_page.h b/src/lv_objx/lv_page.h index 2c9de41f2..ddf68998f 100644 --- a/src/lv_objx/lv_page.h +++ b/src/lv_objx/lv_page.h @@ -49,6 +49,17 @@ enum }; typedef uint8_t lv_sb_mode_t; +/*Edges: describes the four edges of the page*/ + +enum +{ + LV_PAGE_EDGE_LEFT = 0x0, + LV_PAGE_EDGE_TOP = 0x1, + LV_PAGE_EDGE_RIGHT = 0x2, + LV_PAGE_EDGE_BOTTOM = 0x3 +}; +typedef uint8_t lv_page_edge_t; + /*Data of page*/ typedef struct { @@ -349,6 +360,15 @@ lv_style_t * lv_page_get_style(const lv_obj_t *page, lv_page_style_t type); * Other functions *====================*/ + +/** + * Find whether the page has been scrolled to a certain edge. + * @param page Page object + * @param edge Edge to check + * @return true if the page is on the specified edge + */ +bool lv_page_on_edge(lv_obj_t *page, lv_page_edge_t edge); + /** * Glue the object to the page. After it the page can be moved (dragged) with this object too. * @param obj pointer to an object on a page diff --git a/src/lv_objx/lv_tabview.c b/src/lv_objx/lv_tabview.c index 6a0b08fc8..50f707fe7 100644 --- a/src/lv_objx/lv_tabview.c +++ b/src/lv_objx/lv_tabview.c @@ -733,16 +733,28 @@ static void tabpage_pressing_handler(lv_obj_t * tabview, lv_obj_t * tabpage) lv_coord_t x_diff = point_act.x - ext->point_last.x; lv_coord_t y_diff = point_act.y - ext->point_last.y; - if(ext->draging == 0) { - if(x_diff >= LV_INDEV_DRAG_LIMIT || x_diff <= -LV_INDEV_DRAG_LIMIT) { - ext->drag_hor = 1; - ext->draging = 1; - lv_obj_set_drag(lv_page_get_scrl(tabpage), false); - } else if(y_diff >= LV_INDEV_DRAG_LIMIT || y_diff <= -LV_INDEV_DRAG_LIMIT) { - ext->drag_hor = 0; - ext->draging = 1; - } - } + + if(x_diff >= LV_INDEV_DRAG_LIMIT || x_diff <= -LV_INDEV_DRAG_LIMIT) { + ext->draging = 1; + /*Check if the page is on the edge */ + if((lv_page_on_edge(tabpage, LV_PAGE_EDGE_LEFT) && x_diff > 0) || + (lv_page_on_edge(tabpage, LV_PAGE_EDGE_RIGHT) && x_diff < 0)) { + if(ext->drag_hor == 0) { + ext->point_last.x = point_act.x; + ext->point_last.y = point_act.y; + } + ext->drag_hor = 1; + lv_obj_set_drag(lv_page_get_scrl(tabpage), false); + + } else if(ext->drag_hor == 0) { + ext->drag_hor = 0; + } + } else if(y_diff >= LV_INDEV_DRAG_LIMIT || y_diff <= -LV_INDEV_DRAG_LIMIT) { + ext->drag_hor = 0; + ext->draging = 1; + } else + ext->draging = 0; + if(ext->drag_hor) { lv_obj_set_x(ext->content, lv_obj_get_x(ext->content) + point_act.x - ext->point_last.x); ext->point_last.x = point_act.x; From de04b39165f2b5020bccb19b3e695d0013d5ba18 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Fri, 22 Mar 2019 19:11:37 -0400 Subject: [PATCH 12/30] Remove use of 'const' in `lv_btnm_set_one_toggle` --- src/lv_objx/lv_btnm.c | 6 +++--- src/lv_objx/lv_btnm.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lv_objx/lv_btnm.c b/src/lv_objx/lv_btnm.c index 53bbf0782..1594cf781 100644 --- a/src/lv_objx/lv_btnm.c +++ b/src/lv_objx/lv_btnm.c @@ -39,7 +39,7 @@ static uint16_t get_button_from_point(lv_obj_t * btnm, lv_point_t * p); static void allocate_btn_areas_and_controls(const lv_obj_t * btnm, const char ** map); static void invalidate_button_area(const lv_obj_t * btnm, uint16_t btn_idx); static bool maps_are_identical(const char ** map1, const char ** map2); -static void make_one_button_toggled(const lv_obj_t *btnm, uint16_t btn_idx); +static void make_one_button_toggled(lv_obj_t *btnm, uint16_t btn_idx); /********************** * STATIC VARIABLES @@ -408,7 +408,7 @@ void lv_btnm_set_btn_width(const lv_obj_t * btnm, uint16_t btn_id, uint8_t width * @param btnm Button matrix object * @param one_toggle Whether "one toggle" mode is enabled */ -void lv_btnm_set_one_toggle(const lv_obj_t *btnm, bool one_toggle) { +void lv_btnm_set_one_toggle(lv_obj_t *btnm, bool one_toggle) { lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); ext->one_toggle = one_toggle; @@ -1068,7 +1068,7 @@ static bool maps_are_identical(const char ** map1, const char ** map2) * @param btnm Button matrix object * @param btn_idx Button that should remain toggled */ -static void make_one_button_toggled(const lv_obj_t *btnm, uint16_t btn_idx) +static void make_one_button_toggled(lv_obj_t *btnm, uint16_t btn_idx) { /*Save whether the button was toggled*/ bool was_toggled = lv_btnm_get_btn_ctrl(btnm, btn_idx, LV_BTNM_CTRL_TGL_STATE); diff --git a/src/lv_objx/lv_btnm.h b/src/lv_objx/lv_btnm.h index 3b98db5ea..edadc03c7 100644 --- a/src/lv_objx/lv_btnm.h +++ b/src/lv_objx/lv_btnm.h @@ -172,7 +172,7 @@ void lv_btnm_set_btn_width(const lv_obj_t * btnm, uint16_t btn_id, uint8_t width * @param btnm Button matrix object * @param one_toggle Whether "one toggle" mode is enabled */ -void lv_btnm_set_one_toggle(const lv_obj_t *btnm, bool one_toggle); +void lv_btnm_set_one_toggle(lv_obj_t *btnm, bool one_toggle); /*===================== * Getter functions From e1f946281831108e9e9b70d1d5418101377fd436 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Fri, 22 Mar 2019 19:19:03 -0400 Subject: [PATCH 13/30] Add debug info to tabview --- src/lv_objx/lv_page.c | 5 +++++ src/lv_objx/lv_tabview.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/lv_objx/lv_page.c b/src/lv_objx/lv_page.c index ecc2e7cab..bbef816d5 100644 --- a/src/lv_objx/lv_page.c +++ b/src/lv_objx/lv_page.c @@ -6,6 +6,7 @@ /********************* * INCLUDES *********************/ +#include #include "../lv_objx/lv_page.h" #if LV_USE_PAGE != 0 @@ -402,6 +403,10 @@ bool lv_page_on_edge(lv_obj_t *page, lv_page_edge_t edge) { lv_obj_get_coords(scrl, &scrl_coords); lv_obj_get_coords(page, &page_coords); + if(edge == LV_PAGE_EDGE_LEFT) { + printf("scrl_coords.x1 %d\n", scrl_coords.x1); + printf("page_coords.x1 + page_style->body.padding.left %d\n", page_coords.x1 + page_style->body.padding.left); + } if(edge == LV_PAGE_EDGE_TOP && scrl_coords.y1 == page_coords.y1 + page_style->body.padding.top) return true; else if(edge == LV_PAGE_EDGE_BOTTOM && scrl_coords.y2 == page_coords.y2 - page_style->body.padding.bottom) diff --git a/src/lv_objx/lv_tabview.c b/src/lv_objx/lv_tabview.c index 50f707fe7..1455093a1 100644 --- a/src/lv_objx/lv_tabview.c +++ b/src/lv_objx/lv_tabview.c @@ -6,6 +6,7 @@ /********************* * INCLUDES *********************/ +#include #include "lv_tabview.h" #if LV_USE_TABVIEW != 0 @@ -744,11 +745,13 @@ static void tabpage_pressing_handler(lv_obj_t * tabview, lv_obj_t * tabpage) ext->point_last.y = point_act.y; } ext->drag_hor = 1; + printf("Horizontal drag started\n"); lv_obj_set_drag(lv_page_get_scrl(tabpage), false); } else if(ext->drag_hor == 0) { ext->drag_hor = 0; } + printf("%d %d\n", lv_page_on_edge(tabpage, LV_PAGE_EDGE_LEFT), lv_page_on_edge(tabpage, LV_PAGE_EDGE_RIGHT)); } else if(y_diff >= LV_INDEV_DRAG_LIMIT || y_diff <= -LV_INDEV_DRAG_LIMIT) { ext->drag_hor = 0; ext->draging = 1; From 13033c28d83f5768b89a577e27f0fd1de054bbd8 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sat, 23 Mar 2019 01:05:41 +0100 Subject: [PATCH 14/30] lv_page: fix scrl left padding --- src/lv_objx/lv_page.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lv_objx/lv_page.c b/src/lv_objx/lv_page.c index ecc2e7cab..4e7feaf80 100644 --- a/src/lv_objx/lv_page.c +++ b/src/lv_objx/lv_page.c @@ -944,7 +944,7 @@ static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, voi } } else if(scrl_coords.x1 > page_coords.x1 + page_style->body.padding.left) { - new_x = hpad; /*Left align*/ + new_x = page_style->body.padding.left; /*Left align*/ refr_x = true; if(page_ext->edge_flash.enabled && page_ext->edge_flash.left_ip == 0 && page_ext->edge_flash.right_ip == 0 && @@ -955,7 +955,7 @@ static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, voi } } - /*scrollable height smaller then page height? -> align to left*/ + /*scrollable height smaller then page height? -> align to top*/ if(lv_area_get_height(&scrl_coords) + vpad <= lv_area_get_height(&page_coords)) { if(scrl_coords.y1 != page_coords.y1 + page_style->body.padding.top) { new_y = page_style->body.padding.top; From e1e6813eb1c8477e8a2c6f2187b302b0cfc0dd09 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sat, 23 Mar 2019 01:19:57 +0100 Subject: [PATCH 15/30] fix typo in lv_port_..._template files --- porting/lv_port_disp_template.c | 4 ++-- porting/lv_port_indev_template.c | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/porting/lv_port_disp_template.c b/porting/lv_port_disp_template.c index 7fdfa79bc..1f4502720 100644 --- a/porting/lv_port_disp_template.c +++ b/porting/lv_port_disp_template.c @@ -24,7 +24,7 @@ **********************/ static void disp_init(void); -static void disp_flush(lv_disp_t * disp, const lv_area_t * area, lv_color_t * color_p); +static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p); #if LV_USE_GPU static void mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa); static void mem_fill(lv_color_t * dest, uint32_t length, lv_color_t color); @@ -135,7 +135,7 @@ static void disp_init(void) /* Flush the content of the internal buffer the specific area on the display * You can use DMA or any hardware acceleration to do this operation in the background but * 'lv_disp_flush_ready()' has to be called when finished. */ -static void disp_flush(lv_disp_t * disp, const lv_area_t * area, lv_color_t * color_p) +static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) { /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/ diff --git a/porting/lv_port_indev_template.c b/porting/lv_port_indev_template.c index 98fe79b1d..2e243190f 100644 --- a/porting/lv_port_indev_template.c +++ b/porting/lv_port_indev_template.c @@ -24,25 +24,25 @@ **********************/ static void touchpad_init(void); -static bool touchpad_read(lv_indev_t * indev, lv_indev_data_t * data); +static bool touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); static bool touchpad_is_pressed(void); static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y); static void mouse_init(void); -static bool mouse_read(lv_indev_t * indev, lv_indev_data_t * data); +static bool mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); static bool mouse_is_pressed(void); static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y); static void keypad_init(void); -static bool keypad_read(lv_indev_t * indev, lv_indev_data_t * data); +static bool keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); static uint32_t keypad_get_key(void); static void encoder_init(void); -static bool encoder_read(lv_indev_t * indev, lv_indev_data_t * data); +static bool encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); static void encoder_handler(void); static void button_init(void); -static bool button_read(lv_indev_t * indev, lv_indev_data_t * data); +static bool button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); static int8_t button_get_pressed_id(void); static bool button_is_pressed(uint8_t id); @@ -187,7 +187,7 @@ static void touchpad_init(void) } /* Will be called by the library to read the touchpad */ -static bool touchpad_read(lv_indev_t * indev, lv_indev_data_t * data) +static bool touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) { static lv_coord_t last_x = 0; static lv_coord_t last_y = 0; @@ -237,7 +237,7 @@ static void mouse_init(void) } /* Will be called by the library to read the mouse */ -static bool mouse_read(lv_indev_t * indev, lv_indev_data_t * data) +static bool mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) { /*Get the current x and y coordinates*/ mouse_get_xy(&data->point.x, &data->point.y); @@ -281,7 +281,7 @@ static void keypad_init(void) } /* Will be called by the library to read the mouse */ -static bool keypad_read(lv_indev_t * indev, lv_indev_data_t * data) +static bool keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) { static uint32_t last_key = 0; @@ -342,7 +342,7 @@ static void encoder_init(void) } /* Will be called by the library to read the encoder */ -static bool encoder_read(lv_indev_t * indev, lv_indev_data_t * data) +static bool encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) { data->enc_diff = encoder_diff; @@ -373,7 +373,7 @@ static void button_init(void) } /* Will be called by the library to read the button */ -static bool button_read(lv_indev_t * indev, lv_indev_data_t * data) +static bool button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) { static uint8_t last_btn = 0; From f0e423a71eb7f2d1e4f8685f6e9e15f31fb92224 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Fri, 22 Mar 2019 21:28:57 -0400 Subject: [PATCH 16/30] Remove debug information --- src/lv_objx/lv_page.c | 5 ----- src/lv_objx/lv_tabview.c | 3 --- 2 files changed, 8 deletions(-) diff --git a/src/lv_objx/lv_page.c b/src/lv_objx/lv_page.c index be7a11035..4e7feaf80 100644 --- a/src/lv_objx/lv_page.c +++ b/src/lv_objx/lv_page.c @@ -6,7 +6,6 @@ /********************* * INCLUDES *********************/ -#include #include "../lv_objx/lv_page.h" #if LV_USE_PAGE != 0 @@ -403,10 +402,6 @@ bool lv_page_on_edge(lv_obj_t *page, lv_page_edge_t edge) { lv_obj_get_coords(scrl, &scrl_coords); lv_obj_get_coords(page, &page_coords); - if(edge == LV_PAGE_EDGE_LEFT) { - printf("scrl_coords.x1 %d\n", scrl_coords.x1); - printf("page_coords.x1 + page_style->body.padding.left %d\n", page_coords.x1 + page_style->body.padding.left); - } if(edge == LV_PAGE_EDGE_TOP && scrl_coords.y1 == page_coords.y1 + page_style->body.padding.top) return true; else if(edge == LV_PAGE_EDGE_BOTTOM && scrl_coords.y2 == page_coords.y2 - page_style->body.padding.bottom) diff --git a/src/lv_objx/lv_tabview.c b/src/lv_objx/lv_tabview.c index 1455093a1..50f707fe7 100644 --- a/src/lv_objx/lv_tabview.c +++ b/src/lv_objx/lv_tabview.c @@ -6,7 +6,6 @@ /********************* * INCLUDES *********************/ -#include #include "lv_tabview.h" #if LV_USE_TABVIEW != 0 @@ -745,13 +744,11 @@ static void tabpage_pressing_handler(lv_obj_t * tabview, lv_obj_t * tabpage) ext->point_last.y = point_act.y; } ext->drag_hor = 1; - printf("Horizontal drag started\n"); lv_obj_set_drag(lv_page_get_scrl(tabpage), false); } else if(ext->drag_hor == 0) { ext->drag_hor = 0; } - printf("%d %d\n", lv_page_on_edge(tabpage, LV_PAGE_EDGE_LEFT), lv_page_on_edge(tabpage, LV_PAGE_EDGE_RIGHT)); } else if(y_diff >= LV_INDEV_DRAG_LIMIT || y_diff <= -LV_INDEV_DRAG_LIMIT) { ext->drag_hor = 0; ext->draging = 1; From a8dc1afe2c42a5c9df90d19db109ef3e46cefb7e Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Fri, 22 Mar 2019 21:38:05 -0400 Subject: [PATCH 17/30] Lock out horizontal swiping while vertical scrolling is in progress --- src/lv_objx/lv_tabview.c | 5 ++++- src/lv_objx/lv_tabview.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lv_objx/lv_tabview.c b/src/lv_objx/lv_tabview.c index 50f707fe7..3f4e34c88 100644 --- a/src/lv_objx/lv_tabview.c +++ b/src/lv_objx/lv_tabview.c @@ -82,6 +82,7 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy) /*Initialize the allocated 'ext' */ ext->drag_hor = 0; ext->draging = 0; + ext->scroll_ver = 0; ext->slide_enable = 1; ext->tab_cur = 0; ext->point_last.x = 0; @@ -734,7 +735,7 @@ static void tabpage_pressing_handler(lv_obj_t * tabview, lv_obj_t * tabpage) lv_coord_t y_diff = point_act.y - ext->point_last.y; - if(x_diff >= LV_INDEV_DRAG_LIMIT || x_diff <= -LV_INDEV_DRAG_LIMIT) { + if(!ext->scroll_ver && (x_diff >= LV_INDEV_DRAG_LIMIT || x_diff <= -LV_INDEV_DRAG_LIMIT)) { ext->draging = 1; /*Check if the page is on the edge */ if((lv_page_on_edge(tabpage, LV_PAGE_EDGE_LEFT) && x_diff > 0) || @@ -752,6 +753,7 @@ static void tabpage_pressing_handler(lv_obj_t * tabview, lv_obj_t * tabpage) } else if(y_diff >= LV_INDEV_DRAG_LIMIT || y_diff <= -LV_INDEV_DRAG_LIMIT) { ext->drag_hor = 0; ext->draging = 1; + ext->scroll_ver = 1; } else ext->draging = 0; @@ -780,6 +782,7 @@ static void tabpage_press_lost_handler(lv_obj_t * tabview, lv_obj_t * tabpage) lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview); ext->drag_hor = 0; ext->draging = 0; + ext->scroll_ver = 0; lv_obj_set_drag(lv_page_get_scrl(tabpage), true); diff --git a/src/lv_objx/lv_tabview.h b/src/lv_objx/lv_tabview.h index 6c451a6a6..5d0cd8291 100644 --- a/src/lv_objx/lv_tabview.h +++ b/src/lv_objx/lv_tabview.h @@ -64,6 +64,7 @@ typedef struct uint8_t slide_enable :1; /*1: enable horizontal sliding by touch pad*/ uint8_t draging :1; uint8_t drag_hor :1; + uint8_t scroll_ver :1; uint8_t btns_hide :1; lv_tabview_btns_pos_t btns_pos :1; } lv_tabview_ext_t; From e22beaea2251a355393ee615b29c4f55dbea56c2 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 23 Mar 2019 08:59:23 -0400 Subject: [PATCH 18/30] Remove merge information in README.md --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 66ef90a67..d7d19c999 100644 --- a/README.md +++ b/README.md @@ -126,11 +126,7 @@ bool my_touchpad_read(lv_indev_t * indev, lv_indev_data_t * data) return false; /*Return `false` because we are not buffering and no more data to read*/ } ``` -<<<<<<< HEAD -6. Call `lv_task_handler()` periodically every few milliseconds in the main `while(1)` loop, in a Timer interrupt or in an Operation system task. -======= 6. Call `lv_task_handler()` periodically every few milliseconds in the main `while(1)` loop, in Timer interrupt or in an Operation system task. It will redraw the screen if required, handle input devices etc. ->>>>>>> master For a detailed description check the [Documentation](https://docs.littlevgl.com/#Porting) or the [Porting examples](https://github.com/littlevgl/lvgl/tree/multi-disp/lv_porting). From d479927e96a7930d8a1799be42734940c7fde962 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Sat, 23 Mar 2019 09:20:41 -0400 Subject: [PATCH 19/30] Make ddlist more aesthetic --- src/lv_objx/lv_ddlist.c | 35 +++++++++++++++++++++++++++++++---- src/lv_objx/lv_ddlist.h | 1 + 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/lv_objx/lv_ddlist.c b/src/lv_objx/lv_ddlist.c index 205272aa8..07b494db9 100644 --- a/src/lv_objx/lv_ddlist.c +++ b/src/lv_objx/lv_ddlist.c @@ -44,6 +44,8 @@ static lv_res_t lv_ddlist_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * static lv_res_t release_handler(lv_obj_t * ddlist); static void lv_ddlist_refr_size(lv_obj_t * ddlist, bool anim_en); static void lv_ddlist_pos_current_option(lv_obj_t * ddlist); +static void lv_ddlist_anim_cb(lv_obj_t * ddlist); +static void lv_ddlist_adjust_height(lv_obj_t * ddlist, int32_t height); /********************** * STATIC VARIABLES @@ -523,7 +525,7 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_desig lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); lv_opa_t opa_scale = lv_obj_get_opa_scale(ddlist); /*If the list is opened draw a rectangle under the selected item*/ - if(ext->opened != 0) { + if(ext->opened != 0 || ext->force_sel) { lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG); const lv_font_t * font = style->text.font; lv_coord_t font_h = lv_font_get_height(font); @@ -548,7 +550,7 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_desig lv_opa_t opa_scale = lv_obj_get_opa_scale(ddlist); /*Redraw only in opened state*/ - if(ext->opened) { + if(ext->opened || ext->force_sel) { lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG); const lv_font_t * font = style->text.font; lv_coord_t font_h = lv_font_get_height(font); @@ -859,9 +861,9 @@ static void lv_ddlist_refr_size(lv_obj_t * ddlist, bool anim_en) a.var = ddlist; a.start = lv_obj_get_height(ddlist); a.end = new_height; - a.fp = (lv_anim_fp_t)lv_obj_set_height; + a.fp = (lv_anim_fp_t)lv_ddlist_adjust_height; a.path = lv_anim_path_linear; - a.end_cb = (lv_anim_cb_t)lv_ddlist_pos_current_option; + a.end_cb = (lv_anim_cb_t)lv_ddlist_anim_cb; a.act_time = 0; a.time = ext->anim_time; a.playback = 0; @@ -869,11 +871,36 @@ static void lv_ddlist_refr_size(lv_obj_t * ddlist, bool anim_en) a.repeat = 0; a.repeat_pause = 0; + ext->force_sel = 1; /*Keep the list item selected*/ lv_anim_create(&a); #endif } } +/** + * Position the list and remove the selection highlight if it's closed. + * Called at end of list animation. + * @param ddlist pointer to a drop down list + */ +static void lv_ddlist_anim_cb(lv_obj_t * ddlist) { + lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); + + lv_ddlist_pos_current_option(ddlist); + + ext->force_sel = 0; /*Turn off drawing of selection*/ +} + +/** + * Adjusts the ddlist's height and then positions the option within it's new height. + * This keeps the option visible during animation. + * @param ddlist Drop down list object + * @param height New drop down list height + */ +static void lv_ddlist_adjust_height(lv_obj_t * ddlist, int32_t height) { + lv_obj_set_height(ddlist, height); + lv_ddlist_pos_current_option(ddlist); +} + /** * Set the position of list when it is closed to show the selected item * @param ddlist pointer to a drop down list diff --git a/src/lv_objx/lv_ddlist.h b/src/lv_objx/lv_ddlist.h index 5a516a932..799df11e5 100644 --- a/src/lv_objx/lv_ddlist.h +++ b/src/lv_objx/lv_ddlist.h @@ -53,6 +53,7 @@ typedef struct uint16_t sel_opt_id_ori; /*Store the original index on focus*/ uint16_t anim_time; /*Open/Close animation time [ms]*/ uint8_t opened :1; /*1: The list is opened (handled by the library)*/ + uint8_t force_sel :1; /*1: Keep the selection highlight even if the list is closed*/ uint8_t draw_arrow :1; /*1: Draw arrow*/ uint8_t stay_open :1; /*1: Don't close the list when a new item is selected*/ lv_coord_t fix_height; /*Height of the ddlist when opened. (0: auto-size)*/ From 5565516e96bd322c217588d17c757a5749d9539e Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Sat, 23 Mar 2019 09:33:34 -0400 Subject: [PATCH 20/30] Fix off-by-one error in chart line drawing --- src/lv_objx/lv_chart.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lv_objx/lv_chart.c b/src/lv_objx/lv_chart.c index 871d56b66..3e82ac74f 100644 --- a/src/lv_objx/lv_chart.c +++ b/src/lv_objx/lv_chart.c @@ -492,6 +492,7 @@ static bool lv_chart_design(lv_obj_t * chart, const lv_area_t * mask, lv_design_ if(ext->type & LV_CHART_TYPE_POINT) lv_chart_draw_points(chart, mask); if(ext->type & LV_CHART_TYPE_VERTICAL_LINE) lv_chart_draw_vertical_lines(chart, mask); if(ext->type & LV_CHART_TYPE_AREA) lv_chart_draw_areas(chart, mask); + } return true; } @@ -545,8 +546,8 @@ static void lv_chart_draw_div(lv_obj_t * chart, const lv_area_t * mask) uint8_t div_i_start; lv_point_t p1; lv_point_t p2; - lv_coord_t w = lv_obj_get_width(chart); - lv_coord_t h = lv_obj_get_height(chart); + lv_coord_t w = lv_obj_get_width(chart) - 1; + lv_coord_t h = lv_obj_get_height(chart) - 1; lv_coord_t x_ofs = chart->coords.x1; lv_coord_t y_ofs = chart->coords.y1; From db4f4f0360509930209ba2b56e7ac3ad43937816 Mon Sep 17 00:00:00 2001 From: user-0 Date: Sat, 23 Mar 2019 22:21:02 +0200 Subject: [PATCH 21/30] FIXED/UPDATED: Add support for chart axes ticks and value labels / chart label. --- lv_conf_template.h | 1 + src/lv_objx/lv_chart.c | 107 ++++++++++++++++++----------------------- src/lv_objx/lv_chart.h | 20 +++++--- 3 files changed, 59 insertions(+), 69 deletions(-) diff --git a/lv_conf_template.h b/lv_conf_template.h index 8def85a49..8450b6ea8 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -257,6 +257,7 @@ typedef void * lv_obj_user_data_t; /*Declare the type of the user data /*Chart (dependencies: -)*/ #define LV_USE_CHART 1 +#define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 16 /*Table (dependencies: lv_label)*/ #define LV_USE_TABLE 1 diff --git a/src/lv_objx/lv_chart.c b/src/lv_objx/lv_chart.c index 2f9a4d5d5..ac9b2fe1d 100644 --- a/src/lv_objx/lv_chart.c +++ b/src/lv_objx/lv_chart.c @@ -20,13 +20,11 @@ #define LV_CHART_HDIV_DEF 3 #define LV_CHART_VDIV_DEF 5 #define LV_CHART_PNUM_DEF 10 -#define LV_CHART_AXIS_MARGIN 50 -#define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 16 -#define LV_CHART_AXIS_TO_LABEL_DISTANCE 4 -#define LV_CHART_AXIS_MAJOR_TICK_LEN_COE 1/15 -#define LV_CHART_AXIS_MINOR_TICK_LEN_COE 2/3 -#define LV_CHART_AXIS_X_TICK_OFFSET_FIX 1 -#define LV_CHART_AXIS_Y_TICK_OFFSET_FIX 0 +#define LV_CHART_AXIS_TO_LABEL_DISTANCE 4 +#define LV_CHART_AXIS_MAJOR_TICK_LEN_COE 1/15 +#define LV_CHART_AXIS_MINOR_TICK_LEN_COE 2/3 +#define LV_CHART_AXIS_X_TICK_OFFSET_FIX 1 +#define LV_CHART_AXIS_Y_TICK_OFFSET_FIX 0 /********************** * TYPEDEFS @@ -90,6 +88,7 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy) ext->series.opa = LV_OPA_COVER; ext->series.dark = LV_OPA_50; ext->series.width = 2; + ext->margin = 0; memset(&ext->x_axis, 0, sizeof(ext->x_axis)); memset(&ext->y_axis, 0, sizeof(ext->y_axis)); @@ -120,8 +119,9 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy) ext->vdiv_cnt = ext_copy->vdiv_cnt; ext->point_cnt = ext_copy->point_cnt; ext->series.opa = ext_copy->series.opa; - ext->x_axis = ext_copy->x_axis; - ext->y_axis = ext_copy->y_axis; + ext->margin = ext_copy->margin; + memcpy(&ext->x_axis, &ext_copy->x_axis, sizeof(lv_chart_axis_cfg_t)); + memcpy(&ext->y_axis, &ext_copy->y_axis, sizeof(lv_chart_axis_cfg_t)); /*Refresh the style with new signal function*/ lv_obj_refresh_style(new_chart); @@ -401,15 +401,14 @@ void lv_chart_set_next(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y) } /** - * Set the x-axis label of a chart - * @param chart pointer to a chart object - * @param text pointer to the label text (not copied) + * Set the margin around the chart, used for axes value and labels + * @param margin value of the margin */ -void lv_chart_set_label(lv_obj_t* chart, const char* text) +void lv_chart_set_margin(lv_obj_t* chart, uint16_t margin) { - lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); - ext->x_axis.label = text; - lv_obj_refresh_ext_size(chart); + lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); + ext->margin = margin; + lv_obj_refresh_ext_size(chart); } /** @@ -418,32 +417,37 @@ void lv_chart_set_label(lv_obj_t* chart, const char* text) * @param list_of_values list of string values, terminated with \n, except the last * @param num_tick_marks if list_of_values is NULL: total number of ticks per axis * else step in ticks between two value labels - * @param label label to show for this axis (only X) + * @param major_tick_len the length of the major tick, AUTO if 0 + * @param minor_tick_len the length of the minor tick, AUTO if 0 * @param options extra options */ void lv_chart_set_x_ticks( lv_obj_t* chart, const char* list_of_values, uint8_t num_tick_marks, - const char* label, + uint8_t major_tick_len, + uint8_t minor_tick_len, lv_chart_axis_options_t options) { lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); ext->x_axis.num_tick_marks = num_tick_marks; ext->x_axis.list_of_values = list_of_values; - ext->x_axis.label = label; + ext->x_axis.major_tick_len = major_tick_len; + ext->x_axis.minor_tick_len = minor_tick_len; ext->x_axis.options = options; } void lv_chart_set_y_ticks( lv_obj_t* chart, const char* list_of_values, uint8_t num_tick_marks, - const char* label, + uint8_t major_tick_len, + uint8_t minor_tick_len, lv_chart_axis_options_t options) { lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); ext->y_axis.num_tick_marks = num_tick_marks; ext->y_axis.list_of_values = list_of_values; - ext->y_axis.label = label; + ext->y_axis.major_tick_len = major_tick_len; + ext->y_axis.minor_tick_len = minor_tick_len; ext->y_axis.options = options; } @@ -565,6 +569,7 @@ static bool lv_chart_design(lv_obj_t * chart, const lv_area_t * mask, lv_design_ static lv_res_t lv_chart_signal(lv_obj_t * chart, lv_signal_t sign, void * param) { lv_res_t res; + lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); /* Include the ancient signal function */ res = ancestor_signal(chart, sign, param); @@ -572,7 +577,6 @@ static lv_res_t lv_chart_signal(lv_obj_t * chart, lv_signal_t sign, void * param if(sign == LV_SIGNAL_CLEANUP) { lv_coord_t ** datal; - lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); LV_LL_READ(ext->series_ll, datal) { lv_mem_free(*datal); } @@ -585,15 +589,8 @@ static lv_res_t lv_chart_signal(lv_obj_t * chart, lv_signal_t sign, void * param } buf->type[i] = "lv_chart"; } else if(sign == LV_SIGNAL_REFR_EXT_SIZE) { - /*Provide extra px draw area around the chart if needed*/ - lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); - - if( (ext->x_axis.list_of_values != NULL || ext->x_axis.num_tick_marks != 0) || - (ext->y_axis.list_of_values != NULL || ext->y_axis.num_tick_marks != 0) || - (ext->x_axis.label == NULL) ) - { /* Reserve some space for axis ticks and labels, predefined by the user */ - chart->ext_size += LV_CHART_AXIS_MARGIN; - } + /*Provide extra px draw area around the chart*/ + chart->ext_size = ext->margin; } return res; @@ -977,8 +974,15 @@ static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask) char buf[LV_CHART_AXIS_TICK_LABEL_MAX_LEN+1]; /* up to N symbols per label + null terminator */ /* calculate the size of tick marks */ - major_tick_len = (int32_t)w * LV_CHART_AXIS_MAJOR_TICK_LEN_COE; - minor_tick_len = major_tick_len * LV_CHART_AXIS_MINOR_TICK_LEN_COE; + if(ext->y_axis.major_tick_len == 0) + major_tick_len = (int32_t)w * LV_CHART_AXIS_MAJOR_TICK_LEN_COE; + else + major_tick_len = ext->y_axis.major_tick_len; + + if(ext->y_axis.minor_tick_len == 0) + minor_tick_len = major_tick_len * LV_CHART_AXIS_MINOR_TICK_LEN_COE; + else + minor_tick_len = ext->y_axis.minor_tick_len; /* count the '\n'-s to determine the number of options */ list_index = 0; @@ -1084,8 +1088,15 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask) char buf[LV_CHART_AXIS_TICK_LABEL_MAX_LEN+1]; /* up to N symbols per label + null terminator */ /* calculate the size of tick marks */ - major_tick_len = (int32_t)w * LV_CHART_AXIS_MAJOR_TICK_LEN_COE; - minor_tick_len = major_tick_len * LV_CHART_AXIS_MINOR_TICK_LEN_COE; + if(ext->x_axis.major_tick_len == 0) + major_tick_len = (int32_t)w * LV_CHART_AXIS_MAJOR_TICK_LEN_COE; + else + major_tick_len = ext->x_axis.major_tick_len; + + if(ext->x_axis.minor_tick_len == 0) + minor_tick_len = major_tick_len * LV_CHART_AXIS_MINOR_TICK_LEN_COE; + else + minor_tick_len = ext->x_axis.minor_tick_len; /* count the '\n'-s to determine the number of options */ list_index = 0; @@ -1167,35 +1178,9 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask) } } -static void lv_chart_draw_x_axis_label(lv_obj_t * chart, const lv_area_t * mask) -{ - - lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); - - if (ext->x_axis.label != NULL) - { - const lv_style_t * style = lv_obj_get_style(chart); - lv_opa_t opa_scale = lv_obj_get_opa_scale(chart); - lv_coord_t w = lv_obj_get_width(chart); - - lv_point_t size; - lv_txt_get_size(&size, ext->x_axis.label, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, LV_TXT_FLAG_CENTER); - - lv_area_t label_area; - label_area.x1 = chart->coords.x1 + w/2 - size.x/2; - label_area.y1 = chart->coords.y1 - LV_CHART_AXIS_TO_LABEL_DISTANCE - (style->text.font->h_px / 4) - size.y/2; - label_area.x2 = label_area.x1 + size.x; - label_area.y2 = label_area.y1 + size.y/2; - - lv_draw_label(&label_area, mask, style, opa_scale, ext->x_axis.label, LV_TXT_FLAG_CENTER, NULL); - } -} - static void lv_chart_draw_axes(lv_obj_t * chart, const lv_area_t * mask) { lv_chart_draw_y_ticks(chart, mask); lv_chart_draw_x_ticks(chart, mask); - lv_chart_draw_x_axis_label(chart, mask); } - #endif diff --git a/src/lv_objx/lv_chart.h b/src/lv_objx/lv_chart.h index 9297f600c..49c4983bd 100644 --- a/src/lv_objx/lv_chart.h +++ b/src/lv_objx/lv_chart.h @@ -62,8 +62,9 @@ typedef struct { const char* list_of_values; uint8_t num_tick_marks; - const char* label; lv_chart_axis_options_t options; + uint8_t major_tick_len; + uint8_t minor_tick_len; } lv_chart_axis_cfg_t; /*Data of chart */ @@ -80,6 +81,7 @@ typedef struct lv_chart_type_t type; /*Line, column or point chart (from 'lv_chart_type_t')*/ lv_chart_axis_cfg_t y_axis; lv_chart_axis_cfg_t x_axis; + uint16_t margin; struct { lv_coord_t width; /*Line width or point radius*/ uint8_t num; /*Number of data lines in dl_ll*/ @@ -211,11 +213,10 @@ static inline void lv_chart_set_style(lv_obj_t *chart, lv_style_t *style) } /** - * Set the x-axis label of a chart - * @param chart pointer to a chart object - * @param text pointer to the label text (not copied) + * Set the margin around the chart, used for axes value and labels + * @param margin value of the margin */ -void lv_chart_set_label(lv_obj_t* chart, const char* text); +void lv_chart_set_margin(lv_obj_t* chart, uint16_t margin); /** * Set the x/y-axis ticks of a chart @@ -223,19 +224,22 @@ void lv_chart_set_label(lv_obj_t* chart, const char* text); * @param list_of_values list of string values, terminated with \n, except the last * @param num_tick_marks if list_of_values is NULL: total number of ticks per axis * else step in ticks between two value labels - * @param label label to show for this axis (only X) + * @param major_tick_len the length of the major tick, AUTO if 0 + * @param minor_tick_len the length of the minor tick, AUTO if 0 * @param options extra options */ void lv_chart_set_x_ticks( lv_obj_t* chart, const char* list_of_values, uint8_t num_tick_marks, - const char* label, + uint8_t major_tick_len, + uint8_t minor_tick_len, lv_chart_axis_options_t options); void lv_chart_set_y_ticks( lv_obj_t* chart, const char* list_of_values, uint8_t num_tick_marks, - const char* label, + uint8_t major_tick_len, + uint8_t minor_tick_len, lv_chart_axis_options_t options); /*===================== From 81696b85d06faed52c0b4a12d10bd4963f315de9 Mon Sep 17 00:00:00 2001 From: user-0 Date: Sat, 23 Mar 2019 23:59:12 +0200 Subject: [PATCH 22/30] FIXED: Add support for chart axes ticks and value labels / chart label. --- src/lv_objx/lv_chart.c | 11 +++++++++++ src/lv_objx/lv_chart.h | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/src/lv_objx/lv_chart.c b/src/lv_objx/lv_chart.c index ac9b2fe1d..3a3f28343 100644 --- a/src/lv_objx/lv_chart.c +++ b/src/lv_objx/lv_chart.c @@ -523,6 +523,17 @@ void lv_chart_refresh(lv_obj_t * chart) lv_obj_invalidate(chart); } +/** + * Set the margin around the chart, used for axes value and labels + * @param chart pointer to an chart object + * @param return margin value of the margin + */ +uint16_t lv_chart_get_margin(lv_obj_t* chart) +{ + lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); + return ext->margin; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/lv_objx/lv_chart.h b/src/lv_objx/lv_chart.h index 49c4983bd..23e20daf2 100644 --- a/src/lv_objx/lv_chart.h +++ b/src/lv_objx/lv_chart.h @@ -214,6 +214,7 @@ static inline void lv_chart_set_style(lv_obj_t *chart, lv_style_t *style) /** * Set the margin around the chart, used for axes value and labels + * @param chart pointer to an chart object * @param margin value of the margin */ void lv_chart_set_margin(lv_obj_t* chart, uint16_t margin); @@ -291,6 +292,13 @@ static inline lv_style_t* lv_chart_get_style(const lv_obj_t *chart) return lv_obj_get_style(chart); } +/** + * Set the margin around the chart, used for axes value and labels + * @param chart pointer to an chart object + * @param return margin value of the margin + */ +uint16_t lv_chart_get_margin(lv_obj_t* chart); + /*===================== * Other functions *====================*/ From 36b47ba98d3e7ee770944279a8c6b601d4f3e7fb Mon Sep 17 00:00:00 2001 From: user-0 Date: Sun, 24 Mar 2019 00:07:16 +0200 Subject: [PATCH 23/30] FIX margin get function documentation --- src/lv_objx/lv_chart.c | 4 ++-- src/lv_objx/lv_chart.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lv_objx/lv_chart.c b/src/lv_objx/lv_chart.c index 3a3f28343..43b7cf1d6 100644 --- a/src/lv_objx/lv_chart.c +++ b/src/lv_objx/lv_chart.c @@ -524,9 +524,9 @@ void lv_chart_refresh(lv_obj_t * chart) } /** - * Set the margin around the chart, used for axes value and labels + * Get the margin around the chart, used for axes value and labels * @param chart pointer to an chart object - * @param return margin value of the margin + * @param return value of the margin */ uint16_t lv_chart_get_margin(lv_obj_t* chart) { diff --git a/src/lv_objx/lv_chart.h b/src/lv_objx/lv_chart.h index 23e20daf2..3448c2c7f 100644 --- a/src/lv_objx/lv_chart.h +++ b/src/lv_objx/lv_chart.h @@ -293,9 +293,9 @@ static inline lv_style_t* lv_chart_get_style(const lv_obj_t *chart) } /** - * Set the margin around the chart, used for axes value and labels + * Get the margin around the chart, used for axes value and labels * @param chart pointer to an chart object - * @param return margin value of the margin + * @param return value of the margin */ uint16_t lv_chart_get_margin(lv_obj_t* chart); From 13e7f162a05cc93632fb9992c8941d93a8fc4cb8 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 24 Mar 2019 06:11:09 +0100 Subject: [PATCH 24/30] lv_ddlist: fixes for scrollbar visibility --- src/lv_objx/lv_ddlist.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lv_objx/lv_ddlist.c b/src/lv_objx/lv_ddlist.c index 07b494db9..ed1d7d8f8 100644 --- a/src/lv_objx/lv_ddlist.c +++ b/src/lv_objx/lv_ddlist.c @@ -841,7 +841,6 @@ static void lv_ddlist_refr_size(lv_obj_t * ddlist, bool anim_en) style->body.padding.top + style->body.padding.bottom; else new_height = ext->fix_height; - lv_page_set_sb_mode(ddlist, LV_SB_MODE_UNHIDE); } else { /*Close the list*/ const lv_font_t * font = style->text.font; lv_style_t * label_style = lv_obj_get_style(ext->label); @@ -854,6 +853,7 @@ static void lv_ddlist_refr_size(lv_obj_t * ddlist, bool anim_en) if(anim_en == 0) { lv_obj_set_height(ddlist, new_height); lv_ddlist_pos_current_option(ddlist); + if(ext->opened) lv_page_set_sb_mode(ddlist, LV_SB_MODE_UNHIDE); #if LV_USE_ANIMATION lv_anim_del(ddlist, (lv_anim_fp_t)lv_obj_set_height); /*If an animation is in progress then it will overwrite this changes*/ } else { @@ -888,6 +888,8 @@ static void lv_ddlist_anim_cb(lv_obj_t * ddlist) { lv_ddlist_pos_current_option(ddlist); ext->force_sel = 0; /*Turn off drawing of selection*/ + + if(ext->opened) lv_page_set_sb_mode(ddlist, LV_SB_MODE_UNHIDE); } /** From 221e269ccbf2e0d42e4c712bc1271df60f692cd3 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 24 Mar 2019 07:16:13 +0100 Subject: [PATCH 25/30] roller and ddlist fixes --- src/lv_objx/lv_ddlist.c | 2 +- src/lv_objx/lv_roller.c | 25 +++++++++++-------------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/lv_objx/lv_ddlist.c b/src/lv_objx/lv_ddlist.c index ed1d7d8f8..23c43dc62 100644 --- a/src/lv_objx/lv_ddlist.c +++ b/src/lv_objx/lv_ddlist.c @@ -787,7 +787,6 @@ static lv_res_t release_handler(lv_obj_t * ddlist) if(lv_indev_get_type(indev) == LV_INDEV_TYPE_POINTER || lv_indev_get_type(indev) == LV_INDEV_TYPE_BUTTON) { lv_point_t p; lv_indev_get_point(indev, &p); - p.x -= ext->label->coords.x1; p.y -= ext->label->coords.y1; uint16_t letter_i; letter_i = lv_label_get_letter_on(ext->label, &p); @@ -803,6 +802,7 @@ static lv_res_t release_handler(lv_obj_t * ddlist) } ext->sel_opt_id = new_opt; + printf("rid: %d\n", new_opt); } ext->sel_opt_id_ori = ext->sel_opt_id; diff --git a/src/lv_objx/lv_roller.c b/src/lv_objx/lv_roller.c index 1ee06fdf3..57057539c 100644 --- a/src/lv_objx/lv_roller.c +++ b/src/lv_objx/lv_roller.c @@ -410,7 +410,9 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par lv_obj_set_height(lv_page_get_scrl(roller), lv_obj_get_height(ext->ddlist.label) + lv_obj_get_height(roller)); lv_obj_align(ext->ddlist.label, NULL, obj_align, 0, 0); + lv_anim_del(lv_page_get_scrl(roller), (lv_anim_fp_t)lv_obj_set_y); lv_ddlist_set_selected(roller, ext->ddlist.sel_opt_id); + refr_position(roller, false); } else if(sign == LV_SIGNAL_CORD_CHG) { @@ -422,6 +424,7 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par lv_obj_get_height(ext->ddlist.label) + lv_obj_get_height(roller)); lv_obj_align(ext->ddlist.label, NULL, obj_align, 0, 0); + lv_anim_del(lv_page_get_scrl(roller), (lv_anim_fp_t)lv_obj_set_y); lv_ddlist_set_selected(roller, ext->ddlist.sel_opt_id); refr_position(roller, false); } @@ -446,7 +449,6 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par } } else { ext->ddlist.sel_opt_id_ori = ext->ddlist.sel_opt_id; /*Save the current value. Used to revert this state if ENER wont't be pressed*/ - } #endif } else if(sign == LV_SIGNAL_DEFOCUS) { @@ -461,11 +463,15 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par char c = *((char *)param); if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN) { if(ext->ddlist.sel_opt_id + 1 < ext->ddlist.option_cnt) { + uint16_t ori_id = ext->ddlist.sel_opt_id_ori; /*lv_roller_set_selceted will overwrite this*/ lv_roller_set_selected(roller, ext->ddlist.sel_opt_id + 1, true); + ext->ddlist.sel_opt_id_ori = ori_id; } } else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP) { if(ext->ddlist.sel_opt_id > 0) { + uint16_t ori_id = ext->ddlist.sel_opt_id_ori; /*lv_roller_set_selceted will overwrite this*/ lv_roller_set_selected(roller, ext->ddlist.sel_opt_id - 1, true); + ext->ddlist.sel_opt_id_ori = ori_id; } } } else if(sign == LV_SIGNAL_GET_TYPE) { @@ -518,26 +524,18 @@ static lv_res_t lv_roller_scrl_signal(lv_obj_t * roller_scrl, lv_signal_t sign, ext->ddlist.sel_opt_id = id; ext->ddlist.sel_opt_id_ori = id; - res = lv_event_send(roller, LV_EVENT_VALUE_CHANGED, NULL); + res = lv_event_send(roller, LV_EVENT_VALUE_CHANGED, &id); if(res != LV_RES_OK) return res; - } else if(sign == LV_SIGNAL_RELEASED) { + } + else if(sign == LV_SIGNAL_RELEASED) { /*If picked an option by clicking then set it*/ if(!lv_indev_is_dragging(indev)) { - lv_point_t p; - lv_indev_get_point(indev, &p); - p.y = p.y - ext->ddlist.label->coords.y1; - id = p.y / (font_h + style_label->text.line_space); - if(id < 0) id = 0; - if(id >= ext->ddlist.option_cnt) id = ext->ddlist.option_cnt - 1; - ext->ddlist.sel_opt_id = id; - ext->ddlist.sel_opt_id_ori = id; + id = ext->ddlist.sel_opt_id; #if LV_USE_GROUP lv_group_t * g = lv_obj_get_group(roller); bool editing = lv_group_get_editing(g); if(editing) lv_group_set_editing(g, false); /*In edit mode go to navigate mode if an option is selected*/ #endif - res = lv_event_send(roller, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; } } @@ -668,7 +666,6 @@ static void inf_normalize(void * roller_scrl) ext->ddlist.sel_opt_id = ext->ddlist.sel_opt_id % real_id_cnt; ext->ddlist.sel_opt_id += (LV_ROLLER_INF_PAGES / 2) * real_id_cnt; /*Select the middle page*/ - ext->ddlist.sel_opt_id_ori = ext->ddlist.sel_opt_id; /*Move to the new id*/ lv_obj_t * roller_scrl = lv_page_get_scrl(roller); From a402f8258d64c223bd7ab825ca4f431a1c693cc2 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 24 Mar 2019 07:31:56 +0100 Subject: [PATCH 26/30] update lv_conf_checker.h --- scripts/lv_conf_checker.py | 2 +- src/lv_conf_checker.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/lv_conf_checker.py b/scripts/lv_conf_checker.py index 04fcb9f72..a16b36353 100644 --- a/scripts/lv_conf_checker.py +++ b/scripts/lv_conf_checker.py @@ -5,7 +5,7 @@ Generates a chechker file for lv_conf.h from lv_conf_templ.h define all the not import re -fin = open("../templates/lv_conf_templ.h", "r"); +fin = open("../lv_conf_template.h", "r"); fout = open("../src/lv_conf_checker.h", "w"); diff --git a/src/lv_conf_checker.h b/src/lv_conf_checker.h index 8fe96eb7f..e1de81219 100644 --- a/src/lv_conf_checker.h +++ b/src/lv_conf_checker.h @@ -439,6 +439,9 @@ #ifndef LV_USE_CHART #define LV_USE_CHART 1 #endif +#ifndef LV_CHART_AXIS_TICK_LABEL_MAX_LEN +#define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 16 +#endif /*Table (dependencies: lv_label)*/ #ifndef LV_USE_TABLE From d4559a0f39557e58fcc499ce6ea7599478ced682 Mon Sep 17 00:00:00 2001 From: embeddedt Date: Sun, 24 Mar 2019 09:52:24 -0400 Subject: [PATCH 27/30] Move lv_canvas_get_px/lv_canvas_set_px to lv_draw_img.c --- src/lv_draw/lv_draw_img.c | 124 ++++++++++++++++++++++++++++++++++ src/lv_draw/lv_draw_img.h | 19 +++++- src/lv_objx/lv_canvas.c | 137 ++++---------------------------------- 3 files changed, 155 insertions(+), 125 deletions(-) diff --git a/src/lv_draw/lv_draw_img.c b/src/lv_draw/lv_draw_img.c index b2bbb0315..2ef5c033b 100644 --- a/src/lv_draw/lv_draw_img.c +++ b/src/lv_draw/lv_draw_img.c @@ -143,8 +143,132 @@ lv_res_t lv_img_dsc_get_info(const char * src, lv_img_header_t * header) } return true; +} + +/** + * Get the color of a pixel on the canvas + * @param canvas + * @param x x coordinate of the point to set + * @param y x coordinate of the point to set + * @return color of the point + */ +lv_color_t lv_img_buf_get_px(lv_img_dsc_t *dsc, lv_coord_t x, lv_coord_t y) +{ + lv_color_t p_color = LV_COLOR_BLACK; + if(x >= dsc->header.w) { + x = dsc->header.w - 1; + LV_LOG_WARN("lv_canvas_get_px: x is too large (out of canvas)"); + } + else if(x < 0) { + x = 0; + LV_LOG_WARN("lv_canvas_get_px: x is < 0 (out of canvas)"); + } + + + if(y >= dsc->header.h) { + y = dsc->header.h - 1; + LV_LOG_WARN("lv_canvas_get_px: y is too large (out of canvas)"); + } + else if(y < 0) { + y = 0; + LV_LOG_WARN("lv_canvas_get_px: y is < 0 (out of canvas)"); + } + + uint8_t * buf_u8 = (uint8_t *) dsc->data; + + if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || + dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) + { + uint32_t px = dsc->header.w * y * sizeof(lv_color_t) + x * sizeof(lv_color_t); + memcpy(&p_color, &buf_u8[px], sizeof(lv_color_t)); + } + else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT) { + buf_u8 += 4 * 2; + uint8_t bit = x & 0x7; + x = x >> 3; + + uint32_t px = (dsc->header.w >> 3) * y + x; + p_color.full = (buf_u8[px] & (1 << (7 - bit))) >> (7 - bit); + } + else if(dsc->header.cf == LV_IMG_CF_INDEXED_2BIT) { + buf_u8 += 4 * 4; + uint8_t bit = (x & 0x3) * 2; + x = x >> 2; + + uint32_t px = (dsc->header.w >> 2) * y + x; + p_color.full = (buf_u8[px] & (3 << (6 - bit))) >> (6 - bit); + } + else if(dsc->header.cf == LV_IMG_CF_INDEXED_4BIT) { + buf_u8 += 4 * 16; + uint8_t bit = (x & 0x1) * 4; + x = x >> 1; + + uint32_t px = (dsc->header.w >> 1) * y + x; + p_color.full = (buf_u8[px] & (0xF << (4 - bit))) >> (4 - bit); + } + else if(dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) { + buf_u8 += 4 * 256; + uint32_t px = dsc->header.w * y + x; + p_color.full = buf_u8[px]; + } + return p_color; +} + +/** + * Set the color of a pixel on the canvas + * @param dsc image + * @param x x coordinate of the point to set + * @param y x coordinate of the point to set + * @param c color of the point + */ +void lv_img_buf_set_px(lv_img_dsc_t *dsc, lv_coord_t x, lv_coord_t y, lv_color_t c) +{ + uint8_t * buf_u8 = (uint8_t *) dsc->data; + + if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || + dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) + { + uint32_t px = dsc->header.w * y * sizeof(lv_color_t) + x * sizeof(lv_color_t); + + memcpy(&buf_u8[px], &c, sizeof(lv_color_t)); + } + else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT) { + buf_u8 += 4 * 2; + uint8_t bit = x & 0x7; + x = x >> 3; + + uint32_t px = (dsc->header.w >> 3) * y + x; + buf_u8[px] = buf_u8[px] & ~(1 << (7 - bit)); + buf_u8[px] = buf_u8[px] | ((c.full & 0x1) << (7 - bit)); + } + else if(dsc->header.cf == LV_IMG_CF_INDEXED_2BIT) { + buf_u8 += 4 * 4; + uint8_t bit = (x & 0x3) * 2; + x = x >> 2; + + uint32_t px = (dsc->header.w >> 2) * y + x; + + buf_u8[px] = buf_u8[px] & ~(3 << (6 - bit)); + buf_u8[px] = buf_u8[px] | ((c.full & 0x3) << (6 - bit)); + } + else if(dsc->header.cf == LV_IMG_CF_INDEXED_4BIT) { + buf_u8 += 4 * 16; + uint8_t bit = (x & 0x1) * 4; + x = x >> 1; + + uint32_t px = (dsc->header.w >> 1) * y + x; + + buf_u8[px] = buf_u8[px] & ~(0xF << (4 - bit)); + buf_u8[px] = buf_u8[px] | ((c.full & 0xF) << (4 - bit)); + } + else if(dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) { + buf_u8 += 4 * 256; + uint32_t px = dsc->header.w * y + x; + buf_u8[px] = c.full; + } } + uint8_t lv_img_color_format_get_px_size(lv_img_cf_t cf) { uint8_t px_size = 0; diff --git a/src/lv_draw/lv_draw_img.h b/src/lv_draw/lv_draw_img.h index 4f8137676..101c57d89 100644 --- a/src/lv_draw/lv_draw_img.h +++ b/src/lv_draw/lv_draw_img.h @@ -153,7 +153,24 @@ uint8_t lv_img_color_format_get_px_size(lv_img_cf_t cf); bool lv_img_color_format_is_chroma_keyed(lv_img_cf_t cf); bool lv_img_color_format_has_alpha(lv_img_cf_t cf); - + +/** + * Set the color of a pixel on an image + * @param dsc image + * @param x x coordinate of the point to set + * @param y x coordinate of the point to set + * @param c color of the point + */ +void lv_img_buf_set_px(lv_img_dsc_t *dsc, lv_coord_t x, lv_coord_t y, lv_color_t c); + +/** + * Get the color of a pixel on an image + * @param dsc image + * @param x x coordinate of the point to set + * @param y x coordinate of the point to set + * @return color of the point + */ +lv_color_t lv_img_buf_get_px(lv_img_dsc_t *dsc, lv_coord_t x, lv_coord_t y); /********************** * MACROS diff --git a/src/lv_objx/lv_canvas.c b/src/lv_objx/lv_canvas.c index d2870d38d..065badc63 100644 --- a/src/lv_objx/lv_canvas.c +++ b/src/lv_objx/lv_canvas.c @@ -8,7 +8,8 @@ *********************/ #include #include "lv_canvas.h" -#include "../lv_misc/lv_math.h" +#include "../lv_misc/lv_math.h" +#include "../lv_draw/lv_draw_img.h" #if LV_USE_CANVAS != 0 /********************* @@ -23,7 +24,6 @@ * STATIC PROTOTYPES **********************/ static lv_res_t lv_canvas_signal(lv_obj_t * canvas, lv_signal_t sign, void * param); -static void set_px_core(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t c); /********************** * STATIC VARIABLES @@ -130,8 +130,10 @@ void lv_canvas_set_buffer(lv_obj_t * canvas, void * buf, lv_coord_t w, lv_coord_ * @param c color of the point */ void lv_canvas_set_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t c) -{ - set_px_core(canvas, x, y, c); +{ + lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas); + + lv_img_buf_set_px(&ext->dsc, x, y, c); lv_obj_invalidate(canvas); } @@ -164,65 +166,9 @@ void lv_canvas_set_style(lv_obj_t * canvas, lv_canvas_style_t type, lv_style_t * */ lv_color_t lv_canvas_get_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y) { - lv_color_t p_color = LV_COLOR_BLACK; lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas); - if(x >= ext->dsc.header.w) { - x = ext->dsc.header.w - 1; - LV_LOG_WARN("lv_canvas_get_px: x is too large (out of canvas)"); - } - else if(x < 0) { - x = 0; - LV_LOG_WARN("lv_canvas_get_px: x is < 0 (out of canvas)"); - } - - - if(y >= ext->dsc.header.h) { - y = ext->dsc.header.h - 1; - LV_LOG_WARN("lv_canvas_get_px: y is too large (out of canvas)"); - } - else if(y < 0) { - y = 0; - LV_LOG_WARN("lv_canvas_get_px: y is < 0 (out of canvas)"); - } - - uint8_t * buf_u8 = (uint8_t *) ext->dsc.data; - - if(ext->dsc.header.cf == LV_IMG_CF_TRUE_COLOR || - ext->dsc.header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) - { - uint32_t px = ext->dsc.header.w * y * sizeof(lv_color_t) + x * sizeof(lv_color_t); - memcpy(&p_color, &buf_u8[px], sizeof(lv_color_t)); - } - else if(ext->dsc.header.cf == LV_IMG_CF_INDEXED_1BIT) { - buf_u8 += 4 * 2; - uint8_t bit = x & 0x7; - x = x >> 3; - - uint32_t px = (ext->dsc.header.w >> 3) * y + x; - p_color.full = (buf_u8[px] & (1 << (7 - bit))) >> (7 - bit); - } - else if(ext->dsc.header.cf == LV_IMG_CF_INDEXED_2BIT) { - buf_u8 += 4 * 4; - uint8_t bit = (x & 0x3) * 2; - x = x >> 2; - - uint32_t px = (ext->dsc.header.w >> 2) * y + x; - p_color.full = (buf_u8[px] & (3 << (6 - bit))) >> (6 - bit); - } - else if(ext->dsc.header.cf == LV_IMG_CF_INDEXED_4BIT) { - buf_u8 += 4 * 16; - uint8_t bit = (x & 0x1) * 4; - x = x >> 1; - - uint32_t px = (ext->dsc.header.w >> 1) * y + x; - p_color.full = (buf_u8[px] & (0xF << (4 - bit))) >> (4 - bit); - } - else if(ext->dsc.header.cf == LV_IMG_CF_INDEXED_8BIT) { - buf_u8 += 4 * 256; - uint32_t px = ext->dsc.header.w * y + x; - p_color.full = buf_u8[px]; - } - return p_color; + + return lv_img_buf_get_px(&ext->dsc, x, y); } /** @@ -443,7 +389,7 @@ void lv_canvas_rotate(lv_obj_t * canvas_dest, lv_obj_t * canvas_src, int16_t ang // if (x + offset_x >= 0 && x + offset_x < dest_width && y + offset_y >= 0 && y + offset_y < dest_height) { /*The result color as the average of the x/y mixed colors*/ - set_px_core(canvas_dest, x + offset_x, y + offset_y, lv_color_mix(x_dest, y_dest, LV_OPA_50)); + lv_img_buf_set_px(&ext_dst->dsc, x + offset_x, y + offset_y, lv_color_mix(x_dest, y_dest, LV_OPA_50)); } } } @@ -530,7 +476,7 @@ void lv_canvas_draw_line(lv_obj_t * canvas, lv_point_t point1, lv_point_t point2 * @param color line color of the triangle */ void lv_canvas_draw_triangle(lv_obj_t * canvas, lv_point_t * points, lv_color_t color) -{ +{ lv_canvas_draw_polygon(canvas, points, 3, color); } @@ -541,7 +487,7 @@ void lv_canvas_draw_triangle(lv_obj_t * canvas, lv_point_t * points, lv_color_t * @param color line color of the rectangle */ void lv_canvas_draw_rect(lv_obj_t * canvas, lv_point_t * points, lv_color_t color) -{ +{ lv_canvas_draw_polygon(canvas, points, 4, color); } @@ -553,7 +499,7 @@ void lv_canvas_draw_rect(lv_obj_t * canvas, lv_point_t * points, lv_color_t colo * @param color line color of the polygon */ void lv_canvas_draw_polygon(lv_obj_t * canvas, lv_point_t * points, size_t size, lv_color_t color) -{ +{ uint8_t i; for(i=0; i < (size - 1); i++) { @@ -593,7 +539,7 @@ void lv_canvas_fill_polygon(lv_obj_t * canvas, lv_point_t * points, size_t size, * @param x x coordinate of the start position (seed) * @param y y coordinate of the start position (seed) * @param boundary_color edge/boundary color of the area - * @param fill_color fill color of the area + * @param fill_color fill color of the area */ void lv_canvas_boundary_fill4(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t boundary_color, lv_color_t fill_color) { @@ -671,61 +617,4 @@ static lv_res_t lv_canvas_signal(lv_obj_t * canvas, lv_signal_t sign, void * par return res; } -/** - * Set a pixel of the canvas. Doesn't check for errors and doesn't invalidate the canvas - * @param canvas pointer to canvas object - * @param x x coordinate of the point to set - * @param y x coordinate of the point to set - * @param c color of the point - */ -static void set_px_core(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t c) -{ - lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas); - - uint8_t * buf_u8 = (uint8_t *) ext->dsc.data; - - if(ext->dsc.header.cf == LV_IMG_CF_TRUE_COLOR || - ext->dsc.header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) - { - uint32_t px = ext->dsc.header.w * y * sizeof(lv_color_t) + x * sizeof(lv_color_t); - - memcpy(&buf_u8[px], &c, sizeof(lv_color_t)); - } - else if(ext->dsc.header.cf == LV_IMG_CF_INDEXED_1BIT) { - buf_u8 += 4 * 2; - uint8_t bit = x & 0x7; - x = x >> 3; - - uint32_t px = (ext->dsc.header.w >> 3) * y + x; - buf_u8[px] = buf_u8[px] & ~(1 << (7 - bit)); - buf_u8[px] = buf_u8[px] | ((c.full & 0x1) << (7 - bit)); - } - else if(ext->dsc.header.cf == LV_IMG_CF_INDEXED_2BIT) { - buf_u8 += 4 * 4; - uint8_t bit = (x & 0x3) * 2; - x = x >> 2; - - uint32_t px = (ext->dsc.header.w >> 2) * y + x; - - buf_u8[px] = buf_u8[px] & ~(3 << (6 - bit)); - buf_u8[px] = buf_u8[px] | ((c.full & 0x3) << (6 - bit)); - } - else if(ext->dsc.header.cf == LV_IMG_CF_INDEXED_4BIT) { - buf_u8 += 4 * 16; - uint8_t bit = (x & 0x1) * 4; - x = x >> 1; - - uint32_t px = (ext->dsc.header.w >> 1) * y + x; - - buf_u8[px] = buf_u8[px] & ~(0xF << (4 - bit)); - buf_u8[px] = buf_u8[px] | ((c.full & 0xF) << (4 - bit)); - } - else if(ext->dsc.header.cf == LV_IMG_CF_INDEXED_8BIT) { - buf_u8 += 4 * 256; - uint32_t px = ext->dsc.header.w * y + x; - buf_u8[px] = c.full; - } -} - - #endif From 770d1e08e1e5a94db4749da1b80b5cfe4e4153ac Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 24 Mar 2019 18:42:11 +0100 Subject: [PATCH 28/30] lv_ddlist: fix wrong selection on click --- src/lv_objx/lv_ddlist.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lv_objx/lv_ddlist.c b/src/lv_objx/lv_ddlist.c index 23c43dc62..cad91adf1 100644 --- a/src/lv_objx/lv_ddlist.c +++ b/src/lv_objx/lv_ddlist.c @@ -788,6 +788,7 @@ static lv_res_t release_handler(lv_obj_t * ddlist) lv_point_t p; lv_indev_get_point(indev, &p); p.y -= ext->label->coords.y1; + p.x -= ext->label->coords.x1; uint16_t letter_i; letter_i = lv_label_get_letter_on(ext->label, &p); From 8890589dc18d4a53d9e23d4c6f9d5de5a3d1e6f7 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 24 Mar 2019 19:34:52 +0100 Subject: [PATCH 29/30] remove debug printf --- src/lv_objx/lv_ddlist.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lv_objx/lv_ddlist.c b/src/lv_objx/lv_ddlist.c index cad91adf1..e2803f445 100644 --- a/src/lv_objx/lv_ddlist.c +++ b/src/lv_objx/lv_ddlist.c @@ -803,7 +803,6 @@ static lv_res_t release_handler(lv_obj_t * ddlist) } ext->sel_opt_id = new_opt; - printf("rid: %d\n", new_opt); } ext->sel_opt_id_ori = ext->sel_opt_id; From aaad794085eec36edaf8152645c604f61f8a324d Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 24 Mar 2019 19:35:10 +0100 Subject: [PATCH 30/30] lv_canvas_rotate: update API --- src/lv_objx/lv_canvas.c | 35 +++++++++++++++++------------------ src/lv_objx/lv_canvas.h | 27 +++++++++++++-------------- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/lv_objx/lv_canvas.c b/src/lv_objx/lv_canvas.c index 065badc63..d27e5331e 100644 --- a/src/lv_objx/lv_canvas.c +++ b/src/lv_objx/lv_canvas.c @@ -284,10 +284,10 @@ void lv_canvas_mult_buf(lv_obj_t * canvas, void * to_copy, lv_coord_t w, lv_coor } /** - * Rotate the content of canvas (source) and copy the result to an other canvas (destination) - * @param canvas_dest destination canvas. - * @param canvas_src source canvas. - * To rotate an image (lv_img_dsc_t) this canvas be constructed by using the image descriptor directly + * Rotate and image and store the result on a canvas. + * @param canvas pointer to a canvas object + * @param img pointer to an image descriptor. + * Can be the image descriptor of an other canvas too (`lv_canvas_get_img()`). * @param angle the angle of rotation (0..360); * @param offset_x offset X to tell where to put the result data on destination canvas * @param offset_y offset X to tell where to put the result data on destination canvas @@ -296,16 +296,15 @@ void lv_canvas_mult_buf(lv_obj_t * canvas, void * to_copy, lv_coord_t w, lv_coor * @param pivot_y pivot Y of rotation. Relative to the source canvas * Set to `source height / 2` to rotate around the center */ -void lv_canvas_rotate(lv_obj_t * canvas_dest, lv_obj_t * canvas_src, int16_t angle,lv_coord_t offset_x, lv_coord_t offset_y, int32_t pivot_x, int32_t pivot_y) +void lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle,lv_coord_t offset_x, lv_coord_t offset_y, int32_t pivot_x, int32_t pivot_y) { - lv_canvas_ext_t * ext_src = lv_obj_get_ext_attr(canvas_src); - lv_canvas_ext_t * ext_dst = lv_obj_get_ext_attr(canvas_dest); + lv_canvas_ext_t * ext_dst = lv_obj_get_ext_attr(canvas); int32_t sinma = lv_trigo_sin(-angle); int32_t cosma = lv_trigo_sin(-angle + 90); /* cos */ - int32_t src_width = ext_src->dsc.header.w; - int32_t src_height = ext_src->dsc.header.h; + int32_t img_width = img->header.w; + int32_t img_height = img->header.h; int32_t dest_width = ext_dst->dsc.header.w; int32_t dest_height = ext_dst->dsc.header.h; @@ -326,11 +325,11 @@ void lv_canvas_rotate(lv_obj_t * canvas_dest, lv_obj_t * canvas_src, int16_t ang int ys_int = ys >> 8; - if(xs_int >= src_width) continue; + if(xs_int >= img_width) continue; else if(xs_int < 0) continue; - if(ys_int >= src_height) continue; + if(ys_int >= img_height) continue; else if(ys_int < 0) continue; /*Get the fractional part of the source pixel*/ @@ -357,7 +356,7 @@ void lv_canvas_rotate(lv_obj_t * canvas_dest, lv_obj_t * canvas_src, int16_t ang } /*Handle under/overflow*/ - if(xn >= src_width) continue; + if(xn >= img_width) continue; else if(xn < 0) continue; int yn; /*y neightboor*/ @@ -376,17 +375,17 @@ void lv_canvas_rotate(lv_obj_t * canvas_dest, lv_obj_t * canvas_src, int16_t ang } /*Handle under/overflow*/ - if(yn >= src_height) continue; + if(yn >= img_height) continue; else if(yn < 0) continue; /*Get the mixture of the original source and the neightboor pixels in both directions*/ - lv_color_t c_dest_int = lv_canvas_get_px(canvas_src, xs_int, ys_int); - lv_color_t c_dest_xn = lv_canvas_get_px(canvas_src, xn, ys_int); - lv_color_t c_dest_yn = lv_canvas_get_px(canvas_src, xs_int, yn); + lv_color_t c_dest_int = lv_img_buf_get_px(img, xs_int, ys_int); + lv_color_t c_dest_xn = lv_img_buf_get_px(img, xn, ys_int); + lv_color_t c_dest_yn = lv_img_buf_get_px(img, xs_int, yn); lv_color_t x_dest = lv_color_mix(c_dest_int, c_dest_xn, xr); lv_color_t y_dest = lv_color_mix(c_dest_int, c_dest_yn, yr); - // if (x + offset_x >= 0 && x + offset_x < dest_width && y + offset_y >= 0 && y + offset_y < dest_height) + if (x + offset_x >= 0 && x + offset_x < dest_width && y + offset_y >= 0 && y + offset_y < dest_height) { /*The result color as the average of the x/y mixed colors*/ lv_img_buf_set_px(&ext_dst->dsc, x + offset_x, y + offset_y, lv_color_mix(x_dest, y_dest, LV_OPA_50)); @@ -394,7 +393,7 @@ void lv_canvas_rotate(lv_obj_t * canvas_dest, lv_obj_t * canvas_src, int16_t ang } } - lv_obj_invalidate(canvas_dest); + lv_obj_invalidate(canvas); } diff --git a/src/lv_objx/lv_canvas.h b/src/lv_objx/lv_canvas.h index 19d130660..d01d7cbc8 100644 --- a/src/lv_objx/lv_canvas.h +++ b/src/lv_objx/lv_canvas.h @@ -107,6 +107,13 @@ void lv_canvas_set_style(lv_obj_t * canvas, lv_canvas_style_t type, lv_style_t * */ lv_color_t lv_canvas_get_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y); +/** + * Get the image of the canvas as a pointer to an `lv_img_dsc_t` variable. + * @param canvas pointer to a canvas object + * @return pointer to the image descriptor. + */ +lv_img_dsc_t * lv_canvas_get_img(lv_obj_t * canvas); + /** * Get style of a canvas. * @param canvas pointer to canvas object @@ -131,27 +138,19 @@ lv_style_t * lv_canvas_get_style(const lv_obj_t * canvas, lv_canvas_style_t type void lv_canvas_copy_buf(lv_obj_t * canvas, const void * to_copy, lv_coord_t w, lv_coord_t h, lv_coord_t x, lv_coord_t y); /** - * Multiply a buffer with the canvas + * Rotate and image and store the result on a canvas. * @param canvas pointer to a canvas object - * @param to_copy buffer to copy (multiply). LV_IMG_CF_TRUE_COLOR_ALPHA is not supported - * @param w width of the buffer to copy - * @param h height of the buffer to copy - * @param x left side of the destination position - * @param y top side of the destination position - */ -void lv_canvas_mult_buf(lv_obj_t * canvas, void * to_copy, lv_coord_t w, lv_coord_t h, lv_coord_t x, lv_coord_t y); -/** - * Rotate the content of canvas (source) and copy the result to an other canvas (destination) - * @param canvas_dest destination canvas. - * @param canvas_src source canvas. - * To rotate an image (lv_img_dsc_t) this canvas be constructed by using the image descriptor directly + * @param img pointer to an image descriptor. + * Can be the image descriptor of an other canvas too (`lv_canvas_get_img()`). * @param angle the angle of rotation (0..360); * @param offset_x offset X to tell where to put the result data on destination canvas * @param offset_y offset X to tell where to put the result data on destination canvas * @param pivot_x pivot X of rotation. Relative to the source canvas + * Set to `source width / 2` to rotate around the center * @param pivot_y pivot Y of rotation. Relative to the source canvas + * Set to `source height / 2` to rotate around the center */ -void lv_canvas_rotate(lv_obj_t * canvas_dest, lv_obj_t * canvas_src, int16_t angle,lv_coord_t offset_x, lv_coord_t offset_y, int32_t pivot_x, int32_t pivot_y); +void lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle,lv_coord_t offset_x, lv_coord_t offset_y, int32_t pivot_x, int32_t pivot_y); /** * Draw circle function of the canvas