guigui

package module
v0.2.0-alpha Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2026 License: Apache-2.0 Imports: 29 Imported by: 2

README

Guigui (ぐいぐい)

An immediate-mode-inspired GUI framework for Go

[!CAUTION] This project is an alpha version, and everything may change in the future.

[!WARNING] Pull requests for new widgets or features are not accepted. Only small changes like typo fixes and bug fixes are considered. For new widgets or features, please file an issue or make your proposal in Discussion.

[!NOTE] AI is used in the development of this project, but all changes are reviewed by the committer before committing.

  • Compilable without C compilers
  • No HTML, CSS, or JavaScript required
  • Hi-DPI support for clear visuals on modern displays
  • Built-in internationalization (I18N) support for multiple languages
  • Efficient rendering with optimized draw calls for better performance
Light Mode Dark Mode
Light Mode Dark Mode
git clone https://github.com/guigui-gui/guigui.git
cd guigui
go run ./example/gallery

For AI agents

If you use an AI coding agent to write or modify Guigui code, point it at skills. The using-guigui skill there documents the widget lifecycle, layout, and conventions so the agent produces idiomatic Guigui code.

Guigui runs on Ebitengine, so to run, test, or screenshot a Guigui app without a window, also point the agent at Ebitengine's run-ebitengine-app-headless skill. It drives an app headlessly, injects input, and reads back rendered frames so the agent can verify behavior end to end.

The link above points at Ebitengine's main branch. The skill documents the APIs of the version it ships with, so use the tag or branch matching the Ebitengine version your project depends on.

Documentation

Overview

Package guigui provides a GUI framework for Go built on top of Ebitengine.

Widget lifecycle

The core of guigui is the Widget interface. All UI components implement this interface by embedding DefaultWidget in their structs.

The framework guarantees the following about a few of the widget methods:

  • Widget.Build constructs the child widget tree. When Build is called, neither the widget's own bounds nor its parent's bounds are determined yet (so WidgetBounds is not passed as an argument), and the child tree is not determined yet either.
  • Widget.Layout positions and sizes children. When Layout is called, the widget's own bounds and its parent's bounds are determined, but its children's bounds are not yet determined.
  • Widget.Tick is invoked at the application's TPS (60 times per second by default, or whatever TPS the user has configured).
  • Widget.HandlePointingInput is invoked in post-order (children before their parent), per layer from top to bottom. This lets an inner or higher-layer widget consume a pointing event before its ancestors or lower layers see it.
  • Widget.HandleButtonInput is invoked with the same post-order, top-to-bottom-layer traversal, but only on a subset of widgets: roughly, a widget that is focused, has a focused ancestor or descendant, or is itself button-input-receptive (see Context.SetButtonInputReceptive). Disabled or hidden widgets are skipped. See Widget.HandleButtonInput for the exact conditions.
  • Widget.Draw is invoked in pre-order (parent before its children), per layer from bottom to top, so children and higher layers are rendered on top of their parents and lower layers.

All other aspects — such as when and how often each method is called — are implementation details that the framework may change.

Running an application

Use Run to start an application with a root widget:

type Root struct {
	guigui.DefaultWidget
	// ...
}

func main() {
	if err := guigui.Run(&Root{}, &guigui.RunOptions{
		Title: "My App",
	}); err != nil {
		log.Fatal(err)
	}
}

Environment variables

The environment variable GUIGUI_COLOR_MODE specifies the preferred color mode. Its value is either light or dark. Context.SetPreferredColorMode overrides it.

The environment variable GUIGUI_LOCALES specifies the locales. Its value is a comma-separated list of BCP 47 language tags. The effective locales are determined by the app locales, GUIGUI_LOCALES, and the system locales, in that priority order.

The environment variable GUIGUI_KEY_BINDING_MODE specifies the preferred key binding mode. Its value is either command, control-default, or control-emacs. Context.SetPreferredKeyBindingMode overrides it.

Debugging

The environment variable GUIGUI_DEBUG enables debugging features. Its value is a comma-separated list of these options:

  • showrenderingregions: visualizes the regions that are redrawn.
  • showbuildlogs: logs why the widget tree is rebuilt.
  • showinputlogs: logs which widget handled an input.
  • devicescale=<float>: uses the given device scale factor instead of the monitor's.
  • emulateclipboard: replaces the system clipboard with an in-process one, so that copying and pasting leave the system clipboard untouched. The environment variable GUIGUI_DEBUG_CLIPBOARD_TEXT gives the emulated clipboard its initial text.

These options are for debugging and can change at any time.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DispatchEvent

func DispatchEvent(widget Widget, eventKey EventKey, args ...any) ([]any, bool)

DispatchEvent invokes the event handler registered for the given event key on the widget. The handler must have been set via SetEventHandler during the current build phase, as all handlers are reset before each build. args are passed to the handler after the *Context argument. It returns the handler's return values and true if a handler was found, or nil and false otherwise.

func DispatchEventLazy

func DispatchEventLazy(widget Widget, eventKey EventKey, argsFunc any) ([]any, bool)

DispatchEventLazy is like DispatchEvent but defers argument construction. argsFunc must be a func with no parameters whose return values become the handler arguments (after the *Context). It is invoked only when a handler is registered for eventKey, so callers can skip expensive work (such as materializing a large string) when no listener is attached.

func OnFocusChanged

func OnFocusChanged(widget Widget, onfocus func(context *Context, focused bool))

TODO: For focus delegation, create a new function (#340).

func RequestRebuild

func RequestRebuild()

RequestRebuild requests a rebuild of the entire widget tree on the next frame. A rebuild re-runs Widget.Build across the tree but does not by itself repaint anything; to refresh a widget's pixels, call RequestRedraw.

func RequestRedraw

func RequestRedraw(widget Widget)

RequestRedraw requests to redraw the given widget. RequestRedraw causes Draw invocations without rebuilding the widget tree. If the tree, content, or layout changed, call RequestRebuild as well.

func Run

func Run(root Widget, options *RunOptions) error

func RunWithCustomFunc

func RunWithCustomFunc(root Widget, options *RunOptions, f func(game ebiten.Game, options *ebiten.RunGameOptions) error) error

func SetEventHandler

func SetEventHandler(widget Widget, eventKey EventKey, handler any)

SetEventHandler registers an event handler for the given event key on the widget. At most one handler can be registered per event key on a widget. If a handler is already registered for the same key, it is replaced. All event handlers are reset before the build phase starts, so SetEventHandler must be called during every Build to keep the handler active.

Types

type ChildAdder

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

func (*ChildAdder) AddWidget

func (c *ChildAdder) AddWidget(widget Widget)

type ChildLayouter

type ChildLayouter struct {
}

func (*ChildLayouter) LayoutWidget

func (c *ChildLayouter) LayoutWidget(widget Widget, bounds image.Rectangle)

type Constraints

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

Constraints specifies at most one fixed dimension for measuring a widget. The zero value leaves both dimensions unconstrained.

func FixedHeightConstraints

func FixedHeightConstraints(h int) Constraints

FixedHeightConstraints returns constraints with a fixed height.

func FixedWidthConstraints

func FixedWidthConstraints(w int) Constraints

FixedWidthConstraints returns constraints with a fixed width.

func (*Constraints) FixedHeight

func (c *Constraints) FixedHeight() (int, bool)

FixedHeight returns the fixed height, if one is specified.

func (*Constraints) FixedWidth

func (c *Constraints) FixedWidth() (int, bool)

FixedWidth returns the fixed width, if one is specified.

type Context

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

func (*Context) AppBounds

func (c *Context) AppBounds() image.Rectangle

AppBounds returns the bounds of the application.

func (*Context) AppScale

func (c *Context) AppScale() float64

AppScale returns the application scale factor set by Context.SetAppScale. The default value is 1.

func (*Context) AppendAppLocales

func (c *Context) AppendAppLocales(locales []language.Tag) []language.Tag

AppendAppLocales appends the app locales set by Context.SetAppLocales to the given slice and returns the result.

func (*Context) AppendLocales

func (c *Context) AppendLocales(locales []language.Tag) []language.Tag

AppendLocales appends all effective locales to the given slice and returns the result. The effective locales are determined by the app locales, the environment variable GUIGUI_LOCALES, and the system locales, in that priority order.

func (*Context) ColorMode

func (c *Context) ColorMode() ebiten.ColorMode

ColorMode returns the resolved color mode.

ColorMode never returns ebiten.ColorModeUnknown.

func (*Context) DelegateFocus

func (c *Context) DelegateFocus(widget Widget, delegate Widget)

DelegateFocus delegates the focus to another widget.

func (*Context) DeviceScale

func (c *Context) DeviceScale() float64

DeviceScale returns the device scale factor.

func (*Context) Env

func (c *Context) Env(widget Widget, key EnvKey) (any, bool)

Env returns an environment value for the given key by walking up the widget tree. It calls Widget.Env on the given widget first. If the second return value is false, it tries the parent widget, repeating recursively up to the root widget.

func (*Context) FirstLocale

func (c *Context) FirstLocale() language.Tag

FirstLocale returns the first effective locale. The effective locales are determined by the app locales, the environment variable GUIGUI_LOCALES, and the system locales, in that priority order. If no locales are available, the zero value of language.Tag is returned.

func (*Context) IsButtonInputReceptive

func (c *Context) IsButtonInputReceptive(widget Widget) bool

IsButtonInputReceptive reports whether the widget receives button input events even when it is not focused.

func (*Context) IsEnabled

func (c *Context) IsEnabled(widget Widget) bool

IsEnabled reports whether the widget is enabled.

func (*Context) IsFocused

func (c *Context) IsFocused(widget Widget) bool

IsFocused reports whether the widget is focused.

func (*Context) IsFocusedOrHasFocusedDescendant

func (c *Context) IsFocusedOrHasFocusedDescendant(widget Widget) bool

IsFocusedOrHasFocusedDescendant reports whether the widget is focused or has a focused descendant.

IsFocusedOrHasFocusedDescendant must not be called in Widget.Build implementations because it depends on the finished widget tree.

func (*Context) IsVisible

func (c *Context) IsVisible(widget Widget) bool

IsVisible reports whether the widget is visible.

func (*Context) KeyBindingMode

func (c *Context) KeyBindingMode() KeyBindingMode

KeyBindingMode returns the resolved key binding mode. The effective mode is determined by the mode set by Context.SetPreferredKeyBindingMode, the environment variable GUIGUI_KEY_BINDING_MODE, and the system, in that priority order.

KeyBindingMode never returns KeyBindingModeUnknown.

func (*Context) Opacity

func (c *Context) Opacity(widget Widget) float64

Opacity returns the opacity of the widget. The value is in the range [0, 1], where 0 is fully transparent and 1 is fully opaque.

func (*Context) Passthrough

func (c *Context) Passthrough(widget Widget) bool

Passthrough reports whether the widget is in passthrough mode. A passthrough widget does not receive any input events, but its descendants do.

func (*Context) PreferredColorMode

func (c *Context) PreferredColorMode() ebiten.ColorMode

PreferredColorMode returns the color mode set by SetPreferredColorMode.

PreferredColorMode might return ebiten.ColorModeUnknown if the color mode is not set.

func (*Context) PreferredKeyBindingMode

func (c *Context) PreferredKeyBindingMode() KeyBindingMode

PreferredKeyBindingMode returns the key binding mode set by SetPreferredKeyBindingMode.

PreferredKeyBindingMode might return KeyBindingModeUnknown if the mode is not set.

func (*Context) Scale

func (c *Context) Scale() float64

Scale returns the overall scale factor used for rendering. Scale is the product of Context.DeviceScale and Context.AppScale.

func (*Context) SetAppLocales

func (c *Context) SetAppLocales(locales []language.Tag)

SetAppLocales sets the application-level locales. These take the highest priority when resolving locales.

func (*Context) SetAppScale

func (c *Context) SetAppScale(scale float64)

SetAppScale sets the application scale factor.

func (*Context) SetButtonInputReceptive

func (c *Context) SetButtonInputReceptive(widget Widget, receptive bool)

SetButtonInputReceptive sets whether the widget receives button input events even when it is not focused. The effect does not extend to the widget's descendants, which continue to follow normal focus rules. For example, a container can handle a single global key, such as closing on Escape, while its subtree still obeys focus.

The widget receives button input events via Widget.HandleButtonInput. Unlike focus, ancestors of a button-input-receptive widget do not receive button input events themselves; the framework only traverses through them to reach the receptive widget.

func (*Context) SetClipChildren

func (c *Context) SetClipChildren(widget Widget, clip bool)

SetClipChildren sets whether the children on the same layer are clipped by the widget's bounds. The default value is false.

If the child widget is on a different layer from the parent, it is not clipped. Note that a widget layer can be controlled by LayerWidget.

func (*Context) SetEnabled

func (c *Context) SetEnabled(widget Widget, enabled bool)

SetEnabled sets whether the widget is enabled. A disabled widget and its descendants do not receive any input events.

func (*Context) SetFocused

func (c *Context) SetFocused(widget Widget, focused bool)

SetFocused sets or removes the focus on the widget.

When a widget is focused, both the widget and all its ancestors receive button input events via Widget.HandleButtonInput. Only one widget can be focused at a time.

func (*Context) SetOpacity

func (c *Context) SetOpacity(widget Widget, opacity float64)

SetOpacity sets the opacity of the widget. The value is clamped to the range [0, 1].

func (*Context) SetPassthrough

func (c *Context) SetPassthrough(widget Widget, passthrough bool)

SetPassthrough sets whether the widget is in passthrough mode. A passthrough widget does not receive any input events, but its descendants do.

func (*Context) SetPreferredColorMode

func (c *Context) SetPreferredColorMode(mode ebiten.ColorMode)

SetPreferredColorMode sets the preferred color mode.

If mode is ebiten.ColorModeUnknown, SetPreferredColorMode specifies the default system color mode.

func (*Context) SetPreferredKeyBindingMode

func (c *Context) SetPreferredKeyBindingMode(mode KeyBindingMode)

SetPreferredKeyBindingMode sets the preferred key binding mode.

If mode is KeyBindingModeUnknown, SetPreferredKeyBindingMode specifies the default mode.

func (*Context) SetVisible

func (c *Context) SetVisible(widget Widget, visible bool)

SetVisible sets whether the widget is visible. An invisible widget and its descendants do not receive any events and are not rendered.

func (*Context) SetWindowSize

func (c *Context) SetWindowSize(width, height int)

SetWindowSize sets the window size.

func (*Context) SetWindowSizeLimits

func (c *Context) SetWindowSizeLimits(minw, minh, maxw, maxh int)

SetWindowSizeLimits sets the size limits of the window. A negative value indicates the size is not limited.

func (*Context) SetWindowTitle

func (c *Context) SetWindowTitle(title string)

SetWindowTitle sets the window title.

type DefaultWidget

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

func (*DefaultWidget) Build

func (*DefaultWidget) Build(context *Context, adder *ChildAdder) error

func (*DefaultWidget) CursorShape

func (*DefaultWidget) CursorShape(context *Context, widgetBounds *WidgetBounds) (ebiten.CursorShapeType, bool)

func (*DefaultWidget) Draw

func (*DefaultWidget) Draw(context *Context, widgetBounds *WidgetBounds, dst *ebiten.Image)

func (*DefaultWidget) Env

func (*DefaultWidget) Env(context *Context, key EnvKey, source *EnvSource) (any, bool)

func (*DefaultWidget) HandleButtonInput

func (*DefaultWidget) HandleButtonInput(context *Context, widgetBounds *WidgetBounds) HandleInputResult

func (*DefaultWidget) HandlePointingInput

func (*DefaultWidget) HandlePointingInput(context *Context, widgetBounds *WidgetBounds) HandleInputResult

func (*DefaultWidget) Layout

func (*DefaultWidget) Layout(context *Context, widgetBounds *WidgetBounds, layouter *ChildLayouter)

func (*DefaultWidget) Measure

func (d *DefaultWidget) Measure(context *Context, constraints Constraints) image.Point

func (*DefaultWidget) Tick

func (*DefaultWidget) Tick(context *Context, widgetBounds *WidgetBounds) error

func (*DefaultWidget) WriteStateKey

func (*DefaultWidget) WriteStateKey(context *Context, w *StateKeyWriter)

type EnvKey

type EnvKey uniqueKey

EnvKey is a unique identifier for an environment value.

func GenerateEnvKey

func GenerateEnvKey() EnvKey

GenerateEnvKey generates a new EnvKey.

type EnvSource

type EnvSource struct {
	// Origin is the widget that originally called [Context.Env].
	Origin Widget

	// Child is the direct child of the current widget in the walk path.
	// Child is nil when the current widget is the Origin itself.
	Child Widget
}

EnvSource provides information about the origin of an Context.Env call.

type EventKey

type EventKey uniqueKey

EventKey is a unique identifier for an event.

func GenerateEventKey

func GenerateEventKey() EventKey

GenerateEventKey generates a new EventKey.

type HandleInputResult

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

func AbortHandlingInputByWidget

func AbortHandlingInputByWidget(widget Widget) HandleInputResult

func HandleInputByWidget

func HandleInputByWidget(widget Widget) HandleInputResult

func (HandleInputResult) IsHandled

func (r HandleInputResult) IsHandled() bool

IsHandled reports whether the input was handled by a widget.

type KeyBindingMode

type KeyBindingMode int

KeyBindingMode represents the convention that application keyboard shortcuts follow.

const (
	// KeyBindingModeUnknown means that the mode is not specified.
	KeyBindingModeUnknown KeyBindingMode = KeyBindingMode(keybindingmode.Unknown)

	// KeyBindingModeCommand is the convention where Command carries application shortcuts,
	// used on macOS and iOS, including web browsers on them.
	KeyBindingModeCommand KeyBindingMode = KeyBindingMode(keybindingmode.Command)

	// KeyBindingModeControlDefault is the convention where Control carries application shortcuts,
	// used on Windows, Linux, and the other platforms.
	KeyBindingModeControlDefault KeyBindingMode = KeyBindingMode(keybindingmode.ControlDefault)

	// KeyBindingModeControlEmacs is [KeyBindingModeControlDefault] with the Emacs text editing keymap,
	// as enabled by the GTK Emacs key theme.
	KeyBindingModeControlEmacs KeyBindingMode = KeyBindingMode(keybindingmode.ControlEmacs)
)

func (KeyBindingMode) ShortcutModifierKey

func (k KeyBindingMode) ShortcutModifierKey() ebiten.Key

ShortcutModifierKey returns the modifier key that carries application shortcuts, either ebiten.KeyMeta or ebiten.KeyControl.

The returned value is not meaningful for KeyBindingModeUnknown.

func (KeyBindingMode) UsesEmacsKeymap

func (k KeyBindingMode) UsesEmacsKeymap() bool

UsesEmacsKeymap reports whether the Emacs text editing keymap is in effect.

The returned value is not meaningful for KeyBindingModeUnknown.

type LayerWidget

type LayerWidget[T Widget] struct {
	DefaultWidget
	// contains filtered or unexported fields
}

LayerWidget is a widget that can be in a different layer from its parent. LayerWidget is on the same layer as its parent by default.

func (*LayerWidget[T]) BringToFrontLayer

func (l *LayerWidget[T]) BringToFrontLayer(context *Context)

BringToFrontLayer brings the widget to the front layer. After this call, the widget will be in a different layer from its parent.

Lyaers affect the order of rendering and input handling. Usually, a widget's visible bounds are constrained by its parent's visible bounds, which means a widget cannot be rendered outside of its parent's visible bounds. If a widget is in a different layer from its parent, the widget can be rendered regardless of its parent's visible bounds.

Input is handled in the order of layers from top to bottom. Also, layers affect the result of [WidgetBounds.IsCursorHitAt].

func (*LayerWidget[T]) Build

func (l *LayerWidget[T]) Build(context *Context, adder *ChildAdder) error

Build implements Widget.Build.

func (*LayerWidget[T]) Layout

func (l *LayerWidget[T]) Layout(context *Context, widgetBounds *WidgetBounds, layouter *ChildLayouter)

Layout implements Widget.Layout.

func (*LayerWidget[T]) Measure

func (l *LayerWidget[T]) Measure(context *Context, constraints Constraints) image.Point

Measure implements Widget.Measure.

func (*LayerWidget[T]) Widget

func (l *LayerWidget[T]) Widget() T

Widget returns the content widget.

type LayoutDirection

type LayoutDirection int

LayoutDirection is the direction of the layout.

const (
	// LayoutDirectionHorizontal arranges widgets horizontally.
	LayoutDirectionHorizontal LayoutDirection = iota
	// LayoutDirectionVertical arranges widgets vertically.
	LayoutDirectionVertical
)

type LinearLayout

type LinearLayout struct {
	// Direction is the direction of the layout.
	Direction LayoutDirection

	// Items is the list of items to layout.
	Items []LinearLayoutItem

	// Gap is the gap in pixels between items.
	Gap int

	// Padding is the padding around the layout.
	Padding Padding
}

LinearLayout arranges widgets in a linear fashion.

func (LinearLayout) AppendItemBounds

func (l LinearLayout) AppendItemBounds(boundsArr []image.Rectangle, context *Context, bounds image.Rectangle) []image.Rectangle

func (LinearLayout) ItemBoundsAt

func (l LinearLayout) ItemBoundsAt(index int, context *Context, bounds image.Rectangle) image.Rectangle

ItemBoundsAt returns the bounds for the item at the given index.

func (LinearLayout) LayoutWidgets

func (l LinearLayout) LayoutWidgets(context *Context, bounds image.Rectangle, layouter WidgetLayouter)

func (LinearLayout) Measure

func (l LinearLayout) Measure(context *Context, constraints Constraints) image.Point

type LinearLayoutItem

type LinearLayoutItem struct {
	Widget Widget
	Size   Size
	Layout WidgetsLayouter
}

type Padding

type Padding struct {
	// Start is the left padding in pixels. RTL mirroring is not yet supported.
	Start int

	// Top is the padding in pixels at the top of the layout.
	Top int

	// End is the right padding in pixels. RTL mirroring is not yet supported.
	End int

	// Bottom is the padding in pixels at the bottom of the layout.
	Bottom int
}

Padding represents the padding around a layout.

type RunOptions

type RunOptions struct {
	Title          string
	WindowSize     image.Point
	WindowMinSize  image.Point
	WindowMaxSize  image.Point
	WindowFloating bool
	AppScale       float64

	// ApplePressAndHoldDelegated indicates whether RunGameOptions.ApplePressAndHoldEnabled controls
	// the macOS press-and-hold feature. When false, the feature is enabled regardless of
	// RunGameOptions.
	ApplePressAndHoldDelegated bool

	RunGameOptions *ebiten.RunGameOptions
}

type Size

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

Size represents the size of a layout item.

func FixedSize

func FixedSize(value int) Size

FixedSize represents a fixed size in pixels.

func FlexibleSize

func FlexibleSize(value int) Size

FlexibleSize represents a flexible size. The size is distributed proportionally to the values of the flexible items.

type StateKeyWriter

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

StateKeyWriter accumulates a hash of a widget's state. Widgets write their state via the Write* methods in Widget.WriteStateKey; the framework reads the resulting hash after the call.

StateKeyWriter implements io.Writer as an escape hatch for variable-length byte content.

func (*StateKeyWriter) Write

func (w *StateKeyWriter) Write(p []byte) (int, error)

Write implements io.Writer.

Write never returns a non-nil error.

func (*StateKeyWriter) WriteBigInt

func (w *StateKeyWriter) WriteBigInt(v *big.Int)

WriteBigInt writes the value of a big.Int into the writer.

func (*StateKeyWriter) WriteBool

func (w *StateKeyWriter) WriteBool(v bool)

WriteBool writes a bool into the writer.

func (*StateKeyWriter) WriteFloat32

func (w *StateKeyWriter) WriteFloat32(v float32)

WriteFloat32 writes a float32 into the writer.

func (*StateKeyWriter) WriteFloat64

func (w *StateKeyWriter) WriteFloat64(v float64)

WriteFloat64 writes a float64 into the writer.

func (*StateKeyWriter) WriteInt

func (w *StateKeyWriter) WriteInt(v int)

WriteInt writes an int into the writer using its native width (4 bytes on 32-bit platforms, 8 bytes on 64-bit).

func (*StateKeyWriter) WriteInt8

func (w *StateKeyWriter) WriteInt8(v int8)

WriteInt8 writes an int8 into the writer.

func (*StateKeyWriter) WriteInt16

func (w *StateKeyWriter) WriteInt16(v int16)

WriteInt16 writes an int16 into the writer.

func (*StateKeyWriter) WriteInt32

func (w *StateKeyWriter) WriteInt32(v int32)

WriteInt32 writes an int32 into the writer.

func (*StateKeyWriter) WriteInt64

func (w *StateKeyWriter) WriteInt64(v int64)

WriteInt64 writes an int64 into the writer.

func (*StateKeyWriter) WriteString

func (w *StateKeyWriter) WriteString(s string)

WriteString writes a string into the writer. The length is included so that concatenations hash distinctly (e.g. "ab"+"cd" vs "abc"+"d").

func (*StateKeyWriter) WriteUint

func (w *StateKeyWriter) WriteUint(v uint)

WriteUint writes a uint into the writer using its native width (4 bytes on 32-bit platforms, 8 bytes on 64-bit).

func (*StateKeyWriter) WriteUint8

func (w *StateKeyWriter) WriteUint8(v uint8)

WriteUint8 writes a uint8 into the writer.

func (*StateKeyWriter) WriteUint16

func (w *StateKeyWriter) WriteUint16(v uint16)

WriteUint16 writes a uint16 into the writer.

func (*StateKeyWriter) WriteUint32

func (w *StateKeyWriter) WriteUint32(v uint32)

WriteUint32 writes a uint32 into the writer.

func (*StateKeyWriter) WriteUint64

func (w *StateKeyWriter) WriteUint64(v uint64)

WriteUint64 writes a uint64 into the writer.

func (*StateKeyWriter) WriteWidget

func (w *StateKeyWriter) WriteWidget(widget Widget)

WriteWidget writes the identity of a Widget into the writer. A nil widget hashes to zero.

type Widget

type Widget interface {
	// Env returns an environment value associated with the widget for the given key.
	// [Context.Env] calls this method on the given widget first. If the second return value is false,
	// it tries the parent widget, repeating recursively up to the root widget.
	// source provides information about the origin of the [Context.Env] call.
	Env(context *Context, key EnvKey, source *EnvSource) (any, bool)

	// Build constructs the widget's child widget tree.
	// Use adder to add child widgets that this widget contains.
	// Build is called whenever the widget tree needs to be reconstructed.
	Build(context *Context, adder *ChildAdder) error

	// Layout positions and sizes the widget's children within the widget's bounds.
	// Use layouter to set the bounds of each child widget added in Build.
	Layout(context *Context, widgetBounds *WidgetBounds, layouter *ChildLayouter)

	// HandlePointingInput handles mouse or touch input events for the widget.
	// widgetBounds provides the widget's position and hit-testing information.
	// It is skipped entirely when no relevant pointing input is active.
	HandlePointingInput(context *Context, widgetBounds *WidgetBounds) HandleInputResult

	// HandleButtonInput handles keyboard and gamepad button input events for the widget.
	// widgetBounds provides the widget's position and hit-testing information.
	// It is skipped entirely when no buttons are pressed.
	//
	// HandleButtonInput is called when any of the following conditions is met:
	//   - The widget is focused or has a focused descendant.
	//   - The widget is button-input-receptive (see [Context.SetButtonInputReceptive]).
	//   - An ancestor of the widget is focused.
	//
	// When a widget is only an ancestor of a button-input-receptive widget
	// (but is not itself focused or receptive), the framework traverses into its
	// children to reach the receptive widget, but does not call HandleButtonInput
	// on the ancestor itself.
	HandleButtonInput(context *Context, widgetBounds *WidgetBounds) HandleInputResult

	// Tick is called every tick to update the widget's state.
	// Use this for animations, timers, or other per-tick updates.
	Tick(context *Context, widgetBounds *WidgetBounds) error

	// CursorShape returns the cursor shape to display when the cursor is over this widget.
	// The bool return value indicates whether the widget specifies a cursor shape.
	// If false is returned, the parent widget's cursor shape is used.
	CursorShape(context *Context, widgetBounds *WidgetBounds) (ebiten.CursorShapeType, bool)

	// Draw renders the widget onto dst.
	// dst is a SubImage clipped to the widget's bounds.
	Draw(context *Context, widgetBounds *WidgetBounds, dst *ebiten.Image)

	// Measure returns the preferred size of the widget given the constraints.
	// The returned value is advisory; the parent performing layout is not obligated to use it.
	// The constraints may specify a fixed width or a fixed height that the widget should respect.
	Measure(context *Context, constraints Constraints) image.Point

	// WriteStateKey writes a summary of the widget state relevant to rebuilding
	// and rendering the tree into w. The framework hashes the summary after each
	// [Widget.Build] and compares it at later checkpoints (after input handling
	// and [Widget.Tick]); when the hash changes, the framework requests a rebuild
	// automatically, so simple setters do not need to call [RequestRebuild] for
	// fields included here.
	//
	// Write nothing to opt out; widgets that opt out must continue to call
	// [RequestRebuild] explicitly for state that warrants a rebuild.
	WriteStateKey(context *Context, w *StateKeyWriter)
	// contains filtered or unexported methods
}

Widget is the interface that all UI components must implement. Implementations must embed DefaultWidget, as it is the only way to satisfy the unexported widgetState method in this interface.

A Widget implementation should work with its zero value. In Go, the zero value of a variable is the default value (0 for numbers, false for booleans, "" for strings, nil for pointers, etc.). This means that the default state of a widget should be reasonable without any explicit initialization.

type WidgetBounds

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

WidgetBounds provides position and hit-testing information for a widget. It is passed to widget methods such as Widget.Layout, Widget.Draw, and input handlers.

func (*WidgetBounds) Bounds

func (w *WidgetBounds) Bounds() image.Rectangle

Bounds returns the widget's bounding rectangle in screen coordinates.

func (*WidgetBounds) IsHitAt

func (w *WidgetBounds) IsHitAt(point image.Point) bool

IsHitAt reports whether the given point, in screen coordinates, is over this widget and no higher-layer widget is obscuring it at that point.

func (*WidgetBounds) IsHitAtCursor

func (w *WidgetBounds) IsHitAtCursor() bool

IsHitAtCursor reports whether the cursor is over this widget and no higher-layer widget is obscuring it at the cursor position.

func (*WidgetBounds) VisibleBounds

func (w *WidgetBounds) VisibleBounds() image.Rectangle

VisibleBounds returns the portion of the widget's bounds that is actually visible on screen. This is the intersection of the widget's bounds with all ancestor clipping regions.

type WidgetLayouter

type WidgetLayouter interface {
	// LayoutWidget lays out the given widget in the given bounds.
	LayoutWidget(widget Widget, bounds image.Rectangle)
}

WidgetLayouter is an interface for laying out a single widget.

type WidgetSlice

type WidgetSlice[T Widget] struct {
	// contains filtered or unexported fields
}

WidgetSlice is a collection of widgets.

As Widget implementation (DefaultWidget) must not be copied by value, a plain slice of widgets is very risky to use. Use this instead.

func (*WidgetSlice[T]) All

func (w *WidgetSlice[T]) All() iter.Seq2[int, T]

All returns an iterator over index-widget pairs in the slice.

func (*WidgetSlice[T]) At

func (w *WidgetSlice[T]) At(index int) T

At returns the widget at the specified index.

func (*WidgetSlice[T]) Len

func (w *WidgetSlice[T]) Len() int

Len returns the number of widgets.

func (*WidgetSlice[T]) SetLen

func (w *WidgetSlice[T]) SetLen(l int)

SetLen sets the length of the slice.

If the length is increased, the new elements are zero-cleared values. The existing elements are kept.

If the length is decreased, the elements are dropped. The remaining elements are kept.

type WidgetWithPadding

type WidgetWithPadding[T Widget] struct {
	DefaultWidget
	// contains filtered or unexported fields
}

func (*WidgetWithPadding[T]) Build

func (w *WidgetWithPadding[T]) Build(context *Context, adder *ChildAdder) error

func (*WidgetWithPadding[T]) Layout

func (w *WidgetWithPadding[T]) Layout(context *Context, widgetBounds *WidgetBounds, layouter *ChildLayouter)

func (*WidgetWithPadding[T]) Measure

func (w *WidgetWithPadding[T]) Measure(context *Context, constraints Constraints) image.Point

func (*WidgetWithPadding[T]) SetPadding

func (w *WidgetWithPadding[T]) SetPadding(padding Padding)

func (*WidgetWithPadding[T]) Widget

func (w *WidgetWithPadding[T]) Widget() T

type WidgetWithSize

type WidgetWithSize[T Widget] struct {
	DefaultWidget
	// contains filtered or unexported fields
}

func (*WidgetWithSize[T]) Build

func (w *WidgetWithSize[T]) Build(context *Context, adder *ChildAdder) error

func (*WidgetWithSize[T]) Layout

func (w *WidgetWithSize[T]) Layout(context *Context, widgetBounds *WidgetBounds, layouter *ChildLayouter)

func (*WidgetWithSize[T]) Measure

func (w *WidgetWithSize[T]) Measure(context *Context, constraints Constraints) image.Point

func (*WidgetWithSize[T]) SetFixedHeight

func (w *WidgetWithSize[T]) SetFixedHeight(height int)

func (*WidgetWithSize[T]) SetFixedSize

func (w *WidgetWithSize[T]) SetFixedSize(size image.Point)

func (*WidgetWithSize[T]) SetFixedWidth

func (w *WidgetWithSize[T]) SetFixedWidth(width int)

func (*WidgetWithSize[T]) SetIntrinsicSize

func (w *WidgetWithSize[T]) SetIntrinsicSize()

func (*WidgetWithSize[T]) SetMeasureFunc

func (w *WidgetWithSize[T]) SetMeasureFunc(f func(context *Context, constraints Constraints) image.Point)

func (*WidgetWithSize[T]) Widget

func (w *WidgetWithSize[T]) Widget() T

type WidgetsLayouter

type WidgetsLayouter interface {
	// LayoutWidgets lays out the given widgets in the given bounds.
	LayoutWidgets(context *Context, bounds image.Rectangle, layouter WidgetLayouter)

	// Measure measures the size of the layout.
	Measure(context *Context, constraints Constraints) image.Point
}

WidgetsLayouter is an interface for laying out multiple widgets.

Directories

Path Synopsis
internal/chunk
Package chunk places cache-friendly boundaries within a single logical line of text.
Package chunk places cache-friendly boundaries within a single logical line of text.
internal/piecetable
Package piecetable provides an editable text buffer with undo/redo support.
Package piecetable provides an editable text buffer with undo/redo support.
internal/textstyle
Package textstyle provides the attributed-run model for ranged text styling: a set of style overrides laid over byte ranges of a single text value.
Package textstyle provides the attributed-run model for ranged text styling: a set of style overrides laid over byte ranges of a single text value.
internal/textwidget
Package textwidget provides the theme-free core of the basicwidget text widgets: the editable Text widget and the input helpers it is built on.
Package textwidget provides the theme-free core of the basicwidget text widgets: the editable Text widget and the input helpers it is built on.
Package clipboard provides access to the system clipboard.
Package clipboard provides access to the system clipboard.
Package ebitenginewidget provides a Guigui widget that hosts a separate Ebitengine application.
Package ebitenginewidget provides a Guigui widget that hosts a separate Ebitengine application.
example
biglist command
calc command
codeeditor command
codeeditor/internal/highlight
Package highlight maps Go source code to syntax-highlighted byte ranges.
Package highlight maps Go source code to syntax-highlighted byte ranges.
counter command
drawer command
ebitengine command
expander command
font command
gallery command
gridlayout command
imageclipboard command
internal/texteditor
Package texteditor provides widgets and helpers shared by the text-editing example applications.
Package texteditor provides widgets and helpers shared by the text-editing example applications.
menubar command
panels command
richtexteditor command
texteditor command
toast command
todo command
internal
vettool command

Jump to

Keyboard shortcuts

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