fix(docs): fix most sphinx warnings (#6916)
Co-authored-by: Kevin Schlosser <kdschlosser@users.noreply.github.com> Co-authored-by: Liam <30486941+liamHowatt@users.noreply.github.com>
This commit is contained in:
@@ -285,7 +285,7 @@ Fixes
|
|||||||
- **fix(sdl): handle if the window_id is not set correctly in SDL** `6194 <https://github.com/lvgl/lvgl/pull/6194>`__
|
- **fix(sdl): handle if the window_id is not set correctly in SDL** `6194 <https://github.com/lvgl/lvgl/pull/6194>`__
|
||||||
- **fix(drivers): drm driver not initialising with small screens** `6244 <https://github.com/lvgl/lvgl/pull/6244>`__
|
- **fix(drivers): drm driver not initialising with small screens** `6244 <https://github.com/lvgl/lvgl/pull/6244>`__
|
||||||
- **fix(freetype): fix potential multi-threaded data conflicts** `6252 <https://github.com/lvgl/lvgl/pull/6252>`__
|
- **fix(freetype): fix potential multi-threaded data conflicts** `6252 <https://github.com/lvgl/lvgl/pull/6252>`__
|
||||||
- **fix(vglite): build issues ** `6245 <https://github.com/lvgl/lvgl/pull/6245>`__
|
- **fix(vglite): build issues** `6245 <https://github.com/lvgl/lvgl/pull/6245>`__
|
||||||
- **fix(canvas): lv_canvas_set_px for indexed images** `6226 <https://github.com/lvgl/lvgl/pull/6226>`__
|
- **fix(canvas): lv_canvas_set_px for indexed images** `6226 <https://github.com/lvgl/lvgl/pull/6226>`__
|
||||||
- **fix(snapshot): fix memleak in lv_snapshot** `6147 <https://github.com/lvgl/lvgl/pull/6147>`__
|
- **fix(snapshot): fix memleak in lv_snapshot** `6147 <https://github.com/lvgl/lvgl/pull/6147>`__
|
||||||
- **fix(span): fix span incorrect max height calculation** `6243 <https://github.com/lvgl/lvgl/pull/6243>`__
|
- **fix(span): fix span incorrect max height calculation** `6243 <https://github.com/lvgl/lvgl/pull/6243>`__
|
||||||
|
|||||||
245
docs/README.md
Normal file
245
docs/README.md
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
# Documentation
|
||||||
|
|
||||||
|
----------------------------------------------
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
Building the documentation is pretty easy to do but it does have some requirements
|
||||||
|
that have to be filled prior to building them.
|
||||||
|
|
||||||
|
Here are the requirements:
|
||||||
|
|
||||||
|
* Doxygen
|
||||||
|
* Python >= 3.10
|
||||||
|
* C compiler (gcc, msvc, clang, etc...)
|
||||||
|
|
||||||
|
|
||||||
|
There are also some Python specific libraries that need to be installed.
|
||||||
|
You can either install these individually or you can use pip to read the requirements
|
||||||
|
file to install everything that is needed for Python.
|
||||||
|
|
||||||
|
* Sphinx
|
||||||
|
* breathe
|
||||||
|
* imagesize
|
||||||
|
* importlib-metadata
|
||||||
|
* sphinx-rtd-theme
|
||||||
|
* sphinx-sitemap
|
||||||
|
* sphinxcontrib-applehelp
|
||||||
|
* sphinxcontrib-devhelp
|
||||||
|
* sphinxcontrib-htmlhelp
|
||||||
|
* sphinxcontrib-jsmath
|
||||||
|
* sphinxcontrib-qthelp
|
||||||
|
* sphinxcontrib-serializinghtml
|
||||||
|
* sphinxcontrib-mermaid
|
||||||
|
* sphinx-design
|
||||||
|
* sphinx-rtd-dark-mode
|
||||||
|
* typing-extensions
|
||||||
|
|
||||||
|
To install using the `requirements.txt` file use the following command.
|
||||||
|
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
|
||||||
|
Once you have all of the requirements installed you are ready to build them.
|
||||||
|
To build the documentation use the following command.
|
||||||
|
|
||||||
|
python build.py skip_latex clean
|
||||||
|
|
||||||
|
You may have to use the following command if you are on a Unix like OS
|
||||||
|
|
||||||
|
python3 build.py skip_latex clean
|
||||||
|
|
||||||
|
The documentation will be output into the folder `out_html` in the root directory
|
||||||
|
for LVGL.
|
||||||
|
|
||||||
|
## For Developers
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
The most important thing that has to be done when contributing to LVGL is
|
||||||
|
|
||||||
|
|
||||||
|
***EVERYTHING MUST BE DOCUMENTED***
|
||||||
|
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
Some rules to follow when updating any of the `.rst` files located in the docs
|
||||||
|
folder and any of it's subfolders.
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
### index.rst files
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
If you create a new directory you MUST have an `index.rst` file in that directory
|
||||||
|
and that index file needs to be pointed to in the `index.rst` file that is located
|
||||||
|
in the parent directory.
|
||||||
|
|
||||||
|
Let's take a look at the `index.rst` file that is located in the `docs/layouts` directory.
|
||||||
|
|
||||||
|
```
|
||||||
|
.. _layouts:
|
||||||
|
|
||||||
|
=======
|
||||||
|
Layouts
|
||||||
|
=======
|
||||||
|
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
flex
|
||||||
|
grid
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
That is what you see... Below is what the various parts of the file are.
|
||||||
|
|
||||||
|
```
|
||||||
|
.. _layouts: <=== Creates a reference that is linkable
|
||||||
|
|
||||||
|
=======
|
||||||
|
Layouts <=== Heading seen in documentation
|
||||||
|
=======
|
||||||
|
|
||||||
|
|
||||||
|
.. toctree:: <=== Table of contents
|
||||||
|
:maxdepth: 2 <=== Internal use and need to always be set this way
|
||||||
|
|
||||||
|
flex <=== .rst files located in directory with index.rst
|
||||||
|
grid
|
||||||
|
```
|
||||||
|
|
||||||
|
The first line is for the purposes of not having to statically link to other locations
|
||||||
|
in the documentation. It makes it easier when things get moved around as the link will
|
||||||
|
change dynamically if that should occur. In order to create the link it must be formatted
|
||||||
|
in this manner.
|
||||||
|
|
||||||
|
.. _{LINK NAME}:
|
||||||
|
|
||||||
|
where you would replace `{LINK NAME}` with whatever name you wanted to provide.
|
||||||
|
That name is what is going to be used to reference the link. This is done by using
|
||||||
|
|
||||||
|
:ref:`{LINK NAME}`
|
||||||
|
|
||||||
|
The `.. _{LINK NAME}:` line MUST be above a heading and there MUST be a single empty line
|
||||||
|
after it. This is MANDATORY.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Section Headings
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
[Section headers](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#sections)
|
||||||
|
are created by underlining (and optionally overlining) the section title with
|
||||||
|
a punctuation character, at least as long as the text. Example
|
||||||
|
|
||||||
|
=================
|
||||||
|
This Is a Heading
|
||||||
|
=================
|
||||||
|
|
||||||
|
reStructuredText does not impose any particular heading levels assigned to certain characters since the structure is determined from the succession of headings. So if you are modifying an existing .RST file, please follow the pattern it is already using.
|
||||||
|
|
||||||
|
If you are creating a new .RST file, this convention is used:
|
||||||
|
|
||||||
|
=====
|
||||||
|
Title
|
||||||
|
=====
|
||||||
|
|
||||||
|
Chapter
|
||||||
|
*******
|
||||||
|
|
||||||
|
Section
|
||||||
|
-------
|
||||||
|
|
||||||
|
Sub Section
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
Sub Sub Section
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Paragraph
|
||||||
|
'''''''''
|
||||||
|
|
||||||
|
For improved readability in the .RST file, place at least 2 blank lines above headings.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Code Blocks
|
||||||
|
|
||||||
|
--------------------------------------------------------------
|
||||||
|
|
||||||
|
* No tab characters are to be used in a code block.
|
||||||
|
* Indents are done using 4 spaces and only 4 spaces.
|
||||||
|
* Include 2 empty lines at the end of a code block.
|
||||||
|
* One empty line between the code block directive and the code.
|
||||||
|
* `.. code-block:` is the only directive that should be used. `::`, `:code:` or `.. code:` should not be used.
|
||||||
|
* Specify the language after the directive. Some examples are:
|
||||||
|
- `.. code-block: python`,
|
||||||
|
- `.. code-block: c`,
|
||||||
|
- `.. code-block: shell`,
|
||||||
|
- `.. code-block: make`.
|
||||||
|
* If you want to separate code into easier to understand sections you can do so with a single empty line. No more than ONE line.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Bulleted Lists
|
||||||
|
|
||||||
|
-------------------------------------------------------------
|
||||||
|
|
||||||
|
To create a bulleted list, do the following:
|
||||||
|
|
||||||
|
|
||||||
|
- item1: description
|
||||||
|
- item2: If you want to span multiple
|
||||||
|
lines it must be done like this
|
||||||
|
- item3: If you want to use a code block it must be done like this
|
||||||
|
|
||||||
|
.. code-block: python
|
||||||
|
|
||||||
|
# this is some code
|
||||||
|
|
||||||
|
- item3: If you want to have several layers of bullets it needs to be done like this
|
||||||
|
|
||||||
|
- level 2 item 1: text
|
||||||
|
- level 2 item 2: text
|
||||||
|
|
||||||
|
End all lists with 2 empty lines except when it is a nested list. Then you use a single empty line. The same thing holds true for code blocks as well. If it is nested into a list then a single empty line after. If the nested list or code block is at the end of the first level then you need to use 2 empty lines.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Referencing Portions of the API
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
If you want to reference portions of the LVGL code from the documentation (in .RST files) there are special directives to do this:
|
||||||
|
|
||||||
|
:cpp:func:`lv_init`
|
||||||
|
:c:macro:`LV_USE_FLEX`
|
||||||
|
:cpp:type:`lv_event_t`
|
||||||
|
:cpp:enum:`_lv_event_t`
|
||||||
|
:cpp:enumerator:`LV_EVENT_ALL`
|
||||||
|
:cpp:struct:`lv_image_dsc_t`
|
||||||
|
:cpp:union:`lv_style_value_t`
|
||||||
|
|
||||||
|
There is a special directive when wanting to use a more complex expression.
|
||||||
|
For example when showing the arguments passed to a function
|
||||||
|
|
||||||
|
:cpp:expr:`lv_obj_set_layout(obj, LV_LAYOUT_FLEX)`
|
||||||
|
|
||||||
|
you CANNOT have expressions that are like this...
|
||||||
|
|
||||||
|
:cpp:expr:`lv_obj_set_layout(obj, LV_LAYOUT_FLEX/GRID)` <== arg with more than one word
|
||||||
|
:cpp:expr:`lv_obj_set_layout(obj, LV_LAYOUT_*)` <== asterisk
|
||||||
|
:cpp:expr:`lv_obj_set_layout(*obj, LV_LAYOUT_FLEX)` <== asterisk
|
||||||
|
:cpp:expr:`lv_obj_set_layout((lv_obj_t *)obj, LV_LAYOUT_FLEX)` <== cast/asterisk
|
||||||
|
:cpp:expr:`lv_obj_set_layout(&obj, LV_LAYOUT_FLEX);` <== ampersand
|
||||||
|
:cpp:expr:`lv_obj_set_layout(obj, ...)` <== elipsis
|
||||||
|
|
||||||
|
Those are all invalid.
|
||||||
|
|
||||||
@@ -177,7 +177,7 @@ C code
|
|||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * btn = lv_button_create(lv_screen_active()); /*Add a button to the current screen*/
|
lv_obj_t * btn = lv_button_create(lv_screen_active()); /*Add a button to the current screen*/
|
||||||
lv_obj_center(btn); /*Set its position*/
|
lv_obj_center(btn); /*Set its position*/
|
||||||
@@ -212,7 +212,7 @@ MicroPython code \| Online Simulator :gb:
|
|||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def btn_event_cb(e):
|
def btn_event_cb(e):
|
||||||
print("Clicked")
|
print("Clicked")
|
||||||
@@ -253,7 +253,7 @@ C code
|
|||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
|
|
||||||
lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN);
|
lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN);
|
||||||
@@ -297,7 +297,7 @@ MicroPython code \| Online Simulator :gb:
|
|||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def event_handler(e):
|
def event_handler(e):
|
||||||
code = e.get_code()
|
code = e.get_code()
|
||||||
@@ -359,7 +359,7 @@ C code
|
|||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * slider = lv_slider_create(lv_screen_active());
|
lv_obj_t * slider = lv_slider_create(lv_screen_active());
|
||||||
lv_slider_set_value(slider, 70, LV_ANIM_OFF);
|
lv_slider_set_value(slider, 70, LV_ANIM_OFF);
|
||||||
@@ -412,7 +412,7 @@ MicroPython code \| Online Simulator :gb:
|
|||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# Create a slider and add the style
|
# Create a slider and add the style
|
||||||
slider = lv.slider(lv.scr_act())
|
slider = lv.slider(lv.scr_act())
|
||||||
@@ -473,7 +473,7 @@ C code
|
|||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * ltr_label = lv_label_create(lv_screen_active());
|
lv_obj_t * ltr_label = lv_label_create(lv_screen_active());
|
||||||
lv_label_set_text(ltr_label, "In modern terminology, a microcontroller is similar to a system on a chip (SoC).");
|
lv_label_set_text(ltr_label, "In modern terminology, a microcontroller is similar to a system on a chip (SoC).");
|
||||||
@@ -513,7 +513,7 @@ MicroPython code \| Online Simulator :gb:
|
|||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
ltr_label = lv.label(lv.scr_act())
|
ltr_label = lv.label(lv.scr_act())
|
||||||
ltr_label.set_text("In modern terminology, a microcontroller is similar to a system on a chip (SoC).")
|
ltr_label.set_text("In modern terminology, a microcontroller is similar to a system on a chip (SoC).")
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ Código C
|
|||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * btn = lv_button_create(lv_screen_active()); /* Adiciona o botão a tela atual */
|
lv_obj_t * btn = lv_button_create(lv_screen_active()); /* Adiciona o botão a tela atual */
|
||||||
lv_obj_center(btn); /* Define a posição do botão */
|
lv_obj_center(btn); /* Define a posição do botão */
|
||||||
@@ -272,7 +272,7 @@ Código MicroPython \| Simulador online
|
|||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def btn_event_cb(e):
|
def btn_event_cb(e):
|
||||||
print("Clicado")
|
print("Clicado")
|
||||||
@@ -313,7 +313,7 @@ Código em C
|
|||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
|
|
||||||
lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN);
|
lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN);
|
||||||
@@ -357,7 +357,7 @@ Código MicroPython \| Online Simulator
|
|||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def event_handler(e):
|
def event_handler(e):
|
||||||
code = e.get_code()
|
code = e.get_code()
|
||||||
@@ -419,7 +419,7 @@ Código C
|
|||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * slider = lv_slider_create(lv_screen_active());
|
lv_obj_t * slider = lv_slider_create(lv_screen_active());
|
||||||
lv_slider_set_value(slider, 70, LV_ANIM_OFF);
|
lv_slider_set_value(slider, 70, LV_ANIM_OFF);
|
||||||
@@ -472,7 +472,7 @@ Código MicroPython \| Simulador online
|
|||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# Crie um controle deslizante (slider) e adicione o estilo
|
# Crie um controle deslizante (slider) e adicione o estilo
|
||||||
slider = lv.slider(lv.scr_act())
|
slider = lv.slider(lv.scr_act())
|
||||||
@@ -533,7 +533,7 @@ Código C
|
|||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * ltr_label = lv_label_create(lv_screen_active());
|
lv_obj_t * ltr_label = lv_label_create(lv_screen_active());
|
||||||
lv_label_set_text(ltr_label, "In modern terminology, a microcontroller is similar to a system on a chip (SoC).");
|
lv_label_set_text(ltr_label, "In modern terminology, a microcontroller is similar to a system on a chip (SoC).");
|
||||||
@@ -573,7 +573,7 @@ Código MicroPython \| Simulador online
|
|||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
ltr_label = lv.label(lv.scr_act())
|
ltr_label = lv.label(lv.scr_act())
|
||||||
ltr_label.set_text("In modern terminology, a microcontroller is similar to a system on a chip (SoC).")
|
ltr_label.set_text("In modern terminology, a microcontroller is similar to a system on a chip (SoC).")
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ Hello world 标签
|
|||||||
<details>
|
<details>
|
||||||
<summary>C code</summary>
|
<summary>C code</summary>
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/*Change the active screen's background color*/
|
/*Change the active screen's background color*/
|
||||||
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x003a57), LV_PART_MAIN);
|
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x003a57), LV_PART_MAIN);
|
||||||
@@ -201,7 +201,7 @@ Hello world 标签
|
|||||||
<details>
|
<details>
|
||||||
<summary>MicroPython code | <a href="https://sim.lvgl.io/v8.3/micropython/ports/javascript/index.html?script_direct=4ab7c40c35b0dc349aa2f0c3b00938d7d8e8ac9f" target="_blank">在线模拟器</a></summary>
|
<summary>MicroPython code | <a href="https://sim.lvgl.io/v8.3/micropython/ports/javascript/index.html?script_direct=4ab7c40c35b0dc349aa2f0c3b00938d7d8e8ac9f" target="_blank">在线模拟器</a></summary>
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# Change the active screen's background color
|
# Change the active screen's background color
|
||||||
scr = lv.screen_active()
|
scr = lv.screen_active()
|
||||||
@@ -229,7 +229,7 @@ Hello world 标签
|
|||||||
<details>
|
<details>
|
||||||
<summary>C code</summary>
|
<summary>C code</summary>
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * button = lv_button_create(lv_screen_active()); /*Add a button to the current screen*/
|
lv_obj_t * button = lv_button_create(lv_screen_active()); /*Add a button to the current screen*/
|
||||||
lv_obj_center(button); /*Set its position*/
|
lv_obj_center(button); /*Set its position*/
|
||||||
@@ -255,7 +255,7 @@ Hello world 标签
|
|||||||
<details>
|
<details>
|
||||||
<summary>MicroPython code | <a href="https://sim.lvgl.io/v8.3/micropython/ports/javascript/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/header.py&script=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/widgets/slider/lv_example_slider_2.py&script_direct=926bde43ec7af0146c486de470c53f11f167491e" target="_blank">在线模拟器</a></summary>
|
<summary>MicroPython code | <a href="https://sim.lvgl.io/v8.3/micropython/ports/javascript/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/header.py&script=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/widgets/slider/lv_example_slider_2.py&script_direct=926bde43ec7af0146c486de470c53f11f167491e" target="_blank">在线模拟器</a></summary>
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def button_event_cb(e):
|
def button_event_cb(e):
|
||||||
print("Clicked")
|
print("Clicked")
|
||||||
@@ -286,7 +286,7 @@ Hello world 标签
|
|||||||
<details>
|
<details>
|
||||||
<summary>C code</summary>
|
<summary>C code</summary>
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
|
|
||||||
lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN);
|
lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN);
|
||||||
@@ -321,7 +321,7 @@ Hello world 标签
|
|||||||
<details>
|
<details>
|
||||||
<summary>MicroPython code | <a href="https://sim.lvgl.io/v8.3/micropython/ports/javascript/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/header.py&script=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/widgets/slider/lv_example_slider_2.py&script_direct=311d37e5f70daf1cb0d2cad24c7f72751b5f1792" target="_blank">在线模拟器</a></summary>
|
<summary>MicroPython code | <a href="https://sim.lvgl.io/v8.3/micropython/ports/javascript/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/header.py&script=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/widgets/slider/lv_example_slider_2.py&script_direct=311d37e5f70daf1cb0d2cad24c7f72751b5f1792" target="_blank">在线模拟器</a></summary>
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def event_handler(e):
|
def event_handler(e):
|
||||||
code = e.get_code()
|
code = e.get_code()
|
||||||
@@ -373,7 +373,7 @@ Hello world 标签
|
|||||||
<details>
|
<details>
|
||||||
<summary>C code</summary>
|
<summary>C code</summary>
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * slider = lv_slider_create(lv_screen_active());
|
lv_obj_t * slider = lv_slider_create(lv_screen_active());
|
||||||
lv_slider_set_value(slider, 70, LV_ANIM_OFF);
|
lv_slider_set_value(slider, 70, LV_ANIM_OFF);
|
||||||
@@ -419,7 +419,7 @@ Hello world 标签
|
|||||||
<a href="https://sim.lvgl.io/v8.3/micropython/ports/javascript/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/header.py&script=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/widgets/slider/lv_example_slider_2.py&script_direct=c431c7b4dfd2cc0dd9c392b74365d5af6ea986f0" target="_blank">在线模拟器</a>
|
<a href="https://sim.lvgl.io/v8.3/micropython/ports/javascript/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/header.py&script=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/widgets/slider/lv_example_slider_2.py&script_direct=c431c7b4dfd2cc0dd9c392b74365d5af6ea986f0" target="_blank">在线模拟器</a>
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# Create a slider and add the style
|
# Create a slider and add the style
|
||||||
slider = lv.slider(lv.screen_active())
|
slider = lv.slider(lv.screen_active())
|
||||||
@@ -470,7 +470,7 @@ Hello world 标签
|
|||||||
<details>
|
<details>
|
||||||
<summary>C code</summary>
|
<summary>C code</summary>
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * ltr_label = lv_label_create(lv_screen_active());
|
lv_obj_t * ltr_label = lv_label_create(lv_screen_active());
|
||||||
lv_label_set_text(ltr_label, "In modern terminology, a microcontroller is similar to a system on a chip (SoC).");
|
lv_label_set_text(ltr_label, "In modern terminology, a microcontroller is similar to a system on a chip (SoC).");
|
||||||
@@ -501,7 +501,7 @@ Hello world 标签
|
|||||||
<details>
|
<details>
|
||||||
<summary>MicroPython code | <a href="https://sim.lvgl.io/v8.3/micropython/ports/javascript/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/header.py&script=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/widgets/slider/lv_example_slider_2.py&script_direct=18bb38200a64e10ead1aa17a65c977fc18131842" target="_blank">在线模拟器</a></summary>
|
<summary>MicroPython code | <a href="https://sim.lvgl.io/v8.3/micropython/ports/javascript/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/header.py&script=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/widgets/slider/lv_example_slider_2.py&script_direct=18bb38200a64e10ead1aa17a65c977fc18131842" target="_blank">在线模拟器</a></summary>
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
ltr_label = lv.label(lv.screen_active())
|
ltr_label = lv.label(lv.screen_active())
|
||||||
ltr_label.set_text("In modern terminology, a microcontroller is similar to a system on a chip (SoC).")
|
ltr_label.set_text("In modern terminology, a microcontroller is similar to a system on a chip (SoC).")
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
.. _quick-overview:
|
.. _quick-overview:
|
||||||
|
|
||||||
==============
|
==============
|
||||||
Quick Overview
|
Quick overview
|
||||||
==============
|
==============
|
||||||
|
|
||||||
Here you can learn the most important things about LVGL. You should read
|
Here you can learn the most important things about LVGL. You should read
|
||||||
@@ -21,8 +21,9 @@ Go to the :ref:`simulator` section to get ready-to-use projects that can be run
|
|||||||
on your PC. This way you can save the time of porting for now and get some
|
on your PC. This way you can save the time of porting for now and get some
|
||||||
experience with LVGL immediately.
|
experience with LVGL immediately.
|
||||||
|
|
||||||
Add LVGL to Your Project
|
|
||||||
------------------------
|
Add LVGL into your project
|
||||||
|
--------------------------
|
||||||
|
|
||||||
If you would rather try LVGL on your own project follow these steps:
|
If you would rather try LVGL on your own project follow these steps:
|
||||||
|
|
||||||
@@ -30,15 +31,13 @@ If you would rather try LVGL on your own project follow these steps:
|
|||||||
clone the library from GitHub with ``git clone https://github.com/lvgl/lvgl.git``.
|
clone the library from GitHub with ``git clone https://github.com/lvgl/lvgl.git``.
|
||||||
- Copy the ``lvgl`` folder into your project. If you wish you can add only ``lvgl/lvgl.h``, ``lvgl/lv_version.h``, and ``lvgl/src``
|
- Copy the ``lvgl`` folder into your project. If you wish you can add only ``lvgl/lvgl.h``, ``lvgl/lv_version.h``, and ``lvgl/src``
|
||||||
for LVGL itself, and ``lvgl/examples`` and ``lvgl/demos`` for the examples and demos respectively.
|
for LVGL itself, and ``lvgl/examples`` and ``lvgl/demos`` for the examples and demos respectively.
|
||||||
- Copy ``lvgl/lv_conf_template.h`` as ``lv_conf.h`` next to the
|
- Copy ``lvgl/lv_conf_template.h`` as ``lv_conf.h`` next to the ``lvgl`` folder, change the first ``#if 0`` to ``1`` to
|
||||||
``lvgl`` folder, change the first ``#if 0`` to ``1`` to enable the
|
enable the file's content and set the :c:macro:`LV_COLOR_DEPTH` defines.
|
||||||
file's content and set the :c:macro:`LV_COLOR_DEPTH` defines.
|
|
||||||
- Include ``lvgl/lvgl.h`` in files where you need to use LVGL related functions.
|
- Include ``lvgl/lvgl.h`` in files where you need to use LVGL related functions.
|
||||||
- Call :cpp:func:`lv_init`
|
- Call :cpp:expr:`lv_tick_inc(x)` every ``x`` milliseconds in a Timer or Task (``x`` should be between 1 and 10). It is required for
|
||||||
- Call :cpp:expr:`lv_tick_inc(x)` every ``x`` milliseconds in a Timer or Task
|
the internal timing of LVGL. Alternatively, register a ``tick_get_cb`` with :cpp:func:`lv_tick_set_cb` so that LVGL
|
||||||
(``x`` should be between 1 and 10). It is required for the internal
|
can retrieve the current time directly.
|
||||||
timing of LVGL. Alternatively, register a ``tick_get_cb`` with
|
- Call :cpp:func:`lv_init`
|
||||||
:cpp:func:`lv_tick_set_cb` so that LVGL can retrieve the current time directly.
|
|
||||||
- Create a display.
|
- Create a display.
|
||||||
|
|
||||||
|
|
||||||
@@ -107,39 +106,36 @@ If you would rather try LVGL on your own project follow these steps:
|
|||||||
redraw the screen if required, handle input devices, animation etc.
|
redraw the screen if required, handle input devices, animation etc.
|
||||||
|
|
||||||
|
|
||||||
For a more detailed guide go to the :ref:`porting`
|
For a more detailed guide go to the :ref:`porting` section.
|
||||||
section.
|
|
||||||
|
|
||||||
|
|
||||||
Learn the Basics
|
Learn the basics
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
|
||||||
.. _quick-overview_widgets:
|
.. _quick-overview_widgets:
|
||||||
|
|
||||||
Widgets
|
Widgets
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
||||||
The graphical elements like Buttons, Labels, Sliders, Charts etc. are
|
The graphical elements like Buttons, Labels, Sliders, Charts etc. are called objects or widgets.
|
||||||
called objects or widgets. Go to :ref:`widgets` to see the
|
Go to :ref:`widgets` to see the full list of available widgets.
|
||||||
full list of available widgets.
|
|
||||||
|
|
||||||
Every object has a parent object where it is created. For example, if a
|
Every object has a parent object where it is created. For example, if a label is created on a button,
|
||||||
label is created on a button, the button is the parent of label.
|
the button is the parent of label.
|
||||||
|
|
||||||
The child object moves with the parent and if the parent is deleted the
|
The child object moves with the parent and if the parent is deleted the children will be deleted too.
|
||||||
children will be deleted too.
|
|
||||||
|
|
||||||
Children can be visible only within their parent's bounding area. In
|
Children can be visible only within their parent's bounding area. In other words, the parts of the
|
||||||
other words, the parts of the children outside the parent are clipped.
|
children outside the parent are clipped.
|
||||||
|
|
||||||
A Screen is the "root" parent. You can have any number of screens.
|
A Screen is the "root" parent. You can have any number of screens.
|
||||||
|
|
||||||
To get the current screen call :cpp:func:`lv_screen_active`, and to load a screen
|
To get the current screen call :cpp:func:`lv_screen_active`, and to load a screen use :cpp:expr:`lv_screen_load(scr1)`.
|
||||||
use :cpp:expr:`lv_screen_load(scr1)`.
|
|
||||||
|
You can create a new object with ``lv_<type>_create(parent)``. It will return an :cpp:type:`lv_obj_t` ``*`` variable
|
||||||
|
that can be used as a reference to the object to set its parameters.
|
||||||
|
|
||||||
You can create a new object with ``lv_<type>_create(parent)``. It will
|
|
||||||
return an :cpp:type:`lv_obj_t` ``*`` variable that can be used as a reference to the
|
|
||||||
object to set its parameters.
|
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
@@ -147,8 +143,8 @@ For example:
|
|||||||
|
|
||||||
lv_obj_t * slider1 = lv_slider_create(lv_screen_active());
|
lv_obj_t * slider1 = lv_slider_create(lv_screen_active());
|
||||||
|
|
||||||
To set some basic attributes ``lv_obj_set_<parameter_name>(obj, <value>)`` functions can be used. For
|
|
||||||
example:
|
To set some basic attributes ``lv_obj_set_<parameter_name>(obj, <value>)`` functions can be used. For example:
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
@@ -156,26 +152,27 @@ example:
|
|||||||
lv_obj_set_y(btn1, 10);
|
lv_obj_set_y(btn1, 10);
|
||||||
lv_obj_set_size(btn1, 200, 50);
|
lv_obj_set_size(btn1, 200, 50);
|
||||||
|
|
||||||
Along with the basic attributes, widgets can have type specific
|
|
||||||
parameters which are set by ``lv_<widget_type>_set_<parameter_name>(obj, <value>)`` functions. For
|
Along with the basic attributes, widgets can have type specific parameters which are set by
|
||||||
example:
|
``lv_<widget_type>_set_<parameter_name>(obj, <value>)`` functions. For example:
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_slider_set_value(slider1, 70, LV_ANIM_ON);
|
lv_slider_set_value(slider1, 70, LV_ANIM_ON);
|
||||||
|
|
||||||
To see the full API visit the documentation of the widgets or the
|
|
||||||
related header file
|
To see the full API visit the documentation of the widgets or the related header file
|
||||||
(e.g. `lvgl/src/widgets/slider/lv_slider.h <https://github.com/lvgl/lvgl/blob/master/src/widgets/slider/lv_slider.h>`__).
|
(e.g. `lvgl/src/widgets/slider/lv_slider.h <https://github.com/lvgl/lvgl/blob/master/src/widgets/slider/lv_slider.h>`__).
|
||||||
|
|
||||||
|
|
||||||
.. _quick-overview_events:
|
.. _quick-overview_events:
|
||||||
|
|
||||||
Events
|
Events
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
Events are used to inform the user that something has happened with an
|
Events are used to inform the user that something has happened with an object. You can assign one or more
|
||||||
object. You can assign one or more callbacks to an object which will be
|
callbacks to an object which will be called if the object is clicked, released, dragged, being deleted, etc.
|
||||||
called if the object is clicked, released, dragged, being deleted, etc.
|
|
||||||
|
|
||||||
A callback is assigned like this:
|
A callback is assigned like this:
|
||||||
|
|
||||||
@@ -190,8 +187,8 @@ A callback is assigned like this:
|
|||||||
printf("Clicked\n");
|
printf("Clicked\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
:cpp:enumerator:`LV_EVENT_ALL` can be used instead of :cpp:enumerator:`LV_EVENT_CLICKED` to invoke
|
|
||||||
the callback for any event.
|
:cpp:enumerator:`LV_EVENT_ALL` can be used instead of :cpp:enumerator:`LV_EVENT_CLICKED` to invoke the callback for any event.
|
||||||
|
|
||||||
From :cpp:expr:`lv_event_t * e` the current event code can be retrieved with:
|
From :cpp:expr:`lv_event_t * e` the current event code can be retrieved with:
|
||||||
|
|
||||||
@@ -199,14 +196,17 @@ From :cpp:expr:`lv_event_t * e` the current event code can be retrieved with:
|
|||||||
|
|
||||||
lv_event_code_t code = lv_event_get_code(e);
|
lv_event_code_t code = lv_event_get_code(e);
|
||||||
|
|
||||||
|
|
||||||
The object that triggered the event can be retrieved with:
|
The object that triggered the event can be retrieved with:
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * obj = lv_event_get_target(e);
|
lv_obj_t * obj = lv_event_get_target(e);
|
||||||
|
|
||||||
|
|
||||||
To learn all features of the events go to the :ref:`events` section.
|
To learn all features of the events go to the :ref:`events` section.
|
||||||
|
|
||||||
|
|
||||||
.. _quick-overview_parts:
|
.. _quick-overview_parts:
|
||||||
|
|
||||||
Parts
|
Parts
|
||||||
@@ -256,20 +256,18 @@ To manually add or remove states use:
|
|||||||
lv_obj_add_state(obj, LV_STATE_...);
|
lv_obj_add_state(obj, LV_STATE_...);
|
||||||
lv_obj_remove_state(obj, LV_STATE_...);
|
lv_obj_remove_state(obj, LV_STATE_...);
|
||||||
|
|
||||||
.. _quick-overview_styles:
|
|
||||||
|
|
||||||
|
.. _quick-overview_styles:
|
||||||
|
|
||||||
Styles
|
Styles
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
A style instance contains properties such as background color, border
|
A style instance contains properties such as background color, border width, font, etc. that describe the
|
||||||
width, font, etc. that describe the appearance of objects.
|
appearance of objects.
|
||||||
|
|
||||||
Styles are represented with :cpp:struct:`lv_style_t` variables. Only their pointer
|
Styles are represented with :cpp:struct:`lv_style_t` variables. Only their pointer is saved in the objects so
|
||||||
is saved in the objects so they need to be defined as static or global.
|
they need to be defined as static or global. Before using a style it needs to be initialized with
|
||||||
Before using a style it needs to be initialized with
|
:cpp:expr:`lv_style_init(&style1)`. After that, properties can be added to configure the style. For example:
|
||||||
:cpp:expr:`lv_style_init(&style1)`. After that, properties can be added to
|
|
||||||
configure the style. For example:
|
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
@@ -278,73 +276,76 @@ configure the style. For example:
|
|||||||
lv_style_set_bg_color(&style1, lv_color_hex(0xa03080))
|
lv_style_set_bg_color(&style1, lv_color_hex(0xa03080))
|
||||||
lv_style_set_border_width(&style1, 2))
|
lv_style_set_border_width(&style1, 2))
|
||||||
|
|
||||||
|
|
||||||
See the full list of properties here :ref:`styles_properties`.
|
See the full list of properties here :ref:`styles_properties`.
|
||||||
|
|
||||||
Styles are assigned using the ORed combination of an object's part and
|
Styles are assigned using the ORed combination of an object's part and state. For example to use this style on the slider's
|
||||||
state. For example to use this style on the slider's indicator when the
|
indicator when the slider is pressed:
|
||||||
slider is pressed:
|
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_add_style(slider1, &style1, LV_PART_INDICATOR | LV_STATE_PRESSED);
|
lv_obj_add_style(slider1, &style1, LV_PART_INDICATOR | LV_STATE_PRESSED);
|
||||||
|
|
||||||
|
|
||||||
If the *part* is :cpp:enumerator:`LV_PART_MAIN` it can be omitted:
|
If the *part* is :cpp:enumerator:`LV_PART_MAIN` it can be omitted:
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_add_style(btn1, &style1, LV_STATE_PRESSED); /*Equal to LV_PART_MAIN | LV_STATE_PRESSED*/
|
lv_obj_add_style(btn1, &style1, LV_STATE_PRESSED); /*Equal to LV_PART_MAIN | LV_STATE_PRESSED*/
|
||||||
|
|
||||||
|
|
||||||
Similarly, :cpp:enumerator:`LV_STATE_DEFAULT` can be omitted too:
|
Similarly, :cpp:enumerator:`LV_STATE_DEFAULT` can be omitted too:
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_add_style(slider1, &style1, LV_PART_INDICATOR); /*Equal to LV_PART_INDICATOR | LV_STATE_DEFAULT*/
|
lv_obj_add_style(slider1, &style1, LV_PART_INDICATOR); /*Equal to LV_PART_INDICATOR | LV_STATE_DEFAULT*/
|
||||||
|
|
||||||
|
|
||||||
For :cpp:enumerator:`LV_STATE_DEFAULT` and :cpp:enumerator:`LV_PART_MAIN` simply write ``0``:
|
For :cpp:enumerator:`LV_STATE_DEFAULT` and :cpp:enumerator:`LV_PART_MAIN` simply write ``0``:
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_add_style(btn1, &style1, 0); /*Equal to LV_PART_MAIN | LV_STATE_DEFAULT*/
|
lv_obj_add_style(btn1, &style1, 0); /*Equal to LV_PART_MAIN | LV_STATE_DEFAULT*/
|
||||||
|
|
||||||
Styles can be cascaded (similarly to CSS). It means you can add more
|
|
||||||
styles to a part of an object. For example ``style_btn`` can set a
|
Styles can be cascaded (similarly to CSS). It means you can add more styles to a part of an object. For example
|
||||||
default button appearance, and ``style_btn_red`` can overwrite the
|
``style_btn`` can set a default button appearance, and ``style_btn_red`` can overwrite the background color to
|
||||||
background color to make the button red:
|
make the button red:
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_add_style(btn1, &style_btn, 0);
|
lv_obj_add_style(btn1, &style_btn, 0);
|
||||||
lv_obj_add_style(btn1, &style1_btn_red, 0);
|
lv_obj_add_style(btn1, &style1_btn_red, 0);
|
||||||
|
|
||||||
If a property is not set on for the current state, the style with
|
|
||||||
:cpp:enumerator:`LV_STATE_DEFAULT` will be used. A default value is used if the
|
|
||||||
property is not defined in the default state.
|
|
||||||
|
|
||||||
Some properties (typically the text-related ones) can be inherited. This
|
If a property is not set on for the current state, the style with :cpp:enumerator:`LV_STATE_DEFAULT` will be used.
|
||||||
means if a property is not set in an object it will be searched for in
|
A default value is used if the property is not defined in the default state.
|
||||||
its parents too. For example, you can set the font once in the screen's
|
|
||||||
style and all text on that screen will inherit it by default.
|
|
||||||
|
|
||||||
Local style properties also can be added to objects. This creates a
|
Some properties (typically the text-related ones) can be inherited. This means if a property is not set in an object
|
||||||
style which resides inside the object and is used only by the object:
|
it will be searched for in its parents too. For example, you can set the font once in the screen's style and all text
|
||||||
|
on that screen will inherit it by default.
|
||||||
|
|
||||||
|
Local style properties also can be added to objects. This creates a style which resides inside the object and is used
|
||||||
|
only by the object:
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_set_style_bg_color(slider1, lv_color_hex(0x2080bb), LV_PART_INDICATOR | LV_STATE_PRESSED);
|
lv_obj_set_style_bg_color(slider1, lv_color_hex(0x2080bb), LV_PART_INDICATOR | LV_STATE_PRESSED);
|
||||||
|
|
||||||
|
|
||||||
To learn all the features of styles see the :ref:`styles` section.
|
To learn all the features of styles see the :ref:`styles` section.
|
||||||
|
|
||||||
|
|
||||||
.. _quick-overview_themes:
|
.. _quick-overview_themes:
|
||||||
|
|
||||||
|
|
||||||
Themes
|
Themes
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
Themes are the default styles for objects. Styles from a theme are
|
Themes are the default styles for objects. Styles from a theme are applied automatically when objects are created.
|
||||||
applied automatically when objects are created.
|
|
||||||
|
The theme for your application is a compile time configuration set in ``lv_conf.h``.
|
||||||
|
|
||||||
The theme for your application is a compile time configuration set in
|
|
||||||
``lv_conf.h``.
|
|
||||||
|
|
||||||
.. _quick-overview_examples:
|
.. _quick-overview_examples:
|
||||||
|
|
||||||
@@ -354,6 +355,7 @@ Examples
|
|||||||
|
|
||||||
.. include:: ../examples/get_started/index.rst
|
.. include:: ../examples/get_started/index.rst
|
||||||
|
|
||||||
|
|
||||||
.. _quick-overview_micropython:
|
.. _quick-overview_micropython:
|
||||||
|
|
||||||
|
|
||||||
@@ -364,14 +366,14 @@ Learn more about :ref:`micropython`.
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# Initialize
|
# Initialize
|
||||||
import display_driver
|
import display_driver
|
||||||
import lvgl as lv
|
import lvgl as lv
|
||||||
|
|
||||||
# Create a button with a label
|
# Create a button with a label
|
||||||
scr = lv.obj()
|
scr = lv.obj()
|
||||||
btn = lv.button(scr)
|
btn = lv.button(scr)
|
||||||
btn.align(lv.ALIGN.CENTER, 0, 0)
|
btn.align(lv.ALIGN.CENTER, 0, 0)
|
||||||
label = lv.label(btn)
|
label = lv.label(btn)
|
||||||
label.set_text('Hello World!')
|
label.set_text('Hello World!')
|
||||||
lv.screen_load(scr)
|
lv.screen_load(scr)
|
||||||
|
|||||||
@@ -1,56 +1,53 @@
|
|||||||
Output API as JSON data
|
Output API as JSON data
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
We have written a script that will read the header files in LVGL and outputs a
|
We have written a script that will read the header files in LVGL and outputs a more friendly JSON format for the API.
|
||||||
more friendly JSON format for the API. This is done so that bindings that generate
|
This is done so that bindings that generate code automatically will have an easy way to collect the needed information
|
||||||
code automatically will have an easy way to collect the needed information without
|
without having to reinvent the wheel. The JSON data format has already made libraries for reading the format for just
|
||||||
having to reinvent the wheel. The JSON data format has already made libraries for
|
about every programming language out there.
|
||||||
reading the format for just about every programming language out there.
|
|
||||||
|
|
||||||
The script in order to run does have some requirements.
|
The script in order to run does have some requirements.
|
||||||
|
|
||||||
- Python >= 3.10
|
- Python >= 3.10
|
||||||
- Pycparser >= 2.21: Python Library for reading the preprocessor ouotput from the C compiler
|
- Pycparser >= 2.21: Python Library for reading the preprocessor ouotput from the C compiler
|
||||||
- PyMSVC >= 0.4.0: Python library is using MSVC Compiler
|
- PyMSVC >= 0.4.0: Python library is using MSVC Compiler
|
||||||
- C compiler, gcc for Linux, clang for OSX and MSVC for Windows
|
- C compiler, gcc for Linux, clang for OSX and MSVC for Windows
|
||||||
- Doxygen: used to read the docstrings from the header files.
|
- Doxygen: used to read the docstrings from the header files.
|
||||||
|
|
||||||
|
|
||||||
There are several options when running the script. They are as follows
|
There are several options when running the script. They are as follows
|
||||||
|
|
||||||
- `--output-path`: output directory for JSON file. If one is not supplied
|
- `--output-path`: output directory for JSON file. If one is not supplied then it will be output stdout
|
||||||
then it will be output stdout
|
- `--lvgl-config`: path to lv_conf.h (including file name), if this is not set then a config file will be
|
||||||
- `--lvgl-config`: path to lv_conf.h (including file name), if this is not
|
generated that has most common things turned on
|
||||||
set then a config file will be generated that has most common things turned on
|
- `--develop`: leaves the temporary folder in place.
|
||||||
- `--develop`: leaves the temporary folder in place.
|
|
||||||
|
|
||||||
|
|
||||||
to use the script
|
to use the script
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
python /scripts/gen_json/gen_json.py --output-path=json/output/directory --lvgl-config=path/to/lv_conf.h
|
python /scripts/gen_json/gen_json.py --output-path=json/output/directory --lvgl-config=path/to/lv_conf.h
|
||||||
|
|
||||||
|
|
||||||
or if you want to run a subprocess from inside of a generation script and read the output from stdout
|
or if you want to run a subprocess from inside of a generation script and read the output from stdout
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
python /scripts/gen_json/gen_json.py --lvgl-config=path/to/lv_conf.h
|
python /scripts/gen_json/gen_json.py --lvgl-config=path/to/lv_conf.h
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The JSON data is broken apart into a couple of main categories.
|
The JSON data is broken apart into a couple of main categories.
|
||||||
|
|
||||||
- enums
|
- enums
|
||||||
- functions
|
- functions
|
||||||
- function_pointers
|
- function_pointers
|
||||||
- structures
|
- structures
|
||||||
- unions
|
- unions
|
||||||
- variables
|
- variables
|
||||||
- typedefs
|
- typedefs
|
||||||
- forward_decls
|
- forward_decls
|
||||||
- macros
|
- macros
|
||||||
|
|
||||||
Those categories are the element names undert the root of the JSON data.
|
Those categories are the element names undert the root of the JSON data.
|
||||||
The value for each categry is an array of JSON elements. There is a bit of
|
The value for each categry is an array of JSON elements. There is a bit of
|
||||||
@@ -59,205 +56,205 @@ will allow you to identify exactly what you are dealing with.
|
|||||||
|
|
||||||
The different "json_types" are as follows:
|
The different "json_types" are as follows:
|
||||||
|
|
||||||
- ``"array"``: The array type is used to identify arrays.
|
- ``"array"``: The array type is used to identify arrays.
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"dim"``: number of items in the array
|
- ``"dim"``: number of items in the array
|
||||||
- ``"quals"``: array of qualifiers, IE "const"
|
- ``"quals"``: array of qualifiers, IE "const"
|
||||||
- ``"type"``: This may or may not be available.
|
- ``"type"``: This may or may not be available.
|
||||||
- ``"name"``: the name of the data type
|
- ``"name"``: the name of the data type
|
||||||
|
|
||||||
|
|
||||||
- ``"field"``: This type is used to describe fields in structures and unions.
|
- ``"field"``: This type is used to describe fields in structures and unions.
|
||||||
It is used in the ``"fields"`` array of the ``"struct"`` and ``"union"`` JSON types.
|
It is used in the ``"fields"`` array of the ``"struct"`` and ``"union"`` JSON types.
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: The name of the field.
|
- ``"name"``: The name of the field.
|
||||||
- ``"type"``: This contains the type information for the field. Check the
|
- ``"type"``: This contains the type information for the field. Check the
|
||||||
``"json_type"`` to know what type you are dealing with.
|
``"json_type"`` to know what type you are dealing with.
|
||||||
- ``"bitsize"``: The number of bits the field has or ``null``
|
- ``"bitsize"``: The number of bits the field has or ``null``
|
||||||
if there is no bit size defined
|
if there is no bit size defined
|
||||||
- ``"docstring"``: you should know what this is.
|
- ``"docstring"``: you should know what this is.
|
||||||
|
|
||||||
|
|
||||||
- ``"arg"``: Used to describe an argument/parameter in a function or a function pointer.
|
- ``"arg"``: Used to describe an argument/parameter in a function or a function pointer.
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: The name of the argument/parameter.
|
- ``"name"``: The name of the argument/parameter.
|
||||||
- ``"type"``: This contains the type information for the field. Check the
|
- ``"type"``: This contains the type information for the field. Check the
|
||||||
``"json_type"`` to know what type you are dealing with.
|
``"json_type"`` to know what type you are dealing with.
|
||||||
- ``"docstring"``: you should know what this is.
|
- ``"docstring"``: you should know what this is.
|
||||||
- ``"quals"``: array of qualifiers, IE "const"
|
- ``"quals"``: array of qualifiers, IE "const"
|
||||||
|
|
||||||
|
|
||||||
- ``"forward_decl"``: Describes a forward declaration.There are structures in
|
- ``"forward_decl"``: Describes a forward declaration.There are structures in
|
||||||
LVGL that are considered to be private and that is what these desccribe.
|
LVGL that are considered to be private and that is what these desccribe.
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: The name of the formard declaration.
|
- ``"name"``: The name of the formard declaration.
|
||||||
- ``"type"``: This contains the type information for the field. Check the
|
- ``"type"``: This contains the type information for the field. Check the
|
||||||
``"json_type"`` to know what type you are dealing with.
|
``"json_type"`` to know what type you are dealing with.
|
||||||
- ``"docstring"``: you should know what this is.
|
- ``"docstring"``: you should know what this is.
|
||||||
- ``"quals"``: array of qualifiers, IE "const"
|
- ``"quals"``: array of qualifiers, IE "const"
|
||||||
|
|
||||||
|
|
||||||
- ``"function_pointer"``: Describes a function pointer. These are used when
|
- ``"function_pointer"``: Describes a function pointer. These are used when
|
||||||
registering callback functions in LVGL.
|
registering callback functions in LVGL.
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: The name of the function pointer.
|
- ``"name"``: The name of the function pointer.
|
||||||
- ``"type"``: This contains the return type information for the function pointer.
|
- ``"type"``: This contains the return type information for the function pointer.
|
||||||
- ``"docstring"``: you should know what this is.
|
- ``"docstring"``: you should know what this is.
|
||||||
- ``"args"``: array of ``"arg"`` objects. This describes the fuction arguments/parameters.
|
- ``"args"``: array of ``"arg"`` objects. This describes the fuction arguments/parameters.
|
||||||
- ``"quals"``: array of qualifiers, IE "const"
|
- ``"quals"``: array of qualifiers, IE "const"
|
||||||
|
|
||||||
|
|
||||||
- ``"variable"``: Describes a global variable.
|
- ``"variable"``: Describes a global variable.
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: The name of the variable.
|
- ``"name"``: The name of the variable.
|
||||||
- ``"type"``: This contains the type information for the field. Check the
|
- ``"type"``: This contains the type information for the field. Check the
|
||||||
``"json_type"`` to know what type you are dealing with.
|
``"json_type"`` to know what type you are dealing with.
|
||||||
- ``"docstring"``: you should know what this is.
|
- ``"docstring"``: you should know what this is.
|
||||||
- ``"quals"``: array of qualifiers, IE "const"
|
- ``"quals"``: array of qualifiers, IE "const"
|
||||||
- ``"storage"``: array of storage classifiers, IE "extern"
|
- ``"storage"``: array of storage classifiers, IE "extern"
|
||||||
|
|
||||||
|
|
||||||
- ``"special_type"``: Currently only used to describe an ellipsis argument
|
- ``"special_type"``: Currently only used to describe an ellipsis argument
|
||||||
for a function.
|
for a function.
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: will always be "ellipsis".
|
- ``"name"``: will always be "ellipsis".
|
||||||
|
|
||||||
|
|
||||||
- ``"primitive_type"``: This is a base type. There or no other types beneith this.
|
- ``"primitive_type"``: This is a base type. There or no other types beneith this.
|
||||||
This tells you that the type is a basic or primitive C type.
|
This tells you that the type is a basic or primitive C type.
|
||||||
IE: struct, union, int, unsigned int, etc...
|
IE: struct, union, int, unsigned int, etc...
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: The name of the primitive type.
|
- ``"name"``: The name of the primitive type.
|
||||||
|
|
||||||
|
|
||||||
- ``"enum"``: Describes a grouping of enumeration items/members.
|
- ``"enum"``: Describes a grouping of enumeration items/members.
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: The name of the enumeration group/type.
|
- ``"name"``: The name of the enumeration group/type.
|
||||||
- ``"type"``: This contains the type information for the enumeration group.
|
- ``"type"``: This contains the type information for the enumeration group.
|
||||||
This is always going to be an "int" type. Make sure you do not use this
|
This is always going to be an "int" type. Make sure you do not use this
|
||||||
type as the type for the members of this enumeration group. Check the
|
type as the type for the members of this enumeration group. Check the
|
||||||
enumeration members type to get the correct type.
|
enumeration members type to get the correct type.
|
||||||
- ``"docstring"``: you should know what this is.
|
- ``"docstring"``: you should know what this is.
|
||||||
- ``"members"``: array of ``"enum_member"`` objects
|
- ``"members"``: array of ``"enum_member"`` objects
|
||||||
|
|
||||||
|
|
||||||
- ``"enum_member"``: Describes an enumeration item/member. Only found under
|
- ``"enum_member"``: Describes an enumeration item/member. Only found under
|
||||||
the ``"members"`` field of an ``"enum"`` JSON type
|
the ``"members"`` field of an ``"enum"`` JSON type
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: The name of the enumeration.
|
- ``"name"``: The name of the enumeration.
|
||||||
- ``"type"``: This contains the type information for the enum member.
|
- ``"type"``: This contains the type information for the enum member.
|
||||||
This gets a bit tricky because the type specified in here is not always
|
This gets a bit tricky because the type specified in here is not always
|
||||||
going to be an "int". It will usually point to an lvgl type and the type
|
going to be an "int". It will usually point to an lvgl type and the type
|
||||||
of the lvgl type can be found in the ``"typedefs"`` section.
|
of the lvgl type can be found in the ``"typedefs"`` section.
|
||||||
- ``"docstring"``: you should know what this is.
|
- ``"docstring"``: you should know what this is.
|
||||||
- ``"value"``: the enumeration member/item's value
|
- ``"value"``: the enumeration member/item's value
|
||||||
|
|
||||||
|
|
||||||
- ``"lvgl_type"``: This is a base type. There or no other types beneith this.
|
- ``"lvgl_type"``: This is a base type. There or no other types beneith this.
|
||||||
This tells you that the type is an LVGL data type.
|
This tells you that the type is an LVGL data type.
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: The name of the type.
|
- ``"name"``: The name of the type.
|
||||||
- ``"quals"``: array of qualifiers, IE "const
|
- ``"quals"``: array of qualifiers, IE "const
|
||||||
|
|
||||||
|
|
||||||
- ``"struct"``: Describes a structure
|
- ``"struct"``: Describes a structure
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: The name of the structure.
|
- ``"name"``: The name of the structure.
|
||||||
- ``"type"``: This contains the primitive type information for the structure.
|
- ``"type"``: This contains the primitive type information for the structure.
|
||||||
- ``"docstring"``: you should know what this is.
|
- ``"docstring"``: you should know what this is.
|
||||||
- ``"fields"``: array of ``"field"`` elements.
|
- ``"fields"``: array of ``"field"`` elements.
|
||||||
- ``"quals"``: array of qualifiers, IE "const"
|
- ``"quals"``: array of qualifiers, IE "const"
|
||||||
|
|
||||||
|
|
||||||
- ``"union"``: Describes a union
|
- ``"union"``: Describes a union
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: The name of the union.
|
- ``"name"``: The name of the union.
|
||||||
- ``"type"``: This contains the primitive type information for the union.
|
- ``"type"``: This contains the primitive type information for the union.
|
||||||
- ``"docstring"``: you should know what this is.
|
- ``"docstring"``: you should know what this is.
|
||||||
- ``"fields"``: array of ``"field"`` elements.
|
- ``"fields"``: array of ``"field"`` elements.
|
||||||
- ``"quals"``: array of qualifiers, IE "const"
|
- ``"quals"``: array of qualifiers, IE "const"
|
||||||
|
|
||||||
|
|
||||||
- ``"macro"``: describes a macro. There is limited information that can be
|
- ``"macro"``: describes a macro. There is limited information that can be
|
||||||
collected about macros and in most cases a binding will need to have these
|
collected about macros and in most cases a binding will need to have these
|
||||||
statically added to a binding. It is more for collecting the docstrings than
|
statically added to a binding. It is more for collecting the docstrings than
|
||||||
anything else.
|
anything else.
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: The name of the macro.
|
- ``"name"``: The name of the macro.
|
||||||
- ``"docstring"``: you should know what this is.
|
- ``"docstring"``: you should know what this is.
|
||||||
|
|
||||||
|
|
||||||
- ``"ret_type"``: return type from a function. This is only going to be seen in the ``"type"``
|
- ``"ret_type"``: return type from a function. This is only going to be seen in the ``"type"``
|
||||||
element of a ``"function"`` type.
|
element of a ``"function"`` type.
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"type"``: This contains the type information for the field. Check the
|
- ``"type"``: This contains the type information for the field. Check the
|
||||||
``"json_type"`` to know what type you are dealing with.
|
``"json_type"`` to know what type you are dealing with.
|
||||||
- ``"docstring"``: you should know what this is.
|
- ``"docstring"``: you should know what this is.
|
||||||
|
|
||||||
|
|
||||||
- ``"function"``: Describes a function.
|
- ``"function"``: Describes a function.
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: The name of the function.
|
- ``"name"``: The name of the function.
|
||||||
- ``"type"``: This contains the type information for the return value.
|
- ``"type"``: This contains the type information for the return value.
|
||||||
- ``"docstring"``: you should know what this is.
|
- ``"docstring"``: you should know what this is.
|
||||||
- ``"args"``: array of ``"arg"`` json types. This describes the fuction arguments/parameters.
|
- ``"args"``: array of ``"arg"`` json types. This describes the fuction arguments/parameters.
|
||||||
|
|
||||||
|
|
||||||
- ``"stdlib_type"``: This is a base type, meaning that there are no more
|
- ``"stdlib_type"``: This is a base type, meaning that there are no more
|
||||||
type levels beneith this. This tells us that the type is from the C stdlib.
|
type levels beneith this. This tells us that the type is from the C stdlib.
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: The name of the type.
|
- ``"name"``: The name of the type.
|
||||||
- ``"quals"``: array of qualifiers, IE "const
|
- ``"quals"``: array of qualifiers, IE "const
|
||||||
|
|
||||||
|
|
||||||
- ``"unknown_type"``: This should not be seen. If it is then there needs to be
|
- ``"unknown_type"``: This should not be seen. If it is then there needs to be
|
||||||
an adjustment made to the script. Please open an issue and let us know if you see this type.
|
an adjustment made to the script. Please open an issue and let us know if you see this type.
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: The name of the type.
|
- ``"name"``: The name of the type.
|
||||||
- ``"quals"``: array of qualifiers, IE "const
|
- ``"quals"``: array of qualifiers, IE "const
|
||||||
|
|
||||||
|
|
||||||
- ``"pointer"``: This is a wrapper object to let you know that the type you
|
- ``"pointer"``: This is a wrapper object to let you know that the type you
|
||||||
are dealing with is a pointer
|
are dealing with is a pointer
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"type"``: This contains the type information for the pointer. Check the
|
- ``"type"``: This contains the type information for the pointer. Check the
|
||||||
``"json_type"`` to know what type you are dealing with.
|
``"json_type"`` to know what type you are dealing with.
|
||||||
- ``"quals"``: array of qualifiers, IE "const", may or may not be available.
|
- ``"quals"``: array of qualifiers, IE "const", may or may not be available.
|
||||||
|
|
||||||
|
|
||||||
- ``"typedef"``: type definitions. I will explain more on this below.
|
- ``"typedef"``: type definitions. I will explain more on this below.
|
||||||
|
|
||||||
Available JSON fields:
|
Available JSON fields:
|
||||||
- ``"name"``: The name of the typedef.
|
- ``"name"``: The name of the typedef.
|
||||||
- ``"type"``: This contains the type information for the field. Check the
|
- ``"type"``: This contains the type information for the field. Check the
|
||||||
``"json_type"`` to know what type you are dealing with.
|
``"json_type"`` to know what type you are dealing with.
|
||||||
- ``"docstring"``: you should know what this is.
|
- ``"docstring"``: you should know what this is.
|
||||||
- ``"quals"``: array of qualifiers, IE "const"
|
- ``"quals"``: array of qualifiers, IE "const"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Here is an example of what the output will look like.
|
Here is an example of what the output will look like.
|
||||||
|
|
||||||
.. code:: json
|
.. code-block:: json
|
||||||
|
|
||||||
{
|
{
|
||||||
"enums":[
|
"enums":[
|
||||||
|
|||||||
@@ -2,11 +2,10 @@
|
|||||||
JavaScript
|
JavaScript
|
||||||
==========
|
==========
|
||||||
|
|
||||||
With `lv_binding_js <https://github.com/lvgl/lv_binding_js>`__ you can
|
With `lv_binding_js <https://github.com/lvgl/lv_binding_js>`__ you can write lvgl with JavaScript.
|
||||||
write lvgl with JavaScript.
|
|
||||||
|
|
||||||
It uses React's virtual DOM concept to manipulate lvgl UI components,
|
It uses React's virtual DOM concept to manipulate lvgl UI components, providing a familiar React-like
|
||||||
providing a familiar React-like experience to users.
|
experience to users.
|
||||||
|
|
||||||
**Code**
|
**Code**
|
||||||
|
|
||||||
@@ -15,119 +14,123 @@ providing a familiar React-like experience to users.
|
|||||||
Table of Contents
|
Table of Contents
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
- `Features <#features>`__
|
- `Features <#features>`__
|
||||||
- `Demo <#demo>`__
|
- `Demo <#demo>`__
|
||||||
- `Building <#building>`__
|
- `Building <#building>`__
|
||||||
- `Components <#components>`__
|
- `Components <#components>`__
|
||||||
- `Font <#font>`__
|
- `Font <#font>`__
|
||||||
- `Animation <#animation>`__
|
- `Animation <#animation>`__
|
||||||
- `Style <#style>`__
|
- `Style <#style>`__
|
||||||
- `JSAPI <#jsapi>`__
|
- `JSAPI <#jsapi>`__
|
||||||
- `Thanks <#thanks>`__
|
- `Thanks <#thanks>`__
|
||||||
|
|
||||||
|
|
||||||
Features
|
Features
|
||||||
--------
|
--------
|
||||||
|
|
||||||
- Support all lvgl built-in components
|
- Support all lvgl built-in components
|
||||||
- Fully support lvgl flex and grid style
|
- Fully support lvgl flex and grid style
|
||||||
- support most lvgl style, just write like html5 css
|
- support most lvgl style, just write like html5 css
|
||||||
- support dynamic load image
|
- support dynamic load image
|
||||||
- Fully support lvgl animation
|
- Fully support lvgl animation
|
||||||
|
|
||||||
|
|
||||||
Demo
|
Demo
|
||||||
----
|
----
|
||||||
|
|
||||||
See the
|
See the `demo <https://github.com/lvgl/lv_binding_js/tree/master/demo>`__ folder
|
||||||
`demo <https://github.com/lvgl/lv_binding_js/tree/master/demo>`__ folder
|
|
||||||
|
|
||||||
Building
|
Building
|
||||||
--------
|
--------
|
||||||
|
|
||||||
The following are developer notes on how to build lvgljs on your native
|
The following are developer notes on how to build lvgljs on your native platform. They are not complete guides,
|
||||||
platform. They are not complete guides, but include notes on the
|
but include notes on the necessary libraries, compile flags, etc.
|
||||||
necessary libraries, compile flags, etc.
|
|
||||||
|
|
||||||
lvgljs
|
lvgljs
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
- `ubuntu build Notes for sdl
|
- `ubuntu build Notes for sdl simulator <https://github.com/lvgl/lv_binding_js/blob/master/doc/build/build-ubuntu-arm.md>`__
|
||||||
simulator <https://github.com/lvgl/lv_binding_js/blob/master/doc/build/build-ubuntu-arm.md>`__
|
- `macos x86 build Notes for sdl simulator <https://github.com/lvgl/lv_binding_js/blob/master/doc/build/build-macos-x86-simulator.md>`__
|
||||||
- `macos x86 build Notes for sdl
|
- `ubuntu build Notes for platform arm <https://github.com/lvgl/lv_binding_js/blob/master/doc/build/build-ubuntu-x86-simulator.md>`__
|
||||||
simulator <https://github.com/lvgl/lv_binding_js/blob/master/doc/build/build-macos-x86-simulator.md>`__
|
|
||||||
- `ubuntu build Notes for platform
|
|
||||||
arm <https://github.com/lvgl/lv_binding_js/blob/master/doc/build/build-ubuntu-x86-simulator.md>`__
|
|
||||||
|
|
||||||
JS Bundle
|
JS Bundle
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
|
||||||
- `JS Bundle build
|
- `JS Bundle build Notes <https://github.com/lvgl/lv_binding_js/blob/master/doc/build/js-bundle.md>`__
|
||||||
Notes <https://github.com/lvgl/lv_binding_js/blob/master/doc/build/js-bundle.md>`__
|
|
||||||
|
|
||||||
Components
|
Components
|
||||||
----------
|
----------
|
||||||
|
|
||||||
- `View <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/View.md>`__
|
- `View <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/View.md>`__
|
||||||
- `Image <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Image.md>`__
|
- `Image <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Image.md>`__
|
||||||
- `Button <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Button.md>`__
|
- `Button <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Button.md>`__
|
||||||
- `Text <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Text.md>`__
|
- `Text <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Text.md>`__
|
||||||
- `Input <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Input.md>`__
|
- `Input <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Input.md>`__
|
||||||
- `Textarea <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Textarea.md>`__
|
- `Textarea <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Textarea.md>`__
|
||||||
- `Switch <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Switch.md>`__
|
- `Switch <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Switch.md>`__
|
||||||
- `Checkbox <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Checkbox.md>`__
|
- `Checkbox <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Checkbox.md>`__
|
||||||
- `Dropdownlist <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Dropdownlist.md>`__
|
- `Dropdownlist <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Dropdownlist.md>`__
|
||||||
- `ProgressBar <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/ProgressBar.md>`__
|
- `ProgressBar <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/ProgressBar.md>`__
|
||||||
- `Line <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Line.md>`__
|
- `Line <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Line.md>`__
|
||||||
- `Roller <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Roller.md>`__
|
- `Roller <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Roller.md>`__
|
||||||
- `Keyboard <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Keyboard.md>`__
|
- `Keyboard <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Keyboard.md>`__
|
||||||
- `Calendar <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Calendar.md>`__
|
- `Calendar <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Calendar.md>`__
|
||||||
- `Chart <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Chart.md>`__
|
- `Chart <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Chart.md>`__
|
||||||
|
|
||||||
|
|
||||||
Font
|
Font
|
||||||
----
|
----
|
||||||
|
|
||||||
`Builtin-Symbol <https://github.com/lvgl/lv_binding_js/blob/master/doc/Symbol/symbol.md>`__
|
- `Builtin-Symbol <https://github.com/lvgl/lv_binding_js/blob/master/doc/Symbol/symbol.md>`__
|
||||||
|
|
||||||
|
|
||||||
Animation
|
Animation
|
||||||
---------
|
---------
|
||||||
|
|
||||||
`Animation <https://github.com/lvgl/lv_binding_js/blob/master/doc/animate/animate.md>`__
|
- `Animation <https://github.com/lvgl/lv_binding_js/blob/master/doc/animate/animate.md>`__
|
||||||
|
|
||||||
|
|
||||||
Style
|
Style
|
||||||
-----
|
-----
|
||||||
|
|
||||||
.. include::https://github.com/lvgl/lv_binding_js/blob/master/doc/style/position-size-layout.md
|
.. include::https://github.com/lvgl/lv_binding_js/blob/master/doc/style/position-size-layout.md
|
||||||
|
|
||||||
- `position-size-layout <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/position-size-layout.md>`__
|
- `position-size-layout <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/position-size-layout.md>`__
|
||||||
- `boxing-model <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/boxing-model.md>`__
|
- `boxing-model <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/boxing-model.md>`__
|
||||||
- `color <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/color.md>`__
|
- `color <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/color.md>`__
|
||||||
- `flex <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/flex.md>`__
|
- `flex <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/flex.md>`__
|
||||||
- `grid <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/grid.md>`__
|
- `grid <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/grid.md>`__
|
||||||
- `font <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/font.md>`__
|
- `font <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/font.md>`__
|
||||||
- `opacity <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/opacity.md>`__
|
- `opacity <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/opacity.md>`__
|
||||||
- `display <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/display.md>`__
|
- `display <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/display.md>`__
|
||||||
- `background <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/background.md>`__
|
- `background <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/background.md>`__
|
||||||
- `scroll <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/scroll.md>`__
|
- `scroll <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/scroll.md>`__
|
||||||
- `shadow <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/shadow.md>`__
|
- `shadow <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/shadow.md>`__
|
||||||
- `recolor <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/recolor.md>`__
|
- `recolor <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/recolor.md>`__
|
||||||
- `line <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/line.md>`__
|
- `line <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/line.md>`__
|
||||||
- `transition <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/transition.md>`__
|
- `transition <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/transition.md>`__
|
||||||
- `transform <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/transform.md>`__
|
- `transform <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/transform.md>`__
|
||||||
|
|
||||||
|
|
||||||
JSAPI
|
JSAPI
|
||||||
-----
|
-----
|
||||||
|
|
||||||
- `network <https://github.com/lvgl/lv_binding_js/blob/master/doc/jsapi/network.md>`__
|
- `network <https://github.com/lvgl/lv_binding_js/blob/master/doc/jsapi/network.md>`__
|
||||||
- `filesystem <https://github.com/lvgl/lv_binding_js/blob/master/doc/jsapi/fs.md>`__
|
- `filesystem <https://github.com/lvgl/lv_binding_js/blob/master/doc/jsapi/fs.md>`__
|
||||||
- `dimension <https://github.com/lvgl/lv_binding_js/blob/master/doc/jsapi/dimension.md>`__
|
- `dimension <https://github.com/lvgl/lv_binding_js/blob/master/doc/jsapi/dimension.md>`__
|
||||||
|
|
||||||
|
|
||||||
Thanks
|
Thanks
|
||||||
------
|
------
|
||||||
|
|
||||||
lvgljs depends on following excellent work
|
lvgljs depends on following excellent work
|
||||||
|
|
||||||
`lvgl <https://github.com/lvgl/lvgl>`__: Create beautiful UIs for any
|
- `lvgl <https://github.com/lvgl/lvgl>`__: Create beautiful UIs for any MCU, MPU and display type
|
||||||
MCU, MPU and display type `QuickJS <https://bellard.org/quickjs/>`__:
|
- `QuickJS <https://bellard.org/quickjs/>`__: JavaScript engine
|
||||||
JavaScript engine `libuv <https://github.com/libuv/libuv>`__: platform
|
- `libuv <https://github.com/libuv/libuv>`__: platform abstraction layer
|
||||||
abstraction layer `curl <https://github.com/curl/curl>`__: HTTP client
|
- `curl <https://github.com/curl/curl>`__: HTTP client
|
||||||
`txiki.js <https://github.com/saghul/txiki.js>`__: Tiny JavaScript
|
- `txiki.js <https://github.com/saghul/txiki.js>`__: Tiny JavaScript runtime
|
||||||
runtime
|
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
MicroPython
|
MicroPython
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
|
||||||
What is MicroPython?
|
What is MicroPython?
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
`MicroPython <http://micropython.org/>`__ is Python for
|
`MicroPython <http://micropython.org/>`__ is Python for microcontrollers. Using MicroPython, you can write Python3
|
||||||
microcontrollers. Using MicroPython, you can write Python3 code and run
|
code and run it even on a bare metal architecture with limited resources.
|
||||||
it even on a bare metal architecture with limited resources.
|
|
||||||
|
|
||||||
|
|
||||||
Highlights of MicroPython
|
Highlights of MicroPython
|
||||||
@@ -31,6 +31,7 @@ Highlights of MicroPython
|
|||||||
`machine module <https://docs.micropython.org/en/latest/library/machine.html#classes>`__
|
`machine module <https://docs.micropython.org/en/latest/library/machine.html#classes>`__
|
||||||
for accessing low-level hardware (I/O pins, ADC, UART, SPI, I2C, RTC, Timers etc.)
|
for accessing low-level hardware (I/O pins, ADC, UART, SPI, I2C, RTC, Timers etc.)
|
||||||
|
|
||||||
|
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ Here are some advantages of using LVGL in MicroPython:
|
|||||||
**``Change code`` > ``Run``** ! You can even run commands interactively using the
|
**``Change code`` > ``Run``** ! You can even run commands interactively using the
|
||||||
`REPL <https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop>`__ (the interactive prompt)
|
`REPL <https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop>`__ (the interactive prompt)
|
||||||
|
|
||||||
|
|
||||||
MicroPython + LVGL could be used for:
|
MicroPython + LVGL could be used for:
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@@ -65,6 +67,7 @@ MicroPython + LVGL could be used for:
|
|||||||
embedded development.
|
embedded development.
|
||||||
- Creating tools to work with LVGL at a higher level (e.g. drag-and-drop designer).
|
- Creating tools to work with LVGL at a higher level (e.g. drag-and-drop designer).
|
||||||
|
|
||||||
|
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
|
||||||
@@ -79,30 +82,30 @@ Let's dive right into an example!
|
|||||||
A simple example
|
A simple example
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# Initialize
|
# Initialize
|
||||||
import display_driver
|
import display_driver
|
||||||
import lvgl as lv
|
import lvgl as lv
|
||||||
|
|
||||||
# Create a button with a label
|
# Create a button with a label
|
||||||
scr = lv.obj()
|
scr = lv.obj()
|
||||||
btn = lv.button(scr)
|
btn = lv.button(scr)
|
||||||
btn.align(lv.ALIGN.CENTER, 0, 0)
|
btn.align(lv.ALIGN.CENTER, 0, 0)
|
||||||
label = lv.label(btn)
|
label = lv.label(btn)
|
||||||
label.set_text('Hello World!')
|
label.set_text('Hello World!')
|
||||||
lv.screen_load(scr)
|
lv.screen_load(scr)
|
||||||
|
|
||||||
|
|
||||||
How can I use it?
|
How can I use it?
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|
||||||
Online Simulator
|
Online Simulator
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
If you want to experiment with LVGL + MicroPython without downloading
|
If you want to experiment with LVGL + MicroPython without downloading anything, you can use our online
|
||||||
anything - you can use our online simulator! It's a fully functional
|
simulator! It's a fully functional LVGL + MicroPython that runs entirely in the browser and allows you to
|
||||||
LVGL + MicroPython that runs entirely in the browser and allows you to
|
|
||||||
edit a python script and run it.
|
edit a python script and run it.
|
||||||
|
|
||||||
`Click here to experiment on the online simulator <https://sim.lvgl.io/>`__
|
`Click here to experiment on the online simulator <https://sim.lvgl.io/>`__
|
||||||
@@ -130,6 +133,7 @@ supports Linux, ESP32, STM32 and RP2. It can be ported to any other platform sup
|
|||||||
or you can create your own input/display drivers for your specific hardware.
|
or you can create your own input/display drivers for your specific hardware.
|
||||||
- Drivers can be implemented either in C as a MicroPython module, or in pure Python!
|
- Drivers can be implemented either in C as a MicroPython module, or in pure Python!
|
||||||
|
|
||||||
|
|
||||||
lv_micropython already contains these drivers:
|
lv_micropython already contains these drivers:
|
||||||
|
|
||||||
- Display drivers:
|
- Display drivers:
|
||||||
@@ -184,20 +188,22 @@ LVGL C API Coding Conventions
|
|||||||
|
|
||||||
For a summary of coding conventions to follow see the :ref:`coding-style`.
|
For a summary of coding conventions to follow see the :ref:`coding-style`.
|
||||||
|
|
||||||
|
|
||||||
.. _memory_management:
|
.. _memory_management:
|
||||||
|
|
||||||
Memory Management
|
Memory Management
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
| When LVGL runs in MicroPython, all dynamic memory allocations (:cpp:func:`lv_malloc`) are handled by MicroPython's memory
|
- When LVGL runs in MicroPython, all dynamic memory allocations (:cpp:func:`lv_malloc`) are handled by MicroPython's memory
|
||||||
manager which is `garbage-collected <https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)>`__ (GC).
|
manager which is `garbage-collected <https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)>`__ (GC).
|
||||||
| To prevent GC from collecting memory prematurely, all dynamic allocated RAM must be reachable by GC.
|
- To prevent GC from collecting memory prematurely, all dynamic allocated RAM must be reachable by GC.
|
||||||
| GC is aware of most allocations, except from pointers on the `Data Segment <https://en.wikipedia.org/wiki/Data_segment>`__:
|
- GC is aware of most allocations, except from pointers on the `Data Segment <https://en.wikipedia.org/wiki/Data_segment>`__:
|
||||||
|
|
||||||
- Pointers which are global variables
|
- Pointers which are global variables
|
||||||
- Pointers which are static global variables
|
- Pointers which are static global variables
|
||||||
- Pointers which are static local variables
|
- Pointers which are static local variables
|
||||||
|
|
||||||
|
|
||||||
Such pointers need to be defined in a special way to make them reachable by GC
|
Such pointers need to be defined in a special way to make them reachable by GC
|
||||||
|
|
||||||
|
|
||||||
@@ -215,6 +221,7 @@ Solve The Problem
|
|||||||
- Include ``lv_global.h`` on files that use ``LV_GLOBAL_DEFAULT``
|
- Include ``lv_global.h`` on files that use ``LV_GLOBAL_DEFAULT``
|
||||||
- Add ``_var`` to ``lv_global_t`` on ``lv_global.h``
|
- Add ``_var`` to ``lv_global_t`` on ``lv_global.h``
|
||||||
|
|
||||||
|
|
||||||
Example
|
Example
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
|
|
||||||
@@ -225,6 +232,7 @@ More Information
|
|||||||
- `In the README <https://github.com/lvgl/lv_binding_micropython#memory-management>`__
|
- `In the README <https://github.com/lvgl/lv_binding_micropython#memory-management>`__
|
||||||
- `In the Blog <https://blog.lvgl.io/2019-02-20/micropython-bindings#i-need-to-allocate-a-littlevgl-struct-such-as-style-color-etc-how-can-i-do-that-how-do-i-allocatedeallocate-memory-for-it>`__
|
- `In the Blog <https://blog.lvgl.io/2019-02-20/micropython-bindings#i-need-to-allocate-a-littlevgl-struct-such-as-style-color-etc-how-can-i-do-that-how-do-i-allocatedeallocate-memory-for-it>`__
|
||||||
|
|
||||||
|
|
||||||
.. _callbacks:
|
.. _callbacks:
|
||||||
|
|
||||||
Callbacks
|
Callbacks
|
||||||
@@ -244,6 +252,7 @@ next to the function pointer when registering a callback, and access that object
|
|||||||
``user_data`` to automatically keep track of the MicroPython callable object. The glue code updates it when the callback
|
``user_data`` to automatically keep track of the MicroPython callable object. The glue code updates it when the callback
|
||||||
is registered, and uses it when the callback is called in order to invoke a call to the original callable object.
|
is registered, and uses it when the callback is called in order to invoke a call to the original callable object.
|
||||||
|
|
||||||
|
|
||||||
There are a few options for defining a callback in LVGL C API:
|
There are a few options for defining a callback in LVGL C API:
|
||||||
|
|
||||||
- Option 1: ``user_data`` in a struct
|
- Option 1: ``user_data`` in a struct
|
||||||
@@ -265,21 +274,22 @@ There are a few options for defining a callback in LVGL C API:
|
|||||||
|
|
||||||
- The function pointer member receives the same struct as its **first** argument
|
- The function pointer member receives the same struct as its **first** argument
|
||||||
|
|
||||||
|
|
||||||
In practice it's also possible to mix these options, for example provide a struct pointer when registering a callback
|
In practice it's also possible to mix these options, for example provide a struct pointer when registering a callback
|
||||||
(option 1) and provide ``user_data`` argument when calling the callback (options 2),
|
(option 1) and provide ``user_data`` argument when calling the callback (options 2),
|
||||||
**as long as the same ``user_data`` that was registered is passed to the callback when it's called**.
|
**as long as the same ``user_data`` that was registered is passed to the callback when it's called**.
|
||||||
|
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
- :cpp:type:`lv_anim_t` contains ``user_data`` field. :cpp:func:`lv_anim_set_path_cb`
|
- :cpp:type:`lv_anim_t` contains ``user_data`` field. :cpp:func:`lv_anim_set_path_cb` registers `path_cb` callback.
|
||||||
registers `path_cb` callback. Both ``lv_anim_set_path_cb`` and :cpp:type:`lv_anim_path_cb_t`
|
Both ``lv_anim_set_path_cb`` and :cpp:type:`lv_anim_path_cb_t` receive :cpp:type:`lv_anim_t` as their first argument
|
||||||
receive :cpp:type:`lv_anim_t` as their first argument
|
- ``path_cb`` field can also be assigned directly in the Python code because it's a member of :cpp:type:`lv_anim_t`
|
||||||
- ``path_cb`` field can also be assigned directly in the Python code because it's a member
|
which contains ``user_data`` field, and :cpp:type:`lv_anim_path_cb_t` receive :cpp:type:`lv_anim_t` as its first argument.
|
||||||
of :cpp:type:`lv_anim_t` which contains ``user_data`` field, and :cpp:type:`lv_anim_path_cb_t`
|
- :cpp:func:`lv_imgfont_create` registers ``path_cb`` and receives ``user_data`` as the last argument.
|
||||||
receive :cpp:type:`lv_anim_t` as its first argument.
|
The callback :cpp:type:`lv_imgfont_get_path_cb_t` also receives the ``user_data`` as the last argument.
|
||||||
- :cpp:func:`lv_imgfont_create` registers ``path_cb`` and receives ``user_data`` as the last
|
|
||||||
argument. The callback :cpp:type:`lv_imgfont_get_path_cb_t` also receives the ``user_data`` as the last argument.
|
|
||||||
|
|
||||||
.. _more-information-1:
|
.. _more-information-1:
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,25 @@
|
|||||||
PikaScript
|
PikaScript
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
|
||||||
What is PikaScript ?
|
What is PikaScript ?
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
`PikaScript <https://github.com/pikasTech/pikascript>`__ is a Python
|
`PikaScript <https://github.com/pikasTech/pikascript>`__ is a Python interpreter designed specifically for
|
||||||
interpreter designed specifically for microcontrollers, and it supports
|
microcontrollers, and it supports a subset of the common Python3 syntax.
|
||||||
a subset of the common Python3 syntax.
|
|
||||||
|
|
||||||
It's lighter, requiring only 32k of code space and 4k of RAM, which
|
It's lighter, requiring only 32k of code space and 4k of RAM, which means it can run on stm32f103c8 (blue-pill)
|
||||||
means it can run on stm32f103c8 (blue-pill) or even stm32g030c8, on the
|
or even stm32g030c8, on the other hand, you can leave valuable space for more material or larger buffer areas.
|
||||||
other hand, you can leave valuable space for more material or larger
|
|
||||||
buffer areas.
|
|
||||||
|
|
||||||
It is simpler, out of the box, runs with no porting and configuration at
|
It is simpler, out of the box, runs with no porting and configuration at all, does not depend on OS or file
|
||||||
all, does not depend on OS or file system, has good support for popular
|
system, has good support for popular IDEs for Windows platforms like Keil, IAR, RT-Thread-Studio, and of course,
|
||||||
IDEs for Windows platforms like Keil, IAR, RT-Thread-Studio, and of
|
supports linux-gcc development platforms.
|
||||||
course, supports linux-gcc development platforms.
|
|
||||||
|
It's smarter, with a unique C module mechanism that allows you to generate bindings automatically by simply
|
||||||
|
writing the API for the C module in Python, and you don't need to deal with the headache of writing any macros
|
||||||
|
or global tables manually. On the other hand, all C modules have sophisticated smart hints, even hinting at the types
|
||||||
|
of your arguments .
|
||||||
|
|
||||||
It's smarter, with a unique C module mechanism that allows you to
|
|
||||||
generate bindings automatically by simply writing the API for the C
|
|
||||||
module in Python, and you don't need to deal with the headache of
|
|
||||||
writing any macros or global tables manually. On the other hand, all C
|
|
||||||
modules have sophisticated smart hints, even hinting at the types of
|
|
||||||
your arguments .
|
|
||||||
|
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
@@ -31,107 +27,107 @@ your arguments .
|
|||||||
Why PikaScript + LVGL ?
|
Why PikaScript + LVGL ?
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
PikaScript now supports the main features of LVGL8, and these APIs are
|
- PikaScript now supports the main features of LVGL8, and these APIs are fully compatible with MicroPython!
|
||||||
fully compatible with MicroPython!
|
This means that you can continue to use already written code from MicroPython, and then use less code space and RAM.
|
||||||
|
- Enjoy detailed code hints down to the parameter type for a better programming experience
|
||||||
This means that you can continue to use already written code from
|
- Use a more convenient IDE, such as vs-based simulation projects
|
||||||
MicroPython, and then use less code space and RAM.
|
|
||||||
|
|
||||||
Enjoy detailed code hints down to the parameter type for a better
|
|
||||||
programming experience
|
|
||||||
|
|
||||||
Use a more convenient IDE, such as vs-based simulation projects
|
|
||||||
|
|
||||||
|
|
||||||
So how does it look like?
|
So how does it look like?
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
Here are some examples of lvgl that PikaScript can already run, they are
|
Here are some examples of lvgl that PikaScript can already run, they are mainly from the lvgl documentation examples
|
||||||
mainly from the lvgl documentation examples
|
|
||||||
|
|
||||||
|
|
||||||
LV_ARC
|
LV_ARC
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
import pika_lvgl as lv
|
import pika_lvgl as lv
|
||||||
import PikaStdLib
|
import PikaStdLib
|
||||||
mem = PikaStdLib.MemChecker()
|
mem = PikaStdLib.MemChecker()
|
||||||
# Create an Arc
|
# Create an Arc
|
||||||
arc = lv.arc(lv.screen_active())
|
arc = lv.arc(lv.screen_active())
|
||||||
arc.set_end_angle(200)
|
arc.set_end_angle(200)
|
||||||
arc.set_size(150, 150)
|
arc.set_size(150, 150)
|
||||||
arc.center()
|
arc.center()
|
||||||
print('mem used max: %0.2f kB' % (mem.getMax()))
|
print('mem used max: %0.2f kB' % (mem.getMax()))
|
||||||
print('mem used now: %0.2f kB' % (mem.getNow()))
|
print('mem used now: %0.2f kB' % (mem.getNow()))
|
||||||
|
|
||||||
|
|
||||||
LV_BAR
|
LV_BAR
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
import pika_lvgl as lv
|
import pika_lvgl as lv
|
||||||
import PikaStdLib
|
import PikaStdLib
|
||||||
mem = PikaStdLib.MemChecker()
|
mem = PikaStdLib.MemChecker()
|
||||||
bar1 = lv.bar(lv.screen_active())
|
bar1 = lv.bar(lv.screen_active())
|
||||||
bar1.set_size(200, 20)
|
bar1.set_size(200, 20)
|
||||||
bar1.center()
|
bar1.center()
|
||||||
bar1.set_value(70, lv.ANIM.OFF)
|
bar1.set_value(70, lv.ANIM.OFF)
|
||||||
print('mem used max: %0.2f kB' % (mem.getMax()))
|
print('mem used max: %0.2f kB' % (mem.getMax()))
|
||||||
print('mem used now: %0.2f kB' % (mem.getNow()))
|
print('mem used now: %0.2f kB' % (mem.getNow()))
|
||||||
|
|
||||||
|
|
||||||
LV_BTN
|
LV_BTN
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
import pika_lvgl as lv
|
import pika_lvgl as lv
|
||||||
import PikaStdLib
|
import PikaStdLib
|
||||||
mem = PikaStdLib.MemChecker()
|
mem = PikaStdLib.MemChecker()
|
||||||
def event_cb_1(evt):
|
|
||||||
print('in evt1')
|
|
||||||
print('mem used now: %0.2f kB' % (mem.getNow()))
|
def event_cb_1(evt):
|
||||||
def event_cb_2(evt):
|
print('in evt1')
|
||||||
print('in evt2')
|
print('mem used now: %0.2f kB' % (mem.getNow()))
|
||||||
print('mem used now: %0.2f kB' % (mem.getNow()))
|
|
||||||
btn1 = lv.btn(lv.screen_active())
|
|
||||||
btn1.align(lv.ALIGN.TOP_MID, 0, 10)
|
def event_cb_2(evt):
|
||||||
btn2 = lv.btn(lv.screen_active())
|
print('in evt2')
|
||||||
btn2.align(lv.ALIGN.TOP_MID, 0, 50)
|
print('mem used now: %0.2f kB' % (mem.getNow()))
|
||||||
btn1.add_event_cb(event_cb_1, lv.EVENT.CLICKED, 0)
|
|
||||||
btn2.add_event_cb(event_cb_2, lv.EVENT.CLICKED, 0)
|
|
||||||
print('mem used max: %0.2f kB' % (mem.getMax()))
|
btn1 = lv.btn(lv.screen_active())
|
||||||
print('mem used now: %0.2f kB' % (mem.getNow()))
|
btn1.align(lv.ALIGN.TOP_MID, 0, 10)
|
||||||
|
btn2 = lv.btn(lv.screen_active())
|
||||||
|
btn2.align(lv.ALIGN.TOP_MID, 0, 50)
|
||||||
|
btn1.add_event_cb(event_cb_1, lv.EVENT.CLICKED, 0)
|
||||||
|
btn2.add_event_cb(event_cb_2, lv.EVENT.CLICKED, 0)
|
||||||
|
print('mem used max: %0.2f kB' % (mem.getMax()))
|
||||||
|
print('mem used now: %0.2f kB' % (mem.getNow()))
|
||||||
|
|
||||||
|
|
||||||
LV_CHECKBOX
|
LV_CHECKBOX
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
import pika_lvgl as lv
|
||||||
|
import PikaStdLib
|
||||||
|
mem = PikaStdLib.MemChecker()
|
||||||
|
cb = lv.checkbox(lv.screen_active())
|
||||||
|
cb.set_text("Apple")
|
||||||
|
cb.align(lv.ALIGN.TOP_LEFT, 0 ,0)
|
||||||
|
cb = lv.checkbox(lv.screen_active())
|
||||||
|
cb.set_text("Banana")
|
||||||
|
cb.add_state(lv.STATE.CHECKED)
|
||||||
|
cb.align(lv.ALIGN.TOP_LEFT, 0 ,30)
|
||||||
|
cb = lv.checkbox(lv.screen_active())
|
||||||
|
cb.set_text("Lemon")
|
||||||
|
cb.add_state(lv.STATE.DISABLED)
|
||||||
|
cb.align(lv.ALIGN.TOP_LEFT, 0 ,60)
|
||||||
|
cb = lv.checkbox(lv.screen_active())
|
||||||
|
cb.add_state(lv.STATE.CHECKED | lv.STATE.DISABLED)
|
||||||
|
cb.set_text("Melon")
|
||||||
|
cb.align(lv.ALIGN.TOP_LEFT, 0 ,90)
|
||||||
|
print('mem used max: %0.2f kB' % (mem.getMax()))
|
||||||
|
print('mem used now: %0.2f kB' % (mem.getNow()))
|
||||||
|
|
||||||
import pika_lvgl as lv
|
|
||||||
import PikaStdLib
|
|
||||||
mem = PikaStdLib.MemChecker()
|
|
||||||
cb = lv.checkbox(lv.screen_active())
|
|
||||||
cb.set_text("Apple")
|
|
||||||
cb.align(lv.ALIGN.TOP_LEFT, 0 ,0)
|
|
||||||
cb = lv.checkbox(lv.screen_active())
|
|
||||||
cb.set_text("Banana")
|
|
||||||
cb.add_state(lv.STATE.CHECKED)
|
|
||||||
cb.align(lv.ALIGN.TOP_LEFT, 0 ,30)
|
|
||||||
cb = lv.checkbox(lv.screen_active())
|
|
||||||
cb.set_text("Lemon")
|
|
||||||
cb.add_state(lv.STATE.DISABLED)
|
|
||||||
cb.align(lv.ALIGN.TOP_LEFT, 0 ,60)
|
|
||||||
cb = lv.checkbox(lv.screen_active())
|
|
||||||
cb.add_state(lv.STATE.CHECKED | lv.STATE.DISABLED)
|
|
||||||
cb.set_text("Melon")
|
|
||||||
cb.align(lv.ALIGN.TOP_LEFT, 0 ,90)
|
|
||||||
print('mem used max: %0.2f kB' % (mem.getMax()))
|
|
||||||
print('mem used now: %0.2f kB' % (mem.getNow()))
|
|
||||||
|
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
@@ -141,42 +137,41 @@ How does it work?
|
|||||||
|
|
||||||
PikaScript has a unique C module smart binding tool
|
PikaScript has a unique C module smart binding tool
|
||||||
|
|
||||||
Just write the Python interface in pika_lvgl.pyi (.pyi is the python
|
Just write the Python interface in pika_lvgl.pyi (.pyi is the python interface file)
|
||||||
interface file)
|
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# pika_lvgl.pyi
|
# pika_lvgl.pyi
|
||||||
class arc(lv_obj):
|
class arc(lv_obj):
|
||||||
def set_end_angle(self, angle: int): ...
|
def set_end_angle(self, angle: int): ...
|
||||||
def set_bg_angles(self, start: int, end: int): ...
|
def set_bg_angles(self, start: int, end: int): ...
|
||||||
def set_angles(self, start: int, end: int): ...
|
def set_angles(self, start: int, end: int): ...
|
||||||
|
|
||||||
Then PikaScript's pre-compiler can automatically bind the following C
|
|
||||||
functions, simply by naming the functions in the module_class_method
|
|
||||||
format, without any additional work, and all binding and registration is
|
|
||||||
done automatically.
|
|
||||||
|
|
||||||
.. code:: c
|
Then PikaScript's pre-compiler can automatically bind the following C functions, simply by naming the functions
|
||||||
|
in the module_class_method format, without any additional work, and all binding and registration is done automatically.
|
||||||
|
|
||||||
/* pika_lvgl_arc.c */
|
.. code-block:: c
|
||||||
void pika_lvgl_arc_set_end_angle(PikaObj* self, int angle) {
|
|
||||||
lv_obj_t* lv_obj = obj_getPtr(self, "lv_obj");
|
|
||||||
lv_arc_set_end_angle(lv_obj, angle);
|
|
||||||
}
|
|
||||||
void pika_lvgl_arc_set_bg_angles(PikaObj *self, int start, int end){
|
|
||||||
lv_obj_t* lv_obj = obj_getPtr(self, "lv_obj");
|
|
||||||
lv_arc_set_bg_angles(lv_obj, start, end);
|
|
||||||
}
|
|
||||||
void pika_lvgl_arc_set_angles(PikaObj *self, int start, int end){
|
|
||||||
lv_obj_t* lv_obj = obj_getPtr(self, "lv_obj");
|
|
||||||
lv_arc_set_angles(lv_obj, start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
To use the module, just ``import pika_lvgl`` and the precompiler will
|
/* pika_lvgl_arc.c */
|
||||||
automatically scan main.py and bind the ``pika_lvgl`` module
|
void pika_lvgl_arc_set_end_angle(PikaObj* self, int angle) {
|
||||||
|
lv_obj_t* lv_obj = obj_getPtr(self, "lv_obj");
|
||||||
|
lv_arc_set_end_angle(lv_obj, angle);
|
||||||
|
}
|
||||||
|
void pika_lvgl_arc_set_bg_angles(PikaObj *self, int start, int end){
|
||||||
|
lv_obj_t* lv_obj = obj_getPtr(self, "lv_obj");
|
||||||
|
lv_arc_set_bg_angles(lv_obj, start, end);
|
||||||
|
}
|
||||||
|
void pika_lvgl_arc_set_angles(PikaObj *self, int start, int end){
|
||||||
|
lv_obj_t* lv_obj = obj_getPtr(self, "lv_obj");
|
||||||
|
lv_arc_set_angles(lv_obj, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
::
|
|
||||||
|
To use the module, just ``import pika_lvgl`` and the precompiler will automatically scan main.py and bind the
|
||||||
|
``pika_lvgl`` module
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
$ ./rust-msc-latest-win10.exe
|
$ ./rust-msc-latest-win10.exe
|
||||||
(pikascript) packages installed:
|
(pikascript) packages installed:
|
||||||
@@ -187,17 +182,17 @@ automatically scan main.py and bind the ``pika_lvgl`` module
|
|||||||
scanning main.py...
|
scanning main.py...
|
||||||
binding pika_lvgl.pyi...
|
binding pika_lvgl.pyi...
|
||||||
|
|
||||||
The precompiler is written in Rust, runs on windows and linux, and is
|
|
||||||
completely open source.
|
|
||||||
|
|
||||||
In addition to binding C modules, the precompiler compiles Python
|
The precompiler is written in Rust, runs on windows and linux, and is completely open source.
|
||||||
scripts to bytecode in the PC, reducing the size of the script and
|
|
||||||
increasing its speed.
|
In addition to binding C modules, the precompiler compiles Python scripts to bytecode in the PC, reducing the
|
||||||
|
size of the script and increasing its speed.
|
||||||
|
|
||||||
|
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
|
||||||
How can I use it?
|
How can I use it?
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
The simulation repo on vs is available on
|
The simulation repo on vs is available on https://github.com/pikasTech/lv_pikascript
|
||||||
https://github.com/pikasTech/lv_pikascript
|
|
||||||
|
|||||||
@@ -4,18 +4,23 @@
|
|||||||
cmake
|
cmake
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
|
||||||
Overview
|
Overview
|
||||||
********
|
********
|
||||||
This project uses CMakePresets to ensure an easy build. Find out more on Cmake Presets here:
|
|
||||||
https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html
|
This project uses CMakePresets to ensure an easy build.
|
||||||
|
Find out more on Cmake Presets here: https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html
|
||||||
|
|
||||||
|
|
||||||
Prerequisites
|
Prerequisites
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
You need to install
|
You need to install
|
||||||
|
|
||||||
- CMake
|
- CMake
|
||||||
- Ninja (for Linux builds). Be sure to Add ninja to your PATH!
|
- Ninja (for Linux builds). Be sure to Add ninja to your PATH!
|
||||||
|
|
||||||
|
|
||||||
How to build this project using cmake
|
How to build this project using cmake
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
@@ -24,8 +29,10 @@ The recommended way to build this project is to use the provided CMakePresets.js
|
|||||||
- a windows (msvc) build using Visual Studio
|
- a windows (msvc) build using Visual Studio
|
||||||
- a linux (gcc) build using Ninja
|
- a linux (gcc) build using Ninja
|
||||||
|
|
||||||
|
|
||||||
More configurations will be added once available.
|
More configurations will be added once available.
|
||||||
|
|
||||||
|
|
||||||
Build with IDE
|
Build with IDE
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
@@ -35,13 +42,15 @@ The recommend way for consuming CMakePresets is a CMakePresets aware IDE such as
|
|||||||
- VS Code
|
- VS Code
|
||||||
- CLion
|
- CLion
|
||||||
|
|
||||||
|
|
||||||
Simply load this project into your IDE and select your desired preset and you are good to go.
|
Simply load this project into your IDE and select your desired preset and you are good to go.
|
||||||
|
|
||||||
|
|
||||||
Build with CMake GUI
|
Build with CMake GUI
|
||||||
--------------------
|
--------------------
|
||||||
Open this project with CMake GUI and select your desired preset.
|
|
||||||
When hitting the generate button, CMake will create solution files (for VS) or Ninja Files (for Linux Ninja Build)
|
Open this project with CMake GUI and select your desired preset. When hitting the generate button,
|
||||||
|
CMake will create solution files (for VS) or Ninja Files (for Linux Ninja Build)
|
||||||
|
|
||||||
The following targets are available.
|
The following targets are available.
|
||||||
|
|
||||||
@@ -50,6 +59,7 @@ The following targets are available.
|
|||||||
- lvgl_examples (example usages, optional)
|
- lvgl_examples (example usages, optional)
|
||||||
- lvgl_demos (some demos, optional)
|
- lvgl_demos (some demos, optional)
|
||||||
|
|
||||||
|
|
||||||
All optional targets can be disabled by setting the proper cache variables.
|
All optional targets can be disabled by setting the proper cache variables.
|
||||||
If you use cmake to install lvgl 3 folders will be created.
|
If you use cmake to install lvgl 3 folders will be created.
|
||||||
|
|
||||||
@@ -61,11 +71,10 @@ If you use cmake to install lvgl 3 folders will be created.
|
|||||||
Build with Command line
|
Build with Command line
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
You can also build your project using the command line.
|
You can also build your project using the command line. Run the following commands
|
||||||
Run the following commands
|
|
||||||
|
|
||||||
- cmake --preset windows-base
|
- ``cmake --preset windows-base``
|
||||||
- cmake --build --preset windows-base_dbg
|
- ``cmake --build --preset windows-base_dbg``
|
||||||
- ctest --preset windows-base_dbg
|
- ``ctest --preset windows-base_dbg``
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ If you are new to ESP-IDF, follow the instructions in the `ESP-IDF Programming g
|
|||||||
|
|
||||||
|
|
||||||
LVGL Demo Projects for ESP32
|
LVGL Demo Projects for ESP32
|
||||||
---------------------------
|
----------------------------
|
||||||
|
|
||||||
For a quick start with LVGL and ESP32, the following pre-configured demo projects are available for specific development boards:
|
For a quick start with LVGL and ESP32, the following pre-configured demo projects are available for specific development boards:
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ Obtaining LVGL
|
|||||||
LVGL is distributed through `ESP Registry <https://components.espressif.com/>`__, where all LVGL releases are uploaded.
|
LVGL is distributed through `ESP Registry <https://components.espressif.com/>`__, where all LVGL releases are uploaded.
|
||||||
In case you do not want to use esp_lvgl_port, you can add `LVGL component <https://components.espressif.com/component/lvgl/lvgl>`__ into your project with following command:
|
In case you do not want to use esp_lvgl_port, you can add `LVGL component <https://components.espressif.com/component/lvgl/lvgl>`__ into your project with following command:
|
||||||
|
|
||||||
.. code:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
idf.py add-dependency lvgl/lvgl^9.*
|
idf.py add-dependency lvgl/lvgl^9.*
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ Adjust the ``^9.*`` part to match your LVGL version requirement. More informatio
|
|||||||
|
|
||||||
For LVGL development and testing, it may be useful to use LVGL as a local component instead of from the ESP Registry, which offers only released versions and does not allow local modifications. To do this, clone LVGL to your project with the following command:
|
For LVGL development and testing, it may be useful to use LVGL as a local component instead of from the ESP Registry, which offers only released versions and does not allow local modifications. To do this, clone LVGL to your project with the following command:
|
||||||
|
|
||||||
.. code:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
git submodule add https://github.com/lvgl/lvgl.git components/lvgl
|
git submodule add https://github.com/lvgl/lvgl.git components/lvgl
|
||||||
|
|
||||||
@@ -77,7 +77,8 @@ These components share a common public API, making it easy to migrate your proje
|
|||||||
|
|
||||||
To add a display or touch driver to your project, use a command like:
|
To add a display or touch driver to your project, use a command like:
|
||||||
|
|
||||||
.. code:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
idf.py add-dependency "espressif/esp_lcd_gc9a01^2.0.0"
|
idf.py add-dependency "espressif/esp_lcd_gc9a01^2.0.0"
|
||||||
|
|
||||||
Using the File System under ESP-IDF
|
Using the File System under ESP-IDF
|
||||||
@@ -91,9 +92,9 @@ The process is described in details below, using ``SPIFFS`` as demonstration.
|
|||||||
|
|
||||||
ESP-IDF has many, ready-to-use examples like
|
ESP-IDF has many, ready-to-use examples like
|
||||||
`SPIFFS <https://github.com/espressif/esp-idf/tree/master/examples/storage/spiffsgen>`__
|
`SPIFFS <https://github.com/espressif/esp-idf/tree/master/examples/storage/spiffsgen>`__
|
||||||
,
|
,
|
||||||
`SD Card <https://github.com/espressif/esp-idf/tree/master/examples/storage/sd_card/sdspi>`__
|
`SD Card <https://github.com/espressif/esp-idf/tree/master/examples/storage/sd_card/sdspi>`__
|
||||||
and
|
and
|
||||||
`LittleFS <https://github.com/espressif/esp-idf/tree/master/examples/storage/littlefs>`__
|
`LittleFS <https://github.com/espressif/esp-idf/tree/master/examples/storage/littlefs>`__
|
||||||
.
|
.
|
||||||
|
|
||||||
@@ -141,7 +142,7 @@ The process is described in details below, using ``SPIFFS`` as demonstration.
|
|||||||
It supports various formats and compression.
|
It supports various formats and compression.
|
||||||
|
|
||||||
Meanwhile 3rd party libraries
|
Meanwhile 3rd party libraries
|
||||||
(like :ref:`LodePNG<lodepng>` and :ref:`Tiny JPEG<tjpgd>`)
|
(like :ref:`LodePNG<lodepng_rst>` and :ref:`Tiny JPEG<tjpgd>`)
|
||||||
allow using image files without conversion.
|
allow using image files without conversion.
|
||||||
|
|
||||||
After preparing the files, they should be moved to the target device:
|
After preparing the files, they should be moved to the target device:
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ Basic configuration:
|
|||||||
- Select NXP PXP engine in "lv_conf.h": Set :c:macro:`LV_USE_DRAW_PXP` to `1`.
|
- Select NXP PXP engine in "lv_conf.h": Set :c:macro:`LV_USE_DRAW_PXP` to `1`.
|
||||||
- Enable PXP asserts in "lv_conf.h": Set :c:macro: `LV_USE_PXP_ASSERT` to `1`.
|
- Enable PXP asserts in "lv_conf.h": Set :c:macro: `LV_USE_PXP_ASSERT` to `1`.
|
||||||
There are few PXP assertions that can stop the program execution in case the
|
There are few PXP assertions that can stop the program execution in case the
|
||||||
c:macro: `LV_ASSERT_HANDLER` is set to `while(1);` (Halt by default). Else,
|
c:macro:`LV_ASSERT_HANDLER` is set to `while(1);` (Halt by default). Else,
|
||||||
there will be logged just an error message via `LV_LOG_ERROR`.
|
there will be logged just an error message via `LV_LOG_ERROR`.
|
||||||
- If :c:macro:`SDK_OS_FREE_RTOS` symbol is defined, FreeRTOS implementation
|
- If :c:macro:`SDK_OS_FREE_RTOS` symbol is defined, FreeRTOS implementation
|
||||||
will be used, otherwise bare metal code will be included.
|
will be used, otherwise bare metal code will be included.
|
||||||
@@ -50,30 +50,31 @@ Basic initialization:
|
|||||||
PXP draw initialization is done automatically in :cpp:func:`lv_init()` once the
|
PXP draw initialization is done automatically in :cpp:func:`lv_init()` once the
|
||||||
PXP is enabled, no user code is required:
|
PXP is enabled, no user code is required:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#if LV_USE_DRAW_PXP
|
#if LV_USE_DRAW_PXP
|
||||||
lv_draw_pxp_init();
|
lv_draw_pxp_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
During PXP initialization, a new draw unit `lv_draw_pxp_unit_t` will be created
|
During PXP initialization, a new draw unit `lv_draw_pxp_unit_t` will be created
|
||||||
with the additional callbacks:
|
with the additional callbacks:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_draw_pxp_unit_t * draw_pxp_unit = lv_draw_create_unit(sizeof(lv_draw_pxp_unit_t));
|
lv_draw_pxp_unit_t * draw_pxp_unit = lv_draw_create_unit(sizeof(lv_draw_pxp_unit_t));
|
||||||
draw_pxp_unit->base_unit.evaluate_cb = _pxp_evaluate;
|
draw_pxp_unit->base_unit.evaluate_cb = _pxp_evaluate;
|
||||||
draw_pxp_unit->base_unit.dispatch_cb = _pxp_dispatch;
|
draw_pxp_unit->base_unit.dispatch_cb = _pxp_dispatch;
|
||||||
draw_pxp_unit->base_unit.delete_cb = _pxp_delete;
|
draw_pxp_unit->base_unit.delete_cb = _pxp_delete;
|
||||||
|
|
||||||
|
|
||||||
and an addition thread `_pxp_render_thread_cb()` will be spawned in order to
|
and an addition thread `_pxp_render_thread_cb()` will be spawned in order to
|
||||||
handle the supported draw tasks.
|
handle the supported draw tasks.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#if LV_USE_PXP_DRAW_THREAD
|
#if LV_USE_PXP_DRAW_THREAD
|
||||||
lv_thread_init(&draw_pxp_unit->thread, LV_THREAD_PRIO_HIGH, _pxp_render_thread_cb, 2 * 1024, draw_pxp_unit);
|
lv_thread_init(&draw_pxp_unit->thread, LV_THREAD_PRIO_HIGH, _pxp_render_thread_cb, 2 * 1024, draw_pxp_unit);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
If `LV_USE_PXP_DRAW_THREAD` is not defined, then no additional draw thread will be created
|
If `LV_USE_PXP_DRAW_THREAD` is not defined, then no additional draw thread will be created
|
||||||
and the PXP drawing task will get executed on the same LVGL main thread.
|
and the PXP drawing task will get executed on the same LVGL main thread.
|
||||||
@@ -90,6 +91,7 @@ unit for processing.
|
|||||||
|
|
||||||
`_pxp_delete()` will cleanup the PXP draw unit.
|
`_pxp_delete()` will cleanup the PXP draw unit.
|
||||||
|
|
||||||
|
|
||||||
Features supported:
|
Features supported:
|
||||||
^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@@ -100,7 +102,7 @@ power savings.
|
|||||||
|
|
||||||
Supported draw tasks are available in "src/draw/nxp/pxp/lv_draw_pxp.c":
|
Supported draw tasks are available in "src/draw/nxp/pxp/lv_draw_pxp.c":
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
switch(t->type) {
|
switch(t->type) {
|
||||||
case LV_DRAW_TASK_TYPE_FILL:
|
case LV_DRAW_TASK_TYPE_FILL:
|
||||||
@@ -118,7 +120,7 @@ Supported draw tasks are available in "src/draw/nxp/pxp/lv_draw_pxp.c":
|
|||||||
|
|
||||||
Additional, the screen rotation can be handled by the PXP:
|
Additional, the screen rotation can be handled by the PXP:
|
||||||
|
|
||||||
.. code::c
|
.. code-block::c
|
||||||
|
|
||||||
void lv_draw_pxp_rotate(const void * src_buf, void * dest_buf, int32_t src_width, int32_t src_height,
|
void lv_draw_pxp_rotate(const void * src_buf, void * dest_buf, int32_t src_width, int32_t src_height,
|
||||||
int32_t src_stride, int32_t dest_stride, lv_display_rotation_t rotation,
|
int32_t src_stride, int32_t dest_stride, lv_display_rotation_t rotation,
|
||||||
@@ -132,6 +134,7 @@ Additional, the screen rotation can be handled by the PXP:
|
|||||||
- Blending layers (w/ same supported formats as blitting).
|
- Blending layers (w/ same supported formats as blitting).
|
||||||
- Rotate screen (90, 180, 270 degree).
|
- Rotate screen (90, 180, 270 degree).
|
||||||
|
|
||||||
|
|
||||||
Known limitations:
|
Known limitations:
|
||||||
^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@@ -159,7 +162,7 @@ Project setup:
|
|||||||
- "src/draw/nxp/pxp/lv_draw_buf_pxp.c": draw buffer callbacks
|
- "src/draw/nxp/pxp/lv_draw_buf_pxp.c": draw buffer callbacks
|
||||||
- "src/draw/nxp/pxp/lv_draw_pxp_fill.c": fill area
|
- "src/draw/nxp/pxp/lv_draw_pxp_fill.c": fill area
|
||||||
- "src/draw/nxp/pxp/lv_draw_pxp_img.c": blit image (w/ optional recolor or
|
- "src/draw/nxp/pxp/lv_draw_pxp_img.c": blit image (w/ optional recolor or
|
||||||
transformation)
|
transformation)
|
||||||
- "src/draw/nxp/pxp/lv_draw_pxp_layer.c": layer blending
|
- "src/draw/nxp/pxp/lv_draw_pxp_layer.c": layer blending
|
||||||
- "src/draw/nxp/pxp/lv_draw_pxp.c": draw unit initialization
|
- "src/draw/nxp/pxp/lv_draw_pxp.c": draw unit initialization
|
||||||
- "src/draw/nxp/pxp/lv_pxp_cfg.c": init, deinit, run/wait PXP device
|
- "src/draw/nxp/pxp/lv_pxp_cfg.c": init, deinit, run/wait PXP device
|
||||||
@@ -172,6 +175,7 @@ Project setup:
|
|||||||
- fsl_pxp.c: PXP driver
|
- fsl_pxp.c: PXP driver
|
||||||
- fsl_cache.c: CPU cache handling functions
|
- fsl_cache.c: CPU cache handling functions
|
||||||
|
|
||||||
|
|
||||||
PXP default configuration:
|
PXP default configuration:
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@@ -181,13 +185,14 @@ PXP default configuration:
|
|||||||
bare metal is provided in lv_pxp_osa.c.
|
bare metal is provided in lv_pxp_osa.c.
|
||||||
|
|
||||||
- :cpp:func:`pxp_interrupt_init()`: Initialize PXP interrupt (HW setup,
|
- :cpp:func:`pxp_interrupt_init()`: Initialize PXP interrupt (HW setup,
|
||||||
OS setup)
|
OS setup)
|
||||||
- :cpp:func:`pxp_interrupt_deinit()`: Deinitialize PXP interrupt (HW setup,
|
- :cpp:func:`pxp_interrupt_deinit()`: Deinitialize PXP interrupt (HW setup,
|
||||||
OS setup)
|
OS setup)
|
||||||
- :cpp:func:`pxp_run()`: Start PXP job. Use OS-specific mechanism to block
|
- :cpp:func:`pxp_run()`: Start PXP job. Use OS-specific mechanism to block
|
||||||
drawing thread.
|
drawing thread.
|
||||||
- :cpp:func:`pxp_wait()`: Wait for PXP completion.
|
- :cpp:func:`pxp_wait()`: Wait for PXP completion.
|
||||||
|
|
||||||
|
|
||||||
VGLite accelerator
|
VGLite accelerator
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@@ -196,6 +201,7 @@ CPU is available for other operations while the VGLite is running. An
|
|||||||
RTOS is required to block the LVGL drawing thread and switch to another
|
RTOS is required to block the LVGL drawing thread and switch to another
|
||||||
task or suspend the CPU for power savings.
|
task or suspend the CPU for power savings.
|
||||||
|
|
||||||
|
|
||||||
Basic configuration:
|
Basic configuration:
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@@ -216,14 +222,14 @@ Initialize VGLite GPU before calling :cpp:func:`lv_init()` by specifying the
|
|||||||
width/height of tessellation window. The default values for tesselation width
|
width/height of tessellation window. The default values for tesselation width
|
||||||
and height, and command buffer size are in the SDK file "vglite_support.h".
|
and height, and command buffer size are in the SDK file "vglite_support.h".
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#if LV_USE_DRAW_VGLITE
|
#if LV_USE_DRAW_VGLITE
|
||||||
#include "vg_lite.h"
|
#include "vg_lite.h"
|
||||||
#include "vglite_support.h"
|
#include "vglite_support.h"
|
||||||
#endif
|
#endif
|
||||||
...
|
...
|
||||||
#if LV_USE_DRAW_VGLITE
|
#if LV_USE_DRAW_VGLITE
|
||||||
if(vg_lite_init(DEFAULT_VG_LITE_TW_WIDTH, DEFAULT_VG_LITE_TW_HEIGHT) != VG_LITE_SUCCESS)
|
if(vg_lite_init(DEFAULT_VG_LITE_TW_WIDTH, DEFAULT_VG_LITE_TW_HEIGHT) != VG_LITE_SUCCESS)
|
||||||
{
|
{
|
||||||
PRINTF("VGLite init error. STOP.");
|
PRINTF("VGLite init error. STOP.");
|
||||||
@@ -239,21 +245,21 @@ and height, and command buffer size are in the SDK file "vglite_support.h".
|
|||||||
while (1)
|
while (1)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VGLite draw initialization is done automatically in :cpp:func:`lv_init()` once
|
VGLite draw initialization is done automatically in :cpp:func:`lv_init()` once
|
||||||
the VGLite is enabled, no user code is required:
|
the VGLite is enabled, no user code is required:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#if LV_USE_DRAW_VGLITE
|
#if LV_USE_DRAW_VGLITE
|
||||||
lv_draw_vglite_init();
|
lv_draw_vglite_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
During VGLite initialization, a new draw unit `lv_draw_vglite_unit_t` will be
|
During VGLite initialization, a new draw unit `lv_draw_vglite_unit_t` will be
|
||||||
created with the additional callbacks:
|
created with the additional callbacks:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_draw_vglite_unit_t * draw_vglite_unit = lv_draw_create_unit(sizeof(lv_draw_vglite_unit_t));
|
lv_draw_vglite_unit_t * draw_vglite_unit = lv_draw_create_unit(sizeof(lv_draw_vglite_unit_t));
|
||||||
draw_vglite_unit->base_unit.evaluate_cb = _vglite_evaluate;
|
draw_vglite_unit->base_unit.evaluate_cb = _vglite_evaluate;
|
||||||
@@ -263,11 +269,11 @@ created with the additional callbacks:
|
|||||||
and an addition thread `_vglite_render_thread_cb()` will be spawned in order to
|
and an addition thread `_vglite_render_thread_cb()` will be spawned in order to
|
||||||
handle the supported draw tasks.
|
handle the supported draw tasks.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#if LV_USE_VGLITE_DRAW_THREAD
|
#if LV_USE_VGLITE_DRAW_THREAD
|
||||||
lv_thread_init(&draw_vglite_unit->thread, LV_THREAD_PRIO_HIGH, _vglite_render_thread_cb, 2 * 1024, draw_vglite_unit);
|
lv_thread_init(&draw_vglite_unit->thread, LV_THREAD_PRIO_HIGH, _vglite_render_thread_cb, 2 * 1024, draw_vglite_unit);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
If `LV_USE_VGLITE_DRAW_THREAD` is not defined, then no additional draw thread will be created
|
If `LV_USE_VGLITE_DRAW_THREAD` is not defined, then no additional draw thread will be created
|
||||||
and the VGLite drawing task will get executed on the same LVGL main thread.
|
and the VGLite drawing task will get executed on the same LVGL main thread.
|
||||||
@@ -284,6 +290,7 @@ VGLite draw unit for processing.
|
|||||||
|
|
||||||
`_vglite_delete()` will cleanup the VGLite draw unit.
|
`_vglite_delete()` will cleanup the VGLite draw unit.
|
||||||
|
|
||||||
|
|
||||||
Advanced configuration:
|
Advanced configuration:
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@@ -292,9 +299,9 @@ Advanced configuration:
|
|||||||
Enabling the blit split workaround will mitigate any quality degradation issue
|
Enabling the blit split workaround will mitigate any quality degradation issue
|
||||||
on screen's dimension > 352 pixels.
|
on screen's dimension > 352 pixels.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define VGLITE_BLIT_SPLIT_THR 352
|
#define VGLITE_BLIT_SPLIT_THR 352
|
||||||
|
|
||||||
- By default, the blit split threshold is set to 352. Blits with width or height
|
- By default, the blit split threshold is set to 352. Blits with width or height
|
||||||
higher than this value will be done in multiple steps. Value must be multiple
|
higher than this value will be done in multiple steps. Value must be multiple
|
||||||
@@ -320,7 +327,7 @@ power savings.
|
|||||||
|
|
||||||
Supported draw tasks are available in "src/draw/nxp/pxp/lv_draw_vglite.c":
|
Supported draw tasks are available in "src/draw/nxp/pxp/lv_draw_vglite.c":
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
switch(t->type) {
|
switch(t->type) {
|
||||||
case LV_DRAW_TASK_TYPE_LABEL:
|
case LV_DRAW_TASK_TYPE_LABEL:
|
||||||
@@ -351,19 +358,22 @@ Supported draw tasks are available in "src/draw/nxp/pxp/lv_draw_vglite.c":
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
All the below operation can be done in addition with optional opacity.
|
All the below operation can be done in addition with optional opacity.
|
||||||
|
|
||||||
- Fill area with color (w/ radius or gradient).
|
- Fill area with color (w/ radius or gradient).
|
||||||
- Blit source image (any format from `_vglite_src_cf_supported()`) over
|
- Blit source image (any format from ``_vglite_src_cf_supported()``) over
|
||||||
destination (any format from `_vglite_dest_cf_supported()`).
|
destination (any format from ``_vglite_dest_cf_supported()``).
|
||||||
- Recolor source image.
|
- Recolor source image.
|
||||||
- Scale and rotate (any decimal degree) source image.
|
- Scale and rotate (any decimal degree) source image.
|
||||||
- Blending layers (w/ same supported formats as blitting).
|
- Blending layers (w/ same supported formats as blitting).
|
||||||
- Draw letters (blit bitmap letters - raster font).
|
- Draw letters (blit bitmap letters / raster font).
|
||||||
- Draw full borders (LV_BORDER_SIDE_FULL).
|
- Draw full borders (LV_BORDER_SIDE_FULL).
|
||||||
- Draw arcs (w/ rounded edges).
|
- Draw arcs (w/ rounded edges).
|
||||||
- Draw lines (w/ dash or rounded edges).
|
- Draw lines (w/ dash or rounded edges).
|
||||||
- Draw triangles with color (w/ gradient).
|
- Draw triangles with color (w/ gradient).
|
||||||
|
|
||||||
|
|
||||||
Known limitations:
|
Known limitations:
|
||||||
^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@@ -375,6 +385,7 @@ Known limitations:
|
|||||||
tiled (4x4) buffer layouts. The pixel engine has no additional alignment
|
tiled (4x4) buffer layouts. The pixel engine has no additional alignment
|
||||||
requirement for linear buffer layouts (:c:macro:`VG_LITE_LINEAR`).
|
requirement for linear buffer layouts (:c:macro:`VG_LITE_LINEAR`).
|
||||||
|
|
||||||
|
|
||||||
Project setup:
|
Project setup:
|
||||||
^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@@ -385,8 +396,7 @@ Project setup:
|
|||||||
- "src/draw/nxp/vglite/lv_draw_vglite_arc.c": draw arc
|
- "src/draw/nxp/vglite/lv_draw_vglite_arc.c": draw arc
|
||||||
- "src/draw/nxp/vglite/lv_draw_vglite_border.c": draw border
|
- "src/draw/nxp/vglite/lv_draw_vglite_border.c": draw border
|
||||||
- "src/draw/nxp/vglite/lv_draw_vglite_fill.c": fill area
|
- "src/draw/nxp/vglite/lv_draw_vglite_fill.c": fill area
|
||||||
- "src/draw/nxp/vglite/lv_draw_vglite_img.c": blit image (w/ optional
|
- "src/draw/nxp/vglite/lv_draw_vglite_img.c": blit image (w/ optional recolor or transformation)
|
||||||
recolor or transformation)
|
|
||||||
- "src/draw/nxp/vglite/lv_draw_vglite_label.c": draw label
|
- "src/draw/nxp/vglite/lv_draw_vglite_label.c": draw label
|
||||||
- "src/draw/nxp/vglite/lv_draw_vglite_layer.c": layer blending
|
- "src/draw/nxp/vglite/lv_draw_vglite_layer.c": layer blending
|
||||||
- "src/draw/nxp/vglite/lv_draw_vglite_line.c": draw line
|
- "src/draw/nxp/vglite/lv_draw_vglite_line.c": draw line
|
||||||
|
|||||||
@@ -4,9 +4,10 @@
|
|||||||
Renesas
|
Renesas
|
||||||
=======
|
=======
|
||||||
|
|
||||||
`Renesas <https://renesas.com/>`__ is an official partner of LVGL.
|
`Renesas <https://renesas.com/>`__ is an official partner of LVGL. Therefore, LVGL contains built-in support for
|
||||||
Therefore, LVGL contains built-in support for `Dave2D <https://www.renesas.com/document/mas/tes-dave2d-driver-documentation>`__ (the GPU of Renesas)
|
`Dave2D <https://www.renesas.com/document/mas/tes-dave2d-driver-documentation>`__ (the GPU of Renesas) and we also maintain
|
||||||
and we also maintain ready-to-use Renesas projects.
|
ready-to-use Renesas projects.
|
||||||
|
|
||||||
|
|
||||||
Dave2D
|
Dave2D
|
||||||
------
|
------
|
||||||
@@ -19,16 +20,20 @@ Dave2D is capable of accelerating most of the drawing operations of LVGL:
|
|||||||
- Triangle drawing
|
- Triangle drawing
|
||||||
- Line drawing
|
- Line drawing
|
||||||
|
|
||||||
As Dave2D works in the background, the CPU is free for other tasks. In practice, during rendering, Dave2D can reduce the CPU usage by half or to one-third, depending on the application.
|
|
||||||
|
As Dave2D works in the background, the CPU is free for other tasks. In practice, during rendering, Dave2D can reduce the CPU usage by
|
||||||
|
half or to one-third, depending on the application.
|
||||||
|
|
||||||
|
|
||||||
GLCDC
|
GLCDC
|
||||||
-----
|
-----
|
||||||
|
|
||||||
GLCDC is a multi-stage graphics output peripheral available in several Renesas MCUs.
|
GLCDC is a multi-stage graphics output peripheral available in several Renesas MCUs. It is able to drive LCD panels via a highly
|
||||||
It is able to drive LCD panels via a highly configurable RGB interface.
|
configurable RGB interface.
|
||||||
|
|
||||||
More info can be found at the :ref:`driver's page<renesas_glcdc>`.
|
More info can be found at the :ref:`driver's page<renesas_glcdc>`.
|
||||||
|
|
||||||
|
|
||||||
Supported boards
|
Supported boards
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
@@ -84,6 +89,7 @@ Supported boards
|
|||||||
- `Demo repository for EK-RA6M3G <https://github.com/lvgl/lv_port_renesas_ek-ra6m3g>`__
|
- `Demo repository for EK-RA6M3G <https://github.com/lvgl/lv_port_renesas_ek-ra6m3g>`__
|
||||||
- `Demo repository for RX72N Envision Kit <https://github.com/lvgl/lv_port_renesas_rx72n-envision-kit>`__
|
- `Demo repository for RX72N Envision Kit <https://github.com/lvgl/lv_port_renesas_rx72n-envision-kit>`__
|
||||||
|
|
||||||
|
|
||||||
Get started with the Renesas ecosystem
|
Get started with the Renesas ecosystem
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
@@ -92,24 +98,20 @@ Get started with the Renesas ecosystem
|
|||||||
|
|
||||||
.. dropdown:: RA Family
|
.. dropdown:: RA Family
|
||||||
|
|
||||||
- The official IDE of Renesas is called e² studio. As it's Eclipse-based, it runs on Windows, Linux, and Mac as well. The RA family requires the latest version with FSP 5.3. It can be downloaded `here <https://www.renesas.com/us/en/software-tool/flexible-software-package-fsp>`__.
|
- The official IDE of Renesas is called e² studio. As it's Eclipse-based, it runs on Windows, Linux, and Mac as well.
|
||||||
|
The RA family requires the latest version with FSP 5.3. It can be downloaded `here <https://www.renesas.com/us/en/software-tool/flexible-software-package-fsp>`__.
|
||||||
|
- JLink is used for debugging, it can be downloaded `here <https://www.segger.com/downloads/jlink/>`__.
|
||||||
|
- Clone the ready-to-use repository for your selected board:
|
||||||
|
|
||||||
- JLink is used for debugging, it can be downloaded `here <https://www.segger.com/downloads/jlink/>`__.
|
.. code-block:: shell
|
||||||
|
|
||||||
|
git clone https://github.com/lvgl/lv_port_renesas_ek-ra8d1.git --recurse-submodules
|
||||||
|
|
||||||
|
|
||||||
- Clone the ready-to-use repository for your selected board:
|
Downloading the `.zip` from GitHub doesn't work as it doesn't download the submodules.
|
||||||
|
- Open e² studio, go to ``File`` -> ``Import project`` and select ``General`` / ``Existing projects into workspace``
|
||||||
.. code-block:: shell
|
- Browse the cloned folder and press ``Finish``.
|
||||||
|
- Double click on ``configuration.xml``. This will activate the `Configuration Window`.
|
||||||
git clone https://github.com/lvgl/lv_port_renesas_ek-ra8d1.git --recurse-submodules
|
|
||||||
|
|
||||||
Downloading the `.zip` from GitHub doesn't work as it doesn't download the submodules.
|
|
||||||
|
|
||||||
- Open e² studio, go to ``File`` -> ``Import project`` and select ``General`` / ``Existing projects into workspace``
|
|
||||||
|
|
||||||
- Browse the cloned folder and press ``Finish``.
|
|
||||||
|
|
||||||
- Double click on ``configuration.xml``. This will activate the `Configuration Window`.
|
|
||||||
|
|
||||||
Renesas' Flexible Software Package (FSP) incudes BSP and HAL layer support extended with multiple RTOS variants and other middleware stacks.
|
Renesas' Flexible Software Package (FSP) incudes BSP and HAL layer support extended with multiple RTOS variants and other middleware stacks.
|
||||||
The components will be available via code generation, including the entry point of *"main.c"*.
|
The components will be available via code generation, including the entry point of *"main.c"*.
|
||||||
@@ -119,18 +121,17 @@ Get started with the Renesas ecosystem
|
|||||||
.. image:: /misc/renesas/generate.png
|
.. image:: /misc/renesas/generate.png
|
||||||
:alt: Code generation with FSP
|
:alt: Code generation with FSP
|
||||||
|
|
||||||
- Build the project by pressing ``Ctrl`` + ``Alt`` + ``B``
|
- Build the project by pressing ``Ctrl`` + ``Alt`` + ``B``
|
||||||
|
- Click the Debug button (|img_debug_btn|). If prompted with `Debug Configurations`, on the `Debugger` tab select the ``J-Link ARM`` as `Debug hardware` and the proper IC as `Target Device`:
|
||||||
- Click the Debug button (|img_debug_btn|). If prompted with `Debug Configurations`, on the `Debugger` tab select the ``J-Link ARM`` as `Debug hardware` and the proper IC as `Target Device`:
|
|
||||||
|
|
||||||
- ``R7FA8D1BH`` for EK-RA8D1
|
- ``R7FA8D1BH`` for EK-RA8D1
|
||||||
|
|
||||||
.. image:: /misc/renesas/debug_ra8.png
|
.. image:: /misc/renesas/debug_ra8.png
|
||||||
:alt: Debugger parameters for RA8
|
:alt: Debugger parameters for RA8
|
||||||
|
|
||||||
- ``R7FA6M3AH`` for EK-RA6M3G
|
- ``R7FA6M3AH`` for EK-RA6M3G
|
||||||
|
|
||||||
.. image:: /misc/renesas/debug_ra6.png
|
.. image:: /misc/renesas/debug_ra6.png
|
||||||
:alt: Debugger parameters for RA6
|
:alt: Debugger parameters for RA6
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
@@ -138,14 +139,16 @@ Get started with the Renesas ecosystem
|
|||||||
|
|
||||||
.. dropdown:: RX Family
|
.. dropdown:: RX Family
|
||||||
|
|
||||||
- The official IDE of Renesas is called e² studio. As it's Eclipse-based, it runs on Windows, Linux, and Mac as well. It can be downloaded `here <https://www.renesas.com/us/en/software-tool/e-studio>`__.
|
- The official IDE of Renesas is called e² studio. As it's Eclipse-based, it runs on Windows, Linux, and Mac as well.
|
||||||
|
It can be downloaded `here <https://www.renesas.com/us/en/software-tool/e-studio>`__.
|
||||||
|
- Download and install the required driver for the debugger
|
||||||
|
|
||||||
- Download and install the required driver for the debugger
|
- for Windows: `64 bit here <https://www.renesas.com/us/en/document/uid/usb-driver-renesas-mcu-tools-v27700-64-bit-version-windows-os?r=488806>`__
|
||||||
|
and `32 bit here <https://www.renesas.com/us/en/document/uid/usb-driver-renesas-mcu-toolse2e2-liteie850ie850apg-fp5-v27700for-32-bit-version-windows-os?r=488806>`__
|
||||||
- for Windows: `64 bit here <https://www.renesas.com/us/en/document/uid/usb-driver-renesas-mcu-tools-v27700-64-bit-version-windows-os?r=488806>`__ and `32 bit here <https://www.renesas.com/us/en/document/uid/usb-driver-renesas-mcu-toolse2e2-liteie850ie850apg-fp5-v27700for-32-bit-version-windows-os?r=488806>`__
|
|
||||||
- for Linux: `here <https://www.renesas.com/us/en/document/swo/e2-emulator-e2-emulator-lite-linux-driver?r=488806>`__
|
- for Linux: `here <https://www.renesas.com/us/en/document/swo/e2-emulator-e2-emulator-lite-linux-driver?r=488806>`__
|
||||||
|
|
||||||
- RX72 requires an external compiler for the RXv3 core. A free and open-source version is available `here <https://llvm-gcc-renesas.com/rx-download-toolchains/>`__ after a registration.
|
- RX72 requires an external compiler for the RXv3 core. A free and open-source version is available
|
||||||
|
`here <https://llvm-gcc-renesas.com/rx-download-toolchains/>`__ after a registration.
|
||||||
|
|
||||||
The compiler must be activated in e² studio:
|
The compiler must be activated in e² studio:
|
||||||
|
|
||||||
@@ -153,24 +156,23 @@ Get started with the Renesas ecosystem
|
|||||||
- Press the ``Add...`` button
|
- Press the ``Add...`` button
|
||||||
- Browse the installation folder of the toolchain
|
- Browse the installation folder of the toolchain
|
||||||
|
|
||||||
|
|
<br/>
|
||||||
|
|
||||||
.. image:: /misc/renesas/toolchains.png
|
.. image:: /misc/renesas/toolchains.png
|
||||||
:alt: Toolchains
|
:alt: Toolchains
|
||||||
|
|
||||||
- Clone the ready-to-use `lv_port_renesas_rx72n-envision-kit <https://github.com/lvgl/lv_port_renesas_rx72n-envision-kit.git>`__ repository:
|
- Clone the ready-to-use `lv_port_renesas_rx72n-envision-kit <https://github.com/lvgl/lv_port_renesas_rx72n-envision-kit.git>`__ repository:
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
git clone https://github.com/lvgl/lv_port_renesas_rx72n-envision-kit.git --recurse-submodules
|
git clone https://github.com/lvgl/lv_port_renesas_rx72n-envision-kit.git --recurse-submodules
|
||||||
|
|
||||||
|
|
||||||
Downloading the `.zip` from GitHub doesn't work as it doesn't download the submodules.
|
Downloading the `.zip` from GitHub doesn't work as it doesn't download the submodules.
|
||||||
|
|
||||||
- Open e² studio, go to ``File`` -> ``Import project`` and select ``General`` / ``Existing projects into workspace``
|
- Open e² studio, go to ``File`` -> ``Import project`` and select ``General`` / ``Existing projects into workspace``
|
||||||
|
- Select the cloned folder and press ``Finish``.
|
||||||
- Select the cloned folder and press ``Finish``.
|
- Double click on ``RX72N_EnVision_LVGL.scfg``. This will activate the `Configuration Window`.
|
||||||
|
|
||||||
- Double click on ``RX72N_EnVision_LVGL.scfg``. This will activate the `Configuration Window`.
|
|
||||||
|
|
||||||
Renesas' Smart Configurator (SMC) incudes BSP and HAL layer support extended with multiple RTOS variants and other middleware stacks.
|
Renesas' Smart Configurator (SMC) incudes BSP and HAL layer support extended with multiple RTOS variants and other middleware stacks.
|
||||||
The components will be available via code generation, including the entry point of the application.
|
The components will be available via code generation, including the entry point of the application.
|
||||||
@@ -180,19 +182,21 @@ Get started with the Renesas ecosystem
|
|||||||
.. image:: /misc/renesas/generate_smc.png
|
.. image:: /misc/renesas/generate_smc.png
|
||||||
:alt: Code generation with SMC
|
:alt: Code generation with SMC
|
||||||
|
|
||||||
- Build the project by pressing ``Ctrl`` + ``Alt`` + ``B``
|
- Build the project by pressing ``Ctrl`` + ``Alt`` + ``B``
|
||||||
|
- Click the Debug button (|img_debug_btn|). If prompted with `Debug Configurations`, on the `Debugger` tab select the ``E2 Lite``
|
||||||
- Click the Debug button (|img_debug_btn|). If prompted with `Debug Configurations`, on the `Debugger` tab select the ``E2 Lite`` as `Debug hardware` and ``R5F572NN`` as `Target Device`:
|
as `Debug hardware` and ``R5F572NN`` as `Target Device`:
|
||||||
|
|
||||||
.. image:: /misc/renesas/debug_rx72.png
|
.. image:: /misc/renesas/debug_rx72.png
|
||||||
:alt: Debugger parameters for RX72
|
:alt: Debugger parameters for RX72
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Make sure that both channels of ``SW1`` DIP switch (next to ``ECN1``) are OFF.
|
Make sure that both channels of ``SW1`` DIP switch (next to ``ECN1``) are OFF.
|
||||||
|
|
||||||
|
|
||||||
Modify the project
|
Modify the project
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
|
||||||
Open a demo
|
Open a demo
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|
||||||
@@ -200,14 +204,15 @@ The entry point of the main task is contained in ``src/LVGL_thread_entry.c`` in
|
|||||||
|
|
||||||
You can disable the LVGL demos (or just comment them out) and call some ``lv_example_...()`` functions, or add your custom code.
|
You can disable the LVGL demos (or just comment them out) and call some ``lv_example_...()`` functions, or add your custom code.
|
||||||
|
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
``src/lv_conf.h`` contains the most important settings for LVGL. Namely:
|
``src/lv_conf.h`` contains the most important settings for LVGL. Namely:
|
||||||
|
|
||||||
- ``LV_COLOR_DEPTH`` to set LVGL's default color depth
|
- :c:macro:`LV_COLOR_DEPTH` to set LVGL's default color depth
|
||||||
- ``LV_MEM_SIZE to`` set the maximum RAM available for LVGL
|
- :c:macro:`LV_MEM_SIZE` to set the maximum RAM available for LVGL
|
||||||
- ``LV_USE_DAVE2D`` to enable the GPU
|
- :c:macro:`LV_USE_DAVE2D` to enable the GPU
|
||||||
|
|
||||||
|
|
||||||
Hardware and software components can be modified in a visual way using the `Configuration Window`.
|
Hardware and software components can be modified in a visual way using the `Configuration Window`.
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ STM32
|
|||||||
LVGL Can be added to `STM32CubeIDE <https://www.st.com/en/development-tools/stm32cubeide.html>`__
|
LVGL Can be added to `STM32CubeIDE <https://www.st.com/en/development-tools/stm32cubeide.html>`__
|
||||||
in a similar fashion to any other Eclipse-based IDE.
|
in a similar fashion to any other Eclipse-based IDE.
|
||||||
|
|
||||||
|
|
||||||
Including LVGL in a Project
|
Including LVGL in a Project
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
@@ -19,9 +20,10 @@ Including LVGL in a Project
|
|||||||
ensuring that the LVGL directory is listed.
|
ensuring that the LVGL directory is listed.
|
||||||
|
|
||||||
Now that the source files are included in your project, follow the
|
Now that the source files are included in your project, follow the
|
||||||
instructions for `Porting <https://docs.lvgl.io/master/porting/project.html>`__ your
|
instructions for `Porting <https://docs.lvgl.io/master/porting/project.html>`_ your
|
||||||
project to create the ``lv_conf.h`` file, and initialise the display.
|
project to create the ``lv_conf.h`` file, and initialise the display.
|
||||||
|
|
||||||
|
|
||||||
Bare Metal Example
|
Bare Metal Example
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
@@ -32,159 +34,162 @@ set to **SysTick**. \* Configure any other peripherals (including the
|
|||||||
LCD panel), and initialise them in *main.c*. \* ``#include "lvgl.h"`` in
|
LCD panel), and initialise them in *main.c*. \* ``#include "lvgl.h"`` in
|
||||||
the *main.c* file. \* Create some frame buffer(s) as global variables:
|
the *main.c* file. \* Create some frame buffer(s) as global variables:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
//Frame buffers
|
/* Frame buffers
|
||||||
/*Static or global buffer(s). The second buffer is optional*/
|
* Static or global buffer(s). The second buffer is optional
|
||||||
//TODO: Adjust color format and choose buffer size. DISPLAY_WIDTH * 10 is one suggestion.
|
* TODO: Adjust color format and choose buffer size. DISPLAY_WIDTH * 10 is one suggestion. */
|
||||||
#define BYTE_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_RGB565)) /*will be 2 for RGB565 */
|
#define BYTE_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_RGB565)) /*will be 2 for RGB565 */
|
||||||
#define BUFF_SIZE (DISPLAY_WIDTH * 10 * BYTE_PER_PIXEL)
|
#define BUFF_SIZE (DISPLAY_WIDTH * 10 * BYTE_PER_PIXEL)
|
||||||
static uint8_t buf_1[BUFF_SIZE];
|
static uint8_t buf_1[BUFF_SIZE];
|
||||||
static uint8_t buf_2[BUFF_SIZE];
|
static uint8_t buf_2[BUFF_SIZE];
|
||||||
|
|
||||||
- In your ``main()`` function, after initialising your CPU,
|
- In your ``main()`` function, after initialising your CPU,
|
||||||
peripherals, and LCD panel, call :cpp:func:`lv_init` to initialise LVGL.
|
peripherals, and LCD panel, call :cpp:func:`lv_init` to initialise LVGL.
|
||||||
You can then create the display driver using
|
You can then create the display driver using
|
||||||
:cpp:func:`lv_display_create`, and register the frame buffers using
|
:cpp:func:`lv_display_create`, and register the frame buffers using
|
||||||
:cpp:func:`lv_display_set_buffers`.
|
:cpp:func:`lv_display_set_buffers`.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
//Initialise LVGL UI library
|
//Initialise LVGL UI library
|
||||||
lv_init();
|
lv_init();
|
||||||
|
|
||||||
lv_display_t * disp = lv_display_create(WIDTH, HEIGHT); /*Basic initialization with horizontal and vertical resolution in pixels*/
|
lv_display_t * disp = lv_display_create(WIDTH, HEIGHT); /*Basic initialization with horizontal and vertical resolution in pixels*/
|
||||||
lv_display_set_flush_cb(disp, my_flush_cb); /*Set a flush callback to draw to the display*/
|
lv_display_set_flush_cb(disp, my_flush_cb); /*Set a flush callback to draw to the display*/
|
||||||
lv_display_set_buffers(disp, buf_1, buf_2, sizeof(buf_1), LV_DISPLAY_RENDER_MODE_PARTIAL); /*Set an initialized buffer*/
|
lv_display_set_buffers(disp, buf_1, buf_2, sizeof(buf_1), LV_DISPLAY_RENDER_MODE_PARTIAL); /*Set an initialized buffer*/
|
||||||
|
|
||||||
- Create some dummy objects to test the output:
|
- Create some dummy objects to test the output:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
// Change the active screen's background color
|
/* Change the active screen's background color */
|
||||||
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x003a57), LV_PART_MAIN);
|
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x003a57), LV_PART_MAIN);
|
||||||
lv_obj_set_style_text_color(lv_screen_active(), lv_color_hex(0xffffff), LV_PART_MAIN);
|
lv_obj_set_style_text_color(lv_screen_active(), lv_color_hex(0xffffff), LV_PART_MAIN);
|
||||||
|
|
||||||
|
/* Create a spinner */
|
||||||
|
lv_obj_t * spinner = lv_spinner_create(lv_screen_active(), 1000, 60);
|
||||||
|
lv_obj_set_size(spinner, 64, 64);
|
||||||
|
lv_obj_align(spinner, LV_ALIGN_BOTTOM_MID, 0, 0);
|
||||||
|
|
||||||
/*Create a spinner*/
|
|
||||||
lv_obj_t * spinner = lv_spinner_create(lv_screen_active(), 1000, 60);
|
|
||||||
lv_obj_set_size(spinner, 64, 64);
|
|
||||||
lv_obj_align(spinner, LV_ALIGN_BOTTOM_MID, 0, 0);
|
|
||||||
|
|
||||||
- Add a call to :cpp:func:`lv_timer_handler` inside your ``while(1)`` loop:
|
- Add a call to :cpp:func:`lv_timer_handler` inside your ``while(1)`` loop:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/* Infinite loop */
|
/* Infinite loop */
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
lv_timer_handler();
|
lv_timer_handler();
|
||||||
HAL_Delay(5);
|
HAL_Delay(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
- Add a call to :cpp:func:`lv_tick_inc` inside the :cpp:func:`SysTick_Handler`
|
|
||||||
function. Open the *stm32xxxx_it.c* file (the name will depend on
|
|
||||||
your specific MCU), and update the :cpp:func:`SysTick_Handler` function:
|
|
||||||
|
|
||||||
.. code:: c
|
- Add a call to :cpp:func:`lv_tick_inc` inside the :cpp:func:`SysTick_Handler` function. Open the *stm32xxxx_it.c*
|
||||||
|
file (the name will depend on your specific MCU), and update the :cpp:func:`SysTick_Handler` function:
|
||||||
|
|
||||||
void SysTick_Handler(void)
|
.. code-block:: c
|
||||||
{
|
|
||||||
/* USER CODE BEGIN SysTick_IRQn 0 */
|
|
||||||
|
|
||||||
HAL_SYSTICK_IRQHandler();
|
void SysTick_Handler(void)
|
||||||
lv_tick_inc(1);
|
{
|
||||||
#ifdef USE_RTOS_SYSTICK
|
/* USER CODE BEGIN SysTick_IRQn 0 */
|
||||||
osSystickHandler();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* USER CODE END SysTick_IRQn 0 */
|
HAL_SYSTICK_IRQHandler();
|
||||||
HAL_IncTick();
|
lv_tick_inc(1);
|
||||||
/* USER CODE BEGIN SysTick_IRQn 1 */
|
#ifdef USE_RTOS_SYSTICK
|
||||||
|
osSystickHandler();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* USER CODE END SysTick_IRQn 1 */
|
/* USER CODE END SysTick_IRQn 0 */
|
||||||
}
|
HAL_IncTick();
|
||||||
|
/* USER CODE BEGIN SysTick_IRQn 1 */
|
||||||
|
|
||||||
- Finally, write the callback function, ``my_flush_cb``, which will
|
/* USER CODE END SysTick_IRQn 1 */
|
||||||
send the display buffer to your LCD panel. Below is one example, but
|
}
|
||||||
it will vary depending on your setup.
|
|
||||||
|
|
||||||
.. code:: c
|
|
||||||
|
|
||||||
void my_flush_cb(lv_display_t * disp, const lv_area_t * area, lv_color_t * color_p)
|
- Finally, write the callback function, ``my_flush_cb``, which will send the display buffer to your LCD panel. Below is
|
||||||
{
|
one example, but it will vary depending on your setup.
|
||||||
//Set the drawing region
|
|
||||||
set_draw_window(area->x1, area->y1, area->x2, area->y2);
|
|
||||||
|
|
||||||
int height = area->y2 - area->y1 + 1;
|
.. code-block:: c
|
||||||
int width = area->x2 - area->x1 + 1;
|
|
||||||
|
|
||||||
//We will do the SPI write manually here for speed
|
void my_flush_cb(lv_display_t * disp, const lv_area_t * area, lv_color_t * color_p)
|
||||||
HAL_GPIO_WritePin(DC_PORT, DC_PIN, GPIO_PIN_SET);
|
{
|
||||||
//CS low to begin data
|
//Set the drawing region
|
||||||
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET);
|
set_draw_window(area->x1, area->y1, area->x2, area->y2);
|
||||||
|
|
||||||
//Write colour to each pixel
|
int height = area->y2 - area->y1 + 1;
|
||||||
for (int i = 0; i < width * height; i++) {
|
int width = area->x2 - area->x1 + 1;
|
||||||
uint16_t color_full = (color_p->red << 11) | (color_p->green << 5) | (color_p->blue);
|
|
||||||
parallel_write(color_full);
|
|
||||||
|
|
||||||
color_p++;
|
//We will do the SPI write manually here for speed
|
||||||
}
|
HAL_GPIO_WritePin(DC_PORT, DC_PIN, GPIO_PIN_SET);
|
||||||
|
//CS low to begin data
|
||||||
|
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET);
|
||||||
|
|
||||||
//Return CS to high
|
//Write colour to each pixel
|
||||||
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET);
|
for (int i = 0; i < width * height; i++) {
|
||||||
|
uint16_t color_full = (color_p->red << 11) | (color_p->green << 5) | (color_p->blue);
|
||||||
|
parallel_write(color_full);
|
||||||
|
|
||||||
|
color_p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Return CS to high
|
||||||
|
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET);
|
||||||
|
|
||||||
|
/* IMPORTANT!!!
|
||||||
|
* Inform the graphics library that you are ready with the flushing*/
|
||||||
|
lv_display_flush_ready(disp);
|
||||||
|
}
|
||||||
|
|
||||||
/* IMPORTANT!!!
|
|
||||||
* Inform the graphics library that you are ready with the flushing*/
|
|
||||||
lv_display_flush_ready(disp);
|
|
||||||
}
|
|
||||||
|
|
||||||
FreeRTOS Example
|
FreeRTOS Example
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
A minimal example using STM32CubeIDE, HAL, and CMSISv1 (FreeRTOS). *Note
|
A minimal example using STM32CubeIDE, HAL, and CMSISv1 (FreeRTOS).
|
||||||
that we have not used Mutexes in this example, however LVGL is* **NOT**
|
*Note that we have not used Mutexes in this example, however LVGL is* **NOT**
|
||||||
*thread safe and so Mutexes should be used*. See: :ref:`os_interrupt`
|
*thread safe and so Mutexes should be used*. See: :ref:`os_interrupt`
|
||||||
\* ``#include "lvgl.h"`` \* Create your frame buffer(s) as global
|
\* ``#include "lvgl.h"`` \* Create your frame buffer(s) as global variables:
|
||||||
variables:
|
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
//Frame buffers
|
/* Frame buffers
|
||||||
/*Static or global buffer(s). The second buffer is optional*/
|
* Static or global buffer(s). The second buffer is optional */
|
||||||
#define BYTE_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_RGB565)) /*will be 2 for RGB565 */
|
#define BYTE_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_RGB565)) /* will be 2 for RGB565 */
|
||||||
//TODO: Declare your own BUFF_SIZE appropriate to your system.
|
/* TODO: Declare your own BUFF_SIZE appropriate to your system. */
|
||||||
#define BUFF_SIZE (DISPLAY_WIDTH * 10 * BYTE_PER_PIXEL)
|
static lv_color_t buf_1[BUFF_SIZE];
|
||||||
static uint8_t buf_1[BUFF_SIZE];
|
#define BUFF_SIZE (DISPLAY_WIDTH * 10 * BYTE_PER_PIXEL)
|
||||||
static uint8_t buf_2[BUFF_SIZE];
|
static uint8_t buf_1[BUFF_SIZE];
|
||||||
|
static lv_color_t buf_2[BUFF_SIZE];
|
||||||
|
|
||||||
- In your ``main`` function, after your peripherals (SPI, GPIOs, LCD
|
- In your ``main`` function, after your peripherals (SPI, GPIOs, LCD
|
||||||
etc) have been initialised, initialise LVGL using :cpp:func:`lv_init`,
|
etc) have been initialised, initialise LVGL using :cpp:func:`lv_init`,
|
||||||
create a new display driver using :cpp:func:`lv_display_create`, and
|
create a new display driver using :cpp:func:`lv_display_create`, and
|
||||||
register the frame buffers using :cpp:func:`lv_display_set_buffers`.
|
register the frame buffers using :cpp:func:`lv_display_set_buffers`.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
//Initialise LVGL UI library
|
/* Initialise LVGL UI library */
|
||||||
lv_init();
|
lv_init();
|
||||||
lv_display_t *display = lv_display_create(WIDTH, HEIGHT); /*Create the display*/
|
lv_display_t *display = lv_display_create(WIDTH, HEIGHT); /* Create the display */
|
||||||
lv_display_set_flush_cb(display, my_flush_cb); /*Set a flush callback to draw to the display*/
|
lv_display_set_flush_cb(display, my_flush_cb); /* Set a flush callback to draw to the display */
|
||||||
lv_display_set_buffers(disp, buf_1, buf_2, sizeof(buf_1), LV_DISPLAY_RENDER_MODE_PARTIAL); /*Set an initialized buffer*/
|
lv_display_set_buffers(disp, buf_1, buf_2, sizeof(buf_1), LV_DISPLAY_RENDER_MODE_PARTIAL); /* Set an initialized buffer */
|
||||||
|
|
||||||
|
/* Register the touch controller with LVGL - Not included here for brevity. */
|
||||||
|
|
||||||
// Register the touch controller with LVGL - Not included here for brevity.
|
|
||||||
|
|
||||||
- Create some dummy objects to test the output:
|
- Create some dummy objects to test the output:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
// Change the active screen's background color
|
/* Change the active screen's background color */
|
||||||
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x003a57), LV_PART_MAIN);
|
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x003a57), LV_PART_MAIN);
|
||||||
lv_obj_set_style_text_color(lv_screen_active(), lv_color_hex(0xffffff), LV_PART_MAIN);
|
lv_obj_set_style_text_color(lv_screen_active(), lv_color_hex(0xffffff), LV_PART_MAIN);
|
||||||
|
|
||||||
/*Create a spinner*/
|
/* Create a spinner */
|
||||||
lv_obj_t * spinner = lv_spinner_create(lv_screen_active(), 1000, 60);
|
lv_obj_t * spinner = lv_spinner_create(lv_screen_active(), 1000, 60);
|
||||||
lv_obj_set_size(spinner, 64, 64);
|
lv_obj_set_size(spinner, 64, 64);
|
||||||
lv_obj_align(spinner, LV_ALIGN_BOTTOM_MID, 0, 0);
|
lv_obj_align(spinner, LV_ALIGN_BOTTOM_MID, 0, 0);
|
||||||
|
|
||||||
- Create two threads to call :cpp:func:`lv_timer_handler`, and
|
- Create two threads to call :cpp:func:`lv_timer_handler`, and
|
||||||
:cpp:func:`lv_tick_inc`.You will need two ``osThreadId`` handles for
|
:cpp:func:`lv_tick_inc`.You will need two ``osThreadId`` handles for
|
||||||
@@ -193,7 +198,7 @@ variables:
|
|||||||
using CMSIS and STM32Cube code generation it should look something
|
using CMSIS and STM32Cube code generation it should look something
|
||||||
like this:
|
like this:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
//Thread Handles
|
//Thread Handles
|
||||||
osThreadId lvgl_tickHandle;
|
osThreadId lvgl_tickHandle;
|
||||||
@@ -209,7 +214,7 @@ variables:
|
|||||||
|
|
||||||
- And create the thread functions:
|
- And create the thread functions:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/* LVGL timer for tasks. */
|
/* LVGL timer for tasks. */
|
||||||
void LVGLTimer(void const * argument)
|
void LVGLTimer(void const * argument)
|
||||||
@@ -235,7 +240,7 @@ variables:
|
|||||||
depending on which MCU features you are using. Below is an example
|
depending on which MCU features you are using. Below is an example
|
||||||
for a typical MCU interface.
|
for a typical MCU interface.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void my_flush_cb(lv_display_t * display, const lv_area_t * area, uint8_t * px_map);
|
void my_flush_cb(lv_display_t * display, const lv_area_t * area, uint8_t * px_map);
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,13 +24,13 @@ Configure X11 driver
|
|||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
1. Enable the X11 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
1. Enable the X11 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_USE_X11 1
|
#define LV_USE_X11 1
|
||||||
|
|
||||||
2. Optional configuration options:
|
2. Optional configuration options:
|
||||||
- Direct Exit
|
- Direct Exit
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_X11_DIRECT_EXIT 1 /*preferred default - ends the application automatically if last window has been closed*/
|
#define LV_X11_DIRECT_EXIT 1 /*preferred default - ends the application automatically if last window has been closed*/
|
||||||
// or
|
// or
|
||||||
@@ -38,14 +38,14 @@ Configure X11 driver
|
|||||||
|
|
||||||
|
|
||||||
- Double buffering
|
- Double buffering
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_X11_DOUBLE_BUFFER 1 /*preferred default*/
|
#define LV_X11_DOUBLE_BUFFER 1 /*preferred default*/
|
||||||
// or
|
// or
|
||||||
#define LV_X11_DOUBLE_BUFFER 0 /*not recommended*/
|
#define LV_X11_DOUBLE_BUFFER 0 /*not recommended*/
|
||||||
|
|
||||||
- Render mode
|
- Render mode
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_X11_RENDER_MODE_PARTIAL 1 /*LV_DISPLAY_RENDER_MODE_PARTIAL, preferred default*/
|
#define LV_X11_RENDER_MODE_PARTIAL 1 /*LV_DISPLAY_RENDER_MODE_PARTIAL, preferred default*/
|
||||||
// or
|
// or
|
||||||
@@ -59,7 +59,7 @@ Usage
|
|||||||
| The minimal initialisation opening a window and enabling keyboard/mouse support
|
| The minimal initialisation opening a window and enabling keyboard/mouse support
|
||||||
| (e.g. in main.c, LV_X11_DIRECT_EXIT must be 1):
|
| (e.g. in main.c, LV_X11_DIRECT_EXIT must be 1):
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
int main(int argc, char ** argv)
|
int main(int argc, char ** argv)
|
||||||
{
|
{
|
||||||
@@ -85,7 +85,7 @@ Usage
|
|||||||
| Full initialisation with mouse pointer symbol and own application exit handling
|
| Full initialisation with mouse pointer symbol and own application exit handling
|
||||||
| (dependent on LV_X11_DIRECT_EXIT (can be 1 or 0))
|
| (dependent on LV_X11_DIRECT_EXIT (can be 1 or 0))
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
bool terminated = false;
|
bool terminated = false;
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ Configuring the driver
|
|||||||
Enable the framebuffer driver support in lv_conf.h, by cmake compiler define or by KConfig. Additionally you may configure the rendering
|
Enable the framebuffer driver support in lv_conf.h, by cmake compiler define or by KConfig. Additionally you may configure the rendering
|
||||||
mode.
|
mode.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_USE_LINUX_FBDEV 1
|
#define LV_USE_LINUX_FBDEV 1
|
||||||
#define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL
|
#define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL
|
||||||
@@ -31,7 +31,7 @@ Usage
|
|||||||
To set up a framebuffer-based display, first create a display with ``lv_linux_fbdev_create``. Afterwards set the framebuffer device
|
To set up a framebuffer-based display, first create a display with ``lv_linux_fbdev_create``. Afterwards set the framebuffer device
|
||||||
node on the display (usually this is ``/dev/fb0``).
|
node on the display (usually this is ``/dev/fb0``).
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_display_t *disp = lv_linux_fbdev_create();
|
lv_display_t *disp = lv_linux_fbdev_create();
|
||||||
lv_linux_fbdev_set_file(disp, "/dev/fb0");
|
lv_linux_fbdev_set_file(disp, "/dev/fb0");
|
||||||
|
|||||||
@@ -36,19 +36,19 @@ Configuring the driver
|
|||||||
|
|
||||||
Enable the generic MIPI LCD driver support in lv_conf.h, by cmake compiler define or by KConfig
|
Enable the generic MIPI LCD driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_USE_GENERIC_MIPI 1
|
#define LV_USE_GENERIC_MIPI 1
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
``LV_USE_GENERIC_MIPI`` is automatically enabled when a compatible driver is enabled.
|
:c:macro:`LV_USE_GENERIC_MIPI` is automatically enabled when a compatible driver is enabled.
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
You need to implement two platform-dependent functions:
|
You need to implement two platform-dependent functions:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||||
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||||
@@ -89,7 +89,7 @@ Example
|
|||||||
You can find a step-by-step guide and the actual implementation of the callbacks on an STM32F746 using STM32CubeIDE and the ST HAL libraries here: :ref:`lcd_stm32_guide`
|
You can find a step-by-step guide and the actual implementation of the callbacks on an STM32F746 using STM32CubeIDE and the ST HAL libraries here: :ref:`lcd_stm32_guide`
|
||||||
|
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#include "src/drivers/display/st7789/lv_st7789.h"
|
#include "src/drivers/display/st7789/lv_st7789.h"
|
||||||
|
|
||||||
@@ -172,14 +172,14 @@ Create flags
|
|||||||
The third argument of the :cpp:func:`lv_lcd_generic_mipi_create()` function is a flag array. This can be used to configure the orientation and RGB ordering of the panel if the
|
The third argument of the :cpp:func:`lv_lcd_generic_mipi_create()` function is a flag array. This can be used to configure the orientation and RGB ordering of the panel if the
|
||||||
default settings do not work for you. In particular, the generic MIPI driver accepts the following flags:
|
default settings do not work for you. In particular, the generic MIPI driver accepts the following flags:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
LV_LCD_FLAG_NONE
|
LV_LCD_FLAG_NONE
|
||||||
LV_LCD_FLAG_MIRROR_X
|
LV_LCD_FLAG_MIRROR_X
|
||||||
LV_LCD_FLAG_MIRROR_Y
|
LV_LCD_FLAG_MIRROR_Y
|
||||||
LV_LCD_FLAG_BGR
|
LV_LCD_FLAG_BGR
|
||||||
|
|
||||||
You can pass multiple flags by ORing them together, e.g., :c:macro:`LV_LCD_FLAG_MIRROR_X | LV_LCD_FLAG_BGR`.
|
You can pass multiple flags by ORing them together, e.g., :c:macro:`LV_LCD_FLAG_MIRROR_X` ``|`` :c:macro:`LV_LCD_FLAG_BGR`.
|
||||||
|
|
||||||
Custom command lists
|
Custom command lists
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
@@ -191,7 +191,7 @@ of the panel provides some example code with recommended register settings.
|
|||||||
You can use the ``my_lcd_send_cmd()`` function to send an arbitrary command to the LCD controller. However, to make it easier to send a large number of parameters
|
You can use the ``my_lcd_send_cmd()`` function to send an arbitrary command to the LCD controller. However, to make it easier to send a large number of parameters
|
||||||
the generic MIPI driver supports sending a custom command list to the controller. The commands must be put into a 'uint8_t' array:
|
the generic MIPI driver supports sending a custom command list to the controller. The commands must be put into a 'uint8_t' array:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static const uint8_t init_cmd_list[] = {
|
static const uint8_t init_cmd_list[] = {
|
||||||
<command 1>, <number of parameters>, <parameter 1>, ... <parameter N>,
|
<command 1>, <number of parameters>, <parameter 1>, ... <parameter N>,
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Configuring the driver
|
|||||||
|
|
||||||
Enable the ILI9341 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
Enable the ILI9341 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_USE_ILI9341 1
|
#define LV_USE_ILI9341 1
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ Usage
|
|||||||
|
|
||||||
You need to implement two platform-dependent functions:
|
You need to implement two platform-dependent functions:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||||
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||||
@@ -50,7 +50,7 @@ You need to implement two platform-dependent functions:
|
|||||||
|
|
||||||
To create an ILI9341-based display use the function
|
To create an ILI9341-based display use the function
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an LCD display with ILI9341 driver
|
* Create an LCD display with ILI9341 driver
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ Step-by-step instructions
|
|||||||
#. We are ready with the hardware configuration. Save the configuration and let STM32Cube generate the source.
|
#. We are ready with the hardware configuration. Save the configuration and let STM32Cube generate the source.
|
||||||
#. In the project tree clone the LVGL repository into the Middlewares/Third_Party folder (this tutorial uses the release/v9.0 branch of LVGL):
|
#. In the project tree clone the LVGL repository into the Middlewares/Third_Party folder (this tutorial uses the release/v9.0 branch of LVGL):
|
||||||
|
|
||||||
.. code:: dosbatch
|
.. code-block:: dosbatch
|
||||||
|
|
||||||
git clone https://github.com/lvgl/lvgl.git -b release/v9.0
|
git clone https://github.com/lvgl/lvgl.git -b release/v9.0
|
||||||
|
|
||||||
@@ -88,20 +88,20 @@ Step-by-step instructions
|
|||||||
#. Open 'lv_conf.h', and in line 15 change ``#if 0`` to ``#if 1``.
|
#. Open 'lv_conf.h', and in line 15 change ``#if 0`` to ``#if 1``.
|
||||||
#. Search for the string ``LV_USE_ST7735``, and enable the appropriate LCD driver by setting its value to 1. This example uses the ST7789 driver:
|
#. Search for the string ``LV_USE_ST7735``, and enable the appropriate LCD driver by setting its value to 1. This example uses the ST7789 driver:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_USE_ST7789 1
|
#define LV_USE_ST7789 1
|
||||||
|
|
||||||
#. Right click the folder 'Middlewares/Third_Party/lvgl/tests', select Resource Configurations/Exclude from Build..., check both Debug and Release, then press OK.
|
#. Right click the folder 'Middlewares/Third_Party/lvgl/tests', select Resource Configurations/Exclude from Build..., check both Debug and Release, then press OK.
|
||||||
#. Right click the project name and select "Properties". In the C/C++ Build/Settings panel select MCU GCC Compiler/Include paths. In the Configuration dropdown select [ All configurations ]. Add the following Include path:
|
#. Right click the project name and select "Properties". In the C/C++ Build/Settings panel select MCU GCC Compiler/Include paths. In the Configuration dropdown select [ All configurations ]. Add the following Include path:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
../Middlewares/Third_Party/lvgl
|
../Middlewares/Third_Party/lvgl
|
||||||
|
|
||||||
#. Open Core/Src/stm32xxx_it.c (the file name depends on the processor variation). Add 'lv_tick.h' to the Private includes section:
|
#. Open Core/Src/stm32xxx_it.c (the file name depends on the processor variation). Add 'lv_tick.h' to the Private includes section:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/* Private includes ----------------------------------------------------------*/
|
/* Private includes ----------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
@@ -110,7 +110,7 @@ Step-by-step instructions
|
|||||||
|
|
||||||
#. Find the function ``TIM2_IRQHandler``. Add a call to ``lv_tick_inc()``:
|
#. Find the function ``TIM2_IRQHandler``. Add a call to ``lv_tick_inc()``:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void TIM2_IRQHandler(void)
|
void TIM2_IRQHandler(void)
|
||||||
{
|
{
|
||||||
@@ -126,7 +126,7 @@ Step-by-step instructions
|
|||||||
|
|
||||||
#. Save the file, then open Core/Src/main.c. Add the following lines to the Private includes (if your LCD uses other than the ST7789, replace the driver path and header with the appropriate one):
|
#. Save the file, then open Core/Src/main.c. Add the following lines to the Private includes (if your LCD uses other than the ST7789, replace the driver path and header with the appropriate one):
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/* Private includes ----------------------------------------------------------*/
|
/* Private includes ----------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
@@ -136,7 +136,7 @@ Step-by-step instructions
|
|||||||
|
|
||||||
#. Add the following lines to Private defines (change them according to your LCD specs):
|
#. Add the following lines to Private defines (change them according to your LCD specs):
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LCD_H_RES 240
|
#define LCD_H_RES 240
|
||||||
#define LCD_V_RES 320
|
#define LCD_V_RES 320
|
||||||
@@ -145,7 +145,7 @@ Step-by-step instructions
|
|||||||
|
|
||||||
#. Add the following lines to the Private variables:
|
#. Add the following lines to the Private variables:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
osThreadId LvglTaskHandle;
|
osThreadId LvglTaskHandle;
|
||||||
lv_display_t *lcd_disp;
|
lv_display_t *lcd_disp;
|
||||||
@@ -153,21 +153,21 @@ Step-by-step instructions
|
|||||||
|
|
||||||
#. Add the following line to the Private function prototypes:
|
#. Add the following line to the Private function prototypes:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void ui_init(lv_display_t *disp);
|
void ui_init(lv_display_t *disp);
|
||||||
void LVGL_Task(void const *argument);
|
void LVGL_Task(void const *argument);
|
||||||
|
|
||||||
#. Add the following lines after USER CODE BEGIN RTOS_THREADS:
|
#. Add the following lines after USER CODE BEGIN RTOS_THREADS:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
osThreadDef(LvglTask, LVGL_Task, osPriorityIdle, 0, 1024);
|
osThreadDef(LvglTask, LVGL_Task, osPriorityIdle, 0, 1024);
|
||||||
LvglTaskHandle = osThreadCreate(osThread(LvglTask), NULL);
|
LvglTaskHandle = osThreadCreate(osThread(LvglTask), NULL);
|
||||||
|
|
||||||
#. Copy and paste the hardware initialization and the transfer callback functions from the example code after USER CODE BEGIN 4:
|
#. Copy and paste the hardware initialization and the transfer callback functions from the example code after USER CODE BEGIN 4:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/* USER CODE BEGIN 4 */
|
/* USER CODE BEGIN 4 */
|
||||||
|
|
||||||
@@ -250,7 +250,7 @@ Step-by-step instructions
|
|||||||
|
|
||||||
#. Add the LVGL_Task() function. Replace the ``lv_st7789_create()`` call with the appropriate driver. You can change the default orientation by adjusting the parameter of ``lv_display_set_rotation()``. You will also need to create the display buffers here. This example uses a double buffering scheme with 1/10th size partial buffers. In most cases this is a good compromise between the required memory size and performance, but you are free to experiment with other settings.
|
#. Add the LVGL_Task() function. Replace the ``lv_st7789_create()`` call with the appropriate driver. You can change the default orientation by adjusting the parameter of ``lv_display_set_rotation()``. You will also need to create the display buffers here. This example uses a double buffering scheme with 1/10th size partial buffers. In most cases this is a good compromise between the required memory size and performance, but you are free to experiment with other settings.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void LVGL_Task(void const *argument)
|
void LVGL_Task(void const *argument)
|
||||||
{
|
{
|
||||||
@@ -297,7 +297,7 @@ Step-by-step instructions
|
|||||||
|
|
||||||
#. All that's left is to implement ``ui_init()`` to create the screen. Here's a simple "Hello World" example:
|
#. All that's left is to implement ``ui_init()`` to create the screen. Here's a simple "Hello World" example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void ui_init(lv_display_t *disp)
|
void ui_init(lv_display_t *disp)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ Overview
|
|||||||
:alt: Architectural overview of Renesas GLCDC
|
:alt: Architectural overview of Renesas GLCDC
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
|
|
<br/>
|
||||||
|
|
||||||
GLCDC is a multi-stage graphics output peripheral used in Renesas MCUs.
|
GLCDC is a multi-stage graphics output peripheral used in Renesas MCUs.
|
||||||
It is designed to automatically generate timing and data signals for different LCD panels.
|
It is designed to automatically generate timing and data signals for different LCD panels.
|
||||||
@@ -25,12 +25,15 @@ It is designed to automatically generate timing and data signals for different L
|
|||||||
- Supports brightness adjustment, contrast adjustment, and gamma correction
|
- Supports brightness adjustment, contrast adjustment, and gamma correction
|
||||||
- Supports GLCDC interrupts to handle frame-buffer switching or underflow detection
|
- Supports GLCDC interrupts to handle frame-buffer switching or underflow detection
|
||||||
|
|
||||||
| Setting up a project and further integration with Renesas' ecosystem is described in detail on :ref:`page Renesas <renesas>`.
|
|
||||||
| Check out the following repositories for ready-to-use examples:
|
Setting up a project and further integration with Renesas' ecosystem is described in detail on :ref:`page Renesas <renesas>`.
|
||||||
|
Check out the following repositories for ready-to-use examples:
|
||||||
|
|
||||||
- `EK-RA8D1 <https://github.com/lvgl/lv_port_renesas_ek-ra8d1>`__
|
- `EK-RA8D1 <https://github.com/lvgl/lv_port_renesas_ek-ra8d1>`__
|
||||||
- `EK-RA6M3G <https://github.com/lvgl/lv_port_renesas_ek-ra6m3g>`__
|
- `EK-RA6M3G <https://github.com/lvgl/lv_port_renesas_ek-ra6m3g>`__
|
||||||
- `RX72N Envision Kit <https://github.com/lvgl/lv_port_renesas_rx72n-envision-kit>`__
|
- `RX72N Envision Kit <https://github.com/lvgl/lv_port_renesas_rx72n-envision-kit>`__
|
||||||
|
|
||||||
|
|
||||||
Prerequisites
|
Prerequisites
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
@@ -44,7 +47,7 @@ There is no need to implement any platform-specific functions.
|
|||||||
|
|
||||||
The following code demonstrates using the diver in :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_DIRECT` mode.
|
The following code demonstrates using the diver in :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_DIRECT` mode.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_display_t * disp = lv_renesas_glcdc_direct_create();
|
lv_display_t * disp = lv_renesas_glcdc_direct_create();
|
||||||
lv_display_set_default(disp);
|
lv_display_set_default(disp);
|
||||||
@@ -54,7 +57,7 @@ preferably in the fastest available memory region.
|
|||||||
|
|
||||||
Buffer swapping can be activated by passing a second buffer of same size instead of the :cpp:expr:`NULL` argument.
|
Buffer swapping can be activated by passing a second buffer of same size instead of the :cpp:expr:`NULL` argument.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static lv_color_t partial_draw_buf[DISPLAY_HSIZE_INPUT0 * DISPLAY_VSIZE_INPUT0 / 10] BSP_PLACE_IN_SECTION(".sdram") BSP_ALIGN_VARIABLE(1024);
|
static lv_color_t partial_draw_buf[DISPLAY_HSIZE_INPUT0 * DISPLAY_VSIZE_INPUT0 / 10] BSP_PLACE_IN_SECTION(".sdram") BSP_ALIGN_VARIABLE(1024);
|
||||||
|
|
||||||
@@ -71,7 +74,7 @@ Screen rotation
|
|||||||
|
|
||||||
Software based screen rotation is supported in partial mode. It uses the common API, no extra configuration is required:
|
Software based screen rotation is supported in partial mode. It uses the common API, no extra configuration is required:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_display_set_rotation(lv_display_get_default(), LV_DISP_ROTATION_90);
|
lv_display_set_rotation(lv_display_get_default(), LV_DISP_ROTATION_90);
|
||||||
/* OR */
|
/* OR */
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ Configuring the driver
|
|||||||
|
|
||||||
Enable the ST7735 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
Enable the ST7735 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_USE_ST7735 1
|
#define LV_USE_ST7735 1
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ Usage
|
|||||||
|
|
||||||
You need to implement two platform-dependent functions:
|
You need to implement two platform-dependent functions:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||||
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||||
@@ -52,7 +52,7 @@ You need to implement two platform-dependent functions:
|
|||||||
|
|
||||||
To create an ST7735-based display use the function
|
To create an ST7735-based display use the function
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an LCD display with ST7735 driver
|
* Create an LCD display with ST7735 driver
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Configuring the driver
|
|||||||
|
|
||||||
Enable the ST7789 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
Enable the ST7789 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_USE_ST7789 1
|
#define LV_USE_ST7789 1
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ Usage
|
|||||||
|
|
||||||
You need to implement two platform-dependent functions:
|
You need to implement two platform-dependent functions:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||||
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||||
@@ -51,7 +51,7 @@ You need to implement two platform-dependent functions:
|
|||||||
|
|
||||||
To create an ST7789-based display use the function
|
To create an ST7789-based display use the function
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an LCD display with ST7789 driver
|
* Create an LCD display with ST7789 driver
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ Configuring the driver
|
|||||||
|
|
||||||
Enable the ST7796 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
Enable the ST7796 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_USE_ST7796 1
|
#define LV_USE_ST7796 1
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ Usage
|
|||||||
|
|
||||||
You need to implement two platform-dependent functions:
|
You need to implement two platform-dependent functions:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||||
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||||
@@ -52,7 +52,7 @@ You need to implement two platform-dependent functions:
|
|||||||
|
|
||||||
To create an ST7796-based display use the function
|
To create an ST7796-based display use the function
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an LCD display with ST7796 driver
|
* Create an LCD display with ST7796 driver
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ You have the development version of libinput installed (usually ``libinput-dev``
|
|||||||
installed as well (usually in ``/usr/share/libinput/*.quirks``). To test if your device is set up correctly for use with libinput, you can
|
installed as well (usually in ``/usr/share/libinput/*.quirks``). To test if your device is set up correctly for use with libinput, you can
|
||||||
run ``libinput list-devices``.
|
run ``libinput list-devices``.
|
||||||
|
|
||||||
.. code:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ sudo libinput list-devices
|
$ sudo libinput list-devices
|
||||||
...
|
...
|
||||||
@@ -39,13 +39,13 @@ Configuring the driver
|
|||||||
|
|
||||||
Enable the libinput driver support in lv_conf.h, by cmake compiler define or by KConfig.
|
Enable the libinput driver support in lv_conf.h, by cmake compiler define or by KConfig.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_USE_LIBINPUT 1
|
#define LV_USE_LIBINPUT 1
|
||||||
|
|
||||||
Full keyboard support needs to be enabled separately.
|
Full keyboard support needs to be enabled separately.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_LIBINPUT_XKB 1
|
#define LV_LIBINPUT_XKB 1
|
||||||
#define LV_LIBINPUT_XKB_KEY_MAP { .rules = NULL, .model = "pc101", .layout = "us", .variant = NULL, .options = NULL }
|
#define LV_LIBINPUT_XKB_KEY_MAP { .rules = NULL, .model = "pc101", .layout = "us", .variant = NULL, .options = NULL }
|
||||||
@@ -58,7 +58,7 @@ Usage
|
|||||||
To set up an input device via the libinput driver, all you need to do is call ``lv_libinput_create`` with the respective device type
|
To set up an input device via the libinput driver, all you need to do is call ``lv_libinput_create`` with the respective device type
|
||||||
(``LV_INDEV_TYPE_POINTER`` or ``LV_INDEV_TYPE_KEYPAD``) and device node path (e.g. ``/dev/input/event5``).
|
(``LV_INDEV_TYPE_POINTER`` or ``LV_INDEV_TYPE_KEYPAD``) and device node path (e.g. ``/dev/input/event5``).
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_indev_t *indev = lv_libinput_create(LV_INDEV_TYPE_POINTER, "/dev/input/event5");
|
lv_indev_t *indev = lv_libinput_create(LV_INDEV_TYPE_POINTER, "/dev/input/event5");
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ Note that touchscreens are treated as (absolute) pointer devices by the libinput
|
|||||||
Depending on your system, the device node paths might not be stable across reboots. If this is the case, you can use ``lv_libinput_find_dev``
|
Depending on your system, the device node paths might not be stable across reboots. If this is the case, you can use ``lv_libinput_find_dev``
|
||||||
to find the first device that has a specific capability.
|
to find the first device that has a specific capability.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
char *path = lv_libinput_find_dev(LV_LIBINPUT_CAPABILITY_TOUCH, true);
|
char *path = lv_libinput_find_dev(LV_LIBINPUT_CAPABILITY_TOUCH, true);
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ all devices that have a specific capability, use ``lv_libinput_find_devs``.
|
|||||||
|
|
||||||
If you want to connect a keyboard device to a textarea, create a dedicated input group and set it on both the indev and textarea.
|
If you want to connect a keyboard device to a textarea, create a dedicated input group and set it on both the indev and textarea.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t *textarea = lv_textarea_create(...);
|
lv_obj_t *textarea = lv_textarea_create(...);
|
||||||
...
|
...
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ Configure OpenGL driver
|
|||||||
|
|
||||||
1. Required linked libraries: -lGL -lGLEW -lglfw
|
1. Required linked libraries: -lGL -lGLEW -lglfw
|
||||||
2. Enable the OpenGL driver support in lv_conf.h, by cmake compiler define or by KConfig
|
2. Enable the OpenGL driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_USE_OPENGLES 1
|
#define LV_USE_OPENGLES 1
|
||||||
|
|
||||||
Basic usage
|
Basic usage
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#include "lvgl/lvgl.h"
|
#include "lvgl/lvgl.h"
|
||||||
#include "lvgl/examples/lv_examples.h"
|
#include "lvgl/examples/lv_examples.h"
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Configuring the driver
|
|||||||
|
|
||||||
Enable the Linux LVGL evdev driver support in ``lv_conf.h``.
|
Enable the Linux LVGL evdev driver support in ``lv_conf.h``.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_USE_EVDEV 1
|
#define LV_USE_EVDEV 1
|
||||||
|
|
||||||
@@ -28,14 +28,14 @@ Usage
|
|||||||
To set up an event input, first create an input device with ``lv_edev_create`` setting it to the correct Linux event device.
|
To set up an event input, first create an input device with ``lv_edev_create`` setting it to the correct Linux event device.
|
||||||
Then link this to the LVGL display with ``lv_indev_set_display``.
|
Then link this to the LVGL display with ``lv_indev_set_display``.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_indev_t *touch = lv_evdev_create(LV_INDEV_TYPE_POINTER, "/dev/input/event0");
|
lv_indev_t *touch = lv_evdev_create(LV_INDEV_TYPE_POINTER, "/dev/input/event0");
|
||||||
lv_indev_set_display(touch, disp);
|
lv_indev_set_display(touch, disp);
|
||||||
|
|
||||||
Ensure that an ``lv_display_t`` object is already created for ``disp``. An example for this is shown below, using the Linux framebuffer driver.
|
Ensure that an ``lv_display_t`` object is already created for ``disp``. An example for this is shown below, using the Linux framebuffer driver.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_display_t * disp = lv_linux_fbdev
|
lv_display_t * disp = lv_linux_fbdev
|
||||||
lv_linux_fbdev_set_file(disp, "/dev/fb0");_create();
|
lv_linux_fbdev_set_file(disp, "/dev/fb0");_create();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
=======
|
========
|
||||||
Touchpad
|
Touchpad
|
||||||
=======
|
========
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|||||||
@@ -46,14 +46,14 @@ Configure Windows driver
|
|||||||
|
|
||||||
Enable the Windows driver support in lv_conf.h, by cmake compiler define or by KConfig
|
Enable the Windows driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_USE_WINDOWS 1
|
#define LV_USE_WINDOWS 1
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include "lvgl/lvgl.h"
|
#include "lvgl/lvgl.h"
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ this debug information to the serial interface. To enable this feature
|
|||||||
you have to edit the ``lv_conf.h`` file and enable logging in the
|
you have to edit the ``lv_conf.h`` file and enable logging in the
|
||||||
section ``log settings``:
|
section ``log settings``:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/*Log settings*/
|
/*Log settings*/
|
||||||
#define USE_LV_LOG 1 /*Enable/disable the log module*/
|
#define USE_LV_LOG 1 /*Enable/disable the log module*/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
==========
|
==========
|
||||||
Platformio
|
PlatformIO
|
||||||
==========
|
==========
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ Let's dive right into an example!
|
|||||||
A simple example
|
A simple example
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
lv.start() # start LVGL
|
lv.start() # start LVGL
|
||||||
scr = lv.screen_active() # get default screen
|
scr = lv.screen_active() # get default screen
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Using the simulator on a PC has the following advantages:
|
|||||||
- Easy Validation: The simulator is also very useful to report bugs because it
|
- Easy Validation: The simulator is also very useful to report bugs because it
|
||||||
provides a common platform for every user.
|
provides a common platform for every user.
|
||||||
- Better developer experience: On PC Debuggers are usually faster and better, you can log to files,
|
- Better developer experience: On PC Debuggers are usually faster and better, you can log to files,
|
||||||
add a lot of ``printf``-s, do profiling, and so on.
|
add a lot of ``printf`` s, do profiling, and so on.
|
||||||
|
|
||||||
|
|
||||||
Select an IDE
|
Select an IDE
|
||||||
@@ -48,7 +48,7 @@ another driver in ``lv_conf.h`` and calling its ``create`` function.
|
|||||||
For example to use the Linux frame buffer device instead of SDL just enable ``LV_USE_LINUX_FBDEV``
|
For example to use the Linux frame buffer device instead of SDL just enable ``LV_USE_LINUX_FBDEV``
|
||||||
and call
|
and call
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_display_t *display = lv_linux_fbdev_create();
|
lv_display_t *display = lv_linux_fbdev_create();
|
||||||
lv_linux_fbdev_set_file(display, "/dev/fb0")
|
lv_linux_fbdev_set_file(display, "/dev/fb0")
|
||||||
|
|||||||
@@ -88,14 +88,14 @@ First you need to install the pre-requisites on your system
|
|||||||
Let's use the `Windows Subsystem for
|
Let's use the `Windows Subsystem for
|
||||||
Linux <https://acassis.wordpress.com/2018/01/10/how-to-build-nuttx-on-windows-10/>`__
|
Linux <https://acassis.wordpress.com/2018/01/10/how-to-build-nuttx-on-windows-10/>`__
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
$ sudo apt-get install automake bison build-essential flex gcc-arm-none-eabi gperf git libncurses5-dev libtool libusb-dev libusb-1.0.0-dev pkg-config kconfig-frontends openocd
|
$ sudo apt-get install automake bison build-essential flex gcc-arm-none-eabi gperf git libncurses5-dev libtool libusb-dev libusb-1.0.0-dev pkg-config kconfig-frontends openocd
|
||||||
|
|
||||||
Now let's create a workspace to save our files
|
Now let's create a workspace to save our files
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
$ mkdir ~/nuttxspace
|
$ mkdir ~/nuttxspace
|
||||||
$ cd ~/nuttxspace
|
$ cd ~/nuttxspace
|
||||||
@@ -103,7 +103,7 @@ Now let's create a workspace to save our files
|
|||||||
Clone the NuttX and Apps repositories:
|
Clone the NuttX and Apps repositories:
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
$ git clone https://github.com/apache/incubator-nuttx nuttx
|
$ git clone https://github.com/apache/incubator-nuttx nuttx
|
||||||
$ git clone https://github.com/apache/incubator-nuttx-apps apps
|
$ git clone https://github.com/apache/incubator-nuttx-apps apps
|
||||||
@@ -111,7 +111,7 @@ Clone the NuttX and Apps repositories:
|
|||||||
Configure NuttX to use the stm32f429i-disco board and the LVGL Demo
|
Configure NuttX to use the stm32f429i-disco board and the LVGL Demo
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
$ ./tools/configure.sh stm32f429i-disco:lvgl
|
$ ./tools/configure.sh stm32f429i-disco:lvgl
|
||||||
$ make
|
$ make
|
||||||
@@ -119,7 +119,7 @@ Configure NuttX to use the stm32f429i-disco board and the LVGL Demo
|
|||||||
If everything went fine you should have now the file ``nuttx.bin`` to
|
If everything went fine you should have now the file ``nuttx.bin`` to
|
||||||
flash on your board:
|
flash on your board:
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
$ ls -l nuttx.bin
|
$ ls -l nuttx.bin
|
||||||
-rwxrwxr-x 1 alan alan 287144 Jun 27 09:26 nuttx.bin
|
-rwxrwxr-x 1 alan alan 287144 Jun 27 09:26 nuttx.bin
|
||||||
@@ -127,13 +127,13 @@ flash on your board:
|
|||||||
Flashing the firmware in the board using OpenOCD:
|
Flashing the firmware in the board using OpenOCD:
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
$ sudo openocd -f interface/stlink-v2.cfg -f target/stm32f4x.cfg -c init -c "reset halt" -c "flash write_image erase nuttx.bin 0x08000000"
|
$ sudo openocd -f interface/stlink-v2.cfg -f target/stm32f4x.cfg -c init -c "reset halt" -c "flash write_image erase nuttx.bin 0x08000000"
|
||||||
|
|
||||||
Reset the board and using the 'NSH>' terminal start the LVGL demo:
|
Reset the board and using the 'NSH>' terminal start the LVGL demo:
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
nsh> lvgldemo
|
nsh> lvgldemo
|
||||||
|
|
||||||
|
|||||||
@@ -37,15 +37,21 @@ Follow the generic instructions for getting started with LVGL. After copying
|
|||||||
`lv_conf_template.h` to `lv_conf.h` make the following changes to the latter:
|
`lv_conf_template.h` to `lv_conf.h` make the following changes to the latter:
|
||||||
|
|
||||||
1. Enable QNX support:
|
1. Enable QNX support:
|
||||||
.. code::
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_USE_QNX 1
|
#define LV_USE_QNX 1
|
||||||
|
|
||||||
2. Set colour depth to 32:
|
2. Set colour depth to 32:
|
||||||
.. code::
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_COLOR_DEPTH 32
|
#define LV_COLOR_DEPTH 32
|
||||||
|
|
||||||
3. (Optional) Enable double-buffering:
|
3. (Optional) Enable double-buffering:
|
||||||
.. code::
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_QNX_BUF_COUNT 2
|
#define LV_QNX_BUF_COUNT 2
|
||||||
|
|
||||||
Build LVGL as a Library
|
Build LVGL as a Library
|
||||||
@@ -59,7 +65,7 @@ The top-level `qnx` directory includes a recursive make file for building LVGL,
|
|||||||
both as a shared library and as a static library for the supported
|
both as a shared library and as a static library for the supported
|
||||||
architectures. To build all libraries, simply invoke `make` in this directory:
|
architectures. To build all libraries, simply invoke `make` in this directory:
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
# cd $(LVGL_ROOT)/env_support/qnx
|
# cd $(LVGL_ROOT)/env_support/qnx
|
||||||
# make
|
# make
|
||||||
@@ -68,7 +74,7 @@ If you prefer to build for a specific architecture and variant, go to the
|
|||||||
appropriate directory and run `make` there. For example, to build a shared
|
appropriate directory and run `make` there. For example, to build a shared
|
||||||
library for ARMv8:
|
library for ARMv8:
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
# cd $(LVGL_ROOT)/env_support/qnx/aarch64/so.le
|
# cd $(LVGL_ROOT)/env_support/qnx/aarch64/so.le
|
||||||
# make
|
# make
|
||||||
@@ -97,7 +103,7 @@ identical to that of a LVGL application written for any other platform.
|
|||||||
|
|
||||||
The following code shows how to create a "Hello World" application:
|
The following code shows how to create a "Hello World" application:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
|
|
||||||
@@ -135,7 +141,7 @@ and then linking against the library. This can be done in many ways, using
|
|||||||
different build systems. The following is a simple make file for the example
|
different build systems. The following is a simple make file for the example
|
||||||
above, which builds for ARMv8 with the shared library:
|
above, which builds for ARMv8 with the shared library:
|
||||||
|
|
||||||
.. code:: makefile
|
.. code-block:: makefile
|
||||||
|
|
||||||
CC=qcc -Vgcc_ntoaarch64le
|
CC=qcc -Vgcc_ntoaarch64le
|
||||||
|
|
||||||
|
|||||||
@@ -42,26 +42,26 @@ To setup your development environment refer to the
|
|||||||
After you completed the setup above you can check out all of the `provided samples <https://docs.zephyrproject.org/latest/samples/>`__ for various boards.
|
After you completed the setup above you can check out all of the `provided samples <https://docs.zephyrproject.org/latest/samples/>`__ for various boards.
|
||||||
You can check the list of available boards using:
|
You can check the list of available boards using:
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
$ west boards
|
$ west boards
|
||||||
|
|
||||||
After you chose a board you can build one of the LVGL demos for it. Here we are using the :code:`native_posix`
|
After you chose a board you can build one of the LVGL demos for it. Here we are using the :code:`native_posix`
|
||||||
board, which allows for running the application on your posix compliant host system:
|
board, which allows for running the application on your posix compliant host system:
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
$ west build -b native_posix samples/modules/lvgl/demos
|
$ west build -b native_posix samples/modules/lvgl/demos
|
||||||
|
|
||||||
To run the application on your host:
|
To run the application on your host:
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
$ west build -t run
|
$ west build -t run
|
||||||
|
|
||||||
In case you chose any of the other supported boards you can flash to the device with:
|
In case you chose any of the other supported boards you can flash to the device with:
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
$ west flash
|
$ west flash
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ Zephyr includes a powerful shell implementation that can be enabled with the Kco
|
|||||||
|
|
||||||
The shell offers enabling/disabling of LVGL monkeys:
|
The shell offers enabling/disabling of LVGL monkeys:
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
# Create a new monkey with the given indev type
|
# Create a new monkey with the given indev type
|
||||||
uart$ lvgl monkey create [pointer|keypad|button|encoder]
|
uart$ lvgl monkey create [pointer|keypad|button|encoder]
|
||||||
@@ -90,7 +90,7 @@ The shell offers enabling/disabling of LVGL monkeys:
|
|||||||
This is useful for checking your application for memory leaks and other bugs.
|
This is useful for checking your application for memory leaks and other bugs.
|
||||||
Speaking of memory leaks, you can also acquire stats of the memory used by LVGL
|
Speaking of memory leaks, you can also acquire stats of the memory used by LVGL
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
uart$ lvgl stats memory
|
uart$ lvgl stats memory
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ they are created at application start up before :code:`main()` is executed.
|
|||||||
|
|
||||||
Most boards or shields that have a display or display connector have the pointer input device already declared:
|
Most boards or shields that have a display or display connector have the pointer input device already declared:
|
||||||
|
|
||||||
.. code::
|
.. code-block::
|
||||||
|
|
||||||
lvgl_pointer {
|
lvgl_pointer {
|
||||||
compatible = "zephyr,lvgl-pointer-input";
|
compatible = "zephyr,lvgl-pointer-input";
|
||||||
@@ -124,7 +124,7 @@ Most boards or shields that have a display or display connector have the pointer
|
|||||||
You can access the underlying lvgl :code:`lv_indev_t` for configuration.
|
You can access the underlying lvgl :code:`lv_indev_t` for configuration.
|
||||||
Example with the encoder device to assign a :code:`lv_group_t`:
|
Example with the encoder device to assign a :code:`lv_group_t`:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
const struct device *lvgl_encoder = DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_lvgl_encoder_input));
|
const struct device *lvgl_encoder = DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_lvgl_encoder_input));
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ Kconfig
|
|||||||
Aside from enabling the shell you can also use Kconfig to finetune
|
Aside from enabling the shell you can also use Kconfig to finetune
|
||||||
the footprint of your application.
|
the footprint of your application.
|
||||||
|
|
||||||
.. code::
|
.. code-block::
|
||||||
|
|
||||||
# Size of the memory region from which lvgl memory is allocated
|
# Size of the memory region from which lvgl memory is allocated
|
||||||
CONFIG_LV_Z_MEM_POOL_SIZE=8192
|
CONFIG_LV_Z_MEM_POOL_SIZE=8192
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ be :c:macro:`LV_GRID_TEMPLATE_LAST`.
|
|||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static int32_t column_dsc[] = {100, 400, LV_GRID_TEMPLATE_LAST}; /*2 columns with 100 and 400 ps width*/
|
static int32_t column_dsc[] = {100, 400, LV_GRID_TEMPLATE_LAST}; /*2 columns with 100 and 400 ps width*/
|
||||||
static int32_t row_dsc[] = {100, 100, 100, LV_GRID_TEMPLATE_LAST}; /*3 100 px tall rows*/
|
static int32_t row_dsc[] = {100, 100, 100, LV_GRID_TEMPLATE_LAST}; /*3 100 px tall rows*/
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ If enabled in ``lv_conf.h`` by :c:macro:`LV_USE_BMP` LVGL will register a new
|
|||||||
image decoder automatically so BMP files can be directly used as image
|
image decoder automatically so BMP files can be directly used as image
|
||||||
sources. For example:
|
sources. For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_image_set_src(my_img, "S:path/to/picture.bmp");
|
lv_image_set_src(my_img, "S:path/to/picture.bmp");
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Install FFmpeg
|
|||||||
|
|
||||||
Download first FFmpeg from `here <https://www.ffmpeg.org/download.html>`__, then install it:
|
Download first FFmpeg from `here <https://www.ffmpeg.org/download.html>`__, then install it:
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
./configure --disable-all --disable-autodetect --disable-podpages --disable-asm --enable-avcodec --enable-avformat --enable-decoders --enable-encoders --enable-demuxers --enable-parsers --enable-protocol='file' --enable-swscale --enable-zlib
|
./configure --disable-all --disable-autodetect --disable-podpages --disable-asm --enable-avcodec --enable-avformat --enable-decoders --enable-encoders --enable-demuxers --enable-parsers --enable-protocol='file' --enable-swscale --enable-zlib
|
||||||
make
|
make
|
||||||
@@ -33,9 +33,10 @@ Enable :c:macro:`LV_USE_FFMPEG` in ``lv_conf.h``.
|
|||||||
|
|
||||||
See the examples below.
|
See the examples below.
|
||||||
|
|
||||||
:Note: FFmpeg extension doesn't use LVGL's file system. You can
|
:note: FFmpeg extension doesn't use LVGL's file system. You can
|
||||||
simply pass the path to the image or video as usual on your operating
|
simply pass the path to the image or video as usual on your operating
|
||||||
system or platform.
|
system or platform.
|
||||||
|
|
||||||
|
|
||||||
.. _ffmpeg_example:
|
.. _ffmpeg_example:
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ FLASH space.
|
|||||||
- Copy the FreeType source code to your project directory.
|
- Copy the FreeType source code to your project directory.
|
||||||
- Refer to the following ``Makefile`` for configuration:
|
- Refer to the following ``Makefile`` for configuration:
|
||||||
|
|
||||||
.. code:: make
|
.. code-block:: make
|
||||||
|
|
||||||
# FreeType custom configuration header file
|
# FreeType custom configuration header file
|
||||||
CFLAGS += -DFT2_BUILD_LIBRARY
|
CFLAGS += -DFT2_BUILD_LIBRARY
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ To use the memory-mapped file emulation an ``lv_fs_path_ex_t`` object must be
|
|||||||
created and initialized. This object can be passed to :cpp:func:`lv_fs_open` as
|
created and initialized. This object can be passed to :cpp:func:`lv_fs_open` as
|
||||||
the file name:
|
the file name:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_fs_path_ex_t mempath;
|
lv_fs_path_ex_t mempath;
|
||||||
lv_fs_file_t file;
|
lv_fs_file_t file;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ Use GIF images from file
|
|||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_gif_set_src(obj, "S:path/to/example.gif");
|
lv_gif_set_src(obj, "S:path/to/example.gif");
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ When enabled :c:macro:`lv_littlefs_set_handler` can be used to set up a mount po
|
|||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#include "lfs.h"
|
#include "lfs.h"
|
||||||
|
|
||||||
// configuration of the filesystem is provided by this struct
|
// configuration of the filesystem is provided by this struct
|
||||||
|
|||||||
@@ -16,14 +16,14 @@ Library source: https://github.com/libjpeg-turbo/libjpeg-turbo
|
|||||||
Install
|
Install
|
||||||
-------
|
-------
|
||||||
|
|
||||||
.. code:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
sudo apt install libjpeg-turbo8-dev
|
sudo apt install libjpeg-turbo8-dev
|
||||||
|
|
||||||
Add libjpeg-turbo to your project
|
Add libjpeg-turbo to your project
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
.. code:: cmake
|
.. code-block:: cmake
|
||||||
|
|
||||||
find_package(JPEG REQUIRED)
|
find_package(JPEG REQUIRED)
|
||||||
include_directories(${JPEG_INCLUDE_DIR})
|
include_directories(${JPEG_INCLUDE_DIR})
|
||||||
|
|||||||
@@ -11,14 +11,14 @@ Detailed introduction: http://www.libpng.org/pub/png/libpng.html
|
|||||||
Install
|
Install
|
||||||
-------
|
-------
|
||||||
|
|
||||||
.. code:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
sudo apt install libpng-dev
|
sudo apt install libpng-dev
|
||||||
|
|
||||||
Add libpng to your project
|
Add libpng to your project
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
.. code:: cmake
|
.. code-block:: cmake
|
||||||
|
|
||||||
find_package(PNG REQUIRED)
|
find_package(PNG REQUIRED)
|
||||||
include_directories(${PNG_INCLUDE_DIR})
|
include_directories(${PNG_INCLUDE_DIR})
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. _lodepng:
|
.. _lodepng_rst:
|
||||||
|
|
||||||
===============
|
===============
|
||||||
LodePNG decoder
|
LodePNG decoder
|
||||||
@@ -12,11 +12,12 @@ If enabled in ``lv_conf.h`` by :c:macro:`LV_USE_LODEPNG` LVGL will register a ne
|
|||||||
image decoder automatically so PNG files can be directly used as any
|
image decoder automatically so PNG files can be directly used as any
|
||||||
other image sources.
|
other image sources.
|
||||||
|
|
||||||
:Note: a file system driver needs to be registered to open images from
|
:note: a file system driver needs to be registered to open images from
|
||||||
files. Read more about it :ref:`overview_file_system` or just
|
files. Read more about it :ref:`overview_file_system` or just
|
||||||
enable one in ``lv_conf.h`` with ``LV_USE_FS_...``
|
enable one in ``lv_conf.h`` with ``LV_USE_FS_...``
|
||||||
|
|
||||||
The whole PNG image is decoded, so ``width x height x 4`` bytes free RAM space is required.
|
|
||||||
|
The whole PNG image is decoded, so ``width x height x 4`` bytes free RAM space is required.
|
||||||
The decoded image is stored in RGBA pixel format.
|
The decoded image is stored in RGBA pixel format.
|
||||||
|
|
||||||
As it might take significant time to decode PNG images LVGL's :ref:`overview_image_caching` feature can be useful.
|
As it might take significant time to decode PNG images LVGL's :ref:`overview_image_caching` feature can be useful.
|
||||||
@@ -25,13 +26,13 @@ Compress PNG files
|
|||||||
------------------
|
------------------
|
||||||
|
|
||||||
PNG file format supports True color (24/32 bit), and 8-bit palette colors.
|
PNG file format supports True color (24/32 bit), and 8-bit palette colors.
|
||||||
Usually cliparts, drawings, icons and simple graphics are stored in PNG format,
|
Usually cliparts, drawings, icons and simple graphics are stored in PNG format,
|
||||||
that do not use the whole color space, so it is possible to compress further
|
that do not use the whole color space, so it is possible to compress further
|
||||||
the image by using 8-bit palette colors, instead of 24/32 bit True color format.
|
the image by using 8-bit palette colors, instead of 24/32 bit True color format.
|
||||||
Because embedded devices have limited (flash) storage, it is recommended
|
Because embedded devices have limited (flash) storage, it is recommended
|
||||||
to compress images.
|
to compress images.
|
||||||
|
|
||||||
One option is to use a free online PNG compressor site,
|
One option is to use a free online PNG compressor site,
|
||||||
for example Compress PNG: https://compresspng.com/
|
for example Compress PNG: https://compresspng.com/
|
||||||
|
|
||||||
.. _lodepng_example:
|
.. _lodepng_example:
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ If the coming pixels are not repeated, it stores the non-repeat count value and
|
|||||||
original color value. For more details, the script used to compress the image
|
original color value. For more details, the script used to compress the image
|
||||||
can be found from ``lvgl/script/LVGLImage.py``.
|
can be found from ``lvgl/script/LVGLImage.py``.
|
||||||
|
|
||||||
.. code:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def rle_compress(self, data: bytearray, blksize: int, threshold=16):
|
def rle_compress(self, data: bytearray, blksize: int, threshold=16):
|
||||||
index = 0
|
index = 0
|
||||||
@@ -71,7 +71,7 @@ Usage
|
|||||||
To use the RLE Decoder, enable it in ``lv_conf.h`` configuration file by setting :c:macro:`LV_USE_RLE` to `1`.
|
To use the RLE Decoder, enable it in ``lv_conf.h`` configuration file by setting :c:macro:`LV_USE_RLE` to `1`.
|
||||||
The RLE image can be used same as other images.
|
The RLE image can be used same as other images.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_image_set_src(img, "path/to/image.rle");
|
lv_image_set_src(img, "path/to/image.rle");
|
||||||
|
|
||||||
@@ -81,6 +81,6 @@ Generate RLE compressed binary images
|
|||||||
The image can be directly generated using script ``lvgl/script/LVGLImage.py``
|
The image can be directly generated using script ``lvgl/script/LVGLImage.py``
|
||||||
|
|
||||||
|
|
||||||
.. code:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
./script/LVGLImage.py --ofmt BIN --cf I8 --compress RLE cogwheel.png
|
./script/LVGLImage.py --ofmt BIN --cf I8 --compress RLE cogwheel.png
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ To build on desktop you can follow the instructions from Rlottie's
|
|||||||
|
|
||||||
In the most basic case it looks like this:
|
In the most basic case it looks like this:
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
mkdir rlottie_workdir
|
mkdir rlottie_workdir
|
||||||
cd rlottie_workdir
|
cd rlottie_workdir
|
||||||
@@ -59,7 +59,7 @@ Use Rlottie from file
|
|||||||
|
|
||||||
To create a Lottie animation from file use:
|
To create a Lottie animation from file use:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * lottie = lv_rlottie_create_from_file(parent, width, height, "path/to/lottie.json");
|
lv_obj_t * lottie = lv_rlottie_create_from_file(parent, width, height, "path/to/lottie.json");
|
||||||
|
|
||||||
@@ -79,13 +79,13 @@ following reasons:
|
|||||||
``lvgl/scripts/filetohex.py`` can be used to convert a Lottie file a hex
|
``lvgl/scripts/filetohex.py`` can be used to convert a Lottie file a hex
|
||||||
array. E.g.:
|
array. E.g.:
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
./filetohex.py path/to/lottie.json > out.txt
|
./filetohex.py path/to/lottie.json > out.txt
|
||||||
|
|
||||||
To create an animation from raw data:
|
To create an animation from raw data:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
extern const uint8_t lottie_data[];
|
extern const uint8_t lottie_data[];
|
||||||
lv_obj_t* lottie = lv_rlottie_create_from_raw(parent, width, height, (const char *)lottie_data);
|
lv_obj_t* lottie = lv_rlottie_create_from_raw(parent, width, height, (const char *)lottie_data);
|
||||||
@@ -107,7 +107,7 @@ LVGL provides two functions to control the animation mode:
|
|||||||
You'll combine your intentions when calling the first method, like in
|
You'll combine your intentions when calling the first method, like in
|
||||||
these examples:
|
these examples:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * lottie = lv_rlottie_create_from_file(scr, 128, 128, "test.json");
|
lv_obj_t * lottie = lv_rlottie_create_from_file(scr, 128, 128, "test.json");
|
||||||
lv_obj_center(lottie);
|
lv_obj_center(lottie);
|
||||||
@@ -180,7 +180,7 @@ limitations:
|
|||||||
- Build the lottie animation to be sized for the intended size
|
- Build the lottie animation to be sized for the intended size
|
||||||
- it can scale/resize, but performance will be best when the base lottie size is as intended
|
- it can scale/resize, but performance will be best when the base lottie size is as intended
|
||||||
- Limit total number of frames, the longer the lottie animation is,
|
- Limit total number of frames, the longer the lottie animation is,
|
||||||
the more memory it will consume for rendering (rlottie consumes IRAM for rendering)
|
the more memory it will consume for rendering (rlottie consumes IRAM for rendering)
|
||||||
- Build the lottie animation for the intended frame rate
|
- Build the lottie animation for the intended frame rate
|
||||||
- default lottie is 60fps, embedded LCDs likely won't go above 30fps
|
- default lottie is 60fps, embedded LCDs likely won't go above 30fps
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ IDF Setup
|
|||||||
Where the LVGL simulator uses the installed rlottie lib, the IDF works
|
Where the LVGL simulator uses the installed rlottie lib, the IDF works
|
||||||
best when using rlottie as a submodule under the components directory.
|
best when using rlottie as a submodule under the components directory.
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
cd 'your/project/directory'
|
cd 'your/project/directory'
|
||||||
git add submodule
|
git add submodule
|
||||||
@@ -224,7 +224,7 @@ Copy this CMakeLists file to
|
|||||||
In addition to the component CMakeLists file, you'll also need to tell
|
In addition to the component CMakeLists file, you'll also need to tell
|
||||||
your project level CMakeLists in your IDF project to require rlottie:
|
your project level CMakeLists in your IDF project to require rlottie:
|
||||||
|
|
||||||
.. code:: console
|
.. code-block:: console
|
||||||
|
|
||||||
REQUIRES "lvgl" "rlottie"
|
REQUIRES "lvgl" "rlottie"
|
||||||
|
|
||||||
@@ -274,7 +274,7 @@ your espressif project. This is as simple as swapping
|
|||||||
IDF) with the appropriate :cpp:expr:`MALLOC_CAP` call - for SPIRAM usage this is
|
IDF) with the appropriate :cpp:expr:`MALLOC_CAP` call - for SPIRAM usage this is
|
||||||
:cpp:expr:`MALLOC_CAP_SPIRAM`.
|
:cpp:expr:`MALLOC_CAP_SPIRAM`.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
rlottie->allocated_buf = heap_caps_malloc(allocated_buf_size+1, MALLOC_CAP_SPIRAM);
|
rlottie->allocated_buf = heap_caps_malloc(allocated_buf_size+1, MALLOC_CAP_SPIRAM);
|
||||||
|
|
||||||
|
|||||||
@@ -30,19 +30,20 @@ as image sources.
|
|||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_image_set_src(my_img, "S:path/to/picture.jpg");
|
lv_image_set_src(my_img, "S:path/to/picture.jpg");
|
||||||
|
|
||||||
:Note: a file system driver needs to be registered to open images from
|
:note: a file system driver needs to be registered to open images from
|
||||||
files. Read more about :ref:`overview_file_system` or just
|
files. Read more about :ref:`overview_file_system` or just
|
||||||
enable one in ``lv_conf.h`` with ``LV_USE_FS_...`` config.
|
enable one in ``lv_conf.h`` with ``LV_USE_FS_...`` config.
|
||||||
|
|
||||||
|
|
||||||
Converter
|
Converter
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Converting JPEG to C array
|
Converting JPEG to C array
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
- Use lvgl online tool https://lvgl.io/tools/imageconverter
|
- Use lvgl online tool https://lvgl.io/tools/imageconverter
|
||||||
- Color format = RAW, output format = C Array
|
- Color format = RAW, output format = C Array
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ You can use :cpp:func:`lv_file_explorer_get_cur_path` to get the current path
|
|||||||
and :cpp:func:`lv_file_explorer_get_sel_fn` to get the name of the currently
|
and :cpp:func:`lv_file_explorer_get_sel_fn` to get the name of the currently
|
||||||
selected file in the event processing function. For example:
|
selected file in the event processing function. For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static void file_explorer_event_handler(lv_event_t * e)
|
static void file_explorer_event_handler(lv_event_t * e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ Enable :c:macro:`LV_USE_FRAGMENT` in ``lv_conf.h``.
|
|||||||
Create Fragment Class
|
Create Fragment Class
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
struct sample_fragment_t {
|
struct sample_fragment_t {
|
||||||
/* IMPORTANT: don't miss this part */
|
/* IMPORTANT: don't miss this part */
|
||||||
@@ -53,7 +53,7 @@ Create Fragment Class
|
|||||||
Use ``lv_fragment_manager``
|
Use ``lv_fragment_manager``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/* Create fragment instance, and objects will be added to container */
|
/* Create fragment instance, and objects will be added to container */
|
||||||
lv_fragment_manager_t *manager = lv_fragment_manager_create(container, NULL);
|
lv_fragment_manager_t *manager = lv_fragment_manager_create(container, NULL);
|
||||||
@@ -63,7 +63,7 @@ Use ``lv_fragment_manager``
|
|||||||
Fragment Based Navigation
|
Fragment Based Navigation
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/* Add one instance into manager stack. View object of current fragment will be destroyed,
|
/* Add one instance into manager stack. View object of current fragment will be destroyed,
|
||||||
* but instances created in class constructor will be kept.
|
* but instances created in class constructor will be kept.
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ Normally, an environment where :ref:`lv_keyboard` can
|
|||||||
run can also run ``lv_ime_pinyin``. There are two main influencing
|
run can also run ``lv_ime_pinyin``. There are two main influencing
|
||||||
factors: the size of the font file and the size of the dictionary.
|
factors: the size of the font file and the size of the dictionary.
|
||||||
|
|
||||||
.. _ime_pinyin_example:
|
|
||||||
|
.. _ime_pinyin_usage:
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
@@ -37,6 +38,7 @@ custom fonts and thesaurus.
|
|||||||
In the process of using the Pinyin input method plug-in, you can change
|
In the process of using the Pinyin input method plug-in, you can change
|
||||||
the keyboard and dictionary at any time.
|
the keyboard and dictionary at any time.
|
||||||
|
|
||||||
|
|
||||||
Custom dictionary
|
Custom dictionary
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
@@ -62,7 +64,7 @@ to learn about the Hanyu Pinyin syllables and the syllable table.
|
|||||||
|
|
||||||
Then, write your own dictionary according to the following format:
|
Then, write your own dictionary according to the following format:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_100ask_pinyin_dict_t your_pinyin_dict[] = {
|
lv_100ask_pinyin_dict_t your_pinyin_dict[] = {
|
||||||
{ "a", "啊阿呵吖" },
|
{ "a", "啊阿呵吖" },
|
||||||
@@ -79,6 +81,7 @@ Then, write your own dictionary according to the following format:
|
|||||||
**The last item** must end with ``{null, null}``, or it will not work
|
**The last item** must end with ``{null, null}``, or it will not work
|
||||||
properly.
|
properly.
|
||||||
|
|
||||||
|
|
||||||
.. _ime_pinyin_apply_new_dictionary:
|
.. _ime_pinyin_apply_new_dictionary:
|
||||||
|
|
||||||
Apply new dictionary
|
Apply new dictionary
|
||||||
@@ -87,11 +90,12 @@ Apply new dictionary
|
|||||||
After writing a dictionary according to the above dictionary format, you
|
After writing a dictionary according to the above dictionary format, you
|
||||||
only need to call this function to set up and use your dictionary:
|
only need to call this function to set up and use your dictionary:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * pinyin_ime = lv_100ask_pinyin_ime_create(lv_screen_active());
|
lv_obj_t * pinyin_ime = lv_100ask_pinyin_ime_create(lv_screen_active());
|
||||||
lv_100ask_pinyin_ime_set_dict(pinyin_ime, your_pinyin_dict);
|
lv_100ask_pinyin_ime_set_dict(pinyin_ime, your_pinyin_dict);
|
||||||
|
|
||||||
|
|
||||||
.. _ime_pinyin_modes:
|
.. _ime_pinyin_modes:
|
||||||
|
|
||||||
Modes
|
Modes
|
||||||
@@ -108,6 +112,7 @@ The ``TEXT`` modes' layout contains buttons to change mode.
|
|||||||
To set the mode manually, use :cpp:expr:`lv_ime_pinyin_set_mode(pinyin_ime, mode)`.
|
To set the mode manually, use :cpp:expr:`lv_ime_pinyin_set_mode(pinyin_ime, mode)`.
|
||||||
The default mode is :cpp:enumerator:`LV_IME_PINYIN_MODE_K26`.
|
The default mode is :cpp:enumerator:`LV_IME_PINYIN_MODE_K26`.
|
||||||
|
|
||||||
|
|
||||||
.. _ime_pinyin_example:
|
.. _ime_pinyin_example:
|
||||||
|
|
||||||
Example
|
Example
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ Set :c:macro:`LV_USE_OBJ_ID_BUILTIN` to `0` in ``lv_conf.h``.
|
|||||||
|
|
||||||
Below APIs needed to be implemented and linked to lvgl.
|
Below APIs needed to be implemented and linked to lvgl.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void lv_obj_set_id(lv_obj_t * obj, void * id);
|
void lv_obj_set_id(lv_obj_t * obj, void * id);
|
||||||
void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
||||||
@@ -51,7 +51,7 @@ currently being constructed.
|
|||||||
Dump obj tree
|
Dump obj tree
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
Use API :cpp:expr:`lv_obj_dump_tree(lv_obj_t * obj, int depth)` to dump the object tree.
|
Use API ``lv_obj_dump_tree(lv_obj_t * obj, int depth)`` to dump the object tree.
|
||||||
It will walk through all children and print the object ID together with object address.
|
It will walk through all children and print the object ID together with object address.
|
||||||
|
|
||||||
This is useful to debug UI crash. From log we can rebuilt UI the moment before crash.
|
This is useful to debug UI crash. From log we can rebuilt UI the moment before crash.
|
||||||
@@ -62,5 +62,5 @@ From the dump log we can clearly see that the obj does not exist.
|
|||||||
Find child by ID
|
Find child by ID
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Use API :cpp:expr:`lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, void * id);` to find a child by ID.
|
Use API ``lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, void * id)`` to find a child by ID.
|
||||||
It will walk through all children and return the first child with the given ID.
|
It will walk through all children and return the first child with the given ID.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Two APIs are provided to get/set widget properties. It can be enabled by setting
|
|||||||
|
|
||||||
Set :c:macro:`LV_USE_OBJ_PROPERTY_NAME` to `1` in order to use property name instead of ID.
|
Set :c:macro:`LV_USE_OBJ_PROPERTY_NAME` to `1` in order to use property name instead of ID.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
lv_prop_id_t id;
|
lv_prop_id_t id;
|
||||||
@@ -75,7 +75,7 @@ additional code to convert values from dict, table etc to a C struct before sett
|
|||||||
Another possible use case is to ease of creating UI from lots of code. For example, you can gather
|
Another possible use case is to ease of creating UI from lots of code. For example, you can gather
|
||||||
all properties to an array now and set properties with a for loop.
|
all properties to an array now and set properties with a for loop.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_property_t props[] = {
|
lv_property_t props[] = {
|
||||||
{ .id = LV_PROPERTY_IMAGE_SRC, .ptr = &img_demo_widgets_avatar, },
|
{ .id = LV_PROPERTY_IMAGE_SRC, .ptr = &img_demo_widgets_avatar, },
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ It consists of:
|
|||||||
|
|
||||||
A typical use case looks like this:
|
A typical use case looks like this:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
//It's a global variable
|
//It's a global variable
|
||||||
lv_subject_t my_subject;
|
lv_subject_t my_subject;
|
||||||
@@ -80,14 +80,14 @@ Subject initialization
|
|||||||
|
|
||||||
Subjects have to be static or global :cpp:type:`lv_subject_t` type variables.
|
Subjects have to be static or global :cpp:type:`lv_subject_t` type variables.
|
||||||
|
|
||||||
To initialize a subject use :cpp:expr:`lv_subject_init_<type>(&subject, params, init_value)`.
|
To initialize a subject use ``lv_subject_init_<type>(&subject, params, init_value)``.
|
||||||
The following initializations exist for types:
|
The following initializations exist for types:
|
||||||
|
|
||||||
- **Integer** :cpp:expr:`void lv_subject_init_int(lv_subject_t * subject, int32_t value)`
|
- **Integer** ``void lv_subject_init_int(lv_subject_t * subject, int32_t value)``
|
||||||
- **String** :cpp:expr:`void lv_subject_init_string(lv_subject_t * subject, char * buf, char * prev_buf, size_t size, const char * value)`
|
- **String** ``void lv_subject_init_string(lv_subject_t * subject, char * buf, char * prev_buf, size_t size, const char * value)``
|
||||||
- **Pointer** :cpp:expr:`void lv_subject_init_pointer(lv_subject_t * subject, void * value)`
|
- **Pointer** ``void lv_subject_init_pointer(lv_subject_t * subject, void * value)``
|
||||||
- **Color** :cpp:expr:`void lv_subject_init_color(lv_subject_t * subject, lv_color_t color)`
|
- **Color** ``void lv_subject_init_color(lv_subject_t * subject, lv_color_t color)``
|
||||||
- **Group** :cpp:expr:`void lv_subject_init_group(lv_subject_t * subject, lv_subject_t * list[], uint32_t list_len)`
|
- **Group** ``void lv_subject_init_group(lv_subject_t * subject, lv_subject_t * list[], uint32_t list_len)``
|
||||||
|
|
||||||
|
|
||||||
Set subject value
|
Set subject value
|
||||||
@@ -95,10 +95,10 @@ Set subject value
|
|||||||
|
|
||||||
The following functions can be used to set a subject's value:
|
The following functions can be used to set a subject's value:
|
||||||
|
|
||||||
- **Integer** :cpp:expr:`void lv_subject_set_int(lv_subject_t * subject, int32_t value)`
|
- **Integer** ``void lv_subject_set_int(lv_subject_t * subject, int32_t value)``
|
||||||
- **String** :cpp:expr:`void lv_subject_copy_string(lv_subject_t * subject, char * buf)`
|
- **String** ``void lv_subject_copy_string(lv_subject_t * subject, char * buf)``
|
||||||
- **Pointer** :cpp:expr:`void lv_subject_set_pointer(lv_subject_t * subject, void * ptr)`
|
- **Pointer** ``void lv_subject_set_pointer(lv_subject_t * subject, void * ptr)``
|
||||||
- **Color** :cpp:expr:`void lv_subject_set_color(lv_subject_t * subject, lv_color_t color)`
|
- **Color** ``void lv_subject_set_color(lv_subject_t * subject, lv_color_t color)``
|
||||||
|
|
||||||
Get subject's value
|
Get subject's value
|
||||||
-------------------
|
-------------------
|
||||||
@@ -106,10 +106,10 @@ Get subject's value
|
|||||||
The following functions can be used to get a subject's value:
|
The following functions can be used to get a subject's value:
|
||||||
|
|
||||||
|
|
||||||
- **Integer** :cpp:expr:`int32_t lv_subject_get_int(lv_subject_t * subject)`
|
- **Integer** ``int32_t lv_subject_get_int(lv_subject_t * subject)``
|
||||||
- **String** :cpp:expr:`const char * lv_subject_get_string(lv_subject_t * subject)`
|
- **String** ``const char * lv_subject_get_string(lv_subject_t * subject)``
|
||||||
- **Pointer** :cpp:expr:`const void * lv_subject_get_pointer(lv_subject_t * subject)`
|
- **Pointer** ``const void * lv_subject_get_pointer(lv_subject_t * subject)``
|
||||||
- **Color** :cpp:expr:`lv_color_t lv_subject_get_color(lv_subject_t * subject)`
|
- **Color** ``lv_color_t lv_subject_get_color(lv_subject_t * subject)``
|
||||||
|
|
||||||
|
|
||||||
Get subject's previous value
|
Get subject's previous value
|
||||||
@@ -118,10 +118,10 @@ Get subject's previous value
|
|||||||
The following functions can be used to get a subject's previous value:
|
The following functions can be used to get a subject's previous value:
|
||||||
|
|
||||||
|
|
||||||
- **Integer** :cpp:expr:`int32_t lv_subject_get_previous_int(lv_subject_t * subject)`
|
- **Integer** ``int32_t lv_subject_get_previous_int(lv_subject_t * subject)``
|
||||||
- **String** :cpp:expr:`const char * lv_subject_get_previous_string(lv_subject_t * subject)`
|
- **String** ``const char * lv_subject_get_previous_string(lv_subject_t * subject)``
|
||||||
- **Pointer** :cpp:expr:`const void * lv_subject_get_previous_pointer(lv_subject_t * subject)`
|
- **Pointer** ``const void * lv_subject_get_previous_pointer(lv_subject_t * subject)``
|
||||||
- **Color** :cpp:expr:`lv_color_t lv_subject_get_previous_color(lv_subject_t * subject)`
|
- **Color** ``lv_color_t lv_subject_get_previous_color(lv_subject_t * subject)``
|
||||||
|
|
||||||
.. _observer_observer:
|
.. _observer_observer:
|
||||||
|
|
||||||
@@ -133,14 +133,14 @@ Subscribe to a subject
|
|||||||
|
|
||||||
To subscribe to a subject the following function can be used:
|
To subscribe to a subject the following function can be used:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_observer_t * observer = lv_subject_add_observer(&some_subject, some_observer_cb, user_data);
|
lv_observer_t * observer = lv_subject_add_observer(&some_subject, some_observer_cb, user_data);
|
||||||
|
|
||||||
|
|
||||||
Where the observer callback should look like this:
|
Where the observer callback should look like this:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static void some_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
|
static void some_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
|
||||||
{
|
{
|
||||||
@@ -153,14 +153,14 @@ In this case when widget is deleted, it will automatically unsubscribe from the
|
|||||||
|
|
||||||
In the observer callback :cpp:expr:`lv_observer_get_target(observer)` can be used to get the saved widget.
|
In the observer callback :cpp:expr:`lv_observer_get_target(observer)` can be used to get the saved widget.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_observer_t * observer = lv_subject_add_observer_obj(&some_subject, some_observer_cb, obj, user_data);
|
lv_observer_t * observer = lv_subject_add_observer_obj(&some_subject, some_observer_cb, obj, user_data);
|
||||||
|
|
||||||
|
|
||||||
In more generic case any pointer can be saved a target:
|
In more generic case any pointer can be saved a target:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_observer_t * observer = lv_subject_add_observer_with_target(&some_subject, some_observer_cb, some_pointer, user_data);
|
lv_observer_t * observer = lv_subject_add_observer_with_target(&some_subject, some_observer_cb, some_pointer, user_data);
|
||||||
|
|
||||||
@@ -169,16 +169,16 @@ In more generic case any pointer can be saved a target:
|
|||||||
Unsubscribe from a subject
|
Unsubscribe from a subject
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
//`observer` is the return value of `lv_subject_add_observer*`
|
/* `observer` is the return value of `lv_subject_add_observer*` */
|
||||||
lv_observer_remove(observer);
|
lv_observer_remove(observer);
|
||||||
|
|
||||||
To unsubscribe a widget from a given or all subject use:
|
To unsubscribe a widget from a given or all subject use:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_remove_from_subject(obj, subject); //`subject` can be NULL to unsubcribe from all
|
lv_obj_remove_from_subject(obj, subject); /* `subject` can be NULL to unsubcribe from all */
|
||||||
|
|
||||||
.. _observer_subject_groups:
|
.. _observer_subject_groups:
|
||||||
|
|
||||||
@@ -199,7 +199,8 @@ and it needs to know all 3 parameters to compose its text.
|
|||||||
To handle this you can create an array from some existing subjects and pass
|
To handle this you can create an array from some existing subjects and pass
|
||||||
this array as a parameter when you initialize a subject with group type.
|
this array as a parameter when you initialize a subject with group type.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static lv_subject_t * subject_list[3] = {&subject_1, &subject_2, &subject_3};
|
static lv_subject_t * subject_list[3] = {&subject_1, &subject_2, &subject_3};
|
||||||
lv_subject_init_group(&subject_all, subject_list, 3); /*The last parameter is the number of elements*/
|
lv_subject_init_group(&subject_all, subject_list, 3); /*The last parameter is the number of elements*/
|
||||||
|
|
||||||
@@ -208,7 +209,7 @@ The trick is that when any element of the group is notified the subject group wi
|
|||||||
|
|
||||||
The above Voltage/Current measurement example looks like this in the practice:
|
The above Voltage/Current measurement example looks like this in the practice:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * label = lv_label_create(lv_screen_active());
|
lv_obj_t * label = lv_label_create(lv_screen_active());
|
||||||
|
|
||||||
@@ -241,6 +242,7 @@ The above Voltage/Current measurement example looks like this in the practice:
|
|||||||
lv_label_set_text_fmt(label, "%s: %d %s", mode ? "Current" : "Voltage", value, unit);
|
lv_label_set_text_fmt(label, "%s: %d %s", mode ? "Current" : "Voltage", value, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.. _observer_widget_binding:
|
.. _observer_widget_binding:
|
||||||
|
|
||||||
Widget binding
|
Widget binding
|
||||||
@@ -251,31 +253,31 @@ Base object
|
|||||||
|
|
||||||
Set an object flag if an integer subject's value is equal to a reference value, clear the flag otherwise
|
Set an object flag if an integer subject's value is equal to a reference value, clear the flag otherwise
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
observer = lv_obj_bind_flag_if_eq(obj, &subject, LV_OBJ_FLAG_*, ref_value);
|
observer = lv_obj_bind_flag_if_eq(obj, &subject, LV_OBJ_FLAG_*, ref_value);
|
||||||
|
|
||||||
Set an object flag if an integer subject's value is not equal to a reference value, clear the flag otherwise
|
Set an object flag if an integer subject's value is not equal to a reference value, clear the flag otherwise
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
observer = lv_obj_bind_flag_if_not_eq(obj, &subject, LV_OBJ_FLAG_*, ref_value);
|
observer = lv_obj_bind_flag_if_not_eq(obj, &subject, LV_OBJ_FLAG_*, ref_value);
|
||||||
|
|
||||||
Set an object state if an integer subject's value is equal to a reference value, clear the flag otherwise
|
Set an object state if an integer subject's value is equal to a reference value, clear the flag otherwise
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
observer = lv_obj_bind_state_if_eq(obj, &subject, LV_STATE_*, ref_value);
|
observer = lv_obj_bind_state_if_eq(obj, &subject, LV_STATE_*, ref_value);
|
||||||
|
|
||||||
Set an object state if an integer subject's value is not equal to a reference value, clear the flag otherwise
|
Set an object state if an integer subject's value is not equal to a reference value, clear the flag otherwise
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
observer = lv_obj_bind_state_if_not_eq(obj, &subject, LV_STATE_*, ref_value);
|
observer = lv_obj_bind_state_if_not_eq(obj, &subject, LV_STATE_*, ref_value);
|
||||||
|
|
||||||
Set an integer subject to 1 when an object is checked and set it 0 when unchecked.
|
Set an integer subject to 1 when an object is checked and set it 0 when unchecked.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
observer = lv_obj_bind_checked(obj, &subject);
|
observer = lv_obj_bind_checked(obj, &subject);
|
||||||
|
|
||||||
@@ -286,7 +288,7 @@ Bind an integer, string, or pointer (pointing to a string) subject to a label.
|
|||||||
An optional format string can be added with 1 format specifier (e.g. ``"%d °C"``)
|
An optional format string can be added with 1 format specifier (e.g. ``"%d °C"``)
|
||||||
If the format string is ``NULL`` the value will be used directly. In this case on string and pointer type subjects can be used.
|
If the format string is ``NULL`` the value will be used directly. In this case on string and pointer type subjects can be used.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
observer = lv_label_bind_text(obj, &subject, format_string);
|
observer = lv_label_bind_text(obj, &subject, format_string);
|
||||||
|
|
||||||
@@ -296,7 +298,7 @@ Arc
|
|||||||
|
|
||||||
Bind an integer subject to an arc's value.
|
Bind an integer subject to an arc's value.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
observer = lv_arc_bind_value(obj, &subject);
|
observer = lv_arc_bind_value(obj, &subject);
|
||||||
|
|
||||||
@@ -305,7 +307,7 @@ Slider
|
|||||||
|
|
||||||
Bind an integer subject to a slider's value
|
Bind an integer subject to a slider's value
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
observer = lv_slider_bind_value(obj, &subject);
|
observer = lv_slider_bind_value(obj, &subject);
|
||||||
|
|
||||||
@@ -314,7 +316,7 @@ Roller
|
|||||||
|
|
||||||
Bind an integer subject to a roller's value
|
Bind an integer subject to a roller's value
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
observer = lv_roller_bind_value(obj, &subject);
|
observer = lv_roller_bind_value(obj, &subject);
|
||||||
|
|
||||||
@@ -323,7 +325,7 @@ Drop-down
|
|||||||
---------
|
---------
|
||||||
Bind an integer subject to a drop-down's value
|
Bind an integer subject to a drop-down's value
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
observer = lv_dropdown_bind_value(obj, &subject);
|
observer = lv_dropdown_bind_value(obj, &subject);
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ to invalidate cache by :cpp:func:`lv_image_cache_drop` before destroy the draw b
|
|||||||
|
|
||||||
Below code snippet explains usage of this API.
|
Below code snippet explains usage of this API.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void update_snapshot(lv_obj_t * obj, lv_obj_t * img_snapshot)
|
void update_snapshot(lv_obj_t * obj, lv_obj_t * img_snapshot)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ calling an "animator" function with the corresponding value parameter.
|
|||||||
|
|
||||||
The *animator* functions have the following prototype:
|
The *animator* functions have the following prototype:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void func(void * var, lv_anim_var_t value);
|
void func(void * var, lv_anim_var_t value);
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ Create an animation
|
|||||||
To create an animation an :cpp:type:`lv_anim_t` variable has to be initialized
|
To create an animation an :cpp:type:`lv_anim_t` variable has to be initialized
|
||||||
and configured with ``lv_anim_set_...()`` functions.
|
and configured with ``lv_anim_set_...()`` functions.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
|
|
||||||
/* INITIALIZE AN ANIMATION
|
/* INITIALIZE AN ANIMATION
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ RGB
|
|||||||
|
|
||||||
Create colors from Red, Green and Blue channel values:
|
Create colors from Red, Green and Blue channel values:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/*All channels are 0-255*/
|
/*All channels are 0-255*/
|
||||||
lv_color_t c = lv_color_make(red, green, blue);
|
lv_color_t c = lv_color_make(red, green, blue);
|
||||||
@@ -41,7 +41,7 @@ HSV
|
|||||||
|
|
||||||
Create colors from Hue, Saturation and Value values:
|
Create colors from Hue, Saturation and Value values:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
//h = 0..359, s = 0..100, v = 0..100
|
//h = 0..359, s = 0..100, v = 0..100
|
||||||
lv_color_t c = lv_color_hsv_to_rgb(h, s, v);
|
lv_color_t c = lv_color_hsv_to_rgb(h, s, v);
|
||||||
@@ -100,7 +100,7 @@ Modify and mix colors
|
|||||||
|
|
||||||
The following functions can modify a color:
|
The following functions can modify a color:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
// Lighten a color. 0: no change, 255: white
|
// Lighten a color. 0: no change, 255: white
|
||||||
lv_color_t c = lv_color_lighten(c, lvl);
|
lv_color_t c = lv_color_lighten(c, lvl);
|
||||||
|
|||||||
@@ -98,13 +98,13 @@ This is an internal mechanism and doesn't matter much as you use LVGL.
|
|||||||
However, there is one case in which you need to be aware of the
|
However, there is one case in which you need to be aware of the
|
||||||
implementation. If the style(s) of an object are removed by
|
implementation. If the style(s) of an object are removed by
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_remove_style_all(obj)
|
lv_obj_remove_style_all(obj)
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_remove_style(obj, NULL, LV_PART_MAIN);
|
lv_obj_remove_style(obj, NULL, LV_PART_MAIN);
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ the earlier set coordinates will be removed as well.
|
|||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/*The size of obj1 will be set back to the default in the end*/
|
/*The size of obj1 will be set back to the default in the end*/
|
||||||
lv_obj_set_size(obj1, 200, 100); /*Now obj1 has 200;100 size*/
|
lv_obj_set_size(obj1, 200, 100); /*Now obj1 has 200;100 size*/
|
||||||
@@ -133,7 +133,7 @@ Simple way
|
|||||||
|
|
||||||
To simply set the x and y coordinates of an object use:
|
To simply set the x and y coordinates of an object use:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_set_x(obj, 10); //Separate...
|
lv_obj_set_x(obj, 10); //Separate...
|
||||||
lv_obj_set_y(obj, 20);
|
lv_obj_set_y(obj, 20);
|
||||||
@@ -146,7 +146,7 @@ pixels of padding on every side the above code will place ``obj`` at
|
|||||||
|
|
||||||
Percentage values are calculated from the parent's content area size.
|
Percentage values are calculated from the parent's content area size.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_set_x(btn, lv_pct(10)); //x = 10 % of parent content area width
|
lv_obj_set_x(btn, lv_pct(10)); //x = 10 % of parent content area width
|
||||||
|
|
||||||
@@ -158,13 +158,13 @@ from the default top left. If the origin is changed e.g. to
|
|||||||
bottom-right, the (0,0) position means: align to the bottom-right
|
bottom-right, the (0,0) position means: align to the bottom-right
|
||||||
corner. To change the origin use:
|
corner. To change the origin use:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_set_align(obj, align);
|
lv_obj_set_align(obj, align);
|
||||||
|
|
||||||
To change the alignment and set new coordinates:
|
To change the alignment and set new coordinates:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_align(obj, align, x, y);
|
lv_obj_align(obj, align, x, y);
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ The following alignment options can be used:
|
|||||||
It's quite common to align a child to the center of its parent,
|
It's quite common to align a child to the center of its parent,
|
||||||
therefore a dedicated function exists:
|
therefore a dedicated function exists:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_center(obj);
|
lv_obj_center(obj);
|
||||||
|
|
||||||
@@ -196,7 +196,7 @@ children is updated automatically.
|
|||||||
The functions introduced above align the object to its parent. However,
|
The functions introduced above align the object to its parent. However,
|
||||||
it's also possible to align an object to an arbitrary reference object.
|
it's also possible to align an object to an arbitrary reference object.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_align_to(obj_to_align, reference_obj, align, x, y);
|
lv_obj_align_to(obj_to_align, reference_obj, align, x, y);
|
||||||
|
|
||||||
@@ -219,7 +219,7 @@ an object outside the reference object:
|
|||||||
For example to align a label above a button and center the label
|
For example to align a label above a button and center the label
|
||||||
horizontally:
|
horizontally:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_align_to(label, btn, LV_ALIGN_OUT_TOP_MID, 0, -10);
|
lv_obj_align_to(label, btn, LV_ALIGN_OUT_TOP_MID, 0, -10);
|
||||||
|
|
||||||
@@ -237,7 +237,7 @@ Sizing the Simple way
|
|||||||
|
|
||||||
The width and the height of an object can be set easily as well:
|
The width and the height of an object can be set easily as well:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_set_width(obj, 200); //Separate...
|
lv_obj_set_width(obj, 200); //Separate...
|
||||||
lv_obj_set_height(obj, 100);
|
lv_obj_set_height(obj, 100);
|
||||||
@@ -246,7 +246,7 @@ The width and the height of an object can be set easily as well:
|
|||||||
Percentage values are calculated based on the parent's content area
|
Percentage values are calculated based on the parent's content area
|
||||||
size. For example to set the object's height to the screen height:
|
size. For example to set the object's height to the screen height:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_set_height(obj, lv_pct(100));
|
lv_obj_set_height(obj, lv_pct(100));
|
||||||
|
|
||||||
@@ -263,7 +263,7 @@ The above functions set the size of an object's bounding box but the
|
|||||||
size of the content area can be set as well. This means an object's
|
size of the content area can be set as well. This means an object's
|
||||||
bounding box will be enlarged with the addition of padding.
|
bounding box will be enlarged with the addition of padding.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_set_content_width(obj, 50); //The actual width: padding left + 50 + padding right
|
lv_obj_set_content_width(obj, 50); //The actual width: padding left + 50 + padding right
|
||||||
lv_obj_set_content_height(obj, 30); //The actual width: padding top + 30 + padding bottom
|
lv_obj_set_content_height(obj, 30); //The actual width: padding top + 30 + padding bottom
|
||||||
@@ -271,7 +271,7 @@ bounding box will be enlarged with the addition of padding.
|
|||||||
The size of the bounding box and the content area can be retrieved with
|
The size of the bounding box and the content area can be retrieved with
|
||||||
the following functions:
|
the following functions:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
int32_t w = lv_obj_get_width(obj);
|
int32_t w = lv_obj_get_width(obj);
|
||||||
int32_t h = lv_obj_get_height(obj);
|
int32_t h = lv_obj_get_height(obj);
|
||||||
@@ -303,7 +303,7 @@ However, using styles to set the coordinates has some great advantages:
|
|||||||
|
|
||||||
Here are some examples to set an object's size using a style:
|
Here are some examples to set an object's size using a style:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static lv_style_t style;
|
static lv_style_t style;
|
||||||
lv_style_init(&style);
|
lv_style_init(&style);
|
||||||
@@ -329,7 +329,7 @@ it's pressed.
|
|||||||
One way to achieve this is by setting a new Y coordinate for the pressed
|
One way to achieve this is by setting a new Y coordinate for the pressed
|
||||||
state:
|
state:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static lv_style_t style_normal;
|
static lv_style_t style_normal;
|
||||||
lv_style_init(&style_normal);
|
lv_style_init(&style_normal);
|
||||||
@@ -352,7 +352,7 @@ This works, but it's not really flexible because the pressed coordinate
|
|||||||
is hard-coded. If the buttons are not at y=100, ``style_pressed`` won't
|
is hard-coded. If the buttons are not at y=100, ``style_pressed`` won't
|
||||||
work as expected. Translations can be used to solve this:
|
work as expected. Translations can be used to solve this:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static lv_style_t style_normal;
|
static lv_style_t style_normal;
|
||||||
lv_style_init(&style_normal);
|
lv_style_init(&style_normal);
|
||||||
@@ -402,7 +402,7 @@ transformation is "only" a visual effect.
|
|||||||
|
|
||||||
This code enlarges a button when it's pressed:
|
This code enlarges a button when it's pressed:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static lv_style_t style_pressed;
|
static lv_style_t style_pressed;
|
||||||
lv_style_init(&style_pressed);
|
lv_style_init(&style_pressed);
|
||||||
@@ -422,7 +422,7 @@ object's size from becoming smaller/larger than these values. They are
|
|||||||
especially useful if the size is set by percentage or
|
especially useful if the size is set by percentage or
|
||||||
:c:macro:`LV_SIZE_CONTENT`.
|
:c:macro:`LV_SIZE_CONTENT`.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static lv_style_t style_max_height;
|
static lv_style_t style_max_height;
|
||||||
lv_style_init(&style_max_height);
|
lv_style_init(&style_max_height);
|
||||||
@@ -434,7 +434,7 @@ especially useful if the size is set by percentage or
|
|||||||
Percentage values can be used as well which are relative to the size of
|
Percentage values can be used as well which are relative to the size of
|
||||||
the parent's content area.
|
the parent's content area.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static lv_style_t style_max_height;
|
static lv_style_t style_max_height;
|
||||||
lv_style_init(&style_max_height);
|
lv_style_init(&style_max_height);
|
||||||
@@ -491,7 +491,7 @@ Adding new layouts
|
|||||||
|
|
||||||
LVGL can be freely extended by a custom layout like this:
|
LVGL can be freely extended by a custom layout like this:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
uint32_t MY_LAYOUT;
|
uint32_t MY_LAYOUT;
|
||||||
|
|
||||||
@@ -509,7 +509,7 @@ LVGL can be freely extended by a custom layout like this:
|
|||||||
Custom style properties can be added which can be retrieved and used in
|
Custom style properties can be added which can be retrieved and used in
|
||||||
the update callback. For example:
|
the update callback. For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
uint32_t MY_PROP;
|
uint32_t MY_PROP;
|
||||||
...
|
...
|
||||||
|
|||||||
@@ -86,10 +86,10 @@ types are :ref:`Base object <lv_obj>` and :ref:`Image <lv_image>`
|
|||||||
(to create a wallpaper).
|
(to create a wallpaper).
|
||||||
|
|
||||||
To create a screen, use
|
To create a screen, use
|
||||||
:cpp:expr:`lv_obj_t * scr = lv_<type>_create(NULL)`. ``NULL`` indicates no parent.
|
``lv_obj_t * scr = lv_<type>_create(NULL)``. ``NULL`` indicates no parent.
|
||||||
|
|
||||||
To load a screen, use :cpp:expr:`lv_screen_load(scr)`. To get the active screen,
|
To load a screen, use :cpp:expr:`lv_screen_load(scr)`. To get the active screen,
|
||||||
use :cpp:expr:`lv_screen_active()`. These functions work on the default display. If
|
use :cpp:func:`lv_screen_active`. These functions work on the default display. If
|
||||||
you want to specify which display to work on, use
|
you want to specify which display to work on, use
|
||||||
:cpp:expr:`lv_display_get_screen_active(disp)` and :cpp:expr:`lv_display_load_screen(disp, scr)`. A
|
:cpp:expr:`lv_display_get_screen_active(disp)` and :cpp:expr:`lv_display_load_screen(disp, scr)`. A
|
||||||
screen can be loaded with animations too. Read more
|
screen can be loaded with animations too. Read more
|
||||||
|
|||||||
@@ -123,8 +123,8 @@ Input device events
|
|||||||
- :cpp:enumerator:`LV_EVENT_SCROLL_THROW_BEGIN`:
|
- :cpp:enumerator:`LV_EVENT_SCROLL_THROW_BEGIN`:
|
||||||
- :cpp:enumerator:`LV_EVENT_SCROLL_END`: Scrolling ends
|
- :cpp:enumerator:`LV_EVENT_SCROLL_END`: Scrolling ends
|
||||||
- :cpp:enumerator:`LV_EVENT_SCROLL`: Scrolling
|
- :cpp:enumerator:`LV_EVENT_SCROLL`: Scrolling
|
||||||
- :cpp:enumerator:`LV_EVENT_GESTURE`: A gesture is detected. Get the gesture with :cpp:expr:`lv_indev_get_gesture_dir(lv_indev_active());`
|
- :cpp:enumerator:`LV_EVENT_GESTURE`: A gesture is detected. Get the gesture with :cpp:expr:`lv_indev_get_gesture_dir(lv_indev_active())`
|
||||||
- :cpp:enumerator:`LV_EVENT_KEY`: A key is sent to the object. Get the key with :cpp:expr:`lv_indev_get_key(lv_indev_active());`
|
- :cpp:enumerator:`LV_EVENT_KEY`: A key is sent to the object. Get the key with :cpp:expr:`lv_indev_get_key(lv_indev_active())`
|
||||||
- :cpp:enumerator:`LV_EVENT_FOCUSED`: The object is focused
|
- :cpp:enumerator:`LV_EVENT_FOCUSED`: The object is focused
|
||||||
- :cpp:enumerator:`LV_EVENT_DEFOCUSED`: The object is defocused
|
- :cpp:enumerator:`LV_EVENT_DEFOCUSED`: The object is defocused
|
||||||
- :cpp:enumerator:`LV_EVENT_LEAVE`: The object is defocused but still selected
|
- :cpp:enumerator:`LV_EVENT_LEAVE`: The object is defocused but still selected
|
||||||
@@ -200,20 +200,20 @@ Sending events
|
|||||||
**************
|
**************
|
||||||
|
|
||||||
To manually send events to an object, use
|
To manually send events to an object, use
|
||||||
:cpp:expr:`lv_obj_send_event(obj, <EVENT_CODE>, &some_data)`.
|
``lv_obj_send_event(obj, <EVENT_CODE>, &some_data)``.
|
||||||
|
|
||||||
For example, this can be used to manually close a message box by
|
For example, this can be used to manually close a message box by
|
||||||
simulating a button press (although there are simpler ways to do this):
|
simulating a button press (although there are simpler ways to do this):
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/*Simulate the press of the first button (indexes start from zero)*/
|
/*Simulate the press of the first button (indexes start from zero)*/
|
||||||
uint32_t btn_id = 0;
|
uint32_t btn_id = 0;
|
||||||
lv_obj_send_event(mbox, LV_EVENT_VALUE_CHANGED, &btn_id);
|
lv_obj_send_event(mbox, LV_EVENT_VALUE_CHANGED, &btn_id);
|
||||||
|
|
||||||
The same works for display and input devices with
|
The same works for display and input devices with
|
||||||
:cpp:expr:`lv_display_send_event(obj, <EVENT_CODE>, &some_data)` and
|
``lv_display_send_event(obj, <EVENT_CODE>, &some_data)`` and
|
||||||
:cpp:expr:`lv_indev_send_event(obj, <EVENT_CODE>, &some_data)`.
|
``lv_indev_send_event(obj, <EVENT_CODE>, &some_data)``.
|
||||||
|
|
||||||
Refresh event
|
Refresh event
|
||||||
-------------
|
-------------
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ Example
|
|||||||
/*Free the font if not required anymore*/
|
/*Free the font if not required anymore*/
|
||||||
lv_binfont_destroy(my_font);
|
lv_binfont_destroy(my_font);
|
||||||
|
|
||||||
Load a Font from a Memory Buffer at Run-Time
|
Load a font from a memory buffer at run-time
|
||||||
********************************************
|
********************************************
|
||||||
|
|
||||||
:cpp:func:`lv_binfont_create_from_buffer` can be used to load a font from a memory buffer.
|
:cpp:func:`lv_binfont_create_from_buffer` can be used to load a font from a memory buffer.
|
||||||
@@ -397,8 +397,8 @@ line 1
|
|||||||
|
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
Example for a 12-px Font
|
Example for a 12px font
|
||||||
------------------------
|
-----------------------
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
|
|||||||
@@ -13,17 +13,17 @@ drive letter. For example, if an SD card is associated with the letter
|
|||||||
|
|
||||||
If you want to skip the drive prefix from the path, you can use the :c:macro:`LV_FS_DEFAULT_DRIVE_LETTER` config parameter.
|
If you want to skip the drive prefix from the path, you can use the :c:macro:`LV_FS_DEFAULT_DRIVE_LETTER` config parameter.
|
||||||
|
|
||||||
Ready-to-Use Drivers
|
Ready to use drivers
|
||||||
********************
|
********************
|
||||||
|
|
||||||
LVGL contains prepared drivers for the API of POSIX, standard C,
|
LVGL contains prepared drivers for the API of POSIX, standard C,
|
||||||
Windows, and `FATFS <http://elm-chan.org/fsw/ff/00index_e.html>`__.
|
Windows, and `FATFS <http://elm-chan.org/fsw/ff/00index_e.html>`__.
|
||||||
Learn more :ref:`here <libs_filesystem>`.
|
Learn more :ref:`here <libs_filesystem>`.
|
||||||
|
|
||||||
Adding a Driver
|
Adding a driver
|
||||||
***************
|
***************
|
||||||
|
|
||||||
Registering a Driver
|
Registering a driver
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
To add a driver, a :cpp:type:`lv_fs_drv_t` needs to be initialized like below.
|
To add a driver, a :cpp:type:`lv_fs_drv_t` needs to be initialized like below.
|
||||||
@@ -183,7 +183,7 @@ The implementation is documented below. Note that the FS functions make calls
|
|||||||
to other driver FS functions when the cache is enabled. i.e., ``lv_fs_read`` may call the driver's ``seek``
|
to other driver FS functions when the cache is enabled. i.e., ``lv_fs_read`` may call the driver's ``seek``
|
||||||
so the driver needs to implement more callbacks when the cache is enabled.
|
so the driver needs to implement more callbacks when the cache is enabled.
|
||||||
|
|
||||||
``lv_fs_read`` :sub:`(Behavior When Cache is Enabled)`
|
``lv_fs_read`` :sub:`(behavior when the cache is enabled)`
|
||||||
----------------------------------------------------------
|
----------------------------------------------------------
|
||||||
|
|
||||||
.. mermaid::
|
.. mermaid::
|
||||||
@@ -230,21 +230,21 @@ so the driver needs to implement more callbacks when the cache is enabled.
|
|||||||
--> P["copy the required bytes
|
--> P["copy the required bytes
|
||||||
to the destination buffer"]
|
to the destination buffer"]
|
||||||
|
|
||||||
``lv_fs_write`` :sub:`(Behavior When Cache is Enabled)`
|
``lv_fs_write`` :sub:`(behavior when the cache is enabled)`
|
||||||
-------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
|
|
||||||
The part of the cache that coincides with the written content
|
The part of the cache that coincides with the written content
|
||||||
will be updated to reflect the written content.
|
will be updated to reflect the written content.
|
||||||
|
|
||||||
``lv_fs_seek`` :sub:`(Behavior When Cache is Enabled)`
|
``lv_fs_seek`` :sub:`(behavior when the cache is enabled)`
|
||||||
------------------------------------------------------
|
----------------------------------------------------------
|
||||||
|
|
||||||
The driver's ``seek`` will not actually be called unless the ``whence``
|
The driver's ``seek`` will not actually be called unless the ``whence``
|
||||||
is ``LV_FS_SEEK_END``, in which case ``seek`` and ``tell`` will be called
|
is ``LV_FS_SEEK_END``, in which case ``seek`` and ``tell`` will be called
|
||||||
to determine where the end of the file is.
|
to determine where the end of the file is.
|
||||||
|
|
||||||
``lv_fs_tell`` :sub:`(Behavior When Cache is Enabled)`
|
``lv_fs_tell`` :sub:`(behavior when the cache is enabled)`
|
||||||
------------------------------------------------------
|
----------------------------------------------------------
|
||||||
|
|
||||||
The driver's ``tell`` will not actually be called.
|
The driver's ``tell`` will not actually be called.
|
||||||
|
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ Manually create an image
|
|||||||
If you are generating an image at run-time, you can craft an image
|
If you are generating an image at run-time, you can craft an image
|
||||||
variable to display it using LVGL. For example:
|
variable to display it using LVGL. For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
uint8_t my_img_data[] = {0x00, 0x01, 0x02, ...};
|
uint8_t my_img_data[] = {0x00, 0x01, 0x02, ...};
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ Use images
|
|||||||
The simplest way to use an image in LVGL is to display it with an
|
The simplest way to use an image in LVGL is to display it with an
|
||||||
:ref:`lv_image` object:
|
:ref:`lv_image` object:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * icon = lv_image_create(lv_screen_active(), NULL);
|
lv_obj_t * icon = lv_image_create(lv_screen_active(), NULL);
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ Here's an example of getting LVGL to work with PNG images.
|
|||||||
First, you need to create a new image decoder and set some functions to
|
First, you need to create a new image decoder and set some functions to
|
||||||
open/close the PNG files. It should look like this:
|
open/close the PNG files. It should look like this:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/*Create a new decoder and register functions */
|
/*Create a new decoder and register functions */
|
||||||
lv_image_decoder_t * dec = lv_image_decoder_create();
|
lv_image_decoder_t * dec = lv_image_decoder_create();
|
||||||
@@ -397,7 +397,7 @@ the decoding session and call :cpp:func:`lv_image_decoder_open`.
|
|||||||
The ``color`` parameter is used only with ``LV_COLOR_FORMAT_A1/2/4/8``
|
The ``color`` parameter is used only with ``LV_COLOR_FORMAT_A1/2/4/8``
|
||||||
images to tell color of the image.
|
images to tell color of the image.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
|
|
||||||
lv_result_t res;
|
lv_result_t res;
|
||||||
@@ -426,7 +426,7 @@ See the detailed code below:
|
|||||||
|
|
||||||
- Stride alignment and premultiply post-processing example:
|
- Stride alignment and premultiply post-processing example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/* Define post-processing state */
|
/* Define post-processing state */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -476,7 +476,7 @@ See the detailed code below:
|
|||||||
|
|
||||||
- GPU draw unit example:
|
- GPU draw unit example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void gpu_draw_image(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords)
|
void gpu_draw_image(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords)
|
||||||
{
|
{
|
||||||
@@ -573,7 +573,7 @@ LVGL to cache the image again. Otherwise, there is no easy way of
|
|||||||
detecting that the underlying file changed and LVGL will still draw the
|
detecting that the underlying file changed and LVGL will still draw the
|
||||||
old image from cache.
|
old image from cache.
|
||||||
|
|
||||||
To do this, use :cpp:expr:`lv_cache_invalidate(lv_cache_find(&my_png, LV_CACHE_SRC_TYPE_PTR, 0, 0));`.
|
To do this, use :cpp:expr:`lv_cache_invalidate(lv_cache_find(&my_png, LV_CACHE_SRC_TYPE_PTR, 0, 0))`.
|
||||||
|
|
||||||
Custom cache algorithm
|
Custom cache algorithm
|
||||||
----------------------
|
----------------------
|
||||||
@@ -581,7 +581,7 @@ Custom cache algorithm
|
|||||||
If you want to implement your own cache algorithm, you can refer to the
|
If you want to implement your own cache algorithm, you can refer to the
|
||||||
following code to replace the LVGL built-in cache manager:
|
following code to replace the LVGL built-in cache manager:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static lv_cache_entry_t * my_cache_add_cb(size_t size)
|
static lv_cache_entry_t * my_cache_add_cb(size_t size)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Cursor
|
|||||||
|
|
||||||
Pointer input devices (like a mouse) can have a cursor.
|
Pointer input devices (like a mouse) can have a cursor.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
...
|
...
|
||||||
lv_indev_t * mouse_indev = lv_indev_create();
|
lv_indev_t * mouse_indev = lv_indev_create();
|
||||||
@@ -47,7 +47,7 @@ widgets send the gestures to its parent, so finally the gestures can be
|
|||||||
detected on the screen object in a form of an :cpp:enumerator:`LV_EVENT_GESTURE`
|
detected on the screen object in a form of an :cpp:enumerator:`LV_EVENT_GESTURE`
|
||||||
event. For example:
|
event. For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void my_event(lv_event_t * e)
|
void my_event(lv_event_t * e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -66,8 +66,10 @@ There are four explicit ways to bring an object to the foreground:
|
|||||||
- Use :cpp:expr:`lv_obj_swap(obj1, obj2)` to swap the relative layer position of two objects.
|
- Use :cpp:expr:`lv_obj_swap(obj1, obj2)` to swap the relative layer position of two objects.
|
||||||
- When :cpp:expr:`lv_obj_set_parent(obj, new_parent)` is used, ``obj`` will be on the foreground of the ``new_parent``.
|
- When :cpp:expr:`lv_obj_set_parent(obj, new_parent)` is used, ``obj`` will be on the foreground of the ``new_parent``.
|
||||||
|
|
||||||
|
|
||||||
Screen-like layers
|
Screen-like layers
|
||||||
******************
|
******************
|
||||||
|
|
||||||
.. _layers_top_and_sys:
|
.. _layers_top_and_sys:
|
||||||
|
|
||||||
Top and sys layers
|
Top and sys layers
|
||||||
@@ -128,7 +130,7 @@ In this case widget will be sliced into ``LV_DRAW_SW_LAYER_SIMPLE_BUF_SIZE`` siz
|
|||||||
If there is no memory for a new chunk, LVGL will try allocating layer when another chunk is rendered and freed.
|
If there is no memory for a new chunk, LVGL will try allocating layer when another chunk is rendered and freed.
|
||||||
|
|
||||||
|
|
||||||
Transformed Layer
|
Transformed layer
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
When the widget is transformed a larger part of the widget needs to rendered to provide enough data for transformation. LVGL tries to render as small area of the widget as possible, but due to the nature of transformations no slicing is possible in this case.
|
When the widget is transformed a larger part of the widget needs to rendered to provide enough data for transformation. LVGL tries to render as small area of the widget as possible, but due to the nature of transformations no slicing is possible in this case.
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ All object types share some basic attributes:
|
|||||||
You can set/get these attributes with ``lv_obj_set_...`` and
|
You can set/get these attributes with ``lv_obj_set_...`` and
|
||||||
``lv_obj_get_...`` functions. For example:
|
``lv_obj_get_...`` functions. For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/*Set basic object attributes*/
|
/*Set basic object attributes*/
|
||||||
lv_obj_set_size(btn1, 100, 50); /*Set a button's size*/
|
lv_obj_set_size(btn1, 100, 50); /*Set a button's size*/
|
||||||
@@ -55,7 +55,7 @@ The object types have special attributes too. For example, a slider has
|
|||||||
For these special attributes, every object type may have unique API
|
For these special attributes, every object type may have unique API
|
||||||
functions. For example for a slider:
|
functions. For example for a slider:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/*Set slider specific attributes*/
|
/*Set slider specific attributes*/
|
||||||
lv_slider_set_range(slider1, 0, 100); /*Set the min. and max. values*/
|
lv_slider_set_range(slider1, 0, 100); /*Set the min. and max. values*/
|
||||||
@@ -87,7 +87,7 @@ it. Therefore, all positions are relative to the parent.
|
|||||||
|
|
||||||
.. image:: /misc/par_child1.png
|
.. image:: /misc/par_child1.png
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * parent = lv_obj_create(lv_screen_active()); /*Create a parent object on the current screen*/
|
lv_obj_t * parent = lv_obj_create(lv_screen_active()); /*Create a parent object on the current screen*/
|
||||||
lv_obj_set_size(parent, 100, 80); /*Set the size of the parent*/
|
lv_obj_set_size(parent, 100, 80); /*Set the size of the parent*/
|
||||||
@@ -99,7 +99,7 @@ Modify the position of the parent:
|
|||||||
|
|
||||||
.. image:: /misc/par_child2.png
|
.. image:: /misc/par_child2.png
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_set_pos(parent, 50, 50); /*Move the parent. The child will move with it.*/
|
lv_obj_set_pos(parent, 50, 50); /*Move the parent. The child will move with it.*/
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ outside will not be visible.
|
|||||||
|
|
||||||
.. image:: /misc/par_child3.png
|
.. image:: /misc/par_child3.png
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_set_x(obj1, -30); /*Move the child a little bit off the parent*/
|
lv_obj_set_x(obj1, -30); /*Move the child a little bit off the parent*/
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ currently attached sensors.
|
|||||||
|
|
||||||
Every widget has its own **create** function with a prototype like this:
|
Every widget has its own **create** function with a prototype like this:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * lv_<widget>_create(lv_obj_t * parent, <other parameters if any>);
|
lv_obj_t * lv_<widget>_create(lv_obj_t * parent, <other parameters if any>);
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ type.
|
|||||||
There is a common **delete** function for all object types. It deletes
|
There is a common **delete** function for all object types. It deletes
|
||||||
the object and all of its children.
|
the object and all of its children.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void lv_obj_delete(lv_obj_t * obj);
|
void lv_obj_delete(lv_obj_t * obj);
|
||||||
|
|
||||||
@@ -201,7 +201,7 @@ Create screens
|
|||||||
The screens are special objects which have no parent object. So they can
|
The screens are special objects which have no parent object. So they can
|
||||||
be created like:
|
be created like:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * scr1 = lv_obj_create(NULL);
|
lv_obj_t * scr1 = lv_obj_create(NULL);
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
Profiler
|
Profiler
|
||||||
========
|
========
|
||||||
|
|
||||||
As the complexity of the application increases, performance issues such as low FPS and frequent cache misses
|
As the complexity of the application increases, performance issues such as low FPS and frequent cache misses
|
||||||
causing lag may arise. LVGL has internally set up some hooks for performance measurement to help developers
|
causing lag may arise. LVGL has internally set up some hooks for performance measurement to help developers
|
||||||
analyze and locate performance issues.
|
analyze and locate performance issues.
|
||||||
|
|
||||||
.. _profiler_introduction:
|
.. _profiler_introduction:
|
||||||
@@ -13,10 +13,10 @@ analyze and locate performance issues.
|
|||||||
Introduction
|
Introduction
|
||||||
************
|
************
|
||||||
|
|
||||||
LVGL has a built-in trace system to track and record the timestamps of important events that occur during runtime,
|
LVGL has a built-in trace system to track and record the timestamps of important events that occur during runtime,
|
||||||
such as rendering events and user input events. These event timestamps serve as important metrics for performance analysis.
|
such as rendering events and user input events. These event timestamps serve as important metrics for performance analysis.
|
||||||
|
|
||||||
The trace system has a configurable record buffer that stores the names of event functions and their timestamps.
|
The trace system has a configurable record buffer that stores the names of event functions and their timestamps.
|
||||||
When the buffer is full, the trace system prints the log information through the provided user interface.
|
When the buffer is full, the trace system prints the log information through the provided user interface.
|
||||||
|
|
||||||
The output trace logs are formatted according to Android's `systrace <https://developer.android.com/topic/performance/tracing>`_
|
The output trace logs are formatted according to Android's `systrace <https://developer.android.com/topic/performance/tracing>`_
|
||||||
@@ -40,7 +40,7 @@ To enable the profiler, set :c:macro:`LV_USE_PROFILER` in ``lv_conf.h`` and conf
|
|||||||
|
|
||||||
- Recommended configuration in **UNIX** environments:
|
- Recommended configuration in **UNIX** environments:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -78,7 +78,7 @@ To enable the profiler, set :c:macro:`LV_USE_PROFILER` in ``lv_conf.h`` and conf
|
|||||||
|
|
||||||
- Recommended configuration in **Arduino** environments:
|
- Recommended configuration in **Arduino** environments:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void my_profiler_init(void)
|
void my_profiler_init(void)
|
||||||
{
|
{
|
||||||
@@ -91,7 +91,7 @@ To enable the profiler, set :c:macro:`LV_USE_PROFILER` in ``lv_conf.h`` and conf
|
|||||||
|
|
||||||
4. Log output configuration: LVGL uses the :cpp:func:`LV_LOG` interface by default to output trace information. If you want to use another interface to output log information (e.g., file stream), you can redirect the log output using the following code:
|
4. Log output configuration: LVGL uses the :cpp:func:`LV_LOG` interface by default to output trace information. If you want to use another interface to output log information (e.g., file stream), you can redirect the log output using the following code:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static void my_log_print_cb(const char * buf)
|
static void my_log_print_cb(const char * buf)
|
||||||
{
|
{
|
||||||
@@ -117,19 +117,19 @@ Process the logs
|
|||||||
|
|
||||||
Save the output log as `my_trace.txt`, use `trace_filter.py` for filtering and preprocessing:
|
Save the output log as `my_trace.txt`, use `trace_filter.py` for filtering and preprocessing:
|
||||||
|
|
||||||
.. code:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
./lvgl/scripts/trace_filter.py my_trace.txt
|
./lvgl/scripts/trace_filter.py my_trace.txt
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
.. code:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
python3 ./lvgl/scripts/trace_filter.py my_trace.txt
|
python3 ./lvgl/scripts/trace_filter.py my_trace.txt
|
||||||
|
|
||||||
You will obtain a processed text file named `trace.systrace`, which roughly contains the following content:
|
You will obtain a processed text file named `trace.systrace`, which roughly contains the following content:
|
||||||
|
|
||||||
.. code:: text
|
.. code-block:: text
|
||||||
|
|
||||||
# tracer: nop
|
# tracer: nop
|
||||||
#
|
#
|
||||||
@@ -153,8 +153,8 @@ If the log parsing is successful, you will see the following screen:
|
|||||||
|
|
||||||
.. image:: /misc/perfetto_ui.png
|
.. image:: /misc/perfetto_ui.png
|
||||||
|
|
||||||
In the Perfetto UI, use the :kbd:`A` or :kbd:`D` keys to pan the timeline horizontally
|
In the Perfetto UI, use the :kbd:`A` or :kbd:`D` keys to pan the timeline horizontally
|
||||||
and the :kbd:`W` or :kbd:`S` keys to zoom in or out on the timeline.
|
and the :kbd:`W` or :kbd:`S` keys to zoom in or out on the timeline.
|
||||||
Use the mouse to move the focus and click on functions on the timeline to observe their execution time.
|
Use the mouse to move the focus and click on functions on the timeline to observe their execution time.
|
||||||
|
|
||||||
Add Measurement Point
|
Add Measurement Point
|
||||||
@@ -162,7 +162,7 @@ Add Measurement Point
|
|||||||
|
|
||||||
Users can add their own measured functions:
|
Users can add their own measured functions:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void my_function_1(void)
|
void my_function_1(void)
|
||||||
{
|
{
|
||||||
@@ -198,7 +198,7 @@ If you wish to use a profiler method provided by your operating system, you can
|
|||||||
|
|
||||||
Taking `NuttX <https://github.com/apache/nuttx>`_ RTOS as an example:
|
Taking `NuttX <https://github.com/apache/nuttx>`_ RTOS as an example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
#define LV_PROFILER_INCLUDE "nuttx/sched_note.h"
|
#define LV_PROFILER_INCLUDE "nuttx/sched_note.h"
|
||||||
#define LV_PROFILER_BEGIN sched_note_begin(NOTE_TAG_ALWAYS)
|
#define LV_PROFILER_BEGIN sched_note_begin(NOTE_TAG_ALWAYS)
|
||||||
@@ -218,7 +218,7 @@ Please check the completeness of the logs. If the logs are incomplete, it may be
|
|||||||
|
|
||||||
1. Serial port reception errors caused by a high baud rate. You need to reduce the baud rate.
|
1. Serial port reception errors caused by a high baud rate. You need to reduce the baud rate.
|
||||||
2. Data corruption caused by other thread logs inserted during the printing of trace logs. You need to disable the log output of other threads or refer to the configuration above to use a separate log output interface.
|
2. Data corruption caused by other thread logs inserted during the printing of trace logs. You need to disable the log output of other threads or refer to the configuration above to use a separate log output interface.
|
||||||
3. Make sure that the string passed in by :c:macro:`LV_PROFILER_BEGIN_TAG/END_TAG` is not a local variable on the stack or a string in shared memory, because currently only the string address is recorded and the content is not copied.
|
3. Make sure that the string passed in by :c:macro:`LV_PROFILER_BEGIN_TAG` or :c:macro:`LV_PROFILER_END_TAG` is not a local variable on the stack or a string in shared memory, because currently only the string address is recorded and the content is not copied.
|
||||||
|
|
||||||
Function execution time displayed as 0s in Perfetto
|
Function execution time displayed as 0s in Perfetto
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@@ -240,3 +240,4 @@ If the trace logs are not automatically printed when the buffer is not full, you
|
|||||||
|
|
||||||
1. Reduce the value of :c:macro:`LV_PROFILER_BUILTIN_BUF_SIZE` to fill the buffer more quickly and trigger automatic printing.
|
1. Reduce the value of :c:macro:`LV_PROFILER_BUILTIN_BUF_SIZE` to fill the buffer more quickly and trigger automatic printing.
|
||||||
2. Manually call or use a timer to call the :cpp:func:`lv_profiler_builtin_flush` function to force the log output.
|
2. Manually call or use a timer to call the :cpp:func:`lv_profiler_builtin_flush` function to force the log output.
|
||||||
|
|
||||||
|
|||||||
@@ -2,57 +2,64 @@
|
|||||||
VG-Lite General GPU
|
VG-Lite General GPU
|
||||||
===================
|
===================
|
||||||
|
|
||||||
This is a generic VG-Lite rendering backend implementation that is designed to utilize
|
This is a generic VG-Lite rendering backend implementation that is designed to utilize
|
||||||
`VeriSilicon <https://verisilicon.com/>`_'s generic API to operate GPU hardware as much as possible.
|
`VeriSilicon <https://verisilicon.com/>`_'s generic API to operate GPU hardware as much as possible.
|
||||||
|
|
||||||
Even with different chip manufacturers, as long as they use the same version of VG-Lite API as the rendering backend,
|
Even with different chip manufacturers, as long as they use the same version of VG-Lite API as the rendering backend,
|
||||||
LVGL rendering acceleration can be supported without the need for LVGL adaptation work.
|
LVGL rendering acceleration can be supported without the need for LVGL adaptation work.
|
||||||
|
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
*************
|
*************
|
||||||
|
|
||||||
1. Set :c:macro:`LV_USE_DRAW_VG_LITE` to 1 in ``lv_conf.h`` to enabled the VG-Lite rendering backend.
|
1. Set :c:macro:`LV_USE_DRAW_VG_LITE` to 1 in ``lv_conf.h`` to enabled the VG-Lite rendering backend.
|
||||||
Make sure that your hardware has been adapted to the VG-Lite API and that the absolute path to ``vg_lite.h``, which can be directly referenced by lvgl, has been exposed.
|
Make sure that your hardware has been adapted to the VG-Lite API and that the absolute path to ``vg_lite.h``, which can be directly referenced by lvgl, has been exposed.
|
||||||
|
|
||||||
2. Confirm the GPU initialization method, there are two ways:
|
2. Confirm the GPU initialization method, there are two ways:
|
||||||
- The SDK calls the GPU initialization function on its own during system startup, and the GPU is available when LVGL starts; set :c:macro:`LV_VG_LITE_USE_GPU_INIT` to 0.
|
|
||||||
- LVGL actively calls the GPU initialization function, and the SDK needs to implement the public function `gpu_init()`.
|
- The SDK calls the GPU initialization function on its own during system startup, and the GPU is available when LVGL starts; set :c:macro:`LV_VG_LITE_USE_GPU_INIT` to 0.
|
||||||
LVGL will call it to complete the GPU hardware initialization during startup; set :c:macro:`LV_VG_LITE_USE_GPU_INIT` to 1.
|
- LVGL actively calls the GPU initialization function, and the SDK needs to implement the public function `gpu_init()`.
|
||||||
|
LVGL will call it to complete the GPU hardware initialization during startup; set :c:macro:`LV_VG_LITE_USE_GPU_INIT` to 1.
|
||||||
|
|
||||||
3. Set the :c:macro:`LV_VG_LITE_USE_ASSERT` configuration to enable GPU call parameter checking.
|
3. Set the :c:macro:`LV_VG_LITE_USE_ASSERT` configuration to enable GPU call parameter checking.
|
||||||
Due to the complexity of the parameters used in GPU calls, incorrect parameters can result in abnormal GPU hardware operation, such as forgetting to add an end symbol
|
Due to the complexity of the parameters used in GPU calls, incorrect parameters can result in abnormal GPU hardware operation, such as forgetting to add an end symbol
|
||||||
to the path or not meeting the alignment requirements for buffer stride.
|
to the path or not meeting the alignment requirements for buffer stride.
|
||||||
To quickly resolve such issues, strict parameter checking has been added before each VG-Lite call, including buffer stride validation and matrix invertibility check.
|
To quickly resolve such issues, strict parameter checking has been added before each VG-Lite call, including buffer stride validation and matrix invertibility check.
|
||||||
When an error parameter is detected, an assertion will occur to print out the error parameter, allowing the user to promptly make corrections and reduce the time wasted on hardware simulation.
|
When an error parameter is detected, an assertion will occur to print out the error parameter, allowing the user to promptly make corrections and reduce the time wasted on hardware simulation.
|
||||||
Please note that enabling this check will decrease runtime performance. It is recommended to enable it in Debug mode and disable it in the Release version.
|
Please note that enabling this check will decrease runtime performance. It is recommended to enable it in Debug mode and disable it in the Release version.
|
||||||
|
|
||||||
4. Set the :c:macro:`LV_VG_LITE_FLUSH_MAX_COUNT` configuration to specify the flush method.
|
4. Set the :c:macro:`LV_VG_LITE_FLUSH_MAX_COUNT` configuration to specify the flush method.
|
||||||
VG-Lite uses two sets of command buffer buffers to render instructions, and utilizing this mechanism well can greatly improve drawing efficiency.
|
VG-Lite uses two sets of command buffer buffers to render instructions, and utilizing this mechanism well can greatly improve drawing efficiency.
|
||||||
Currently, two buffering methods are supported:
|
Currently, two buffering methods are supported:
|
||||||
- Set :c:macro:`LV_VG_LITE_FLUSH_MAX_COUNT` to zero (recommended). The rendering backend will obtain the GPU's working status every time it writes rendering instructions to the command buffer.
|
|
||||||
When the GPU is idle, it will immediately call ``vg_lite_flush`` to notify the GPU to start rendering and swap the command buffer. When the GPU is busy, it will continue to fill the command buffer cache with rendering instructions.
|
- Set :c:macro:`LV_VG_LITE_FLUSH_MAX_COUNT` to zero (recommended). The rendering backend will obtain the GPU's working status every time it writes rendering instructions to the command buffer.
|
||||||
The underlying driver will automatically determine if the command buffer has been filled. When it is about to be filled, it will forcibly wait for the unfinished drawing tasks to end and swap the command buffer.
|
|
||||||
This method can effectively improve GPU utilization, especially in scenarios where rendering text, as the GPU's drawing time and the CPU's data preparation time are very close, allowing the CPU and GPU to run in parallel.
|
When the GPU is idle, it will immediately call ``vg_lite_flush`` to notify the GPU to start rendering and swap the command buffer. When the GPU is busy, it will continue to fill the command buffer cache with rendering instructions.
|
||||||
- Set :c:macro:`LV_VG_LITE_FLUSH_MAX_COUNT` to a value greater than zero, such as 8. After writing 8 rendering instructions to the command buffer, the rendering backend
|
The underlying driver will automatically determine if the command buffer has been filled. When it is about to be filled, it will forcibly wait for the unfinished drawing tasks to end and swap the command buffer.
|
||||||
will call ``vg_lite_flush`` to notify the GPU to start rendering and swap the command buffer.
|
This method can effectively improve GPU utilization, especially in scenarios where rendering text, as the GPU's drawing time and the CPU's data preparation time are very close, allowing the CPU and GPU to run in parallel.
|
||||||
|
|
||||||
|
- Set :c:macro:`LV_VG_LITE_FLUSH_MAX_COUNT` to a value greater than zero, such as 8. After writing 8 rendering instructions to the command buffer, the rendering backend
|
||||||
|
|
||||||
|
will call ``vg_lite_flush`` to notify the GPU to start rendering and swap the command buffer.
|
||||||
|
|
||||||
5. Set the :c:macro:`LV_VG_LITE_USE_BOX_SHADOW` configuration to use GPU rendering for shadows.
|
5. Set the :c:macro:`LV_VG_LITE_USE_BOX_SHADOW` configuration to use GPU rendering for shadows.
|
||||||
In fact, GPU hardware does not actually support shadow rendering. However, through experimentation, it has been found that a similar shadow effect
|
In fact, GPU hardware does not actually support shadow rendering. However, through experimentation, it has been found that a similar shadow effect
|
||||||
can be achieved by using multiple layers of borders with different levels of transparency.
|
can be achieved by using multiple layers of borders with different levels of transparency.
|
||||||
It is recommended to enable this configuration in scenarios where the shadow quality requirements are not high, as it can significantly improve rendering efficiency.
|
It is recommended to enable this configuration in scenarios where the shadow quality requirements are not high, as it can significantly improve rendering efficiency.
|
||||||
|
|
||||||
6. Set the :c:macro:`LV_VG_LITE_GRAD_CACHE_CNT` configuration to specify the number of gradient cache entries.
|
6. Set the :c:macro:`LV_VG_LITE_GRAD_CACHE_CNT` configuration to specify the number of gradient cache entries.
|
||||||
Gradient drawing includes linear gradients and radial gradients. Using a cache can effectively reduce the number of times the gradient image is created and improve drawing efficiency.
|
Gradient drawing includes linear gradients and radial gradients. Using a cache can effectively reduce the number of times the gradient image is created and improve drawing efficiency.
|
||||||
Each individual gradient consumes around 4K of GPU memory pool. If there are many gradients used in the interface, you can try increasing the number of gradient cache entries.
|
Each individual gradient consumes around 4K of GPU memory pool. If there are many gradients used in the interface, you can try increasing the number of gradient cache entries.
|
||||||
If the VG-Lite API returns the :c:macro:`VG_LITE_OUT_OF_RESOURCES` error, you can try increasing the size of the GPU memory pool or reducing the number of gradient cache entries.
|
If the VG-Lite API returns the :c:macro:`VG_LITE_OUT_OF_RESOURCES` error, you can try increasing the size of the GPU memory pool or reducing the number of gradient cache entries.
|
||||||
|
|
||||||
7. Set the :c:macro:`LV_VG_LITE_STROKE_CACHE_CNT` configuration to specify the number of stroke path caches.
|
7. Set the :c:macro:`LV_VG_LITE_STROKE_CACHE_CNT` configuration to specify the number of stroke path caches.
|
||||||
When the stroke parameters do not change, the previously generated stroke parameters are automatically retrieved from the cache to improve rendering performance.
|
When the stroke parameters do not change, the previously generated stroke parameters are automatically retrieved from the cache to improve rendering performance.
|
||||||
The memory occupied by the stroke is strongly related to the path length. If the VG-Lite API returns the :c:macro:`VG_LITE_OUT_OF_RESOURCES` error,
|
The memory occupied by the stroke is strongly related to the path length. If the VG-Lite API returns the :c:macro:`VG_LITE_OUT_OF_RESOURCES` error,
|
||||||
you can try increasing the size of the GPU memory pool or reducing the number of stroke cache entries.
|
you can try increasing the size of the GPU memory pool or reducing the number of stroke cache entries.
|
||||||
|
|
||||||
NOTE: VG-Lite rendering backend does not support multi-threaded calls, please make sure :c:macro:`LV_USE_OS` is always configured as :c:macro:`LV_OS_NONE`.
|
NOTE: VG-Lite rendering backend does not support multi-threaded calls, please make sure :c:macro:`LV_USE_OS` is always configured as :c:macro:`LV_OS_NONE`.
|
||||||
|
|
||||||
|
|
||||||
VG-Lite Simulator
|
VG-Lite Simulator
|
||||||
*****************
|
*****************
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ The scrollbars have their own dedicated part, called
|
|||||||
:cpp:enumerator:`LV_PART_SCROLLBAR`. For example a scrollbar can turn to red like
|
:cpp:enumerator:`LV_PART_SCROLLBAR`. For example a scrollbar can turn to red like
|
||||||
this:
|
this:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static lv_style_t style_red;
|
static lv_style_t style_red;
|
||||||
lv_style_init(&style_red);
|
lv_style_init(&style_red);
|
||||||
@@ -55,7 +55,7 @@ scrolled. This allows adding different styles to the scrollbar or the
|
|||||||
object itself when scrolled. This code makes the scrollbar blue when the
|
object itself when scrolled. This code makes the scrollbar blue when the
|
||||||
object is scrolled:
|
object is scrolled:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static lv_style_t style_blue;
|
static lv_style_t style_blue;
|
||||||
lv_style_init(&style_blue);
|
lv_style_init(&style_blue);
|
||||||
@@ -219,7 +219,7 @@ element, either to restore it later, or to display dynamically some
|
|||||||
elements according to the current scroll. Here is an example to see how
|
elements according to the current scroll. Here is an example to see how
|
||||||
to combine scroll event and store the scroll top position.
|
to combine scroll event and store the scroll top position.
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static int scroll_value = 0;
|
static int scroll_value = 0;
|
||||||
|
|
||||||
@@ -262,7 +262,7 @@ larger self size will too.
|
|||||||
LVGL uses the :cpp:enumerator:`LV_EVENT_GET_SELF_SIZE` event to get the self size of
|
LVGL uses the :cpp:enumerator:`LV_EVENT_GET_SELF_SIZE` event to get the self size of
|
||||||
an object. Here is an example to see how to handle the event:
|
an object. Here is an example to see how to handle the event:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
if(event_code == LV_EVENT_GET_SELF_SIZE) {
|
if(event_code == LV_EVENT_GET_SELF_SIZE) {
|
||||||
lv_point_t * p = lv_event_get_param(e);
|
lv_point_t * p = lv_event_get_param(e);
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ be added or changed.
|
|||||||
Property set functions looks like this:
|
Property set functions looks like this:
|
||||||
``lv_style_set_<property_name>(&style, <value>);`` For example:
|
``lv_style_set_<property_name>(&style, <value>);`` For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
static lv_style_t style_btn;
|
static lv_style_t style_btn;
|
||||||
lv_style_init(&style_btn);
|
lv_style_init(&style_btn);
|
||||||
@@ -210,13 +210,13 @@ Property set functions looks like this:
|
|||||||
|
|
||||||
To remove a property use:
|
To remove a property use:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_style_remove_prop(&style, LV_STYLE_BG_COLOR);
|
lv_style_remove_prop(&style, LV_STYLE_BG_COLOR);
|
||||||
|
|
||||||
To get a property's value from a style:
|
To get a property's value from a style:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_style_value_t v;
|
lv_style_value_t v;
|
||||||
lv_result_t res = lv_style_get_prop(&style, LV_STYLE_BG_COLOR, &v);
|
lv_result_t res = lv_style_get_prop(&style, LV_STYLE_BG_COLOR, &v);
|
||||||
@@ -232,13 +232,13 @@ To get a property's value from a style:
|
|||||||
|
|
||||||
To reset a style (free all its data) use:
|
To reset a style (free all its data) use:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_style_reset(&style);
|
lv_style_reset(&style);
|
||||||
|
|
||||||
Styles can be built as ``const`` too to save RAM:
|
Styles can be built as ``const`` too to save RAM:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
const lv_style_const_prop_t style1_props[] = {
|
const lv_style_const_prop_t style1_props[] = {
|
||||||
LV_STYLE_CONST_WIDTH(50),
|
LV_STYLE_CONST_WIDTH(50),
|
||||||
@@ -275,7 +275,7 @@ examples:
|
|||||||
|
|
||||||
Using :cpp:func:`lv_obj_add_style`:
|
Using :cpp:func:`lv_obj_add_style`:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_add_style(btn, &style_btn, 0); /*Default button style*/
|
lv_obj_add_style(btn, &style_btn, 0); /*Default button style*/
|
||||||
lv_obj_add_style(btn, &btn_red, LV_STATE_PRESSED); /*Overwrite only some colors to red when pressed*/
|
lv_obj_add_style(btn, &btn_red, LV_STATE_PRESSED); /*Overwrite only some colors to red when pressed*/
|
||||||
@@ -296,7 +296,7 @@ place.
|
|||||||
|
|
||||||
Using :cpp:func:`lv_obj_replace_style`:
|
Using :cpp:func:`lv_obj_replace_style`:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_add_style(btn, &style_btn, 0); /*Add a button style*/
|
lv_obj_add_style(btn, &style_btn, 0); /*Add a button style*/
|
||||||
lv_obj_replace_style(btn, &style_btn, &new_style_btn, 0); /*Replace the button style with a different one*/
|
lv_obj_replace_style(btn, &style_btn, &new_style_btn, 0); /*Replace the button style with a different one*/
|
||||||
@@ -341,7 +341,7 @@ To get a final value of property
|
|||||||
These functions use the object's current state and if no better candidate exists they return a default value.
|
These functions use the object's current state and if no better candidate exists they return a default value.
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_color_t color = lv_obj_get_style_bg_color(btn, LV_PART_MAIN);
|
lv_color_t color = lv_obj_get_style_bg_color(btn, LV_PART_MAIN);
|
||||||
|
|
||||||
@@ -365,7 +365,7 @@ Unlike in CSS, LVGL local styles can be assigned to states
|
|||||||
To set a local property use functions like
|
To set a local property use functions like
|
||||||
``lv_obj_set_style_<property_name>(obj, <value>, <selector>);`` For example:
|
``lv_obj_set_style_<property_name>(obj, <value>, <selector>);`` For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_set_style_bg_color(slider, lv_color_red(), LV_PART_INDICATOR | LV_STATE_FOCUSED);
|
lv_obj_set_style_bg_color(slider, lv_color_red(), LV_PART_INDICATOR | LV_STATE_FOCUSED);
|
||||||
|
|
||||||
@@ -422,7 +422,7 @@ going back to default slowly.
|
|||||||
To describe a transition an :cpp:struct:`lv_transition_dsc_t` variable needs to be
|
To describe a transition an :cpp:struct:`lv_transition_dsc_t` variable needs to be
|
||||||
initialized and added to a style:
|
initialized and added to a style:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/*Only its pointer is saved so must static, global or dynamically allocated */
|
/*Only its pointer is saved so must static, global or dynamically allocated */
|
||||||
static const lv_style_prop_t trans_props[] = {
|
static const lv_style_prop_t trans_props[] = {
|
||||||
@@ -498,7 +498,7 @@ To set a theme for a display, two steps are required:
|
|||||||
Theme initialization functions can have different prototypes. This
|
Theme initialization functions can have different prototypes. This
|
||||||
example shows how to set the "default" theme:
|
example shows how to set the "default" theme:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_theme_t * th = lv_theme_default_init(display, /*Use the DPI, size, etc from this display*/
|
lv_theme_t * th = lv_theme_default_init(display, /*Use the DPI, size, etc from this display*/
|
||||||
LV_COLOR_PALETTE_BLUE, LV_COLOR_PALETTE_CYAN, /*Primary and secondary palette*/
|
LV_COLOR_PALETTE_BLUE, LV_COLOR_PALETTE_CYAN, /*Primary and secondary palette*/
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ prototype.
|
|||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void my_timer(lv_timer_t * timer)
|
void my_timer(lv_timer_t * timer)
|
||||||
{
|
{
|
||||||
@@ -117,7 +117,7 @@ clear all asynchronous calls matching ``my_function`` and ``data_p``.
|
|||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void my_screen_clean_up(void * scr)
|
void my_screen_clean_up(void * scr)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ It's very important that draw buffer(s) should be large enough for any
|
|||||||
selected color format.
|
selected color format.
|
||||||
|
|
||||||
|
|
||||||
Swap Endianness
|
Swap endianness
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
In case of RGB565 color format it might be required to swap the 2 bytes
|
In case of RGB565 color format it might be required to swap the 2 bytes
|
||||||
@@ -350,7 +350,8 @@ Further reading
|
|||||||
|
|
||||||
- `lv_port_disp_template.c <https://github.com/lvgl/lvgl/blob/master/examples/porting/lv_port_disp_template.c>`__
|
- `lv_port_disp_template.c <https://github.com/lvgl/lvgl/blob/master/examples/porting/lv_port_disp_template.c>`__
|
||||||
for a template for your own driver.
|
for a template for your own driver.
|
||||||
- :ref:`Drawing <porting_draw>` to learn more about how rendering works in LVGL.
|
- :ref:`Drawing <porting_draw>` to learn more about how rendering
|
||||||
|
works in LVGL.
|
||||||
- :ref:`display_features` to learn more about higher
|
- :ref:`display_features` to learn more about higher
|
||||||
level display features.
|
level display features.
|
||||||
|
|
||||||
|
|||||||
@@ -62,11 +62,15 @@ Hierarchy of modules
|
|||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
All these together looks like this
|
All these together looks like this
|
||||||
|
|
||||||
- list of draw units
|
- list of draw units
|
||||||
- display(s)
|
- display(s)
|
||||||
|
|
||||||
- layer(s): Each display has its own list of layers
|
- layer(s): Each display has its own list of layers
|
||||||
|
|
||||||
- draw tasks: Each layer has its own list of draw tasks
|
- draw tasks: Each layer has its own list of draw tasks
|
||||||
|
|
||||||
|
|
||||||
References
|
References
|
||||||
**********
|
**********
|
||||||
|
|
||||||
|
|||||||
@@ -82,10 +82,12 @@ The final diff is calculated like this:
|
|||||||
|
|
||||||
``diff_final = diff_in * (indev_sensitivity / 256) + (widget_sensitivity / 256);``
|
``diff_final = diff_in * (indev_sensitivity / 256) + (widget_sensitivity / 256);``
|
||||||
|
|
||||||
|
|
||||||
For example, if both the indev and widget sensitivity is set to 128 (0.5), the input diff. will be
|
For example, if both the indev and widget sensitivity is set to 128 (0.5), the input diff. will be
|
||||||
multiplied by 0.25 (divided by 4). The value of the widget will be incremented by this value or
|
multiplied by 0.25 (divided by 4). The value of the widget will be incremented by this value or
|
||||||
the widget will be scrolled this amount of pixels.
|
the widget will be scrolled this amount of pixels.
|
||||||
|
|
||||||
|
|
||||||
Keypad or keyboard
|
Keypad or keyboard
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
@@ -150,7 +152,7 @@ added to groups.
|
|||||||
else data->state = LV_INDEV_STATE_RELEASED;
|
else data->state = LV_INDEV_STATE_RELEASED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Using Buttons with Encoder Logic
|
Using buttons with Encoder logic
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
In addition to standard encoder behavior, you can also utilize its logic
|
In addition to standard encoder behavior, you can also utilize its logic
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ can register a "logger" callback with :cpp:func:`lv_log_register_print_cb`.
|
|||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void my_log_cb(lv_log_level_t level, const char * buf)
|
void my_log_cb(lv_log_level_t level, const char * buf)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ than ``LV_OS_NONE``.
|
|||||||
|
|
||||||
Here is some pseudocode to illustrate the concept:
|
Here is some pseudocode to illustrate the concept:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void lvgl_thread(void)
|
void lvgl_thread(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ LVGL also supports ``make`` and ``CMake`` build systems out of the box.
|
|||||||
To add LVGL to your Makefile based build system add these lines to your
|
To add LVGL to your Makefile based build system add these lines to your
|
||||||
main Makefile:
|
main Makefile:
|
||||||
|
|
||||||
.. code:: make
|
.. code-block:: make
|
||||||
|
|
||||||
LVGL_DIR_NAME ?= lvgl #The name of the lvgl folder (change this if you have renamed it)
|
LVGL_DIR_NAME ?= lvgl #The name of the lvgl folder (change this if you have renamed it)
|
||||||
LVGL_DIR ?= ${shell pwd} #The path where the lvgl folder is
|
LVGL_DIR ?= ${shell pwd} #The path where the lvgl folder is
|
||||||
@@ -113,7 +113,7 @@ in TLS (Thread Local Storage).
|
|||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_global_t * lv_global_default(void)
|
lv_global_t * lv_global_default(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Sleep management
|
|||||||
The MCU can go to sleep when no user input happens. In this case, the
|
The MCU can go to sleep when no user input happens. In this case, the
|
||||||
main ``while(1)`` should look like this:
|
main ``while(1)`` should look like this:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
/*Normal operation (no sleep) in < 1 sec inactivity*/
|
/*Normal operation (no sleep) in < 1 sec inactivity*/
|
||||||
@@ -23,7 +23,7 @@ main ``while(1)`` should look like this:
|
|||||||
You should also add the following lines to your input device read
|
You should also add the following lines to your input device read
|
||||||
function to signal a wake-up (press, touch or click etc.) has happened:
|
function to signal a wake-up (press, touch or click etc.) has happened:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_tick_inc(LV_DEF_REFR_PERIOD); /*Force task execution on wake-up*/
|
lv_tick_inc(LV_DEF_REFR_PERIOD); /*Force task execution on wake-up*/
|
||||||
timer_start(); /*Restart the timer where lv_tick_inc() is called*/
|
timer_start(); /*Restart the timer where lv_tick_inc() is called*/
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ The ticks (milliseconds) should be independent from any other activities of the
|
|||||||
|
|
||||||
For example this works, but LVGL's timing will be incorrect as the execution time of ``lv_timer_handler`` is not considered:
|
For example this works, but LVGL's timing will be incorrect as the execution time of ``lv_timer_handler`` is not considered:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
// Bad idea
|
// Bad idea
|
||||||
lv_timer_handler();
|
lv_timer_handler();
|
||||||
lv_tick_inc(5);
|
lv_tick_inc(5);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ periodically in one of the following:
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
uint32_t time_till_next = lv_timer_handler();
|
uint32_t time_till_next = lv_timer_handler();
|
||||||
@@ -24,7 +24,7 @@ If you want to use :cpp:func:`lv_timer_handler` in a super-loop, a helper
|
|||||||
function :cpp:func:`lv_timer_handler_run_in_period` is provided to simplify
|
function :cpp:func:`lv_timer_handler_run_in_period` is provided to simplify
|
||||||
the porting:
|
the porting:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
...
|
...
|
||||||
@@ -34,7 +34,7 @@ the porting:
|
|||||||
|
|
||||||
Or use the sleep time automatically calculated by LVGL:
|
Or use the sleep time automatically calculated by LVGL:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
...
|
...
|
||||||
@@ -45,7 +45,7 @@ Or use the sleep time automatically calculated by LVGL:
|
|||||||
In an OS environment, you can use it together with the **delay** or
|
In an OS environment, you can use it together with the **delay** or
|
||||||
**sleep** provided by OS to release CPU whenever possible:
|
**sleep** provided by OS to release CPU whenever possible:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
uint32_t time_till_next = lv_timer_handler();
|
uint32_t time_till_next = lv_timer_handler();
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ unintended behavior.
|
|||||||
To make the arc non-adjustable, remove the style of the knob and make
|
To make the arc non-adjustable, remove the style of the knob and make
|
||||||
the object non-clickable:
|
the object non-clickable:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_remove_style(arc, NULL, LV_PART_KNOB);
|
lv_obj_remove_style(arc, NULL, LV_PART_KNOB);
|
||||||
lv_obj_remove_flag(arc, LV_OBJ_FLAG_CLICKABLE);
|
lv_obj_remove_flag(arc, LV_OBJ_FLAG_CLICKABLE);
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ Button's text
|
|||||||
There is a text on each button. To specify them a descriptor string
|
There is a text on each button. To specify them a descriptor string
|
||||||
array, called *map*, needs to be used. The map can be set with
|
array, called *map*, needs to be used. The map can be set with
|
||||||
:cpp:expr:`lv_buttonmatrix_set_map(buttonm, my_map)`. The declaration of a map should
|
:cpp:expr:`lv_buttonmatrix_set_map(buttonm, my_map)`. The declaration of a map should
|
||||||
look like :cpp:expr:`const char * map[] = {"button1", "button2", "button3", NULL}`. Note
|
look like ``const char * map[] = {"button1", "button2", "button3", NULL}``. Note
|
||||||
that the last element has to be either ``NULL`` or an empty string
|
that the last element has to be either ``NULL`` or an empty string
|
||||||
(``""``)!
|
(``""``)!
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ lvgl's drawing engine.
|
|||||||
Parts and Styles
|
Parts and Styles
|
||||||
****************
|
****************
|
||||||
|
|
||||||
- :cpp:enumerator:`LV_PART_MAIN` Uses the typical rectangle style properties and image
|
- :cpp:enumerator:`LV_PART_MAIN` Uses the typical rectangle style properties and image
|
||||||
style properties.
|
style properties.
|
||||||
|
|
||||||
.. _lv_canvas_usage:
|
.. _lv_canvas_usage:
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ Check, uncheck, disable
|
|||||||
You can manually check, un-check, and disable the Checkbox by using the
|
You can manually check, un-check, and disable the Checkbox by using the
|
||||||
common state add/clear function:
|
common state add/clear function:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_add_state(cb, LV_STATE_CHECKED); /*Make the checkbox checked*/
|
lv_obj_add_state(cb, LV_STATE_CHECKED); /*Make the checkbox checked*/
|
||||||
lv_obj_remove_state(cb, LV_STATE_CHECKED); /*Make the checkbox unchecked*/
|
lv_obj_remove_state(cb, LV_STATE_CHECKED); /*Make the checkbox unchecked*/
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ List
|
|||||||
The list is hidden/shown on open/close. To add styles to it use
|
The list is hidden/shown on open/close. To add styles to it use
|
||||||
:cpp:expr:`lv_dropdown_get_list(dropdown)` to get the list object. For example:
|
:cpp:expr:`lv_dropdown_get_list(dropdown)` to get the list object. For example:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_t * list = lv_dropdown_get_list(dropdown) /*Get the list*/
|
lv_obj_t * list = lv_dropdown_get_list(dropdown) /*Get the list*/
|
||||||
lv_obj_add_style(list, &my_style, selector) /*Add the styles to the list*/
|
lv_obj_add_style(list, &my_style, selector) /*Add the styles to the list*/
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ To set the source of an image, use :cpp:expr:`lv_image_set_src(img, src)`.
|
|||||||
To generate a pixel array from a PNG, JPG or BMP image, use the `Online image converter tool <https://lvgl.io/tools/imageconverter>`__
|
To generate a pixel array from a PNG, JPG or BMP image, use the `Online image converter tool <https://lvgl.io/tools/imageconverter>`__
|
||||||
and set the converted image with its pointer :cpp:expr:`lv_image_set_src(img1, &converted_img_var)`
|
and set the converted image with its pointer :cpp:expr:`lv_image_set_src(img1, &converted_img_var)`
|
||||||
To make the variable visible in the C file, you need to declare it with
|
To make the variable visible in the C file, you need to declare it with
|
||||||
:cpp:expr:`LV_IMAGE_DECLARE(converted_img_var)`.
|
:c:macro:`LV_IMAGE_DECLARE(converted_img_var)`.
|
||||||
|
|
||||||
To use external files, you also need to convert the image files using
|
To use external files, you also need to convert the image files using
|
||||||
the online converter tool but now you should select the binary output
|
the online converter tool but now you should select the binary output
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ Widgets
|
|||||||
buttonmatrix
|
buttonmatrix
|
||||||
calendar
|
calendar
|
||||||
chart
|
chart
|
||||||
colorwheel
|
|
||||||
canvas
|
canvas
|
||||||
checkbox
|
checkbox
|
||||||
dropdown
|
dropdown
|
||||||
|
|||||||
@@ -33,11 +33,11 @@ Dependencies
|
|||||||
------------
|
------------
|
||||||
|
|
||||||
The Lottie widget uses the `ThorVG <https://github.com/thorvg/thorvg>`__ library which is `integrated into LVGL <https://github.com/lvgl/lvgl/tree/master/src/libs/thorvg>`__.
|
The Lottie widget uses the `ThorVG <https://github.com/thorvg/thorvg>`__ library which is `integrated into LVGL <https://github.com/lvgl/lvgl/tree/master/src/libs/thorvg>`__.
|
||||||
In order to use Lottie animations ``LV_USE_THORVG_INTERNAL`` (to use the built-in ThorVG) or
|
In order to use Lottie animations :c:macro:`LV_USE_THORVG_INTERNAL` (to use the built-in ThorVG) or
|
||||||
``LV_USE_THORVG_EXTERNAL`` (to link it externally) needs to enabled. For vector graphics in general
|
:c:macro:`LV_USE_THORVG_EXTERNAL` (to link it externally) needs to enabled. For vector graphics in general
|
||||||
``LV_USE_VECTOR_GRAPHIC`` also needs to be enabled.
|
:c:macro:`LV_USE_VECTOR_GRAPHIC` also needs to be enabled.
|
||||||
|
|
||||||
As ThorVG is written in C++, when using ``LV_USE_THORVG_INTERNAL`` be sure that you
|
As ThorVG is written in C++, when using :c:macro:`LV_USE_THORVG_INTERNAL` be sure that you
|
||||||
can compile the cpp files.
|
can compile the cpp files.
|
||||||
|
|
||||||
Set a buffer
|
Set a buffer
|
||||||
@@ -50,10 +50,10 @@ The animations are rendered in ARGB8888 format, therefor the buffer's size shoul
|
|||||||
To keep the buffer size and the animation size consistent,
|
To keep the buffer size and the animation size consistent,
|
||||||
the size of the widget (i.e. the size of the animation) is set to the dimensions of the buffer internally.
|
the size of the widget (i.e. the size of the animation) is set to the dimensions of the buffer internally.
|
||||||
|
|
||||||
The buffer can be set with either :cpp:expr:`void lv_lottie_set_buffer(lottie, w, h, buf);`
|
The buffer can be set with either :cpp:expr:`lv_lottie_set_buffer(lottie, w, h, buf)`
|
||||||
or :cpp:expr:`lv_lottie_set_draw_buf(lottie, draw_buf)`.
|
or :cpp:expr:`lv_lottie_set_draw_buf(lottie, draw_buf)`.
|
||||||
|
|
||||||
When a draw buffer is used, it must be already initialized by the user with :cpp:expr:`LV_COLOR_FORMAT_ARGB8888` color format.
|
When a draw buffer is used, it must be already initialized by the user with :cpp:enumerator:`LV_COLOR_FORMAT_ARGB8888` color format.
|
||||||
|
|
||||||
Set a source
|
Set a source
|
||||||
------------
|
------------
|
||||||
@@ -66,14 +66,14 @@ following reasons:
|
|||||||
``lvgl/scripts/filetohex.py`` can be used to convert a Lottie file a hex
|
``lvgl/scripts/filetohex.py`` can be used to convert a Lottie file a hex
|
||||||
array. E.g.:
|
array. E.g.:
|
||||||
|
|
||||||
.. code:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
./filetohex.py path/to/lottie.json > out.txt
|
./filetohex.py path/to/lottie.json > out.txt
|
||||||
|
|
||||||
To create an animation from data use
|
To create an animation from data use
|
||||||
:cpp:enumerator:`lv_lottie_set_src_data(lottie, data, sizeof(data))`
|
:cpp:expr:`lv_lottie_set_src_data(lottie, data, sizeof(data))`
|
||||||
|
|
||||||
Lottie animations can be opened from JSON files by using :cpp:enumerator:`lv_lottie_set_src_file(lottie, "path/to/file.json")`.
|
Lottie animations can be opened from JSON files by using :cpp:expr:`lv_lottie_set_src_file(lottie, "path/to/file.json")`.
|
||||||
Note that the Lottie loader doesn't support LVGL's File System interface but a "normal path" should be used without a driver letter.
|
Note that the Lottie loader doesn't support LVGL's File System interface but a "normal path" should be used without a driver letter.
|
||||||
|
|
||||||
Get the animation
|
Get the animation
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ If ``parent`` is ``NULL`` the message box will be modal.
|
|||||||
E.g. ``const char * btn_txts[] = {"Ok", "Cancel", NULL}``.
|
E.g. ``const char * btn_txts[] = {"Ok", "Cancel", NULL}``.
|
||||||
|
|
||||||
|
|
||||||
Get the Parts
|
Get the parts
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
The building blocks of the message box can be obtained using the
|
The building blocks of the message box can be obtained using the
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ You can align the object on its parent with
|
|||||||
setting will be relative to the set alignment mode. For example, this
|
setting will be relative to the set alignment mode. For example, this
|
||||||
will shift the object by 10;20 px from the center of its parent:
|
will shift the object by 10;20 px from the center of its parent:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
lv_obj_set_align(obj, LV_ALIGN_CENTER);
|
lv_obj_set_align(obj, LV_ALIGN_CENTER);
|
||||||
lv_obj_set_pos(obj, 10, 20);
|
lv_obj_set_pos(obj, 10, 20);
|
||||||
@@ -96,7 +96,7 @@ To get a specific child of a parent use :cpp:expr:`lv_obj_get_child(parent, idx)
|
|||||||
|
|
||||||
The children can be iterated like this:
|
The children can be iterated like this:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
for(i = 0; i < lv_obj_get_child_count(parent); i++) {
|
for(i = 0; i < lv_obj_get_child_count(parent); i++) {
|
||||||
@@ -211,7 +211,7 @@ There are some attributes which can be enabled/disabled by
|
|||||||
|
|
||||||
Some examples:
|
Some examples:
|
||||||
|
|
||||||
.. code:: c
|
.. code-block:: c
|
||||||
|
|
||||||
/*Hide on object*/
|
/*Hide on object*/
|
||||||
lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ Labels on major ticks can be configured with :cpp:expr:`lv_scale_set_label_show(
|
|||||||
set `show_label` to true if labels should be drawn, :cpp:expr:`false` to hide them.
|
set `show_label` to true if labels should be drawn, :cpp:expr:`false` to hide them.
|
||||||
If instead of a numerical value in the major ticks a text is required they can be set
|
If instead of a numerical value in the major ticks a text is required they can be set
|
||||||
with :cpp:expr:`lv_scale_set_text_src(scale, custom_labels)` using ``NULL`` as the last element,
|
with :cpp:expr:`lv_scale_set_text_src(scale, custom_labels)` using ``NULL`` as the last element,
|
||||||
i.e. ``static char * custom_labels[3] = {"One", "Two", NULL}``.
|
i.e. :cpp:expr:`static char * custom_labels[3] = {"One", "Two", NULL}`.
|
||||||
|
|
||||||
<strong> NOTE: </strong> The major tick value is calculated with the :cpp:expr:`lv_map` API (when not setting the custom labels),
|
<strong> NOTE: </strong> The major tick value is calculated with the :cpp:expr:`lv_map` API (when not setting the custom labels),
|
||||||
this calculation takes into consideration the total tick number and the scale range, so the label drawn can present rounding errors
|
this calculation takes into consideration the total tick number and the scale range, so the label drawn can present rounding errors
|
||||||
|
|||||||
@@ -23,14 +23,14 @@ Value, range and step
|
|||||||
|
|
||||||
- :cpp:expr:`lv_spinbox_set_value(spinbox, 1234)` sets a new value on the Spinbox.
|
- :cpp:expr:`lv_spinbox_set_value(spinbox, 1234)` sets a new value on the Spinbox.
|
||||||
- :cpp:expr:`lv_spinbox_increment(spinbox)` and :cpp:expr:`lv_spinbox_decrement(spinbox)`
|
- :cpp:expr:`lv_spinbox_increment(spinbox)` and :cpp:expr:`lv_spinbox_decrement(spinbox)`
|
||||||
increments/decrements the value of the Spinbox according to the currently selected digit.
|
increments/decrements the value of the Spinbox according to the currently selected digit.
|
||||||
- :cpp:expr:`lv_spinbox_set_range(spinbox, -1000, 2500)` sets a range. If the
|
- :cpp:expr:`lv_spinbox_set_range(spinbox, -1000, 2500)` sets a range. If the
|
||||||
value is changed by :cpp:func:`lv_spinbox_set_value`, by
|
value is changed by :cpp:func:`lv_spinbox_set_value`, by
|
||||||
*Keys*,\ ``lv_spinbox_increment/decrement`` this range will be respected.
|
*Keys*,\ ``lv_spinbox_increment/decrement`` this range will be respected.
|
||||||
- :cpp:expr:`lv_spinbox_set_step(spinbox, 100)` sets which digits to change on
|
- :cpp:expr:`lv_spinbox_set_step(spinbox, 100)` sets which digits to change on
|
||||||
increment/decrement. Only multiples of ten can be set, and not for example 3.
|
increment/decrement. Only multiples of ten can be set, and not for example 3.
|
||||||
- :cpp:expr:`lv_spinbox_set_cursor_pos(spinbox, 1)` sets the cursor to a specific
|
- :cpp:expr:`lv_spinbox_set_cursor_pos(spinbox, 1)` sets the cursor to a specific
|
||||||
digit to change on increment/decrement. For example position '0' sets the cursor to the least significant digit.
|
digit to change on increment/decrement. For example position '0' sets the cursor to the least significant digit.
|
||||||
|
|
||||||
If an encoder is used as input device, the selected digit is shifted to
|
If an encoder is used as input device, the selected digit is shifted to
|
||||||
the right by default whenever the encoder button is clicked. To change this behaviour to shifting
|
the right by default whenever the encoder button is clicked. To change this behaviour to shifting
|
||||||
@@ -57,7 +57,7 @@ is disabled the value will remain at the minimum or maximum value.
|
|||||||
Events
|
Events
|
||||||
******
|
******
|
||||||
|
|
||||||
- :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` Sent when the value has changed.
|
- :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` Sent when the value has changed.
|
||||||
|
|
||||||
See the events of the :ref:`Text area <lv_textarea>` too.
|
See the events of the :ref:`Text area <lv_textarea>` too.
|
||||||
|
|
||||||
@@ -68,12 +68,12 @@ Learn more about :ref:`events`.
|
|||||||
Keys
|
Keys
|
||||||
****
|
****
|
||||||
|
|
||||||
- ``LV_KEY_LEFT/RIGHT`` With *Keypad* move the cursor left/right. With
|
- ``LV_KEY_LEFT/RIGHT`` With *Keypad* move the cursor left/right. With
|
||||||
*Encoder* decrement/increment the selected digit.
|
*Encoder* decrement/increment the selected digit.
|
||||||
- ``LV_KEY_UP/DOWN`` With *Keypad* and *Encoder* increment/decrement
|
- ``LV_KEY_UP/DOWN`` With *Keypad* and *Encoder* increment/decrement
|
||||||
the value.
|
the value.
|
||||||
- :cpp:enumerator:`LV_KEY_ENTER` With *Encoder* got the net digit. Jump to the first
|
- :cpp:enumerator:`LV_KEY_ENTER` With *Encoder* got the net digit. Jump to the first
|
||||||
after the last.
|
after the last.
|
||||||
|
|
||||||
.. _lv_spinbox_example:
|
.. _lv_spinbox_example:
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ Radial gradient as background
|
|||||||
:language: c
|
:language: c
|
||||||
|
|
||||||
Gradients for button background
|
Gradients for button background
|
||||||
-----------------------------
|
-------------------------------
|
||||||
|
|
||||||
.. lv_example:: styles/lv_example_style_18
|
.. lv_example:: styles/lv_example_style_18
|
||||||
:language: c
|
:language: c
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ Draw a line to the canvas
|
|||||||
:language: c
|
:language: c
|
||||||
|
|
||||||
Draw a vector graphic to the canvas
|
Draw a vector graphic to the canvas
|
||||||
-------------------------
|
-----------------------------------
|
||||||
|
|
||||||
.. lv_example:: widgets/canvas/lv_example_canvas_8
|
.. lv_example:: widgets/canvas/lv_example_canvas_8
|
||||||
:language: c
|
:language: c
|
||||||
|
|||||||
@@ -1,35 +1,35 @@
|
|||||||
A simple horizontal scale
|
A simple horizontal scale
|
||||||
"""""""""""""""""""""""""
|
-------------------------
|
||||||
|
|
||||||
.. lv_example:: widgets/scale/lv_example_scale_1
|
.. lv_example:: widgets/scale/lv_example_scale_1
|
||||||
:language: c
|
:language: c
|
||||||
|
|
||||||
An vertical scale with section and custom styling
|
An vertical scale with section and custom styling
|
||||||
"""""""""""""""""""""""""""""""""""""""""""""""""
|
-------------------------------------------------
|
||||||
|
|
||||||
.. lv_example:: widgets/scale/lv_example_scale_2
|
.. lv_example:: widgets/scale/lv_example_scale_2
|
||||||
:language: c
|
:language: c
|
||||||
|
|
||||||
A simple round scale
|
A simple round scale
|
||||||
""""""""""""""""""""
|
--------------------
|
||||||
|
|
||||||
.. lv_example:: widgets/scale/lv_example_scale_3
|
.. lv_example:: widgets/scale/lv_example_scale_3
|
||||||
:language: c
|
:language: c
|
||||||
|
|
||||||
A round scale with section and custom styling
|
A round scale with section and custom styling
|
||||||
"""""""""""""""""""""""""""""""""""""""""""""
|
---------------------------------------------
|
||||||
|
|
||||||
.. lv_example:: widgets/scale/lv_example_scale_4
|
.. lv_example:: widgets/scale/lv_example_scale_4
|
||||||
:language: c
|
:language: c
|
||||||
|
|
||||||
An scale with section and custom styling
|
An scale with section and custom styling
|
||||||
""""""""""""""""""""""""""""""""""""""""
|
----------------------------------------
|
||||||
|
|
||||||
.. lv_example:: widgets/scale/lv_example_scale_5
|
.. lv_example:: widgets/scale/lv_example_scale_5
|
||||||
:language: c
|
:language: c
|
||||||
|
|
||||||
A round scale with multiple needles, resembling a clock
|
A round scale with multiple needles, resembling a clock
|
||||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
-------------------------------------------------------
|
||||||
|
|
||||||
.. lv_example:: widgets/scale/lv_example_scale_6
|
.. lv_example:: widgets/scale/lv_example_scale_6
|
||||||
:language: c
|
:language: c
|
||||||
|
|||||||
@@ -1021,8 +1021,8 @@
|
|||||||
#define LV_FILE_EXPLORER_QUICK_ACCESS 1
|
#define LV_FILE_EXPLORER_QUICK_ACCESS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*1: Enable freetype font manager*/
|
/** 1: Enable freetype font manager
|
||||||
/*Requires: LV_USE_FREETYPE*/
|
* - Requires: LV_USE_FREETYPE */
|
||||||
#define LV_USE_FONT_MANAGER 0
|
#define LV_USE_FONT_MANAGER 0
|
||||||
#if LV_USE_FONT_MANAGER
|
#if LV_USE_FONT_MANAGER
|
||||||
|
|
||||||
|
|||||||
@@ -3258,8 +3258,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*1: Enable freetype font manager*/
|
/** 1: Enable freetype font manager
|
||||||
/*Requires: LV_USE_FREETYPE*/
|
* - Requires: LV_USE_FREETYPE */
|
||||||
#ifndef LV_USE_FONT_MANAGER
|
#ifndef LV_USE_FONT_MANAGER
|
||||||
#ifdef CONFIG_LV_USE_FONT_MANAGER
|
#ifdef CONFIG_LV_USE_FONT_MANAGER
|
||||||
#define LV_USE_FONT_MANAGER CONFIG_LV_USE_FONT_MANAGER
|
#define LV_USE_FONT_MANAGER CONFIG_LV_USE_FONT_MANAGER
|
||||||
|
|||||||
Reference in New Issue
Block a user