Compare commits

...

81 Commits
0.1.0 ... main

Author SHA1 Message Date
d928b464f1 Fix broken preferences page tabs #74
Some checks failed
Deploy Docs / publish (push) Has been cancelled
SwiftLint / SwiftLint (push) Has been cancelled
2026-02-17 16:29:12 +01:00
2072c16040 Add support for keypaths where sensible #74
All checks were successful
SwiftLint / SwiftLint (push) Successful in 7s
Deploy Docs / publish (push) Successful in 1h49m51s
2026-02-04 16:36:51 +01:00
c08a9dc3bd Fix build failing on macOS #74
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2026-02-03 20:35:35 +01:00
7e41c9b5df Add exposeGeneratedAppearUpdateFunctions trait #74
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2026-02-03 00:29:14 +01:00
6acf83dce3 Fix not building on macOS #78
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2026-02-03 00:17:07 +01:00
0fc91dc50e Use new update logic to construct dialog UIs
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2026-02-03 00:15:37 +01:00
d0d7d2b6d3 Use the new wrapModifier for simple modifiers
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2026-02-03 00:07:26 +01:00
8f6a83dfc3 Move update responsibility to constructor
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
When constructing views, the top-level constructor should now update
those views directly after the construction process. In adwaita-swift,
this applies only for EitherViews (as Meta will now automatically update
when constructing new scene elements).
2026-02-02 22:44:44 +01:00
c976c29cd0 Add round style class #74
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2026-02-02 21:32:10 +01:00
6b76a4c8f4 Use new wrap modifier
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2026-02-02 21:26:50 +01:00
19aa17c0ab Fix to work with latest SQLite.swift version
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2026-02-02 21:21:43 +01:00
54619c69f4 Add support for specifying the CSS scheme to load
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2026-02-02 19:42:31 +01:00
07d6a38edc Remove old style context providers in (css) #74
Some checks failed
Deploy Docs / publish (push) Has been cancelled
SwiftLint / SwiftLint (push) Has been cancelled
2026-01-30 14:49:10 +01:00
29194341e2 Fix CSS updating on each view update #74
Some checks are pending
Deploy Docs / publish (push) Waiting to run
2026-01-30 14:33:59 +01:00
cf60b8103f Add homogeneous option to ForEach #74
Some checks failed
Deploy Docs / publish (push) Has been cancelled
SwiftLint / SwiftLint (push) Has been cancelled
2025-12-30 16:32:24 +01:00
b364557f2f FlowBox: Selection disabled by default #74
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2025-12-30 16:24:47 +01:00
adae811e41 Add alternative padding method #74
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2025-12-30 16:04:25 +01:00
c29c6e22cb Add id modifier #74
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2025-12-30 15:14:51 +01:00
92fe4fb256 Name sqlite file after application id
Some checks failed
Deploy Docs / publish (push) Has been cancelled
SwiftLint / SwiftLint (push) Has been cancelled
For non-Flatpak apps
2025-11-06 13:02:58 +01:00
4de2d312ab Fix style
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2025-11-05 13:04:53 +01:00
a524cde9b0 Add support for AdwShortcutsDialog
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2025-11-05 13:01:27 +01:00
7eb2bf7bb2 Add internal initializer to autogeneration
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2025-11-04 13:09:17 +01:00
90e8c78163 Add support for toggle groups
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2025-11-03 22:28:28 +01:00
1418d1333c Generation: store views as Body
Some checks failed
Deploy Docs / publish (push) Has been cancelled
SwiftLint / SwiftLint (push) Has been cancelled
2025-10-31 23:43:47 +01:00
557ec14232 Fix style
All checks were successful
Deploy Docs / publish (push) Successful in 1h52m14s
SwiftLint / SwiftLint (push) Successful in 39s
2025-10-30 22:01:48 +01:00
edb6a81812 Remove explicit passing of window to shortcuts
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2025-10-30 21:55:38 +01:00
04c77831b5 Remove Core library
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2025-10-30 21:36:13 +01:00
fd29eccd68 Improve autogenerated docs
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2025-10-30 20:48:37 +01:00
david-swift
f86e968028 Merge pull request 'Add Symbol view' (#73) from marquiskurt/adwaita-swift:main into main
Some checks failed
Deploy Docs / publish (push) Has been cancelled
SwiftLint / SwiftLint (push) Has been cancelled
Reviewed-on: #73
Reviewed-by: david-swift <david-swift@noreply.aproksha.uber.space>
2025-10-25 15:37:35 +02:00
ac2dbadedb
Add Symbol view
Some checks failed
SwiftLint / SwiftLint (pull_request) Has been cancelled
A symbol view is used to display an symbolic icon at an arbitrary
size. It is a typealias to the Image class from GTK.
2025-10-23 22:54:27 -04:00
5b9047ea85 Rename "keep" close confirmation to "cancel"
Some checks failed
Deploy Docs / publish (push) Has been cancelled
SwiftLint / SwiftLint (push) Has been cancelled
2025-10-20 13:03:30 +02:00
571ed60954 Add default values to onClose (in file dialogs)
Some checks failed
Deploy Docs / publish (push) Has been cancelled
SwiftLint / SwiftLint (push) Has been cancelled
2025-10-17 13:07:16 +02:00
c8ce2cc2fe Add support for folder importers
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2025-10-17 12:47:39 +02:00
037a697c74 Make onClose easier to understand
Some checks failed
Deploy Docs / publish (push) Has been cancelled
SwiftLint / SwiftLint (push) Has been cancelled
2025-10-12 21:53:46 +02:00
e430031bbc Add onClose to windows
Some checks failed
Deploy Docs / publish (push) Has been cancelled
SwiftLint / SwiftLint (push) Has been cancelled
2025-10-03 23:07:41 +02:00
1bc36e0759 Remove invisible unicode characters
Some checks failed
Deploy Docs / publish (push) Has been cancelled
SwiftLint / SwiftLint (push) Has been cancelled
2025-09-18 21:40:57 +02:00
d17306f195 Add HSplitView and VSplitView
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
Co-authored-by: desbeers nick@desbeers.nl
2025-09-18 21:22:20 +02:00
david-swift
fea203fabd Merge pull request 'Add implementation for WrapMode initializer.' (#71) from mlm/adwaita-swift:AddInitializerImplementation into main
Some checks failed
Deploy Docs / publish (push) Has been cancelled
SwiftLint / SwiftLint (push) Has been cancelled
Reviewed-on: #71
Reviewed-by: david-swift <david-swift@noreply.aproksha.uber.space>
2025-09-07 10:04:46 +02:00
ml
6e6265aa76 Add implementation for WrapMode initializer.
Some checks failed
SwiftLint / SwiftLint (pull_request) Has been cancelled
2025-09-05 14:05:07 +02:00
0d4db96f60 Fix crashing when removing items from ForEach
Some checks failed
Deploy Docs / publish (push) Has been cancelled
SwiftLint / SwiftLint (push) Has been cancelled
2025-09-03 13:35:29 +02:00
david-swift
ebb2455fe1 Merge pull request 'Add WrapMode to TextView/TextEditor' (#68) from mlm/adwaita-swift:AddWrapMode into main
Some checks failed
SwiftLint / SwiftLint (push) Failing after 21m8s
Deploy Docs / publish (push) Has been cancelled
Reviewed-on: #68
2025-08-27 13:36:21 +02:00
4eb58b154c Use more declarative approach for text editor
Some checks failed
SwiftLint / SwiftLint (pull_request) Has been cancelled
2025-08-27 13:27:36 +02:00
87b970d844 Fix code style
All checks were successful
SwiftLint / SwiftLint (pull_request) Successful in 6s
2025-08-26 13:33:43 +02:00
ml
0af3864058 Add WrapMode to TextView/TextEditor
Some checks failed
SwiftLint / SwiftLint (pull_request) Has been cancelled
2025-08-25 10:12:02 +02:00
david-swift
daa922d33b Merge pull request 'Update README.me' (#66) from Sylphrena/adwaita-swift:template-repo into main
Some checks failed
Deploy Docs / publish (push) Has been cancelled
Reviewed-on: #66
Reviewed-by: david-swift <david-swift@noreply.aproksha.uber.space>
2025-08-15 17:40:44 +02:00
4e95e4e655 Implement proper self destruction of signals
Some checks failed
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Has been cancelled
2025-08-14 23:24:30 +02:00
Sylphrena
d53ba5f4e7 Update README.me
Replace old github link to the template repo with the new one.
2025-08-12 15:46:59 +02:00
049b5b54f8 Add support for text editors
Some checks failed
SwiftLint / SwiftLint (push) Successful in 6s
Deploy Docs / publish (push) Has been cancelled
2025-08-09 10:48:04 +02:00
a04bd9025d Add support for dynamic CSS #61
Some checks failed
Deploy Docs / publish (push) Has been cancelled
SwiftLint / SwiftLint (push) Has been cancelled
2025-05-05 13:11:35 +02:00
7eeec9e0fd Add support for GtkEntry
All checks were successful
Deploy Docs / publish (push) Successful in 1h45m1s
SwiftLint / SwiftLint (push) Successful in 5s
2025-04-19 19:03:26 +02:00
a996be3f16 Add support for setting a window's minimum size
Some checks are pending
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Waiting to run
2025-04-19 18:37:23 +02:00
f209c8387c Add support for AdwToolbarStyle
Some checks failed
Deploy Docs / publish (push) Failing after 1s
SwiftLint / SwiftLint (push) Failing after 1s
2025-04-15 16:44:20 +02:00
513a5d36a3 Add SwiftLint to Flatpak manifest
Some checks failed
Deploy Docs / publish (push) Has been cancelled
2025-04-11 10:31:41 +02:00
befa7d52ea Add spacing to VStack/HStack initializers
Some checks failed
Deploy Docs / publish (push) Waiting to run
SwiftLint / SwiftLint (push) Has been cancelled
2025-04-11 10:31:11 +02:00
4290dd4137 Use latest version of SFTP upload action
All checks were successful
Deploy Docs / publish (push) Successful in 1h43m10s
2025-04-09 16:52:30 +02:00
281bf7cf40 Fix code style
Some checks failed
SwiftLint / SwiftLint (push) Successful in 3s
Deploy Docs / publish (push) Has been cancelled
2025-04-09 16:51:33 +02:00
a898efcdf8 Add support for GtkDropDown 2025-04-09 16:06:57 +02:00
62b3aa93b2 Add Flatpak manifest for generation
Some checks failed
Deploy Docs / publish (push) Failing after 8m47s
SwiftLint / SwiftLint (push) Failing after 38s
2025-04-09 11:13:27 +02:00
9ae203fd7b Update GNOME runtime
Some checks are pending
Deploy Docs / publish (push) Waiting to run
2025-04-08 17:12:30 +02:00
90349fd435 Fix file dialog children updates not working
This was reported in https://forums.aparoksha.dev/d/5-at-state-and-fileexporter-dont-like-each-other
2025-03-23 11:06:32 +01:00
f89b44cee6 Only update alert dialog's extra child if visible
Some checks failed
Deploy Docs / publish (push) Failing after 25s
SwiftLint / SwiftLint (push) Successful in 5s
2025-01-24 18:11:37 +01:00
5613ce13cd Fix memory leaks
Some checks failed
SwiftLint / SwiftLint (push) Successful in 6s
Deploy Docs / publish (push) Failing after 25s
2025-01-23 13:02:11 +01:00
a0c0136298 Add storage fields to AdwaitaWindow
All checks were successful
SwiftLint / SwiftLint (push) Successful in 5s
Deploy Docs / publish (push) Successful in 22m31s
2024-12-01 13:58:19 +01:00
90beecaeb9 Add custom content to alert dialog
All checks were successful
Deploy Docs / publish (push) Successful in 22m31s
SwiftLint / SwiftLint (push) Successful in 5s
2024-11-27 09:15:35 +01:00
776b63f46a Polish demo
All checks were successful
Deploy Docs / publish (push) Successful in 20m37s
SwiftLint / SwiftLint (push) Successful in 5s
2024-11-23 11:35:50 +01:00
6a9f05bc18 Remove system-specific default icons
All checks were successful
Deploy Docs / publish (push) Successful in 20m59s
2024-11-23 10:57:59 +01:00
4b23fe16d1 Fix crash when closing dialog
All checks were successful
Deploy Docs / publish (push) Successful in 20m30s
SwiftLint / SwiftLint (push) Successful in 6s
2024-11-11 21:52:26 +01:00
188007ceb3 Add support for preferences dialogs
All checks were successful
Deploy Docs / publish (push) Successful in 20m26s
SwiftLint / SwiftLint (push) Successful in 5s
2024-11-05 13:18:37 +01:00
6229b85f46 Fix memory leaks
All checks were successful
Deploy Docs / publish (push) Successful in 21m49s
SwiftLint / SwiftLint (push) Successful in 5s
2024-10-31 23:00:50 +01:00
6bf6df0c6f Fix about dialog setting previous state
All checks were successful
Deploy Docs / publish (push) Successful in 21m20s
SwiftLint / SwiftLint (push) Successful in 5s
2024-10-30 09:20:09 +01:00
d93bc321a2 Make breakpoints check condition when initializing
All checks were successful
Deploy Docs / publish (push) Successful in 21m20s
SwiftLint / SwiftLint (push) Successful in 5s
2024-10-28 21:59:59 +01:00
e2da50703c Add padding option to natural width and height
All checks were successful
Deploy Docs / publish (push) Successful in 22m10s
SwiftLint / SwiftLint (push) Successful in 4s
2024-10-26 21:08:50 +02:00
2d12c57236 Set a scroll view's scroll bar policies
All checks were successful
Deploy Docs / publish (push) Successful in 20m49s
SwiftLint / SwiftLint (push) Successful in 4s
2024-10-26 18:44:31 +02:00
356eec00a9 Replace GtkSpinner with AdwSpinner
All checks were successful
Deploy Docs / publish (push) Successful in 21m36s
SwiftLint / SwiftLint (push) Successful in 5s
2024-10-26 17:32:45 +02:00
ced07e4293 Add support for natural sizes for breakpoints
All checks were successful
Deploy Docs / publish (push) Successful in 21m0s
SwiftLint / SwiftLint (push) Successful in 5s
2024-10-25 14:02:45 +02:00
e7c81dba1d Do not compare bindings before updating
All checks were successful
Deploy Docs / publish (push) Successful in 21m8s
SwiftLint / SwiftLint (push) Successful in 4s
2024-10-22 13:11:48 +02:00
963a02b1e1 Add support for AdwBreakpointBin
All checks were successful
Deploy Docs / publish (push) Successful in 21m42s
SwiftLint / SwiftLint (push) Successful in 3s
2024-10-21 18:30:10 +02:00
016425e329 Make view switcher dynamic
Some checks failed
Deploy Docs / publish (push) Successful in 19m25s
SwiftLint / SwiftLint (push) Failing after 1s
2024-10-19 22:50:41 +02:00
8c50494c74 Fix view switcher not updating selection
Some checks failed
Deploy Docs / publish (push) Successful in 19m56s
SwiftLint / SwiftLint (push) Failing after 1s
2024-10-19 21:54:38 +02:00
4913c0a382 Update view switcher option protocol
Some checks failed
Deploy Docs / publish (push) Successful in 20m36s
SwiftLint / SwiftLint (push) Failing after 1s
2024-10-19 20:36:19 +02:00
c893a8f0c6 Add option to pass custom array to view switcher
Some checks failed
SwiftLint / SwiftLint (push) Waiting to run
Deploy Docs / publish (push) Has been cancelled
2024-10-19 20:28:08 +02:00
169 changed files with 6275 additions and 4310 deletions

View File

@ -31,7 +31,7 @@ jobs:
echo "<script>window.location.href += \"/documentation/adwaita\"</script><p>Please enable JavaScript to view the documentation <a href='/documentation/adwaita'>here</a>.</p>" > docs/index.html;
sed -i '' 's/,2px/,10px/g' docs/css/index.*.css
- name: Upload
uses: wangyucode/sftp-upload-action@v2.0.2
uses: wangyucode/sftp-upload-action@v2.0.4
with:
host: 'volans.uberspace.de'
username: 'akforum'

View File

@ -154,5 +154,5 @@ type_contents_order:
- other_method
excluded:
- Sources/Core/View/Generated/
- Sources/Adwaita/View/Generated/
- .build/

View File

@ -1,4 +1,4 @@
// swift-tools-version: 6.0
// swift-tools-version: 6.1
//
// Package.swift
// Adwaita
@ -8,40 +8,44 @@
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(.v10_15), .iOS(.v13), .tvOS(.v13), .watchOS(.v6), .macCatalyst(.v13)],
platforms: [.macOS(.v13), .iOS(.v13), .tvOS(.v13), .watchOS(.v6), .macCatalyst(.v13)],
products: [
.library(
name: "Adwaita",
targets: ["Adwaita"]
),
.library(
name: "Core",
targets: ["Core"]
),
.library(
name: "CAdw",
targets: ["CAdw"]
)
],
dependencies: [
.package(url: "https://git.aparoksha.dev/aparoksha/meta", from: "0.1.0"),
.package(url: "https://git.aparoksha.dev/aparoksha/meta-sqlite", from: "0.1.0"),
.package(
url: "https://git.aparoksha.dev/aparoksha/levenshtein-transformations",
from: "0.1.0"
),
.package(url: "https://github.com/CoreOffice/XMLCoder", from: "0.17.1")
],
traits: [.trait(name: "exposeGeneratedAppearUpdateFunctions")],
dependencies: dependencies,
targets: [
.systemLibrary(
name: "CAdw",
pkgConfig: "libadwaita-1"
),
.target(
name: "Core",
name: "Adwaita",
dependencies: [
"CAdw",
.product(name: "LevenshteinTransformations", package: "levenshtein-transformations"),
@ -49,10 +53,6 @@ let package = Package(
.product(name: "MetaSQLite", package: "meta-sqlite")
]
),
.target(
name: "Adwaita",
dependencies: ["Core"]
),
.executableTarget(
name: "Generation",
dependencies: [

View File

@ -66,7 +66,7 @@ Find more information about the project's motivation in [this blog post](https:/
It is recommended to develop apps inside of a Flatpak.
That way, you don't have to install Swift or any of the dependencies on your system, and you always have access to the latest versions.
Take a look at the [template repository](https://github.com/AparokshaUI/AdwaitaTemplate).
Take a look at the [template repository](https://git.aparoksha.dev/aparoksha/adwaita-template).
This works on Linux only.
#### Directly on System
@ -92,7 +92,7 @@ brew install libadwaita
## Usage
I recommend using the [template repository](https://github.com/AparokshaUI/AdwaitaTemplate) as a starting point.
I recommend using the [template repository](https://git.aparoksha.dev/aparoksha/adwaita-template) as a starting point.
Follow the [interactive tutorial](https://adwaita-swift.aparoksha.dev//tutorials/table-of-contents) or [read the docs](https://adwaita-swift.aparoksha.dev/) in order to get to know _Adwaita for Swift_.

View File

@ -1,17 +0,0 @@
//
// ActionRow+.swift
// Adwaita
//
// Created by david-swift on 16.10.24.
//
extension ActionRow {
/// Deemphasize the row title and emphasize the subtitle.
/// - Parameter active: Whether the style is currently applied.
/// - Returns: A view.
public func property(_ active: Bool = true) -> AnyView {
style("property", active: active)
}
}

View File

@ -1,24 +0,0 @@
//
// 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

@ -33,7 +33,7 @@ public class AdwaitaApp: AppStorage {
/// - Parameter id: The identifier.
public required init(id: String) {
pointer = adw_application_new(id, G_APPLICATION_DEFAULT_FLAGS)?.cast()
DatabaseInformation.setPath(Self.userDataDir().appendingPathComponent("data.sqlite").path)
DatabaseInformation.setPath(Self.userDataDir().appendingPathComponent("\(id).sqlite").path)
}
/// Copy a string to the clipboard.
@ -100,7 +100,9 @@ public class AdwaitaApp: AppStorage {
g_action_map_add_action(.init(pointer), action)
signals[id] = data
}
gtk_application_set_accels_for_action(pointer, (window == nil ? "app." : "win.") + id, [shortcut].cArray)
let array = [shortcut].cArray
gtk_application_set_accels_for_action(pointer, (window == nil ? "app." : "win.") + id, array)
array?.deallocate()
}
/// Remove a keyboard shortcut from the application.

View File

@ -0,0 +1,23 @@
//
// 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

@ -29,7 +29,7 @@ public enum Icon {
}
/// A preinstalled icon.
public enum DefaultIcon: String {
public enum DefaultIcon: String, CaseIterable {
// swiftlint:disable missing_docs identifier_name
case acAdapter
case accessoriesCalculator
@ -40,7 +40,6 @@ public enum Icon {
case addressBookNew
case airplaneMode
case alarm
case appRemove
case appletsScreenshooter
case applicationCertificate
case applicationExitRtl
@ -288,7 +287,6 @@ public enum Icon {
case functionLinear
case gestureSwipeLeft
case gestureSwipeRight
case gnomeDisksStateStandby
case gnomePowerManager
case goBottom
case goDown
@ -301,12 +299,6 @@ public enum Icon {
case goPrevious
case goTop
case goUp
case goaAccountExchange
case goaAccountGoogle
case goaAccountLastfm
case goaAccountMsn
case goaAccountOwncloud
case goaAccount
case goaPanel
case gtk3Demo
case gtk3WidgetFactory
@ -317,7 +309,6 @@ public enum Icon {
case imageLoading
case imageMissing
case imageXGeneric
case info
case inodeDirectory
case inputDialpad
case inputGaming
@ -343,13 +334,6 @@ public enum Icon {
case langTypedef
case langUnion
case langVariable
case libreofficeBase
case libreofficeCalc
case libreofficeDraw
case libreofficeImpress
case libreofficeMain
case libreofficeMath
case libreofficeWriter
case listAdd
case listDragHandle
case listRemoveAll
@ -469,9 +453,6 @@ public enum Icon {
case networkWorkgroup
case nightLightDisabled
case nightLight
case nmDeviceWiredSecure
case nmDeviceWired
case nmDeviceWwan
case nonStarred
case notificationsDisabled
case objectFlipHorizontal
@ -480,70 +461,6 @@ public enum Icon {
case objectRotateRight
case objectSelect
case openMenu
case orca
case fedoraprojectAnacondaInstaller = "org.fedoraproject.AnacondaInstaller"
case freedesktopMalcontentControl = "org.freedesktop.MalcontentControl"
case gnomeAdwaita1Demo = "org.gnome.Adwaita1.Demo"
case gnomeBoxes = "org.gnome.Boxes"
case gnomeBuilder = "org.gnome.Builder"
case gnomeCalculator = "org.gnome.Calculator"
case gnomeCharacters = "org.gnome.Characters"
case gnomeCheese = "org.gnome.Cheese"
case gnomeConsole = "org.gnome.Console"
case gnomeDiskUtility = "org.gnome.DiskUtility"
case gnomeEpiphany = "org.gnome.Epiphany"
case gnomeEvince = "org.gnome.Evince"
case gnomeLogs = "org.gnome.Logs"
case gnomeMaps = "org.gnome.Maps"
case gnomeNautilus = "org.gnome.Nautilus"
case gnomePhotos = "org.gnome.Photos"
case gnomeRhythmbox3 = "org.gnome.Rhythmbox3"
case gnomeSettingsAbout = "org.gnome.Settings-about"
case gnomeSettingsAccessibility = "org.gnome.Settings-accessibility"
case gnomeSettingsAppearance = "org.gnome.Settings-appearance"
case gnomeSettingsApplications = "org.gnome.Settings-applications"
case gnomeSettingsBluetooth = "org.gnome.Settings-bluetooth"
case gnomeSettingsCamera = "org.gnome.Settings-camera"
case gnomeSettingsColor = "org.gnome.Settings-color"
case gnomeSettingsDefaultApps = "org.gnome.Settings-default-apps"
case gnomeSettingsDiagnostics = "org.gnome.Settings-diagnostics"
case gnomeSettingsDisplay = "org.gnome.Settings-display"
case gnomeSettingsFileHistory = "org.gnome.Settings-file-history"
case gnomeSettingsKeyboard = "org.gnome.Settings-keyboard"
case gnomeSettingsLocation = "org.gnome.Settings-location"
case gnomeSettingsMicrophone = "org.gnome.Settings-microphone"
case gnomeSettingsMobileNetwork = "org.gnome.Settings-mobile-network"
case gnomeSettingsMouse = "org.gnome.Settings-mouse"
case gnomeSettingsMultitasking = "org.gnome.Settings-multitasking"
case gnomeSettingsNetwork = "org.gnome.Settings-network"
case gnomeSettingsNotifications = "org.gnome.Settings-notifications"
case gnomeSettingsOnlineAccounts = "org.gnome.Settings-online-accounts"
case gnomeSettingsPower = "org.gnome.Settings-power"
case gnomeSettingsPinters = "org.gnome.Setting-printers"
case gnomeSettingsRegion = "org.gnome.Settings-region"
case gnomeSettingsRemovableMedia = "org.gnome.Settings-removable-media"
case gnomeSettingsSearch = "org.gnome.Settings-search"
case gnomeSettingsSharing = "org.gnome.Settings-sharing"
case gnomeSettingsSound = "org.gnome.Settings-sound"
case gnomeSettings = "org.gnome.Settings"
case gnomeSettingsSystemLockScreen = "org.gnome.Settings-system-lock-screen"
case gnomeSettingsThunderbolt = "org.gnome.Settings-thunderbolt"
case gnomeSettingsTime = "org.gnome.Settings-time"
case gnomeSettingsUsers = "org.gnome.Settings-users"
case gnomeSettingsWacom = "org.gnome.Settings-wacom"
case gnomeShellExtensions = "org.gnome.Shell.Extensions"
case gnomeSoftware = "org.gnome.Software"
case gnomeSystemMonitor = "org.gnome.SystemMonitor"
case gnomeTextEditor = "org.gnome.TextEditor"
case gnomeTotem = "org.gnome.Totem"
case gnomeWeather = "org.gnome.Weather"
case gnomeYelp = "org.gnome.Yelp"
case gnomeBaobab = "org.gnome.baobab"
case gnomeClocks = "org.gnome.clocks"
case gnomeDesignIconLibrary = "org.gnome.design.IconLibrary"
case gnomeEog = "org.gnome.eog"
case gnomeFontViewer = "org.gnome.font-viewer"
case gnomeTweaks = "org.gnome.tweaks"
case gtkDemo4 = "org.gtk.Demo4"
case gtkIconBrowser4 = "org.gtk.IconBrowser4"
case gtkPrintEditor4 = "org.gtk.PrintEditor4"
@ -554,18 +471,12 @@ public enum Icon {
case orientationPortraitInverse
case orientationPortraitLeft
case orientationPortraitRight
case orientationProtrait
case orientationPortrait
case packageXGeneric
case panDown
case panEnd
case panStart
case panUp
case panelBottom
case panelCenter
case panelLeft
case panelModified
case panelRight
case panelTop
case pda
case phoneAppleIphone
case phoneOld
@ -629,7 +540,6 @@ public enum Icon {
case sidebarShow
case softwareUpdateAvailable
case softwareUpdateUrgent
case speedometer
case starNew
case starred
case startHere
@ -652,13 +562,11 @@ public enum Icon {
case tablet
case taskDue
case taskPastDue
case temperature
case textEditor
case textXGeneric
case thunderboltAcquiring
case thunderbolt
case toolsCheckSpelling
case totemTv
case touchDisabled
case touchpadDisabled
case tv
@ -681,7 +589,7 @@ public enum Icon {
case valueDecrease
case valueIncrease
case videoDisplay
case videoJoineDisplays
case videoJoinedDisplays
case videoSingleDisplay
case videoXGeneric
case viewAppGrid
@ -716,7 +624,6 @@ public enum Icon {
case weatherFewCloudsNight
case weatherFewClouds
case weatherFog
case weatherHourly
case weatherOvercast
case weatherSevereAlert
case weatherShowersScattered

View File

@ -0,0 +1,27 @@
//
// ContentFit.swift
// Adwaita
//
// Created by david-swift on 19.07.24.
//
import CAdw
/// The visibility of a scroll bar.
public enum ScrollbarVisibility: UInt32 {
/// The scrollbar is always visible. The view size is independent of the content.
case alwaysVisible
/// The scrollbar will appear and disappear as necessary.
case automatic
/// The scrollbar should never appear. In this mode the content determines the size.
case never
/// Dont show a scrollbar, but dont force the size to follow the content.
case external
/// The ScrollbarVisibility value as a GtkPolicyType value.
var gtkValue: GtkPolicyType {
.init(rawValue)
}
}

View File

@ -0,0 +1,25 @@
//
// ToolbarStyle.swift
// Adwaita
//
// Created by david-swift on 15.04.25.
//
import CAdw
/// The top and bottom bar styles.
public enum ToolbarStyle: UInt32 {
/// No background, shadow only for scrolled content.
case flat
/// Opaque background with a persistent shadow.
case raised
/// Opaque background with a persistent border.
case raisedBorder
/// The ToolbarStyle value as an AdwToolbarStyle value.
var gtkValue: AdwToolbarStyle {
.init(rawValue)
}
}

View File

@ -0,0 +1,54 @@
//
// WrapMode.swift
// Adwaita
//
// Created by mlm on 24.08.25.
//
import CAdw
/// Wrap modes for `TextView`/`TextEditor`
public enum WrapMode: GtkWrapMode, RawRepresentable {
// swiftlint:disable discouraged_none_name
/// GTK_WRAP_NONE
case none
// swiftlint:enable discouraged_none_name
/// GTK_WRAP_CHAR
case char
/// GTK_WRAP_WORD
case word
/// GTK_WRAP_WORD_CHAR
case wordChar
/// Get the GtkWrapMode.
public var rawValue: GtkWrapMode {
switch self {
case .none:
GTK_WRAP_NONE
case .char:
GTK_WRAP_CHAR
case .word:
GTK_WRAP_WORD
case .wordChar:
GTK_WRAP_WORD_CHAR
}
}
/// Initialize from the GtkWrapMode.
/// - Parameter rawValue: The GtkWrapMode.
public init?(rawValue: GtkWrapMode) {
switch rawValue {
case GTK_WRAP_NONE:
self = .none
case GTK_WRAP_CHAR:
self = .char
case GTK_WRAP_WORD:
self = .word
case GTK_WRAP_WORD_CHAR:
self = .wordChar
default:
return nil
}
}
}

View File

@ -5,6 +5,8 @@
// Created by david-swift on 15.01.24.
//
import CAdw
extension Bool {
/// Get the gboolean for C.

View File

@ -0,0 +1,19 @@
//
// GtkWrapMode.swift
// Adwaita
//
// Created by mlm on 24.08.25.
//
import CAdw
/// Add ExpressibleByIntegerLiteral conformance to make GtkWrapMode usable as
/// a RawValue in an enum.
extension GtkWrapMode: @retroactive ExpressibleByIntegerLiteral {
/// Initialize from an integer literal.
public init(integerLiteral value: Int) {
self.init(UInt32(value))
}
}

View File

@ -78,6 +78,20 @@ public struct Idle {
/// An idle handler.
class IdleHandler {
/// Execute the function.
/// - Parameter pointer: The closure wrapper's pointer.
static func run(pointer: gpointer?) -> Int32 {
if let pointer {
let container = Unmanaged<ClosureContainer>.fromOpaque(pointer).takeUnretainedValue()
let result = container.closure()
if !result {
Unmanaged<ClosureContainer>.fromOpaque(pointer).release()
}
return result.cBool
}
return G_SOURCE_REMOVE
}
/// Add a function to be called whenever there are no higher priority events pending to the default main loop.
/// - Parameter closure: The function.
func add(_ closure: @escaping () -> Bool, priority: Int32, delay: Int64? = nil) {
@ -93,20 +107,6 @@ public struct Idle {
}
}
/// Execute the function.
/// - Parameter pointer: The closure wrapper's pointer.
static func run(pointer: gpointer?) -> Int32 {
if let pointer {
let container = Unmanaged<ClosureContainer>.fromOpaque(pointer).takeUnretainedValue()
let result = container.closure()
if !result {
Unmanaged<ClosureContainer>.fromOpaque(pointer).release()
}
return result.cBool
}
return G_SOURCE_REMOVE
}
}
/// A reference type holding a closure.

View File

@ -11,13 +11,15 @@ import CAdw
public class SignalData {
/// The closure.
public var closure: ([Any?]) -> Void
public var closure: ([Any?]) -> Any?
/// Destroy the class.
public var selfDestruction: (() -> Void)?
/// The closure as a C handler.
var handler: @convention(c) (UnsafeMutableRawPointer, UnsafeMutableRawPointer) -> Void {
{ _, data in
let data = unsafeBitCast(data, to: SignalData.self)
data.closure([])
_ = data.closure([])
}
}
@ -29,7 +31,7 @@ public class SignalData {
) -> Void {
{ _, arg1, data in
let data = unsafeBitCast(data, to: SignalData.self)
data.closure([arg1])
_ = data.closure([arg1])
}
}
@ -42,7 +44,7 @@ public class SignalData {
) -> Void {
{ _, arg1, arg2, data in
let data = unsafeBitCast(data, to: SignalData.self)
data.closure([arg1, arg2])
_ = data.closure([arg1, arg2])
}
}
@ -56,20 +58,49 @@ public class SignalData {
) -> Void {
{ _, arg1, arg2, arg3, data in
let data = unsafeBitCast(data, to: SignalData.self)
data.closure([arg1, arg2, arg3])
_ = data.closure([arg1, arg2, arg3])
}
}
/// The closure as a C handler with a return value.
var boolHandler: @convention(c) (UnsafeMutableRawPointer, UnsafeMutableRawPointer) -> Bool {
{ _, data in
let data = unsafeBitCast(data, to: SignalData.self)
return data.closure([]) as? Bool ?? false
}
}
/// Initialize the signal data.
/// - Parameter closure: The signal's closure.
public convenience init(closure: @escaping () -> Void) {
self.init { _ in closure() }
/// - Parameters:
/// - closure: The signal's closure.
/// - destroy: The self destruction.
public convenience init(closure: @escaping () -> Any?, destroy: (() -> Void)? = nil) {
self.init(closure: { _ in closure() }, destroy: destroy)
}
/// Initialize the signal data.
/// - Parameter closure: The signal's closure.
public init(closure: @escaping ([Any]) -> Void) {
/// - Parameters:
/// - closure: The signal's closure.
/// - destroy: The self destruction.
public convenience init(closure: @escaping () -> Void, destroy: (() -> Void)? = nil) {
self.init(closure: { _ in closure(); return nil }, destroy: destroy)
}
/// Initialize the signal data.
/// - Parameters:
/// - closure: The signal's closure.
/// - destroy: The self destruction.
public init(closure: @escaping ([Any]) -> Any?, destroy: (() -> Void)? = nil) {
self.closure = closure
self.selfDestruction = destroy
}
/// The return type.
public enum ReturnType {
/// Returns a boolean.
case bool
}
/// Connect the signal data to a signal.
@ -77,9 +108,20 @@ public class SignalData {
/// - pointer: The pointer to the object which holds the signal.
/// - signal: The signal's name.
/// - argCount: The number of arguments.
public func connect(pointer: UnsafeMutableRawPointer?, signal: String, argCount: Int = 0) {
/// - return: The return type.
public func connect(
pointer: UnsafeMutableRawPointer?,
signal: String,
argCount: Int = 0,
return: ReturnType? = nil
) {
let callback: GCallback
if argCount >= 3 {
if let `return` {
switch `return` {
case .bool:
callback = unsafeBitCast(boolHandler, to: GCallback.self)
}
} else if argCount >= 3 {
callback = unsafeBitCast(fiveParamsHandler, to: GCallback.self)
} else if argCount == 2 {
callback = unsafeBitCast(fourParamsHandler, to: GCallback.self)
@ -88,12 +130,19 @@ public class SignalData {
} else {
callback = unsafeBitCast(handler, to: GCallback.self)
}
let destroy: GClosureNotify = { data, _ in
guard let data else {
return
}
let signalData: SignalData = Unmanaged.fromOpaque(data).takeUnretainedValue()
signalData.selfDestruction?()
}
g_signal_connect_data(
pointer,
signal,
callback,
Unmanaged.passUnretained(self).toOpaque().cast(),
nil,
destroy,
G_CONNECT_AFTER
)
}

View File

@ -48,7 +48,30 @@ extension Storage {
pointer: OpaquePointer? = nil,
handler: @escaping () -> Void
) {
connectSignal(name: name, id: id, argCount: argCount, pointer: pointer) { _ in
connectSignal(name: name, id: id, argCount: argCount, pointer: pointer) {
handler()
return nil
}
}
/// Connect a handler to a signal.
/// - Parameters:
/// - name: The signal's name.
/// - id: The handlers id to separate form others connecting to the signal.
/// - connectFlags: The GConnectFlags.
/// - argCount: The number of additional arguments (without the first and the last one).
/// - return: The return type.
/// - pointer: A custom pointer instead of the stored one.
/// - handler: The signal's handler.
public func connectSignal(
name: String,
id: String = "",
argCount: Int = 0,
return: SignalData.ReturnType? = nil,
pointer: OpaquePointer? = nil,
handler: @escaping () -> Any?
) {
connectSignal(name: name, id: id, argCount: argCount, return: `return`, pointer: pointer) { _ in
handler()
}
}
@ -66,13 +89,42 @@ extension Storage {
argCount: Int = 0,
pointer: OpaquePointer? = nil,
handler: @escaping ([Any]) -> Void
) {
connectSignal(name: name, id: id, argCount: argCount, pointer: pointer) { args in
handler(args)
return nil
}
}
/// Connect a handler to a signal.
/// - Parameters:
/// - name: The signal's name.
/// - id: The handlers id to separate form others connecting to the signal.
/// - argCount: The number of additional arguments (without the first and the last one).
/// - return: The return type.
/// - pointer: A custom pointer instead of the stored one.
/// - handler: The signal's handler.
public func connectSignal(
name: String,
id: String = "",
argCount: Int = 0,
return: SignalData.ReturnType? = nil,
pointer: OpaquePointer? = nil,
handler: @escaping ([Any]) -> Any?
) {
if let data = fields[name + id] as? SignalData {
data.closure = handler
} else {
let data = SignalData(closure: handler)
let data = SignalData(closure: handler) { [self] in fields[name + id] = nil }
fields[name + id] = data
data.connect(pointer: (pointer ?? opaquePointer)?.cast(), signal: name, argCount: argCount)
data.connect(
pointer: (
pointer ?? opaquePointer ?? ((self as? SceneStorage)?.pointer as? AdwaitaWindow)?.pointer?.opaque()
)?.cast(),
signal: name,
argCount: argCount,
return: `return`
)
}
}

View File

@ -1,17 +0,0 @@
//
// StatusPage+.swift
// Adwaita
//
// Created by david-swift on 16.10.24.
//
extension StatusPage {
/// Make the status page more compact.
/// - Parameter active: Whether the style is applied.
/// - Returns: A view.
public func compact(_ active: Bool = true) -> AnyView {
style("compact", active: active)
}
}

View File

@ -108,6 +108,13 @@ 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.
@ -271,13 +278,6 @@ 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,22 +336,58 @@ extension AnyView {
}
/// Add CSS classes to the app as soon as the view appears.
/// - Parameter getString: Get the CSS.
/// - Parameters:
/// - scheme: The color scheme.
/// - getString: Get the CSS.
/// - Returns: A view.
public func css(_ getString: @escaping () -> String) -> AnyView {
inspectOnAppear { _ in
let provider = gtk_css_provider_new()
gtk_css_provider_load_from_string(
provider,
getString()
)
let display = gdk_display_get_default()
gtk_style_context_add_provider_for_display(
display,
provider?.opaque(),
.init(GTK_STYLE_PROVIDER_PRIORITY_APPLICATION)
)
public func css(scheme: ColorScheme? = nil, getString: @escaping () -> String) -> AnyView {
wrap { 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
)
let display = gdk_display_get_default()
gtk_style_context_add_provider_for_display(
display,
provider?.opaque(),
.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

@ -5,7 +5,7 @@
// Created by david-swift on 16.10.24.
//
@_exported import Core
import CAdw
import Foundation
extension AnyView {
@ -45,6 +45,8 @@ extension AnyView {
/// - visible: Whether the dialog is presented.
/// - heading: The heading.
/// - body: The body text.
/// - id: An optional identifier.
/// - extraChild: A view with custom content.
public func alertDialog(
visible: Binding<Bool>,
heading: String,
@ -60,6 +62,30 @@ extension AnyView {
)
}
/// Add an alert dialog to the parent window.
/// - Parameters:
/// - visible: Whether the dialog is presented.
/// - heading: The heading.
/// - body: The body text.
/// - id: An optional identifier.
/// - extraChild: A view with custom content.
public func alertDialog(
visible: Binding<Bool>,
heading: String,
body: String = "",
id: String? = nil,
@ViewBuilder extraChild: () -> Body
) -> AlertDialog {
.init(
visible: visible,
child: self,
id: id ?? "no-id",
heading: heading,
body: body,
extraChild: extraChild()
)
}
/// Add a dialog to the parent window.
/// - Parameters:
/// - visible: Whether the dialog is presented.
@ -86,12 +112,43 @@ extension AnyView {
)
}
/// Add a preferences dialog to the parent window.
/// - Parameters:
/// - visible: Whether the dialog is presented.
/// - id: The dialog's id.
/// - Returns: The view.
public func preferencesDialog(
visible: Binding<Bool>,
id: String? = nil
) -> PreferencesDialog {
.init(
visible: visible,
child: self,
id: id ?? ""
)
}
/// Add a shortcuts dialog to the parent window.
/// - Parameters:
/// - visible: Whether the dialog is presented.
/// - id: The dialog's id.
/// - Returns: The view.
public func shortcutsDialog(
visible: Binding<Bool>,
id: String? = nil
) -> ShortcutsDialog {
.init(
visible: visible,
child: self,
id: id ?? ""
)
}
/// Create an importer file dialog.
/// - Parameters:
/// - open: The signal to open the dialog.
/// - initialFolder: The URL to the folder open when being opened.
/// - extensions: The accepted file extensions.
/// - folders: Whether folders are accepted.
/// - onOpen: Run this when a file for importing has been chosen.
/// - onClose: Run this when the user cancelled the action.
public func fileImporter(
@ -99,17 +156,37 @@ extension AnyView {
initialFolder: URL? = nil,
extensions: [String]? = nil,
onOpen: @escaping (URL) -> Void,
onClose: @escaping () -> Void
onClose: @escaping () -> Void = { }
) -> AnyView {
FileDialog(
importer: true,
type: .importer(folder: false, extensions: extensions),
open: open,
child: self,
result: onOpen,
cancel: onClose,
initialFolder: initialFolder,
initialName: nil,
extensions: extensions
initialFolder: initialFolder
)
}
/// Create an importer file dialog for folders.
/// - Parameters:
/// - open: The signal to open the dialog.
/// - initialFolder: The URL to the folder open when being opened.
/// - onOpen: Run this when a file for importing has been chosen.
/// - onClose: Run this when the user cancelled the action.
public func folderImporter(
open: Signal,
initialFolder: URL? = nil,
onOpen: @escaping (URL) -> Void,
onClose: @escaping () -> Void = { }
) -> AnyView {
FileDialog(
type: .importer(folder: true, extensions: nil),
open: open,
child: self,
result: onOpen,
cancel: onClose,
initialFolder: initialFolder
)
}
@ -125,16 +202,15 @@ extension AnyView {
initialFolder: URL? = nil,
initialName: String? = nil,
onSave: @escaping (URL) -> Void,
onClose: @escaping () -> Void
onClose: @escaping () -> Void = { }
) -> AnyView {
FileDialog(
importer: false,
type: .exporter(initialName: initialName),
open: open,
child: self,
result: onSave,
cancel: onClose,
initialFolder: initialFolder,
initialName: initialName
initialFolder: initialFolder
)
}
@ -168,82 +244,6 @@ 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)
}
/// 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.
@ -267,4 +267,43 @@ extension AnyView {
.action(button: button, handler: handler)
}
/// Add a breakpoint.
/// - Parameters:
/// - maxWidth: The maximum width.
/// - matches: Whether the content view matches the breakpoint.
public func breakpoint(maxWidth: Int, matches: Binding<Bool>) -> AnyView {
BreakpointBin(condition: .maxWidth(maxWidth), matches: matches) { self }
}
/// Add a breakpoint.
/// - Parameters:
/// - minWidth: The minimum width.
/// - matches: Whether the content view matches the breakpoint.
public func breakpoint(minWidth: Int, matches: Binding<Bool>) -> AnyView {
BreakpointBin(condition: .minWidth(minWidth), matches: matches) { self }
}
/// Add a breakpoint.
/// - Parameters:
/// - maxHeight: The maximum height.
/// - matches: Whether the content view matches the breakpoint.
public func breakpoint(maxHeight: Int, matches: Binding<Bool>) -> AnyView {
BreakpointBin(condition: .maxHeight(maxHeight), matches: matches) { self }
}
/// Add a breakpoint.
/// - Parameters:
/// - minHeight: The minimum height.
/// - matches: Whether the content view matches the breakpoint.
public func breakpoint(minHeight: Int, matches: Binding<Bool>) -> AnyView {
BreakpointBin(condition: .minHeight(minHeight), matches: matches) { self }
}
/// Build the UI from scratch once the identifier changes.
/// - Parameter id: The identifier.
public func id(_ id: CustomStringConvertible) -> AnyView {
ViewStack(id: id) { _ in self }
.limitChildren()
}
}

View File

@ -0,0 +1,123 @@
//
// 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

@ -0,0 +1,154 @@
//
// BreakpointBin.swift
// Adwaita
//
// Created by david-swift on 21.10.24.
//
import CAdw
import Meta
/// Bind a dimension's to observe whether the child view matches a condition.
public struct BreakpointBin: AdwaitaWidget {
/// The child view.
@ViewProperty(
set: { bin, view in
var width: Int32 = 0
var height: Int32 = 0
gtk_widget_measure(view.cast(), GTK_ORIENTATION_VERTICAL, -1, &height, nil, nil, nil)
gtk_widget_measure(view.cast(), GTK_ORIENTATION_HORIZONTAL, -1, &width, nil, nil, nil)
gtk_widget_set_size_request(bin.cast(), width, height)
adw_breakpoint_bin_set_child(bin.cast(), view.cast())
},
pointer: OpaquePointer.self,
subview: OpaquePointer.self,
context: AdwaitaMainView.self
)
var content
/// The condition.
@Property(
set: { bin, condition, storage in
var condition = condition
switch condition {
case let .naturalWidth(padding):
let child = adw_breakpoint_bin_get_child(bin.cast())
var size: Int32 = 0
gtk_widget_measure(child, GTK_ORIENTATION_HORIZONTAL, -1, nil, &size, nil, nil)
condition = .minWidth(.init(size) + padding)
case let .naturalHeight(padding):
let child = adw_breakpoint_bin_get_child(bin.cast())
var size: Int32 = 0
gtk_widget_measure(child, GTK_ORIENTATION_VERTICAL, -1, nil, &size, nil, nil)
condition = .minHeight(.init(size) + padding)
default:
break
}
storage.fields["condition"] = condition
let string = adw_breakpoint_condition_parse(condition.condition)
if let breakpoint = storage.fields["breakpoint"] as? OpaquePointer {
g_object_unref(adw_breakpoint_get_condition(breakpoint)?.cast())
adw_breakpoint_set_condition(breakpoint, string)
} else {
let breakpoint = adw_breakpoint_new(string)
adw_breakpoint_bin_add_breakpoint(bin.cast(), breakpoint)
storage.fields["breakpoint"] = breakpoint
if let matches = storage.fields["binding"] as? Binding<Bool> {
Idle {
condition.initialize(child: adw_breakpoint_bin_get_child(bin.cast()), matches: matches)
}
}
}
},
pointer: OpaquePointer.self
)
var condition: BreakpointCondition = .maxWidth(0)
/// Whether the child view does not match the condition.
@BindingProperty(
observe: { bin, matches, storage in
storage.notify(name: "current-breakpoint") {
matches.wrappedValue = adw_breakpoint_bin_get_current_breakpoint(bin.cast()) != nil
}
storage.fields["binding"] = matches
},
set: { _, _, _ in },
pointer: OpaquePointer.self
)
var matches: Binding<Bool> = .constant(false)
/// Initialize a breakpoint bin.
/// - Parameters:
/// - condition: The condition.
/// - matches: Whether the content matches the condition.
/// - content: The content.
public init(
condition: BreakpointCondition,
matches: Binding<Bool>,
@ViewBuilder content: () -> Body
) {
self.condition = condition
self.matches = matches
self.content = content()
}
/// Initialize the widget.
public func initializeWidget() -> Any {
adw_breakpoint_bin_new()?.opaque() as Any
}
}
/// A breakpoint condition.
public enum BreakpointCondition: Equatable {
/// Define a maximum width.
case maxWidth(_ width: Int)
/// Define a maximum height.
case maxHeight(_ height: Int)
/// Define a minimum width.
case minWidth(_ width: Int)
/// Define a minimum height.
case minHeight(_ height: Int)
/// The minimum width is the content's natural width.
case naturalWidth(padding: Int = 0)
/// The minimum height is the content's natural height.
case naturalHeight(padding: Int = 0)
/// The condition to parse.
var condition: String? {
switch self {
case let .maxWidth(width):
"max-width: \(width)sp"
case let .maxHeight(height):
"max-height: \(height)sp"
case let .minWidth(width):
"min-width: \(width)sp"
case let .minHeight(height):
"min-height: \(height)sp"
default:
nil
}
}
/// Initialize the breakpoint when initializing the view.
/// - Parameters:
/// - child: The widget.
/// - matches: The matches binding.
func initialize(child: UnsafeMutablePointer<GtkWidget>?, matches: Binding<Bool>) {
switch self {
case let .maxWidth(width):
matches.wrappedValue = gtk_widget_get_width(child) <= width
case let .minWidth(width):
matches.wrappedValue = gtk_widget_get_width(child) >= width
case let .maxHeight(height):
matches.wrappedValue = gtk_widget_get_height(child) <= height
case let .minHeight(height):
matches.wrappedValue = gtk_widget_get_height(child) >= height
default:
break
}
}
}

View File

@ -45,8 +45,11 @@ extension Button {
/// - window: The application window.
/// - active: Whether the keyboard shortcut is active.
/// - Returns: The button.
public func keyboardShortcut(_ shortcut: String, window: AdwaitaWindow, active: Bool = true) -> AnyView {
onUpdate {
public func keyboardShortcut(_ shortcut: String, active: Bool = true) -> AnyView {
inspect { _, data, _ in
guard let window = data.sceneStorage.pointer as? AdwaitaWindow else {
return
}
if active {
window.app.addKeyboardShortcut(shortcut, id: shortcut, window: window) { self.clicked?() }
} else {
@ -63,12 +66,15 @@ extension Button {
/// - window: The application.
/// - active: Whether the keyboard shortcut is active.
/// - Returns: The button.
public func keyboardShortcut(_ shortcut: String, app: AdwaitaApp, active: Bool = true) -> AnyView {
onUpdate {
public func appKeyboardShortcut(_ shortcut: String, active: Bool = true) -> AnyView {
inspect { _, data, _ in
guard let window = data.sceneStorage.pointer as? AdwaitaWindow else {
return
}
if active {
app.addKeyboardShortcut(shortcut, id: shortcut) { self.clicked?() }
window.app.addKeyboardShortcut(shortcut, id: shortcut) { self.clicked?() }
} else {
app.removeKeyboardShortcut(id: shortcut)
window.app.removeKeyboardShortcut(id: shortcut)
}
}
}

View File

@ -9,7 +9,7 @@ import CAdw
import Foundation
/// The about dialog widget.
public struct AboutDialog: AdwaitaWidget {
struct AboutDialog: AdwaitaWidget {
/// Whether the dialog is visible.
@Binding var visible: Bool
@ -42,7 +42,7 @@ public struct AboutDialog: AdwaitaWidget {
/// - icon: The icon.
/// - website: The website's URL.
/// - issues: The link for opening issues.
public init(
init(
visible: Binding<Bool>,
child: AnyView,
appName: String? = nil,
@ -67,10 +67,8 @@ public struct AboutDialog: AdwaitaWidget {
/// - modifiers: Modify views before being updated.
/// - type: The view render data type.
/// - Returns: The view storage.
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
let storage = child.storage(data: data, type: type)
update(storage, data: data, updateProperties: true, type: type)
return storage
func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
child.storage(data: data, type: type)
}
/// Update the stored content.
@ -79,14 +77,14 @@ public struct AboutDialog: AdwaitaWidget {
/// - modifiers: Modify views before being updated
/// - updateProperties: Whether to update the view's properties.
/// - type: The view render data type.
public func update<Data>(
func update<Data>(
_ storage: ViewStorage,
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
child.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
guard updateProperties, (storage.previousState as? Self)?.visible != visible else {
guard updateProperties else {
return
}
if visible {
@ -119,10 +117,11 @@ public struct AboutDialog: AdwaitaWidget {
adw_dialog_set_content_height(dialog?.cast(), -1)
} else {
if storage.content[dialogID]?.first != nil {
adw_dialog_close(storage.content[dialogID]?.first?.opaquePointer?.cast())
let dialog = storage.content[dialogID]?.first?.opaquePointer
adw_dialog_close(dialog?.cast())
storage.content[dialogID] = []
}
}
storage.previousState = self
}
/// Create a new instance of the dialog.

View File

@ -28,6 +28,8 @@ public struct AlertDialog: AdwaitaWidget {
var heading: String
/// The body text.
var body: String
/// The body view.
var extraChild: Body?
/// The available responses.
var responses: [Response] = []
/// The child view.
@ -40,18 +42,21 @@ public struct AlertDialog: AdwaitaWidget {
/// - id: A unique identifier for dialogs on the view.
/// - heading: The heading.
/// - body: The body text.
public init(
/// - extraChild: The body view.
init(
visible: Binding<Bool>,
child: AnyView,
id: String,
heading: String,
body: String
body: String,
extraChild: Body? = nil
) {
self._visible = visible
self.child = child
self.id = id
self.heading = heading
self.body = body
self.extraChild = extraChild
}
/// Information about a response.
@ -101,9 +106,7 @@ public struct AlertDialog: AdwaitaWidget {
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let storage = child.storage(data: data, type: type)
update(storage, data: data, updateProperties: true, type: type)
return storage
child.storage(data: data, type: type)
}
/// Update the stored content.
@ -120,13 +123,18 @@ public struct AlertDialog: AdwaitaWidget {
) where Data: ViewRenderData {
storage.fields[Self.visibleID + id] = _visible
child.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
defer {
if let storage = storage.content["extra-child"]?.first, visible {
extraChild?.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
}
}
guard updateProperties else {
return
}
if visible {
var present = false
if storage.content[Self.dialogID + id]?.first == nil {
createDialog(storage: storage)
createDialog(storage: storage, data: data)
present = true
}
let pointer = storage.content[Self.dialogID + id]?.first?.opaquePointer
@ -135,10 +143,7 @@ public struct AlertDialog: AdwaitaWidget {
let old = storage.fields[Self.responsesID + id] as? [Response] ?? []
old.identifiableTransform(
to: responses,
functions: .init { index, element in
adw_alert_dialog_remove_response(pointer?.cast(), responseID(old[safe: index]?.id))
adw_alert_dialog_add_response(pointer?.cast(), responseID(element.id), element.title)
} delete: { index in
functions: .init { index in
adw_alert_dialog_remove_response(pointer?.cast(), responseID(old[safe: index]?.id))
} insert: { _, element in
adw_alert_dialog_add_response(pointer?.cast(), responseID(element.id), element.title)
@ -160,7 +165,9 @@ public struct AlertDialog: AdwaitaWidget {
}
} else {
if storage.content[Self.dialogID + id]?.first != nil {
adw_dialog_close(storage.content[Self.dialogID + id]?.first?.opaquePointer?.cast())
let dialog = storage.content[Self.dialogID + id]?.first?.opaquePointer
adw_dialog_close(dialog?.cast())
storage.content[Self.dialogID] = []
}
}
}
@ -199,11 +206,20 @@ public struct AlertDialog: AdwaitaWidget {
}
/// Create a new instance of the dialog.
/// - Parameter storage: The wrapped view's storage.
func createDialog(storage: ViewStorage) {
/// - Parameters:
/// - storage: The wrapped view's storage.
/// - data: The widget data.
func createDialog(storage: ViewStorage, data: WidgetData) {
let pointer = adw_alert_dialog_new(nil, nil)
let dialog = ViewStorage(pointer?.opaque())
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())
}
}
/// Get the identifier of a response which is combined with the dialog's id.

View File

@ -8,7 +8,7 @@
import CAdw
/// The dialog widget.
public struct Dialog: AdwaitaWidget {
struct Dialog: AdwaitaWidget {
/// Whether the dialog is visible.
@Binding var visible: Bool
@ -39,7 +39,7 @@ public struct Dialog: AdwaitaWidget {
/// - title: The title.
/// - width: The width.
/// - height: The height.
public init(
init(
visible: Binding<Bool>,
child: AnyView,
id: String,
@ -62,11 +62,9 @@ public struct Dialog: AdwaitaWidget {
/// - modifiers: Modify views before being updated.
/// - type: The view render data type.
/// - Returns: The view storage.
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
let child = child.storage(data: data, type: type)
let storage = ViewStorage(child.opaquePointer, content: [.mainContent: [child]])
update(storage, data: data, updateProperties: true, type: type)
return storage
return .init(child.opaquePointer, content: [.mainContent: [child]])
}
/// Update the stored content.
@ -75,7 +73,7 @@ public struct Dialog: AdwaitaWidget {
/// - modifiers: Modify views before being updated
/// - updateProperties: Whether to update the view's properties.
/// - type: The view render data type.
public func update<Data>(
func update<Data>(
_ storage: ViewStorage,
data: WidgetData,
updateProperties: Bool,
@ -111,7 +109,9 @@ public struct Dialog: AdwaitaWidget {
}
} else {
if storage.content[dialogID + id]?.first != nil {
adw_dialog_close(storage.content[dialogID + id]?.first?.opaquePointer?.cast())
let dialog = storage.content[dialogID + id]?.first?.opaquePointer
adw_dialog_close(dialog?.cast())
storage.content[dialogID + id] = []
}
}
}
@ -130,6 +130,7 @@ public 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

@ -9,67 +9,103 @@ import CAdw
import Foundation
/// A structure representing a file dialog window.
public struct FileDialog: AdwaitaWidget {
struct FileDialog: AdwaitaWidget {
/// Whether the dialog is an importer.
var importer: Bool
/// The dialog type.
var type: DialogType
/// Whether the dialog should open.
var open: Signal
/// The dialog's child.
var child: AnyView
/// The initial folder.
var initialFolder: URL?
/// The initial file name for the file exporter.
var initialName: String?
/// The accepted extensions for the file importer.
var extensions: [String]?
/// The closure to run when the import or export is successful.
var result: (URL) -> Void
/// The closure to run when the import or export is not successful.
var cancel: () -> Void
// swiftlint:disable function_default_parameter_at_end
/// Initialize the file dialog wrapper.
/// - Parameters:
/// - importer: Whether it is an importer.
/// - type: The dialog type.
/// - open: The signal.
/// - child: The wrapped view.
/// - initialFolder: The initial URL.
/// - initialName: The initial name.
/// - extensions: The file extensions.
/// - result: Run when the import or export succeeds.
/// - cancel: Run when the import or export is not successful.
public init(
importer: Bool = true,
/// - initialFolder: The initial folder.
init(
type: DialogType,
`open`: Signal,
child: AnyView,
result: @escaping (URL) -> Void,
cancel: @escaping () -> Void,
initialFolder: URL? = nil,
initialName: String? = nil,
extensions: [String]? = nil
) {
self.importer = importer
self.type = type
self.open = open
self.child = child
self.result = result
self.cancel = cancel
self.initialFolder = initialFolder
self.initialName = initialName
self.extensions = extensions
}
// swiftlint:enable function_default_parameter_at_end
/// The different types of dialogs and their properties.
enum DialogType {
/// An importer dialog.
case importer(folder: Bool, extensions: [String]?)
/// An exporter dialog.
case exporter(initialName: String?)
/// Whether the dialog is an importer.
var isImporter: Bool {
switch self {
case .importer:
true
default:
false
}
}
/// The supported extensions.
var extensions: [String]? {
switch self {
case let .importer(folder: _, extensions: extensions):
extensions
default:
nil
}
}
/// Whether to import folders.
var folder: Bool {
switch self {
case let .importer(folder: folder, extensions: _):
folder
default:
false
}
}
/// The initial name.
var initialName: String? {
switch self {
case let .exporter(initialName: initialName):
initialName
default:
nil
}
}
}
/// The view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The view render data type.
/// - Returns: The view storage.
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
let child = child.storage(data: data, type: type)
let storage = ViewStorage(child.opaquePointer, content: [.mainContent: [child]])
update(storage, data: data, updateProperties: true, type: type)
return storage
return .init(child.opaquePointer, content: [.mainContent: [child]])
}
/// Update the stored content.
@ -78,7 +114,7 @@ public struct FileDialog: AdwaitaWidget {
/// - modifiers: Modify views before being updated
/// - updateProperties: Whether to update the view's properties.
/// - type: The view render data type.
public func update<Data>(
func update<Data>(
_ storage: ViewStorage,
data: WidgetData,
updateProperties: Bool,
@ -89,32 +125,45 @@ public struct FileDialog: AdwaitaWidget {
guard let mainStorage = storage.content[.mainContent]?.first else {
return
}
child.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
child.updateStorage(mainStorage, data: data, updateProperties: updateProperties, type: type)
if open.update, storage.fields["callbacks"] == nil {
var unref: [OpaquePointer?] = []
let pointer = gtk_file_dialog_new()
if let initialName {
unref.append(pointer)
if let initialName = self.type.initialName {
gtk_file_dialog_set_initial_name(pointer, initialName)
}
if let extensions {
if let extensions = self.type.extensions {
let filter = gtk_file_filter_new()
for name in extensions {
gtk_file_filter_add_suffix(filter, name)
}
gtk_file_dialog_set_default_filter(pointer, filter)
unref.append(filter)
} else {
gtk_file_dialog_set_default_filter(pointer, nil)
}
if let initialFolder {
gtk_file_dialog_set_initial_folder(pointer, g_file_new_for_path(initialFolder.absoluteString))
let file = g_file_new_for_path(initialFolder.absoluteString)
gtk_file_dialog_set_initial_folder(pointer, file)
unref.append(file)
}
let callbacks = AdwaitaFileDialog()
callbacks.onResult = { (storage.fields["result"] as? (URL) -> Void)?($0) }
callbacks.onCancel = { (storage.fields["cancel"] as? () -> Void)?() }
let unrefClosure = {
for ref in unref {
g_object_unref(ref?.cast())
}
storage.fields["callbacks"] = nil
}
callbacks.onResult = { (storage.fields["result"] as? (URL) -> Void)?($0); unrefClosure() }
callbacks.onCancel = { (storage.fields["cancel"] as? () -> Void)?(); unrefClosure() }
callbacks.reset = { storage.fields["callbacks"] = nil }
storage.fields["callbacks"] = callbacks
let ptr = UInt64(Int(bitPattern: pointer))
let window = UInt64(Int(bitPattern: gtk_widget_get_root(mainStorage.opaquePointer?.cast())))
if importer {
if self.type.isImporter && self.type.folder {
gtui_filedialog_open_folder(ptr, unsafeBitCast(callbacks, to: UInt64.self), window)
} else if self.type.isImporter {
gtui_filedialog_open(ptr, unsafeBitCast(callbacks, to: UInt64.self), window)
} else {
gtui_filedialog_save(ptr, unsafeBitCast(callbacks, to: UInt64.self), window)
@ -135,8 +184,9 @@ class AdwaitaFileDialog {
var reset: () -> Void = { }
/// Initialize the window callback.
init() {
}
init() { }
deinit { print("DEINIT fd") }
/// Run this when a file gets opened.
/// - Parameter path: The file path.

View File

@ -0,0 +1,252 @@
//
// PreferencesDialog.swift
// Adwaita
//
// Created by david-swift on 04.11.24.
//
import CAdw
/// The preferences dialog widget.
public struct PreferencesDialog: AdwaitaWidget {
/// Whether the dialog is visible.
@Binding var visible: Bool
/// An identifier used if multiple dialogs are on one view.
var id: String
/// The settings dialog pages.
var pages: [PreferencesPage] = []
/// The content.
var child: AnyView
/// The ID for the dialog's storage.
let dialogID = "dialog"
/// The ID for the content's storage.
let contentID = "content"
/// Initialize a dialog wrapper.
/// - Parameters:
/// - visible: Whether the dialog is visible.
/// - child: The wrapped view.
/// - id: An unique identifier for dialogs on the view.
init(
visible: Binding<Bool>,
child: AnyView,
id: String
) {
self._visible = visible
self.child = child
self.id = id
}
/// A preferences page.
public struct PreferencesPage {
/// The page's title.
var title: String
/// The page's icon.
var icon: Icon
/// The page content.
var content: [PreferencesGroup] = []
/// Initialize the preferences page.
/// - Parameters:
/// - title: The page title.
/// - icon: The page's icon.
init(_ title: String, icon: Icon) {
self.title = title
self.icon = icon
}
/// Get the GTK preferences page as well as the group's view storages.
/// - Parameter data: The widget data.
/// - Returns: The preferences page pointer and the groups view storages.
func gtkPreferencesPage(data: WidgetData) -> (OpaquePointer?, [ViewStorage]) {
let page = Adwaita.PreferencesPage()
.title(title)
.iconName(icon.string)
let pageStorage = page.storage(data: data.noModifiers, type: AdwaitaMainView.self)
page.update(pageStorage, data: data, updateProperties: true, type: AdwaitaMainView.self)
let groups = content.map { item in
let storage = item.gtkPreferencesGroup(data: data)
item.update(group: storage, data: data, updateProperties: true)
adw_preferences_page_add(pageStorage.opaquePointer?.cast(), storage.opaquePointer?.cast())
return storage
}
return (pageStorage.opaquePointer, groups)
}
/// Update the page.
/// - Parameters:
/// - groups: The groups' view storages.
/// - data: The widget data.
/// - updateProperties: Whether to update the properties.
func update(groups: [ViewStorage], data: WidgetData, updateProperties: Bool) {
for (index, storage) in groups.enumerated() {
content[safe: index]?.update(group: storage, data: data, updateProperties: updateProperties)
}
}
/// Add a preferences group.
/// - Parameters:
/// - title: The group's title.
/// - description: The group's description.
/// - child: The view child.
public func group(
_ title: String,
description: String = "",
@ViewBuilder child: () -> Body
) -> Self {
var newSelf = self
newSelf.content.append(
.init(
title: title,
description: description,
child: child()
)
)
return newSelf
}
}
/// The preferences group.
struct PreferencesGroup {
/// The group's title.
var title: String
/// The group's description.
var description: String
/// The group's child view.
var child: Body
/// Get the GTk preferences group.
/// - Parameter data: The widget data.
/// - Returns: The preferences group.
func group(data: WidgetData) -> Adwaita.PreferencesGroup {
.init()
.title(title)
.description(description)
.child { child }
}
/// Get the GTK preferences group's storage.
/// - Parameter data: The widget data.
/// - Returns: The view storage.
func gtkPreferencesGroup(data: WidgetData) -> ViewStorage {
group(data: data).container(data: data.noModifiers, type: AdwaitaMainView.self)
}
/// Update the preferences group.
/// - Parameters:
/// - group: The view storage.
/// - data: The widget data.
/// - updateProperties: Whether to update the properties.
func update(group: ViewStorage, data: WidgetData, updateProperties: Bool) {
self.group(data: data)
.update(group, data: data, updateProperties: updateProperties, type: AdwaitaMainView.self)
}
}
/// The view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The view render data type.
/// - 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]])
}
/// 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.
public func update<Data>(
_ storage: ViewStorage,
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
if let storage = storage.content[.mainContent]?.first {
child.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
}
defer {
if visible {
for (index, page) in pages.enumerated() {
if let preferences = storage.content["preferences-\(index)"] {
page.update(groups: preferences, data: data, updateProperties: updateProperties)
}
}
}
}
guard updateProperties else {
return
}
if visible {
if storage.content[dialogID + id]?.first == nil {
createDialog(storage: storage, data: data, type: type)
adw_dialog_present(
storage.content[dialogID + id]?.first?.opaquePointer?.cast(),
storage.opaquePointer?.cast()
)
}
} else {
if storage.content[dialogID + id]?.first != nil {
let dialog = storage.content[dialogID + id]?.first?.opaquePointer
adw_dialog_close(dialog?.cast())
g_object_unref(dialog?.cast())
for index in pages.indices {
let container = storage.content["preferences-\(index)"]?.map { $0.opaquePointer }
container?.forEach { g_object_unref($0?.cast()) }
g_object_unref((storage.fields["preferences-\(index)"] as? OpaquePointer)?.cast())
}
}
}
}
/// Create a new instance of the dialog.
/// - Parameters:
/// - storage: The wrapped view's storage.
/// - modifiers: The view modifiers.
/// - type: The view render data type.
func createDialog<Data>(
storage: ViewStorage,
data: WidgetData,
type: Data.Type
) where Data: ViewRenderData {
let pointer = adw_preferences_dialog_new()
adw_preferences_dialog_set_search_enabled(pointer?.cast(), 1)
let dialog = ViewStorage(pointer?.opaque())
storage.content[dialogID + id] = [dialog]
dialog.connectSignal(name: "closed") {
storage.content[dialogID + id] = []
storage.content[contentID + id] = []
if visible {
visible = false
}
}
for (index, page) in pages.map({ $0.gtkPreferencesPage(data: data) }).enumerated() {
storage.content["preferences-\(index)"] = page.1
storage.fields["preferences-\(index)"] = page.0
adw_preferences_dialog_add(pointer?.cast(), page.0?.cast())
}
}
/// Add a preferences page.
/// - Parameters:
/// - title: The page title.
/// - icon: The page icon.
/// - content: Modify the preferences pages.
public func preferencesPage(
_ title: String,
icon: Icon,
content: (PreferencesPage) -> PreferencesPage
) -> Self {
modify { $0.pages.append(content(.init(title, icon: icon))) }
}
}

View File

@ -0,0 +1,192 @@
//
// ShortcutsDialog.swift
// Adwaita
//
// Created by david-swift on 04.11.25.
//
import CAdw
/// The shortcuts dialog widget.
public struct ShortcutsDialog: AdwaitaWidget {
/// Whether the dialog is visible.
@Binding var visible: Bool
/// An identifier used if multiple dialogs are on one view.
var id: String
/// The shortcuts dialog sections.
var sections: [ShortcutsSection] = []
/// The content.
var child: AnyView
/// The ID for the dialog's storage.
let dialogID = "dialog"
/// The ID for the content's storage.
let contentID = "content"
/// Initialize a dialog wrapper.
/// - Parameters:
/// - visible: Whether the dialog is visible.
/// - child: The wrapped view.
/// - id: A unique identifier for dialogs on the view.
init(
visible: Binding<Bool>,
child: AnyView,
id: String
) {
self._visible = visible
self.child = child
self.id = id
}
/// A shortcuts section.
public struct ShortcutsSection {
/// The section's title.
var title: String?
/// The section's content.
var content: [ShortcutsItem] = []
/// Initialize the shortcuts section.
/// - Parameter title: The section's title.
init(_ title: String?) {
self.title = title
}
/// Get the GTK shortcuts section as well as the section's view storages.
/// - Parameter data: The widget data.
/// - Returns: The shortcuts section pointer and the section's view storages.
func gtkShortcutsSection(data: WidgetData) -> (OpaquePointer?, [ViewStorage]) {
let section = adw_shortcuts_section_new(title)
let items = content.map { $0.gtkShortcutsItem(data: data) }
for item in items {
adw_shortcuts_section_add(section, item.opaquePointer)
}
return (section, items)
}
/// Add a shortcuts item.
/// - Parameters:
/// - title: The item's title.
/// - accelerator: The shortcut acccelerator.
public func shortcutsItem(
_ title: String,
accelerator: String
) -> Self {
var newSelf = self
newSelf.content.append(
.init(
title: title,
accelerator: accelerator
)
)
return newSelf
}
}
/// The shortcuts item.
struct ShortcutsItem {
/// The item's title.
var title: String
/// The item's description.
var accelerator: String
/// Get the GTK preferences group's storage.
/// - Parameter data: The widget data.
/// - Returns: The view storage.
func gtkShortcutsItem(data: WidgetData) -> ViewStorage {
.init(adw_shortcuts_item_new(title, accelerator))
}
}
/// The view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The view render data type.
/// - 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]])
}
/// 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.
public func update<Data>(
_ storage: ViewStorage,
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
if let storage = storage.content[.mainContent]?.first {
child.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
}
guard updateProperties else {
return
}
if visible {
if storage.content[dialogID + id]?.first == nil {
createDialog(storage: storage, data: data, type: type)
adw_dialog_present(
storage.content[dialogID + id]?.first?.opaquePointer?.cast(),
storage.opaquePointer?.cast()
)
}
} else {
if storage.content[dialogID + id]?.first != nil {
let dialog = storage.content[dialogID + id]?.first?.opaquePointer
adw_dialog_close(dialog?.cast())
g_object_unref(dialog?.cast())
for index in sections.indices {
let container = storage.content["shortcuts-\(index)"]?.map { $0.opaquePointer }
container?.forEach { g_object_unref($0?.cast()) }
g_object_unref((storage.fields["shortcuts-\(index)"] as? OpaquePointer)?.cast())
}
}
}
}
/// Create a new instance of the dialog.
/// - Parameters:
/// - storage: The wrapped view's storage.
/// - modifiers: The view modifiers.
/// - type: The view render data type.
func createDialog<Data>(
storage: ViewStorage,
data: WidgetData,
type: Data.Type
) where Data: ViewRenderData {
let pointer = adw_shortcuts_dialog_new()
let dialog = ViewStorage(pointer?.opaque())
storage.content[dialogID + id] = [dialog]
dialog.connectSignal(name: "closed") {
storage.content[dialogID + id] = []
storage.content[contentID + id] = []
if visible {
visible = false
}
}
for (index, section) in sections.map({ $0.gtkShortcutsSection(data: data) }).enumerated() {
storage.content["shortcuts-\(index)"] = section.1
storage.fields["shortcuts-\(index)"] = section.0
adw_shortcuts_dialog_add(pointer?.opaque(), section.0)
}
}
/// Add a shortcuts section.
/// - Parameters:
/// - title: The section's title or `nil`.
/// - content: Modify the shortcuts items.
public func shortcutsSection(
_ title: String? = nil,
content: (ShortcutsSection) -> ShortcutsSection
) -> Self {
modify { $0.sections.append(content(.init(title))) }
}
}

View File

@ -1,15 +1,14 @@
//
// ComboRow+.swift
// DropDown+.swift
// Adwaita
//
// Created by david-swift on 20.01.24.
// Created by david-swift on 09.04.25.
//
import CAdw
import LevenshteinTransformations
/// A row for selecting an element out of a list of elements.
extension ComboRow {
extension DropDown {
/// The identifier for the values.
static var values: String { "values" }
@ -18,30 +17,40 @@ extension ComboRow {
/// Initialize a combo row.
/// - Parameters:
/// - title: The row's title.
/// - selection: The selected value.
/// - values: The available values.
public init<Element>(
_ title: String,
selection: Binding<Element.ID>,
values: [Element]
) where Element: Identifiable, Element: CustomStringConvertible {
self = self.title(title)
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.id == selection.wrappedValue } ?? 0)
.init(values.firstIndex { $0[keyPath: id] == selection.wrappedValue } ?? 0)
} set: { index in
if let id = values[safe: .init(index)]?.id {
if let id = values[safe: .init(index)]?[keyPath: id] {
selection.wrappedValue = id
}
})
appearFunctions.append { storage, _ in
let list = gtk_string_list_new(nil)
storage.fields[Self.stringList] = list
adw_combo_row_set_model(storage.opaquePointer?.cast(), list)
Self.updateContent(storage: storage, values: values, element: Element.self)
storage.fields[Self.stringList] = gtk_drop_down_get_model(storage.opaquePointer)
Self.updateContent(storage: storage, values: values, id: id, description: description)
}
updateFunctions.append { storage, _, _ in
Self.updateContent(storage: storage, values: values, element: Element.self)
Self.updateContent(storage: storage, values: values, id: id, description: description)
}
}
@ -49,23 +58,23 @@ extension ComboRow {
/// - Parameters:
/// - storage: The view storage.
/// - values: The elements.
/// - element: The type of the elements.
static func updateContent<Element>(
/// - id: The keypath to the id.
/// - description: The keypath to the description.
static func updateContent<Element, Identifier>(
storage: ViewStorage,
values: [Element],
element: Element.Type
) where Element: Identifiable, Element: CustomStringConvertible {
id: KeyPath<Element, Identifier>,
description: KeyPath<Element, String>
) where Identifier: Equatable {
if let list = storage.fields[Self.stringList] as? OpaquePointer {
let old = storage.fields[Self.values] as? [Element] ?? []
old.identifiableTransform(
old.transform(
to: values,
functions: .init { index, element in
gtk_string_list_remove(list, .init(index))
gtk_string_list_append(list, element.description)
} delete: { index in
id: id,
functions: .init { index in
gtk_string_list_remove(list, .init(index))
} insert: { _, element in
gtk_string_list_append(list, element.description)
gtk_string_list_append(list, element[keyPath: description])
}
)
storage.fields[Self.values] = values

View File

@ -0,0 +1,21 @@
//
// Entry+.swift
// Adwaita
//
// Created by david-swift on 19.04.25.
//
extension Entry {
/// Initialize an entry.
/// - Parameters:
/// - placeholder: The placeholder text.
/// - text: The value.
public init(_ placeholder: String, text: Binding<String>) {
self.init()
self = self
.text(text)
.placeholderText(placeholder)
}
}

View File

@ -17,19 +17,21 @@ 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],
selection: Binding<Element.ID>?,
id: KeyPath<Element, Identifier>,
selection: Binding<Identifier>? = nil,
@ViewBuilder content: @escaping (Element) -> Body
) {
self.init(elements, content: content)
let id: (ViewStorage, [Element]) -> Element.ID? = { storage, elements in
self.init(elements, id: id, content: content)
let getID: (ViewStorage, [Element]) -> Identifier? = { 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 }]?.id
.firstIndex { $0.opaquePointer?.cast() == element }]?[keyPath: id]
}
return nil
}
@ -37,12 +39,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 = id(storage, elements) {
let id = getID(storage, elements) {
selection.wrappedValue = id
}
}
if selection.wrappedValue != id(storage, elements),
let index = elements.firstIndex(where: { $0.id == selection.wrappedValue })?.cInt {
if selection.wrappedValue != getID(storage, elements),
let index = elements.firstIndex(where: { $0[keyPath: id] == selection.wrappedValue })?.cInt {
gtk_flow_box_select_child(
storage.opaquePointer,
gtk_flow_box_get_child_at_index(storage.opaquePointer, index)
@ -57,3 +59,20 @@ 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>: AdwaitaWidget where Element: Identifiable {
public struct ForEach<Element, Identifier>: AdwaitaWidget where Identifier: Equatable {
/// The dynamic widget elements.
var elements: [Element]
@ -17,12 +17,22 @@ public struct ForEach<Element>: AdwaitaWidget where Element: Identifiable {
var content: (Element) -> Body
/// Whether the list is horizontal.
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], horizontal: Bool = false, @ViewBuilder content: @escaping (Element) -> Body) {
public init(
_ elements: [Element],
id: KeyPath<Element, Identifier>,
horizontal: Bool = false,
@ViewBuilder content: @escaping (Element) -> Body
) {
self.elements = elements
self.content = content
self.horizontal = horizontal
self.id = id
}
/// The view storage.
@ -34,11 +44,9 @@ public struct ForEach<Element>: AdwaitaWidget where Element: Identifiable {
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let storage = ViewStorage(
.init(
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.
@ -56,20 +64,12 @@ public struct ForEach<Element>: AdwaitaWidget where Element: Identifiable {
var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? []
let old = storage.fields["element"] as? [Element] ?? []
let widget: UnsafeMutablePointer<GtkBox>? = storage.opaquePointer?.cast()
old.identifiableTransform(
old.transform(
to: elements,
functions: .init { index, element in
let child = content(element).storage(data: data, type: type)
gtk_box_remove(widget, contentStorage[safe: index]?.opaquePointer?.cast())
gtk_box_insert_child_after(
widget,
child.opaquePointer?.cast(),
contentStorage[safe: index - 1]?.opaquePointer?.cast()
)
contentStorage.remove(at: index)
contentStorage.insert(child, at: index)
} delete: { index in
gtk_box_remove(widget, contentStorage[safe: index]?.opaquePointer?.cast())
id: id,
functions: .init { index in
let child = contentStorage[safe: index]?.opaquePointer
gtk_box_remove(widget, child?.cast())
contentStorage.remove(at: index)
} insert: { index, element in
let child = content(element).storage(data: data, type: type)
@ -82,10 +82,16 @@ public struct ForEach<Element>: AdwaitaWidget where Element: Identifiable {
}
)
if updateProperties {
gtk_orientable_set_orientation(
widget?.opaque(),
horizontal ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL
)
if (storage.previousState as? Self)?.horizontal != horizontal {
gtk_orientable_set_orientation(
widget?.opaque(),
horizontal ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL
)
}
if let homogeneous, (storage.previousState as? Self)?.homogeneous != homogeneous {
gtk_box_set_homogeneous(widget?.cast(), homogeneous.cBool)
}
storage.previousState = self
}
storage.fields["element"] = elements
storage.content[.mainContent] = contentStorage
@ -100,4 +106,23 @@ public struct ForEach<Element>: AdwaitaWidget where Element: Identifiable {
}
}
/// Whether the children should all be the same size.
/// - Parameter homogeneous: Whether the children should all be the same size.
/// - Returns: The for each view.
public func homogeneous(_ homogeneous: Bool? = true) -> Self {
modify { $0.homogeneous = homogeneous }
}
}
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

@ -14,4 +14,11 @@ extension ActionRow {
self = self.title(title)
}
/// Deemphasize the row title and emphasize the subtitle.
/// - Parameter active: Whether the style is currently applied.
/// - Returns: A view.
public func property(_ active: Bool = true) -> AnyView {
style("property", active: active)
}
}

View File

@ -0,0 +1,64 @@
//
// ComboRow+.swift
// Adwaita
//
// Created by david-swift on 20.01.24.
//
import CAdw
import LevenshteinTransformations
/// A row for selecting an element out of a list of elements.
extension ComboRow {
/// The identifier for the values.
static var values: String { "values" }
/// The identifier for the string list.
static var stringList: String { "string-list" }
/// Initialize a combo row.
/// - Parameters:
/// - title: The row's title.
/// - selection: The selected value.
/// - values: The available values.
public init<Element>(
_ title: String,
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)
} set: { index in
if let id = values[safe: .init(index)]?[keyPath: id] {
selection.wrappedValue = id
}
})
appearFunctions.append { storage, _ in
let list = gtk_string_list_new(nil)
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)
}
updateFunctions.append { storage, _, _ in
DropDown.updateContent(storage: storage, values: values, id: id, description: description)
}
}
}

View File

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

View File

@ -2,15 +2,15 @@
// ActionRow.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// A [class@Gtk.ListBoxRow] used to present actions.
/// A `Gtk.ListBoxRow` used to present actions.
///
///
/// <picture><source srcset="action-row-dark.png" media="(prefers-color-scheme: dark)"><img src="action-row.png" alt="action-row"></picture>
///
/// The `AdwActionRow` widget can have a title, a subtitle and an icon. The row
/// can receive additional widgets at its end, or prefix widgets at its start.
@ -21,50 +21,35 @@ import LevenshteinTransformations
/// will automatically make it activatable, but unsetting it won't change the
/// row's activatability.
///
/// ## AdwActionRow as GtkBuildable
///
/// The `AdwActionRow` implementation of the [iface@Gtk.Buildable] interface
/// supports adding a child at its end by specifying suffix or omitting the
/// type attribute of a <child> element.
///
/// It also supports adding a child as a prefix widget by specifying prefix as
/// the type attribute of a <child> element.
///
/// ## CSS nodes
///
/// `AdwActionRow` has a main CSS node with name `row`.
///
/// It contains the subnode `box.header` for its main horizontal box, and
/// `box.title` for the vertical box containing the title and subtitle labels.
///
/// It contains subnodes `label.title` and `label.subtitle` representing
/// respectively the title label and subtitle label.
///
/// `AdwActionRow` can use the
/// [`.property`](style-classes.html#property-rows) style class to emphasize
/// the row subtitle instead of the row title, which is useful for
/// displaying read-only properties.
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.
///
/// The row can be activated either by clicking on it, calling
/// [method@ActionRow.activate], or via mnemonics in the title.
/// See the [property@PreferencesRow:use-underline] property to enable
/// `ActionRow.activate`, or via mnemonics in the title.
/// See the ``useUnderline(_:)`` property to enable
/// mnemonics.
///
/// The target widget will be activated by emitting the
/// [signal@Gtk.Widget::mnemonic-activate] signal on it.
var activatableWidget: (() -> Body)?
/// `Gtk.Widget::mnemonic-activate` signal on it.
var activatableWidget: Body?
/// The subtitle for this row.
///
/// The subtitle is interpreted as Pango markup unless
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
/// ``useMarkup(_:)`` is set to `false`.
var subtitle: String?
/// The number of lines at the end of which the subtitle label will be
/// ellipsized.
@ -73,12 +58,12 @@ public struct ActionRow: AdwaitaWidget {
var subtitleLines: Int?
/// Whether the user can copy the subtitle from the label.
///
/// See also [property@Gtk.Label:selectable].
/// See also ``selectable(_:)``.
var subtitleSelectable: Bool?
/// The title of the preference represented by this row.
///
/// The title is interpreted as Pango markup unless
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
/// ``useMarkup(_:)`` is set to `false`.
var title: String?
/// The number of lines at the end of which the title label will be ellipsized.
///
@ -86,13 +71,13 @@ public struct ActionRow: AdwaitaWidget {
var titleLines: Int?
/// Whether the user can copy the title from the label.
///
/// See also [property@Gtk.Label:selectable].
/// See also ``selectable(_:)``.
var titleSelectable: Bool?
/// Whether to use Pango markup for the title label.
///
/// Subclasses may also use it for other labels, such as subtitle.
///
/// See also [func@Pango.parse_markup].
/// See also `Pango.parse_markup`.
var useMarkup: Bool?
/// Whether an embedded underline in the title indicates a mnemonic.
var useUnderline: Bool?
@ -117,8 +102,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) {
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())
}
@ -153,7 +137,7 @@ public struct ActionRow: AdwaitaWidget {
storage.modify { widget in
if let widget = storage.content["activatableWidget"]?.first {
activatableWidget?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
activatableWidget?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
if let subtitleLines, updateProperties, (storage.previousState as? Self)?.subtitleLines != subtitleLines {
adw_action_row_set_subtitle_lines(widget?.cast(), subtitleLines.cInt)
@ -205,6 +189,7 @@ public struct ActionRow: AdwaitaWidget {
}
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -217,28 +202,22 @@ public struct ActionRow: AdwaitaWidget {
/// The widget to activate when the row is activated.
///
/// The row can be activated either by clicking on it, calling
/// [method@ActionRow.activate], or via mnemonics in the title.
/// See the [property@PreferencesRow:use-underline] property to enable
/// `ActionRow.activate`, or via mnemonics in the title.
/// See the ``useUnderline(_:)`` property to enable
/// mnemonics.
///
/// The target widget will be activated by emitting the
/// [signal@Gtk.Widget::mnemonic-activate] signal on it.
public func activatableWidget(@ViewBuilder _ activatableWidget: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.activatableWidget = activatableWidget
return newSelf
/// `Gtk.Widget::mnemonic-activate` signal on it.
public func activatableWidget(@ViewBuilder _ activatableWidget: () -> Body) -> Self {
modify { $0.activatableWidget = activatableWidget() }
}
/// The subtitle for this row.
///
/// The subtitle is interpreted as Pango markup unless
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
/// ``useMarkup(_:)`` is set to `false`.
public func subtitle(_ subtitle: String?) -> Self {
var newSelf = self
newSelf.subtitle = subtitle
return newSelf
modify { $0.subtitle = subtitle }
}
/// The number of lines at the end of which the subtitle label will be
@ -246,71 +225,50 @@ public struct ActionRow: AdwaitaWidget {
///
/// If the value is 0, the number of lines won't be limited.
public func subtitleLines(_ subtitleLines: Int?) -> Self {
var newSelf = self
newSelf.subtitleLines = subtitleLines
return newSelf
modify { $0.subtitleLines = subtitleLines }
}
/// Whether the user can copy the subtitle from the label.
///
/// See also [property@Gtk.Label:selectable].
/// See also ``selectable(_:)``.
public func subtitleSelectable(_ subtitleSelectable: Bool? = true) -> Self {
var newSelf = self
newSelf.subtitleSelectable = subtitleSelectable
return newSelf
modify { $0.subtitleSelectable = subtitleSelectable }
}
/// The title of the preference represented by this row.
///
/// The title is interpreted as Pango markup unless
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
/// ``useMarkup(_:)`` is set to `false`.
public func title(_ title: String?) -> Self {
var newSelf = self
newSelf.title = title
return newSelf
modify { $0.title = title }
}
/// The number of lines at the end of which the title label will be ellipsized.
///
/// If the value is 0, the number of lines won't be limited.
public func titleLines(_ titleLines: Int?) -> Self {
var newSelf = self
newSelf.titleLines = titleLines
return newSelf
modify { $0.titleLines = titleLines }
}
/// Whether the user can copy the title from the label.
///
/// See also [property@Gtk.Label:selectable].
/// See also ``selectable(_:)``.
public func titleSelectable(_ titleSelectable: Bool? = true) -> Self {
var newSelf = self
newSelf.titleSelectable = titleSelectable
return newSelf
modify { $0.titleSelectable = titleSelectable }
}
/// Whether to use Pango markup for the title label.
///
/// Subclasses may also use it for other labels, such as subtitle.
///
/// See also [func@Pango.parse_markup].
/// See also `Pango.parse_markup`.
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
var newSelf = self
newSelf.useMarkup = useMarkup
return newSelf
modify { $0.useMarkup = useMarkup }
}
/// Whether an embedded underline in the title indicates a mnemonic.
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
var newSelf = self
newSelf.useUnderline = useUnderline
return newSelf
modify { $0.useUnderline = useUnderline }
}
/// This signal is emitted after the row has been activated.

View File

@ -2,45 +2,44 @@
// AspectFrame.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// `GtkAspectFrame` preserves the aspect ratio of its child.
/// Preserves the aspect ratio of its child.
///
/// The frame can respect the aspect ratio of the child widget,
/// or use its own aspect ratio.
///
/// # CSS nodes
///
/// `GtkAspectFrame` uses a CSS node with name `frame`.
///
/// # Accessibility
///
/// Until GTK 4.10, `GtkAspectFrame` used the `GTK_ACCESSIBLE_ROLE_GROUP` role.
///
/// Starting from GTK 4.12, `GtkAspectFrame` uses the `GTK_ACCESSIBLE_ROLE_GENERIC` role.
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.
///
/// The accessible role cannot be changed once set.
var accessibleRole: String?
/// The child widget.
var child: (() -> Body)?
var child: Body?
/// Whether the `GtkAspectFrame` should use the aspect ratio of its child.
var obeyChild: Bool?
/// The aspect ratio to be used by the `GtkAspectFrame`.
///
/// This property is only used if
/// [property@Gtk.AspectFrame:obey-child] is set to %FALSE.
/// ``obeyChild(_:)`` is set to `false`.
var ratio: Float
/// The horizontal alignment of the child.
var xalign: Float?
@ -62,8 +61,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) {
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
gtk_aspect_frame_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())
}
@ -81,7 +79,7 @@ public struct AspectFrame: AdwaitaWidget {
storage.modify { widget in
if let widget = storage.content["child"]?.first {
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
child?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
if let obeyChild, updateProperties, (storage.previousState as? Self)?.obeyChild != obeyChild {
gtk_aspect_frame_set_obey_child(widget, obeyChild.cBool)
@ -97,6 +95,7 @@ public struct AspectFrame: AdwaitaWidget {
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -110,53 +109,35 @@ public struct AspectFrame: AdwaitaWidget {
///
/// The accessible role cannot be changed once set.
public func accessibleRole(_ accessibleRole: String?) -> Self {
var newSelf = self
newSelf.accessibleRole = accessibleRole
return newSelf
modify { $0.accessibleRole = accessibleRole }
}
/// The child widget.
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.child = child
return newSelf
public func child(@ViewBuilder _ child: () -> Body) -> Self {
modify { $0.child = child() }
}
/// Whether the `GtkAspectFrame` should use the aspect ratio of its child.
public func obeyChild(_ obeyChild: Bool? = true) -> Self {
var newSelf = self
newSelf.obeyChild = obeyChild
return newSelf
modify { $0.obeyChild = obeyChild }
}
/// The aspect ratio to be used by the `GtkAspectFrame`.
///
/// This property is only used if
/// [property@Gtk.AspectFrame:obey-child] is set to %FALSE.
/// ``obeyChild(_:)`` is set to `false`.
public func ratio(_ ratio: Float) -> Self {
var newSelf = self
newSelf.ratio = ratio
return newSelf
modify { $0.ratio = ratio }
}
/// The horizontal alignment of the child.
public func xalign(_ xalign: Float?) -> Self {
var newSelf = self
newSelf.xalign = xalign
return newSelf
modify { $0.xalign = xalign }
}
/// The vertical alignment of the child.
public func yalign(_ yalign: Float?) -> Self {
var newSelf = self
newSelf.yalign = yalign
return newSelf
modify { $0.yalign = yalign }
}
}

View File

@ -2,7 +2,7 @@
// Avatar.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
@ -10,30 +10,35 @@ import LevenshteinTransformations
/// A widget displaying an image, with a generated fallback.
///
/// <picture><source srcset="avatar-dark.png" media="(prefers-color-scheme: dark)"><img src="avatar.png" alt="avatar"></picture>
///
///
/// `AdwAvatar` is a widget that shows a round avatar.
///
/// `AdwAvatar` generates an avatar with the initials of the
/// [property@Avatar:text] on top of a colored background.
/// ``text(_:)`` on top of a colored background.
///
/// The color is picked based on the hash of the [property@Avatar:text].
/// The color is picked based on the hash of the ``text(_:)``.
///
/// If [property@Avatar:show-initials] is set to `FALSE`,
/// [property@Avatar:icon-name] or `avatar-default-symbolic` is shown instead of
/// If ``showInitials(_:)`` is set to `false`,
/// ``iconName(_:)`` or `avatar-default-symbolic` is shown instead of
/// the initials.
///
/// Use [property@Avatar:custom-image] to set a custom image.
/// Use ``customImage(_:)`` to set a custom image.
///
/// ## CSS nodes
///
/// `AdwAvatar` has a single CSS node with name `avatar`.
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.
///
@ -41,14 +46,14 @@ public struct Avatar: AdwaitaWidget {
var iconName: String?
/// Whether initials are used instead of an icon on the fallback avatar.
///
/// See [property@Avatar:icon-name] for how to change the fallback icon.
/// See ``iconName(_:)`` for how to change the fallback icon.
var showInitials: Bool
/// The size of the avatar.
var size: Int
/// Sets the text used to generate the fallback initials and color.
///
/// It's only used to generate the color if [property@Avatar:show-initials] is
/// `FALSE`.
/// It's only used to generate the color if ``showInitials(_:)`` is
/// `false`.
var text: String?
/// Initialize `Avatar`.
@ -67,7 +72,6 @@ public struct Avatar: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}
@ -95,6 +99,7 @@ public struct Avatar: AdwaitaWidget {
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -108,39 +113,27 @@ public struct Avatar: AdwaitaWidget {
///
/// If no name is set, `avatar-default-symbolic` will be used.
public func iconName(_ iconName: String?) -> Self {
var newSelf = self
newSelf.iconName = iconName
return newSelf
modify { $0.iconName = iconName }
}
/// Whether initials are used instead of an icon on the fallback avatar.
///
/// See [property@Avatar:icon-name] for how to change the fallback icon.
/// See ``iconName(_:)`` for how to change the fallback icon.
public func showInitials(_ showInitials: Bool) -> Self {
var newSelf = self
newSelf.showInitials = showInitials
return newSelf
modify { $0.showInitials = showInitials }
}
/// The size of the avatar.
public func size(_ size: Int) -> Self {
var newSelf = self
newSelf.size = size
return newSelf
modify { $0.size = size }
}
/// Sets the text used to generate the fallback initials and color.
///
/// It's only used to generate the color if [property@Avatar:show-initials] is
/// `FALSE`.
/// It's only used to generate the color if ``showInitials(_:)`` is
/// `false`.
public func text(_ text: String?) -> Self {
var newSelf = self
newSelf.text = text
return newSelf
modify { $0.text = text }
}
}

View File

@ -2,7 +2,7 @@
// Banner.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
@ -10,46 +10,54 @@ import LevenshteinTransformations
/// A bar with contextual information.
///
/// <picture><source srcset="banner-dark.png" media="(prefers-color-scheme: dark)"><img src="banner.png" alt="banner"></picture>
///
/// Banners are hidden by default, use [property@Banner:revealed] to show them.
///
/// Banners have a title, set with [property@Banner:title]. Titles can be marked
/// up with Pango markup, use [property@Banner:use-markup] to enable it.
/// Banners are hidden by default, use ``revealed(_:)`` to show them.
///
/// Banners have a title, set with ``title(_:)``. Titles can be marked
/// up with Pango markup, use ``useMarkup(_:)`` to enable it.
///
/// The title will be shown centered or left-aligned depending on available
/// space.
///
/// Banners can optionally have a button with text on it, set through
/// [property@Banner:button-label]. The button can be used with a `GAction`,
/// or with the [signal@Banner::button-clicked] signal.
/// ``buttonLabel(_:)``. The button can be used with a `GAction`,
/// or with the `Banner::button-clicked` signal. The button can have
/// different styles, a gray style and a suggested style.
///
///
///
/// ## CSS nodes
///
/// `AdwBanner` has a main CSS node with the name `banner`.
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.
///
/// If set to `""` or `NULL`, the button won't be shown.
///
/// The button can be used with a `GAction`, or with the
/// [signal@Banner::button-clicked] signal.
/// `Banner::button-clicked` signal.
var buttonLabel: String?
/// Whether the banner is currently revealed.
var revealed: Bool?
/// The title for this banner.
///
/// See also: [property@Banner:use-markup].
/// See also: ``useMarkup(_:)``.
var title: String
/// Whether to use Pango markup for the banner title.
///
/// See also [func@Pango.parse_markup].
/// See also `Pango.parse_markup`.
var useMarkup: Bool?
/// This signal is emitted after the action button has been clicked.
///
@ -71,7 +79,6 @@ public struct Banner: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}
@ -104,6 +111,7 @@ public struct Banner: AdwaitaWidget {
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -118,40 +126,28 @@ public struct Banner: AdwaitaWidget {
/// If set to `""` or `NULL`, the button won't be shown.
///
/// The button can be used with a `GAction`, or with the
/// [signal@Banner::button-clicked] signal.
/// `Banner::button-clicked` signal.
public func buttonLabel(_ buttonLabel: String?) -> Self {
var newSelf = self
newSelf.buttonLabel = buttonLabel
return newSelf
modify { $0.buttonLabel = buttonLabel }
}
/// Whether the banner is currently revealed.
public func revealed(_ revealed: Bool? = true) -> Self {
var newSelf = self
newSelf.revealed = revealed
return newSelf
modify { $0.revealed = revealed }
}
/// The title for this banner.
///
/// See also: [property@Banner:use-markup].
/// See also: ``useMarkup(_:)``.
public func title(_ title: String) -> Self {
var newSelf = self
newSelf.title = title
return newSelf
modify { $0.title = title }
}
/// Whether to use Pango markup for the banner title.
///
/// See also [func@Pango.parse_markup].
/// See also `Pango.parse_markup`.
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
var newSelf = self
newSelf.useMarkup = useMarkup
return newSelf
modify { $0.useMarkup = useMarkup }
}
/// This signal is emitted after the action button has been clicked.

View File

@ -2,7 +2,7 @@
// Bin.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
@ -10,22 +10,29 @@ import LevenshteinTransformations
/// A widget with one child.
///
/// <picture><source srcset="bin-dark.png" media="(prefers-color-scheme: dark)"><img src="bin.png" alt="bin"></picture>
///
/// The `AdwBin` widget has only one child, set with the [property@Bin:child]
///
/// The `AdwBin` widget has only one child, set with the ``child(_:)``
/// property.
///
/// It is useful for deriving subclasses, since it provides common code needed
/// 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)?
var child: Body?
/// Initialize `Bin`.
public init() {
@ -41,8 +48,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) {
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
adw_bin_set_child(storage.opaquePointer?.cast(), childStorage.opaquePointer?.cast())
}
@ -60,10 +66,11 @@ public struct Bin: AdwaitaWidget {
storage.modify { widget in
if let widget = storage.content["child"]?.first {
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
child?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -74,11 +81,8 @@ public struct Bin: AdwaitaWidget {
}
/// The child widget of the `AdwBin`.
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.child = child
return newSelf
public func child(@ViewBuilder _ child: () -> Body) -> Self {
modify { $0.child = child() }
}
}

View File

@ -2,58 +2,59 @@
// Box.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// The `GtkBox` widget arranges child widgets into a single row or column.
/// Arranges child widgets into a single row or column.
///
///
/// ![An example GtkBox](box.png)
///
/// Whether it is a row or column depends on the value of its
/// [property@Gtk.Orientable:orientation] property. Within the other
/// dimension, all children are allocated the same size. Of course, the
/// [property@Gtk.Widget:halign] and [property@Gtk.Widget:valign] properties
/// can be used on the children to influence their allocation.
/// ``orientation(_:)`` property. Within the other
/// dimension, all children are allocated the same size. The
/// ``halign(_:)`` and ``valign(_:)``
/// properties can be used on the children to influence their allocation.
///
/// Use repeated calls to [method@Gtk.Box.append] to pack widgets into a
/// `GtkBox` from start to end. Use [method@Gtk.Box.remove] to remove widgets
/// from the `GtkBox`. [method@Gtk.Box.insert_child_after] can be used to add
/// Use repeated calls to `Gtk.Box.append` to pack widgets into a
/// `GtkBox` from start to end. Use `Gtk.Box.remove` to remove widgets
/// from the `GtkBox`. `Gtk.Box.insert_child_after` can be used to add
/// a child at a particular position.
///
/// Use [method@Gtk.Box.set_homogeneous] to specify whether or not all children
/// Use `Gtk.Box.set_homogeneous` to specify whether or not all children
/// of the `GtkBox` are forced to get the same amount of space.
///
/// Use [method@Gtk.Box.set_spacing] to determine how much space will be minimally
/// Use `Gtk.Box.set_spacing` to determine how much space will be minimally
/// placed between all children in the `GtkBox`. Note that spacing is added
/// *between* the children.
///
/// Use [method@Gtk.Box.reorder_child_after] to move a child to a different
/// Use `Gtk.Box.reorder_child_after` to move a child to a different
/// place in the box.
///
/// # CSS nodes
///
/// `GtkBox` uses a single CSS node with name box.
///
/// # Accessibility
///
/// Until GTK 4.10, `GtkBox` used the `GTK_ACCESSIBLE_ROLE_GROUP` role.
///
/// Starting from GTK 4.12, `GtkBox` uses the `GTK_ACCESSIBLE_ROLE_GENERIC` role.
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.
///
/// The accessible role cannot be changed once set.
var accessibleRole: String?
/// The child that determines the baseline, in vertical orientation.
/// The position of the child that determines the baseline.
///
/// This is only relevant if the box is in vertical orientation.
var baselineChild: Int?
/// Whether the children should all be the same size.
var homogeneous: Bool?
@ -65,7 +66,7 @@ public struct Box: AdwaitaWidget {
var prepend: () -> Body = { [] }
/// Initialize `Box`.
public init(spacing: Int) {
init(spacing: Int) {
self.spacing = spacing
}
@ -79,7 +80,6 @@ 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() {
@ -140,6 +140,7 @@ public struct Box: AdwaitaWidget {
}
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -153,34 +154,24 @@ public struct Box: AdwaitaWidget {
///
/// The accessible role cannot be changed once set.
public func accessibleRole(_ accessibleRole: String?) -> Self {
var newSelf = self
newSelf.accessibleRole = accessibleRole
return newSelf
modify { $0.accessibleRole = accessibleRole }
}
/// The child that determines the baseline, in vertical orientation.
/// The position of the child that determines the baseline.
///
/// This is only relevant if the box is in vertical orientation.
public func baselineChild(_ baselineChild: Int?) -> Self {
var newSelf = self
newSelf.baselineChild = baselineChild
return newSelf
modify { $0.baselineChild = baselineChild }
}
/// Whether the children should all be the same size.
public func homogeneous(_ homogeneous: Bool? = true) -> Self {
var newSelf = self
newSelf.homogeneous = homogeneous
return newSelf
modify { $0.homogeneous = homogeneous }
}
/// The amount of space between children.
public func spacing(_ spacing: Int) -> Self {
var newSelf = self
newSelf.spacing = spacing
return newSelf
modify { $0.spacing = spacing }
}
/// Set the body for "append".

View File

@ -2,54 +2,40 @@
// Button.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// The `GtkButton` widget is generally used to trigger a callback function that is
/// called when the button is pressed.
/// Calls a callback function when the button is clicked.
///
///
/// ![An example GtkButton](button.png)
///
/// The `GtkButton` widget can hold any valid child widget. That is, it can hold
/// almost any other standard `GtkWidget`. The most commonly used child is the
/// `GtkLabel`.
///
/// # CSS nodes
///
/// `GtkButton` has a single CSS node with name button. The node will get the
/// style classes .image-button or .text-button, if the content is just an
/// image or label, respectively. It may also receive the .flat style class.
/// When activating a button via the keyboard, the button will temporarily
/// gain the .keyboard-activating style class.
///
/// Other style classes that are commonly used with `GtkButton` include
/// .suggested-action and .destructive-action. In special cases, buttons
/// can be made round by adding the .circular style class.
///
/// Button-like widgets like [class@Gtk.ToggleButton], [class@Gtk.MenuButton],
/// [class@Gtk.VolumeButton], [class@Gtk.LockButton], [class@Gtk.ColorButton]
/// or [class@Gtk.FontButton] use style classes such as .toggle, .popup, .scale,
/// .lock, .color on the button node to differentiate themselves from a plain
/// `GtkButton`.
///
/// # Accessibility
///
/// `GtkButton` uses the %GTK_ACCESSIBLE_ROLE_BUTTON role.
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.
///
/// The accessible role cannot be changed once set.
var accessibleRole: String?
/// action-name
/// The name of the action with which this widget should be associated.
var actionName: String?
/// Whether the size of the button can be made smaller than the natural
/// size of its contents.
@ -60,7 +46,7 @@ public struct Button: AdwaitaWidget {
/// property has no effect.
var canShrink: Bool?
/// The child widget.
var child: (() -> Body)?
var child: Body?
/// Whether the button has a frame.
var hasFrame: Bool?
/// The name of the icon used to automatically populate the button.
@ -73,7 +59,7 @@ public struct Button: AdwaitaWidget {
/// Emitted to animate press then release.
///
/// This is an action signal. Applications should never connect
/// to this signal, but use the [signal@Gtk.Button::clicked] signal.
/// to this signal, but use the `Gtk.Button::clicked` signal.
///
/// The default bindings for this signal are all forms of the
/// <kbd></kbd> and <kbd>Enter</kbd> keys.
@ -82,7 +68,7 @@ public struct Button: AdwaitaWidget {
var clicked: (() -> Void)?
/// Initialize `Button`.
public init() {
init() {
}
/// The view storage.
@ -95,8 +81,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) {
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
gtk_button_set_child(storage.opaquePointer?.cast(), childStorage.opaquePointer?.cast())
}
@ -130,7 +115,7 @@ public struct Button: AdwaitaWidget {
gtk_button_set_can_shrink(widget?.cast(), canShrink.cBool)
}
if let widget = storage.content["child"]?.first {
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
child?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
if let hasFrame, updateProperties, (storage.previousState as? Self)?.hasFrame != hasFrame {
gtk_button_set_has_frame(widget?.cast(), hasFrame.cBool)
@ -146,6 +131,7 @@ public struct Button: AdwaitaWidget {
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -159,18 +145,12 @@ public struct Button: AdwaitaWidget {
///
/// The accessible role cannot be changed once set.
public func accessibleRole(_ accessibleRole: String?) -> Self {
var newSelf = self
newSelf.accessibleRole = accessibleRole
return newSelf
modify { $0.accessibleRole = accessibleRole }
}
/// action-name
/// The name of the action with which this widget should be associated.
public func actionName(_ actionName: String?) -> Self {
var newSelf = self
newSelf.actionName = actionName
return newSelf
modify { $0.actionName = actionName }
}
/// Whether the size of the button can be made smaller than the natural
@ -181,57 +161,39 @@ public struct Button: AdwaitaWidget {
/// If the contents of a button are an icon or a custom widget, setting this
/// property has no effect.
public func canShrink(_ canShrink: Bool? = true) -> Self {
var newSelf = self
newSelf.canShrink = canShrink
return newSelf
modify { $0.canShrink = canShrink }
}
/// The child widget.
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.child = child
return newSelf
public func child(@ViewBuilder _ child: () -> Body) -> Self {
modify { $0.child = child() }
}
/// Whether the button has a frame.
public func hasFrame(_ hasFrame: Bool? = true) -> Self {
var newSelf = self
newSelf.hasFrame = hasFrame
return newSelf
modify { $0.hasFrame = hasFrame }
}
/// The name of the icon used to automatically populate the button.
public func iconName(_ iconName: String?) -> Self {
var newSelf = self
newSelf.iconName = iconName
return newSelf
modify { $0.iconName = iconName }
}
/// Text of the label inside the button, if the button contains a label widget.
public func label(_ label: String?) -> Self {
var newSelf = self
newSelf.label = label
return newSelf
modify { $0.label = label }
}
/// If set, an underline in the text indicates that the following character is
/// to be used as mnemonic.
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
var newSelf = self
newSelf.useUnderline = useUnderline
return newSelf
modify { $0.useUnderline = useUnderline }
}
/// Emitted to animate press then release.
///
/// This is an action signal. Applications should never connect
/// to this signal, but use the [signal@Gtk.Button::clicked] signal.
/// to this signal, but use the `Gtk.Button::clicked` signal.
///
/// The default bindings for this signal are all forms of the
/// <kbd></kbd> and <kbd>Enter</kbd> keys.

View File

@ -2,7 +2,7 @@
// ButtonContent.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
@ -10,12 +10,12 @@ import LevenshteinTransformations
/// A helper widget for creating buttons.
///
/// <picture><source srcset="button-content-dark.png" media="(prefers-color-scheme: dark)"><img src="button-content.png" alt="button-content"></picture>
///
///
/// `AdwButtonContent` is a box-like widget with an icon and a label.
///
/// It's intended to be used as a direct child of [class@Gtk.Button],
/// [class@Gtk.MenuButton] or [class@SplitButton], when they need to have both an
/// It's intended to be used as a direct child of `Gtk.Button`,
/// `Gtk.MenuButton` or `SplitButton`, when they need to have both an
/// icon and a label, as follows:
///
/// ```xml
@ -25,37 +25,26 @@ import LevenshteinTransformations
/// `AdwButtonContent` handles style classes and connecting the mnemonic to the
/// button automatically.
///
/// ## CSS nodes
///
/// ```
/// buttoncontent
/// box
/// image
/// label
/// ```
///
/// `AdwButtonContent`'s CSS node is called `buttoncontent`. It contains a `box`
/// subnode that serves as a container for the `image` and `label` nodes.
///
/// When inside a `GtkButton` or `AdwSplitButton`, the button will receive the
/// `.image-text-button` style class. When inside a `GtkMenuButton`, the
/// internal `GtkButton` will receive it instead.
///
/// ## Accessibility
///
/// `AdwButtonContent` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
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.
///
/// If set to `TRUE`, the label will ellipsize.
/// If set to `true`, the label will ellipsize.
///
/// See [property@Gtk.Button:can-shrink].
/// See ``canShrink(_:)``.
var canShrink: Bool?
/// The name of the displayed icon.
///
@ -67,7 +56,7 @@ public struct ButtonContent: AdwaitaWidget {
///
/// The mnemonic can be used to activate the parent button.
///
/// See [property@ButtonContent:label].
/// See ``label(_:)``.
var useUnderline: Bool?
/// Initialize `ButtonContent`.
@ -84,7 +73,6 @@ public struct ButtonContent: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}
@ -112,6 +100,7 @@ public struct ButtonContent: AdwaitaWidget {
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -123,44 +112,32 @@ public struct ButtonContent: AdwaitaWidget {
/// Whether the button can be smaller than the natural size of its contents.
///
/// If set to `TRUE`, the label will ellipsize.
/// If set to `true`, the label will ellipsize.
///
/// See [property@Gtk.Button:can-shrink].
/// See ``canShrink(_:)``.
public func canShrink(_ canShrink: Bool? = true) -> Self {
var newSelf = self
newSelf.canShrink = canShrink
return newSelf
modify { $0.canShrink = canShrink }
}
/// The name of the displayed icon.
///
/// If empty, the icon is not shown.
public func iconName(_ iconName: String?) -> Self {
var newSelf = self
newSelf.iconName = iconName
return newSelf
modify { $0.iconName = iconName }
}
/// The displayed label.
public func label(_ label: String?) -> Self {
var newSelf = self
newSelf.label = label
return newSelf
modify { $0.label = label }
}
/// Whether an underline in the text indicates a mnemonic.
///
/// The mnemonic can be used to activate the parent button.
///
/// See [property@ButtonContent:label].
/// See ``label(_:)``.
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
var newSelf = self
newSelf.useUnderline = useUnderline
return newSelf
modify { $0.useUnderline = useUnderline }
}
}

View File

@ -2,7 +2,7 @@
// Carousel.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
@ -10,35 +10,40 @@ import LevenshteinTransformations
/// A paginated scrolling widget.
///
/// <picture><source srcset="carousel-dark.png" media="(prefers-color-scheme: dark)"><img src="carousel.png" alt="carousel"></picture>
///
///
/// The `AdwCarousel` widget can be used to display a set of pages with
/// swipe-based navigation between them.
///
/// [class@CarouselIndicatorDots] and [class@CarouselIndicatorLines] can be used
/// `CarouselIndicatorDots` and `CarouselIndicatorLines` can be used
/// to provide page indicators for `AdwCarousel`.
///
/// ## CSS nodes
///
/// `AdwCarousel` has a single CSS node with name `carousel`.
public struct Carousel<Element>: AdwaitaWidget where Element: Identifiable {
public struct Carousel<Element, Identifier>: AdwaitaWidget where Identifier: Equatable {
#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.
///
/// If the value is `FALSE`, each swipe can only move to the adjacent pages.
/// If the value is `false`, each swipe can only move to the adjacent pages.
var allowLongSwipes: Bool?
/// Sets whether the `AdwCarousel` can be dragged with mouse pointer.
///
/// If the value is `FALSE`, dragging is only available on touch.
/// If the value is `false`, dragging is only available on touch.
var allowMouseDrag: Bool?
/// Whether the widget will respond to scroll wheel events.
///
/// If the value is `FALSE`, wheel events will be ignored.
/// If the value is `false`, wheel events will be ignored.
var allowScrollWheel: Bool?
/// Whether the carousel can be navigated.
///
@ -58,18 +63,21 @@ public struct Carousel<Element>: AdwaitaWidget where Element: Identifiable {
/// It can be used to implement "infinite scrolling" by amending the pages
/// after every scroll.
///
/// ::: note
/// An empty carousel is indicated by `(int)index == -1`.
/// > [!NOTE]
/// > An empty carousel is indicated by `(int)index == -1`.
var pageChanged: (() -> Void)?
/// The dynamic widget elements.
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], @ViewBuilder content: @escaping (Element) -> Body) {
public init(_ elements: [Element], id: KeyPath<Element, Identifier>, @ViewBuilder content: @escaping (Element) -> Body) {
self.elements = elements
self.content = content
self.id = id
}
/// The view storage.
@ -82,7 +90,6 @@ public struct Carousel<Element>: AdwaitaWidget where Element: Identifiable {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}
@ -122,15 +129,10 @@ public struct Carousel<Element>: AdwaitaWidget where Element: Identifiable {
var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? []
let old = storage.fields["element"] as? [Element] ?? []
old.identifiableTransform(
old.transform(
to: elements,
functions: .init { index, element in
let child = content(element).storage(data: data, type: type)
adw_carousel_remove(widget, adw_carousel_get_nth_page(widget, UInt(index).cInt))
adw_carousel_insert(widget, child.opaquePointer?.cast(), index.cInt)
contentStorage.remove(at: index)
contentStorage.insert(child, at: index)
} delete: { index in
id: id,
functions: .init { index in
adw_carousel_remove(widget, adw_carousel_get_nth_page(widget, UInt(index).cInt))
contentStorage.remove(at: index)
} insert: { index, element in
@ -144,6 +146,7 @@ public struct Carousel<Element>: AdwaitaWidget where Element: Identifiable {
for (index, element) in elements.enumerated() {
content(element).updateStorage(contentStorage[index], data: data, updateProperties: updateProperties, type: type)
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -155,32 +158,23 @@ public struct Carousel<Element>: AdwaitaWidget where Element: Identifiable {
/// Whether to allow swiping for more than one page at a time.
///
/// If the value is `FALSE`, each swipe can only move to the adjacent pages.
/// If the value is `false`, each swipe can only move to the adjacent pages.
public func allowLongSwipes(_ allowLongSwipes: Bool? = true) -> Self {
var newSelf = self
newSelf.allowLongSwipes = allowLongSwipes
return newSelf
modify { $0.allowLongSwipes = allowLongSwipes }
}
/// Sets whether the `AdwCarousel` can be dragged with mouse pointer.
///
/// If the value is `FALSE`, dragging is only available on touch.
/// If the value is `false`, dragging is only available on touch.
public func allowMouseDrag(_ allowMouseDrag: Bool? = true) -> Self {
var newSelf = self
newSelf.allowMouseDrag = allowMouseDrag
return newSelf
modify { $0.allowMouseDrag = allowMouseDrag }
}
/// Whether the widget will respond to scroll wheel events.
///
/// If the value is `FALSE`, wheel events will be ignored.
/// If the value is `false`, wheel events will be ignored.
public func allowScrollWheel(_ allowScrollWheel: Bool? = true) -> Self {
var newSelf = self
newSelf.allowScrollWheel = allowScrollWheel
return newSelf
modify { $0.allowScrollWheel = allowScrollWheel }
}
/// Whether the carousel can be navigated.
@ -188,36 +182,24 @@ public struct Carousel<Element>: AdwaitaWidget where Element: Identifiable {
/// This can be used to temporarily disable the carousel to only allow
/// navigating it in a certain state.
public func interactive(_ interactive: Bool? = true) -> Self {
var newSelf = self
newSelf.interactive = interactive
return newSelf
modify { $0.interactive = interactive }
}
/// The number of pages in a `AdwCarousel`.
public func nPages(_ nPages: UInt?) -> Self {
var newSelf = self
newSelf.nPages = nPages
return newSelf
modify { $0.nPages = nPages }
}
/// Page reveal duration, in milliseconds.
///
/// Reveal duration is used when animating adding or removing pages.
public func revealDuration(_ revealDuration: UInt?) -> Self {
var newSelf = self
newSelf.revealDuration = revealDuration
return newSelf
modify { $0.revealDuration = revealDuration }
}
/// Spacing between pages in pixels.
public func spacing(_ spacing: UInt?) -> Self {
var newSelf = self
newSelf.spacing = spacing
return newSelf
modify { $0.spacing = spacing }
}
/// This signal is emitted after a page has been changed.
@ -225,8 +207,8 @@ public struct Carousel<Element>: AdwaitaWidget where Element: Identifiable {
/// It can be used to implement "infinite scrolling" by amending the pages
/// after every scroll.
///
/// ::: note
/// An empty carousel is indicated by `(int)index == -1`.
/// > [!NOTE]
/// > An empty carousel is indicated by `(int)index == -1`.
public func pageChanged(_ pageChanged: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.pageChanged = pageChanged
@ -234,3 +216,14 @@ public struct Carousel<Element>: AdwaitaWidget where Element: Identifiable {
}
}
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,80 +2,66 @@
// CenterBox.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// `GtkCenterBox` arranges three children in a row, keeping the middle child
/// Arranges three children in a row, keeping the middle child
/// centered as well as possible.
///
/// ![An example GtkCenterBox](centerbox.png)
///
/// To add children to `GtkCenterBox`, use [method@Gtk.CenterBox.set_start_widget],
/// [method@Gtk.CenterBox.set_center_widget] and
/// [method@Gtk.CenterBox.set_end_widget].
///
/// To add children to `GtkCenterBox`, use `Gtk.CenterBox.set_start_widget`,
/// `Gtk.CenterBox.set_center_widget` and
/// `Gtk.CenterBox.set_end_widget`.
///
/// The sizing and positioning of children can be influenced with the
/// align and expand properties of the children.
///
/// # GtkCenterBox as GtkBuildable
///
/// The `GtkCenterBox` implementation of the `GtkBuildable` interface
/// supports placing children in the 3 positions by specifying start, center
/// or end as the type attribute of a `<child>` element.
///
/// # CSS nodes
///
/// `GtkCenterBox` uses a single CSS node with the name box,
///
/// The first child of the `GtkCenterBox` will be allocated depending on the
/// text direction, i.e. in left-to-right layouts it will be allocated on the
/// left and in right-to-left layouts on the right.
///
/// In vertical orientation, the nodes of the children are arranged from top to
/// bottom.
///
/// # Accessibility
///
/// Until GTK 4.10, `GtkCenterBox` used the `GTK_ACCESSIBLE_ROLE_GROUP` role.
///
/// Starting from GTK 4.12, `GtkCenterBox` uses the `GTK_ACCESSIBLE_ROLE_GENERIC` role.
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.
///
/// The accessible role cannot be changed once set.
var accessibleRole: String?
/// The widget that is placed at the center position.
var centerWidget: (() -> Body)?
var centerWidget: Body?
/// The widget that is placed at the end position.
///
/// In vertical orientation, the end position is at the bottom.
/// In horizontal orientation, the end position is at the trailing
/// edge wrt. to the text direction.
var endWidget: (() -> Body)?
/// edge with respect to the text direction.
var endWidget: Body?
/// Whether to shrink the center widget after other children.
///
/// By default, when there's no space to give all three children their
/// natural widths, the start and end widgets start shrinking and the
/// center child keeps natural width until they reach minimum width.
///
/// If set to `FALSE`, start and end widgets keep natural width and the
/// If false, start and end widgets keep natural width and the
/// center widget starts shrinking instead.
var shrinkCenterLast: Bool?
/// The widget that is placed at the start position.
///
/// In vertical orientation, the start position is at the top.
/// In horizontal orientation, the start position is at the leading
/// edge wrt. to the text direction.
var startWidget: (() -> Body)?
/// edge with respect to the text direction.
var startWidget: Body?
/// Initialize `CenterBox`.
public init() {
@ -91,16 +77,15 @@ 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) {
if let centerWidgetStorage = centerWidget?.storage(data: data, type: type) {
storage.content["centerWidget"] = [centerWidgetStorage]
gtk_center_box_set_center_widget(storage.opaquePointer, centerWidgetStorage.opaquePointer?.cast())
}
if let endWidgetStorage = endWidget?().storage(data: data, type: type) {
if let endWidgetStorage = endWidget?.storage(data: data, type: type) {
storage.content["endWidget"] = [endWidgetStorage]
gtk_center_box_set_end_widget(storage.opaquePointer, endWidgetStorage.opaquePointer?.cast())
}
if let startWidgetStorage = startWidget?().storage(data: data, type: type) {
if let startWidgetStorage = startWidget?.storage(data: data, type: type) {
storage.content["startWidget"] = [startWidgetStorage]
gtk_center_box_set_start_widget(storage.opaquePointer, startWidgetStorage.opaquePointer?.cast())
}
@ -118,19 +103,20 @@ public struct CenterBox: AdwaitaWidget {
storage.modify { widget in
if let widget = storage.content["centerWidget"]?.first {
centerWidget?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
centerWidget?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
if let widget = storage.content["endWidget"]?.first {
endWidget?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
endWidget?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
if let shrinkCenterLast, updateProperties, (storage.previousState as? Self)?.shrinkCenterLast != shrinkCenterLast {
gtk_center_box_set_shrink_center_last(widget, shrinkCenterLast.cBool)
}
if let widget = storage.content["startWidget"]?.first {
startWidget?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
startWidget?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -144,30 +130,21 @@ public struct CenterBox: AdwaitaWidget {
///
/// The accessible role cannot be changed once set.
public func accessibleRole(_ accessibleRole: String?) -> Self {
var newSelf = self
newSelf.accessibleRole = accessibleRole
return newSelf
modify { $0.accessibleRole = accessibleRole }
}
/// The widget that is placed at the center position.
public func centerWidget(@ViewBuilder _ centerWidget: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.centerWidget = centerWidget
return newSelf
public func centerWidget(@ViewBuilder _ centerWidget: () -> Body) -> Self {
modify { $0.centerWidget = centerWidget() }
}
/// The widget that is placed at the end position.
///
/// In vertical orientation, the end position is at the bottom.
/// In horizontal orientation, the end position is at the trailing
/// edge wrt. to the text direction.
public func endWidget(@ViewBuilder _ endWidget: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.endWidget = endWidget
return newSelf
/// edge with respect to the text direction.
public func endWidget(@ViewBuilder _ endWidget: () -> Body) -> Self {
modify { $0.endWidget = endWidget() }
}
/// Whether to shrink the center widget after other children.
@ -176,25 +153,19 @@ public struct CenterBox: AdwaitaWidget {
/// natural widths, the start and end widgets start shrinking and the
/// center child keeps natural width until they reach minimum width.
///
/// If set to `FALSE`, start and end widgets keep natural width and the
/// If false, start and end widgets keep natural width and the
/// center widget starts shrinking instead.
public func shrinkCenterLast(_ shrinkCenterLast: Bool? = true) -> Self {
var newSelf = self
newSelf.shrinkCenterLast = shrinkCenterLast
return newSelf
modify { $0.shrinkCenterLast = shrinkCenterLast }
}
/// The widget that is placed at the start position.
///
/// In vertical orientation, the start position is at the top.
/// In horizontal orientation, the start position is at the leading
/// edge wrt. to the text direction.
public func startWidget(@ViewBuilder _ startWidget: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.startWidget = startWidget
return newSelf
/// edge with respect to the text direction.
public func startWidget(@ViewBuilder _ startWidget: () -> Body) -> Self {
modify { $0.startWidget = startWidget() }
}
}

View File

@ -2,89 +2,51 @@
// CheckButton.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// A `GtkCheckButton` places a label next to an indicator.
/// Places a label next to an indicator.
///
/// ![Example GtkCheckButtons](check-button.png)
///
/// A `GtkCheckButton` is created by calling either [ctor@Gtk.CheckButton.new]
/// or [ctor@Gtk.CheckButton.new_with_label].
///
/// A `GtkCheckButton` is created by calling either `Gtk.CheckButton.new`
/// or `Gtk.CheckButton.new_with_label`.
///
/// The state of a `GtkCheckButton` can be set specifically using
/// [method@Gtk.CheckButton.set_active], and retrieved using
/// [method@Gtk.CheckButton.get_active].
/// `Gtk.CheckButton.set_active`, and retrieved using
/// `Gtk.CheckButton.get_active`.
///
/// # Inconsistent state
///
/// In addition to "on" and "off", check buttons can be an
/// "in between" state that is neither on nor off. This can be used
/// e.g. when the user has selected a range of elements (such as some
/// text or spreadsheet cells) that are affected by a check button,
/// and the current values in that range are inconsistent.
///
/// To set a `GtkCheckButton` to inconsistent state, use
/// [method@Gtk.CheckButton.set_inconsistent].
///
/// # Grouping
///
/// Check buttons can be grouped together, to form mutually exclusive
/// groups - only one of the buttons can be toggled at a time, and toggling
/// another one will switch the currently toggled one off.
///
/// Grouped check buttons use a different indicator, and are commonly referred
/// to as *radio buttons*.
///
/// ![Example GtkCheckButtons](radio-button.png)
///
/// To add a `GtkCheckButton` to a group, use [method@Gtk.CheckButton.set_group].
///
/// When the code must keep track of the state of a group of radio buttons, it
/// is recommended to keep track of such state through a stateful
/// `GAction` with a target for each button. Using the `toggled` signals to keep
/// track of the group changes and state is discouraged.
///
/// # CSS nodes
///
/// ```
/// checkbutton[.text-button]
/// check
/// [label]
/// ```
///
/// A `GtkCheckButton` has a main node with name checkbutton. If the
/// [property@Gtk.CheckButton:label] or [property@Gtk.CheckButton:child]
/// properties are set, it contains a child widget. The indicator node
/// is named check when no group is set, and radio if the checkbutton
/// is grouped together with other checkbuttons.
///
/// # Accessibility
///
/// `GtkCheckButton` uses the %GTK_ACCESSIBLE_ROLE_CHECKBOX role.
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.
///
/// The accessible role cannot be changed once set.
var accessibleRole: String?
/// action-name
/// The name of the action with which this widget should be associated.
var actionName: String?
/// If the check button is active.
///
/// Setting `active` to %TRUE will add the `:checked:` state to both
/// Setting `active` to `true` will add the `:checked:` state to both
/// the check button and the indicator CSS node.
var active: Binding<Bool>?
/// The child widget.
var child: (() -> Body)?
var child: Body?
/// If the check button is in an in between state.
///
/// The inconsistent state only affects visual appearance,
@ -101,12 +63,12 @@ public struct CheckButton: AdwaitaWidget {
/// emitting it causes the button to animate press then release.
///
/// Applications should never connect to this signal, but use the
/// [signal@Gtk.CheckButton::toggled] signal.
/// `Gtk.CheckButton::toggled` signal.
///
/// The default bindings for this signal are all forms of the
/// <kbd></kbd> and <kbd>Enter</kbd> keys.
var activate: (() -> Void)?
/// Emitted when the buttons's [property@Gtk.CheckButton:active]
/// Emitted when the buttons's ``active(_:)``
/// property changes.
var toggled: (() -> Void)?
@ -124,8 +86,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) {
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
gtk_check_button_set_child(storage.opaquePointer?.cast(), childStorage.opaquePointer?.cast())
}
@ -165,7 +126,7 @@ if let active, newValue != active.wrappedValue {
gtk_check_button_set_active(storage.opaquePointer?.cast(), active.wrappedValue.cBool)
}
if let widget = storage.content["child"]?.first {
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
child?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
if let inconsistent, updateProperties, (storage.previousState as? Self)?.inconsistent != inconsistent {
gtk_check_button_set_inconsistent(widget?.cast(), inconsistent.cBool)
@ -178,6 +139,7 @@ if let active, newValue != active.wrappedValue {
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -191,37 +153,25 @@ if let active, newValue != active.wrappedValue {
///
/// The accessible role cannot be changed once set.
public func accessibleRole(_ accessibleRole: String?) -> Self {
var newSelf = self
newSelf.accessibleRole = accessibleRole
return newSelf
modify { $0.accessibleRole = accessibleRole }
}
/// action-name
/// The name of the action with which this widget should be associated.
public func actionName(_ actionName: String?) -> Self {
var newSelf = self
newSelf.actionName = actionName
return newSelf
modify { $0.actionName = actionName }
}
/// If the check button is active.
///
/// Setting `active` to %TRUE will add the `:checked:` state to both
/// Setting `active` to `true` will add the `:checked:` state to both
/// the check button and the indicator CSS node.
public func active(_ active: Binding<Bool>?) -> Self {
var newSelf = self
newSelf.active = active
return newSelf
modify { $0.active = active }
}
/// The child widget.
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.child = child
return newSelf
public func child(@ViewBuilder _ child: () -> Body) -> Self {
modify { $0.child = child() }
}
/// If the check button is in an in between state.
@ -229,27 +179,18 @@ if let active, newValue != active.wrappedValue {
/// The inconsistent state only affects visual appearance,
/// not the semantics of the button.
public func inconsistent(_ inconsistent: Bool? = true) -> Self {
var newSelf = self
newSelf.inconsistent = inconsistent
return newSelf
modify { $0.inconsistent = inconsistent }
}
/// Text of the label inside the check button, if it contains a label widget.
public func label(_ label: String?) -> Self {
var newSelf = self
newSelf.label = label
return newSelf
modify { $0.label = label }
}
/// If set, an underline in the text indicates that the following
/// character is to be used as mnemonic.
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
var newSelf = self
newSelf.useUnderline = useUnderline
return newSelf
modify { $0.useUnderline = useUnderline }
}
/// Emitted to when the check button is activated.
@ -258,7 +199,7 @@ if let active, newValue != active.wrappedValue {
/// emitting it causes the button to animate press then release.
///
/// Applications should never connect to this signal, but use the
/// [signal@Gtk.CheckButton::toggled] signal.
/// `Gtk.CheckButton::toggled` signal.
///
/// The default bindings for this signal are all forms of the
/// <kbd></kbd> and <kbd>Enter</kbd> keys.
@ -268,7 +209,7 @@ if let active, newValue != active.wrappedValue {
return newSelf
}
/// Emitted when the buttons's [property@Gtk.CheckButton:active]
/// Emitted when the buttons's ``active(_:)``
/// property changes.
public func toggled(_ toggled: @escaping () -> Void) -> Self {
var newSelf = self

View File

@ -2,7 +2,7 @@
// Clamp.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
@ -10,7 +10,7 @@ import LevenshteinTransformations
/// A widget constraining its child to a given size.
///
/// <picture><source srcset="clamp-wide-dark.png" media="(prefers-color-scheme: dark)"><img src="clamp-wide.png" alt="clamp-wide"></picture><picture><source srcset="clamp-narrow-dark.png" media="(prefers-color-scheme: dark)"><img src="clamp-narrow.png" alt="clamp-narrow"></picture>
///
///
/// The `AdwClamp` widget constrains the size of the widget it contains to a
/// given maximum size. It will constrain the width if it is horizontal, or the
@ -21,20 +21,27 @@ import LevenshteinTransformations
/// allocated the minimum size it can fit in instead.
///
/// `AdwClamp` can scale with the text scale factor, use the
/// [property@ClampLayout:unit] property to enable that behavior.
/// ``unit(_:)`` property to enable that behavior.
///
/// See also: `ClampLayout`, `ClampScrollable`.
///
/// ## CSS nodes
///
/// `AdwClamp` has a single CSS node with name `clamp`.
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)?
var child: Body?
/// The maximum size allocated to the child.
///
/// It is the width if the clamp is horizontal, or the height if it is vertical.
@ -69,8 +76,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) {
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
adw_clamp_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())
}
@ -88,7 +94,7 @@ public struct Clamp: AdwaitaWidget {
storage.modify { widget in
if let widget = storage.content["child"]?.first {
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
child?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
if let maximumSize, updateProperties, (storage.previousState as? Self)?.maximumSize != maximumSize {
adw_clamp_set_maximum_size(widget, maximumSize.cInt)
@ -98,6 +104,7 @@ public struct Clamp: AdwaitaWidget {
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -108,21 +115,15 @@ public struct Clamp: AdwaitaWidget {
}
/// The child widget of the `AdwClamp`.
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.child = child
return newSelf
public func child(@ViewBuilder _ child: () -> Body) -> Self {
modify { $0.child = child() }
}
/// The maximum size allocated to the child.
///
/// It is the width if the clamp is horizontal, or the height if it is vertical.
public func maximumSize(_ maximumSize: Int?) -> Self {
var newSelf = self
newSelf.maximumSize = maximumSize
return newSelf
modify { $0.maximumSize = maximumSize }
}
/// The size above which the child is clamped.
@ -140,10 +141,7 @@ public struct Clamp: AdwaitaWidget {
/// Effectively, tightening the grip on the child before it reaches its maximum
/// size makes transitions to and from the maximum size smoother when resizing.
public func tighteningThreshold(_ tighteningThreshold: Int?) -> Self {
var newSelf = self
newSelf.tighteningThreshold = tighteningThreshold
return newSelf
modify { $0.tighteningThreshold = tighteningThreshold }
}
}

View File

@ -2,15 +2,15 @@
// ComboRow.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// A [class@Gtk.ListBoxRow] used to choose from a list of items.
/// A `Gtk.ListBoxRow` used to choose from a list of items.
///
///
/// <picture><source srcset="combo-row-dark.png" media="(prefers-color-scheme: dark)"><img src="combo-row.png" alt="combo-row"></picture>
///
/// The `AdwComboRow` widget allows the user to choose from a list of valid
/// choices. The row displays the selected choice. When activated, the row
@ -21,59 +21,55 @@ import LevenshteinTransformations
/// <object class="AdwComboRow"><property name="title" translatable="yes">Combo Row</property><property name="model"><object class="GtkStringList"><items><item translatable="yes">Foo</item><item translatable="yes">Bar</item><item translatable="yes">Baz</item></items></object></property></object>
/// ```
///
/// The [property@ComboRow:selected] and [property@ComboRow:selected-item]
/// The ``selected(_:)`` and ``selectedItem(_:)``
/// properties can be used to keep track of the selected item and react to their
/// changes.
///
/// `AdwComboRow` mirrors [class@Gtk.DropDown], see that widget for details.
/// `AdwComboRow` mirrors `Gtk.DropDown`, see that widget for details.
///
/// `AdwComboRow` is [property@Gtk.ListBoxRow:activatable] if a model is set.
/// `AdwComboRow` is ``activatable(_:)`` if a model is set.
///
/// ## CSS nodes
///
/// `AdwComboRow` has a main CSS node with name `row` and the `.combo` style
/// class.
///
/// Its popover has the node named `popover` with the `.menu` style class, it
/// contains a [class@Gtk.ScrolledWindow], which in turn contains a
/// [class@Gtk.ListView], both are accessible via their regular nodes.
///
/// ## Accessibility
///
/// `AdwComboRow` uses the `GTK_ACCESSIBLE_ROLE_COMBO_BOX` role.
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.
///
/// The row can be activated either by clicking on it, calling
/// [method@ActionRow.activate], or via mnemonics in the title.
/// See the [property@PreferencesRow:use-underline] property to enable
/// `ActionRow.activate`, or via mnemonics in the title.
/// See the ``useUnderline(_:)`` property to enable
/// mnemonics.
///
/// The target widget will be activated by emitting the
/// [signal@Gtk.Widget::mnemonic-activate] signal on it.
var activatableWidget: (() -> Body)?
/// `Gtk.Widget::mnemonic-activate` signal on it.
var activatableWidget: Body?
/// Whether to show a search entry in the popup.
///
/// If set to `TRUE`, a search entry will be shown in the popup that
/// If set to `true`, a search entry will be shown in the popup that
/// allows to search for items in the list.
///
/// Search requires [property@ComboRow:expression] to be set.
/// Search requires ``expression(_:)`` to be set.
var enableSearch: Bool?
/// The position of the selected item.
///
/// If no item is selected, the property has the value
/// [const@Gtk.INVALID_LIST_POSITION]
/// `Gtk.INVALID_LIST_POSITION`
var selected: Binding<UInt>?
/// The subtitle for this row.
///
/// The subtitle is interpreted as Pango markup unless
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
/// ``useMarkup(_:)`` is set to `false`.
var subtitle: String?
/// The number of lines at the end of which the subtitle label will be
/// ellipsized.
@ -82,12 +78,12 @@ public struct ComboRow: AdwaitaWidget {
var subtitleLines: Int?
/// Whether the user can copy the subtitle from the label.
///
/// See also [property@Gtk.Label:selectable].
/// See also ``selectable(_:)``.
var subtitleSelectable: Bool?
/// The title of the preference represented by this row.
///
/// The title is interpreted as Pango markup unless
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
/// ``useMarkup(_:)`` is set to `false`.
var title: String?
/// The number of lines at the end of which the title label will be ellipsized.
///
@ -95,23 +91,23 @@ public struct ComboRow: AdwaitaWidget {
var titleLines: Int?
/// Whether the user can copy the title from the label.
///
/// See also [property@Gtk.Label:selectable].
/// See also ``selectable(_:)``.
var titleSelectable: Bool?
/// Whether to use Pango markup for the title label.
///
/// Subclasses may also use it for other labels, such as subtitle.
///
/// See also [func@Pango.parse_markup].
/// See also `Pango.parse_markup`.
var useMarkup: Bool?
/// Whether to use the current value as the subtitle.
///
/// If you use a custom list item factory, you will need to give the row a
/// name conversion expression with [property@ComboRow:expression].
/// name conversion expression with ``expression(_:)``.
///
/// If set to `TRUE`, you should not access [property@ActionRow:subtitle].
/// If set to `true`, you should not access ``subtitle(_:)``.
///
/// The subtitle is interpreted as Pango markup if
/// [property@PreferencesRow:use-markup] is set to `TRUE`.
/// ``useMarkup(_:)`` is set to `true`.
var useSubtitle: Bool?
/// Whether an embedded underline in the title indicates a mnemonic.
var useUnderline: Bool?
@ -123,7 +119,7 @@ public struct ComboRow: AdwaitaWidget {
var prefix: () -> Body = { [] }
/// Initialize `ComboRow`.
public init() {
init() {
}
/// The view storage.
@ -136,8 +132,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) {
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())
}
@ -178,7 +173,7 @@ if let selected, newValue != selected.wrappedValue {
}
}
if let widget = storage.content["activatableWidget"]?.first {
activatableWidget?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
activatableWidget?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
if let enableSearch, updateProperties, (storage.previousState as? Self)?.enableSearch != enableSearch {
adw_combo_row_set_enable_search(widget?.cast(), enableSearch.cBool)
@ -215,6 +210,7 @@ if let selected, newValue != selected.wrappedValue {
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -227,52 +223,40 @@ if let selected, newValue != selected.wrappedValue {
/// The widget to activate when the row is activated.
///
/// The row can be activated either by clicking on it, calling
/// [method@ActionRow.activate], or via mnemonics in the title.
/// See the [property@PreferencesRow:use-underline] property to enable
/// `ActionRow.activate`, or via mnemonics in the title.
/// See the ``useUnderline(_:)`` property to enable
/// mnemonics.
///
/// The target widget will be activated by emitting the
/// [signal@Gtk.Widget::mnemonic-activate] signal on it.
public func activatableWidget(@ViewBuilder _ activatableWidget: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.activatableWidget = activatableWidget
return newSelf
/// `Gtk.Widget::mnemonic-activate` signal on it.
public func activatableWidget(@ViewBuilder _ activatableWidget: () -> Body) -> Self {
modify { $0.activatableWidget = activatableWidget() }
}
/// Whether to show a search entry in the popup.
///
/// If set to `TRUE`, a search entry will be shown in the popup that
/// If set to `true`, a search entry will be shown in the popup that
/// allows to search for items in the list.
///
/// Search requires [property@ComboRow:expression] to be set.
/// Search requires ``expression(_:)`` to be set.
public func enableSearch(_ enableSearch: Bool? = true) -> Self {
var newSelf = self
newSelf.enableSearch = enableSearch
return newSelf
modify { $0.enableSearch = enableSearch }
}
/// The position of the selected item.
///
/// If no item is selected, the property has the value
/// [const@Gtk.INVALID_LIST_POSITION]
/// `Gtk.INVALID_LIST_POSITION`
public func selected(_ selected: Binding<UInt>?) -> Self {
var newSelf = self
newSelf.selected = selected
return newSelf
modify { $0.selected = selected }
}
/// The subtitle for this row.
///
/// The subtitle is interpreted as Pango markup unless
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
/// ``useMarkup(_:)`` is set to `false`.
public func subtitle(_ subtitle: String?) -> Self {
var newSelf = self
newSelf.subtitle = subtitle
return newSelf
modify { $0.subtitle = subtitle }
}
/// The number of lines at the end of which the subtitle label will be
@ -280,87 +264,63 @@ if let selected, newValue != selected.wrappedValue {
///
/// If the value is 0, the number of lines won't be limited.
public func subtitleLines(_ subtitleLines: Int?) -> Self {
var newSelf = self
newSelf.subtitleLines = subtitleLines
return newSelf
modify { $0.subtitleLines = subtitleLines }
}
/// Whether the user can copy the subtitle from the label.
///
/// See also [property@Gtk.Label:selectable].
/// See also ``selectable(_:)``.
public func subtitleSelectable(_ subtitleSelectable: Bool? = true) -> Self {
var newSelf = self
newSelf.subtitleSelectable = subtitleSelectable
return newSelf
modify { $0.subtitleSelectable = subtitleSelectable }
}
/// The title of the preference represented by this row.
///
/// The title is interpreted as Pango markup unless
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
/// ``useMarkup(_:)`` is set to `false`.
public func title(_ title: String?) -> Self {
var newSelf = self
newSelf.title = title
return newSelf
modify { $0.title = title }
}
/// The number of lines at the end of which the title label will be ellipsized.
///
/// If the value is 0, the number of lines won't be limited.
public func titleLines(_ titleLines: Int?) -> Self {
var newSelf = self
newSelf.titleLines = titleLines
return newSelf
modify { $0.titleLines = titleLines }
}
/// Whether the user can copy the title from the label.
///
/// See also [property@Gtk.Label:selectable].
/// See also ``selectable(_:)``.
public func titleSelectable(_ titleSelectable: Bool? = true) -> Self {
var newSelf = self
newSelf.titleSelectable = titleSelectable
return newSelf
modify { $0.titleSelectable = titleSelectable }
}
/// Whether to use Pango markup for the title label.
///
/// Subclasses may also use it for other labels, such as subtitle.
///
/// See also [func@Pango.parse_markup].
/// See also `Pango.parse_markup`.
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
var newSelf = self
newSelf.useMarkup = useMarkup
return newSelf
modify { $0.useMarkup = useMarkup }
}
/// Whether to use the current value as the subtitle.
///
/// If you use a custom list item factory, you will need to give the row a
/// name conversion expression with [property@ComboRow:expression].
/// name conversion expression with ``expression(_:)``.
///
/// If set to `TRUE`, you should not access [property@ActionRow:subtitle].
/// If set to `true`, you should not access ``subtitle(_:)``.
///
/// The subtitle is interpreted as Pango markup if
/// [property@PreferencesRow:use-markup] is set to `TRUE`.
/// ``useMarkup(_:)`` is set to `true`.
public func useSubtitle(_ useSubtitle: Bool? = true) -> Self {
var newSelf = self
newSelf.useSubtitle = useSubtitle
return newSelf
modify { $0.useSubtitle = useSubtitle }
}
/// Whether an embedded underline in the title indicates a mnemonic.
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
var newSelf = self
newSelf.useUnderline = useUnderline
return newSelf
modify { $0.useUnderline = useUnderline }
}
/// This signal is emitted after the row has been activated.

View File

@ -0,0 +1,182 @@
//
// DropDown.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// Allows the user to choose an item from a list of options.
///
///
///
/// The `GtkDropDown` displays the [selected]``selected(_:)``
/// choice.
///
/// The options are given to `GtkDropDown` in the form of `GListModel`
/// and how the individual options are represented is determined by
/// a `Gtk.ListItemFactory`. The default factory displays simple strings,
/// and adds a checkmark to the selected item in the popup.
///
/// To set your own factory, use `Gtk.DropDown.set_factory`. It is
/// possible to use a separate factory for the items in the popup, with
/// `Gtk.DropDown.set_list_factory`.
///
/// `GtkDropDown` knows how to obtain strings from the items in a
/// `Gtk.StringList`; for other models, you have to provide an expression
/// to find the strings via `Gtk.DropDown.set_expression`.
///
/// `GtkDropDown` can optionally allow search in the popup, which is
/// useful if the list of options is long. To enable the search entry,
/// use `Gtk.DropDown.set_enable_search`.
///
/// Here is a UI definition example for `GtkDropDown` with a simple model:
///
/// ```xml
/// <object class="GtkDropDown"><property name="model"><object class="GtkStringList"><items><item translatable="yes">Factory</item><item translatable="yes">Home</item><item translatable="yes">Subway</item></items></object></property></object>
/// ```
///
/// If a `GtkDropDown` is created in this manner, or with
/// `Gtk.DropDown.new_from_strings`, for instance, the object returned from
/// `Gtk.DropDown.get_selected_item` will be a `Gtk.StringObject`.
///
/// To learn more about the list widget framework, see the
/// [overview](section-list-widget.html).
///
///
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.
///
/// The accessible role cannot be changed once set.
var accessibleRole: String?
/// Whether to show a search entry in the popup.
///
/// Note that search requires ``expression(_:)``
/// to be set.
var enableSearch: Bool?
/// The position of the selected item.
///
/// If no item is selected, the property has the value
/// %GTK_INVALID_LIST_POSITION.
var selected: Binding<UInt>?
/// Whether to show an arrow within the GtkDropDown widget.
var showArrow: Bool?
/// Emitted to when the drop down is activated.
///
/// The `::activate` signal on `GtkDropDown` is an action signal and
/// emitting it causes the drop down to pop up its dropdown.
var activate: (() -> Void)?
/// Initialize `DropDown`.
init() {
}
/// The view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The view render data type.
/// - Returns: The view storage.
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
let storage = ViewStorage(gtk_drop_down_new(gtk_string_list_new(nil), nil)?.opaque())
for function in appearFunctions {
function(storage, data)
}
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.
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
if let activate {
storage.connectSignal(name: "activate", argCount: 0) {
activate()
}
}
storage.modify { widget in
storage.notify(name: "selected") {
let newValue = UInt(gtk_drop_down_get_selected(storage.opaquePointer))
if let selected, newValue != selected.wrappedValue {
selected.wrappedValue = newValue
}
}
if let enableSearch, updateProperties, (storage.previousState as? Self)?.enableSearch != enableSearch {
gtk_drop_down_set_enable_search(widget, enableSearch.cBool)
}
if let selected, updateProperties, (UInt(gtk_drop_down_get_selected(storage.opaquePointer))) != selected.wrappedValue {
gtk_drop_down_set_selected(storage.opaquePointer, selected.wrappedValue.cInt)
}
if let showArrow, updateProperties, (storage.previousState as? Self)?.showArrow != showArrow {
gtk_drop_down_set_show_arrow(widget, showArrow.cBool)
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
}
if updateProperties {
storage.previousState = self
}
}
/// The accessible role of the given `GtkAccessible` implementation.
///
/// The accessible role cannot be changed once set.
public func accessibleRole(_ accessibleRole: String?) -> Self {
modify { $0.accessibleRole = accessibleRole }
}
/// Whether to show a search entry in the popup.
///
/// Note that search requires ``expression(_:)``
/// to be set.
public func enableSearch(_ enableSearch: Bool? = true) -> Self {
modify { $0.enableSearch = enableSearch }
}
/// The position of the selected item.
///
/// If no item is selected, the property has the value
/// %GTK_INVALID_LIST_POSITION.
public func selected(_ selected: Binding<UInt>?) -> Self {
modify { $0.selected = selected }
}
/// Whether to show an arrow within the GtkDropDown widget.
public func showArrow(_ showArrow: Bool? = true) -> Self {
modify { $0.showArrow = showArrow }
}
/// Emitted to when the drop down is activated.
///
/// The `::activate` signal on `GtkDropDown` is an action signal and
/// emitting it causes the drop down to pop up its dropdown.
public func activate(_ activate: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.activate = activate
return newSelf
}
}

View File

@ -0,0 +1,779 @@
//
// Entry.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// A single-line text entry widget.
///
///
///
/// A fairly large set of key bindings are supported by default. If the
/// entered text is longer than the allocation of the widget, the widget
/// will scroll so that the cursor position is visible.
///
/// When using an entry for passwords and other sensitive information, it
/// can be put into password mode using `Gtk.Entry.set_visibility`.
/// In this mode, entered text is displayed using a invisible character.
/// By default, GTK picks the best invisible character that is available
/// in the current font, but it can be changed with
/// `Gtk.Entry.set_invisible_char`.
///
/// `GtkEntry` has the ability to display progress or activity
/// information behind the text. To make an entry display such information,
/// use `Gtk.Entry.set_progress_fraction` or
/// `Gtk.Entry.set_progress_pulse_step`.
///
/// Additionally, `GtkEntry` can show icons at either side of the entry.
/// These icons can be activatable by clicking, can be set up as drag source
/// and can have tooltips. To add an icon, use
/// `Gtk.Entry.set_icon_from_gicon` or one of the various other functions
/// that set an icon from an icon name or a paintable. To trigger an action when
/// the user clicks an icon, connect to the `Gtk.Entry::icon-press` signal.
/// To allow DND operations from an icon, use
/// `Gtk.Entry.set_icon_drag_source`. To set a tooltip on an icon, use
/// `Gtk.Entry.set_icon_tooltip_text` or the corresponding function
/// for markup.
///
/// Note that functionality or information that is only available by clicking
/// on an icon in an entry may not be accessible at all to users which are not
/// able to use a mouse or other pointing device. It is therefore recommended
/// that any such functionality should also be available by other means, e.g.
/// via the context menu of the entry.
///
///
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.
///
/// The accessible role cannot be changed once set.
var accessibleRole: String?
/// The current position of the insertion cursor in chars.
var cursorPosition: Int?
/// Whether the entry contents can be edited.
var editable: Bool?
/// Indicates whether editing on the cell has been canceled.
var editingCanceled: Bool?
/// Whether to suggest Emoji replacements for :-delimited names
/// like `:heart:`.
var enableEmojiCompletion: Bool?
/// If undo/redo should be enabled for the editable.
var enableUndo: Bool?
/// A menu model whose contents will be appended to the context menu.
var extraMenu: Body?
/// Whether the entry should draw a frame.
var hasFrame: Bool?
/// Which IM (input method) module should be used for this entry.
///
/// See `Gtk.IMContext`.
///
/// Setting this to a non-%NULL value overrides the system-wide IM
/// module setting. See the GtkSettings ``gtkImModule(_:)``
/// property.
var imModule: String?
/// The character to use when masking entry contents (password mode).
var invisibleCharacter: UInt?
/// Whether the invisible char has been set for the `GtkEntry`.
var invisibleCharacterSet: Bool?
/// Maximum number of characters for this entry.
var maxLength: Int?
/// The desired maximum width of the entry, in characters.
var maxWidthChars: Int?
/// Text for an item in the context menu to activate the primary icon action.
///
/// When the primary icon is activatable and this property has been set, a new entry
/// in the context menu of this GtkEntry will appear with this text. Selecting that
/// menu entry will result in the primary icon being activated, exactly in the same way
/// as it would be activated from a mouse click.
///
/// This simplifies adding accessibility support to applications using activatable
/// icons. The activatable icons aren't focusable when navigating the interface with
/// the keyboard This is why Gtk recommends to also add those actions in the context
/// menu. This set of methods greatly simplifies this, by adding a menu item that, when
/// enabled, calls the same callback than clicking on the icon.
var menuEntryIconPrimaryText: String?
/// Text for an item in the context menu to activate the secondary icon action.
///
/// When the primary icon is activatable and this property has been set, a new entry
/// in the context menu of this GtkEntry will appear with this text. Selecting that
/// menu entry will result in the primary icon being activated, exactly in the same way
/// as it would be activated from a mouse click.
///
/// This simplifies adding accessibility support to applications using activatable
/// icons. The activatable icons aren't focusable when navigating the interface with
/// the keyboard This is why Gtk recommends to also add those actions in the context
/// menu. This set of methods greatly simplifies this, by adding a menu item that, when
/// enabled, calls the same callback than clicking on the icon.
var menuEntryIconSecondaryText: String?
/// If text is overwritten when typing in the `GtkEntry`.
var overwriteMode: Bool?
/// The text that will be displayed in the `GtkEntry` when it is empty
/// and unfocused.
var placeholderText: String?
/// Whether the primary icon is activatable.
///
/// GTK emits the `Gtk.Entry::icon-press` and
/// `Gtk.Entry::icon-release` signals only on sensitive,
/// activatable icons.
///
/// Sensitive, but non-activatable icons can be used for purely
/// informational purposes.
var primaryIconActivatable: Bool?
/// The icon name to use for the primary icon for the entry.
var primaryIconName: String?
/// Whether the primary icon is sensitive.
///
/// An insensitive icon appears grayed out. GTK does not emit the
/// `Gtk.Entry::icon-press` and `Gtk.Entry::icon-release`
/// signals and does not allow DND from insensitive icons.
///
/// An icon should be set insensitive if the action that would trigger
/// when clicked is currently not available.
var primaryIconSensitive: Bool?
/// The contents of the tooltip on the primary icon, with markup.
///
/// Also see `Gtk.Entry.set_icon_tooltip_markup`.
var primaryIconTooltipMarkup: String?
/// The contents of the tooltip on the primary icon.
///
/// Also see `Gtk.Entry.set_icon_tooltip_text`.
var primaryIconTooltipText: String?
/// The current fraction of the task that's been completed.
var progressFraction: Double?
/// The fraction of total entry width to move the progress
/// bouncing block for each pulse.
///
/// See `Gtk.Entry.progress_pulse`.
var progressPulseStep: Double?
/// Number of pixels of the entry scrolled off the screen to the left.
var scrollOffset: Int?
/// Whether the secondary icon is activatable.
///
/// GTK emits the `Gtk.Entry::icon-press` and
/// `Gtk.Entry::icon-release` signals only on sensitive,
/// activatable icons.
///
/// Sensitive, but non-activatable icons can be used for purely
/// informational purposes.
var secondaryIconActivatable: Bool?
/// The icon name to use for the secondary icon for the entry.
var secondaryIconName: String?
/// Whether the secondary icon is sensitive.
///
/// An insensitive icon appears grayed out. GTK does not emit the
/// `Gtk.Entry::icon-press[ and [signal@Gtk.Entry::icon-release`
/// signals and does not allow DND from insensitive icons.
///
/// An icon should be set insensitive if the action that would trigger
/// when clicked is currently not available.
var secondaryIconSensitive: Bool?
/// The contents of the tooltip on the secondary icon, with markup.
///
/// Also see `Gtk.Entry.set_icon_tooltip_markup`.
var secondaryIconTooltipMarkup: String?
/// The contents of the tooltip on the secondary icon.
///
/// Also see `Gtk.Entry.set_icon_tooltip_text`.
var secondaryIconTooltipText: String?
/// The position of the opposite end of the selection from the cursor in chars.
var selectionBound: Int?
/// Whether the entry will show an Emoji icon in the secondary icon position
/// to open the Emoji chooser.
var showEmojiIcon: Bool?
/// The contents of the entry.
var text: Binding<String>?
/// The length of the text in the `GtkEntry`.
var textLength: UInt?
/// When `true`, pasted multi-line text is truncated to the first line.
var truncateMultiline: Bool?
/// Whether the entry should show the invisible char instead of the
/// actual text (password mode).
var visibility: Bool?
/// Number of characters to leave space for in the entry.
var widthChars: Int?
/// The horizontal alignment, from 0 (left) to 1 (right).
///
/// Reversed for RTL layouts.
var xalign: Float?
/// Emitted when the entry is activated.
///
/// The keybindings for this signal are all forms of the Enter key.
var activate: (() -> Void)?
/// Emitted at the end of a single user-visible operation on the
/// contents.
///
/// E.g., a paste operation that replaces the contents of the
/// selection will cause only one signal emission (even though it
/// is implemented by first deleting the selection, then inserting
/// the new content, and may cause multiple ::notify::text signals
/// to be emitted).
var changed: (() -> Void)?
/// Emitted when text is deleted from the widget by the user.
///
/// The default handler for this signal will normally be responsible for
/// deleting the text, so by connecting to this signal and then stopping
/// the signal with g_signal_stop_emission(), it is possible to modify the
/// range of deleted text, or prevent it from being deleted entirely.
///
/// The @start_pos and @end_pos parameters are interpreted as for
/// `Gtk.Editable.delete_text`.
var deleteText: (() -> Void)?
/// This signal is a sign for the cell renderer to update its
/// value from the @cell_editable.
///
/// Implementations of `GtkCellEditable` are responsible for
/// emitting this signal when they are done editing, e.g.
/// `GtkEntry` emits this signal when the user presses Enter. Typical things to
/// do in a handler for ::editing-done are to capture the edited value,
/// disconnect the @cell_editable from signals on the `GtkCellRenderer`, etc.
///
/// gtk_cell_editable_editing_done() is a convenience method
/// for emitting `GtkCellEditable::editing-done`.
var editingDone: (() -> Void)?
/// Emitted when an activatable icon is clicked.
var iconPress: (() -> Void)?
/// Emitted on the button release from a mouse click
/// over an activatable icon.
var iconRelease: (() -> Void)?
/// Emitted when text is inserted into the widget by the user.
///
/// The default handler for this signal will normally be responsible
/// for inserting the text, so by connecting to this signal and then
/// stopping the signal with g_signal_stop_emission(), it is possible
/// to modify the inserted text, or prevent it from being inserted entirely.
var insertText: (() -> Void)?
/// This signal is meant to indicate that the cell is finished
/// editing, and the @cell_editable widget is being removed and may
/// subsequently be destroyed.
///
/// Implementations of `GtkCellEditable` are responsible for
/// emitting this signal when they are done editing. It must
/// be emitted after the `GtkCellEditable::editing-done` signal,
/// to give the cell renderer a chance to update the cell's value
/// before the widget is removed.
///
/// gtk_cell_editable_remove_widget() is a convenience method
/// for emitting `GtkCellEditable::remove-widget`.
var removeWidget: (() -> Void)?
/// Initialize `Entry`.
init() {
}
/// The view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The view render data type.
/// - Returns: The view storage.
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
let storage = ViewStorage(gtk_entry_new()?.opaque())
for function in appearFunctions {
function(storage, data)
}
if let extraMenu {
let childStorage = MenuCollection { extraMenu }.getMenu(data: data)
storage.content["extraMenu"] = [childStorage]
gtk_entry_set_extra_menu(storage.opaquePointer?.cast(), childStorage.opaquePointer?.cast())
}
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.
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
if let activate {
storage.connectSignal(name: "activate", argCount: 0) {
activate()
}
}
if let changed {
storage.connectSignal(name: "changed", argCount: 0) {
changed()
}
}
if let deleteText {
storage.connectSignal(name: "delete-text", argCount: 2) {
deleteText()
}
}
if let editingDone {
storage.connectSignal(name: "editing-done", argCount: 0) {
editingDone()
}
}
if let iconPress {
storage.connectSignal(name: "icon-press", argCount: 1) {
iconPress()
}
}
if let iconRelease {
storage.connectSignal(name: "icon-release", argCount: 1) {
iconRelease()
}
}
if let insertText {
storage.connectSignal(name: "insert-text", argCount: 3) {
insertText()
}
}
if let removeWidget {
storage.connectSignal(name: "remove-widget", argCount: 0) {
removeWidget()
}
}
storage.modify { widget in
storage.notify(name: "text") {
let newValue = String(cString: gtk_editable_get_text(storage.opaquePointer))
if let text, newValue != text.wrappedValue {
text.wrappedValue = newValue
}
}
if let cursorPosition, updateProperties, (storage.previousState as? Self)?.cursorPosition != cursorPosition {
gtk_editable_set_position(widget, cursorPosition.cInt)
}
if let editable, updateProperties, (storage.previousState as? Self)?.editable != editable {
gtk_editable_set_editable(widget, editable.cBool)
}
if let enableUndo, updateProperties, (storage.previousState as? Self)?.enableUndo != enableUndo {
gtk_editable_set_enable_undo(widget, enableUndo.cBool)
}
if let menu = storage.content["extraMenu"]?.first {
MenuCollection { extraMenu ?? [] }
.updateStorage(menu, data: data.noModifiers, updateProperties: updateProperties, type: MenuContext.self)
}
if let hasFrame, updateProperties, (storage.previousState as? Self)?.hasFrame != hasFrame {
gtk_entry_set_has_frame(widget?.cast(), hasFrame.cBool)
}
if let invisibleCharacter, updateProperties, (storage.previousState as? Self)?.invisibleCharacter != invisibleCharacter {
gtk_entry_set_invisible_char(widget?.cast(), invisibleCharacter.cInt)
}
if let maxLength, updateProperties, (storage.previousState as? Self)?.maxLength != maxLength {
gtk_entry_set_max_length(widget?.cast(), maxLength.cInt)
}
if let maxWidthChars, updateProperties, (storage.previousState as? Self)?.maxWidthChars != maxWidthChars {
gtk_editable_set_max_width_chars(widget, maxWidthChars.cInt)
}
if let overwriteMode, updateProperties, (storage.previousState as? Self)?.overwriteMode != overwriteMode {
gtk_entry_set_overwrite_mode(widget?.cast(), overwriteMode.cBool)
}
if let placeholderText, updateProperties, (storage.previousState as? Self)?.placeholderText != placeholderText {
gtk_entry_set_placeholder_text(widget?.cast(), placeholderText)
}
if let progressFraction, updateProperties, (storage.previousState as? Self)?.progressFraction != progressFraction {
gtk_entry_set_progress_fraction(widget?.cast(), progressFraction)
}
if let progressPulseStep, updateProperties, (storage.previousState as? Self)?.progressPulseStep != progressPulseStep {
gtk_entry_set_progress_pulse_step(widget?.cast(), progressPulseStep)
}
if let text, updateProperties, (String(cString: gtk_editable_get_text(storage.opaquePointer))) != text.wrappedValue {
gtk_editable_set_text(storage.opaquePointer, text.wrappedValue)
}
if let visibility, updateProperties, (storage.previousState as? Self)?.visibility != visibility {
gtk_entry_set_visibility(widget?.cast(), visibility.cBool)
}
if let widthChars, updateProperties, (storage.previousState as? Self)?.widthChars != widthChars {
gtk_editable_set_width_chars(widget, widthChars.cInt)
}
if let xalign, updateProperties, (storage.previousState as? Self)?.xalign != xalign {
gtk_editable_set_alignment(widget, xalign)
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
}
if updateProperties {
storage.previousState = self
}
}
/// The accessible role of the given `GtkAccessible` implementation.
///
/// The accessible role cannot be changed once set.
public func accessibleRole(_ accessibleRole: String?) -> Self {
modify { $0.accessibleRole = accessibleRole }
}
/// The current position of the insertion cursor in chars.
public func cursorPosition(_ cursorPosition: Int?) -> Self {
modify { $0.cursorPosition = cursorPosition }
}
/// Whether the entry contents can be edited.
public func editable(_ editable: Bool? = true) -> Self {
modify { $0.editable = editable }
}
/// Indicates whether editing on the cell has been canceled.
public func editingCanceled(_ editingCanceled: Bool? = true) -> Self {
modify { $0.editingCanceled = editingCanceled }
}
/// Whether to suggest Emoji replacements for :-delimited names
/// like `:heart:`.
public func enableEmojiCompletion(_ enableEmojiCompletion: Bool? = true) -> Self {
modify { $0.enableEmojiCompletion = enableEmojiCompletion }
}
/// If undo/redo should be enabled for the editable.
public func enableUndo(_ enableUndo: Bool? = true) -> Self {
modify { $0.enableUndo = enableUndo }
}
/// A menu model whose contents will be appended to the context menu.
public func extraMenu(@ViewBuilder _ extraMenu: () -> Body) -> Self {
modify { $0.extraMenu = extraMenu() }
}
/// Whether the entry should draw a frame.
public func hasFrame(_ hasFrame: Bool? = true) -> Self {
modify { $0.hasFrame = hasFrame }
}
/// Which IM (input method) module should be used for this entry.
///
/// See `Gtk.IMContext`.
///
/// Setting this to a non-%NULL value overrides the system-wide IM
/// module setting. See the GtkSettings ``gtkImModule(_:)``
/// property.
public func imModule(_ imModule: String?) -> Self {
modify { $0.imModule = imModule }
}
/// The character to use when masking entry contents (password mode).
public func invisibleCharacter(_ invisibleCharacter: UInt?) -> Self {
modify { $0.invisibleCharacter = invisibleCharacter }
}
/// Whether the invisible char has been set for the `GtkEntry`.
public func invisibleCharacterSet(_ invisibleCharacterSet: Bool? = true) -> Self {
modify { $0.invisibleCharacterSet = invisibleCharacterSet }
}
/// Maximum number of characters for this entry.
public func maxLength(_ maxLength: Int?) -> Self {
modify { $0.maxLength = maxLength }
}
/// The desired maximum width of the entry, in characters.
public func maxWidthChars(_ maxWidthChars: Int?) -> Self {
modify { $0.maxWidthChars = maxWidthChars }
}
/// Text for an item in the context menu to activate the primary icon action.
///
/// When the primary icon is activatable and this property has been set, a new entry
/// in the context menu of this GtkEntry will appear with this text. Selecting that
/// menu entry will result in the primary icon being activated, exactly in the same way
/// as it would be activated from a mouse click.
///
/// This simplifies adding accessibility support to applications using activatable
/// icons. The activatable icons aren't focusable when navigating the interface with
/// the keyboard This is why Gtk recommends to also add those actions in the context
/// menu. This set of methods greatly simplifies this, by adding a menu item that, when
/// enabled, calls the same callback than clicking on the icon.
public func menuEntryIconPrimaryText(_ menuEntryIconPrimaryText: String?) -> Self {
modify { $0.menuEntryIconPrimaryText = menuEntryIconPrimaryText }
}
/// Text for an item in the context menu to activate the secondary icon action.
///
/// When the primary icon is activatable and this property has been set, a new entry
/// in the context menu of this GtkEntry will appear with this text. Selecting that
/// menu entry will result in the primary icon being activated, exactly in the same way
/// as it would be activated from a mouse click.
///
/// This simplifies adding accessibility support to applications using activatable
/// icons. The activatable icons aren't focusable when navigating the interface with
/// the keyboard This is why Gtk recommends to also add those actions in the context
/// menu. This set of methods greatly simplifies this, by adding a menu item that, when
/// enabled, calls the same callback than clicking on the icon.
public func menuEntryIconSecondaryText(_ menuEntryIconSecondaryText: String?) -> Self {
modify { $0.menuEntryIconSecondaryText = menuEntryIconSecondaryText }
}
/// If text is overwritten when typing in the `GtkEntry`.
public func overwriteMode(_ overwriteMode: Bool? = true) -> Self {
modify { $0.overwriteMode = overwriteMode }
}
/// The text that will be displayed in the `GtkEntry` when it is empty
/// and unfocused.
public func placeholderText(_ placeholderText: String?) -> Self {
modify { $0.placeholderText = placeholderText }
}
/// Whether the primary icon is activatable.
///
/// GTK emits the `Gtk.Entry::icon-press` and
/// `Gtk.Entry::icon-release` signals only on sensitive,
/// activatable icons.
///
/// Sensitive, but non-activatable icons can be used for purely
/// informational purposes.
public func primaryIconActivatable(_ primaryIconActivatable: Bool? = true) -> Self {
modify { $0.primaryIconActivatable = primaryIconActivatable }
}
/// The icon name to use for the primary icon for the entry.
public func primaryIconName(_ primaryIconName: String?) -> Self {
modify { $0.primaryIconName = primaryIconName }
}
/// Whether the primary icon is sensitive.
///
/// An insensitive icon appears grayed out. GTK does not emit the
/// `Gtk.Entry::icon-press` and `Gtk.Entry::icon-release`
/// signals and does not allow DND from insensitive icons.
///
/// An icon should be set insensitive if the action that would trigger
/// when clicked is currently not available.
public func primaryIconSensitive(_ primaryIconSensitive: Bool? = true) -> Self {
modify { $0.primaryIconSensitive = primaryIconSensitive }
}
/// The contents of the tooltip on the primary icon, with markup.
///
/// Also see `Gtk.Entry.set_icon_tooltip_markup`.
public func primaryIconTooltipMarkup(_ primaryIconTooltipMarkup: String?) -> Self {
modify { $0.primaryIconTooltipMarkup = primaryIconTooltipMarkup }
}
/// The contents of the tooltip on the primary icon.
///
/// Also see `Gtk.Entry.set_icon_tooltip_text`.
public func primaryIconTooltipText(_ primaryIconTooltipText: String?) -> Self {
modify { $0.primaryIconTooltipText = primaryIconTooltipText }
}
/// The current fraction of the task that's been completed.
public func progressFraction(_ progressFraction: Double?) -> Self {
modify { $0.progressFraction = progressFraction }
}
/// The fraction of total entry width to move the progress
/// bouncing block for each pulse.
///
/// See `Gtk.Entry.progress_pulse`.
public func progressPulseStep(_ progressPulseStep: Double?) -> Self {
modify { $0.progressPulseStep = progressPulseStep }
}
/// Number of pixels of the entry scrolled off the screen to the left.
public func scrollOffset(_ scrollOffset: Int?) -> Self {
modify { $0.scrollOffset = scrollOffset }
}
/// Whether the secondary icon is activatable.
///
/// GTK emits the `Gtk.Entry::icon-press` and
/// `Gtk.Entry::icon-release` signals only on sensitive,
/// activatable icons.
///
/// Sensitive, but non-activatable icons can be used for purely
/// informational purposes.
public func secondaryIconActivatable(_ secondaryIconActivatable: Bool? = true) -> Self {
modify { $0.secondaryIconActivatable = secondaryIconActivatable }
}
/// The icon name to use for the secondary icon for the entry.
public func secondaryIconName(_ secondaryIconName: String?) -> Self {
modify { $0.secondaryIconName = secondaryIconName }
}
/// Whether the secondary icon is sensitive.
///
/// An insensitive icon appears grayed out. GTK does not emit the
/// `Gtk.Entry::icon-press[ and [signal@Gtk.Entry::icon-release`
/// signals and does not allow DND from insensitive icons.
///
/// An icon should be set insensitive if the action that would trigger
/// when clicked is currently not available.
public func secondaryIconSensitive(_ secondaryIconSensitive: Bool? = true) -> Self {
modify { $0.secondaryIconSensitive = secondaryIconSensitive }
}
/// The contents of the tooltip on the secondary icon, with markup.
///
/// Also see `Gtk.Entry.set_icon_tooltip_markup`.
public func secondaryIconTooltipMarkup(_ secondaryIconTooltipMarkup: String?) -> Self {
modify { $0.secondaryIconTooltipMarkup = secondaryIconTooltipMarkup }
}
/// The contents of the tooltip on the secondary icon.
///
/// Also see `Gtk.Entry.set_icon_tooltip_text`.
public func secondaryIconTooltipText(_ secondaryIconTooltipText: String?) -> Self {
modify { $0.secondaryIconTooltipText = secondaryIconTooltipText }
}
/// The position of the opposite end of the selection from the cursor in chars.
public func selectionBound(_ selectionBound: Int?) -> Self {
modify { $0.selectionBound = selectionBound }
}
/// Whether the entry will show an Emoji icon in the secondary icon position
/// to open the Emoji chooser.
public func showEmojiIcon(_ showEmojiIcon: Bool? = true) -> Self {
modify { $0.showEmojiIcon = showEmojiIcon }
}
/// The contents of the entry.
public func text(_ text: Binding<String>?) -> Self {
modify { $0.text = text }
}
/// The length of the text in the `GtkEntry`.
public func textLength(_ textLength: UInt?) -> Self {
modify { $0.textLength = textLength }
}
/// When `true`, pasted multi-line text is truncated to the first line.
public func truncateMultiline(_ truncateMultiline: Bool? = true) -> Self {
modify { $0.truncateMultiline = truncateMultiline }
}
/// Whether the entry should show the invisible char instead of the
/// actual text (password mode).
public func visibility(_ visibility: Bool? = true) -> Self {
modify { $0.visibility = visibility }
}
/// Number of characters to leave space for in the entry.
public func widthChars(_ widthChars: Int?) -> Self {
modify { $0.widthChars = widthChars }
}
/// The horizontal alignment, from 0 (left) to 1 (right).
///
/// Reversed for RTL layouts.
public func xalign(_ xalign: Float?) -> Self {
modify { $0.xalign = xalign }
}
/// Emitted when the entry is activated.
///
/// The keybindings for this signal are all forms of the Enter key.
public func activate(_ activate: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.activate = activate
return newSelf
}
/// Emitted at the end of a single user-visible operation on the
/// contents.
///
/// E.g., a paste operation that replaces the contents of the
/// selection will cause only one signal emission (even though it
/// is implemented by first deleting the selection, then inserting
/// the new content, and may cause multiple ::notify::text signals
/// to be emitted).
public func changed(_ changed: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.changed = changed
return newSelf
}
/// Emitted when text is deleted from the widget by the user.
///
/// The default handler for this signal will normally be responsible for
/// deleting the text, so by connecting to this signal and then stopping
/// the signal with g_signal_stop_emission(), it is possible to modify the
/// range of deleted text, or prevent it from being deleted entirely.
///
/// The @start_pos and @end_pos parameters are interpreted as for
/// `Gtk.Editable.delete_text`.
public func deleteText(_ deleteText: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.deleteText = deleteText
return newSelf
}
/// This signal is a sign for the cell renderer to update its
/// value from the @cell_editable.
///
/// Implementations of `GtkCellEditable` are responsible for
/// emitting this signal when they are done editing, e.g.
/// `GtkEntry` emits this signal when the user presses Enter. Typical things to
/// do in a handler for ::editing-done are to capture the edited value,
/// disconnect the @cell_editable from signals on the `GtkCellRenderer`, etc.
///
/// gtk_cell_editable_editing_done() is a convenience method
/// for emitting `GtkCellEditable::editing-done`.
public func editingDone(_ editingDone: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.editingDone = editingDone
return newSelf
}
/// Emitted when an activatable icon is clicked.
public func iconPress(_ iconPress: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.iconPress = iconPress
return newSelf
}
/// Emitted on the button release from a mouse click
/// over an activatable icon.
public func iconRelease(_ iconRelease: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.iconRelease = iconRelease
return newSelf
}
/// Emitted when text is inserted into the widget by the user.
///
/// The default handler for this signal will normally be responsible
/// for inserting the text, so by connecting to this signal and then
/// stopping the signal with g_signal_stop_emission(), it is possible
/// to modify the inserted text, or prevent it from being inserted entirely.
public func insertText(_ insertText: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.insertText = insertText
return newSelf
}
/// This signal is meant to indicate that the cell is finished
/// editing, and the @cell_editable widget is being removed and may
/// subsequently be destroyed.
///
/// Implementations of `GtkCellEditable` are responsible for
/// emitting this signal when they are done editing. It must
/// be emitted after the `GtkCellEditable::editing-done` signal,
/// to give the cell renderer a chance to update the cell's value
/// before the widget is removed.
///
/// gtk_cell_editable_remove_widget() is a convenience method
/// for emitting `GtkCellEditable::remove-widget`.
public func removeWidget(_ removeWidget: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.removeWidget = removeWidget
return newSelf
}
}

View File

@ -2,49 +2,44 @@
// EntryRow.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// A [class@Gtk.ListBoxRow] with an embedded text entry.
/// A `Gtk.ListBoxRow` with an embedded text entry.
///
///
/// <picture><source srcset="entry-row-dark.png" media="(prefers-color-scheme: dark)"><img src="entry-row.png" alt="entry-row"></picture>
///
/// `AdwEntryRow` has a title that doubles as placeholder text. It shows an icon
/// indicating that it's editable and can receive additional widgets before or
/// after the editable part.
///
/// If [property@EntryRow:show-apply-button] is set to `TRUE`, `AdwEntryRow` can
/// If ``showApplyButton(_:)`` is set to `true`, `AdwEntryRow` can
/// show an apply button when editing its contents. This can be useful if
/// changing its contents can result in an expensive operation, such as network
/// activity.
///
/// `AdwEntryRow` provides only minimal API and should be used with the
/// [iface@Gtk.Editable] API.
/// `Gtk.Editable` API.
///
/// See also [class@PasswordEntryRow].
/// See also `PasswordEntryRow`.
///
/// ## AdwEntryRow as GtkBuildable
///
/// The `AdwEntryRow` implementation of the [iface@Gtk.Buildable] interface
/// supports adding a child at its end by specifying suffix or omitting the
/// type attribute of a <child> element.
///
/// It also supports adding a child as a prefix widget by specifying prefix as
/// the type attribute of a <child> element.
///
/// ## CSS nodes
///
/// `AdwEntryRow` has a single CSS node with name `row` and the `.entry` style
/// class.
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?
@ -52,11 +47,13 @@ public struct EntryRow: AdwaitaWidget {
///
/// Emoji replacement is done with :-delimited names, like `:heart:`.
var enableEmojiCompletion: Bool?
/// Maximum number of characters for the entry.
var maxLength: Int?
/// Whether to show the apply button.
///
/// When set to `TRUE`, typing text in the entry will reveal an apply button.
/// When set to `true`, typing text in the entry will reveal an apply button.
/// Clicking it or pressing the <kbd>Enter</kbd> key will hide the button and
/// emit the [signal@EntryRow::apply] signal.
/// emit the `EntryRow::apply` signal.
///
/// This is useful if changing the entry contents can trigger an expensive
/// operation, e.g. network activity, to avoid triggering it after typing every
@ -67,23 +64,23 @@ public struct EntryRow: AdwaitaWidget {
/// The title of the preference represented by this row.
///
/// The title is interpreted as Pango markup unless
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
/// ``useMarkup(_:)`` is set to `false`.
var title: String?
/// Whether the user can copy the title from the label.
///
/// See also [property@Gtk.Label:selectable].
/// See also ``selectable(_:)``.
var titleSelectable: Bool?
/// Whether to use Pango markup for the title label.
///
/// Subclasses may also use it for other labels, such as subtitle.
///
/// See also [func@Pango.parse_markup].
/// See also `Pango.parse_markup`.
var useMarkup: Bool?
/// Whether an embedded underline in the title indicates a mnemonic.
var useUnderline: Bool?
/// Emitted when the apply button is pressed.
///
/// See [property@EntryRow:show-apply-button].
/// See ``showApplyButton(_:)``.
var apply: (() -> Void)?
/// Emitted when the embedded entry is activated.
var entryActivated: (() -> Void)?
@ -93,7 +90,7 @@ public struct EntryRow: AdwaitaWidget {
var prefix: () -> Body = { [] }
/// Initialize `EntryRow`.
public init() {
init() {
}
/// The view storage.
@ -106,7 +103,6 @@ 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() {
@ -148,6 +144,9 @@ public struct EntryRow: AdwaitaWidget {
if let enableEmojiCompletion, updateProperties, (storage.previousState as? Self)?.enableEmojiCompletion != enableEmojiCompletion {
adw_entry_row_set_enable_emoji_completion(widget?.cast(), enableEmojiCompletion.cBool)
}
if let maxLength, updateProperties, (storage.previousState as? Self)?.maxLength != maxLength {
adw_entry_row_set_max_length(widget?.cast(), maxLength.cInt)
}
if let showApplyButton, updateProperties, (storage.previousState as? Self)?.showApplyButton != showApplyButton {
adw_entry_row_set_show_apply_button(widget?.cast(), showApplyButton.cBool)
}
@ -189,6 +188,7 @@ public struct EntryRow: AdwaitaWidget {
}
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -200,90 +200,71 @@ public struct EntryRow: AdwaitaWidget {
/// Whether activating the embedded entry can activate the default widget.
public func activatesDefault(_ activatesDefault: Bool? = true) -> Self {
var newSelf = self
newSelf.activatesDefault = activatesDefault
return newSelf
modify { $0.activatesDefault = activatesDefault }
}
/// Whether to suggest emoji replacements on the entry row.
///
/// Emoji replacement is done with :-delimited names, like `:heart:`.
public func enableEmojiCompletion(_ enableEmojiCompletion: Bool? = true) -> Self {
var newSelf = self
newSelf.enableEmojiCompletion = enableEmojiCompletion
return newSelf
modify { $0.enableEmojiCompletion = enableEmojiCompletion }
}
/// Maximum number of characters for the entry.
public func maxLength(_ maxLength: Int?) -> Self {
modify { $0.maxLength = maxLength }
}
/// Whether to show the apply button.
///
/// When set to `TRUE`, typing text in the entry will reveal an apply button.
/// When set to `true`, typing text in the entry will reveal an apply button.
/// Clicking it or pressing the <kbd>Enter</kbd> key will hide the button and
/// emit the [signal@EntryRow::apply] signal.
/// emit the `EntryRow::apply` signal.
///
/// This is useful if changing the entry contents can trigger an expensive
/// operation, e.g. network activity, to avoid triggering it after typing every
/// character.
public func showApplyButton(_ showApplyButton: Bool? = true) -> Self {
var newSelf = self
newSelf.showApplyButton = showApplyButton
return newSelf
modify { $0.showApplyButton = showApplyButton }
}
/// The length of the text in the entry row.
public func textLength(_ textLength: UInt?) -> Self {
var newSelf = self
newSelf.textLength = textLength
return newSelf
modify { $0.textLength = textLength }
}
/// The title of the preference represented by this row.
///
/// The title is interpreted as Pango markup unless
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
/// ``useMarkup(_:)`` is set to `false`.
public func title(_ title: String?) -> Self {
var newSelf = self
newSelf.title = title
return newSelf
modify { $0.title = title }
}
/// Whether the user can copy the title from the label.
///
/// See also [property@Gtk.Label:selectable].
/// See also ``selectable(_:)``.
public func titleSelectable(_ titleSelectable: Bool? = true) -> Self {
var newSelf = self
newSelf.titleSelectable = titleSelectable
return newSelf
modify { $0.titleSelectable = titleSelectable }
}
/// Whether to use Pango markup for the title label.
///
/// Subclasses may also use it for other labels, such as subtitle.
///
/// See also [func@Pango.parse_markup].
/// See also `Pango.parse_markup`.
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
var newSelf = self
newSelf.useMarkup = useMarkup
return newSelf
modify { $0.useMarkup = useMarkup }
}
/// Whether an embedded underline in the title indicates a mnemonic.
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
var newSelf = self
newSelf.useUnderline = useUnderline
return newSelf
modify { $0.useUnderline = useUnderline }
}
/// Emitted when the apply button is pressed.
///
/// See [property@EntryRow:show-apply-button].
/// See ``showApplyButton(_:)``.
public func apply(_ apply: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.apply = apply

View File

@ -2,43 +2,34 @@
// ExpanderRow.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// A [class@Gtk.ListBoxRow] used to reveal widgets.
/// A `Gtk.ListBoxRow` used to reveal widgets.
///
///
/// <picture><source srcset="expander-row-dark.png" media="(prefers-color-scheme: dark)"><img src="expander-row.png" alt="expander-row"></picture>
///
/// The `AdwExpanderRow` widget allows the user to reveal or hide widgets below
/// it. It also allows the user to enable the expansion of the row, allowing to
/// disable all that the row contains.
///
/// ## AdwExpanderRow as GtkBuildable
///
/// The `AdwExpanderRow` implementation of the [iface@Gtk.Buildable] interface
/// supports adding a child as an suffix widget by specifying suffix as the
/// type attribute of a <child> element.
///
/// It also supports adding it as a prefix widget by specifying prefix as the
/// type attribute of a <child> element.
///
/// ## CSS nodes
///
/// `AdwExpanderRow` has a main CSS node with name `row` and the `.expander`
/// style class. It has the `.empty` style class when it contains no children.
///
/// It contains the subnodes `row.header` for its main embedded row,
/// `list.nested` for the list it can expand, and `image.expander-row-arrow` for
/// its arrow.
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>?
@ -49,7 +40,7 @@ public struct ExpanderRow: AdwaitaWidget {
/// The subtitle for this row.
///
/// The subtitle is interpreted as Pango markup unless
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
/// ``useMarkup(_:)`` is set to `false`.
var subtitle: String?
/// The number of lines at the end of which the subtitle label will be
/// ellipsized.
@ -59,7 +50,7 @@ public struct ExpanderRow: AdwaitaWidget {
/// The title of the preference represented by this row.
///
/// The title is interpreted as Pango markup unless
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
/// ``useMarkup(_:)`` is set to `false`.
var title: String?
/// The number of lines at the end of which the title label will be ellipsized.
///
@ -67,13 +58,13 @@ public struct ExpanderRow: AdwaitaWidget {
var titleLines: Int?
/// Whether the user can copy the title from the label.
///
/// See also [property@Gtk.Label:selectable].
/// See also ``selectable(_:)``.
var titleSelectable: Bool?
/// Whether to use Pango markup for the title label.
///
/// Subclasses may also use it for other labels, such as subtitle.
///
/// See also [func@Pango.parse_markup].
/// See also `Pango.parse_markup`.
var useMarkup: Bool?
/// Whether an embedded underline in the title indicates a mnemonic.
var useUnderline: Bool?
@ -98,7 +89,6 @@ 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() {
@ -210,6 +200,7 @@ if let expanded, newValue != expanded.wrappedValue {
}
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -221,37 +212,25 @@ if let expanded, newValue != expanded.wrappedValue {
/// Whether expansion is enabled.
public func enableExpansion(_ enableExpansion: Binding<Bool>?) -> Self {
var newSelf = self
newSelf.enableExpansion = enableExpansion
return newSelf
modify { $0.enableExpansion = enableExpansion }
}
/// Whether the row is expanded.
public func expanded(_ expanded: Binding<Bool>?) -> Self {
var newSelf = self
newSelf.expanded = expanded
return newSelf
modify { $0.expanded = expanded }
}
/// Whether the switch enabling the expansion is visible.
public func showEnableSwitch(_ showEnableSwitch: Bool? = true) -> Self {
var newSelf = self
newSelf.showEnableSwitch = showEnableSwitch
return newSelf
modify { $0.showEnableSwitch = showEnableSwitch }
}
/// The subtitle for this row.
///
/// The subtitle is interpreted as Pango markup unless
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
/// ``useMarkup(_:)`` is set to `false`.
public func subtitle(_ subtitle: String?) -> Self {
var newSelf = self
newSelf.subtitle = subtitle
return newSelf
modify { $0.subtitle = subtitle }
}
/// The number of lines at the end of which the subtitle label will be
@ -259,61 +238,43 @@ if let expanded, newValue != expanded.wrappedValue {
///
/// If the value is 0, the number of lines won't be limited.
public func subtitleLines(_ subtitleLines: Int?) -> Self {
var newSelf = self
newSelf.subtitleLines = subtitleLines
return newSelf
modify { $0.subtitleLines = subtitleLines }
}
/// The title of the preference represented by this row.
///
/// The title is interpreted as Pango markup unless
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
/// ``useMarkup(_:)`` is set to `false`.
public func title(_ title: String?) -> Self {
var newSelf = self
newSelf.title = title
return newSelf
modify { $0.title = title }
}
/// The number of lines at the end of which the title label will be ellipsized.
///
/// If the value is 0, the number of lines won't be limited.
public func titleLines(_ titleLines: Int?) -> Self {
var newSelf = self
newSelf.titleLines = titleLines
return newSelf
modify { $0.titleLines = titleLines }
}
/// Whether the user can copy the title from the label.
///
/// See also [property@Gtk.Label:selectable].
/// See also ``selectable(_:)``.
public func titleSelectable(_ titleSelectable: Bool? = true) -> Self {
var newSelf = self
newSelf.titleSelectable = titleSelectable
return newSelf
modify { $0.titleSelectable = titleSelectable }
}
/// Whether to use Pango markup for the title label.
///
/// Subclasses may also use it for other labels, such as subtitle.
///
/// See also [func@Pango.parse_markup].
/// See also `Pango.parse_markup`.
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
var newSelf = self
newSelf.useMarkup = useMarkup
return newSelf
modify { $0.useMarkup = useMarkup }
}
/// Whether an embedded underline in the title indicates a mnemonic.
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
var newSelf = self
newSelf.useUnderline = useUnderline
return newSelf
modify { $0.useUnderline = useUnderline }
}
/// Set the body for "rows".

View File

@ -2,13 +2,13 @@
// Fixed.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// `GtkFixed` places its child widgets at fixed positions and with fixed sizes.
/// Places its child widgets at fixed positions and with fixed sizes.
///
/// `GtkFixed` performs no automatic layout management.
///
@ -47,10 +47,17 @@ 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.
///
@ -71,7 +78,6 @@ public struct Fixed: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}
@ -87,6 +93,7 @@ public struct Fixed: AdwaitaWidget {
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -100,10 +107,7 @@ public struct Fixed: AdwaitaWidget {
///
/// The accessible role cannot be changed once set.
public func accessibleRole(_ accessibleRole: String?) -> Self {
var newSelf = self
newSelf.accessibleRole = accessibleRole
return newSelf
modify { $0.accessibleRole = accessibleRole }
}
}

View File

@ -2,13 +2,15 @@
// FlowBox.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// A `GtkFlowBox` puts child widgets in reflowing grid.
/// Puts child widgets in a reflowing grid.
///
///
///
/// For instance, with the horizontal orientation, the widgets will be
/// arranged from left to right, starting a new row under the previous
@ -28,38 +30,28 @@ import LevenshteinTransformations
/// The children of a `GtkFlowBox` can be dynamically sorted and filtered.
///
/// Although a `GtkFlowBox` must have only `GtkFlowBoxChild` children, you
/// can add any kind of widget to it via [method@Gtk.FlowBox.insert], and a
/// can add any kind of widget to it via `Gtk.FlowBox.insert`, and a
/// `GtkFlowBoxChild` widget will automatically be inserted between the box
/// and the widget.
///
/// Also see [class@Gtk.ListBox].
/// Also see `Gtk.ListBox`.
///
/// # CSS nodes
///
/// ```
/// flowbox
/// flowboxchild
/// <child> flowboxchild
/// <child>
/// [rubberband]
/// ```
///
/// `GtkFlowBox` uses a single CSS node with name flowbox. `GtkFlowBoxChild`
/// uses a single CSS node with name flowboxchild. For rubberband selection,
/// a subnode with name rubberband is used.
///
/// # Accessibility
///
/// `GtkFlowBox` uses the %GTK_ACCESSIBLE_ROLE_GRID role, and `GtkFlowBoxChild`
/// uses the %GTK_ACCESSIBLE_ROLE_GRID_CELL role.
public struct FlowBox<Element>: AdwaitaWidget where Element: Identifiable {
public struct FlowBox<Element, Identifier>: AdwaitaWidget where Identifier: Equatable {
#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
/// accept-unpaired-release
/// Whether to accept unpaired release events.
var acceptUnpairedRelease: Bool?
/// The accessible role of the given `GtkAccessible` implementation.
///
@ -117,8 +109,8 @@ public struct FlowBox<Element>: AdwaitaWidget where Element: Identifiable {
var selectAll: (() -> Void)?
/// Emitted when the set of selected children changes.
///
/// Use [method@Gtk.FlowBox.selected_foreach] or
/// [method@Gtk.FlowBox.get_selected_children] to obtain the
/// Use `Gtk.FlowBox.selected_foreach` or
/// `Gtk.FlowBox.get_selected_children` to obtain the
/// selected children.
var selectedChildrenChanged: (() -> Void)?
/// Emitted to toggle the selection of the child that has the focus.
@ -138,11 +130,14 @@ public struct FlowBox<Element>: AdwaitaWidget where Element: Identifiable {
var elements: [Element]
/// The dynamic widget content.
var content: (Element) -> Body
/// The dynamic widget identifier key path.
var id: KeyPath<Element, Identifier>
/// Initialize `FlowBox`.
public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) {
init(_ elements: [Element], id: KeyPath<Element, Identifier>, @ViewBuilder content: @escaping (Element) -> Body) {
self.elements = elements
self.content = content
self.id = id
}
/// The view storage.
@ -155,7 +150,6 @@ public struct FlowBox<Element>: AdwaitaWidget where Element: Identifiable {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}
@ -225,15 +219,10 @@ public struct FlowBox<Element>: AdwaitaWidget where Element: Identifiable {
var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? []
let old = storage.fields["element"] as? [Element] ?? []
old.identifiableTransform(
old.transform(
to: elements,
functions: .init { index, element in
let child = content(element).storage(data: data, type: type)
gtk_flow_box_remove(widget, gtk_flow_box_get_child_at_index(widget, index.cInt)?.cast())
gtk_flow_box_insert(widget, child.opaquePointer?.cast(), index.cInt)
contentStorage.remove(at: index)
contentStorage.insert(child, at: index)
} delete: { index in
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)
} insert: { index, element in
@ -247,6 +236,7 @@ public struct FlowBox<Element>: AdwaitaWidget where Element: Identifiable {
for (index, element) in elements.enumerated() {
content(element).updateStorage(contentStorage[index], data: data, updateProperties: updateProperties, type: type)
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -256,57 +246,39 @@ public struct FlowBox<Element>: AdwaitaWidget where Element: Identifiable {
}
}
/// accept-unpaired-release
/// Whether to accept unpaired release events.
public func acceptUnpairedRelease(_ acceptUnpairedRelease: Bool? = true) -> Self {
var newSelf = self
newSelf.acceptUnpairedRelease = acceptUnpairedRelease
return newSelf
modify { $0.acceptUnpairedRelease = acceptUnpairedRelease }
}
/// The accessible role of the given `GtkAccessible` implementation.
///
/// The accessible role cannot be changed once set.
public func accessibleRole(_ accessibleRole: String?) -> Self {
var newSelf = self
newSelf.accessibleRole = accessibleRole
return newSelf
modify { $0.accessibleRole = accessibleRole }
}
/// Determines whether children can be activated with a single
/// click, or require a double-click.
public func activateOnSingleClick(_ activateOnSingleClick: Bool? = true) -> Self {
var newSelf = self
newSelf.activateOnSingleClick = activateOnSingleClick
return newSelf
modify { $0.activateOnSingleClick = activateOnSingleClick }
}
/// The amount of horizontal space between two children.
public func columnSpacing(_ columnSpacing: UInt?) -> Self {
var newSelf = self
newSelf.columnSpacing = columnSpacing
return newSelf
modify { $0.columnSpacing = columnSpacing }
}
/// Determines whether all children should be allocated the
/// same size.
public func homogeneous(_ homogeneous: Bool? = true) -> Self {
var newSelf = self
newSelf.homogeneous = homogeneous
return newSelf
modify { $0.homogeneous = homogeneous }
}
/// The maximum amount of children to request space for consecutively
/// in the given orientation.
public func maxChildrenPerLine(_ maxChildrenPerLine: UInt?) -> Self {
var newSelf = self
newSelf.maxChildrenPerLine = maxChildrenPerLine
return newSelf
modify { $0.maxChildrenPerLine = maxChildrenPerLine }
}
/// The minimum number of children to allocate consecutively
@ -316,18 +288,12 @@ public struct FlowBox<Element>: AdwaitaWidget where Element: Identifiable {
/// that a reasonably small height will be requested
/// for the overall minimum width of the box.
public func minChildrenPerLine(_ minChildrenPerLine: UInt?) -> Self {
var newSelf = self
newSelf.minChildrenPerLine = minChildrenPerLine
return newSelf
modify { $0.minChildrenPerLine = minChildrenPerLine }
}
/// The amount of vertical space between two children.
public func rowSpacing(_ rowSpacing: UInt?) -> Self {
var newSelf = self
newSelf.rowSpacing = rowSpacing
return newSelf
modify { $0.rowSpacing = rowSpacing }
}
/// Emitted when the user activates the @box.
@ -382,8 +348,8 @@ public struct FlowBox<Element>: AdwaitaWidget where Element: Identifiable {
/// Emitted when the set of selected children changes.
///
/// Use [method@Gtk.FlowBox.selected_foreach] or
/// [method@Gtk.FlowBox.get_selected_children] to obtain the
/// Use `Gtk.FlowBox.selected_foreach` or
/// `Gtk.FlowBox.get_selected_children` to obtain the
/// selected children.
public func selectedChildrenChanged(_ selectedChildrenChanged: @escaping () -> Void) -> Self {
var newSelf = self
@ -415,3 +381,14 @@ public struct FlowBox<Element>: AdwaitaWidget where Element: Identifiable {
}
}
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 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
@ -10,99 +10,31 @@ import LevenshteinTransformations
/// A title bar widget.
///
/// <picture><source srcset="header-bar-dark.png" media="(prefers-color-scheme: dark)"><img src="header-bar.png" alt="header-bar"></picture>
///
/// `AdwHeaderBar` is similar to [class@Gtk.HeaderBar], but provides additional
///
/// `AdwHeaderBar` is similar to `Gtk.HeaderBar`, but provides additional
/// features compared to it. Refer to `GtkHeaderBar` for details. It is typically
/// used as a top bar within [class@ToolbarView].
/// used as a top bar within `ToolbarView`.
///
/// ## Dialog Integration
///
/// When placed inside an [class@Dialog], `AdwHeaderBar` will display the dialog
/// title intead of window title. It will also adjust the decoration layout to
/// ensure it always has a close button and nothing else. Set
/// [property@HeaderBar:show-start-title-buttons] and
/// [property@HeaderBar:show-end-title-buttons] to `FALSE` to remove it if it's
/// unwanted.
///
/// ## Navigation View Integration
///
/// When placed inside an [class@NavigationPage], `AdwHeaderBar` will display the
/// page title instead of window title.
///
/// When used together with [class@NavigationView] or [class@NavigationSplitView],
/// it will also display a back button that can be used to go back to the previous
/// page. The button also has a context menu, allowing to pop multiple pages at
/// once, potentially across multiple navigation views.
///
/// Set [property@HeaderBar:show-back-button] to `FALSE` to disable this behavior
/// in rare scenarios where it's unwanted.
///
/// ## Split View Integration
///
/// When placed inside [class@NavigationSplitView] or [class@OverlaySplitView],
/// `AdwHeaderBar` will automatically hide the title buttons other than at the
/// edges of the window.
///
/// ## Centering Policy
///
/// [property@HeaderBar:centering-policy] allows to enforce strict centering of
/// the title widget. This can be useful for entries inside [class@Clamp].
///
/// ## Title Buttons
///
/// Unlike `GtkHeaderBar`, `AdwHeaderBar` allows to toggle title button
/// visibility for each side individually, using the
/// [property@HeaderBar:show-start-title-buttons] and
/// [property@HeaderBar:show-end-title-buttons] properties.
///
/// ## CSS nodes
///
/// ```
/// headerbar
/// windowhandle
/// box
/// widget
/// box.start
/// windowcontrols.start
/// widget
/// [button.back]
/// [other children]
/// widget
/// [Title Widget]
/// widget
/// box.end
/// [other children]
/// windowcontrols.end
/// ```
///
/// `AdwHeaderBar`'s CSS node is called `headerbar`. It contains a `windowhandle`
/// subnode, which contains a `box` subnode, which contains three `widget`
/// subnodes at the start, center and end of the header bar. The start and end
/// subnotes contain a `box` subnode with the `.start` and `.end` style classes
/// respectively, and the center node contains a node that represents the title.
///
/// Each of the boxes contains a `windowcontrols` subnode, see
/// [class@Gtk.WindowControls] for details, as well as other children.
///
/// When [property@HeaderBar:show-back-button] is `TRUE`, the start box also
/// contains a node with the name `widget` that contains a node with the name
/// `button` and `.back` style class.
///
/// ## Accessibility
///
/// `AdwHeaderBar` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
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.
///
/// If this property is not set, the
/// [property@Gtk.Settings:gtk-decoration-layout] setting is used.
/// ``gtkDecorationLayout(_:)`` setting is used.
///
/// The format of the string is button names, separated by commas. A colon
/// separates the buttons that should appear at the start from those at the
@ -115,23 +47,23 @@ public struct HeaderBar: AdwaitaWidget {
/// Whether the header bar can show the back button.
///
/// The back button will never be shown unless the header bar is placed inside an
/// [class@NavigationView]. Usually, there is no reason to set this to `FALSE`.
/// `NavigationView`. Usually, there is no reason to set this to `false`.
var showBackButton: Bool?
/// Whether to show title buttons at the end of the header bar.
///
/// See [property@HeaderBar:show-start-title-buttons] for the other side.
/// See ``showStartTitleButtons(_:)`` for the other side.
///
/// Which buttons are actually shown and where is determined by the
/// [property@HeaderBar:decoration-layout] property, and by the state of the
/// ``decorationLayout(_:)`` property, and by the state of the
/// window (e.g. a close button will not be shown if the window can't be
/// closed).
var showEndTitleButtons: Bool?
/// Whether to show title buttons at the start of the header bar.
///
/// See [property@HeaderBar:show-end-title-buttons] for the other side.
/// See ``showEndTitleButtons(_:)`` for the other side.
///
/// Which buttons are actually shown and where is determined by the
/// [property@HeaderBar:decoration-layout] property, and by the state of the
/// ``decorationLayout(_:)`` property, and by the state of the
/// window (e.g. a close button will not be shown if the window can't be
/// closed).
var showStartTitleButtons: Bool?
@ -142,12 +74,12 @@ public struct HeaderBar: AdwaitaWidget {
/// When set to `NULL`, the header bar will display the title of the window it
/// is contained in.
///
/// To use a different title, use [class@WindowTitle]:
/// To use a different title, use `WindowTitle`:
///
/// ```xml
/// <object class="AdwHeaderBar"><property name="title-widget"><object class="AdwWindowTitle"><property name="title" translatable="yes">Title</property></object></property></object>
/// ```
var titleWidget: (() -> Body)?
var titleWidget: Body?
/// The body for the widget "start".
var start: () -> Body = { [] }
/// The body for the widget "end".
@ -167,8 +99,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) {
if let titleWidgetStorage = titleWidget?.storage(data: data, type: type) {
storage.content["titleWidget"] = [titleWidgetStorage]
adw_header_bar_set_title_widget(storage.opaquePointer, titleWidgetStorage.opaquePointer?.cast())
}
@ -213,7 +144,7 @@ public struct HeaderBar: AdwaitaWidget {
adw_header_bar_set_show_title(widget, showTitle.cBool)
}
if let widget = storage.content["titleWidget"]?.first {
titleWidget?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
titleWidget?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
if let startStorage = storage.content["start"] {
@ -241,6 +172,7 @@ public struct HeaderBar: AdwaitaWidget {
}
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -253,7 +185,7 @@ public struct HeaderBar: AdwaitaWidget {
/// The decoration layout for buttons.
///
/// If this property is not set, the
/// [property@Gtk.Settings:gtk-decoration-layout] setting is used.
/// ``gtkDecorationLayout(_:)`` setting is used.
///
/// The format of the string is button names, separated by commas. A colon
/// separates the buttons that should appear at the start from those at the
@ -263,59 +195,44 @@ public struct HeaderBar: AdwaitaWidget {
/// For example, icon:minimize,maximize,close specifies an icon at the start,
/// and minimize, maximize and close buttons at the end.
public func decorationLayout(_ decorationLayout: String?) -> Self {
var newSelf = self
newSelf.decorationLayout = decorationLayout
return newSelf
modify { $0.decorationLayout = decorationLayout }
}
/// Whether the header bar can show the back button.
///
/// The back button will never be shown unless the header bar is placed inside an
/// [class@NavigationView]. Usually, there is no reason to set this to `FALSE`.
/// `NavigationView`. Usually, there is no reason to set this to `false`.
public func showBackButton(_ showBackButton: Bool? = true) -> Self {
var newSelf = self
newSelf.showBackButton = showBackButton
return newSelf
modify { $0.showBackButton = showBackButton }
}
/// Whether to show title buttons at the end of the header bar.
///
/// See [property@HeaderBar:show-start-title-buttons] for the other side.
/// See ``showStartTitleButtons(_:)`` for the other side.
///
/// Which buttons are actually shown and where is determined by the
/// [property@HeaderBar:decoration-layout] property, and by the state of the
/// ``decorationLayout(_:)`` property, and by the state of the
/// window (e.g. a close button will not be shown if the window can't be
/// closed).
public func showEndTitleButtons(_ showEndTitleButtons: Bool? = true) -> Self {
var newSelf = self
newSelf.showEndTitleButtons = showEndTitleButtons
return newSelf
modify { $0.showEndTitleButtons = showEndTitleButtons }
}
/// Whether to show title buttons at the start of the header bar.
///
/// See [property@HeaderBar:show-end-title-buttons] for the other side.
/// See ``showEndTitleButtons(_:)`` for the other side.
///
/// Which buttons are actually shown and where is determined by the
/// [property@HeaderBar:decoration-layout] property, and by the state of the
/// ``decorationLayout(_:)`` property, and by the state of the
/// window (e.g. a close button will not be shown if the window can't be
/// closed).
public func showStartTitleButtons(_ showStartTitleButtons: Bool? = true) -> Self {
var newSelf = self
newSelf.showStartTitleButtons = showStartTitleButtons
return newSelf
modify { $0.showStartTitleButtons = showStartTitleButtons }
}
/// Whether the title widget should be shown.
public func showTitle(_ showTitle: Bool? = true) -> Self {
var newSelf = self
newSelf.showTitle = showTitle
return newSelf
modify { $0.showTitle = showTitle }
}
/// The title widget to display.
@ -323,16 +240,13 @@ public struct HeaderBar: AdwaitaWidget {
/// When set to `NULL`, the header bar will display the title of the window it
/// is contained in.
///
/// To use a different title, use [class@WindowTitle]:
/// To use a different title, use `WindowTitle`:
///
/// ```xml
/// <object class="AdwHeaderBar"><property name="title-widget"><object class="AdwWindowTitle"><property name="title" translatable="yes">Title</property></object></property></object>
/// ```
public func titleWidget(@ViewBuilder _ titleWidget: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.titleWidget = titleWidget
return newSelf
public func titleWidget(@ViewBuilder _ titleWidget: () -> Body) -> Self {
modify { $0.titleWidget = titleWidget() }
}
/// Set the body for "start".

View File

@ -0,0 +1,168 @@
//
// Image.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// Displays an image.
///
///
///
/// Various kinds of object can be displayed as an image; most typically,
/// you would load a `GdkTexture` from a file, using the convenience function
/// `Gtk.Image.new_from_file`, for instance:
///
/// ```c
/// GtkWidget *image = gtk_image_new_from_file ("myfile.png");
/// ```
///
/// If the file isnt loaded successfully, the image will contain a
/// broken image icon similar to that used in many web browsers.
///
/// If you want to handle errors in loading the file yourself, for example
/// by displaying an error message, then load the image with an image
/// loading framework such as libglycin, then create the `GtkImage` with
/// `Gtk.Image.new_from_paintable`.
///
/// Sometimes an application will want to avoid depending on external data
/// files, such as image files. See the documentation of `GResource` inside
/// GIO, for details. In this case, ``resource(_:)``,
/// `Gtk.Image.new_from_resource`, and `Gtk.Image.set_from_resource`
/// should be used.
///
/// `GtkImage` displays its image as an icon, with a size that is determined
/// by the application. See `Gtk.Picture` if you want to show an image
/// at is actual size.
///
///
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.
///
/// The accessible role cannot be changed once set.
var accessibleRole: String?
/// The name of the icon in the icon theme.
///
/// If the icon theme is changed, the image will be updated automatically.
var iconName: String?
/// The size in pixels to display icons at.
///
/// If set to a value != -1, this property overrides the
/// ``iconSize(_:)`` property for images of type
/// `GTK_IMAGE_ICON_NAME`.
var pixelSize: Int?
/// A path to a resource file to display.
var resource: String?
/// The representation being used for image data.
var storageType: String?
/// Whether the icon displayed in the `GtkImage` will use
/// standard icon names fallback.
///
/// The value of this property is only relevant for images of type
/// %GTK_IMAGE_ICON_NAME and %GTK_IMAGE_GICON.
var useFallback: Bool?
/// Initialize `Image`.
public init() {
}
/// The view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The view render data type.
/// - Returns: The view storage.
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
let storage = ViewStorage(gtk_image_new()?.opaque())
for function in appearFunctions {
function(storage, data)
}
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.
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
storage.modify { widget in
if let iconName, updateProperties, (storage.previousState as? Self)?.iconName != iconName {
gtk_image_set_from_icon_name(widget, iconName)
}
if let pixelSize, updateProperties, (storage.previousState as? Self)?.pixelSize != pixelSize {
gtk_image_set_pixel_size(widget, pixelSize.cInt)
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
}
if updateProperties {
storage.previousState = self
}
}
/// The accessible role of the given `GtkAccessible` implementation.
///
/// The accessible role cannot be changed once set.
public func accessibleRole(_ accessibleRole: String?) -> Self {
modify { $0.accessibleRole = accessibleRole }
}
/// The name of the icon in the icon theme.
///
/// If the icon theme is changed, the image will be updated automatically.
public func iconName(_ iconName: String?) -> Self {
modify { $0.iconName = iconName }
}
/// The size in pixels to display icons at.
///
/// If set to a value != -1, this property overrides the
/// ``iconSize(_:)`` property for images of type
/// `GTK_IMAGE_ICON_NAME`.
public func pixelSize(_ pixelSize: Int?) -> Self {
modify { $0.pixelSize = pixelSize }
}
/// A path to a resource file to display.
public func resource(_ resource: String?) -> Self {
modify { $0.resource = resource }
}
/// The representation being used for image data.
public func storageType(_ storageType: String?) -> Self {
modify { $0.storageType = storageType }
}
/// Whether the icon displayed in the `GtkImage` will use
/// standard icon names fallback.
///
/// The value of this property is only relevant for images of type
/// %GTK_IMAGE_ICON_NAME and %GTK_IMAGE_GICON.
public func useFallback(_ useFallback: Bool? = true) -> Self {
modify { $0.useFallback = useFallback }
}
}

View File

@ -0,0 +1,331 @@
//
// Label.swift
// Adwaita
//
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// Displays a small amount of text.
///
/// Most labels are used to label another widget (such as an `Entry`).
///
///
///
///
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.
///
/// The accessible role cannot be changed once set.
var accessibleRole: String?
/// The contents of the label.
///
/// If the string contains Pango markup (see `Pango.parse_markup`),
/// you will have to set the ``useMarkup(_:)`` property to
/// true in order for the label to display the markup attributes. See also
/// `Gtk.Label.set_markup` for a convenience function that sets both
/// this property and the ``useMarkup(_:)`` property at the
/// same time.
///
/// If the string contains underlines acting as mnemonics, you will have to
/// set the ``useUnderline(_:)`` property to true in order
/// for the label to display them.
var label: String
/// The number of lines to which an ellipsized, wrapping label
/// should display before it gets ellipsized. This both prevents the label
/// from ellipsizing before this many lines are displayed, and limits the
/// height request of the label to this many lines.
///
/// > [!WARNING]
/// > Setting this property has unintuitive and unfortunate consequences
/// for the minimum _width_ of the label. Specifically, if the height
/// of the label is such that it fits a smaller number of lines than
/// the value of this property, the label can not be ellipsized at all,
/// which means it must be wide enough to fit all the text fully.
///
/// This property has no effect if the label is not wrapping or ellipsized.
///
/// Set this property to -1 if you don't want to limit the number of lines.
var lines: Int?
/// The desired maximum width of the label, in characters.
///
/// If this property is set to -1, the width will be calculated automatically.
///
/// See the section on [text layout](class.Label.html
var maxWidthChars: Int?
/// The mnemonic accelerator key for the label.
var mnemonicKeyval: UInt?
/// The widget to be activated when the labels mnemonic key is pressed.
var mnemonicWidget: Body?
/// Whether the label text can be selected with the mouse.
var selectable: Bool?
/// Whether the label is in single line mode.
///
/// In single line mode, the height of the label does not depend on the
/// actual text, it is always set to ascent + descent of the font. This
/// can be an advantage in situations where resizing the label because
/// of text changes would be distracting, e.g. in a statusbar.
var singleLineMode: Bool?
/// True if the text of the label includes Pango markup.
///
/// See `Pango.parse_markup`.
var useMarkup: Bool?
/// True if the text of the label indicates a mnemonic with an `_`
/// before the mnemonic character.
var useUnderline: Bool?
/// The desired width of the label, in characters.
///
/// If this property is set to -1, the width will be calculated automatically.
///
/// See the section on [text layout](class.Label.html
var widthChars: Int?
/// True if the label text will wrap if it gets too wide.
var wrap: Bool?
/// The horizontal alignment of the label text inside its size allocation.
///
/// Compare this to ``halign(_:)``, which determines how the
/// labels size allocation is positioned in the space available for the label.
var xalign: Float?
/// The vertical alignment of the label text inside its size allocation.
///
/// Compare this to ``valign(_:)``, which determines how the
/// labels size allocation is positioned in the space available for the label.
var yalign: Float?
/// Gets emitted to copy the selection to the clipboard.
///
/// The `::copy-clipboard` signal is a [keybinding signal](class.SignalAction.html).
///
/// The default binding for this signal is <kbd>Ctrl</kbd>+<kbd>c</kbd>.
var copyClipboard: (() -> Void)?
/// Initialize `Label`.
public init(label: String) {
self.label = label
}
/// The view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The view render data type.
/// - Returns: The view storage.
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
let storage = ViewStorage(gtk_label_new(label)?.opaque())
for function in appearFunctions {
function(storage, data)
}
if let mnemonicWidgetStorage = mnemonicWidget?.storage(data: data, type: type) {
storage.content["mnemonicWidget"] = [mnemonicWidgetStorage]
gtk_label_set_mnemonic_widget(storage.opaquePointer, mnemonicWidgetStorage.opaquePointer?.cast())
}
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.
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
if let copyClipboard {
storage.connectSignal(name: "copy-clipboard", argCount: 0) {
copyClipboard()
}
}
storage.modify { widget in
if updateProperties, (storage.previousState as? Self)?.label != label {
gtk_label_set_label(widget, label)
}
if let lines, updateProperties, (storage.previousState as? Self)?.lines != lines {
gtk_label_set_lines(widget, lines.cInt)
}
if let maxWidthChars, updateProperties, (storage.previousState as? Self)?.maxWidthChars != maxWidthChars {
gtk_label_set_max_width_chars(widget, maxWidthChars.cInt)
}
if let widget = storage.content["mnemonicWidget"]?.first {
mnemonicWidget?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
if let selectable, updateProperties, (storage.previousState as? Self)?.selectable != selectable {
gtk_label_set_selectable(widget, selectable.cBool)
}
if let singleLineMode, updateProperties, (storage.previousState as? Self)?.singleLineMode != singleLineMode {
gtk_label_set_single_line_mode(widget, singleLineMode.cBool)
}
if let useMarkup, updateProperties, (storage.previousState as? Self)?.useMarkup != useMarkup {
gtk_label_set_use_markup(widget, useMarkup.cBool)
}
if let useUnderline, updateProperties, (storage.previousState as? Self)?.useUnderline != useUnderline {
gtk_label_set_use_underline(widget, useUnderline.cBool)
}
if let widthChars, updateProperties, (storage.previousState as? Self)?.widthChars != widthChars {
gtk_label_set_width_chars(widget, widthChars.cInt)
}
if let wrap, updateProperties, (storage.previousState as? Self)?.wrap != wrap {
gtk_label_set_wrap(widget, wrap.cBool)
}
if let xalign, updateProperties, (storage.previousState as? Self)?.xalign != xalign {
gtk_label_set_xalign(widget, xalign)
}
if let yalign, updateProperties, (storage.previousState as? Self)?.yalign != yalign {
gtk_label_set_yalign(widget, yalign)
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
}
if updateProperties {
storage.previousState = self
}
}
/// The accessible role of the given `GtkAccessible` implementation.
///
/// The accessible role cannot be changed once set.
public func accessibleRole(_ accessibleRole: String?) -> Self {
modify { $0.accessibleRole = accessibleRole }
}
/// The contents of the label.
///
/// If the string contains Pango markup (see `Pango.parse_markup`),
/// you will have to set the ``useMarkup(_:)`` property to
/// true in order for the label to display the markup attributes. See also
/// `Gtk.Label.set_markup` for a convenience function that sets both
/// this property and the ``useMarkup(_:)`` property at the
/// same time.
///
/// If the string contains underlines acting as mnemonics, you will have to
/// set the ``useUnderline(_:)`` property to true in order
/// for the label to display them.
public func label(_ label: String) -> Self {
modify { $0.label = label }
}
/// The number of lines to which an ellipsized, wrapping label
/// should display before it gets ellipsized. This both prevents the label
/// from ellipsizing before this many lines are displayed, and limits the
/// height request of the label to this many lines.
///
/// > [!WARNING]
/// > Setting this property has unintuitive and unfortunate consequences
/// for the minimum _width_ of the label. Specifically, if the height
/// of the label is such that it fits a smaller number of lines than
/// the value of this property, the label can not be ellipsized at all,
/// which means it must be wide enough to fit all the text fully.
///
/// This property has no effect if the label is not wrapping or ellipsized.
///
/// Set this property to -1 if you don't want to limit the number of lines.
public func lines(_ lines: Int?) -> Self {
modify { $0.lines = lines }
}
/// The desired maximum width of the label, in characters.
///
/// If this property is set to -1, the width will be calculated automatically.
///
/// See the section on [text layout](class.Label.html
public func maxWidthChars(_ maxWidthChars: Int?) -> Self {
modify { $0.maxWidthChars = maxWidthChars }
}
/// The mnemonic accelerator key for the label.
public func mnemonicKeyval(_ mnemonicKeyval: UInt?) -> Self {
modify { $0.mnemonicKeyval = mnemonicKeyval }
}
/// The widget to be activated when the labels mnemonic key is pressed.
public func mnemonicWidget(@ViewBuilder _ mnemonicWidget: () -> Body) -> Self {
modify { $0.mnemonicWidget = mnemonicWidget() }
}
/// Whether the label text can be selected with the mouse.
public func selectable(_ selectable: Bool? = true) -> Self {
modify { $0.selectable = selectable }
}
/// Whether the label is in single line mode.
///
/// In single line mode, the height of the label does not depend on the
/// actual text, it is always set to ascent + descent of the font. This
/// can be an advantage in situations where resizing the label because
/// of text changes would be distracting, e.g. in a statusbar.
public func singleLineMode(_ singleLineMode: Bool? = true) -> Self {
modify { $0.singleLineMode = singleLineMode }
}
/// True if the text of the label includes Pango markup.
///
/// See `Pango.parse_markup`.
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
modify { $0.useMarkup = useMarkup }
}
/// True if the text of the label indicates a mnemonic with an `_`
/// before the mnemonic character.
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
modify { $0.useUnderline = useUnderline }
}
/// The desired width of the label, in characters.
///
/// If this property is set to -1, the width will be calculated automatically.
///
/// See the section on [text layout](class.Label.html
public func widthChars(_ widthChars: Int?) -> Self {
modify { $0.widthChars = widthChars }
}
/// True if the label text will wrap if it gets too wide.
public func wrap(_ wrap: Bool? = true) -> Self {
modify { $0.wrap = wrap }
}
/// The horizontal alignment of the label text inside its size allocation.
///
/// Compare this to ``halign(_:)``, which determines how the
/// labels size allocation is positioned in the space available for the label.
public func xalign(_ xalign: Float?) -> Self {
modify { $0.xalign = xalign }
}
/// The vertical alignment of the label text inside its size allocation.
///
/// Compare this to ``valign(_:)``, which determines how the
/// labels size allocation is positioned in the space available for the label.
public func yalign(_ yalign: Float?) -> Self {
modify { $0.yalign = yalign }
}
/// Gets emitted to copy the selection to the clipboard.
///
/// The `::copy-clipboard` signal is a [keybinding signal](class.SignalAction.html).
///
/// The default binding for this signal is <kbd>Ctrl</kbd>+<kbd>c</kbd>.
public func copyClipboard(_ copyClipboard: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.copyClipboard = copyClipboard
return newSelf
}
}

View File

@ -2,21 +2,21 @@
// LevelBar.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// `GtkLevelBar` is a widget that can be used as a level indicator.
/// Shows a level indicator.
///
/// Typical use cases are displaying the strength of a password, or
/// showing the charge level of a battery.
///
/// ![An example GtkLevelBar](levelbar.png)
///
/// Use [method@Gtk.LevelBar.set_value] to set the current value, and
/// [method@Gtk.LevelBar.add_offset_value] to set the value offsets at which
///
/// Use `Gtk.LevelBar.set_value` to set the current value, and
/// `Gtk.LevelBar.add_offset_value` to set the value offsets at which
/// the bar will be considered in a different state. GTK will add a few
/// offsets by default on the level bar: %GTK_LEVEL_BAR_OFFSET_LOW,
/// %GTK_LEVEL_BAR_OFFSET_HIGH and %GTK_LEVEL_BAR_OFFSET_FULL, with
@ -26,91 +26,20 @@ import LevenshteinTransformations
/// when changing the minimum or maximum value. GTK will simply clamp
/// them to the new range.
///
/// ## Adding a custom offset on the bar
///
/// ```c
/// static GtkWidget *
/// create_level_bar (void)
/// {
/// GtkWidget *widget;
/// GtkLevelBar *bar;
///
/// widget = gtk_level_bar_new ();
/// bar = GTK_LEVEL_BAR (widget);
///
/// // This changes the value of the default low offset
///
/// gtk_level_bar_add_offset_value (bar,
/// GTK_LEVEL_BAR_OFFSET_LOW,
/// 0.10);
///
/// // This adds a new offset to the bar; the application will
/// // be able to change its color CSS like this:
/// //
/// // levelbar block.my-offset {
/// // background-color: magenta;
/// // border-style: solid;
/// // border-color: black;
/// // border-width: 1px;
/// // }
///
/// gtk_level_bar_add_offset_value (bar, "my-offset", 0.60);
///
/// return widget;
/// }
/// ```
///
/// The default interval of values is between zero and one, but its possible
/// to modify the interval using [method@Gtk.LevelBar.set_min_value] and
/// [method@Gtk.LevelBar.set_max_value]. The value will be always drawn in
/// proportion to the admissible interval, i.e. a value of 15 with a specified
/// interval between 10 and 20 is equivalent to a value of 0.5 with an interval
/// between 0 and 1. When %GTK_LEVEL_BAR_MODE_DISCRETE is used, the bar level
/// is rendered as a finite number of separated blocks instead of a single one.
/// The number of blocks that will be rendered is equal to the number of units
/// specified by the admissible interval.
///
/// For instance, to build a bar rendered with five blocks, its sufficient to
/// set the minimum value to 0 and the maximum value to 5 after changing the
/// indicator mode to discrete.
///
/// # GtkLevelBar as GtkBuildable
///
/// The `GtkLevelBar` implementation of the `GtkBuildable` interface supports a
/// custom `<offsets>` element, which can contain any number of `<offset>` elements,
/// each of which must have "name" and "value" attributes.
///
/// # CSS nodes
///
/// ```
/// levelbar[.discrete]
/// trough
/// block.filled.level-name
///
/// block.empty
///
/// ```
///
/// `GtkLevelBar` has a main CSS node with name levelbar and one of the style
/// classes .discrete or .continuous and a subnode with name trough. Below the
/// trough node are a number of nodes with name block and style class .filled
/// or .empty. In continuous mode, there is exactly one node of each, in discrete
/// mode, the number of filled and unfilled nodes corresponds to blocks that are
/// drawn. The block.filled nodes also get a style class .level-name corresponding
/// to the level for the current value.
///
/// In horizontal orientation, the nodes are always arranged from left to right,
/// regardless of text direction.
///
/// # Accessibility
///
/// `GtkLevelBar` uses the %GTK_ACCESSIBLE_ROLE_METER role.
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.
///
@ -129,7 +58,7 @@ public struct LevelBar: AdwaitaWidget {
var value: Double?
/// Emitted when an offset specified on the bar changes value.
///
/// This typically is the result of a [method@Gtk.LevelBar.add_offset_value]
/// This typically is the result of a `Gtk.LevelBar.add_offset_value`
/// call.
///
/// The signal supports detailed connections; you can connect to the
@ -151,7 +80,6 @@ public struct LevelBar: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}
@ -184,6 +112,7 @@ public struct LevelBar: AdwaitaWidget {
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -197,10 +126,7 @@ public struct LevelBar: AdwaitaWidget {
///
/// The accessible role cannot be changed once set.
public func accessibleRole(_ accessibleRole: String?) -> Self {
var newSelf = self
newSelf.accessibleRole = accessibleRole
return newSelf
modify { $0.accessibleRole = accessibleRole }
}
/// Whether the `GtkLeveBar` is inverted.
@ -208,39 +134,27 @@ public struct LevelBar: AdwaitaWidget {
/// Level bars normally grow from top to bottom or left to right.
/// Inverted level bars grow in the opposite direction.
public func inverted(_ inverted: Bool? = true) -> Self {
var newSelf = self
newSelf.inverted = inverted
return newSelf
modify { $0.inverted = inverted }
}
/// Determines the maximum value of the interval that can be displayed by the bar.
public func maxValue(_ maxValue: Double?) -> Self {
var newSelf = self
newSelf.maxValue = maxValue
return newSelf
modify { $0.maxValue = maxValue }
}
/// Determines the minimum value of the interval that can be displayed by the bar.
public func minValue(_ minValue: Double?) -> Self {
var newSelf = self
newSelf.minValue = minValue
return newSelf
modify { $0.minValue = minValue }
}
/// Determines the currently filled value of the level bar.
public func value(_ value: Double?) -> Self {
var newSelf = self
newSelf.value = value
return newSelf
modify { $0.value = value }
}
/// Emitted when an offset specified on the bar changes value.
///
/// This typically is the result of a [method@Gtk.LevelBar.add_offset_value]
/// This typically is the result of a `Gtk.LevelBar.add_offset_value`
/// call.
///
/// The signal supports detailed connections; you can connect to the

View File

@ -2,50 +2,50 @@
// LinkButton.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// A `GtkLinkButton` is a button with a hyperlink.
/// A button with a hyperlink.
///
///
/// ![An example GtkLinkButton](link-button.png)
///
/// It is useful to show quick links to resources.
///
/// A link button is created by calling either [ctor@Gtk.LinkButton.new] or
/// [ctor@Gtk.LinkButton.new_with_label]. If using the former, the URI you
/// A link button is created by calling either `Gtk.LinkButton.new` or
/// `Gtk.LinkButton.new_with_label`. If using the former, the URI you
/// pass to the constructor is used as a label for the widget.
///
/// The URI bound to a `GtkLinkButton` can be set specifically using
/// [method@Gtk.LinkButton.set_uri].
/// `Gtk.LinkButton.set_uri`.
///
/// By default, `GtkLinkButton` calls [method@Gtk.FileLauncher.launch] when the button
/// By default, `GtkLinkButton` calls `Gtk.FileLauncher.launch` when the button
/// is clicked. This behaviour can be overridden by connecting to the
/// [signal@Gtk.LinkButton::activate-link] signal and returning %TRUE from
/// `Gtk.LinkButton::activate-link` signal and returning `true` from
/// the signal handler.
///
/// # CSS nodes
///
/// `GtkLinkButton` has a single CSS node with name button. To differentiate
/// it from a plain `GtkButton`, it gets the .link style class.
///
/// # Accessibility
///
/// `GtkLinkButton` uses the %GTK_ACCESSIBLE_ROLE_LINK role.
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.
///
/// The accessible role cannot be changed once set.
var accessibleRole: String?
/// action-name
/// The name of the action with which this widget should be associated.
var actionName: String?
/// Whether the size of the button can be made smaller than the natural
/// size of its contents.
@ -56,7 +56,7 @@ public struct LinkButton: AdwaitaWidget {
/// property has no effect.
var canShrink: Bool?
/// The child widget.
var child: (() -> Body)?
var child: Body?
/// Whether the button has a frame.
var hasFrame: Bool?
/// The name of the icon used to automatically populate the button.
@ -75,7 +75,7 @@ public struct LinkButton: AdwaitaWidget {
/// Emitted to animate press then release.
///
/// This is an action signal. Applications should never connect
/// to this signal, but use the [signal@Gtk.Button::clicked] signal.
/// to this signal, but use the `Gtk.Button::clicked` signal.
///
/// The default bindings for this signal are all forms of the
/// <kbd></kbd> and <kbd>Enter</kbd> keys.
@ -98,8 +98,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) {
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
gtk_button_set_child(storage.opaquePointer?.cast(), childStorage.opaquePointer?.cast())
}
@ -133,7 +132,7 @@ public struct LinkButton: AdwaitaWidget {
gtk_button_set_can_shrink(widget?.cast(), canShrink.cBool)
}
if let widget = storage.content["child"]?.first {
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
child?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
if let hasFrame, updateProperties, (storage.previousState as? Self)?.hasFrame != hasFrame {
gtk_button_set_has_frame(widget?.cast(), hasFrame.cBool)
@ -155,6 +154,7 @@ public struct LinkButton: AdwaitaWidget {
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -168,18 +168,12 @@ public struct LinkButton: AdwaitaWidget {
///
/// The accessible role cannot be changed once set.
public func accessibleRole(_ accessibleRole: String?) -> Self {
var newSelf = self
newSelf.accessibleRole = accessibleRole
return newSelf
modify { $0.accessibleRole = accessibleRole }
}
/// action-name
/// The name of the action with which this widget should be associated.
public func actionName(_ actionName: String?) -> Self {
var newSelf = self
newSelf.actionName = actionName
return newSelf
modify { $0.actionName = actionName }
}
/// Whether the size of the button can be made smaller than the natural
@ -190,75 +184,51 @@ public struct LinkButton: AdwaitaWidget {
/// If the contents of a button are an icon or a custom widget, setting this
/// property has no effect.
public func canShrink(_ canShrink: Bool? = true) -> Self {
var newSelf = self
newSelf.canShrink = canShrink
return newSelf
modify { $0.canShrink = canShrink }
}
/// The child widget.
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.child = child
return newSelf
public func child(@ViewBuilder _ child: () -> Body) -> Self {
modify { $0.child = child() }
}
/// Whether the button has a frame.
public func hasFrame(_ hasFrame: Bool? = true) -> Self {
var newSelf = self
newSelf.hasFrame = hasFrame
return newSelf
modify { $0.hasFrame = hasFrame }
}
/// The name of the icon used to automatically populate the button.
public func iconName(_ iconName: String?) -> Self {
var newSelf = self
newSelf.iconName = iconName
return newSelf
modify { $0.iconName = iconName }
}
/// Text of the label inside the button, if the button contains a label widget.
public func label(_ label: String?) -> Self {
var newSelf = self
newSelf.label = label
return newSelf
modify { $0.label = label }
}
/// The URI bound to this button.
public func uri(_ uri: String) -> Self {
var newSelf = self
newSelf.uri = uri
return newSelf
modify { $0.uri = uri }
}
/// If set, an underline in the text indicates that the following character is
/// to be used as mnemonic.
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
var newSelf = self
newSelf.useUnderline = useUnderline
return newSelf
modify { $0.useUnderline = useUnderline }
}
/// The 'visited' state of this button.
///
/// A visited link is drawn in a different color.
public func visited(_ visited: Bool? = true) -> Self {
var newSelf = self
newSelf.visited = visited
return newSelf
modify { $0.visited = visited }
}
/// Emitted to animate press then release.
///
/// This is an action signal. Applications should never connect
/// to this signal, but use the [signal@Gtk.Button::clicked] signal.
/// to this signal, but use the `Gtk.Button::clicked` signal.
///
/// The default bindings for this signal are all forms of the
/// <kbd></kbd> and <kbd>Enter</kbd> keys.

View File

@ -2,13 +2,15 @@
// ListBox.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// `GtkListBox` is a vertical list.
/// Shows a vertical list.
///
///
///
/// A `GtkListBox` only contains `GtkListBoxRow` children. These rows can
/// by dynamically sorted and filtered, and headers can be added dynamically
@ -21,52 +23,30 @@ import LevenshteinTransformations
/// button in it).
///
/// Although a `GtkListBox` must have only `GtkListBoxRow` children, you can
/// add any kind of widget to it via [method@Gtk.ListBox.prepend],
/// [method@Gtk.ListBox.append] and [method@Gtk.ListBox.insert] and a
/// add any kind of widget to it via `Gtk.ListBox.prepend`,
/// `Gtk.ListBox.append` and `Gtk.ListBox.insert` and a
/// `GtkListBoxRow` widget will automatically be inserted between the list
/// and the widget.
///
/// `GtkListBoxRows` can be marked as activatable or selectable. If a row is
/// activatable, [signal@Gtk.ListBox::row-activated] will be emitted for it when
/// activatable, `Gtk.ListBox::row-activated` will be emitted for it when
/// the user tries to activate it. If it is selectable, the row will be marked
/// as selected when the user tries to select it.
///
/// # GtkListBox as GtkBuildable
///
/// The `GtkListBox` implementation of the `GtkBuildable` interface supports
/// setting a child as the placeholder by specifying placeholder as the type
/// attribute of a `<child>` element. See [method@Gtk.ListBox.set_placeholder]
/// for info.
///
/// # CSS nodes
///
/// |[<!-- language="plain" -->
/// list[.separators][.rich-list][.navigation-sidebar][.boxed-list]
/// row[.activatable]
/// ]|
///
/// `GtkListBox` uses a single CSS node named list. It may carry the .separators
/// style class, when the [property@Gtk.ListBox:show-separators] property is set.
/// Each `GtkListBoxRow` uses a single CSS node named row. The row nodes get the
/// .activatable style class added when appropriate.
///
/// It may also carry the .boxed-list style class. In this case, the list will be
/// automatically surrounded by a frame and have separators.
///
/// The main list node may also carry style classes to select
/// the style of [list presentation](section-list-widget.html#list-styles):
/// .rich-list, .navigation-sidebar or .data-table.
///
/// # Accessibility
///
/// `GtkListBox` uses the %GTK_ACCESSIBLE_ROLE_LIST role and `GtkListBoxRow` uses
/// the %GTK_ACCESSIBLE_ROLE_LIST_ITEM role.
public struct ListBox<Element>: AdwaitaWidget where Element: Identifiable {
public struct ListBox<Element, Identifier>: AdwaitaWidget where Identifier: Equatable {
#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?
@ -79,9 +59,19 @@ public struct ListBox<Element>: AdwaitaWidget where Element: Identifiable {
var activateOnSingleClick: Bool?
/// Whether to show separators between rows.
var showSeparators: Bool?
/// activateCursorRow
/// Emitted when the cursor row is activated.
var activateCursorRow: (() -> Void)?
/// moveCursor
/// Emitted when the user initiates a cursor movement.
///
/// The default bindings for this signal come in two variants, the variant with
/// the Shift modifier extends the selection, the variant without the Shift
/// modifier does not. There are too many key combinations to list them all
/// here.
///
/// - <kbd></kbd>, <kbd></kbd>, <kbd></kbd>, <kbd></kbd>
/// move by individual children
/// - <kbd>Home</kbd>, <kbd>End</kbd> move to the ends of the box
/// - <kbd>PgUp</kbd>, <kbd>PgDn</kbd> move vertically by pages
var moveCursor: (() -> Void)?
/// Emitted when a row has been activated by the user.
var rowActivated: (() -> Void)?
@ -90,7 +80,7 @@ public struct ListBox<Element>: AdwaitaWidget where Element: Identifiable {
///
/// When the @box is using %GTK_SELECTION_MULTIPLE, this signal will not
/// give you the full picture of selection changes, and you should use
/// the [signal@Gtk.ListBox::selected-rows-changed] signal instead.
/// the `Gtk.ListBox::selected-rows-changed` signal instead.
var rowSelected: (() -> Void)?
/// Emitted to select all children of the box, if the selection
/// mode permits it.
@ -101,7 +91,9 @@ public struct ListBox<Element>: AdwaitaWidget where Element: Identifiable {
var selectAll: (() -> Void)?
/// Emitted when the set of selected rows changes.
var selectedRowsChanged: (() -> Void)?
/// toggleCursorRow
/// Emitted when the cursor row is toggled.
///
/// The default bindings for this signal is <kbd>Ctrl</kbd>+<kbd></kbd>.
var toggleCursorRow: (() -> Void)?
/// Emitted to unselect all children of the box, if the selection
/// mode permits it.
@ -115,11 +107,14 @@ public struct ListBox<Element>: AdwaitaWidget where Element: Identifiable {
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], @ViewBuilder content: @escaping (Element) -> Body) {
public init(_ elements: [Element], id: KeyPath<Element, Identifier>, @ViewBuilder content: @escaping (Element) -> Body) {
self.elements = elements
self.content = content
self.id = id
}
/// The view storage.
@ -132,7 +127,6 @@ public struct ListBox<Element>: AdwaitaWidget where Element: Identifiable {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}
@ -195,15 +189,10 @@ public struct ListBox<Element>: AdwaitaWidget where Element: Identifiable {
var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? []
let old = storage.fields["element"] as? [Element] ?? []
old.identifiableTransform(
old.transform(
to: elements,
functions: .init { index, element in
let child = content(element).storage(data: data, type: type)
gtk_list_box_remove(widget, gtk_list_box_get_row_at_index(widget, index.cInt)?.cast())
gtk_list_box_insert(widget, child.opaquePointer?.cast(), index.cInt)
contentStorage.remove(at: index)
contentStorage.insert(child, at: index)
} delete: { index in
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)
} insert: { index, element in
@ -217,6 +206,7 @@ public struct ListBox<Element>: AdwaitaWidget where Element: Identifiable {
for (index, element) in elements.enumerated() {
content(element).updateStorage(contentStorage[index], data: data, updateProperties: updateProperties, type: type)
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -228,47 +218,45 @@ public struct ListBox<Element>: AdwaitaWidget where Element: Identifiable {
/// Whether to accept unpaired release events.
public func acceptUnpairedRelease(_ acceptUnpairedRelease: Bool? = true) -> Self {
var newSelf = self
newSelf.acceptUnpairedRelease = acceptUnpairedRelease
return newSelf
modify { $0.acceptUnpairedRelease = acceptUnpairedRelease }
}
/// The accessible role of the given `GtkAccessible` implementation.
///
/// The accessible role cannot be changed once set.
public func accessibleRole(_ accessibleRole: String?) -> Self {
var newSelf = self
newSelf.accessibleRole = accessibleRole
return newSelf
modify { $0.accessibleRole = accessibleRole }
}
/// Determines whether children can be activated with a single
/// click, or require a double-click.
public func activateOnSingleClick(_ activateOnSingleClick: Bool? = true) -> Self {
var newSelf = self
newSelf.activateOnSingleClick = activateOnSingleClick
return newSelf
modify { $0.activateOnSingleClick = activateOnSingleClick }
}
/// Whether to show separators between rows.
public func showSeparators(_ showSeparators: Bool? = true) -> Self {
var newSelf = self
newSelf.showSeparators = showSeparators
return newSelf
modify { $0.showSeparators = showSeparators }
}
/// activateCursorRow
/// Emitted when the cursor row is activated.
public func activateCursorRow(_ activateCursorRow: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.activateCursorRow = activateCursorRow
return newSelf
}
/// moveCursor
/// Emitted when the user initiates a cursor movement.
///
/// The default bindings for this signal come in two variants, the variant with
/// the Shift modifier extends the selection, the variant without the Shift
/// modifier does not. There are too many key combinations to list them all
/// here.
///
/// - <kbd></kbd>, <kbd></kbd>, <kbd></kbd>, <kbd></kbd>
/// move by individual children
/// - <kbd>Home</kbd>, <kbd>End</kbd> move to the ends of the box
/// - <kbd>PgUp</kbd>, <kbd>PgDn</kbd> move vertically by pages
public func moveCursor(_ moveCursor: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.moveCursor = moveCursor
@ -287,7 +275,7 @@ public struct ListBox<Element>: AdwaitaWidget where Element: Identifiable {
///
/// When the @box is using %GTK_SELECTION_MULTIPLE, this signal will not
/// give you the full picture of selection changes, and you should use
/// the [signal@Gtk.ListBox::selected-rows-changed] signal instead.
/// the `Gtk.ListBox::selected-rows-changed` signal instead.
public func rowSelected(_ rowSelected: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.rowSelected = rowSelected
@ -313,7 +301,9 @@ public struct ListBox<Element>: AdwaitaWidget where Element: Identifiable {
return newSelf
}
/// toggleCursorRow
/// Emitted when the cursor row is toggled.
///
/// The default bindings for this signal is <kbd>Ctrl</kbd>+<kbd></kbd>.
public func toggleCursorRow(_ toggleCursorRow: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.toggleCursorRow = toggleCursorRow
@ -334,3 +324,14 @@ public struct ListBox<Element>: AdwaitaWidget where Element: Identifiable {
}
}
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,30 +2,30 @@
// Menu.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// The `GtkMenuButton` widget is used to display a popup when clicked.
/// Displays a popup when clicked.
///
///
/// ![An example GtkMenuButton](menu-button.png)
///
/// This popup can be provided either as a `GtkPopover` or as an abstract
/// `GMenuModel`.
///
/// The `GtkMenuButton` widget can show either an icon (set with the
/// [property@Gtk.MenuButton:icon-name] property) or a label (set with the
/// [property@Gtk.MenuButton:label] property). If neither is explicitly set,
/// a [class@Gtk.Image] is automatically created, using an arrow image oriented
/// according to [property@Gtk.MenuButton:direction] or the generic
/// ``iconName(_:)`` property) or a label (set with the
/// ``label(_:)`` property). If neither is explicitly set,
/// a `Gtk.Image` is automatically created, using an arrow image oriented
/// according to ``direction(_:)`` or the generic
/// open-menu-symbolic icon if the direction is not set.
///
/// The positioning of the popup is determined by the
/// [property@Gtk.MenuButton:direction] property of the menu button.
/// ``direction(_:)`` property of the menu button.
///
/// For menus, the [property@Gtk.Widget:halign] and [property@Gtk.Widget:valign]
/// For menus, the ``halign(_:)`` and ``valign(_:)``
/// properties of the menu are also taken into account. For example, when the
/// direction is %GTK_ARROW_DOWN and the horizontal alignment is %GTK_ALIGN_START,
/// the menu will be positioned below the button, with the starting edge
@ -41,40 +41,20 @@ import LevenshteinTransformations
/// | **left** | ![](left-start.png) | ![](left-center.png) | ![](left-end.png) |
/// | **right** | ![](right-start.png) | ![](right-center.png) | ![](right-end.png) |
///
/// # CSS nodes
///
/// ```
/// menubutton
/// button.toggle
/// <content> [arrow]
/// ```
///
/// `GtkMenuButton` has a single CSS node with name `menubutton`
/// which contains a `button` node with a `.toggle` style class.
///
/// If the button contains an icon, it will have the `.image-button` style class,
/// if it contains text, it will have `.text-button` style class. If an arrow is
/// visible in addition to an icon, text or a custom child, it will also have
/// `.arrow-button` style class.
///
/// Inside the toggle button content, there is an `arrow` node for
/// the indicator, which will carry one of the `.none`, `.up`, `.down`,
/// `.left` or `.right` style classes to indicate the direction that
/// the menu will appear in. The CSS is expected to provide a suitable
/// image for each of these cases using the `-gtk-icon-source` property.
///
/// Optionally, the `menubutton` node can carry the `.circular` style class
/// to request a round appearance.
///
/// # Accessibility
///
/// `GtkMenuButton` uses the %GTK_ACCESSIBLE_ROLE_BUTTON role.
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.
///
@ -88,7 +68,7 @@ public struct Menu: AdwaitaWidget {
/// size of its contents.
var canShrink: Bool?
/// The child widget.
var child: (() -> Body)?
var child: Body?
/// Whether the button has a frame.
var hasFrame: Bool?
/// The name of the icon used to automatically populate the button.
@ -97,9 +77,9 @@ public struct Menu: AdwaitaWidget {
var label: String?
/// The `GMenuModel` from which the popup will be created.
///
/// See [method@Gtk.MenuButton.set_menu_model] for the interaction
/// with the [property@Gtk.MenuButton:popover] property.
var menuModel: (() -> Body)?
/// See `Gtk.MenuButton.set_menu_model` for the interaction
/// with the ``popover(_:)`` property.
var menuModel: Body?
/// Whether the menu button acts as a primary menu.
///
/// Primary menus can be opened using the <kbd>F10</kbd> key
@ -113,7 +93,7 @@ public struct Menu: AdwaitaWidget {
var activate: (() -> Void)?
/// Initialize `Menu`.
public init() {
init() {
}
/// The view storage.
@ -126,13 +106,12 @@ 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) {
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
gtk_menu_button_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())
}
if let menu = menuModel?() {
let childStorage = MenuCollection { menu }.getMenu(data: data)
if let menuModel {
let childStorage = MenuCollection { menuModel }.getMenu(data: data)
storage.content["menuModel"] = [childStorage]
gtk_menu_button_set_menu_model(storage.opaquePointer, childStorage.opaquePointer?.cast())
}
@ -170,7 +149,7 @@ if let active, newValue != active.wrappedValue {
gtk_menu_button_set_can_shrink(widget, canShrink.cBool)
}
if let widget = storage.content["child"]?.first {
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
child?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
if let hasFrame, updateProperties, (storage.previousState as? Self)?.hasFrame != hasFrame {
gtk_menu_button_set_has_frame(widget, hasFrame.cBool)
@ -182,7 +161,7 @@ if let active, newValue != active.wrappedValue {
gtk_menu_button_set_label(widget, label)
}
if let menu = storage.content["menuModel"]?.first {
MenuCollection { menuModel?() ?? [] }
MenuCollection { menuModel ?? [] }
.updateStorage(menu, data: data.noModifiers, updateProperties: updateProperties, type: MenuContext.self)
}
if let primary, updateProperties, (storage.previousState as? Self)?.primary != primary {
@ -193,6 +172,7 @@ if let active, newValue != active.wrappedValue {
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -206,96 +186,63 @@ if let active, newValue != active.wrappedValue {
///
/// The accessible role cannot be changed once set.
public func accessibleRole(_ accessibleRole: String?) -> Self {
var newSelf = self
newSelf.accessibleRole = accessibleRole
return newSelf
modify { $0.accessibleRole = accessibleRole }
}
/// Whether the menu button is active.
public func active(_ active: Binding<Bool>?) -> Self {
var newSelf = self
newSelf.active = active
return newSelf
modify { $0.active = active }
}
/// Whether to show a dropdown arrow even when using an icon or a custom child.
public func alwaysShowArrow(_ alwaysShowArrow: Bool? = true) -> Self {
var newSelf = self
newSelf.alwaysShowArrow = alwaysShowArrow
return newSelf
modify { $0.alwaysShowArrow = alwaysShowArrow }
}
/// Whether the size of the button can be made smaller than the natural
/// size of its contents.
public func canShrink(_ canShrink: Bool? = true) -> Self {
var newSelf = self
newSelf.canShrink = canShrink
return newSelf
modify { $0.canShrink = canShrink }
}
/// The child widget.
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.child = child
return newSelf
public func child(@ViewBuilder _ child: () -> Body) -> Self {
modify { $0.child = child() }
}
/// Whether the button has a frame.
public func hasFrame(_ hasFrame: Bool? = true) -> Self {
var newSelf = self
newSelf.hasFrame = hasFrame
return newSelf
modify { $0.hasFrame = hasFrame }
}
/// The name of the icon used to automatically populate the button.
public func iconName(_ iconName: String?) -> Self {
var newSelf = self
newSelf.iconName = iconName
return newSelf
modify { $0.iconName = iconName }
}
/// The label for the button.
public func label(_ label: String?) -> Self {
var newSelf = self
newSelf.label = label
return newSelf
modify { $0.label = label }
}
/// The `GMenuModel` from which the popup will be created.
///
/// See [method@Gtk.MenuButton.set_menu_model] for the interaction
/// with the [property@Gtk.MenuButton:popover] property.
public func menuModel(@ViewBuilder _ menuModel: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.menuModel = menuModel
return newSelf
/// See `Gtk.MenuButton.set_menu_model` for the interaction
/// with the ``popover(_:)`` property.
public func menuModel(@ViewBuilder _ menuModel: () -> Body) -> Self {
modify { $0.menuModel = menuModel() }
}
/// Whether the menu button acts as a primary menu.
///
/// Primary menus can be opened using the <kbd>F10</kbd> key
public func primary(_ primary: Bool? = true) -> Self {
var newSelf = self
newSelf.primary = primary
return newSelf
modify { $0.primary = primary }
}
/// If set an underscore in the text indicates a mnemonic.
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
var newSelf = self
newSelf.useUnderline = useUnderline
return newSelf
modify { $0.useUnderline = useUnderline }
}
/// Emitted to when the menu button is activated.

View File

@ -2,7 +2,7 @@
// NavigationView.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
@ -10,130 +10,74 @@ import LevenshteinTransformations
/// A page-based navigation container.
///
/// <picture><source srcset="navigation-view-dark.png" media="(prefers-color-scheme: dark)"><img src="navigation-view.png" alt="navigation-view"></picture>
///
///
/// `AdwNavigationView` presents one child at a time, similar to
/// [class@Gtk.Stack].
/// `Gtk.Stack`.
///
/// `AdwNavigationView` can only contain [class@NavigationPage] children.
/// `AdwNavigationView` can only contain `NavigationPage` children.
///
/// It maintains a navigation stack that can be controlled with
/// [method@NavigationView.push] and [method@NavigationView.pop]. The whole
/// navigation stack can also be replaced using [method@NavigationView.replace].
/// `NavigationView.push` and `NavigationView.pop`. The whole
/// navigation stack can also be replaced using `NavigationView.replace`.
///
/// `AdwNavigationView` allows to manage pages statically or dynamically.
///
/// Static pages can be added using the [method@NavigationView.add] method. The
/// Static pages can be added using the `NavigationView.add` method. The
/// `AdwNavigationView` will keep a reference to these pages, but they aren't
/// accessible to the user until [method@NavigationView.push] is called (except
/// accessible to the user until `NavigationView.push` is called (except
/// for the first page, which is pushed automatically). Use the
/// [method@NavigationView.remove] method to remove them. This is useful for
/// `NavigationView.remove` method to remove them. This is useful for
/// applications that have a small number of unique pages and just need
/// navigation between them.
///
/// Dynamic pages are automatically destroyed once they are popped off the
/// navigation stack. To add a page like this, push it using the
/// [method@NavigationView.push] method without calling
/// [method@NavigationView.add] first.
/// `NavigationView.push` method without calling
/// `NavigationView.add` first.
///
/// ## Tags
///
/// Static pages, as well as any pages in the navigation stack, can be accessed
/// by their [property@NavigationPage:tag]. For example,
/// [method@NavigationView.push_by_tag] can be used to push a static page that's
/// not in the navigation stack without having to keep a reference to it manually.
///
/// ## Header Bar Integration
///
/// When used inside `AdwNavigationView`, [class@HeaderBar] will automatically
/// display a back button that can be used to go back to the previous page when
/// possible. The button also has a context menu, allowing to pop multiple pages
/// at once, potentially across multiple navigation views.
///
/// Set [property@HeaderBar:show-back-button] to `FALSE` to disable this behavior
/// in rare scenarios where it's unwanted.
///
/// `AdwHeaderBar` will also display the title of the `AdwNavigationPage` it's
/// placed into, so most applications shouldn't need to customize it at all.
///
/// ## Shortcuts and Gestures
///
/// `AdwNavigationView` supports the following shortcuts for going to the
/// previous page:
///
/// - <kbd>Escape</kbd> (unless [property@NavigationView:pop-on-escape] is set to
/// `FALSE`)
/// - <kbd>Alt</kbd>+<kbd></kbd>
/// - Back mouse button
///
/// Additionally, it supports interactive gestures:
///
/// - One-finger swipe towards the right on touchscreens
/// - Scrolling towards the right on touchpads (usually two-finger swipe)
///
/// These gestures have transitions enabled regardless of the
/// [property@NavigationView:animate-transitions] value.
///
/// Applications can also enable shortcuts for pushing another page onto the
/// navigation stack via connecting to the [signal@NavigationView::get-next-page]
/// signal, in that case the following shortcuts are supported:
///
/// - <kbd>Alt</kbd>+<kbd></kbd>
/// - Forward mouse button
/// - Swipe/scrolling towards the left
///
/// For right-to-left locales, the gestures and shortcuts are reversed.
///
/// [property@NavigationPage:can-pop] can be used to disable them, along with the
/// header bar back buttons.
///
/// ## Actions
///
/// `AdwNavigationView` defines actions for controlling the navigation stack.
/// actions for controlling the navigation stack:
///
/// - `navigation.push` takes a string parameter specifying the tag of the page to
/// push, and is equivalent to calling [method@NavigationView.push_by_tag].
///
/// - `navigation.pop` doesn't take any parameters and pops the current page from
/// the navigation stack, equivalent to calling [method@NavigationView.pop].
///
/// ## `AdwNavigationView` as `GtkBuildable`
///
/// `AdwNavigationView` allows to add pages as children, equivalent to using the
/// [method@NavigationView.add] method.
///
/// Example of an `AdwNavigationView` UI definition:
///
/// ```xml
/// <object class="AdwNavigationView"><child><object class="AdwNavigationPage"><property name="title" translatable="yes">Page 1</property><property name="child"><object class="AdwToolbarView"><child type="top"><object class="AdwHeaderBar"/></child><property name="content"><object class="GtkButton"><property name="label" translatable="yes">Open Page 2</property><property name="halign">center</property><property name="valign">center</property><property name="action-name">navigation.push</property><property name="action-target">'page-2'</property><style><class name="pill"/></style></object></property></object></property></object></child><child><object class="AdwNavigationPage"><property name="title" translatable="yes">Page 2</property><property name="tag">page-2</property><property name="child"><object class="AdwToolbarView"><child type="top"><object class="AdwHeaderBar"/></child><property name="content"><!-- ... --></property></object></property></object></child></object>
/// ```
///
/// <picture><source srcset="navigation-view-example-dark.png" media="(prefers-color-scheme: dark)"><img src="navigation-view-example.png" alt="navigation-view-example"></picture>
///
/// ## CSS nodes
///
/// `AdwNavigationView` has a single CSS node with the name `navigation-view`.
///
/// ## Accessibility
///
/// `AdwNavigationView` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
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.
///
/// Gesture-based transitions are always animated.
var animateTransitions: Bool?
/// Whether the view is horizontally homogeneous.
///
/// If the view is horizontally homogeneous, it allocates the same width for
/// all pages.
///
/// If it's not, the page may change width when a different page becomes
/// visible.
var hhomogeneous: Bool?
/// Whether pressing Escape pops the current page.
///
/// Applications using `AdwNavigationView` to implement a browser may want to
/// disable it.
var popOnEscape: Bool?
/// Whether the view is vertically homogeneous.
///
/// If the view is vertically homogeneous, it allocates the same height for
/// all pages.
///
/// If it's not, the view may change height when a different page becomes
/// visible.
var vhomogeneous: Bool?
/// The tag of the currently visible page.
var visiblePageTag: String?
/// Emitted when a push shortcut or a gesture is triggered.
///
/// To support the push shortcuts and gestures, the application is expected to
@ -144,27 +88,27 @@ public struct NavigationView: AdwaitaWidget {
/// not make any irreversible changes in the handler, such as removing the page
/// from a forward stack.
///
/// Instead, it should be done in the [signal@NavigationView::pushed] handler.
/// Instead, it should be done in the `NavigationView::pushed` handler.
var getNextPage: (() -> Void)?
/// Emitted after @page has been popped from the navigation stack.
///
/// See [method@NavigationView.pop].
/// See `NavigationView.pop`.
///
/// When using [method@NavigationView.pop_to_page] or
/// [method@NavigationView.pop_to_tag], this signal is emitted for each of the
/// When using `NavigationView.pop_to_page` or
/// `NavigationView.pop_to_tag`, this signal is emitted for each of the
/// popped pages.
var popped: (() -> Void)?
/// Emitted after a page has been pushed to the navigation stack.
///
/// See [method@NavigationView.push].
/// See `NavigationView.push`.
var pushed: (() -> Void)?
/// Emitted after the navigation stack has been replaced.
///
/// See [method@NavigationView.replace].
/// See `NavigationView.replace`.
var replaced: (() -> Void)?
/// Initialize `NavigationView`.
public init() {
init() {
}
/// The view storage.
@ -177,7 +121,6 @@ public struct NavigationView: AdwaitaWidget {
for function in appearFunctions {
function(storage, data)
}
update(storage, data: data, updateProperties: true, type: type)
return storage
}
@ -214,9 +157,16 @@ public struct NavigationView: AdwaitaWidget {
if let animateTransitions, updateProperties, (storage.previousState as? Self)?.animateTransitions != animateTransitions {
adw_navigation_view_set_animate_transitions(widget, animateTransitions.cBool)
}
if let hhomogeneous, updateProperties, (storage.previousState as? Self)?.hhomogeneous != hhomogeneous {
adw_navigation_view_set_hhomogeneous(widget, hhomogeneous.cBool)
}
if let popOnEscape, updateProperties, (storage.previousState as? Self)?.popOnEscape != popOnEscape {
adw_navigation_view_set_pop_on_escape(widget, popOnEscape.cBool)
}
if let vhomogeneous, updateProperties, (storage.previousState as? Self)?.vhomogeneous != vhomogeneous {
adw_navigation_view_set_vhomogeneous(widget, vhomogeneous.cBool)
}
}
@ -232,10 +182,18 @@ public struct NavigationView: AdwaitaWidget {
///
/// Gesture-based transitions are always animated.
public func animateTransitions(_ animateTransitions: Bool? = true) -> Self {
var newSelf = self
newSelf.animateTransitions = animateTransitions
return newSelf
modify { $0.animateTransitions = animateTransitions }
}
/// Whether the view is horizontally homogeneous.
///
/// If the view is horizontally homogeneous, it allocates the same width for
/// all pages.
///
/// If it's not, the page may change width when a different page becomes
/// visible.
public func hhomogeneous(_ hhomogeneous: Bool? = true) -> Self {
modify { $0.hhomogeneous = hhomogeneous }
}
/// Whether pressing Escape pops the current page.
@ -243,10 +201,23 @@ public struct NavigationView: AdwaitaWidget {
/// Applications using `AdwNavigationView` to implement a browser may want to
/// disable it.
public func popOnEscape(_ popOnEscape: Bool? = true) -> Self {
var newSelf = self
newSelf.popOnEscape = popOnEscape
return newSelf
modify { $0.popOnEscape = popOnEscape }
}
/// Whether the view is vertically homogeneous.
///
/// If the view is vertically homogeneous, it allocates the same height for
/// all pages.
///
/// If it's not, the view may change height when a different page becomes
/// visible.
public func vhomogeneous(_ vhomogeneous: Bool? = true) -> Self {
modify { $0.vhomogeneous = vhomogeneous }
}
/// The tag of the currently visible page.
public func visiblePageTag(_ visiblePageTag: String?) -> Self {
modify { $0.visiblePageTag = visiblePageTag }
}
/// Emitted when a push shortcut or a gesture is triggered.
@ -259,7 +230,7 @@ public struct NavigationView: AdwaitaWidget {
/// not make any irreversible changes in the handler, such as removing the page
/// from a forward stack.
///
/// Instead, it should be done in the [signal@NavigationView::pushed] handler.
/// Instead, it should be done in the `NavigationView::pushed` handler.
public func getNextPage(_ getNextPage: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.getNextPage = getNextPage
@ -268,10 +239,10 @@ public struct NavigationView: AdwaitaWidget {
/// Emitted after @page has been popped from the navigation stack.
///
/// See [method@NavigationView.pop].
/// See `NavigationView.pop`.
///
/// When using [method@NavigationView.pop_to_page] or
/// [method@NavigationView.pop_to_tag], this signal is emitted for each of the
/// When using `NavigationView.pop_to_page` or
/// `NavigationView.pop_to_tag`, this signal is emitted for each of the
/// popped pages.
public func popped(_ popped: @escaping () -> Void) -> Self {
var newSelf = self
@ -281,7 +252,7 @@ public struct NavigationView: AdwaitaWidget {
/// Emitted after a page has been pushed to the navigation stack.
///
/// See [method@NavigationView.push].
/// See `NavigationView.push`.
public func pushed(_ pushed: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.pushed = pushed
@ -290,7 +261,7 @@ public struct NavigationView: AdwaitaWidget {
/// Emitted after the navigation stack has been replaced.
///
/// See [method@NavigationView.replace].
/// See `NavigationView.replace`.
public func replaced(_ replaced: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.replaced = replaced

View File

@ -2,19 +2,18 @@
// Overlay.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// `GtkOverlay` is a container which contains a single main child, on top
/// of which it can place overlay widgets.
/// Places overlay widgets on top of a single main child.
///
///
/// ![An example GtkOverlay](overlay.png)
///
/// The position of each overlay widget is determined by its
/// [property@Gtk.Widget:halign] and [property@Gtk.Widget:valign]
/// ``halign(_:)`` and ``valign(_:)``
/// properties. E.g. a widget with both alignments set to %GTK_ALIGN_START
/// will be placed at the top left corner of the `GtkOverlay` container,
/// whereas an overlay with halign set to %GTK_ALIGN_CENTER and valign set
@ -23,36 +22,33 @@ import LevenshteinTransformations
/// properties of the child to non-zero values.
///
/// More complicated placement of overlays is possible by connecting
/// to the [signal@Gtk.Overlay::get-child-position] signal.
/// to the `Gtk.Overlay::get-child-position` signal.
///
/// An overlays minimum and natural sizes are those of its main child.
/// The sizes of overlay children are not considered when measuring these
/// preferred sizes.
///
/// # GtkOverlay as GtkBuildable
///
/// The `GtkOverlay` implementation of the `GtkBuildable` interface
/// supports placing a child as an overlay by specifying overlay as
/// the type attribute of a `<child>` element.
///
/// # CSS nodes
///
/// `GtkOverlay` has a single CSS node with the name overlay. Overlay children
/// whose alignments cause them to be positioned at an edge get the style classes
/// .left, .right, .top, and/or .bottom according to their position.
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.
///
/// The accessible role cannot be changed once set.
var accessibleRole: String?
/// The main child widget.
var child: (() -> Body)?
var child: Body?
/// Emitted to determine the position and size of any overlay
/// child widgets.
///
@ -85,8 +81,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) {
if let childStorage = child?.storage(data: data, type: type) {
storage.content["child"] = [childStorage]
gtk_overlay_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())
}
@ -115,7 +110,7 @@ public struct Overlay: AdwaitaWidget {
storage.modify { widget in
if let widget = storage.content["child"]?.first {
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
child?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
if let overlayStorage = storage.content["overlay"] {
@ -131,6 +126,7 @@ public struct Overlay: AdwaitaWidget {
}
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -144,18 +140,12 @@ public struct Overlay: AdwaitaWidget {
///
/// The accessible role cannot be changed once set.
public func accessibleRole(_ accessibleRole: String?) -> Self {
var newSelf = self
newSelf.accessibleRole = accessibleRole
return newSelf
modify { $0.accessibleRole = accessibleRole }
}
/// The main child widget.
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.child = child
return newSelf
public func child(@ViewBuilder _ child: () -> Body) -> Self {
modify { $0.child = child() }
}
/// Emitted to determine the position and size of any overlay

View File

@ -2,7 +2,7 @@
// OverlaySplitView.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
@ -10,115 +10,57 @@ import LevenshteinTransformations
/// A widget presenting sidebar and content side by side or as an overlay.
///
/// <picture><source srcset="overlay-split-view-dark.png" media="(prefers-color-scheme: dark)"><img src="overlay-split-view.png" alt="overlay-split-view"></picture><picture><source srcset="overlay-split-view-collapsed-dark.png" media="(prefers-color-scheme: dark)"><img src="overlay-split-view-collapsed.png" alt="overlay-split-view-collapsed"></picture>
///
///
/// `AdwOverlaySplitView` has two children: sidebar and content, and displays
/// them side by side.
///
/// When [property@OverlaySplitView:collapsed] is set to `TRUE`, the sidebar is
/// When ``collapsed(_:)`` is set to `true`, the sidebar is
/// instead shown as an overlay above the content widget.
///
/// The sidebar can be hidden or shown using the
/// [property@OverlaySplitView:show-sidebar] property.
/// ``showSidebar(_:)`` property.
///
/// Sidebar can be displayed before or after the content, this can be controlled
/// with the [property@OverlaySplitView:sidebar-position] property.
/// with the ``sidebarPosition(_:)`` property.
///
/// Collapsing the split view automatically hides the sidebar widget, and
/// uncollapsing it shows the sidebar. If this behavior is not desired, the
/// [property@OverlaySplitView:pin-sidebar] property can be used to override it.
/// ``pinSidebar(_:)`` property can be used to override it.
///
/// `AdwOverlaySplitView` supports an edge swipe gesture for showing the sidebar,
/// and a swipe from the sidebar for hiding it. Gestures are only supported on
/// touchscreen, but not touchpad. Gestures can be controlled with the
/// [property@OverlaySplitView:enable-show-gesture] and
/// [property@OverlaySplitView:enable-hide-gesture] properties.
/// ``enableShowGesture(_:)`` and
/// ``enableHideGesture(_:)`` properties.
///
/// See also [class@NavigationSplitView].
/// See also `NavigationSplitView`.
///
/// `AdwOverlaySplitView` is typically used together with an [class@Breakpoint]
/// setting the `collapsed` property to `TRUE` on small widths, as follows:
/// `AdwOverlaySplitView` is typically used together with an `Breakpoint`
/// setting the `collapsed` property to `true` on small widths, as follows:
///
/// ```xml
/// <object class="AdwWindow"><property name="width-request">360</property><property name="height-request">200</property><property name="default-width">800</property><property name="default-height">800</property><child><object class="AdwBreakpoint"><condition>max-width: 400sp</condition><setter object="split_view" property="collapsed">True</setter></object></child><property name="content"><object class="AdwOverlaySplitView" id="split_view"><property name="sidebar"><!-- ... --></property><property name="content"><!-- ... --></property></object></property></object>
/// <object class="AdwWindow"><property name="default-width">800</property><property name="default-height">800</property><child><object class="AdwBreakpoint"><condition>max-width: 400sp</condition><setter object="split_view" property="collapsed">True</setter></object></child><property name="content"><object class="AdwOverlaySplitView" id="split_view"><property name="sidebar"><!-- ... --></property><property name="content"><!-- ... --></property></object></property></object>
/// ```
///
/// `AdwOverlaySplitView` is often used for implementing the
/// [utility pane](https://developer.gnome.org/hig/patterns/containers/utility-panes.html)
/// pattern.
///
/// ## Sizing
///
/// When not collapsed, `AdwOverlaySplitView` changes the sidebar width
/// depending on its own width.
///
/// If possible, it tries to allocate a fraction of the total width, controlled
/// with the [property@OverlaySplitView:sidebar-width-fraction] property.
///
/// The sidebar also has minimum and maximum sizes, controlled with the
/// [property@OverlaySplitView:min-sidebar-width] and
/// [property@OverlaySplitView:max-sidebar-width] properties.
///
/// The minimum and maximum sizes are using the length unit specified with the
/// [property@OverlaySplitView:sidebar-width-unit].
///
/// By default, sidebar is using 25% of the total width, with 180sp as the
/// minimum size and 280sp as the maximum size.
///
/// When collapsed, the preferred width fraction is ignored and the sidebar uses
/// [property@OverlaySplitView:max-sidebar-width] when possible.
///
/// ## Header Bar Integration
///
/// When used inside `AdwOverlaySplitView`, [class@HeaderBar] will automatically
/// hide the window buttons in the middle.
///
/// ## `AdwOverlaySplitView` as `GtkBuildable`
///
/// The `AdwOverlaySplitView` implementation of the [iface@Gtk.Buildable]
/// interface supports setting the sidebar widget by specifying sidebar as the
/// type attribute of a `<child>` element, Specifying content child type or
/// omitting it results in setting the content widget.
///
/// ## CSS nodes
///
/// `AdwOverlaySplitView` has a single CSS node with the name
/// `overlay-split-view`.
///
/// It contains two nodes with the name `widget`, containing the sidebar and
/// content children.
///
/// When not collapsed, they have the `.sidebar-view` and `.content-view` style
/// classes respectively.
///
/// ```
/// overlay-split-view
/// widget.sidebar-pane
/// [sidebar child]
/// widget.content-pane
/// [content child]
/// ```
///
/// When collapsed, the one containing the sidebar child has the `.background`
/// style class and the other one has no style classes.
///
/// ```
/// overlay-split-view
/// widget.background
/// [sidebar child]
/// widget
/// [content child]
/// ```
///
/// ## Accessibility
///
/// `AdwOverlaySplitView` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
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.
///
@ -126,7 +68,7 @@ public struct OverlaySplitView: AdwaitaWidget {
/// content widget, otherwise they are displayed side by side.
var collapsed: Bool?
/// The content widget.
var content: (() -> Body)?
var content: Body?
/// Whether the sidebar can be closed with a swipe gesture.
///
/// Only touchscreen swipes are supported.
@ -138,7 +80,7 @@ public struct OverlaySplitView: AdwaitaWidget {
/// The maximum sidebar width.
///
/// Maximum width is affected by
/// [property@OverlaySplitView:sidebar-width-unit].
/// ``sidebarWidthUnit(_:)``.
///
/// The sidebar widget can still be allocated with larger width if its own
/// minimum width exceeds it.
@ -146,7 +88,7 @@ public struct OverlaySplitView: AdwaitaWidget {
/// The minimum sidebar width.
///
/// Minimum width is affected by
/// [property@OverlaySplitView:sidebar-width-unit].
/// ``sidebarWidthUnit(_:)``.
///
/// The sidebar widget can still be allocated with larger width if its own
/// minimum width exceeds it.
@ -154,25 +96,25 @@ public struct OverlaySplitView: AdwaitaWidget {
/// Whether the sidebar widget is pinned.
///
/// By default, collapsing @self automatically hides the sidebar widget, and
/// uncollapsing it shows the sidebar. If set to `TRUE`, sidebar visibility
/// uncollapsing it shows the sidebar. If set to `true`, sidebar visibility
/// never changes on its own.
var pinSidebar: Bool?
/// Whether the sidebar widget is shown.
var showSidebar: Binding<Bool>?
/// The sidebar widget.
var sidebar: (() -> Body)?
var sidebar: Body?
/// The preferred sidebar width as a fraction of the total width.
///
/// The preferred width is additionally limited by
/// [property@OverlaySplitView:min-sidebar-width] and
/// [property@OverlaySplitView:max-sidebar-width].
/// ``minSidebarWidth(_:)`` and
/// ``maxSidebarWidth(_:)``.
///
/// The sidebar widget can be allocated with larger width if its own minimum
/// width exceeds the preferred width.
var sidebarWidthFraction: Double?
/// Initialize `OverlaySplitView`.
public init() {
init() {
}
/// The view storage.
@ -185,12 +127,11 @@ 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) {
if let contentStorage = content?.storage(data: data, type: type) {
storage.content["content"] = [contentStorage]
adw_overlay_split_view_set_content(storage.opaquePointer, contentStorage.opaquePointer?.cast())
}
if let sidebarStorage = sidebar?().storage(data: data, type: type) {
if let sidebarStorage = sidebar?.storage(data: data, type: type) {
storage.content["sidebar"] = [sidebarStorage]
adw_overlay_split_view_set_sidebar(storage.opaquePointer, sidebarStorage.opaquePointer?.cast())
}
@ -217,7 +158,7 @@ if let showSidebar, newValue != showSidebar.wrappedValue {
adw_overlay_split_view_set_collapsed(widget, collapsed.cBool)
}
if let widget = storage.content["content"]?.first {
content?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
content?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
if let enableHideGesture, updateProperties, (storage.previousState as? Self)?.enableHideGesture != enableHideGesture {
adw_overlay_split_view_set_enable_hide_gesture(widget, enableHideGesture.cBool)
@ -238,13 +179,14 @@ if let showSidebar, newValue != showSidebar.wrappedValue {
adw_overlay_split_view_set_show_sidebar(storage.opaquePointer, showSidebar.wrappedValue.cBool)
}
if let widget = storage.content["sidebar"]?.first {
sidebar?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
sidebar?.updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
}
if let sidebarWidthFraction, updateProperties, (storage.previousState as? Self)?.sidebarWidthFraction != sidebarWidthFraction {
adw_overlay_split_view_set_sidebar_width_fraction(widget, sidebarWidthFraction)
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -259,109 +201,79 @@ if let showSidebar, newValue != showSidebar.wrappedValue {
/// When collapsed, the sidebar widget is presented as an overlay above the
/// content widget, otherwise they are displayed side by side.
public func collapsed(_ collapsed: Bool? = true) -> Self {
var newSelf = self
newSelf.collapsed = collapsed
return newSelf
modify { $0.collapsed = collapsed }
}
/// The content widget.
public func content(@ViewBuilder _ content: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.content = content
return newSelf
public func content(@ViewBuilder _ content: () -> Body) -> Self {
modify { $0.content = content() }
}
/// Whether the sidebar can be closed with a swipe gesture.
///
/// Only touchscreen swipes are supported.
public func enableHideGesture(_ enableHideGesture: Bool? = true) -> Self {
var newSelf = self
newSelf.enableHideGesture = enableHideGesture
return newSelf
modify { $0.enableHideGesture = enableHideGesture }
}
/// Whether the sidebar can be opened with an edge swipe gesture.
///
/// Only touchscreen swipes are supported.
public func enableShowGesture(_ enableShowGesture: Bool? = true) -> Self {
var newSelf = self
newSelf.enableShowGesture = enableShowGesture
return newSelf
modify { $0.enableShowGesture = enableShowGesture }
}
/// The maximum sidebar width.
///
/// Maximum width is affected by
/// [property@OverlaySplitView:sidebar-width-unit].
/// ``sidebarWidthUnit(_:)``.
///
/// The sidebar widget can still be allocated with larger width if its own
/// minimum width exceeds it.
public func maxSidebarWidth(_ maxSidebarWidth: Double?) -> Self {
var newSelf = self
newSelf.maxSidebarWidth = maxSidebarWidth
return newSelf
modify { $0.maxSidebarWidth = maxSidebarWidth }
}
/// The minimum sidebar width.
///
/// Minimum width is affected by
/// [property@OverlaySplitView:sidebar-width-unit].
/// ``sidebarWidthUnit(_:)``.
///
/// The sidebar widget can still be allocated with larger width if its own
/// minimum width exceeds it.
public func minSidebarWidth(_ minSidebarWidth: Double?) -> Self {
var newSelf = self
newSelf.minSidebarWidth = minSidebarWidth
return newSelf
modify { $0.minSidebarWidth = minSidebarWidth }
}
/// Whether the sidebar widget is pinned.
///
/// By default, collapsing @self automatically hides the sidebar widget, and
/// uncollapsing it shows the sidebar. If set to `TRUE`, sidebar visibility
/// uncollapsing it shows the sidebar. If set to `true`, sidebar visibility
/// never changes on its own.
public func pinSidebar(_ pinSidebar: Bool? = true) -> Self {
var newSelf = self
newSelf.pinSidebar = pinSidebar
return newSelf
modify { $0.pinSidebar = pinSidebar }
}
/// Whether the sidebar widget is shown.
public func showSidebar(_ showSidebar: Binding<Bool>?) -> Self {
var newSelf = self
newSelf.showSidebar = showSidebar
return newSelf
modify { $0.showSidebar = showSidebar }
}
/// The sidebar widget.
public func sidebar(@ViewBuilder _ sidebar: @escaping (() -> Body)) -> Self {
var newSelf = self
newSelf.sidebar = sidebar
return newSelf
public func sidebar(@ViewBuilder _ sidebar: () -> Body) -> Self {
modify { $0.sidebar = sidebar() }
}
/// The preferred sidebar width as a fraction of the total width.
///
/// The preferred width is additionally limited by
/// [property@OverlaySplitView:min-sidebar-width] and
/// [property@OverlaySplitView:max-sidebar-width].
/// ``minSidebarWidth(_:)`` and
/// ``maxSidebarWidth(_:)``.
///
/// The sidebar widget can be allocated with larger width if its own minimum
/// width exceeds the preferred width.
public func sidebarWidthFraction(_ sidebarWidthFraction: Double?) -> Self {
var newSelf = self
newSelf.sidebarWidthFraction = sidebarWidthFraction
return newSelf
modify { $0.sidebarWidthFraction = sidebarWidthFraction }
}
}

View File

@ -2,15 +2,15 @@
// PasswordEntryRow.swift
// Adwaita
//
// Created by auto-generation on 15.08.24.
// Created by auto-generation on 04.02.26.
//
import CAdw
import LevenshteinTransformations
/// A [class@EntryRow] tailored for entering secrets.
/// A `EntryRow` tailored for entering secrets.
///
///
/// <picture><source srcset="password-entry-row-dark.png" media="(prefers-color-scheme: dark)"><img src="password-entry-row.png" alt="password-entry-row"></picture>
///
/// It does not show its contents in clear text, does not allow to copy it to the
/// clipboard, and shows a warning when Caps Lock is engaged. If the underlying
@ -20,16 +20,20 @@ import LevenshteinTransformations
///
/// It offer a way to reveal the contents in clear text.
///
/// ## CSS Nodes
///
/// `AdwPasswordEntryRow` has a single CSS node with name `row` that carries
/// `.entry` and `.password` style classes.
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?
@ -37,11 +41,13 @@ public struct PasswordEntryRow: AdwaitaWidget {
///
/// Emoji replacement is done with :-delimited names, like `:heart:`.
var enableEmojiCompletion: Bool?
/// Maximum number of characters for the entry.
var maxLength: Int?
/// Whether to show the apply button.
///
/// When set to `TRUE`, typing text in the entry will reveal an apply button.
/// When set to `true`, typing text in the entry will reveal an apply button.
/// Clicking it or pressing the <kbd>Enter</kbd> key will hide the button and
/// emit the [signal@EntryRow::apply] signal.
/// emit the `EntryRow::apply` signal.
///
/// This is useful if changing the entry contents can trigger an expensive
/// operation, e.g. network activity, to avoid triggering it after typing every
@ -52,23 +58,23 @@ public struct PasswordEntryRow: AdwaitaWidget {
/// The title of the preference represented by this row.
///
/// The title is interpreted as Pango markup unless
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
/// ``useMarkup(_:)`` is set to `false`.
var title: String?
/// Whether the user can copy the title from the label.
///
/// See also [property@Gtk.Label:selectable].
/// See also ``selectable(_:)``.
var titleSelectable: Bool?
/// Whether to use Pango markup for the title label.
///
/// Subclasses may also use it for other labels, such as subtitle.
///
/// See also [func@Pango.parse_markup].
/// See also `Pango.parse_markup`.
var useMarkup: Bool?
/// Whether an embedded underline in the title indicates a mnemonic.
var useUnderline: Bool?
/// Emitted when the apply button is pressed.
///
/// See [property@EntryRow:show-apply-button].
/// See ``showApplyButton(_:)``.
var apply: (() -> Void)?
/// Emitted when the embedded entry is activated.
var entryActivated: (() -> Void)?
@ -78,7 +84,7 @@ public struct PasswordEntryRow: AdwaitaWidget {
var prefix: () -> Body = { [] }
/// Initialize `PasswordEntryRow`.
public init() {
init() {
}
/// The view storage.
@ -91,7 +97,6 @@ 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() {
@ -133,6 +138,9 @@ public struct PasswordEntryRow: AdwaitaWidget {
if let enableEmojiCompletion, updateProperties, (storage.previousState as? Self)?.enableEmojiCompletion != enableEmojiCompletion {
adw_entry_row_set_enable_emoji_completion(widget?.cast(), enableEmojiCompletion.cBool)
}
if let maxLength, updateProperties, (storage.previousState as? Self)?.maxLength != maxLength {
adw_entry_row_set_max_length(widget?.cast(), maxLength.cInt)
}
if let showApplyButton, updateProperties, (storage.previousState as? Self)?.showApplyButton != showApplyButton {
adw_entry_row_set_show_apply_button(widget?.cast(), showApplyButton.cBool)
}
@ -150,6 +158,7 @@ public struct PasswordEntryRow: AdwaitaWidget {
}
}
for function in updateFunctions {
function(storage, data, updateProperties)
@ -161,90 +170,71 @@ public struct PasswordEntryRow: AdwaitaWidget {
/// Whether activating the embedded entry can activate the default widget.
public func activatesDefault(_ activatesDefault: Bool? = true) -> Self {
var newSelf = self
newSelf.activatesDefault = activatesDefault
return newSelf
modify { $0.activatesDefault = activatesDefault }
}
/// Whether to suggest emoji replacements on the entry row.
///
/// Emoji replacement is done with :-delimited names, like `:heart:`.
public func enableEmojiCompletion(_ enableEmojiCompletion: Bool? = true) -> Self {
var newSelf = self
newSelf.enableEmojiCompletion = enableEmojiCompletion
return newSelf
modify { $0.enableEmojiCompletion = enableEmojiCompletion }
}
/// Maximum number of characters for the entry.
public func maxLength(_ maxLength: Int?) -> Self {
modify { $0.maxLength = maxLength }
}
/// Whether to show the apply button.
///
/// When set to `TRUE`, typing text in the entry will reveal an apply button.
/// When set to `true`, typing text in the entry will reveal an apply button.
/// Clicking it or pressing the <kbd>Enter</kbd> key will hide the button and
/// emit the [signal@EntryRow::apply] signal.
/// emit the `EntryRow::apply` signal.
///
/// This is useful if changing the entry contents can trigger an expensive
/// operation, e.g. network activity, to avoid triggering it after typing every
/// character.
public func showApplyButton(_ showApplyButton: Bool? = true) -> Self {
var newSelf = self
newSelf.showApplyButton = showApplyButton
return newSelf
modify { $0.showApplyButton = showApplyButton }
}
/// The length of the text in the entry row.
public func textLength(_ textLength: UInt?) -> Self {
var newSelf = self
newSelf.textLength = textLength
return newSelf
modify { $0.textLength = textLength }
}
/// The title of the preference represented by this row.
///
/// The title is interpreted as Pango markup unless
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
/// ``useMarkup(_:)`` is set to `false`.
public func title(_ title: String?) -> Self {
var newSelf = self
newSelf.title = title
return newSelf
modify { $0.title = title }
}
/// Whether the user can copy the title from the label.
///
/// See also [property@Gtk.Label:selectable].
/// See also ``selectable(_:)``.
public func titleSelectable(_ titleSelectable: Bool? = true) -> Self {
var newSelf = self
newSelf.titleSelectable = titleSelectable
return newSelf
modify { $0.titleSelectable = titleSelectable }
}
/// Whether to use Pango markup for the title label.
///
/// Subclasses may also use it for other labels, such as subtitle.
///
/// See also [func@Pango.parse_markup].
/// See also `Pango.parse_markup`.
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
var newSelf = self
newSelf.useMarkup = useMarkup
return newSelf
modify { $0.useMarkup = useMarkup }
}
/// Whether an embedded underline in the title indicates a mnemonic.
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
var newSelf = self
newSelf.useUnderline = useUnderline
return newSelf
modify { $0.useUnderline = useUnderline }
}
/// Emitted when the apply button is pressed.
///
/// See [property@EntryRow:show-apply-button].
/// See ``showApplyButton(_:)``.
public func apply(_ apply: @escaping () -> Void) -> Self {
var newSelf = self
newSelf.apply = apply

Some files were not shown because too many files have changed in this diff Show More