feat(docs): batch 14 of proofread/edited docs (#7477)
This commit is contained in:
@@ -188,27 +188,28 @@ and attach them to LVGL via the *Image decoder* interface.
|
|||||||
|
|
||||||
An image decoder consists of 4 callbacks:
|
An image decoder consists of 4 callbacks:
|
||||||
|
|
||||||
- **info** get some basic info about the image (width, height and color format).
|
:info: get some basic info about the image (width, height and color format).
|
||||||
- **open** open an image:
|
:open: open an image:
|
||||||
- store a decoded image
|
- store a decoded image
|
||||||
- set it to ``NULL`` to indicate the image can be read line-by-line.
|
- set it to ``NULL`` to indicate the image can be read line-by-line.
|
||||||
- **get_area** if *open* didn't fully open an image this function should give back part of image as decoded data.
|
:get_area: if *open* didn't fully open an image this function should give back part of image as decoded data.
|
||||||
- **close** close an opened image, free the allocated resources.
|
:close: close an opened image, free the allocated resources.
|
||||||
|
|
||||||
You can add any number of image decoders. When an image needs to be
|
You can add any number of image decoders. When an image needs to be
|
||||||
drawn, the library will try all the registered image decoders until it
|
drawn, the library will try all the registered image decoders until it
|
||||||
finds one which can open the image, i.e. one which knows that format.
|
finds one which can open the image, i.e. one which knows that format.
|
||||||
|
|
||||||
The following formats are understood by the built-in decoder:
|
The following formats are understood by the built-in decoder:
|
||||||
- ``LV_COLOR_FORMAT_I1``
|
|
||||||
- ``LV_COLOR_FORMAT_I2``
|
- :cpp:enumerator:`LV_COLOR_FORMAT_I1`
|
||||||
- ``LV_COLOR_FORMAT_I4``
|
- :cpp:enumerator:`LV_COLOR_FORMAT_I2`
|
||||||
- ``LV_COLOR_FORMAT_I8``
|
- :cpp:enumerator:`LV_COLOR_FORMAT_I4`
|
||||||
- ``LV_COLOR_FORMAT_RGB888``
|
- :cpp:enumerator:`LV_COLOR_FORMAT_I8`
|
||||||
- ``LV_COLOR_FORMAT_XRGB8888``
|
- :cpp:enumerator:`LV_COLOR_FORMAT_RGB888`
|
||||||
- ``LV_COLOR_FORMAT_ARGB8888``
|
- :cpp:enumerator:`LV_COLOR_FORMAT_XRGB8888`
|
||||||
- ``LV_COLOR_FORMAT_RGB565``
|
- :cpp:enumerator:`LV_COLOR_FORMAT_ARGB8888`
|
||||||
- ``LV_COLOR_FORMAT_RGB565A8``
|
- :cpp:enumerator:`LV_COLOR_FORMAT_RGB565`
|
||||||
|
- :cpp:enumerator:`LV_COLOR_FORMAT_RGB565A8`
|
||||||
|
|
||||||
|
|
||||||
Custom image formats
|
Custom image formats
|
||||||
@@ -230,8 +231,8 @@ library. In other words, the image decoder must decode the *Raw* images
|
|||||||
to *True color* according to the format described in the :ref:`overview_image_color_formats` section.
|
to *True color* according to the format described in the :ref:`overview_image_color_formats` section.
|
||||||
|
|
||||||
|
|
||||||
Register an image decoder
|
Registering an image decoder
|
||||||
-------------------------
|
----------------------------
|
||||||
|
|
||||||
Here's an example of getting LVGL to work with PNG images.
|
Here's an example of getting LVGL to work with PNG images.
|
||||||
|
|
||||||
|
|||||||
@@ -18,19 +18,21 @@ Such concept also has some similarities to `UiViewController on
|
|||||||
iOS <https://developer.apple.com/documentation/uikit/uiviewcontroller>`__.
|
iOS <https://developer.apple.com/documentation/uikit/uiviewcontroller>`__.
|
||||||
|
|
||||||
Fragment Manager is a manager holding references to fragments attached
|
Fragment Manager is a manager holding references to fragments attached
|
||||||
to it, and has an internal stack to achieve navigation. You can use
|
to it, and has an internal stack to achieve forward and backwards navigation. You can use
|
||||||
fragment manager to build navigation stack, or multi pane application
|
fragment manager to build a navigation stack, or a multi-pane application
|
||||||
easily.
|
easily.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _fragment_usage:
|
.. _fragment_usage:
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
*****
|
||||||
|
|
||||||
Enable :c:macro:`LV_USE_FRAGMENT` in ``lv_conf.h``.
|
Enable :c:macro:`LV_USE_FRAGMENT` in ``lv_conf.h``.
|
||||||
|
|
||||||
Create Fragment Class
|
Create Fragment Class
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
---------------------
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
@@ -51,7 +53,7 @@ Create Fragment Class
|
|||||||
};
|
};
|
||||||
|
|
||||||
Use ``lv_fragment_manager``
|
Use ``lv_fragment_manager``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
---------------------------
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
@@ -61,7 +63,7 @@ Use ``lv_fragment_manager``
|
|||||||
lv_fragment_manager_replace(manager, &sample_cls, init_argument);
|
lv_fragment_manager_replace(manager, &sample_cls, init_argument);
|
||||||
|
|
||||||
Fragment Based Navigation
|
Fragment Based Navigation
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
-------------------------
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
@@ -73,14 +75,18 @@ Fragment Based Navigation
|
|||||||
/* Remove the top most fragment from the stack, and bring back previous one. */
|
/* Remove the top most fragment from the stack, and bring back previous one. */
|
||||||
lv_fragment_manager_pop(manager);
|
lv_fragment_manager_pop(manager);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _fragment_example:
|
.. _fragment_example:
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
*******
|
||||||
|
|
||||||
.. include:: ../../examples/others/fragment/index.rst
|
.. include:: ../../examples/others/fragment/index.rst
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _fragment_api:
|
.. _fragment_api:
|
||||||
|
|
||||||
API
|
API
|
||||||
---
|
***
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
Grid navigation
|
Grid navigation
|
||||||
===============
|
===============
|
||||||
|
|
||||||
Grid navigation (gridnav for short) is a feature that changes the
|
Grid navigation (gridnav for short) is a feature that moves focus among a set
|
||||||
currently focused child Widget as arrow keys are pressed.
|
of child Widgets via arrow-key presses.
|
||||||
|
|
||||||
If the children are arranged into a grid-like layout then the up, down,
|
If the child Widgets are arranged into a grid-like layout then the up, down,
|
||||||
left and right arrows move focus to the nearest sibling in the
|
left and right arrows move focus to the nearest sibling in the
|
||||||
respective direction.
|
respective direction.
|
||||||
|
|
||||||
@@ -17,8 +17,8 @@ manually positioned children, as well as :ref:`flex` and
|
|||||||
:ref:`grid` layouts.
|
:ref:`grid` layouts.
|
||||||
|
|
||||||
Gridnav also works if the children are arranged into a single row or
|
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
|
column. This is useful, for example, to simplify navigation among items in a
|
||||||
:ref:`List widget <lv_list>`.
|
:ref:`List Widget <lv_list>`.
|
||||||
|
|
||||||
Gridnav assumes that the Widget to which gridnav is added is part of a
|
Gridnav assumes that the Widget to which gridnav is added is part of a
|
||||||
:ref:`group <indev_groups>`. This way, if the Widget with
|
:ref:`group <indev_groups>`. This way, if the Widget with
|
||||||
@@ -34,15 +34,18 @@ key on keyboard as usual.
|
|||||||
If the container is scrollable and the focused child is out of the view,
|
If the container is scrollable and the focused child is out of the view,
|
||||||
gridnav will automatically scroll the child into view.
|
gridnav will automatically scroll the child into view.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _gridnav_usage:
|
.. _gridnav_usage:
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
*****
|
||||||
|
|
||||||
To add the gridnav feature to a Widget use
|
To add gridnav behavior to any Widget (e.g. one serving as a container for
|
||||||
:cpp:expr:`lv_gridnav_add(cont, flags)`.
|
child Widgets that the end user will navigate among using arrow keys) use
|
||||||
|
:cpp:expr:`lv_gridnav_add(container, flags)`.
|
||||||
|
|
||||||
``flags`` control the behavior of gridnav:
|
The ``flags`` argument controls the navigation behavior:
|
||||||
|
|
||||||
- :cpp:enumerator:`LV_GRIDNAV_CTRL_NONE`: Default settings
|
- :cpp:enumerator:`LV_GRIDNAV_CTRL_NONE`: Default settings
|
||||||
- :cpp:enumerator:`LV_GRIDNAV_CTRL_ROLLOVER`: If there is no next/previous Widget in a
|
- :cpp:enumerator:`LV_GRIDNAV_CTRL_ROLLOVER`: If there is no next/previous Widget in a
|
||||||
@@ -51,33 +54,40 @@ To add the gridnav feature to a Widget use
|
|||||||
- :cpp:enumerator:`LV_GRIDNAV_CTRL_SCROLL_FIRST`: If an arrow is pressed and the focused
|
- :cpp:enumerator:`LV_GRIDNAV_CTRL_SCROLL_FIRST`: If an arrow is pressed and the focused
|
||||||
Widget can be scrolled in that direction then it will be scrolled instead of
|
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
|
going to the next/previous Widget. If there is no more room for scrolling the
|
||||||
next/previous Widget will be focused normally
|
next/previous Widget will receive focus normally.
|
||||||
- :cpp:enumerator:`LV_GRIDNAV_CTRL_HORIZONTAL_MOVE_ONLY`: Only use the left/right keys
|
- :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 Widget.
|
for grid navigation. Up/down key events will be sent to the Widget that has focus.
|
||||||
- :cpp:enumerator:`LV_GRIDNAV_CTRL_VERTICAL_MOVE_ONLY`: Only use the up/down keys
|
- :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 Widget.
|
for grid navigation. Left/right key events will be sent to the Widget that has focus.
|
||||||
|
|
||||||
|
While the above behaviors can be combined by bit-wise OR-ing the above values together,
|
||||||
:cpp:enumerator:`LV_GRIDNAV_CTRL_HORIZONTAL_MOVE_ONLY` and :cpp:enumerator:`LV_GRIDNAV_CTRL_VERTICAL_MOVE_ONLY`
|
:cpp:enumerator:`LV_GRIDNAV_CTRL_HORIZONTAL_MOVE_ONLY` and :cpp:enumerator:`LV_GRIDNAV_CTRL_VERTICAL_MOVE_ONLY`
|
||||||
should not be used together.
|
should not be used together.
|
||||||
|
|
||||||
:cpp:expr:`lv_gridnav_remove(cont)` Removes gridnav from a Widget.
|
:cpp:expr:`lv_gridnav_remove(container)` Removes gridnav behavior from a Widget.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Focusable Widgets
|
Focusable Widgets
|
||||||
-----------------
|
*****************
|
||||||
|
|
||||||
A Widget 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
|
(: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.
|
hidden (:cpp:enumerator:`LV_OBJ_FLAG_HIDDEN`) to receive focus via gridnav.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _gridnav_example:
|
.. _gridnav_example:
|
||||||
|
|
||||||
Example
|
Examples
|
||||||
-------
|
********
|
||||||
|
|
||||||
.. include:: ../../examples/others/gridnav/index.rst
|
.. include:: ../../examples/others/gridnav/index.rst
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _gridnav_api:
|
.. _gridnav_api:
|
||||||
|
|
||||||
API
|
API
|
||||||
---
|
***
|
||||||
|
|
||||||
|
|||||||
@@ -4,47 +4,48 @@
|
|||||||
Pinyin IME
|
Pinyin IME
|
||||||
==========
|
==========
|
||||||
|
|
||||||
Pinyin IME provides API to provide Chinese Pinyin input method (Chinese
|
Pinyin IME provides an API to provide Chinese Pinyin input method (Chinese
|
||||||
input) for keyboard object, which supports 26 key and 9 key input modes.
|
input) for a Keyboard Widget, which supports both 26-key and 9-key input modes.
|
||||||
You can think of ``lv_ime_pinyin`` as a Pinyin input method plug-in for
|
You can think of ``lv_ime_pinyin`` as a Pinyin input method plug-in for
|
||||||
keyboard objects.
|
the Keyboard Widget.
|
||||||
|
|
||||||
Normally, an environment where :ref:`lv_keyboard` can
|
Normally, an environment where :ref:`lv_keyboard` can
|
||||||
run can also run ``lv_ime_pinyin``. There are two main influencing
|
run can also run ``lv_ime_pinyin``. There are two main influencing
|
||||||
factors: the size of the font file and the size of the dictionary.
|
factors: the size of the font file and the size of the dictionary.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _ime_pinyin_usage:
|
.. _ime_pinyin_usage:
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
*****
|
||||||
|
|
||||||
Enable :c:macro:`LV_USE_IME_PINYIN` in ``lv_conf.h``.
|
Enable :c:macro:`LV_USE_IME_PINYIN` in ``lv_conf.h``.
|
||||||
|
|
||||||
First use :cpp:expr:`lv_ime_pinyin_create(lv_screen_active())` to create a Pinyin
|
First use :cpp:expr:`lv_ime_pinyin_create(lv_screen_active())` to create a Pinyin
|
||||||
input method plug-in, then use
|
input-method plug-in, then use
|
||||||
:cpp:expr:`lv_ime_pinyin_set_keyboard(pinyin_ime, kb)` to add the ``keyboard``
|
:cpp:expr:`lv_ime_pinyin_set_keyboard(pinyin_ime, kb)` to add the Keyboard Widget
|
||||||
you created to the Pinyin input method plug-in. You can use
|
you created to the Pinyin input method plug-in. You can use
|
||||||
:cpp:expr:`lv_ime_pinyin_set_dict(pinyin_ime, your_dict)` to use a custom
|
:cpp:expr:`lv_ime_pinyin_set_dict(pinyin_ime, your_dict)` to use a custom
|
||||||
dictionary (if you don't want to use the built-in dictionary at first,
|
dictionary. If you don't want to use the built-in dictionary,
|
||||||
you can disable :c:macro:`LV_IME_PINYIN_USE_DEFAULT_DICT` in ``lv_conf.h``,
|
you can disable :c:macro:`LV_IME_PINYIN_USE_DEFAULT_DICT` in ``lv_conf.h``,
|
||||||
which can save a lot of memory space).
|
which can save a lot of memory space.
|
||||||
|
|
||||||
The built-in thesaurus is customized based on the
|
The built-in thesaurus is customized based on the
|
||||||
**LV_FONT_SIMSUN_16_CJK** font library, which currently only has more
|
**LV_FONT_SIMSUN_16_CJK** font library, which currently has more
|
||||||
than ``1,000`` most common CJK radicals, so it is recommended to use
|
than 1,000 of the most common CJK radicals, so it is recommended to use a
|
||||||
custom fonts and thesaurus.
|
custom font and thesaurus.
|
||||||
|
|
||||||
In the process of using the Pinyin input method plug-in, you can change
|
In the process of using the Pinyin input method plug-in, you can change
|
||||||
the keyboard and dictionary at any time.
|
the Keyboard and dictionary at any time.
|
||||||
|
|
||||||
|
|
||||||
Custom dictionary
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
If you don't want to use the built-in Pinyin dictionary, you can use the
|
Custom Dictionary
|
||||||
custom dictionary. Or if you think that the built-in phonetic dictionary
|
*****************
|
||||||
consumes a lot of memory, you can also use a custom dictionary.
|
|
||||||
|
If you don't want to use the built-in Pinyin dictionary, or if you feel that the
|
||||||
|
built-in phonetic dictionary consumes too much memory, you can use a custom dictionary.
|
||||||
|
|
||||||
Customizing the dictionary is very simple.
|
Customizing the dictionary is very simple.
|
||||||
|
|
||||||
@@ -54,11 +55,11 @@ Then, write a dictionary in the following format.
|
|||||||
|
|
||||||
|
|
||||||
Dictionary format
|
Dictionary format
|
||||||
~~~~~~~~~~~~~~~~~
|
-----------------
|
||||||
|
|
||||||
The arrangement order of each pinyin syllable is very important. You
|
The arrangement order of each pinyin syllable is very important. If you
|
||||||
need to customize your own thesaurus according to the Hanyu Pinyin
|
need to customize your own thesaurus according to the Hanyu Pinyin
|
||||||
syllable table. You can read
|
syllable table, you can read
|
||||||
`here <https://baike.baidu.com/item/%E6%B1%89%E8%AF%AD%E6%8B%BC%E9%9F%B3%E9%9F%B3%E8%8A%82/9167981>`__
|
`here <https://baike.baidu.com/item/%E6%B1%89%E8%AF%AD%E6%8B%BC%E9%9F%B3%E9%9F%B3%E8%8A%82/9167981>`__
|
||||||
to learn about the Hanyu Pinyin syllables and the syllable table.
|
to learn about the Hanyu Pinyin syllables and the syllable table.
|
||||||
|
|
||||||
@@ -78,14 +79,14 @@ Then, write your own dictionary according to the following format:
|
|||||||
{ "zuo", "昨左佐做作坐座撮琢柞"},
|
{ "zuo", "昨左佐做作坐座撮琢柞"},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
|
|
||||||
**The last item** must end with ``{null, null}``, or it will not work
|
**The last item** must be ``{null, null}``, or it will not work
|
||||||
properly.
|
properly.
|
||||||
|
|
||||||
|
|
||||||
.. _ime_pinyin_apply_new_dictionary:
|
.. _ime_pinyin_apply_new_dictionary:
|
||||||
|
|
||||||
Apply new dictionary
|
Applying a new dictionary
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
-------------------------
|
||||||
|
|
||||||
After writing a dictionary according to the above dictionary format, you
|
After writing a dictionary according to the above dictionary format, you
|
||||||
only need to call this function to set up and use your dictionary:
|
only need to call this function to set up and use your dictionary:
|
||||||
@@ -96,32 +97,36 @@ only need to call this function to set up and use your dictionary:
|
|||||||
lv_100ask_pinyin_ime_set_dict(pinyin_ime, your_pinyin_dict);
|
lv_100ask_pinyin_ime_set_dict(pinyin_ime, your_pinyin_dict);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _ime_pinyin_modes:
|
.. _ime_pinyin_modes:
|
||||||
|
|
||||||
Modes
|
Modes
|
||||||
-----
|
*****
|
||||||
|
|
||||||
The lv_ime_pinyin have the following modes:
|
lv_ime_pinyin has the following modes:
|
||||||
|
|
||||||
- :cpp:enumerator:`LV_IME_PINYIN_MODE_K26`: Pinyin 26 key input mode
|
- :cpp:enumerator:`LV_IME_PINYIN_MODE_K26`: Pinyin 26-key input mode
|
||||||
- :cpp:enumerator:`LV_IME_PINYIN_MODE_K9`: Pinyin 9 key input mode
|
- :cpp:enumerator:`LV_IME_PINYIN_MODE_K9`: Pinyin 9-key input mode
|
||||||
- :cpp:enumerator:`LV_IME_PINYIN_MODE_K9_NUMBER`: Numeric keypad mode
|
- :cpp:enumerator:`LV_IME_PINYIN_MODE_K9_NUMBER`: Numeric keypad mode
|
||||||
|
|
||||||
The ``TEXT`` modes' layout contains buttons to change mode.
|
The Keyboard's ``TEXT``-mode layout contains buttons to change mode.
|
||||||
|
|
||||||
To set the mode manually, use :cpp:expr:`lv_ime_pinyin_set_mode(pinyin_ime, mode)`.
|
To set the mode manually, use :cpp:expr:`lv_ime_pinyin_set_mode(pinyin_ime, mode)`.
|
||||||
The default mode is :cpp:enumerator:`LV_IME_PINYIN_MODE_K26`.
|
The default mode is :cpp:enumerator:`LV_IME_PINYIN_MODE_K26`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _ime_pinyin_example:
|
.. _ime_pinyin_example:
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
*******
|
||||||
|
|
||||||
.. include:: ../../examples/others/ime/index.rst
|
.. include:: ../../examples/others/ime/index.rst
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _ime_pinyin_api:
|
.. _ime_pinyin_api:
|
||||||
|
|
||||||
API
|
API
|
||||||
---
|
***
|
||||||
|
|
||||||
|
|||||||
@@ -9,18 +9,26 @@ display Unicode emoji icons in text.
|
|||||||
|
|
||||||
Supported image formats: determined by enabled LVGL :ref:`image decoders <overview_image_decoder>`.
|
Supported image formats: determined by enabled LVGL :ref:`image decoders <overview_image_decoder>`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _lv_imgfont_usage:
|
.. _lv_imgfont_usage:
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
*****
|
||||||
|
|
||||||
Enable :c:macro:`LV_USE_IMGFONT` in ``lv_conf.h``.
|
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)`.
|
To create a new *imgfont*:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
static lv_font_t * imgfont;
|
||||||
|
...
|
||||||
|
imgfont = lv_imgfont_create(height, path_cb, user_data);
|
||||||
|
|
||||||
- ``height`` Font size.
|
- ``height`` Font size.
|
||||||
- ``path_cb`` A function to get the image path of a character.
|
- ``path_cb`` A function to get the image path of a character.
|
||||||
Return ``NULL`` if no image should be shown, but the character itself.
|
Pass ``NULL`` if no image should be shown, but the character itself.
|
||||||
- ``user_data`` Pointer to user data.
|
- ``user_data`` Pointer to user data.
|
||||||
|
|
||||||
To use the *imgfont* in a label, reference it:
|
To use the *imgfont* in a label, reference it:
|
||||||
@@ -28,14 +36,18 @@ To use the *imgfont* in a label, reference it:
|
|||||||
|
|
||||||
To destroy the *imgfont* that is no longer used, use :cpp:expr:`lv_imgfont_destroy(imgfont)`.
|
To destroy the *imgfont* that is no longer used, use :cpp:expr:`lv_imgfont_destroy(imgfont)`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _lv_imgfont_example:
|
.. _lv_imgfont_example:
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
*******
|
||||||
|
|
||||||
.. include:: ../../examples/others/imgfont/index.rst
|
.. include:: ../../examples/others/imgfont/index.rst
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _lv_imgfont_api:
|
.. _lv_imgfont_api:
|
||||||
|
|
||||||
API
|
API
|
||||||
---
|
***
|
||||||
|
|||||||
@@ -4,28 +4,38 @@
|
|||||||
Monkey
|
Monkey
|
||||||
======
|
======
|
||||||
|
|
||||||
A simple monkey test. Use random input to stress test the application.
|
The Monkey module provides LVGL applications with a simple monkey test. Monkey
|
||||||
|
Testing is a technique where the user tests the application or system by providing
|
||||||
|
random inputs and checking the behavior or seeing whether the aplication or system
|
||||||
|
will crash. This module provides this service as simulated random input to stress
|
||||||
|
test an LVGL application.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _monkey_usage:
|
.. _monkey_usage:
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
*****
|
||||||
|
|
||||||
Enable :c:macro:`LV_USE_MONKEY` in ``lv_conf.h``.
|
First, enable :c:macro:`LV_USE_MONKEY` in ``lv_conf.h``.
|
||||||
|
|
||||||
First configure monkey, use :c:struct:`lv_monkey_config_t` to define the
|
Next, declare a variable (it can be local) of type :c:type:`lv_monkey_config_t` to
|
||||||
configuration structure, set the ``type`` (check :ref:`Input Devices <indev>`
|
define the configuration structure, initialize it using
|
||||||
for the supported types), and then set the
|
:cpp:expr:`lv_monkey_config_init(cfg)` then set its ``type`` member to the desired
|
||||||
range of ``period_range`` and ``input_range``, the monkey will output
|
type of :ref:`input device <indev>`, and set the ``min`` and ``max`` values for its
|
||||||
random operations at random times within this range. Call
|
``period_range`` and ``input_range`` members to set the time ranges (in milliseconds)
|
||||||
:cpp:func:`lv_monkey_create` to create monkey. Finally call
|
and input ranges the Monkey module will use to generate random input at random times.
|
||||||
:cpp:expr:`lv_monkey_set_enable(monkey, true)` to enable monkey.
|
|
||||||
|
Next, call :cpp:expr:`lv_monkey_create(cfg)` to create the Monkey. It returns a
|
||||||
|
pointer to the ``lv_monkey_t`` created.
|
||||||
|
|
||||||
|
Finally call :cpp:expr:`lv_monkey_set_enable(monkey, true)` to enable Monkey.
|
||||||
|
|
||||||
If you want to pause the monkey, call
|
If you want to pause the monkey, call
|
||||||
:cpp:expr:`lv_monkey_set_enable(monkey, false)`. To delete the monkey, call
|
:cpp:expr:`lv_monkey_set_enable(monkey, false)`. To delete it, call
|
||||||
:cpp:expr:`lv_monkey_delete(monkey)`.
|
:cpp:expr:`lv_monkey_delete(monkey)`.
|
||||||
|
|
||||||
Note that ``input_range`` has different meanings in different ``type``:
|
Note that ``input_range`` has different meanings depending on the ``type`` input device:
|
||||||
|
|
||||||
- :cpp:enumerator:`LV_INDEV_TYPE_POINTER`: No effect, click randomly within the pixels of the screen resolution.
|
- :cpp:enumerator:`LV_INDEV_TYPE_POINTER`: No effect, click randomly within the pixels of the screen resolution.
|
||||||
- :cpp:enumerator:`LV_INDEV_TYPE_ENCODER`: The minimum and maximum values of ``enc_diff``.
|
- :cpp:enumerator:`LV_INDEV_TYPE_ENCODER`: The minimum and maximum values of ``enc_diff``.
|
||||||
@@ -34,15 +44,19 @@ Note that ``input_range`` has different meanings in different ``type``:
|
|||||||
:cpp:func:`lv_indev_set_button_points` to map the key ID to the coordinates.
|
:cpp:func:`lv_indev_set_button_points` to map the key ID to the coordinates.
|
||||||
- :cpp:enumerator:`LV_INDEV_TYPE_KEYPAD`: No effect, Send random :ref:`indev_keys`.
|
- :cpp:enumerator:`LV_INDEV_TYPE_KEYPAD`: No effect, Send random :ref:`indev_keys`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _monkey_example:
|
.. _monkey_example:
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
*******
|
||||||
|
|
||||||
.. include:: ../../examples/others/monkey/index.rst
|
.. include:: ../../examples/others/monkey/index.rst
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _monkey_api:
|
.. _monkey_api:
|
||||||
|
|
||||||
API
|
API
|
||||||
---
|
***
|
||||||
|
|
||||||
|
|||||||
@@ -1,66 +1,196 @@
|
|||||||
.. _obj_id:
|
.. _widget_id:
|
||||||
|
|
||||||
=========
|
=========
|
||||||
Widget ID
|
Widget ID
|
||||||
=========
|
=========
|
||||||
|
|
||||||
LVGL provides an optional field in :cpp:type:`lv_obj_t` to store the Widget ID.
|
Widgets can optionally have identifiers added to their functionality if needed for
|
||||||
Widget ID can be used in many cases, for example, to identify the Widget.
|
the application. Exactly how that happens is designed to be flexible, and can morph
|
||||||
Or we can store a program backtrace to where the Widget is created.
|
with the needs of the application. It can even be a timestamp or other data current
|
||||||
|
at the time the Widget was created.
|
||||||
|
|
||||||
.. _obj_id_usage:
|
|
||||||
|
|
||||||
|
.. _widget_id_usage:
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
*****
|
||||||
|
|
||||||
Enable this feature by setting :c:macro:`LV_USE_OBJ_ID` to `1` in ``lv_conf.h``.
|
Enable Widget ID functionality 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 Widget when it's created.
|
Once enabled, several things change:
|
||||||
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.
|
- each Widget will now have a ``void *`` field called ``id``;
|
||||||
To use the builtin ID generator, set :c:macro:`LV_USE_OBJ_ID_BUILTIN` to `1`.
|
- these two API functions become available:
|
||||||
|
|
||||||
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)`
|
- :cpp:expr:`lv_obj_get_id(widget)`,
|
||||||
to get a string representation of the ID.
|
- :cpp:expr:`lv_obj_get_child_by_id(widget, id)`;
|
||||||
|
|
||||||
Use custom ID generator
|
- several more Widget-ID-related API functions become available if
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
:c:macro:`LV_USE_OBJ_ID_BUILTIN` is non-zero (more on this below);
|
||||||
|
- two additional configuration macros both :c:macro:`LV_OBJ_ID_AUTO_ASSIGN` and
|
||||||
|
:c:macro:`LV_USE_OBJ_ID_BUILTIN` now have meaning.
|
||||||
|
|
||||||
Set :c:macro:`LV_USE_OBJ_ID_BUILTIN` to `0` in ``lv_conf.h``.
|
|
||||||
|
|
||||||
Below APIs needed to be implemented and linked to lvgl.
|
:c:macro:`LV_OBJ_ID_AUTO_ASSIGN`
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
This macro in ``lv_conf.h`` defaults to whatever value :c:macro:`LV_USE_OBJ_ID`
|
||||||
|
equates to. You can change this if you wish. Either way, if it equates to a
|
||||||
|
non-zero value, it causes two things to happen:
|
||||||
|
|
||||||
|
- :cpp:expr:`lv_obj_assign_id(class_p, widget)` will be called at the end of each
|
||||||
|
Widget's creation, and
|
||||||
|
- :cpp:expr:`lv_obj_free_id(widget)` will be called at the end of the sequence when
|
||||||
|
each Widget is deleted.
|
||||||
|
|
||||||
|
Because of this timing, custom versions of these functions can be used according to
|
||||||
|
the below, and they can even be used like "event hooks" to implement a trace
|
||||||
|
operation that occurs when each Widget is created and deleted.
|
||||||
|
|
||||||
|
:cpp:expr:`lv_obj_assign_id(class_p, widget)`
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
This function (whether provided by LVGL or by you --- more on this below) is
|
||||||
|
responsible for assigning a value to the Widget's ``id`` field, and possibly do
|
||||||
|
other things, depending on the implementation.
|
||||||
|
|
||||||
|
:cpp:expr:`lv_obj_free_id(widget)`
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
This function (whether provided by LVGL or by you --- more on this below) is
|
||||||
|
responsible for doing the clean-up of any resources allocated by
|
||||||
|
:cpp:func:`lv_obj_assign_id()`
|
||||||
|
|
||||||
|
|
||||||
|
:c:macro:`LV_USE_OBJ_ID_BUILTIN`
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
This macro in ``lv_conf.h`` equates to ``1`` by default. You can change this if you
|
||||||
|
wish. When it equates to a non-zero value the following function implementations are
|
||||||
|
provided by LVGL:
|
||||||
|
|
||||||
|
- :cpp:expr:`lv_obj_assign_id(class_p, widget)`
|
||||||
|
- :cpp:expr:`lv_obj_free_id(widget)`
|
||||||
|
- :cpp:expr:`lv_obj_set_id(widget, id)`
|
||||||
|
- :cpp:expr:`lv_obj_stringify_id(widget, buf, len)`
|
||||||
|
- :cpp:expr:`lv_obj_id_compare(id1, id2)`
|
||||||
|
|
||||||
|
These supply the default implementation for Widget IDs, namely that for each Widget
|
||||||
|
created, :cpp:expr:`lv_obj_stringify_id(widget, buf, len)` will produce a unique
|
||||||
|
string for it. Example: if the following 6 Widgets are created in this sequence:
|
||||||
|
|
||||||
|
- Screen
|
||||||
|
- Label
|
||||||
|
- Button
|
||||||
|
- Label
|
||||||
|
- Label
|
||||||
|
- Image
|
||||||
|
|
||||||
|
the strings produced by :cpp:expr:`lv_obj_stringify_id(widget, buf, len)` would be
|
||||||
|
|
||||||
|
- obj1
|
||||||
|
- label1
|
||||||
|
- btn1
|
||||||
|
- label2
|
||||||
|
- label3
|
||||||
|
- image1
|
||||||
|
|
||||||
|
respectively.
|
||||||
|
|
||||||
|
|
||||||
|
.. _widget_id_custom_generator:
|
||||||
|
|
||||||
|
Using a custom ID generator
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
If you wish, you can provide custom implementations for several Widget-ID related
|
||||||
|
functions. You do this by first setting :c:macro:`LV_USE_OBJ_ID_BUILTIN` to `0` in
|
||||||
|
``lv_conf.h``.
|
||||||
|
|
||||||
|
You will then need to provide implementations for the following functions (and link
|
||||||
|
them with LVGL):
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
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);
|
const char * lv_obj_stringify_id(lv_obj_t * widget, char * buf, uint32_t len);
|
||||||
int lv_obj_id_compare(void * id1, void * id2);
|
int lv_obj_id_compare(const void * id1, const void * id2);
|
||||||
|
|
||||||
|
If :c:macro:`LV_OBJ_ID_AUTO_ASSIGN` equates to a non-zero value (or if you otherwise
|
||||||
|
simply need to use them), you will also need to provide implementations for:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
If :c:macro:`LV_BUILD_TEST` equates to a non-zero value and you are including LVGL
|
||||||
|
test code in your compile (or if you otherwise simply need to use them), you
|
||||||
|
will also need to provide an implementation for:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
void lv_obj_set_id(lv_obj_t * widget, void * id);
|
||||||
|
|
||||||
|
|
||||||
:cpp:func:`lv_obj_assign_id` is called when a Widget is created. The Widget final class is passed from
|
Examples of implementations of these functions exist in ``lv_obj_id_builtin.c``, but
|
||||||
parameter ``class_p``. Note it may be different than :cpp:expr:`obj->class_p` which is the class
|
you are free to use a different design if needed.
|
||||||
currently being constructed.
|
|
||||||
|
|
||||||
: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 the passed ``widget`` to a string
|
||||||
|
representation (typically incorporating the ``id`` field) and writes it into the
|
||||||
|
buffer provided in its ``buf`` argument.
|
||||||
|
|
||||||
:cpp:func:`lv_obj_stringify_id` converts id to a string representation. The string is stored in ``buf``.
|
:cpp:func:`lv_obj_id_compare` compares 2 ``void * id`` values and returns ``0`` when
|
||||||
|
they are considered equal, and non-zero otherwise.
|
||||||
|
|
||||||
Dump Widget Tree
|
If :c:macro:`LV_OBJ_ID_AUTO_ASSIGN` equates to a non-zero value,
|
||||||
~~~~~~~~~~~~~~~~
|
:cpp:func:`lv_obj_assign_id` is called when a Widget is created. It is responsible
|
||||||
|
for assigning a value to the Widget's ``id`` field. A pointer to the Widget's final
|
||||||
|
class is passed in its ``class_p`` argument in case it is needed for determining the
|
||||||
|
value for the ``id`` field, or for other possible needs related to your design for
|
||||||
|
Widget IDs. Note that this pointer may be different than :cpp:expr:`widget->class_p`
|
||||||
|
which is the class of the Widget currently being created.
|
||||||
|
|
||||||
Use API ``lv_obj_dump_tree(lv_obj_t * widget, int depth)`` to dump the Widget Tree.
|
If :c:macro:`LV_OBJ_ID_AUTO_ASSIGN` equates to a non-zero value,
|
||||||
It will walk through all children and print the Widget ID together with Widget address.
|
:cpp:func:`lv_obj_free_id` is called when a Widget is deleted. It needs to perform
|
||||||
|
the clean-up for any resources allocated by :cpp:func:`lv_obj_assign_id`.
|
||||||
|
|
||||||
|
|
||||||
|
Dumping a Widget Tree
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Regardless of the state of any of the above macros, the function
|
||||||
|
:cpp:expr:`lv_obj_dump_tree(widget)` provides a "dump" of the Widget Tree for the
|
||||||
|
specified Widget (that Widget plus all its children recursively) using the
|
||||||
|
currently-configured method used by the :c:macro:`LV_LOG_USER` macro. If NULL is
|
||||||
|
passed instead of a pointer to a "root" Widget, the dump will include the Widget Tree
|
||||||
|
for all :ref:`Screens`, for all :ref:`Displays <display>` in the system.
|
||||||
|
|
||||||
|
For :c:macro:`LV_LOG_USER` to produce output, the following needs to be true in
|
||||||
|
``lv_conf.h``:
|
||||||
|
|
||||||
|
- :c:macro:`LV_USE_LOG` must equate to a non-zero value
|
||||||
|
- :c:macro:`LV_LOG_LEVEL` <= :c:macro:`LV_LOG_LEVEL_USER`
|
||||||
|
|
||||||
|
It will recursively walk through all that Widget's children (starting with the Widget
|
||||||
|
itself) and print the Widget's parent's address, the Widget's address, and if
|
||||||
|
:c:macro:`LV_USE_OBJ_ID` equates to a non-zero value, will also print the output of
|
||||||
|
:cpp:func:`lv_obj_stringify_id` for that Widget.
|
||||||
|
|
||||||
|
This can be useful in the event of a UI crash. From that log you can examine the
|
||||||
|
state of the Widget Tree when :cpp:expr:`lv_obj_dump_tree(widget)` was called.
|
||||||
|
|
||||||
|
For example, if a pointer to a deleted Widget is stored in a Timer's
|
||||||
|
:cpp:expr:`timer->user_data` field when the timer event callback is called, attempted
|
||||||
|
use of that pointer will likly cause a crash because the pointer is not valid any
|
||||||
|
more. However, a timely dump of the Widget Tree right before that point will show
|
||||||
|
that the Widget no longer exists.
|
||||||
|
|
||||||
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.
|
|
||||||
Timer callback will crash because of accessing wild pointer.
|
|
||||||
From the dump log we can clearly see that the obj does not exist.
|
|
||||||
|
|
||||||
Find child by ID
|
Find child by ID
|
||||||
~~~~~~~~~~~~~~~~
|
----------------
|
||||||
|
|
||||||
|
:cpp:expr:`lv_obj_get_child_by_id(widget, id)` will perform a recursive walk through
|
||||||
|
``widget``\ 's children and return the first child encountered having the given 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.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user