Selkie--Widget--Toast
NAME
Selkie::Widget::Toast - Transient overlay notification
SYNOPSIS
You normally use $app.toast(...) which manages the widget for you:
$app.toast('Settings saved');
$app.toast('Connection lost', duration => 5e0);Direct construction is rarely needed.
DESCRIPTION
A centered single-line message bar that auto-dismisses. By convention rendered near the bottom of the screen.
Unlike most widgets, Toast does not own a backing plane covering its full area β that would obscure the widgets behind it. Instead it manages a small inline plane, created on show and destroyed on hide, attached directly to the parent stdplane via attach.
The Selkie::App.toast wrapper hides these details: it lazily constructs the widget, calls attach, and ensures the correct size on each invocation.
Fading
Off by default. Selkie::App.new(:animate-toast) turns it on, at which point Selkie::App hands the toast its tween group via enable-fade and every show resolves the bar up out of the screen background over fade-in-seconds and dissolves it back over fade-out-seconds before it disappears.
my $app = Selkie::App.new(theme => $theme, :animate-toast);
$app.toast('Saved'); # fades in, holds, fades out
# Driving a detached Toast yourself:
$toast.enable-fade($app.tweens);
$toast.show('Saved', duration => 2e0);What ramps is colour, not alpha β notcurses alpha is a two-bit enum with no intermediate states (Selkie::Alpha), so a fade is a walk between two RGB values. The far end is theme.base.bg for both the foreground and the background, i.e. a bar the same colour as the screen behind it. A theme whose base carries no bg has no colour to fade from, and the toast simply appears and disappears as it always has.
The out-fade is armed from inside tick, which Selkie::App already calls once per frame: when the remaining lifetime drops below fade-out-seconds the toast adds one reversed tween to the group and never looks at the clock again. Both tweens are bounded, and the toast cancels whatever is in flight on the next show, on dismissal, and in destroy β so a fade can never outlive the plane it paints into.
Timings are fade-in-seconds (0.1) and fade-out-seconds (0.2), settable at construction. A toast whose whole duration is shorter than fade-out-seconds gets an out-fade clamped to the time it actually has left rather than one that would run past its own dismissal.
EXAMPLES
Custom styling
# Red warning style
$app.store.subscribe-with-callback(
'errors',
-> $s { $s.get-in('error') // '' },
-> $msg {
if $msg.chars > 0 {
$app.toast($msg); # default blue-highlight style
}
},
$some-widget,
);SEE ALSO
Selkie::App β
toast(...)wrapper is the normal entry pointSelkie::Tween β the interpolation the fade runs on
Selkie::Alpha β why a fade is a colour ramp and never an alpha ramp
has Num $.fade-in-seconds
Seconds the toast takes to resolve up out of the screen background. Only consulted once enable-fade has been called.
has Num $.fade-out-seconds
Seconds the toast takes to dissolve back into it, ending as the duration expires. Clamped to the lifetime actually remaining.
method attach
method attach(
Notcurses::Native::Types::NcplaneHandle $parent-plane,
Int :$rows where { ... },
Int :$cols where { ... }
) returns MuAttach to the standard plane. Called once by Selkie::App in place of the usual init-plane β Toast lives outside the widget tree (so it can paint on top of any screen and any modal) so it doesn't adopt a plane of its own; the toast-plane is created lazily in render on first show.
method handle-resize
method handle-resize(
Int $rows where { ... },
Int $cols where { ... }
) returns MuToast lives at screen-top, outside the widget tree, so it doesn't receive the normal handle-resize cascade from containers. App calls this directly when the terminal resizes so the toast-plane sits at the correct width.
method resize-screen
method resize-screen(
Int $rows where { ... },
Int $cols where { ... }
) returns MuBack-compat alias. Deprecated β prefer handle-resize.
method show
method show(
Str:D $message,
Num :$duration = 2e0,
Selkie::Style :$style,
Instant :$at = Code.new
) returns MuShow a toast message for :duration seconds. Re-callable while a toast is already showing β the new message replaces the old and the duration restarts from :at. Apps don't usually call this directly; prefer $app.toast(...) which routes here. :at is the toast's zero point, defaulting to now; pass it explicitly to drive the lifetime (and the fades) from a test clock rather than the wall clock.
method is-visible
method is-visible() returns BoolTrue while a toast is currently being shown (between show and the next tick that observes the duration has expired).
method enable-fade
method enable-fade(
Selkie::Tween::TweenGroup:D $group
) returns NilTurn fading on and hand the toast the Selkie::Tween::TweenGroup its fades run on β normally Selkie::App.tweens, wired automatically when the app was built with CΒ«:animate-toastΒ». Idempotent, and takes effect from the next show: a toast already on screen keeps whatever it is doing.
method disable-fade
method disable-fade() returns NilGo back to appearing and vanishing. Any fade in flight is cancelled and the toast drops straight to its own style, so a "reduce motion" preference flipped mid-fade lands somewhere sane rather than freezing a half-transparent bar on screen.
method fade-enabled
method fade-enabled() returns BoolTrue once enable-fade has been called and disable-fade hasn't.
method fading
method fading() returns BoolTrue while a fade-in or fade-out is actually running. A testing hook.
method render-style
method render-style() returns Selkie::StyleThe style render paints with right now: the fade's current interpolation while one is in flight, and the toast's own style otherwise. Public so a fade can be asserted without a plane.
method fade-from
method fade-from(
Selkie::Style:D $to
) returns Selkie::StyleThe colour a fade starts from (and ends at): the theme's base background on both channels, with every discrete attribute copied from $to so nothing snaps at the midpoint. Returns $to unchanged when the theme's base has no background β there is no colour to fade from, so there is no fade.
method tick
method tick(
Instant $at = Code.new
) returns BoolAdvance the toast's lifetime clock. Called once per frame by Selkie::App. When the duration has elapsed, the toast flips to invisible and its plane is destroyed. Returns True when visibility just transitioned from visible to invisible this tick β the caller (Selkie::App) treats that as a signal to force one more composite render so the toast is actually erased from the terminal. Returns False otherwise (toast is still visible, or was never visible this tick). $at defaults to now; pass it to drive the lifetime from a test clock. This is also where the out-fade is armed, once, when the remaining lifetime drops under fade-out-seconds β a check that costs one subtraction on a toast that isn't fading.
method destroy
method destroy() returns MuTear down the toast plane and cancel any fade still running against it. Called by Selkie::App.shutdown; apps don't usually call this directly.