Documentation
¶
Overview ¶
Package primitives provides the fundamental widget building blocks for the gogpu/ui framework: BoxWidget, TextWidget, and ImageWidget.
These three primitives are the lowest-level concrete widgets from which all higher-level components are composed. Each primitive implements widget.Widget for layout, drawing, and event handling, and a11y.Accessible for accessibility.
Fluent Builder API ¶
All primitives use a Tailwind-inspired fluent builder API where the constructor returns a pointer to the widget struct, and style methods return that same pointer for chaining. There is no separate Build step; the returned value is a ready-to-use widget.
root := primitives.Box(
primitives.Text("Hello World").
FontSize(24).
Color(widget.RGBA(0, 0, 0, 1)),
primitives.Text("Subtitle").
FontSize(14),
).Padding(16).Background(widget.RGBA(1, 1, 1, 1)).Rounded(8)
Box ¶
Box is a container widget that lays out its children in a vertical stack with optional padding, background, border, rounded corners, shadow, and gap between children.
card := primitives.Box(
primitives.Text("Title").FontSize(18).Bold(),
primitives.Text("Body text").FontSize(14),
).Padding(16).Background(widget.Hex(0xFFFFFF)).Rounded(12).Shadow(2)
Text ¶
Text displays static or reactive text content. Static text is created with Text, reactive text via a function with TextFn, and signal-bound text with TextWidget.ContentSignal.
label := primitives.Text("Hello").FontSize(16).Bold()
counter := state.NewSignal(0)
dynamic := primitives.TextFn(func() string {
return fmt.Sprintf("Count: %d", counter.Get())
}).FontSize(14)
name := state.NewSignal("Alice")
bound := primitives.Text("").ContentSignal(name).FontSize(14)
Image ¶
Image displays a raster image with support for different fit modes (cover, contain, fill) and an alt text label for accessibility.
img := primitives.Image(mySource).
Size(200, 150).
Cover().
Alt("Photo of a sunset").
Rounded(8)
Index ¶
- Constants
- type Border
- type BoxStyle
- type BoxWidget
- func (b *BoxWidget) AccessibilityActions() []a11y.Action
- func (b *BoxWidget) AccessibilityHint() string
- func (b *BoxWidget) AccessibilityLabel() string
- func (b *BoxWidget) AccessibilityRole() a11y.Role
- func (b *BoxWidget) AccessibilityState() a11y.State
- func (b *BoxWidget) AccessibilityValue() string
- func (b *BoxWidget) Background(c widget.Color) *BoxWidget
- func (b *BoxWidget) BorderStyle(width float32, color widget.Color) *BoxWidget
- func (b *BoxWidget) Children() []widget.Widget
- func (b *BoxWidget) DirectionSignal(sig state.ReadonlySignal[Direction]) *BoxWidget
- func (b *BoxWidget) Draw(ctx widget.Context, canvas widget.Canvas)
- func (b *BoxWidget) Event(ctx widget.Context, e event.Event) bool
- func (b *BoxWidget) Gap(v float32) *BoxWidget
- func (b *BoxWidget) Height(v float32) *BoxWidget
- func (b *BoxWidget) Label(label string) *BoxWidget
- func (b *BoxWidget) Layout(ctx widget.Context, constraints geometry.Constraints) geometry.Size
- func (b *BoxWidget) MaxHeightValue(v float32) *BoxWidget
- func (b *BoxWidget) MaxWidthValue(v float32) *BoxWidget
- func (b *BoxWidget) MinHeightValue(v float32) *BoxWidget
- func (b *BoxWidget) MinWidthValue(v float32) *BoxWidget
- func (b *BoxWidget) Mount(ctx widget.Context)
- func (b *BoxWidget) Padding(v float32) *BoxWidget
- func (b *BoxWidget) PaddingBottom(v float32) *BoxWidget
- func (b *BoxWidget) PaddingLeft(v float32) *BoxWidget
- func (b *BoxWidget) PaddingRight(v float32) *BoxWidget
- func (b *BoxWidget) PaddingTop(v float32) *BoxWidget
- func (b *BoxWidget) PaddingXY(x, y float32) *BoxWidget
- func (b *BoxWidget) ResolvedDirection() Direction
- func (b *BoxWidget) Rounded(r float32) *BoxWidget
- func (b *BoxWidget) SetDirection(d Direction) *BoxWidget
- func (b *BoxWidget) ShadowLevel(level int) *BoxWidget
- func (b *BoxWidget) Style() BoxStyle
- func (b *BoxWidget) Unmount()
- func (b *BoxWidget) Width(v float32) *BoxWidget
- type Direction
- type ExpandedWidget
- func (e *ExpandedWidget) AccessibilityActions() []a11y.Action
- func (e *ExpandedWidget) AccessibilityHint() string
- func (e *ExpandedWidget) AccessibilityLabel() string
- func (e *ExpandedWidget) AccessibilityRole() a11y.Role
- func (e *ExpandedWidget) AccessibilityState() a11y.State
- func (e *ExpandedWidget) AccessibilityValue() string
- func (e *ExpandedWidget) Child() widget.Widget
- func (e *ExpandedWidget) Children() []widget.Widget
- func (e *ExpandedWidget) Draw(ctx widget.Context, canvas widget.Canvas)
- func (e *ExpandedWidget) Event(ctx widget.Context, ev event.Event) bool
- func (e *ExpandedWidget) IsExpanded() bool
- func (e *ExpandedWidget) Layout(ctx widget.Context, constraints geometry.Constraints) geometry.Size
- type ImageFit
- type ImageSource
- type ImageStyle
- type ImageWidget
- func (w *ImageWidget) AccessibilityActions() []a11y.Action
- func (w *ImageWidget) AccessibilityHint() string
- func (w *ImageWidget) AccessibilityLabel() string
- func (w *ImageWidget) AccessibilityRole() a11y.Role
- func (w *ImageWidget) AccessibilityState() a11y.State
- func (w *ImageWidget) AccessibilityValue() string
- func (w *ImageWidget) Alt(text string) *ImageWidget
- func (w *ImageWidget) AltText() string
- func (w *ImageWidget) Children() []widget.Widget
- func (w *ImageWidget) Contain() *ImageWidget
- func (w *ImageWidget) Cover() *ImageWidget
- func (w *ImageWidget) Draw(_ widget.Context, canvas widget.Canvas)
- func (w *ImageWidget) Event(_ widget.Context, _ event.Event) bool
- func (w *ImageWidget) Fill() *ImageWidget
- func (w *ImageWidget) Fit(f ImageFit) *ImageWidget
- func (w *ImageWidget) Layout(_ widget.Context, constraints geometry.Constraints) geometry.Size
- func (w *ImageWidget) Rounded(r float32) *ImageWidget
- func (w *ImageWidget) Size(width, height float32) *ImageWidget
- func (w *ImageWidget) Source() ImageSource
- func (w *ImageWidget) Style() ImageStyle
- type Option
- type RasterCacheConfig
- type RasterCacheStats
- type RepaintBoundary
- func (rb *RepaintBoundary) AccessibilityActions() []a11y.Action
- func (rb *RepaintBoundary) AccessibilityHint() string
- func (rb *RepaintBoundary) AccessibilityLabel() string
- func (rb *RepaintBoundary) AccessibilityRole() a11y.Role
- func (rb *RepaintBoundary) AccessibilityState() a11y.State
- func (rb *RepaintBoundary) AccessibilityValue() string
- func (rb *RepaintBoundary) CacheHits() int
- func (rb *RepaintBoundary) CacheKey() uint64
- func (rb *RepaintBoundary) CacheValid() bool
- func (rb *RepaintBoundary) Child() widget.Widget
- func (rb *RepaintBoundary) Children() []widget.Widget
- func (rb *RepaintBoundary) ClearBoundaryDirty()
- func (rb *RepaintBoundary) ConsecutiveHits() int
- func (rb *RepaintBoundary) DebugLabel() string
- func (rb *RepaintBoundary) Draw(ctx widget.Context, canvas widget.Canvas)
- func (rb *RepaintBoundary) Event(ctx widget.Context, e event.Event) bool
- func (rb *RepaintBoundary) InvalidateCache()
- func (rb *RepaintBoundary) IsBoundaryDirty() bool
- func (rb *RepaintBoundary) IsStable() bool
- func (rb *RepaintBoundary) Layout(ctx widget.Context, constraints geometry.Constraints) geometry.Size
- func (rb *RepaintBoundary) MarkBoundaryDirty()
- func (rb *RepaintBoundary) RasterCacheStats() RasterCacheStats
- func (rb *RepaintBoundary) SceneChanged(sinceVersion uint64) bool
- func (rb *RepaintBoundary) SceneVersion() uint64
- func (rb *RepaintBoundary) SetOnBoundaryDirty(fn func(rb *RepaintBoundary))
- func (rb *RepaintBoundary) Unmount()
- type Shadow
- type TextAlign
- type TextOverflow
- type TextStyle
- type TextWidget
- func (t *TextWidget) AccessibilityActions() []a11y.Action
- func (t *TextWidget) AccessibilityHint() string
- func (t *TextWidget) AccessibilityLabel() string
- func (t *TextWidget) AccessibilityRole() a11y.Role
- func (t *TextWidget) AccessibilityState() a11y.State
- func (t *TextWidget) AccessibilityValue() string
- func (t *TextWidget) Align(a TextAlign) *TextWidget
- func (t *TextWidget) Bold() *TextWidget
- func (t *TextWidget) Children() []widget.Widget
- func (t *TextWidget) Color(c widget.Color) *TextWidget
- func (t *TextWidget) Content() string
- func (t *TextWidget) ContentSignal(sig state.ReadonlySignal[string]) *TextWidget
- func (t *TextWidget) Draw(ctx widget.Context, canvas widget.Canvas)
- func (t *TextWidget) Ellipsis() *TextWidget
- func (t *TextWidget) Event(_ widget.Context, _ event.Event) bool
- func (t *TextWidget) FontSize(size float32) *TextWidget
- func (t *TextWidget) IsReactive() bool
- func (t *TextWidget) Layout(_ widget.Context, constraints geometry.Constraints) geometry.Size
- func (t *TextWidget) LineHeight(v float32) *TextWidget
- func (t *TextWidget) MaxLines(n int) *TextWidget
- func (t *TextWidget) Mount(ctx widget.Context)
- func (t *TextWidget) Style() TextStyle
- func (t *TextWidget) Unmount()
- type ThemeScopeWidget
- func (ts *ThemeScopeWidget) Children() []widget.Widget
- func (ts *ThemeScopeWidget) Draw(ctx widget.Context, canvas widget.Canvas)
- func (ts *ThemeScopeWidget) Event(ctx widget.Context, e event.Event) bool
- func (ts *ThemeScopeWidget) Layout(ctx widget.Context, constraints geometry.Constraints) geometry.Size
- func (ts *ThemeScopeWidget) SetTheme(theme widget.ThemeProvider)
- func (ts *ThemeScopeWidget) Theme() widget.ThemeProvider
Constants ¶
const ( // TextAlignStart aligns text to the start edge (left in LTR, right in RTL). TextAlignStart = widget.TextAlignLeft // TextAlignCenter centers text horizontally. TextAlignCenter = widget.TextAlignCenter // TextAlignEnd aligns text to the end edge (right in LTR, left in RTL). TextAlignEnd = widget.TextAlignRight )
TextAlign constants mapped to widget.TextAlign values.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Border ¶
type Border struct {
// Width is the border thickness in logical pixels.
Width float32
// Color is the border color.
Color widget.Color
}
Border describes the border of a widget.
type BoxStyle ¶
type BoxStyle struct {
Padding geometry.Insets
Background widget.Color
Radius float32
Border Border
Shadow Shadow
Gap float32
// Explicit dimensions. Zero means unconstrained in that dimension.
ExplicitWidth float32
ExplicitHeight float32
MinWidth float32
MinHeight float32
MaxWidth float32
MaxHeight float32
}
BoxStyle holds all visual styling for a BoxWidget.
type BoxWidget ¶
type BoxWidget struct {
widget.WidgetBase
// contains filtered or unexported fields
}
BoxWidget is a container that lays out children vertically or horizontally with optional padding, background, border, rounded corners, shadow, and gap.
BoxWidget implements widget.Widget, a11y.Accessible, and widget.Lifecycle.
Create a BoxWidget with the Box constructor. Use HBox or VBox for convenience constructors with a pre-set direction.
func Box ¶
Box creates a new container widget with the given children.
Children are laid out vertically from top to bottom by default. Use BoxWidget.SetDirection to switch to horizontal layout, or use the HBox and VBox convenience constructors.
card := primitives.Box(
primitives.Text("Title").Bold(),
primitives.Text("Body"),
).Padding(16).Background(widget.Hex(0xFFFFFF))
func HBox ¶
HBox creates a new container that lays out children horizontally (left to right).
This is a convenience constructor equivalent to Box(children...).SetDirection(DirectionHorizontal).
row := primitives.HBox(icon, label, spacer).Gap(8)
func VBox ¶
VBox creates a new container that lays out children vertically (top to bottom).
This is a convenience constructor equivalent to Box(children...).SetDirection(DirectionVertical). Since vertical is the default direction, VBox is primarily useful for readability when paired with HBox in the same codebase.
column := primitives.VBox(title, subtitle, body).Gap(4)
func (*BoxWidget) AccessibilityActions ¶
AccessibilityActions returns nil. Containers have no actions.
func (*BoxWidget) AccessibilityHint ¶
AccessibilityHint returns an empty string. Containers typically have no hint.
func (*BoxWidget) AccessibilityLabel ¶
AccessibilityLabel returns the custom label, or empty string if none set.
func (*BoxWidget) AccessibilityRole ¶
AccessibilityRole returns a11y.RoleGenericContainer.
func (*BoxWidget) AccessibilityState ¶
AccessibilityState returns the default state.
func (*BoxWidget) AccessibilityValue ¶
AccessibilityValue returns an empty string. Containers have no value.
func (*BoxWidget) Background ¶
Background sets the background color.
func (*BoxWidget) BorderStyle ¶
BorderStyle sets the border width and color.
func (*BoxWidget) DirectionSignal ¶
func (b *BoxWidget) DirectionSignal(sig state.ReadonlySignal[Direction]) *BoxWidget
DirectionSignal binds the layout direction to a read-only reactive signal. When set, the signal value takes precedence over the static direction set via BoxWidget.SetDirection.
Because BoxWidget is a container (not user-editable), only state.ReadonlySignal is accepted (no write-back capability is needed).
dir := state.NewSignal(primitives.DirectionHorizontal) box := primitives.Box(a, b).DirectionSignal(dir)
func (*BoxWidget) Draw ¶
Draw renders the box background, border, shadow, and then draws all children.
func (*BoxWidget) Event ¶
Event dispatches the event to children. Returns true if any child consumed it.
func (*BoxWidget) Gap ¶
Gap sets the spacing between children. The gap is applied in the layout direction: vertically for DirectionVertical, horizontally for DirectionHorizontal.
func (*BoxWidget) Layout ¶
Layout calculates the box size by laying out children in the resolved direction (vertical or horizontal) with padding and gap, then constraining the result.
func (*BoxWidget) MaxHeightValue ¶
MaxHeightValue sets the maximum height.
func (*BoxWidget) MaxWidthValue ¶
MaxWidthValue sets the maximum width.
func (*BoxWidget) MinHeightValue ¶
MinHeightValue sets the minimum height.
func (*BoxWidget) MinWidthValue ¶
MinWidthValue sets the minimum width.
func (*BoxWidget) Mount ¶
Mount creates signal bindings for push-based invalidation. Implements widget.Lifecycle.
func (*BoxWidget) PaddingBottom ¶
PaddingBottom sets the bottom padding.
func (*BoxWidget) PaddingLeft ¶
PaddingLeft sets the left padding.
func (*BoxWidget) PaddingRight ¶
PaddingRight sets the right padding.
func (*BoxWidget) PaddingTop ¶
PaddingTop sets the top padding.
func (*BoxWidget) ResolvedDirection ¶
ResolvedDirection returns the effective layout direction. Priority: ReadonlySignal > Static.
func (*BoxWidget) SetDirection ¶
SetDirection sets the layout direction for child widgets.
primitives.Box(a, b, c).SetDirection(primitives.DirectionHorizontal)
func (*BoxWidget) ShadowLevel ¶
ShadowLevel sets the elevation shadow level (0-5).
func (*BoxWidget) Unmount ¶
func (b *BoxWidget) Unmount()
Unmount is called when the box widget is removed from the widget tree. Implements widget.Lifecycle.
type Direction ¶
type Direction uint8
Direction specifies the layout direction for child widgets within a container.
type ExpandedWidget ¶ added in v0.1.4
type ExpandedWidget struct {
widget.WidgetBase
// contains filtered or unexported fields
}
ExpandedWidget wraps a widget to indicate it should fill all remaining space in a BoxWidget layout (HBox/VBox). Without Expanded, children take only their intrinsic size. With Expanded, the child receives all space left after fixed-size siblings are measured.
ExpandedWidget is transparent: it delegates Layout, Draw, Event, and Children entirely to its wrapped child. It serves only as a marker for the parent BoxWidget's two-pass layout algorithm.
Usage:
primitives.HBox(
leftPanel.Width(56), // fixed 56px
primitives.Expanded(editor), // fills remaining
rightPanel.Width(40), // fixed 40px
)
Multiple Expanded children in the same BoxWidget split the remaining space equally:
primitives.HBox(
primitives.Expanded(left), // 50% of remaining
primitives.Expanded(right), // 50% of remaining
)
func Expanded ¶ added in v0.1.4
func Expanded(child widget.Widget) *ExpandedWidget
Expanded wraps a widget to mark it as filling remaining space in a BoxWidget. The child must not be nil.
func (*ExpandedWidget) AccessibilityActions ¶ added in v0.1.4
func (e *ExpandedWidget) AccessibilityActions() []a11y.Action
AccessibilityActions delegates to the child if it implements a11y.Accessible.
func (*ExpandedWidget) AccessibilityHint ¶ added in v0.1.4
func (e *ExpandedWidget) AccessibilityHint() string
AccessibilityHint delegates to the child if it implements a11y.Accessible.
func (*ExpandedWidget) AccessibilityLabel ¶ added in v0.1.4
func (e *ExpandedWidget) AccessibilityLabel() string
AccessibilityLabel delegates to the child if it implements a11y.Accessible.
func (*ExpandedWidget) AccessibilityRole ¶ added in v0.1.4
func (e *ExpandedWidget) AccessibilityRole() a11y.Role
AccessibilityRole delegates to the child if it implements a11y.Accessible, otherwise returns a11y.RoleNone.
func (*ExpandedWidget) AccessibilityState ¶ added in v0.1.4
func (e *ExpandedWidget) AccessibilityState() a11y.State
AccessibilityState delegates to the child if it implements a11y.Accessible.
func (*ExpandedWidget) AccessibilityValue ¶ added in v0.1.4
func (e *ExpandedWidget) AccessibilityValue() string
AccessibilityValue delegates to the child if it implements a11y.Accessible.
func (*ExpandedWidget) Child ¶ added in v0.1.4
func (e *ExpandedWidget) Child() widget.Widget
Child returns the wrapped widget.
func (*ExpandedWidget) Children ¶ added in v0.1.4
func (e *ExpandedWidget) Children() []widget.Widget
Children returns the wrapped child as a single-element slice.
func (*ExpandedWidget) Draw ¶ added in v0.1.4
func (e *ExpandedWidget) Draw(ctx widget.Context, canvas widget.Canvas)
Draw delegates to the wrapped child, applying a transform for positioning.
func (*ExpandedWidget) Event ¶ added in v0.1.4
Event delegates to the wrapped child with coordinate translation for mouse and wheel events.
func (*ExpandedWidget) IsExpanded ¶ added in v0.1.4
func (e *ExpandedWidget) IsExpanded() bool
IsExpanded returns true. Public API for querying expanded state.
func (*ExpandedWidget) Layout ¶ added in v0.1.4
func (e *ExpandedWidget) Layout(ctx widget.Context, constraints geometry.Constraints) geometry.Size
Layout delegates to the wrapped child and stores the resulting bounds.
type ImageFit ¶
type ImageFit uint8
ImageFit specifies how an image is sized relative to its container.
const ( // ImageFitContain scales the image to fit entirely within the container // while preserving aspect ratio. The image may not fill the entire // container. ImageFitContain ImageFit = iota // ImageFitCover scales the image to completely cover the container while // preserving aspect ratio. Parts of the image may be clipped. ImageFitCover // ImageFitFill stretches the image to exactly fill the container, // ignoring aspect ratio. ImageFitFill // ImageFitNone displays the image at its natural size, centered within // the container. Overflow is clipped. ImageFitNone )
ImageFit constants.
type ImageSource ¶
type ImageSource interface {
// Bounds returns the natural pixel dimensions of the image.
Bounds() [2]float32
}
ImageSource provides the natural dimensions of an image.
Concrete implementations are provided by the rendering backend. The primitives package only queries the image bounds for layout; actual pixel data is drawn by the backend-specific Canvas implementation.
type ImageStyle ¶
type ImageStyle struct {
// ExplicitWidth and ExplicitHeight override the natural image size.
// Zero means use the natural dimension.
ExplicitWidth float32
ExplicitHeight float32
Fit ImageFit
Radius float32
}
ImageStyle holds all visual styling for an ImageWidget.
type ImageWidget ¶
type ImageWidget struct {
widget.WidgetBase
// contains filtered or unexported fields
}
ImageWidget displays a raster image with configurable fit mode, optional rounded corners, and accessibility alt text.
ImageWidget implements widget.Widget and a11y.Accessible.
Create an ImageWidget with the Image constructor.
func Image ¶
func Image(source ImageSource) *ImageWidget
Image creates a new image widget with the given source.
The source provides the natural pixel dimensions of the image. If source is nil, the widget has zero natural size.
img := primitives.Image(mySource).Size(200, 150).Cover()
func (*ImageWidget) AccessibilityActions ¶
func (w *ImageWidget) AccessibilityActions() []a11y.Action
AccessibilityActions returns nil. Images have no actions.
func (*ImageWidget) AccessibilityHint ¶
func (w *ImageWidget) AccessibilityHint() string
AccessibilityHint returns an empty string.
func (*ImageWidget) AccessibilityLabel ¶
func (w *ImageWidget) AccessibilityLabel() string
AccessibilityLabel returns the alt text.
func (*ImageWidget) AccessibilityRole ¶
func (w *ImageWidget) AccessibilityRole() a11y.Role
AccessibilityRole returns a11y.RoleImage.
func (*ImageWidget) AccessibilityState ¶
func (w *ImageWidget) AccessibilityState() a11y.State
AccessibilityState returns the default state.
func (*ImageWidget) AccessibilityValue ¶
func (w *ImageWidget) AccessibilityValue() string
AccessibilityValue returns an empty string.
func (*ImageWidget) Alt ¶
func (w *ImageWidget) Alt(text string) *ImageWidget
Alt sets the accessibility alt text.
func (*ImageWidget) AltText ¶
func (w *ImageWidget) AltText() string
AltText returns the accessibility alt text.
func (*ImageWidget) Children ¶
func (w *ImageWidget) Children() []widget.Widget
Children returns nil. Image is a leaf widget.
func (*ImageWidget) Contain ¶
func (w *ImageWidget) Contain() *ImageWidget
Contain is a shorthand for Fit(ImageFitContain).
func (*ImageWidget) Cover ¶
func (w *ImageWidget) Cover() *ImageWidget
Cover is a shorthand for Fit(ImageFitCover).
func (*ImageWidget) Draw ¶
func (w *ImageWidget) Draw(_ widget.Context, canvas widget.Canvas)
Draw renders the image placeholder.
The current implementation draws a light gray rectangle with a centered cross to indicate the image area. Full image rendering requires a Canvas implementation that supports DrawImage, which will be provided by the rendering backend.
func (*ImageWidget) Fill ¶
func (w *ImageWidget) Fill() *ImageWidget
Fill is a shorthand for Fit(ImageFitFill).
func (*ImageWidget) Fit ¶
func (w *ImageWidget) Fit(f ImageFit) *ImageWidget
Fit sets the image fit mode.
func (*ImageWidget) Layout ¶
func (w *ImageWidget) Layout(_ widget.Context, constraints geometry.Constraints) geometry.Size
Layout determines the widget size based on the image source bounds, the explicit size overrides, and the fit mode.
func (*ImageWidget) Rounded ¶
func (w *ImageWidget) Rounded(r float32) *ImageWidget
Rounded sets the border radius for clipping.
func (*ImageWidget) Size ¶
func (w *ImageWidget) Size(width, height float32) *ImageWidget
Size sets explicit width and height.
func (*ImageWidget) Source ¶
func (w *ImageWidget) Source() ImageSource
Source returns the image source.
func (*ImageWidget) Style ¶
func (w *ImageWidget) Style() ImageStyle
Style returns the current image style (read-only snapshot).
type Option ¶
type Option func(*RepaintBoundary)
Option configures a RepaintBoundary.
func WithDebugLabel ¶
WithDebugLabel sets an optional label for diagnostics and logging.
func WithRasterCacheConfig ¶ added in v0.1.14
func WithRasterCacheConfig(cfg RasterCacheConfig) Option
WithRasterCacheConfig sets a custom raster cache configuration for a RepaintBoundary. By default, DefaultRasterCacheConfig is used.
type RasterCacheConfig ¶ added in v0.1.14
type RasterCacheConfig struct {
// PromotionThreshold is the number of consecutive cache hits required
// before a boundary is considered stable. Flutter uses 3.
PromotionThreshold int
// MinComplexity is the minimum number of encoding tags (draw commands)
// in the scene to qualify for promotion. Simple scenes (e.g., a single
// rectangle) are cheap to replay and don't benefit from caching.
// Flutter uses ~20 encoding operations.
MinComplexity int
// MinArea is the minimum pixel area (width * height) for promotion.
// Small boundaries have negligible replay cost and the overhead of
// tracking/promoting them is not worthwhile.
MinArea int
}
RasterCacheConfig controls heuristic parameters for display list stability tracking in RepaintBoundary. When a boundary's scene is replayed for several consecutive frames without invalidation (consecutiveHits >= threshold), and the content is complex enough (tag count > minComplexity) and large enough (area >= minArea), the boundary is promoted to "stable" status.
Stable boundaries indicate to the compositor that these display lists rarely change and are candidates for GPU texture caching (Phase 4: actual texture promotion when gg exposes DrawGPUTexture through the Canvas interface).
This follows the Flutter RasterCache pattern (raster_cache.cc):
- Track consecutive cache hits per boundary
- Promote after N consecutive hits with sufficient complexity
- Demote on cache invalidation (boundaryDirty)
All fields have sane defaults via DefaultRasterCacheConfig.
func DefaultRasterCacheConfig ¶ added in v0.1.14
func DefaultRasterCacheConfig() RasterCacheConfig
DefaultRasterCacheConfig returns the default raster cache configuration.
Values follow Flutter's RasterCache heuristics:
- PromotionThreshold: 3 consecutive cache hits
- MinComplexity: 20 encoding tags (draw commands)
- MinArea: 4096 pixels (64x64)
type RasterCacheStats ¶ added in v0.1.14
type RasterCacheStats struct {
// ConsecutiveHits is the number of consecutive cache hits since the
// last cache miss (boundary dirty or first draw). Reset to 0 on miss.
ConsecutiveHits int
// IsStable is true when the boundary has been promoted to stable status
// (consecutiveHits >= threshold, complexity and area qualifiers met).
// Stable boundaries are candidates for GPU texture caching.
IsStable bool
// TagCount is the number of encoding tags in the cached scene.
// Zero when no scene is cached.
TagCount int
// Area is the pixel area (width * height) of the boundary.
Area int
// TotalPromotions is the cumulative count of times this boundary
// has been promoted to stable status (for diagnostics).
TotalPromotions int
// TotalDemotions is the cumulative count of times this boundary
// has been demoted from stable status (for diagnostics).
TotalDemotions int
}
RasterCacheStats provides observability into the raster cache state of a RepaintBoundary. Used for diagnostics, benchmarks, and compositor optimization decisions.
type RepaintBoundary ¶
type RepaintBoundary struct {
widget.WidgetBase
// contains filtered or unexported fields
}
RepaintBoundary is a display widget that caches its child subtree as a scene.Scene display list. When the child subtree is clean (no dirty widgets), the cached display list is replayed into the parent canvas instead of re-executing Draw on every descendant.
This is the Flutter RepaintBoundary / PictureLayer pattern: an explicit opt-in boundary that isolates expensive subtrees from the rest of the render tree. Display lists are portable across all gg backends (Vulkan, DX12, Metal, GLES, Software, future WASM/WebGPU).
Cache lifecycle:
- The cached scene is allocated on first draw (lazy).
- The cache is invalidated when any descendant calls SetNeedsRedraw, which propagates UP to the boundary (ADR-007 upward propagation), or when the widget size changes.
- The cache is freed on Unmount.
RepaintBoundary implements widget.Widget and a11y.Accessible.
Example:
expensive := primitives.Box(
primitives.Text("Complex chart..."),
).Padding(16)
cached := primitives.NewRepaintBoundary(expensive)
func NewRepaintBoundary ¶
func NewRepaintBoundary(child widget.Widget, opts ...Option) *RepaintBoundary
NewRepaintBoundary creates a RepaintBoundary that caches the rendering of the given child widget as a scene.Scene display list.
If child is nil, the boundary renders nothing and reports zero size.
Options:
- WithDebugLabel — optional label for diagnostics
func (*RepaintBoundary) AccessibilityActions ¶
func (rb *RepaintBoundary) AccessibilityActions() []a11y.Action
AccessibilityActions returns nil.
func (*RepaintBoundary) AccessibilityHint ¶
func (rb *RepaintBoundary) AccessibilityHint() string
AccessibilityHint returns an empty string.
func (*RepaintBoundary) AccessibilityLabel ¶
func (rb *RepaintBoundary) AccessibilityLabel() string
AccessibilityLabel returns the debug label or empty string.
func (*RepaintBoundary) AccessibilityRole ¶
func (rb *RepaintBoundary) AccessibilityRole() a11y.Role
AccessibilityRole returns a11y.RoleGenericContainer.
func (*RepaintBoundary) AccessibilityState ¶
func (rb *RepaintBoundary) AccessibilityState() a11y.State
AccessibilityState returns the default state.
func (*RepaintBoundary) AccessibilityValue ¶
func (rb *RepaintBoundary) AccessibilityValue() string
AccessibilityValue returns an empty string.
func (*RepaintBoundary) CacheHits ¶
func (rb *RepaintBoundary) CacheHits() int
CacheHits returns how many times the cache was served instead of re-rendering.
func (*RepaintBoundary) CacheKey ¶ added in v0.1.14
func (rb *RepaintBoundary) CacheKey() uint64
CacheKey returns the unique monotonic ID for this boundary.
func (*RepaintBoundary) CacheValid ¶
func (rb *RepaintBoundary) CacheValid() bool
CacheValid reports whether the cached scene holds valid content.
func (*RepaintBoundary) Child ¶
func (rb *RepaintBoundary) Child() widget.Widget
Child returns the wrapped child widget.
func (*RepaintBoundary) Children ¶
func (rb *RepaintBoundary) Children() []widget.Widget
Children returns the child widget, or nil if none.
func (*RepaintBoundary) ClearBoundaryDirty ¶ added in v0.1.14
func (rb *RepaintBoundary) ClearBoundaryDirty()
ClearBoundaryDirty resets the boundary dirty flag after the boundary has been repainted. Called by the Window after painting dirty boundaries.
func (*RepaintBoundary) ConsecutiveHits ¶ added in v0.1.14
func (rb *RepaintBoundary) ConsecutiveHits() int
ConsecutiveHits returns the number of consecutive cache hits since the last cache miss. Used for observability and testing.
func (*RepaintBoundary) DebugLabel ¶
func (rb *RepaintBoundary) DebugLabel() string
DebugLabel returns the diagnostic label, or empty string if none set.
func (*RepaintBoundary) Draw ¶
func (rb *RepaintBoundary) Draw(ctx widget.Context, canvas widget.Canvas)
Draw renders the child subtree, using the scene cache when possible.
On cache hit (boundary not dirty, cached scene exists): replays the cached scene.Scene into the canvas via Canvas.ReplayScene — no child re-execution. This is O(commands) via Encoding.Append or GPU dispatch.
On cache miss (boundary dirty or first draw): records child.Draw into a new scene.Scene via SceneCanvas, then replays the result.
This is the ADR-007 retained-mode pattern: display list per boundary.
func (*RepaintBoundary) InvalidateCache ¶
func (rb *RepaintBoundary) InvalidateCache()
InvalidateCache marks the cache as stale, forcing a re-record on the next draw pass. This is called automatically when descendants are dirty; manual invocation is rarely needed.
func (*RepaintBoundary) IsBoundaryDirty ¶ added in v0.1.14
func (rb *RepaintBoundary) IsBoundaryDirty() bool
IsBoundaryDirty reports whether this boundary has been marked dirty by upward propagation since the last draw pass.
func (*RepaintBoundary) IsStable ¶ added in v0.1.14
func (rb *RepaintBoundary) IsStable() bool
IsStable reports whether this boundary has been promoted to stable status by the raster cache heuristic. Stable boundaries have had consecutive cache hits >= the promotion threshold, with sufficient complexity and area.
Stable boundaries are candidates for GPU texture caching (future Phase 4). The compositor can use this to prioritize GPU texture allocation.
func (*RepaintBoundary) Layout ¶
func (rb *RepaintBoundary) Layout(ctx widget.Context, constraints geometry.Constraints) geometry.Size
Layout delegates to the child and stores the resulting size.
func (*RepaintBoundary) MarkBoundaryDirty ¶ added in v0.1.14
func (rb *RepaintBoundary) MarkBoundaryDirty()
MarkBoundaryDirty marks this repaint boundary as needing re-rendering.
Called by the upward dirty propagation in widget.WidgetBase.SetNeedsRedraw when a descendant widget changes. This invalidates the scene cache and notifies the Window (via callback) to add this boundary to its dirty set.
Implements widget.RepaintBoundaryMarker.
func (*RepaintBoundary) RasterCacheStats ¶ added in v0.1.14
func (rb *RepaintBoundary) RasterCacheStats() RasterCacheStats
RasterCacheStats returns a snapshot of the raster cache state for this boundary. Used for diagnostics, benchmarks, and compositor decisions.
func (*RepaintBoundary) SceneChanged ¶ added in v0.1.14
func (rb *RepaintBoundary) SceneChanged(sinceVersion uint64) bool
SceneChanged reports whether the boundary's scene has changed since the given version. Used by the compositor to determine which boundaries need re-compositing in the damage-aware pipeline (Task 3d).
Usage:
if rb.SceneChanged(lastVersion) {
// Re-composite this boundary's region.
lastVersion = rb.SceneVersion()
}
func (*RepaintBoundary) SceneVersion ¶ added in v0.1.14
func (rb *RepaintBoundary) SceneVersion() uint64
SceneVersion returns a monotonic counter that increments each time the boundary's scene cache is re-recorded. The compositor uses this to detect when a boundary's content has actually changed between frames.
When SceneVersion() == lastObservedVersion, the boundary's scene has not changed and the compositor can skip re-compositing this region.
func (*RepaintBoundary) SetOnBoundaryDirty ¶ added in v0.1.14
func (rb *RepaintBoundary) SetOnBoundaryDirty(fn func(rb *RepaintBoundary))
SetOnBoundaryDirty sets the callback invoked when this boundary transitions from clean to dirty via upward propagation.
Used by the Window to collect dirty boundaries into its set.
func (*RepaintBoundary) Unmount ¶
func (rb *RepaintBoundary) Unmount()
Unmount releases the scene cache when the widget is removed from the tree.
type Shadow ¶
type Shadow struct {
// Level is the elevation level from 0 (none) to maxShadowLevel.
Level int
}
Shadow describes a box shadow with an integer elevation level (0-5).
Level 0 means no shadow. Higher levels produce progressively larger and more diffuse shadows. The rendering of each level is determined by the current theme; the primitives package uses a simple constant lookup.
type TextOverflow ¶
type TextOverflow uint8
TextOverflow specifies how text behaves when it exceeds its container.
const ( // TextOverflowClip clips overflowing text at the container boundary. TextOverflowClip TextOverflow = iota // TextOverflowEllipsis truncates overflowing text and appends "...". TextOverflowEllipsis )
TextOverflow constants.
func (TextOverflow) String ¶
func (o TextOverflow) String() string
String returns a human-readable name for the text overflow mode.
type TextStyle ¶
type TextStyle struct {
FontSize float32
Color widget.Color
Bold bool
Align TextAlign
MaxLines int
Overflow TextOverflow
LineHeight float32
}
TextStyle holds all visual styling for a TextWidget.
type TextWidget ¶
type TextWidget struct {
widget.WidgetBase
// contains filtered or unexported fields
}
TextWidget displays static or reactive text content.
TextWidget implements widget.Widget and a11y.Accessible.
Create a TextWidget with Text (static) or TextFn (reactive).
Theme-Aware Default Color ¶
By default, TextWidget uses the theme's OnSurface color for text when a ThemeProvider is available on the context. If no theme is set, the fallback is widget.ColorBlack. An explicit call to TextWidget.Color always takes precedence over the theme default.
func Text ¶
func Text(content string) *TextWidget
Text creates a new text widget with static content.
label := primitives.Text("Hello World").FontSize(18).Bold()
func TextFn ¶
func TextFn(fn func() string) *TextWidget
TextFn creates a new text widget with reactive content.
The function fn is called during layout and draw to obtain the current text. When the function reads a signal's value, changes to that signal will cause re-layout and re-draw when the binding is set up externally.
counter := state.NewSignal(0)
label := primitives.TextFn(func() string {
return fmt.Sprintf("Count: %d", counter.Get())
}).FontSize(14)
func (*TextWidget) AccessibilityActions ¶
func (t *TextWidget) AccessibilityActions() []a11y.Action
AccessibilityActions returns nil. Text has no actions.
func (*TextWidget) AccessibilityHint ¶
func (t *TextWidget) AccessibilityHint() string
AccessibilityHint returns an empty string.
func (*TextWidget) AccessibilityLabel ¶
func (t *TextWidget) AccessibilityLabel() string
AccessibilityLabel returns the text content.
func (*TextWidget) AccessibilityRole ¶
func (t *TextWidget) AccessibilityRole() a11y.Role
AccessibilityRole returns a11y.RoleLabel.
func (*TextWidget) AccessibilityState ¶
func (t *TextWidget) AccessibilityState() a11y.State
AccessibilityState returns the default state.
func (*TextWidget) AccessibilityValue ¶
func (t *TextWidget) AccessibilityValue() string
AccessibilityValue returns an empty string.
func (*TextWidget) Align ¶
func (t *TextWidget) Align(a TextAlign) *TextWidget
Align sets horizontal text alignment.
func (*TextWidget) Children ¶
func (t *TextWidget) Children() []widget.Widget
Children returns nil. Text is a leaf widget.
func (*TextWidget) Color ¶
func (t *TextWidget) Color(c widget.Color) *TextWidget
Color sets the text color explicitly.
An explicit color always takes precedence over the theme's default OnSurface color.
func (*TextWidget) Content ¶
func (t *TextWidget) Content() string
Content returns the current text content.
Resolution priority: [ContentSignal] > TextFn > static Text.
func (*TextWidget) ContentSignal ¶
func (t *TextWidget) ContentSignal(sig state.ReadonlySignal[string]) *TextWidget
ContentSignal binds the text content to a read-only reactive signal. When set, the signal value takes precedence over both TextFn and static content set via Text.
Because TextWidget is display-only, only state.ReadonlySignal is accepted (no write-back capability is needed).
name := state.NewSignal("Alice")
label := primitives.Text("").ContentSignal(name).FontSize(14)
func (*TextWidget) Draw ¶
func (t *TextWidget) Draw(ctx widget.Context, canvas widget.Canvas)
Draw renders the text content.
The text color is resolved with the following priority:
- Explicit color set via TextWidget.Color (always wins)
- ThemeProvider's OnSurface color (if a theme is active)
- widget.ColorBlack (fallback when no theme is set)
func (*TextWidget) Ellipsis ¶
func (t *TextWidget) Ellipsis() *TextWidget
Ellipsis enables truncation with "..." when text overflows.
func (*TextWidget) FontSize ¶
func (t *TextWidget) FontSize(size float32) *TextWidget
FontSize sets the font size in logical pixels.
func (*TextWidget) IsReactive ¶
func (t *TextWidget) IsReactive() bool
IsReactive returns true if the widget uses a function or signal for its content.
func (*TextWidget) Layout ¶
func (t *TextWidget) Layout(_ widget.Context, constraints geometry.Constraints) geometry.Size
Layout measures the text and returns the constrained size.
Text measurement uses a simple character-width heuristic. Real font measurement is delegated to the Canvas implementation in production.
func (*TextWidget) LineHeight ¶
func (t *TextWidget) LineHeight(v float32) *TextWidget
LineHeight sets the line height multiplier. The default is 1.2.
func (*TextWidget) MaxLines ¶
func (t *TextWidget) MaxLines(n int) *TextWidget
MaxLines limits the number of displayed lines. Zero means unlimited.
func (*TextWidget) Mount ¶
func (t *TextWidget) Mount(ctx widget.Context)
Mount creates signal bindings for push-based invalidation. Implements widget.Lifecycle.
func (*TextWidget) Style ¶
func (t *TextWidget) Style() TextStyle
Style returns the current text style (read-only snapshot).
func (*TextWidget) Unmount ¶
func (t *TextWidget) Unmount()
Unmount is called when the text widget is removed from the widget tree. Implements widget.Lifecycle.
type ThemeScopeWidget ¶
type ThemeScopeWidget struct {
widget.WidgetBase
// contains filtered or unexported fields
}
ThemeScopeWidget overrides the theme for a subtree of widgets.
All descendants of a ThemeScopeWidget receive the scoped ThemeProvider instead of the application-level theme. This enables use cases like a dark dialog inside a light application, a branded section, or a high-contrast widget region.
ThemeScopeWidget is transparent to layout: it delegates sizing entirely to its single child. If the scope has no child, it reports zero size.
Nested ThemeScopeWidgets follow the "nearest wins" rule, matching the Flutter InheritedWidget pattern. The priority chain is:
Widget override > Nearest ThemeScope > App theme > Default
Create a ThemeScopeWidget with the ThemeScope constructor.
Example:
darkTheme := material3.NewDark(widget.Hex(0x6750A4))
scoped := primitives.ThemeScope(darkTheme,
primitives.Text("Dark text"),
primitives.Box(
primitives.Text("Also dark"),
).Padding(8),
)
func ThemeScope ¶
func ThemeScope(theme widget.ThemeProvider, children ...widget.Widget) *ThemeScopeWidget
ThemeScope creates a new ThemeScopeWidget that overrides the theme for the given children.
If multiple children are provided, they are wrapped in a Box container for vertical layout. A single child is used directly. If no children are provided, the scope has no child and reports zero size.
The theme parameter must not be nil; passing nil causes ThemeScope to behave as if no theme override is applied (the parent context theme is used).
func (*ThemeScopeWidget) Children ¶
func (ts *ThemeScopeWidget) Children() []widget.Widget
Children returns the child widget, or nil if none.
func (*ThemeScopeWidget) Draw ¶
func (ts *ThemeScopeWidget) Draw(ctx widget.Context, canvas widget.Canvas)
Draw renders the child with the scoped theme context.
func (*ThemeScopeWidget) Event ¶
Event dispatches events to the child with the scoped theme context.
func (*ThemeScopeWidget) Layout ¶
func (ts *ThemeScopeWidget) Layout(ctx widget.Context, constraints geometry.Constraints) geometry.Size
Layout delegates sizing to the child widget, passing a context with the overridden theme.
func (*ThemeScopeWidget) SetTheme ¶
func (ts *ThemeScopeWidget) SetTheme(theme widget.ThemeProvider)
SetTheme changes the scoped theme.
func (*ThemeScopeWidget) Theme ¶
func (ts *ThemeScopeWidget) Theme() widget.ThemeProvider
Theme returns the ThemeProvider set on this scope.