diff --git a/examples/others/xml/index.rst b/examples/others/xml/index.rst index 73e9e738a..a5c8cd8b8 100644 --- a/examples/others/xml/index.rst +++ b/examples/others/xml/index.rst @@ -3,3 +3,6 @@ Load components at runtime .. lv_example:: others/xml/lv_example_xml_1 :language: c + +.. lv_example:: others/xml/lv_example_xml_2 + :language: c diff --git a/examples/others/xml/lv_example_xml.h b/examples/others/xml/lv_example_xml.h index 341144881..a37cd2159 100644 --- a/examples/others/xml/lv_example_xml.h +++ b/examples/others/xml/lv_example_xml.h @@ -26,6 +26,7 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ void lv_example_xml_1(void); +void lv_example_xml_2(void); /********************** * MACROS diff --git a/examples/others/xml/lv_example_xml_1.c b/examples/others/xml/lv_example_xml_1.c index 6b1dcd894..d0e78fc44 100644 --- a/examples/others/xml/lv_example_xml_1.c +++ b/examples/others/xml/lv_example_xml_1.c @@ -3,35 +3,61 @@ void lv_example_xml_1(void) { - lv_xml_component_register_from_file("A:lvgl/examples/others/xml/my_h3.xml"); - lv_xml_component_register_from_file("A:lvgl/examples/others/xml/my_card.xml"); - lv_xml_component_register_from_file("A:lvgl/examples/others/xml/my_button.xml"); - lv_xml_component_register_from_file("A:lvgl/examples/others/xml/view.xml"); + /*A red button created from builti-in LVGL widgets + *It has an API parameter too to change its text.*/ + const char * red_button_xml = + "" + " " + " " + " " + " " + " " + " " + ""; - lv_obj_t * obj = lv_xml_create(lv_screen_active(), "view", NULL); - lv_obj_set_pos(obj, 10, 10); + /*The card is just an lv_obj where a label and two red buttons are used. + * Its API allow setting a title (label test) and the action (the text of a button)*/ + const char * card_xml = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; - const char * my_button_attrs[] = { - "x", "10", - "y", "-10", - "align", "bottom_left", - "btn_text", "New button", + /* Motor card is a special case of a card where the title and action are already set*/ + const char * motor_card_xml = + "" + " " + " " + ""; + + /*Register all the custom components*/ + lv_xml_component_register_from_data("red_button", red_button_xml); + lv_xml_component_register_from_data("card", card_xml); + lv_xml_component_register_from_data("motor_card", motor_card_xml); + + lv_obj_t * card; + /*Create a card with the default values*/ + card = lv_xml_create(lv_screen_active(), "card", NULL); + + /*Create a motor card too. The returned value can be adjusted freely*/ + card = lv_xml_create(lv_screen_active(), "motor_card", NULL); + lv_obj_set_y(card, 90); + + /*Pass properties to a card*/ + const char * attrs[] = { + "y", "180", + "action", "Apply", + "title", "New title", NULL, NULL, }; + card = lv_xml_create(lv_screen_active(), "card", attrs); - lv_xml_component_unregister("my_button"); - - lv_xml_create(lv_screen_active(), "my_button", my_button_attrs); - - const char * slider_attrs[] = { - "x", "200", - "y", "-15", - "align", "bottom_left", - "value", "30", - NULL, NULL, - }; - - lv_obj_t * slider = lv_xml_create(lv_screen_active(), "lv_slider", slider_attrs); - lv_obj_set_width(slider, 100); } #endif diff --git a/examples/others/xml/lv_example_xml_2.c b/examples/others/xml/lv_example_xml_2.c new file mode 100644 index 000000000..d3e702010 --- /dev/null +++ b/examples/others/xml/lv_example_xml_2.c @@ -0,0 +1,43 @@ +#include "../../lv_examples.h" +#if LV_BUILD_EXAMPLES && LV_USE_XML + +void lv_example_xml_2(void) +{ + lv_result_t res; + res = lv_xml_component_register_from_file("A:lvgl/examples/others/xml/my_h3.xml"); + if(res != LV_RESULT_OK) { + lv_obj_t * label = lv_label_create(lv_screen_active()); + lv_label_set_text(label, "Couldn't open the XML files."); + lv_obj_center(label); + } + lv_xml_component_register_from_file("A:lvgl/examples/others/xml/my_card.xml"); + lv_xml_component_register_from_file("A:lvgl/examples/others/xml/my_button.xml"); + lv_xml_component_register_from_file("A:lvgl/examples/others/xml/view.xml"); + + lv_obj_t * obj = lv_xml_create(lv_screen_active(), "view", NULL); + lv_obj_set_pos(obj, 10, 10); + + const char * my_button_attrs[] = { + "x", "10", + "y", "-10", + "align", "bottom_left", + "btn_text", "New button", + NULL, NULL, + }; + + lv_xml_component_unregister("my_button"); + + lv_xml_create(lv_screen_active(), "my_button", my_button_attrs); + + const char * slider_attrs[] = { + "x", "200", + "y", "-15", + "align", "bottom_left", + "value", "30", + NULL, NULL, + }; + + lv_obj_t * slider = lv_xml_create(lv_screen_active(), "lv_slider", slider_attrs); + lv_obj_set_width(slider, 100); +} +#endif diff --git a/src/misc/lv_style.h b/src/misc/lv_style.h index 60ae0f163..89409a041 100644 --- a/src/misc/lv_style.h +++ b/src/misc/lv_style.h @@ -587,6 +587,18 @@ static inline void lv_style_set_pad_gap(lv_style_t * style, int32_t value) lv_style_set_pad_column(style, value); } +static inline void lv_style_set_margin_hor(lv_style_t * style, int32_t value) +{ + lv_style_set_margin_left(style, value); + lv_style_set_margin_right(style, value); +} + +static inline void lv_style_set_margin_ver(lv_style_t * style, int32_t value) +{ + lv_style_set_margin_top(style, value); + lv_style_set_margin_bottom(style, value); +} + static inline void lv_style_set_margin_all(lv_style_t * style, int32_t value) { lv_style_set_margin_left(style, value); diff --git a/src/others/xml/lv_xml.c b/src/others/xml/lv_xml.c index d937c548a..1fcc70c1c 100644 --- a/src/others/xml/lv_xml.c +++ b/src/others/xml/lv_xml.c @@ -26,6 +26,8 @@ #include "parsers/lv_xml_slider_parser.h" #include "parsers/lv_xml_tabview_parser.h" #include "parsers/lv_xml_chart_parser.h" +#include "parsers/lv_xml_table_parser.h" +#include "parsers/lv_xml_dropdown_parser.h" #include "../../libs/expat/expat.h" #include "../../draw/lv_draw_image.h" @@ -42,6 +44,7 @@ **********************/ static void view_start_element_handler(void * user_data, const char * name, const char ** attrs); static void view_end_element_handler(void * user_data, const char * name); +static void register_builtin_fonts(void); /********************** * STATIC VARIABLES @@ -62,24 +65,10 @@ void lv_xml_init(void) lv_ll_init(&font_ll, sizeof(lv_xml_font_t)); lv_ll_init(&image_ll, sizeof(lv_xml_image_t)); -#if LV_FONT_MONTSERRAT_14 - lv_xml_register_font("lv_montserrat_14", &lv_font_montserrat_14); -#endif - -#if LV_FONT_MONTSERRAT_16 - lv_xml_register_font("lv_montserrat_16", &lv_font_montserrat_16); -#endif - -#if LV_FONT_MONTSERRAT_18 - lv_xml_register_font("lv_montserrat_18", &lv_font_montserrat_18); -#endif - -#if LV_FONT_MONTSERRAT_20 - lv_xml_register_font("lv_montserrat_20", &lv_font_montserrat_20); -#endif - lv_xml_component_init(); + register_builtin_fonts(); + lv_xml_widget_register("lv_obj", lv_xml_obj_create, lv_xml_obj_apply); lv_xml_widget_register("lv_button", lv_xml_button_create, lv_xml_button_apply); lv_xml_widget_register("lv_label", lv_xml_label_create, lv_xml_label_apply); @@ -91,10 +80,16 @@ void lv_xml_init(void) lv_xml_widget_register("lv_chart", lv_xml_chart_create, lv_xml_chart_apply); lv_xml_widget_register("lv_chart-cursor", lv_xml_chart_cursor_create, lv_xml_chart_cursor_apply); lv_xml_widget_register("lv_chart-series", lv_xml_chart_series_create, lv_xml_chart_series_apply); + lv_xml_widget_register("lv_chart-axis", lv_xml_chart_axis_create, lv_xml_chart_axis_apply); + lv_xml_widget_register("lv_table", lv_xml_table_create, lv_xml_table_apply); + lv_xml_widget_register("lv_table-column", lv_xml_table_column_create, lv_xml_table_column_apply); + lv_xml_widget_register("lv_table-cell", lv_xml_table_cell_create, lv_xml_table_cell_apply); + lv_xml_widget_register("lv_dropdown", lv_xml_dropdown_create, lv_xml_dropdown_apply); + lv_xml_widget_register("lv_dropdown-list", lv_xml_dropdown_list_create, lv_xml_dropdown_list_apply); } -lv_obj_t * lv_xml_create_from_ctx(lv_obj_t * parent, lv_xml_component_ctx_t * parent_ctx, lv_xml_component_ctx_t * ctx, - const char ** attrs) +void * lv_xml_create_from_ctx(lv_obj_t * parent, lv_xml_component_ctx_t * parent_ctx, lv_xml_component_ctx_t * ctx, + const char ** attrs) { /* Initialize the parser state */ lv_xml_parser_state_t state; @@ -132,7 +127,7 @@ lv_obj_t * lv_xml_create_from_ctx(lv_obj_t * parent, lv_xml_component_ctx_t * pa return state.view; } -lv_obj_t * lv_xml_create(lv_obj_t * parent, const char * name, const char ** attrs) +void * lv_xml_create(lv_obj_t * parent, const char * name, const char ** attrs) { lv_obj_t * item = NULL; @@ -345,7 +340,7 @@ static void view_start_element_handler(void * user_data, const char * name, cons *now it has the button theme styles. However if it were a real widget *it had e.g. `my_widget_class` so the button's theme wouldn't apply on it. *Removing the style will ensure a better preview*/ - if(state->ctx.is_widget) lv_obj_remove_style_all(item); + if(state->ctx.is_widget && is_view) lv_obj_remove_style_all(item); /*Apply the attributes from e.g. ``*/ if(item) { @@ -386,4 +381,108 @@ static void view_end_element_handler(void * user_data, const char * name) } } + +static void register_builtin_fonts(void) +{ +#if LV_FONT_MONTSERRAT_8 + lv_xml_register_font("lv_montserrat_8", &lv_font_montserrat_8); +#endif + +#if LV_FONT_MONTSERRAT_10 + lv_xml_register_font("lv_montserrat_10", &lv_font_montserrat_10); +#endif + +#if LV_FONT_MONTSERRAT_12 + lv_xml_register_font("lv_montserrat_12", &lv_font_montserrat_12); +#endif + +#if LV_FONT_MONTSERRAT_14 + lv_xml_register_font("lv_montserrat_14", &lv_font_montserrat_14); +#endif + +#if LV_FONT_MONTSERRAT_16 + lv_xml_register_font("lv_montserrat_16", &lv_font_montserrat_16); +#endif + +#if LV_FONT_MONTSERRAT_18 + lv_xml_register_font("lv_montserrat_18", &lv_font_montserrat_18); +#endif + +#if LV_FONT_MONTSERRAT_20 + lv_xml_register_font("lv_montserrat_20", &lv_font_montserrat_20); +#endif + +#if LV_FONT_MONTSERRAT_22 + lv_xml_register_font("lv_montserrat_22", &lv_font_montserrat_22); +#endif + +#if LV_FONT_MONTSERRAT_24 + lv_xml_register_font("lv_montserrat_24", &lv_font_montserrat_24); +#endif + +#if LV_FONT_MONTSERRAT_26 + lv_xml_register_font("lv_montserrat_26", &lv_font_montserrat_26); +#endif + +#if LV_FONT_MONTSERRAT_28 + lv_xml_register_font("lv_montserrat_28", &lv_font_montserrat_28); +#endif + +#if LV_FONT_MONTSERRAT_30 + lv_xml_register_font("lv_montserrat_30", &lv_font_montserrat_30); +#endif + +#if LV_FONT_MONTSERRAT_32 + lv_xml_register_font("lv_montserrat_32", &lv_font_montserrat_32); +#endif + +#if LV_FONT_MONTSERRAT_34 + lv_xml_register_font("lv_montserrat_34", &lv_font_montserrat_34); +#endif + +#if LV_FONT_MONTSERRAT_36 + lv_xml_register_font("lv_montserrat_36", &lv_font_montserrat_36); +#endif + +#if LV_FONT_MONTSERRAT_38 + lv_xml_register_font("lv_montserrat_38", &lv_font_montserrat_38); +#endif + +#if LV_FONT_MONTSERRAT_40 + lv_xml_register_font("lv_montserrat_40", &lv_font_montserrat_40); +#endif + +#if LV_FONT_MONTSERRAT_42 + lv_xml_register_font("lv_montserrat_42", &lv_font_montserrat_42); +#endif + +#if LV_FONT_MONTSERRAT_44 + lv_xml_register_font("lv_montserrat_44", &lv_font_montserrat_44); +#endif + +#if LV_FONT_MONTSERRAT_46 + lv_xml_register_font("lv_montserrat_46", &lv_font_montserrat_46); +#endif + +#if LV_FONT_MONTSERRAT_48 + lv_xml_register_font("lv_montserrat_48", &lv_font_montserrat_48); +#endif + +#if LV_FONT_UNSCII_8 + lv_xml_register_font("lv_unscii_8", &lv_font_unscii_8); +#endif + +#if LV_FONT_UNSCII_16 + lv_xml_register_font("lv_unscii_16", &lv_font_unscii_16); +#endif + +#if LV_FONT_SIMSUN_16_CJK + lv_xml_register_font("lv_simsun_cjk_16", &lv_font_simsun_16_cjk); +#endif + +#if LV_FONT_DEJAVU_16_PERSIAN_HEBREW + lv_xml_register_font("lv_font_dejavu_16_persian_hebrew", &lv_font_dejavu_16_persian_hebrew); +#endif +} + #endif /* LV_USE_XML */ diff --git a/src/others/xml/lv_xml.h b/src/others/xml/lv_xml.h index 1b5646097..1a0948d9b 100644 --- a/src/others/xml/lv_xml.h +++ b/src/others/xml/lv_xml.h @@ -30,10 +30,10 @@ extern "C" { void lv_xml_init(void); -lv_obj_t * lv_xml_create(lv_obj_t * parent, const char * name, const char ** attrs); +void * lv_xml_create(lv_obj_t * parent, const char * name, const char ** attrs); -lv_obj_t * lv_xml_create_from_ctx(lv_obj_t * parent, lv_xml_component_ctx_t * parent_ctx, lv_xml_component_ctx_t * ctx, - const char ** attrs); +void * lv_xml_create_from_ctx(lv_obj_t * parent, lv_xml_component_ctx_t * parent_ctx, lv_xml_component_ctx_t * ctx, + const char ** attrs); lv_result_t lv_xml_register_font(const char * name, const lv_font_t * font); diff --git a/src/others/xml/lv_xml_base_types.c b/src/others/xml/lv_xml_base_types.c index b1aa834af..ef9ec3aa4 100644 --- a/src/others/xml/lv_xml_base_types.c +++ b/src/others/xml/lv_xml_base_types.c @@ -48,11 +48,11 @@ int32_t lv_xml_to_size(const char * txt) else return v; } -lv_align_t lv_xml_align_string_to_enum_value(const char * txt) +lv_align_t lv_xml_align_to_enum(const char * txt) { if(lv_streq("top_left", txt)) return LV_ALIGN_TOP_LEFT; if(lv_streq("top_mid", txt)) return LV_ALIGN_TOP_MID; - if(lv_streq("top_right", txt)) return LV_ALIGN_TOP_LEFT; + if(lv_streq("top_right", txt)) return LV_ALIGN_TOP_RIGHT; if(lv_streq("bottom_left", txt)) return LV_ALIGN_BOTTOM_LEFT; if(lv_streq("bottom_mid", txt)) return LV_ALIGN_BOTTOM_MID; if(lv_streq("bottom_right", txt)) return LV_ALIGN_BOTTOM_RIGHT; @@ -64,8 +64,9 @@ lv_align_t lv_xml_align_string_to_enum_value(const char * txt) return 0; /*Return 0 in lack of a better option. */ } -lv_dir_t lv_xml_dir_string_to_enum_value(const char * txt) +lv_dir_t lv_xml_dir_to_enum(const char * txt) { + if(lv_streq("none", txt)) return LV_DIR_NONE; if(lv_streq("top", txt)) return LV_DIR_TOP; if(lv_streq("bottom", txt)) return LV_DIR_BOTTOM; if(lv_streq("left", txt)) return LV_DIR_LEFT; @@ -76,7 +77,61 @@ lv_dir_t lv_xml_dir_string_to_enum_value(const char * txt) return 0; /*Return 0 in lack of a better option. */ } -lv_flex_flow_t lv_xml_flex_flow_string_to_enum_value(const char * txt) +lv_border_side_t lv_xml_border_side_to_enum(const char * txt) +{ + if(lv_streq("none", txt)) return LV_BORDER_SIDE_NONE; + if(lv_streq("top", txt)) return LV_BORDER_SIDE_TOP; + if(lv_streq("bottom", txt)) return LV_BORDER_SIDE_BOTTOM; + if(lv_streq("left", txt)) return LV_BORDER_SIDE_LEFT; + if(lv_streq("right", txt)) return LV_BORDER_SIDE_RIGHT; + if(lv_streq("full", txt)) return LV_BORDER_SIDE_FULL; + + LV_LOG_WARN("%s is an unknown value for border_side", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_grad_dir_t lv_xml_grad_dir_to_enum(const char * txt) +{ + if(lv_streq("none", txt)) return LV_GRAD_DIR_NONE; + if(lv_streq("hor", txt)) return LV_GRAD_DIR_HOR; + if(lv_streq("ver", txt)) return LV_GRAD_DIR_VER; + + LV_LOG_WARN("%s is an unknown value for grad_dir", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_base_dir_t lv_xml_base_dir_to_enum(const char * txt) +{ + if(lv_streq("auto", txt)) return LV_BASE_DIR_AUTO; + if(lv_streq("ltr", txt)) return LV_BASE_DIR_LTR; + if(lv_streq("rtl", txt)) return LV_BASE_DIR_RTL; + + LV_LOG_WARN("%s is an unknown value for base_dir", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_text_align_t lv_xml_text_align_to_enum(const char * txt) +{ + if(lv_streq("left", txt)) return LV_TEXT_ALIGN_LEFT; + if(lv_streq("right", txt)) return LV_TEXT_ALIGN_RIGHT; + if(lv_streq("center", txt)) return LV_TEXT_ALIGN_CENTER; + if(lv_streq("auto", txt)) return LV_TEXT_ALIGN_AUTO; + + LV_LOG_WARN("%s is an unknown value for text_align", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_text_decor_t lv_xml_text_decor_to_enum(const char * txt) +{ + if(lv_streq("none", txt)) return LV_TEXT_DECOR_NONE; + if(lv_streq("underline", txt)) return LV_TEXT_DECOR_UNDERLINE; + if(lv_streq("strikethrough", txt)) return LV_TEXT_DECOR_STRIKETHROUGH; + + LV_LOG_WARN("%s is an unknown value for text_decor", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_flex_flow_t lv_xml_flex_flow_to_enum(const char * txt) { if(lv_streq("column", txt)) return LV_FLEX_FLOW_COLUMN; if(lv_streq("column_reverse", txt)) return LV_FLEX_FLOW_COLUMN_REVERSE; @@ -87,11 +142,11 @@ lv_flex_flow_t lv_xml_flex_flow_string_to_enum_value(const char * txt) if(lv_streq("row_wrap", txt)) return LV_FLEX_FLOW_ROW_WRAP; if(lv_streq("row_wrap_reverse", txt)) return LV_FLEX_FLOW_ROW_WRAP_REVERSE; - LV_LOG_WARN("%s is an unknown value for flex flow", txt); + LV_LOG_WARN("%s is an unknown value for flex_flow", txt); return 0; /*Return 0 in lack of a better option. */ } -lv_flex_align_t lv_xml_flex_align_string_to_enum_value(const char * txt) +lv_flex_align_t lv_xml_flex_align_to_enum(const char * txt) { if(lv_streq("center", txt)) return LV_FLEX_ALIGN_CENTER; if(lv_streq("end", txt)) return LV_FLEX_ALIGN_END; @@ -100,10 +155,45 @@ lv_flex_align_t lv_xml_flex_align_string_to_enum_value(const char * txt) if(lv_streq("space_between", txt)) return LV_FLEX_ALIGN_SPACE_BETWEEN; if(lv_streq("space_evenly", txt)) return LV_FLEX_ALIGN_SPACE_EVENLY; - LV_LOG_WARN("%s is an unknown value for flex align", txt); + LV_LOG_WARN("%s is an unknown value for flex_align", txt); return 0; /*Return 0 in lack of a better option. */ } +lv_grid_align_t lv_xml_grid_align_to_enum(const char * txt) +{ + if(lv_streq("center", txt)) return LV_GRID_ALIGN_CENTER; + if(lv_streq("end", txt)) return LV_GRID_ALIGN_END; + if(lv_streq("start", txt)) return LV_GRID_ALIGN_START; + if(lv_streq("stretch", txt)) return LV_GRID_ALIGN_STRETCH; + if(lv_streq("space_around", txt)) return LV_GRID_ALIGN_SPACE_AROUND; + if(lv_streq("space_between", txt)) return LV_GRID_ALIGN_SPACE_BETWEEN; + if(lv_streq("space_evenly", txt)) return LV_GRID_ALIGN_SPACE_EVENLY; + + LV_LOG_WARN("%s is an unknown value for grid_align", txt); + return 0; /*Return 0 in lack of a better option. */ +} + + +lv_layout_t lv_xml_layout_to_enum(const char * txt) +{ + if(lv_streq("none", txt)) return LV_LAYOUT_NONE; + if(lv_streq("flex", txt)) return LV_LAYOUT_FLEX; + if(lv_streq("grid", txt)) return LV_LAYOUT_GRID; + + LV_LOG_WARN("%s is an unknown value for layout", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_blend_mode_t lv_xml_blend_mode_to_enum(const char * txt) +{ + if(lv_streq("normal", txt)) return LV_BLEND_MODE_NORMAL; + if(lv_streq("additive", txt)) return LV_BLEND_MODE_ADDITIVE; + if(lv_streq("subtractive", txt)) return LV_BLEND_MODE_SUBTRACTIVE; + if(lv_streq("multiply", txt)) return LV_BLEND_MODE_MULTIPLY; + + LV_LOG_WARN("%s is an unknown value for blend_mode", txt); + return 0; /*Return 0 in lack of a better option. */ +} /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/others/xml/lv_xml_base_types.h b/src/others/xml/lv_xml_base_types.h index bd8bd6863..87936c170 100644 --- a/src/others/xml/lv_xml_base_types.h +++ b/src/others/xml/lv_xml_base_types.h @@ -39,29 +39,85 @@ int32_t lv_xml_to_size(const char * txt); * @param txt e.g. "center" * @return the related enum, e.g. `LV_ALIGN_CENTER` */ -lv_align_t lv_xml_align_string_to_enum_value(const char * txt); +lv_align_t lv_xml_align_to_enum(const char * txt); /** * Convert a direction string to enum * @param txt e.g. "top" * @return the related enum, e.g. `LV_DIR_TOP` */ -lv_dir_t lv_xml_dir_string_to_enum_value(const char * txt); +lv_dir_t lv_xml_dir_to_enum(const char * txt); +/** + * Convert a direction string to enum + * @param txt e.g. "top" + * @return the related enum, e.g. `LV_BORDER_SIDE_TOP` + */ +lv_border_side_t lv_xml_border_side_to_enum(const char * txt); + +/** + * Convert a base dir string to enum + * @param txt e.g. "rtl" + * @return the related enum, e.g. `LV_BASE_DIR_RTL` + */ +lv_base_dir_t lv_xml_base_dir_to_enum(const char * txt); + +/** + * Convert a grad dir string to enum + * @param txt e.g. "hor" + * @return the related enum, e.g. `LV_GRAD_DIR_HOR` + */ +lv_grad_dir_t lv_xml_grad_dir_to_enum(const char * txt); + + +/** + * Convert a text align string to enum + * @param txt e.g. "left" + * @return the related enum, e.g. `LV_TEXT_ALIGN_LEFT` + */ +lv_text_align_t lv_xml_text_align_to_enum(const char * txt); + +/** + * Convert a text decor string to enum + * @param txt e.g. "underline" + * @return the related enum, e.g. `LV_TEXT_DECOR_UNDERLINE` + */ +lv_text_decor_t lv_xml_text_decor_to_enum(const char * txt); /** * Convert a flex flow string to enum * @param txt e.g. "row_wrap" * @return the related enum, e.g. `LV_FLEX_FLOW_ROW_WRAP` */ -lv_flex_flow_t lv_xml_flex_flow_string_to_enum_value(const char * txt); +lv_flex_flow_t lv_xml_flex_flow_to_enum(const char * txt); /** * Convert a flex align string to enum * @param txt e.g. "space_between" * @return the related enum, e.g. `LV_FLEX_ALIGN_SPACE_BETWEEN` */ -lv_flex_align_t lv_xml_flex_align_string_to_enum_value(const char * txt); +lv_flex_align_t lv_xml_flex_align_to_enum(const char * txt); + +/** + * Convert a grid align string to enum + * @param txt e.g. "space_between" + * @return the related enum, e.g. `LV_GRID_ALIGN_SPACE_BETWEEN` + */ +lv_grid_align_t lv_xml_grid_align_to_enum(const char * txt); + +/** + * Convert a layout string to enum + * @param txt e.g. "flex" + * @return the related enum, e.g. `LV_LAYOUT_FLEX` + */ +lv_layout_t lv_xml_layout_to_enum(const char * txt); + +/** + * Convert a blend mode string to enum + * @param txt e.g. "additive" + * @return the related enum, e.g. `LV_BLEND_MODE_ADDITIVE` + */ +lv_blend_mode_t lv_xml_blend_mode_to_enum(const char * txt); /********************** * MACROS diff --git a/src/others/xml/lv_xml_component.c b/src/others/xml/lv_xml_component.c index 439fdd8a2..da88f20e7 100644 --- a/src/others/xml/lv_xml_component.c +++ b/src/others/xml/lv_xml_component.c @@ -224,15 +224,15 @@ static void process_const_element(lv_xml_parser_state_t * state, const char ** a static void process_prop_element(lv_xml_parser_state_t * state, const char ** attrs) { - lv_xml_param_t * cnst = lv_ll_ins_tail(&state->ctx.param_ll); - cnst->name = lv_strdup(lv_xml_get_value_of(attrs, "name")); + lv_xml_param_t * prop = lv_ll_ins_tail(&state->ctx.param_ll); + prop->name = lv_strdup(lv_xml_get_value_of(attrs, "name")); const char * def = lv_xml_get_value_of(attrs, "default"); - if(def) cnst->def = lv_strdup(def); - else cnst->def = NULL; + if(def) prop->def = lv_strdup(def); + else prop->def = NULL; const char * type = lv_xml_get_value_of(attrs, "type"); if(type == NULL) type = "compound"; /*If there in no type it means there are s*/ - cnst->type = lv_strdup(lv_xml_get_value_of(attrs, "type")); + prop->type = lv_strdup(type); } static void start_metadata_handler(void * user_data, const char * name, const char ** attrs) @@ -244,7 +244,18 @@ static void start_metadata_handler(void * user_data, const char * name, const ch if(lv_streq(name, "view")) { const char * extends = lv_xml_get_value_of(attrs, "extends"); if(extends == NULL) extends = "lv_obj"; + state->ctx.root_widget = lv_xml_widget_get_processor(extends); + if(state->ctx.root_widget == NULL) { + lv_xml_component_ctx_t * extended_component = lv_xml_component_get_ctx(extends); + if(extended_component) { + state->ctx.root_widget = extended_component->root_widget; + } + else { + LV_LOG_WARN("The 'extend'ed widget is not found, using `lv_obj` as a fall back"); + state->ctx.root_widget = lv_xml_widget_get_processor("lv_obj"); + } + } } if(lv_streq(name, "widget")) state->ctx.is_widget = 1; diff --git a/src/others/xml/lv_xml_style.c b/src/others/xml/lv_xml_style.c index aaf294b0f..7bf0c2dab 100644 --- a/src/others/xml/lv_xml_style.c +++ b/src/others/xml/lv_xml_style.c @@ -39,26 +39,39 @@ * MACROS **********************/ +/*Expands to e.g. + if(lv_streq(name, "height")) lv_style_set_height(style, lv_xml_to_size(value)); + */ +#define SET_STYLE_IF(prop, value) if(lv_streq(name, #prop)) lv_style_set_##prop(style, value) + /********************** * GLOBAL FUNCTIONS **********************/ -lv_state_t lv_xml_style_state_string_to_enum_value(const char * txt) +lv_state_t lv_xml_style_state_to_enum(const char * txt) { if(lv_streq("default", txt)) return LV_STATE_DEFAULT; - if(lv_streq("pressed", txt)) return LV_STATE_PRESSED; - if(lv_streq("checked", txt)) return LV_STATE_CHECKED; - if(lv_streq("scrolled", txt)) return LV_STATE_SCROLLED; + else if(lv_streq("pressed", txt)) return LV_STATE_PRESSED; + else if(lv_streq("checked", txt)) return LV_STATE_CHECKED; + else if(lv_streq("scrolled", txt)) return LV_STATE_SCROLLED; + else if(lv_streq("focused", txt)) return LV_STATE_FOCUSED; + else if(lv_streq("focus_key", txt)) return LV_STATE_FOCUS_KEY; + else if(lv_streq("edited", txt)) return LV_STATE_EDITED; + else if(lv_streq("hovered", txt)) return LV_STATE_HOVERED; + else if(lv_streq("disabled", txt)) return LV_STATE_DISABLED; return 0; /*Return 0 in lack of a better option. */ } -lv_part_t lv_xml_style_part_string_to_enum_value(const char * txt) +lv_part_t lv_xml_style_part_to_enum(const char * txt) { if(lv_streq("main", txt)) return LV_PART_MAIN; - if(lv_streq("scrollbar", txt)) return LV_PART_SCROLLBAR; - if(lv_streq("indicator", txt)) return LV_PART_INDICATOR; - if(lv_streq("knob", txt)) return LV_PART_KNOB; + else if(lv_streq("scrollbar", txt)) return LV_PART_SCROLLBAR; + else if(lv_streq("indicator", txt)) return LV_PART_INDICATOR; + else if(lv_streq("knob", txt)) return LV_PART_KNOB; + else if(lv_streq("selected", txt)) return LV_PART_SELECTED; + else if(lv_streq("items", txt)) return LV_PART_ITEMS; + else if(lv_streq("cursor", txt)) return LV_PART_CURSOR; return 0; /*Return 0 in lack of a better option. */ } @@ -96,18 +109,125 @@ void lv_xml_style_register(lv_xml_component_ctx_t * ctx, const char ** attrs) } } - if(lv_streq(name, "width")) lv_style_set_width(style, lv_xml_to_size(value)); - else if(lv_streq(name, "height")) lv_style_set_height(style, lv_xml_to_size(value)); - else if(lv_streq(name, "radius")) lv_style_set_radius(style, lv_xml_atoi(value)); - else if(lv_streq(name, "bg_opa")) lv_style_set_bg_opa(style, lv_xml_atoi(value)); - else if(lv_streq(name, "bg_color")) lv_style_set_bg_color(style, lv_xml_to_color(value)); - else if(lv_streq(name, "border_color")) lv_style_set_border_color(style, lv_xml_to_color(value)); - else if(lv_streq(name, "border_width")) lv_style_set_border_width(style, lv_xml_atoi(value)); - else if(lv_streq(name, "border_opa")) lv_style_set_border_opa(style, lv_xml_atoi(value)); - else if(lv_streq(name, "text_color")) lv_style_set_text_color(style, lv_xml_to_color(value)); - else if(lv_streq(name, "text_font")) lv_style_set_text_font(style, lv_xml_get_font(value)); - else if(lv_streq(name, "bg_image_src")) lv_style_set_bg_image_src(style, lv_xml_get_image(value)); - else if(lv_streq(name, "bg_image_tiled")) lv_style_set_bg_image_tiled(style, lv_xml_to_bool(value)); + + SET_STYLE_IF(width, lv_xml_to_size(value)); + else SET_STYLE_IF(height, lv_xml_to_size(value)); + else SET_STYLE_IF(length, lv_xml_to_size(value)); + else SET_STYLE_IF(radius, lv_xml_to_size(value)); + + else SET_STYLE_IF(pad_left, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_right, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_top, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_bottom, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_hor, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_ver, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_all, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_row, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_column, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_gap, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_radial, lv_xml_atoi(value)); + + else SET_STYLE_IF(margin_left, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_right, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_top, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_bottom, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_hor, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_ver, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_all, lv_xml_atoi(value)); + + else SET_STYLE_IF(base_dir, lv_xml_base_dir_to_enum(value)); + else SET_STYLE_IF(clip_corner, lv_xml_to_bool(value)); + + else SET_STYLE_IF(bg_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(bg_color, lv_xml_to_color(value)); + else SET_STYLE_IF(bg_grad_dir, lv_xml_grad_dir_to_enum(value)); + else SET_STYLE_IF(bg_grad_color, lv_xml_to_color(value)); + else SET_STYLE_IF(bg_main_stop, lv_xml_atoi(value)); + else SET_STYLE_IF(bg_grad_stop, lv_xml_atoi(value)); + + else SET_STYLE_IF(bg_image_src, lv_xml_get_image(value)); + else SET_STYLE_IF(bg_image_tiled, lv_xml_to_bool(value)); + else SET_STYLE_IF(bg_image_recolor, lv_xml_to_color(value)); + else SET_STYLE_IF(bg_image_recolor_opa, lv_xml_to_opa(value)); + + else SET_STYLE_IF(border_color, lv_xml_to_color(value)); + else SET_STYLE_IF(border_width, lv_xml_atoi(value)); + else SET_STYLE_IF(border_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(border_side, lv_xml_border_side_to_enum(value)); + else SET_STYLE_IF(border_post, lv_xml_to_bool(value)); + + else SET_STYLE_IF(outline_color, lv_xml_to_color(value)); + else SET_STYLE_IF(outline_width, lv_xml_atoi(value)); + else SET_STYLE_IF(outline_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(outline_pad, lv_xml_atoi(value)); + + else SET_STYLE_IF(shadow_width, lv_xml_atoi(value)); + else SET_STYLE_IF(shadow_color, lv_xml_to_color(value)); + else SET_STYLE_IF(shadow_offset_x, lv_xml_atoi(value)); + else SET_STYLE_IF(shadow_offset_y, lv_xml_atoi(value)); + else SET_STYLE_IF(shadow_spread, lv_xml_atoi(value)); + else SET_STYLE_IF(shadow_opa, lv_xml_to_opa(value)); + + else SET_STYLE_IF(text_color, lv_xml_to_color(value)); + else SET_STYLE_IF(text_font, lv_xml_get_font(value)); + else SET_STYLE_IF(text_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(text_align, lv_xml_text_align_to_enum(value)); + else SET_STYLE_IF(text_letter_space, lv_xml_atoi(value)); + else SET_STYLE_IF(text_line_space, lv_xml_atoi(value)); + else SET_STYLE_IF(text_decor, lv_xml_text_decor_to_enum(value)); + + else SET_STYLE_IF(image_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(image_recolor, lv_xml_to_color(value)); + else SET_STYLE_IF(image_recolor_opa, lv_xml_to_opa(value)); + + else SET_STYLE_IF(line_color, lv_xml_to_color(value)); + else SET_STYLE_IF(line_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(line_width, lv_xml_atoi(value)); + else SET_STYLE_IF(line_dash_width, lv_xml_atoi(value)); + else SET_STYLE_IF(line_dash_gap, lv_xml_atoi(value)); + else SET_STYLE_IF(line_rounded, lv_xml_to_bool(value)); + + else SET_STYLE_IF(arc_color, lv_xml_to_color(value)); + else SET_STYLE_IF(arc_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(arc_width, lv_xml_atoi(value)); + else SET_STYLE_IF(arc_rounded, lv_xml_to_bool(value)); + else SET_STYLE_IF(arc_image_src, lv_xml_get_image(value)); + + else SET_STYLE_IF(opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(opa_layered, lv_xml_to_opa(value)); + else SET_STYLE_IF(color_filter_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(anim_duration, lv_xml_atoi(value)); + else SET_STYLE_IF(blend_mode, lv_xml_blend_mode_to_enum(value)); + else SET_STYLE_IF(transform_width, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_height, lv_xml_atoi(value)); + else SET_STYLE_IF(translate_x, lv_xml_atoi(value)); + else SET_STYLE_IF(translate_y, lv_xml_atoi(value)); + else SET_STYLE_IF(translate_radial, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_scale_x, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_scale_y, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_rotation, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_pivot_x, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_pivot_y, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_skew_x, lv_xml_atoi(value)); + else SET_STYLE_IF(bitmap_mask_src, lv_xml_get_image(value)); + else SET_STYLE_IF(rotary_sensitivity, lv_xml_atoi(value)); + + else SET_STYLE_IF(layout, lv_xml_layout_to_enum(value)); + + else SET_STYLE_IF(flex_flow, lv_xml_flex_flow_to_enum(value)); + else SET_STYLE_IF(flex_grow, lv_xml_atoi(value)); + else SET_STYLE_IF(flex_main_place, lv_xml_flex_align_to_enum(value)); + else SET_STYLE_IF(flex_cross_place, lv_xml_flex_align_to_enum(value)); + else SET_STYLE_IF(flex_track_place, lv_xml_flex_align_to_enum(value)); + + else SET_STYLE_IF(grid_column_align, lv_xml_grid_align_to_enum(value)); + else SET_STYLE_IF(grid_row_align, lv_xml_grid_align_to_enum(value)); + else SET_STYLE_IF(grid_cell_column_pos, lv_xml_atoi(value)); + else SET_STYLE_IF(grid_cell_column_span, lv_xml_atoi(value)); + else SET_STYLE_IF(grid_cell_x_align, lv_xml_grid_align_to_enum(value)); + else SET_STYLE_IF(grid_cell_row_pos, lv_xml_atoi(value)); + else SET_STYLE_IF(grid_cell_row_span, lv_xml_atoi(value)); + else SET_STYLE_IF(grid_cell_y_align, lv_xml_grid_align_to_enum(value)); else { LV_LOG_WARN("%s style property is not supported", name); } @@ -122,8 +242,8 @@ const char * lv_xml_style_string_process(char * txt, lv_style_selector_t * selec char * selector_str = lv_xml_split_str(&txt, ':'); while(selector_str != NULL) { /* Handle different states and parts */ - *selector |= lv_xml_style_state_string_to_enum_value(selector_str); - *selector |= lv_xml_style_part_string_to_enum_value(selector_str); + *selector |= lv_xml_style_state_to_enum(selector_str); + *selector |= lv_xml_style_part_to_enum(selector_str); /* Move to the next token */ selector_str = lv_xml_split_str(&txt, ':'); diff --git a/src/others/xml/lv_xml_style.h b/src/others/xml/lv_xml_style.h index d7288bd34..e54e26595 100644 --- a/src/others/xml/lv_xml_style.h +++ b/src/others/xml/lv_xml_style.h @@ -53,14 +53,14 @@ void lv_xml_style_add_to_obj(lv_xml_parser_state_t * state, lv_obj_t * obj, cons * @param txt e.g. "pressed" * @return the enum `LV_STATE_PRESSED` */ -lv_state_t lv_xml_style_state_string_to_enum_value(const char * txt); +lv_state_t lv_xml_style_state_to_enum(const char * txt); /** * Convert a style part to enum * @param txt e.g. "knob" * @return the enum `LV_PART_KNOB` */ -lv_part_t lv_xml_style_part_string_to_enum_value(const char * txt); +lv_part_t lv_xml_style_part_to_enum(const char * txt); /** * Decompose a string like `"style1:pressed:checked:knob"` to style name and selector diff --git a/src/others/xml/lv_xml_utils.c b/src/others/xml/lv_xml_utils.c index ad4f72523..d16b20eb0 100644 --- a/src/others/xml/lv_xml_utils.c +++ b/src/others/xml/lv_xml_utils.c @@ -25,9 +25,7 @@ /********************** * STATIC PROTOTYPES **********************/ -#if LV_USE_STDLIB_STRING != LV_STDLIB_CLIB - static bool lv_xml_is_digit(char c, int base); -#endif +static bool is_digit(char c, int base); /********************** * STATIC VARIABLES @@ -59,29 +57,26 @@ lv_color_t lv_xml_to_color(const char * str) return lv_color_hex(lv_xml_strtol(str, NULL, 16)); } +lv_opa_t lv_xml_to_opa(const char * str) +{ + int32_t v = lv_xml_atoi(str); + size_t len = lv_strlen(str); + if(str[len - 1] == '%') { + v = v * 255 / 100; + } + + v = LV_CLAMP(0, v, 255); + return (lv_opa_t)v; +} + bool lv_xml_to_bool(const char * str) { return lv_streq(str, "false") ? false : true; } - -#if LV_USE_STDLIB_STRING == LV_STDLIB_CLIB -int32_t lv_xml_atoi(const char * str) +int32_t lv_xml_atoi_split(const char ** str, char delimiter) { - return atoi(str); -} - - -int32_t lv_xml_strtol(const char * str, char ** endptr, int32_t base) -{ - return strtol(str, endptr, base); -} - -#else /*LV_USE_STDLIB_STRING == LV_STDLIB_CLIB*/ - -int32_t lv_xml_atoi(const char * str) -{ - const char * s = str; + const char * s = *str; int32_t result = 0; int sign = 1; @@ -98,24 +93,32 @@ int32_t lv_xml_atoi(const char * str) } /* Convert the string*/ - while(*s) { + while(*s != delimiter) { if(*s >= '0' && *s <= '9') { int32_t digit = *s - '0'; - /* Check for overflow before it happens */ - if(result > (INT_MAX - digit) / 10) { - return (sign == 1) ? INT_MAX : INT_MIN; // Return limits on overflow - } - result = result * 10 + digit; s++; } else { - break; // Non-digit character + break; /* Non-digit character */ } } - return result * sign; + result = result * sign; + + if(*s != '\0') s++; /*Skip the delimiter*/ + *str = s; + return result; + +} + + +int32_t lv_xml_atoi(const char * str) +{ + + return lv_xml_atoi_split(&str, '\0'); + } int32_t lv_xml_strtol(const char * str, char ** endptr, int32_t base) @@ -157,7 +160,7 @@ int32_t lv_xml_strtol(const char * str, char ** endptr, int32_t base) while(*s) { int32_t digit; - if(lv_xml_is_digit(*s, base)) { + if(is_digit(*s, base)) { if(*s >= '0' && *s <= '9') { digit = *s - '0'; } @@ -168,7 +171,7 @@ int32_t lv_xml_strtol(const char * str, char ** endptr, int32_t base) digit = *s - 'A' + 10; } else { - /* This should not happen due to lv_xml_is_digit check*/ + /* This should not happen due to is_digit check*/ break; } @@ -192,8 +195,6 @@ int32_t lv_xml_strtol(const char * str, char ** endptr, int32_t base) return result * sign; } -#endif /*LV_USE_STDLIB_STRING == LV_STDLIB_CLIB*/ - char * lv_xml_split_str(char ** src, char delimiter) { if(*src[0] == '\0') return NULL; @@ -221,8 +222,7 @@ char * lv_xml_split_str(char ** src, char delimiter) * STATIC FUNCTIONS **********************/ -#if LV_USE_STDLIB_STRING != LV_STDLIB_CLIB -static bool lv_xml_is_digit(char c, int base) +static bool is_digit(char c, int base) { if(base <= 10) { return (c >= '0' && c < '0' + base); @@ -232,6 +232,5 @@ static bool lv_xml_is_digit(char c, int base) } } -#endif /*LV_USE_STDLIB_STRING == LV_STDLIB_CLIB*/ #endif /* LV_USE_XML */ diff --git a/src/others/xml/lv_xml_utils.h b/src/others/xml/lv_xml_utils.h index dfde5f894..d5bd5ec34 100644 --- a/src/others/xml/lv_xml_utils.h +++ b/src/others/xml/lv_xml_utils.h @@ -26,8 +26,25 @@ const char * lv_xml_get_value_of(const char ** attrs, const char * name); int32_t lv_xml_atoi(const char * str); + +/** + * Convert sections of a string to int. + * The end of the string is indicated by the `delimiter`. + * @param str pointer to a string, it will point to the character after the delimiter + * @param delimiter a character to indicate the end of the int + * @return the int before the next delimiter + */ +int32_t lv_xml_atoi_split(const char ** str, char delimiter); + lv_color_t lv_xml_to_color(const char * str); +/** + * Concert percentage or integer opacity value from string to integer. + * @param str e.g. "70%" or 180 + * @return 0..255 + */ +lv_opa_t lv_xml_to_opa(const char * str); + bool lv_xml_to_bool(const char * str); int32_t lv_xml_strtol(const char * str, char ** endptr, int32_t base); diff --git a/src/others/xml/parsers/lv_xml_chart_parser.c b/src/others/xml/parsers/lv_xml_chart_parser.c index 5ef70d882..3d91659fb 100644 --- a/src/others/xml/parsers/lv_xml_chart_parser.c +++ b/src/others/xml/parsers/lv_xml_chart_parser.c @@ -23,9 +23,9 @@ /********************** * STATIC PROTOTYPES **********************/ -static lv_chart_type_t chart_type_string_to_enum_value(const char * txt); -static lv_chart_update_mode_t chart_update_mode_string_to_enum_value(const char * txt); -static lv_chart_axis_t chart_axis_string_to_enum_value(const char * txt); +static lv_chart_type_t chart_type_to_enum(const char * txt); +static lv_chart_update_mode_t chart_update_mode_to_enum(const char * txt); +static lv_chart_axis_t chart_axis_to_enum(const char * txt); /********************** * STATIC VARIABLES @@ -59,8 +59,14 @@ void lv_xml_chart_apply(lv_xml_parser_state_t * state, const char ** attrs) const char * value = attrs[i + 1]; if(lv_streq("point_count", name)) lv_chart_set_point_count(item, lv_xml_atoi(value)); - if(lv_streq("type", name)) lv_chart_set_type(item, chart_type_string_to_enum_value(value)); - if(lv_streq("mode", name)) lv_chart_set_update_mode(item, chart_update_mode_string_to_enum_value(value)); + else if(lv_streq("type", name)) lv_chart_set_type(item, chart_type_to_enum(value)); + else if(lv_streq("update_mode", name)) lv_chart_set_update_mode(item, chart_update_mode_to_enum(value)); + else if(lv_streq("div_line_count", name)) { + + int32_t value1 = lv_xml_atoi_split(&value, ' '); + int32_t value2 = lv_xml_atoi_split(&value, ' '); + lv_chart_set_div_line_count(item, value1, value2); + } } } @@ -69,11 +75,7 @@ void * lv_xml_chart_series_create(lv_xml_parser_state_t * state, const char ** a const char * color = lv_xml_get_value_of(attrs, "color"); const char * axis = lv_xml_get_value_of(attrs, "axis"); void * item = lv_chart_add_series(lv_xml_state_get_parent(state), lv_color_hex(lv_xml_strtol(color, NULL, 16)), - chart_axis_string_to_enum_value(axis)); - - lv_obj_t * parent = lv_xml_state_get_parent(state); - lv_chart_set_all_value(parent, item, lv_rand(10, 90)); - + chart_axis_to_enum(axis)); return item; } @@ -82,7 +84,20 @@ void lv_xml_chart_series_apply(lv_xml_parser_state_t * state, const char ** attr LV_UNUSED(state); LV_UNUSED(attrs); - /*Nothing to apply*/ + lv_obj_t * chart = lv_xml_state_get_parent(state); + lv_chart_series_t * ser = lv_xml_state_get_item(state); + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("values", name)) { + while(value[0] != '\0') { + int32_t v = lv_xml_atoi_split(&value, ' '); + lv_chart_set_next_value(chart, ser, v); + } + } + } } void * lv_xml_chart_cursor_create(lv_xml_parser_state_t * state, const char ** attrs) @@ -90,13 +105,7 @@ void * lv_xml_chart_cursor_create(lv_xml_parser_state_t * state, const char ** a const char * color = lv_xml_get_value_of(attrs, "color"); const char * dir = lv_xml_get_value_of(attrs, "dir"); void * item = lv_chart_add_cursor(lv_xml_state_get_parent(state), lv_color_hex(lv_xml_strtol(color, NULL, 16)), - lv_xml_dir_string_to_enum_value(dir)); - - lv_obj_t * parent = lv_xml_state_get_parent(state); - lv_point_t p = {30, 40}; - lv_chart_set_cursor_pos(parent, item, &p); - - /* There are no properties to process */ + lv_xml_dir_to_enum(dir)); return item; } @@ -106,14 +115,56 @@ void lv_xml_chart_cursor_apply(lv_xml_parser_state_t * state, const char ** attr LV_UNUSED(state); LV_UNUSED(attrs); - /*Nothing to apply*/ + lv_obj_t * chart = lv_xml_state_get_parent(state); + lv_chart_cursor_t * cursor = lv_xml_state_get_item(state); + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + + if(lv_streq("pos", name)) { + int32_t x = lv_xml_atoi_split(&value, ' '); + int32_t y = lv_xml_atoi_split(&value, ' '); + lv_point_t p = {x, y}; + lv_chart_set_cursor_pos(chart, cursor, &p); + } + } +} + +void * lv_xml_chart_axis_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + /*Nothing to create*/ + return lv_xml_state_get_parent(state);; +} + +void lv_xml_chart_axis_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(state); + LV_UNUSED(attrs); + + lv_obj_t * chart = lv_xml_state_get_parent(state); + lv_chart_axis_t axis = chart_axis_to_enum(lv_xml_get_value_of(attrs, "axis")); + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("range", name)) { + int32_t min_val = lv_xml_atoi_split(&value, ' '); + int32_t max_val = lv_xml_atoi_split(&value, ' '); + lv_chart_set_range(chart, axis, min_val, max_val); + } + } } /********************** * STATIC FUNCTIONS **********************/ -static lv_chart_type_t chart_type_string_to_enum_value(const char * txt) +static lv_chart_type_t chart_type_to_enum(const char * txt) { if(lv_streq("none", txt)) return LV_CHART_TYPE_NONE; if(lv_streq("line", txt)) return LV_CHART_TYPE_LINE; @@ -123,7 +174,8 @@ static lv_chart_type_t chart_type_string_to_enum_value(const char * txt) LV_LOG_WARN("%s is an unknown value for chart's chart_type", txt); return 0; /*Return 0 in lack of a better option. */ } -static lv_chart_update_mode_t chart_update_mode_string_to_enum_value(const char * txt) + +static lv_chart_update_mode_t chart_update_mode_to_enum(const char * txt) { if(lv_streq("shift", txt)) return LV_CHART_UPDATE_MODE_SHIFT; if(lv_streq("circular", txt)) return LV_CHART_UPDATE_MODE_CIRCULAR; @@ -131,7 +183,8 @@ static lv_chart_update_mode_t chart_update_mode_string_to_enum_value(const char LV_LOG_WARN("%s is an unknown value for chart's chart_update_mode", txt); return 0; /*Return 0 in lack of a better option. */ } -static lv_chart_axis_t chart_axis_string_to_enum_value(const char * txt) + +static lv_chart_axis_t chart_axis_to_enum(const char * txt) { if(lv_streq("primary_x", txt)) return LV_CHART_AXIS_PRIMARY_X; if(lv_streq("primary_y", txt)) return LV_CHART_AXIS_PRIMARY_Y; diff --git a/src/others/xml/parsers/lv_xml_chart_parser.h b/src/others/xml/parsers/lv_xml_chart_parser.h index 34a3104c9..0307e4f8e 100644 --- a/src/others/xml/parsers/lv_xml_chart_parser.h +++ b/src/others/xml/parsers/lv_xml_chart_parser.h @@ -30,6 +30,8 @@ void * lv_xml_chart_series_create(lv_xml_parser_state_t * state, const char ** a void lv_xml_chart_series_apply(lv_xml_parser_state_t * state, const char ** attrs); void * lv_xml_chart_cursor_create(lv_xml_parser_state_t * state, const char ** attrs); void lv_xml_chart_cursor_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_chart_axis_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_chart_axis_apply(lv_xml_parser_state_t * state, const char ** attrs); /********************** * MACROS diff --git a/src/others/xml/parsers/lv_xml_dropdown_parser.c b/src/others/xml/parsers/lv_xml_dropdown_parser.c new file mode 100644 index 000000000..ffa32e351 --- /dev/null +++ b/src/others/xml/parsers/lv_xml_dropdown_parser.c @@ -0,0 +1,84 @@ +/** + * @file lv_xml_dropdown_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_dropdown_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_dropdown_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_dropdown_create(lv_xml_state_get_parent(state)); + + return item; +} + + +void lv_xml_dropdown_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("options", name)) lv_dropdown_set_options(item, value); + if(lv_streq("text", name)) lv_dropdown_set_text(item, value); + if(lv_streq("selected", name)) lv_dropdown_set_selected(item, lv_xml_atoi(value), LV_ANIM_OFF); + if(lv_streq("symbol", name)) lv_dropdown_set_symbol(item, lv_xml_get_image(value)); + } +} + +void * lv_xml_dropdown_list_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + return lv_dropdown_get_list(lv_xml_state_get_parent(state)); +} + +void lv_xml_dropdown_list_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(state); + LV_UNUSED(attrs); + + lv_xml_obj_apply(state, attrs); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /* LV_USE_XML */ diff --git a/src/others/xml/parsers/lv_xml_dropdown_parser.h b/src/others/xml/parsers/lv_xml_dropdown_parser.h new file mode 100644 index 000000000..3a6919256 --- /dev/null +++ b/src/others/xml/parsers/lv_xml_dropdown_parser.h @@ -0,0 +1,41 @@ +/** + * @file lv_xml_dropdown_parser.h + * + */ + +#ifndef LV_DROPDOWN_XML_PARSER_H +#define LV_DROPDOWN_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_dropdown_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_dropdown_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_dropdown_list_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_dropdown_list_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DROPDOWN_XML_PARSE_H*/ diff --git a/src/others/xml/parsers/lv_xml_image_parser.c b/src/others/xml/parsers/lv_xml_image_parser.c index b33c1abff..ff1d0e6c6 100644 --- a/src/others/xml/parsers/lv_xml_image_parser.c +++ b/src/others/xml/parsers/lv_xml_image_parser.c @@ -23,6 +23,7 @@ /********************** * STATIC PROTOTYPES **********************/ +static lv_image_align_t image_align_to_enum(const char * txt); /********************** * STATIC VARIABLES @@ -49,56 +50,25 @@ void * lv_xml_image_create(lv_xml_parser_state_t * state, const char ** attrs) return item; } -void lv_xml_check_file(const char * filepath) -{ - lv_fs_file_t f; - lv_fs_res_t res = lv_fs_open(&f, filepath, LV_FS_MODE_RD); - - if(res == LV_FS_RES_OK) { - uint32_t size; - uint8_t buffer[10]; - lv_fs_read(&f, buffer, 0, &size); - - lv_fs_seek(&f, 0, LV_FS_SEEK_END); - lv_fs_tell(&f, &size); - LV_LOG_USER("File %s exists (%u bytes)", filepath, size); - - - lv_fs_close(&f); - - lv_image_header_t info; - lv_image_decoder_get_info(filepath, &info); - LV_LOG_USER("Image info: %d x %d, %d color", info.w, info.h, info.cf); - } - else { - LV_LOG_ERROR("Failed to open file: %s", filepath); - } -} - void lv_xml_image_apply(lv_xml_parser_state_t * state, const char ** attrs) { void * item = lv_xml_state_get_item(state); - if(item == NULL) { - LV_LOG_ERROR("Failed to get image"); - return; - } - 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("src", name)) { - const void * img_src = lv_xml_get_image(value); - if(img_src == NULL) { - LV_LOG_WARN("Failed to get image source for '%s'", value); - return; - } - - lv_image_set_src(item, (const char *)img_src); - + if(lv_streq("src", name)) lv_image_set_src(item, lv_xml_get_image(value)); + if(lv_streq("inner_align", name)) lv_image_set_inner_align(item, image_align_to_enum(value)); + if(lv_streq("rotation", name)) lv_image_set_rotation(item, lv_xml_atoi(value)); + if(lv_streq("scale_x", name)) lv_image_set_scale_x(item, lv_xml_atoi(value)); + if(lv_streq("scale_y", name)) lv_image_set_scale_y(item, lv_xml_atoi(value)); + if(lv_streq("pivot", name)) { + int32_t x = lv_xml_atoi_split(&value, ' '); + int32_t y = lv_xml_atoi_split(&value, ' '); + lv_image_set_pivot(item, x, y); } } @@ -109,4 +79,23 @@ void lv_xml_image_apply(lv_xml_parser_state_t * state, const char ** attrs) * STATIC FUNCTIONS **********************/ +static lv_image_align_t image_align_to_enum(const char * txt) +{ + if(lv_streq("top_left", txt)) return LV_IMAGE_ALIGN_TOP_LEFT; + if(lv_streq("top_mid", txt)) return LV_IMAGE_ALIGN_TOP_MID; + if(lv_streq("top_right", txt)) return LV_IMAGE_ALIGN_TOP_RIGHT; + if(lv_streq("bottom_left", txt)) return LV_IMAGE_ALIGN_BOTTOM_LEFT; + if(lv_streq("bottom_mid", txt)) return LV_IMAGE_ALIGN_BOTTOM_MID; + if(lv_streq("bottom_right", txt)) return LV_IMAGE_ALIGN_BOTTOM_RIGHT; + if(lv_streq("right_mid", txt)) return LV_IMAGE_ALIGN_RIGHT_MID; + if(lv_streq("left_mid", txt)) return LV_IMAGE_ALIGN_LEFT_MID; + if(lv_streq("center", txt)) return LV_IMAGE_ALIGN_CENTER; + if(lv_streq("stretch", txt)) return LV_IMAGE_ALIGN_STRETCH; + if(lv_streq("tile", txt)) return LV_IMAGE_ALIGN_TILE; + + LV_LOG_WARN("%s is an unknown value for image align", txt); + return 0; /*Return 0 in lack of a better option. */ +} + + #endif /* LV_USE_XML */ diff --git a/src/others/xml/parsers/lv_xml_obj_parser.c b/src/others/xml/parsers/lv_xml_obj_parser.c index 2af6b02f4..2802d31fc 100644 --- a/src/others/xml/parsers/lv_xml_obj_parser.c +++ b/src/others/xml/parsers/lv_xml_obj_parser.c @@ -23,6 +23,7 @@ /********************** * STATIC PROTOTYPES **********************/ +static void apply_styles(lv_obj_t * obj, const char * name, const char * value); /********************** * STATIC VARIABLES @@ -32,6 +33,11 @@ * MACROS **********************/ +/* Expands to + if(lv_streq(prop_name, "style_height")) lv_obj_set_style_height(obj, value, selector) + */ +#define SET_STYLE_IF(prop, value) if(lv_streq(prop_name, "style_" #prop)) lv_obj_set_style_##prop(obj, value, selector) + /********************** * GLOBAL FUNCTIONS **********************/ @@ -53,30 +59,56 @@ void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs) const char * value = attrs[i + 1]; if(lv_streq("x", name)) lv_obj_set_x(item, lv_xml_to_size(value)); - if(lv_streq("y", name)) lv_obj_set_y(item, lv_xml_to_size(value)); - if(lv_streq("width", name)) lv_obj_set_width(item, lv_xml_to_size(value)); - if(lv_streq("height", name)) lv_obj_set_height(item, lv_xml_to_size(value)); - if(lv_streq("align", name)) lv_obj_set_align(item, lv_xml_align_string_to_enum_value(value)); + else if(lv_streq("y", name)) lv_obj_set_y(item, lv_xml_to_size(value)); + else if(lv_streq("width", name)) lv_obj_set_width(item, lv_xml_to_size(value)); + else if(lv_streq("height", name)) lv_obj_set_height(item, lv_xml_to_size(value)); + else if(lv_streq("align", name)) lv_obj_set_align(item, lv_xml_align_to_enum(value)); + else if(lv_streq("flex_flow", name)) lv_obj_set_flex_flow(item, lv_xml_flex_flow_to_enum(value)); + else if(lv_streq("flex_grow", name)) lv_obj_set_flex_grow(item, lv_xml_atoi(value)); - if(lv_streq("styles", name)) lv_xml_style_add_to_obj(state, item, value); + else if(lv_streq("hidden", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_HIDDEN, lv_xml_to_bool(value)); + else if(lv_streq("clickable", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_CLICKABLE, lv_xml_to_bool(value)); + else if(lv_streq("click_focusable", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_CLICK_FOCUSABLE, + lv_xml_to_bool(value)); + else if(lv_streq("checkable", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_CHECKABLE, lv_xml_to_bool(value)); + else if(lv_streq("scrollable", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_SCROLLABLE, lv_xml_to_bool(value)); + else if(lv_streq("scroll_elastic", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_SCROLL_ELASTIC, + lv_xml_to_bool(value)); + else if(lv_streq("scroll_momentum", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_SCROLL_MOMENTUM, + lv_xml_to_bool(value)); + else if(lv_streq("scroll_one", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_SCROLL_ONE, lv_xml_to_bool(value)); + else if(lv_streq("scroll_chain_hor", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_SCROLL_CHAIN_HOR, + lv_xml_to_bool(value)); + else if(lv_streq("scroll_chain_ver", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_SCROLL_CHAIN_VER, + lv_xml_to_bool(value)); + else if(lv_streq("scroll_chain", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_SCROLL_CHAIN, + lv_xml_to_bool(value)); + else if(lv_streq("scroll_on_focus", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_SCROLL_ON_FOCUS, + lv_xml_to_bool(value)); + else if(lv_streq("scroll_with_arrow", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_SCROLL_WITH_ARROW, + lv_xml_to_bool(value)); + else if(lv_streq("snappable", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_SNAPPABLE, lv_xml_to_bool(value)); + else if(lv_streq("press_lock", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_PRESS_LOCK, lv_xml_to_bool(value)); + else if(lv_streq("event_bubble", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_EVENT_BUBBLE, + lv_xml_to_bool(value)); + else if(lv_streq("gesture_bubble", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_GESTURE_BUBBLE, + lv_xml_to_bool(value)); + else if(lv_streq("adv_hittest", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_ADV_HITTEST, + lv_xml_to_bool(value)); + else if(lv_streq("ignore_layout", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_IGNORE_LAYOUT, + lv_xml_to_bool(value)); + else if(lv_streq("floating", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_FLOATING, lv_xml_to_bool(value)); + else if(lv_streq("send_draw_task_events", name))lv_obj_update_flag(item, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS, + lv_xml_to_bool(value)); + else if(lv_streq("overflow_visible", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_OVERFLOW_VISIBLE, + lv_xml_to_bool(value)); + else if(lv_streq("flex_in_new_track", name)) lv_obj_update_flag(item, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK, + lv_xml_to_bool(value)); - if(lv_strlen(name) > 6 && lv_memcmp("style_", name, 6) == 0) { - char name_local[512]; - lv_strlcpy(name_local, name, sizeof(name_local)); + else if(lv_streq("styles", name)) lv_xml_style_add_to_obj(state, item, value); - lv_style_selector_t selector; - const char * prop_name = lv_xml_style_string_process(name_local, &selector); - - if(lv_streq("style_radius", prop_name)) lv_obj_set_style_radius(item, lv_xml_atoi(value), selector); - if(lv_streq("style_bg_color", prop_name)) lv_obj_set_style_bg_color(item, lv_xml_to_color(value), selector); - if(lv_streq("style_bg_opa", prop_name)) lv_obj_set_style_bg_opa(item, lv_xml_atoi(value), selector); - if(lv_streq("style_border_color", prop_name)) lv_obj_set_style_border_color(item, lv_xml_to_color(value), selector); - if(lv_streq("style_border_opa", prop_name)) lv_obj_set_style_border_opa(item, lv_xml_atoi(value), selector); - if(lv_streq("style_border_width", prop_name)) lv_obj_set_style_border_width(item, lv_xml_atoi(value), selector); - if(lv_streq("style_bg_image_src", prop_name)) lv_obj_set_style_bg_image_src(item, lv_xml_get_image(value), selector); - if(lv_streq("style_bg_image_tiled", prop_name)) lv_obj_set_style_bg_image_tiled(item, lv_xml_to_bool(value), selector); - if(lv_streq("style_text_color", prop_name)) lv_obj_set_style_text_color(item, lv_xml_to_color(value), selector); - if(lv_streq("style_text_font", prop_name)) lv_obj_set_style_text_font(item, lv_xml_get_font(value), selector); + else if(lv_strlen(name) > 6 && lv_memcmp("style_", name, 6) == 0) { + apply_styles(item, name, value); } } } @@ -85,5 +117,133 @@ void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs) * STATIC FUNCTIONS **********************/ +static void apply_styles(lv_obj_t * obj, const char * name, const char * value) +{ + char name_local[512]; + lv_strlcpy(name_local, name, sizeof(name_local)); + + lv_style_selector_t selector; + const char * prop_name = lv_xml_style_string_process(name_local, &selector); + + SET_STYLE_IF(width, lv_xml_to_size(value)); + else SET_STYLE_IF(height, lv_xml_to_size(value)); + else SET_STYLE_IF(length, lv_xml_to_size(value)); + else SET_STYLE_IF(radius, lv_xml_to_size(value)); + + else SET_STYLE_IF(pad_left, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_right, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_top, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_bottom, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_hor, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_ver, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_all, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_row, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_column, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_gap, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_radial, lv_xml_atoi(value)); + + else SET_STYLE_IF(margin_left, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_right, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_top, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_bottom, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_hor, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_ver, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_all, lv_xml_atoi(value)); + + else SET_STYLE_IF(base_dir, lv_xml_base_dir_to_enum(value)); + else SET_STYLE_IF(clip_corner, lv_xml_to_bool(value)); + + else SET_STYLE_IF(bg_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(bg_color, lv_xml_to_color(value)); + else SET_STYLE_IF(bg_grad_dir, lv_xml_grad_dir_to_enum(value)); + else SET_STYLE_IF(bg_grad_color, lv_xml_to_color(value)); + else SET_STYLE_IF(bg_main_stop, lv_xml_atoi(value)); + else SET_STYLE_IF(bg_grad_stop, lv_xml_atoi(value)); + + else SET_STYLE_IF(bg_image_src, lv_xml_get_image(value)); + else SET_STYLE_IF(bg_image_tiled, lv_xml_to_bool(value)); + else SET_STYLE_IF(bg_image_recolor, lv_xml_to_color(value)); + else SET_STYLE_IF(bg_image_recolor_opa, lv_xml_to_opa(value)); + + else SET_STYLE_IF(border_color, lv_xml_to_color(value)); + else SET_STYLE_IF(border_width, lv_xml_atoi(value)); + else SET_STYLE_IF(border_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(border_side, lv_xml_border_side_to_enum(value)); + else SET_STYLE_IF(border_post, lv_xml_to_bool(value)); + + else SET_STYLE_IF(outline_color, lv_xml_to_color(value)); + else SET_STYLE_IF(outline_width, lv_xml_atoi(value)); + else SET_STYLE_IF(outline_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(outline_pad, lv_xml_atoi(value)); + + else SET_STYLE_IF(shadow_width, lv_xml_atoi(value)); + else SET_STYLE_IF(shadow_color, lv_xml_to_color(value)); + else SET_STYLE_IF(shadow_offset_x, lv_xml_atoi(value)); + else SET_STYLE_IF(shadow_offset_y, lv_xml_atoi(value)); + else SET_STYLE_IF(shadow_spread, lv_xml_atoi(value)); + else SET_STYLE_IF(shadow_opa, lv_xml_to_opa(value)); + + else SET_STYLE_IF(text_color, lv_xml_to_color(value)); + else SET_STYLE_IF(text_font, lv_xml_get_font(value)); + else SET_STYLE_IF(text_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(text_align, lv_xml_text_align_to_enum(value)); + else SET_STYLE_IF(text_letter_space, lv_xml_atoi(value)); + else SET_STYLE_IF(text_line_space, lv_xml_atoi(value)); + else SET_STYLE_IF(text_decor, lv_xml_text_decor_to_enum(value)); + + else SET_STYLE_IF(image_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(image_recolor, lv_xml_to_color(value)); + else SET_STYLE_IF(image_recolor_opa, lv_xml_to_opa(value)); + + else SET_STYLE_IF(line_color, lv_xml_to_color(value)); + else SET_STYLE_IF(line_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(line_width, lv_xml_atoi(value)); + else SET_STYLE_IF(line_dash_width, lv_xml_atoi(value)); + else SET_STYLE_IF(line_dash_gap, lv_xml_atoi(value)); + else SET_STYLE_IF(line_rounded, lv_xml_to_bool(value)); + + else SET_STYLE_IF(arc_color, lv_xml_to_color(value)); + else SET_STYLE_IF(arc_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(arc_width, lv_xml_atoi(value)); + else SET_STYLE_IF(arc_rounded, lv_xml_to_bool(value)); + else SET_STYLE_IF(arc_image_src, lv_xml_get_image(value)); + + else SET_STYLE_IF(opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(opa_layered, lv_xml_to_opa(value)); + else SET_STYLE_IF(color_filter_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(anim_duration, lv_xml_atoi(value)); + else SET_STYLE_IF(blend_mode, lv_xml_blend_mode_to_enum(value)); + else SET_STYLE_IF(transform_width, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_height, lv_xml_atoi(value)); + else SET_STYLE_IF(translate_x, lv_xml_atoi(value)); + else SET_STYLE_IF(translate_y, lv_xml_atoi(value)); + else SET_STYLE_IF(translate_radial, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_scale_x, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_scale_y, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_rotation, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_pivot_x, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_pivot_y, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_skew_x, lv_xml_atoi(value)); + else SET_STYLE_IF(bitmap_mask_src, lv_xml_get_image(value)); + else SET_STYLE_IF(rotary_sensitivity, lv_xml_atoi(value)); + + else SET_STYLE_IF(layout, lv_xml_layout_to_enum(value)); + + else SET_STYLE_IF(flex_flow, lv_xml_flex_flow_to_enum(value)); + else SET_STYLE_IF(flex_grow, lv_xml_atoi(value)); + else SET_STYLE_IF(flex_main_place, lv_xml_flex_align_to_enum(value)); + else SET_STYLE_IF(flex_cross_place, lv_xml_flex_align_to_enum(value)); + else SET_STYLE_IF(flex_track_place, lv_xml_flex_align_to_enum(value)); + + else SET_STYLE_IF(grid_column_align, lv_xml_grid_align_to_enum(value)); + else SET_STYLE_IF(grid_row_align, lv_xml_grid_align_to_enum(value)); + else SET_STYLE_IF(grid_cell_column_pos, lv_xml_atoi(value)); + else SET_STYLE_IF(grid_cell_column_span, lv_xml_atoi(value)); + else SET_STYLE_IF(grid_cell_x_align, lv_xml_grid_align_to_enum(value)); + else SET_STYLE_IF(grid_cell_row_pos, lv_xml_atoi(value)); + else SET_STYLE_IF(grid_cell_row_span, lv_xml_atoi(value)); + else SET_STYLE_IF(grid_cell_y_align, lv_xml_grid_align_to_enum(value)); +} + #endif /* LV_USE_XML */ diff --git a/src/others/xml/parsers/lv_xml_obj_parser.h b/src/others/xml/parsers/lv_xml_obj_parser.h index d08014560..238881278 100644 --- a/src/others/xml/parsers/lv_xml_obj_parser.h +++ b/src/others/xml/parsers/lv_xml_obj_parser.h @@ -27,7 +27,6 @@ extern "C" { void * lv_xml_obj_create(lv_xml_parser_state_t * state, const char ** attrs); void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs); - /********************** * MACROS **********************/ diff --git a/src/others/xml/parsers/lv_xml_table_parser.c b/src/others/xml/parsers/lv_xml_table_parser.c new file mode 100644 index 000000000..8a6504719 --- /dev/null +++ b/src/others/xml/parsers/lv_xml_table_parser.c @@ -0,0 +1,149 @@ +/** + * @file lv_xml_table_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_table_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_table_cell_ctrl_t table_ctrl_to_enum(const char * txt); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_table_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_table_create(lv_xml_state_get_parent(state)); + + return item; +} + + +void lv_xml_table_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("column_conunt", name)) lv_table_set_column_count(item, lv_xml_atoi(value)); + else if(lv_streq("row_conunt", name)) lv_table_set_row_count(item, lv_xml_atoi(value)); + else if(lv_streq("selected_cell", name)) { + + int32_t value1 = lv_xml_atoi_split(&value, ' '); + int32_t value2 = lv_xml_atoi_split(&value, ' '); + lv_table_set_selected_cell(item, value1, value2); + } + } +} + +void * lv_xml_table_column_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + /*Nothing to create*/ + return lv_xml_state_get_parent(state);; +} + +void lv_xml_table_column_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(state); + LV_UNUSED(attrs); + + lv_obj_t * table = lv_xml_state_get_parent(state); + int32_t column = lv_xml_atoi(lv_xml_get_value_of(attrs, "column")); + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("width", name)) lv_table_set_column_width(table, column, lv_xml_atoi(value)); + } +} + +void * lv_xml_table_cell_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + /*Nothing to create*/ + return lv_xml_state_get_parent(state);; +} + +void lv_xml_table_cell_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(state); + LV_UNUSED(attrs); + + lv_obj_t * table = lv_xml_state_get_parent(state); + int32_t row = lv_xml_atoi(lv_xml_get_value_of(attrs, "row")); + int32_t column = lv_xml_atoi(lv_xml_get_value_of(attrs, "column")); + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("value", name)) lv_table_set_cell_value(table, row, column, value); + if(lv_streq("ctrl", name)) { + lv_table_cell_ctrl_t ctrl = 0; + char buf[256]; + lv_strncpy(buf, value, sizeof(buf)); + char * buf_p = buf; + const char * str; + while((str = lv_xml_split_str(&buf_p, ' ')) != NULL) { + ctrl |= table_ctrl_to_enum(str); + } + + lv_table_add_cell_ctrl(table, row, column, ctrl); + } + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_table_cell_ctrl_t table_ctrl_to_enum(const char * txt) +{ + if(lv_streq("none", txt)) return LV_TABLE_CELL_CTRL_NONE; + if(lv_streq("merge_right", txt)) return LV_TABLE_CELL_CTRL_MERGE_RIGHT; + if(lv_streq("text_crop", txt)) return LV_TABLE_CELL_CTRL_TEXT_CROP; + if(lv_streq("custom_1", txt)) return LV_TABLE_CELL_CTRL_CUSTOM_1; + if(lv_streq("custom_2", txt)) return LV_TABLE_CELL_CTRL_CUSTOM_2; + if(lv_streq("custom_3", txt)) return LV_TABLE_CELL_CTRL_CUSTOM_3; + if(lv_streq("custom_4", txt)) return LV_TABLE_CELL_CTRL_CUSTOM_4; + + LV_LOG_WARN("%s is an unknown value for table's 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_table_parser.h b/src/others/xml/parsers/lv_xml_table_parser.h new file mode 100644 index 000000000..111c1ffaa --- /dev/null +++ b/src/others/xml/parsers/lv_xml_table_parser.h @@ -0,0 +1,43 @@ +/** + * @file lv_xml_table_parser.h + * + */ + +#ifndef LV_TABLE_XML_PARSER_H +#define LV_TABLE_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_table_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_table_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_table_column_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_table_column_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_table_cell_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_table_cell_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TABLE_XML_PARSE_H*/ diff --git a/src/others/xml/parsers/lv_xml_tabview_parser.c b/src/others/xml/parsers/lv_xml_tabview_parser.c index 93c020d59..e1e8947b0 100644 --- a/src/others/xml/parsers/lv_xml_tabview_parser.c +++ b/src/others/xml/parsers/lv_xml_tabview_parser.c @@ -38,17 +38,9 @@ void * lv_xml_tabview_create(lv_xml_parser_state_t * state, const char ** attrs) { + LV_UNUSED(attrs); void * item = lv_tabview_create(lv_xml_state_get_parent(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("active", name)) lv_tabview_set_active(item, lv_xml_atoi(value), 0); - if(lv_streq("tab_bar_position", name)) lv_tabview_set_tab_bar_position(item, lv_xml_dir_string_to_enum_value(value)); - } return item; } @@ -64,17 +56,14 @@ void lv_xml_tabview_apply(lv_xml_parser_state_t * state, const char ** attrs) const char * value = attrs[i + 1]; if(lv_streq("active", name)) lv_tabview_set_active(item, lv_xml_atoi(value), 0); - if(lv_streq("tab_bar_position", name)) lv_tabview_set_tab_bar_position(item, lv_xml_dir_string_to_enum_value(value)); + if(lv_streq("tab_bar_position", name)) lv_tabview_set_tab_bar_position(item, lv_xml_dir_to_enum(value)); } } void * lv_xml_tabview_tab_bar_create(lv_xml_parser_state_t * state, const char ** attrs) { + LV_UNUSED(attrs); void * item = lv_tabview_get_tab_bar(lv_xml_state_get_parent(state)); - - /*Apply the common properties, e.g. width, height, styles flags etc*/ - lv_xml_obj_apply(state, attrs); - return item; } @@ -89,10 +78,6 @@ void * lv_xml_tabview_tab_create(lv_xml_parser_state_t * state, const char ** at { const char * text = lv_xml_get_value_of(attrs, "text"); void * item = lv_tabview_add_tab(lv_xml_state_get_parent(state), text); - - /*Apply the common properties, e.g. width, height, styles flags etc*/ - lv_xml_obj_apply(state, attrs); - return item; } diff --git a/src/widgets/table/lv_table.c b/src/widgets/table/lv_table.c index 948292aa4..6a198484a 100644 --- a/src/widgets/table/lv_table.c +++ b/src/widgets/table/lv_table.c @@ -828,7 +828,10 @@ static void draw_main(lv_event_t * e) /*Align the content to the middle if not cropped*/ bool crop = ctrl & LV_TABLE_CELL_CTRL_TEXT_CROP; - if(crop) txt_flags = LV_TEXT_FLAG_EXPAND; + if(crop) { + txt_flags = LV_TEXT_FLAG_EXPAND; + label_dsc_act.flag |= LV_TEXT_FLAG_EXPAND; + } lv_text_get_size(&txt_size, table->cell_data[cell]->txt, label_dsc_def.font, label_dsc_act.letter_space, label_dsc_act.line_space, diff --git a/src/widgets/table/lv_table.h b/src/widgets/table/lv_table.h index 0d615a1b1..d8df7406b 100644 --- a/src/widgets/table/lv_table.h +++ b/src/widgets/table/lv_table.h @@ -34,6 +34,7 @@ LV_EXPORT_CONST_INT(LV_TABLE_CELL_NONE); **********************/ typedef enum { + LV_TABLE_CELL_CTRL_NONE = 0 << 0, LV_TABLE_CELL_CTRL_MERGE_RIGHT = 1 << 0, LV_TABLE_CELL_CTRL_TEXT_CROP = 1 << 1, LV_TABLE_CELL_CTRL_CUSTOM_1 = 1 << 4, diff --git a/src/widgets/tabview/lv_tabview.c b/src/widgets/tabview/lv_tabview.c index 29e3e2e27..b639d6821 100644 --- a/src/widgets/tabview/lv_tabview.c +++ b/src/widgets/tabview/lv_tabview.c @@ -74,7 +74,6 @@ lv_obj_t * lv_tabview_add_tab(lv_obj_t * obj, const char * name) lv_obj_t * page = lv_obj_create(cont); lv_obj_set_size(page, lv_pct(100), lv_pct(100)); - uint32_t tab_idx = lv_obj_get_child_count(cont); lv_obj_t * tab_bar = lv_tabview_get_tab_bar(obj); @@ -89,8 +88,10 @@ lv_obj_t * lv_tabview_add_tab(lv_obj_t * obj, const char * name) lv_label_set_text(label, name); lv_obj_center(label); - if(tab_idx == 1) { - lv_tabview_set_active(obj, 0, LV_ANIM_OFF); + uint32_t tab_idx = lv_obj_get_child_count(cont) - 1; + lv_tabview_t * tabview = (lv_tabview_t *)obj; + if(tab_idx == tabview->tab_cur) { + lv_tabview_set_active(obj, tab_idx, LV_ANIM_OFF); } return page; @@ -111,19 +112,19 @@ void lv_tabview_set_active(lv_obj_t * obj, uint32_t idx, lv_anim_enable_t anim_e LV_ASSERT_OBJ(obj, MY_CLASS); lv_tabview_t * tabview = (lv_tabview_t *)obj; + tabview->tab_cur = idx; + lv_obj_t * cont = lv_tabview_get_content(obj); lv_obj_t * tab_bar = lv_tabview_get_tab_bar(obj); uint32_t tab_cnt = lv_tabview_get_tab_count(obj); - if(idx >= tab_cnt) { - idx = tab_cnt - 1; - } + if(idx >= tab_cnt) return; /*To be sure lv_obj_get_content_width will return valid value*/ - lv_obj_update_layout(obj); - if(cont == NULL) return; + lv_obj_update_layout(obj); + if((tabview->tab_pos & LV_DIR_VER) != 0) { int32_t gap = lv_obj_get_style_pad_column(cont, LV_PART_MAIN); int32_t w = lv_obj_get_content_width(cont); @@ -149,7 +150,6 @@ void lv_tabview_set_active(lv_obj_t * obj, uint32_t idx, lv_anim_enable_t anim_e button = lv_obj_get_child_by_type(tab_bar, (int32_t)i, &lv_button_class); } - tabview->tab_cur = idx; } void lv_tabview_set_tab_bar_position(lv_obj_t * obj, lv_dir_t dir) @@ -233,7 +233,6 @@ void lv_tabview_set_tab_bar_size(lv_obj_t * obj, int32_t size) else { lv_obj_set_width(tab_bar, size); } - } uint32_t lv_tabview_get_tab_active(lv_obj_t * obj) diff --git a/tests/ref_imgs/widgets/table_1.png b/tests/ref_imgs/widgets/table_1.png index a702cf3c1..ba465d5ce 100644 Binary files a/tests/ref_imgs/widgets/table_1.png and b/tests/ref_imgs/widgets/table_1.png differ diff --git a/tests/ref_imgs/xml/lv_chart.png b/tests/ref_imgs/xml/lv_chart.png new file mode 100644 index 000000000..51c01d916 Binary files /dev/null and b/tests/ref_imgs/xml/lv_chart.png differ diff --git a/tests/ref_imgs/xml/lv_dropdown.png b/tests/ref_imgs/xml/lv_dropdown.png new file mode 100644 index 000000000..bf89f7c9b Binary files /dev/null and b/tests/ref_imgs/xml/lv_dropdown.png differ diff --git a/tests/ref_imgs/xml/lv_image.png b/tests/ref_imgs/xml/lv_image.png new file mode 100644 index 000000000..4d85b3871 Binary files /dev/null and b/tests/ref_imgs/xml/lv_image.png differ diff --git a/tests/ref_imgs/xml/lv_table.png b/tests/ref_imgs/xml/lv_table.png new file mode 100644 index 000000000..03856a1a9 Binary files /dev/null and b/tests/ref_imgs/xml/lv_table.png differ diff --git a/tests/ref_imgs/xml/lv_tabview.png b/tests/ref_imgs/xml/lv_tabview.png new file mode 100644 index 000000000..51c3fb389 Binary files /dev/null and b/tests/ref_imgs/xml/lv_tabview.png differ diff --git a/tests/ref_imgs_vg_lite/widgets/table_1.png b/tests/ref_imgs_vg_lite/widgets/table_1.png index d94818d30..d84921e82 100644 Binary files a/tests/ref_imgs_vg_lite/widgets/table_1.png and b/tests/ref_imgs_vg_lite/widgets/table_1.png differ diff --git a/tests/ref_imgs_vg_lite/xml/lv_chart.png b/tests/ref_imgs_vg_lite/xml/lv_chart.png new file mode 100644 index 000000000..fee22593b Binary files /dev/null and b/tests/ref_imgs_vg_lite/xml/lv_chart.png differ diff --git a/tests/ref_imgs_vg_lite/xml/lv_dropdown.png b/tests/ref_imgs_vg_lite/xml/lv_dropdown.png new file mode 100644 index 000000000..b3dce7077 Binary files /dev/null and b/tests/ref_imgs_vg_lite/xml/lv_dropdown.png differ diff --git a/tests/ref_imgs_vg_lite/xml/lv_image.png b/tests/ref_imgs_vg_lite/xml/lv_image.png new file mode 100644 index 000000000..ba552ec4b Binary files /dev/null and b/tests/ref_imgs_vg_lite/xml/lv_image.png differ diff --git a/tests/ref_imgs_vg_lite/xml/lv_table.png b/tests/ref_imgs_vg_lite/xml/lv_table.png new file mode 100644 index 000000000..75219f952 Binary files /dev/null and b/tests/ref_imgs_vg_lite/xml/lv_table.png differ diff --git a/tests/ref_imgs_vg_lite/xml/lv_tabview.png b/tests/ref_imgs_vg_lite/xml/lv_tabview.png new file mode 100644 index 000000000..1e4708456 Binary files /dev/null and b/tests/ref_imgs_vg_lite/xml/lv_tabview.png differ diff --git a/tests/src/test_cases/xml/test_xml_chart.c b/tests/src/test_cases/xml/test_xml_chart.c new file mode 100644 index 000000000..657500463 --- /dev/null +++ b/tests/src/test_cases/xml/test_xml_chart.c @@ -0,0 +1,71 @@ +#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_chart_with_attrs(void) +{ + lv_obj_t * scr = lv_screen_active(); + + const char * chart_attrs[] = { + "width", "200", + "height", "100", + "type", "bar", + "point_count", "8", + NULL, NULL, + }; + + lv_obj_t * chart = lv_xml_create(scr, "lv_chart", chart_attrs); + lv_obj_center(chart); + + const char * primary_y_axis_attrs[] = { + "axis", "primary_y", + "range", "0 40", + NULL, NULL, + }; + lv_xml_create(chart, "lv_chart-axis", primary_y_axis_attrs); + + const char * series_1_axis_attrs[] = { + "axis", "primary_y", + "color", "0xff0000", + "values", "10 20 30 10 20 30", + NULL, NULL, + }; + + lv_chart_series_t * ser1 = lv_xml_create(chart, "lv_chart-series", series_1_axis_attrs); + + const char * series_2_axis_attrs[] = { + "axis", "secondary_y", + "color", "0x00ff00", + "values", "90 80", + NULL, NULL, + }; + + lv_chart_series_t * ser2 = lv_xml_create(chart, "lv_chart-series", series_2_axis_attrs); + + const char * secondary_y_axis_attrs[] = { + "axis", "secondary_y", + "range", "70 90", + NULL, NULL, + }; + lv_xml_create(chart, "lv_chart-axis", secondary_y_axis_attrs); + + lv_chart_set_next_value(chart, ser1, 40); + lv_chart_set_next_value(chart, ser2, 70); + + + TEST_ASSERT_EQUAL_SCREENSHOT("xml/lv_chart.png"); +} + +#endif diff --git a/tests/src/test_cases/xml/test_xml_dropdown.c b/tests/src/test_cases/xml/test_xml_dropdown.c new file mode 100644 index 000000000..0aea1b214 --- /dev/null +++ b/tests/src/test_cases/xml/test_xml_dropdown.c @@ -0,0 +1,43 @@ +#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_tabview_with_attrs(void) +{ + lv_obj_t * scr = lv_screen_active(); + + const char * dropdown_attrs[] = { + "options", "First\nSecond\nThird", + "text", "Select", + "selected", "1", + "style_bg_color", "0xaaaaff", + NULL, NULL, + }; + + lv_obj_t * dropdown = lv_xml_create(scr, "lv_dropdown", dropdown_attrs); + lv_obj_center(dropdown); + lv_dropdown_open(dropdown); + + const char * list_attrs[] = { + "style_bg_color", "0xffaaaa", + NULL, NULL, + }; + lv_xml_create(dropdown, "lv_dropdown-list", list_attrs); + + + TEST_ASSERT_EQUAL_SCREENSHOT("xml/lv_dropdown.png"); +} + +#endif diff --git a/tests/src/test_cases/xml/test_xml_image.c b/tests/src/test_cases/xml/test_xml_image.c new file mode 100644 index 000000000..f7aa06b7d --- /dev/null +++ b/tests/src/test_cases/xml/test_xml_image.c @@ -0,0 +1,53 @@ +#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_tabview_with_attrs(void) +{ + LV_IMAGE_DECLARE(test_img_lvgl_logo_png); + lv_xml_register_image("logo", &test_img_lvgl_logo_png); + lv_obj_t * scr = lv_screen_active(); + + const char * image1_attrs[] = { + "src", "logo", + "rotation", "300", + "scale_x", "300", + "scale_y", "500", + "x", "50", + "y", "50", + NULL, NULL, + }; + + lv_xml_create(scr, "lv_image", image1_attrs); + + const char * image2_attrs[] = { + "src", "logo", + "inner_align", "bottom_right", + "style_bg_color", "0xff0000", + "style_bg_opa", "100", + "x", "200", + "y", "10", + "width", "150", + "height", "100", + NULL, NULL, + }; + + lv_xml_create(scr, "lv_image", image2_attrs); + + + TEST_ASSERT_EQUAL_SCREENSHOT("xml/lv_image.png"); +} + +#endif diff --git a/tests/src/test_cases/xml/test_xml_table.c b/tests/src/test_cases/xml/test_xml_table.c new file mode 100644 index 000000000..28ce82f39 --- /dev/null +++ b/tests/src/test_cases/xml/test_xml_table.c @@ -0,0 +1,69 @@ +#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_table_with_attrs(void) +{ + lv_obj_t * scr = lv_screen_active(); + + const char * table_attrs[] = { + "width", "content", + "style_border_side:items", "full", + NULL, NULL, + }; + + lv_obj_t * table = lv_xml_create(scr, "lv_table", table_attrs); + lv_obj_center(table); + + const char * column_1_attrs[] = { + "column", "0", + "width", "80", + NULL, NULL, + }; + lv_xml_create(table, "lv_table-column", column_1_attrs); + + const char * cell_1_2_attrs[] = { + "row", "1", + "column", "2", + "value", "A", + NULL, NULL, + }; + lv_xml_create(table, "lv_table-cell", cell_1_2_attrs); + + + const char * cell_2_0_attrs[] = { + "row", "2", + "column", "0", + "value", "hello this a long text which should be cropped", + "ctrl", "text_crop merge_right", + NULL, NULL, + }; + + lv_xml_create(table, "lv_table-cell", cell_2_0_attrs); + + const char * cell_3_0_attrs[] = { + "row", "3", + "column", "0", + "value", "wrap this text", + NULL, NULL, + }; + + lv_xml_create(table, "lv_table-cell", cell_3_0_attrs); + + + TEST_ASSERT_EQUAL_SCREENSHOT("xml/lv_table.png"); +} + +#endif diff --git a/tests/src/test_cases/xml/test_xml_tabview.c b/tests/src/test_cases/xml/test_xml_tabview.c new file mode 100644 index 000000000..af334d548 --- /dev/null +++ b/tests/src/test_cases/xml/test_xml_tabview.c @@ -0,0 +1,72 @@ +#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_tabview_with_attrs(void) +{ + lv_obj_t * scr = lv_screen_active(); + + const char * tabview_attrs[] = { + "width", "300", + "height", "250", + "tab_bar_position", "bottom", + "active", "1", + NULL, NULL, + }; + + lv_obj_t * tabview = lv_xml_create(scr, "lv_tabview", tabview_attrs); + lv_obj_center(tabview); + + const char * tabbar_attrs[] = { + "style_pad_left", "100", + "height", "100", + NULL, NULL, + }; + lv_obj_t * tabbar = lv_xml_create(tabview, "lv_tabview-tab_bar", tabbar_attrs); + + const char * tabbar_label_attrs[] = { + "ignore_layout", "true", + "text", "Hello\ntabview!", + "x", "-90", + "style_text_align", "right", + "align", "left_mid", + NULL, NULL, + }; + lv_xml_create(tabbar, "lv_label", tabbar_label_attrs); + + + const char * tab1_attrs[] = { + "text", "Tab1", + NULL, NULL, + }; + lv_obj_t * tab1 = lv_xml_create(tabview, "lv_tabview-tab", tab1_attrs); + + lv_obj_t * label1 = lv_label_create(tab1); + lv_label_set_text(label1, "This is the first tab"); + + const char * tab2_attrs[] = { + "text", "Tab2", + NULL, NULL, + }; + lv_obj_t * tab2 = lv_xml_create(tabview, "lv_tabview-tab", tab2_attrs); + + lv_obj_t * label2 = lv_label_create(tab2); + lv_label_set_text(label2, "This is the second tab"); + + + TEST_ASSERT_EQUAL_SCREENSHOT("xml/lv_tabview.png"); +} + +#endif diff --git a/xmls/globals.xml b/xmls/globals.xml index c4e6e7278..acbdad942 100644 --- a/xmls/globals.xml +++ b/xmls/globals.xml @@ -1,5 +1,3 @@ - - @@ -18,6 +16,7 @@ + @@ -41,5 +40,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmls/lv_chart.xml b/xmls/lv_chart.xml index cc7ab250a..9b275c5e7 100644 --- a/xmls/lv_chart.xml +++ b/xmls/lv_chart.xml @@ -42,9 +42,7 @@ - - - + diff --git a/xmls/lv_dropdown.xml b/xmls/lv_dropdown.xml index 3c48ff553..0d756d59d 100644 --- a/xmls/lv_dropdown.xml +++ b/xmls/lv_dropdown.xml @@ -7,18 +7,10 @@ Example - - - - - - - - - - - - + + + + diff --git a/xmls/lv_image.xml b/xmls/lv_image.xml new file mode 100644 index 000000000..445df68a8 --- /dev/null +++ b/xmls/lv_image.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/xmls/lv_obj.xml b/xmls/lv_obj.xml index 9449e689b..70cf72abf 100644 --- a/xmls/lv_obj.xml +++ b/xmls/lv_obj.xml @@ -1,71 +1,92 @@ - - - + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/xmls/lv_table.xml b/xmls/lv_table.xml index 799f84a44..5eb148aa1 100644 --- a/xmls/lv_table.xml +++ b/xmls/lv_table.xml @@ -17,11 +17,10 @@ - - + - + @@ -39,12 +38,8 @@ - - - - - - + + diff --git a/xmls/lv_tabview.xml b/xmls/lv_tabview.xml index b7ddbc258..8aa360f7e 100644 --- a/xmls/lv_tabview.xml +++ b/xmls/lv_tabview.xml @@ -9,16 +9,12 @@ Example - - - - - - + + - +