Compare commits

..

14 Commits

87 changed files with 1067 additions and 995 deletions

7
.swiftformat Normal file
View File

@ -0,0 +1,7 @@
--exclude **/Generated
--type-blank-lines insert
--self init-only
--empty-braces spaced
--extension-acl on-declarations
--trailing-commas never
--disable indent

View File

@ -1,4 +1,4 @@
// swift-tools-version: 6.1
// swift-tools-version: 6.0
//
// Package.swift
// Adwaita
@ -8,25 +8,10 @@
import PackageDescription
/// The dependencies.
var dependencies: [Package.Dependency] = [
.package(url: "https://git.aparoksha.dev/aparoksha/meta", branch: "main"),
.package(url: "https://git.aparoksha.dev/aparoksha/meta-sqlite", branch: "main"),
.package(
url: "https://git.aparoksha.dev/aparoksha/levenshtein-transformations",
branch: "main"
),
.package(url: "https://github.com/CoreOffice/XMLCoder", from: "0.17.1")
]
#if os(Linux)
dependencies.append(.package(url: "https://github.com/stephencelis/CSQLite", from: "3.50.4"))
#endif
/// The Adwaita package.
let package = Package(
name: "Adwaita",
platforms: [.macOS(.v13), .iOS(.v13), .tvOS(.v13), .watchOS(.v6), .macCatalyst(.v13)],
platforms: [.macOS(.v10_15), .iOS(.v13), .tvOS(.v13), .watchOS(.v6), .macCatalyst(.v13)],
products: [
.library(
name: "Adwaita",
@ -37,8 +22,15 @@ let package = Package(
targets: ["CAdw"]
)
],
traits: [.trait(name: "exposeGeneratedAppearUpdateFunctions")],
dependencies: dependencies,
dependencies: [
.package(url: "https://git.aparoksha.dev/aparoksha/meta", branch: "main"),
.package(url: "https://git.aparoksha.dev/aparoksha/meta-sqlite", from: "0.1.0"),
.package(
url: "https://git.aparoksha.dev/aparoksha/levenshtein-transformations",
branch: "main"
),
.package(url: "https://github.com/CoreOffice/XMLCoder", from: "0.17.1")
],
targets: [
.systemLibrary(
name: "CAdw",

View File

@ -5,7 +5,6 @@
// Created by david-swift on 16.10.24.
//
import CAdw
import Foundation
extension AnyView {
@ -13,30 +12,15 @@ extension AnyView {
/// Add an about dialog to the parent window.
/// - Parameters:
/// - visible: Whether the dialog is presented.
/// - 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.
/// - configure: A closure that mutates the dialog configuration.
public func aboutDialog(
visible: Binding<Bool>,
app: String? = nil,
developer: String? = nil,
version: String? = nil,
icon: Icon? = nil,
website: URL? = nil,
issues: URL? = nil
configure: (inout AdwaitaAboutDialogConfig) -> Void
) -> AnyView {
AboutDialog(
visible: visible,
child: self,
appName: app,
developer: developer,
version: version,
icon: icon,
website: website,
issues: issues
configure: configure
)
}
@ -244,6 +228,90 @@ extension AnyView {
.maximumSize(maxHeight ?? -1)
}
/// Add padding around a view.
/// - Parameters:
/// - padding: The size of the padding.
/// - edges: The edges which are affected by the padding.
/// - Returns: A view.
public func padding(_ padding: Int = 10, _ edges: Set<Edge> = .all) -> AnyView {
ModifierWrapper(content: self, padding: padding, edges: edges)
}
/// Add a padding of 10 around a view.
/// - Parameters:
/// - edges: The edges which are affected by the padding.
/// - Returns: A view.
public func padding(_ edges: Set<Edge> = .all) -> AnyView {
padding(10, edges)
}
/// Enable or disable the horizontal expansion.
/// - Parameter enabled: Whether it is enabled or disabled.
/// - Returns: A view.
public func hexpand(_ enabled: Bool = true) -> AnyView {
ModifierWrapper(content: self, hexpand: enabled)
}
/// Enable or disable the vertical expansion.
/// - Parameter enabled: Whether it is enabled or disabled.
/// - Returns: A view.
public func vexpand(_ enabled: Bool = true) -> AnyView {
ModifierWrapper(content: self, vexpand: enabled)
}
/// Set the horizontal alignment.
/// - Parameter align: The alignment.
/// - Returns: A view.
public func halign(_ align: Alignment) -> AnyView {
ModifierWrapper(content: self, halign: align)
}
/// Set the vertical alignment.
/// - Parameter align: The alignment.
/// - Returns: A view.
public func valign(_ align: Alignment) -> AnyView {
ModifierWrapper(content: self, valign: align)
}
/// Set the view's minimal width or height.
/// - Parameters:
/// - minWidth: The minimal width.
/// - minHeight: The minimal height.
/// - Returns: A view.
public func frame(minWidth: Int? = nil, minHeight: Int? = nil) -> AnyView {
ModifierWrapper(content: self, minWidth: minWidth, minHeight: minHeight)
}
/// Add a style class to the view.
/// - Parameters:
/// - style: The style class.
/// - active: Whether the style is currently applied.
/// - Returns: A view.
public func style(_ style: String, active: Bool = true) -> AnyView {
ModifierWrapper(content: self, style: style, styleActive: active)
}
/// Make the view insensitive (useful e.g. in overlays).
/// - Parameter insensitive: Whether the view is insensitive.
/// - Returns: A view.
public func insensitive(_ insensitive: Bool = true) -> AnyView {
ModifierWrapper(content: self, insensitive: insensitive)
}
/// Set the view's visibility.
/// - Parameter visible: Whether the view is visible.
/// - Returns: A view.
public func visible(_ visible: Bool = true) -> AnyView {
ModifierWrapper(content: self, visible: visible)
}
/// Add a tooltip to the widget.
/// - Parameter tooltip: The tooltip text.
/// - Returns: A view.
public func tooltip(_ tooltip: String) -> AnyView {
ModifierWrapper(content: self, tooltip: tooltip)
}
/// Present a toast when the signal gets activated.
/// - Parameters:
/// - title: The title of the toast.
@ -299,6 +367,22 @@ extension AnyView {
BreakpointBin(condition: .minHeight(minHeight), matches: matches) { self }
}
/// Whether the view has a width higher or equal to its natural width.
/// - Parameters:
/// - matches: Whether the content view matches the breakpoint.
/// - padding: Increase the natural width by a certain padding.
public func naturalWidth(matches: Binding<Bool>, padding: Int = 0) -> AnyView {
BreakpointBin(condition: .naturalWidth(padding: padding), matches: matches) { self }
}
/// Whether the view has a height higher or equal to its natural height.
/// - Parameters:
/// - matches: Whether the content view matches the breakpoint.
/// - padding: Increase the natural height by a certain padding.
public func naturalHeight(matches: Binding<Bool>, padding: Int = 0) -> AnyView {
BreakpointBin(condition: .naturalHeight(padding: padding), matches: matches) { self }
}
/// Build the UI from scratch once the identifier changes.
/// - Parameter id: The identifier.
public func id(_ id: CustomStringConvertible) -> AnyView {

View File

@ -0,0 +1,328 @@
//
// 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<CChar>?) -> 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)
}
}

View File

@ -1,23 +0,0 @@
//
// ColorScheme.swift
// Adwaita
//
// Created by david-swift on 01.02.26.
//
import CAdw
/// The system color scheme.
public enum ColorScheme: UInt32 {
/// The dark color scheme.
case dark = 2
/// The light color scheme.
case light = 3
/// The ColorScheme value as GtkInterfaceColorScheme.
var gtkValue: GtkInterfaceColorScheme {
.init(rawValue)
}
}

View File

@ -5,11 +5,13 @@
// Created by david-swift on 06.08.23.
//
import Foundation
extension Array where Element == String {
/// Get the C version of the array.
var cArray: UnsafePointer<UnsafePointer<CChar>?>? {
let cStrings = self.map { $0.utf8CString }
let cStrings = map { $0.utf8CString }
let cStringPointers = cStrings.map { $0.withUnsafeBufferPointer { $0.baseAddress } }
let optionalCStringPointers = cStringPointers + [nil]
var optionalCStringPointersCopy = optionalCStringPointers
@ -25,4 +27,20 @@ extension Array where Element == String {
return UnsafePointer(pointer)
}
/// Get the mutable C version of the array.
var cMutableArray: UnsafeMutablePointer<UnsafePointer<CChar>?>? {
let pointer = UnsafeMutablePointer<UnsafePointer<CChar>?>.allocate(
capacity: count + 1
)
for (index, string) in enumerated() {
let cstr = strdup(string)
pointer[index] = UnsafePointer(cstr)
}
pointer[count] = nil
return pointer
}
}

View File

@ -108,13 +108,6 @@ extension AnyView {
style("circular", active: active)
}
/// Make a button or similar widget use round appearance.
/// - Parameter active: Whether the style is currently applied.
/// - Returns: A view.
public func round(_ active: Bool = true) -> AnyView {
style("round", active: active)
}
/// Make a button or similar widget appear as a pill.
/// - Parameter active: Whether the style is currently applied.
/// - Returns: A view.
@ -278,6 +271,13 @@ extension AnyView {
style("frame", active: active)
}
/// Run a function when the view gets an update.
/// - Parameter onUpdate: The function.
/// - Returns: A view.
public func onUpdate(_ onUpdate: @escaping () -> Void) -> AnyView {
inspect { _, _ in onUpdate() }
}
/// Bind to the view's focus.
/// - Parameter focus: Whether the view is focused.
/// - Returns: A view.
@ -336,21 +336,15 @@ extension AnyView {
}
/// Add CSS classes to the app as soon as the view appears.
/// - Parameters:
/// - scheme: The color scheme.
/// - getString: Get the CSS.
/// - Parameter getString: Get the CSS.
/// - Returns: A view.
public func css(scheme: ColorScheme? = nil, getString: @escaping () -> String) -> AnyView {
wrap { storage, updateProperties in
public func css(_ getString: @escaping () -> String) -> AnyView {
inspect { storage, updateProperties in
let cssID = "internal-css"
let providerID = "internal-css-provider"
let previous = storage.fields[cssID] as? String
let string = getString()
if updateProperties, string != previous {
let provider = gtk_css_provider_new()
if let scheme {
gtui_cssprovider_set_prefers_color_scheme(.init(Int(bitPattern: provider)), scheme.gtkValue)
}
gtk_css_provider_load_from_string(
provider,
string
@ -362,32 +356,8 @@ extension AnyView {
.init(GTK_STYLE_PROVIDER_PRIORITY_APPLICATION)
)
g_object_unref(provider)
storage.fields[cssID] = string
if let oldProvider = storage.fields[providerID] as? OpaquePointer {
gtk_style_context_remove_provider_for_display(
display,
oldProvider
)
}
storage.fields[providerID] = provider?.opaque()
}
}
}
/// Whether the view has a width higher or equal to its natural width.
/// - Parameters:
/// - matches: Whether the content view matches the breakpoint.
/// - padding: Increase the natural width by a certain padding.
public func naturalWidth(matches: Binding<Bool>, padding: Int = 0) -> AnyView {
BreakpointBin(condition: .naturalWidth(padding: padding), matches: matches) { self }
}
/// Whether the view has a height higher or equal to its natural height.
/// - Parameters:
/// - matches: Whether the content view matches the breakpoint.
/// - padding: Increase the natural height by a certain padding.
public func naturalHeight(matches: Binding<Bool>, padding: Int = 0) -> AnyView {
BreakpointBin(condition: .naturalHeight(padding: padding), matches: matches) { self }
}
}

View File

@ -1,123 +0,0 @@
//
// AnyView+wrapModifier.swift
// Adwaita
//
// Created by david-swift on 02.02.26.
//
import CAdw
extension AnyView {
/// Add padding around a view.
/// - Parameters:
/// - padding: The size of the padding.
/// - edges: The edges which are affected by the padding.
/// - Returns: A view.
public func padding(_ padding: Int = 10, _ edges: Set<Edge> = .all) -> AnyView {
wrapModifier(properties: [padding, edges]) { storage in
if edges.contains(.leading) { gtk_widget_set_margin_start(storage.opaquePointer?.cast(), padding.cInt) }
if edges.contains(.trailing) { gtk_widget_set_margin_end(storage.opaquePointer?.cast(), padding.cInt) }
if edges.contains(.top) { gtk_widget_set_margin_top(storage.opaquePointer?.cast(), padding.cInt) }
if edges.contains(.bottom) { gtk_widget_set_margin_bottom(storage.opaquePointer?.cast(), padding.cInt) }
}
}
/// Add a padding of 10 around a view.
/// - Parameters:
/// - edges: The edges which are affected by the padding.
/// - Returns: A view.
public func padding(_ edges: Set<Edge> = .all) -> AnyView {
padding(10, edges)
}
/// Enable or disable the horizontal expansion.
/// - Parameter enabled: Whether it is enabled or disabled.
/// - Returns: A view.
public func hexpand(_ enabled: Bool = true) -> AnyView {
wrapModifier(properties: [enabled]) { storage in
gtk_widget_set_hexpand(storage.opaquePointer?.cast(), enabled.cBool)
}
}
/// Enable or disable the vertical expansion.
/// - Parameter enabled: Whether it is enabled or disabled.
/// - Returns: A view.
public func vexpand(_ enabled: Bool = true) -> AnyView {
wrapModifier(properties: [enabled]) { storage in
gtk_widget_set_vexpand(storage.opaquePointer?.cast(), enabled.cBool)
}
}
/// Set the horizontal alignment.
/// - Parameter align: The alignment.
/// - Returns: A view.
public func halign(_ align: Alignment) -> AnyView {
wrapModifier(properties: [align]) { storage in
gtk_widget_set_halign(storage.opaquePointer?.cast(), align.cAlign)
}
}
/// Set the vertical alignment.
/// - Parameter align: The alignment.
/// - Returns: A view.
public func valign(_ align: Alignment) -> AnyView {
wrapModifier(properties: [align]) { storage in
gtk_widget_set_valign(storage.opaquePointer?.cast(), align.cAlign)
}
}
/// Set the view's minimal width or height.
/// - Parameters:
/// - minWidth: The minimal width.
/// - minHeight: The minimal height.
/// - Returns: A view.
public func frame(minWidth: Int? = nil, minHeight: Int? = nil) -> AnyView {
wrapModifier(properties: [minWidth, minHeight]) { storage in
gtk_widget_set_size_request(storage.opaquePointer?.cast(), minWidth?.cInt ?? 1, minHeight?.cInt ?? -1)
}
}
/// Add a style class to the view.
/// - Parameters:
/// - style: The style class.
/// - active: Whether the style is currently applied.
/// - Returns: A view.
public func style(_ style: String, active: Bool = true) -> AnyView {
wrapModifier(properties: [style, active]) { storage in
if active {
gtk_widget_add_css_class(storage.opaquePointer?.cast(), style)
} else {
gtk_widget_remove_css_class(storage.opaquePointer?.cast(), style)
}
}
}
/// Make the view insensitive (useful e.g. in overlays).
/// - Parameter insensitive: Whether the view is insensitive.
/// - Returns: A view.
public func insensitive(_ insensitive: Bool = true) -> AnyView {
wrapModifier(properties: [insensitive]) { storage in
gtk_widget_set_sensitive(storage.opaquePointer?.cast(), insensitive ? 0 : 1)
}
}
/// Set the view's visibility.
/// - Parameter visible: Whether the view is visible.
/// - Returns: A view.
public func visible(_ visible: Bool = true) -> AnyView {
wrapModifier(properties: [visible]) { storage in
gtk_widget_set_visible(storage.opaquePointer?.cast(), visible.cBool)
}
}
/// Add a tooltip to the widget.
/// - Parameter tooltip: The tooltip text.
/// - Returns: A view.
public func tooltip(_ tooltip: String) -> AnyView {
wrapModifier(properties: [tooltip]) { storage in
gtk_widget_set_tooltip_markup(storage.opaquePointer?.cast(), tooltip)
}
}
}

View File

@ -15,19 +15,8 @@ struct AboutDialog: AdwaitaWidget {
@Binding var visible: Bool
/// The wrapped view.
var child: AnyView
/// 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 dialog configuration options.
var config: AdwaitaAboutDialogConfig
/// The ID for the dialog's storage.
let dialogID = "dialog"
@ -36,30 +25,18 @@ struct AboutDialog: AdwaitaWidget {
/// - Parameters:
/// - visible: The visibility.
/// - child: The child view.
/// - 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.
/// - configure: A closure that mutates the dialog configuration.
init(
visible: Binding<Bool>,
child: AnyView,
appName: String? = nil,
developer: String? = nil,
version: String? = nil,
icon: Icon? = nil,
website: URL? = nil,
issues: URL? = nil
configure: (inout AdwaitaAboutDialogConfig) -> Void
) {
self._visible = visible
self.child = child
self.appName = appName
self.developer = developer
self.version = version
self.icon = icon
self.website = website
self.issues = issues
var cfg = AdwaitaAboutDialogConfig()
configure(&cfg)
self.config = cfg
}
/// The view storage.
@ -68,7 +45,9 @@ struct AboutDialog: AdwaitaWidget {
/// - type: The view render data type.
/// - Returns: The view storage.
func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
child.storage(data: data, type: type)
let storage = child.storage(data: data, type: type)
update(storage, data: data, updateProperties: true, type: type)
return storage
}
/// Update the stored content.
@ -95,26 +74,12 @@ struct AboutDialog: AdwaitaWidget {
storage.opaquePointer?.cast()
)
}
let dialog = storage.content[dialogID]?.first?.opaquePointer
if let appName {
adw_about_dialog_set_application_name(dialog, appName)
guard let dialog = storage.content[dialogID]?.first?.opaquePointer else {
return
}
if let developer {
adw_about_dialog_set_developer_name(dialog, developer)
}
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)
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

View File

@ -106,7 +106,9 @@ public struct AlertDialog: AdwaitaWidget {
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
child.storage(data: data, type: type)
let storage = child.storage(data: data, type: type)
update(storage, data: data, updateProperties: true, type: type)
return storage
}
/// Update the stored content.
@ -215,7 +217,6 @@ public struct AlertDialog: AdwaitaWidget {
storage.content[Self.dialogID + id] = [dialog]
if let extraChild {
let child = extraChild.storage(data: data, type: AdwaitaMainView.self)
extraChild.updateStorage(child, data: data, updateProperties: true, type: AdwaitaMainView.self)
let childPointer = child.pointer as? OpaquePointer
storage.content["extra-child"] = [child]
adw_alert_dialog_set_extra_child(pointer?.cast(), childPointer?.cast())

View File

@ -64,7 +64,9 @@ struct Dialog: AdwaitaWidget {
/// - Returns: The view storage.
func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
let child = child.storage(data: data, type: type)
return .init(child.opaquePointer, content: [.mainContent: [child]])
let storage = ViewStorage(child.opaquePointer, content: [.mainContent: [child]])
update(storage, data: data, updateProperties: true, type: type)
return storage
}
/// Update the stored content.
@ -130,7 +132,6 @@ struct Dialog: AdwaitaWidget {
let dialog = ViewStorage(pointer?.opaque())
storage.content[dialogID + id] = [dialog]
let contentStorage = content.storage(data: data, type: type)
content.updateStorage(contentStorage, data: data, updateProperties: true, type: type)
adw_dialog_set_child(pointer, contentStorage.opaquePointer?.cast())
storage.content[contentID + id] = [contentStorage]
dialog.connectSignal(name: "closed") {

View File

@ -105,7 +105,9 @@ struct FileDialog: AdwaitaWidget {
/// - Returns: The view storage.
func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
let child = child.storage(data: data, type: type)
return .init(child.opaquePointer, content: [.mainContent: [child]])
let storage = ViewStorage(child.opaquePointer, content: [.mainContent: [child]])
update(storage, data: data, updateProperties: true, type: type)
return storage
}
/// Update the stored content.

View File

@ -153,7 +153,9 @@ public struct PreferencesDialog: AdwaitaWidget {
/// - Returns: The view storage.
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
let child = child.storage(data: data, type: type)
return .init(child.opaquePointer, content: [.mainContent: [child]])
let storage = ViewStorage(child.opaquePointer, content: [.mainContent: [child]])
update(storage, data: data, updateProperties: true, type: type)
return storage
}
/// Update the stored content.

View File

@ -109,7 +109,9 @@ public struct ShortcutsDialog: AdwaitaWidget {
/// - Returns: The view storage.
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
let child = child.storage(data: data, type: type)
return .init(child.opaquePointer, content: [.mainContent: [child]])
let storage = ViewStorage(child.opaquePointer, content: [.mainContent: [child]])
update(storage, data: data, updateProperties: true, type: type)
return storage
}
/// Update the stored content.

View File

@ -17,40 +17,27 @@ extension DropDown {
/// Initialize a combo row.
/// - Parameters:
/// - title: The row's title.
/// - selection: The selected value.
/// - values: The available values.
public init<Element>(
selection: Binding<Element.ID>,
values: [Element]
) where Element: Identifiable, Element: CustomStringConvertible {
self.init(selection: selection, values: values, id: \.id, description: \.description)
}
/// Initialize a combo row.
/// - Parameters:
/// - title: The row's title.
/// - selection: The selected value.
/// - values: The available values.
public init<Element, Identifier>(
selection: Binding<Identifier>,
values: [Element],
id: KeyPath<Element, Identifier>,
description: KeyPath<Element, String>
) where Identifier: Equatable {
self.init()
self = self.selected(.init {
.init(values.firstIndex { $0[keyPath: id] == selection.wrappedValue } ?? 0)
.init(values.firstIndex { $0.id == selection.wrappedValue } ?? 0)
} set: { index in
if let id = values[safe: .init(index)]?[keyPath: id] {
if let id = values[safe: .init(index)]?.id {
selection.wrappedValue = id
}
})
appearFunctions.append { storage, _ in
storage.fields[Self.stringList] = gtk_drop_down_get_model(storage.opaquePointer)
Self.updateContent(storage: storage, values: values, id: id, description: description)
Self.updateContent(storage: storage, values: values, element: Element.self)
}
updateFunctions.append { storage, _, _ in
Self.updateContent(storage: storage, values: values, id: id, description: description)
Self.updateContent(storage: storage, values: values, element: Element.self)
}
}
@ -58,23 +45,20 @@ extension DropDown {
/// - Parameters:
/// - storage: The view storage.
/// - values: The elements.
/// - id: The keypath to the id.
/// - description: The keypath to the description.
static func updateContent<Element, Identifier>(
/// - element: The type of the elements.
static func updateContent<Element>(
storage: ViewStorage,
values: [Element],
id: KeyPath<Element, Identifier>,
description: KeyPath<Element, String>
) where Identifier: Equatable {
element: Element.Type
) where Element: Identifiable, Element: CustomStringConvertible {
if let list = storage.fields[Self.stringList] as? OpaquePointer {
let old = storage.fields[Self.values] as? [Element] ?? []
old.transform(
old.identifiableTransform(
to: values,
id: id,
functions: .init { index in
gtk_string_list_remove(list, .init(index))
} insert: { _, element in
gtk_string_list_append(list, element[keyPath: description])
gtk_string_list_append(list, element.description)
}
)
storage.fields[Self.values] = values

View File

@ -17,21 +17,19 @@ extension FlowBox {
/// Initialize `FlowBox`.
/// - Parameters:
/// - elements: The elements.
/// - id: The element identifier keypath.
/// - selection: The identifier of the selected element. Selection disabled if `nil`.
/// - content: The view for an element.
public init(
_ elements: [Element],
id: KeyPath<Element, Identifier>,
selection: Binding<Identifier>? = nil,
selection: Binding<Element.ID>? = nil,
@ViewBuilder content: @escaping (Element) -> Body
) {
self.init(elements, id: id, content: content)
let getID: (ViewStorage, [Element]) -> Identifier? = { storage, elements in
self.init(elements, content: content)
let id: (ViewStorage, [Element]) -> Element.ID? = { storage, elements in
if let child = g_list_nth_data(gtk_flow_box_get_selected_children(storage.opaquePointer), 0) {
let element = gtk_flow_box_child_get_child(child.cast())
return elements[safe: storage.content[.mainContent]?
.firstIndex { $0.opaquePointer?.cast() == element }]?[keyPath: id]
.firstIndex { $0.opaquePointer?.cast() == element }]?.id
}
return nil
}
@ -39,12 +37,12 @@ extension FlowBox {
updateFunctions.append { storage, _, _ in
storage.connectSignal(name: "selected_children_changed", id: Self.selectionField) {
if let elements = storage.fields[Self.elementsField] as? [Element],
let id = getID(storage, elements) {
let id = id(storage, elements) {
selection.wrappedValue = id
}
}
if selection.wrappedValue != getID(storage, elements),
let index = elements.firstIndex(where: { $0[keyPath: id] == selection.wrappedValue })?.cInt {
if selection.wrappedValue != id(storage, elements),
let index = elements.firstIndex(where: { $0.id == selection.wrappedValue })?.cInt {
gtk_flow_box_select_child(
storage.opaquePointer,
gtk_flow_box_get_child_at_index(storage.opaquePointer, index)
@ -59,20 +57,3 @@ extension FlowBox {
}
}
extension FlowBox where Element: Identifiable, Identifier == Element.ID {
/// Initialize `FlowBox`.
/// - Parameters:
/// - elements: The elements.
/// - selection: The identifier of the selected element. Selection disabled if `nil`.
/// - content: The view for an element.
public init(
_ elements: [Element],
selection: Binding<Element.ID>? = nil,
@ViewBuilder content: @escaping (Element) -> Body
) {
self.init(elements, id: \.id, selection: selection, content: content)
}
}

View File

@ -9,7 +9,7 @@ import CAdw
import LevenshteinTransformations
/// A dynamic list but without a list design in the user interface.
public struct ForEach<Element, Identifier>: AdwaitaWidget where Identifier: Equatable {
public struct ForEach<Element>: AdwaitaWidget where Element: Identifiable {
/// The dynamic widget elements.
var elements: [Element]
@ -19,20 +19,12 @@ public struct ForEach<Element, Identifier>: AdwaitaWidget where Identifier: Equa
var horizontal: Bool
/// Whether the children should all be the same size.
var homogeneous: Bool?
/// The path to the identifier.
var id: KeyPath<Element, Identifier>
/// Initialize `ForEach`.
public init(
_ elements: [Element],
id: KeyPath<Element, Identifier>,
horizontal: Bool = false,
@ViewBuilder content: @escaping (Element) -> Body
) {
public init(_ elements: [Element], horizontal: Bool = false, @ViewBuilder content: @escaping (Element) -> Body) {
self.elements = elements
self.content = content
self.horizontal = horizontal
self.id = id
}
/// The view storage.
@ -44,9 +36,11 @@ public struct ForEach<Element, Identifier>: AdwaitaWidget where Identifier: Equa
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
.init(
let storage = ViewStorage(
gtk_box_new(horizontal ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL, 0)?.opaque()
)
update(storage, data: data, updateProperties: true, type: type)
return storage
}
/// Update the stored content.
@ -64,9 +58,8 @@ public struct ForEach<Element, Identifier>: AdwaitaWidget where Identifier: Equa
var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? []
let old = storage.fields["element"] as? [Element] ?? []
let widget: UnsafeMutablePointer<GtkBox>? = storage.opaquePointer?.cast()
old.transform(
old.identifiableTransform(
to: elements,
id: id,
functions: .init { index in
let child = contentStorage[safe: index]?.opaquePointer
gtk_box_remove(widget, child?.cast())
@ -114,15 +107,3 @@ public struct ForEach<Element, Identifier>: AdwaitaWidget where Identifier: Equa
}
}
extension ForEach where Element: Identifiable, Identifier == Element.ID {
/// Initialize `ForEach`.
public init(_ elements: [Element], horizontal: Bool = false, @ViewBuilder content: @escaping (Element) -> Body) {
self.elements = elements
self.content = content
self.horizontal = horizontal
self.id = \.id
}
}

View File

@ -26,26 +26,11 @@ extension ComboRow {
selection: Binding<Element.ID>,
values: [Element]
) where Element: Identifiable, Element: CustomStringConvertible {
self.init(title, selection: selection, values: values, id: \.id, description: \.description)
}
/// Initialize a combo row.
/// - Parameters:
/// - title: The row's title.
/// - selection: The selected value.
/// - values: The available values.
public init<Element, Identifier>(
_ title: String,
selection: Binding<Identifier>,
values: [Element],
id: KeyPath<Element, Identifier>,
description: KeyPath<Element, String>
) where Identifier: Equatable {
self = self.title(title)
self = self.selected(.init {
.init(values.firstIndex { $0[keyPath: id] == selection.wrappedValue } ?? 0)
.init(values.firstIndex { $0.id == selection.wrappedValue } ?? 0)
} set: { index in
if let id = values[safe: .init(index)]?[keyPath: id] {
if let id = values[safe: .init(index)]?.id {
selection.wrappedValue = id
}
})
@ -54,10 +39,34 @@ extension ComboRow {
storage.fields[Self.stringList] = list
adw_combo_row_set_model(storage.opaquePointer?.cast(), list)
g_object_unref(list?.cast())
DropDown.updateContent(storage: storage, values: values, id: id, description: description)
Self.updateContent(storage: storage, values: values, element: Element.self)
}
updateFunctions.append { storage, _, _ in
DropDown.updateContent(storage: storage, values: values, id: id, description: description)
Self.updateContent(storage: storage, values: values, element: Element.self)
}
}
/// Update the combo row's content.
/// - Parameters:
/// - storage: The view storage.
/// - values: The elements.
/// - element: The type of the elements.
static func updateContent<Element>(
storage: ViewStorage,
values: [Element],
element: Element.Type
) where Element: Identifiable, Element: CustomStringConvertible {
if let list = storage.fields[Self.stringList] as? OpaquePointer {
let old = storage.fields[Self.values] as? [Element] ?? []
old.identifiableTransform(
to: values,
functions: .init { index in
gtk_string_list_remove(list, .init(index))
} insert: { _, element in
gtk_string_list_append(list, element.description)
}
)
storage.fields[Self.values] = values
}
}

View File

@ -15,8 +15,11 @@ public struct Form: SimpleView {
/// The view's body.
public var view: Body {
List([Int](content.indices), selection: nil) { index in content[index] }
.style("boxed-list")
ModifierWrapper(
content: List([Int](content.indices), selection: nil) { index in content[index] },
style: "boxed-list",
styleActive: true
)
}
/// Initialize a `Form`.

View File

@ -2,7 +2,7 @@
// ActionRow.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -24,17 +24,10 @@ import LevenshteinTransformations
///
public struct ActionRow: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The widget to activate when the row is activated.
///
@ -102,6 +95,7 @@ public struct ActionRow: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let activatableWidgetStorage = activatableWidget?.storage(data: data, type: type) {
storage.content["activatableWidget"] = [activatableWidgetStorage]
adw_action_row_set_activatable_widget(storage.opaquePointer?.cast(), activatableWidgetStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// AspectFrame.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -16,17 +16,10 @@ import LevenshteinTransformations
///
public struct AspectFrame: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -61,6 +54,7 @@ public struct AspectFrame: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
gtk_aspect_frame_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// Avatar.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -28,17 +28,10 @@ import LevenshteinTransformations
///
public struct Avatar: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The name of an icon to use as a fallback.
///
@ -72,6 +65,7 @@ public struct Avatar: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}

View File

@ -2,7 +2,7 @@
// Banner.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -30,17 +30,10 @@ import LevenshteinTransformations
///
public struct Banner: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The label to show on the button.
///
@ -79,6 +72,7 @@ public struct Banner: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}

View File

@ -2,7 +2,7 @@
// Bin.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -19,17 +19,10 @@ import LevenshteinTransformations
/// for handling a single child widget.
public struct Bin: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The child widget of the `AdwBin`.
var child: Body?
@ -48,6 +41,7 @@ public struct Bin: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
adw_bin_set_child(storage.opaquePointer?.cast(), childStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// Box.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -36,17 +36,10 @@ import LevenshteinTransformations
///
public struct Box: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -80,6 +73,7 @@ public struct Box: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
var appendStorage: [ViewStorage] = []
for view in append() {

View File

@ -2,7 +2,7 @@
// Button.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -19,17 +19,10 @@ import LevenshteinTransformations
///
public struct Button: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -81,6 +74,7 @@ public struct Button: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
gtk_button_set_child(storage.opaquePointer?.cast(), childStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// ButtonContent.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -28,17 +28,10 @@ import LevenshteinTransformations
///
public struct ButtonContent: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// Whether the button can be smaller than the natural size of its contents.
///
@ -73,6 +66,7 @@ public struct ButtonContent: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}

View File

@ -2,7 +2,7 @@
// Carousel.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -19,19 +19,12 @@ import LevenshteinTransformations
/// to provide page indicators for `AdwCarousel`.
///
///
public struct Carousel<Element, Identifier>: AdwaitaWidget where Identifier: Equatable {
public struct Carousel<Element>: AdwaitaWidget where Element: Identifiable {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// Whether to allow swiping for more than one page at a time.
///
@ -70,14 +63,11 @@ public struct Carousel<Element, Identifier>: AdwaitaWidget where Identifier: Equ
var elements: [Element]
/// The dynamic widget content.
var content: (Element) -> Body
/// The dynamic widget identifier key path.
var id: KeyPath<Element, Identifier>
/// Initialize `Carousel`.
public init(_ elements: [Element], id: KeyPath<Element, Identifier>, @ViewBuilder content: @escaping (Element) -> Body) {
public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) {
self.elements = elements
self.content = content
self.id = id
}
/// The view storage.
@ -90,6 +80,7 @@ public struct Carousel<Element, Identifier>: AdwaitaWidget where Identifier: Equ
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}
@ -129,9 +120,8 @@ public struct Carousel<Element, Identifier>: AdwaitaWidget where Identifier: Equ
var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? []
let old = storage.fields["element"] as? [Element] ?? []
old.transform(
old.identifiableTransform(
to: elements,
id: id,
functions: .init { index in
adw_carousel_remove(widget, adw_carousel_get_nth_page(widget, UInt(index).cInt))
contentStorage.remove(at: index)
@ -216,14 +206,3 @@ public struct Carousel<Element, Identifier>: AdwaitaWidget where Identifier: Equ
}
}
extension Carousel where Element: Identifiable, Identifier == Element.ID {
/// Initialize `Carousel`.
public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) {
self.elements = elements
self.content = content
self.id = \.id
}
}

View File

@ -2,7 +2,7 @@
// CenterBox.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -23,17 +23,10 @@ import LevenshteinTransformations
///
public struct CenterBox: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -77,6 +70,7 @@ public struct CenterBox: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let centerWidgetStorage = centerWidget?.storage(data: data, type: type) {
storage.content["centerWidget"] = [centerWidgetStorage]
gtk_center_box_set_center_widget(storage.opaquePointer, centerWidgetStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// CheckButton.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -22,17 +22,10 @@ import LevenshteinTransformations
///
public struct CheckButton: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -86,6 +79,7 @@ public struct CheckButton: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
gtk_check_button_set_child(storage.opaquePointer?.cast(), childStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// Clamp.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -28,17 +28,10 @@ import LevenshteinTransformations
///
public struct Clamp: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The child widget of the `AdwClamp`.
var child: Body?
@ -76,6 +69,7 @@ public struct Clamp: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
adw_clamp_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// ComboRow.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -32,17 +32,10 @@ import LevenshteinTransformations
///
public struct ComboRow: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The widget to activate when the row is activated.
///
@ -132,6 +125,7 @@ public struct ComboRow: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let activatableWidgetStorage = activatableWidget?.storage(data: data, type: type) {
storage.content["activatableWidget"] = [activatableWidgetStorage]
adw_action_row_set_activatable_widget(storage.opaquePointer?.cast(), activatableWidgetStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// DropDown.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -48,17 +48,10 @@ import LevenshteinTransformations
///
public struct DropDown: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -96,6 +89,7 @@ public struct DropDown: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}

View File

@ -2,7 +2,7 @@
// Entry.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -48,17 +48,10 @@ import LevenshteinTransformations
///
public struct Entry: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -286,6 +279,7 @@ public struct Entry: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let extraMenu {
let childStorage = MenuCollection { extraMenu }.getMenu(data: data)
storage.content["extraMenu"] = [childStorage]

View File

@ -2,7 +2,7 @@
// EntryRow.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -29,17 +29,10 @@ import LevenshteinTransformations
///
public struct EntryRow: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// Whether activating the embedded entry can activate the default widget.
var activatesDefault: Bool?
@ -103,6 +96,7 @@ public struct EntryRow: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
var suffixStorage: [ViewStorage] = []
for view in suffix() {

View File

@ -2,7 +2,7 @@
// ExpanderRow.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -19,17 +19,10 @@ import LevenshteinTransformations
///
public struct ExpanderRow: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// Whether expansion is enabled.
var enableExpansion: Binding<Bool>?
@ -89,6 +82,7 @@ public struct ExpanderRow: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
var rowsStorage: [ViewStorage] = []
for view in rows() {

View File

@ -2,7 +2,7 @@
// Fixed.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -47,17 +47,10 @@ import LevenshteinTransformations
/// widget. But you should be aware of the tradeoffs.
public struct Fixed: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -78,6 +71,7 @@ public struct Fixed: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}

View File

@ -2,7 +2,7 @@
// FlowBox.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -37,19 +37,12 @@ import LevenshteinTransformations
/// Also see `Gtk.ListBox`.
///
///
public struct FlowBox<Element, Identifier>: AdwaitaWidget where Identifier: Equatable {
public struct FlowBox<Element>: AdwaitaWidget where Element: Identifiable {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// Whether to accept unpaired release events.
var acceptUnpairedRelease: Bool?
@ -130,14 +123,11 @@ public struct FlowBox<Element, Identifier>: AdwaitaWidget where Identifier: Equa
var elements: [Element]
/// The dynamic widget content.
var content: (Element) -> Body
/// The dynamic widget identifier key path.
var id: KeyPath<Element, Identifier>
/// Initialize `FlowBox`.
init(_ elements: [Element], id: KeyPath<Element, Identifier>, @ViewBuilder content: @escaping (Element) -> Body) {
init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) {
self.elements = elements
self.content = content
self.id = id
}
/// The view storage.
@ -150,6 +140,7 @@ public struct FlowBox<Element, Identifier>: AdwaitaWidget where Identifier: Equa
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}
@ -219,9 +210,8 @@ public struct FlowBox<Element, Identifier>: AdwaitaWidget where Identifier: Equa
var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? []
let old = storage.fields["element"] as? [Element] ?? []
old.transform(
old.identifiableTransform(
to: elements,
id: id,
functions: .init { index in
gtk_flow_box_remove(widget, gtk_flow_box_get_child_at_index(widget, index.cInt)?.cast())
contentStorage.remove(at: index)
@ -381,14 +371,3 @@ public struct FlowBox<Element, Identifier>: AdwaitaWidget where Identifier: Equa
}
}
extension FlowBox where Element: Identifiable, Identifier == Element.ID {
/// Initialize `FlowBox`.
public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) {
self.elements = elements
self.content = content
self.id = \.id
}
}

View File

@ -2,7 +2,7 @@
// HeaderBar.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -19,17 +19,10 @@ import LevenshteinTransformations
///
public struct HeaderBar: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The decoration layout for buttons.
///
@ -99,6 +92,7 @@ public struct HeaderBar: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let titleWidgetStorage = titleWidget?.storage(data: data, type: type) {
storage.content["titleWidget"] = [titleWidgetStorage]
adw_header_bar_set_title_widget(storage.opaquePointer, titleWidgetStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// Image.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -41,17 +41,10 @@ import LevenshteinTransformations
///
public struct Image: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -92,6 +85,7 @@ public struct Image: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}

View File

@ -2,7 +2,7 @@
// Label.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -17,17 +17,10 @@ import LevenshteinTransformations
///
public struct Label: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -128,6 +121,7 @@ public struct Label: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let mnemonicWidgetStorage = mnemonicWidget?.storage(data: data, type: type) {
storage.content["mnemonicWidget"] = [mnemonicWidgetStorage]
gtk_label_set_mnemonic_widget(storage.opaquePointer, mnemonicWidgetStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// LevelBar.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -29,17 +29,10 @@ import LevenshteinTransformations
///
public struct LevelBar: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -80,6 +73,7 @@ public struct LevelBar: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}

View File

@ -2,7 +2,7 @@
// LinkButton.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -29,17 +29,10 @@ import LevenshteinTransformations
///
public struct LinkButton: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -98,6 +91,7 @@ public struct LinkButton: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
gtk_button_set_child(storage.opaquePointer?.cast(), childStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// ListBox.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -34,19 +34,12 @@ import LevenshteinTransformations
/// as selected when the user tries to select it.
///
///
public struct ListBox<Element, Identifier>: AdwaitaWidget where Identifier: Equatable {
public struct ListBox<Element>: AdwaitaWidget where Element: Identifiable {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// Whether to accept unpaired release events.
var acceptUnpairedRelease: Bool?
@ -107,14 +100,11 @@ public struct ListBox<Element, Identifier>: AdwaitaWidget where Identifier: Equa
var elements: [Element]
/// The dynamic widget content.
var content: (Element) -> Body
/// The dynamic widget identifier key path.
var id: KeyPath<Element, Identifier>
/// Initialize `ListBox`.
public init(_ elements: [Element], id: KeyPath<Element, Identifier>, @ViewBuilder content: @escaping (Element) -> Body) {
public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) {
self.elements = elements
self.content = content
self.id = id
}
/// The view storage.
@ -127,6 +117,7 @@ public struct ListBox<Element, Identifier>: AdwaitaWidget where Identifier: Equa
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}
@ -189,9 +180,8 @@ public struct ListBox<Element, Identifier>: AdwaitaWidget where Identifier: Equa
var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? []
let old = storage.fields["element"] as? [Element] ?? []
old.transform(
old.identifiableTransform(
to: elements,
id: id,
functions: .init { index in
gtk_list_box_remove(widget, gtk_list_box_get_row_at_index(widget, index.cInt)?.cast())
contentStorage.remove(at: index)
@ -324,14 +314,3 @@ public struct ListBox<Element, Identifier>: AdwaitaWidget where Identifier: Equa
}
}
extension ListBox where Element: Identifiable, Identifier == Element.ID {
/// Initialize `ListBox`.
public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) {
self.elements = elements
self.content = content
self.id = \.id
}
}

View File

@ -2,7 +2,7 @@
// Menu.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -44,17 +44,10 @@ import LevenshteinTransformations
///
public struct Menu: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -106,6 +99,7 @@ public struct Menu: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
gtk_menu_button_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// NavigationView.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -39,17 +39,10 @@ import LevenshteinTransformations
///
public struct NavigationView: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// Whether to animate page transitions.
///
@ -121,6 +114,7 @@ public struct NavigationView: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}

View File

@ -2,7 +2,7 @@
// Overlay.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -31,17 +31,10 @@ import LevenshteinTransformations
///
public struct Overlay: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -81,6 +74,7 @@ public struct Overlay: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
gtk_overlay_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// OverlaySplitView.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -50,17 +50,10 @@ import LevenshteinTransformations
///
public struct OverlaySplitView: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// Whether the split view is collapsed.
///
@ -127,6 +120,7 @@ public struct OverlaySplitView: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let contentStorage = content?.storage(data: data, type: type) {
storage.content["content"] = [contentStorage]
adw_overlay_split_view_set_content(storage.opaquePointer, contentStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// PasswordEntryRow.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -23,17 +23,10 @@ import LevenshteinTransformations
///
public struct PasswordEntryRow: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// Whether activating the embedded entry can activate the default widget.
var activatesDefault: Bool?
@ -97,6 +90,7 @@ public struct PasswordEntryRow: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
var suffixStorage: [ViewStorage] = []
for view in suffix() {

View File

@ -2,7 +2,7 @@
// Picture.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -38,17 +38,10 @@ import LevenshteinTransformations
///
public struct Picture: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -75,6 +68,7 @@ public struct Picture: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}

View File

@ -2,7 +2,7 @@
// Popover.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -35,17 +35,10 @@ import LevenshteinTransformations
///
public struct Popover: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -88,6 +81,7 @@ public struct Popover: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
gtk_popover_set_child(storage.opaquePointer?.cast(), childStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// PreferencesGroup.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -24,17 +24,10 @@ import LevenshteinTransformations
/// [`.boxed-list-separate`](style-classes.html
public struct PreferencesGroup: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The description for this group of preferences.
var description: String?
@ -69,6 +62,7 @@ public struct PreferencesGroup: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let headerSuffixStorage = headerSuffix?.storage(data: data, type: type) {
storage.content["headerSuffix"] = [headerSuffixStorage]
adw_preferences_group_set_header_suffix(storage.opaquePointer?.cast(), headerSuffixStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// PreferencesPage.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -18,17 +18,10 @@ import LevenshteinTransformations
///
public struct PreferencesPage: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The description to be displayed at the top of the page.
var description: String?
@ -59,6 +52,7 @@ public struct PreferencesPage: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
var childStorage: [ViewStorage] = []
for view in child() {

View File

@ -2,7 +2,7 @@
// PreferencesRow.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -19,17 +19,10 @@ import LevenshteinTransformations
/// compose the inputs of the preference around it.
public struct PreferencesRow: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The title of the preference represented by this row.
///
@ -63,6 +56,7 @@ public struct PreferencesRow: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}

View File

@ -2,7 +2,7 @@
// ProgressBar.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -36,17 +36,10 @@ import LevenshteinTransformations
///
public struct ProgressBar: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -86,6 +79,7 @@ public struct ProgressBar: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}

View File

@ -2,7 +2,7 @@
// ScrolledWindow.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -42,17 +42,10 @@ import LevenshteinTransformations
///
public struct ScrolledWindow: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -160,6 +153,7 @@ public struct ScrolledWindow: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
gtk_scrolled_window_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// SearchBar.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -30,17 +30,10 @@ import LevenshteinTransformations
///
public struct SearchBar: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -69,6 +62,7 @@ public struct SearchBar: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
gtk_search_bar_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// SearchEntry.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -41,17 +41,10 @@ import LevenshteinTransformations
///
public struct SearchEntry: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -164,6 +157,7 @@ public struct SearchEntry: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}

View File

@ -2,7 +2,7 @@
// Separator.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -19,17 +19,10 @@ import LevenshteinTransformations
///
public struct Separator: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -50,6 +43,7 @@ public struct Separator: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}

View File

@ -2,7 +2,7 @@
// SpinRow.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -23,17 +23,10 @@ import LevenshteinTransformations
///
public struct SpinRow: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The widget to activate when the row is activated.
///
@ -132,6 +125,7 @@ public struct SpinRow: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let activatableWidgetStorage = activatableWidget?.storage(data: data, type: type) {
storage.content["activatableWidget"] = [activatableWidgetStorage]
adw_action_row_set_activatable_widget(storage.opaquePointer?.cast(), activatableWidgetStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// Spinner.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -31,17 +31,10 @@ import LevenshteinTransformations
///
public struct Spinner: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// Initialize `Spinner`.
@ -58,6 +51,7 @@ public struct Spinner: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}

View File

@ -2,7 +2,7 @@
// SplitButton.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -21,17 +21,10 @@ import LevenshteinTransformations
///
public struct SplitButton: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// Whether the button can be smaller than the natural size of its contents.
///
@ -96,6 +89,7 @@ public struct SplitButton: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
adw_split_button_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// StatusPage.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -18,17 +18,10 @@ import LevenshteinTransformations
///
public struct StatusPage: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The child widget.
var child: Body?
@ -57,6 +50,7 @@ public struct StatusPage: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
adw_status_page_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// SwitchRow.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -32,17 +32,10 @@ import LevenshteinTransformations
///
public struct SwitchRow: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The widget to activate when the row is activated.
///
@ -112,6 +105,7 @@ public struct SwitchRow: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let activatableWidgetStorage = activatableWidget?.storage(data: data, type: type) {
storage.content["activatableWidget"] = [activatableWidgetStorage]
adw_action_row_set_activatable_widget(storage.opaquePointer?.cast(), activatableWidgetStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// ToastOverlay.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -24,17 +24,10 @@ import LevenshteinTransformations
///
public struct ToastOverlay: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The child widget.
var child: Body?
@ -53,6 +46,7 @@ public struct ToastOverlay: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
adw_toast_overlay_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// ToggleButton.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -26,17 +26,10 @@ import LevenshteinTransformations
///
public struct ToggleButton: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -92,6 +85,7 @@ public struct ToggleButton: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
gtk_button_set_child(storage.opaquePointer?.cast(), childStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// ToggleGroup.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -46,17 +46,10 @@ import LevenshteinTransformations
///
public struct ToggleGroup: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The index of the active toggle.
///
@ -98,6 +91,7 @@ public struct ToggleGroup: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}

View File

@ -2,7 +2,7 @@
// ToolbarView.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -33,17 +33,10 @@ import LevenshteinTransformations
/// [`.toolbar`](style-classes.html
public struct ToolbarView: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The current bottom bar height.
///
@ -127,6 +120,7 @@ public struct ToolbarView: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
if let contentStorage = content?.storage(data: data, type: type) {
storage.content["content"] = [contentStorage]
adw_toolbar_view_set_content(storage.opaquePointer, contentStorage.opaquePointer?.cast())

View File

@ -2,7 +2,7 @@
// WindowTitle.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
// Created by auto-generation on 30.12.25.
//
import CAdw
@ -18,17 +18,10 @@ import LevenshteinTransformations
///
public struct WindowTitle: AdwaitaWidget {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
/// The subtitle to display.
///
@ -56,6 +49,7 @@ public struct WindowTitle: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}

View File

@ -17,7 +17,11 @@ public struct HStack: SimpleView {
/// The view's body.
public var view: Body {
VStack(horizontal: true, spacing: spacing, content: content)
ModifierWrapper(
content: VStack(horizontal: true, spacing: spacing, content: content),
style: "linked",
styleActive: linked
)
}
/// Initialize a `HStack`.

View File

@ -0,0 +1,24 @@
//
// List+.swift
// Adwaita
//
// Created by david-swift on 16.10.24.
//
extension List {
/// Add the "navigation-sidebar" style class.
/// - Parameter active: Whether the style is applied.
/// - Returns: A view.
public func sidebarStyle(_ active: Bool = true) -> AnyView {
style("navigation-sidebar", active: active)
}
/// Apply the boxed list style class.
/// - Parameter active: Whether the style is applied.
/// - Returns: A view.
public func boxedList(_ active: Bool = true) -> AnyView {
style("boxed-list", active: active)
}
}

View File

@ -21,19 +21,17 @@ extension List {
/// Initialize `List`.
/// - Parameters:
/// - elements: The elements.
/// - id: The key path to the elements' identifiers.
/// - selection: The identifier of the selected element. Selection disabled if `nil`.
/// - content: The view for an element.
public init(
_ elements: [Element],
id: KeyPath<Element, Identifier>,
selection: Binding<Identifier>?,
selection: Binding<Element.ID>?,
@ViewBuilder content: @escaping (Element) -> Body
) {
self.init(elements, id: id, content: content)
let getID: (ViewStorage, [Element]) -> Identifier? = { storage, elements in
self.init(elements, content: content)
let id: (ViewStorage, [Element]) -> Element.ID? = { storage, elements in
if let row = gtk_list_box_get_selected_row(storage.opaquePointer) {
return elements[safe: .init(gtk_list_box_row_get_index(row))]?[keyPath: id]
return elements[safe: .init(gtk_list_box_row_get_index(row))]?.id
}
return nil
}
@ -41,13 +39,13 @@ extension List {
updateFunctions.append { storage, _, _ in
storage.connectSignal(name: "selected_rows_changed", id: Self.selectionField) {
if let elements = storage.fields[Self.elementsField] as? [Element],
let id = getID(storage, elements),
let id = id(storage, elements),
selection.wrappedValue != id {
selection.wrappedValue = id
}
}
if selection.wrappedValue != getID(storage, elements),
let index = elements.firstIndex(where: { $0[keyPath: id] == selection.wrappedValue })?.cInt {
if selection.wrappedValue != id(storage, elements),
let index = elements.firstIndex(where: { $0.id == selection.wrappedValue })?.cInt {
gtk_list_box_select_row(
storage.opaquePointer,
gtk_list_box_get_row_at_index(storage.opaquePointer, index)
@ -61,35 +59,4 @@ extension List {
}
}
/// Add the "navigation-sidebar" style class.
/// - Parameter active: Whether the style is applied.
/// - Returns: A view.
public func sidebarStyle(_ active: Bool = true) -> AnyView {
style("navigation-sidebar", active: active)
}
/// Apply the boxed list style class.
/// - Parameter active: Whether the style is applied.
/// - Returns: A view.
public func boxedList(_ active: Bool = true) -> AnyView {
style("boxed-list", active: active)
}
}
extension List where Element: Identifiable, Element.ID == Identifier {
/// Initialize `List`.
/// - Parameters:
/// - elements: The elements.
/// - selection: The identifier of the selected element. Selection disabled if `nil`.
/// - content: The view for an element.
public init(
_ elements: [Element],
selection: Binding<Element.ID>?,
@ViewBuilder content: @escaping (Element) -> Body
) {
self.init(elements, id: \.id, selection: selection, content: content)
}
}

View File

@ -0,0 +1,192 @@
//
// ModifierWrapper.swift
// Adwaita
//
// Created by david-swift on 04.09.24.
//
import CAdw
/// A wrapper for view modifiers for any view.
struct ModifierWrapper: AdwaitaWidget {
/// The view.
var content: AnyView
/// The padding.
var padding: Int?
/// The padding edges.
var edges: Set<Edge>?
/// Whether to expand horizontally.
var hexpand: Bool?
/// Whether to expand vertically.
var vexpand: Bool?
/// The horizontal alignment.
var halign: Alignment?
/// The vertical alignment.
var valign: Alignment?
/// The minimum width.
var minWidth: Int?
/// The minimum height.
var minHeight: Int?
/// The style class.
var style: String?
/// Whether the style is active.
var styleActive: Bool?
/// Whether the view is insensitive.
var insensitive: Bool?
/// Whether the view is visible.
var visible: Bool?
/// The tooltip.
var tooltip: String?
/// Initialize a modifier wrapper.
/// - Parameters:
/// - content: The view.
/// - padding: The padding.
/// - edges: The padding edges.
/// - hexpand: Whether to expand horizontally.
/// - vexpand: Whether to expand vertically.
/// - halign: The horizontal alignment.
/// - valign: The vertical alignment.
/// - minWidth: The minimum width.
/// - minHeight: The minimum height.
/// - style: The style class.
/// - styleActive: Whether the style is active.
/// - insensitive: Whether the view is insensitive.
/// - visible: Whether the view is visible.
/// - tooltip: The tooltip.
init(
content: AnyView,
padding: Int? = nil,
edges: Set<Edge>? = nil,
hexpand: Bool? = nil,
vexpand: Bool? = nil,
halign: Alignment? = nil,
valign: Alignment? = nil,
minWidth: Int? = nil,
minHeight: Int? = nil,
style: String? = nil,
styleActive: Bool? = nil,
insensitive: Bool? = nil,
visible: Bool? = nil,
tooltip: String? = nil
) {
self.content = content
self.padding = padding
self.edges = edges
self.hexpand = hexpand
self.vexpand = vexpand
self.halign = halign
self.valign = valign
self.minWidth = minWidth
self.minHeight = minHeight
self.style = style
self.styleActive = styleActive
self.insensitive = insensitive
self.visible = visible
self.tooltip = tooltip
}
/// The view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The view render data type.
/// - Returns: The view storage.
func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
let content = content.storage(data: data, type: type)
let storage = ViewStorage(content.pointer, content: [.mainContent: [content]])
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<Data>(
_ storage: ViewStorage,
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
if let storage = storage.content[.mainContent]?.first {
content.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
}
guard updateProperties else {
return
}
update1(storage, data: data, updateProperties: updateProperties, type: type)
update2(storage, data: data, updateProperties: updateProperties, type: type)
storage.previousState = self
}
/// Update part 1 of the properties.
/// - 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 update1<Data>(
_ storage: ViewStorage,
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
let previousState = storage.previousState as? Self
if let padding, let edges, previousState?.padding != padding || previousState?.edges != edges {
if edges.contains(.leading) { gtk_widget_set_margin_start(storage.opaquePointer?.cast(), padding.cInt) }
if edges.contains(.trailing) { gtk_widget_set_margin_end(storage.opaquePointer?.cast(), padding.cInt) }
if edges.contains(.top) { gtk_widget_set_margin_top(storage.opaquePointer?.cast(), padding.cInt) }
if edges.contains(.bottom) { gtk_widget_set_margin_bottom(storage.opaquePointer?.cast(), padding.cInt) }
}
if let hexpand, previousState?.hexpand != hexpand {
gtk_widget_set_hexpand(storage.opaquePointer?.cast(), hexpand.cBool)
}
if let vexpand, previousState?.vexpand != vexpand {
gtk_widget_set_vexpand(storage.opaquePointer?.cast(), vexpand.cBool)
}
if let halign, previousState?.halign != halign {
gtk_widget_set_halign(storage.opaquePointer?.cast(), halign.cAlign)
}
if let valign, previousState?.valign != valign {
gtk_widget_set_valign(storage.opaquePointer?.cast(), valign.cAlign)
}
}
/// Update part 2 of the properties.
/// - 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 update2<Data>(
_ storage: ViewStorage,
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
let previousState = storage.previousState as? Self
if minWidth != previousState?.minWidth || minHeight != previousState?.minHeight {
gtk_widget_set_size_request(storage.opaquePointer?.cast(), minWidth?.cInt ?? 1, minHeight?.cInt ?? -1)
}
if let style, let styleActive, previousState?.styleActive != styleActive {
if styleActive {
gtk_widget_add_css_class(storage.opaquePointer?.cast(), style)
} else {
gtk_widget_remove_css_class(storage.opaquePointer?.cast(), style)
}
}
if let insensitive, previousState?.insensitive != insensitive {
gtk_widget_set_sensitive(storage.opaquePointer?.cast(), insensitive ? 0 : 1)
}
if let visible, previousState?.visible != visible {
gtk_widget_set_visible(storage.opaquePointer?.cast(), visible.cBool)
}
if let tooltip, previousState?.tooltip != tooltip {
gtk_widget_set_tooltip_markup(storage.opaquePointer?.cast(), tooltip)
}
}
}

View File

@ -58,6 +58,7 @@ public struct NavigationSplitView: AdwaitaWidget {
content[contentID] = [mainContent]
let storage = ViewStorage(splitView?.opaque(), content: content)
update(storage, data: data, updateProperties: true, type: type)
storage.fields["sidebar-page"] = sidebarPage?.opaque()
storage.fields["main-page"] = mainPage?.opaque()

View File

@ -111,8 +111,6 @@ extension NavigationView {
} else { print("Warning: removing the initial view is not allowed.") }
case let .push(component):
let contentStorage = views.0(component).storage(data: data, type: AdwaitaMainView.self)
views.0(component)
.updateStorage(contentStorage, data: data, updateProperties: true, type: AdwaitaMainView.self)
contentStorage.fields[Self.componentID] = component
storages.append(contentStorage)
adw_navigation_view_push(

View File

@ -104,6 +104,7 @@ public struct TextView: AdwaitaWidget {
content: ["buffer": [buffer]]
)
initProperties(editor, data: data, type: type)
update(editor, data: data, updateProperties: true, type: type)
return editor
}

View File

@ -23,103 +23,72 @@ extension ToggleGroup {
selection: Binding<Element.ID>,
values: [Element]
) where Element: ToggleGroupItem {
self.init(
selection: selection,
values: values,
id: \.id,
label: \.id.description,
icon: \.icon,
showLabel: \.showLabel
)
}
/// Initialize a toggle group.
/// - Parameters:
/// - selection: The selected value.
/// - values: The available values.
/// - id: The path to the identifier.
/// - label: The path to the label.
/// - icon: The path to the icon.
/// - showLabel: The path to the boolean that defines whether to show an element's label.
public init<Element, Identifier>(
selection: Binding<Identifier>,
values: [Element],
id: KeyPath<Element, Identifier>,
label: KeyPath<Element, String>,
icon: KeyPath<Element, Icon?>? = nil,
showLabel: KeyPath<Element, Bool>? = nil
) where Identifier: Equatable {
self.init()
appearFunctions.append { storage, _ in
storage.notify(name: "active-name", id: "init") {
if let name = adw_toggle_group_get_active_name(storage.opaquePointer),
let values = storage.fields[Self.values] as? [Element],
let identifier = values
.map({ $0[keyPath: label] }).first(where: { $0.description == String(cString: name) }),
let value = values.first(where: { $0[keyPath: label] == identifier }) {
selection.wrappedValue = value[keyPath: id]
let value = values.first(where: { $0.id.description == String(cString: name) }) {
selection.wrappedValue = value.id
}
}
Self.updateContent(
storage: storage,
selection: selection.wrappedValue,
values: values,
updateProperties: true
)
}
updateFunctions.append { storage, _, updateProperties in
Self.updateContent(
storage: storage,
selection: selection.wrappedValue,
values: values,
id: id,
label: label,
icon: icon,
showLabel: showLabel,
updateProperties: updateProperties
)
}
}
// swiftlint:disable function_parameter_count
/// Update the combo row's content.
static func updateContent<Element, Identifier>(
/// - Parameters:
/// - storage: The view storage.
/// - values: The elements.
/// - updateProperties: Whether to update the properties.
static func updateContent<Element>(
storage: ViewStorage,
selection: Identifier,
selection: Element.ID,
values: [Element],
id: KeyPath<Element, Identifier>,
label: KeyPath<Element, String>,
icon: KeyPath<Element, Icon?>?,
showLabel: KeyPath<Element, Bool>?,
updateProperties: Bool
) where Identifier: Equatable {
) where Element: ToggleGroupItem {
guard updateProperties else {
return
}
let old = storage.fields[Self.values] as? [Element] ?? []
old.transform(
old.identifiableTransform(
to: values,
id: id,
functions: .init { index in
if let id = old[safe: index]?[keyPath: label],
if let id = old[safe: index]?.id.description,
let toggle = storage.fields[Self.toggle + id] as? OpaquePointer {
adw_toggle_group_remove(storage.opaquePointer, toggle)
}
} insert: { _, element in
let toggle = adw_toggle_new()
adw_toggle_set_name(toggle, element[keyPath: label])
if let showLabel, !element[keyPath: showLabel] {
adw_toggle_set_tooltip(toggle, element[keyPath: label])
adw_toggle_set_name(toggle, element.id.description)
if element.showLabel {
adw_toggle_set_label(toggle, element.id.description)
} else {
adw_toggle_set_label(toggle, element[keyPath: label])
adw_toggle_set_tooltip(toggle, element.id.description)
}
if let icon, let icon = element[keyPath: icon] {
if let icon = element.icon {
adw_toggle_set_icon_name(toggle, icon.string)
}
storage.fields[Self.toggle + element[keyPath: label]] = toggle
storage.fields[Self.toggle + element.id.description] = toggle
adw_toggle_group_add(storage.opaquePointer, toggle)
}
)
storage.fields[Self.values] = values
if let selection = values.first(where: { $0[keyPath: id] == selection }) {
adw_toggle_group_set_active_name(storage.opaquePointer, selection[keyPath: label])
}
adw_toggle_group_set_active_name(storage.opaquePointer, selection.description)
}
// swiftlint:enable function_parameter_count
}

View File

@ -53,7 +53,9 @@ public struct ViewStack: AdwaitaWidget {
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let stack = gtk_stack_new()
return .init(stack?.opaque())
let storage = ViewStorage(stack?.opaque())
update(storage, data: data, updateProperties: true, type: type)
return storage
}
/// Update the stored content.
@ -72,7 +74,6 @@ public struct ViewStack: AdwaitaWidget {
content.updateStorage(view, data: data, updateProperties: updateProperties, type: type)
} else {
let view = content.storage(data: data, type: type)
content.updateStorage(view, data: data, updateProperties: true, type: type)
gtk_stack_add_named(storage.opaquePointer, view.opaquePointer?.cast(), id.description)
storage.content[id.description] = [view]
}

View File

@ -39,6 +39,7 @@ public struct ViewSwitcher<Element>: AdwaitaWidget where Element: ViewSwitcherOp
let switcher = ViewStorage(adw_view_switcher_new()?.opaque())
let stack = ViewStorage(adw_view_stack_new()?.opaque())
adw_view_switcher_set_stack(switcher.opaquePointer, stack.opaquePointer)
updateSwitcher(switcher: switcher)
switcher.fields["stack"] = stack
return switcher
}

View File

@ -85,13 +85,3 @@ gtui_initialize_boolean (gboolean boolean)
g_value_set_boolean(&val, boolean);
return val;
}
static void
gtui_cssprovider_set_prefers_color_scheme (uint64_t provider, GtkInterfaceColorScheme scheme)
{
GValue val = G_VALUE_INIT;
g_value_init(&val, G_TYPE_ENUM);
g_value_set_enum(&val, scheme);
g_object_set_property(provider, "prefers-color-scheme", &val);
g_value_unset(&val);
}

View File

@ -0,0 +1,115 @@
//
// AboutDialogDemo.swift
// Adwaita
//
// Created by lambdaclan on 24.01.26.
//
// swiftlint:disable missing_docs
import Adwaita
import Foundation
enum AboutDialogDemo {
static var sample: (inout AdwaitaAboutDialogConfig) -> Void {
{ cfg in
applyDemoConfig(&cfg)
}
}
private static let demoReleaseNotes = """
<p>This template supports three structures: paragraphs using <code>&lt;p&gt;</code>, ordered lists using
<code>&lt;ol&gt;</code>, and unordered lists using <code>&lt;ul&gt;</code>.
Both list types must contain list items marked with <code>&lt;li&gt;</code>.</p>
<p>Within paragraphs and list items, you may use <code>&lt;em&gt;</code> to apply
<em>emphasis</em>(italic text) and <code>&lt;code&gt;</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>&lt;p&gt;</code>, <code>&lt;ol&gt;</code>,
<code>&lt;ul&gt;</code>, or <code>&lt;li&gt;</code> tags is ignored by the template
processor.</p>
<ol>
<li>Ordered list items represent numbered content and may
include <code>&lt;em&gt;</code> for <em>emphasis</em> or <code>&lt;code&gt;</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>
"""
private 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">AdwaitaSwift Documentation</a>
You can embed these links directly in your UI using Pango markup.
"""
private static func applyDemoConfig(_ cfg: inout AdwaitaAboutDialogConfig) {
cfg.appName = "Demo"
cfg.developer = "david-swift"
cfg.version = "Test"
cfg.icon = .default(icon: .applicationXExecutable)
cfg.website = URL(string: "https://adwaita-swift.aparoksha.dev/tutorials/table-of-contents")
cfg.issues = URL(string: "https://git.aparoksha.dev/aparoksha/adwaita-swift/issues")
cfg.support = URL(string: "https://adwaita-swift.aparoksha.dev/")
cfg.links = [
.init(title: "Source Code", url: URL(string: "https://git.aparoksha.dev/aparoksha/adwaita-swift")),
.init(title: "Donate", url: URL(string: "https://ko-fi.com/david_swift"))
]
cfg.copyright = "© 2026 david-swift"
cfg.license = "MIT"
cfg.releaseNotes = demoReleaseNotes
cfg.comments = demoComments
cfg.credits = [
.init(role: .developer, name: "Jane Doe"),
.init(role: .developer, name: "John Roe"),
.init(role: .designer, name: "Mika Sato"),
.init(role: .artist, name: "Leo Martins"),
.init(role: .translator, name: "Yuki Nakamura"),
.init(role: .translator, name: "Tod Brown")
]
cfg.acknowledgements = [
.init(title: "Special Thanks", name: "GNOME Project"),
.init(title: "Special Thanks", name: "Swift Programming Language"),
.init(title: "Additional Support", name: "LibAdwaita Contributors")
]
cfg.otherApps = [
.init(
appID: "io.github.david_swift.Flashcards",
name: "Memorize",
summary: "An app for creating, studying, and importing flashcard sets with a builtin test mode."
)
]
}
}
// swiftlint:enable missing_docs

View File

@ -150,15 +150,7 @@ struct Demo: App {
}
.collapsed(!wide)
.breakpoint(minWidth: 550, matches: $wide)
.aboutDialog(
visible: $about,
app: "Demo",
developer: "david-swift",
version: "Test",
icon: .default(icon: .applicationXExecutable),
website: .init(string: "https://adwaita-swift.aparoksha.dev/"),
issues: .init(string: "https://git.aparoksha.dev/aparoksha/adwaita-swift/issues")
)
.aboutDialog(visible: $about, configure: AboutDialogDemo.sample)
.preferencesDialog(visible: $preferences)
.preferencesPage("Page 1", icon: .default(icon: .audioHeadset)) { page in
page

View File

@ -28,7 +28,7 @@ struct FlowBoxDemo: View {
selectedItem = items[safe: index]?.id ?? items[safe: index ?? 0 - 1]?.id ?? items.first?.id ?? ""
}
}
.modifyContent(VStack.self) { $0.linked() }
.linked()
.padding()
.halign(.center)
if !items.isEmpty {

View File

@ -28,7 +28,7 @@ struct ListDemo: View {
selectedItem = items[safe: index]?.id ?? items[safe: index ?? 0 - 1]?.id ?? items.first?.id ?? ""
}
}
.modifyContent(VStack.self) { $0.linked() }
.linked()
.padding()
.halign(.center)
if !items.isEmpty {

View File

@ -15,13 +15,8 @@ struct ToggleGroupDemo: View {
@State private var selection: Subview = .view1
var view: Body {
ToggleGroup(
selection: $selection,
values: Subview.allCases,
id: \.self,
label: \.rawValue
)
.padding()
ToggleGroup(selection: $selection, values: Subview.allCases)
.padding()
VStack {
Text(selection.rawValue)
.padding()
@ -31,11 +26,19 @@ struct ToggleGroupDemo: View {
.padding()
}
enum Subview: String, CaseIterable, Equatable {
enum Subview: String, ToggleGroupItem, CaseIterable, CustomStringConvertible {
case view1 = "View 1"
case view2 = "View 2"
var id: Self { self }
var description: String { rawValue }
var icon: Icon? { nil }
var showLabel: Bool { true }
}
}

View File

@ -24,7 +24,7 @@ extension Class {
.filter { config.requiredProperties.contains($0.name) }
var initializer = "\(config.internalInitializer ? "" : "public ")init("
if config.dynamicWidget != nil {
initializer.append("_ elements: [Element], id: KeyPath<Element, Identifier>, ")
initializer.append("_ elements: [Element], ")
}
for property in requiredProperties {
initializer.append("\(property.parameter(config: config, genConfig: genConfig)), ")
@ -46,7 +46,6 @@ extension Class {
self.elements = elements
self.content = content
self.id = id
"""
)
}
@ -168,8 +167,6 @@ extension Class {
var elements: [Element]
/// The dynamic widget content.
var content: (Element) -> Body
/// The dynamic widget identifier key path.
var id: KeyPath<Element, Identifier>
"""
}
content += staticWidgetProperties(namespace: namespace, configs: configs)
@ -229,9 +226,8 @@ extension Class {
return """
var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? []
let old = storage.fields["element"] as? [Element] ?? []
old.transform(
old.identifiableTransform(
to: elements,
id: id,
functions: .init { index in
\(dynamicWidget.remove)(\(widget), \(dynamicWidget.getElement))
contentStorage.remove(at: index)

View File

@ -64,25 +64,10 @@ struct Class: ClassLike, Decodable {
dateFormatter.dateFormat = "dd.MM.yy"
let widgetName = config.name ?? config.class
let definition: String
var extensions = ""
if config.dynamicWidget == nil {
definition = "\(widgetName): AdwaitaWidget"
} else {
definition = "\(widgetName)<Element, Identifier>: AdwaitaWidget where Identifier: Equatable"
extensions += """
extension \(widgetName) where Element: Identifiable, Identifier == Element.ID {
/// Initialize `\(widgetName)`.
public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) {
self.elements = elements
self.content = content
self.id = \\.id
}
}
"""
definition = "\(widgetName)<Element>: AdwaitaWidget where Element: Identifiable"
}
return """
//
@ -98,17 +83,10 @@ struct Class: ClassLike, Decodable {
\(doc.docComment(configuration: genConfig))
public struct \(definition) {
#if exposeGeneratedAppearUpdateFunctions
/// Additional update functions for type extensions.
public var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
public var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#else
/// Additional update functions for type extensions.
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
/// Additional appear functions for type extensions.
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
#endif
\(generateProperties(config: config, genConfig: genConfig, namespace: namespace, configs: configs))
/// Initialize `\(widgetName)`.
@ -124,6 +102,7 @@ struct Class: ClassLike, Decodable {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
\(generateWidgetAssignments(config: config, genConfig: genConfig, namespace: namespace, configs: configs))
return storage
}
@ -150,7 +129,7 @@ struct Class: ClassLike, Decodable {
}
\(generateModifiers(config: config, genConfig: genConfig, namespace: namespace, configs: configs))
}
\(extensions)
"""
}
// swiftlint:enable function_body_length line_length