1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

feat(docs): batch 12 of proofread/edited docs (#7440)

This commit is contained in:
Victor Wheeler 2025-01-10 07:06:42 -07:00 committed by GitHub
parent 5563787cac
commit ad66f13f96
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 568 additions and 224 deletions

View File

@ -1200,7 +1200,7 @@ menu "LVGL configuration"
endmenu endmenu
menu "3rd Party Libraries" menu "3rd Party Libraries"
config LV_FS_DEFAULT_DRIVE_LETTER config LV_FS_DEFAULT_DRIVER_LETTER
int "Default drive letter (e.g. 65 for 'A')" int "Default drive letter (e.g. 65 for 'A')"
default 0 default 0
help help

View File

@ -10,7 +10,7 @@
#include "lv_demo_high_res_private.h" #include "lv_demo_high_res_private.h"
#if LV_USE_DEMO_HIGH_RES #if LV_USE_DEMO_HIGH_RES
#if LV_FS_DEFAULT_DRIVE_LETTER == '\0' #if LV_FS_DEFAULT_DRIVER_LETTER == '\0'
#error set a default drive letter (and enable an FS driver) for the high res demo #error set a default drive letter (and enable an FS driver) for the high res demo
#endif #endif

View File

@ -85,7 +85,7 @@ typedef void (*lv_demo_high_res_exit_cb_t)(lv_demo_high_res_api_t * api);
* Start the High Resolution Demo on the default display, on the active screen. * Start the High Resolution Demo on the default display, on the active screen.
* This demo requires `LV_USE_DEMO_HIGH_RES` and `LV_FONT_FMT_TXT_LARGE` * This demo requires `LV_USE_DEMO_HIGH_RES` and `LV_FONT_FMT_TXT_LARGE`
* to be enabled as well as a filesystem driver to be configured and the * to be enabled as well as a filesystem driver to be configured and the
* `LV_FS_DEFAULT_DRIVE_LETTER` set. The display size should be * `LV_FS_DEFAULT_DRIVER_LETTER` set. The display size should be
* 800x480, 1280x720, or 1920x1080. * 800x480, 1280x720, or 1920x1080.
* @param assets_path Folder where the image assets are. * @param assets_path Folder where the image assets are.
* If `NULL`, "lvgl/demos/high_res/assets" will be used. * If `NULL`, "lvgl/demos/high_res/assets" will be used.
@ -112,7 +112,7 @@ lv_demo_high_res_api_t * lv_demo_high_res(const char * assets_path,
* Start the High Resolution Demo on the default display, on the active screen. * Start the High Resolution Demo on the default display, on the active screen.
* This demo requires `LV_USE_DEMO_HIGH_RES` and `LV_FONT_FMT_TXT_LARGE` * This demo requires `LV_USE_DEMO_HIGH_RES` and `LV_FONT_FMT_TXT_LARGE`
* to be enabled as well as a filesystem driver to be configured and the * to be enabled as well as a filesystem driver to be configured and the
* `LV_FS_DEFAULT_DRIVE_LETTER` set. The display size should be * `LV_FS_DEFAULT_DRIVER_LETTER` set. The display size should be
* 800x480, 1280x720, or 1920x1080. * 800x480, 1280x720, or 1920x1080.
* @param assets_path Folder where the image assets are. * @param assets_path Folder where the image assets are.
* If `NULL`, "lvgl/demos/high_res/assets" will be used. * If `NULL`, "lvgl/demos/high_res/assets" will be used.

View File

@ -195,4 +195,4 @@ The process is described in details below, using ``SPIFFS`` as demonstration.
CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_LV_USE_FS_STDIO=y CONFIG_LV_USE_FS_STDIO=y
CONFIG_LV_FS_STDIO_LETTER=65 CONFIG_LV_FS_STDIO_LETTER=65
CONFIG_LV_LV_FS_DEFAULT_DRIVE_LETTER=65 CONFIG_LV_FS_DEFAULT_DRIVER_LETTER=65

View File

@ -33,10 +33,10 @@ files using that driver letter. E.g. ``"S:path/to/file.txt"``.
Working with common prefixes Working with common prefixes
"""""""""""""""""""""""""""" """"""""""""""""""""""""""""
A **default driver letter** can be set by ``LV_FS_DEFAULT_DRIVE_LETTER``, A **default driver letter** can be set by ``LV_FS_DEFAULT_DRIVER_LETTER``,
which allows skipping the drive prefix in file paths. 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_DRIVER_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. 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.

View File

@ -1,3 +1,11 @@
.. |check| unicode:: U+02713 .. CHECK MARK
.. |Aacute| unicode:: U+000C1 .. LATIN CAPITAL LETTER A WITH ACUTE
.. |eacute| unicode:: U+000E9 .. LATIN SMALL LETTER E WITH ACUTE
.. |otilde| unicode:: U+000F5 .. LATIN SMALL LETTER O WITH TILDE
.. |Utilde| unicode:: U+00168 .. LATIN CAPITAL LETTER U WITH TILDE
.. |uuml| unicode:: U+000FC .. LATIN SMALL LETTER U WITH DIAERESIS
.. |uml| unicode:: U+000A8 .. DIAERESIS
.. _font: .. _font:
============== ==============
@ -11,29 +19,37 @@ For example:
.. code-block:: c .. 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. Fonts have a **format** property. It describes how the glyph data is stored.
It has *2* categories: `Legacy simple format` and `Advanced format`. At this writing there are 12 possible values that this field can take, and those
In the most simple case, the font is stored in a simple array of bitmaps. values fall into 2 categories:
In the advanced format, the font can be stored in a different way like `Vector`, `SVG`, etc.
In case of the simple format, the value stored for a pixel determines the pixel's opacity. :Legacy simple: 1, 2, 4 or 8-bpp (aligned or unaligned) and image format, and
This way, with higher *bpp (bit per pixel)*, the edges of the letter can be smoother. :Advanced: vector, SVG, and custom formats; for the latter, the user provides
The possible *bpp* values are 1, 2, 4 and 8 (higher values mean better quality). the rendering logic.
The *format* property also affects the amount of memory needed to store a For simple formats:
font. For example, *format = LV_FONT_GLYPH_FORMAT_A4* makes a font nearly four times larger
compared to *format = LV_FONT_GLYPH_FORMAT_A1*. - the font is stored as an array of bitmaps, one bitmap per glyph;
- the value stored for each pixel determines the pixel's opacity, enabling edges
to be smoother --- higher bpp values result in smoother edges.
For advanced formats, the font information is stored in its respective format.
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
Unicode Support
*************** ***************
LVGL supports **UTF-8** encoded Unicode characters. Your editor needs to LVGL supports **UTF-8** encoded Unicode characters. Your editor needs to
be configured to save your code/text as UTF-8 (usually this the default) be configured to save your code/text as UTF-8 (usually this the default)
and be sure that, :c:macro:`LV_TXT_ENC` is set to :c:macro:`LV_TXT_ENC_UTF8` in and be sure that :c:macro:`LV_TXT_ENC` is set to :c:macro:`LV_TXT_ENC_UTF8` in
*lv_conf.h*. (This is the default value) ``lv_conf.h``. (This is the default value.)
To test it try To test it try
@ -42,7 +58,7 @@ To test it try
lv_obj_t * label1 = lv_label_create(lv_screen_active(), NULL); lv_obj_t * label1 = lv_label_create(lv_screen_active(), NULL);
lv_label_set_text(label1, LV_SYMBOL_OK); lv_label_set_text(label1, LV_SYMBOL_OK);
If all works well, a character should be displayed. If all works well, a '\ |check|\ ' character should be displayed.
Typesetting Typesetting
@ -61,32 +77,26 @@ Languages like Arabic, Persian, and Hebrew, which use Right-to-Left
(RTL) or mixed writing directions, are also supported in LVGL. (RTL) or mixed writing directions, are also supported in LVGL.
Learn more :ref:`here <bidi>`. Learn more :ref:`here <bidi>`.
For characters such as '|eacute|', '|uuml|', '|otilde|', '|Aacute|', and '|Utilde|',
.. |Aacute| unicode:: U+000C1 .. LATIN CAPITAL LETTER A WITH ACUTE it is recommended to use the single Unicode format (NFC) rather than decomposing them
.. |eacute| unicode:: U+000E9 .. LATIN SMALL LETTER E WITH ACUTE into a base letter and diacritics (e.g. ``u`` + |uml|).
.. |otilde| unicode:: U+000F5 .. LATIN SMALL LETTER O WITH TILDE
.. |Utilde| unicode:: U+00168 .. LATIN CAPITAL LETTER U WITH TILDE
.. |uuml| unicode:: U+000FC .. LATIN SMALL LETTER U WITH DIAERESIS
For characters such as '|eacute|', '|uuml|', '|otilde|', '|Aacute|', and '|Utilde|', it is recommended
to use the single Unicode format (NFC) rather than decomposing them into
a base letter and diacritics (e.g. ``u + ¨``).
Complex languages where subsequent characters combine into a single glyph Complex languages where subsequent characters combine into a single glyph
and where the resulting glyph has no individual Unicode representation and where the resulting glyph has no individual Unicode representation
(e.g., Devanagari), have limited support in LVGL. (e.g., Devanagari), have limited support in LVGL.
Built-in fonts
Built-In Fonts
************** **************
There are several built-in fonts in different sizes, which can be 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 Normal Fonts
------------ ------------
Containing all the ASCII characters, the degree symbol (U+00B0), the The following fonts contain all ASCII characters, the degree symbol (U+00B0), the
bullet symbol (U+2022) and the built-in symbols (see below). bullet symbol (U+2022) and the built-in symbols (see below).
- :c:macro:`LV_FONT_MONTSERRAT_12`: 12 px font - :c:macro:`LV_FONT_MONTSERRAT_12`: 12 px font
@ -120,9 +130,13 @@ Special fonts
The built-in fonts are **global variables** with names like The built-in fonts are **global variables** with names like
:cpp:var:`lv_font_montserrat_16` for a 16 px height font. To use them in a :cpp:var:`lv_font_montserrat_16` for a 16 px height font. To use them in a
style, just add a pointer to a font variable like shown above. style, just add a pointer to a font variable like this:
The built-in fonts with *bpp = 4* contain the ASCII characters and use .. code-block:: c
lv_style_set_text_font(&my_style, &lv_font_montserrat_28);
The built-in fonts with ``bpp = 4`` contain the ASCII characters and use
the `Montserrat <https://fonts.google.com/specimen/Montserrat>`__ font. the `Montserrat <https://fonts.google.com/specimen/Montserrat>`__ font.
In addition to the ASCII range, the following symbols are also added to In addition to the ASCII range, the following symbols are also added to
@ -152,6 +166,7 @@ Or more symbols together:
lv_label_set_text(my_label, LV_SYMBOL_OK LV_SYMBOL_WIFI LV_SYMBOL_PLAY); lv_label_set_text(my_label, LV_SYMBOL_OK LV_SYMBOL_WIFI LV_SYMBOL_PLAY);
Special Features Special Features
**************** ****************
@ -169,17 +184,17 @@ bidirectional, BiDi) text rendering as well. Some examples:
.. image:: /misc/bidi.png .. image:: /misc/bidi.png
BiDi support is enabled by :c:macro:`LV_USE_BIDI` in *lv_conf.h* BiDi support is enabled by setting :c:macro:`LV_USE_BIDI` to a non-zero value in ``lv_conf.h``.
All text has a base direction (LTR or RTL) which determines some All text has a base direction (LTR or RTL) which determines some
rendering rules and the default alignment of the text (Left or Right). 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 However, in LVGL, the base direction is not only applied to labels. It's
a general property which can be set for every Widget. 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 will be inherited from the parent. This means it's enough to set the
base direction of a screen and every Widget will inherit it. base direction of a screen and its child Widgets will inherit it.
The default base direction for screens can be set by The default base direction for screens can be set by
:c:macro:`LV_BIDI_BASE_DIR_DEF` in *lv_conf.h* and other Widgets inherit the :c:macro:`LV_BIDI_BASE_DIR_DEF` in ``lv_conf.h`` and other Widgets inherit the
base direction from their parent. base direction from their parent.
To set a Widget's base direction use :cpp:expr:`lv_obj_set_style_base_dir(widget, base_dir, selector)`. To set a Widget's base direction use :cpp:expr:`lv_obj_set_style_base_dir(widget, base_dir, selector)`.
@ -194,10 +209,11 @@ This list summarizes the effect of RTL base direction on Widgets:
- Create Widgets by default on the right - Create Widgets by default on the right
- ``lv_tabview``: Displays tabs from right to left - ``lv_tabview``: Displays tabs from right to left
- ``lv_checkbox``: Shows the box on the right - ``lv_checkbox``: Shows the box on the right
- ``lv_buttonmatrix``: Shows buttons from right to left - ``lv_buttonmatrix``: Orders buttons from right to left
- ``lv_list``: Shows icons on the right - ``lv_list``: Shows icons on the right
- ``lv_dropdown``: Aligns options to the right - ``lv_dropdown``: Aligns options to the right
- The text strings in ``lv_table``, ``lv_buttonmatrix``, ``lv_keyboard``, ``lv_tabview``, ``lv_dropdown``, ``lv_roller`` are "BiDi processed" to be displayed correctly - The text strings in ``lv_table``, ``lv_buttonmatrix``, ``lv_keyboard``, ``lv_tabview``,
``lv_dropdown``, ``lv_roller`` are "BiDi processed" to be displayed correctly
Arabic and Persian support Arabic and Persian support
-------------------------- --------------------------
@ -208,12 +224,15 @@ different form of the same letter needs to be used when it is isolated,
at start, middle or end positions. Besides these, some conjunction rules at start, middle or end positions. Besides these, some conjunction rules
should also be taken into account. should also be taken into account.
LVGL supports these rules if :c:macro:`LV_USE_ARABIC_PERSIAN_CHARS` is enabled. LVGL supports these rules if :c:macro:`LV_USE_ARABIC_PERSIAN_CHARS` is enabled
in ``lv_conf.h``.
However, there are some limitations: However, there are some limitations:
- Only displaying text is supported (e.g. on labels), text inputs (e.g. text area) don't support this feature. - Only displaying text is supported (e.g. on labels), i.e. text inputs (e.g. Text
- Static text (i.e. const) is not processed. E.g. text set by :cpp:func:`lv_label_set_text` will be "Arabic processed" but :cpp:func:`lv_label_set_text_static` won't. Area) do not support this feature.
- Static text (i.e. const) is not processed. E.g. text set by :cpp:func:`lv_label_set_text`
will be "Arabic processed" but :cpp:func:`lv_label_set_text_static` will not.
- Text get functions (e.g. :cpp:func:`lv_label_get_text`) will return the processed text. - Text get functions (e.g. :cpp:func:`lv_label_get_text`) will return the processed text.
.. _fonts_compressed: .. _fonts_compressed:
@ -228,13 +247,14 @@ Compressed fonts can be generated by
- not passing the ``--no-compress`` flag to the offline converter (compression is applied by default) - not passing the ``--no-compress`` flag to the offline converter (compression is applied by default)
Compression is more effective with larger fonts and higher bpp. However, Compression is more effective with larger fonts and higher bpp. However,
it's about 30% slower to render compressed fonts. Therefore, it's it's about 30% slower to render compressed fonts. Therefore, it is
recommended to compress only the largest fonts of a user interface, recommended to compress only the largest fonts of a user interface,
because because
- they need the most memory - they need the most memory
- they can be compressed better - they can be compressed better
- and probably they are used less frequently then the medium-sized fonts, so the performance cost is smaller. - and on the likelihood that they are used less frequently than the medium-sized
fonts, the performance cost will be smaller.
Compressed fonts also support ``bpp=3``. Compressed fonts also support ``bpp=3``.
@ -248,13 +268,14 @@ characters.
- The offline converter generates kerning tables unless ``--no-kerning`` is - The offline converter generates kerning tables unless ``--no-kerning`` is
specified. specified.
- FreeType integration does not currently support kerning. - FreeType integration does not currently support kerning.
- The Tiny TTF font engine supports GPOS and Kern tables. - The Tiny TTF font engine supports GPOS (Glyph Positioning) and Kern tables.
To configure kerning at runtime, use :cpp:func:`lv_font_set_kerning`. To configure kerning at runtime, use :cpp:func:`lv_font_set_kerning`.
.. _add_font:
.. _add_font:
Adding a New Font Adding a New Font
***************** *****************
@ -270,12 +291,13 @@ There are several ways to add a new font to your project:
fonts (Montserrat font and symbols) but in a different size and/or fonts (Montserrat font and symbols) but in a different size and/or
ranges, you can use the ``built_in_font_gen.py`` script in ranges, you can use the ``built_in_font_gen.py`` script in
``lvgl/scripts/built_in_font`` folder. (This requires Python and ``lvgl/scripts/built_in_font`` folder. (This requires Python and
``lv_font_conv`` to be installed) https://github.com/lvgl/lv_font_conv/ to be installed.)
To declare a font in a file, use :cpp:expr:`LV_FONT_DECLARE(my_font_name)`. 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 To make fonts globally available (like the built-in fonts), add them to
:c:macro:`LV_FONT_CUSTOM_DECLARE` in *lv_conf.h*. :c:macro:`LV_FONT_CUSTOM_DECLARE` in ``lv_conf.h``.
Adding New Symbols Adding New Symbols
@ -285,7 +307,7 @@ The built-in symbols are created from the `FontAwesome <https://fontawesome.com/
1. Search for a symbol on https://fontawesome.com. For example the 1. Search for a symbol on https://fontawesome.com. For example the
`USB symbol <https://fontawesome.com/icons/usb?style=brands>`__. Copy its `USB symbol <https://fontawesome.com/icons/usb?style=brands>`__. Copy its
Unicode ID which is ``0xf287`` in this case. Unicode ID which is ``0xf287``.
2. Open the `Online font converter <https://lvgl.io/tools/fontconverter>`__. 2. Open the `Online font converter <https://lvgl.io/tools/fontconverter>`__.
Add `FontAwesome.woff <https://lvgl.io/assets/others/FontAwesome5-Solid+Brands+Regular.woff>`__. Add `FontAwesome.woff <https://lvgl.io/assets/others/FontAwesome5-Solid+Brands+Regular.woff>`__.
3. Set the parameters such as Name, Size, BPP. You'll use this name to 3. Set the parameters such as Name, Size, BPP. You'll use this name to
@ -293,7 +315,7 @@ The built-in symbols are created from the `FontAwesome <https://fontawesome.com/
4. Add the Unicode ID of the symbol to the range field. E.g.\ ``0xf287`` 4. Add the Unicode ID of the symbol to the range field. E.g.\ ``0xf287``
for the USB symbol. More symbols can be enumerated with ``,``. for the USB symbol. More symbols can be enumerated with ``,``.
5. Convert the font and copy the generated source code to your project. 5. Convert the font and copy the generated source code to your project.
Make sure to compile the .c file of your font. Make sure to compile the ``.c`` file of your font.
6. Declare the font using ``extern lv_font_t my_font_name;`` or simply 6. Declare the font using ``extern lv_font_t my_font_name;`` or simply
use :cpp:expr:`LV_FONT_DECLARE(my_font_name)`. use :cpp:expr:`LV_FONT_DECLARE(my_font_name)`.
@ -302,12 +324,15 @@ The built-in symbols are created from the `FontAwesome <https://fontawesome.com/
1. Convert the Unicode value to UTF8, for example on 1. Convert the Unicode value to UTF8, for example on
`this site <http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=f287&mode=hex>`__. `this site <http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=f287&mode=hex>`__.
For ``0xf287`` the *Hex UTF-8 bytes* are ``EF 8A 87``. For ``0xf287`` the *Hex UTF-8 bytes* are ``EF 8A 87``.
2. Create a ``define`` string from the UTF8 values: ``#define MY_USB_SYMBOL "\xEF\x8A\x87"`` 2. Create a ``#define`` string from the UTF8 values: ``#define MY_USB_SYMBOL "\xEF\x8A\x87"``
3. Create a label and set the text. Eg. :cpp:expr:`lv_label_set_text(label, MY_USB_SYMBOL)` 3. Create a label and set the text. Eg. :cpp:expr:`lv_label_set_text(label, MY_USB_SYMBOL)`
:note: :cpp:expr:`lv_label_set_text(label, MY_USB_SYMBOL)` searches for this :note: :cpp:expr:`lv_label_set_text(label, MY_USB_SYMBOL)` searches for this symbol
symbol in the font defined in ``style.text.font`` properties. To use the in the font defined in the style's ``text.font`` property. To use the symbol
symbol you may need to change it. Eg ``style.text.font = my_font_name`` you will need to set the style's text font to use the generated font, e.g.
:cpp:expr:`lv_style_set_text_font(&my_style, &my_font_name)` or
:cpp:expr:`lv_obj_set_style_text_font(label, &my_font_name, 0)`.
Loading a Font at Run-Time Loading a Font at Run-Time
@ -334,6 +359,7 @@ Example
lv_binfont_destroy(my_font); lv_binfont_destroy(my_font);
Loading a Font from a Memory Buffer at Run-Time Loading a Font from a Memory Buffer at Run-Time
*********************************************** ***********************************************
@ -374,10 +400,11 @@ Convert BDF to TTF
------------------ ------------------
BDF are bitmap fonts where fonts are not described in outlines but in pixels. BDF files can be used but BDF are bitmap fonts where fonts are not described in outlines but in pixels. BDF files can be used but
they must be converted into the TTF format via mkttf. This tool uses potrace to generate outlines from they must be converted into the TTF format using ``mkttf``, which can be found
in this GitHub repository: https://github.com/Tblue/mkttf . This tool uses potrace to generate outlines from
the bitmap information. The bitmap itself will be embedded into the TTF as well. `lv_font_conv <https://github.com/lvgl/lv_font_conv/>`__ uses the bitmap information. The bitmap itself will be embedded into the TTF as well. `lv_font_conv <https://github.com/lvgl/lv_font_conv/>`__ uses
the embedded bitmap but it also needs the outlines. One could think you can use a fake MS Bitmap the embedded bitmap but it also needs the outlines. One might think you can use a fake MS Bitmap
only sfnt (ttf) (TTF without outlines) created by fontforge but this will not work. only sfnt (ttf) (TTF without outlines) created by fontforge, but this will not work.
Install imagemagick, python3, python3-fontforge and potrace Install imagemagick, python3, python3-fontforge and potrace
@ -396,8 +423,8 @@ Clone mkttf
Read the mkttf docs. Read the mkttf docs.
Former versions of imagemagick needs the imagemagick call in front of convert, identify and so on. Former versions of imagemagick needs the imagemagick call in front of convert, identify and so on.
But newer versions don't. So you might probably change 2 lines in potrace-wrapper.sh. But newer versions don't. So you might want to change 2 lines in ``potrace-wrapper.sh`` ---
Open potrace-wrapper.sh and remove imagemagick from line 55 and line 64. open ``potrace-wrapper.sh`` and remove imagemagick from line 55 and line 64:
line 55 line 55
@ -433,15 +460,16 @@ Example for a 12px font
Saving SFD file... Saving SFD file...
Done! Done!
The TTF TerminusMedium-001.000.ttf has been created from ./TerminusMedium-12-12.bdf. The TTF ``TerminusMedium-001.000.ttf`` will be created from ``./TerminusMedium-12-12.bdf``.
Create font for lvgl To create a font for LVGL:
.. code:: bash .. code:: bash
lv_font_conv --bpp 1 --size 12 --no-compress --font TerminusMedium-001.000.ttf --range 0x20-0x7e,0xa1-0xff --format lvgl -o terminus_1bpp_12px.c lv_font_conv --bpp 1 --size 12 --no-compress --font TerminusMedium-001.000.ttf --range 0x20-0x7e,0xa1-0xff --format lvgl -o terminus_1bpp_12px.c
:note: use 1bpp because we don't use anti-aliasing. It doesn't look sharp on displays with a low resolution. :note: use 1-bpp because we don't use anti-aliasing. It doesn't look sharp on displays with a low resolution.
Adding a New Font Engine Adding a New Font Engine
@ -502,12 +530,12 @@ To add a new font engine, a custom :cpp:type:`lv_font_t` variable needs to be cr
} }
Using Font Fallback Using Font Fallback
******************* *******************
You can specify ``fallback`` in :cpp:type:`lv_font_t` to provide fallback to the If the font in use does not have a glyph needed in a text-rendering task, you can
font. When the font fails to find glyph to a letter, it will try to let specify a ``fallback`` font to be used in :cpp:type:`lv_font_t`.
font from ``fallback`` to handle.
``fallback`` can be chained, so it will try to solve until there is no ``fallback`` set. ``fallback`` can be chained, so it will try to solve until there is no ``fallback`` set.
@ -521,6 +549,7 @@ font from ``fallback`` to handle.
roboto->fallback = droid_sans_fallback; roboto->fallback = droid_sans_fallback;
.. _fonts_api: .. _fonts_api:
API API

View File

@ -4,14 +4,18 @@
File System (lv_fs_drv) File System (lv_fs_drv)
======================= =======================
LVGL has a 'File system' abstraction module that enables you to attach 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 any type of file system. A file system is identified by an assigned
drive letter. For example, if an SD card is associated with the letter identifier letter. For example, if an SD card is associated with the letter
``'S'``, a file can be reached using ``"S:path/to/file.txt"``. ``'S'``, a file can be reached using ``"S:/path/to/file.txt"``. See details
under :ref:`lv_fs_identifier_letters`.
.. note:: .. note::
If you want to skip the drive prefix from the path, you can use the :c:macro:`LV_FS_DEFAULT_DRIVE_LETTER` config parameter. If you want to skip the drive-letter prefix in Unix-like paths, you can use the
:c:macro:`LV_FS_DEFAULT_DRIVER_LETTER` config parameter.
Ready-to-use drivers Ready-to-use drivers
******************** ********************
@ -20,15 +24,80 @@ LVGL contains prepared drivers for the API of POSIX, standard C,
Windows, and `FATFS <http://elm-chan.org/fsw/ff/00index_e.html>`__. Windows, and `FATFS <http://elm-chan.org/fsw/ff/00index_e.html>`__.
Learn more :ref:`here <libs_filesystem>`. Learn more :ref:`here <libs_filesystem>`.
Adding a driver
.. _lv_fs_identifier_letters:
Identifier Letters
*********************
As mentioned above, a file system is identified by an assigned identifier letter.
This identifier is merely a way for the LVGL File System abtraction logic to look up
the appropriate registered file-system driver for a given path.
**How it Works:**
You register a driver for your file system and assign it an identifier letter. This
letter must be unique among all registered file-system drivers, and in the range [A-Z]
or the character '/'. See :ref:`lv_fs_adding_a_driver` for how this is done.
Later, when using paths to files on your file system, you prefix the path with that
identifier character plus a colon (':').
.. note::
Do not confuse this with a Windows or DOS drive letter.
**Example:**
Let's use the letter 'Z' as the identifier character, and "path_to_file" as the path,
then the path strings you pass to ``lv_fs_...()`` functions would look like this::
"Z:path_to_file"
^ ^^^^^^^^^^^^
| |
| +-- This part gets passed to the OS-level file-system functions.
|
+-- This part LVGL strips from path string, and uses it to find the appropriate
driver (i.e. set of functions) that apply to that file system.
Note also that the path can be a relative path or a "rooted path" (beginning with
``/``), though rooted paths are recommended since the driver does not yet provide a
way to set the default directory.
**Examples for Unix-like file systems:**
- "Z:/etc/images/splash.png"
- "Z:/etc/images/left_button.png"
- "Z:/etc/images/right_button.png"
- "Z:/home/users/me/wip/proposal.txt"
**Examples for Windows/DOS-like file systems:**
- "Z:C:/Users/me/wip/proposal.txt"
- "Z:/Users/me/wip/proposal.txt" (if the default drive is known to be C:)
- "Z:C:/Users/Public/Documents/meeting_notes.txt"
- "Z:D:/to_print.docx"
Reminder: Note carefully that the prefixed "Z:" has nothing to do with the "C:" and
"D:" Windows/DOS drive letters in 3 of the above examples, which are part of the path.
"Z:" is used to look up the driver for that file system in the list of all file-system
drivers registered with LVGL.
.. _lv_fs_adding_a_driver:
Adding a Driver
*************** ***************
Registering a driver Registering a driver
-------------------- --------------------
To add a driver, a :cpp:type:`lv_fs_drv_t` needs to be initialized like the example below. To add a driver, a :cpp:type:`lv_fs_drv_t` object needs to be initialized and
The :cpp:type:`lv_fs_drv_t` needs to be static, global or dynamically allocated registered in a way similar to the code below. The :cpp:type:`lv_fs_drv_t` variable
and not a local variable. needs to be static, global or dynamically allocated and not a local variable, since
its contents need to remain valid as long as the driver is in use.
.. code-block:: c .. code-block:: c
@ -61,7 +130,7 @@ Implementing the callbacks
-------------------------- --------------------------
Open callback Open callback
^^^^^^^^^^^^^ ~~~~~~~~~~~~~
The prototype of ``open_cb`` looks like this: The prototype of ``open_cb`` looks like this:
@ -88,13 +157,75 @@ like this:
lv_fs_res_t (*write_cb)(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw); lv_fs_res_t (*write_cb)(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
For ``file_p``, LVGL passes the return value of ``open_cb``, ``buf`` is For ``file_p``, LVGL passes the return value of ``open_cb``, ``buf`` is
the data to write, ``btw`` is the Bytes To Write, ``bw`` is the actual the data to write, ``btw`` is the number of "bytes to write", ``bw`` is the number of
bytes written during the call. "bytes written" (written to during the function call).
For a template of these callbacks see For a list of prototypes for these callbacks see
`lv_fs_template.c <https://github.com/lvgl/lvgl/blob/master/examples/porting/lv_port_fs_template.c>`__. `lv_fs_template.c <https://github.com/lvgl/lvgl/blob/master/examples/porting/lv_port_fs_template.c>`__.
This file also provides a template for new file-system drivers you can use if the
one you need is not already provided.
Usage example Drivers that come with LVGL
---------------------------
As of this writing, the list of already-available file-system drivers can be enabled
by setting one or more of the following macros to a non-zero value in ``lv_conf.h``.
The drivers are as implied by the macro names.
If you use more than one, each associated identifier letter you use must be unique.
- :c:macro:`LV_USE_FS_FATFS`
- :c:macro:`LV_USE_FS_STDIO`
- :c:macro:`LV_USE_FS_POSIX`
- :c:macro:`LV_USE_FS_WIN32`
- :c:macro:`LV_USE_FS_MEMFS`
- :c:macro:`LV_USE_FS_LITTLEFS`
- :c:macro:`LV_USE_FS_ARDUINO_ESP_LITTLEFS`
- :c:macro:`LV_USE_FS_ARDUINO_SD`
Limiting Directory Access
*************************
If you are using one of the following file-system drivers:
- :c:macro:`LV_USE_FS_STDIO`
- :c:macro:`LV_USE_FS_POSIX`
- :c:macro:`LV_USE_FS_WIN32`
you will have a ``LV_FS_xxx_PATH`` macro available to you in ``lv_conf.h`` that you
can use to provide a path that gets dynamically prefixed to the ``path_to_file``
portion of of the path strings provided to ``lv_fs_...()`` functions when files and
directories are opened. This can be useful to limit directory access (e.g. when a
portion of a path can be typed by an end user), or simply to reduce the length of the
path strings provided to ``lv_fs_...()`` functions.
Do this by filling in the full path to the directory you wish his access to be
limited to in the applicable ``LV_FS_xxx_PATH`` macro in ``lv_conf.h``. Do not
prefix the path with the driver-identifier letter, and do append a directory
separator character at the end.
**Examples for Unix-like file systems:**
.. code-block:: c
#define LV_FS_WIN32_PATH "/home/users/me/"
**Examples for Windows/DOS-like file systems:**
.. code-block:: c
#define LV_FS_WIN32_PATH "C:/Users/me/"
Then in both cases, path strings passed to ``lv_fs_...()`` functions in the
application get reduced to:
- "Z:wip/proposal.txt"
Usage Example
************* *************
The example below shows how to read from a file: The example below shows how to read from a file:
@ -113,8 +244,9 @@ The example below shows how to read from a file:
lv_fs_close(&f); lv_fs_close(&f);
The mode in :cpp:func:`lv_fs_open` can be :cpp:enumerator:`LV_FS_MODE_WR` to open for writes The mode in :cpp:func:`lv_fs_open` can be :cpp:enumerator:`LV_FS_MODE_WR` to open for
only or :cpp:enumerator:`LV_FS_MODE_RD` ``|`` :cpp:enumerator:`LV_FS_MODE_WR` for both writes only, :cpp:enumerator:`LV_FS_MODE_RD` for reads only, or
:cpp:enumerator:`LV_FS_MODE_RD` ``|`` :cpp:enumerator:`LV_FS_MODE_WR` for both.
This example shows how to read a directory's content. It's up to the This example shows how to read a directory's content. It's up to the
driver how to mark directories in the result but it can be a good driver how to mark directories in the result but it can be a good
@ -135,7 +267,7 @@ practice to insert a ``'/'`` in front of each directory name.
break; break;
} }
/* fn is empty, if no more files to read */ /* fn is empty if there are no more files to read. */
if(strlen(fn) == 0) { if(strlen(fn) == 0) {
break; break;
} }
@ -145,7 +277,9 @@ practice to insert a ``'/'`` in front of each directory name.
lv_fs_dir_close(&dir); lv_fs_dir_close(&dir);
Use drives for images
Use Drives for Images
********************* *********************
:ref:`Image <lv_image>` Widgets can be opened from files as well (besides :ref:`Image <lv_image>` Widgets can be opened from files as well (besides
@ -159,9 +293,11 @@ To use files in Image Widgets the following callbacks are required:
- seek - seek
- tell - tell
.. _overview_file_system_cache: .. _overview_file_system_cache:
Optional file buffering/caching Optional File Buffering/Caching
******************************* *******************************
Files will buffer their reads if the corresponding ``LV_FS_*_CACHE_SIZE`` Files will buffer their reads if the corresponding ``LV_FS_*_CACHE_SIZE``
@ -248,6 +384,8 @@ to determine where the end of the file is.
The driver's ``tell`` will not actually be called. The driver's ``tell`` will not actually be called.
.. _overview_file_system_api: .. _overview_file_system_api:
API API

View File

@ -4,85 +4,192 @@
File Explorer File Explorer
============= =============
``lv_file_explorer`` provides an API to browse the contents of the file ``lv_file_explorer`` provides a UI enabling the end user to browse the contents of a
system. ``lv_file_explorer`` only provides the file browsing function, file system. Its main area is called the "Browsing Area" and provides the list of
but does not provide the actual file operation function. In other words, files contained in the currently-viewed directory.
you can't click a picture file to open and view the picture like a PC.
``lv_file_explorer`` will tell you the full path and name of the When enabled, there is also a "Quick-Access" panel on the left, which provides a
currently clicked file. The file operation function needs to be convenient way to reach parts of the file system that are frequently accessed.
implemented by the user. Available "Quick-Access" destinations are:
- File System,
- HOME,
- Video,
- Pictures,
- Music, and
- Documents.
You specify what paths these lead to during ``lv_file_explorer``\ 's initialization.
``lv_file_explorer`` only provides the file browsing and events caused by user
activity (e.g. clicking a file), but does not provide the actual file operations.
Client code must hook various events and decide what to do when they are emitted
(e.g. a click or double-click on a file). The actions taken might to open the file,
display it, send it to some other part of the application, etc..
``lv_file_explorer`` passes the full path and name of file that was clicked to the
event callback functions. What happens next is up to the application designer.
``lv_file_explorer`` uses the :ref:`lv_table` Widget for the "Browsing Area", and the
:ref:`lv_list` Widget for the "Quick-Access" panel when it is enabled. Thus,
:c:macro:`LV_USE_TABLE` macro must be set to a non-zero value in ``lv_conf.h`` in
order to use ``lv_file_explorer``, and and :c:macro:`LV_USE_LIST` must be set to a
non-zero value to use the "Quick-Access" panel.
.. note::
In order to use File Explorer, :ref:`overview_file_system` has to be set up and
know about all the drive letters you use when passing paths to File System
(described below).
Prerequisites
*************
If you haven't already done so, you will need to learn about the LVGL :ref:`File
System abstraction <overview_file_system>`, since it must be set up and be functional
for File Explorer to work.
The file list in ``lv_file_explorer`` is based on
:ref:`lv_table`, and the quick access bar is based on
:ref:`lv_list`. Therefore, care should be taken to ensure
that :ref:`lv_table` and :ref:`lv_list` are
enabled.
.. _file_explorer_usage: .. _file_explorer_usage:
Usage Usage
----- *****
Enable :c:macro:`LV_USE_FILE_EXPLORER` in ``lv_conf.h``. Set :c:macro:`LV_USE_FILE_EXPLORER` to a non-zero value in ``lv_conf.h``.
First use :cpp:expr:`lv_file_explorer_create(lv_screen_active())` to create a file First use :cpp:expr:`lv_file_explorer_create(lv_screen_active())` to create a File
explorer, The default size is the screen size. After that, you can Explorer. The default size is the screen size. After that, you can
customize the style like widget. customize the style like any Widget.
Quick access The size of the ``current_path`` buffer is set by :c:macro:`LV_FILE_EXPLORER_PATH_MAX_LEN`
~~~~~~~~~~~~ in ``lv_conf.h``.
The quick access bar is optional. You can turn off The object hierarchy of a freshly-created File Explorer looks like this:
:c:macro:`LV_FILE_EXPLORER_QUICK_ACCESS` in ``lv_conf.h`` so that the quick
access bar will not be created. This can save some memory, but not much.
After the quick access bar is created, it can be hidden by clicking the
button at the top left corner of the browsing area, which is very useful
for small screen devices.
You can use - ``File Explorer``: occupies full area of parent Widget, typically a Screen (Flex-Flow COLUMN)
:cpp:expr:`lv_file_explorer_set_quick_access_path(file_explorer, LV_FILE_EXPLORER_QA_XX, "path")`
to set the path of the quick access bar. The items of the quick access - ``Container``: occupies full area of File Explorer (Flex grow 1)
bar are fixed. Currently, there are the following items:
- ``Quick-Access Panel``:
- ``Device List``: grows to accommodate children
- ``File System``: button
- ``Places List``: grows to accommodate children
- ``HOME``: button
- ``Video``: button
- ``Pictures``: button
- ``Music``: button
- ``Documents``: button
- ``Browser Panel``:
- ``Header``: 14% of ``Browser Panel`` height
- ``Current Path``: label
- ``File Table``: with 1 column, 86% of ``Browser Panel`` height
- Fields:
- ``home_dir`` = NULL
- ``video_dir`` = NULL
- ``pictures_dir`` = NULL
- ``music_dir`` = NULL
- ``docs_dir`` = NULL
- ``fs_dir`` = NULL
- ``current_path`` = [empty buffer]
- ``sel_fn`` (selected file)
- ``sort`` (default :cpp:enumerator:`LV_EXPLORER_SORT_NONE`)
Accessing the Parts
-------------------
This list of functions provides access to the parts shown in diagram above:
- :cpp:expr:`lv_file_explorer_get_selected_file_name(explorer)` (pointer
to NUL-terminated string containing file-path user selected; typically used inside
an :cpp:enumerator:`LV_EVENT_CLICKED` event)
- :cpp:expr:`lv_file_explorer_get_current_path(explorer)` (pointer to ``current_path`` ``char`` buffer)
- :cpp:expr:`lv_file_explorer_get_file_table(explorer)` (pointer to ``File Table`` :ref:`lv_table` Widget)
- :cpp:expr:`lv_file_explorer_get_header(explorer)` (pointer to ``Header`` :ref:`base_widget` Widget)
- :cpp:expr:`lv_file_explorer_get_path_label(explorer)` (pointer to ``Current Path Label`` :ref:`lv_label` Widget)
- :cpp:expr:`lv_file_explorer_get_quick_access_area(explorer)` (pointer to ``Quick-Access Panel`` :ref:`base_widget`)
- :cpp:expr:`lv_file_explorer_get_places_list(explorer)` (pointer to ``Places List`` :ref:`lv_list` Widget)
- :cpp:expr:`lv_file_explorer_get_device_list(explorer)` (pointer to ``Device List`` :ref:`lv_list` Widget)
Quick-Access Panel
------------------
The ``Quick-Access Panel`` behaves like a typical navigation panel and appears on the
left, while the ``Browser Panel`` appears on the right
This panel is optional. If you set :c:macro:`LV_FILE_EXPLORER_QUICK_ACCESS` to ``0``
in ``lv_conf.h``, the ``Quick-Access Panel`` will not be created. This saves only a
little bit of memory.
Soon after the File Explorer is created, you typically use
:cpp:expr:`lv_file_explorer_set_quick_access_path(explorer, LV_EXPLORER_XXX_DIR, "path")`
to set the path that will be navigated to when the buttons in the ``Quick-Access Panel``
are clicked, which is currently a fixed list. The corresponding values you will need
to pass as the 2nd argument are the following:
- :cpp:enumerator:`LV_EXPLORER_HOME_DIR`
- :cpp:enumerator:`LV_EXPLORER_MUSIC_DIR`
- :cpp:enumerator:`LV_EXPLORER_PICTURES_DIR`
- :cpp:enumerator:`LV_EXPLORER_VIDEO_DIR`
- :cpp:enumerator:`LV_EXPLORER_DOCS_DIR`
- :cpp:enumerator:`LV_EXPLORER_FS_DIR`
- :cpp:enumerator:`LV_FILE_EXPLORER_QA_HOME`
- :cpp:enumerator:`LV_FILE_EXPLORER_QA_MUSIC`
- :cpp:enumerator:`LV_FILE_EXPLORER_QA_PICTURES`
- :cpp:enumerator:`LV_FILE_EXPLORER_QA_VIDEO`
- :cpp:enumerator:`LV_FILE_EXPLORER_QA_DOCS`
- :cpp:enumerator:`LV_FILE_EXPLORER_QA_MNT`
- :cpp:enumerator:`LV_FILE_EXPLORER_QA_FS`
.. _file_explorer_sort: .. _file_explorer_sort:
Sort Sort
~~~~ ----
You can use You can use
:cpp:expr:`lv_file_explorer_set_sort(file_explorer, LV_EXPLORER_SORT_XX)` to set :cpp:expr:`lv_file_explorer_set_sort(explorer, LV_EXPLORER_SORT_XX)` to set
sorting method. the sorting method.
There are the following sorting methods: These are the possible sorting methods:
- :cpp:enumerator:`LV_EXPLORER_SORT_NONE` - :cpp:enumerator:`LV_EXPLORER_SORT_NONE` (default)
- :cpp:enumerator:`LV_EXPLORER_SORT_KIND` - :cpp:enumerator:`LV_EXPLORER_SORT_KIND`
You can customize the sorting. Before custom sort, please set the :cpp:expr:`lv_file_explorer_get_sort(explorer)` returns the current sorting method.
default sorting to :cpp:enumerator:`LV_EXPLORER_SORT_NONE`. The default is
:cpp:enumerator:`LV_EXPLORER_SORT_NONE`.
.. _file_explorer_events: .. _file_explorer_events:
Events Events
------ ******
- :cpp:enumerator:`LV_EVENT_READY` Sent when a directory is opened. You can customize - :cpp:enumerator:`LV_EVENT_READY` Sent when a directory is opened, which can happen:
the sort.
- :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` Sent when an item (file) in the file list
is clicked.
You can use :cpp:func:`lv_file_explorer_get_cur_path` to get the current path - when the File Explorer is initially opened,
and :cpp:func:`lv_file_explorer_get_sel_fn` to get the name of the currently - after a user clicks on a ``Quick-Access Panel`` navigation button, and
selected file in the event processing function. For example: - after the user clicks on a directory displayed in the ``Browser Panel``.
You can use it to, for example, customize the file sort.
- :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` Sent once when any item (file) in the
``Brwoser Panel``\ 's file list is clicked.
- :cpp:enumerator:`LV_EVENT_CLICKED` Sent twice when an item in the ``Browser Panel``
is clicked: once as a result of the input-device :cpp:enumerator:`LV_EVENT_RELEASED`
event and a second as a result of the input device :cpp:enumerator:`LV_EVENT_CLICKED`
event. This applies to files, directories, and the "< Back" item in the ``Browser Panel``.
In these events you can use :cpp:func:`lv_file_explorer_get_current_path` to get the
current path and :cpp:func:`lv_file_explorer_get_selected_file_name` to get the name
of the currently selected file in the event processing function. For example:
.. code-block:: c .. code-block:: c
@ -92,8 +199,8 @@ selected file in the event processing function. For example:
lv_obj_t * obj = lv_event_get_target(e); lv_obj_t * obj = lv_event_get_target(e);
if(code == LV_EVENT_VALUE_CHANGED) { if(code == LV_EVENT_VALUE_CHANGED) {
char * cur_path = lv_file_explorer_get_cur_path(widget); char * cur_path = lv_file_explorer_get_current_path(widget);
char * sel_fn = lv_file_explorer_get_sel_fn(widget); char * sel_fn = lv_file_explorer_get_selected_file_name(widget);
LV_LOG_USER("%s%s", cur_path, sel_fn); LV_LOG_USER("%s%s", cur_path, sel_fn);
} }
} }
@ -101,15 +208,19 @@ selected file in the event processing function. For example:
You can also save the obtained **path** and **file** name into an array You can also save the obtained **path** and **file** name into an array
through functions such as :cpp:func:`strcpy` and :cpp:func:`strcat` for later use. through functions such as :cpp:func:`strcpy` and :cpp:func:`strcat` for later use.
.. _file_explorer_example: .. _file_explorer_example:
Example Example
------- *******
.. include:: ../../examples/others/file_explorer/index.rst .. include:: ../../examples/others/file_explorer/index.rst
.. _file_explorer_api: .. _file_explorer_api:
API API
--- ***

View File

@ -5,7 +5,7 @@ XML - Declarative UI
==================== ====================
Introduction Introduction
------------ ************
LVGL is capable of loading UI elements written in XML. LVGL is capable of loading UI elements written in XML.
Although still under development, the basics are already functional, serving as a preview. Although still under development, the basics are already functional, serving as a preview.
@ -44,7 +44,7 @@ Limitations:
- The documentation is not complete yet. - The documentation is not complete yet.
Main Concept Main Concept
~~~~~~~~~~~~ ------------
It's important to distinguish between widgets and components: It's important to distinguish between widgets and components:
@ -67,11 +67,13 @@ The main characteristics of components are:
- Cannot have custom C code. - Cannot have custom C code.
- Can be loaded from XML at runtime as they describe only the visuals. - Can be loaded from XML at runtime as they describe only the visuals.
Components Components
---------- **********
Overview Overview
~~~~~~~~ --------
In light of the above, only components can be loaded from XML. In light of the above, only components can be loaded from XML.
An example of a ``my_button`` component looks like this: An example of a ``my_button`` component looks like this:
@ -100,9 +102,9 @@ An example of a ``my_button`` component looks like this:
- ``<component>``: The root element. - ``<component>``: The root element.
- ``<consts>``: Constants with ``int``, ``px``, ``string``, ``color``, or ``style`` types. - ``<consts>``: Constants with ``int``, ``px``, ``string``, ``color``, or ``style`` types.
Constants can later be referenced as ``#name``. Constants can later be referenced as ``#name``.
- ``<params>``: Parameters with ``int``, ``px``, ``string``, ``color``, or ``style`` types. - ``<params>``: Parameters with ``int``, ``px``, ``string``, ``color``, or ``style`` types.
Parameters can later be referenced as ``$name``. Parameters can later be referenced as ``$name``.
- ``<styles>``: ``<style>`` properties can be defined with names and properties. - ``<styles>``: ``<style>`` properties can be defined with names and properties.
- ``<view>``: Describes how the component looks. Can reference constants, parameters, and styles. - ``<view>``: Describes how the component looks. Can reference constants, parameters, and styles.
@ -115,9 +117,10 @@ Naming conventions:
- ``params`` can be referenced with ``$`` - ``params`` can be referenced with ``$``
- ``consts`` can be referenced with ``#`` - ``consts`` can be referenced with ``#``
- ``styles`` can be attached to states and/or parts like ``styles="red blue:pressed green:focused:scrollbar"`` - ``styles`` can be attached to states and/or parts like ``styles="red blue:pressed green:focused:scrollbar"``
- Local styles can be used like ``<lv_label style_text_color="0xff0000" style_text_color:checked="0x00ff00" `` - Local styles can be used like ``<lv_label style_text_color="0xff0000" style_text_color:checked="0x00ff00"``
Usage Usage
~~~~~ -----
Once a component is created (e.g., ``my_button``), it can be registered by calling either: Once a component is created (e.g., ``my_button``), it can be registered by calling either:
@ -149,7 +152,7 @@ The last parameter can be ``NULL`` or an attribute list, like this:
lv_obj_t * btn1 = lv_xml_create(lv_screen_active(), "my_button", my_button_attrs); lv_obj_t * btn1 = lv_xml_create(lv_screen_active(), "my_button", my_button_attrs);
Parameters Parameters
~~~~~~~~~~ ----------
It is possible to pass parameters to child components and widgets. It is possible to pass parameters to child components and widgets.
These parameters can be set on a parent widget or provided by the user. These parameters can be set on a parent widget or provided by the user.
@ -196,18 +199,20 @@ The following example demonstrates parameter chaining and the use of the
}; };
lv_xml_create(lv_screen_active(), "red_button", attrs); lv_xml_create(lv_screen_active(), "red_button", attrs);
Widgets Widgets
------- *******
Overview Overview
~~~~~~~~ --------
Widgets are written in C and compiled into the application. Widgets are written in C and compiled into the application.
They can be referenced from components, and their API can be used via the exposed attributes They can be referenced from components, and their API can be used via the exposed attributes
(e.g., label text or slider value). (e.g., label text or slider value).
Usage Usage
~~~~~ -----
To make the widgets accessible from XML, an XML parser needs to be registered for each widget. To make the widgets accessible from XML, an XML parser needs to be registered for each widget.
The XML parser for the slider looks like this: The XML parser for the slider looks like this:
@ -222,11 +227,11 @@ The XML parser for the slider looks like this:
} }
void lv_xml_label_apply(lv_xml_parser_state_t * state, const char ** attrs) void lv_xml_label_apply(lv_xml_parser_state_t * state, const char ** attrs)
{ {
void * item = lv_xml_state_get_item(state); void * item = lv_xml_state_get_item(state);
/*Apply the common properties, e.g. width, height, styles flags etc*/ /*Apply the common properties, e.g. width, height, styles flags etc*/
lv_xml_obj_apply(state, attrs); lv_xml_obj_apply(state, attrs);
/* Apply the common properties, e.g., width, height, styles, flags, etc. */ /* Apply the common properties, e.g., width, height, styles, flags, etc. */
lv_obj_xml_apply_attrs(state, item, attrs); lv_obj_xml_apply_attrs(state, item, attrs);
@ -239,7 +244,7 @@ The XML parser for the slider looks like this:
if(lv_streq("text", name)) lv_label_set_text(item, value); if(lv_streq("text", name)) lv_label_set_text(item, value);
if(lv_streq("long_mode", name)) lv_label_set_long_mode(item, long_mode_text_to_enum_value(value)); if(lv_streq("long_mode", name)) lv_label_set_long_mode(item, long_mode_text_to_enum_value(value));
} }
} }
/* Helper to convert the string to enum values */ /* Helper to convert the string to enum values */
static lv_label_long_mode_t long_mode_text_to_enum_value(const char * txt) static lv_label_long_mode_t long_mode_text_to_enum_value(const char * txt)
@ -252,7 +257,7 @@ The XML parser for the slider looks like this:
} }
A widget XML process can be registered like A widget XML process can be registered like
:cpp:expr:`lv_xml_widget_register("lv_label", lv_xml_label_create, lv_xml_label_apply);` :cpp:expr:`lv_xml_widget_register("lv_label", lv_xml_label_create, lv_xml_label_apply)`
After this, a widget can be created like this: After this, a widget can be created like this:
@ -269,8 +274,10 @@ After this, a widget can be created like this:
LVGL automatically registers its built-in widgets, LVGL automatically registers its built-in widgets,
so only custom widgets need to be registered manually. so only custom widgets need to be registered manually.
Images and Fonts Images and Fonts
---------------- ****************
In an XML file, images and fonts can be referenced via a name like this: In an XML file, images and fonts can be referenced via a name like this:
``<lv_image src="image1" style_text_font="font1"/>`` ``<lv_image src="image1" style_text_font="font1"/>``
@ -290,12 +297,16 @@ The built-in fonts are automatically registered with names like
The registration functions should be called after The registration functions should be called after
:cpp:expr:`lv_init()` but before :cpp:expr:`lv_xml_create(...)`. :cpp:expr:`lv_init()` but before :cpp:expr:`lv_xml_create(...)`.
Example Example
------- *******
.. include:: ../../examples/others/xml/index.rst .. include:: ../../examples/others/xml/index.rst
.. _xml_api: .. _xml_api:
API API
--- ***

View File

@ -774,7 +774,7 @@
/* File system interfaces for common APIs */ /* File system interfaces for common APIs */
/** Setting a default driver letter allows skipping the driver prefix in filepaths. */ /** Setting a default driver letter allows skipping the driver prefix in filepaths. */
#define LV_FS_DEFAULT_DRIVE_LETTER '\0' #define LV_FS_DEFAULT_DRIVER_LETTER '\0'
/** API for fopen, fread, etc. */ /** API for fopen, fread, etc. */
#if LV_USE_FS_STDIO #if LV_USE_FS_STDIO

View File

@ -24,14 +24,26 @@ void lv_example_file_explorer_1(void)
lv_file_explorer_set_sort(file_explorer, LV_EXPLORER_SORT_KIND); lv_file_explorer_set_sort(file_explorer, LV_EXPLORER_SORT_KIND);
#if LV_USE_FS_WIN32 #if LV_USE_FS_WIN32
lv_file_explorer_open_dir(file_explorer, "D:"); /* Note to Windows users: the initial "C:" on these paths corresponds to
* the value of `LV_FS_WIN32_LETTER` in `lv_conf.h`, and should not be
* confused with the Windows/DOS drive letter. It is an identifier that
* is used to enable LVGL to look up the appropriate driver from a list of
* registered file-system drivers. `lv_fs_win32_init()` happens to use the
* identifier letter 'C' so "C:" is the driver-identifier-prefix used here.
* The "C:" following that is indeed the Windows/DOS drive letter and is
* part of the actual path that gets passed to the OS-level functions.
*
* See https://docs.lvgl.io/master/details/main-components/fs.html for details.
* File Explorer uses `lv_fs` internally, thus the required prefix in path strings.
*/
lv_file_explorer_open_dir(file_explorer, "C:C:/");
#if LV_FILE_EXPLORER_QUICK_ACCESS #if LV_FILE_EXPLORER_QUICK_ACCESS
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_HOME_DIR, "C:/Users/Public/Desktop"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_HOME_DIR, "C:C:/Users/Public/Desktop");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_VIDEO_DIR, "C:/Users/Public/Videos"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_VIDEO_DIR, "C:C:/Users/Public/Videos");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_PICTURES_DIR, "C:/Users/Public/Pictures"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_PICTURES_DIR, "C:C:/Users/Public/Pictures");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_MUSIC_DIR, "C:/Users/Public/Music"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_MUSIC_DIR, "C:C:/Users/Public/Music");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_DOCS_DIR, "C:/Users/Public/Documents"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_DOCS_DIR, "C:C:/Users/Public/Documents");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_FS_DIR, "D:"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_FS_DIR, "C:C:/");
#endif #endif
#else #else

View File

@ -58,14 +58,26 @@ void lv_example_file_explorer_2(void)
lv_obj_t * file_explorer = lv_file_explorer_create(lv_screen_active()); lv_obj_t * file_explorer = lv_file_explorer_create(lv_screen_active());
#if LV_USE_FS_WIN32 #if LV_USE_FS_WIN32
lv_file_explorer_open_dir(file_explorer, "D:"); /* Note to Windows users: the initial "C:" on these paths corresponds to
* the value of `LV_FS_WIN32_LETTER` in `lv_conf.h`, and should not be
* confused with the Windows/DOS drive letter. It is an identifier that
* is used to enable LVGL to look up the appropriate driver from a list of
* registered file-system drivers. `lv_fs_win32_init()` happens to use the
* identifier letter 'C' so "C:" is the driver-identifier-prefix used here.
* The "C:" following that is indeed the Windows/DOS drive letter and is
* part of the actual path that gets passed to the OS-level functions.
*
* See https://docs.lvgl.io/master/details/main-components/fs.html for details.
* File Explorer uses `lv_fs` internally, thus the required prefix in path strings.
*/
lv_file_explorer_open_dir(file_explorer, "C:C:/");
#if LV_FILE_EXPLORER_QUICK_ACCESS #if LV_FILE_EXPLORER_QUICK_ACCESS
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_HOME_DIR, "C:/Users/Public/Desktop"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_HOME_DIR, "C:C:/Users/Public/Desktop");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_VIDEO_DIR, "C:/Users/Public/Videos"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_VIDEO_DIR, "C:C:/Users/Public/Videos");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_PICTURES_DIR, "C:/Users/Public/Pictures"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_PICTURES_DIR, "C:C:/Users/Public/Pictures");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_MUSIC_DIR, "C:/Users/Public/Music"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_MUSIC_DIR, "C:C:/Users/Public/Music");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_DOCS_DIR, "C:/Users/Public/Documents"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_DOCS_DIR, "C:C:/Users/Public/Documents");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_FS_DIR, "D:"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_FS_DIR, "C:C:/");
#endif #endif
#else #else

View File

@ -68,14 +68,26 @@ void lv_example_file_explorer_3(void)
lv_file_explorer_set_sort(file_explorer, LV_EXPLORER_SORT_NONE); lv_file_explorer_set_sort(file_explorer, LV_EXPLORER_SORT_NONE);
#if LV_USE_FS_WIN32 #if LV_USE_FS_WIN32
lv_file_explorer_open_dir(file_explorer, "D:"); /* Note to Windows users: the initial "C:" on these paths corresponds to
* the value of `LV_FS_WIN32_LETTER` in `lv_conf.h`, and should not be
* confused with the Windows/DOS drive letter. It is an identifier that
* is used to enable LVGL to look up the appropriate driver from a list of
* registered file-system drivers. `lv_fs_win32_init()` happens to use the
* identifier letter 'C' so "C:" is the driver-identifier-prefix used here.
* The "C:" following that is indeed the Windows/DOS drive letter and is
* part of the actual path that gets passed to the OS-level functions.
*
* See https://docs.lvgl.io/master/details/main-components/fs.html for details.
* File Explorer uses `lv_fs` internally, thus the required prefix in path strings.
*/
lv_file_explorer_open_dir(file_explorer, "C:C:/");
#if LV_FILE_EXPLORER_QUICK_ACCESS #if LV_FILE_EXPLORER_QUICK_ACCESS
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_HOME_DIR, "C:/Users/Public/Desktop"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_HOME_DIR, "C:C:/Users/Public/Desktop");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_VIDEO_DIR, "C:/Users/Public/Videos"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_VIDEO_DIR, "C:C:/Users/Public/Videos");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_PICTURES_DIR, "C:/Users/Public/Pictures"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_PICTURES_DIR, "C:C:/Users/Public/Pictures");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_MUSIC_DIR, "C:/Users/Public/Music"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_MUSIC_DIR, "C:C:/Users/Public/Music");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_DOCS_DIR, "C:/Users/Public/Documents"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_DOCS_DIR, "C:C:/Users/Public/Documents");
lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_FS_DIR, "D:"); lv_file_explorer_set_quick_access_path(file_explorer, LV_EXPLORER_FS_DIR, "C:C:/");
#endif #endif
#else #else

View File

@ -791,7 +791,7 @@
/* File system interfaces for common APIs */ /* File system interfaces for common APIs */
/** Setting a default driver letter allows skipping the driver prefix in filepaths. */ /** Setting a default driver letter allows skipping the driver prefix in filepaths. */
#define LV_FS_DEFAULT_DRIVE_LETTER '\0' #define LV_FS_DEFAULT_DRIVER_LETTER '\0'
/** API for fopen, fread, etc. */ /** API for fopen, fread, etc. */
#define LV_USE_FS_STDIO 0 #define LV_USE_FS_STDIO 0
@ -945,7 +945,7 @@
#if LV_USE_FFMPEG #if LV_USE_FFMPEG
/** Dump input information to stderr */ /** Dump input information to stderr */
#define LV_FFMPEG_DUMP_FORMAT 0 #define LV_FFMPEG_DUMP_FORMAT 0
/** Use lvgl file path in FFmpeg Player widget /** Use lvgl file path in FFmpeg Player widget
* You won't be able to open URLs after enabling this feature. * You won't be able to open URLs after enabling this feature.
* Note that FFmpeg image decoder will always use lvgl file system. */ * Note that FFmpeg image decoder will always use lvgl file system. */
#define LV_FFMPEG_PLAYER_USE_LV_FS 0 #define LV_FFMPEG_PLAYER_USE_LV_FS 0

View File

@ -88,6 +88,11 @@ fout.write(
#endif #endif
#endif #endif
/* Renamed config backwards-compatibility */
#if !defined(LV_FS_DEFAULT_DRIVER_LETTER) && defined(LV_FS_DEFAULT_DRIVE_LETTER)
#define LV_FS_DEFAULT_DRIVER_LETTER LV_FS_DEFAULT_DRIVE_LETTER
#endif
#ifdef CONFIG_LV_COLOR_DEPTH #ifdef CONFIG_LV_COLOR_DEPTH
#define LV_KCONFIG_PRESENT #define LV_KCONFIG_PRESENT
#endif #endif
@ -117,9 +122,9 @@ for line in fin.read().splitlines():
indent = r[1] indent = r[1]
name = r[3] name = r[3]
name = re.sub('\(.*?\)', '', name, 1) #remove parentheses from macros. E.g. MY_FUNC(5) -> MY_FUNC name = re.sub(r'\(.*?\)', '', name, 1) #remove parentheses from macros. E.g. MY_FUNC(5) -> MY_FUNC
line = re.sub('[\s]*', '', line, 1) line = re.sub(r'[\s]*', '', line, 1)
#If the value should be 1 (enabled) by default use a more complex structure for Kconfig checks because #If the value should be 1 (enabled) by default use a more complex structure for Kconfig checks because
#if a not defined CONFIG_... value should be interpreted as 0 and not the LVGL default #if a not defined CONFIG_... value should be interpreted as 0 and not the LVGL default

View File

@ -378,20 +378,23 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path)
lv_strcpy(handle->next_fn, ""); lv_strcpy(handle->next_fn, "");
handle->dir_p = FindFirstFileA(buf, &fdata); handle->dir_p = FindFirstFileA(buf, &fdata);
do {
if(is_dots_name(fdata.cFileName)) { if(handle->dir_p != INVALID_HANDLE_VALUE) {
continue; do {
} if(is_dots_name(fdata.cFileName)) {
else { continue;
if(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "/%s", fdata.cFileName);
} }
else { else {
lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "%s", fdata.cFileName); if(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "/%s", fdata.cFileName);
}
else {
lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "%s", fdata.cFileName);
}
break;
} }
break; } while(FindNextFileA(handle->dir_p, &fdata));
} }
} while(FindNextFileA(handle->dir_p, &fdata));
if(handle->dir_p == INVALID_HANDLE_VALUE) { if(handle->dir_p == INVALID_HANDLE_VALUE) {
lv_free(handle); lv_free(handle);

View File

@ -81,6 +81,8 @@ extern "C" {
#define lv_chart_set_all_value lv_chart_set_all_values #define lv_chart_set_all_value lv_chart_set_all_values
#define lv_calendar_set_showed_date lv_calendar_set_month_shown #define lv_calendar_set_showed_date lv_calendar_set_month_shown
#define LV_FS_DEFAULT_DRIVE_LETTER LV_FS_DEFAULT_DRIVER_LETTER
#define LV_LABEL_LONG_WRAP LV_LABEL_LONG_MODE_WRAP #define LV_LABEL_LONG_WRAP LV_LABEL_LONG_MODE_WRAP
#define LV_LABEL_LONG_DOT LV_LABEL_LONG_MODE_DOTS #define LV_LABEL_LONG_DOT LV_LABEL_LONG_MODE_DOTS
#define LV_LABEL_LONG_SCROLL LV_LABEL_LONG_MODE_SCROLL #define LV_LABEL_LONG_SCROLL LV_LABEL_LONG_MODE_SCROLL

View File

@ -66,6 +66,11 @@
#endif #endif
#endif #endif
/* Renamed config backwards-compatibility */
#if !defined(LV_FS_DEFAULT_DRIVER_LETTER) && defined(LV_FS_DEFAULT_DRIVE_LETTER)
#define LV_FS_DEFAULT_DRIVER_LETTER LV_FS_DEFAULT_DRIVE_LETTER
#endif
#ifdef CONFIG_LV_COLOR_DEPTH #ifdef CONFIG_LV_COLOR_DEPTH
#define LV_KCONFIG_PRESENT #define LV_KCONFIG_PRESENT
#endif #endif
@ -2520,11 +2525,11 @@
/* File system interfaces for common APIs */ /* File system interfaces for common APIs */
/** Setting a default driver letter allows skipping the driver prefix in filepaths. */ /** Setting a default driver letter allows skipping the driver prefix in filepaths. */
#ifndef LV_FS_DEFAULT_DRIVE_LETTER #ifndef LV_FS_DEFAULT_DRIVER_LETTER
#ifdef CONFIG_LV_FS_DEFAULT_DRIVE_LETTER #ifdef CONFIG_LV_FS_DEFAULT_DRIVER_LETTER
#define LV_FS_DEFAULT_DRIVE_LETTER CONFIG_LV_FS_DEFAULT_DRIVE_LETTER #define LV_FS_DEFAULT_DRIVER_LETTER CONFIG_LV_FS_DEFAULT_DRIVER_LETTER
#else #else
#define LV_FS_DEFAULT_DRIVE_LETTER '\0' #define LV_FS_DEFAULT_DRIVER_LETTER '\0'
#endif #endif
#endif #endif
@ -3022,7 +3027,7 @@
#define LV_FFMPEG_DUMP_FORMAT 0 #define LV_FFMPEG_DUMP_FORMAT 0
#endif #endif
#endif #endif
/** Use lvgl file path in FFmpeg Player widget /** Use lvgl file path in FFmpeg Player widget
* You won't be able to open URLs after enabling this feature. * You won't be able to open URLs after enabling this feature.
* Note that FFmpeg image decoder will always use lvgl file system. */ * Note that FFmpeg image decoder will always use lvgl file system. */
#ifndef LV_FFMPEG_PLAYER_USE_LV_FS #ifndef LV_FFMPEG_PLAYER_USE_LV_FS

View File

@ -18,8 +18,8 @@
* DEFINES * DEFINES
*********************/ *********************/
#if LV_FS_DEFAULT_DRIVE_LETTER != '\0' && (LV_FS_DEFAULT_DRIVE_LETTER < 'A' || 'Z' < LV_FS_DEFAULT_DRIVE_LETTER) #if LV_FS_DEFAULT_DRIVER_LETTER != '\0' && (LV_FS_DEFAULT_DRIVER_LETTER < 'A' || 'Z' < LV_FS_DEFAULT_DRIVER_LETTER)
#error "When enabled, LV_FS_DEFAULT_DRIVE_LETTER needs to be a capital ASCII letter (A-Z)" #error "When enabled, LV_FS_DEFAULT_DRIVER_LETTER needs to be a capital ASCII letter (A-Z)"
#endif #endif
#define fsdrv_ll_p &(LV_GLOBAL_DEFAULT()->fsdrv_ll) #define fsdrv_ll_p &(LV_GLOBAL_DEFAULT()->fsdrv_ll)
@ -28,7 +28,7 @@
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
typedef struct { typedef struct {
char drive_letter; char driver_letter;
const char * real_path; const char * real_path;
} resolved_path_t; } resolved_path_t;
@ -82,7 +82,7 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo
resolved_path_t resolved_path = lv_fs_resolve_path(path); resolved_path_t resolved_path = lv_fs_resolve_path(path);
lv_fs_drv_t * drv = lv_fs_get_drv(resolved_path.drive_letter); lv_fs_drv_t * drv = lv_fs_get_drv(resolved_path.driver_letter);
if(drv == NULL) { if(drv == NULL) {
LV_LOG_WARN("Can't open file (%s): unknown driver letter", path); LV_LOG_WARN("Can't open file (%s): unknown driver letter", path);
@ -307,7 +307,7 @@ lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path)
resolved_path_t resolved_path = lv_fs_resolve_path(path); resolved_path_t resolved_path = lv_fs_resolve_path(path);
lv_fs_drv_t * drv = lv_fs_get_drv(resolved_path.drive_letter); lv_fs_drv_t * drv = lv_fs_get_drv(resolved_path.driver_letter);
if(drv == NULL) { if(drv == NULL) {
return LV_FS_RES_NOT_EX; return LV_FS_RES_NOT_EX;
@ -509,19 +509,19 @@ static resolved_path_t lv_fs_resolve_path(const char * path)
{ {
resolved_path_t resolved; resolved_path_t resolved;
#if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/ #if LV_FS_DEFAULT_DRIVER_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/
bool has_drive_prefix = ('A' <= path[0]) && (path[0] <= 'Z') && (path[1] == ':'); bool has_drive_prefix = ('A' <= path[0]) && (path[0] <= 'Z') && (path[1] == ':');
if(has_drive_prefix) { if(has_drive_prefix) {
resolved.drive_letter = path[0]; resolved.driver_letter = path[0];
resolved.real_path = path + 2; resolved.real_path = path + 2;
} }
else { else {
resolved.drive_letter = LV_FS_DEFAULT_DRIVE_LETTER; resolved.driver_letter = LV_FS_DEFAULT_DRIVER_LETTER;
resolved.real_path = path; resolved.real_path = path;
} }
# else /*Lean rules for backward compatibility*/ # else /*Lean rules for backward compatibility*/
resolved.drive_letter = path[0]; resolved.driver_letter = path[0];
if(*path != '\0') { if(*path != '\0') {
path++; /*Ignore the driver letter*/ path++; /*Ignore the driver letter*/

View File

@ -406,11 +406,15 @@ static void init_style(lv_obj_t * obj)
lv_style_set_border_width(&quick_access_list_button_style, 0); lv_style_set_border_width(&quick_access_list_button_style, 0);
lv_style_set_bg_color(&quick_access_list_button_style, lv_color_hex(0xf2f1f6)); lv_style_set_bg_color(&quick_access_list_button_style, lv_color_hex(0xf2f1f6));
uint32_t i, j; uint32_t ch_cnt = lv_obj_get_child_count(explorer->quick_access_area);
for(i = 0; i < lv_obj_get_child_count(explorer->quick_access_area); i++) {
for(uint32_t i = 0; i < ch_cnt; i++) {
lv_obj_t * child = lv_obj_get_child(explorer->quick_access_area, i); lv_obj_t * child = lv_obj_get_child(explorer->quick_access_area, i);
if(lv_obj_check_type(child, &lv_list_class)) { if(lv_obj_check_type(child, &lv_list_class)) {
for(j = 0; j < lv_obj_get_child_count(child); j++) { uint32_t list_ch_cnt = lv_obj_get_child_count(child);
for(uint32_t j = 0; j < list_ch_cnt; j++) {
lv_obj_t * list_child = lv_obj_get_child(child, j); lv_obj_t * list_child = lv_obj_get_child(child, j);
if(lv_obj_check_type(list_child, &lv_list_button_class)) { if(lv_obj_check_type(list_child, &lv_list_button_class)) {
lv_obj_add_style(list_child, &quick_access_list_button_style, 0); lv_obj_add_style(list_child, &quick_access_list_button_style, 0);
@ -564,13 +568,13 @@ static void show_dir(lv_obj_t * obj, const char * path)
while(1) { while(1) {
res = lv_fs_dir_read(&dir, fn, sizeof(fn)); res = lv_fs_dir_read(&dir, fn, sizeof(fn));
if(res != LV_FS_RES_OK) { if(res != LV_FS_RES_OK) {
LV_LOG_USER("Driver, file or directory is not exists %d!", res); LV_LOG_USER("Driver, file or directory does not exist %d!", res);
break; break;
} }
/*fn is empty, if not more files to read*/ /*fn is empty, if not more files to read*/
if(lv_strlen(fn) == 0) { if(lv_strlen(fn) == 0) {
LV_LOG_USER("Not more files to read!"); LV_LOG_USER("No more files to read!");
break; break;
} }
@ -706,8 +710,8 @@ static bool is_end_with(const char * str1, const char * str2)
if(str1 == NULL || str2 == NULL) if(str1 == NULL || str2 == NULL)
return false; return false;
uint16_t len1 = lv_strlen(str1); size_t len1 = lv_strlen(str1);
uint16_t len2 = lv_strlen(str2); size_t len2 = lv_strlen(str2);
if((len1 < len2) || (len1 == 0 || len2 == 0)) if((len1 < len2) || (len1 == 0 || len2 == 0))
return false; return false;

View File

@ -70,7 +70,7 @@
#define LV_USE_FS_MEMFS 1 #define LV_USE_FS_MEMFS 1
#define LV_FS_MEMFS_LETTER 'M' #define LV_FS_MEMFS_LETTER 'M'
#define LV_FS_DEFAULT_DRIVE_LETTER 'A' #define LV_FS_DEFAULT_DRIVER_LETTER 'A'
#define LV_USE_MONKEY 1 #define LV_USE_MONKEY 1
#define LV_USE_RLE 1 #define LV_USE_RLE 1