diff --git a/src/others/xml/lv_xml.c b/src/others/xml/lv_xml.c index feec65c47a..3cf32ee681 100644 --- a/src/others/xml/lv_xml.c +++ b/src/others/xml/lv_xml.c @@ -31,6 +31,7 @@ #include "parsers/lv_xml_dropdown_parser.h" #include "parsers/lv_xml_roller_parser.h" #include "parsers/lv_xml_scale_parser.h" +#include "parsers/lv_xml_buttonmatrix_parser.h" #include "parsers/lv_xml_spangroup_parser.h" #include "parsers/lv_xml_event_parser.h" #include "../../libs/expat/expat.h" @@ -99,6 +100,7 @@ void lv_xml_init(void) lv_xml_widget_register("lv_scale-section", lv_xml_scale_section_create, lv_xml_scale_section_apply); lv_xml_widget_register("lv_spangroup", lv_xml_spangroup_create, lv_xml_spangroup_apply); lv_xml_widget_register("lv_spangroup-span", lv_xml_spangroup_span_create, lv_xml_spangroup_span_apply); + lv_xml_widget_register("lv_buttonmatrix", lv_xml_buttonmatrix_create, lv_xml_buttonmatrix_apply); lv_xml_widget_register("lv_event-call_function", lv_xml_event_call_function_create, lv_xml_event_call_function_apply); } diff --git a/src/others/xml/parsers/lv_xml_buttonmatrix_parser.c b/src/others/xml/parsers/lv_xml_buttonmatrix_parser.c new file mode 100644 index 0000000000..ee6f2c1686 --- /dev/null +++ b/src/others/xml/parsers/lv_xml_buttonmatrix_parser.c @@ -0,0 +1,170 @@ +/** + * @file lv_xml_buttonmatrix_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_buttonmatrix_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_buttonmatrix_ctrl_t ctrl_text_to_enum_value(const char * txt); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_buttonmatrix_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + void * item = lv_buttonmatrix_create(lv_xml_state_get_parent(state)); + return item; +} + +void lv_xml_buttonmatrix_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("map", name)) { + char * value2 = lv_strdup(value); + uint32_t str_array_size = 8; + char ** str_array = lv_malloc(sizeof(char *) * str_array_size); + char * text_start = NULL; + /*Count the `'`s (`\'`) is an escape sequence*/ + uint32_t j = 0; + uint32_t btn_cnt = 0; + bool in_text = false; + for(j = 0; value2[j]; j++) { + /*Skip the escaped `\`*/ + if(value2[j] == '\\' && value2[j + 1] == '\\') { + j++; + continue; + } + + if(value2[j] == '\'') { + /*Not escaped*/ + if(j == 0 || value2[j - 1] != '\\') { + if(!in_text) { + in_text = true; + text_start = &value2[j + 1]; + } + /*Trailing*/ + else { + value2[j] = '\0'; + if(btn_cnt >= str_array_size) { + str_array_size += 4; + str_array = lv_realloc(str_array, sizeof(char *) * str_array_size); + } + if(lv_streq("\\n", text_start)) text_start = "\n"; + str_array[btn_cnt] = lv_strdup(text_start); + btn_cnt++; + in_text = false; + } + } + } + } + + lv_free(value2); + + if(btn_cnt >= str_array_size) { + str_array_size += 4; + str_array = lv_realloc(str_array, sizeof(char *) * str_array_size); + } + str_array[btn_cnt] = NULL; + + lv_buttonmatrix_set_map(item, (const char * const *)str_array); + ((lv_buttonmatrix_t *)item)->auto_free_map = 1; + } + else if(lv_streq("ctrl_map", name)) { + char buf[512]; + lv_strlcpy(buf, value, sizeof(buf)); + char * buf_p = buf; + char * ctrls_ored = lv_xml_split_str(&buf_p, ' '); + uint32_t btn_i = 0; + while(ctrls_ored) { + lv_buttonmatrix_ctrl_t ctrl_enum = 0; + char * ctrl = ctrls_ored; + ctrl = lv_xml_split_str(&ctrls_ored, '|'); + while(ctrl) { + ctrl_enum |= ctrl_text_to_enum_value(ctrl); + ctrl = lv_xml_split_str(&ctrls_ored, '|'); + } + lv_buttonmatrix_set_button_ctrl(item, btn_i, ctrl_enum); + ctrls_ored = lv_xml_split_str(&buf_p, ' '); + btn_i++; + } + } + else if(lv_streq("selected_button", name)) lv_buttonmatrix_set_selected_button(item, lv_xml_atoi(value)); + else if(lv_streq("one_checked", name)) lv_buttonmatrix_set_one_checked(item, lv_xml_to_bool(value)); + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_buttonmatrix_ctrl_t ctrl_text_to_enum_value(const char * txt) +{ + if(lv_streq("none", txt)) return LV_BUTTONMATRIX_CTRL_NONE; + if(lv_streq("width_1", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_1; + if(lv_streq("width_2", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_2; + if(lv_streq("width_3", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_3; + if(lv_streq("width_4", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_4; + if(lv_streq("width_5", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_5; + if(lv_streq("width_6", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_6; + if(lv_streq("width_7", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_7; + if(lv_streq("width_8", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_8; + if(lv_streq("width_9", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_9; + if(lv_streq("width_10", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_10; + if(lv_streq("width_11", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_11; + if(lv_streq("width_12", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_12; + if(lv_streq("width_13", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_13; + if(lv_streq("width_14", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_14; + if(lv_streq("width_15", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_15; + if(lv_streq("hidden", txt)) return LV_BUTTONMATRIX_CTRL_HIDDEN; + if(lv_streq("no_repeat", txt)) return LV_BUTTONMATRIX_CTRL_NO_REPEAT; + if(lv_streq("disabled", txt)) return LV_BUTTONMATRIX_CTRL_DISABLED; + if(lv_streq("checkable", txt)) return LV_BUTTONMATRIX_CTRL_CHECKABLE; + if(lv_streq("checked", txt)) return LV_BUTTONMATRIX_CTRL_CHECKED; + if(lv_streq("click_trig", txt)) return LV_BUTTONMATRIX_CTRL_CLICK_TRIG; + if(lv_streq("popover", txt)) return LV_BUTTONMATRIX_CTRL_POPOVER; + if(lv_streq("reserved_1", txt)) return LV_BUTTONMATRIX_CTRL_RESERVED_1; + if(lv_streq("reserved_2", txt)) return LV_BUTTONMATRIX_CTRL_RESERVED_2; + if(lv_streq("custom_1", txt)) return LV_BUTTONMATRIX_CTRL_CUSTOM_1; + if(lv_streq("custom_2", txt)) return LV_BUTTONMATRIX_CTRL_CUSTOM_2; + + LV_LOG_WARN("%s is an unknown value for buttonmatrix's map_ctrl", txt); + return 0; /*Return 0 in lack of a better option. */ +} + + +#endif /* LV_USE_XML */ diff --git a/src/others/xml/parsers/lv_xml_buttonmatrix_parser.h b/src/others/xml/parsers/lv_xml_buttonmatrix_parser.h new file mode 100644 index 0000000000..df814a9063 --- /dev/null +++ b/src/others/xml/parsers/lv_xml_buttonmatrix_parser.h @@ -0,0 +1,41 @@ +/** + * @file lv_xml_buttonmatrix_parser.h + * + */ + +#ifndef LV_BUTTONMATRIX_XML_PARSER_H +#define LV_BUTTONMATRIX_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_buttonmatrix_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_buttonmatrix_apply(lv_xml_parser_state_t * state, const char ** attrs); + + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BUTTONMATRIX_XML_PARSE_H*/ diff --git a/src/widgets/buttonmatrix/lv_buttonmatrix.c b/src/widgets/buttonmatrix/lv_buttonmatrix.c index de1bebf58b..1c9427f5e9 100644 --- a/src/widgets/buttonmatrix/lv_buttonmatrix.c +++ b/src/widgets/buttonmatrix/lv_buttonmatrix.c @@ -56,6 +56,8 @@ static void invalidate_button_area(const lv_obj_t * obj, uint32_t btn_idx); static void make_one_button_checked(lv_obj_t * obj, uint32_t btn_idx); static bool has_popovers_in_top_row(lv_obj_t * obj); static bool button_is_recolor(lv_buttonmatrix_ctrl_t ctrl_bits); +static void update_map(lv_obj_t * obj); +static void free_map(lv_buttonmatrix_t * btnm); /********************** * STATIC VARIABLES @@ -103,89 +105,14 @@ void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * const map[]) if(map == NULL) return; lv_buttonmatrix_t * btnm = (lv_buttonmatrix_t *)obj; + if(btnm->auto_free_map) free_map(btnm); + btnm->auto_free_map = 0; /*Analyze the map and create the required number of buttons*/ allocate_button_areas_and_controls(obj, map); btnm->map_p = map; - lv_base_dir_t base_dir = lv_obj_get_style_base_dir(obj, LV_PART_MAIN); - - /*Set size and positions of the buttons*/ - int32_t sleft = lv_obj_get_style_space_left(obj, LV_PART_MAIN); - int32_t stop = lv_obj_get_style_space_top(obj, LV_PART_MAIN); - int32_t prow = lv_obj_get_style_pad_row(obj, LV_PART_MAIN); - int32_t pcol = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); - - int32_t max_w = lv_obj_get_content_width(obj); - int32_t max_h = lv_obj_get_content_height(obj); - - /*Calculate the position of each row*/ - int32_t max_h_no_gap = max_h - (prow * (btnm->row_cnt - 1)); - - /*Count the units and the buttons in a line - *(A button can be 1,2,3... unit wide)*/ - uint32_t txt_tot_i = 0; /*Act. index in the str map*/ - uint32_t btn_tot_i = 0; /*Act. index of button areas*/ - const char * const * map_row = map; - - /*Count the units and the buttons in a line*/ - uint32_t row; - for(row = 0; row < btnm->row_cnt; row++) { - uint32_t unit_cnt = 0; /*Number of units in a row*/ - uint32_t btn_cnt = 0; /*Number of buttons in a row*/ - /*Count the buttons and units in this row*/ - while(map_row[btn_cnt] && lv_strcmp(map_row[btn_cnt], "\n") != 0 && map_row[btn_cnt][0] != '\0') { - unit_cnt += get_button_width(btnm->ctrl_bits[btn_tot_i + btn_cnt]); - btn_cnt++; - } - - /*Only deal with the non empty lines*/ - if(btn_cnt == 0) { - map_row = &map_row[btn_cnt + 1]; /*Set the map to the next row*/ - continue; - } - - int32_t row_y1 = stop + (max_h_no_gap * row) / btnm->row_cnt + row * prow; - int32_t row_y2 = stop + (max_h_no_gap * (row + 1)) / btnm->row_cnt + row * prow - 1; - - /*Set the button size and positions*/ - int32_t max_w_no_gap = max_w - (pcol * (btn_cnt - 1)); - if(max_w_no_gap < 0) max_w_no_gap = 0; - - uint32_t row_unit_cnt = 0; /*The current unit position in the row*/ - uint32_t btn; - for(btn = 0; btn < btn_cnt; btn++, btn_tot_i++, txt_tot_i++) { - uint32_t btn_u = get_button_width(btnm->ctrl_bits[btn_tot_i]); - - int32_t btn_x1 = (max_w_no_gap * row_unit_cnt) / unit_cnt + btn * pcol; - int32_t btn_x2 = (max_w_no_gap * (row_unit_cnt + btn_u)) / unit_cnt + btn * pcol - 1; - - /*If RTL start from the right*/ - if(base_dir == LV_BASE_DIR_RTL) { - int32_t tmp = btn_x1; - btn_x1 = btn_x2; - btn_x2 = tmp; - - btn_x1 = max_w - btn_x1; - btn_x2 = max_w - btn_x2; - } - - btn_x1 += sleft; - btn_x2 += sleft; - - lv_area_set(&btnm->button_areas[btn_tot_i], btn_x1, row_y1, btn_x2, row_y2); - - row_unit_cnt += btn_u; - } - - map_row = &map_row[btn_cnt + 1]; /*Set the map to the next line*/ - } - - /*Popovers in the top row will draw outside the widget and the extended draw size depends on - *the row height which may have changed when setting the new map*/ - lv_obj_refresh_ext_draw_size(obj); - - lv_obj_invalidate(obj); + update_map(obj); } void lv_buttonmatrix_set_ctrl_map(lv_obj_t * obj, const lv_buttonmatrix_ctrl_t ctrl_map[]) @@ -195,7 +122,7 @@ void lv_buttonmatrix_set_ctrl_map(lv_obj_t * obj, const lv_buttonmatrix_ctrl_t c lv_buttonmatrix_t * btnm = (lv_buttonmatrix_t *)obj; lv_memcpy(btnm->ctrl_bits, ctrl_map, sizeof(lv_buttonmatrix_ctrl_t) * btnm->btn_cnt); - lv_buttonmatrix_set_map(obj, btnm->map_p); + update_map(obj); } void lv_buttonmatrix_set_selected_button(lv_obj_t * obj, uint32_t btn_id) @@ -278,7 +205,7 @@ void lv_buttonmatrix_set_button_width(lv_obj_t * obj, uint32_t btn_id, uint32_t btnm->ctrl_bits[btn_id] &= (~LV_BUTTONMATRIX_WIDTH_MASK); btnm->ctrl_bits[btn_id] |= (LV_BUTTONMATRIX_WIDTH_MASK & width); - lv_buttonmatrix_set_map(obj, btnm->map_p); + update_map(obj); } void lv_buttonmatrix_set_one_checked(lv_obj_t * obj, bool en) @@ -415,10 +342,10 @@ static void lv_buttonmatrix_event(const lv_obj_class_t * class_p, lv_event_t * e } } if(code == LV_EVENT_STYLE_CHANGED) { - lv_buttonmatrix_set_map(obj, btnm->map_p); + update_map(obj); } else if(code == LV_EVENT_SIZE_CHANGED) { - lv_buttonmatrix_set_map(obj, btnm->map_p); + update_map(obj); } else if(code == LV_EVENT_PRESSED) { lv_indev_t * indev = lv_event_get_indev(e); @@ -663,6 +590,9 @@ static void lv_buttonmatrix_event(const lv_obj_class_t * class_p, lv_event_t * e else if(code == LV_EVENT_DRAW_MAIN) { draw_main(e); } + else if(code == LV_EVENT_DELETE) { + if(btnm->auto_free_map) free_map(btnm); + } } @@ -1059,4 +989,99 @@ static bool button_is_recolor(lv_buttonmatrix_ctrl_t ctrl_bits) return (ctrl_bits & LV_BUTTONMATRIX_CTRL_RECOLOR) ? true : false; } +static void update_map(lv_obj_t * obj) +{ + lv_buttonmatrix_t * btnm = (lv_buttonmatrix_t *)obj; + + lv_base_dir_t base_dir = lv_obj_get_style_base_dir(obj, LV_PART_MAIN); + + /*Set size and positions of the buttons*/ + int32_t sleft = lv_obj_get_style_space_left(obj, LV_PART_MAIN); + int32_t stop = lv_obj_get_style_space_top(obj, LV_PART_MAIN); + int32_t prow = lv_obj_get_style_pad_row(obj, LV_PART_MAIN); + int32_t pcol = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); + + int32_t max_w = lv_obj_get_content_width(obj); + int32_t max_h = lv_obj_get_content_height(obj); + + /*Calculate the position of each row*/ + int32_t max_h_no_gap = max_h - (prow * (btnm->row_cnt - 1)); + + /*Count the units and the buttons in a line + *(A button can be 1,2,3... unit wide)*/ + uint32_t txt_tot_i = 0; /*Act. index in the str map*/ + uint32_t btn_tot_i = 0; /*Act. index of button areas*/ + const char * const * map_row = btnm->map_p; + + /*Count the units and the buttons in a line*/ + uint32_t row; + for(row = 0; row < btnm->row_cnt; row++) { + uint32_t unit_cnt = 0; /*Number of units in a row*/ + uint32_t btn_cnt = 0; /*Number of buttons in a row*/ + /*Count the buttons and units in this row*/ + while(map_row[btn_cnt] && lv_strcmp(map_row[btn_cnt], "\n") != 0 && map_row[btn_cnt][0] != '\0') { + unit_cnt += get_button_width(btnm->ctrl_bits[btn_tot_i + btn_cnt]); + btn_cnt++; + } + + /*Only deal with the non empty lines*/ + if(btn_cnt == 0) { + map_row = &map_row[btn_cnt + 1]; /*Set the map to the next row*/ + continue; + } + + int32_t row_y1 = stop + (max_h_no_gap * row) / btnm->row_cnt + row * prow; + int32_t row_y2 = stop + (max_h_no_gap * (row + 1)) / btnm->row_cnt + row * prow - 1; + + /*Set the button size and positions*/ + int32_t max_w_no_gap = max_w - (pcol * (btn_cnt - 1)); + if(max_w_no_gap < 0) max_w_no_gap = 0; + + uint32_t row_unit_cnt = 0; /*The current unit position in the row*/ + uint32_t btn; + for(btn = 0; btn < btn_cnt; btn++, btn_tot_i++, txt_tot_i++) { + uint32_t btn_u = get_button_width(btnm->ctrl_bits[btn_tot_i]); + + int32_t btn_x1 = (max_w_no_gap * row_unit_cnt) / unit_cnt + btn * pcol; + int32_t btn_x2 = (max_w_no_gap * (row_unit_cnt + btn_u)) / unit_cnt + btn * pcol - 1; + + /*If RTL start from the right*/ + if(base_dir == LV_BASE_DIR_RTL) { + int32_t tmp = btn_x1; + btn_x1 = btn_x2; + btn_x2 = tmp; + + btn_x1 = max_w - btn_x1; + btn_x2 = max_w - btn_x2; + } + + btn_x1 += sleft; + btn_x2 += sleft; + + lv_area_set(&btnm->button_areas[btn_tot_i], btn_x1, row_y1, btn_x2, row_y2); + + row_unit_cnt += btn_u; + } + + map_row = &map_row[btn_cnt + 1]; /*Set the map to the next line*/ + } + + /*Popovers in the top row will draw outside the widget and the extended draw size depends on + *the row height which may have changed when setting the new map*/ + lv_obj_refresh_ext_draw_size(obj); + + lv_obj_invalidate(obj); + +} + +static void free_map(lv_buttonmatrix_t * btnm) +{ + uint32_t i; + for(i = 0; btnm->map_p[i]; i++) { + lv_free((void *)btnm->map_p[i]); + } + lv_free((void *)btnm->map_p); + btnm->map_p = NULL; +} + #endif diff --git a/src/widgets/buttonmatrix/lv_buttonmatrix.h b/src/widgets/buttonmatrix/lv_buttonmatrix.h index 3145104463..fc2550e1fe 100644 --- a/src/widgets/buttonmatrix/lv_buttonmatrix.h +++ b/src/widgets/buttonmatrix/lv_buttonmatrix.h @@ -32,6 +32,22 @@ LV_EXPORT_CONST_INT(LV_BUTTONMATRIX_BUTTON_NONE); /** Type to store button control flags (disabled, hidden etc.) * The least-significant 4 bits are used to store button-width proportions in range [1..15]. */ typedef enum { + LV_BUTTONMATRIX_CTRL_NONE = 0x0000, /**< No extra control, use the default settings*/ + LV_BUTTONMATRIX_CTRL_WIDTH_1 = 0x0001, /**< Set the width to 1 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_2 = 0x0002, /**< Set the width to 2 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_3 = 0x0003, /**< Set the width to 3 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_4 = 0x0004, /**< Set the width to 4 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_5 = 0x0005, /**< Set the width to 5 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_6 = 0x0006, /**< Set the width to 6 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_7 = 0x0007, /**< Set the width to 7 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_8 = 0x0008, /**< Set the width to 8 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_9 = 0x0009, /**< Set the width to 9 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_10 = 0x000A, /**< Set the width to 10 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_11 = 0x000B, /**< Set the width to 11 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_12 = 0x000C, /**< Set the width to 12 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_13 = 0x000D, /**< Set the width to 13 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_14 = 0x000E, /**< Set the width to 14 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_15 = 0x000F, /**< Set the width to 15 relative to the other buttons in the same row */ LV_BUTTONMATRIX_CTRL_HIDDEN = 0x0010, /**< Hides button; it continues to hold its space in layout. */ LV_BUTTONMATRIX_CTRL_NO_REPEAT = 0x0020, /**< Do not emit LV_EVENT_LONG_PRESSED_REPEAT events while button is long-pressed. */ LV_BUTTONMATRIX_CTRL_DISABLED = 0x0040, /**< Disables button like LV_STATE_DISABLED on normal Widgets. */ @@ -40,8 +56,8 @@ typedef enum { LV_BUTTONMATRIX_CTRL_CLICK_TRIG = 0x0200, /**< 1: Enables sending LV_EVENT_VALUE_CHANGE on CLICK, 0: sends LV_EVENT_VALUE_CHANGE on PRESS. */ LV_BUTTONMATRIX_CTRL_POPOVER = 0x0400, /**< Show button text in a pop-over while being pressed. */ LV_BUTTONMATRIX_CTRL_RECOLOR = 0x0800, /**< Enable text recoloring with `#color` */ - LV_BUTTONMATRIX_CTRL_RESERVED_2 = 0x1000, /**< Reserved for later use */ - LV_BUTTONMATRIX_CTRL_RESERVED_3 = 0x2000, /**< Reserved for later use */ + LV_BUTTONMATRIX_CTRL_RESERVED_1 = 0x1000, /**< Reserved for later use */ + LV_BUTTONMATRIX_CTRL_RESERVED_2 = 0x2000, /**< Reserved for later use */ LV_BUTTONMATRIX_CTRL_CUSTOM_1 = 0x4000, /**< Custom free-to-use flag */ LV_BUTTONMATRIX_CTRL_CUSTOM_2 = 0x8000, /**< Custom free-to-use flag */ } lv_buttonmatrix_ctrl_t; diff --git a/src/widgets/buttonmatrix/lv_buttonmatrix_private.h b/src/widgets/buttonmatrix/lv_buttonmatrix_private.h index 824bdcb0d2..3f6b0fa539 100644 --- a/src/widgets/buttonmatrix/lv_buttonmatrix_private.h +++ b/src/widgets/buttonmatrix/lv_buttonmatrix_private.h @@ -36,7 +36,8 @@ struct _lv_buttonmatrix_t { uint32_t btn_cnt; /**< Number of button in 'map_p'(Handled by the library) */ uint32_t row_cnt; /**< Number of rows in 'map_p'(Handled by the library) */ uint32_t btn_id_sel; /**< Index of the active button (being pressed/released etc) or LV_BUTTONMATRIX_BUTTON_NONE */ - uint32_t one_check : 1; /**< Single button toggled at once */ + uint32_t one_check : 1; /**< 1: Single button toggled at once */ + uint32_t auto_free_map : 1; /**< 1: Automatically free the map when the widget is deleted */ }; diff --git a/tests/ref_imgs/xml/lv_buttonmatrix.png b/tests/ref_imgs/xml/lv_buttonmatrix.png new file mode 100644 index 0000000000..8d0b77a381 Binary files /dev/null and b/tests/ref_imgs/xml/lv_buttonmatrix.png differ diff --git a/tests/ref_imgs_vg_lite/xml/lv_buttonmatrix.png b/tests/ref_imgs_vg_lite/xml/lv_buttonmatrix.png new file mode 100644 index 0000000000..5bb7043869 Binary files /dev/null and b/tests/ref_imgs_vg_lite/xml/lv_buttonmatrix.png differ diff --git a/tests/src/test_cases/xml/test_xml_buttonmatrix.c b/tests/src/test_cases/xml/test_xml_buttonmatrix.c new file mode 100644 index 0000000000..89f862b56e --- /dev/null +++ b/tests/src/test_cases/xml/test_xml_buttonmatrix.c @@ -0,0 +1,34 @@ +#if LV_BUILD_TEST +#include "../lvgl.h" + +#include "unity/unity.h" + +void setUp(void) +{ + /* Function run before every test */ +} + +void tearDown(void) +{ + /* Function run after every test */ + lv_obj_clean(lv_screen_active()); +} + +void test_xml_buttonmatrix_with_attrs(void) +{ + + const char * attrs_1[] = { + "map", "'1' '2' '3' '\n' '4\\'s value' '\n' '5' '6' '7' '8' '9' '\n' 'Escape \\ 10'", + "ctrl_map", "checked|width_3 none disabled none checkable none none none none checked", + "width", "300", + "height", "200", + NULL, NULL, + }; + + lv_xml_create(lv_screen_active(), "lv_buttonmatrix", attrs_1); + + + TEST_ASSERT_EQUAL_SCREENSHOT("xml/lv_buttonmatrix.png"); +} + +#endif diff --git a/xmls/lv_buttonmatrix.xml b/xmls/lv_buttonmatrix.xml index 94da83802b..3dce7b83d4 100644 --- a/xmls/lv_buttonmatrix.xml +++ b/xmls/lv_buttonmatrix.xml @@ -29,18 +29,18 @@ Example + - - - - - - - + + + + + + \ No newline at end of file