1.. _grid:
2
3====
4Grid
5====
6
7
8
9Overview
10********
11
12The Grid layout is a subset of `CSS Grid`_ layout.
13
14It can arrange items (child Widgets) into a 2D "table" that has rows and columns
15(tracks).  An item can span multiple columns or rows. The
16track's size can be set in pixels, to the largest item
17(:c:macro:`LV_GRID_CONTENT`), or to a fraction of the available free space
18(i.e. `Free [FR] Units <fr units_>`_) to distribute free space proportionally.
19
20To make a Widget a Grid container call :cpp:expr:`lv_obj_set_layout(widget, LV_LAYOUT_GRID)`.
21
22Note that the Grid layout feature of LVGL needs to be globally enabled
23with :c:macro:`LV_USE_GRID` in ``lv_conf.h``.
24
25
26
27Terms
28*****
29
30-  **tracks**: rows or columns
31-  **free (FR) units**: if a track's size is set in ``FR units`` it will grow
32   to fill the remaining space in the parent Widget (container), in proportion with
33   other tracks that have non-zero FR-unit values.
34-  **gap**: the space between rows and columns or the items on a track
35
36
37
38Simple Interface
39****************
40
41With the following functions you can cause any parent Widget to have Grid-layout behaviors.
42
43.. note::
44
45    As with Flex containers, the parent Widget must be a Grid container for these
46    styles to take effect.  The functions below cause the parent Widget to become a
47    Grid container if it is not already.
48
49
50.. _grid_descriptors:
51
52Grid descriptors
53----------------
54
55First you need to describe the size of rows and columns. It can be done
56by declaring 2 arrays and the track sizes in them. The last element must
57be :c:macro:`LV_GRID_TEMPLATE_LAST`.
58
59For example:
60
61.. code-block:: c
62
63   static int32_t column_dsc[] = {100, 400, LV_GRID_TEMPLATE_LAST};   /* 2 columns with 100- and 400-px width */
64   static int32_t row_dsc[] = {100, 100, 100, LV_GRID_TEMPLATE_LAST}; /* 3 100-px tall rows */
65
66To set the descriptors on a parent use
67:cpp:expr:`lv_obj_set_grid_dsc_array(widget, col_dsc, row_dsc)`.
68
69Besides settings the sizes in pixels, you can use two special
70values:
71
72- :c:macro:`LV_GRID_CONTENT` sets size to fit the largest child on this track
73- :cpp:expr:`LV_GRID_FR(X)` determines what portion of the remaining space
74  should be used by this track. Larger values means larger space.
75
76.. _grid_items:
77
78Grid items
79----------
80
81By default, a Widget's children are not added to the grid. They need to be
82added manually to a cell.
83
84To do this call
85:cpp:expr:`lv_obj_set_grid_cell(child, column_align, column_pos, column_span, row_align, row_pos, row_span)`.
86
87``column_align`` and ``row_align`` determine how to align the child Widget
88in its cell.  Possible values are:
89
90- :cpp:enumerator:`LV_GRID_ALIGN_START`: means left when direction is horizontal and top when vertical (default)
91- :cpp:enumerator:`LV_GRID_ALIGN_END`: means right when direction is horizontal and bottom when vertical
92- :cpp:enumerator:`LV_GRID_ALIGN_CENTER`: simply center ``column_pos`` and ``row_pos``
93  means the zero-based index of the cell in which the item should be placed.
94
95``column_span`` and ``row_span`` means how many tracks should be occupied
96from the start cell. Must be ``>= 1``.
97
98.. _grid_align:
99
100Grid align
101----------
102
103If there is some empty space, items (Widgets) in Grid tracks can be aligned in several ways:
104
105- :cpp:enumerator:`LV_GRID_ALIGN_START`: means left when direction is horizontal and top when vertical. (default)
106- :cpp:enumerator:`LV_GRID_ALIGN_END`: means right when direction is horizontal and bottom when vertical
107- :cpp:enumerator:`LV_GRID_ALIGN_CENTER`: simply center
108- :cpp:enumerator:`LV_GRID_ALIGN_SPACE_EVENLY`: items are distributed so that the spacing
109  between any two items (and the space to the edges) is equal. Not applies to ``track_cross_place``.
110- :cpp:enumerator:`LV_GRID_ALIGN_SPACE_AROUND`: items are
111  evenly distributed in the track with equal space around them. Note that
112  visually the spaces aren't equal, since all the items have equal space
113  on both sides. This makes the space between items double the space
114  between edge items and the container's edge. Does not apply to ``track_cross_place``.
115- :cpp:enumerator:`LV_GRID_ALIGN_SPACE_BETWEEN`: items are
116  evenly distributed in the track with first and last items next to container's edges.
117  Does not apply to ``track_cross_place``.
118
119To set the track's alignment use
120:cpp:expr:`lv_obj_set_grid_align(widget, column_align, row_align)`.
121
122.. _grid_subgrid:
123
124Sub grid
125--------
126
127If you set the column and/or row grid descriptors of a widget to ``NULL`` it will use
128the grid descriptor(s) from it's parent.
129
130For example if you create a grid item that spans columns 2..6 columns and rows 1..3
131of the grid, the grid item will occupy 5 columns and 4 rows with the corresponding
132track size from the parent Grid container.
133
134This way even if a wrapper item is used in the grid, it can be made "transparent"
135from the grid's point of view.
136
137Limitations:
138
139- The sub-grid is resolved only to a depth of 1 level. That is, a grid can have a
140  sub-grid child, but that sub-grid cannot have another sub-grid.
141
142- ``LV_GRID_CONTENT`` tracks on the grid are not handled in the sub-grid, only in its
143  own grid.
144
145The sub-grid feature works the same as in CSS.  For further information, see
146`CSS Subgrid`_.
147
148
149
150.. _grid_style:
151
152Style Interface
153***************
154
155All the Grid-related values are style properties under the hood so you
156can use them as you would any other style property.
157
158The following Grid-related style properties exist:
159
160-  :cpp:enumerator:`GRID_COLUMN_DSC_ARRAY`
161-  :cpp:enumerator:`GRID_ROW_DSC_ARRAY`
162-  :cpp:enumerator:`GRID_COLUMN_ALIGN`
163-  :cpp:enumerator:`GRID_ROW_ALIGN`
164-  :cpp:enumerator:`GRID_CELL_X_ALIGN`
165-  :cpp:enumerator:`GRID_CELL_COLUMN_POS`
166-  :cpp:enumerator:`GRID_CELL_COLUMN_SPAN`
167-  :cpp:enumerator:`GRID_CELL_Y_ALIGN`
168-  :cpp:enumerator:`GRID_CELL_ROW_POS`
169-  :cpp:enumerator:`GRID_CELL_ROW_SPAN`
170
171.. _grid_padding:
172
173Internal padding
174----------------
175
176To modify the minimum space Grid inserts between Widgets, the following
177properties can be set on the Grid container style:
178
179-  :cpp:func:`lv_style_set_pad_row` sets padding between rows.
180
181-  :cpp:func:`lv_style_set_pad_column` sets padding between columns.
182
183
184
185.. _grid_other:
186
187Other features
188**************
189
190RTL
191---
192
193If the base direction of the container is set to :cpp:enumerator:`LV_BASE_DIR_RTL`,
194the meaning of :cpp:enumerator:`LV_GRID_ALIGN_START` and :cpp:enumerator:`LV_GRID_ALIGN_END` is
195swapped. I.e. ``START`` will mean right-most.
196
197The columns will be placed from right to left.
198
199
200
201.. admonition::  Further Reading
202
203    - Learn more about `CSS Grid`_ layout.
204    - Learn more about `CSS Subgrid`_ layout.
205
206
207
208.. _grid_examples:
209
210Example
211*******
212
213.. include:: ../../../examples/layouts/grid/index.rst
214
215
216..  Hyperlinks
217
218.. _css grid:     https://css-tricks.com/snippets/css/complete-guide-grid/
219.. _fr units:     https://css-tricks.com/introduction-fr-css-unit/
220.. _css subgrid:  https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Subgrid
221
222
223
224.. _grid_api:
225
226API
227***
228