feat(docs): proofread and edited docs (#7144)

This commit is contained in:
Victor Wheeler 2024-10-27 08:07:06 -06:00 committed by GitHub
parent b1dc25a9af
commit 64a2f3ac5c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 309 additions and 168 deletions

View File

@ -17,7 +17,7 @@ It's huge release with many interesting updates:
- SDL renderer improvements (supporting all draw task types and improving speed)
- Radial, Conic, and Skew `gradients supported <https://docs.lvgl.io/master/details/base-widget/styles/style.html#metallic-knob-with-conic-gradient>`__ by software rendering and VG-Lite
- :ref:`qnx` and :ref:`mqx` support
- :ref:`Mouse hover handling <styles_states>`
- :ref:`Mouse hover handling <style_states>`
- :ref:`lv_lottie` support
- CI tests for UEFI builds

View File

@ -38,9 +38,9 @@ Units
.. _coord_boxing_model:
.. _boxing_model:
Boxing model
Boxing Model
************
LVGL follows CSS's `border-box <https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing>`__
@ -164,11 +164,11 @@ Alignment
Inside parent widget
~~~~~~~~~~~~~~~~~~~~
In many cases it is more convenient to tell LVGL to align your object relative to
an "anchor point" in its parent *other* than its upper left corner. To establish
that "anchor point", call :cpp:expr:`lv_obj_set_align(widget, LV_ALIGN_...)`. After
that call, that "anchor point" will be remembered until another one is established.
an "anchor" in its parent *other* than its upper left corner. To establish
that "anchor", call :cpp:expr:`lv_obj_set_align(widget, LV_ALIGN_...)`. After
that call, that "anchor" will be remembered until another one is established.
In other words, every futire x and y setting for that Widget will be relative to the
that "anchor point".
that "anchor".
Example: Position Widget (10,20) px relative to the center of its parent:
@ -180,7 +180,7 @@ Example: Position Widget (10,20) px relative to the center of its parent:
/* Or combine the above in one function... */
lv_obj_align(widget, LV_ALIGN_CENTER, 10, 20);
9 convenient "anchor points" can be used with these functions:
9 convenient "anchors" can be used with these functions:
- :cpp:enumerator:`LV_ALIGN_TOP_LEFT`
- :cpp:enumerator:`LV_ALIGN_TOP_MID`
@ -210,7 +210,7 @@ children is updated automatically.
Relative to another Widget
~~~~~~~~~~~~~~~~~~~~~~~~~~
Alternately, you can choose an "anchor point" on another Widget.
Alternately, you can choose an "anchor" on another Widget.
.. code-block:: c
@ -238,10 +238,10 @@ Example: to horizontally center a label 10 pixels above a button:
lv_obj_align_to(label, btn, LV_ALIGN_OUT_TOP_MID, 0, -10);
Note that, unlike with :cpp:func:`lv_obj_align`, :cpp:func:`lv_obj_align_to`
does not remember the "anchor point" used, and so will not automatically reposition
does not remember the "anchor" used, and so will not automatically reposition
the aligned widget if the reference widget later moves.
The following illustration shows the meaning of each "anchor point" mentioned above.
The following illustration shows the meaning of each "anchor" mentioned above.
.. image:: /misc/align.png

View File

@ -4,39 +4,54 @@
Flex
====
Overview
********
The Flexbox (or Flex for short) is a subset of `CSS Flexbox <https://css-tricks.com/snippets/css/a-guide-to-flexbox/>`__.
The Flexbox (or Flex for short) is a subset of `CSS Flexbox`_ behaviors.
It can arrange items into rows or columns (tracks), handle wrapping,
adjust the spacing between the items and tracks, handle *grow* to make
the item(s) fill the remaining space with respect to min/max width and
It can arrange items (child Widgets) into rows or columns (tracks), handle wrapping,
adjust the spacing between items and tracks, handle *grow* to make
item(s) fill remaining space with respect to min/max width and
height.
To make a Widget flex container call
To make a Widget a Flex container call
:cpp:expr:`lv_obj_set_layout(widget, LV_LAYOUT_FLEX)`.
Note that the flex layout feature of LVGL needs to be globally enabled
Note that the Flex layout feature of LVGL needs to be globally enabled
with :c:macro:`LV_USE_FLEX` in ``lv_conf.h``.
Terms
*****
- **tracks**: the rows or columns
- **main direction**: row or column, the direction in which the items are
placed
- **cross direction**: perpendicular to the main direction
- **wrap**: if there is no more space in the track a new track is started
- **grow**: if set on an item it will grow to fill the remaining space on
- **tracks**: rows or columns
- **main direction**: row or column, the direction in which multiple items are
placed first
- **cross direction**: the direction perpendicular to the **main direction**
- **wrap**: if there is no more space in the track, a new track is started
- **grow**: if set on an item it will "grow" to fill the remaining space in
the track. The available space will be distributed among items
respective to their grow value (larger value means more space)
- **gap**: the space between the rows and columns or the items on a track
- **gap**: the space between rows and columns or the items on a track
Simple interface
See `CSS Flexbox`_ for illustrations showing the meanings of these terms.
Simple Interface
****************
With the following functions you can set a Flex layout on any parent.
Use the following functions to set and control the Flex layout on any parent Widget.
.. note::
The parent Widget must be a Flex container for these styles to take effect.
The functions below cause the parent Widget to become a Flex container if it is
not already.
.. _flex_flow:
@ -56,68 +71,83 @@ The possible values for ``flex_flow`` are:
- :cpp:enumerator:`LV_FLEX_FLOW_ROW_WRAP_REVERSE`: Place the children in a row with wrapping but in reversed order
- :cpp:enumerator:`LV_FLEX_FLOW_COLUMN_WRAP_REVERSE`: Place the children in a column with wrapping but in reversed order
These values cause the Widget's layout behavior to model `CSS Flexbox`_ behavior
by combining flex-direction_ and flex-wrap_ as defined under flex-flow_.
.. _flex_align:
Flex align
----------
To manage the placement of the children use
To manage placement of children use
:cpp:expr:`lv_obj_set_flex_align(widget, main_place, cross_place, track_cross_place)`
which makes the parent Widget model the Flex-container behavior defined `here
<justify-content_>`_.
- ``main_place`` determines how to distribute the items in their track
on the main axis. E.g. flush the items to the right on :cpp:enumerator:`LV_FLEX_FLOW_ROW_WRAP`. (It's called
``justify-content`` in CSS)
on the main axis. E.g. flush the items to the right on
:cpp:enumerator:`LV_FLEX_FLOW_ROW_WRAP`. (It's called
justify-content_ in CSS.)
- ``cross_place`` determines how to distribute the items in their track
on the cross axis. E.g. if the items have different height place them
to the bottom of the track. (It's called ``align-items`` in CSS)
on the cross axis. E.g. if the items have different height, align them
against the bottom of the track. (It's called align-items_ in CSS.)
- ``track_cross_place`` determines how to distribute the tracks (It's
called ``align-content`` in CSS)
called align-content_ in CSS.)
The possible values are:
- :cpp:enumerator:`LV_FLEX_ALIGN_START`: means left on a horizontally and top vertically (default)
- :cpp:enumerator:`LV_FLEX_ALIGN_END`: means right on a horizontally and bottom vertically
- :cpp:enumerator:`LV_FLEX_ALIGN_CENTER`: simply center
- :cpp:enumerator:`LV_FLEX_ALIGN_START`: means left when direction is horizontal, top when vertical (default)
- :cpp:enumerator:`LV_FLEX_ALIGN_END`: means right when direction is horizontal, bottom when vertical
- :cpp:enumerator:`LV_FLEX_ALIGN_CENTER`: simply center with respect to direction
- :cpp:enumerator:`LV_FLEX_ALIGN_SPACE_EVENLY`: items are distributed so
that the spacing between any two items (and the space to the edges) is
equal. Does not apply to ``track_cross_place``.
- :cpp:enumerator:`LV_FLEX_ALIGN_SPACE_AROUND`: items are evenly
distributed in the track with equal space around them. Note that
visually the spaces aren't equal, since all the items have equal space
on both sides. The first item will have one unit of space against the
container edge, but two units of space between the next item because
that next item has its own spacing that applies. Not applies to
visually the spaces are not equal since all the items have equal space
on both sides. This makes the space between items double the space
between edge items and the container's edge. Does not apply to
``track_cross_place``.
- :cpp:enumerator:`LV_FLEX_ALIGN_SPACE_BETWEEN`: items are evenly distributed in
the track: first item is on the start line, last item on the end line. Not applies to ``track_cross_place``.
the track with no space before and after first and last items. Does not apply
to ``track_cross_place``.
See justify-content_, align-items_ and align-content_ for illustrations of these values.
.. _flex_grow:
Flex grow
---------
Flex grow can be used to make one or more children fill the available
space on the track. When more children have grow parameters, the
available space will be distributed proportionally to the grow values.
For example, there is 400 px remaining space and 4 Widgets with grow:
Flex grow can be used to make one or more children fill available space in the track.
When more than one child Widget have non-zero grow values, all available space will
be distributed in proportion to their respective grow values. For example, if there
is 400 px space remaining and 3 child Widgets with non-zero grow values:
- ``A`` with grow = 1
- ``B`` with grow = 1
- ``C`` with grow = 2
``A`` and ``B`` will have 100 px size, and ``C`` will have 200 px size.
``A`` and ``B`` will occupy 100 px, and ``C`` will occupy 200 px.
Flex grow can be set on a child with
:cpp:expr:`lv_obj_set_flex_grow(child, value)`. ``value`` needs to be >
Flex grow can be set on a child Widget with
:cpp:expr:`lv_obj_set_flex_grow(child, value)`. ``value`` needs to be >=
1 or 0 to disable grow on the child.
See flex-grow_ for an illustration of this behavior.
.. _flex_style:
Style interface
Style Interface
***************
All the Flex-related values are style properties under the hood and you
can use them similarly to any other style property.
All Flex-related values are style properties under the hood so you
can use them as you would any other style property.
The following flex related style properties exist:
@ -133,18 +163,20 @@ Internal padding
----------------
To modify the minimum space flexbox inserts between Widgets, the
following properties can be set on the flex container style:
following functions can be used to set the flex container padding style:
- ``pad_row`` Sets the padding between the rows.
- :cpp:func:`lv_style_set_pad_row` sets padding between rows.
- ``pad_column`` Sets the padding between the columns.
- :cpp:func:`lv_style_set_pad_column` sets padding between columns.
These can for example be used if you don't want any padding between your
These can, for example, be used if you do not want any padding between
Widgets: :cpp:expr:`lv_style_set_pad_column(&row_container_style, 0)`
.. _flex_other:
Other features
Other Features
**************
RTL
@ -165,13 +197,34 @@ New track
You can force Flex to put an item into a new line with
:cpp:expr:`lv_obj_add_flag(child, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK)`.
.. _flex_example:
Example
*******
.. admonition:: Further Reading
Learn more about `CSS Flexbox`_.
.. _flex_examples:
Examples
********
.. include:: ../../../examples/layouts/flex/index.rst
.. Hyperlinks
.. _css flexbox: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
.. _flex-direction: https://css-tricks.com/snippets/css/a-guide-to-flexbox/#aa-flex-direction
.. _flex-wrap: https://css-tricks.com/snippets/css/a-guide-to-flexbox/#aa-flex-wrap
.. _flex-flow: https://css-tricks.com/snippets/css/a-guide-to-flexbox/#aa-flex-flow
.. _justify-content: https://css-tricks.com/snippets/css/a-guide-to-flexbox/#aa-justify-content
.. _align-items: https://css-tricks.com/snippets/css/a-guide-to-flexbox/#aa-align-items
.. _align-content: https://css-tricks.com/snippets/css/a-guide-to-flexbox/#aa-align-content
.. _flex-grow: https://css-tricks.com/snippets/css/a-guide-to-flexbox/#aa-flex-grow
.. _flex_api:
API

View File

@ -4,35 +4,48 @@
Grid
====
Overview
********
The Grid layout is a subset of `CSS Grid <https://css-tricks.com/snippets/css/complete-guide-grid/>`__.
The Grid layout is a subset of `CSS Grid`_ layout.
It can arrange items into a 2D "table" that has rows or columns
(tracks). The item can span through multiple columns or rows. The
track's size can be set in pixel, to the largest item
(:c:macro:`LV_GRID_CONTENT`) or in "Free unit" (FR) to distribute the free
space proportionally.
It can arrange items (child Widgets) into a 2D "table" that has rows and columns
(tracks). An item can span multiple columns or rows. The
track's size can be set in pixels, to the largest item
(:c:macro:`LV_GRID_CONTENT`), or to a fraction of the available free space
(i.e. `Free [FR] Units <fr units_>`_) to distribute free space proportionally.
To make a Widget a grid container call :cpp:expr:`lv_obj_set_layout(widget, LV_LAYOUT_GRID)`.
To make a Widget a Grid container call :cpp:expr:`lv_obj_set_layout(widget, LV_LAYOUT_GRID)`.
Note that the grid layout feature of LVGL needs to be globally enabled
Note that the Grid layout feature of LVGL needs to be globally enabled
with :c:macro:`LV_USE_GRID` in ``lv_conf.h``.
Terms
*****
- **tracks**: the rows or columns
- **free unit (FR)**: if set on track's size is set in ``FR`` it will grow
to fill the remaining space on the parent.
- **gap**: the space between the rows and columns or the items on a track
- **tracks**: rows or columns
- **free (FR) units**: if a track's size is set in ``FR units`` it will grow
to fill the remaining space in the parent Widget (container), in proportion with
other tracks that have non-zero FR-unit values.
- **gap**: the space between rows and columns or the items on a track
Simple interface
Simple Interface
****************
With the following functions you can easily set a Grid layout on any
parent.
With the following functions you can cause any parent Widget to have Grid-layout behaviors.
.. note::
As with Flex containers, the parent Widget must be a Grid container for these
styles to take effect. The functions below cause the parent Widget to become a
Grid container if it is not already.
.. _grid_descriptors:
@ -47,62 +60,61 @@ For example:
.. code-block:: c
static int32_t column_dsc[] = {100, 400, LV_GRID_TEMPLATE_LAST}; /* 2 columns with 100 and 400 ps width */
static int32_t row_dsc[] = {100, 100, 100, LV_GRID_TEMPLATE_LAST}; /* 3 100 px tall rows */
static int32_t column_dsc[] = {100, 400, LV_GRID_TEMPLATE_LAST}; /* 2 columns with 100- and 400-px width */
static int32_t row_dsc[] = {100, 100, 100, LV_GRID_TEMPLATE_LAST}; /* 3 100-px tall rows */
To set the descriptors on a parent use
:cpp:expr:`lv_obj_set_grid_dsc_array(widget, col_dsc, row_dsc)`.
Besides simple settings the size in pixel you can use two special
Besides settings the sizes in pixels, you can use two special
values:
- :c:macro:`LV_GRID_CONTENT` set the size to fit the largest child on this track
- :cpp:expr:`LV_GRID_FR(X)` tell what portion of the remaining space
should be used by this track. Larger value means larger space.
- :c:macro:`LV_GRID_CONTENT` sets size to fit the largest child on this track
- :cpp:expr:`LV_GRID_FR(X)` determines what portion of the remaining space
should be used by this track. Larger values means larger space.
.. _grid_items:
Grid items
----------
By default, the children are not added to the grid. They need to be
By default, a Widget's children are not added to the grid. They need to be
added manually to a cell.
To do this call
:cpp:expr:`lv_obj_set_grid_cell(child, column_align, column_pos, column_span, row_align, row_pos, row_span)`.
``column_align`` and ``row_align`` determine how to align the children
in its cell. The possible values are:
``column_align`` and ``row_align`` determine how to align the child Widget
in its cell. Possible values are:
- :cpp:enumerator:`LV_GRID_ALIGN_START`: means left on a horizontally and top vertically (default)
- :cpp:enumerator:`LV_GRID_ALIGN_END`: means right on a horizontally and bottom vertically
- :cpp:enumerator:`LV_GRID_ALIGN_START`: means left when direction is horizontal and top when vertical (default)
- :cpp:enumerator:`LV_GRID_ALIGN_END`: means right when direction is horizontal and bottom when vertical
- :cpp:enumerator:`LV_GRID_ALIGN_CENTER`: simply center ``column_pos`` and ``row_pos``
means the zero based index of the cell into the item should be placed.
means the zero-based index of the cell in which the item should be placed.
``column_span`` and ``row_span`` means how many tracks should the item
involve from the start cell. Must be ``>= 1``.
``column_span`` and ``row_span`` means how many tracks should be occupied
from the start cell. Must be ``>= 1``.
.. _grid_align:
Grid align
----------
If there are some empty space the track can be aligned several ways:
If there is some empty space, items (Widgets) in Grid tracks can be aligned in several ways:
- :cpp:enumerator:`LV_GRID_ALIGN_START`: means left on a horizontally and top vertically. (default)
- :cpp:enumerator:`LV_GRID_ALIGN_END`: means right on a horizontally and bottom vertically
- :cpp:enumerator:`LV_GRID_ALIGN_START`: means left when direction is horizontal and top when vertical. (default)
- :cpp:enumerator:`LV_GRID_ALIGN_END`: means right when direction is horizontal and bottom when vertical
- :cpp:enumerator:`LV_GRID_ALIGN_CENTER`: simply center
- :cpp:enumerator:`LV_GRID_ALIGN_SPACE_EVENLY`: items are distributed so that the spacing
between any two items (and the space to the edges) is equal. Not applies to ``track_cross_place``.
- :cpp:enumerator:`LV_GRID_ALIGN_SPACE_AROUND`: items are
evenly distributed in the track with equal space around them. Note that
visually the spaces aren't equal, since all the items have equal space
on both sides. The first item will have one unit of space against the
container edge, but two units of space between the next item because
that next item has its own spacing that applies. Not applies to ``track_cross_place``.
on both sides. This makes the space between items double the space
between edge items and the container's edge. Does not apply to ``track_cross_place``.
- :cpp:enumerator:`LV_GRID_ALIGN_SPACE_BETWEEN`: items are
evenly distributed in the track: first item is on the start line, last
item on the end line. Not applies to ``track_cross_place``.
evenly distributed in the track with first and last items next to container's edges.
Does not apply to ``track_cross_place``.
To set the track's alignment use
:cpp:expr:`lv_obj_set_grid_align(widget, column_align, row_align)`.
@ -112,28 +124,38 @@ To set the track's alignment use
Sub grid
--------
If you set the column and/or row grid descriptors of a widget to ``NULL`` it will use the grid descriptor(s) from it's parent.
For example if you create a grid item on 2..6 columns and 1..3 rows of the parent,
the grid item will see 5 columns and 4 rows with the corresponding track size from the parent.
If you set the column and/or row grid descriptors of a widget to ``NULL`` it will use
the grid descriptor(s) from it's parent.
This way even if a wrapper item is used on the grid and can be made "transparent" from the grid's point of view.
For example if you create a grid item that spans columns 2..6 columns and rows 1..3
of the grid, the grid item will occupy 5 columns and 4 rows with the corresponding
track size from the parent Grid container.
This way even if a wrapper item is used in the grid, it can be made "transparent"
from the grid's point of view.
Limitations:
- The sub grid is resolved only in one level depth. That is a grid can have a sub grid children, but a sub grid can't have another sub grid.
- ``LV_GRID_CONTENT`` tracks on the are not handled in the sub grid, only in the its own grid.
- The sub-grid is resolved only to a depth of 1 level. That is, a grid can have a
sub-grid child, but that sub-grid cannot have another sub-grid.
- ``LV_GRID_CONTENT`` tracks on the grid are not handled in the sub-grid, only in its
own grid.
The sub-grid feature works the same as in CSS. For further information, see
`CSS Subgrid`_.
The sub grid feature works the same as in CSS. For further reference see `this description <https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Subgrid>`__.
.. _grid_style:
Style interface
Style Interface
***************
All the Grid related values are style properties under the hood and you
can use them similarly to any other style properties.
All the Grid-related values are style properties under the hood so you
can use them as you would any other style property.
The following Grid related style properties exist:
The following Grid-related style properties exist:
- :cpp:enumerator:`GRID_COLUMN_DSC_ARRAY`
- :cpp:enumerator:`GRID_ROW_DSC_ARRAY`
@ -154,8 +176,11 @@ Internal padding
To modify the minimum space Grid inserts between Widgets, the following
properties can be set on the Grid container style:
- ``pad_row`` Sets the padding between the rows.
- ``pad_column`` Sets the padding between the columns.
- :cpp:func:`lv_style_set_pad_row` sets padding between rows.
- :cpp:func:`lv_style_set_pad_column` sets padding between columns.
.. _grid_other:
@ -171,6 +196,15 @@ swapped. I.e. ``START`` will mean right-most.
The columns will be placed from right to left.
.. admonition:: Further Reading
- Learn more about `CSS Grid`_ layout.
- Learn more about `CSS Subgrid`_ layout.
.. _grid_examples:
Example
@ -178,6 +212,15 @@ Example
.. include:: ../../../examples/layouts/grid/index.rst
.. Hyperlinks
.. _css grid: https://css-tricks.com/snippets/css/complete-guide-grid/
.. _fr units: https://css-tricks.com/introduction-fr-css-unit/
.. _css subgrid: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Subgrid
.. _grid_api:
API

View File

@ -4,20 +4,20 @@
Style Details
=============
*Styles* are used to set the appearance of Widgets. Styles in lvgl are
Styles are used to set the appearance of Widgets. Styles in lvgl are
heavily inspired by CSS. The concept in a nutshell is that a
style is an :cpp:type:`lv_style_t` variable which can hold properties like
border width, font, text color and so on. It's similar to a ``class`` in CSS.
- Styles can be assigned to Widgets to change their appearance. Upon
assignment, the target part (*pseudo-element* in CSS) and target state
(*pseudo class*) can be specified. For example one can add
assignment, the target part (pseudo-element_ in CSS) and target state
(pseudo-class_ in CSS) can be specified. For example one can add
``style_blue`` to the knob of a slider when it's in pressed state.
- The same style can be used by any number of Widgets.
- Styles can be cascaded which means multiple styles may be assigned to a Widget and
each style can have different properties. Therefore, not all properties
have to be specified in a style. LVGL will search for a property until a
style defines it or use a default if it's not specified by any of the
style defines it or use a default value if it's not specified by any of the
styles. For example ``style_btn`` can result in a default gray button
and ``style_btn_red`` can add only a ``background-color=red`` to
overwrite the background color.
@ -25,11 +25,13 @@ border width, font, text color and so on. It's similar to a ``class`` in CSS.
is specified in two styles the newest style in the Widget will be used.
- Some properties (e.g. text color) can be inherited from a parent(s) if it's not specified in a Widget.
- Widgets can also have local styles with higher precedence than "normal" styles.
- Unlike CSS (where pseudo-classes describe different states, e.g. ``:focus``),
- Unlike CSS (where pseudo-classes_ describe different states, e.g. ``:focus``),
in LVGL a property is assigned to a given state.
- Transitions can be applied when the Widget changes state.
.. _styles_states:
.. _style_states:
States
******
@ -60,8 +62,9 @@ property will be used. Typically this means the property with
:cpp:enumerator:`LV_STATE_DEFAULT` is used.˛ If the property is not set even for the
default state the default value will be used. (See later)
But what does the "best matching state's property" really mean? States
have a precedence which is shown by their value (see in the above list).
What does the "best matching state's property" mean?
----------------------------------------------------
States have a precedence which is shown by their value (see in the above list).
A higher value means higher precedence. To determine which state's
property to use let's take an example. Imagine the background color is
defined like this:
@ -93,15 +96,15 @@ defined like this:
Some practical notes:
- The precedence (value) of states is quite intuitive, and it's something the
user would expect naturally. E.g. if a Widget has focus the user will still
user would expect naturally. Example: if a Widget has focus the user will still
want to see if it's pressed, therefore the pressed state has a higher
precedence. If the focused state had a higher precedence it would overwrite
the pressed color.
- If you want to set a property for all states (e.g. red background color)
just set it for the default state. If the Widget can't find a property
for its current state it will fall back to the default state's property.
- Use ORed states to describe the properties for complex cases. (E.g.
pressed + checked + focused)
- Use ORed states to describe the properties for complex cases (e.g.
pressed + checked + focused).
- It might be a good idea to use different
style elements for different states. For example, finding background
colors for released, pressed, checked + pressed, focused, focused +
@ -109,9 +112,11 @@ Some practical notes:
Instead, for example, use the background color for pressed and checked
states and indicate the focused state with a different border color.
.. _styles_cascading:
Cascading styles
.. _style_cascading:
Cascading Styles
****************
It's not required to set all the properties in one style. It's possible
@ -138,7 +143,9 @@ style (red). When the button is pressed the light-gray color is a better
match because it describes the current state perfectly, so the button
will be light-gray.
.. _styles_inheritance:
.. _style_inheritance:
Inheritance
***********
@ -147,12 +154,14 @@ Some properties (typically those related to text) can be inherited from
the parent Widget's styles. Inheritance is applied only if the given
property is not set in the Widget's styles (even in default state). In
this case, if the property is inheritable, the property's value will be
searched in the parents until a Widget specifies a value for the
searched up the parent hierarchy until a Widget specifies a value for the
property. The parents will use their own state to determine the value.
So if a button is pressed, and the text color comes from here, the
So if a button is pressed, and the text color comes from a parent, the
pressed text color will be used.
.. _styles_parts:
.. _style_parts:
Parts
*****
@ -172,16 +181,18 @@ The following predefined parts exist in LVGL:
For example a :ref:`Slider <lv_slider>` has three parts:
- Background
- Main (background)
- Indicator
- Knob
This means all three parts of the slider can have their own styles. See
later how to add styles to Widgets and parts.
.. _styles_initialize:
Initialize styles and set/get properties
.. _style_initialize:
Initialize Styles and Set/Get Properties
****************************************
Styles are stored in :cpp:type:`lv_style_t` variables. Style variables should be
@ -224,7 +235,8 @@ To get a property's value from a style:
do_something(v.color);
}
:cpp:union:`lv_style_value_t` has 3 fields:
:cpp:union:`lv_style_value_t` has 3 fields, only one of which will apply, depending
on the type of property it is applied to:
- :cpp:member:`num`: for integer, boolean and opacity properties
- :cpp:member:`color`: for color properties
@ -251,13 +263,15 @@ Styles can be built as ``const`` as well to save RAM:
Later ``const`` style can be used like any other style but (obviously)
new properties cannot be added.
.. _styles_add_remove:
.. _style_add_remove:
Add and remove styles to a widget
*********************************
A style on its own is not that useful. It must be assigned to a Widget
to take effect.
A style on its own has no effect until it is added (assigned) to a Widget.
Add styles
----------
@ -287,8 +301,8 @@ To replace a specific style of a Widget use
:cpp:expr:`lv_obj_replace_style(widget, old_style, new_style, selector)`. This
function will only replace ``old_style`` with ``new_style`` if the
``selector`` matches the ``selector`` used in ``lv_obj_add_style``. Both
styles, i.e. ``old_style`` and ``new_style``, must not be ``NULL`` (for
adding and removing separate functions exist). If the combination of
``old_style`` and ``new_style`` must not be ``NULL``. Separate functions exist for
adding and removing styles. If the combination of
``old_style`` and ``selector`` exists multiple times in ``obj``\ 's
styles, all occurrences will be replaced. The return value of the
function indicates whether at least one successful replacement took
@ -314,8 +328,8 @@ To remove specific styles use
the :cpp:enumerator:`LV_STATE_ANY` and :cpp:enumerator:`LV_PART_ANY` values to remove the style from
any state or part.
Report style changes
--------------------
Reporting style changes
-----------------------
If a style which is already assigned to a Widget changes (i.e. a
property is added or changed), the Widgets using that style should be
@ -331,23 +345,28 @@ notified. There are 3 options to do this:
when needed, call :cpp:expr:`lv_obj_report_style_change(&style)`. If ``style``
is ``NULL`` all Widgets will be notified about a style change.
Get a property's value on a Widget
-----------------------------------
Get a style property's value on a Widget
----------------------------------------
To get a final value of property
To get the final value of a style's property considering
- considering cascading, inheritance, local styles and transitions (see below)
- property get functions like this can be used: ``lv_obj_get_style_<property_name>(widget, <part>)``.
These functions use the Widget's current state and if no better candidate exists they return a default value.
- cascading,
- inheritance,
- local styles and transitions (see below)
property "get" functions like this can be used: ``lv_obj_get_style_<property_name>(widget, <part>)``.
These functions use the Widget's current state and if no better candidate exists they return the default value.
For example:
.. code-block:: c
lv_color_t color = lv_obj_get_style_bg_color(btn, LV_PART_MAIN);
.. _styles_local:
Local styles
.. _style_local:
Local Styles
************
In addition to "normal" styles, Widgets can also store local styles.
@ -360,7 +379,7 @@ freed when the Widget is deleted. They are useful to add local
customization to a Widget.
Unlike in CSS, LVGL local styles can be assigned to states
(*pseudo-classes*) and parts (*pseudo-elements*).
(pseudo-classes_) and parts (pseudo-elements_).
To set a local property use functions like
``lv_obj_set_style_<property_name>(widget, <value>, <selector>);`` For example:
@ -370,6 +389,7 @@ To set a local property use functions like
lv_obj_set_style_bg_color(slider, lv_color_red(), LV_PART_INDICATOR | LV_STATE_FOCUSED);
.. _style_properties_overview:
Style Properties Overview
@ -381,9 +401,9 @@ For the full list of style properties click :ref:`here <style_properties>`.
Typical background properties
-----------------------------
In the documentation of the widgets you will see sentences like "The
In documentation of widgets you will see sentences like "The
widget uses the typical background properties". These "typical
background properties" are the ones related to:
background properties" are the properties being referred to:
- Background
- Border
@ -393,7 +413,11 @@ background properties" are the ones related to:
- Width and height transformation
- X and Y translation
.. _styles_transitions:
See :ref:`boxing_model` for the meanings of these terms.
.. _style_transitions:
Transitions
***********
@ -436,14 +460,16 @@ initialized and added to a style:
lv_style_set_transition(&style1, &trans1);
.. _styles_opacity_blend_modes_transformations:
Opacity, Blend modes and Transformations
.. _style_opacity_blend_modes_transformations:
Opacity, Blend Modes and Transformations
****************************************
If the ``opa``, ``blend_mode``, ``transform_angle``, or
``transform_zoom`` properties are set to their non-default value LVGL
creates a snapshot about the widget and all its children in order to
``transform_zoom`` properties are set to a non-default value LVGL
creates a snapshot of the widget and its children in order to
blend the whole widget with the set opacity, blend mode and
transformation properties.
@ -459,32 +485,36 @@ configured by the following properties in ``lv_conf.h``:
- :cpp:enumerator:`LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE`: [bytes] used if :cpp:enumerator:`LV_LAYER_SIMPLE_BUF_SIZE` couldn't be allocated.
If transformation properties were also used the layer cannot be
rendered in chunks, but one larger memory needs to be allocated. The
rendered in chunks, but one larger memory block needs to be allocated. The
required memory depends on the angle, zoom and pivot parameters, and the
size of the area to redraw, but it's never larger than the size of the
widget (including the extra draw size used for shadow, outline, etc).
If the widget can fully cover the area to redraw, LVGL creates an RGB
layer (which is faster to render and uses less memory). If the opposite
case ARGB rendering needs to be used. A widget might not cover its area
if it has radius, ``bg_opa != 255``, has shadow, outline, etc.
case ARGB rendering needs to be used, a widget might not cover its area
if it has radius, ``bg_opa < 255``, has shadow, outline, etc.
The click area of the widget is also transformed accordingly.
.. _styles_color_filter:
Color filter
.. _style_color_filter:
Color Filter
************
TODO
.. _styles_themes:
.. _style_themes:
Themes
******
Themes are a collection of styles. If there is an active theme LVGL
applies it on every created widget. This will give a default appearance
applies it to every newly-created widget. This will give a default appearance
to the UI which can then be modified by adding further styles.
Every display can have a different theme. For example, you could have a
@ -501,12 +531,15 @@ example shows how to set the "default" theme:
.. code-block:: c
lv_theme_t * th = lv_theme_default_init(display, /* Use the DPI, size, etc from this display */
LV_COLOR_PALETTE_BLUE, LV_COLOR_PALETTE_CYAN, /* Primary and secondary palette */
false, /* Light or dark mode */
&lv_font_montserrat_10, &lv_font_montserrat_14, &lv_font_montserrat_18); /* Small, normal, large fonts */
lv_theme_t * th = lv_theme_default_init(display, /* Use DPI, size, etc. from this display */
LV_COLOR_PALETTE_BLUE, /* Primary and secondary palette */
LV_COLOR_PALETTE_CYAN,
false, /* Dark theme? False = light theme. */
&lv_font_montserrat_10, /* Small, normal, large fonts */
&lv_font_montserrat_14,
&lv_font_montserrat_18);
lv_display_set_theme(display, th); /* Assign the theme to the display */
lv_display_set_theme(display, th); /* Assign theme to display */
The included themes are enabled in ``lv_conf.h``. If the default theme
is enabled by :c:macro:`LV_USE_THEME_DEFAULT` LVGL automatically initializes
@ -523,7 +556,7 @@ E.g. default theme -> custom theme -> dark theme.
:cpp:expr:`lv_theme_set_parent(new_theme, base_theme)` extends the
``base_theme`` with the ``new_theme``.
There is an example for it below.
There is an example of this below.
.. _styles_example:
@ -532,6 +565,18 @@ Examples
.. include:: ../../../examples/styles/index.rst
.. Hyperlinks
.. _pseudo-elements:
.. _pseudo-element: https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors#pseudo-classes_and_pseudo-elements
.. _pseudo-classes:
.. _pseudo-class: https://developer.mozilla.org/en-US/docs/Glossary/Pseudo-class
.. _styles_api:
API

View File

@ -144,7 +144,7 @@ the original, non-zoomed coordinates.
**IMPORTANT** The transformation of the image is independent of the
transformation properties coming from styles. (See
:ref:`here <styles_opacity_blend_modes_transformations>`). The main
:ref:`here <style_opacity_blend_modes_transformations>`). The main
differences are that pure image widget transformation
- doesn't transform the children of the image widget