mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-26 11:07:34 +08:00
docs(xml): next set of XML-doc refinements (#8740)
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
.. _xml_build_ui:
|
||||
.. _xml_building_uis:
|
||||
|
||||
=========
|
||||
Build UIs
|
||||
=========
|
||||
============
|
||||
Building UIs
|
||||
============
|
||||
|
||||
.. toctree::
|
||||
:class: toctree-1-deep
|
||||
|
||||
@@ -13,6 +13,8 @@ The only common point is that both Widgets and Components support having
|
||||
However, as Widgets and Components work very differently (Widgets have C code,
|
||||
but Components are pure XML), even properties are interpreted differently.
|
||||
|
||||
|
||||
|
||||
Components
|
||||
**********
|
||||
|
||||
@@ -41,6 +43,7 @@ These properties are set once (at creation time), and there are no specific
|
||||
``set`` functions to modify the property later. LVGL's general API can still be
|
||||
used to modify any widget in the component, but no dedicated API functions are generated.
|
||||
|
||||
|
||||
Referencing properties
|
||||
----------------------
|
||||
|
||||
@@ -50,6 +53,7 @@ it can be used in a label as ``<lv_label text="$button_label"/>``.
|
||||
|
||||
In the generated code, these are passed as arguments in create/set functions.
|
||||
|
||||
|
||||
Default values
|
||||
--------------
|
||||
|
||||
@@ -59,12 +63,14 @@ This can be ensured by:
|
||||
- Simply setting them in the XML instance
|
||||
- Providing a default value in the ``<api>``, e.g., ``<prop name="foo" type="string" default="bar"/>``
|
||||
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
|
||||
Note that none of the Widget API features such as ``<param>``, ``<enumdef>``, or ``<element>``
|
||||
can be used for Components. Only simple properties that are forwarded are supported.
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
@@ -92,9 +98,12 @@ Example
|
||||
</view>
|
||||
</component>
|
||||
|
||||
|
||||
|
||||
Widgets
|
||||
*******
|
||||
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
@@ -106,6 +115,7 @@ Properties are the core part of describing a Widget's API.
|
||||
<prop name="text" type="string" help="Text of the label."/>
|
||||
</api>
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
@@ -137,6 +147,7 @@ Unset parameters fall back to:
|
||||
- Their default value (if defined)
|
||||
- Type-specific defaults (e.g., 0, false, NULL)
|
||||
|
||||
|
||||
Mapping
|
||||
-------
|
||||
|
||||
@@ -148,6 +159,7 @@ If ``<param>``s are used, they are passed to the same ``set`` function.
|
||||
If a property is not set on a Widget instance, it is skipped and the Widget's
|
||||
built-in default is used.
|
||||
|
||||
|
||||
<enumdef>
|
||||
---------
|
||||
|
||||
@@ -168,6 +180,7 @@ Only used with Widgets, this tag defines enums for parameter values.
|
||||
Enum values are ignored in export; the names are used and resolved by the compiler.
|
||||
XML parsers must handle mapping enum names to C enums.
|
||||
|
||||
|
||||
.. _xml_widget_element:
|
||||
|
||||
<element>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
.. _xml_main_tags:
|
||||
|
||||
=========
|
||||
Main tags
|
||||
=========
|
||||
=============
|
||||
Main XML Tags
|
||||
=============
|
||||
|
||||
.. toctree::
|
||||
:class: toctree-1-deep
|
||||
:maxdepth: 2
|
||||
|
||||
api
|
||||
|
||||
@@ -7,12 +7,12 @@ View
|
||||
Overview
|
||||
********
|
||||
|
||||
The ``<view>`` tag can be used in:
|
||||
The ``<view>`` tag can be used as a child of the following tags:
|
||||
|
||||
- ``<component>``\ s
|
||||
- ``<widget>``\ s
|
||||
- ``<screen>``\ s
|
||||
- ``<test>``\ s
|
||||
- ``<component>``
|
||||
- ``<widget>``
|
||||
- ``<screen>``
|
||||
- ``<test>``
|
||||
|
||||
to describe how these items look. Inside ``<view>``, children can be added in a nested way
|
||||
using already defined ``widget``\ s and ``component``\ s. For example:
|
||||
@@ -26,6 +26,8 @@ using already defined ``widget``\ s and ``component``\ s. For example:
|
||||
</lv_button>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
Extends
|
||||
*******
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ Overview
|
||||
|
||||
Components are one of the main building blocks for creating new UI elements.
|
||||
|
||||
``<component>``\ s support the following child XML tags:
|
||||
``<component>`` elements may contain the following child elements:
|
||||
|
||||
- :ref:`<consts> <xml_consts>`
|
||||
- :ref:`<api> <xml_api>`
|
||||
@@ -19,33 +19,38 @@ Components are one of the main building blocks for creating new UI elements.
|
||||
|
||||
Although they can't contain C code, they are very powerful:
|
||||
|
||||
- They can extend another Component or Widget (the base can be defined)
|
||||
- Components can be built from Widgets and other Components
|
||||
- A custom API can be defined
|
||||
- Local styles can be defined, and the global styles can be used
|
||||
- Local constants can be defined, and the global constants can be used
|
||||
- Function calls, subject changes, or screen load/create events can be added. See :ref:`XML Events <xml_events>`
|
||||
- Previews can be defined to preview the components in various settings
|
||||
- They can extend another Component or Widget (an "inherited" base Component or
|
||||
Widget can be specified).
|
||||
- Components can be built from Widgets and/or other Components.
|
||||
- A custom API can be defined.
|
||||
- Local styles can be defined, and global styles can be referenced.
|
||||
- Local constants can be defined, and global constants can be referenced.
|
||||
- Events can be added as function calls, or responses to changes of Subject values,
|
||||
or responses to Screens being created or loaded. See :ref:`XML Events <xml_events>`.
|
||||
- Previews can be defined to preview the components in various settings.
|
||||
|
||||
Unlike Widgets (which are always compiled into the application), Components can either:
|
||||
|
||||
1. be loaded at runtime from XML, or
|
||||
2. be exported to C code and compiled with the application.
|
||||
|
||||
Usage from XML
|
||||
**************
|
||||
|
||||
|
||||
Using Components from XML
|
||||
*************************
|
||||
|
||||
|
||||
In XML Files
|
||||
------------
|
||||
|
||||
Using Components in XMLs is very intuitive. The name of the components can be used as XML tag
|
||||
in the ``<view>`` of other Components, Screens, and Widgets.
|
||||
Using Components in XMLs is very intuitive. The name of the components can be used as
|
||||
the name of the XML tag in the ``<view>`` of other Components, Screens, and Widgets.
|
||||
|
||||
The Component properties are just XML attributes.
|
||||
|
||||
To load Components from file, it's assumed that the XML files are saved to the device
|
||||
either as data (byte array) or as file. Once the data is saved, each component
|
||||
can be registered, and instances can be created after that.
|
||||
either as data (byte array) or as a file. Once the data is saved, each component
|
||||
can be registered, after which instances of that Component can be created.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
@@ -57,8 +62,9 @@ can be registered, and instances can be created after that.
|
||||
</view>
|
||||
</component>
|
||||
|
||||
:ref:`Styles <xml_styles>`, :ref:`Constants <xml_consts>`, and :ref:`custom API <component_custom_api>`
|
||||
can also be described in the XML files.
|
||||
:ref:`Styles <xml_styles>`, :ref:`Constants <xml_consts>`, and a
|
||||
:ref:`custom API <component_custom_properties>` can also be described in the XML files.
|
||||
|
||||
|
||||
Registration
|
||||
------------
|
||||
@@ -68,15 +74,18 @@ Once a Component is created (e.g., ``my_button``), it can be registered by calli
|
||||
- :cpp:expr:`lv_xml_component_register_from_file("A:lvgl/examples/others/xml/my_button.xml")`
|
||||
- :cpp:expr:`lv_xml_component_register_from_data("my_button", xml_data_of_my_button)`
|
||||
|
||||
These registration functions process the XML data and store relevant information internally.
|
||||
This is required to make LVGL recognize the Component by name.
|
||||
These registration functions process the XML data and store relevant information
|
||||
internally by name. When loaded from a file, the file name is used as the Component
|
||||
name.
|
||||
|
||||
Note that the "A:" in the above path is a file system "driver identifier letter" from
|
||||
:ref:`file_system` and used accordingly. See that documentation for details.
|
||||
During registration, the ``<view>`` of the Component is saved in RAM as a template for
|
||||
creating instances of that Component.
|
||||
|
||||
When loaded from a file, the file name is used as the Component name.
|
||||
.. note::
|
||||
|
||||
Note that the "A:" in the above path is a file system "driver identifier letter" from
|
||||
:ref:`file_system` and used accordingly. See that documentation for details.
|
||||
|
||||
During registration, the ``<view>`` of the Component is saved in RAM.
|
||||
|
||||
Instantiation
|
||||
-------------
|
||||
@@ -87,7 +96,7 @@ After registration, a new instance of any registered Component can be created wi
|
||||
|
||||
lv_obj_t * obj = lv_xml_create(lv_screen_active(), "my_button", NULL);
|
||||
|
||||
The created Widget is a normal LVGL Widget that can be used like any other manually-created Widget.
|
||||
The created Widget is a normal LVGL Widget that can be used like any other Widget.
|
||||
|
||||
The last parameter can be ``NULL`` or an attribute list, like this:
|
||||
|
||||
@@ -103,8 +112,10 @@ The last parameter can be ``NULL`` or an attribute list, like this:
|
||||
|
||||
lv_obj_t * btn1 = lv_xml_create(lv_screen_active(), "my_button", my_button_attrs);
|
||||
|
||||
Usage from Exported Code
|
||||
************************
|
||||
|
||||
|
||||
Using Components from Exported C Code
|
||||
*************************************
|
||||
|
||||
From each Component XML file, a C and H file is exported with a single function inside:
|
||||
|
||||
@@ -125,28 +136,31 @@ If the user needs to access or modify values dynamically, it is recommended to u
|
||||
The user can also call these ``..._create()`` functions at any time from application code
|
||||
to create new components on demand.
|
||||
|
||||
|
||||
|
||||
Extending
|
||||
*********
|
||||
|
||||
Additionally, when a Component is created, it can use the extended Widget's attributes
|
||||
(see ``<view extends="...">`` in the code examples below).
|
||||
When a Component is defined as "extending" a Widget, it effectively inherits that
|
||||
Widget's attributes, and they can be used with that Component.
|
||||
(See ``<view extends="...">`` in the code examples below.)
|
||||
|
||||
This means that Components inherit the API of the extended Widget as well.
|
||||
|
||||
.. _component_custom_api:
|
||||
|
||||
.. _component_custom_properties:
|
||||
|
||||
Custom Properties
|
||||
*****************
|
||||
|
||||
The properties of child elements can be adjusted, such as:
|
||||
The properties of child elements can be set directly, such as:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<my_button x="10" width="200"/>
|
||||
|
||||
However, it's also possible to define custom properties in the ``<api>`` tag.
|
||||
The properties then can be passed to any properties of the children by
|
||||
referencing them by ``$``. For example:
|
||||
It is also possible to define custom properties in the ``<api>`` tag.
|
||||
Those properties then can thereafter be referenced in any properties of the children
|
||||
by using a ``$`` prefix with its name. Example:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
@@ -161,7 +175,7 @@ referencing them by ``$``. For example:
|
||||
</view>
|
||||
</component>
|
||||
|
||||
And it can be used like
|
||||
And it can be used by other Components like this:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
@@ -175,19 +189,21 @@ And it can be used like
|
||||
</component>
|
||||
|
||||
In this setup, the ``btn_text`` property is mandatory, however it can be made optional
|
||||
by setting a default value:
|
||||
by providing a default value like this:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<prop name="btn_text" type="string" default="Title"/>
|
||||
|
||||
See :ref:`<api> <xml_api>` for more details and :ref:`XML Syntax <xml_syntax>` for all the supported types.
|
||||
See :ref:`<api> <xml_api>` for more details, and :ref:`XML Syntax <xml_syntax>` for all the supported types.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
********
|
||||
|
||||
The following example demonstrates parameter passing and the use of the
|
||||
``text`` label property on a Component. Styles and Constants are also shown.
|
||||
``text`` label property in a Component. Styles and Constants are also shown.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
@@ -225,20 +241,28 @@ The following example demonstrates parameter passing and the use of the
|
||||
lv_xml_component_register_from_file("A:path/to/h3.xml");
|
||||
lv_xml_component_register_from_file("A:path/to/red_button.xml");
|
||||
|
||||
/* Creates a button with "None" text */
|
||||
/* Create a button with "None" text. */
|
||||
lv_xml_create(lv_screen_active(), "red_button", NULL);
|
||||
|
||||
/* Use attributes to set the button text */
|
||||
/* Use attributes to set the button text. */
|
||||
const char * attrs[] = {
|
||||
"btn_text", "Click here",
|
||||
NULL, NULL,
|
||||
};
|
||||
lv_xml_create(lv_screen_active(), "red_button", attrs);
|
||||
|
||||
|
||||
|
||||
Live Example
|
||||
*************
|
||||
|
||||
.. include:: ../../../../../../examples/others/xml/index.rst
|
||||
|
||||
|
||||
|
||||
API
|
||||
***
|
||||
|
||||
.. API startswith: lv_xml_component_
|
||||
|
||||
.. API equals: lv_xml_create
|
||||
|
||||
@@ -15,31 +15,34 @@ Screens work very similarly to Components. Both can be:
|
||||
- Loaded from XML
|
||||
- Contain Widgets and Components as children
|
||||
|
||||
Screens are wrapped in the ``<screen>`` XML root element and used to organize
|
||||
Screens have ``<screen>`` as their root element and are used to organize
|
||||
the content of the UI.
|
||||
|
||||
Screens can have only the following child XML tags:
|
||||
``<screen>`` elements may contain only the following child elements:
|
||||
|
||||
- :ref:`<consts> <xml_consts>`
|
||||
- :ref:`<styles> <xml_styles>`, and
|
||||
- :ref:`<view> <xml_view>`
|
||||
|
||||
That is, Screens **cannot** have an :ref:`<api> <xml_api>` or :ref:`<preview> <xml_preview>`.
|
||||
That is, Screens **cannot** have :ref:`<api> <xml_api>` or :ref:`<preview> <xml_preview>`
|
||||
elements.
|
||||
|
||||
|
||||
|
||||
Usage
|
||||
*****
|
||||
|
||||
Each XML file describes a :ref:`Screen <screens>`. The name of the XML file will
|
||||
also be the name of the Screen.
|
||||
Each Screen XML file defines a :ref:`Screen <screens>`. The name of the XML file will
|
||||
be the name of the Screen.
|
||||
|
||||
This example illustrates a screen in XML. In the example, a ``<my_header>``
|
||||
This example illustrates a Screen in XML. In the example, a ``<my_header>``
|
||||
and a ``<my_main_cont>`` component is used to keep the screen simple.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<screen>
|
||||
<consts>
|
||||
<string name="title" value="Main menu"/>
|
||||
<string name="title" value="Main Menu"/>
|
||||
</consts>
|
||||
|
||||
<styles>
|
||||
@@ -59,31 +62,37 @@ and a ``<my_main_cont>`` component is used to keep the screen simple.
|
||||
</view>
|
||||
</screen>
|
||||
|
||||
Code export
|
||||
|
||||
|
||||
Code Export
|
||||
***********
|
||||
|
||||
When the C code is exported from the UI |nbsp| Editor, ``screen_name_gen.c/h`` files are exported,
|
||||
When C code is exported from the UI |nbsp| Editor, ``screen_name_gen.c/h`` files are exported,
|
||||
containing only a single ``lv_obj_t * screen_name_create(void)`` create function.
|
||||
|
||||
By using this function, any number of screen instances can be created and loaded as needed.
|
||||
|
||||
|
||||
|
||||
Preview
|
||||
*******
|
||||
|
||||
Screens don't support the :ref:`<preview> <xml_preview>` tag because it doesn't make
|
||||
sense to preview each screen in different resolutions.
|
||||
|
||||
As Screens are related to the target hardware in the ``project.xml`` file, multiple
|
||||
Since Screens are related to target hardware specified in the ``project.xml`` file, multiple
|
||||
``<display>`` elements can be defined. In the UI |nbsp| Editor, when a Screen is being developed,
|
||||
the user can select from all the defined displays in the Preview, and the Screen will be shown with
|
||||
the given resolution and color depth.
|
||||
|
||||
This is useful for verifying responsive designs.
|
||||
|
||||
|
||||
|
||||
Events
|
||||
******
|
||||
|
||||
It's very common to load or create Screens on a button click or other events.
|
||||
It is very common to load or create Screens from a button-click or other type of event.
|
||||
|
||||
Both are supported by adding special XML tags as children of Components or Widgets:
|
||||
|
||||
@@ -93,15 +102,15 @@ Both are supported by adding special XML tags as children of Components or Widge
|
||||
<lv_button>
|
||||
<lv_label text="Click or Long press me"/>
|
||||
|
||||
<!-- Load an already created screen that has the name "first".
|
||||
<!-- Load an already created screen named "first".
|
||||
Note that here the name of the instance is used,
|
||||
and not the name of the XML file. -->
|
||||
not the name of the XML file. -->
|
||||
<screen_load_event screen="first" trigger="clicked" anim_type="fade"/>
|
||||
|
||||
<!-- Create an instance of "about" and load it.
|
||||
Note that here the name of the XML file is used. -->
|
||||
<!-- Create an instance of "about" Screen and load it.
|
||||
Note that the name of the XML file is used. -->
|
||||
<screen_create_event screen="about" trigger="long_pressed"/>
|
||||
</lv_button>
|
||||
</view>
|
||||
|
||||
Learn more on :ref:`XML Events <xml_events_screen>` page.
|
||||
Learn more on the :ref:`XML Events <xml_events_screen>` page.
|
||||
|
||||
@@ -11,9 +11,9 @@ Overview
|
||||
:trim:
|
||||
|
||||
Besides components and Screens, Widgets are the other main building blocks of UIs.
|
||||
The XML file of the Widgets is wrapped in a ``<widget>`` XML root element.
|
||||
XML files defining Widgets have ``<widget>`` as their XML root element.
|
||||
|
||||
``<widget>``\ s support the following child XML tags:
|
||||
``<widget>`` elements may contain the following child elements:
|
||||
|
||||
- :ref:`<consts> <xml_consts>`
|
||||
- :ref:`<api> <xml_api>`
|
||||
@@ -21,23 +21,25 @@ The XML file of the Widgets is wrapped in a ``<widget>`` XML root element.
|
||||
- :ref:`<view> <xml_view>`
|
||||
- :ref:`<previews> <xml_preview>`
|
||||
|
||||
Just like Components, Widgets also can be the children of other Widgets and Components.
|
||||
Just like Components, Widgets can also be the children of other Widgets and Components.
|
||||
|
||||
The main difference is that Widgets are written in C and compiled into the
|
||||
application. This means, unlike Components, Widgets can contain custom C code. For
|
||||
example, when a property is set, any complex C code can run to set that value.
|
||||
|
||||
To connect the C code to XML, XML parser functions need to be implemented and registered. It is
|
||||
pretty simple since LVGL already provides all the helper functions and the required libraries. Also there
|
||||
are `many XML parser examples here <https://github.com/lvgl/lvgl/tree/master/src/others/xml/parsers>`__.
|
||||
|
||||
The main difference is that Widgets are written in C and compiled into the application.
|
||||
It means unlike Components, Widgets can contain custom C code. For example, when a property is set,
|
||||
any complex C code can run to set that value.
|
||||
|
||||
To connect the C code to XML, XML parser functions need to be implemented and registered. It's
|
||||
pretty simple as LVGL already provides all the helper functions and the required libraries. Also there
|
||||
are `many XML parser examples here. <https://github.com/lvgl/lvgl/tree/master/src/others/xml/parsers>`__
|
||||
|
||||
Built-in Widgets
|
||||
****************
|
||||
|
||||
The built-in LVGL widgets (e.g. :ref:`lv_slider`, :ref:`lv_label`, :ref:`lv_chart`, etc.) already
|
||||
have XML parsers and therefore are available in XML.
|
||||
LVGL already has XML parsers for LVGL's built-in widgets (e.g. :ref:`lv_slider`,
|
||||
:ref:`lv_label`, :ref:`lv_chart`, etc.), which makes them available in XML.
|
||||
|
||||
For example:
|
||||
Example:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
@@ -45,20 +47,23 @@ For example:
|
||||
<lv_label x="10" text="Hello"/>
|
||||
</view>
|
||||
|
||||
The built-in widgets are
|
||||
The built-in widgets are:
|
||||
|
||||
- pure C code
|
||||
(e.g. `lv_slider.c <https://github.com/lvgl/lvgl/tree/master/src/widgets/slider/lv_slider.c>`__)
|
||||
- an XML file to define only the API
|
||||
(e.g. `lv_slider.xml <https://github.com/lvgl/lvgl/blob/master/xmls/lv_slider.xml>`__).
|
||||
It is used only in the UI |nbsp| Editor to validate and autocomplete properties.
|
||||
(e.g. `lv_slider.xml <https://github.com/lvgl/lvgl/blob/master/xmls/lv_slider.xml>`__)
|
||||
(used only in the UI |nbsp| Editor to validate and autocomplete properties)
|
||||
- an XML parser C file to map the XML attributes to C functions.
|
||||
(e.g. `lv_xml_slider_parser.c <https://github.com/lvgl/lvgl/blob/master/src/others/xml/parsers/lv_xml_slider_parser.c>`__)
|
||||
|
||||
|
||||
|
||||
Creating New Widgets
|
||||
********************
|
||||
|
||||
It's possible to create new widgets in the same way as the built-in LVGL widgets are handled.
|
||||
It is possible to create new Widgets that can be treated in the same way as built-in
|
||||
LVGL Widgets.
|
||||
|
||||
However, using the UI |nbsp| Editor it's much faster and simpler. When an XML file is created and
|
||||
the ``<widget>`` root element is used, the following .C/.H files are generated automatically:
|
||||
@@ -78,6 +83,8 @@ the ``<widget>`` root element is used, the following .C/.H files are generated a
|
||||
functions according to the set attributes. Only a
|
||||
skeleton is exported once.
|
||||
|
||||
|
||||
|
||||
Usage
|
||||
*****
|
||||
|
||||
@@ -142,7 +149,7 @@ After registration, a Widget can be created like this from C code:
|
||||
|
||||
lv_xml_create(lv_screen_active(), "lv_label", attrs);
|
||||
|
||||
And in XML it can be used like
|
||||
And in XML it can be used like this:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
@@ -150,17 +157,18 @@ And in XML it can be used like
|
||||
<lv_label width="100" text="I'm a label!" wrap="scroll"/>
|
||||
</view>
|
||||
|
||||
|
||||
Adding Custom Code
|
||||
------------------
|
||||
|
||||
``<widget_name>.c`` contains three hooks:
|
||||
|
||||
- **Constructor hook**: Called when the Widget and all its children are created. Any
|
||||
modifications can be done on the children here.
|
||||
modifications to the children can be done here.
|
||||
- **Destructor hook**: Called when the Widget is deleted. All manually allocated
|
||||
memory needs to be freed here.
|
||||
- **Event hook**: Called at the beginning of the Widget's event callback to perform
|
||||
any custom action.
|
||||
any custom actions.
|
||||
|
||||
In this C file, the ``set`` functions for each API ``<prop>`` also need to be
|
||||
implemented. The declaration of these functions is automatically exported in
|
||||
@@ -168,13 +176,23 @@ implemented. The declaration of these functions is automatically exported in
|
||||
|
||||
Besides these, any custom code and functions can be freely implemented in this file.
|
||||
|
||||
|
||||
Elements
|
||||
--------
|
||||
|
||||
Elements are internal parts of the widget that can be accessed and/or created dynamically.
|
||||
For example, tabs of a tabview, list of a dropdown, series of a chart, etc.
|
||||
For example, tabs of a tabview, list of a dropdown, series of a chart, etc..
|
||||
|
||||
Just like any other Widget API properties, Elements also can be defined in the ``<api>``
|
||||
tag of the Widget's XML.
|
||||
Just like any other Widget API properties, Elements also can be defined within the
|
||||
``<api>`` element of the Widget's XML.
|
||||
|
||||
Learn more about the Elements in the documentation page of :ref:`<api> <xml_widget_element>`.
|
||||
Learn more about Elements under the :ref:`<api> element documentation <xml_widget_element>`.
|
||||
|
||||
|
||||
|
||||
API
|
||||
***
|
||||
|
||||
.. API startswith: lv_xml_widget_
|
||||
|
||||
.. API equals: lv_xml_create
|
||||
@@ -1,8 +1,8 @@
|
||||
.. _xml_translation:
|
||||
|
||||
============
|
||||
Translations
|
||||
============
|
||||
=====================
|
||||
Language Translations
|
||||
=====================
|
||||
|
||||
Overview
|
||||
********
|
||||
@@ -10,7 +10,10 @@ Overview
|
||||
The XML translation module allows defining and using translated strings directly within XML files.
|
||||
|
||||
It's built on top of :ref:`LVGL's translation module <translation>`.
|
||||
Check it out to learn more about selecting the active language, retrieving translations, and fallback behavior.
|
||||
|
||||
Check it out to learn more about selecting the active language, retrieving
|
||||
translations, and fallback behavior.
|
||||
|
||||
|
||||
|
||||
Usage
|
||||
|
||||
@@ -13,17 +13,18 @@ Overview
|
||||
The collection of Components, Widgets, Screens, Images, Fonts, etc., is called a
|
||||
Component Library.
|
||||
|
||||
A Component Library can be fully self-sufficient, but it can also reference data from
|
||||
A Component Library can be fully self-contained, or it can also reference data from
|
||||
other Component Libraries.
|
||||
|
||||
LVGL itself is a Component Library that supplies the built-in Widgets, data types,
|
||||
etc. You can
|
||||
find the XML files that describe the LVGL Widgets
|
||||
etc. You can find the XML files that describe the LVGL Widgets
|
||||
`here <https://github.com/lvgl/lvgl/tree/master/xmls>`__.
|
||||
|
||||
A project always has at least 2 Component Libraries: that of LVGL as mentioned
|
||||
above, and its own where the Screens, Components, and Widgets of the project are
|
||||
defined. A project may include additional Component Libraries.
|
||||
An LVGL firmware project that uses external XML files to define part (or all) of its
|
||||
user interface (UI) always has at least 2 Component Libraries: that of LVGL as
|
||||
mentioned above, and at least 1 Component Library where a related set of Screens,
|
||||
Components, and Widgets of the project are defined. A project may include additional
|
||||
Component Libraries.
|
||||
|
||||
|
||||
Structure
|
||||
@@ -63,33 +64,30 @@ A typical structure for a Component Library looks like this:
|
||||
└── image2.png
|
||||
|
||||
|
||||
Visibility
|
||||
**********
|
||||
Name Visibility
|
||||
***************
|
||||
|
||||
The content of all ``globals.xml`` files is part of a common global scope, and
|
||||
any Components, Widgets or Screens defined therein can be used in all .XML files.
|
||||
In the context of UI components defined in XML files, there are two namespaces:
|
||||
|
||||
Styles, constants, and other data defined in the XML file of Components, Widgets, or Screens
|
||||
are local to that XML file.
|
||||
:global namespace:
|
||||
|
||||
Thus, there are two namespaces:
|
||||
Created from the combined data from the ``globals.xml`` file from each included
|
||||
Component Library, the names of :ref:`Subjects <observer_subject>`, enumerations,
|
||||
constants, styles, fonts and images defined therein can be referenced from all
|
||||
XML files used in a project.
|
||||
|
||||
1. **local namespace** within the given XML file of Components, Widgets and Screens.
|
||||
2. **global namespace** created from the data in the ``globals.xml`` file from each
|
||||
Component Library included.
|
||||
:local namespace:
|
||||
|
||||
To find names referenced in XML files, the local namespace is checked first, and if
|
||||
a name is not found there, then the global namespace is checked.
|
||||
|
||||
The names of defined Components, Widgets and Screens become part of the global
|
||||
namespace and must be unique therein. This ensures that each Component has a unique
|
||||
name.
|
||||
Names created within all other XML files can only be referenced from within those
|
||||
XML files. Exception: names of defined Components, Widgets and Screens become
|
||||
part of the global namespace, and therefore must be unique within the global
|
||||
namespace. This ensures each Component has a unique name.
|
||||
|
||||
All data belonging to the LVGL core Component Library is prefixed by ``lv_``
|
||||
(e.g., ``lv_label``, ``lv_font_default``).
|
||||
|
||||
A custom Component can be prefixed with ``watch_``, ``small_``, ``light_``, or
|
||||
anything else the developer deems appropriate.
|
||||
anything else the development team deems appropriate.
|
||||
|
||||
LVGL's UI |nbsp| Editor will show an error if there is a name conflict.
|
||||
|
||||
@@ -105,7 +103,7 @@ in it are:
|
||||
|
||||
:<config>: Can specify name and help.
|
||||
:<api>: Used with ``<enumdefs>`` to show possible values for Widget or Component attributes.
|
||||
:<subjects>: List of :ref:`Subjects <observer_subject>`. Can be considered the API of a Component Library.
|
||||
:<subjects>: List of :ref:`Subjects <observer_subject>`; can be considered the API of a Component Library.
|
||||
:<consts>: Globally available constants.
|
||||
:<styles>: Globally available styles.
|
||||
:<fonts>: Globally available fonts.
|
||||
|
||||
@@ -7,15 +7,33 @@ Introduction
|
||||
.. |nbsp| unicode:: U+000A0 .. NO-BREAK SPACE
|
||||
:trim:
|
||||
|
||||
The LVGL XML Module implements LVGL's Declarative UI by loading UI elements written in
|
||||
XML. The XML file can be written by hand, but it's highly recommended to use `LVGL's
|
||||
UI editor <https://lvgl.io/editor>`__ to write the XML files. This UI editor
|
||||
provides features like:
|
||||
.. glossary::
|
||||
|
||||
- Instant preview of the XML files
|
||||
- Autocomplete and Syntax highlighting
|
||||
- Online preview for collaboration and testing
|
||||
- `Figma <https://www.figma.com/>`__ integration to easily reimplement Figma designs
|
||||
Declarative UI
|
||||
|
||||
Declarative UI (user interface) is an approach to UI creation in which the
|
||||
creator describes *what* elements are needed in the UI, what data they are
|
||||
bound to, and to some degree, what they should look like, but can leave out
|
||||
details such as their exact position or in what sequence they should be
|
||||
created at run time.
|
||||
|
||||
Imperative UI
|
||||
|
||||
Imperative UI is an approach to UI creation in which the creator describes
|
||||
every detail of how the UI is created at run time. Imperative UI is the
|
||||
UI-building approach you use when you build your LVGL UI in C code.
|
||||
|
||||
The LVGL XML Module implements LVGL's :term:`Declarative UI` by loading UI elements
|
||||
written in XML. The XML file can be written by hand, but it is considerably more
|
||||
efficient to write the XML files using `LVGL's UI Editor <https://lvgl.io/editor>`__
|
||||
and thus highly recommended. This UI Editor provides features like:
|
||||
|
||||
- instant preview of the XML files,
|
||||
- auto-complete,
|
||||
- syntax highlighting,
|
||||
- online preview for collaboration and testing,
|
||||
- `Figma <https://www.figma.com/>`__ integration to efficiently implement Figma
|
||||
designs in LVGL.
|
||||
|
||||
.. warning::
|
||||
|
||||
@@ -60,7 +78,7 @@ push it back to the git repository so that other projects can be updated from it
|
||||
The built-in Widgets of LVGL are considered ``the core Component Library`` which is
|
||||
always available.
|
||||
|
||||
A UI editor project can have any number of Component Libraries but will always
|
||||
A UI Editor project can have any number of Component Libraries but will always
|
||||
have at least 2:
|
||||
|
||||
- LVGL's built-in Widgets, and
|
||||
@@ -88,11 +106,11 @@ but rather compiled into the application as C code. The main characteristics of
|
||||
- They can have a large API with ``set/get/add`` functions.
|
||||
- They can themselves contain Widgets as children (e.g. ``Tabview``'s tabs, ``Dropdown``'s lists).
|
||||
|
||||
Any handwritten Widget can be accessed from XML by:
|
||||
Any custom Widgets you create can be accessed from XML by:
|
||||
|
||||
1. Defining its API in an XML file.
|
||||
2. Writing and registering an XML parser for it.
|
||||
`See some examples here. <https://github.com/lvgl/lvgl/tree/master/src/others/xml/parsers>`__
|
||||
`See examples here. <https://github.com/lvgl/lvgl/tree/master/src/others/xml/parsers>`__
|
||||
|
||||
|
||||
Components
|
||||
@@ -109,10 +127,11 @@ The main characteristics of Components are:
|
||||
- They can contain (as children) Widgets and/or other Components.
|
||||
- They can have a simple API to pass properties to their children (e.g. ``btn_text`` to a Label's text).
|
||||
|
||||
Regardless of whether the XML was written manually or by the UI |nbsp| editor, the XML files
|
||||
defining Components can be registered in LVGL, and after that, instances can be created.
|
||||
In other words, LVGL can just read the XML files, "learn" the Components from them, and
|
||||
thereafter create children as part of Screens and other Components.
|
||||
Regardless of whether the XML was written manually or by the UI |nbsp| Editor, the XML
|
||||
files defining Components can be registered in LVGL, and after that, instances can be
|
||||
created. In other words, LVGL can just read the XML files, "learn" the Components
|
||||
from them, and thereafter create those components as children of Screens and/or other
|
||||
Components.
|
||||
|
||||
|
||||
Screens
|
||||
@@ -124,7 +143,7 @@ Screens
|
||||
- They are built from Widgets and/or other Components to describe the :ref:`Screen <screens>`.
|
||||
- They can be loaded from XML at runtime as they describe only visual aspects of the UI.
|
||||
- They do not have an API.
|
||||
- They can be referenced in Screen load events.
|
||||
- They can be referenced in Screen-load events.
|
||||
|
||||
|
||||
|
||||
@@ -148,7 +167,7 @@ will be children of these root elements:
|
||||
children and their properties.
|
||||
|
||||
This is a simple example illustrating what an LVGL XML Component looks like.
|
||||
Note that only the basic features are shown here.
|
||||
Only basic features are shown.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
@@ -183,34 +202,36 @@ Usage Teaser
|
||||
|
||||
LVGL's UI editor can be used in two different ways.
|
||||
|
||||
|
||||
Export C and H Files
|
||||
--------------------
|
||||
|
||||
The Widgets, Components, Screens, images, fonts, etc., can be converted to .C/.H files having
|
||||
plain LVGL code. The exported code works the same way as if it was written by the
|
||||
user.
|
||||
code that accesses the LVGL API in the same way user-written code does.
|
||||
|
||||
In this case, the XML files are not required anymore to run the C code (unless modifications may
|
||||
be made later and code is exported again).
|
||||
In this case, the XML files are not required anymore to run the C code (unless modifications
|
||||
are made later and code is exported again).
|
||||
|
||||
The XML files were used only during Widget and Component creation to save
|
||||
recompilation time and optionally to take advantage of other useful UI editor features.
|
||||
|
||||
The XML files were used only during editing/implementing the Widgets and Components to save
|
||||
recompilation time and optionally leverage other useful UI |nbsp| Editor features.
|
||||
|
||||
Load the UI from XML
|
||||
--------------------
|
||||
|
||||
Although the Widgets' code always needs to be exported in C and compiled into the
|
||||
application (just like the built-in LVGL Widgets are also part of the application), the Components'
|
||||
XML can be loaded and any number of instances can be created at runtime.
|
||||
Although Widgets' XML always needs to be exported in C and compiled into the
|
||||
application (just like the built-in LVGL Widgets' C code is compiled into the
|
||||
application), the XML for Components can be loaded (learned) at runtime, and
|
||||
thereafter any number of instances of them can be created.
|
||||
|
||||
In the simplest case, a Component can be registered with
|
||||
:cpp:expr:`lv_xml_component_register_from_file(path)` and an instance can be created with
|
||||
:cpp:expr:`lv_obj_t * obj = lv_xml_create(parent, "my_button", NULL)`.
|
||||
|
||||
Note that loading the UI from XML practically has no impact on performance.
|
||||
Once the XML files are registered and the UI is created, it behaves the same way
|
||||
as if it were created from C code.
|
||||
Note that loading UI components from XML has virtually no impact on performance.
|
||||
Once the XML files are registered and the UI is created, the performance, appearance
|
||||
and behavior are exactly the same as if it were created from C code.
|
||||
|
||||
Registering XMLs and creating instances is not memory hungry nor slow. The biggest
|
||||
memory overhead is that the ``<view>`` of the Components is saved in RAM (typically
|
||||
1–2 kB/component).
|
||||
Registering XML Components and creating instances are neither memory hungry nor slow.
|
||||
The biggest memory overhead is that the ``<view>`` of the Components is saved in RAM
|
||||
(typically 1–2 kB/component).
|
||||
|
||||
@@ -13,8 +13,9 @@ Overview
|
||||
A single ``project.xml`` file should be created for each project where the following
|
||||
content is specified:
|
||||
|
||||
:<folders>: Specifies the path to Component Libraries. LVGL's base Widgets are
|
||||
always loaded automatically.
|
||||
:<folders>: Specifies the list of paths to Component Libraries. LVGL's base Widgets are
|
||||
always loaded automatically, and therefore do not need to be specified
|
||||
in this list.
|
||||
:<targets>: Describes various hardware configurations, allowing the UI |nbsp| Editor
|
||||
to check if the UI is out of resources and to select different previews
|
||||
for each Screen according to the specified displays.
|
||||
|
||||
@@ -11,15 +11,15 @@ Naming conventions
|
||||
:trim:
|
||||
|
||||
- A standard XML syntax is used.
|
||||
- Lowercase letters with ``_`` separation are used for attribute names.
|
||||
- Tag names follow the usual variable-name rules: they must start with a letter or
|
||||
- Lowercase letters with ``'_'`` separators are used for attribute names.
|
||||
- Tag names follow the usual C variable-name rules: they must start with a letter or
|
||||
``'_'`` and the rest of the name may be comprised of letters, ``'_'`` and digits.
|
||||
- The LVGL API is followed as much as possible, e.g., ``align="center"``, ``bg_color="0xff0000"``.
|
||||
- For colors, all these syntaxes are supported (similar to CSS colors): ``0x112233``,
|
||||
``#112233``, ``112233``, ``0x123``, ``#123``, ``123``. Note that like CSS,
|
||||
``0x123``, ``#123`` and ``123`` all mean ``#112233``.
|
||||
- ``params`` can be referenced with ``$``.
|
||||
- ``consts`` can be referenced with ``#``.
|
||||
- ``params`` can be referenced using ``$`` as a name prefix.
|
||||
- ``consts`` can be referenced using ``#`` as a name prefix.
|
||||
- ``styles`` can be attached to states and/or parts like this:
|
||||
``styles="style1 style2:pressed style3:focused:scrollbar"``.
|
||||
- Local styles (i.e. styles that are stored within the Component and thus not shared
|
||||
@@ -28,10 +28,10 @@ Naming conventions
|
||||
|
||||
|
||||
|
||||
Types
|
||||
*****
|
||||
Data Types
|
||||
**********
|
||||
|
||||
All of the types can be used as API property types, but only a subset of them can be
|
||||
All of the data types can be used as API property types, but only a subset of them can be
|
||||
used as constant and :ref:`Subject <observer_subject>` types.
|
||||
|
||||
|
||||
@@ -42,10 +42,10 @@ The following simple built-in types are supported:
|
||||
|
||||
:bool: a ``true`` or ``false``.
|
||||
|
||||
:int: Integer number in the range of roughly -2B to 2B by default.
|
||||
:int: Integer number in the range of roughly -2 billion to 2 billion by default.
|
||||
(Same as ``int32_t`` in C.)
|
||||
|
||||
:px: Simple pixel units. The unit ``px`` can be omitted.
|
||||
:px: Simple pixel units. The unit suffix ``px`` can be omitted from the numeric value.
|
||||
|
||||
:%: Percentage. ``%`` must be appended to the value as the unit.
|
||||
(Means the same as :cpp:expr:`lv_pct()`.)
|
||||
@@ -53,7 +53,8 @@ The following simple built-in types are supported:
|
||||
:content: Means ``LV_SIZE_CONTENT``.
|
||||
|
||||
:string: Simple NUL-terminated string. When multiple strings are used in a
|
||||
property or string array, ``'`` should be used. E.g. ``foo="'a' 'b'"``.
|
||||
property or string array, ``'`` should be used. E.g. ``foo="'a' 'b'"``
|
||||
represents an array of 2 strings.
|
||||
|
||||
:color: A color stored as 24-bit RGB (:cpp:expr:`lv_color_t`).
|
||||
|
||||
@@ -64,47 +65,50 @@ The following simple built-in types are supported:
|
||||
|
||||
:screen: Pointer to a screen (also :cpp:expr:`lv_obj_t *`).
|
||||
|
||||
:time_ms: Means some time in milliseconds unit
|
||||
:time_ms: Means some time in milliseconds
|
||||
|
||||
:deg_0.1: Degrees with 0.1 resolution
|
||||
|
||||
:scale_1/256: Scale/Zoom, where 256 means 100%, 128 means 50%, 512 means 200% etc.
|
||||
|
||||
|
||||
Name-based types
|
||||
----------------
|
||||
|
||||
In XML files, fonts, images, styles, etc., are not used by pointer but by string
|
||||
names. For example, a style is defined like ``<style name="red" bg_color="0xff0000"/>``.
|
||||
Later, they can be referenced by their names.
|
||||
In XML files, fonts, images, styles, etc., are used by their names, rather than by
|
||||
pointers as they are in C. For example, a style is defined like ``<style name="red"
|
||||
bg_color="0xff0000"/>``. Later, it can be referenced by its name: "red".
|
||||
|
||||
This means that the actual values need to be bound to the names when the UI is loaded
|
||||
from XML, otherwise, LVGL wouldn't know what a name means.
|
||||
This means that the actual objects need to be bound to the names when the UI is loaded
|
||||
from XML files so LVGL knows what each name means.
|
||||
|
||||
Most of these connections are done automatically (e.g., for styles, fonts, images,
|
||||
animations, gradients, etc.), but others need to be connected manually (e.g., event
|
||||
callbacks where the callback itself is available only in the code).
|
||||
animations, gradients, etc.), but others need to be connected manually in C code
|
||||
(e.g., event callbacks where the callback itself is available only in C code).
|
||||
|
||||
For fonts and images, the connections are created automatically if the source is a file.
|
||||
If the font or image is compiled into the application (as a C array), the user needs
|
||||
to specify which variable a given name refers to.
|
||||
For fonts and images, the connections are created automatically if the source is an
|
||||
XML file. If the font or image is compiled into the application (as a C array), the
|
||||
user needs to specify which variable a given name refers to.
|
||||
|
||||
To create these connections, functions like
|
||||
|
||||
- ``lv_xml_register_image(scope, name, pointer)``
|
||||
- ``lv_xml_register_font(scope, name, pointer)``
|
||||
- ``lv_xml_register_event_cb(scope, name, callback)``
|
||||
- :cpp:expr:`lv_xml_register_image(scope, name, pointer)`
|
||||
- :cpp:expr:`lv_xml_register_font(scope, name, pointer)`
|
||||
- :cpp:expr:`lv_xml_register_event_cb(scope, name, callback)`
|
||||
- etc.
|
||||
|
||||
can be used. Later, a pointer to the object can be retrieved by
|
||||
|
||||
- ``lv_xml_get_image(scope, name)``
|
||||
- ``lv_xml_get_font(scope, name)``
|
||||
- ``lv_xml_get_event_cb(scope, name)``
|
||||
- :cpp:expr:`lv_xml_get_image(scope, name)`
|
||||
- :cpp:expr:`lv_xml_get_font(scope, name)`
|
||||
- :cpp:expr:`lv_xml_get_event_cb(scope, name)`
|
||||
- etc.
|
||||
|
||||
``scope`` can be ``NULL`` to use the global scope or :cpp:expr:`lv_xml_component_get_scope("my_component")`
|
||||
returns the a component's local scope.
|
||||
|
||||
The passed ``name`` strings can be bound to:
|
||||
|
||||
:style: Name of a style. :cpp:expr:`lv_xml_get_style_by_name(&ctx, name)` returns an :cpp:expr:`lv_style_t *`.
|
||||
:font: Name of a font. :cpp:expr:`lv_xml_get_font(&ctx, name)` returns an :cpp:expr:`lv_font_t *`.
|
||||
:image: Name of an image. :cpp:expr:`lv_xml_get_image(&ctx, name)` returns an :cpp:expr:`const void *`,
|
||||
@@ -113,7 +117,8 @@ returns the a component's local scope.
|
||||
:subject: Name of a :ref:`Subject <observer_subject>`. :cpp:expr:`lv_xml_get_subject(&ctx, name)` returns an :cpp:expr:`lv_subject_t *`.
|
||||
:grad: Name of a gradient. :cpp:expr:`lv_xml_get_grad(&ctx, name)` returns an :cpp:expr:`lv_grad_dsc_t *`.
|
||||
:event_cb: Name of an event callback. :cpp:expr:`lv_xml_get_event_cb(&ctx, name)` returns an :cpp:expr:`lv_event_cb_t`.
|
||||
:screen_create_cb: In XML it's the name of a screen XML file. In exported code it's a function like ``lv_obj_t * my_screen_create(void)``
|
||||
:screen_create_cb: In XML it's the name of a screen's XML file. In exported code it's a function like ``lv_obj_t * my_screen_create(void)``
|
||||
|
||||
|
||||
Arrays
|
||||
------
|
||||
@@ -121,7 +126,7 @@ Arrays
|
||||
An array of any type can be defined in four ways:
|
||||
|
||||
:int[N]: An integer array with ``N`` elements.
|
||||
In the exported code ``N`` is passed a parameter after the array.
|
||||
In the exported code ``N`` is passed as a parameter after the array.
|
||||
:string[...NULL]: An array terminated with a ``NULL`` element. ``NULL`` can be
|
||||
replaced by any value.
|
||||
:string[5]: An array that must have exactly 5 elements. In the exported code only the array will be passed
|
||||
@@ -146,7 +151,7 @@ For example:
|
||||
<enum name="inverted" help="Inverted mode"/>
|
||||
</enumdef>
|
||||
|
||||
<prop name="mode" help="help"type="enum:my_widget_mode" help="help"/>
|
||||
<prop name="mode" help="help" type="enum:my_widget_mode" help="help"/>
|
||||
</api>
|
||||
|
||||
When used as a type, a ``+`` suffix means multiple values can be selected and ORed.
|
||||
@@ -157,7 +162,7 @@ For example: ``type="axis+"``. In this case, the options should be separated by
|
||||
Compound types
|
||||
--------------
|
||||
|
||||
Types can be compound, meaning multiple options/types are possible. For example, for
|
||||
Types can be compound, meaning multiple options/types are possible. Example for
|
||||
width: ``type="px|%|content"``.
|
||||
|
||||
|
||||
@@ -169,7 +174,7 @@ For example:
|
||||
|
||||
- Enums: ``type="dir(top bottom)"``
|
||||
- Colors: ``type="color(0xff0000 0x00ff00 0x0000ff)"``
|
||||
- Strings: ``type="string('Ok' 'Cancel')``
|
||||
- Strings: ``type="string('Ok' 'Cancel')"``
|
||||
|
||||
Limiting accepted values is not supported yet, however in the UI |nbsp| Editor if
|
||||
an invalid option is selected, it will be highlighted as an error.
|
||||
|
||||
Reference in New Issue
Block a user