Documentation / Designing

Position and layout

Anchors and offsets rather than coordinates - and what that buys you when the screen changes.

LVGL does not position objects by absolute coordinate, and neither does the designer. A widget has an alignment - one of seventeen anchors on its parent - and an X and Y offset from that anchor. Dragging on the canvas keeps the alignment and rewrites the offsets, so a widget you put bottom-right stays bottom-right when the screen size changes.

Alignment anchors

Nine are inside the parent and eight are outside it, mirroring LV_ALIGN_*:

InsideOutside
Top left · Top mid · Top rightOut top left · Out top mid · Out top right
Left mid · Center · Right midOut left mid · Out right mid
Bottom left · Bottom mid · Bottom rightOut bottom left · Out bottom mid · Out bottom right

The Out anchors place a widget relative to its parent's outside edge, which is how LVGL positions a label next to a slider it does not contain. On the canvas an out-aligned child can sit beyond its parent's box; the parent's Overflow visible flag decides whether the device draws it.

The offset is signed. Center with X=-40 is forty pixels left of centre; Bottom right with Y=-10 is ten pixels up from the bottom.

Size

Width and height are in device pixels. New widgets get a sensible default per type (a slider is 180 × 12, a switch 50 × 25); the resize handles change both, and Shift keeps the aspect. The validator warns when a widget extends beyond the screen, since anything past the edge is cut off on the device.

The alignment row

Under Geometry in the Inspector is a row of six buttons - align left, centre horizontally, align right, align top, centre vertically, align bottom. One selected widget is aligned within its parent - align left puts it against the parent's left edge, centre horizontally centres it. Several selected widgets are aligned to each other, against the bounding box of the selection, so align left lines them all up with the leftmost. With three or more selected, the distribute controls space them evenly between the first and the last, horizontally or vertically.

Z-order

Later children draw on top of earlier ones. Bring to front, Bring forward, Send backward and Send to back re-order the selection among its siblings, and the Hierarchy panel shows the result. The generator creates objects in this order, which is what sets the z-order on the device.

Nesting

Panels, containers, tab pages and - in fact - any widget can hold children. Drop a widget onto a panel to make it a child, or drag it in the Hierarchy. A child's alignment and offsets are relative to its parent, so a panel can be moved as one thing. Deleting a parent deletes its children.

Flags

The Flags section is LVGL's lv_obj_add_flag() switches. The ones people actually reach for:

FlagEffect
HiddenNot drawn and not touchable. The usual thing to toggle from an event or a binding to show and hide a panel.
ClickableReceives presses. On by default for controls, off for labels and images.
CheckableA press toggles the Checked state - how a button becomes a toggle button.
ScrollableChildren beyond the box can be scrolled to. Off makes a panel clip instead.
Event bubbleEvents are passed to the parent as well, so a panel can react to a tap on any child.
Gesture bubbleThe same for swipes - needed for a swipe on a widget to reach the screen's swipe handlers.
Ignore layoutExcludes a child from its parent's flex layout.
Overflow visibleDraws children that extend outside the parent.

The full list also includes Click focusable, Scroll elastic, Scroll momentum, Scroll one, Scroll chain (horizontal and vertical), Scroll on focus, Scroll with arrow, Snappable, Press lock, Advanced hit-test and Floating. Only flags you change from the type's default are emitted, as lv_obj_add_flag or lv_obj_remove_flag (lv_obj_clear_flag on LVGL 8).

Flex layout

Set a container's Layout to Flex and its children are arranged by LVGL rather than by their offsets - the canvas shows the same arrangement. Four settings follow:

SettingOptions
Flex flowRow, Column, Row wrap, Column wrap, Row reverse, Column reverse
Main placeStart, End, Center, Space evenly, Space around, Space between - along the flow direction
Cross placeThe same six, across it
Track placeThe same six, for how wrapped rows or columns are placed

Widgets inside a flex container keep their size but not their position; the Ignore layout flag opts one child out. Padding on the container (Style settings > Padding, including Row and Column gaps) is what spaces the items.

Grid layout

Grid emits lv_obj_set_layout(obj, LV_LAYOUT_GRID) and stops there: the column and row descriptor arrays and each child's cell are set in your own code, typically in ui_events.c after ui_init(). The canvas does not lay out a grid, so a grid container shows its children where their offsets put them.