core/dialog/widget.go

Functions Structs

Functions

func Children

Children returns nil; the surface has no child widgets in the tree.

func (s *surfaceWidget) Children() []widget.Widget {
	return nil
}

func Children

Children returns nil because the dialog's content is rendered via the

overlay surface, not as a direct child.

func (w *Widget) Children() []widget.Widget {
	return nil
}

func Close

Close removes the dialog from the overlay stack.

If the dialog is not open, this is a no-op.

func (w *Widget) Close(ctx widget.Context) {
	w.doClose(ctx)
}

func Dismiss

Dismiss is called by the overlay stack when the overlay should close.

func (s *surfaceWidget) Dismiss() {
	s.dialog.doClose(s.ctx)
}

func Draw

Draw renders the backdrop and dialog surface.

func (s *surfaceWidget) Draw(ctx widget.Context, canvas widget.Canvas) {
	if canvas == nil {
		return
	}

	d := s.dialog

	// Draw backdrop.
	backdropColor := defaultBackdropColor
	canvas.DrawRect(s.Bounds(), backdropColor)

	// Compute dialog bounds.
	windowSize := ctx.WindowSize()
	dialogBounds := d.computeDialogBounds(windowSize)

	// Delegate to painter for the dialog surface.
	d.painter.PaintDialog(canvas, PaintState{
		Title:		d.cfg.ResolvedTitle(),
		HasContent:	d.cfg.content != nil,
		Actions:	d.cfg.actions,
		Focused:	s.focusIndex >= 0,
		Bounds:		dialogBounds,
	})

	// Draw content widget if present.
	if d.cfg.content != nil {
		contentBounds := geometry.Rect{
			Min:	geometry.Pt(dialogBounds.Min.X+contentPadding, dialogBounds.Min.Y+titleAreaHeight),
			Max:	geometry.Pt(dialogBounds.Max.X-contentPadding, dialogBounds.Max.Y-actionAreaHeight),
		}
		if setter, ok := d.cfg.content.(interface{ SetBounds(geometry.Rect) }); ok {
			setter.SetBounds(contentBounds)
		}
		d.cfg.content.Draw(ctx, canvas)
	}
}

func Draw

Draw renders the dialog. When shown as an overlay, drawing is handled

by the surfaceWidget. This is a no-op when hidden.

func (w *Widget) Draw(_ widget.Context, _ widget.Canvas) {
	// Rendering is handled by surfaceWidget in the overlay stack.
}

func Event

Event handles input events. When shown as an overlay, events are handled

by the surfaceWidget. This returns false when hidden.

func (w *Widget) Event(_ widget.Context, _ event.Event) bool {
	return false
}

func Event

Event handles input events for the dialog overlay.

func (s *surfaceWidget) Event(ctx widget.Context, e event.Event) bool {
	switch ev := e.(type) {
	case *event.KeyEvent:
		return s.handleKeyEvent(ctx, ev)
	case *event.MouseEvent:
		return s.handleMouseEvent(ctx, ev)
	default:
		// Modal: consume all events to prevent interaction with background.
		return true
	}
}

func IsOpen

IsOpen returns true if the dialog is currently visible as an overlay.

func (w *Widget) IsOpen() bool {
	return w.visible
}

func Layout

Layout calculates the dialog's preferred size. When shown as an overlay,

layout is handled by the surfaceWidget. This returns zero size when hidden.

func (w *Widget) Layout(_ widget.Context, constraints geometry.Constraints) geometry.Size {
	if !w.visible {
		return geometry.Size{}
	}
	return constraints.Constrain(geometry.Sz(defaultMaxWidth, minDialogHeight))
}

func Layout

Layout fills the entire window.

func (s *surfaceWidget) Layout(ctx widget.Context, constraints geometry.Constraints) geometry.Size {
	windowSize := ctx.WindowSize()
	size := constraints.Constrain(windowSize)
	s.SetBounds(geometry.NewRect(0, 0, size.Width, size.Height))
	return size
}

func Modal

Modal returns true; dialogs always block interaction with the background.

func (s *surfaceWidget) Modal() bool {
	return true
}

func Mount

Mount creates signal bindings for push-based invalidation.

Implements [widget.Lifecycle].

func (w *Widget) Mount(ctx widget.Context) {
	sched := ctx.Scheduler()
	if sched == nil {
		return
	}
	if w.cfg.readonlyTitleSignal != nil {
		b := state.BindToScheduler(w.cfg.readonlyTitleSignal, w, sched)
		w.AddBinding(b)
	} else if w.cfg.titleSignal != nil {
		b := state.BindToScheduler(w.cfg.titleSignal, w, sched)
		w.AddBinding(b)
	}
}

func New

New creates a new dialog Widget with the given options.

 

The returned widget is NOT visible until [Widget.Show] is called.

By default, the dialog is dismissible (backdrop click) and closes on Escape.

func New(opts ...Option) *Widget {
	w := &Widget{
		painter: DefaultPainter{},
	}
	// Defaults.
	w.cfg.dismissible = true
	w.cfg.escToClose = true
	w.cfg.maxWidth = defaultMaxWidth

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

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

	w.SetEnabled(true)

	return w
}

func Show

Show pushes the dialog as a modal overlay via the context's OverlayManager.

If the dialog is already open, this is a no-op.

func (w *Widget) Show(ctx widget.Context) {
	if w.visible {
		return
	}

	om := ctx.OverlayManager()
	if om == nil {
		return
	}

	w.visible = true
	w.SetVisible(true)

	// Create the surface widget for overlay rendering.
	w.surface = newSurfaceWidget(w, ctx)

	om.PushOverlay(w.surface, func() {
		w.doClose(ctx)
	})

	// ADR-028: visual only — overlay display is handled by DrawOverlays.
	w.SetNeedsRedraw(true)
}

func Unmount

Unmount is called when the dialog is removed from the widget tree.

Implements [widget.Lifecycle].

func (w *Widget) Unmount() {
	// Bindings are cleaned up automatically by WidgetBase.CleanupBindings().
}

Structs

type Widget struct

Widget implements a modal dialog with title, content, and action buttons.

 

A dialog is created in a hidden state with [New]. Call [Widget.Show] to

push it as a modal overlay, and [Widget.Close] to remove it.

 

The dialog renders a semi-transparent backdrop that blocks interaction

with the background, and a centered surface containing the title,

optional content widget, and action buttons.

type Widget struct {
	widget.WidgetBase
	cfg	config
	painter	Painter
	visible	bool

	// Overlay surface widget manages the dialog surface content.
	surface	*surfaceWidget
}