wayne

package module
v0.0.0-...-e48acf2 Latest Latest
Warning

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

Go to latest
Published: Jun 20, 2026 License: MIT Imports: 19 Imported by: 0

README

wayne

API-compatible cross-platform GUI for Windows, macOS, Android, iOS

Platform Support

wayne provides cross-platform GUI widgets using Ebitengine as the rendering backend. It maintains API compatibility with opd-ai/wain, enabling source-level migration for applications targeting non-Linux platforms.

Supported Platforms
  • Windows - Fully tested via CI
  • macOS - Fully tested via CI
  • Android - Tested via CI (emulator)
  • iOS - Tested via CI (simulator)
  • Linux/BSD - Not supported. For Linux, use opd-ai/wain instead
Testing Status
Platform Build Unit Tests Integration Tests CI Status
Windows ✅ Yes ✅ Yes ⚠️ Partial ✅ Automated
macOS ✅ Yes ✅ Yes ⚠️ Partial ✅ Automated
Android ✅ Yes ✅ Yes ⚠️ Partial ✅ Automated
iOS ✅ Yes ✅ Yes ⚠️ Partial ✅ Automated

Note: Android tests run on an x86_64 emulator (API 29) and iOS tests run on an iPhone simulator. For device-specific testing, use gomobile test with appropriate device configurations.

Running Tests

Tests require CGO and platform-specific graphics contexts:

# On Windows
CGO_ENABLED=1 go test -v ./...

# On macOS  
CGO_ENABLED=1 go test -v ./...

# On Linux (not supported - build tags exclude Linux)
# Tests will not match any packages

For Android and iOS, tests must be run using gomobile test with appropriate device configurations (see Ebitengine documentation).

Development

# Install dependencies
go mod download

# Run tests (on supported platforms)
CGO_ENABLED=1 go test -race ./...

# Run static analysis
go vet ./...

Donate Monero(The only good cryptocurrency) to support development

  • monero:43H3Uqnc9rfEsJjUXZYmam45MbtWmREFSANAWY5hijY4aht8cqYaT2BCNhfBhua5XwNdx9Tb6BEdt4tjUHJDwNW5H7mTiwe

Documentation

Overview

Package wayne provides cross-platform UI widgets. See doc.go for details.

Package wayne provides an API-compatible alternative to the opd-ai/wain widget system, targeting Windows, macOS, Android, and iOS.

Wayne uses Ebitengine (github.com/hajimehoshi/ebiten/v2) as its rendering and windowing backend, replacing wain's Linux-specific Wayland/X11 backend.

Public API compatibility: All public widget interfaces, constructors, and types match wain's API surface, enabling source-level migration by changing the import path. See COMPATIBILITY.md for details on known differences and migration strategies.

Quick Start

app := wayne.NewApp()
defer app.Close()

win, _ := app.NewWindow(wayne.WindowConfig{Title: "Hello", Width: 800, Height: 600})
win.Show()

btn := wayne.NewButton("Click me", wayne.Size{Width: 30, Height: 10})
btn.OnClick(func() { fmt.Println("clicked!") })

col := wayne.NewColumn()
col.Add(btn)
win.SetRoot(col)

app.Run()

HiDPI Scaling

Wayne supports HiDPI displays (Retina, 4K) through the Theme.Scale property. Set Scale to 2.0 for Retina/HiDPI displays to ensure UI elements render at the correct physical size:

theme := wayne.DefaultDark()
theme.Scale = 2.0  // For HiDPI/Retina displays
app.SetTheme(theme)

The scale factor affects:

  • Text rendering (font sizes are multiplied by scale)
  • Widget borders and padding
  • Border radius for rounded corners

Widget positions and layout percentages are not affected by scale; only visual rendering is scaled.

Keyboard Focus and Tab Navigation

Wayne supports keyboard focus management with automatic Tab navigation. Widgets that implement the Focusable interface (Button, TextInput) can receive focus and respond to keyboard events.

Focus chain is automatically built from the widget tree when SetRoot is called. Users can navigate between focusable widgets using Tab (forward) and Shift+Tab (backward). Focused buttons can be activated with Enter or Space keys.

// Focus is automatically managed
btn1 := wayne.NewButton("First", wayne.Size{Width: 30, Height: 10})
btn2 := wayne.NewButton("Second", wayne.Size{Width: 30, Height: 10})
input := wayne.NewTextInput("Type here", wayne.Size{Width: 50, Height: 8})

col := wayne.NewColumn()
col.Add(btn1)
col.Add(input)
col.Add(btn2)
win.SetRoot(col)  // Focus chain: btn1 → input → btn2

Programmatic focus control is available via the window's event dispatcher:

win.SetRoot(col)
// Set focus to a specific widget
win.dispatcher.SetFocus(input)

Widget Sizing Convention

Widgets with text content (Button, Label, TextInput) require explicit Size parameters. Spacers and containers (Panel, ScrollView, ImageWidget) also require explicit Size. Container widgets (Row, Column, Stack, Grid) use percentage-based defaults of 100x100 (full parent dimensions).

All Size values are percentages (0-100) of the parent container. For example, Size{Width: 50, Height: 100} means "50% of parent width, 100% of parent height".

Supported Platforms

Wayne compiles on Windows, macOS, Android, and iOS. It explicitly does NOT support Linux or BSD.

Architecture

Wayne's App type wraps an Ebitengine game loop (ebiten.RunGame). The widget tree is resolved and rendered each frame via Ebitengine's Draw callback, with layout computed from percentage-based Size values.

Example

Example demonstrates creating a simple application with a button.

package main

import (
	"fmt"

	"github.com/opd-ai/wayne"
)

func main() {
	app := wayne.NewApp()
	panel := wayne.NewPanel(wayne.Size{Width: 100, Height: 100})
	btn := wayne.NewButton("Click Me", wayne.Size{Width: 50, Height: 10})
	btn.OnClick(func() {
		fmt.Println("Button clicked!")
	})
	panel.Add(btn)
	app.SetRoot(panel)
	// In a real application: app.Run(wayne.WindowConfig{Title: "Demo"})
	fmt.Println("App created with button")
}
Output:
App created with button
Example (Themes)

Example_themes demonstrates using the built-in themes.

package main

import (
	"fmt"

	"github.com/opd-ai/wayne"
)

func main() {
	dark := wayne.DefaultDark()
	light := wayne.DefaultLight()
	contrast := wayne.HighContrast()
	fmt.Printf("Themes: dark=%T, light=%T, contrast=%T\n", dark, light, contrast)
}
Output:
Themes: dark=wayne.Theme, light=wayne.Theme, contrast=wayne.Theme

Index

Examples

Constants

View Source
const (
	// DefaultPadding is the default inner padding in pixels.
	DefaultPadding = 8

	// DefaultGap is the default gap between sibling widgets in pixels.
	DefaultGap = 6

	// DefaultBorderRadius is the default border radius for rounded corners in pixels.
	DefaultBorderRadius = 4
)

Variables

View Source
var (
	// ErrNotRunning is returned when calling methods that require Run() to be active.
	ErrNotRunning = errors.New("wayne: app not running")

	// ErrAlreadyRunning is returned when Run() is called more than once.
	ErrAlreadyRunning = errors.New("wayne: app already running")

	// ErrInvalidWindowConfig is returned when window configuration is invalid.
	ErrInvalidWindowConfig = errors.New("wayne: invalid window configuration")
)
View Source
var (
	// Transparent is fully transparent black.
	Transparent = RGBA(0, 0, 0, 0)

	// Black is opaque black.
	Black = RGB(0, 0, 0)

	// White is opaque white.
	White = RGB(255, 255, 255)

	// Red is opaque red.
	Red = RGB(255, 0, 0)

	// Green is opaque green.
	Green = RGB(0, 255, 0)

	// Blue is opaque blue.
	Blue = RGB(0, 0, 255)

	// Gray is opaque medium gray.
	Gray = RGB(128, 128, 128)

	// LightGray is opaque light gray.
	LightGray = RGB(192, 192, 192)

	// DarkGray is opaque dark gray.
	DarkGray = RGB(64, 64, 64)

	// Yellow is opaque yellow.
	Yellow = RGB(255, 255, 0)
)

Common color constants for convenience.

View Source
var (
	// DarkBase is the primary background color for dark themes.
	DarkBase = RGB(30, 30, 46)

	// DarkText is the primary text color for dark themes.
	DarkText = RGB(205, 214, 244)

	// DarkAccent is the accent/highlight color for dark themes.
	DarkAccent = RGB(137, 180, 250)

	// DarkBorder is the border color for dark themes.
	DarkBorder = RGB(88, 91, 112)
)

Theme color palette constants for dark theme (Catppuccin-inspired).

View Source
var (
	// LightBase is the primary background color for light themes.
	LightBase = RGB(245, 245, 245)

	// LightText is the primary text color for light themes.
	LightText = RGB(30, 30, 30)

	// LightAccent is the accent/highlight color for light themes.
	LightAccent = RGB(74, 144, 226)

	// LightBorder is the border color for light themes.
	LightBorder = RGB(200, 200, 200)
)

Theme color palette constants for light theme.

View Source
var (
	// ErrUnsupportedImageFormat is returned for unsupported image formats.
	ErrUnsupportedImageFormat = errors.New("wayne: unsupported image format")

	// ErrInvalidFontData is returned when font data is malformed.
	ErrInvalidFontData = errors.New("wayne: invalid font data")

	// ErrResourceManagerClosed is returned when attempting to load resources after cleanup.
	ErrResourceManagerClosed = errors.New("wayne: resource manager is closed")
)

Functions

This section is empty.

Types

type Align

type Align int

Align specifies alignment on the cross axis of a container.

const (
	// AlignStart aligns children to the start of the cross axis.
	AlignStart Align = iota
	// AlignCenter centers children on the cross axis.
	AlignCenter
	// AlignEnd aligns children to the end of the cross axis.
	AlignEnd
	// AlignStretch stretches children to fill the cross axis.
	AlignStretch
)

type App

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

App represents a UI application backed by Ebitengine.

App manages the main event loop and the primary window. It is the entry point for all wayne applications.

Example:

app := wayne.NewApp()
defer app.Close()
win, _ := app.NewWindow(wayne.WindowConfig{Title: "Hello", Width: 800, Height: 600})
win.Show()
app.Run()

func NewApp

func NewApp() *App

NewApp creates a new application with default configuration.

Example

ExampleNewApp demonstrates creating a basic application.

package main

import (
	"fmt"

	"github.com/opd-ai/wayne"
)

func main() {
	app := wayne.NewApp()
	app.SetTheme(wayne.DefaultDark())
	fmt.Printf("App created: %T\n", app)
}
Output:
App created: *wayne.App

func NewAppWithConfig

func NewAppWithConfig(cfg AppConfig) *App

NewAppWithConfig creates a new application with the specified configuration.

Example

ExampleNewAppWithConfig demonstrates creating an app with custom configuration.

package main

import (
	"fmt"

	"github.com/opd-ai/wayne"
)

func main() {
	cfg := wayne.AppConfig{
		Width:  800,
		Height: 600,
	}
	app := wayne.NewAppWithConfig(cfg)
	fmt.Printf("App with config: %T\n", app)
}
Output:
App with config: *wayne.App

func (*App) Close

func (a *App) Close()

Close releases resources associated with the app. It does not stop a running event loop; call Quit() for that.

func (*App) DefaultFont

func (a *App) DefaultFont() *Font

DefaultFont returns the embedded default font.

func (*App) LoadFont

func (a *App) LoadFont(path string, size float64) (*Font, error)

LoadFont loads a font from the specified path at the given size.

Supported formats: TrueType (.ttf), OpenType (.otf) - currently not implemented, falls back to embedded font.

Size is specified in points and must be positive.

Returns an error if the app is not running or if the font parameters are invalid.

func (*App) LoadImage

func (a *App) LoadImage(path string) (*Image, error)

LoadImage loads an image from the specified path.

Supported formats: PNG, JPEG, GIF (via standard library image decoders).

Returns an error if the app is not running, the file does not exist, or the image format is unsupported.

func (*App) NewWindow

func (a *App) NewWindow(cfg WindowConfig) (*Window, error)

NewWindow creates a new window.

Since Ebitengine manages a single OS window, the first call to NewWindow configures the primary window. Subsequent calls create logical windows that are rendered as overlapping root widget subtrees.

func (*App) Notify

func (a *App) Notify(fn func())

Notify schedules a function to be called from the main goroutine on the next tick. This is safe to call from any goroutine.

func (*App) Quit

func (a *App) Quit()

Quit signals the application to exit on the next tick.

func (*App) Run

func (a *App) Run() error

Run starts the main event loop. This blocks until the app is quit or an error occurs. Run must be called from the main goroutine.

func (*App) SetRoot

func (a *App) SetRoot(w PublicWidget)

SetRoot sets the root widget on the primary window. This is a convenience method equivalent to primaryWindow.SetRoot(w).

func (*App) SetTheme

func (a *App) SetTheme(theme Theme)

SetTheme sets the application-wide theme.

type AppConfig

type AppConfig struct {
	// Width is the initial window width in pixels (default: 800).
	Width int

	// Height is the initial window height in pixels (default: 600).
	Height int

	// Verbose enables logging of backend selection decisions (default: false).
	Verbose bool
}

AppConfig contains configuration options for creating an App.

func DefaultConfig

func DefaultConfig() AppConfig

DefaultConfig returns the default application configuration.

type BasePublicWidget

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

BasePublicWidget provides default implementations for the PublicWidget interface.

Embed BasePublicWidget in custom widget types to get default event handling and bounds management. Override Draw() to provide custom rendering.

Example:

type ColoredPanel struct {
    wayne.BasePublicWidget
    Color wayne.Color
}

func (p *ColoredPanel) Draw(c wayne.Canvas) {
    c.FillRect(p.X(), p.Y(), p.Width(), p.Height(), p.Color)
}

func NewBasePublicWidget

func NewBasePublicWidget(width, height int) BasePublicWidget

NewBasePublicWidget creates a BasePublicWidget with the given pixel dimensions.

func (*BasePublicWidget) Add

func (w *BasePublicWidget) Add(child PublicWidget)

Add appends a child widget.

func (*BasePublicWidget) Children

func (w *BasePublicWidget) Children() []PublicWidget

Children returns the list of child widgets.

func (*BasePublicWidget) Draw

func (w *BasePublicWidget) Draw(c Canvas)

Draw is a no-op. Override this in concrete widget types.

func (*BasePublicWidget) HandleEvent

func (w *BasePublicWidget) HandleEvent(evt Event) bool

HandleEvent processes an event. The default implementation invokes the registered event handler if one is set, otherwise returns false.

func (*BasePublicWidget) Height

func (w *BasePublicWidget) Height() int

Height returns the current height of the widget in pixels.

func (*BasePublicWidget) IsFocused

func (w *BasePublicWidget) IsFocused() bool

IsFocused returns true if the widget currently has keyboard focus.

func (*BasePublicWidget) IsVisible

func (w *BasePublicWidget) IsVisible() bool

IsVisible returns true if the widget is visible.

func (*BasePublicWidget) OnEvent

func (w *BasePublicWidget) OnEvent(handler func(Event) bool)

OnEvent registers a callback to handle events for this widget.

func (*BasePublicWidget) SetBounds

func (w *BasePublicWidget) SetBounds(x, y, width, height int)

SetBounds updates the widget's pixel dimensions and position.

func (*BasePublicWidget) SetFocused

func (w *BasePublicWidget) SetFocused(focused bool)

SetFocused sets the widget's keyboard focus state.

func (*BasePublicWidget) SetVisible

func (w *BasePublicWidget) SetVisible(visible bool)

SetVisible controls whether the widget participates in layout and rendering.

func (*BasePublicWidget) Width

func (w *BasePublicWidget) Width() int

Width returns the current width of the widget in pixels.

func (*BasePublicWidget) X

func (w *BasePublicWidget) X() int

X returns the current x-coordinate of the widget in pixels.

func (*BasePublicWidget) Y

func (w *BasePublicWidget) Y() int

Y returns the current y-coordinate of the widget in pixels.

type BaseWidget deprecated

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

BaseWidget provides default implementations for the Widget interface.

Deprecated: Use BasePublicWidget instead. See Widget interface documentation for migration guidance.

func (*BaseWidget) AddChild

func (w *BaseWidget) AddChild(child Widget)

AddChild adds a child widget.

func (*BaseWidget) Children

func (w *BaseWidget) Children() []Widget

Children returns the widget's child widgets.

func (*BaseWidget) Contains

func (w *BaseWidget) Contains(x, y float64) bool

Contains returns true if (x, y) is inside the widget's bounds.

func (*BaseWidget) HandleKey

func (w *BaseWidget) HandleKey(evt *KeyEvent)

HandleKey processes a keyboard event, invoking the callback if set.

func (*BaseWidget) HandlePointer

func (w *BaseWidget) HandlePointer(evt *PointerEvent)

HandlePointer processes a pointer event, invoking the callback if set.

func (*BaseWidget) HandleTouch

func (w *BaseWidget) HandleTouch(evt *TouchEvent)

HandleTouch processes a touch event, invoking the callback if set.

func (*BaseWidget) IsFocused

func (w *BaseWidget) IsFocused() bool

IsFocused returns true if the widget currently has keyboard focus.

func (*BaseWidget) OnKey

func (w *BaseWidget) OnKey(handler func(*KeyEvent))

OnKey sets the keyboard event callback.

func (*BaseWidget) OnPointer

func (w *BaseWidget) OnPointer(handler func(*PointerEvent))

OnPointer sets the pointer event callback.

func (*BaseWidget) OnTouch

func (w *BaseWidget) OnTouch(handler func(*TouchEvent))

OnTouch sets the touch event callback.

func (*BaseWidget) SetBounds

func (w *BaseWidget) SetBounds(x, y, width, height float64)

SetBounds sets the widget's position and size.

func (*BaseWidget) SetFocused

func (w *BaseWidget) SetFocused(focused bool)

SetFocused sets the widget's keyboard focus state.

type Button

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

Button is a clickable button widget with text and onClick callback.

Example:

btn := wayne.NewButton("Submit", wayne.Size{Width: 30, Height: 8})
btn.OnClick(func() {
    fmt.Println("Button clicked!")
})
panel.Add(btn)

func NewButton

func NewButton(label string, size Size) *Button

NewButton creates a new button with the specified label and percentage-based size.

Example

ExampleNewButton demonstrates creating and configuring a Button widget.

package main

import (
	"fmt"

	"github.com/opd-ai/wayne"
)

func main() {
	btn := wayne.NewButton("Submit", wayne.Size{Width: 30, Height: 8})
	btn.OnClick(func() {
		fmt.Println("Submitted!")
	})
	btn.SetEnabled(true)
	fmt.Printf("Button label can be set: %T\n", btn)
}
Output:
Button label can be set: *wayne.Button

func (*Button) CanTakeFocus

func (b *Button) CanTakeFocus() bool

CanTakeFocus returns true if the button can currently receive keyboard focus.

func (*Button) Draw

func (b *Button) Draw(c Canvas)

Draw renders the button to the canvas.

func (*Button) HandleEvent

func (b *Button) HandleEvent(evt Event) bool

HandleEvent processes pointer, touch, and keyboard events for button interaction.

func (*Button) OnClick

func (b *Button) OnClick(handler func())

OnClick registers a callback to be invoked when the button is clicked.

func (*Button) SetEnabled

func (b *Button) SetEnabled(enabled bool)

SetEnabled enables or disables the button.

func (*Button) SetLabel

func (b *Button) SetLabel(text string)

SetLabel changes the button's displayed text.

func (*Button) SetText deprecated

func (b *Button) SetText(text string)

SetText changes the button's displayed text (alias for SetLabel).

Deprecated: Use SetLabel instead. SetText is retained for compatibility but will be removed in v2.0.0.

func (*Button) SetTheme

func (b *Button) SetTheme(theme Theme)

SetTheme applies a theme to this button.

func (*Button) Text

func (b *Button) Text() string

Text returns the button's current label.

type Canvas

type Canvas interface {
	// FillRect fills a solid rectangle at the given position and size.
	FillRect(x, y, width, height int, color Color)

	// FillRoundedRect fills a rounded rectangle with the specified corner radius.
	FillRoundedRect(x, y, width, height, radius int, color Color)

	// DrawLine draws a line segment from (x1, y1) to (x2, y2).
	DrawLine(x1, y1, x2, y2 int, color Color, thickness int)

	// DrawText renders text at the given position using the specified font and color.
	DrawText(text string, x, y int, font *Font, color Color)

	// DrawImage renders an image at the given position and size.
	DrawImage(img *Image, x, y, width, height int)

	// LinearGradient fills a rectangle with a linear gradient from startColor to endColor.
	// The angle parameter specifies the gradient direction in degrees (0 = left-to-right,
	// 90 = top-to-bottom, 180 = right-to-left, 270 = bottom-to-top).
	//
	// Note: Uses approximation rendering that may show banding on large gradients (>500px).
	LinearGradient(x, y, width, height int, startColor, endColor Color, angle float64)

	// RadialGradient fills a rectangle with a radial gradient from centerColor to edgeColor.
	// The gradient radiates from the rectangle's center to its corners.
	//
	// Note: Uses concentric circle approximation. Very large gradients (>1000px diagonal)
	// may show subtle banding on high-DPI displays.
	RadialGradient(x, y, width, height int, centerColor, edgeColor Color)

	// BoxShadow renders a simplified shadow around the given rectangle.
	// offsetX and offsetY control shadow position, blur controls spread and corner radius.
	//
	// Note: This is a simplified approximation without Gaussian blur. Does not match CSS
	// box-shadow semantics. For production-quality shadows, consider pre-rendered images.
	BoxShadow(x, y, width, height, offsetX, offsetY, blur int, color Color)

	// Theme returns the application-wide theme for this rendering context.
	Theme() Theme

	// Scale returns the current HiDPI scale factor from the theme.
	// A value of 1.0 means standard resolution, 2.0 means retina/HiDPI.
	// Widgets should use this to scale padding, borders, and other pixel values.
	Scale() float64
}

Canvas provides a high-level drawing API for widget rendering.

Canvas abstracts over the internal rendering backend (Ebitengine). Methods accept pixel coordinates and handle GPU rendering automatically.

Canvas instances are provided by the framework during widget rendering; application code does not create Canvas instances directly.

type Color

type Color struct {
	R, G, B, A int32
}

Color represents an RGBA color with 8-bit channels.

Colors are specified in sRGB color space with separate red, green, blue, and alpha components. Alpha of 255 is fully opaque, 0 is fully transparent.

Note: Fields use int32 for gomobile compatibility (uint8 generates invalid Objective-C code). Values should be in range 0-255.

Example:

red := wayne.RGB(255, 0, 0)
transparentBlue := wayne.RGBA(0, 0, 255, 128)

func RGB

func RGB(r, g, b int32) Color

RGB creates an opaque color from red, green, and blue components. Values should be in range 0-255.

func RGBA

func RGBA(r, g, b, a int32) Color

RGBA creates a color from red, green, blue, and alpha components. Values should be in range 0-255.

func (Color) WithAlpha

func (c Color) WithAlpha(a int32) Color

WithAlpha returns a new color with the specified alpha value. Alpha should be in range 0-255.

type Column

type Column struct {
	*Panel
}

Column is a convenience container that arranges children vertically.

Column is equivalent to a Panel with FlowDirection set to FlowColumn.

func NewColumn

func NewColumn() *Column

NewColumn creates a new vertical container.

Example

ExampleNewColumn demonstrates creating a vertical layout container.

package main

import (
	"fmt"

	"github.com/opd-ai/wayne"
)

func main() {
	col := wayne.NewColumn()
	col.SetGap(10)
	col.Add(wayne.NewLabel("Top", wayne.Size{Width: 100, Height: 10}))
	col.Add(wayne.NewLabel("Bottom", wayne.Size{Width: 100, Height: 10}))
	fmt.Printf("Column children: %d\n", len(col.Children()))
}
Output:
Column children: 2

type Container

type Container interface {
	PublicWidget

	// Add appends a child widget to this container.
	Add(child PublicWidget)

	// Children returns a slice of the container's child widgets.
	Children() []PublicWidget
}

Container extends PublicWidget for widgets that can contain child widgets.

type CustomEvent

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

CustomEvent represents application-defined events.

func NewCustomEvent

func NewCustomEvent(data CustomEventPayload) *CustomEvent

NewCustomEvent creates a new custom event with the given payload.

func (*CustomEvent) Consume

func (e *CustomEvent) Consume()

Consume marks this event as consumed, preventing further propagation.

func (*CustomEvent) Consumed

func (e *CustomEvent) Consumed() bool

Consumed returns true if this event has been consumed by a handler.

func (*CustomEvent) Data

func (e *CustomEvent) Data() CustomEventPayload

Data returns the application-defined payload for this custom event.

func (*CustomEvent) Timestamp

func (e *CustomEvent) Timestamp() time.Time

Timestamp returns the time when the event was created.

func (*CustomEvent) Type

func (e *CustomEvent) Type() EventType

Type returns the general event type (EventTypeCustom).

type CustomEventPayload

type CustomEventPayload interface{}

CustomEventPayload is an opaque payload for application-defined custom events.

type Event

type Event interface {
	Type() EventType
	Timestamp() time.Time
	Consumed() bool
	Consume()
}

Event is the common interface for all events.

type EventDispatcher

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

EventDispatcher manages event routing from platform sources to widget handlers.

func NewEventDispatcher

func NewEventDispatcher() *EventDispatcher

NewEventDispatcher creates a new event dispatcher.

func (*EventDispatcher) Dispatch

func (d *EventDispatcher) Dispatch(evt Event)

Dispatch routes an event to appropriate handlers.

func (*EventDispatcher) FocusedWidget

func (d *EventDispatcher) FocusedWidget() PublicWidget

FocusedWidget returns the currently focused widget.

func (*EventDispatcher) OnCustom

func (d *EventDispatcher) OnCustom(handler func(*CustomEvent))

OnCustom registers a custom event handler.

func (*EventDispatcher) OnKey

func (d *EventDispatcher) OnKey(handler func(*KeyEvent))

OnKey registers a keyboard event handler.

func (*EventDispatcher) OnPointer

func (d *EventDispatcher) OnPointer(handler func(*PointerEvent))

OnPointer registers a pointer event handler.

func (*EventDispatcher) OnTouch

func (d *EventDispatcher) OnTouch(handler func(*TouchEvent))

OnTouch registers a touch event handler.

func (*EventDispatcher) OnWindow

func (d *EventDispatcher) OnWindow(handler func(*WindowEvent))

OnWindow registers a window event handler.

func (*EventDispatcher) SetFocus

func (d *EventDispatcher) SetFocus(w PublicWidget)

SetFocus sets focus to a specific widget.

func (*EventDispatcher) SetWidgetRoot

func (d *EventDispatcher) SetWidgetRoot(root PublicWidget)

SetWidgetRoot sets the root widget for hit-testing.

type EventHandler

type EventHandler func(Event)

EventHandler is a function that processes events.

type EventType

type EventType int

EventType identifies the category of an event.

const (
	// EventTypePointer identifies mouse/touchpad pointer events.
	EventTypePointer EventType = iota
	// EventTypeKey identifies keyboard events.
	EventTypeKey
	// EventTypeTouch identifies touch screen events.
	EventTypeTouch
	// EventTypeWindow identifies window state events.
	EventTypeWindow
	// EventTypeCustom identifies application-defined events.
	EventTypeCustom
)

type FlowDirection

type FlowDirection int

FlowDirection controls how a container arranges its child widgets.

const (
	// FlowRow arranges children horizontally, left to right.
	FlowRow FlowDirection = iota

	// FlowColumn arranges children vertically, top to bottom.
	FlowColumn
)

type FocusManager

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

FocusManager manages keyboard focus and tab order.

func NewFocusManager

func NewFocusManager() *FocusManager

NewFocusManager creates a new focus manager.

func (*FocusManager) ClearFocus

func (fm *FocusManager) ClearFocus()

ClearFocus removes focus from all widgets.

func (*FocusManager) Focus

func (fm *FocusManager) Focus(w PublicWidget)

Focus sets focus to a specific widget.

func (*FocusManager) FocusNext

func (fm *FocusManager) FocusNext()

FocusNext moves focus to the next widget in the chain.

func (*FocusManager) FocusPrev

func (fm *FocusManager) FocusPrev()

FocusPrev moves focus to the previous widget in the chain.

func (*FocusManager) Focused

func (fm *FocusManager) Focused() PublicWidget

Focused returns the currently focused widget.

func (*FocusManager) SetChain

func (fm *FocusManager) SetChain(widgets []PublicWidget)

SetChain sets the focus chain (tab order).

func (*FocusManager) SetChainFromRoot

func (fm *FocusManager) SetChainFromRoot(root PublicWidget)

SetChainFromRoot builds a focus chain from a widget tree. It collects all Focusable widgets in depth-first order.

type Focusable

type Focusable interface {
	PublicWidget

	// CanTakeFocus returns true if the widget can currently receive focus.
	// Disabled or hidden widgets should return false.
	CanTakeFocus() bool
}

Focusable is the interface for widgets that can receive keyboard focus.

type Font

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

Font represents a loaded font resource.

func (*Font) Size

func (f *Font) Size() float64

Size returns the font size in points.

type Grid

type Grid struct {
	*Panel
	// contains filtered or unexported fields
}

Grid is a fixed-column grid container.

func NewGrid

func NewGrid(columns int) *Grid

NewGrid creates a new grid container with the specified number of columns.

Example

ExampleNewGrid demonstrates creating a grid layout container.

package main

import (
	"fmt"

	"github.com/opd-ai/wayne"
)

func main() {
	grid := wayne.NewGrid(3) // 3 columns
	for i := 0; i < 6; i++ {
		grid.Add(wayne.NewLabel(fmt.Sprintf("Cell %d", i), wayne.Size{Width: 30, Height: 10}))
	}
	fmt.Printf("Grid children: %d\n", len(grid.Children()))
}
Output:
Grid children: 6

func (*Grid) Columns

func (g *Grid) Columns() int

Columns returns the number of columns in the grid.

func (*Grid) SetColumns

func (g *Grid) SetColumns(columns int)

SetColumns changes the number of columns in the grid.

type Image

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

Image represents a loaded image resource.

func (*Image) Height

func (img *Image) Height() int

Height returns the image height in pixels.

func (*Image) Width

func (img *Image) Width() int

Width returns the image width in pixels.

type ImageWidget

type ImageWidget struct {
	BasePublicWidget
	// contains filtered or unexported fields
}

ImageWidget displays an image resource.

Example:

imageWidget := wayne.NewImageWidget(wayne.Size{Width: 20, Height: 20})
imageWidget.SetImage(img)
panel.Add(imageWidget)

func NewImageWidget

func NewImageWidget(size Size) *ImageWidget

NewImageWidget creates a new image display widget.

Example

ExampleNewImageWidget demonstrates creating an image display widget.

package main

import (
	"fmt"

	"github.com/opd-ai/wayne"
)

func main() {
	img := wayne.NewImageWidget(wayne.Size{Width: 50, Height: 50})
	// Load image: img.SetImage(loadedImage)
	fmt.Printf("ImageWidget created: %T\n", img)
}
Output:
ImageWidget created: *wayne.ImageWidget

func NewImageWidgetWithImage

func NewImageWidgetWithImage(img *Image, size Size) *ImageWidget

NewImageWidgetWithImage creates a new image display widget with an initial image. This constructor provides compatibility with wain's NewImageWidget(img, size) signature.

func (*ImageWidget) Draw

func (iw *ImageWidget) Draw(c Canvas)

Draw renders the image to the canvas.

func (*ImageWidget) GetImage

func (iw *ImageWidget) GetImage() *Image

GetImage returns the currently displayed image.

func (*ImageWidget) HandleEvent

func (iw *ImageWidget) HandleEvent(_ Event) bool

HandleEvent does nothing for image widgets.

func (*ImageWidget) SetImage

func (iw *ImageWidget) SetImage(img *Image)

SetImage changes the displayed image.

type Key

type Key uint32

Key represents a keyboard key symbol (compatible with X11 keysyms).

const (
	KeyEscape    Key = 0xFF1B
	KeyReturn    Key = 0xFF0D
	KeyTab       Key = 0xFF09
	KeyBackspace Key = 0xFF08
	KeyDelete    Key = 0xFFFF
	KeyLeft      Key = 0xFF51
	KeyUp        Key = 0xFF52
	KeyRight     Key = 0xFF53
	KeyDown      Key = 0xFF54
	KeyHome      Key = 0xFF50
	KeyEnd       Key = 0xFF57
	KeyPageUp    Key = 0xFF55
	KeyPageDown  Key = 0xFF56
	KeySpace     Key = 0x0020

	// Modifier key constants - exported for consumer use in detecting modifier key presses.
	KeyShiftL   Key = 0xFFE1
	KeyShiftR   Key = 0xFFE2
	KeyControlL Key = 0xFFE3
	KeyControlR Key = 0xFFE4
	KeyAltL     Key = 0xFFE9
	KeyAltR     Key = 0xFFEA
	KeySuperL   Key = 0xFFEB
	KeySuperR   Key = 0xFFEC
)

Common key constants. These are exported for use by application code that needs to detect specific key presses in HandleEvent callbacks. Modifier keys are included for completeness even if not directly used by internal widget implementations.

type KeyEvent

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

KeyEvent represents keyboard events.

func NewKeyEvent

func NewKeyEvent(evtType KeyEventType, key Key, mods Modifier, r rune) *KeyEvent

NewKeyEvent creates a new KeyEvent.

func (*KeyEvent) Consume

func (e *KeyEvent) Consume()

Consume marks this event as consumed, preventing further propagation.

func (*KeyEvent) Consumed

func (e *KeyEvent) Consumed() bool

Consumed returns true if this event has been consumed by a handler.

func (*KeyEvent) EventType

func (e *KeyEvent) EventType() KeyEventType

EventType returns the specific key event type (press, release, or repeat).

func (*KeyEvent) IsPress

func (e *KeyEvent) IsPress() bool

IsPress returns true if this is a key press or repeat event.

func (*KeyEvent) Key

func (e *KeyEvent) Key() Key

Key returns the key symbol associated with this keyboard event.

func (*KeyEvent) Modifiers

func (e *KeyEvent) Modifiers() Modifier

Modifiers returns the keyboard modifiers active during this event.

func (*KeyEvent) Rune

func (e *KeyEvent) Rune() rune

Rune returns the Unicode character produced by this key event.

func (*KeyEvent) Timestamp

func (e *KeyEvent) Timestamp() time.Time

Timestamp returns the time when the event was created.

func (*KeyEvent) Type

func (e *KeyEvent) Type() EventType

Type returns the general event type (EventTypeKey).

type KeyEventType

type KeyEventType int

KeyEventType specifies the type of keyboard event.

const (
	// KeyPress indicates a key was pressed.
	KeyPress KeyEventType = iota
	// KeyRelease indicates a key was released.
	KeyRelease
	// KeyRepeat indicates a key is repeating (held down).
	KeyRepeat
)

type Label

type Label struct {
	BasePublicWidget
	// contains filtered or unexported fields
}

Label is a static text display widget.

Example:

label := wayne.NewLabel("Welcome", wayne.Size{Width: 100, Height: 5})
panel.Add(label)

func NewLabel

func NewLabel(text string, size Size) *Label

NewLabel creates a new label with the specified text and percentage-based size.

Example

ExampleNewLabel demonstrates creating a text label widget.

package main

import (
	"fmt"

	"github.com/opd-ai/wayne"
)

func main() {
	label := wayne.NewLabel("Hello, World!", wayne.Size{Width: 50, Height: 5})
	label.SetText("Updated text")
	fmt.Printf("Label created: %T\n", label)
}
Output:
Label created: *wayne.Label

func (*Label) Draw

func (l *Label) Draw(c Canvas)

Draw renders the label text to the canvas.

func (*Label) HandleEvent

func (l *Label) HandleEvent(_ Event) bool

HandleEvent does nothing for labels (they don't respond to input).

func (*Label) SetFontSize

func (l *Label) SetFontSize(size int)

SetFontSize sets the font size in pixels.

func (*Label) SetText

func (l *Label) SetText(text string)

SetText changes the label's displayed text.

func (*Label) SetTextColor

func (l *Label) SetTextColor(color Color)

SetTextColor sets the color of the label's text.

func (*Label) SetTheme

func (l *Label) SetTheme(theme Theme)

SetTheme applies a theme to this label.

func (*Label) Text

func (l *Label) Text() string

Text returns the label's current text.

type Modifier

type Modifier uint32

Modifier represents keyboard modifiers.

const (
	// ModShift indicates the Shift key is held.
	ModShift Modifier = 1 << 0
	// ModControl indicates the Control key is held.
	ModControl Modifier = 1 << 1
	// ModAlt indicates the Alt key is held.
	ModAlt Modifier = 1 << 2
	// ModSuper indicates the Super (Windows/Command) key is held.
	ModSuper Modifier = 1 << 3
)

type Panel

type Panel struct {
	BasePublicWidget
	// contains filtered or unexported fields
}

Panel is a styled rectangular container that holds child widgets.

Panel supports percentage-based sizing and automatic layout. It can be used as a building block for complex UIs by nesting panels.

Example:

panel := wayne.NewPanel(wayne.Size{Width: 50, Height: 100})
panel.SetFlowDirection(wayne.FlowColumn)
panel.SetPadding(10)
panel.SetGap(5)
panel.Add(header)
panel.Add(content)

func NewPanel

func NewPanel(size Size) *Panel

NewPanel creates a new Panel with percentage-based dimensions.

Example

ExampleNewPanel demonstrates creating a container panel.

package main

import (
	"fmt"

	"github.com/opd-ai/wayne"
)

func main() {
	panel := wayne.NewPanel(wayne.Size{Width: 100, Height: 100})
	panel.Add(wayne.NewLabel("Item 1", wayne.Size{Width: 50, Height: 10}))
	panel.Add(wayne.NewLabel("Item 2", wayne.Size{Width: 50, Height: 10}))
	fmt.Printf("Panel children: %d\n", len(panel.Children()))
}
Output:
Panel children: 2

func (*Panel) Add

func (p *Panel) Add(child PublicWidget)

Add appends a child widget to this panel.

func (*Panel) Children

func (p *Panel) Children() []PublicWidget

Children returns this panel's child widgets.

func (*Panel) Draw

func (p *Panel) Draw(c Canvas)

Draw renders the panel background and all children.

func (*Panel) FlowDirection

func (p *Panel) FlowDirection() FlowDirection

FlowDirection returns the current flow direction.

func (*Panel) HandleEvent

func (p *Panel) HandleEvent(evt Event) bool

HandleEvent passes events to children and returns true if any child consumed it. For pointer and touch events, only forwards to children whose bounds contain the event coordinates.

func (*Panel) Height

func (p *Panel) Height() int

Height returns the resolved height in pixels.

func (*Panel) SetAlign

func (p *Panel) SetAlign(align Align)

SetAlign sets the cross-axis alignment for children.

func (*Panel) SetFlowDirection

func (p *Panel) SetFlowDirection(dir FlowDirection)

SetFlowDirection sets how this panel arranges its children.

func (*Panel) SetGap

func (p *Panel) SetGap(pixels int)

SetGap sets the spacing (in pixels) between child widgets.

func (*Panel) SetPadding

func (p *Panel) SetPadding(pixels int)

SetPadding sets the padding (in pixels) around the content area.

func (*Panel) SetStyle

func (p *Panel) SetStyle(override StyleOverride)

SetStyle applies a style override to this panel.

func (*Panel) SetTheme

func (p *Panel) SetTheme(theme Theme)

SetTheme applies a theme to this panel and all its children.

func (*Panel) SetVisible

func (p *Panel) SetVisible(visible bool)

SetVisible controls whether this panel is drawn.

func (*Panel) Visible

func (p *Panel) Visible() bool

Visible reports whether the panel is currently visible.

func (*Panel) Width

func (p *Panel) Width() int

Width returns the resolved width in pixels.

type PointerButton

type PointerButton uint32

PointerButton represents a mouse button.

const (
	// PointerButtonLeft is the left mouse button.
	PointerButtonLeft PointerButton = 0x110
	// PointerButtonRight is the right mouse button.
	PointerButtonRight PointerButton = 0x111
	// PointerButtonMiddle is the middle mouse button.
	PointerButtonMiddle PointerButton = 0x112
)

type PointerEvent

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

PointerEvent represents mouse/touchpad pointer events.

func NewPointerEvent

func NewPointerEvent(evtType PointerEventType, x, y float64, button PointerButton, axis ScrollAxis, value float64) *PointerEvent

NewPointerEvent creates a new PointerEvent with the given parameters.

func (*PointerEvent) Axis

func (e *PointerEvent) Axis() ScrollAxis

Axis returns the scroll axis for scroll events (vertical or horizontal).

func (*PointerEvent) Button

func (e *PointerEvent) Button() PointerButton

Button returns the mouse button associated with this pointer event.

func (*PointerEvent) Consume

func (e *PointerEvent) Consume()

Consume marks this event as consumed, preventing further propagation.

func (*PointerEvent) Consumed

func (e *PointerEvent) Consumed() bool

Consumed returns true if this event has been consumed by a handler.

func (*PointerEvent) EventType

func (e *PointerEvent) EventType() PointerEventType

EventType returns the specific pointer event type (move, press, release, scroll).

func (*PointerEvent) Timestamp

func (e *PointerEvent) Timestamp() time.Time

Timestamp returns the time when the event was created.

func (*PointerEvent) Type

func (e *PointerEvent) Type() EventType

Type returns the general event type (EventTypePointer).

func (*PointerEvent) Value

func (e *PointerEvent) Value() float64

Value returns the scroll amount for scroll events.

func (*PointerEvent) X

func (e *PointerEvent) X() float64

X returns the horizontal coordinate of the pointer event.

func (*PointerEvent) Y

func (e *PointerEvent) Y() float64

Y returns the vertical coordinate of the pointer event.

type PointerEventType

type PointerEventType int

PointerEventType specifies the type of pointer event.

const (
	// PointerMove indicates the pointer has moved.
	PointerMove PointerEventType = iota
	// PointerButtonPress indicates a mouse button was pressed.
	PointerButtonPress
	// PointerButtonRelease indicates a mouse button was released.
	PointerButtonRelease
	// PointerScroll indicates a scroll wheel event.
	PointerScroll
	// PointerEnter indicates the pointer entered the window.
	PointerEnter
	// PointerLeave indicates the pointer left the window.
	PointerLeave
)

type PublicWidget

type PublicWidget interface {
	// Width returns the current width in pixels.
	Width() int

	// Height returns the current height in pixels.
	Height() int

	// HandleEvent processes a user interaction event. Returns true if consumed.
	HandleEvent(Event) bool

	// Draw renders the widget to the provided canvas.
	Draw(Canvas)

	// SetFocused sets the widget's keyboard focus state.
	SetFocused(focused bool)

	// IsFocused returns true if the widget currently has keyboard focus.
	IsFocused() bool
}

PublicWidget is the stable public interface for all UI widgets in wayne.

PublicWidget provides a simplified, stable contract for application developers. All concrete widget types implement this interface.

Note: The interface uses single-value accessors (Width, Height) for gomobile compatibility. For Go-only code, concrete types also provide Bounds() (int, int) as a convenience method.

type ResourceManager

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

ResourceManager manages fonts and images for an application.

func (*ResourceManager) DefaultFont

func (rm *ResourceManager) DefaultFont() *Font

DefaultFont returns the embedded default font.

func (*ResourceManager) LoadFont

func (rm *ResourceManager) LoadFont(path string, size float64) (*Font, error)

LoadFont loads a font from the specified path at the given size.

Supported formats: TrueType (.ttf) and OpenType (.otf) fonts. Size is specified in points.

Returns ErrInvalidFontData if the file cannot be parsed as a valid font.

func (*ResourceManager) LoadImage

func (rm *ResourceManager) LoadImage(path string) (*Image, error)

LoadImage loads an image from the specified path.

Supported formats: PNG, JPEG, GIF (via standard library image decoders).

Returns an error if the file does not exist, is not accessible, or contains unsupported image data. Error messages include the file path for debugging.

func (*ResourceManager) LoadImageFromReader

func (rm *ResourceManager) LoadImageFromReader(r io.Reader, filenameHint string) (*Image, error)

LoadImageFromReader loads an image from an io.Reader.

Supported formats: PNG, JPEG, GIF. The filenameHint is used in error messages for better debugging context.

Returns ErrUnsupportedImageFormat for unsupported formats, or a descriptive error for malformed image data.

type Row

type Row struct {
	*Panel
}

Row is a convenience container that arranges children horizontally.

Row is equivalent to a Panel with FlowDirection set to FlowRow.

func NewRow

func NewRow() *Row

NewRow creates a new horizontal container.

Example

ExampleNewRow demonstrates creating a horizontal layout container.

package main

import (
	"fmt"

	"github.com/opd-ai/wayne"
)

func main() {
	row := wayne.NewRow()
	row.SetGap(5)
	row.SetAlign(wayne.AlignCenter)
	row.Add(wayne.NewButton("A", wayne.Size{Width: 30, Height: 10}))
	row.Add(wayne.NewButton("B", wayne.Size{Width: 30, Height: 10}))
	fmt.Printf("Row children: %d\n", len(row.Children()))
}
Output:
Row children: 2

type ScrollAxis

type ScrollAxis int

ScrollAxis represents the scroll direction.

const (
	// ScrollAxisVertical indicates vertical scrolling.
	ScrollAxisVertical ScrollAxis = iota
	// ScrollAxisHorizontal indicates horizontal scrolling.
	ScrollAxisHorizontal
)

type ScrollView

type ScrollView struct {
	BasePublicWidget
	// contains filtered or unexported fields
}

ScrollView is a scrollable container for overflow content.

Example:

scroll := wayne.NewScrollView(wayne.Size{Width: 100, Height: 80})
for i := 0; i < 50; i++ {
    scroll.Add(wayne.NewLabel(fmt.Sprintf("Item %d", i), wayne.Size{Width: 100, Height: 5}))
}

func NewScrollView

func NewScrollView(size Size) *ScrollView

NewScrollView creates a new scrollable container.

Example

ExampleNewScrollView demonstrates creating a scrollable container.

package main

import (
	"fmt"

	"github.com/opd-ai/wayne"
)

func main() {
	scroll := wayne.NewScrollView(wayne.Size{Width: 100, Height: 50})
	content := wayne.NewColumn()
	for i := 0; i < 20; i++ {
		content.Add(wayne.NewLabel(fmt.Sprintf("Item %d", i), wayne.Size{Width: 100, Height: 5}))
	}
	scroll.Add(content) // Add content to scroll view
	fmt.Printf("ScrollView created: %T\n", scroll)
}
Output:
ScrollView created: *wayne.ScrollView

func (*ScrollView) Add

func (s *ScrollView) Add(child PublicWidget)

Add appends a child widget to the scroll view.

func (*ScrollView) Children

func (s *ScrollView) Children() []PublicWidget

Children returns the scroll view's children.

func (*ScrollView) Draw

func (s *ScrollView) Draw(c Canvas)

Draw renders the scroll view and its visible children with clipping.

func (*ScrollView) HandleEvent

func (s *ScrollView) HandleEvent(evt Event) bool

HandleEvent processes scroll events.

func (*ScrollView) OnScroll

func (s *ScrollView) OnScroll(handler func(offset int))

OnScroll registers a callback invoked when the scroll offset changes.

func (*ScrollView) ScrollOffset

func (s *ScrollView) ScrollOffset() int

ScrollOffset returns the current scroll position in pixels.

func (*ScrollView) SetScrollOffset

func (s *ScrollView) SetScrollOffset(offset int)

SetScrollOffset sets the current scroll position in pixels.

func (*ScrollView) SetTheme

func (s *ScrollView) SetTheme(theme Theme)

SetTheme applies a theme to this scroll view.

type Size

type Size struct {
	Width  float64 // Width as percentage of parent (0-100)
	Height float64 // Height as percentage of parent (0-100)
}

Size represents percentage-based dimensions for a widget.

Width and Height are specified as percentages (0-100) of the parent container.

Example:

sidebar := wayne.NewPanel(wayne.Size{Width: 25, Height: 100}) // 25% wide, full height
content := wayne.NewPanel(wayne.Size{Width: 75, Height: 100}) // 75% wide, full height
Example

ExampleSize demonstrates the percentage-based size specification.

package main

import (
	"fmt"

	"github.com/opd-ai/wayne"
)

func main() {
	// Sizes are specified as percentages of parent container
	full := wayne.Size{Width: 100, Height: 100}  // Full width and height
	half := wayne.Size{Width: 50, Height: 50}    // Half width and height
	narrow := wayne.Size{Width: 20, Height: 100} // 20% width, full height
	fmt.Printf("Sizes: full=%v, half=%v, narrow=%v\n", full, half, narrow)
}
Output:
Sizes: full={100 100}, half={50 50}, narrow={20 100}

type Spacer

type Spacer struct {
	BasePublicWidget
	// contains filtered or unexported fields
}

Spacer is an invisible widget that consumes percentage space for layout.

Example:

row := wayne.NewRow()
row.Add(wayne.NewButton("Left", wayne.Size{Width: 20, Height: 10}))
row.Add(wayne.NewSpacer(wayne.Size{Width: 60, Height: 10}))
row.Add(wayne.NewButton("Right", wayne.Size{Width: 20, Height: 10}))

func NewSpacer

func NewSpacer(size Size) *Spacer

NewSpacer creates a new invisible spacer widget.

Example

ExampleNewSpacer demonstrates creating a flexible spacer widget.

package main

import (
	"fmt"

	"github.com/opd-ai/wayne"
)

func main() {
	row := wayne.NewRow()
	row.Add(wayne.NewLabel("Left", wayne.Size{Width: 20, Height: 10}))
	row.Add(wayne.NewSpacer(wayne.Size{Width: 60, Height: 10})) // Pushes content apart
	row.Add(wayne.NewLabel("Right", wayne.Size{Width: 20, Height: 10}))
	fmt.Printf("Row with spacer: %d children\n", len(row.Children()))
}
Output:
Row with spacer: 3 children

func (*Spacer) Draw

func (s *Spacer) Draw(_ Canvas)

Draw does nothing (spacers are invisible).

func (*Spacer) HandleEvent

func (s *Spacer) HandleEvent(_ Event) bool

HandleEvent does nothing for spacers.

type Stack

type Stack struct {
	*Panel
}

Stack is a layering container that places children on top of each other.

func NewStack

func NewStack() *Stack

NewStack creates a new layering container.

Example

ExampleNewStack demonstrates creating a stacked (overlay) layout.

package main

import (
	"fmt"

	"github.com/opd-ai/wayne"
)

func main() {
	stack := wayne.NewStack()
	stack.Add(wayne.NewLabel("Background", wayne.Size{Width: 100, Height: 100}))
	stack.Add(wayne.NewButton("Overlay", wayne.Size{Width: 50, Height: 10}))
	fmt.Printf("Stack children: %d\n", len(stack.Children()))
}
Output:
Stack children: 2

type StyleOverride

type StyleOverride struct {
	// Background overrides the background color if non-nil.
	Background *Color

	// Foreground overrides the foreground color if non-nil.
	Foreground *Color

	// Accent overrides the accent color if non-nil.
	Accent *Color

	// Border overrides the border color if non-nil.
	Border *Color

	// FontSize overrides the font size if non-nil.
	FontSize *float64

	// Padding overrides the padding if non-nil.
	Padding *int

	// Gap overrides the gap if non-nil.
	Gap *int

	// BorderWidth overrides the border width if non-nil.
	BorderWidth *int

	// BorderRadius overrides the border radius if non-nil.
	BorderRadius *int
}

StyleOverride provides per-widget visual customization.

Any field left as nil will inherit from the parent container's theme.

Example:

bg := wayne.RGB(40, 40, 60)
panel.SetStyle(wayne.StyleOverride{Background: &bg})

type TextInput

type TextInput struct {
	BasePublicWidget
	// contains filtered or unexported fields
}

TextInput is a single-line editable text field.

Example:

input := wayne.NewTextInput("Enter name...", wayne.Size{Width: 50, Height: 6})
input.OnChange(func(text string) {
    fmt.Println("Input:", text)
})
panel.Add(input)

func NewTextInput

func NewTextInput(placeholder string, size Size) *TextInput

NewTextInput creates a new text input field with placeholder text and size.

Example

ExampleNewTextInput demonstrates creating a text input field.

package main

import (
	"fmt"

	"github.com/opd-ai/wayne"
)

func main() {
	input := wayne.NewTextInput("Enter name...", wayne.Size{Width: 60, Height: 8})
	input.SetText("Default value")
	text := input.Text()
	fmt.Printf("Input text: %s\n", text)
}
Output:
Input text: Default value

func (*TextInput) CanTakeFocus

func (t *TextInput) CanTakeFocus() bool

CanTakeFocus returns true (text inputs can always receive focus).

func (*TextInput) Draw

func (t *TextInput) Draw(c Canvas)

Draw renders the text input to the canvas.

func (*TextInput) HandleEvent

func (t *TextInput) HandleEvent(evt Event) bool

HandleEvent processes keyboard and pointer events for text input.

func (*TextInput) OnChange

func (t *TextInput) OnChange(handler func(string))

OnChange registers a callback invoked when the text changes.

func (*TextInput) SetPlaceholder

func (t *TextInput) SetPlaceholder(placeholder string)

SetPlaceholder sets the placeholder text shown when the input is empty.

func (*TextInput) SetText

func (t *TextInput) SetText(text string)

SetText changes the input's text content.

func (*TextInput) SetTheme

func (t *TextInput) SetTheme(theme Theme)

SetTheme applies a theme to this text input.

func (*TextInput) Text

func (t *TextInput) Text() string

Text returns the current text content.

type Theme

type Theme struct {
	// Background is the primary background color.
	Background Color

	// Foreground is the primary text/foreground color.
	Foreground Color

	// Accent is the accent/highlight color for interactive elements.
	Accent Color

	// Border is the default border color.
	Border Color

	// FontSize is the base font size in pixels.
	FontSize float64

	// Padding is the default inner padding in pixels.
	Padding int

	// Gap is the default gap between sibling widgets in pixels.
	Gap int

	// BorderWidth is the default border width in pixels.
	BorderWidth int

	// BorderRadius is the default border radius for rounded corners in pixels.
	BorderRadius int

	// Scale is the HiDPI scale factor (1.0 = standard, 2.0 = retina).
	Scale float64
}

Theme defines the global visual appearance of the application.

A Theme specifies colors, fonts, spacing, and scale applied application-wide or per-widget. Widgets inherit theme from their parent container unless overridden with a StyleOverride.

Example:

app.SetTheme(wayne.DefaultDark())
app.SetTheme(wayne.HighContrast())

func DefaultDark

func DefaultDark() Theme

DefaultDark returns the built-in dark theme.

func DefaultLight

func DefaultLight() Theme

DefaultLight returns the built-in light theme.

func HighContrast

func HighContrast() Theme

HighContrast returns a high-contrast theme for accessibility.

type Themeable

type Themeable interface {
	// SetTheme applies a custom theme to this widget.
	SetTheme(Theme)
}

Themeable is the interface for widgets that support theme customization.

type TouchEvent

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

TouchEvent represents touch screen events.

func NewTouchEvent

func NewTouchEvent(phase TouchEventType, id int32, x, y float64) *TouchEvent

NewTouchEvent creates a new TouchEvent.

func (*TouchEvent) Consume

func (e *TouchEvent) Consume()

Consume marks this event as consumed, preventing further propagation.

func (*TouchEvent) Consumed

func (e *TouchEvent) Consumed() bool

Consumed returns true if this event has been consumed by a handler.

func (*TouchEvent) EventType

func (e *TouchEvent) EventType() TouchEventType

EventType returns the specific touch event type (began, moved, ended, cancelled).

func (*TouchEvent) ID

func (e *TouchEvent) ID() int32

ID returns the unique identifier for this touch point.

func (*TouchEvent) Phase

func (e *TouchEvent) Phase() TouchPhase

Phase returns the phase of this touch event.

func (*TouchEvent) Timestamp

func (e *TouchEvent) Timestamp() time.Time

Timestamp returns the time when the event was created.

func (*TouchEvent) TouchID

func (e *TouchEvent) TouchID() int32

TouchID returns the unique identifier for this touch point.

func (*TouchEvent) Type

func (e *TouchEvent) Type() EventType

Type returns the general event type (EventTypeTouch).

func (*TouchEvent) X

func (e *TouchEvent) X() float64

X returns the horizontal coordinate of the touch event.

func (*TouchEvent) Y

func (e *TouchEvent) Y() float64

Y returns the vertical coordinate of the touch event.

type TouchEventType

type TouchEventType int

TouchEventType specifies the type of touch event.

const (
	// TouchDown indicates a touch point was pressed.
	TouchDown TouchEventType = iota
	// TouchUp indicates a touch point was released.
	TouchUp
	// TouchMotion indicates a touch point moved.
	TouchMotion
	// TouchCancel indicates a touch sequence was cancelled.
	TouchCancel
)

type TouchPhase

type TouchPhase = TouchEventType

TouchPhase is an alias for TouchEventType for API surface compatibility.

type Widget deprecated

type Widget interface {
	// Contains returns true if the point (x, y) is inside the widget's bounds.
	Contains(x, y float64) bool

	// Children returns the widget's child widgets.
	Children() []Widget

	// HandlePointer processes a pointer event.
	HandlePointer(evt *PointerEvent)

	// HandleKey processes a keyboard event.
	HandleKey(evt *KeyEvent)

	// HandleTouch processes a touch event.
	HandleTouch(evt *TouchEvent)

	// SetFocused sets the widget's focus state.
	SetFocused(focused bool)

	// IsFocused returns true if the widget has keyboard focus.
	IsFocused() bool
}

Widget is a legacy interface preserved for backwards compatibility.

Deprecated: Use PublicWidget instead. This interface predates the unified event handling model. All concrete widget types in wayne implement PublicWidget, which uses a single HandleEvent(Event) method for all input types. This interface is retained for codebases that may have implemented it directly.

Migration guide:

// Old pattern (Widget interface):
type MyWidget struct { wayne.BaseWidget }
func (w *MyWidget) HandlePointer(evt *PointerEvent) { ... }
func (w *MyWidget) HandleKey(evt *KeyEvent) { ... }

// New pattern (PublicWidget interface):
type MyWidget struct { wayne.BasePublicWidget }
func (w *MyWidget) HandleEvent(evt Event) bool {
    switch e := evt.(type) {
    case *PointerEvent: ...
    case *KeyEvent: ...
    }
    return false
}

type Window

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

Window represents a UI window.

Since Ebitengine manages a single OS window, the primary Window corresponds to the Ebitengine window. Methods like SetTitle and Show delegate to Ebitengine.

func (*Window) Close

func (w *Window) Close()

Close closes the window. If this is the primary window, it quits the app.

func (*Window) SetRoot

func (w *Window) SetRoot(root PublicWidget)

SetRoot sets the root widget for this window.

func (*Window) SetTitle

func (w *Window) SetTitle(title string)

SetTitle sets the window title.

func (*Window) Show

func (w *Window) Show()

Show displays the window. For Ebitengine, this is a no-op because the window appears automatically when App.Run() is called.

type WindowConfig

type WindowConfig struct {
	// Title is the window title (default: "").
	Title string

	// Width is the initial window width in pixels (default: 800).
	Width int

	// Height is the initial window height in pixels (default: 600).
	Height int

	// MinWidth is the minimum window width in pixels.
	MinWidth int

	// MinHeight is the minimum window height in pixels.
	MinHeight int

	// MaxWidth is the maximum window width in pixels.
	MaxWidth int

	// MaxHeight is the maximum window height in pixels.
	MaxHeight int

	// Fullscreen indicates whether the window should start fullscreen.
	Fullscreen bool

	// Decorations controls window decorations (title bar, borders).
	// nil (default) = decorated window (default platform behavior)
	// true = force decorated window
	// false = borderless window (no title bar, borders)
	//
	// Note: On mobile platforms (Android, iOS), this setting has no effect
	// as Ebitengine does not support window decoration control on mobile.
	Decorations *bool
}

WindowConfig contains configuration options for creating a Window.

type WindowEvent

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

WindowEvent represents window state events.

func (*WindowEvent) Consume

func (e *WindowEvent) Consume()

Consume marks this event as consumed, preventing further propagation.

func (*WindowEvent) Consumed

func (e *WindowEvent) Consumed() bool

Consumed returns true if this event has been consumed by a handler.

func (*WindowEvent) EventType

func (e *WindowEvent) EventType() WindowEventType

EventType returns the specific window event type (resize, close, focus, etc.).

func (*WindowEvent) Height

func (e *WindowEvent) Height() int

Height returns the window height in pixels for resize events.

func (*WindowEvent) Scale

func (e *WindowEvent) Scale() float64

Scale returns the window scale factor for scale change events.

func (*WindowEvent) Timestamp

func (e *WindowEvent) Timestamp() time.Time

Timestamp returns the time when the event was created.

func (*WindowEvent) Type

func (e *WindowEvent) Type() EventType

Type returns the general event type (EventTypeWindow).

func (*WindowEvent) Width

func (e *WindowEvent) Width() int

Width returns the window width in pixels for resize events.

type WindowEventType

type WindowEventType int

WindowEventType specifies the type of window event.

const (
	// WindowResize indicates the window was resized.
	WindowResize WindowEventType = iota
	// WindowClose indicates the window close was requested.
	WindowClose
	// WindowFocus indicates the window gained focus.
	WindowFocus
	// WindowUnfocus indicates the window lost focus.
	WindowUnfocus
	// WindowScaleChange indicates the window's scale factor changed.
	WindowScaleChange
)

Directories

Path Synopsis
examples
form command
Example: form - A form application with text inputs, labels, and validation.
Example: form - A form application with text inputs, labels, and validation.
hello command
Example: hello - Minimal wayne application with a button and label.
Example: hello - Minimal wayne application with a button and label.
scrollview command
Example: scrollview - A scrollable list demonstration.
Example: scrollview - A scrollable list demonstration.

Jump to

Keyboard shortcuts

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