mirror of
https://github.com/lvgl/lvgl.git
synced 2026-06-01 00:51:49 +08:00
docs(xml): restructure and extend the XML docs (#8495)
This commit is contained in:
committed by
GitHub
parent
3bcefbc68f
commit
dec36ddb69
@@ -20,4 +20,3 @@ Auxiliary Modules
|
|||||||
snapshot
|
snapshot
|
||||||
test
|
test
|
||||||
translation
|
translation
|
||||||
xml/index
|
|
||||||
|
|||||||
@@ -1,163 +0,0 @@
|
|||||||
.. _xml_components:
|
|
||||||
|
|
||||||
==========
|
|
||||||
Components
|
|
||||||
==========
|
|
||||||
|
|
||||||
Overview
|
|
||||||
********
|
|
||||||
|
|
||||||
``<component>`` the following child elements:
|
|
||||||
|
|
||||||
- ``<consts>``,
|
|
||||||
- ``<api>``,
|
|
||||||
- ``<styles>``, and
|
|
||||||
- ``<view>``.
|
|
||||||
|
|
||||||
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 Exported Code
|
|
||||||
************************
|
|
||||||
|
|
||||||
From each Component XML file, a C and H file is exported with a single function inside:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
lv_obj_t * component_name_create(lv_obj_t * parent, ...api properties...);
|
|
||||||
|
|
||||||
where 'component_name' (in the function above) is replaced by the Component's XML
|
|
||||||
file name.
|
|
||||||
|
|
||||||
When a Component is used in another Component's XML code and the code is exported,
|
|
||||||
this ``create`` function will be called. This means that Components do not have a
|
|
||||||
detailed set/get API but can be created with a fixed set of parameters.
|
|
||||||
|
|
||||||
If the user needs to access or modify values dynamically, it is recommended to use a
|
|
||||||
:ref:`Subject <observer_subject>`.
|
|
||||||
|
|
||||||
The user can also call these ``..._create()`` functions at any time from application code.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Usage from XML
|
|
||||||
**************
|
|
||||||
|
|
||||||
|
|
||||||
Registration
|
|
||||||
------------
|
|
||||||
|
|
||||||
Once a Component is created (e.g., ``my_button``), it can be registered by calling either:
|
|
||||||
|
|
||||||
- ``lv_xml_component_register_from_file("A:lvgl/examples/others/xml/my_button.xml");``
|
|
||||||
- ``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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
When loaded from a file, the file name is used as the Component name.
|
|
||||||
|
|
||||||
|
|
||||||
Instantiation
|
|
||||||
-------------
|
|
||||||
|
|
||||||
After registration, a new instance of any registered Component can be created with:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
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 last parameter can be ``NULL`` or an attribute list, like this:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
/* Can be local */
|
|
||||||
char * my_button_attrs[] = {
|
|
||||||
"x", "10",
|
|
||||||
"y", "-10",
|
|
||||||
"align", "bottom_left",
|
|
||||||
"btn_text", "New button",
|
|
||||||
NULL, NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
lv_obj_t * btn1 = lv_xml_create(lv_screen_active(), "my_button", my_button_attrs);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
**********
|
|
||||||
|
|
||||||
The properties of child elements can be adjusted, such as:
|
|
||||||
|
|
||||||
.. code-block:: xml
|
|
||||||
|
|
||||||
<lv_label x="10" text="Hello"/>
|
|
||||||
|
|
||||||
These parameters can be set to a fixed value. However, with the help of ``<prop>``
|
|
||||||
elements inside the ``<api>`` tag, they can also be passed when an instance is
|
|
||||||
created. Only the whole property can be passed, but not individual ``<param>``
|
|
||||||
elements.
|
|
||||||
|
|
||||||
Additionally, when a Component is created, it can use the extended Widget's attributes
|
|
||||||
(see ``<view extends="...">`` in the code examples below).
|
|
||||||
|
|
||||||
This means that Components inherit the API of the extended Widget as well.
|
|
||||||
|
|
||||||
The following example demonstrates parameter passing and the use of the
|
|
||||||
``text`` label property on a Component:
|
|
||||||
|
|
||||||
.. code-block:: xml
|
|
||||||
|
|
||||||
<!-- h3.xml -->
|
|
||||||
<component>
|
|
||||||
<view extends="lv_label"/>
|
|
||||||
</component>
|
|
||||||
|
|
||||||
.. code-block:: xml
|
|
||||||
|
|
||||||
<!-- red_button.xml -->
|
|
||||||
<component>
|
|
||||||
<api>
|
|
||||||
<prop type="string" name="btn_text" default="None"/>
|
|
||||||
</api>
|
|
||||||
<view extends="lv_button" style_radius="0" style_bg_color="0xff0000">
|
|
||||||
<h3 text="Some text"/>
|
|
||||||
<h3 text="$btn_text" y="40"/>
|
|
||||||
</view>
|
|
||||||
</component>
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
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 */
|
|
||||||
lv_xml_create(lv_screen_active(), "red_button", NULL);
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Example
|
|
||||||
*******
|
|
||||||
|
|
||||||
.. include:: ../../../examples/others/xml/index.rst
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
API
|
|
||||||
***
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
.. _xml_component:
|
|
||||||
|
|
||||||
====================
|
|
||||||
XML - Declarative UI
|
|
||||||
====================
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:class: toctree-1-deep
|
|
||||||
:maxdepth: 1
|
|
||||||
|
|
||||||
intro
|
|
||||||
component_library
|
|
||||||
project
|
|
||||||
syntax
|
|
||||||
|
|
||||||
components
|
|
||||||
screens
|
|
||||||
widgets
|
|
||||||
|
|
||||||
preview
|
|
||||||
api
|
|
||||||
styles
|
|
||||||
consts
|
|
||||||
view
|
|
||||||
fonts
|
|
||||||
images
|
|
||||||
events
|
|
||||||
subjects
|
|
||||||
animations
|
|
||||||
translation
|
|
||||||
test
|
|
||||||
license
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
.. _xml_screens:
|
|
||||||
|
|
||||||
=======
|
|
||||||
Screens
|
|
||||||
=======
|
|
||||||
|
|
||||||
Overview
|
|
||||||
********
|
|
||||||
|
|
||||||
.. |nbsp| unicode:: U+000A0 .. NO-BREAK SPACE
|
|
||||||
:trim:
|
|
||||||
|
|
||||||
Screens work very similarly to Components. Both can be:
|
|
||||||
|
|
||||||
- Loaded from XML
|
|
||||||
- Contain Widgets and Components as children
|
|
||||||
- Have ``<styles>``
|
|
||||||
- Have ``<consts>``
|
|
||||||
- Have a ``<view>``
|
|
||||||
|
|
||||||
However, Screens **cannot** have an ``<api>``.
|
|
||||||
|
|
||||||
It's also possible to define ``<screen permanent="true">`` which
|
|
||||||
will make the screen created automatically.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Usage
|
|
||||||
*****
|
|
||||||
|
|
||||||
Each XML file describes a :ref:`Screen <screens>`. The name of the XML file will
|
|
||||||
also be the name of the Screen.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
This example illustrates a screen in XML:
|
|
||||||
|
|
||||||
.. code-block:: xml
|
|
||||||
|
|
||||||
<screen>
|
|
||||||
<consts>
|
|
||||||
<string name="title" value="Main menu"/>
|
|
||||||
</consts>
|
|
||||||
|
|
||||||
<styles>
|
|
||||||
<style name="dark" bg_color="0x333"/>
|
|
||||||
</styles>
|
|
||||||
|
|
||||||
<view>
|
|
||||||
<header label="#title"/>
|
|
||||||
<selector_container styles="dark">
|
|
||||||
<button text="Weather" icon="cloudy"/>
|
|
||||||
<button text="Messages" icon="envelope"/>
|
|
||||||
<button text="Settings" icon="cogwheel"/>
|
|
||||||
<button text="About" icon="questionmark"/>
|
|
||||||
</selector_container>
|
|
||||||
</view>
|
|
||||||
</screen>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Screen Load and Create events
|
|
||||||
*****************************
|
|
||||||
|
|
||||||
By using the ``<screen_load_event>`` and ``<screen_create_event>`` tags as a child
|
|
||||||
of a widget or component, screens can be loaded or created on a trigger (e.g. click).
|
|
||||||
|
|
||||||
The difference between load and create is that:
|
|
||||||
|
|
||||||
- **load**: Just loads an already existing screen. When the screen is left, it remains in memory,
|
|
||||||
so all states are preserved.
|
|
||||||
- **create**: The screen is created dynamically, and when it's left, it is deleted, so all changes are lost
|
|
||||||
(unless they are saved in ``subjects``).
|
|
||||||
|
|
||||||
Both tags support the following optional attributes:
|
|
||||||
|
|
||||||
- ``trigger``: Event code that triggers the action (e.g. ``"clicked"``, ``"long_pressed"``, etc). Default: ``"clicked"``.
|
|
||||||
- ``anim_type``: Describes how the screen is loaded (e.g. ``"move_right"``, ``"fade_in"``). Default: ``"none"``.
|
|
||||||
- ``duration``: Length of the animation in milliseconds. Default: ``0``. Only used if ``anim_type`` is not ``"none"``.
|
|
||||||
- ``delay``: Wait time before loading the screen in milliseconds.
|
|
||||||
|
|
||||||
This is a simple example of both load and create:
|
|
||||||
|
|
||||||
.. code-block:: xml
|
|
||||||
|
|
||||||
<!-- screen1.xml -->
|
|
||||||
<screen>
|
|
||||||
<view style_bg_color="0xff7788" name="first">
|
|
||||||
<lv_button>
|
|
||||||
<lv_label text="Create"/>
|
|
||||||
<!-- Create an instance of "screen2" and load it.
|
|
||||||
Note that here the name of the XML file is used. -->
|
|
||||||
<screen_create_event screen="screen2" anim_type="over_right" duration="500" delay="1000"/>
|
|
||||||
</lv_button>
|
|
||||||
</view>
|
|
||||||
</screen>
|
|
||||||
|
|
||||||
<!-- screen2.xml -->
|
|
||||||
<screen>
|
|
||||||
<view style_bg_color="0x77ff88" name="second">
|
|
||||||
<lv_button>
|
|
||||||
<lv_label text="Load"/>
|
|
||||||
<!-- Load an already created screen that has the name "first".
|
|
||||||
Note that here the name of the instance is used,
|
|
||||||
and not the name of the XML file. -->
|
|
||||||
<screen_load_event screen="first"/>
|
|
||||||
</lv_button>
|
|
||||||
</view>
|
|
||||||
</screen>
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
lv_xml_component_register_from_data("screen1", screen1_xml);
|
|
||||||
lv_xml_component_register_from_data("screen2", screen2_xml);
|
|
||||||
|
|
||||||
/*Create an instance of screen_1 so that it can loaded from screen2.*/
|
|
||||||
lv_obj_t * screen1 = lv_xml_create(NULL, "screen1", NULL);
|
|
||||||
lv_screen_load(screen1);
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
.. _xml_view:
|
|
||||||
|
|
||||||
=========
|
|
||||||
View
|
|
||||||
=========
|
|
||||||
|
|
||||||
TODO
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
.. _xml_widgets:
|
|
||||||
|
|
||||||
=======
|
|
||||||
Widgets
|
|
||||||
=======
|
|
||||||
|
|
||||||
Overview
|
|
||||||
********
|
|
||||||
|
|
||||||
.. |nbsp| unicode:: U+000A0 .. NO-BREAK SPACE
|
|
||||||
:trim:
|
|
||||||
|
|
||||||
Widgets are written in C and compiled into the application.
|
|
||||||
They can be referenced from Components, and their API can be used via the exposed attributes
|
|
||||||
(e.g., label text or slider value).
|
|
||||||
|
|
||||||
Using the UI |nbsp| Editor, all the following .C/.H files can be exported from the XML of the Widgets:
|
|
||||||
|
|
||||||
:<widget_name>_gen.h: Contains the generated API implementation of the widget
|
|
||||||
(overwritten on each code export).
|
|
||||||
:<widget_name>_private_gen.h: Contains private API and the data for the widget
|
|
||||||
(overwritten on each code export).
|
|
||||||
:<widget_name>_gen.c: Contains the internals of the Widget (overwritten on
|
|
||||||
each code export).
|
|
||||||
:<widget_name>.h: Includes ``<widget_name>_gen.h`` and allows the user to
|
|
||||||
define custom APIs. Only a skeleton is exported once.
|
|
||||||
:<widget_name>.c: Contains hooks from ``<widget_name>_gen.c`` and allows
|
|
||||||
the user to write custom code. Only a skeleton is
|
|
||||||
exported once.
|
|
||||||
:<widget_name>_xml_parser.c: Processes the XML strings and calls the required
|
|
||||||
functions according to the set attributes. Only a
|
|
||||||
skeleton is exported once.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Usage
|
|
||||||
*****
|
|
||||||
|
|
||||||
|
|
||||||
XML Parser
|
|
||||||
----------
|
|
||||||
|
|
||||||
To make the Widgets accessible from XML, an XML parser needs to be created and
|
|
||||||
registered for each Widget. The XML parser for the label Widget looks like this:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
void * lv_xml_label_create(lv_xml_parser_state_t * state, const char ** attrs)
|
|
||||||
{
|
|
||||||
/* Create the label */
|
|
||||||
void * obj = lv_label_create(lv_xml_state_get_parent(state));
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lv_xml_label_apply(lv_xml_parser_state_t * state, const char ** attrs)
|
|
||||||
{
|
|
||||||
void * obj = lv_xml_state_get_item(state);
|
|
||||||
|
|
||||||
/* Apply the common properties, e.g., width, height, styles, flags, etc. */
|
|
||||||
lv_xml_obj_apply(state, attrs);
|
|
||||||
|
|
||||||
/* Process the label-specific attributes */
|
|
||||||
for(int i = 0; attrs[i]; i += 2) {
|
|
||||||
const char * name = attrs[i];
|
|
||||||
const char * value = attrs[i + 1];
|
|
||||||
|
|
||||||
if(lv_streq("text", name)) lv_label_set_text(obj, value);
|
|
||||||
if(lv_streq("long_mode", name)) lv_label_set_long_mode(obj, long_mode_text_to_enum(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Helper to convert the string to enum values */
|
|
||||||
static lv_label_long_mode_t long_mode_text_to_enum(const char * txt)
|
|
||||||
{
|
|
||||||
if(lv_streq("wrap", txt)) return LV_LABEL_LONG_WRAP;
|
|
||||||
if(lv_streq("scroll", txt)) return LV_LABEL_LONG_SCROLL;
|
|
||||||
|
|
||||||
LV_LOG_WARN("%s is an unknown value for label's long_mode", txt);
|
|
||||||
return 0; /* Return 0 in the absence of a better option. */
|
|
||||||
}
|
|
||||||
|
|
||||||
A Widget XML processor can be registered like this:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
lv_xml_widget_register("lv_label", lv_xml_label_create, lv_xml_label_apply);
|
|
||||||
|
|
||||||
After registration, a Widget can be created like this:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
const char * attrs[] = {
|
|
||||||
"text", "Click here",
|
|
||||||
"align", "center",
|
|
||||||
NULL, NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
lv_xml_create(lv_screen_active(), "lv_label", attrs);
|
|
||||||
|
|
||||||
LVGL automatically registers its built-in Widgets, so only custom Widgets need to be
|
|
||||||
registered manually.
|
|
||||||
|
|
||||||
|
|
||||||
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.
|
|
||||||
- **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.
|
|
||||||
|
|
||||||
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
|
|
||||||
``<widget_name>_gen.h``.
|
|
||||||
|
|
||||||
Besides these, any custom code and functions can be freely implemented in this file.
|
|
||||||
+43
-18
@@ -4,6 +4,10 @@
|
|||||||
Fonts
|
Fonts
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
|
||||||
|
.. |nbsp| unicode:: U+000A0 .. NO-BREAK SPACE
|
||||||
|
:trim:
|
||||||
|
|
||||||
Overview
|
Overview
|
||||||
********
|
********
|
||||||
|
|
||||||
@@ -84,26 +88,47 @@ created, and in the initialization function of the Component Library (e.g.,
|
|||||||
In ``lv_style_set_text_font(&style1, <font_name>)``, the created font is referenced.
|
In ``lv_style_set_text_font(&style1, <font_name>)``, the created font is referenced.
|
||||||
|
|
||||||
|
|
||||||
Constants
|
|
||||||
---------
|
|
||||||
|
|
||||||
Constants can also be used with fonts.
|
|
||||||
|
|
||||||
.. code-block:: xml
|
|
||||||
|
|
||||||
<consts>
|
|
||||||
<int name="font_size" value="32">
|
|
||||||
<variant name="size" case="small" value="24"/>
|
|
||||||
</int>
|
|
||||||
</consts>
|
|
||||||
|
|
||||||
<fonts>
|
|
||||||
<bin name="medium" src_path="file.ttf" range="0x20-0x7f" symbols="°" size="#font_size"/>
|
|
||||||
</fonts>
|
|
||||||
|
|
||||||
|
|
||||||
Default Font
|
Default Font
|
||||||
------------
|
------------
|
||||||
|
|
||||||
``"lv_font_default"`` can be used to access ``LV_FONT_DEFAULT``. Other built-in fonts
|
``"lv_font_default"`` can be used to access ``LV_FONT_DEFAULT``. Other built-in fonts
|
||||||
are not exposed by default.
|
are not exposed by default.
|
||||||
|
|
||||||
|
|
||||||
|
Registering fonts
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
If the UI is created from XML at runtime and a ``globals.xml`` is parsed, the ``<... as_file="false">`` tags are skipped
|
||||||
|
because it is assumed that the user manually created the mapping.
|
||||||
|
This is because the XML parser cannot automatically map fonts like:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
lv_font_t my_font;
|
||||||
|
|
||||||
|
to
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<data name="my_font"/>
|
||||||
|
|
||||||
|
To register a font in the XML engine use:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
lv_xml_register_font(scope, "font_name", &my_font);
|
||||||
|
|
||||||
|
``scope`` is usually ``NULL`` to register the font in the global scope.
|
||||||
|
To register a font locally for a component you can get its scope with:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
lv_xml_component_get_scope("component_name");
|
||||||
|
|
||||||
|
After calling this function, when ``"font_name"`` is used as a font in XML, ``&my_font`` will be used.
|
||||||
|
|
||||||
|
Notes for the UI Editor
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
For simplicity, in the UI |nbsp| Editor's preview, fonts are always loaded as tinyttf fonts.
|
||||||
|
It makes the preview dynamic as no code export and compilation is needed when a font changes.
|
||||||
+20
-32
@@ -13,28 +13,14 @@ Overview
|
|||||||
An ``<images>`` section can be added to ``globals.xml`` files. If present, it
|
An ``<images>`` section can be added to ``globals.xml`` files. If present, it
|
||||||
describes how to map images with names.
|
describes how to map images with names.
|
||||||
|
|
||||||
(Later, it might also be possible in Components and Widgets to define local images to
|
|
||||||
keep the global space cleaner.)
|
|
||||||
|
|
||||||
Currently ``<file>`` is the only supported child element, and ``<convert>`` is not
|
|
||||||
yet implemented.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
*****
|
*****
|
||||||
|
|
||||||
.. code-block:: xml
|
.. code-block:: xml
|
||||||
|
|
||||||
<images>
|
<images>
|
||||||
<file name="avatar" src_path="avatar1.png">
|
<file name="avatar" src_path="avatar1.png"/>
|
||||||
<convert path="raw/avatar.svg" width="100px" color_format="L8"/>
|
<data name="logo" src_path="logo1.png" color-format="rgb565" />
|
||||||
</file>
|
|
||||||
|
|
||||||
<data name="logo" src_path="logo1.png" color-format="rgb565" memory="RAM2">
|
|
||||||
<convert path="https://foo.com/image.png" width="50%" height="80%"
|
|
||||||
color_format="RGB565"/>
|
|
||||||
</data>
|
|
||||||
</images>
|
</images>
|
||||||
|
|
||||||
- ``<file>`` means that the image source is used as a file path:
|
- ``<file>`` means that the image source is used as a file path:
|
||||||
@@ -48,10 +34,11 @@ In :cpp:expr:`lv_image_set_src(image, image_name)` ``image_name`` is used
|
|||||||
instead of the path or :cpp:type:`lv_image_dsc_t` pointer.
|
instead of the path or :cpp:type:`lv_image_dsc_t` pointer.
|
||||||
|
|
||||||
|
|
||||||
For simplicity, in the UI |nbsp| Editor preview, images are always loaded as files.
|
Registering images
|
||||||
|
------------------
|
||||||
|
|
||||||
If the UI is created from XML at runtime and a ``globals.xml`` is parsed, the ``<data>`` tags are skipped
|
If the UI is created from XML at runtime and a ``globals.xml`` is parsed, the ``<data>`` tags are skipped
|
||||||
because it is assumed that the user manually created the mapping. This is because the XML parser cannot
|
because it is assumed that the user manually created the mapping. This is because the XML parser cannot
|
||||||
automatically map an image like:
|
automatically map an image like:
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
@@ -64,25 +51,26 @@ to
|
|||||||
|
|
||||||
<data name="my_logo"/>
|
<data name="my_logo"/>
|
||||||
|
|
||||||
|
To register an image path or data in the XML engine use:
|
||||||
|
|
||||||
Constants
|
.. code-block:: cpp
|
||||||
---------
|
|
||||||
|
|
||||||
Constants can be used with images as well.
|
lv_xml_register_image(scope, "image_name", data)
|
||||||
|
|
||||||
.. code-block:: xml
|
``scope`` is usually ``NULL`` to register the image in the global scope.
|
||||||
|
To register an image locally for a component you can get its scope with:
|
||||||
|
|
||||||
<consts>
|
.. code-block:: cpp
|
||||||
<int name="icon_size" value="32">
|
|
||||||
<variant name="size" case="small" value="16"/>
|
|
||||||
</int>
|
|
||||||
</consts>
|
|
||||||
|
|
||||||
<images>
|
lv_xml_component_get_scope("component_name")
|
||||||
<data name="icon_apply" src_path="apply.png">
|
|
||||||
<convert path="raw/apply.png" width="#icon_size"/>
|
After calling this function, when ``"image_name"`` is used as an image source in XML, ``data``
|
||||||
</data>
|
(can be a path or a pointer to an image descriptor) will be used.
|
||||||
</images>
|
|
||||||
|
|
||||||
|
|
||||||
|
Notes for the UI Editor
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
For simplicity, in the UI |nbsp| Editor's preview, images are always loaded as files.
|
||||||
|
It makes the preview dynamic so no code export and compilation is needed when an image changes.
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
.. _xml_assets:
|
||||||
|
|
||||||
|
======
|
||||||
|
Assets
|
||||||
|
======
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:class: toctree-1-deep
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
images
|
||||||
|
fonts
|
||||||
|
|
||||||
+64
@@ -51,6 +51,70 @@ For example, ``callback="my_callback_1"`` will be exported as:
|
|||||||
|
|
||||||
The ``user_data`` is optional. If omitted, ``NULL`` will be passed.
|
The ``user_data`` is optional. If omitted, ``NULL`` will be passed.
|
||||||
|
|
||||||
|
|
||||||
|
.. _xml_events_screen:
|
||||||
|
|
||||||
|
|
||||||
|
Screen Load and Create events
|
||||||
|
*****************************
|
||||||
|
|
||||||
|
By using the ``<screen_load_event>`` and ``<screen_create_event>`` tags as a child
|
||||||
|
of a widget or component, screens can be loaded or created on a trigger (e.g. click).
|
||||||
|
|
||||||
|
The difference between load and create is that:
|
||||||
|
|
||||||
|
- **load**: Just loads an already existing screen. When the screen is left, it remains in memory,
|
||||||
|
so all states are preserved.
|
||||||
|
- **create**: The screen is created dynamically, and when it's left, it is deleted, so all changes are lost
|
||||||
|
(unless they are saved in ``subjects``).
|
||||||
|
|
||||||
|
Both tags support the following optional attributes:
|
||||||
|
|
||||||
|
- ``trigger``: Event code that triggers the action (e.g. ``"clicked"``, ``"long_pressed"``, etc). Default: ``"clicked"``.
|
||||||
|
- ``anim_type``: Describes how the screen is loaded (e.g. ``"move_right"``, ``"fade_in"``). Default: ``"none"``.
|
||||||
|
- ``duration``: Length of the animation in milliseconds. Default: ``0``. Only used if ``anim_type`` is not ``"none"``.
|
||||||
|
- ``delay``: Wait time before loading the screen in milliseconds.
|
||||||
|
|
||||||
|
This is a simple example of both load and create:
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<!-- screen1.xml -->
|
||||||
|
<screen>
|
||||||
|
<view style_bg_color="0xff7788" name="first">
|
||||||
|
<lv_button>
|
||||||
|
<lv_label text="Create"/>
|
||||||
|
<!-- Create an instance of "screen2" and load it.
|
||||||
|
Note that here the name of the XML file is used. -->
|
||||||
|
<screen_create_event screen="screen2" anim_type="over_right" duration="500" delay="1000"/>
|
||||||
|
</lv_button>
|
||||||
|
</view>
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<!-- screen2.xml -->
|
||||||
|
<screen>
|
||||||
|
<view style_bg_color="0x77ff88" name="second">
|
||||||
|
<lv_button>
|
||||||
|
<lv_label text="Load"/>
|
||||||
|
<!-- Load an already created screen that has the name "first".
|
||||||
|
Note that here the name of the instance is used,
|
||||||
|
and not the name of the XML file. -->
|
||||||
|
<screen_load_event screen="first"/>
|
||||||
|
</lv_button>
|
||||||
|
</view>
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
lv_xml_component_register_from_data("screen1", screen1_xml);
|
||||||
|
lv_xml_component_register_from_data("screen2", screen2_xml);
|
||||||
|
|
||||||
|
/*Create an instance of screen_1 so that it can loaded from screen2.*/
|
||||||
|
lv_obj_t * screen1 = lv_xml_create(NULL, "screen1", NULL);
|
||||||
|
lv_obj_set_name(screen1, "first"); /*Will be referenced by this name when loaded*/
|
||||||
|
lv_screen_load(screen1);
|
||||||
|
|
||||||
|
|
||||||
Set subject value
|
Set subject value
|
||||||
*****************
|
*****************
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
.. _xml_build_ui:
|
||||||
|
|
||||||
|
=========
|
||||||
|
Build UIs
|
||||||
|
=========
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:class: toctree-1-deep
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
root_elements/index
|
||||||
|
main_tags/index
|
||||||
|
assets/index
|
||||||
|
events
|
||||||
|
subjects
|
||||||
|
translation
|
||||||
+18
-16
@@ -5,6 +5,7 @@ API
|
|||||||
===
|
===
|
||||||
|
|
||||||
The ``<api>`` tag can be a child of ``<widget>`` and ``<component>`` tags.
|
The ``<api>`` tag can be a child of ``<widget>`` and ``<component>`` tags.
|
||||||
|
(``<screen>``\ s don't support custom APIs.)
|
||||||
|
|
||||||
The only common point is that both Widgets and Components support having
|
The only common point is that both Widgets and Components support having
|
||||||
``<prop>`` (properties) in the ``<api>`` tag to describe their interface.
|
``<prop>`` (properties) in the ``<api>`` tag to describe their interface.
|
||||||
@@ -55,8 +56,8 @@ Default values
|
|||||||
Since each property is passed as an argument to the create function, each must have a value.
|
Since each property is passed as an argument to the create function, each must have a value.
|
||||||
This can be ensured by:
|
This can be ensured by:
|
||||||
|
|
||||||
- Setting them in the XML instance
|
- Simply setting them in the XML instance
|
||||||
- Providing a default value, e.g., ``<prop name="foo" type="string" default="bar"/>``
|
- Providing a default value in the ``<api>``, e.g., ``<prop name="foo" type="string" default="bar"/>``
|
||||||
|
|
||||||
Limitations
|
Limitations
|
||||||
-----------
|
-----------
|
||||||
@@ -72,7 +73,7 @@ Example
|
|||||||
<!-- my_button.xml -->
|
<!-- my_button.xml -->
|
||||||
<component>
|
<component>
|
||||||
<api>
|
<api>
|
||||||
<prop name="button_icon" type="image"/>
|
<prop name="button_icon" type="image" default="NULL"/>
|
||||||
<prop name="button_label" type="string" default="Label"/>
|
<prop name="button_label" type="string" default="Label"/>
|
||||||
</api>
|
</api>
|
||||||
|
|
||||||
@@ -167,6 +168,8 @@ 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.
|
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 parsers must handle mapping enum names to C enums.
|
||||||
|
|
||||||
|
.. _xml_widget_element:
|
||||||
|
|
||||||
<element>
|
<element>
|
||||||
---------
|
---------
|
||||||
|
|
||||||
@@ -175,22 +178,27 @@ Also exclusive to Widgets, elements define sub-widgets or internal structures
|
|||||||
|
|
||||||
They support ``<arg>`` and ``<prop>``:
|
They support ``<arg>`` and ``<prop>``:
|
||||||
|
|
||||||
- ``<arg>``\ s are required and used for creation.
|
- ``<arg>``\ s are required and used when creating/getting the element.
|
||||||
- ``<prop>``\ s are optional and mapped to setters.
|
- ``<prop>``\ s are optional and mapped to setters.
|
||||||
|
|
||||||
Elements are referenced as ``<widget-element>`` in views.
|
Elements are referenced as ``<widget-element>`` in views.
|
||||||
|
|
||||||
Name parts are separated by `-` (not allowed inside names).
|
Name parts are separated by `-` ( as `-` is not allowed inside names).
|
||||||
|
|
||||||
Element `access` types:
|
Element `access` types:
|
||||||
|
|
||||||
- ``add``: Create multiple elements dynamically.
|
- ``add``: Create multiple elements dynamically.
|
||||||
- ``get``: Access implicitly created elements.
|
- ``get``: Access implicitly created elements.
|
||||||
- ``set``: Access indexed parts (e.g., table cells).
|
- ``set``: Access indexed parts (e.g., table cells).
|
||||||
|
- ``custom``: Map custom C function to XML.
|
||||||
|
|
||||||
``type="obj"`` allows children; custom types do not.
|
As ``add`` and ``get`` elements return an object they also have a type.
|
||||||
|
This type can be any custom type, for example, `type="my_data"`. In the exported code the
|
||||||
|
return value will be saved in a ``my_data_t *`` variable.
|
||||||
|
|
||||||
Only the API can be defined in XML for elements; implementations must be in C.
|
If the type is ``type="lv_obj"`` it allows the element to have children widgets or components.
|
||||||
|
|
||||||
|
Note that, only the API can be defined in XML for elements; implementations must be in C.
|
||||||
|
|
||||||
access="add"
|
access="add"
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
@@ -234,9 +242,7 @@ Used for internal/implicit elements:
|
|||||||
<api>
|
<api>
|
||||||
<element name="control_button" type="obj" help="A control button of my_widget" access="get">
|
<element name="control_button" type="obj" help="A control button of my_widget" access="get">
|
||||||
<arg name="index" type="int"/>
|
<arg name="index" type="int"/>
|
||||||
<prop name="title">
|
<prop name="title" type="string"/>
|
||||||
<param name="text" type="string"/>
|
|
||||||
</prop>
|
|
||||||
</element>
|
</element>
|
||||||
</api>
|
</api>
|
||||||
|
|
||||||
@@ -265,12 +271,8 @@ Used for indexed access, like setting values in a table:
|
|||||||
<api>
|
<api>
|
||||||
<element name="item" type="obj" access="set">
|
<element name="item" type="obj" access="set">
|
||||||
<arg name="index" type="int"/>
|
<arg name="index" type="int"/>
|
||||||
<prop name="icon">
|
<prop name="icon" type="img_src"/>
|
||||||
<param name="icon_src" type="img_src"/>
|
<prop name="color" type="color"/>
|
||||||
</prop>
|
|
||||||
<prop name="color">
|
|
||||||
<param name="color" type="color"/>
|
|
||||||
</prop>
|
|
||||||
</element>
|
</element>
|
||||||
</api>
|
</api>
|
||||||
|
|
||||||
-31
@@ -18,7 +18,6 @@ The supported types are:
|
|||||||
- ``bool``
|
- ``bool``
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
*****
|
*****
|
||||||
|
|
||||||
@@ -41,33 +40,3 @@ And they can be used like this:
|
|||||||
<styles>
|
<styles>
|
||||||
<style name="style1" bg_color="#color1"/>
|
<style name="style1" bg_color="#color1"/>
|
||||||
</styles>
|
</styles>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Variants
|
|
||||||
********
|
|
||||||
|
|
||||||
Constants support a ``<variant>`` attribute to change the constants at compile time. For example:
|
|
||||||
|
|
||||||
.. code-block:: xml
|
|
||||||
|
|
||||||
<consts>
|
|
||||||
<px name="pad" value="8" help="General padding">
|
|
||||||
<variant name="size" case="small" value="4"/>
|
|
||||||
<variant name="size" case="large" value="12"/>
|
|
||||||
</px>
|
|
||||||
</consts>
|
|
||||||
|
|
||||||
from which the following C code can be exported:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
#if SIZE == SMALL
|
|
||||||
#define PAD 4
|
|
||||||
#elif SIZE == LARGE
|
|
||||||
#define PAD 12
|
|
||||||
#else
|
|
||||||
#define PAD 8
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Where ``SMALL`` and ``LARGE`` are just preprocessor defines with incremental values.
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
.. _xml_main_tags:
|
||||||
|
|
||||||
|
=========
|
||||||
|
Main tags
|
||||||
|
=========
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:class: toctree-1-deep
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
api
|
||||||
|
consts
|
||||||
|
styles
|
||||||
|
view
|
||||||
|
animations
|
||||||
|
preview
|
||||||
+11
-3
@@ -21,6 +21,7 @@ For example, you might want to:
|
|||||||
- Set margins.
|
- Set margins.
|
||||||
- Change the size of the preview.
|
- Change the size of the preview.
|
||||||
|
|
||||||
|
``style_radius`` can be used to make preview rounded.
|
||||||
|
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
@@ -44,9 +45,16 @@ Example
|
|||||||
|
|
||||||
<component>
|
<component>
|
||||||
<previews>
|
<previews>
|
||||||
<preview name="small_dark" width="content" height="100" style_bg_color="0x333" style_pad_all="32"/>
|
|
||||||
<preview name="centered" width="200" height="100" flex="row center"/>
|
<preview name="small_dark_round"
|
||||||
<preview name="large_light" width="1980" height="1080" style_bg_color="0xeeeeee"/>
|
width="240" height="240"
|
||||||
|
style_bg_color="0x333" style_pad_all="32"
|
||||||
|
style_radius="32"/>
|
||||||
|
|
||||||
|
<preview name="large_light"
|
||||||
|
width="1980" height="1080"
|
||||||
|
style_bg_color="0xeeeeee"/>
|
||||||
|
|
||||||
</previews>
|
</previews>
|
||||||
|
|
||||||
<view>
|
<view>
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
.. _xml_view:
|
||||||
|
|
||||||
|
=========
|
||||||
|
View
|
||||||
|
=========
|
||||||
|
|
||||||
|
Overview
|
||||||
|
********
|
||||||
|
|
||||||
|
The ``<view>`` tag can be used in:
|
||||||
|
|
||||||
|
- ``<component>``\ s
|
||||||
|
- ``<widget>``\ s
|
||||||
|
- ``<screen>``\ s
|
||||||
|
- ``<test>``\ s
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<view>
|
||||||
|
<lv_button width="200">
|
||||||
|
<my_icon src="image1"/>
|
||||||
|
<lv_label text="Click me"/>
|
||||||
|
</lv_button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
Extends
|
||||||
|
*******
|
||||||
|
|
||||||
|
The ``<view>`` itself is also a widget or component, which will become the parent of the children.
|
||||||
|
To define the type of the ``<view>``, use the ``extends`` attribute. For example, ``extends="lv_slider"``.
|
||||||
|
In this case, an ``lv_slider`` will be created first, and the children will be added to it.
|
||||||
|
|
||||||
|
By adding properties to the ``<view>``, the extended type can be customized. For example:
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<view extends="lv_slider" width="100%" style_bg_color="0xff8800" flex_flow="row">
|
||||||
|
<style name="my_style" selector="pressed|knob"/>
|
||||||
|
<lv_label text="Current value: "/>
|
||||||
|
<lv_label bind_text="subject_1"/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
Rules for the allowed values of ``extends``:
|
||||||
|
|
||||||
|
- ``<component>``: can extend both ``<widget>``\ s and ``<component>``\ s
|
||||||
|
- ``<widget>``: can extend only ``<widget>``\ s
|
||||||
|
- ``<screen>``: cannot extend anything
|
||||||
|
- ``<test>``: can extend ``<widget>``, ``<component>``, or ``<screen>``
|
||||||
@@ -0,0 +1,244 @@
|
|||||||
|
.. _xml_components:
|
||||||
|
|
||||||
|
==========
|
||||||
|
Components
|
||||||
|
==========
|
||||||
|
|
||||||
|
Overview
|
||||||
|
********
|
||||||
|
|
||||||
|
Components are one of the main building blocks for creating new UI elements.
|
||||||
|
|
||||||
|
``<component>``\ s support the following child XML tags:
|
||||||
|
|
||||||
|
- :ref:`<consts> <xml_consts>`
|
||||||
|
- :ref:`<api> <xml_api>`
|
||||||
|
- :ref:`<styles> <xml_styles>`, and
|
||||||
|
- :ref:`<view> <xml_view>`
|
||||||
|
- :ref:`<previews> <xml_preview>`
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
**************
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<!-- my_button.xml -->
|
||||||
|
<component>
|
||||||
|
<view extends="lv_button" flex_flow="row">
|
||||||
|
<lv_image src="logo"/>
|
||||||
|
<my_h3 text="Title"/>
|
||||||
|
</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.
|
||||||
|
|
||||||
|
Registration
|
||||||
|
------------
|
||||||
|
|
||||||
|
Once a Component is created (e.g., ``my_button``), it can be registered by calling either:
|
||||||
|
|
||||||
|
- :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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
When loaded from a file, the file name is used as the Component name.
|
||||||
|
|
||||||
|
During registration, the ``<view>`` of the Component is saved in RAM.
|
||||||
|
|
||||||
|
Instantiation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
After registration, a new instance of any registered Component can be created with:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
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 last parameter can be ``NULL`` or an attribute list, like this:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
/* Can be local */
|
||||||
|
char * my_button_attrs[] = {
|
||||||
|
"x", "10",
|
||||||
|
"y", "-10",
|
||||||
|
"align", "bottom_left",
|
||||||
|
NULL, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
lv_obj_t * btn1 = lv_xml_create(lv_screen_active(), "my_button", my_button_attrs);
|
||||||
|
|
||||||
|
Usage from Exported Code
|
||||||
|
************************
|
||||||
|
|
||||||
|
From each Component XML file, a C and H file is exported with a single function inside:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
lv_obj_t * component_name_create(lv_obj_t * parent, ...api properties...);
|
||||||
|
|
||||||
|
where 'component_name' (in the function above) is replaced by the Component's XML
|
||||||
|
file name.
|
||||||
|
|
||||||
|
When a Component is used in another Component's XML code and the code is exported,
|
||||||
|
this ``create`` function will be called. This means that Components do not have a
|
||||||
|
detailed set/get API but can be created with a fixed set of parameters.
|
||||||
|
|
||||||
|
If the user needs to access or modify values dynamically, it is recommended to use a
|
||||||
|
:ref:`Data bindings via Subject <xml_subjects>`.
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
This means that Components inherit the API of the extended Widget as well.
|
||||||
|
|
||||||
|
.. _component_custom_api:
|
||||||
|
|
||||||
|
Custom Properties
|
||||||
|
*****************
|
||||||
|
|
||||||
|
The properties of child elements can be adjusted, 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:
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<!-- my_button.xml -->
|
||||||
|
<component>
|
||||||
|
<api>
|
||||||
|
<prop name="btn_text" type="string"/>
|
||||||
|
</api>
|
||||||
|
|
||||||
|
<view extends="lv_button">
|
||||||
|
<lv_label text="$btn_text"/>
|
||||||
|
</view>
|
||||||
|
</component>
|
||||||
|
|
||||||
|
And it can be used like
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<!-- my_list.xml -->
|
||||||
|
<component>
|
||||||
|
<view>
|
||||||
|
<my_button btn_text="First"/>
|
||||||
|
<my_button btn_text="Second"/>
|
||||||
|
<my_button btn_text="Third"/>
|
||||||
|
</view>
|
||||||
|
</component>
|
||||||
|
|
||||||
|
In this setup, the ``btn_text`` property is mandatory, however it can be made optional
|
||||||
|
by setting a default value:
|
||||||
|
|
||||||
|
.. 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.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
********
|
||||||
|
|
||||||
|
The following example demonstrates parameter passing and the use of the
|
||||||
|
``text`` label property on a Component. Styles and Constants are also shown.
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<!-- h3.xml -->
|
||||||
|
<component>
|
||||||
|
<view extends="lv_label" style_text_color="0xffff00"/>
|
||||||
|
</component>
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<!-- red_button.xml -->
|
||||||
|
<component>
|
||||||
|
<api>
|
||||||
|
<prop type="string" name="btn_text" default="None"/>
|
||||||
|
</api>
|
||||||
|
|
||||||
|
<consts>
|
||||||
|
<int name="thin" value="2"/>
|
||||||
|
</consts>
|
||||||
|
|
||||||
|
<styles>
|
||||||
|
<style name="pressed_style" border_width="#thin" border_color="0xff0000"/>
|
||||||
|
</styles>
|
||||||
|
|
||||||
|
<view extends="lv_button" style_radius="0" style_bg_color="0xff0000">
|
||||||
|
<style name="pressed_style" selector="pressed"/>
|
||||||
|
|
||||||
|
<h3 text="Some text"/>
|
||||||
|
<h3 text="$btn_text" y="40"/>
|
||||||
|
</view>
|
||||||
|
</component>
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
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 */
|
||||||
|
lv_xml_create(lv_screen_active(), "red_button", NULL);
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
***
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
.. _xml_root_elements:
|
||||||
|
|
||||||
|
=============
|
||||||
|
Root elements
|
||||||
|
=============
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:class: toctree-1-deep
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
components
|
||||||
|
widgets
|
||||||
|
screens
|
||||||
|
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
.. _xml_screens:
|
||||||
|
|
||||||
|
=======
|
||||||
|
Screens
|
||||||
|
=======
|
||||||
|
|
||||||
|
Overview
|
||||||
|
********
|
||||||
|
|
||||||
|
.. |nbsp| unicode:: U+000A0 .. NO-BREAK SPACE
|
||||||
|
:trim:
|
||||||
|
|
||||||
|
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
|
||||||
|
the content of the UI.
|
||||||
|
|
||||||
|
Screens can have only the following child XML tags:
|
||||||
|
|
||||||
|
- :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>`.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
*****
|
||||||
|
|
||||||
|
Each XML file describes a :ref:`Screen <screens>`. The name of the XML file will
|
||||||
|
also be the name of the Screen.
|
||||||
|
|
||||||
|
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"/>
|
||||||
|
</consts>
|
||||||
|
|
||||||
|
<styles>
|
||||||
|
<style name="dark" bg_color="0x333"/>
|
||||||
|
</styles>
|
||||||
|
|
||||||
|
<view>
|
||||||
|
<my_header label="#title"/>
|
||||||
|
<my_main_cont>
|
||||||
|
<style name="dark"/>
|
||||||
|
|
||||||
|
<button text="Weather" icon="cloudy"/>
|
||||||
|
<button text="Messages" icon="envelope"/>
|
||||||
|
<button text="Settings" icon="cogwheel"/>
|
||||||
|
<button text="About" icon="questionmark"/>
|
||||||
|
</my_main_cont>
|
||||||
|
</view>
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
Code export
|
||||||
|
***********
|
||||||
|
|
||||||
|
When the 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
|
||||||
|
``<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.
|
||||||
|
|
||||||
|
Both are supported by adding special XML tags as children of Components or Widgets:
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<view>
|
||||||
|
<lv_button>
|
||||||
|
<lv_label text="Click or Long press me"/>
|
||||||
|
|
||||||
|
<!-- Load an already created screen that has the name "first".
|
||||||
|
Note that here the name of the instance is used,
|
||||||
|
and 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. -->
|
||||||
|
<screen_create_event screen="about" trigger="long_pressed"/>
|
||||||
|
</lv_button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
Learn more on :ref:`XML Events <xml_events_screen>` page.
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
.. _xml_widgets:
|
||||||
|
|
||||||
|
=======
|
||||||
|
Widgets
|
||||||
|
=======
|
||||||
|
|
||||||
|
Overview
|
||||||
|
********
|
||||||
|
|
||||||
|
.. |nbsp| unicode:: U+000A0 .. NO-BREAK SPACE
|
||||||
|
: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.
|
||||||
|
|
||||||
|
``<widget>``\ s support the following child XML tags:
|
||||||
|
|
||||||
|
- :ref:`<consts> <xml_consts>`
|
||||||
|
- :ref:`<api> <xml_api>`
|
||||||
|
- :ref:`<styles> <xml_styles>`, and
|
||||||
|
- :ref:`<view> <xml_view>`
|
||||||
|
- :ref:`<previews> <xml_preview>`
|
||||||
|
|
||||||
|
Just like Components, Widgets also can be the children of other Widgets and Components.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<view>
|
||||||
|
<lv_label x="10" text="Hello"/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
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.
|
||||||
|
- 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.
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
:<widget_name>_gen.h: Contains the generated API implementation of the widget
|
||||||
|
(overwritten on each code export).
|
||||||
|
:<widget_name>_private_gen.h: Contains private API and the data for the widget
|
||||||
|
(overwritten on each code export).
|
||||||
|
:<widget_name>_gen.c: Contains the internals of the Widget, e.g. constructor with the children,
|
||||||
|
destructors, event handler, etc. (overwritten on each code export).
|
||||||
|
:<widget_name>.h: Includes ``<widget_name>_gen.h`` and allows the user to
|
||||||
|
define custom APIs. Only a skeleton is exported once.
|
||||||
|
:<widget_name>.c: Contains hooks from ``<widget_name>_gen.c`` and allows
|
||||||
|
the user to write custom code. Only a skeleton is
|
||||||
|
exported once.
|
||||||
|
:<widget_name>_xml_parser.c: Processes the XML strings and calls the required
|
||||||
|
functions according to the set attributes. Only a
|
||||||
|
skeleton is exported once.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
*****
|
||||||
|
|
||||||
|
XML Parser
|
||||||
|
----------
|
||||||
|
|
||||||
|
To make the Widgets accessible from XML, an XML parser needs to be created and
|
||||||
|
registered for each Widget. The XML parser for the label Widget looks like this:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
void * lv_xml_label_create(lv_xml_parser_state_t * state, const char ** attrs)
|
||||||
|
{
|
||||||
|
/* Create the label */
|
||||||
|
void * obj = lv_label_create(lv_xml_state_get_parent(state));
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lv_xml_label_apply(lv_xml_parser_state_t * state, const char ** attrs)
|
||||||
|
{
|
||||||
|
void * obj = lv_xml_state_get_item(state);
|
||||||
|
|
||||||
|
/* Apply the common properties, e.g., width, height, styles, flags, etc. */
|
||||||
|
lv_xml_obj_apply(state, attrs);
|
||||||
|
|
||||||
|
/* Process the label-specific attributes */
|
||||||
|
for(int i = 0; attrs[i]; i += 2) {
|
||||||
|
const char * name = attrs[i];
|
||||||
|
const char * value = attrs[i + 1];
|
||||||
|
|
||||||
|
if(lv_streq("text", name)) lv_label_set_text(obj, value);
|
||||||
|
if(lv_streq("long_mode", name)) lv_label_set_long_mode(obj, long_mode_text_to_enum(value));
|
||||||
|
/* Process more props here */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Helper to convert strings to enum values */
|
||||||
|
static lv_label_long_mode_t long_mode_text_to_enum(const char * txt)
|
||||||
|
{
|
||||||
|
if(lv_streq("wrap", txt)) return LV_LABEL_LONG_WRAP;
|
||||||
|
if(lv_streq("scroll", txt)) return LV_LABEL_LONG_SCROLL;
|
||||||
|
|
||||||
|
LV_LOG_WARN("%s is an unknown value for label's long_mode", txt);
|
||||||
|
return 0; /* Return 0 in the absence of a better option. */
|
||||||
|
}
|
||||||
|
|
||||||
|
A Widget XML processor can be registered like this:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
lv_xml_widget_register("lv_label", lv_xml_label_create, lv_xml_label_apply);
|
||||||
|
|
||||||
|
After registration, a Widget can be created like this from C code:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
const char * attrs[] = {
|
||||||
|
"text", "Click here",
|
||||||
|
"align", "center",
|
||||||
|
NULL, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
lv_xml_create(lv_screen_active(), "lv_label", attrs);
|
||||||
|
|
||||||
|
And in XML it can be used like
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<view>
|
||||||
|
<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.
|
||||||
|
- **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.
|
||||||
|
|
||||||
|
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
|
||||||
|
``<widget_name>_gen.h``.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Just like any other Widget API properties, Elements also can be defined in the ``<api>``
|
||||||
|
tag of the Widget's XML.
|
||||||
|
|
||||||
|
Learn more about the Elements in the documentation page of :ref:`<api> <xml_widget_element>`.
|
||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
.. _xml_subjects:
|
.. _xml_subjects:
|
||||||
|
|
||||||
========
|
=======================
|
||||||
Subjects
|
Data binding (Subjects)
|
||||||
========
|
=======================
|
||||||
|
|
||||||
Overview
|
Overview
|
||||||
********
|
********
|
||||||
+2
-7
@@ -9,6 +9,8 @@ Overview
|
|||||||
|
|
||||||
The XML translation module allows defining and using translated strings directly within XML files.
|
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.
|
||||||
|
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
@@ -51,10 +53,3 @@ Some widget properties support a ``*-translated`` suffix to refer to translation
|
|||||||
|
|
||||||
This sets the label's text to the translated string for ``"dog"``.
|
This sets the label's text to the translated string for ``"dog"``.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
More Details
|
|
||||||
************
|
|
||||||
|
|
||||||
For information on selecting the active language, retrieving translations, and fallback behavior,
|
|
||||||
refer to the general :ref:`LVGL translation module <translation>`.
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
.. _xml_main:
|
||||||
|
|
||||||
|
====================
|
||||||
|
XML - Declarative UI
|
||||||
|
====================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:class: toctree-1-deep
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
overview/index
|
||||||
|
build_ui/index
|
||||||
|
test
|
||||||
|
license
|
||||||
+18
-13
@@ -12,21 +12,26 @@ License
|
|||||||
1. Overview
|
1. Overview
|
||||||
===========
|
===========
|
||||||
|
|
||||||
The LVGL XML Format (the "Specification") defines an XML-based language for describing user interfaces within the LVGL ecosystem.
|
The LVGL XML Specification (the "Specification") defines an XML-based language for describing user interfaces within the LVGL ecosystem.
|
||||||
|
|
||||||
This Specification is protected by copyright. It is provided with limited rights of use as outlined below.
|
This Specification is protected by copyright. It is provided with limited rights of use as outlined below.
|
||||||
|
|
||||||
|
The purpose of this license is to ensure that the Specification remains freely usable for application developers working with LVGL,
|
||||||
|
while restricting its use in third-party UI editors or design tools.
|
||||||
|
This protects the long-term integrity and sustainability of the LVGL ecosystem by preventing unlicensed tools
|
||||||
|
from reusing or replicating the Specification in ways that compete with official LVGL offerings.
|
||||||
|
|
||||||
|
|
||||||
2. Permitted Usage
|
2. Permitted Usage
|
||||||
==================
|
==================
|
||||||
|
|
||||||
You are permitted to:
|
You are permitted to:
|
||||||
|
|
||||||
- Use this format in **any firmware or embedded application** built on top of the official `LVGL library <https://github.com/lvgl/lvgl>`_ (MIT-licensed).
|
- Use this Specification in **any firmware or embedded application** built on top of the official `LVGL library <https://github.com/lvgl/lvgl>`_ (MIT-licensed).
|
||||||
- Use the LVGL XML loader freely in accordance with its MIT license.
|
- Use the LVGL XML loader freely in accordance with its MIT license.
|
||||||
- Use the format with the **LVGL UI Editor** and **official LVGL tools such as the CLI or XML loader**.
|
- Use the Specification with the **LVGL UI Editor** and **official LVGL tools such as the CLI or XML loader**.
|
||||||
- Write, load, edit, or generate user interfaces described in the LVGL XML format for **internal use** only, including automation or configuration tools used solely inside your organization.
|
- Write, load, edit, or generate user interfaces described in the LVGL XML Specification for **internal use** only, including automation or configuration tools used solely inside your organization.
|
||||||
- Create **internal scripts or plugins** that help your own developers use or manage this format, as long as these are **not shared outside your organization or made publicly available**.
|
- Create **internal scripts or plugins** that help your own developers use or manage this Specification, as long as these are **not shared outside your organization or made publicly available**.
|
||||||
- Share XML-based UI files within customer firmware or projects that target LVGL-based embedded systems.
|
- Share XML-based UI files within customer firmware or projects that target LVGL-based embedded systems.
|
||||||
|
|
||||||
|
|
||||||
@@ -35,11 +40,11 @@ You are permitted to:
|
|||||||
|
|
||||||
You are **not permitted** to:
|
You are **not permitted** to:
|
||||||
|
|
||||||
- Create, release, or distribute any **UI editor, visual builder, layout designer, code generator, or tool** that reads, writes, or interprets this format — **whether commercial, open-source, or intended for public use, use by customers or partners, or any use outside your own organization** — without written permission from LVGL LLC.
|
- Create, release, or distribute any **UI editor, visual builder, layout designer, code generator, or tool** that reads, writes, or interprets XML files using this Specification — **whether commercial, open-source, or intended for public use, use by customers or partners, or any use outside your own organization** — without written permission from LVGL LLC.
|
||||||
- Implement or extend this Specification in any **software or platform that provides UI creation, editing, or design capabilities similar to those in the LVGL UI Editor**.
|
- Implement or extend this Specification in any **software or platform that provides UI creation, editing, or design capabilities similar to those in the LVGL UI Editor**.
|
||||||
- Build public APIs, plugins, converters, or SDKs based on this format.
|
- Build public APIs, plugins, converters, or SDKs based on this Specification.
|
||||||
- Share or publish internal tooling built around this format.
|
- Share or publish internal tooling built around this Specification.
|
||||||
- Embed this format into general-purpose design tools or frameworks outside the LVGL ecosystem.
|
- Use this Specification into general-purpose design tools or frameworks outside the LVGL ecosystem.
|
||||||
|
|
||||||
These restrictions apply regardless of whether the software is commercial, free, or open-source.
|
These restrictions apply regardless of whether the software is commercial, free, or open-source.
|
||||||
|
|
||||||
@@ -48,16 +53,16 @@ These restrictions apply regardless of whether the software is commercial, free,
|
|||||||
|
|
||||||
You are **explicitly permitted** to:
|
You are **explicitly permitted** to:
|
||||||
|
|
||||||
- Use this XML format in your own projects.
|
- Use XML files with this Specification in your own projects.
|
||||||
- Load XMLs at runtime using LVGL’s XML loader.
|
- Load XMLs at runtime using LVGL’s XML loader.
|
||||||
- Generate XMLs using the LVGL UI Editor.
|
- Generate XMLs using the LVGL UI Editor.
|
||||||
- Customize XMLs manually or with internal utilities.
|
- Customize XMLs manually or with internal utilities.
|
||||||
- Share LVGL-based projects with XML files as part of a commercial product or firmware.
|
- Share LVGL-based projects with XML files as part of a commercial product or firmware.
|
||||||
|
|
||||||
If you are building embedded software using LVGL, **this license does not affect you**.
|
If you are building embedded software using LVGL, **this license does not affect you**.
|
||||||
This license only applies to **UI development tools** that **read, generate, or process this XML format for UI development purposes** in a public or commercial manner.
|
This license only applies to **UI development tools** that **read, generate, or process XML files using this Specification for UI development purposes** in a public or commercial manner.
|
||||||
|
|
||||||
You may create **internal tools** to aid development using the format, but these must not be published, sold, or shared externally without a license.
|
You may create **internal tools** to aid development using the Specification, but these must not be published, sold, or shared externally without a license.
|
||||||
|
|
||||||
|
|
||||||
5. Trademarks
|
5. Trademarks
|
||||||
@@ -69,7 +74,7 @@ This license does not grant any rights to use the LVGL name, logo, or trademarks
|
|||||||
6. Licensing and Permissions
|
6. Licensing and Permissions
|
||||||
============================
|
============================
|
||||||
|
|
||||||
To request permission for broader use or commercial licensing (e.g. using this format in your own UI tool), contact:
|
To request permission for broader use or commercial licensing (e.g. using this Specification in your own UI tool), contact:
|
||||||
|
|
||||||
**lvgl@lvgl.io**
|
**lvgl@lvgl.io**
|
||||||
|
|
||||||
+2
-35
@@ -17,7 +17,7 @@ A Component Library can be fully self-sufficient, but it can also reference data
|
|||||||
other Component Libraries.
|
other Component Libraries.
|
||||||
|
|
||||||
LVGL itself is a Component Library that supplies the built-in Widgets, data types,
|
LVGL itself is a Component Library that supplies the built-in Widgets, data types,
|
||||||
etc., so typically Component Libraries use at least the core LVGL data. You can
|
etc. You can
|
||||||
find the XML files that describe the LVGL Widgets
|
find the XML files that describe the LVGL Widgets
|
||||||
`here <https://github.com/lvgl/lvgl/tree/master/xmls>`__.
|
`here <https://github.com/lvgl/lvgl/tree/master/xmls>`__.
|
||||||
|
|
||||||
@@ -26,7 +26,6 @@ above, and its own where the Screens, Components, and Widgets of the project are
|
|||||||
defined. A project may include additional Component Libraries.
|
defined. A project may include additional Component Libraries.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Structure
|
Structure
|
||||||
*********
|
*********
|
||||||
|
|
||||||
@@ -64,7 +63,6 @@ A typical structure for a Component Library looks like this:
|
|||||||
└── image2.png
|
└── image2.png
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Visibility
|
Visibility
|
||||||
**********
|
**********
|
||||||
|
|
||||||
@@ -124,22 +122,6 @@ included by all generated header files --- not only in the sub-folders where
|
|||||||
constants, fonts, and other global data are available for all Widgets and new Widgets.
|
constants, fonts, and other global data are available for all Widgets and new Widgets.
|
||||||
|
|
||||||
|
|
||||||
Variants
|
|
||||||
--------
|
|
||||||
|
|
||||||
``<const_variant>`` can be used by constants to create variants that can be selected at compile time.
|
|
||||||
This can be used to select a different display size, color scheme, etc.
|
|
||||||
|
|
||||||
``<style_variant>`` can be used by styles only, to modify styles at runtime. To
|
|
||||||
select the current style variant, an integer :ref:`Subject <observer_subject>` (i.e.
|
|
||||||
a Subject containing an integer value in the Observer Pattern implemented in
|
|
||||||
``lv_observer.c/.h``) ``<style_variant.name>_variant`` is created. Styles can
|
|
||||||
subscribe to this, and the style properties can be changed according to the selected
|
|
||||||
variant's integer value. (See `observer` for details about how to do this.)
|
|
||||||
|
|
||||||
All possible variants should be defined in ``globals.xml``.
|
|
||||||
|
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
|
|
||||||
@@ -148,21 +130,6 @@ A ``globals.xml`` file of a Component Library might look like this:
|
|||||||
.. code-block:: xml
|
.. code-block:: xml
|
||||||
|
|
||||||
<globals>
|
<globals>
|
||||||
<config name="mylib" help="This is my great Component Library"/>
|
|
||||||
<const_variants>
|
|
||||||
<const_variant name="size" help="Select the size">
|
|
||||||
<case name="small" help="Assets for 320x240 Screen"/>
|
|
||||||
<case name="large" help="Assets for 1280x768 Screen"/>
|
|
||||||
</const_variant>
|
|
||||||
</const_variants>
|
|
||||||
|
|
||||||
<style_variants>
|
|
||||||
<style_variant name="color" help="Select the color of the UI">
|
|
||||||
<case name="red" help="Select a red theme"/>
|
|
||||||
<case name="blue" help="Select a blue theme"/>
|
|
||||||
</style_variant>
|
|
||||||
</style_variants>
|
|
||||||
|
|
||||||
<api>
|
<api>
|
||||||
<enumdef name="mode">
|
<enumdef name="mode">
|
||||||
<enum name="slow"/>
|
<enum name="slow"/>
|
||||||
@@ -176,7 +143,7 @@ A ``globals.xml`` file of a Component Library might look like this:
|
|||||||
</consts>
|
</consts>
|
||||||
|
|
||||||
<styles>
|
<styles>
|
||||||
<style name="card" bg_color="0xeee" radius="#small_unit" padding="12px"/>
|
<style name="style_red" bg_color="0xff0000">
|
||||||
</styles>
|
</styles>
|
||||||
|
|
||||||
<images>
|
<images>
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
.. _xml_overview:
|
||||||
|
|
||||||
|
========
|
||||||
|
Overview
|
||||||
|
========
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:class: toctree-1-deep
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
intro
|
||||||
|
component_library
|
||||||
|
project
|
||||||
|
syntax
|
||||||
|
|
||||||
+52
-70
@@ -4,24 +4,21 @@
|
|||||||
Introduction
|
Introduction
|
||||||
============
|
============
|
||||||
|
|
||||||
Overview
|
|
||||||
********
|
|
||||||
|
|
||||||
.. |nbsp| unicode:: U+000A0 .. NO-BREAK SPACE
|
.. |nbsp| unicode:: U+000A0 .. NO-BREAK SPACE
|
||||||
:trim:
|
:trim:
|
||||||
|
|
||||||
LVGL is capable of loading UI elements written in XML. The XML file can be written by hand, but
|
LVGL is capable of loading UI elements written in XML. The XML file can be written by hand, but
|
||||||
it's highly recommended to use LVGL's UI |nbsp| Editor to write the XML files. The UI |nbsp| Editor provides
|
it's highly recommended to use `LVGL's UI |nbsp| Editor <https://lvgl.io/editor>`__ to write the XML files. The UI |nbsp| Editor provides
|
||||||
features like:
|
features like:
|
||||||
|
|
||||||
- Instant preview the XML files
|
- Instant preview of the XML files
|
||||||
- Autocomplete and Syntax highlighting
|
- Autocomplete and Syntax highlighting
|
||||||
- Online preview for collaboration and testing
|
- Online preview for collaboration and testing
|
||||||
- `Figma <https://www.figma.com/>`__ integration to easily reimplement the designs
|
- `Figma <https://www.figma.com/>`__ integration to easily reimplement the designs
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
The UI |nbsp| Editor and the XML loader are still under development and not production ready.
|
The UI |nbsp| Editor and the XML loader are still under development and not production-ready.
|
||||||
Consider them as an open beta, or experimental features.
|
Consider them as an open beta, or experimental features.
|
||||||
|
|
||||||
Describing the UI in XML in a declarative manner offers several advantages:
|
Describing the UI in XML in a declarative manner offers several advantages:
|
||||||
@@ -32,30 +29,6 @@ Describing the UI in XML in a declarative manner offers several advantages:
|
|||||||
- XML can be used to generate LVGL code in any language.
|
- XML can be used to generate LVGL code in any language.
|
||||||
- XML helps to separate the view from the internal logic.
|
- XML helps to separate the view from the internal logic.
|
||||||
|
|
||||||
Currently supported features:
|
|
||||||
|
|
||||||
- Load XML Components at runtime from file or any type of input
|
|
||||||
- Nest Components and Widgets to any depth
|
|
||||||
- Dynamically create instances of XML Components in C
|
|
||||||
- Register images and font that can be accessed by name later in the XML data (only from
|
|
||||||
file, no C file is generated for images and fonts)
|
|
||||||
- Constants are working for Widget- and style-properties
|
|
||||||
- Parameters can be defined, passed and used for Components
|
|
||||||
- Most of the built-in Widgets are supported, even the complex ones (``label``, ``slider``,
|
|
||||||
``bar``, ``button``, ``chart``, ``scale``, ``button matrix``, ``table``, etc.)
|
|
||||||
- Style sheets and local styles can be assigned to parts and states supporting
|
|
||||||
almost all style properties
|
|
||||||
|
|
||||||
Limitations:
|
|
||||||
|
|
||||||
- Screens are not supported yet (only Components)
|
|
||||||
- Events are not supported yet.
|
|
||||||
- Animations are not supported yet.
|
|
||||||
- Observer pattern Subjects are not supported yet.
|
|
||||||
- The documentation is not complete yet.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Concept
|
Concept
|
||||||
*******
|
*******
|
||||||
|
|
||||||
@@ -63,40 +36,37 @@ The XML files are Component-oriented. To be more specific, they are ``Component-
|
|||||||
That is, they are structured in a way to make it easy to create reusable Component Libraries.
|
That is, they are structured in a way to make it easy to create reusable Component Libraries.
|
||||||
|
|
||||||
For example, a company can have a Component Library for the basic Widgets for all its products
|
For example, a company can have a Component Library for the basic Widgets for all its products
|
||||||
(smart home, smart watch, smart oven, etc.), and create other industry-specific Libraries
|
(generic widgets for all smart devices), and create other industry-specific Libraries
|
||||||
(smart-home specific, smart-watch specific, etc.) containing only a few extra Widgets.
|
(smart-home specific, smart-watch specific, etc.) containing only a few extra Widgets and Components.
|
||||||
|
|
||||||
These Component Libraries are independent, can be reused across many products, and
|
These Component Libraries are independent, can be reused across many products, and
|
||||||
can be freely versioned and managed.
|
can be freely versioned and managed.
|
||||||
|
|
||||||
Imagine a Component Library as a collection of XML files, images, fonts, and other
|
Imagine a Component Library as a collection of XML files that describe Widgets, Components, Screens,
|
||||||
assets stored in a git repository, which can be a submodule in many projects.
|
images, fonts, and other assets stored in a git repository, which can be a submodule in many projects.
|
||||||
|
|
||||||
If someone finds a bug in the Component Library, they can just fix it in just one
|
If someone finds a bug in the Component Library, they can just fix it in one
|
||||||
place and push it back to the git repository so that other projects can be updated
|
place and push it back to the git repository so that other projects can be updated
|
||||||
from it.
|
from it.
|
||||||
|
|
||||||
The built-in Widgets of LVGL are also considered a ``Component Library`` which is
|
The built-in Widgets of LVGL are also considered a ``Component Library`` which is
|
||||||
always available.
|
always available.
|
||||||
|
|
||||||
A UI |nbsp| Editor project can have any number of Component Libraries and will always have
|
A UI |nbsp| Editor project can have any number of Component Libraries but will always have
|
||||||
at least 2:
|
at least 2:
|
||||||
|
|
||||||
- LVGL's built-in Widgets, and
|
- LVGL's built-in Widgets, and
|
||||||
- XML-based definitions of Screen contents, along with other project-specific Components.
|
- XML-based definitions of Screen contents, along with other project-specific Components.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Widgets, Components, and Screens
|
Widgets, Components, and Screens
|
||||||
********************************
|
********************************
|
||||||
|
|
||||||
It is important to distinguish between :dfn:`Widgets` and :dfn:`Components`.
|
It is important to distinguish between :dfn:`Widgets`, :dfn:`Components`, and :dfn:`Screens`.
|
||||||
|
|
||||||
|
|
||||||
Widgets
|
Widgets
|
||||||
-------
|
-------
|
||||||
|
|
||||||
:dfn:`Widgets` are the core building blocks of the UI and are not meant to be loaded at runtime
|
:dfn:`Widgets` are the core building blocks of the UI and are **not meant to be loaded at runtime**
|
||||||
but rather compiled into the application. The main characteristics of Widgets are:
|
but rather compiled into the application. The main characteristics of Widgets are:
|
||||||
|
|
||||||
- In XML, they start with a ``<widget>`` root element.
|
- In XML, they start with a ``<widget>`` root element.
|
||||||
@@ -104,7 +74,7 @@ but rather compiled into the application. The main characteristics of Widgets ar
|
|||||||
- They are built using ``lv_obj_class`` objects.
|
- They are built using ``lv_obj_class`` objects.
|
||||||
- They have custom and complex logic inside.
|
- They have custom and complex logic inside.
|
||||||
- They cannot be loaded from XML at runtime because the custom code cannot be loaded.
|
- They cannot be loaded from XML at runtime because the custom code cannot be loaded.
|
||||||
- They have a large API with ``set/get/add`` functions.
|
- 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).
|
- 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 handwritten Widget can be accessed from XML by:
|
||||||
@@ -113,26 +83,27 @@ Any handwritten Widget can be accessed from XML by:
|
|||||||
2. Writing and registering an XML parser for it.
|
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 some examples here. <https://github.com/lvgl/lvgl/tree/master/src/others/xml/parsers>`__
|
||||||
|
|
||||||
|
|
||||||
Components
|
Components
|
||||||
----------
|
----------
|
||||||
|
|
||||||
:dfn:`Components` are built from other Components and Widgets, and can be loaded at runtime.
|
:dfn:`Components` are built from other Components and Widgets, and **can be loaded at runtime**.
|
||||||
The main characteristics of Components are:
|
The main characteristics of Components are:
|
||||||
|
|
||||||
- In XML, they start with a ``<component>`` root element.
|
- In XML, they start with a ``<component>`` root element.
|
||||||
- They are built in XML only and cannot have custom C code.
|
- They are built in XML only and cannot have custom C code.
|
||||||
- They can be loaded from XML at runtime as they describe only visual aspects of the UI.
|
- They can be loaded from XML as they don't contain custom C code, only XML.
|
||||||
- They are built from Widgets or other Components.
|
- They are built from Widgets or other Components.
|
||||||
- They can be used for styling Widgets.
|
- They can be used for styling Widgets and other Components.
|
||||||
- They can contain (as children) Widgets or other Components.
|
- They can contain (as children) Widgets or other Components.
|
||||||
- They can have a simple API to pass properties to their children (e.g., ``btn_text`` to a Label's text).
|
- 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
|
Regardless of whether the XML was written manually or by the UI |nbsp| Editor, the XML files
|
||||||
of Components can be registered in LVGL, and after that, instances can be created.
|
of 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
|
In other words, LVGL can just read the XML files, "learn" the Components from them, and
|
||||||
thereafter create Components as part of a :ref:`Screen's <screens>` :ref:`Widget Tree
|
thereafter create children as part of Screens and other Components.
|
||||||
<basic_data_flow>` according to their structure.
|
|
||||||
|
Screens
|
||||||
|
-------
|
||||||
|
|
||||||
:dfn:`Screens` are similar to Components:
|
:dfn:`Screens` are similar to Components:
|
||||||
|
|
||||||
@@ -142,22 +113,20 @@ thereafter create Components as part of a :ref:`Screen's <screens>` :ref:`Widget
|
|||||||
- They do not have an API.
|
- They do not have an API.
|
||||||
- They can be referenced in Screen load events.
|
- They can be referenced in Screen load events.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Syntax Teaser
|
Syntax Teaser
|
||||||
*************
|
*************
|
||||||
|
|
||||||
Each Widget or Component XML file describes a single Widget or Component. The root
|
Each Widget, Component, or Screen XML file describes a single UI element. The root
|
||||||
element for Widgets, Components, and Screens are ``<widget>``, ``<component>`` and
|
element for Widgets, Components, and Screens is ``<widget>``, ``<component>``, and
|
||||||
``<screen>`` respectively. Other than that, the contained XML elements are almost
|
``<screen>``, respectively. Other than that, the contained XML elements are almost
|
||||||
identical. This is a high-level overview of the most important XML elements that
|
identical. This is a high-level overview of the most important XML elements that
|
||||||
will be children of these root elements:
|
will be children of these root elements:
|
||||||
|
|
||||||
:<api>: Describes the properties that can be ``set`` for a Widget or Component.
|
:<api>: Describes the properties that can be ``set`` for a Widget or Component.
|
||||||
Properties can be referenced ysubg ``$``. For Widgets, custom enums can
|
Properties can be referenced by ``$``. For Widgets, custom enums can
|
||||||
also be defined with the ``<enumdef>`` tag.
|
also be defined with the ``<enumdef>`` tag.
|
||||||
:<consts>: Specifies constants (local to the Widget or Component) for colors, sizes,
|
:<consts>: Specifies constants (local to the Widget or Component) for colors, sizes,
|
||||||
and other values. Constant values can be referenced using ``#``.
|
and other values. Constant values can be referenced using ``#``.
|
||||||
:<styles>: Describes style (``lv_style_t``) objects that can be referenced (and
|
:<styles>: Describes style (``lv_style_t``) objects that can be referenced (and
|
||||||
shared) by Widgets and Components later.
|
shared) by Widgets and Components later.
|
||||||
:<view>: Specifies the appearance of the Widget or Component by describing the
|
:<view>: Specifies the appearance of the Widget or Component by describing the
|
||||||
@@ -183,35 +152,48 @@ Note that only the basic features are shown here.
|
|||||||
<style name="red" bg_color="0xff0000"/>
|
<style name="red" bg_color="0xff0000"/>
|
||||||
</styles>
|
</styles>
|
||||||
|
|
||||||
<view extends="lv_button" width="#size" styles="blue red:pressed">
|
<view extends="lv_button" width="#size">
|
||||||
<my_h3 text="$btn_text" align="center" color="#orange" style_text_color:checked="0x00ff00"/>
|
<style name="blue"/>
|
||||||
|
<style name="red" selector="pressed"/>
|
||||||
|
<my_h3 text="$btn_text"
|
||||||
|
color="#orange"
|
||||||
|
align="center"/>
|
||||||
</view>
|
</view>
|
||||||
</component>
|
</component>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Usage Teaser
|
Usage Teaser
|
||||||
************
|
************
|
||||||
|
|
||||||
LVGL's UI |nbsp| Editor can be used in two different ways.
|
LVGL's UI |nbsp| Editor can be used in two different ways.
|
||||||
|
|
||||||
|
|
||||||
Export C and H Files
|
Export C and H Files
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
The Widgets, Components, images, fonts, etc., can be converted to .C/.H files with
|
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
|
plain LVGL code. The exported code works the same way as if it was written by the
|
||||||
user. In this case, the XML files are not required anymore unless modifications may
|
user.
|
||||||
be made later. 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.
|
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
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
|
Load the UI from XML
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
Although the Widgets' code always needs to be exported in C and compiled into the
|
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'
|
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. In the simplest case,
|
XML can be loaded and any number of instances can be created at runtime.
|
||||||
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)`.
|
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.
|
||||||
|
|
||||||
|
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).
|
||||||
+1
-2
@@ -20,6 +20,7 @@ content is specified:
|
|||||||
for each Screen according to the specified displays.
|
for each Screen according to the specified displays.
|
||||||
|
|
||||||
|
|
||||||
|
In LVGL's Editor the ``folders``, ``memory`` and `` <display color_format="..."/>`` are not supported yet.
|
||||||
|
|
||||||
Example
|
Example
|
||||||
*******
|
*******
|
||||||
@@ -34,8 +35,6 @@ Example
|
|||||||
</folders>
|
</folders>
|
||||||
|
|
||||||
<targets>
|
<targets>
|
||||||
<renesas-RA8D1-EK gpu="true"/>
|
|
||||||
|
|
||||||
<target name="small">
|
<target name="small">
|
||||||
<display width="320" height="240" color_format="RGB565"/>
|
<display width="320" height="240" color_format="RGB565"/>
|
||||||
<memory name="int_ram" size="128K"/>
|
<memory name="int_ram" size="128K"/>
|
||||||
+16
-14
@@ -90,18 +90,21 @@ to specify which variable a given name refers to.
|
|||||||
|
|
||||||
To create these connections, functions like
|
To create these connections, functions like
|
||||||
|
|
||||||
- ``lv_xml_register_image(&ctx, name, pointer)``
|
- ``lv_xml_register_image(scope, name, pointer)``
|
||||||
- ``lv_xml_register_font(&ctx, name, pointer)``
|
- ``lv_xml_register_font(scope, name, pointer)``
|
||||||
- ``lv_xml_register_event_cb(&ctx, name, callback)``
|
- ``lv_xml_register_event_cb(scope, name, callback)``
|
||||||
- etc.
|
- etc.
|
||||||
|
|
||||||
can be used. Later, a pointer to the object can be retrieved by
|
can be used. Later, a pointer to the object can be retrieved by
|
||||||
|
|
||||||
- ``lv_xml_get_image(&ctx, name)``
|
- ``lv_xml_get_image(scope, name)``
|
||||||
- ``lv_xml_get_font(&ctx, name)``
|
- ``lv_xml_get_font(scope, name)``
|
||||||
- ``lv_xml_get_event_cb(&ctx, name)``
|
- ``lv_xml_get_event_cb(scope, name)``
|
||||||
- etc.
|
- 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.
|
||||||
|
|
||||||
:style: Name of a style. :cpp:expr:`lv_xml_get_style_by_name(&ctx, name)` returns an :cpp:expr:`lv_style_t *`.
|
: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 *`.
|
: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 *`,
|
:image: Name of an image. :cpp:expr:`lv_xml_get_image(&ctx, name)` returns an :cpp:expr:`const void *`,
|
||||||
@@ -118,14 +121,15 @@ Arrays
|
|||||||
An array of any type can be defined in four ways:
|
An array of any type can be defined in four ways:
|
||||||
|
|
||||||
:int[N]: An integer array with ``N`` elements.
|
:int[N]: An integer array with ``N`` elements.
|
||||||
|
In the exported code ``N`` is passed a parameter after the array.
|
||||||
:string[...NULL]: An array terminated with a ``NULL`` element. ``NULL`` can be
|
:string[...NULL]: An array terminated with a ``NULL`` element. ``NULL`` can be
|
||||||
replaced by any value, e.g., ``grid_template_last``.
|
replaced by any value.
|
||||||
:string[5]: An array that must have exactly 5 elements.
|
:string[5]: An array that must have exactly 5 elements. In the exported code only the array will be passed
|
||||||
|
as the Widget assumes the given number of elements.
|
||||||
:string[]: No ``NULL`` termination and no count parameter, used when the
|
:string[]: No ``NULL`` termination and no count parameter, used when the
|
||||||
number of elements is not known or delivered via another
|
number of elements is not known or delivered via another
|
||||||
mechanism, such as via a function parameter.
|
mechanism, such as via a function parameter.
|
||||||
|
|
||||||
|
|
||||||
Enums
|
Enums
|
||||||
-----
|
-----
|
||||||
|
|
||||||
@@ -142,9 +146,7 @@ For example:
|
|||||||
<enum name="inverted" help="Inverted mode"/>
|
<enum name="inverted" help="Inverted mode"/>
|
||||||
</enumdef>
|
</enumdef>
|
||||||
|
|
||||||
<prop name="mode" help="help">
|
<prop name="mode" help="help"type="enum:my_widget_mode" help="help"/>
|
||||||
<param name="mode" type="enum:my_widget_mode" help="help"/>
|
|
||||||
</prop>
|
|
||||||
</api>
|
</api>
|
||||||
|
|
||||||
When used as a type, a ``+`` suffix means multiple values can be selected and ORed.
|
When used as a type, a ``+`` suffix means multiple values can be selected and ORed.
|
||||||
@@ -169,5 +171,5 @@ For example:
|
|||||||
- Colors: ``type="color(0xff0000 0x00ff00 0x0000ff)"``
|
- Colors: ``type="color(0xff0000 0x00ff00 0x0000ff)"``
|
||||||
- Strings: ``type="string('Ok' 'Cancel')``
|
- Strings: ``type="string('Ok' 'Cancel')``
|
||||||
|
|
||||||
These are checked in the UI |nbsp| Editor, and if an invalid option is selected, it
|
Limiting accepted values is not supported yet, however in the UI |nbsp| Editor if
|
||||||
will be highlighted as an error.
|
an invalid option is selected, it will be highlighted as an error.
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
.. _xml_test:
|
.. _xml_test:
|
||||||
|
|
||||||
====
|
==========
|
||||||
Test
|
UI Testing
|
||||||
====
|
==========
|
||||||
|
|
||||||
Overview
|
Overview
|
||||||
********
|
********
|
||||||
@@ -77,6 +77,7 @@ Details
|
|||||||
details/common-widget-features/index
|
details/common-widget-features/index
|
||||||
details/widgets/index
|
details/widgets/index
|
||||||
details/main-modules/index
|
details/main-modules/index
|
||||||
|
details/xml/index
|
||||||
details/auxiliary-modules/index
|
details/auxiliary-modules/index
|
||||||
details/libs/index
|
details/libs/index
|
||||||
details/debugging/index
|
details/debugging/index
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ lv_translation_tag_dsc_t * lv_translation_add_tag(lv_translation_pack_t * pack,
|
|||||||
{
|
{
|
||||||
if(pack->is_static) {
|
if(pack->is_static) {
|
||||||
LV_LOG_WARN("Can't add tag `%s` to static translation pack `%p`", tag_name, (void *)pack);
|
LV_LOG_WARN("Can't add tag `%s` to static translation pack `%p`", tag_name, (void *)pack);
|
||||||
return LV_RESULT_INVALID;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_translation_tag_dsc_t tag;
|
lv_translation_tag_dsc_t tag;
|
||||||
|
|||||||
+3
-3
@@ -22,14 +22,14 @@
|
|||||||
|
|
||||||
<element name="column" access="set">
|
<element name="column" access="set">
|
||||||
<arg name="column" type="int" help=""/>
|
<arg name="column" type="int" help=""/>
|
||||||
<arg name="width" type="px" help="width of the column"/>
|
<prop name="width" type="px" help="width of the column"/>
|
||||||
</element>
|
</element>
|
||||||
|
|
||||||
<element name="cell" access="set">
|
<element name="cell" access="set">
|
||||||
<arg name="row" type="int" help=""/>
|
<arg name="row" type="int" help=""/>
|
||||||
<arg name="column" type="int" help=""/>
|
<arg name="column" type="int" help=""/>
|
||||||
<arg name="value" type="string" help=""/>
|
<prop name="value" type="string" help=""/>
|
||||||
<arg name="ctrl" type="enum:lv_table_cell_ctrl+" help=""/>
|
<prop name="ctrl" type="enum:lv_table_cell_ctrl+" help=""/>
|
||||||
</element>
|
</element>
|
||||||
</api>
|
</api>
|
||||||
</widget>
|
</widget>
|
||||||
|
|||||||
Reference in New Issue
Block a user