Skip to main content

Layout

Layout containers hold children and handle all size negotiation between them. Every container implements Component (so it can be nested anywhere) and Layout (so the framework can walk its children for theme propagation and focus collection).

Containers

ContainerPurpose
VBox and HBoxStack children vertically or horizontally; the primary building blocks
BorderWrap a child with a configurable box border and optional title
PaddingAdd blank space around a child
ScrollViewClip a child to a viewport with vertical scrolling
GridRows × columns grid with equal cell sizes

Spacers and wrappers

TypePurpose
Spacers (VFill, HFill, VGap, HGap)Push, fill, or add fixed gaps between children
FlexChildWrap any component as a flex slot for inline use in variadic constructors
AlignChildPer-child cross-axis alignment override

Two-pass render pipeline

Every container follows the same two-pass contract:

  1. Measure — the parent calls Measure(constraint) on each child to learn its desired size. Constraint.MaxWidth / MaxHeight are the available cells; -1 means unconstrained.
  2. Render — the parent calls Render(buf, region) on each child with its allocated Region. The child draws into buf clipped to that region.

Never skip Measure before Render. Never store buf or region across frames.

AddChild vs AddFlexChild

The core sizing decision in every box layout:

  • AddChild(c) — natural size. The child takes exactly what Measure returns.
  • AddFlexChild(c, weight) — flex distribution. Leftover space is divided among flex children proportionally by weight.

See VBox and HBox for a full explanation with diagrams.

Import path

import "github.com/antoniocali/oat-latte/layout"