// // AdwaitaAboutDialogConfig.swift // Adwaita // // Created by lambdaclan on 09.01.2026. // import CAdw import Foundation /// A link shown in the About dialog. public struct AboutLink { /// The link title. public var title: String /// The destination URL. public var url: URL? /// Create a new link. /// - Parameters: /// - title: The link title. /// - url: The destination URL. public init(title: String, url: URL?) { self.title = title self.url = url } } /// The type of contribution made by a credited person. public enum ContributionRole { /// A person who contributed to development. case developer /// A person who contributed to design. case designer /// A person who contributed artwork or visuals. case artist /// A person who contributed translations. case translator } /// A credited person and their contribution role. public struct CreditEntry { /// The contributor's role. public var role: ContributionRole /// The contributor's name. public var name: String /// Create a new credit entry. /// - Parameters: /// - role: The contributor's role. /// - name: The contributor's name. public init(role: ContributionRole, name: String) { self.role = role self.name = name } } /// An acknowledgement entry. public struct AcknowledgementEntry { /// The acknowledgement section title. public var title: String /// Acknowledged person/organization name. public var name: String /// Create a new acknowledgement entry. /// - Parameters: /// - title: The acknowledgement section title. /// - name: The acknowledged person or organization. public init(title: String, name: String) { self.title = title self.name = name } } /// Other (additional) application entry. public struct OtherAppEntry { /// The application identifier of the referenced app. public var appID: String /// The display name of the referenced app. public var name: String /// A short descriptive summary of the referenced app. public var summary: String /// Creates a new other application entry. /// - Parameters: /// - appID: The application identifier of the referenced app. /// - name: The display name of the referenced app. /// - summary: A short descriptive summary of the referenced app. public init(appID: String, name: String, summary: String) { self.appID = appID self.name = name self.summary = summary } } /// Initialization options for the about dialog wrapper. public struct AdwaitaAboutDialogConfig { /// The app's name. public var appName: String? /// The developer's name. public var developer: String? /// The app version. public var version: String? /// The app icon. public var icon: Icon? /// The app's website. public var website: URL? /// The link for opening issues. public var issues: URL? /// The link for getting support. public var support: URL? /// Additional links related to the app. public var links: [AboutLink]? /// The app's copyright information. public var copyright: String? /// The app's license. public var license: String? /// The app's release notes. public var releaseNotes: String? /// The comments about the application. public var comments: String? /// Recognition by name and role of contributors. public var credits: [CreditEntry]? /// Acknowledgements to display in the dialog. public var acknowledgements: [AcknowledgementEntry]? /// Additional applications. public var otherApps: [OtherAppEntry]? /// Initialize the about dialog wrapper. /// - Parameters: /// - appName: The app's name. /// - developer: The developer's name. /// - version: The version string. /// - icon: The app icon. /// - website: The app's website. /// - issues: Website for reporting issues. /// - support: Website for getting support. /// - links: Additional links related to the app. /// - copyright: The app's copyright information. /// - license: The app's license. /// - releaseNotes: The app's release notes. /// - comments: The comments about the application. /// - credits: Recognition by name and role of contributors. /// - acknowledgements: List of acknowledgements. /// - otherApps: List of other applications. public init( appName: String? = nil, developer: String? = nil, version: String? = nil, icon: Icon? = nil, website: URL? = nil, issues: URL? = nil, support: URL? = nil, links: [AboutLink]? = nil, copyright: String? = nil, license: String? = nil, releaseNotes: String? = nil, comments: String? = nil, credits: [CreditEntry]? = nil, acknowledgements: [AcknowledgementEntry]? = nil, otherApps: [OtherAppEntry]? = nil ) { self.appName = appName self.developer = developer self.version = version self.icon = icon self.website = website self.issues = issues self.support = support self.links = links self.copyright = copyright self.license = license self.releaseNotes = releaseNotes self.comments = comments self.credits = credits self.acknowledgements = acknowledgements self.otherApps = otherApps } /// Applies a string value to the dialog using the given setter. /// - Parameters: /// - value: The optional string to apply. /// - setter: The C function that sets the value on the dialog. /// - dialog: The dialog instance. @inline(__always) private func set( _ value: String?, using setter: (OpaquePointer, UnsafePointer?) -> Void, on dialog: OpaquePointer ) { guard let value else { return } setter(dialog, value) } /// Applies a list of links to the dialog. /// - Parameters: /// - links: The optional list of links. /// - dialog: The dialog instance. @inline(__always) private func set( _ links: [AboutLink]?, on dialog: OpaquePointer ) { links?.forEach { link in adw_about_dialog_add_link(dialog, link.title, link.url?.absoluteString) } } /// Applies credit entries to the dialog. /// - Parameters: /// - credits: The optional list of credit entries. /// - dialog: The dialog instance. @inline(__always) private func set(_ credits: [CreditEntry]?, on dialog: OpaquePointer) { guard let credits else { return } let grouped = Dictionary(grouping: credits, by: \.role) if let devs = grouped[.developer]?.map(\.name), let ptr = devs.cMutableArray { adw_about_dialog_set_developers(dialog, ptr) } if let designers = grouped[.designer]?.map(\.name), let ptr = designers.cMutableArray { adw_about_dialog_set_designers(dialog, ptr) } if let artists = grouped[.artist]?.map(\.name), let ptr = artists.cMutableArray { adw_about_dialog_set_artists(dialog, ptr) } if let translators = grouped[.translator]?.map(\.name), !translators.isEmpty { let joined = translators.joined(separator: "\n") adw_about_dialog_set_translator_credits(dialog, joined) } } /// Applies acknowledgement entries to the dialog. /// - Parameters: /// - acknowledgements: The optional list of acknowledgement entries. /// - dialog: The dialog instance. @inline(__always) private func set( _ acknowledgements: [AcknowledgementEntry]?, on dialog: OpaquePointer ) { guard let acknowledgements else { return } let grouped = Dictionary(grouping: acknowledgements) { $0.title } for (title, entries) in grouped { let names = entries.map { $0.name } guard let people = names.cMutableArray else { continue } adw_about_dialog_add_acknowledgement_section(dialog, title, people) } } /// Applies other apps entries to the dialog. /// - Parameters: /// - otherApps: The optional list of other app entries. /// - dialog: The dialog instance. @inline(__always) private func set( _ otherApps: [OtherAppEntry]?, on dialog: OpaquePointer ) { guard let otherApps else { return } for entry in otherApps { adw_about_dialog_add_other_app( dialog, entry.appID, entry.name, entry.summary ) } } /// Apply the configuration values to the given dialog. /// - Parameters: /// - dialog: The underlying Adwaita dialog instance to update with the configuration. func apply(to dialog: OpaquePointer) { set(appName, using: adw_about_dialog_set_application_name, on: dialog) set(developer, using: adw_about_dialog_set_developer_name, on: dialog) set(version, using: adw_about_dialog_set_version, on: dialog) set(icon?.string, using: adw_about_dialog_set_application_icon, on: dialog) set(website?.absoluteString, using: adw_about_dialog_set_website, on: dialog) set(issues?.absoluteString, using: adw_about_dialog_set_issue_url, on: dialog) set(support?.absoluteString, using: adw_about_dialog_set_support_url, on: dialog) set(copyright, using: adw_about_dialog_set_copyright, on: dialog) set(license, using: adw_about_dialog_set_license, on: dialog) set(releaseNotes, using: adw_about_dialog_set_release_notes, on: dialog) set(comments, using: adw_about_dialog_set_comments, on: dialog) set(links, on: dialog) set(credits, on: dialog) set(acknowledgements, on: dialog) set(otherApps, on: dialog) } }