diff --git a/Sources/Adwaita/Model/AdwaitaAboutDialogConfig.swift b/Sources/Adwaita/Model/AdwaitaAboutDialogConfig.swift
index 0678104..25710c3 100644
--- a/Sources/Adwaita/Model/AdwaitaAboutDialogConfig.swift
+++ b/Sources/Adwaita/Model/AdwaitaAboutDialogConfig.swift
@@ -82,64 +82,34 @@ public struct AcknowledgementEntry {
}
+/// 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 {
- /// Example HTML release notes used for demonstrating how the About dialog
- /// renders structured content such as paragraphs, lists, and inline markup.
- /// This sample is intended for testing, previews, and documentation.
- public static let demoReleaseNotes = """
-
This template supports three structures: paragraphs using <p>, ordered lists using
- <ol>, and unordered lists using <ul>.
- Both list types must contain list items marked with <li>.
- Within paragraphs and list items, you may use <em> to apply
- emphasis(italic text) and <code> to mark inline code
- for monospaced text.
- These inline styles are supported only inside those elements.
- Any text placed outside <p>, <ol>,
- <ul>, or <li> tags is ignored by the template
- processor.
-
- - Ordered list items represent numbered content and may
- include
<em> for emphasis or <code> for inline code.
- - They follow the same rules as paragraphs regarding allowed inline styles.
-
-
- - Unordered list items represent bullet points and support the same inline styles.
- - They must contain only text and allowed inline formatting.
-
- """
-
- /// Example Pango‑markup comments showcasing how styled text, links, and
- /// formatting behave inside the About dialog’s “Details” section.
- /// Useful for previews, testing, and as a reference for developers who want
- /// to embed formatted text in their own dialogs.
- public static let demoComments = """
- This text demonstrates basic Pango markup along with helpful documentation links.
-
- Comments shown in an Adwaita AboutDialog will appear on the Details page.
- They can be long and detailed, and they may include links and Pango markup for
- formatting.
-
- Pango markup supports tags like:
- • bold
- • italic
- • colored text
-
- Full reference: Pango Markup
- Reference
-
- Example markup:
- Demo Title
- Highlighted text
- Underlined text
-
- Useful links:
- • Adwaita‑Swift Documentation
-
- You can embed these links directly in your UI using Pango markup.
- """
-
/// The app's name.
public var appName: String?
/// The developer's name.
@@ -168,6 +138,8 @@ public struct AdwaitaAboutDialogConfig {
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:
@@ -185,6 +157,7 @@ public struct AdwaitaAboutDialogConfig {
/// - 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,
@@ -199,7 +172,8 @@ public struct AdwaitaAboutDialogConfig {
releaseNotes: String? = nil,
comments: String? = nil,
credits: [CreditEntry]? = nil,
- acknowledgements: [AcknowledgementEntry]? = nil
+ acknowledgements: [AcknowledgementEntry]? = nil,
+ otherApps: [OtherAppEntry]? = nil
) {
self.appName = appName
self.developer = developer
@@ -215,6 +189,7 @@ public struct AdwaitaAboutDialogConfig {
self.comments = comments
self.credits = credits
self.acknowledgements = acknowledgements
+ self.otherApps = otherApps
}
/// Applies a string value to the dialog using the given setter.
@@ -228,9 +203,11 @@ public struct AdwaitaAboutDialogConfig {
using setter: (OpaquePointer, UnsafePointer?) -> Void,
on dialog: OpaquePointer
) {
- if let value {
- setter(dialog, value)
+ guard let value else {
+ return
}
+
+ setter(dialog, value)
}
/// Applies a list of links to the dialog.
@@ -252,45 +229,32 @@ public struct AdwaitaAboutDialogConfig {
/// - credits: The optional list of credit entries.
/// - dialog: The dialog instance.
@inline(__always)
- private func set(
- _ credits: [CreditEntry]?,
- on dialog: OpaquePointer
- ) {
- if let credits {
- var developers: [String] = []
- var designers: [String] = []
- var artists: [String] = []
- var translators: [String] = []
+ private func set(_ credits: [CreditEntry]?, on dialog: OpaquePointer) {
+ guard let credits else {
+ return
+ }
- for entry in credits {
- switch entry.role {
- case .developer:
- developers.append(entry.name)
- case .designer:
- designers.append(entry.name)
- case .artist:
- artists.append(entry.name)
- case .translator:
- translators.append(entry.name)
- }
- }
+ let grouped = Dictionary(grouping: credits, by: \.role)
- if let ptr = developers.cMutableArray, !developers.isEmpty {
- adw_about_dialog_set_developers(dialog, ptr)
- }
+ if let devs = grouped[.developer]?.map(\.name),
+ let ptr = devs.cMutableArray {
+ adw_about_dialog_set_developers(dialog, ptr)
+ }
- if let ptr = designers.cMutableArray, !designers.isEmpty {
- adw_about_dialog_set_designers(dialog, ptr)
- }
+ if let designers = grouped[.designer]?.map(\.name),
+ let ptr = designers.cMutableArray {
+ adw_about_dialog_set_designers(dialog, ptr)
+ }
- if let ptr = artists.cMutableArray, !artists.isEmpty {
- adw_about_dialog_set_artists(dialog, ptr)
- }
+ if let artists = grouped[.artist]?.map(\.name),
+ let ptr = artists.cMutableArray {
+ adw_about_dialog_set_artists(dialog, ptr)
+ }
- if !translators.isEmpty {
- let joined = translators.joined(separator: "\n")
- adw_about_dialog_set_translator_credits(dialog, joined)
- }
+ if let translators = grouped[.translator]?.map(\.name),
+ !translators.isEmpty {
+ let joined = translators.joined(separator: "\n")
+ adw_about_dialog_set_translator_credits(dialog, joined)
}
}
@@ -303,18 +267,43 @@ public struct AdwaitaAboutDialogConfig {
_ acknowledgements: [AcknowledgementEntry]?,
on dialog: OpaquePointer
) {
- if let acknowledgements {
- let grouped = Dictionary(grouping: acknowledgements) { $0.title }
+ guard let acknowledgements else {
+ return
+ }
- for (title, entries) in grouped {
- let names = entries.map { $0.name }
- guard let people = names.cMutableArray else { continue }
+ let grouped = Dictionary(grouping: acknowledgements) { $0.title }
- adw_about_dialog_add_acknowledgement_section(dialog, title, people)
- }
+ 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.
@@ -333,6 +322,7 @@ public struct AdwaitaAboutDialogConfig {
set(links, on: dialog)
set(credits, on: dialog)
set(acknowledgements, on: dialog)
+ set(otherApps, on: dialog)
}
}