widget

package
v1.1.2 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2026 License: BSD-3-Clause Imports: 64 Imported by: 0

Documentation

Overview

Package widget defines the UI widgets within the Bellui toolkit.

Index

Constants

This section is empty.

Variables

View Source
var (
	// RichTextStyleBlockquote represents a quote presented in an indented block.
	//
	// Since: 1.0
	RichTextStyleBlockquote = RichTextStyle{
		ColorName: theme.ColorNameOnSurfaceVariant,
		Inline:    false,
		SizeName:  theme.SizeNameBodyMedium,
		TextStyle: bellui.TextStyle{Italic: true},
	}
	// RichTextStyleCodeBlock represents a code blog segment.
	//
	// Since: 1.0
	RichTextStyleCodeBlock = RichTextStyle{
		ColorName: theme.ColorNameOnSurface,
		Inline:    false,
		SizeName:  theme.SizeNameBodyMedium,
		TextStyle: bellui.TextStyle{Monospace: true},
	}
	// RichTextStyleCodeInline represents an inline code segment.
	//
	// Since: 1.0
	RichTextStyleCodeInline = RichTextStyle{
		ColorName: theme.ColorNameOnSurface,
		Inline:    true,
		SizeName:  theme.SizeNameBodyMedium,
		TextStyle: bellui.TextStyle{Monospace: true},
	}
	// RichTextStyleEmphasis represents regular text with emphasis.
	//
	// Since: 1.0
	RichTextStyleEmphasis = RichTextStyle{
		ColorName: theme.ColorNameOnSurface,
		Inline:    true,
		SizeName:  theme.SizeNameBodyMedium,
		TextStyle: bellui.TextStyle{Italic: true},
	}
	// RichTextStyleHeading represents a heading text that stands on its own line.
	//
	// Since: 1.0
	RichTextStyleHeading = RichTextStyle{
		ColorName:    theme.ColorNameOnSurface,
		Inline:       false,
		SizeName:     theme.SizeNameTitleLarge,
		TextStyle:    bellui.TextStyle{Bold: true},
		HeadingLevel: 1,
	}
	// RichTextStyleInline represents standard text that can be surrounded by other elements.
	//
	// Since: 1.0
	RichTextStyleInline = RichTextStyle{
		ColorName: theme.ColorNameOnSurface,
		Inline:    true,
		SizeName:  theme.SizeNameBodyMedium,
	}
	// RichTextStyleParagraph represents standard text that should appear separate from other text.
	//
	// Since: 1.0
	RichTextStyleParagraph = RichTextStyle{
		ColorName: theme.ColorNameOnSurface,
		Inline:    false,
		SizeName:  theme.SizeNameBodyMedium,
	}
	// RichTextStylePassword represents standard sized text where the characters are obscured.
	//
	// Since: 1.0
	RichTextStylePassword = RichTextStyle{
		ColorName: theme.ColorNameOnSurface,
		Inline:    true,
		SizeName:  theme.SizeNameBodyMedium,
		// contains filtered or unexported fields
	}
	// RichTextStyleStrong represents regular text with a strong emphasis.
	//
	// Since: 1.0
	RichTextStyleStrong = RichTextStyle{
		ColorName: theme.ColorNameOnSurface,
		Inline:    true,
		SizeName:  theme.SizeNameBodyMedium,
		TextStyle: bellui.TextStyle{Bold: true},
	}
	// RichTextStyleSubHeading represents a sub-heading text that stands on its own line.
	//
	// Since: 1.0
	RichTextStyleSubHeading = RichTextStyle{
		ColorName:    theme.ColorNameOnSurface,
		Inline:       false,
		SizeName:     theme.SizeNameTitleMedium,
		TextStyle:    bellui.TextStyle{Bold: true},
		HeadingLevel: 2,
	}
)
View Source
var DebugLayout bool

DebugLayout enables logging of MinSize calculations and Resize calls. Set to true during development to understand why widgets get specific sizes.

widget.DebugLayout = true
View Source
var DebugRefresh bool

DebugRefresh enables logging of every widget Refresh() call. Set to true during development to trace the refresh cascade.

widget.DebugRefresh = true

Functions

func BindCheck

func BindCheck(check *Check, value *flow.Value[bool]) func()

BindCheck creates a bidirectional binding between a Check and a flow.Value[bool]. Returns an unsubscribe function.

enabled := flow.New(true)
check := widget.NewCheck("Enable", nil)
unbind := widget.BindCheck(check, enabled)

func BindEntry

func BindEntry(entry *Entry, value *flow.Value[string]) func()

BindEntry creates a bidirectional binding between an Entry and a flow.Value[string]. The Entry's text is set from the value, and typing in the Entry updates the value. Returns an unsubscribe function that removes the binding.

name := flow.New("Hello")
entry := widget.NewEntry()
unbind := widget.BindEntry(entry, name)

func BindLabel

func BindLabel(label *Label, source StringSource) func()

BindLabel creates a one-way binding from a flow.Source to a Label. The Label's text is updated whenever the source value changes. Works with both flow.Value[string] and flow.Derived[string]. Returns an unsubscribe function.

name := flow.New("Hello")
label := widget.NewLabel("")
unbind := widget.BindLabel(label, name)

func BindListModel

func BindListModel[T any](list *List, m model.Model[T],
	createItem func() core.CanvasObject,
	updateItem func(item T, row core.CanvasObject),
) (unbind func())

BindListModel drives a List from a model.Model, setting its Length, CreateItem and UpdateItem callbacks and refreshing the list whenever the model changes. Because the model may be a model.SortProxy or model.FilterProxy (or a composition of them), this is how a list gets locale-aware sorting and live filtering without the app hand-rolling index bookkeeping.

updateItem receives the typed item for a row rather than a positional id, so callers never index back into their data. The returned function detaches the binding; call it when the list is discarded.

Mutate the underlying model on the main goroutine (use bellui.Do from a background goroutine), the same rule the widgets already follow.

Since: 1.0

func BindListSelection

func BindListSelection[T any, K comparable](list *List, m model.Model[T], sel *model.SelectionModel[T, K]) (unbind func())

BindListSelection keeps a List's selection in sync with a model.SelectionModel that is keyed by stable item identity, so the selection survives a re-sort or re-filter of m: a tap updates the selection model, and when the model reorders or the selection changes the list's highlight is re-derived from the selected item's current row.

The List widget can only paint a single highlighted row; for multi-selection have the list's updateItem call model.SelectionModel.IsIndexSelected to style every selected row itself. This function still tracks the full multi-selection in sel — it only reflects the most recent selected row into the built-in highlight. The returned function detaches the binding.

Since: 1.0

func BindProgressBar

func BindProgressBar(bar *ProgressBar, value *flow.Value[float64]) func()

BindProgressBar creates a one-way binding from a flow.Value[float64] to a ProgressBar. Returns an unsubscribe function.

func BindSlider

func BindSlider(slider *Slider, value *flow.Value[float64]) func()

BindSlider creates a bidirectional binding between a Slider and a flow.Value[float64]. Returns an unsubscribe function.

func BindTableModel

func BindTableModel[T any](t *Table, m model.Model[T], cols int,
	createCell func() core.CanvasObject,
	updateCell func(item T, col int, cell core.CanvasObject),
) (unbind func())

BindTableModel drives a Table whose rows come from a model.Model, with a fixed number of columns. updateCell receives the row's typed item plus the column index, so the app maps (item, col) to cell content. The returned function detaches the binding.

For header-click sorting over a model.SortProxy, pair this with BindTableSort on the same proxy.

Since: 1.0

func BindTreeModel

func BindTreeModel(tree *Tree, p *model.TreeProxy) (unbind func())

BindTreeModel drives a Tree from a model.TreeProxy, setting its Root, ChildUIDs and IsBranch callbacks and refreshing the tree whenever the proxy's view changes. Because the proxy applies ancestor-keeping filtering and per-sibling-group sorting, this is how a tree gets locale-aware ordering and live filtering without the app re-deriving the visible hierarchy itself.

The app supplies the tree's CreateNode/UpdateNode as usual. Change the view by calling the proxy's SetLess/SetPredicate/Refresh on the main goroutine (use bellui.Do from a background goroutine), the same rule the widgets already follow. The returned function detaches the binding.

Since: 1.0

func InspectLayout

func InspectLayout(obj core.CanvasObject) string

InspectLayout returns a human-readable tree showing each object's type, size, position, and MinSize. Useful for debugging why a widget gets a particular size.

fmt.Println(widget.InspectLayout(myWindow.Content()))

Output example:

*widget.Button  size=(200,40)  pos=(10,10)  min=(80,36)
  *canvas.Text  size=(180,20)  pos=(10,10)  min=(60,16)

func NewSimpleRenderer

func NewSimpleRenderer(object core.CanvasObject) core.WidgetRenderer

NewSimpleRenderer creates a new SimpleRenderer to render a widget using a single core.CanvasObject.

Since: 1.0

func ResetExtendWarningsForTests

func ResetExtendWarningsForTests(t interface{ Cleanup(func()) })

ResetExtendWarningsForTests clears the process-global de-dup set that limits the "used before ExtendBaseWidget was called" warning (see super) to once per call site for the whole process. That de-dup is the right default in production (a misconfigured widget would otherwise log every frame), but it makes a regression test that asserts a widget does NOT warn unreliable in a shared package run: an earlier test that tripped the same call site suppresses the log the later test is watching for. Call this at the start of such a test so it observes the warning fresh; the registered cleanup clears the set again so a following test starts clean too. Mirrors lang.SetLocaleForTests (takes the minimal Cleanup interface to avoid importing testing into production code).

func SaveThemeSelection

func SaveThemeSelection(sel ThemeSelection, p bellui.Preferences)

SaveThemeSelection stores sel in the given preferences, typically an app's own Preferences, so the appearance choice follows the app rather than the system-wide Bellui settings. Restore it with LoadThemeSelection.

Since: 1.0

func ShowAutoDateTimePicker

func ShowAutoDateTimePicker(selected time.Time, changed func(time.Time), c core.Canvas)

ShowAutoDateTimePicker shows a combined date+time picker modal that auto-detects 12h/24h mode from the current locale.

Since: 1.0

func ShowAutoTimePicker

func ShowAutoTimePicker(hour, minute int, changed func(hour, minute int), c core.Canvas)

ShowAutoTimePicker shows a time picker modal that auto-detects 12h/24h mode.

Since: 1.0

func ShowBottomSheet

func ShowBottomSheet(content core.CanvasObject, c core.Canvas)

ShowBottomSheet is a convenience function.

func ShowDatePicker

func ShowDatePicker(selected time.Time, changed func(time.Time), c core.Canvas)

ShowDatePicker shows the date picker as a modal dialog.

Since: 1.0

func ShowDateTimePicker

func ShowDateTimePicker(selected time.Time, use24h bool, changed func(time.Time), c core.Canvas)

ShowDateTimePicker shows the combined picker as a modal dialog.

Since: 1.0

func ShowFontPickerPopup

func ShowFontPickerPopup(config FontPickerConfig, families []FontFamily, changed func(FontPickerConfig), c core.Canvas)

ShowFontPickerPopup shows the font picker in a modal popup with OK/Cancel buttons.

func ShowModalPopUp

func ShowModalPopUp(content core.CanvasObject, canvas core.Canvas)

ShowModalPopUp creates a new popUp for the specified content and displays it on the passed canvas. A modal PopUp blocks interactions with underlying elements, covered with a semi-transparent overlay.

func ShowPopUp

func ShowPopUp(content core.CanvasObject, canvas core.Canvas)

ShowPopUp creates a new popUp for the specified content and displays it on the passed canvas.

func ShowPopUpAtPosition

func ShowPopUpAtPosition(content core.CanvasObject, canvas core.Canvas, pos geo.Position)

ShowPopUpAtPosition creates a new popUp for the specified content at the specified absolute position. It will then display the popup on the passed canvas.

func ShowPopUpAtRelativePosition

func ShowPopUpAtRelativePosition(content core.CanvasObject, canvas core.Canvas, rel geo.Position, to core.CanvasObject)

ShowPopUpAtRelativePosition shows a new popUp for the specified content at the given position relative to stated object. It will then display the popup on the passed canvas.

Since: 1.0

func ShowPopUpMenuAtPosition

func ShowPopUpMenuAtPosition(menu *bellui.Menu, c core.Canvas, pos geo.Position)

ShowPopUpMenuAtPosition creates a PopUp menu populated with items from the passed menu structure. It will automatically be positioned at the provided location and shown as an overlay on the specified canvas.

func ShowPopUpMenuAtRelativePosition

func ShowPopUpMenuAtRelativePosition(menu *bellui.Menu, c core.Canvas, rel geo.Position, to core.CanvasObject)

ShowPopUpMenuAtRelativePosition creates a PopUp menu populated with menu items from the passed menu structure. It will automatically be positioned at the given position relative to stated object and shown as an overlay on the specified canvas.

Since: 1.0

func ShowSideSheet

func ShowSideSheet(content core.CanvasObject, c core.Canvas)

ShowSideSheet is a convenience function.

func ShowSnackbar

func ShowSnackbar(text, actionText string, action func(), c core.Canvas)

ShowSnackbar is a convenience function to show a snackbar on the given canvas.

func ShowTimePicker

func ShowTimePicker(hour, minute int, use24h bool, changed func(hour, minute int), c core.Canvas)

ShowTimePicker shows the time picker as a modal dialog.

Since: 1.0

Types

type Accordion

type Accordion struct {
	BaseWidget
	Items     []*AccordionItem
	MultiOpen bool
}

Accordion displays a list of AccordionItems. Each item is represented by a button that reveals a detailed view when tapped.

func NewAccordion

func NewAccordion(items ...*AccordionItem) *Accordion

NewAccordion creates a new accordion widget.

func (*Accordion) AccessibleLabel

func (a *Accordion) AccessibleLabel() string

AccessibleLabel returns an empty string; accordions have no intrinsic label.

func (*Accordion) AccessibleRole

func (a *Accordion) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleAccordion.

func (*Accordion) Append

func (a *Accordion) Append(item *AccordionItem)

Append adds the given item to this Accordion.

func (*Accordion) Close

func (a *Accordion) Close(index int)

Close collapses the item at the given index.

func (*Accordion) CloseAll

func (a *Accordion) CloseAll()

CloseAll collapses all items.

func (*Accordion) CreateRenderer

func (a *Accordion) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*Accordion) MinSize

func (a *Accordion) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below.

func (*Accordion) Open

func (a *Accordion) Open(index int)

Open expands the item at the given index.

func (*Accordion) OpenAll

func (a *Accordion) OpenAll()

OpenAll expands all items, note that your Accordion should have [MultiOpen] set to `true` for this to operate as expected. For single-open accordions it will open only the first item.

func (*Accordion) Prepend

func (a *Accordion) Prepend(item *AccordionItem)

Prepend adds the given item to the beginning of this Accordion.

Since: 1.0

func (*Accordion) Remove

func (a *Accordion) Remove(item *AccordionItem)

Remove deletes the given item from this Accordion.

func (*Accordion) RemoveIndex

func (a *Accordion) RemoveIndex(index int)

RemoveIndex deletes the item at the given index from this Accordion.

type AccordionItem

type AccordionItem struct {
	Title  string
	Detail core.CanvasObject
	Open   bool
}

AccordionItem represents a single item in an Acc rdion.

func NewAccordionItem

func NewAccordionItem(title string, detail core.CanvasObject) *AccordionItem

NewAccordionItem creates a new item for an Accordion.

type Activity

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

Activity is used to indicate that something is happening that should be waited for, or is in the background (depending on usage).

Since: 1.0

func NewActivity

func NewActivity() *Activity

NewActivity returns a widget for indicating activity

Since: 1.0

func (*Activity) CreateRenderer

func (a *Activity) CreateRenderer() core.WidgetRenderer

func (*Activity) MinSize

func (a *Activity) MinSize() geo.Size

func (*Activity) Start

func (a *Activity) Start()

Start the activity indicator animation

func (*Activity) Stop

func (a *Activity) Stop()

Stop the activity indicator animation

type AnimatedGif

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

AnimatedGif widget shows a Gif image with many frames. All methods must be called from the main (UI) goroutine, like other widgets; frames are advanced by a per-frame animation tick, so playback pauses with the canvas and needs no background goroutine.

Since: 1.0

func NewAnimatedGif

func NewAnimatedGif(u bellui.URI) (*AnimatedGif, error)

NewAnimatedGif creates a new widget loaded to show the specified image. If there is an error loading the image it will be returned in the error value.

func NewAnimatedGifFromResource

func NewAnimatedGifFromResource(r bellui.Resource) (*AnimatedGif, error)

NewAnimatedGifFromResource creates a new widget loaded to show the specified image resource. If there is an error loading the image it will be returned in the error value.

func (*AnimatedGif) CreateRenderer

func (g *AnimatedGif) CreateRenderer() core.WidgetRenderer

CreateRenderer loads the widget renderer for this widget. This is an internal requirement for Bellui.

func (*AnimatedGif) Load

func (g *AnimatedGif) Load(u bellui.URI) error

Load is used to change the gif file shown. It will change the loaded content and prepare the new frames for animation. Any running animation is stopped.

func (*AnimatedGif) LoadResource

func (g *AnimatedGif) LoadResource(r bellui.Resource) error

LoadResource is used to change the gif resource shown. It will change the loaded content and prepare the new frames for animation. Any running animation is stopped.

func (*AnimatedGif) MinSize

func (g *AnimatedGif) MinSize() geo.Size

MinSize returns the minimum size that this GIF can occupy. Because gif images are measured in pixels we cannot use the dimensions, so this defaults to 0x0. You can set a minimum size if required using SetMinSize.

func (*AnimatedGif) SetMinSize

func (g *AnimatedGif) SetMinSize(min geo.Size)

SetMinSize sets the smallest possible size that this AnimatedGif should be drawn at. Be careful not to set this based on pixel sizes as that will vary based on output device.

func (*AnimatedGif) Start

func (g *AnimatedGif) Start()

Start begins the animation. The speed of the transition is controlled by the loaded gif file.

func (*AnimatedGif) Stop

func (g *AnimatedGif) Stop()

Stop will request that the animation stops running, the last frame will remain visible.

type AuthButton

type AuthButton struct {
	BaseWidget

	// Provider is the provider key (e.g., "google", "microsoft").
	Provider string

	// ClientID is the OAuth 2.0 client identifier.
	ClientID string

	// Issuer overrides the OIDC discovery URL. Required for "okta",
	// "keycloak", and "custom" providers.
	Issuer string

	// Scopes is a space-separated list of OAuth scopes.
	// Defaults to "openid email profile" for OIDC providers and to
	// "user:email read:user" for GitHub.
	Scopes string

	// Text overrides the button label. Defaults to the provider preset.
	Text string

	Logo bellui.Resource

	// OnAuthenticated is called on the main thread after a successful
	// authentication with the user's claims.
	OnAuthenticated func(result auth.OIDCResult) `json:"-"`

	// OnError is called on the main thread if authentication fails.
	OnError func(err error) `json:"-"`
	// contains filtered or unexported fields
}

AuthButton is a branded sign-in button that triggers an OIDC or OAuth 2.0 authentication flow for a specific provider. It displays the provider's logo and brand-compliant colors.

Supported providers: "google", "microsoft", "apple", "github", "okta", "keycloak", and "custom".

func NewAuthButton

func NewAuthButton(provider, clientID string, onAuth func(auth.OIDCResult)) *AuthButton

NewAuthButton creates a new authentication button for the given provider.

func (*AuthButton) CancelAuth

func (b *AuthButton) CancelAuth()

CancelAuth cancels any in-flight authentication flow.

func (*AuthButton) CreateRenderer

func (b *AuthButton) CreateRenderer() core.WidgetRenderer

func (*AuthButton) Tapped

func (b *AuthButton) Tapped(_ *event.PointEvent)

Tapped triggers the authentication flow in a background goroutine. If an authentication is already in progress, the tap is ignored.

type Badge

type Badge struct {
	BaseWidget
	Count   int               // 0 = dot only, >0 = shows number (capped at 999+)
	Content core.CanvasObject // the widget to attach the badge to
}

Badge is an MD3 notification indicator (dot or count) attached to a widget.

func NewBadge

func NewBadge(content core.CanvasObject) *Badge

NewBadge creates a dot badge on the given content.

func NewBadgeWithCount

func NewBadgeWithCount(content core.CanvasObject, count int) *Badge

NewBadgeWithCount creates a numbered badge on the given content.

func (*Badge) AccessibleLabel

func (b *Badge) AccessibleLabel() string

AccessibleLabel returns the badge count as a string, or "new" for dot-only badges.

func (*Badge) AccessibleRole

func (b *Badge) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleBadge.

func (*Badge) CreateRenderer

func (b *Badge) CreateRenderer() core.WidgetRenderer

func (*Badge) MinSize

func (b *Badge) MinSize() geo.Size

type BaseWidget

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

BaseWidget provides a helper that handles basic widget behaviours.

func (*BaseWidget) AccessibilityLabel

func (w *BaseWidget) AccessibilityLabel() string

AccessibilityLabel returns the label set via BaseWidget.SetAccessibilityLabel, or an empty string when none is set. It implements core.AccessibleLabelOverrider.

func (*BaseWidget) ExtendBaseWidget

func (w *BaseWidget) ExtendBaseWidget(wid core.Widget)

ExtendBaseWidget is used by an extending widget to make use of BaseWidget functionality.

func (*BaseWidget) Hide

func (w *BaseWidget) Hide()

Hide this widget so it is no longer visible

func (*BaseWidget) MinSize

func (w *BaseWidget) MinSize() geo.Size

MinSize for the widget - it should never be resized below this value. Enable widget.DebugLayout to trace MinSize calculations.

func (*BaseWidget) Move

func (w *BaseWidget) Move(pos geo.Position)

Move the widget to a new position, relative to its parent. Note this should not be used if the widget is being managed by a Layout within a Container.

func (*BaseWidget) Position

func (w *BaseWidget) Position() geo.Position

Position gets the current position of this widget, relative to its parent.

func (*BaseWidget) Refresh

func (w *BaseWidget) Refresh()

Refresh causes this widget to be redrawn in its current state.

The refresh sequence is:

  1. Re-entrance check — prevents infinite Refresh↔Resize loops
  2. SyncState — if the widget implements StateSyncer, its SyncState() method is called to sync public fields to internal rendering state
  3. Renderer.Refresh — the renderer updates canvas objects from state

Widgets should implement StateSyncer instead of overriding Refresh() to ensure state is always synced before rendering.

func (*BaseWidget) Resize

func (w *BaseWidget) Resize(size geo.Size)

Resize sets a new size for a widget. Note this should not be used if the widget is being managed by a Layout within a Container.

func (*BaseWidget) SetAccessibilityLabel

func (w *BaseWidget) SetAccessibilityLabel(label string)

SetAccessibilityLabel sets an application-supplied accessible label that takes precedence over the widget's intrinsic AccessibleLabel. Use it to name widgets without visible text, such as icon-only buttons:

btn := widget.NewIconButton(theme.DeleteIcon(), onDelete)
btn.SetAccessibilityLabel(lang.L("Delete"))

It only affects widgets that implement core.Accessible.

func (*BaseWidget) SetToolTipText

func (w *BaseWidget) SetToolTipText(text string)

SetToolTipText sets the hover tooltip text for this widget. The desktop driver shows the text in a small bubble after a short hover delay, and hides it when the pointer leaves; an empty string (the default) means no tooltip. This is the ergonomic, driver-level replacement for wrapping a widget in widget.NewTooltip:

btn := widget.NewIconButton(theme.ContentAddIcon(), onNew)
btn.SetToolTipText(lang.L("New file"))

Since: 1.0

func (*BaseWidget) Show

func (w *BaseWidget) Show()

Show this widget so it becomes visible

func (*BaseWidget) Size

func (w *BaseWidget) Size() geo.Size

Size gets the current size of this widget.

func (*BaseWidget) Theme

func (w *BaseWidget) Theme() bellui.Theme

Theme returns a cached Theme instance for this widget (or its extending widget). This will be the app theme in most cases, or a widget specific theme if it is inside a ThemeOverride container.

Since: 1.0

func (*BaseWidget) ToolTip

func (w *BaseWidget) ToolTip() string

ToolTip returns the tooltip text set via BaseWidget.SetToolTipText, or an empty string when none is set. It implements core.ToolTipable, so every widget can carry a hover tooltip.

Since: 1.0

func (*BaseWidget) Visible

func (w *BaseWidget) Visible() bool

Visible returns whether or not this widget should be visible. Note that this may not mean it is currently visible if a parent has been hidden.

type BottomAppBar

type BottomAppBar struct {
	BaseWidget
	Actions []*BottomAppBarAction
	FAB     *FAB // optional, positioned at right
}

BottomAppBar is an MD3 bottom toolbar with action icons and an optional FAB.

func NewBottomAppBar

func NewBottomAppBar(actions []*BottomAppBarAction, fab *FAB) *BottomAppBar

NewBottomAppBar creates a bottom app bar.

func (*BottomAppBar) AccessibleLabel

func (b *BottomAppBar) AccessibleLabel() string

AccessibleLabel returns an empty string.

func (*BottomAppBar) AccessibleRole

func (b *BottomAppBar) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleToolbar.

func (*BottomAppBar) CreateRenderer

func (b *BottomAppBar) CreateRenderer() core.WidgetRenderer

func (*BottomAppBar) MinSize

func (b *BottomAppBar) MinSize() geo.Size

type BottomAppBarAction

type BottomAppBarAction struct {
	Icon     bellui.Resource
	OnTapped func()
}

BottomAppBarAction is an action icon in the bottom app bar.

type BottomSheet

type BottomSheet struct {
	Content core.CanvasObject
	Modal   bool
	// contains filtered or unexported fields
}

BottomSheet is an MD3 bottom sheet that shows content from the bottom of the screen.

func NewBottomSheet

func NewBottomSheet(content core.CanvasObject) *BottomSheet

NewBottomSheet creates a bottom sheet with the given content.

func (*BottomSheet) Hide

func (s *BottomSheet) Hide()

Hide dismisses the bottom sheet.

func (*BottomSheet) Show

func (s *BottomSheet) Show(c core.Canvas)

Show displays the bottom sheet on the given canvas.

type Button

type Button struct {
	DisableableWidget
	Text string
	Icon bellui.Resource
	// Specify how prominent the button should be, High will highlight the button and Low will remove some decoration.
	//
	// Since: 1.0
	Importance Importance
	// Style sets the MD3 visual variant. When ButtonStyleDefault, the Importance
	// field controls colors. Other styles override Importance for color selection.
	Style         ButtonStyle
	Alignment     ButtonAlign
	IconPlacement ButtonIconPlacement

	OnTapped func() `json:"-"`
	// contains filtered or unexported fields
}

Button widget has a text label and triggers an event func when clicked

func NewButton

func NewButton(label string, tapped func()) *Button

NewButton creates a new button widget with the set label and tap handler

func NewButtonWithIcon

func NewButtonWithIcon(label string, icon bellui.Resource, tapped func()) *Button

NewButtonWithIcon creates a new button widget with the specified label, themed icon and tap handler

func (*Button) AccessibleActions

func (b *Button) AccessibleActions() []core.AccessibleAction

AccessibleActions returns the "press" action.

func (*Button) AccessibleLabel

func (b *Button) AccessibleLabel() string

AccessibleLabel returns the button text.

func (*Button) AccessibleRole

func (b *Button) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleButton.

func (*Button) ActivatedByKey

func (b *Button) ActivatedByKey(ev *event.KeyEvent) bool

ActivatedByKey reports that Space activates the button, so the driver fires the keyboard-activation signal in parity with a pointer tap (pre-rebrand tracker #700).

func (*Button) CreateRenderer

func (b *Button) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*Button) Cursor

func (b *Button) Cursor() desktop.Cursor

Cursor returns the cursor type of this widget

func (*Button) FocusGained

func (b *Button) FocusGained()

FocusGained is a hook called by the focus handling logic after this object gained the focus.

func (*Button) FocusLost

func (b *Button) FocusLost()

FocusLost is a hook called by the focus handling logic after this object lost the focus.

func (*Button) HoverIn

func (b *Button) HoverIn(*event.HoverEvent)

HoverIn is called when a desktop pointer enters the widget

func (*Button) HoverMoved

func (b *Button) HoverMoved(*event.HoverEvent)

HoverMoved is called when a desktop pointer hovers over the widget

func (*Button) HoverOut

func (b *Button) HoverOut()

HoverOut is called when a desktop pointer exits the widget

func (*Button) MinSize

func (b *Button) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below

func (*Button) PerformAccessibleAction

func (b *Button) PerformAccessibleAction(name string)

PerformAccessibleAction invokes the button's tap handler.

func (*Button) SetIcon

func (b *Button) SetIcon(icon bellui.Resource)

SetIcon updates the icon on a label - pass nil to hide an icon. It is safe to call from any goroutine.

func (*Button) SetText

func (b *Button) SetText(text string)

SetText allows the button label to be changed. It is safe to call from any goroutine.

func (*Button) Tapped

func (b *Button) Tapped(ev *event.PointEvent)

Tapped is called when a pointer tapped event is captured and triggers any tap handler

func (*Button) TypedKey

func (b *Button) TypedKey(ev *event.KeyEvent)

TypedKey is a hook called by the input handling logic on key events if this object is focused.

func (*Button) TypedRune

func (b *Button) TypedRune(rune)

TypedRune is a hook called by the input handling logic on text input events if this object is focused.

type ButtonAlign

type ButtonAlign int

ButtonAlign represents the horizontal alignment of a button.

const (
	// ButtonAlignCenter aligns the icon and the text centrally.
	ButtonAlignCenter ButtonAlign = iota
	// ButtonAlignLeading aligns the icon and the text with the leading edge.
	ButtonAlignLeading
	// ButtonAlignTrailing aligns the icon and the text with the trailing edge.
	ButtonAlignTrailing
)

type ButtonGroup

type ButtonGroup struct {
	BaseWidget
	Buttons []*Button
}

ButtonGroup is an MD3 connected group of buttons sharing borders.

func NewButtonGroup

func NewButtonGroup(buttons ...*Button) *ButtonGroup

NewButtonGroup creates a connected button group.

func (*ButtonGroup) CreateRenderer

func (g *ButtonGroup) CreateRenderer() core.WidgetRenderer

func (*ButtonGroup) MinSize

func (g *ButtonGroup) MinSize() geo.Size

type ButtonIconPlacement

type ButtonIconPlacement int

ButtonIconPlacement represents the ordering of icon & text within a button.

const (
	// ButtonIconLeadingText aligns the icon on the leading edge of the text.
	ButtonIconLeadingText ButtonIconPlacement = iota
	// ButtonIconTrailingText aligns the icon on the trailing edge of the text.
	ButtonIconTrailingText
)

type ButtonStyle

type ButtonStyle int

ButtonStyle determines the visual variant of a button per MD3 spec.

const (
	// ButtonStyleDefault follows the Importance field for color scheme.
	ButtonStyleDefault ButtonStyle = iota
	// ButtonStyleFilled uses Primary background with OnPrimary text (MD3 Filled).
	ButtonStyleFilled
	// ButtonStyleFilledTonal uses SecondaryContainer background (MD3 Filled Tonal).
	ButtonStyleFilledTonal
	// ButtonStyleElevated uses surface color with shadow and Primary text (MD3 Elevated).
	ButtonStyleElevated
	// ButtonStyleOutlined uses transparent background with border (MD3 Outlined).
	ButtonStyleOutlined
	// ButtonStyleText uses transparent background with Primary text (MD3 Text).
	ButtonStyleText
)

type Card

type Card struct {
	BaseWidget
	Title, Subtitle string
	Image           *canvas.Image
	Content         core.CanvasObject
	// Style sets the MD3 visual variant (Elevated, Filled, Outlined).
	Style CardStyle
}

Card widget groups title, subtitle with content and a header image

Since: 1.0

func NewCard

func NewCard(title, subtitle string, content core.CanvasObject) *Card

NewCard creates a new card widget with the specified title, subtitle and content (all optional).

Since: 1.0

func (*Card) AccessibleLabel

func (c *Card) AccessibleLabel() string

AccessibleLabel returns the card title.

func (*Card) AccessibleRole

func (c *Card) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleCard.

func (*Card) CreateRenderer

func (c *Card) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*Card) MinSize

func (c *Card) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below

func (*Card) SetContent

func (c *Card) SetContent(obj core.CanvasObject)

SetContent changes the body of this card to have the specified content.

func (*Card) SetImage

func (c *Card) SetImage(img *canvas.Image)

SetImage changes the image displayed above the title for this card.

func (*Card) SetSubTitle

func (c *Card) SetSubTitle(text string)

SetSubTitle updates the secondary title for this card.

func (*Card) SetTitle

func (c *Card) SetTitle(text string)

SetTitle updates the main title for this card.

type CardStyle

type CardStyle int

CardStyle determines the visual variant of a card per MD3 spec.

const (
	// CardStyleElevated uses shadow + surface fill (default).
	CardStyleElevated CardStyle = iota
	// CardStyleFilled uses SurfaceContainerHighest fill, no shadow.
	CardStyleFilled
	// CardStyleOutlined uses surface fill with border, no shadow.
	CardStyleOutlined
)
type Carousel struct {
	BaseWidget
	Items       []core.CanvasObject
	CurrentItem int
	OnChanged   func(int) `json:"-"`
}

Carousel is an MD3 horizontally-scrolling showcase of items with snapping.

func NewCarousel

func NewCarousel(items ...core.CanvasObject) *Carousel

NewCarousel creates a carousel with the given items.

func (*Carousel) AccessibleLabel

func (c *Carousel) AccessibleLabel() string

AccessibleLabel returns an empty string; use SetAccessibilityLabel to name the showcase.

func (*Carousel) AccessibleRole

func (c *Carousel) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleGroup; the navigation buttons and item content inside provide their own semantics.

func (*Carousel) CreateRenderer

func (c *Carousel) CreateRenderer() core.WidgetRenderer

func (*Carousel) DragEnd

func (c *Carousel) DragEnd()

func (*Carousel) Dragged

func (c *Carousel) Dragged(e *event.DragEvent)

func (*Carousel) MinSize

func (c *Carousel) MinSize() geo.Size

func (*Carousel) Next

func (c *Carousel) Next()

Next advances to the next item.

func (*Carousel) Previous

func (c *Carousel) Previous()

Previous goes to the previous item.

type CellEditor

type CellEditor[T any] struct {
	// Text returns the string to seed the editor with when editing begins.
	Text func(item T) string

	// Commit parses the edited text back into an updated item. Returning a
	// non-nil error rejects the edit as invalid: the editor stays open and the
	// model is not written, backing validation. When Commit is nil the item is
	// not editable (editing that cell/row is a no-op).
	Commit func(item T, text string) (T, error)

	// Validator, if set, is attached to the editor Entry for live in-field
	// validation feedback while typing. It does not gate the commit — only
	// Commit's returned error does.
	Validator bellui.StringValidator
}

CellEditor describes how an inline editor exchanges a string with a model item for the editing delegates (BindListEditing / BindTableEditing). Values are edited through a single-line Entry: Text seeds the editor when editing begins and Commit turns the edited text back into an item.

Since: 1.0

type Check

type Check struct {
	DisableableWidget
	Text    string
	Checked bool

	// Partial check is when there is an indeterminate state (usually meaning that child items are some-what checked).
	// Turning this on will override the checked state and show a dash icon (neither checked nor unchecked).
	// The user interaction cannot turn this on, tapping a partial check state will set `Checked` to true.
	//
	// Since: 1.0
	Partial bool

	OnChanged func(bool) `json:"-"`
	// contains filtered or unexported fields
}

Check widget has a text label and a checked (or unchecked) icon and triggers an event func when toggled

func NewCheck

func NewCheck(label string, changed func(bool)) *Check

NewCheck creates a new check widget with the set label and change handler

func NewCheckWithData

func NewCheckWithData(label string, data binding.Bool) *Check

NewCheckWithData returns a check widget connected with the specified data source.

Since: 1.0

func (*Check) AccessibleActions

func (c *Check) AccessibleActions() []core.AccessibleAction

AccessibleActions returns the "toggle" action.

func (*Check) AccessibleLabel

func (c *Check) AccessibleLabel() string

AccessibleLabel returns the check label text.

func (*Check) AccessibleRole

func (c *Check) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleCheckbox.

func (*Check) AccessibleState

func (c *Check) AccessibleState() core.AccessibleState

AccessibleState returns the checked, partial, and disabled state.

func (*Check) Bind

func (c *Check) Bind(data binding.Bool)

Bind connects the specified data source to this Check. The current value will be displayed and any changes in the data will cause the widget to update. User interactions with this Check will set the value into the data source.

The public Check.OnChanged field is left alone: binding and an app change handler coexist, and OnChanged may be assigned before or after Bind.

Since: 1.0

func (*Check) CreateRenderer

func (c *Check) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*Check) FocusGained

func (c *Check) FocusGained()

FocusGained is called when the Check has been given focus.

func (*Check) FocusLost

func (c *Check) FocusLost()

FocusLost is called when the Check has had focus removed.

func (*Check) Hide

func (c *Check) Hide()

Hide this widget, if it was previously visible

func (*Check) HoverIn

func (c *Check) HoverIn(me *event.HoverEvent)

HoverIn is called when a desktop pointer enters the widget

func (*Check) HoverMoved

func (c *Check) HoverMoved(me *event.HoverEvent)

HoverMoved is called when a desktop pointer hovers over the widget

func (*Check) HoverOut

func (c *Check) HoverOut()

HoverOut is called when a desktop pointer exits the widget

func (*Check) MinSize

func (c *Check) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below

func (*Check) PerformAccessibleAction

func (c *Check) PerformAccessibleAction(name string)

PerformAccessibleAction toggles the check state.

func (*Check) SetChecked

func (c *Check) SetChecked(checked bool)

SetChecked sets the checked state and refreshes widget. If the `Partial` state is set this will be turned off to respect the `checked` bool passed in here. It is safe to call from any goroutine.

func (*Check) SetText

func (c *Check) SetText(text string)

SetText sets the text of the Check

Since: 1.0

func (*Check) Tapped

func (c *Check) Tapped(pe *event.PointEvent)

Tapped is called when a pointer tapped event is captured and triggers any change handler

func (*Check) TypedKey

func (c *Check) TypedKey(key *event.KeyEvent)

TypedKey receives key input events when the Check is focused.

func (*Check) TypedRune

func (c *Check) TypedRune(r rune)

TypedRune receives text input events when the Check is focused.

func (*Check) Unbind

func (c *Check) Unbind()

Unbind disconnects any configured data source from this Check. The current value will remain at the last value of the data source.

Any Check.OnChanged handler the app installed is left in place -- Unbind only clears the write-back it installed itself.

Since: 1.0

type CheckGroup

type CheckGroup struct {
	DisableableWidget
	Horizontal bool
	Required   bool
	OnChanged  func([]string) `json:"-"`
	Options    []string
	Selected   []string
	// contains filtered or unexported fields
}

CheckGroup widget has a list of text labels and checkbox icons next to each. Changing the selection (any number can be selected) will trigger the changed func.

Since: 1.0

func NewCheckGroup

func NewCheckGroup(options []string, changed func([]string)) *CheckGroup

NewCheckGroup creates a new check group widget with the set options and change handler

Since: 1.0

func (*CheckGroup) Append

func (r *CheckGroup) Append(option string)

Append adds a new option to the end of a CheckGroup widget.

func (*CheckGroup) CreateRenderer

func (r *CheckGroup) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*CheckGroup) MinSize

func (r *CheckGroup) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below

func (*CheckGroup) Refresh

func (r *CheckGroup) Refresh()

Refresh causes this widget to be redrawn in it's current state.

func (*CheckGroup) Remove

func (r *CheckGroup) Remove(option string) bool

Remove removes the first occurrence of the specified option found from a CheckGroup widget. Return true if an option was removed.

Since: 1.0

func (*CheckGroup) SetSelected

func (r *CheckGroup) SetSelected(options []string)

SetSelected sets the checked options, it can be used to set a default option.

type Chip

type Chip struct {
	BaseWidget
	Text      string
	Icon      bellui.Resource // optional leading icon
	Style     ChipStyle
	Selected  bool   // for Filter chips
	OnTapped  func() `json:"-"`
	OnDeleted func() `json:"-"` // for Input chips (shows X)
	// contains filtered or unexported fields
}

Chip is a compact MD3 element for selections, filters, or actions.

func NewChip

func NewChip(text string, tapped func()) *Chip

NewChip creates an assist/suggestion chip.

func NewFilterChip

func NewFilterChip(text string, changed func(bool)) *Chip

NewFilterChip creates a filter chip with selection toggle.

func (*Chip) AccessibleLabel

func (c *Chip) AccessibleLabel() string

AccessibleLabel returns the chip text.

func (*Chip) AccessibleRole

func (c *Chip) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleButton.

func (*Chip) CreateRenderer

func (c *Chip) CreateRenderer() core.WidgetRenderer

func (*Chip) HoverIn

func (c *Chip) HoverIn(*event.HoverEvent)

func (*Chip) HoverMoved

func (c *Chip) HoverMoved(*event.HoverEvent)

func (*Chip) HoverOut

func (c *Chip) HoverOut()

func (*Chip) MinSize

func (c *Chip) MinSize() geo.Size

func (*Chip) Tapped

func (c *Chip) Tapped(e *event.PointEvent)

type ChipStyle

type ChipStyle int

ChipStyle determines the type of chip.

const (
	ChipStyleAssist     ChipStyle = iota // Outlined, icon+label
	ChipStyleFilter                      // Selectable, checkmark when selected
	ChipStyleInput                       // Label + delete button
	ChipStyleSuggestion                  // Outlined, label only
)

type CodeSegment

type CodeSegment struct {
	Text     string
	Language string
}

CodeSegment represents a syntax-highlighted code block within a RichText widget. When the language is recognized (go, json, yaml, starlark, protobuf), the code is tokenized and rendered with syntax highlighting colors. Otherwise it falls back to plain monospace rendering.

func (*CodeSegment) Inline

func (c *CodeSegment) Inline() bool

Inline returns false — code blocks are block-level elements.

func (*CodeSegment) Select

func (c *CodeSegment) Select(_, _ geo.Position)

Select does nothing for a code block.

func (*CodeSegment) SelectedText

func (c *CodeSegment) SelectedText() string

SelectedText returns the empty string for this code block.

func (*CodeSegment) Textual

func (c *CodeSegment) Textual() string

Textual returns the plain-text content of this code block.

func (*CodeSegment) Unselect

func (c *CodeSegment) Unselect()

Unselect does nothing for a code block.

func (*CodeSegment) Update

func (c *CodeSegment) Update(o core.CanvasObject)

Update applies the current state of this code segment to an existing visual.

func (*CodeSegment) Visual

func (c *CodeSegment) Visual() core.CanvasObject

Visual returns a new richCodeBlock widget to render this segment.

type ColumnSort

type ColumnSort struct {
	Column    int
	Direction SortDirection
}

ColumnSort reports one active sort key: the column index and its direction.

Since: 1.0

type CompletionItem

type CompletionItem struct {
	// Text is the primary suggestion, shown leading and inserted on selection.
	Text string
	// Detail is optional secondary information about the item. When set, a
	// trailing information icon is shown for the row (leading when the active
	// layout direction is right-to-left).
	Detail string
	// Icon is an optional leading icon (for example a completion-kind glyph).
	Icon bellui.Resource

	// Documentation is optional longer help for the item — e.g. a language
	// server's documentation string. When any item in the popup carries
	// documentation, a scrollable panel is shown beside the list and follows
	// the selection; it replaces the small Detail tooltip while visible (pre-rebrand tracker #435).
	//
	// Since: 1.0
	Documentation string
	// DocumentationMarkdown renders Documentation as markdown when true, and
	// verbatim text otherwise.
	//
	// Since: 1.0
	DocumentationMarkdown bool
}

CompletionItem is a single suggestion shown in a CompletionPopup.

Since: 1.0

type CompletionPopup

type CompletionPopup struct {
	BaseWidget

	// OnSelected is called when the user accepts an item (Enter, Space or tap).
	OnSelected func(index int, item CompletionItem)

	// MaxVisibleRows caps how many suggestion rows are visible at once; a
	// longer list scrolls behind that window (Up/Down keep the selection in
	// view, the mouse wheel moves the window, and a thin indicator shows the
	// position). Zero applies the default of 8 rows (pre-rebrand tracker #436).
	//
	// Since: 1.0
	MaxVisibleRows int

	// KeepHostFocus, when set before Show, leaves keyboard focus where it is
	// instead of focusing the popup: the popup's overlay becomes
	// focus-transparent, so the canvas keeps delivering keys, runes and
	// shortcuts to the focused widget through its own dispatch as if the
	// popup were not open. The popup then receives no key events itself; the
	// host offers them via [CompletionPopup.HandleKey] (arrows, Enter, Tab,
	// Escape → consumed) and accepts the selection through OnSelected as
	// usual. The overlay is also tap-through on desktop (pre-rebrand tracker #472): a click
	// outside the popup dismisses it and is re-delivered to the widget
	// beneath, so the same click places the caret in the editor host.
	// Intended for editor hosts whose caret, focus-loss logic, window
	// shortcuts and key routing must survive the popup being open (pre-rebrand tracker #442);
	// plain [Entry.ShowCompletion] hosts keep the default forwarding model
	// (pre-rebrand tracker #361).
	//
	// Since: 1.0
	KeepHostFocus bool

	// OnMoved, when set, is called with the popup's final on-canvas rectangle
	// — the same values [CompletionPopup.Position] and [CompletionPopup.Size]
	// report — whenever the placement changes while the popup is visible: the
	// initial show (after [CompletionPopup.ShowAtCaret]'s below/above flip and
	// on-screen clamping), a live [CompletionPopup.SetItems] resize, or any
	// explicit move. When the popup hides it is called once with the zero
	// rectangle. Hosts use it to anchor a companion surface — e.g. a signature
	// help card — next to wherever the popup actually landed (pre-rebrand tracker #437).
	//
	// Since: 1.0
	OnMoved func(geo.Rectangle) `json:"-"`
	// contains filtered or unexported fields
}

CompletionPopup is a lightweight, application-driven completion/suggestion popup. The host application supplies the items (autocomplete, history, snippets, language-server completions, …) and the popup renders them anchored at a caret rectangle.

It is deliberately styled not to compete with the rest of the UI: no shadow, a subtle corner radius and a thin outline so it still reads as a distinct surface. Each row shows its text with an optional trailing information icon; the whole row mirrors when the active layout direction is right-to-left, so the icon moves to the leading edge. A list longer than [MaxVisibleRows] is capped and scrolls behind the visible window instead of growing taller.

This is distinct from the platform IME candidate window, which the operating system owns and positions itself; CompletionPopup complements it for app-level suggestions.

Since: 1.0

func NewCompletionPopup

func NewCompletionPopup(c core.Canvas, items []CompletionItem) *CompletionPopup

NewCompletionPopup creates a completion popup for the given items on canvas c. Show it with CompletionPopup.ShowAtCaret.

Since: 1.0

func (*CompletionPopup) AccessibleActiveDescendant

func (p *CompletionPopup) AccessibleActiveDescendant() any

AccessibleActiveDescendant returns the identity of the keyboard-selected row, so assistive technology follows and announces each candidate as the user arrows through the list rather than re-announcing the whole popup (pre-rebrand tracker #688). It reports nil when the selection is scrolled outside the emitted window (a wheel scroll that left the cursor behind), since a designated descendant must be a node in the reconciled tree.

func (*CompletionPopup) AccessibleLabel

func (p *CompletionPopup) AccessibleLabel() string

AccessibleLabel returns the popup's title, if any.

func (*CompletionPopup) AccessibleRole

func (p *CompletionPopup) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleList.

func (*CompletionPopup) AccessibleVirtualNodes

func (p *CompletionPopup) AccessibleVirtualNodes() []core.AccessibleVirtualNode

AccessibleVirtualNodes reports one core.RoleListItem node per suggestion in the visible window. The popup paints its rows itself (flat canvas objects, no per-row widget), so without these virtual nodes a screen reader sees only the list container. Only the scrolled-in window is emitted — the same rows the renderer lays out — matching the CompletionPopup.MaxVisibleRows windowing; the keyboard-selected row is always kept inside that window (scrollSelectionIntoView), so the active descendant is always present. The selected row carries core.StateSelected; each node's ID is a [completionRowID] so the backend can track it and resolve the active descendant (pre-rebrand tracker #801).

func (*CompletionPopup) CreateRenderer

func (p *CompletionPopup) CreateRenderer() core.WidgetRenderer

CreateRenderer is private to Bellui.

func (*CompletionPopup) FocusGained

func (p *CompletionPopup) FocusGained()

FocusGained satisfies event.Focusable; the popup needs no visual focus change.

func (*CompletionPopup) FocusLost

func (p *CompletionPopup) FocusLost()

FocusLost satisfies event.Focusable.

func (*CompletionPopup) HandleKey

func (p *CompletionPopup) HandleKey(e *event.KeyEvent) bool

HandleKey lets a focused host offer a key event to a visible popup: up/down move the selection, Enter/Tab accept, Escape dismisses and PageUp/PageDown page the documentation panel when it is showing. It reports whether the popup consumed the event; when false (including for a hidden popup) the host handles the key natively. This is the key-routing surface for CompletionPopup.KeepHostFocus hosts, and the same switch the popup's own TypedKey consumes first in the default focused model.

Since: 1.0

func (*CompletionPopup) HandlesEscape

func (p *CompletionPopup) HandlesEscape() bool

HandlesEscape reports whether Escape closes the completion list rather than the surface it is shown over. It does so whenever the list is up: the list is the innermost thing on screen.

Since: 1.0

func (*CompletionPopup) Hide

func (p *CompletionPopup) Hide()

Hide hides the popup and any open detail tooltip. A set OnMoved observes the zero rectangle, so a companion surface can dismiss with the popup no matter what hid it (Escape, an outside tap, or an accepted item).

func (*CompletionPopup) HoverIn

func (p *CompletionPopup) HoverIn(e *event.HoverEvent)

HoverIn highlights the item under the pointer.

func (*CompletionPopup) HoverMoved

func (p *CompletionPopup) HoverMoved(e *event.HoverEvent)

HoverMoved highlights the item under the pointer.

func (*CompletionPopup) HoverOut

func (p *CompletionPopup) HoverOut()

HoverOut hides the detail tooltip; the selection persists for keyboard use.

func (*CompletionPopup) Move

func (p *CompletionPopup) Move(pos geo.Position)

Move positions the popup. The position is absolute within the canvas overlay and is clamped so the popup stays on-screen. [CompletionPopup.Position] reports the final, clamped placement.

func (*CompletionPopup) Reposition

func (p *CompletionPopup) Reposition(caret geo.Rectangle)

Reposition re-anchors a visible popup to a new caret rectangle, with the same below/above flip and on-screen clamping as CompletionPopup.ShowAtCaret. Hosts call it from their scroll handler so the popup follows the caret while the content scrolls underneath; a set OnMoved observes the new placement. A no-op while the popup is hidden.

Since: 1.0

func (*CompletionPopup) Resize

func (p *CompletionPopup) Resize(size geo.Size)

Resize changes the popup size, keeping it within the canvas.

func (*CompletionPopup) Scrolled

func (p *CompletionPopup) Scrolled(e *event.ScrollEvent)

Scrolled moves the visible window over a capped list with the mouse wheel or trackpad, banking sub-row deltas so slow trackpad scrolls still add up. The selection is left where it is; a row scrolled out of the window simply loses its highlight until it returns.

Scrolled implements the event.Scrollable interface.

Since: 1.0

func (*CompletionPopup) SetItems

func (p *CompletionPopup) SetItems(items []CompletionItem)

SetItems replaces the popup's suggestions, resetting the active selection. When the popup is already showing it resizes to fit the new items, so it can be driven live as the edited text filters the list.

func (*CompletionPopup) SetTitle

func (p *CompletionPopup) SetTitle(title string)

SetTitle sets an optional header shown above the suggestions. An empty string removes the header.

func (*CompletionPopup) Show

func (p *CompletionPopup) Show()

Show makes the popup visible and gives it keyboard focus on desktop. When the popup has a host Entry it stays focused but forwards typing back to the host (see TypedKey/TypedRune), so the Entry keeps its caret and edits live. With CompletionPopup.KeepHostFocus set, focus is left untouched and the focused host drives the popup through CompletionPopup.HandleKey instead.

func (*CompletionPopup) ShowAtCaret

func (p *CompletionPopup) ShowAtCaret(caret geo.Rectangle)

ShowAtCaret shows the popup anchored to the caret rectangle (in canvas coordinates). It is placed just below the caret, flipping above it when there is not enough room beneath, so it never covers the line being typed.

func (*CompletionPopup) Tapped

func (p *CompletionPopup) Tapped(e *event.PointEvent)

Tapped accepts the item under the pointer.

func (*CompletionPopup) TypedKey

func (p *CompletionPopup) TypedKey(e *event.KeyEvent)

TypedKey drives the popup: up/down move the selection, Enter/Tab accept and Escape dismisses. Any other key is forwarded to the host Entry (backspace, cursor movement, …) so editing continues; a standalone popup instead treats Space as accept.

func (*CompletionPopup) TypedRune

func (p *CompletionPopup) TypedRune(r rune)

TypedRune forwards typed characters to the host Entry, so typing continues to edit the text (and filter the list) while the popup is open. Standalone popups ignore runes.

type ContextMenu

type ContextMenu struct {
	BaseWidget

	Content core.CanvasObject  // The wrapped widget
	Menu    *bellui.Menu       // Menu shown on right-click
	Items   []*bellui.MenuItem // Alternative: menu items (used if Menu is nil)
	// contains filtered or unexported fields
}

ContextMenu is a decorator widget that wraps any CanvasObject and shows a right-click (secondary tap) popup menu. The wrapped content receives all normal interactions (tap, hover, drag, etc.) except the right-click is intercepted to display the menu.

Since: 1.0

func NewContextMenu

func NewContextMenu(content core.CanvasObject, items ...*bellui.MenuItem) *ContextMenu

NewContextMenu creates a context menu wrapper around the given content. The provided items will be shown as a popup menu on right-click.

Since: 1.0

func NewContextMenuWithMenu

func NewContextMenuWithMenu(content core.CanvasObject, menu *bellui.Menu) *ContextMenu

NewContextMenuWithMenu creates a context menu wrapper using a pre-built bellui.Menu.

Since: 1.0

func (*ContextMenu) CreateRenderer

func (cm *ContextMenu) CreateRenderer() core.WidgetRenderer

CreateRenderer returns the renderer for the context menu.

func (*ContextMenu) Hide

func (cm *ContextMenu) Hide()

Hide hides the widget and any visible popup.

func (*ContextMenu) HoverIn

func (cm *ContextMenu) HoverIn(e *event.HoverEvent)

HoverIn delegates hover to the wrapped content.

func (*ContextMenu) HoverMoved

func (cm *ContextMenu) HoverMoved(e *event.HoverEvent)

HoverMoved delegates hover to the wrapped content.

func (*ContextMenu) HoverOut

func (cm *ContextMenu) HoverOut()

HoverOut delegates hover to the wrapped content.

func (*ContextMenu) Tapped

func (cm *ContextMenu) Tapped(e *event.PointEvent)

Tapped delegates the tap to the wrapped content.

func (*ContextMenu) TappedSecondary

func (cm *ContextMenu) TappedSecondary(pe *event.PointEvent)

TappedSecondary shows the context menu at the tap position.

type CustomTextGridStyle

type CustomTextGridStyle struct {
	// Since: 1.0
	TextStyle        bellui.TextStyle
	FGColor, BGColor color.Color
}

CustomTextGridStyle is a utility type for those not wanting to define their own style types.

func (*CustomTextGridStyle) BackgroundColor

func (c *CustomTextGridStyle) BackgroundColor() color.Color

BackgroundColor is the color a cell should use for the background.

func (*CustomTextGridStyle) Style

Style is the text style a cell should use.

func (*CustomTextGridStyle) TextColor

func (c *CustomTextGridStyle) TextColor() color.Color

TextColor is the color a cell should use for the text.

type DateEntry

type DateEntry struct {
	Entry

	// Selected is the currently selected date. Updated when a valid date is
	// typed or chosen from the popup.
	Selected time.Time
	// OnChanged is called when the selected date changes.
	OnChanged func(time.Time) `json:"-"`
	// contains filtered or unexported fields
}

DateEntry is an Entry that accepts locale-formatted dates with an optional calendar popup triggered by an action button.

Since: 1.0

func NewDateEntry

func NewDateEntry() *DateEntry

NewDateEntry creates a new DateEntry with a calendar action button and locale-aware date validation. Use the DateEntry.OnChanged field (not Entry.OnChanged) to receive parsed date values.

Since: 1.0

func (*DateEntry) CreateRenderer

func (e *DateEntry) CreateRenderer() core.WidgetRenderer

CreateRenderer returns a new renderer for this date entry.

func (*DateEntry) Date

func (e *DateEntry) Date() (time.Time, error)

Date parses the current text and returns the date, or an error if invalid.

func (*DateEntry) Disable

func (e *DateEntry) Disable()

Disable disables the entry and its action button.

func (*DateEntry) Enable

func (e *DateEntry) Enable()

Enable enables the entry and its action button.

func (*DateEntry) MinSize

func (e *DateEntry) MinSize() geo.Size

MinSize returns the minimum size.

func (*DateEntry) Move

func (e *DateEntry) Move(pos geo.Position)

Move repositions the entry and any open popup.

func (*DateEntry) Resize

func (e *DateEntry) Resize(size geo.Size)

Resize resizes the entry and repositions any open popup.

func (*DateEntry) SetDate

func (e *DateEntry) SetDate(t time.Time)

SetDate sets the entry text to the locale-formatted representation of t.

func (*DateEntry) TypedRune

func (e *DateEntry) TypedRune(r rune)

TypedRune filters characters that cannot appear in a date string.

func (*DateEntry) TypedShortcut

func (e *DateEntry) TypedShortcut(s core.Shortcut)

TypedShortcut intercepts paste to filter invalid characters.

type DatePicker

type DatePicker struct {
	BaseWidget
	Selected  time.Time
	OnChanged func(time.Time) `json:"-"`
	// contains filtered or unexported fields
}

DatePicker is an MD3-compliant date picker with a calendar grid.

Since: 1.0

func NewDatePicker

func NewDatePicker(selected time.Time, changed func(time.Time)) *DatePicker

NewDatePicker creates a new MD3 date picker.

Since: 1.0

func (*DatePicker) AccessibleLabel

func (d *DatePicker) AccessibleLabel() string

AccessibleLabel returns a localized "Select date".

func (*DatePicker) AccessibleRange

func (d *DatePicker) AccessibleRange() (min, max, current float64)

AccessibleRange is not applicable to date pickers; it returns zeros.

func (*DatePicker) AccessibleRole

func (d *DatePicker) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleGroup; the month navigation buttons inside provide their own semantics.

func (*DatePicker) AccessibleValue

func (d *DatePicker) AccessibleValue() string

AccessibleValue returns the selected date in the locale's format.

func (*DatePicker) CreateRenderer

func (d *DatePicker) CreateRenderer() core.WidgetRenderer

CreateRenderer returns a new renderer for the date picker.

func (*DatePicker) FocusGained

func (d *DatePicker) FocusGained()

FocusGained is called when the picker gains keyboard focus; the day cursor starts on the selected date (or today) in the viewing month.

func (*DatePicker) FocusLost

func (d *DatePicker) FocusLost()

FocusLost is called when the picker loses keyboard focus.

func (*DatePicker) MinSize

func (d *DatePicker) MinSize() geo.Size

MinSize returns the minimum size for the date picker.

func (*DatePicker) TypedKey

func (d *DatePicker) TypedKey(ev *event.KeyEvent)

TypedKey navigates the day grid (ARIA grid pattern): arrows move the day cursor (crossing a month boundary flips the viewing month), Home/End jump to the week edges, PageUp/PageDown move a month, Enter/Space select.

func (*DatePicker) TypedRune

func (d *DatePicker) TypedRune(rune)

TypedRune is called if a text event happens while the picker is focused.

type DateTimeEntry

type DateTimeEntry struct {
	Entry

	// Selected is the currently selected date and time.
	Selected time.Time
	// OnChanged is called when the selected datetime changes.
	OnChanged func(time.Time) `json:"-"`
	// Use24Hour controls 12h/24h mode for the time picker popup.
	// Set automatically from the locale by NewDateTimeEntry.
	Use24Hour bool
	// contains filtered or unexported fields
}

DateTimeEntry is an Entry that accepts locale-formatted date+time values with an optional picker popup triggered by an action button.

Since: 1.0

func NewDateTimeEntry

func NewDateTimeEntry() *DateTimeEntry

NewDateTimeEntry creates a new DateTimeEntry with a picker action button. The 12h/24h mode is auto-detected from the current locale. NewDateTimeEntry creates a new DateTimeEntry with a picker action button. The 12h/24h mode is auto-detected from the current locale. Use the DateTimeEntry.OnChanged field (not Entry.OnChanged) to receive parsed values.

Since: 1.0

func (*DateTimeEntry) CreateRenderer

func (e *DateTimeEntry) CreateRenderer() core.WidgetRenderer

CreateRenderer returns a new renderer for this datetime entry.

func (*DateTimeEntry) DateTime

func (e *DateTimeEntry) DateTime() (time.Time, error)

DateTime parses the current text and returns the datetime, or an error.

func (*DateTimeEntry) Disable

func (e *DateTimeEntry) Disable()

Disable disables the entry and its action button.

func (*DateTimeEntry) Enable

func (e *DateTimeEntry) Enable()

Enable enables the entry and its action button.

func (*DateTimeEntry) MinSize

func (e *DateTimeEntry) MinSize() geo.Size

MinSize returns the minimum size.

func (*DateTimeEntry) Move

func (e *DateTimeEntry) Move(pos geo.Position)

Move repositions the entry and any open popup.

func (*DateTimeEntry) Resize

func (e *DateTimeEntry) Resize(size geo.Size)

Resize resizes the entry and repositions any open popup.

func (*DateTimeEntry) SetDateTime

func (e *DateTimeEntry) SetDateTime(t time.Time)

SetDateTime sets the entry text to the locale-formatted representation of t.

func (*DateTimeEntry) TypedRune

func (e *DateTimeEntry) TypedRune(r rune)

TypedRune filters characters that cannot appear in a datetime string. Lowercase AM/PM letters are accepted and uppercased during validation.

func (*DateTimeEntry) TypedShortcut

func (e *DateTimeEntry) TypedShortcut(s core.Shortcut)

TypedShortcut intercepts paste to filter invalid characters.

type DateTimePicker

type DateTimePicker struct {
	BaseWidget
	Selected  time.Time
	OnChanged func(time.Time) `json:"-"`
	Use24Hour bool
	// contains filtered or unexported fields
}

DateTimePicker combines DatePicker and TimePicker in a tabbed interface.

Since: 1.0

func NewAutoDateTimePicker

func NewAutoDateTimePicker(selected time.Time, changed func(time.Time)) *DateTimePicker

NewAutoDateTimePicker creates a combined date+time picker that auto-detects 12h/24h mode from the current locale.

Since: 1.0

func NewDateTimePicker

func NewDateTimePicker(selected time.Time, use24h bool, changed func(time.Time)) *DateTimePicker

NewDateTimePicker creates a new combined date+time picker.

Since: 1.0

func (*DateTimePicker) AccessibleLabel

func (dt *DateTimePicker) AccessibleLabel() string

AccessibleLabel returns a localized "Select date & time".

func (*DateTimePicker) AccessibleRange

func (dt *DateTimePicker) AccessibleRange() (min, max, current float64)

AccessibleRange is not applicable to date+time pickers; it returns zeros.

func (*DateTimePicker) AccessibleRole

func (dt *DateTimePicker) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleGroup; the embedded date and time pickers provide their own semantics.

func (*DateTimePicker) AccessibleValue

func (dt *DateTimePicker) AccessibleValue() string

AccessibleValue returns the selected date and time in the locale's format.

func (*DateTimePicker) CreateRenderer

func (dt *DateTimePicker) CreateRenderer() core.WidgetRenderer

CreateRenderer returns a new renderer for the date+time picker.

func (*DateTimePicker) MinSize

func (dt *DateTimePicker) MinSize() geo.Size

MinSize returns the minimum size for the date+time picker.

type DisableableWidget

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

DisableableWidget describes an extension to BaseWidget which can be disabled. Disabled widgets should have a visually distinct style when disabled, normally using theme.DisabledButtonColor.

func (*DisableableWidget) Disable

func (w *DisableableWidget) Disable()

Disable this widget so that it cannot be interacted with, updating any style appropriately.

func (*DisableableWidget) Disabled

func (w *DisableableWidget) Disabled() bool

Disabled returns true if this widget is currently disabled or false if it can currently be interacted with.

func (*DisableableWidget) Enable

func (w *DisableableWidget) Enable()

Enable this widget, updating any style or features appropriately.

type Entry

type Entry struct {
	DisableableWidget

	Text string
	// Since: 1.0
	TextStyle bellui.TextStyle
	// Alignment sets the horizontal alignment of the entry text.
	// Defaults to bellui.TextAlignLeading (left).
	Alignment bellui.TextAlign
	// Style sets the MD3 visual variant (Filled or Outlined).
	Style       EntryStyle
	PlaceHolder string
	OnChanged   func(string) `json:"-"`

	// OnSubmitted will be called when the user presses Enter/Return (for a single line entry).
	// MultiLine entries will be submitted when Shift+Enter (or Return) are pressed.
	//
	// Since: 1.0
	OnSubmitted func(string) `json:"-"`

	// OnEscape will be called when the user presses Escape while the entry is
	// focused — the cancel counterpart of OnSubmitted, letting a host dismiss
	// an inline editor (pre-rebrand tracker #1052). An in-progress IME composition keeps
	// precedence: Escape discards the composition (pre-rebrand tracker #354) and reaches this
	// hook only once no composition is pending. Nil ignores the key.
	//
	// Since: 1.0
	OnEscape  func() `json:"-"`
	Password  bool
	MultiLine bool
	Wrapping  bellui.TextWrap

	// ReadOnly prevents text editing while keeping full visual styling
	// (no dimming) and allowing text selection, copy, and navigation.
	// Unlike Disable(), read-only entries are focusable and selectable.
	//
	// Since: 1.0
	ReadOnly bool

	// DeferTextSync, when true, defers synchronising the exported Text field
	// after each edit. By default every keystroke materializes the whole
	// document into Text and hands it to OnChanged, the Validator and any
	// bound value — one allocation and copy of the full document per edit,
	// the dominant per-keystroke cost once documents reach tens of megabytes.
	// With this mode on, edits update only the internal buffer (rendering,
	// caret, selection and SelectedText always reflect the live content) and
	// Text is refreshed at sync points instead: [Entry.SyncText], focus loss,
	// and Enter/Return submission (before OnSubmitted fires). OnChanged, the
	// Validator and binding writes run once per sync point — with the full
	// current text — rather than per keystroke.
	//
	// Between sync points a direct read of the Text field returns the text as
	// of the last sync (Go cannot intercept field reads); call SyncText to
	// obtain the current text. Writing Text directly while edits are pending
	// discards those edits. The mode only takes effect on the multi-line
	// single-style fast path (no folds); elsewhere edits keep the default
	// per-keystroke behavior. Off by default — the default behavior is
	// unchanged.
	//
	// Since: 1.0
	DeferTextSync bool

	// Scroll can be used to turn off the scrolling of our entry when Wrapping is WrapNone.
	//
	// Since: 1.0
	Scroll bellui.ScrollDirection

	// Set a validator that this entry will check against
	// Since: 1.0
	Validator bellui.StringValidator `json:"-"`

	// If true, the Validator runs automatically on render without user interaction.
	// It will reflect any validation errors found or those explicitly set via SetValidationError().
	// Since: 1.0
	AlwaysShowValidationError bool

	// ValidateWithBorder, when true, shows validation errors via a thicker red
	// border instead of the check/error icon. The icon is hidden and no extra
	// space is reserved for it. Useful for compact widgets like SpinBox.
	ValidateWithBorder bool

	CursorRow, CursorColumn int

	OnCursorChanged func() `json:"-"`

	// LineHighlighter, when set, provides per-line syntax highlighting.
	// It receives a line of text and a state value (0 = initial/clear).
	// It returns styled runs for the line and the state at the end of
	// the line (to feed into the next line). The Entry caches the output
	// and only re-highlights lines affected by edits. It must be a pure
	// function of (line, state): the cache replays recorded states to skip
	// unchanged stretches of the document.
	//
	// Cost model for large documents: highlighting is computed for the
	// visible window on demand, and state chains strictly forward — the one
	// full chain is the first jump deep into freshly-set content (e.g.
	// restoring a scroll position after SetText), which must run the
	// highlighter from line 0 up to the viewport once. After SetText that
	// chain is prefilled in the background in per-frame time slices (pre-rebrand tracker #417),
	// so a deep jump only pays synchronously for the gap the prefill has not
	// reached yet. Edits stay cheap even far above the viewport: re-chaining
	// stops as soon as the state converges back into the already-highlighted
	// stretch (pre-rebrand tracker #412).
	//
	// Since: 1.0
	LineHighlighter func(line string, state int) ([]StyleRun, int) `json:"-"`

	// StyleOverlayForRow, when set, supplies additional per-row style runs
	// composited over the LineHighlighter output for that display row — e.g.
	// foreground for LSP semantic tokens computed from a whole-document
	// analysis, which the line-at-a-time LineHighlighter cannot express. It is
	// called at render time for the rows the renderer materialises (the
	// visible window on large documents); return nil for rows with no overlay.
	//
	// The returned runs tile the row from its first rune: each run covers
	// len([]rune(run.Text)) runes of the row and only that length is used —
	// the overlay never changes the text. A zero-valued run is a spacer
	// leaving its range unstyled, so a sparse overlay is spacer/token/spacer/
	// token, and the tiling may stop short of the row end (anything past it is
	// ignored). Over a covered range, a non-nil ForegroundColor or non-empty
	// ColorName replaces the base run's foreground as a unit; Bold/Italic only
	// ever switch on; a non-nil BackgroundColor replaces the base background;
	// Underline true carries UnderlineStyle and UnderlineColor with it. Unset
	// overlay fields keep the base run's values, so a semantic foreground
	// overrides lexical color without clobbering bold or an existing squiggle.
	//
	// The overlay is pure composition: it never feeds the LineHighlighter
	// state chain and never invalidates the highlight cache, so Refresh() on
	// new overlay data repaints without re-lexing. While an IME composition is
	// active the preedit is spliced into its display row — overlay offsets on
	// that one row are shifted until commit — and the preedit underline is
	// drawn over the overlay.
	//
	// Since: 1.0
	StyleOverlayForRow func(row int) []StyleRun `json:"-"`

	// Icon is displayed at the outer left of the entry.
	// It is not clickable, but can be used to indicate the purpose of the entry.
	// Since: 1.0
	Icon bellui.Resource `json:"-"`

	// OnGutterTap is called when the user clicks in the line number gutter.
	// The callback receives the 1-based line number that was clicked.
	// Only fires when ShowLineNumbers is active (i.e., LineHighlighter is set).
	OnGutterTap func(line int) `json:"-"`

	// BreakpointLines is the set of 1-based line numbers where breakpoint
	// markers (red dots) should be rendered in the gutter.
	BreakpointLines map[int]bool `json:"-"`

	// HighlightedRow is the 1-based line number to highlight with a
	// background color (e.g., current execution line in a debugger).
	// Set to 0 to disable.
	HighlightedRow int `json:"-"`

	// KeepSelectionVisible, when true, keeps the text selection highlight
	// visible even when the entry loses focus.
	KeepSelectionVisible bool `json:"-"`

	// OnScrolled is called when the Entry's internal scroll offset changes.
	// The position reports the current scroll offset (X and Y in pixels).
	// Useful for synchronising external widgets (e.g. a pinned gutter)
	// with the Entry's vertical scroll position.
	//
	// Since: 1.0
	OnScrolled func(geo.Position) `json:"-"`

	// SuppressGutter disables the built-in line number gutter and breakpoint
	// rendering even when LineHighlighter is set. Syntax highlighting still
	// works; only the gutter is suppressed. Use this when an external gutter
	// widget is managing line numbers and breakpoints.
	//
	// Since: 1.0
	SuppressGutter bool `json:"-"`

	// HiddenRanges are logical-line ranges (0-based, inclusive Start, exclusive
	// End) the Entry lays out and paints as if absent — code folding. Text(),
	// the cursor model and search positions are unaffected; only rendering and
	// vertical geometry skip them, so a folded region collapses to zero height.
	// RowPositions/RowMetrics report visible-row geometry, the scroll extent
	// shrinks by the folded height, and caret navigation skips folded rows.
	// Ranges past the end of the document are clamped/ignored. Empty == today's
	// behavior. Composes with row virtualisation (pre-rebrand tracker #119).
	//
	// Ranges are in logical lines (newline-delimited), not visual rows. When a
	// logical line wraps to several visual rows, folding that line hides all of
	// its wrapped rows (pre-rebrand tracker #145). For wrap-off content a line is a single row, so
	// the two coincide.
	//
	// Since: 1.0
	HiddenRanges []LineRange `json:"-"`

	// OnSelectChanged is called whenever the text selection changes.
	// The callback receives the currently selected text (empty string when
	// the selection is cleared).
	OnSelectChanged func(string) `json:"-"`

	// BeforeChange, when set, is consulted before every text mutation. It
	// receives sel, the range being replaced (rune offsets into Text), and
	// next, the proposed replacement text for that range. Returning false
	// vetoes the change, leaving Text, the cursor and the undo stack untouched.
	// It fires for every interactive edit path: typing, IME commit, paste, cut,
	// delete, backspace, word-delete, newline and programmatic
	// select-and-overwrite. A nil hook imposes no restriction. The
	// whole-document resets SetText and Append are not gated.
	//
	// Since: 1.0
	BeforeChange func(sel TextRange, next string) bool `json:"-"`

	// ProtectedRanges are spans the Entry refuses to mutate. An edit overlapping
	// any range is rejected across every edit path, so a vetoed edit never
	// reaches the undo stack and cannot be re-introduced by undo/redo. A range
	// with CaretOpaque set additionally bars the caret from entering it (arrow
	// navigation, clicks and mobile taps skip over it). Offsets are rune indices
	// into Text; the caller owns reconciliation when Text changes.
	// An empty (nil) slice is exactly today's behavior.
	//
	// Protection gates new interactive edits only. Undo and Redo replay the
	// recorded document history verbatim and are not re-gated against
	// ProtectedRanges, so undoing an older legitimate edit can reconstruct text
	// that overlaps a range protected after that edit was recorded. Treat
	// ProtectedRanges as caller-managed view state reconciled alongside history.
	//
	// Since: 1.0
	ProtectedRanges []ProtectedRange `json:"-"`

	// ActionItem is a small item which is displayed at the outer right of the entry (like a password revealer)
	ActionItem core.CanvasObject `json:"-"`

	// OnCompletionSelected is called when the user accepts an item from a
	// completion popup shown via ShowCompletion.
	OnCompletionSelected func(CompletionItem)
	// contains filtered or unexported fields
}

func NewEntry

func NewEntry() *Entry

NewEntry creates a new single line entry widget.

func NewEntryWithData

func NewEntryWithData(data binding.String) *Entry

NewEntryWithData returns an Entry widget connected to the specified data source.

Since: 1.0

func NewMultiLineEntry

func NewMultiLineEntry() *Entry

NewMultiLineEntry creates a new entry that allows multiple lines

func NewPasswordEntry

func NewPasswordEntry() *Entry

NewPasswordEntry creates a new entry password widget

func (*Entry) AcceptsTab

func (e *Entry) AcceptsTab() bool

AcceptsTab returns if Entry accepts the Tab key or not.

Since: 1.0

func (*Entry) AccessibleActions

func (e *Entry) AccessibleActions() []core.AccessibleAction

AccessibleActions declares the entry's undo/redo actions so assistive technology can reach them without the long-press context menu (pre-rebrand tracker #1025) — they have no standard platform action, so backends surface them as custom actions (VoiceOver's actions rotor, TalkBack's actions menu, AT-SPI Action). Gated on availability like the context menu: none while read-only or on a password field, and each direction only while its history is non-empty. Cut/copy/paste/select-all are not declared here — they travel through the standard editable-text protocols instead.

func (*Entry) AccessibleCaret

func (e *Entry) AccessibleCaret() int

AccessibleCaret returns the rune offset of the insertion point.

func (*Entry) AccessibleComposing

func (e *Entry) AccessibleComposing() bool

AccessibleComposing reports whether an IME composition is currently active (a preedit is being shown — including an empty one). The text-input mirror seam matches this method structurally to recognize a stale composition finalize (pre-rebrand tracker #1057): a hardware keystroke commits the preedit as typed text (see TypedKey's desktop-commit path), so an IME commit arriving after that would insert content the document already holds.

func (*Entry) AccessibleConcealed

func (e *Entry) AccessibleConcealed() bool

AccessibleConcealed reports whether this entry conceals its content, i.e. it is a password field. Semantic auto-capture (see core.AccessibleConcealed) excludes concealed entries wholesale.

func (*Entry) AccessibleLabel

func (e *Entry) AccessibleLabel() string

AccessibleLabel returns the placeholder text as the accessible name.

func (*Entry) AccessibleLineCount

func (e *Entry) AccessibleLineCount() int

AccessibleLineCount returns the number of visual (soft-wrapped) lines of the laid-out content (see core.AccessibleTextLayouter).

func (*Entry) AccessibleLineForOffset

func (e *Entry) AccessibleLineForOffset(off int) int

AccessibleLineForOffset returns the zero-based visual line containing the rune offset, clamped to the content (see core.AccessibleTextLayouter).

func (*Entry) AccessibleLineRange

func (e *Entry) AccessibleLineRange(line int) (start, end int, ok bool)

AccessibleLineRange returns the half-open rune range of the zero-based visual line (see core.AccessibleTextLayouter): end is the start of the following line — covering a terminating newline or the soft-wrap boundary — or the content length on the last line.

func (*Entry) AccessiblePreedit

func (e *Entry) AccessiblePreedit() (text string, start int, ok bool)

AccessiblePreedit reports the in-progress IME preedit and the rune offset where it is spliced into Entry.AccessibleText; ok is false while no preedit is shown. The text-input mirror seam matches this method structurally to subtract the preedit from its pushes, so the native IME buffer is only ever seeded with committed text (pre-rebrand tracker #1057) — Entry, unlike RichEntry, splices the preedit through its provider, so the accessible text alone cannot tell committed from composing runes.

func (*Entry) AccessibleRange

func (e *Entry) AccessibleRange() (min, max, current float64)

AccessibleRange is not applicable to text entries; it returns zeros.

func (*Entry) AccessibleRangeBounds

func (e *Entry) AccessibleRangeBounds(start, end int) []geo.Rectangle

AccessibleRangeBounds returns one rectangle per visible visual line touched by the rune range, in the Entry's own coordinate space adjusted for its scroll offset — the same space as Entry.PreeditCursorRectangle (see core.AccessibleTextLayouter). Lines scrolled out of the viewport are omitted, so the work and the result stay bounded by the viewport no matter how large the range: the first visible row is found by binary search over the (monotonically increasing) row tops, and the walk stops at the first row below the fold. Each rectangle spans the caret rectangles at the range's endpoints within that row — an approximation on bidirectional rows, where reordered runs may extend past the endpoint span.

func (*Entry) AccessibleRole

func (e *Entry) AccessibleRole() core.AccessibleRole

AccessibleRole returns the appropriate text input role based on the entry's configuration (password, multi-line, or standard text box).

func (*Entry) AccessibleSelection

func (e *Entry) AccessibleSelection() (start, end int)

AccessibleSelection returns the selection as a half-open rune range; when nothing is selected both offsets are the caret position.

func (*Entry) AccessibleState

func (e *Entry) AccessibleState() core.AccessibleState

AccessibleState returns the disabled and read-only state.

func (*Entry) AccessibleText

func (e *Entry) AccessibleText() string

AccessibleText returns the text assistive technology reads and navigates (see core.AccessibleTexter). It reflects the live content — ahead of the Text field under Entry.DeferTextSync — so offsets agree with the caret and selection. Password entries return the mask characters, never the secret; the rune length still matches.

func (*Entry) AccessibleValue

func (e *Entry) AccessibleValue() string

AccessibleValue returns the current text. For password entries it returns an empty string to avoid exposing sensitive input.

func (*Entry) AddShortcut

func (e *Entry) AddShortcut(shortcut core.Shortcut, handler func(core.Shortcut))

AddShortcut registers a handler for a keyboard shortcut on this Entry. The handler fires via TypedShortcut when the Entry has focus.

func (*Entry) Append

func (e *Entry) Append(text string)

Append appends the text to the end of the entry.

Since: 1.0

func (*Entry) ApplyEdits

func (e *Entry) ApplyEdits(edits []TextEdit) bool

ApplyEdits applies a set of splices to the entry's content as one atomic edit: a single undo/redo step, one Validator run and one OnChanged call (one sync point under Entry.DeferTextSync). It is the primitive for multi-region operations — block indent/dedent, replace-all — that must not fragment into per-splice undo steps the way sequential edits do.

All offsets are rune indices into the content as it is before the batch; edits are applied in one pass, so no edit observes another's shift. The ranges may be given in any order but must not overlap (edits touching at an endpoint are fine, and insertions sharing an offset keep their given order). Every edit is gated through Entry.ProtectedRanges and Entry.BeforeChange before anything is applied: one veto rejects the whole batch, so a partial application can never be observed. Out-of-range offsets are clamped.

It reports whether the batch was applied — false for a read-only or disabled entry, an empty or all-no-op batch, overlapping ranges, or a vetoed edit. Afterwards any selection is cleared and the caret sits at the end of the last edit's replacement text. Any in-progress IME composition is cancelled first. It is safe to call from any goroutine.

Since: 1.0

func (*Entry) Bind

func (e *Entry) Bind(data binding.String)

Bind connects the specified data source to this Entry. The current value will be displayed and any changes in the data will cause the widget to update. User interactions with this Entry will set the value into the data source.

The public Entry.Validator field is left alone: the data-binding conversion check is composed with it rather than replacing it, so binding a validated Entry keeps the app's rule and Validator may be assigned before or after Bind. A conversion error wins over the app's rule -- text that cannot be written to the bound source is invalid whatever the app's rule says about it.

Since: 1.0

func (*Entry) CaretRect

func (e *Entry) CaretRect(row, col int) geo.Rectangle

CaretRect returns the pixel rectangle of the caret at the logical position (row, col), in the Entry's content coordinate space (pre-scroll). The rectangle's Pos is the top-left of the caret cell (matching the position of the live cursor as returned by Entry.CursorPosition); its width is one character cell and its height is the row height.

A zero geo.Rectangle is returned when (row, col) is out of range. Callers that render outside the scroll viewport (e.g. an anchored popover or a span decoration) should subtract the current scroll offset and treat positions outside the viewport as hidden.

Since: 1.0

func (*Entry) Compose

func (e *Entry) Compose(ev *event.PreeditEvent)

Compose sets or replaces the inline IME preedit (composition) text shown at the caret. It does not modify Text, fire OnChanged, touch the undo stack or write to a bound value — only ComposeCommit does. An empty PreeditEvent.Text clears the visible preedit without committing.

Compose implements the event.Composable interface; platform drivers call it while an input method is composing.

Since: 1.0

func (*Entry) ComposeCancel

func (e *Entry) ComposeCancel()

ComposeCancel discards any in-progress IME composition without committing, restoring the caret to where composition began. Text is untouched.

ComposeCancel implements the event.Composable interface.

Since: 1.0

func (*Entry) ComposeCommit

func (e *Entry) ComposeCommit(text string)

ComposeCommit finalizes an IME composition, inserting text as if it had been typed: Text, the undo history and OnChanged are all updated as a single edit. An empty string commits nothing and behaves like ComposeCancel.

ComposeCommit implements the event.Composable interface.

Since: 1.0

func (*Entry) CreateRenderer

func (e *Entry) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*Entry) Cursor

func (e *Entry) Cursor() desktop.Cursor

Cursor returns the cursor type of this widget. Returns the default pointer over the gutter, I-beam over text.

func (*Entry) CursorPosition

func (e *Entry) CursorPosition() geo.Position

CursorPosition returns the relative position of this Entry widget's cursor.

Since: 1.0

func (*Entry) CursorTextOffset

func (e *Entry) CursorTextOffset() (pos int)

CursorTextOffset returns how many runes into the source text the cursor is positioned at.

Since: 1.0

func (*Entry) DoubleTapped

func (e *Entry) DoubleTapped(_ *event.PointEvent)

DoubleTapped is called when this entry has been double tapped so we should select text below the pointer

func (*Entry) DragEnd

func (e *Entry) DragEnd()

DragEnd is called at end of a drag event.

func (*Entry) Dragged

func (e *Entry) Dragged(d *event.DragEvent)

Dragged is called when the pointer moves while a button is held down. It updates the selection accordingly.

func (*Entry) ExtendBaseWidget

func (e *Entry) ExtendBaseWidget(wid core.Widget)

ExtendBaseWidget is used by an extending widget to make use of BaseWidget functionality.

func (*Entry) FocusGained

func (e *Entry) FocusGained()

FocusGained is called when the Entry has been given focus.

func (*Entry) FocusLost

func (e *Entry) FocusLost()

FocusLost is called when the Entry has had focus removed.

func (*Entry) HandlesEscape

func (e *Entry) HandlesEscape() bool

HandlesEscape reports whether Escape belongs to this entry rather than to the pop-up or dialog around it: while an IME composition is in flight there is a composition to reject, and a host that set OnEscape has its own meaning for the key. Otherwise Escape falls through and closes the surface the entry sits in.

Since: 1.0

func (*Entry) Hide

func (e *Entry) Hide()

Hide hides the entry.

func (*Entry) HideCompletion

func (e *Entry) HideCompletion()

HideCompletion hides the completion popup if one is showing.

Since: 1.0

func (*Entry) HighlightRunsForRow

func (e *Entry) HighlightRunsForRow(row int) []StyleRun

HighlightRunsForRow returns the styled runs for a given row index. Returns nil if no highlighter is active or the row is out of range. The gutter/highlighter path runs wrap-off, so visual rows and logical lines coincide; in the lazy model the requested row is highlighted on demand.

func (*Entry) InsertText

func (e *Entry) InsertText(text string)

InsertText inserts text at the caret as one edit, exactly as if it had been typed in a single action: any active selection is replaced, the edit is gated through Entry.ProtectedRanges and Entry.BeforeChange, recorded in the undo history and OnChanged fires once. It is the exported form of the primitive behind TypedRune and IME commit — use it instead of routing programmatic inserts through Entry.ComposeCommit. Any in-progress IME composition is cancelled first; its preedit is uncommitted display state, discarded like on any other programmatic write. A no-op for read-only or disabled entries and for an empty string. It is safe to call from any goroutine.

Since: 1.0

func (*Entry) IntrinsicSize

func (e *Entry) IntrinsicSize() geo.Size

IntrinsicSize reports the natural extent of the entry's text measured as if Wrapping and Truncation were off, plus padding — mirroring RichText.IntrinsicSize (an Entry embeds a RichText) for content autosizing. For a wrapping entry the embedded text's min width collapses to ~0, so use IntrinsicSize to size the entry (or a container around it) to its content. It measures the text only; the entry's own chrome (border, scrollbars) is not added.

Since: 1.0

func (*Entry) KeyDown

func (e *Entry) KeyDown(key *event.KeyEvent)

KeyDown handler for keypress events - used to store shift modifier state for text selection

func (*Entry) KeyUp

func (e *Entry) KeyUp(key *event.KeyEvent)

KeyUp handler for key release events - used to reset shift modifier state for text selection

func (*Entry) Keyboard

func (e *Entry) Keyboard() mobile.KeyboardType

Keyboard implements the Keyboardable interface

func (*Entry) LineCount

func (e *Entry) LineCount() int

LineCount returns the number of logical (newline-delimited) lines in the entry's content; an empty entry has one line. Under Entry.DeferTextSync it reflects the live buffer, not the possibly-stale Text field, so a host can size its gutter or scroll model against a deferred entry without forcing a materialization. O(1) on the lazy single-segment path (the buffer keeps a line index); O(content) otherwise.

Since: 1.0

func (*Entry) LongPressed

func (e *Entry) LongPressed(ev *event.PointEvent)

LongPressed implements event.LongPressable. A touch held on the entry selects the word under the finger, the native mobile gesture (pre-rebrand tracker #758); the release that follows opens the context menu via TappedSecondary. Desktop right-click is unaffected (it dispatches TappedSecondary directly).

func (*Entry) MinSize

func (e *Entry) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below.

func (*Entry) MouseDown

func (e *Entry) MouseDown(m *desktop.MouseEvent)

MouseDown called on mouse click, this triggers a mouse click which can move the cursor, update the existing selection (if shift is held), or start a selection dragging operation.

func (*Entry) MouseUp

func (e *Entry) MouseUp(m *desktop.MouseEvent)

MouseUp called on mouse release If a mouse drag event has completed then check to see if it has resulted in an empty selection, if so, and if a text select key isn't held, then disable selecting

func (*Entry) PerformAccessibleAction

func (e *Entry) PerformAccessibleAction(name string)

PerformAccessibleAction invokes the named accessible action.

func (*Entry) PreeditCursorRectangle

func (e *Entry) PreeditCursorRectangle() geo.Rectangle

PreeditCursorRectangle reports the caret rectangle in the Entry's content coordinate space (adjusted for the current scroll offset) so a driver can position the IME candidate window. It implements event.PreeditPositioner.

Since: 1.0

func (*Entry) Redo

func (e *Entry) Redo()

Redo un-does the last undo action.

Like Entry.Undo, Redo replays recorded history verbatim and is not re-gated against Entry.ProtectedRanges.

Since: 1.0

func (*Entry) RefreshGutter

func (e *Entry) RefreshGutter()

RefreshGutter redraws the gutter (breakpoint markers, highlighted row) without scrolling to the cursor position. Use this instead of Refresh() when only gutter visuals have changed.

func (*Entry) ReplaceAccessibleSelection

func (e *Entry) ReplaceAccessibleSelection(text string)

ReplaceAccessibleSelection replaces the current selection — or inserts at the caret — as one gated, undo-recorded edit (the Entry.ApplyEdits path: one OnChanged, one Validator run). A no-op for read-only or disabled entries. It is safe to call from any goroutine.

func (*Entry) RowMetrics

func (e *Entry) RowMetrics() (topOffset, stride float32)

RowMetrics returns the Y offset of the first text row and the vertical stride between consecutive rows. External widgets (such as a pinned gutter or row decorator overlay) use these values to align with the Entry's text content.

After the first layout pass the values come from the cached RichText geometry and are exact. Before layout a theme-derived fallback is used.

Since: 1.0

func (*Entry) RowPositions

func (e *Entry) RowPositions() (yPositions []float32, heights []float32)

RowPositions returns the exact Y position and height for each row, as computed during the last layout pass. External gutter and decorator widgets should prefer these over RowMetrics to avoid floating-point drift on long documents.

Returns nil before the first layout pass.

Since: 1.0

func (*Entry) Select

func (e *Entry) Select(startRow, startCol, endRow, endCol int)

Select programmatically selects text from (startRow, startCol) to (endRow, endCol). Coordinates are 0-based. The cursor is placed at the end of the selection. Out-of-range values are clamped to valid bounds.

func (*Entry) SelectedText

func (e *Entry) SelectedText() string

SelectedText returns the text currently selected in this Entry. If there is no selection it will return the empty string.

func (*Entry) SelectionRange

func (e *Entry) SelectionRange() (r TextRange, ok bool)

SelectionRange returns the current selection as a half-open rune range [Start, End) into the entry's content, normalized so Start <= End. ok is false when nothing is selected. The caret always sits at one end of the range; compare Entry.CursorTextOffset against Start and End to recover which end is the anchor.

Since: 1.0

func (*Entry) SetAccessibleSelection

func (e *Entry) SetAccessibleSelection(start, end int)

SetAccessibleSelection selects [start, end), clamped to the content; equal offsets place the caret there with no selection. It is safe to call from any goroutine.

func (*Entry) SetIcon

func (e *Entry) SetIcon(res bellui.Resource)

SetIcon sets the leading icon resource for the entry. The icon will be displayed at the outer left of the entry, but is not clickable. This can be used to indicate the purpose of the entry, such as an email or password field.

Since: 1.0

func (*Entry) SetMinRowsVisible

func (e *Entry) SetMinRowsVisible(count int)

SetMinRowsVisible forces a multi-line entry to show `count` number of rows without scrolling. This is not a validation or requirement, it just impacts the minimum visible size. Use this carefully as Bellui apps can run on small screens so you may wish to add a scroll container if this number is high. Default is 3.

Since: 1.0

func (*Entry) SetOnValidationChanged

func (e *Entry) SetOnValidationChanged(callback func(error))

SetOnValidationChanged is intended for parent widgets or containers to hook into the validation. The function might be overwritten by a parent that cares about child validation (e.g. widget.Form).

func (*Entry) SetPlaceHolder

func (e *Entry) SetPlaceHolder(text string)

SetPlaceHolder sets the text that will be displayed if the entry is otherwise empty. It is safe to call from any goroutine.

func (*Entry) SetText

func (e *Entry) SetText(text string)

SetText manually sets the text of the Entry to the given text value. Calling SetText resets all undo history. It is safe to call from any goroutine.

func (*Entry) SetValidationError

func (e *Entry) SetValidationError(err error)

SetValidationError manually updates the validation status until the next input change.

func (*Entry) ShowCompletion

func (e *Entry) ShowCompletion(title string, items []CompletionItem)

ShowCompletion displays an application-driven completion popup anchored at the Entry's caret. The optional title is shown as a header above the items; pass an empty string for no header. When the user accepts an item (Enter, Space or tap), OnCompletionSelected is called. Passing no items hides any open popup.

The popup is placed just below the caret line, flipping above it when there is not enough room beneath, so it never covers the text being edited. It is the caller's responsibility to refresh or hide the popup as the edited text changes (for example from OnChanged).

This is for app-level suggestions (history, snippets, language-server completions). It is separate from the platform IME candidate window, which the operating system renders and positions itself.

Since: 1.0

func (*Entry) SyncState

func (e *Entry) SyncState()

SyncState syncs Entry's public fields to internal rendering state. Called automatically by BaseWidget.Refresh() before the renderer refreshes.

func (*Entry) SyncText

func (e *Entry) SyncText() string

SyncText returns the entry's current text, first synchronising any edits the Entry.DeferTextSync mode left pending: the Text field is refreshed and, if the text changed since the last sync point, the Validator, OnChanged and any bound value observe it now. When the mode is off (the default) Text is always current and SyncText simply returns it. It is safe to call from any goroutine.

Since: 1.0

func (*Entry) Tapped

func (e *Entry) Tapped(ev *event.PointEvent)

Tapped is called when this entry has been tapped. We update the cursor position in device-specific callbacks (MouseDown() and TouchDown()).

func (*Entry) TappedSecondary

func (e *Entry) TappedSecondary(pe *event.PointEvent)

TappedSecondary is called when right or alternative tap is invoked.

Opens the PopUpMenu with `Paste` item to paste text from the clipboard.

func (*Entry) TouchCancel

func (e *Entry) TouchCancel(*mobile.TouchEvent)

TouchCancel is called when this entry gets a touch cancel event on mobile device (app was removed from focus).

Since: 1.0

func (*Entry) TouchDown

func (e *Entry) TouchDown(ev *mobile.TouchEvent)

TouchDown is called when this entry gets a touch down event on mobile device, we ensure we have focus.

Since: 1.0

func (*Entry) TouchUp

func (e *Entry) TouchUp(*mobile.TouchEvent)

TouchUp is called when this entry gets a touch up event on mobile device.

Since: 1.0

func (*Entry) TypedKey

func (e *Entry) TypedKey(key *event.KeyEvent)

func (*Entry) TypedRune

func (e *Entry) TypedRune(r rune)

func (*Entry) TypedShortcut

func (e *Entry) TypedShortcut(shortcut core.Shortcut)

TypedShortcut implements the Shortcutable interface

func (*Entry) Unbind

func (e *Entry) Unbind()

Unbind disconnects any configured data source from this Entry. The current value will remain at the last value of the data source.

Any Entry.Validator the app installed is left in place -- Unbind only drops the data-binding conversion check it installed itself.

Since: 1.0

func (*Entry) Undo

func (e *Entry) Undo()

Undo un-does the last modifying user-action.

Undo replays the recorded document history verbatim; it is not re-gated against Entry.ProtectedRanges, so it may reconstruct text overlapping a range protected after the undone edit was recorded. Protection applies to new interactive edits, not history replay.

Since: 1.0

func (*Entry) Unselect

func (e *Entry) Unselect()

Unselect clears the current text selection, if any, leaving the cursor where it is. When a non-empty selection was cleared, OnSelectChanged fires with the empty string. It is a no-op when nothing is selected.

Since: 1.0

func (*Entry) Validate

func (e *Entry) Validate() error

Validate validates the current text in the widget.

type EntryStyle

type EntryStyle int

EntryStyle determines the visual variant of an entry field.

const (
	// EntryStyleFilled is the default entry style with a visible background fill.
	EntryStyleFilled EntryStyle = iota
	// EntryStyleOutlined has no fill, with a visible border around all edges.
	EntryStyleOutlined
)

type FAB

type FAB struct {
	DisableableWidget
	Icon     bellui.Resource
	Text     string // empty = regular FAB, non-empty = Extended FAB
	Style    FABStyle
	OnTapped func() `json:"-"`
	// contains filtered or unexported fields
}

FAB is a Material Design 3 Floating Action Button. Set Text for an Extended FAB (icon + label), leave empty for a standard FAB (icon only).

func NewExtendedFAB

func NewExtendedFAB(text string, icon bellui.Resource, tapped func()) *FAB

NewExtendedFAB creates an extended FAB with icon and label.

func NewFAB

func NewFAB(icon bellui.Resource, tapped func()) *FAB

NewFAB creates a standard (icon-only) FAB.

func (*FAB) AccessibleActions

func (f *FAB) AccessibleActions() []core.AccessibleAction

AccessibleActions returns the "press" action.

func (*FAB) AccessibleLabel

func (f *FAB) AccessibleLabel() string

AccessibleLabel returns the FAB text (empty for icon-only FABs).

func (*FAB) AccessibleRole

func (f *FAB) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleButton.

func (*FAB) CreateRenderer

func (f *FAB) CreateRenderer() core.WidgetRenderer

func (*FAB) HoverIn

func (f *FAB) HoverIn(*event.HoverEvent)

func (*FAB) HoverMoved

func (f *FAB) HoverMoved(*event.HoverEvent)

func (*FAB) HoverOut

func (f *FAB) HoverOut()

func (*FAB) MinSize

func (f *FAB) MinSize() geo.Size

func (*FAB) PerformAccessibleAction

func (f *FAB) PerformAccessibleAction(name string)

PerformAccessibleAction invokes the FAB's tap handler.

func (*FAB) Tapped

func (f *FAB) Tapped(*event.PointEvent)

type FABMenu

type FABMenu struct {
	Icon  bellui.Resource // main FAB icon
	Items []*FABMenuItem
	// contains filtered or unexported fields
}

FABMenu is an MD3 speed-dial FAB that expands to show action items.

func NewFABMenu

func NewFABMenu(icon bellui.Resource, items []*FABMenuItem) *FABMenu

NewFABMenu creates a FAB menu.

func (*FABMenu) Hide

func (f *FABMenu) Hide()

Hide dismisses the FAB menu.

func (*FABMenu) IsOpen

func (f *FABMenu) IsOpen() bool

IsOpen returns whether the menu is currently shown.

func (*FABMenu) Show

func (f *FABMenu) Show(c core.Canvas, pos geo.Position)

Show displays the FAB menu at the given position on the canvas. Typically positioned at bottom-right.

func (*FABMenu) Toggle

func (f *FABMenu) Toggle(c core.Canvas, pos geo.Position)

Toggle opens the menu if closed, closes if open.

type FABMenuItem

type FABMenuItem struct {
	Label    string
	Icon     bellui.Resource
	OnTapped func()
}

FABMenuItem is an action in a FAB menu.

type FABStyle

type FABStyle int

FABStyle determines the color scheme of a FAB.

const (
	FABStylePrimary   FABStyle = iota // PrimaryContainer bg (default)
	FABStyleSurface                   // SurfaceContainerHigh bg
	FABStyleSecondary                 // SecondaryContainer bg
	FABStyleTertiary                  // TertiaryContainer bg
)

type FileIcon

type FileIcon struct {
	BaseWidget

	URI bellui.URI
	// contains filtered or unexported fields
}

FileIcon is an adaption of widget.Icon for showing files and folders

Since: 1.0

func NewFileIcon

func NewFileIcon(uri bellui.URI) *FileIcon

NewFileIcon takes a filepath and creates an icon with an overlaid label using the detected mimetype and extension

Since: 1.0

func (*FileIcon) CreateRenderer

func (i *FileIcon) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*FileIcon) MinSize

func (i *FileIcon) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below

func (*FileIcon) SetURI

func (i *FileIcon) SetURI(uri bellui.URI)

SetURI changes the URI and makes the icon reflect a different file

type FileTree

type FileTree struct {
	Tree

	// Filter limits the files shown, in the manner of the file dialog.
	// Directories are always shown.
	Filter storage.FileFilter
	// ShowHidden shows items the platform considers hidden
	// (storage.IsHidden), mirroring the file dialog's hidden-files toggle.
	ShowHidden bool
	// ShowRootPath labels the root node with its full URI string instead of
	// its name.
	ShowRootPath bool
	// Sorter orders the children of each branch; when nil the lister's
	// order is kept. For locale-correct name ordering (rather than raw
	// code-point order, which mis-sorts accented and non-English names), set:
	//
	//	tree.Sorter = func(a, b bellui.URI) bool { return lang.Compare(a.Name(), b.Name()) < 0 }
	//
	// lang.Compare is goroutine-safe, so it is fine to call from here (Sorter
	// runs on a background goroutine).
	Sorter func(bellui.URI, bellui.URI) bool
	// Watch, when set before the tree is shown, watches the file system and
	// automatically re-lists a branch whose directory contents change
	// externally — the root and every open branch are watched while the tree
	// is shown (watches stop when the renderer is destroyed and re-arm on
	// re-show). Requires the URIs' repository to implement
	// [repository.WatchableRepository]; the built-in file repository does on
	// desktop and mobile, while platforms or schemes without change
	// notification degrade silently to manual Refresh.
	//
	// Since: 1.0
	Watch bool
	// contains filtered or unexported fields
}

FileTree extends Tree to display a file system hierarchy rooted at a URI. Directory contents are listed asynchronously off the main goroutine, so a slow lister (network mount, custom repository) does not stall a frame; a "Loading..." placeholder row is shown until the listing lands.

Configuration fields must be set before the tree is shown and, like all widget state, be mutated only on the main goroutine (call Refresh after changing them). Filter and Sorter are invoked on a background goroutine and must not touch widget state.

Since: 1.0

func NewFileTree

func NewFileTree(root bellui.URI) *FileTree

NewFileTree creates a new FileTree from the given root URI.

Since: 1.0

func (*FileTree) CreateRenderer

func (t *FileTree) CreateRenderer() core.WidgetRenderer

CreateRenderer is an internal requirement for Bellui; it also (re-)arms the file-system watches: a renderer Destroy releases them (a discarded tree must not keep a watcher goroutine notifying it), and Destroy also fires on cache eviction of a live, temporarily-hidden tree, so re-show re-arms here.

func (*FileTree) MapURI

func (t *FileTree) MapURI(uid TreeNodeID, target bellui.URI)

MapURI allows an app to return a specific URI for the given uid. This can be helpful to make more custom trees based on file structure. The mapping survives Refresh; map to nil to remove it.

func (*FileTree) Refresh

func (t *FileTree) Refresh()

Refresh re-lists every known branch and redraws the tree. Current children stay visible until each fresh listing lands, so an open tree does not flash back to placeholders.

type FontFamily

type FontFamily struct {
	Name     string          // Display name
	Resource bellui.Resource // Font file bytes (nil = resolve from system at preview time)
}

FontFamily represents a selectable font family.

type FontPicker

type FontPicker struct {
	DisableableWidget

	Config    FontPickerConfig
	Families  []FontFamily           // nil = use system fonts
	OnChanged func(FontPickerConfig) `json:"-"`
	// contains filtered or unexported fields
}

FontPicker is a composite widget for selecting font family, size, weight, and style.

func NewFontPicker

func NewFontPicker(config FontPickerConfig, families []FontFamily, changed func(FontPickerConfig)) *FontPicker

NewFontPicker creates a font picker with an explicit font family list.

func NewFontPickerWithSystemFonts

func NewFontPickerWithSystemFonts(config FontPickerConfig, changed func(FontPickerConfig)) *FontPicker

NewFontPickerWithSystemFonts creates a font picker that enumerates system fonts. The font list loads asynchronously.

func (*FontPicker) CreateRenderer

func (fp *FontPicker) CreateRenderer() core.WidgetRenderer

CreateRenderer returns the renderer for the font picker.

func (*FontPicker) Disable

func (fp *FontPicker) Disable()

Disable disables the font picker and all sub-widgets.

func (*FontPicker) Enable

func (fp *FontPicker) Enable()

Enable enables the font picker and all sub-widgets.

func (*FontPicker) MinSize

func (fp *FontPicker) MinSize() geo.Size

MinSize returns the minimum size of the font picker.

func (*FontPicker) SetConfig

func (fp *FontPicker) SetConfig(config FontPickerConfig)

SetConfig updates the picker's configuration and refreshes all controls.

func (*FontPicker) SetFamilies

func (fp *FontPicker) SetFamilies(families []FontFamily)

SetFamilies updates the available font families.

type FontPickerConfig

type FontPickerConfig struct {
	Family    string
	Size      float64
	Weight    bellui.TextWeight
	Bold      bool
	Italic    bool
	Underline bool
}

FontPickerConfig holds the current font selection state.

func (FontPickerConfig) TextStyle

func (c FontPickerConfig) TextStyle() bellui.TextStyle

TextStyle converts the config to a bellui.TextStyle.

type Form

type Form struct {
	BaseWidget

	Items      []*FormItem
	OnSubmit   func() `json:"-"`
	OnCancel   func() `json:"-"`
	SubmitText string
	CancelText string

	// Orientation allows a form to be vertical (a single column), horizontal (default, label then input)
	// or to adapt according to the orientation of the mobile device (adaptive).
	//
	// Since: 1.0
	Orientation Orientation
	// contains filtered or unexported fields
}

Form widget is two column grid where each row has a label and a widget (usually an input). The last row of the grid will contain the appropriate form control buttons if any should be shown. Setting OnSubmit will set the submit button to be visible and call back the function when tapped. Setting OnCancel will do the same for a cancel button. If you change OnSubmit/OnCancel after the form is created and rendered, you need to call Refresh() to update the form with the correct buttons. Setting OnSubmit/OnCancel to nil will remove the buttons.

func NewForm

func NewForm(items ...*FormItem) *Form

NewForm creates a new form widget with the specified rows of form items and (if any of them should be shown) a form controls row at the bottom

func (*Form) AccessibleLabel

func (f *Form) AccessibleLabel() string

AccessibleLabel returns an empty string; forms have no intrinsic label.

func (*Form) AccessibleRole

func (f *Form) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleForm.

func (*Form) Append

func (f *Form) Append(text string, widget core.CanvasObject)

Append adds a new row to the form, using the text as a label next to the specified Widget

func (*Form) AppendItem

func (f *Form) AppendItem(item *FormItem)

AppendItem adds the specified row to the end of the Form

func (*Form) CreateRenderer

func (f *Form) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*Form) Disable

func (f *Form) Disable()

Disable disables submitting this form.

Since: 1.0

func (*Form) Disabled

func (f *Form) Disabled() bool

Disabled returns whether submitting the form is disabled. Note that, if the form fails validation, the submit button may be disabled even if this method returns true.

Since: 1.0

func (*Form) Enable

func (f *Form) Enable()

Enable enables submitting this form.

Since: 1.0

func (*Form) MinSize

func (f *Form) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below

func (*Form) Refresh

func (f *Form) Refresh()

Refresh updates the widget state when requested.

func (*Form) SetOnValidationChanged

func (f *Form) SetOnValidationChanged(callback func(error))

SetOnValidationChanged is intended for parent widgets or containers to hook into the validation. The function might be overwritten by a parent that cares about child validation (e.g. widget.Form)

func (*Form) Validate

func (f *Form) Validate() error

Validate validates the entire form and returns the first error that is encountered.

type FormItem

type FormItem struct {
	Text   string
	Widget core.CanvasObject

	// Since: 1.0
	HintText string
	// contains filtered or unexported fields
}

FormItem provides the details for a row in a form

func NewFormItem

func NewFormItem(text string, widget core.CanvasObject) *FormItem

NewFormItem creates a new form item with the specified label text and input widget

type GridWrap

type GridWrap struct {
	BaseWidget

	// Length is a callback for returning the number of items in the GridWrap.
	Length func() int `json:"-"`

	// CreateItem is a callback invoked to create a new widget to render
	// an item in the GridWrap.
	CreateItem func() core.CanvasObject `json:"-"`

	// UpdateItem is a callback invoked to update a GridWrap item widget
	// to display a new item in the list. The UpdateItem callback should
	// only update the given item, it should not invoke APIs that would
	// change other properties of the GridWrap itself.
	UpdateItem func(id GridWrapItemID, item core.CanvasObject) `json:"-"`

	// OnSelected is a callback to be notified when a given item
	// in the GridWrap has been selected.
	OnSelected func(id GridWrapItemID) `json:"-"`

	// OnUnselected is a callback to be notified when a given item
	// in the GridWrap has been unselected.
	OnUnselected func(id GridWrapItemID) `json:"-"`
	// contains filtered or unexported fields
}

GridWrap is a widget with an API very similar to widget.List, that lays out items in a scrollable wrapping grid similar to container.NewGridWrap. It caches and reuses widgets for performance.

Since: 1.0

func NewGridWrap

func NewGridWrap(length func() int, createItem func() core.CanvasObject, updateItem func(GridWrapItemID, core.CanvasObject)) *GridWrap

NewGridWrap creates and returns a GridWrap widget for displaying items in a wrapping grid layout with scrolling and caching for performance.

Since: 1.0

func NewGridWrapWithData

func NewGridWrapWithData(data binding.DataList, createItem func() core.CanvasObject, updateItem func(binding.DataItem, core.CanvasObject)) *GridWrap

NewGridWrapWithData creates a new GridWrap widget that will display the contents of the provided data.

Since: 1.0

func (*GridWrap) AccessibleLabel

func (l *GridWrap) AccessibleLabel() string

AccessibleLabel returns an empty string; realized items provide their own semantics.

func (*GridWrap) AccessibleRole

func (l *GridWrap) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleList.

func (*GridWrap) ColumnCount

func (l *GridWrap) ColumnCount() int

ColumnCount returns the number of columns that are/will be shown in this GridWrap, based on the widget's current width.

Since: 1.0

func (*GridWrap) CreateRenderer

func (l *GridWrap) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer.

func (*GridWrap) FocusGained

func (l *GridWrap) FocusGained()

FocusGained is called after this GridWrap has gained focus.

func (*GridWrap) FocusLost

func (l *GridWrap) FocusLost()

FocusLost is called after this GridWrap has lost focus.

func (*GridWrap) GetScrollOffset

func (l *GridWrap) GetScrollOffset() float32

GetScrollOffset returns the current scroll offset position

func (*GridWrap) MinSize

func (l *GridWrap) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below.

func (*GridWrap) Refresh

func (l *GridWrap) Refresh()

Refresh causes this GridWrap to be redrawn in its current state.

func (*GridWrap) RefreshItem

func (l *GridWrap) RefreshItem(id GridWrapItemID)

RefreshItem refreshes a single item, specified by the item ID passed in.

Since: 1.0

func (*GridWrap) Resize

func (l *GridWrap) Resize(s geo.Size)

Resize is called when this GridWrap should change size. We refresh to ensure invisible items are drawn.

func (*GridWrap) ScrollTo

func (l *GridWrap) ScrollTo(id GridWrapItemID)

ScrollTo scrolls to the item represented by id

func (*GridWrap) ScrollToBottom

func (l *GridWrap) ScrollToBottom()

ScrollToBottom scrolls to the end of the list

func (*GridWrap) ScrollToOffset

func (l *GridWrap) ScrollToOffset(offset float32)

ScrollToOffset scrolls the list to the given offset position

func (*GridWrap) ScrollToTop

func (l *GridWrap) ScrollToTop()

ScrollToTop scrolls to the start of the list

func (*GridWrap) Select

func (l *GridWrap) Select(id GridWrapItemID)

Select adds the item identified by the given ID to the selection.

func (*GridWrap) TypedKey

func (l *GridWrap) TypedKey(ev *event.KeyEvent)

TypedKey is called if a key event happens while this GridWrap is focused.

func (*GridWrap) TypedRune

func (l *GridWrap) TypedRune(_ rune)

TypedRune is called if a text event happens while this GridWrap is focused.

func (*GridWrap) Unselect

func (l *GridWrap) Unselect(id GridWrapItemID)

Unselect removes the item identified by the given ID from the selection.

func (*GridWrap) UnselectAll

func (l *GridWrap) UnselectAll()

UnselectAll removes all items from the selection.

type GridWrapItemID

type GridWrapItemID = int

GridWrapItemID is the ID of an individual item in the GridWrap widget.

Since: 1.0

type Hyperlink struct {
	BaseWidget
	Text      string
	URL       *url.URL
	Alignment bellui.TextAlign // The alignment of the Text
	Wrapping  bellui.TextWrap  // The wrapping of the Text
	TextStyle bellui.TextStyle // The style of the hyperlink text

	// The truncation mode of the hyperlink
	//
	// Since: 1.0
	Truncation bellui.TextTruncation

	// The theme size name for the text size of the hyperlink
	//
	// Since: 1.0
	SizeName bellui.ThemeSizeName

	// ColorName is the theme color used to render the link text, its hover
	// underline and its focus ring. When empty (the zero value) the link uses
	// the theme's primary color, so existing links are unchanged.
	//
	// Since: 1.0
	ColorName bellui.ThemeColorName

	// FontSource is an optional custom font resource used to render the link
	// text, matching TextSegment.Style.FontSource (pre-rebrand tracker #494). When nil (the zero
	// value) the theme font is used, so existing links are unchanged. The chosen
	// font is honoured for measurement as well as rendering.
	//
	// Since: 1.0
	FontSource bellui.Resource

	// OnTapped overrides the default `bellui.OpenURL` call when the link is tapped
	//
	// Since: 1.0
	OnTapped func() `json:"-"`
	// contains filtered or unexported fields
}

Hyperlink widget is a text component with appropriate padding and layout. When clicked, the default web browser should open with a URL

func NewHyperlink(text string, url *url.URL) *Hyperlink

NewHyperlink creates a new hyperlink widget with the set text content

func NewHyperlinkWithStyle

func NewHyperlinkWithStyle(text string, url *url.URL, alignment bellui.TextAlign, style bellui.TextStyle) *Hyperlink

NewHyperlinkWithStyle creates a new hyperlink widget with the set text content

func (*Hyperlink) AccessibleActions

func (hl *Hyperlink) AccessibleActions() []core.AccessibleAction

AccessibleActions returns the "press" action.

func (*Hyperlink) AccessibleLabel

func (hl *Hyperlink) AccessibleLabel() string

AccessibleLabel returns the hyperlink text.

func (*Hyperlink) AccessibleRole

func (hl *Hyperlink) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleLink.

func (*Hyperlink) ActivatedByKey

func (hl *Hyperlink) ActivatedByKey(ev *event.KeyEvent) bool

ActivatedByKey reports that Space activates the link, so the driver fires the keyboard-activation signal in parity with a pointer tap (pre-rebrand tracker #700).

func (*Hyperlink) CreateRenderer

func (hl *Hyperlink) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*Hyperlink) Cursor

func (hl *Hyperlink) Cursor() desktop.Cursor

Cursor returns the cursor type of this widget

func (*Hyperlink) FocusGained

func (hl *Hyperlink) FocusGained()

FocusGained is a hook called by the focus handling logic after this object gained the focus.

func (*Hyperlink) FocusLost

func (hl *Hyperlink) FocusLost()

FocusLost is a hook called by the focus handling logic after this object lost the focus.

func (*Hyperlink) HoverIn

func (hl *Hyperlink) HoverIn(e *event.HoverEvent)

HoverIn is a hook that is called if the pointer enters the element.

func (*Hyperlink) HoverMoved

func (hl *Hyperlink) HoverMoved(e *event.HoverEvent)

HoverMoved is a hook that is called if the pointer moved over the element.

func (*Hyperlink) HoverOut

func (hl *Hyperlink) HoverOut()

HoverOut is a hook that is called if the pointer leaves the element.

func (*Hyperlink) MinSize

func (hl *Hyperlink) MinSize() geo.Size

MinSize returns the smallest size this widget can shrink to

func (*Hyperlink) PerformAccessibleAction

func (hl *Hyperlink) PerformAccessibleAction(name string)

PerformAccessibleAction opens the link URL.

func (*Hyperlink) Refresh

func (hl *Hyperlink) Refresh()

Refresh triggers a redraw of the hyperlink.

func (*Hyperlink) Resize

func (hl *Hyperlink) Resize(size geo.Size)

Resize sets a new size for the hyperlink. Note this should not be used if the widget is being managed by a Layout within a Container.

func (*Hyperlink) SetText

func (hl *Hyperlink) SetText(text string)

SetText sets the text of the hyperlink. It is safe to call from any goroutine.

func (*Hyperlink) SetURL

func (hl *Hyperlink) SetURL(url *url.URL)

SetURL sets the URL of the hyperlink, taking in a URL type

func (*Hyperlink) SetURLFromString

func (hl *Hyperlink) SetURLFromString(str string) error

SetURLFromString sets the URL of the hyperlink, taking in a string type

func (*Hyperlink) Tapped

func (hl *Hyperlink) Tapped(e *event.PointEvent)

Tapped is called when a pointer tapped event is captured and triggers any change handler

func (*Hyperlink) TypedKey

func (hl *Hyperlink) TypedKey(ev *event.KeyEvent)

TypedKey is a hook called by the input handling logic on key events if this object is focused.

func (*Hyperlink) TypedRune

func (hl *Hyperlink) TypedRune(rune)

TypedRune is a hook called by the input handling logic on text input events if this object is focused.

type HyperlinkSegment

type HyperlinkSegment struct {
	Alignment bellui.TextAlign
	Text      string
	URL       *url.URL

	// OnTapped overrides the default `bellui.OpenURL` call when the link is tapped
	//
	// Since: 1.0
	OnTapped func() `json:"-"`

	// Style carries optional per-segment styling for the link text — FontSource
	// (pre-rebrand tracker #494/#651), ColorName, SizeName and TextStyle — mirroring TextSegment.Style
	// so a link can render in a custom font, color or size rather than always the
	// theme font/primary color. The zero value is byte-identical to before (theme
	// font, primary color, theme text size). The segment's own Alignment field
	// (not Style.Alignment) controls alignment; Style.Inline, HeadingLevel and the
	// internal concealed flag are not consulted for links.
	//
	// Since: 1.0
	Style RichTextStyle
}

HyperlinkSegment represents a hyperlink within a rich text widget.

Since: 1.0

func (*HyperlinkSegment) Inline

func (h *HyperlinkSegment) Inline() bool

Inline returns true as hyperlinks are inside other elements.

func (*HyperlinkSegment) Select

func (h *HyperlinkSegment) Select(begin, end geo.Position)

Select tells the segment that the user is selecting the content between the two positions.

func (*HyperlinkSegment) SelectedText

func (h *HyperlinkSegment) SelectedText() string

SelectedText should return the text representation of any content currently selected through the Select call.

func (*HyperlinkSegment) Textual

func (h *HyperlinkSegment) Textual() string

Textual returns the content of this segment rendered to plain text.

func (*HyperlinkSegment) Unselect

func (h *HyperlinkSegment) Unselect()

Unselect tells the segment that the user is has cancelled the previous selection.

func (*HyperlinkSegment) Update

func (h *HyperlinkSegment) Update(o core.CanvasObject)

Update applies the current state of this hyperlink segment to an existing visual.

func (*HyperlinkSegment) Visual

func (h *HyperlinkSegment) Visual() core.CanvasObject

Visual returns a new instance of a hyperlink widget required to render this segment.

type Icon

type Icon struct {
	BaseWidget

	Resource bellui.Resource // The resource for this icon
	// contains filtered or unexported fields
}

Icon widget is a basic image component that load's its resource to match the theme.

func NewIcon

func NewIcon(res bellui.Resource) *Icon

NewIcon returns a new icon widget that displays a themed icon resource

func (*Icon) CreateRenderer

func (i *Icon) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*Icon) MinSize

func (i *Icon) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below

func (*Icon) SetResource

func (i *Icon) SetResource(res bellui.Resource)

SetResource updates the resource rendered in this icon widget

type IconButton

type IconButton struct {
	DisableableWidget
	Icon     bellui.Resource
	Style    IconButtonStyle
	OnTapped func() `json:"-"`
	// contains filtered or unexported fields
}

IconButton is an icon-only button with MD3 visual variants.

func NewIconButton

func NewIconButton(icon bellui.Resource, tapped func()) *IconButton

NewIconButton creates a standard icon button.

func (*IconButton) AccessibleActions

func (b *IconButton) AccessibleActions() []core.AccessibleAction

AccessibleActions returns the "press" action.

func (*IconButton) AccessibleLabel

func (b *IconButton) AccessibleLabel() string

AccessibleLabel returns an empty string; icon buttons have no intrinsic text label. Use [AccessibleDescriber] to provide a description for screen readers.

func (*IconButton) AccessibleRole

func (b *IconButton) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleButton.

func (*IconButton) CreateRenderer

func (b *IconButton) CreateRenderer() core.WidgetRenderer

func (*IconButton) HoverIn

func (b *IconButton) HoverIn(*event.HoverEvent)

func (*IconButton) HoverMoved

func (b *IconButton) HoverMoved(*event.HoverEvent)

func (*IconButton) HoverOut

func (b *IconButton) HoverOut()

func (*IconButton) MinSize

func (b *IconButton) MinSize() geo.Size

func (*IconButton) PerformAccessibleAction

func (b *IconButton) PerformAccessibleAction(name string)

PerformAccessibleAction invokes the button's tap handler.

func (*IconButton) Tapped

func (b *IconButton) Tapped(*event.PointEvent)

type IconButtonStyle

type IconButtonStyle int

IconButtonStyle determines the visual variant of an icon button.

const (
	// IconButtonStyleStandard has no background, icon color OnSurfaceVariant.
	IconButtonStyleStandard IconButtonStyle = iota
	// IconButtonStyleFilled has Primary background, OnPrimary icon.
	IconButtonStyleFilled
	// IconButtonStyleFilledTonal has SecondaryContainer background.
	IconButtonStyleFilledTonal
	// IconButtonStyleOutlined has border, no fill, OnSurfaceVariant icon.
	IconButtonStyleOutlined
)

type ImageSegment

type ImageSegment struct {
	Source bellui.URI
	Title  string

	// Image is an in-memory image source. When set it takes precedence over
	// Source and is rendered without any network or disk access — so it is not
	// subject to the AllowRemoteContent policy. Use it to embed decoded image
	// data (e.g. a pasted bitmap) directly.
	//
	// Since: 1.0
	Image image.Image

	// Resource is an in-memory resource source (e.g. bundled image bytes). Like
	// Image it is rendered without network or disk access. Source precedence is
	// Image, then Resource, then Source.
	//
	// Since: 1.0
	Resource bellui.Resource

	// Alignment specifies the horizontal alignment of this image segment
	// Since: 1.0
	Alignment bellui.TextAlign

	// InlineImage lays the image out *within* a text row — flowing between the
	// surrounding text like a large glyph — instead of on its own block row. The
	// image still occupies exactly one caret position. Zero value (false) keeps
	// the historical block layout, so existing content is unchanged (pre-rebrand tracker #665).
	//
	// Since: 1.0
	InlineImage bool
	// contains filtered or unexported fields
}

ImageSegment represents an image within a rich text widget.

Since: 1.0

func (*ImageSegment) Inline

func (i *ImageSegment) Inline() bool

Inline reports whether this image flows within a text row (see InlineImage). Block images (the default) return false and lay out on their own row.

func (*ImageSegment) Select

func (i *ImageSegment) Select(begin, end geo.Position)

Select tells the segment that the user is selecting the content between the two positions.

func (*ImageSegment) SelectedText

func (i *ImageSegment) SelectedText() string

SelectedText should return the text representation of any content currently selected through the Select call.

func (*ImageSegment) Textual

func (i *ImageSegment) Textual() string

Textual returns the content of this segment rendered to plain text.

func (*ImageSegment) Unselect

func (i *ImageSegment) Unselect()

Unselect tells the segment that the user is has cancelled the previous selection.

func (*ImageSegment) Update

func (i *ImageSegment) Update(o core.CanvasObject)

Update applies the current state of this image segment to an existing visual.

func (*ImageSegment) Visual

func (i *ImageSegment) Visual() core.CanvasObject

Visual returns a new instance of an image widget required to render this segment.

type Importance

type Importance int

Importance represents how prominent the widget should appear

Since: 1.0

const (
	// MediumImportance applies a standard appearance.
	MediumImportance Importance = iota
	// HighImportance applies a prominent appearance.
	HighImportance
	// LowImportance applies a subtle appearance.
	LowImportance

	// DangerImportance applies an error theme to the widget.
	//
	// Since: 1.0
	DangerImportance
	// WarningImportance applies a warning theme to the widget.
	//
	// Since: 1.0
	WarningImportance

	// SuccessImportance applies a success theme to the widget.
	//
	// Since: 1.0
	SuccessImportance
)

type Interactive

type Interactive struct {
	BaseWidget

	// Content is the wrapped CanvasObject.
	Content core.CanvasObject

	// Pointer events.
	OnTapped          func(*event.PointEvent)
	OnDoubleTapped    func(*event.PointEvent)
	OnTappedSecondary func(*event.PointEvent)

	// Drag events.
	OnDragged func(*event.DragEvent)
	OnDragEnd func()

	// Scroll events.
	OnScrolled func(*event.ScrollEvent)

	// Hover events.
	OnHoverIn    func(*event.HoverEvent)
	OnHoverMoved func(*event.HoverEvent)
	OnHoverOut   func()

	// CursorStyle override (desktop only). Nil means default cursor.
	CursorStyle desktop.Cursor
}

Interactive wraps any CanvasObject and adds event handling via callbacks. This bridges the gap between canvas primitives (which can only draw) and widgets (which can handle events), without the full CreateRenderer ceremony.

Usage:

rect := canvas.NewRectangle(color.NRGBA{R: 200, A: 255})
btn := widget.NewInteractive(rect)
btn.OnTapped = func(*event.PointEvent) {
    rect.FillColor = color.NRGBA{G: 200, A: 255}
    canvas.Refresh(rect)
}

Interactive implements Tappable, DoubleTappable, SecondaryTappable, Draggable, Scrollable, event.Hoverable, and desktop.Cursorable — but only dispatches events when the corresponding callback is set.

func NewInteractive

func NewInteractive(content core.CanvasObject) *Interactive

NewInteractive wraps a CanvasObject to make it interactive.

func (*Interactive) CreateRenderer

func (i *Interactive) CreateRenderer() core.WidgetRenderer

CreateRenderer returns the renderer for this interactive wrapper.

func (*Interactive) Cursor

func (i *Interactive) Cursor() desktop.Cursor

func (*Interactive) DoubleTapped

func (i *Interactive) DoubleTapped(ev *event.PointEvent)

func (*Interactive) DragEnd

func (i *Interactive) DragEnd()

func (*Interactive) Dragged

func (i *Interactive) Dragged(ev *event.DragEvent)

func (*Interactive) HoverIn

func (i *Interactive) HoverIn(ev *event.HoverEvent)

func (*Interactive) HoverMoved

func (i *Interactive) HoverMoved(ev *event.HoverEvent)

func (*Interactive) HoverOut

func (i *Interactive) HoverOut()

func (*Interactive) Scrolled

func (i *Interactive) Scrolled(ev *event.ScrollEvent)

func (*Interactive) Tapped

func (i *Interactive) Tapped(ev *event.PointEvent)

func (*Interactive) TappedSecondary

func (i *Interactive) TappedSecondary(ev *event.PointEvent)

type Label

type Label struct {
	BaseWidget
	Text      string
	Alignment bellui.TextAlign // The alignment of the text
	Wrapping  bellui.TextWrap  // The wrapping of the text
	TextStyle bellui.TextStyle // The style of the label text

	// The truncation mode of the text
	//
	// Since: 1.0
	Truncation bellui.TextTruncation
	// Importance informs how the label should be styled, i.e. warning or disabled
	//
	// Since: 1.0
	Importance Importance

	// The theme size name for the text size of the label
	//
	// Since: 1.0
	SizeName bellui.ThemeSizeName

	// If set to true, Selectable indicates that this label should support select interaction
	// to allow the text to be copied.
	//
	//Since: 1.0
	Selectable bool

	// ShowTooltipWhenTruncated, when true, shows a hover tooltip with the full
	// text when the label is truncated. Only effective when Truncation is set to
	// a non-off mode (e.g. TextTruncateEllipsis or TextTruncateClip).
	//
	// Since: 1.0
	ShowTooltipWhenTruncated bool
	// contains filtered or unexported fields
}

Label widget is a label component with appropriate padding and layout.

func NewLabel

func NewLabel(text string) *Label

NewLabel creates a new label widget with the set text content

func NewLabelWithData

func NewLabelWithData(data binding.String) *Label

NewLabelWithData returns a Label widget connected to the specified data source.

Since: 1.0

func NewLabelWithStyle

func NewLabelWithStyle(text string, alignment bellui.TextAlign, style bellui.TextStyle) *Label

NewLabelWithStyle creates a new label widget with the set text content

func (*Label) AccessibleCaret

func (l *Label) AccessibleCaret() int

AccessibleCaret returns the rune offset of the selection cursor.

func (*Label) AccessibleLabel

func (l *Label) AccessibleLabel() string

AccessibleLabel returns the label text.

func (*Label) AccessibleRole

func (l *Label) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleLabel.

func (*Label) AccessibleSelection

func (l *Label) AccessibleSelection() (start, end int)

AccessibleSelection returns the user selection as a half-open rune range; when nothing is selected both offsets are the cursor position. Always (0, 0) while the label is not selectable.

func (*Label) AccessibleText

func (l *Label) AccessibleText() string

AccessibleText returns the label text for assistive technologies (pre-rebrand tracker #556): together with the selection offsets below it lets a screen reader read a selectable label's content, selection and caret, not just its static value.

func (*Label) Bind

func (l *Label) Bind(data binding.String)

Bind connects the specified data source to this Label. The current value will be displayed and any changes in the data will cause the widget to update.

Since: 1.0

func (*Label) CreateRenderer

func (l *Label) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*Label) IntrinsicSize

func (l *Label) IntrinsicSize() geo.Size

IntrinsicSize reports the size the label wants at unlimited width: its natural extent measured as if Wrapping and Truncation were off, plus padding. It mirrors RichText.IntrinsicSize (the label wraps a RichText) for content autosizing: a wrapping or truncating label's Label.MinSize reports a width of ~0, so use IntrinsicSize to size a container, popover or tooltip to the content. When Wrapping and Truncation are off it equals MinSize.

Since: 1.0

func (*Label) MinSize

func (l *Label) MinSize() geo.Size

MinSize returns the size that this label should not shrink below.

func (*Label) ReplaceAccessibleSelection

func (l *Label) ReplaceAccessibleSelection(string)

ReplaceAccessibleSelection is a no-op: labels are not editable.

func (*Label) SelectedText

func (l *Label) SelectedText() string

SelectedText returns the text currently selected in this Label. If the label is not selectable (considering both the widget property and the window-level [SelectableMode]) it will return an empty string. If there is no selection it will return the empty string.

Since: 1.0

func (*Label) SetAccessibleSelection

func (l *Label) SetAccessibleSelection(start, end int)

SetAccessibleSelection selects [start, end), clamped to the content; equal offsets clear the selection. A no-op while the label is not selectable. It is safe to call from any goroutine.

func (*Label) SetText

func (l *Label) SetText(text string)

SetText sets the text of the label. It is safe to call from any goroutine.

func (*Label) SyncState

func (l *Label) SyncState()

SyncState syncs Label's public fields to internal rendering state. Called automatically by BaseWidget.Refresh() before the renderer refreshes.

func (*Label) Unbind

func (l *Label) Unbind()

Unbind disconnects any configured data source from this Label. The current value will remain at the last value of the data source.

Since: 1.0

type LineRange

type LineRange struct {
	Start, End int
}

LineRange is a 0-based range with inclusive Start and exclusive End. It identifies a contiguous block of lines, for example a folded region fed to Entry.HiddenRanges (where the unit is logical, newline-delimited lines).

Since: 1.0

type List

type List struct {
	BaseWidget

	// Length is a callback for returning the number of items in the list.
	Length func() int `json:"-"`

	// CreateItem is a callback invoked to create a new widget to render
	// a row in the list.
	CreateItem func() core.CanvasObject `json:"-"`

	// UpdateItem is a callback invoked to update a list row widget
	// to display a new row in the list. The UpdateItem callback should
	// only update the given item, it should not invoke APIs that would
	// change other properties of the list itself.
	UpdateItem func(id ListItemID, item core.CanvasObject) `json:"-"`

	// OnSelected is a callback to be notified when a given item
	// in the list has been selected.
	OnSelected func(id ListItemID) `json:"-"`

	// OnUnselected is a callback to be notified when a given item
	// in the list has been unselected.
	OnUnselected func(id ListItemID) `json:"-"`

	// HideSeparators hides the separators between list rows
	//
	// Since: 1.0
	HideSeparators bool
	// contains filtered or unexported fields
}

List is a widget that pools list items for performance and lays the items out in a vertical direction inside of a scroller. By default, List requires that all items are the same size, but specific rows can have their heights set with SetItemHeight.

Since: 1.0

func NewList

func NewList(length func() int, createItem func() core.CanvasObject, updateItem func(ListItemID, core.CanvasObject)) *List

NewList creates and returns a list widget for displaying items in a vertical layout with scrolling and caching for performance.

Since: 1.0

func NewListWithData

func NewListWithData(data binding.DataList, createItem func() core.CanvasObject, updateItem func(binding.DataItem, core.CanvasObject)) *List

NewListWithData creates a new list widget that will display the contents of the provided data.

Since: 1.0

func (*List) AccessibleLabel

func (l *List) AccessibleLabel() string

AccessibleLabel returns an empty string; lists have no intrinsic label.

func (*List) AccessibleRole

func (l *List) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleList.

func (*List) CreateRenderer

func (l *List) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer.

func (*List) FocusGained

func (l *List) FocusGained()

FocusGained is called after this List has gained focus.

func (*List) FocusLost

func (l *List) FocusLost()

FocusLost is called after this List has lost focus.

func (*List) GetScrollOffset

func (l *List) GetScrollOffset() float32

GetScrollOffset returns the current scroll offset position

Since: 1.0

func (*List) MinSize

func (l *List) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below.

func (*List) Refresh

func (l *List) Refresh()

Refresh causes this List to be redrawn in its current state

func (*List) RefreshItem

func (l *List) RefreshItem(id ListItemID)

RefreshItem refreshes a single item, specified by the item ID passed in.

Since: 1.0

func (*List) Resize

func (l *List) Resize(s geo.Size)

Resize is called when this list should change size. We refresh to ensure invisible items are drawn.

func (*List) ScrollTo

func (l *List) ScrollTo(id ListItemID)

ScrollTo scrolls to the item represented by id

Since: 1.0

func (*List) ScrollToBottom

func (l *List) ScrollToBottom()

ScrollToBottom scrolls to the end of the list

Since: 1.0

func (*List) ScrollToOffset

func (l *List) ScrollToOffset(offset float32)

ScrollToOffset scrolls the list to the given offset position.

Since: 1.0

func (*List) ScrollToTop

func (l *List) ScrollToTop()

ScrollToTop scrolls to the start of the list

Since: 1.0

func (*List) Select

func (l *List) Select(id ListItemID)

Select add the item identified by the given ID to the selection.

func (*List) SetItemHeight

func (l *List) SetItemHeight(id ListItemID, height float32)

SetItemHeight supports changing the height of the specified list item. Items normally take the height of the template returned from the CreateItem callback. The height parameter uses the same units as a geo.Size type and refers to the internal content height not including the divider size.

Since: 1.0

func (*List) TypedKey

func (l *List) TypedKey(ev *event.KeyEvent)

TypedKey is called if a key event happens while this List is focused.

func (*List) TypedRune

func (l *List) TypedRune(_ rune)

TypedRune is called if a text event happens while this List is focused.

func (*List) Unselect

func (l *List) Unselect(id ListItemID)

Unselect removes the item identified by the given ID from the selection.

func (*List) UnselectAll

func (l *List) UnselectAll()

UnselectAll removes all items from the selection.

Since: 1.0

type ListEditor

type ListEditor[T any] struct {
	// EditOnActivate begins editing a row when it is selected (the default). Set
	// it to false to drive editing yourself — for example from a
	// [model.SelectionModel], by calling [ListEditor.Edit] with the selected row.
	EditOnActivate bool
	// contains filtered or unexported fields
}

ListEditor is the controller returned by BindListEditing. It drives an inline editor over the rows of a List: begin editing a row, commit the edit back through the model as one gated write, or cancel it.

Call all methods on the main goroutine, like every widget mutation.

Since: 1.0

func BindListEditing

func BindListEditing[T any](list *List, m model.MutableModel[T],
	createDisplay func() core.CanvasObject,
	updateDisplay func(item T, display core.CanvasObject),
	editor CellEditor[T],
) (*ListEditor[T], func())

BindListEditing drives an editable List from a model.MutableModel: rows render through createDisplay/updateDisplay, and activating a row swaps its display for an inline editor described by editor. Committing writes the edited value back through the model as one gated edit (a single model.MutableModel.SetItem, so it fires one change notification); an invalid edit (Commit returns an error) is rejected and the editor stays open; Escape cancels and discards.

Because m may be a model.SortProxy/model.FilterProxy (or a chain), the write is mapped from the displayed row back to the correct source row automatically.

The returned ListEditor is the controller; the returned function detaches the binding. Mutate the model on the main goroutine (use bellui.Do from a background goroutine), the same rule the widgets already follow.

Since: 1.0

func (*ListEditor[T]) Cancel

func (ed *ListEditor[T]) Cancel()

Cancel discards the current edit and closes the editor.

func (*ListEditor[T]) Commit

func (ed *ListEditor[T]) Commit() error

Commit validates the current edit and, if it is accepted, writes it back through the model as one gated edit and closes the editor. It returns the validation error from the editor's Commit when the edit is rejected (the editor stays open in that case), or nil when there was nothing to commit or the write succeeded.

func (*ListEditor[T]) Edit

func (ed *ListEditor[T]) Edit(row int)

Edit begins inline editing of the row at display index row (a no-op if the row is out of range or the editor has no Commit). It replaces any edit in progress.

func (*ListEditor[T]) Editing

func (ed *ListEditor[T]) Editing() (row int, ok bool)

Editing reports the row currently being edited, and whether an edit is active.

type ListItemID

type ListItemID = int

ListItemID uniquely identifies an item within a list.

type ListSegment

type ListSegment struct {
	Items   []RichTextSegment
	Ordered bool
	// contains filtered or unexported fields
}

ListSegment includes an itemised list with the content set using the Items field.

Since: 1.0

func (*ListSegment) Inline

func (l *ListSegment) Inline() bool

Inline returns false as a list should be in a block.

func (*ListSegment) Segments

func (l *ListSegment) Segments() []RichTextSegment

Segments returns the segments required to draw bullets before each item

func (*ListSegment) Select

func (l *ListSegment) Select(_, _ geo.Position)

Select does nothing for a list container.

func (*ListSegment) SelectedText

func (l *ListSegment) SelectedText() string

SelectedText returns the empty string for this list.

func (*ListSegment) SetStartNumber

func (l *ListSegment) SetStartNumber(s int)

SetStartNumber sets the starting number for an ordered list. Unordered lists are not affected.

Since: 1.0

func (*ListSegment) StartNumber

func (l *ListSegment) StartNumber() int

StartNumber return the starting number for an ordered list.

Since: 1.0

func (*ListSegment) Textual

func (l *ListSegment) Textual() string

Textual returns no content for a list as the content is in sub-segments.

func (*ListSegment) Unselect

func (l *ListSegment) Unselect()

Unselect does nothing for a list container.

func (*ListSegment) Update

func (l *ListSegment) Update(core.CanvasObject)

Update doesn't need to change a list visual.

func (*ListSegment) Visual

func (l *ListSegment) Visual() core.CanvasObject

Visual returns no additional elements for this segment.

type LoadingIndicator

type LoadingIndicator struct {
	BaseWidget
	Shape LoadingShape
	// contains filtered or unexported fields
}

LoadingIndicator is an MD3 skeleton/shimmer placeholder shown while content loads.

func NewLoadingIndicator

func NewLoadingIndicator(shape LoadingShape) *LoadingIndicator

NewLoadingIndicator creates a loading indicator with the given shape.

func (*LoadingIndicator) CreateRenderer

func (l *LoadingIndicator) CreateRenderer() core.WidgetRenderer

func (*LoadingIndicator) MinSize

func (l *LoadingIndicator) MinSize() geo.Size

type LoadingShape

type LoadingShape int

LoadingShape determines the shape of a loading indicator.

const (
	LoadingShapeRect   LoadingShape = iota // Rectangular placeholder (cards, images)
	LoadingShapeCircle                     // Circular placeholder (avatars)
	LoadingShapeText                       // Thin rectangles (text lines)
)
type Menu struct {
	BaseWidget

	Items     []core.CanvasObject
	OnDismiss func() `json:"-"`
	// contains filtered or unexported fields
}

Menu is a widget for displaying a bellui.Menu.

func NewMenu

func NewMenu(menu *bellui.Menu) *Menu

NewMenu creates a new Menu.

func (m *Menu) AccessibleLabel() string

AccessibleLabel returns an empty string; menus have no intrinsic label.

func (m *Menu) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleMenu.

func (m *Menu) ActivateLastSubmenu() bool

ActivateLastSubmenu finds the last active menu item traversing through the open submenus and activates its submenu if any. It returns `true` if there was a submenu and it was activated and `false` elsewhere. Activating a submenu does show it and activate its first item.

func (m *Menu) ActivateNext()

ActivateNext activates the menu item following the currently active menu item. If there is no menu item active, it activates the first menu item. If there is no menu item after the current active one, it does nothing. If a submenu is open, it delegates the activation to this submenu.

func (m *Menu) ActivatePrevious()

ActivatePrevious activates the menu item preceding the currently active menu item. If there is no menu item active, it activates the last menu item. If there is no menu item before the current active one, it does nothing. If a submenu is open, it delegates the activation to this submenu.

func (m *Menu) CreateRenderer() core.WidgetRenderer

CreateRenderer returns a new renderer for the menu.

func (m *Menu) DeactivateChild()

DeactivateChild deactivates the active menu item and hides its submenu if any.

func (m *Menu) DeactivateLastSubmenu() bool

DeactivateLastSubmenu finds the last open submenu traversing through the open submenus, deactivates its active item and hides it. This also deactivates any submenus of the deactivated submenu. It returns `true` if there was a submenu open and closed and `false` elsewhere.

func (m *Menu) Dismiss()

Dismiss dismisses the menu by dismissing and hiding the active child and performing OnDismiss.

func (m *Menu) MinSize() geo.Size

MinSize returns the minimal size of the menu.

func (m *Menu) Refresh()

Refresh updates the menu to reflect changes in the data.

func (m *Menu) Tapped(*event.PointEvent)

Tapped catches taps on separators and the menu background. It doesn't perform any action.

func (m *Menu) TriggerLast()

TriggerLast finds the last active menu item traversing through the open submenus and triggers it.

type NativeView

type NativeView interface {
	// Attach creates the platform view inside win, whose native handle the
	// backend obtains through [driver.NativeWindow.RunNative]. It is called
	// once, when the host is first laid out on a canvas. Returning an error
	// leaves the host inert — it occupies its space and draws nothing.
	Attach(win bellui.Window) error

	// SetGeometry places the view. rect is the host's rectangle and clip the
	// region the view must be masked to, both in canvas-absolute bellui
	// coordinates (device-independent points); scale is the canvas scale,
	// which converts them to whatever unit the platform view uses. clip is
	// always contained in rect's canvas and never empty — the host hides the
	// view rather than reporting an empty clip.
	SetGeometry(rect, clip geo.Rectangle, scale float32)

	// SetVisible shows or hides the platform view. The host calls it with
	// false when it is hidden, detached from a canvas, or clipped entirely
	// out of view, and with true when it becomes visible again.
	SetVisible(visible bool)

	// Destroy removes the platform view and releases its resources. It must
	// be safe to call more than once, and safe to call without a preceding
	// successful Attach.
	Destroy()
}

NativeView is the platform-side view a NativeViewHost places, sizes, clips and tears down. Implementations are inherently platform-specific and belong in their own optional package, so an app that never embeds a native view never links the platform SDK.

Every method is called on the main goroutine.

Since: 1.0

type NativeViewFocuser

type NativeViewFocuser interface {
	NativeView

	// TakeFocus asks the platform view to become the OS keyboard focus, as a
	// click inside it would, and reports whether the platform accepted.
	TakeFocus() bool

	// ResignFocus gives the OS keyboard focus back to bellui's own surface,
	// so that keys and input-method composition reach the canvas again. It
	// reports whether the platform accepted; a backend that does not hold the
	// focus should report success and do nothing.
	ResignFocus() bool

	// HasFocus reports whether the platform view currently holds the OS
	// keyboard focus, meaning bellui is receiving no key events. It is called
	// once per frame while the view is shown, so it must be cheap.
	HasFocus() bool
}

NativeViewFocuser is the optional capability of a NativeView whose platform view can hold the OS keyboard focus. A NativeViewHost whose backend implements it bridges the platform responder chain to canvas focus in both directions (#59); a backend without it — a video surface or a map that never wants the keyboard — is left alone.

The three methods are the whole contract: the host polls HasFocus on the per-frame sync it already runs, so a backend needs no focus-change notification of its own. Every method is called on the main goroutine.

Since: 1.0

type NativeViewHost

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

NativeViewHost embeds an OS-owned view — a web view, a native video surface, a map or a camera preview — at a widget's position in the layout.

This is a hole punch, not a composited widget

Bellui draws its whole scene into one GPU surface. An OS view has its own render pipeline and cannot be composited into that surface, so a NativeViewHost does not draw the native content at all: it draws nothing, and drives a real platform view positioned over the canvas at the host's screen rectangle. This is the same approach Flutter, Compose Multiplatform and Avalonia ship, and it carries limitations that are properties of the approach rather than bugs to be fixed later:

  • Nothing bellui draws can appear above the native view. Every PopUp, dialog, menu, Tooltip, Toast, Snackbar, CompletionPopup and the mobile selection handles and loupe are occluded where they overlap it.
  • core.Canvas.Capture sees a hole. The native content is not in the surface Capture reads back, so screenshots, golden-image tests and the hack/*probe -auto verification convention capture whatever bellui drew underneath, never the native view.
  • Render-pipeline features do not reach it: [container.RepaintBoundary] FBO caching, dirty-region culling, SetGroupOpacity, world transforms and [container.DirectionScope] mirroring all apply to bellui's surface only.
  • Clipping is native. The host converts its bellui clip bounds into a platform clip or mask (see NativeView.SetGeometry); a backend that does not implement one will overflow an enclosing [container.Scroll].

Use it when the embedded content genuinely has to be an OS view. When bellui can draw the content itself, draw it — a real widget composites, captures, clips and mirrors for free.

Keyboard focus

Keyboard focus is arbitrated by the platform's own responder chain, which bellui's canvas focus knows nothing about, so a host whose backend implements NativeViewFocuser bridges the two (#59):

  • When the platform view takes the OS focus — which is what a click inside it does — the host clears the canvas focus, so no bellui widget is left drawing a caret while the keystrokes go to the OS view.
  • When bellui focuses one of its own widgets while the platform view still holds the OS focus, the host makes the platform view resign it, so the OS routes keys and IME composition back to bellui.

The bridge rides the same per-frame sync as the geometry (see Lifecycle), polling the backend rather than requiring every platform to grow a focus-change notification; a backend that does not implement NativeViewFocuser simply has no bridge, and focus behaves as it did before.

A NativeViewHost is deliberately *not* a Tab stop. Once the platform view holds the OS focus bellui never sees the Tab key, so it could not move the focus back out — putting the host in the Tab ring would create a keyboard trap (WCAG 2.1.2 No Keyboard Trap), which is worse than not being reachable by Tab at all. Focus reaches the platform view by clicking into it, or programmatically through NativeViewHost.FocusNativeView.

Lifecycle

The host attaches its NativeView once it is laid out on a canvas, then re-syncs the view's geometry and visibility every frame while it is shown, so the native view tracks scrolling, resizing and layout changes the widget itself is never told about. Hiding the host, scrolling it fully out of a clipping ancestor, or removing it from the tree hides the native view; destroying the renderer (the widget leaving the tree, or its window closing) destroys it.

All methods must be called on the main goroutine.

Since: 1.0

func NewNativeViewHost

func NewNativeViewHost(view NativeView) *NativeViewHost

NewNativeViewHost returns a host that embeds view at its position in the layout. The view is not created until the host is laid out on a canvas.

Since: 1.0

func (*NativeViewHost) CreateRenderer

func (h *NativeViewHost) CreateRenderer() core.WidgetRenderer

CreateRenderer returns a renderer that draws nothing. The space the host occupies is a hole through which the native view is seen.

func (*NativeViewHost) FocusNativeView

func (h *NativeViewHost) FocusNativeView() bool

FocusNativeView hands the OS keyboard focus to the platform view, the way a click inside it would, and clears the canvas focus so no bellui widget is left drawing itself focused. It reports whether the platform accepted.

It is the programmatic way into a native view: the host is deliberately not a Tab stop (see NativeViewHost), so an app that wants the keyboard to start in the embedded content calls this. It reports false for a backend that does not implement NativeViewFocuser, or one that has not attached.

func (*NativeViewHost) Hide

func (h *NativeViewHost) Hide()

Hide hides the host and its native view.

func (*NativeViewHost) MinSize

func (h *NativeViewHost) MinSize() geo.Size

MinSize returns the minimum size of the host. A native view has no intrinsic size bellui can measure — the OS owns its content — so this defaults to 0x0 and the host takes whatever the layout gives it. Set a floor with NativeViewHost.SetMinSize when the layout would otherwise collapse it.

func (*NativeViewHost) Move

func (h *NativeViewHost) Move(pos geo.Position)

Move moves the host and re-places its native view.

func (*NativeViewHost) NativeViewFocused

func (h *NativeViewHost) NativeViewFocused() bool

NativeViewFocused reports whether the OS keyboard focus is inside the platform view, meaning keys and input-method composition are going to it rather than to bellui. It reports false for a backend that cannot take focus.

func (*NativeViewHost) Refresh

func (h *NativeViewHost) Refresh()

Refresh re-places the native view along with the widget.

func (*NativeViewHost) Resize

func (h *NativeViewHost) Resize(size geo.Size)

Resize resizes the host and re-places its native view.

func (*NativeViewHost) SetMinSize

func (h *NativeViewHost) SetMinSize(min geo.Size)

SetMinSize sets the smallest size this host should be laid out at. Use device-independent points, not pixels, as with any other widget size.

func (*NativeViewHost) Show

func (h *NativeViewHost) Show()

Show shows the host and its native view.

func (*NativeViewHost) SyncStats

func (h *NativeViewHost) SyncStats() (syncs, applies uint64)

SyncStats reports how many per-frame geometry evaluations have run and how many of them actually reached the backend. It exists to make the cost of the per-frame sync measurable; the counters are cumulative for the life of the host.

func (*NativeViewHost) View

func (h *NativeViewHost) View() NativeView

View returns the platform view this host drives.

type NavigationBar struct {
	BaseWidget
	Items     []*NavigationBarItem
	Selected  int       // index of the selected destination; out of range selects nothing
	OnChanged func(int) `json:"-"`
}

NavigationBar is an MD3 bottom navigation bar with 3-5 destinations.

func NewNavigationBar

func NewNavigationBar(items []*NavigationBarItem, changed func(int)) *NavigationBar

NewNavigationBar creates a bottom navigation bar.

func (n *NavigationBar) AccessibleLabel() string

AccessibleLabel returns an empty string.

func (n *NavigationBar) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleNavigation.

func (n *NavigationBar) CreateRenderer() core.WidgetRenderer
func (n *NavigationBar) MinSize() geo.Size
type NavigationBarItem struct {
	Label string
	Icon  bellui.Resource
}

NavigationBarItem represents a destination in a NavigationBar.

type NavigationDrawer struct {
	Items     []*NavigationDrawerItem
	Header    core.CanvasObject // optional header content
	Selected  int
	OnChanged func(int) `json:"-"`
	Modal     bool
	// contains filtered or unexported fields
}

NavigationDrawer is an MD3 slide-out side panel with destinations.

func NewNavigationDrawer

func NewNavigationDrawer(items []*NavigationDrawerItem, changed func(int)) *NavigationDrawer

NewNavigationDrawer creates a navigation drawer.

func (d *NavigationDrawer) Hide()

Hide dismisses the drawer.

func (d *NavigationDrawer) IsOpen() bool

IsOpen returns whether the drawer is showing.

func (d *NavigationDrawer) Show(c core.Canvas)

Show displays the drawer on the given canvas.

func (d *NavigationDrawer) Toggle(c core.Canvas)

Toggle opens or closes the drawer.

type NavigationDrawerItem struct {
	Label     string
	Icon      bellui.Resource
	IsDivider bool // true = render as separator
}

NavigationDrawerItem represents a destination in a NavigationDrawer.

type NavigationRail struct {
	BaseWidget
	Items      []*NavigationRailItem
	Selected   int       // index of the selected destination; out of range selects nothing
	ShowLabels bool      // show labels below icons
	OnChanged  func(int) `json:"-"`
}

NavigationRail is an MD3 side navigation rail with 3-7 destinations.

func NewNavigationRail

func NewNavigationRail(items []*NavigationRailItem, changed func(int)) *NavigationRail

NewNavigationRail creates a side navigation rail.

func (n *NavigationRail) AccessibleLabel() string

AccessibleLabel returns an empty string.

func (n *NavigationRail) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleNavigation.

func (n *NavigationRail) CreateRenderer() core.WidgetRenderer
func (n *NavigationRail) MinSize() geo.Size
type NavigationRailItem struct {
	Label string
	Icon  bellui.Resource
}

NavigationRailItem represents a destination in a NavigationRail.

type NumericEntry

type NumericEntry struct {
	Entry

	// AllowFloat permits decimal point input. Default true.
	AllowFloat bool
	// AllowNegative permits minus sign input. Default true.
	AllowNegative bool

	// LocaleFormat enables locale-aware decimal and grouping separators.
	// When false (default), '.' is always the decimal separator.
	// When true, the locale's decimal separator is used for display and input.
	LocaleFormat bool

	// Min is the minimum allowed value. Nil means no lower bound.
	Min *float64
	// Max is the maximum allowed value. Nil means no upper bound.
	Max *float64

	// OnValueChanged is called when the text changes to a valid number.
	//
	// It fires from the text-change path (not from validation), so it runs only
	// on an actual edit, never speculatively from a [NumericEntry.Validate] call.
	// NumericEntry installs an internal [Entry.OnChanged] handler to drive this;
	// assigning OnChanged directly will disable OnValueChanged.
	OnValueChanged func(float64) `json:"-"`

	// OnTypedKey is an optional callback for key events before default handling.
	// Return true to consume the event and prevent default processing.
	OnTypedKey func(*event.KeyEvent) bool `json:"-"`
}

NumericEntry is an Entry that only accepts numeric input. Text is right-aligned by default. Non-numeric keystrokes are silently rejected.

Since: 1.0

func NewIntegerEntry

func NewIntegerEntry() *NumericEntry

NewIntegerEntry creates a new right-aligned entry that accepts integers only.

Since: 1.0

func NewNumericEntry

func NewNumericEntry() *NumericEntry

NewNumericEntry creates a new right-aligned entry that accepts floating point numbers.

Since: 1.0

func (*NumericEntry) ReplaceAccessibleSelection

func (e *NumericEntry) ReplaceAccessibleSelection(text string)

ReplaceAccessibleSelection filters non-numeric content before applying the edit, so range replacements that bypass TypedRune — the accessibility text protocols and the mobile text-input / IME mirror (pre-rebrand tracker #771), which route select-and-replace and paste-like edits through this path — still respect the numeric constraint (pre-rebrand tracker #782). An empty replacement (a deletion) passes through; a replacement that filters down to nothing is dropped, matching TypedRune's silent rejection.

func (*NumericEntry) SetBounds

func (e *NumericEntry) SetBounds(min, max float64)

SetBounds sets both Min and Max. Pass math.Inf(-1) or math.Inf(1) to clear a bound.

func (*NumericEntry) SetValue

func (e *NumericEntry) SetValue(v float64)

SetValue sets the entry text to the string representation of the given value.

func (*NumericEntry) TypedKey

func (e *NumericEntry) TypedKey(key *event.KeyEvent)

TypedKey forwards key events to OnTypedKey if set, then to the Entry.

func (*NumericEntry) TypedRune

func (e *NumericEntry) TypedRune(r rune)

TypedRune filters non-numeric characters before passing to the Entry.

func (*NumericEntry) TypedShortcut

func (e *NumericEntry) TypedShortcut(s core.Shortcut)

TypedShortcut intercepts paste to filter non-numeric content.

func (*NumericEntry) Value

func (e *NumericEntry) Value() (float64, error)

Value returns the current numeric value, or 0 and an error if the text is not a valid number.

type Orientation

type Orientation int

Orientation controls the horizontal/vertical layout of a widget

const (
	Horizontal Orientation = 0
	Vertical   Orientation = 1

	// Adaptive will switch between horizontal and vertical layouts according to device orientation.
	// This orientation is not always supported and interpretation can vary per-widget.
	//
	// Since: 1.0
	Adaptive Orientation = 2
)

Orientation constants to control widget layout

type ParagraphSegment

type ParagraphSegment struct {
	Texts []RichTextSegment
}

ParagraphSegment wraps a number of text elements in a paragraph. It is similar to using a list of text elements when the final style is RichTextStyleParagraph.

Since: 1.0

func (*ParagraphSegment) Inline

func (p *ParagraphSegment) Inline() bool

Inline returns false as a paragraph should be in a block.

func (*ParagraphSegment) Segments

func (p *ParagraphSegment) Segments() []RichTextSegment

Segments returns the list of text elements in this paragraph.

func (*ParagraphSegment) Select

func (p *ParagraphSegment) Select(_, _ geo.Position)

Select does nothing for a paragraph container.

func (*ParagraphSegment) SelectedText

func (p *ParagraphSegment) SelectedText() string

SelectedText returns the empty string for this paragraph container.

func (*ParagraphSegment) Textual

func (p *ParagraphSegment) Textual() string

Textual returns no content for a paragraph container.

func (*ParagraphSegment) Unselect

func (p *ParagraphSegment) Unselect()

Unselect does nothing for a paragraph container.

func (*ParagraphSegment) Update

func (p *ParagraphSegment) Update(core.CanvasObject)

Update doesn't need to change a paragraph container.

func (*ParagraphSegment) Visual

func (p *ParagraphSegment) Visual() core.CanvasObject

Visual returns the no extra elements.

type PopUp struct {
	BaseWidget

	Content core.CanvasObject
	Canvas  core.Canvas

	// OnDismissed, when set, replaces hiding as the response to the user
	// dismissing this pop-up. A host that has its own close path — a dialog
	// with a result to report — sets it so that path runs whatever the user
	// dismissed with.
	//
	// Since: 1.0
	OnDismissed func() `json:"-"`
	// contains filtered or unexported fields
}

PopUp is a widget that can float above the user interface. It wraps any standard elements with padding and a shadow. If it is modal then the shadow will cover the entire canvas it hovers over and block interactions.

func NewModalPopUp

func NewModalPopUp(content core.CanvasObject, canvas core.Canvas) *PopUp

NewModalPopUp creates a new popUp for the specified content and displays it on the passed canvas. A modal PopUp blocks interactions with underlying elements, covered with a semi-transparent overlay.

func NewPopUp

func NewPopUp(content core.CanvasObject, canvas core.Canvas) *PopUp

NewPopUp creates a new popUp for the specified content and displays it on the passed canvas.

func (*PopUp) AccessibleActions

func (p *PopUp) AccessibleActions() []core.AccessibleAction

AccessibleActions returns the "dismiss" action for pop-ups that dismiss on an outside tap.

func (*PopUp) AccessibleLabel

func (p *PopUp) AccessibleLabel() string

AccessibleLabel returns an empty string; the content names itself.

func (*PopUp) AccessibleRole

func (p *PopUp) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleDialog for modal pop-ups and core.RoleGroup otherwise. Dialogs, sheets and drawers are all built on modal pop-ups, so this gives each of them a dialog container node; the pop-up's content provides its own semantics as child nodes.

func (*PopUp) AccessibleState

func (p *PopUp) AccessibleState() core.AccessibleState

AccessibleState reports the modal state.

func (*PopUp) CreateRenderer

func (p *PopUp) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*PopUp) DismissOnEscape

func (p *PopUp) DismissOnEscape() bool

DismissOnEscape closes the pop-up because the user pressed Escape, reporting whether it did.

Unlike an outside tap this is not blocked by being modal — Escape is how a user cancels a dialog, and every canvas dialog is a modal pop-up. What does block it is a pop-up that manages its own dismissal (a snackbar) or one that is not an input surface at all (a toast, a tooltip): those keep counting down and leave the key to whatever is beneath them.

Since: 1.0

func (*PopUp) Hide

func (p *PopUp) Hide()

Hide this widget, if it was previously visible

func (*PopUp) MinSize

func (p *PopUp) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below

func (*PopUp) Move

func (p *PopUp) Move(pos geo.Position)

Move the widget to a new position. A PopUp position is absolute to the top, left of its canvas. For PopUp this actually moves the content so checking Position() will not return the same value as is set here.

func (*PopUp) PassesInputThrough

func (p *PopUp) PassesInputThrough() bool

PassesInputThrough marks pass-through pop-ups (transient surfaces like Toast and Snackbar, pre-rebrand tracker #569) as input-transparent for the driver hit tests and the canvas focus routing: taps, scrolls and keyboard input outside the content reach the UI beneath as if the pop-up were not there, per the MD3 rule that transient notifications never block interaction. Taps on the content itself (a Snackbar's action button) still work.

func (*PopUp) PerformAccessibleAction

func (p *PopUp) PerformAccessibleAction(name string)

PerformAccessibleAction dismisses the pop-up, mirroring an outside tap.

func (*PopUp) Resize

func (p *PopUp) Resize(size geo.Size)

Resize changes the size of the PopUp's content. PopUps always have the size of their canvas, but this call updates the size of the content portion.

func (*PopUp) SetPadded

func (p *PopUp) SetPadded(padded bool)

SetPadded controls whether the pop-up surrounds its content with inner padding and positions it accordingly. Disable for content that draws its own chrome, such as a container.InnerWindow.

func (*PopUp) Show

func (p *PopUp) Show()

Show this pop-up as overlay if not already shown.

func (*PopUp) ShowAtPosition

func (p *PopUp) ShowAtPosition(pos geo.Position)

ShowAtPosition shows this pop-up at the given position.

func (*PopUp) ShowAtRelativePosition

func (p *PopUp) ShowAtRelativePosition(rel geo.Position, to core.CanvasObject)

ShowAtRelativePosition shows this pop-up at the given position relative to stated object.

Since: 1.0

func (*PopUp) Tapped

func (p *PopUp) Tapped(e *event.PointEvent)

Tapped is called when the user taps the popUp. If not modal and the tap is outside the content area, then dismiss this widget

func (*PopUp) TappedSecondary

func (p *PopUp) TappedSecondary(e *event.PointEvent)

TappedSecondary is called when the user right/alt taps the popUp. If not modal and the tap is outside the content area, then dismiss this widget

type PopUpMenu

type PopUpMenu struct {
	*Menu
	// contains filtered or unexported fields
}

PopUpMenu is a Menu which displays itself in an OverlayContainer.

func NewPopUpMenu

func NewPopUpMenu(menu *bellui.Menu, c core.Canvas) *PopUpMenu

NewPopUpMenu creates a new, reusable popup menu. You can show it using ShowAtPosition.

Since: 1.0

func (*PopUpMenu) AccessibleLabel

func (p *PopUpMenu) AccessibleLabel() string

AccessibleLabel returns an empty string.

func (*PopUpMenu) AccessibleRole

func (p *PopUpMenu) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleMenu.

func (*PopUpMenu) FocusGained

func (p *PopUpMenu) FocusGained()

FocusGained is triggered when the object gained focus. For the pop-up menu it does nothing.

func (*PopUpMenu) FocusLost

func (p *PopUpMenu) FocusLost()

FocusLost is triggered when the object lost focus. For the pop-up menu it does nothing.

func (*PopUpMenu) Hide

func (p *PopUpMenu) Hide()

Hide hides the pop-up menu.

func (*PopUpMenu) Move

func (p *PopUpMenu) Move(pos geo.Position)

Move moves the pop-up menu. The position is absolute because pop-up menus are shown in an overlay which covers the whole canvas.

func (*PopUpMenu) Resize

func (p *PopUpMenu) Resize(size geo.Size)

Resize changes the size of the pop-up menu.

func (*PopUpMenu) Show

func (p *PopUpMenu) Show()

Show makes the pop-up menu visible.

func (*PopUpMenu) ShowAtPosition

func (p *PopUpMenu) ShowAtPosition(pos geo.Position)

ShowAtPosition shows the pop-up menu at the specified position.

func (*PopUpMenu) ShowAtRelativePosition

func (p *PopUpMenu) ShowAtRelativePosition(rel geo.Position, to core.CanvasObject)

ShowAtRelativePosition shows the pop-up menu at the position relative to given object.

Since: 1.0

func (*PopUpMenu) TypedKey

func (p *PopUpMenu) TypedKey(e *event.KeyEvent)

TypedKey handles key events. It allows keyboard control of the pop-up menu.

func (*PopUpMenu) TypedRune

func (p *PopUpMenu) TypedRune(rune)

TypedRune handles text events. For pop-up menus this does nothing.

type ProgressBar

type ProgressBar struct {
	BaseWidget

	Min, Max, Value float64

	// TextFormatter can be used to have a custom format of progress text.
	// If set, it overrides the percentage readout and runs each time the value updates.
	//
	// Since: 1.0
	TextFormatter func() string `json:"-"`
	// contains filtered or unexported fields
}

ProgressBar widget creates a horizontal panel that indicates progress

func NewProgressBar

func NewProgressBar() *ProgressBar

NewProgressBar creates a new progress bar widget. The default Min is 0 and Max is 1, Values set should be between those numbers. The display will convert this to a percentage.

func NewProgressBarWithData

func NewProgressBarWithData(data binding.Float) *ProgressBar

NewProgressBarWithData returns a progress bar connected with the specified data source.

Since: 1.0

func (*ProgressBar) AccessibleLabel

func (p *ProgressBar) AccessibleLabel() string

AccessibleLabel returns an empty string; progress bars have no intrinsic label.

func (*ProgressBar) AccessibleRange

func (p *ProgressBar) AccessibleRange() (min, max, current float64)

AccessibleRange returns the minimum, maximum, and current progress values.

func (*ProgressBar) AccessibleRole

func (p *ProgressBar) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleProgressBar.

func (*ProgressBar) AccessibleValue

func (p *ProgressBar) AccessibleValue() string

AccessibleValue returns a human-readable percentage string.

func (*ProgressBar) Bind

func (p *ProgressBar) Bind(data binding.Float)

Bind connects the specified data source to this ProgressBar. The current value will be displayed and any changes in the data will cause the widget to update.

Since: 1.0

func (*ProgressBar) CreateRenderer

func (p *ProgressBar) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*ProgressBar) MinSize

func (p *ProgressBar) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below

func (*ProgressBar) SetValue

func (p *ProgressBar) SetValue(v float64)

SetValue changes the current value of this progress bar (from p.Min to p.Max). The widget will be refreshed to indicate the change. It is safe to call from any goroutine.

func (*ProgressBar) Unbind

func (p *ProgressBar) Unbind()

Unbind disconnects any configured data source from this ProgressBar. The current value will remain at the last value of the data source.

Since: 1.0

type ProgressBarInfinite

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

ProgressBarInfinite widget creates a horizontal panel that indicates waiting indefinitely An infinite progress bar loops 0% -> 100% repeatedly until Stop() is called

func NewProgressBarInfinite

func NewProgressBarInfinite() *ProgressBarInfinite

NewProgressBarInfinite creates a new progress bar widget that loops indefinitely from 0% -> 100% SetValue() is not defined for infinite progress bar To stop the looping progress and set the progress bar to 100%, call ProgressBarInfinite.Stop()

func (*ProgressBarInfinite) CreateRenderer

func (p *ProgressBarInfinite) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*ProgressBarInfinite) Hide

func (p *ProgressBarInfinite) Hide()

Hide this widget, if it was previously visible

func (*ProgressBarInfinite) MinSize

func (p *ProgressBarInfinite) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below

func (*ProgressBarInfinite) Running

func (p *ProgressBarInfinite) Running() bool

Running returns the current state of the infinite progress animation

func (*ProgressBarInfinite) Show

func (p *ProgressBarInfinite) Show()

Show this widget, if it was previously hidden

func (*ProgressBarInfinite) Start

func (p *ProgressBarInfinite) Start()

Start the infinite progress bar animation

func (*ProgressBarInfinite) Stop

func (p *ProgressBarInfinite) Stop()

Stop the infinite progress bar animation

type ProtectedRange

type ProtectedRange struct {
	Start, End  int
	CaretOpaque bool
}

ProtectedRange marks a span of an Entry's text that the widget refuses to mutate. Offsets are rune indices into Text, half-open [Start, End). An edit overlapping the span is rejected across every edit path, and undo/redo cannot re-introduce it.

When CaretOpaque is true the caret is additionally barred from entering the span: arrow navigation, clicks and mobile taps cannot land strictly inside it (used for fully-masked / redacted regions). The caret may still rest on either boundary. Touch placement is enforced through the same updateMousePointer path as desktop clicks.

Offsets are rune indices into the current Text; the caller owns reconciling them when Text changes.

Since: 1.0

type RadioGroup

type RadioGroup struct {
	DisableableWidget
	Horizontal bool
	Required   bool
	OnChanged  func(string) `json:"-"`
	Options    []string
	Selected   string
	// contains filtered or unexported fields
}

RadioGroup widget has a list of text labels and checks check icons next to each. Changing the selection (only one can be selected) will trigger the changed func.

Since: 1.0

func NewRadioGroup

func NewRadioGroup(options []string, changed func(string)) *RadioGroup

NewRadioGroup creates a new radio group widget with the set options and change handler

Since: 1.0

func (*RadioGroup) AccessibleLabel

func (r *RadioGroup) AccessibleLabel() string

AccessibleLabel returns the currently selected option.

func (*RadioGroup) AccessibleRole

func (r *RadioGroup) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleRadioGroup.

func (*RadioGroup) Append

func (r *RadioGroup) Append(option string)

Append adds a new option to the end of a RadioGroup widget.

func (*RadioGroup) CreateRenderer

func (r *RadioGroup) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*RadioGroup) MinSize

func (r *RadioGroup) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below

func (*RadioGroup) Refresh

func (r *RadioGroup) Refresh()

func (*RadioGroup) SetSelected

func (r *RadioGroup) SetSelected(option string)

SetSelected sets the radio option, it can be used to set a default option. It is safe to call from any goroutine.

type RangeSlider

type RangeSlider struct {
	BaseWidget

	LowValue  float64
	HighValue float64
	Min       float64
	Max       float64
	Step      float64

	Orientation Orientation
	OnChanged   func(low, high float64) `json:"-"`

	// OnChangeEnded is called once a change to the range has settled: the end of
	// a drag that moved a thumb, a tap, a screen-reader adjustment, or a call to
	// [RangeSlider.SetValues]. It is the commit signal a trim control (video
	// in/out points) acts on, as distinct from the stream of in-drag OnChanged
	// updates.
	//
	// It only fires when a thumb actually moved, so a press and release that
	// changed nothing reports neither callback — use [RangeSlider.Dragging] to
	// track drag state rather than inferring it from the callback pair.
	//
	// Since: 1.0
	OnChangeEnded func(low, high float64) `json:"-"`

	// OnHover is called with the value under the pointer as it moves across the
	// slider, without moving either thumb. It is the seam a media scrubber uses
	// to preview the frame at a position before committing a seek.
	//
	// The reported value is continuous — it is NOT snapped to Step, since a
	// preview wants the true pointer position and a consumer that wants the
	// snapped value can round it, while the reverse is not recoverable. It is
	// clamped to [Min, Max].
	//
	// Since: 1.0
	OnHover func(float64) `json:"-"`

	// OnHoverEnd is called when the pointer leaves the slider, so anything shown
	// in response to OnHover can be taken down again.
	//
	// Since: 1.0
	OnHoverEnd func() `json:"-"`
	// contains filtered or unexported fields
}

RangeSlider is a widget with two thumbs for selecting a value range.

func NewRangeSlider

func NewRangeSlider(min, max float64) *RangeSlider

NewRangeSlider creates a range slider with the given bounds.

func (*RangeSlider) AccessibleLabel

func (s *RangeSlider) AccessibleLabel() string

AccessibleLabel returns an empty string; the group has no intrinsic label and each thumb carries its own.

func (*RangeSlider) AccessibleRole

func (s *RangeSlider) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleGroup: a range slider is a container of two independently adjustable thumbs — the low and high sliders — each exposed as its own accessible child ([rangeSliderThumb], pre-rebrand tracker #810) rather than a single slider. Mobile screen readers flatten the group away and surface the two thumb sliders directly; desktop screen readers present them within the group.

func (*RangeSlider) CreateRenderer

func (s *RangeSlider) CreateRenderer() core.WidgetRenderer

func (*RangeSlider) Disable

func (s *RangeSlider) Disable()

Disable makes the range slider read-only: drags, taps, arrow keys and screen-reader adjustments no longer move either thumb, and the thumbs and active track are painted in the disabled colour.

Since: 1.0

func (*RangeSlider) Disabled

func (s *RangeSlider) Disabled() bool

Disabled reports whether the range slider is currently disabled.

Since: 1.0

func (*RangeSlider) DragEnd

func (s *RangeSlider) DragEnd()

func (*RangeSlider) Dragged

func (s *RangeSlider) Dragged(e *event.DragEvent)

func (*RangeSlider) Dragging

func (s *RangeSlider) Dragging() bool

Dragging reports whether the user is currently dragging one of the thumbs, between the first Dragged event and DragEnd.

This is the authoritative signal a media scrubber needs in order to suppress its own periodic position updates while the user is scrubbing — otherwise a thumb jumps back under the pointer on every tick. Inferring it from OnChanged/OnChangeEnded instead is unreliable: a press and release that does not move a thumb fires neither callback.

Since: 1.0

func (*RangeSlider) DraggingHigh

func (s *RangeSlider) DraggingHigh() bool

DraggingHigh reports which thumb an in-progress drag is moving: true for the high thumb, false for the low one. It is only meaningful while RangeSlider.Dragging reports true — afterwards it retains the thumb the last drag moved.

Since: 1.0

func (*RangeSlider) Enable

func (s *RangeSlider) Enable()

Enable reverses RangeSlider.Disable.

Since: 1.0

func (*RangeSlider) FocusGained

func (s *RangeSlider) FocusGained()

FocusGained is called when this widget gains keyboard focus.

Since: 1.0

func (*RangeSlider) FocusLost

func (s *RangeSlider) FocusLost()

FocusLost is called when this widget loses keyboard focus.

Since: 1.0

func (*RangeSlider) FocusedHigh

func (s *RangeSlider) FocusedHigh() bool

FocusedHigh reports which thumb the arrow keys currently move: true for the high thumb, false for the low one. It follows the thumb the pointer last acted on and is changed from the keyboard by the cross-axis arrows.

Since: 1.0

func (*RangeSlider) HoverIn

func (s *RangeSlider) HoverIn(e *event.HoverEvent)

func (*RangeSlider) HoverMoved

func (s *RangeSlider) HoverMoved(e *event.HoverEvent)

func (*RangeSlider) HoverOut

func (s *RangeSlider) HoverOut()

func (*RangeSlider) MinSize

func (s *RangeSlider) MinSize() geo.Size

func (*RangeSlider) SetFocusedHigh

func (s *RangeSlider) SetFocusedHigh(high bool)

SetFocusedHigh selects which thumb the arrow keys move.

Since: 1.0

func (*RangeSlider) SetValues

func (s *RangeSlider) SetValues(low, high float64)

SetValues updates both thumb positions, clamping each into [Min, Max], snapping to Step and swapping them if they arrive the wrong way round. It is safe to call from any goroutine.

The change is reported as though the user made it: both OnChanged and OnChangeEnded fire, matching Slider.SetValue. For programmatic updates that should not look like user interaction — a player advancing a preview range many times a second — use RangeSlider.SetValuesSilently.

func (*RangeSlider) SetValuesSilently

func (s *RangeSlider) SetValuesSilently(low, high float64)

SetValuesSilently updates both thumb positions and redraws, without firing OnChanged or OnChangeEnded. It is safe to call from any goroutine.

This is the path for updates the user did not cause, where every RangeSlider.SetValues call would otherwise be indistinguishable from the user dragging a thumb.

Since: 1.0

func (*RangeSlider) Tapped

func (s *RangeSlider) Tapped(e *event.PointEvent)

func (*RangeSlider) TypedKey

func (s *RangeSlider) TypedKey(key *event.KeyEvent)

TypedKey adjusts the range from the keyboard.

The arrows along the slider's own axis — Left/Right when horizontal, Up/Down when vertical — move the focused thumb by one step. The arrows across that axis switch which thumb is focused: a two-thumb control needs a switch that Slider does not, and the cross-axis arrows are the only keys free to carry it (Tab must keep moving focus out of the widget, and Home/End are left for a future jump-to-extreme). The focused thumb also follows the last drag or tap, so in practice the switch is rarely needed.

The step is RangeSlider.Step when set, falling back to a hundredth of the range, so the arrows still work on a slider with no explicit Step.

Since: 1.0

func (*RangeSlider) TypedRune

func (s *RangeSlider) TypedRune(_ rune)

TypedRune is called when this widget receives a character event. A range slider has nothing to do with typed text.

Since: 1.0

type Renderer

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

Renderer builds a WidgetRenderer using a fluent API, eliminating the need for a separate renderer struct. Each method is optional with sensible defaults.

Usage inside CreateRenderer:

func (w *MyBadge) CreateRenderer() core.WidgetRenderer {
    bg := canvas.NewRectangle(color.NRGBA{R: 200, A: 255})
    label := canvas.NewText(w.Text, color.White)

    return widget.NewRenderer(bg, label).
        Layout(func(size geo.Size) {
            bg.Resize(size)
            label.Move(geo.NewPos(8, 4))
        }).
        MinSizeFunc(func() geo.Size {
            ts := label.MinSize()
            return geo.NewSize(ts.Width+16, ts.Height+8)
        }).
        Refresh(func() {
            label.Text = w.Text
            canvas.Refresh(label)
        })
}

Defaults:

  • Layout: all objects resize to fill the widget
  • MinSize: largest child's MinSize
  • Refresh: no-op
  • Destroy: no-op

func NewRenderer

func NewRenderer(objects ...core.CanvasObject) *Renderer

NewRenderer creates a renderer with the given canvas objects.

func (*Renderer) Build

func (r *Renderer) Build() core.WidgetRenderer

Build returns the WidgetRenderer. Call this at the end of the builder chain if needed for explicit type conversion.

func (*Renderer) DestroyFunc

func (r *Renderer) DestroyFunc(fn func()) *Renderer

DestroyFunc sets a cleanup function called when the renderer is disposed.

func (*Renderer) Layout

func (r *Renderer) Layout(fn func(geo.Size)) *Renderer

Layout sets the layout function that positions child objects.

func (*Renderer) MinSizeFunc

func (r *Renderer) MinSizeFunc(fn func() geo.Size) *Renderer

MinSizeFunc sets a custom minimum size calculator.

func (*Renderer) Objects

func (r *Renderer) Objects() []core.CanvasObject

func (*Renderer) Refresh

func (r *Renderer) Refresh(fn func()) *Renderer

Refresh sets the function called when the widget state changes and canvas objects need updating (colors, text, visibility).

func (*Renderer) SetObjects

func (r *Renderer) SetObjects(objects []core.CanvasObject)

type RichEntry

type RichEntry struct {
	BaseWidget

	// OnChanged is called, on the main goroutine, after any edit that changes the
	// content.
	//
	// Since: 1.0
	OnChanged func()

	// OnContentChanged is called, on the main goroutine, after any edit that
	// changes the content, with the current document segments. The slice is the
	// live backing store — treat it as read-only (the same contract as
	// [RichEntry.Segments]). Use this instead of OnChanged + Segments() when a
	// host wants the rich content on every change without a separate read.
	//
	// Since: 1.0
	OnContentChanged func([]RichTextSegment)

	// Wrapping selects how logical lines that exceed the width are laid out. The
	// default [bellui.TextWrapOff] keeps each '\n'-separated line on one rendered row
	// (horizontal scrolling is the caller's concern); [bellui.TextWrapWord] and
	// [bellui.TextWrapBreak] soft-wrap a long line onto multiple visual rows, with
	// the caret and selection mapping following the wrap (pre-rebrand tracker #653).
	//
	// Since: 1.0
	Wrapping bellui.TextWrap

	// Style selects the MD3 visual chrome, matching [Entry.Style]: [EntryStyleFilled]
	// (the default) draws a filled rounded-rect background; [EntryStyleOutlined] is
	// transparent with an always-visible outline. In both styles the border adopts
	// the primary color while focused.
	//
	// Since: 1.0
	Style EntryStyle

	// TypingStyle is the style applied to newly typed text. Its zero value means
	// "inherit the style at the caret" (typing inside a bold run stays bold); set
	// it to type in a specific style regardless of the surrounding runs.
	//
	// Since: 1.0
	TypingStyle RichTextStyle
	// contains filtered or unexported fields
}

RichEntry is an editable rich-text surface: text with per-run styling laid out and rendered by RichText, edited through a segment-aware document model (pre-rebrand tracker #648, Phase 1).

Unlike Entry — which is flat-string / single-segment to the bone — RichEntry stores its content as an ordered list of [TextSegment]s and ImageSegment atoms, and addresses the caret and selection with a position model in which each image occupies exactly one position. It covers text editing (typing, deletion, caret navigation, selection), per-run styling via RichEntry.ApplyStyle, undo/redo, IME composition, flavor-aware clipboard, and both block and inline images (RichEntry.InsertImage / RichEntry.InsertInlineImage, pre-rebrand tracker #665). Word/character wrapping is opt-in via RichEntry.Wrapping (pre-rebrand tracker #653; the default is off, one rendered row per '\n'-separated line).

Since: 1.0

func NewRichEntry

func NewRichEntry() *RichEntry

NewRichEntry creates a new empty rich-text editor.

Since: 1.0

func (*RichEntry) AccessibleActions

func (e *RichEntry) AccessibleActions() []core.AccessibleAction

AccessibleActions declares the editor's undo/redo actions (pre-rebrand tracker #1025), each gated on its history being non-empty — the same availability rule as Entry.AccessibleActions and the TappedSecondary context menu. The backends surface them data-driven (VoiceOver's actions rotor, TalkBack's actions menu, AT-SPI Action) now that the editor carries its semantic role.

func (*RichEntry) AccessibleCaret

func (e *RichEntry) AccessibleCaret() int

AccessibleCaret returns the rune offset of the insertion point.

func (*RichEntry) AccessibleComposing

func (e *RichEntry) AccessibleComposing() bool

AccessibleComposing reports whether an IME composition is currently active, for the text-input mirror seam's stale-finalize detection (pre-rebrand tracker #1057) — see the Entry.AccessibleComposing doc.

func (*RichEntry) AccessibleLabel

func (e *RichEntry) AccessibleLabel() string

AccessibleLabel returns no intrinsic name; hosts name the editor via BaseWidget.SetAccessibilityLabel.

func (*RichEntry) AccessibleLineCount

func (e *RichEntry) AccessibleLineCount() int

AccessibleLineCount returns the number of rendered (visual) rows — one per wrapped line and one per block image (see core.AccessibleTextLayouter).

func (*RichEntry) AccessibleLineForOffset

func (e *RichEntry) AccessibleLineForOffset(off int) int

AccessibleLineForOffset returns the zero-based visual row containing the rune offset, clamped to the content (see core.AccessibleTextLayouter).

func (*RichEntry) AccessibleLineRange

func (e *RichEntry) AccessibleLineRange(line int) (start, end int, ok bool)

AccessibleLineRange returns the half-open rune range of the zero-based visual row (see core.AccessibleTextLayouter): end is the start of the following row — covering a terminating newline or the soft-wrap boundary that sits in the one-position gap between rows — or the content length on the last row.

func (*RichEntry) AccessibleRange

func (e *RichEntry) AccessibleRange() (min, max, current float64)

AccessibleRange is not applicable to text editors; it returns zeros.

func (*RichEntry) AccessibleRangeBounds

func (e *RichEntry) AccessibleRangeBounds(start, end int) []geo.Rectangle

AccessibleRangeBounds returns one rectangle per visible visual row touched by the rune range, in RichEntry's own coordinate space — the same space as RichEntry.PreeditCursorRectangle (see core.AccessibleTextLayouter). Rows are laid out top to bottom, so once a row starts below the widget viewport the walk stops; each rectangle is clipped to the viewport and a row clipped away entirely is omitted. Each rectangle spans the caret rectangles at the range's endpoints within that row — an approximation on bidirectional rows, where reordered runs may extend past the endpoint span.

RichEntry does not virtualize, so a range spanning many rows in a widget as tall as its content yields one rectangle per row; the enclosing [container.Scroll] clips the display. In practice the bridges query small ranges (the selection/marked range for the VoiceOver ring), so this is bounded by the selection, not the document.

func (*RichEntry) AccessibleRole

func (e *RichEntry) AccessibleRole() core.AccessibleRole

AccessibleRole reports the rich editor as a multi-line text input — the semantic-role half of pre-rebrand tracker #659, deferred when the AccessibleTexter seam shipped and delivered during the pre-rebrand tracker #951 device pass: without a text role the editor publishes no accessibility element at all, so a screen reader cannot focus it and the mobile input-view swap (pre-rebrand tracker #570/#1124) never engages — leaving VoiceOver caret navigation with no editing context. The role also makes the editor one semantic unit (NonInteractiveChildrenPresentational prunes the internal render widgets that paint its value).

func (*RichEntry) AccessibleSelection

func (e *RichEntry) AccessibleSelection() (start, end int)

AccessibleSelection returns the selection as a half-open [start, end) rune range; with no selection both offsets are the caret position.

func (*RichEntry) AccessibleText

func (e *RichEntry) AccessibleText() string

AccessibleText returns the document as a rune stream in its global position space: text runes verbatim and each non-text atom as one U+FFFC object replacement character, so a rune offset into the result is a caret offset (matching RichEntry.AccessibleSelection).

The result is memoized and invalidated only on committed-content changes (afterEditNotify — edits, undo/redo, paste, image insert — and SetSegments), not on the broad syncProvider that also runs on every repaint, IME preedit and restyle: those leave this rune stream unchanged, so dropping the memo there would rebuild the whole string per query for no reason — the exact large-doc thrash the desktop a11y-text bridges hit while a screen reader tracks the caret during CJK composition (pre-rebrand tracker #794). The mobile text-input mirror's per-paint-frame sync (pre-rebrand tracker #783) thus reuses the same string object until the next real edit, so the seam's redundant-push filter stays O(1). Main-goroutine-owned, like the rest of the widget's state.

func (*RichEntry) AccessibleValue

func (e *RichEntry) AccessibleValue() string

AccessibleValue returns the document's accessible rune stream (atoms as U+FFFC), matching the offsets the editable-text protocols use.

func (*RichEntry) ApplyStyle

func (e *RichEntry) ApplyStyle(style RichTextStyle)

ApplyStyle applies a style to the current selection, splitting runs at the selection boundaries. With no selection it sets RichEntry.TypingStyle so the next typed text uses the style.

Since: 1.0

func (*RichEntry) Compose

func (e *RichEntry) Compose(ev *event.PreeditEvent)

Compose sets or replaces the inline preedit text shown at the caret. It does not change the document, undo history or change callbacks.

func (*RichEntry) ComposeCancel

func (e *RichEntry) ComposeCancel()

ComposeCancel discards any in-progress composition without committing.

func (*RichEntry) ComposeCommit

func (e *RichEntry) ComposeCommit(text string)

ComposeCommit finalizes composition, inserting the committed text as one edit.

func (*RichEntry) CreateRenderer

func (e *RichEntry) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer.

func (*RichEntry) Cursor

func (e *RichEntry) Cursor() desktop.Cursor

Cursor shows the text I-beam while hovering the editor.

func (*RichEntry) DoubleTapped

func (e *RichEntry) DoubleTapped(ev *event.PointEvent)

DoubleTapped selects the word under the pointer, mirroring Entry. On mobile, where there is no Shift key, double-tap is a primary way to begin a selection.

func (*RichEntry) DragEnd

func (e *RichEntry) DragEnd()

DragEnd finalizes a drag selection, collapsing it when the drag selected nothing (a press-drag that returned to its origin).

func (*RichEntry) Dragged

func (e *RichEntry) Dragged(d *event.DragEvent)

Dragged extends a text selection as the pointer (or touch) moves. The first event of a drag anchors the selection at the drag's start position; later events move the caret end. This is the only selection path on mobile, which has no Shift key (pre-rebrand tracker #750).

func (*RichEntry) FocusGained

func (e *RichEntry) FocusGained()

FocusGained is called when the RichEntry has been given focus.

func (*RichEntry) FocusLost

func (e *RichEntry) FocusLost()

FocusLost is called when the RichEntry has had focus removed.

func (*RichEntry) Hide

func (e *RichEntry) Hide()

Hide hides the editor, dismissing its mobile selection handles with it.

func (*RichEntry) InsertImage

func (e *RichEntry) InsertImage(img image.Image)

InsertImage inserts an in-memory image at the caret as one undo step. The image is a block that occupies its own row; the caret lands after it. Any current selection is replaced.

Since: 1.0

func (*RichEntry) InsertImageResource

func (e *RichEntry) InsertImageResource(res bellui.Resource)

InsertImageResource is like RichEntry.InsertImage for a resource-backed image (e.g. bundled bytes).

Since: 1.0

func (*RichEntry) InsertInlineImage

func (e *RichEntry) InsertInlineImage(img image.Image)

InsertInlineImage inserts an in-memory image that flows *within* the current text row (like a large glyph) rather than on its own block row, as one undo step. The image occupies one caret position; any current selection is replaced (pre-rebrand tracker #665).

Since: 1.0

func (*RichEntry) InsertInlineImageResource

func (e *RichEntry) InsertInlineImageResource(res bellui.Resource)

InsertInlineImageResource is like RichEntry.InsertInlineImage for a resource-backed image.

Since: 1.0

func (*RichEntry) KeyDown

func (e *RichEntry) KeyDown(key *event.KeyEvent)

KeyDown records shift-key presses so cursor navigation extends the selection.

func (*RichEntry) KeyUp

func (e *RichEntry) KeyUp(key *event.KeyEvent)

KeyUp clears the shift-key state.

func (*RichEntry) Keyboard

func (e *RichEntry) Keyboard() mobile.KeyboardType

Keyboard returns the type of keyboard to show on mobile devices.

func (*RichEntry) LongPressed

func (e *RichEntry) LongPressed(ev *event.PointEvent)

LongPressed implements event.LongPressable. A touch held on the editor places the caret at the press point and selects the word under it — the native mobile gesture; the release that follows opens the context menu via TappedSecondary. Desktop right-click is unaffected (it dispatches TappedSecondary directly). The embedded selectable forwards the driver's dispatch here (it is the deeper LongPressable in the object tree).

func (*RichEntry) MouseDown

func (e *RichEntry) MouseDown(*desktop.MouseEvent)

MouseDown records that the active pointer is a mouse (forwarded by the embedded selectable, which grabs focus itself).

func (*RichEntry) MouseUp

func (e *RichEntry) MouseUp(*desktop.MouseEvent)

MouseUp implements desktop.Mouseable.

func (*RichEntry) PerformAccessibleAction

func (e *RichEntry) PerformAccessibleAction(name string)

PerformAccessibleAction invokes the named accessible action.

func (*RichEntry) PreeditCursorRectangle

func (e *RichEntry) PreeditCursorRectangle() geo.Rectangle

PreeditCursorRectangle reports the caret rectangle so a driver can position the IME candidate window. It implements event.PreeditPositioner.

func (*RichEntry) Redo

func (e *RichEntry) Redo()

Redo re-applies the last undone edit. It is a no-op when there is nothing to redo.

Since: 1.0

func (*RichEntry) ReplaceAccessibleSelection

func (e *RichEntry) ReplaceAccessibleSelection(text string)

ReplaceAccessibleSelection replaces the current selection — or inserts at the caret — with text, as one gated, undo-recorded edit (one OnChanged). An empty text deletes the selection. Safe to call from any goroutine.

func (*RichEntry) Segments

func (e *RichEntry) Segments() []RichTextSegment

Segments returns the current document segments. The slice is the live backing store — treat it as read-only and use the editing methods to mutate content.

Since: 1.0

func (*RichEntry) SelectedText

func (e *RichEntry) SelectedText() string

SelectedText returns the currently selected text, or the empty string when nothing is selected.

Since: 1.0

func (*RichEntry) SetAccessibleSelection

func (e *RichEntry) SetAccessibleSelection(start, end int)

SetAccessibleSelection selects [start, end), clamped to the document; equal offsets place the caret there with no selection. Safe to call from any goroutine.

func (*RichEntry) SetSegments

func (e *RichEntry) SetSegments(segs []RichTextSegment)

SetSegments replaces the editor content with the given rich-text segments and moves the caret to the start. Text segments are forced inline; non-text segments are rendered but not yet caret-addressable (Phase 1).

Since: 1.0

func (*RichEntry) String

func (e *RichEntry) String() string

String returns the plain-text content of the editor.

Since: 1.0

func (*RichEntry) Tapped

func (e *RichEntry) Tapped(ev *event.PointEvent)

Tapped focuses the editor and places the caret at the tapped position.

func (*RichEntry) TappedSecondary

func (e *RichEntry) TappedSecondary(pe *event.PointEvent)

TappedSecondary opens the editor's context menu (Undo/Redo when available, Cut, Copy, Paste, Select all) at the tapped position. On mobile it is also re-summoned after a long-press release or a handle adjustment — the native "text toolbar reappears" behavior (pre-rebrand tracker #945).

func (*RichEntry) TouchCancel

func (e *RichEntry) TouchCancel(*mobile.TouchEvent)

TouchCancel implements mobile.Touchable.

func (*RichEntry) TouchDown

func (e *RichEntry) TouchDown(*mobile.TouchEvent)

TouchDown records that the active pointer is a touch, which gates the selection handles to touch-initiated selections. The embedded selectable forwards its TouchDown here (like the other pointer gestures).

func (*RichEntry) TouchUp

func (e *RichEntry) TouchUp(*mobile.TouchEvent)

TouchUp implements mobile.Touchable.

func (*RichEntry) TypedKey

func (e *RichEntry) TypedKey(key *event.KeyEvent)

TypedKey receives key input events for editing and navigation.

func (*RichEntry) TypedRune

func (e *RichEntry) TypedRune(r rune)

TypedRune receives text input events and inserts the rune at the caret. While an IME composition is active, a typed rune commits it (the desktop char callback path).

func (*RichEntry) TypedShortcut

func (e *RichEntry) TypedShortcut(s core.Shortcut)

TypedShortcut handles registered keyboard shortcuts (copy/cut/paste/select-all).

func (*RichEntry) Undo

func (e *RichEntry) Undo()

Undo reverts the last edit, restoring the caret. It is a no-op when there is nothing to undo.

Since: 1.0

type RichText

type RichText struct {
	BaseWidget
	Segments []RichTextSegment
	Wrapping bellui.TextWrap
	Scroll   bellui.ScrollDirection

	// The truncation mode of the text
	//
	// Since: 1.0
	Truncation bellui.TextTruncation

	// AllowRemoteContent opts this RichText into loading image segments whose
	// source is a remote (http/https) or local-file URI. It is false by default
	// so that rendering untrusted HTML/Markdown cannot, with no user
	// interaction, trigger network requests (SSRF, unbounded downloads) or read
	// local files (pre-rebrand tracker #285). When false, such ImageSegments render a broken-image
	// placeholder instead of being fetched. Set it to true only for content you
	// trust (e.g. local documentation or your own markdown).
	//
	// Since: 1.0
	AllowRemoteContent bool

	// Virtualize opts a scrollable RichText (Scroll != ScrollNone) into row
	// virtualisation: only the rows whose vertical band intersects the viewport
	// are materialised and shaped, so a very large document (thousands of rows)
	// scrolls without laying out every row up front (pre-rebrand tracker #158). It has no effect when
	// Scroll is ScrollNone, or on the truncation/single-row configurations that
	// cannot virtualise (see canVirtualize).
	//
	// Off by default: virtualisation trades exact, eager measurement for a
	// windowed model whose vertical (and, for wrap-off content, horizontal) scroll
	// extent is estimated from the materialised window and refines as you scroll
	// (pre-rebrand tracker #157/#170 jitter). That is a worthwhile trade only for genuinely large
	// documents, so it is opt-in rather than automatic for every scrolling
	// RichText. Entry enables the equivalent path internally regardless of this
	// field.
	Virtualize bool

	// RowHighlighter, when set, returns styled runs for a row. Used by Entry
	// for syntax highlighting without modifying the segment model.
	RowHighlighter func(row int) []StyleRun

	// ShowLineNumbers renders line numbers in the gutter area.
	// GutterWidth is computed and used by Layout, CursorPosition, and getRowCol.
	ShowLineNumbers bool
	GutterWidth     float32 // computed; read by Entry for cursor offset

	// BreakpointLines is the set of 1-based line numbers where breakpoint
	// markers (red dots) should be rendered in the gutter.
	BreakpointLines map[int]bool

	// HighlightedRow is the 1-based line number to highlight with a
	// background color (e.g., current execution line in a debugger).
	// Set to 0 to disable.
	HighlightedRow int

	// Selectable enables text selection on this RichText when the window's
	// SelectableMode is SelectableAll. Default false — internal RichText
	// widgets (e.g. inside Button) leave this false so they remain non-selectable.
	//
	// Since: 1.0
	Selectable bool
	// contains filtered or unexported fields
}

RichText represents the base element for a rich text-based widget.

Since: 1.0

func NewRichText

func NewRichText(segments ...RichTextSegment) *RichText

NewRichText returns a new RichText widget that renders the given text and segments. If no segments are specified it will be converted to a single segment using the default text settings.

Since: 1.0

func NewRichTextFromHTML

func NewRichTextFromHTML(content string) *RichText

NewRichTextFromHTML configures a RichText widget by parsing the provided HTML content.

Custom fonts cannot be selected via this constructor: the returned widget has no named-font allowlist yet, so any font-family / <font face> in the content falls through to the default behaviour. To let parsed content select a custom font, build the widget, register the font with RegisterNamedFont, then call ParseHTML / AppendHTML (pre-rebrand tracker #496).

func NewRichTextFromMarkdown

func NewRichTextFromMarkdown(content string) *RichText

NewRichTextFromMarkdown configures a RichText widget by parsing the provided markdown content.

Since: 1.0

func NewRichTextWithText

func NewRichTextWithText(text string) *RichText

NewRichTextWithText returns a new RichText widget that renders the given text. The string will be converted to a single text segment using the default text settings.

Since: 1.0

func (*RichText) AccessibleCaret

func (t *RichText) AccessibleCaret() int

AccessibleCaret returns the rune offset of the selection cursor.

func (*RichText) AccessibleLabel

func (t *RichText) AccessibleLabel() string

AccessibleLabel returns the concatenated plain text of all segments.

func (*RichText) AccessibleRole

func (t *RichText) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleLabel.

func (*RichText) AccessibleSelection

func (t *RichText) AccessibleSelection() (start, end int)

AccessibleSelection returns the user selection as a half-open rune range; when nothing is selected both offsets are the cursor position. Always (0, 0) while the rich text is not selectable.

func (*RichText) AccessibleText

func (t *RichText) AccessibleText() string

AccessibleText returns the concatenated segment text for assistive technologies (pre-rebrand tracker #556). Selection offsets index this text; around non-text block segments (images, separators) — which contribute rows but no runes — the mapping is approximate.

func (*RichText) AccessibleVirtualNodes

func (t *RichText) AccessibleVirtualNodes() []core.AccessibleVirtualNode

AccessibleVirtualNodes reports one RoleHeading node per heading segment (pre-rebrand tracker #533), so screen readers can navigate rendered markdown/HTML by headings. Headings have no CanvasObject of their own — their text is painted by the shared row machinery — so each node's bounds are the union of the segment's laid-out row visuals, read from the visual cache without touching the layout engine. Segments not yet rendered contribute no node.

func (*RichText) AppendHTML

func (t *RichText) AppendHTML(content string)

AppendHTML parses the given HTML string and appends the content to the widget, with the appropriate formatting.

func (*RichText) AppendMarkdown

func (t *RichText) AppendMarkdown(content string)

AppendMarkdown parses the given markdown string and appends the content to the widget, with the appropriate formatting. This API is intended for appending complete markdown documents or standalone fragments, and should not be used to parse a single markdown document piecewise.

Since: 1.0

func (*RichText) CreateRenderer

func (t *RichText) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*RichText) IntrinsicSize

func (t *RichText) IntrinsicSize() geo.Size

IntrinsicSize reports the size the text wants when given unlimited width: its natural extent measured as if Wrapping and Truncation were off, plus the standard padding.

It complements RichText.MinSize, which for a wrapping or truncating widget reports a width of ~0 — such a widget can shrink to fit any width by wrapping or clipping, so its minimum width carries no information about the content. Use IntrinsicSize to size a container, popover, or tooltip to its content: measure the natural width, cap it as desired, then read the wrapped height back from MinSize at that capped width.

When Wrapping and Truncation are already off, IntrinsicSize is identical to MinSize.

func (*RichText) MinSize

func (t *RichText) MinSize() geo.Size

MinSize calculates the minimum size of a rich text widget. This is based on the contained text with a standard amount of padding added.

func (*RichText) ParseHTML

func (t *RichText) ParseHTML(content string)

ParseHTML allows setting the content of this RichText widget from an HTML string. It will replace the content of this widget similarly to SetText, but with the appropriate formatting.

func (*RichText) ParseMarkdown

func (t *RichText) ParseMarkdown(content string)

ParseMarkdown allows setting the content of this RichText widget from a markdown string. It will replace the content of this widget similarly to SetText, but with the appropriate formatting.

func (*RichText) RegisterNamedFont

func (t *RichText) RegisterNamedFont(name string, res bellui.Resource)

RegisterNamedFont adds a custom font to this RichText's per-widget allowlist under the given family name, so that parsed HTML/Markdown content can select it via CSS font-family / <font face> (pre-rebrand tracker #496). The name is matched case- and whitespace-insensitively (it is trimmed and lowercased before storage and lookup). Registering an empty name is a no-op; registering a nil resource removes any existing entry.

This is the only way parsed (potentially untrusted) content can choose a custom font: the parser will never load a font file named in the content, only select from fonts the application registered here (consistent with the untrusted-content security model, pre-rebrand tracker #285). A requested family that is not registered falls through to the default behaviour (nil FontSource).

Since: 1.0

func (*RichText) ReplaceAccessibleSelection

func (t *RichText) ReplaceAccessibleSelection(string)

ReplaceAccessibleSelection is a no-op: rich text is not editable.

func (*RichText) Resize

func (t *RichText) Resize(size geo.Size)

Resize sets a new size for the rich text. This should only be called if it is not in a container with a layout manager.

func (*RichText) RowGeometry

func (t *RichText) RowGeometry(row int) (yPos, height float32)

RowGeometry returns the Y position and height of the given row, as computed during the last Layout pass. Returns (0, charMinSize) if the row is out of range or layout hasn't run yet.

func (*RichText) SelectedText

func (t *RichText) SelectedText() string

SelectedText returns the text currently selected in this RichText. Only works when Selectable is true and the window's SelectableMode permits it.

Since: 1.0

func (*RichText) SetAccessibleSelection

func (t *RichText) SetAccessibleSelection(start, end int)

SetAccessibleSelection selects [start, end), clamped to the content; equal offsets clear the selection. A no-op while the rich text is not selectable. It is safe to call from any goroutine.

func (*RichText) SetVisibleRange

func (t *RichText) SetVisibleRange(top, height float32) bool

SetVisibleRange informs a virtualised RichText of the viewport (in content coordinates) it is being scrolled within, so only the visible rows are materialised. A parent scroll container (Entry) calls this on scroll, layout and resize. It returns true when the materialised row window changed and the caller should trigger a cheap, window-sized re-render of the renderer.

func (*RichText) String

func (t *RichText) String() string

String returns the text widget buffer as string

func (*RichText) SyncState

func (t *RichText) SyncState()

SyncState syncs RichText's segments to internal rendering state. Called automatically by BaseWidget.Refresh() before the renderer refreshes.

type RichTextBlock

type RichTextBlock interface {
	Segments() []RichTextSegment
}

RichTextBlock is an extension of a text segment that contains other segments

Since: 1.0

type RichTextSegment

type RichTextSegment interface {
	Inline() bool
	Textual() string
	Update(core.CanvasObject)
	Visual() core.CanvasObject

	Select(pos1, pos2 geo.Position)
	SelectedText() string
	Unselect()
}

RichTextSegment describes any element that can be rendered in a RichText widget.

Since: 1.0

type RichTextStyle

type RichTextStyle struct {
	Alignment bellui.TextAlign
	ColorName bellui.ThemeColorName
	Inline    bool
	SizeName  bellui.ThemeSizeName // The theme name of the text size to use, if blank will be the standard text size
	TextStyle bellui.TextStyle

	// FontSource is an optional custom font resource used to render this
	// segment's text, matching canvas.Text.FontSource / canvas.TextRun.FontSource
	// at the canvas level. When nil (the zero value) the segment renders with the
	// theme font, so existing content is byte-identical to before. The chosen font
	// is honoured consistently across measurement, wrapping, alignment, selection
	// and truncation, so a custom-font segment lays out exactly as it renders.
	//
	// Since: 1.0
	FontSource bellui.Resource

	// HeadingLevel marks the segment as a document heading of the given
	// 1-based level (1 = H1). Zero means not a heading. It carries no
	// visual meaning of its own — the markdown/HTML parsers set it
	// alongside the heading text styles — but it feeds the accessibility
	// tree, where headings are exposed as navigable RoleHeading nodes.
	HeadingLevel int
	// contains filtered or unexported fields
}

RichTextStyle describes the details of a text object inside a RichText widget.

Since: 1.0

type ScrollIndicator

type ScrollIndicator struct {
	BaseWidget

	Scroll *iwidget.Scroll

	// Placement controls which corner the minimap appears in.
	// Defaults to BottomRight.
	Placement ScrollIndicatorPlacement
	// contains filtered or unexported fields
}

ScrollIndicator is a transparent overlay that shows the current scroll position within a Scroll container. It is designed to be placed on top of the scroll area (e.g. via a Stack/max layout) and renders a semi-transparent minimap in the corner showing the viewport position within the total content.

Attach it to a Scroll container using NewScrollIndicator, which automatically registers a scroll listener (via Scroll.AddScrollListener) to stay in sync.

Since: 1.0

func NewScrollIndicator

func NewScrollIndicator(scroll *iwidget.Scroll) *ScrollIndicator

NewScrollIndicator creates a scroll indicator overlay attached to the given Scroll. Place it on top of the scroll using a Stack layout:

container.NewStack(scroll, widget.NewScrollIndicator(scroll))

Since: 1.0

func (*ScrollIndicator) AccessibleLabel

func (si *ScrollIndicator) AccessibleLabel() string

AccessibleLabel returns an empty string.

func (*ScrollIndicator) AccessibleRole

func (si *ScrollIndicator) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleScrollBar.

func (*ScrollIndicator) CreateRenderer

func (si *ScrollIndicator) CreateRenderer() core.WidgetRenderer

CreateRenderer returns the renderer for the scroll indicator overlay.

func (*ScrollIndicator) MinSize

func (si *ScrollIndicator) MinSize() geo.Size

MinSize returns zero — the overlay stretches to fill its parent stack.

func (*ScrollIndicator) Refresh

func (si *ScrollIndicator) Refresh()

Refresh updates the indicator to reflect the current scroll state.

type ScrollIndicatorPlacement

type ScrollIndicatorPlacement int

ScrollIndicatorPlacement controls the corner of the minimap overlay.

const (
	// ScrollIndicatorBottomRight places the indicator in the bottom-right corner.
	ScrollIndicatorBottomRight ScrollIndicatorPlacement = iota
	// ScrollIndicatorBottomLeft places the indicator in the bottom-left corner.
	ScrollIndicatorBottomLeft
	// ScrollIndicatorTopRight places the indicator in the top-right corner.
	ScrollIndicatorTopRight
	// ScrollIndicatorTopLeft places the indicator in the top-left corner.
	ScrollIndicatorTopLeft
)

type SearchField

type SearchField struct {
	Entry

	// OnSearched is called when the user presses Enter/Return.
	OnSearched func(string) `json:"-"`

	// OnChanged is called on every text change for live filtering.
	OnChanged func(string) `json:"-"`
	// contains filtered or unexported fields
}

SearchField is an Entry with a leading search icon and a trailing clear button. OnChanged fires on every keystroke for live filtering. OnSearched fires when the user presses Enter/Return.

Since: 1.0

func NewSearchField

func NewSearchField(changed func(string)) *SearchField

NewSearchField creates a search input with the given callback fired on each text change.

Since: 1.0

func (*SearchField) AccessibleLabel

func (sf *SearchField) AccessibleLabel() string

AccessibleLabel returns the placeholder text.

func (*SearchField) AccessibleRole

func (sf *SearchField) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleSearchField.

func (*SearchField) CreateRenderer

func (sf *SearchField) CreateRenderer() core.WidgetRenderer

CreateRenderer returns a new renderer for this search field.

func (*SearchField) MinSize

func (sf *SearchField) MinSize() geo.Size

MinSize returns the minimal size of the search field.

func (*SearchField) SetText

func (sf *SearchField) SetText(text string)

SetText updates the text in the search field.

func (*SearchField) TypedKey

func (sf *SearchField) TypedKey(key *event.KeyEvent)

TypedKey intercepts Enter/Return to fire OnSearched, then delegates to Entry.

type SearchSelect

type SearchSelect struct {
	DisableableWidget

	Options     []string     // All available options
	Preferred   []string     // Options shown first, above a divider
	Selected    string       // Currently selected value
	PlaceHolder string       // Text shown when nothing is selected
	OnChanged   func(string) `json:"-"`
	// contains filtered or unexported fields
}

SearchSelect is a dropdown widget with text search filtering and support for preferred options shown at the top with a divider.

func NewSearchSelect

func NewSearchSelect(options []string, changed func(string)) *SearchSelect

NewSearchSelect creates a new SearchSelect with the given options and change handler.

func (*SearchSelect) ClearSelected

func (s *SearchSelect) ClearSelected()

ClearSelected resets the selection to empty.

func (*SearchSelect) CreateRenderer

func (s *SearchSelect) CreateRenderer() core.WidgetRenderer

CreateRenderer returns the renderer for SearchSelect. It reuses Select's visual appearance: background, label, dropdown icon.

func (*SearchSelect) MinSize

func (s *SearchSelect) MinSize() geo.Size

MinSize returns the minimum size.

func (*SearchSelect) SetOptions

func (s *SearchSelect) SetOptions(options []string)

SetOptions updates the list of available options.

func (*SearchSelect) SetPreferred

func (s *SearchSelect) SetPreferred(preferred []string)

SetPreferred updates the preferred options shown at the top.

func (*SearchSelect) SetSelected

func (s *SearchSelect) SetSelected(text string)

SetSelected sets the current option and updates the displayed label.

func (*SearchSelect) Tapped

func (s *SearchSelect) Tapped(*event.PointEvent)

Tapped opens the search popup.

type SegmentedButton

type SegmentedButton struct {
	BaseWidget
	Items     []string
	Selected  int       // index of selected item; -1 or out of range selects none
	OnChanged func(int) `json:"-"`
	// contains filtered or unexported fields
}

SegmentedButton is an MD3 group of 2-5 mutually exclusive toggle buttons.

func NewSegmentedButton

func NewSegmentedButton(items []string, changed func(int)) *SegmentedButton

NewSegmentedButton creates a segmented button group.

func (*SegmentedButton) AccessibleLabel

func (s *SegmentedButton) AccessibleLabel() string

AccessibleLabel returns an empty string.

func (*SegmentedButton) AccessibleRole

func (s *SegmentedButton) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleTabList.

func (*SegmentedButton) CreateRenderer

func (s *SegmentedButton) CreateRenderer() core.WidgetRenderer

func (*SegmentedButton) FocusGained

func (s *SegmentedButton) FocusGained()

FocusGained is called when this SegmentedButton gains keyboard focus.

func (*SegmentedButton) FocusLost

func (s *SegmentedButton) FocusLost()

FocusLost is called when this SegmentedButton loses keyboard focus.

func (*SegmentedButton) MinSize

func (s *SegmentedButton) MinSize() geo.Size

func (*SegmentedButton) TypedKey

func (s *SegmentedButton) TypedKey(ev *event.KeyEvent)

TypedKey moves the selection between segments with the left/right arrows. Under a right-to-left layout the visual order is reversed, so the right arrow steps to the previous segment and the left arrow to the next, matching the mirrored pixels.

func (*SegmentedButton) TypedRune

func (s *SegmentedButton) TypedRune(rune)

TypedRune is called if a text event happens while this SegmentedButton is focused. It is intentionally a no-op.

type Select

type Select struct {
	DisableableWidget

	// Alignment sets the text alignment of the select and its list of options.
	//
	// Since: 1.0
	Alignment   bellui.TextAlign
	Selected    string
	Options     []string
	PlaceHolder string
	OnChanged   func(string) `json:"-"`
	// contains filtered or unexported fields
}

Select widget has a list of options, with the current one shown, and triggers an event func when clicked

func NewSelect

func NewSelect(options []string, changed func(string)) *Select

NewSelect creates a new select widget with the set list of options and changes handler

func NewSelectWithData

func NewSelectWithData(options []string, data binding.String) *Select

NewSelectWithData returns a new select widget connected to the specified data source.

Since: 1.0

func (*Select) AccessibleLabel

func (s *Select) AccessibleLabel() string

AccessibleLabel returns the selected value or the placeholder text.

func (*Select) AccessibleRole

func (s *Select) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleComboBox.

func (*Select) AccessibleState

func (s *Select) AccessibleState() core.AccessibleState

AccessibleState returns the disabled state.

func (*Select) Bind

func (s *Select) Bind(data binding.String)

Bind connects the specified data source to this select. The current value will be displayed and any changes in the data will cause the widget to update.

The public Select.OnChanged field is left alone: binding and an app change handler coexist, and OnChanged may be assigned before or after Bind.

Since: 1.0

func (*Select) ClearSelected

func (s *Select) ClearSelected()

ClearSelected clears the current option of the select widget. After clearing the current option, the Select widget's PlaceHolder will be displayed.

func (*Select) CreateRenderer

func (s *Select) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*Select) FocusGained

func (s *Select) FocusGained()

FocusGained is called after this Select has gained focus.

func (*Select) FocusLost

func (s *Select) FocusLost()

FocusLost is called after this Select has lost focus.

func (*Select) Hide

func (s *Select) Hide()

Hide hides the select.

func (*Select) HoverIn

func (s *Select) HoverIn(*event.HoverEvent)

HoverIn is called when a desktop pointer enters the widget

func (*Select) HoverMoved

func (s *Select) HoverMoved(*event.HoverEvent)

HoverMoved is called when a desktop pointer hovers over the widget

func (*Select) HoverOut

func (s *Select) HoverOut()

HoverOut is called when a desktop pointer exits the widget

func (*Select) MinSize

func (s *Select) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below

func (*Select) Move

func (s *Select) Move(pos geo.Position)

Move changes the relative position of the select.

func (*Select) Resize

func (s *Select) Resize(size geo.Size)

Resize sets a new size for a widget. Note this should not be used if the widget is being managed by a Layout within a Container.

func (*Select) SelectedIndex

func (s *Select) SelectedIndex() int

SelectedIndex returns the index value of the currently selected item in Options list. It will return -1 if there is no selection.

func (*Select) SetOptions

func (s *Select) SetOptions(options []string)

SetOptions updates the list of options available and refreshes the widget

Since: 1.0

func (*Select) SetSelected

func (s *Select) SetSelected(text string)

SetSelected sets the current option of the select widget. It is safe to call from any goroutine.

func (*Select) SetSelectedIndex

func (s *Select) SetSelectedIndex(index int)

SetSelectedIndex will set the Selected option from the value in Options list at index position. It is safe to call from any goroutine.

func (*Select) Tapped

func (s *Select) Tapped(*event.PointEvent)

Tapped is called when a pointer tapped event is captured and triggers any tap handler

func (*Select) TypedKey

func (s *Select) TypedKey(ev *event.KeyEvent)

TypedKey is called if a key event happens while this Select is focused.

func (*Select) TypedRune

func (s *Select) TypedRune(_ rune)

TypedRune is called if a text event happens while this Select is focused.

func (*Select) Unbind

func (s *Select) Unbind()

Unbind disconnects any configured data source from this Select. The current value will remain at the last value of the data source.

Any Select.OnChanged handler the app installed is left in place -- Unbind only clears the write-back it installed itself.

Since: 1.0

type SelectEntry

type SelectEntry struct {
	Entry

	// OnOptionSelected is called when the user picks an option from the
	// drop-down menu, after the entry's text has been set to it (so it fires
	// after OnChanged). It lets a consumer treat a pick as a complete edit —
	// e.g. an inline table cell editor committing on pick — which a plain
	// OnChanged cannot distinguish from free-text typing. Typing never
	// triggers it, even when the typed text equals an option (pre-rebrand tracker #1047).
	//
	// Since: 1.0
	OnOptionSelected func(string)
	// contains filtered or unexported fields
}

SelectEntry is an input field which supports selecting from a fixed set of options.

func NewSelectEntry

func NewSelectEntry(options []string) *SelectEntry

NewSelectEntry creates a SelectEntry.

func (*SelectEntry) CreateRenderer

func (e *SelectEntry) CreateRenderer() core.WidgetRenderer

CreateRenderer returns a new renderer for this select entry.

func (*SelectEntry) Disable

func (e *SelectEntry) Disable()

Disable this widget so that it cannot be interacted with, updating any style appropriately.

func (*SelectEntry) Enable

func (e *SelectEntry) Enable()

Enable this widget, updating any style or features appropriately.

func (*SelectEntry) MinSize

func (e *SelectEntry) MinSize() geo.Size

MinSize returns the minimal size of the select entry.

func (*SelectEntry) Move

func (e *SelectEntry) Move(pos geo.Position)

Move changes the relative position of the select entry.

func (*SelectEntry) Resize

func (e *SelectEntry) Resize(size geo.Size)

Resize changes the size of the select entry.

func (*SelectEntry) SetOptions

func (e *SelectEntry) SetOptions(options []string)

SetOptions sets the options the user might select from.

type Separator

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

Separator is a widget for displaying a separator with themeable color.

Since: 1.0

func NewSeparator

func NewSeparator() *Separator

NewSeparator creates a new separator.

Since: 1.0

func (*Separator) CreateRenderer

func (s *Separator) CreateRenderer() core.WidgetRenderer

CreateRenderer returns a new renderer for the separator.

func (*Separator) MinSize

func (s *Separator) MinSize() geo.Size

MinSize returns the minimal size of the separator.

type SeparatorSegment

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

SeparatorSegment includes a horizontal separator in a rich text widget.

Since: 1.0

func (*SeparatorSegment) Inline

func (s *SeparatorSegment) Inline() bool

Inline returns false as a separator should be full width.

func (*SeparatorSegment) Select

func (s *SeparatorSegment) Select(_, _ geo.Position)

Select does nothing for a separator.

func (*SeparatorSegment) SelectedText

func (s *SeparatorSegment) SelectedText() string

SelectedText returns the empty string for this separator.

func (*SeparatorSegment) Textual

func (s *SeparatorSegment) Textual() string

Textual returns no content for a separator element.

func (*SeparatorSegment) Unselect

func (s *SeparatorSegment) Unselect()

Unselect does nothing for a separator.

func (*SeparatorSegment) Update

func (s *SeparatorSegment) Update(core.CanvasObject)

Update doesn't need to change a separator visual.

func (*SeparatorSegment) Visual

func (s *SeparatorSegment) Visual() core.CanvasObject

Visual returns a new instance of a separator widget for this segment.

type SideSheet

type SideSheet struct {
	Content core.CanvasObject
	Modal   bool
	// contains filtered or unexported fields
}

SideSheet is an MD3 side-anchored supplementary panel.

func NewSideSheet

func NewSideSheet(content core.CanvasObject) *SideSheet

NewSideSheet creates a side sheet with the given content.

func (*SideSheet) Hide

func (s *SideSheet) Hide()

Hide dismisses the side sheet.

func (*SideSheet) Show

func (s *SideSheet) Show(c core.Canvas)

Show displays the side sheet on the right side of the canvas.

type SimpleWidget

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

SimpleWidget creates a widget from canvas objects and a layout function, avoiding the need to implement CreateRenderer and a separate renderer type.

Usage:

bg := canvas.NewRectangle(color.NRGBA{R: 255, A: 255})
label := canvas.NewText("Hello", color.White)

w := widget.NewSimpleWidget(
    func() []core.CanvasObject { return []core.CanvasObject{bg, label} },
    func(size geo.Size) {
        bg.Resize(size)
        label.Move(geo.NewPos(8, 4))
    },
)

For even simpler cases where you just want to stack objects:

w := widget.NewSimpleWidget(
    func() []core.CanvasObject { return []core.CanvasObject{bg, label} },
    nil, // nil layout = all objects fill the widget size
)

func NewSimpleWidget

func NewSimpleWidget(objects func() []core.CanvasObject, layout func(geo.Size)) *SimpleWidget

NewSimpleWidget creates a widget from an objects function and an optional layout function. The objects function returns the canvas objects to render. The layout function positions them when the widget is resized (nil = fill).

func (*SimpleWidget) CreateRenderer

func (w *SimpleWidget) CreateRenderer() core.WidgetRenderer

CreateRenderer returns the widget renderer.

func (*SimpleWidget) SetMinSizeFunc

func (w *SimpleWidget) SetMinSizeFunc(fn func() geo.Size) *SimpleWidget

SetMinSizeFunc sets a custom minimum size calculator.

func (*SimpleWidget) SetRefreshFunc

func (w *SimpleWidget) SetRefreshFunc(fn func()) *SimpleWidget

SetRefreshFunc sets a function called when the widget is refreshed. Use this to update canvas object properties (colors, text, etc.) based on state.

type Slider

type Slider struct {
	BaseWidget

	Value float64
	Min   float64
	Max   float64
	Step  float64

	Orientation Orientation
	OnChanged   func(float64) `json:"-"`

	// Since: 1.0
	OnChangeEnded func(float64) `json:"-"`

	// OnHover is called with the value under the pointer as it moves across the
	// slider, without changing the slider's own value. It is the seam a media
	// scrubber uses to preview the frame at a position before committing a seek.
	// Not called while the slider is disabled.
	//
	// The reported value is continuous — it is NOT snapped to Step, since a
	// preview wants the true pointer position and a consumer that wants the
	// snapped value can round it, while the reverse is not recoverable.
	//
	// Since: 1.0
	OnHover func(float64) `json:"-"`

	// OnHoverEnd is called when the pointer leaves the slider, so anything shown
	// in response to OnHover can be taken down again. It fires even when the
	// slider has been disabled mid-hover, so a consumer is never left displaying
	// a stale preview.
	//
	// Since: 1.0
	OnHoverEnd func() `json:"-"`

	// ShowValueIndicator displays a popup above the thumb with the current
	// value while dragging.
	ShowValueIndicator bool

	// ShowTickMarks draws small marks along the track at each Step interval.
	// Only visible when Step > 0.
	ShowTickMarks bool
	// contains filtered or unexported fields
}

Slider is a widget that can slide between two fixed values.

func NewSlider

func NewSlider(min, max float64) *Slider

NewSlider returns a basic slider.

func NewSliderWithData

func NewSliderWithData(min, max float64, data binding.Float) *Slider

NewSliderWithData returns a slider connected with the specified data source.

Since: 1.0

func (*Slider) AccessibleActions

func (s *Slider) AccessibleActions() []core.AccessibleAction

AccessibleActions returns the "increment" and "decrement" actions.

func (*Slider) AccessibleLabel

func (s *Slider) AccessibleLabel() string

AccessibleLabel returns an empty string; sliders have no intrinsic text label.

func (*Slider) AccessibleRange

func (s *Slider) AccessibleRange() (min, max, current float64)

AccessibleRange returns the minimum, maximum, and current slider values.

func (*Slider) AccessibleRole

func (s *Slider) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleSlider.

func (*Slider) AccessibleValue

func (s *Slider) AccessibleValue() string

AccessibleValue returns a human-readable representation of the current value.

func (*Slider) Bind

func (s *Slider) Bind(data binding.Float)

Bind connects the specified data source to this Slider. The current value will be displayed and any changes in the data will cause the widget to update. User interactions with this Slider will set the value into the data source.

Binding does not claim Slider.OnChanged: the write-back rides a private hook, so an app handler set before or after Bind keeps working and the data source keeps tracking the widget either way.

Since: 1.0

func (*Slider) CreateRenderer

func (s *Slider) CreateRenderer() core.WidgetRenderer

CreateRenderer links this widget to its renderer.

func (*Slider) CursorPosition

func (s *Slider) CursorPosition() geo.Position

CursorPosition returns the position of the slider thumb relative to the widget.

func (*Slider) Disable

func (s *Slider) Disable()

Disable disables the slider

Since: 1.0

func (*Slider) Disabled

func (s *Slider) Disabled() bool

Disabled returns true if the slider is currently disabled

Since: 1.0

func (*Slider) DragEnd

func (s *Slider) DragEnd()

DragEnd is called when the drag ends.

func (*Slider) Dragged

func (s *Slider) Dragged(e *event.DragEvent)

Dragged is called when a drag event occurs.

func (*Slider) Dragging

func (s *Slider) Dragging() bool

Dragging reports whether the user is currently dragging the slider's thumb, between the first Dragged event and DragEnd.

This is the authoritative signal a media scrubber needs in order to suppress its own periodic position updates while the user is scrubbing — otherwise the thumb jumps back under the pointer on every tick. Inferring it from OnChanged/OnChangeEnded instead is unreliable: a press and release that does not move the value fires neither callback.

Since: 1.0

func (*Slider) Enable

func (s *Slider) Enable()

Enable enables the slider

Since: 1.0

func (*Slider) FocusGained

func (s *Slider) FocusGained()

FocusGained is called when this item gained the focus.

Since: 1.0

func (*Slider) FocusLost

func (s *Slider) FocusLost()

FocusLost is called when this item lost the focus.

Since: 1.0

func (*Slider) HoverIn

func (s *Slider) HoverIn(e *event.HoverEvent)

HoverIn is called when a desktop pointer enters the widget.

Since: 1.0

func (*Slider) HoverMoved

func (s *Slider) HoverMoved(e *event.HoverEvent)

HoverMoved is called when a desktop pointer hovers over the widget.

Since: 1.0

func (*Slider) HoverOut

func (s *Slider) HoverOut()

HoverOut is called when a desktop pointer exits the widget

Since: 1.0

func (*Slider) MinSize

func (s *Slider) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below

func (*Slider) PerformAccessibleAction

func (s *Slider) PerformAccessibleAction(name string)

PerformAccessibleAction adjusts the slider value by one step.

func (*Slider) SetValue

func (s *Slider) SetValue(value float64)

SetValue updates the value of the slider and clamps the value to be within the range. It is safe to call from any goroutine.

The change is reported as though the user made it: both OnChanged and OnChangeEnded fire. That is deliberate — the arrow keys and the screen-reader increment/decrement actions route through here and must notify the app. For programmatic updates that should not look like user interaction, such as a media player advancing a position bar, use Slider.SetValueSilently.

func (*Slider) SetValueSilently

func (s *Slider) SetValueSilently(value float64)

SetValueSilently updates the value and redraws, without firing OnChanged or OnChangeEnded. It is safe to call from any goroutine.

This is the path for updates the user did not cause — a player advancing its position bar many times a second cannot use Slider.SetValue, because every call would be indistinguishable from the user seeking.

Because a bound data source is written on the same change notification the callbacks ride (see Slider.Bind), a silent update does NOT propagate to bound data. It is intended for display-only updates of an unbound slider; use Slider.SetValue to move a bound one.

Since: 1.0

func (*Slider) Tapped

func (s *Slider) Tapped(e *event.PointEvent)

Tapped is called when a pointer tapped event is captured.

Since: 1.0

func (*Slider) TypedKey

func (s *Slider) TypedKey(key *event.KeyEvent)

TypedKey is called when this item receives a key event.

Since: 1.0

func (*Slider) TypedRune

func (s *Slider) TypedRune(_ rune)

TypedRune is called when this item receives a char event.

Since: 1.0

func (*Slider) Unbind

func (s *Slider) Unbind()

Unbind disconnects any configured data source from this Slider. The current value will remain at the last value of the data source.

Only the write-back hook Bind installed is removed; Slider.OnChanged belongs to the app and is left alone.

Since: 1.0

type Snackbar

type Snackbar struct {
	Text       string
	ActionText string
	OnAction   func() `json:"-"`
	Duration   time.Duration
	// contains filtered or unexported fields
}

Snackbar shows a brief message at the bottom of the screen with an optional action button. It auto-dismisses after Duration.

func NewSnackbar

func NewSnackbar(text, actionText string, action func()) *Snackbar

NewSnackbar creates a snackbar. Call Show() to display it.

func (*Snackbar) Hide

func (s *Snackbar) Hide()

Hide dismisses the snackbar. It is safe to call from any goroutine.

func (*Snackbar) Show

func (s *Snackbar) Show(c core.Canvas)

Show displays the snackbar at the bottom of the given canvas.

type SortDirection

type SortDirection int

SortDirection is the order a column is sorted in by a TableSorter.

Since: 1.0

const (
	// SortNone means the column does not contribute to the sort order.
	SortNone SortDirection = iota
	// SortAscending sorts the column from smallest to largest.
	SortAscending
	// SortDescending sorts the column from largest to smallest.
	SortDescending
)

type SortableColumn

type SortableColumn[T any] struct {
	Title string
	Less  func(a, b T) bool
}

SortableColumn describes one sortable column for BindTableSort: a header Title and a Less comparator that orders two row items by this column in ascending order (return true when a should sort before b). For descending order the TableSorter inverts the result, so callers write Less once.

For user-visible text use model.StringLess for locale-aware ordering, e.g.

{Title: "Name", Less: func(a, b person) bool { return model.StringLess(a.Name, b.Name) }}

A nil Less makes the column inert (its header is shown but clicking it does nothing), which is convenient for display-only columns.

Since: 1.0

type SpinBox

type SpinBox struct {
	DisableableWidget

	// Value is the current value of the spin box.
	Value float64
	// Min is the minimum value the spin box may hold.
	Min float64
	// Max is the maximum value the spin box may hold.
	Max float64
	// Step is the amount added or subtracted on each increment or decrement.
	Step float64
	// OnChanged is called whenever the value changes.
	OnChanged func(float64) `json:"-"`
	// contains filtered or unexported fields
}

SpinBox is a numeric input with increment and decrement buttons.

Since: 1.0

func NewSpinBox

func NewSpinBox(min, max, step float64) *SpinBox

NewSpinBox creates a new spin box with the given range and step.

Since: 1.0

func (*SpinBox) AccessibleActions

func (s *SpinBox) AccessibleActions() []core.AccessibleAction

AccessibleActions returns the "increment" and "decrement" actions.

func (*SpinBox) AccessibleLabel

func (s *SpinBox) AccessibleLabel() string

AccessibleLabel returns an empty string; spin boxes have no intrinsic label.

func (*SpinBox) AccessibleRange

func (s *SpinBox) AccessibleRange() (min, max, current float64)

AccessibleRange returns the minimum, maximum, and current spin box values.

func (*SpinBox) AccessibleRole

func (s *SpinBox) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleSpinButton.

func (*SpinBox) AccessibleValue

func (s *SpinBox) AccessibleValue() string

AccessibleValue returns a human-readable representation of the current value.

func (*SpinBox) CreateRenderer

func (s *SpinBox) CreateRenderer() core.WidgetRenderer

CreateRenderer returns the renderer for the spin box.

func (*SpinBox) Disable

func (s *SpinBox) Disable()

Disable disables the spin box and its children.

func (*SpinBox) Enable

func (s *SpinBox) Enable()

Enable enables the spin box and its children.

func (*SpinBox) FocusGained

func (s *SpinBox) FocusGained()

FocusGained delegates focus to the internal entry.

func (*SpinBox) FocusLost

func (s *SpinBox) FocusLost()

FocusLost delegates focus loss to the internal entry.

func (*SpinBox) MinSize

func (s *SpinBox) MinSize() geo.Size

MinSize returns the minimum size of the spin box.

func (*SpinBox) PerformAccessibleAction

func (s *SpinBox) PerformAccessibleAction(name string)

PerformAccessibleAction adjusts the spin box value by one step.

func (*SpinBox) SetValue

func (s *SpinBox) SetValue(val float64)

SetValue sets the spin box value, clamping to [Min, Max].

func (*SpinBox) TypedKey

func (s *SpinBox) TypedKey(key *event.KeyEvent)

TypedKey handles arrow up/down for increment/decrement.

func (*SpinBox) TypedRune

func (s *SpinBox) TypedRune(r rune)

TypedRune delegates to the internal entry.

type SplitButton

type SplitButton struct {
	DisableableWidget
	Text      string
	Icon      bellui.Resource
	OnTapped  func() `json:"-"`
	MenuItems []*bellui.MenuItem
	// contains filtered or unexported fields
}

SplitButton is an MD3 button with a primary action and a dropdown arrow that opens a menu of secondary actions.

func NewSplitButton

func NewSplitButton(text string, tapped func(), items []*bellui.MenuItem) *SplitButton

NewSplitButton creates a split button with a primary action and menu items.

func (*SplitButton) AccessibleActions

func (s *SplitButton) AccessibleActions() []core.AccessibleAction

AccessibleActions returns the "press" action.

func (*SplitButton) AccessibleLabel

func (s *SplitButton) AccessibleLabel() string

AccessibleLabel returns the button text.

func (*SplitButton) AccessibleRole

func (s *SplitButton) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleButton.

func (*SplitButton) CreateRenderer

func (s *SplitButton) CreateRenderer() core.WidgetRenderer

func (*SplitButton) HoverIn

func (s *SplitButton) HoverIn(*event.HoverEvent)

func (*SplitButton) HoverMoved

func (s *SplitButton) HoverMoved(*event.HoverEvent)

func (*SplitButton) HoverOut

func (s *SplitButton) HoverOut()

func (*SplitButton) MinSize

func (s *SplitButton) MinSize() geo.Size

func (*SplitButton) PerformAccessibleAction

func (s *SplitButton) PerformAccessibleAction(name string)

PerformAccessibleAction invokes the button's primary tap handler.

func (*SplitButton) Tapped

func (s *SplitButton) Tapped(e *event.PointEvent)

type State

type State[T comparable] struct {
	// contains filtered or unexported fields
}

State is a reactive value holder that automatically refreshes a widget when the value changes. It eliminates the need for manual Refresh() calls after state mutations.

Usage:

type MyWidget struct {
    widget.BaseWidget
    Title *widget.State[string]
    Count *widget.State[int]
}

func NewMyWidget() *MyWidget {
    w := &MyWidget{}
    w.Title = widget.NewState(w, "Hello")
    w.Count = widget.NewState(w, 0)
    w.ExtendBaseWidget(w)
    return w
}

// From any goroutine:
w.Title.Set("World")   // automatically refreshes the widget
w.Count.Set(42)        // automatically refreshes the widget
fmt.Println(w.Title.Get()) // "World"

func NewState

func NewState[T comparable](w core.Widget, initial T) *State[T]

NewState creates a reactive state bound to a widget. When the value changes via Set(), the widget is automatically refreshed.

func NewStateWithCallback

func NewStateWithCallback[T comparable](w core.Widget, initial T, onChange func(T)) *State[T]

NewStateWithCallback creates a reactive state that calls onChange in addition to refreshing the widget.

func (*State[T]) Get

func (s *State[T]) Get() T

Get returns the current value.

func (*State[T]) Set

func (s *State[T]) Set(value T)

Set updates the value and refreshes the bound widget if the value changed. It is safe to call from any goroutine.

type StateSyncer

type StateSyncer interface {
	SyncState()
}

StateSyncer is an optional interface that widgets implement to sync their public fields to internal rendering state. If a widget implements this, BaseWidget.Refresh() calls SyncState() automatically before the renderer's Refresh(), ensuring state is always consistent.

This eliminates the class of bugs where a widget's Refresh() forgets to sync internal state (segments, sub-widgets, caches) before triggering a renderer redraw.

Example:

func (e *Entry) SyncState() {
    e.syncSegments()
    e.text.Refresh()
}

type StatusBar

type StatusBar struct {
	BaseWidget
	Items []StatusBarItem
}

StatusBar is a bottom bar widget with multiple sections.

Text sections containing a Label with truncation enabled (what StatusBarLabel produces by default) are width-flexible: they render at their natural width when the bar has room and shrink — truncating with an ellipsis — when it does not, so a long status message never grows the bar's minimum size (pre-rebrand tracker #1041). Other items keep their minimum width and StatusBarSpacer absorbs any leftover space.

Since: 1.0

func NewStatusBar

func NewStatusBar(items ...StatusBarItem) *StatusBar

NewStatusBar creates a new status bar widget.

Since: 1.0

func (*StatusBar) AccessibleLabel

func (sb *StatusBar) AccessibleLabel() string

AccessibleLabel returns an empty string.

func (*StatusBar) AccessibleRole

func (sb *StatusBar) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleToolbar; the bar's items provide their own semantics.

func (*StatusBar) Append

func (sb *StatusBar) Append(item StatusBarItem)

Append adds a new item to the end of the status bar.

func (*StatusBar) CreateRenderer

func (sb *StatusBar) CreateRenderer() core.WidgetRenderer

CreateRenderer returns a new renderer for this status bar.

func (*StatusBar) MinSize

func (sb *StatusBar) MinSize() geo.Size

MinSize returns the minimum size of the status bar.

func (*StatusBar) SetItems

func (sb *StatusBar) SetItems(items ...StatusBarItem)

SetItems replaces all items in the status bar.

type StatusBarItem

type StatusBarItem interface {
	StatusBarObject() core.CanvasObject
}

StatusBarItem represents any interface element that can be added to a status bar.

type StatusBarLabel

type StatusBarLabel struct {
	Text string
	Icon bellui.Resource

	// NoTruncate opts this section out of the default ellipsis truncation,
	// restoring the sizing where the status bar's minimum width tracks the
	// full text.
	NoTruncate bool
	// contains filtered or unexported fields
}

StatusBarLabel is a text section in the status bar.

By default the text truncates with an ellipsis instead of growing the status bar's minimum size: a status bar is a fixed strip, and a long message (an error with a file path) must not force a window-wide relayout (pre-rebrand tracker #1041). Within the bar the section is width-flexible — it shows the full text whenever the bar has room and shrinks (truncating) when it does not. Set NoTruncate for a section whose text must always be fully visible and may dictate the bar's minimum width.

func NewStatusBarLabel

func NewStatusBarLabel(text string) *StatusBarLabel

NewStatusBarLabel returns a new text item for a StatusBar.

func NewStatusBarLabelWithIcon

func NewStatusBarLabelWithIcon(text string, icon bellui.Resource) *StatusBarLabel

NewStatusBarLabelWithIcon returns a new text item with an icon for a StatusBar.

func (*StatusBarLabel) SetText

func (s *StatusBarLabel) SetText(text string)

SetText updates the text shown in this status bar label.

func (*StatusBarLabel) StatusBarObject

func (s *StatusBarLabel) StatusBarObject() core.CanvasObject

StatusBarObject returns the canvas object for this label.

type StatusBarSeparator

type StatusBarSeparator struct{}

StatusBarSeparator is a thin vertical divider between status bar sections.

func NewStatusBarSeparator

func NewStatusBarSeparator() *StatusBarSeparator

NewStatusBarSeparator returns a new separator item for a StatusBar.

func (*StatusBarSeparator) StatusBarObject

func (s *StatusBarSeparator) StatusBarObject() core.CanvasObject

StatusBarObject returns a separator canvas object.

type StatusBarSpacer

type StatusBarSpacer struct{}

StatusBarSpacer is a blank, stretchable space for a status bar.

func NewStatusBarSpacer

func NewStatusBarSpacer() *StatusBarSpacer

NewStatusBarSpacer returns a new spacer item for a StatusBar.

func (*StatusBarSpacer) StatusBarObject

func (s *StatusBarSpacer) StatusBarObject() core.CanvasObject

StatusBarObject returns a spacer canvas object.

type StringDerived

type StringDerived struct{ *flow.Derived[string] }

StringDerived wraps a flow.Derived[string] to implement StringSource.

func (StringDerived) GetString

func (s StringDerived) GetString() string

type StringSource

type StringSource interface {
	GetString() string
	OnChange(func()) func()
}

StringSource is the interface for anything that provides a string value and can be listened to. Satisfied by StringValue, StringDerived, FormatValue.

func FormatValue

func FormatValue[T comparable](value *flow.Value[T], format string) StringSource

FormatValue creates a StringSource from any flow.Value by formatting with fmt.Sprint. Useful for binding non-string values to Labels:

count := flow.New(0)
label := widget.NewLabel("")
widget.BindLabel(label, widget.FormatValue(count, "Count: %d"))

type StringValue

type StringValue struct{ *flow.Value[string] }

StringValue wraps a flow.Value[string] to implement StringSource.

func (StringValue) GetString

func (s StringValue) GetString() string

type StyleRun

type StyleRun struct {
	Text            string
	ColorName       bellui.ThemeColorName // empty = default foreground
	ForegroundColor color.Color           // direct color, overrides ColorName when non-nil
	Italic          bool                  // render this run in italic

	// Bold renders this run in a bold font weight.
	//
	// Since: 1.0
	Bold bool
	// BackgroundColor, when non-nil, fills the run's cell rectangle behind the
	// text — a sub-line background (e.g. a semantic-token wash).
	//
	// Since: 1.0
	BackgroundColor color.Color
	// Underline draws a line beneath the run. UnderlineStyle selects its shape
	// (solid by default; wavy/dotted for diagnostic squiggles) and
	// UnderlineColor its color (the run's text color when nil).
	//
	// Since: 1.0
	Underline      bool
	UnderlineStyle UnderlineStyle
	UnderlineColor color.Color

	// StrikeThrough draws a line through the middle of the run — e.g. the
	// industry-standard rendering for a deprecated symbol from a semantic
	// analysis stream. StrikeColor selects its color (the run's text color
	// when nil, like UnderlineColor).
	//
	// Since: 1.0
	StrikeThrough bool
	StrikeColor   color.Color
}

StyleRun represents a run of text with a single color. Used by LineHighlighter to return per-token coloring for a line.

type Switch

type Switch struct {
	DisableableWidget
	On        bool
	OnChanged func(bool) `json:"-"`
	// contains filtered or unexported fields
}

Switch is an MD3-style toggle switch with a sliding thumb.

func NewSwitch

func NewSwitch(changed func(bool)) *Switch

NewSwitch creates a new switch widget.

func (*Switch) AccessibleActions

func (s *Switch) AccessibleActions() []core.AccessibleAction

AccessibleActions returns the "toggle" action.

func (*Switch) AccessibleLabel

func (s *Switch) AccessibleLabel() string

AccessibleLabel returns an empty string; switches have no intrinsic text label.

func (*Switch) AccessibleRole

func (s *Switch) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleSwitch.

func (*Switch) AccessibleState

func (s *Switch) AccessibleState() core.AccessibleState

AccessibleState returns the checked and disabled state.

func (*Switch) ActivatedByKey

func (s *Switch) ActivatedByKey(ev *event.KeyEvent) bool

ActivatedByKey reports that Space activates the switch, so the driver fires the central keyboard-activation signal in parity with a pointer tap (pre-rebrand tracker #834, pre-rebrand tracker #700).

func (*Switch) CreateRenderer

func (s *Switch) CreateRenderer() core.WidgetRenderer

func (*Switch) FocusGained

func (s *Switch) FocusGained()

FocusGained is called when the Switch is given keyboard focus.

func (*Switch) FocusLost

func (s *Switch) FocusLost()

FocusLost is called when the Switch loses keyboard focus.

func (*Switch) HoverIn

func (s *Switch) HoverIn(*event.HoverEvent)

func (*Switch) HoverMoved

func (s *Switch) HoverMoved(*event.HoverEvent)

func (*Switch) HoverOut

func (s *Switch) HoverOut()

func (*Switch) MinSize

func (s *Switch) MinSize() geo.Size

func (*Switch) PerformAccessibleAction

func (s *Switch) PerformAccessibleAction(name string)

PerformAccessibleAction toggles the switch.

func (*Switch) Tapped

func (s *Switch) Tapped(*event.PointEvent)

Tapped toggles the switch state.

func (*Switch) TypedKey

func (s *Switch) TypedKey(ev *event.KeyEvent)

TypedKey toggles the switch on Space, giving it keyboard operability (an a11y gap MD3 switches previously had — they toggled on tap only).

func (*Switch) TypedRune

func (s *Switch) TypedRune(rune)

TypedRune is unused; the Switch toggles on Space via TypedKey.

type Table

type Table struct {
	BaseWidget

	Length       func() (rows int, cols int)                      `json:"-"`
	CreateCell   func() core.CanvasObject                         `json:"-"`
	UpdateCell   func(id TableCellID, template core.CanvasObject) `json:"-"`
	OnSelected   func(id TableCellID)                             `json:"-"`
	OnUnselected func(id TableCellID)                             `json:"-"`

	// ShowHeaderRow specifies that a row should be added to the table with header content.
	// This will default to an A-Z style content, unless overridden with `CreateHeader` and `UpdateHeader` calls.
	//
	// Since: 1.0
	ShowHeaderRow bool

	// ShowHeaderColumn specifies that a column should be added to the table with header content.
	// This will default to an 1-10 style numeric content, unless overridden with `CreateHeader` and `UpdateHeader` calls.
	//
	// Since: 1.0
	ShowHeaderColumn bool

	// CreateHeader is an optional function that allows overriding of the default header widget.
	// Developers must also override `UpdateHeader`.
	//
	// Since: 1.0
	CreateHeader func() core.CanvasObject `json:"-"`

	// UpdateHeader is used with `CreateHeader` to support custom header content.
	// The `id` parameter will have `-1` value to indicate a header, and `> 0` where the column or row refer to data.
	//
	// Since: 1.0
	UpdateHeader func(id TableCellID, template core.CanvasObject) `json:"-"`

	// StickyRowCount specifies how many data rows should not scroll when the content moves.
	// If `ShowHeaderRow` us `true` then the stuck row will appear immediately underneath.
	//
	// Since: 1.0
	StickyRowCount int

	// StickyColumnCount specifies how many data columns should not scroll when the content moves.
	// If `ShowHeaderColumn` us `true` then the stuck column will appear immediately next to the header.
	//
	// Since: 1.0
	StickyColumnCount int

	// HideSeparators hides the separator lines between the table cells
	//
	// Since: 1.0
	HideSeparators bool
	// contains filtered or unexported fields
}

Table widget is a grid of items that can be scrolled and a cell selected. Its performance is provided by caching cell templates created with CreateCell and re-using them with UpdateCell. The size of the content rows/columns is returned by the Length callback.

Since: 1.0

func NewTable

func NewTable(length func() (rows int, cols int), create func() core.CanvasObject, update func(TableCellID, core.CanvasObject)) *Table

NewTable returns a new performant table widget defined by the passed functions. The first returns the data size in rows and columns, second parameter is a function that returns cell template objects that can be cached and the third is used to apply data at specified data location to the passed template CanvasObject.

Since: 1.0

func NewTableWithHeaders

func NewTableWithHeaders(length func() (rows int, cols int), create func() core.CanvasObject, update func(TableCellID, core.CanvasObject)) *Table

NewTableWithHeaders returns a new performant table widget defined by the passed functions including sticky headers. The first returns the data size in rows and columns, second parameter is a function that returns cell template objects that can be cached and the third is used to apply data at specified data location to the passed template CanvasObject. The row and column headers will stick to the leading and top edges of the table and contain "1-10" and "A-Z" formatted labels.

Since: 1.0

func (*Table) AccessibleGridDimensions

func (t *Table) AccessibleGridDimensions() (rows, cols int)

AccessibleGridDimensions returns the table's row and column count from the Length callback. Only realized (visible) cells produce semantic nodes, so this is how assistive technologies learn the full extent (pre-rebrand tracker #487). Table has no built-in sort or filter, so the presented extent equals the data extent; a widget that reorders or filters rows returns its current-view count (see core.AccessibleGridDimensioner).

func (*Table) AccessibleLabel

func (t *Table) AccessibleLabel() string

AccessibleLabel returns an empty string; tables have no intrinsic label.

func (*Table) AccessibleRole

func (t *Table) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleTable.

func (*Table) CreateRenderer

func (t *Table) CreateRenderer() core.WidgetRenderer

CreateRenderer returns a new renderer for the table.

func (*Table) Cursor

func (t *Table) Cursor() desktop.Cursor

func (*Table) DragEnd

func (t *Table) DragEnd()

func (*Table) Dragged

func (t *Table) Dragged(e *event.DragEvent)

func (*Table) FocusGained

func (t *Table) FocusGained()

FocusGained is called after this table has gained focus.

func (*Table) FocusLost

func (t *Table) FocusLost()

FocusLost is called after this Table has lost focus.

func (*Table) HoverIn

func (t *Table) HoverIn(ev *event.HoverEvent)

func (*Table) HoverMoved

func (t *Table) HoverMoved(ev *event.HoverEvent)

func (*Table) HoverOut

func (t *Table) HoverOut()

func (*Table) MouseDown

func (t *Table) MouseDown(e *desktop.MouseEvent)

MouseDown response to desktop mouse event

func (*Table) MouseUp

func (t *Table) MouseUp(*desktop.MouseEvent)

MouseUp response to desktop mouse event

func (*Table) RefreshItem

func (t *Table) RefreshItem(id TableCellID)

RefreshItem refreshes a single item, specified by the item ID passed in.

Since: 1.0

func (*Table) ScrollTo

func (t *Table) ScrollTo(id TableCellID)

ScrollTo will scroll to the given cell without changing the selection. Attempting to scroll beyond the limits of the table will scroll to the edge of the table instead.

Since: 1.0

func (*Table) ScrollToBottom

func (t *Table) ScrollToBottom()

ScrollToBottom scrolls to the last row in the table

Since: 1.0

func (*Table) ScrollToLeading

func (t *Table) ScrollToLeading()

ScrollToLeading scrolls horizontally to the leading edge of the table

Since: 1.0

func (*Table) ScrollToOffset

func (t *Table) ScrollToOffset(off geo.Position)

ScrollToOffset scrolls the table to a specific position

Since: 1.0

func (*Table) ScrollToTop

func (t *Table) ScrollToTop()

ScrollToTop scrolls to the first row in the table

Since: 1.0

func (*Table) ScrollToTrailing

func (t *Table) ScrollToTrailing()

ScrollToTrailing scrolls horizontally to the trailing edge of the table

Since: 1.0

func (*Table) Select

func (t *Table) Select(id TableCellID)

Select will mark the specified cell as selected.

func (*Table) SetColumnWidth

func (t *Table) SetColumnWidth(id int, width float32)

SetColumnWidth supports changing the width of the specified column. Columns normally take the width of the template cell returned from the CreateCell callback. The width parameter uses the same units as a geo.Size type and refers to the internal content width not including the divider size.

Since: 1.0

func (*Table) SetRowHeight

func (t *Table) SetRowHeight(id int, height float32)

SetRowHeight supports changing the height of the specified row. Rows normally take the height of the template cell returned from the CreateCell callback. The height parameter uses the same units as a geo.Size type and refers to the internal content height not including the divider size.

Since: 1.0

func (*Table) Tapped

func (t *Table) Tapped(e *event.PointEvent)

func (*Table) TouchCancel

func (t *Table) TouchCancel(*mobile.TouchEvent)

TouchCancel response to mobile touch event

func (*Table) TouchDown

func (t *Table) TouchDown(e *mobile.TouchEvent)

TouchDown response to mobile touch event

func (*Table) TouchUp

func (t *Table) TouchUp(*mobile.TouchEvent)

TouchUp response to mobile touch event

func (*Table) TypedKey

func (t *Table) TypedKey(ev *event.KeyEvent)

TypedKey is called if a key event happens while this Table is focused.

func (*Table) TypedRune

func (t *Table) TypedRune(_ rune)

TypedRune is called if a text event happens while this Table is focused.

func (*Table) Unselect

func (t *Table) Unselect(id TableCellID)

Unselect will mark the cell provided by id as unselected.

func (*Table) UnselectAll

func (t *Table) UnselectAll()

UnselectAll will mark all cells as unselected.

Since: 1.0

type TableCellID

type TableCellID struct {
	Row int
	Col int
}

TableCellID is a type that represents a cell's position in a table based on its row and column location.

type TableEditor

type TableEditor[T any] struct {
	// EditOnActivate begins editing a cell when it is selected (the default). Set
	// it to false to drive editing yourself via [TableEditor.Edit].
	EditOnActivate bool
	// contains filtered or unexported fields
}

TableEditor is the controller returned by BindTableEditing. It drives an inline editor over the cells of a Table. See ListEditor for the semantics; the only difference is that a cell is addressed by TableCellID and each column carries its own CellEditor.

Call all methods on the main goroutine.

Since: 1.0

func BindTableEditing

func BindTableEditing[T any](t *Table, m model.MutableModel[T], cols int,
	createDisplay func() core.CanvasObject,
	updateDisplay func(item T, col int, display core.CanvasObject),
	editors []CellEditor[T],
) (*TableEditor[T], func())

BindTableEditing drives an editable Table from a model.MutableModel whose rows are the model items and whose columns are fixed at cols. Cells render through createDisplay/updateDisplay; editors is indexed by column, and a column is editable only when its CellEditor has a non-nil Commit (columns past the end of editors are not editable). Committing writes the edited value back through the model as one gated edit; validation and cancel behave as in BindListEditing.

The returned TableEditor is the controller; the returned function detaches the binding.

Since: 1.0

func (*TableEditor[T]) Cancel

func (ed *TableEditor[T]) Cancel()

Cancel discards the current edit and closes the editor.

func (*TableEditor[T]) Commit

func (ed *TableEditor[T]) Commit() error

Commit validates the current edit and, if accepted, writes it back through the model as one gated edit and closes the editor. See ListEditor.Commit.

func (*TableEditor[T]) Edit

func (ed *TableEditor[T]) Edit(id TableCellID)

Edit begins inline editing of the given cell (a no-op if the cell is out of range or its column is not editable). It replaces any edit in progress.

func (*TableEditor[T]) Editing

func (ed *TableEditor[T]) Editing() (id TableCellID, ok bool)

Editing reports the cell currently being edited, and whether an edit is active.

type TableSegment

type TableSegment struct {
	Header     []string
	Rows       [][]string
	Alignments []bellui.TextAlign
}

TableSegment includes a table parsed from markdown in a rich text widget.

Since: 1.0

func (*TableSegment) Inline

func (t *TableSegment) Inline() bool

Inline returns false as a table should be in a block.

func (*TableSegment) Select

func (t *TableSegment) Select(_, _ geo.Position)

Select does nothing for a table.

func (*TableSegment) SelectedText

func (t *TableSegment) SelectedText() string

SelectedText returns the empty string for this table.

func (*TableSegment) Textual

func (t *TableSegment) Textual() string

Textual returns the text content of the table.

func (*TableSegment) Unselect

func (t *TableSegment) Unselect()

Unselect does nothing for a table.

func (*TableSegment) Update

func (t *TableSegment) Update(o core.CanvasObject)

Update applies the current state of this table segment to an existing visual.

func (*TableSegment) Visual

func (t *TableSegment) Visual() core.CanvasObject

Visual returns a new table widget to render this segment.

type TableSorter

type TableSorter[T any] struct {
	// contains filtered or unexported fields
}

TableSorter wires a Table's header row to a model.SortProxy, turning a header click into a change of the proxy's comparator. It is returned by BindTableSort.

Clicking a column header cycles that column through ascending → descending → unsorted and makes it the primary sort key; columns clicked earlier stay active as stable tie-breakers, so clicking column A then column B sorts by B then A (the proxy sorts stably). The composed comparator is recomputed and pushed to the proxy on every change, which re-sorts the rows and refreshes the header arrows.

A TableSorter mutates widget state; call its methods on the main goroutine (use bellui.Do from a background goroutine), the same rule the widgets follow.

Since: 1.0

func BindTableSort

func BindTableSort[T any](t *Table, proxy *model.SortProxy[T], cols []SortableColumn[T]) *TableSorter[T]

BindTableSort adds header-click sorting to t, driving proxy's comparator from the descriptors in cols. It enables t.ShowHeaderRow and installs CreateHeader and UpdateHeader that render each column's Title with an ascending/descending arrow and a click target; it does not touch t.Length/CreateCell/UpdateCell, so it composes with BindTableModel over the same proxy:

proxy := model.NewSortProxy[person](src)
widget.BindTableModel(table, proxy, 2, createCell, updateCell)
sorter := widget.BindTableSort(table, proxy, []widget.SortableColumn[person]{
	{Title: "Name", Less: func(a, b person) bool { return a.Name < b.Name }},
	{Title: "Age", Less: func(a, b person) bool { return a.Age < b.Age }},
})

The returned TableSorter also drives the sort programmatically (TableSorter.SortByColumn, TableSorter.Clear) and reports the current state (TableSorter.Sorts, TableSorter.DirectionOf).

Since: 1.0

func (*TableSorter[T]) Clear

func (s *TableSorter[T]) Clear()

Clear removes all active sort keys, restoring the proxy's source order.

func (*TableSorter[T]) DirectionOf

func (s *TableSorter[T]) DirectionOf(col int) SortDirection

DirectionOf reports the current SortDirection for a column, or SortNone if the column is not part of the active sort.

func (*TableSorter[T]) SortByColumn

func (s *TableSorter[T]) SortByColumn(col int)

SortByColumn advances the sort state of the given column as if its header were clicked: the column cycles ascending → descending → unsorted and becomes the primary key. Out-of-range columns and columns with a nil Less are ignored.

func (*TableSorter[T]) Sorts

func (s *TableSorter[T]) Sorts() []ColumnSort

Sorts returns the active sort keys in priority order (primary first). The most recently clicked column is primary; earlier clicks act as stable tie-breakers.

func (*TableSorter[T]) Unbind

func (s *TableSorter[T]) Unbind()

Unbind detaches the sorter from the table by clearing the header callbacks it installed. It leaves the proxy comparator untouched.

type TextEdit

type TextEdit struct {
	Start, End int
	Text       string
}

TextEdit describes one splice of an Entry.ApplyEdits batch: the half-open rune range [Start, End) of the current content is replaced by Text. Start == End inserts at that offset; an empty Text deletes the range.

Since: 1.0

type TextGrid

type TextGrid struct {
	BaseWidget
	Rows []TextGridRow

	ShowLineNumbers bool
	ShowWhitespace  bool
	TabWidth        int // If set to 0 the bellui.DefaultTabWidth is used

	// Scroll can be used to turn off the scrolling of our TextGrid.
	//
	// Since: 1.0
	Scroll bellui.ScrollDirection
	// contains filtered or unexported fields
}

TextGrid is a monospaced grid of characters. This is designed to be used by a text editor, code preview or terminal emulator.

func NewTextGrid

func NewTextGrid() *TextGrid

NewTextGrid creates a new empty TextGrid widget.

func NewTextGridFromString

func NewTextGridFromString(content string) *TextGrid

NewTextGridFromString creates a new TextGrid widget with the specified string content.

func (*TextGrid) Append

func (t *TextGrid) Append(text string)

Append will add new lines to the end of this TextGrid. The first character will be at the beginning of a new line and any newline characters will split the text further.

Since: 1.0

func (*TextGrid) CreateRenderer

func (t *TextGrid) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*TextGrid) CursorLocationForPosition

func (t *TextGrid) CursorLocationForPosition(p geo.Position) (row, col int)

CursorLocationForPosition returns the location where a cursor would be if it was located in the cell under the requested position. If the grid is scrolled the position will refer to the visible offset and not the distance from the top left of the overall document.

Since: 1.0

func (*TextGrid) MinSize

func (t *TextGrid) MinSize() geo.Size

MinSize returns the smallest size this widget can shrink to

func (*TextGrid) PositionForCursorLocation

func (t *TextGrid) PositionForCursorLocation(row, col int) geo.Position

PositionForCursorLocation returns the relative position in this TextGrid for the cell at position row, col. If the grid has been scrolled this will be taken into account so that the position compared to top left will refer to the requested location.

Since: 1.0

func (*TextGrid) Resize

func (t *TextGrid) Resize(size geo.Size)

Resize is called when this widget changes size. We should make sure that we refresh cells.

func (*TextGrid) Row

func (t *TextGrid) Row(row int) TextGridRow

Row returns a copy of the content in a specified row as a TextGridRow. If the index is out of bounds it returns an empty row object.

func (*TextGrid) RowText

func (t *TextGrid) RowText(row int) string

RowText returns a string representation of the content at the row specified. If the index is out of bounds it returns an empty string.

func (*TextGrid) ScrollToBottom

func (t *TextGrid) ScrollToBottom()

ScrollToBottom will scroll content to container bottom - to show latest info which end user just added

Since: 1.0

func (*TextGrid) ScrollToTop

func (t *TextGrid) ScrollToTop()

ScrollToTop will scroll content to container top

Since: 1.0

func (*TextGrid) SetCell

func (t *TextGrid) SetCell(row, col int, cell TextGridCell)

SetCell sets a grid data to the cell at named row and column.

func (*TextGrid) SetRow

func (t *TextGrid) SetRow(row int, content TextGridRow)

SetRow updates the specified row of the grid's contents using the specified content and style and then refreshes. If the row is beyond the end of the current buffer it will be expanded. Tab characters are not padded with spaces.

func (*TextGrid) SetRowStyle

func (t *TextGrid) SetRowStyle(row int, style TextGridStyle)

SetRowStyle sets a grid style to all the cells cell at the specified row. Any cells in this row with their own style will override this value when displayed.

func (*TextGrid) SetRune

func (t *TextGrid) SetRune(row, col int, r rune)

SetRune sets a character to the cell at named row and column.

func (*TextGrid) SetStyle

func (t *TextGrid) SetStyle(row, col int, style TextGridStyle)

SetStyle sets a grid style to the cell at named row and column.

func (*TextGrid) SetStyleRange

func (t *TextGrid) SetStyleRange(startRow, startCol, endRow, endCol int, style TextGridStyle)

SetStyleRange sets a grid style to all the cells between the start row and column through to the end row and column.

func (*TextGrid) SetText

func (t *TextGrid) SetText(text string)

SetText updates the buffer of this textgrid to contain the specified text. New lines and columns will be added as required. Lines are separated by '\n'. The grid will use default text style and any previous content and style will be removed. Tab characters are padded with spaces to the next tab stop.

func (*TextGrid) Text

func (t *TextGrid) Text() string

Text returns the contents of the buffer as a single string (with no style information). It reconstructs the lines by joining with a `\n` character. Tab characters have padded spaces removed.

type TextGridCell

type TextGridCell struct {
	Rune  rune
	Style TextGridStyle
}

TextGridCell represents a single cell in a text grid. It has a rune for the text content and a style associated with it.

type TextGridRow

type TextGridRow struct {
	Cells []TextGridCell
	Style TextGridStyle
}

TextGridRow represents a row of cells cell in a text grid. It contains the cells for the row and an optional style.

type TextGridStyle

type TextGridStyle interface {
	Style() bellui.TextStyle
	TextColor() color.Color
	BackgroundColor() color.Color
}

TextGridStyle defines a style that can be applied to a TextGrid cell.

var (
	// TextGridStyleDefault is a default style for test grid cells
	TextGridStyleDefault TextGridStyle
	// TextGridStyleWhitespace is the style used for whitespace characters, if enabled
	TextGridStyleWhitespace TextGridStyle
)

type TextRange

type TextRange struct {
	Start, End int
}

TextRange is a half-open span of an Entry's text expressed as rune offsets into Text: Start is inclusive, End exclusive. Start == End is an empty range (a caret position). It is the unit passed to Entry.BeforeChange.

Since: 1.0

type TextSegment

type TextSegment struct {
	Style RichTextStyle
	Text  string
	// contains filtered or unexported fields
}

TextSegment represents the styling for a segment of rich text.

Since: 1.0

func (*TextSegment) Inline

func (t *TextSegment) Inline() bool

Inline should return true if this text can be included within other elements, or false if it creates a new block.

func (*TextSegment) Select

func (t *TextSegment) Select(begin, end geo.Position)

Select tells the segment that the user is selecting the content between the two positions.

func (*TextSegment) SelectedText

func (t *TextSegment) SelectedText() string

SelectedText should return the text representation of any content currently selected through the Select call.

func (*TextSegment) Textual

func (t *TextSegment) Textual() string

Textual returns the content of this segment rendered to plain text.

func (*TextSegment) Unselect

func (t *TextSegment) Unselect()

Unselect tells the segment that the user is has cancelled the previous selection.

func (*TextSegment) Update

func (t *TextSegment) Update(o core.CanvasObject)

Update applies the current state of this text segment to an existing visual.

func (*TextSegment) Visual

func (t *TextSegment) Visual() core.CanvasObject

Visual returns a new instance of a graphical element required to render this segment.

type ThemeSelection

type ThemeSelection struct {
	Variant ThemeVariantSelection
	Primary string
}

ThemeSelection is the state of a ThemeSelector: a theme variant choice and a named primary color (one of theme.PrimaryColorNames).

Since: 1.0

func LoadThemeSelection

func LoadThemeSelection(p bellui.Preferences) (ThemeSelection, bool)

LoadThemeSelection restores a selection stored by SaveThemeSelection. The boolean reports whether a stored selection was found; call ThemeSelection.Apply on the result at startup to restore the appearance.

Since: 1.0

func (ThemeSelection) Apply

func (t ThemeSelection) Apply()

Apply re-themes the running app to this selection via its Settings. It only affects the current app — nothing is written to the system-wide Bellui settings. ThemeVariantSystem resolves the operating system appearance at call time; it does not follow later OS changes. The primary color is applied when the app settings implement bellui.PrimaryColorSettings (the default app and the test app do); an empty Primary leaves the current primary color untouched.

type ThemeSelector

type ThemeSelector struct {
	BaseWidget

	// Selection is the current choice shown by the widget.
	Selection ThemeSelection
	// OnChanged fires whenever the user changes the selection.
	OnChanged func(ThemeSelection) `json:"-"`
}

ThemeSelector is a compact appearance picker for app settings pages: a System/Light/Dark variant selector above the standard primary color swatches. It is callback-driven — interacting updates Selection and fires OnChanged, but nothing is applied or persisted by the widget itself. Use ThemeSelection.Apply and SaveThemeSelection for that.

Since: 1.0

func NewThemeSelector

func NewThemeSelector(changed func(ThemeSelection)) *ThemeSelector

NewThemeSelector creates a theme selector. The initial selection is the system variant with the app's current primary color.

Since: 1.0

func (*ThemeSelector) CreateRenderer

func (t *ThemeSelector) CreateRenderer() core.WidgetRenderer

CreateRenderer returns a new renderer for the theme selector.

func (*ThemeSelector) MinSize

func (t *ThemeSelector) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below.

func (*ThemeSelector) SetSelection

func (t *ThemeSelector) SetSelection(sel ThemeSelection)

SetSelection updates the shown selection, firing OnChanged if it changed.

type ThemeVariantSelection

type ThemeVariantSelection int

ThemeVariantSelection is the variant choice of a ThemeSelection: follow the system appearance, always light, or always dark.

Since: 1.0

const (
	// ThemeVariantSystem follows the operating system light/dark appearance.
	ThemeVariantSystem ThemeVariantSelection = iota
	// ThemeVariantLight always uses the light theme variant.
	ThemeVariantLight
	// ThemeVariantDark always uses the dark theme variant.
	ThemeVariantDark
)

func (ThemeVariantSelection) String

func (v ThemeVariantSelection) String() string

String returns a stable textual form ("system", "light" or "dark"), also used when a selection is stored in Preferences.

type TimePicker

type TimePicker struct {
	BaseWidget
	Hour, Minute int
	Use24Hour    bool
	OnChanged    func(hour, minute int) `json:"-"`
	// contains filtered or unexported fields
}

TimePicker is an MD3-compliant time picker with a clock dial.

Since: 1.0

func NewAutoTimePicker

func NewAutoTimePicker(hour, minute int, changed func(hour, minute int)) *TimePicker

NewAutoTimePicker creates a time picker that auto-detects 12h/24h mode from the current locale.

Since: 1.0

func NewTimePicker

func NewTimePicker(hour, minute int, use24h bool, changed func(hour, minute int)) *TimePicker

NewTimePicker creates a new MD3 time picker.

Since: 1.0

func (*TimePicker) AccessibleLabel

func (t *TimePicker) AccessibleLabel() string

AccessibleLabel returns a localized "Select time".

func (*TimePicker) AccessibleRange

func (t *TimePicker) AccessibleRange() (min, max, current float64)

AccessibleRange is not applicable to time pickers; it returns zeros.

func (*TimePicker) AccessibleRole

func (t *TimePicker) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleGroup; the hour/minute controls inside provide their own semantics.

func (*TimePicker) AccessibleValue

func (t *TimePicker) AccessibleValue() string

AccessibleValue returns the chosen time in the locale's format.

func (*TimePicker) CreateRenderer

func (t *TimePicker) CreateRenderer() core.WidgetRenderer

CreateRenderer returns a new renderer for the time picker.

func (*TimePicker) DragEnd

func (t *TimePicker) DragEnd()

DragEnd is called when the drag finishes.

func (*TimePicker) Dragged

func (t *TimePicker) Dragged(e *event.DragEvent)

Dragged handles drag events on the clock dial.

func (*TimePicker) FocusGained

func (t *TimePicker) FocusGained()

FocusGained is called when the picker gains keyboard focus; the field cursor starts on whichever of hour/minute the dial is selecting.

func (*TimePicker) FocusLost

func (t *TimePicker) FocusLost()

FocusLost is called when the picker loses keyboard focus.

func (*TimePicker) HandlesEscape

func (t *TimePicker) HandlesEscape() bool

HandlesEscape reports whether Escape belongs to this picker: it discards a half-typed value, so it only claims the key while one is buffered. With nothing pending, Escape closes the dialog the picker is usually shown in.

Since: 1.0

func (*TimePicker) MinSize

func (t *TimePicker) MinSize() geo.Size

MinSize returns the minimum size for the time picker.

func (*TimePicker) Tapped

func (t *TimePicker) Tapped(e *event.PointEvent)

Tapped handles taps on the clock face; the header fields (hour, minute, AM/PM) are widgets that receive their own taps (pre-rebrand tracker #543).

func (*TimePicker) TypedKey

func (t *TimePicker) TypedKey(ev *event.KeyEvent)

TypedKey drives the picker from the keyboard (pre-rebrand tracker #543): Left/Right move between the hour, minute and (12h mode) AM/PM fields, Up/Down adjust the focused field — hour and minute wrap, AM/PM toggles — and Enter/Space activates it like a tap (switching the dial or setting the meridiem).

func (*TimePicker) TypedRune

func (t *TimePicker) TypedRune(r rune)

TypedRune drives direct digit entry (pre-rebrand tracker #549): typed digits accumulate into the focused hour or minute field. A first digit that could still be the tens place of a valid two-digit value (hour "1"/"2" in 24h, "0"/"1" in 12h; minute "0".."5") is buffered to await a second digit; any other digit commits immediately as a leading-zero value and auto-advances (hour to minute). A second digit forms the two-digit number, clamps to the valid range and commits. In 12h mode, "A"/"P" (case-insensitive) set the meridiem. The advance and commit are deterministic (no wall-clock timeout), so behaviour is fully reproducible.

type Toast

type Toast struct {
	BaseWidget

	Text       string
	Importance Importance
	Duration   time.Duration
	// contains filtered or unexported fields
}

Toast is a transient notification that appears briefly and auto-dismisses.

Since: 1.0

func ShowToast

func ShowToast(text string, c core.Canvas) *Toast

ShowToast shows a transient notification at the bottom of the canvas. The toast auto-dismisses after 3 seconds.

Since: 1.0

func ShowToastWithImportance

func ShowToastWithImportance(text string, importance Importance, c core.Canvas) *Toast

ShowToastWithImportance shows a styled transient notification at the bottom of the canvas. The returned Toast can be used to dismiss the notification early; its auto-dismiss timer keeps running otherwise, so callers that tear the canvas down before Duration elapses (e.g. tests) should call Dismiss.

Since: 1.0

func (*Toast) AccessibleLabel

func (t *Toast) AccessibleLabel() string

AccessibleLabel returns the toast text.

func (*Toast) AccessibleRole

func (t *Toast) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleStatus.

func (*Toast) CreateRenderer

func (t *Toast) CreateRenderer() core.WidgetRenderer

CreateRenderer returns a minimal renderer (Toast is shown via PopUp, not inline).

func (*Toast) Dismiss

func (t *Toast) Dismiss()

Dismiss hides the toast immediately and cancels the auto-dismiss timer.

func (*Toast) Show

func (t *Toast) Show()

Show displays the toast on the canvas and starts the auto-dismiss timer.

type Toolbar

type Toolbar struct {
	BaseWidget
	Items []ToolbarItem
}

func NewToolbar

func NewToolbar(items ...ToolbarItem) *Toolbar

NewToolbar creates a new toolbar widget.

func (*Toolbar) AccessibleLabel

func (t *Toolbar) AccessibleLabel() string

AccessibleLabel returns an empty string; toolbars have no intrinsic label.

func (*Toolbar) AccessibleRole

func (t *Toolbar) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleToolbar.

func (*Toolbar) Append

func (t *Toolbar) Append(item ToolbarItem)

Append a new ToolbarItem to the end of this Toolbar

func (*Toolbar) CreateRenderer

func (t *Toolbar) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer

func (*Toolbar) MinSize

func (t *Toolbar) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below

func (*Toolbar) Prepend

func (t *Toolbar) Prepend(item ToolbarItem)

Prepend a new ToolbarItem to the start of this Toolbar

type ToolbarAction

type ToolbarAction struct {
	Icon        bellui.Resource
	OnActivated func() `json:"-"`
	// contains filtered or unexported fields
}

ToolbarAction is push button style of ToolbarItem

func NewToolbarAction

func NewToolbarAction(icon bellui.Resource, onActivated func()) *ToolbarAction

NewToolbarAction returns a new push button style ToolbarItem

func (*ToolbarAction) Disable

func (t *ToolbarAction) Disable()

Disable this ToolbarAction so that it cannot be interacted with, updating any style appropriately.

Since: 1.0

func (*ToolbarAction) Disabled

func (t *ToolbarAction) Disabled() bool

Disabled returns true if this ToolbarAction is currently disabled or false if it can currently be interacted with.

Since: 1.0

func (*ToolbarAction) Enable

func (t *ToolbarAction) Enable()

Enable this ToolbarAction, updating any style or features appropriately.

Since: 1.0

func (*ToolbarAction) SetIcon

func (t *ToolbarAction) SetIcon(icon bellui.Resource)

SetIcon updates the icon on a ToolbarItem

Since: 1.0

func (*ToolbarAction) ToolbarObject

func (t *ToolbarAction) ToolbarObject() core.CanvasObject

ToolbarObject gets a button to render this ToolbarAction

type ToolbarItem

type ToolbarItem interface {
	ToolbarObject() core.CanvasObject
}

ToolbarItem represents any interface element that can be added to a toolbar

type ToolbarSeparator

type ToolbarSeparator struct{}

ToolbarSeparator is a thin, visible divide that can be added to a Toolbar. This is typically used to assist visual grouping of ToolbarItems.

func NewToolbarSeparator

func NewToolbarSeparator() *ToolbarSeparator

NewToolbarSeparator returns a new separator item for a Toolbar to assist with ToolbarItem grouping

func (*ToolbarSeparator) ToolbarObject

func (t *ToolbarSeparator) ToolbarObject() core.CanvasObject

ToolbarObject gets the visible line object for this ToolbarSeparator

type ToolbarSpacer

type ToolbarSpacer struct{}

ToolbarSpacer is a blank, stretchable space for a toolbar. This is typically used to assist layout if you wish some left and some right aligned items. Space will be split evebly amongst all the spacers on a toolbar.

func NewToolbarSpacer

func NewToolbarSpacer() *ToolbarSpacer

NewToolbarSpacer returns a new spacer item for a Toolbar to assist with ToolbarItem alignment

func (*ToolbarSpacer) ToolbarObject

func (t *ToolbarSpacer) ToolbarObject() core.CanvasObject

ToolbarObject gets the actual spacer object for this ToolbarSpacer

type Tooltip

type Tooltip struct {
	BaseWidget

	Content core.CanvasObject // The wrapped widget
	Text    string            // The tooltip text
	// contains filtered or unexported fields
}

Tooltip wraps any CanvasObject and shows hover text after a short delay. It works by placing a transparent hover-intercepting overlay on top of the content, ensuring the tooltip receives hover events even when the content widget (e.g. Button) handles hover internally.

Since: 1.0

func NewTooltip

func NewTooltip(content core.CanvasObject, text string) *Tooltip

NewTooltip creates a new tooltip wrapper around the given content.

Since: 1.0

func (*Tooltip) AccessibleLabel

func (t *Tooltip) AccessibleLabel() string

AccessibleLabel returns the tooltip text.

func (*Tooltip) AccessibleRole

func (t *Tooltip) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleTooltip.

func (*Tooltip) CreateRenderer

func (t *Tooltip) CreateRenderer() core.WidgetRenderer

CreateRenderer returns the renderer for this tooltip.

func (*Tooltip) HoverIn

func (t *Tooltip) HoverIn(e *event.HoverEvent)

HoverIn is implemented for the Hoverable interface but hover is handled by the internal overlay. This is called only for non-widget content.

func (*Tooltip) HoverMoved

func (t *Tooltip) HoverMoved(e *event.HoverEvent)

HoverMoved is implemented for the event.Hoverable interface; pointer movement within the content does not affect the tooltip, so it is a no-op.

func (*Tooltip) HoverOut

func (t *Tooltip) HoverOut()

HoverOut is implemented for the event.Hoverable interface and cancels any pending tooltip and hides a visible one when the pointer leaves the content.

func (*Tooltip) MinSize

func (t *Tooltip) MinSize() geo.Size

MinSize returns the wrapped content's minimum size.

func (*Tooltip) Tapped

func (t *Tooltip) Tapped(e *event.PointEvent)

Tapped delegates to the wrapped content and hides any visible tooltip.

func (*Tooltip) ToolTip

func (t *Tooltip) ToolTip() string

ToolTip returns the tooltip text, so the driver-level tooltip path (pre-rebrand tracker #800) shows this wrapper's text on the glfw desktop driver where the internal hover-catcher overlay never receives hover events.

type TopAppBar

type TopAppBar struct {
	BaseWidget
	Title          string
	NavigationIcon bellui.Resource
	Actions        []TopAppBarAction
	OnNavigation   func() `json:"-"`
}

TopAppBar is an MD3 top application bar with title, navigation icon, and action icons.

func NewTopAppBar

func NewTopAppBar(title string, navIcon bellui.Resource, navAction func()) *TopAppBar

NewTopAppBar creates a top app bar.

func (*TopAppBar) AccessibleLabel

func (t *TopAppBar) AccessibleLabel() string

AccessibleLabel returns the app bar title.

func (*TopAppBar) AccessibleRole

func (t *TopAppBar) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleToolbar.

func (*TopAppBar) CreateRenderer

func (t *TopAppBar) CreateRenderer() core.WidgetRenderer

func (*TopAppBar) MinSize

func (t *TopAppBar) MinSize() geo.Size

type TopAppBarAction

type TopAppBarAction struct {
	Icon     bellui.Resource
	OnTapped func()
}

TopAppBarAction is an action icon in the top app bar.

type Tree

type Tree struct {
	BaseWidget
	Root TreeNodeID

	// HideSeparators hides the separators between tree nodes
	//
	// Since: 1.0
	HideSeparators bool

	ChildUIDs      func(uid TreeNodeID) (c []TreeNodeID)                     `json:"-"` // Return a sorted slice of Children TreeNodeIDs for the given Node TreeNodeID
	CreateNode     func(branch bool) (o core.CanvasObject)                   `json:"-"` // Return a CanvasObject that can represent a Branch (if branch is true), or a Leaf (if branch is false)
	IsBranch       func(uid TreeNodeID) (ok bool)                            `json:"-"` // Return true if the given TreeNodeID represents a Branch
	OnBranchClosed func(uid TreeNodeID)                                      `json:"-"` // Called when a Branch is closed
	OnBranchOpened func(uid TreeNodeID)                                      `json:"-"` // Called when a Branch is opened
	OnSelected     func(uid TreeNodeID)                                      `json:"-"` // Called when the Node with the given TreeNodeID is selected.
	OnUnselected   func(uid TreeNodeID)                                      `json:"-"` // Called when the Node with the given TreeNodeID is unselected.
	UpdateNode     func(uid TreeNodeID, branch bool, node core.CanvasObject) `json:"-"` // Called to update the given CanvasObject to represent the data at the given TreeNodeID
	// contains filtered or unexported fields
}

Tree widget displays hierarchical data. Each node of the tree must be identified by a Unique TreeNodeID.

Since: 1.0

func NewTree

func NewTree(childUIDs func(TreeNodeID) []TreeNodeID, isBranch func(TreeNodeID) bool, create func(bool) core.CanvasObject, update func(TreeNodeID, bool, core.CanvasObject)) *Tree

NewTree returns a new performant tree widget defined by the passed functions. childUIDs returns the child TreeNodeIDs of the given node. isBranch returns true if the given node is a branch, false if it is a leaf. create returns a new template object that can be cached. update is used to apply data at specified data location to the passed template CanvasObject.

Since: 1.0

func NewTreeWithData

func NewTreeWithData(data binding.DataTree, createItem func(bool) core.CanvasObject, updateItem func(binding.DataItem, bool, core.CanvasObject)) *Tree

NewTreeWithData creates a new tree widget that will display the contents of the provided data.

Since: 1.0

func NewTreeWithStrings

func NewTreeWithStrings(data map[string][]string) (t *Tree)

NewTreeWithStrings creates a new tree with the given string map. Data must contain a mapping for the root, which defaults to empty string ("").

Since: 1.0

func (*Tree) AccessibleLabel

func (t *Tree) AccessibleLabel() string

AccessibleLabel returns an empty string; trees have no intrinsic label.

func (*Tree) AccessibleRole

func (t *Tree) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleTree.

func (*Tree) CloseAllBranches

func (t *Tree) CloseAllBranches()

CloseAllBranches closes all branches in the tree.

func (*Tree) CloseBranch

func (t *Tree) CloseBranch(uid TreeNodeID)

CloseBranch closes the branch with the given TreeNodeID.

func (*Tree) CreateRenderer

func (t *Tree) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer.

func (*Tree) FocusGained

func (t *Tree) FocusGained()

FocusGained is called after this Tree has gained focus.

func (*Tree) FocusLost

func (t *Tree) FocusLost()

FocusLost is called after this Tree has lost focus.

func (*Tree) IsBranchOpen

func (t *Tree) IsBranchOpen(uid TreeNodeID) bool

IsBranchOpen returns true if the branch with the given TreeNodeID is expanded.

func (*Tree) MinSize

func (t *Tree) MinSize() geo.Size

MinSize returns the size that this widget should not shrink below.

func (*Tree) OpenAllBranches

func (t *Tree) OpenAllBranches()

OpenAllBranches opens all branches in the tree.

func (*Tree) OpenBranch

func (t *Tree) OpenBranch(uid TreeNodeID)

OpenBranch opens the branch with the given TreeNodeID.

func (*Tree) RefreshItem

func (t *Tree) RefreshItem(id TreeNodeID)

RefreshItem refreshes a single item, specified by the item ID passed in.

Since: 1.0

func (*Tree) Resize

func (t *Tree) Resize(size geo.Size)

Resize sets a new size for a widget.

func (*Tree) ScrollTo

func (t *Tree) ScrollTo(uid TreeNodeID)

ScrollTo scrolls to the node with the given id. If the node is inside a closed branch, all ancestor branches are opened first.

Since: 1.0

func (*Tree) ScrollToBottom

func (t *Tree) ScrollToBottom()

ScrollToBottom scrolls to the bottom of the tree.

Since: 1.0

func (*Tree) ScrollToOffset

func (t *Tree) ScrollToOffset(offset float32)

ScrollToOffset scrolls the tree to the given offset position.

Since: 1.0

func (*Tree) ScrollToTop

func (t *Tree) ScrollToTop()

ScrollToTop scrolls to the top of the tree.

Since: 1.0

func (*Tree) Select

func (t *Tree) Select(uid TreeNodeID)

Select marks the specified node to be selected.

func (*Tree) ToggleBranch

func (t *Tree) ToggleBranch(uid string)

ToggleBranch flips the state of the branch with the given TreeNodeID.

func (*Tree) TypedKey

func (t *Tree) TypedKey(ev *event.KeyEvent)

TypedKey is called if a key event happens while this Tree is focused.

func (*Tree) TypedRune

func (t *Tree) TypedRune(_ rune)

TypedRune is called if a text event happens while this Tree is focused.

func (*Tree) Unselect

func (t *Tree) Unselect(uid TreeNodeID)

Unselect marks the specified node to be not selected.

func (*Tree) UnselectAll

func (t *Tree) UnselectAll()

UnselectAll sets all nodes to be not selected.

Since: 1.0

type TreeNodeID

type TreeNodeID = string

TreeNodeID represents the unique id of a tree node.

type TreeView

type TreeView struct {
	BaseWidget
	Root TreeViewNodeID // hidden root ID, default ""

	// Feature toggles
	AllowReorder   bool // enable drag-to-reorder within same parent
	AllowReparent  bool // enable drag to reparent into other branches
	AllowRename    bool // enable double-click inline rename
	AllowDelete    bool // enable Delete key and context menu delete
	ShowGuideLines bool // show vertical indent guide lines
	HideSeparators bool // hide row separators

	// Custom rendering (optional — defaults to icon + label)
	CreateNode func(branch bool) core.CanvasObject
	UpdateNode func(id TreeViewNodeID, branch bool, node core.CanvasObject)

	// ContextActions supplies extra entries for a node's right-click menu.
	// It is called per node, so the actions offered can depend on what that
	// node is, and its items are appended below the built-in Rename and
	// Delete entries with a separator between the two groups. Leaving it nil
	// — or returning no items — gives exactly the built-in menu.
	//
	// Since: 1.0
	ContextActions func(id TreeViewNodeID) []*bellui.MenuItem `json:"-"`

	// Event callbacks
	OnSelected     func(id TreeViewNodeID)                         `json:"-"`
	OnUnselected   func(id TreeViewNodeID)                         `json:"-"`
	OnBranchOpened func(id TreeViewNodeID)                         `json:"-"`
	OnBranchClosed func(id TreeViewNodeID)                         `json:"-"`
	OnMoved        func(id, newParentID TreeViewNodeID, index int) `json:"-"`
	OnRenamed      func(id TreeViewNodeID, newName string)         `json:"-"`
	OnDeleted      func(id TreeViewNodeID)                         `json:"-"`
	OnLoadMore     func(parentID TreeViewNodeID)                   `json:"-"`
	// contains filtered or unexported fields
}

TreeView displays hierarchical data with MD3 styling. It supports drag-to-reorder, inline rename, delete, icons, and chunked loading.

func NewTreeView

func NewTreeView() *TreeView

NewTreeView creates an empty TreeView.

func NewTreeViewWithNodes

func NewTreeViewWithNodes(nodes []TreeViewNode) *TreeView

NewTreeViewWithNodes creates a TreeView pre-populated with root-level nodes.

func (*TreeView) AccessibleLabel

func (tv *TreeView) AccessibleLabel() string

AccessibleLabel returns an empty string; tree views have no intrinsic label.

func (*TreeView) AccessibleRole

func (tv *TreeView) AccessibleRole() core.AccessibleRole

AccessibleRole returns core.RoleTree.

func (*TreeView) AddNode

func (tv *TreeView) AddNode(parentID TreeViewNodeID, node TreeViewNode) error

AddNode adds a node as the last child of parentID. Use "" as parentID for root-level nodes.

func (*TreeView) BeginRename

func (tv *TreeView) BeginRename(id TreeViewNodeID)

BeginRename starts inline rename of a node, putting the row into the same editor a double-click or the context menu's Rename entry opens. Use it for a host-supplied menu item or toolbar button that should rename the way the built-in gesture does — TreeView.RenameNode writes the new text straight into the model, which is the wrong tool when the user is meant to type it.

Ancestors are opened and the row scrolled into view first. A node added a moment earlier has no row yet, so the rename is held until the row exists and applied then; it is dropped if the row never appears. AllowRename gates the user's own rename gestures and does not apply here: calling this is the application asking for the editor.

Since: 1.0

func (*TreeView) ChildIDs

func (tv *TreeView) ChildIDs(parentID TreeViewNodeID) []TreeViewNodeID

ChildIDs returns the ordered list of child IDs for the given parent.

func (*TreeView) CloseAllBranches

func (tv *TreeView) CloseAllBranches()

CloseAllBranches collapses all branches.

func (*TreeView) CloseBranch

func (tv *TreeView) CloseBranch(id TreeViewNodeID)

CloseBranch collapses the branch with the given ID.

func (*TreeView) CreateRenderer

func (tv *TreeView) CreateRenderer() core.WidgetRenderer

CreateRenderer is a private method to Bellui which links this widget to its renderer.

func (*TreeView) DeleteNode

func (tv *TreeView) DeleteNode(id TreeViewNodeID)

DeleteNode removes a node. Emits OnDeleted.

func (*TreeView) FocusGained

func (tv *TreeView) FocusGained()

FocusGained is called when the TreeView gains focus.

func (*TreeView) FocusLost

func (tv *TreeView) FocusLost()

FocusLost is called when the TreeView loses focus.

func (*TreeView) GetNode

func (tv *TreeView) GetNode(id TreeViewNodeID) (TreeViewNode, bool)

GetNode returns a copy of the TreeViewNode for the given ID.

func (*TreeView) GetScrollOffset

func (tv *TreeView) GetScrollOffset() float32

GetScrollOffset returns the current Y scroll offset.

func (*TreeView) InsertNode

func (tv *TreeView) InsertNode(parentID TreeViewNodeID, index int, node TreeViewNode) error

InsertNode adds a node as a child of parentID at the given index.

func (*TreeView) IsBranch

func (tv *TreeView) IsBranch(id TreeViewNodeID) bool

IsBranch returns true if the node has children or hasMore is set.

func (*TreeView) IsBranchOpen

func (tv *TreeView) IsBranchOpen(id TreeViewNodeID) bool

IsBranchOpen returns true if the branch is expanded.

func (*TreeView) MinSize

func (tv *TreeView) MinSize() geo.Size

MinSize returns the minimum size of this TreeView.

func (*TreeView) MoveNode

func (tv *TreeView) MoveNode(id, newParentID TreeViewNodeID, index int)

MoveNode moves a node to a new parent at the given index. Emits OnMoved.

func (*TreeView) OpenAllBranches

func (tv *TreeView) OpenAllBranches()

OpenAllBranches expands all branches recursively.

func (*TreeView) OpenBranch

func (tv *TreeView) OpenBranch(id TreeViewNodeID)

OpenBranch expands the branch with the given ID.

func (*TreeView) RefreshItem

func (tv *TreeView) RefreshItem(id TreeViewNodeID)

RefreshItem refreshes a single item.

func (*TreeView) RemoveNode

func (tv *TreeView) RemoveNode(id TreeViewNodeID)

RemoveNode removes a node and all its descendants.

func (*TreeView) RenameNode

func (tv *TreeView) RenameNode(id TreeViewNodeID, newName string)

RenameNode updates a node's text. Emits OnRenamed.

func (*TreeView) Resize

func (tv *TreeView) Resize(size geo.Size)

Resize handles size changes.

func (*TreeView) ScrollTo

func (tv *TreeView) ScrollTo(id TreeViewNodeID)

ScrollTo scrolls to make the node with the given ID visible.

func (*TreeView) ScrollToBottom

func (tv *TreeView) ScrollToBottom()

ScrollToBottom scrolls to the bottom.

func (*TreeView) ScrollToOffset

func (tv *TreeView) ScrollToOffset(offset float32)

ScrollToOffset scrolls to the given Y offset.

func (*TreeView) ScrollToTop

func (tv *TreeView) ScrollToTop()

ScrollToTop scrolls to the top.

func (*TreeView) Select

func (tv *TreeView) Select(id TreeViewNodeID)

Select selects the node with the given ID.

func (*TreeView) Selected

func (tv *TreeView) Selected() TreeViewNodeID

Selected returns the currently selected node ID, or "" if none.

func (*TreeView) SetChildren

func (tv *TreeView) SetChildren(parentID TreeViewNodeID, nodes []TreeViewNode)

SetChildren replaces all children of parentID with the given nodes.

func (*TreeView) SetHasMore

func (tv *TreeView) SetHasMore(parentID TreeViewNodeID, hasMore bool)

SetHasMore marks a branch as having more children to load.

func (*TreeView) ToggleBranch

func (tv *TreeView) ToggleBranch(id TreeViewNodeID)

ToggleBranch toggles the branch with the given ID.

func (*TreeView) TypedKey

func (tv *TreeView) TypedKey(ev *event.KeyEvent)

TypedKey handles keyboard navigation.

func (*TreeView) TypedRune

func (tv *TreeView) TypedRune(_ rune)

TypedRune is a no-op.

func (*TreeView) Unselect

func (tv *TreeView) Unselect(id TreeViewNodeID)

Unselect deselects the node with the given ID.

func (*TreeView) UnselectAll

func (tv *TreeView) UnselectAll()

UnselectAll clears all selection.

func (*TreeView) UpdateNodeData

func (tv *TreeView) UpdateNodeData(id TreeViewNodeID, node TreeViewNode)

UpdateNodeData updates the Text, Icon, and Data of an existing node.

type TreeViewNode

type TreeViewNode struct {
	ID   TreeViewNodeID
	Text string
	Icon bellui.Resource // optional; nil means no icon
	Data any             // arbitrary user data
}

TreeViewNode describes a single node's data in a TreeView.

type TreeViewNodeID

type TreeViewNodeID = string

TreeViewNodeID represents the unique id of a tree view node.

type TwoStateToolbarAction

type TwoStateToolbarAction struct {
	// OnActivated is called with the new state whenever it changes, by tap
	// or by SetOn.
	OnActivated func(on bool) `json:"-"`
	// contains filtered or unexported fields
}

TwoStateToolbarAction is a push button style of ToolbarItem that displays a different icon depending on its state, e.g. play/pause for a media player or show/hide for a side panel. Tapping toggles the state.

Since: 1.0

func NewTwoStateToolbarAction

func NewTwoStateToolbarAction(offIcon, onIcon bellui.Resource, onActivated func(on bool)) *TwoStateToolbarAction

NewTwoStateToolbarAction returns a new two-state ToolbarItem showing offIcon while the state is false and onIcon while it is true.

Since: 1.0

func (*TwoStateToolbarAction) On

func (t *TwoStateToolbarAction) On() bool

On returns the current state.

func (*TwoStateToolbarAction) SetOffIcon

func (t *TwoStateToolbarAction) SetOffIcon(icon bellui.Resource)

SetOffIcon sets the icon that is displayed when the state is false.

func (*TwoStateToolbarAction) SetOn

func (t *TwoStateToolbarAction) SetOn(on bool)

SetOn updates the state, the icon shown, and notifies OnActivated when the state actually changed.

func (*TwoStateToolbarAction) SetOnIcon

func (t *TwoStateToolbarAction) SetOnIcon(icon bellui.Resource)

SetOnIcon sets the icon that is displayed when the state is true.

func (*TwoStateToolbarAction) ToolbarObject

func (t *TwoStateToolbarAction) ToolbarObject() core.CanvasObject

ToolbarObject gets a button to render this ToolbarAction.

type UnderlineStyle

type UnderlineStyle int

UnderlineStyle selects the shape of a StyleRun underline.

Since: 1.0

const (
	// UnderlineSolid is a straight line, e.g. for link decorations.
	UnderlineSolid UnderlineStyle = iota
	// UnderlineWavy is a sine-wave squiggle, e.g. for error/warning diagnostics.
	UnderlineWavy
	// UnderlineDotted is a dotted line, an alternative diagnostic style.
	UnderlineDotted
)

Source Files

Jump to

Keyboard shortcuts

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