core/titlebar/titlebar.go

Functions Structs Interfaces

Functions

func AccessibilityActions

AccessibilityActions returns nil.

func (w *Widget) AccessibilityActions() []a11y.Action {
	return nil
}

func AccessibilityHint

AccessibilityHint returns the window title as a hint.

func (w *Widget) AccessibilityHint() string {
	return w.cfg.title
}

func AccessibilityLabel

AccessibilityLabel returns "Title Bar".

func (w *Widget) AccessibilityLabel() string {
	return a11yLabel
}

func AccessibilityRole

AccessibilityRole returns [a11y.RoleBanner].

func (w *Widget) AccessibilityRole() a11y.Role {
	return a11y.RoleBanner
}

func AccessibilityState

AccessibilityState returns the accessibility state.

func (w *Widget) AccessibilityState() a11y.State {
	return a11y.State{
		Disabled:	!w.IsEnabled(),
		Hidden:		!w.IsVisible(),
	}
}

func AccessibilityValue

AccessibilityValue returns an empty string.

func (w *Widget) AccessibilityValue() string {
	return ""
}

func Children

Children returns all child widgets (leading + center).

func (w *Widget) Children() []widget.Widget {
	var children []widget.Widget
	for _, child := range w.cfg.leading {
		if child != nil {
			children = append(children, child)
		}
	}
	for _, child := range w.cfg.center {
		if child != nil {
			children = append(children, child)
		}
	}
	if len(children) == 0 {
		return nil
	}
	return children
}

func Draw

Draw renders the title bar background, child widgets, and control buttons.

func (w *Widget) Draw(ctx widget.Context, canvas widget.Canvas) {
	if !w.IsVisible() {
		return
	}

	bounds := w.Bounds()

	// Draw background.
	w.painter.DrawBackground(canvas, bounds, BackgroundState{
		Focused: w.cfg.focused,
	})

	// Draw children with transform offset.
	canvas.PushTransform(bounds.Min)

	// Draw leading children.
	for _, child := range w.cfg.leading {
		if child == nil {
			continue
		}
		widget.StampScreenOrigin(child, canvas)
		child.Draw(ctx, canvas)
	}

	// Draw title text if no center children and title is set.
	if len(w.cfg.center) == 0 && w.cfg.title != "" {
		controlsWidth := w.controlsZoneWidth()
		titleBounds := geometry.NewRect(0, 0, bounds.Width()-controlsWidth, bounds.Height())
		canvas.DrawText(w.cfg.title, titleBounds, titleFontSize, defaultControlFg, false, widget.TextAlignCenter)
	}

	// Draw center children.
	for _, child := range w.cfg.center {
		if child == nil {
			continue
		}
		widget.StampScreenOrigin(child, canvas)
		child.Draw(ctx, canvas)
	}

	// Draw control buttons.
	if w.cfg.chrome != nil {
		for i := 0; i < controlCount; i++ {
			ct := w.controlTypeForIndex(i)
			w.painter.DrawControlButton(canvas, w.controlBounds[i], ct, ControlState{
				Hovered:	w.controlStates[i] == stateHover,
				Pressed:	w.controlStates[i] == statePressed,
			})
		}
	}

	canvas.PopTransform()
}

func Event

Event handles input events for the title bar and its children.

func (w *Widget) Event(ctx widget.Context, e event.Event) bool {
	if !w.IsVisible() || !w.IsEnabled() {
		return false
	}

	switch ev := e.(type) {
	case *event.MouseEvent:
		return w.handleMouseEvent(ctx, ev)
	default:
		// Dispatch to child widgets.
		return w.dispatchToChildren(ctx, e)
	}
}

func HasChrome

HasChrome reports whether a WindowChrome is available.

func (w *Widget) HasChrome() bool {
	return w.cfg.chrome != nil
}

func HitTest

HitTest returns what region of the title bar a screen-space point falls in.

This is intended to be called from a hit-test callback registered with the

window system.

func (w *Widget) HitTest(x, y float64) HitTestResult {
	pt := geometry.Pt(float32(x), float32(y))
	screenBounds := w.ScreenBounds()

	// Not in title bar at all.
	if !screenBounds.Contains(pt) {
		return HitTestClient
	}

	local := pt.Sub(screenBounds.Min)

	// Check control buttons (reverse order: close first for priority).
	if w.cfg.chrome != nil {
		for i := controlCount - 1; i >= 0; i-- {
			if w.controlBounds[i].Contains(local) {
				switch i {
				case controlIdxClose:
					return HitTestClose
				case controlIdxMaximize:
					return HitTestMaximize
				case controlIdxMinimize:
					return HitTestMinimize
				}
			}
		}
	}

	// Check leading and center child widgets.
	if hitTestChildren(w.cfg.leading, w.leadingBounds, local) {
		return HitTestClient
	}
	if hitTestChildren(w.cfg.center, w.centerBounds, local) {
		return HitTestClient
	}

	// Empty space = caption (drag to move).
	return HitTestCaption
}

func IsFocusable

IsFocusable reports whether the title bar can receive keyboard focus.

Title bars are not typically focusable.

func (w *Widget) IsFocusable() bool {
	return false
}

func Layout

Layout calculates the title bar's preferred size within the given constraints.

func (w *Widget) Layout(ctx widget.Context, constraints geometry.Constraints) geometry.Size {
	preferred := geometry.Sz(constraints.MaxWidth, w.cfg.height)
	size := constraints.Constrain(preferred)

	w.layoutChildren(ctx, size)

	w.SetBounds(geometry.FromPointSize(w.Position(), size))
	return size
}

func New

New creates a new title bar Widget with the given options.

 

The returned widget is visible and enabled by default. The default

height is 40 logical pixels.

func New(opts ...Option) *Widget {
	w := &Widget{
		painter: DefaultPainter{},
	}
	w.SetVisible(true)
	w.SetEnabled(true)

	w.cfg.height = defaultBarHeight
	w.cfg.focused = true

	for _, opt := range opts {
		opt(&w.cfg)
	}

	if w.cfg.painter != nil {
		w.painter = w.cfg.painter
	}

	w.leadingBounds = make([]geometry.Rect, len(w.cfg.leading))
	w.centerBounds = make([]geometry.Rect, len(w.cfg.center))

	// ADR-028: parent chain for upward dirty propagation.
	// Flutter: RenderObject.adoptChild sets parent on each child.
	type parentSetter interface{ SetParent(widget.Widget) }
	for _, child := range w.cfg.leading {
		if child != nil {
			if ps, ok := child.(parentSetter); ok {
				ps.SetParent(w)
			}
		}
	}
	for _, child := range w.cfg.center {
		if child != nil {
			if ps, ok := child.(parentSetter); ok {
				ps.SetParent(w)
			}
		}
	}

	return w
}

func SetFocusedState

SetFocusedState updates whether the window is focused, affecting visual appearance.

func (w *Widget) SetFocusedState(focused bool) {
	w.cfg.focused = focused
}

func SetTitle

SetTitle updates the title text.

func (w *Widget) SetTitle(title string) {
	w.cfg.title = title
}

func Title

Title returns the current title text.

func (w *Widget) Title() string {
	return w.cfg.title
}

Structs

type Widget struct

Widget implements a custom window title bar.

 

The title bar renders a horizontal bar with three zones: leading (left),

center, and trailing (right). The trailing zone contains window control

buttons (minimize, maximize/restore, close) when a [WindowChrome] is provided.

 

Empty space in the title bar acts as a drag region for window movement.

Child widgets placed in the leading and center zones receive events normally.

 

A Widget is created with [New] using functional options:

 

tb := titlebar.New(

titlebar.Title("My App"),

titlebar.Leading(menuBtn),

titlebar.Chrome(windowChrome),

titlebar.PainterOpt(painter),

)

type Widget struct {
	widget.WidgetBase

	cfg	config
	painter	Painter

	// controlBounds holds the bounds for each control button (min, max, close).
	controlBounds	[controlCount]geometry.Rect

	// controlStates holds the interaction state for each control button.
	controlStates	[controlCount]interactionState

	// leadingBounds holds the calculated bounds for each leading child widget.
	leadingBounds	[]geometry.Rect

	// centerBounds holds the calculated bounds for each center child widget.
	centerBounds	[]geometry.Rect

	// hoveredChild tracks the currently hovered child for MouseLeave dispatch.
	// nil means no child is hovered.
	hoveredChild	widget.Widget
}

Interfaces

type WindowChrome interface

WindowChrome provides window management operations.

 

This interface is a subset of gpucontext.WindowChrome, defined locally

to avoid a direct dependency on the gpucontext package. Callers should

pass the gpucontext.WindowChrome value obtained from the window provider.

type WindowChrome interface {
	// Minimize minimizes the window.
	Minimize()

	// Maximize maximizes the window.
	Maximize()

	// IsMaximized reports whether the window is currently maximized.
	IsMaximized() bool

	// Close closes the window.
	Close()
}