feat(docs): reorganize docs (#7136)

This commit is contained in:
Victor Wheeler
2024-10-23 12:53:33 -06:00
committed by GitHub
parent c61ca42a2a
commit 9b6f6d23f1
212 changed files with 6314 additions and 5806 deletions
+10 -10
View File
@@ -1,24 +1,24 @@
.. _changelog:
Changelog
=========
Change Log
==========
`v9.2 <https://github.com/lvgl/lvgl/compare/v9.1.0...v9.2.0>`__ 26 August 2024
------------------------------------------------------------------------------
It's huge release with many interesting updates:
- Built-in `Wayland driver <https://docs.lvgl.io/master/integration/driver/wayland.html>`__
- `OpenGL ES and GLFW driver <https://docs.lvgl.io/master/integration/driver/opengles.html>`__ with support for external textures
- `Renesas GLCDC <https://docs.lvgl.io/master/integration/driver/display/renesas_glcdc.html>`__ driver
- Built-in :ref:`Wayland driver <wayland_driver>`
- :ref:`OpenGL ES and GLFW driver <opengl_es_driver>` with support for external textures
- :ref:`renesas_glcdc` driver
- L8 and I1 rendering support
- Matrix transformations during rendering
- New `file system interfaces <https://docs.lvgl.io/master/libs/fs.html>`__: LittleFS, ESP LittleFS, Arduino FS
- New :ref:`file system interfaces <libs_filesystem>`: LittleFS, ESP LittleFS, Arduino FS
- SDL renderer improvements (supporting all draw task types and improving speed)
- Radial, Conic, and Skew `gradients supported <https://docs.lvgl.io/master/overview/style.html#metallic-knob-with-conic-gradient>`__ by software rendering and VG-Lite
- `QNX <https://docs.lvgl.io/master/integration/os/qnx.html>`__ and `MQX <https://docs.lvgl.io/master/integration/os/mqx.html>`__ support
- `Mouse hover handling <https://docs.lvgl.io/master/get-started/quick-overview.html>`__
- `Lottie <https://docs.lvgl.io/master/widgets/lottie.html>`__ support
- Radial, Conic, and Skew `gradients supported <https://docs.lvgl.io/master/details/base-widget/styles/style.html#metallic-knob-with-conic-gradient>`__ by software rendering and VG-Lite
- :ref:`qnx` and :ref:`mqx` support
- :ref:`Mouse hover handling <styles_states>`
- :ref:`lv_lottie` support
- CI tests for UEFI builds
And many smaller fixes and features
+6 -6
View File
@@ -148,7 +148,7 @@ illustrating most of the Doxygen commands used in LVGL.
.. code-block:: c
/**
* Set alignment of objects placed in containers with LV_STYLE_FLEX_FLOW style.
* Set alignment of Widgets placed in containers with LV_STYLE_FLEX_FLOW style.
*
* The values for the `..._place` arguments come from the `lv_flex_align_t`
* enumeration and have the same meanings as they do for flex containers in CSS.
@@ -170,7 +170,7 @@ illustrating most of the Doxygen commands used in LVGL.
* - https://css-tricks.com/snippets/css/a-guide-to-flexbox/
* - see `lv_obj_set_flex_grow()` for additional information.
*/
void lv_obj_set_flex_align(lv_obj_t * obj, lv_flex_align_t main_place, lv_flex_align_t cross_place,
void lv_obj_set_flex_align(lv_obj_t * widget, lv_flex_align_t main_place, lv_flex_align_t cross_place,
lv_flex_align_t track_cross_place);
@@ -264,12 +264,12 @@ follow some coding conventions:
- Use typed pointers instead of :cpp:expr:`void *` pointers
- Widget constructor must follow the ``lv_<widget_name>_create(lv_obj_t * parent)`` pattern.
- Widget members function must start with ``lv_<widget_name>`` and should receive :cpp:expr:`lv_obj_t *` as first
argument which is a pointer to widget object itself.
argument which is a pointer to Widget object itself.
- ``struct`` APIs should follow the widgets' conventions. That is to receive a pointer to the ``struct`` as the
first argument, and the prefix of the ``struct`` name should be used as the prefix of the
function name too (e.g. :cpp:expr:`lv_display_set_default(lv_display_t * disp)`)
function name as well (e.g. :cpp:expr:`lv_display_set_default(lv_display_t * disp)`)
- Functions and ``struct``\ s which are not part of the public API must begin with underscore in order to mark them as "private".
- Argument must be named in H files too.
- Argument must be named in H files as well.
- Do not ``malloc`` into a static or global variables. Instead declare the variable in ``lv_global_t``
structure in ``lv_global.h`` and mark the variable with :cpp:expr:`(LV_GLOBAL_DEFAULT()->variable)` when it's used.
- To register and use callbacks one of the following needs to be followed.
@@ -293,7 +293,7 @@ Here is example to show bracket placing and using of white space:
/**
* Set new text for a label. Memory will be allocated by label to store text.
*
* @param label pointer to label object
* @param label pointer to label Widget
* @param text '\0' terminated character string.
* NULL to refresh with current text.
*/
+34 -20
View File
@@ -52,7 +52,18 @@ The most important thing that has to be done when contributing to LVGL is ***EVE
The below are some rules to follow when updating any of the `.rst` files located in the `./docs/` directory and any of it's subdirectories.
### index.rst files
### What to Name Your `.rst` File
The documentation-generation logic uses the stem of the file name (i.e. "event" from file name "event.rst") and compares this with code-element names found by Doxygen. If a match is found, then it appends hyperlinks to the API pages that contain those code elements (names of macros, enum/struct/union types, variables, namespaces, typedefs and functions).
If this is appropriate for the .RST file you are creating, ensure the stem of the file name matches the beginning part of the code-element name you want it to be associated with.
If this is *not* appropriate for the .RST file you are creating, ensure the stem of the file name DOES NOT match any code-element names found in the LVGL header files under the ./src/ directory.
In alignment with the above, use a file name stem that is appropriate to the topic being covered.
### 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.
@@ -124,6 +135,8 @@ This in-line markup (interpreted text using the Sphinx-defined custom `:ref:` ro
This latter syntax enables you to put a **link target** anywhere in an .RST file (not just above a heading) and link to it using this syntax.
Note: This latter syntax was either added or fixed in Sphinx recently. It did not work in Sphinx 7.3.7.
@@ -144,19 +157,19 @@ If you are creating a new .RST file, use this convention:
=====
Title
=====
Chapter
*******
Section
-------
Sub Section
~~~~~~~~~~~
Sub Sub Section
^^^^^^^^^^^^^^^
Sub Sub Sub Section
'''''''''''''''''''
@@ -201,7 +214,7 @@ To create a bulleted list, do the following:
lines to align with item text like this.
- If you want to include a code block under a list item,
it must be intended to align with the list item like this:
.. code-block: python
<=== blank line here is important
# this is some code
@@ -232,22 +245,23 @@ If you want to reference portions of the LVGL code from the documentation (in .R
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)`
:cpp:expr:`lv_obj_set_layout(widget, LV_LAYOUT_FLEX)`
:cpp:expr:`lv_slider_set_mode(slider, LV_SLIDER_MODE_...)`
Arguments that are expressions (more than one word), or contain non-alphanumeric characters will cause the `:cpp:expr:` interpreted-text to fail. Examples:
:cpp:expr:`lv_obj_set_layout(obj, LV_LAYOUT_FLEX/GRID)` <== arg with > 1 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
:cpp:expr:`lv_obj_set_layout(&obj, LV_LAYOUT_FLEX);` <== ampersand
:cpp:expr:`lv_obj_set_layout(obj, ...)` <== elipsis
:cpp:expr:`lv_obj_set_layout(widget, LV_LAYOUT_FLEX/GRID)` <== arg with > 1 word
:cpp:expr:`lv_obj_set_layout(widget, LV_LAYOUT_*)` <== asterisk
:cpp:expr:`lv_obj_set_layout(*widget, LV_LAYOUT_FLEX)` <== asterisk
:cpp:expr:`lv_obj_set_layout((lv_obj_t *)widget, LV_LAYOUT_FLEX)` <== cast
:cpp:expr:`lv_obj_set_layout(&widget, LV_LAYOUT_FLEX);` <== ampersand & semicolon
:cpp:expr:`lv_obj_set_layout(widget, ...)` <== lone elipsis
For such examples, simply use reStructuredText literal markup like this:
``lv_obj_set_layout(obj, LV_LAYOUT_FLEX/GRID)``
``lv_obj_set_layout(obj, LV_LAYOUT_*)``
``lv_obj_set_layout(*obj, LV_LAYOUT_FLEX)``
``lv_obj_set_layout((lv_obj_t *)obj, LV_LAYOUT_FLEX)``
``lv_obj_set_layout(&obj, LV_LAYOUT_FLEX);``
``lv_obj_set_layout(obj, ...)``
``lv_obj_set_layout(widget, LV_LAYOUT_FLEX/GRID)``
``lv_obj_set_layout(widget, LV_LAYOUT_*)``
``lv_obj_set_layout(*widget, LV_LAYOUT_FLEX)``
``lv_obj_set_layout((lv_obj_t *)widget, LV_LAYOUT_FLEX)``
``lv_obj_set_layout(&widget, LV_LAYOUT_FLEX);``
``lv_obj_set_layout(widget, ...)``
+18 -18
View File
@@ -75,16 +75,16 @@ Cライブラリ。(C++互換) -
任意の(RT)OS、任意のMCU・MPU用にコンパイル可能。 -
電子ペーパー、OLEDディスプレイ、TFTディスプレイ、白黒ディスプレイ、モニターに対応。
`Porting
Guide <https://docs-lvgl-io.translate.goog/master/porting/project.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
Guide <https://docs-lvgl-io.translate.goog/master/intro/add-lvgl-to-your-project/project.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
- MITライセンスにより商用利用可能。 - システム要件:RAM 32KB、Flash
128KB、フレームバッファ、レンダリング用に1/10以上のスクリーンサイズのバッファ。
- OS、外部メモリ、GPUもサポート。
**ウィジェット、スタイル、レイアウトなど** - 30以上の組み込み
`ウィジェット <https://docs-lvgl-io.translate.goog/master/widgets/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__: ボタン、ラベル、スライダー、グラフ、キーボード、メーター、円弧、表など。
`ウィジェット <https://docs-lvgl-io.translate.goog/master/details/widgets/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__: ボタン、ラベル、スライダー、グラフ、キーボード、メーター、円弧、表など。
-
ウィジェットの任意の部分を任意の状態にカスタマイズ可能な豊富なスタイルプロパティを備えた柔軟な
`スタイルシステム <https://docs-lvgl-io.translate.goog/master/overview/style.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__\ 。
`スタイルシステム <https://docs-lvgl-io.translate.goog/master/details/base-widget/styles/style.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__\ 。
-
`Flexbox <https://docs-lvgl-io.translate.goog/master/layouts/flex.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
および
@@ -98,9 +98,9 @@ Guide <https://docs-lvgl-io.translate.goog/master/porting/project.html?_x_tr_sl=
アニメーション、アンチエイリアシング、不透明度、スムーズスクロール、シャドウ、画像変換などをサポートするレンダリングエンジン。
-
マウス、タッチパッド、キーパッド、キーボード、外部ボタン、エンコーダ等の
`入力デバイス <https://docs-lvgl-io.translate.goog/master/porting/indev.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
`入力デバイス <https://docs-lvgl-io.translate.goog/master/details/modules/indev.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
をサポート。 -
`マルチディスプレイ <https://docs-lvgl-io.translate.goog/master/overview/display.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
`マルチディスプレイ <https://docs-lvgl-io.translate.goog/master/details/modules/display.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
対応。
**Binding と Build をサポート** - `MicroPython
@@ -108,9 +108,9 @@ Binding <https://blog-lvgl-io.translate.goog/2019-02-20/micropython-bindings?_x_
が LVGL API を公開。 -
カスタムビルドシステムは使用せず、プロジェクトの他のファイルをビルドするときに、LVGLをビルド可能。
- Make と
`CMake <https://docs-lvgl-io.translate.goog/master/get-started/platforms/cmake.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
`CMake <https://docs-lvgl-io.translate.goog/master/details/integration/building/cmake.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
が含まれており、すぐ使えるようにサポート。 -
`PCのシミュレータで開発したUIコード <https://docs-lvgl-io.translate.goog/master/get-started/platforms/pc-simulator.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
`PCのシミュレータで開発したUIコード <https://docs-lvgl-io.translate.goog/master/details/integration/ide/pc-simulator.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
は、そのまま組込み用ハードウェアでも使用可能。 - `Emscripten
port <https://github.com/lvgl/lv_web_emscripten>`__ :gb:
によりC言語のUIコードをHTMLファイルに変換。
@@ -128,19 +128,19 @@ UI開発をよりシンプルかつ迅速にするための、ユーザーイン
--------------------
LVGL は以下で利用可能です。 - `Arduino
library <https://docs-lvgl-io.translate.goog/master/get-started/platforms/arduino.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
library <https://docs-lvgl-io.translate.goog/master/details/entegration/framework/arduino.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
- `PlatformIO
package <https://registry.platformio.org/libraries/lvgl/lvgl>`__ :gb: -
`Zephyr
library <https://docs-zephyrproject-org.translate.goog/latest/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
- `ESP32
component <https://docs-lvgl-io.translate.goog/master/get-started/platforms/espressif.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
component <https://docs-lvgl-io.translate.goog/master/details/integration/chip/espressif.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
- `NXP MCUXpresso
component <https://www-nxp-com.translate.goog/design/software/embedded-software/lvgl-open-source-graphics-library:LITTLEVGL-OPEN-SOURCE-GRAPHICS-LIBRARY?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
- `NuttX
library <https://docs-lvgl-io.translate.goog/master/get-started/os/nuttx.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
library <https://docs-lvgl-io.translate.goog/master/details/integration/os/nuttx.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
- `RT-Thread
RTOS <https://docs-lvgl-io.translate.goog/master/get-started/os/rt-thread.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
RTOS <https://docs-lvgl-io.translate.goog/master/details/integration/os/rt-thread.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
- NXP MCUXpresso library - CMSIS-Pack
:robot:
@@ -386,7 +386,7 @@ C code
/*Add the style sheet to the slider's INDICATOR part*/
lv_obj_add_style(slider, &style_indicator, LV_PART_INDICATOR);
/*Add the same style to the KNOB part too and locally overwrite some properties*/
/*Add the same style to the KNOB part as well and locally overwrite some properties*/
lv_obj_add_style(slider, &style_indicator, LV_PART_KNOB);
lv_obj_set_style_outline_color(slider, lv_color_hex(0x0096FF), LV_PART_KNOB);
@@ -441,7 +441,7 @@ MicroPython code \| Online Simulator :gb:
slider.add_style(style_indicator, lv.PART.INDICATOR)
slider.add_style(style_indicator, lv.PART.KNOB)
# Add the same style to the KNOB part too and locally overwrite some properties
# Add the same style to the KNOB part as well and locally overwrite some properties
slider.set_style_outline_color(lv.color_hex(0x0096FF), lv.PART.KNOB)
slider.set_style_outline_width(3, lv.PART.KNOB)
slider.set_style_outline_pad(-5, lv.PART.KNOB)
@@ -556,16 +556,16 @@ LVGLを使い始める時は、以下の順に進める事をおすすめしま
`Introduction <https://docs-lvgl-io.translate.goog/master/intro/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
を読みましょう。 (5分間)
3. LVGLの基本に慣れるため `Quick
overview <https://docs-lvgl-io.translate.goog/master/get-started/quick-overview.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
overview <https://docs-lvgl-io.translate.goog/master/intro/overview.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
を読みましょう。 (15分間)
**LVGLを使ってみましょう**
4. `シミュレータ <https://docs-lvgl-io.translate.goog/master/get-started/platforms/pc-simulator.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
4. `シミュレータ <https://docs-lvgl-io.translate.goog/master/details/integration/ide/pc-simulator.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
をセットアップしましょう。 (10 minutes)
5. `サンプルプログラム <https://github.com/lvgl/lvgl/tree/master/examples>`__
:gb: を動かしてみましょう。
6. `移植ガイド <https://docs-lvgl-io.translate.goog/master/porting/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
6. `移植ガイド <https://docs-lvgl-io.translate.goog/master/intro/add-lvgl-to-your-project/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
を参考に、LVGLを開発ボードに移植してみましょう。すぐ使える形の
`プロジェクト <https://github.com/lvgl?q=lv_port_>`__ :gb:
も用意してあります。
@@ -573,10 +573,10 @@ LVGLを使い始める時は、以下の順に進める事をおすすめしま
**より詳しく体験してみましょう**
7. ライブラリの理解を深めるため
`Overview <https://docs-lvgl-io.translate.goog/master/overview/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
`Overview <https://docs-lvgl-io.translate.goog/master/details/modules/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
を読みましょう。 (23時間)
8. ウィジェットの機能や使い方の詳細は
`Widgets <https://docs-lvgl-io.translate.goog/master/widgets/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
`Widgets <https://docs-lvgl-io.translate.goog/master/details/widgets/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
でご確認ください。
**助け合いましょう**
+13 -13
View File
@@ -88,8 +88,8 @@ algum suporte durante o desenvolvimento de seu próximo projeto de GUI.
dependências externas.
- Pode ser compilado para qualquer display MCU ou MPU, e qualquer
sistema operacional de tempo real (RT-OS).
- Suporta monitores monocromáticos, ePaper, OLED ou TFT. `Guia de
portabilidade <https://docs.lvgl.io/master/porting/project.html>`__
- Suporta monitores monocromáticos, ePaper, OLED ou TFT. :ref:`Guia de
portabilidade <initializing_lvgl>`
- Distribuído sob a licença do MIT, para que você também possa usá-lo
facilmente em projetos comerciais.
- Precisa de apenas 32 kB de RAM e 128 kB de Flash, um frame buffer e
@@ -126,10 +126,10 @@ algum suporte durante o desenvolvimento de seu próximo projeto de GUI.
- Nenhum sistema de compilação personalizado é usado. Você pode
construir o LVGL enquanto constrói os outros arquivos do seu projeto.
- O suporte para Make e
`CMake <https://docs.lvgl.io/master/get-started/platforms/cmake.html>`__
:ref:`CMake <build_cmake>`
já vem incluído.
- `Desenvolva no
PC <https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html>`__
PC <https://docs.lvgl.io/master/details/integration/ide/pc-simulator.html>`__
e use o mesmo código de interface do usuário em hardwares
incorporados (embedded hardware).
- Converta o código C para um arquivo HTML com o `Emscripten
@@ -187,19 +187,19 @@ receberá o pagamento em alguns dias.
LVGL está disponível para:
- `Arduino
library <https://docs.lvgl.io/master/get-started/platforms/arduino.html>`__
library <https://docs.lvgl.io/master/details/entegration/framework/arduino.html>`__
- `PlatformIO
package <https://registry.platformio.org/libraries/lvgl/lvgl>`__
- `Zephyr
library <https://docs.zephyrproject.org/latest/kconfig.html#CONFIG_LVGL>`__
- `ESP32
component <https://docs.lvgl.io/master/get-started/platforms/espressif.html>`__
component <https://docs.lvgl.io/master/details/integration/chip/espressif.html>`__
- `NXP MCUXpresso
component <https://www.nxp.com/design/software/embedded-software/lvgl-open-source-graphics-library:LITTLEVGL-OPEN-SOURCE-GRAPHICS-LIBRARY>`__
- `NuttX
library <https://docs.lvgl.io/master/get-started/os/nuttx.html>`__
library <https://docs.lvgl.io/master/details/integration/os/nuttx.html>`__
- `RT-Thread
RTOS <https://docs.lvgl.io/master/get-started/os/rt-thread.html>`__
RTOS <https://docs.lvgl.io/master/details/integration/os/rt-thread.html>`__
- NXP MCUXpresso library
- CMSIS-Pack
@@ -614,28 +614,28 @@ Esta lista irá guiá-lo para começar com o LVGL passo a passo.
`introdução <https://docs.lvgl.io/master/intro/index.html>`__ da
documentação (~5 minutos)
3. Familiarize-se com o básico na página de `visão geral
rápida <https://docs.lvgl.io/master/get-started/quick-overview.html>`__
rápida <https://docs.lvgl.io/master/intro/overview.html>`__
(~15 minutos)
**Começando a usar o LVGL**
4. Configure um
`simulador <https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html>`__
`simulador <https://docs.lvgl.io/master/details/integration/ide/pc-simulator.html>`__
(~10 minutos)
5. Experimente alguns
`exemplos <https://github.com/lvgl/lvgl/tree/master/examples>`__
6. Porte o LVGL para uma placa. Veja o guia `portando o
LVGL <https://docs.lvgl.io/master/porting/index.html>`__ ou veja um
LVGL <https://docs.lvgl.io/master/intro/add-lvgl-to-your-project/index.html>`__ ou veja um
projeto pronto para usar em
`projetos <https://github.com/lvgl?q=lv_port_>`__
**Torne-se um profissional**
7. Leia a página `visão
geral <https://docs.lvgl.io/master/overview/index.html>`__ para
geral <https://docs.lvgl.io/master/details/modules/index.html>`__ para
entender melhor a biblioteca (~2-3 horas)
8. Verifique a documentação dos
`widgets <https://docs.lvgl.io/master/widgets/index.html>`__ para ver
`widgets <https://docs.lvgl.io/master/details/widgets/index.html>`__ para ver
seus recursos e usabilidade
**Obtenha ajuda e ajude outras pessoas**
+16 -16
View File
@@ -72,25 +72,25 @@ RAM 和 128 KB Flash、C 编译器、帧缓冲区和至少 1/10 屏幕大小的
- 一个完全可移植的 C(C++ 兼容)库,没有外部依赖关系。
- 可以编译到任何 MCU 或 MPU,使用任何 RTOS 或者操作系统。
- 支持单色、ePaper、OLED、TFT 显示器或者模拟器。
`移植指南 <https://docs.lvgl.io/master/porting/project.html>`__
`移植指南 <https://docs.lvgl.io/master/intro/add-lvgl-to-your-project/project.html>`__
- 该项目使用 MIT 许可证,因此您可以在商业项目中轻松使用它。
- 仅需 32 KB RAM 和 128 KB Flash,一个帧缓冲区,以及至少 1/10 屏幕大小的渲染缓冲区。
- 支持使用可选的操作系统、外部存储器和 GPU。
**控件、样式、布局等**
- 30+ 内置\ `控件 <https://docs.lvgl.io/master/widgets/index.html>`__:
- 30+ 内置\ `控件 <https://docs.lvgl.io/master/details/widgets/index.html>`__:
 按钮、标签、滑块、图表、键盘、仪表、弧形、表格等等。
- 灵活的\ `样式系统 <https://docs.lvgl.io/master/overview/style.html>`__
- 灵活的\ `样式系统 <https://docs.lvgl.io/master/details/base-widget/styles/style.html>`__
支持约 100 个样式属性,可在任何状态下自定义控件的任何部分。
- `Flex 布局 <https://docs.lvgl.io/master/layouts/flex.html>`__
`Grid 布局 <https://docs.lvgl.io/master/layouts/grid.html>`__
- `Flex 布局 <https://docs.lvgl.io/master/details/base-widget/layouts/flex.html>`__
`Grid 布局 <https://docs.lvgl.io/master/details/base-widget/layouts/grid.html>`__
可以响应式自动调整控件的大小和位置。
- 文本支持 UTF-8 编码,支持 CJK、泰语、印地语、阿拉伯语和波斯语书写系统。
- 支持自动换行、字距调整、文本滚动、亚像素渲染、拼音输入法、文本表情符号。
- 渲染引擎支持动画、抗锯齿、不透明度、平滑滚动、阴影、图形变换等。
- 支持鼠标、触摸板、小键盘、键盘、外部按钮、编码器\ `输入设备 <https://docs.lvgl.io/master/porting/indev.html>`__\ 。
- 支持\ `多显示器 <https://docs.lvgl.io/master/overview/display.html#multiple-display-support>`__\ 。
- 支持鼠标、触摸板、小键盘、键盘、外部按钮、编码器\ `输入设备 <https://docs.lvgl.io/master/details/modules/indev.html>`__\ 。
- 支持\ `多显示器 <https://docs.lvgl.io/master/details/modules/display.html#multiple-display-support>`__\ 。
**绑定和构建支持**
@@ -99,7 +99,7 @@ RAM 和 128 KB Flash、C 编译器、帧缓冲区和至少 1/10 屏幕大小的
- `PikaScript 绑定 <https://blog.lvgl.io/2022-08-24/pikascript-and-lvgl>`__
在 MCU 上的更轻更简单的 Python 版本
- 未使用自定义生成系统。您可以在构建项目的其他文件时构建 LVGL。
- 支持开箱即用的 Make 和 \ `CMake <https://docs.lvgl.io/master/integration/building/cmake.html>`__\ 编译系统。
- 支持开箱即用的 Make 和 \ `CMake <https://docs.lvgl.io/master/details/integration/building/cmake.html>`__\ 编译系统。
- 支持在 \ `PC 上开发 <https://docs.lvgl.io/master/integration/ide/pc-simulator.html>`__\ ,并可以在嵌入式硬件上使用相同的 UI 代码。
- 支持使用我们的 \ `Emscripten 移植 <https://github.com/lvgl/lv_web_emscripten>`__\ 从而将 C 写的 UI 代码转换为 HTML 文件。
@@ -183,7 +183,7 @@ Hello world 标签
.. code-block:: c
/*Change the active screen's background color*/
/* Change Active Screen's background color */
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x003a57), LV_PART_MAIN);
/*Create a white label, set its text and align it to the center*/
@@ -203,7 +203,7 @@ Hello world 标签
.. code-block:: python
# Change the active screen's background color
# Change Active Screen's background color
scr = lv.screen_active()
scr.set_style_bg_color(lv.color_hex(0x003a57), lv.PART.MAIN)
@@ -400,7 +400,7 @@ Hello world 标签
/*Add the style sheet to the slider's INDICATOR part*/
lv_obj_add_style(slider, &style_indicator, LV_PART_INDICATOR);
/*Add the same style to the KNOB part too and locally overwrite some properties*/
/*Add the same style to the KNOB part as well and locally overwrite some properties*/
lv_obj_add_style(slider, &style_indicator, LV_PART_KNOB);
lv_obj_set_style_outline_color(slider, lv_color_hex(0x0096FF), LV_PART_KNOB);
@@ -448,7 +448,7 @@ Hello world 标签
slider.add_style(style_indicator, lv.PART.INDICATOR)
slider.add_style(style_indicator, lv.PART.KNOB)
# Add the same style to the KNOB part too and locally overwrite some properties
# Add the same style to the KNOB part as well and locally overwrite some properties
slider.set_style_outline_color(lv.color_hex(0x0096FF), lv.PART.KNOB)
slider.set_style_outline_width(3, lv.PART.KNOB)
slider.set_style_outline_pad(-5, lv.PART.KNOB)
@@ -540,19 +540,19 @@ Hello world 标签
1. 查看\ `在线演示 <https://lvgl.io/demos>`__\ ,了解 LVGL 的实际操作(3 分钟)
2. 阅读\ `文档 <https://docs.lvgl.io/master/intro/index.html>`__\ 的简介页(5 分钟)
3. 熟悉\ `快速概览 <https://docs.lvgl.io/master/get-started/quick-overview.html>`__
3. 熟悉\ `快速概览 <https://docs.lvgl.io/master/intro/overview.html>`__
页面上的基本知识(15 分钟)
**开始使用 LVGL**
4. 设置\ `模拟器 <https://docs.lvgl.io/master/integration/ide/pc-simulator.html#simulator>`__ 10 分钟)
5. 尝试一些\ `示例 <https://github.com/lvgl/lvgl/tree/master/examples>`__
6. 将LVGL端口连接到线路板。请参阅\ `移植 <https://docs.lvgl.io/master/porting/index.html>`__\ 指南,或查看现成的\ `项目 <https://github.com/lvgl?q=lv_port_>`__
6. 将LVGL端口连接到线路板。请参阅\ `移植 <https://docs.lvgl.io/master/intro/add-lvgl-to-your-project/index.html>`__\ 指南,或查看现成的\ `项目 <https://github.com/lvgl?q=lv_port_>`__
**成为专业人士**
7. 阅读\ `概述 <https://docs.lvgl.io/master/overview/index.html>`__\ 页面以更好地了解图书馆(2-3 小时)
8. 查看\ `控件 <https://docs.lvgl.io/master/widgets/index.html>`__\ 的文档以查看其功能和用法
7. 阅读\ `概述 <https://docs.lvgl.io/master/details/modules/index.html>`__\ 页面以更好地了解图书馆(2-3 小时)
8. 查看\ `控件 <https://docs.lvgl.io/master/details/widgets/index.html>`__\ 的文档以查看其功能和用法
**获得帮助并帮助他人**
+4 -4
View File
@@ -50,12 +50,12 @@ Architecture
(see `here <https://github.com/lvgl/lvgl/pull/3390#pullrequestreview-990710921>`__)
- |check| Make LVGL render independent areas in parallel.
`#4016 <https://github.com/lvgl/lvgl/issues/4016>`__
- |check| Drop `lv_mem_buf_get` as tlsf should be fast enough for normal allocations too.
- |check| Drop `lv_mem_buf_get` as tlsf should be fast enough for normal allocations as well.
Fragmentation is also lower if processes can completely clean up after themselves.
- |check| More color formats: 24 bit, ARGB1555, ARGB4444 etc
(see `here <https://forum.lvgl.io/t/keypad-input-device-why-lv-event-long-pressed-only-on-enter/10263>`__)
- |check| Unified caching #3116 #3415
- |check| Variable binding. I.e create properties which can be bound to objects and those objects are notified on value change. Maybe based on `lv_msg`?
- |check| Variable binding. I.e create properties which can be bound to Widgets and those Widgets are notified on value change. Maybe based on `lv_msg`?
- |uncheck| Add GPU abstraction for display rotation
- |check| Replace the `read_line_cb` of the image decoders with `get_area_cb`
- |check| Limit the image caching size in bytes instead of image count
@@ -144,7 +144,7 @@ Widgets
- |uncheck| `lv_bar`, `lv_arc`: handle max < min for fill direction swapping #4039
- |uncheck| `lv_bar`, `lv_slider`, `lv_arc`: make possible to move the knob only inside the background (see `here <https://forum.lvgl.io/t/slider-knob-out-of-the-track/11956>`__)
- |uncheck| Improve `lv_label_align_t` #1656
- |uncheck| `lv_label` reconsider label long modes. (support min/max-width/height too) #3420
- |uncheck| `lv_label` reconsider label long modes. (support min/max-width/height as well) #3420
- |uncheck| `lv_roller` make it more flexible #4009
Others
@@ -164,7 +164,7 @@ Ideas
- Reconsider how themes should work.
- Better way to reset global variables in `lv_deinit()` #3385
- `lv_array`: replace linked lists with array where possible (arrays are faster and uses less memory)
- Reconsider how to handle UTF-8 characters (allow different encoding too) and Bidi. Maybe create an abstraction for textshaping.
- Reconsider how to handle UTF-8 characters (allow different encoding as well) and Bidi. Maybe create an abstraction for textshaping.
- Consider direct binary font format support
- Improve groups. `Discussion <https://forum.lvgl.io/t/lv-group-tabindex/2927/3>`__.
Reconsider focusing logic. Allow having no widget selected (on web it's possible). Keep editing state in `lv_obj_t`
+5 -3
View File
@@ -37,10 +37,12 @@ class TranslationLinkNodeTransform(SphinxPostTransform):
(language, link_text) = text.split(':')
env = self.document.settings.env
docname = env.docname
#doc_path = env.doc2path(docname, False)
urlpath = os.environ['LVGL_URLPATH']+'/'
# doc_path = env.doc2path(docname, False)
if "LVGL_URLPATH" not in os.environ:
os.environ['LVGL_URLPATH'] = 'master'
urlpath = os.getenv('LVGL_URLPATH')+'/'
return_path = URL_BASE.get(language, "") + urlpath
url = '{}.html'.format(os.path.join(return_path, docname))
node.replace_self(nodes.reference(rawtext, link_text, refuri=url, **options))
+19 -1
View File
@@ -106,7 +106,25 @@ class LvExample(Directive):
def setup(app):
app.add_directive("lv_example", LvExample)
app.add_config_value("repo_commit_hash", "", "env")
# Direct [View on GitHub] links in examples to use current
# branch (stored in LVGL_GITCOMMIT environment variable) instead
# of the current commit hash as was being done previously.
# Default to 'master' if Sphinx is being run outside of `build.py`.
# Resulting example link:
# [https://github.com/lvgl/lvgl/blob/master/examples/anim/lv_example_anim_1.c].
# [https://github.com/lvgl/lvgl/blob/v8.4.0/examples/anim/lv_example_anim_1.c].
# [https://github.com/lvgl/lvgl/blob/v9.2.0/examples/anim/lv_example_anim_1.c].
if 'LVGL_GITCOMMIT' in os.environ:
git_commit = os.environ['LVGL_GITCOMMIT']
else:
git_commit = 'master'
app.add_config_value("repo_commit_hash", git_commit, "env")
# if 'repo_commit_hash' in app.config._options:
# print(f"repo_commit_hash from lv_example.py: [{app.config._options['repo_commit_hash']}]")
# else:
# print("repo_commit_hash not found in [app.config._options] at this time.")
return {
'version': '0.1',
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 11 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 12 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 11 KiB

+236 -69
View File
@@ -17,25 +17,113 @@ import tempfile
import config_builder
import add_translation
# due to the modifications that take place to the documentation files
# -------------------------------------------------------------------------
# Process args.
#
# Normal usage:
# $ python build.py skip_latex
#
# Other optional arguments are meant for doc development to speed up
# turn-around time between doc modification and seeing the final results:
#
# - skip_api
# Skips generating API pages (this saves about 70% of build time).
# This is intended to be used only during doc development to speed up
# turn-around time between doc modifications and seeing final results.
# - no_fresh_env
# excludes -E command-line argument to `sphinx-build`, which forces
# generating a whole new environment (memory of what was built
# previously, forcing a full rebuild). "no_fresh_env" enables a
# rebuild of only docs that got updated -- Sphinx's default behavior.
# - develop
# Leaves temporary directory intact for docs development purposes.
# - fixed_tmp_dir
# If (fixed_tmp_dir and 'LVGL_FIXED_TEMP_DIR' in os.environ),
# then the temporary directory in the value of that environment
# variable will be used instead of the normal (randomly-named)
# temporary directory. This is important when getting `sphinx-build`
# to ONLY rebuild updated documents, since changing the directory
# from which they are generated (normally the randomly-named temp
# dir) will force Sphinx to do a full-rebuild because it remembers
# the doc paths from which the build was last generated.
# - docs_dev
# Forces "fresh_env" to False, and "fixed_tmp_dir" to True. This is
# merely a shortcut to having both "no_fresh_env" and "fixed_tmp_dir"
# on the command line.
# - skip_trans
# Skips adding translation links. This allows direct copying of
# of .RST files to `temp_directory` when they are updated to save
# time during re-build. Final build must not include this option
# so that the translation links are added at the top of each page.
#
# With arguments [skip_latex, develop, docs_dev], Sphinx will generate
# docs from a fixed temporary directory that can be then used later from
# the LVGL ./docs/ directory like this:
#
# $ sphinx-build -b html "fixed_temp_dir" "..\out_html" -D version="9.3" -j cpu_count
#
# to only rebuild docs that have been updated.
# -------------------------------------------------------------------------
clean = 0
skip_latex = False
skip_api = False
fresh_env = True
develop = False
fixed_tmp_dir = False
docs_dev = False
skip_trans = False
args = sys.argv[1:]
if len(args) >= 1:
if "clean" in args:
clean = 1
if "skip_latex" in args:
skip_latex = True
if 'skip_api' in args:
skip_api = True
if 'no_fresh_env' in args:
fresh_env = False
if 'develop' in args:
develop = True
if 'fixed_tmp_dir' in args:
fixed_tmp_dir = True
if 'docs_dev' in args:
docs_dev = True
if 'skip_trans' in args:
skip_trans = True
# Arg ramifications...
# docs_dev implies no fresh_env
if docs_dev:
fresh_env = False
fixed_tmp_dir = True
# -------------------------------------------------------------------------
# Due to the modifications that take place to the documentation files
# when the documentation builds it is better to copy the source files to a
# temporary folder and modify the copies. Not setting it up this way makes it
# a real headache when making alterations that need to be committed as the
# alterations trigger the files as changed.
# If there is debugging that needs to be done you can provide a command line
# switch of "develop" and it will leave the temporary directory in tact and
# that directory will be output at the end of the build.
# the html and PDF output locations are going to remain the same as they were.
# alterations trigger the files as changed. Also, this keeps maintenance
# effort to a minimum as adding a new language translation only needs to be
# done in 2 places (add_translation.py and ./docs/_ext/link_roles.py) rather
# than once for each .rst file.
#
# The html and PDF output locations are going to remain the same as they were.
# it's just the source documentation files that are going to be copied.
# -------------------------------------------------------------------------
if fixed_tmp_dir and 'LVGL_FIXED_TEMP_DIR' in os.environ:
temp_directory = os.environ['LVGL_FIXED_TEMP_DIR']
else:
temp_directory = tempfile.mkdtemp(suffix='.lvgl_docs')
temp_directory = tempfile.mkdtemp(suffix='.lvgl_docs')
print(f'Using temp directory: [{temp_directory}]')
langs = ['en']
# Change to script directory for consistency
# -------------------------------------------------------------------------
# Set up paths.
# -------------------------------------------------------------------------
base_path = os.path.abspath(os.path.dirname(__file__))
project_path = os.path.abspath(os.path.join(base_path, '..'))
examples_path = os.path.join(project_path, 'examples')
@@ -48,24 +136,14 @@ pdf_dst_file = os.path.join(temp_directory, 'LVGL.pdf')
html_src_path = temp_directory
html_dst_path = os.path.join(project_path, 'out_html')
# -------------------------------------------------------------------------
# Change to script directory for consistency.
# -------------------------------------------------------------------------
os.chdir(base_path)
clean = 0
trans = 0
skip_latex = False
develop = False
args = sys.argv[1:]
if len(args) >= 1:
if "clean" in args:
clean = 1
if "skip_latex" in args:
skip_latex = True
if 'develop' in args:
develop = True
# -------------------------------------------------------------------------
# Provide a way to run an external command and abort build on error.
# -------------------------------------------------------------------------
def cmd(s, start_dir=None):
if start_dir is None:
start_dir = os.getcwd()
@@ -79,18 +157,32 @@ def cmd(s, start_dir=None):
os.chdir(saved_dir)
if result != 0:
print("Exit build due to previous error")
print("Exiting build due to previous error.")
sys.exit(result)
# Get the current branch name
# -------------------------------------------------------------------------
# Get current branch name
# -------------------------------------------------------------------------
# 03-Oct-2024: Gabor requested this be changed to a branch name
# since that will always be current, and it will fix a large number
# of broken links on the docs website. This gets used in the
# 'Edit on GitHub' links in the upper-right corner of pages.
# Original code:
# status, br = subprocess.getstatusoutput("git branch --show-current")
# _, gitcommit = subprocess.getstatusoutput("git rev-parse HEAD")
# br = re.sub(r'\* ', '', br)
status, br = subprocess.getstatusoutput("git branch --show-current")
_, gitcommit = subprocess.getstatusoutput("git rev-parse HEAD")
br = re.sub(r'\* ', '', br)
# If in an unusual branch that is not 'master' or 'release/...'
# then default to 'master'.
if '/' in br and 'release' not in br:
br = 'master'
gitcommit = br
urlpath = re.sub('release/', '', br)
# These environment variables are used in other scripts.
os.environ['LVGL_URLPATH'] = urlpath
os.environ['LVGL_GITCOMMIT'] = gitcommit
@@ -101,8 +193,9 @@ print("****************")
print("Building")
print("****************")
# Remove all previous output files if 'clean' on command line.
if clean:
print('cleaning...')
print('Removing previous output files...')
# api_path = os.path.join(dname, 'API')
# xml_path = os.path.join(dname, 'xml')
# doxy_path = os.path.join(dname, 'doxygen_html')
@@ -125,11 +218,21 @@ if clean:
# os.mkdir(api_path)
# os.mkdir(lang)
# -------------------------------------------------------------------------
# Build local lv_conf.h from lv_conf_template.h for this build only.
# -------------------------------------------------------------------------
config_builder.run()
# -------------------------------------------------------------------------
# Copy files to 'temp_directory' where they will be edited
# (translation link and API links) before being used to generate new docs.
# -------------------------------------------------------------------------
shutil.copytree('.', temp_directory, dirs_exist_ok=True)
shutil.copytree(examples_path, os.path.join(temp_directory, 'examples'))
shutil.copytree(examples_path, os.path.join(temp_directory, 'examples'), dirs_exist_ok=True)
# -------------------------------------------------------------------------
# Replace tokens in Doxyfile in 'temp_directory' with data from this run.
# -------------------------------------------------------------------------
with open(os.path.join(temp_directory, 'Doxyfile'), 'rb') as f:
data = f.read().decode('utf-8')
@@ -139,35 +242,69 @@ data = data.replace('*#*#SRC#*#*', '"{0}"'.format(lvgl_src_path))
with open(os.path.join(temp_directory, 'Doxyfile'), 'wb') as f:
f.write(data.encode('utf-8'))
print("Generate the list of examples")
# -------------------------------------------------------------------------
# Generate examples pages.
# -------------------------------------------------------------------------
print("Generating examples...")
ex.exec(temp_directory)
print("Add translation")
add_translation.exec(temp_directory)
if skip_trans:
print("Skipping translation links as requested.")
else:
# ---------------------------------------------------------------------
# Add translation links at top of all .rst files.
# ---------------------------------------------------------------------
print("Adding translation links...")
add_translation.exec(temp_directory)
print("Running doxygen")
cmd('doxygen Doxyfile', temp_directory)
if skip_api:
print("Skipping API generation as requested.")
else:
# ---------------------------------------------------------------------
# Generate API pages and links thereto.
# ---------------------------------------------------------------------
print("Running Doxygen...")
cmd('doxygen Doxyfile', temp_directory)
print("Generating API documentation .RST files...")
print('Reading Doxygen output')
doc_builder.EMIT_WARNINGS = False
doc_builder.EMIT_WARNINGS = False
# Create .RST files for API pages.
doc_builder.run(
project_path,
temp_directory,
os.path.join(temp_directory, 'intro'),
os.path.join(temp_directory, 'intro', 'add-lvgl-to-your-project'),
os.path.join(temp_directory, 'details'),
os.path.join(temp_directory, 'details', 'base-widget'),
os.path.join(temp_directory, 'details', 'base-widget', 'layouts'),
os.path.join(temp_directory, 'details', 'base-widget', 'styles'),
os.path.join(temp_directory, 'details', 'debugging'),
os.path.join(temp_directory, 'details', 'integration'),
os.path.join(temp_directory, 'details', 'integration', 'bindings'),
os.path.join(temp_directory, 'details', 'integration', 'building'),
os.path.join(temp_directory, 'details', 'integration', 'chip'),
os.path.join(temp_directory, 'details', 'integration', 'driver'),
os.path.join(temp_directory, 'details', 'integration', 'driver', 'display'),
os.path.join(temp_directory, 'details', 'integration', 'driver', 'touchpad'),
os.path.join(temp_directory, 'details', 'integration', 'framework'),
os.path.join(temp_directory, 'details', 'integration', 'ide'),
os.path.join(temp_directory, 'details', 'integration', 'os'),
os.path.join(temp_directory, 'details', 'integration', 'os', 'yocto'),
os.path.join(temp_directory, 'details', 'integration', 'renderers'),
os.path.join(temp_directory, 'details', 'libs'),
os.path.join(temp_directory, 'details', 'main-components'),
os.path.join(temp_directory, 'details', 'other-components'),
os.path.join(temp_directory, 'details', 'widgets')
)
doc_builder.run(
project_path,
temp_directory,
os.path.join(temp_directory, 'layouts'),
os.path.join(temp_directory, 'libs'),
os.path.join(temp_directory, 'others'),
os.path.join(temp_directory, 'overview'),
os.path.join(temp_directory, 'overview', 'renderers'),
os.path.join(temp_directory, 'porting'),
os.path.join(temp_directory, 'widgets')
)
print('Reading Doxygen output...')
# we make sure to remove the link to the PDF before the PDF get generated
# -------------------------------------------------------------------------
# We make sure to remove the link to the PDF before the PDF get generated
# doesn't make any sense to have a link to the PDF in the PDF. The link gets
# added if there is a PDF build so the HTML build will have the link.
# -------------------------------------------------------------------------
index_path = os.path.join(temp_directory, 'index.rst')
with open(index_path, 'rb') as f:
@@ -181,11 +318,12 @@ if 'PDF version: :download:`LVGL.pdf <LVGL.pdf>`' in index_data:
with open(index_path, 'wb') as f:
f.write(index_data.encode('utf-8'))
# -------------------------------------------------------------------------
# BUILD PDF
# -------------------------------------------------------------------------
if skip_latex:
print("skipping latex build as requested")
print("Skipping latex build as requested.")
else:
# Silly workaround to include the more or less correct
# PDF download link in the PDF
# cmd("cp -f " + lang +"/latex/LVGL.pdf LVGL.pdf | true")
@@ -212,9 +350,10 @@ else:
with open(index_path, 'wb') as f:
f.write(index_data.encode('utf-8'))
# -------------------------------------------------------------------------
# BUILD HTML
# This version of get_version() works correctly under Windows and Linux.
# Credit: @kdschlosser
# -------------------------------------------------------------------------
# This version of get_version() also works correctly under Windows.
def get_version():
path = os.path.join(project_path, 'lv_version.h')
with open(path, 'rb') as fle:
@@ -230,17 +369,39 @@ def get_version():
return f'{major.strip()}.{minor.strip()}'
cmd('sphinx-build -b html "{src}" "{dst}" -D version="{version}" -E -j {cpu}'.format(
src=html_src_path,
dst=html_dst_path,
version=get_version(),
cpu=os.cpu_count()
))
if develop:
print('temp directory:', temp_directory)
# -------------------------------------------------------------------------
# Run Sphinx after determining whether to use -E (fresh environment)
# command-line argument.
# -------------------------------------------------------------------------
if fresh_env:
# Uses -E option (same as --fresh-env). Forces sphinx-build to rebuild sphinx
# environment so that all docs are fully regenerated, even if they have not changed.
print("Regenerating all files...")
cmd('sphinx-build -b html "{src}" "{dst}" -D version="{version}" -E -j {cpu}'.format(
src=html_src_path,
dst=html_dst_path,
version=get_version(),
cpu=os.cpu_count()
))
else:
# Does not use -E option (same as --fresh-env).
print("Regenerating only updated files...")
cmd('sphinx-build -b html "{src}" "{dst}" -D version="{version}" -j {cpu}'.format(
src=html_src_path,
dst=html_dst_path,
version=get_version(),
cpu=os.cpu_count()
))
# -------------------------------------------------------------------------
# If 'develop' was specified on command line, announce location of temp dir.
# Otherwise, remove temporary files created for the doc build.
# -------------------------------------------------------------------------
if develop:
print('Temp directory: ', temp_directory)
else:
print('Removing temporary files...', temp_directory)
# Recursively remove generated files in `temp_directory`.
def iter_temp(p):
folders = []
remove_folder = True
@@ -268,7 +429,13 @@ else:
iter_temp(temp_directory)
# -------------------------------------------------------------------------
# Remove temporary `lv_conf.h` created for this build.
# -------------------------------------------------------------------------
config_builder.cleanup()
print('output path:', html_dst_path)
print('\nFINISHED!!')
# -------------------------------------------------------------------------
# Indicate results.
# -------------------------------------------------------------------------
print('Output path: ', html_dst_path)
print('Finished.')
+45 -8
View File
@@ -44,7 +44,8 @@ extensions = [
'sphinx_design',
'sphinx_rtd_dark_mode',
'link_roles',
'sphinxcontrib.mermaid'
'sphinxcontrib.mermaid',
'sphinx_reredirects'
]
default_dark_mode = False
@@ -61,7 +62,7 @@ highlight_language = 'c'
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
source_suffix = ['.rst']
source_suffix = {'.rst': 'restructuredtext'}
# The master toctree document.
@@ -78,7 +79,8 @@ author = 'LVGL community'
# built documents.
#
# The short X.Y version.
# embeddedt: extract using scripts/find_version.sh
# `version` is extracted from lv_version.h using a cross-platform compatible
# Python function in build.py, and passed in on `sphinx-build` command line.
version = ''
@@ -114,9 +116,12 @@ html_theme = 'sphinx_rtd_theme'
# documentation.
#
# Note: 'display_version' option is now obsolete in the current (08-Oct-2024)
# version of sphinx-rtd-theme (upgraded for Sphinx v8.x). The removed line is
# preserved by commenting it out in case it is ever needed again.
html_theme_options = {
'display_version': True,
# 'display_version': True,
'prev_next_buttons_location': 'both',
'style_external_links': False,
# 'vcs_pageview_mode': '',
@@ -133,7 +138,12 @@ html_theme_options = {
# For site map generation
html_baseurl = f"https://docs.lvgl.io/{os.environ['LVGL_URLPATH']}/"
if "LVGL_URLPATH" not in os.environ:
os.environ['LVGL_URLPATH'] = 'master'
_branch = os.getenv('LVGL_URLPATH')
html_baseurl = f"https://docs.lvgl.io/{_branch}/"
sitemap_url_scheme = "{link}"
@@ -141,8 +151,13 @@ sitemap_url_scheme = "{link}"
#extlinks = {'github_link_base': (github_url + '%s', github_url)}
if "LVGL_GITCOMMIT" not in os.environ:
os.environ['LVGL_GITCOMMIT'] = 'master'
_git_commit_ref = os.getenv('LVGL_GITCOMMIT')
html_context = {
'github_version': os.environ['LVGL_GITCOMMIT'],
'github_version': _git_commit_ref,
'github_user': 'lvgl',
'github_repo': 'lvgl',
'display_github': True,
@@ -260,10 +275,30 @@ StandaloneHTMLBuilder.supported_image_types = [
'image/jpeg'
]
smartquotes = False
repo_commit_hash = os.environ['LVGL_GITCOMMIT']
# Enabling smart quotes action to convert -- to en dashes and --- to em dashes.
# Converting quotation marks and ellipses is NOT done because the default
# `smartquotes_action` 'qDe' is changed to just 'D' below, which accomplishes
# the dash conversions as desired.
smartquotes = True
smartquotes_action = 'D'
repo_commit_hash = _git_commit_ref
# -- Options for sphinx_reredirects ---------------------------------------
# The below generates .HTML page redirects for pages that have been moved.
# Browsers are redirected via `<meta http-equiv="refresh" content="0; url=new_url">`.
redirects = {
"get-started/index": "../intro/basics.html#going-deeper" ,
"integration/index": "../details/integration/index.html" ,
"porting/index": "../intro/add-lvgl-to-your-project/index.html",
"overview/index": "../details/main-components/index.html" ,
"layouts/index": "../details/base-widget/layouts/index.html" ,
"libs/index": "../details/libs/index.html" ,
"others/index": "../details/other-components/index.html"
}
# Example configuration for intersphinx: refer to the Python standard library.
@@ -275,3 +310,5 @@ def setup(app):
# app.add_transform(AutoStructify)
app.add_css_file('css/custom.css')
app.add_css_file('css/fontawesome.min.css')
+9 -1
View File
@@ -1,4 +1,12 @@
"""
Create lv_conf.h in same directory as this file
from ../lv_conf_template.h that has:
1. all its #define LV_USE... 0-or-1 options set to 1
(except for LV_USER_PROFILER),
2. all its #define LV_FONT... 0-or-1 options set to 1,
3. its #if 0 directive set to #if 1.
"""
import os
base_path = os.path.dirname(__file__)
@@ -25,7 +33,7 @@ def run(c_path=None):
if 'LV_USE_PROFILER' in line:
continue
if 'LV_USE' in line or 'LV_FONT' in line and '#define' in line:
if 'LV_USE' in line or ('LV_FONT' in line and '#define' in line):
line = [item for item in line.split(' ') if item]
for j, item in enumerate(line):
File diff suppressed because it is too large Load Diff
@@ -5,27 +5,30 @@ Events
======
Events are triggered in LVGL when something happens which might be
interesting to the user, e.g. when an object:
interesting to the user, e.g. when a Widget:
- is clicked
- is scrolled
- has its value changed
- is redrawn, etc.
Besides widgets, events can registered from displays and input devices too.
It's not detailed below, however the same applies to displays and indevs as well
by changing the prefix of the functions from ``lv_obj_`` to ``lv_display_`` or ``lv_indev_``.
Besides Widgets, events can registered from displays and input devices as well.
It is not detailed below, but you can do this by changing the prefix of the functions
from ``lv_obj_`` to ``lv_display_`` or ``lv_indev_``.
Add events to a widget
**********************
The user can assign callback functions to an object to see its events.
.. _adding_events_to_a_widget:
Adding Events to a Widget
*************************
The user can assign callback functions to a widget to process events.
In practice, it looks like this:
.. code-block:: c
lv_obj_t * btn = lv_button_create(lv_screen_active());
lv_obj_add_event_cb(btn, my_event_cb, LV_EVENT_CLICKED, NULL); /*Assign an event callback*/
lv_obj_add_event_cb(btn, my_event_cb, LV_EVENT_CLICKED, user_data); /* Assign an event callback */
...
@@ -39,30 +42,37 @@ call ``my_event_cb``. See the :ref:`list of event codes <events_codes>` for
all the options. :cpp:enumerator:`LV_EVENT_ALL` can be used to receive all events.
The last parameter of :cpp:func:`lv_obj_add_event` is a pointer to any custom
data that will be available in the event. It will be described later in
more detail.
More events can be added to an object, like this:
data that will be available in the event. NULL may be passed for this argument if
there is no need to use that data when the event is processed. You can retrieve the
pointer passed when setting the callback function like this:
.. code-block:: c
lv_obj_add_event_cb(obj, my_event_cb_1, LV_EVENT_CLICKED, NULL);
lv_obj_add_event_cb(obj, my_event_cb_2, LV_EVENT_PRESSED, NULL);
lv_obj_add_event_cb(obj, my_event_cb_3, LV_EVENT_ALL, NULL); /*No filtering, receive all events*/
my_user_data_t * user_data;
...
user_data = lv_event_get_user_data(e);
Even the same event callback can be used on an object with different
More events can be added to a Widget, like this:
.. code-block:: c
lv_obj_add_event_cb(widget, my_event_cb_1, LV_EVENT_CLICKED, NULL);
lv_obj_add_event_cb(widget, my_event_cb_2, LV_EVENT_PRESSED, NULL);
lv_obj_add_event_cb(widget, my_event_cb_3, LV_EVENT_ALL, NULL); /* No filtering, receive all events */
Even the same event callback can be used on a Widget with different
``user_data``. For example:
.. code-block:: c
lv_obj_add_event_cb(obj, increment_on_click, LV_EVENT_CLICKED, &num1);
lv_obj_add_event_cb(obj, increment_on_click, LV_EVENT_CLICKED, &num2);
lv_obj_add_event_cb(widget, increment_on_click, LV_EVENT_CLICKED, &num1);
lv_obj_add_event_cb(widget, increment_on_click, LV_EVENT_CLICKED, &num2);
The events will be called in the order as they were added.
Other objects can use the same *event callback*.
Other Widgets can use the same *event callback*.
In the very same way events can attached to the input devices and displays like this
In the very same way, events can be attached to input devices and displays like this:
.. code-block:: c
@@ -70,30 +80,31 @@ In the very same way events can attached to the input devices and displays like
lv_indev_add_event_cb(indev, event_cb, LV_EVENT_CLICKED, NULL);
Remove event(s) from widgets
****************************
Removing Event(s) from Widgets
******************************
.. code-block:: c
uint32_t i;
uint32_t event_cnt = lv_obj_get_event_count(obj);
uint32_t event_cnt = lv_obj_get_event_count(widget);
for(i = 0; i < event_cnt; i++) {
lv_event_dsc_t * event_dsc = lv_obj_get_event_dsc(obj, i);
lv_event_dsc_t * event_dsc = lv_obj_get_event_dsc(widget, i);
if(lv_event_dsc_get_cb(event_dsc) == some_event_cb) {
lv_obj_remove_event(obj, i);
lv_obj_remove_event(widget, i);
break;
}
}
.. _events_codes:
Event codes
Event Codes
***********
The event codes can be grouped into these categories: - Input device
events - Drawing events - Other events - Special events - Custom events
All objects (such as Buttons/Labels/Sliders etc.) regardless their type
All Widgets (such as Buttons/Labels/Sliders etc.) regardless their type
receive the *Input device*, *Drawing* and *Other* events.
However, the *Special events* are specific to a particular widget type.
@@ -104,40 +115,39 @@ are sent,
The following event codes exist:
Input device events
Input Device Events
-------------------
- :cpp:enumerator:`LV_EVENT_PRESSED`: The object has been pressed
- :cpp:enumerator:`LV_EVENT_PRESSING`: The object is being pressed (called continuously while pressing)
- :cpp:enumerator:`LV_EVENT_PRESS_LOST`: The object is still being pressed but slid cursor/finger off of the object
- :cpp:enumerator:`LV_EVENT_SHORT_CLICKED`: The object was pressed for a short period of time, and then released without scrolling.
- :cpp:enumerator:`LV_EVENT_SINGLE_CLICKED`: The object was pressed for a short period of time, and then released without scrolling, for the first time in a click streak. A click streak refers to multiple short clicks within a short period of time and a small distance.
- :cpp:enumerator:`LV_EVENT_DOUBLE_CLICKED`: The object was pressed for a short period of time, and then released without scrolling, for the second time in a click streak.
- :cpp:enumerator:`LV_EVENT_TRIPLE_CLICKED`: The object was pressed for a short period of time, and then released without scrolling, for the third time in a click streak.
- :cpp:enumerator:`LV_EVENT_LONG_PRESSED`: Object has been pressed for at least `long_press_time`. Not called if scrolled.
- :cpp:enumerator:`LV_EVENT_PRESSED`: Widget has been pressed
- :cpp:enumerator:`LV_EVENT_PRESSING`: Widget is being pressed (called continuously while pressing)
- :cpp:enumerator:`LV_EVENT_PRESS_LOST`: Widget is still being pressed but slid cursor/finger off Widget
- :cpp:enumerator:`LV_EVENT_SHORT_CLICKED`: Widget was pressed for a short period of time, and then released without scrolling.
- :cpp:enumerator:`LV_EVENT_SINGLE_CLICKED`: Widget was pressed for a short period of time, and then released without scrolling, for the first time in a click streak. A click streak refers to multiple short clicks within a short period of time and a small distance.
- :cpp:enumerator:`LV_EVENT_DOUBLE_CLICKED`: Widget was pressed for a short period of time, and then released without scrolling, for the second time in a click streak.
- :cpp:enumerator:`LV_EVENT_TRIPLE_CLICKED`: Widget was pressed for a short period of time, and then released without scrolling, for the third time in a click streak.
- :cpp:enumerator:`LV_EVENT_LONG_PRESSED`: Widget has been pressed for at least `long_press_time`. Not called if scrolled.
- :cpp:enumerator:`LV_EVENT_LONG_PRESSED_REPEAT`: Called after `long_press_time` in every `long_press_repeat_time` ms. Not called if scrolled.
- :cpp:enumerator:`LV_EVENT_CLICKED`: Called on release if not scrolled (regardless of long press)
- :cpp:enumerator:`LV_EVENT_RELEASED`: Called in every cases when the object has been released
- :cpp:enumerator:`LV_EVENT_RELEASED`: Called in every cases when Widget has been released
- :cpp:enumerator:`LV_EVENT_SCROLL_BEGIN`: Scrolling begins. The event parameter is a pointer to the animation of the scroll. Can be modified
- :cpp:enumerator:`LV_EVENT_SCROLL_THROW_BEGIN`:
- :cpp:enumerator:`LV_EVENT_SCROLL_END`: Scrolling ends
- :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_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_DEFOCUSED`: The object is defocused
- :cpp:enumerator:`LV_EVENT_LEAVE`: The object is defocused but still selected
- :cpp:enumerator:`LV_EVENT_KEY`: A key is sent to Widget. Get the key with :cpp:expr:`lv_indev_get_key(lv_indev_active())`
- :cpp:enumerator:`LV_EVENT_FOCUSED`: Widget received focus
- :cpp:enumerator:`LV_EVENT_DEFOCUSED`: Widget is defocused
- :cpp:enumerator:`LV_EVENT_LEAVE`: Widget is defocused but still selected
- :cpp:enumerator:`LV_EVENT_HIT_TEST`: Perform advanced hit-testing
- :cpp:enumerator:`LV_EVENT_INDEV_RESET`: Indev has been reset
- :cpp:enumerator:`LV_EVENT_HOVER_OVER`: Indev hover over object
- :cpp:enumerator:`LV_EVENT_HOVER_LEAVE`: Indev hover leave object
- :cpp:enumerator:`LV_EVENT_HOVER_OVER`: Indev hover over Widget
- :cpp:enumerator:`LV_EVENT_HOVER_LEAVE`: Indev hover leave Widget
Drawing Events
--------------
- :cpp:enumerator:`LV_EVENT_COVER_CHECK`: Check if the object fully covers an area. The event parameter is :cpp:type:`lv_cover_check_info_t` ``*``.
- :cpp:enumerator:`LV_EVENT_REFR_EXT_DRAW_SIZE`: Get the required extra draw area around the object (e.g. for shadow). The event parameter is :cpp:type:`int32_t` ``*`` to store the size.
- :cpp:enumerator:`LV_EVENT_COVER_CHECK`: Check if Widget fully covers an area. The event parameter is :cpp:type:`lv_cover_check_info_t` ``*``.
- :cpp:enumerator:`LV_EVENT_REFR_EXT_DRAW_SIZE`: Get the required extra draw area around Widget (e.g. for shadow). The event parameter is :cpp:type:`int32_t` ``*`` to store the size.
- :cpp:enumerator:`LV_EVENT_DRAW_MAIN_BEGIN`: Starting the main drawing phase
- :cpp:enumerator:`LV_EVENT_DRAW_MAIN`: Perform the main drawing
- :cpp:enumerator:`LV_EVENT_DRAW_MAIN_END`: Finishing the main drawing phase
@@ -146,20 +156,20 @@ Drawing Events
- :cpp:enumerator:`LV_EVENT_DRAW_POST_END`: Finishing the post draw phase (when all children are drawn)
- :cpp:enumerator:`LV_EVENT_DRAW_TASK_ADDED`: Adding a draw task
Special events
Special Events
--------------
- :cpp:enumerator:`LV_EVENT_VALUE_CHANGED`: The object's value has changed (i.e. slider moved)
- :cpp:enumerator:`LV_EVENT_INSERT`: A text is inserted to the object. The event data is :cpp:type:`char` ``*`` being inserted.
- :cpp:enumerator:`LV_EVENT_REFRESH`: Notify the object to refresh something on it (for the user)
- :cpp:enumerator:`LV_EVENT_VALUE_CHANGED`: Widget's value has changed (i.e. slider moved)
- :cpp:enumerator:`LV_EVENT_INSERT`: A text is inserted to Widget. The event data is ``char `*`` being inserted.
- :cpp:enumerator:`LV_EVENT_REFRESH`: Notify Widget to refresh something on it (for the user)
- :cpp:enumerator:`LV_EVENT_READY`: A process has finished
- :cpp:enumerator:`LV_EVENT_CANCEL`: A process has been cancelled
Other events
Other Events
------------
- :cpp:enumerator:`LV_EVENT_CREATE`: Object is being created
- :cpp:enumerator:`LV_EVENT_DELETE`: Object is being deleted
- :cpp:enumerator:`LV_EVENT_CREATE`: Widget is being created
- :cpp:enumerator:`LV_EVENT_DELETE`: Widget is being deleted
- :cpp:enumerator:`LV_EVENT_CHILD_CHANGED`: Child was removed, added, or its size, position were changed
- :cpp:enumerator:`LV_EVENT_CHILD_CREATED`: Child was created, always bubbles up to all parents
- :cpp:enumerator:`LV_EVENT_CHILD_DELETED`: Child was deleted, always bubbles up to all parents
@@ -167,12 +177,12 @@ Other events
- :cpp:enumerator:`LV_EVENT_SCREEN_LOAD_START`: A screen load started, fired when the screen change delay is expired
- :cpp:enumerator:`LV_EVENT_SCREEN_LOADED`: A screen was loaded
- :cpp:enumerator:`LV_EVENT_SCREEN_UNLOADED`: A screen was unloaded
- :cpp:enumerator:`LV_EVENT_SIZE_CHANGED`: Object coordinates/size have changed
- :cpp:enumerator:`LV_EVENT_STYLE_CHANGED`: Object's style has changed
- :cpp:enumerator:`LV_EVENT_SIZE_CHANGED`: Widget coordinates/size have changed
- :cpp:enumerator:`LV_EVENT_STYLE_CHANGED`: Widget's style has changed
- :cpp:enumerator:`LV_EVENT_LAYOUT_CHANGED`: The children position has changed due to a layout recalculation
- :cpp:enumerator:`LV_EVENT_GET_SELF_SIZE`: Get the internal size of a widget
Display events
Display Events
--------------
- :cpp:enumerator:`LV_EVENT_INVALIDATE_AREA`
@@ -187,44 +197,47 @@ Display events
- :cpp:enumerator:`LV_EVENT_FLUSH_FINISH`
Custom events
Custom Events
-------------
Any number of custom event codes can be registered by
``uint32_t MY_EVENT_1 =`` :cpp:func:`lv_event_register_id`
They can be sent to any objects with
:cpp:expr:`lv_obj_send_event(obj, MY_EVENT_1, &some_data)`
They can be sent to any Widget with
:cpp:expr:`lv_obj_send_event(widget, MY_EVENT_1, &some_data)`
Sending events
**************
To manually send events to an object, use
``lv_obj_send_event(obj, <EVENT_CODE>, &some_data)``.
Refresh Event
-------------
:cpp:enumerator:`LV_EVENT_REFRESH` is a special event because it's designed to let the
user notify a Widget to refresh itself. Some examples:
- notify a label to refresh its text according to one or more variables (e.g. current time)
- refresh a label when the language changes
- enable a button if some conditions are met (e.g. the correct PIN is entered)
- add/remove styles to/from a Widget if a limit is exceeded, etc
Sending Events Manually
***********************
To manually send events to a Widget, use
``lv_obj_send_event(widget, <EVENT_CODE>, &some_data)``.
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):
.. 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;
lv_obj_send_event(mbox, LV_EVENT_VALUE_CHANGED, &btn_id);
The same works for display and input devices with
``lv_display_send_event(obj, <EVENT_CODE>, &some_data)`` and
``lv_indev_send_event(obj, <EVENT_CODE>, &some_data)``.
``lv_display_send_event(widget, <EVENT_CODE>, &some_data)`` and
``lv_indev_send_event(widget, <EVENT_CODE>, &some_data)``.
Refresh event
-------------
:cpp:enumerator:`LV_EVENT_REFRESH` is a special event because it's designed to let the
user notify an object to refresh itself. Some examples:
- notify a label to refresh its text according to one or more variables (e.g. current time)
- refresh a label when the language changes
- enable a button if some conditions are met (e.g. the correct PIN is entered)
- add/remove styles to/from an object if a limit is exceeded, etc
Fields of lv_event_t
********************
@@ -233,31 +246,34 @@ Fields of lv_event_t
contains all data about the event. The following values can be gotten from it:
- :cpp:expr:`lv_event_get_code(e)`: get the event code
- :cpp:expr:`lv_event_get_current_target(e)`: get the object to which an event was sent. I.e. the object whose event handler is being called.
- :cpp:expr:`lv_event_get_target(e)`: get the object that originally triggered the event (different from :cpp:func:`lv_event_get_target` if :ref:`event bubbling <event_bubbling>` is enabled)
- :cpp:expr:`lv_event_get_current_target(e)`: get Widget to which an event was sent. I.e. the Widget whose event handler is being called.
- :cpp:expr:`lv_event_get_target(e)`: get Widget that originally triggered the event (different from :cpp:func:`lv_event_get_target` if :ref:`event bubbling <event_bubbling>` is enabled)
- :cpp:expr:`lv_event_get_user_data(e)`: get the pointer passed as the last parameter of :cpp:func:`lv_obj_add_event`.
- :cpp:expr:`lv_event_get_param(e)`: get the parameter passed as the last parameter of :cpp:func:`lv_obj_send_event`
.. _event_bubbling:
Event bubbling
Event Bubbling
**************
If :cpp:expr:`lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE)` is enabled all
events will be sent to an object's parent too. If the parent also has
If :cpp:expr:`lv_obj_add_flag(widget, LV_OBJ_FLAG_EVENT_BUBBLE)` is enabled all
events will be sent to a Widget's parent as well. If the parent also has
:cpp:enumerator:`LV_OBJ_FLAG_EVENT_BUBBLE` enabled the event will be sent to its
parent and so on.
parent, and so on.
The *target* parameter of the event is always the current target object,
not the original object. To get the original target call
The *target* parameter of the event is always the current target Widget,
not the original Widget. To get the original target call
:cpp:expr:`lv_event_get_target_obj(e)` in the event handler.
.. _events_examples:
Examples
********
.. include:: ../examples/event/index.rst
.. include:: ../../examples/event/index.rst
.. _events_api:
+18
View File
@@ -0,0 +1,18 @@
.. _base_widget_overview:
===========
Base Widget
===========
The following details apply to all types of Widgets.
.. toctree::
:maxdepth: 3
obj
coord
layer
styles/index
event
layouts/index
scroll
+126
View File
@@ -0,0 +1,126 @@
.. _layers:
======
Layers
======
When the term "layer" is used in LVGL documentation, it may refer to one of several
things:
1. for Widgets, the :ref:`layers_creation` creates a natural layering of Widgets;
2. in the context of pixel rendering (drawing), there are :ref:`draw_layers`;
3. permanent :ref:`screen_layers` are part of each :ref:`display` object, and
are covered :ref:`here <screen_layers>`
#1 and #2 are covered below.
.. _layers_creation:
Order of Creation
*****************
By default, LVGL draws new Widgets on top of old Widgets.
For example, assume we add a button to a parent Widget named button1 and
then another button named button2. Then button1 (along with its child
Widget(s)) will be in the background and can be covered by button2 and
its children.
.. image:: /misc/layers.png
.. code-block:: c
/* Create a screen */
lv_obj_t * scr = lv_obj_create(NULL, NULL);
lv_screen_load(scr); /* Load the screen */
/* Create 2 buttons */
lv_obj_t * btn1 = lv_button_create(scr, NULL); /* Create a button on the screen */
lv_button_set_fit(btn1, true, true); /* Enable automatically setting the size according to content */
lv_obj_set_pos(btn1, 60, 40); /* Set the position of the button */
lv_obj_t * btn2 = lv_button_create(scr, btn1); /* Copy the first button */
lv_obj_set_pos(btn2, 180, 80); /* Set the position of the button */
/* Add labels to the buttons */
lv_obj_t * label1 = lv_label_create(btn1, NULL); /* Create a label on the first button */
lv_label_set_text(label1, "Button 1"); /* Set the text of the label */
lv_obj_t * label2 = lv_label_create(btn2, NULL); /* Create a label on the second button */
lv_label_set_text(label2, "Button 2"); /* Set the text of the label */
/* Delete the second label */
lv_obj_delete(label2);
.. _layers_order:
Changing Order
--------------
There are four explicit ways to bring a Widget to the foreground:
- Use :cpp:expr:`lv_obj_move_foreground(widget)` to bring a Widget to the foreground.
Similarly, use :cpp:expr:`lv_obj_move_background(widget)` to move it to the background.
- Use :cpp:expr:`lv_obj_move_to_index(widget, idx)` to move a Widget to a given index in the order of children.
- ``0``: background
- ``child_num - 1``: foreground
- ``< 0``: count from the top, to move forward (up): :cpp:expr:`lv_obj_move_to_index(widget, lv_obj_get_index(widget) - 1)`
- Use :cpp:expr:`lv_obj_swap(widget1, widget2)` to swap the relative layer position of two Widgets.
- When :cpp:expr:`lv_obj_set_parent(widget, new_parent)` is used, ``widget`` will be on the foreground of ``new_parent``.
.. _draw_layers:
Draw Layers
***********
Some style properties cause LVGL to allocate a buffer and render a Widget and its
children there first. Later that layer will be merged to the screen or its parent
layer after applying some transformations or other modifications.
Simple Layer
------------
The following style properties trigger the creation of a "Simple Layer":
- ``opa_layered``
- ``bitmap_mask_src``
- ``blend_mode``
In this case the Widget will be sliced into ``LV_DRAW_SW_LAYER_SIMPLE_BUF_SIZE``
sized chunks.
If there is no memory for a new chunk, LVGL will try allocating the layer after
another chunk is rendered and freed.
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.
The following style properties trigger the creation of a "Transform Layer":
- ``transform_scale_x``
- ``transform_scale_y``
- ``transform_skew_x``
- ``transform_skew_y``
- ``transform_rotate``
Clip corner
-----------
The ``clip_corner`` style property also causes LVGL to create a 2 layers with radius
height for the top and bottom parts of the Widget.
.. _layers_api:
API
***
@@ -14,8 +14,8 @@ adjust the spacing between the items and tracks, handle *grow* to make
the item(s) fill the remaining space with respect to min/max width and
height.
To make an object flex container call
:cpp:expr:`lv_obj_set_layout(obj, LV_LAYOUT_FLEX)`.
To make a Widget flex container call
:cpp:expr:`lv_obj_set_layout(widget, LV_LAYOUT_FLEX)`.
Note that the flex layout feature of LVGL needs to be globally enabled
with :c:macro:`LV_USE_FLEX` in ``lv_conf.h``.
@@ -43,7 +43,7 @@ With the following functions you can set a Flex layout on any parent.
Flex flow
---------
:cpp:expr:`lv_obj_set_flex_flow(obj, flex_flow)`
:cpp:expr:`lv_obj_set_flex_flow(widget, flex_flow)`
The possible values for ``flex_flow`` are:
@@ -62,7 +62,7 @@ Flex align
----------
To manage the placement of the children use
:cpp:expr:`lv_obj_set_flex_align(obj, main_place, cross_place, track_cross_place)`
:cpp:expr:`lv_obj_set_flex_align(widget, main_place, cross_place, track_cross_place)`
- ``main_place`` determines how to distribute the items in their track
on the main axis. E.g. flush the items to the right on :cpp:enumerator:`LV_FLEX_FLOW_ROW_WRAP`. (It's called
@@ -99,7 +99,7 @@ Flex grow
Flex grow can be used to make one or more children fill the available
space on the track. When more children have grow parameters, the
available space will be distributed proportionally to the grow values.
For example, there is 400 px remaining space and 4 objects with grow:
For example, there is 400 px remaining space and 4 Widgets with grow:
- ``A`` with grow = 1
- ``B`` with grow = 1
@@ -132,7 +132,7 @@ The following flex related style properties exist:
Internal padding
----------------
To modify the minimum space flexbox inserts between objects, the
To modify the minimum space flexbox inserts between Widgets, the
following properties can be set on the flex container style:
- ``pad_row`` Sets the padding between the rows.
@@ -140,7 +140,7 @@ following properties can be set on the flex container style:
- ``pad_column`` Sets the padding between the columns.
These can for example be used if you don't want any padding between your
objects: :cpp:expr:`lv_style_set_pad_column(&row_container_style,0)`
Widgets: :cpp:expr:`lv_style_set_pad_column(&row_container_style,0)`
.. _flex_other:
@@ -170,7 +170,7 @@ You can force Flex to put an item into a new line with
Example
*******
.. include:: ../examples/layouts/flex/index.rst
.. include:: ../../../examples/layouts/flex/index.rst
.. _flex_api:
@@ -15,7 +15,7 @@ track's size can be set in pixel, to the largest item
(:c:macro:`LV_GRID_CONTENT`) or in "Free unit" (FR) to distribute the free
space proportionally.
To make an object a grid container call :cpp:expr:`lv_obj_set_layout(obj, LV_LAYOUT_GRID)`.
To make a Widget a grid container call :cpp:expr:`lv_obj_set_layout(widget, LV_LAYOUT_GRID)`.
Note that the grid layout feature of LVGL needs to be globally enabled
with :c:macro:`LV_USE_GRID` in ``lv_conf.h``.
@@ -47,11 +47,11 @@ For example:
.. 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 row_dsc[] = {100, 100, 100, LV_GRID_TEMPLATE_LAST}; /*3 100 px tall rows*/
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 */
To set the descriptors on a parent use
:cpp:expr:`lv_obj_set_grid_dsc_array(obj, col_dsc, row_dsc)`.
:cpp:expr:`lv_obj_set_grid_dsc_array(widget, col_dsc, row_dsc)`.
Besides simple settings the size in pixel you can use two special
values:
@@ -105,7 +105,7 @@ If there are some empty space the track can be aligned several ways:
item on the end line. Not applies to ``track_cross_place``.
To set the track's alignment use
:cpp:expr:`lv_obj_set_grid_align(obj, column_align, row_align)`.
:cpp:expr:`lv_obj_set_grid_align(widget, column_align, row_align)`.
.. _grid_subgrid:
@@ -151,7 +151,7 @@ The following Grid related style properties exist:
Internal padding
----------------
To modify the minimum space Grid inserts between objects, the following
To modify the minimum space Grid inserts between Widgets, the following
properties can be set on the Grid container style:
- ``pad_row`` Sets the padding between the rows.
@@ -176,7 +176,7 @@ The columns will be placed from right to left.
Example
*******
.. include:: ../examples/layouts/grid/index.rst
.. include:: ../../../examples/layouts/grid/index.rst
.. _grid_api:
File diff suppressed because it is too large Load Diff
@@ -1,22 +1,24 @@
.. _scroll:
.. _scrolling:
=========
Scrolling
=========
======
Scroll
======
Overview
********
In LVGL scrolling works very intuitively: if an object is outside its
In LVGL scrolling works very intuitively: if a Widget is outside its
parent content area (the size without padding), the parent becomes
scrollable and scrollbar(s) will appear. That's it.
Any object can be scrollable including ``lv_obj``, ``lv_image``,
Any Widget can be scrollable including :ref:`base_widget`, ``lv_image``,
``lv_button``, ``lv_meter``, etc
The object can either be scrolled horizontally or vertically in one
The Widget can either be scrolled horizontally or vertically in one
stroke; diagonal scrolling is not possible.
Scrollbar
---------
@@ -28,10 +30,10 @@ following ``mode``\ (s) exist:
- :cpp:enumerator:`LV_SCROLLBAR_MODE_OFF`: Never show the scrollbars
- :cpp:enumerator:`LV_SCROLLBAR_MODE_ON`: Always show the scrollbars
- :cpp:enumerator:`LV_SCROLLBAR_MODE_ACTIVE`: Show scroll bars while an object is being scrolled
- :cpp:enumerator:`LV_SCROLLBAR_MODE_ACTIVE`: Show scroll bars while a Widget is being scrolled
- :cpp:enumerator:`LV_SCROLLBAR_MODE_AUTO`: Show scroll bars when the content is large enough to be scrolled
``lv_obj_set_scrollbar_mode(obj, LV_SCROLLBAR_MODE_...)`` sets the scrollbar mode on an object.
:cpp:expr:`lv_obj_set_scrollbar_mode(widget, LV_SCROLLBAR_MODE_...)` sets the scrollbar mode on a Widget.
Styling
^^^^^^^
@@ -48,12 +50,12 @@ this:
...
lv_obj_add_style(obj, &style_red, LV_PART_SCROLLBAR);
lv_obj_add_style(widget, &style_red, LV_PART_SCROLLBAR);
An object goes to the :cpp:enumerator:`LV_STATE_SCROLLED` state while it's being
A Widget goes to the :cpp:enumerator:`LV_STATE_SCROLLED` state while it's being
scrolled. This allows adding different styles to the scrollbar or the
object itself when scrolled. This code makes the scrollbar blue when the
object is scrolled:
Widget itself when scrolled. This code makes the scrollbar blue when the
Widget is scrolled:
.. code-block:: c
@@ -63,22 +65,23 @@ object is scrolled:
...
lv_obj_add_style(obj, &style_blue, LV_STATE_SCROLLED | LV_PART_SCROLLBAR);
lv_obj_add_style(widget, &style_blue, LV_STATE_SCROLLED | LV_PART_SCROLLBAR);
If the base direction of the :cpp:enumerator:`LV_PART_SCROLLBAR` is RTL
(:c:macro:`LV_BASE_DIR_RTL`) the vertical scrollbar will be placed on the left.
Note that, the ``base_dir`` style property is inherited. Therefore, it
can be set directly on the :cpp:enumerator:`LV_PART_SCROLLBAR` part of an object or on
the object's or any parent's main part to make a scrollbar inherit the
can be set directly on the :cpp:enumerator:`LV_PART_SCROLLBAR` part of a Widget or on
the Widget's or any parent's main part to make a scrollbar inherit the
base direction.
``pad_left/right/top/bottom`` sets the spacing around the scrollbars and
``width`` sets the scrollbar's width.
.. _scroll_events:
Events
------
Scrolling Events
----------------
The following events are related to scrolling:
@@ -87,10 +90,6 @@ The following events are related to scrolling:
- :cpp:enumerator:`LV_EVENT_SCROLL_END`: Scrolling ends.
- :cpp:enumerator:`LV_EVENT_SCROLL`: Scroll happened. Triggered on every position change. Scroll events
Basic example
*************
TODO
Features of scrolling
*********************
@@ -101,13 +100,14 @@ useful additional features.
Scrollable
----------
It's possible to make an object non-scrollable with
:cpp:expr:`lv_obj_remove_flag(obj, LV_OBJ_FLAG_SCROLLABLE)`.
It's possible to make a Widget non-scrollable with
:cpp:expr:`lv_obj_remove_flag(widget, LV_OBJ_FLAG_SCROLLABLE)`.
Non-scrollable objects can still propagate the scrolling (chain) to
Non-scrollable Widgets can still propagate the scrolling (chain) to
their parents.
The direction in which scrolling happens can be controlled by ``lv_obj_set_scroll_dir(obj, LV_DIR_...)``.
The direction in which scrolling happens can be controlled by
:cpp:expr:`lv_obj_set_scroll_dir(widget, LV_DIR_...)`.
The following values are possible for the direction:
@@ -124,7 +124,7 @@ OR-ed values are also possible. E.g. :cpp:expr:`LV_DIR_TOP | LV_DIR_LEFT`.
Scroll chain
------------
If an object can't be scrolled further (e.g. its content has reached the
If a Widget can't be scrolled further (e.g. its content has reached the
bottom-most position) additional scrolling is propagated to its parent.
If the parent can be scrolled in that direction than it will be scrolled
instead. It continues propagating to the grandparent and
@@ -132,14 +132,14 @@ grand-grandparents as well.
The propagation on scrolling is called "scroll chaining" and it can be
enabled/disabled with ``LV_OBJ_FLAG_SCROLL_CHAIN_HOR/VER`` flag. If
chaining is disabled the propagation stops on the object and the
chaining is disabled the propagation stops on the Widget and the
parent(s) won't be scrolled.
Scroll momentum
---------------
When the user scrolls an object and releases it, LVGL can emulate
inertial momentum for the scrolling. It's like the object was thrown and
When the user scrolls a Widget and releases it, LVGL can emulate
inertial momentum for the scrolling. It's like the Widget was thrown and
scrolling slows down smoothly.
The scroll momentum can be enabled/disabled with the
@@ -148,36 +148,37 @@ The scroll momentum can be enabled/disabled with the
Elastic scroll
--------------
Normally an object can't be scrolled past the extremities of its
Normally a Widget can't be scrolled past the extremities of its
content. That is the top side of the content can't be below the top side
of the object.
of the Widget.
However, with :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_ELASTIC` a fancy effect is added
when the user "over-scrolls" the content. The scrolling slows down, and
the content can be scrolled inside the object. When the object is
the content can be scrolled inside the Widget. When the Widget is
released the content scrolled in it will be animated back to the valid
position.
Snapping
--------
The children of an object can be snapped according to specific rules
The children of a Widget can be snapped according to specific rules
when scrolling ends. Children can be made snappable individually with
the :cpp:enumerator:`LV_OBJ_FLAG_SNAPPABLE` flag.
An object can align snapped children in four ways:
A Widget can align snapped children in four ways:
- :cpp:enumerator:`LV_SCROLL_SNAP_NONE`: Snapping is disabled. (default)
- :cpp:enumerator:`LV_SCROLL_SNAP_START`: Align the children to the left/top side of a scrolled object
- :cpp:enumerator:`LV_SCROLL_SNAP_END`: Align the children to the right/bottom side of a scrolled object
- :cpp:enumerator:`LV_SCROLL_SNAP_CENTER`: Align the children to the center of a scrolled object
- :cpp:enumerator:`LV_SCROLL_SNAP_START`: Align the children to the left/top side of a scrolled Widget
- :cpp:enumerator:`LV_SCROLL_SNAP_END`: Align the children to the right/bottom side of a scrolled Widget
- :cpp:enumerator:`LV_SCROLL_SNAP_CENTER`: Align the children to the center of a scrolled Widget
Snap alignment is set with
``lv_obj_set_scroll_snap_x/y(obj, LV_SCROLL_SNAP_...)``:
:cpp:expr:`lv_obj_set_scroll_snap_x(widget, LV_SCROLL_SNAP_...)` and
:cpp:expr:`lv_obj_set_scroll_snap_y(widget, LV_SCROLL_SNAP_...)`.
Under the hood the following happens:
1. User scrolls an object and releases the screen
1. User scrolls a Widget and releases the screen
2. LVGL calculates where the scroll would end considering scroll momentum
3. LVGL finds the nearest scroll point
4. LVGL scrolls to the snap point with an animation
@@ -195,24 +196,25 @@ This feature can be enabled by the :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_ONE` flag
Scroll on focus
---------------
Imagine that there a lot of objects in a group that are on a scrollable
object. Pressing the "Tab" button focuses the next object but it might
be outside the visible area of the scrollable object. If the "scroll on
focus" feature is enabled LVGL will automatically scroll objects to
Imagine that there a lot of Widgets in a group that are on a scrollable
Widget. Pressing the "Tab" button focuses the next Widget but it might
be outside the visible area of the scrollable Widget. If the "scroll on
focus" feature is enabled LVGL will automatically scroll Widgets to
bring their children into view. The scrolling happens recursively
therefore even nested scrollable objects are handled properly. The
object will be scrolled into view even if it's on a different page of a
therefore even nested scrollable Widgets are handled properly. The
Widget will be scrolled into view even if it's on a different page of a
tabview.
Scroll manually
***************
The following API functions allow manual scrolling of objects:
The following API functions allow manual scrolling of Widgets:
- ``lv_obj_scroll_by(obj, x, y, LV_ANIM_ON/OFF)`` scroll by ``x`` and ``y`` values
- ``lv_obj_scroll_to(obj, x, y, LV_ANIM_ON/OFF)`` scroll to bring the given coordinate to the top left corner
- ``lv_obj_scroll_to_x(obj, x, LV_ANIM_ON/OFF)`` scroll to bring the given coordinate to the left side
- ``lv_obj_scroll_to_y(obj, y, LV_ANIM_ON/OFF)`` scroll to bring the given coordinate to the top side
- ``lv_obj_scroll_by(widget, x, y, LV_ANIM_ON/OFF)`` scroll by ``x`` and ``y`` values
- ``lv_obj_scroll_to(widget, x, y, LV_ANIM_ON/OFF)`` scroll to bring the given coordinate to the top left corner
- ``lv_obj_scroll_to_x(widget, x, LV_ANIM_ON/OFF)`` scroll to bring the given coordinate to the left side
- ``lv_obj_scroll_to_y(widget, y, LV_ANIM_ON/OFF)`` scroll to bring the given coordinate to the top side
From time to time you may need to retrieve the scroll position of an
element, either to restore it later, or to display dynamically some
@@ -235,32 +237,32 @@ to combine scroll event and store the scroll top position.
Scroll coordinates can be retrieved from different axes with these
functions:
- ``lv_obj_get_scroll_x(obj)`` Get the ``x`` coordinate of object
- ``lv_obj_get_scroll_y(obj)`` Get the ``y`` coordinate of object
- ``lv_obj_get_scroll_top(obj)`` Get the scroll coordinate from the top
- ``lv_obj_get_scroll_bottom(obj)`` Get the scroll coordinate from the bottom
- ``lv_obj_get_scroll_left(obj)`` Get the scroll coordinate from the left
- ``lv_obj_get_scroll_right(obj)`` Get the scroll coordinate from the right
- ``lv_obj_get_scroll_x(widget)`` Get the ``x`` coordinate of Widget
- ``lv_obj_get_scroll_y(widget)`` Get the ``y`` coordinate of Widget
- ``lv_obj_get_scroll_top(widget)`` Get the scroll coordinate from the top
- ``lv_obj_get_scroll_bottom(widget)`` Get the scroll coordinate from the bottom
- ``lv_obj_get_scroll_left(widget)`` Get the scroll coordinate from the left
- ``lv_obj_get_scroll_right(widget)`` Get the scroll coordinate from the right
Self size
*********
Self size is a property of an object. Normally, the user shouldn't use
Self size is a property of a Widget. Normally, the user shouldn't use
this parameter but if a custom widget is created it might be useful.
In short, self size establishes the size of an object's content. To
In short, self size establishes the size of a Widget's content. To
understand it better take the example of a table. Let's say it has 10
rows each with 50 px height. So the total height of the content is 500
px. In other words the "self height" is 500 px. If the user sets only
200 px height for the table LVGL will see that the self size is larger
and make the table scrollable.
This means not only the children can make an object scrollable but a
larger self size will too.
This means not only the children can make a Widget scrollable but a
larger self size will as well.
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:
a Widget. Here is an example to see how to handle the event:
.. code-block:: c
@@ -279,12 +281,14 @@ an object. Here is an example to see how to handle the event:
.. _scroll_example:
Examples
********
.. include:: ../examples/scroll/index.rst
.. include:: ../../examples/scroll/index.rst
.. _scroll_api:
API
***
+11
View File
@@ -0,0 +1,11 @@
.. _styles:
======
Styles
======
.. toctree::
:maxdepth: 2
style
style-properties
@@ -1,20 +1,20 @@
.. _styles:
.. _style_details:
======
Styles
======
=============
Style Details
=============
*Styles* are used to set the appearance of objects. Styles in lvgl are
heavily inspired by CSS. The concept in a nutshell is as follows: - A
*Styles* are used to set the appearance of Widgets. Styles in lvgl are
heavily inspired by CSS. The concept in a nutshell is that a
style is an :cpp:type:`lv_style_t` variable which can hold properties like
border width, text color and so on. It's similar to a ``class`` in CSS.
border width, font, text color and so on. It's similar to a ``class`` in CSS.
- Styles can be assigned to objects to change their appearance. Upon
- Styles can be assigned to Widgets to change their appearance. Upon
assignment, the target part (*pseudo-element* in CSS) and target state
(*pseudo class*) can be specified. For example one can add
``style_blue`` to the knob of a slider when it's in pressed state.
- The same style can be used by any number of objects.
- Styles can be cascaded which means multiple styles may be assigned to an object and
- The same style can be used by any number of Widgets.
- Styles can be cascaded which means multiple styles may be assigned to a Widget and
each style can have different properties. Therefore, not all properties
have to be specified in a style. LVGL will search for a property until a
style defines it or use a default if it's not specified by any of the
@@ -22,19 +22,19 @@ border width, text color and so on. It's similar to a ``class`` in CSS.
and ``style_btn_red`` can add only a ``background-color=red`` to
overwrite the background color.
- The most recently added style has higher precedence. This means if a property
is specified in two styles the newest style in the object will be used.
- Some properties (e.g. text color) can be inherited from a parent(s) if it's not specified in an object.
- Objects can also have local styles with higher precedence than "normal" styles.
is specified in two styles the newest style in the Widget will be used.
- Some properties (e.g. text color) can be inherited from a parent(s) if it's not specified in a Widget.
- Widgets can also have local styles with higher precedence than "normal" styles.
- Unlike CSS (where pseudo-classes describe different states, e.g. ``:focus``),
in LVGL a property is assigned to a given state.
- Transitions can be applied when the object changes state.
- Transitions can be applied when the Widget changes state.
.. _styles_states:
States
******
The objects can be in the combination of the following states:
The Widgets can be in the combination of the following states:
- :cpp:enumerator:`LV_STATE_DEFAULT`: (0x0000) Normal, released state
- :cpp:enumerator:`LV_STATE_CHECKED`: (0x0001) Toggled or checked state
@@ -50,7 +50,7 @@ The objects can be in the combination of the following states:
- :cpp:enumerator:`LV_STATE_USER_3`: (0x4000) Custom state
- :cpp:enumerator:`LV_STATE_USER_4`: (0x8000) Custom state
An object can be in a combination of states such as being focused and
A Widget can be in a combination of states such as being focused and
pressed at the same time. This is represented as :cpp:expr:`LV_STATE_FOCUSED | LV_STATE_PRESSED`.
A style can be added to any state or state combination. For example,
@@ -70,35 +70,35 @@ defined like this:
- :cpp:enumerator:`LV_STATE_PRESSED`: gray
- :cpp:enumerator:`LV_STATE_FOCUSED`: red
1. Initially the object is in the default state, so it's a simple case:
the property is perfectly defined in the object's current state as
1. Initially the Widget is in the default state, so it's a simple case:
the property is perfectly defined in the Widget's current state as
white.
2. When the object is pressed there are 2 related properties: default
2. When the Widget is pressed there are 2 related properties: default
with white (default is related to every state) and pressed with gray.
The pressed state has 0x0020 precedence which is higher than the
default state's 0x0000 precedence, so gray color will be used.
3. When the object is focused the same thing happens as in pressed state
3. When the Widget has focus the same thing happens as in pressed state
and red color will be used. (Focused state has higher precedence than
default state).
4. When the object is focused and pressed both gray and red would work,
4. When the Widget has focus and pressed both gray and red would work,
but the pressed state has higher precedence than focused so gray
color will be used.
5. It's possible to set e.g. rose color for :cpp:expr:`LV_STATE_PRESSED | LV_STATE_FOCUSED`.
In this case, this combined state has 0x0020 + 0x0002 = 0x0022 precedence, which is higher than
the pressed state's precedence so rose color would be used.
6. When the object is in the checked state there is no property to set
6. When the Widget is in the checked state there is no property to set
the background color for this state. So for lack of a better option,
the object remains white from the default state's property.
the Widget remains white from the default state's property.
Some practical notes:
- The precedence (value) of states is quite intuitive, and it's something the
user would expect naturally. E.g. if an object is focused the user will still
user would expect naturally. E.g. if a Widget has focus the user will still
want to see if it's pressed, therefore the pressed state has a higher
precedence. If the focused state had a higher precedence it would overwrite
the pressed color.
- If you want to set a property for all states (e.g. red background color)
just set it for the default state. If the object can't find a property
just set it for the default state. If the Widget can't find a property
for its current state it will fall back to the default state's property.
- Use ORed states to describe the properties for complex cases. (E.g.
pressed + checked + focused)
@@ -115,7 +115,7 @@ Cascading styles
****************
It's not required to set all the properties in one style. It's possible
to add more styles to an object and have the latter added style modify
to add more styles to a Widget and have the latter added style modify
or extend appearance. For example, create a general gray button style
and create a new one for red buttons where only the new background color
is set.
@@ -144,10 +144,10 @@ Inheritance
***********
Some properties (typically those related to text) can be inherited from
the parent object's styles. Inheritance is applied only if the given
property is not set in the object's styles (even in default state). In
the parent Widget's styles. Inheritance is applied only if the given
property is not set in the Widget's styles (even in default state). In
this case, if the property is inheritable, the property's value will be
searched in the parents until an object specifies a value for the
searched in the parents until a Widget specifies a value for the
property. The parents will use their own state to determine the value.
So if a button is pressed, and the text color comes from here, the
pressed text color will be used.
@@ -157,7 +157,7 @@ pressed text color will be used.
Parts
*****
Objects can be composed of *parts* which may each have their own styles.
Widgets can be composed of *parts* which may each have their own styles.
The following predefined parts exist in LVGL:
@@ -177,7 +177,7 @@ For example a :ref:`Slider <lv_slider>` has three parts:
- Knob
This means all three parts of the slider can have their own styles. See
later how to add styles to objects and parts.
later how to add styles to Widgets and parts.
.. _styles_initialize:
@@ -220,7 +220,7 @@ To get a property's value from a style:
lv_style_value_t v;
lv_result_t res = lv_style_get_prop(&style, LV_STYLE_BG_COLOR, &v);
if(res == LV_RESULT_OK) { /*Found*/
if(res == LV_RESULT_OK) { /* Found */
do_something(v.color);
}
@@ -236,7 +236,7 @@ To reset a style (free all its data) use:
lv_style_reset(&style);
Styles can be built as ``const`` too to save RAM:
Styles can be built as ``const`` as well to save RAM:
.. code-block:: c
@@ -256,35 +256,35 @@ new properties cannot be added.
Add and remove styles to a widget
*********************************
A style on its own is not that useful. It must be assigned to an object
A style on its own is not that useful. It must be assigned to a Widget
to take effect.
Add styles
----------
To add a style to an object use
``lv_obj_add_style(obj, &style, <selector>)``. ``<selector>`` is an
To add a style to a Widget use
``lv_obj_add_style(widget, &style, <selector>)``. ``<selector>`` is an
OR-ed value of parts and state to which the style should be added. Some
examples:
- :cpp:expr:`LV_PART_MAIN | LV_STATE_DEFAULT`
- :cpp:enumerator:`LV_STATE_PRESSED`: The main part in pressed state. :cpp:enumerator:`LV_PART_MAIN` can be omitted
- :cpp:enumerator:`LV_PART_SCROLLBAR`: The scrollbar part in the default state. :cpp:enumerator:`LV_STATE_DEFAULT` can be omitted.
- :cpp:expr:`LV_PART_SCROLLBAR | LV_STATE_SCROLLED`: The scrollbar part when the object is being scrolled
- :cpp:expr:`LV_PART_INDICATOR | LV_STATE_PRESSED | LV_STATE_CHECKED` The indicator part when the object is pressed and checked at the same time.
- :cpp:expr:`LV_PART_SCROLLBAR | LV_STATE_SCROLLED`: The scrollbar part when the Widget is being scrolled
- :cpp:expr:`LV_PART_INDICATOR | LV_STATE_PRESSED | LV_STATE_CHECKED` The indicator part when the Widget is pressed and checked at the same time.
Using :cpp:func:`lv_obj_add_style`:
.. code-block:: c
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, &style_btn, 0); /* Default button style */
lv_obj_add_style(btn, &btn_red, LV_STATE_PRESSED); /* Overwrite only some colors to red when pressed */
Replace styles
--------------
To replace a specific style of an object use
:cpp:expr:`lv_obj_replace_style(obj, old_style, new_style, selector)`. This
To replace a specific style of a Widget use
:cpp:expr:`lv_obj_replace_style(widget, old_style, new_style, selector)`. This
function will only replace ``old_style`` with ``new_style`` if the
``selector`` matches the ``selector`` used in ``lv_obj_add_style``. Both
styles, i.e. ``old_style`` and ``new_style``, must not be ``NULL`` (for
@@ -298,16 +298,16 @@ Using :cpp:func:`lv_obj_replace_style`:
.. code-block:: c
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_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 */
Remove styles
-------------
To remove all styles from an object use :cpp:expr:`lv_obj_remove_style_all(obj)`.
To remove all styles from a Widget use :cpp:expr:`lv_obj_remove_style_all(widget)`.
To remove specific styles use
:cpp:expr:`lv_obj_remove_style(obj, style, selector)`. This function will remove
:cpp:expr:`lv_obj_remove_style(widget, style, selector)`. This function will remove
``style`` only if the ``selector`` matches with the ``selector`` used in
:cpp:func:`lv_obj_add_style`. ``style`` can be ``NULL`` to check only the
``selector`` and remove all matching styles. The ``selector`` can use
@@ -317,65 +317,66 @@ any state or part.
Report style changes
--------------------
If a style which is already assigned to an object changes (i.e. a
property is added or changed), the objects using that style should be
If a style which is already assigned to a Widget changes (i.e. a
property is added or changed), the Widgets using that style should be
notified. There are 3 options to do this:
1. If you know that the changed properties can be applied by a simple redraw
(e.g. color or opacity changes) just call :cpp:expr:`lv_obj_invalidate(obj)`
(e.g. color or opacity changes) just call :cpp:expr:`lv_obj_invalidate(widget)`
or :cpp:expr:`lv_obj_invalidate(lv_screen_active())`.
2. If more complex style properties were changed or added, and you know which
object(s) are affected by that style call :cpp:expr:`lv_obj_refresh_style(obj, part, property)`.
To refresh all parts and properties use :cpp:expr:`lv_obj_refresh_style(obj, LV_PART_ANY, LV_STYLE_PROP_ANY)`.
3. To make LVGL check all objects to see if they use a style and refresh them
Widget(s) are affected by that style call :cpp:expr:`lv_obj_refresh_style(widget, part, property)`.
To refresh all parts and properties use :cpp:expr:`lv_obj_refresh_style(widget, LV_PART_ANY, LV_STYLE_PROP_ANY)`.
3. To make LVGL check all Widgets to see if they use a style and refresh them
when needed, call :cpp:expr:`lv_obj_report_style_change(&style)`. If ``style``
is ``NULL`` all objects will be notified about a style change.
is ``NULL`` all Widgets will be notified about a style change.
Get a property's value on an object
Get a property's value on a Widget
-----------------------------------
To get a final value of property
- considering cascading, inheritance, local styles and transitions (see below)
- property get functions like this can be used: ``lv_obj_get_style_<property_name>(obj, <part>)``.
These functions use the object's current state and if no better candidate exists they return a default value.
- property get functions like this can be used: ``lv_obj_get_style_<property_name>(widget, <part>)``.
These functions use the Widget's current state and if no better candidate exists they return a default value.
For example:
.. 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);
.. _styles_local:
Local styles
************
In addition to "normal" styles, objects can also store local styles.
In addition to "normal" styles, Widgets can also store local styles.
This concept is similar to inline styles in CSS
(e.g. ``<div style="color:red">``) with some modification.
Local styles are like normal styles, but they can't be shared among
other objects. If used, local styles are allocated automatically, and
freed when the object is deleted. They are useful to add local
customization to an object.
other Widgets. If used, local styles are allocated automatically, and
freed when the Widget is deleted. They are useful to add local
customization to a Widget.
Unlike in CSS, LVGL local styles can be assigned to states
(*pseudo-classes*) and parts (*pseudo-elements*).
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>(widget, <value>, <selector>);`` For example:
.. 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);
.. _styles_properties:
Properties
**********
.. _style_properties_overview:
Style Properties Overview
*************************
For the full list of style properties click :ref:`here <style_properties>`.
For the full list of style properties click
:ref:`here <style_properties>`.
Typical background properties
-----------------------------
@@ -397,7 +398,7 @@ background properties" are the ones related to:
Transitions
***********
By default, when an object changes state (e.g. it's pressed) the new
By default, when a Widget changes state (e.g. it's pressed) the new
properties from the new state are set immediately. However, with
transitions it's possible to play an animation on state change. For
example, on pressing a button its background color can be animated to
@@ -413,7 +414,7 @@ possible to set
The transition properties can be defined for each state. For example,
setting a 500 ms transition time in the default state means that when
the object goes to the default state a 500 ms transition time is
the Widget goes to the default state a 500 ms transition time is
applied. Setting a 100 ms transition time in the pressed state causes a
100 ms transition when going to the pressed state. This example
configuration results in going to the pressed state quickly and then
@@ -424,10 +425,10 @@ initialized and added to a style:
.. 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[] = {
LV_STYLE_BG_OPA, LV_STYLE_BG_COLOR,
0, /*End marker*/
0, /* End marker */
};
static lv_style_transition_dsc_t trans1;
@@ -500,12 +501,12 @@ example shows how to set the "default" theme:
.. code-block:: c
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*/
false, /*Light or dark mode*/
&lv_font_montserrat_10, &lv_font_montserrat_14, &lv_font_montserrat_18); /*Small, normal, large fonts*/
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 */
false, /* Light or dark mode */
&lv_font_montserrat_10, &lv_font_montserrat_14, &lv_font_montserrat_18); /* Small, normal, large fonts */
lv_display_set_theme(display, th); /*Assign the theme to the display*/
lv_display_set_theme(display, th); /* Assign the theme to the display */
The included themes are enabled in ``lv_conf.h``. If the default theme
is enabled by :c:macro:`LV_USE_THEME_DEFAULT` LVGL automatically initializes
@@ -529,7 +530,7 @@ There is an example for it below.
Examples
********
.. include:: ../examples/styles/index.rst
.. include:: ../../../examples/styles/index.rst
.. _styles_api:
@@ -1,8 +1,8 @@
.. _debugging:
==============
Debugging LVGL
==============
=========
Debugging
=========
.. toctree::
:maxdepth: 2
@@ -20,9 +20,9 @@ To enable logging, set :c:macro:`LV_USE_LOG` in ``lv_conf.h`` and set
- :c:macro:`LV_LOG_LEVEL_USER`: Only user messages
- :c:macro:`LV_LOG_LEVEL_NONE`: Do not log anything
The events which have a higher level than the set log level will be
logged too. E.g. if you :c:macro:`LV_LOG_LEVEL_WARN`, errors will be also
logged.
The events which have a higher level than the set log level will be logged
as well. E.g. if you :c:macro:`LV_LOG_LEVEL_WARN`, errors will be also logged.
Printing logs
*************
@@ -18,7 +18,7 @@ and simulate the same rendering images as the real hardware on the simulator.
Configuration
*************
1. Enable VG-Lite rendering backend, see `VG-Lite Rendering Backend <overview/renderers/vg_lite>`__.
1. Enable VG-Lite rendering backend, see :ref:`vglite`.
2. Enable ThorVG and turn on the configuration :c:macro:`LV_USE_THORVG_INTERNAL` or :c:macro:`LV_USE_THORVG_EXTERNAL`.
It is recommended to use the internal ThorVG library to ensure uniform rendering results.
+17
View File
@@ -0,0 +1,17 @@
.. _reference:
=========
Reference
=========
.. toctree::
:maxdepth: 2
base-widget/index
widgets/index
main-components/index
other-components/index
../examples
debugging/index
integration/index
libs/index
@@ -105,7 +105,7 @@ The different "json_types" are as follows:
- ``"name"``: The name of the function pointer.
- ``"type"``: This contains the return type information for the function pointer.
- ``"docstring"``: you should know what this is.
- ``"args"``: array of ``"arg"`` objects. This describes the fuction arguments/parameters.
- ``"args"``: array of ``"arg"`` Widgets. This describes the fuction arguments/parameters.
- ``"quals"``: array of qualifiers, IE "const"
@@ -144,7 +144,7 @@ The different "json_types" are as follows:
type as the type for the members of this enumeration group. Check the
enumeration members type to get the correct type.
- ``"docstring"``: you should know what this is.
- ``"members"``: array of ``"enum_member"`` objects
- ``"members"``: array of ``"enum_member"`` Widgets
- ``"enum_member"``: Describes an enumeration item/member. Only found under
@@ -59,7 +59,7 @@ MicroPython + LVGL could be used for:
- Fast prototyping GUI.
- Shortening the cycle of changing and fine-tuning the GUI.
- Modelling the GUI in a more abstract way by defining reusable composite objects, taking advantage of Python's language features
- Modelling the GUI in a more abstract way by defining reusable composite Widgets, taking advantage of Python's language features
such as Inheritance, Closures, List Comprehension, Generators, Exception Handling, Arbitrary Precision Integers and others.
- Make LVGL accessible to a larger audience. No need to know C to create a nice GUI on an embedded system. This goes well with
`CircuitPython vision <https://learn.adafruit.com/welcome-to-circuitpython/what-is-circuitpython>`__.
@@ -110,7 +110,7 @@ edit a python script and run it.
`Click here to experiment on the online simulator <https://sim.lvgl.io/>`__
Many `LVGL examples <https://docs.lvgl.io/master/examples.html>`__ are available also for MicroPython. Just click the link!
Many :ref:`LVGL examples <examples>` are available also for MicroPython. Just click the link!
PC Simulator
@@ -1,7 +1,7 @@
.. _build_cmake:
=====
cmake
CMake
=====
@@ -176,8 +176,8 @@ The process is described in details below, using ``SPIFFS`` as demonstration.
}
lv_obj_t * obj = lv_image_create(lv_screen_active());
lv_image_set_src(obj, "A:/spiffs/logo.bin");
lv_obj_center(obj);
lv_image_set_src(widget, "A:/spiffs/logo.bin");
lv_obj_center(widget);
}
- **Build and flash**
@@ -5,7 +5,7 @@ NXP
NXP has integrated LVGL into the MCUXpresso SDK packages for several of our
microcontrollers as an optional software component, allowing easy evaluation and
migration into your product design. LVGL is a free and open-source embedded
graphic library with features that enable you need to create embedded GUIs with
graphic library with features that enable you to create embedded GUIs with
intuitive graphical elements, beautiful visual effects and a low memory
footprint. The complete graphic framework includes a variety of widgets for you
to use in the creation of your GUI, and supports more advanced functions such as

Some files were not shown because too many files have changed in this diff Show More