diff --git a/docs/src/details/auxiliary-modules/observer/observer.rst b/docs/src/details/auxiliary-modules/observer/observer.rst
index 86c0a41ebe..5981d30458 100644
--- a/docs/src/details/auxiliary-modules/observer/observer.rst
+++ b/docs/src/details/auxiliary-modules/observer/observer.rst
@@ -372,7 +372,7 @@ integer value:
- Drop-Down
- Roller
- Slider
- - Scale Section Min/Max value
++ - Scale Section Min/Max values
Any number of Observers can be created for a single Widget, each bound to ONE of
the above properties.
@@ -521,6 +521,9 @@ The only difference is that in the bind function both the spangroup and the span
:cpp:expr:`lv_spangroup_bind_span_text(spangroup, span1, &subject, format_string)`
+Note that before calling :cpp:expr:`lv_spangroup_delete_span` :cpp:expr:`lv_observer_remove`
+needs to be called manually as LVGL can't remove the binding automatically.
+
Arc Widgets
~~~~~~~~~~~
@@ -578,10 +581,10 @@ Scale's Section
This method of subscribing to an integer Subject affects a Section of a Scale Widget's integer
minimum or maximum values directly. Note that this is a one way binding (Subject ==> Widget)
-as the Scale Section's are not interactive.
+as the Scale Section's boundaries are not interactive.
(Requires :c:macro:`LV_USE_SCALE` to be configured to ``1``.)
-It support only integer subjects.
+It supports only integer subjects.
- :cpp:expr:`lv_scale_bind_section_min_value(scale, section1, &subject)`
- :cpp:expr:`lv_scale_bind_section_max_value(scale, section1, &subject)`
diff --git a/examples/others/xml/view.xml b/examples/others/xml/view.xml
index 750d161030..5facef5cd3 100644
--- a/examples/others/xml/view.xml
+++ b/examples/others/xml/view.xml
@@ -9,17 +9,26 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
\ No newline at end of file
diff --git a/src/others/observer/lv_observer.h b/src/others/observer/lv_observer.h
index 742a1f8ffc..e7c7b0c316 100644
--- a/src/others/observer/lv_observer.h
+++ b/src/others/observer/lv_observer.h
@@ -548,7 +548,7 @@ lv_observer_t * lv_label_bind_text(lv_obj_t * obj, lv_subject_t * subject, const
#if LV_USE_LABEL
/**
- * Bind an integer, string, or pointer Subject to a Label.
+ * Bind an integer, string, or pointer Subject to a Spangroup's Span.
* @param obj pointer to Spangroup
* @param span pointer to Span
* @param subject pointer to Subject
@@ -607,7 +607,7 @@ lv_observer_t * lv_dropdown_bind_value(lv_obj_t * obj, lv_subject_t * subject);
/**
* Bind an integer subject to a scales section minimum value
- * @param obj pointer to an Scale
+ * @param obj pointer to a Scale
* @param section pointer to a Scale section
* @param subject pointer to a Subject
* @return pointer to newly-created Observer
diff --git a/src/others/xml/lv_xml_style.c b/src/others/xml/lv_xml_style.c
index c16d764e6b..0f797eaf5b 100644
--- a/src/others/xml/lv_xml_style.c
+++ b/src/others/xml/lv_xml_style.c
@@ -290,7 +290,7 @@ lv_result_t lv_xml_style_register(lv_xml_component_scope_t * scope, const char *
if(value[c] == ' ') item_cnt++;
}
- int32_t * dsc_array = lv_malloc((item_cnt + 1) * sizeof(int32_t)); /*+1 for LV_GRID_TEMPLATE_LAST*/
+ int32_t * dsc_array = lv_malloc((item_cnt + 2) * sizeof(int32_t)); /*+2 for LV_GRID_TEMPLATE_LAST*/
char * value_buf = (char *)value;
item_cnt = 0;
diff --git a/src/others/xml/lv_xml_widget.h b/src/others/xml/lv_xml_widget.h
index 96690f0b5b..f09d154fab 100644
--- a/src/others/xml/lv_xml_widget.h
+++ b/src/others/xml/lv_xml_widget.h
@@ -16,7 +16,6 @@ extern "C" {
#include "../../misc/lv_types.h"
#if LV_USE_XML
-#include "lv_xml.h"
#include "lv_xml_utils.h"
/**********************
diff --git a/src/others/xml/parsers/lv_xml_obj_parser.c b/src/others/xml/parsers/lv_xml_obj_parser.c
index a1fc975d08..d1d617325b 100644
--- a/src/others/xml/parsers/lv_xml_obj_parser.c
+++ b/src/others/xml/parsers/lv_xml_obj_parser.c
@@ -900,7 +900,7 @@ static void apply_styles(lv_xml_parser_state_t * state, lv_obj_t * obj, const ch
if(value[i] == ' ') item_cnt++;
}
- int32_t * dsc_array = lv_malloc((item_cnt + 1) * sizeof(int32_t)); /*+1 for LV_GRID_TEMPLATE_LAST*/
+ int32_t * dsc_array = lv_malloc((item_cnt + 2) * sizeof(int32_t)); /*+2 for LV_GRID_TEMPLATE_LAST*/
char * value_buf = (char *)value;
item_cnt = 0;
diff --git a/src/others/xml/parsers/lv_xml_spangroup_parser.c b/src/others/xml/parsers/lv_xml_spangroup_parser.c
index c35ad6f6aa..8f1c51cc34 100644
--- a/src/others/xml/parsers/lv_xml_spangroup_parser.c
+++ b/src/others/xml/parsers/lv_xml_spangroup_parser.c
@@ -25,7 +25,6 @@
**********************/
static lv_span_overflow_t spangroup_overflow_to_enum(const char * txt);
-static void free_fmt_event_cb(lv_event_t * e);
/**********************
* STATIC VARIABLES
@@ -97,7 +96,7 @@ void lv_xml_spangroup_span_apply(lv_xml_parser_state_t * state, const char ** at
const char * fmt = lv_xml_get_value_of(attrs, "bind_text-fmt");
if(fmt) {
fmt = lv_strdup(fmt);
- lv_obj_add_event_cb(spangroup, free_fmt_event_cb, LV_EVENT_DELETE, (void *) fmt);
+ lv_obj_add_event_cb(spangroup, lv_event_free_user_data_cb, LV_EVENT_DELETE, (void *) fmt);
}
lv_spangroup_bind_span_text(spangroup, span, subject, fmt);
}
@@ -117,10 +116,4 @@ static lv_span_overflow_t spangroup_overflow_to_enum(const char * txt)
return 0; /*Return 0 in lack of a better option. */
}
-static void free_fmt_event_cb(lv_event_t * e)
-{
- void * fmt = lv_event_get_user_data(e);
- lv_free(fmt);
-}
-
#endif /* LV_USE_XML */
diff --git a/src/others/xml/parsers/lv_xml_textarea_parser.c b/src/others/xml/parsers/lv_xml_textarea_parser.c
index cea2c7efc4..4ce0fbe7a4 100644
--- a/src/others/xml/parsers/lv_xml_textarea_parser.c
+++ b/src/others/xml/parsers/lv_xml_textarea_parser.c
@@ -56,7 +56,7 @@ void lv_xml_textarea_apply(lv_xml_parser_state_t * state, const char ** attrs)
if(lv_streq("text", name)) lv_textarea_set_text(item, value);
- else if(lv_streq("placeholder", name)) lv_textarea_set_placeholder_text(item, value);
+ else if(lv_streq("placeholder_text", name)) lv_textarea_set_placeholder_text(item, value);
else if(lv_streq("one_line", name)) lv_textarea_set_one_line(item, lv_xml_to_bool(value));
else if(lv_streq("password_mode", name)) lv_textarea_set_password_mode(item, lv_xml_to_bool(value));
else if(lv_streq("password_show_time", name)) lv_textarea_set_password_show_time(item, lv_xml_atoi(value));
diff --git a/src/widgets/label/lv_label.h b/src/widgets/label/lv_label.h
index 202427b5d4..b71cc7bafa 100644
--- a/src/widgets/label/lv_label.h
+++ b/src/widgets/label/lv_label.h
@@ -97,7 +97,7 @@ void lv_label_set_text(lv_obj_t * obj, const char * text);
* @code
* lv_label_set_text_fmt(label1, "%d user", user_num);
* @endcode
- * @note It ignores `LV_USE_ARABIC_PERSIAN_CHARS`
+ * @note If `LV_USE_ARABIC_PERSIAN_CHARS` is enabled the text will be modified to have the correct Arabic characters in it.
*/
void lv_label_set_text_fmt(lv_obj_t * obj, const char * fmt, ...) LV_FORMAT_ATTRIBUTE(2, 3);
diff --git a/src/widgets/span/lv_span.c b/src/widgets/span/lv_span.c
index dfb6b187c3..acac2f9c88 100644
--- a/src/widgets/span/lv_span.c
+++ b/src/widgets/span/lv_span.c
@@ -209,11 +209,14 @@ void lv_span_set_text_fmt(lv_span_t * span, const char * fmt, ...)
va_start(args, fmt);
char * text = lv_text_set_text_vfmt(fmt, args);
LV_ASSERT_MALLOC(text);
- if(text == NULL) return;
+ if(text == NULL) {
+ va_end(args);
+ return;
+ }
va_end(args);
- if(span->txt == NULL && span->static_flag) {
+ if(span->txt && !span->static_flag) {
lv_free(span->txt);
}
@@ -267,11 +270,14 @@ void lv_spangroup_set_span_text_fmt(lv_obj_t * obj, lv_span_t * span, const char
va_start(args, fmt);
char * text = lv_text_set_text_vfmt(fmt, args);
LV_ASSERT_MALLOC(text);
- if(text == NULL) return;
+ if(text == NULL) {
+ va_end(args);
+ return;
+ }
va_end(args);
- if(span->txt == NULL && span->static_flag) {
+ if(span->txt && !span->static_flag) {
lv_free(span->txt);
}
diff --git a/src/widgets/span/lv_span.h b/src/widgets/span/lv_span.h
index 38b211da4b..95f1599bbe 100644
--- a/src/widgets/span/lv_span.h
+++ b/src/widgets/span/lv_span.h
@@ -75,6 +75,9 @@ lv_span_t * lv_spangroup_add_span(lv_obj_t * obj);
* Remove the span from the spangroup and free memory.
* @param obj pointer to a spangroup object.
* @param span pointer to a span.
+ * @note Note that before calling `lv_spangroup_delete_span`
+ * `lv_observer_remove` needs to be called manually as LVGL can't remove the
+ * binding automatically.
*/
void lv_spangroup_delete_span(lv_obj_t * obj, lv_span_t * span);
@@ -100,7 +103,7 @@ void lv_span_set_text(lv_span_t * span, const char * text);
* @param span pointer to a span.
* @param fmt `printf`-like format string
*/
-void lv_span_set_text_fmt(lv_span_t * span, const char * fmt, ...);
+void lv_span_set_text_fmt(lv_span_t * span, const char * fmt, ...) LV_FORMAT_ATTRIBUTE(2, 3);
/**
* Set a static text. It will not be saved by the span so the 'text' variable
@@ -136,7 +139,7 @@ void lv_spangroup_set_span_text_static(lv_obj_t * obj, lv_span_t * span, const c
* @param span pointer to a span.
* @param fmt `printf`-like format string
*/
-void lv_spangroup_set_span_text_fmt(lv_obj_t * obj, lv_span_t * span, const char * fmt, ...);
+void lv_spangroup_set_span_text_fmt(lv_obj_t * obj, lv_span_t * span, const char * fmt, ...) LV_FORMAT_ATTRIBUTE(3, 4);
/**
* Set a static text. It will not be saved by the span so the 'text' variable
diff --git a/xmls/lv_spangroup.xml b/xmls/lv_spangroup.xml
index 20f1bff09f..5335174058 100644
--- a/xmls/lv_spangroup.xml
+++ b/xmls/lv_spangroup.xml
@@ -1,35 +1,35 @@
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
\ No newline at end of file