// // AboutDialog.swift // Adwaita // // Created by david-swift on 21.03.24. // import CAdw import Foundation /// The about dialog widget. struct AboutDialog: AdwaitaWidget { /// Whether the dialog is visible. @Binding var visible: Bool /// The wrapped view. var child: AnyView /// The dialog configuration options. var config: AdwaitaAboutDialogConfig /// The ID for the dialog's storage. let dialogID = "dialog" /// Initialize the about dialog wrapper. /// - Parameters: /// - visible: The visibility. /// - child: The child view. /// - configure: A closure that mutates the dialog configuration. init( visible: Binding, child: AnyView, configure: (inout AdwaitaAboutDialogConfig) -> Void ) { self._visible = visible self.child = child var cfg = AdwaitaAboutDialogConfig() configure(&cfg) self.config = cfg } /// The view storage. /// - Parameters: /// - modifiers: Modify views before being updated. /// - type: The view render data type. /// - Returns: The view storage. func container(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData { let storage = child.storage(data: data, type: type) update(storage, data: data, updateProperties: true, type: type) return storage } /// Update the stored content. /// - Parameters: /// - storage: The storage to update. /// - modifiers: Modify views before being updated /// - updateProperties: Whether to update the view's properties. /// - type: The view render data type. func update( _ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type ) where Data: ViewRenderData { child.updateStorage(storage, data: data, updateProperties: updateProperties, type: type) guard updateProperties else { return } if visible { if storage.content[dialogID]?.first == nil { createDialog(storage: storage) adw_dialog_present( storage.content[dialogID]?.first?.opaquePointer?.cast(), storage.opaquePointer?.cast() ) } guard let dialog = storage.content[dialogID]?.first?.opaquePointer else { return } config.apply(to: dialog) adw_dialog_set_content_height(dialog.cast(), -1) } else { if storage.content[dialogID]?.first != nil { let dialog = storage.content[dialogID]?.first?.opaquePointer adw_dialog_close(dialog?.cast()) storage.content[dialogID] = [] } } } /// Create a new instance of the dialog. /// - Parameter storage: The wrapped view's storage. func createDialog(storage: ViewStorage) { let pointer = adw_about_dialog_new() let dialog = ViewStorage(pointer?.opaque()) storage.content[dialogID] = [dialog] dialog.connectSignal(name: "closed") { storage.content[dialogID] = [] if visible { visible = false } } } }