62 lines
2.9 KiB
Swift
62 lines
2.9 KiB
Swift
import Adw
|
|
|
|
/// Converts `duration` to the whole seconds `adw_toast_set_timeout` expects.
|
|
///
|
|
/// A positive duration never rounds down to `0`, because `0` means "never
|
|
/// auto-dismiss" in libadwaita and silently turning a brief toast into a
|
|
/// permanent one would be worse than rounding up. `.zero` and negative
|
|
/// durations map to `0` deliberately.
|
|
///
|
|
/// - Parameter duration: The requested on-screen time.
|
|
/// - Returns: Whole seconds, clamped to at least `1` for any positive duration.
|
|
private func toastTimeoutSeconds(_ duration: Duration) -> UInt32 {
|
|
let components = duration.components
|
|
guard components.seconds > 0 || (components.seconds == 0 && components.attoseconds > 0)
|
|
else { return 0 }
|
|
let rounded = components.seconds + (components.attoseconds >= 500_000_000_000_000_000 ? 1 : 0)
|
|
return UInt32(clamping: max(1, rounded))
|
|
}
|
|
|
|
extension Adw.Toast {
|
|
/// Creates a fully configured toast in one expression.
|
|
///
|
|
/// ```swift
|
|
/// toasts.addToast(Toast(title: "File saved", buttonLabel: "Undo") { undo() })
|
|
/// ```
|
|
///
|
|
/// `onClick` has no default value, so the inherited `Toast(title:)`
|
|
/// initializer stays reachable and unambiguous for the bare case.
|
|
///
|
|
/// - Parameters:
|
|
/// - title: The toast text, interpreted as Pango markup unless `useMarkup`
|
|
/// is `false`.
|
|
/// - timeout: How long the toast stays on screen. `nil` keeps libadwaita's
|
|
/// default. `.zero` (or a negative duration) means the toast never
|
|
/// dismisses itself. `AdwToast` counts whole seconds, so the value is
|
|
/// rounded to the nearest second and any positive duration is clamped to
|
|
/// at least one second rather than collapsing to "never".
|
|
/// - priority: How the toast behaves when one is already displayed. `nil`
|
|
/// keeps libadwaita's default.
|
|
/// - buttonLabel: Label for the toast's action button. `nil` shows no button.
|
|
/// - useMarkup: Whether `title` is Pango markup. `nil` keeps libadwaita's
|
|
/// default.
|
|
/// - onClick: Runs when the action button is clicked. The
|
|
/// `::button-clicked` handler is owned by the toast and released with it,
|
|
/// so there is nothing to unregister - but avoid capturing the toast
|
|
/// itself, which would keep it alive forever.
|
|
public convenience init(
|
|
title: String,
|
|
timeout: Duration? = nil,
|
|
priority: ToastPriority? = nil,
|
|
buttonLabel: String? = nil,
|
|
useMarkup: Bool? = nil,
|
|
_ onClick: @escaping () -> Void
|
|
) {
|
|
self.init(title: title)
|
|
if let timeout { setTimeout(timeout: toastTimeoutSeconds(timeout)) }
|
|
if let priority { setPriority(priority: priority) }
|
|
if let buttonLabel { setButtonLabel(buttonLabel: buttonLabel) }
|
|
if let useMarkup { setUseMarkup(useMarkup: useMarkup) }
|
|
_ = connectButtonClicked { _ in onClick() }
|
|
}
|
|
}
|