diff --git a/docs/CHANGELOG.rst b/docs/CHANGELOG.rst index 86ecd5a59..5de8425de 100644 --- a/docs/CHANGELOG.rst +++ b/docs/CHANGELOG.rst @@ -1,24 +1,24 @@ .. _changelog: -Changelog -========= +Change Log +========== `v9.2 `__ 26 August 2024 ------------------------------------------------------------------------------ It's huge release with many interesting updates: -- Built-in `Wayland driver `__ -- `OpenGL ES and GLFW driver `__ with support for external textures -- `Renesas GLCDC `__ driver +- Built-in :ref:`Wayland driver ` +- :ref:`OpenGL ES and GLFW driver ` with support for external textures +- :ref:`renesas_glcdc` driver - L8 and I1 rendering support - Matrix transformations during rendering -- New `file system interfaces `__: LittleFS, ESP LittleFS, Arduino FS +- New :ref:`file system interfaces `: LittleFS, ESP LittleFS, Arduino FS - SDL renderer improvements (supporting all draw task types and improving speed) -- Radial, Conic, and Skew `gradients supported `__ by software rendering and VG-Lite -- `QNX `__ and `MQX `__ support -- `Mouse hover handling `__ -- `Lottie `__ support +- Radial, Conic, and Skew `gradients supported `__ by software rendering and VG-Lite +- :ref:`qnx` and :ref:`mqx` support +- :ref:`Mouse hover handling ` +- :ref:`lv_lottie` support - CI tests for UEFI builds And many smaller fixes and features diff --git a/docs/CODING_STYLE.rst b/docs/CODING_STYLE.rst index f1dcce998..e50972848 100644 --- a/docs/CODING_STYLE.rst +++ b/docs/CODING_STYLE.rst @@ -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__create(lv_obj_t * parent)`` pattern. - Widget members function must start with ``lv_`` 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. */ diff --git a/docs/README.md b/docs/README.md index 7b4ea3711..f8069e5be 100644 --- a/docs/README.md +++ b/docs/README.md @@ -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, ...)`` diff --git a/docs/README_jp.rst b/docs/README_jp.rst index df0e13954..b59fb93e4 100644 --- a/docs/README_jp.rst +++ b/docs/README_jp.rst @@ -75,16 +75,16 @@ Cライブラリ。(C++互換) - 任意の(RT)OS、任意のMCU・MPU用にコンパイル可能。 - 電子ペーパー、OLEDディスプレイ、TFTディスプレイ、白黒ディスプレイ、モニターに対応。 `Porting -Guide `__ +Guide `__ - MITライセンスにより商用利用可能。 - システム要件:RAM 32KB、Flash 128KB、フレームバッファ、レンダリング用に1/10以上のスクリーンサイズのバッファ。 - OS、外部メモリ、GPUもサポート。 **ウィジェット、スタイル、レイアウトなど** - 30以上の組み込み -`ウィジェット `__: ボタン、ラベル、スライダー、グラフ、キーボード、メーター、円弧、表など。 +`ウィジェット `__: ボタン、ラベル、スライダー、グラフ、キーボード、メーター、円弧、表など。 - ウィジェットの任意の部分を任意の状態にカスタマイズ可能な豊富なスタイルプロパティを備えた柔軟な -`スタイルシステム `__\ 。 +`スタイルシステム `__\ 。 - `Flexbox `__ および @@ -98,9 +98,9 @@ Guide `__ +`入力デバイス `__ をサポート。 - -`マルチディスプレイ `__ +`マルチディスプレイ `__ 対応。 **Binding と Build をサポート** - `MicroPython @@ -108,9 +108,9 @@ Binding `__ +`CMake `__ が含まれており、すぐ使えるようにサポート。 - -`PCのシミュレータで開発したUIコード `__ +`PCのシミュレータで開発したUIコード `__ は、そのまま組込み用ハードウェアでも使用可能。 - `Emscripten port `__ :gb: によりC言語のUIコードをHTMLファイルに変換。 @@ -128,19 +128,19 @@ UI開発をよりシンプルかつ迅速にするための、ユーザーイン -------------------- LVGL は以下で利用可能です。 - `Arduino -library `__ +library `__ - `PlatformIO package `__ :gb: - `Zephyr library `__ - `ESP32 -component `__ +component `__ - `NXP MCUXpresso component `__ - `NuttX -library `__ +library `__ - `RT-Thread -RTOS `__ +RTOS `__ - 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 `__ を読みましょう。 (5分間) 3. LVGLの基本に慣れるため `Quick - overview `__ + overview `__ を読みましょう。 (15分間) **LVGLを使ってみましょう** -4. `シミュレータ `__ +4. `シミュレータ `__ をセットアップしましょう。 (10 minutes) 5. `サンプルプログラム `__ :gb: を動かしてみましょう。 -6. `移植ガイド `__ +6. `移植ガイド `__ を参考に、LVGLを開発ボードに移植してみましょう。すぐ使える形の `プロジェクト `__ :gb: も用意してあります。 @@ -573,10 +573,10 @@ LVGLを使い始める時は、以下の順に進める事をおすすめしま **より詳しく体験してみましょう** 7. ライブラリの理解を深めるため - `Overview `__ + `Overview `__ を読みましょう。 (2~3時間) 8. ウィジェットの機能や使い方の詳細は - `Widgets `__ + `Widgets `__ でご確認ください。 **助け合いましょう** diff --git a/docs/README_pt_BR.rst b/docs/README_pt_BR.rst index f60a04655..defc3f125 100644 --- a/docs/README_pt_BR.rst +++ b/docs/README_pt_BR.rst @@ -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 `__ +- Suporta monitores monocromáticos, ePaper, OLED ou TFT. :ref:`Guia de + portabilidade ` - 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 `__ + :ref:`CMake ` já vem incluído. - `Desenvolva no - PC `__ + PC `__ 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 `__ + library `__ - `PlatformIO package `__ - `Zephyr library `__ - `ESP32 - component `__ + component `__ - `NXP MCUXpresso component `__ - `NuttX - library `__ + library `__ - `RT-Thread - RTOS `__ + RTOS `__ - 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 `__ da documentação (~5 minutos) 3. Familiarize-se com o básico na página de `visão geral - rápida `__ + rápida `__ (~15 minutos) **Começando a usar o LVGL** 4. Configure um - `simulador `__ + `simulador `__ (~10 minutos) 5. Experimente alguns `exemplos `__ 6. Porte o LVGL para uma placa. Veja o guia `portando o - LVGL `__ ou veja um + LVGL `__ ou veja um projeto pronto para usar em `projetos `__ **Torne-se um profissional** 7. Leia a página `visão - geral `__ para + geral `__ para entender melhor a biblioteca (~2-3 horas) 8. Verifique a documentação dos - `widgets `__ para ver + `widgets `__ para ver seus recursos e usabilidade **Obtenha ajuda e ajude outras pessoas** diff --git a/docs/README_zh.rst b/docs/README_zh.rst index e6878294d..32b17c03a 100644 --- a/docs/README_zh.rst +++ b/docs/README_zh.rst @@ -72,25 +72,25 @@ RAM 和 128 KB Flash、C 编译器、帧缓冲区和至少 1/10 屏幕大小的 - 一个完全可移植的 C(C++ 兼容)库,没有外部依赖关系。 - 可以编译到任何 MCU 或 MPU,使用任何 RTOS 或者操作系统。 - 支持单色、ePaper、OLED、TFT 显示器或者模拟器。 - `移植指南 `__ + `移植指南 `__ - 该项目使用 MIT 许可证,因此您可以在商业项目中轻松使用它。 - 仅需 32 KB RAM 和 128 KB Flash,一个帧缓冲区,以及至少 1/10 屏幕大小的渲染缓冲区。 - 支持使用可选的操作系统、外部存储器和 GPU。 **控件、样式、布局等** -- 30+ 内置\ `控件 `__: +- 30+ 内置\ `控件 `__:  按钮、标签、滑块、图表、键盘、仪表、弧形、表格等等。 -- 灵活的\ `样式系统 `__ +- 灵活的\ `样式系统 `__ 支持约 100 个样式属性,可在任何状态下自定义控件的任何部分。 -- `Flex 布局 `__ 和 - `Grid 布局 `__ +- `Flex 布局 `__ 和 + `Grid 布局 `__ 可以响应式自动调整控件的大小和位置。 - 文本支持 UTF-8 编码,支持 CJK、泰语、印地语、阿拉伯语和波斯语书写系统。 - 支持自动换行、字距调整、文本滚动、亚像素渲染、拼音输入法、文本表情符号。 - 渲染引擎支持动画、抗锯齿、不透明度、平滑滚动、阴影、图形变换等。 -- 支持鼠标、触摸板、小键盘、键盘、外部按钮、编码器\ `输入设备 `__\ 。 -- 支持\ `多显示器 `__\ 。 +- 支持鼠标、触摸板、小键盘、键盘、外部按钮、编码器\ `输入设备 `__\ 。 +- 支持\ `多显示器 `__\ 。 **绑定和构建支持** @@ -99,7 +99,7 @@ RAM 和 128 KB Flash、C 编译器、帧缓冲区和至少 1/10 屏幕大小的 - `PikaScript 绑定 `__ 在 MCU 上的更轻更简单的 Python 版本 - 未使用自定义生成系统。您可以在构建项目的其他文件时构建 LVGL。 -- 支持开箱即用的 Make 和 \ `CMake `__\ 编译系统。 +- 支持开箱即用的 Make 和 \ `CMake `__\ 编译系统。 - 支持在 \ `PC 上开发 `__\ ,并可以在嵌入式硬件上使用相同的 UI 代码。 - 支持使用我们的 \ `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. 查看\ `在线演示 `__\ ,了解 LVGL 的实际操作(3 分钟) 2. 阅读\ `文档 `__\ 的简介页(5 分钟) -3. 熟悉\ `快速概览 `__ +3. 熟悉\ `快速概览 `__ 页面上的基本知识(15 分钟) **开始使用 LVGL** 4. 设置\ `模拟器 `__ (10 分钟) 5. 尝试一些\ `示例 `__ -6. 将LVGL端口连接到线路板。请参阅\ `移植 `__\ 指南,或查看现成的\ `项目 `__ +6. 将LVGL端口连接到线路板。请参阅\ `移植 `__\ 指南,或查看现成的\ `项目 `__ **成为专业人士** -7. 阅读\ `概述 `__\ 页面以更好地了解图书馆(2-3 小时) -8. 查看\ `控件 `__\ 的文档以查看其功能和用法 +7. 阅读\ `概述 `__\ 页面以更好地了解图书馆(2-3 小时) +8. 查看\ `控件 `__\ 的文档以查看其功能和用法 **获得帮助并帮助他人** diff --git a/docs/ROADMAP.rst b/docs/ROADMAP.rst index c5bab1e95..f68e4c451 100644 --- a/docs/ROADMAP.rst +++ b/docs/ROADMAP.rst @@ -50,12 +50,12 @@ Architecture (see `here `__) - |check| Make LVGL render independent areas in parallel. `#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 `__) - |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 `__) - |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 `__. Reconsider focusing logic. Allow having no widget selected (on web it's possible). Keep editing state in `lv_obj_t` diff --git a/docs/_ext/link_roles.py b/docs/_ext/link_roles.py index 48e36180d..80a2c6e90 100644 --- a/docs/_ext/link_roles.py +++ b/docs/_ext/link_roles.py @@ -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)) diff --git a/docs/_ext/lv_example.py b/docs/_ext/lv_example.py index 014e7c3e2..8425e541f 100644 --- a/docs/_ext/lv_example.py +++ b/docs/_ext/lv_example.py @@ -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', diff --git a/docs/_static/img/gh-header.webp b/docs/_static/img/gh-header.webp new file mode 100644 index 000000000..5a5df3db8 Binary files /dev/null and b/docs/_static/img/gh-header.webp differ diff --git a/docs/_static/img/home_1.png b/docs/_static/img/home_1.png index 608acfe09..a1f145611 100644 Binary files a/docs/_static/img/home_1.png and b/docs/_static/img/home_1.png differ diff --git a/docs/_static/img/home_2.png b/docs/_static/img/home_2.png index d61ee512c..3c40372ff 100644 Binary files a/docs/_static/img/home_2.png and b/docs/_static/img/home_2.png differ diff --git a/docs/_static/img/home_3.png b/docs/_static/img/home_3.png index da0c2b888..e0b5a5125 100644 Binary files a/docs/_static/img/home_3.png and b/docs/_static/img/home_3.png differ diff --git a/docs/_static/img/home_4.png b/docs/_static/img/home_4.png index b059da7e2..7a4951703 100644 Binary files a/docs/_static/img/home_4.png and b/docs/_static/img/home_4.png differ diff --git a/docs/_static/img/home_5.png b/docs/_static/img/home_5.png index 1d002ea19..cdb28726d 100644 Binary files a/docs/_static/img/home_5.png and b/docs/_static/img/home_5.png differ diff --git a/docs/build.py b/docs/build.py index cfd75eb26..6b7700b92 100755 --- a/docs/build.py +++ b/docs/build.py @@ -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 `' 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.') diff --git a/docs/conf.py b/docs/conf.py index 5df4e3cdf..df6b62dac 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -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 ``. +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') + + diff --git a/docs/config_builder.py b/docs/config_builder.py index fde52275e..aff06ad94 100644 --- a/docs/config_builder.py +++ b/docs/config_builder.py @@ -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): diff --git a/docs/overview/coord.rst b/docs/details/base-widget/coord.rst similarity index 62% rename from docs/overview/coord.rst rename to docs/details/base-widget/coord.rst index 8967e2401..2dd435f02 100644 --- a/docs/overview/coord.rst +++ b/docs/details/base-widget/coord.rst @@ -1,66 +1,69 @@ .. _coord: -============================= -Positions, sizes, and layouts -============================= +============================ +Positions, Sizes and Layouts +============================ + Overview ******** -Similarly to many other parts of LVGL, the concept of setting the +Similar to many other parts of LVGL, the concept of setting the coordinates was inspired by CSS. LVGL has by no means a complete implementation of CSS but a comparable subset is implemented (sometimes with minor adjustments). -In short this means: +In short this means: -- Explicitly set coordinates are stored in styles (size, position, layouts, etc.) +- Explicitly set coordinates are stored in styles (position, size, layouts, etc.) - support min-width, max-width, min-height, max-height - have pixel, percentage, and "content" units - x=0; y=0 coordinate means the top-left corner of the parent plus the left/top padding plus border width - width/height means the full size, the "content area" is smaller with padding and border width - a subset of flexbox and grid layouts are supported -.. _coord_unites: +.. _coord_units: Units ------ +***** - pixel: Simply a position in pixels. An integer always means pixels. E.g. :cpp:expr:`lv_obj_set_x(btn, 10)` -- percentage: The percentage of the size of the object or its parent +- percentage: The percentage of the size of the Widget or its parent (depending on the property). :cpp:expr:`lv_pct(value)` converts a value to percentage. E.g. :cpp:expr:`lv_obj_set_width(btn, lv_pct(50))` - :c:macro:`LV_SIZE_CONTENT`: Special value to set the width/height of an - object to involve all the children. It's similar to ``auto`` in CSS. + Widget to involve all the children. It's similar to ``auto`` in CSS. E.g. :cpp:expr:`lv_obj_set_width(btn, LV_SIZE_CONTENT)`. + + .. _coord_boxing_model: Boxing model ------------- +************ LVGL follows CSS's `border-box `__ -model. An object's "box" is built from the following parts: +model. A Widget's "box" is built from the following parts: - bounding box: the width/height of the elements. - border width: the width of the border. -- padding: space between the sides of the object and its children. -- margin: space outside of the object (considered only by some layouts) +- padding: space between the sides of the Widget and its children. +- margin: space outside of the Widget (considered only by some layouts) - content: the content area which is the size of the bounding box reduced by the border width and padding. .. image:: /misc/boxmodel.png :alt: The box models of LVGL: The content area is smaller than the bounding box with the padding and border width The border is drawn inside the bounding box. Inside the border LVGL -keeps a "padding margin" when placing an object's children. +keeps a "padding margin" when placing a Widget's children. The outline is drawn outside the bounding box. .. _coord_notes: -Important notes ---------------- +Important Notes +*************** This section describes special cases in which LVGL's behavior might be unexpected. @@ -68,45 +71,45 @@ unexpected. .. _coord_postponed_coordinate_calculation: Postponed coordinate calculation -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +-------------------------------- LVGL doesn't recalculate all the coordinate changes immediately. This is -done to improve performance. Instead, the objects are marked as "dirty" +done to improve performance. Instead, the Widgets are marked as "dirty" and before redrawing the screen LVGL checks if there are any "dirty" -objects. If so it refreshes their position, size and layout. +Widgets. If so it refreshes their position, size and layout. -In other words, if you need to get the coordinate of an object and the +In other words, if you need to get the coordinate of a Widget and the coordinates were just changed, LVGL needs to be forced to recalculate the coordinates. To do this call :cpp:func:`lv_obj_update_layout`. The size and position might depend on the parent or layout. Therefore -:cpp:func:`lv_obj_update_layout` recalculates the coordinates of all objects on +:cpp:func:`lv_obj_update_layout` recalculates the coordinates of all Widgets on the screen of ``obj``. .. _coord_removing styles: Removing styles -^^^^^^^^^^^^^^^ +--------------- As it's described in the :ref:`coord_using_styles` section, coordinates can also be set via style properties. To be more precise, under the hood every style coordinate related property is stored as a -style property. If you use :cpp:expr:`lv_obj_set_x(obj, 20)` LVGL saves ``x=20`` -in the local style of the object. +style property. If you use :cpp:expr:`lv_obj_set_x(widget, 20)` LVGL saves ``x=20`` +in the local style of the Widget. This is an internal mechanism and doesn't matter much as you use LVGL. However, there is one case in which you need to be aware of the -implementation. If the style(s) of an object are removed by +implementation. If the style(s) of a Widget are removed by .. code-block:: c - lv_obj_remove_style_all(obj) + lv_obj_remove_style_all(widget) or .. code-block:: c - lv_obj_remove_style(obj, NULL, LV_PART_MAIN); + lv_obj_remove_style(widget, NULL, LV_PART_MAIN); the earlier set coordinates will be removed as well. @@ -114,30 +117,33 @@ For example: .. code-block:: c - /*The size of obj1 will be set back to the default in the end*/ - lv_obj_set_size(obj1, 200, 100); /*Now obj1 has 200;100 size*/ - lv_obj_remove_style_all(obj1); /*It removes the set sizes*/ + /* The size of obj1 will be set back to the default in the end */ + lv_obj_set_size(widget1, 200, 100); /* Now obj1 has 200;100 size */ + lv_obj_remove_style_all(widget1); /* It removes the set sizes */ - /*obj2 will have 200;100 size in the end */ - lv_obj_remove_style_all(obj2); - lv_obj_set_size(obj2, 200, 100); + /* widget2 will have 200;100 size in the end */ + lv_obj_remove_style_all(widget2); + lv_obj_set_size(widget2, 200, 100); -.. _coord_position: -Position -******** -Simple way ----------- +.. _positioning_widgets: -To simply set the x and y coordinates of an object use: +Positioning Widgets +******************* + + +Direct +------ + +To simply set the x and y coordinates of a Widget use: .. code-block:: c - lv_obj_set_x(obj, 10); //Separate... - lv_obj_set_y(obj, 20); - lv_obj_set_pos(obj, 10, 20); //Or in one function + lv_obj_set_x(widget, 10); /* Separate... */ + lv_obj_set_y(widget, 20); + lv_obj_set_pos(widget, 10, 20); /* Or in one function */ By default, the x and y coordinates are measured from the top left corner of the parent's content area. For example if the parent has five @@ -150,25 +156,31 @@ Percentage values are calculated from the parent's content area size. lv_obj_set_x(btn, lv_pct(10)); //x = 10 % of parent content area width -Align ------ -In some cases it's convenient to change the origin of the positioning -from the default top left. If the origin is changed e.g. to -bottom-right, the (0,0) position means: align to the bottom-right -corner. To change the origin use: +Alignment +--------- + + +Inside parent widget +~~~~~~~~~~~~~~~~~~~~ +In many cases it is more convenient to tell LVGL to align your object relative to +an "anchor point" in its parent *other* than its upper left corner. To establish +that "anchor point", call :cpp:expr:`lv_obj_set_align(widget, LV_ALIGN_...)`. After +that call, that "anchor point" will be remembered until another one is established. +In other words, every futire x and y setting for that Widget will be relative to the +that "anchor point". + +Example: Position Widget (10,20) px relative to the center of its parent: .. code-block:: c - lv_obj_set_align(obj, align); + lv_obj_set_align(widget, LV_ALIGN_CENTER); + lv_obj_set_pos(widget, 10, 20); -To change the alignment and set new coordinates: + /* Or combine the above in one function... */ + lv_obj_align(widget, LV_ALIGN_CENTER, 10, 20); -.. code-block:: c - - lv_obj_align(obj, align, x, y); - -The following alignment options can be used: +9 convenient "anchor points" can be used with these functions: - :cpp:enumerator:`LV_ALIGN_TOP_LEFT` - :cpp:enumerator:`LV_ALIGN_TOP_MID` @@ -180,28 +192,31 @@ The following alignment options can be used: - :cpp:enumerator:`LV_ALIGN_RIGHT_MID` - :cpp:enumerator:`LV_ALIGN_CENTER` +See illustration below to visualize what these mean. + It's quite common to align a child to the center of its parent, therefore a dedicated function exists: .. code-block:: c - lv_obj_center(obj); + lv_obj_center(widget); //Has the same effect - lv_obj_align(obj, LV_ALIGN_CENTER, 0, 0); + lv_obj_align(widget, LV_ALIGN_CENTER, 0, 0); If the parent's size changes, the set alignment and position of the children is updated automatically. -The functions introduced above align the object to its parent. However, -it's also possible to align an object to an arbitrary reference object. + +Relative to another Widget +~~~~~~~~~~~~~~~~~~~~~~~~~~ +Alternately, you can choose an "anchor point" on another Widget. .. code-block:: c - lv_obj_align_to(obj_to_align, reference_obj, align, x, y); + lv_obj_align_to(widget, reference_widget, align, x, y); -Besides the alignments options above, the following can be used to align -an object outside the reference object: +where ``align`` can be done of the following: - :cpp:enumerator:`LV_ALIGN_OUT_TOP_LEFT` - :cpp:enumerator:`LV_ALIGN_OUT_TOP_MID` @@ -216,67 +231,84 @@ an object outside the reference object: - :cpp:enumerator:`LV_ALIGN_OUT_RIGHT_MID` - :cpp:enumerator:`LV_ALIGN_OUT_RIGHT_BOTTOM` -For example to align a label above a button and center the label -horizontally: +Example: to horizontally center a label 10 pixels above a button: .. code-block:: c lv_obj_align_to(label, btn, LV_ALIGN_OUT_TOP_MID, 0, -10); -Note that, unlike with :cpp:func:`lv_obj_align`, :cpp:func:`lv_obj_align_to` cannot -realign the object if its coordinates or the reference object's -coordinates change. +Note that, unlike with :cpp:func:`lv_obj_align`, :cpp:func:`lv_obj_align_to` +does not remember the "anchor point" used, and so will not automatically reposition +the aligned widget if the reference widget later moves. + +The following illustration shows the meaning of each "anchor point" mentioned above. + +.. image:: /misc/align.png + + .. _coord_size: Size **** -Sizing the Simple way +Sizing the simple way --------------------- -The width and the height of an object can be set easily as well: +The width and the height of a Widget can be set easily as well: .. code-block:: c - lv_obj_set_width(obj, 200); //Separate... - lv_obj_set_height(obj, 100); - lv_obj_set_size(obj, 200, 100); //Or in one function + lv_obj_set_width(widget, 200); /* Separate... */ + lv_obj_set_height(widget, 100); + lv_obj_set_size(widget, 200, 100); /* Or in one function */ Percentage values are calculated based on the parent's content area -size. For example to set the object's height to the screen height: +size. For example to set the Widget's height to the screen height: .. code-block:: c - lv_obj_set_height(obj, lv_pct(100)); + lv_obj_set_height(widget, lv_pct(100)); The size settings support a special value: :c:macro:`LV_SIZE_CONTENT`. It means -the object's size in the respective direction will be set to the size of +the Widget's size in the respective direction will be set to the size of its children. Note that only children on the right and bottom sides will be considered and children on the top and left remain cropped. This limitation makes the behavior more predictable. -Objects with :cpp:enumerator:`LV_OBJ_FLAG_HIDDEN` or :cpp:enumerator:`LV_OBJ_FLAG_FLOATING` will be +Widgets with :cpp:enumerator:`LV_OBJ_FLAG_HIDDEN` or :cpp:enumerator:`LV_OBJ_FLAG_FLOATING` will be ignored by the :c:macro:`LV_SIZE_CONTENT` calculation. -The above functions set the size of an object's bounding box but the -size of the content area can be set as well. This means an object's +The above functions set the size of a Widget's bounding box but the +size of the content area can be set as well. This means a Widget's bounding box will be enlarged with the addition of padding. .. code-block:: c - lv_obj_set_content_width(obj, 50); //The actual width: padding left + 50 + padding right - lv_obj_set_content_height(obj, 30); //The actual width: padding top + 30 + padding bottom + lv_obj_set_content_width(widget, 50); /* The actual width: padding left + 50 + padding right */ + lv_obj_set_content_height(widget, 30); /* The actual width: padding top + 30 + padding bottom */ The size of the bounding box and the content area can be retrieved with the following functions: .. code-block:: c - int32_t w = lv_obj_get_width(obj); - int32_t h = lv_obj_get_height(obj); - int32_t content_w = lv_obj_get_content_width(obj); - int32_t content_h = lv_obj_get_content_height(obj); + int32_t w = lv_obj_get_width(widget); + int32_t h = lv_obj_get_height(widget); + int32_t content_w = lv_obj_get_content_width(widget); + int32_t content_h = lv_obj_get_content_height(widget); + + +.. _extending_click_area: + +Extending the click area +------------------------ + +By default, Widgets can be clicked only within their bounding area. However, +especially with small Widgets, it can be helpful to make a Widget's "clickable" area +larger. You can do this with :cpp:expr:`lv_obj_set_ext_click_area(widget, size)`. + + .. _coord_using_styles: @@ -286,22 +318,22 @@ Using styles Under the hood the position, size and alignment properties are style properties. The above described "simple functions" hide the style related code for the sake of simplicity and set the position, size, and -alignment properties in the local styles of the object. +alignment properties in the local styles of the Widget. However, using styles to set the coordinates has some great advantages: -- It makes it easy to set the width/height/etc. for several objects +- It makes it easy to set the width/height/etc. for several Widgets together. E.g. make all the sliders 100x10 pixels sized. - It also makes possible to modify the values in one place. - The values can be partially overwritten by other styles. For example - ``style_btn`` makes the object ``100x50`` by default but adding - ``style_full_width`` overwrites only the width of the object. -- The object can have different position or size depending on state. + ``style_btn`` makes the Widget ``100x50`` by default but adding + ``style_full_width`` overwrites only the width of the Widget. +- The Widget can have different position or size depending on state. E.g. 100 px wide in :cpp:enumerator:`LV_STATE_DEFAULT` but 120 px in :cpp:enumerator:`LV_STATE_PRESSED`. - Style transitions can be used to make the coordinate changes smooth. -Here are some examples to set an object's size using a style: +Here are some examples to set a Widget's size using a style: .. code-block:: c @@ -371,18 +403,18 @@ work as expected. Translations can be used to solve this: lv_obj_add_style(btn3, &style_normal, LV_STATE_DEFAULT); lv_obj_add_style(btn3, &style_pressed, LV_STATE_PRESSED); -Translation is applied from the current position of the object. +Translation is applied from the current position of the Widget. Percentage values can be used in translations as well. The percentage is -relative to the size of the object (and not to the size of the parent). -For example :cpp:expr:`lv_pct(50)` will move the object with half of its +relative to the size of the Widget (and not to the size of the parent). +For example :cpp:expr:`lv_pct(50)` will move the Widget with half of its width/height. The translation is applied after the layouts are calculated. Therefore, -even laid out objects' position can be translated. +even laid out Widgets' position can be translated. -The translation actually moves the object. That means it makes the -scrollbars and :c:macro:`LV_SIZE_CONTENT` sized objects react to the position +The translation actually moves the Widget. That means it makes the +scrollbars and :c:macro:`LV_SIZE_CONTENT` sized Widgets react to the position change. .. _coord_transformation: @@ -390,13 +422,13 @@ change. Transformation ************** -Similarly to position, an object's size can be changed relative to the +Similarly to position, a Widget's size can be changed relative to the current size as well. The transformed width and height are added on both -sides of the object. This means a 10 px transformed width makes the -object 2x10 pixels wider. +sides of the Widget. This means a 10 px transformed width makes the +Widget 2x10 pixels wider. Unlike position translation, the size transformation doesn't make the -object "really" larger. In other words scrollbars, layouts, and +Widget "really" larger. In other words scrollbars, layouts, and :c:macro:`LV_SIZE_CONTENT` will not react to the transformed size. Hence, size transformation is "only" a visual effect. @@ -417,8 +449,8 @@ Min and Max size ---------------- Similarly to CSS, LVGL also supports ``min-width``, ``max-width``, -``min-height`` and ``max-height``. These are limits preventing an -object's size from becoming smaller/larger than these values. They are +``min-height`` and ``max-height``. These are limits preventing a +Widget's size from becoming smaller/larger than these values. They are especially useful if the size is set by percentage or :c:macro:`LV_SIZE_CONTENT`. @@ -428,8 +460,8 @@ especially useful if the size is set by percentage or lv_style_init(&style_max_height); lv_style_set_y(&style_max_height, 200); - lv_obj_set_height(obj, lv_pct(100)); - lv_obj_add_style(obj, &style_max_height, LV_STATE_DEFAULT); //Limit the height to 200 px + lv_obj_set_height(widget, lv_pct(100)); + lv_obj_add_style(widget, &style_max_height, LV_STATE_DEFAULT); //Limit the height to 200 px Percentage values can be used as well which are relative to the size of the parent's content area. @@ -440,18 +472,21 @@ the parent's content area. lv_style_init(&style_max_height); lv_style_set_y(&style_max_height, lv_pct(50)); - lv_obj_set_height(obj, lv_pct(100)); - lv_obj_add_style(obj, &style_max_height, LV_STATE_DEFAULT); //Limit the height to half parent height + lv_obj_set_height(widget, lv_pct(100)); + lv_obj_add_style(widget, &style_max_height, LV_STATE_DEFAULT); //Limit the height to half parent height + + .. _coord_layout: Layout ****** -Layout Overview + +Layout overview --------------- -Layouts can update the position and size of an object's children. They +Layouts can update the position and size of a Widget's children. They can be used to automatically arrange the children into a line or column, or in much more complicated forms. @@ -459,32 +494,35 @@ The position and size set by the layout overwrites the "normal" x, y, width, and height settings. There is only one function that is the same for every layout: -:cpp:func:`lv_obj_set_layout` ``(obj, )`` sets the layout on an object. +:cpp:func:`lv_obj_set_layout` ``(widget, )`` sets the layout on a Widget. For further settings of the parent and children see the documentation of the given layout. -Built-in layout ---------------- + +Built-in layouts +---------------- LVGL comes with two very powerful layouts: -* Flexbox: arrange objects into rows or columns, with support for wrapping and expanding items. -* Grid: arrange objects into fixed positions in 2D table. +* Flexbox: arrange Widgets into rows or columns, with support for wrapping and expanding items. +* Grid: arrange Widgets into fixed positions in 2D table. Both are heavily inspired by the CSS layouts with the same name. Layouts are described in detail in their own section of documentation. + Flags ----- -There are some flags that can be used on objects to affect how they +There are some flags that can be used on Widgets to affect how they behave with layouts: -- :cpp:enumerator:`LV_OBJ_FLAG_HIDDEN` Hidden objects are ignored in layout calculations. -- :cpp:enumerator:`LV_OBJ_FLAG_IGNORE_LAYOUT` The object is simply ignored by the layouts. Its coordinates can be set as usual. -- :cpp:enumerator:`LV_OBJ_FLAG_FLOATING` Same as :cpp:enumerator:`LV_OBJ_FLAG_IGNORE_LAYOUT` but the object with :cpp:enumerator:`LV_OBJ_FLAG_FLOATING` will be ignored in :c:macro:`LV_SIZE_CONTENT` calculations. +- :cpp:enumerator:`LV_OBJ_FLAG_HIDDEN` Hidden Widgets are ignored in layout calculations. +- :cpp:enumerator:`LV_OBJ_FLAG_IGNORE_LAYOUT` The Widget is simply ignored by the layouts. Its coordinates can be set as usual. +- :cpp:enumerator:`LV_OBJ_FLAG_FLOATING` Same as :cpp:enumerator:`LV_OBJ_FLAG_IGNORE_LAYOUT` but the Widget with :cpp:enumerator:`LV_OBJ_FLAG_FLOATING` will be ignored in :c:macro:`LV_SIZE_CONTENT` calculations. + +These flags can be added/removed with :cpp:expr:`lv_obj_add_flag(widget, FLAG)` and :cpp:expr:`lv_obj_remove_flag(widget, FLAG)` -These flags can be added/removed with :cpp:expr:`lv_obj_add_flag(obj, FLAG)` and :cpp:expr:`lv_obj_remove_flag(obj, FLAG)` Adding new layouts ------------------ @@ -501,9 +539,9 @@ LVGL can be freely extended by a custom layout like this: ... - void my_layout_update(lv_obj_t * obj, void * user_data) + void my_layout_update(lv_obj_t * widget, void * user_data) { - /*Will be called automatically if it's required to reposition/resize the children of "obj" */ + /* Will be called automatically if it's required to reposition/resize the children of "obj" */ } Custom style properties can be added which can be retrieved and used in @@ -525,11 +563,15 @@ the update callback. For example: lv_style_set_prop(style, LV_STYLE_MY_PROP, v); } + + .. _coord_example: Examples ******** + + .. _coord_api: API diff --git a/docs/overview/event.rst b/docs/details/base-widget/event.rst similarity index 53% rename from docs/overview/event.rst rename to docs/details/base-widget/event.rst index 751d7e530..9fcbbfaff 100644 --- a/docs/overview/event.rst +++ b/docs/details/base-widget/event.rst @@ -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 ` 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, , &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, , &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, , &some_data)`` and -``lv_indev_send_event(obj, , &some_data)``. +``lv_display_send_event(widget, , &some_data)`` and +``lv_indev_send_event(widget, , &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 ` 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 ` 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: diff --git a/docs/details/base-widget/index.rst b/docs/details/base-widget/index.rst new file mode 100644 index 000000000..b141a9c88 --- /dev/null +++ b/docs/details/base-widget/index.rst @@ -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 diff --git a/docs/details/base-widget/layer.rst b/docs/details/base-widget/layer.rst new file mode 100644 index 000000000..3a72eb639 --- /dev/null +++ b/docs/details/base-widget/layer.rst @@ -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 ` + +#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 +*** diff --git a/docs/layouts/flex.rst b/docs/details/base-widget/layouts/flex.rst similarity index 92% rename from docs/layouts/flex.rst rename to docs/details/base-widget/layouts/flex.rst index 8289865cb..37e656fa9 100644 --- a/docs/layouts/flex.rst +++ b/docs/details/base-widget/layouts/flex.rst @@ -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: diff --git a/docs/layouts/grid.rst b/docs/details/base-widget/layouts/grid.rst similarity index 93% rename from docs/layouts/grid.rst rename to docs/details/base-widget/layouts/grid.rst index c4afb143e..bc4fd6593 100644 --- a/docs/layouts/grid.rst +++ b/docs/details/base-widget/layouts/grid.rst @@ -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: diff --git a/docs/layouts/index.rst b/docs/details/base-widget/layouts/index.rst similarity index 100% rename from docs/layouts/index.rst rename to docs/details/base-widget/layouts/index.rst diff --git a/docs/details/base-widget/obj.rst b/docs/details/base-widget/obj.rst new file mode 100644 index 000000000..7946f607f --- /dev/null +++ b/docs/details/base-widget/obj.rst @@ -0,0 +1,633 @@ +.. _widget_basics: + +============= +Widget Basics +============= + + + +What is a Widget? +***************** +A Widget is the **basic building block** of the LVGL user interface. + +Examples of Widgets: :ref:`Base Widget (and Screen) `, +:ref:`Button `, :ref:`Label `, +:ref:`Image `, :ref:`List `, +:ref:`Chart ` and :ref:`Text Area `. + +See :ref:`widgets` to see all Widget types. + +All Widgets are referenced using an :cpp:type:`lv_obj_t` pointer as a handle. +This pointer can later be used to read or change the Widget's attributes. + + + +.. _base_widget: + +Base Widget +*********** +The most fundamental of all Widgets is the Base Widget, on which all other widgets +are based. From an Object-Oriented perspective, think of the Base Widget as the +Widget class from which all other Widgets inherit. + +The functions and functionalities of the Base Widget can be used with +other widgets as well. For example :cpp:expr:`lv_obj_set_width(slider, 100)`. + +The Base Widget can be used directly as a simple widget. While it is a simple +rectangle, it has a large number of features shared with all Widgets, detailed +below and in subsequent pages. In HTML terms, think of it as a ``
``. + + + +.. _widget_attributes: + +Attributes +********** + + +Basic attributes +---------------- + +All Widget types share some basic attributes: + +- Position +- Size +- Parent +- Styles +- Events it emits +- Flags like *Clickable*, *Scollable*, etc. +- Etc. + +You can set/get these attributes with ``lv_obj_set_...`` and +``lv_obj_get_...`` functions. For example: + +.. code-block:: c + + /* Set basic Widget attributes */ + lv_obj_set_size(btn1, 100, 50); /* Set a button's size */ + lv_obj_set_pos(btn1, 20,30); /* Set a button's position */ + +For complete details on position, size, coordinates and layouts, see :ref:`coord`. + + +Widget-specific attributes +-------------------------- + +The Widget types have special attributes as well. For example, a slider has + +- Minimum and maximum values +- Current value + +For these special attributes, every Widget type may have unique API +functions. For example for a slider: + +.. code-block:: c + + /* Set slider specific attributes */ + lv_slider_set_range(slider1, 0, 100); /* Set the min. and max. values */ + lv_slider_set_value(slider1, 40, LV_ANIM_ON); /* Set the current value (position) */ + +The API of the widgets is described in their +:ref:`Documentation ` but you can also check the respective +header files (e.g. *widgets/lv_slider.h*) + + +.. _lv_obj_parents_and_children: + +Parents and children +-------------------- + +A Widget's parent is set when the widget is created --- the parent is passed to the +creation function. + +To get a Widget's current parent, use :cpp:expr:`lv_obj_get_parent(widget)`. + +You can move the Widget to a new parent with :cpp:expr:`lv_obj_set_parent(widget, new_parent)`. + +To get a specific child of a parent use :cpp:expr:`lv_obj_get_child(parent, idx)`. +Some examples for ``idx``: + +- ``0`` get the child created first +- ``1`` get the child created second +- ``-1`` get the child created last + +You can iterate through a parent Widget's children like this: + +.. code-block:: c + + uint32_t i; + for(i = 0; i < lv_obj_get_child_count(parent); i++) { + lv_obj_t * child = lv_obj_get_child(parent, i); + /* Do something with child. */ + } + +:cpp:expr:`lv_obj_get_index(widget)` returns the index of the Widget in its parent. +It is equivalent to the number of older children in the parent. + +You can bring a Widget to the foreground or send it to the background with +:cpp:expr:`lv_obj_move_foreground(widget)` and :cpp:expr:`lv_obj_move_background(widget)`. + +You can change the index of a Widget in its parent using :cpp:expr:`lv_obj_move_to_index(widget, index)`. + +You can swap the position of two Widgets with :cpp:expr:`lv_obj_swap(widget1, widget2)`. + +To get a Widget's Screen (highest-level parent) use :cpp:expr:`lv_obj_get_screen(widget)`. + + + +.. _widget_working_mechanisms: + +Working Mechanisms +****************** + +Parent-child structure +---------------------- + +A parent Widget can be considered as the container of its children. Every Widget has +exactly one parent Widget (except Screens), but a parent Widget can have any number +of children. There is no limitation for the type of the parent but there are Widgets +which are typically a parent (e.g. button) or a child (e.g. label). + + + +Moving together +--------------- + +If the position of a parent changes, the children will move along with +it. Therefore, all positions are relative to the parent. + +.. image:: /misc/par_child1.png + +.. code-block:: c + + lv_obj_t * parent = lv_obj_create(lv_screen_active()); /* Create a parent Widget on current screen */ + lv_obj_set_size(parent, 100, 80); /* Set size of parent */ + + lv_obj_t * obj1 = lv_obj_create(parent); /* Create a Widget on previously created parent Widget */ + lv_obj_set_pos(widget1, 10, 10); /* Set position of new Widget */ + +Modify the position of the parent: + +.. image:: /misc/par_child2.png + +.. code-block:: c + + lv_obj_set_pos(parent, 50, 50); /* Move the parent. The child will move with it. */ + +(For simplicity the adjusting of colors of the Widgets is not shown in +the example.) + +Visibility only on the parent +----------------------------- + +If a child is partially or fully outside its parent then the parts +outside will not be visible. + +.. image:: /misc/par_child3.png + +.. code-block:: c + + lv_obj_set_x(widget1, -30); /* Move the child a little bit off the parent */ + +This behavior can be overwritten with +:cpp:expr:`lv_obj_add_flag(widget, LV_OBJ_FLAG_OVERFLOW_VISIBLE)` which allow the +children to be drawn out of the parent. + +Create and delete Widgets +------------------------- + +In LVGL, Widgets can be created and deleted dynamically at run time. It +means only the currently created (existing) Widgets consume RAM. + +This allows for the creation of a screen just when a button is clicked +to open it, and for deletion of screens when a new screen is loaded. + +UIs can be created based on the current environment of the device. For +example one can create meters, charts, bars and sliders based on the +currently attached sensors. + +Every widget has its own **create** function with a prototype like this: + +.. code-block:: c + + lv_obj_t * lv__create(lv_obj_t * parent, ); + +Typically, the create functions only have a ``parent`` parameter telling +them on which Widget to create the new Widget. + +The return value is a pointer to the created Widget with :cpp:type:`lv_obj_t` ``*`` +type. + +There is a common **delete** function for all Widget types. It deletes +the Widget and all of its children. + +.. code-block:: c + + void lv_obj_delete(lv_obj_t * widget); + +:cpp:func:`lv_obj_delete` will delete the Widget immediately. If for any reason you +can't delete the Widget immediately you can use +:cpp:expr:`lv_obj_delete_async(widget)` which will perform the deletion on the next +call of :cpp:func:`lv_timer_handler`. This is useful e.g. if you want to +delete the parent of a Widget in the child's :cpp:enumerator:`LV_EVENT_DELETE` +handler. + +You can remove all the children of a Widget (but not the Widget itself) +using :cpp:expr:`lv_obj_clean(widget)`. + +You can use :cpp:expr:`lv_obj_delete_delayed(widget, 1000)` to delete a Widget after +some time. The delay is expressed in milliseconds. + +Sometimes you're not sure whether a Widget was deleted and you need some way to +check if it's still "alive". Anytime before the Widget is deleted, you can use +cpp:expr:`lv_obj_null_on_delete(&widget)` to cause your Widget pointer to be set to ``NULL`` +when the Widget is deleted. + +Make sure the pointer variable itself stays valid until the Widget is deleted. Here +is an example: + +.. code:: c + + void some_timer_callback(lv_timer_t * t) + { + static lv_obj_t * my_label; + if(my_label == NULL) { + my_label = lv_label_create(lv_screen_active()); + lv_obj_delete_delayed(my_label, 1000); + lv_obj_null_on_delete(&my_label); + } + else { + lv_obj_set_x(my_label, lv_obj_get_x(my_label) + 1); + } + } + + + +.. _screens: + +Screens +******* + +What are Screens? +----------------- + +Not to be confused with a :ref:`display`, Screens are simply any Widget created +without a parent (i.e. passing NULL for the ``parent`` argument during creation). As +such, they form the "root" of a Widget Tree. + +Normally the Base Widget is used for this purpose since it has all the features most +Screens need. But an :ref:`lv_image` Widget can also be used to create a wallpaper +background for the Widget Tree. + +All Screens: + +- are automatically attached to the :ref:`default_display` current when the Screen + was created; +- automatically occupy the full area of the associated display; +- cannot be moved, i.e. functions such as :cpp:func:`lv_obj_set_pos` and + :cpp:func:`lv_obj_set_size` cannot be used on screens. + +Each :ref:`display` object can have multiple screens associated with it, but not vice +versa. Thus the relationship:: + + Display + | + --- (one or more) + /|\ + Screen Widgets (root of a Widget Tree) + | + O (zero or more) + /|\ + Child Widgets + + +Creating Screens +---------------- + +Screens are created like this: + +.. code-block:: c + + lv_obj_t * scr1 = lv_obj_create(NULL); + +Screens can be deleted with :cpp:expr:`lv_obj_delete(scr)`, but be sure you do not +delete the :ref:`active_screen`. + + +.. _active_screen: + +Active Screen +------------- +While each :ref:`display` object can have any number of Screens Widgets associated +with it, only one of those Screens is considered "Active" at any given time. That +Screen is referred to as the Display's "Active Screen". For this reason, only one +Screen and its child Widgets will ever be shown on a display at one time. + +When each :ref:`display` object was created, a default screen was created with it and +set as its "Active Screen". + +To get a pointer to the "Active Screen", call :cpp:func:`lv_screen_active`. + +To set a Screen to be the "Active Screen", call :cpp:func:`lv_screen_load` or +:cpp:func:`lv_screen_load_anim`. + + +.. _loading_screens: + +Loading Screens +--------------- + +To load a new screen, use :cpp:expr:`lv_screen_load(scr1)`. This sets ``scr1`` as +the Active Screen. + +Load Screen with Animation +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A new screen can be loaded with animation by using +:cpp:expr:`lv_screen_load_anim(scr, transition_type, time, delay, auto_del)`. The +following transition types exist: + +- :cpp:enumerator:`LV_SCR_LOAD_ANIM_NONE`: Switch immediately after ``delay`` milliseconds +- :cpp:enumerator:`LV_SCR_LOAD_ANIM_OVER_LEFT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_OVER_RIGHT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_OVER_TOP` and :cpp:enumerator:`LV_SCR_LOAD_ANIM_OVER_BOTTOM`: Move the new screen over the current towards the given direction +- :cpp:enumerator:`LV_SCR_LOAD_ANIM_OUT_LEFT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_OUT_RIGHT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_OUT_TOP` and :cpp:enumerator:`LV_SCR_LOAD_ANIM_OUT_BOTTOM`: Move out the old screen over the current towards the given direction +- :cpp:enumerator:`LV_SCR_LOAD_ANIM_MOVE_LEFT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_MOVE_RIGHT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_MOVE_TOP` and :cpp:enumerator:`LV_SCR_LOAD_ANIM_MOVE_BOTTOM`: Move both the current and new screens towards the given direction +- :cpp:enumerator:`LV_SCR_LOAD_ANIM_FADE_IN` and :cpp:enumerator:`LV_SCR_LOAD_ANIM_FADE_OUT`: Fade the new screen over the old screen, or vice versa + +Setting ``auto_del`` to ``true`` will automatically delete the old +screen when the animation is finished. + +The new screen will become active (returned by :cpp:func:`lv_screen_active`) when +the animation starts after ``delay`` time. All inputs are disabled +during the screen animation. + + +.. _layers_overview: + +Layers +------ + +When an ``lv_display_t`` object is created, 4 Screens (layers) are created and +attached to it. + +1. Bottom Layer +2. Active Screen +3. Top Layer +4. System Layer + +1, 3 and 4 are independent of the :ref:`active_screen` and they will be shown (if +they contain anything that is visible) regardless of which screen is the Active +Screen. See :ref:`screen_layers` for more information. + + +.. _transparent_screens: + +Transparent Screens +------------------- + +Usually, the opacity of the Screen is :cpp:enumerator:`LV_OPA_COVER` to provide a +solid background for its children. If this is not the case (opacity < +100%) the display's ``bottom_layer`` will be visible. If the bottom layer's +opacity is also not :cpp:enumerator:`LV_OPA_COVER` LVGL will have no solid background +to draw. + +This configuration (transparent Screen) could be useful to create, for example, +on-screen display (OSD) menus where a video is played on a different hardware layer +of the display panel, and a menu is overlaid on a higher layer. + +To properly render a UI on a transparent Screen the Display's color format needs to +be set to one with an alpha channel (for example LV_COLOR_FORMAT_ARGB8888). + +In summary, to enable transparent screens and displays for OSD menu-like UIs: + +- Set the screen's ``bg_opa`` to transparent: + :cpp:expr:`lv_obj_set_style_bg_opa(lv_screen_active(), LV_OPA_TRANSP, LV_PART_MAIN)` +- Set the bottom layer's ``bg_opa`` to transparent: + :cpp:expr:`lv_obj_set_style_bg_opa(lv_layer_bottom(), LV_OPA_TRANSP, LV_PART_MAIN)` +- Set a color format with alpha channel. E.g. + :cpp:expr:`lv_display_set_color_format(disp, LV_COLOR_FORMAT_ARGB8888)` + + + +.. _widget_parts: + +Parts +***** + +The widgets are built from multiple parts. For example a +:ref:`Base Widget ` uses the main and scrollbar parts but a +:ref:`Slider ` uses the main, indicator and knob parts. +Parts are similar to *pseudo-elements* in CSS. + +The following predefined parts exist in LVGL: + +- :cpp:enumerator:`LV_PART_MAIN`: A background like rectangle +- :cpp:enumerator:`LV_PART_SCROLLBAR`: The scrollbar(s) +- :cpp:enumerator:`LV_PART_INDICATOR`: Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox +- :cpp:enumerator:`LV_PART_KNOB`: Like a handle to grab to adjust the value +- :cpp:enumerator:`LV_PART_SELECTED`: Indicate the currently selected option or section +- :cpp:enumerator:`LV_PART_ITEMS`: Used if the widget has multiple similar elements (e.g. table cells) +- :cpp:enumerator:`LV_PART_CURSOR`: Mark a specific place e.g. text area's or chart's cursor +- :cpp:enumerator:`LV_PART_CUSTOM_FIRST`: Custom parts can be added from here. + +The main purpose of parts is to allow styling the "components" of the +widgets. They are described in more detail in the +:ref:`Style overview ` section. + + + +.. _widget_states: + +States +****** + +The Widget can be in a combination of the following states: + +- :cpp:enumerator:`LV_STATE_DEFAULT`: Normal, released state +- :cpp:enumerator:`LV_STATE_CHECKED`: Toggled or checked state +- :cpp:enumerator:`LV_STATE_FOCUSED`: Focused via keypad or encoder or clicked via touchpad/mouse +- :cpp:enumerator:`LV_STATE_FOCUS_KEY`: Focused via keypad or encoder but not via touchpad/mouse +- :cpp:enumerator:`LV_STATE_EDITED`: Edit by an encoder +- :cpp:enumerator:`LV_STATE_HOVERED`: Hovered by mouse (not supported now) +- :cpp:enumerator:`LV_STATE_PRESSED`: Being pressed +- :cpp:enumerator:`LV_STATE_SCROLLED`: Being scrolled +- :cpp:enumerator:`LV_STATE_DISABLED`: Disabled state +- :cpp:enumerator:`LV_STATE_USER_1`: Custom state +- :cpp:enumerator:`LV_STATE_USER_2`: Custom state +- :cpp:enumerator:`LV_STATE_USER_3`: Custom state +- :cpp:enumerator:`LV_STATE_USER_4`: Custom state + +The states are usually automatically changed by the library as the user +interacts with a Widget (presses, releases, focuses, etc.). However, +the states can be changed manually as well. To set or clear given state (but +leave the other states untouched) use +:cpp:expr:`lv_obj_add_state(widget, LV_STATE_...)` and +:cpp:expr:`lv_obj_remove_state(widget, LV_STATE_...)`. In both cases OR-ed state +values can be used as well. E.g. +:cpp:expr:`lv_obj_add_state(widget, part, LV_STATE_PRESSED | LV_PRESSED_CHECKED)`. + +To learn more about the states read the related section of the +:ref:`Style overview `. + + + +.. _lv_obj_flags: + +Flags +***** + +There are some Widget attributes which can be enabled/disabled by +:cpp:expr:`lv_obj_add_flag(widget, LV_OBJ_FLAG_...)` and +:cpp:expr:`lv_obj_remove_flag(widget, LV_OBJ_FLAG_...)`. + +- :cpp:enumerator:`LV_OBJ_FLAG_HIDDEN` Make the Widget hidden. (Like it wasn't there at all) +- :cpp:enumerator:`LV_OBJ_FLAG_CLICKABLE` Make the Widget clickable by input devices +- :cpp:enumerator:`LV_OBJ_FLAG_CLICK_FOCUSABLE` Add focused state to the Widget when clicked +- :cpp:enumerator:`LV_OBJ_FLAG_CHECKABLE` Toggle checked state when the Widget is clicked +- :cpp:enumerator:`LV_OBJ_FLAG_SCROLLABLE` Make the Widget scrollable +- :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_ELASTIC` Allow scrolling inside but with slower speed +- :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_MOMENTUM` Make the Widget scroll further when "thrown" +- :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_ONE` Allow scrolling only one snappable children +- :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_CHAIN_HOR` Allow propagating the horizontal scroll to a parent +- :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_CHAIN_VER` Allow propagating the vertical scroll to a parent +- :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_CHAIN` Simple packaging for (:cpp:expr:`LV_OBJ_FLAG_SCROLL_CHAIN_HOR | LV_OBJ_FLAG_SCROLL_CHAIN_VER`) +- :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_ON_FOCUS` Automatically scroll Widget to make it visible when focused +- :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_WITH_ARROW` Allow scrolling the focused Widget with arrow keys +- :cpp:enumerator:`LV_OBJ_FLAG_SNAPPABLE` If scroll snap is enabled on the parent it can snap to this Widget +- :cpp:enumerator:`LV_OBJ_FLAG_PRESS_LOCK` Keep the Widget pressed even if the press slid from the Widget +- :cpp:enumerator:`LV_OBJ_FLAG_EVENT_BUBBLE` Propagate the events to the parent as well +- :cpp:enumerator:`LV_OBJ_FLAG_GESTURE_BUBBLE` Propagate the gestures to the parent +- :cpp:enumerator:`LV_OBJ_FLAG_ADV_HITTEST` Allow performing more accurate hit (click) test. E.g. accounting for rounded corners +- :cpp:enumerator:`LV_OBJ_FLAG_IGNORE_LAYOUT` Make the Widget not positioned by the layouts +- :cpp:enumerator:`LV_OBJ_FLAG_FLOATING` Do not scroll the Widget when the parent scrolls and ignore layout +- :cpp:enumerator:`LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS` Enable sending ``LV_EVENT_DRAW_TASK_ADDED`` events +- :cpp:enumerator:`LV_OBJ_FLAG_OVERFLOW_VISIBLE` Do not clip the children's content to the parent's boundary +- :cpp:enumerator:`LV_OBJ_FLAG_FLEX_IN_NEW_TRACK` Start a new flex track on this item +- :cpp:enumerator:`LV_OBJ_FLAG_LAYOUT_1` Custom flag, free to use by layouts +- :cpp:enumerator:`LV_OBJ_FLAG_LAYOUT_2` Custom flag, free to use by layouts +- :cpp:enumerator:`LV_OBJ_FLAG_WIDGET_1` Custom flag, free to use by widget +- :cpp:enumerator:`LV_OBJ_FLAG_WIDGET_2` Custom flag, free to use by widget +- :cpp:enumerator:`LV_OBJ_FLAG_USER_1` Custom flag, free to use by user +- :cpp:enumerator:`LV_OBJ_FLAG_USER_2` Custom flag, free to use by user +- :cpp:enumerator:`LV_OBJ_FLAG_USER_3` Custom flag, free to use by user +- :cpp:enumerator:`LV_OBJ_FLAG_USER_4` Custom flag, free to use by user + +Some examples: + +.. code-block:: c + + /* Hide on Widget */ + lv_obj_add_flag(widget, LV_OBJ_FLAG_HIDDEN); + + /* Make a Widget non-clickable */ + lv_obj_remove_flag(widget, LV_OBJ_FLAG_CLICKABLE); + + + +.. _lv_obj_events: + +Base-Widget Events +****************** + +.. _widget_events: + +Events from Input Devices +------------------------- +- :cpp:enumerator:`LV_EVENT_PRESSED` Widget has been pressed. +- :cpp:enumerator:`LV_EVENT_PRESSING` Widget is being pressed (sent 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, then released. Not sent if scrolled. +- :cpp:enumerator:`LV_EVENT_SINGLE_CLICKED` Sent for first short click within a small distance and short time. +- :cpp:enumerator:`LV_EVENT_DOUBLE_CLICKED` Sent for second short click within small distance and short time. +- :cpp:enumerator:`LV_EVENT_TRIPLE_CLICKED` Sent for third short click within small distance and short time. +- :cpp:enumerator:`LV_EVENT_LONG_PRESSED` Object has been pressed for at least `long_press_time`. Not sent if scrolled. +- :cpp:enumerator:`LV_EVENT_LONG_PRESSED_REPEAT` Sent after `long_press_time` in every `long_press_repeat_time` ms. Not sent if scrolled. +- :cpp:enumerator:`LV_EVENT_CLICKED` Sent on release if not scrolled (regardless to long press). +- :cpp:enumerator:`LV_EVENT_RELEASED` Sent 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` Received when scrolling begins. +- :cpp:enumerator:`LV_EVENT_SCROLL_END` Scrolling ended. +- :cpp:enumerator:`LV_EVENT_SCROLL` Scrolling +- :cpp:enumerator:`LV_EVENT_GESTURE` A gesture is detected. Get gesture with `lv_indev_get_gesture_dir(lv_indev_active());` +- :cpp:enumerator:`LV_EVENT_KEY` A key is sent to Widget. Get key with `lv_indev_get_key(lv_indev_active());` +- :cpp:enumerator:`LV_EVENT_FOCUSED` Widget received focus, +- :cpp:enumerator:`LV_EVENT_DEFOCUSED` Widget's focus has been lost. +- :cpp:enumerator:`LV_EVENT_LEAVE` Widget's focus has been lost but is still selected. +- :cpp:enumerator:`LV_EVENT_HIT_TEST` Perform advanced hit-testing. + +Special Events +-------------- +- :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` when the :cpp:enumerator:`LV_OBJ_FLAG_CHECKABLE` flag is + enabled and the Widget was clicked (on transition to/from the checked state) + +Drawing Events +-------------- +- :cpp:enumerator:`LV_EVENT_DRAW_MAIN` Performing drawing of main part +- :cpp:enumerator:`LV_EVENT_DRAW_MAIN_BEGIN` Starting drawing of main part +- :cpp:enumerator:`LV_EVENT_DRAW_MAIN_END` Finishing drawing of main part +- :cpp:enumerator:`LV_EVENT_DRAW_POST` Perform the post draw phase (when all children are drawn) +- :cpp:enumerator:`LV_EVENT_DRAW_POST_BEGIN` Starting the post draw phase (when all children are drawn) +- :cpp:enumerator:`LV_EVENT_DRAW_POST_END` Finishing the post draw phase (when all children are drawn) + +Other Events +------------ +- :cpp:enumerator:`LV_EVENT_DELETE` Object 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 +- :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_LAYOUT_CHANGED` A child's position has changed due to a layout recalculation (when container has flex or grid layout style) +- :cpp:enumerator:`LV_EVENT_GET_SELF_SIZE` Get internal size of a widget + +.. admonition:: Further Reading + + Learn more about :ref:`events`. + + + +.. _lv_obj_keys: + +Keys +**** + +If :cpp:enumerator:`LV_OBJ_FLAG_CHECKABLE` is enabled, :cpp:enumerator:`LV_KEY_RIGHT` and +:cpp:enumerator:`LV_KEY_UP` make the Widget checked, and :cpp:enumerator:`LV_KEY_LEFT` and +:cpp:enumerator:`LV_KEY_DOWN` make it unchecked. + +If :cpp:enumerator:`LV_OBJ_FLAG_SCROLLABLE` is enabled, but the Widget is not editable +(as declared by the widget class), the arrow keys (:cpp:enumerator:`LV_KEY_UP`, +:cpp:enumerator:`LV_KEY_DOWN`, :cpp:enumerator:`LV_KEY_LEFT`, :cpp:enumerator:`LV_KEY_RIGHT`) scroll the Widget. +If the Widget can only scroll vertically, :cpp:enumerator:`LV_KEY_LEFT` and +:cpp:enumerator:`LV_KEY_RIGHT` will scroll up/down instead, making it compatible with +an encoder input device. See :ref:`Input devices overview ` for +more on encoder behaviors and the edit mode. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + + + + +.. _widget_snapshot: + +Snapshot +******** + +A snapshot image can be generated for a Widget together with its +children. Check details in :ref:`snapshot`. + + + +Example +******* + +.. include:: ../../examples/widgets/obj/index.rst + + + +.. _lv_obj_api: + +API +*** diff --git a/docs/overview/scroll.rst b/docs/details/base-widget/scroll.rst similarity index 64% rename from docs/overview/scroll.rst rename to docs/details/base-widget/scroll.rst index d3659f4ef..a6affdc2f 100644 --- a/docs/overview/scroll.rst +++ b/docs/details/base-widget/scroll.rst @@ -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 *** diff --git a/docs/details/base-widget/styles/index.rst b/docs/details/base-widget/styles/index.rst new file mode 100644 index 000000000..abfadaf66 --- /dev/null +++ b/docs/details/base-widget/styles/index.rst @@ -0,0 +1,11 @@ +.. _styles: + +====== +Styles +====== + +.. toctree:: + :maxdepth: 2 + + style + style-properties diff --git a/docs/overview/style-props.rst b/docs/details/base-widget/styles/style-properties.rst similarity index 85% rename from docs/overview/style-props.rst rename to docs/details/base-widget/styles/style-properties.rst index 93b44ad04..7641f3d14 100644 --- a/docs/overview/style-props.rst +++ b/docs/details/base-widget/styles/style-properties.rst @@ -1,16 +1,18 @@ +.. _style_properties: + ================ -Style properties +Style Properties ================ Size and position ----------------- -Properties related to size, position, alignment and layout of the objects. +Properties related to size, position, alignment and layout of Widgets. width ~~~~~ -Sets the width of object. Pixel, percentage and `LV_SIZE_CONTENT` values can be used. Percentage values are relative to the width of the parent's content area. +Sets width of Widget. Pixel, percentage and `LV_SIZE_CONTENT` values can be used. Percentage values are relative to the width of the parent's content area. .. raw:: html @@ -52,7 +54,7 @@ Sets a maximal width. Pixel and percentage values can be used. Percentage values height ~~~~~~ -Sets the height of object. Pixel, percentage and `LV_SIZE_CONTENT` can be used. Percentage values are relative to the height of the parent's content area. +Sets height of Widget. Pixel, percentage and `LV_SIZE_CONTENT` can be used. Percentage values are relative to the height of the parent's content area. .. raw:: html @@ -94,7 +96,7 @@ Sets a maximal height. Pixel and percentage values can be used. Percentage value length ~~~~~~ -Its meaning depends on the type of the widget. For example in case of lv_scale it means the length of the ticks. +Its meaning depends on the type of Widget. For example in case of lv_scale it means the length of the ticks. .. raw:: html @@ -108,7 +110,7 @@ Its meaning depends on the type of the widget. For example in case of lv_scale i x ~ -Set the X coordinate of the object considering the set `align`. Pixel and percentage values can be used. Percentage values are relative to the width of the parent's content area. +Set X coordinate of Widget considering the ``align`` setting. Pixel and percentage values can be used. Percentage values are relative to the width of the parent's content area. .. raw:: html @@ -122,7 +124,7 @@ Set the X coordinate of the object considering the set `align`. Pixel and percen y ~ -Set the Y coordinate of the object considering the set `align`. Pixel and percentage values can be used. Percentage values are relative to the height of the parent's content area. +Set Y coordinate of Widget considering the ``align`` setting. Pixel and percentage values can be used. Percentage values are relative to the height of the parent's content area. .. raw:: html @@ -136,7 +138,7 @@ Set the Y coordinate of the object considering the set `align`. Pixel and percen align ~~~~~ -Set the alignment which tells from which point of the parent the X and Y coordinates should be interpreted. The possible values are: `LV_ALIGN_DEFAULT`, `LV_ALIGN_TOP_LEFT/MID/RIGHT`, `LV_ALIGN_BOTTOM_LEFT/MID/RIGHT`, `LV_ALIGN_LEFT/RIGHT_MID`, `LV_ALIGN_CENTER`. `LV_ALIGN_DEFAULT` means `LV_ALIGN_TOP_LEFT` with LTR base direction and `LV_ALIGN_TOP_RIGHT` with RTL base direction. +Set the alignment which tells from which point of the parent the X and Y coordinates should be interpreted. Possible values are: `LV_ALIGN_DEFAULT`, `LV_ALIGN_TOP_LEFT/MID/RIGHT`, `LV_ALIGN_BOTTOM_LEFT/MID/RIGHT`, `LV_ALIGN_LEFT/RIGHT_MID`, `LV_ALIGN_CENTER`. `LV_ALIGN_DEFAULT` means `LV_ALIGN_TOP_LEFT` with LTR base direction and `LV_ALIGN_TOP_RIGHT` with RTL base direction. .. raw:: html @@ -150,7 +152,7 @@ Set the alignment which tells from which point of the parent the X and Y coordin transform_width ~~~~~~~~~~~~~~~ -Make the object wider on both sides with this value. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to the object's width. +Make Widget wider on both sides with this value. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to Widget's width. .. raw:: html @@ -164,7 +166,7 @@ Make the object wider on both sides with this value. Pixel and percentage (with transform_height ~~~~~~~~~~~~~~~~ -Make the object higher on both sides with this value. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to the object's height. +Make Widget higher on both sides with this value. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to Widget's height. .. raw:: html @@ -178,7 +180,7 @@ Make the object higher on both sides with this value. Pixel and percentage (with translate_x ~~~~~~~~~~~ -Move the object with this value in X direction. Applied after layouts, aligns and other positioning. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to the object's width. +Move Widget with this value in X direction. Applied after layouts, aligns and other positioning. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to Widget's width. .. raw:: html @@ -192,7 +194,7 @@ Move the object with this value in X direction. Applied after layouts, aligns an translate_y ~~~~~~~~~~~ -Move the object with this value in Y direction. Applied after layouts, aligns and other positioning. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to the object's height. +Move Widget with this value in Y direction. Applied after layouts, aligns and other positioning. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to Widget's height. .. raw:: html @@ -206,7 +208,7 @@ Move the object with this value in Y direction. Applied after layouts, aligns an translate_radial ~~~~~~~~~~~~~~~~ -Move the object around the centre of the parent object (e.g. around the circumference of a scale) +Move object around the centre of the parent object (e.g. around the circumference of a scale) .. raw:: html @@ -220,7 +222,7 @@ Move the object around the centre of the parent object (e.g. around the circumfe transform_scale_x ~~~~~~~~~~~~~~~~~ -Zoom an objects horizontally. The value 256 (or `LV_SCALE_NONE`) means normal size, 128 half size, 512 double size, and so on +Zoom Widget horizontally. The value 256 (or `LV_SCALE_NONE`) means normal size, 128 half size, 512 double size, and so on .. raw:: html @@ -234,7 +236,7 @@ Zoom an objects horizontally. The value 256 (or `LV_SCALE_NONE`) means normal si transform_scale_y ~~~~~~~~~~~~~~~~~ -Zoom an objects vertically. The value 256 (or `LV_SCALE_NONE`) means normal size, 128 half size, 512 double size, and so on +Zoom Widget vertically. The value 256 (or `LV_SCALE_NONE`) means normal size, 128 half size, 512 double size, and so on .. raw:: html @@ -248,7 +250,7 @@ Zoom an objects vertically. The value 256 (or `LV_SCALE_NONE`) means normal size transform_rotation ~~~~~~~~~~~~~~~~~~ -Rotate an objects. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg. +Rotate Widget. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg. .. raw:: html @@ -262,7 +264,7 @@ Rotate an objects. The value is interpreted in 0.1 degree units. E.g. 450 means transform_pivot_x ~~~~~~~~~~~~~~~~~ -Set the pivot point's X coordinate for transformations. Relative to the object's top left corner' +Set pivot point's X coordinate for transformations. Relative to Widget's top left corner' .. raw:: html @@ -276,7 +278,7 @@ Set the pivot point's X coordinate for transformations. Relative to the object's transform_pivot_y ~~~~~~~~~~~~~~~~~ -Set the pivot point's Y coordinate for transformations. Relative to the object's top left corner' +Set pivot point's Y coordinate for transformations. Relative to Widget's top left corner' .. raw:: html @@ -290,7 +292,7 @@ Set the pivot point's Y coordinate for transformations. Relative to the object's transform_skew_x ~~~~~~~~~~~~~~~~ -Skew an object horizontally. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg. +Skew Widget horizontally. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg. .. raw:: html @@ -304,7 +306,7 @@ Skew an object horizontally. The value is interpreted in 0.1 degree units. E.g. transform_skew_y ~~~~~~~~~~~~~~~~ -Skew an object vertically. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg. +Skew Widget vertically. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg. .. raw:: html @@ -407,7 +409,7 @@ Sets the padding between the columns. Used by the layouts. pad_radial ~~~~~~~~~~ -Pad the text labels away from the scale ticks/remainder of the LV_PART_ +Pad text labels away from the scale ticks/remainder of the LV_PART_ .. raw:: html @@ -421,12 +423,12 @@ Pad the text labels away from the scale ticks/remainder of the LV_PART_ Margin ------ -Properties to describe spacing around an object. Very similar to the margin properties in HTML. +Properties to describe spacing around a Widget. Very similar to the margin properties in HTML. margin_top ~~~~~~~~~~ -Sets the margin on the top. The object will keep this space from its siblings in layouts. +Sets margin on the top. Widget will keep this space from its siblings in layouts. .. raw:: html @@ -440,7 +442,7 @@ Sets the margin on the top. The object will keep this space from its siblings in margin_bottom ~~~~~~~~~~~~~ -Sets the margin on the bottom. The object will keep this space from its siblings in layouts. +Sets margin on the bottom. Widget will keep this space from its siblings in layouts. .. raw:: html @@ -454,7 +456,7 @@ Sets the margin on the bottom. The object will keep this space from its siblings margin_left ~~~~~~~~~~~ -Sets the margin on the left. The object will keep this space from its siblings in layouts. +Sets margin on the left. Widget will keep this space from its siblings in layouts. .. raw:: html @@ -468,7 +470,7 @@ Sets the margin on the left. The object will keep this space from its siblings i margin_right ~~~~~~~~~~~~ -Sets the margin on the right. The object will keep this space from its siblings in layouts. +Sets margin on the right. Widget will keep this space from its siblings in layouts. .. raw:: html @@ -482,12 +484,12 @@ Sets the margin on the right. The object will keep this space from its siblings Background ---------- -Properties to describe the background color and image of the objects. +Properties to describe the background color and image of Widget. bg_color ~~~~~~~~ -Set the background color of the object. +Set background color of Widget. .. raw:: html @@ -501,7 +503,7 @@ Set the background color of the object. bg_opa ~~~~~~ -Set the opacity of the background. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. +Set opacity of the background. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. .. raw:: html @@ -515,7 +517,7 @@ Set the opacity of the background. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means bg_grad_color ~~~~~~~~~~~~~ -Set the gradient color of the background. Used only if `grad_dir` is not `LV_GRAD_DIR_NONE` +Set gradient color of the background. Used only if `grad_dir` is not `LV_GRAD_DIR_NONE` .. raw:: html @@ -529,7 +531,7 @@ Set the gradient color of the background. Used only if `grad_dir` is not `LV_GRA bg_grad_dir ~~~~~~~~~~~ -Set the direction of the gradient of the background. The possible values are `LV_GRAD_DIR_NONE/HOR/VER`. +Set direction of the gradient of the background. Possible values are `LV_GRAD_DIR_NONE/HOR/VER`. .. raw:: html @@ -543,7 +545,7 @@ Set the direction of the gradient of the background. The possible values are `LV bg_main_stop ~~~~~~~~~~~~ -Set the point from which the background color should start for gradients. 0 means to top/left side, 255 the bottom/right side, 128 the center, and so on +Set point from which background color should start for gradients. 0 means to top/left side, 255 the bottom/right side, 128 the center, and so on .. raw:: html @@ -557,7 +559,7 @@ Set the point from which the background color should start for gradients. 0 mean bg_grad_stop ~~~~~~~~~~~~ -Set the point from which the background's gradient color should start. 0 means to top/left side, 255 the bottom/right side, 128 the center, and so on +Set point from which background's gradient color should start. 0 means to top/left side, 255 the bottom/right side, 128 the center, and so on .. raw:: html @@ -571,7 +573,7 @@ Set the point from which the background's gradient color should start. 0 means t bg_main_opa ~~~~~~~~~~~ -Set the opacity of the first gradient color +Set opacity of the first gradient color .. raw:: html @@ -585,7 +587,7 @@ Set the opacity of the first gradient color bg_grad_opa ~~~~~~~~~~~ -Set the opacity of the second gradient color +Set opacity of the second gradient color .. raw:: html @@ -599,7 +601,7 @@ Set the opacity of the second gradient color bg_grad ~~~~~~~ -Set the gradient definition. The pointed instance must exist while the object is alive. NULL to disable. It wraps `BG_GRAD_COLOR`, `BG_GRAD_DIR`, `BG_MAIN_STOP` and `BG_GRAD_STOP` into one descriptor and allows creating gradients with more colors too. If it's set other gradient related properties will be ignored' +Set gradient definition. The pointed instance must exist while Widget is alive. NULL to disable. It wraps `BG_GRAD_COLOR`, `BG_GRAD_DIR`, `BG_MAIN_STOP` and `BG_GRAD_STOP` into one descriptor and allows creating gradients with more colors as well. If it's set other gradient related properties will be ignored' .. raw:: html @@ -627,7 +629,7 @@ Set a background image. Can be a pointer to `lv_image_dsc_t`, a path to a file o bg_image_opa ~~~~~~~~~~~~ -Set the opacity of the background image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. +Set opacity of the background image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. .. raw:: html @@ -655,7 +657,7 @@ Set a color to mix to the background image. bg_image_recolor_opa ~~~~~~~~~~~~~~~~~~~~ -Set the intensity of background image recoloring. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means no mixing, 255, `LV_OPA_100` or `LV_OPA_COVER` means full recoloring, other values or LV_OPA_10, LV_OPA_20, etc are interpreted proportionally. +Set intensity of background image recoloring. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means no mixing, 255, `LV_OPA_100` or `LV_OPA_COVER` means full recoloring, other values or LV_OPA_10, LV_OPA_20, etc are interpreted proportionally. .. raw:: html @@ -669,7 +671,7 @@ Set the intensity of background image recoloring. Value 0, `LV_OPA_0` or `LV_OPA bg_image_tiled ~~~~~~~~~~~~~~ -If enabled the background image will be tiled. The possible values are `true` or `false`. +If enabled the background image will be tiled. Possible values are `true` or `false`. .. raw:: html @@ -688,7 +690,7 @@ Properties to describe the borders border_color ~~~~~~~~~~~~ -Set the color of the border +Set color of the border .. raw:: html @@ -702,7 +704,7 @@ Set the color of the border border_opa ~~~~~~~~~~ -Set the opacity of the border. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. +Set opacity of the border. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. .. raw:: html @@ -716,7 +718,7 @@ Set the opacity of the border. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means full border_width ~~~~~~~~~~~~ -Set the width of the border. Only pixel values can be used. +Set width of the border. Only pixel values can be used. .. raw:: html @@ -730,7 +732,7 @@ Set the width of the border. Only pixel values can be used. border_side ~~~~~~~~~~~ -Set only which side(s) the border should be drawn. The possible values are `LV_BORDER_SIDE_NONE/TOP/BOTTOM/LEFT/RIGHT/INTERNAL`. OR-ed values can be used as well, e.g. `LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_LEFT`. +Set only which side(s) the border should be drawn. Possible values are `LV_BORDER_SIDE_NONE/TOP/BOTTOM/LEFT/RIGHT/INTERNAL`. OR-ed values can be used as well, e.g. `LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_LEFT`. .. raw:: html @@ -763,7 +765,7 @@ Properties to describe the outline. It's like a border but drawn outside of the outline_width ~~~~~~~~~~~~~ -Set the width of the outline in pixels. +Set width of outline in pixels. .. raw:: html @@ -777,7 +779,7 @@ Set the width of the outline in pixels. outline_color ~~~~~~~~~~~~~ -Set the color of the outline. +Set color of outline. .. raw:: html @@ -791,7 +793,7 @@ Set the color of the outline. outline_opa ~~~~~~~~~~~ -Set the opacity of the outline. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. +Set opacity of outline. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. .. raw:: html @@ -805,7 +807,7 @@ Set the opacity of the outline. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means ful outline_pad ~~~~~~~~~~~ -Set the padding of the outline, i.e. the gap between object and the outline. +Set padding of outline, i.e. the gap between Widget and the outline. .. raw:: html @@ -824,7 +826,7 @@ Properties to describe the shadow drawn under the rectangles. shadow_width ~~~~~~~~~~~~ -Set the width of the shadow in pixels. The value should be >= 0. +Set width of the shadow in pixels. The value should be >= 0. .. raw:: html @@ -838,7 +840,7 @@ Set the width of the shadow in pixels. The value should be >= 0. shadow_offset_x ~~~~~~~~~~~~~~~ -Set an offset on the shadow in pixels in X direction. +Set an offset on the shadow in pixels in X direction. .. raw:: html @@ -852,7 +854,7 @@ Set an offset on the shadow in pixels in X direction. shadow_offset_y ~~~~~~~~~~~~~~~ -Set an offset on the shadow in pixels in Y direction. +Set an offset on the shadow in pixels in Y direction. .. raw:: html @@ -866,7 +868,7 @@ Set an offset on the shadow in pixels in Y direction. shadow_spread ~~~~~~~~~~~~~ -Make the shadow calculation to use a larger or smaller rectangle as base. The value can be in pixel to make the area larger/smaller +Make shadow calculation to use a larger or smaller rectangle as base. The value can be in pixels to make the area larger/smaller .. raw:: html @@ -880,7 +882,7 @@ Make the shadow calculation to use a larger or smaller rectangle as base. The va shadow_color ~~~~~~~~~~~~ -Set the color of the shadow +Set color of shadow .. raw:: html @@ -894,7 +896,7 @@ Set the color of the shadow shadow_opa ~~~~~~~~~~ -Set the opacity of the shadow. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. +Set opacity of shadow. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. .. raw:: html @@ -913,7 +915,7 @@ Properties to describe the images image_opa ~~~~~~~~~ -Set the opacity of an image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. +Set opacity of an image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. .. raw:: html @@ -927,7 +929,7 @@ Set the opacity of an image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully image_recolor ~~~~~~~~~~~~~ -Set color to mixt to the image. +Set color to mix with the image. .. raw:: html @@ -941,7 +943,7 @@ Set color to mixt to the image. image_recolor_opa ~~~~~~~~~~~~~~~~~ -Set the intensity of the color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. +Set intensity of color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. .. raw:: html @@ -955,12 +957,12 @@ Set the intensity of the color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` me Line ---- -Properties to describe line-like objects +Properties to describe line-like Widgets line_width ~~~~~~~~~~ -Set the width of the lines in pixel. +Set width of lines in pixels. .. raw:: html @@ -974,7 +976,7 @@ Set the width of the lines in pixel. line_dash_width ~~~~~~~~~~~~~~~ -Set the width of dashes in pixel. Note that dash works only on horizontal and vertical lines +Set width of dashes in pixels. Note that dash works only on horizontal and vertical lines .. raw:: html @@ -988,7 +990,7 @@ Set the width of dashes in pixel. Note that dash works only on horizontal and ve line_dash_gap ~~~~~~~~~~~~~ -Set the gap between dashes in pixel. Note that dash works only on horizontal and vertical lines +Set gap between dashes in pixels. Note that dash works only on horizontal and vertical lines .. raw:: html @@ -1002,7 +1004,7 @@ Set the gap between dashes in pixel. Note that dash works only on horizontal and line_rounded ~~~~~~~~~~~~ -Make the end points of the lines rounded. `true`: rounded, `false`: perpendicular line ending +Make end points of the lines rounded. `true`: rounded, `false`: perpendicular line ending .. raw:: html @@ -1016,7 +1018,7 @@ Make the end points of the lines rounded. `true`: rounded, `false`: perpendicula line_color ~~~~~~~~~~ -Set the color of the lines. +Set color of lines. .. raw:: html @@ -1030,7 +1032,7 @@ Set the color of the lines. line_opa ~~~~~~~~ -Set the opacity of the lines. +Set opacity of lines. .. raw:: html @@ -1049,7 +1051,7 @@ TODO arc_width ~~~~~~~~~ -Set the width (thickness) of the arcs in pixel. +Set width (thickness) of arcs in pixels. .. raw:: html @@ -1063,7 +1065,7 @@ Set the width (thickness) of the arcs in pixel. arc_rounded ~~~~~~~~~~~ -Make the end points of the arcs rounded. `true`: rounded, `false`: perpendicular line ending +Make end points of arcs rounded. `true`: rounded, `false`: perpendicular line ending .. raw:: html @@ -1077,7 +1079,7 @@ Make the end points of the arcs rounded. `true`: rounded, `false`: perpendicular arc_color ~~~~~~~~~ -Set the color of the arc. +Set color of arc. .. raw:: html @@ -1091,7 +1093,7 @@ Set the color of the arc. arc_opa ~~~~~~~ -Set the opacity of the arcs. +Set opacity of arcs. .. raw:: html @@ -1105,7 +1107,7 @@ Set the opacity of the arcs. arc_image_src ~~~~~~~~~~~~~ -Set an image from which the arc will be masked out. It's useful to display complex effects on the arcs. Can be a pointer to `lv_image_dsc_t` or a path to a file +Set an image from which arc will be masked out. It's useful to display complex effects on the arcs. Can be a pointer to `lv_image_dsc_t` or a path to a file .. raw:: html @@ -1124,7 +1126,7 @@ Properties to describe the properties of text. All these properties are inherite text_color ~~~~~~~~~~ -Sets the color of the text. +Sets color of text. .. raw:: html @@ -1138,7 +1140,7 @@ Sets the color of the text. text_opa ~~~~~~~~ -Set the opacity of the text. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. +Set opacity of text. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. .. raw:: html @@ -1152,7 +1154,7 @@ Set the opacity of the text. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully text_font ~~~~~~~~~ -Set the font of the text (a pointer `lv_font_t *`). +Set font of text (a pointer `lv_font_t *`). .. raw:: html @@ -1166,7 +1168,7 @@ Set the font of the text (a pointer `lv_font_t *`). text_letter_space ~~~~~~~~~~~~~~~~~ -Set the letter space in pixels +Set letter space in pixels .. raw:: html @@ -1180,7 +1182,7 @@ Set the letter space in pixels text_line_space ~~~~~~~~~~~~~~~ -Set the line space in pixels. +Set line space in pixels. .. raw:: html @@ -1194,7 +1196,7 @@ Set the line space in pixels. text_decor ~~~~~~~~~~ -Set decoration for the text. The possible values are `LV_TEXT_DECOR_NONE/UNDERLINE/STRIKETHROUGH`. OR-ed values can be used as well. +Set decoration for the text. Possible values are `LV_TEXT_DECOR_NONE/UNDERLINE/STRIKETHROUGH`. OR-ed values can be used as well. .. raw:: html @@ -1208,7 +1210,7 @@ Set decoration for the text. The possible values are `LV_TEXT_DECOR_NONE/UNDERLI text_align ~~~~~~~~~~ -Set how to align the lines of the text. Note that it doesn't align the object itself, only the lines inside the object. The possible values are `LV_TEXT_ALIGN_LEFT/CENTER/RIGHT/AUTO`. `LV_TEXT_ALIGN_AUTO` detect the text base direction and uses left or right alignment accordingly +Set how to align the lines of the text. Note that it doesn't align the Widget itself, only the lines inside the Widget. Possible values are `LV_TEXT_ALIGN_LEFT/CENTER/RIGHT/AUTO`. `LV_TEXT_ALIGN_AUTO` detect the text base direction and uses left or right alignment accordingly .. raw:: html @@ -1227,7 +1229,7 @@ Mixed properties for various purposes. radius ~~~~~~ -Set the radius on every corner. The value is interpreted in pixel (>= 0) or `LV_RADIUS_CIRCLE` for max. radius +Set radius on every corner. The value is interpreted in pixels (>= 0) or `LV_RADIUS_CIRCLE` for max. radius .. raw:: html @@ -1241,7 +1243,7 @@ Set the radius on every corner. The value is interpreted in pixel (>= 0) or `LV_ radial_offset ~~~~~~~~~~~~~ -Move the start point of the object (e.g. scale tick) radially +Move start point of object (e.g. scale tick) radially .. raw:: html @@ -1269,7 +1271,7 @@ Enable to clip the overflowed content on the rounded corner. Can be `true` or `f opa ~~~ -Scale down all opacity values of the object by this factor. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. +Scale down all opacity values of the Widget by this factor. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. .. raw:: html @@ -1283,7 +1285,7 @@ Scale down all opacity values of the object by this factor. Value 0, `LV_OPA_0` opa_layered ~~~~~~~~~~~ -First draw the object on the layer, then scale down layer opacity factor. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. +First draw Widget on the layer, then scale down layer opacity factor. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. .. raw:: html @@ -1297,7 +1299,7 @@ First draw the object on the layer, then scale down layer opacity factor. Value color_filter_dsc ~~~~~~~~~~~~~~~~ -Mix a color to all colors of the object. +Mix a color with all colors of the Widget. .. raw:: html @@ -1325,7 +1327,7 @@ The intensity of mixing of color filter. anim ~~~~ -The animation template for the object's animation. Should be a pointer to `lv_anim_t`. The animation parameters are widget specific, e.g. animation time could be the E.g. blink time of the cursor on the text area or scroll time of a roller. See the widgets' documentation to learn more. +Animation template for Widget's animation. Should be a pointer to `lv_anim_t`. The animation parameters are widget specific, e.g. animation time could be the E.g. blink time of the cursor on the text area or scroll time of a roller. See Widgets' documentation to learn more. .. raw:: html @@ -1339,7 +1341,7 @@ The animation template for the object's animation. Should be a pointer to `lv_an anim_duration ~~~~~~~~~~~~~ -The animation duration in milliseconds. Its meaning is widget specific. E.g. blink time of the cursor on the text area or scroll time of a roller. See the widgets' documentation to learn more. +Animation duration in milliseconds. Its meaning is widget specific. E.g. blink time of the cursor on the text area or scroll time of a roller. See Widgets' documentation to learn more. .. raw:: html @@ -1353,7 +1355,7 @@ The animation duration in milliseconds. Its meaning is widget specific. E.g. bli transition ~~~~~~~~~~ -An initialized `lv_style_transition_dsc_t` to describe a transition. +An initialized ``lv_style_transition_dsc_t`` to describe a transition. .. raw:: html @@ -1367,7 +1369,7 @@ An initialized `lv_style_transition_dsc_t` to describe a transition. blend_mode ~~~~~~~~~~ -Describes how to blend the colors to the background. The possible values are `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE/MULTIPLY` +Describes how to blend the colors to the background. Possible values are `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE/MULTIPLY` .. raw:: html @@ -1381,7 +1383,7 @@ Describes how to blend the colors to the background. The possible values are `LV layout ~~~~~~ -Set the layout if the object. The children will be repositioned and resized according to the policies set for the layout. For the possible values see the documentation of the layouts. +Set layout of Widget. Children will be repositioned and resized according to policies set for the layout. For possible values see documentation of the layouts. .. raw:: html @@ -1395,7 +1397,7 @@ Set the layout if the object. The children will be repositioned and resized acco base_dir ~~~~~~~~ -Set the base direction of the object. The possible values are `LV_BIDI_DIR_LTR/RTL/AUTO`. +Set base direction of Widget. Possible values are `LV_BIDI_DIR_LTR/RTL/AUTO`. .. raw:: html @@ -1409,7 +1411,7 @@ Set the base direction of the object. The possible values are `LV_BIDI_DIR_LTR/R bitmap_mask_src ~~~~~~~~~~~~~~~ -If set a layer will be created for the widget and the layer will be masked with this A8 bitmap mask. +If set, a layer will be created for the widget and the layer will be masked with this A8 bitmap mask. .. raw:: html @@ -1423,7 +1425,7 @@ If set a layer will be created for the widget and the layer will be masked with rotary_sensitivity ~~~~~~~~~~~~~~~~~~ -Adjust the sensitivity for rotary encoders in 1/256 unit. It means, 128: slow down the rotary to half, 512: speeds up to double, 256: no change +Adjust sensitivity for rotary encoders in 1/256 unit. It means, 128: slow down the rotary to half, 512: speeds up to double, 256: no change .. raw:: html @@ -1498,7 +1500,7 @@ Defines how to align the tracks of the flow flex_grow ~~~~~~~~~ -Defines how much space to take proportionally from the free space of the object's track +Defines how much space to take proportionally from the free space of the Widget's track .. raw:: html @@ -1573,7 +1575,7 @@ Defines how to distribute the rows. grid_cell_column_pos ~~~~~~~~~~~~~~~~~~~~ -Set the column in which the object should be placed +Set column in which Widget should be placed. .. raw:: html @@ -1587,7 +1589,7 @@ Set the column in which the object should be placed grid_cell_x_align ~~~~~~~~~~~~~~~~~ -Set how to align the object horizontally. +Set how to align Widget horizontally. .. raw:: html @@ -1601,7 +1603,7 @@ Set how to align the object horizontally. grid_cell_column_span ~~~~~~~~~~~~~~~~~~~~~ -Set how many columns the object should span. Needs to be >= 1 +Set how many columns Widget should span. Needs to be >= 1. .. raw:: html @@ -1615,7 +1617,7 @@ Set how many columns the object should span. Needs to be >= 1 grid_cell_row_pos ~~~~~~~~~~~~~~~~~ -Set the row in which the object should be placed +Set row in which Widget should be placed. .. raw:: html @@ -1629,7 +1631,7 @@ Set the row in which the object should be placed grid_cell_y_align ~~~~~~~~~~~~~~~~~ -Set how to align the object vertically. +Set how to align Widget vertically. .. raw:: html @@ -1643,7 +1645,7 @@ Set how to align the object vertically. grid_cell_row_span ~~~~~~~~~~~~~~~~~~ -Set how many rows the object should span. Needs to be >= 1 +Set how many rows Widget should span. Needs to be >= 1. .. raw:: html diff --git a/docs/overview/style.rst b/docs/details/base-widget/styles/style.rst similarity index 78% rename from docs/overview/style.rst rename to docs/details/base-widget/styles/style.rst index ebc17616e..521dd4647 100644 --- a/docs/overview/style.rst +++ b/docs/details/base-widget/styles/style.rst @@ -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 ` 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, )``. ```` is an +To add a style to a Widget use +``lv_obj_add_style(widget, &style, )``. ```` 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_(obj, )``. - 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_(widget, )``. + 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. ``
``) 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_(obj, , );`` For example: +``lv_obj_set_style_(widget, , );`` 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 `. -For the full list of style properties click -:ref:`here `. 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: diff --git a/docs/overview/debugging/gdb_plugin.rst b/docs/details/debugging/gdb_plugin.rst similarity index 100% rename from docs/overview/debugging/gdb_plugin.rst rename to docs/details/debugging/gdb_plugin.rst diff --git a/docs/overview/debugging/index.rst b/docs/details/debugging/index.rst similarity index 68% rename from docs/overview/debugging/index.rst rename to docs/details/debugging/index.rst index 2cf92b254..9bd52b10a 100644 --- a/docs/overview/debugging/index.rst +++ b/docs/details/debugging/index.rst @@ -1,8 +1,8 @@ .. _debugging: -============== -Debugging LVGL -============== +========= +Debugging +========= .. toctree:: :maxdepth: 2 diff --git a/docs/overview/debugging/log.rst b/docs/details/debugging/log.rst similarity index 95% rename from docs/overview/debugging/log.rst rename to docs/details/debugging/log.rst index 3fa9d4d7d..06535666b 100644 --- a/docs/overview/debugging/log.rst +++ b/docs/details/debugging/log.rst @@ -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 ************* diff --git a/docs/overview/debugging/profiler.rst b/docs/details/debugging/profiler.rst similarity index 100% rename from docs/overview/debugging/profiler.rst rename to docs/details/debugging/profiler.rst diff --git a/docs/overview/debugging/vg_lite_tvg.rst b/docs/details/debugging/vg_lite_tvg.rst similarity index 92% rename from docs/overview/debugging/vg_lite_tvg.rst rename to docs/details/debugging/vg_lite_tvg.rst index 5c445a3c5..e04cbee7e 100644 --- a/docs/overview/debugging/vg_lite_tvg.rst +++ b/docs/details/debugging/vg_lite_tvg.rst @@ -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 `__. +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. diff --git a/docs/details/index.rst b/docs/details/index.rst new file mode 100644 index 000000000..3f450aa6a --- /dev/null +++ b/docs/details/index.rst @@ -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 diff --git a/docs/integration/bindings/api_json.rst b/docs/details/integration/bindings/api_json.rst similarity index 99% rename from docs/integration/bindings/api_json.rst rename to docs/details/integration/bindings/api_json.rst index 20adffc59..a15167f60 100644 --- a/docs/integration/bindings/api_json.rst +++ b/docs/details/integration/bindings/api_json.rst @@ -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 diff --git a/docs/integration/bindings/cpp.rst b/docs/details/integration/bindings/cpp.rst similarity index 100% rename from docs/integration/bindings/cpp.rst rename to docs/details/integration/bindings/cpp.rst diff --git a/docs/integration/bindings/index.rst b/docs/details/integration/bindings/index.rst similarity index 100% rename from docs/integration/bindings/index.rst rename to docs/details/integration/bindings/index.rst diff --git a/docs/integration/bindings/javascript.rst b/docs/details/integration/bindings/javascript.rst similarity index 100% rename from docs/integration/bindings/javascript.rst rename to docs/details/integration/bindings/javascript.rst diff --git a/docs/integration/bindings/micropython.rst b/docs/details/integration/bindings/micropython.rst similarity index 98% rename from docs/integration/bindings/micropython.rst rename to docs/details/integration/bindings/micropython.rst index 37e8c1783..cca969482 100644 --- a/docs/integration/bindings/micropython.rst +++ b/docs/details/integration/bindings/micropython.rst @@ -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 `__. @@ -110,7 +110,7 @@ edit a python script and run it. `Click here to experiment on the online simulator `__ -Many `LVGL examples `__ are available also for MicroPython. Just click the link! +Many :ref:`LVGL examples ` are available also for MicroPython. Just click the link! PC Simulator diff --git a/docs/integration/bindings/pikascript.rst b/docs/details/integration/bindings/pikascript.rst similarity index 100% rename from docs/integration/bindings/pikascript.rst rename to docs/details/integration/bindings/pikascript.rst diff --git a/docs/integration/building/cmake.rst b/docs/details/integration/building/cmake.rst similarity index 99% rename from docs/integration/building/cmake.rst rename to docs/details/integration/building/cmake.rst index 5577d96b4..d4a362732 100644 --- a/docs/integration/building/cmake.rst +++ b/docs/details/integration/building/cmake.rst @@ -1,7 +1,7 @@ .. _build_cmake: ===== -cmake +CMake ===== diff --git a/docs/integration/building/index.rst b/docs/details/integration/building/index.rst similarity index 100% rename from docs/integration/building/index.rst rename to docs/details/integration/building/index.rst diff --git a/docs/integration/building/make.rst b/docs/details/integration/building/make.rst similarity index 100% rename from docs/integration/building/make.rst rename to docs/details/integration/building/make.rst diff --git a/docs/integration/chip/arm.rst b/docs/details/integration/chip/arm.rst similarity index 100% rename from docs/integration/chip/arm.rst rename to docs/details/integration/chip/arm.rst diff --git a/docs/integration/chip/espressif.rst b/docs/details/integration/chip/espressif.rst similarity index 99% rename from docs/integration/chip/espressif.rst rename to docs/details/integration/chip/espressif.rst index 0ecd7994f..4593217ec 100644 --- a/docs/integration/chip/espressif.rst +++ b/docs/details/integration/chip/espressif.rst @@ -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** diff --git a/docs/integration/chip/index.rst b/docs/details/integration/chip/index.rst similarity index 100% rename from docs/integration/chip/index.rst rename to docs/details/integration/chip/index.rst diff --git a/docs/integration/chip/nxp.rst b/docs/details/integration/chip/nxp.rst similarity index 99% rename from docs/integration/chip/nxp.rst rename to docs/details/integration/chip/nxp.rst index 60dc5bde5..84013cf32 100644 --- a/docs/integration/chip/nxp.rst +++ b/docs/details/integration/chip/nxp.rst @@ -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 diff --git a/docs/integration/chip/renesas.rst b/docs/details/integration/chip/renesas.rst similarity index 100% rename from docs/integration/chip/renesas.rst rename to docs/details/integration/chip/renesas.rst diff --git a/docs/integration/chip/stm32.rst b/docs/details/integration/chip/stm32.rst similarity index 90% rename from docs/integration/chip/stm32.rst rename to docs/details/integration/chip/stm32.rst index 4e7ce7fa5..1068474cd 100644 --- a/docs/integration/chip/stm32.rst +++ b/docs/details/integration/chip/stm32.rst @@ -19,9 +19,9 @@ Including LVGL in a Project navigating to **C/C++ Build** -> **Settings** -> **Include paths**, and ensuring that the LVGL directory is listed. -Now that the source files are included in your project, follow the -instructions for `Porting `_ your -project to create the ``lv_conf.h`` file, and initialise the display. +Now that the source files are included in your project, follow the instructions to +:ref:`add_lvgl_to_your_project` and to create the ``lv_conf.h`` file, and +initialise the display. Bare Metal Example @@ -39,8 +39,8 @@ the *main.c* file. \* Create some frame buffer(s) as global variables: /* Frame buffers * Static or global buffer(s). The second buffer is optional * TODO: Adjust color format and choose buffer size. DISPLAY_WIDTH * 10 is one suggestion. */ - #define BYTE_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_RGB565)) /*will be 2 for RGB565 */ - #define BUFF_SIZE (DISPLAY_WIDTH * 10 * BYTE_PER_PIXEL) + #define BYTES_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_RGB565)) /* will be 2 for RGB565 */ + #define BUFF_SIZE (DISPLAY_WIDTH * 10 * BYTES_PER_PIXEL) static uint8_t buf_1[BUFF_SIZE]; static uint8_t buf_2[BUFF_SIZE]; @@ -55,15 +55,15 @@ the *main.c* file. \* Create some frame buffer(s) as global variables: //Initialise LVGL UI library lv_init(); - lv_display_t * disp = lv_display_create(WIDTH, HEIGHT); /*Basic initialization with horizontal and vertical resolution in pixels*/ - lv_display_set_flush_cb(disp, my_flush_cb); /*Set a flush callback to draw to the display*/ - lv_display_set_buffers(disp, buf_1, buf_2, sizeof(buf_1), LV_DISPLAY_RENDER_MODE_PARTIAL); /*Set an initialized buffer*/ + lv_display_t * disp = lv_display_create(WIDTH, HEIGHT); /* Basic initialization with horizontal and vertical resolution in pixels */ + lv_display_set_flush_cb(disp, my_flush_cb); /* Set a flush callback to draw to the display */ + lv_display_set_buffers(disp, buf_1, buf_2, sizeof(buf_1), LV_DISPLAY_RENDER_MODE_PARTIAL); /* Set an initialized buffer */ -- Create some dummy objects to test the output: +- Create some dummy Widgets to test the output: .. 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); lv_obj_set_style_text_color(lv_screen_active(), lv_color_hex(0xffffff), LV_PART_MAIN); @@ -138,7 +138,7 @@ the *main.c* file. \* Create some frame buffer(s) as global variables: HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET); /* IMPORTANT!!! - * Inform the graphics library that you are ready with the flushing*/ + * Inform the graphics library that you are ready with the flushing */ lv_display_flush_ready(disp); } @@ -148,17 +148,17 @@ FreeRTOS Example A minimal example using STM32CubeIDE, HAL, and CMSISv1 (FreeRTOS). *Note that we have not used Mutexes in this example, however LVGL is* **NOT** -*thread safe and so Mutexes should be used*. See: :ref:`os_interrupt` +*thread safe and so Mutexes should be used*. See: :ref:`threading` \* ``#include "lvgl.h"`` \* Create your frame buffer(s) as global variables: .. code-block:: c /* Frame buffers * Static or global buffer(s). The second buffer is optional */ - #define BYTE_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_RGB565)) /* will be 2 for RGB565 */ + #define BYTES_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_RGB565)) /* will be 2 for RGB565 */ /* TODO: Declare your own BUFF_SIZE appropriate to your system. */ static lv_color_t buf_1[BUFF_SIZE]; - #define BUFF_SIZE (DISPLAY_WIDTH * 10 * BYTE_PER_PIXEL) + #define BUFF_SIZE (DISPLAY_WIDTH * 10 * BYTES_PER_PIXEL) static uint8_t buf_1[BUFF_SIZE]; static lv_color_t buf_2[BUFF_SIZE]; @@ -178,11 +178,11 @@ A minimal example using STM32CubeIDE, HAL, and CMSISv1 (FreeRTOS). /* Register the touch controller with LVGL - Not included here for brevity. */ -- Create some dummy objects to test the output: +- Create some dummy Widgets to test the output: .. 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); lv_obj_set_style_text_color(lv_screen_active(), lv_color_hex(0xffffff), LV_PART_MAIN); @@ -266,7 +266,7 @@ A minimal example using STM32CubeIDE, HAL, and CMSISv1 (FreeRTOS). HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET); /* IMPORTANT!!! - * Inform the graphics library that you are ready with the flushing*/ + * Inform the graphics library that you are ready with the flushing */ lv_display_flush_ready(display); } diff --git a/docs/integration/driver/X11.rst b/docs/details/integration/driver/X11.rst similarity index 79% rename from docs/integration/driver/X11.rst rename to docs/details/integration/driver/X11.rst index e5d1be524..0ed8246cf 100644 --- a/docs/integration/driver/X11.rst +++ b/docs/details/integration/driver/X11.rst @@ -32,26 +32,26 @@ Configure X11 driver - Direct Exit .. code-block:: c - #define LV_X11_DIRECT_EXIT 1 /*preferred default - ends the application automatically if last window has been closed*/ + #define LV_X11_DIRECT_EXIT 1 /* preferred default - ends the application automatically if last window has been closed */ // or - #define LV_X11_DIRECT_EXIT 0 /*application is responsible for ending the application (e.g. by own LV_EVENT_DELETE handler*/ + #define LV_X11_DIRECT_EXIT 0 /* application is responsible for ending the application (e.g. by own LV_EVENT_DELETE handler */ - Double buffering .. code-block:: c - #define LV_X11_DOUBLE_BUFFER 1 /*preferred default*/ + #define LV_X11_DOUBLE_BUFFER 1 /* preferred default */ // or - #define LV_X11_DOUBLE_BUFFER 0 /*not recommended*/ + #define LV_X11_DOUBLE_BUFFER 0 /* not recommended */ - Render mode .. code-block:: c - #define LV_X11_RENDER_MODE_PARTIAL 1 /*LV_DISPLAY_RENDER_MODE_PARTIAL, preferred default*/ + #define LV_X11_RENDER_MODE_PARTIAL 1 /* LV_DISPLAY_RENDER_MODE_PARTIAL, preferred default */ // or - #define LV_X11_RENDER_MODE_DIRECT 1 /*LV_DISPLAY_RENDER_MODE_DIRECT, not recommended for X11 driver*/ + #define LV_X11_RENDER_MODE_DIRECT 1 /* LV_DISPLAY_RENDER_MODE_DIRECT, not recommended for X11 driver */ // or - #define LV_X11_RENDER_MODE_DULL 1 /*LV_DISPLAY_RENDER_MODE_FULL, not recommended for X11 driver*/ + #define LV_X11_RENDER_MODE_DULL 1 /* LV_DISPLAY_RENDER_MODE_FULL, not recommended for X11 driver */ Usage ----- diff --git a/docs/integration/driver/display/fbdev.rst b/docs/details/integration/driver/display/fbdev.rst similarity index 100% rename from docs/integration/driver/display/fbdev.rst rename to docs/details/integration/driver/display/fbdev.rst diff --git a/docs/integration/driver/display/gen_mipi.rst b/docs/details/integration/driver/display/gen_mipi.rst similarity index 100% rename from docs/integration/driver/display/gen_mipi.rst rename to docs/details/integration/driver/display/gen_mipi.rst diff --git a/docs/integration/driver/display/ili9341.rst b/docs/details/integration/driver/display/ili9341.rst similarity index 100% rename from docs/integration/driver/display/ili9341.rst rename to docs/details/integration/driver/display/ili9341.rst diff --git a/docs/integration/driver/display/index.rst b/docs/details/integration/driver/display/index.rst similarity index 100% rename from docs/integration/driver/display/index.rst rename to docs/details/integration/driver/display/index.rst diff --git a/docs/integration/driver/display/lcd_stm32_guide.rst b/docs/details/integration/driver/display/lcd_stm32_guide.rst similarity index 97% rename from docs/integration/driver/display/lcd_stm32_guide.rst rename to docs/details/integration/driver/display/lcd_stm32_guide.rst index e79bb22c0..085b7e635 100644 --- a/docs/integration/driver/display/lcd_stm32_guide.rst +++ b/docs/details/integration/driver/display/lcd_stm32_guide.rst @@ -11,9 +11,9 @@ This guide is intended to be a step-by-step instruction of how to configure the .. tip:: ST Micro provide their own TFT-LCD drivers in their X-CUBE-DISPLAY Software Extension Package. While these drivers can be used with LVGL as well, the LVGL LCD drivers do not depend on this package. - + The LVGL LCD drivers are meant as an alternative, simple to use API to implement LCD support for your LVGL-based project on any platform. Moreover, even in the initial release we support more LCD controllers than X-CUBE-DISPLAY currently provides, and we plan to add support for even more LCD controllers in the future. - + Please note however, that – unlike X-CUBE-DISPLAY – the LVGL LCD drivers do not implement the communication part, whether SPI, parallel i8080 bus or other. It is the user's responsibility to implement – and optimize – these on their chosen platform. LVGL will only provide examples for the most popular platforms. By following the steps you will have a fully functional program, which can be used as the foundation of your own LVGL-based project. If you are in a hurry and not interested in the details, you can find the final project `here `__. You will only need to configure LVGL to use the driver corresponding to your hardware (if it is other than the ST7789), and implement the function ``ui_init()`` to create your widgets. @@ -25,7 +25,7 @@ By following the steps you will have a fully functional program, which can be us .. note:: Although the example uses FreeRTOS, this is not a strict requirement with the LVGL LCD display drivers. - + You can find the source code snippets of this guide in the `lv_port_lcd_stm32_template.c `__ example. Hardware configuration @@ -79,30 +79,30 @@ Step-by-step instructions #. Open the Project Manager tab, and select Advanced Settings. On the right hand side there is a Register Callback window. Select SPI and set it to ENABLE. #. We are ready with the hardware configuration. Save the configuration and let STM32Cube generate the source. #. In the project tree clone the LVGL repository into the Middlewares/Third_Party folder (this tutorial uses the release/v9.0 branch of LVGL): - + .. code-block:: dosbatch - + git clone https://github.com/lvgl/lvgl.git -b release/v9.0 - + #. Cloning should create an 'lvgl' subfolder inside the 'Third_Party' folder. From the 'lvgl' folder copy 'lv_conf_template.h' into the 'Middlewares' folder, and rename it to 'lv_conf.h'. Refresh the project tree. #. Open 'lv_conf.h', and in line 15 change ``#if 0`` to ``#if 1``. #. Search for the string ``LV_USE_ST7735``, and enable the appropriate LCD driver by setting its value to 1. This example uses the ST7789 driver: .. code-block:: c - + #define LV_USE_ST7789 1 - + #. Right click the folder 'Middlewares/Third_Party/lvgl/tests', select Resource Configurations/Exclude from Build..., check both Debug and Release, then press OK. #. Right click the project name and select "Properties". In the C/C++ Build/Settings panel select MCU GCC Compiler/Include paths. In the Configuration dropdown select [ All configurations ]. Add the following Include path: .. code-block:: c - + ../Middlewares/Third_Party/lvgl - + #. Open Core/Src/stm32xxx_it.c (the file name depends on the processor variation). Add 'lv_tick.h' to the Private includes section: .. code-block:: c - + /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "./src/tick/lv_tick.h" @@ -146,7 +146,7 @@ Step-by-step instructions #. Add the following lines to the Private variables: .. code-block:: c - + osThreadId LvglTaskHandle; lv_display_t *lcd_disp; volatile int lcd_bus_busy = 0; @@ -251,7 +251,7 @@ Step-by-step instructions #. Add the LVGL_Task() function. Replace the ``lv_st7789_create()`` call with the appropriate driver. You can change the default orientation by adjusting the parameter of ``lv_display_set_rotation()``. You will also need to create the display buffers here. This example uses a double buffering scheme with 1/10th size partial buffers. In most cases this is a good compromise between the required memory size and performance, but you are free to experiment with other settings. .. code-block:: c - + void LVGL_Task(void const *argument) { /* Initialize LVGL */ @@ -310,11 +310,11 @@ Step-by-step instructions /* create label */ obj = lv_label_create(scr); - lv_obj_set_align(obj, LV_ALIGN_CENTER); - lv_obj_set_height(obj, LV_SIZE_CONTENT); - lv_obj_set_width(obj, LV_SIZE_CONTENT); - lv_obj_set_style_text_font(obj, &lv_font_montserrat_14, 0); - lv_obj_set_style_text_color(obj, lv_color_black(), 0); - lv_label_set_text(obj, "Hello World!"); + lv_obj_set_align(widget, LV_ALIGN_CENTER); + lv_obj_set_height(widget, LV_SIZE_CONTENT); + lv_obj_set_width(widget, LV_SIZE_CONTENT); + lv_obj_set_style_text_font(widget, &lv_font_montserrat_14, 0); + lv_obj_set_style_text_color(widget, lv_color_black(), 0); + lv_label_set_text(widget, "Hello World!"); } - \ No newline at end of file + diff --git a/docs/integration/driver/display/renesas_glcdc.rst b/docs/details/integration/driver/display/renesas_glcdc.rst similarity index 100% rename from docs/integration/driver/display/renesas_glcdc.rst rename to docs/details/integration/driver/display/renesas_glcdc.rst diff --git a/docs/integration/driver/display/st7735.rst b/docs/details/integration/driver/display/st7735.rst similarity index 100% rename from docs/integration/driver/display/st7735.rst rename to docs/details/integration/driver/display/st7735.rst diff --git a/docs/integration/driver/display/st7789.rst b/docs/details/integration/driver/display/st7789.rst similarity index 100% rename from docs/integration/driver/display/st7789.rst rename to docs/details/integration/driver/display/st7789.rst diff --git a/docs/integration/driver/display/st7796.rst b/docs/details/integration/driver/display/st7796.rst similarity index 100% rename from docs/integration/driver/display/st7796.rst rename to docs/details/integration/driver/display/st7796.rst diff --git a/docs/integration/driver/display/st_ltdc.rst b/docs/details/integration/driver/display/st_ltdc.rst similarity index 91% rename from docs/integration/driver/display/st_ltdc.rst rename to docs/details/integration/driver/display/st_ltdc.rst index c47c9ed94..a83527ec2 100644 --- a/docs/integration/driver/display/st_ltdc.rst +++ b/docs/details/integration/driver/display/st_ltdc.rst @@ -92,11 +92,11 @@ option. It must not be enabled at the same time as :c:macro:`LV_USE_DRAW_DMA2D`. See the :ref:`DMA2D support `. -Further Reading -*************** -You may be interested in enabling the :ref:`Nema GFX renderer ` -if your STM32 has a GPU which is supported by Nema GFX. +.. admonition:: Further Reading -`lv_port_riverdi_stm32u5 `__ -is a way to quick way to get started with LTDC on LVGL. + You may be interested in enabling the :ref:`Nema GFX renderer ` + if your STM32 has a GPU which is supported by Nema GFX. + + `lv_port_riverdi_stm32u5 `__ + is a way to quick way to get started with LTDC on LVGL. diff --git a/docs/integration/driver/index.rst b/docs/details/integration/driver/index.rst similarity index 91% rename from docs/integration/driver/index.rst rename to docs/details/integration/driver/index.rst index 0dc786176..0a7c508cf 100644 --- a/docs/integration/driver/index.rst +++ b/docs/details/integration/driver/index.rst @@ -1,3 +1,5 @@ +.. _drivers: + ======= Drivers ======= diff --git a/docs/integration/driver/libinput.rst b/docs/details/integration/driver/libinput.rst similarity index 100% rename from docs/integration/driver/libinput.rst rename to docs/details/integration/driver/libinput.rst diff --git a/docs/integration/driver/opengles.rst b/docs/details/integration/driver/opengles.rst similarity index 95% rename from docs/integration/driver/opengles.rst rename to docs/details/integration/driver/opengles.rst index 1d00027c8..cd01b5646 100644 --- a/docs/integration/driver/opengles.rst +++ b/docs/details/integration/driver/opengles.rst @@ -1,3 +1,5 @@ +.. _opengl_es_driver: + =============================== OpenGL ES Display/Inputs Driver =============================== @@ -63,7 +65,7 @@ Basic Usage lv_image_set_src(cursor_obj, &mouse_cursor_icon); lv_indev_set_cursor(mouse, cursor_obj); - /* create objects on the screen */ + /* create Widgets on the screen */ lv_demo_widgets(); while (1) @@ -121,7 +123,7 @@ used to add content to a texture and the driver will draw the texture in the win lv_image_set_src(cursor_obj, &mouse_cursor_icon); lv_indev_set_cursor(main_texture_mouse, cursor_obj); - /* create objects on the screen of the main texture */ + /* create Widgets on the screen of the main texture */ lv_demo_widgets(); /********************** @@ -137,7 +139,7 @@ used to add content to a texture and the driver will draw the texture in the win unsigned int sub_texture_id = lv_opengles_texture_get_texture_id(sub_texture); lv_glfw_texture_t * window_sub_texture = lv_glfw_window_add_texture(window, sub_texture_id, sub_texture_w, sub_texture_h); - /* create objects on the screen of the sub texture */ + /* create Widgets on the screen of the sub texture */ lv_display_set_default(sub_texture); lv_example_keyboard_2(); lv_display_set_default(main_texture); @@ -210,9 +212,13 @@ Known Limitations ~~~~~~~~~~~~~~~~~ - Performance will be the same or slightly worse if the drawn areas are never found in the cache - due to objects with continuously varying colors or shapes. One example is a label whose color + due to Widgets with continuously varying colors or shapes. One example is a label whose color is set to a random value every frame, as in the "Multiple labels" scene of the benchmark demo. - Layers with transparent pixels and an overall layer transparency will not blend correctly. The effect can be observed in the "Containers with opa_layer" scene of the benchmark demo in the border corners. - Layers with rotation are not currently supported. Images with rotation are fine. + + +.. Comment: The above blank line is necessary for Sphinx to not complain, + since it looks for the blank line after a bullet list. diff --git a/docs/integration/driver/touchpad/evdev.rst b/docs/details/integration/driver/touchpad/evdev.rst similarity index 100% rename from docs/integration/driver/touchpad/evdev.rst rename to docs/details/integration/driver/touchpad/evdev.rst diff --git a/docs/integration/driver/touchpad/ft6x36.rst b/docs/details/integration/driver/touchpad/ft6x36.rst similarity index 100% rename from docs/integration/driver/touchpad/ft6x36.rst rename to docs/details/integration/driver/touchpad/ft6x36.rst diff --git a/docs/integration/driver/touchpad/index.rst b/docs/details/integration/driver/touchpad/index.rst similarity index 100% rename from docs/integration/driver/touchpad/index.rst rename to docs/details/integration/driver/touchpad/index.rst diff --git a/docs/integration/driver/wayland.rst b/docs/details/integration/driver/wayland.rst similarity index 99% rename from docs/integration/driver/wayland.rst rename to docs/details/integration/driver/wayland.rst index f9860f0f7..115ffd2de 100644 --- a/docs/integration/driver/wayland.rst +++ b/docs/details/integration/driver/wayland.rst @@ -1,3 +1,5 @@ +.. _wayland_driver: + ============================= Wayland Display/Inputs driver ============================= diff --git a/docs/integration/driver/windows.rst b/docs/details/integration/driver/windows.rst similarity index 100% rename from docs/integration/driver/windows.rst rename to docs/details/integration/driver/windows.rst diff --git a/docs/integration/framework/arduino.rst b/docs/details/integration/framework/arduino.rst similarity index 94% rename from docs/integration/framework/arduino.rst rename to docs/details/integration/framework/arduino.rst index 5882d4f29..dfd86f3dc 100644 --- a/docs/integration/framework/arduino.rst +++ b/docs/details/integration/framework/arduino.rst @@ -5,7 +5,7 @@ Arduino The `LVGL library `__ is directly available as Arduino libraries. Note that you need to choose a board powerful enough to run LVGL and -your GUI. See the `requirements of LVGL `__. +your GUI. See the :ref:`requirements of LVGL `. For example ESP32 is a good candidate to create UI's with LVGL. @@ -87,8 +87,8 @@ section ``log settings``: .. code-block:: c - /*Log settings*/ - #define USE_LV_LOG 1 /*Enable/disable the log module*/ + /* Log settings */ + #define USE_LV_LOG 1 /* Enable/disable the log module */ #if LV_USE_LOG /* How important log should be added: * LV_LOG_LEVEL_TRACE A lot of logs to give detailed information diff --git a/docs/integration/framework/index.rst b/docs/details/integration/framework/index.rst similarity index 100% rename from docs/integration/framework/index.rst rename to docs/details/integration/framework/index.rst diff --git a/docs/integration/framework/platformio.rst b/docs/details/integration/framework/platformio.rst similarity index 100% rename from docs/integration/framework/platformio.rst rename to docs/details/integration/framework/platformio.rst diff --git a/docs/integration/framework/tasmota-berry.rst b/docs/details/integration/framework/tasmota-berry.rst similarity index 99% rename from docs/integration/framework/tasmota-berry.rst rename to docs/details/integration/framework/tasmota-berry.rst index d8b738ddf..2c8943f3b 100644 --- a/docs/integration/framework/tasmota-berry.rst +++ b/docs/details/integration/framework/tasmota-berry.rst @@ -62,7 +62,7 @@ Tasmota + Berry + 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 +- Modelling the GUI in a more abstract way by defining reusable composite Widgets, taking advantage of Berry's language features such as Inheritance, Closures, Exception Handling… - Make LVGL accessible to a larger audience. No need to know C to create a nice GUI on an embedded system. diff --git a/docs/integration/ide/index.rst b/docs/details/integration/ide/index.rst similarity index 100% rename from docs/integration/ide/index.rst rename to docs/details/integration/ide/index.rst diff --git a/docs/integration/ide/mdk.rst b/docs/details/integration/ide/mdk.rst similarity index 100% rename from docs/integration/ide/mdk.rst rename to docs/details/integration/ide/mdk.rst diff --git a/docs/integration/ide/pc-simulator.rst b/docs/details/integration/ide/pc-simulator.rst similarity index 93% rename from docs/integration/ide/pc-simulator.rst rename to docs/details/integration/ide/pc-simulator.rst index afe5664ef..84dac264e 100644 --- a/docs/integration/ide/pc-simulator.rst +++ b/docs/details/integration/ide/pc-simulator.rst @@ -25,11 +25,11 @@ Select an IDE The simulator is ported to various IDEs (Integrated Development Environments). Choose your favorite IDE, read its README on GitHub, download the project, and load it to the IDE. -- `Eclipse with SDL driver `__: Recommended on Linux and Mac, supports CMake too +- `Eclipse with SDL driver `__: Recommended on Linux and Mac, supports CMake as well - `VisualStudio `__: Recommended on Windows - `VSCode with SDL driver `__: Recommended on Linux (SDL) and Mac (SDL) - `CodeBlocks `__: Recommended on Windows -- `PlatformIO with SDL driver `__: Recommended on Linux and Mac but has an STM32 environment too +- `PlatformIO with SDL driver `__: Recommended on Linux and Mac but has an STM32 environment as well - `Generic Linux `__: CMake based project where you can easily switch between fbdev, DRM, and SDL. - `MDK with FastModel `__: For Windows @@ -40,7 +40,7 @@ External project not maintained by the LVGL organization: Built-in drivers ---------------- -LVGL comes with several `built-in drivers `__. +LVGL comes with several :ref:`built-in drivers `. Even if a simulator project comes with e.g. SDL, you can easily replace it by enabling another driver in ``lv_conf.h`` and calling its ``create`` function. diff --git a/docs/integration/index.rst b/docs/details/integration/index.rst similarity index 83% rename from docs/integration/index.rst rename to docs/details/integration/index.rst index c22b311ce..d11c90c7e 100644 --- a/docs/integration/index.rst +++ b/docs/details/integration/index.rst @@ -1,3 +1,5 @@ +.. _integration_index: + ======================= Integration and Drivers ======================= @@ -9,6 +11,7 @@ Integration and Drivers building/index chip/index driver/index + renderers/index framework/index ide/index os/index diff --git a/docs/integration/os/freertos.rst b/docs/details/integration/os/freertos.rst similarity index 100% rename from docs/integration/os/freertos.rst rename to docs/details/integration/os/freertos.rst diff --git a/docs/integration/os/index.rst b/docs/details/integration/os/index.rst similarity index 100% rename from docs/integration/os/index.rst rename to docs/details/integration/os/index.rst diff --git a/docs/integration/os/mqx.rst b/docs/details/integration/os/mqx.rst similarity index 95% rename from docs/integration/os/mqx.rst rename to docs/details/integration/os/mqx.rst index 906bb08e6..140aa5d31 100644 --- a/docs/integration/os/mqx.rst +++ b/docs/details/integration/os/mqx.rst @@ -1,3 +1,5 @@ +.. _mqx: + ======== MQX RTOS ======== diff --git a/docs/integration/os/nuttx.rst b/docs/details/integration/os/nuttx.rst similarity index 97% rename from docs/integration/os/nuttx.rst rename to docs/details/integration/os/nuttx.rst index 2e3c65371..7298642b5 100644 --- a/docs/integration/os/nuttx.rst +++ b/docs/details/integration/os/nuttx.rst @@ -152,3 +152,7 @@ Where can I find more information? LPCXpresso54628 `__ - NuttX mailing list: `Apache NuttX Mailing List `__ + + +.. Comment: The above blank line is necessary for Sphinx to not complain, + since it looks for the blank line after a bullet list. diff --git a/docs/integration/os/px5.rst b/docs/details/integration/os/px5.rst similarity index 100% rename from docs/integration/os/px5.rst rename to docs/details/integration/os/px5.rst diff --git a/docs/integration/os/qnx.rst b/docs/details/integration/os/qnx.rst similarity index 96% rename from docs/integration/os/qnx.rst rename to docs/details/integration/os/qnx.rst index 2bb34abf7..5df7a5c04 100644 --- a/docs/integration/os/qnx.rst +++ b/docs/details/integration/os/qnx.rst @@ -1,9 +1,11 @@ +.. _qnx: + === QNX === What is QNX? ------------- +************ QNX is a commercial operating system first released in 1980. The operating system is based on a micro-kernel design, with the file system(s), network @@ -13,7 +15,7 @@ address space. See www.qnx.com for more details. Highlight of QNX -~~~~~~~~~~~~~~~~ +---------------- - 64-bit only, runs on x86_64 and ARMv8 - Requires an MMU as the design mandates separation among processes @@ -24,14 +26,14 @@ Highlight of QNX - Safety certification to various automotive, industrial and medical standards How to run LVGL on QNX? ------------------------ +*********************** There are two ways to use LVGL in your QNX project. The first is similar to how LVGL is used on other systems. The second is to build LVGL as either a shared or a static library. Include LVGL in Your Project -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------- Follow the generic instructions for getting started with LVGL. After copying `lv_conf_template.h` to `lv_conf.h` make the following changes to the latter: @@ -55,7 +57,7 @@ Follow the generic instructions for getting started with LVGL. After copying #define LV_QNX_BUF_COUNT 2 Build LVGL as a Library -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- **Note that this method is an alternative to including LVGL in your project. If you choose to build a library then you do not need to follow the instructions in @@ -88,7 +90,7 @@ Before building the library, you may wish to edit double-buffering. Writing a LVGL Application -~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------- To create a LVGL application for QNX, follow these steps in your code: @@ -134,7 +136,7 @@ The following code shows how to create a "Hello World" application: } Build the Application -~~~~~~~~~~~~~~~~~~~~~ +--------------------- Building the application consists of compiling the source with the LVGL headers, and then linking against the library. This can be done in many ways, using diff --git a/docs/integration/os/rt-thread.rst b/docs/details/integration/os/rt-thread.rst similarity index 100% rename from docs/integration/os/rt-thread.rst rename to docs/details/integration/os/rt-thread.rst diff --git a/docs/integration/os/yocto/core_components.rst b/docs/details/integration/os/yocto/core_components.rst similarity index 93% rename from docs/integration/os/yocto/core_components.rst rename to docs/details/integration/os/yocto/core_components.rst index ec99b24ea..855d3767a 100644 --- a/docs/integration/os/yocto/core_components.rst +++ b/docs/details/integration/os/yocto/core_components.rst @@ -1,8 +1,11 @@ -Yocto Project Core Components -############################# +.. _yocto_project_core_components: -The BitBake task executor together with various types of configuration files -form the OpenEmbedded-Core (OE-Core). This section overviews these components +============================= +Yocto Project Core Components +============================= + +The BitBake task executor together with various types of configuration files +form the OpenEmbedded-Core (OE-Core). This section overviews these components by describing their use and how they interact. BitBake handles the parsing and execution of the data files. The data @@ -18,20 +21,20 @@ itself is of various types: everything together. BitBake knows how to combine multiple data sources together and refers -to each data source as a layer. +to each data source as a layer. -Here are some brief details on these core components. +Here are some brief details on these core components. .. _bitbake_section: BitBake ******* -BitBake is the tool at the heart of the OpenEmbedded Build System and is -responsible for parsing the Metadata, generating a list of tasks from it, and +BitBake is the tool at the heart of the OpenEmbedded Build System and is +responsible for parsing the Metadata, generating a list of tasks from it, and then executing those tasks. -This section briefly introduces BitBake. If you want more information on +This section briefly introduces BitBake. If you want more information on BitBake, see the `BitBake User Manual `_. @@ -54,7 +57,7 @@ Several different versions of ``matchbox-desktop`` might exist. BitBake chooses the one selected by the distribution configuration. You can get more details about how BitBake chooses between different target versions and providers in the "`Preferences `_" section of the BitBake User +bitbake-user-manual-execution.html#preferences>`_" section of the BitBake User Manual. BitBake also tries to execute any dependent tasks first. So for example, @@ -133,14 +136,14 @@ several pieces of hardware. There are many layers working in the Yocto Project development environment. The `Yocto Project Compatible Layer Index `_ and `OpenEmbedded Layer Index `_ both contain layers +layers.openembedded.org/layerindex/branch/master/layers/>`_ both contain layers from which you can use or leverage. -By convention, layers in the Yocto Project follow a specific form. Conforming -to a known structure allows BitBake to make assumptions during builds on where -to find types of metadata. You can find procedures and learn about tools (i.e. -``bitbake-layers``) for creating layers suitable for the Yocto Project in the +By convention, layers in the Yocto Project follow a specific form. Conforming +to a known structure allows BitBake to make assumptions during builds on where +to find types of metadata. You can find procedures and learn about tools (i.e. +``bitbake-layers``) for creating layers suitable for the Yocto Project in the "`understanding and creating layers `_" section of the -Yocto Project Development Tasks Manual. \ No newline at end of file +layers.html#understanding-and-creating-layers>`_" section of the +Yocto Project Development Tasks Manual. diff --git a/docs/integration/os/yocto/index.rst b/docs/details/integration/os/yocto/index.rst similarity index 87% rename from docs/integration/os/yocto/index.rst rename to docs/details/integration/os/yocto/index.rst index f8bd75839..f8cdf51e7 100644 --- a/docs/integration/os/yocto/index.rst +++ b/docs/details/integration/os/yocto/index.rst @@ -1,16 +1,19 @@ -Yocto -##### +.. _yocto: -The Yocto Project (YP) is an open source collaboration project that helps -developers create custom Linux-based systems regardless of the hardware +===== +Yocto +===== + +The Yocto Project (YP) is an open source collaboration project that helps +developers create custom Linux-based systems regardless of the hardware architecture. -The project provides a flexible set of tools and a space where embedded -developers worldwide can share technologies, software stacks, configurations, -and best practices that can be used to create tailored Linux images for +The project provides a flexible set of tools and a space where embedded +developers worldwide can share technologies, software stacks, configurations, +and best practices that can be used to create tailored Linux images for embedded and IOT devices, or anywhere a customized Linux OS is needed. -This section objective is to ease to process of understanding the basic +This section objective is to ease to process of understanding the basic concepts of Yocto and to help beginners to start with Yocto. @@ -21,5 +24,5 @@ concepts of Yocto and to help beginners to start with Yocto. core_components lvgl_recipe terms_and_variables - - \ No newline at end of file + + diff --git a/docs/integration/os/yocto/lvgl_recipe.rst b/docs/details/integration/os/yocto/lvgl_recipe.rst similarity index 88% rename from docs/integration/os/yocto/lvgl_recipe.rst rename to docs/details/integration/os/yocto/lvgl_recipe.rst index c5519629c..ebb1f4a6c 100644 --- a/docs/integration/os/yocto/lvgl_recipe.rst +++ b/docs/details/integration/os/yocto/lvgl_recipe.rst @@ -1,27 +1,30 @@ -LVGL in Yocto -############# +.. _yocto_lvgl_recipe: -This chapter serves as a guide to help you create a recipe for an application -using LVGL. While the process will be demonstrated for the Raspberry Pi 3 +============= +LVGL in Yocto +============= + +This chapter serves as a guide to help you create a recipe for an application +using LVGL. While the process will be demonstrated for the Raspberry Pi 3 (64-bit), it can be applied to any board in a similar way. -Build Host Packages +Build Host Packages ******************* -You must install essential host packages on your build host. The following +You must install essential host packages on your build host. The following command installs the host packages based on an Ubuntu distribution .. code-block:: sudo apt install gawk wget git diffstat unzip texinfo gcc build-essential \ chrpath socat cpio python3 python3-pip python3-pexpect xz-utils \ - debianutils iputils-ping python3-git python3-jinja2 python3-subunit zstd \ + debianutils iputils-ping python3-git python3-jinja2 python3-subunit zstd \ liblz4-tool file locales libacl1 .. note:: - For host package requirements on all supported Linux distributions, see the + For host package requirements on all supported Linux distributions, see the `Required Packages for the Build Host `_ + ref-manual/system-requirements.html#required-packages-for-the-build-host>`_ section in the Yocto Project Reference Manual. @@ -35,7 +38,7 @@ After this section the folder tree will be like this lvgl_yocto_guide/ ├── build/ │ ├── cache/ - │ ├── conf/ + │ ├── conf/ │ ├── downloads/ │ └── ... └── sources/ @@ -53,32 +56,32 @@ Clone Poky, meta-openembedded and meta-raspberrypi in the sources .. code-block:: - cd lvgl_yocto_guide/sources + cd lvgl_yocto_guide/sources git clone --branch scarthgap https://git.yoctoproject.org/poky.git - git clone --branch scarthgap https://git.openembedded.org/meta-openembedded + git clone --branch scarthgap https://git.openembedded.org/meta-openembedded git clone --branch scarthgap git://git.yoctoproject.org/meta-raspberrypi Build a base image ****************** -To understand better what is going on, let's build the image like it is +To understand better what is going on, let's build the image like it is prepared for us .. code-block:: none - cd ../ # go back to the root folder - source sources/poky/oe-init-build-env + cd ../ # go back to the root folder + source sources/poky/oe-init-build-env -Now you should have a folder named ``build`` next to ``sources``. The last -command -also sets the current directory to the build directory. +Now you should have a folder named ``build`` next to ``sources``. The last +command +also sets the current directory to the build directory. In the build directory, there is a ``conf`` folder with some files in it .. code-block:: none └── build/ - └── conf/ + └── conf/ ├── bblayers.conf ├── conf-notes.txt ├── conf-summary.txt @@ -87,11 +90,11 @@ In the build directory, there is a ``conf`` folder with some files in it The important files for us are ``local.conf`` and ``bblayers.conf`` -To add layers to the project there are 2 options: +To add layers to the project there are 2 options: **Bitbake commands (Option 1)** -You need to be in the same terminal you did the ``source`` command. Add the +You need to be in the same terminal you did the ``source`` command. Add the layers with the Bitbake command like this .. code-block:: @@ -104,7 +107,7 @@ layers with the Bitbake command like this Open ``conf/bblayers.conf`` file and add manually the paths: .. code-block:: bash - + # POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf # changes incompatibly POKY_BBLAYERS_CONF_VERSION = "2" @@ -123,12 +126,12 @@ Open ``conf/bblayers.conf`` file and add manually the paths: ${TOPDIR}/../sources/meta-openembedded/meta-python \ " -To ensure the layers were added as expected, run the Bitbake command to show +To ensure the layers were added as expected, run the Bitbake command to show all the layers:: bitbake-layers show-layers -The following layers should be listed: +The following layers should be listed: - core - yocto - yoctobsp @@ -147,14 +150,14 @@ The available machine configurations for Raspberrypi can be listed like this ls ../sources/meta-raspberrypi/conf/machine/*.conf -To build an image for Raspberrypi3 64 bits, modify the file ``local.conf`` file +To build an image for Raspberrypi3 64 bits, modify the file ``local.conf`` file replacing the ``MACHINE ??=`` default value like this .. code-block:: bash MACHINE ??= "raspberrypi3-64" -To build the image we will target, it is also needed to add this to the file: +To build the image we will target, it is also needed to add this to the file: .. code-block:: bash @@ -162,105 +165,105 @@ To build the image we will target, it is also needed to add this to the file: .. note:: - You can find more information about this variable `here `_. + You can find more information about this variable `here `_. Everything is setup, time to build the image:: bitbake core-image-base -Overview of the build +Overview of the build ===================== Let's go through the build folders to understand what happened. -Downloads +Downloads --------- The folder location can be changed with the ``DL_DIR`` variable. -The Downloads folder is a fundamental part of the Yocto build environment, -serving as a local cache for all external sources and dependencies. This -caching mechanism is essential for efficient builds, ensuring that repeated +The Downloads folder is a fundamental part of the Yocto build environment, +serving as a local cache for all external sources and dependencies. This +caching mechanism is essential for efficient builds, ensuring that repeated builds do not waste time downloading the same files again. -tmp/deploy +tmp/deploy ---------- -This folder contains the final output artifacts that are ready for deployment. -These artifacts include kernel images, root filesystems, packages, SDKs, -bootloader files, and other components that are generated during the Yocto +This folder contains the final output artifacts that are ready for deployment. +These artifacts include kernel images, root filesystems, packages, SDKs, +bootloader files, and other components that are generated during the Yocto build process. -There are some key folders: - - **images**: it contains the images that can be flashed or deployed to +There are some key folders: + - **images**: it contains the images that can be flashed or deployed to the target device. Files like the Linux kernel, root filesystem (e.g., . - ext4, .tar.gz, .squashfs), bootloaders (e.g., U-Boot), and other - bootable images for the device are found here. t’s organized by the + ext4, .tar.gz, .squashfs), bootloaders (e.g., U-Boot), and other + bootable images for the device are found here. t’s organized by the machine (or target board) for which the image was built. - - **rmp/deb/ipk**: These folders contain the individual software packages - generated during the build, in the specified package format (RPM, DEB, - or IPK). These packages are typically created when you’re building your - Yocto project with package management support enabled. These can later + - **rmp/deb/ipk**: These folders contain the individual software packages + generated during the build, in the specified package format (RPM, DEB, + or IPK). These packages are typically created when you’re building your + Yocto project with package management support enabled. These can later be installed on the target device using package management tools - - **sdk**: This subdirectory contains Software Development Kits (SDKs) - that you can use to cross-compile applications for your target system. - The SDKs are generated when you use the ``bitbake -c populate_sdk`` + - **sdk**: This subdirectory contains Software Development Kits (SDKs) + that you can use to cross-compile applications for your target system. + The SDKs are generated when you use the ``bitbake -c populate_sdk`` command. tmp/sysroots-components ----------------------- -This folder is a modular approach introduced in Yocto to handle sysroots. It -divides the sysroot into individual components, which can be thought of as the +This folder is a modular approach introduced in Yocto to handle sysroots. It +divides the sysroot into individual components, which can be thought of as the building blocks or packages that make up the entire sysroot environment. -Each component corresponds to a specific package or dependency that is staged -into the sysroot. This approach allows for more efficient reuse of sysroots -across multiple packages or builds, and it helps with dependency tracking and +Each component corresponds to a specific package or dependency that is staged +into the sysroot. This approach allows for more efficient reuse of sysroots +across multiple packages or builds, and it helps with dependency tracking and management during the build process. -The sysroot-components directory helps optimize the build process because if -one package changes, Yocto only needs to update the corresponding component +The sysroot-components directory helps optimize the build process because if +one package changes, Yocto only needs to update the corresponding component rather than rebuilding or copying the entire sysroot. -If you followed the previous steps, here are the folders you will find: +If you followed the previous steps, here are the folders you will find: - ``all``: Architecture-independent files. - ``cortexa53``: Files for the Cortex-A53 (ARMv8-A) architecture. - ``manifests``: Track files installed in the sysroot by package. - ``raspberrypi3_64``: Files specific to the Raspberry Pi 3 (64-bit). - - ``x86_64``: Files for the x86_64 (PC) architecture, typically for + - ``x86_64``: Files for the x86_64 (PC) architecture, typically for cross-compilation tools. - - ``x86_64-nativesdk``: Files related to the SDK for cross-compilation on + - ``x86_64-nativesdk``: Files related to the SDK for cross-compilation on an x86_64 host. -Each folder corresponds to components relevant to the specific architecture, -and they collectively form the complete environment needed to compile and run +Each folder corresponds to components relevant to the specific architecture, +and they collectively form the complete environment needed to compile and run software for the target and host systems. tmp/sysroots-uninative ---------------------- -The sysroots-uninative directory in Yocto is used to support the "uninative" -feature, which allows for more reproducible builds by ensuring that the build -environment remains consistent across different host systems. It essentially -provides a way to use the same native build tools across different Linux +The sysroots-uninative directory in Yocto is used to support the "uninative" +feature, which allows for more reproducible builds by ensuring that the build +environment remains consistent across different host systems. It essentially +provides a way to use the same native build tools across different Linux distributions. tmp/work -------- -The ``work`` folder in Yocto is a key directory in the ``tmp`` folder that -holds all the temporary build artifacts for each package during the build -process. It is where the actual building and compiling of individual packages -or recipes takes place. Each package (or "recipe") that BitBake processes +The ``work`` folder in Yocto is a key directory in the ``tmp`` folder that +holds all the temporary build artifacts for each package during the build +process. It is where the actual building and compiling of individual packages +or recipes takes place. Each package (or "recipe") that BitBake processes generates temporary files and directories inside this ``work`` folder. -The ``work`` folder is typically structured by machine architecture and +The ``work`` folder is typically structured by machine architecture and package. Here's how it generally works: -.. code-block:: none +.. code-block:: none work/ └── / @@ -271,8 +274,8 @@ package. Here's how it generally works: ├── sysroot-destdir/ └── image/ -This folder is very important and helps a lot during debug phases. The ``temp`` -subfolder contains important logs that can help you diagnose build issues. This +This folder is very important and helps a lot during debug phases. The ``temp`` +subfolder contains important logs that can help you diagnose build issues. This is where you'll look when a build fails to figure out what went wrong. @@ -284,37 +287,37 @@ Find more information about recipes in :ref:`recipes_section` section. There is a recipe in ``meta-openembedded`` since ``honister``. .. list-table:: lvgl recipe version - :widths: 200 100 + :widths: 200 100 :header-rows: 1 * - Branch - Recipe * - scarthgap (Yocto Project 5.0) - lvgl 9.1.0 - * - nanbield (Yocto Project 4.3) + * - nanbield (Yocto Project 4.3) - lvgl 8.3.10 - * - mickledore (Yocto Project 4.2) - - lvgl 8.1.0 - * - langdale (Yocto Project 4.1) + * - mickledore (Yocto Project 4.2) - lvgl 8.1.0 * - langdale (Yocto Project 4.1) - lvgl 8.1.0 - * - kirkstone (Yocto Project 4.0) + * - langdale (Yocto Project 4.1) + - lvgl 8.1.0 + * - kirkstone (Yocto Project 4.0) - lvgl 8.0.3 In this guide, we are on the ``scarthgap`` branch, so we are using lvgl 9.1.0. -Let's dive into this recipe to understand what is done. The objective is to add -this library as a shared object in the target rootfs, and also to generate a +Let's dive into this recipe to understand what is done. The objective is to add +this library as a shared object in the target rootfs, and also to generate a SDK with lvgl. This is the path of lvgl recipes: ``lvgl_yocto_guide/sources/meta-openembedded/ meta-oe/recipes-graphics/lvgl`` -Here is the architecture of lvgl recipes folder: +Here is the architecture of lvgl recipes folder: .. code-block:: bash - + lvgl ├── files │ ├── 0002-fix-sdl-handle-both-LV_IMAGE_SRC_FILE-and-LV_IMAGE_S.patch @@ -328,9 +331,9 @@ Here is the architecture of lvgl recipes folder: ├── lvgl_9.1.0.bb └── lvgl-demo-fb_9.1.0.bb -- ``file`` folder contains all the patches that can be applied when +- ``file`` folder contains all the patches that can be applied when building the recipe. -- ``lv_conf.inc`` is an include file, usually containing common configuration +- ``lv_conf.inc`` is an include file, usually containing common configuration settings for LVGL that can be shared between multiple recipes. - ``lvgl_9.1.0.bb`` is the recipe to build lvgl library. - ``lvgl-demo-fb_9.1.0.bb`` is a recipe to build an application using lvgl. @@ -373,48 +376,48 @@ For now let's understand the recipe of lvgl library. ${includedir}/${PN}/ \ " -**LICENSE**: Indicates the licensing of the software, stating that it is +**LICENSE**: Indicates the licensing of the software, stating that it is distributed under the MIT License. -**LIC_FILES_CHKSUM**: This variable contains a checksum (in this case, an MD5 hash) -for the license file (here assumed to be LICENCE.txt). This helps to ensure the -integrity of the license file included in the package. In LVGL repository, -there is a LICENSE.txt. To get the value of the hash of the file, you can do +**LIC_FILES_CHKSUM**: This variable contains a checksum (in this case, an MD5 hash) +for the license file (here assumed to be LICENCE.txt). This helps to ensure the +integrity of the license file included in the package. In LVGL repository, +there is a LICENSE.txt. To get the value of the hash of the file, you can do this command: ``md5sum LICENSE.txt`` SRC_URI: Specifies the locations of the source code and patches for the recipe: - The main source repository for LVGL specifying the master branch. - - The following arguments are the local patch files that will be applied to - the source code during the build process. + - The following arguments are the local patch files that will be applied to + the source code during the build process. -**SRCREV**: Defines the specific commit (in this case, a Git SHA hash) from -which the source code will be fetched. This ensures that the build uses a +**SRCREV**: Defines the specific commit (in this case, a Git SHA hash) from +which the source code will be fetched. This ensures that the build uses a consistent version of the code. -**inherit**: This line indicates that the recipe uses the ``cmake`` class, -which provides functionality for building projects that use CMake as +**inherit**: This line indicates that the recipe uses the ``cmake`` class, +which provides functionality for building projects that use CMake as their build system. -**EXTRA_OECMAKE**: Additional options passed to CMake during the +**EXTRA_OECMAKE**: Additional options passed to CMake during the configuration step. -**S**: This variable defines the source directory where the unpacked source -code will be located after fetching. ``${WORKDIR}`` is a standard +**S**: This variable defines the source directory where the unpacked source +code will be located after fetching. ``${WORKDIR}`` is a standard variable in BitBake that points to the working directory for the recipe. -require: This line includes another configuration file, ``lv-conf.inc``, -which likely contains additional configuration options or variables +require: This line includes another configuration file, ``lv-conf.inc``, +which likely contains additional configuration options or variables specific to the LVGL library. -**FILES**: This is a BitBake variable used to specify the files that should -be included in a particular package. In this case, the variable is -specifying files for a package related to development (i.e., header +**FILES**: This is a BitBake variable used to specify the files that should +be included in a particular package. In this case, the variable is +specifying files for a package related to development (i.e., header files). Recipe Tasks ************ -When a recipe is compiled, it will run multiple tasks. You can run each task -manually to understand what is generated each step, or you can run ``bitbake +When a recipe is compiled, it will run multiple tasks. You can run each task +manually to understand what is generated each step, or you can run ``bitbake lvgl`` to run all the tasks. Fetch (do_fetch) @@ -424,17 +427,17 @@ Fetch (do_fetch) Fetch task fetches the package source from the local or remote repository. - The fetch Repo address has to be stored in **SRC_URI** variable. In + The fetch Repo address has to be stored in **SRC_URI** variable. In **SRCREV** Variable the commit hash of github repo is defined. - When the fetch task has been completed, you can find the fetched sources in + When the fetch task has been completed, you can find the fetched sources in ``build/downloads``. For this recipe, you will find a new folder here: ``lvgl_yocto_guide build/downloads/git2/github.com.lvgl.lvgl``. You can also find the folder architecture created in ``lvgl_yocto_guide/ - build/tmp/work/cortexa53-poky-linux/lvgl`` but these folders are empty since + build/tmp/work/cortexa53-poky-linux/lvgl`` but these folders are empty since only the fetch was done. @@ -443,28 +446,28 @@ Fetch (do_fetch) Unpack (do_upack) .. code-block:: bash - bitbake lvgl -c unpack - + bitbake lvgl -c unpack + Unpack task unpacks the package that has been downloaded with Fetch task. - In the ``lvgl_yocto_guide/build/tmp/work/cortexa53-poky-linux/lvgl/9.1.0`` - folder, you can now find the source code in ``git`` (as it was defined in - the recipe). You will also see the patches that will be applied on the next - step. So for now, the sources are unmodified and the same than the commit + In the ``lvgl_yocto_guide/build/tmp/work/cortexa53-poky-linux/lvgl/9.1.0`` + folder, you can now find the source code in ``git`` (as it was defined in + the recipe). You will also see the patches that will be applied on the next + step. So for now, the sources are unmodified and the same than the commit that was specified. - + Patch (do_patch) .. code-block:: bash bitbake lvgl -c patch - Patch task locates the patch files and applies the patches to the sources - if any patch is available. This is optional task, executes if patch is + Patch task locates the patch files and applies the patches to the sources + if any patch is available. This is optional task, executes if patch is available. - Patch file is also defined in **SRC_URI** variable. By default it runs in + Patch file is also defined in **SRC_URI** variable. By default it runs in current source directory **${S}**. Configure (do_configure) @@ -472,21 +475,21 @@ Configure (do_configure) bitbake lvgl -c configure - The Configuration task configures the source by enabling and disabling any - build-time and configuration options for the software being built before + The Configuration task configures the source by enabling and disabling any + build-time and configuration options for the software being built before compilation if any configuration is available. This is a optional steps, executes if configuration is available. - In this case, it creates a build directory, It invokes CMake to configure - the project, specifying build options and paths based on variables in your + In this case, it creates a build directory, It invokes CMake to configure + the project, specifying build options and paths based on variables in your recipe. It generates Makefiles or project files needed for the build. Also, - there are operations added in the task in ``lv-conf.inc``. + there are operations added in the task in ``lv-conf.inc``. So at the end of the task, in the ``lvgl_yocto_guide/build/tmp/work/ - cortexa53-poky-linux/lvgl/9.1.0``, you will find a ``build`` folder that was - generated running the CMake command, but nothing is built yet. Also, the - sysroots have everything required to build lvgl library. + cortexa53-poky-linux/lvgl/9.1.0``, you will find a ``build`` folder that was + generated running the CMake command, but nothing is built yet. Also, the + sysroots have everything required to build lvgl library. Compile (do_compile) @@ -494,17 +497,17 @@ Compile (do_compile) bitbake lvgl -c compile - The Compilation task compiles the source code if any compilation steps are + The Compilation task compiles the source code if any compilation steps are available and generates a binary file. - + This is a optional steps, executes if compilation is available. - - If there are any compilation steps, then these steps are define in + + If there are any compilation steps, then these steps are define in do_compile() funtion of bitbake. - Like in the previous task, this is handle by ``inherit cmake``. + Like in the previous task, this is handle by ``inherit cmake``. - In the build folder, you can now see the built library. The ``.so`` files + In the build folder, you can now see the built library. The ``.so`` files are available in ``lvgl_yocto_guide/build/tmp/work/ cortexa53-poky-linux/lvgl/9.1.0/build/lib``. After this task has been completed, everything is ready to be installed. @@ -514,22 +517,22 @@ Install (do_install) bitbake lvgl -c install - The Install task copies files that are to be packaged into the holding area - **${D}**. This task runs with the current working directory **${S}** which + The Install task copies files that are to be packaged into the holding area + **${D}**. This task runs with the current working directory **${S}** which is the compilation directory. - It creates the necessary directory for the header files in the destination + It creates the necessary directory for the header files in the destination installation directory. - It installs the ``lv_conf.h`` header file from the source directory into the - appropriate include directory in the destination path, ensuring it has the + It installs the ``lv_conf.h`` header file from the source directory into the + appropriate include directory in the destination path, ensuring it has the correct permissions. - The lvgl library (``.so`` files) are also ready to be installed in the final - image. A new folder ``image`` was created. + The lvgl library (``.so`` files) are also ready to be installed in the final + image. A new folder ``image`` was created. .. important:: - In the file ``build/conf/local.conf``, add these 2 lines at the end of the + In the file ``build/conf/local.conf``, add these 2 lines at the end of the file: .. code-block:: bash @@ -537,41 +540,41 @@ Install (do_install) IMAGE_INSTALL:append = " lvgl" TOOLCHAIN_HOST_TASK:append = " lvgl" - This will add the lvgl library in the generated image, and it will also add + This will add the lvgl library in the generated image, and it will also add the library to the host SDK we will generate later on. - With these modifications, you can now run the image recipe again:: + With these modifications, you can now run the image recipe again:: bitbake core-image-base This will execute all the previous described tasks. If everything went well, you should now found this file ``build/tmp/deploy/ - rpm/cortexa53/lvgl-9.1.0-r0.cortexa53.rpm`` and other rpm files related to + rpm/cortexa53/lvgl-9.1.0-r0.cortexa53.rpm`` and other rpm files related to lvgl. SDK generation ************** -Generating a Software Development Kit (SDK) in Yocto serves several important -purposes, particularly in embedded development: +Generating a Software Development Kit (SDK) in Yocto serves several important +purposes, particularly in embedded development: - - **Development Environment**: The SDK provides developers with a - ready-to-use development environment tailored for a specific target - hardware platform. - This includes the necessary tools, libraries, and headers to build + - **Development Environment**: The SDK provides developers with a + ready-to-use development environment tailored for a specific target + hardware platform. + This includes the necessary tools, libraries, and headers to build applications that run on the target device. - - **Cross-Compilation**: The SDK allows developers to cross-compile - applications from a host machine (typically x86 or x86_64 architecture) - for a different architecture (e.g., ARM). This is essential for embedded + - **Cross-Compilation**: The SDK allows developers to cross-compile + applications from a host machine (typically x86 or x86_64 architecture) + for a different architecture (e.g., ARM). This is essential for embedded systems, where development often occurs on more powerful machines. - - **Simplified Development**: By packaging all required components, the SDK - simplifies the process of setting up a development environment. - Developers don't need to manually install and configure tools and + - **Simplified Development**: By packaging all required components, the SDK + simplifies the process of setting up a development environment. + Developers don't need to manually install and configure tools and libraries; everything needed is included in the SDK. - - **Consistent Build Environment**: The SDK ensures that developers are - working with the same versions of and tools used in the Yocto - build, which helps to avoid compatibility issues and ensures that + - **Consistent Build Environment**: The SDK ensures that developers are + working with the same versions of and tools used in the Yocto + build, which helps to avoid compatibility issues and ensures that applications will behave as expected on the target device. To generate an SDK of the environment, run the following command: @@ -579,21 +582,21 @@ To generate an SDK of the environment, run the following command: .. code-block:: bash bitbake core-image-base -c populate_sdk - + This will create a sript ``build/tmp/deploy/sdk/ poky-glibc-x86_64-core-image-base-cortexa53-raspberrypi3-64-toolchain-5.0.4. -sh``. This script allows you to install the SDK where you prefer. Here is the +sh``. This script allows you to install the SDK where you prefer. Here is the execution output of the scrips .. code-block:: bash - $ ./sdk/poky-glibc-x86_64-core-image-base-cortexa53-raspberrypi3-64-toolchain-5.0.4.sh + $ ./sdk/poky-glibc-x86_64-core-image-base-cortexa53-raspberrypi3-64-toolchain-5.0.4.sh Poky (Yocto Project Reference Distro) SDK installer version 5.0.4 ================================================================= Enter target directory for SDK (default: /opt/poky/5.0.4): /opt/poky/sdk-with-lvgl You are about to install the SDK to "/opt/poky/sdk-with-lvgl". Proceed [Y/n]? y -If you want to ensure the SDK was generated with lvgl being installed, go to +If you want to ensure the SDK was generated with lvgl being installed, go to the path you extracted the SDK and find all lvgl files: .. code-block:: bash @@ -611,18 +614,18 @@ Now to use the SDK environment and cross-compile an application: .. note:: - The tools available in LVGL library will depend on the build configuration + The tools available in LVGL library will depend on the build configuration the recipe was done with. -Custom recipe +Custom recipe ************* -Until this section, everything was already done for you. We used existing -recipes. The objective here is to create a recipe from scratch and to add the +Until this section, everything was already done for you. We used existing +recipes. The objective here is to create a recipe from scratch and to add the generated binary in the image. -Create a layer +Create a layer ============== First, create a layer and add it to the configuration file @@ -632,7 +635,7 @@ First, create a layer and add it to the configuration file bitbake-layers create-layer ../sources/meta-mylvgl bitbake-layers add-layer ../sources/meta-mylvgl -In the ``sources`` folder, a new folder was created: ``meta-mylvgl`` and the +In the ``sources`` folder, a new folder was created: ``meta-mylvgl`` and the directory tree should look like the following .. code-block:: none @@ -646,28 +649,28 @@ directory tree should look like the following └── example_0.1.bb -Create a recipe +Create a recipe =============== -Following this structure, create a folder containing the recipies to build 1 +Following this structure, create a folder containing the recipies to build 1 or multiple applications using lvgl .. code-block:: - + cd ../sources/meta-mylvgl mkdir -p recipes-lvglapp/lvgl-fbdev-benchmark/files touch recipes-lvglapp/lvgl-fbdev-benchmark/lvglbenchmarkfbdev_2.4.bb -We will focus on 1 application that will clone an lvgl git repository and patch +We will focus on 1 application that will clone an lvgl git repository and patch it for our needs. The content of ``recipes-lvglapp/lvgl-fbdev-benchmark/lvglbenchmarkfbdev_2.4. bb`` .. code-block:: none - + DESCRIPTION = "My C++ lvgl app with CMake" - + LICENSE = "MIT" LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" @@ -675,7 +678,7 @@ bb`` SRC_URI = "gitsm://github.com/lvgl/lv_port_linux.git;branch=master;protocol=https \ file://0001-change-config-file-to-run-fbdev-with-2-threads.patch \ file://0002-adapt-CMakeLists-file-to-compile-and-link-fbdev.patch \ - " + " S = "${WORKDIR}/git" @@ -727,7 +730,7 @@ Content of ``0001-change-config-file-to-run-fbdev-with-2-threads.patch`` +#define LV_USE_STDLIB_MALLOC LV_STDLIB_CLIB +#define LV_USE_STDLIB_STRING LV_STDLIB_CLIB +#define LV_USE_STDLIB_SPRINTF LV_STDLIB_CLIB - + #define LV_STDINT_INCLUDE #define LV_STDDEF_INCLUDE @@ -89,7 +89,7 @@ @@ -736,22 +739,22 @@ Content of ``0001-change-config-file-to-run-fbdev-with-2-threads.patch`` * - LV_OS_CUSTOM */ -#define LV_USE_OS LV_OS_NONE +#define LV_USE_OS LV_OS_PTHREAD - + #if LV_USE_OS == LV_OS_CUSTOM #define LV_OS_CUSTOM_INCLUDE @@ -117,12 +117,12 @@ * and can't be drawn in chunks. */ - - /*The target buffer size for simple layer chunks.*/ - -#define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /*[bytes]*/ - +#define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (512 * 1024) /*[bytes]*/ - + + /* The target buffer size for simple layer chunks. */ + -#define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /* [bytes] */ + +#define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (512 * 1024) /* [bytes] */ + /* The stack size of the drawing thread. * NOTE: If FreeType or ThorVG is enabled, it is recommended to set it to 32KB or more. */ - -#define LV_DRAW_THREAD_STACK_SIZE (8 * 1024) /*[bytes]*/ - +#define LV_DRAW_THREAD_STACK_SIZE (32 * 1024) /*[bytes]*/ - + -#define LV_DRAW_THREAD_STACK_SIZE (8 * 1024) /* [bytes] */ + +#define LV_DRAW_THREAD_STACK_SIZE (32 * 1024) /* [bytes] */ + #define LV_USE_DRAW_SW 1 #if LV_USE_DRAW_SW == 1 @@ -147,7 +147,7 @@ @@ -760,7 +763,7 @@ Content of ``0001-change-config-file-to-run-fbdev-with-2-threads.patch`` * > 1 means multiple threads will render the screen in parallel */ - #define LV_DRAW_SW_DRAW_UNIT_CNT 1 + #define LV_DRAW_SW_DRAW_UNIT_CNT 2 - + /* Use Arm-2D to accelerate the sw render */ #define LV_USE_DRAW_ARM2D_SYNC 0 @@ -979,8 +979,8 @@ @@ -773,26 +776,26 @@ Content of ``0001-change-config-file-to-run-fbdev-with-2-threads.patch`` + #define LV_LINUX_FBDEV_BUFFER_COUNT 2 #define LV_LINUX_FBDEV_BUFFER_SIZE 60 #endif - + @@ -1069,19 +1069,19 @@ #define LV_USE_DEMO_WIDGETS 1 - - /*Demonstrate the usage of encoder and keyboard*/ + + /* Demonstrate the usage of encoder and keyboard */ -#define LV_USE_DEMO_KEYPAD_AND_ENCODER 1 +#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 - - /*Benchmark your system*/ + + /* Benchmark your system */ #define LV_USE_DEMO_BENCHMARK 1 - - /*Render test for each primitives. Requires at least 480x272 display*/ + + /* Render test for each primitives. Requires at least 480x272 display */ -#define LV_USE_DEMO_RENDER 1 +#define LV_USE_DEMO_RENDER 0 - - /*Stress test for LVGL*/ + + /* Stress test for LVGL */ -#define LV_USE_DEMO_STRESS 1 +#define LV_USE_DEMO_STRESS 0 - - /*Music player demo*/ + + /* Music player demo */ -#define LV_USE_DEMO_MUSIC 1 +#define LV_USE_DEMO_MUSIC 0 #if LV_USE_DEMO_MUSIC @@ -800,26 +803,26 @@ Content of ``0001-change-config-file-to-run-fbdev-with-2-threads.patch`` #define LV_DEMO_MUSIC_LANDSCAPE 0 @@ -1091,16 +1091,16 @@ #endif - - /*Flex layout demo*/ + + /* Flex layout demo */ -#define LV_USE_DEMO_FLEX_LAYOUT 1 +#define LV_USE_DEMO_FLEX_LAYOUT 0 - - /*Smart-phone like multi-language demo*/ + + /* Smart-phone like multi-language demo */ -#define LV_USE_DEMO_MULTILANG 1 +#define LV_USE_DEMO_MULTILANG 0 - - /*Widget transformation demo*/ + + /* Widget transformation demo */ -#define LV_USE_DEMO_TRANSFORM 1 +#define LV_USE_DEMO_TRANSFORM 0 - - /*Demonstrate scroll settings*/ + + /* Demonstrate scroll settings */ -#define LV_USE_DEMO_SCROLL 1 +#define LV_USE_DEMO_SCROLL 0 - - /*Vector graphic demo*/ + + /* Vector graphic demo */ #define LV_USE_DEMO_VECTOR_GRAPHIC 0 - -- + -- 2.34.1 @@ -852,21 +855,21 @@ Content of ``0002-adapt-CMakeLists-file-to-compile-and-link-fbdev.patch`` @@ -1,8 +1,8 @@ cmake_minimum_required(VERSION 3.10) project(lvgl) - + -set(CMAKE_C_STANDARD 99)#C99 # lvgl officially support C99 and above -set(CMAKE_CXX_STANDARD 17)#C17 +set(CMAKE_C_STANDARD 99) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) - + set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) @@ -10,15 +10,8 @@ set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) add_subdirectory(lvgl) target_include_directories(lvgl PUBLIC ${PROJECT_SOURCE_DIR}) - + -add_executable(main main.c mouse_cursor_icon.c) +add_executable(lvglbenchmark main.c mouse_cursor_icon.c) - + -include(${CMAKE_CURRENT_LIST_DIR}/lvgl/tests/FindLibDRM.cmake) -include_directories(${Libdrm_INCLUDE_DIRS}) - @@ -878,11 +881,11 @@ Content of ``0002-adapt-CMakeLists-file-to-compile-and-link-fbdev.patch`` -add_custom_target (run COMMAND ${EXECUTABLE_OUTPUT_PATH}/main DEPENDS main) +target_link_libraries(lvglbenchmark lvgl lvgl::examples lvgl::demos lvgl::thorvg m pthread) +add_custom_target (run COMMAND ${EXECUTABLE_OUTPUT_PATH}/lvglbenchmark DEPENDS main) - - -- + + -- 2.34.1 -Build the recipe +Build the recipe ================ You should now be able to see the recipe listing the existing recipes @@ -891,7 +894,7 @@ You should now be able to see the recipe listing the existing recipes bitbake-layers show-recipes | grep lvglbenchmarkfbdev -Now add the recipe to the project. Modify ``build/conf/local.conf`` file adding +Now add the recipe to the project. Modify ``build/conf/local.conf`` file adding this line .. code-block:: @@ -904,7 +907,7 @@ Now build the image bitbake core-image-base -Run this command to ensure the binary was generated and was installed in the +Run this command to ensure the binary was generated and was installed in the rootfs .. code-block:: diff --git a/docs/integration/os/yocto/terms_and_variables.rst b/docs/details/integration/os/yocto/terms_and_variables.rst similarity index 86% rename from docs/integration/os/yocto/terms_and_variables.rst rename to docs/details/integration/os/yocto/terms_and_variables.rst index 1566b4895..5a448cc64 100644 --- a/docs/integration/os/yocto/terms_and_variables.rst +++ b/docs/details/integration/os/yocto/terms_and_variables.rst @@ -1,52 +1,55 @@ -Yocto Project Terms -################### +.. _yocto_project_terms: -Getting started in Yocto can be overwheming. There are many terms used that are +=================== +Yocto Project Terms +=================== + +Getting started in Yocto can be overwheming. There are many terms used that are specific to Yocto and Bitbake environment. -A list of terms and definitions users new to the Yocto Project +A list of terms and definitions users new to the Yocto Project development environment might find helpful can be found `here `_. Yocto Variables Glossary -######################## +************************ -This chapter lists basic variables used in the LVGL Yocto guide and gives an +This chapter lists basic variables used in the LVGL Yocto guide and gives an overview of their function and contents. -A More complete variable glossary can be found in `Yocto Variable Glossary -`_. This section +A More complete variable glossary can be found in `Yocto Variable Glossary +`_. This section covers a lot of variables used in the OpenEmbedded build system. .. _S: -S -= +S +- The location in the Build Directory where unpacked recipe source code resides. - By default, this directory is ${WORKDIR}/${BPN}-${PV}, where ${BPN} is the - base recipe name and ${PV} is the recipe version. If the source tarball - extracts the code to a directory named anything other than ${BPN}-${PV}, or if - the source code is fetched from an SCM such as Git or Subversion, then you - must set S in the recipe so that the OpenEmbedded build system knows where to + By default, this directory is ${WORKDIR}/${BPN}-${PV}, where ${BPN} is the + base recipe name and ${PV} is the recipe version. If the source tarball + extracts the code to a directory named anything other than ${BPN}-${PV}, or if + the source code is fetched from an SCM such as Git or Subversion, then you + must set S in the recipe so that the OpenEmbedded build system knows where to find the unpacked source. -As an example, assume a Source Directory top-level folder named poky and a -default Build Directory at poky/build. In this case, the work directory the +As an example, assume a Source Directory top-level folder named poky and a +default Build Directory at poky/build. In this case, the work directory the build system uses to keep the unpacked recipe for db is the following: -.. code-block:: bash +.. code-block:: bash poky/build/tmp/work/qemux86-poky-linux/db/5.1.19-r3/db-5.1.19 The unpacked source code resides in the db-5.1.19 folder. -This next example assumes a Git repository. By default, Git repositories are -cloned to ${WORKDIR}/git during do_fetch. Since this path is different from the +This next example assumes a Git repository. By default, Git repositories are +cloned to ${WORKDIR}/git during do_fetch. Since this path is different from the default value of S, you must set it specifically so the source can be located: -.. code-block:: bash +.. code-block:: bash SRC_URI = "git://path/to/repo.git;branch=main" S = "${WORKDIR}/git" @@ -54,10 +57,10 @@ default value of S, you must set it specifically so the source can be located: .. _D: -D -= +D +- -The destination directory. The location in the Build Directory where components +The destination directory. The location in the Build Directory where components are installed by the do_install task. This location defaults to: .. code-block:: bash @@ -70,35 +73,35 @@ are installed by the do_install task. This location defaults to: .. _B: -B -= +B +- -The directory within the Build Directory in which the OpenEmbedded build system -places generated objects during a recipe's build process. By default, this +The directory within the Build Directory in which the OpenEmbedded build system +places generated objects during a recipe's build process. By default, this directory is the same as the S directory, which is defined as: -.. code-block:: bash +.. code-block:: bash S = "${WORKDIR}/${BP}" -You can separate the (S) directory and the directory pointed to by the B -variable. Most Autotools-based recipes support separating these directories. -The build system defaults to using separate directories for gcc and some kernel +You can separate the (S) directory and the directory pointed to by the B +variable. Most Autotools-based recipes support separating these directories. +The build system defaults to using separate directories for gcc and some kernel recipes. .. _WORKDIR: WORKDIR -======= +------- -The pathname of the work directory in which the OpenEmbedded build system -builds a recipe. This directory is located within the TMPDIR directory -structure and is specific to the recipe being built and the system for which it +The pathname of the work directory in which the OpenEmbedded build system +builds a recipe. This directory is located within the TMPDIR directory +structure and is specific to the recipe being built and the system for which it is being built. The WORKDIR directory is defined as follows: -.. code-block:: bash +.. code-block:: bash ${TMPDIR}/work/${MULTIMACH_TARGET_SYS}/${PN}/${EXTENDPE}${PV}-${PR} @@ -107,45 +110,45 @@ The actual directory depends on several things: - **TMPDIR**: The top-level build output directory - **MULTIMACH_TARGET_SYS**: The target system identifier - **PN**: The recipe name - - **EXTENDPE**: The epoch — if PE is not specified, which is usually the + - **EXTENDPE**: The epoch — if PE is not specified, which is usually the case for most recipes, then EXTENDPE is blank. - **PV**: The recipe version - **PR**: The recipe revision -As an example, assume a Source Directory top-level folder name poky, a default -Build Directory at poky/build, and a qemux86-poky-linux machine target system. -Furthermore, suppose your recipe is named foo_1.3.0-r0.bb. In this case, the +As an example, assume a Source Directory top-level folder name poky, a default +Build Directory at poky/build, and a qemux86-poky-linux machine target system. +Furthermore, suppose your recipe is named foo_1.3.0-r0.bb. In this case, the work directory the build system uses to build the package would be as follows: -.. code-block:: bash +.. code-block:: bash poky/build/tmp/work/qemux86-poky-linux/foo/1.3.0-r0 .. _PN: -PN -== +PN +-- -This variable can have two separate functions depending on the context: a +This variable can have two separate functions depending on the context: a recipe name or a resulting package name. -PN refers to a recipe name in the context of a file used by the OpenEmbedded -build system as input to create a package. The name is normally extracted from -the recipe file name. For example, if the recipe is named expat_2.0.1.bb, then +PN refers to a recipe name in the context of a file used by the OpenEmbedded +build system as input to create a package. The name is normally extracted from +the recipe file name. For example, if the recipe is named expat_2.0.1.bb, then the default value of PN will be “expat”. -The variable refers to a package name in the context of a file created or +The variable refers to a package name in the context of a file created or produced by the OpenEmbedded build system. -If applicable, the PN variable also contains any special suffix or prefix. For -example, using bash to build packages for the native machine, PN is -bash-native. Using bash to build packages for the target and for Multilib, PN +If applicable, the PN variable also contains any special suffix or prefix. For +example, using bash to build packages for the native machine, PN is +bash-native. Using bash to build packages for the target and for Multilib, PN would be bash and lib64-bash, respectively. .. _PR: PR -== +-- The revision of the recipe. The default value for this variable is "r0". Subsequent revisions of the recipe conventionally have the @@ -154,8 +157,8 @@ PR is conventionally reset to "r0". .. note:: - The OpenEmbedded build system does not need the aid of PR to know when to - rebuild a recipe. The build system uses the task input checksums along with + The OpenEmbedded build system does not need the aid of PR to know when to + rebuild a recipe. The build system uses the task input checksums along with the stamp and shared state cache mechanisms. The PR variable primarily becomes significant when a package @@ -176,18 +179,18 @@ packaging fixes. Because manually managing PR can be cumbersome and error-prone, an automated solution exists. See the "`working with a pr service `_" section in the Yocto Project Development +html#working-with-a-pr-service>`_" section in the Yocto Project Development Tasks Manual for more information. .. _PV: PV -== +-- -The version of the recipe. The version is normally extracted from the recipe -filename. For example, if the recipe is named expat_2.0.1.bb, then the default -value of PV will be “2.0.1”. PV is generally not overridden within a recipe -unless it is building an unstable (i.e. development) version from a source code +The version of the recipe. The version is normally extracted from the recipe +filename. For example, if the recipe is named expat_2.0.1.bb, then the default +value of PV will be “2.0.1”. PV is generally not overridden within a recipe +unless it is building an unstable (i.e. development) version from a source code repository (e.g. Git or Subversion). -PV is the default value of the PKGV variable. \ No newline at end of file +PV is the default value of the PKGV variable. diff --git a/docs/integration/os/zephyr.rst b/docs/details/integration/os/zephyr.rst similarity index 100% rename from docs/integration/os/zephyr.rst rename to docs/details/integration/os/zephyr.rst diff --git a/docs/overview/renderers/arm2d.rst b/docs/details/integration/renderers/arm2d.rst similarity index 100% rename from docs/overview/renderers/arm2d.rst rename to docs/details/integration/renderers/arm2d.rst diff --git a/docs/overview/renderers/index.rst b/docs/details/integration/renderers/index.rst similarity index 79% rename from docs/overview/renderers/index.rst rename to docs/details/integration/renderers/index.rst index 5177dec8f..80b1668aa 100644 --- a/docs/overview/renderers/index.rst +++ b/docs/details/integration/renderers/index.rst @@ -5,12 +5,10 @@ Renderers and GPUs .. toctree:: :maxdepth: 2 + sw arm2d nema_gfx - pxp + nxp_pxp + nxp_vglite sdl stm32_dma2d - sw - vglite - vg_lite - diff --git a/docs/overview/renderers/nema_gfx.rst b/docs/details/integration/renderers/nema_gfx.rst similarity index 100% rename from docs/overview/renderers/nema_gfx.rst rename to docs/details/integration/renderers/nema_gfx.rst diff --git a/docs/overview/renderers/pxp.rst b/docs/details/integration/renderers/nxp_pxp.rst similarity index 96% rename from docs/overview/renderers/pxp.rst rename to docs/details/integration/renderers/nxp_pxp.rst index 427755708..02b0a0c64 100644 --- a/docs/overview/renderers/pxp.rst +++ b/docs/details/integration/renderers/nxp_pxp.rst @@ -3,7 +3,7 @@ NXP PXP GPU =========== API ---- +*** :ref:`lv_draw_pxp_h` diff --git a/docs/overview/renderers/vg_lite.rst b/docs/details/integration/renderers/nxp_vglite.rst similarity index 95% rename from docs/overview/renderers/vg_lite.rst rename to docs/details/integration/renderers/nxp_vglite.rst index aa396b8d0..ea6f33a25 100644 --- a/docs/overview/renderers/vg_lite.rst +++ b/docs/details/integration/renderers/nxp_vglite.rst @@ -1,6 +1,8 @@ -=================== -VG-Lite General GPU -=================== +.. _vglite: + +=============== +NXP VG-Lite GPU +=============== This is a generic VG-Lite rendering backend implementation that is designed to utilize `VeriSilicon `_'s generic API to operate GPU hardware as much as possible. @@ -65,4 +67,20 @@ VG-Lite Simulator LVGL integrates a VG-Lite simulator based on ThorVG. Its purpose is to simplify the debugging of VG-Lite adaptation and reduce the time of debugging and locating problems on hardware devices. -For detailed instructions, see `VG-Lite Simulator `__. +For detailed instructions, see :ref:`vg_lite_tvg`. + + +API +*** + +:ref:`lv_draw_vglite_h` + +:ref:`lv_vglite_buf_h` + +:ref:`lv_vglite_matrix_h` + +:ref:`lv_vglite_path_h` + +:ref:`lv_vglite_utils_h` + + diff --git a/docs/overview/renderers/sdl.rst b/docs/details/integration/renderers/sdl.rst similarity index 76% rename from docs/overview/renderers/sdl.rst rename to docs/details/integration/renderers/sdl.rst index 6785c1187..82730640f 100644 --- a/docs/overview/renderers/sdl.rst +++ b/docs/details/integration/renderers/sdl.rst @@ -1,9 +1,9 @@ ============ -SDL renderer +SDL Renderer ============ API ---- +*** :ref:`lv_draw_sdl_h` diff --git a/docs/details/integration/renderers/stm32_dma2d.rst b/docs/details/integration/renderers/stm32_dma2d.rst new file mode 100644 index 000000000..0d5fe00d9 --- /dev/null +++ b/docs/details/integration/renderers/stm32_dma2d.rst @@ -0,0 +1,9 @@ +=============== +STM32 DMA2D GPU +=============== + +API +*** + +:ref:`lv_draw_dma2d_h` + diff --git a/docs/overview/renderers/sw.rst b/docs/details/integration/renderers/sw.rst similarity index 84% rename from docs/overview/renderers/sw.rst rename to docs/details/integration/renderers/sw.rst index ee2fe51d0..d5afcdbb2 100644 --- a/docs/overview/renderers/sw.rst +++ b/docs/details/integration/renderers/sw.rst @@ -1,9 +1,9 @@ ================= -Software renderer +Software Renderer ================= API ---- +*** :ref:`lv_draw_sw_h` diff --git a/docs/libs/arduino_esp_littlefs.rst b/docs/details/libs/arduino_esp_littlefs.rst similarity index 100% rename from docs/libs/arduino_esp_littlefs.rst rename to docs/details/libs/arduino_esp_littlefs.rst diff --git a/docs/libs/arduino_sd.rst b/docs/details/libs/arduino_sd.rst similarity index 100% rename from docs/libs/arduino_sd.rst rename to docs/details/libs/arduino_sd.rst diff --git a/docs/libs/barcode.rst b/docs/details/libs/barcode.rst similarity index 90% rename from docs/libs/barcode.rst rename to docs/details/libs/barcode.rst index 99e5e0345..293acba2e 100644 --- a/docs/libs/barcode.rst +++ b/docs/details/libs/barcode.rst @@ -28,7 +28,7 @@ Notes ----- - It is best not to manually set the width of the barcode, because when - the width of the object is lower than the width of the barcode, the + the width of the Widget is lower than the width of the barcode, the display will be incomplete due to truncation. - The scale adjustment can only be an integer multiple, for example, :cpp:expr:`lv_barcode_set_scale(barcode, 2)` means 2x scaling. @@ -39,7 +39,7 @@ Notes Example ------- -.. include:: ../examples/libs/barcode/index.rst +.. include:: ../../examples/libs/barcode/index.rst .. _barcode_api: diff --git a/docs/libs/bmp.rst b/docs/details/libs/bmp.rst similarity index 93% rename from docs/libs/bmp.rst rename to docs/details/libs/bmp.rst index 356d42927..1e7587575 100644 --- a/docs/libs/bmp.rst +++ b/docs/details/libs/bmp.rst @@ -4,7 +4,7 @@ BMP decoder =========== -This extension allows the use of BMP images in LVGL. +This extension allows the use of BMP images in LVGL. Library source: https://github.com/caj-johnson/bmp-decoder @@ -45,7 +45,7 @@ Limitations Example ------- -.. include:: ../examples/libs/bmp/index.rst +.. include:: ../../examples/libs/bmp/index.rst .. _bmp_api: diff --git a/docs/libs/ffmpeg.rst b/docs/details/libs/ffmpeg.rst similarity index 95% rename from docs/libs/ffmpeg.rst rename to docs/details/libs/ffmpeg.rst index d1e82ac4e..3fd113c47 100644 --- a/docs/libs/ffmpeg.rst +++ b/docs/details/libs/ffmpeg.rst @@ -43,7 +43,7 @@ See the examples below. Example ------- -.. include:: ../examples/libs/ffmpeg/index.rst +.. include:: ../../examples/libs/ffmpeg/index.rst .. _ffmpeg_api: diff --git a/docs/libs/freetype.rst b/docs/details/libs/freetype.rst similarity index 98% rename from docs/libs/freetype.rst rename to docs/details/libs/freetype.rst index 25f69c48e..87abcf768 100644 --- a/docs/libs/freetype.rst +++ b/docs/details/libs/freetype.rst @@ -102,7 +102,7 @@ please refer to example code. Examples -------- -.. include:: ../examples/libs/freetype/index.rst +.. include:: ../../examples/libs/freetype/index.rst Learn more ---------- diff --git a/docs/libs/fs.rst b/docs/details/libs/fs.rst similarity index 96% rename from docs/libs/fs.rst rename to docs/details/libs/fs.rst index 003467de5..701103d78 100644 --- a/docs/libs/fs.rst +++ b/docs/details/libs/fs.rst @@ -36,10 +36,10 @@ Working with common prefixes A **default driver letter** can be set by ``LV_FS_DEFAULT_DRIVE_LETTER``, which allows skipping the drive prefix in file paths. -For example if ``LV_FS_DEFAULT_DRIVE_LETTER`` is set the ``'S'`` *"path/to/file.txt"* will mean *"S:path/to/file.txt"*. +For example if ``LV_FS_DEFAULT_DRIVE_LETTER`` is set the ``'S'`` *"path/to/file.txt"* will mean *"S:path/to/file.txt"*. This feature is useful if you have only a single driver and don't want to bother with LVGL's driver layer in the file paths. -It also helps to use a unified path with LVGL's file system and normal file systems. +It also helps to use a unified path with LVGL's file system and normal file systems. The original mechanism is not affected, so a path starting with drive letter will still work. The **working directory** can be set with ``LV_FS_..._PATH``. E.g. @@ -64,7 +64,7 @@ the file name: uint8_t *buffer; uint32_t size; - /*Initialize buffer*/ + /* Initialize buffer */ ... lv_fs_make_path_from_buffer(&mempath, LV_FS_MEMFS_LETTER, (void*)buffer, size); diff --git a/docs/libs/gif.rst b/docs/details/libs/gif.rst similarity index 86% rename from docs/libs/gif.rst rename to docs/details/libs/gif.rst index 06425e1ff..087dd8b7a 100644 --- a/docs/libs/gif.rst +++ b/docs/details/libs/gif.rst @@ -11,7 +11,7 @@ Detailed introduction: https://github.com/lecram/gifdec When enabled in ``lv_conf.h`` with :c:macro:`LV_USE_GIF` :cpp:expr:`lv_gif_create(parent)` can be used to create a gif widget. -:cpp:expr:`lv_gif_set_src(obj, src)` works very similarly to :cpp:func:`lv_image_set_src`. +:cpp:expr:`lv_gif_set_src(widget, src)` works very similarly to :cpp:func:`lv_image_set_src`. As source, it also accepts images as variables (:c:struct:`lv_image_dsc_t`) or files. @@ -29,7 +29,7 @@ For example: .. code-block:: c - lv_gif_set_src(obj, "S:path/to/example.gif"); + lv_gif_set_src(widget, "S:path/to/example.gif"); Note that, a file system driver needs to be registered to open images from files. Read more about it :ref:`overview_file_system` or just @@ -50,7 +50,7 @@ required: Example ------- -.. include:: ../examples/libs/gif/index.rst +.. include:: ../../examples/libs/gif/index.rst .. _gif_api: diff --git a/docs/libs/index.rst b/docs/details/libs/index.rst similarity index 93% rename from docs/libs/index.rst rename to docs/details/libs/index.rst index 4230b096f..fb1a9dc0a 100644 --- a/docs/libs/index.rst +++ b/docs/details/libs/index.rst @@ -1,7 +1,7 @@ .. _3rd_party_libraries: =================== -3rd party libraries +3rd-Party Libraries =================== diff --git a/docs/libs/lfs.rst b/docs/details/libs/lfs.rst similarity index 100% rename from docs/libs/lfs.rst rename to docs/details/libs/lfs.rst diff --git a/docs/libs/libjpeg_turbo.rst b/docs/details/libs/libjpeg_turbo.rst similarity index 95% rename from docs/libs/libjpeg_turbo.rst rename to docs/details/libs/libjpeg_turbo.rst index 414bf9ef3..d074df584 100644 --- a/docs/libs/libjpeg_turbo.rst +++ b/docs/details/libs/libjpeg_turbo.rst @@ -45,7 +45,7 @@ and it needs to be combined with the :ref:`overview_image_caching` feature to en Example ------- -.. include:: ../examples/libs/libjpeg_turbo/index.rst +.. include:: ../../examples/libs/libjpeg_turbo/index.rst .. _libjpeg_api: diff --git a/docs/libs/libpng.rst b/docs/details/libs/libpng.rst similarity index 91% rename from docs/libs/libpng.rst rename to docs/details/libs/libpng.rst index 01abafb1d..4784fb318 100644 --- a/docs/libs/libpng.rst +++ b/docs/details/libs/libpng.rst @@ -32,7 +32,7 @@ Usage Enable :c:macro:`LV_USE_LIBPNG` in ``lv_conf.h``. See the examples below. -It should be noted that each image of this decoder needs to consume ``width x height x 4`` bytes of RAM, +It should be noted that each image of this decoder needs to consume ``width x height x 4`` bytes of RAM, and it needs to be combined with the :ref:`overview_image_caching` feature to ensure that the memory usage is within a reasonable range. The decoded image is stored in RGBA pixel format. @@ -41,7 +41,7 @@ The decoded image is stored in RGBA pixel format. Example ------- -.. include:: ../examples/libs/libpng/index.rst +.. include:: ../../examples/libs/libpng/index.rst .. _libpng_api: diff --git a/docs/libs/lodepng.rst b/docs/details/libs/lodepng.rst similarity index 96% rename from docs/libs/lodepng.rst rename to docs/details/libs/lodepng.rst index 84ee72a06..1a704de88 100644 --- a/docs/libs/lodepng.rst +++ b/docs/details/libs/lodepng.rst @@ -40,7 +40,7 @@ for example Compress PNG: https://compresspng.com/ Example ------- -.. include:: ../examples/libs/lodepng/index.rst +.. include:: ../../examples/libs/lodepng/index.rst .. _lodepng_api: diff --git a/docs/libs/qrcode.rst b/docs/details/libs/qrcode.rst similarity index 94% rename from docs/libs/qrcode.rst rename to docs/details/libs/qrcode.rst index 027346cc2..263f26ccf 100644 --- a/docs/libs/qrcode.rst +++ b/docs/details/libs/qrcode.rst @@ -34,7 +34,7 @@ Notes Example ------- -.. include:: ../examples/libs/qrcode/index.rst +.. include:: ../../examples/libs/qrcode/index.rst .. _qrcode_api: diff --git a/docs/libs/rle-compress-statistics.png b/docs/details/libs/rle-compress-statistics.png similarity index 100% rename from docs/libs/rle-compress-statistics.png rename to docs/details/libs/rle-compress-statistics.png diff --git a/docs/libs/rle.rst b/docs/details/libs/rle.rst similarity index 96% rename from docs/libs/rle.rst rename to docs/details/libs/rle.rst index 0c28bf62f..fb2cdb553 100644 --- a/docs/libs/rle.rst +++ b/docs/details/libs/rle.rst @@ -19,7 +19,7 @@ to save more than 70% space as show in below statistic. It shows the file count of every compress level. For rare conditions, RLE compress may increase the file size if there's no large repetition in data. -.. image:: /libs/rle-compress-statistics.png +.. image:: rle-compress-statistics.png :alt: RLE compress statistics from a watch project :align: center @@ -53,7 +53,7 @@ can be found from ``lvgl/script/LVGLImage.py``. ctrl_byte = uint8_t(nonrepeat_cnt | 0x80) compressed_data.append(ctrl_byte) compressed_data.append( - memview[index: index + nonrepeat_cnt*blksize]) + memview[index: index + nonrepeat_cnt * blksize]) index += nonrepeat_cnt * blksize else: ctrl_byte = uint8_t(repeat_cnt) diff --git a/docs/libs/rlottie.rst b/docs/details/libs/rlottie.rst similarity index 98% rename from docs/libs/rlottie.rst rename to docs/details/libs/rlottie.rst index 7ca81a5ea..0b80739a5 100644 --- a/docs/libs/rlottie.rst +++ b/docs/details/libs/rlottie.rst @@ -51,7 +51,7 @@ Usage You can use animation from files or raw data (text). In either case first you need to enable :c:macro:`LV_USE_RLOTTIE` in ``lv_conf.h``. -The ``width`` and ``height`` of the object be set in the *create* +The ``width`` and ``height`` of the Widget be set in the *create* function and the animation will be scaled accordingly. Use Rlottie from file @@ -283,7 +283,7 @@ IDF) with the appropriate :cpp:expr:`MALLOC_CAP` call - for SPIRAM usage this is Example ------- -.. include:: ../examples/libs/rlottie/index.rst +.. include:: ../../examples/libs/rlottie/index.rst .. _rlottie_api: diff --git a/docs/libs/svg.rst b/docs/details/libs/svg.rst similarity index 79% rename from docs/libs/svg.rst rename to docs/details/libs/svg.rst index 6bebe6af0..cdf634f3b 100644 --- a/docs/libs/svg.rst +++ b/docs/details/libs/svg.rst @@ -9,21 +9,19 @@ Scalable Vector Graphics (SVG) Tiny 1.2 support in LVGL. Detailed introduction: https://www.w3.org/TR/SVGTiny12/ Usage ------ +***** Enable :c:macro:`LV_USE_SVG` in ``lv_conf.h``. See the examples below. -If you need support SVG animation attribute parsing, +If you need support SVG animation attribute parsing, you can enable :c:macro:`LV_USE_SVG_ANIMATION` in ``lv_conf.h``. .. _svg_example: Example -------- - -.. include:: ../examples/libs/svg/index.rst +******* .. code:: c @@ -31,7 +29,7 @@ Example const char* svg_data = ""; /* Create an SVG DOM tree*/ - svg_doc = lv_svg_load_data(svg_data, svg_len); + svg_doc = lv_svg_load_data(svg_data, svg_len); ... /* Draw SVG image*/ @@ -44,6 +42,6 @@ Example .. _svg_api: API ---- +*** diff --git a/docs/libs/tiny_ttf.rst b/docs/details/libs/tiny_ttf.rst similarity index 96% rename from docs/libs/tiny_ttf.rst rename to docs/details/libs/tiny_ttf.rst index 137d519d9..25964bbd9 100644 --- a/docs/libs/tiny_ttf.rst +++ b/docs/details/libs/tiny_ttf.rst @@ -43,7 +43,7 @@ if supported, or disable. Example ------- -.. include:: ../examples/libs/tiny_ttf/index.rst +.. include:: ../../examples/libs/tiny_ttf/index.rst .. _tiny_ttf_api: diff --git a/docs/libs/tjpgd.rst b/docs/details/libs/tjpgd.rst similarity index 96% rename from docs/libs/tjpgd.rst rename to docs/details/libs/tjpgd.rst index 719531205..e8f3e7bc2 100644 --- a/docs/libs/tjpgd.rst +++ b/docs/details/libs/tjpgd.rst @@ -53,7 +53,7 @@ Converting JPEG to C array Example ------- -.. include:: ../examples/libs/tjpgd/index.rst +.. include:: ../../examples/libs/tjpgd/index.rst .. _tjpgd_api: diff --git a/docs/overview/animations.rst b/docs/details/main-components/animation.rst similarity index 77% rename from docs/overview/animations.rst rename to docs/details/main-components/animation.rst index 8a4764dc9..b6140d114 100644 --- a/docs/overview/animations.rst +++ b/docs/details/main-components/animation.rst @@ -1,8 +1,8 @@ -.. _animations: +.. _animation: -========== -Animations -========== +=================== +Animation (lv_anim) +=================== You can automatically change the value of a variable between a start and an end value using animations. Animation will happen by periodically @@ -15,8 +15,8 @@ The *animator* functions have the following prototype: void func(void * var, lv_anim_var_t value); This prototype is compatible with the majority of the property *set* -functions in LVGL. For example :cpp:expr:`lv_obj_set_x(obj, value)` or -:cpp:expr:`lv_obj_set_width(obj, value)` +functions in LVGL. For example :cpp:expr:`lv_obj_set_x(widget, value)` or +:cpp:expr:`lv_obj_set_width(widget, value)` .. _animations_create: @@ -38,54 +38,54 @@ and configured with ``lv_anim_set_...()`` functions. /* MANDATORY SETTINGS *------------------*/ - /*Set the "animator" function*/ + /* Set the "animator" function */ lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t) lv_obj_set_x); - /*Set target of the animation*/ - lv_anim_set_var(&a, obj); + /* Set target of the animation */ + lv_anim_set_var(&a, widget); - /*Length of the animation [ms]*/ + /* Length of the animation [ms] */ lv_anim_set_duration(&a, duration); - /*Set start and end values. E.g. 0, 150*/ + /* Set start and end values. E.g. 0, 150 */ lv_anim_set_values(&a, start, end); /* OPTIONAL SETTINGS *------------------*/ - /*Time to wait before starting the animation [ms]*/ + /* Time to wait before starting the animation [ms] */ lv_anim_set_delay(&a, delay); - /*Set path (curve). Default is linear*/ + /* Set path (curve). Default is linear */ lv_anim_set_path_cb(&a, lv_anim_path_ease_in); - /*Set a callback to indicate when the animation is completed.*/ + /* Set a callback to indicate when the animation is completed. */ lv_anim_set_completed_cb(&a, completed_cb); - /*Set a callback to indicate when the animation is deleted (idle).*/ + /* Set a callback to indicate when the animation is deleted (idle). */ lv_anim_set_deleted_cb(&a, deleted_cb); - /*Set a callback to indicate when the animation is started (after delay).*/ + /* Set a callback to indicate when the animation is started (after delay). */ lv_anim_set_start_cb(&a, start_cb); - /*When ready, play the animation backward with this duration. Default is 0 (disabled) [ms]*/ + /* When ready, play the animation backward with this duration. Default is 0 (disabled) [ms] */ lv_anim_set_playback_duration(&a, time); - /*Delay before playback. Default is 0 (disabled) [ms]*/ + /* Delay before playback. Default is 0 (disabled) [ms] */ lv_anim_set_playback_delay(&a, delay); - /*Number of repetitions. Default is 1. LV_ANIM_REPEAT_INFINITE for infinite repetition*/ + /* Number of repetitions. Default is 1. LV_ANIM_REPEAT_INFINITE for infinite repetition */ lv_anim_set_repeat_count(&a, cnt); - /*Delay before repeat. Default is 0 (disabled) [ms]*/ + /* Delay before repeat. Default is 0 (disabled) [ms] */ lv_anim_set_repeat_delay(&a, delay); - /*true (default): apply the start value immediately, false: apply start value after delay when the anim. really starts. */ + /* true (default): apply the start value immediately, false: apply start value after delay when the anim. really starts. */ lv_anim_set_early_apply(&a, true/false); /* START THE ANIMATION *------------------*/ - lv_anim_start(&a); /*Start the animation*/ + lv_anim_start(&a); /* Start the animation */ You can apply multiple different animations on the same variable at the same time. For example, animate the x and y coordinates with @@ -166,7 +166,7 @@ after adding all animations and before starting to play. Call :cpp:expr:`lv_anim_timeline_stop(at)` to stop the animation timeline. Call :cpp:expr:`lv_anim_timeline_set_progress(at, progress)` function to set the -state of the object corresponding to the progress of the timeline. +state of the Widget corresponding to the progress of the timeline. Call :cpp:expr:`lv_anim_timeline_get_playtime(at)` function to get the total duration of the entire animation timeline. @@ -175,8 +175,8 @@ Call :cpp:expr:`lv_anim_timeline_get_reverse(at)` function to get whether to reverse the animation timeline. Call :cpp:expr:`lv_anim_timeline_delete(at)` function to delete the animation timeline. -**Note**: If you need to delete an object during animation, be sure to delete the -anim timeline before deleting the object. Otherwise, the program may crash or behave abnormally. +**Note**: If you need to delete a Widget during animation, be sure to delete the +anim timeline before deleting the Widget. Otherwise, the program may crash or behave abnormally. .. image:: /misc/anim-timeline.png @@ -185,7 +185,7 @@ anim timeline before deleting the object. Otherwise, the program may crash or be Examples ******** -.. include:: ../examples/anim/index.rst +.. include:: ../../examples/anim/index.rst .. _animations_api: diff --git a/docs/overview/color.rst b/docs/details/main-components/color.rst similarity index 86% rename from docs/overview/color.rst rename to docs/details/main-components/color.rst index 64373cbf8..dc1456327 100644 --- a/docs/overview/color.rst +++ b/docs/details/main-components/color.rst @@ -1,8 +1,8 @@ .. _color: -====== -Colors -====== +================ +Color (lv_color) +================ The color module handles all color-related functions like changing color depth, creating colors from hex code, converting between color depths, @@ -23,17 +23,17 @@ Create colors from Red, Green and Blue channel values: .. code-block:: c - /*All channels are 0-255*/ + /* All channels are 0-255 */ lv_color_t c = lv_color_make(red, green, blue); - /*Same but can be used for const initialization too */ + /* Same but can be used for const initialization as well */ lv_color_t c = LV_COLOR_MAKE(red, green, blue); - /*From hex code 0x000000..0xFFFFFF interpreted as RED + GREEN + BLUE*/ + /* From hex code 0x000000..0xFFFFFF interpreted as RED + GREEN + BLUE */ lv_color_t c = lv_color_hex(0x123456); - /*From 3 digits. Same as lv_color_hex(0x112233)*/ + /* From 3 digits. Same as lv_color_hex(0x112233) */ lv_color_t c = lv_color_hex3(0x123); HSV @@ -85,12 +85,12 @@ The names of the colors are as follows: - :c:macro:`LV_PALETTE_GREY` To get the main color use -``lv_color_t c = lv_palette_main(LV_PALETTE_...)``. +:cpp:expr:`lv_color_t` ``c =`` :cpp:expr:`lv_palette_main(LV_PALETTE_...)`. For the lighter variants of a palette color use -``lv_color_t c = lv_palette_lighten(LV_PALETTE_..., v)``. ``v`` can be +:cpp:expr:`lv_color_t` ``c =`` :cpp:expr:`lv_palette_lighten(LV_PALETTE_..., v)`. ``v`` can be 1..5. For the darker variants of a palette color use -``lv_color_t c = lv_palette_darken(LV_PALETTE_..., v)``. ``v`` can be +:cpp:expr:`lv_color_t` ``c =`` :cpp:expr:`lv_palette_darken(LV_PALETTE_..., v)`. ``v`` can be 1..4. .. _color_modify_and_mix: diff --git a/docs/details/main-components/display.rst b/docs/details/main-components/display.rst new file mode 100644 index 000000000..8b2b9f68c --- /dev/null +++ b/docs/details/main-components/display.rst @@ -0,0 +1,654 @@ +.. _display: + +==================== +Display (lv_display) +==================== + + +What is a Display? +****************** +In LVGL, an *lv_display_t* (not to be confused with a :ref:`Screen `) is a +data type that represents a single display panel --- the hardware that displays +LVGL-rendered pixels on your device. During system initialization, you must do the +following for each display panel you want LVGL to use: + +- :ref:`create an lv_display_t ` object for it, +- assign a :ref:`flush_callback` for it, and +- assign its :ref:`draw_buffers`. + + +.. _multiple_dislays: + +How Many Displays Can LVGL Use? +******************************* +LVGL can use any number of displays. It is only limited by available RAM and MCU time. + +Why would you want multi-display support? Here are some examples: + +- Have a "normal" TFT display with local UI and create "virtual" screens on VNC + on demand. (You need to add your VNC driver.) +- Have a large TFT display and a small monochrome display. +- Have some smaller and simple displays in a large instrument or technology. +- Have two large TFT displays: one for a customer and one for the shop assistant. + +If you set up LVGL to use more than one display, be aware that some functions use the +:ref:`default_display` during their execution, such as creating :ref:`screens`. + + + +.. _display_features: + +Display Features +**************** + + +.. _display_attributes: + +Attributes +---------- +Once created, a Display object remembers the characteristics of the display hardware +it is representing, as well as other things relevant to its lifetime: + +- Resolution (width and height in pixels) +- Color Depth (bits per pixel) +- Color Format (how colors in pixels are laid out) +- 4 :ref:`screen_layers` automatically created with each display +- All :ref:`screens` created in association with this display (and not yet deleted---only + one is dislayed at any given time) +- The :ref:`draw_buffers` assigned to it +- The :ref:`flush_callback` function that moves pixels from :ref:`draw_buffers` to Display hardware +- What areas of the display have been updated (made "dirty") so rendering logic can + compute what to render during a :ref:`display refresh ` +- Optional custom pointer as :ref:`display_user_data` + + +.. _screen_layers: + +Screen Layers +------------- + +When an ``lv_display_t`` object is created, 4 permanent :ref:`screens` that +facilitate layering are created and attached to it. + +1. Bottom Layer (below Active Screen, transparent, not scroll-able, but click-able) +2. :ref:`active_screen` +3. Top Layer (above Active Screen, transparent and neither scroll-able nor click-able) +4. System Layer (above Top Layer, transparent and neither scroll-able nor click-able) + +1, 3 and 4 are independent of the :ref:`active_screen` and they will be shown (if +they contain anything that is visible) regardless of which screen is the +:ref:`active_screen`. + +.. note:: + + For the bottom layer to be visible, the Active Screen's background has to be + at least partially, if not fully, transparent. + +You can get pointers to each of these screens on the :ref:`default_display` by using +(respectively): + +- :cpp:func:`lv_screen_active`, +- :cpp:func:`lv_layer_top`, +- :cpp:func:`lv_layer_sys`, and +- :cpp:func:`lv_layer_bottom`. + +You can get pointers to each of these screens on a specified display by using +(respectively): + +- :cpp:expr:`lv_display_get_screen_active(disp)`, +- :cpp:expr:`lv_display_get_layer_top(disp)`, +- :cpp:expr:`lv_display_get_layer_sys(disp)`, and +- :cpp:expr:`lv_display_get_layer_bottom(disp)`. + +To set a Screen you create to be the :ref:`active_screen`, call +:cpp:func:`lv_screen_load` or :cpp:func:`lv_screen_load_anim`. + +.. _layers_top_and_sys: + +Top and System Layers +~~~~~~~~~~~~~~~~~~~~~ + +LVGL uses the Top Layer and System Layer two empower you to ensure that certain +:ref:`widgets` are *always* on top of other layers. + +You can add "pop-up windows" to the *Top Layer* freely. The Top Layer was meant to +be used to create Widgets that are visible on all Screens shown on a Display. But, +the *System Layer* is intended for system-level things (e.g. mouse cursor will be +placed there with :cpp:func:`lv_indev_set_cursor`). + +These layers work like any other Widget, meaning they have styles, and any kind of +Widgets can be created in them. + +.. note:: + While the Top Layer and System Layer are created by their owning :ref:`display` + as not scroll-able and not click-able, these behaviors can be overridden the same + as any other Widget by using :cpp:expr:`lv_obj_set_scrollbar_mode(scr1, LV_SCROLLBAR_MODE_xxx)` + and :cpp:expr:`lv_obj_add_flag(scr1, LV_OBJ_FLAG_CLICKABLE)` respectively. + +If the :cpp:enumerator:`LV_OBJ_FLAG_CLICKABLE` flag is set on the Top Layer, then it will +absorb all user clicks and acts as a modal Widget. + +.. code-block:: c + + lv_obj_add_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE); + +.. _layers_bottom: + +Bottom Layer +~~~~~~~~~~~~ + +Similar to the Top- and System Layers, the Bottom Layer is also the full size of the +Display, but it is located below the :ref:`active_screen`. It's visible only if the +Active Screen's background opacity is < 255. + + + +.. _display_events: + +Display Events +************** + +:cpp:expr:`lv_display_add_event_cb(disp, event_cb, LV_EVENT_..., user_data)` adds +an event handler to a display. + +If you added ``user_data`` to the Display, you can retrieve it in an event like this: + +.. code-block:: c + + lv_dislay_t *display1; + my_type_t *my_user_data; + display1 = (lv_dislay_t *)lv_event_get_current_target(e); + my_user_data = lv_display_get_user_data(display1); + +The following events are sent: + +- :cpp:enumerator:`LV_EVENT_INVALIDATE_AREA` An area is invalidated (marked for redraw). + :cpp:expr:`lv_event_get_param(e)` returns a pointer to an :cpp:struct:`lv_area_t` + variable with the coordinates of the area to be invalidated. The area can + be freely modified if needed to adopt it the special requirement of the + display. Usually needed with monochrome displays to invalidate ``N x 8`` + rows or columns at once. +- :cpp:enumerator:`LV_EVENT_REFR_REQUEST`: Sent when something happened that requires redraw. +- :cpp:enumerator:`LV_EVENT_REFR_START`: Sent when a refreshing cycle starts. Sent even if there is nothing to redraw. +- :cpp:enumerator:`LV_EVENT_REFR_READY`: Sent when refreshing is ready (after rendering and calling the :ref:`flush_callback`). Sent even if no redraw happened. +- :cpp:enumerator:`LV_EVENT_RENDER_START`: Sent when rendering starts. +- :cpp:enumerator:`LV_EVENT_RENDER_READY`: Sent when rendering is ready (before calling the :ref:`flush_callback`) +- :cpp:enumerator:`LV_EVENT_FLUSH_START`: Sent before the :ref:`flush_callback` is called. +- :cpp:enumerator:`LV_EVENT_FLUSH_READY`: Sent when the :ref:`flush_callback` returned. +- :cpp:enumerator:`LV_EVENT_RESOLUTION_CHANGED`: Sent when the resolution changes due + to :cpp:func:`lv_display_set_resolution` or :cpp:func:`lv_display_set_rotation`. + + + +.. _display_setup: + +Display Setup +************* + + +.. _creating_a_display: + +Creating a Display +------------------ + +To create a display for LVGL: + +.. code-block:: c + + lv_display_t * display1 = lv_display_create(hor_res, ver_res) + +You can create :ref:`multiple dislays ` with a different driver for +each (see below). + +When an ``lv_display_t`` object is created, with it are created 4 Screens set up +to help you manage layering of displayed Widgets. See :ref:`transparent_screens` and +:ref:`screen_layers` for more information. + + +.. _default_display: + +Default Display +~~~~~~~~~~~~~~~ +When the first :ref:`display` object is created, it becomes the Default Display. If +other Display Objects are created (to service additional Display Panels), the Default +Display remains the first one created. + +To set another :ref:`display` as the Default Display, call :cpp:func:`lv_display_set_default`. + +See :ref:`multiple_dislays` for more information about using multiple displays. + +For many ``lv_display_...()`` functions, passing NULL for the ``disp`` argument will +cause the function to target the Default Display. Check the API documentation for +the function you are calling to be sure. + + +.. _draw_buffers: + +Draw Buffer(s) +-------------- + +During system initialization, you must set drawing buffers for LVGL to use for each +display. Do so by calling: + +.. code-block:: c + + lv_display_set_buffers(display1, buf1, buf2, buf_size_in_bytes, render_mode) + +- ``buf1`` a buffer to which LVGL can render pixels +- ``buf2`` a second optional buffer (see below) +- ``buf_size_in_bytes`` size of buffer(s) in bytes +- ``render_mode`` is one of the following: + + - :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_PARTIAL` Use the buffer(s) to render + to the display using buffers smaller than the size of the display. Use of + buffers at least 1/10 display size is recommended. In :ref:`flush_callback` the rendered + images needs to be copied to the given area of the display. In this mode if a + button is pressed only the button's area will be redrawn. + - :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_DIRECT` The buffer size(es) must match + the size of the display. LVGL will render into the correct location of the + buffer. Using this method the buffer(s) always contain the whole display image. + If two buffer are used, the rendered areas are automatically copied to the + other buffer after flushing. Due to this in :ref:`flush_callback` typically + only a frame buffer address needs to be changed. If a button is pressed + only the button's area will be redrawn. + - :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_FULL` The buffer size(es) must match + the size of the display. LVGL will always redraw the whole screen even if only + 1 pixel has been changed. If two display-sized draw buffers are provided, + LVGL's display handling works like "traditional" double buffering. This means + the :ref:`flush_callback` callback only has to update the address of the frame buffer to + the ``px_map`` parameter. + + +Simple Example +~~~~~~~~~~~~~~ + +.. code-block:: c + + /* Declare buffer for 1/10 screen size; BYTES_PER_PIXEL will be 2 for RGB565. */ + #define BYTES_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_RGB565)) + static uint8_t buf1[MY_DISP_HOR_RES * MY_DISP_VER_RES / 10 * BYTES_PER_PIXEL]; + /* Set display buffer for display `display1`. */ + lv_display_set_buffers(display1, buf1, NULL, sizeof(buf1), LV_DISPLAY_RENDER_MODE_PARTIAL); + +One Buffer +~~~~~~~~~~ + +If only one buffer is used, LVGL draws the content of the screen into +that draw buffer and sends it to the display via the :ref:`flush_callback`. LVGL +then waits until :cpp:func:`lv_display_flush_ready` is called +(that is, the content of the buffer has been sent to the +display) before drawing something new into it. + +Two Buffers +~~~~~~~~~~~ + +If two buffers are used LVGL can draw into one buffer while the content +of the other buffer is sent to the display in the background. DMA or +other hardware should be used to transfer data to the display so the MCU +can continue drawing. Doing so allows *rendering* and *refreshing* the +display to become parallel operations. + + +.. _flush_callback: + +Flush Callback +-------------- + +Draw buffer(s) are simple array(s) that LVGL uses to render the display's +content. Once rendering is has been completed, the content of the draw buffer is +sent to the display using a Flush Callback function. + +An example looks like this: + +.. code-block:: c + + void my_flush_cb(lv_display_t * display, const lv_area_t * area, uint8_t * px_map) + { + /* The most simple case (also the slowest) to send all rendered pixels to the + * screen one-by-one. `put_px` is just an example. It needs to be implemented by you. */ + uint16_t * buf16 = (uint16_t *)px_map; /* Let's say it's a 16 bit (RGB565) display */ + int32_t x, y; + for(y = area->y1; y <= area->y2; y++) { + for(x = area->x1; x <= area->x2; x++) { + put_px(x, y, *buf16); + buf16++; + } + } + + /* IMPORTANT!!! + * Inform LVGL that flushing is complete so buffer can be modified again. */ + lv_display_flush_ready(disp); + } + +During system initialization, tell LVGL you want that function to copy pixels from +rendered pixel-buffers to a particular display by doing the following: + +.. code-block:: c + + lv_display_set_flush_cb(display1, my_flush_cb) + +Note that which display is targeted is passed to the function, so you can use the +same function for multiple displays, or use different functions for multiple +displays. It's up to you. + +.. note:: + + :cpp:expr:`lv_display_flush_ready(display1)` needs to be called when flushing is + complete to inform LVGL that the buffer is available again to render new content + into it. + +LVGL might render the screen in multiple chunks and therefore call your Flush +Callback multiple times. To see whether the current call is for the last chunk being +rendered, use :cpp:expr:`lv_display_flush_is_last(display1)`. + + + +Advanced Options +**************** + + +Resolution +---------- + +To set the resolution of the display after creation use +:cpp:expr:`lv_display_set_resolution(display, hor_res, ver_res)` + +It's not mandatory to use the whole display for LVGL, however in some +cases the physical resolution is important. For example the touchpad +still sees the whole resolution and the values needs to be converted to +the active LVGL display area. So the physical resolution and the offset +of the active area can be set with +:cpp:expr:`lv_display_set_physical_resolution(disp, hor_res, ver_res)` and +:cpp:expr:`lv_display_set_offset(disp, x, y)` + + +Flush-Wait Callback +------------------- + +By using :cpp:func:`lv_display_flush_ready` LVGL will spin in a loop +while waiting for flushing. + +However with the help of :cpp:func:`lv_display_set_flush_wait_cb` a custom +wait callback be set for flushing. This callback can use a semaphore, mutex, +or anything else to optimize waiting for the flush to be completed. + +If a Flush-Wait Callback is not set, LVGL assumes that +:cpp:func:`lv_display_flush_ready` is used. + + +Rotation +-------- + +LVGL supports rotation of the display in 90 degree increments. You can +select whether you would like software rotation or hardware rotation. + +The orientation of the display can be changed with +``lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_0/90/180/270)``. +LVGL will swap the horizontal and vertical resolutions internally +according to the set degree. When changing the rotation +:cpp:enumerator:`LV_EVENT_SIZE_CHANGED` event is emitted (for any part of your system +that has "subscribed" to this event) to allow reconfiguring of the hardware. +In lack of hardware display rotation support +:cpp:func:`lv_draw_sw_rotate` can be used to rotate the buffer in the +:ref:`flush_callback`. + +:cpp:expr:`lv_display_rotate_area(display, &area)` rotates the rendered area +according to the current rotation settings of the display. + +Note that in :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_DIRECT` the small changed areas +are rendered directly in the frame buffer so they cannot be +rotated later. Therefore in direct mode only the whole frame buffer can be rotated. +The same is true for :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_FULL`. + +In the case of :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_PARTIAL` the small rendered areas +can be rotated on their own before flushing to the frame buffer. + + +Color Format +------------ + +The default color format of the display is set according to :c:macro:`LV_COLOR_DEPTH` +(see ``lv_conf.h``) + +- :c:macro:`LV_COLOR_DEPTH` ``32``: XRGB8888 (4 bytes/pixel) +- :c:macro:`LV_COLOR_DEPTH` ``24``: RGB888 (3 bytes/pixel) +- :c:macro:`LV_COLOR_DEPTH` ``16``: RGB565 (2 bytes/pixel) +- :c:macro:`LV_COLOR_DEPTH` ``8``: L8 (1 bytes/pixel) +- :c:macro:`LV_COLOR_DEPTH` ``1``: I1 (1 bit/pixel) Only support for horizontal mapped buffers. See :ref:`monochrome` for more details: + +The ``color_format`` can be changed with +:cpp:expr:`lv_display_set_color_depth(display, LV_COLOR_FORMAT_...)`. +Besides the default value :c:macro:`LV_COLOR_FORMAT_ARGB8888` can be +used as a well. + +It's very important that draw buffer(s) should be large enough for the +selected color format. + + +Swapping Endian-ness +-------------------- + +In case of RGB565 color format it might be required to swap the 2 bytes +because the SPI, I2C or 8 bit parallel port periphery sends them in the wrong order. + +The ideal solution is configure the hardware to handle the 16 bit data with different byte order, +however if this is not possible :cpp:expr:`lv_draw_sw_rgb565_swap(buf, buf_size_in_px)` +can be called in the :ref:`flush_callback` to swap the bytes. + +If you wish you can also write your own function, or use assembly instructions for +the fastest possible byte swapping. + +Note that this is not about swapping the Red and Blue channel but converting + +``RRRRR GGG | GGG BBBBB`` + +to + +``GGG BBBBB | RRRRR GGG``. + +.. _monochrome: + + +Monochrome Displays +------------------- + +LVGL supports rendering directly in a 1-bit format for monochrome displays. +To enable it, set ``LV_COLOR_DEPTH 1`` or use :cpp:expr:`lv_display_set_color_format(display, LV_COLOR_FORMAT_I1)`. + +The :cpp:expr:`LV_COLOR_FORMAT_I1` format assumes that bytes are mapped to rows (i.e., the bits of a byte are written next to each other). +The order of bits is MSB first, which means: + +.. code-block:: + + MSB LSB + bits 7 6 5 4 3 2 1 0 + +are represented on the display as: + +.. code-block:: + + pixels 0 1 2 3 4 5 6 7 + Left Right + +Ensure that the LCD controller is configured accordingly. + +Internally, LVGL rounds the redrawn areas to byte boundaries. Therefore, updated areas will: + +- start on an ``Nx8`` coordinate, and +- end on an ``Nx8 - 1`` coordinate. + +When setting up the buffers for rendering (:cpp:func:`lv_display_set_buffers`), make the buffer 8 bytes larger. +This is necessary because LVGL reserves 2 x 4 bytes in the buffer, as these are assumed to be used as a palette. + +To skip the palette, include the following line in your :ref:`flush_callback` function: ``px_map += 8``. + +As usual, monochrome displays support partial, full, and direct rendering modes as well. +In full and direct modes, the buffer size should be large enough for the whole screen, +meaning ``(horizontal_resolution x vertical_resolution / 8) + 8`` bytes. +As LVGL can not handle fractional width make sure to round the horizontal resolution +to 8 bits (for example 90 to 96). + + +Constraints on Redrawn Area +--------------------------- + +Some display controllers have specific requirements for the window area where the rendered image can be sent +(e.g., `x1` must be even, and `x2` must be odd). + +In the case of monochrome displays, `x1` must be `Nx8`, and `x2` must be `Nx8 - 1`. +(If the display uses `LV_COLOR_FORMAT_I1`, LVGL automatically applies this rounding. See :ref:`monochrome`.) + +The size of the invalidated (redrawn) area can be controlled as follows: + +.. code-block:: c + + void rounder_event_cb(lv_event_t * e) + { + lv_area_t * a = lv_event_get_invalidated_area(e); + + a->x1 = a->x1 & (~0x1); /* Ensure x1 is even */ + a->x2 = a->x2 | 0x1; /* Ensure x2 is odd */ + } + + ... + + lv_display_add_event_cb(disp, rounder_event_cb, LV_EVENT_INVALIDATE_AREA, NULL); + + +Tiled Rendering +--------------- + +When multiple CPU cores are available and a large area needs to be redrawn, LVGL must identify independent areas that can be rendered in parallel. + +For example, if there are 4 CPU cores, one core can draw the screen's background while the other 3 must wait until it is finished. If there are 2 buttons on the screen, those 2 buttons can be rendered in parallel, but 2 cores will still remain idle. + +Due to dependencies among different areas, CPU cores cannot always be fully utilized. + +To address this, LVGL can divide large areas that need to be updated into smaller tiles. These tiles are independent, making it easier to find areas that can be rendered concurrently. + +Specifically, if there are 4 tiles and 4 cores, there will always be an independent area for each core within one of the tiles. + +The maximum number of tiles can be set using the function :cpp:expr:`lv_display_set_tile_cnt(disp, cnt)`. The default value is :cpp:expr:`LV_DRAW_SW_DRAW_UNIT_CNT` (or 1 if software rendering is not enabled). + +Small areas are not further divided into smaller tiles because the overhead of spinning up 4 cores would outweigh the benefits. + +The ideal tile size is calculated as ``ideal_tile_size = draw_buf_size / tile_cnt``. For example, in :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_DIRECT` mode on an 800x480 screen, the display buffer is 800x480 = 375k pixels. If there are 4 tiles, the ideal tile size is approximately 93k pixels. Based on this, core utilization is as follows: + +- 30k pixels: 1 core +- 90k pixels: 1 core +- 95k pixels: 2 cores (above 93k pixels, 2 cores are used) +- 150k pixels: 2 cores +- 200k pixels: 3 cores (above 186k pixels, 3 cores are used) +- 300k pixels: 4 cores (above 279k pixels, 4 cores are used) +- 375k pixels: 4 cores + +In :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_DIRECT`, the screen-sized draw buffer is divided by the tile count to determine the ideal tile sizes. If smaller areas are refreshed, it may result in fewer cores being used. + +In :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_FULL`, the maximum number of tiles is always created when the entire screen is refreshed. + +In :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_PARTIAL`, the partial buffer is divided into tiles. For example, if the draw buffer is 1/10th the size of the screen and there are 2 tiles, then 1/20th + 1/20th of the screen area will be rendered at once. + +Tiled rendering only affects the rendering process, and the :ref:`flush_callback` is called once for each invalidated area. Therefore, tiling is not visible from the flushing point of view. + + +Decoupling the Display Refresh Timer +------------------------------------ + +Normally the dirty (a.k.a invalid) areas are checked and redrawn in +every :c:macro:`LV_DEF_REFR_PERIOD` milliseconds (set in ``lv_conf.h``). +However, in some cases you might need more control on when the display +refreshing happen, for example to synchronize rendering with VSYNC or +the TE signal. + +You can do this in the following way: + +.. code-block:: c + + /* Delete original display refresh timer */ + lv_display_delete_refr_timer(display1); + + /* Call this to refresh dirty (changed) areas of the display. */ + _lv_display_refr_timer(NULL); + +If you have multiple displays call :cpp:expr:`lv_display_set_default(display1)` to +select the display to refresh before :cpp:expr:`_lv_display_refr_timer(NULL)`. + + +.. note:: :cpp:func:`lv_timer_handler` and :cpp:func:`_lv_display_refr_timer` must not run at the same time. + + +If the performance monitor is enabled, the value of :c:macro:`LV_DEF_REFR_PERIOD` needs to be set to be +consistent with the refresh period of the display to ensure that the statistical results are correct. + + +Force Refreshing +---------------- + +Normally the invalidated areas (marked for redrawing) are rendered in +:cpp:func:`lv_timer_handler` in every :c:macro:`LV_DEF_REFR_PERIOD` milliseconds. +However, by using :cpp:expr:`lv_refr_now(display)` you can ask LVGL to redraw the +invalid areas immediately. The refreshing will happen in :cpp:func:`lv_refr_now` +which might take longer. + +The parameter of :cpp:func:`lv_refr_now` is a display to refresh. If ``NULL`` is set +the :ref:`default_display` will be updated. + + +Mirroring a Display +------------------- + +To mirror the image of a display to another display, you don't need to use +multi-display support. Just transfer the buffer received in the first display's +:ref:`flush_callback` to the other display as well. + + +Split Image +----------- + +You can create a larger virtual display from an array of smaller ones. +You can create it by: + +1. setting the resolution of the displays to the large display's resolution; +2. in :ref:`flush_callback`, truncate and modify the ``area`` parameter for each display; and +3. send the buffer's content to each real display with the truncated area. + + +.. _display_user_data: + +User Data +--------- + +With :cpp:expr:`lv_display_set_user_data(display1, p)` a custom pointer can be stored +with ``lv_display_t`` object. This pointer can be used later, e.g. in +:ref:`display_events`. + + +.. _display_inactivity: + +Inactivity Measurement +---------------------- + +A user's inactivity time is measured and stored with each ``lv_display_t`` object. +Every use of an :ref:`Input Device ` (if :ref:`associated with the display +`) counts as an activity. To get time elapsed since the last +activity, use :cpp:expr:`lv_display_get_inactive_time(display1)`. If ``NULL`` is +passed, the lowest inactivity time among all displays will be returned (in this case +NULL does *not* mean the :ref:`default_display`). + +You can manually trigger an activity using +:cpp:expr:`lv_display_trigger_activity(display1)`. If ``display1`` is ``NULL``, the +:ref:`default_display` will be used (**not all displays**). + + + + +.. admonition:: Further Reading + + - `lv_port_disp_template.c `__ + for a template for your own driver. + - :ref:`Drawing ` to learn more about how rendering works in LVGL. + + + +API +*** diff --git a/docs/porting/draw.rst b/docs/details/main-components/draw.rst similarity index 94% rename from docs/porting/draw.rst rename to docs/details/main-components/draw.rst index bad8a397a..c575a4648 100644 --- a/docs/porting/draw.rst +++ b/docs/details/main-components/draw.rst @@ -1,10 +1,10 @@ -.. _porting_draw: +.. _draw: -========== -Custom GPU -========== +================ +Drawing Pipeline +================ -LVGL has a flexible and extendable draw pipeline. You can hook it to do +LVGL has a flexible and extendable drawing pipeline. You can hook it to do some rendering with a GPU or even completely replace the built-in software renderer. diff --git a/docs/overview/font.rst b/docs/details/main-components/font.rst similarity index 87% rename from docs/overview/font.rst rename to docs/details/main-components/font.rst index 0da0d15d5..1141c18a9 100644 --- a/docs/overview/font.rst +++ b/docs/details/main-components/font.rst @@ -1,8 +1,8 @@ -.. _fonts: +.. _font: -===== -Fonts -===== +============== +Font (lv_font) +============== In LVGL fonts are collections of bitmaps and other information required to render images of individual letters (glyph). A font is stored in a @@ -11,7 +11,7 @@ For example: .. code-block:: c - lv_style_set_text_font(&my_style, &lv_font_montserrat_28); /*Set a larger font*/ + lv_style_set_text_font(&my_style, &lv_font_montserrat_28); /* Set a larger font */ Fonts have a **format** property. It describes how the glyph draw data is stored. It has *2* categories: `Legacy simple format` and `Advanced format`. @@ -26,6 +26,7 @@ The *format* property also affects the amount of memory needed to store a font. For example, *format = LV_FONT_GLYPH_FORMAT_A4* makes a font nearly four times larger compared to *format = LV_FONT_GLYPH_FORMAT_A1*. + Unicode support *************** @@ -43,11 +44,12 @@ To test it try If all works well, a ✓ character should be displayed. + Built-in fonts ************** There are several built-in fonts in different sizes, which can be -enabled in ``lv_conf.h`` with *LV_FONT\_…* defines. +enabled in ``lv_conf.h`` with *LV_FONT\_…* defines. Normal fonts ------------ @@ -117,7 +119,8 @@ Or more symbols together: lv_label_set_text(my_label, LV_SYMBOL_OK LV_SYMBOL_WIFI LV_SYMBOL_PLAY); -Special features + +Special Features **************** Bidirectional support @@ -127,8 +130,8 @@ Most languages use a Left-to-Right (LTR for short) writing direction, however some languages (such as Hebrew, Persian or Arabic) use Right-to-Left (RTL for short) direction. -LVGL not only supports RTL texts but supports mixed (a.k.a. -bidirectional, BiDi) text rendering too. Some examples: +LVGL not only supports RTL text but supports mixed (a.k.a. +bidirectional, BiDi) text rendering as well. Some examples: .. image:: /misc/bidi.png @@ -137,24 +140,24 @@ BiDi support is enabled by :c:macro:`LV_USE_BIDI` in *lv_conf.h* All texts have a base direction (LTR or RTL) which determines some rendering rules and the default alignment of the text (Left or Right). However, in LVGL, the base direction is not only applied to labels. It's -a general property which can be set for every object. If not set then it +a general property which can be set for every Widget. If not set then it will be inherited from the parent. This means it's enough to set the -base direction of a screen and every object will inherit it. +base direction of a screen and every Widget will inherit it. The default base direction for screens can be set by -:c:macro:`LV_BIDI_BASE_DIR_DEF` in *lv_conf.h* and other objects inherit the +:c:macro:`LV_BIDI_BASE_DIR_DEF` in *lv_conf.h* and other Widgets inherit the base direction from their parent. -To set an object's base direction use :cpp:expr:`lv_obj_set_style_base_dir(obj, base_dir, selector)`. +To set a Widget's base direction use :cpp:expr:`lv_obj_set_style_base_dir(widget, base_dir, selector)`. The possible base directions are: - :cpp:enumerator:`LV_BASE_DIR_LTR`: Left to Right base direction - :cpp:enumerator:`LV_BASE_DIR_RTL`: Right to Left base direction - :cpp:enumerator:`LV_BASE_DIR_AUTO`: Auto detect base direction -This list summarizes the effect of RTL base direction on objects: +This list summarizes the effect of RTL base direction on Widgets: -- Create objects by default on the right +- Create Widgets by default on the right - ``lv_tabview``: Displays tabs from right to left - ``lv_checkbox``: Shows the box on the right - ``lv_buttonmatrix``: Shows buttons from right to left @@ -237,8 +240,9 @@ To configure kerning at runtime, use :cpp:func:`lv_font_set_kerning`. .. _add_font: -Add a new font -************** + +Adding a New Font +***************** There are several ways to add a new font to your project: @@ -259,8 +263,9 @@ To declare a font in a file, use :cpp:expr:`LV_FONT_DECLARE(my_font_name)`. To make fonts globally available (like the built-in fonts), add them to :c:macro:`LV_FONT_CUSTOM_DECLARE` in *lv_conf.h*. -Add new symbols -*************** + +Adding New Symbols +****************** The built-in symbols are created from the `FontAwesome `__ font. @@ -290,8 +295,9 @@ The built-in symbols are created from the `FontAwesome adv_w = 12; /*Horizontal space required by the glyph in [px]*/ - dsc_out->box_h = 8; /*Height of the bitmap in [px]*/ - dsc_out->box_w = 6; /*Width of the bitmap in [px]*/ - dsc_out->ofs_x = 0; /*X offset of the bitmap in [pf]*/ - dsc_out->ofs_y = 3; /*Y offset of the bitmap measured from the as line*/ + dsc_out->adv_w = 12; /* Horizontal space required by the glyph in [px] */ + dsc_out->box_h = 8; /* Height of the bitmap in [px] */ + dsc_out->box_w = 6; /* Width of the bitmap in [px] */ + dsc_out->ofs_x = 0; /* X offset of the bitmap in [pf] */ + dsc_out->ofs_y = 3; /* Y offset of the bitmap measured from the as line */ dsc_out->format= LV_FONT_GLYPH_FORMAT_A2; - return true; /*true: glyph found; false: glyph was not found*/ + return true; /* true: glyph found; false: glyph was not found */ } @@ -475,11 +484,12 @@ To add a new font engine, a custom :cpp:type:`lv_font_t` variable needs to be cr /* The bitmap should be a continuous bitstream where * each pixel is represented by `bpp` bits */ - return bitmap; /*Or NULL if not found*/ + return bitmap; /* Or NULL if not found */ } -Use font fallback -***************** + +Using Font Fallback +******************* You can specify ``fallback`` in :cpp:type:`lv_font_t` to provide fallback to the font. When the font fails to find glyph to a letter, it will try to let @@ -496,6 +506,7 @@ font from ``fallback`` to handle. /* So now we can display Roboto for supported characters while having wider characters set support */ roboto->fallback = droid_sans_fallback; + .. _fonts_api: API diff --git a/docs/overview/fs.rst b/docs/details/main-components/fs.rst similarity index 78% rename from docs/overview/fs.rst rename to docs/details/main-components/fs.rst index 783513650..2713eb0be 100644 --- a/docs/overview/fs.rst +++ b/docs/details/main-components/fs.rst @@ -1,8 +1,8 @@ .. _overview_file_system: -=========== -File system -=========== +======================= +File System (lv_fs_drv) +======================= LVGL has a 'File system' abstraction module that enables you to attach any type of file system. A file system is identified by an assigned @@ -13,7 +13,7 @@ drive letter. For example, if an SD card is associated with the letter If you want to skip the drive prefix from the path, you can use the :c:macro:`LV_FS_DEFAULT_DRIVE_LETTER` config parameter. -Ready to use drivers +Ready-to-use drivers ******************** LVGL contains prepared drivers for the API of POSIX, standard C, @@ -32,27 +32,27 @@ and not a local variable. .. code-block:: c - static lv_fs_drv_t drv; /*Needs to be static or global*/ - lv_fs_drv_init(&drv); /*Basic initialization*/ + static lv_fs_drv_t drv; /* Needs to be static or global */ + lv_fs_drv_init(&drv); /* Basic initialization */ - drv.letter = 'S'; /*An uppercase letter to identify the drive */ - drv.cache_size = my_cache_size; /*Cache size for reading in bytes. 0 to not cache.*/ + drv.letter = 'S'; /* An uppercase letter to identify the drive */ + drv.cache_size = my_cache_size; /* Cache size for reading in bytes. 0 to not cache. */ - drv.ready_cb = my_ready_cb; /*Callback to tell if the drive is ready to use */ - drv.open_cb = my_open_cb; /*Callback to open a file */ - drv.close_cb = my_close_cb; /*Callback to close a file */ - drv.read_cb = my_read_cb; /*Callback to read a file */ - drv.write_cb = my_write_cb; /*Callback to write a file */ - drv.seek_cb = my_seek_cb; /*Callback to seek in a file (Move cursor) */ - drv.tell_cb = my_tell_cb; /*Callback to tell the cursor position */ + drv.ready_cb = my_ready_cb; /* Callback to tell if the drive is ready to use */ + drv.open_cb = my_open_cb; /* Callback to open a file */ + drv.close_cb = my_close_cb; /* Callback to close a file */ + drv.read_cb = my_read_cb; /* Callback to read a file */ + drv.write_cb = my_write_cb; /* Callback to write a file */ + drv.seek_cb = my_seek_cb; /* Callback to seek in a file (Move cursor) */ + drv.tell_cb = my_tell_cb; /* Callback to tell the cursor position */ - drv.dir_open_cb = my_dir_open_cb; /*Callback to open directory to read its content */ - drv.dir_read_cb = my_dir_read_cb; /*Callback to read a directory's content */ - drv.dir_close_cb = my_dir_close_cb; /*Callback to close a directory */ + drv.dir_open_cb = my_dir_open_cb; /* Callback to open directory to read its content */ + drv.dir_read_cb = my_dir_read_cb; /* Callback to read a directory's content */ + drv.dir_close_cb = my_dir_close_cb; /* Callback to close a directory */ - drv.user_data = my_user_data; /*Any custom data if required*/ + drv.user_data = my_user_data; /* Any custom data if required */ - lv_fs_drv_register(&drv); /*Finally register the drive*/ + lv_fs_drv_register(&drv); /* Finally register the drive */ Any of the callbacks can be ``NULL`` to indicate that operation is not supported. @@ -135,7 +135,7 @@ practice to insert a ``'/'`` in front of each directory name. break; } - /*fn is empty, if not more files to read*/ + /* fn is empty, if not more files to read */ if(strlen(fn) == 0) { break; } @@ -148,7 +148,7 @@ practice to insert a ``'/'`` in front of each directory name. Use drives for images ********************* -:ref:`Image ` objects can be opened from files too (besides +:ref:`Image ` Widgets can be opened from files as well (besides variables stored in the compiled program). To use files in image widgets the following callbacks are required: @@ -183,8 +183,8 @@ The implementation is documented below. Note that the FS functions make calls to other driver FS functions when the cache is enabled. i.e., ``lv_fs_read`` may call the driver's ``seek`` so the driver needs to implement more callbacks when the cache is enabled. -``lv_fs_read`` :sub:`(behavior when the cache is enabled)` ----------------------------------------------------------- +``lv_fs_read`` :sub:`(behavior when cache is enabled)` +------------------------------------------------------ .. mermaid:: :zoom: @@ -230,21 +230,21 @@ so the driver needs to implement more callbacks when the cache is enabled. --> P["copy the required bytes to the destination buffer"] -``lv_fs_write`` :sub:`(behavior when the cache is enabled)` ------------------------------------------------------------ +``lv_fs_write`` :sub:`(behavior when cache is enabled)` +------------------------------------------------------- The part of the cache that coincides with the written content will be updated to reflect the written content. -``lv_fs_seek`` :sub:`(behavior when the cache is enabled)` ----------------------------------------------------------- +``lv_fs_seek`` :sub:`(behavior when cache is enabled)` +------------------------------------------------------ The driver's ``seek`` will not actually be called unless the ``whence`` is ``LV_FS_SEEK_END``, in which case ``seek`` and ``tell`` will be called to determine where the end of the file is. -``lv_fs_tell`` :sub:`(behavior when the cache is enabled)` ----------------------------------------------------------- +``lv_fs_tell`` :sub:`(behavior when cache is enabled)` +------------------------------------------------------ The driver's ``tell`` will not actually be called. diff --git a/docs/overview/image.rst b/docs/details/main-components/image.rst similarity index 93% rename from docs/overview/image.rst rename to docs/details/main-components/image.rst index c5eef716d..3eb9619d6 100644 --- a/docs/overview/image.rst +++ b/docs/details/main-components/image.rst @@ -1,8 +1,8 @@ .. _overview_image: -====== -Images -====== +================= +Images (lv_image) +================= An image can be a file or a variable which stores the bitmap itself and some metadata. @@ -146,27 +146,27 @@ variable to display it using LVGL. For example: .header.w = 80, .header.h = 60, .data_size = 80 * 60 * LV_COLOR_DEPTH / 8, - .header.cf = LV_COLOR_FORMAT_NATIVE, /*Set the color format*/ + .header.cf = LV_COLOR_FORMAT_NATIVE, /* Set the color format */ .data = my_img_data, }; Another (possibly simpler) option to create and display an image at -run-time is to use the :ref:`Canvas ` object. +run-time is to use the :ref:`Canvas ` Widget. Use images ---------- The simplest way to use an image in LVGL is to display it with an -:ref:`lv_image` object: +:ref:`lv_image` Widget: .. code-block:: c lv_obj_t * icon = lv_image_create(lv_screen_active(), NULL); - /*From variable*/ + /* From variable */ lv_image_set_src(icon, &my_icon_dsc); - /*From file*/ + /* From file */ lv_image_set_src(icon, "S:my_icon.bin"); If the image was converted with the online converter, you should use @@ -240,7 +240,7 @@ open/close the PNG files. It should look like this: .. code-block:: c - /*Create a new decoder and register functions */ + /* Create a new decoder and register functions */ lv_image_decoder_t * dec = lv_image_decoder_create(); lv_image_decoder_set_info_cb(dec, decoder_info); lv_image_decoder_set_open_cb(dec, decoder_open); @@ -257,7 +257,7 @@ open/close the PNG files. It should look like this: */ static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header) { - /*Check whether the type `src` is known by the decoder*/ + /* Check whether the type `src` is known by the decoder */ if(is_png(src) == false) return LV_RESULT_INVALID; /* Read the PNG header and find `width` and `height` */ @@ -276,18 +276,18 @@ open/close the PNG files. It should look like this: */ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc) { - (void) decoder; /*Unused*/ + (void) decoder; /* Unused */ - /*Check whether the type `src` is known by the decoder*/ + /* Check whether the type `src` is known by the decoder */ if(is_png(dsc->src) == false) return LV_RESULT_INVALID; - /*Decode and store the image. If `dsc->decoded` is `NULL`, the `decoder_get_area` function will be called to get the image data line-by-line*/ + /* Decode and store the image. If `dsc->decoded` is `NULL`, the `decoder_get_area` function will be called to get the image data line-by-line */ dsc->decoded = my_png_decoder(dsc->src); - /*Change the color format if decoded image format is different than original format. For PNG it's usually decoded to ARGB8888 format*/ + /* Change the color format if decoded image format is different than original format. For PNG it's usually decoded to ARGB8888 format */ dsc->decoded.header.cf = LV_COLOR_FORMAT_... - /*Call a binary image decoder function if required. It's not required if `my_png_decoder` opened the image in true color format.*/ + /* Call a binary image decoder function if required. It's not required if `my_png_decoder` opened the image in true color format. */ lv_result_t res = lv_bin_decoder_open(decoder, dsc); return res; @@ -359,13 +359,13 @@ open/close the PNG files. It should look like this: */ static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc) { - /*Free all allocated data*/ + /* Free all allocated data */ my_png_cleanup(); my_decoder_data_t * my_decoder_data = dsc->user_data; lv_draw_buf_destroy(my_decoder_data->partial); - /*Call the built-in close function if the built-in open/get_area was used*/ + /* Call the built-in close function if the built-in open/get_area was used */ lv_bin_decoder_close(decoder, dsc); } @@ -390,8 +390,8 @@ Manually use an image decoder ----------------------------- LVGL will use registered image decoders automatically if you try and -draw a raw image (i.e. using the ``lv_image`` object) but you can use them -manually too. Create an :cpp:type:`lv_image_decoder_dsc_t` variable to describe +draw a raw image (i.e. using the ``lv_image`` Widget) but you can use them +manually as well. Create an :cpp:type:`lv_image_decoder_dsc_t` variable to describe the decoding session and call :cpp:func:`lv_image_decoder_open`. The ``color`` parameter is used only with ``LV_COLOR_FORMAT_A1/2/4/8`` @@ -402,11 +402,11 @@ images to tell color of the image. lv_result_t res; lv_image_decoder_dsc_t dsc; - lv_image_decoder_args_t args = { 0 }; /*Custom decoder behavior via args*/ + lv_image_decoder_args_t args = { 0 }; /* Custom decoder behavior via args */ res = lv_image_decoder_open(&dsc, &my_img_dsc, &args); if(res == LV_RESULT_OK) { - /*Do something with `dsc->decoded`. You can copy out the decoded image by `lv_draw_buf_dup(dsc.decoded)`*/ + /* Do something with `dsc->decoded`. You can copy out the decoded image by `lv_draw_buf_dup(dsc.decoded)`*/ lv_image_decoder_close(&dsc); } @@ -567,7 +567,7 @@ Clean the cache --------------- Let's say you have loaded a PNG image into a :cpp:struct:`lv_image_dsc_t` ``my_png`` -variable and use it in an ``lv_image`` object. If the image is already +variable and use it in an ``lv_image`` Widget. If the image is already cached and you then change the underlying PNG file, you need to notify LVGL to cache the image again. Otherwise, there is no easy way of detecting that the underlying file changed and LVGL will still draw the @@ -620,7 +620,7 @@ following code to replace the LVGL built-in cache manager: void my_cache_init(void) { - /*Initialize new cache manager.*/ + /* Initialize new cache manager. */ lv_cache_manager_t my_manager; my_manager.add_cb = my_cache_add_cb; my_manager.find_cb = my_cache_find_cb; @@ -630,7 +630,7 @@ following code to replace the LVGL built-in cache manager: my_manager.set_max_size_cb = my_cache_set_max_size_cb; my_manager.empty_cb = my_cache_empty_cb; - /*Replace existing cache manager with the new one.*/ + /* Replace existing cache manager with the new one. */ lv_cache_lock(); lv_cache_set_manager(&my_manager); lv_cache_unlock(); diff --git a/docs/details/main-components/indev.rst b/docs/details/main-components/indev.rst new file mode 100644 index 000000000..7ac1b96c0 --- /dev/null +++ b/docs/details/main-components/indev.rst @@ -0,0 +1,501 @@ +.. _indev: + +======================= +Input Device (lv_indev) +======================= + + +.. _indev_creation: + +Creating an Input Device +************************ + +To create an input device on the :ref:`default_display`: + +.. code-block:: c + + /* Create and set up at least one display before you register any input devices. */ + lv_indev_t * indev = lv_indev_create(); /* Create input device connected to Default Display. */ + lv_indev_set_type(indev, LV_INDEV_TYPE_...); /* Touch pad is a pointer-like device. */ + lv_indev_set_read_cb(indev, my_input_read); /* Set driver function. */ + +If you have multiple displays, you will need to ensure the Default Display is set +to the display your input device is "connected to" before making the above calls. + +The ``type`` member can be: + +- :cpp:enumerator:`LV_INDEV_TYPE_POINTER`: touchpad or mouse +- :cpp:enumerator:`LV_INDEV_TYPE_KEYPAD`: keyboard or keypad +- :cpp:enumerator:`LV_INDEV_TYPE_ENCODER`: encoder with left/right turn and push options +- :cpp:enumerator:`LV_INDEV_TYPE_BUTTON`: external buttons virtually pressing the screen + +``my_input_read`` is a function pointer which will be called periodically to +report the current state of an input device to LVGL. + + + +Touchpad, Touch-Screen, Mouse or Any Pointer +-------------------------------------------- + +Input devices that can click points on the display belong to the POINTER +category. Here is an example of a simple input-device Read Callback function: + +.. code-block:: c + + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + ... + + void my_input_read(lv_indev_t * indev, lv_indev_data_t * data) + { + if(touchpad_pressed) { + data->point.x = touchpad_x; + data->point.y = touchpad_y; + data->state = LV_INDEV_STATE_PRESSED; + } else { + data->state = LV_INDEV_STATE_RELEASED; + } + } + + +.. _indev_cursor: + +Mouse Cursor +~~~~~~~~~~~~ + +Pointer input devices (like a mouse) can have a cursor. + +.. code-block:: c + + ... + lv_indev_t * mouse_indev = lv_indev_create(); + ... + LV_IMAGE_DECLARE(mouse_cursor_icon); /* Declare the image source. */ + lv_obj_t * cursor_obj = lv_image_create(lv_screen_active()); /* Create image Widget for cursor. */ + lv_image_set_src(cursor_obj, &mouse_cursor_icon); /* Set image source. */ + lv_indev_set_cursor(mouse_indev, cursor_obj); /* Connect image to Input Device. */ + +Note that the cursor object should have +:cpp:expr:`lv_obj_remove_flag(cursor_obj, LV_OBJ_FLAG_CLICKABLE)`. +For images, *clicking* is disabled by default. + + +.. _indev_gestures: + +Gestures +~~~~~~~~ + +Pointer input devices can detect basic gestures. By default, most Widgets send +gestures to their parents so they can be detected on the Screen Widget in the +form of an :cpp:enumerator:`LV_EVENT_GESTURE` event. For example: + +.. code-block:: c + + void my_event(lv_event_t * e) + { + lv_obj_t * screen = lv_event_get_current_target(e); + lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_active()); + switch(dir) { + case LV_DIR_LEFT: + ... + break; + case LV_DIR_RIGHT: + ... + break; + case LV_DIR_TOP: + ... + break; + case LV_DIR_BOTTOM: + ... + break; + } + } + + ... + + lv_obj_add_event_cb(screen1, my_event, LV_EVENT_GESTURE, NULL); + +To prevent passing the gesture event to the parent from a Widget, use +:cpp:expr:`lv_obj_remove_flag(widget, LV_OBJ_FLAG_GESTURE_BUBBLE)`. + +Note that, gestures are not triggered if a Widget is being scrolled. + +If you did some action on a gesture you can call +:cpp:expr:`lv_indev_wait_release(lv_indev_active())` in the event handler to +prevent LVGL sending further input-device-related events. + + +.. _indev_crown: + +Crown Behavior +~~~~~~~~~~~~~~ + +A "Crown" is a rotary device typically found on smart watches. + +When the user clicks somewhere and after that turns the rotary +the last clicked widget will be either scrolled or it's value will be incremented/decremented +(e.g. in case of a slider). + +As this behavior is tightly related to the last clicked widget, the crown support is +an extension of the pointer input device. Just set ``data->diff`` to the number of +turned steps and LVGL will automatically send the :cpp:enumerator:`LV_EVENT_ROTARY` +event or scroll the widget based on the ``editable`` flag in the widget's class. +Non-editable widgets are scrolled and for editable widgets the event is sent. + +To get the steps in an event callback use ``int32_t diff = lv_event_get_rotary_diff(e)`` + +The rotary sensitivity can be adjusted on 2 levels: + +1. in the input device by the ``indev->rotary_sensitivity`` element (1/256 unit), and +2. by the ``rotary_sensitivity`` style property in the widget (1/256 unit). + +The final diff is calculated like this: + +``diff_final = diff_in * (indev_sensitivity / 256) + (widget_sensitivity / 256);`` + + +For example, if both the indev and widget sensitivity is set to 128 (0.5), the input +diff will be multiplied by 0.25. The value of the Widget will be incremented by that +value or the Widget will be scrolled that amount of pixels. + + +Keypad or Keyboard +------------------ + +Full keyboards with all the letters or simple keypads with a few navigation buttons +belong in the keypad category. + +You can fully control the user interface without a touchpad or mouse by using a +keypad or encoder. It works similar to the *TAB* key on the PC to select an element +in an application or web page. + +To use a keyboard or keypad: + +- Register a Read Callback function for your device and set its type to + :cpp:enumerator:`LV_INDEV_TYPE_KEYPAD`. +- Create a Widget Group (``lv_group_t * g = lv_group_create()``) and add Widgets to + it with :cpp:expr:`lv_group_add_obj(g, widget)`. +- Assign the group to an input device: :cpp:expr:`lv_indev_set_group(indev, g)`. +- Use ``LV_KEY_...`` to navigate among the Widgets in the group. See + ``lv_core/lv_group.h`` for the available keys. + +.. code-block:: c + + lv_indev_set_type(indev, LV_INDEV_TYPE_KEYPAD); + + ... + + void keyboard_read(lv_indev_t * indev, lv_indev_data_t * data){ + data->key = last_key(); /* Get the last pressed or released key */ + + if(key_pressed()) data->state = LV_INDEV_STATE_PRESSED; + else data->state = LV_INDEV_STATE_RELEASED; + } + + +Encoder +------- + +A common example of an encoder is a device with a turning knob that tells the hosting +device *when* the knob is being turned, and *in which direction*. + +With an encoder your application can receive events from the following: + +1. press of its button, +2. oong-press of its button, +3. turn left, and +4. turn right. + +In short, the Encoder input devices work like this: + +- By turning the encoder you can focus on the next/previous object. +- When you press the encoder on a simple object (like a button), it will be clicked. +- If you press the encoder on a complex object (like a list, message box, etc.) + the Widget will go to edit mode whereby you can navigate inside the + object by turning the encoder. +- To leave edit mode, long press the button. + +To use an Encoder (similar to the *Keypads*) the Widgets should be added to a group. + +.. code-block:: c + + lv_indev_set_type(indev, LV_INDEV_TYPE_ENCODER); + + ... + + void encoder_read(lv_indev_t * indev, lv_indev_data_t * data){ + data->enc_diff = enc_get_new_moves(); + + if(enc_pressed()) data->state = LV_INDEV_STATE_PRESSED; + else data->state = LV_INDEV_STATE_RELEASED; + } + + +.. _indev_groups: + +Widget Groups +------------- +When input focus needs to be managed among a set of Widgets (e.g. to capture user +input from a keypad or encoder), that set of Widgets is placed in a group which +thereafter manages how input focus moves from Widget to Widget. + +In each group there is exactly one object with focus which receives the pressed keys +or the encoder actions. For example, if a :ref:`Text Area ` has focus +and you press some letter on a keyboard, the keys will be sent and inserted into the +text area. Similarly, if a :ref:`Slider ` has focus and you press the +left or right arrows, the slider's value will be changed. + +You need to associate an input device with a group. An input device can +send key events to only one group but a group can receive data from more +than one input device. + +To create a group use :cpp:expr:`lv_group_t * g = lv_group_create()` and to add +a Widget to the group use :cpp:expr:`lv_group_add_obj(g, widget)`. + +Once a Widget has been added to a group, you can find out what group it is in +using :cpp:expr:`lv_obj_get_group(widget)`. + +To find out if a Widget in a group has focus, call :cpp:expr:`lv_obj_is_focused(widget)`. +If the Widget is not part of a group, this function will return ``false``. + +To associate a group with an input device use :cpp:expr:`lv_indev_set_group(indev, g)`. + + + +.. _indev_keys: + +Keys +~~~~ + +There are some predefined keys which have special meaning: + +- :cpp:enumerator:`LV_KEY_NEXT`: Move focus to next object +- :cpp:enumerator:`LV_KEY_PREV`: Move focus to previous object +- :cpp:enumerator:`LV_KEY_ENTER`: Triggers :cpp:enumerator:`LV_EVENT_PRESSED`, :cpp:enumerator:`LV_EVENT_CLICKED`, or :cpp:enumerator:`LV_EVENT_LONG_PRESSED` etc. events +- :cpp:enumerator:`LV_KEY_UP`: Increase value or move up +- :cpp:enumerator:`LV_KEY_DOWN`: Decrease value or move down +- :cpp:enumerator:`LV_KEY_RIGHT`: Increase value or move to the right +- :cpp:enumerator:`LV_KEY_LEFT`: Decrease value or move to the left +- :cpp:enumerator:`LV_KEY_ESC`: Close or exit (e.g. close a :ref:`Drop-Down List `) +- :cpp:enumerator:`LV_KEY_DEL`: Delete (e.g. a character on the right in a :ref:`Text Area `) +- :cpp:enumerator:`LV_KEY_BACKSPACE`: Delete (e.g. a character on the left in a :ref:`Text Area `) +- :cpp:enumerator:`LV_KEY_HOME`: Go to the beginning/top (e.g. in a :ref:`Text Area `) +- :cpp:enumerator:`LV_KEY_END`: Go to the end (e.g. in a :ref:`Text Area `) + +The most important special keys in your :cpp:func:`read_cb` function are: + +- :cpp:enumerator:`LV_KEY_NEXT` +- :cpp:enumerator:`LV_KEY_PREV` +- :cpp:enumerator:`LV_KEY_ENTER` +- :cpp:enumerator:`LV_KEY_UP` +- :cpp:enumerator:`LV_KEY_DOWN` +- :cpp:enumerator:`LV_KEY_LEFT` +- :cpp:enumerator:`LV_KEY_RIGHT` + +You should translate some of your keys to these special keys to support navigation +in a group and interact with selected Widgets. + +Usually, it's enough to use only :cpp:enumerator:`LV_KEY_LEFT` and :cpp:enumerator:`LV_KEY_RIGHT` because most +Widgets can be fully controlled with them. + +With an encoder you should use only :cpp:enumerator:`LV_KEY_LEFT`, :cpp:enumerator:`LV_KEY_RIGHT`, +and :cpp:enumerator:`LV_KEY_ENTER`. + +Edit and Navigate Mode +~~~~~~~~~~~~~~~~~~~~~~ + +Since a keypad has plenty of keys, it's easy to navigate between Widgets +and edit them using the keypad. But encoders have a limited number of +"keys" and hence it is difficult to navigate using the default options. +*Navigate* and *Edit* modes are used to avoid this problem with +encoders. + +In *Navigate* mode, an encoder's :cpp:enumerator:`LV_KEY_LEFT` or :cpp:enumerator:`LV_KEY_RIGHT` is translated to +:cpp:enumerator:`LV_KEY_NEXT` or :cpp:enumerator:`LV_KEY_PREV`. Therefore, the next or previous object will be +selected by turning the encoder. Pressing :cpp:enumerator:`LV_KEY_ENTER` will change +to *Edit* mode. + +In *Edit* mode, :cpp:enumerator:`LV_KEY_NEXT` and :cpp:enumerator:`LV_KEY_PREV` is usually used to modify an +object. Depending on the Widget's type, a short or long press of +:cpp:enumerator:`LV_KEY_ENTER` changes back to *Navigate* mode. Usually, a Widget +which cannot be pressed (like a :ref:`Slider `) leaves +*Edit* mode upon a short click. But with Widgets where a short click has +meaning (e.g. :ref:`Button `), a long press is required. + +Default Group +~~~~~~~~~~~~~ + +Interactive widgets (such as Buttons, Checkboxes, Sliders, etc.) can +be automatically added to a default group. Just create a group with +:cpp:expr:`lv_group_t * g = lv_group_create()` and set the default group with +:cpp:expr:`lv_group_set_default(g)` + +Don't forget to assign one or more input devices to the default group +with :cpp:expr:`lv_indev_set_group(my_indev, g)`. + +Styling +------- + +When a Widget receives focus either by clicking it via touchpad or by navigating to +it with an encoder or keypad, it goes to the :cpp:enumerator:`LV_STATE_FOCUSED` +state. Hence, focused styles will be applied to it. + +If a Widget switches to edit mode it enters the +:cpp:expr:`LV_STATE_FOCUSED | LV_STATE_EDITED` states so any style properties +assigned to these states will be shown. + +See :ref:`styles` for more details. + + + + +Using Buttons with Encoder Logic +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In addition to standard encoder behavior, you can also utilize its logic +to navigate(focus) and edit widgets using buttons. This is especially +handy if you have only few buttons available, or you want to use other +buttons in addition to an encoder wheel. + +You need to have 3 buttons available: + +- :cpp:enumerator:`LV_KEY_ENTER`: will simulate press or pushing of the encoder button. +- :cpp:enumerator:`LV_KEY_LEFT`: will simulate turning encoder left. +- :cpp:enumerator:`LV_KEY_RIGHT`: will simulate turning encoder right. +- other keys will be passed to the focused widget. + +If you hold the keys it will simulate an encoder advance with period +specified in ``indev_drv.long_press_repeat_time``. + +.. code-block:: c + + + lv_indev_set_type(indev, LV_INDEV_TYPE_ENCODER); + + ... + + void encoder_with_keys_read(lv_indev_t * indev, lv_indev_data_t * data){ + data->key = last_key(); /* Get the last pressed or released key */ + /* use LV_KEY_ENTER for encoder press */ + if(key_pressed()) data->state = LV_INDEV_STATE_PRESSED; + else { + data->state = LV_INDEV_STATE_RELEASED; + /* Optionally you can also use enc_diff, if you have encoder */ + data->enc_diff = enc_get_new_moves(); + } + } + + +Hardware Button +--------------- + +A *Hardware Button* here is an external button (switch) typically next to the screen +which is assigned to specific coordinates of the screen. If a button is pressed it +will simulate the pressing on the assigned coordinate, similar to a touchpad. + +To assign Hardware Buttons to coordinates use ``lv_indev_set_button_points(my_indev, +points_array)``. ``points_array`` should look like ``const lv_point_t points_array[] += { {12,30}, {60,90}, ...}`` + +.. admonition:: Important: + + ``points_array`` cannot be allowed to go out of scope. Either declare it as a + global variable or as a static variable inside a function. + +.. code-block:: c + + lv_indev_set_type(indev, LV_INDEV_TYPE_BUTTON); + + ... + + void button_read(lv_indev_t * indev, lv_indev_data_t * data){ + static uint32_t last_btn = 0; /* Store the last pressed button */ + int btn_pr = my_btn_read(); /* Get the ID (0,1,2...) of the pressed button */ + if(btn_pr >= 0) { /* Is there a button press? (E.g. -1 indicated no button was pressed) */ + last_btn = btn_pr; /* Save the ID of the pressed button */ + data->state = LV_INDEV_STATE_PRESSED; /* Set the pressed state */ + } else { + data->state = LV_INDEV_STATE_RELEASED; /* Set the released state */ + } + + data->btn_id = last_btn; /* Save the last button */ + } + +When the ``button_read`` callback in the example above changes the ``data->btn_id`` to ``0`` +a press/release action at the first index of the ``points_array`` will be performed (``{12,30}``). + + +.. _indev_other_features: + +Other Features +************** + +Parameters +---------- + +The default value of the following parameters can be changed in :cpp:type:`lv_indev_t`: + +- ``scroll_limit`` Number of pixels to slide before actually scrolling the Widget +- ``scroll_throw`` Scroll throw (momentum) slow-down in [%]. Greater value means faster slow-down. +- ``long_press_time`` Press time to send :cpp:enumerator:`LV_EVENT_LONG_PRESSED` (in milliseconds) +- ``long_press_repeat_time`` Interval of sending :cpp:enumerator:`LV_EVENT_LONG_PRESSED_REPEAT` (in milliseconds) +- ``read_timer`` pointer to the ``lv_timer`` which reads the input device. Its parameters + can be changed by calling ``lv_timer_...()`` functions. :c:macro:`LV_DEF_REFR_PERIOD` + in ``lv_conf.h`` sets the default read period. + +Feedback +-------- + +Besides ``read_cb`` a ``feedback_cb`` callback can be also specified in +:cpp:type:`lv_indev_t`. ``feedback_cb`` is called when any type of event is sent +by input devices (independently of their type). This allows generating +feedback for the user, e.g. to play a sound on :cpp:enumerator:`LV_EVENT_CLICKED`. + +Buffered Reading +---------------- + +By default, LVGL calls ``read_cb`` periodically. Because of this +intermittent polling there is a chance that some user gestures are +missed. + +To solve this you can write an event driven driver for your input device +that buffers measured data. In ``read_cb`` you can report the buffered +data instead of directly reading the input device. Setting the +``data->continue_reading`` flag will tell LVGL there is more data to +read and it should call ``read_cb`` again. + +Switching the Input Device to Event-Driven Mode +----------------------------------------------- + +Normally an Input Device is read every :c:macro:`LV_DEF_REFR_PERIOD` +milliseconds (set in ``lv_conf.h``). However, in some cases, you might +need more control over when to read the input device. For example, you +might need to read it by polling a file descriptor (fd). + +You can do this by: + +.. code-block:: c + + /* Update the input device's running mode to LV_INDEV_MODE_EVENT */ + lv_indev_set_mode(indev, LV_INDEV_MODE_EVENT); + + ... + + /* Call this anywhere you want to read the input device */ + lv_indev_read(indev); + +.. note:: :cpp:func:`lv_indev_read`, :cpp:func:`lv_timer_handler` and :cpp:func:`_lv_display_refr_timer` cannot run at the same time. + +.. note:: For devices in event-driven mode, `data->continue_reading` is ignored. + + +.. admonition:: Further Reading + + - `lv_port_indev_template.c `__ + for a template for your own Input-Device driver. + + + +.. _indev_api: + +API +*** diff --git a/docs/details/main-components/index.rst b/docs/details/main-components/index.rst new file mode 100644 index 000000000..32750229e --- /dev/null +++ b/docs/details/main-components/index.rst @@ -0,0 +1,18 @@ +.. _main_components: + +=============== +Main Components +=============== + +.. toctree:: + :maxdepth: 2 + + display + indev + color + font + image + timer + animation + fs + draw diff --git a/docs/overview/timer.rst b/docs/details/main-components/timer.rst similarity index 85% rename from docs/overview/timer.rst rename to docs/details/main-components/timer.rst index 817a68967..1b15837ec 100644 --- a/docs/overview/timer.rst +++ b/docs/details/main-components/timer.rst @@ -1,13 +1,13 @@ -.. _timers: +.. _timer: -====== -Timers -====== +================ +Timer (lv_timer) +================ LVGL has a built-in timer system. You can register a function to have it be called periodically. The timers are handled and called in :cpp:func:`lv_timer_handler`, which needs to be called every few milliseconds. -See `Porting `__ for more information. +See :ref:`timer_handler` for more information. Timers are non-preemptive, which means a timer cannot interrupt another timer. Therefore, you can call any LVGL related function in a timer. @@ -30,11 +30,11 @@ For example: void my_timer(lv_timer_t * timer) { - /*Use the user_data*/ + /* Use the user_data */ uint32_t * user_data = timer->user_data; printf("my_timer called with user data: %d\n", *user_data); - /*Do something with LVGL*/ + /* Do something with LVGL */ if(something_happened) { something_happened = false; lv_button_create(lv_screen_active(), NULL); @@ -104,7 +104,7 @@ Asynchronous calls ****************** In some cases, you can't perform an action immediately. For example, you -can't delete an object because something else is still using it, or you +can't delete a Widget because something else is still using it, or you don't want to block the execution now. For these cases, :cpp:expr:`lv_async_call(my_function, data_p)` can be used to call ``my_function`` on the next invocation of :cpp:func:`lv_timer_handler`. @@ -121,24 +121,24 @@ For example: void my_screen_clean_up(void * scr) { - /*Free some resources related to `scr`*/ + /* Free some resources related to `scr`*/ - /*Finally delete the screen*/ + /* Finally delete the screen */ lv_obj_delete(scr); } ... - /*Do something with the object on the current screen*/ + /* Do something with the Widget on the current screen */ - /*Delete screen on next call of `lv_timer_handler`, not right now.*/ + /* Delete screen on next call of `lv_timer_handler`, not right now. */ lv_async_call(my_screen_clean_up, lv_screen_active()); - /*The screen is still valid so you can do other things with it*/ + /* The screen is still valid so you can do other things with it */ -If you just want to delete an object and don't need to clean anything up +If you just want to delete a Widget and don't need to clean anything up in ``my_screen_cleanup`` you could just use :cpp:func:`lv_obj_delete_async` which -will delete the object on the next call to :cpp:func:`lv_timer_handler`. +will delete the Widget on the next call to :cpp:func:`lv_timer_handler`. .. _timer_api: diff --git a/docs/others/file_explorer.rst b/docs/details/other-components/file_explorer.rst similarity index 94% rename from docs/others/file_explorer.rst rename to docs/details/other-components/file_explorer.rst index 4443919b9..9138c9153 100644 --- a/docs/others/file_explorer.rst +++ b/docs/details/other-components/file_explorer.rst @@ -59,7 +59,7 @@ Sort You can use :cpp:expr:`lv_file_explorer_set_sort(file_explorer, LV_EXPLORER_SORT_XX)` to set -sorting method. +sorting method. There are the following sorting methods: @@ -92,8 +92,8 @@ selected file in the event processing function. For example: lv_obj_t * obj = lv_event_get_target(e); if(code == LV_EVENT_VALUE_CHANGED) { - char * cur_path = lv_file_explorer_get_cur_path(obj); - char * sel_fn = lv_file_explorer_get_sel_fn(obj); + char * cur_path = lv_file_explorer_get_cur_path(widget); + char * sel_fn = lv_file_explorer_get_sel_fn(widget); LV_LOG_USER("%s%s", cur_path, sel_fn); } } @@ -106,7 +106,7 @@ through functions such as :cpp:func:`strcpy` and :cpp:func:`strcat` for later us Example ------- -.. include:: ../examples/others/file_explorer/index.rst +.. include:: ../../examples/others/file_explorer/index.rst .. _file_explorer_api: diff --git a/docs/others/font_manager.rst b/docs/details/other-components/font_manager.rst similarity index 60% rename from docs/others/font_manager.rst rename to docs/details/other-components/font_manager.rst index d153883aa..3942bf88b 100644 --- a/docs/others/font_manager.rst +++ b/docs/details/other-components/font_manager.rst @@ -4,31 +4,36 @@ Font Manager ============ -Font Manager is a secondary encapsulation based on :ref:`_freetype`, which facilitates upper-level applications to manage and use vector fonts. -Currently supported functions include: +Font Manager is a secondary encapsulation based on :ref:`freetype`, which +facilitates upper-level applications to manage and use vector fonts. Currently +supported functions include: + - Font resource reference counting (reduces repeated creation of font resources). - Font resource concatenation (font fallback). - Font resource recycling mechanism (buffers recently deleted font resources to reduce the time overhead of repeated creation). + .. _font_manager_usage: Usage ------ +***** Enable :c:macro:`LIB_FREETYPE` and `LV_USE_FONT_MANAGER` in ``lv_conf.h``. Configure :c:macro:`LV_FONT_MANAGER_NAME_MAX_LEN` to set the maximum length of the font name. Initialize Font Manager -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- -Use :cpp:func:`lv_font_manager_create` to create a font manager, where the :cpp:func:`recycle_cache_size` parameter -is used to set the number of font recycling caches,which can improve font creation efficiency. +Use :cpp:func:`lv_font_manager_create` to create a font manager, where the +:cpp:func:`recycle_cache_size` parameter is used to set the number of font recycling +caches,which can improve font creation efficiency. -Use :cpp:func:`lv_font_manager_add_path_static` to add a mapping between the font file path and the custom font name, -so that the application can access the font resources more conveniently. -It should be noted that if the file path is not static (assigned from a local variable), -please use :cpp:func:`lv_font_manager_add_path` to add the path. This API will copy the path content to the internal management. +Use :cpp:func:`lv_font_manager_add_path_static` to add a mapping between the font +file path and the custom font name, so that the application can access the font +resources more conveniently. It should be noted that if the file path is not static +(assigned from a local variable), please use :cpp:func:`lv_font_manager_add_path` to +add the path. This API will copy the path content to the internal management. Use :cpp:func:`lv_font_manager_remove_path` to remove the font path mapping. @@ -47,11 +52,15 @@ Use :cpp:func:`lv_font_manager_remove_path` to remove the font path mapping. } Create Font from Font Manager -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------- -Use :cpp:func:`lv_font_manager_create_font` to create a font. The parameters are basically the same as :cpp:func:`lv_freetype_font_create`. -The :cpp:func:`font_family` parameter can be filled with the names of multiple fonts (separated by :cpp:expr:`,`) -to achieve font concatenation (when the corresponding glyph is not found in a font file, it will automatically search from the next concatenated font). +Use :cpp:func:`lv_font_manager_create_font` to create a font. The parameters are +basically the same as :cpp:func:`lv_freetype_font_create`. + +The :cpp:func:`font_family` parameter can be filled with the names of multiple fonts +(separated by ``,``) to achieve font concatenation (when the corresponding glyph is +not found in a font file, it will automatically search from the next concatenated +font). .. code-block:: c @@ -70,11 +79,14 @@ to achieve font concatenation (when the corresponding glyph is not found in a fo lv_label_set_text(label, "Hello World!"); Delete Font -~~~~~~~~~~~ +----------- Use :cpp:func:`lv_font_manager_delete_font` to delete the font. -The font manager will mark the font resource as a recyclable font so that it can be quickly created next time. -Note that you need to delete the widget that references the font first, and then delete the font to avoid accessing wild pointers. +The font manager will mark the font resource as a recyclable font so that it can be +quickly created next time. + +Note that you need to delete the widget that references the font first, and then +delete the font to avoid accessing wild pointers. .. code-block:: c @@ -84,21 +96,23 @@ Note that you need to delete the widget that references the font first, and then g_font = NULL; Delete Font Manager -~~~~~~~~~~~~~~~~~~~ +------------------- + +Use :cpp:func:`lv_font_manager_delete` to destroy the entire font manager. It should +be noted that before destruction, it is necessary to ensure that the application has +deleted all fonts using :cpp:func:`lv_font_manager_delete_font`. The font manager +will check the reference status of all allocated fonts. If there are still fonts +being referenced, the font manager will fail to destroy and return false. -Use :cpp:func:`lv_font_manager_delete` to destroy the entire font manager. It should be noted that before destruction, -it is necessary to ensure that the application has deleted all fonts using :cpp:func:`lv_font_manager_delete_font`. -The font manager will check the reference status of all allocated fonts. If there are still fonts being referenced, -the font manager will fail to destroy and return false. .. _font_manager_example: Example -------- +******* -.. include:: ../examples/others/font_manager/index.rst +.. include:: ../../examples/others/font_manager/index.rst .. _font_manager_api: API ---- +*** diff --git a/docs/others/fragment.rst b/docs/details/other-components/fragment.rst similarity index 92% rename from docs/others/fragment.rst rename to docs/details/other-components/fragment.rst index 0b0a29ce0..55db7e16b 100644 --- a/docs/others/fragment.rst +++ b/docs/details/other-components/fragment.rst @@ -10,7 +10,7 @@ Fragment is a concept copied from It represents a reusable portion of your app's UI. A fragment defines and manages its own layout, has its own lifecycle, and can handle its own events. Like Android's Fragment that must be hosted by an activity -or another fragment, Fragment in LVGL needs to be hosted by an object, +or another fragment, Fragment in LVGL needs to be hosted by a Widget, or another fragment. The fragment's view hierarchy becomes part of, or attaches to, the host's view hierarchy. @@ -55,7 +55,7 @@ Use ``lv_fragment_manager`` .. code-block:: c - /* Create fragment instance, and objects will be added to container */ + /* Create fragment instance, and Widgets will be added to container */ lv_fragment_manager_t *manager = lv_fragment_manager_create(container, NULL); /* Replace current fragment with instance of sample_cls, and init_argument is user defined pointer */ lv_fragment_manager_replace(manager, &sample_cls, init_argument); @@ -78,7 +78,7 @@ Fragment Based Navigation Example ------- -.. include:: ../examples/others/fragment/index.rst +.. include:: ../../examples/others/fragment/index.rst .. _fragment_api: diff --git a/docs/others/gridnav.rst b/docs/details/other-components/gridnav.rst similarity index 72% rename from docs/others/gridnav.rst rename to docs/details/other-components/gridnav.rst index 74e2722c1..04730d9b3 100644 --- a/docs/others/gridnav.rst +++ b/docs/details/other-components/gridnav.rst @@ -5,7 +5,7 @@ Grid navigation =============== Grid navigation (gridnav for short) is a feature that changes the -currently focused child object as arrow keys are pressed. +currently focused child Widget as arrow keys are pressed. If the children are arranged into a grid-like layout then the up, down, left and right arrows move focus to the nearest sibling in the @@ -20,10 +20,10 @@ Gridnav also works if the children are arranged into a single row or column. That makes it useful, for example, to simplify navigation on a :ref:`List widget `. -Gridnav assumes that the object to which gridnav is added is part of a -:ref:`group `. This way, if the object with -gridnav is focused, the arrow key presses are automatically forwarded to -the object so that gridnav can process the arrow keys. +Gridnav assumes that the Widget to which gridnav is added is part of a +:ref:`group `. This way, if the Widget with +gridnav has focus, the arrow key presses are automatically forwarded to +the Widget so that gridnav can process the arrow keys. To move the focus to the next widget of the group use :cpp:enumerator:`LV_KEY_NEXT` or :cpp:enumerator:`LV_KEY_PREV`. @@ -39,33 +39,33 @@ gridnav will automatically scroll the child into view. Usage ----- -To add the gridnav feature to an object use +To add the gridnav feature to a Widget use :cpp:expr:`lv_gridnav_add(cont, flags)`. ``flags`` control the behavior of gridnav: - :cpp:enumerator:`LV_GRIDNAV_CTRL_NONE`: Default settings -- :cpp:enumerator:`LV_GRIDNAV_CTRL_ROLLOVER`: If there is no next/previous object in a - direction, the focus goes to the object in the next/previous row (on +- :cpp:enumerator:`LV_GRIDNAV_CTRL_ROLLOVER`: If there is no next/previous Widget in a + direction, the focus goes to the Widget in the next/previous row (on left/right keys) or first/last row (on up/down keys) - :cpp:enumerator:`LV_GRIDNAV_CTRL_SCROLL_FIRST`: If an arrow is pressed and the focused - object can be scrolled in that direction then it will be scrolled instead of - going to the next/previous object. If there is no more room for scrolling the - next/previous object will be focused normally + Widget can be scrolled in that direction then it will be scrolled instead of + going to the next/previous Widget. If there is no more room for scrolling the + next/previous Widget will be focused normally - :cpp:enumerator:`LV_GRIDNAV_CTRL_HORIZONTAL_MOVE_ONLY`: Only use the left/right keys - for grid navigation. Up/down key events will be sent to the focused object. + for grid navigation. Up/down key events will be sent to the focused Widget. - :cpp:enumerator:`LV_GRIDNAV_CTRL_VERTICAL_MOVE_ONLY`: Only use the up/down keys - for grid navigation. Left/right key events will be sent to the focused object. + for grid navigation. Left/right key events will be sent to the focused Widget. :cpp:enumerator:`LV_GRIDNAV_CTRL_HORIZONTAL_MOVE_ONLY` and :cpp:enumerator:`LV_GRIDNAV_CTRL_VERTICAL_MOVE_ONLY` should not be used together. -:cpp:expr:`lv_gridnav_remove(cont)` Removes gridnav from an object. +:cpp:expr:`lv_gridnav_remove(cont)` Removes gridnav from a Widget. -Focusable objects +Focusable Widgets ----------------- -An object needs to be clickable or click focusable +A Widget needs to be clickable or click focusable (:cpp:enumerator:`LV_OBJ_FLAG_CLICKABLE` or :cpp:enumerator:`LV_OBJ_FLAG_CLICK_FOCUSABLE`) and not hidden (:cpp:enumerator:`LV_OBJ_FLAG_HIDDEN`) to be focusable by gridnav. @@ -74,7 +74,7 @@ hidden (:cpp:enumerator:`LV_OBJ_FLAG_HIDDEN`) to be focusable by gridnav. Example ------- -.. include:: ../examples/others/gridnav/index.rst +.. include:: ../../examples/others/gridnav/index.rst .. _gridnav_api: diff --git a/docs/others/ime_pinyin.rst b/docs/details/other-components/ime_pinyin.rst similarity index 98% rename from docs/others/ime_pinyin.rst rename to docs/details/other-components/ime_pinyin.rst index 229792435..25382fe0e 100644 --- a/docs/others/ime_pinyin.rst +++ b/docs/details/other-components/ime_pinyin.rst @@ -118,7 +118,7 @@ The default mode is :cpp:enumerator:`LV_IME_PINYIN_MODE_K26`. Example ------- -.. include:: ../examples/others/ime/index.rst +.. include:: ../../examples/others/ime/index.rst .. _ime_pinyin_api: diff --git a/docs/others/imgfont.rst b/docs/details/other-components/imgfont.rst similarity index 85% rename from docs/others/imgfont.rst rename to docs/details/other-components/imgfont.rst index 96e401333..f769ad93c 100644 --- a/docs/others/imgfont.rst +++ b/docs/details/other-components/imgfont.rst @@ -18,8 +18,8 @@ Enable :c:macro:`LV_USE_IMGFONT` in ``lv_conf.h``. To create a new *imgfont* use :cpp:expr:`lv_imgfont_create(height, path_cb, user_data)`. -- ``height`` Font size. -- ``path_cb`` A function to get the image path of a character. +- ``height`` Font size. +- ``path_cb`` A function to get the image path of a character. Return ``NULL`` if no image should be shown, but the character itself. - ``user_data`` Pointer to user data. @@ -33,7 +33,7 @@ To destroy the *imgfont* that is no longer used, use :cpp:expr:`lv_imgfont_destr Example ------- -.. include:: ../examples/others/imgfont/index.rst +.. include:: ../../examples/others/imgfont/index.rst .. _lv_imgfont_api: diff --git a/docs/others/index.rst b/docs/details/other-components/index.rst similarity index 79% rename from docs/others/index.rst rename to docs/details/other-components/index.rst index c6a4a0bb3..769703559 100644 --- a/docs/others/index.rst +++ b/docs/details/other-components/index.rst @@ -1,8 +1,8 @@ .. _others: -====== -Others -====== +================ +Other Components +================ .. toctree:: :maxdepth: 1 diff --git a/docs/others/monkey.rst b/docs/details/other-components/monkey.rst similarity index 88% rename from docs/others/monkey.rst rename to docs/details/other-components/monkey.rst index 79b84aeda..9624610ee 100644 --- a/docs/others/monkey.rst +++ b/docs/details/other-components/monkey.rst @@ -14,7 +14,8 @@ Usage Enable :c:macro:`LV_USE_MONKEY` in ``lv_conf.h``. First configure monkey, use :c:struct:`lv_monkey_config_t` to define the -configuration structure, set the ``type`` (check `input devices `__ for the supported types), and then set the +configuration structure, set the ``type`` (check :ref:`Input Devices ` +for the supported types), and then set the range of ``period_range`` and ``input_range``, the monkey will output random operations at random times within this range. Call :cpp:func:`lv_monkey_create` to create monkey. Finally call @@ -38,7 +39,7 @@ Note that ``input_range`` has different meanings in different ``type``: Example ------- -.. include:: ../examples/others/monkey/index.rst +.. include:: ../../examples/others/monkey/index.rst .. _monkey_api: diff --git a/docs/others/obj_id.rst b/docs/details/other-components/obj_id.rst similarity index 61% rename from docs/others/obj_id.rst rename to docs/details/other-components/obj_id.rst index d215465c3..bb7c91779 100644 --- a/docs/others/obj_id.rst +++ b/docs/details/other-components/obj_id.rst @@ -1,12 +1,12 @@ .. _obj_id: -====== -OBJ ID -====== +========= +Widget ID +========= -LVGL provides an optional field in :cpp:type:`lv_obj_t` to store the object ID. -Object ID can be used in many cases, for example, to identify the object. -Or we can store a program backtrace to where the object is created. +LVGL provides an optional field in :cpp:type:`lv_obj_t` to store the Widget ID. +Widget ID can be used in many cases, for example, to identify the Widget. +Or we can store a program backtrace to where the Widget is created. .. _obj_id_usage: @@ -15,13 +15,13 @@ Usage Enable this feature by setting :c:macro:`LV_USE_OBJ_ID` to `1` in ``lv_conf.h``. -Enable :c:macro:`LV_OBJ_ID_AUTO_ASSIGN` to automatically assign an ID to object when it's created. +Enable :c:macro:`LV_OBJ_ID_AUTO_ASSIGN` to automatically assign an ID to Widget when it's created. It's done by calling function :cpp:func:`lv_obj_assign_id` from :cpp:func:`lv_obj_constructor`. You can either use your own ID generator by defining the function :cpp:func:`lv_obj_assign_id` or you can utilize the built-in one. To use the builtin ID generator, set :c:macro:`LV_USE_OBJ_ID_BUILTIN` to `1`. -You can directly access the ID by :cpp:expr:`lv_obj_get_id(obj)` or use API :cpp:expr:`lv_obj_stringify_id(obj, buf, len)` +You can directly access the ID by :cpp:expr:`lv_obj_get_id(widget)` or use API :cpp:expr:`lv_obj_stringify_id(widget, buf, len)` to get a string representation of the ID. Use custom ID generator @@ -33,26 +33,26 @@ Below APIs needed to be implemented and linked to lvgl. .. code-block:: c - void lv_obj_set_id(lv_obj_t * obj, void * id); - void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj); - void lv_obj_free_id(lv_obj_t * obj); - const char * lv_obj_stringify_id(lv_obj_t * obj, char * buf, uint32_t len); + void lv_obj_set_id(lv_obj_t * widget, void * id); + void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * widget); + void lv_obj_free_id(lv_obj_t * widget); + const char * lv_obj_stringify_id(lv_obj_t * widget, char * buf, uint32_t len); int lv_obj_id_compare(void * id1, void * id2); -:cpp:func:`lv_obj_assign_id` is called when an object is created. The object final class is passed from +:cpp:func:`lv_obj_assign_id` is called when a Widget is created. The Widget final class is passed from parameter ``class_p``. Note it may be different than :cpp:expr:`obj->class_p` which is the class currently being constructed. -:cpp:func:`lv_obj_free_id` is called when object is deconstructed. Free any resource allocated in :cpp:func:`lv_obj_assign_id`. +:cpp:func:`lv_obj_free_id` is called when Widget is deconstructed. Free any resource allocated in :cpp:func:`lv_obj_assign_id`. :cpp:func:`lv_obj_stringify_id` converts id to a string representation. The string is stored in ``buf``. -Dump obj tree -~~~~~~~~~~~~~ +Dump Widget Tree +~~~~~~~~~~~~~~~~ -Use API ``lv_obj_dump_tree(lv_obj_t * obj, int depth)`` to dump the object tree. -It will walk through all children and print the object ID together with object address. +Use API ``lv_obj_dump_tree(lv_obj_t * widget, int depth)`` to dump the Widget Tree. +It will walk through all children and print the Widget ID together with Widget address. This is useful to debug UI crash. From log we can rebuilt UI the moment before crash. For example, if the obj is stored to a :cpp:expr:`timer->user_data`, but obj is deleted when timer expired. @@ -62,5 +62,5 @@ From the dump log we can clearly see that the obj does not exist. Find child by ID ~~~~~~~~~~~~~~~~ -Use API ``lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, void * id)`` to find a child by ID. +Use API ``lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * widget, void * id)`` to find a child by ID. It will walk through all children and return the first child with the given ID. diff --git a/docs/others/obj_property.rst b/docs/details/other-components/obj_property.rst similarity index 89% rename from docs/others/obj_property.rst rename to docs/details/other-components/obj_property.rst index 03ef29590..0d779634d 100644 --- a/docs/others/obj_property.rst +++ b/docs/details/other-components/obj_property.rst @@ -23,10 +23,10 @@ Set :c:macro:`LV_USE_OBJ_PROPERTY_NAME` to `1` in order to use property name ins typedef struct { lv_prop_id_t id; union { - int32_t num; /**< Number integer number (opacity, enums, booleans or "normal" numbers)*/ - const void * ptr; /**< Constant pointers (font, cone text, etc)*/ - lv_color_t color; /**< Colors*/ - lv_value_precise_t precise; /**< float or int for precise value*/ + int32_t num; /**< Number integer number (opacity, enums, booleans or "normal" numbers) */ + const void * ptr; /**< Constant pointers (font, cone text, etc) */ + lv_color_t color; /**< Colors */ + lv_value_precise_t precise; /**< float or int for precise value */ struct { lv_style_value_t style; /**< Make sure it's the first element in struct. */ uint32_t selector; /**< Style selector, lv_part_t | lv_state_t */ @@ -34,8 +34,8 @@ Set :c:macro:`LV_USE_OBJ_PROPERTY_NAME` to `1` in order to use property name ins }; } lv_property_t; - lv_result_t lv_obj_set_property(lv_obj_t * obj, const lv_property_t * value); - lv_property_t lv_obj_get_property(lv_obj_t * obj, lv_prop_id_t id); + lv_result_t lv_obj_set_property(lv_obj_t * widget, const lv_property_t * value); + lv_property_t lv_obj_get_property(lv_obj_t * widget, lv_prop_id_t id); lv_prop_id_t lv_obj_property_get_id(const lv_obj_class_t * clz, const char * name); @@ -86,4 +86,4 @@ all properties to an array now and set properties with a for loop. { .id = LV_STYLE_BG_COLOR, .color = (lv_color_t){.red = 0x11, .green = 0x22, .blue = 0x33}, }, } - LV_OBJ_SET_PROPERTY_ARRAY(obj, props); + LV_OBJ_SET_PROPERTY_ARRAY(widget, props); diff --git a/docs/others/observer.rst b/docs/details/other-components/observer.rst similarity index 85% rename from docs/others/observer.rst rename to docs/details/other-components/observer.rst index 4aefcfbbf..f32307435 100644 --- a/docs/others/observer.rst +++ b/docs/details/other-components/observer.rst @@ -155,7 +155,7 @@ In the observer callback :cpp:expr:`lv_observer_get_target(observer)` can be use .. code-block:: c - lv_observer_t * observer = lv_subject_add_observer_obj(&some_subject, some_observer_cb, obj, user_data); + lv_observer_t * observer = lv_subject_add_observer_obj(&some_subject, some_observer_cb, widget, user_data); In more generic case any pointer can be saved a target: @@ -178,7 +178,7 @@ To unsubscribe a widget from a given or all subject use: .. code-block:: c - lv_obj_remove_from_subject(obj, subject); /* `subject` can be NULL to unsubcribe from all */ + lv_obj_remove_from_subject(widget, subject); /* `subject` can be NULL to unsubcribe from all */ .. _observer_subject_groups: @@ -202,10 +202,10 @@ this array as a parameter when you initialize a subject with group type. .. code-block:: c static lv_subject_t * subject_list[3] = {&subject_1, &subject_2, &subject_3}; - lv_subject_init_group(&subject_all, subject_list, 3); /*The last parameter is the number of elements*/ + lv_subject_init_group(&subject_all, subject_list, 3); /*The last parameter is the number of elements */ You can add observers to subject groups in the regular way. -The trick is that when any element of the group is notified the subject group will be notified too. +The trick is that when any element of the group is notified the subject group will be notified as well. The above Voltage/Current measurement example looks like this in the practice: @@ -248,38 +248,38 @@ The above Voltage/Current measurement example looks like this in the practice: Widget binding ************** -Base object +Base Widget ----------- -Set an object flag if an integer subject's value is equal to a reference value, clear the flag otherwise +Set a Widget flag if an integer subject's value is equal to a reference value, clear the flag otherwise .. code-block:: c - observer = lv_obj_bind_flag_if_eq(obj, &subject, LV_OBJ_FLAG_*, ref_value); + observer = lv_obj_bind_flag_if_eq(widget, &subject, LV_OBJ_FLAG_*, ref_value); -Set an object flag if an integer subject's value is not equal to a reference value, clear the flag otherwise +Set a Widget flag if an integer subject's value is not equal to a reference value, clear the flag otherwise .. code-block:: c - observer = lv_obj_bind_flag_if_not_eq(obj, &subject, LV_OBJ_FLAG_*, ref_value); + observer = lv_obj_bind_flag_if_not_eq(widget, &subject, LV_OBJ_FLAG_*, ref_value); -Set an object state if an integer subject's value is equal to a reference value, clear the flag otherwise +Set a Widget state if an integer subject's value is equal to a reference value, clear the flag otherwise .. code-block:: c - observer = lv_obj_bind_state_if_eq(obj, &subject, LV_STATE_*, ref_value); + observer = lv_obj_bind_state_if_eq(widget, &subject, LV_STATE_*, ref_value); -Set an object state if an integer subject's value is not equal to a reference value, clear the flag otherwise +Set a Widget state if an integer subject's value is not equal to a reference value, clear the flag otherwise .. code-block:: c - observer = lv_obj_bind_state_if_not_eq(obj, &subject, LV_STATE_*, ref_value); + observer = lv_obj_bind_state_if_not_eq(widget, &subject, LV_STATE_*, ref_value); -Set an integer subject to 1 when an object is checked and set it 0 when unchecked. +Set an integer subject to 1 when a Widget is checked and set it 0 when unchecked. .. code-block:: c - observer = lv_obj_bind_checked(obj, &subject); + observer = lv_obj_bind_checked(widget, &subject); Label ----- @@ -290,7 +290,7 @@ If the format string is ``NULL`` the value will be used directly. In this case o .. code-block:: c - observer = lv_label_bind_text(obj, &subject, format_string); + observer = lv_label_bind_text(widget, &subject, format_string); Arc @@ -300,7 +300,7 @@ Bind an integer subject to an arc's value. .. code-block:: c - observer = lv_arc_bind_value(obj, &subject); + observer = lv_arc_bind_value(widget, &subject); Slider ------ @@ -309,7 +309,7 @@ Bind an integer subject to a slider's value .. code-block:: c - observer = lv_slider_bind_value(obj, &subject); + observer = lv_slider_bind_value(widget, &subject); Roller ------ @@ -318,7 +318,7 @@ Bind an integer subject to a roller's value .. code-block:: c - observer = lv_roller_bind_value(obj, &subject); + observer = lv_roller_bind_value(widget, &subject); Drop-down @@ -327,14 +327,14 @@ Bind an integer subject to a drop-down's value .. code-block:: c - observer = lv_dropdown_bind_value(obj, &subject); + observer = lv_dropdown_bind_value(widget, &subject); .. _observer_example: Example ******* -.. include:: ../examples/others/observer/index.rst +.. include:: ../../examples/others/observer/index.rst .. _observer_api: diff --git a/docs/others/snapshot.rst b/docs/details/other-components/snapshot.rst similarity index 77% rename from docs/others/snapshot.rst rename to docs/details/other-components/snapshot.rst index 266c5badb..23ac8e520 100644 --- a/docs/others/snapshot.rst +++ b/docs/details/other-components/snapshot.rst @@ -4,8 +4,8 @@ Snapshot ======== -Snapshot provides API to take snapshot image for LVGL object together -with its children. The image will look exactly like the object on display. +Snapshot provides API to take snapshot image for LVGL Widget together +with its children. The image will look exactly like the Widget on display. .. _snapshot_usage: @@ -13,7 +13,7 @@ Usage ----- Simply call API :cpp:func:`lv_snapshot_take` to generate the image descriptor -which can be set as image object src using :cpp:func:`lv_image_set_src`. +which can be set as image Widget src using :cpp:func:`lv_image_set_src`. Note, only following color formats are supported for now: @@ -38,13 +38,13 @@ Below code snippet explains usage of this API. .. code-block:: c - void update_snapshot(lv_obj_t * obj, lv_obj_t * img_snapshot) + void update_snapshot(lv_obj_t * widget, lv_obj_t * img_snapshot) { lv_draw_buf_t* snapshot = (void*)lv_image_get_src(img_snapshot); if(snapshot) { lv_draw_buf_destroy(snapshot); } - snapshot = lv_snapshot_take(obj, LV_COLOR_FORMAT_ARGB8888); + snapshot = lv_snapshot_take(widget, LV_COLOR_FORMAT_ARGB8888); lv_image_set_src(img_snapshot, snapshot); } @@ -52,14 +52,14 @@ Use Existing Buffer ~~~~~~~~~~~~~~~~~~~ If the snapshot needs update now and then, or simply caller provides memory, use API -``lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, lv_draw_buf_t * draw_buf);`` +``lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * widget, lv_color_format_t cf, lv_draw_buf_t * draw_buf);`` for this case. It's caller's responsibility to create and destroy the draw buffer. If snapshot is generated successfully, the image descriptor is updated and image data will be stored to provided ``buf``. Note that snapshot may fail if provided buffer is not enough, which may -happen when object size changes. It's recommended to use API +happen when Widget size changes. It's recommended to use API :cpp:func:`lv_snapshot_reshape_draw_buf` to prepare the buffer firstly and if it fails, destroy the existing draw buffer and call `lv_snapshot_take` directly. @@ -68,7 +68,7 @@ fails, destroy the existing draw buffer and call `lv_snapshot_take` directly. Example ------- -.. include:: ../examples/others/snapshot/index.rst +.. include:: ../../examples/others/snapshot/index.rst .. _snapshot_api: diff --git a/docs/widgets/animimg.rst b/docs/details/widgets/animimg.rst similarity index 66% rename from docs/widgets/animimg.rst rename to docs/details/widgets/animimg.rst index 2fdf13fe9..dda3a5329 100644 --- a/docs/widgets/animimg.rst +++ b/docs/details/widgets/animimg.rst @@ -7,9 +7,9 @@ Animation Image (lv_animimg) Overview ******** -The animation image is similar to the normal 'Image' object. The only +The animation image is similar to the normal 'Image' Widget. The only difference is that instead of one source image, you set an array of -multiple source images. +multiple source images that supply "frames" in an animation. You can specify a duration and repeat count. @@ -38,37 +38,49 @@ Using the inner animation For more advanced use cases, the animation internally used by the image can be retrieved using the :cpp:expr:`lv_animimg_get_anim(image)`. This way, the -:ref:`Animation ` functions can be used, for example to +:ref:`Animation ` functions can be used, for example to override the animation values using the :cpp:expr:`lv_anim_set_values(anim, start, end)` or to set a callback on the animation completed event. + + .. _lv_animimg_events: Events ****** -No special events are sent by image objects. +No special events are sent by Animation-Image Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. -See the events of the Base object too. -Learn more about :ref:`events`. .. _lv_animimg_keys: Keys **** -No Keys are processed by the object type. +No *Keys* are processed by Animation-Image Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + -Learn more about :ref:`indev_keys`. .. _lv_animimg_example: Example ******* -.. include:: ../examples/widgets/animimg/index.rst +.. include:: ../../examples/widgets/animimg/index.rst + + .. _lv_animimg_api: diff --git a/docs/widgets/arc.rst b/docs/details/widgets/arc.rst similarity index 89% rename from docs/widgets/arc.rst rename to docs/details/widgets/arc.rst index 04280cfaf..9c9f03607 100644 --- a/docs/widgets/arc.rst +++ b/docs/details/widgets/arc.rst @@ -45,7 +45,7 @@ To set the start and end angle of the background arc use the :cpp:expr:`lv_arc_set_bg_angles(arc, start_angle, end_angle)` functions or ``lv_arc_set_bg_start/end_angle(arc, angle)``. -Zero degrees is at the middle right (3 o'clock) of the object and the +Zero degrees is at the middle right (3 o'clock) of the Widget and the degrees are increasing in clockwise direction. The angles should be in the [0;360] range. @@ -98,7 +98,7 @@ exclusively use one or the other. Mixing the two might result in unintended behavior. To make the arc non-adjustable, remove the style of the knob and make -the object non-clickable: +the Widget non-clickable: .. code-block:: c @@ -108,27 +108,27 @@ the object non-clickable: Interactive area ---------------- -By default :cpp:enumerator:`LV_OBJ_FLAG_ADV_HITTEST` is disabled which -means the arc's whole area is interactive. +By default :cpp:enumerator:`LV_OBJ_FLAG_ADV_HITTEST` is disabled which +means the arc's whole area is interactive. As usual :cpp:func:`lv_obj_set_ext_click_size` can be used to increase the sensitive area outside the arc by a specified number of pixels. -If :cpp:enumerator:`LV_OBJ_FLAG_ADV_HITTEST` is enabled the arc will be sensitive only -in the range of start and end background angles and on the arc itself (not inside the arc). +If :cpp:enumerator:`LV_OBJ_FLAG_ADV_HITTEST` is enabled the arc will be sensitive only +in the range of start and end background angles and on the arc itself (not inside the arc). In this case ``ext_click_size`` makes the sensitive area ticker both inward and outward. -Additionally, a tolerance of :cpp:expr:`lv_dpx(50)` pixels is applied to each angle, extending the +Additionally, a tolerance of :cpp:expr:`lv_dpx(50)` pixels is applied to each angle, extending the hit-test range along the arc's length. -Place another object to the knob +Place another Widget to the knob -------------------------------- -Another object can be positioned according to the current position of +Another Widget can be positioned according to the current position of the arc in order to follow the arc's current value (angle). To do this use :cpp:expr:`lv_arc_align_obj_to_angle(arc, obj_to_align, radius_offset)`. Similarly :cpp:expr:`lv_arc_rotate_obj_to_angle(arc, obj_to_rotate, radius_offset)` can be -used to rotate the object to the current value of the arc. +used to rotate the Widget to the current value of the arc. It's a typical use case to call these functions in the ``VALUE_CHANGED`` event of the arc. @@ -163,9 +163,14 @@ Events - ``draw_area``: the area of the knob - ``rect_dsc``: -See the events of the :ref:`Base object ` too. -Learn more about :ref:`events`. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + + .. _lv_arc_keys: @@ -175,14 +180,20 @@ Keys - ``LV_KEY_RIGHT/UP`` Increases the value by one. - ``LV_KEY_LEFT/DOWN`` Decreases the value by one. -Learn more about :ref:`indev_keys`. +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + .. _lv_arc_example: Example ******* -.. include:: ../examples/widgets/arc/index.rst +.. include:: ../../examples/widgets/arc/index.rst + + .. _lv_arc_api: diff --git a/docs/widgets/bar.rst b/docs/details/widgets/bar.rst similarity index 80% rename from docs/widgets/bar.rst rename to docs/details/widgets/bar.rst index 35ab4fb9b..d3ed21a16 100644 --- a/docs/widgets/bar.rst +++ b/docs/details/widgets/bar.rst @@ -7,10 +7,10 @@ Bar (lv_bar) Overview ******** -The bar object has a background and an indicator on it. The width of the +The bar Widget has a background and an indicator on it. The width of the indicator is set according to the current value of the bar. -Vertical bars can be created if the width of the object is smaller than +Vertical bars can be created if the width of the Widget is smaller than its height. Not only the end, but also the start value of the bar can be set, which @@ -55,33 +55,48 @@ The bar can be one of the following modes: - :cpp:enumerator:`LV_BAR_MODE_NORMAL` A normal bar as described above - :cpp:enumerator:`LV_BAR_MODE_SYMMETRICAL` Draw the indicator from the zero value to current value. Requires a negative minimum range and positive maximum range. -- :cpp:enumerator:`LV_BAR_MODE_RANGE` Allows setting the start value too by +- :cpp:enumerator:`LV_BAR_MODE_RANGE` Allows setting the start value as well by ``lv_bar_set_start_value(bar, new_value, LV_ANIM_ON/OFF)``. The start value always has to be smaller than the end value. + + .. _lv_bar_events: Events ****** -See the events of the :ref:`Base object ` too. -Learn more about :ref:`events`. +No special events are sent by Bar Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + + .. _lv_bar_keys: Keys **** -No *Keys* are processed by the object type. +No *Keys* are processed by Bar Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + -Learn more about :ref:`indev_keys`. .. _lv_bar_example: Example ******* -.. include:: ../examples/widgets/bar/index.rst +.. include:: ../../examples/widgets/bar/index.rst + + .. _lv_bar_api: diff --git a/docs/widgets/button.rst b/docs/details/widgets/button.rst similarity index 59% rename from docs/widgets/button.rst rename to docs/details/widgets/button.rst index c4fc33b1f..e63ba904b 100644 --- a/docs/widgets/button.rst +++ b/docs/details/widgets/button.rst @@ -7,10 +7,10 @@ Button (lv_button) Overview ******** -Buttons have no new features compared to the :ref:`Base object `. They are useful for semantic purposes and have -slightly different default settings. +Buttons have no new features compared to the :ref:`base_widget`. +They are useful for semantic purposes and have slightly different default settings. -Buttons, by default, differ from Base object in the following ways: - +Buttons, by default, differ from Base Widget in the following ways: - Not scrollable - Added to the default group - Default height and width set to :cpp:enumerator:`LV_SIZE_CONTENT` @@ -27,7 +27,9 @@ Parts and Styles Usage ***** -There are no new features compared to :ref:`Base object `. +There are no new features compared to :ref:`Base Widget `. + + .. _lv_button_events: @@ -35,10 +37,16 @@ Events ****** - :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` when the :cpp:enumerator:`LV_OBJ_FLAG_CHECKABLE` flag is - enabled and the object is clicked. The event happens on transition + enabled and the Widget is clicked. The event happens on transition to/from the checked state. -Learn more about :ref:`events`. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + + .. _lv_button_keys: @@ -49,16 +57,20 @@ Note that the state of :cpp:enumerator:`LV_KEY_ENTER` is translated to :cpp:enumerator:`LV_EVENT_PRESSED`, :cpp:enumerator:`LV_EVENT_PRESSING` and :cpp:enumerator:`LV_EVENT_RELEASED` etc. -See the events of the :ref:`Base object ` too. +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + -Learn more about :ref:`indev_keys`. .. _lv_button_example: Example ******* -.. include:: ../examples/widgets/button/index.rst +.. include:: ../../examples/widgets/button/index.rst + + .. _lv_button_api: diff --git a/docs/widgets/buttonmatrix.rst b/docs/details/widgets/buttonmatrix.rst similarity index 89% rename from docs/widgets/buttonmatrix.rst rename to docs/details/widgets/buttonmatrix.rst index 131b37de9..88043931d 100644 --- a/docs/widgets/buttonmatrix.rst +++ b/docs/details/widgets/buttonmatrix.rst @@ -1,22 +1,22 @@ .. _lv_buttonmatrix: =============================== -Button matrix (lv_buttonmatrix) +Button Matrix (lv_buttonmatrix) =============================== Overview ******** -The Button Matrix object is a lightweight way to display multiple +The Button Matrix Widget is a lightweight way to display multiple buttons in rows and columns. Lightweight because the buttons are not actually created but just virtually drawn on the fly. This way, one button use only eight extra bytes of memory instead of the ~100-150 -bytes a normal `Button `__ object plus the 100 or so bytes -for the `Label `__ object. +bytes a normal :ref:`Button ` Widget plus the 100 or so bytes +for the :ref:`Label ` Widget. The Button matrix is added to the default group (if one is set). Besides -the Button matrix is an editable object to allow selecting and clicking -the buttons with encoder navigation too. +the Button matrix is an editable Widget to allow selecting and clicking +the buttons with encoder navigation as well. .. _lv_buttonmatrix_parts_and_styles: @@ -67,7 +67,7 @@ following parameters: - :cpp:enumerator:`LV_BUTTONMATRIX_CTRL_HIDDEN`: Makes a button hidden (hidden buttons still take up space in the layout, they are just not visible or clickable) - :cpp:enumerator:`LV_BUTTONMATRIX_CTRL_NO_REPEAT`: Disable repeating when the button is long pressed -- :cpp:enumerator:`LV_BUTTONMATRIX_CTRL_DISABLED`: Makes a button disabled Like :cpp:enumerator:`LV_STATE_DISABLED` on normal objects +- :cpp:enumerator:`LV_BUTTONMATRIX_CTRL_DISABLED`: Makes a button disabled Like :cpp:enumerator:`LV_STATE_DISABLED` on normal Widgets - :cpp:enumerator:`LV_BUTTONMATRIX_CTRL_CHECKABLE`: Enable toggling of a button. I.e. :cpp:enumerator:`LV_STATE_CHECKED` will be added/removed as the button is clicked - :cpp:enumerator:`LV_BUTTONMATRIX_CTRL_CHECKED`: Make the button checked. It will use the :cpp:enumerator:`LV_STATE_CHECHKED` styles. - :cpp:enumerator:`LV_BUTTONMATRIX_CTRL_CLICK_TRIG`: Enabled: send LV_EVENT_VALUE_CHANGE on CLICK, Disabled: send :cpp:enumerator:`LV_EVENT_VALUE_CHANGE` on PRESS @@ -100,6 +100,8 @@ The "One check" feature can be enabled with :cpp:expr:`lv_buttonmatrix_set_one_checked(buttonm, true)` to allow only one button to be checked at a time. + + .. _lv_buttonmatrix_events: Events @@ -109,8 +111,6 @@ Events repeated after long press. The event parameter is set to the ID of the pressed/released button. -See the events of the :ref:`Base object ` too. - :cpp:expr:`lv_buttonmatrix_get_selected_button(buttonm)` returns the index of the most recently released or focused button or :cpp:enumerator:`LV_BUTTONMATRIX_BUTTON_NONE` if no such button. @@ -118,7 +118,13 @@ such button. :cpp:expr:`lv_buttonmatrix_get_button_text(buttonm, button_id)` returns a pointer to the text of ``button_id``\ th button. -Learn more about :ref:`events`. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + + .. _lv_buttonmatrix_keys: @@ -137,14 +143,20 @@ to the button matrix if used with encoder. This way, the pressed button repeat feature is disabled and on leaving edit mode the selected button won't be activated. -Learn more about :ref:`indev_keys`. +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + .. _lv_buttonmatrix_example: Example ******* -.. include:: ../examples/widgets/buttonmatrix/index.rst +.. include:: ../../examples/widgets/buttonmatrix/index.rst + + .. _lv_buttonmatrix_api: diff --git a/docs/widgets/calendar.rst b/docs/details/widgets/calendar.rst similarity index 86% rename from docs/widgets/calendar.rst rename to docs/details/widgets/calendar.rst index 965a7c150..9343d53c2 100644 --- a/docs/widgets/calendar.rst +++ b/docs/details/widgets/calendar.rst @@ -7,13 +7,13 @@ Calendar (lv_calendar) Overview ******** -The Calendar object is a classic calendar which can: - show the days of +The Calendar Widget is a classic calendar which can: - show the days of any month in a 7x7 matrix - Show the name of the days - highlight the current day (today) - highlight any user-defined dates The Calendar is added to the default group (if it is set). Calendar is -an editable object which allow selecting and clicking the dates with -encoder navigation too. +an editable Widget which allow selecting and clicking the dates with +encoder navigation as well. To make the Calendar flexible, by default it doesn't show the current year or month. Instead, there are optional "headers" that can be @@ -24,8 +24,8 @@ attached to the calendar. Parts and Styles **************** -The calendar object uses the `Button matrix `__ -object under the hood to arrange the days into a matrix. +The calendar Widget uses the :ref:`Button Matrix ` +Widget under the hood to arrange the days into a matrix. - :cpp:enumerator:`LV_PART_MAIN` The background of the calendar. Uses all the background related style properties. - :cpp:enumerator:`LV_PART_ITEMS` Refers to the dates and day names. Button matrix control flags are set to differentiate the @@ -79,24 +79,26 @@ Custom year list Sets a custom year list with :cpp:expr:`lv_calendar_header_dropdown_set_year_list(calendar, years_list)` where ``years_list`` is a pointer to the custom years list. It can be a constant string -like ``static const char * years = "2023\n2022\n2021\n2020\n2019";``, +like ``static const char * years = "2023\n2022\n2021\n2020\n2019";``, or can be generated dynamically into a buffer as well. Chinese calendar ---------------- -The Chinese calendar is a traditional cultural tool that integrates elements -such as the lunar calendar, solar terms, and traditional festivals. It is -widely used in Chinese social life, helping people understand the dates of -the lunar calendar, arrange festival activities, and inherit the excellent -traditional culture of the Chinese nation. Whether in families, businesses, -or education, the Chinese calendar plays an irreplaceable role, enabling -people to better understand and appreciate the charm of Chinese traditional +The Chinese calendar is a traditional cultural tool that integrates elements +such as the lunar calendar, solar terms, and traditional festivals. It is +widely used in Chinese social life, helping people understand the dates of +the lunar calendar, arrange festival activities, and inherit the excellent +traditional culture of the Chinese nation. Whether in families, businesses, +or education, the Chinese calendar plays an irreplaceable role, enabling +people to better understand and appreciate the charm of Chinese traditional culture. -If you want to use the Chinese calendar, please +If you want to use the Chinese calendar, please use :cpp:expr:`lv_calendar_set_chinese_mode(calendar, true)` to enable it. + + .. _lv_calendar_events: Events @@ -107,7 +109,14 @@ Events date currently being pressed. Returns :cpp:enumerator:`LV_RESULT_OK` if there is a valid pressed date, else :cpp:enumerator:`LV_RESULT_INVALID`. -Learn more about :ref:`events`. + +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + + .. _lv_calendar_keys: @@ -117,7 +126,11 @@ Keys - ``LV_KEY_RIGHT/UP/LEFT/RIGHT`` To navigate among the buttons to dates - :cpp:enumerator:`LV_KEY_ENTER` To press/release the selected date -Learn more about :ref:`indev_keys`. +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + .. _lv_calendar_header: @@ -142,10 +155,14 @@ contains 2 drop-drown lists: one for the year and another for the month. .. _lv_calendar_example: + + Example ******* -.. include:: ../examples/widgets/calendar/index.rst +.. include:: ../../examples/widgets/calendar/index.rst + + .. _lv_calendar_api: diff --git a/docs/widgets/canvas.rst b/docs/details/widgets/canvas.rst similarity index 87% rename from docs/widgets/canvas.rst rename to docs/details/widgets/canvas.rst index 17e5320e5..eb3deca44 100644 --- a/docs/widgets/canvas.rst +++ b/docs/details/widgets/canvas.rst @@ -73,33 +73,45 @@ The draw function can draw to any color format to which LVGL can render. Typical :cpp:enumerator:`LV_COLOR_FORMAT_RGB565`, :cpp:enumerator:`LV_COLOR_FORMAT_RGB888`, :cpp:enumerator:`LV_COLOR_FORMAT_XRGB888`, and :cpp:enumerator:`LV_COLOR_FORMAT_ARGB8888`. + + .. _lv_canvas_events: Events ****** -No special events are sent by canvas objects. The same events are sent +No special events are sent by canvas Widgets. The same events are sent as for the -See the events of the :ref:`lv_image` too. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + -Learn more about :ref:`events`. .. _lv_canvas_keys: Keys **** -No *Keys* are processed by the object type. +No *Keys* are processed by Canvas Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + -Learn more about :ref:`indev_keys`. .. _lv_canvas_example: Example ******* -.. include:: ../examples/widgets/canvas/index.rst +.. include:: ../../examples/widgets/canvas/index.rst + + .. _lv_canvas_api: diff --git a/docs/widgets/chart.rst b/docs/details/widgets/chart.rst similarity index 92% rename from docs/widgets/chart.rst rename to docs/details/widgets/chart.rst index b8c588cb0..1fe92af4d 100644 --- a/docs/widgets/chart.rst +++ b/docs/details/widgets/chart.rst @@ -7,7 +7,7 @@ Chart (lv_chart) Overview ******** -Charts are a basic object to visualize data points. Currently *Line* +Charts are a basic Widget to visualize data points. Currently *Line* charts (connect points with lines and/or draw points on them) and *Bar* charts are supported. @@ -25,7 +25,7 @@ Parts and Styles charts ``pad_column`` sets the space between the columns of the adjacent indices. - :cpp:enumerator:`LV_PART_SCROLLBAR` The scrollbar used if the chart is zoomed. See - the :ref:`Base object `\ 's documentation for details. + :ref:`base_widget`'s documentation for details. - :cpp:enumerator:`LV_PART_ITEMS` Refers to the line or bar series. - Line chart: The *line* properties are used by the lines. @@ -64,7 +64,7 @@ Data series You can add any number of series to the charts by :cpp:expr:`lv_chart_add_series(chart, color, axis)`. This allocates an -:cpp:struct:`lv_chart_series_t` structure which contains the chosen ``color`` and +:cpp:expr:`lv_chart_series_t` structure which contains the chosen ``color`` and an array for the data points. ``axis`` can have the following values: - :cpp:enumerator:`LV_CHART_AXIS_PRIMARY_Y`: Left axis @@ -173,7 +173,7 @@ Note that :cpp:enumerator:`LV_CHART_UPDATE_MODE_SHIFT` also changes the Tick marks and labels --------------------- -With the help of `Scale `__, vertical and horizontal scales can be added in a very flexible way. +With the help of :ref:`Scale `, vertical and horizontal scales can be added in a very flexible way. See the example below to learn more. Zoom @@ -202,6 +202,8 @@ point. the cursor at a point. If the point's position changes (new value or scrolling) the cursor will move with the point. + + .. _lv_chart_events: Events @@ -211,25 +213,35 @@ Events :cpp:expr:`lv_chart_get_pressed_point(chart)` returns the zero-based index of the pressed point. -See the events of the :ref:`Base object ` too. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + -Learn more about :ref:`events`. .. _lv_chart_keys: Keys **** -No *Keys* are processed by the object type. +No *Keys* are processed by Chart Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + -Learn more about :ref:`indev_keys`. .. _lv_chart_example: Example ******* -.. include:: ../examples/widgets/chart/index.rst +.. include:: ../../examples/widgets/chart/index.rst + + .. _lv_chart_api: diff --git a/docs/widgets/checkbox.rst b/docs/details/widgets/checkbox.rst similarity index 79% rename from docs/widgets/checkbox.rst rename to docs/details/widgets/checkbox.rst index bef5d9fd4..d1836649b 100644 --- a/docs/widgets/checkbox.rst +++ b/docs/details/widgets/checkbox.rst @@ -7,7 +7,7 @@ Checkbox (lv_checkbox) Overview ******** -The Checkbox object is created from a "tick box" and a label. When the +The Checkbox Widget is created from a "tick box" and a label. When the Checkbox is clicked the tick box is toggled. .. _lv_checkbox_parts_and_styles: @@ -49,13 +49,15 @@ common state add/clear function: .. code-block:: c - lv_obj_add_state(cb, LV_STATE_CHECKED); /*Make the checkbox checked*/ - lv_obj_remove_state(cb, LV_STATE_CHECKED); /*Make the checkbox unchecked*/ - lv_obj_add_state(cb, LV_STATE_CHECKED | LV_STATE_DISABLED); /*Make the checkbox checked and disabled*/ + lv_obj_add_state(cb, LV_STATE_CHECKED); /* Make the checkbox checked */ + lv_obj_remove_state(cb, LV_STATE_CHECKED); /* Make the checkbox unchecked */ + lv_obj_add_state(cb, LV_STATE_CHECKED | LV_STATE_DISABLED); /* Make the checkbox checked and disabled */ To get whether the checkbox is checked or not use: :cpp:expr:`lv_obj_has_state(cb, LV_STATE_CHECKED)`. + + .. _lv_checkbox_events: Events @@ -63,9 +65,13 @@ Events - :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` Sent when the checkbox is toggled. -See the events of the :ref:`Base object ` too. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + -Learn more about :ref:`events`. .. _lv_checkbox_keys: @@ -80,14 +86,20 @@ The following *Keys* are processed by the 'Buttons': - Note that, as usual, the state of :cpp:enumerator:`LV_KEY_ENTER` is translated to ``LV_EVENT_PRESSED/PRESSING/RELEASED`` etc. -Learn more about :ref:`indev_keys`. +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + .. _lv_checkbox_example: Example ******* -.. include:: ../examples/widgets/checkbox/index.rst +.. include:: ../../examples/widgets/checkbox/index.rst + + .. _lv_checkboxapi: diff --git a/docs/widgets/dropdown.rst b/docs/details/widgets/dropdown.rst similarity index 89% rename from docs/widgets/dropdown.rst rename to docs/details/widgets/dropdown.rst index ae542ef55..397b2b180 100644 --- a/docs/widgets/dropdown.rst +++ b/docs/details/widgets/dropdown.rst @@ -1,7 +1,7 @@ .. _lv_dropdown: ============================ -Drop-down list (lv_dropdown) +Drop-Down List (lv_dropdown) ============================ Overview @@ -15,8 +15,8 @@ is created from which the user may select one option. When the user selects a new value, the list is deleted again. The Drop-down list is added to the default group (if it is set). Besides -the Drop-down list is an editable object to allow selecting an option -with encoder navigation too. +the Drop-down list is an editable Widget to allow selecting an option +with encoder navigation as well. .. _lv_dropdown_parts_and_styles: @@ -49,7 +49,7 @@ List pressed+checked option. Also uses the typical background properties. The list is hidden/shown on open/close. To add styles to it use -:cpp:expr:`lv_dropdown_get_list(dropdown)` to get the list object. For example: +:cpp:expr:`lv_dropdown_get_list(dropdown)` to get the list Widget. For example: .. code-block:: c @@ -80,7 +80,7 @@ variable. The :cpp:expr:`lv_dropdown_add_option(dropdown, "New option", pos)` function inserts a new option to ``pos`` index. -To save memory the options can set from a static(constant) string too +To save memory the options can set from a static(constant) string as well with :cpp:expr:`lv_dropdown_set_static_options(dropdown, options)`. In this case the options string should be alive while the drop-down list exists and :cpp:func:`lv_dropdown_add_option` can't be used @@ -130,22 +130,24 @@ Manually open/close To manually open or close the drop-down list the ``lv_dropdown_open/close(dropdown)`` function can be used. + + .. _lv_dropdown_events: Events ****** -Apart from the `Generic events <../overview/event.html#generic-events>`__, the following -`Special events <../overview/event.html#special-events>`__ are sent by -the drop-down list: - - :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` Sent when the new option is selected or the list is opened/closed. - :cpp:enumerator:`LV_EVENT_CANCEL` Sent when the list is closed - :cpp:enumerator:`LV_EVENT_READY` Sent when the list is opened -See the events of the :ref:`Base object ` too. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + -Learn more about :ref:`events`. .. _lv_dropdown_keys: @@ -157,14 +159,20 @@ Keys - :cpp:enumerator:`LV_KEY_ENTER` Apply the selected option (Sends :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` event and closes the drop-down list). -Learn more about :ref:`indev_keys`. +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + .. _lv_dropdown_example: Example ******* -.. include:: ../examples/widgets/dropdown/index.rst +.. include:: ../../examples/widgets/dropdown/index.rst + + .. _lv_dropdown_api: diff --git a/docs/widgets/image.rst b/docs/details/widgets/image.rst similarity index 89% rename from docs/widgets/image.rst rename to docs/details/widgets/image.rst index 81ec35882..45785ec29 100644 --- a/docs/widgets/image.rst +++ b/docs/details/widgets/image.rst @@ -7,8 +7,8 @@ Image (lv_image) Overview ******** -Images are the basic object to display images from flash (as arrays) or -from files. Images can display symbols (``LV_SYMBOL_...``) too. +Images are the basic Widget to display images from flash (as arrays) or +from files. Images can display symbols (``LV_SYMBOL_...``) as well. Using the :ref:`Image decoder interface ` custom image formats can be supported as well. @@ -41,7 +41,7 @@ To set the source of an image, use :cpp:expr:`lv_image_set_src(img, src)`. To generate a pixel array from a PNG, JPG or BMP image, use the `Online image converter tool `__ and set the converted image with its pointer :cpp:expr:`lv_image_set_src(img1, &converted_img_var)` To make the variable visible in the C file, you need to declare it with -:c:macro:`LV_IMAGE_DECLARE(converted_img_var)`. +:cpp:expr:`LV_IMAGE_DECLARE(converted_img_var)`. To use external files, you also need to convert the image files using the online converter tool but now you should select the binary output @@ -104,9 +104,9 @@ Offset With :cpp:expr:`lv_image_set_offset_x(img, x_ofs)` and :cpp:expr:`lv_image_set_offset_y(img, y_ofs)`, you can add some offset to the -displayed image. Useful if the object size is smaller than the image +displayed image. Useful if the Widget size is smaller than the image source size. Using the offset parameter a `Texture atlas `__ -or a "running image" effect can be created by :ref:`Animating ` the x or y offset. +or a "running image" effect can be created by :ref:`Animating ` the x or y offset. Transformations --------------- @@ -138,7 +138,7 @@ In other words transformations work only on normal (A)RGB or A8 images stored as C array, or if a custom :ref:`overview_image_decoder` returns the whole image. -Note that the real coordinates of image objects won't change during +Note that the real coordinates of image Widgets won't change during transformation. That is :cpp:expr:`lv_obj_get_width/height/x/y()` will return the original, non-zoomed coordinates. @@ -185,32 +185,46 @@ Or to automatically scale or tile the image The alignment can be set by :cpp:func:`lv_image_set_inner_align` + + .. _lv_image_events: Events ****** -No special events are sent by image objects. +No special events are sent by Image Widgets. By default, Image Widgets are created +without the LV_OBJ_FLAG_CLICKABLE flag, but you can add it to make a Label Widget +emit LV_EVENT_CLICKED events if desired. + +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. -See the events of the :ref:`Base object ` too. -Learn more about :ref:`events`. .. _lv_image_keys: Keys **** -No *Keys* are processed by the object type. +No *Keys* are processed by Image Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + -Learn more about :ref:`indev_keys`. .. _lv_image_example: Example ******* -.. include:: ../examples/widgets/image/index.rst +.. include:: ../../examples/widgets/image/index.rst + + .. _lv_image_api: diff --git a/docs/widgets/imagebutton.rst b/docs/details/widgets/imagebutton.rst similarity index 79% rename from docs/widgets/imagebutton.rst rename to docs/details/widgets/imagebutton.rst index 3dc1666bf..c025d09da 100644 --- a/docs/widgets/imagebutton.rst +++ b/docs/details/widgets/imagebutton.rst @@ -1,18 +1,18 @@ .. _lv_imagebutton: ============================= -Image button (lv_imagebutton) +Image Button (lv_imagebutton) ============================= Overview ******** -The Image button is very similar to the simple 'Button' object. The only +The Image button is very similar to the simple 'Button' Widget. The only difference is that it displays user-defined images in each state instead of drawing a rectangle. You can set a left, right and center image, and the center image will be -repeated to match the width of the object. +repeated to match the width of the Widget. .. _lv_imagebutton_parts_and_styles: @@ -34,7 +34,7 @@ Image sources To set the image in a state, use the :cpp:expr:`lv_imagebutton_set_src(imagebutton, LV_IMAGEBUTTON_STATE_..., src_left, src_center, src_right)`. -The image sources work the same as described in the `Image object `__ +The image sources work the same as described in the :ref:`Image Widget ` except that "Symbols" are not supported by the Image button. Any of the sources can ``NULL``. If only ``src_center`` is specified, the width of the widget will be set automatically to the @@ -51,7 +51,7 @@ The possible states are: - :cpp:enumerator:`LV_IMAGEBUTTON_STATE_CHECKED_DISABLED` If you set sources only in :cpp:enumerator:`LV_IMAGEBUTTON_STATE_RELEASED`, these sources -will be used in other states too. If you set e.g. :cpp:enumerator:`LV_IMAGEBUTTON_STATE_PRESSED` +will be used in other states as well. If you set e.g. :cpp:enumerator:`LV_IMAGEBUTTON_STATE_PRESSED` they will be used in pressed state instead of the released images. States @@ -61,6 +61,8 @@ Instead of the regular :cpp:func:`lv_obj_add_state` and :cpp:func:`lv_obj_remove the :cpp:expr:`lv_imagebutton_set_state(imagebutton, LV_IMAGEBUTTON_STATE_...)` function should be used to manually set a state. + + .. _lv_imagebutton_events: Events @@ -68,7 +70,13 @@ Events - :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` Sent when the button is toggled. -Learn more about :ref:`events`. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + + .. _lv_imagebutton_keys: @@ -81,14 +89,20 @@ Keys :cpp:enumerator:`LV_OBJ_FLAG_CHECKABLE` is enabled. - :cpp:enumerator:`LV_KEY_ENTER` Clicks the button -Learn more about :ref:`indev_keys`. +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + .. _lv_imagebutton_example: Example ******* -.. include:: ../examples/widgets/imagebutton/index.rst +.. include:: ../../examples/widgets/imagebutton/index.rst + + .. _lv_imagebutton_api: diff --git a/docs/widgets/index.rst b/docs/details/widgets/index.rst similarity index 96% rename from docs/widgets/index.rst rename to docs/details/widgets/index.rst index 3ceb829c4..108a8b23d 100644 --- a/docs/widgets/index.rst +++ b/docs/details/widgets/index.rst @@ -7,7 +7,6 @@ Widgets .. toctree:: :maxdepth: 1 - obj animimg arc bar @@ -40,3 +39,4 @@ Widgets textarea tileview win + new_widget diff --git a/docs/widgets/keyboard.rst b/docs/details/widgets/keyboard.rst similarity index 87% rename from docs/widgets/keyboard.rst rename to docs/details/widgets/keyboard.rst index 1b0f03fad..cc6df35bb 100644 --- a/docs/widgets/keyboard.rst +++ b/docs/details/widgets/keyboard.rst @@ -7,7 +7,7 @@ Keyboard (lv_keyboard) Overview ******** -The Keyboard object is a special :ref:`Button matrix ` +The Keyboard Widget is a special :ref:`Button matrix ` with predefined keymaps and other features to realize a virtual keyboard to write texts into a :ref:`Text area `. @@ -88,6 +88,8 @@ with the original map: - ``"abc"`` Load the lower case map. - ``"1#"`` Load the lower case map. + + .. _lv_keyboard_events: Events @@ -104,11 +106,19 @@ The keyboard has a **default event handler** callback called changing, the assigned text area, etc. You can remove it and replace it with a custom event handler if you wish. +.. note:: + + In 8.0 and newer, adding an event handler to the keyboard does not remove the + default event handler. This behavior differs from v7, where adding an event + handler would always replace the previous one. + +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. -:note: In 8.0 and newer, adding an event handler to the keyboard does not remove the default event handler. - This behavior differs from v7, where adding an event handler would always replace the previous one. -Learn more about :ref:`events`. .. _lv_keyboard_keys: @@ -119,14 +129,20 @@ Keys select one. - :cpp:enumerator:`LV_KEY_ENTER` To press/release the selected button. -Learn more about :ref:`indev_keys`. +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + .. _lv_keyboard_example: Example ******* -.. include:: ../examples/widgets/keyboard/index.rst +.. include:: ../../examples/widgets/keyboard/index.rst + + .. _lv_keyboard_api: diff --git a/docs/widgets/label.rst b/docs/details/widgets/label.rst similarity index 67% rename from docs/widgets/label.rst rename to docs/details/widgets/label.rst index a6b0de6c3..678e54970 100644 --- a/docs/widgets/label.rst +++ b/docs/details/widgets/label.rst @@ -7,7 +7,7 @@ Label (lv_label) Overview ******** -A label is the basic object type that is used to display text. +A label is the basic Widget type that is used to display text. .. _lv_label_parts_and_styles: @@ -40,21 +40,43 @@ Therefore, you don't need to keep the text you pass to With :cpp:expr:`lv_label_set_text_fmt(label, "Value: %d", 15)` printf formatting can be used to set the text. -Labels are able to show text from a static character buffer. To do so, -use :cpp:expr:`lv_label_set_text_static(label, "Text")`. In this case, the text -is not stored in the dynamic memory and the given buffer is used -directly instead. This means that the array can't be a local variable -which goes out of scope when the function exits. Constant strings are -safe to use with :cpp:func:`lv_label_set_text_static` (except when used with -:cpp:enumerator:`LV_LABEL_LONG_DOT`, as it modifies the buffer in-place), as they are -stored in ROM memory, which is always accessible. +Labels are able to show text from a static character buffer as well. To do so, use +:cpp:expr:`lv_label_set_text_static(label, "Text")`. In this case, the text is not +stored in dynamic memory and the given buffer is used directly instead. This means +that the character buffer *must not* be a local variable that goes out of scope when +the function exits. + +``const`` strings are safe to use with :cpp:func:`lv_label_set_text_static` since +they are stored in ROM memory, which is always accessible. + +.. danger:: + + Do not use ``const`` strings with :cpp:func:`lv_label_set_text_static` when the + label is being used in :cpp:enumerator:`LV_LABEL_LONG_DOT` mode since the label + will attempt to do an in-place edit of the string. This will cause an MCU + exception by attempting to modify program memory (ROM). + +.. caution:: + + If your label is updated with new strings rapidly (e.g. > 30X / second, such as + RPM in a dashboard), and the length of those strings changes frequently, it is + advisable to: + + - allocate a static string buffer large enough contain the largest possible string, + - update that buffer with the new strings only when they will make a visible + difference for the end user, and + - update the label with :cpp:expr:`lv_label_set_text_static(label, buffer)` using that buffer. + + Reason: if you use :cpp:expr:`lv_label_set_text(label, new_text)`, a memory + realloc() will be forced every time the length of the string changes. That + MCU overhead can be avoided by doing the above. .. _lv_label_newline: Newline ------- -Newline characters are handled automatically by the label object. You +Newline characters are handled automatically by the label Widget. You can use ``\n`` to make a line break. For example: ``"line1\nline2\n\nline4"`` @@ -71,7 +93,7 @@ wider than the label's width can be manipulated according to several long mode policies. Similarly, the policies can be applied if the height of the text is greater than the height of the label. -- :cpp:enumerator:`LV_LABEL_LONG_WRAP` Wrap too long lines. If the height is :c:macro:`LV_SIZE_CONTENT` the label's +- :cpp:enumerator:`LV_LABEL_LONG_WRAP` Wrap lines that are too long. If the height is :c:macro:`LV_SIZE_CONTENT` the label's height will be expanded, otherwise the text will be clipped. (Default) - :cpp:enumerator:`LV_LABEL_LONG_DOT` Replaces the last 3 characters from bottom right corner of the label with dots (``.``) - :cpp:enumerator:`LV_LABEL_LONG_SCROLL` If the text is wider than the label scroll it horizontally back and forth. If it's @@ -141,34 +163,48 @@ Symbols ------- The labels can display symbols alongside letters (or on their own). Read -the :ref:`fonts` section to learn more about the symbols. +the :ref:`font` section to learn more about the symbols. + + .. _lv_label_events: Events ****** -No special events are sent by the Label. +No special events are sent by Label Widgets. By default, Label Widgets are created +without the LV_OBJ_FLAG_CLICKABLE flag, but you can add it to make a Label Widget +emit LV_EVENT_CLICKED events if desired. + +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. -See the events of the :ref:`Base object ` too. -Learn more about :ref:`events`. .. _lv_label_keys: Keys **** -No *Keys* are processed by the object type. +No *Keys* are processed by Label Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + -Learn more about :ref:`indev_keys`. .. _lv_label_example: Example ******* -.. include:: ../examples/widgets/label/index.rst +.. include:: ../../examples/widgets/label/index.rst + + .. _lv_label_api: diff --git a/docs/widgets/led.rst b/docs/details/widgets/led.rst similarity index 71% rename from docs/widgets/led.rst rename to docs/details/widgets/led.rst index bb011a9a5..91083e571 100644 --- a/docs/widgets/led.rst +++ b/docs/details/widgets/led.rst @@ -7,7 +7,7 @@ LED (lv_led) Overview ******** -The LEDs are rectangle-like (or circle) object whose brightness can be +The LEDs are rectangle-like (or circle) Widget whose brightness can be adjusted. With lower brightness the colors of the LED become darker. .. _lv_led_parts_and_styles: @@ -42,30 +42,44 @@ Use :cpp:expr:`lv_led_on(led)` and :cpp:expr:`lv_led_off(led)` to set the bright a predefined ON or OFF value. The :cpp:expr:`lv_led_toggle(led)` toggles between the ON and OFF state. + + .. _lv_led_events: Events ****** -See the events of the :ref:`Base object ` too. +No special events are sent by LED Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + -Learn more about :ref:`events`. .. _lv_led_keys: Keys **** -No *Keys* are processed by the object type. +No *Keys* are processed by LED Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + -Learn more about :ref:`indev_keys`. .. _lv_led_example: Example ******* -.. include:: ../examples/widgets/led/index.rst +.. include:: ../../examples/widgets/led/index.rst + + .. _lv_led_api: diff --git a/docs/widgets/line.rst b/docs/details/widgets/line.rst similarity index 67% rename from docs/widgets/line.rst rename to docs/details/widgets/line.rst index e6d707161..5dd272d4a 100644 --- a/docs/widgets/line.rst +++ b/docs/details/widgets/line.rst @@ -7,7 +7,7 @@ Line (lv_line) Overview ******** -The Line object is capable of drawing straight lines between a set of +The Line Widget is capable of drawing straight lines between a set of points. .. _lv_line_parts_and_styles: @@ -26,7 +26,7 @@ Set points ---------- The points have to be stored in an :cpp:struct:`lv_point_precise_t` array and passed to -the object by the :cpp:expr:`lv_line_set_points(lines, point_array, point_cnt)` +the Widget by the :cpp:expr:`lv_line_set_points(lines, point_array, point_cnt)` function. Their coordinates can either be specified as raw pixel coordinates @@ -45,38 +45,49 @@ the size is set explicitly, parts on the line may not be visible. Invert y -------- -By default, the *y == 0* point is in the top of the object. It might be +By default, the *y == 0* point is in the top of the Widget. It might be counter-intuitive in some cases so the y coordinates can be inverted with :cpp:expr:`lv_line_set_y_invert(line, true)`. In this case, *y == 0* will -be the bottom of the object. *y invert* is disabled by default. +be the bottom of the Widget. *y invert* is disabled by default. + + .. _lv_line_events: Events ****** -Only the `Generic events <../overview/event.html#generic-events>`__ are -sent by the object type. +Only the :ref:`Generic events ` are sent by Line Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. -See the events of the :ref:`Base object ` too. -Learn more about :ref:`events`. .. _lv_line_keys: Keys **** -No *Keys* are processed by the object type. +No *Keys* are processed by Line Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + -Learn more about :ref:`indev_keys`. .. _lv_line_example: Example ******* -.. include:: ../examples/widgets/line/index.rst +.. include:: ../../examples/widgets/line/index.rst + + .. _lv_line_api: diff --git a/docs/widgets/list.rst b/docs/details/widgets/list.rst similarity index 69% rename from docs/widgets/list.rst rename to docs/details/widgets/list.rst index 01b887a0e..f1f580c6e 100644 --- a/docs/widgets/list.rst +++ b/docs/details/widgets/list.rst @@ -18,7 +18,8 @@ Parts and Styles **Background** - :cpp:enumerator:`LV_PART_MAIN` The main part of the list that uses all the typical background properties -- :cpp:enumerator:`LV_PART_SCROLLBAR` The scrollbar. See the :ref:`Base objects ` documentation for details. +- :cpp:enumerator:`LV_PART_SCROLLBAR` The scrollbar. See the :ref:`base_widget` + documentation for details. **Buttons and Texts** See the :ref:`Button `\ 's and :ref:`Label `\ 's documentation. @@ -42,30 +43,44 @@ Texts :cpp:expr:`lv_list_add_text(list, text)` adds a text. + + .. _lv_list_events: Events ****** -No special events are sent by the List, but sent by the Button as usual. +No special events are sent by List Widgets, but events are sent by Buttons as usual. + +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + -Learn more about :ref:`events`. .. _lv_list_keys: Keys **** -No *Keys* are processed by the object type. +No *Keys* are processed by List Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + -Learn more about :ref:`indev_keys`. .. _lv_list_example: Example ******* -.. include:: ../examples/widgets/list/index.rst +.. include:: ../../examples/widgets/list/index.rst + + .. _lv_list_api: diff --git a/docs/widgets/lottie.rst b/docs/details/widgets/lottie.rst similarity index 90% rename from docs/widgets/lottie.rst rename to docs/details/widgets/lottie.rst index 439871b4b..1dbbb72fb 100644 --- a/docs/widgets/lottie.rst +++ b/docs/details/widgets/lottie.rst @@ -83,29 +83,44 @@ Get the animation Lottie animation. By default it is running infinitely at 60FPS however the LVGL animation can be freely adjusted. + + .. _lv_lottie_events: Events ****** -No special events are sent by the Lottie widget. +No *Keys* are processed by Lottie Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + -Learn more about :ref:`events`. .. _lv_lottie_keys: Keys **** -No keys are processed by the Lottie widget -Learn more about :ref:`indev_keys`. +No keys are processed by Lottie Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + .. _lv_lottie_example: Example ******* -.. include:: ../examples/widgets/lottie/index.rst +.. include:: ../../examples/widgets/lottie/index.rst + + .. _lv_lottie_api: diff --git a/docs/widgets/menu.rst b/docs/details/widgets/menu.rst similarity index 87% rename from docs/widgets/menu.rst rename to docs/details/widgets/menu.rst index 1cbdac30e..06955fdad 100644 --- a/docs/widgets/menu.rst +++ b/docs/details/widgets/menu.rst @@ -15,7 +15,7 @@ handles the traversal between pages automatically. Parts and Styles **************** -The menu widget is built from the following objects: +The menu widget is built from the following Widgets: - Main container: :cpp:type:`lv_menu_main_cont` - Main header: :cpp:type:`lv_menu_main_header_cont` @@ -83,8 +83,8 @@ Linking between menu pages -------------------------- For instance, you have created a button obj in the main page. When you -click the button obj, you want it to open up a new page, use -:cpp:expr:`lv_menu_set_load_page_event(menu, obj, new page)`. +click the button Widget, you want it to open up a new page, use +:cpp:expr:`lv_menu_set_load_page_event(menu, btn, new page)`. Create a menu container, section, separator ------------------------------------------- @@ -96,6 +96,8 @@ menu: - :cpp:expr:`lv_menu_section_create(parent page)` creates a new empty section. - :cpp:expr:`lv_menu_separator_create(parent page)` creates a separator. + + .. _lv_menu_events: Events @@ -115,25 +117,35 @@ Events - :cpp:expr:`lv_menu_back_button_is_root(menu, button)` to check if button is root back button -See the events of the :ref:`Base object ` too. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + -Learn more about :ref:`events`. .. _lv_menu_keys: Keys **** -No keys are handled by the menu widget. +No *Keys* are processed by Menu Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + -Learn more about :ref:`indev_keys`. .. _lv_menu_example: Example ******* -.. include:: ../examples/widgets/menu/index.rst +.. include:: ../../examples/widgets/menu/index.rst + + .. _lv_menu_api: diff --git a/docs/widgets/msgbox.rst b/docs/details/widgets/msgbox.rst similarity index 64% rename from docs/widgets/msgbox.rst rename to docs/details/widgets/msgbox.rst index 4af670299..9710a4ccb 100644 --- a/docs/widgets/msgbox.rst +++ b/docs/details/widgets/msgbox.rst @@ -1,7 +1,7 @@ .. _lv_msgbox: ======================= -Message box (lv_msgbox) +Message Box (lv_msgbox) ======================= Overview @@ -27,7 +27,7 @@ Parts and Styles The message box is built from other widgets, so you can check these widgets' documentation for details. -- Content, header, and footer: :ref:`lv_obj` +- Content, header, and footer: :ref:`base_widget` - Buttons: :ref:`lv_button` - Title and content text: :ref:`lv_label` @@ -53,20 +53,20 @@ following functions: .. code-block:: c - lv_obj_t * lv_msgbox_get_content(lv_obj_t * obj); - lv_obj_t * lv_msgbox_get_title(lv_obj_t * obj); - lv_obj_t * lv_msgbox_get_header(lv_obj_t * obj); - lv_obj_t * lv_msgbox_get_footer(lv_obj_t * obj); + lv_obj_t * lv_msgbox_get_content(lv_obj_t * widget); + lv_obj_t * lv_msgbox_get_title(lv_obj_t * widget); + lv_obj_t * lv_msgbox_get_header(lv_obj_t * widget); + lv_obj_t * lv_msgbox_get_footer(lv_obj_t * widget); -Functions that add something to the message box return the newly added object: +Functions that add something to the message box return the newly added Widget: .. code:: c - lv_obj_t * lv_msgbox_add_text(lv_obj_t * obj, const char * text); - lv_obj_t * lv_msgbox_add_title(lv_obj_t * obj, const char * title); - lv_obj_t * lv_msgbox_add_close_button(lv_obj_t * obj); - lv_obj_t * lv_msgbox_add_header_button(lv_obj_t * obj, const void * icon); - lv_obj_t * lv_msgbox_add_footer_button(lv_obj_t * obj, const char * text); + lv_obj_t * lv_msgbox_add_text(lv_obj_t * widget, const char * text); + lv_obj_t * lv_msgbox_add_title(lv_obj_t * widget, const char * title); + lv_obj_t * lv_msgbox_add_close_button(lv_obj_t * widget); + lv_obj_t * lv_msgbox_add_header_button(lv_obj_t * widget, const void * icon); + lv_obj_t * lv_msgbox_add_footer_button(lv_obj_t * widget, const char * text); Close the message box @@ -78,6 +78,8 @@ Close the message box asynchronously. This is useful if you want the message box to close the on the next call to ``lv_timer_handler`` instead of immediately. + + .. _lv_msgbox_events: Events @@ -85,23 +87,35 @@ Events No special events are sent by this widget. -Learn more about :ref:`events`. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + + .. _lv_msgbox_keys: Keys **** -No *Keys* are processed by the object type. +No *Keys* are processed by Msgbox Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + -Learn more about :ref:`indev_keys`. .. _lv_msgbox_example: Example ******* -.. include:: ../examples/widgets/msgbox/index.rst +.. include:: ../../examples/widgets/msgbox/index.rst + + .. _lv_msgbox_api: diff --git a/docs/overview/new_widget.rst b/docs/details/widgets/new_widget.rst similarity index 78% rename from docs/overview/new_widget.rst rename to docs/details/widgets/new_widget.rst index 35127af28..146ceccb3 100644 --- a/docs/overview/new_widget.rst +++ b/docs/details/widgets/new_widget.rst @@ -1,5 +1,5 @@ .. _new_widget: ========== -New widget +New Widget ========== diff --git a/docs/widgets/roller.rst b/docs/details/widgets/roller.rst similarity index 89% rename from docs/widgets/roller.rst rename to docs/details/widgets/roller.rst index 688260cec..0653cb641 100644 --- a/docs/widgets/roller.rst +++ b/docs/details/widgets/roller.rst @@ -59,6 +59,8 @@ This function calculates the height with the current style. If the font, line space, border width, etc. of the roller changes this function needs to be called again. + + .. _lv_roller_events: Events @@ -66,9 +68,13 @@ Events - :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` Sent when a new option is selected. -See the events of the :ref:`Base object ` too. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + -Learn more about :ref:`events`. .. _lv_roller_keys: @@ -79,12 +85,20 @@ Keys - ``LV_KEY_LEFT/UP`` Select the previous option - :cpp:enumerator:`LY_KEY_ENTER` Apply the selected option (Send :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` event) +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + + .. _lv_roller_example: Example ******* -.. include:: ../examples/widgets/roller/index.rst +.. include:: ../../examples/widgets/roller/index.rst + + .. _lv_roller_api: diff --git a/docs/widgets/scale.rst b/docs/details/widgets/scale.rst similarity index 88% rename from docs/widgets/scale.rst rename to docs/details/widgets/scale.rst index 2bd861e91..e3abc62a3 100644 --- a/docs/widgets/scale.rst +++ b/docs/details/widgets/scale.rst @@ -56,7 +56,8 @@ Labels on major ticks can be configured with :cpp:expr:`lv_scale_set_label_show( set `show_label` to true if labels should be drawn, :cpp:expr:`false` to hide them. If instead of a numerical value in the major ticks a text is required they can be set with :cpp:expr:`lv_scale_set_text_src(scale, custom_labels)` using ``NULL`` as the last element, -i.e. :cpp:expr:`static char * custom_labels[3] = {"One", "Two", NULL};`. +i.e. ``static char * custom_labels[3] = {"One", "Two", NULL}``. + It's possible to have the labels automatically rotated to match the ticks (only for RADIAL scales) using :cpp:expr:`lv_obj_set_style_transform_rotation(scale, LV_SCALE_LABEL_ROTATE_MATCH_TICKS, LV_PART_INDICATOR);` Or rotated a fixed amount (on any scale type) - here for 20 degrees: @@ -70,9 +71,12 @@ Labels that would be upside down are then rotated 180 Labels can also be moved a fixed distance in X and Y using e.g. :cpp:expr:`lv_obj_set_style_translate_x(scale, 10, LV_PART_INDICATOR);` -**NOTE:** The major tick value is calculated with the :cpp:expr:`lv_map` API (when not setting the custom labels), -this calculation takes into consideration the total tick number and the scale range, so the label drawn can present rounding errors -when the calculated value is a float number. +.. note:: + + The major tick value is calculated with the :cpp:expr:`lv_map` API (when not + setting custom labels), this calculation takes into consideration the total + number of ticks and the scale range, so the label drawn can present rounding + errors when the calculated value is a float number. The length of the ticks can be configured with the length style property on the :cpp:enumerator:`LV_PART_INDICATOR` for major ticks and :cpp:enumerator:`LV_PART_ITEMS` for minor ticks, for example with local style: @@ -105,6 +109,8 @@ For labels the following properties can be configured: For lines (main line, major and minor ticks) the following properties can be configured: :cpp:func:`lv_style_set_line_color`, :cpp:func:`lv_style_set_line_width`. + + .. _lv_scale_events: Events @@ -112,19 +118,35 @@ Events No events supported by this widget. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + + + .. _lv_scale_keys: Keys **** -No keys supported by this widget. +No *Keys* are processed by Scale Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + .. _lv_scale_example: Example ******* -.. include:: ../examples/widgets/scale/index.rst +.. include:: ../../examples/widgets/scale/index.rst + + .. _lv_scale_api: diff --git a/docs/widgets/slider.rst b/docs/details/widgets/slider.rst similarity index 88% rename from docs/widgets/slider.rst rename to docs/details/widgets/slider.rst index 89f8d2a54..eda530e54 100644 --- a/docs/widgets/slider.rst +++ b/docs/details/widgets/slider.rst @@ -7,7 +7,7 @@ Slider (lv_slider) Overview ******** -The Slider object looks like a `Bar `__ supplemented with +The Slider Widget looks like a :ref:`Bar ` supplemented with a knob. The knob can be dragged to set a value. Just like Bar, Slider can be vertical or horizontal. @@ -26,7 +26,7 @@ Parts and Styles knob(s). By default, the knob is square (with an optional corner radius) with side length equal to the smaller side of the slider. The knob can be made larger with the ``padding`` values. Padding values - can be asymmetric too. + can be asymmetric as well. .. _lv_slider_usage: @@ -52,7 +52,7 @@ The slider can be one of the following modes: - :cpp:enumerator:`LV_SLIDER_MODE_NORMAL` A normal slider as described above - :cpp:enumerator:`LV_SLIDER_SYMMETRICAL` Draw the indicator form the zero value to current value. Requires negative minimum range and positive maximum range. -- :cpp:enumerator:`LV_SLIDER_RANGE` Allows setting the start value too by +- :cpp:enumerator:`LV_SLIDER_RANGE` Allows setting the start value as well by :cpp:expr:`lv_bar_set_start_value(bar, new_value, LV_ANIM_ON/OFF)`. The start value has to be always smaller than the end value. @@ -70,6 +70,8 @@ feature is enabled by adding the :cpp:enumerator:`LV_OBJ_FLAG_ADV_HITTEST`: The extended click area (set by :cpp:expr:`lv_obj_set_ext_click_area(slider, value)`) increases to knob's click area. + + .. _lv_slider_events: Events @@ -80,9 +82,15 @@ Events being dragged. - :cpp:enumerator:`LV_EVENT_RELEASED` Sent when the slider has just been released. -See the events of the `Bar `__ too. +.. admonition:: Further Reading + + :ref:`Bar Events `. + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + -Learn more about :ref:`events`. .. _lv_slider_keys: @@ -92,14 +100,20 @@ Keys - ``LV_KEY_UP/RIGHT`` Increment the slider's value by 1 - ``LV_KEY_DOWN/LEFT`` Decrement the slider's value by 1 -Learn more about :ref:`indev_keys`. +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + .. _lv_slider_example: Example ******* -.. include:: ../examples/widgets/slider/index.rst +.. include:: ../../examples/widgets/slider/index.rst + + .. _lv_slider_api: diff --git a/docs/widgets/span.rst b/docs/details/widgets/span.rst similarity index 73% rename from docs/widgets/span.rst rename to docs/details/widgets/span.rst index 8c6ab51bf..45fb5b090 100644 --- a/docs/widgets/span.rst +++ b/docs/details/widgets/span.rst @@ -7,9 +7,9 @@ Span (lv_span) Overview ******** -A spangroup is the object that is used to display rich text. Different -from the label object, ``spangroup`` can render text styled with -different fonts, colors, and sizes into the spangroup object. +A spangroup is the Widget that is used to display rich text. Different +from the label Widget, ``spangroup`` can render text styled with +different fonts, colors, and sizes into the spangroup Widget. .. _lv_span_parts_and_styles: @@ -26,20 +26,20 @@ Usage Set text and style ------------------ -The spangroup object uses span to describe text and text style. so, +The spangroup Widget uses span to describe text and text style. so, first we need to create ``span`` descriptor using ``lv_span_t * span = lv_spangroup_new_span(spangroup)``. Then use :cpp:expr:`lv_span_set_text(span, "text")` to set text. The style of the span is -configured as with a normal style object by using its ``style`` member, +configured as with a normal style Widget by using its ``style`` member, eg::cpp:expr:`lv_style_set_text_color(&span->style, lv_palette_main(LV_PALETTE_RED))`. -If spangroup object ``mode != LV_SPAN_MODE_FIXED`` you must call +If spangroup Widget ``mode != LV_SPAN_MODE_FIXED`` you must call :cpp:func:`lv_spangroup_refr_mode` after you have modified ``span`` style(eg:set text, changed the font size, del span). Retrieving a span child ----------------------- -Spangroups store their children differently from normal objects, so +Spangroups store their children differently from normal Widgets, so normal functions for getting children won't work. :cpp:expr:`lv_spangroup_get_child(spangroup, id)` will return a pointer to the @@ -63,7 +63,7 @@ E.g. ``uint32_t size = lv_spangroup_get_span_count(spangroup)`` Text align ---------- -Like label object, the spangroup can be set to one the following modes: +Like label Widget, the spangroup can be set to one the following modes: - :cpp:enumerator:`LV_TEXT_ALIGN_LEFT` Align to left. - :cpp:enumerator:`LV_TEXT_ALIGN_CENTER` Align to center. @@ -78,12 +78,12 @@ Modes The spangroup can be set to one the following modes: -- :cpp:enumerator:`LV_SPAN_MODE_FIXED` Fixes the object size. -- :cpp:enumerator:`LV_SPAN_MODE_EXPAND` Expand the object size to the text size but stay on a single line. -- :cpp:enumerator:`LV_SPAN_MODE_BREAK` Keep width, break the too long lines and auto expand height. +- :cpp:enumerator:`LV_SPAN_MODE_FIXED` Fixes the Widget size. +- :cpp:enumerator:`LV_SPAN_MODE_EXPAND` Expand the Widget size to the text size but stay on a single line. +- :cpp:enumerator:`LV_SPAN_MODE_BREAK` Keep width, break lines that are too long and auto expand height. Use the function :cpp:expr:`lv_spangroup_set_mode(spangroup, LV_SPAN_MODE_BREAK)` to set -object mode. +Widget mode. Overflow -------- @@ -93,7 +93,7 @@ The spangroup can be set to one the following modes: - :cpp:enumerator:`LV_SPAN_OVERFLOW_CLIP` truncates the text at the limit of the area. - :cpp:enumerator:`LV_SPAN_OVERFLOW_ELLIPSIS` will display an ellipsis (``...``) when text overflows the area. -Use function :cpp:expr:`lv_spangroup_set_overflow(spangroup, LV_SPAN_OVERFLOW_CLIP)` to set object overflow mode. +Use function :cpp:expr:`lv_spangroup_set_overflow(spangroup, LV_SPAN_OVERFLOW_CLIP)` to set Widget overflow mode. First line indent ----------------- @@ -101,7 +101,7 @@ First line indent Use function :cpp:expr:`lv_spangroup_set_indent(spangroup, 20)` to set the indent of the first line. all modes support pixel units, in addition to :cpp:enumerator:`LV_SPAN_MODE_FIXED` and :cpp:enumerator:`LV_SPAN_MODE_BREAK` mode supports percentage units -too. +as well. Lines ----- @@ -110,6 +110,8 @@ Use function :cpp:expr:`lv_spangroup_set_max_lines(spangroup, 10)` to set the ma of lines to be displayed in :cpp:enumerator::`LV_SPAN_MODE_BREAK` mode, negative values indicate no limit. + + .. _lv_span_events: Events @@ -117,23 +119,35 @@ Events No special events are sent by this widget. -Learn more about :ref:`events`. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + + .. _lv_span_keys: Keys **** -No *Keys* are processed by the object type. +No *Keys* are processed by Span Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + -Learn more about :ref:`indev_keys`. .. _lv_span_example: Example ******* -.. include:: ../examples/widgets/span/index.rst +.. include:: ../../examples/widgets/span/index.rst + + .. _lv_span_api: diff --git a/docs/widgets/spinbox.rst b/docs/details/widgets/spinbox.rst similarity index 89% rename from docs/widgets/spinbox.rst rename to docs/details/widgets/spinbox.rst index 5bc0692dd..f7a051656 100644 --- a/docs/widgets/spinbox.rst +++ b/docs/details/widgets/spinbox.rst @@ -52,6 +52,8 @@ rollover mode. If either the minimum or maximum value is reached with rollover enabled, the value will change to the other limit. If rollover is disabled the value will remain at the minimum or maximum value. + + .. _lv_spinbox_events: Events @@ -59,9 +61,15 @@ Events - :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` Sent when the value has changed. -See the events of the :ref:`Text area ` too. +.. admonition:: Further Reading + + :ref:`Textarea Events `. + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + -Learn more about :ref:`events`. .. _lv_spinbox_keys: @@ -75,12 +83,20 @@ Keys - :cpp:enumerator:`LV_KEY_ENTER` With *Encoder* got the net digit. Jump to the first after the last. +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + + .. _lv_spinbox_example: Example ******* -.. include:: ../examples/widgets/spinbox/index.rst +.. include:: ../../examples/widgets/spinbox/index.rst + + .. _lv_spinbox_api: diff --git a/docs/widgets/spinner.rst b/docs/details/widgets/spinner.rst similarity index 59% rename from docs/widgets/spinner.rst rename to docs/details/widgets/spinner.rst index e7e86aa97..38640f746 100644 --- a/docs/widgets/spinner.rst +++ b/docs/details/widgets/spinner.rst @@ -7,7 +7,7 @@ Spinner (lv_spinner) Overview ******** -The Spinner object is a spinning arc over a ring. +The Spinner Widget is a spinning arc over a ring. .. _lv_spinner_parts_and_styles: @@ -30,32 +30,46 @@ To create a spinner use Using :cpp:expr:`lv_spinner_set_anim_params(spinner, spin_duration, angle)` the duration of one revolution and the length of he arc can be customized. + + .. _lv_spinner_events: Events ****** -No special events are sent to the Spinner. +No special events are sent to Spinner Widgets. + +.. admonition:: Further Reading + + :ref:`Arc Events ` + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. -See the events of the `Arc `__ too. -Learn more about :ref:`events`. .. _lv_spinner_keys: Keys **** -No *Keys* are processed by the object type. +No *Keys* are processed by Spinner Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + -Learn more about :ref:`indev_keys`. .. _lv_spinner_example: Example ******* -.. include:: ../examples/widgets/spinner/index.rst +.. include:: ../../examples/widgets/spinner/index.rst + + .. _lv_spinner_api: diff --git a/docs/widgets/switch.rst b/docs/details/widgets/switch.rst similarity index 66% rename from docs/widgets/switch.rst rename to docs/details/widgets/switch.rst index 938b48873..032e6341c 100644 --- a/docs/widgets/switch.rst +++ b/docs/details/widgets/switch.rst @@ -10,7 +10,7 @@ Overview The Switch looks like a little slider and can be used to turn something on and off. -Vertical Switch can be created if the width of the object is smaller than its height. +Vertical Switch can be created if the width of the Widget is smaller than its height. .. _lv_switch_parts_and_styles: @@ -27,7 +27,7 @@ Parts and Styles describe the knob(s). By default, the knob is square (with an optional corner radius) with side length equal to the smaller side of the slider. The knob can be made larger with the ``padding`` values. - Padding values can be asymmetric too. + Padding values can be asymmetric as well. .. _lv_switch_usage: @@ -40,15 +40,16 @@ Change state The switch uses the standard :cpp:enumerator:`LV_STATE_CHECKED` state. To get the current state of the switch (with ``true`` being on), use -:cpp:expr:`lv_obj_has_state(obj, LV_STATE_CHECKED)`. +:cpp:expr:`lv_obj_has_state(widget, LV_STATE_CHECKED)`. -Call :cpp:expr:`lv_obj_add_state(obj, LV_STATE_CHECKED)` to turn it on, or -:cpp:expr:`lv_obj_remove_state(obj, LV_STATE_CHECKED)` to turn it off. +Call :cpp:expr:`lv_obj_add_state(widget, LV_STATE_CHECKED)` to turn it on, or +:cpp:expr:`lv_obj_remove_state(widget, LV_STATE_CHECKED)` to turn it off. Change orientation ------------------ -:cpp:expr:`lv_switch_set_orientation(obj, LV_SWITCH_ORIENTATION_VERTICAL)` change orientation, default orientation is :cpp:enumerator:`LV_SWITCH_ORIENTATION_AUTO`, adaptive based on the width and height of the object. +:cpp:expr:`lv_switch_set_orientation(widget, LV_SWITCH_ORIENTATION_VERTICAL)` change orientation, default orientation is :cpp:enumerator:`LV_SWITCH_ORIENTATION_AUTO`, adaptive based on the width and height of the Widget. + .. _lv_switch_events: @@ -58,9 +59,13 @@ Events - :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` Sent when the switch changes state. -See the events of the :ref:`Base object ` too. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + -Learn more about :ref:`events`. .. _lv_switch_keys: @@ -71,14 +76,20 @@ Keys - ``LV_KEY_DOWN/LEFT`` Turns off the slider - :cpp:enumerator:`LV_KEY_ENTER` Toggles the switch -Learn more about :ref:`indev_keys`. +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + .. _lv_switch_example: Example ******* -.. include:: ../examples/widgets/switch/index.rst +.. include:: ../../examples/widgets/switch/index.rst + + .. _lv_switch_api: diff --git a/docs/widgets/table.rst b/docs/details/widgets/table.rst similarity index 82% rename from docs/widgets/table.rst rename to docs/details/widgets/table.rst index b8cc79d8c..f6e8e0556 100644 --- a/docs/widgets/table.rst +++ b/docs/details/widgets/table.rst @@ -10,13 +10,13 @@ Overview Tables, as usual, are built from rows, columns, and cells containing texts. -The Table object is very lightweight because only the texts are stored. -No real objects are created for cells but they are just drawn on the +The Table Widget is very lightweight because only the texts are stored. +No real Widgets are created for cells but they are just drawn on the fly. The Table is added to the default group (if it is set). Besides the -Table is an editable object to allow selecting a cell with encoder -navigation too. +Table is an editable Widget to allow selecting a cell with encoder +navigation as well. .. _lv_table_parts_and_styles: @@ -58,7 +58,7 @@ Width and Height The width of the columns can be set with :cpp:expr:`lv_table_set_column_width(table, col_id, width)`. The overall width of -the Table object will be set to the sum of columns widths. +the Table Widget will be set to the sum of columns widths. The height is calculated automatically from the cell styles (font, padding etc) and the number of rows. @@ -81,6 +81,8 @@ automatically sets the table size to show all the columns and rows. If the width or height is set to a smaller number than the "intrinsic" size then the table becomes scrollable. + + .. _lv_table_events: Events @@ -89,16 +91,20 @@ Events - :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` Sent when a new cell is selected with keys. -See the events of the :ref:`Base object ` too. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + -Learn more about :ref:`events`. .. _lv_table_keys: Keys **** -The following *Keys* are processed by the Tables: - +The following *Keys* are processed by Table Widgets: - ``LV_KEY_RIGHT/LEFT/UP/DOWN/`` Select a cell. Note that, as usual, the state of :cpp:enumerator:`LV_KEY_ENTER` is translated to @@ -108,20 +114,26 @@ Note that, as usual, the state of :cpp:enumerator:`LV_KEY_ENTER` is translated t currently selected cell. Row and column will be set to :c:macro:`LV_TABLE_CELL_NONE` no cell is selected. -Learn more about :ref:`indev_keys`. +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + .. _lv_table_example: Example ******* -.. include:: ../examples/widgets/table/index.rst +.. include:: ../../examples/widgets/table/index.rst MicroPython ----------- No examples yet. + + .. _lv_table_api: API diff --git a/docs/widgets/tabview.rst b/docs/details/widgets/tabview.rst similarity index 74% rename from docs/widgets/tabview.rst rename to docs/details/widgets/tabview.rst index 85fa88b82..4ef13c7b3 100644 --- a/docs/widgets/tabview.rst +++ b/docs/details/widgets/tabview.rst @@ -7,13 +7,13 @@ Tabview (lv_tabview) Overview ******** -The Tab view object can be used to organize content in tabs. The Tab +The Tab view Widget can be used to organize content in tabs. The Tab view is built from other widgets: -- Main container: :ref:`lv_obj` -- Tab buttons: an :ref:`lv_obj` with :ref:`lv_button` -- Container for the tabs: :ref:`lv_obj` -- Content of the tabs: :ref:`lv_obj` +- Main container: :ref:`base_widget` +- Tab buttons: an :ref:`base_widget` with :ref:`lv_button` +- Container for the tabs: :ref:`base_widget` +- Content of the tabs: :ref:`base_widget` The tab buttons can be positioned on the top, bottom, left and right side of the Tab view. @@ -26,8 +26,8 @@ sliding horizontally on the content. Parts and Styles **************** -There are no special parts on the Tab view but the ``lv_obj`` and -``lv_button`` widgets are used to create the Tab view. +There are no special parts on the Tab view but the :ref:`base_widget` and +:ref:`lv_button` widgets are used to create the Tab view. .. _lv_tabview_usage: @@ -43,7 +43,7 @@ Add tabs -------- New tabs can be added with :cpp:expr:`lv_tabview_add_tab(tabview, "Tab name")`. -This will return a pointer to an :ref:`lv_obj` object where +This will return a pointer to a :ref:`base_widget` where the tab's content can be created. Rename tabs @@ -81,6 +81,8 @@ Get the parts - :cpp:expr:`lv_tabview_get_content(tabview)` returns the container for tabs content - :cpp:expr:`lv_tabview_get_tab_bar(tabview)` returns the container for tabs buttons + + .. _lv_tabview_events: Events @@ -90,7 +92,13 @@ Events or clicking the tab button. :cpp:expr:`lv_tabview_get_tab_active(tabview)` returns the zero based index of the current tab. -Learn more about :ref:`events`. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + + .. _lv_tabview_keys: @@ -100,14 +108,20 @@ Keys Keys have effect only on the tab buttons. Add manually to a group if required. -Learn more about :ref:`indev_keys`. +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + .. _lv_tabview_example: Example ******* -.. include:: ../examples/widgets/tabview/index.rst +.. include:: ../../examples/widgets/tabview/index.rst + + .. _lv_tabview_api: diff --git a/docs/widgets/textarea.rst b/docs/details/widgets/textarea.rst similarity index 91% rename from docs/widgets/textarea.rst rename to docs/details/widgets/textarea.rst index b39882780..77ca7ddb2 100644 --- a/docs/widgets/textarea.rst +++ b/docs/details/widgets/textarea.rst @@ -1,16 +1,15 @@ .. _lv_textarea: ======================= -Text area (lv_textarea) +Text Area (lv_textarea) ======================= Overview ******** -The Text Area is a `Base object `__ with a -`Label `__ and a cursor on it. Texts or characters -can be added to it. Long lines are wrapped and when the text becomes -long enough the Text area can be scrolled. +The Text Area is a :ref:`base_widget_overview` with a :ref:`lv_label` and a cursor on +it. Texts or characters can be added to it. Long lines are wrapped and when the +text becomes long enough the Text area can be scrolled. One line mode and password modes are supported. @@ -152,6 +151,8 @@ Any part of the text can be selected if enabled with :cpp:expr:`lv_textarea_set_text_selection(textarea, true)`. This works much like when you select text on your PC with your mouse. + + .. _lv_textarea_events: Events @@ -168,9 +169,13 @@ Events - :cpp:enumerator:`LV_EVENT_READY` Sent when :cpp:enumerator:`LV_KEY_ENTER` is pressed (or sent) to a one line text area. -See the events of the :ref:`Base object ` too. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + -Learn more about :ref:`events`. .. _lv_textarea_keys: @@ -180,14 +185,20 @@ Keys - ``LV_KEY_UP/DOWN/LEFT/RIGHT`` Move the cursor - ``Any character`` Add the character to the current cursor position -Learn more about :ref:`indev_keys`. +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + + .. _lv_textarea_example: Example ******* -.. include:: ../examples/widgets/textarea/index.rst +.. include:: ../../examples/widgets/textarea/index.rst + + .. _lv_textarea_api: diff --git a/docs/widgets/tileview.rst b/docs/details/widgets/tileview.rst similarity index 72% rename from docs/widgets/tileview.rst rename to docs/details/widgets/tileview.rst index 2f6d3f3ab..c66d188b1 100644 --- a/docs/widgets/tileview.rst +++ b/docs/details/widgets/tileview.rst @@ -1,13 +1,13 @@ .. _lv_tileview: ======================= -Tile view (lv_tileview) +Tile View (lv_tileview) ======================= Overview ******** -The Tile view is a container object whose elements (called *tiles*) can +The Tile view is a container Widget whose elements (called *tiles*) can be arranged in grid form. A user can navigate between the tiles by swiping. Any direction of swiping can be disabled on the tiles individually to not allow moving from one tile to another. @@ -20,10 +20,10 @@ may have seen on smartwatches. Parts and Styles **************** -The Tile view is built from an :ref:`lv_obj` container and -:ref:`lv_obj` tiles. +The Tile view is built from an :ref:`base_widget` container and +:ref:`base_widget` tiles. -The parts and styles work the same as for :ref:`lv_obj`. +The parts and styles work the same as for :ref:`base_widget`. .. _lv_tileview_usage: @@ -48,6 +48,8 @@ The Tile view can scroll to a tile with :cpp:expr:`lv_tileview_set_tile(tileview, tile_obj, LV_ANIM_ON/OFF)` or :cpp:expr:`lv_tileview_set_tile_by_index(tileview, col_id, row_id, LV_ANIM_ON/OFF)` + + .. _lv_tileview_events: Events @@ -57,21 +59,35 @@ Events :cpp:expr:`lv_tileview_get_tile_active(tabview)` can be used to get current tile. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + + + .. _lv_tileview_keys: Keys **** -*Keys* are not handled by the Tile view. +No *Keys* are processed by Tileview Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + -Learn more about :ref:`indev_keys`. .. _lv_tileview_example: Example ******* -.. include:: ../examples/widgets/tileview/index.rst +.. include:: ../../examples/widgets/tileview/index.rst + + .. _lv_tileview_api: diff --git a/docs/widgets/win.rst b/docs/details/widgets/win.rst similarity index 74% rename from docs/widgets/win.rst rename to docs/details/widgets/win.rst index 2ca889829..e5b57e619 100644 --- a/docs/widgets/win.rst +++ b/docs/details/widgets/win.rst @@ -7,7 +7,7 @@ Window (lv_win) Overview ******** -The Window is container-like object built from a header with title and +The Window is container-like Widget built from a header with title and buttons and a content area. .. _lv_win_parts_and_styles: @@ -18,11 +18,11 @@ Parts and Styles The Window is built from other widgets so you can check their documentation for details: -- Background: :ref:`lv_obj` -- Header on the background: :ref:`lv_obj` +- Background: :ref:`base_widget` +- Header on the background: :ref:`base_widget` - Title on the header: :ref:`lv_label` - Buttons on the header: :ref:`lv_button` -- Content area on the background: :ref:`lv_obj` +- Content area on the background: :ref:`base_widget` .. _lv_win_usage: @@ -61,31 +61,45 @@ Get the parts :cpp:expr:`lv_win_get_content(win)` returns a pointer to the content container to which the content of the window can be added. + + .. _lv_win_events: Events ****** -No special events are sent by the windows, however events can be added +No special events are sent by Window Widgets, however events can be added manually to the return value of :cpp:func:`lv_win_add_button`. -Learn more about :ref:`events`. +.. admonition:: Further Reading + + Learn more about :ref:`lv_obj_events` emitted by all Widgets. + + Learn more about :ref:`events`. + + .. _lv_win_keys: Keys **** -No *Keys* are handled by the window. +No *Keys* are processed by Window Widgets. + +.. admonition:: Further Reading + + Learn more about :ref:`indev_keys`. + -Learn more about :ref:`indev_keys`. .. _lv_win_example: Example ******* -.. include:: ../examples/widgets/win/index.rst +.. include:: ../../examples/widgets/win/index.rst + + .. _lv_win_api: diff --git a/docs/doc_builder.py b/docs/doc_builder.py index bbf5a3e1d..cfb5c1e04 100644 --- a/docs/doc_builder.py +++ b/docs/doc_builder.py @@ -1,3 +1,124 @@ +""" +This file opens the XML `index.xml` file generated by Doxygen +which has the following structure: + + + + + ... + + +Each element has a 'kind' attribute that is one of the following: + + - define + - dir + - enum + - enumvalue + - example + - file + - function + - page + - struct + - typedef + - union + - variable + +Most elements have child elements with their own contents +depending on the 'kind' of element they are in. + +This file defines classes for each of these except for + + - dir + - page + - example + +The remaining 'kind' values are: + + - define + - enum + - enumvalue + - file + - function + - struct + - typedef + - union + - variable + +The list of classes is: + + Class | Adds Self to Dictionary in __init__() + --------- | -------------------------------------- + DEFINE => `defines` + ENUM => `enums` + VARIABLE => `variables` + NAMESPACE => `namespaces` + STRUCT => `structures` + UNION appears to have a different purpose + TYPEDEF => `typedefs` + FUNCTION => `functions` + GROUP => `groups` + FILE => `files` + CLASS => `classes` + +Additional classes: + + - NAMESPACE(object): + - FUNC_ARG(object): (becomes members of FUNCTION objects) + - STRUCT_FIELD(object): (becomes members of STRUCT objects) + - GROUP(object): + - CLASS(object): + - XMLSearch(object): + +Each of the above Dictionary variables has entries with + + - keys = actual name of the code elements Doxygen found in the .H files. + - values = XML node generated by `xml.etree::ElementTree` + +Samples: + + 'defines': {'ZERO_MEM_SENTINEL': , + 'LV_GLOBAL_DEFAULT': , + 'LV_ASSERT_OBJ': , + 'LV_TRACE_OBJ_CREATE': , + + 'enums': {'lv_key_t': , + 'lv_group_refocus_policy_t': , + 'lv_obj_flag_t': , + 'lv_obj_class_editable_t': , + + 'variables': {'lv_global': , + 'lv_obj_class': , + 'lv_font_montserrat_8': , + 'lv_font_montserrat_10': , + + 'namespaces': {}, + + 'structures': {'_lv_anim_t::_lv_anim_path_para_t': , + '_lv_anim_t': , + '_lv_animimg_t': , + '_lv_arc_t': , + + 'unions': {}, + + 'typedefs': {'lv_global_t': , + 'lv_group_focus_cb_t': , + 'lv_group_edge_cb_t': , + + 'functions': {'lv_group_create': , + 'lv_group_delete': , + 'lv_group_set_default': , + +Additional dictionaries: + 'files': {'lv_global.h': , + 'lv_group.h': , + 'lv_group_private.h': , + + 'html_files': {'lvgl': 'lvgl.html', + 'lv_api_map_v8': 'lv_api_map_v8.html', + 'lv_api_map_v9_0': 'lv_api_map_v9_0.html', + 'lv_api_map_v9_1': 'lv_api_map_v9_1.html', + +""" import os import sys from xml.etree import ElementTree as ET @@ -1150,6 +1271,12 @@ def clean_name(nme): return nme +# Definitions: +# - "section" => The name "abc_def" has 2 sections. +# - N = number of sections in `item_name`. +# After removing leading '_lv_', 'lv_' and trailing '_t' from `obj_name`, +# do the remaining first N "sections" of `obj_name` match `item_name` +# (case sensitive)? def is_name_match(item_name, obj_name): # Handle error: # AttributeError: 'NoneType' object has no attribute 'split' @@ -1159,8 +1286,11 @@ def is_name_match(item_name, obj_name): u_num = item_name.count('_') + 1 obj_name = obj_name.split('_') + + # Reject (False) if `obj_name` doesn't have as many sections as `item_name`. if len(obj_name) < u_num: return False + obj_name = '_'.join(obj_name[:u_num]) return item_name == obj_name @@ -1289,6 +1419,20 @@ class XMLSearch(object): def run(project_path, temp_directory, *doc_paths): + """ + This function does 2 things: + 1. Generates .RST files for the LVGL header files that will have API + pages generated for them. It places these in /API/... + following the /src/ directory structure. + 2. Add Sphinx hyperlinks to the end of source .RST files found + in the `doc_paths` array directories, whose file-name stems + match code-element names found by Doxygen. + + :param project_path: platform-appropriate path to LVGL root directory + :param temp_directory: platform-appropriate path to temp dir being operated on + :param doc_paths: list of platform-appropriate paths to find source .RST files. + :return: n/a + """ global base_path global xml_path global lvgl_src_path @@ -1304,29 +1448,89 @@ def run(project_path, temp_directory, *doc_paths): # Generate .RST files for API pages. iter_src('API', '') + # Load index.xml -- core of what was generated by Doxygen. index = load_xml('index') + # Populate these dictionaries. + # Keys : C-code-element names (str) found by Doxygen. + # Values: The XML-node created by `xml.etree::ElementTree` in `load_xml()` above. + # + # - defines, + # - enums, + # - variables, + # - namespaces, + # - structures, + # - unions, + # - typedefs, + # - functions. for compound in index: compound.attrib['name'] = compound[0].text.strip() if compound.attrib['kind'] in ('example', 'page', 'dir'): continue + # This below highly-compressed command effectively does this: + # + # namespace_dict = globals() + # compound_elem_kind_upper = compound.attrib['kind'].upper() + # e.g. 'FUNCTION' + # class_obj = namespace_dict['FUNCTION'] + # # In each case of `class_obj`, the __init__ args are: + # # (self, parent, refid, name, **_) + # # So we get... + # attrib_keyword_args = **compound.attrib + # # Passing (**compound.attrib) as an argument creates and + # # passes a set of keyword arguments produced from the + # # dictionary `compound.attrib`. + # new_obj = class_obj(None, node=compound, attrib_keyword_args) + # + # Note carefully that `new_obj` gets thrown away, but the new object created + # doesn't go away because during its execution of __init__(), the new object + # adds itself to the global dictionary matching its "kind": + # + # Class Dictionary New Object Adds Itself To + # ------------ | ------------------------------------ + # - DEFINE => `defines` + # - ENUM => `enums` + # - VARIABLE => `variables` + # - NAMESPACE => `namespaces` + # - STRUCT => `structures` + # - UNION appears to have a different purpose + # - TYPEDEF => `typedefs` + # - FUNCTION => `functions` + # - GROUP => `groups` + # - FILE => `files` + # - CLASS => `classes` + # + # Populating these dictionaries takes quite a while: + # ~18-seconds on a medium-speed system. globals()[compound.attrib['kind'].upper()]( None, node=compound, **compound.attrib ) + # For each directory entry in `doc_paths` array... for folder in doc_paths: - items = list( + # Fetch a list of '.rst' files excluding 'index.rst'. + rst_files = list( (os.path.splitext(item)[0], os.path.join(folder, item)) for item in os.listdir(folder) - if item.endswith('rst') and 'index' not in item + if item.endswith('.rst') and 'index.rst' not in item ) - for name, path in items: + # For each .RST file in that directory... + for stem, path in rst_files: + # Start with an empty set. html_includes = set() + # Build `html_includes` set as a list of tuples containing + # (name, html_file). Example: "draw.rst" has `stem` == 'draw', + # and generates a list of tuples from .H files where matching + # C-code-element names were found. Example: + # {('lv_draw_line', 'draw\\lv_draw_line.html'), + # ('lv_draw_sdl', 'draw\\sdl\\lv_draw_sdl.html'), + # ('lv_draw_sw_blend_to_i1', 'draw\\sw\\blend\\lv_draw_sw_blend_to_i1.html'), + # etc.} for container in ( defines, enums, @@ -1338,16 +1542,32 @@ def run(project_path, temp_directory, *doc_paths): functions ): for n, o in container.items(): - get_includes(name, n, o, html_includes) + get_includes(stem, n, o, html_includes) if html_includes: + # Convert `html_includes` set to a list of strings containing the + # Sphinx hyperlink syntax "link references". Example from above: + # [':ref:`lv_draw_line_h`\n', + # ':ref:`lv_draw_sdl_h`\n', + # ':ref:`lv_draw_sw_blend_to_i1_h`\n', + # etc.] html_includes = list( ':ref:`{0}_h`\n'.format(inc) for inc, _ in html_includes ) + # Convert that list to a single string of Sphinx hyperlink + # references with blank lines between them. + # :ref:`lv_draw_line_h` + # + # :ref:`lv_draw_sdl_h` + # + # :ref:`lv_draw_sw_blend_to_i1_h` + # + # etc. output = ('\n'.join(html_includes)) + '\n' + # Append that string to the source .RST file being processed. with open(path, 'rb') as f: try: data = f.read().decode('utf-8') diff --git a/docs/example_list.py b/docs/example_list.py index ddab74cb4..add11d309 100755 --- a/docs/example_list.py +++ b/docs/example_list.py @@ -39,7 +39,7 @@ h1 = { } widgets = { - "obj": "Base Object", + "obj": "Base Widget", "animimg": "Animation Image", "arc": "Arc", "bar": "Bar", diff --git a/docs/get-started/index.rst b/docs/get-started/index.rst deleted file mode 100644 index eefca8653..000000000 --- a/docs/get-started/index.rst +++ /dev/null @@ -1,27 +0,0 @@ -.. _get_started: - -=========== -Get Started -=========== - -There are several ways to get your feet wet with LVGL. Here is one -recommended order of documents to read and things to play with when you -are learning to use LVGL: - -1. Check the `Online demos `__ to see LVGL in action (3 minutes) -2. Read the :ref:`introduction` page of the documentation (5 minutes) -3. Read the :ref:`quick-overview` page of the documentation (15 minutes) -4. Set up a :ref:`simulator` (10 minutes) -5. Try out some :ref:`examples` -6. Check out the Platform-specific tutorials. (in this section below). (10 minutes) -7. Port LVGL to a board. See the :ref:`porting` guide or check the ready to use `Projects `__ -8. Read the :ref:`overview` page to get a better understanding of the library. (2-3 hours) -9. Check the documentation of the :ref:`widgets` to see their features and usage -10. If you have questions go to the `Forum `__ -11. Read the :ref:`contributing` guide to see how you can help to improve LVGL (15 minutes) - - -.. toctree:: - :maxdepth: 2 - - quick-overview diff --git a/docs/get-started/quick-overview.rst b/docs/get-started/quick-overview.rst deleted file mode 100644 index 348d888fd..000000000 --- a/docs/get-started/quick-overview.rst +++ /dev/null @@ -1,379 +0,0 @@ -.. _quick-overview: - -============== -Quick overview -============== - -Here you can learn the most important things about LVGL. You should read -this first to get a general impression and read the detailed -:ref:`porting` and :ref:`overview` sections -after that. - - -Getting Started with a Simulator --------------------------------- - -Instead of porting LVGL to embedded hardware straight away, it's highly -recommended to get started in a simulator first. - -LVGL is ported to many IDEs to be sure you will find your favorite one. -Go to the :ref:`simulator` section to get ready-to-use projects that can be run -on your PC. This way you can save the time of porting for now and get some -experience with LVGL immediately. - - -Add LVGL into your project --------------------------- - -If you would rather try LVGL on your own project follow these steps: - -- `Download `__ or - clone the library from GitHub with ``git clone https://github.com/lvgl/lvgl.git``. -- Copy the ``lvgl`` folder into your project. If you wish you can add only ``lvgl/lvgl.h``, ``lvgl/lv_version.h``, and ``lvgl/src`` - for LVGL itself, and ``lvgl/examples`` and ``lvgl/demos`` for the examples and demos respectively. -- Copy ``lvgl/lv_conf_template.h`` as ``lv_conf.h`` next to the ``lvgl`` folder, change the first ``#if 0`` to ``1`` to - enable the file's content and set the :c:macro:`LV_COLOR_DEPTH` defines. -- Include ``lvgl/lvgl.h`` in files where you need to use LVGL related functions. -- Call :cpp:expr:`lv_tick_inc(x)` every ``x`` milliseconds in a Timer or Task (``x`` should be between 1 and 10). It is required for - the internal timing of LVGL. Alternatively, register a ``tick_get_cb`` with :cpp:func:`lv_tick_set_cb` so that LVGL - can retrieve the current time directly. -- Call :cpp:func:`lv_init` -- Create a display. - - - .. code-block:: c - - lv_display_t *display = lv_display_create(MY_DISP_HOR_RES, MY_DISP_VER_RES); - - -- Create a draw buffer: LVGL supports multiple buffering methods. Here you can see how to set up partial buffering - (that is render the screen and the changed areas in a smaller buffer). The buffer size can be set freely but 1/10 - screen size is a good starting point. - - .. code-block:: c - - /* Declare a buffer for 1/10 screen size */ - #define BYTE_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_RGB565)) /*will be 2 for RGB565 */ - static uint8_t buf1[MY_DISP_HOR_RES * MY_DISP_VER_RES / 10 * BYTE_PER_PIXEL]; - lv_display_set_buffers(display, buf1, NULL, sizeof(buf1), LV_DISPLAY_RENDER_MODE_PARTIAL); /* Initialize the display buffer. */ - - -- Implement and register a function which can copy the rendered image - to an area of your display: - - .. code-block:: c - - lv_display_set_flush_cb(display, my_disp_flush); - - void my_disp_flush(lv_display_t * disp, const lv_area_t * area, lv_color_t * color_p) - { - int32_t x, y; - /*It's a very slow but simple implementation. - *`set_pixel` needs to be written by you to a set pixel on the screen*/ - for(y = area->y1; y <= area->y2; y++) { - for(x = area->x1; x <= area->x2; x++) { - set_pixel(x, y, *color_p); - color_p++; - } - } - - lv_display_flush_ready(disp); /* Indicate you are ready with the flushing*/ - } - - -- Implement and register a function which can read an input device. E.g. for a touchpad: - - .. code-block:: c - - lv_indev_t * indev = lv_indev_create(); /*Create an input device*/ - lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); /*Touch pad is a pointer-like device*/ - lv_ondev_set_read_cb(indev, my_touchpad_read); /*Set your driver function*/ - - void my_touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) - { - /*`touchpad_is_pressed` and `touchpad_get_xy` needs to be implemented by you*/ - if(touchpad_is_pressed()) { - data->state = LV_INDEV_STATE_PRESSED; - touchpad_get_xy(&data->point.x, &data->point.y); - } else { - data->state = LV_INDEV_STATE_RELEASED; - } - } - - -- Call :cpp:func:`lv_timer_handler` periodically every few milliseconds in - the main ``while(1)`` loop or in an operating system task. It will - redraw the screen if required, handle input devices, animation etc. - - -For a more detailed guide go to the :ref:`porting` section. - - -Learn the basics ----------------- - - -.. _quick-overview_widgets: - -Widgets -~~~~~~~ - -The graphical elements like Buttons, Labels, Sliders, Charts etc. are called objects or widgets. -Go to :ref:`widgets` to see the full list of available widgets. - -Every object has a parent object where it is created. For example, if a label is created on a button, -the button is the parent of label. - -The child object moves with the parent and if the parent is deleted the children will be deleted too. - -Children can be visible only within their parent's bounding area. In other words, the parts of the -children outside the parent are clipped. - -A Screen is the "root" parent. You can have any number of screens. - -To get the current screen call :cpp:func:`lv_screen_active`, and to load a screen use :cpp:expr:`lv_screen_load(scr1)`. - -You can create a new object with ``lv__create(parent)``. It will return an :cpp:type:`lv_obj_t` ``*`` variable -that can be used as a reference to the object to set its parameters. - - -For example: - -.. code-block:: c - - lv_obj_t * slider1 = lv_slider_create(lv_screen_active()); - - -To set some basic attributes ``lv_obj_set_(obj, )`` functions can be used. For example: - -.. code-block:: c - - lv_obj_set_x(btn1, 30); - lv_obj_set_y(btn1, 10); - lv_obj_set_size(btn1, 200, 50); - - -Along with the basic attributes, widgets can have type specific parameters which are set by -``lv__set_(obj, )`` functions. For example: - -.. code-block:: c - - lv_slider_set_value(slider1, 70, LV_ANIM_ON); - - -To see the full API visit the documentation of the widgets or the related header file -(e.g. `lvgl/src/widgets/slider/lv_slider.h `__). - - -.. _quick-overview_events: - -Events -~~~~~~ - -Events are used to inform the user that something has happened with an object. You can assign one or more -callbacks to an object which will be called if the object is clicked, released, dragged, being deleted, etc. - - -A callback is assigned like this: - -.. code-block:: c - - lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL); /*Assign a callback to the button*/ - - ... - - void btn_event_cb(lv_event_t * e) - { - printf("Clicked\n"); - } - - -:cpp:enumerator:`LV_EVENT_ALL` can be used instead of :cpp:enumerator:`LV_EVENT_CLICKED` to invoke the callback for any event. - -From :cpp:expr:`lv_event_t * e` the current event code can be retrieved with: - -.. code-block:: c - - lv_event_code_t code = lv_event_get_code(e); - - -The object that triggered the event can be retrieved with: - -.. code-block:: c - - lv_obj_t * obj = lv_event_get_target(e); - - -To learn all features of the events go to the :ref:`events` section. - - -.. _quick-overview_parts: - -Parts -~~~~~ - -Widgets might be built from one or more *parts*. For example, a button -has only one part called :cpp:enumerator:`LV_PART_MAIN`. However, a -:ref:`lv_slider` has :cpp:enumerator:`LV_PART_MAIN`, :cpp:enumerator:`LV_PART_INDICATOR` -and :cpp:enumerator:`LV_PART_KNOB`. - -By using parts you can apply different styles to sub-elements of a -widget. (See below.) - -Read the widgets' documentation to learn which parts each uses. - - -.. _quick-overview_states: - -States -~~~~~~ - -LVGL objects can be in a combination of the following states: - -- :cpp:enumerator:`LV_STATE_DEFAULT`: Normal, released state -- :cpp:enumerator:`LV_STATE_CHECKED`: Toggled or checked state -- :cpp:enumerator:`LV_STATE_FOCUSED`: Focused via keypad or encoder or clicked via touchpad/mouse -- :cpp:enumerator:`LV_STATE_FOCUS_KEY`: Focused via keypad or encoder but not via touchpad/mouse -- :cpp:enumerator:`LV_STATE_EDITED`: Edit by an encoder -- :cpp:enumerator:`LV_STATE_HOVERED`: Hovered by mouse -- :cpp:enumerator:`LV_STATE_PRESSED`: Being pressed -- :cpp:enumerator:`LV_STATE_SCROLLED`: Being scrolled -- :cpp:enumerator:`LV_STATE_DISABLED`: Disabled - -For example, if you press an object it will automatically go to the -:cpp:enumerator:`LV_STATE_FOCUSED` and :cpp:enumerator:`LV_STATE_PRESSED` states and when you -release it the :cpp:enumerator:`LV_STATE_PRESSED` state will be removed while focus -remains active. - -To check if an object is in a given state use -``lv_obj_has_state(obj, LV_STATE_...)``. It will return ``true`` if the -object is currently in that state. - -To manually add or remove states use: - -.. code-block:: c - - lv_obj_add_state(obj, LV_STATE_...); - lv_obj_remove_state(obj, LV_STATE_...); - - -.. _quick-overview_styles: - -Styles -~~~~~~ - -A style instance contains properties such as background color, border width, font, etc. that describe the -appearance of objects. - -Styles are represented with :cpp:struct:`lv_style_t` variables. Only their pointer is saved in the objects so -they need to be defined as static or global. Before using a style it needs to be initialized with -:cpp:expr:`lv_style_init(&style1)`. After that, properties can be added to configure the style. For example: - -.. code-block:: c - - static lv_style_t style1; - lv_style_init(&style1); - lv_style_set_bg_color(&style1, lv_color_hex(0xa03080)) - lv_style_set_border_width(&style1, 2)) - - -See the full list of properties here :ref:`styles_properties`. - -Styles are assigned using the ORed combination of an object's part and state. For example to use this style on the slider's -indicator when the slider is pressed: - -.. code-block:: c - - lv_obj_add_style(slider1, &style1, LV_PART_INDICATOR | LV_STATE_PRESSED); - - -If the *part* is :cpp:enumerator:`LV_PART_MAIN` it can be omitted: - -.. code-block:: c - - lv_obj_add_style(btn1, &style1, LV_STATE_PRESSED); /*Equal to LV_PART_MAIN | LV_STATE_PRESSED*/ - - -Similarly, :cpp:enumerator:`LV_STATE_DEFAULT` can be omitted too: - -.. code-block:: c - - lv_obj_add_style(slider1, &style1, LV_PART_INDICATOR); /*Equal to LV_PART_INDICATOR | LV_STATE_DEFAULT*/ - - -For :cpp:enumerator:`LV_STATE_DEFAULT` and :cpp:enumerator:`LV_PART_MAIN` simply write ``0``: - -.. code-block:: c - - lv_obj_add_style(btn1, &style1, 0); /*Equal to LV_PART_MAIN | LV_STATE_DEFAULT*/ - - -Styles can be cascaded (similarly to CSS). It means you can add more styles to a part of an object. For example -``style_btn`` can set a default button appearance, and ``style_btn_red`` can overwrite the background color to -make the button red: - -.. code-block:: c - - lv_obj_add_style(btn1, &style_btn, 0); - lv_obj_add_style(btn1, &style1_btn_red, 0); - - -If a property is not set on for the current state, the style with :cpp:enumerator:`LV_STATE_DEFAULT` will be used. -A default value is used if the property is not defined in the default state. - -Some properties (typically the text-related ones) can be inherited. This means if a property is not set in an object -it will be searched for in its parents too. For example, you can set the font once in the screen's style and all text -on that screen will inherit it by default. - -Local style properties also can be added to objects. This creates a style which resides inside the object and is used -only by the object: - -.. code-block:: c - - lv_obj_set_style_bg_color(slider1, lv_color_hex(0x2080bb), LV_PART_INDICATOR | LV_STATE_PRESSED); - - -To learn all the features of styles see the :ref:`styles` section. - - -.. _quick-overview_themes: - - -Themes -~~~~~~ - -Themes are the default styles for objects. Styles from a theme are applied automatically when objects are created. - -The theme for your application is a compile time configuration set in ``lv_conf.h``. - - -.. _quick-overview_examples: - - -Examples --------- - -.. include:: ../examples/get_started/index.rst - - -.. _quick-overview_micropython: - - -MicroPython ------------ - -Learn more about :ref:`micropython`. - -.. code-block:: python - - # Initialize - import display_driver - import lvgl as lv - - # Create a button with a label - scr = lv.obj() - btn = lv.button(scr) - btn.align(lv.ALIGN.CENTER, 0, 0) - label = lv.label(btn) - label.set_text('Hello World!') - lv.screen_load(scr) diff --git a/docs/index.rst b/docs/index.rst index 557017176..9caf5f8aa 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,33 +1,64 @@ -===================================== -Welcome to the documentation of LVGL! -===================================== +=========================================== +LVGL: Light and Versatile Graphics Library +=========================================== +Create beautiful UIs for any MCU, MPU and display type. +******************************************************* .. raw:: html - Get familiar with the LVGL project - Learn the basic of LVGL and its usage on various platforms - See how to port LVGL to any platform - Learn the how LVGL works in more detail - Take a look at the description of the available widgets - Be part of the development of LVGL +
+ LVGL Documentation +
+ +.. raw:: html + +
+ Get familiar with LVGL. + Learn how LVGL works. + Get your feet wet with LVGL. + Learn how to add LVGL to your project for any platform, framework and display type. + Learn to use LVGL Widgets with examples. + Be part of LVGL's development. +
+Introduction +------------ .. toctree:: - :maxdepth: 6 + :maxdepth: 1 - intro/index + intro/introduction + intro/basics + intro/add-lvgl-to-your-project/index + + +Details +------- + +.. toctree:: + :maxdepth: 1 + + details/base-widget/index + details/widgets/index + details/main-components/index + details/other-components/index examples - get-started/index - integration/index - porting/index - overview/index - widgets/index - layouts/index - libs/index - others/index + details/debugging/index + details/integration/index + details/libs/index API/index + + +Appendix +-------- + +.. toctree:: + :maxdepth: 1 + CONTRIBUTING CODING_STYLE CHANGELOG ROADMAP + + diff --git a/docs/intro/add-lvgl-to-your-project/building_lvgl.rst b/docs/intro/add-lvgl-to-your-project/building_lvgl.rst new file mode 100644 index 000000000..5560d1078 --- /dev/null +++ b/docs/intro/add-lvgl-to-your-project/building_lvgl.rst @@ -0,0 +1,28 @@ +.. _building_lvgl: + +============= +Building LVGL +============= + + +Make and CMake +************** + +LVGL also supports ``make`` and ``CMake`` build systems out of the box. +To add LVGL to your Makefile based build system add these lines to your +main Makefile: + +.. code-block:: make + + LVGL_DIR_NAME ?= lvgl #The name of the lvgl folder (change this if you have renamed it) + LVGL_DIR ?= ${shell pwd} #The path where the lvgl folder is + include $(LVGL_DIR)/$(LVGL_DIR_NAME)/lvgl.mk + +For integration with CMake take a look this section of the +:ref:`Documentation `. + + +Managed builds +************** +TODO + diff --git a/docs/intro/add-lvgl-to-your-project/configuration.rst b/docs/intro/add-lvgl-to-your-project/configuration.rst new file mode 100644 index 000000000..553467f52 --- /dev/null +++ b/docs/intro/add-lvgl-to-your-project/configuration.rst @@ -0,0 +1,93 @@ +.. _configuration: + +============= +Configuration +============= + + + +.. _lv_conf: + +lv_conf.h +********* + + +Creating lv_conf.h +------------------ + +When setting up your project for the first time, copy ``lvgl/lv_conf_template.h`` to +``lv_conf.h`` next to the ``lvgl`` folder. Change the first ``#if 0`` to ``1`` to +enable the file's content and set the :c:macro:`LV_COLOR_DEPTH` define to align with +the color depth used by your display panel. See comments in ``lv_conf.h`` for +details. + +The layout of the files should look like this:: + + lvgl/ + lv_conf.h + other files and folders in your project + +Alternatively, ``lv_conf.h`` can be copied to another place but then you +should add the :c:macro:`LV_CONF_INCLUDE_SIMPLE` define to your compiler +options (e.g. ``-DLV_CONF_INCLUDE_SIMPLE`` for GCC compiler) and set the +include path manually (e.g. ``-I../include/gui``). In this case LVGL +will attempt to include ``lv_conf.h`` simply with ``#include "lv_conf.h"``. + +You can even use a different name for ``lv_conf.h``. The custom path can +be set via the :c:macro:`LV_CONF_PATH` define. For example +``-DLV_CONF_PATH="/home/joe/my_project/my_custom_conf.h"``. If this define +is set :c:macro:`LV_CONF_SKIP` is assumed to be ``0``. + +If :c:macro:`LV_CONF_SKIP` is defined, LVGL will not try to include +``lv_conf.h``. Instead you can pass the config defines using build +options. For example ``"-DLV_COLOR_DEPTH=32 -DLV_USE_BUTTON=1"``. Unset +options will get a default value which is the same as the content of +``lv_conf_template.h``. + +LVGL also can be used via ``Kconfig`` and ``menuconfig``. You can use +``lv_conf.h`` together with Kconfig as well, but keep in mind that the values +from ``lv_conf.h`` or build settings (``-D...``) override the values +set in Kconfig. To ignore the configs from ``lv_conf.h`` simply remove +its content, or define :c:macro:`LV_CONF_SKIP`. + + +.. _configuration_settings: + +Configuration Settings +---------------------- + +Once the ``lv_conf.h`` file is in place, you can modify this header to configure +LVGL's behavior, disable unused modules and features, adjust the size of buffers, etc. + +The comments in ``lv_conf.h`` explain the meaning of each setting. Be sure +to at least set :c:macro:`LV_COLOR_DEPTH` according to your display's color +depth. Note that the examples and demos explicitly need to be enabled +in ``lv_conf.h`` if you need them. + +TODO: Add all things related to ``lv_conf.h`` file and its contents. + + +Multiple Instances of LVGL +~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is possible to run multiple, independent isntances of LVGL. To enable its +multi-instance feature, set :c:macro:`LV_GLOBAL_CUSTOM` in ``lv_conf.h`` +and provide a custom function to :cpp:func:`lv_global_default` using ``__thread`` or +``pthread_key_t``. It will allow running multiple LVGL instances by storing LVGL's +global variables in TLS (Thread-Local Storage). + +For example: + +.. code-block:: c + + lv_global_t * lv_global_default(void) + { + static __thread lv_global_t lv_global; + return &lv_global; + } + + + +Kconfig +******* +TODO: Add how to use LVGL with Kconfig. + diff --git a/docs/intro/add-lvgl-to-your-project/connecting_lvgl.rst b/docs/intro/add-lvgl-to-your-project/connecting_lvgl.rst new file mode 100644 index 000000000..867775e61 --- /dev/null +++ b/docs/intro/add-lvgl-to-your-project/connecting_lvgl.rst @@ -0,0 +1,131 @@ +.. _connecting_lvgl: + +================================ +Connecting LVGL to Your Hardware +================================ + + +.. _initializing_lvgl: + +Initializing LVGL +***************** +After you have: + +- :ref:`acquired LVGL `, +- added the appropriate LVGL files to your project, and +- :ref:`created a lv_conf.h file ` for your project, + +you will need to complete a few more steps to get your project up and running with LVGL. + +1. Initialize LVGL once early during system execution by calling :cpp:func:`lv_init`. + This needs to be done before making any other LVGL calls. + +2. Initialize your drivers. + +3. Connect the :ref:`tick_interface`. + +4. Connect the :ref:`display_interface`. + +5. Connect the :ref:`indev_interface`. + +6. Drive LVGL time-related tasks by calling :cpp:func:`lv_timer_handler` every few + milliseconds to manage LVGL timers. See :ref:`timer_handler` for different ways + to do this. + +7. Optionally set a theme with :cpp:func:`lv_display_set_theme`. + +8. Thereafter #include "lvgl/lvgl.h" in source files wherever you need to use LVGL + functions. + + + +.. _tick_interface: + +Tick Interface +************** + +LVGL needs awareness of what time it is (i.e. elapsed time in milliseconds) for +all of its tasks for which time is a factor: refreshing displays, reading user +input, firing events, animations, etc. + +.. image:: /misc/intro_data_flow.png + :scale: 75 % + :alt: LVGL Data Flow + :align: center + +There are two ways to provide this information to LVGL: + +1. Supply LVGL with a callback function to retrieve elapsed system milliseconds by + calling :cpp:expr:`lv_tick_set_cb(my_get_milliseconds_function)`. + :cpp:expr:`my_get_milliseconds_function()` needs to return the number of + milliseconds elapsed since system start up. Many platforms have built-in + functions that can be used as they are. For example: + + - SDL: ``lv_tick_set_cb(SDL_GetTicks);`` + - Arduino: ``lv_tick_set_cb(my_tick_get_cb);``, where ``my_tick_get_cb`` is: + ``static uint32_t my_tick_get_cb(void) { return millis(); }`` + - FreeRTOS: ``lv_tick_set_cb(xTaskGetTickCount);`` + - STM32: ``lv_tick_set_cb(HAL_GetTick);`` + - ESP32: ``lv_tick_set_cb(my_tick_get_cb);``, where ``my_tick_get_cb`` is a + wrapper for ``esp_timer_get_time() / 1000;`` + +2. Call :cpp:expr:`lv_tick_inc(x)` periodically, where ``x`` is the elapsed + milliseconds since the last call. If :cpp:func:`lv_tick_inc` is called from an + ISR, it should be from either a high priority interrupt or an interrupt that + cannot be missed when the system is under high load. + + .. note:: :cpp:func:`lv_tick_inc` is only one of two LVGL functions that may be + called from an interrupt. See the :ref:`threading` section to learn more. + +The ticks (milliseconds) should be independent from any other activities of the MCU. + +For example this works, but LVGL's timing will be incorrect as the execution time of +:c:func:`lv_timer_handler` is not considered: + +.. code-block:: c + + // Bad idea + lv_timer_handler(); + lv_tick_inc(5); + my_delay_ms(5); + + + +.. _display_interface: + +Display Interface +***************** +LVGL needs to be supplied with knowledge about each display panel you want it to use. +Specificially: + +- its pixel format and size (:ref:`creating_a_display`), +- where to render pixels for it (:ref:`draw_buffers`), and +- how to send those rendered pixels to it (:ref:`flush_callback`). + +See the respective links for how to supply LVGL with this knowledge. + + + +.. _indev_interface: + +Input-Device Interface +********************** +LVGL needs to know how to get input from all user-input devices that will be used in +your project. LVGL supports a wide variety of user-input devices: + +- touch-screens, +- touch-pads, +- mice, +- crowns, +- encoders, +- keypads, +- keyboards, +- etc. + +See :ref:`indev_creation` to see how to do this. + + + +API +*** +:ref:`lv_tick_h` diff --git a/docs/intro/add-lvgl-to-your-project/getting_lvgl.rst b/docs/intro/add-lvgl-to-your-project/getting_lvgl.rst new file mode 100644 index 000000000..6db04bb62 --- /dev/null +++ b/docs/intro/add-lvgl-to-your-project/getting_lvgl.rst @@ -0,0 +1,25 @@ +.. _getting_lvgl: + +============ +Getting LVGL +============ + +LVGL is available on GitHub: https://github.com/lvgl/lvgl. + +You can clone it or +`Download `__ +the latest version of the library from GitHub. + +The graphics library itself is the ``lvgl`` directory. It contains several +directories but to use LVGL you only need the ``.c`` and ``.h`` files under +the ``src`` directory, plus ``lvgl/lvgl.h``, and ``lvgl/lv_version.h``. + + +Demos and Examples +------------------ + +The ``lvgl`` directory also contains an ``examples`` and a ``demos`` +directory. If your project needs examples and/or demos, add the these +directories to your project. If ``make`` or :ref:`build_cmake` handle the +examples and demos directories, no extra action is required. + diff --git a/docs/intro/add-lvgl-to-your-project/index.rst b/docs/intro/add-lvgl-to-your-project/index.rst new file mode 100644 index 000000000..0b53d6edf --- /dev/null +++ b/docs/intro/add-lvgl-to-your-project/index.rst @@ -0,0 +1,18 @@ +.. _add_lvgl_to_your_project: + +======================== +Add LVGL to Your Project +======================== + + +.. toctree:: + :maxdepth: 2 + + getting_lvgl + building_lvgl + configuration + connecting_lvgl + timer_handler + threading + other_platforms + diff --git a/docs/intro/add-lvgl-to-your-project/other_platforms.rst b/docs/intro/add-lvgl-to-your-project/other_platforms.rst new file mode 100644 index 000000000..e317e483d --- /dev/null +++ b/docs/intro/add-lvgl-to-your-project/other_platforms.rst @@ -0,0 +1,11 @@ +.. _other_platforms: + +========================= +Other Platforms and Tools +========================= + +See :ref:`Integration ` to see how to use LVGL on different +platforms. There, you will find many platform-specific descriptions e.g. for ESP32, +Arduino, NXP, RT-Thread, NuttX, etc. + + diff --git a/docs/intro/add-lvgl-to-your-project/threading.rst b/docs/intro/add-lvgl-to-your-project/threading.rst new file mode 100644 index 000000000..53edea76f --- /dev/null +++ b/docs/intro/add-lvgl-to-your-project/threading.rst @@ -0,0 +1,277 @@ +.. _threading: + +======================== +Threading Considerations +======================== + +.. _threading_definitions: + +Definitions +*********** + +.. _thread: + +Thread + In the context of this document, a thread is any sequence of CPU instructions. + In "bare-metal" implementations (i.e. no OS), threads include: + + - the main thread executing a while(1) loop that runs the system, and + - interrupts. + + When running under an OS, threads include: + + - each task (or process), + - interrupts, and + - advanced OSes can have multiple "execution threads" within a processes. + +.. _atomic operation: + +Atomic Operation + If operation X is atomic, that means that any thread observing the operation will + see it either as not yet started, or as completed, and not in any state that is + partially completed. + + If other threads can see the operation in a partially performed state, or + interfere with it, then operation X is not atomic. + + If an atomic operation can fail, its implementation must return the the resource + back to the state before the operation was started. To other threads it must + appear as though the operation had not yet started. + +.. _atomic data: +.. _atomic: +.. _non-atomic data: + +Atomic Data + A datum (i.e. contents of a variable or data structure) is atomic if any thread + observing it will always see it in a consistent state, as if operations on it + have either not yet started, or have been successfully completed, and not in a + state that is partially changed or otherwise inconsistent. + + When reading or writing a value is started and completed with 1 CPU instruction, + it is automatically atomic, since it can never been seen in an inconsistent + (partially-changed) state, even from a CPU interrupt or exception. With such + values, no special protection is required by programmers to ensure all threads + see it in a consistent state. + + + +.. _lvgl_and_threads: + +LVGL and Threads +**************** + +LVGL is **not thread-safe**. + +That means it is the programmer's responsibility to see that no LVGL function is +called while another LVGL call is in progress in another thread. This includes calls +to :cpp:func:`lv_timer_handler`. + +.. note:: + Assuming the above is the case, it is safe to call LVGL functions in + + - :ref:`event callbacks `, and in + - :ref:`timer callbacks ` + + because the thread that drives both of these is the thread that calls + :cpp:func:`lv_timer_handler`. + +Reason: + +LVGL manages many complex data structures, and those structures are "system +resources" that must be protected from being "seen" by other threads in an +inconsistent state. A high percentage LVGL functions (functions that start with +``lv_``) either read from or change those data structures. Those that change them +place the data in an inconsistent state during execution (because such changes are +multi-step sequences), but return them to a consistent state before those functions +return. For this reason, execution of each LVGL function must be allowed to complete +before any other LVGL function is started. + +.. _os_exception: + +.. admonition:: Exceptions to the Above: + + These two LVGL functions may be called from any thread: + + - :cpp:func:`lv_tick_inc` (see :ref:`tick_interface` for more information) and + - :cpp:func:`lv_display_flush_ready` (see :ref:`flush_callback` for more information) + + The reason this is okay is that the LVGL data changed by them is :ref:`atomic `. + + If an interrupt MUST convey information to part of your application that calls + LVGL functions, set a flag or other atomic value that your LVGL-calling thread + (or an :ref:`LVGL Timer ` you create) can read from and take action. + + If you are using an OS, there are a few other options. See below. + + +.. _tasks: + +Tasks +***** +Under an OS, it is common to have many threads of execution ("tasks" in some OSes) +performing services for the application. In some cases, such threads can acquire +data that should be shown (or otherwise reflected) in the user interface, and doing +so requires making LVGL calls to get that data (or change) shown. + +Yet it still remains the programmer's responsibility to see that no LVGL function is +called while another LVGL call is in progress. + +How do you do this? + + +.. _gateway thread: + +Method 1: Use a Gateway Thread +------------------------------- +A "Gateway Thread" (or "Gateway Task" in some OSes) is a thread (task) that the +system designer designates to *exclusively* manage a system resource. An example is +management of a remote chip, such as an EEPROM or other device that always needs to +be brought into a consistent state before something new is started. Another example +is management of multiple devices on an I2C bus (or any data bus). In this case the +I2C bus is the "exclusively-managed resource", and having only one thread managing it +guarantees that each action started is allowed to complete before another action with +it is started. + +LVGL's data structures are a system resource that requires such protection. + +Using this method, creation, modification and deletion of all Widgets and other +LVGL resources (i.e. all LVGL function calls excluding the :ref:`exceptions +` mentioned above) are called by that thread. That means +that thread is also the ONLY caller of :cpp:func:`lv_timer_handler`. (See +:ref:`add_lvgl_to_your_project` for more information.) + +This ensures LVGL's data structures "appear" atomic_ (all threads using this data +"see" it in a consistent state) by the fact that no other threads are "viewing" those +data structures. This is enforced by programmer discipline that ensures the `Gateway +Thread`_ is the only thread making LVGL calls (excluding the :ref:`exceptions +` mentioned above). + +If `atomic data`_ relevant to the user interface is updated in another thread (i.e. +by another task or in an interrupt), the thread calling LVGL functions can read that +data directly without worry that it is in an inconsistent state. (To avoid +unnecessary CPU overhead, a mechanism can be provided [such as a flag raised by the +updating thread] so that the user interface is only updated when it will result in a +change visible to the end user.) + +If `non-atomic data`_ relevant to the user interface is updated in another thread +(i.e. by another task or in an interrupt), an alternate (and safe) way of convey that +data to the thread calling LVGL functions is to pass a private copy of that data to +that thread via a QUEUE or other OS mechanism that protects that data from being seen +in an inconsistent state. + +Use of a `Gateway Thread`_ avoids the CPU-overhead (and coding overhead) of using a +MUTEX to protect LVGL data structures. + + +Method 2: Use a MUTEX +---------------------- +A MUTEX stands for "MUTually EXclusive" and is a synchronization primative that +protects the state of a system resource from being modified or accessed by multiple +threads of execution at once. In other words, it makes data so protected "appear" +atomic (all threads using this data "see" it in a consistent state). Most OSes +provide MUTEXes. + +The system designer assigns a single MUTEX to product a single system resource. Once +assigned, that MUTEX performs such protection by programmers: + +1. acquiring the MUTEX (a.k.a. locking it) before accessing or modifying that + resource, and + +2. releasing the MUTEX (a.k.a. unlocking it) after that access or modification + is complete. + +If a thread attempts to acquire (lock) the MUTEX while another thread "owns" it, +that thread waits on the other thread to release (unlock) it before it is allowed +to continue execution. + +To be clear: this must be done *both* by threads that READ from that resource, and +threads that MODIFY that resource. + +If a MUTEX is used to protect LVGL data structures, that means *every* LVGL function +call (or group of function calls) must be preceeded by #1, and followed by #2, +including calls to :cpp:func:`lv_timer_handler`. + +.. note:: + If your OS is integrated with LVGL (the macro :c:macro:`LV_USE_OS` has a value + other than ``LV_OS_NONE`` in ``lv_conf.h``) you can use :cpp:func:`lv_lock()` and + :cpp:func:`lv_unlock()` to perform #1 and #2. + + When this is the case, :cpp:func:`lv_timer_handler` calls :cpp:func:`lv_lock()` + and :cpp:func:`lv_unlock()` internally, so you do not have to bracket your + calls to :cpp:func:`lv_timer_handler` with them. + + If your OS is NOT integrated with LVGL, then these calls either return + immediately with no effect, or are optimized away by the linker. + + To enable :cpp:func:`lv_lock()` and :cpp:func:`lv_unlock()`, set ``LV_USE_OS`` + to a value other than ``LV_OS_NONE``. + +This pseudocode illustrates the concept of using a MUTEX: + +.. code-block:: c + + void lvgl_thread(void) + { + while(1) { + uint32_t time_till_next; + time_till_next = lv_timer_handler(); /* lv_lock/lv_unlock is called internally */ + thread_sleep(time_till_next); /* sleep for a while */ + } + } + + void other_thread(void) + { + /* You must always hold (lock) the MUTEX while calling LVGL functions. */ + lv_lock(); + lv_obj_t *img = lv_image_create(lv_screen_active()); + lv_unlock(); + + while(1) { + lv_lock(); + /* Change to next image. */ + lv_image_set_src(img, next_image); + lv_unlock(); + thread_sleep(2000); + } + } + + + +.. _sleep_management: + +Sleep Management +**************** + +The MCU can go to sleep when no user input has been received for a certain period. +In this case, the main ``while(1)`` could look like this: + +.. code-block:: c + + while(1) { + /* Normal operation (no sleep) in < 1 sec inactivity */ + if(lv_display_get_inactive_time(NULL) < 1000) { + lv_timer_handler(); + } + /* Sleep after 1 sec inactivity */ + else { + timer_stop(); /* Stop the timer where lv_tick_inc() is called */ + sleep(); /* Sleep the MCU */ + } + my_delay_ms(5); + } + +You should also add the following lines to your input device read +function to signal a wake-up (press, touch, click, etc.) has happened: + +.. code-block:: c + + lv_tick_inc(LV_DEF_REFR_PERIOD); /* Force task execution on wake-up */ + timer_start(); /* Restart timer where lv_tick_inc() is called */ + lv_timer_handler(); /* Call `lv_timer_handler()` manually to process the wake-up event */ + +In addition to :cpp:func:`lv_display_get_inactive_time` you can check +:cpp:func:`lv_anim_count_running` to see if all animations have finished. + + + diff --git a/docs/porting/timer_handler.rst b/docs/intro/add-lvgl-to-your-project/timer_handler.rst similarity index 73% rename from docs/porting/timer_handler.rst rename to docs/intro/add-lvgl-to-your-project/timer_handler.rst index 72bde4bd6..f517baa28 100644 --- a/docs/porting/timer_handler.rst +++ b/docs/intro/add-lvgl-to-your-project/timer_handler.rst @@ -4,12 +4,16 @@ Timer Handler ============= -To handle the tasks of LVGL you need to call :cpp:func:`lv_timer_handler` +To drive the timers of LVGL you need to call :cpp:func:`lv_timer_handler` periodically in one of the following: -- *while(1)* of *main()* function -- timer interrupt periodically (lower priority than :cpp:func:`lv_tick_inc`) -- an OS task periodically +- *while(1)* of *main()* function, or +- an OS task periodically. (See :ref:`lvgl_and_threads`.) + +.. image:: /misc/intro_data_flow.png + :scale: 75 % + :alt: LVGL Data Flow + :align: center Example: @@ -22,7 +26,7 @@ Example: If you want to use :cpp:func:`lv_timer_handler` in a super-loop, a helper function :cpp:func:`lv_timer_handler_run_in_period` is provided to simplify -the porting: +supplying LVGL with time awareness: .. code-block:: c @@ -52,8 +56,8 @@ In an OS environment, you can use it together with the **delay** or os_delay_ms(time_till_next); /* delay to avoid unnecessary polling */ } -To learn more about timers visit the :ref:`timers` -section. +See :ref:`timer` section to learn more about timers. + API *** diff --git a/docs/intro/basics.rst b/docs/intro/basics.rst new file mode 100644 index 000000000..adab061ae --- /dev/null +++ b/docs/intro/basics.rst @@ -0,0 +1,468 @@ +.. _lvgl_basics: + +=========== +LVGL Basics +=========== + +LVGL (Light and Versatile Graphics Library) is a free and open-source graphics +library providing everything you need to create an embedded GUI with easy-to-use +graphical elements, beautiful visual effects, and a low memory footprint. + +How does it do this? + + + +.. _basic_data_flow: + +Overview of LVGL's Data Flow +**************************** + +.. figure:: /misc/intro_data_flow.png + :scale: 75 % + :alt: LVGL Data Flow + :align: center + :figwidth: image + + Overview of LVGL Data Flow + + +You create one :ref:`display` for each physical display panel, create +:ref:`basics_screen_widgets` on them, add :ref:`basics_widgets` onto those Screens. +To handle touch, mouse, keypad, etc., you :ref:`create an Input Device ` +for each. The :ref:`tick_interface` tells LVGL what time is it. :ref:`timer_handler` +drives LVGL's timers which, in turn, perform all of LVGL's time-related tasks: + +- periodically refreshes displays, +- reads input devices, +- fires events, +- runs any animations, and +- runs user-created timers. + + +.. _applications_job: + +Application's Job +----------------- + +After initialization, the application's job is merely to create Widget Trees when +they are needed, manage events those Widgets generate (by way of user interaction +and other things), and delete them when they are no longer needed. LVGL takes care +of the rest. + + + +.. _basics_major_concepts: + +Major Concepts +************** + + +.. _display-vs-screen: + +Display vs Screen +----------------- +Before we get into any details about Widgets, let us first clarify the difference +between two terms that you will hereafter see frequently: + +- A **Display** or **Display Panel** is the physical hardware displaying the pixels. +- A :ref:`display` object is an object in RAM that represents a **Display** meant + to be used by LVGL. +- A **Screen** is the "root" Widget in the Widget Trees mentioned above, and are + "attached to" a particular :ref:`display`. + + +Default Display +--------------- +When the first :ref:`display` object is created, it becomes the Default Display. +Many functions related to Screen Widgets use the default display. +See :ref:`default_display` for more information. + + +.. _basics_screen_widgets: + +Screen Widgets +-------------- +In this documentation, the term "Screen Widget" is frequently shortened to just +"Screen". But it is important to understand that a "Screen" is simply any +:ref:`Widget ` created without a parent --- the "root" of each Widget Tree. + +See :ref:`screens` for more details. + + +Active Screen +------------- + +The Active Screen is the screen (and its child Widgets) currently being displayed. +See :ref:`active_screen` for more information. + + +.. _basics_widgets: + +Widgets +------- +After LVGL is initialized (see :ref:`initializing_lvgl`), to create an interactive +user interface, an application next creates a tree of Widgets that LVGL can render to +the associated dislay, and with which the user can interact. + +Widgets are "intelligent" LVGL graphical elements such as :ref:`Base Widgets +` (simple rectangles and :ref:`screens`), Buttons, Labels, +Checkboxes, Switches, Sliders, Charts, etc. Go to :ref:`widgets` to see the full +list. + +To build this Widget Tree, the application first acquires a pointer to a Screen Widget. +A system designer is free to use the default Screen created with the :ref:`display` +and/or create his own. To create a new Screen Widget, simply create a Widget passing +NULL as the parent argument. Technically, this can be any type of Widget, but in +most cases it is a :ref:`base_widget_overview`. (An example of another type of +Widget being used as a Screen is an :ref:`lv_image` Widget to supply an image for the +background.) + +The application then adds Widgets to this Screen as children in the tree. Widgets +are automatically added as children to their parent Widgets at time of creation --- +the Widget's parent is passed as the first argument to the function that creates +the Widget. After being so added, we say that the parent Widget "contains" the +child Widget. + +Any Widget can contain other Widgets. For example, if you want a Button to have +text, create a Label Widget and add it to the Button as a child. + +Each child Widget becomes "part of" its parent Widget. Because of this relationship: + +- when the parent Widget moves, its children move with it; +- when the parent Widget is deleted, its children are deleted with it; +- a child Widget is only visible within its parent's boundaries; any part of a child + outside its parent's boundaries is clipped (i.e. not rendered). + +Screens (and their child Widgets) can be created and deleted at any time *except* +when the Screen is the :ref:`active_screen`. If you want to delete the current Screen +as you load a new one, call :cpp:func:`lv_screen_load_anim` and pass ``true`` for the +``auto_del`` argument. If you want to keep the current Screen in RAM when you load a +new Screen, pass ``false`` for the ``auto_del`` argument, or call +:cpp:func:`lv_screen_active` to load the new screen. + +A system designer is free to keep any number of Screens (and their child Widgets) in +RAM (e.g. for quick re-display again later). Doing so: + +- requires more RAM, but +- can save the time of repeatedly creating the Screen and its child Widgets; +- can be handy when a Screen is complex and/or can be made the :ref:`active_screen` freqently. + +If multiple Screens are maintained in RAM simultaneously, it is up to the system +designer as to how they are managed. + + +.. _basics_creating_widgets: + +Creating Widgets +~~~~~~~~~~~~~~~~ +Widgets are created by calling functions that look like this:: + + lv__create(parent) + +The call will return an :cpp:type:`lv_obj_t` ``*`` pointer that can be used later to +reference the Widget to set its attributes. + +For example: + +.. code-block:: c + + lv_obj_t * slider1 = lv_slider_create(lv_screen_active()); + + +.. _basics_modifying_widgets: + +Modifying Widgets +~~~~~~~~~~~~~~~~~ +Attributes common to all Widgets are set by functions that look like this:: + + lv_obj_set_(widget, ) + +For example: + +.. code-block:: c + + lv_obj_set_x(slider1, 30); + lv_obj_set_y(slider1, 10); + lv_obj_set_size(slider1, 200, 50); + +Along with these attributes, widgets can have type-specific attributes which are +set by functions that look like this:: + + lv__set_(widget, ) + +For example: + +.. code-block:: c + + lv_slider_set_value(slider1, 70, LV_ANIM_ON); + +To see the full API visit the documentation of the Widget in question under +:ref:`widgets` or study its related header file in the source code, e.g. + +- lvgl/src/widgets/slider/lv_slider.h + +or view it on GitHub, e.g. + +- https://github.com/lvgl/lvgl/blob/master/src/widgets/slider/lv_slider.h . + + +.. _basics_deleting_widgets: + +Deleting Widgets +~~~~~~~~~~~~~~~~ +To delete any widget and its children:: + + lv_obj_delete(lv_obj_t * widget) + + + +.. _basics_events: + +Events +------ + +Events are used to inform the application that something has happened with a Widget. +You can assign one or more callbacks to a Widget which will be called when the +Widget is clicked, released, dragged, being deleted, etc. + +A callback is assigned like this: + +.. code-block:: c + + lv_obj_add_event_cb(btn, my_btn_event_cb, LV_EVENT_CLICKED, NULL); + + ... + + void my_btn_event_cb(lv_event_t * e) + { + printf("Clicked\n"); + } + +:cpp:enumerator:`LV_EVENT_ALL` can be used instead of :cpp:enumerator:`LV_EVENT_CLICKED` +to invoke the callback for all events. (Beware: there are a LOT of events! This can +be handy for debugging or learning what events occur for a given Widget, or indeed +if the application needs to process all events for some reason.) + +Event callbacks receive the argument :cpp:expr:`lv_event_t * e` containing the +current event code and other event-related information. The current event code can +be retrieved with: + +.. code-block:: c + + lv_event_code_t code = lv_event_get_code(e); + +The Widget that triggered the event can be retrieved with: + +.. code-block:: c + + lv_obj_t * obj = lv_event_get_target(e); + +To learn all features of the events go to the :ref:`events` section. + + +.. _basics_parts: + +Parts +----- + +Widgets are built from one or more *parts*. For example, a button +has only one part called :cpp:enumerator:`LV_PART_MAIN`. However, a +:ref:`lv_slider` has :cpp:enumerator:`LV_PART_MAIN`, :cpp:enumerator:`LV_PART_INDICATOR` +and :cpp:enumerator:`LV_PART_KNOB`. + +By using parts you can apply different styles to sub-elements of a widget. (See below.) + +Read the Widget's documentation to learn which parts it uses. + + +.. _basics_states: + +States +------ + +Widgets can be in a combination of the following states: + +- :cpp:enumerator:`LV_STATE_DEFAULT`: Normal, released state +- :cpp:enumerator:`LV_STATE_CHECKED`: Toggled or checked state +- :cpp:enumerator:`LV_STATE_FOCUSED`: Focused via keypad or encoder or clicked via touchpad/mouse +- :cpp:enumerator:`LV_STATE_FOCUS_KEY`: Focused via keypad or encoder but not via touchpad/mouse +- :cpp:enumerator:`LV_STATE_EDITED`: Edit by an encoder +- :cpp:enumerator:`LV_STATE_HOVERED`: Hovered by mouse +- :cpp:enumerator:`LV_STATE_PRESSED`: Being pressed +- :cpp:enumerator:`LV_STATE_SCROLLED`: Being scrolled +- :cpp:enumerator:`LV_STATE_DISABLED`: Disabled + +For example, if you press a Widget it will automatically go to the +:cpp:enumerator:`LV_STATE_FOCUSED` and :cpp:enumerator:`LV_STATE_PRESSED` states and when you +release it the :cpp:enumerator:`LV_STATE_PRESSED` state will be removed while the +:cpp:enumerator:`LV_STATE_FOCUSED` state remains active. + +To check if a Widget is in a given state use +:cpp:expr:`lv_obj_has_state(widget, LV_STATE_...)`. It will return ``true`` if the +Widget is currently in that state. + +To manually add or remove states use: + +.. code-block:: c + + lv_obj_add_state(widget, LV_STATE_...); + lv_obj_remove_state(widget, LV_STATE_...); + + +.. _basics_styles: + +Styles +------ + +A style instance contains properties such as background color, border +width, font, etc. that describe the appearance of Widgets. + +Styles are carried in :cpp:struct:`lv_style_t` objects. Only their pointer is saved +in the Widgets so they need to be defined as static or global variables. Before +using a style it needs to be initialized with :cpp:expr:`lv_style_init(&style1)`. +After that, properties can be added to configure the style. For example: + +.. code-block:: c + + static lv_style_t style1; + lv_style_init(&style1); + lv_style_set_bg_color(&style1, lv_color_hex(0xa03080)) + lv_style_set_border_width(&style1, 2)) + +See :ref:`style_properties_overview` for more details. + +See :ref:`style_properties` to see the full list. + +Styles are assigned using the OR-ed combination of a Widget's part and +state. For example to use this style on the slider's indicator when the +slider is pressed: + +.. code-block:: c + + lv_obj_add_style(slider1, &style1, LV_PART_INDICATOR | LV_STATE_PRESSED); + +If the *part* is :cpp:enumerator:`LV_PART_MAIN` it can be omitted: + +.. code-block:: c + + lv_obj_add_style(btn1, &style1, LV_STATE_PRESSED); /* Equal to LV_PART_MAIN | LV_STATE_PRESSED */ + +Similarly, :cpp:enumerator:`LV_STATE_DEFAULT` can be omitted: + +.. code-block:: c + + lv_obj_add_style(slider1, &style1, LV_PART_INDICATOR); /* Equal to LV_PART_INDICATOR | LV_STATE_DEFAULT */ + +For :cpp:enumerator:`LV_STATE_DEFAULT` | :cpp:enumerator:`LV_PART_MAIN` simply pass ``0``: + +.. code-block:: c + + lv_obj_add_style(btn1, &style1, 0); /* Equal to LV_PART_MAIN | LV_STATE_DEFAULT */ + +Styles can be cascaded (similarly to CSS). This means you can add more +styles to a part of a Widget. For example ``style_btn`` can set a +default button appearance, and ``style_btn_red`` can overwrite the +background color to make the button red: + +.. code-block:: c + + lv_obj_add_style(btn1, &style_btn, 0); + lv_obj_add_style(btn1, &style1_btn_red, 0); + +If a property is not set for the current state, the style with +:cpp:enumerator:`LV_STATE_DEFAULT` will be used. A default value is used if the +property is not defined in the default state. + +Some properties (particularly the text-related ones) can be inherited. This +means if a property is not set in a Widget it will be searched for in +its parents. For example, you can set the font once in the screen's +style and all text on that screen will inherit it by default. + +Local style properties also can be added to Widgets. This creates a +style which resides inside the Widget and is used only by that Widget: + +.. code-block:: c + + lv_obj_set_style_bg_color(slider1, lv_color_hex(0x2080bb), LV_PART_INDICATOR | LV_STATE_PRESSED); + +To learn all the features of styles see :ref:`styles`. + + +.. _basics_themes: + +Themes +------ + +Themes are the default styles for Widgets. Styles from a theme are +applied automatically when Widgets are created. + +The theme for your application is a compile time configuration set in +``lv_conf.h``. + + +.. _basics_micropython: + +MicroPython +----------- + +LVGL can even be used with :ref:`micropython`. + +.. code-block:: python + + # Initialize + import display_driver + import lvgl as lv + + # Create a button with a label + scr = lv.obj() + btn = lv.button(scr) + btn.align(lv.ALIGN.CENTER, 0, 0) + label = lv.label(btn) + label.set_text('Hello World!') + lv.screen_load(scr) + + + +.. _going_deeper: + +Going Deeper +************* + +There are several good ways ways to gain deeper knowledge of LVGL. Here is one +recommended order of documents to read and things to play with while you are +advancing your knowledge: + +1. If not already read, start with :ref:`introduction` page of + the documentation. (5 minutes) +2. Check out the `Online Demos`_ to see LVGL in action. (3 minutes) +3. If not already done, read the :ref:`lvgl_basics` (above). (15 minutes) +4. Set up an LVGL :ref:`simulator`. (10 minutes) +5. Have a look at some :ref:`examples` and their code. +6. Add LVGL to your project. See :ref:`add_lvgl_to_your_project` or check out + the `ready-to-use Projects`_. +7. Read the :ref:`main_components` pages to get a better understanding of the library. (2-3 hours) +8. Skim the documentation of :ref:`widgets` to see what is available. +9. If you have questions go to the `Forum`_. +10. Read the :ref:`contributing` guide to see how you can help to improve LVGL. (15 minutes) + + +.. _online demos: https://lvgl.io/demos +.. _ready-to-use projects: https://github.com/lvgl?q=lv_port_&type=&language= +.. _forum: https://forum.lvgl.io/ + + + +.. _basics_examples: + +Basic Examples +************** + +Below are several basic examples. They include the application code that produces +the Widget Tree needed to make LVGL render the examples shown. Each example assumes +a LVGL has undergone normal initialization, meaning that a ``lv_display_t`` object +was created and therefore has an :ref:`active_screen`. + + +.. include:: ../examples/get_started/index.rst + + diff --git a/docs/intro/index.rst b/docs/intro/index.rst index 2e3ecd4b2..8b8280b36 100644 --- a/docs/intro/index.rst +++ b/docs/intro/index.rst @@ -1,290 +1,11 @@ -.. _introduction: +.. _intro-page: -============ Introduction ============ -LVGL (Light and Versatile Graphics Library) is a free and open-source graphics library providing everything you need to create an embedded GUI with easy-to-use graphical elements, beautiful visual effects and a low memory footprint. +.. toctree:: + :maxdepth: 1 - -Key features ------------- - -- Powerful building blocks such as buttons, charts, lists, sliders, images, etc. -- Advanced graphics with animations, anti-aliasing, opacity, smooth scrolling -- Various input devices such as touchpad, mouse, keyboard, encoder, etc. -- Multi-language support with UTF-8 encoding -- Multi-display support, i.e. use multiple TFT, monochrome displays simultaneously -- Fully customizable graphic elements with CSS-like styles -- Hardware independent: use with any microcontroller or display -- Scalable: able to operate with little memory (64 kB Flash, 16 kB RAM) -- OS, external memory and GPU are supported but not required -- Single frame buffer operation even with advanced graphic effects -- Written in C for maximal compatibility (C++ compatible) -- Simulator to start embedded GUI design on a PC without embedded hardware -- Binding to MicroPython -- Tutorials, examples, themes for rapid GUI design -- Documentation is available online and as PDF -- Free and open-source under MIT license - -.. _requirements: - -Requirements ------------- - -Basically, every modern controller which is able to drive a display is suitable to run LVGL. The minimal requirements are: - -* 16, 32 or 64 bit microcontroller or processor -* > 16 MHz clock speed is recommended -* Flash/ROM: > 64 kB for the very essential components (> 180 kB is recommended) -* RAM: - * Static RAM usage: ~2 kB depending on the used features and object types - * stack: > 2kB (> 8 kB is recommended) - * Dynamic data (heap): > 2 KB (> 48 kB is recommended if using several objects). - Set by :c:macro:`LV_MEM_SIZE` in ``lv_conf.h``. - * Display buffer: > *"Horizontal resolution"* pixels (> 10 *"Horizontal resolution"* is recommended) - * One frame buffer in the MCU or in an external display controller -* C99 or newer compiler -* Basic C (or C++) knowledge: - * `pointers `_. - * `structs `_. - * `callbacks `_. - - - -:Note: *memory usage may vary depending on architecture, compiler and build options.* - -License -------- - -The LVGL project (including all repositories) is licensed under `MIT license `_. -This means you can use it even in commercial projects. - -It's not mandatory, but we highly appreciate it if you write a few words about your project in the `My projects `_ category of the forum or a private message to `lvgl.io `_. - -Although you can get LVGL for free there is a massive amount of work behind it. It's created by a group of volunteers who made it available for you in their free time. - -To make the LVGL project sustainable, please consider :ref:`contributing` to the project. -You can choose from many different ways of contributing See :ref:`contributing` such as simply writing a tweet about you using LVGL, fixing bugs, translating the documentation, or even becoming a maintainer. - -Repository layout ------------------ - -All repositories of the LVGL project are hosted on `GitHub `_ - -You will find these repositories there: - -* `lvgl `_: The library itself with many `examples `_ and `demos `_. -* `lv_drivers `_: Display and input device drivers -* `blog `_: Source of the `blog's site `_ -* `sim `_: Source of the `online simulator's site `_ -* `lv_port_* `_: LVGL ports to development boards or environments -* `lv_binding_* `_: Bindings to other languages - -Release policy --------------- - -The core repositories follow the rules of `Semantic versioning `_: - -* Major version: incompatible API changes. E.g. v5.0.0, v6.0.0 -* Minor version: new but backward-compatible functionalities. E.g. v6.1.0, v6.2.0 -* Patch version: backward-compatible bug fixes. E.g. v6.1.1, v6.1.2 - -Tags like `vX.Y.Z` are created for every release. - - -Release cycle -^^^^^^^^^^^^^ - -* Bug fixes: Released on demand even weekly -* Minor releases: Every 3-4 months -* Major releases: Approximately yearly - -Branches -^^^^^^^^ - -The core repositories have at least the following branches: - -* `master`: latest version, patches are merged directly here. -* `release/vX.Y`: stable versions of the minor releases -* `fix/some-description`: temporary branches for bug fixes -* `feat/some-description`: temporary branches for features - - -Changelog -^^^^^^^^^ - -The changes are recorded in :ref:`changelog`. - -Version support -^^^^^^^^^^^^^^^ - -Before v8 the last minor release of each major series was supported for 1 year. -Starting from v8, every minor release is supported for 1 year. - - -+---------+--------------+--------------+--------+ -| Version | Release date | Support end | Active | -+=========+==============+==============+========+ -|v5.3 | 1 Feb, 2019 | 1 Feb, 2020 | No | -+---------+--------------+--------------+--------+ -|v6.1 | 26 Nov, 2019 | 26 Nov, 2020 | No | -+---------+--------------+--------------+--------+ -|v7.11 | 16 Mar, 2021 | 16 Mar, 2022 | No | -+---------+--------------+--------------+--------+ -|v8.0 | 1 Jun, 2021 | 1 Jun, 2022 | No | -+---------+--------------+--------------+--------+ -|v8.1 | 10 Nov, 2021 | 10 Nov, 2022 | No | -+---------+--------------+--------------+--------+ -|v8.2 | 31 Jan, 2022 | 31 Jan, 2023 | No | -+---------+--------------+--------------+--------+ -|v8.3 | 6 July, 2022 | 1 Jan, 2025 | Yes | -+---------+--------------+--------------+--------+ -|v8.4 | Mar 19, 2024 | Mar 20, 2025 | Yes | -+---------+--------------+--------------+--------+ -|v9.0 | Jan 22, 2024 | Jan 22, 2025 | Yes | -+---------+--------------+--------------+--------+ -|v9.1 | Mar 20, 2024 | Mar 20, 2025 | Yes | -+---------+--------------+--------------+--------+ -|v9.2 | Aug 26, 2024 | Aug 26, 2025 | Yes | -+---------+--------------+--------------+--------+ - - -FAQ ---- - -Where can I ask questions? -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -You can ask questions in the forum: `https://forum.lvgl.io/ `_. - -We use `GitHub issues `_ for development related discussion. -You should use them only if your question or issue is tightly related to the development of the library. - -Before posting a question, please ready this FAQ section as you might find answer to your issue here too. - - -Is my MCU/hardware supported? -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Every MCU which is capable of driving a display via parallel port, SPI, RGB interface or anything else and fulfills the :ref:`requirements` is supported by LVGL. - -This includes: - -* "Common" MCUs like STM32F, STM32H, NXP Kinetis, LPC, iMX, dsPIC33, PIC32, SWM341 etc. -* Bluetooth, GSM, Wi-Fi modules like Nordic NRF, Espressif ESP32 and Raspberry Pi Pico W -* Linux with frame buffer device such as /dev/fb0. This includes Single-board computers like the Raspberry Pi -* Anything else with a strong enough MCU and a peripheral to drive a display - - -Is my display supported? -^^^^^^^^^^^^^^^^^^^^^^^^ - -LVGL needs just one simple driver function to copy an array of pixels into a given area of the display. -If you can do this with your display then you can use it with LVGL. - -Some examples of the supported display types: - -* TFTs with 16 or 24 bit color depth -* Monitors with an HDMI port -* Small monochrome displays -* Gray-scale displays -* even LED matrices -* or any other display where you can control the color/state of the pixels - -See the :ref:`display_interface` section to learn more. - - -LVGL doesn't start, randomly crashes or nothing is drawn on the display. What can be the problem? -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -* Try increasing :c:macro:`LV_MEM_SIZE`. -* Be sure your display works without LVGL. E.g. paint it to red on start up. -* Enable :ref:`logging` -* Enable asserts in ``lv_conf.h`` (`LV_USE_ASSERT_...`) -* If you use an RTOS - * increase the stack size of the task which calls :cpp:func:`lv_timer_handler` - * Be sure you used a mutex as described here: :ref:`os_interrupt` - - -My display driver is not called. What have I missed? -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Be sure you are calling :cpp:expr:`lv_tick_inc(x)` in an interrupt and :cpp:func:`lv_timer_handler` in your main ``while(1)``. - -Learn more in the :ref:`tick` and :ref:`timer_handler` sections. - - -Why is the display driver called only once? Only the upper part of the display is refreshed. -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Be sure you are calling :cpp:expr:`lv_display_flush_ready(drv)` at the end of your "*display flush callback*". - - -Why do I see only garbage on the screen? -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Probably there a bug in your display driver. Try the following code without using LVGL. You should see a square with red-blue gradient. - -.. code-block:: c - - #define BUF_W 20 - #define BUF_H 10 - - lv_color_t buf[BUF_W * BUF_H]; - lv_color_t * buf_p = buf; - uint16_t x, y; - for(y = 0; y < BUF_H; y++) { - lv_color_t c = lv_color_mix(LV_COLOR_BLUE, LV_COLOR_RED, (y * 255) / BUF_H); - for(x = 0; x < BUF_W; x++){ - (*buf_p) = c; - buf_p++; - } - } - - lv_area_t a; - a.x1 = 10; - a.y1 = 40; - a.x2 = a.x1 + BUF_W - 1; - a.y2 = a.y1 + BUF_H - 1; - my_flush_cb(NULL, &a, buf); - - -Why do I see nonsense colors on the screen? -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Probably LVGL's color format is not compatible with your display's color format. Check :c:macro:`LV_COLOR_DEPTH` in *lv_conf.h*. - - -How to speed up my UI? -^^^^^^^^^^^^^^^^^^^^^^ - -- Turn on compiler optimization and enable cache if your MCU has it -- Increase the size of the display buffer -- Use two display buffers and flush the buffer with DMA (or similar peripheral) in the background -- Increase the clock speed of the SPI or parallel port if you use them to drive the display -- If your display has an SPI port consider changing to a model with a parallel interface because it has much higher throughput -- Keep the display buffer in internal RAM (not in external SRAM) because LVGL uses it a lot and it should have a fast access time - - -How to reduce flash/ROM usage? -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -You can disable all the unused features (such as animations, file system, GPU etc.) and object types in *lv_conf.h*. - -If you are using GCC/CLANG you can add `-fdata-sections -ffunction-sections` compiler flags and `--gc-sections` linker flag to remove unused functions and variables from the final binary. If possible, add the `-flto` compiler flag to enable link-time-optimisation together with `-Os` for GCC or `-Oz` for CLANG. - - -How to reduce the RAM usage -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -* Lower the size of the *Display buffer* -* Reduce :c:macro:`LV_MEM_SIZE` in *lv_conf.h*. This memory is used when you create objects like buttons, labels, etc. -* To work with lower :c:macro:`LV_MEM_SIZE` you can create objects only when required and delete them when they are not needed anymore - - -How to work with an operating system? -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -To work with an operating system where tasks can interrupt each other (preemptively) you should protect LVGL related function calls with a mutex. -See the :ref:`os_interrupt` section to learn more. + introduction + basics + add-lvgl-to-your-project/index diff --git a/docs/intro/introduction.rst b/docs/intro/introduction.rst new file mode 100644 index 000000000..49e2858e0 --- /dev/null +++ b/docs/intro/introduction.rst @@ -0,0 +1,304 @@ +.. _introduction: + +============ +Introduction +============ + +LVGL (Light and Versatile Graphics Library) is a free and open-source graphics +library providing everything you need to create an embedded GUI with easy-to-use +graphical elements, beautiful visual effects, and a low memory footprint. + + +Key features +------------ + +- Powerful building blocks such as :ref:`buttons, charts, lists, sliders, images `, etc. +- Advanced graphics with animations, anti-aliasing, opacity, smooth scrolling +- Various input devices such as touchpad, mouse, keyboard, encoder, etc. +- Multi-language support with UTF-8 encoding +- Multi-display support, even with mixed color formats +- Fully customizable graphic elements with CSS-like styles +- Hardware independent: use with any microcontroller or display +- Scalable: able to operate with little memory (64 kB Flash, 16 kB RAM) +- :ref:`OS `, external memory and :ref:`GPU ` are supported but not required +- Single frame buffer operation even with advanced graphic effects +- Written in C for maximal compatibility (C++ compatible) +- :ref:`Simulator ` to start embedded GUI design on a PC without embedded hardware +- User code developed under similator can be shared with firmware to make UI development more efficient. +- Binding to :ref:`MicroPython` +- Tutorials, examples, themes for rapid GUI design +- Documentation is available online +- Free and open-source under MIT license + + +.. _requirements: + +Requirements +------------ + +Basically, every modern controller which is able to drive a display is suitable to run LVGL. The minimal requirements are: + +* 16, 32 or 64 bit microcontroller or processor +* > 16 MHz clock speed is recommended +* Flash/ROM: > 64 kB for the very essential components (> 180 kB is recommended) +* RAM: + * Static RAM usage: ~2 kB depending on the used features and Widget types + * stack: > 2kB (> 8 kB recommended) + * Dynamic data (heap): > 2 KB (> 48 kB is recommended if using many GUI Widgets). + Set by :c:macro:`LV_MEM_SIZE` in ``lv_conf.h``. + * Display buffer: > *"Horizontal resolution"* pixels (> 10 X *"Horizontal resolution"* is recommended) + * One frame buffer in the MCU or in an external display controller +* C99 or newer compiler +* Basic C (or C++) knowledge: + * `pointers `__. + * `structs `__. + * `callbacks `__. + +.. note:: + *Memory usage may vary depending on architecture, compiler and build options.* + + +License +------- + +The LVGL project (including all repositories) is licensed under the `MIT license `__. +This means you can use it even in commercial projects. + +It is not mandatory, but we highly appreciate it if you write a few words about your project in the `My projects `__ category of the forum or a private message to `lvgl.io `__. + +Although you can get LVGL for free there is a massive amount of work behind it. It's created by a group of volunteers who made it available for you in their free time. + +To make the LVGL project sustainable, please consider :ref:`contributing` to the project. +You can choose from many different ways of contributing See :ref:`contributing` such as simply writing a tweet about you using LVGL, fixing bugs, translating the documentation, or even becoming a maintainer. + + +Repository layout +----------------- + +All repositories of the LVGL project are hosted on `GitHub `_. + +You will find these repositories there: + +* `lvgl `__: The library itself with many `examples `_ and `demos `__. +* `lv_drivers `__: Display and input device drivers +* `blog `__: Source of the `blog's site `__ +* `sim `__: Source of the `online simulator's site `__ +* `lv_port_* `__: LVGL ports to development boards or environments +* `lv_binding_* `__: Bindings to other languages + + +Release policy +-------------- + +The core repositories follow the rules of `Semantic Versioning `__: + +* Major version: incompatible API changes. E.g. v5.0.0, v6.0.0 +* Minor version: new but backward-compatible functionalities. E.g. v6.1.0, v6.2.0 +* Patch version: backward-compatible bug fixes. E.g. v6.1.1, v6.1.2 + +Tags like `vX.Y.Z` are created for every release. + + +Release cycle +^^^^^^^^^^^^^ + +* Bug fixes: released on demand even weekly +* Minor releases: every 3-4 months +* Major releases: approximately yearly + + +Branches +^^^^^^^^ + +The core repositories have at least the following branches: + +* `master`: latest version, patches are merged directly here +* `release/vX.Y`: stable versions of the minor releases +* `fix/some-description`: temporary branches for bug fixes +* `feat/some-description`: temporary branches for features + + +Change log +^^^^^^^^^^ + +The changes are recorded in :ref:`changelog`. + + +Version support +^^^^^^^^^^^^^^^ + +Before v8 the last minor release of each major series was supported for 1 year. +Starting from v8, every minor release is supported for 1 year. + + ++---------+--------------+--------------+--------+ +| Version | Release date | Support end | Active | ++=========+==============+==============+========+ +|v5.3 | 1 Feb, 2019 | 1 Feb, 2020 | No | ++---------+--------------+--------------+--------+ +|v6.1 | 26 Nov, 2019 | 26 Nov, 2020 | No | ++---------+--------------+--------------+--------+ +|v7.11 | 16 Mar, 2021 | 16 Mar, 2022 | No | ++---------+--------------+--------------+--------+ +|v8.0 | 1 Jun, 2021 | 1 Jun, 2022 | No | ++---------+--------------+--------------+--------+ +|v8.1 | 10 Nov, 2021 | 10 Nov, 2022 | No | ++---------+--------------+--------------+--------+ +|v8.2 | 31 Jan, 2022 | 31 Jan, 2023 | No | ++---------+--------------+--------------+--------+ +|v8.3 | 6 July, 2022 | 1 Jan, 2025 | Yes | ++---------+--------------+--------------+--------+ +|v8.4 | Mar 19, 2024 | Mar 20, 2025 | Yes | ++---------+--------------+--------------+--------+ +|v9.0 | Jan 22, 2024 | Jan 22, 2025 | Yes | ++---------+--------------+--------------+--------+ +|v9.1 | Mar 20, 2024 | Mar 20, 2025 | Yes | ++---------+--------------+--------------+--------+ +|v9.2 | Aug 26, 2024 | Aug 26, 2025 | Yes | ++---------+--------------+--------------+--------+ + + +FAQ +--- + +Where can I ask questions? +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can ask questions in the forum: https://forum.lvgl.io/. + +We use `GitHub issues `_ for development related discussion. +You should use them only if your question or issue is tightly related to the development of the library. + +Before posting a question, please read this FAQ section since you might find the answer to your issue here as well. + + +Is my MCU/hardware supported? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Every MCU which is capable of driving a display via parallel port, SPI, RGB interface or anything else and fulfills the :ref:`requirements` is supported by LVGL. + +This includes: + +* "Common" MCUs like STM32F, STM32H, NXP Kinetis, LPC, iMX, dsPIC33, PIC32, SWM341 etc. +* Bluetooth, GSM, Wi-Fi modules like Nordic NRF, Espressif ESP32 and Raspberry Pi Pico W +* Linux with frame buffer device such as /dev/fb0. This includes Single-board computers like the Raspberry Pi +* Anything else with a strong enough MCU and a peripheral to drive a display + + +Is my display supported? +^^^^^^^^^^^^^^^^^^^^^^^^ + +LVGL needs just one simple driver function to copy an array of pixels into a given area of the display. +If you can do this with your display then you can use it with LVGL. + +Some examples of the supported display types: + +* TFTs with 16 or 24 bit color depth +* Monitors with an HDMI port +* Small monochrome displays +* Gray-scale displays +* even LED matrices +* or any other display where you can control the color/state of the pixels + +See the :ref:`display` section to learn more. + + +LVGL doesn't start, randomly crashes or nothing is drawn on the display. What can be the problem? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* Try increasing :c:macro:`LV_MEM_SIZE`. +* Be sure your display works without LVGL. E.g. paint it to red on start up. +* Enable :ref:`logging`. +* Enable assertions in ``lv_conf.h`` (``LV_USE_ASSERT_...``). +* If you use an RTOS: + * Increase the stack size of the task that calls :cpp:func:`lv_timer_handler`. + * Be sure you are using one of the methods for thread management as described in :ref:`threading`. + + +My display driver is not called. What have I missed? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Be sure you are calling :cpp:expr:`lv_tick_inc(x)` as prescribed in +:ref:`tick_interface` and are calling :cpp:func:`lv_timer_handler` as prescribed in +:ref:`timer_handler`. + +Learn more in the :ref:`tick_interface` and :ref:`timer_handler` sections. + + +Why is the display driver called only once? Only the upper part of the display is refreshed. +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Be sure you are calling :cpp:expr:`lv_display_flush_ready(drv)` at the end of your +"*display flush callback*" as per :ref:`flush_callback` section. + + +Why do I see only garbage on the screen? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There is probably a bug in your display driver. Try the following code without using LVGL. You should see a square with red-blue gradient. + +.. code-block:: c + + #define BUF_W 20 + #define BUF_H 10 + + lv_color_t buf[BUF_W * BUF_H]; + lv_color_t * buf_p = buf; + uint16_t x, y; + for(y = 0; y < BUF_H; y++) { + lv_color_t c = lv_color_mix(LV_COLOR_BLUE, LV_COLOR_RED, (y * 255) / BUF_H); + for(x = 0; x < BUF_W; x++){ + (*buf_p) = c; + buf_p++; + } + } + + lv_area_t a; + a.x1 = 10; + a.y1 = 40; + a.x2 = a.x1 + BUF_W - 1; + a.y2 = a.y1 + BUF_H - 1; + my_flush_cb(NULL, &a, buf); + + +Why do I see nonsense colors on the screen? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The configured LVGL color format is probably not compatible with your display's color format. Check :c:macro:`LV_COLOR_DEPTH` in *lv_conf.h*. + + +How do I speed up my UI? +^^^^^^^^^^^^^^^^^^^^^^^^ + +- Turn on compiler optimization and enable instruction- and data-caching if your MCU has them. +- Increase the size of the display buffer. +- Use two display buffers and flush the buffer with DMA (or similar peripheral) in the background. +- Increase the clock speed of the SPI or parallel port if you use them to drive the display. +- If your display has an SPI port consider changing to a model with a parallel interface because it has much higher throughput. +- Keep the display buffer in internal RAM (not in external SRAM) because LVGL uses it a lot and it should have fast access time. + + +How do I reduce flash/ROM usage? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can disable unused features (such as animations, file system, GPU etc.) and widget types in *lv_conf.h*. + +If you are using GCC/CLANG you can add `-fdata-sections -ffunction-sections` compiler flags and `--gc-sections` linker flag to remove unused functions and variables from the final binary. If possible, add the `-flto` compiler flag to enable link-time-optimisation together with `-Os` for GCC or `-Oz` for CLANG. + + +How do I reduce RAM usage? +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* Lower the size of the *Display buffer*. +* Reduce :c:macro:`LV_MEM_SIZE` in *lv_conf.h*. This memory is used when you create Widgets like buttons, labels, etc. +* To work with lower :c:macro:`LV_MEM_SIZE` you can create Widgets only when required and delete them when they are not needed anymore. + + +How do I use LVGL with an operating system? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To work with an operating system where tasks can interrupt each other (preemptively), +you must ensure that no LVGL function call be called while another LVGL call is in +progress. There are several ways to do this. See the :ref:`threading` section to +learn more. + diff --git a/docs/misc/intro_data_flow.png b/docs/misc/intro_data_flow.png new file mode 100644 index 000000000..f5745dc60 Binary files /dev/null and b/docs/misc/intro_data_flow.png differ diff --git a/docs/overview/display.rst b/docs/overview/display.rst deleted file mode 100644 index e838d5a20..000000000 --- a/docs/overview/display.rst +++ /dev/null @@ -1,175 +0,0 @@ -.. _display: - -======== -Displays -======== - -:important: The basic concept of a *display* in LVGL is explained in the :ref:`porting` section. So before reading further, please read that section first. - -.. _display_multi_display_support: - -Multiple display support -************************ - -In LVGL you can have multiple displays, each with their own driver, -widgets and color depth. - -Creating more displays is easy: just use :cpp:func:`lv_display_create` and -add set the buffer and the ``flush_cb``. When you create the UI, use -:cpp:expr:`lv_display_set_default(disp)` to tell the library on which display to -create objects. - -Why would you want multi-display support? Here are some examples: - -- Have a "normal" TFT display with local UI and create "virtual" screens on VNC - on demand. (You need to add your VNC driver). -- Have a large TFT display and a small monochrome display. -- Have some smaller and simple displays in a large instrument or technology. -- Have two large TFT displays: one for a customer and one for the shop assistant. - -.. _display_one_display: - -Using only one display ----------------------- - -Using more displays can be useful but in most cases it's not required. -Therefore, the whole concept of multi-display handling is completely -hidden if you register only one display. By default, the last created -(and only) display is used. - -:cpp:func:`lv_screen_active`, :cpp:func:`lv_screen_load`, :cpp:func:`lv_layer_top`, -:cpp:func:`lv_layer_sys`, :c:macro:`LV_HOR_RES` and :c:macro:`LV_VER_RES` are always applied -on the most recently created (default) display. If you pass ``NULL`` as -``disp`` parameter to display related functions the default display will -usually be used. E.g. :cpp:expr:`lv_display_trigger_activity(NULL)` will trigger a -user activity on the default display. (See below in :ref:`Inactivity `). - -Mirror display --------------- - -To mirror the image of a display to another display, you don't need to -use multi-display support. Just transfer the buffer received in -``flush_cb`` to the other display too. - -Split image ------------ - -You can create a larger virtual display from an array of smaller ones. -You can create it as below: 1. Set the resolution of the displays to the -large display's resolution. 2. In ``flush_cb``, truncate and modify the -``area`` parameter for each display. 3. Send the buffer's content to -each real display with the truncated area. - -.. _display_screens: - -Screens -******* - -Every display has its own set of :ref:`screens ` and the -objects on each screen. - -Be sure not to confuse displays and screens: - -- **Displays** are the physical hardware drawing the pixels. -- **Screens** are the high-level root objects associated with a - particular display. One display can have multiple screens associated - with it, but not vice versa. - -Screens can be considered the highest level containers which have no -parent. A screen's size is always equal to its display and their origin -is (0;0). Therefore, a screen's coordinates can't be changed, -i.e. :cpp:func:`lv_obj_set_pos`, :cpp:func:`lv_obj_set_size` or similar functions -can't be used on screens. - -A screen can be created from any object type but the two most typical -types are :ref:`Base object ` and :ref:`Image ` -(to create a wallpaper). - -To create a screen, use -``lv_obj_t * scr = lv__create(NULL)``. ``NULL`` indicates no parent. - -To load a screen, use :cpp:expr:`lv_screen_load(scr)`. To get the active screen, -use :cpp:func:`lv_screen_active`. These functions work on the default display. If -you want to specify which display to work on, use -:cpp:expr:`lv_display_get_screen_active(disp)` and :cpp:expr:`lv_display_load_screen(disp, scr)`. A -screen can be loaded with animations too. Read more -:ref:`here `. - -Screens can be deleted with :cpp:expr:`lv_obj_delete(scr)`, but ensure that you do -not delete the currently loaded screen. - -Transparent screens -------------------- - -Usually, the opacity of the screen is :cpp:enumerator:`LV_OPA_COVER` to provide a -solid background for its children. If this is not the case (opacity < -100%) the display's ``bottom_layer`` be visible. If the bottom layer's -opacity is also not :cpp:enumerator:`LV_OPA_COVER` LVGL has no solid background to -draw. - -This configuration (transparent screen and display) could be used to -create for example OSD menus where a video is played on a lower layer, -and a menu is overlaid on an upper layer. - -To properly render the screen the display's color format needs to be set -to one with alpha channel. - -In summary, to enable transparent screens and displays for OSD menu-like -UIs: - -- Set the screen's ``bg_opa`` to transparent: - :cpp:expr:`lv_obj_set_style_bg_opa(lv_screen_active(), LV_OPA_TRANSP, LV_PART_MAIN)` -- Set the bottom layer's ``bg_opa`` to transparent: - :cpp:expr:`lv_obj_set_style_bg_opa(lv_layer_bottom(), LV_OPA_TRANSP, LV_PART_MAIN)` -- Set the screen's ``bg_opa`` to 0: - :cpp:expr:`lv_obj_set_style_bg_opa(lv_screen_active(), LV_OPA_0, LV_PART_MAIN)` -- Set a color format with alpha channel. E.g. - :cpp:expr:`lv_display_set_color_format(disp, LV_COLOR_FORMAT_ARGB8888)` - -.. _display_features: - -Features of displays -******************** - -.. _display_inactivity: - -Inactivity ----------- - -A user's inactivity time is measured on each display. Every use of an -:ref:`Input device ` (if :ref:`associated with the display `) counts as an activity. To -get time elapsed since the last activity, use -:cpp:expr:`lv_display_get_inactive_time(disp)`. If ``NULL`` is passed, the lowest -inactivity time among all displays will be returned (**NULL isn't just -the default display**). - -You can manually trigger an activity using -:cpp:expr:`lv_display_trigger_activity(disp)`. If ``disp`` is ``NULL``, the default -screen will be used (**and not all displays**). - -Background ----------- - -Every display has a background color, background image and background -opacity properties. They become visible when the current screen is -transparent or not positioned to cover the whole display. - -The background color is a simple color to fill the display. It can be -adjusted with :cpp:expr:`lv_obj_set_style_bg_color(obj, color)`; - -The display background image is a path to a file or a pointer to an -:cpp:struct:`lv_image_dsc_t` variable (converted image data) to be used as -wallpaper. It can be set with :cpp:expr:`lv_obj_set_style_bg_image_src(obj, &my_img)`; -If a background image is configured the background won't be filled with -``bg_color``. - -The opacity of the background color or image can be adjusted with -:cpp:expr:`lv_obj_set_style_bg_opa(obj, opa)`. - -The ``disp`` parameter of these functions can be ``NULL`` to select the -default display. - -.. _display_api: - -API -*** diff --git a/docs/overview/indev.rst b/docs/overview/indev.rst deleted file mode 100644 index a4334baa2..000000000 --- a/docs/overview/indev.rst +++ /dev/null @@ -1,206 +0,0 @@ -.. _indev: - -============= -Input devices -============= - -An input device usually means: - -- Pointer-like input device like touchpad or mouse -- Keypads like a normal keyboard or simple numeric keypad -- Encoders with left/right turn and push options -- External hardware buttons which are assigned to specific points on the screen - -:important: Before reading further, please read the `Porting `__ section of Input devices - -Pointers -******** - -.. _indev_cursor: - -Cursor ------- - -Pointer input devices (like a mouse) can have a cursor. - -.. code-block:: c - - ... - lv_indev_t * mouse_indev = lv_indev_create(); - ... - LV_IMAGE_DECLARE(mouse_cursor_icon); /*Declare the image source.*/ - lv_obj_t * cursor_obj = lv_image_create(lv_screen_active()); /*Create an image object for the cursor */ - lv_image_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/ - lv_indev_set_cursor(mouse_indev, cursor_obj); /*Connect the image object to the driver*/ - -Note that the cursor object should have -:cpp:expr:`lv_obj_remove_flag(cursor_obj, LV_OBJ_FLAG_CLICKABLE)`. For images, -*clicking* is disabled by default. - -.. _indev_gestures: - -Gestures --------- - -Pointer input devices can detect basic gestures. By default, most of the -widgets send the gestures to its parent, so finally the gestures can be -detected on the screen object in a form of an :cpp:enumerator:`LV_EVENT_GESTURE` -event. For example: - -.. code-block:: c - - void my_event(lv_event_t * e) - { - lv_obj_t * screen = lv_event_get_current_target(e); - lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_active()); - switch(dir) { - case LV_DIR_LEFT: - ... - break; - case LV_DIR_RIGHT: - ... - break; - case LV_DIR_TOP: - ... - break; - case LV_DIR_BOTTOM: - ... - break; - } - } - - ... - - lv_obj_add_event_cb(screen1, my_event, LV_EVENT_GESTURE, NULL); - -To prevent passing the gesture event to the parent from an object use -:cpp:expr:`lv_obj_remove_flag(obj, LV_OBJ_FLAG_GESTURE_BUBBLE)`. - -Note that, gestures are not triggered if an object is being scrolled. - -If you did some action on a gesture you can call -:cpp:expr:`lv_indev_wait_release(lv_indev_active())` in the event handler to -prevent LVGL sending further input device related events. - -.. _indev_keypad_and_encoder: - -Keypad and encoder -****************** - -You can fully control the user interface without a touchpad or mouse by -using a keypad or encoder(s). It works similar to the *TAB* key on the -PC to select an element in an application or a web page. - -.. _indev_groups: - -Groups ------- - -Objects you want to control with a keypad or encoder need to be added to -a *Group*. In every group there is exactly one focused object which -receives the pressed keys or the encoder actions. For example, if a -:ref:`Text area ` is focused and you press some letter -on a keyboard, the keys will be sent and inserted into the text area. -Similarly, if a :ref:`Slider ` is focused and you press -the left or right arrows, the slider's value will be changed. - -You need to associate an input device with a group. An input device can -send key events to only one group but a group can receive data from more -than one input device. - -To create a group use :cpp:expr:`lv_group_t * g = lv_group_create()` and to add -an object to the group use :cpp:expr:`lv_group_add_obj(g, obj)`. - -To associate a group with an input device use -:cpp:expr:`lv_indev_set_group(indev, g)`. - -.. _indev_keys: - -Keys -^^^^ - -There are some predefined keys which have special meaning: - -- :cpp:enumerator:`LV_KEY_NEXT`: Focus on the next object -- :cpp:enumerator:`LV_KEY_PREV`: Focus on the previous object -- :cpp:enumerator:`LV_KEY_ENTER`: Triggers :cpp:enumerator:`LV_EVENT_PRESSED`, :cpp:enumerator:`LV_EVENT_CLICKED`, or :cpp:enumerator:`LV_EVENT_LONG_PRESSED` etc. events -- :cpp:enumerator:`LV_KEY_UP`: Increase value or move upwards -- :cpp:enumerator:`LV_KEY_DOWN`: Decrease value or move downwards -- :cpp:enumerator:`LV_KEY_RIGHT`: Increase value or move to the right -- :cpp:enumerator:`LV_KEY_LEFT`: Decrease value or move to the left -- :cpp:enumerator:`LV_KEY_ESC`: Close or exit (E.g. close a :ref:`Drop down list `) -- :cpp:enumerator:`LV_KEY_DEL`: Delete (E.g. a character on the right in a :ref:`Text area `) -- :cpp:enumerator:`LV_KEY_BACKSPACE`: Delete a character on the left (E.g. in a :ref:`Text area `) -- :cpp:enumerator:`LV_KEY_HOME`: Go to the beginning/top (E.g. in a :ref:`Text area `) -- :cpp:enumerator:`LV_KEY_END`: Go to the end (E.g. in a :ref:`Text area `) - -The most important special keys in your :cpp:func:`read_cb` function are: - -- :cpp:enumerator:`LV_KEY_NEXT` -- :cpp:enumerator:`LV_KEY_PREV` -- :cpp:enumerator:`LV_KEY_ENTER` -- :cpp:enumerator:`LV_KEY_UP` -- :cpp:enumerator:`LV_KEY_DOWN` -- :cpp:enumerator:`LV_KEY_LEFT` -- :cpp:enumerator:`LV_KEY_RIGHT` - -You should translate some of your keys to these special keys to support navigation -in a group and interact with selected objects. - -Usually, it's enough to use only :cpp:enumerator:`LV_KEY_LEFT` and :cpp:enumerator:`LV_KEY_RIGHT` because most -objects can be fully controlled with them. - -With an encoder you should use only :cpp:enumerator:`LV_KEY_LEFT`, :cpp:enumerator:`LV_KEY_RIGHT`, -and :cpp:enumerator:`LV_KEY_ENTER`. - -Edit and navigate mode -^^^^^^^^^^^^^^^^^^^^^^ - -Since a keypad has plenty of keys, it's easy to navigate between objects -and edit them using the keypad. But encoders have a limited number of -"keys" and hence it is difficult to navigate using the default options. -*Navigate* and *Edit* modes are used to avoid this problem with -encoders. - -In *Navigate* mode, an encoder's :cpp:enumerator:`LV_KEY_LEFT` or :cpp:enumerator:`LV_KEY_RIGHT` is translated to -:cpp:enumerator:`LV_KEY_NEXT` or :cpp:enumerator:`LV_KEY_PREV`. Therefore, the next or previous object will be -selected by turning the encoder. Pressing :cpp:enumerator:`LV_KEY_ENTER` will change -to *Edit* mode. - -In *Edit* mode, :cpp:enumerator:`LV_KEY_NEXT` and :cpp:enumerator:`LV_KEY_PREV` is usually used to modify an -object. Depending on the object's type, a short or long press of -:cpp:enumerator:`LV_KEY_ENTER` changes back to *Navigate* mode. Usually, an object -which cannot be pressed (like a :ref:`Slider `) leaves -*Edit* mode upon a short click. But with objects where a short click has -meaning (e.g. :ref:`Button `), a long press is required. - -Default group -^^^^^^^^^^^^^ - -Interactive widgets - such as buttons, checkboxes, sliders, etc. - can -be automatically added to a default group. Just create a group with -:cpp:expr:`lv_group_t * g = lv_group_create()` and set the default group with -:cpp:expr:`lv_group_set_default(g)` - -Don't forget to assign one or more input devices to the default group -with :cpp:expr:`lv_indev_set_group(my_indev, g)`. - -Styling -------- - -If an object is focused either by clicking it via touchpad or focused -via an encoder or keypad it goes to the :cpp:enumerator:`LV_STATE_FOCUSED` state. -Hence, focused styles will be applied to it. - -If an object switches to edit mode it enters the -:cpp:expr:`LV_STATE_FOCUSED | LV_STATE_EDITED` states so these style properties -will be shown. - -For a more detailed description read the -`Style `__ section. - - -.. _indev_api: - -API -*** diff --git a/docs/overview/index.rst b/docs/overview/index.rst deleted file mode 100644 index c9fd09371..000000000 --- a/docs/overview/index.rst +++ /dev/null @@ -1,28 +0,0 @@ -.. _overview: - -======== -Overview -======== - - -.. toctree:: - :maxdepth: 2 - - animations - color - coord - debugging/index - display - event - font - fs - image - indev - layer - new_widget - obj - renderers/index - scroll - style - style-props - timer diff --git a/docs/overview/layer.rst b/docs/overview/layer.rst deleted file mode 100644 index f17791cb3..000000000 --- a/docs/overview/layer.rst +++ /dev/null @@ -1,155 +0,0 @@ -.. _layers: - -====== -Layers -====== - -In LVGL "layers" can be interpreted in various ways: - -1. The order of widget creation naturally creates a layering of widgets -2. Permanent screen-sized layers can be also used -3. For some draw operations LVGL renders a widget and all its children into a buffer (a.k.a. layer) first - -.. _layers_creation: - -Order of creation -***************** - -By default, LVGL draws new objects on top of old objects. - -For example, assume we add a button to a parent object named button1 and -then another button named button2. Then button1 (along with its child -object(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: - -Change order ------------- - -There are four explicit ways to bring an object to the foreground: - -- Use :cpp:expr:`lv_obj_move_foreground(obj)` to bring an object to the foreground. - Similarly, use :cpp:expr:`lv_obj_move_background(obj)` to move it to the background. -- Use :cpp:expr:`lv_obj_move_to_index(obj, idx)` to move an object 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(obj, lv_obj_get_index(obj) - 1)` - -- Use :cpp:expr:`lv_obj_swap(obj1, obj2)` to swap the relative layer position of two objects. -- When :cpp:expr:`lv_obj_set_parent(obj, new_parent)` is used, ``obj`` will be on the foreground of the ``new_parent``. - - -Screen-like layers -****************** - -.. _layers_top_and_sys: - -Top and sys layers ------------------- - -LVGL uses two special layers named ``layer_top`` and ``layer_sys``. Both -are visible and common on all screens of a display. **They are not, -however, shared among multiple physical displays.** The ``layer_top`` is -always on top of the default screen (:cpp:func:`lv_screen_active`), and -``layer_sys`` is on top of ``layer_top``. - -The get these layers use :cpp:func:`lv_layer_top` and :cpp:func:`lv_layer_sys`. - -These layers work like any other widget, meaning the can be styles, scrolled, -and any kind of widgets can be created on them. - -The ``layer_top`` can be used by the user to create some content visible -everywhere. For example, a menu bar, a pop-up, etc. If the ``click`` -attribute is enabled, then ``layer_top`` will absorb all user clicks and -acts as a modal. - -.. code-block:: c - - lv_obj_add_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE); - -The ``layer_sys`` is also used for similar purposes in LVGL. For -example, it places the mouse cursor above all layers to be sure it's -always visible. - -.. _layers_bottom: - -Bottom layers -------------- - -Similarly top and sys. layer bottom layer is also screen size but -it's located below the active screen. It's visible only if the active screen's -background opacity is < 255. - -The get the bottom layer use :cpp:func:`lv_layer_bottom`. - -Draw layers -*********** - -Some style properties make 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 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 layer when 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 makes LVGL to create a 2 layers with radius height for the top and bottom part of the widget. - -.. _layers_api: - -API -*** diff --git a/docs/overview/obj.rst b/docs/overview/obj.rst deleted file mode 100644 index 29bfedd0e..000000000 --- a/docs/overview/obj.rst +++ /dev/null @@ -1,348 +0,0 @@ -.. _objects: - -======= -Objects -======= - -In LVGL the **basic building blocks** of a user interface are the -objects, also called *Widgets*. For example a -:ref:`Button `, :ref:`Label `, -:ref:`Image `, :ref:`List `, -:ref:`Chart ` or :ref:`Text area `. - -You can see all the :ref:`Object types ` here. - -All objects are referenced using an :cpp:type:`lv_obj_t` pointer as a handle. -This pointer can later be used to set or get the attributes of the -object. - -.. _objects_attributes: - -Attributes -********** - -Basic attributes ----------------- - -All object types share some basic attributes: - -- Position -- Size -- Parent -- Styles -- Event handlers -- Etc - -You can set/get these attributes with ``lv_obj_set_...`` and -``lv_obj_get_...`` functions. For example: - -.. code-block:: c - - /*Set basic object attributes*/ - lv_obj_set_size(btn1, 100, 50); /*Set a button's size*/ - lv_obj_set_pos(btn1, 20,30); /*Set a button's position*/ - -To see all the available functions visit the :ref:`Base object's documentation `. - -Specific attributes -------------------- - -The object types have special attributes too. For example, a slider has - -- Minimum and maximum values -- Current value - -For these special attributes, every object type may have unique API -functions. For example for a slider: - -.. code-block:: c - - /*Set slider specific attributes*/ - lv_slider_set_range(slider1, 0, 100); /*Set the min. and max. values*/ - lv_slider_set_value(slider1, 40, LV_ANIM_ON); /*Set the current value (position)*/ - -The API of the widgets is described in their -:ref:`Documentation ` but you can also check the respective -header files (e.g. *widgets/lv_slider.h*) - -.. _objects_working_mechanisms: - -Working mechanisms -****************** - -Parent-child structure ----------------------- - -A parent object can be considered as the container of its children. -Every object has exactly one parent object (except screens), but a -parent can have any number of children. There is no limitation for the -type of the parent but there are objects which are typically a parent -(e.g. button) or a child (e.g. label). - -Moving together ---------------- - -If the position of a parent changes, the children will move along with -it. Therefore, all positions are relative to the parent. - -.. image:: /misc/par_child1.png - -.. code-block:: c - - lv_obj_t * parent = lv_obj_create(lv_screen_active()); /*Create a parent object on the current screen*/ - lv_obj_set_size(parent, 100, 80); /*Set the size of the parent*/ - - lv_obj_t * obj1 = lv_obj_create(parent); /*Create an object on the previously created parent object*/ - lv_obj_set_pos(obj1, 10, 10); /*Set the position of the new object*/ - -Modify the position of the parent: - -.. image:: /misc/par_child2.png - -.. code-block:: c - - lv_obj_set_pos(parent, 50, 50); /*Move the parent. The child will move with it.*/ - -(For simplicity the adjusting of colors of the objects is not shown in -the example.) - -Visibility only on the parent ------------------------------ - -If a child is partially or fully outside its parent then the parts -outside will not be visible. - -.. image:: /misc/par_child3.png - -.. code-block:: c - - lv_obj_set_x(obj1, -30); /*Move the child a little bit off the parent*/ - -This behavior can be overwritten with -:cpp:expr:`lv_obj_add_flag(obj, LV_OBJ_FLAG_OVERFLOW_VISIBLE)` which allow the -children to be drawn out of the parent. - -Create and delete objects -------------------------- - -In LVGL, objects can be created and deleted dynamically at run time. It -means only the currently created (existing) objects consume RAM. - -This allows for the creation of a screen just when a button is clicked -to open it, and for deletion of screens when a new screen is loaded. - -UIs can be created based on the current environment of the device. For -example one can create meters, charts, bars and sliders based on the -currently attached sensors. - -Every widget has its own **create** function with a prototype like this: - -.. code-block:: c - - lv_obj_t * lv__create(lv_obj_t * parent, ); - -Typically, the create functions only have a *parent* parameter telling -them on which object to create the new widget. - -The return value is a pointer to the created object with :cpp:type:`lv_obj_t` ``*`` -type. - -There is a common **delete** function for all object types. It deletes -the object and all of its children. - -.. code-block:: c - - void lv_obj_delete(lv_obj_t * obj); - -:cpp:func:`lv_obj_delete` will delete the object immediately. If for any reason you -can't delete the object immediately you can use -:cpp:expr:`lv_obj_delete_async(obj)` which will perform the deletion on the next -call of :cpp:func:`lv_timer_handler`. This is useful e.g. if you want to -delete the parent of an object in the child's :cpp:enumerator:`LV_EVENT_DELETE` -handler. - -You can remove all the children of an object (but not the object itself) -using :cpp:expr:`lv_obj_clean(obj)`. - -You can use :cpp:expr:`lv_obj_delete_delayed(obj, 1000)` to delete an object after -some time. The delay is expressed in milliseconds. - -Sometimes you're not sure whether an object was deleted and you need some way to -check if it's still "alive". Anytime before the object is deleted, you can use -cpp:expr:`lv_obj_null_on_delete(&obj)` to cause your object pointer to be set to ``NULL`` -when the object is deleted. - -Make sure the pointer variable itself stays valid until the object is deleted. Here -is an example: - -.. code:: c - - void some_timer_callback(lv_timer_t * t) - { - static lv_obj_t * my_label; - if(my_label == NULL) { - my_label = lv_label_create(lv_screen_active()); - lv_obj_delete_delayed(my_label, 1000); - lv_obj_null_on_delete(&my_label); - } - else { - lv_obj_set_x(my_label, lv_obj_get_x(my_label) + 1); - } - } - -.. _objects_screens: - -Screens -******* - -Create screens --------------- - -The screens are special objects which have no parent object. So they can -be created like: - -.. code-block:: c - - lv_obj_t * scr1 = lv_obj_create(NULL); - -Screens can be created with any object type. For example, a -:ref:`Base object ` or an image to make a wallpaper. - -Get the active screen ---------------------- - -There is always an active screen on each display. By default, the -library creates and loads a "Base object" as a screen for each display. - -To get the currently active screen use the :cpp:func:`lv_screen_active` function. - -.. _objects_load_screens: - -Load screens ------------- - -To load a new screen, use :cpp:expr:`lv_screen_load(scr1)`. - -Layers ------- - -There are two automatically generated layers: - -- top layer -- system layer - -They are independent of the screens and they will be shown on every -screen. The *top layer* is above every object on the screen and the -*system layer* is above the *top layer*. You can add any pop-up windows -to the *top layer* freely. But, the *system layer* is restricted to -system-level things (e.g. mouse cursor will be placed there with -:cpp:func:`lv_indev_set_cursor`). - -The :cpp:func:`lv_layer_top` and :cpp:func:`lv_layer_sys` functions return pointers -to the top and system layers respectively. - -Read the :ref:`Layer overview ` section to learn more -about layers. - -Load screen with animation -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -A new screen can be loaded with animation by using -:cpp:expr:`lv_screen_load_anim(scr, transition_type, time, delay, auto_del)`. The -following transition types exist: - -- :cpp:enumerator:`LV_SCR_LOAD_ANIM_NONE`: Switch immediately after ``delay`` milliseconds -- :cpp:enumerator:`LV_SCR_LOAD_ANIM_OVER_LEFT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_OVER_RIGHT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_OVER_TOP` and :cpp:enumerator:`LV_SCR_LOAD_ANIM_OVER_BOTTOM`: Move the new screen over the current towards the given direction -- :cpp:enumerator:`LV_SCR_LOAD_ANIM_OUT_LEFT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_OUT_RIGHT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_OUT_TOP` and :cpp:enumerator:`LV_SCR_LOAD_ANIM_OUT_BOTTOM`: Move out the old screen over the current towards the given direction -- :cpp:enumerator:`LV_SCR_LOAD_ANIM_MOVE_LEFT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_MOVE_RIGHT`, :cpp:enumerator:`LV_SCR_LOAD_ANIM_MOVE_TOP` and :cpp:enumerator:`LV_SCR_LOAD_ANIM_MOVE_BOTTOM`: Move both the current and new screens towards the given direction -- :cpp:enumerator:`LV_SCR_LOAD_ANIM_FADE_IN` and :cpp:enumerator:`LV_SCR_LOAD_ANIM_FADE_OUT`: Fade the new screen over the old screen, or vice versa - -Setting ``auto_del`` to ``true`` will automatically delete the old -screen when the animation is finished. - -The new screen will become active (returned by :cpp:func:`lv_screen_active`) when -the animation starts after ``delay`` time. All inputs are disabled -during the screen animation. - -Handling multiple displays --------------------------- - -Screens are created on the currently selected *default display*. The -*default display* is the last registered display with -:cpp:func:`lv_display_create`. You can also explicitly select a new default -display using :cpp:expr:`lv_display_set_default(disp)`. - -:cpp:func:`lv_screen_active`, :cpp:func:`lv_screen_load` and :cpp:func:`lv_screen_load_anim` operate -on the default display. - -Visit :ref:`display_multi_display_support` to learn more. - -.. _objects_parts: - -Parts -***** - -The widgets are built from multiple parts. For example a -:ref:`Base object ` uses the main and scrollbar parts but a -:ref:`Slider ` uses the main, indicator and knob parts. -Parts are similar to *pseudo-elements* in CSS. - -The following predefined parts exist in LVGL: - -- :cpp:enumerator:`LV_PART_MAIN`: A background like rectangle -- :cpp:enumerator:`LV_PART_SCROLLBAR`: The scrollbar(s) -- :cpp:enumerator:`LV_PART_INDICATOR`: Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox -- :cpp:enumerator:`LV_PART_KNOB`: Like a handle to grab to adjust the value -- :cpp:enumerator:`LV_PART_SELECTED`: Indicate the currently selected option or section -- :cpp:enumerator:`LV_PART_ITEMS`: Used if the widget has multiple similar elements (e.g. table cells) -- :cpp:enumerator:`LV_PART_CURSOR`: Mark a specific place e.g. text area's or chart's cursor -- :cpp:enumerator:`LV_PART_CUSTOM_FIRST`: Custom parts can be added from here. - -The main purpose of parts is to allow styling the "components" of the -widgets. They are described in more detail in the -:ref:`Style overview ` section. - -.. _objects_states: - -States -****** - -The object can be in a combination of the following states: - -- :cpp:enumerator:`LV_STATE_DEFAULT`: Normal, released state -- :cpp:enumerator:`LV_STATE_CHECKED`: Toggled or checked state -- :cpp:enumerator:`LV_STATE_FOCUSED`: Focused via keypad or encoder or clicked via touchpad/mouse -- :cpp:enumerator:`LV_STATE_FOCUS_KEY`: Focused via keypad or encoder but not via touchpad/mouse -- :cpp:enumerator:`LV_STATE_EDITED`: Edit by an encoder -- :cpp:enumerator:`LV_STATE_HOVERED`: Hovered by mouse (not supported now) -- :cpp:enumerator:`LV_STATE_PRESSED`: Being pressed -- :cpp:enumerator:`LV_STATE_SCROLLED`: Being scrolled -- :cpp:enumerator:`LV_STATE_DISABLED`: Disabled state -- :cpp:enumerator:`LV_STATE_USER_1`: Custom state -- :cpp:enumerator:`LV_STATE_USER_2`: Custom state -- :cpp:enumerator:`LV_STATE_USER_3`: Custom state -- :cpp:enumerator:`LV_STATE_USER_4`: Custom state - -The states are usually automatically changed by the library as the user -interacts with an object (presses, releases, focuses, etc.). However, -the states can be changed manually too. To set or clear given state (but -leave the other states untouched) use -``lv_obj_add/remove_state(obj, LV_STATE_...)`` In both cases OR-ed state -values can be used as well. E.g. -:cpp:expr:`lv_obj_add_state(obj, part, LV_STATE_PRESSED | LV_PRESSED_CHECKED)`. - -To learn more about the states read the related section of the -:ref:`Style overview `. - -.. _objects_snapshot: - -Snapshot -******** - -A snapshot image can be generated for an object together with its -children. Check details in :ref:`snapshot`. - -.. _objects_api: - -API -*** diff --git a/docs/overview/renderers/stm32_dma2d.rst b/docs/overview/renderers/stm32_dma2d.rst deleted file mode 100644 index 82c689e05..000000000 --- a/docs/overview/renderers/stm32_dma2d.rst +++ /dev/null @@ -1,9 +0,0 @@ -========= -DMA2D GPU -========= - -API ---- - -:ref:`lv_draw_dma2d_h` - diff --git a/docs/overview/renderers/vglite.rst b/docs/overview/renderers/vglite.rst deleted file mode 100644 index 8b67ca211..000000000 --- a/docs/overview/renderers/vglite.rst +++ /dev/null @@ -1,17 +0,0 @@ -============== -NXP VGLite GPU -============== - -API ---- - -:ref:`lv_draw_vglite_h` - -:ref:`lv_vglite_buf_h` - -:ref:`lv_vglite_matrix_h` - -:ref:`lv_vglite_path_h` - -:ref:`lv_vglite_utils_h` - diff --git a/docs/overview/style-props.md b/docs/overview/style-props.md deleted file mode 100644 index 832f9e86e..000000000 --- a/docs/overview/style-props.md +++ /dev/null @@ -1,1033 +0,0 @@ -# Style properties - -## Size and position -Properties related to size, position, alignment and layout of the objects. - -### width -Sets the width of object. Pixel, percentage and `LV_SIZE_CONTENT` values can be used. Percentage values are relative to the width of the parent's content area. -
    -
  • Default Widget dependent
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### min_width -Sets a minimal width. Pixel and percentage values can be used. Percentage values are relative to the width of the parent's content area. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### max_width -Sets a maximal width. Pixel and percentage values can be used. Percentage values are relative to the width of the parent's content area. -
    -
  • Default LV_COORD_MAX
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### height -Sets the height of object. Pixel, percentage and `LV_SIZE_CONTENT` can be used. Percentage values are relative to the height of the parent's content area. -
    -
  • Default Widget dependent
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### min_height -Sets a minimal height. Pixel and percentage values can be used. Percentage values are relative to the width of the parent's content area. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### max_height -Sets a maximal height. Pixel and percentage values can be used. Percentage values are relative to the height of the parent's content area. -
    -
  • Default LV_COORD_MAX
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### length -Its meaning depends on the type of the widget. For example in case of lv_scale it means the length of the ticks. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw Yes
  • -
- -### x -Set the X coordinate of the object considering the set `align`. Pixel and percentage values can be used. Percentage values are relative to the width of the parent's content area. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### y -Set the Y coordinate of the object considering the set `align`. Pixel and percentage values can be used. Percentage values are relative to the height of the parent's content area. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### align -Set the alignment which tells from which point of the parent the X and Y coordinates should be interpreted. The possible values are: `LV_ALIGN_DEFAULT`, `LV_ALIGN_TOP_LEFT/MID/RIGHT`, `LV_ALIGN_BOTTOM_LEFT/MID/RIGHT`, `LV_ALIGN_LEFT/RIGHT_MID`, `LV_ALIGN_CENTER`. `LV_ALIGN_DEFAULT` means `LV_ALIGN_TOP_LEFT` with LTR base direction and `LV_ALIGN_TOP_RIGHT` with RTL base direction. -
    -
  • Default `LV_ALIGN_DEFAULT`
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### transform_width -Make the object wider on both sides with this value. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to the object's width. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw Yes
  • -
- -### transform_height -Make the object higher on both sides with this value. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to the object's height. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw Yes
  • -
- -### translate_x -Move the object with this value in X direction. Applied after layouts, aligns and other positioning. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to the object's width. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### translate_y -Move the object with this value in Y direction. Applied after layouts, aligns and other positioning. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to the object's height. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### transform_scale_x -Zoom an objects horizontally. The value 256 (or `LV_SCALE_NONE`) means normal size, 128 half size, 512 double size, and so on -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw Yes
  • -
- -### transform_scale_y -Zoom an objects vertically. The value 256 (or `LV_SCALE_NONE`) means normal size, 128 half size, 512 double size, and so on -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw Yes
  • -
- -### transform_rotation -Rotate an objects. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw Yes
  • -
- -### transform_pivot_x -Set the pivot point's X coordinate for transformations. Relative to the object's top left corner' -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### transform_pivot_y -Set the pivot point's Y coordinate for transformations. Relative to the object's top left corner' -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### transform_skew_x -Skew an object horizontally. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw Yes
  • -
- -### transform_skew_y -Skew an object vertically. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw Yes
  • -
- -## Padding -Properties to describe spacing between the parent's sides and the children and among the children. Very similar to the padding properties in HTML. - -### pad_top -Sets the padding on the top. It makes the content area smaller in this direction. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### pad_bottom -Sets the padding on the bottom. It makes the content area smaller in this direction. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### pad_left -Sets the padding on the left. It makes the content area smaller in this direction. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### pad_right -Sets the padding on the right. It makes the content area smaller in this direction. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### pad_row -Sets the padding between the rows. Used by the layouts. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### pad_column -Sets the padding between the columns. Used by the layouts. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -## Margin -Properties to describe spacing around an object. Very similar to the margin properties in HTML. - -### margin_top -Sets the margin on the top. The object will keep this space from its siblings in layouts. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### margin_bottom -Sets the margin on the bottom. The object will keep this space from its siblings in layouts. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### margin_left -Sets the margin on the left. The object will keep this space from its siblings in layouts. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### margin_right -Sets the margin on the right. The object will keep this space from its siblings in layouts. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -## Background -Properties to describe the background color and image of the objects. - -### bg_color -Set the background color of the object. -
    -
  • Default `0xffffff`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### bg_opa -Set the opacity of the background. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. -
    -
  • Default `LV_OPA_TRANSP`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### bg_grad_color -Set the gradient color of the background. Used only if `grad_dir` is not `LV_GRAD_DIR_NONE` -
    -
  • Default `0x000000`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### bg_grad_dir -Set the direction of the gradient of the background. The possible values are `LV_GRAD_DIR_NONE/HOR/VER`. -
    -
  • Default `LV_GRAD_DIR_NONE`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### bg_main_stop -Set the point from which the background color should start for gradients. 0 means to top/left side, 255 the bottom/right side, 128 the center, and so on -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### bg_grad_stop -Set the point from which the background's gradient color should start. 0 means to top/left side, 255 the bottom/right side, 128 the center, and so on -
    -
  • Default 255
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### bg_main_opa -Set the opacity of the first gradient color -
    -
  • Default 255
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### bg_grad_opa -Set the opacity of the second gradient color -
    -
  • Default 255
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### bg_grad -Set the gradient definition. The pointed instance must exist while the object is alive. NULL to disable. It wraps `BG_GRAD_COLOR`, `BG_GRAD_DIR`, `BG_MAIN_STOP` and `BG_GRAD_STOP` into one descriptor and allows creating gradients with more colors too. If it's set other gradient related properties will be ignored' -
    -
  • Default `NULL`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### bg_image_src -Set a background image. Can be a pointer to `lv_image_dsc_t`, a path to a file or an `LV_SYMBOL_...` -
    -
  • Default `NULL`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw Yes
  • -
- -### bg_image_opa -Set the opacity of the background image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. -
    -
  • Default `LV_OPA_COVER`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### bg_image_recolor -Set a color to mix to the background image. -
    -
  • Default `0x000000`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### bg_image_recolor_opa -Set the intensity of background image recoloring. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means no mixing, 255, `LV_OPA_100` or `LV_OPA_COVER` means full recoloring, other values or LV_OPA_10, LV_OPA_20, etc are interpreted proportionally. -
    -
  • Default `LV_OPA_TRANSP`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### bg_image_tiled -If enabled the background image will be tiled. The possible values are `true` or `false`. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -## Border -Properties to describe the borders - -### border_color -Set the color of the border -
    -
  • Default `0x000000`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### border_opa -Set the opacity of the border. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. -
    -
  • Default `LV_OPA_COVER`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### border_width -Set the width of the border. Only pixel values can be used. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### border_side -Set only which side(s) the border should be drawn. The possible values are `LV_BORDER_SIDE_NONE/TOP/BOTTOM/LEFT/RIGHT/INTERNAL`. OR-ed values can be used as well, e.g. `LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_LEFT`. -
    -
  • Default `LV_BORDER_SIDE_NONE`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### border_post -Sets whether the border should be drawn before or after the children are drawn. `true`: after children, `false`: before children -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -## Outline -Properties to describe the outline. It's like a border but drawn outside of the rectangles. - -### outline_width -Set the width of the outline in pixels. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw Yes
  • -
- -### outline_color -Set the color of the outline. -
    -
  • Default `0x000000`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### outline_opa -Set the opacity of the outline. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. -
    -
  • Default `LV_OPA_COVER`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw Yes
  • -
- -### outline_pad -Set the padding of the outline, i.e. the gap between object and the outline. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw Yes
  • -
- -## Shadow -Properties to describe the shadow drawn under the rectangles. - -### shadow_width -Set the width of the shadow in pixels. The value should be >= 0. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw Yes
  • -
- -### shadow_offset_x -Set an offset on the shadow in pixels in X direction. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw Yes
  • -
- -### shadow_offset_y -Set an offset on the shadow in pixels in Y direction. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw Yes
  • -
- -### shadow_spread -Make the shadow calculation to use a larger or smaller rectangle as base. The value can be in pixel to make the area larger/smaller -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw Yes
  • -
- -### shadow_color -Set the color of the shadow -
    -
  • Default `0x000000`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### shadow_opa -Set the opacity of the shadow. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. -
    -
  • Default `LV_OPA_COVER`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw Yes
  • -
- -## Image -Properties to describe the images - -### image_opa -Set the opacity of an image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. -
    -
  • Default `LV_OPA_COVER`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### image_recolor -Set color to mixt to the image. -
    -
  • Default `0x000000`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### image_recolor_opa -Set the intensity of the color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -## Line -Properties to describe line-like objects - -### line_width -Set the width of the lines in pixel. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw Yes
  • -
- -### line_dash_width -Set the width of dashes in pixel. Note that dash works only on horizontal and vertical lines -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### line_dash_gap -Set the gap between dashes in pixel. Note that dash works only on horizontal and vertical lines -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### line_rounded -Make the end points of the lines rounded. `true`: rounded, `false`: perpendicular line ending -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### line_color -Set the color of the lines. -
    -
  • Default `0x000000`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### line_opa -Set the opacity of the lines. -
    -
  • Default `LV_OPA_COVER`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -## Arc -TODO - -### arc_width -Set the width (thickness) of the arcs in pixel. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw Yes
  • -
- -### arc_rounded -Make the end points of the arcs rounded. `true`: rounded, `false`: perpendicular line ending -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### arc_color -Set the color of the arc. -
    -
  • Default `0x000000`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### arc_opa -Set the opacity of the arcs. -
    -
  • Default `LV_OPA_COVER`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### arc_image_src -Set an image from which the arc will be masked out. It's useful to display complex effects on the arcs. Can be a pointer to `lv_image_dsc_t` or a path to a file -
    -
  • Default `NULL`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -## Text -Properties to describe the properties of text. All these properties are inherited. - -### text_color -Sets the color of the text. -
    -
  • Default `0x000000`
  • -
  • Inherited Yes
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### text_opa -Set the opacity of the text. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. -
    -
  • Default `LV_OPA_COVER`
  • -
  • Inherited Yes
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### text_font -Set the font of the text (a pointer `lv_font_t *`). -
    -
  • Default `LV_FONT_DEFAULT`
  • -
  • Inherited Yes
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### text_letter_space -Set the letter space in pixels -
    -
  • Default 0
  • -
  • Inherited Yes
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### text_line_space -Set the line space in pixels. -
    -
  • Default 0
  • -
  • Inherited Yes
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### text_decor -Set decoration for the text. The possible values are `LV_TEXT_DECOR_NONE/UNDERLINE/STRIKETHROUGH`. OR-ed values can be used as well. -
    -
  • Default `LV_TEXT_DECOR_NONE`
  • -
  • Inherited Yes
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### text_align -Set how to align the lines of the text. Note that it doesn't align the object itself, only the lines inside the object. The possible values are `LV_TEXT_ALIGN_LEFT/CENTER/RIGHT/AUTO`. `LV_TEXT_ALIGN_AUTO` detect the text base direction and uses left or right alignment accordingly -
    -
  • Default `LV_TEXT_ALIGN_AUTO`
  • -
  • Inherited Yes
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -## Miscellaneous -Mixed properties for various purposes. - -### radius -Set the radius on every corner. The value is interpreted in pixel (>= 0) or `LV_RADIUS_CIRCLE` for max. radius -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### clip_corner -Enable to clip the overflowed content on the rounded corner. Can be `true` or `false`. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### opa -Scale down all opacity values of the object by this factor. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. -
    -
  • Default `LV_OPA_COVER`
  • -
  • Inherited Yes
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### opa_layered -First draw the object on the layer, then scale down layer opacity factor. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency. -
    -
  • Default `LV_OPA_COVER`
  • -
  • Inherited Yes
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### color_filter_dsc -Mix a color to all colors of the object. -
    -
  • Default `NULL`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### color_filter_opa -The intensity of mixing of color filter. -
    -
  • Default `LV_OPA_TRANSP`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### anim -The animation template for the object's animation. Should be a pointer to `lv_anim_t`. The animation parameters are widget specific, e.g. animation time could be the E.g. blink time of the cursor on the text area or scroll time of a roller. See the widgets' documentation to learn more. -
    -
  • Default `NULL`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### anim_duration -The animation duration in milliseconds. Its meaning is widget specific. E.g. blink time of the cursor on the text area or scroll time of a roller. See the widgets' documentation to learn more. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### transition -An initialized `lv_style_transition_dsc_t` to describe a transition. -
    -
  • Default `NULL`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### blend_mode -Describes how to blend the colors to the background. The possible values are `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE/MULTIPLY` -
    -
  • Default `LV_BLEND_MODE_NORMAL`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### layout -Set the layout if the object. The children will be repositioned and resized according to the policies set for the layout. For the possible values see the documentation of the layouts. -
    -
  • Default 0
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### base_dir -Set the base direction of the object. The possible values are `LV_BIDI_DIR_LTR/RTL/AUTO`. -
    -
  • Default `LV_BASE_DIR_AUTO`
  • -
  • Inherited Yes
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### bitmap_mask_src -If set a layer will be created for the widget and the layer will be masked with this A8 bitmap mask. -
    -
  • Default `NULL`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -### rotary_sensitivity -Adjust the sensitivity for rotary encoders in 1/256 unit. It means, 128: slow down the rotary to half, 512: speeds up to double, 256: no change -
    -
  • Default `256`
  • -
  • Inherited No
  • -
  • Layout No
  • -
  • Ext. draw No
  • -
- -## Flex -Flex layout properties. - -### flex_flow -Defines in which direct the flex layout should arrange the children -
    -
  • Default `LV_FLEX_FLOW_NONE`
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### flex_main_place -Defines how to align the children in the direction of flex flow -
    -
  • Default `LV_FLEX_ALIGN_NONE`
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### flex_cross_place -Defines how to align the children perpendicular to the direction of flex flow -
    -
  • Default `LV_FLEX_ALIGN_NONE`
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### flex_track_place -Defines how to align the tracks of the flow -
    -
  • Default `LV_FLEX_ALIGN_NONE`
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### flex_grow -Defines how much space to take proportionally from the free space of the object's track -
    -
  • Default `LV_FLEX_ALIGN_ROW`
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -## Grid -Grid layout properties. - -### grid_column_dsc_array -An array to describe the columns of the grid. Should be LV_GRID_TEMPLATE_LAST terminated -
    -
  • Default `NULL`
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### grid_column_align -Defines how to distribute the columns -
    -
  • Default `LV_GRID_ALIGN_START`
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### grid_row_dsc_array -An array to describe the rows of the grid. Should be LV_GRID_TEMPLATE_LAST terminated -
    -
  • Default `NULL`
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### grid_row_align -Defines how to distribute the rows. -
    -
  • Default `LV_GRID_ALIGN_START`
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### grid_cell_column_pos -Set the column in which the object should be placed -
    -
  • Default `LV_GRID_ALIGN_START`
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### grid_cell_x_align -Set how to align the object horizontally. -
    -
  • Default `LV_GRID_ALIGN_START`
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### grid_cell_column_span -Set how many columns the object should span. Needs to be >= 1 -
    -
  • Default `LV_GRID_ALIGN_START`
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### grid_cell_row_pos -Set the row in which the object should be placed -
    -
  • Default `LV_GRID_ALIGN_START`
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### grid_cell_y_align -Set how to align the object vertically. -
    -
  • Default `LV_GRID_ALIGN_START`
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
- -### grid_cell_row_span -Set how many rows the object should span. Needs to be >= 1 -
    -
  • Default `LV_GRID_ALIGN_START`
  • -
  • Inherited No
  • -
  • Layout Yes
  • -
  • Ext. draw No
  • -
diff --git a/docs/porting/display.rst b/docs/porting/display.rst deleted file mode 100644 index 49eea6868..000000000 --- a/docs/porting/display.rst +++ /dev/null @@ -1,384 +0,0 @@ -.. _display_interface: - -================= -Display interface -================= - -To create a display for LVGL call -:cpp:expr:`lv_display_t * display = lv_display_create(hor_res, ver_res)`. You can create -a multiple displays and a different driver for each (see below), - -Basic setup -*********** - -Draw buffer(s) are simple array(s) that LVGL uses to render the screen's -content. Once rendering is ready the content of the draw buffer is sent -to the display using the ``flush_cb`` function. - -flush_cb --------- - -An example ``flush_cb`` looks like this: - -.. code-block:: c - - void my_flush_cb(lv_display_t * display, const lv_area_t * area, uint8_t * px_map) - { - /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one - *`put_px` is just an example, it needs to be implemented by you.*/ - uint16_t * buf16 = (uint16_t *)px_map; /*Let's say it's a 16 bit (RGB565) display*/ - int32_t x, y; - for(y = area->y1; y <= area->y2; y++) { - for(x = area->x1; x <= area->x2; x++) { - put_px(x, y, *buf16); - buf16++; - } - } - - /* IMPORTANT!!! - * Inform LVGL that you are ready with the flushing and buf is not used anymore*/ - lv_display_flush_ready(disp); - } - -Use :cpp:expr:`lv_display_set_flush_cb(disp, my_flush_cb)` to set a new ``flush_cb``. - -:cpp:expr:`lv_display_flush_ready(disp)` needs to be called when flushing is ready -to inform LVGL the buffer is not used anymore by the driver and it can -render new content into it. - -LVGL might render the screen in multiple chunks and therefore call -``flush_cb`` multiple times. To see if the current one is the last chunk -of rendering use :cpp:expr:`lv_display_flush_is_last(display)`. - -Draw buffers ------------- - -The draw buffers can be set with -:cpp:expr:`lv_display_set_buffers(display, buf1, buf2, buf_size_byte, render_mode)` - -- ``buf1`` a buffer where LVGL can render -- ``buf2`` a second optional buffer (see more details below) -- ``buf_size_byte`` size of the buffer(s) in bytes -- ``render_mode`` - - - :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_PARTIAL` Use the buffer(s) to render the - screen in smaller parts. This way the buffers can be smaller then - the display to save RAM. At least 1/10 screen size buffer(s) are - recommended. In ``flush_cb`` the rendered images needs to be - copied to the given area of the display. In this mode if a button is pressed - only the button's area will be redrawn. - - :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_DIRECT` The buffer(s) has to be screen - sized and LVGL will render into the correct location of the - buffer. This way the buffer always contain the whole image. If two - buffer are used the rendered areas are automatically copied to the - other buffer after flushing. Due to this in ``flush_cb`` typically - only a frame buffer address needs to be changed. If a button is pressed - only the button's area will be redrawn. - - :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_FULL` The buffer(s) has to be screen - sized and LVGL will always redraw the whole screen even if only 1 - pixel has been changed. If two screen sized draw buffers are - provided, LVGL's display handling works like "traditional" double - buffering. This means the ``flush_cb`` callback only has to update - the address of the frame buffer to the ``px_map`` parameter. - -Example: - -.. code-block:: c - - static uint16_t buf[LCD_HOR_RES * LCD_VER_RES / 10]; - lv_display_set_buffers(disp, buf, NULL, sizeof(buf), LV_DISPLAY_RENDER_MODE_PARTIAL); - -One buffer -^^^^^^^^^^ - -If only one buffer is used LVGL draws the content of the screen into -that draw buffer and sends it to the display via the ``flush_cb``. LVGL -then needs to wait until :cpp:expr:`lv_display_flush_ready` is called -(that is the content of the buffer is sent to the -display) before drawing something new into it. - -Two buffers -^^^^^^^^^^^ - -If two buffers are used LVGL can draw into one buffer while the content -of the other buffer is sent to the display in the background. DMA or -other hardware should be used to transfer data to the display so the MCU -can continue drawing. This way, the rendering and refreshing of the -display become parallel operations. - -Advanced options -**************** - -Resolution ----------- - -To set the resolution of the display after creation use -:cpp:expr:`lv_display_set_resolution(display, hor_res, ver_res)` - -It's not mandatory to use the whole display for LVGL, however in some -cases the physical resolution is important. For example the touchpad -still sees the whole resolution and the values needs to be converted to -the active LVGL display area. So the physical resolution and the offset -of the active area can be set with -:cpp:expr:`lv_display_set_physical_resolution(disp, hor_res, ver_res)` and -:cpp:expr:`lv_display_set_offset(disp, x, y)` - -Flush wait callback -------------------- - -By using :cpp:expr:`lv_display_flush_ready` LVGL will spin in a loop -while waiting for flushing. - -However with the help of :cpp:expr:`lv_display_set_flush_wait_cb` a custom -wait callback be set for flushing. This callback can use a semaphore, mutex, -or anything else to optimize while the waiting for flush. - -If ``flush_wait_cb`` is not set, LVGL assume that `lv_display_flush_ready` -is used. - -Rotation --------- - -LVGL supports rotation of the display in 90 degree increments. You can -select whether you would like software rotation or hardware rotation. - -The orientation of the display can be changed with -``lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_0/90/180/270)``. -LVGL will swap the horizontal and vertical resolutions internally -according to the set degree. When changing the rotation -:cpp:expr:`LV_EVENT_SIZE_CHANGED` is sent to the display to allow -reconfiguring the hardware. In lack of hardware display rotation support -:cpp:expr:`lv_draw_sw_rotate` can be used to rotate the buffer in the -``flush_cb``. - -:cpp:expr:`lv_display_rotate_area(display, &area)` rotates the rendered area -according to the current rotation settings of the display. - -Note that in :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_DIRECT` the small changed areas -are rendered directly in the frame buffer so they cannot be -rotated later. Therefore in direct mode only the whole frame buffer can be rotated. -The same is true for :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_FULL`. - -In the case of :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_PARTIAL` the small rendered areas -can be rotated on their own before flushing to the frame buffer. - -Color format ------------- - -The default color format of the display is set according to :c:macro:`LV_COLOR_DEPTH` -(see ``lv_conf.h``) - -- :c:macro:`LV_COLOR_DEPTH` ``32``: XRGB8888 (4 bytes/pixel) -- :c:macro:`LV_COLOR_DEPTH` ``24``: RGB888 (3 bytes/pixel) -- :c:macro:`LV_COLOR_DEPTH` ``16``: RGB565 (2 bytes/pixel) -- :c:macro:`LV_COLOR_DEPTH` ``8``: L8 (1 bytes/pixel) -- :c:macro:`LV_COLOR_DEPTH` ``1``: I1 (1 bit/pixel) Only support for horizontal mapped buffers. See :ref:`monochrome` for more details: - -The ``color_format`` can be changed with -``lv_display_set_color_depth(display, LV_COLOR_FORMAT_...)`` . -Besides the default value :c:macro:`LV_COLOR_FORMAT_ARGB8888` can be -used as a well. - -It's very important that draw buffer(s) should be large enough for any -selected color format. - - -Swap endianness ---------------- - -In case of RGB565 color format it might be required to swap the 2 bytes -because the SPI, I2C or 8 bit parallel port periphery sends them in the wrong order. - -The ideal solution is configure the hardware to handle the 16 bit data with different byte order, -however if it's not possible :cpp:expr:`lv_draw_sw_rgb565_swap(buf, buf_size_in_px)` -can be called in the ``flush_cb`` to swap the bytes. - -If you wish you can also write your own function, or use assembly instructions for -the fastest possible byte swapping. - -Note that this is not about swapping the Red and Blue channel but converting - -``RRRRR GGG | GGG BBBBB`` - -to - -``GGG BBBBB | RRRRR GGG``. - -.. _monochrome: - -Monochrome Displays -------------------- - -LVGL supports rendering directly in a 1-bit format for monochrome displays. -To enable it, set ``LV_COLOR_DEPTH 1`` or use :cpp:expr:`lv_display_set_color_format(display, LV_COLOR_FORMAT_I1)`. - -The :cpp:expr:`LV_COLOR_FORMAT_I1` format assumes that bytes are mapped to rows (i.e., the bits of a byte are written next to each other). -The order of bits is MSB first, which means: - -.. code:: - - MSB LSB - bits 7 6 5 4 3 2 1 0 - pixels 0 1 2 3 4 5 6 7 - Left Right - -Ensure that the LCD controller is configured accordingly. - -Internally, LVGL rounds the redrawn areas to byte boundaries. Therefore, updated areas will: - -- Start on an ``Nx8`` coordinate. -- End on an ``Nx8 - 1`` coordinate. - -When setting up the buffers for rendering (:cpp:func:`lv_display_set_buffers`), make the buffer 8 bytes larger. -This is necessary because LVGL reserves 2 x 4 bytes in the buffer, as these are assumed to be used as a palette. - -To skip the palette, include the following line in your ``flush_cb`` function: ``px_map += 8``. - -As usual, monochrome displays support partial, full, and direct rendering modes as well. -In full and direct modes, the buffer size should be large enough for the whole screen, meaning ``(horizontal_resolution x vertical_resolution / 8) + 8`` bytes. -As LVGL can not handle fractional width make sure to round the horizontal resolution to 8- -(For example 90 to 96) - -Constraints on the Redrawn Area -------------------------------- - -Some display controllers have specific requirements for the window area where the rendered image can be sent -(e.g., `x1` must be even, and `x2` must be odd). - -In the case of monochrome displays, `x1` must be `Nx8`, and `x2` must be `Nx8 - 1`. -(If the display uses `LV_COLOR_FORMAT_I1`, LVGL automatically applies this rounding. See :ref:`monochrome`.) - -The size of the invalidated (redrawn) area can be controlled as follows: - -.. code:: c - - void rounder_event_cb(lv_event_t * e) - { - lv_area_t * a = lv_event_get_invalidated_area(e); - - a->x1 = a->x1 & (~0x1); /* Ensure that x1 is even */ - a->x2 = a->x2 | 0x1; /* Ensure that x2 is odd */ - } - - ... - - lv_display_add_event_cb(disp, rounder_event_cb, LV_EVENT_INVALIDATE_AREA, NULL); - - -Tiled Rendering ---------------- - -When multiple CPU cores are available and a large area needs to be redrawn, LVGL must identify independent areas that can be rendered in parallel. - -For example, if there are 4 CPU cores, one core can draw the screen's background while the other 3 must wait until it is finished. If there are 2 buttons on the screen, those 2 buttons can be rendered in parallel, but 2 cores will still remain idle. - -Due to dependencies among different areas, CPU cores cannot always be fully utilized. - -To address this, LVGL can divide large areas that need to be updated into smaller tiles. These tiles are independent, making it easier to find areas that can be rendered concurrently. - -Specifically, if there are 4 tiles and 4 cores, there will always be an independent area for each core within one of the tiles. - -The maximum number of tiles can be set using the function :cpp:func:`lv_display_set_tile_cnt(disp, cnt)`. The default value is :cpp:expr:`LV_DRAW_SW_DRAW_UNIT_CNT` (or 1 if software rendering is not enabled). - -Small areas are not further divided into smaller tiles because the overhead of spinning up 4 cores would outweigh the benefits. - -The ideal tile size is calculated as ``ideal_tile_size = draw_buf_size / tile_cnt``. For example, in :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_DIRECT` mode on an 800x480 screen, the display buffer is 800x480 = 375k pixels. If there are 4 tiles, the ideal tile size is approximately 93k pixels. Based on this, core utilization is as follows: - -- 30k pixels: 1 core -- 90k pixels: 1 core -- 95k pixels: 2 cores (above 93k pixels, 2 cores are used) -- 150k pixels: 2 cores -- 200k pixels: 3 cores (above 186k pixels, 3 cores are used) -- 300k pixels: 4 cores (above 279k pixels, 4 cores are used) -- 375k pixels: 4 cores - -In :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_DIRECT`, the screen-sized draw buffer is divided by the tile count to determine the ideal tile sizes. If smaller areas are refreshed, it may result in fewer cores being used. - -In :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_FULL`, the maximum number of tiles is always created as the entire screen is refreshed. - -In :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_PARTIAL`, the partial buffer is divided into tiles. For example, if the draw buffer is 1/10th the size of the screen and there are 2 tiles, then 1/20th + 1/20th of the screen area will be rendered at once. - -Tiled rendering only affects the rendering process, and the ``flush_cb`` is called once for each invalidated area. Therefore, tiling is not visible from the flushing point of view. - - -User data ---------- - -With :cpp:expr:`lv_display_set_user_data(disp, p)` a pointer to a custom data can -be stored in display object. - -Decoupling the display refresh timer ------------------------------------- - -Normally the dirty (a.k.a invalid) areas are checked and redrawn in -every :c:macro:`LV_DEF_REFR_PERIOD` milliseconds (set in ``lv_conf.h``). -However, in some cases you might need more control on when the display -refreshing happen, for example to synchronize rendering with VSYNC or -the TE signal. - -You can do this in the following way: - -.. code-block:: c - - /*Delete the original display refresh timer*/ - lv_display_delete_refr_timer(disp); - - /*Call this anywhere you want to refresh the dirty areas*/ - _lv_display_refr_timer(NULL); - -If you have multiple displays call :cpp:expr:`lv_display_set_default(disp1)` to -select the display to refresh before :cpp:expr:`_lv_display_refr_timer(NULL)`. - - -.. note:: that :cpp:func:`lv_timer_handler` and :cpp:func:`_lv_display_refr_timer` cannot run at the same time. - - -If the performance monitor is enabled, the value of :c:macro:`LV_DEF_REFR_PERIOD` needs to be set to be -consistent with the refresh period of the display to ensure that the statistical results are correct. - - -Force refreshing ----------------- - -Normally the invalidated areas (marked for redraw) are rendered in :cpp:func:`lv_timer_handler` in every -:c:macro:`LV_DEF_REFR_PERIOD` milliseconds. However, by using :cpp:expr:`lv_refr_now(display)` you can ask LVGL to -redraw the invalid areas immediately. The refreshing will happen in :cpp:func:`lv_refr_now` which might take -longer time. - -The parameter of :cpp:func:`lv_refr_now` is a display to refresh. If ``NULL`` is set the default display will be updated. - -Events -****** - -:cpp:expr:`lv_display_add_event_cb(disp, event_cb, LV_EVENT_..., user_data)` adds -an event handler to a display. The following events are sent: - -- :cpp:enumerator:`LV_EVENT_INVALIDATE_AREA` An area is invalidated (marked for redraw). - :cpp:expr:`lv_event_get_param(e)` returns a pointer to an :cpp:struct:`lv_area_t` - variable with the coordinates of the area to be invalidated. The area can - be freely modified if needed to adopt it the special requirement of the - display. Usually needed with monochrome displays to invalidate ``N x 8`` - rows or columns at once. -- :cpp:enumerator:`LV_EVENT_REFR_REQUEST`: Sent when something happened that requires redraw. -- :cpp:enumerator:`LV_EVENT_REFR_START`: Sent when a refreshing cycle starts. Sent even if there is nothing to redraw. -- :cpp:enumerator:`LV_EVENT_REFR_READY`: Sent when refreshing is ready (after rendering and calling the ``flush_cb``). Sent even if no redraw happened. -- :cpp:enumerator:`LV_EVENT_RENDER_START`: Sent when rendering starts. -- :cpp:enumerator:`LV_EVENT_RENDER_READY`: Sent when rendering is ready (before calling the ``flush_cb``) -- :cpp:enumerator:`LV_EVENT_FLUSH_START`: Sent before the ``flush_cb`` is called. -- :cpp:enumerator:`LV_EVENT_FLUSH_READY`: Sent when the ``flush_cb`` returned. -- :cpp:enumerator:`LV_EVENT_RESOLUTION_CHANGED`: Sent when the resolution changes due - to :cpp:func:`lv_display_set_resolution` or :cpp:func:`lv_display_set_rotation`. - - -Further reading -*************** - -- `lv_port_disp_template.c `__ - for a template for your own driver. -- :ref:`Drawing ` to learn more about how rendering - works in LVGL. -- :ref:`display_features` to learn more about higher - level display features. - -API -*** diff --git a/docs/porting/indev.rst b/docs/porting/indev.rst deleted file mode 100644 index 8801e3e56..000000000 --- a/docs/porting/indev.rst +++ /dev/null @@ -1,305 +0,0 @@ -.. _porting_indev: - -====================== -Input device interface -====================== - -Types of input devices -********************** - -To create an input device use - -.. code-block:: c - - /*Register at least one display before you register any input devices*/ - lv_indev_t * indev = lv_indev_create(); - lv_indev_set_type(indev, LV_INDEV_TYPE_...); /*See below.*/ - lv_indev_set_read_cb(indev, read_cb); /*See below.*/ - -The ``type`` member can be: - -- :cpp:enumerator:`LV_INDEV_TYPE_POINTER`: touchpad or mouse -- :cpp:enumerator:`LV_INDEV_TYPE_KEYPAD`: keyboard or keypad -- :cpp:enumerator:`LV_INDEV_TYPE_ENCODER`: encoder with left/right turn and push options -- :cpp:enumerator:`LV_INDEV_TYPE_BUTTON`: external buttons virtually pressing the screen - -``read_cb`` is a function pointer which will be called periodically to -report the current state of an input device. - -Visit :ref:`Input devices ` to learn more about input -devices in general. - -Touchpad, mouse or any pointer ------------------------------- - -Input devices that can click points on the screen belong to this -category. - -.. code-block:: c - - lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); - ... - - void my_input_read(lv_indev_t * indev, lv_indev_data_t*data) - { - if(touchpad_pressed) { - data->point.x = touchpad_x; - data->point.y = touchpad_y; - data->state = LV_INDEV_STATE_PRESSED; - } else { - data->state = LV_INDEV_STATE_RELEASED; - } - } - - -Mouse cursor -~~~~~~~~~~~~ - -To set a mouse cursor use :cpp:expr:`lv_indev_set_cursor(indev, &img_cursor)`. - -Crown behavior -~~~~~~~~~~~~~~ - -The "Crown" is a rotary device typically found on smart watches. - -When the user clicks somewhere and after that turns the rotary -the last clicked widget will be either scrolled or it's value will be incremented/decremented -(e.g. in case of a slider). - -As this behavior is tightly related to the last clicked widget, the crown support is -an extension of the pointer input device. Just set ``data->diff`` to the number of -turned steps and LVGL will automatically send :cpp:enumerator:`LV_EVENT_ROTARY` or scroll the widget based on the -``editable`` flag in the widget's class. Non-editable widgets are scrolled and for editable widgets the event is sent. - -To get the steps in an event callback use :cpp:func:`lv_event_get_rotary_diff` - -The rotary sensitivity can be adjusted on 2 levels: - -1. In the input device by the `indev->rotary_sensitivity` element (1/256 unit) -2. By the `rotary_sensitivity` style property in the widget (1/256 unit) - -The final diff is calculated like this: - -``diff_final = diff_in * (indev_sensitivity / 256) + (widget_sensitivity / 256);`` - - -For example, if both the indev and widget sensitivity is set to 128 (0.5), the input diff. will be -multiplied by 0.25 (divided by 4). The value of the widget will be incremented by this value or -the widget will be scrolled this amount of pixels. - - -Keypad or keyboard ------------------- - -Full keyboards with all the letters or simple keypads with a few -navigation buttons belong here. - -To use a keyboard/keypad: - -- Register a ``read_cb`` function and use :cpp:enumerator:`LV_INDEV_TYPE_KEYPAD` type. -- An object group has to be created: ``lv_group_t * g = lv_group_create()`` and objects have to be added to - it with :cpp:expr:`lv_group_add_obj(g, obj)` -- The created group has to be assigned to an input device: :cpp:expr:`lv_indev_set_group(indev, g)` -- Use ``LV_KEY_...`` to navigate among the objects in the group. See - ``lv_core/lv_group.h`` for the available keys. - -.. code-block:: c - - - lv_indev_set_type(indev, LV_INDEV_TYPE_KEYPAD); - - ... - - void keyboard_read(lv_indev_t * indev, lv_indev_data_t*data){ - data->key = last_key(); /*Get the last pressed or released key*/ - - if(key_pressed()) data->state = LV_INDEV_STATE_PRESSED; - else data->state = LV_INDEV_STATE_RELEASED; - } - -Encoder -------- - -With an encoder you can do the following: - -1. Press its button -2. Long-press its button -3. Turn left -4. Turn right - -In short, the Encoder input devices work like this: - -- By turning the encoder you can focus on the next/previous object. -- When you press the encoder on a simple object (like a button), it will be clicked. -- If you press the encoder on a complex object (like a list, message box, etc.) - the object will go to edit mode whereby you can navigate inside the - object by turning the encoder. -- To leave edit mode, long press the button. - -To use an *Encoder* (similarly to the *Keypads*) the objects should be -added to groups. - -.. code-block:: c - - lv_indev_set_type(indev, LV_INDEV_TYPE_ENCODER); - - ... - - void encoder_read(lv_indev_t * indev, lv_indev_data_t*data){ - data->enc_diff = enc_get_new_moves(); - - if(enc_pressed()) data->state = LV_INDEV_STATE_PRESSED; - else data->state = LV_INDEV_STATE_RELEASED; - } - -Using buttons with Encoder logic -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In addition to standard encoder behavior, you can also utilize its logic -to navigate(focus) and edit widgets using buttons. This is especially -handy if you have only few buttons available, or you want to use other -buttons in addition to encoder wheel. - -You need to have 3 buttons available: - -- :cpp:enumerator:`LV_KEY_ENTER`: will simulate press or pushing of the encoder button -- :cpp:enumerator:`LV_KEY_LEFT`: will simulate turning encoder left -- :cpp:enumerator:`LV_KEY_RIGHT`: will simulate turning encoder right -- other keys will be passed to the focused widget - -If you hold the keys it will simulate an encoder advance with period -specified in ``indev_drv.long_press_repeat_time``. - -.. code-block:: c - - - lv_indev_set_type(indev, LV_INDEV_TYPE_ENCODER); - - ... - - void encoder_with_keys_read(lv_indev_t * indev, lv_indev_data_t*data){ - data->key = last_key(); /*Get the last pressed or released key*/ - /* use LV_KEY_ENTER for encoder press */ - if(key_pressed()) data->state = LV_INDEV_STATE_PRESSED; - else { - data->state = LV_INDEV_STATE_RELEASED; - /* Optionally you can also use enc_diff, if you have encoder*/ - data->enc_diff = enc_get_new_moves(); - } - } - -Button ------- - -*Buttons* mean external "hardware" buttons next to the screen which are -assigned to specific coordinates of the screen. If a button is pressed -it will simulate the pressing on the assigned coordinate. (Similarly to a touchpad) - -To assign buttons to coordinates use ``lv_indev_set_button_points(my_indev, points_array)``. ``points_array`` -should look like ``const lv_point_t points_array[] = { {12,30},{60,90}, ...}`` - -:important: The points_array can't go out of scope. Either declare it as a global variable - or as a static variable inside a function.` - -.. code-block:: c - - - lv_indev_set_type(indev, LV_INDEV_TYPE_BUTTON); - - ... - - void button_read(lv_indev_t * indev, lv_indev_data_t*data){ - static uint32_t last_btn = 0; /*Store the last pressed button*/ - int btn_pr = my_btn_read(); /*Get the ID (0,1,2...) of the pressed button*/ - if(btn_pr >= 0) { /*Is there a button press? (E.g. -1 indicated no button was pressed)*/ - last_btn = btn_pr; /*Save the ID of the pressed button*/ - data->state = LV_INDEV_STATE_PRESSED; /*Set the pressed state*/ - } else { - data->state = LV_INDEV_STATE_RELEASED; /*Set the released state*/ - } - - data->btn_id = last_btn; /*Save the last button*/ - } - -When the ``button_read`` callback in the example above changes the ``data->btn_id`` to ``0`` -a press/release action at the first index of the ``points_array`` will be performed (``{12,30}``). - -.. _porting_indev_other_features: - -Other features -************** - -Parameters ----------- - -The default value of the following parameters can be changed in :cpp:type:`lv_indev_t`: - -- ``scroll_limit`` Number of pixels to slide before actually scrolling the object. -- ``scroll_throw`` Scroll throw (momentum) slow-down in [%]. Greater value means faster slow-down. -- ``long_press_time`` Press time to send :cpp:enumerator:`LV_EVENT_LONG_PRESSED` (in milliseconds) -- ``long_press_repeat_time`` Interval of sending :cpp:enumerator:`LV_EVENT_LONG_PRESSED_REPEAT` (in milliseconds) -- ``read_timer`` pointer to the ``lv_timer`` which reads the input device. Its parameters - can be changed by ``lv_timer_...()`` functions. :c:macro:`LV_DEF_REFR_PERIOD` - in ``lv_conf.h`` sets the default read period. - -Feedback --------- - -Besides ``read_cb`` a ``feedback_cb`` callback can be also specified in -:cpp:type:`lv_indev_t`. ``feedback_cb`` is called when any type of event is sent -by the input devices (independently of its type). This allows generating -feedback for the user, e.g. to play a sound on :cpp:enumerator:`LV_EVENT_CLICKED`. - -Associating with a display --------------------------- - -Every input device is associated with a display. By default, a new input -device is added to the last display created or explicitly selected -(using :cpp:func:`lv_display_set_default`). The associated display is stored and -can be changed in ``disp`` field of the driver. - -Buffered reading ----------------- - -By default, LVGL calls ``read_cb`` periodically. Because of this -intermittent polling there is a chance that some user gestures are -missed. - -To solve this you can write an event driven driver for your input device -that buffers measured data. In ``read_cb`` you can report the buffered -data instead of directly reading the input device. Setting the -``data->continue_reading`` flag will tell LVGL there is more data to -read and it should call ``read_cb`` again. - -Switching the input device to event-driven mode ------------------------------------------------ - -Normally the input event is read every :c:macro:`LV_DEF_REFR_PERIOD` -milliseconds (set in ``lv_conf.h``). However, in some cases, you might -need more control over when to read the input device. For example, you -might need to read it by polling file descriptor (fd). - -You can do this in the following way: - -.. code-block:: c - - /*Update the input device's running mode to LV_INDEV_MODE_EVENT*/ - lv_indev_set_mode(indev, LV_INDEV_MODE_EVENT); - - ... - - /*Call this anywhere you want to read the input device*/ - lv_indev_read(indev); - -.. note:: that :cpp:func:`lv_indev_read`, :cpp:func:`lv_timer_handler` and :cpp:func:`_lv_display_refr_timer` cannot run at the same time. - -.. note:: For devices in event-driven mode, `data->continue_reading` is ignored. - -Further reading -*************** - -- `lv_port_indev_template.c `__ for a template for your own driver. -- `INdev features ` to learn more about higher level input device features. - -API -*** diff --git a/docs/porting/index.rst b/docs/porting/index.rst deleted file mode 100644 index 27fad7d82..000000000 --- a/docs/porting/index.rst +++ /dev/null @@ -1,18 +0,0 @@ -.. _porting: - -======= -Porting -======= - - -.. toctree:: - :maxdepth: 2 - - display - draw - indev - os - project - sleep - tick - timer_handler diff --git a/docs/porting/os.rst b/docs/porting/os.rst deleted file mode 100644 index afb200359..000000000 --- a/docs/porting/os.rst +++ /dev/null @@ -1,76 +0,0 @@ -.. _os_interrupt: - -=============================== -Operating system and interrupts -=============================== - -LVGL is **not thread-safe** by default. - -However, in the following conditions it's valid to call LVGL related -functions: - -- In *events*. Learn more in :ref:`events`. -- In *lv_timer*. Learn more in :ref:`timers`. - -Tasks and threads ------------------ - -If you need to use real tasks or threads, you need a mutex which should -be invoked before the call of :cpp:func:`lv_timer_handler` and released after -it. Also, you have to use the same mutex in other tasks and threads -around every LVGL (``lv_...``) related function call and code. This way -you can use LVGL in a real multitasking environment. Just make use of a -mutex to avoid the concurrent calling of LVGL functions. - -LVGL has a built-in mutex which can be used with: - -- :cpp:func:`lv_lock()` and :cpp:func:`lv_lock_isr()` -- :cpp:func:`lv_unlock()` - -These functions are called internally in :cpp:func:`lv_timer_handler` -and the users need to call them only from their own threads. - -To enable ``lv_lock/lv_unlock`` ``LV_USE_OS`` needs to be set to other -than ``LV_OS_NONE``. - - -Here is some pseudocode to illustrate the concept: - -.. code-block:: c - - void lvgl_thread(void) - { - while(1) { - uint32_t time_till_next; - time_till_next = lv_timer_handler(); /*lv_lock/lv_unlock is called internally*/ - thread_sleep(time_till_next); /* sleep for a while */ - } - } - - void other_thread(void) - { - /* You must always hold the mutex while using LVGL APIs */ - lv_lock(); - lv_obj_t *img = lv_image_create(lv_screen_active()); - lv_unlock(); - - while(1) { - lv_lock(); - /* change to the next image */ - lv_image_set_src(img, next_image); - lv_unlock(); - thread_sleep(2000); - } - } - -Interrupts ----------- - -Try to avoid calling LVGL functions from interrupt handlers (except -:cpp:func:`lv_tick_inc` and :cpp:func:`lv_display_flush_ready`). But if you need to do -this you have to disable the interrupt which uses LVGL functions while -:cpp:func:`lv_timer_handler` is running. - -It's a better approach to simply set a flag or some value in the -interrupt, and periodically check it in an LVGL timer (which is run by -:cpp:func:`lv_timer_handler`). diff --git a/docs/porting/project.rst b/docs/porting/project.rst deleted file mode 100644 index 91454a399..000000000 --- a/docs/porting/project.rst +++ /dev/null @@ -1,139 +0,0 @@ -================ -Set up a project -================ - -Get the library ---------------- - -LVGL is available on GitHub: https://github.com/lvgl/lvgl. - -You can clone it or -`Download `__ -the latest version of the library from GitHub. - -Add lvgl to your project ------------------------- - -The graphics library itself is the ``lvgl`` directory. It contains a -couple of folders but to use ``lvgl`` you only need the ``.c`` and ``.h`` -files in the ``src`` folder. - -Automatically add files -~~~~~~~~~~~~~~~~~~~~~~~ - -If your IDE automatically adds the files from the folders copied to the -project folder (as Eclipse or VSCode does), you can simply copy the -``lvgl`` folder as it is into your project. - -Make and CMake -~~~~~~~~~~~~~~ - -LVGL also supports ``make`` and ``CMake`` build systems out of the box. -To add LVGL to your Makefile based build system add these lines to your -main Makefile: - -.. code-block:: make - - LVGL_DIR_NAME ?= lvgl #The name of the lvgl folder (change this if you have renamed it) - LVGL_DIR ?= ${shell pwd} #The path where the lvgl folder is - include $(LVGL_DIR)/$(LVGL_DIR_NAME)/lvgl.mk - -For integration with CMake take a look this section of the -`Documentation `__. - -Other platforms and tools -~~~~~~~~~~~~~~~~~~~~~~~~~ - -The `Get started `__ section contains many platform -specific descriptions e.g. for ESP32, Arduino, NXP, RT-Thread, NuttX, -etc. - -Demos and Examples -~~~~~~~~~~~~~~~~~~ - -The ``lvgl`` folder also contains an ``examples`` and a ``demos`` -folder. If you needed to add the source files manually to your project, -you can do the same with the source files of these two folders too. -``make`` and ``CMake`` handles the examples and demos, so no extra -action required in these cases. - -Configuration file ------------------- - -There is a configuration header file for LVGL called **lv_conf.h**. You -can modify this header to set the library's basic behavior, disable unused -modules and features, adjust the size of buffers in compile-time, -etc. - -To get ``lv_conf.h`` **copy lvgl/lv_conf_template.h** next to the -``lvgl`` directory and rename it to *lv_conf.h*. Open the file and -change the ``#if 0`` at the beginning to ``#if 1`` to enable its -content. So the layout of the files should look like this: - -:: - - |-lvgl - |-lv_conf.h - |-other files and folders - -Comments in the config file explain the meaning of the options. Be sure -to set at least :c:macro:`LV_COLOR_DEPTH` according to your display's color -depth. Note that, the examples and demos explicitly need to be enabled -in ``lv_conf.h``. - -Alternatively, ``lv_conf.h`` can be copied to another place but then you -should add the :c:macro:`LV_CONF_INCLUDE_SIMPLE` define to your compiler -options (e.g. ``-DLV_CONF_INCLUDE_SIMPLE`` for GCC compiler) and set the -include path manually (e.g. ``-I../include/gui``). In this case LVGL -will attempt to include ``lv_conf.h`` simply with -``#include "lv_conf.h"``. - -You can even use a different name for ``lv_conf.h``. The custom path can -be set via the :c:macro:`LV_CONF_PATH` define. For example -``-DLV_CONF_PATH="/home/joe/my_project/my_custom_conf.h"``. If this define -is set :c:macro:`LV_CONF_SKIP` is assumed to be ``0``. - -If :c:macro:`LV_CONF_SKIP` is defined, LVGL will not try to include -``lv_conf.h``. Instead you can pass the config defines using build -options. For example ``"-DLV_COLOR_DEPTH=32 -DLV_USE_BUTTON=1"``. The unset -options will get a default value which is the same as the content of -``lv_conf_template.h``. - -LVGL also can be used via ``Kconfig`` and ``menuconfig``. You can use -``lv_conf.h`` together with Kconfig too, but keep in mind that the value -from ``lv_conf.h`` or build settings (``-D...``) overwrite the values -set in Kconfig. To ignore the configs from ``lv_conf.h`` simply remove -its content, or define :c:macro:`LV_CONF_SKIP`. - -To enable multi-instance feature, set :c:macro:`LV_GLOBAL_CUSTOM` in -``lv_conf.h`` and provide a custom function to -:cpp:func:`lv_global_default` using ``__thread`` or ``pthread_key_t``. -It will allow running multiple LVGL instances by storing the global variables -in TLS (Thread Local Storage). - -For example: - -.. code-block:: c - - lv_global_t * lv_global_default(void) - { - static __thread lv_global_t lv_global; - return &lv_global; - } - - -Initialization --------------- - -To use the graphics library you have to initialize it and setup required -components. The order of the initialization is: - -1. Call :cpp:func:`lv_init`. -2. Initialize your drivers. -3. Register the display and input devices drivers in LVGL. Learn more - about `Display `__ and `Input - device `__ registration. -4. Call :cpp:expr:`lv_tick_inc(x)` every ``x`` milliseconds in an interrupt to - report the elapsed time to LVGL. `Learn more `__. -5. Call :cpp:func:`lv_timer_handler` every few milliseconds to handle LVGL - related tasks. `Learn more `__. diff --git a/docs/porting/sleep.rst b/docs/porting/sleep.rst deleted file mode 100644 index f7737a845..000000000 --- a/docs/porting/sleep.rst +++ /dev/null @@ -1,33 +0,0 @@ -================ -Sleep management -================ - -The MCU can go to sleep when no user input happens. In this case, the -main ``while(1)`` should look like this: - -.. code-block:: c - - while(1) { - /*Normal operation (no sleep) in < 1 sec inactivity*/ - if(lv_display_get_inactive_time(NULL) < 1000) { - lv_timer_handler(); - } - /*Sleep after 1 sec inactivity*/ - else { - timer_stop(); /*Stop the timer where lv_tick_inc() is called*/ - sleep(); /*Sleep the MCU*/ - } - my_delay_ms(5); - } - -You should also add the following lines to your input device read -function to signal a wake-up (press, touch or click etc.) has happened: - -.. code-block:: c - - lv_tick_inc(LV_DEF_REFR_PERIOD); /*Force task execution on wake-up*/ - timer_start(); /*Restart the timer where lv_tick_inc() is called*/ - lv_timer_handler(); /*Call `lv_timer_handler()` manually to process the wake-up event*/ - -In addition to :cpp:func:`lv_display_get_inactive_time` you can check -:cpp:func:`lv_anim_count_running` to see if all animations have finished. diff --git a/docs/porting/tick.rst b/docs/porting/tick.rst deleted file mode 100644 index 901ab855b..000000000 --- a/docs/porting/tick.rst +++ /dev/null @@ -1,34 +0,0 @@ -.. _tick: - -============== -Tick interface -============== - -LVGL needs a system tick to know the elapsed time for animations and other -tasks. - -There are two ways to provide the tick to LVGL: - -1. Call ``lv_tick_set_cb(my_get_milliseconds_function);``: `my_get_milliseconds_function` needs to tell how many milliseconds have elapsed since start up. Most of the platforms have built-in functions that can be used as they are. For example - - - SDL: ``lv_tick_set_cb(SDL_GetTicks);`` - - Arduino: ``lv_tick_set_cb(my_tick_get_cb);``, where ``my_tick_get_cb`` is: ``static uint32_t my_tick_get_cb(void) { return millis(); }`` - - FreeRTOS: ``lv_tick_set_cb(xTaskGetTickCount);`` - - STM32: ``lv_tick_set_cb(HAL_GetTick);`` - - ESP32: ``lv_tick_set_cb(my_tick_get_cb);``, where ``my_tick_get_cb`` is a wrapper for ``esp_timer_get_time() / 1000;`` - -2. Call ``lv_tick_inc(x)`` periodically, where ``x`` is the elapsed milliseconds since the last call. ``lv_tick_inc`` should be called from a high priority interrupt. - -The ticks (milliseconds) should be independent from any other activities of the MCU. - -For example this works, but LVGL's timing will be incorrect as the execution time of ``lv_timer_handler`` is not considered: - -.. code-block:: c - - // Bad idea - lv_timer_handler(); - lv_tick_inc(5); - my_delay_ms(5); - -API ---- diff --git a/docs/requirements.txt b/docs/requirements.txt index 27054d90d..138de0cec 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -14,3 +14,4 @@ sphinxcontrib-mermaid sphinx-design sphinx-rtd-dark-mode typing-extensions +sphinx-reredirects diff --git a/docs/widgets/obj.rst b/docs/widgets/obj.rst deleted file mode 100644 index 90c587669..000000000 --- a/docs/widgets/obj.rst +++ /dev/null @@ -1,290 +0,0 @@ -.. _lv_obj: - -==================== -Base object (lv_obj) -==================== - -Overview -******** - -The 'Base Object' implements the basic properties of widgets on a -screen, such as: - -- coordinates -- parent object -- children -- contains the styles -- attributes like *Clickable*, *Scrollable*, etc. - -In object-oriented thinking, it is the base class from which all other -objects in LVGL are inherited. - -The functions and functionalities of the Base object can be used with -other widgets too. For example :cpp:expr:`lv_obj_set_width(slider, 100)` - -The Base object can be directly used as a simple widget: it's nothing -more than a rectangle. In HTML terms, think of it as a ``
``. - -.. _lv_obj_coordinates: - -Coordinates ------------ - -Only a small subset of coordinate settings is described here. To see all -the features of LVGL (padding, coordinates in styles, layouts, etc) -visit the :ref:`Coordinates ` page. - -.. _lv_obj_size: - -Size -^^^^ - -The object size can be modified on individual axes with -:cpp:expr:`lv_obj_set_width(obj, new_width)` and -:cpp:expr:`lv_obj_set_height(obj, new_height)`, or both axes can be modified at -the same time with :cpp:expr:`lv_obj_set_size(obj, new_width, new_height)`. - -.. _lv_obj_position: - -Position -^^^^^^^^ - -You can set the position relative to the parent with -:cpp:expr:`lv_obj_set_x(obj, new_x)` and :cpp:expr:`lv_obj_set_y(obj, new_y)`, or both -axes at the same time with :cpp:expr:`lv_obj_set_pos(obj, new_x, new_y)`. - -.. _lv_obj_alignment: - -Alignment -^^^^^^^^^ - -You can align the object on its parent with -:cpp:expr:`lv_obj_set_align(obj, LV_ALIGN_...)`. After this every x and y -setting will be relative to the set alignment mode. For example, this -will shift the object by 10;20 px from the center of its parent: - -.. code-block:: c - - lv_obj_set_align(obj, LV_ALIGN_CENTER); - lv_obj_set_pos(obj, 10, 20); - - //Or in one function - lv_obj_align(obj, LV_ALIGN_CENTER, 10, 20); - -To align one object to another use: -:cpp:expr:`lv_obj_align_to(obj_to_align, obj_reference, LV_ALIGN_..., x, y)` - -For example, to align a text below an image: -:cpp:expr:`lv_obj_align_to(text, image, LV_ALIGN_OUT_BOTTOM_MID, 0, 10)`. - -The following align types exist: |image1| - -.. _lv_obj_parents_and_children: - -Parents and children --------------------- - -You can set a new parent for an object with -:cpp:expr:`lv_obj_set_parent(obj, new_parent)`. To get the current parent, use -:cpp:expr:`lv_obj_get_parent(obj)`. - -To get a specific child of a parent use :cpp:expr:`lv_obj_get_child(parent, idx)`. Some examples for ``idx``: - -- ``0`` get the child created first -- ``1`` get the child created second -- ``-1`` get the child created last - -The children can be iterated like this: - -.. code-block:: c - - uint32_t i; - for(i = 0; i < lv_obj_get_child_count(parent); i++) { - lv_obj_t * child = lv_obj_get_child(parent, i); - /*Do something with child*/ - } - -:cpp:expr:`lv_obj_get_index(obj)` returns the index of the object in its parent. -It is equivalent to the number of younger children in the parent. - -You can bring an object to the foreground or send it to the background -with :cpp:expr:`lv_obj_move_foreground(obj)` and -:cpp:expr:`lv_obj_move_background(obj)`. - -You can change the index of an object in its parent using -:cpp:expr:`lv_obj_move_to_index(obj, index)`. - -You can swap the position of two objects with -:cpp:expr:`lv_obj_swap(obj1, obj2)`. - -.. _lv_obj_display_and_screens: - -Display and Screens -------------------- - -At the highest level of the LVGL object hierarchy is the *display* which -represents the driver for a display device (physical display or -simulator). A display can have one or more screens associated with it. -Each screen contains a hierarchy of objects for graphical widgets -representing a layout that covers the entire display. - -When you have created a screen like -``lv_obj_t * screen = lv_obj_create(NULL)``, you can make it active with -:cpp:expr:`lv_screen_load(screen)`. The :cpp:func:`lv_screen_active` function gives you a -pointer to the active screen. - -If you have multiple displays, it's important to know that the screen -functions operate on the most recently created display or the one -explicitly selected with :cpp:func:`lv_display_set_default`. - -To get an object's screen use the :cpp:expr:`lv_obj_get_screen(obj)` function. - -.. _lv_obj_overview_events: - -Events ------- - -To set an event callback for an object, use -:cpp:expr:`lv_obj_add_event_cb(obj, event_cb, LV_EVENT_..., user_data)`, - -To manually send an event to an object, use -:cpp:expr:`lv_event_send(obj, LV_EVENT_..., param)` - -Read the :ref:`Event overview ` to learn more about -events. - -.. _lv_obj_styles: - -Styles ------- - -Be sure to read the :ref:`Style overview `. Here only the -most essential functions are described. - -A new style can be added to an object with the -:cpp:expr:`lv_obj_add_style(obj, &new_style, selector)` function. ``selector`` -is an ORed combination of part and state(s). E.g. -:cpp:expr:`LV_PART_SCROLLBAR | LV_STATE_PRESSED`. - -The base objects use :cpp:enumerator:`LV_PART_MAIN` style properties and -:cpp:enumerator:`LV_PART_SCROLLBAR` with the typical background style properties. - -.. _lv_obj_flags: - -Flags ------ - -There are some attributes which can be enabled/disabled by -``lv_obj_add/remove_flag(obj, LV_OBJ_FLAG_...)`` and ``lv_obj_set_flag(obj, LV_OBJ_FLAG_..., true/false)`` - -- :cpp:enumerator:`LV_OBJ_FLAG_HIDDEN` Make the object hidden. (Like it wasn't there at all) -- :cpp:enumerator:`LV_OBJ_FLAG_CLICKABLE` Make the object clickable by input devices -- :cpp:enumerator:`LV_OBJ_FLAG_CLICK_FOCUSABLE` Add focused state to the object when clicked -- :cpp:enumerator:`LV_OBJ_FLAG_CHECKABLE` Toggle checked state when the object is clicked -- :cpp:enumerator:`LV_OBJ_FLAG_SCROLLABLE` Make the object scrollable -- :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_ELASTIC` Allow scrolling inside but with slower speed -- :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_MOMENTUM` Make the object scroll further when "thrown" -- :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_ONE` Allow scrolling only one snappable children -- :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_CHAIN_HOR` Allow propagating the horizontal scroll to a parent -- :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_CHAIN_VER` Allow propagating the vertical scroll to a parent -- :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_CHAIN` Simple packaging for (:cpp:expr:`LV_OBJ_FLAG_SCROLL_CHAIN_HOR | LV_OBJ_FLAG_SCROLL_CHAIN_VER`) -- :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_ON_FOCUS` Automatically scroll object to make it visible when focused -- :cpp:enumerator:`LV_OBJ_FLAG_SCROLL_WITH_ARROW` Allow scrolling the focused object with arrow keys -- :cpp:enumerator:`LV_OBJ_FLAG_SNAPPABLE` If scroll snap is enabled on the parent it can snap to this object -- :cpp:enumerator:`LV_OBJ_FLAG_PRESS_LOCK` Keep the object pressed even if the press slid from the object -- :cpp:enumerator:`LV_OBJ_FLAG_EVENT_BUBBLE` Propagate the events to the parent too -- :cpp:enumerator:`LV_OBJ_FLAG_GESTURE_BUBBLE` Propagate the gestures to the parent -- :cpp:enumerator:`LV_OBJ_FLAG_ADV_HITTEST` Allow performing more accurate hit (click) test. E.g. accounting for rounded corners -- :cpp:enumerator:`LV_OBJ_FLAG_IGNORE_LAYOUT` Make the object not positioned by the layouts -- :cpp:enumerator:`LV_OBJ_FLAG_FLOATING` Do not scroll the object when the parent scrolls and ignore layout -- :cpp:enumerator:`LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS` Enable sending ``LV_EVENT_DRAW_TASK_ADDED`` events -- :cpp:enumerator:`LV_OBJ_FLAG_OVERFLOW_VISIBLE` Do not clip the children's content to the parent's boundary -- :cpp:enumerator:`LV_OBJ_FLAG_FLEX_IN_NEW_TRACK` Start a new flex track on this item -- :cpp:enumerator:`LV_OBJ_FLAG_LAYOUT_1` Custom flag, free to use by layouts -- :cpp:enumerator:`LV_OBJ_FLAG_LAYOUT_2` Custom flag, free to use by layouts -- :cpp:enumerator:`LV_OBJ_FLAG_WIDGET_1` Custom flag, free to use by widget -- :cpp:enumerator:`LV_OBJ_FLAG_WIDGET_2` Custom flag, free to use by widget -- :cpp:enumerator:`LV_OBJ_FLAG_USER_1` Custom flag, free to use by user -- :cpp:enumerator:`LV_OBJ_FLAG_USER_2` Custom flag, free to use by user -- :cpp:enumerator:`LV_OBJ_FLAG_USER_3` Custom flag, free to use by user -- :cpp:enumerator:`LV_OBJ_FLAG_USER_4` Custom flag, free to use by user - -Some examples: - -.. code-block:: c - - /*Hide on object*/ - lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN); - - /*Make an object non-clickable*/ - lv_obj_remove_flag(obj, LV_OBJ_FLAG_CLICKABLE); - -.. _lv_obj_groups: - -Groups ------- - -Read the :ref:`Input devices overview ` to learn more -about *Groups*. - -Objects are added to a *group* with :cpp:expr:`lv_group_add_obj(group, obj)`, -and you can use :cpp:expr:`lv_obj_get_group(obj)` to see which group an object -belongs to. - -:cpp:expr:`lv_obj_is_focused(obj)` returns if the object is currently focused on -its group or not. If the object is not added to a group, ``false`` will -be returned. - -.. _lv_obj_extended_click_area: - -Extended click area -------------------- - -By default, the objects can be clicked only within their bounding area. -However, this can be extended with -:cpp:expr:`lv_obj_set_ext_click_area(obj, size)`. - -.. _events-1: - -.. _lv_obj_events: - -Events -****** - -- :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` when the :cpp:enumerator:`LV_OBJ_FLAG_CHECKABLE` flag is - enabled and the object clicked (on transition to/from the checked state) - -Learn more about :ref:`events`. - -.. _lv_obj_keys: - -Keys -**** - -If :cpp:enumerator:`LV_OBJ_FLAG_CHECKABLE` is enabled, :cpp:enumerator:`LV_KEY_RIGHT` and -:cpp:enumerator:`LV_KEY_UP` make the object checked, and :cpp:enumerator:`LV_KEY_LEFT` and -:cpp:enumerator:`LV_KEY_DOWN` make it unchecked. - -If :cpp:enumerator:`LV_OBJ_FLAG_SCROLLABLE` is enabled, but the object is not editable -(as declared by the widget class), the arrow keys (:cpp:enumerator:`LV_KEY_UP`, -:cpp:enumerator:`LV_KEY_DOWN`, :cpp:enumerator:`LV_KEY_LEFT`, :cpp:enumerator:`LV_KEY_RIGHT`) scroll the object. -If the object can only scroll vertically, :cpp:enumerator:`LV_KEY_LEFT` and -:cpp:enumerator:`LV_KEY_RIGHT` will scroll up/down instead, making it compatible with -an encoder input device. See :ref:`Input devices overview ` for -more on encoder behaviors and the edit mode. - -Learn more about :ref:`indev_keys`. - -.. |image1| image:: /misc/align.png - -.. _lv_obj_example: - -Example -******* - -.. include:: ../examples/widgets/obj/index.rst - -.. _lv_obj_api: - -API -*** diff --git a/scripts/style_api_gen.py b/scripts/style_api_gen.py index 2db6fa931..c365a1a9e 100755 --- a/scripts/style_api_gen.py +++ b/scripts/style_api_gen.py @@ -5,10 +5,10 @@ import re import sys props = [ -{'section': 'Size and position', 'dsc':'Properties related to size, position, alignment and layout of the objects.' }, +{'section': 'Size and position', 'dsc':'Properties related to size, position, alignment and layout of Widgets.' }, {'name': 'WIDTH', 'style_type': 'num', 'var_type': 'int32_t' , 'default':'Widget dependent', 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Sets the width of object. Pixel, percentage and `LV_SIZE_CONTENT` values can be used. Percentage values are relative to the width of the parent's content area."}, + 'dsc': "Sets width of Widget. Pixel, percentage and `LV_SIZE_CONTENT` values can be used. Percentage values are relative to the width of the parent's content area."}, {'name': 'MIN_WIDTH', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0, @@ -20,7 +20,7 @@ props = [ {'name': 'HEIGHT', 'style_type': 'num', 'var_type': 'int32_t' , 'default':'Widget dependent', 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Sets the height of object. Pixel, percentage and `LV_SIZE_CONTENT` can be used. Percentage values are relative to the height of the parent's content area."}, + 'dsc': "Sets height of Widget. Pixel, percentage and `LV_SIZE_CONTENT` can be used. Percentage values are relative to the height of the parent's content area."}, {'name': 'MIN_HEIGHT', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0, @@ -32,67 +32,67 @@ props = [ {'name': 'LENGTH', 'style_type': 'num', 'var_type': 'int32_t' , 'default':'0', 'inherited': 0, 'layout': 0, 'ext_draw': 1, - 'dsc': "Its meaning depends on the type of the widget. For example in case of lv_scale it means the length of the ticks."}, + 'dsc': "Its meaning depends on the type of Widget. For example in case of lv_scale it means the length of the ticks."}, {'name': 'X', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Set the X coordinate of the object considering the set `align`. Pixel and percentage values can be used. Percentage values are relative to the width of the parent's content area."}, + 'dsc': "Set X coordinate of Widget considering the ``align`` setting. Pixel and percentage values can be used. Percentage values are relative to the width of the parent's content area."}, {'name': 'Y', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Set the Y coordinate of the object considering the set `align`. Pixel and percentage values can be used. Percentage values are relative to the height of the parent's content area."}, + 'dsc': "Set Y coordinate of Widget considering the ``align`` setting. Pixel and percentage values can be used. Percentage values are relative to the height of the parent's content area."}, {'name': 'ALIGN', 'style_type': 'num', 'var_type': 'lv_align_t', 'default':'`LV_ALIGN_DEFAULT`', 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Set the alignment which tells from which point of the parent the X and Y coordinates should be interpreted. The possible values are: `LV_ALIGN_DEFAULT`, `LV_ALIGN_TOP_LEFT/MID/RIGHT`, `LV_ALIGN_BOTTOM_LEFT/MID/RIGHT`, `LV_ALIGN_LEFT/RIGHT_MID`, `LV_ALIGN_CENTER`. `LV_ALIGN_DEFAULT` means `LV_ALIGN_TOP_LEFT` with LTR base direction and `LV_ALIGN_TOP_RIGHT` with RTL base direction."}, + 'dsc': "Set the alignment which tells from which point of the parent the X and Y coordinates should be interpreted. Possible values are: `LV_ALIGN_DEFAULT`, `LV_ALIGN_TOP_LEFT/MID/RIGHT`, `LV_ALIGN_BOTTOM_LEFT/MID/RIGHT`, `LV_ALIGN_LEFT/RIGHT_MID`, `LV_ALIGN_CENTER`. `LV_ALIGN_DEFAULT` means `LV_ALIGN_TOP_LEFT` with LTR base direction and `LV_ALIGN_TOP_RIGHT` with RTL base direction."}, {'name': 'TRANSFORM_WIDTH', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1, - 'dsc': "Make the object wider on both sides with this value. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to the object's width." }, + 'dsc': "Make Widget wider on both sides with this value. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to Widget's width." }, {'name': 'TRANSFORM_HEIGHT', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1, - 'dsc': "Make the object higher on both sides with this value. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to the object's height." }, + 'dsc': "Make Widget higher on both sides with this value. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to Widget's height." }, {'name': 'TRANSLATE_X', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Move the object with this value in X direction. Applied after layouts, aligns and other positioning. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to the object's width." }, + 'dsc': "Move Widget with this value in X direction. Applied after layouts, aligns and other positioning. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to Widget's width." }, {'name': 'TRANSLATE_Y', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Move the object with this value in Y direction. Applied after layouts, aligns and other positioning. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to the object's height." }, + 'dsc': "Move Widget with this value in Y direction. Applied after layouts, aligns and other positioning. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to Widget's height." }, {'name': 'TRANSLATE_RADIAL', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Move the object around the centre of the parent object (e.g. around the circumference of a scale)"}, + 'dsc': "Move object around the centre of the parent object (e.g. around the circumference of a scale)"}, {'name': 'TRANSFORM_SCALE_X', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 1, - 'dsc': "Zoom an objects horizontally. The value 256 (or `LV_SCALE_NONE`) means normal size, 128 half size, 512 double size, and so on" }, + 'dsc': "Zoom Widget horizontally. The value 256 (or `LV_SCALE_NONE`) means normal size, 128 half size, 512 double size, and so on" }, {'name': 'TRANSFORM_SCALE_Y', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 1, - 'dsc': "Zoom an objects vertically. The value 256 (or `LV_SCALE_NONE`) means normal size, 128 half size, 512 double size, and so on" }, + 'dsc': "Zoom Widget vertically. The value 256 (or `LV_SCALE_NONE`) means normal size, 128 half size, 512 double size, and so on" }, {'name': 'TRANSFORM_ROTATION', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 1, - 'dsc': "Rotate an objects. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg."}, + 'dsc': "Rotate Widget. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg."}, {'name': 'TRANSFORM_PIVOT_X', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the pivot point's X coordinate for transformations. Relative to the object's top left corner'"}, + 'dsc': "Set pivot point's X coordinate for transformations. Relative to Widget's top left corner'"}, {'name': 'TRANSFORM_PIVOT_Y', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the pivot point's Y coordinate for transformations. Relative to the object's top left corner'"}, + 'dsc': "Set pivot point's Y coordinate for transformations. Relative to Widget's top left corner'"}, {'name': 'TRANSFORM_SKEW_X', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 1, - 'dsc': "Skew an object horizontally. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg."}, + 'dsc': "Skew Widget horizontally. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg."}, {'name': 'TRANSFORM_SKEW_Y', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 1, - 'dsc': "Skew an object vertically. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg."}, + 'dsc': "Skew Widget vertically. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg."}, {'section': 'Padding', 'dsc' : "Properties to describe spacing between the parent's sides and the children and among the children. Very similar to the padding properties in HTML."}, {'name': 'PAD_TOP', @@ -121,61 +121,61 @@ props = [ {'name': 'PAD_RADIAL', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Pad the text labels away from the scale ticks/remainder of the LV_PART_"}, + 'dsc': "Pad text labels away from the scale ticks/remainder of the LV_PART_"}, -{'section': 'Margin', 'dsc' : "Properties to describe spacing around an object. Very similar to the margin properties in HTML."}, +{'section': 'Margin', 'dsc' : "Properties to describe spacing around a Widget. Very similar to the margin properties in HTML."}, {'name': 'MARGIN_TOP', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Sets the margin on the top. The object will keep this space from its siblings in layouts. "}, + 'dsc': "Sets margin on the top. Widget will keep this space from its siblings in layouts. "}, {'name': 'MARGIN_BOTTOM', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Sets the margin on the bottom. The object will keep this space from its siblings in layouts."}, + 'dsc': "Sets margin on the bottom. Widget will keep this space from its siblings in layouts."}, {'name': 'MARGIN_LEFT', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Sets the margin on the left. The object will keep this space from its siblings in layouts."}, + 'dsc': "Sets margin on the left. Widget will keep this space from its siblings in layouts."}, {'name': 'MARGIN_RIGHT', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Sets the margin on the right. The object will keep this space from its siblings in layouts."}, + 'dsc': "Sets margin on the right. Widget will keep this space from its siblings in layouts."}, -{'section': 'Background', 'dsc':'Properties to describe the background color and image of the objects.' }, +{'section': 'Background', 'dsc':'Properties to describe the background color and image of Widget.' }, {'name': 'BG_COLOR', 'style_type': 'color', 'var_type': 'lv_color_t', 'default':'`0xffffff`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1, - 'dsc': "Set the background color of the object."}, + 'dsc': "Set background color of Widget."}, {'name': 'BG_OPA', 'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_TRANSP`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the opacity of the background. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, + 'dsc': "Set opacity of the background. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, {'name': 'BG_GRAD_COLOR', 'style_type': 'color', 'var_type': 'lv_color_t', 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1, - 'dsc': "Set the gradient color of the background. Used only if `grad_dir` is not `LV_GRAD_DIR_NONE`"}, + 'dsc': "Set gradient color of the background. Used only if `grad_dir` is not `LV_GRAD_DIR_NONE`"}, {'name': 'BG_GRAD_DIR', 'style_type': 'num', 'var_type': 'lv_grad_dir_t', 'default':'`LV_GRAD_DIR_NONE`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the direction of the gradient of the background. The possible values are `LV_GRAD_DIR_NONE/HOR/VER`."}, + 'dsc': "Set direction of the gradient of the background. Possible values are `LV_GRAD_DIR_NONE/HOR/VER`."}, {'name': 'BG_MAIN_STOP', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the point from which the background color should start for gradients. 0 means to top/left side, 255 the bottom/right side, 128 the center, and so on"}, + 'dsc': "Set point from which background color should start for gradients. 0 means to top/left side, 255 the bottom/right side, 128 the center, and so on"}, {'name': 'BG_GRAD_STOP', 'style_type': 'num', 'var_type': 'int32_t', 'default':255, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the point from which the background's gradient color should start. 0 means to top/left side, 255 the bottom/right side, 128 the center, and so on"}, + 'dsc': "Set point from which background's gradient color should start. 0 means to top/left side, 255 the bottom/right side, 128 the center, and so on"}, {'name': 'BG_MAIN_OPA', 'style_type': 'num', 'var_type': 'lv_opa_t', 'default':255, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the opacity of the first gradient color"}, + 'dsc': "Set opacity of the first gradient color"}, {'name': 'BG_GRAD_OPA', 'style_type': 'num', 'var_type': 'lv_opa_t', 'default':255, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the opacity of the second gradient color"}, + 'dsc': "Set opacity of the second gradient color"}, {'name': 'BG_GRAD', 'style_type': 'ptr', 'var_type': 'const lv_grad_dsc_t *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the gradient definition. The pointed instance must exist while the object is alive. NULL to disable. It wraps `BG_GRAD_COLOR`, `BG_GRAD_DIR`, `BG_MAIN_STOP` and `BG_GRAD_STOP` into one descriptor and allows creating gradients with more colors too. If it's set other gradient related properties will be ignored'"}, + 'dsc': "Set gradient definition. The pointed instance must exist while Widget is alive. NULL to disable. It wraps `BG_GRAD_COLOR`, `BG_GRAD_DIR`, `BG_MAIN_STOP` and `BG_GRAD_STOP` into one descriptor and allows creating gradients with more colors as well. If it's set other gradient related properties will be ignored'"}, {'name': 'BG_IMAGE_SRC', 'style_type': 'ptr', 'var_type': 'const void *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 1, @@ -183,7 +183,7 @@ props = [ {'name': 'BG_IMAGE_OPA', 'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_COVER`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the opacity of the background image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, + 'dsc': "Set opacity of the background image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, {'name': 'BG_IMAGE_RECOLOR', 'style_type': 'color', 'var_type': 'lv_color_t', 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1, @@ -191,28 +191,28 @@ props = [ {'name': 'BG_IMAGE_RECOLOR_OPA', 'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_TRANSP`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the intensity of background image recoloring. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means no mixing, 255, `LV_OPA_100` or `LV_OPA_COVER` means full recoloring, other values or LV_OPA_10, LV_OPA_20, etc are interpreted proportionally."}, + 'dsc': "Set intensity of background image recoloring. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means no mixing, 255, `LV_OPA_100` or `LV_OPA_COVER` means full recoloring, other values or LV_OPA_10, LV_OPA_20, etc are interpreted proportionally."}, {'name': 'BG_IMAGE_TILED', 'style_type': 'num', 'var_type': 'bool', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "If enabled the background image will be tiled. The possible values are `true` or `false`."}, + 'dsc': "If enabled the background image will be tiled. Possible values are `true` or `false`."}, {'section': 'Border', 'dsc':'Properties to describe the borders' }, {'name': 'BORDER_COLOR', 'style_type': 'color', 'var_type': 'lv_color_t', 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1, - 'dsc': "Set the color of the border"}, + 'dsc': "Set color of the border"}, {'name': 'BORDER_OPA', 'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':'`LV_OPA_COVER`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the opacity of the border. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, + 'dsc': "Set opacity of the border. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, {'name': 'BORDER_WIDTH', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Set the width of the border. Only pixel values can be used."}, + 'dsc': "Set width of the border. Only pixel values can be used."}, {'name': 'BORDER_SIDE', 'style_type': 'num', 'var_type': 'lv_border_side_t', 'default':'`LV_BORDER_SIDE_NONE`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set only which side(s) the border should be drawn. The possible values are `LV_BORDER_SIDE_NONE/TOP/BOTTOM/LEFT/RIGHT/INTERNAL`. OR-ed values can be used as well, e.g. `LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_LEFT`."}, + 'dsc': "Set only which side(s) the border should be drawn. Possible values are `LV_BORDER_SIDE_NONE/TOP/BOTTOM/LEFT/RIGHT/INTERNAL`. OR-ed values can be used as well, e.g. `LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_LEFT`."}, {'name': 'BORDER_POST', 'style_type': 'num', 'var_type': 'bool' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, @@ -221,141 +221,141 @@ props = [ {'section': 'Outline', 'dsc':'Properties to describe the outline. It\'s like a border but drawn outside of the rectangles.' }, {'name': 'OUTLINE_WIDTH', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1, - 'dsc': "Set the width of the outline in pixels. "}, + 'dsc': "Set width of outline in pixels. "}, {'name': 'OUTLINE_COLOR', 'style_type': 'color', 'var_type': 'lv_color_t' , 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1, - 'dsc': "Set the color of the outline."}, + 'dsc': "Set color of outline."}, {'name': 'OUTLINE_OPA', 'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':'`LV_OPA_COVER`', 'inherited': 0, 'layout': 0, 'ext_draw': 1, - 'dsc': "Set the opacity of the outline. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, + 'dsc': "Set opacity of outline. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, {'name': 'OUTLINE_PAD', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1, - 'dsc': "Set the padding of the outline, i.e. the gap between object and the outline."}, + 'dsc': "Set padding of outline, i.e. the gap between Widget and the outline."}, {'section': 'Shadow', 'dsc':'Properties to describe the shadow drawn under the rectangles.' }, {'name': 'SHADOW_WIDTH', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1, - 'dsc': "Set the width of the shadow in pixels. The value should be >= 0."}, + 'dsc': "Set width of the shadow in pixels. The value should be >= 0."}, {'name': 'SHADOW_OFFSET_X', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1, - 'dsc': "Set an offset on the shadow in pixels in X direction. "}, + 'dsc': "Set an offset on the shadow in pixels in X direction."}, {'name': 'SHADOW_OFFSET_Y', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1, - 'dsc': "Set an offset on the shadow in pixels in Y direction. "}, + 'dsc': "Set an offset on the shadow in pixels in Y direction."}, {'name': 'SHADOW_SPREAD', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1, - 'dsc': "Make the shadow calculation to use a larger or smaller rectangle as base. The value can be in pixel to make the area larger/smaller"}, + 'dsc': "Make shadow calculation to use a larger or smaller rectangle as base. The value can be in pixels to make the area larger/smaller"}, {'name': 'SHADOW_COLOR', 'style_type': 'color', 'var_type': 'lv_color_t' , 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1, - 'dsc': "Set the color of the shadow"}, + 'dsc': "Set color of shadow"}, {'name': 'SHADOW_OPA', 'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':'`LV_OPA_COVER`', 'inherited': 0, 'layout': 0, 'ext_draw': 1, - 'dsc': "Set the opacity of the shadow. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, + 'dsc': "Set opacity of shadow. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, {'section': 'Image', 'dsc':'Properties to describe the images' }, {'name': 'IMAGE_OPA', 'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':'`LV_OPA_COVER`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the opacity of an image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, + 'dsc': "Set opacity of an image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, {'name': 'IMAGE_RECOLOR', 'style_type': 'color', 'var_type': 'lv_color_t', 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1, - 'dsc': "Set color to mixt to the image."}, + 'dsc': "Set color to mix with the image."}, {'name': 'IMAGE_RECOLOR_OPA', 'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the intensity of the color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, + 'dsc': "Set intensity of color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, -{'section': 'Line', 'dsc':'Properties to describe line-like objects' }, +{'section': 'Line', 'dsc':'Properties to describe line-like Widgets' }, {'name': 'LINE_WIDTH', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1, - 'dsc': "Set the width of the lines in pixel."}, + 'dsc': "Set width of lines in pixels."}, {'name': 'LINE_DASH_WIDTH', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the width of dashes in pixel. Note that dash works only on horizontal and vertical lines"}, + 'dsc': "Set width of dashes in pixels. Note that dash works only on horizontal and vertical lines"}, {'name': 'LINE_DASH_GAP', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the gap between dashes in pixel. Note that dash works only on horizontal and vertical lines"}, + 'dsc': "Set gap between dashes in pixels. Note that dash works only on horizontal and vertical lines"}, {'name': 'LINE_ROUNDED', 'style_type': 'num', 'var_type': 'bool' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Make the end points of the lines rounded. `true`: rounded, `false`: perpendicular line ending "}, + 'dsc': "Make end points of the lines rounded. `true`: rounded, `false`: perpendicular line ending "}, {'name': 'LINE_COLOR', 'style_type': 'color', 'var_type': 'lv_color_t' , 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1, - 'dsc': "Set the color of the lines."}, + 'dsc': "Set color of lines."}, {'name': 'LINE_OPA', 'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':'`LV_OPA_COVER`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the opacity of the lines."}, + 'dsc': "Set opacity of lines."}, {'section': 'Arc', 'dsc':'TODO' }, {'name': 'ARC_WIDTH', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1, - 'dsc': "Set the width (thickness) of the arcs in pixel."}, + 'dsc': "Set width (thickness) of arcs in pixels."}, {'name': 'ARC_ROUNDED', 'style_type': 'num', 'var_type': 'bool' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Make the end points of the arcs rounded. `true`: rounded, `false`: perpendicular line ending "}, + 'dsc': "Make end points of arcs rounded. `true`: rounded, `false`: perpendicular line ending "}, {'name': 'ARC_COLOR', 'style_type': 'color', 'var_type': 'lv_color_t', 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1, - 'dsc': "Set the color of the arc."}, + 'dsc': "Set color of arc."}, {'name': 'ARC_OPA', 'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':'`LV_OPA_COVER`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the opacity of the arcs."}, + 'dsc': "Set opacity of arcs."}, {'name': 'ARC_IMAGE_SRC', 'style_type': 'ptr', 'var_type': 'const void *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set an image from which the arc will be masked out. It's useful to display complex effects on the arcs. Can be a pointer to `lv_image_dsc_t` or a path to a file"}, + 'dsc': "Set an image from which arc will be masked out. It's useful to display complex effects on the arcs. Can be a pointer to `lv_image_dsc_t` or a path to a file"}, {'section': 'Text', 'dsc':'Properties to describe the properties of text. All these properties are inherited.' }, {'name': 'TEXT_COLOR', 'style_type': 'color', 'var_type': 'lv_color_t', 'default':'`0x000000`', 'inherited': 1, 'layout': 0, 'ext_draw': 0, 'filtered': 1, - 'dsc': "Sets the color of the text."}, + 'dsc': "Sets color of text."}, {'name': 'TEXT_OPA', 'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_COVER`', 'inherited': 1, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the opacity of the text. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, + 'dsc': "Set opacity of text. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, {'name': 'TEXT_FONT', 'style_type': 'ptr', 'var_type': 'const lv_font_t *', 'default':'`LV_FONT_DEFAULT`', 'inherited': 1, 'layout': 1, 'ext_draw': 0, - 'dsc': "Set the font of the text (a pointer `lv_font_t *`). "}, + 'dsc': "Set font of text (a pointer `lv_font_t *`). "}, {'name': 'TEXT_LETTER_SPACE', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 1, 'layout': 1, 'ext_draw': 0, - 'dsc': "Set the letter space in pixels"}, + 'dsc': "Set letter space in pixels"}, {'name': 'TEXT_LINE_SPACE', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 1, 'layout': 1, 'ext_draw': 0, - 'dsc': "Set the line space in pixels."}, + 'dsc': "Set line space in pixels."}, {'name': 'TEXT_DECOR', 'style_type': 'num', 'var_type': 'lv_text_decor_t' , 'default':'`LV_TEXT_DECOR_NONE`', 'inherited': 1, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set decoration for the text. The possible values are `LV_TEXT_DECOR_NONE/UNDERLINE/STRIKETHROUGH`. OR-ed values can be used as well." }, + 'dsc': "Set decoration for the text. Possible values are `LV_TEXT_DECOR_NONE/UNDERLINE/STRIKETHROUGH`. OR-ed values can be used as well." }, {'name': 'TEXT_ALIGN', 'style_type': 'num', 'var_type': 'lv_text_align_t' , 'default':'`LV_TEXT_ALIGN_AUTO`', 'inherited': 1, 'layout': 1, 'ext_draw': 0, - 'dsc': "Set how to align the lines of the text. Note that it doesn't align the object itself, only the lines inside the object. The possible values are `LV_TEXT_ALIGN_LEFT/CENTER/RIGHT/AUTO`. `LV_TEXT_ALIGN_AUTO` detect the text base direction and uses left or right alignment accordingly"}, + 'dsc': "Set how to align the lines of the text. Note that it doesn't align the Widget itself, only the lines inside the Widget. Possible values are `LV_TEXT_ALIGN_LEFT/CENTER/RIGHT/AUTO`. `LV_TEXT_ALIGN_AUTO` detect the text base direction and uses left or right alignment accordingly"}, {'section': 'Miscellaneous', 'dsc':'Mixed properties for various purposes.' }, {'name': 'RADIUS', 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set the radius on every corner. The value is interpreted in pixel (>= 0) or `LV_RADIUS_CIRCLE` for max. radius"}, + 'dsc': "Set radius on every corner. The value is interpreted in pixels (>= 0) or `LV_RADIUS_CIRCLE` for max. radius"}, {'name': 'RADIAL_OFFSET', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Move the start point of the object (e.g. scale tick) radially"}, + 'dsc': "Move start point of object (e.g. scale tick) radially"}, {'name': 'CLIP_CORNER', 'style_type': 'num', 'var_type': 'bool', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, @@ -363,15 +363,15 @@ props = [ {'name': 'OPA', 'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_COVER`', 'inherited': 1, 'layout': 0, 'ext_draw': 0, - 'dsc': "Scale down all opacity values of the object by this factor. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency." }, + 'dsc': "Scale down all opacity values of the Widget by this factor. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency." }, {'name': 'OPA_LAYERED', 'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_COVER`', 'inherited': 1, 'layout': 0, 'ext_draw': 0, - 'dsc': "First draw the object on the layer, then scale down layer opacity factor. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency." }, + 'dsc': "First draw Widget on the layer, then scale down layer opacity factor. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency." }, {'name': 'COLOR_FILTER_DSC', 'style_type': 'ptr', 'var_type': 'const lv_color_filter_dsc_t *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Mix a color to all colors of the object." }, + 'dsc': "Mix a color with all colors of the Widget." }, {'name': 'COLOR_FILTER_OPA', 'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':'`LV_OPA_TRANSP`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, @@ -379,35 +379,35 @@ props = [ {'name': 'ANIM', 'style_type': 'ptr', 'var_type': 'const lv_anim_t *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "The animation template for the object's animation. Should be a pointer to `lv_anim_t`. The animation parameters are widget specific, e.g. animation time could be the E.g. blink time of the cursor on the text area or scroll time of a roller. See the widgets' documentation to learn more."}, + 'dsc': "Animation template for Widget's animation. Should be a pointer to `lv_anim_t`. The animation parameters are widget specific, e.g. animation time could be the E.g. blink time of the cursor on the text area or scroll time of a roller. See Widgets' documentation to learn more."}, {'name': 'ANIM_DURATION', 'style_type': 'num', 'var_type': 'uint32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "The animation duration in milliseconds. Its meaning is widget specific. E.g. blink time of the cursor on the text area or scroll time of a roller. See the widgets' documentation to learn more."}, + 'dsc': "Animation duration in milliseconds. Its meaning is widget specific. E.g. blink time of the cursor on the text area or scroll time of a roller. See Widgets' documentation to learn more."}, {'name': 'TRANSITION', 'style_type': 'ptr', 'var_type': 'const lv_style_transition_dsc_t *' , 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "An initialized `lv_style_transition_dsc_t` to describe a transition."}, + 'dsc': "An initialized ``lv_style_transition_dsc_t`` to describe a transition."}, {'name': 'BLEND_MODE', 'style_type': 'num', 'var_type': 'lv_blend_mode_t' , 'default':'`LV_BLEND_MODE_NORMAL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Describes how to blend the colors to the background. The possible values are `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE/MULTIPLY`"}, + 'dsc': "Describes how to blend the colors to the background. Possible values are `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE/MULTIPLY`"}, {'name': 'LAYOUT', 'style_type': 'num', 'var_type': 'uint16_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Set the layout if the object. The children will be repositioned and resized according to the policies set for the layout. For the possible values see the documentation of the layouts."}, + 'dsc': "Set layout of Widget. Children will be repositioned and resized according to policies set for the layout. For possible values see documentation of the layouts."}, {'name': 'BASE_DIR', 'style_type': 'num', 'var_type': 'lv_base_dir_t', 'default':'`LV_BASE_DIR_AUTO`', 'inherited': 1, 'layout': 1, 'ext_draw': 0, - 'dsc': "Set the base direction of the object. The possible values are `LV_BIDI_DIR_LTR/RTL/AUTO`."}, + 'dsc': "Set base direction of Widget. Possible values are `LV_BIDI_DIR_LTR/RTL/AUTO`."}, {'name': 'BITMAP_MASK_SRC', 'style_type': 'ptr', 'var_type': 'const void *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "If set a layer will be created for the widget and the layer will be masked with this A8 bitmap mask."}, + 'dsc': "If set, a layer will be created for the widget and the layer will be masked with this A8 bitmap mask."}, {'name': 'ROTARY_SENSITIVITY', 'style_type': 'num', 'var_type': 'uint32_t', 'default':'`256`', 'inherited': 1, 'layout': 0, 'ext_draw': 0, - 'dsc': "Adjust the sensitivity for rotary encoders in 1/256 unit. It means, 128: slow down the rotary to half, 512: speeds up to double, 256: no change"}, + 'dsc': "Adjust sensitivity for rotary encoders in 1/256 unit. It means, 128: slow down the rotary to half, 512: speeds up to double, 256: no change"}, {'section': 'Flex', 'dsc':'Flex layout properties.', 'guard':'LV_USE_FLEX'}, @@ -433,7 +433,7 @@ props = [ {'name': 'FLEX_GROW', 'style_type': 'num', 'var_type': 'uint8_t', 'default':'`LV_FLEX_ALIGN_ROW`', 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Defines how much space to take proportionally from the free space of the object's track"}, + 'dsc': "Defines how much space to take proportionally from the free space of the Widget's track"}, @@ -459,27 +459,27 @@ props = [ {'name': 'GRID_CELL_COLUMN_POS', 'style_type': 'num', 'var_type': 'int32_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Set the column in which the object should be placed"}, + 'dsc': "Set column in which Widget should be placed."}, {'name': 'GRID_CELL_X_ALIGN', 'style_type': 'num', 'var_type': 'lv_grid_align_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Set how to align the object horizontally."}, + 'dsc': "Set how to align Widget horizontally."}, {'name': 'GRID_CELL_COLUMN_SPAN', 'style_type': 'num', 'var_type': 'int32_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Set how many columns the object should span. Needs to be >= 1"}, + 'dsc': "Set how many columns Widget should span. Needs to be >= 1."}, {'name': 'GRID_CELL_ROW_POS', 'style_type': 'num', 'var_type': 'int32_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Set the row in which the object should be placed"}, + 'dsc': "Set row in which Widget should be placed."}, {'name': 'GRID_CELL_Y_ALIGN', 'style_type': 'num', 'var_type': 'lv_grid_align_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Set how to align the object vertically."}, + 'dsc': "Set how to align Widget vertically."}, {'name': 'GRID_CELL_ROW_SPAN', 'style_type': 'num', 'var_type': 'int32_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0, - 'dsc': "Set how many rows the object should span. Needs to be >= 1"}, + 'dsc': "Set how many rows Widget should span. Needs to be >= 1."}, ] @@ -727,10 +727,12 @@ print('''\ ''') print('#endif /* LV_STYLE_GEN_H */') -sys.stdout = open(base_dir + '/../docs/overview/style-props.rst', 'w') +sys.stdout = open(base_dir + '/../docs/details/base-widget/styles/style-properties.rst', 'w') +print('.. _style_properties:') +print() print('================') -print('Style properties') +print('Style Properties') print('================') for p in props: diff --git a/src/core/lv_group.h b/src/core/lv_group.h index e5f267d00..f092848e3 100644 --- a/src/core/lv_group.h +++ b/src/core/lv_group.h @@ -21,7 +21,7 @@ extern "C" { /********************* * DEFINES *********************/ -/** Predefined keys to control focused object via lv_group_send(group, c) */ +/** Predefined keys to control which Widget has focus via lv_group_send(group, c) */ typedef enum { LV_KEY_UP = 17, /*0x11*/ LV_KEY_DOWN = 18, /*0x12*/ @@ -54,90 +54,91 @@ typedef enum { **********************/ /** - * Create a new object group - * @return pointer to the new object group + * Create new Widget group. + * @return pointer to the new Widget group */ lv_group_t * lv_group_create(void); /** - * Delete a group object + * Delete group object. * @param group pointer to a group */ void lv_group_delete(lv_group_t * group); /** - * Set a default group. New object are added to this group if it's enabled in their class with `add_to_def_group = true` + * Set default group. New Widgets will be added to this group if it's enabled in + * their class with `add_to_def_group = true`. * @param group pointer to a group (can be `NULL`) */ void lv_group_set_default(lv_group_t * group); /** - * Get the default group + * Get default group. * @return pointer to the default group */ lv_group_t * lv_group_get_default(void); /** - * Add an object to a group + * Add an Widget to group. * @param group pointer to a group - * @param obj pointer to an object to add + * @param obj pointer to a Widget to add */ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj); /** - * Swap 2 object in a group. The object must be in the same group - * @param obj1 pointer to an object - * @param obj2 pointer to another object + * Swap 2 Widgets in group. Widgets must be in the same group. + * @param obj1 pointer to a Widget + * @param obj2 pointer to another Widget */ void lv_group_swap_obj(lv_obj_t * obj1, lv_obj_t * obj2); /** - * Remove an object from its group - * @param obj pointer to an object to remove + * Remove a Widget from its group. + * @param obj pointer to Widget to remove */ void lv_group_remove_obj(lv_obj_t * obj); /** - * Remove all objects from a group + * Remove all Widgets from a group. * @param group pointer to a group */ void lv_group_remove_all_objs(lv_group_t * group); /** - * Focus on an object (defocus the current) - * @param obj pointer to an object to focus on + * Focus on a Widget (defocus the current). + * @param obj pointer to Widget to focus on */ void lv_group_focus_obj(lv_obj_t * obj); /** - * Focus the next object in a group (defocus the current) + * Focus on next Widget in a group (defocus the current). * @param group pointer to a group */ void lv_group_focus_next(lv_group_t * group); /** - * Focus the previous object in a group (defocus the current) + * Focus on previous Widget in a group (defocus the current). * @param group pointer to a group */ void lv_group_focus_prev(lv_group_t * group); /** - * Do not let to change the focus from the current object + * Do not allow changing focus from current Widget. * @param group pointer to a group * @param en true: freeze, false: release freezing (normal mode) */ void lv_group_focus_freeze(lv_group_t * group, bool en); /** - * Send a control character to the focuses object of a group + * Send a control character to Widget that has focus in a group. * @param group pointer to a group * @param c a character (use LV_KEY_.. to navigate) - * @return result of focused object in group. + * @return result of Widget with focus in group. */ lv_result_t lv_group_send_data(lv_group_t * group, uint32_t c); /** - * Set a function for a group which will be called when a new object is focused + * Set a function for a group which will be called when a new Widget has focus. * @param group pointer to a group * @param focus_cb the call back function or NULL if unused */ @@ -151,8 +152,8 @@ void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb); void lv_group_set_edge_cb(lv_group_t * group, lv_group_edge_cb_t edge_cb); /** - * Set whether the next or previous item in a group is focused if the currently focused obj is - * deleted. + * Set whether the next or previous Widget in a group gets focus when Widget that has + * focus is deleted. * @param group pointer to a group * @param policy new refocus policy enum */ @@ -166,69 +167,71 @@ void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t p void lv_group_set_editing(lv_group_t * group, bool edit); /** - * Set whether focus next/prev will allow wrapping from first->last or last->first object. + * Set whether moving focus to next/previous Widget will allow wrapping from + * first->last or last->first Widget. * @param group pointer to group * @param en true: wrapping enabled; false: wrapping disabled */ void lv_group_set_wrap(lv_group_t * group, bool en); /** - * Get the focused object or NULL if there isn't one + * Get Widget that has focus, or NULL if there isn't one. * @param group pointer to a group - * @return pointer to the focused object + * @return pointer to Widget with focus */ lv_obj_t * lv_group_get_focused(const lv_group_t * group); /** - * Get the focus callback function of a group + * Get focus callback function of a group. * @param group pointer to a group * @return the call back function or NULL if not set */ lv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t * group); /** - * Get the edge callback function of a group + * Get edge callback function of a group. * @param group pointer to a group * @return the call back function or NULL if not set */ lv_group_edge_cb_t lv_group_get_edge_cb(const lv_group_t * group); /** - * Get the current mode (edit or navigate). + * Get current mode (edit or navigate). * @param group pointer to group * @return true: edit mode; false: navigate mode */ bool lv_group_get_editing(const lv_group_t * group); /** - * Get whether focus next/prev will allow wrapping from first->last or last->first object. + * Get whether moving focus to next/previous Widget will allow wrapping from + * first->last or last->first Widget. * @param group pointer to group */ bool lv_group_get_wrap(lv_group_t * group); /** - * Get the number of object in the group + * Get number of Widgets in group. * @param group pointer to a group - * @return number of objects in the group + * @return number of Widgets in the group */ uint32_t lv_group_get_obj_count(lv_group_t * group); /** - * Get the nth object within a group + * Get nth Widget within group. * @param group pointer to a group - * @param index index of object within the group - * @return pointer to the object + * @param index index of Widget within the group + * @return pointer to Widget */ lv_obj_t * lv_group_get_obj_by_index(lv_group_t * group, uint32_t index); /** - * Get the number of groups + * Get the number of groups. * @return number of groups */ uint32_t lv_group_get_count(void); /** - * Get a group by its index + * Get a group by its index. * @param index index of the group * @return pointer to the group */ diff --git a/src/misc/lv_event.h b/src/misc/lv_event.h index 89aee8abd..0cd32cf92 100644 --- a/src/misc/lv_event.h +++ b/src/misc/lv_event.h @@ -29,72 +29,72 @@ extern "C" { typedef void (*lv_event_cb_t)(lv_event_t * e); /** - * Type of event being sent to the object. + * Type of event being sent to Widget */ typedef enum { LV_EVENT_ALL = 0, /** Input device events*/ - LV_EVENT_PRESSED, /**< The object has been pressed*/ - LV_EVENT_PRESSING, /**< The object is being pressed (called continuously while pressing)*/ - LV_EVENT_PRESS_LOST, /**< The object is still being pressed but slid cursor/finger off of the object */ - LV_EVENT_SHORT_CLICKED, /**< The object was pressed for a short period of time, then released it. Not called if scrolled.*/ - LV_EVENT_SINGLE_CLICKED, /**< Called for the first short click within a small distance and short time*/ - LV_EVENT_DOUBLE_CLICKED, /**< Called for the second short click within small distance and short time*/ - LV_EVENT_TRIPLE_CLICKED, /**< Called for the third short click within small distance and short time*/ - LV_EVENT_LONG_PRESSED, /**< Object has been pressed for at least `long_press_time`. Not called if scrolled.*/ - LV_EVENT_LONG_PRESSED_REPEAT, /**< Called after `long_press_time` in every `long_press_repeat_time` ms. Not called if scrolled.*/ - LV_EVENT_CLICKED, /**< Called on release if not scrolled (regardless to long press)*/ - LV_EVENT_RELEASED, /**< Called in every cases when the object has been released*/ - LV_EVENT_SCROLL_BEGIN, /**< Scrolling begins. The event parameter is a pointer to the animation of the scroll. Can be modified*/ + LV_EVENT_PRESSED, /**< Widget has been pressed */ + LV_EVENT_PRESSING, /**< Widget is being pressed (sent continuously while pressing)*/ + LV_EVENT_PRESS_LOST, /**< Widget is still being pressed but slid cursor/finger off Widget */ + LV_EVENT_SHORT_CLICKED, /**< Widget was pressed for a short period of time, then released. Not sent if scrolled. */ + LV_EVENT_SINGLE_CLICKED, /**< Sent for first short click within a small distance and short time */ + LV_EVENT_DOUBLE_CLICKED, /**< Sent for second short click within small distance and short time */ + LV_EVENT_TRIPLE_CLICKED, /**< Sent for third short click within small distance and short time */ + LV_EVENT_LONG_PRESSED, /**< Object has been pressed for at least `long_press_time`. Not sent if scrolled. */ + LV_EVENT_LONG_PRESSED_REPEAT, /**< Sent after `long_press_time` in every `long_press_repeat_time` ms. Not sent if scrolled. */ + LV_EVENT_CLICKED, /**< Sent on release if not scrolled (regardless to long press)*/ + LV_EVENT_RELEASED, /**< Sent in every cases when Widget has been released */ + LV_EVENT_SCROLL_BEGIN, /**< Scrolling begins. The event parameter is a pointer to the animation of the scroll. Can be modified */ LV_EVENT_SCROLL_THROW_BEGIN, - LV_EVENT_SCROLL_END, /**< Scrolling ends*/ - LV_EVENT_SCROLL, /**< Scrolling*/ - LV_EVENT_GESTURE, /**< A gesture is detected. Get the gesture with `lv_indev_get_gesture_dir(lv_indev_active());` */ - LV_EVENT_KEY, /**< A key is sent to the object. Get the key with `lv_indev_get_key(lv_indev_active());`*/ - LV_EVENT_ROTARY, /**< An encoder or wheel was rotated. Get the rotation count with `lv_event_get_rotary_diff(e);`*/ - LV_EVENT_FOCUSED, /**< The object is focused*/ - LV_EVENT_DEFOCUSED, /**< The object is defocused*/ - LV_EVENT_LEAVE, /**< The object is defocused but still selected*/ - LV_EVENT_HIT_TEST, /**< Perform advanced hit-testing*/ - LV_EVENT_INDEV_RESET, /**< Indev has been reset*/ - LV_EVENT_HOVER_OVER, /**< Indev hover over object*/ - LV_EVENT_HOVER_LEAVE, /**< Indev hover leave object*/ + LV_EVENT_SCROLL_END, /**< Scrolling ends */ + LV_EVENT_SCROLL, /**< Scrolling */ + LV_EVENT_GESTURE, /**< A gesture is detected. Get gesture with `lv_indev_get_gesture_dir(lv_indev_active());` */ + LV_EVENT_KEY, /**< A key is sent to Widget. Get key with `lv_indev_get_key(lv_indev_active());`*/ + LV_EVENT_ROTARY, /**< An encoder or wheel was rotated. Get rotation count with `lv_event_get_rotary_diff(e);`*/ + LV_EVENT_FOCUSED, /**< Widget received focus */ + LV_EVENT_DEFOCUSED, /**< Widget's focus has been lost */ + LV_EVENT_LEAVE, /**< Widget's focus has been lost but is still selected */ + LV_EVENT_HIT_TEST, /**< Perform advanced hit-testing */ + LV_EVENT_INDEV_RESET, /**< Indev has been reset */ + LV_EVENT_HOVER_OVER, /**< Indev hover over object */ + LV_EVENT_HOVER_LEAVE, /**< Indev hover leave object */ - /** Drawing events*/ - LV_EVENT_COVER_CHECK, /**< Check if the object fully covers an area. The event parameter is `lv_cover_check_info_t *`.*/ - LV_EVENT_REFR_EXT_DRAW_SIZE, /**< Get the required extra draw area around the object (e.g. for shadow). The event parameter is `int32_t *` to store the size.*/ - LV_EVENT_DRAW_MAIN_BEGIN, /**< Starting the main drawing phase*/ - LV_EVENT_DRAW_MAIN, /**< Perform the main drawing*/ - LV_EVENT_DRAW_MAIN_END, /**< Finishing the main drawing phase*/ - LV_EVENT_DRAW_POST_BEGIN, /**< Starting the post draw phase (when all children are drawn)*/ - LV_EVENT_DRAW_POST, /**< Perform the post draw phase (when all children are drawn)*/ - LV_EVENT_DRAW_POST_END, /**< Finishing the post draw phase (when all children are drawn)*/ - LV_EVENT_DRAW_TASK_ADDED, /**< Adding a draw task */ + /** Drawing events */ + LV_EVENT_COVER_CHECK, /**< Check if Widget fully covers an area. The event parameter is `lv_cover_check_info_t *`. */ + LV_EVENT_REFR_EXT_DRAW_SIZE, /**< Get required extra draw area around Widget (e.g. for shadow). The event parameter is `int32_t *` to store the size. */ + LV_EVENT_DRAW_MAIN_BEGIN, /**< Starting the main drawing phase */ + LV_EVENT_DRAW_MAIN, /**< Perform the main drawing */ + LV_EVENT_DRAW_MAIN_END, /**< Finishing the main drawing phase */ + LV_EVENT_DRAW_POST_BEGIN, /**< Starting the post draw phase (when all children are drawn)*/ + LV_EVENT_DRAW_POST, /**< Perform the post draw phase (when all children are drawn)*/ + LV_EVENT_DRAW_POST_END, /**< Finishing the post draw phase (when all children are drawn)*/ + LV_EVENT_DRAW_TASK_ADDED, /**< Adding a draw task */ - /** Special events*/ - LV_EVENT_VALUE_CHANGED, /**< The object's value has changed (i.e. slider moved)*/ - LV_EVENT_INSERT, /**< A text is inserted to the object. The event data is `char *` being inserted.*/ - LV_EVENT_REFRESH, /**< Notify the object to refresh something on it (for the user)*/ - LV_EVENT_READY, /**< A process has finished*/ + /** Special events */ + LV_EVENT_VALUE_CHANGED, /**< Widget's value has changed (i.e. slider moved)*/ + LV_EVENT_INSERT, /**< Text has been inserted into Widget. The event data is `char *` being inserted. */ + LV_EVENT_REFRESH, /**< Notify Widget to refresh something on it (for user)*/ + LV_EVENT_READY, /**< A process has finished */ LV_EVENT_CANCEL, /**< A process has been cancelled */ - /** Other events*/ - LV_EVENT_CREATE, /**< Object is being created*/ - LV_EVENT_DELETE, /**< Object is being deleted*/ + /** Other events */ + LV_EVENT_CREATE, /**< Object is being created */ + LV_EVENT_DELETE, /**< Object is being deleted */ LV_EVENT_CHILD_CHANGED, /**< Child was removed, added, or its size, position were changed */ - LV_EVENT_CHILD_CREATED, /**< Child was created, always bubbles up to all parents*/ - LV_EVENT_CHILD_DELETED, /**< Child was deleted, always bubbles up to all parents*/ - LV_EVENT_SCREEN_UNLOAD_START, /**< A screen unload started, fired immediately when scr_load is called*/ - LV_EVENT_SCREEN_LOAD_START, /**< A screen load started, fired when the screen change delay is expired*/ - LV_EVENT_SCREEN_LOADED, /**< A screen was loaded*/ - LV_EVENT_SCREEN_UNLOADED, /**< A screen was unloaded*/ - LV_EVENT_SIZE_CHANGED, /**< Object coordinates/size have changed*/ - LV_EVENT_STYLE_CHANGED, /**< Object's style has changed*/ - LV_EVENT_LAYOUT_CHANGED, /**< The children position has changed due to a layout recalculation*/ - LV_EVENT_GET_SELF_SIZE, /**< Get the internal size of a widget*/ + LV_EVENT_CHILD_CREATED, /**< Child was created, always bubbles up to all parents */ + LV_EVENT_CHILD_DELETED, /**< Child was deleted, always bubbles up to all parents */ + LV_EVENT_SCREEN_UNLOAD_START, /**< A screen unload started, fired immediately when scr_load is called */ + LV_EVENT_SCREEN_LOAD_START, /**< A screen load started, fired when the screen change delay is expired */ + LV_EVENT_SCREEN_LOADED, /**< A screen was loaded */ + LV_EVENT_SCREEN_UNLOADED, /**< A screen was unloaded */ + LV_EVENT_SIZE_CHANGED, /**< Object coordinates/size have changed */ + LV_EVENT_STYLE_CHANGED, /**< Object's style has changed */ + LV_EVENT_LAYOUT_CHANGED, /**< A child's position position has changed due to a layout recalculation */ + LV_EVENT_GET_SELF_SIZE, /**< Get internal size of a widget */ - /** Events of optional LVGL components*/ + /** Events of optional LVGL components */ LV_EVENT_INVALIDATE_AREA, LV_EVENT_RESOLUTION_CHANGED, LV_EVENT_COLOR_FORMAT_CHANGED, @@ -110,7 +110,7 @@ typedef enum { LV_EVENT_VSYNC, - LV_EVENT_LAST, /** Number of default events*/ + LV_EVENT_LAST, /** Number of default events */ LV_EVENT_PREPROCESS = 0x8000, /** This is a flag that can be set with an event so it's processed before the class default event processing */ @@ -126,7 +126,7 @@ typedef struct { /** * @brief Event callback. - * Events are used to notify the user of some action being taken on the object. + * Events are used to notify the user of some action being taken on Widget. * For details, see ::lv_event_t. */ @@ -148,14 +148,14 @@ bool lv_event_remove(lv_event_list_t * list, uint32_t index); void lv_event_remove_all(lv_event_list_t * list); /** - * Get the object originally targeted by the event. It's the same even if the event is bubbled. + * Get Widget originally targeted by the event. It's the same even if event was bubbled. * @param e pointer to the event descriptor * @return the target of the event_code */ void * lv_event_get_target(lv_event_t * e); /** - * Get the current target of the event. It's the object which event handler being called. + * Get current target of the event. It's the Widget for which the event handler being called. * If the event is not bubbled it's the same as "normal" target. * @param e pointer to the event descriptor * @return pointer to the current target of the event_code @@ -163,28 +163,28 @@ void * lv_event_get_target(lv_event_t * e); void * lv_event_get_current_target(lv_event_t * e); /** - * Get the event code of an event + * Get event code of an event. * @param e pointer to the event descriptor * @return the event code. (E.g. `LV_EVENT_CLICKED`, `LV_EVENT_FOCUSED`, etc) */ lv_event_code_t lv_event_get_code(lv_event_t * e); /** - * Get the parameter passed when the event was sent + * Get parameter passed when event was sent. * @param e pointer to the event descriptor * @return pointer to the parameter */ void * lv_event_get_param(lv_event_t * e); /** - * Get the user_data passed when the event was registered on the object + * Get user_data passed when event was registered on Widget. * @param e pointer to the event descriptor * @return pointer to the user_data */ void * lv_event_get_user_data(lv_event_t * e); /** - * Stop the event from bubbling. + * Stop event from bubbling. * This is only valid when called in the middle of an event processing chain. * @param e pointer to the event descriptor */ @@ -221,4 +221,4 @@ uint32_t lv_event_register_id(void); } /*extern "C"*/ #endif -#endif /*LV_EVENT_H*/ +#endif /* LV_EVENT_H */ diff --git a/src/widgets/label/lv_label.h b/src/widgets/label/lv_label.h index d9fddd817..371ec0948 100644 --- a/src/widgets/label/lv_label.h +++ b/src/widgets/label/lv_label.h @@ -133,7 +133,7 @@ void lv_label_set_text_selection_end(lv_obj_t * obj, uint32_t index); * Enable the recoloring by in-line commands * @param obj pointer to a label object * @param en true: enable recoloring, false: disable - * @example "This is a #ff0000 red# word" + * Example: "This is a #ff0000 red# word" */ void lv_label_set_recolor(lv_obj_t * obj, bool en);