Documentation
¶
Overview ¶
Package overlay provides an overlay stack for displaying floating content above the normal widget tree.
Overlays are used by dropdowns, popovers, tooltips, dialogs, and any widget that needs to float above the main UI. The package manages their lifecycle, event dispatch, and draw order.
Stack ¶
The core abstraction is Stack, owned by the [app.Window], which manages a last-in-first-out collection of Overlay widgets. Events are dispatched to the top overlay before reaching the regular widget tree, and overlays are drawn after (on top of) the regular tree.
stack := overlay.NewStack(func() { requestRedraw() })
stack.Push(myOverlay)
stack.Pop()
Container ¶
Container is a ready-made Overlay implementation that wraps content with a full-window transparent backdrop. Clicks on the backdrop (outside the content) trigger dismissal. For modal overlays, a semi-transparent scrim is drawn behind the content:
c := overlay.NewContainer(menuWidget, windowSize,
overlay.WithOnDismiss(func() { closeMenu() }),
overlay.WithModal(true),
)
Positioning ¶
The Position helper calculates where an overlay should appear relative to an anchor widget, with automatic viewport clamping to keep the overlay on screen:
pos := overlay.Position(
overlay.PlacementBelow,
anchorBounds,
overlaySize,
windowSize,
4, // gap
)
Integration ¶
Widgets push overlays via the widget.OverlayManager interface obtained from widget.Context, and never import the overlay package directly. This avoids circular dependencies between widget packages and the overlay infrastructure.
Package overlay provides an overlay stack for displaying content above the normal widget tree. Overlays are used by dropdowns, tooltips, dialogs, and any widget that needs to float above the main UI.
The core abstraction is Stack, owned by the Window, which manages a last-in-first-out collection of Overlay widgets. Events are dispatched to the top overlay before reaching the regular widget tree, and overlays are drawn after (on top of) the regular tree.
Widgets push overlays via the widget.OverlayManager interface obtained from widget.Context, and never import the overlay package directly. This avoids circular dependencies.
Index ¶
- func Position(placement Placement, anchorGlobal geometry.Rect, overlaySize geometry.Size, ...) geometry.Point
- type Container
- func (c *Container) Children() []widget.Widget
- func (c *Container) Content() widget.Widget
- func (c *Container) Dismiss()
- func (c *Container) Draw(ctx widget.Context, canvas widget.Canvas)
- func (c *Container) Event(ctx widget.Context, e event.Event) bool
- func (c *Container) Layout(ctx widget.Context, constraints geometry.Constraints) geometry.Size
- func (c *Container) Modal() bool
- func (c *Container) SetWindowSize(size geometry.Size)
- type ContainerOption
- type Overlay
- type Placement
- type Stack
- func (s *Stack) Draw(ctx widget.Context, canvas widget.Canvas)
- func (s *Stack) HandleEvent(ctx widget.Context, e event.Event) bool
- func (s *Stack) IsEmpty() bool
- func (s *Stack) Layout(ctx widget.Context, windowSize geometry.Size)
- func (s *Stack) Len() int
- func (s *Stack) List() []Overlay
- func (s *Stack) Pop() Overlay
- func (s *Stack) Push(o Overlay)
- func (s *Stack) Remove(o Overlay)
- func (s *Stack) Top() Overlay
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Position ¶
func Position( placement Placement, anchorGlobal geometry.Rect, overlaySize geometry.Size, windowSize geometry.Size, gap float32, ) geometry.Point
Position calculates the overlay position relative to an anchor rectangle.
Parameters:
- placement: preferred placement direction
- anchorGlobal: the anchor widget's bounds in window coordinates
- overlaySize: the measured size of the overlay content
- windowSize: the total window size for viewport clamping
- gap: spacing between the anchor and overlay edges
The function applies flip logic (tries the opposite side if the overlay would go out of bounds) and then clamps to the viewport.
Types ¶
type Container ¶
type Container struct {
widget.WidgetBase
// contains filtered or unexported fields
}
Container wraps overlay content with a full-window transparent backdrop. Clicks on the backdrop (outside the content) trigger dismissal. For modal overlays, a semi-transparent scrim is drawn behind the content.
Container implements the Overlay interface.
func NewContainer ¶
func NewContainer(content widget.Widget, windowSize geometry.Size, opts ...ContainerOption) *Container
NewContainer creates a new overlay container wrapping the given content. The windowSize is used to size the backdrop to fill the entire window.
func (*Container) Event ¶
Event dispatches events. Content gets first chance. If content does not consume the event, Escape key and mouse press outside content trigger dismissal. Modal containers consume all remaining events.
func (*Container) Modal ¶
Modal returns true if this container blocks interaction with content below.
func (*Container) SetWindowSize ¶
SetWindowSize updates the backdrop size. Call this when the window is resized.
type ContainerOption ¶
type ContainerOption func(*Container)
ContainerOption configures a Container during construction.
func WithModal ¶
func WithModal(modal bool) ContainerOption
WithModal makes the container modal. A modal container draws a semi-transparent scrim and consumes all events not handled by the content.
func WithOnDismiss ¶
func WithOnDismiss(fn func()) ContainerOption
WithOnDismiss sets the callback invoked when the container is dismissed (click outside content or Escape key).
type Overlay ¶
type Overlay interface {
widget.Widget
// Dismiss is called when the overlay should close (e.g. click outside, Escape key).
Dismiss()
// Modal returns true if the overlay blocks interaction with content below.
// A modal overlay consumes all events that are not handled by its content.
Modal() bool
}
Overlay represents content displayed above the normal widget tree. It extends widget.Widget with dismissal and modality support.
type Placement ¶
type Placement uint8
Placement defines where an overlay appears relative to its anchor widget.
const ( // PlacementBelow positions the overlay below the anchor (default for dropdowns). PlacementBelow Placement = iota // PlacementAbove positions the overlay above the anchor. PlacementAbove // PlacementLeft positions the overlay to the left of the anchor. PlacementLeft // PlacementRight positions the overlay to the right of the anchor. PlacementRight )
Placement constants.
type Stack ¶
type Stack struct {
// contains filtered or unexported fields
}
Stack manages a last-in-first-out collection of overlays for a window.
The stack supports push, pop, and targeted removal. When an overlay is removed, all overlays above it in the stack are also removed (maintaining stack semantics). An optional onChange callback is invoked whenever the stack is modified, which typically triggers a redraw.
Stack is NOT safe for concurrent access. All operations must occur on the main/UI thread.
func NewStack ¶
func NewStack(onChange func()) *Stack
NewStack creates an empty overlay stack. The onChange callback, if non-nil, is called whenever the stack contents change (push, pop, or remove).
func (*Stack) HandleEvent ¶
HandleEvent dispatches an event to the overlay stack. Events are sent to the top overlay first. If the top overlay is modal and does not consume the event, the event is still blocked from reaching the normal widget tree.
Returns true if the event was consumed or blocked by a modal overlay.
func (*Stack) List ¶
List returns the overlay slice in bottom-to-top order. The returned slice should not be modified by the caller.