forked from aparoksha/adwaita-swift
Compare commits
No commits in common. "9cb8ca266d93494aa7801773b3e5a5cddb7a37b2" and "9597c57b394eb5b5775faa1c366fb487a583658d" have entirely different histories.
9cb8ca266d
...
9597c57b39
@ -12,15 +12,30 @@ extension AnyView {
|
|||||||
/// Add an about dialog to the parent window.
|
/// Add an about dialog to the parent window.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - visible: Whether the dialog is presented.
|
/// - visible: Whether the dialog is presented.
|
||||||
/// - configure: A closure that mutates the dialog configuration.
|
/// - app: 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.
|
||||||
public func aboutDialog(
|
public func aboutDialog(
|
||||||
visible: Binding<Bool>,
|
visible: Binding<Bool>,
|
||||||
configure: (inout AdwaitaAboutDialogConfig) -> Void
|
app: String? = nil,
|
||||||
|
developer: String? = nil,
|
||||||
|
version: String? = nil,
|
||||||
|
icon: Icon? = nil,
|
||||||
|
website: URL? = nil,
|
||||||
|
issues: URL? = nil
|
||||||
) -> AnyView {
|
) -> AnyView {
|
||||||
AboutDialog(
|
AboutDialog(
|
||||||
visible: visible,
|
visible: visible,
|
||||||
child: self,
|
child: self,
|
||||||
configure: configure
|
appName: app,
|
||||||
|
developer: developer,
|
||||||
|
version: version,
|
||||||
|
icon: icon,
|
||||||
|
website: website,
|
||||||
|
issues: issues
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,136 +0,0 @@
|
|||||||
//
|
|
||||||
// AdwaitaAboutDialogConfig.swift
|
|
||||||
// Adwaita
|
|
||||||
//
|
|
||||||
// Created by lambdaclan on 09.01.2026.
|
|
||||||
//
|
|
||||||
|
|
||||||
import CAdw
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
/// 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 = """
|
|
||||||
<p>This template supports three structures: paragraphs using <code><p></code>, ordered lists using
|
|
||||||
<code><ol></code>, and unordered lists using <code><ul></code>.
|
|
||||||
Both list types must contain list items marked with <code><li></code>.</p>
|
|
||||||
<p>Within paragraphs and list items, you may use <code><em></code> to apply
|
|
||||||
<em>emphasis</em>(italic text) and <code><code></code> to mark <code>inline code</code>
|
|
||||||
for monospaced text.
|
|
||||||
These inline styles are supported only inside those elements.</p>
|
|
||||||
<p>Any text placed outside <code><p></code>, <code><ol></code>,
|
|
||||||
<code><ul></code>, or <code><li></code> tags is ignored by the template
|
|
||||||
processor.</p>
|
|
||||||
<ol>
|
|
||||||
<li>Ordered list items represent numbered content and may
|
|
||||||
include <code><em></code> for <em>emphasis</em> or <code><code></code> for inline code.</li>
|
|
||||||
<li>They follow the same rules as paragraphs regarding allowed inline styles.</li>
|
|
||||||
</ol>
|
|
||||||
<ul>
|
|
||||||
<li>Unordered list items represent bullet points and support the same inline styles.</li>
|
|
||||||
<li>They must contain only text and allowed inline formatting.</li>
|
|
||||||
</ul>
|
|
||||||
"""
|
|
||||||
|
|
||||||
/// 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:
|
|
||||||
• <b>bold</b>
|
|
||||||
• <i>italic</i>
|
|
||||||
• <span foreground="steelblue">colored text</span>
|
|
||||||
|
|
||||||
Full reference: <a href="https://docs.gtk.org/Pango/pango_markup.html">Pango Markup
|
|
||||||
Reference</a>
|
|
||||||
|
|
||||||
Example markup:
|
|
||||||
<span font="14pt" weight="bold">Demo Title</span>
|
|
||||||
<span foreground="tomato">Highlighted text</span>
|
|
||||||
<u>Underlined text</u>
|
|
||||||
|
|
||||||
Useful links:
|
|
||||||
• <a href="https://adwaita-swift.aparoksha.dev/documentation/adwaita">Adwaita‑Swift Documentation</a>
|
|
||||||
|
|
||||||
You can embed these links directly in your UI using Pango markup.
|
|
||||||
"""
|
|
||||||
|
|
||||||
/// 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 app's release notes
|
|
||||||
public var releaseNotes: String?
|
|
||||||
/// The comments about the application
|
|
||||||
public var comments: String?
|
|
||||||
|
|
||||||
/// 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.
|
|
||||||
/// - releaseNotes: The app's release notes.
|
|
||||||
/// - comments: The comments about the application.
|
|
||||||
public init(
|
|
||||||
appName: String? = nil,
|
|
||||||
developer: String? = nil,
|
|
||||||
version: String? = nil,
|
|
||||||
icon: Icon? = nil,
|
|
||||||
website: URL? = nil,
|
|
||||||
issues: URL? = nil,
|
|
||||||
releaseNotes: String? = nil,
|
|
||||||
comments: String? = nil
|
|
||||||
) {
|
|
||||||
self.appName = appName
|
|
||||||
self.developer = developer
|
|
||||||
self.version = version
|
|
||||||
self.icon = icon
|
|
||||||
self.website = website
|
|
||||||
self.issues = issues
|
|
||||||
self.releaseNotes = releaseNotes
|
|
||||||
self.comments = comments
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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) {
|
|
||||||
let handlers: [(String?, (OpaquePointer, UnsafePointer<CChar>?) -> Void)] = [
|
|
||||||
(appName, adw_about_dialog_set_application_name),
|
|
||||||
(developer, adw_about_dialog_set_developer_name),
|
|
||||||
(version, adw_about_dialog_set_version),
|
|
||||||
(icon?.string, adw_about_dialog_set_application_icon),
|
|
||||||
(website?.absoluteString, adw_about_dialog_set_website),
|
|
||||||
(issues?.absoluteString, adw_about_dialog_set_issue_url),
|
|
||||||
(releaseNotes, adw_about_dialog_set_release_notes),
|
|
||||||
(comments, adw_about_dialog_set_comments)
|
|
||||||
]
|
|
||||||
|
|
||||||
for (value, action) in handlers {
|
|
||||||
value.map { action(dialog, $0) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -15,8 +15,19 @@ struct AboutDialog: AdwaitaWidget {
|
|||||||
@Binding var visible: Bool
|
@Binding var visible: Bool
|
||||||
/// The wrapped view.
|
/// The wrapped view.
|
||||||
var child: AnyView
|
var child: AnyView
|
||||||
/// The dialog configuration options.
|
|
||||||
var config: AdwaitaAboutDialogConfig
|
/// The app's name.
|
||||||
|
var appName: String?
|
||||||
|
/// The developer's name.
|
||||||
|
var developer: String?
|
||||||
|
/// The app version.
|
||||||
|
var version: String?
|
||||||
|
/// The app icon.
|
||||||
|
var icon: Icon?
|
||||||
|
/// The app's website.
|
||||||
|
var website: URL?
|
||||||
|
/// The link for opening issues.
|
||||||
|
var issues: URL?
|
||||||
|
|
||||||
/// The ID for the dialog's storage.
|
/// The ID for the dialog's storage.
|
||||||
let dialogID = "dialog"
|
let dialogID = "dialog"
|
||||||
@ -25,18 +36,30 @@ struct AboutDialog: AdwaitaWidget {
|
|||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - visible: The visibility.
|
/// - visible: The visibility.
|
||||||
/// - child: The child view.
|
/// - child: The child view.
|
||||||
/// - configure: A closure that mutates the dialog configuration.
|
/// - appName: The app's name.
|
||||||
|
/// - developer: The developer's name.
|
||||||
|
/// - version: The version.
|
||||||
|
/// - icon: The icon.
|
||||||
|
/// - website: The website's URL.
|
||||||
|
/// - issues: The link for opening issues.
|
||||||
init(
|
init(
|
||||||
visible: Binding<Bool>,
|
visible: Binding<Bool>,
|
||||||
child: AnyView,
|
child: AnyView,
|
||||||
configure: (inout AdwaitaAboutDialogConfig) -> Void
|
appName: String? = nil,
|
||||||
|
developer: String? = nil,
|
||||||
|
version: String? = nil,
|
||||||
|
icon: Icon? = nil,
|
||||||
|
website: URL? = nil,
|
||||||
|
issues: URL? = nil
|
||||||
) {
|
) {
|
||||||
self._visible = visible
|
self._visible = visible
|
||||||
self.child = child
|
self.child = child
|
||||||
|
self.appName = appName
|
||||||
var cfg = AdwaitaAboutDialogConfig()
|
self.developer = developer
|
||||||
configure(&cfg)
|
self.version = version
|
||||||
self.config = cfg
|
self.icon = icon
|
||||||
|
self.website = website
|
||||||
|
self.issues = issues
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The view storage.
|
/// The view storage.
|
||||||
@ -74,12 +97,26 @@ struct AboutDialog: AdwaitaWidget {
|
|||||||
storage.opaquePointer?.cast()
|
storage.opaquePointer?.cast()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
guard let dialog = storage.content[dialogID]?.first?.opaquePointer else {
|
let dialog = storage.content[dialogID]?.first?.opaquePointer
|
||||||
return
|
if let appName {
|
||||||
|
adw_about_dialog_set_application_name(dialog, appName)
|
||||||
}
|
}
|
||||||
config.apply(to: dialog)
|
if let developer {
|
||||||
|
adw_about_dialog_set_developer_name(dialog, developer)
|
||||||
adw_dialog_set_content_height(dialog.cast(), -1)
|
}
|
||||||
|
if let version {
|
||||||
|
adw_about_dialog_set_version(dialog, version)
|
||||||
|
}
|
||||||
|
if let icon {
|
||||||
|
adw_about_dialog_set_application_icon(dialog, icon.string)
|
||||||
|
}
|
||||||
|
if let website {
|
||||||
|
adw_about_dialog_set_website(dialog, website.absoluteString)
|
||||||
|
}
|
||||||
|
if let issues {
|
||||||
|
adw_about_dialog_set_issue_url(dialog, issues.absoluteString)
|
||||||
|
}
|
||||||
|
adw_dialog_set_content_height(dialog?.cast(), -1)
|
||||||
} else {
|
} else {
|
||||||
if storage.content[dialogID]?.first != nil {
|
if storage.content[dialogID]?.first != nil {
|
||||||
let dialog = storage.content[dialogID]?.first?.opaquePointer
|
let dialog = storage.content[dialogID]?.first?.opaquePointer
|
||||||
|
|||||||
@ -150,16 +150,15 @@ struct Demo: App {
|
|||||||
}
|
}
|
||||||
.collapsed(!wide)
|
.collapsed(!wide)
|
||||||
.breakpoint(minWidth: 550, matches: $wide)
|
.breakpoint(minWidth: 550, matches: $wide)
|
||||||
.aboutDialog(visible: $about) { cfg in
|
.aboutDialog(
|
||||||
cfg.appName = "Demo"
|
visible: $about,
|
||||||
cfg.developer = "david-swift"
|
app: "Demo",
|
||||||
cfg.version = "Test"
|
developer: "david-swift",
|
||||||
cfg.icon = .default(icon: .applicationXExecutable)
|
version: "Test",
|
||||||
cfg.website = URL(string: "https://adwaita-swift.aparoksha.dev/")
|
icon: .default(icon: .applicationXExecutable),
|
||||||
cfg.issues = URL(string: "https://git.aparoksha.dev/aparoksha/adwaita-swift/issues")
|
website: .init(string: "https://adwaita-swift.aparoksha.dev/"),
|
||||||
cfg.releaseNotes = AdwaitaAboutDialogConfig.demoReleaseNotes
|
issues: .init(string: "https://git.aparoksha.dev/aparoksha/adwaita-swift/issues")
|
||||||
cfg.comments = AdwaitaAboutDialogConfig.demoComments
|
)
|
||||||
}
|
|
||||||
.preferencesDialog(visible: $preferences)
|
.preferencesDialog(visible: $preferences)
|
||||||
.preferencesPage("Page 1", icon: .default(icon: .audioHeadset)) { page in
|
.preferencesPage("Page 1", icon: .default(icon: .audioHeadset)) { page in
|
||||||
page
|
page
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user