diff --git a/docs/src/details/auxiliary-modules/observer/observer.rst b/docs/src/details/auxiliary-modules/observer/observer.rst index 0a65de2275..064a1ff07d 100644 --- a/docs/src/details/auxiliary-modules/observer/observer.rst +++ b/docs/src/details/auxiliary-modules/observer/observer.rst @@ -361,13 +361,9 @@ integer value: - flag (or OR-ed combination of flags) from from the ``LV_OBJ_FLAG_...`` enumeration values; - state (or OR-ed combination of states) from the ``LV_STATE_...`` enumeration values; -- text value for - +- text and/or integer values for - Label - Span; - -- integer value for these Widget types: - - Arc - Drop-Down - Roller @@ -457,141 +453,11 @@ Subject's value to be set to ``1`` or ``0`` respectively. - :cpp:expr:`lv_obj_bind_checked(widget, &subject)` +Specific Widget Types +~~~~~~~~~~~~~~~~~~~~~ -Label Widgets -~~~~~~~~~~~~~ - -.. |deg| unicode:: U+000B0 .. DEGREE SIGN - -This method of subscribing to an integer Subject affects a Label Widget's -``text``. The Subject can be an STRING, POINTER or INTEGER type. - -When the subscribing occurs, and each time the Subject's value is changed thereafter, -the Subject's value is used to update the Label's text as follows: - -:string Subject: Subject's string is used to directly update the Label's text. - -:pointer Subject: If NULL is passed as the ``format_string`` argument when - subscribing, the Subject's pointer value is assumed to point to a - NUL-terminated string. and is used to directly update the Label's - text. See :ref:`observer_format_string` for other options. - -:integer Subject: Subject's integer value is used with the ``format_string`` argument. - See See :ref:`observer_format_string` for details. - -Note that this is a one-way binding (Subject ===> Widget). - -- :cpp:expr:`lv_label_bind_text(label, &subject, format_string)` - -.. _observer_format_string: - -The ``format_string`` Argument -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The ``format_string`` argument is optional and if provided, must contain exactly 1 -printf-like format specifier and be one of the following: - -:string or pointer Subject: "%s" to format the new pointer value as a string or "%p" - to format the pointer as a pointer (typically the - pointer's address value is spelled out with 4, 8 or 16 - hexadecimal characters depending on the platform). - -:integer Subject: "%d" format specifier (``"%" PRIdxx`` --- a - cross-platform equivalent where ``xx`` can be ``8``, - ``16``, ``32`` or ``64``, depending on the platform). - -:float Subject: "%f" format specifier, or e.g. "%0.2f" to display two digits after the decimal point. - - -If ``NULL`` is passed for the ``format_string`` argument: - -:string or pointer Subject: Updates expect the pointer to point to a NUL-terminated string. -:integer Subject: The Label will simply display the number. Equivalent to "%d". -:float Subject: The Label will display the value with "%0.1f" format string. - -**Example:** "%d |deg|\C" - - -Spangroup's Span -~~~~~~~~~~~~~~~~ - -Very similar to Label-text binding, a Span's text can be bound to a subject as well. - -The only difference is that in the bind function both the Spangroup and the Span need to be specified: - - :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 -~~~~~~~~~~~ - -This method of subscribing to an integer Subject affects an Arc Widget's integer -value directly. Note that this is a two-way binding (Subject <===> Widget) so an end -user's direct interaction with the Arc Widget updates the Subject's value and vice -versa. (Requires :c:macro:`LV_USE_ARC` to be configured to ``1``.) - -It support integer and float subjects. - - -- :cpp:expr:`lv_arc_bind_value(arc, &subject)` - - -Slider Widgets -~~~~~~~~~~~~~~ - -This method of subscribing to an integer Subject affects a Slider Widget's integer -value directly. Note that this is a two-way binding (Subject <===> Widget) so an end -user's direct interaction with the Slider Widget updates the Subject's value and vice -versa. (Requires :c:macro:`LV_USE_SLIDER` to be configured to ``1``.) - -It support integer and float subjects. - -- :cpp:expr:`lv_slider_bind_value(slider, &subject)` - - -Roller Widgets -~~~~~~~~~~~~~~ - -This method of subscribing to an integer Subject affects a Roller Widget's integer -value directly. Note that this is a two-way binding (Subject <===> Widget) so an end -user's direct interaction with the Slider Widget updates the Subject's value and vice -versa. (Requires :c:macro:`LV_USE_ROLLER` to be configured to ``1``.) - -It support only integer subjects. - -- :cpp:expr:`lv_roller_bind_value(roller, &subject)` - - -Drop-Down Widgets -~~~~~~~~~~~~~~~~~ - -This method of subscribing to an integer Subject affects a Drop-Down Widget's integer -value directly. Note that this is a two-way binding (Subject <===> Widget) so an end -user's direct interaction with the Drop-Down Widget updates the Subject's value and -vice versa. (Requires :c:macro:`LV_USE_DROPDOWN` to be configured to ``1``.) - -It support only integer subjects. - -- :cpp:expr:`lv_dropdown_bind_value(dropdown, &subject)` - -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 boundaries are not interactive. -(Requires :c:macro:`LV_USE_SCALE` to be configured to ``1``.) - -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)` - - -.. _change_subject_on_event: - +To learn how to bind subjects to Arcs, Labels, Slider, etc. visit the "Data binding" +section of the given widget's documentation. For example: :ref:`Data binding for lv_label `. Change Subject on Event ----------------------- diff --git a/docs/src/details/widgets/arc.rst b/docs/src/details/widgets/arc.rst index 1983724c3f..8b0f794f31 100644 --- a/docs/src/details/widgets/arc.rst +++ b/docs/src/details/widgets/arc.rst @@ -141,6 +141,22 @@ used to rotate the Widget to the current value of the Arc. A typical use case is to call these functions in the ``VALUE_CHANGED`` event of the Arc. +Data binding +------------ + +To get familiar with observers, subjects, and data bindings in general visit the +:ref:`Observer ` page. + +This method of subscribing to an integer Subject affects an Arc Widget's integer +value directly. Note that this is a two-way binding (Subject <===> Widget), so an end +user's direct interaction with the Arc Widget updates the Subject's value and vice +versa. + +It support integer and float subjects. + + +- :cpp:expr:`lv_arc_bind_value(arc, &subject)` + .. _lv_arc_events: diff --git a/docs/src/details/widgets/dropdown.rst b/docs/src/details/widgets/dropdown.rst index 9e22874d25..12ba540cd0 100644 --- a/docs/src/details/widgets/dropdown.rst +++ b/docs/src/details/widgets/dropdown.rst @@ -132,6 +132,21 @@ To programmatically open or close the Drop-Down List use :cpp:expr:`lv_dropdown_open(dropdown)` or :cpp:expr:`lv_dropdown_close(dropdown)`. +Data binding +------------ + +To get familiar with observers, subjects, and data bindings in general visit the +:ref:`Observer ` page. + +This method of subscribing to an integer Subject affects a Drop-Down Widget's integer +value directly. Note that this is a two-way binding (Subject <===> Widget) so an end +user's direct interaction with the Drop-Down Widget updates the Subject's value and +vice versa. + +It support only integer subjects. + +- :cpp:expr:`lv_dropdown_bind_value(dropdown, &subject)` + .. _lv_dropdown_events: diff --git a/docs/src/details/widgets/image.rst b/docs/src/details/widgets/image.rst index f6eefcce6f..b17ab677d5 100644 --- a/docs/src/details/widgets/image.rst +++ b/docs/src/details/widgets/image.rst @@ -194,7 +194,19 @@ To automatically scale or tile the image, pass one of these ``align`` values: - :cpp:enumerator:`LV_IMAGE_ALIGN_CONTAIN` The image keeps its aspect ratio, but is resized to the maximum size that fits within the Widget's area. - :cpp:enumerator:`LV_IMAGE_ALIGN_COVER` The image keeps its aspect ratio and fills the Widget's area. +Data binding +------------ +To get familiar with observers, subjects, and data bindings in general visit the +:ref:`Observer ` page. + +This method of subscribing to a pointer Subject affects an Image Widget's source (``src``) +value directly. Note that this is a one-way binding (Subject ==> Widget) so when +the subject changes the Image will be update too. + +It support only pointer subjects. + +- :cpp:expr:`lv_image_bind_src(slider, &subject)` .. _lv_image_events: diff --git a/docs/src/details/widgets/label.rst b/docs/src/details/widgets/label.rst index 35137ed051..8442935ff5 100644 --- a/docs/src/details/widgets/label.rst +++ b/docs/src/details/widgets/label.rst @@ -122,8 +122,8 @@ this implementation detail is unnoticed. This is not the case with Text recolor ------------ -In the text, you can use commands to recolor parts of the text. -For example: ``Write a #ff0000 red# word``. This feature can be enabled +In the text, you can use commands to recolor parts of the text. +For example: ``Write a #ff0000 red# word``. This feature can be enabled individually for each label by :cpp:expr:`lv_label_set_recolor(label, en)` function. In the context of word-wrapped text, any Recoloring started on a line will be terminated at the end of the line where the line is wrapped if it @@ -155,6 +155,7 @@ Note that this has a visible effect only if: - the Label Widget's width is larger than the width of the longest line of text, and - the text has multiple lines with different line lengths. + .. _lv_label_very_long_texts: Very long text @@ -185,6 +186,69 @@ the :ref:`font` section to learn more about symbols. +.. _lv_label_data_binding: + +Data binding +------------ + +.. |deg| unicode:: U+000B0 .. DEGREE SIGN + +To get familiar with observers, subjects, and data bindings in general visit the +:ref:`Observer ` page. + +This method of subscribing to a Subject affects a Label Widget's +``text``. The Subject can be an STRING, POINTER or INTEGER type. + +When the subscription occurs, and each time the Subject's value is changed thereafter, +the Subject's value is used to update the Label's text as follows: + +:string Subject: Subject's string is used to directly update the Label's text. + +:pointer Subject: If NULL is passed as the ``format_string`` argument when + subscribing, the Subject's pointer value is assumed to point to a + NUL-terminated string and is used to directly update the Label's + text. See :ref:`observer_format_string` for other options. + +:integer Subject: Subject's integer value is used with the ``format_string`` argument. + See :ref:`observer_format_string` for details. + +Note that this is a one-way binding (Subject ===> Widget). + +- :cpp:expr:`lv_label_bind_text(label, &subject, format_string)` + +.. _observer_format_string: + +The ``format_string`` Argument +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``format_string`` argument is optional and if provided, must contain exactly 1 +printf-like format specifier and be one of the following: + +:string or pointer Subject: "%s" to format the new pointer value as a string or "%p" + to format the pointer as a pointer (typically the + pointer's address value is spelled out with 4, 8 or 16 + hexadecimal characters depending on the platform). + +:integer Subject: "%d" format specifier (``"%" PRIdxx`` --- a + cross-platform equivalent where ``xx`` can be ``8``, + ``16``, ``32`` or ``64``, depending on the platform). + +:float Subject: "%f" format specifier, or e.g. "%0.2f" to display two digits after the decimal point. + + +If ``NULL`` is passed for the ``format_string`` argument: + +:string or pointer Subject: Updates expect the pointer to point to a NUL-terminated string. +:integer Subject: The Label will simply display the number. Equivalent to "%d". +:float Subject: The Label will display the value with "%0.1f" format string. + +**Example:** "%d |deg|\C" + +As usual with format strings, ``%%`` shall be used to get ``%``. For example ``%d%%`` + + + + .. _lv_label_events: Events diff --git a/docs/src/details/widgets/roller.rst b/docs/src/details/widgets/roller.rst index a1d0380835..c9394ccc2d 100644 --- a/docs/src/details/widgets/roller.rst +++ b/docs/src/details/widgets/roller.rst @@ -76,6 +76,21 @@ This function calculates the height with the current style. If the font, line space, border width, etc. of the Roller changes, this function needs to be called again. +Data binding +------------ + +To get familiar with observers, subjects, and data bindings in general visit the +:ref:`Observer ` page. + +This method of subscribing to an integer Subject affects a Roller Widget's integer +value directly. Note that this is a two-way binding (Subject <===> Widget) so an end +user's direct interaction with the Roller Widget updates the Subject's value and vice +versa. + +It supports only integer subjects. + +- :cpp:expr:`lv_roller_bind_value(roller, &subject)` + .. _lv_roller_events: diff --git a/docs/src/details/widgets/scale.rst b/docs/src/details/widgets/scale.rst index a0ce605a2b..8f81cb952f 100644 --- a/docs/src/details/widgets/scale.rst +++ b/docs/src/details/widgets/scale.rst @@ -184,6 +184,25 @@ range. If a Section's range is not within the Scale's range at all, it will not used in drawing. That can be useful to temporarily "disable" a Section, e.g. :cpp:expr:`lv_scale_section_set_range(section, 0, -1)`.) +Data binding +~~~~~~~~~~~~ + +To get familiar with observers, subjects, and data bindings in general, visit the +:ref:`Observer ` page. + +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 boundaries are not interactive. + + +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)` + + +.. _change_subject_on_event: + .. _scale_styling_sections: diff --git a/docs/src/details/widgets/slider.rst b/docs/src/details/widgets/slider.rst index 71d6ed0e3a..3b95356a3d 100644 --- a/docs/src/details/widgets/slider.rst +++ b/docs/src/details/widgets/slider.rst @@ -93,6 +93,20 @@ feature is enabled by adding the :cpp:enumerator:`LV_OBJ_FLAG_ADV_HITTEST` flag: Any extended click area (set by :cpp:expr:`lv_obj_set_ext_click_area(slider, value)`) increases the knob's click area. +Data binding +------------ + +To get familiar with observers, subjects, and data bindings in general, visit the +:ref:`Observer ` page. + +This method of subscribing to an integer Subject affects a Slider Widget's integer +value directly. Note that this is a two-way binding (Subject <===> Widget), so an end +user's direct interaction with the Slider Widget updates the Subject's value and vice +versa. + +It supports integer and float subjects. + +- :cpp:expr:`lv_slider_bind_value(slider, &subject)` .. _lv_slider_events: diff --git a/docs/src/details/widgets/spangroup.rst b/docs/src/details/widgets/spangroup.rst index 5a9cc4ea5f..809caebe47 100644 --- a/docs/src/details/widgets/spangroup.rst +++ b/docs/src/details/widgets/spangroup.rst @@ -146,6 +146,20 @@ of lines to be displayed in :cpp:enumerator:`LV_SPAN_MODE_BREAK` mode. A negativ value indicates no limit. +Data binding +------------ + +To get familiar with observers, subjects, and data bindings in general, visit the +:ref:`Observer ` page. + +Very similar to Label-text binding, a Span's text can be bound to a subject as well. + +The only difference is that in the bind function both the Spangroup and the Span need to be specified: + +: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. .. _lv_spangroup_events: diff --git a/src/others/xml/parsers/lv_xml_bar_parser.c b/src/others/xml/parsers/lv_xml_bar_parser.c index 870804c137..9561d6512d 100644 --- a/src/others/xml/parsers/lv_xml_bar_parser.c +++ b/src/others/xml/parsers/lv_xml_bar_parser.c @@ -67,10 +67,19 @@ void lv_xml_bar_apply(lv_xml_parser_state_t * state, const char ** attrs) bool anim = anim_str ? lv_xml_to_bool(anim_str) : false; lv_bar_set_start_value(item, v, anim); } - if(lv_streq("min_value", name)) lv_bar_set_min_value(item, lv_xml_atoi(value)); - if(lv_streq("max_value", name)) lv_bar_set_max_value(item, lv_xml_atoi(value)); - if(lv_streq("orientation", name)) lv_bar_set_orientation(item, orientation_text_to_enum_value(value)); - if(lv_streq("mode", name)) lv_bar_set_mode(item, mode_text_to_enum_value(value)); + else if(lv_streq("min_value", name)) lv_bar_set_min_value(item, lv_xml_atoi(value)); + else if(lv_streq("max_value", name)) lv_bar_set_max_value(item, lv_xml_atoi(value)); + else if(lv_streq("orientation", name)) lv_bar_set_orientation(item, orientation_text_to_enum_value(value)); + else if(lv_streq("mode", name)) lv_bar_set_mode(item, mode_text_to_enum_value(value)); + else if(lv_streq("bind_value", name)) { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); + if(subject) { + lv_bar_bind_value(item, subject); + } + else { + LV_LOG_WARN("Subject \"%s\" doesn't exist in bar bind_value", value); + } + } } }