diff --git a/docs/CHANGELOG.rst b/docs/CHANGELOG.rst index 5de8425de..a7402360e 100644 --- a/docs/CHANGELOG.rst +++ b/docs/CHANGELOG.rst @@ -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 `__ by software rendering and VG-Lite - :ref:`qnx` and :ref:`mqx` support -- :ref:`Mouse hover handling ` +- :ref:`Mouse hover handling ` - :ref:`lv_lottie` support - CI tests for UEFI builds diff --git a/docs/details/base-widget/coord.rst b/docs/details/base-widget/coord.rst index 2dd435f02..813ed71f7 100644 --- a/docs/details/base-widget/coord.rst +++ b/docs/details/base-widget/coord.rst @@ -38,9 +38,9 @@ Units -.. _coord_boxing_model: +.. _boxing_model: -Boxing model +Boxing Model ************ LVGL follows CSS's `border-box `__ @@ -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 diff --git a/docs/details/base-widget/layouts/flex.rst b/docs/details/base-widget/layouts/flex.rst index 37e656fa9..7b7f58b32 100644 --- a/docs/details/base-widget/layouts/flex.rst +++ b/docs/details/base-widget/layouts/flex.rst @@ -4,39 +4,54 @@ Flex ==== + + Overview ******** -The Flexbox (or Flex for short) is a subset of `CSS 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 +`_. - ``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. + +- :cpp:func:`lv_style_set_pad_column` sets padding between columns. + +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)` -- ``pad_column`` Sets the padding between the columns. -These can for example be used if you don't want any padding between your -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 diff --git a/docs/details/base-widget/layouts/grid.rst b/docs/details/base-widget/layouts/grid.rst index bc4fd6593..5c55c48a1 100644 --- a/docs/details/base-widget/layouts/grid.rst +++ b/docs/details/base-widget/layouts/grid.rst @@ -4,35 +4,48 @@ Grid ==== + + Overview ******** -The Grid layout is a subset of `CSS 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 `_) 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 `__. .. _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 diff --git a/docs/details/base-widget/styles/style.rst b/docs/details/base-widget/styles/style.rst index 521dd4647..194ba0476 100644 --- a/docs/details/base-widget/styles/style.rst +++ b/docs/details/base-widget/styles/style.rst @@ -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 ` 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_(widget, )``. - These functions use the Widget's current state and if no better candidate exists they return a default value. - For example: +- cascading, +- inheritance, +- local styles and transitions (see below) + +property "get" functions like this can be used: ``lv_obj_get_style_(widget, )``. +These functions use the Widget's current state and if no better candidate exists they return 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_(widget, , );`` 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 `. 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 diff --git a/docs/details/widgets/image.rst b/docs/details/widgets/image.rst index 45785ec29..de0faf2ad 100644 --- a/docs/details/widgets/image.rst +++ b/docs/details/widgets/image.rst @@ -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 `). The main +:ref:`here `). The main differences are that pure image widget transformation - doesn't transform the children of the image widget