1 /**
2  * @file lv_xml_chart_parser.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "lv_xml_chart_parser.h"
10 #if LV_USE_XML
11 
12 #include "../../../lvgl.h"
13 #include "../../../lvgl_private.h"
14 
15 /*********************
16  *      DEFINES
17  *********************/
18 
19 /**********************
20  *      TYPEDEFS
21  **********************/
22 
23 /**********************
24  *  STATIC PROTOTYPES
25  **********************/
26 static lv_chart_type_t chart_type_to_enum(const char * txt);
27 static lv_chart_update_mode_t chart_update_mode_to_enum(const char * txt);
28 static lv_chart_axis_t chart_axis_to_enum(const char * txt);
29 
30 /**********************
31  *  STATIC VARIABLES
32  **********************/
33 
34 /**********************
35  *      MACROS
36  **********************/
37 
38 /**********************
39  *   GLOBAL FUNCTIONS
40  **********************/
41 
lv_xml_chart_create(lv_xml_parser_state_t * state,const char ** attrs)42 void * lv_xml_chart_create(lv_xml_parser_state_t * state, const char ** attrs)
43 {
44     LV_UNUSED(attrs);
45     void * item = lv_chart_create(lv_xml_state_get_parent(state));
46 
47     return item;
48 }
49 
50 
lv_xml_chart_apply(lv_xml_parser_state_t * state,const char ** attrs)51 void lv_xml_chart_apply(lv_xml_parser_state_t * state, const char ** attrs)
52 {
53     void * item = lv_xml_state_get_item(state);
54 
55     lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/
56 
57     for(int i = 0; attrs[i]; i += 2) {
58         const char * name = attrs[i];
59         const char * value = attrs[i + 1];
60 
61         if(lv_streq("point_count", name)) lv_chart_set_point_count(item, lv_xml_atoi(value));
62         else if(lv_streq("type", name)) lv_chart_set_type(item, chart_type_to_enum(value));
63         else if(lv_streq("update_mode", name)) lv_chart_set_update_mode(item, chart_update_mode_to_enum(value));
64         else if(lv_streq("div_line_count", name)) {
65 
66             int32_t value1 = lv_xml_atoi_split(&value, ' ');
67             int32_t value2 = lv_xml_atoi_split(&value, ' ');
68             lv_chart_set_div_line_count(item, value1, value2);
69         }
70     }
71 }
72 
lv_xml_chart_series_create(lv_xml_parser_state_t * state,const char ** attrs)73 void * lv_xml_chart_series_create(lv_xml_parser_state_t * state, const char ** attrs)
74 {
75     const char * color = lv_xml_get_value_of(attrs, "color");
76     const char * axis = lv_xml_get_value_of(attrs, "axis");
77     void * item = lv_chart_add_series(lv_xml_state_get_parent(state), lv_color_hex(lv_xml_strtol(color, NULL, 16)),
78                                       chart_axis_to_enum(axis));
79     return item;
80 }
81 
lv_xml_chart_series_apply(lv_xml_parser_state_t * state,const char ** attrs)82 void lv_xml_chart_series_apply(lv_xml_parser_state_t * state, const char ** attrs)
83 {
84     LV_UNUSED(state);
85     LV_UNUSED(attrs);
86 
87     lv_obj_t * chart = lv_xml_state_get_parent(state);
88     lv_chart_series_t * ser = lv_xml_state_get_item(state);
89 
90     for(int i = 0; attrs[i]; i += 2) {
91         const char * name = attrs[i];
92         const char * value = attrs[i + 1];
93 
94         if(lv_streq("values", name)) {
95             while(value[0] != '\0') {
96                 int32_t v = lv_xml_atoi_split(&value, ' ');
97                 lv_chart_set_next_value(chart, ser, v);
98             }
99         }
100     }
101 }
102 
lv_xml_chart_cursor_create(lv_xml_parser_state_t * state,const char ** attrs)103 void * lv_xml_chart_cursor_create(lv_xml_parser_state_t * state, const char ** attrs)
104 {
105     const char * color = lv_xml_get_value_of(attrs, "color");
106     const char * dir = lv_xml_get_value_of(attrs, "dir");
107     void * item = lv_chart_add_cursor(lv_xml_state_get_parent(state), lv_color_hex(lv_xml_strtol(color, NULL, 16)),
108                                       lv_xml_dir_to_enum(dir));
109 
110     return item;
111 }
112 
lv_xml_chart_cursor_apply(lv_xml_parser_state_t * state,const char ** attrs)113 void lv_xml_chart_cursor_apply(lv_xml_parser_state_t * state, const char ** attrs)
114 {
115     LV_UNUSED(state);
116     LV_UNUSED(attrs);
117 
118     lv_obj_t * chart = lv_xml_state_get_parent(state);
119     lv_chart_cursor_t * cursor = lv_xml_state_get_item(state);
120 
121     for(int i = 0; attrs[i]; i += 2) {
122         const char * name = attrs[i];
123         const char * value = attrs[i + 1];
124 
125 
126         if(lv_streq("pos", name)) {
127             int32_t x = lv_xml_atoi_split(&value, ' ');
128             int32_t y = lv_xml_atoi_split(&value, ' ');
129             lv_point_t p = {x, y};
130             lv_chart_set_cursor_pos(chart, cursor, &p);
131         }
132     }
133 }
134 
lv_xml_chart_axis_create(lv_xml_parser_state_t * state,const char ** attrs)135 void * lv_xml_chart_axis_create(lv_xml_parser_state_t * state, const char ** attrs)
136 {
137     LV_UNUSED(attrs);
138 
139     /*Nothing to create*/
140     return lv_xml_state_get_parent(state);;
141 }
142 
lv_xml_chart_axis_apply(lv_xml_parser_state_t * state,const char ** attrs)143 void lv_xml_chart_axis_apply(lv_xml_parser_state_t * state, const char ** attrs)
144 {
145     LV_UNUSED(state);
146     LV_UNUSED(attrs);
147 
148     lv_obj_t * chart = lv_xml_state_get_parent(state);
149     lv_chart_axis_t axis = chart_axis_to_enum(lv_xml_get_value_of(attrs, "axis"));
150 
151     for(int i = 0; attrs[i]; i += 2) {
152         const char * name = attrs[i];
153         const char * value = attrs[i + 1];
154 
155         if(lv_streq("range", name)) {
156             int32_t min_val = lv_xml_atoi_split(&value, ' ');
157             int32_t max_val = lv_xml_atoi_split(&value, ' ');
158             lv_chart_set_range(chart, axis, min_val, max_val);
159         }
160     }
161 }
162 
163 /**********************
164  *   STATIC FUNCTIONS
165  **********************/
166 
chart_type_to_enum(const char * txt)167 static lv_chart_type_t chart_type_to_enum(const char * txt)
168 {
169     if(lv_streq("none", txt)) return LV_CHART_TYPE_NONE;
170     if(lv_streq("line", txt)) return LV_CHART_TYPE_LINE;
171     if(lv_streq("bar", txt)) return LV_CHART_TYPE_BAR;
172     if(lv_streq("scatter", txt)) return LV_CHART_TYPE_SCATTER;
173 
174     LV_LOG_WARN("%s is an unknown value for chart's chart_type", txt);
175     return 0; /*Return 0 in lack of a better option. */
176 }
177 
chart_update_mode_to_enum(const char * txt)178 static lv_chart_update_mode_t chart_update_mode_to_enum(const char * txt)
179 {
180     if(lv_streq("shift", txt)) return LV_CHART_UPDATE_MODE_SHIFT;
181     if(lv_streq("circular", txt)) return LV_CHART_UPDATE_MODE_CIRCULAR;
182 
183     LV_LOG_WARN("%s is an unknown value for chart's chart_update_mode", txt);
184     return 0; /*Return 0 in lack of a better option. */
185 }
186 
chart_axis_to_enum(const char * txt)187 static lv_chart_axis_t chart_axis_to_enum(const char * txt)
188 {
189     if(lv_streq("primary_x", txt)) return LV_CHART_AXIS_PRIMARY_X;
190     if(lv_streq("primary_y", txt)) return LV_CHART_AXIS_PRIMARY_Y;
191     if(lv_streq("secondary_x", txt)) return LV_CHART_AXIS_SECONDARY_X;
192     if(lv_streq("secondary_y", txt)) return LV_CHART_AXIS_SECONDARY_Y;
193 
194     LV_LOG_WARN("%s is an unknown value for chart's chart_axis", txt);
195     return 0; /*Return 0 in lack of a better option. */
196 }
197 
198 #endif /* LV_USE_XML */
199