layout
Package layout provides layout value types and the render system.
This package defines the types used for positioning and sizing widgets: Constraints, EdgeInsets, Alignment, and the render object system.
Layout Types
Constraints specify the min/max dimensions a child can occupy:
constraints := layout.Tight(rendering.Size{Width: 100, Height: 50})
constraints := layout.Loose(rendering.Size{Width: 200, Height: 200})
EdgeInsets represents padding/margin on four sides:
padding := layout.EdgeInsetsAll(16)
padding := layout.EdgeInsetsSymmetric(horizontal: 8, vertical: 16)
Alignment represents a position within a rectangle:
alignment := layout.AlignmentCenter
alignment := layout.AlignmentTopLeft
Render Objects
RenderObject handles layout, painting, and hit testing. The render tree is responsible for the actual visual representation of widgets.
RenderBox is a RenderObject with box layout, the most common type.
PipelineOwner tracks render objects that need layout or paint updates.
Variables
var (
// AlignmentTopLeft aligns to the top-left corner.
AlignmentTopLeft = Alignment{-1, -1}
// AlignmentTopCenter aligns to the top center.
AlignmentTopCenter = Alignment{0, -1}
// AlignmentTopRight aligns to the top-right corner.
AlignmentTopRight = Alignment{1, -1}
// AlignmentCenterLeft aligns to the center-left edge.
AlignmentCenterLeft = Alignment{-1, 0}
// AlignmentCenter aligns to the center.
AlignmentCenter = Alignment{0, 0}
// AlignmentCenterRight aligns to the center-right edge.
AlignmentCenterRight = Alignment{1, 0}
// AlignmentBottomLeft aligns to the bottom-left corner.
AlignmentBottomLeft = Alignment{-1, 1}
// AlignmentBottomCenter aligns to the bottom center.
AlignmentBottomCenter = Alignment{0, 1}
// AlignmentBottomRight aligns to the bottom-right corner.
AlignmentBottomRight = Alignment{1, 1}
)
type Alignment
Alignment represents a position within a rectangle.
type Alignment struct {
X float64
Y float64
}
func (Alignment) WithinRect
func (a Alignment) WithinRect(rect rendering.Rect, childSize rendering.Size) rendering.Offset
WithinRect returns the offset for a child within the given rect.
type BoxParentData
BoxParentData stores the offset for a child in a box layout.
type BoxParentData struct {
Offset rendering.Offset
}
type ChildVisitor
ChildVisitor is implemented by render objects that have children.
type ChildVisitor interface {
// VisitChildren calls the visitor function for each child.
VisitChildren(visitor func(RenderObject))
}
type Constraints
Constraints specify the min/max dimensions a child can occupy.
type Constraints struct {
MinWidth float64
MaxWidth float64
MinHeight float64
MaxHeight float64
}
func Loose
func Loose(size rendering.Size) Constraints
Loose returns constraints with zero minimum.
func Tight
func Tight(size rendering.Size) Constraints
Tight returns constraints that force an exact size.
func (Constraints) Constrain
func (c Constraints) Constrain(size rendering.Size) rendering.Size
Constrain clamps a size to fit within the constraints.
func (Constraints) Deflate
func (c Constraints) Deflate(insets EdgeInsets) Constraints
Deflate reduces constraints by the provided padding.
func (Constraints) HasTightHeight
func (c Constraints) HasTightHeight() bool
HasTightHeight returns true if height is fixed.
func (Constraints) HasTightWidth
func (c Constraints) HasTightWidth() bool
HasTightWidth returns true if width is fixed.
func (Constraints) IsTight
func (c Constraints) IsTight() bool
IsTight returns true if both width and height are tight.
type EdgeInsets
EdgeInsets represents padding/margin on four sides.
type EdgeInsets struct {
Left float64
Top float64
Right float64
Bottom float64
}
func EdgeInsetsAll
func EdgeInsetsAll(value float64) EdgeInsets
EdgeInsetsAll creates uniform padding on all sides.
func EdgeInsetsOnly
func EdgeInsetsOnly(left, top, right, bottom float64) EdgeInsets
EdgeInsetsOnly creates padding with explicit values.
func EdgeInsetsSymmetric
func EdgeInsetsSymmetric(horizontal, vertical float64) EdgeInsets
EdgeInsetsSymmetric creates symmetric padding.
func (EdgeInsets) Add
func (e EdgeInsets) Add(all float64) EdgeInsets
Add returns a new EdgeInsets with uniform padding added to all sides.
func (EdgeInsets) AddBottom
func (e EdgeInsets) AddBottom(value float64) EdgeInsets
AddBottom returns a new EdgeInsets with padding added to bottom.
func (EdgeInsets) AddHorizontal
func (e EdgeInsets) AddHorizontal(value float64) EdgeInsets
AddHorizontal returns a new EdgeInsets with padding added to left and right.
func (EdgeInsets) AddLeft
func (e EdgeInsets) AddLeft(value float64) EdgeInsets
AddLeft returns a new EdgeInsets with padding added to left.
func (EdgeInsets) AddRight
func (e EdgeInsets) AddRight(value float64) EdgeInsets
AddRight returns a new EdgeInsets with padding added to right.
func (EdgeInsets) AddTop
func (e EdgeInsets) AddTop(value float64) EdgeInsets
AddTop returns a new EdgeInsets with padding added to top.
func (EdgeInsets) AddVertical
func (e EdgeInsets) AddVertical(value float64) EdgeInsets
AddVertical returns a new EdgeInsets with padding added to top and bottom.
func (EdgeInsets) Horizontal
func (e EdgeInsets) Horizontal() float64
Horizontal returns the sum of left and right padding.
func (EdgeInsets) OnlyBottom
func (e EdgeInsets) OnlyBottom() EdgeInsets
OnlyBottom returns a new EdgeInsets with only the bottom value preserved.
func (EdgeInsets) OnlyHorizontal
func (e EdgeInsets) OnlyHorizontal() EdgeInsets
OnlyHorizontal returns a new EdgeInsets with only left and right preserved.
func (EdgeInsets) OnlyLeft
func (e EdgeInsets) OnlyLeft() EdgeInsets
OnlyLeft returns a new EdgeInsets with only the left value preserved.
func (EdgeInsets) OnlyRight
func (e EdgeInsets) OnlyRight() EdgeInsets
OnlyRight returns a new EdgeInsets with only the right value preserved.
func (EdgeInsets) OnlyTop
func (e EdgeInsets) OnlyTop() EdgeInsets
OnlyTop returns a new EdgeInsets with only the top value preserved.
func (EdgeInsets) OnlyVertical
func (e EdgeInsets) OnlyVertical() EdgeInsets
OnlyVertical returns a new EdgeInsets with only top and bottom preserved.
func (EdgeInsets) Vertical
func (e EdgeInsets) Vertical() float64
Vertical returns the sum of top and bottom padding.
type HitTestResult
HitTestResult collects hit test entries in paint order.
type HitTestResult struct {
Entries []RenderObject
}
func (*HitTestResult) Add
func (h *HitTestResult) Add(target RenderObject)
Add inserts a render object into the hit test result list.
type PaintContext
PaintContext provides the canvas for painting render objects.
type PaintContext struct {
Canvas rendering.Canvas
}
func (*PaintContext) PaintChild
func (p *PaintContext) PaintChild(child RenderBox, offset rendering.Offset)
PaintChild paints a child render box at the given offset.
func (*PaintContext) PaintChildWithLayer
func (p *PaintContext) PaintChildWithLayer(child RenderBox, offset rendering.Offset)
PaintChildWithLayer paints a child, using its cached layer if available.
type PipelineOwner
PipelineOwner tracks render objects that need layout or paint.
Layout scheduling works with relayout boundaries: when a node needs layout, MarkNeedsLayout walks up to the nearest boundary, marking each node along the way. The boundary gets scheduled here. During FlushLayoutForRoot, layout propagates from the root (or scheduled boundaries) down through all marked nodes.
type PipelineOwner struct {
// contains filtered or unexported fields
}
func (*PipelineOwner) FlushLayout
func (p *PipelineOwner) FlushLayout()
FlushLayout clears the dirty layout list without performing layout.
func (*PipelineOwner) FlushLayoutForRoot
func (p *PipelineOwner) FlushLayoutForRoot(root RenderObject, constraints Constraints)
FlushLayoutForRoot runs layout starting from the root.
The typical frame sequence is:
- FlushBuild - rebuilds dirty elements, updates render object properties
- FlushLayoutForRoot - lays out from root, propagating to dirty subtrees
- Paint - renders the tree
Layout starts at the root with tight constraints (root is always a boundary). From there, layout propagates down. Nodes with needsLayout=true will run PerformLayout; clean nodes with unchanged constraints skip layout entirely.
func (*PipelineOwner) FlushLayoutFromBoundaries
func (p *PipelineOwner) FlushLayoutFromBoundaries()
FlushLayoutFromBoundaries processes dirty relayout boundaries without a root. This is useful for incremental updates outside the normal frame cycle.
func (*PipelineOwner) FlushPaint
func (p *PipelineOwner) FlushPaint() []RenderObject
FlushPaint processes dirty repaint boundaries in depth order. Returns boundaries that need repainting (parents first).
func (*PipelineOwner) FlushSemantics
func (p *PipelineOwner) FlushSemantics() []RenderObject
FlushSemantics returns dirty semantics boundaries sorted by depth.
func (*PipelineOwner) NeedsLayout
func (p *PipelineOwner) NeedsLayout() bool
NeedsLayout reports if any render objects need layout.
func (*PipelineOwner) NeedsPaint
func (p *PipelineOwner) NeedsPaint() bool
NeedsPaint reports if any render objects need paint.
func (*PipelineOwner) NeedsSemantics
func (p *PipelineOwner) NeedsSemantics() bool
NeedsSemantics reports if any render objects need semantics update.
func (*PipelineOwner) ScheduleLayout
func (p *PipelineOwner) ScheduleLayout(object RenderObject)
ScheduleLayout marks a relayout boundary as needing layout. Only relayout boundaries should be scheduled here - intermediate nodes are marked via MarkNeedsLayout but not scheduled directly.
func (*PipelineOwner) SchedulePaint
func (p *PipelineOwner) SchedulePaint(object RenderObject)
SchedulePaint marks a render object as needing paint.
func (*PipelineOwner) ScheduleSemantics
func (p *PipelineOwner) ScheduleSemantics(object RenderObject)
ScheduleSemantics marks a semantics boundary as needing update.
type PointerHandler
PointerHandler receives pointer events routed from hit testing.
type PointerHandler interface {
HandlePointer(event gestures.PointerEvent)
}
type RenderBox
RenderBox is a RenderObject with box layout.
type RenderBox interface {
RenderObject
}
type RenderBoxBase
RenderBoxBase provides base behavior for render boxes.
type RenderBoxBase struct {
// contains filtered or unexported fields
}
func (*RenderBoxBase) ClearNeedsPaint
func (r *RenderBoxBase) ClearNeedsPaint()
ClearNeedsPaint marks this render object as painted.
func (*RenderBoxBase) ClearNeedsSemanticsUpdate
func (r *RenderBoxBase) ClearNeedsSemanticsUpdate()
ClearNeedsSemanticsUpdate marks this render object's semantics as updated.
func (*RenderBoxBase) Constraints
func (r *RenderBoxBase) Constraints() Constraints
Constraints returns the last received constraints.
func (*RenderBoxBase) Depth
func (r *RenderBoxBase) Depth() int
Depth returns the tree depth (root = 0).
func (*RenderBoxBase) DescribeSemanticsConfiguration
func (r *RenderBoxBase) DescribeSemanticsConfiguration(config *semantics.SemanticsConfiguration) bool
DescribeSemanticsConfiguration is the default implementation that reports no semantic content. Override this method in render objects that provide semantic information.
func (*RenderBoxBase) IsRepaintBoundary
func (r *RenderBoxBase) IsRepaintBoundary() bool
IsRepaintBoundary returns whether this render object repaints separately. Override this in render objects that should isolate their paint.
func (*RenderBoxBase) Layer
func (r *RenderBoxBase) Layer() *rendering.DisplayList
Layer returns the cached display list for repaint boundaries.
func (*RenderBoxBase) Layout
func (r *RenderBoxBase) Layout(constraints Constraints, parentUsesSize bool)
Layout handles boundary determination and delegates to PerformLayout.
This implements Flutter's relayout boundary optimization. A node becomes a relayout boundary when:
- It receives tight constraints (parent dictates exact size)
- It is the root (no parent)
- Parent doesn't use our size (parentUsesSize=false)
Boundaries contain layout changes - when a descendant needs layout, the walk up stops at the boundary, preventing unnecessary relayout of ancestors.
Widgets should implement PerformLayout() for their specific layout logic. The base Layout() handles:
- Updating the relayout boundary reference
- Skipping layout when clean and constraints unchanged
- Clearing the needsLayout flag
- Calling PerformLayout()
func (*RenderBoxBase) MarkNeedsLayout
func (r *RenderBoxBase) MarkNeedsLayout()
MarkNeedsLayout marks this render box as needing layout.
This follows Flutter's relayout boundary pattern: when a node needs layout, we walk up the tree marking each node until we reach a relayout boundary. The boundary then gets scheduled for layout. During layout, all marked nodes will run their PerformLayout because their needsLayout flag is true.
This ensures that when a deep descendant changes, layout properly propagates from the boundary down through all intermediate nodes to reach the changed node.
func (*RenderBoxBase) MarkNeedsPaint
func (r *RenderBoxBase) MarkNeedsPaint()
MarkNeedsPaint marks this render box as needing paint.
This follows Flutter's repaint boundary pattern: when a node needs paint, we walk up the tree until we reach a repaint boundary. The boundary then gets scheduled for paint.
Note: Unlike MarkNeedsLayout, we don't early-return when needsPaint is true. This is because SetSelf() pre-sets needsPaint=true without scheduling, and SchedulePaint() already handles deduplication internally.
func (*RenderBoxBase) MarkNeedsSemanticsUpdate
func (r *RenderBoxBase) MarkNeedsSemanticsUpdate()
MarkNeedsSemanticsUpdate marks this render box as needing semantics update.
This follows Flutter's semantics boundary pattern: when a node needs semantics update, we walk up the tree until we reach a semantics boundary. The boundary then gets scheduled for semantics update.
Note: Unlike MarkNeedsLayout, we don't early-return when needsSemanticsUpdate is true. This is because SetSelf() and SetParent() pre-set needsSemanticsUpdate=true without scheduling, and ScheduleSemantics() already handles deduplication internally.
NOTE: This method marks needsSemanticsUpdate=true on all nodes along the path to the boundary, but only the boundary is added to dirtySemantics. When FlushSemantics clears flags, only boundary flags are cleared - intermediate nodes remain dirty. This is harmless with the current full-rebuild approach but would need addressing for true incremental updates (either clear all affected nodes, or only mark boundaries).
func (*RenderBoxBase) NeedsLayout
func (r *RenderBoxBase) NeedsLayout() bool
NeedsLayout returns true if this render box needs layout.
func (*RenderBoxBase) NeedsPaint
func (r *RenderBoxBase) NeedsPaint() bool
NeedsPaint returns true if this render box needs painting.
func (*RenderBoxBase) NeedsSemanticsUpdate
func (r *RenderBoxBase) NeedsSemanticsUpdate() bool
NeedsSemanticsUpdate returns true if this render box needs semantics update.
func (*RenderBoxBase) Parent
func (r *RenderBoxBase) Parent() RenderObject
Parent returns the parent render object.
func (*RenderBoxBase) ParentData
func (r *RenderBoxBase) ParentData() any
ParentData returns the parent-assigned data for this render box.
func (*RenderBoxBase) RelayoutBoundary
func (r *RenderBoxBase) RelayoutBoundary() RenderObject
RelayoutBoundary returns the cached nearest relayout boundary.
func (*RenderBoxBase) RepaintBoundary
func (r *RenderBoxBase) RepaintBoundary() RenderObject
RepaintBoundary returns the cached nearest repaint boundary.
func (*RenderBoxBase) SemanticsBoundary
func (r *RenderBoxBase) SemanticsBoundary() RenderObject
SemanticsBoundary returns the cached nearest semantics boundary.
func (*RenderBoxBase) SetLayer
func (r *RenderBoxBase) SetLayer(list *rendering.DisplayList)
SetLayer stores the cached display list.
func (*RenderBoxBase) SetOwner
func (r *RenderBoxBase) SetOwner(owner *PipelineOwner)
SetOwner assigns the pipeline owner for scheduling layout and paint.
func (*RenderBoxBase) SetParent
func (r *RenderBoxBase) SetParent(parent RenderObject)
SetParent sets the parent render object and computes depth. Clears relayoutBoundary and constraints to prevent stale references when the object is reparented to a different subtree.
func (*RenderBoxBase) SetParentData
func (r *RenderBoxBase) SetParentData(data any)
SetParentData assigns parent-controlled data to this render box.
func (*RenderBoxBase) SetSelf
func (r *RenderBoxBase) SetSelf(self RenderObject)
SetSelf registers the concrete render object for scheduling.
func (*RenderBoxBase) SetSize
func (r *RenderBoxBase) SetSize(size rendering.Size)
SetSize updates the render box size.
func (*RenderBoxBase) Size
func (r *RenderBoxBase) Size() rendering.Size
Size returns the current size of the render box.
type RenderObject
RenderObject handles layout, painting, and hit testing.
type RenderObject interface {
Layout(constraints Constraints, parentUsesSize bool)
Size() rendering.Size
Paint(ctx *PaintContext)
HitTest(position rendering.Offset, result *HitTestResult) bool
ParentData() any
SetParentData(data any)
MarkNeedsLayout()
MarkNeedsPaint()
MarkNeedsSemanticsUpdate()
SetOwner(owner *PipelineOwner)
IsRepaintBoundary() bool
}
type ScrollOffsetProvider
ScrollOffsetProvider is implemented by scrollable render objects. The accessibility system uses this to adjust child positions for scroll offset.
type ScrollOffsetProvider interface {
// SemanticScrollOffset returns the scroll offset to subtract from child positions.
// A positive Y value means content has scrolled up (showing lower content).
SemanticScrollOffset() rendering.Offset
}
type SemanticsDescriber
SemanticsDescriber is implemented by render objects that provide semantic information.
type SemanticsDescriber interface {
// DescribeSemanticsConfiguration populates the semantic configuration for this render object.
// Returns true if this render object contributes semantic information.
DescribeSemanticsConfiguration(config *semantics.SemanticsConfiguration) bool
}
type TapTarget
TapTarget is a render object that responds to tap events.
type TapTarget interface {
OnTap()
}
Generated by gomarkdoc