gui

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: May 9, 2026 License: MIT Imports: 20 Imported by: 0

README

go-rlgui

Go Reference

go-rlgui is a box-model UI library for raylib-go that sits between immediate-mode and retained-mode: the node tree is rebuilt from scratch every frame, so your UI code reads top-to-bottom like an immediate-mode library, but widget state (scroll offsets, slider positions, text input contents, dropdown selections) is persisted across frames in a cache keyed by stable node IDs.

A real world example using this library can be found here.


Installation

go get github.com/MarcosTypeAP/go-rlgui

Requirements: Go 1.24+ and a working raylib-go setup.


Quick start

package main

import (
    gui "github.com/MarcosTypeAP/go-rlgui"
    rl  "github.com/gen2brain/raylib-go/raylib"
)

func main() {
	rl.SetConfigFlags(rl.FlagWindowResizable | rl.FlagMsaa4xHint)

    gui.InitWindow(gui.Vec2(800, 600), "My App")
    defer gui.CloseWindow()

    rl.SetTargetFPS(60)

    // Every [SubWindow] needs a root. [ZIndexRoot] pins it behind floating windows.
    sw := gui.AddSubWindow(gui.NewSubWindow(gui.SubWindowProps{
        SizingX: gui.Grow(),
        SizingY: gui.Grow(),
        ZIndex:  gui.ZIndexRoot,
    }), gui.Vec2(0, 0))

    for !rl.WindowShouldClose() {
        // 1. Clear the previous tree
        gui.ResetLayout()

        // 2. Rebuild the tree
        root := sw.SetRoot(gui.NewBox(gui.BoxProps{
            SizingX:     gui.Grow(),
            SizingY:     gui.Grow(),
            Padding:     gui.Padding(20),
            BgColor:     gui.ColorHex(0x1A1F25FF),
            Orientation: gui.Vertical,
            ChildGap:    12,
        }))

        btn := gui.AddChild(root, gui.NewButton(gui.ButtonProps{
            BoxProps: gui.BoxProps{
                Padding:      gui.Padding(10, 20),
                BgColor:      rl.DarkBlue,
                CornerRadius: gui.Radius(8),
                ChildAlignX:  gui.Center,
            },
            OnHover: gui.EffectBrighten,
        }))
        gui.AddChild(btn, gui.NewText(gui.TextProps{}, "Click me"))

        // 3. Resolve all sizes and positions
        gui.ComputeLayout()

        // 4. Process input and widget state
        gui.Update()       

        // 5. React to input after Update,
        //    or add a callback with [gui.AddPostUpdate].
        if btn.IsLeftButtonPressed() {
            // handle click
        }

        // 6. Draw everything
        rl.BeginDrawing()
        gui.Render()
        rl.EndDrawing()
    }
}

Frame loop

Every frame must follow this order:

Step
1 Call gui.ResetLayout() to clear the node tree (does not wipe widget state caches).
2 Build the tree calling gui.AddChild(...) to the root (SubWindow.Root() / SubWindow.SetRoot(...)) to describe the UI.
3 Call gui.ComputeLayout() to resolve all sizes and absolute positions.
4 Call gui.Update() to process input, update nodes, run gui.AddPostUpdate callbacks.
5 React to input reading node state (Button.IsLeftButtonPressed(), Slider.GetValue(), …).
6 Call gui.Render() to draw the tree; must be called between rl.BeginDrawing / rl.EndDrawing.

Post-update logic can be registered with gui.AddPostUpdate(func() { ... }) during tree construction so it runs after gui.Update().


Sizing

Every axis of every box is sized independently via a SizingProp. Short aliases from aliases.go are shown alongside the full constructors.

Alias Constructor Behaviour
Shrink(min?, max?) NewSizingShrink Shrinks to fit content. Optional min/max pixel constraints.
Grow(min?, max?) NewSizingGrow Expands to fill remaining space in the parent. Optional min/max pixel constraints.
Fixed(px) NewSizingFixed Locked to an exact pixel size.
Percentage(pct, min?, max?) NewSizingPercentage Fraction of the parent's size on the same axis (0–100). Optional min/max pixel constraints.
AspectRatio(ratio) NewSizingAspectRatio Y axis only — height = width / ratio.
// A box that fills 40 % of its parent's width and grows vertically
gui.BoxProps{
    SizingX: gui.Percentage(40),
    SizingY: gui.Grow(),
}

Styling helpers

Constructor Alias Usage
NewBoxSides(v…) Padding / Border Accepts between 1 and 4 values, following CSS padding shorthand conventions.
NewBoxSidesOverride(base, top, right, bottom, left) PaddingOverride / BorderOverride Start from an existing BoxSides and override specific sides.
NewBoxCorners(v…) Radius Accepts between 1 and 4 values, following CSS border-radius shorthand conventions.
NewBoxCornersOverride(base, topLeft, topRight, bottomRight, bottomLeft) RadiusOverride Start from an existing BoxCorners and override specific corners.

Built-in widgets

Box

It's the fundamental building block of the UI and the base for any node. It is a rectangular container that can hold children, display a background color, gradient, or texture, and draw a bordered rounded rectangle.

gui.NewBox(gui.BoxProps{
    SizingX:     gui.Grow(),
    SizingY:     gui.Fixed(60),
    Padding:     gui.Padding(10),
    BgColor:     gui.ColorHex(0x2F3439FF),
    CornerRadius: gui.Radius(10),
    Orientation: gui.Vertical, // gui.Horizontal or gui.Vertical
    ChildGap:    8,
    ChildAlignX: gui.Center, // gui.Start | gui.Center | gui.End
    ChildAlignY: gui.Start,
    HideOverflow: true,
})
BoxImage

Displays a texture loaded from an fs.FS or the filesystem.

//go:embed icon.png
var assetsFS embed.FS

gui.AddChild(parent, gui.NewBoxImage(gui.BoxProps{
    SizingX:     gui.Fixed(32),
    SizingY:     gui.AspectRatio(1),
}, "icon.png", assetsFS))
Spacer

It's a helper Box constructor that creates a horizontal/vertical spacer. An optional gui.SizingProp controls how much space it occupies; defaults to gui.NewSizingGrow().

gui.AddChild(parent, gui.NewBox( /* … */ ))
gui.AddChild(parent, gui.NewSpacerX()) // Similar effect to CSS "justify-content: space-between";
gui.AddChild(parent, gui.NewBox( /* … */ ))
Text

It's a node that renders a string of text.

gui.NewText(gui.TextProps{
    BoxProps: gui.BoxProps{SizingX: gui.Grow()},
    FontConfigProps: gui.FontConfigProps{
        FgColor:  rl.White,
        FontSize: 24,
    },
    Wrapping: gui.Wrap, // gui.NoWrap | gui.Wrap | gui.EllipsisOverflow
}, "Hello, world!")
Button

It's a clickable container node. It reports press and release events for both mouse buttons and applies optional visual effects on hover and press. Children are added with gui.AddChild(...) to build the button's visual content (icons, labels, etc.).

btn := gui.AddChild(parent, gui.NewButton(gui.ButtonProps{
    BoxProps: gui.BoxProps{ /* … */ },
    OnHover: gui.EffectBrighten,
    OnPress: func(box *gui.Box) func() {
        box.BgColor = rl.DarkGray
        return nil // optional cleanup callback, called when released
    },
}))

// After gui.Update() or inside a gui.AddPostUpdate(...) callback:
if btn.IsLeftButtonPressed() { /* … */ }
ScrollBox

It's a container that clips its children to its visible area and allows scrolling via the mouse wheel or by dragging the scroll thumb.

scroll := gui.AddChild(parent, gui.NewScrollBox(gui.ScrollBoxProps{
    BoxProps: gui.BoxProps{
        ID:          sw.GetAutoID(),
        SizingX:     gui.Grow(),
        SizingY:     gui.Grow(),
        Orientation: gui.Vertical,
        ChildGap:    10,
    },
    ScrollOrientation: gui.Vertical,
    ThumbWidth:        10,
    ThumbColor:        gui.ColorHex(0xFFFFFFAA),
    ThumbCornerRadius: 10,
}))

StatefulWidget note: ScrollBox, Slider, Toggle, CheckBox, TextInput, and Dropdown all require a stable NodeID field so their internal state survives gui.ResetLayout. Use SubWindow.GetAutoID() for automatic sequential IDs, or assign an ID manually by calling gui.NewID(...).

Slider

It's a numeric range input that lets the user drag a thumb along a track to pick a value between min and max.

slider := gui.AddChild(parent, gui.NewSlider(gui.SliderProps{
    BoxProps: gui.BoxProps{
        ID:      sw.GetAutoID(),
        SizingX: gui.Grow(),
        SizingY: gui.Fixed(30),
    },
    TrackActiveColor:  rl.Blue,
    TrackCornerRadius: gui.Radius(420),
    ThumbCornerRadius: gui.Radius(69),
}, 0 /*min*/, 100 /*max*/, 50 /*initial*/))

// After gui.Update() or inside a gui.AddPostUpdate(...) callback:
if slider.IsChanging() {
    value := slider.GetValue()
}
Toggle / CheckBox

It's a boolean switch widget. It renders either as a sliding pill (when created with gui.NewToggle(...)) or as a filled square/circle checkbox (when created with gui.NewCheckBox(...)).

toggle := gui.AddChild(parent, gui.NewToggle(gui.ToggleProps{
    BoxProps: gui.BoxProps{
        ID:           sw.GetAutoID(),
        SizingX:      gui.Fixed(40),
        SizingY:      gui.Fixed(20),
        CornerRadius: gui.Radius(69),
    },
    OnColor:  rl.White,
    OffColor: rl.Gray,
}, false /*initial*/))

// gui.NewCheckBox uses the same ToggleProps signature.
checkbox := gui.AddChild(parent, gui.NewCheckBox(gui.ToggleProps{ /* … */ }, false))

// After gui.Update() or inside a gui.AddPostUpdate(...) callback:
isOn := toggle.GetValue()
Dropdown

It's a single-select control that shows a list of string options. When closed it displays the selected option (or a placeholder); when open it expands downward to show all options. Clicking outside or selecting an option closes the list.

dd := gui.AddChild(parent, gui.NewDropdown(gui.DropdownProps{
    BoxProps: gui.BoxProps{
        ID:           sw.GetAutoID(),
        Padding:      gui.Padding(10, 20),
        CornerRadius: gui.Radius(10),
        BgColor:      gui.ColorHex(0x1A1F25FF),
        BorderWidth:  gui.Border(2),
        BorderColor:  rl.White,
    },
}, "Select…", []string{"Option A", "Option B", "Option C"}, -1 /*initial index, -1 = none*/))

// After gui.Update() or inside a gui.AddPostUpdate(...) callback:
if dd.HasChanged() {
    idx := dd.GetSelectedIdx()
}
TextInput

It's a single-line editable text field. It supports a placeholder string shown when the field is empty, an optional error message displayed below the field, keyboard navigation (arrows, backspace, delete, Ctrl+V), mouse navigation (click to move cursor), and a blinking text cursor.

input := gui.AddChild(parent, gui.NewTextInput(gui.TextInputProps{
    BoxProps: gui.BoxProps{
        ID:           sw.GetAutoID(),
        SizingX:      gui.Grow(),
        BgColor:      rl.DarkGray,
        Padding:      gui.Padding(10, 15),
        CornerRadius: gui.Radius(8),
    },
    PlaceholderColor: rl.Gray,
}, "Placeholder", "Initial value"))

// After gui.Update() or inside a gui.AddPostUpdate(...) callback:
text := input.Value()

Gradients

// Linear gradient at 45 degrees
gui.BoxProps{
    Gradient: gui.GradientLinear(rl.Red, rl.Blue, 45),
}

GradientRadial is declared but not yet implemented (it's just a placeholder for a (perhaps) future implementation).


Sub-windows

Sub-windows are independent layout roots. Floating sub-windows can be dragged and optionally closed.

// Non-floating root window
root := gui.AddSubWindow(gui.NewSubWindow(gui.SubWindowProps{
    SizingX: gui.Grow(),
    SizingY: gui.Grow(),
    ZIndex:  gui.ZIndexRoot,
}), gui.Vec2(0, 0))

// Floating, closable window
floating := gui.AddSubWindow(gui.NewSubWindow(gui.SubWindowProps{
    Floating: true,
    Closable: true,
}), gui.Vec2(200, 150))

// Ephemeral window (hidden as soon as loses focus)
floating := gui.AddSubWindow(gui.NewSubWindow(gui.SubWindowProps{
    Hidden: true,
    ZIndex: gui.ZIndexEphemeral,
}), gui.Vec2(100, 50))

Custom nodes

Implement the Node interface to create fully custom widgets. Embed gui.Box, call gui.CacheNode / gui.GetNodeFromCache for state persistence, and call gui.DebuggingInfo() at the end of gui.Render() to participate in the debug overlay.

type MyWidget struct {
    gui.Box
    // your state fields
}

func NewMyWidget(props gui.BoxProps) *MyWidget {
    if node := gui.GetNodeFromCache[*MyWidget](props.ID); node != nil {
        return node
    }

    n := &MyWidget{}
    n.ApplyProps(props)

    gui.CacheNode(n)
    return n
}

func (n *MyWidget) Update() {
    if !gui.IsNodeHovered(n) {
        return
    }
    // handle input
}

func (n *MyWidget) Render() {
    rect := n.Rect()
    rl.DrawRectangleRec(rect, rl.Purple)

    gui.DebuggingInfo(n) // participates in debug overlay
}

See cmd/example/example.go for a complete PaintNode implementation that draws on a rl.RenderTexture2D.


Global defaults

These package-level variables can be set to tune the library's default behavior (see gui.go).

E.g.: gui.DefaultTextColor, gui.DefaultFontSize, gui.DefaultCharSpacing, gui.ScrollBoxSpeed, gui.FontTextureFilter, ...


Utility functions

Function Description
Clamp(v, min, max) Generic numeric clamp.
Abs(v) Generic absolute value.
Ternary(cond, a, b) Inline conditional; both branches evaluated eagerly.
TernaryLazy(cond, a, b) Same, but branches are func() T — only the chosen one is called.
Must(v, err) Unwraps (T, error), panics on error.
Must2(v1, v2, err) Unwraps (T1, T2, error), panics on error.
Vec2(x, y) Short alias for rl.NewVector2.
Rect(x, y, w, h) Short alias for rl.NewRectangle.
RectPosition(rect) Returns the top-left corner as rl.Vector2.
RectSize(rect) Returns the width and height as rl.Vector2.
ColorHex(0xRRGGBBAA) Short alias for rl.GetColor.
ColorContrast(color, factor) Returns a brightened or darkened version of color.
ColorToUniformVec4(color) Returns a []float32 with each channel normalised to [0, 1].

Custom drawing functions

The library exposes several drawing helpers that use the same internal rounded-rect shader as the built-in widgets.

DrawRectangle

Draws a filled rectangle with optional per-corner radius, per-side border width, and a solid fill color.

gui.DrawRectangle(
    gui.Rect(x, y, w, h),
    gui.Border(2),           // per-side border widths
    gui.Radius(10),          // per-corner radii
    rl.White,                // border color
    gui.ColorHex(0x2F3439FF), // fill color
)
DrawRectangleWithGradient

Same as DrawRectangle but fills with a Gradient instead of a solid color.

gui.DrawRectangleWithGradient(
    gui.Rect(x, y, w, h),
    gui.Border(0),
    gui.Radius(12),
    rl.Blank,
    gui.GradientLinear(rl.Red, rl.Blue, 90),
)
DrawRectangleWithTexture

Same as DrawRectangle but fills with a texture. The textureFit parameter controls how the texture is scaled inside the rectangle.

gui.DrawRectangleWithTexture(
    gui.Rect(x, y, w, h),
    gui.Border(0),
    gui.Radius(8),
    rl.Blank,
    myTexture, rl.White,
    gui.FitCover,   // or gui.FitContain
)
DrawTextEllipsis

Draws text inside a bounding rectangle. If the text is wider than the bounds it is truncated and a suffix is appended. Supports horizontal and vertical alignment.

gui.DrawTextEllipsis(
    gui.Rect(x, y, w, h),
    gui.Center, gui.Center,  // alignX, alignY
    gui.GetDefaultFont(),
    "Some long label that might overflow",
    20, 1, rl.White,         // fontSize, charSpacing, color
)
WrapText

Re-flows a string so no line exceeds the width of bounds. Words are split at spaces and tabs; existing newlines are preserved. Returns the wrapped string with \n separators.

wrapped := gui.WrapText(
    gui.Rect(0, 0, 300, 1000),
    gui.GetDefaultFont(),
    "A long paragraph that needs wrapping",
    20, 1,
)
Scissor clipping

BeginScissorMode / EndScissorMode are nestable wrappers around raylib's scissor API. Each call intersects the new region with the current top-of-stack region, so nested clipping works correctly.

func (n *MyWidget) Render() {
    rect := n.Rect()
    gui.BeginScissorMode(rect)
    defer gui.EndScissorMode()
 
    // anything drawn here is clipped to rect
    rl.DrawCircleV(somePos, 20, rl.Red)
}
Scheduling draw calls

Use AddPostRender to schedule a draw callback that runs after all sub-windows and nodes have been rendered — useful for top-level overlays or debug visualizations that must always appear on top.

gui.AddPostRender(func() {
    rl.DrawText("FPS: "+strconv.Itoa(int(rl.GetFPS())), 10, 10, 20, rl.Green)
})

Examples

Showcase

An example showcase lives in cmd/example/example.go. It demonstrates gradients, a scrollable button grid, a paint canvas (custom node), text input, toggles, checkboxes, a dropdown, sliders, and spawnable floating windows.

go run ./cmd/example

Press Q to quit.

Soundpad

A real world example using this library can be found here.


Licenses

See LICENSE and THIRD_PARTY_LICENSES.

Documentation

Overview

Package gui provides a semi-immediate-mode, box-model UI library for raylib-go.

The library is built around a tree of Node values. Every frame the caller reconstructs the tree, configures sizing, colors, gradients, etc. through Props structs, and then computes the layout, updates the nodes, and finally renders the tree:

// create a sub window
sw := gui.AddSubWindow(gui.NewSubWindow(...), ...)

for !rl.WindowShouldClose() {
	// clear the node tree
	gui.ResetLayout()

	// rebuild the tree with [AddChild] calls
	root := sw.Root() // or sw.SetRoot(gui.NewBox(...))
	childBtn := gui.AddChild(root, gui.NewButton(...))

	// resolve all sizes and positions
	gui.ComputeLayout()

	// process input, nodes, and sub windows, and post-update callbacks
	gui.Update()

	// your logic
	if childBtn.IsLeftButtonPressed() {
		// do something
	}

	// draw everything and run post-render callbacks
	rl.BeginDrawing()
	gui.Render()
	rl.EndDrawing()
}

Stateful widgets (ScrollBox, Slider, Toggle, TextInput, Dropdown, etc.) must be given a NodeID so that their internal state is cached and survives across the rebuild, or set it to NodeIDManual to handle its lifecycle manually.

Custom nodes can be defined by implementing the Node interface.

Index

Constants

View Source
const (
	// Horizontal is a short alias for [OrientationHorizontal].
	Horizontal = OrientationHorizontal

	// Vertical is a short alias for [OrientationVertical].
	Vertical = OrientationVertical
)
View Source
const (
	// NoWrap is a short alias for [TextNoWrap].
	NoWrap = TextNoWrap

	// Wrap is a short alias for [TextWrap].
	Wrap = TextWrap

	// EllipsisOverflow is a short alias for [TextEllipsisOverflow].
	EllipsisOverflow = TextEllipsisOverflow
)
View Source
const (
	// FitCover is a short alias for [TextureFitCover].
	FitCover = TextureFitCover

	// FitContain is a short alias for [TextureFitContain].
	FitContain = TextureFitContain
)
View Source
const (
	// Start is a short alias for [AlignStart].
	Start = AlignStart

	// End is a short alias for [AlignEnd].
	End = AlignEnd

	// Center is a short alias for [AlignCenter].
	Center = AlignCenter
)
View Source
const (
	ShaderRenderModeSolidColor int32 = iota
	ShaderRenderModeGradientLinear
	ShaderRenderModeGradientRadial // Deprecated: unimplemented
	ShaderRenderModeTexture
)

Variables

View Source
var Debug = false

Debug enables per-node visual debugging overlays. When true, DebuggingInfo draws outline rectangles around every node's bounding box and inner (post-padding) rect, and prints node details to stdout when the node is left-clicked.

View Source
var DebugLinesColor = rl.ColorAlpha(rl.Red, 0.5)

DebugLinesColor is the color used for the debug overlay rectangles drawn when Debug is true.

View Source
var DefaultCharSpacing float32 = 1

DefaultCharSpacing is the default pixel gap between glyphs used by *Text and *TextInput nodes.

View Source
var DefaultDropdownCollapseIcon rl.Texture2D

DefaultDropdownCollapseIcon is the texture shown on a *Dropdown when it is expanded. It is initialised by LoadAssets from the bundled icon file and may be replaced before creating any Dropdown nodes.

View Source
var DefaultDropdownExpandIcon rl.Texture2D

DefaultDropdownExpandIcon is the texture shown on a *Dropdown when it is collapsed. It is initialised by LoadAssets from the bundled icon file and may be replaced before creating any Dropdown nodes.

View Source
var DefaultDropdownIconGap float32 = 15

DefaultDropdownIconGap is the horizontal pixel gap between a *Dropdown's icon and its label text.

View Source
var DefaultDropdownIconSizeFactor float32 = 0.7

DefaultDropdownIconSizeFactor is a multiplier applied to the font size to get the width and height used when drawing the expand/collapse icons of a *Dropdown.

View Source
var DefaultErrorColor = rl.Red

DefaultErrorColor is the border and error-message color used by *TextInput when its ErrorMessage field is non-empty.

View Source
var DefaultFontBaselineCorrectionFactor float32 = 0

DefaultFontBaselineCorrectionFactor is a multiplier applied to the font size to nudge the text baseline upward. A value of 0 disables the correction. Increase it slightly if text appears too low inside its bounding box.

View Source
var DefaultFontSize float32 = 20

DefaultFontSize is the font size used by *Text and *TextInput nodes when no explicit size is supplied in FontConfigProps.

View Source
var DefaultScrollBoxThumbWidth float32 = 5

DefaultScrollBoxThumbWidth is the default width (or height for a horizontal scroll bar) of a *ScrollBox thumb in pixels.

View Source
var DefaultSliderThumbWidth float32 = 20

DefaultSliderThumbWidth is the default width (or height for a horizontal slider) of a *Slider thumb in pixels.

View Source
var DefaultSliderTrackWidth float32 = 10

DefaultSliderTrackWidth is the default width (or height for a horizontal slider) of a *Slider track in pixels.

View Source
var DefaultTextColor = rl.Black

DefaultTextColor is the foreground color applied to *Text and *TextInput nodes when no color is set in FontConfigProps.

View Source
var DropdownOptionsBoxMarginTop float32 = 4

DropdownOptionsBoxMarginTop is the space between the selected item and the options box.

View Source
var ErrFontInvalid = errors.New("invalid font")
View Source
var FontTextureFilter = rl.FilterBilinear

FontTextureFilter is the texture-filter mode applied to fonts loaded via LoadFont, LoadFontFromMemory, and LoadFontFS.

View Source
var ImageTextureFilter = rl.FilterBilinear

ImageTextureFilter is the texture-filter mode applied to images loaded via LoadImage, LoadImageTexture and NewBoxImage.

View Source
var InfNegative = float32(math.Inf(-1))

InfNegative is -Inf float32.

View Source
var InfPositive = float32(math.Inf(1))

InfPositive is +Inf float32.

View Source
var ScrollBoxSpeed float32 = 30

ScrollBoxSpeed is the number of pixels scrolled per mouse-wheel tick inside a *ScrollBox.

View Source
var ScrollBoxThumbMargin float32 = 4

ScrollBoxThumbMargin is the margin in pixels at sides of the thumb of a *ScrollBox for interacting with the mouse left-click.

View Source
var SubWindowHeaderHeight float32 = 20

SubWindowHeaderHeight is the pixel height of the draggable title-bar rendered above floating [*SubWindow]s.

Functions

func Abs

func Abs[N Number](v N) N

Abs returns the absolute value of v.

func AddChild

func AddChild[T Node](parent Node, child T) T

AddChild appends child to parent's child list and returns child.

func AddNodeToHighPriorityList

func AddNodeToHighPriorityList(node Node)

AddNodeToHighPriorityList inserts node into the high-priority hover list. Nodes on this list take hover precedence over any other node under the mouse (e.g. an open *Dropdown). The list is ordered; use MoveNodeToTopOfHighPriorityList to adjust priority after insertion. Has no effect if node is already in the list.

func AddPostRender

func AddPostRender(fn func())

AddPostRender schedules fn to be called at the end of the current Render call, after all sub-windows have been rendered.

func AddPostUpdate

func AddPostUpdate(fn func())

AddPostUpdate schedules fn to be called at the end of the current Update call, after all nodes have processed input. Useful to keep locality of behavior.

func BeginScissorMode

func BeginScissorMode(intersection rl.Rectangle)

BeginScissorMode begins a scissor-clipping region that restricts rendering to intersection. Calls can be nested; each call intersects the new region with the current top-of-stack region. Must be balanced with EndScissorMode.

func CacheNode

func CacheNode(node Node)

CacheNode stores node in the per-frame-persistent cache under its ID. Stateful widgets (ScrollBox, Slider, Toggle, TextInput, Dropdown) call this in their constructors so that their state survives the tree rebuild each frame. Panics if node ID is not set. If node ID is NodeIDManual, this is NO-OP.

func Clamp

func Clamp[N Number](v, min, max N) N

Clamp returns v clamped to the closed interval [min, max].

func CloseWindow

func CloseWindow()

CloseWindow calls UnloadAssets and then closes the raylib window. Defer this after InitWindow.

func ColorContrast

func ColorContrast(color rl.Color, factor float32) rl.Color

ColorContrast returns a brightened or darkened version of color. The adjustment direction is chosen automatically based on the perceived luminance of the color so that the result always has higher contrast against the original. factor controls the magnitude [0–1].

func ColorHex

func ColorHex(hexValue uint) rl.Color

ColorHex is a short alias for rl.GetColor.

func ColorToUniformVec4

func ColorToUniformVec4(color rl.Color) []float32

ColorToUniformVec4 converts a rl.Color to a []float32 slice of length 4 with each component normalised to [0, 1]. The slice is suitable for passing to shader uniform setters.

func ComputeLayout

func ComputeLayout()

ComputeLayout computes the layout on all sub-windows. Call this after building the node tree and before Update or Render.

func ConsumeMouseButtonPressed

func ConsumeMouseButtonPressed(button rl.MouseButton)

ConsumeMouseButtonPressed clears the pressed-this-frame flag for button so that subsequent calls to IsMouseButtonPressed for the same button return false. Use this in interactive nodes to prevent multiple handlers from reacting to the same press event.

func ConsumeMouseButtonReleased

func ConsumeMouseButtonReleased(button rl.MouseButton)

ConsumeMouseButtonReleased clears the pressed-this-frame flag for button so that subsequent calls to IsMouseButtonReleased for the same button return false. Use this in interactive nodes to prevent multiple handlers from reacting to the same press event.

func DebuggingInfo

func DebuggingInfo(node Node)

DebuggingInfo draws the debug overlay for node when Debug is true. Custom Node implementations should call this at the end of their Render method to participate in the debug visualisation.

func DrawRectangle

func DrawRectangle(
	rect rl.Rectangle,
	borderWidth BoxSides, cornerRadius BoxCorners, borderColor rl.Color,
	color rl.Color,
)

DrawRectangle draws a rectangle using the library's rounded-rect shader. It supports per-side border widths, per-corner radius, a border color, and a fill color. When no border (none or transparent) and no corner radius are needed the call falls back to the (I suppose) cheaper rl.DrawRectangleRec.

func DrawRectangleWithGradient

func DrawRectangleWithGradient(
	rect rl.Rectangle,
	borderWidth BoxSides, cornerRadius BoxCorners, borderColor rl.Color,
	gradient Gradient,
)

DrawRectangleWithGradient is like DrawRectangle but fills the rectangle with a Gradient instead of a solid color.

func DrawRectangleWithTexture

func DrawRectangleWithTexture(
	rect rl.Rectangle,
	borderWidth BoxSides, cornerRadius BoxCorners, borderColor rl.Color,
	texture rl.Texture2D, textureTint rl.Color, textureFit TextureFit,
)

DrawRectangleWithTexture is like DrawRectangle but fills the rectangle with texture according to the specified textureFit mode.

func DrawTextEllipsis

func DrawTextEllipsis(
	bounds rl.Rectangle,
	alignX, alignY Alignment,
	font rl.Font,
	text string,
	fontSize float32, charSpacing float32, color rl.Color,
)

DrawTextEllipsis draws text inside bounds. If the text is too wide it is truncated and a "..." suffix is appended. The text is aligned horizontally with alignX and vertically with alignY.

func EffectBrighten

func EffectBrighten(box *Box) func()

EffectBrighten is a simple EffectFunc util that lightens the button's background color for the current frame. The mutation is permanent within the frame and the returned cleanup function is nil.

func EndScissorMode

func EndScissorMode()

EndScissorMode pops the current scissor region and restores the previous one. Panics if there is no matching BeginScissorMode call on the stack.

func GetDefaultFont

func GetDefaultFont() rl.Font

GetDefaultFont returns the font that will be used when a node does not specify one in its FontConfigProps. Falls back to the raylib default font if no font has been set via SetDefaultFont.

func GetNodeFromCache

func GetNodeFromCache[N Node](id NodeID) N

GetNodeFromCache retrieves a previously cached node of type N by its ID. If found, the node's layout is reset (parent and position cleared, children list emptied) so it is ready to be re-inserted into the tree. Returns the zero value of N if no node with that ID is cached or the ID is NodeIDManual. Panics if node ID is not set.

func GetScreenSize

func GetScreenSize() rl.Vector2

GetScreenSize returns the current window dimensions as a Vector2. The value is updated once per frame by UpdateScreenSize (called inside Update).

func InitWindow

func InitWindow(size rl.Vector2, title string)

InitWindow creates the raylib window with the given size and title, and calls LoadAssets. Use this instead of rl.InitWindow so that all GUI resources are ready before the first frame.

func IsMouseButtonPressed

func IsMouseButtonPressed(button rl.MouseButton) bool

IsMouseButtonPressed reports whether button was pressed this frame. Unlike rl.IsMouseButtonPressed, this reads from a state snapshot taken at the start of Update, allowing the event to be consumed via ConsumeMouseButtonPressed.

func IsMouseButtonPressedConsume

func IsMouseButtonPressedConsume(button rl.MouseButton) bool

IsMouseButtonPressedConsume is like IsMouseButtonPressed, but consumes the event if button was pressed.

func IsMouseButtonReleased

func IsMouseButtonReleased(button rl.MouseButton) bool

IsMouseButtonReleased reports whether button was released this frame. Unlike rl.IsMouseButtonReleased, this reads from a state snapshot taken at the start of Update, allowing the event to be consumed via ConsumeMouseButtonReleased.

func IsMouseButtonReleasedConsume

func IsMouseButtonReleasedConsume(button rl.MouseButton) bool

IsMouseButtonReleasedConsume is like IsMouseButtonReleased, but consumes the event if button was released.

func IsNodeHovered

func IsNodeHovered(node Node) bool

IsNodeHovered reports whether the mouse cursor is currently positioned over node and no higher-priority node (see AddNodeToHighPriorityList) or a higher-z-index *SubWindow is blocking it.

func IsNodeInHighPriorityList

func IsNodeInHighPriorityList(node Node) bool

IsNodeInHighPriorityList reports whether node is currently registered in the high-priority hover list.

func IsNodeVisible

func IsNodeVisible(node Node) bool

IsNodeVisible reports whether node will produce visible pixels when rendered. A node is not visible if it is marked Invisible, if its Ignored flag is set, or if it is entirely clipped by an ancestor *ScrollBox.

func LoadAssets

func LoadAssets()

LoadAssets loads all shaders, built-in textures, and the fallback font required by the library. It must be called after rl.InitWindow (or InitWindow, which calls it automatically) and before any rendering.

func LoadFont

func LoadFont(fileName string, fontSize int32, codepointCount int, codepoints ...rune) (rl.Font, error)

LoadFont loads a font from disk and applies FontTextureFilter to it.

fileName is the path to the font file, that must supported by raylib. fontSize controls the rasterisation size. codepointCount is the number of codepoints (starting at space, 0x20) to rasterise; pass 0 when supplying an explicit codepoints slice. codepoints is an optional list of Unicode codepoints to include. It is invalid to supply both a non-zero codepointCount and a non-empty codepoints slice.

func LoadFontFS

func LoadFontFS(fileSystem fs.FS, filePath string, fontSize int32, codepointCount int, codepoints ...rune) (rl.Font, error)

LoadFontFS loads a font from an fs.FS (e.g. an embedded FS). filePath must be relative and include a supported extension by raylib. The remaining parameters are identical to LoadFontFromMemory.

func LoadFontFromMemory

func LoadFontFromMemory(fileExtension string, fileData []byte, fontSize int32, codepointCount int, codepoints ...rune) (rl.Font, error)

LoadFontFromMemory loads a font from an in-memory byte slice. fileExtension must be a supported extension by raylib. If codepointCount > 0 and no explicit codepoints are given, the first codepointCount codepoints (starting at space, 0x20) are used. It is invalid to supply both a non-zero codepointCount and a non-empty codepoints slice.

func LoadImage

func LoadImage(filePath string, fileSystem fs.FS) (*rl.Image, error)

LoadImage loads an image from filePath. The result is cached; subsequent calls with the same (filePath, fileSystem) pair return the cached image.

If fileSystem is nil the file is read from the OS filesystem. If fileSystem is non-nil, filePath must be relative.

func LoadImageTexture

func LoadImageTexture(filePath string, fileSystem fs.FS) (rl.Texture2D, error)

LoadImageTexture loads an image from filePath and returns a GPU texture. The result is cached; subsequent calls with the same (filePath, fileSystem) pair return the cached texture.

If fileSystem is nil the file is read from the OS filesystem. If fileSystem is non-nil, filePath must be relative.

The loaded texture has ImageTextureFilter applied.

func MoveNodeToTopOfHighPriorityList

func MoveNodeToTopOfHighPriorityList(node Node)

MoveNodeToTopOfHighPriorityList moves an already-registered node to the highest-priority position. Panics if node is not currently in the list.

func Must

func Must[T any](v T, err error) T

Must unwraps a (T, error) pair. It panics if err is non-nil.

func Must2

func Must2[T1, T2 any](v1 T1, v2 T2, err error) (T1, T2)

Must2 unwraps a (T1, T2, error) triple. It panics if err is non-nil.

func Pointer deprecated

func Pointer[T any](value T) *T

Pointer returns a pointer to value. This is a helper for taking the address of a literal.

Deprecated: Use the built-in new(value) syntax if using go >= 1.26.0

func Rect

func Rect(x, y, width, height float32) rl.Rectangle

Rect is a short alias for rl.NewRectangle.

func RectPosition

func RectPosition(rect rl.Rectangle) rl.Vector2

RectPosition returns the top-left corner of rect as a rl.Vector2.

func RectSize

func RectSize(rect rl.Rectangle) rl.Vector2

RectSize returns the width and height of rect as a rl.Vector2.

func RemoveNodeFromCache

func RemoveNodeFromCache(id NodeID)

RemoveNodeFromCache removes the node associated with ID from the cache. Use this when you need to force a stateful widget to reset to its initial state (e.g. after the data it displays has changed programmatically). Panics if node ID is not set. If node ID is NodeIDManual, this is NO-OP.

func RemoveNodeFromHighPriorityList

func RemoveNodeFromHighPriorityList(node Node)

RemoveNodeFromHighPriorityList removes node from the high-priority list. Has no effect if node is not in the list.

func RemoveSubWindow

func RemoveSubWindow(subWindow *SubWindow)

RemoveSubWindow unregisters subWindow from the global sub-window list. Panics if subWindow is not currently registered.

func Render

func Render()

Render draws all sub-windows and their node trees in z-index order (lowest first). Must be called between rl.BeginDrawing and rl.EndDrawing. Panics if LoadAssets has not been called.

func ResetIDs

func ResetIDs()

ResetIDs clears all auto-generated IDs from all sub-windows and removes the corresponding nodes from the cache.

func ResetLayout

func ResetLayout()

ResetLayout clears the child list of every sub-window's root node and restarts the auto-ID counters. Call this at the beginning of each frame before rebuilding the UI tree.

func RestartIDs

func RestartIDs()

RestartIDs rewinds the auto-ID cursors on all sub-windows without evicting anything from the node cache. This is called automatically by ResetLayout each frame so that auto-IDs are handed out in the same sequence on every rebuild.

func SetDefaultFont

func SetDefaultFont(font rl.Font)

SetDefaultFont replaces the font returned by GetDefaultFont.

func SetMouseCursor

func SetMouseCursor(cursor rl.MouseCursor)

SetMouseCursor requests that the OS cursor be changed to cursor for the current frame. The last call wins; the cursor is applied at the end of Update.

func Ternary

func Ternary[T any](condition bool, a, b T) T

Ternary returns a if condition is true, otherwise b. Both a and b are evaluated eagerly; use TernaryLazy to avoid that. Useful for Node construction.

func TernaryLazy

func TernaryLazy[T any](condition bool, a, b func() T) T

TernaryLazy is like Ternary but only calls the chosen branch function, which avoids evaluating the other branch. Useful for Node construction.

func UnloadAssets

func UnloadAssets()

UnloadAssets frees all GPU resources (shaders, textures, fonts) that were loaded by LoadAssets. It is called automatically by CloseWindow.

func UnloadImage

func UnloadImage(filePath string, fileSystem fs.FS)

UnloadImage removes an image from the cache. filePath and fileSystem must match the values passed to LoadImage.

func UnloadImageTexture

func UnloadImageTexture(filePath string, fileSystem fs.FS)

UnloadImageTexture removes an image from the cache and unloads its GPU texture. filePath and fileSystem must match the values passed to LoadImageTexture.

func Update

func Update()

Update runs the per-frame input processing pass.

It snapshots pressed/released mouse buttons, updates the screen size, bubbles the clicked sub-window to the top of the z-order, runs the top sub-window's own Update (for dragging floating windows), calls Update on every node in every sub-window, applies the cursor, and finally executes all functions queued with AddPostUpdate.

Must be called after ComputeLayout and before Render.

func UpdateScreenSize

func UpdateScreenSize()

UpdateScreenSize refreshes the cached screen size when the window has been resized. This is called automatically by Update; you only need to call it manually if you resize the window outside the normal update loop.

func Vec2

func Vec2(x, y float32) rl.Vector2

Vec2 is a short alias for rl.NewVector2.

func WrapText

func WrapText(bounds rl.Rectangle, font rl.Font, text string, fontSize float32, charSpacing float32) string

WrapText re-flows text so that no line exceeds the width of bounds. Words are separated at space and tab characters; newlines in the source are preserved. The returned string uses "\n" as the line separator.

Types

type Alignment

type Alignment uint8

Alignment controls how children or text are positioned along one axis inside a container.

const (
	AlignStart Alignment = iota
	AlignEnd
	AlignCenter
)

type Box

type Box struct {

	// Texture is an optional GPU texture drawn as this box's background.
	Texture rl.Texture2D

	// CornerRadius holds the per-corner radius values for this box.
	CornerRadius BoxCorners

	// BorderWidth holds the per-side border thickness for this box.
	BorderWidth BoxSides

	// TextureTint is the color multiplied against the Texture. Defaults to
	// white.
	TextureTint rl.Color

	// BgColor is the solid background color of this box.
	BgColor rl.Color

	// BorderColor is the border stroke color.
	BorderColor rl.Color

	// Gradient is the background gradient of this box.
	Gradient Gradient

	// Invisible hides the box visually (no background drawn, no children
	// rendered) while keeping it in the layout.
	Invisible bool

	// HideOverflow clips any child content that extends beyond the box's inner
	// (post-padding) rectangle using a scissor rect.
	HideOverflow bool
	// contains filtered or unexported fields
}

Box is the fundamental building block of the UI and the base for any node. It is a rectangular container that can hold children, display a background color, gradient, or texture, and draw a bordered rounded rectangle.

func NewBox

func NewBox(props BoxProps) *Box

NewBox allocates a Box and applies props.

func NewBoxImage

func NewBoxImage(props BoxProps, imagePath string, fileSystem fs.FS) *Box

NewBoxImage creates a *Box whose background is an image loaded from imagePath inside fileSystem. The image is loaded via LoadImageTexture and cached. Ensure imagePath and fileSystem are valid to avoid panicking.

func (*Box) AbsPos

func (n *Box) AbsPos() rl.Vector2

AbsPos returns the absolute screen-space position of the box's top-left corner.

func (*Box) ApplyProps

func (n *Box) ApplyProps(props BoxProps)

ApplyProps updates the box in place with the values from props.

func (*Box) ComputeMinInnerSizeX

func (n *Box) ComputeMinInnerSizeX() float32

ComputeMinInnerSizeX implements [Node.ComputeMinInnerSizeX]. ComputeMinInnerSizeX returns 0 for a plain box (no intrinsic width).

func (*Box) ComputeMinInnerSizeY

func (n *Box) ComputeMinInnerSizeY() float32

ComputeMinInnerSizeY implements [Node.ComputeMinInnerSizeY]. ComputeMinInnerSizeY returns 0 for a plain box (no intrinsic height).

func (*Box) GetChild

func (n *Box) GetChild(idx int) Node

GetChild returns the child at index idx. Negative indices count from the end (e.g. -1 returns the last child). Panics if idx is out of range.

func (*Box) GetComputedChildCount

func (n *Box) GetComputedChildCount() int

GetComputedChildCount returns the number of children that participate in layout (i.e. total children minus those with Ignored set).

func (*Box) ID

func (n *Box) ID() NodeID

ID returns the NodeID assigned to this box.

func (*Box) InnerRect

func (n *Box) InnerRect() rl.Rectangle

InnerRect returns the rectangle of the content area, i.e. the bounding rectangle shrunk by the box's padding on all sides.

func (*Box) Rect

func (n *Box) Rect() rl.Rectangle

Rect returns the box's bounding rectangle in screen-space coordinates.

func (*Box) Render

func (n *Box) Render()

Render implements [Node.Render]. Render draws the box background (solid color, gradient, or texture), then recursively renders all children. If HideOverflow is set, children are clipped to the Box.InnerRect.

func (*Box) TotalArea

func (n *Box) TotalArea() rl.Rectangle

TotalArea implements [Node.TotalArea].

func (*Box) Update

func (n *Box) Update()

Update implements [Node.Update]. Update is a no-op for plain boxes.

type BoxCorners

type BoxCorners struct {
	TopLeft, TopRight, BottomRight, BottomLeft float32
}

BoxCorners holds per-corner radius values for a box.

func NewBoxCorners

func NewBoxCorners(v ...float32) BoxCorners

NewBoxCorners creates a BoxCorners value following CSS shorthand conventions:

TL = Top Left, TR = Top Right, BR = Bottom Right, BL = Bottom Left

NewBoxCorners(a)          → TL/TR/BR/BL = a
NewBoxCorners(a, b)       → TL/BR = a, TR/BL = b
NewBoxCorners(a, b, c)    → TL = a, TR/BL = b, BR = c
NewBoxCorners(a, b, c, d) → TL = a, TR = b, BR = c, BL = d

All values must be non-negative.

func NewBoxCornersOverride

func NewBoxCornersOverride(boxCorners BoxCorners, topLeft, topRight, bottomRight, bottomLeft float32) BoxCorners

NewBoxCornersOverride returns a copy of boxCorners with individual corners replaced. A negative value leaves that corner unchanged.

func Radius

func Radius(v ...float32) BoxCorners

Radius is a short alias for NewBoxCorners.

func RadiusOverride

func RadiusOverride(radius BoxCorners, topLeft, topRight, bottomRight, bottomLeft float32) BoxCorners

RadiusOverride is a short alias for NewBoxCornersOverride.

type BoxProps

type BoxProps struct {
	// DebugID is an optional human-readable label printed by the debug overlay.
	DebugID string

	// ID is the stable cache key for stateful widgets. Generate one with
	// [SubWindow.GetAutoID] or [NewID]. Leave zero for stateless boxes.
	// Set it to [NodeIDManual] to handle the node lifecycle manually.
	ID NodeID

	// AllocChildren pre-allocates the children slice to avoid reallocations
	// when the number of children is known in advance.
	AllocChildren uint

	// SizingX controls horizontal sizing. Defaults to [SizingShrink].
	SizingX SizingProp

	// SizingY controls vertical sizing. Defaults to [SizingShrink].
	SizingY SizingProp

	// Padding is the space between the box border and its children.
	Padding BoxSides

	// ChildGap is the pixel gap inserted between consecutive children.
	ChildGap float32

	// CornerRadius rounds the corners of the box.
	CornerRadius BoxCorners

	// BorderWidth is the per-side border thickness.
	BorderWidth BoxSides

	// Texture is an optional GPU texture drawn as the box background.
	Texture rl.Texture2D

	// Gradient is an optional gradient drawn as the box background.
	Gradient Gradient

	// BgColor is the solid fill color.
	BgColor rl.Color

	// BorderColor is the color of the border stroke.
	BorderColor rl.Color

	// TextureTint is multiplied against the texture color. Defaults to white.
	TextureTint rl.Color

	// TextureFit controls how the texture is scaled within the box.
	TextureFit TextureFit

	// Orientation controls whether children are laid out horizontally or
	// vertically.
	Orientation Orientation

	// ChildAlignX controls horizontal alignment of children inside the box.
	ChildAlignX Alignment

	// ChildAlignY controls vertical alignment of children inside the box.
	ChildAlignY Alignment

	// ChildWrap enables multi-line (wrapping) layout for horizontal boxes.
	// Children that do not fit on the current row are moved to the next row.
	ChildWrap bool

	// Invisible hides the box visually (no background drawn, no children
	// rendered) while keeping it in the layout.
	Invisible bool

	// Ignored removes the box from both layout and rendering as if it did not
	// exist.
	Ignored bool

	// HideOverflow clips any child content that extends beyond the box's inner
	// (post-padding) rectangle using a scissor rect.
	HideOverflow bool
}

BoxProps is the configuration struct for NewBox and for the BoxProps field embedded in the Props structs of derived node types.

type BoxSides

type BoxSides struct {
	Top, Right, Bottom, Left float32
}

BoxSides holds four float32 values representing the four sides of a box — typically used for padding, or border widths.

func Border

func Border(v ...float32) BoxSides

Border is a short alias for NewBoxSides.

func BorderOverride

func BorderOverride(borders BoxSides, top, right, bottom, left float32) BoxSides

BorderOverride is a short alias for NewBoxSidesOverride.

func NewBoxSides

func NewBoxSides(v ...float32) BoxSides

NewBoxSides creates a BoxSides value following CSS shorthand conventions:

NewBoxSides(a)          → top/right/bottom/left = a
NewBoxSides(a, b)       → top/bottom = a, left/right = b
NewBoxSides(a, b, c)    → top = a, left/right = b, bottom = c
NewBoxSides(a, b, c, d) → top = a, right = b, bottom = c, left = d

All values must be non-negative.

func NewBoxSidesOverride

func NewBoxSidesOverride(boxSides BoxSides, top, right, bottom, left float32) BoxSides

NewBoxSidesOverride returns a copy of boxSides with individual sides replaced. A negative value leaves that side unchanged.

func Padding

func Padding(v ...float32) BoxSides

Padding is a short alias for NewBoxSides.

func PaddingOverride

func PaddingOverride(padding BoxSides, top, right, bottom, left float32) BoxSides

PaddingOverride is a short alias for NewBoxSidesOverride.

func (BoxSides) X

func (b BoxSides) X() float32

X returns the sum of Left and Right.

func (BoxSides) Y

func (b BoxSides) Y() float32

Y returns the sum of Top and Bottom.

type Button

type Button struct {
	Box
	// contains filtered or unexported fields
}

Button is a clickable container node. It reports press and release events for both mouse buttons and applies optional visual effects on hover and press. Children are added with AddChild to build the button's visual content (icons, labels, etc.).

func NewButton

func NewButton(props ButtonProps) *Button

NewButton allocates a Button node and applies props.

func (*Button) ApplyProps

func (n *Button) ApplyProps(props ButtonProps)

ApplyProps updates the button's configuration.

func (*Button) IsLeftButtonDown

func (n *Button) IsLeftButtonDown() bool

IsLeftButtonDown reports whether the left mouse button is currently held down while the cursor is over this button.

func (*Button) IsLeftButtonPressed

func (n *Button) IsLeftButtonPressed() bool

IsLeftButtonPressed reports whether the left mouse button was pressed over this button this frame.

func (*Button) IsLeftButtonReleased

func (n *Button) IsLeftButtonReleased() bool

IsLeftButtonReleased reports whether the left mouse button was released over this button this frame.

func (*Button) IsLeftButtonUp

func (n *Button) IsLeftButtonUp() bool

IsLeftButtonUp reports whether the left mouse button is currently up while the cursor is over this button.

func (*Button) IsRightButtonDown

func (n *Button) IsRightButtonDown() bool

IsRightButtonDown reports whether the right mouse button is currently held down while the cursor is over this button.

func (*Button) IsRightButtonPressed

func (n *Button) IsRightButtonPressed() bool

IsRightButtonPressed reports whether the right mouse button was pressed over this button this frame.

func (*Button) IsRightButtonReleased

func (n *Button) IsRightButtonReleased() bool

IsRightButtonReleased reports whether the right mouse button was released over this button this frame.

func (*Button) IsRightButtonUp

func (n *Button) IsRightButtonUp() bool

IsRightButtonUp reports whether the right mouse button is currently up while the cursor is over this button.

func (*Button) Render

func (n *Button) Render()

Render implements [Node.Render]. Render applies OnPress or OnHover effects when appropriate, draws the button background and children, and then calls the cleanup function returned by the effect (if any).

func (*Button) Update

func (n *Button) Update()

Update implements [Node.Update]. Update records which mouse buttons were pressed or released over the button this frame and sets the mouse cursor to a pointer hand when hovered.

type ButtonProps

type ButtonProps struct {
	BoxProps

	// OnHover is called each frame the button is hovered. Its return value
	// is called after the button is rendered.
	OnHover EffectFunc

	// OnPress is called each frame the left mouse button is held down over the
	// button. Its return value is called after rendering.
	OnPress EffectFunc
}

ButtonProps is the configuration struct for *Button.

type ChildlessNode

type ChildlessNode struct{}

ChildlessNode is a mix-in for node types that must not have children. Embed it in custom node structs to get a panicking AddChild method.

func (*ChildlessNode) AddChild

func (n *ChildlessNode) AddChild(thisPanics Node)

AddChild panics unconditionally. Embedding ChildlessNode in a node type prevents child nodes from being attached to it.

type Color

type Color = rl.Color

Color is an alias for rl.Color.

type Dropdown struct {
	Box
	ChildlessNode
	FontConfig

	OptionsCornerRadius BoxCorners
	// contains filtered or unexported fields
}

Dropdown is a single-select control that shows a list of string options. When closed it displays the selected option (or a placeholder); when open it expands downward to show all options. Clicking outside or selecting an option closes the list.

Dropdown requires an ID. State is persisted in the node cache.

func NewDropdown

func NewDropdown(props DropdownProps, placeholder string, options []string, selected int16) *Dropdown

NewDropdown creates (or retrieves from cache) a Dropdown node. placeholder is shown when no option is selected. options is the list of selectable strings; they cannot contain '\n'. selected is the zero-based index of the initially selected option, or -1 for no selection. Requires a non-zero ID in props.

func (n *Dropdown) ApplyProps(props DropdownProps)

ApplyProps updates the dropdown configuration.

func (n *Dropdown) Close()

Close collapses the dropdown list and removes this node from the high-priority list.

func (n *Dropdown) ComputeMinInnerSizeX() float32

ComputeMinInnerSizeX implements [Node.ComputeMinInnerSizeX]. ComputeMinInnerSizeX returns the minimum width that can accommodate the widest option label plus the icons and gaps.

func (n *Dropdown) ComputeMinInnerSizeY() float32

ComputeMinInnerSizeY implements [Node.ComputeMinInnerSizeY]. ComputeMinInnerSizeY returns the minimum height needed to render one row (the taller of the text height and the icon height).

func (n *Dropdown) GetNumberOfOptions() int

GetNumberOfOptions returns the total number of options in the dropdown.

func (n *Dropdown) GetSelected() string

GetSelected returns the string value of the currently selected option, or "" if no option is selected.

func (n *Dropdown) GetSelectedIdx() int

GetSelectedIdx returns the zero-based index of the currently selected option, or -1 if no option is selected.

func (n *Dropdown) HasChanged() bool

HasChanged reports whether the selected option changed during the last Update call.

func (n *Dropdown) HasSelection() bool

HasSelection reports whether an option is currently selected (i.e. [GetSelectedIdx] != -1).

func (n *Dropdown) IsOpen() bool

IsOpen reports whether the dropdown list is currently expanded.

func (n *Dropdown) Open()

Open expands the dropdown list and adds this node to the high-priority list so that hover detection works through the expanded area.

func (n *Dropdown) Render()

Render implements [Node.Render]. Render draws the collapsed dropdown header (or the full expanded list when open). When open, rendering is deferred to the post-render pass via AddPostRender so the list appears on top of all other content.

func (n *Dropdown) TotalArea() rl.Rectangle

TotalArea implements [Node.TotalArea]. TotalArea returns the full expanded rectangle when the dropdown is open, ensuring hover detection works over the list.

func (n *Dropdown) Update()

Update implements [Node.Update]. Update handles opening/closing the dropdown and selecting an option. Clicking anywhere outside the dropdown while it is open closes it.

type DropdownProps struct {
	BoxProps
	FontConfigProps

	// OptionsCornerRadius rounds the corners of the options box.
	OptionsCornerRadius BoxCorners

	// ExpandIcon is the texture shown when the list is collapsed. Defaults to
	// [DefaultDropdownExpandIcon].
	ExpandIcon rl.Texture2D

	// CollapseIcon is the texture shown when the list is expanded. Defaults
	// to [DefaultDropdownCollapseIcon].
	CollapseIcon rl.Texture2D

	// IconSize is the width and height of the expand/collapse icon in pixels.
	// Defaults to [FontConfigProps.FontSize] * [DefaultDropdownIconSizeFactor].
	IconSize float32

	// IconGap is the horizontal gap between the icon and the label text.
	// Defaults to [BoxProps.Padding].Right or [DefaultDropdownIconGap].
	IconGap float32
}

DropdownProps is the configuration struct for *Dropdown.

type EffectFunc

type EffectFunc func(box *Box) func()

EffectFunc is a callback type used by *Button for hover and press effects. It receives a pointer to the button's *Box so that properties such as BgColor or Gradient can be modified temporarily for the frame. The returned function, if non-nil, is called after the box has been rendered to restore any properties that were mutated.

type FontConfig

type FontConfig struct {
	FgColor rl.Color
	// contains filtered or unexported fields
}

FontConfig holds the resolved font configuration for a node after defaults have been applied. It is embedded in node types that render text.

func (*FontConfig) ApplyProps

func (c *FontConfig) ApplyProps(props FontConfigProps)

ApplyProps resolves the FontConfigProps into the FontConfig, substituting library-level defaults for any zero values.

type FontConfigProps

type FontConfigProps struct {
	// FgColor is the text color; defaults to [DefaultTextColor].
	FgColor rl.Color

	// Font is the font to use; defaults to [GetDefaultFont].
	Font rl.Font

	// FontSize is the text size in pixels; defaults to [DefaultFontSize].
	FontSize float32

	// CharSpacing is the extra pixel gap between glyphs; defaults to
	// [DefaultCharSpacing].
	CharSpacing float32

	// BaselineCorrectionFactor nudges the text upward by this fraction of the
	// font size; defaults to [DefaultFontBaselineCorrectionFactor].
	BaselineCorrectionFactor float32
}

FontConfigProps is the configuration for font rendering inside a node. Embed in node Props structs that display text.

type Gradient

type Gradient struct {
	// StartColor is the first color of the gradient
	// (the "from" color for linear, or the centre color for radial).
	StartColor rl.Color

	// EndColor is the second color of the gradient
	// (the "to" color for linear, or the edge color for radial).
	EndColor rl.Color

	// Angle stores the direction in radians for a linear gradient.
	// A sentinel value of [InfPositive] marks a radial gradient.
	Angle float32
}

Gradient describes a color gradient used as a *Box background.

func GradientLinear

func GradientLinear(startColor, endColor rl.Color, angleDegrees float32) Gradient

GradientLinear is a short alias for NewGradientLinear.

func GradientRadial deprecated

func GradientRadial(centerColor, edgeColor rl.Color) Gradient

GradientRadial is a short alias for NewGradientRadial.

Deprecated: Unimplemented.

func NewGradientLinear

func NewGradientLinear(startColor, endColor rl.Color, angleDegrees float32) Gradient

NewGradientLinear creates a linear Gradient from startColor to endColor rotated by angleDegrees (0 = left-to-right).

func NewGradientRadial deprecated

func NewGradientRadial(centerColor, edgeColor rl.Color) Gradient

NewGradientRadial creates a radial Gradient from centerColor at the center to edgeColor at the edges.

Deprecated: Unimplemented

func (Gradient) IsVisible

func (g Gradient) IsVisible() bool

IsVisible reports whether the gradient will produce any visible pixels (i.e. at least one color has a non-zero alpha channel).

func (Gradient) Kind

func (g Gradient) Kind() GradientKind

Kind returns the GradientKind of the gradient, determined by its internal Angle value.

type GradientKind

type GradientKind uint8

GradientKind distinguishes between the supported gradient styles.

const (
	GradientKindLinear GradientKind = iota
	GradientKindRadial              // Deprecated: Unimplemented
)

type Node

type Node interface {

	// ID returns the node's [NodeID].
	ID() NodeID

	// TotalArea returns the rectangle that should be used for hit-testing.
	// For most nodes this is the same as Rect(); nodes that expand visually
	// (e.g. an open [*Dropdown]) override this to report the larger area.
	TotalArea() rl.Rectangle

	// ComputeMinInnerSizeX returns the minimum width required for the node's
	// own content, not counting padding. Called during the X layout pass.
	ComputeMinInnerSizeX() float32

	// ComputeMinInnerSizeY returns the minimum height required for the node's
	// own content, not counting padding. Called during the Y layout pass.
	ComputeMinInnerSizeY() float32

	// Update is called once per frame for every node, after ComputeLayout,
	// to process input events.
	Update()

	// Render draws the node and its children. Implementations should guard
	// with [IsNodeVisible] and call [DebuggingInfo] at the end.
	Render()
	// contains filtered or unexported methods
}

Node is the interface implemented by every element in the UI tree. The library provides concrete implementations (e.g. *Box, *Button, etc.). You can also implement Node yourself to create custom widgets; embed *Box (or any other node that embeds it) and override the methods you need.

ComputeMinInnerSizeX / ComputeMinInnerSizeY return the minimum content size that should be reserved inside the padding area; override them in custom nodes that have intrinsic size (e.g. text, images).

func GetHighestPriorityNodeUnderMouse

func GetHighestPriorityNodeUnderMouse() Node

GetHighestPriorityNodeUnderMouse returns the highest-priority node in the high-priority list whose total area contains the mouse cursor, or nil if no such node exists.

type NodeID

type NodeID uint64

NodeID is an opaque 64-bit identifier for a node. It is used as a cache key for stateful widgets. Generate stable IDs with NewID or obtain auto-incremented IDs from SubWindow.GetAutoID.

const (
	// NodeIDUnset is the zero value for [NodeID]. A node with this ID has no
	// assigned identity and will be skipped by the cache.
	NodeIDUnset NodeID = iota

	// NodeIDManual is a reserved sentinel for nodes whose lifecycle is
	// managed entirely by the caller (e.g. the node will not be cached).
	NodeIDManual
)

func NewID

func NewID(id string) NodeID

NewID derives a deterministic NodeID from a string by computing a CRC-64 hash. Panics if the same string is used twice in the same frame (duplicate IDs). Use this for nodes whose position in the tree may change.

type NodeIDGenerator

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

NodeIDGenerator issues NodeID values from a fixed sequence that is reproduced identically on every frame rebuild by restarting the cursor. Each *SubWindow owns one and issues IDs through SubWindow.GetAutoID. The zero value for NodeIDGenerator is an empty generator ready to use.

func (*NodeIDGenerator) GetID

func (g *NodeIDGenerator) GetID() NodeID

GetID returns the next ID in the sequence, if any, otherwise a new random ID is generated and appended.

func (*NodeIDGenerator) Reset

func (g *NodeIDGenerator) Reset()

Reset rewinds the cursor and evicts all IDs in the sequence from the node cache, effectively discarding all stateful widget state issued by this generator.

func (*NodeIDGenerator) Restart

func (g *NodeIDGenerator) Restart()

Restart rewinds the cursor to the beginning of the sequence without removing any IDs or touching the cache.

type Number

type Number interface {
	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~float32 | ~float64
}

Number is a type constraint that matches all integer and floating-point kinds. It is used by generic utility functions such as Clamp and Abs.

type Orientation

type Orientation uint8

Orientation controls whether a *Box's children are laid out in a row (horizontal) or a column (vertical).

const (
	OrientationHorizontal Orientation = iota
	OrientationVertical
)

type ScrollBox

type ScrollBox struct {
	Box

	// ThumbColor is the fill color of the scroll thumb.
	ThumbColor rl.Color

	// ThumbCornerRadius is the per-corner radius of the scroll thumb.
	ThumbCornerRadius BoxCorners
	// contains filtered or unexported fields
}

ScrollBox is a container that clips its children to its visible area and allows scrolling via the mouse wheel or by dragging the scroll thumb.

ScrollBox requires an ID. State is persisted in the node cache.

func NewScrollBox

func NewScrollBox(props ScrollBoxProps) *ScrollBox

NewScrollBox creates (or retrieves from cache) a *ScrollBox node. Requires a non-zero ID in props.

func (*ScrollBox) ApplyProps

func (n *ScrollBox) ApplyProps(props ScrollBoxProps)

ApplyProps updates the ScrollBox configuration.

func (*ScrollBox) Render

func (n *ScrollBox) Render()

Render implements [Node.Render]. Render draws the scroll box content within a scissor clip and then overlays the scroll-bar thumb (unless HideScrollBar is set or the content fits).

func (*ScrollBox) Update

func (n *ScrollBox) Update()

Update implements [Node.Update]. Update handles mouse wheel scrolling and scroll-thumb dragging. When content fits in the visible area, scrollDistance is reset to 0.

type ScrollBoxProps

type ScrollBoxProps struct {
	BoxProps

	// ThumbWidth is the width (or height for a horizontal scroll bar) of the
	// scroll thumb in pixels. Defaults to [DefaultScrollBoxThumbWidth].
	ThumbWidth float32

	// ThumbColor is the fill color of the scroll thumb. Defaults to a
	// contrast color derived from BgColor.
	ThumbColor rl.Color

	// ThumbCornerRadius is the uniform corner radius of the scroll thumb.
	ThumbCornerRadius float32

	// HideScrollBar hides the scroll-bar thumb while still allowing scrolling.
	HideScrollBar bool

	// ScrollOrientation controls the scroll direction.
	ScrollOrientation Orientation
}

ScrollBoxProps is the configuration struct for *ScrollBox.

type Sizing

type Sizing struct {
	rl.Vector2
	// contains filtered or unexported fields
}

Sizing holds all size-related state for a single *Box. The embedded rl.Vector2 carries the resolved pixel dimensions (X, Y) after layout. The remaining fields are set from a SizingProp and consumed by the layout engine.

type SizingMode

type SizingMode uint8

SizingMode describes how a *Box's size on one axis is determined during layout.

const (
	// SizingUnset means no sizing mode has been assigned, and represents an
	// invalid state.
	SizingUnset SizingMode = iota

	// SizingShrink makes the box as small as its content requires.
	SizingShrink

	// SizingGrow distributes free space among all growing siblings along the
	// parent's orientation axis.
	SizingGrow

	// SizingFixed sets the box to an exact pixel size regardless of content or
	// available space.
	SizingFixed

	// SizingPercentage sets the box size to a percentage of the parent's size
	// on the same axis.
	SizingPercentage

	// SizingAspectRatio (Y axis only) derives the height from the already-
	// computed width by dividing by a given ratio.
	SizingAspectRatio
)

type SizingProp

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

SizingProp encodes a sizing specification for one axis of a *Box.

func AspectRatio

func AspectRatio(ratio float32) SizingProp

AspectRatio is a short alias for NewSizingAspectRatio.

func Fixed

func Fixed(size float32) SizingProp

Fixed is a short alias for NewSizingFixed.

func Grow

func Grow(v ...float32) SizingProp

Grow is a short alias for NewSizingGrow.

func NewSizingAspectRatio

func NewSizingAspectRatio(ratio float32) SizingProp

NewSizingAspectRatio returns a SizingProp for the Y axis that derives the height from the already-computed width divided by ratio. Use this on the Y axis only; setting it on the X axis panics.

func NewSizingFixed

func NewSizingFixed(size float32) SizingProp

NewSizingFixed returns a SizingProp that locks the box to exactly size pixels. Min and max are both set to size so layout cannot change it.

func NewSizingGrow

func NewSizingGrow(v ...float32) SizingProp

NewSizingGrow returns a SizingProp that expands the box to fill available space along the parent's main axis. Optional min/max pixel constraints are accepted in the same way as NewSizingShrink.

func NewSizingPercentage

func NewSizingPercentage(percentage uint8, v ...float32) SizingProp

NewSizingPercentage returns a SizingProp that sizes the box to a percentage of the parent's size on the same axis. percentage must be in [0, 100]. Optional min/max pixel constraints are accepted in the same way as NewSizingShrink.

func NewSizingShrink

func NewSizingShrink(v ...float32) SizingProp

NewSizingShrink returns a SizingProp that sizes the box to its minimum content size. An optional first argument sets the minimum pixel size; an optional second argument sets the maximum pixel size (default: unbounded).

func Percentage

func Percentage(percentage uint8, v ...float32) SizingProp

Percentage is a short alias for NewSizingPercentage.

func Shrink

func Shrink(v ...float32) SizingProp

Shrink is a short alias for NewSizingShrink.

type Slider

type Slider struct {
	Box
	ChildlessNode

	// ThumbCornerRadius is the per-corner radius of the slider thumb.
	ThumbCornerRadius BoxCorners

	// ThumbColor is the fill color of the slider thumb.
	ThumbColor rl.Color

	// TrackCornerRadius is the per-corner radius of the active/inactive track
	// segments.
	TrackCornerRadius BoxCorners

	// TrackActiveColor is the color of the active (filled) portion of the
	// track.
	TrackActiveColor rl.Color

	// TrackInactiveColor is the color of the inactive (empty) portion of the
	// track.
	TrackInactiveColor rl.Color
	// contains filtered or unexported fields
}

Slider is a numeric range input that lets the user drag a thumb along a track to pick a value between min and max.

Slider requires an ID. State is persisted in the node cache.

func NewSlider

func NewSlider(props SliderProps, min, max, value float32) *Slider

NewSlider creates (or retrieves from cache) a Slider node. min and max define the value range; value is the initial position. Requires a non-zero ID in props.

func (*Slider) ApplyProps

func (n *Slider) ApplyProps(props SliderProps)

ApplyProps updates the Slider properties.

func (*Slider) ComputeMinInnerSizeX

func (n *Slider) ComputeMinInnerSizeX() float32

ComputeMinInnerSizeX implements [Node.ComputeMinInnerSizeX]. ComputeMinInnerSizeX returns the minimum horizontal size required. For a vertical slider this is the larger of thumb and track widths; for a horizontal slider it is 0.

func (*Slider) ComputeMinInnerSizeY

func (n *Slider) ComputeMinInnerSizeY() float32

ComputeMinInnerSizeY implements [Node.ComputeMinInnerSizeY]. ComputeMinInnerSizeY returns the minimum vertical size required. For a horizontal slider this is the larger of thumb and track widths; for a vertical slider it is 0.

func (*Slider) GetProgress

func (n *Slider) GetProgress() float32

GetProgress returns the current position of the thumb as a normalised value in [0, 1].

func (*Slider) GetValue

func (n *Slider) GetValue() float32

GetValue returns the current slider value in the [min, max] range, snapped to the nearest [SliderProps.Step] if one was specified.

func (*Slider) HasChanged

func (n *Slider) HasChanged() bool

HasChanged reports whether the drag ended this frame (mouse button released). Use this to trigger actions that should only fire once per interaction, not on every drag frame.

func (*Slider) IsChanging

func (n *Slider) IsChanging() bool

IsChanging reports whether the user is currently dragging the thumb. Use this to apply real-time updates (e.g. live preview) while the drag is in progress.

func (*Slider) Render

func (n *Slider) Render()

Render implements [Node.Render]. Render draws the active track segment, the inactive track segment, and the thumb.

func (*Slider) SetProgress

func (n *Slider) SetProgress(progress float32)

SetProgress moves the thumb to a normalised position. progress must be in [0, 1].

func (*Slider) SetValue

func (n *Slider) SetValue(value float32)

SetValue moves the thumb to position the slider at value. value is clamped to [min, max].

func (*Slider) Update

func (n *Slider) Update()

Update implements [Node.Update]. Update processes mouse input to drag the thumb. While dragging, the cursor is changed to a pointing hand.

type SliderProps

type SliderProps struct {
	BoxProps

	// ThumbWidth is the pixel size of the circular thumb (diameter).
	// Defaults to [DefaultSliderThumbWidth].
	ThumbWidth float32

	// ThumbCornerRadius is the corner radius of the thumb rectangle.
	ThumbCornerRadius BoxCorners

	// ThumbColor is the fill color of the thumb. Defaults to rl.RayWhite.
	ThumbColor rl.Color

	// TrackWidth is the pixel thickness of the slider track. Defaults to
	// [DefaultSliderTrackWidth].
	TrackWidth float32

	// TrackCornerRadius is the corner radius of the track rectangles.
	TrackCornerRadius BoxCorners

	// TrackActiveColor is the color of the portion of the track between the
	// start and the thumb. Defaults to rl.LightGray.
	TrackActiveColor rl.Color

	// TrackInactiveColor is the color of the track portion after the thumb.
	// Defaults to rl.DarkGray.
	TrackInactiveColor rl.Color

	// Step is the quantisation step size. When non-zero the value snaps to
	// multiples of Step. A zero Step means continuous.
	Step float32

	// Orientation is the direction of the slider.
	Orientation Orientation
}

SliderProps is the configuration struct for *Slider.

type Spacer

type Spacer struct {
	Box
}

Spacer is an invisible box used to consume free space along the parent's main axis.

func NewSpacerX

func NewSpacerX(sizing ...SizingProp) *Spacer

NewSpacerX creates a horizontal spacer. An optional SizingProp controls how much space it occupies; defaults to NewSizingGrow.

func NewSpacerY

func NewSpacerY(sizing ...SizingProp) *Spacer

NewSpacerY creates a vertical spacer. An optional SizingProp controls how much space it occupies; defaults to NewSizingGrow.

func (*Spacer) Render

func (n *Spacer) Render()

Render implements [Node.Render]. Render is a no-op; spacers are invisible.

type SubWindow

type SubWindow struct {
	// For internal debugging
	DebugID string

	// HeaderColor is the background color of the draggable title bar rendered
	// above floating sub-windows.
	HeaderColor rl.Color
	// contains filtered or unexported fields
}

SubWindow is a self-contained layer that owns a root *Box and a NodeIDGenerator. The entire GUI is composed of one or more sub-windows stacked in z-index order. The primary full-screen window typically uses ZIndexRoot; transient overlays (dropdowns, tooltips, floating panels) get higher z-indices.

func AddSubWindow

func AddSubWindow(subWindow *SubWindow, position rl.Vector2) *SubWindow

AddSubWindow registers subWindow with the global sub-window list and places its root at position. For floating windows position is the content area origin (the header is drawn above it); the header offset is applied automatically.

Sub-windows are kept sorted by ZIndex; same-index windows are ordered by insertion time. The function returns subWindow for convenience.

func NewSubWindow

func NewSubWindow(props SubWindowProps) *SubWindow

NewSubWindow allocates and initialises a SubWindow from props. After creation, register it with AddSubWindow.

func (*SubWindow) ComputeLayout

func (w *SubWindow) ComputeLayout()

ComputeLayout computes the layout for this sub-window. Sub-windows that are hidden are skipped.

func (*SubWindow) Drag

func (w *SubWindow) Drag(delta rl.Vector2)

Drag is identical to [Translate] but clamps the resulting position so the window stays within the screen bounds (including the header). Only valid for floating sub-windows; panics otherwise.

func (*SubWindow) GetAutoID

func (w *SubWindow) GetAutoID() NodeID

GetAutoID issues the next auto-incremented NodeID from this sub-window's generator. Use this in the BoxProps.ID field of stateful widgets (Slider, Toggle, TextInput, ScrollBox, Dropdown) that do not have a stable position in the tree. The sequence must be called in exactly the same order every frame so that IDs remain stable.

func (*SubWindow) HeaderBounds

func (w *SubWindow) HeaderBounds() rl.Rectangle

HeaderBounds returns the rectangle of the draggable header bar for floating sub-windows. Returns an empty rectangle for non-floating windows.

func (*SubWindow) Hide

func (w *SubWindow) Hide()

Hide marks the sub-window as hidden.

func (*SubWindow) IsHidden

func (w *SubWindow) IsHidden() bool

IsHidden reports whether the sub-window is currently hidden.

func (*SubWindow) Move

func (w *SubWindow) Move(position rl.Vector2)

Move sets the absolute position of the sub-window's content area to position.

func (*SubWindow) Rect

func (w *SubWindow) Rect() rl.Rectangle

Rect returns the bounding rectangle of the sub-window, including the header bar if it is a floating window.

func (*SubWindow) Render

func (w *SubWindow) Render()

Render draws the sub-window's root node tree and, for floating windows, the draggable header bar (including the × close button if Closable is set). Hidden sub-windows are skipped; the first frame after Show/Hide is also skipped to prevent one-frame flicker.

func (*SubWindow) ResetIDs

func (w *SubWindow) ResetIDs()

ResetIDs clears all auto-generated IDs in this sub-window's generator and removes the associated nodes from the global cache.

func (*SubWindow) ResetLayout

func (w *SubWindow) ResetLayout()

ResetLayout clears the root node's children list. Called automatically by ResetLayout each frame.

func (*SubWindow) RestartIDs

func (w *SubWindow) RestartIDs()

RestartIDs rewinds the auto-ID cursor to zero without touching the cache. Called automatically by ResetLayout each frame.

func (*SubWindow) Root

func (w *SubWindow) Root() *Box

Root returns the current root *Box of the sub-window.

func (*SubWindow) SetHidden

func (w *SubWindow) SetHidden(hidden bool)

SetHidden shows or hides the sub-window. Equivalent to calling [Show] or [Hide].

func (*SubWindow) SetRoot

func (w *SubWindow) SetRoot(root *Box) *Box

SetRoot replaces the sub-window's root box with root, transferring the current position and sub-window reference. Returns root for convenience.

func (*SubWindow) SetSizingX

func (w *SubWindow) SetSizingX(sizing SizingProp)

SetSizingX updates the horizontal sizing mode of the sub-window's root box.

func (*SubWindow) SetSizingY

func (w *SubWindow) SetSizingY(sizing SizingProp)

SetSizingY updates the vertical sizing mode of the sub-window's root box.

func (*SubWindow) Show

func (w *SubWindow) Show()

Show marks the sub-window as visible and brings it to the top of its z-index tier.

func (*SubWindow) Translate

func (w *SubWindow) Translate(delta rl.Vector2)

Translate shifts the sub-window by delta pixels.

func (*SubWindow) Update

func (w *SubWindow) Update()

Update handles dragging and the close-button interaction for floating sub-windows. Hidden sub-windows are skipped. Called automatically by Update.

type SubWindowProps

type SubWindowProps struct {
	// For internal debugging
	DebugID string

	// SizingX controls how the sub-window's root box sizes itself horizontally.
	// Defaults to [SizingShrink] when zero.
	SizingX SizingProp

	// SizingY controls how the sub-window's root box sizes itself vertically.
	// Defaults to [SizingShrink] when zero.
	SizingY SizingProp

	// ZIndex determines the rendering order among all sub-windows. Use the
	// [ZIndexRoot], [ZIndexBase], [ZIndexPopup], [ZIndexEphemeral] constants
	// as starting points.
	ZIndex ZIndex

	// Floating makes the sub-window draggable with a header bar rendered above
	// it. Floating windows are clamped to the screen bounds while dragging.
	Floating bool

	// Hidden sets the initial visibility of the sub-window.
	Hidden bool

	// Closable adds an × button to the header of floating sub-windows.
	// Clicking it calls [RemoveSubWindow].
	Closable bool

	// HeaderColor is the fill color of the draggable header bar drawn above
	// floating sub-windows.
	HeaderColor rl.Color
}

SubWindowProps holds the configuration options for NewSubWindow.

type Text

type Text struct {
	Box
	FontConfig
	// contains filtered or unexported fields
}

Text is a node that renders a string of text.

func NewText

func NewText(props TextProps, text string) *Text

NewText creates a Text node with the given props and content string.

func (*Text) ApplyProps

func (n *Text) ApplyProps(props TextProps)

ApplyProps updates the Text node's configuration.

func (*Text) ComputeMinInnerSizeX

func (n *Text) ComputeMinInnerSizeX() float32

ComputeMinInnerSizeX implements [Node.ComputeMinInnerSizeX]. ComputeMinInnerSizeX returns the minimum horizontal space required for the text content.

func (*Text) ComputeMinInnerSizeY

func (n *Text) ComputeMinInnerSizeY() float32

ComputeMinInnerSizeY implements [Node.ComputeMinInnerSizeY]. ComputeMinInnerSizeY returns the height of a single line of text (accounting for the baseline correction factor).

func (*Text) Render

func (n *Text) Render()

Render implements [Node.Render]. Render draws the text. Panics if ComputeLayout has not been called since the last *Text.SetText or ResetLayout (i.e. the text has not been wrapped yet).

func (*Text) SetText

func (n *Text) SetText(text string)

SetText updates the displayed string. If text is identical to the current value the call is a no-op; otherwise the node is marked as uncomputed, so ComputeLayout must be called before the next call to Render.

type TextInput

type TextInput struct {
	Box
	ChildlessNode
	FontConfig

	// ErrorMessage is displayed below the field in ErrorColor when non-empty.
	// Setting it to a non-empty string also highlights the field border.
	ErrorMessage string

	// ErrorColor is the color used for the error border and error message.
	ErrorColor rl.Color

	// PlaceholderColor is the color used to draw the placeholder text when
	// the field is empty.
	PlaceholderColor rl.Color
	// contains filtered or unexported fields
}

TextInput is a single-line editable text field. It supports a placeholder string shown when the field is empty, an optional error message displayed below the field, keyboard navigation (arrows, backspace, delete, Ctrl+V), mouse navigation (click to move cursor), and a blinking text cursor.

TextInput requires an ID. State is persisted in the node cache.

func NewTextInput

func NewTextInput(props TextInputProps, placeholder, value string) *TextInput

NewTextInput creates (or retrieves from cache) a TextInput node. placeholder is shown when the field is empty. value is the initial text content. Requires a non-zero ID in props.

func (*TextInput) ApplyProps

func (n *TextInput) ApplyProps(props TextInputProps)

ApplyProps updates the *TextInput configuration.

func (*TextInput) Blur

func (n *TextInput) Blur()

Blur programmatically removes keyboard focus from this *TextInput.

func (*TextInput) ComputeMinInnerSizeY

func (n *TextInput) ComputeMinInnerSizeY() float32

ComputeMinInnerSizeY implements [Node.ComputeMinInnerSizeY]. ComputeMinInnerSizeY returns the height of its text value, used to set a minimum height for the field.

func (*TextInput) Focus

func (n *TextInput) Focus()

Focus programmatically gives keyboard focus to this *TextInput.

func (*TextInput) HasChanged

func (n *TextInput) HasChanged() bool

HasChanged reports whether the text content changed during the last Update call.

func (*TextInput) Render

func (n *TextInput) Render()

Render implements [Node.Render]. Render draws the text field background, the current value (or placeholder when empty), the text cursor when focused, and the error message when set.

func (*TextInput) SetValue

func (n *TextInput) SetValue(value string)

SetValue replaces the current text content with value, moving the cursor to the end.

func (*TextInput) Submitted

func (n *TextInput) Submitted() bool

Submitted reports whether the user pressed Enter while this field was focused.

func (*TextInput) Update

func (n *TextInput) Update()

Update implements [Node.Update]. Update processes keyboard input, mouse clicks for focus/cursor placement, and clipboard paste (Ctrl+V). Escape and Enter blur the field.

func (*TextInput) Value

func (n *TextInput) Value() string

Value returns the current text content as a string.

type TextInputProps

type TextInputProps struct {
	BoxProps

	FontConfigProps

	// ErrorColor is the border and error message color when ErrorMessage is
	// set. Defaults to [DefaultErrorColor].
	ErrorColor rl.Color

	// PlaceholderColor is the color used to render the placeholder text.
	// Defaults to a contrast-adjusted version of the foreground color.
	PlaceholderColor rl.Color
}

TextInputProps is the configuration struct for *TextInput.

type TextProps

type TextProps struct {
	BoxProps

	FontConfigProps

	// Wrapping controls how text behaves when it exceeds its bounding box
	// width.
	Wrapping TextWrapping
}

TextProps is the configuration struct for Text.

type TextWrapping

type TextWrapping uint8

TextWrapping controls how a *Text node handles content wider than its bounding box.

const (
	// TextNoWrap renders text on a single line.
	TextNoWrap TextWrapping = iota

	// TextWrap breaks text onto multiple lines at word boundaries.
	TextWrap

	// TextEllipsisOverflow clips text and appends "..." when it overflows.
	TextEllipsisOverflow
)

type TextureFit

type TextureFit uint8

TextureFit controls how an image is scaled to fit inside a *Box that has a texture set.

const (
	// TextureFitCover scales the texture uniformly until it covers the entire
	// box, cropping any overflow.
	TextureFitCover TextureFit = iota

	// TextureFitContain scales the texture uniformly so it fits entirely within
	// the box, leaving empty strips if aspect ratios differ.
	TextureFitContain
)

type Toggle

type Toggle struct {
	Box
	ChildlessNode

	// OffColor is the color of the thumb/fill when the toggle is off.
	OffColor rl.Color

	// OnColor is the color of the thumb/fill when the toggle is on.
	OnColor rl.Color
	// contains filtered or unexported fields
}

Toggle is a boolean switch widget. It renders either as a sliding pill (when created with NewToggle) or as a filled square/circle checkbox (when created with NewCheckBox).

Toggle requires an ID. State is persisted in the node cache.

func NewCheckBox

func NewCheckBox(props ToggleProps, value bool) *Toggle

NewCheckBox creates (or retrieves from cache) a checkbox-style toggle. value is the initial on/off state. Requires a non-zero ID in props.

func NewToggle

func NewToggle(props ToggleProps, value bool) *Toggle

NewToggle creates (or retrieves from cache) a sliding pill toggle. value is the initial on/off state. Requires a non-zero ID in props.

func (*Toggle) ApplyProps

func (n *Toggle) ApplyProps(props ToggleProps)

ApplyProps updates the toggle's visual properties, applying style-specific defaults (pill vs checkbox).

func (*Toggle) GetValue

func (n *Toggle) GetValue() bool

GetValue returns the current toggle state.

func (*Toggle) HasChanged

func (n *Toggle) HasChanged() bool

HasChanged reports whether the toggle state changed during the last Update call.

func (*Toggle) Render

func (n *Toggle) Render()

Render implements [Node.Render]. Render draws the toggle. For checkboxes it fills with OnColor or OffColor. For pill toggles it draws a background track and a sliding thumb.

func (*Toggle) SetValue

func (n *Toggle) SetValue(value bool)

SetValue programmatically sets the toggle state.

func (*Toggle) Toggle

func (n *Toggle) Toggle()

Toggle flips the current boolean state.

func (*Toggle) Update

func (n *Toggle) Update()

Update implements [Node.Update]. Update flips the toggle state when clicked.

type ToggleProps

type ToggleProps struct {
	BoxProps

	// OnColor is the color of the thumb/fill when the toggle is on.
	// Defaults to rl.RayWhite.
	OnColor rl.Color

	// OffColor is the color of the thumb/fill when the toggle is off.
	// Defaults to rl.Gray.
	OffColor rl.Color
}

ToggleProps is the configuration struct for *Toggle.

type ZIndex

type ZIndex = int16

ZIndex is the type used for sub-window layering. Higher values render on top.

const (
	// ZIndexEphemeral is the z-index assigned to ephemeral sub-windows.
	// It marks the window as a one-shot overlay (e.g. a context menu)
	// that is automatically hidden when the user clicks outside of it.
	// It is the highest possible value so they always render on top.
	ZIndexEphemeral ZIndex = math.MaxInt16

	// ZIndexPopup is a z-index suitable for modal or pop-up sub-windows that
	// should appear above normal content but below ephemeral overlays.
	ZIndexPopup ZIndex = 10_000

	// ZIndexBase is the default z-index for ordinary sub-windows.
	ZIndexBase ZIndex = 0

	// ZIndexRoot is the lowest possible z-index. Assign it to the primary
	// root sub-window so that all other windows render on top of it.
	ZIndexRoot ZIndex = math.MinInt16
)

Directories

Path Synopsis
cmd
example command

Jump to

Keyboard shortcuts

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