Separate AnyView extensions from widgets
This commit is contained in:
parent
079fa02755
commit
8eeda083e9
@ -154,6 +154,5 @@ type_contents_order:
|
|||||||
- other_method
|
- other_method
|
||||||
|
|
||||||
excluded:
|
excluded:
|
||||||
- Sources/Adwaita/View/Generated/
|
- Sources/Core/View/Generated/
|
||||||
- Sources/Adwaita/Adwaita.docc/
|
|
||||||
- .build/
|
- .build/
|
@ -17,6 +17,10 @@ let package = Package(
|
|||||||
name: "Adwaita",
|
name: "Adwaita",
|
||||||
targets: ["Adwaita"]
|
targets: ["Adwaita"]
|
||||||
),
|
),
|
||||||
|
.library(
|
||||||
|
name: "Core",
|
||||||
|
targets: ["Core"]
|
||||||
|
),
|
||||||
.library(
|
.library(
|
||||||
name: "CAdw",
|
name: "CAdw",
|
||||||
targets: ["CAdw"]
|
targets: ["CAdw"]
|
||||||
@ -37,7 +41,7 @@ let package = Package(
|
|||||||
pkgConfig: "libadwaita-1"
|
pkgConfig: "libadwaita-1"
|
||||||
),
|
),
|
||||||
.target(
|
.target(
|
||||||
name: "Adwaita",
|
name: "Core",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
"CAdw",
|
"CAdw",
|
||||||
.product(name: "LevenshteinTransformations", package: "levenshtein-transformations"),
|
.product(name: "LevenshteinTransformations", package: "levenshtein-transformations"),
|
||||||
@ -45,6 +49,10 @@ let package = Package(
|
|||||||
.product(name: "MetaSQLite", package: "meta-sqlite")
|
.product(name: "MetaSQLite", package: "meta-sqlite")
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
.target(
|
||||||
|
name: "Adwaita",
|
||||||
|
dependencies: ["Core"]
|
||||||
|
),
|
||||||
.executableTarget(
|
.executableTarget(
|
||||||
name: "Generation",
|
name: "Generation",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
|
17
Sources/Adwaita/ActionRow+.swift
Normal file
17
Sources/Adwaita/ActionRow+.swift
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
//
|
//
|
||||||
// AnyView+.swift
|
// AnyView++.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by david-swift on 01.08.24.
|
// Created by david-swift on 16.10.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
270
Sources/Adwaita/AnyView+.swift
Normal file
270
Sources/Adwaita/AnyView+.swift
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
//
|
||||||
|
// AnyView+.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 16.10.24.
|
||||||
|
//
|
||||||
|
|
||||||
|
@_exported import Core
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension AnyView {
|
||||||
|
|
||||||
|
/// Add an about dialog to the parent window.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - visible: Whether the dialog is presented.
|
||||||
|
/// - app: The app's name.
|
||||||
|
/// - developer: The developer's name.
|
||||||
|
/// - version: The version string.
|
||||||
|
/// - icon: The app icon.
|
||||||
|
/// - website: The app's website.
|
||||||
|
/// - issues: Website for reporting issues.
|
||||||
|
public func aboutDialog(
|
||||||
|
visible: Binding<Bool>,
|
||||||
|
app: String? = nil,
|
||||||
|
developer: String? = nil,
|
||||||
|
version: String? = nil,
|
||||||
|
icon: Icon? = nil,
|
||||||
|
website: URL? = nil,
|
||||||
|
issues: URL? = nil
|
||||||
|
) -> AnyView {
|
||||||
|
AboutDialog(
|
||||||
|
visible: visible,
|
||||||
|
child: self,
|
||||||
|
appName: app,
|
||||||
|
developer: developer,
|
||||||
|
version: version,
|
||||||
|
icon: icon,
|
||||||
|
website: website,
|
||||||
|
issues: issues
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add an alert dialog to the parent window.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - visible: Whether the dialog is presented.
|
||||||
|
/// - heading: The heading.
|
||||||
|
/// - body: The body text.
|
||||||
|
public func alertDialog(
|
||||||
|
visible: Binding<Bool>,
|
||||||
|
heading: String,
|
||||||
|
body: String = "",
|
||||||
|
id: String? = nil
|
||||||
|
) -> AlertDialog {
|
||||||
|
.init(
|
||||||
|
visible: visible,
|
||||||
|
child: self,
|
||||||
|
id: id ?? "no-id",
|
||||||
|
heading: heading,
|
||||||
|
body: body
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a dialog to the parent window.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - visible: Whether the dialog is presented.
|
||||||
|
/// - title: The dialog's title.
|
||||||
|
/// - width: The dialog's width.
|
||||||
|
/// - height: The dialog's height.
|
||||||
|
/// - content: The dialog's content.
|
||||||
|
public func dialog(
|
||||||
|
visible: Binding<Bool>,
|
||||||
|
title: String? = nil,
|
||||||
|
id: String? = nil,
|
||||||
|
width: Int? = nil,
|
||||||
|
height: Int? = nil,
|
||||||
|
@ViewBuilder content: () -> Body
|
||||||
|
) -> AnyView {
|
||||||
|
Dialog(
|
||||||
|
visible: visible,
|
||||||
|
child: self,
|
||||||
|
id: id ?? "",
|
||||||
|
content: content(),
|
||||||
|
title: title,
|
||||||
|
width: width,
|
||||||
|
height: height
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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(
|
||||||
|
open: Signal,
|
||||||
|
initialFolder: URL? = nil,
|
||||||
|
extensions: [String]? = nil,
|
||||||
|
onOpen: @escaping (URL) -> Void,
|
||||||
|
onClose: @escaping () -> Void
|
||||||
|
) -> AnyView {
|
||||||
|
FileDialog(
|
||||||
|
importer: true,
|
||||||
|
open: open,
|
||||||
|
child: self,
|
||||||
|
result: onOpen,
|
||||||
|
cancel: onClose,
|
||||||
|
initialFolder: initialFolder,
|
||||||
|
initialName: nil,
|
||||||
|
extensions: extensions
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create an exporter file dialog.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - exporter: The signal to open the dialog.
|
||||||
|
/// - initialFolder: The URL to the folder open when being opened.
|
||||||
|
/// - initialName: The default file name.
|
||||||
|
/// - onSave: Run this when a path for exporting has been chosen.
|
||||||
|
/// - onClose: Run this when the user cancelled the action.
|
||||||
|
public func fileExporter(
|
||||||
|
open: Signal,
|
||||||
|
initialFolder: URL? = nil,
|
||||||
|
initialName: String? = nil,
|
||||||
|
onSave: @escaping (URL) -> Void,
|
||||||
|
onClose: @escaping () -> Void
|
||||||
|
) -> AnyView {
|
||||||
|
FileDialog(
|
||||||
|
importer: false,
|
||||||
|
open: open,
|
||||||
|
child: self,
|
||||||
|
result: onSave,
|
||||||
|
cancel: onClose,
|
||||||
|
initialFolder: initialFolder,
|
||||||
|
initialName: initialName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a popover on top of the view.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - visible: Whether the popover is displayed.
|
||||||
|
/// - content: The popover's content.
|
||||||
|
/// - Returns: The view.
|
||||||
|
public func popover(visible: Binding<Bool>, @ViewBuilder content: @escaping () -> Body) -> Overlay {
|
||||||
|
overlay {
|
||||||
|
Popover(visible: visible)
|
||||||
|
.child(content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the view's maximum width.
|
||||||
|
/// - Parameter maxWidth: The maximum width.
|
||||||
|
/// - Returns: A view.
|
||||||
|
public func frame(maxWidth: Int? = nil) -> Clamp {
|
||||||
|
.init()
|
||||||
|
.child { self }
|
||||||
|
.maximumSize(maxWidth ?? -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the view's maximum height.
|
||||||
|
/// - Parameter maxHeight: The maximum height.
|
||||||
|
/// - Returns: A view.
|
||||||
|
public func frame(maxHeight: Int? = nil) -> Clamp {
|
||||||
|
.init(vertical: true)
|
||||||
|
.child { self }
|
||||||
|
.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.
|
||||||
|
/// - signal: The signal which activates the presentation of a toast.
|
||||||
|
/// - Returns: A view.
|
||||||
|
public func toast(_ title: String, signal: Signal) -> ToastOverlay {
|
||||||
|
.init(title, signal: signal)
|
||||||
|
.child { self }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Present a toast with a button when the signal gets activated.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - title: The title of the toast.
|
||||||
|
/// - signal: The signal which activates the presentation of a toast.
|
||||||
|
/// - button: The button's label.
|
||||||
|
/// - handler: The handler for the button.
|
||||||
|
/// - Returns: A view.
|
||||||
|
public func toast(_ title: String, signal: Signal, button: String, handler: @escaping () -> Void) -> ToastOverlay {
|
||||||
|
.init(title, signal: signal)
|
||||||
|
.child { self }
|
||||||
|
.action(button: button, handler: handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
Sources/Adwaita/Box+.swift
Normal file
15
Sources/Adwaita/Box+.swift
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// Box+.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 16.10.24.
|
||||||
|
//
|
||||||
|
|
||||||
|
extension Box {
|
||||||
|
|
||||||
|
/// Link the children.
|
||||||
|
public func linked(_ active: Bool = true) -> AnyView {
|
||||||
|
style("linked", active: active)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
24
Sources/Adwaita/List+.swift
Normal file
24
Sources/Adwaita/List+.swift
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//
|
||||||
|
// List+.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 16.10.24.
|
||||||
|
//
|
||||||
|
|
||||||
|
extension List {
|
||||||
|
|
||||||
|
/// Add the "navigation-sidebar" style class.
|
||||||
|
/// - Parameter active: Whether the style is applied.
|
||||||
|
/// - Returns: A view.
|
||||||
|
public func sidebarStyle(_ active: Bool = true) -> AnyView {
|
||||||
|
style("navigation-sidebar", active: active)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply the boxed list style class.
|
||||||
|
/// - Parameter active: Whether the style is applied.
|
||||||
|
/// - Returns: A view.
|
||||||
|
public func boxedList(_ active: Bool = true) -> AnyView {
|
||||||
|
style("boxed-list", active: active)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
17
Sources/Adwaita/StatusPage+.swift
Normal file
17
Sources/Adwaita/StatusPage+.swift
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,45 +0,0 @@
|
|||||||
//
|
|
||||||
// Clamp+.swift
|
|
||||||
// Adwaita
|
|
||||||
//
|
|
||||||
// Created by david-swift on 20.01.24.
|
|
||||||
//
|
|
||||||
|
|
||||||
import CAdw
|
|
||||||
|
|
||||||
extension Clamp {
|
|
||||||
|
|
||||||
/// Initialize either a horizontal or vertical clamp.
|
|
||||||
/// - Parameter vertical: Whether it is a vertical clamp.
|
|
||||||
init(vertical: Bool) {
|
|
||||||
self.init()
|
|
||||||
if vertical {
|
|
||||||
appearFunctions.append { storage, _ in
|
|
||||||
gtk_orientable_set_orientation(storage.opaquePointer, GTK_ORIENTATION_VERTICAL)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extension AnyView {
|
|
||||||
|
|
||||||
/// Set the view's maximum width.
|
|
||||||
/// - Parameter maxWidth: The maximum width.
|
|
||||||
/// - Returns: A view.
|
|
||||||
public func frame(maxWidth: Int? = nil) -> Clamp {
|
|
||||||
.init()
|
|
||||||
.child { self }
|
|
||||||
.maximumSize(maxWidth ?? -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the view's maximum height.
|
|
||||||
/// - Parameter maxHeight: The maximum height.
|
|
||||||
/// - Returns: A view.
|
|
||||||
public func frame(maxHeight: Int? = nil) -> Clamp {
|
|
||||||
.init(vertical: true)
|
|
||||||
.child { self }
|
|
||||||
.maximumSize(maxHeight ?? -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -8,9 +8,9 @@
|
|||||||
extension String {
|
extension String {
|
||||||
|
|
||||||
/// A label for the transition data in a widget's fields.
|
/// A label for the transition data in a widget's fields.
|
||||||
static var transition: Self { "transition" }
|
public static var transition: Self { "transition" }
|
||||||
/// A label for the navigation label in a widget's fields.
|
/// A label for the navigation label in a widget's fields.
|
||||||
static var navigationLabel: Self { "navigation-label" }
|
public static var navigationLabel: Self { "navigation-label" }
|
||||||
|
|
||||||
/// Add the Ctrl key to a shortcut.
|
/// Add the Ctrl key to a shortcut.
|
||||||
/// - Returns: The shortcut.
|
/// - Returns: The shortcut.
|
@ -9,7 +9,7 @@ import CAdw
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
/// The about dialog widget.
|
/// The about dialog widget.
|
||||||
struct AboutDialog: AdwaitaWidget {
|
public struct AboutDialog: AdwaitaWidget {
|
||||||
|
|
||||||
/// Whether the dialog is visible.
|
/// Whether the dialog is visible.
|
||||||
@Binding var visible: Bool
|
@Binding var visible: Bool
|
||||||
@ -32,12 +32,42 @@ struct AboutDialog: AdwaitaWidget {
|
|||||||
/// The ID for the dialog's storage.
|
/// The ID for the dialog's storage.
|
||||||
let dialogID = "dialog"
|
let dialogID = "dialog"
|
||||||
|
|
||||||
|
/// Initialize the about dialog wrapper.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - visible: The visibility.
|
||||||
|
/// - child: The child view.
|
||||||
|
/// - appName: The app's name.
|
||||||
|
/// - developer: The developer's name.
|
||||||
|
/// - version: The version.
|
||||||
|
/// - icon: The icon.
|
||||||
|
/// - website: The website's URL.
|
||||||
|
/// - issues: The link for opening issues.
|
||||||
|
public init(
|
||||||
|
visible: Binding<Bool>,
|
||||||
|
child: AnyView,
|
||||||
|
appName: String? = nil,
|
||||||
|
developer: String? = nil,
|
||||||
|
version: String? = nil,
|
||||||
|
icon: Icon? = nil,
|
||||||
|
website: URL? = nil,
|
||||||
|
issues: URL? = nil
|
||||||
|
) {
|
||||||
|
self._visible = visible
|
||||||
|
self.child = child
|
||||||
|
self.appName = appName
|
||||||
|
self.developer = developer
|
||||||
|
self.version = version
|
||||||
|
self.icon = icon
|
||||||
|
self.website = website
|
||||||
|
self.issues = issues
|
||||||
|
}
|
||||||
|
|
||||||
/// The view storage.
|
/// The view storage.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - modifiers: Modify views before being updated.
|
/// - modifiers: Modify views before being updated.
|
||||||
/// - type: The view render data type.
|
/// - type: The view render data type.
|
||||||
/// - Returns: The view storage.
|
/// - Returns: The view storage.
|
||||||
func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||||
let storage = child.storage(data: data, type: type)
|
let storage = child.storage(data: data, type: type)
|
||||||
update(storage, data: data, updateProperties: true, type: type)
|
update(storage, data: data, updateProperties: true, type: type)
|
||||||
return storage
|
return storage
|
||||||
@ -49,7 +79,7 @@ struct AboutDialog: AdwaitaWidget {
|
|||||||
/// - modifiers: Modify views before being updated
|
/// - modifiers: Modify views before being updated
|
||||||
/// - updateProperties: Whether to update the view's properties.
|
/// - updateProperties: Whether to update the view's properties.
|
||||||
/// - type: The view render data type.
|
/// - type: The view render data type.
|
||||||
func update<Data>(
|
public func update<Data>(
|
||||||
_ storage: ViewStorage,
|
_ storage: ViewStorage,
|
||||||
data: WidgetData,
|
data: WidgetData,
|
||||||
updateProperties: Bool,
|
updateProperties: Bool,
|
||||||
@ -110,37 +140,3 @@ struct AboutDialog: AdwaitaWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension AnyView {
|
|
||||||
|
|
||||||
/// Add an about dialog to the parent window.
|
|
||||||
/// - Parameters:
|
|
||||||
/// - visible: Whether the dialog is presented.
|
|
||||||
/// - app: The app's name.
|
|
||||||
/// - developer: The developer's name.
|
|
||||||
/// - version: The version string.
|
|
||||||
/// - icon: The app icon.
|
|
||||||
/// - website: The app's website.
|
|
||||||
/// - issues: Website for reporting issues.
|
|
||||||
public func aboutDialog(
|
|
||||||
visible: Binding<Bool>,
|
|
||||||
app: String? = nil,
|
|
||||||
developer: String? = nil,
|
|
||||||
version: String? = nil,
|
|
||||||
icon: Icon? = nil,
|
|
||||||
website: URL? = nil,
|
|
||||||
issues: URL? = nil
|
|
||||||
) -> AnyView {
|
|
||||||
AboutDialog(
|
|
||||||
visible: visible,
|
|
||||||
child: self,
|
|
||||||
appName: app,
|
|
||||||
developer: developer,
|
|
||||||
version: version,
|
|
||||||
icon: icon,
|
|
||||||
website: website,
|
|
||||||
issues: issues
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -33,6 +33,27 @@ public struct AlertDialog: AdwaitaWidget {
|
|||||||
/// The child view.
|
/// The child view.
|
||||||
var child: AnyView
|
var child: AnyView
|
||||||
|
|
||||||
|
/// Initialize an alert dialog wrapper.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - visible: Whether the dialog is visible.
|
||||||
|
/// - child: The child view.
|
||||||
|
/// - id: A unique identifier for dialogs on the view.
|
||||||
|
/// - heading: The heading.
|
||||||
|
/// - body: The body text.
|
||||||
|
public init(
|
||||||
|
visible: Binding<Bool>,
|
||||||
|
child: AnyView,
|
||||||
|
id: String,
|
||||||
|
heading: String,
|
||||||
|
body: String
|
||||||
|
) {
|
||||||
|
self._visible = visible
|
||||||
|
self.child = child
|
||||||
|
self.id = id
|
||||||
|
self.heading = heading
|
||||||
|
self.body = body
|
||||||
|
}
|
||||||
|
|
||||||
/// Information about a response.
|
/// Information about a response.
|
||||||
struct Response: Identifiable {
|
struct Response: Identifiable {
|
||||||
|
|
||||||
@ -214,30 +235,6 @@ public struct AlertDialog: AdwaitaWidget {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension AnyView {
|
|
||||||
|
|
||||||
/// Add an alert dialog to the parent window.
|
|
||||||
/// - Parameters:
|
|
||||||
/// - visible: Whether the dialog is presented.
|
|
||||||
/// - heading: The heading.
|
|
||||||
/// - body: The body text.
|
|
||||||
public func alertDialog(
|
|
||||||
visible: Binding<Bool>,
|
|
||||||
heading: String,
|
|
||||||
body: String = "",
|
|
||||||
id: String? = nil
|
|
||||||
) -> AlertDialog {
|
|
||||||
.init(
|
|
||||||
visible: visible,
|
|
||||||
id: id ?? "no-id",
|
|
||||||
heading: heading,
|
|
||||||
body: body,
|
|
||||||
child: self
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Run when an alert dialog closes.
|
/// Run when an alert dialog closes.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - ptr: The pointer.
|
/// - ptr: The pointer.
|
@ -8,7 +8,7 @@
|
|||||||
import CAdw
|
import CAdw
|
||||||
|
|
||||||
/// The dialog widget.
|
/// The dialog widget.
|
||||||
struct Dialog: AdwaitaWidget {
|
public struct Dialog: AdwaitaWidget {
|
||||||
|
|
||||||
/// Whether the dialog is visible.
|
/// Whether the dialog is visible.
|
||||||
@Binding var visible: Bool
|
@Binding var visible: Bool
|
||||||
@ -30,12 +30,39 @@ struct Dialog: AdwaitaWidget {
|
|||||||
/// The ID for the content's storage.
|
/// The ID for the content's storage.
|
||||||
let contentID = "content"
|
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.
|
||||||
|
/// - content: The content.
|
||||||
|
/// - title: The title.
|
||||||
|
/// - width: The width.
|
||||||
|
/// - height: The height.
|
||||||
|
public init(
|
||||||
|
visible: Binding<Bool>,
|
||||||
|
child: AnyView,
|
||||||
|
id: String,
|
||||||
|
content: Body,
|
||||||
|
title: String? = nil,
|
||||||
|
width: Int? = nil,
|
||||||
|
height: Int? = nil
|
||||||
|
) {
|
||||||
|
self._visible = visible
|
||||||
|
self.child = child
|
||||||
|
self.id = id
|
||||||
|
self.content = content
|
||||||
|
self.title = title
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
}
|
||||||
|
|
||||||
/// The view storage.
|
/// The view storage.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - modifiers: Modify views before being updated.
|
/// - modifiers: Modify views before being updated.
|
||||||
/// - type: The view render data type.
|
/// - type: The view render data type.
|
||||||
/// - Returns: The view storage.
|
/// - Returns: The view storage.
|
||||||
func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||||
let child = child.storage(data: data, type: type)
|
let child = child.storage(data: data, type: type)
|
||||||
let storage = ViewStorage(child.opaquePointer, content: [.mainContent: [child]])
|
let storage = ViewStorage(child.opaquePointer, content: [.mainContent: [child]])
|
||||||
update(storage, data: data, updateProperties: true, type: type)
|
update(storage, data: data, updateProperties: true, type: type)
|
||||||
@ -48,7 +75,7 @@ struct Dialog: AdwaitaWidget {
|
|||||||
/// - modifiers: Modify views before being updated
|
/// - modifiers: Modify views before being updated
|
||||||
/// - updateProperties: Whether to update the view's properties.
|
/// - updateProperties: Whether to update the view's properties.
|
||||||
/// - type: The view render data type.
|
/// - type: The view render data type.
|
||||||
func update<Data>(
|
public func update<Data>(
|
||||||
_ storage: ViewStorage,
|
_ storage: ViewStorage,
|
||||||
data: WidgetData,
|
data: WidgetData,
|
||||||
updateProperties: Bool,
|
updateProperties: Bool,
|
||||||
@ -115,33 +142,3 @@ struct Dialog: AdwaitaWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension AnyView {
|
|
||||||
|
|
||||||
/// Add a dialog to the parent window.
|
|
||||||
/// - Parameters:
|
|
||||||
/// - visible: Whether the dialog is presented.
|
|
||||||
/// - title: The dialog's title.
|
|
||||||
/// - width: The dialog's width.
|
|
||||||
/// - height: The dialog's height.
|
|
||||||
/// - content: The dialog's content.
|
|
||||||
public func dialog(
|
|
||||||
visible: Binding<Bool>,
|
|
||||||
title: String? = nil,
|
|
||||||
id: String? = nil,
|
|
||||||
width: Int? = nil,
|
|
||||||
height: Int? = nil,
|
|
||||||
@ViewBuilder content: () -> Body
|
|
||||||
) -> AnyView {
|
|
||||||
Dialog(
|
|
||||||
visible: visible,
|
|
||||||
id: id ?? "",
|
|
||||||
title: title,
|
|
||||||
child: self,
|
|
||||||
content: content(),
|
|
||||||
width: width,
|
|
||||||
height: height
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -9,10 +9,10 @@ import CAdw
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
/// A structure representing a file dialog window.
|
/// A structure representing a file dialog window.
|
||||||
struct FileDialog: AdwaitaWidget {
|
public struct FileDialog: AdwaitaWidget {
|
||||||
|
|
||||||
/// Whether the dialog is an importer.
|
/// Whether the dialog is an importer.
|
||||||
var importer = true
|
var importer: Bool
|
||||||
/// Whether the dialog should open.
|
/// Whether the dialog should open.
|
||||||
var open: Signal
|
var open: Signal
|
||||||
/// The dialog's child.
|
/// The dialog's child.
|
||||||
@ -28,12 +28,44 @@ struct FileDialog: AdwaitaWidget {
|
|||||||
/// The closure to run when the import or export is not successful.
|
/// The closure to run when the import or export is not successful.
|
||||||
var cancel: () -> Void
|
var cancel: () -> Void
|
||||||
|
|
||||||
|
// swiftlint:disable function_default_parameter_at_end
|
||||||
|
/// Initialize the file dialog wrapper.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - importer: Whether it is an importer.
|
||||||
|
/// - 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,
|
||||||
|
`open`: Signal,
|
||||||
|
child: AnyView,
|
||||||
|
result: @escaping (URL) -> Void,
|
||||||
|
cancel: @escaping () -> Void,
|
||||||
|
initialFolder: URL? = nil,
|
||||||
|
initialName: String? = nil,
|
||||||
|
extensions: [String]? = nil
|
||||||
|
) {
|
||||||
|
self.importer = importer
|
||||||
|
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 view storage.
|
/// The view storage.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - modifiers: Modify views before being updated.
|
/// - modifiers: Modify views before being updated.
|
||||||
/// - type: The view render data type.
|
/// - type: The view render data type.
|
||||||
/// - Returns: The view storage.
|
/// - Returns: The view storage.
|
||||||
func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||||
let child = child.storage(data: data, type: type)
|
let child = child.storage(data: data, type: type)
|
||||||
let storage = ViewStorage(child.opaquePointer, content: [.mainContent: [child]])
|
let storage = ViewStorage(child.opaquePointer, content: [.mainContent: [child]])
|
||||||
update(storage, data: data, updateProperties: true, type: type)
|
update(storage, data: data, updateProperties: true, type: type)
|
||||||
@ -46,7 +78,7 @@ struct FileDialog: AdwaitaWidget {
|
|||||||
/// - modifiers: Modify views before being updated
|
/// - modifiers: Modify views before being updated
|
||||||
/// - updateProperties: Whether to update the view's properties.
|
/// - updateProperties: Whether to update the view's properties.
|
||||||
/// - type: The view render data type.
|
/// - type: The view render data type.
|
||||||
func update<Data>(
|
public func update<Data>(
|
||||||
_ storage: ViewStorage,
|
_ storage: ViewStorage,
|
||||||
data: WidgetData,
|
data: WidgetData,
|
||||||
updateProperties: Bool,
|
updateProperties: Bool,
|
||||||
@ -92,62 +124,6 @@ struct FileDialog: AdwaitaWidget {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension AnyView {
|
|
||||||
|
|
||||||
/// 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(
|
|
||||||
open: Signal,
|
|
||||||
initialFolder: URL? = nil,
|
|
||||||
extensions: [String]? = nil,
|
|
||||||
onOpen: @escaping (URL) -> Void,
|
|
||||||
onClose: @escaping () -> Void
|
|
||||||
) -> AnyView {
|
|
||||||
FileDialog(
|
|
||||||
importer: true,
|
|
||||||
open: open,
|
|
||||||
child: self,
|
|
||||||
initialFolder: initialFolder,
|
|
||||||
initialName: nil,
|
|
||||||
extensions: extensions,
|
|
||||||
result: onOpen,
|
|
||||||
cancel: onClose
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create an exporter file dialog.
|
|
||||||
/// - Parameters:
|
|
||||||
/// - exporter: The signal to open the dialog.
|
|
||||||
/// - initialFolder: The URL to the folder open when being opened.
|
|
||||||
/// - initialName: The default file name.
|
|
||||||
/// - onSave: Run this when a path for exporting has been chosen.
|
|
||||||
/// - onClose: Run this when the user cancelled the action.
|
|
||||||
public func fileExporter(
|
|
||||||
open: Signal,
|
|
||||||
initialFolder: URL? = nil,
|
|
||||||
initialName: String? = nil,
|
|
||||||
onSave: @escaping (URL) -> Void,
|
|
||||||
onClose: @escaping () -> Void
|
|
||||||
) -> AnyView {
|
|
||||||
FileDialog(
|
|
||||||
importer: false,
|
|
||||||
open: open,
|
|
||||||
child: self,
|
|
||||||
initialFolder: initialFolder,
|
|
||||||
initialName: initialName,
|
|
||||||
result: onSave,
|
|
||||||
cancel: onClose
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An Adwaita file dialog window callback.
|
/// An Adwaita file dialog window callback.
|
||||||
class AdwaitaFileDialog {
|
class AdwaitaFileDialog {
|
||||||
|
|
@ -14,11 +14,4 @@ extension ActionRow {
|
|||||||
self = self.title(title)
|
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -15,8 +15,11 @@ public struct Form: SimpleView {
|
|||||||
|
|
||||||
/// The view's body.
|
/// The view's body.
|
||||||
public var view: Body {
|
public var view: Body {
|
||||||
List([Int](content.indices), selection: nil) { index in content[index] }
|
ModifierWrapper(
|
||||||
.style("boxed-list")
|
content: List([Int](content.indices), selection: nil) { index in content[index] },
|
||||||
|
style: "boxed-list",
|
||||||
|
styleActive: true
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize a `Form`.
|
/// Initialize a `Form`.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user