layout

package
v0.1.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 8, 2026 License: MIT Imports: 1 Imported by: 0

Documentation

Overview

Package layout provides the internal layout engine implementation for gogpu/ui.

This package is INTERNAL and not intended for public use. It implements constraint-based layout algorithms used by the widget system.

Architecture

The layout package provides several layout algorithms:

Constraint-Based Layout

Layout follows a constraint-passing model similar to Flutter:

  1. Parent passes constraints down to children
  2. Children compute their preferred size within constraints
  3. Children return their computed size to parent
  4. Parent positions children and computes its own size

Constraints specify minimum and maximum dimensions. A "tight" constraint forces a specific size (min == max), while a "loose" constraint allows flexibility (min = 0).

Layout Engine

The Engine manages layout passes efficiently:

  • Single-pass layout for simple hierarchies
  • Multi-pass layout for intrinsic sizing
  • Caching of layout results to avoid redundant calculations
  • Dirty tracking for incremental layout updates

Flexbox Layout

FlexContainer implements a simplified CSS Flexbox model:

  • Main axis and cross axis handling
  • flex-grow, flex-shrink for space distribution
  • justify-content: Start, End, Center, SpaceBetween, SpaceAround, SpaceEvenly
  • align-items: Start, End, Center, Stretch
  • direction: Row, Column, RowReverse, ColumnReverse
  • wrap support for flowing to multiple lines

Stack Layouts

Stack layouts are common shortcuts:

  • VStack: Vertical stack with spacing and alignment
  • HStack: Horizontal stack with spacing and alignment
  • ZStack: Overlay stack for layering widgets

Grid Layout

GridContainer provides basic grid layout:

  • Fixed or fractional column/row definitions
  • Gap between cells
  • Cell spanning (optional)

Thread Safety

Layout types are NOT thread-safe. All layout operations must occur on the main/UI thread during the Layout phase.

Usage

This package is used internally by the UI framework. Application code should use the public layout widgets instead of directly using this package.

// Internal framework usage
engine := layout.NewEngine()
flex := layout.NewFlexContainer(layout.Row, layout.JustifyStart, layout.AlignStretch)
flex.AddChild(child1, layout.FlexItem{Grow: 1})
flex.AddChild(child2, layout.FlexItem{Grow: 2})
size := engine.Layout(flex, constraints)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AlignItems

type AlignItems int

AlignItems specifies how to align children along the cross axis.

const (
	// AlignStart aligns children to the start of the cross axis.
	AlignStart AlignItems = iota
	// AlignEnd aligns children to the end of the cross axis.
	AlignEnd
	// AlignCenter centers children along the cross axis.
	AlignCenter
	// AlignStretch stretches children to fill the cross axis.
	AlignStretch
	// AlignBaseline aligns children by their baselines (text alignment).
	AlignBaseline
)

func (AlignItems) String

func (a AlignItems) String() string

String returns a string representation of align items.

type AlignSelf

type AlignSelf int

AlignSelf allows an item to override the container's AlignItems.

const (
	// AlignSelfAuto uses the container's AlignItems value.
	AlignSelfAuto AlignSelf = iota
	// AlignSelfStart aligns this item to the start.
	AlignSelfStart
	// AlignSelfEnd aligns this item to the end.
	AlignSelfEnd
	// AlignSelfCenter centers this item.
	AlignSelfCenter
	// AlignSelfStretch stretches this item.
	AlignSelfStretch
)

type Direction

type Direction int

Direction specifies the main axis direction for flex layout.

const (
	// Row arranges children horizontally from left to right.
	Row Direction = iota
	// RowReverse arranges children horizontally from right to left.
	RowReverse
	// Column arranges children vertically from top to bottom.
	Column
	// ColumnReverse arranges children vertically from bottom to top.
	ColumnReverse
)

func (Direction) IsHorizontal

func (d Direction) IsHorizontal() bool

IsHorizontal returns true if the direction is horizontal (Row or RowReverse).

func (Direction) IsReversed

func (d Direction) IsReversed() bool

IsReversed returns true if the direction is reversed.

func (Direction) String

func (d Direction) String() string

String returns a string representation of the direction.

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine manages layout passes with optional caching and dirty tracking.

The engine supports:

  • Single-pass layout for most cases
  • Multi-pass layout for intrinsic sizing
  • Caching to avoid redundant layout calculations
  • Dirty tracking for incremental updates

Engine is NOT thread-safe.

func NewEngine

func NewEngine() *Engine

NewEngine creates a new layout engine.

By default, caching is disabled. Use EnableCache to enable it.

func (*Engine) CacheSize

func (e *Engine) CacheSize() int

CacheSize returns the number of cached layout results.

func (*Engine) ClearAllDirty

func (e *Engine) ClearAllDirty()

ClearAllDirty removes all dirty flags.

func (*Engine) ClearCache

func (e *Engine) ClearCache()

ClearCache removes all cached layout results.

Call this when the layout tree structure changes significantly.

func (*Engine) ClearCacheFor

func (e *Engine) ClearCacheFor(id uint64)

ClearCacheFor removes cached results for a specific element.

func (*Engine) ClearDirty

func (e *Engine) ClearDirty(id uint64)

ClearDirty removes the dirty flag for an element.

func (*Engine) DirtyCount

func (e *Engine) DirtyCount() int

DirtyCount returns the number of dirty elements.

func (*Engine) EnableCache

func (e *Engine) EnableCache(enable bool)

EnableCache enables or disables layout caching.

When enabled, the engine caches layout results and reuses them when the same element is laid out with the same constraints.

func (*Engine) IsCacheEnabled

func (e *Engine) IsCacheEnabled() bool

IsCacheEnabled returns whether caching is enabled.

func (*Engine) IsDirty

func (e *Engine) IsDirty(id uint64) bool

IsDirty returns whether an element needs re-layout.

func (*Engine) Layout

func (e *Engine) Layout(element Layoutable, constraints geometry.Constraints) geometry.Size

Layout performs a layout pass on the given element.

This is the main entry point for layout. It delegates to the element's Layout method, optionally using cached results.

func (*Engine) LayoutTree

func (e *Engine) LayoutTree(root Layoutable, constraints geometry.Constraints) geometry.Size

LayoutTree performs layout on an entire tree of elements.

This recursively lays out all children before the parent, ensuring that child sizes are known when positioning them.

func (*Engine) LayoutWithIntrinsics

func (e *Engine) LayoutWithIntrinsics(element Layoutable, constraints geometry.Constraints) geometry.Size

LayoutWithIntrinsics performs layout with intrinsic size calculation.

This is a two-pass layout:

  1. First pass: measure intrinsic sizes with loose constraints
  2. Second pass: layout with actual constraints using intrinsic info

Use this for elements that need to know their content size before layout.

func (*Engine) MarkDirty

func (e *Engine) MarkDirty(id uint64)

MarkDirty marks an element as needing re-layout.

This invalidates the cache for the element and all ancestors. Call this when an element's content or properties change.

func (*Engine) MarkDirtyWithAncestors

func (e *Engine) MarkDirtyWithAncestors(id uint64, ancestorIDs []uint64)

MarkDirtyWithAncestors marks an element and all provided ancestor IDs as dirty.

func (*Engine) ResetStats

func (e *Engine) ResetStats()

ResetStats resets layout statistics to zero.

func (*Engine) Stats

func (e *Engine) Stats() LayoutStats

Stats returns current layout statistics.

type FlexContainer

type FlexContainer struct {

	// Direction specifies the main axis direction.
	Direction Direction

	// JustifyContent specifies main axis space distribution.
	JustifyContent JustifyContent

	// AlignItems specifies cross axis alignment.
	AlignItems AlignItems

	// Wrap specifies whether items wrap to multiple lines.
	Wrap WrapMode

	// Gap is the space between items (main axis).
	Gap float32

	// CrossGap is the space between lines when wrapping (cross axis).
	CrossGap float32

	// Items are the flex children with their flex properties.
	Items []FlexItem
	// contains filtered or unexported fields
}

FlexContainer implements CSS Flexbox-style layout.

FlexContainer arranges children along a main axis (row or column), distributing space according to flex properties.

func NewFlexContainer

func NewFlexContainer(direction Direction, justify JustifyContent, align AlignItems) *FlexContainer

NewFlexContainer creates a new flex container with the given properties.

func (*FlexContainer) AddChild

func (f *FlexContainer) AddChild(element Layoutable)

AddChild adds a child element with default flex properties.

func (*FlexContainer) AddChildWithFlex

func (f *FlexContainer) AddChildWithFlex(element Layoutable, grow, shrink, basis float32)

AddChildWithFlex adds a child element with custom flex properties.

func (*FlexContainer) AddFlexItem

func (f *FlexContainer) AddFlexItem(item FlexItem)

AddFlexItem adds a fully configured flex item.

func (*FlexContainer) Children

func (f *FlexContainer) Children() []Layoutable

Children returns child layoutables.

func (*FlexContainer) Clear

func (f *FlexContainer) Clear()

Clear removes all children.

func (*FlexContainer) ID

func (f *FlexContainer) ID() uint64

ID returns the unique identifier.

func (*FlexContainer) ItemBounds

func (f *FlexContainer) ItemBounds(index int) geometry.Rect

ItemBounds returns the bounds of a child item after layout.

func (*FlexContainer) ItemPosition

func (f *FlexContainer) ItemPosition(index int) geometry.Point

ItemPosition returns the position of a child item after layout.

func (*FlexContainer) ItemSize

func (f *FlexContainer) ItemSize(index int) geometry.Size

ItemSize returns the computed size of a child item after layout.

func (*FlexContainer) Layout

func (f *FlexContainer) Layout(constraints geometry.Constraints) geometry.Size

Layout performs flex layout and returns the container size.

func (*FlexContainer) SetID

func (f *FlexContainer) SetID(id uint64)

SetID sets the unique identifier for caching.

func (*FlexContainer) Size

func (f *FlexContainer) Size() geometry.Size

Size returns the computed size after layout.

type FlexItem

type FlexItem struct {
	// Element is the layoutable child element.
	Element Layoutable

	// Grow is the flex-grow factor. Positive values allow the item
	// to grow to fill available space proportionally.
	// Default: 0 (no growing)
	Grow float32

	// Shrink is the flex-shrink factor. Positive values allow the item
	// to shrink when space is insufficient.
	// Default: 1 (can shrink)
	Shrink float32

	// Basis is the initial main axis size before grow/shrink.
	// Use 0 for auto (use element's preferred size).
	// Use negative values for content-based sizing.
	Basis float32

	// AlignSelf overrides the container's AlignItems for this item.
	// Use AlignSelfAuto to use the container's AlignItems.
	AlignSelf AlignSelf
	// contains filtered or unexported fields
}

FlexItem configures how a child participates in flex layout.

type GridCell

type GridCell struct {
	// Element is the layoutable child.
	Element Layoutable

	// Row is the row index (0-based).
	Row int

	// Column is the column index (0-based).
	Column int

	// RowSpan is the number of rows to span (default 1).
	RowSpan int

	// ColSpan is the number of columns to span (default 1).
	ColSpan int
	// contains filtered or unexported fields
}

GridCell represents a child in the grid.

type GridContainer

type GridContainer struct {

	// Columns defines the column tracks.
	Columns []Track

	// Rows defines the row tracks.
	Rows []Track

	// ColumnGap is the space between columns.
	ColumnGap float32

	// RowGap is the space between rows.
	RowGap float32

	// Cells are the grid children.
	Cells []GridCell
	// contains filtered or unexported fields
}

GridContainer implements grid layout.

GridContainer arranges children in a grid of rows and columns. Each track (row/column) can be auto-sized, fixed, or fractional.

func NewGridContainer

func NewGridContainer(columns, rows []Track) *GridContainer

NewGridContainer creates a new grid container.

func NewSimpleGrid

func NewSimpleGrid(numColumns int) *GridContainer

NewSimpleGrid creates a grid with equal fractional columns and auto rows.

func (*GridContainer) AddCell

func (g *GridContainer) AddCell(element Layoutable, row, column int)

AddCell adds a child at the specified grid position.

func (*GridContainer) AddCellWithSpan

func (g *GridContainer) AddCellWithSpan(element Layoutable, row, column, rowSpan, colSpan int)

AddCellWithSpan adds a child that spans multiple cells.

func (*GridContainer) AddChildAutoFlow

func (g *GridContainer) AddChildAutoFlow(element Layoutable)

AddChildAutoFlow adds a child, automatically placing it in the next available cell. Cells are filled left-to-right, top-to-bottom.

func (*GridContainer) CellBounds

func (g *GridContainer) CellBounds(index int) geometry.Rect

CellBounds returns the bounds of a cell after layout.

func (*GridContainer) CellPosition

func (g *GridContainer) CellPosition(index int) geometry.Point

CellPosition returns the position of a cell after layout.

func (*GridContainer) CellSize

func (g *GridContainer) CellSize(index int) geometry.Size

CellSize returns the computed size of a cell after layout.

func (*GridContainer) Children

func (g *GridContainer) Children() []Layoutable

Children returns child layoutables.

func (*GridContainer) Clear

func (g *GridContainer) Clear()

Clear removes all cells.

func (*GridContainer) ColumnCount

func (g *GridContainer) ColumnCount() int

ColumnCount returns the number of columns.

func (*GridContainer) ColumnOffset

func (g *GridContainer) ColumnOffset(column int) float32

ColumnOffset returns the X offset for a column.

func (*GridContainer) ColumnSize

func (g *GridContainer) ColumnSize(column int) float32

ColumnSize returns the width of a column after layout.

func (*GridContainer) ID

func (g *GridContainer) ID() uint64

ID returns the unique identifier.

func (*GridContainer) Layout

func (g *GridContainer) Layout(constraints geometry.Constraints) geometry.Size

Layout performs grid layout.

func (*GridContainer) RowCount

func (g *GridContainer) RowCount() int

RowCount returns the number of rows.

func (*GridContainer) RowOffset

func (g *GridContainer) RowOffset(row int) float32

RowOffset returns the Y offset for a row.

func (*GridContainer) RowSize

func (g *GridContainer) RowSize(row int) float32

RowSize returns the height of a row after layout.

func (*GridContainer) SetGap

func (g *GridContainer) SetGap(gap float32)

SetGap sets both column and row gaps.

func (*GridContainer) SetID

func (g *GridContainer) SetID(id uint64)

SetID sets the unique identifier for caching.

func (*GridContainer) Size

func (g *GridContainer) Size() geometry.Size

Size returns the computed size after layout.

type HStack

type HStack struct {

	// Spacing is the gap between children.
	Spacing float32

	// Alignment specifies vertical alignment of children.
	Alignment StackAlignment

	// Children are the stack items.
	Children []StackChild
	// contains filtered or unexported fields
}

HStack arranges children horizontally with spacing.

HStack is a simplified layout that stacks children from left to right, with optional spacing and cross-axis (vertical) alignment.

func NewHStack

func NewHStack(spacing float32, alignment StackAlignment) *HStack

NewHStack creates a new horizontal stack.

func (*HStack) AddChild

func (h *HStack) AddChild(element Layoutable)

AddChild adds a child element.

func (*HStack) ChildBounds

func (h *HStack) ChildBounds(index int) geometry.Rect

ChildBounds returns the bounds of a child after layout.

func (*HStack) ChildLayoutables

func (h *HStack) ChildLayoutables() []Layoutable

ChildLayoutables returns child layoutables for the Layoutable interface.

func (*HStack) ChildPosition

func (h *HStack) ChildPosition(index int) geometry.Point

ChildPosition returns the position of a child after layout.

func (*HStack) ChildSize

func (h *HStack) ChildSize(index int) geometry.Size

ChildSize returns the computed size of a child after layout.

func (*HStack) Clear

func (h *HStack) Clear()

Clear removes all children.

func (*HStack) ID

func (h *HStack) ID() uint64

ID returns the unique identifier.

func (*HStack) Layout

func (h *HStack) Layout(constraints geometry.Constraints) geometry.Size

Layout performs horizontal stack layout.

func (*HStack) SetID

func (h *HStack) SetID(id uint64)

SetID sets the unique identifier for caching.

func (*HStack) Size

func (h *HStack) Size() geometry.Size

Size returns the computed size after layout.

type JustifyContent

type JustifyContent int

JustifyContent specifies how to distribute space along the main axis.

const (
	// JustifyStart packs children at the start of the main axis.
	JustifyStart JustifyContent = iota
	// JustifyEnd packs children at the end of the main axis.
	JustifyEnd
	// JustifyCenter centers children along the main axis.
	JustifyCenter
	// JustifySpaceBetween distributes space between children (no space at edges).
	JustifySpaceBetween
	// JustifySpaceAround distributes space around children (half space at edges).
	JustifySpaceAround
	// JustifySpaceEvenly distributes space evenly (equal space everywhere).
	JustifySpaceEvenly
)

func (JustifyContent) String

func (j JustifyContent) String() string

String returns a string representation of justify content.

type LayoutResult

type LayoutResult struct {
	// Size is the computed size after layout.
	Size geometry.Size

	// Position is the offset from parent origin.
	Position geometry.Point

	// Constraints used for this layout pass.
	Constraints geometry.Constraints
}

LayoutResult stores the computed layout for an element.

type LayoutStats

type LayoutStats struct {
	// LayoutCalls is the number of Layout calls made.
	LayoutCalls int

	// CacheHits is the number of times a cached result was used.
	CacheHits int

	// CacheMisses is the number of times layout was computed.
	CacheMisses int
}

LayoutStats provides layout performance metrics.

type Layoutable

type Layoutable interface {
	// Layout calculates size given constraints and returns the computed size.
	// The implementation should also position any children.
	Layout(constraints geometry.Constraints) geometry.Size

	// Children returns child layoutables for traversal.
	// Returns nil for leaf elements.
	Children() []Layoutable

	// ID returns a unique identifier for caching purposes.
	// Return 0 if caching is not needed for this element.
	ID() uint64
}

Layoutable represents an element that can be laid out.

This interface abstracts over widgets and layout containers, allowing the engine to work with any layoutable element.

type StackAlignment

type StackAlignment int

StackAlignment specifies how children are aligned within a stack.

const (
	// StackAlignStart aligns children to the start (top/left).
	StackAlignStart StackAlignment = iota
	// StackAlignCenter centers children.
	StackAlignCenter
	// StackAlignEnd aligns children to the end (bottom/right).
	StackAlignEnd
	// StackAlignStretch stretches children to fill the available space.
	StackAlignStretch
)

func (StackAlignment) String

func (a StackAlignment) String() string

String returns a string representation of stack alignment.

type StackChild

type StackChild struct {
	// Element is the layoutable child.
	Element Layoutable
	// contains filtered or unexported fields
}

StackChild represents a child in a stack layout.

type Track

type Track struct {
	// Sizing specifies how the track is sized.
	Sizing TrackSizing

	// Value is the size value. Meaning depends on Sizing:
	//   - TrackAuto: ignored
	//   - TrackFixed: pixel size
	//   - TrackFraction: fraction value (like 1fr, 2fr)
	Value float32
	// contains filtered or unexported fields
}

Track defines a grid row or column.

func AutoTrack

func AutoTrack() Track

AutoTrack creates an auto-sized track.

func FixedTrack

func FixedTrack(size float32) Track

FixedTrack creates a fixed-size track.

func FractionTrack

func FractionTrack(fr float32) Track

FractionTrack creates a fractional track.

type TrackSizing

type TrackSizing int

TrackSizing specifies how a grid track (row or column) is sized.

const (
	// TrackAuto sizes the track to fit its content.
	TrackAuto TrackSizing = iota
	// TrackFixed uses a fixed pixel size.
	TrackFixed
	// TrackFraction uses a fraction of available space (like CSS fr unit).
	TrackFraction
)

type VStack

type VStack struct {

	// Spacing is the gap between children.
	Spacing float32

	// Alignment specifies horizontal alignment of children.
	Alignment StackAlignment

	// Children are the stack items.
	Children []StackChild
	// contains filtered or unexported fields
}

VStack arranges children vertically with spacing.

VStack is a simplified layout that stacks children from top to bottom, with optional spacing and cross-axis (horizontal) alignment.

func NewVStack

func NewVStack(spacing float32, alignment StackAlignment) *VStack

NewVStack creates a new vertical stack.

func (*VStack) AddChild

func (v *VStack) AddChild(element Layoutable)

AddChild adds a child element.

func (*VStack) ChildBounds

func (v *VStack) ChildBounds(index int) geometry.Rect

ChildBounds returns the bounds of a child after layout.

func (*VStack) ChildLayoutables

func (v *VStack) ChildLayoutables() []Layoutable

ChildLayoutables returns child layoutables for the Layoutable interface.

func (*VStack) ChildPosition

func (v *VStack) ChildPosition(index int) geometry.Point

ChildPosition returns the position of a child after layout.

func (*VStack) ChildSize

func (v *VStack) ChildSize(index int) geometry.Size

ChildSize returns the computed size of a child after layout.

func (*VStack) Clear

func (v *VStack) Clear()

Clear removes all children.

func (*VStack) ID

func (v *VStack) ID() uint64

ID returns the unique identifier.

func (*VStack) Layout

func (v *VStack) Layout(constraints geometry.Constraints) geometry.Size

Layout performs vertical stack layout.

func (*VStack) SetID

func (v *VStack) SetID(id uint64)

SetID sets the unique identifier for caching.

func (*VStack) Size

func (v *VStack) Size() geometry.Size

Size returns the computed size after layout.

type WrapMode

type WrapMode int

WrapMode specifies whether flex items wrap to multiple lines.

const (
	// NoWrap keeps all items on a single line.
	NoWrap WrapMode = iota
	// Wrap allows items to wrap to multiple lines.
	Wrap
	// WrapReverse wraps items in reverse order.
	WrapReverse
)

func (WrapMode) String

func (w WrapMode) String() string

String returns a string representation of wrap mode.

type ZStack

type ZStack struct {

	// Alignment specifies how children are positioned.
	Alignment ZStackAlignment

	// Children are the stack items (bottom to top order).
	Children []StackChild
	// contains filtered or unexported fields
}

ZStack overlays children on top of each other.

ZStack is useful for layering widgets, such as placing a badge on top of an icon, or creating overlays.

func NewZStack

func NewZStack(alignment ZStackAlignment) *ZStack

NewZStack creates a new overlay stack.

func (*ZStack) AddChild

func (z *ZStack) AddChild(element Layoutable)

AddChild adds a child element (will be rendered on top of previous children).

func (*ZStack) ChildBounds

func (z *ZStack) ChildBounds(index int) geometry.Rect

ChildBounds returns the bounds of a child after layout.

func (*ZStack) ChildLayoutables

func (z *ZStack) ChildLayoutables() []Layoutable

ChildLayoutables returns child layoutables for the Layoutable interface.

func (*ZStack) ChildPosition

func (z *ZStack) ChildPosition(index int) geometry.Point

ChildPosition returns the position of a child after layout.

func (*ZStack) ChildSize

func (z *ZStack) ChildSize(index int) geometry.Size

ChildSize returns the computed size of a child after layout.

func (*ZStack) Clear

func (z *ZStack) Clear()

Clear removes all children.

func (*ZStack) ID

func (z *ZStack) ID() uint64

ID returns the unique identifier.

func (*ZStack) Layout

func (z *ZStack) Layout(constraints geometry.Constraints) geometry.Size

Layout performs overlay stack layout.

func (*ZStack) SetID

func (z *ZStack) SetID(id uint64)

SetID sets the unique identifier for caching.

func (*ZStack) Size

func (z *ZStack) Size() geometry.Size

Size returns the computed size after layout.

type ZStackAlignment

type ZStackAlignment int

ZStackAlignment specifies how children are positioned in a ZStack.

const (
	// ZAlignTopLeft positions children at the top-left.
	ZAlignTopLeft ZStackAlignment = iota
	// ZAlignTop positions children at the top-center.
	ZAlignTop
	// ZAlignTopRight positions children at the top-right.
	ZAlignTopRight
	// ZAlignLeft positions children at the middle-left.
	ZAlignLeft
	// ZAlignCenter positions children at the center.
	ZAlignCenter
	// ZAlignRight positions children at the middle-right.
	ZAlignRight
	// ZAlignBottomLeft positions children at the bottom-left.
	ZAlignBottomLeft
	// ZAlignBottom positions children at the bottom-center.
	ZAlignBottom
	// ZAlignBottomRight positions children at the bottom-right.
	ZAlignBottomRight
)

func (ZStackAlignment) String

func (a ZStackAlignment) String() string

String returns a string representation of ZStack alignment.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL