// // ToastOverlay+.swift // Adwaita // // Created by david-swift on 21.01.24. // import CAdw import Foundation /// A wrapper around a view presenting toasts. extension ToastOverlay { /// Initialize a toast overlay. /// - Parameters: /// - title: The toast's title. /// - signal: The signal for adding a toast. public init(_ title: String, signal: Signal) { updateFunctions.append { storage, _, _ in if signal.update { let toast = ViewStorage(adw_toast_new(title)) storage.fields[UUID().uuidString] = toast if let button = storage.fields["button"] as? String, let handler = storage.fields["handler"] as? () -> Void { adw_toast_set_button_label(toast.opaquePointer, button) toast.connectSignal(name: "button-clicked", handler: handler) } adw_toast_overlay_add_toast(storage.opaquePointer, toast.opaquePointer) } } } /// Add an action button to the toast. /// - Parameters: /// - button: The button's label. /// - handler: The handler. /// - Returns: The toast overlay. public func action(button: String, handler: @escaping () -> Void) -> Self { var newSelf = self let action: (ViewStorage, WidgetData, Bool) -> Void = { storage, _, _ in storage.fields["button"] = button storage.fields["handler"] = handler } newSelf.updateFunctions.insert(action, at: 0) return newSelf } } extension AnyView { /// Present a toast when the signal gets activated. /// - Parameters: /// - title: The title of the toast. /// - signal: The signal which activates the presentation of a toast. /// - Returns: A view. public func toast(_ title: String, signal: Signal) -> ToastOverlay { .init(title, signal: signal) .child { self } } /// Present a toast with a button when the signal gets activated. /// - Parameters: /// - title: The title of the toast. /// - signal: The signal which activates the presentation of a toast. /// - button: The button's label. /// - handler: The handler for the button. /// - Returns: A view. public func toast(_ title: String, signal: Signal, button: String, handler: @escaping () -> Void) -> ToastOverlay { .init(title, signal: signal) .child { self } .action(button: button, handler: handler) } }