commit
ec319a6738
2
.github/workflows/docs.yml
vendored
2
.github/workflows/docs.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: macos-14
|
||||
runs-on: macos-15
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Libadwaita
|
||||
|
@ -16,8 +16,6 @@ opt_in_rules:
|
||||
- convenience_type
|
||||
- discouraged_none_name
|
||||
- discouraged_object_literal
|
||||
- discouraged_optional_boolean
|
||||
- discouraged_optional_collection
|
||||
- empty_collection_literal
|
||||
- empty_count
|
||||
- empty_string
|
||||
@ -51,7 +49,6 @@ opt_in_rules:
|
||||
- multiline_parameters_brackets
|
||||
- no_extension_access_modifier
|
||||
- no_grouping_extension
|
||||
- no_magic_numbers
|
||||
- number_separator
|
||||
- operator_usage_whitespace
|
||||
- optional_enum_case_matching
|
||||
@ -141,7 +138,7 @@ file_header:
|
||||
missing_docs:
|
||||
warning: [internal, private]
|
||||
error: [open, public]
|
||||
excludes_extensions: false
|
||||
excludes_extensions: true
|
||||
excludes_inherited_types: false
|
||||
type_contents_order:
|
||||
order:
|
||||
|
@ -1,8 +0,0 @@
|
||||
# Contributors
|
||||
|
||||
- [david-swift](https://github.com/david-swift)
|
||||
- [Greg Cotten](https://github.com/gregcotten)
|
||||
- [Zev Eisenberg](https://github.com/ZevEisenberg)
|
||||
- [Jay Wren](https://github.com/jrwren)
|
||||
- [Amzd](https://github.com/amzd)
|
||||
- [lambdaclan](https://github.com/lambdaclan)
|
@ -1,4 +1,4 @@
|
||||
// swift-tools-version: 5.8
|
||||
// swift-tools-version: 6.0
|
||||
//
|
||||
// Package.swift
|
||||
// Adwaita
|
||||
@ -11,9 +11,7 @@ import PackageDescription
|
||||
/// The Adwaita package.
|
||||
let package = Package(
|
||||
name: "Adwaita",
|
||||
platforms: [
|
||||
.macOS(.v10_15)
|
||||
],
|
||||
platforms: [.macOS(.v10_15), .iOS(.v13), .tvOS(.v13), .watchOS(.v6), .macCatalyst(.v13)],
|
||||
products: [
|
||||
.library(
|
||||
name: "Adwaita",
|
||||
@ -25,6 +23,8 @@ let package = Package(
|
||||
)
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/AparokshaUI/Meta", branch: "main"),
|
||||
.package(url: "https://github.com/AparokshaUI/meta-sqlite", branch: "main"),
|
||||
.package(
|
||||
url: "https://github.com/david-swift/LevenshteinTransformations",
|
||||
from: "0.1.1"
|
||||
@ -40,7 +40,9 @@ let package = Package(
|
||||
name: "Adwaita",
|
||||
dependencies: [
|
||||
"CAdw",
|
||||
.product(name: "LevenshteinTransformations", package: "LevenshteinTransformations")
|
||||
.product(name: "LevenshteinTransformations", package: "LevenshteinTransformations"),
|
||||
.product(name: "Meta", package: "Meta"),
|
||||
.product(name: "MetaSQLite", package: "meta-sqlite")
|
||||
]
|
||||
),
|
||||
.executableTarget(
|
||||
@ -51,8 +53,8 @@ let package = Package(
|
||||
),
|
||||
.executableTarget(
|
||||
name: "Demo",
|
||||
dependencies: ["Adwaita"],
|
||||
path: "Tests"
|
||||
dependencies: ["Adwaita"]
|
||||
)
|
||||
]
|
||||
],
|
||||
swiftLanguageModes: [.v5]
|
||||
)
|
||||
|
@ -8,7 +8,7 @@
|
||||
import CAdw
|
||||
|
||||
/// A button widget for menus.
|
||||
public struct MenuButton: MenuItem {
|
||||
public struct MenuButton: MenuWidget {
|
||||
|
||||
/// The button's label.
|
||||
var label: String
|
||||
@ -16,8 +16,6 @@ public struct MenuButton: MenuItem {
|
||||
var handler: () -> Void
|
||||
/// The keyboard shortcut.
|
||||
var shortcut = ""
|
||||
/// Whether the keyboard shortcut is currently available.
|
||||
var active = true
|
||||
/// Whether to prefer adding the action to the application window.
|
||||
var preferApplicationWindow: Bool
|
||||
|
||||
@ -35,33 +33,61 @@ public struct MenuButton: MenuItem {
|
||||
self.handler = handler
|
||||
}
|
||||
|
||||
/// Add the button to a menu.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - menu: The menu.
|
||||
/// - app: The application containing the menu.
|
||||
/// - window: The application window containing the menu.
|
||||
public func addMenuItem(menu: OpaquePointer?, app: GTUIApp, window: GTUIApplicationWindow?) {
|
||||
if let window, preferApplicationWindow {
|
||||
window.addKeyboardShortcut(active ? shortcut : "", id: filteredLabel, handler: handler)
|
||||
g_menu_append(menu, label, "win." + filteredLabel)
|
||||
/// - modifiers: Modify the views before updating.
|
||||
/// - type: The type of the views.
|
||||
/// - Returns: The view storage.
|
||||
public func container<Data>(
|
||||
data: WidgetData,
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(nil)
|
||||
var label = filteredLabel
|
||||
guard let app = data.appStorage as? AdwaitaApp else {
|
||||
return .init(nil)
|
||||
}
|
||||
if let window = data.sceneStorage.pointer as? AdwaitaWindow, preferApplicationWindow {
|
||||
app.addKeyboardShortcut(shortcut, id: filteredLabel, window: window, handler: handler)
|
||||
label = "win." + label
|
||||
} else {
|
||||
app.addKeyboardShortcut(active ? shortcut : "", id: filteredLabel, handler: handler)
|
||||
g_menu_append(menu, label, "app." + filteredLabel)
|
||||
app.addKeyboardShortcut(shortcut, id: filteredLabel, handler: handler)
|
||||
label = "app." + label
|
||||
}
|
||||
let pointer = g_menu_item_new(self.label, label)
|
||||
storage.pointer = pointer
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify the views before updating.
|
||||
/// - updateProperties: Whether to update the properties.
|
||||
/// - type: The type of the views.
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
data: WidgetData,
|
||||
updateProperties: Bool,
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
guard let app = data.appStorage as? AdwaitaApp else {
|
||||
return
|
||||
}
|
||||
if let window = data.sceneStorage.pointer as? AdwaitaWindow, preferApplicationWindow {
|
||||
app.addKeyboardShortcut(shortcut, id: filteredLabel, window: window, handler: handler)
|
||||
} else {
|
||||
app.addKeyboardShortcut(shortcut, id: filteredLabel, handler: handler)
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a keyboard shortcut for an application from a button.
|
||||
///
|
||||
/// Note that the keyboard shortcut is available after the view has been visible for the first time.
|
||||
/// - Parameters:
|
||||
/// - shortcut: The keyboard shortcut.
|
||||
/// - active: Whether the keyboard shortcut is currently available.
|
||||
/// - Parameter shortcut: The keyboard shortcut.
|
||||
/// - Returns: The button.
|
||||
public func keyboardShortcut(_ shortcut: String, active: Bool = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.shortcut = shortcut
|
||||
newSelf.active = active
|
||||
return newSelf
|
||||
public func keyboardShortcut(_ shortcut: String) -> Self {
|
||||
modify { $0.shortcut = shortcut }
|
||||
}
|
||||
|
||||
}
|
||||
|
84
Sources/Adwaita/Menu/MenuCollection.swift
Normal file
84
Sources/Adwaita/Menu/MenuCollection.swift
Normal file
@ -0,0 +1,84 @@
|
||||
//
|
||||
// MenuCollection.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 02.08.2024.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import Foundation
|
||||
|
||||
/// A collection of menus.
|
||||
public struct MenuCollection: MenuWidget, Wrapper {
|
||||
|
||||
/// The content of the collection.
|
||||
var content: Body
|
||||
|
||||
/// Initialize a menu.
|
||||
/// - Parameter content: The content of the collection.
|
||||
public init(@ViewBuilder content: @escaping () -> Body) {
|
||||
self.content = content()
|
||||
}
|
||||
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify the views before updating.
|
||||
/// - type: The type of the views.
|
||||
/// - Returns: The view storage.
|
||||
public func container<Data>(
|
||||
data: WidgetData,
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let storages = content.storages(data: data, type: type)
|
||||
return .init(nil, content: [.mainContent: storages])
|
||||
}
|
||||
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify the views before updating.
|
||||
/// - updateProperties: Whether to update the properties.
|
||||
/// - type: The type of the views.
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
data: WidgetData,
|
||||
updateProperties: Bool,
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
guard let storages = storage.content[.mainContent] else {
|
||||
return
|
||||
}
|
||||
content.update(storages, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
|
||||
/// Render the collection as a menu.
|
||||
/// - Parameter data: The widget data.
|
||||
/// - Returns: The view storage with the GMenu as the pointer.
|
||||
public func getMenu(data: WidgetData) -> ViewStorage {
|
||||
let menu = g_menu_new()
|
||||
let storage = container(data: data.noModifiers, type: MenuContext.self)
|
||||
if let app = data.appStorage as? AdwaitaApp, let window = data.sceneStorage.pointer as? AdwaitaWindow {
|
||||
initializeMenu(menu: menu, storage: storage, app: app, window: window)
|
||||
}
|
||||
storage.pointer = menu
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Initialize a menu.
|
||||
/// - Parameters:
|
||||
/// - menu: The pointer to the GMenu.
|
||||
/// - storage: The storage for the menu's content.
|
||||
/// - app: The app object.
|
||||
/// - window: The window object.
|
||||
func initializeMenu(menu: OpaquePointer?, storage: ViewStorage, app: AdwaitaApp, window: AdwaitaWindow?) {
|
||||
if let item = storage.opaquePointer {
|
||||
g_menu_append_item(menu, item)
|
||||
storage.pointer = item
|
||||
} else {
|
||||
for element in storage.content[.mainContent] ?? [] {
|
||||
initializeMenu(menu: menu, storage: element, app: app, window: window)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
21
Sources/Adwaita/Menu/MenuContext.swift
Normal file
21
Sources/Adwaita/Menu/MenuContext.swift
Normal file
@ -0,0 +1,21 @@
|
||||
//
|
||||
// MenuContext.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 01.08.24.
|
||||
//
|
||||
|
||||
/// The menu items view context.
|
||||
public enum MenuContext: ViewRenderData {
|
||||
|
||||
/// The type of the widgets.
|
||||
public typealias WidgetType = MenuWidget
|
||||
/// The wrapper type.
|
||||
public typealias WrapperType = MenuCollection
|
||||
/// The either view type.
|
||||
public typealias EitherViewType = MenuEitherView
|
||||
|
||||
}
|
||||
|
||||
/// The type of the widgets.
|
||||
public protocol MenuWidget: Meta.Widget { }
|
23
Sources/Adwaita/Menu/MenuEitherView.swift
Normal file
23
Sources/Adwaita/Menu/MenuEitherView.swift
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// MenuEitherView.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 06.08.2024.
|
||||
//
|
||||
|
||||
/// Show one of two views depending on a condition.
|
||||
public struct MenuEitherView: Meta.EitherView, SimpleView {
|
||||
|
||||
/// The view.
|
||||
public var view: Body
|
||||
|
||||
/// Initialize an either view.
|
||||
/// - Parameters:
|
||||
/// - condition: The condition.
|
||||
/// - view1: The first view.
|
||||
/// - view2: The second view.
|
||||
public init(_ condition: Bool, view1: () -> Body, else view2: () -> Body) {
|
||||
self.view = condition ? view1() : view2()
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Submenu.swift
|
||||
// MenuButton.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 22.10.23.
|
||||
@ -7,29 +7,52 @@
|
||||
|
||||
import CAdw
|
||||
|
||||
/// A section for menus.
|
||||
public struct MenuSection: MenuItem {
|
||||
/// A button widget for menus.
|
||||
public struct MenuSection: MenuWidget {
|
||||
|
||||
/// The content of the section.
|
||||
var sectionContent: MenuContent
|
||||
var sectionContent: Body
|
||||
|
||||
/// Initialize a section for menus.
|
||||
/// - Parameter content: The content of the section.
|
||||
public init(@MenuBuilder content: () -> MenuContent) {
|
||||
public init(@ViewBuilder content: () -> Body) {
|
||||
self.sectionContent = content()
|
||||
}
|
||||
|
||||
/// Add the section to a menu.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - menu: The menu.
|
||||
/// - app: The application containing the menu.
|
||||
/// - window: The application window containing the menu.
|
||||
public func addMenuItem(menu: OpaquePointer?, app: GTUIApp, window: GTUIApplicationWindow?) {
|
||||
let section = g_menu_new()
|
||||
g_menu_append_section(menu, nil, section?.cast())
|
||||
for element in sectionContent {
|
||||
element.addMenuItems(menu: section, app: app, window: window)
|
||||
/// - modifiers: Modify the views before updating.
|
||||
/// - type: The type of the views.
|
||||
/// - Returns: The view storage.
|
||||
public func container<Data>(
|
||||
data: WidgetData,
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(nil)
|
||||
let childStorage = MenuCollection { sectionContent }.getMenu(data: data)
|
||||
storage.content[.mainContent] = [childStorage]
|
||||
let pointer = g_menu_item_new_section(nil, childStorage.opaquePointer?.cast())
|
||||
storage.pointer = pointer
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify the views before updating.
|
||||
/// - updateProperties: Whether to update the properties.
|
||||
/// - type: The type of the views.
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
data: WidgetData,
|
||||
updateProperties: Bool,
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
guard let content = storage.content[.mainContent]?.first else {
|
||||
return
|
||||
}
|
||||
MenuCollection { sectionContent }
|
||||
.updateStorage(content, data: data, updateProperties: updateProperties, type: MenuContext.self)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,33 +8,56 @@
|
||||
import CAdw
|
||||
|
||||
/// A submenu widget.
|
||||
public struct Submenu: MenuItem {
|
||||
public struct Submenu: MenuWidget {
|
||||
|
||||
/// The submenu's label.
|
||||
/// The label of the submenu.
|
||||
var label: String
|
||||
/// The content of the submenu.
|
||||
var submenuContent: MenuContent
|
||||
var content: Body
|
||||
|
||||
/// Initialize a submenu.
|
||||
/// - Parameters:
|
||||
/// - label: The submenu's label.
|
||||
/// - content: The content of the submenu.
|
||||
public init(_ label: String, @MenuBuilder content: () -> MenuContent) {
|
||||
/// - content: The content of the section.
|
||||
public init(_ label: String, @ViewBuilder content: () -> Body) {
|
||||
self.label = label
|
||||
self.submenuContent = content()
|
||||
self.content = content()
|
||||
}
|
||||
|
||||
/// Add the submenu to a menu.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - menu: The menu.
|
||||
/// - app: The application containing the menu.
|
||||
/// - window: The application window containing the menu.
|
||||
public func addMenuItem(menu: OpaquePointer?, app: GTUIApp, window: GTUIApplicationWindow?) {
|
||||
let submenu = g_menu_new()
|
||||
g_menu_append_submenu(menu, label, submenu?.cast())
|
||||
for element in submenuContent {
|
||||
element.addMenuItems(menu: submenu, app: app, window: window)
|
||||
/// - modifiers: Modify the views before updating.
|
||||
/// - type: The type of the views.
|
||||
/// - Returns: The view storage.
|
||||
public func container<Data>(
|
||||
data: WidgetData,
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(nil)
|
||||
let childStorage = MenuCollection { content }.getMenu(data: data)
|
||||
storage.content[.mainContent] = [childStorage]
|
||||
let pointer = g_menu_item_new_submenu(label, childStorage.opaquePointer?.cast())
|
||||
storage.pointer = pointer
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify the views before updating.
|
||||
/// - updateProperties: Whether to update the properties.
|
||||
/// - type: The type of the views.
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
data: WidgetData,
|
||||
updateProperties: Bool,
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
guard let content = storage.content[.mainContent]?.first else {
|
||||
return
|
||||
}
|
||||
MenuCollection { self.content }
|
||||
.updateStorage(content, data: data, updateProperties: updateProperties, type: MenuContext.self)
|
||||
}
|
||||
|
||||
}
|
||||
|
123
Sources/Adwaita/Model/AdwaitaApp.swift
Normal file
123
Sources/Adwaita/Model/AdwaitaApp.swift
Normal file
@ -0,0 +1,123 @@
|
||||
//
|
||||
// AdwaitaApp.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 31.07.2024.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import Foundation
|
||||
@_exported import Meta
|
||||
@_exported import MetaSQLite
|
||||
|
||||
/// The Meta app storage for the Adwaita backend.
|
||||
public class AdwaitaApp: AppStorage {
|
||||
|
||||
/// The scene element type of the Adwaita backend.
|
||||
public typealias SceneElementType = AdwaitaSceneElement
|
||||
/// The widget type of the Adwaita backend.
|
||||
public typealias WidgetType = AdwaitaWidget
|
||||
/// The wrapper type of the Adwaita backend.
|
||||
public typealias WrapperType = VStack
|
||||
|
||||
/// The app storage.
|
||||
public var storage: StandardAppStorage = .init()
|
||||
/// The signal data for running.
|
||||
var runSignal: SignalData?
|
||||
/// The application's pointer.
|
||||
var pointer: UnsafeMutablePointer<GtkApplication>?
|
||||
/// Fields for storing closure data.
|
||||
var signals: [String: SignalData] = [:]
|
||||
|
||||
/// Initialize the app storage.
|
||||
/// - 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)
|
||||
}
|
||||
|
||||
/// Copy a string to the clipboard.
|
||||
public static func copy(_ text: String) {
|
||||
let clipboard = gdk_display_get_clipboard(gdk_display_get_default())
|
||||
gdk_clipboard_set_text(clipboard, text)
|
||||
}
|
||||
|
||||
/// The directory used for storing user data.
|
||||
/// - Returns: The URL.
|
||||
public static func userDataDir() -> URL {
|
||||
.init(fileURLWithPath: .init(cString: g_get_user_data_dir()))
|
||||
}
|
||||
|
||||
/// Execute the app.
|
||||
/// - Parameter setup: Set the scene elements up.
|
||||
public func run(setup: @escaping () -> Void) {
|
||||
let data = SignalData {
|
||||
setup()
|
||||
}
|
||||
runSignal = data
|
||||
data.connect(pointer: pointer, signal: "activate")
|
||||
g_application_run(pointer?.cast(), 0, nil)
|
||||
}
|
||||
|
||||
/// Quit the app.
|
||||
public func quit() {
|
||||
g_application_quit(pointer?.cast())
|
||||
}
|
||||
|
||||
/// Add a keyboard shortcut to the application.
|
||||
/// - Parameters:
|
||||
/// - shortcut: The keyboard shortcut.
|
||||
/// - id: The action's id.
|
||||
/// - window: Optionally an application window.
|
||||
/// - handler: The action's handler.
|
||||
func addKeyboardShortcut(
|
||||
_ shortcut: String,
|
||||
id: String,
|
||||
window: AdwaitaWindow? = nil,
|
||||
handler: @escaping () -> Void
|
||||
) {
|
||||
if window == nil, let data = signals[id] {
|
||||
data.closure = { _ in handler() }
|
||||
return
|
||||
} else if let data = window?.signals[id] {
|
||||
data.closure = { _ in handler() }
|
||||
return
|
||||
}
|
||||
let action = g_simple_action_new(id, nil)
|
||||
let data = SignalData(closure: handler)
|
||||
g_signal_connect_data(
|
||||
action?.cast(),
|
||||
"activate",
|
||||
unsafeBitCast(data.threeParamsHandler, to: GCallback.self),
|
||||
Unmanaged.passUnretained(data).toOpaque().cast(),
|
||||
nil,
|
||||
G_CONNECT_AFTER
|
||||
)
|
||||
if let window {
|
||||
g_action_map_add_action(.init(window.pointer), action)
|
||||
window.signals[id] = data
|
||||
} else {
|
||||
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)
|
||||
}
|
||||
|
||||
/// Remove a keyboard shortcut from the application.
|
||||
/// - Parameters:
|
||||
/// - id: The keyboard shortcut's id.
|
||||
/// - window: Optionally an application window.
|
||||
func removeKeyboardShortcut(
|
||||
id: String,
|
||||
window: AdwaitaWindow? = nil
|
||||
) {
|
||||
if let window {
|
||||
g_action_map_remove_action(.init(window.pointer), id)
|
||||
window.signals.removeValue(forKey: id)
|
||||
} else {
|
||||
g_action_map_remove_action(.init(pointer), id)
|
||||
signals.removeValue(forKey: id)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
18
Sources/Adwaita/Model/AdwaitaMainView.swift
Normal file
18
Sources/Adwaita/Model/AdwaitaMainView.swift
Normal file
@ -0,0 +1,18 @@
|
||||
//
|
||||
// AdwaitaMainView.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 31.07.2024.
|
||||
//
|
||||
|
||||
/// The type of widgets of the Adwaita backend.
|
||||
public enum AdwaitaMainView: ViewRenderData {
|
||||
|
||||
/// The type of the widgets.
|
||||
public typealias WidgetType = AdwaitaWidget
|
||||
/// The wrapper type.
|
||||
public typealias WrapperType = VStackWrapper
|
||||
/// The either view type.
|
||||
public typealias EitherViewType = EitherView
|
||||
|
||||
}
|
9
Sources/Adwaita/Model/AdwaitaSceneElement.swift
Normal file
9
Sources/Adwaita/Model/AdwaitaSceneElement.swift
Normal file
@ -0,0 +1,9 @@
|
||||
//
|
||||
// AdwaitaSceneElement.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 31.07.2024.
|
||||
//
|
||||
|
||||
/// The type of scene elements of the Adwaita backend.
|
||||
public protocol AdwaitaSceneElement: SceneElement { }
|
9
Sources/Adwaita/Model/AdwaitaWidget.swift
Normal file
9
Sources/Adwaita/Model/AdwaitaWidget.swift
Normal file
@ -0,0 +1,9 @@
|
||||
//
|
||||
// AdwaitaWidget.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 31.07.2024.
|
||||
//
|
||||
|
||||
/// The type of widgets of the Adwaita backend.
|
||||
public protocol AdwaitaWidget: Widget { }
|
@ -1,113 +0,0 @@
|
||||
//
|
||||
// ArrayBuilder.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 05.08.23.
|
||||
//
|
||||
// Thanks to Jaden Geller for the GitHub Gist:
|
||||
// "ArrayBuilder.swift"
|
||||
// https://gist.github.com/JadenGeller/c375fc15ad5900a0ddac4ed8ba8307a9
|
||||
//
|
||||
|
||||
/// The ``ArrayBuilder`` is a simple result builder that outputs an array of any type.
|
||||
///
|
||||
/// You can define any array using Swift's DSL:
|
||||
/// ```swift
|
||||
/// @ArrayBuilder<String> var string: [String] {
|
||||
/// "Hello, "
|
||||
/// if bool {
|
||||
/// "world!"
|
||||
/// } else {
|
||||
/// "colibri!"
|
||||
/// }
|
||||
/// for x in 0...10 {
|
||||
/// "\nIteration Number \(x)"
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
@resultBuilder
|
||||
public enum ArrayBuilder<Element> {
|
||||
|
||||
/// A component used in the ``ArrayBuilder``.
|
||||
public enum Component {
|
||||
|
||||
/// An element as a component.
|
||||
case element(_: Element)
|
||||
/// An array of components as a component.
|
||||
case components(_: [Self])
|
||||
|
||||
}
|
||||
|
||||
/// Build combined results from statement blocks.
|
||||
/// - Parameter components: The components.
|
||||
/// - Returns: The components in a component.
|
||||
public static func buildBlock(_ elements: Component...) -> Component {
|
||||
.components(elements)
|
||||
}
|
||||
|
||||
/// Translate an element into an ``ArrayBuilder.Component``.
|
||||
/// - Parameter element: The element to translate.
|
||||
/// - Returns: A component created from the element.
|
||||
public static func buildExpression(_ element: Element) -> Component {
|
||||
.element(element)
|
||||
}
|
||||
|
||||
/// Translate an array of elements into an ``ArrayBuilder.Component``.
|
||||
/// - Parameter elements: The elements to translate.
|
||||
/// - Returns: A component created from the element.
|
||||
public static func buildExpression(_ elements: [Element]) -> Component {
|
||||
var components: [Component] = []
|
||||
for element in elements {
|
||||
components.append(.element(element))
|
||||
}
|
||||
return .components(components)
|
||||
}
|
||||
|
||||
/// Fetch a component.
|
||||
/// - Parameter component: A component.
|
||||
/// - Returns: The component.
|
||||
public static func buildExpression(_ component: Component) -> Component {
|
||||
component
|
||||
}
|
||||
|
||||
/// Enables support for `if` statements without an `else`.
|
||||
/// - Parameter component: An optional component.
|
||||
/// - Returns: A nonoptional component.
|
||||
public static func buildOptional(_ component: Component?) -> Component {
|
||||
component ?? .components([])
|
||||
}
|
||||
|
||||
/// Enables support for `if`-`else` and `switch` statements.
|
||||
/// - Parameter component: A component.
|
||||
/// - Returns: The component.
|
||||
public static func buildEither(first component: Component) -> Component {
|
||||
component
|
||||
}
|
||||
|
||||
/// Enables support for `if`-`else` and `switch` statements.
|
||||
/// - Parameter component: A component.
|
||||
/// - Returns: The component.
|
||||
public static func buildEither(second component: Component) -> Component {
|
||||
component
|
||||
}
|
||||
|
||||
/// Enables support for `for..in` loops.
|
||||
/// - Parameter components: The components as a two dimensional array.
|
||||
/// - Returns: The components as a one dimensional array.
|
||||
public static func buildArray(_ components: [Component]) -> Component {
|
||||
.components(components)
|
||||
}
|
||||
|
||||
/// Convert a component to an array of elements.
|
||||
/// - Parameter component: The component to convert.
|
||||
/// - Returns: The generated array of elements.
|
||||
public static func buildFinalResult(_ component: Component) -> [Element] {
|
||||
switch component {
|
||||
case let .element(element):
|
||||
return [element]
|
||||
case let .components(components):
|
||||
return components.flatMap { buildFinalResult($0) }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
//
|
||||
// Binding.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 06.08.23.
|
||||
//
|
||||
|
||||
/// A property wrapper for a property of a view that binds the property of the parent view.
|
||||
///
|
||||
/// ```swift
|
||||
/// struct Grandparent: View {
|
||||
///
|
||||
/// @State private var state = false
|
||||
///
|
||||
/// var view: Body {
|
||||
/// Parent(value: $state)
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// struct Parent: View {
|
||||
///
|
||||
/// @Binding var value: Bool
|
||||
///
|
||||
/// var view: Body {
|
||||
/// Child(value: $value)
|
||||
/// }
|
||||
///
|
||||
/// }
|
||||
///
|
||||
/// struct Child: View {
|
||||
///
|
||||
/// @Binding var value: Bool
|
||||
///
|
||||
/// var view: Body {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// }
|
||||
/// ```
|
||||
@propertyWrapper
|
||||
@dynamicMemberLookup
|
||||
public struct Binding<Value> {
|
||||
|
||||
/// The value.
|
||||
public var wrappedValue: Value {
|
||||
get {
|
||||
getValue()
|
||||
}
|
||||
nonmutating set {
|
||||
setValue(newValue)
|
||||
for handler in handlers {
|
||||
handler(newValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the value as a binding using the `$` prefix.
|
||||
public var projectedValue: Binding<Value> {
|
||||
.init {
|
||||
wrappedValue
|
||||
} set: { newValue in
|
||||
wrappedValue = newValue
|
||||
}
|
||||
}
|
||||
|
||||
/// The closure for getting the value.
|
||||
private let getValue: () -> Value
|
||||
/// The closure for settings the value.
|
||||
private let setValue: (Value) -> Void
|
||||
/// Handlers observing whether the binding changes.
|
||||
private var handlers: [(Value) -> Void] = []
|
||||
|
||||
/// Get a property of any content of a `Binding` as a `Binding`.
|
||||
/// - Parameter dynamicMember: The path to the member.
|
||||
/// - Returns: The binding.
|
||||
public subscript<Subject>(dynamicMember keyPath: WritableKeyPath<Value, Subject>) -> Binding<Subject> {
|
||||
.init {
|
||||
wrappedValue[keyPath: keyPath]
|
||||
} set: { newValue in
|
||||
wrappedValue[keyPath: keyPath] = newValue
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize a property that is bound from a parent view.
|
||||
/// - Parameters:
|
||||
/// - get: The closure for getting the value.
|
||||
/// - set: The closure for setting the value.
|
||||
public init(get: @escaping () -> Value, set: @escaping (Value) -> Void) {
|
||||
self.getValue = get
|
||||
self.setValue = set
|
||||
}
|
||||
|
||||
/// Initialize a property that does not react to changes in the child view.
|
||||
/// - Parameters:
|
||||
/// - value: The constant value.
|
||||
/// - Returns: The binding.
|
||||
public static func constant(_ value: Value) -> Binding<Value> {
|
||||
.init {
|
||||
value
|
||||
} set: { _ in
|
||||
}
|
||||
}
|
||||
|
||||
/// Observe whether data is changed over this binding.
|
||||
/// - Parameter handler: The handler.
|
||||
/// - Returns: The binding.
|
||||
public func onSet(_ handler: @escaping (Value) -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.handlers.append(handler)
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// An extension
|
||||
extension Binding where Value: MutableCollection {
|
||||
|
||||
/// Get a child at a certain index of the array as a binding.
|
||||
/// - Parameters:
|
||||
/// - index: The child's index.
|
||||
/// - defaultValue: The value used if the index is out of range does not exist.
|
||||
/// - Returns: The child as a binding.
|
||||
public subscript(safe index: Value.Index?, default defaultValue: Value.Element) -> Binding<Value.Element> {
|
||||
.init {
|
||||
if let index, wrappedValue.indices.contains(index) {
|
||||
return wrappedValue[index]
|
||||
}
|
||||
return defaultValue
|
||||
} set: { newValue in
|
||||
if let index, wrappedValue.indices.contains(index) {
|
||||
wrappedValue[index] = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// An extension
|
||||
extension Binding where Value: MutableCollection, Value.Element: Identifiable {
|
||||
|
||||
/// Get a child of the array with a certain id as a binding.
|
||||
/// - Parameters:
|
||||
/// - id: The child's id.
|
||||
/// - defaultValue: The value used if the index is out of range does not exist.
|
||||
/// - Returns: The child as a binding.
|
||||
public subscript(id id: Value.Element.ID?, default defaultValue: Value.Element) -> Binding<Value.Element> {
|
||||
self[safe: wrappedValue.firstIndex { $0.id == id }, default: defaultValue]
|
||||
}
|
||||
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
//
|
||||
// Signal.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 30.11.23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// A type that signalizes an action.
|
||||
public struct Signal {
|
||||
|
||||
/// An action is signalized by toggling a boolean to `true` and back to `false`.
|
||||
@State var boolean = false
|
||||
/// A signal has a unique identifier.
|
||||
public let id: UUID = .init()
|
||||
|
||||
/// Whether the action has caused an update.
|
||||
public var update: Bool { boolean }
|
||||
|
||||
/// Initialize a signal.
|
||||
public init() { }
|
||||
|
||||
/// Activate a signal.
|
||||
public func signal() {
|
||||
boolean = true
|
||||
boolean = false
|
||||
}
|
||||
|
||||
}
|
@ -1,252 +0,0 @@
|
||||
//
|
||||
// State.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 06.08.23.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import Foundation
|
||||
|
||||
/// A property wrapper for properties in a view that should be stored throughout view updates.
|
||||
@propertyWrapper
|
||||
public struct State<Value>: StateProtocol {
|
||||
|
||||
/// Access the stored value. This updates the views when being changed.
|
||||
public var wrappedValue: Value {
|
||||
get {
|
||||
rawValue
|
||||
}
|
||||
nonmutating set {
|
||||
rawValue = newValue
|
||||
content.storage.update = true
|
||||
Self.updateViews(force: forceUpdates)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the value as a binding using the `$` prefix.
|
||||
public var projectedValue: Binding<Value> {
|
||||
.init {
|
||||
wrappedValue
|
||||
} set: { newValue in
|
||||
self.wrappedValue = newValue
|
||||
}
|
||||
}
|
||||
|
||||
// swiftlint:disable force_cast
|
||||
/// Get and set the value without updating the views.
|
||||
public var rawValue: Value {
|
||||
get {
|
||||
if let readValue, !content.fetched {
|
||||
let newValue = readValue()
|
||||
content.storage.value = newValue
|
||||
content.fetched = true
|
||||
return newValue
|
||||
}
|
||||
return content.storage.value as! Value
|
||||
}
|
||||
nonmutating set {
|
||||
content.storage.value = newValue
|
||||
writeValue?()
|
||||
}
|
||||
}
|
||||
// swiftlint:enable force_cast
|
||||
|
||||
/// The stored value.
|
||||
public let content: State<Any>.Content
|
||||
|
||||
/// Whether to force update the views when the value changes.
|
||||
public var forceUpdates: Bool
|
||||
|
||||
/// The function for updating the value in the settings file.
|
||||
private var writeValue: (() -> Void)?
|
||||
/// The function for reading the value in the settings file.
|
||||
var readValue: (() -> Value)?
|
||||
|
||||
/// The value with an erased type.
|
||||
public var value: Any {
|
||||
get {
|
||||
wrappedValue
|
||||
}
|
||||
nonmutating set {
|
||||
if let newValue = newValue as? Value {
|
||||
content.storage.value = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize a property representing a state in the view.
|
||||
/// - Parameters:
|
||||
/// - wrappedValue: The wrapped value.
|
||||
/// - forceUpdates: Whether to force update all available views when the property gets modified.
|
||||
public init(wrappedValue: Value, forceUpdates: Bool = false) {
|
||||
content = .init(initialValue: wrappedValue)
|
||||
self.forceUpdates = forceUpdates
|
||||
}
|
||||
|
||||
/// A class storing the state's content.
|
||||
public class Content {
|
||||
|
||||
/// The storage.
|
||||
public var storage: Storage {
|
||||
get {
|
||||
if let internalStorage {
|
||||
return internalStorage
|
||||
}
|
||||
let storage = Storage(value: initialValue)
|
||||
internalStorage = storage
|
||||
return storage
|
||||
}
|
||||
set {
|
||||
internalStorage = newValue
|
||||
}
|
||||
}
|
||||
/// The internal storage.
|
||||
var internalStorage: Storage?
|
||||
/// The initial value.
|
||||
private var initialValue: Value
|
||||
/// Whether the value has already been fetched from the file stored on the system.
|
||||
var fetched = false
|
||||
|
||||
/// Initialize the content.
|
||||
/// - Parameter storage: The storage.
|
||||
@available(*, deprecated, message: "Use a safer initializer instead")
|
||||
public init(storage: Storage) {
|
||||
// swiftlint:disable force_cast
|
||||
let initialValue = storage.value as! Value
|
||||
// swiftlint:enable force_cast
|
||||
self.initialValue = initialValue
|
||||
self.storage = storage
|
||||
}
|
||||
|
||||
/// Initialize the content.
|
||||
/// - Parameter initialValue: The initial value.
|
||||
public init(initialValue: Value) {
|
||||
self.initialValue = initialValue
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// A class storing the value.
|
||||
public class Storage {
|
||||
|
||||
/// The stored value.
|
||||
public var value: Any
|
||||
/// The storage key.
|
||||
public var key: String?
|
||||
/// The folder path.
|
||||
public var folder: String?
|
||||
/// Whether to update the affected views.
|
||||
public var update = false
|
||||
|
||||
/// Initialize the storage.
|
||||
/// - Parameters:
|
||||
/// - value: The value.
|
||||
public init(value: Any) {
|
||||
self.value = value
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Update all of the views.
|
||||
/// - Parameter force: Whether to force all views to update.
|
||||
public static func updateViews(force: Bool = false) {
|
||||
UpdateManager.updateViews(force: force)
|
||||
}
|
||||
|
||||
/// The directory used for storing user data.
|
||||
/// - Returns: The URL.
|
||||
public static func userDataDir() -> URL {
|
||||
.init(fileURLWithPath: .init(cString: g_get_user_data_dir()))
|
||||
}
|
||||
|
||||
/// Copy a text to the clipboard.
|
||||
/// - Parameter text: The text.
|
||||
public static func copy(_ text: String) {
|
||||
let clipboard = gdk_display_get_clipboard(gdk_display_get_default())
|
||||
gdk_clipboard_set_text(clipboard, text)
|
||||
}
|
||||
|
||||
/// Get the settings directory path.
|
||||
/// - Returns: The path.
|
||||
private func dirPath() -> URL? {
|
||||
guard let folder = content.storage.folder ?? GTUIApp.appID else {
|
||||
return nil
|
||||
}
|
||||
return Self.userDataDir()
|
||||
.appendingPathComponent(folder, isDirectory: true)
|
||||
}
|
||||
|
||||
/// Get the settings file path.
|
||||
/// - Returns: The path.
|
||||
private func filePath() -> URL? {
|
||||
dirPath()?.appendingPathComponent("\(content.storage.key ?? "temporary").json")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// An extension
|
||||
extension State where Value: Codable {
|
||||
|
||||
/// Initialize a property representing a state in the view.
|
||||
/// - Parameters:
|
||||
/// - wrappedValue: The wrapped value.
|
||||
/// - key: The unique storage key of the property.
|
||||
/// - folder: The path to the folder containing the JSON file.
|
||||
/// - forceUpdates: Whether to force update all available views when the property gets modified.
|
||||
///
|
||||
/// The folder path will be appended to the XDG data home directory.
|
||||
public init(wrappedValue: Value, _ key: String, folder: String? = nil, forceUpdates: Bool = false) {
|
||||
content = .init(initialValue: wrappedValue)
|
||||
self.forceUpdates = forceUpdates
|
||||
content.storage.key = key
|
||||
content.storage.folder = folder
|
||||
let value = self
|
||||
self.readValue = {
|
||||
value.checkFile()
|
||||
return value.readActualValue() ?? wrappedValue
|
||||
}
|
||||
self.writeValue = writeCodableValue
|
||||
}
|
||||
|
||||
/// Check whether the settings file exists, and, if not, create it.
|
||||
private func checkFile() {
|
||||
let fileManager = FileManager.default
|
||||
guard let dirPath = dirPath(), let filePath = filePath() else {
|
||||
print("Stored state value accessed before initializing app id.")
|
||||
return
|
||||
}
|
||||
if !fileManager.fileExists(atPath: dirPath.path) {
|
||||
try? fileManager.createDirectory(
|
||||
at: .init(fileURLWithPath: dirPath.path),
|
||||
withIntermediateDirectories: true,
|
||||
attributes: nil
|
||||
)
|
||||
}
|
||||
if !fileManager.fileExists(atPath: filePath.path) {
|
||||
fileManager.createFile(atPath: filePath.path, contents: .init(), attributes: nil)
|
||||
}
|
||||
}
|
||||
|
||||
/// Update the local value with the value from the file.
|
||||
private func readActualValue() -> Value? {
|
||||
if let filePath = filePath(),
|
||||
let data = try? Data(contentsOf: filePath),
|
||||
let value = try? JSONDecoder().decode(Value.self, from: data) {
|
||||
return value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Update the value on the file with the local value.
|
||||
private func writeCodableValue() {
|
||||
let encoder = JSONEncoder()
|
||||
encoder.outputFormatting = .prettyPrinted
|
||||
let data = try? encoder.encode(rawValue)
|
||||
guard let filePath = filePath() else {
|
||||
return
|
||||
}
|
||||
try? data?.write(to: filePath)
|
||||
}
|
||||
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
//
|
||||
// StateProtocol.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 09.09.23.
|
||||
//
|
||||
|
||||
/// An interface for accessing `State` without specifying the generic type.
|
||||
public protocol StateProtocol {
|
||||
|
||||
/// The class storing the value.
|
||||
var content: State<Any>.Content { get }
|
||||
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
//
|
||||
// UpdateManager.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 17.02.23.
|
||||
//
|
||||
|
||||
/// This type manages view updates.
|
||||
enum UpdateManager {
|
||||
|
||||
/// The class storing the value.
|
||||
static var blockUpdates = false
|
||||
|
||||
/// Update all of the views.
|
||||
/// - Parameter force: Whether to force all views to update.
|
||||
static func updateViews(force: Bool = false) {
|
||||
if !blockUpdates {
|
||||
for handler in GTUIApp.updateHandlers {
|
||||
handler(force)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -5,60 +5,6 @@
|
||||
// Created by david-swift on 06.08.23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// An extension
|
||||
extension Array: View where Element == View {
|
||||
|
||||
/// The array's view body is the array itself.
|
||||
public var view: Body { self }
|
||||
|
||||
/// Get a widget from a collection of views.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// - Returns: A widget.
|
||||
public func widget(modifiers: [(View) -> View]) -> Widget {
|
||||
if count == 1, let widget = self[safe: 0]?.widget(modifiers: modifiers) {
|
||||
return widget
|
||||
} else {
|
||||
var modified = self
|
||||
for (index, view) in modified.enumerated() {
|
||||
for modifier in modifiers {
|
||||
modified[safe: index] = modifier(view)
|
||||
}
|
||||
}
|
||||
return VStack { modified }
|
||||
}
|
||||
}
|
||||
|
||||
/// Update a collection of views with a collection of view storages.
|
||||
/// - Parameters:
|
||||
/// - storage: The collection of view storages.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - updateProperties: Whether to update properties.
|
||||
public func update(_ storage: [ViewStorage], modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
for (index, element) in enumerated() {
|
||||
if let storage = storage[safe: index] {
|
||||
element
|
||||
.widget(modifiers: modifiers)
|
||||
.updateStorage(storage, modifiers: modifiers, updateProperties: updateProperties)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// An extension
|
||||
extension Array where Element == WindowSceneGroup {
|
||||
|
||||
/// Get the content of an array of window scene groups.
|
||||
/// - Returns: The array of windows.
|
||||
public func windows() -> [WindowScene] {
|
||||
flatMap { $0.windows() }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// An extension
|
||||
extension Array where Element == String {
|
||||
|
||||
/// Get the C version of the array.
|
||||
@ -80,49 +26,3 @@ extension Array where Element == String {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// An extension
|
||||
extension Array {
|
||||
|
||||
/// Accesses the element at the specified position safely.
|
||||
/// - Parameters:
|
||||
/// - index: The position of the element to access.
|
||||
///
|
||||
/// Access and set elements the safe way:
|
||||
/// ```swift
|
||||
/// var array = ["Hello", "World"]
|
||||
/// print(array[safe: 2] ?? "Out of range")
|
||||
/// ```
|
||||
public subscript(safe index: Int?) -> Element? {
|
||||
get {
|
||||
if let index, indices.contains(index) {
|
||||
return self[index]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
set {
|
||||
if let index, let value = newValue, indices.contains(index) {
|
||||
self[index] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// An extension
|
||||
extension Array where Element: Identifiable {
|
||||
|
||||
/// Accesses the element with a certain id safely.
|
||||
/// - Parameters:
|
||||
/// - id: The child's id.
|
||||
///
|
||||
/// Access and set elements the safe way:
|
||||
/// ```swift
|
||||
/// var array = ["Hello", "World"]
|
||||
/// print(array[safe: 2] ?? "Out of range")
|
||||
/// ```
|
||||
public subscript(id id: Element.ID) -> Element? {
|
||||
self[safe: firstIndex { $0.id == id }]
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
// Created by david-swift on 15.01.24.
|
||||
//
|
||||
|
||||
// An extension
|
||||
extension Bool {
|
||||
|
||||
/// Get the gboolean for C.
|
||||
|
@ -5,14 +5,13 @@
|
||||
// Created by david-swift on 15.01.24.
|
||||
//
|
||||
|
||||
// An extension
|
||||
extension Int: Identifiable {
|
||||
extension Int: @retroactive Identifiable {
|
||||
|
||||
/// Get the integer itself as the identifier.
|
||||
public var id: Int { self }
|
||||
/// The C integer.
|
||||
public var cInt: Int32 {
|
||||
.init(self)
|
||||
.init(truncatingIfNeeded: self)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
// Created by david-swift on 15.01.23.
|
||||
//
|
||||
|
||||
// An extension
|
||||
extension OpaquePointer {
|
||||
|
||||
/// Convert an opaque pointer into an unsafe mutable pointer with a defined type.
|
||||
|
@ -5,7 +5,6 @@
|
||||
// Created by david-swift on 21.01.24.
|
||||
//
|
||||
|
||||
// An extension
|
||||
extension Set where Element == Edge {
|
||||
|
||||
/// Horizontal and vertical edges.
|
||||
|
@ -5,14 +5,11 @@
|
||||
// Created by david-swift on 09.09.23.
|
||||
//
|
||||
|
||||
// An extension
|
||||
extension String {
|
||||
|
||||
/// A label for main content in a view storage.
|
||||
static var mainContent: Self { "main" }
|
||||
/// A label for the transition data in a GTUI widget's fields.
|
||||
/// A label for the transition data in a widget's fields.
|
||||
static var transition: Self { "transition" }
|
||||
/// A label for the navigation label in a GTUI widget's fields.
|
||||
/// A label for the navigation label in a widget's fields.
|
||||
static var navigationLabel: Self { "navigation-label" }
|
||||
|
||||
/// Add the Ctrl key to a shortcut.
|
||||
|
@ -5,12 +5,11 @@
|
||||
// Created by david-swift on 19.01.24.
|
||||
//
|
||||
|
||||
// An extension
|
||||
extension UInt {
|
||||
|
||||
/// Convert an unsigned integer into the C form.
|
||||
public var cInt: UInt32 {
|
||||
.init(self)
|
||||
.init(truncatingIfNeeded: self)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
// Created by david-swift on 15.01.24.
|
||||
//
|
||||
|
||||
// An extension
|
||||
extension UnsafeMutablePointer {
|
||||
|
||||
/// Convert into an opaque pointer.
|
||||
|
@ -5,7 +5,6 @@
|
||||
// Created by david-swift on 15.01.24.
|
||||
//
|
||||
|
||||
// An extension
|
||||
extension UnsafeMutableRawPointer {
|
||||
|
||||
/// Convert into an unsafe mutable pointer of a certain type.
|
||||
|
24
Sources/Adwaita/Model/Extensions/ViewStorage.swift
Normal file
24
Sources/Adwaita/Model/Extensions/ViewStorage.swift
Normal file
@ -0,0 +1,24 @@
|
||||
//
|
||||
// ViewStorage.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 01.08.24.
|
||||
//
|
||||
|
||||
extension ViewStorage {
|
||||
|
||||
/// Modify the view.
|
||||
/// - Parameter modify: The modification function.
|
||||
public func modify(_ modify: (OpaquePointer?) -> Void) {
|
||||
modify(opaquePointer)
|
||||
}
|
||||
|
||||
/// Convert the pointer to a pointer of a certain type and modify the view.
|
||||
/// - Parameters:
|
||||
/// - type: The pointer's type.
|
||||
/// - modify: The modification function.
|
||||
public func modify<T>(_ type: T.Type, _ modify: (UnsafeMutablePointer<T>?) -> Void) {
|
||||
modify(opaquePointer?.cast())
|
||||
}
|
||||
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
// Idle.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 02.05.24.
|
||||
// Created by david-swift on 12.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
101
Sources/Adwaita/Model/Signals/SignalData.swift
Normal file
101
Sources/Adwaita/Model/Signals/SignalData.swift
Normal file
@ -0,0 +1,101 @@
|
||||
//
|
||||
// SignalData.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 31.07.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
/// Data to pass to signal handlers.
|
||||
public class SignalData {
|
||||
|
||||
/// The closure.
|
||||
public var closure: ([Any?]) -> 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([])
|
||||
}
|
||||
}
|
||||
|
||||
/// The closure as a C handler with three parameters.
|
||||
var threeParamsHandler: @convention(c) (
|
||||
UnsafeMutableRawPointer,
|
||||
UnsafeRawPointer?,
|
||||
UnsafeMutableRawPointer
|
||||
) -> Void {
|
||||
{ _, arg1, data in
|
||||
let data = unsafeBitCast(data, to: SignalData.self)
|
||||
data.closure([arg1])
|
||||
}
|
||||
}
|
||||
|
||||
/// The closure as a C handler with four parameters.
|
||||
var fourParamsHandler: @convention(c) (
|
||||
UnsafeMutableRawPointer,
|
||||
UnsafeRawPointer?,
|
||||
UnsafeRawPointer?,
|
||||
UnsafeMutableRawPointer
|
||||
) -> Void {
|
||||
{ _, arg1, arg2, data in
|
||||
let data = unsafeBitCast(data, to: SignalData.self)
|
||||
data.closure([arg1, arg2])
|
||||
}
|
||||
}
|
||||
|
||||
/// The closure as a C handler with five parameters.
|
||||
var fiveParamsHandler: @convention(c) (
|
||||
UnsafeMutableRawPointer,
|
||||
UnsafeRawPointer?,
|
||||
Double,
|
||||
Double,
|
||||
UnsafeMutableRawPointer
|
||||
) -> Void {
|
||||
{ _, arg1, arg2, arg3, data in
|
||||
let data = unsafeBitCast(data, to: SignalData.self)
|
||||
data.closure([arg1, arg2, arg3])
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize the signal data.
|
||||
/// - Parameter closure: The signal's closure.
|
||||
public convenience init(closure: @escaping () -> Void) {
|
||||
self.init { _ in closure() }
|
||||
}
|
||||
|
||||
/// Initialize the signal data.
|
||||
/// - Parameter closure: The signal's closure.
|
||||
public init(closure: @escaping ([Any]) -> Void) {
|
||||
self.closure = closure
|
||||
}
|
||||
|
||||
/// Connect the signal data to a signal.
|
||||
/// - Parameters:
|
||||
/// - 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) {
|
||||
let callback: GCallback
|
||||
if argCount >= 3 {
|
||||
callback = unsafeBitCast(fiveParamsHandler, to: GCallback.self)
|
||||
} else if argCount == 2 {
|
||||
callback = unsafeBitCast(fourParamsHandler, to: GCallback.self)
|
||||
} else if argCount == 1 {
|
||||
callback = unsafeBitCast(threeParamsHandler, to: GCallback.self)
|
||||
} else {
|
||||
callback = unsafeBitCast(handler, to: GCallback.self)
|
||||
}
|
||||
g_signal_connect_data(
|
||||
pointer,
|
||||
signal,
|
||||
callback,
|
||||
Unmanaged.passUnretained(self).toOpaque().cast(),
|
||||
nil,
|
||||
G_CONNECT_AFTER
|
||||
)
|
||||
}
|
||||
|
||||
}
|
82
Sources/Adwaita/Model/Storage.swift
Normal file
82
Sources/Adwaita/Model/Storage.swift
Normal file
@ -0,0 +1,82 @@
|
||||
//
|
||||
// WindowView.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 06.08.24.
|
||||
//
|
||||
|
||||
/// A storage type is a view storage or a scene storage.
|
||||
public protocol Storage: AnyObject {
|
||||
|
||||
/// The pointer.
|
||||
var opaquePointer: OpaquePointer? { get }
|
||||
/// Additional fields.
|
||||
var fields: [String: Any] { get set }
|
||||
|
||||
}
|
||||
|
||||
extension Storage {
|
||||
|
||||
/// Connect a handler to the observer of a property.
|
||||
/// - Parameters:
|
||||
/// - name: The property's name.
|
||||
/// - id: The handlers id to separate form others connecting to the signal.
|
||||
/// - pointer: A custom pointer instead of the stored one.
|
||||
/// - handler: The signal's handler.
|
||||
public func notify(
|
||||
name: String,
|
||||
id: String = "",
|
||||
pointer: OpaquePointer? = nil,
|
||||
handler: @escaping () -> Void
|
||||
) {
|
||||
let name = "notify::" + name
|
||||
connectSignal(name: name, id: id, argCount: 1, pointer: pointer, handler: handler)
|
||||
}
|
||||
|
||||
/// 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).
|
||||
/// - pointer: A custom pointer instead of the stored one.
|
||||
/// - handler: The signal's handler.
|
||||
public func connectSignal(
|
||||
name: String,
|
||||
id: String = "",
|
||||
argCount: Int = 0,
|
||||
pointer: OpaquePointer? = nil,
|
||||
handler: @escaping () -> Void
|
||||
) {
|
||||
connectSignal(name: name, id: id, argCount: argCount, pointer: pointer) { _ in
|
||||
handler()
|
||||
}
|
||||
}
|
||||
|
||||
/// 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).
|
||||
/// - pointer: A custom pointer instead of the stored one.
|
||||
/// - handler: The signal's handler.
|
||||
public func connectSignal(
|
||||
name: String,
|
||||
id: String = "",
|
||||
argCount: Int = 0,
|
||||
pointer: OpaquePointer? = nil,
|
||||
handler: @escaping ([Any]) -> Void
|
||||
) {
|
||||
if let data = fields[name + id] as? SignalData {
|
||||
data.closure = handler
|
||||
} else {
|
||||
let data = SignalData(closure: handler)
|
||||
fields[name + id] = data
|
||||
data.connect(pointer: (pointer ?? opaquePointer)?.cast(), signal: name, argCount: argCount)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension ViewStorage: Storage { }
|
||||
extension SceneStorage: Storage { }
|
@ -1,73 +0,0 @@
|
||||
//
|
||||
// App.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 05.08.23.
|
||||
//
|
||||
|
||||
/// A structure conforming to `App` is the entry point of your app.
|
||||
///
|
||||
/// ```swift
|
||||
/// @main
|
||||
/// struct Test: App {
|
||||
///
|
||||
/// let id = "io.github.AparokshaUI.TestApp"
|
||||
/// var app: GTUIApp!
|
||||
///
|
||||
/// var scene: Scene {
|
||||
/// WindowScene()
|
||||
/// }
|
||||
///
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
public protocol App {
|
||||
|
||||
/// The app's application ID.
|
||||
var id: String { get }
|
||||
|
||||
/// The app's windows.
|
||||
@SceneBuilder var scene: Scene { get }
|
||||
// swiftlint:disable implicitly_unwrapped_optional
|
||||
/// The app.
|
||||
var app: GTUIApp! { get set }
|
||||
// swiftlint:enable implicitly_unwrapped_optional
|
||||
|
||||
/// An app has to have an `init()` initializer.
|
||||
init()
|
||||
|
||||
}
|
||||
|
||||
/// An extension
|
||||
extension App {
|
||||
|
||||
/// The application's entry point.
|
||||
public static func main() {
|
||||
let app = setupApp()
|
||||
app.run()
|
||||
}
|
||||
|
||||
/// Initialize and get the GTUI app.
|
||||
///
|
||||
/// To run the app, call the ``GTUIApp/run(automaticSetup:manualSetup:)`` function.
|
||||
public static func setupApp() -> GTUIApp {
|
||||
var appInstance = self.init()
|
||||
appInstance.app = GTUIApp(appInstance.id) { appInstance }
|
||||
GTUIApp.updateHandlers.append { force in
|
||||
var removeIndices: [Int] = []
|
||||
for (index, window) in appInstance.app.sceneStorage.enumerated() {
|
||||
if window.destroy {
|
||||
removeIndices.insert(index, at: 0)
|
||||
} else if let scene = appInstance.scene.windows().first(where: { $0.id == window.id }) {
|
||||
scene.update(window, app: appInstance.app, force: force)
|
||||
}
|
||||
}
|
||||
for index in removeIndices {
|
||||
appInstance.app.sceneStorage.remove(at: index)
|
||||
}
|
||||
}
|
||||
GTUIApp.appID = appInstance.id
|
||||
return appInstance.app
|
||||
}
|
||||
|
||||
}
|
@ -1,160 +0,0 @@
|
||||
//
|
||||
// GTUIApp.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 05.08.23.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
/// The GTUI application.
|
||||
public class GTUIApp {
|
||||
|
||||
/// The handlers which are called when a state changes.
|
||||
static var updateHandlers: [(Bool) -> Void] = []
|
||||
/// The app's id for the file name for storing the data.
|
||||
static var appID: String?
|
||||
/// The pointer to the application.
|
||||
public var pointer: UnsafeMutablePointer<GtkApplication>?
|
||||
/// Fields for additional information.
|
||||
public var fields: [String: Any] = [:]
|
||||
|
||||
/// The app's content.
|
||||
var body: () -> App
|
||||
/// The scenes that are displayed.
|
||||
var sceneStorage: [WindowStorage] = []
|
||||
/// A string signaling that the parent should not be overwritten.
|
||||
let overwriteParentID = "overwrite-parent"
|
||||
|
||||
/// Initialize the GTUI application.
|
||||
/// - Parameters:
|
||||
/// - id: The application id.
|
||||
/// - body: The application's content.
|
||||
init(_ id: String, body: @escaping () -> App) {
|
||||
self.body = body
|
||||
self.pointer = adw_application_new(id, G_APPLICATION_DEFAULT_FLAGS)?.cast()
|
||||
}
|
||||
|
||||
/// The entry point of the application.
|
||||
public func onActivate() {
|
||||
let body = body()
|
||||
for windowScene in body.scene.windows() {
|
||||
for _ in 0..<windowScene.open {
|
||||
addWindow(windowScene.id)
|
||||
}
|
||||
setParentWindows()
|
||||
}
|
||||
}
|
||||
|
||||
/// Run the application.
|
||||
/// - Parameters:
|
||||
/// - automaticSetup: Whether the initial windows should be added.
|
||||
/// - manualSetup: A closure that is executed in the main loop.
|
||||
public func run(automaticSetup: Bool = true, manualSetup: @escaping () -> Void = { }) {
|
||||
let data = ViewStorage.SignalData {
|
||||
if automaticSetup {
|
||||
self.onActivate()
|
||||
}
|
||||
manualSetup()
|
||||
}
|
||||
fields["run"] = data
|
||||
g_signal_connect_data(
|
||||
pointer?.cast(),
|
||||
"activate",
|
||||
unsafeBitCast(data.handler, to: GCallback.self),
|
||||
Unmanaged.passUnretained(data).toOpaque().cast(),
|
||||
nil,
|
||||
G_CONNECT_AFTER
|
||||
)
|
||||
g_application_run(pointer?.cast(), 0, nil)
|
||||
}
|
||||
|
||||
/// Add a keyboard shortcut to the application.
|
||||
/// - Parameters:
|
||||
/// - shortcut: The keyboard shortcut.
|
||||
/// - id: The action's id.
|
||||
/// - window: Optionally an application window.
|
||||
/// - handler: The action's handler.
|
||||
public func addKeyboardShortcut(
|
||||
_ shortcut: String,
|
||||
id: String,
|
||||
window: GTUIApplicationWindow? = nil,
|
||||
handler: @escaping () -> Void
|
||||
) {
|
||||
let action = g_simple_action_new(id, nil)
|
||||
let data = ViewStorage.SignalData(closure: handler)
|
||||
g_signal_connect_data(
|
||||
action?.cast(),
|
||||
"activate",
|
||||
unsafeBitCast(data.threeParamsHandler, to: GCallback.self),
|
||||
Unmanaged.passUnretained(data).toOpaque().cast(),
|
||||
nil,
|
||||
G_CONNECT_AFTER
|
||||
)
|
||||
if let window {
|
||||
g_action_map_add_action(.init(window.pointer), action)
|
||||
window.fields[id] = data
|
||||
} else {
|
||||
g_action_map_add_action(.init(pointer), action)
|
||||
fields[id] = data
|
||||
}
|
||||
gtk_application_set_accels_for_action(pointer, (window == nil ? "app." : "win.") + id, [shortcut].cArray)
|
||||
}
|
||||
|
||||
/// Remove a keyboard shortcut from the application.
|
||||
/// - Parameters:
|
||||
/// - id: The keyboard shortcut's id.
|
||||
/// - window: Optionally an application window.
|
||||
public func removeKeyboardShortcut(
|
||||
id: String,
|
||||
window: GTUIApplicationWindow? = nil
|
||||
) {
|
||||
if let window {
|
||||
g_action_map_remove_action(.init(window.pointer), id)
|
||||
window.fields.removeValue(forKey: id)
|
||||
} else {
|
||||
g_action_map_remove_action(.init(pointer), id)
|
||||
fields.removeValue(forKey: id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Focus the window with a certain id. Create the window if it doesn't already exist.
|
||||
/// - Parameters:
|
||||
/// - id: The window's id.
|
||||
public func showWindow(_ id: String) {
|
||||
sceneStorage.last { $0.id == id && !$0.destroy }?.window.show() ?? addWindow(id)
|
||||
}
|
||||
|
||||
/// Add a new window with the content of the window with a certain id.
|
||||
/// - Parameters:
|
||||
/// - id: The window's id.
|
||||
/// - parent: The parent window.
|
||||
public func addWindow(_ id: String, parent: GTUIWindow? = nil) {
|
||||
State<Any>.updateViews()
|
||||
if let window = body().scene.windows().last(where: { $0.id == id }) {
|
||||
let window = window.createWindow(app: self)
|
||||
sceneStorage.append(window)
|
||||
if let parent {
|
||||
window.window.setParentWindow(parent)
|
||||
window.window.fields[overwriteParentID] = true
|
||||
}
|
||||
setParentWindows()
|
||||
showWindow(id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the parents of every window having a parent window.
|
||||
func setParentWindows() {
|
||||
for window in sceneStorage where !(window.window.fields[overwriteParentID] as? Bool ?? false) {
|
||||
if let parent = sceneStorage.first(where: { $0.id == window.parentID }) {
|
||||
window.window.setParentWindow(parent.window)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Terminate the application.
|
||||
public func quit() {
|
||||
g_application_quit(pointer?.cast())
|
||||
}
|
||||
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
//
|
||||
// MenuItem.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 22.10.23.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
/// A structure representing the content for a certain menu item type.
|
||||
public protocol MenuItem: MenuItemGroup {
|
||||
|
||||
/// Add the menu item to a certain menu.
|
||||
/// - Parameters:
|
||||
/// - menu: The menu.
|
||||
/// - app: The application containing the menu.
|
||||
/// - window: The application window containing the menu.
|
||||
func addMenuItem(menu: OpaquePointer?, app: GTUIApp, window: GTUIApplicationWindow?)
|
||||
|
||||
}
|
||||
|
||||
/// An extension
|
||||
extension MenuItem {
|
||||
|
||||
/// The menu item's content is itself.
|
||||
@MenuBuilder public var content: MenuContent { self }
|
||||
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
//
|
||||
// MenuItemGroup.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 22.10.23.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
/// A structure conforming to `MenuItemGroup` can be added to the content accepting a menu.
|
||||
public protocol MenuItemGroup {
|
||||
|
||||
/// The menu's content.
|
||||
@MenuBuilder var content: MenuContent { get }
|
||||
|
||||
}
|
||||
|
||||
/// An extension
|
||||
extension MenuItemGroup {
|
||||
|
||||
/// Add the menu items described by the group to a menu.
|
||||
/// - Parameter menu: The menu.
|
||||
func addMenuItems(menu: OpaquePointer?, app: GTUIApp, window: GTUIApplicationWindow?) {
|
||||
for element in content {
|
||||
if let item = element as? MenuItem {
|
||||
item.addMenuItem(menu: menu, app: app, window: window)
|
||||
} else {
|
||||
element.addMenuItems(menu: menu, app: app, window: window)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// `MenuContent` is an array of menu item groups.
|
||||
public typealias MenuContent = [MenuItemGroup]
|
||||
/// A builder for the `MenuContent`
|
||||
public typealias MenuBuilder = ArrayBuilder<MenuItemGroup>
|
@ -1,91 +0,0 @@
|
||||
//
|
||||
// View.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 05.08.23.
|
||||
//
|
||||
|
||||
/// A structure conforming to `View` is referred to as a view.
|
||||
/// It can be part of a body.
|
||||
///
|
||||
/// ```swift
|
||||
/// struct Test: View {
|
||||
///
|
||||
/// var view: Body {
|
||||
/// AnotherView()
|
||||
/// }
|
||||
///
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
public protocol View {
|
||||
|
||||
/// The view's content.
|
||||
@ViewBuilder var view: Body { get }
|
||||
|
||||
}
|
||||
|
||||
/// An extension
|
||||
extension View {
|
||||
|
||||
/// Wrap the view into a widget.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// - Returns: The widget.
|
||||
public func widget(modifiers: [(View) -> View]) -> Widget {
|
||||
let modified = getModified(modifiers: modifiers)
|
||||
if let peer = modified as? Widget {
|
||||
return peer
|
||||
} else {
|
||||
return StateWrapper(content: { view }, state: getState())
|
||||
}
|
||||
}
|
||||
|
||||
/// Update a storage to a view.
|
||||
/// - Parameters:
|
||||
/// - storage: The storage.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - updateProperties: Whether to update properties.
|
||||
public func updateStorage(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
let modified = getModified(modifiers: modifiers)
|
||||
if let widget = modified as? Widget {
|
||||
widget.update(storage, modifiers: modifiers, updateProperties: updateProperties)
|
||||
} else {
|
||||
StateWrapper(content: { view }, state: getState())
|
||||
.update(storage, modifiers: modifiers, updateProperties: updateProperties)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the state.
|
||||
/// - Returns: The state.
|
||||
func getState() -> [String: StateProtocol] {
|
||||
var state: [String: StateProtocol] = [:]
|
||||
for property in Mirror(reflecting: self).children {
|
||||
if let label = property.label, let value = property.value as? StateProtocol {
|
||||
state[label] = value
|
||||
}
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
/// Get a storage.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// - Returns: The storage.
|
||||
public func storage(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
}
|
||||
|
||||
/// Get the modified view.
|
||||
/// - Parameter modifiers: The modifiers.
|
||||
/// - Returns: The modified view.
|
||||
func getModified(modifiers: [(View) -> View]) -> View {
|
||||
var modified: View = self
|
||||
for modifier in modifiers {
|
||||
modified = modifier(modified)
|
||||
}
|
||||
return modified
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// `Body` is an array of views.
|
||||
public typealias Body = [View]
|
@ -1,99 +0,0 @@
|
||||
//
|
||||
// ViewBuilder.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 05.08.23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// The ``ViewBuilder`` is a result builder for views.
|
||||
@resultBuilder
|
||||
public enum ViewBuilder {
|
||||
|
||||
/// A component used in the ``ArrayBuilder``.
|
||||
public enum Component {
|
||||
|
||||
/// A view as a component.
|
||||
case element(_: View)
|
||||
/// An array of components as a component.
|
||||
case components(_: [Self])
|
||||
|
||||
}
|
||||
|
||||
/// Build combined results from statement blocks.
|
||||
/// - Parameter components: The components.
|
||||
/// - Returns: The components in a component.
|
||||
public static func buildBlock(_ elements: Component...) -> Component {
|
||||
.components(elements)
|
||||
}
|
||||
|
||||
/// Translate an element into a ``ViewBuilder.Component``.
|
||||
/// - Parameter element: The element to translate.
|
||||
/// - Returns: A component created from the element.
|
||||
public static func buildExpression(_ element: View) -> Component {
|
||||
.element(element)
|
||||
}
|
||||
|
||||
/// Translate an array of elements into a ``ViewBuilder.Component``.
|
||||
/// - Parameter elements: The elements to translate.
|
||||
/// - Returns: A component created from the element.
|
||||
public static func buildExpression(_ elements: [View]) -> Component {
|
||||
var components: [Component] = []
|
||||
for element in elements {
|
||||
components.append(.element(element))
|
||||
}
|
||||
return .components(components)
|
||||
}
|
||||
|
||||
/// Fetch a component.
|
||||
/// - Parameter component: A component.
|
||||
/// - Returns: The component.
|
||||
public static func buildExpression(_ component: Component) -> Component {
|
||||
component
|
||||
}
|
||||
|
||||
/// Enables support for `if` statements without an `else`.
|
||||
/// - Parameter component: An optional component.
|
||||
/// - Returns: A nonoptional component.
|
||||
public static func buildOptional(_ component: Component?) -> Component {
|
||||
.element(
|
||||
Bin()
|
||||
.child {
|
||||
if let component {
|
||||
buildFinalResult(component)
|
||||
} else {
|
||||
[]
|
||||
}
|
||||
}
|
||||
.visible(component != nil)
|
||||
)
|
||||
}
|
||||
|
||||
/// Enables support for `if`-`else` and `switch` statements.
|
||||
/// - Parameter component: A component.
|
||||
/// - Returns: The component.
|
||||
public static func buildEither(first component: Component) -> Component {
|
||||
.element(ViewStack(id: true) { _ in buildFinalResult(component) })
|
||||
}
|
||||
|
||||
/// Enables support for `if`-`else` and `switch` statements.
|
||||
/// - Parameter component: A component.
|
||||
/// - Returns: The component.
|
||||
public static func buildEither(second component: Component) -> Component {
|
||||
.element(ViewStack(id: false) { _ in buildFinalResult(component) })
|
||||
}
|
||||
|
||||
/// Convert a component to an array of elements.
|
||||
/// - Parameter component: The component to convert.
|
||||
/// - Returns: The generated array of elements.
|
||||
public static func buildFinalResult(_ component: Component) -> [View] {
|
||||
switch component {
|
||||
case let .element(element):
|
||||
return [element]
|
||||
case let .components(components):
|
||||
return components.flatMap { buildFinalResult($0) }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,197 +0,0 @@
|
||||
//
|
||||
// ViewStorage.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 31.08.23.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
/// Store a rendered view in a view storage.
|
||||
public class ViewStorage {
|
||||
|
||||
/// The pointer.
|
||||
public var pointer: OpaquePointer?
|
||||
/// The view's content.
|
||||
public var content: [String: [ViewStorage]]
|
||||
/// The view's state (used in `StateWrapper`).
|
||||
public var state: [String: StateProtocol]
|
||||
/// The signal handlers.
|
||||
public var handlers: [String: SignalData] = [:]
|
||||
/// Other properties.
|
||||
public var fields: [String: Any] = [:]
|
||||
|
||||
/// Initialize a view storage.
|
||||
/// - Parameters:
|
||||
/// - pointer: The pointer to the Gtk widget.
|
||||
/// - content: The view's content.
|
||||
/// - state: The view's state.
|
||||
public init(
|
||||
_ pointer: OpaquePointer?,
|
||||
content: [String: [ViewStorage]] = [:],
|
||||
state: [String: StateProtocol] = [:]
|
||||
) {
|
||||
self.pointer = pointer
|
||||
self.content = content
|
||||
self.state = state
|
||||
}
|
||||
|
||||
/// Data to pass to signal handlers.
|
||||
public class SignalData {
|
||||
|
||||
/// The closure.
|
||||
public var closure: ([Any]) -> 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([])
|
||||
}
|
||||
}
|
||||
|
||||
/// The closure as a C handler with three parameters.
|
||||
var threeParamsHandler: @convention(c) (
|
||||
UnsafeMutableRawPointer,
|
||||
UnsafeRawPointer?,
|
||||
UnsafeMutableRawPointer
|
||||
) -> Void {
|
||||
{ _, arg1, data in
|
||||
let data = unsafeBitCast(data, to: SignalData.self)
|
||||
data.closure([arg1])
|
||||
}
|
||||
}
|
||||
|
||||
/// The closure as a C handler with four parameters.
|
||||
var fourParamsHandler: @convention(c) (
|
||||
UnsafeMutableRawPointer,
|
||||
UnsafeRawPointer?,
|
||||
UnsafeRawPointer?,
|
||||
UnsafeMutableRawPointer
|
||||
) -> Void {
|
||||
{ _, arg1, arg2, data in
|
||||
let data = unsafeBitCast(data, to: SignalData.self)
|
||||
data.closure([arg1, arg2])
|
||||
}
|
||||
}
|
||||
|
||||
/// The closure as a C handler with five parameters.
|
||||
var fiveParamsHandler: @convention(c) (
|
||||
UnsafeMutableRawPointer,
|
||||
UnsafeRawPointer?,
|
||||
Double,
|
||||
Double,
|
||||
UnsafeMutableRawPointer
|
||||
) -> Void {
|
||||
{ _, arg1, arg2, arg3, data in
|
||||
let data = unsafeBitCast(data, to: SignalData.self)
|
||||
data.closure([arg1, arg2, arg3])
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize the signal data.
|
||||
/// - Parameter closure: The signal's closure.
|
||||
public convenience init(closure: @escaping () -> Void) {
|
||||
self.init { _ in closure() }
|
||||
}
|
||||
|
||||
/// Initialize the signal data.
|
||||
/// - Parameter closure: The signal's closure.
|
||||
public init(closure: @escaping ([Any]) -> Void) {
|
||||
self.closure = closure
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Connect a handler to the observer of a property.
|
||||
/// - Parameters:
|
||||
/// - name: The property's name.
|
||||
/// - id: The handlers id to separate form others connecting to the signal.
|
||||
/// - connectFlags: The GConnectFlags.
|
||||
/// - handler: The signal's handler.
|
||||
public func notify(
|
||||
name: String,
|
||||
id: String = "",
|
||||
connectFlags: GConnectFlags = G_CONNECT_AFTER,
|
||||
handler: @escaping () -> Void
|
||||
) {
|
||||
let name = "notify::" + name
|
||||
connectSignal(name: name, id: id, connectFlags: connectFlags, argCount: 1, handler: handler)
|
||||
}
|
||||
|
||||
/// 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).
|
||||
/// - handler: The signal's handler.
|
||||
public func connectSignal(
|
||||
name: String,
|
||||
id: String = "",
|
||||
connectFlags: GConnectFlags = G_CONNECT_AFTER,
|
||||
argCount: Int = 0,
|
||||
handler: @escaping () -> Void
|
||||
) {
|
||||
connectSignal(name: name, id: id, connectFlags: connectFlags, argCount: argCount) { _ in
|
||||
handler()
|
||||
}
|
||||
}
|
||||
|
||||
/// 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).
|
||||
/// - handler: The signal's handler.
|
||||
public func connectSignal(
|
||||
name: String,
|
||||
id: String = "",
|
||||
connectFlags: GConnectFlags = G_CONNECT_AFTER,
|
||||
argCount: Int = 0,
|
||||
handler: @escaping ([Any]) -> Void
|
||||
) {
|
||||
if let data = handlers[name + id] {
|
||||
data.closure = handler
|
||||
} else {
|
||||
let data = SignalData(closure: handler)
|
||||
handlers[name + id] = data
|
||||
let callback: GCallback
|
||||
let three = 3
|
||||
let two = 2
|
||||
if argCount >= three {
|
||||
callback = unsafeBitCast(data.fiveParamsHandler, to: GCallback.self)
|
||||
} else if argCount == two {
|
||||
callback = unsafeBitCast(data.fourParamsHandler, to: GCallback.self)
|
||||
} else if argCount == 1 {
|
||||
callback = unsafeBitCast(data.threeParamsHandler, to: GCallback.self)
|
||||
} else {
|
||||
callback = unsafeBitCast(data.handler, to: GCallback.self)
|
||||
}
|
||||
g_signal_connect_data(
|
||||
pointer?.cast(),
|
||||
name,
|
||||
callback,
|
||||
Unmanaged.passUnretained(data).toOpaque().cast(),
|
||||
nil,
|
||||
connectFlags
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Modify the view.
|
||||
/// - Parameter modify: The modification function.
|
||||
public func modify(_ modify: (OpaquePointer?) -> Void) {
|
||||
modify(pointer)
|
||||
}
|
||||
|
||||
/// Convert the pointer to a pointer of a certain type and modify the view.
|
||||
/// - Parameters:
|
||||
/// - type: The pointer's type.
|
||||
/// - modify: The modification function.
|
||||
public func modify<T>(_ type: T.Type, _ modify: (UnsafeMutablePointer<T>?) -> Void) {
|
||||
modify(pointer?.cast())
|
||||
}
|
||||
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
//
|
||||
// Widget.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 16.08.23.
|
||||
//
|
||||
|
||||
/// A widget is a view that know about its GTUI widget.
|
||||
public protocol Widget: View {
|
||||
|
||||
/// The view storage.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
func container(modifiers: [(View) -> View]) -> ViewStorage
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool)
|
||||
|
||||
}
|
||||
|
||||
/// An extension
|
||||
extension Widget {
|
||||
|
||||
/// A widget's view is empty.
|
||||
public var view: Body { [] }
|
||||
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
//
|
||||
// GTUIAboutWindow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 21.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
/// A GTUI about window.
|
||||
public class GTUIAboutWindow: GTUIWindow {
|
||||
|
||||
/// Initialize an about window using the AppStream metadata.
|
||||
/// - Parameter filePath: The path.
|
||||
public init(filePath: String? = nil) {
|
||||
super.init(fields: [:])
|
||||
if let filePath {
|
||||
#if os(Windows)
|
||||
pointer = adw_about_window_new()?.cast()
|
||||
#else
|
||||
pointer = adw_about_window_new_from_appdata(filePath, nil)?.cast()
|
||||
#endif
|
||||
} else {
|
||||
pointer = adw_about_window_new()?.cast()
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the general data.
|
||||
/// - Parameters:
|
||||
/// - title: The app name.
|
||||
/// - icon: The app icon.
|
||||
/// - developer: The app's developer.
|
||||
/// - version: The app's version.
|
||||
public func generalData(title: String, icon: Icon, developer: String, version: String) {
|
||||
adw_about_window_set_application_name(.init(pointer), title)
|
||||
adw_about_window_set_application_icon(.init(pointer), icon.string)
|
||||
adw_about_window_set_developer_name(.init(pointer), developer)
|
||||
adw_about_window_set_version(.init(pointer), version)
|
||||
}
|
||||
|
||||
/// Set the website.
|
||||
/// - Parameter url: The website.
|
||||
public func website(url: String) {
|
||||
adw_about_window_set_website(.init(pointer), url)
|
||||
}
|
||||
|
||||
/// Set the URL for issues.
|
||||
/// - Parameter issues: The issues website.
|
||||
public func issues(url: String) {
|
||||
adw_about_window_set_issue_url(.init(pointer), url)
|
||||
}
|
||||
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
//
|
||||
// GTUIApplicationWindow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 19.10.23.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
/// A GTUI application window.
|
||||
public class GTUIApplicationWindow: GTUIWindow {
|
||||
|
||||
/// The window's parent app.
|
||||
public var app: GTUIApp
|
||||
|
||||
/// Initialize the application window.
|
||||
/// - Parameter app: The application.
|
||||
public init(app: GTUIApp) {
|
||||
self.app = app
|
||||
super.init(fields: [:])
|
||||
pointer = adw_application_window_new(app.pointer)?.cast()
|
||||
}
|
||||
|
||||
/// Add a keyboard shortcut.
|
||||
/// - Parameters:
|
||||
/// - shortcut: The keyboard shortcut.
|
||||
/// - id: The action's id.
|
||||
/// - handler: The action's handler.
|
||||
public func addKeyboardShortcut(_ shortcut: String, id: String, handler: @escaping () -> Void) {
|
||||
app.addKeyboardShortcut(shortcut, id: id, window: self, handler: handler)
|
||||
}
|
||||
|
||||
/// Remove a keyboard shortcut.
|
||||
/// - Parameters:
|
||||
/// - id: The action's id.
|
||||
public func removeKeyboardShortcut(id: String) {
|
||||
app.removeKeyboardShortcut(id: id, window: self)
|
||||
}
|
||||
|
||||
/// Set the window's child.
|
||||
/// - Parameter child: The child.
|
||||
override public func setChild(_ child: OpaquePointer?) {
|
||||
adw_application_window_set_content(pointer?.cast(), child?.cast())
|
||||
}
|
||||
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
//
|
||||
// GTUIFileDialog.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 09.12.23.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import Foundation
|
||||
|
||||
/// A GTUI file dialog window.
|
||||
public class GTUIFileDialog: WindowType {
|
||||
|
||||
/// The file dialog's pointer.
|
||||
public var pointer: OpaquePointer?
|
||||
/// Fields for additional data.
|
||||
public var fields: [String: Any] = [:]
|
||||
/// A link to the file dialog.
|
||||
var selfAddr: UInt64 {
|
||||
unsafeBitCast(self, to: UInt64.self)
|
||||
}
|
||||
/// The parent window.
|
||||
var parent: OpaquePointer?
|
||||
/// Whether the file dialog is an importer.
|
||||
var isImporter = false
|
||||
/// The selected folder in the file dialog.
|
||||
var folder: URL?
|
||||
/// A closure triggered on selecting a file in the dialog.
|
||||
var onResult: (URL) -> Void = { _ in }
|
||||
/// A closure triggered when the dialog is canceled.
|
||||
var onCancel: () -> Void = { }
|
||||
|
||||
/// Initialize the window.
|
||||
public init() {
|
||||
pointer = gtk_file_dialog_new()
|
||||
}
|
||||
|
||||
/// Set the window's parent window.
|
||||
/// - Parameter parent: The parent window.
|
||||
public func setParentWindow(_ parent: WindowType) {
|
||||
if let window = parent as? GTUIWindow {
|
||||
self.parent = .init(window.pointer)
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the initial name.
|
||||
/// - Parameter name: The parent window.
|
||||
public func setInitialName(_ name: String) {
|
||||
gtk_file_dialog_set_initial_name(pointer, name)
|
||||
}
|
||||
|
||||
// swiftlint:disable discouraged_optional_collection
|
||||
/// Set the allowed file extensions.
|
||||
/// - Parameters:
|
||||
/// - extensions: The file extensions.
|
||||
public func setExtensions(_ extensions: [String]?) {
|
||||
if let 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)
|
||||
} else {
|
||||
gtk_file_dialog_set_default_filter(pointer, nil)
|
||||
}
|
||||
}
|
||||
// swiftlint:enable discouraged_optional_collection
|
||||
|
||||
/// Display the file dialog.
|
||||
public func show() {
|
||||
if let folder {
|
||||
gtk_file_dialog_set_initial_folder(pointer, g_file_new_for_path(folder.absoluteString))
|
||||
}
|
||||
if isImporter {
|
||||
gtui_filedialog_open(UInt64(Int(bitPattern: pointer)), selfAddr, UInt64(Int(bitPattern: parent)))
|
||||
} else {
|
||||
gtui_filedialog_save(UInt64(Int(bitPattern: pointer)), selfAddr, UInt64(Int(bitPattern: parent)))
|
||||
}
|
||||
}
|
||||
|
||||
/// Run this when a file gets opened.
|
||||
/// - Parameter path: The file path.
|
||||
func onOpen(_ path: String) {
|
||||
let url = URL(fileURLWithPath: path)
|
||||
onResult(url)
|
||||
}
|
||||
|
||||
/// Run this when a file gets saved.
|
||||
/// - Parameter path: The file path.
|
||||
func onSave(_ path: String) {
|
||||
let url = URL(fileURLWithPath: path)
|
||||
onResult(url)
|
||||
}
|
||||
|
||||
/// Run this when the user cancels the action.
|
||||
func onClose() {
|
||||
onCancel()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Run when a file should be opened.
|
||||
/// - Parameters:
|
||||
/// - ptr: The pointer.
|
||||
/// - file: The path to the file.
|
||||
/// - userData: The file dialog data.
|
||||
@_cdecl("filedialog_on_open_cb")
|
||||
func filedialog_on_open_cb(
|
||||
ptr: UnsafeMutableRawPointer,
|
||||
file: UnsafePointer<CChar>?,
|
||||
userData: UnsafeMutableRawPointer
|
||||
) {
|
||||
let dialog = Unmanaged<GTUIFileDialog>.fromOpaque(userData).takeUnretainedValue()
|
||||
if let file {
|
||||
dialog.onOpen(.init(cString: file))
|
||||
} else {
|
||||
dialog.onClose()
|
||||
}
|
||||
}
|
||||
|
||||
/// Run when a file should be saved.
|
||||
/// - Parameters:
|
||||
/// - ptr: The pointer.
|
||||
/// - file: The path to the file.
|
||||
/// - userData: The file dialog data.
|
||||
@_cdecl("filedialog_on_save_cb")
|
||||
func filedialog_on_save_cb(
|
||||
ptr: UnsafeMutableRawPointer,
|
||||
file: UnsafePointer<CChar>?,
|
||||
userData: UnsafeMutableRawPointer
|
||||
) {
|
||||
let dialog = Unmanaged<GTUIFileDialog>.fromOpaque(userData).takeUnretainedValue()
|
||||
if let file {
|
||||
dialog.onSave(.init(cString: file))
|
||||
} else {
|
||||
dialog.onClose()
|
||||
}
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
//
|
||||
// GTUIWindow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 12.10.23.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
/// A GTUI window.
|
||||
public class GTUIWindow: WindowType {
|
||||
|
||||
/// The window's pointer.
|
||||
public var pointer: UnsafeMutablePointer<GtkWindow>?
|
||||
/// Fields for additional information.
|
||||
public var fields: [String: Any] = [:]
|
||||
|
||||
/// Initialize the window.
|
||||
public init() {
|
||||
pointer = adw_window_new()?.cast()
|
||||
}
|
||||
|
||||
/// Initialize the window, but not the pointer.
|
||||
/// - Parameter fields: The fields.
|
||||
init(fields: [String: Any]) {
|
||||
self.fields = fields
|
||||
}
|
||||
|
||||
/// Set the default window size.
|
||||
/// - Parameters:
|
||||
/// - width: The width.
|
||||
/// - height: The height.
|
||||
public func setDefaultSize(width: Int?, height: Int?) {
|
||||
gtk_window_set_default_size(pointer, width?.cInt ?? -1, height?.cInt ?? -1)
|
||||
}
|
||||
|
||||
/// Set the resizability.
|
||||
/// - Parameter resizable: Whether the window is resizable.
|
||||
public func setResizability(_ resizable: Bool) {
|
||||
gtk_window_set_resizable(pointer, resizable.cBool)
|
||||
}
|
||||
|
||||
/// Set the deletability.
|
||||
/// - Parameter deletable: Whether the window is deletable.
|
||||
public func setDeletability(_ deletable: Bool) {
|
||||
gtk_window_set_deletable(pointer, deletable.cBool)
|
||||
}
|
||||
|
||||
/// Set the window title.
|
||||
/// - Parameter title: The window's title.
|
||||
public func setTitle(_ title: String) {
|
||||
gtk_window_set_title(pointer, title)
|
||||
}
|
||||
|
||||
/// Set the window's child.
|
||||
/// - Parameter child: The child.
|
||||
public func setChild(_ child: OpaquePointer?) {
|
||||
gtk_window_set_child(pointer, child?.cast())
|
||||
}
|
||||
|
||||
/// Present the window.
|
||||
public func show() {
|
||||
gtk_window_present(pointer)
|
||||
}
|
||||
|
||||
/// Observe when the window is being closed.
|
||||
/// - Parameter observer: The signal closure.
|
||||
public func observeHide(observer: @escaping () -> Void) {
|
||||
let hideObserver = ViewStorage.SignalData(closure: observer)
|
||||
self.fields["observe-hide"] = hideObserver
|
||||
g_signal_connect_data(
|
||||
pointer?.cast(),
|
||||
"destroy",
|
||||
unsafeBitCast(hideObserver.handler, to: GCallback.self),
|
||||
Unmanaged.passUnretained(hideObserver).toOpaque().cast(),
|
||||
nil,
|
||||
G_CONNECT_AFTER
|
||||
)
|
||||
}
|
||||
|
||||
/// Close the window.
|
||||
public func close() {
|
||||
gtk_window_close(pointer)
|
||||
}
|
||||
|
||||
/// Set the window's parent window.
|
||||
/// - Parameter parent: The parent window.
|
||||
public func setParentWindow(_ parent: WindowType) {
|
||||
// swiftlint:disable prefer_self_in_static_references
|
||||
if let window = parent as? GTUIWindow {
|
||||
gtk_window_set_modal(pointer, 1)
|
||||
gtk_window_set_transient_for(pointer, window.pointer)
|
||||
}
|
||||
// swiftlint:enable prefer_self_in_static_references
|
||||
}
|
||||
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
//
|
||||
// WindowScene.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 05.08.23.
|
||||
//
|
||||
|
||||
/// A structure representing the content for a certain window type.
|
||||
public protocol WindowScene: WindowSceneGroup {
|
||||
|
||||
/// The window type's identifier.
|
||||
var id: String { get }
|
||||
/// The identifier of the window's parent window.
|
||||
var parentID: String? { get set }
|
||||
/// The number of instances of the window at the startup.
|
||||
var `open`: Int { get }
|
||||
/// The keyboard shortcuts on the application's level.
|
||||
var appShortcuts: [String: (GTUIApp) -> Void] { get set }
|
||||
/// Get the storage for the window.
|
||||
/// - Parameter app: The application.
|
||||
/// - Returns: The storage.
|
||||
func createWindow(app: GTUIApp) -> WindowStorage
|
||||
/// Update a window storage's content.
|
||||
/// - Parameters:
|
||||
/// - storage: The storage to update.
|
||||
/// - app: The application.
|
||||
/// - force: Whether to force update all the views.
|
||||
func update(_ storage: WindowStorage, app: GTUIApp, force: Bool)
|
||||
|
||||
}
|
||||
|
||||
/// An extension
|
||||
extension WindowScene {
|
||||
|
||||
/// The window scene's body is itself.
|
||||
@SceneBuilder public var scene: Scene { self }
|
||||
|
||||
/// Add a keyboard shortcut that is available for the whole app.
|
||||
/// - Parameters:
|
||||
/// - shortcut: The keyboard shortcut.
|
||||
/// - The closure to execute.
|
||||
public func appKeyboardShortcut(_ shortcut: String, action: @escaping (GTUIApp) -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.appShortcuts[shortcut] = action
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Update the app shortcuts.
|
||||
///
|
||||
/// Call this function in types of window scene.
|
||||
public func updateAppShortcuts(app: GTUIApp) {
|
||||
for shortcut in appShortcuts {
|
||||
app.addKeyboardShortcut(shortcut.key, id: shortcut.key) { shortcut.value(app) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Add the shortcut "<Ctrl>q" which terminates the application.
|
||||
/// - Returns: The app.
|
||||
public func quitShortcut() -> Self {
|
||||
appKeyboardShortcut("q".ctrl()) { $0.quit() }
|
||||
}
|
||||
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
//
|
||||
// WindowSceneGroup.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 14.09.23.
|
||||
//
|
||||
|
||||
/// A structure conforming to `WindowScene` can be added to an app's `scene`.
|
||||
public protocol WindowSceneGroup {
|
||||
|
||||
/// The group's content.
|
||||
@SceneBuilder var scene: Scene { get }
|
||||
|
||||
}
|
||||
|
||||
/// An extension
|
||||
extension WindowSceneGroup {
|
||||
|
||||
/// Get the windows described by the group.
|
||||
/// - Returns: The windows.
|
||||
func windows() -> [WindowScene] {
|
||||
var content: [WindowScene] = []
|
||||
for element in scene {
|
||||
if let window = element as? WindowScene {
|
||||
content.append(window)
|
||||
} else {
|
||||
content += element.windows()
|
||||
}
|
||||
}
|
||||
return content
|
||||
}
|
||||
|
||||
/// Update the windows described by the group.
|
||||
/// - Parameters:
|
||||
/// - storage: The window's storage.
|
||||
/// - app: The application.
|
||||
/// - force: Whether to force update all the views.
|
||||
func update(_ storage: [WindowStorage], app: GTUIApp, force: Bool) {
|
||||
for (index, window) in windows().enumerated() {
|
||||
if let storage = storage[safe: index] {
|
||||
window.update(storage, app: app, force: force)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// `Scene` is an array of windows.
|
||||
public typealias Scene = [WindowSceneGroup]
|
||||
/// A builder for the `Scene`
|
||||
public typealias SceneBuilder = ArrayBuilder<WindowSceneGroup>
|
@ -1,33 +0,0 @@
|
||||
//
|
||||
// SceneStorage.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 31.08.23.
|
||||
//
|
||||
|
||||
/// A storage for an app's window.
|
||||
public class WindowStorage {
|
||||
|
||||
/// The window's identifier.
|
||||
public var id: String
|
||||
/// The identifier of the window's parent window.
|
||||
public var parentID: String?
|
||||
/// Whether the reference to the window should disappear in the next update.
|
||||
public var destroy = false
|
||||
/// The window.
|
||||
public var window: WindowType
|
||||
/// The content's storage.
|
||||
public var view: ViewStorage?
|
||||
|
||||
/// Initialize a window storage.
|
||||
/// - Parameters:
|
||||
/// - id: The window's identifier.
|
||||
/// - window: The window.
|
||||
/// - view: The content's storage.
|
||||
public init(id: String, window: WindowType, view: ViewStorage?) {
|
||||
self.id = id
|
||||
self.window = window
|
||||
self.view = view
|
||||
}
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
//
|
||||
// GTUIWindowRepresentable.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 09.12.23.
|
||||
//
|
||||
|
||||
/// A window type.
|
||||
public protocol WindowType {
|
||||
|
||||
/// A dictionary for custom data.
|
||||
var fields: [String: Any] { get set }
|
||||
/// Set a parent window.
|
||||
/// - Parameter parent: The parent window.
|
||||
func setParentWindow(_ parent: WindowType)
|
||||
/// Show the window.
|
||||
func show()
|
||||
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
// WindowView.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 26.02.24.
|
||||
// Created by david-swift on 06.08.24.
|
||||
//
|
||||
|
||||
/// A special view that can access the window of the current instance
|
@ -45,13 +45,14 @@ extension Button {
|
||||
/// - window: The application window.
|
||||
/// - active: Whether the keyboard shortcut is active.
|
||||
/// - Returns: The button.
|
||||
public func keyboardShortcut(_ shortcut: String, window: GTUIApplicationWindow, active: Bool = true) -> Self {
|
||||
public func keyboardShortcut(_ shortcut: String, window: AdwaitaWindow, active: Bool = true) -> AnyView {
|
||||
onUpdate {
|
||||
if active {
|
||||
window.addKeyboardShortcut(shortcut, id: shortcut) { self.clicked?() }
|
||||
window.app.addKeyboardShortcut(shortcut, id: shortcut, window: window) { self.clicked?() }
|
||||
} else {
|
||||
window.removeKeyboardShortcut(id: shortcut)
|
||||
window.app.removeKeyboardShortcut(id: shortcut, window: window)
|
||||
}
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
||||
/// Create a keyboard shortcut for an application from a button.
|
||||
@ -62,13 +63,14 @@ extension Button {
|
||||
/// - window: The application.
|
||||
/// - active: Whether the keyboard shortcut is active.
|
||||
/// - Returns: The button.
|
||||
public func keyboardShortcut(_ shortcut: String, app: GTUIApp, active: Bool = true) -> Self {
|
||||
public func keyboardShortcut(_ shortcut: String, app: AdwaitaApp, active: Bool = true) -> AnyView {
|
||||
onUpdate {
|
||||
if active {
|
||||
app.addKeyboardShortcut(shortcut, id: shortcut) { self.clicked?() }
|
||||
} else {
|
||||
app.removeKeyboardShortcut(id: shortcut)
|
||||
}
|
||||
return self
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ extension CheckButton {
|
||||
/// Apply the selection mode style class.
|
||||
/// - Parameter active: Whether it is applied.
|
||||
/// - Returns: A view.
|
||||
public func selectionMode(_ active: Bool = true) -> View {
|
||||
public func selectionMode(_ active: Bool = true) -> AnyView {
|
||||
style("selection-mode", active: active)
|
||||
}
|
||||
|
||||
|
@ -9,12 +9,12 @@ import CAdw
|
||||
import Foundation
|
||||
|
||||
/// The about dialog widget.
|
||||
struct AboutDialog: Widget {
|
||||
struct AboutDialog: AdwaitaWidget {
|
||||
|
||||
/// Whether the dialog is visible.
|
||||
@Binding var visible: Bool
|
||||
/// The wrapped view.
|
||||
var child: View
|
||||
var child: AnyView
|
||||
|
||||
/// The app's name.
|
||||
var appName: String?
|
||||
@ -32,50 +32,72 @@ struct AboutDialog: Widget {
|
||||
/// The ID for the dialog's storage.
|
||||
let dialogID = "dialog"
|
||||
|
||||
/// Get the container of the child.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = child.storage(modifiers: modifiers)
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
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
|
||||
}
|
||||
|
||||
/// Update the view storage of the child, dialog, and dialog content.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - updateProperties: Whether to update properties.
|
||||
func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
child.widget(modifiers: modifiers).update(storage, modifiers: modifiers, updateProperties: updateProperties)
|
||||
guard updateProperties else {
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
/// - type: The view render data type.
|
||||
func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
data: WidgetData,
|
||||
updateProperties: Bool,
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
child.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
|
||||
guard updateProperties, (storage.previousState as? Self)?.visible != visible else {
|
||||
return
|
||||
}
|
||||
if visible {
|
||||
if storage.content[dialogID]?.first == nil {
|
||||
createDialog(storage: storage, modifiers: modifiers)
|
||||
adw_dialog_present(storage.content[dialogID]?.first?.pointer?.cast(), storage.pointer?.cast())
|
||||
createDialog(storage: storage)
|
||||
adw_dialog_present(
|
||||
storage.content[dialogID]?.first?.opaquePointer?.cast(),
|
||||
storage.opaquePointer?.cast()
|
||||
)
|
||||
}
|
||||
let dialog = storage.content[dialogID]?.first?.pointer
|
||||
let dialog = storage.content[dialogID]?.first?.opaquePointer
|
||||
if let appName {
|
||||
adw_about_dialog_set_application_name(dialog, appName)
|
||||
}
|
||||
if let developer {
|
||||
adw_about_dialog_set_developer_name(dialog, developer)
|
||||
}
|
||||
if let version {
|
||||
adw_about_dialog_set_version(dialog, version)
|
||||
adw_about_dialog_set_application_icon(dialog, icon?.string)
|
||||
adw_about_dialog_set_website(dialog, website?.absoluteString)
|
||||
adw_about_dialog_set_support_url(dialog, issues?.absoluteString)
|
||||
}
|
||||
if let icon {
|
||||
adw_about_dialog_set_application_icon(dialog, icon.string)
|
||||
}
|
||||
if let website {
|
||||
adw_about_dialog_set_website(dialog, website.absoluteString)
|
||||
}
|
||||
if let issues {
|
||||
adw_about_dialog_set_issue_url(dialog, issues.absoluteString)
|
||||
}
|
||||
adw_dialog_set_content_height(dialog?.cast(), -1)
|
||||
} else {
|
||||
if storage.content[dialogID]?.first != nil {
|
||||
adw_dialog_close(storage.content[dialogID]?.first?.pointer?.cast())
|
||||
adw_dialog_close(storage.content[dialogID]?.first?.opaquePointer?.cast())
|
||||
}
|
||||
}
|
||||
storage.previousState = self
|
||||
}
|
||||
|
||||
/// Create a new instance of the dialog.
|
||||
/// - Parameters:
|
||||
/// - storage: The wrapped view's storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
func createDialog(storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
/// - Parameter storage: The wrapped view's storage.
|
||||
func createDialog(storage: ViewStorage) {
|
||||
let pointer = adw_about_dialog_new()
|
||||
let dialog = ViewStorage(pointer?.opaque())
|
||||
storage.content[dialogID] = [dialog]
|
||||
@ -89,7 +111,7 @@ struct AboutDialog: Widget {
|
||||
|
||||
}
|
||||
|
||||
extension View {
|
||||
extension AnyView {
|
||||
|
||||
/// Add an about dialog to the parent window.
|
||||
/// - Parameters:
|
||||
@ -108,7 +130,7 @@ extension View {
|
||||
icon: Icon? = nil,
|
||||
website: URL? = nil,
|
||||
issues: URL? = nil
|
||||
) -> View {
|
||||
) -> AnyView {
|
||||
AboutDialog(
|
||||
visible: visible,
|
||||
child: self,
|
||||
|
@ -9,7 +9,7 @@ import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// The message dialog widget.
|
||||
public struct AlertDialog: Widget {
|
||||
public struct AlertDialog: AdwaitaWidget {
|
||||
|
||||
/// The ID for the dialog's storage.
|
||||
static let dialogID = "alert-dialog"
|
||||
@ -31,7 +31,7 @@ public struct AlertDialog: Widget {
|
||||
/// The available responses.
|
||||
var responses: [Response] = []
|
||||
/// The child view.
|
||||
var child: View
|
||||
var child: AnyView
|
||||
|
||||
/// Information about a response.
|
||||
struct Response: Identifiable {
|
||||
@ -71,33 +71,44 @@ public struct AlertDialog: Widget {
|
||||
|
||||
}
|
||||
|
||||
/// Get the container of the child.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = child.storage(modifiers: modifiers)
|
||||
storage.fields[Self.visibleID + id] = _visible
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
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
|
||||
}
|
||||
|
||||
/// Update the view storage of the child, dialog, and dialog content.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - updateProperties: Whether to update properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
child.widget(modifiers: modifiers).update(storage, modifiers: modifiers, updateProperties: updateProperties)
|
||||
/// - 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.fields[Self.visibleID + id] = _visible
|
||||
child.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, modifiers: modifiers)
|
||||
createDialog(storage: storage)
|
||||
present = true
|
||||
}
|
||||
let pointer = storage.content[Self.dialogID + id]?.first?.pointer
|
||||
let pointer = storage.content[Self.dialogID + id]?.first?.opaquePointer
|
||||
adw_alert_dialog_set_heading(pointer?.cast(), heading)
|
||||
adw_alert_dialog_set_body(pointer?.cast(), body)
|
||||
let old = storage.fields[Self.responsesID + id] as? [Response] ?? []
|
||||
@ -123,12 +134,12 @@ public struct AlertDialog: Widget {
|
||||
gtui_alertdialog_choose(
|
||||
.init(Int(bitPattern: pointer)),
|
||||
unsafeBitCast(storage, to: UInt64.self),
|
||||
.init(Int(bitPattern: storage.pointer))
|
||||
.init(Int(bitPattern: storage.opaquePointer))
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if storage.content[Self.dialogID + id]?.first != nil {
|
||||
adw_dialog_close(storage.content[Self.dialogID + id]?.first?.pointer?.cast())
|
||||
adw_dialog_close(storage.content[Self.dialogID + id]?.first?.opaquePointer?.cast())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -167,10 +178,8 @@ public struct AlertDialog: Widget {
|
||||
}
|
||||
|
||||
/// Create a new instance of the dialog.
|
||||
/// - Parameters:
|
||||
/// - storage: The wrapped view's storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
func createDialog(storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
/// - Parameter storage: The wrapped view's storage.
|
||||
func createDialog(storage: ViewStorage) {
|
||||
let pointer = adw_alert_dialog_new(nil, nil)
|
||||
let dialog = ViewStorage(pointer?.opaque())
|
||||
storage.content[Self.dialogID + id] = [dialog]
|
||||
@ -205,7 +214,7 @@ public struct AlertDialog: Widget {
|
||||
|
||||
}
|
||||
|
||||
extension View {
|
||||
extension AnyView {
|
||||
|
||||
/// Add an alert dialog to the parent window.
|
||||
/// - Parameters:
|
||||
|
@ -8,7 +8,7 @@
|
||||
import CAdw
|
||||
|
||||
/// The dialog widget.
|
||||
struct Dialog: Widget {
|
||||
struct Dialog: AdwaitaWidget {
|
||||
|
||||
/// Whether the dialog is visible.
|
||||
@Binding var visible: Bool
|
||||
@ -17,7 +17,7 @@ struct Dialog: Widget {
|
||||
/// The dialog's title.
|
||||
var title: String?
|
||||
/// The wrapped view.
|
||||
var child: View
|
||||
var child: AnyView
|
||||
/// The content of the dialog.
|
||||
var content: Body
|
||||
/// The dialog's width.
|
||||
@ -30,42 +30,61 @@ struct Dialog: Widget {
|
||||
/// The ID for the content's storage.
|
||||
let contentID = "content"
|
||||
|
||||
/// Get the container of the child.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = child.storage(modifiers: modifiers)
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
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
|
||||
}
|
||||
|
||||
/// Update the view storage of the child, dialog, and dialog content.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - updateProperties: Whether to update properties.
|
||||
func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
child.widget(modifiers: modifiers).update(storage, modifiers: modifiers, updateProperties: updateProperties)
|
||||
if let storage = storage.content[contentID + id]?.first as? ViewStorage {
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
/// - type: The view render data type.
|
||||
func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
data: WidgetData,
|
||||
updateProperties: Bool,
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
if let storage = storage.content[.mainContent]?.first {
|
||||
child.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let storage = storage.content[contentID + id]?.first {
|
||||
content
|
||||
.widget(modifiers: modifiers)
|
||||
.update(storage, modifiers: modifiers, updateProperties: updateProperties)
|
||||
.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
guard updateProperties else {
|
||||
return
|
||||
}
|
||||
if visible {
|
||||
if storage.content[dialogID + id]?.first == nil {
|
||||
createDialog(storage: storage, modifiers: modifiers)
|
||||
adw_dialog_present(storage.content[dialogID + id]?.first?.pointer?.cast(), storage.pointer?.cast())
|
||||
createDialog(storage: storage, data: data, type: type)
|
||||
adw_dialog_present(
|
||||
storage.content[dialogID + id]?.first?.opaquePointer?.cast(),
|
||||
storage.opaquePointer?.cast()
|
||||
)
|
||||
}
|
||||
let pointer = storage.content[dialogID + id]?.first?.opaquePointer
|
||||
if let title {
|
||||
adw_dialog_set_title(pointer?.cast(), title)
|
||||
}
|
||||
if let width {
|
||||
adw_dialog_set_content_width(pointer?.cast(), width.cInt)
|
||||
}
|
||||
if let height {
|
||||
adw_dialog_set_content_height(pointer?.cast(), height.cInt)
|
||||
}
|
||||
let pointer = storage.content[dialogID + id]?.first?.pointer
|
||||
adw_dialog_set_title(pointer?.cast(), title ?? "")
|
||||
adw_dialog_set_content_width(pointer?.cast(), width?.cInt ?? -1)
|
||||
adw_dialog_set_content_height(pointer?.cast(), height?.cInt ?? -1)
|
||||
} else {
|
||||
if storage.content[dialogID + id]?.first != nil {
|
||||
adw_dialog_close(storage.content[dialogID + id]?.first?.pointer?.cast())
|
||||
adw_dialog_close(storage.content[dialogID + id]?.first?.opaquePointer?.cast())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -74,12 +93,17 @@ struct Dialog: Widget {
|
||||
/// - Parameters:
|
||||
/// - storage: The wrapped view's storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
func createDialog(storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
/// - type: The view render data type.
|
||||
func createDialog<Data>(
|
||||
storage: ViewStorage,
|
||||
data: WidgetData,
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
let pointer = adw_dialog_new()
|
||||
let dialog = ViewStorage(pointer?.opaque())
|
||||
storage.content[dialogID + id] = [dialog]
|
||||
let contentStorage = content.widget(modifiers: modifiers).storage(modifiers: modifiers)
|
||||
adw_dialog_set_child(pointer, contentStorage.pointer?.cast())
|
||||
let contentStorage = content.storage(data: data, type: type)
|
||||
adw_dialog_set_child(pointer, contentStorage.opaquePointer?.cast())
|
||||
storage.content[contentID + id] = [contentStorage]
|
||||
dialog.connectSignal(name: "closed") {
|
||||
storage.content[dialogID + id] = []
|
||||
@ -92,7 +116,7 @@ struct Dialog: Widget {
|
||||
|
||||
}
|
||||
|
||||
extension View {
|
||||
extension AnyView {
|
||||
|
||||
/// Add a dialog to the parent window.
|
||||
/// - Parameters:
|
||||
@ -108,7 +132,7 @@ extension View {
|
||||
width: Int? = nil,
|
||||
height: Int? = nil,
|
||||
@ViewBuilder content: () -> Body
|
||||
) -> View {
|
||||
) -> AnyView {
|
||||
Dialog(
|
||||
visible: visible,
|
||||
id: id ?? "",
|
||||
|
225
Sources/Adwaita/View/Dialogs/FileDialog.swift
Normal file
225
Sources/Adwaita/View/Dialogs/FileDialog.swift
Normal file
@ -0,0 +1,225 @@
|
||||
//
|
||||
// FileDialog.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 12.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import Foundation
|
||||
|
||||
/// A structure representing a file dialog window.
|
||||
struct FileDialog: AdwaitaWidget {
|
||||
|
||||
/// Whether the dialog is an importer.
|
||||
var importer = true
|
||||
/// 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
|
||||
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let 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
|
||||
}
|
||||
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
/// - type: The view render data type.
|
||||
func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
data: WidgetData,
|
||||
updateProperties: Bool,
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
storage.fields["result"] = result
|
||||
storage.fields["cancel"] = cancel
|
||||
guard let mainStorage = storage.content[.mainContent]?.first else {
|
||||
return
|
||||
}
|
||||
child.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
|
||||
if open.update, storage.fields["callbacks"] == nil {
|
||||
let pointer = gtk_file_dialog_new()
|
||||
if let initialName {
|
||||
gtk_file_dialog_set_initial_name(pointer, initialName)
|
||||
}
|
||||
if let 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)
|
||||
} 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 callbacks = AdwaitaFileDialog()
|
||||
callbacks.onResult = { (storage.fields["result"] as? (URL) -> Void)?($0) }
|
||||
callbacks.onCancel = { (storage.fields["cancel"] as? () -> Void)?() }
|
||||
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 {
|
||||
gtui_filedialog_open(ptr, unsafeBitCast(callbacks, to: UInt64.self), window)
|
||||
} else {
|
||||
gtui_filedialog_save(ptr, unsafeBitCast(callbacks, to: UInt64.self), window)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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.
|
||||
class AdwaitaFileDialog {
|
||||
|
||||
/// A closure triggered on selecting a file in the dialog.
|
||||
var onResult: (URL) -> Void = { _ in }
|
||||
/// A closure triggered when the dialog is canceled.
|
||||
var onCancel: () -> Void = { }
|
||||
/// Reset the file dialog.
|
||||
var reset: () -> Void = { }
|
||||
|
||||
/// Initialize the window callback.
|
||||
init() {
|
||||
}
|
||||
|
||||
/// Run this when a file gets opened.
|
||||
/// - Parameter path: The file path.
|
||||
func onOpen(_ path: String) {
|
||||
let url = URL(fileURLWithPath: path)
|
||||
onResult(url)
|
||||
reset()
|
||||
}
|
||||
|
||||
/// Run this when a file gets saved.
|
||||
/// - Parameter path: The file path.
|
||||
func onSave(_ path: String) {
|
||||
let url = URL(fileURLWithPath: path)
|
||||
onResult(url)
|
||||
reset()
|
||||
}
|
||||
|
||||
/// Run this when the user cancels the action.
|
||||
func onClose() {
|
||||
onCancel()
|
||||
reset()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Run when a file should be opened.
|
||||
/// - Parameters:
|
||||
/// - ptr: The pointer.
|
||||
/// - file: The path to the file.
|
||||
/// - userData: The file dialog data.
|
||||
@_cdecl("filedialog_on_open_cb")
|
||||
func filedialog_on_open_cb(
|
||||
ptr: UnsafeMutableRawPointer,
|
||||
file: UnsafePointer<CChar>?,
|
||||
userData: UnsafeMutableRawPointer
|
||||
) {
|
||||
let dialog = Unmanaged<AdwaitaFileDialog>.fromOpaque(userData).takeUnretainedValue()
|
||||
if let file {
|
||||
dialog.onOpen(.init(cString: file))
|
||||
} else {
|
||||
dialog.onClose()
|
||||
}
|
||||
}
|
||||
|
||||
/// Run when a file should be saved.
|
||||
/// - Parameters:
|
||||
/// - ptr: The pointer.
|
||||
/// - file: The path to the file.
|
||||
/// - userData: The file dialog data.
|
||||
@_cdecl("filedialog_on_save_cb")
|
||||
func filedialog_on_save_cb(
|
||||
ptr: UnsafeMutableRawPointer,
|
||||
file: UnsafePointer<CChar>?,
|
||||
userData: UnsafeMutableRawPointer
|
||||
) {
|
||||
let dialog = Unmanaged<AdwaitaFileDialog>.fromOpaque(userData).takeUnretainedValue()
|
||||
if let file {
|
||||
dialog.onSave(.init(cString: file))
|
||||
} else {
|
||||
dialog.onClose()
|
||||
}
|
||||
}
|
44
Sources/Adwaita/View/EitherView.swift
Normal file
44
Sources/Adwaita/View/EitherView.swift
Normal file
@ -0,0 +1,44 @@
|
||||
//
|
||||
// ViewStack.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 30.12.23.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
/// A widget showing one of two widgets based on a condition.
|
||||
public struct EitherView: SimpleView, Meta.EitherView {
|
||||
|
||||
/// Whether the first view is visible.
|
||||
var condition: Bool
|
||||
/// The first view.
|
||||
var view1: Body
|
||||
/// The second view.
|
||||
var view2: Body
|
||||
|
||||
/// The view's content.
|
||||
public var view: Body {
|
||||
if condition {
|
||||
return [ViewStack(id: true) { _ in view1 }.homogeneous(false)]
|
||||
} else {
|
||||
return [ViewStack(id: false) { _ in view2 }.homogeneous(false)]
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize the either view.
|
||||
/// - Parameters:
|
||||
/// - condition: Whether the first view is visible-
|
||||
/// - view1: The first view, visible if true.
|
||||
/// - view2: The second view, visible if false.
|
||||
public init(
|
||||
_ condition: Bool,
|
||||
@ViewBuilder view1: () -> Body,
|
||||
@ViewBuilder else view2: () -> Body
|
||||
) {
|
||||
self.condition = condition
|
||||
self.view1 = view1()
|
||||
self.view2 = view2()
|
||||
}
|
||||
|
||||
}
|
@ -23,25 +23,31 @@ extension Fixed {
|
||||
@ViewBuilder view: @escaping () -> Body
|
||||
) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.appearFunctions.append { storage, modifiers in
|
||||
let view = view().storage(modifiers: modifiers)
|
||||
newSelf.appearFunctions.append { storage, data in
|
||||
let view = view().storage(data: data, type: AdwaitaMainView.self)
|
||||
gtk_fixed_put(
|
||||
storage.pointer?.cast(),
|
||||
view.pointer?.cast(),
|
||||
storage.opaquePointer?.cast(),
|
||||
view.opaquePointer?.cast(),
|
||||
xCoordinate,
|
||||
yCoordinate
|
||||
)
|
||||
storage.content[id] = [view]
|
||||
}
|
||||
newSelf.updateFunctions.append { storage, modifiers, updateProperties in
|
||||
newSelf.updateFunctions.append { storage, data, updateProperties in
|
||||
guard let content = storage.content[id]?.first else {
|
||||
return
|
||||
}
|
||||
view().updateStorage(content, modifiers: modifiers, updateProperties: updateProperties)
|
||||
view()
|
||||
.updateStorage(
|
||||
content,
|
||||
data: data,
|
||||
updateProperties: updateProperties,
|
||||
type: AdwaitaMainView.self
|
||||
)
|
||||
if updateProperties {
|
||||
gtk_fixed_move(
|
||||
storage.pointer?.cast(),
|
||||
content.pointer?.cast(),
|
||||
storage.opaquePointer?.cast(),
|
||||
content.opaquePointer?.cast(),
|
||||
xCoordinate,
|
||||
yCoordinate
|
||||
)
|
||||
|
@ -26,32 +26,32 @@ extension FlowBox {
|
||||
) {
|
||||
self.init(elements, content: content)
|
||||
let id: (ViewStorage, [Element]) -> Element.ID? = { storage, elements in
|
||||
if let child = g_list_nth_data(gtk_flow_box_get_selected_children(storage.pointer), 0) {
|
||||
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.pointer?.cast() == element }]?.id
|
||||
return elements[safe: storage.content[.mainContent]?
|
||||
.firstIndex { $0.opaquePointer?.cast() == element }]?.id
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if let selection {
|
||||
appearFunctions.append { storage, _ in
|
||||
storage.fields[Self.selectionField] = selection
|
||||
storage.connectSignal(name: "selected_children_changed", id: Self.selectionField) {
|
||||
if let binding = storage.fields[Self.selectionField] as? Binding<Element.ID>,
|
||||
let elements = storage.fields[Self.elementsField] as? [Element],
|
||||
let id = id(storage, elements) {
|
||||
binding.wrappedValue = id
|
||||
}
|
||||
}
|
||||
}
|
||||
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) {
|
||||
selection.wrappedValue = id
|
||||
}
|
||||
}
|
||||
if selection.wrappedValue != id(storage, elements),
|
||||
let index = elements.firstIndex(where: { $0.id == selection.wrappedValue })?.cInt {
|
||||
gtk_flow_box_select_child(storage.pointer, gtk_flow_box_get_child_at_index(storage.pointer, index))
|
||||
gtk_flow_box_select_child(
|
||||
storage.opaquePointer,
|
||||
gtk_flow_box_get_child_at_index(storage.opaquePointer, index)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
appearFunctions.append { storage, _ in
|
||||
gtk_flow_box_set_selection_mode(storage.pointer, GTK_SELECTION_NONE)
|
||||
gtk_flow_box_set_selection_mode(storage.opaquePointer, GTK_SELECTION_NONE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A dynamic list but without a list design in the user interface.
|
||||
public struct ForEach<Element>: Widget where Element: Identifiable {
|
||||
public struct ForEach<Element>: AdwaitaWidget where Element: Identifiable {
|
||||
|
||||
/// The dynamic widget elements.
|
||||
var elements: [Element]
|
||||
@ -25,47 +25,58 @@ public struct ForEach<Element>: Widget where Element: Identifiable {
|
||||
self.horizontal = horizontal
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(
|
||||
data: WidgetData,
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(
|
||||
gtk_box_new(horizontal ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL, 0)?.opaque()
|
||||
)
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - type: The view render data type.
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
data: WidgetData,
|
||||
updateProperties: Bool,
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? []
|
||||
let old = storage.fields["element"] as? [Element] ?? []
|
||||
let widget: UnsafeMutablePointer<GtkBox>? = storage.pointer?.cast()
|
||||
let widget: UnsafeMutablePointer<GtkBox>? = storage.opaquePointer?.cast()
|
||||
old.identifiableTransform(
|
||||
to: elements,
|
||||
functions: .init { index, element in
|
||||
let child = content(element).widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
gtk_box_remove(widget, contentStorage[safe: index]?.pointer?.cast())
|
||||
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.pointer?.cast(),
|
||||
contentStorage[safe: index - 1]?.pointer?.cast()
|
||||
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]?.pointer?.cast())
|
||||
gtk_box_remove(widget, contentStorage[safe: index]?.opaquePointer?.cast())
|
||||
contentStorage.remove(at: index)
|
||||
} insert: { index, element in
|
||||
let child = content(element).widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
let child = content(element).storage(data: data, type: type)
|
||||
gtk_box_insert_child_after(
|
||||
widget,
|
||||
child.pointer?.cast(),
|
||||
contentStorage[safe: index - 1]?.pointer?.cast()
|
||||
child.opaquePointer?.cast(),
|
||||
contentStorage[safe: index - 1]?.opaquePointer?.cast()
|
||||
)
|
||||
contentStorage.insert(child, at: index)
|
||||
}
|
||||
@ -80,8 +91,12 @@ public struct ForEach<Element>: Widget where Element: Identifiable {
|
||||
storage.content[.mainContent] = contentStorage
|
||||
for (index, element) in elements.enumerated() {
|
||||
content(element)
|
||||
.widget(modifiers: modifiers)
|
||||
.update(contentStorage[index], modifiers: modifiers, updateProperties: updateProperties)
|
||||
.updateStorage(
|
||||
contentStorage[index],
|
||||
data: data,
|
||||
updateProperties: updateProperties,
|
||||
type: type
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ 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) -> View {
|
||||
public func property(_ active: Bool = true) -> AnyView {
|
||||
style("property", active: active)
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,9 @@ 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.
|
||||
@ -35,7 +37,7 @@ extension ComboRow {
|
||||
appearFunctions.append { storage, _ in
|
||||
let list = gtk_string_list_new(nil)
|
||||
storage.fields[Self.stringList] = list
|
||||
adw_combo_row_set_model(storage.pointer?.cast(), list)
|
||||
adw_combo_row_set_model(storage.opaquePointer?.cast(), list)
|
||||
Self.updateContent(storage: storage, values: values, element: Element.self)
|
||||
}
|
||||
updateFunctions.append { storage, _, _ in
|
||||
@ -43,6 +45,11 @@ extension ComboRow {
|
||||
}
|
||||
}
|
||||
|
||||
/// Update the combo row's content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - values: The elements.
|
||||
/// - element: The type of the elements.
|
||||
static func updateContent<Element>(
|
||||
storage: ViewStorage,
|
||||
values: [Element],
|
||||
|
@ -9,8 +9,6 @@ import CAdw
|
||||
|
||||
extension EntryRow {
|
||||
|
||||
static var textField: String { "text" }
|
||||
|
||||
/// Initialize an entry row.
|
||||
/// - Parameters:
|
||||
/// - title: The row's title.
|
||||
@ -18,18 +16,15 @@ extension EntryRow {
|
||||
public init(_ title: String, text: Binding<String>) {
|
||||
self.init()
|
||||
self = self.title(title)
|
||||
appearFunctions.append { storage, _ in
|
||||
storage.fields[Self.textField] = text
|
||||
storage.notify(name: "text") {
|
||||
let newValue = String(cString: gtk_editable_get_text(storage.pointer))
|
||||
if let binding = storage.fields[Self.textField] as? Binding<String>, binding.wrappedValue != newValue {
|
||||
binding.wrappedValue = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
updateFunctions.append { storage, _, _ in
|
||||
if text.wrappedValue != .init(cString: gtk_editable_get_text(storage.pointer)) {
|
||||
gtk_editable_set_text(storage.pointer, text.wrappedValue)
|
||||
storage.notify(name: "text") {
|
||||
let newValue = String(cString: gtk_editable_get_text(storage.opaquePointer))
|
||||
if text.wrappedValue != newValue {
|
||||
text.wrappedValue = newValue
|
||||
}
|
||||
}
|
||||
if text.wrappedValue != .init(cString: gtk_editable_get_text(storage.opaquePointer)) {
|
||||
gtk_editable_set_text(storage.opaquePointer, text.wrappedValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
import CAdw
|
||||
|
||||
/// A list with no dynamic content styled as a boxed list.
|
||||
public struct Form: View {
|
||||
public struct Form: SimpleView {
|
||||
|
||||
/// The content.
|
||||
var content: Body
|
||||
|
@ -9,8 +9,6 @@ import CAdw
|
||||
|
||||
extension PasswordEntryRow {
|
||||
|
||||
static var textField: String { "text" }
|
||||
|
||||
/// Initialize an entry row.
|
||||
/// - Parameters:
|
||||
/// - title: The row's title.
|
||||
@ -18,17 +16,15 @@ extension PasswordEntryRow {
|
||||
public init(_ title: String, text: Binding<String>) {
|
||||
self.init()
|
||||
self = self.title(title)
|
||||
appearFunctions.append { storage, _ in
|
||||
storage.fields[Self.textField] = text
|
||||
storage.notify(name: "text") {
|
||||
if let binding = storage.fields[Self.textField] as? Binding<String> {
|
||||
binding.wrappedValue = .init(cString: gtk_editable_get_text(storage.pointer))
|
||||
}
|
||||
}
|
||||
}
|
||||
updateFunctions.append { storage, _, _ in
|
||||
if text.wrappedValue != .init(cString: gtk_editable_get_text(storage.pointer)) {
|
||||
gtk_editable_set_text(storage.pointer, text.wrappedValue)
|
||||
storage.notify(name: "text") {
|
||||
let newValue = String(cString: gtk_editable_get_text(storage.opaquePointer))
|
||||
if text.wrappedValue != newValue {
|
||||
text.wrappedValue = newValue
|
||||
}
|
||||
}
|
||||
if text.wrappedValue != .init(cString: gtk_editable_get_text(storage.opaquePointer)) {
|
||||
gtk_editable_set_text(storage.opaquePointer, text.wrappedValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ extension SpinRow {
|
||||
self = self.value(value)
|
||||
self = self.step(1)
|
||||
updateFunctions.append { storage, _, _ in
|
||||
adw_spin_row_set_range(storage.pointer, min, max)
|
||||
adw_spin_row_set_range(storage.opaquePointer, min, max)
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ extension SpinRow {
|
||||
public func step(_ step: Double) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.updateFunctions.append { storage, _, _ in
|
||||
let adjustment = adw_spin_row_get_adjustment(storage.pointer)
|
||||
let adjustment = adw_spin_row_get_adjustment(storage.opaquePointer)
|
||||
gtk_adjustment_set_step_increment(adjustment, step)
|
||||
}
|
||||
return newSelf
|
||||
|
@ -2,7 +2,7 @@
|
||||
// ActionRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -44,12 +44,12 @@ import LevenshteinTransformations
|
||||
/// [`.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: Widget {
|
||||
public struct ActionRow: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The widget to activate when the row is activated.
|
||||
///
|
||||
@ -61,8 +61,6 @@ public struct ActionRow: Widget {
|
||||
/// The target widget will be activated by emitting the
|
||||
/// [signal@Gtk.Widget::mnemonic-activate] signal on it.
|
||||
var activatableWidget: (() -> Body)?
|
||||
/// The icon name for this row.
|
||||
var iconName: String?
|
||||
/// The subtitle for this row.
|
||||
///
|
||||
/// The subtitle is interpreted as Pango markup unless
|
||||
@ -104,50 +102,49 @@ public struct ActionRow: Widget {
|
||||
var suffix: () -> Body = { [] }
|
||||
/// The body for the widget "prefix".
|
||||
var prefix: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ActionRow`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_action_row_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let activatableWidgetStorage = activatableWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let activatableWidgetStorage = activatableWidget?().storage(data: data, type: type) {
|
||||
storage.content["activatableWidget"] = [activatableWidgetStorage]
|
||||
adw_action_row_set_activatable_widget(storage.pointer?.cast(), activatableWidgetStorage.pointer?.cast())
|
||||
adw_action_row_set_activatable_widget(storage.opaquePointer?.cast(), activatableWidgetStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
var suffixStorage: [ViewStorage] = []
|
||||
for view in suffix() {
|
||||
suffixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_action_row_add_suffix(storage.pointer?.cast(), suffixStorage.last?.pointer?.cast())
|
||||
suffixStorage.append(view.storage(data: data, type: type))
|
||||
adw_action_row_add_suffix(storage.opaquePointer?.cast(), suffixStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["suffix"] = suffixStorage
|
||||
var prefixStorage: [ViewStorage] = []
|
||||
for view in prefix() {
|
||||
prefixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_action_row_add_prefix(storage.pointer?.cast(), prefixStorage.last?.pointer?.cast())
|
||||
prefixStorage.append(view.storage(data: data, type: type))
|
||||
adw_action_row_add_prefix(storage.opaquePointer?.cast(), prefixStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["prefix"] = prefixStorage
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - type: The view render data type.
|
||||
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
|
||||
if let activated {
|
||||
storage.connectSignal(name: "activated", argCount: 0) {
|
||||
activated()
|
||||
@ -156,33 +153,30 @@ public struct ActionRow: Widget {
|
||||
storage.modify { widget in
|
||||
|
||||
if let widget = storage.content["activatableWidget"]?.first {
|
||||
activatableWidget?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
activatableWidget?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let iconName, updateProperties {
|
||||
adw_action_row_set_icon_name(widget?.cast(), iconName)
|
||||
}
|
||||
if let subtitleLines, updateProperties {
|
||||
if let subtitleLines, updateProperties, (storage.previousState as? Self)?.subtitleLines != subtitleLines {
|
||||
adw_action_row_set_subtitle_lines(widget?.cast(), subtitleLines.cInt)
|
||||
}
|
||||
if let subtitleSelectable, updateProperties {
|
||||
if let subtitleSelectable, updateProperties, (storage.previousState as? Self)?.subtitleSelectable != subtitleSelectable {
|
||||
adw_action_row_set_subtitle_selectable(widget?.cast(), subtitleSelectable.cBool)
|
||||
}
|
||||
if let titleLines, updateProperties {
|
||||
if let titleLines, updateProperties, (storage.previousState as? Self)?.titleLines != titleLines {
|
||||
adw_action_row_set_title_lines(widget?.cast(), titleLines.cInt)
|
||||
}
|
||||
if let titleSelectable, updateProperties {
|
||||
if let titleSelectable, updateProperties, (storage.previousState as? Self)?.titleSelectable != titleSelectable {
|
||||
adw_preferences_row_set_title_selectable(widget?.cast(), titleSelectable.cBool)
|
||||
}
|
||||
if let useMarkup, updateProperties {
|
||||
if let useMarkup, updateProperties, (storage.previousState as? Self)?.useMarkup != useMarkup {
|
||||
adw_preferences_row_set_use_markup(widget?.cast(), useMarkup.cBool)
|
||||
}
|
||||
if let useUnderline, updateProperties {
|
||||
if let useUnderline, updateProperties, (storage.previousState as? Self)?.useUnderline != useUnderline {
|
||||
adw_preferences_row_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
if let title, updateProperties {
|
||||
if let title, updateProperties, (storage.previousState as? Self)?.title != title {
|
||||
adw_preferences_row_set_title(widget?.cast(), title)
|
||||
}
|
||||
if let subtitle, updateProperties {
|
||||
if let subtitle, updateProperties, (storage.previousState as? Self)?.subtitle != subtitle {
|
||||
adw_action_row_set_subtitle(widget?.cast(), subtitle)
|
||||
}
|
||||
|
||||
@ -191,8 +185,9 @@ public struct ActionRow: Widget {
|
||||
if let storage = suffixStorage[safe: index] {
|
||||
view.updateStorage(
|
||||
storage,
|
||||
modifiers: modifiers,
|
||||
updateProperties: updateProperties
|
||||
data: data,
|
||||
updateProperties: updateProperties,
|
||||
type: type
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -202,8 +197,9 @@ public struct ActionRow: Widget {
|
||||
if let storage = prefixStorage[safe: index] {
|
||||
view.updateStorage(
|
||||
storage,
|
||||
modifiers: modifiers,
|
||||
updateProperties: updateProperties
|
||||
data: data,
|
||||
updateProperties: updateProperties,
|
||||
type: type
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -211,7 +207,10 @@ public struct ActionRow: Widget {
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,14 +230,6 @@ public struct ActionRow: Widget {
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The icon name for this row.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The subtitle for this row.
|
||||
///
|
||||
/// The subtitle is interpreted as Pango markup unless
|
||||
|
@ -2,7 +2,7 @@
|
||||
// AspectFrame.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -22,12 +22,12 @@ import LevenshteinTransformations
|
||||
/// 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: Widget {
|
||||
public struct AspectFrame: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The accessible role of the given `GtkAccessible` implementation.
|
||||
///
|
||||
@ -46,61 +46,63 @@ public struct AspectFrame: Widget {
|
||||
var xalign: Float?
|
||||
/// The vertical alignment of the child.
|
||||
var yalign: Float?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `AspectFrame`.
|
||||
public init(ratio: Float) {
|
||||
self.ratio = ratio
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(gtk_aspect_frame_new(0.5, 0.5, ratio, 0)?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let childStorage = child?().storage(data: data, type: type) {
|
||||
storage.content["child"] = [childStorage]
|
||||
gtk_aspect_frame_set_child(storage.pointer, childStorage.pointer?.cast())
|
||||
gtk_aspect_frame_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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 widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let obeyChild, updateProperties {
|
||||
if let obeyChild, updateProperties, (storage.previousState as? Self)?.obeyChild != obeyChild {
|
||||
gtk_aspect_frame_set_obey_child(widget, obeyChild.cBool)
|
||||
}
|
||||
if updateProperties {
|
||||
if updateProperties, (storage.previousState as? Self)?.ratio != ratio {
|
||||
gtk_aspect_frame_set_ratio(widget, ratio)
|
||||
}
|
||||
if let xalign, updateProperties {
|
||||
if let xalign, updateProperties, (storage.previousState as? Self)?.xalign != xalign {
|
||||
gtk_aspect_frame_set_xalign(widget, xalign)
|
||||
}
|
||||
if let yalign, updateProperties {
|
||||
if let yalign, updateProperties, (storage.previousState as? Self)?.yalign != yalign {
|
||||
gtk_aspect_frame_set_yalign(widget, yalign)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Avatar.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -28,12 +28,12 @@ import LevenshteinTransformations
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwAvatar` has a single CSS node with name `avatar`.
|
||||
public struct Avatar: Widget {
|
||||
public struct Avatar: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The name of an icon to use as a fallback.
|
||||
///
|
||||
@ -50,10 +50,6 @@ public struct Avatar: Widget {
|
||||
/// It's only used to generate the color if [property@Avatar:show-initials] is
|
||||
/// `FALSE`.
|
||||
var text: String?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Avatar`.
|
||||
public init(showInitials: Bool, size: Int) {
|
||||
@ -61,44 +57,50 @@ public struct Avatar: Widget {
|
||||
self.size = size
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_avatar_new(size.cInt, text, showInitials.cBool)?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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 {
|
||||
if let iconName, updateProperties, (storage.previousState as? Self)?.iconName != iconName {
|
||||
adw_avatar_set_icon_name(widget, iconName)
|
||||
}
|
||||
if updateProperties {
|
||||
if updateProperties, (storage.previousState as? Self)?.showInitials != showInitials {
|
||||
adw_avatar_set_show_initials(widget, showInitials.cBool)
|
||||
}
|
||||
if updateProperties {
|
||||
if updateProperties, (storage.previousState as? Self)?.size != size {
|
||||
adw_avatar_set_size(widget, size.cInt)
|
||||
}
|
||||
if let text, updateProperties {
|
||||
if let text, updateProperties, (storage.previousState as? Self)?.text != text {
|
||||
adw_avatar_set_text(widget, text)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Banner.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -27,12 +27,12 @@ import LevenshteinTransformations
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwBanner` has a main CSS node with the name `banner`.
|
||||
public struct Banner: Widget {
|
||||
public struct Banner: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The label to show on the button.
|
||||
///
|
||||
@ -55,35 +55,34 @@ public struct Banner: Widget {
|
||||
///
|
||||
/// It can be used as an alternative to setting an action.
|
||||
var buttonClicked: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Banner`.
|
||||
public init(title: String) {
|
||||
self.title = title
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_banner_new(title)?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - type: The view render data type.
|
||||
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
|
||||
if let buttonClicked {
|
||||
storage.connectSignal(name: "button-clicked", argCount: 0) {
|
||||
buttonClicked()
|
||||
@ -91,23 +90,26 @@ public struct Banner: Widget {
|
||||
}
|
||||
storage.modify { widget in
|
||||
|
||||
if let buttonLabel, updateProperties {
|
||||
if let buttonLabel, updateProperties, (storage.previousState as? Self)?.buttonLabel != buttonLabel {
|
||||
adw_banner_set_button_label(widget, buttonLabel)
|
||||
}
|
||||
if let revealed, updateProperties {
|
||||
if let revealed, updateProperties, (storage.previousState as? Self)?.revealed != revealed {
|
||||
adw_banner_set_revealed(widget, revealed.cBool)
|
||||
}
|
||||
if updateProperties {
|
||||
if updateProperties, (storage.previousState as? Self)?.title != title {
|
||||
adw_banner_set_title(widget, title)
|
||||
}
|
||||
if let useMarkup, updateProperties {
|
||||
if let useMarkup, updateProperties, (storage.previousState as? Self)?.useMarkup != useMarkup {
|
||||
adw_banner_set_use_markup(widget, useMarkup.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Bin.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -17,57 +17,59 @@ import LevenshteinTransformations
|
||||
///
|
||||
/// It is useful for deriving subclasses, since it provides common code needed
|
||||
/// for handling a single child widget.
|
||||
public struct Bin: Widget {
|
||||
public struct Bin: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The child widget of the `AdwBin`.
|
||||
var child: (() -> Body)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Bin`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_bin_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let childStorage = child?().storage(data: data, type: type) {
|
||||
storage.content["child"] = [childStorage]
|
||||
adw_bin_set_child(storage.pointer?.cast(), childStorage.pointer?.cast())
|
||||
adw_bin_set_child(storage.opaquePointer?.cast(), childStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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 widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Box.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -42,12 +42,12 @@ import LevenshteinTransformations
|
||||
/// 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: Widget {
|
||||
public struct Box: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The accessible role of the given `GtkAccessible` implementation.
|
||||
///
|
||||
@ -63,56 +63,55 @@ public struct Box: Widget {
|
||||
var append: () -> Body = { [] }
|
||||
/// The body for the widget "prepend".
|
||||
var prepend: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Box`.
|
||||
public init(spacing: Int) {
|
||||
self.spacing = spacing
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(gtk_box_new(GTK_ORIENTATION_VERTICAL, spacing.cInt)?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
var appendStorage: [ViewStorage] = []
|
||||
for view in append() {
|
||||
appendStorage.append(view.storage(modifiers: modifiers))
|
||||
gtk_box_append(storage.pointer?.cast(), appendStorage.last?.pointer?.cast())
|
||||
appendStorage.append(view.storage(data: data, type: type))
|
||||
gtk_box_append(storage.opaquePointer?.cast(), appendStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["append"] = appendStorage
|
||||
var prependStorage: [ViewStorage] = []
|
||||
for view in prepend() {
|
||||
prependStorage.append(view.storage(modifiers: modifiers))
|
||||
gtk_box_prepend(storage.pointer?.cast(), prependStorage.last?.pointer?.cast())
|
||||
prependStorage.append(view.storage(data: data, type: type))
|
||||
gtk_box_prepend(storage.opaquePointer?.cast(), prependStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["prepend"] = prependStorage
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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 baselineChild, updateProperties {
|
||||
if let baselineChild, updateProperties, (storage.previousState as? Self)?.baselineChild != baselineChild {
|
||||
gtk_box_set_baseline_child(widget?.cast(), baselineChild.cInt)
|
||||
}
|
||||
if let homogeneous, updateProperties {
|
||||
if let homogeneous, updateProperties, (storage.previousState as? Self)?.homogeneous != homogeneous {
|
||||
gtk_box_set_homogeneous(widget?.cast(), homogeneous.cBool)
|
||||
}
|
||||
if updateProperties {
|
||||
if updateProperties, (storage.previousState as? Self)?.spacing != spacing {
|
||||
gtk_box_set_spacing(widget?.cast(), spacing.cInt)
|
||||
}
|
||||
|
||||
@ -121,8 +120,9 @@ public struct Box: Widget {
|
||||
if let storage = appendStorage[safe: index] {
|
||||
view.updateStorage(
|
||||
storage,
|
||||
modifiers: modifiers,
|
||||
updateProperties: updateProperties
|
||||
data: data,
|
||||
updateProperties: updateProperties,
|
||||
type: type
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -132,8 +132,9 @@ public struct Box: Widget {
|
||||
if let storage = prependStorage[safe: index] {
|
||||
view.updateStorage(
|
||||
storage,
|
||||
modifiers: modifiers,
|
||||
updateProperties: updateProperties
|
||||
data: data,
|
||||
updateProperties: updateProperties,
|
||||
type: type
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -141,7 +142,10 @@ public struct Box: Widget {
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Button.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -38,12 +38,12 @@ import LevenshteinTransformations
|
||||
/// # Accessibility
|
||||
///
|
||||
/// `GtkButton` uses the %GTK_ACCESSIBLE_ROLE_BUTTON role.
|
||||
public struct Button: Widget {
|
||||
public struct Button: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The accessible role of the given `GtkAccessible` implementation.
|
||||
///
|
||||
@ -80,38 +80,37 @@ public struct Button: Widget {
|
||||
var activate: (() -> Void)?
|
||||
/// Emitted when the button has been activated (pressed and released).
|
||||
var clicked: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Button`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(gtk_button_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let childStorage = child?().storage(data: data, type: type) {
|
||||
storage.content["child"] = [childStorage]
|
||||
gtk_button_set_child(storage.pointer?.cast(), childStorage.pointer?.cast())
|
||||
gtk_button_set_child(storage.opaquePointer?.cast(), childStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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()
|
||||
@ -124,32 +123,35 @@ public struct Button: Widget {
|
||||
}
|
||||
storage.modify { widget in
|
||||
|
||||
if let actionName, updateProperties {
|
||||
if let actionName, updateProperties, (storage.previousState as? Self)?.actionName != actionName {
|
||||
gtk_actionable_set_action_name(widget, actionName)
|
||||
}
|
||||
if let canShrink, updateProperties {
|
||||
if let canShrink, updateProperties, (storage.previousState as? Self)?.canShrink != canShrink {
|
||||
gtk_button_set_can_shrink(widget?.cast(), canShrink.cBool)
|
||||
}
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let hasFrame, updateProperties {
|
||||
if let hasFrame, updateProperties, (storage.previousState as? Self)?.hasFrame != hasFrame {
|
||||
gtk_button_set_has_frame(widget?.cast(), hasFrame.cBool)
|
||||
}
|
||||
if let iconName, updateProperties {
|
||||
if let iconName, updateProperties, (storage.previousState as? Self)?.iconName != iconName {
|
||||
gtk_button_set_icon_name(widget?.cast(), iconName)
|
||||
}
|
||||
if let label, storage.content["child"] == nil, updateProperties {
|
||||
if let label, storage.content["child"] == nil, updateProperties, (storage.previousState as? Self)?.label != label {
|
||||
gtk_button_set_label(widget?.cast(), label)
|
||||
}
|
||||
if let useUnderline, updateProperties {
|
||||
if let useUnderline, updateProperties, (storage.previousState as? Self)?.useUnderline != useUnderline {
|
||||
gtk_button_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// ButtonContent.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -44,12 +44,12 @@ import LevenshteinTransformations
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `AdwButtonContent` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
public struct ButtonContent: Widget {
|
||||
public struct ButtonContent: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// Whether the button can be smaller than the natural size of its contents.
|
||||
///
|
||||
@ -69,53 +69,55 @@ public struct ButtonContent: Widget {
|
||||
///
|
||||
/// See [property@ButtonContent:label].
|
||||
var useUnderline: Bool?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ButtonContent`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_button_content_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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 canShrink, updateProperties {
|
||||
if let canShrink, updateProperties, (storage.previousState as? Self)?.canShrink != canShrink {
|
||||
adw_button_content_set_can_shrink(widget, canShrink.cBool)
|
||||
}
|
||||
if let iconName, updateProperties {
|
||||
if let iconName, updateProperties, (storage.previousState as? Self)?.iconName != iconName {
|
||||
adw_button_content_set_icon_name(widget, iconName)
|
||||
}
|
||||
if let label, updateProperties {
|
||||
if let label, updateProperties, (storage.previousState as? Self)?.label != label {
|
||||
adw_button_content_set_label(widget, label)
|
||||
}
|
||||
if let useUnderline, updateProperties {
|
||||
if let useUnderline, updateProperties, (storage.previousState as? Self)?.useUnderline != useUnderline {
|
||||
adw_button_content_set_use_underline(widget, useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Carousel.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -21,12 +21,12 @@ import LevenshteinTransformations
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwCarousel` has a single CSS node with name `carousel`.
|
||||
public struct Carousel<Element>: Widget where Element: Identifiable {
|
||||
public struct Carousel<Element>: AdwaitaWidget where Element: Identifiable {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// Whether to allow swiping for more than one page at a time.
|
||||
///
|
||||
@ -65,10 +65,6 @@ public struct Carousel<Element>: Widget where Element: Identifiable {
|
||||
var elements: [Element]
|
||||
/// The dynamic widget content.
|
||||
var content: (Element) -> Body
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Carousel`.
|
||||
public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) {
|
||||
@ -76,25 +72,28 @@ public struct Carousel<Element>: Widget where Element: Identifiable {
|
||||
self.content = content
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_carousel_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - type: The view render data type.
|
||||
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
|
||||
if let pageChanged {
|
||||
storage.connectSignal(name: "page-changed", argCount: 1) {
|
||||
pageChanged()
|
||||
@ -102,22 +101,22 @@ public struct Carousel<Element>: Widget where Element: Identifiable {
|
||||
}
|
||||
storage.modify { widget in
|
||||
|
||||
if let allowLongSwipes, updateProperties {
|
||||
if let allowLongSwipes, updateProperties, (storage.previousState as? Self)?.allowLongSwipes != allowLongSwipes {
|
||||
adw_carousel_set_allow_long_swipes(widget, allowLongSwipes.cBool)
|
||||
}
|
||||
if let allowMouseDrag, updateProperties {
|
||||
if let allowMouseDrag, updateProperties, (storage.previousState as? Self)?.allowMouseDrag != allowMouseDrag {
|
||||
adw_carousel_set_allow_mouse_drag(widget, allowMouseDrag.cBool)
|
||||
}
|
||||
if let allowScrollWheel, updateProperties {
|
||||
if let allowScrollWheel, updateProperties, (storage.previousState as? Self)?.allowScrollWheel != allowScrollWheel {
|
||||
adw_carousel_set_allow_scroll_wheel(widget, allowScrollWheel.cBool)
|
||||
}
|
||||
if let interactive, updateProperties {
|
||||
if let interactive, updateProperties, (storage.previousState as? Self)?.interactive != interactive {
|
||||
adw_carousel_set_interactive(widget, interactive.cBool)
|
||||
}
|
||||
if let revealDuration, updateProperties {
|
||||
if let revealDuration, updateProperties, (storage.previousState as? Self)?.revealDuration != revealDuration {
|
||||
adw_carousel_set_reveal_duration(widget, revealDuration.cInt)
|
||||
}
|
||||
if let spacing, updateProperties {
|
||||
if let spacing, updateProperties, (storage.previousState as? Self)?.spacing != spacing {
|
||||
adw_carousel_set_spacing(widget, spacing.cInt)
|
||||
}
|
||||
|
||||
@ -126,28 +125,31 @@ public struct Carousel<Element>: Widget where Element: Identifiable {
|
||||
old.identifiableTransform(
|
||||
to: elements,
|
||||
functions: .init { index, element in
|
||||
let child = content(element).widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
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.pointer?.cast(), index.cInt)
|
||||
adw_carousel_insert(widget, child.opaquePointer?.cast(), index.cInt)
|
||||
contentStorage.remove(at: index)
|
||||
contentStorage.insert(child, at: index)
|
||||
} delete: { index in
|
||||
adw_carousel_remove(widget, adw_carousel_get_nth_page(widget, UInt(index).cInt))
|
||||
contentStorage.remove(at: index)
|
||||
} insert: { index, element in
|
||||
let child = content(element).widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
adw_carousel_insert(widget, child.pointer?.cast(), index.cInt)
|
||||
let child = content(element).storage(data: data, type: type)
|
||||
adw_carousel_insert(widget, child.opaquePointer?.cast(), index.cInt)
|
||||
contentStorage.insert(child, at: index)
|
||||
}
|
||||
)
|
||||
storage.fields["element"] = elements
|
||||
storage.content[.mainContent] = contentStorage
|
||||
for (index, element) in elements.enumerated() {
|
||||
content(element).widget(modifiers: modifiers).update(contentStorage[index], modifiers: modifiers, updateProperties: updateProperties)
|
||||
content(element).updateStorage(contentStorage[index], data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// CenterBox.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -42,12 +42,12 @@ import LevenshteinTransformations
|
||||
/// 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: Widget {
|
||||
public struct CenterBox: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The accessible role of the given `GtkAccessible` implementation.
|
||||
///
|
||||
@ -76,65 +76,67 @@ public struct CenterBox: Widget {
|
||||
/// In horizontal orientation, the start position is at the leading
|
||||
/// edge wrt. to the text direction.
|
||||
var startWidget: (() -> Body)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `CenterBox`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(gtk_center_box_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let centerWidgetStorage = centerWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let centerWidgetStorage = centerWidget?().storage(data: data, type: type) {
|
||||
storage.content["centerWidget"] = [centerWidgetStorage]
|
||||
gtk_center_box_set_center_widget(storage.pointer, centerWidgetStorage.pointer?.cast())
|
||||
gtk_center_box_set_center_widget(storage.opaquePointer, centerWidgetStorage.opaquePointer?.cast())
|
||||
}
|
||||
if let endWidgetStorage = endWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
if let endWidgetStorage = endWidget?().storage(data: data, type: type) {
|
||||
storage.content["endWidget"] = [endWidgetStorage]
|
||||
gtk_center_box_set_end_widget(storage.pointer, endWidgetStorage.pointer?.cast())
|
||||
gtk_center_box_set_end_widget(storage.opaquePointer, endWidgetStorage.opaquePointer?.cast())
|
||||
}
|
||||
if let startWidgetStorage = startWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
if let startWidgetStorage = startWidget?().storage(data: data, type: type) {
|
||||
storage.content["startWidget"] = [startWidgetStorage]
|
||||
gtk_center_box_set_start_widget(storage.pointer, startWidgetStorage.pointer?.cast())
|
||||
gtk_center_box_set_start_widget(storage.opaquePointer, startWidgetStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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 widget = storage.content["centerWidget"]?.first {
|
||||
centerWidget?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
centerWidget?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let widget = storage.content["endWidget"]?.first {
|
||||
endWidget?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
endWidget?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let shrinkCenterLast, updateProperties {
|
||||
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?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
startWidget?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// CheckButton.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -65,12 +65,12 @@ import LevenshteinTransformations
|
||||
/// # Accessibility
|
||||
///
|
||||
/// `GtkCheckButton` uses the %GTK_ACCESSIBLE_ROLE_CHECKBOX role.
|
||||
public struct CheckButton: Widget {
|
||||
public struct CheckButton: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The accessible role of the given `GtkAccessible` implementation.
|
||||
///
|
||||
@ -109,38 +109,37 @@ public struct CheckButton: Widget {
|
||||
/// Emitted when the buttons's [property@Gtk.CheckButton:active]
|
||||
/// property changes.
|
||||
var toggled: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `CheckButton`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(gtk_check_button_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let childStorage = child?().storage(data: data, type: type) {
|
||||
storage.content["child"] = [childStorage]
|
||||
gtk_check_button_set_child(storage.pointer?.cast(), childStorage.pointer?.cast())
|
||||
gtk_check_button_set_child(storage.opaquePointer?.cast(), childStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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()
|
||||
@ -154,34 +153,37 @@ public struct CheckButton: Widget {
|
||||
storage.modify { widget in
|
||||
|
||||
storage.notify(name: "active") {
|
||||
let newValue = gtk_check_button_get_active(storage.pointer?.cast()) != 0
|
||||
let newValue = gtk_check_button_get_active(storage.opaquePointer?.cast()) != 0
|
||||
if let active, newValue != active.wrappedValue {
|
||||
active.wrappedValue = newValue
|
||||
}
|
||||
}
|
||||
if let actionName, updateProperties {
|
||||
if let actionName, updateProperties, (storage.previousState as? Self)?.actionName != actionName {
|
||||
gtk_actionable_set_action_name(widget, actionName)
|
||||
}
|
||||
if let active, updateProperties, (gtk_check_button_get_active(storage.pointer?.cast()) != 0) != active.wrappedValue {
|
||||
gtk_check_button_set_active(storage.pointer?.cast(), active.wrappedValue.cBool)
|
||||
if let active, updateProperties, (gtk_check_button_get_active(storage.opaquePointer?.cast()) != 0) != active.wrappedValue {
|
||||
gtk_check_button_set_active(storage.opaquePointer?.cast(), active.wrappedValue.cBool)
|
||||
}
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let inconsistent, updateProperties {
|
||||
if let inconsistent, updateProperties, (storage.previousState as? Self)?.inconsistent != inconsistent {
|
||||
gtk_check_button_set_inconsistent(widget?.cast(), inconsistent.cBool)
|
||||
}
|
||||
if let label, storage.content["child"] == nil, updateProperties {
|
||||
if let label, storage.content["child"] == nil, updateProperties, (storage.previousState as? Self)?.label != label {
|
||||
gtk_check_button_set_label(widget?.cast(), label)
|
||||
}
|
||||
if let useUnderline, updateProperties {
|
||||
if let useUnderline, updateProperties, (storage.previousState as? Self)?.useUnderline != useUnderline {
|
||||
gtk_check_button_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Clamp.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -26,12 +26,12 @@ import LevenshteinTransformations
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwClamp` has a single CSS node with name `clamp`.
|
||||
public struct Clamp: Widget {
|
||||
public struct Clamp: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The child widget of the `AdwClamp`.
|
||||
var child: (() -> Body)?
|
||||
@ -54,54 +54,56 @@ public struct Clamp: Widget {
|
||||
/// Effectively, tightening the grip on the child before it reaches its maximum
|
||||
/// size makes transitions to and from the maximum size smoother when resizing.
|
||||
var tighteningThreshold: Int?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Clamp`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_clamp_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let childStorage = child?().storage(data: data, type: type) {
|
||||
storage.content["child"] = [childStorage]
|
||||
adw_clamp_set_child(storage.pointer, childStorage.pointer?.cast())
|
||||
adw_clamp_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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 widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let maximumSize, updateProperties {
|
||||
if let maximumSize, updateProperties, (storage.previousState as? Self)?.maximumSize != maximumSize {
|
||||
adw_clamp_set_maximum_size(widget, maximumSize.cInt)
|
||||
}
|
||||
if let tighteningThreshold, updateProperties {
|
||||
if let tighteningThreshold, updateProperties, (storage.previousState as? Self)?.tighteningThreshold != tighteningThreshold {
|
||||
adw_clamp_set_tightening_threshold(widget, tighteningThreshold.cInt)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// ComboRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -41,12 +41,12 @@ import LevenshteinTransformations
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `AdwComboRow` uses the `GTK_ACCESSIBLE_ROLE_COMBO_BOX` role.
|
||||
public struct ComboRow: Widget {
|
||||
public struct ComboRow: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The widget to activate when the row is activated.
|
||||
///
|
||||
@ -65,8 +65,6 @@ public struct ComboRow: Widget {
|
||||
///
|
||||
/// Search requires [property@ComboRow:expression] to be set.
|
||||
var enableSearch: Bool?
|
||||
/// The icon name for this row.
|
||||
var iconName: String?
|
||||
/// The position of the selected item.
|
||||
///
|
||||
/// If no item is selected, the property has the value
|
||||
@ -123,50 +121,49 @@ public struct ComboRow: Widget {
|
||||
var suffix: () -> Body = { [] }
|
||||
/// The body for the widget "prefix".
|
||||
var prefix: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ComboRow`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_combo_row_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let activatableWidgetStorage = activatableWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let activatableWidgetStorage = activatableWidget?().storage(data: data, type: type) {
|
||||
storage.content["activatableWidget"] = [activatableWidgetStorage]
|
||||
adw_action_row_set_activatable_widget(storage.pointer?.cast(), activatableWidgetStorage.pointer?.cast())
|
||||
adw_action_row_set_activatable_widget(storage.opaquePointer?.cast(), activatableWidgetStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
var suffixStorage: [ViewStorage] = []
|
||||
for view in suffix() {
|
||||
suffixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_action_row_add_suffix(storage.pointer?.cast(), suffixStorage.last?.pointer?.cast())
|
||||
suffixStorage.append(view.storage(data: data, type: type))
|
||||
adw_action_row_add_suffix(storage.opaquePointer?.cast(), suffixStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["suffix"] = suffixStorage
|
||||
var prefixStorage: [ViewStorage] = []
|
||||
for view in prefix() {
|
||||
prefixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_action_row_add_prefix(storage.pointer?.cast(), prefixStorage.last?.pointer?.cast())
|
||||
prefixStorage.append(view.storage(data: data, type: type))
|
||||
adw_action_row_add_prefix(storage.opaquePointer?.cast(), prefixStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["prefix"] = prefixStorage
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - type: The view render data type.
|
||||
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
|
||||
if let activated {
|
||||
storage.connectSignal(name: "activated", argCount: 0) {
|
||||
activated()
|
||||
@ -175,55 +172,55 @@ public struct ComboRow: Widget {
|
||||
storage.modify { widget in
|
||||
|
||||
storage.notify(name: "selected") {
|
||||
let newValue = UInt(adw_combo_row_get_selected(storage.pointer?.cast()))
|
||||
let newValue = UInt(adw_combo_row_get_selected(storage.opaquePointer?.cast()))
|
||||
if let selected, newValue != selected.wrappedValue {
|
||||
selected.wrappedValue = newValue
|
||||
}
|
||||
}
|
||||
if let widget = storage.content["activatableWidget"]?.first {
|
||||
activatableWidget?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
activatableWidget?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let enableSearch, updateProperties {
|
||||
if let enableSearch, updateProperties, (storage.previousState as? Self)?.enableSearch != enableSearch {
|
||||
adw_combo_row_set_enable_search(widget?.cast(), enableSearch.cBool)
|
||||
}
|
||||
if let iconName, updateProperties {
|
||||
adw_action_row_set_icon_name(widget?.cast(), iconName)
|
||||
if let selected, updateProperties, (UInt(adw_combo_row_get_selected(storage.opaquePointer?.cast()))) != selected.wrappedValue {
|
||||
adw_combo_row_set_selected(storage.opaquePointer?.cast(), selected.wrappedValue.cInt)
|
||||
}
|
||||
if let selected, updateProperties, (UInt(adw_combo_row_get_selected(storage.pointer?.cast()))) != selected.wrappedValue {
|
||||
adw_combo_row_set_selected(storage.pointer?.cast(), selected.wrappedValue.cInt)
|
||||
}
|
||||
if let subtitle, updateProperties {
|
||||
if let subtitle, updateProperties, (storage.previousState as? Self)?.subtitle != subtitle {
|
||||
adw_action_row_set_subtitle(widget?.cast(), subtitle)
|
||||
}
|
||||
if let subtitleLines, updateProperties {
|
||||
if let subtitleLines, updateProperties, (storage.previousState as? Self)?.subtitleLines != subtitleLines {
|
||||
adw_action_row_set_subtitle_lines(widget?.cast(), subtitleLines.cInt)
|
||||
}
|
||||
if let subtitleSelectable, updateProperties {
|
||||
if let subtitleSelectable, updateProperties, (storage.previousState as? Self)?.subtitleSelectable != subtitleSelectable {
|
||||
adw_action_row_set_subtitle_selectable(widget?.cast(), subtitleSelectable.cBool)
|
||||
}
|
||||
if let title, updateProperties {
|
||||
if let title, updateProperties, (storage.previousState as? Self)?.title != title {
|
||||
adw_preferences_row_set_title(widget?.cast(), title)
|
||||
}
|
||||
if let titleLines, updateProperties {
|
||||
if let titleLines, updateProperties, (storage.previousState as? Self)?.titleLines != titleLines {
|
||||
adw_action_row_set_title_lines(widget?.cast(), titleLines.cInt)
|
||||
}
|
||||
if let titleSelectable, updateProperties {
|
||||
if let titleSelectable, updateProperties, (storage.previousState as? Self)?.titleSelectable != titleSelectable {
|
||||
adw_preferences_row_set_title_selectable(widget?.cast(), titleSelectable.cBool)
|
||||
}
|
||||
if let useMarkup, updateProperties {
|
||||
if let useMarkup, updateProperties, (storage.previousState as? Self)?.useMarkup != useMarkup {
|
||||
adw_preferences_row_set_use_markup(widget?.cast(), useMarkup.cBool)
|
||||
}
|
||||
if let useSubtitle, updateProperties {
|
||||
if let useSubtitle, updateProperties, (storage.previousState as? Self)?.useSubtitle != useSubtitle {
|
||||
adw_combo_row_set_use_subtitle(widget?.cast(), useSubtitle.cBool)
|
||||
}
|
||||
if let useUnderline, updateProperties {
|
||||
if let useUnderline, updateProperties, (storage.previousState as? Self)?.useUnderline != useUnderline {
|
||||
adw_preferences_row_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,14 +253,6 @@ if let selected, newValue != selected.wrappedValue {
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The icon name for this row.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The position of the selected item.
|
||||
///
|
||||
/// If no item is selected, the property has the value
|
||||
|
@ -2,7 +2,7 @@
|
||||
// EntryRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -39,12 +39,12 @@ import LevenshteinTransformations
|
||||
///
|
||||
/// `AdwEntryRow` has a single CSS node with name `row` and the `.entry` style
|
||||
/// class.
|
||||
public struct EntryRow: Widget {
|
||||
public struct EntryRow: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// Whether activating the embedded entry can activate the default widget.
|
||||
var activatesDefault: Bool?
|
||||
@ -91,46 +91,45 @@ public struct EntryRow: Widget {
|
||||
var suffix: () -> Body = { [] }
|
||||
/// The body for the widget "prefix".
|
||||
var prefix: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `EntryRow`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_entry_row_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
var suffixStorage: [ViewStorage] = []
|
||||
for view in suffix() {
|
||||
suffixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_entry_row_add_suffix(storage.pointer?.cast(), suffixStorage.last?.pointer?.cast())
|
||||
suffixStorage.append(view.storage(data: data, type: type))
|
||||
adw_entry_row_add_suffix(storage.opaquePointer?.cast(), suffixStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["suffix"] = suffixStorage
|
||||
var prefixStorage: [ViewStorage] = []
|
||||
for view in prefix() {
|
||||
prefixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_entry_row_add_prefix(storage.pointer?.cast(), prefixStorage.last?.pointer?.cast())
|
||||
prefixStorage.append(view.storage(data: data, type: type))
|
||||
adw_entry_row_add_prefix(storage.opaquePointer?.cast(), prefixStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["prefix"] = prefixStorage
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - type: The view render data type.
|
||||
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
|
||||
if let apply {
|
||||
storage.connectSignal(name: "apply", argCount: 0) {
|
||||
apply()
|
||||
@ -143,25 +142,25 @@ public struct EntryRow: Widget {
|
||||
}
|
||||
storage.modify { widget in
|
||||
|
||||
if let activatesDefault, updateProperties {
|
||||
if let activatesDefault, updateProperties, (storage.previousState as? Self)?.activatesDefault != activatesDefault {
|
||||
adw_entry_row_set_activates_default(widget?.cast(), activatesDefault.cBool)
|
||||
}
|
||||
if let enableEmojiCompletion, updateProperties {
|
||||
if let enableEmojiCompletion, updateProperties, (storage.previousState as? Self)?.enableEmojiCompletion != enableEmojiCompletion {
|
||||
adw_entry_row_set_enable_emoji_completion(widget?.cast(), enableEmojiCompletion.cBool)
|
||||
}
|
||||
if let showApplyButton, updateProperties {
|
||||
if let showApplyButton, updateProperties, (storage.previousState as? Self)?.showApplyButton != showApplyButton {
|
||||
adw_entry_row_set_show_apply_button(widget?.cast(), showApplyButton.cBool)
|
||||
}
|
||||
if let title, updateProperties {
|
||||
if let title, updateProperties, (storage.previousState as? Self)?.title != title {
|
||||
adw_preferences_row_set_title(widget?.cast(), title)
|
||||
}
|
||||
if let titleSelectable, updateProperties {
|
||||
if let titleSelectable, updateProperties, (storage.previousState as? Self)?.titleSelectable != titleSelectable {
|
||||
adw_preferences_row_set_title_selectable(widget?.cast(), titleSelectable.cBool)
|
||||
}
|
||||
if let useMarkup, updateProperties {
|
||||
if let useMarkup, updateProperties, (storage.previousState as? Self)?.useMarkup != useMarkup {
|
||||
adw_preferences_row_set_use_markup(widget?.cast(), useMarkup.cBool)
|
||||
}
|
||||
if let useUnderline, updateProperties {
|
||||
if let useUnderline, updateProperties, (storage.previousState as? Self)?.useUnderline != useUnderline {
|
||||
adw_preferences_row_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
@ -170,8 +169,9 @@ public struct EntryRow: Widget {
|
||||
if let storage = suffixStorage[safe: index] {
|
||||
view.updateStorage(
|
||||
storage,
|
||||
modifiers: modifiers,
|
||||
updateProperties: updateProperties
|
||||
data: data,
|
||||
updateProperties: updateProperties,
|
||||
type: type
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -181,8 +181,9 @@ public struct EntryRow: Widget {
|
||||
if let storage = prefixStorage[safe: index] {
|
||||
view.updateStorage(
|
||||
storage,
|
||||
modifiers: modifiers,
|
||||
updateProperties: updateProperties
|
||||
data: data,
|
||||
updateProperties: updateProperties,
|
||||
type: type
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -190,7 +191,10 @@ public struct EntryRow: Widget {
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// ExpanderRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -33,19 +33,17 @@ import LevenshteinTransformations
|
||||
/// 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: Widget {
|
||||
public struct ExpanderRow: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// Whether expansion is enabled.
|
||||
var enableExpansion: Binding<Bool>?
|
||||
/// Whether the row is expanded.
|
||||
var expanded: Binding<Bool>?
|
||||
/// The icon name for this row.
|
||||
var iconName: String?
|
||||
/// Whether the switch enabling the expansion is visible.
|
||||
var showEnableSwitch: Bool?
|
||||
/// The subtitle for this row.
|
||||
@ -85,97 +83,93 @@ public struct ExpanderRow: Widget {
|
||||
var suffix: () -> Body = { [] }
|
||||
/// The body for the widget "prefix".
|
||||
var prefix: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ExpanderRow`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_expander_row_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
var rowsStorage: [ViewStorage] = []
|
||||
for view in rows() {
|
||||
rowsStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_expander_row_add_row(storage.pointer?.cast(), rowsStorage.last?.pointer?.cast())
|
||||
rowsStorage.append(view.storage(data: data, type: type))
|
||||
adw_expander_row_add_row(storage.opaquePointer?.cast(), rowsStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["rows"] = rowsStorage
|
||||
var suffixStorage: [ViewStorage] = []
|
||||
for view in suffix() {
|
||||
suffixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_expander_row_add_suffix(storage.pointer?.cast(), suffixStorage.last?.pointer?.cast())
|
||||
suffixStorage.append(view.storage(data: data, type: type))
|
||||
adw_expander_row_add_suffix(storage.opaquePointer?.cast(), suffixStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["suffix"] = suffixStorage
|
||||
var prefixStorage: [ViewStorage] = []
|
||||
for view in prefix() {
|
||||
prefixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_expander_row_add_prefix(storage.pointer?.cast(), prefixStorage.last?.pointer?.cast())
|
||||
prefixStorage.append(view.storage(data: data, type: type))
|
||||
adw_expander_row_add_prefix(storage.opaquePointer?.cast(), prefixStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["prefix"] = prefixStorage
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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
|
||||
|
||||
storage.notify(name: "enable-expansion") {
|
||||
let newValue = adw_expander_row_get_enable_expansion(storage.pointer?.cast()) != 0
|
||||
let newValue = adw_expander_row_get_enable_expansion(storage.opaquePointer?.cast()) != 0
|
||||
if let enableExpansion, newValue != enableExpansion.wrappedValue {
|
||||
enableExpansion.wrappedValue = newValue
|
||||
}
|
||||
}
|
||||
storage.notify(name: "expanded") {
|
||||
let newValue = adw_expander_row_get_expanded(storage.pointer?.cast()) != 0
|
||||
let newValue = adw_expander_row_get_expanded(storage.opaquePointer?.cast()) != 0
|
||||
if let expanded, newValue != expanded.wrappedValue {
|
||||
expanded.wrappedValue = newValue
|
||||
}
|
||||
}
|
||||
if let enableExpansion, updateProperties, (adw_expander_row_get_enable_expansion(storage.pointer?.cast()) != 0) != enableExpansion.wrappedValue {
|
||||
adw_expander_row_set_enable_expansion(storage.pointer?.cast(), enableExpansion.wrappedValue.cBool)
|
||||
if let enableExpansion, updateProperties, (adw_expander_row_get_enable_expansion(storage.opaquePointer?.cast()) != 0) != enableExpansion.wrappedValue {
|
||||
adw_expander_row_set_enable_expansion(storage.opaquePointer?.cast(), enableExpansion.wrappedValue.cBool)
|
||||
}
|
||||
if let expanded, updateProperties, (adw_expander_row_get_expanded(storage.pointer?.cast()) != 0) != expanded.wrappedValue {
|
||||
adw_expander_row_set_expanded(storage.pointer?.cast(), expanded.wrappedValue.cBool)
|
||||
if let expanded, updateProperties, (adw_expander_row_get_expanded(storage.opaquePointer?.cast()) != 0) != expanded.wrappedValue {
|
||||
adw_expander_row_set_expanded(storage.opaquePointer?.cast(), expanded.wrappedValue.cBool)
|
||||
}
|
||||
if let iconName, updateProperties {
|
||||
adw_expander_row_set_icon_name(widget?.cast(), iconName)
|
||||
}
|
||||
if let showEnableSwitch, updateProperties {
|
||||
if let showEnableSwitch, updateProperties, (storage.previousState as? Self)?.showEnableSwitch != showEnableSwitch {
|
||||
adw_expander_row_set_show_enable_switch(widget?.cast(), showEnableSwitch.cBool)
|
||||
}
|
||||
if let subtitle, updateProperties {
|
||||
if let subtitle, updateProperties, (storage.previousState as? Self)?.subtitle != subtitle {
|
||||
adw_expander_row_set_subtitle(widget?.cast(), subtitle)
|
||||
}
|
||||
if let subtitleLines, updateProperties {
|
||||
if let subtitleLines, updateProperties, (storage.previousState as? Self)?.subtitleLines != subtitleLines {
|
||||
adw_expander_row_set_subtitle_lines(widget?.cast(), subtitleLines.cInt)
|
||||
}
|
||||
if let title, updateProperties {
|
||||
if let title, updateProperties, (storage.previousState as? Self)?.title != title {
|
||||
adw_preferences_row_set_title(widget?.cast(), title)
|
||||
}
|
||||
if let titleLines, updateProperties {
|
||||
if let titleLines, updateProperties, (storage.previousState as? Self)?.titleLines != titleLines {
|
||||
adw_expander_row_set_title_lines(widget?.cast(), titleLines.cInt)
|
||||
}
|
||||
if let titleSelectable, updateProperties {
|
||||
if let titleSelectable, updateProperties, (storage.previousState as? Self)?.titleSelectable != titleSelectable {
|
||||
adw_preferences_row_set_title_selectable(widget?.cast(), titleSelectable.cBool)
|
||||
}
|
||||
if let useMarkup, updateProperties {
|
||||
if let useMarkup, updateProperties, (storage.previousState as? Self)?.useMarkup != useMarkup {
|
||||
adw_preferences_row_set_use_markup(widget?.cast(), useMarkup.cBool)
|
||||
}
|
||||
if let useUnderline, updateProperties {
|
||||
if let useUnderline, updateProperties, (storage.previousState as? Self)?.useUnderline != useUnderline {
|
||||
adw_preferences_row_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
@ -184,8 +178,9 @@ if let expanded, newValue != expanded.wrappedValue {
|
||||
if let storage = rowsStorage[safe: index] {
|
||||
view.updateStorage(
|
||||
storage,
|
||||
modifiers: modifiers,
|
||||
updateProperties: updateProperties
|
||||
data: data,
|
||||
updateProperties: updateProperties,
|
||||
type: type
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -195,8 +190,9 @@ if let expanded, newValue != expanded.wrappedValue {
|
||||
if let storage = suffixStorage[safe: index] {
|
||||
view.updateStorage(
|
||||
storage,
|
||||
modifiers: modifiers,
|
||||
updateProperties: updateProperties
|
||||
data: data,
|
||||
updateProperties: updateProperties,
|
||||
type: type
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -206,8 +202,9 @@ if let expanded, newValue != expanded.wrappedValue {
|
||||
if let storage = prefixStorage[safe: index] {
|
||||
view.updateStorage(
|
||||
storage,
|
||||
modifiers: modifiers,
|
||||
updateProperties: updateProperties
|
||||
data: data,
|
||||
updateProperties: updateProperties,
|
||||
type: type
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -215,7 +212,10 @@ if let expanded, newValue != expanded.wrappedValue {
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,14 +235,6 @@ if let expanded, newValue != expanded.wrappedValue {
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The icon name for this row.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the switch enabling the expansion is visible.
|
||||
public func showEnableSwitch(_ showEnableSwitch: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Fixed.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -45,52 +45,54 @@ import LevenshteinTransformations
|
||||
/// If you know none of these things are an issue for your application,
|
||||
/// and prefer the simplicity of `GtkFixed`, by all means use the
|
||||
/// widget. But you should be aware of the tradeoffs.
|
||||
public struct Fixed: Widget {
|
||||
public struct Fixed: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The accessible role of the given `GtkAccessible` implementation.
|
||||
///
|
||||
/// The accessible role cannot be changed once set.
|
||||
var accessibleRole: String?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Fixed`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(gtk_fixed_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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
|
||||
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// FlowBox.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -52,12 +52,12 @@ import LevenshteinTransformations
|
||||
///
|
||||
/// `GtkFlowBox` uses the %GTK_ACCESSIBLE_ROLE_GRID role, and `GtkFlowBoxChild`
|
||||
/// uses the %GTK_ACCESSIBLE_ROLE_GRID_CELL role.
|
||||
public struct FlowBox<Element>: Widget where Element: Identifiable {
|
||||
public struct FlowBox<Element>: AdwaitaWidget where Element: Identifiable {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// accept-unpaired-release
|
||||
var acceptUnpairedRelease: Bool?
|
||||
@ -138,10 +138,6 @@ public struct FlowBox<Element>: Widget where Element: Identifiable {
|
||||
var elements: [Element]
|
||||
/// The dynamic widget content.
|
||||
var content: (Element) -> Body
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `FlowBox`.
|
||||
public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) {
|
||||
@ -149,25 +145,28 @@ public struct FlowBox<Element>: Widget where Element: Identifiable {
|
||||
self.content = content
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(gtk_flow_box_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - type: The view render data type.
|
||||
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
|
||||
if let activateCursorChild {
|
||||
storage.connectSignal(name: "activate-cursor-child", argCount: 0) {
|
||||
activateCursorChild()
|
||||
@ -205,22 +204,22 @@ public struct FlowBox<Element>: Widget where Element: Identifiable {
|
||||
}
|
||||
storage.modify { widget in
|
||||
|
||||
if let activateOnSingleClick, updateProperties {
|
||||
if let activateOnSingleClick, updateProperties, (storage.previousState as? Self)?.activateOnSingleClick != activateOnSingleClick {
|
||||
gtk_flow_box_set_activate_on_single_click(widget, activateOnSingleClick.cBool)
|
||||
}
|
||||
if let columnSpacing, updateProperties {
|
||||
if let columnSpacing, updateProperties, (storage.previousState as? Self)?.columnSpacing != columnSpacing {
|
||||
gtk_flow_box_set_column_spacing(widget, columnSpacing.cInt)
|
||||
}
|
||||
if let homogeneous, updateProperties {
|
||||
if let homogeneous, updateProperties, (storage.previousState as? Self)?.homogeneous != homogeneous {
|
||||
gtk_flow_box_set_homogeneous(widget, homogeneous.cBool)
|
||||
}
|
||||
if let maxChildrenPerLine, updateProperties {
|
||||
if let maxChildrenPerLine, updateProperties, (storage.previousState as? Self)?.maxChildrenPerLine != maxChildrenPerLine {
|
||||
gtk_flow_box_set_max_children_per_line(widget, maxChildrenPerLine.cInt)
|
||||
}
|
||||
if let minChildrenPerLine, updateProperties {
|
||||
if let minChildrenPerLine, updateProperties, (storage.previousState as? Self)?.minChildrenPerLine != minChildrenPerLine {
|
||||
gtk_flow_box_set_min_children_per_line(widget, minChildrenPerLine.cInt)
|
||||
}
|
||||
if let rowSpacing, updateProperties {
|
||||
if let rowSpacing, updateProperties, (storage.previousState as? Self)?.rowSpacing != rowSpacing {
|
||||
gtk_flow_box_set_row_spacing(widget, rowSpacing.cInt)
|
||||
}
|
||||
|
||||
@ -229,28 +228,31 @@ public struct FlowBox<Element>: Widget where Element: Identifiable {
|
||||
old.identifiableTransform(
|
||||
to: elements,
|
||||
functions: .init { index, element in
|
||||
let child = content(element).widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
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.pointer?.cast(), index.cInt)
|
||||
gtk_flow_box_insert(widget, child.opaquePointer?.cast(), index.cInt)
|
||||
contentStorage.remove(at: index)
|
||||
contentStorage.insert(child, at: index)
|
||||
} delete: { 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
|
||||
let child = content(element).widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
gtk_flow_box_insert(widget, child.pointer?.cast(), index.cInt)
|
||||
let child = content(element).storage(data: data, type: type)
|
||||
gtk_flow_box_insert(widget, child.opaquePointer?.cast(), index.cInt)
|
||||
contentStorage.insert(child, at: index)
|
||||
}
|
||||
)
|
||||
storage.fields["element"] = elements
|
||||
storage.content[.mainContent] = contentStorage
|
||||
for (index, element) in elements.enumerated() {
|
||||
content(element).widget(modifiers: modifiers).update(contentStorage[index], modifiers: modifiers, updateProperties: updateProperties)
|
||||
content(element).updateStorage(contentStorage[index], data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// HeaderBar.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -92,12 +92,12 @@ import LevenshteinTransformations
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `AdwHeaderBar` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
public struct HeaderBar: Widget {
|
||||
public struct HeaderBar: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The decoration layout for buttons.
|
||||
///
|
||||
@ -152,69 +152,68 @@ public struct HeaderBar: Widget {
|
||||
var start: () -> Body = { [] }
|
||||
/// The body for the widget "end".
|
||||
var end: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `HeaderBar`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_header_bar_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let titleWidgetStorage = titleWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let titleWidgetStorage = titleWidget?().storage(data: data, type: type) {
|
||||
storage.content["titleWidget"] = [titleWidgetStorage]
|
||||
adw_header_bar_set_title_widget(storage.pointer, titleWidgetStorage.pointer?.cast())
|
||||
adw_header_bar_set_title_widget(storage.opaquePointer, titleWidgetStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
var startStorage: [ViewStorage] = []
|
||||
for view in start() {
|
||||
startStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_header_bar_pack_start(storage.pointer, startStorage.last?.pointer?.cast())
|
||||
startStorage.append(view.storage(data: data, type: type))
|
||||
adw_header_bar_pack_start(storage.opaquePointer, startStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["start"] = startStorage
|
||||
var endStorage: [ViewStorage] = []
|
||||
for view in end() {
|
||||
endStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_header_bar_pack_end(storage.pointer, endStorage.last?.pointer?.cast())
|
||||
endStorage.append(view.storage(data: data, type: type))
|
||||
adw_header_bar_pack_end(storage.opaquePointer, endStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["end"] = endStorage
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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 decorationLayout, updateProperties {
|
||||
if let decorationLayout, updateProperties, (storage.previousState as? Self)?.decorationLayout != decorationLayout {
|
||||
adw_header_bar_set_decoration_layout(widget, decorationLayout)
|
||||
}
|
||||
if let showBackButton, updateProperties {
|
||||
if let showBackButton, updateProperties, (storage.previousState as? Self)?.showBackButton != showBackButton {
|
||||
adw_header_bar_set_show_back_button(widget, showBackButton.cBool)
|
||||
}
|
||||
if let showEndTitleButtons, updateProperties {
|
||||
if let showEndTitleButtons, updateProperties, (storage.previousState as? Self)?.showEndTitleButtons != showEndTitleButtons {
|
||||
adw_header_bar_set_show_end_title_buttons(widget, showEndTitleButtons.cBool)
|
||||
}
|
||||
if let showStartTitleButtons, updateProperties {
|
||||
if let showStartTitleButtons, updateProperties, (storage.previousState as? Self)?.showStartTitleButtons != showStartTitleButtons {
|
||||
adw_header_bar_set_show_start_title_buttons(widget, showStartTitleButtons.cBool)
|
||||
}
|
||||
if let showTitle, updateProperties {
|
||||
if let showTitle, updateProperties, (storage.previousState as? Self)?.showTitle != showTitle {
|
||||
adw_header_bar_set_show_title(widget, showTitle.cBool)
|
||||
}
|
||||
if let widget = storage.content["titleWidget"]?.first {
|
||||
titleWidget?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
titleWidget?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
|
||||
if let startStorage = storage.content["start"] {
|
||||
@ -222,8 +221,9 @@ public struct HeaderBar: Widget {
|
||||
if let storage = startStorage[safe: index] {
|
||||
view.updateStorage(
|
||||
storage,
|
||||
modifiers: modifiers,
|
||||
updateProperties: updateProperties
|
||||
data: data,
|
||||
updateProperties: updateProperties,
|
||||
type: type
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -233,8 +233,9 @@ public struct HeaderBar: Widget {
|
||||
if let storage = endStorage[safe: index] {
|
||||
view.updateStorage(
|
||||
storage,
|
||||
modifiers: modifiers,
|
||||
updateProperties: updateProperties
|
||||
data: data,
|
||||
updateProperties: updateProperties,
|
||||
type: type
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -242,7 +243,10 @@ public struct HeaderBar: Widget {
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Label.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -184,12 +184,12 @@ import LevenshteinTransformations
|
||||
/// It is possible to implement custom handling for links and their tooltips
|
||||
/// with the [signal@Gtk.Label::activate-link] signal and the
|
||||
/// [method@Gtk.Label.get_current_uri] function.
|
||||
public struct Label: Widget {
|
||||
public struct Label: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The accessible role of the given `GtkAccessible` implementation.
|
||||
///
|
||||
@ -268,39 +268,38 @@ public struct Label: Widget {
|
||||
///
|
||||
/// The default binding for this signal is <kbd>Ctrl</kbd>+<kbd>c</kbd>.
|
||||
var copyClipboard: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Label`.
|
||||
public init(label: String) {
|
||||
self.label = label
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
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, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let mnemonicWidgetStorage = mnemonicWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let mnemonicWidgetStorage = mnemonicWidget?().storage(data: data, type: type) {
|
||||
storage.content["mnemonicWidget"] = [mnemonicWidgetStorage]
|
||||
gtk_label_set_mnemonic_widget(storage.pointer, mnemonicWidgetStorage.pointer?.cast())
|
||||
gtk_label_set_mnemonic_widget(storage.opaquePointer, mnemonicWidgetStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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()
|
||||
@ -308,47 +307,50 @@ public struct Label: Widget {
|
||||
}
|
||||
storage.modify { widget in
|
||||
|
||||
if updateProperties {
|
||||
if updateProperties, (storage.previousState as? Self)?.label != label {
|
||||
gtk_label_set_label(widget, label)
|
||||
}
|
||||
if let lines, updateProperties {
|
||||
if let lines, updateProperties, (storage.previousState as? Self)?.lines != lines {
|
||||
gtk_label_set_lines(widget, lines.cInt)
|
||||
}
|
||||
if let maxWidthChars, updateProperties {
|
||||
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?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
mnemonicWidget?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let selectable, updateProperties {
|
||||
if let selectable, updateProperties, (storage.previousState as? Self)?.selectable != selectable {
|
||||
gtk_label_set_selectable(widget, selectable.cBool)
|
||||
}
|
||||
if let singleLineMode, updateProperties {
|
||||
if let singleLineMode, updateProperties, (storage.previousState as? Self)?.singleLineMode != singleLineMode {
|
||||
gtk_label_set_single_line_mode(widget, singleLineMode.cBool)
|
||||
}
|
||||
if let useMarkup, updateProperties {
|
||||
if let useMarkup, updateProperties, (storage.previousState as? Self)?.useMarkup != useMarkup {
|
||||
gtk_label_set_use_markup(widget, useMarkup.cBool)
|
||||
}
|
||||
if let useUnderline, updateProperties {
|
||||
if let useUnderline, updateProperties, (storage.previousState as? Self)?.useUnderline != useUnderline {
|
||||
gtk_label_set_use_underline(widget, useUnderline.cBool)
|
||||
}
|
||||
if let widthChars, updateProperties {
|
||||
if let widthChars, updateProperties, (storage.previousState as? Self)?.widthChars != widthChars {
|
||||
gtk_label_set_width_chars(widget, widthChars.cInt)
|
||||
}
|
||||
if let wrap, updateProperties {
|
||||
if let wrap, updateProperties, (storage.previousState as? Self)?.wrap != wrap {
|
||||
gtk_label_set_wrap(widget, wrap.cBool)
|
||||
}
|
||||
if let xalign, updateProperties {
|
||||
if let xalign, updateProperties, (storage.previousState as? Self)?.xalign != xalign {
|
||||
gtk_label_set_xalign(widget, xalign)
|
||||
}
|
||||
if let yalign, updateProperties {
|
||||
if let yalign, updateProperties, (storage.previousState as? Self)?.yalign != yalign {
|
||||
gtk_label_set_yalign(widget, yalign)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// LevelBar.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -105,12 +105,12 @@ import LevenshteinTransformations
|
||||
/// # Accessibility
|
||||
///
|
||||
/// `GtkLevelBar` uses the %GTK_ACCESSIBLE_ROLE_METER role.
|
||||
public struct LevelBar: Widget {
|
||||
public struct LevelBar: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The accessible role of the given `GtkAccessible` implementation.
|
||||
///
|
||||
@ -136,34 +136,33 @@ public struct LevelBar: Widget {
|
||||
/// detailed signal "changed::x" in order to only receive callbacks when
|
||||
/// the value of offset "x" changes.
|
||||
var offsetChanged: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `LevelBar`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(gtk_level_bar_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - type: The view render data type.
|
||||
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
|
||||
if let offsetChanged {
|
||||
storage.connectSignal(name: "offset-changed", argCount: 1) {
|
||||
offsetChanged()
|
||||
@ -171,23 +170,26 @@ public struct LevelBar: Widget {
|
||||
}
|
||||
storage.modify { widget in
|
||||
|
||||
if let inverted, updateProperties {
|
||||
if let inverted, updateProperties, (storage.previousState as? Self)?.inverted != inverted {
|
||||
gtk_level_bar_set_inverted(widget, inverted.cBool)
|
||||
}
|
||||
if let maxValue, updateProperties {
|
||||
if let maxValue, updateProperties, (storage.previousState as? Self)?.maxValue != maxValue {
|
||||
gtk_level_bar_set_max_value(widget, maxValue)
|
||||
}
|
||||
if let minValue, updateProperties {
|
||||
if let minValue, updateProperties, (storage.previousState as? Self)?.minValue != minValue {
|
||||
gtk_level_bar_set_min_value(widget, minValue)
|
||||
}
|
||||
if let value, updateProperties {
|
||||
if let value, updateProperties, (storage.previousState as? Self)?.value != value {
|
||||
gtk_level_bar_set_value(widget, value)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// LinkButton.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -34,12 +34,12 @@ import LevenshteinTransformations
|
||||
/// # Accessibility
|
||||
///
|
||||
/// `GtkLinkButton` uses the %GTK_ACCESSIBLE_ROLE_LINK role.
|
||||
public struct LinkButton: Widget {
|
||||
public struct LinkButton: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The accessible role of the given `GtkAccessible` implementation.
|
||||
///
|
||||
@ -82,39 +82,38 @@ public struct LinkButton: Widget {
|
||||
var activate: (() -> Void)?
|
||||
/// Emitted when the button has been activated (pressed and released).
|
||||
var clicked: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `LinkButton`.
|
||||
public init(uri: String) {
|
||||
self.uri = uri
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(gtk_link_button_new(uri)?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let childStorage = child?().storage(data: data, type: type) {
|
||||
storage.content["child"] = [childStorage]
|
||||
gtk_button_set_child(storage.pointer?.cast(), childStorage.pointer?.cast())
|
||||
gtk_button_set_child(storage.opaquePointer?.cast(), childStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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()
|
||||
@ -127,38 +126,41 @@ public struct LinkButton: Widget {
|
||||
}
|
||||
storage.modify { widget in
|
||||
|
||||
if let actionName, updateProperties {
|
||||
if let actionName, updateProperties, (storage.previousState as? Self)?.actionName != actionName {
|
||||
gtk_actionable_set_action_name(widget, actionName)
|
||||
}
|
||||
if let canShrink, updateProperties {
|
||||
if let canShrink, updateProperties, (storage.previousState as? Self)?.canShrink != canShrink {
|
||||
gtk_button_set_can_shrink(widget?.cast(), canShrink.cBool)
|
||||
}
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let hasFrame, updateProperties {
|
||||
if let hasFrame, updateProperties, (storage.previousState as? Self)?.hasFrame != hasFrame {
|
||||
gtk_button_set_has_frame(widget?.cast(), hasFrame.cBool)
|
||||
}
|
||||
if let iconName, updateProperties {
|
||||
if let iconName, updateProperties, (storage.previousState as? Self)?.iconName != iconName {
|
||||
gtk_button_set_icon_name(widget?.cast(), iconName)
|
||||
}
|
||||
if let label, storage.content["child"] == nil, updateProperties {
|
||||
if let label, storage.content["child"] == nil, updateProperties, (storage.previousState as? Self)?.label != label {
|
||||
gtk_button_set_label(widget?.cast(), label)
|
||||
}
|
||||
if updateProperties {
|
||||
if updateProperties, (storage.previousState as? Self)?.uri != uri {
|
||||
gtk_link_button_set_uri(widget, uri)
|
||||
}
|
||||
if let useUnderline, updateProperties {
|
||||
if let useUnderline, updateProperties, (storage.previousState as? Self)?.useUnderline != useUnderline {
|
||||
gtk_button_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
if let visited, updateProperties {
|
||||
if let visited, updateProperties, (storage.previousState as? Self)?.visited != visited {
|
||||
gtk_link_button_set_visited(widget, visited.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// ListBox.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -61,12 +61,12 @@ import LevenshteinTransformations
|
||||
///
|
||||
/// `GtkListBox` uses the %GTK_ACCESSIBLE_ROLE_LIST role and `GtkListBoxRow` uses
|
||||
/// the %GTK_ACCESSIBLE_ROLE_LIST_ITEM role.
|
||||
public struct ListBox<Element>: Widget where Element: Identifiable {
|
||||
public struct ListBox<Element>: AdwaitaWidget where Element: Identifiable {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// Whether to accept unpaired release events.
|
||||
var acceptUnpairedRelease: Bool?
|
||||
@ -115,10 +115,6 @@ public struct ListBox<Element>: Widget where Element: Identifiable {
|
||||
var elements: [Element]
|
||||
/// The dynamic widget content.
|
||||
var content: (Element) -> Body
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ListBox`.
|
||||
public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) {
|
||||
@ -126,25 +122,28 @@ public struct ListBox<Element>: Widget where Element: Identifiable {
|
||||
self.content = content
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(gtk_list_box_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - type: The view render data type.
|
||||
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
|
||||
if let activateCursorRow {
|
||||
storage.connectSignal(name: "activate-cursor-row", argCount: 0) {
|
||||
activateCursorRow()
|
||||
@ -187,10 +186,10 @@ public struct ListBox<Element>: Widget where Element: Identifiable {
|
||||
}
|
||||
storage.modify { widget in
|
||||
|
||||
if let activateOnSingleClick, updateProperties {
|
||||
if let activateOnSingleClick, updateProperties, (storage.previousState as? Self)?.activateOnSingleClick != activateOnSingleClick {
|
||||
gtk_list_box_set_activate_on_single_click(widget, activateOnSingleClick.cBool)
|
||||
}
|
||||
if let showSeparators, updateProperties {
|
||||
if let showSeparators, updateProperties, (storage.previousState as? Self)?.showSeparators != showSeparators {
|
||||
gtk_list_box_set_show_separators(widget, showSeparators.cBool)
|
||||
}
|
||||
|
||||
@ -199,28 +198,31 @@ public struct ListBox<Element>: Widget where Element: Identifiable {
|
||||
old.identifiableTransform(
|
||||
to: elements,
|
||||
functions: .init { index, element in
|
||||
let child = content(element).widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
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.pointer?.cast(), index.cInt)
|
||||
gtk_list_box_insert(widget, child.opaquePointer?.cast(), index.cInt)
|
||||
contentStorage.remove(at: index)
|
||||
contentStorage.insert(child, at: index)
|
||||
} delete: { 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
|
||||
let child = content(element).widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
gtk_list_box_insert(widget, child.pointer?.cast(), index.cInt)
|
||||
let child = content(element).storage(data: data, type: type)
|
||||
gtk_list_box_insert(widget, child.opaquePointer?.cast(), index.cInt)
|
||||
contentStorage.insert(child, at: index)
|
||||
}
|
||||
)
|
||||
storage.fields["element"] = elements
|
||||
storage.content[.mainContent] = contentStorage
|
||||
for (index, element) in elements.enumerated() {
|
||||
content(element).widget(modifiers: modifiers).update(contentStorage[index], modifiers: modifiers, updateProperties: updateProperties)
|
||||
content(element).updateStorage(contentStorage[index], data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Menu.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -69,12 +69,12 @@ import LevenshteinTransformations
|
||||
/// # Accessibility
|
||||
///
|
||||
/// `GtkMenuButton` uses the %GTK_ACCESSIBLE_ROLE_BUTTON role.
|
||||
public struct Menu: Widget {
|
||||
public struct Menu: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The accessible role of the given `GtkAccessible` implementation.
|
||||
///
|
||||
@ -99,7 +99,7 @@ public struct Menu: Widget {
|
||||
///
|
||||
/// See [method@Gtk.MenuButton.set_menu_model] for the interaction
|
||||
/// with the [property@Gtk.MenuButton:popover] property.
|
||||
var menuModel: (() -> MenuContent)?
|
||||
var menuModel: (() -> Body)?
|
||||
/// Whether the menu button acts as a primary menu.
|
||||
///
|
||||
/// Primary menus can be opened using the <kbd>F10</kbd> key
|
||||
@ -111,45 +111,42 @@ public struct Menu: Widget {
|
||||
/// The `::activate` signal on `GtkMenuButton` is an action signal and
|
||||
/// emitting it causes the button to pop up its menu.
|
||||
var activate: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Menu`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(gtk_menu_button_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let childStorage = child?().storage(data: data, type: type) {
|
||||
storage.content["child"] = [childStorage]
|
||||
gtk_menu_button_set_child(storage.pointer, childStorage.pointer?.cast())
|
||||
}
|
||||
if let declarative = menuModel?(), let app {
|
||||
let menu = g_menu_new()
|
||||
gtk_menu_button_set_menu_model(storage.pointer, menu?.cast())
|
||||
for item in declarative {
|
||||
item.addMenuItems(menu: menu, app: app, window: window)
|
||||
gtk_menu_button_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())
|
||||
}
|
||||
if let menu = menuModel?() {
|
||||
let childStorage = MenuCollection { menu }.getMenu(data: data)
|
||||
storage.content["menuModel"] = [childStorage]
|
||||
gtk_menu_button_set_menu_model(storage.opaquePointer, childStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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()
|
||||
@ -158,43 +155,50 @@ public struct Menu: Widget {
|
||||
storage.modify { widget in
|
||||
|
||||
storage.notify(name: "active") {
|
||||
let newValue = gtk_menu_button_get_active(storage.pointer) != 0
|
||||
let newValue = gtk_menu_button_get_active(storage.opaquePointer) != 0
|
||||
if let active, newValue != active.wrappedValue {
|
||||
active.wrappedValue = newValue
|
||||
}
|
||||
}
|
||||
if let active, updateProperties, (gtk_menu_button_get_active(storage.pointer) != 0) != active.wrappedValue {
|
||||
gtk_menu_button_set_active(storage.pointer, active.wrappedValue.cBool)
|
||||
if let active, updateProperties, (gtk_menu_button_get_active(storage.opaquePointer) != 0) != active.wrappedValue {
|
||||
gtk_menu_button_set_active(storage.opaquePointer, active.wrappedValue.cBool)
|
||||
}
|
||||
if let alwaysShowArrow, updateProperties {
|
||||
if let alwaysShowArrow, updateProperties, (storage.previousState as? Self)?.alwaysShowArrow != alwaysShowArrow {
|
||||
gtk_menu_button_set_always_show_arrow(widget, alwaysShowArrow.cBool)
|
||||
}
|
||||
if let canShrink, updateProperties {
|
||||
if let canShrink, updateProperties, (storage.previousState as? Self)?.canShrink != canShrink {
|
||||
gtk_menu_button_set_can_shrink(widget, canShrink.cBool)
|
||||
}
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let hasFrame, updateProperties {
|
||||
if let hasFrame, updateProperties, (storage.previousState as? Self)?.hasFrame != hasFrame {
|
||||
gtk_menu_button_set_has_frame(widget, hasFrame.cBool)
|
||||
}
|
||||
if let iconName, updateProperties {
|
||||
if let iconName, updateProperties, (storage.previousState as? Self)?.iconName != iconName {
|
||||
gtk_menu_button_set_icon_name(widget, iconName)
|
||||
}
|
||||
if let label, storage.content["child"] == nil, updateProperties {
|
||||
if let label, storage.content["child"] == nil, updateProperties, (storage.previousState as? Self)?.label != label {
|
||||
gtk_menu_button_set_label(widget, label)
|
||||
}
|
||||
if let primary, updateProperties {
|
||||
if let menu = storage.content["menuModel"]?.first {
|
||||
MenuCollection { menuModel?() ?? [] }
|
||||
.updateStorage(menu, data: data.noModifiers, updateProperties: updateProperties, type: MenuContext.self)
|
||||
}
|
||||
if let primary, updateProperties, (storage.previousState as? Self)?.primary != primary {
|
||||
gtk_menu_button_set_primary(widget, primary.cBool)
|
||||
}
|
||||
if let useUnderline, updateProperties {
|
||||
if let useUnderline, updateProperties, (storage.previousState as? Self)?.useUnderline != useUnderline {
|
||||
gtk_menu_button_set_use_underline(widget, useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,10 +273,10 @@ if let active, newValue != active.wrappedValue {
|
||||
///
|
||||
/// See [method@Gtk.MenuButton.set_menu_model] for the interaction
|
||||
/// with the [property@Gtk.MenuButton:popover] property.
|
||||
public func menuModel(app: GTUIApp, window: GTUIApplicationWindow? = nil, @MenuBuilder _ menuModel: @escaping (() -> MenuContent)) -> Self {
|
||||
public func menuModel(@ViewBuilder _ menuModel: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.menuModel = menuModel
|
||||
newSelf.app = app; newSelf.window = window
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// NavigationView.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -118,12 +118,12 @@ import LevenshteinTransformations
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `AdwNavigationView` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
public struct NavigationView: Widget {
|
||||
public struct NavigationView: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// Whether to animate page transitions.
|
||||
///
|
||||
@ -162,34 +162,33 @@ public struct NavigationView: Widget {
|
||||
///
|
||||
/// See [method@NavigationView.replace].
|
||||
var replaced: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `NavigationView`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_navigation_view_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - type: The view render data type.
|
||||
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
|
||||
if let getNextPage {
|
||||
storage.connectSignal(name: "get-next-page", argCount: 0) {
|
||||
getNextPage()
|
||||
@ -212,17 +211,20 @@ public struct NavigationView: Widget {
|
||||
}
|
||||
storage.modify { widget in
|
||||
|
||||
if let animateTransitions, updateProperties {
|
||||
if let animateTransitions, updateProperties, (storage.previousState as? Self)?.animateTransitions != animateTransitions {
|
||||
adw_navigation_view_set_animate_transitions(widget, animateTransitions.cBool)
|
||||
}
|
||||
if let popOnEscape, updateProperties {
|
||||
if let popOnEscape, updateProperties, (storage.previousState as? Self)?.popOnEscape != popOnEscape {
|
||||
adw_navigation_view_set_pop_on_escape(widget, popOnEscape.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Overlay.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -40,12 +40,12 @@ import LevenshteinTransformations
|
||||
/// `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: Widget {
|
||||
public struct Overlay: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The accessible role of the given `GtkAccessible` implementation.
|
||||
///
|
||||
@ -70,44 +70,43 @@ public struct Overlay: Widget {
|
||||
var getChildPosition: (() -> Void)?
|
||||
/// The body for the widget "overlay".
|
||||
var overlay: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Overlay`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(gtk_overlay_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let childStorage = child?().storage(data: data, type: type) {
|
||||
storage.content["child"] = [childStorage]
|
||||
gtk_overlay_set_child(storage.pointer, childStorage.pointer?.cast())
|
||||
gtk_overlay_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
var overlayStorage: [ViewStorage] = []
|
||||
for view in overlay() {
|
||||
overlayStorage.append(view.storage(modifiers: modifiers))
|
||||
gtk_overlay_add_overlay(storage.pointer, overlayStorage.last?.pointer?.cast())
|
||||
overlayStorage.append(view.storage(data: data, type: type))
|
||||
gtk_overlay_add_overlay(storage.opaquePointer, overlayStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["overlay"] = overlayStorage
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - type: The view render data type.
|
||||
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
|
||||
if let getChildPosition {
|
||||
storage.connectSignal(name: "get-child-position", argCount: 2) {
|
||||
getChildPosition()
|
||||
@ -116,7 +115,7 @@ public struct Overlay: Widget {
|
||||
storage.modify { widget in
|
||||
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
|
||||
if let overlayStorage = storage.content["overlay"] {
|
||||
@ -124,8 +123,9 @@ public struct Overlay: Widget {
|
||||
if let storage = overlayStorage[safe: index] {
|
||||
view.updateStorage(
|
||||
storage,
|
||||
modifiers: modifiers,
|
||||
updateProperties: updateProperties
|
||||
data: data,
|
||||
updateProperties: updateProperties,
|
||||
type: type
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -133,7 +133,10 @@ public struct Overlay: Widget {
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// OverlaySplitView.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -113,12 +113,12 @@ import LevenshteinTransformations
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `AdwOverlaySplitView` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
public struct OverlaySplitView: Widget {
|
||||
public struct OverlaySplitView: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// Whether the split view is collapsed.
|
||||
///
|
||||
@ -170,85 +170,87 @@ public struct OverlaySplitView: Widget {
|
||||
/// The sidebar widget can be allocated with larger width if its own minimum
|
||||
/// width exceeds the preferred width.
|
||||
var sidebarWidthFraction: Double?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `OverlaySplitView`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_overlay_split_view_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let contentStorage = content?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let contentStorage = content?().storage(data: data, type: type) {
|
||||
storage.content["content"] = [contentStorage]
|
||||
adw_overlay_split_view_set_content(storage.pointer, contentStorage.pointer?.cast())
|
||||
adw_overlay_split_view_set_content(storage.opaquePointer, contentStorage.opaquePointer?.cast())
|
||||
}
|
||||
if let sidebarStorage = sidebar?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
if let sidebarStorage = sidebar?().storage(data: data, type: type) {
|
||||
storage.content["sidebar"] = [sidebarStorage]
|
||||
adw_overlay_split_view_set_sidebar(storage.pointer, sidebarStorage.pointer?.cast())
|
||||
adw_overlay_split_view_set_sidebar(storage.opaquePointer, sidebarStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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
|
||||
|
||||
storage.notify(name: "show-sidebar") {
|
||||
let newValue = adw_overlay_split_view_get_show_sidebar(storage.pointer) != 0
|
||||
let newValue = adw_overlay_split_view_get_show_sidebar(storage.opaquePointer) != 0
|
||||
if let showSidebar, newValue != showSidebar.wrappedValue {
|
||||
showSidebar.wrappedValue = newValue
|
||||
}
|
||||
}
|
||||
if let collapsed, updateProperties {
|
||||
if let collapsed, updateProperties, (storage.previousState as? Self)?.collapsed != collapsed {
|
||||
adw_overlay_split_view_set_collapsed(widget, collapsed.cBool)
|
||||
}
|
||||
if let widget = storage.content["content"]?.first {
|
||||
content?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
content?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let enableHideGesture, updateProperties {
|
||||
if let enableHideGesture, updateProperties, (storage.previousState as? Self)?.enableHideGesture != enableHideGesture {
|
||||
adw_overlay_split_view_set_enable_hide_gesture(widget, enableHideGesture.cBool)
|
||||
}
|
||||
if let enableShowGesture, updateProperties {
|
||||
if let enableShowGesture, updateProperties, (storage.previousState as? Self)?.enableShowGesture != enableShowGesture {
|
||||
adw_overlay_split_view_set_enable_show_gesture(widget, enableShowGesture.cBool)
|
||||
}
|
||||
if let maxSidebarWidth, updateProperties {
|
||||
if let maxSidebarWidth, updateProperties, (storage.previousState as? Self)?.maxSidebarWidth != maxSidebarWidth {
|
||||
adw_overlay_split_view_set_max_sidebar_width(widget, maxSidebarWidth)
|
||||
}
|
||||
if let minSidebarWidth, updateProperties {
|
||||
if let minSidebarWidth, updateProperties, (storage.previousState as? Self)?.minSidebarWidth != minSidebarWidth {
|
||||
adw_overlay_split_view_set_min_sidebar_width(widget, minSidebarWidth)
|
||||
}
|
||||
if let pinSidebar, updateProperties {
|
||||
if let pinSidebar, updateProperties, (storage.previousState as? Self)?.pinSidebar != pinSidebar {
|
||||
adw_overlay_split_view_set_pin_sidebar(widget, pinSidebar.cBool)
|
||||
}
|
||||
if let showSidebar, updateProperties, (adw_overlay_split_view_get_show_sidebar(storage.pointer) != 0) != showSidebar.wrappedValue {
|
||||
adw_overlay_split_view_set_show_sidebar(storage.pointer, showSidebar.wrappedValue.cBool)
|
||||
if let showSidebar, updateProperties, (adw_overlay_split_view_get_show_sidebar(storage.opaquePointer) != 0) != showSidebar.wrappedValue {
|
||||
adw_overlay_split_view_set_show_sidebar(storage.opaquePointer, showSidebar.wrappedValue.cBool)
|
||||
}
|
||||
if let widget = storage.content["sidebar"]?.first {
|
||||
sidebar?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
sidebar?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let sidebarWidthFraction, updateProperties {
|
||||
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, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// PasswordEntryRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -24,12 +24,12 @@ import LevenshteinTransformations
|
||||
///
|
||||
/// `AdwPasswordEntryRow` has a single CSS node with name `row` that carries
|
||||
/// `.entry` and `.password` style classes.
|
||||
public struct PasswordEntryRow: Widget {
|
||||
public struct PasswordEntryRow: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// Whether activating the embedded entry can activate the default widget.
|
||||
var activatesDefault: Bool?
|
||||
@ -76,46 +76,45 @@ public struct PasswordEntryRow: Widget {
|
||||
var suffix: () -> Body = { [] }
|
||||
/// The body for the widget "prefix".
|
||||
var prefix: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `PasswordEntryRow`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_password_entry_row_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
var suffixStorage: [ViewStorage] = []
|
||||
for view in suffix() {
|
||||
suffixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_entry_row_add_suffix(storage.pointer?.cast(), suffixStorage.last?.pointer?.cast())
|
||||
suffixStorage.append(view.storage(data: data, type: type))
|
||||
adw_entry_row_add_suffix(storage.opaquePointer?.cast(), suffixStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["suffix"] = suffixStorage
|
||||
var prefixStorage: [ViewStorage] = []
|
||||
for view in prefix() {
|
||||
prefixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_entry_row_add_prefix(storage.pointer?.cast(), prefixStorage.last?.pointer?.cast())
|
||||
prefixStorage.append(view.storage(data: data, type: type))
|
||||
adw_entry_row_add_prefix(storage.opaquePointer?.cast(), prefixStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["prefix"] = prefixStorage
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - type: The view render data type.
|
||||
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
|
||||
if let apply {
|
||||
storage.connectSignal(name: "apply", argCount: 0) {
|
||||
apply()
|
||||
@ -128,32 +127,35 @@ public struct PasswordEntryRow: Widget {
|
||||
}
|
||||
storage.modify { widget in
|
||||
|
||||
if let activatesDefault, updateProperties {
|
||||
if let activatesDefault, updateProperties, (storage.previousState as? Self)?.activatesDefault != activatesDefault {
|
||||
adw_entry_row_set_activates_default(widget?.cast(), activatesDefault.cBool)
|
||||
}
|
||||
if let enableEmojiCompletion, updateProperties {
|
||||
if let enableEmojiCompletion, updateProperties, (storage.previousState as? Self)?.enableEmojiCompletion != enableEmojiCompletion {
|
||||
adw_entry_row_set_enable_emoji_completion(widget?.cast(), enableEmojiCompletion.cBool)
|
||||
}
|
||||
if let showApplyButton, updateProperties {
|
||||
if let showApplyButton, updateProperties, (storage.previousState as? Self)?.showApplyButton != showApplyButton {
|
||||
adw_entry_row_set_show_apply_button(widget?.cast(), showApplyButton.cBool)
|
||||
}
|
||||
if let title, updateProperties {
|
||||
if let title, updateProperties, (storage.previousState as? Self)?.title != title {
|
||||
adw_preferences_row_set_title(widget?.cast(), title)
|
||||
}
|
||||
if let titleSelectable, updateProperties {
|
||||
if let titleSelectable, updateProperties, (storage.previousState as? Self)?.titleSelectable != titleSelectable {
|
||||
adw_preferences_row_set_title_selectable(widget?.cast(), titleSelectable.cBool)
|
||||
}
|
||||
if let useMarkup, updateProperties {
|
||||
if let useMarkup, updateProperties, (storage.previousState as? Self)?.useMarkup != useMarkup {
|
||||
adw_preferences_row_set_use_markup(widget?.cast(), useMarkup.cBool)
|
||||
}
|
||||
if let useUnderline, updateProperties {
|
||||
if let useUnderline, updateProperties, (storage.previousState as? Self)?.useUnderline != useUnderline {
|
||||
adw_preferences_row_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Picture.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -54,12 +54,12 @@ import LevenshteinTransformations
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `GtkPicture` uses the `GTK_ACCESSIBLE_ROLE_IMG` role.
|
||||
public struct Picture: Widget {
|
||||
public struct Picture: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The accessible role of the given `GtkAccessible` implementation.
|
||||
///
|
||||
@ -71,56 +71,52 @@ public struct Picture: Widget {
|
||||
var canShrink: Bool?
|
||||
/// How the content should be resized to fit inside the `GtkPicture`.
|
||||
var contentFit: ContentFit?
|
||||
/// Whether the GtkPicture will render its contents trying to preserve the aspect
|
||||
/// ratio.
|
||||
var keepAspectRatio: Bool?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Picture`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(gtk_picture_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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 alternativeText, updateProperties {
|
||||
if let alternativeText, updateProperties, (storage.previousState as? Self)?.alternativeText != alternativeText {
|
||||
gtk_picture_set_alternative_text(widget, alternativeText)
|
||||
}
|
||||
if let canShrink, updateProperties {
|
||||
if let canShrink, updateProperties, (storage.previousState as? Self)?.canShrink != canShrink {
|
||||
gtk_picture_set_can_shrink(widget, canShrink.cBool)
|
||||
}
|
||||
if let contentFit, updateProperties {
|
||||
if let contentFit, updateProperties, (storage.previousState as? Self)?.contentFit != contentFit {
|
||||
gtk_picture_set_content_fit(widget, contentFit.gtkValue)
|
||||
}
|
||||
if let keepAspectRatio, updateProperties {
|
||||
gtk_picture_set_keep_aspect_ratio(widget, keepAspectRatio.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,13 +154,4 @@ public struct Picture: Widget {
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the GtkPicture will render its contents trying to preserve the aspect
|
||||
/// ratio.
|
||||
public func keepAspectRatio(_ keepAspectRatio: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.keepAspectRatio = keepAspectRatio
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Popover.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -68,12 +68,12 @@ import LevenshteinTransformations
|
||||
/// be the same. The arrow also does not support any border shape other than
|
||||
/// solid, no border-radius, only one border width (border-bottom-width is
|
||||
/// used) and no box-shadow.
|
||||
public struct Popover: Widget {
|
||||
public struct Popover: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The accessible role of the given `GtkAccessible` implementation.
|
||||
///
|
||||
@ -99,42 +99,41 @@ public struct Popover: Widget {
|
||||
var activateDefault: (() -> Void)?
|
||||
/// Emitted when the popover is closed.
|
||||
var closed: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Popover`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(gtk_popover_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let childStorage = child?().storage(data: data, type: type) {
|
||||
storage.content["child"] = [childStorage]
|
||||
gtk_popover_set_child(storage.pointer?.cast(), childStorage.pointer?.cast())
|
||||
gtk_popover_set_child(storage.opaquePointer?.cast(), childStorage.opaquePointer?.cast())
|
||||
}
|
||||
if let defaultWidgetStorage = defaultWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
if let defaultWidgetStorage = defaultWidget?().storage(data: data, type: type) {
|
||||
storage.content["defaultWidget"] = [defaultWidgetStorage]
|
||||
gtk_popover_set_default_widget(storage.pointer?.cast(), defaultWidgetStorage.pointer?.cast())
|
||||
gtk_popover_set_default_widget(storage.opaquePointer?.cast(), defaultWidgetStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - type: The view render data type.
|
||||
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
|
||||
if let activateDefault {
|
||||
storage.connectSignal(name: "activate-default", argCount: 0) {
|
||||
activateDefault()
|
||||
@ -147,29 +146,32 @@ public struct Popover: Widget {
|
||||
}
|
||||
storage.modify { widget in
|
||||
|
||||
if let autohide, updateProperties {
|
||||
if let autohide, updateProperties, (storage.previousState as? Self)?.autohide != autohide {
|
||||
gtk_popover_set_autohide(widget?.cast(), autohide.cBool)
|
||||
}
|
||||
if let cascadePopdown, updateProperties {
|
||||
if let cascadePopdown, updateProperties, (storage.previousState as? Self)?.cascadePopdown != cascadePopdown {
|
||||
gtk_popover_set_cascade_popdown(widget?.cast(), cascadePopdown.cBool)
|
||||
}
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let widget = storage.content["defaultWidget"]?.first {
|
||||
defaultWidget?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
defaultWidget?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let hasArrow, updateProperties {
|
||||
if let hasArrow, updateProperties, (storage.previousState as? Self)?.hasArrow != hasArrow {
|
||||
gtk_popover_set_has_arrow(widget?.cast(), hasArrow.cBool)
|
||||
}
|
||||
if let mnemonicsVisible, updateProperties {
|
||||
if let mnemonicsVisible, updateProperties, (storage.previousState as? Self)?.mnemonicsVisible != mnemonicsVisible {
|
||||
gtk_popover_set_mnemonics_visible(widget?.cast(), mnemonicsVisible.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// PreferencesGroup.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -36,12 +36,12 @@ import LevenshteinTransformations
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `AdwPreferencesGroup` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
public struct PreferencesGroup: Widget {
|
||||
public struct PreferencesGroup: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The description for this group of preferences.
|
||||
var description: String?
|
||||
@ -56,53 +56,52 @@ public struct PreferencesGroup: Widget {
|
||||
var title: String?
|
||||
/// The body for the widget "child".
|
||||
var child: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `PreferencesGroup`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_preferences_group_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let headerSuffixStorage = headerSuffix?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let headerSuffixStorage = headerSuffix?().storage(data: data, type: type) {
|
||||
storage.content["headerSuffix"] = [headerSuffixStorage]
|
||||
adw_preferences_group_set_header_suffix(storage.pointer?.cast(), headerSuffixStorage.pointer?.cast())
|
||||
adw_preferences_group_set_header_suffix(storage.opaquePointer?.cast(), headerSuffixStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
var childStorage: [ViewStorage] = []
|
||||
for view in child() {
|
||||
childStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_preferences_group_add(storage.pointer?.cast(), childStorage.last?.pointer?.cast())
|
||||
childStorage.append(view.storage(data: data, type: type))
|
||||
adw_preferences_group_add(storage.opaquePointer?.cast(), childStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["child"] = childStorage
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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 description, updateProperties {
|
||||
if let description, updateProperties, (storage.previousState as? Self)?.description != description {
|
||||
adw_preferences_group_set_description(widget?.cast(), description)
|
||||
}
|
||||
if let widget = storage.content["headerSuffix"]?.first {
|
||||
headerSuffix?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
headerSuffix?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let title, updateProperties {
|
||||
if let title, updateProperties, (storage.previousState as? Self)?.title != title {
|
||||
adw_preferences_group_set_title(widget?.cast(), title)
|
||||
}
|
||||
|
||||
@ -111,8 +110,9 @@ public struct PreferencesGroup: Widget {
|
||||
if let storage = childStorage[safe: index] {
|
||||
view.updateStorage(
|
||||
storage,
|
||||
modifiers: modifiers,
|
||||
updateProperties: updateProperties
|
||||
data: data,
|
||||
updateProperties: updateProperties,
|
||||
type: type
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -120,7 +120,10 @@ public struct PreferencesGroup: Widget {
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// PreferencesPage.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -22,12 +22,12 @@ import LevenshteinTransformations
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `AdwPreferencesPage` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
public struct PreferencesPage: Widget {
|
||||
public struct PreferencesPage: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The description to be displayed at the top of the page.
|
||||
var description: String?
|
||||
@ -41,55 +41,54 @@ public struct PreferencesPage: Widget {
|
||||
var useUnderline: Bool?
|
||||
/// The body for the widget "child".
|
||||
var child: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `PreferencesPage`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_preferences_page_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
var childStorage: [ViewStorage] = []
|
||||
for view in child() {
|
||||
childStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_preferences_group_add(storage.pointer?.cast(), childStorage.last?.pointer?.cast())
|
||||
childStorage.append(view.storage(data: data, type: type))
|
||||
adw_preferences_group_add(storage.opaquePointer?.cast(), childStorage.last?.opaquePointer?.cast())
|
||||
}
|
||||
storage.content["child"] = childStorage
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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 description, updateProperties {
|
||||
if let description, updateProperties, (storage.previousState as? Self)?.description != description {
|
||||
adw_preferences_page_set_description(widget?.cast(), description)
|
||||
}
|
||||
if let iconName, updateProperties {
|
||||
if let iconName, updateProperties, (storage.previousState as? Self)?.iconName != iconName {
|
||||
adw_preferences_page_set_icon_name(widget?.cast(), iconName)
|
||||
}
|
||||
if let name, updateProperties {
|
||||
if let name, updateProperties, (storage.previousState as? Self)?.name != name {
|
||||
adw_preferences_page_set_name(widget?.cast(), name)
|
||||
}
|
||||
if let title, updateProperties {
|
||||
if let title, updateProperties, (storage.previousState as? Self)?.title != title {
|
||||
adw_preferences_page_set_title(widget?.cast(), title)
|
||||
}
|
||||
if let useUnderline, updateProperties {
|
||||
if let useUnderline, updateProperties, (storage.previousState as? Self)?.useUnderline != useUnderline {
|
||||
adw_preferences_page_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
@ -98,8 +97,9 @@ public struct PreferencesPage: Widget {
|
||||
if let storage = childStorage[safe: index] {
|
||||
view.updateStorage(
|
||||
storage,
|
||||
modifiers: modifiers,
|
||||
updateProperties: updateProperties
|
||||
data: data,
|
||||
updateProperties: updateProperties,
|
||||
type: type
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -107,7 +107,10 @@ public struct PreferencesPage: Widget {
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// PreferencesRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -17,12 +17,12 @@ import LevenshteinTransformations
|
||||
/// [class@ActionRow] and its derivatives are convenient to use as preference
|
||||
/// rows as they take care of presenting the preference's title while letting you
|
||||
/// compose the inputs of the preference around it.
|
||||
public struct PreferencesRow: Widget {
|
||||
public struct PreferencesRow: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
@ -41,53 +41,55 @@ public struct PreferencesRow: Widget {
|
||||
var useMarkup: Bool?
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
var useUnderline: Bool?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `PreferencesRow`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(adw_preferences_row_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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 title, updateProperties {
|
||||
if let title, updateProperties, (storage.previousState as? Self)?.title != title {
|
||||
adw_preferences_row_set_title(widget?.cast(), title)
|
||||
}
|
||||
if let titleSelectable, updateProperties {
|
||||
if let titleSelectable, updateProperties, (storage.previousState as? Self)?.titleSelectable != titleSelectable {
|
||||
adw_preferences_row_set_title_selectable(widget?.cast(), titleSelectable.cBool)
|
||||
}
|
||||
if let useMarkup, updateProperties {
|
||||
if let useMarkup, updateProperties, (storage.previousState as? Self)?.useMarkup != useMarkup {
|
||||
adw_preferences_row_set_use_markup(widget?.cast(), useMarkup.cBool)
|
||||
}
|
||||
if let useUnderline, updateProperties {
|
||||
if let useUnderline, updateProperties, (storage.previousState as? Self)?.useUnderline != useUnderline {
|
||||
adw_preferences_row_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// ProgressBar.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -54,12 +54,12 @@ import LevenshteinTransformations
|
||||
/// # Accessibility
|
||||
///
|
||||
/// `GtkProgressBar` uses the %GTK_ACCESSIBLE_ROLE_PROGRESS_BAR role.
|
||||
public struct ProgressBar: Widget {
|
||||
public struct ProgressBar: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The accessible role of the given `GtkAccessible` implementation.
|
||||
///
|
||||
@ -84,56 +84,58 @@ public struct ProgressBar: Widget {
|
||||
var showText: Bool?
|
||||
/// Text to be displayed in the progress bar.
|
||||
var text: String?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ProgressBar`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(gtk_progress_bar_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - 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 fraction, updateProperties {
|
||||
if let fraction, updateProperties, (storage.previousState as? Self)?.fraction != fraction {
|
||||
gtk_progress_bar_set_fraction(widget, fraction)
|
||||
}
|
||||
if let inverted, updateProperties {
|
||||
if let inverted, updateProperties, (storage.previousState as? Self)?.inverted != inverted {
|
||||
gtk_progress_bar_set_inverted(widget, inverted.cBool)
|
||||
}
|
||||
if let pulseStep, updateProperties {
|
||||
if let pulseStep, updateProperties, (storage.previousState as? Self)?.pulseStep != pulseStep {
|
||||
gtk_progress_bar_set_pulse_step(widget, pulseStep)
|
||||
}
|
||||
if let showText, updateProperties {
|
||||
if let showText, updateProperties, (storage.previousState as? Self)?.showText != showText {
|
||||
gtk_progress_bar_set_show_text(widget, showText.cBool)
|
||||
}
|
||||
if let text, updateProperties {
|
||||
if let text, updateProperties, (storage.previousState as? Self)?.text != text {
|
||||
gtk_progress_bar_set_text(widget, text)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// ScrolledWindow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
// Created by auto-generation on 15.08.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
@ -76,12 +76,12 @@ import LevenshteinTransformations
|
||||
/// Until GTK 4.10, `GtkScrolledWindow` used the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
///
|
||||
/// Starting from GTK 4.12, `GtkScrolledWindow` uses the `GTK_ACCESSIBLE_ROLE_GENERIC` role.
|
||||
public struct ScrolledWindow: Widget {
|
||||
public struct ScrolledWindow: AdwaitaWidget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
var updateFunctions: [(ViewStorage, WidgetData, Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> Void] = []
|
||||
var appearFunctions: [(ViewStorage, WidgetData) -> Void] = []
|
||||
|
||||
/// The accessible role of the given `GtkAccessible` implementation.
|
||||
///
|
||||
@ -164,38 +164,37 @@ public struct ScrolledWindow: Widget {
|
||||
/// The horizontal or vertical adjustment is updated which triggers a
|
||||
/// signal that the scrolled window’s child may listen to and scroll itself.
|
||||
var scrollChild: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ScrolledWindow`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The view render data type.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
public func container<Data>(data: WidgetData, type: Data.Type) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(gtk_scrolled_window_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
function(storage, data)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
update(storage, data: data, updateProperties: true, type: type)
|
||||
if let childStorage = child?().storage(data: data, type: type) {
|
||||
storage.content["child"] = [childStorage]
|
||||
gtk_scrolled_window_set_child(storage.pointer, childStorage.pointer?.cast())
|
||||
gtk_scrolled_window_set_child(storage.opaquePointer, childStorage.opaquePointer?.cast())
|
||||
}
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
/// - type: The view render data type.
|
||||
public func update<Data>(_ storage: ViewStorage, data: WidgetData, updateProperties: Bool, type: Data.Type) where Data: ViewRenderData {
|
||||
if let edgeOvershot {
|
||||
storage.connectSignal(name: "edge-overshot", argCount: 1) {
|
||||
edgeOvershot()
|
||||
@ -219,40 +218,43 @@ public struct ScrolledWindow: Widget {
|
||||
storage.modify { widget in
|
||||
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
child?().updateStorage(widget, data: data, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
if let hasFrame, updateProperties {
|
||||
if let hasFrame, updateProperties, (storage.previousState as? Self)?.hasFrame != hasFrame {
|
||||
gtk_scrolled_window_set_has_frame(widget, hasFrame.cBool)
|
||||
}
|
||||
if let kineticScrolling, updateProperties {
|
||||
if let kineticScrolling, updateProperties, (storage.previousState as? Self)?.kineticScrolling != kineticScrolling {
|
||||
gtk_scrolled_window_set_kinetic_scrolling(widget, kineticScrolling.cBool)
|
||||
}
|
||||
if let maxContentHeight, updateProperties {
|
||||
if let maxContentHeight, updateProperties, (storage.previousState as? Self)?.maxContentHeight != maxContentHeight {
|
||||
gtk_scrolled_window_set_max_content_height(widget, maxContentHeight.cInt)
|
||||
}
|
||||
if let maxContentWidth, updateProperties {
|
||||
if let maxContentWidth, updateProperties, (storage.previousState as? Self)?.maxContentWidth != maxContentWidth {
|
||||
gtk_scrolled_window_set_max_content_width(widget, maxContentWidth.cInt)
|
||||
}
|
||||
if let minContentHeight, updateProperties {
|
||||
if let minContentHeight, updateProperties, (storage.previousState as? Self)?.minContentHeight != minContentHeight {
|
||||
gtk_scrolled_window_set_min_content_height(widget, minContentHeight.cInt)
|
||||
}
|
||||
if let minContentWidth, updateProperties {
|
||||
if let minContentWidth, updateProperties, (storage.previousState as? Self)?.minContentWidth != minContentWidth {
|
||||
gtk_scrolled_window_set_min_content_width(widget, minContentWidth.cInt)
|
||||
}
|
||||
if let overlayScrolling, updateProperties {
|
||||
if let overlayScrolling, updateProperties, (storage.previousState as? Self)?.overlayScrolling != overlayScrolling {
|
||||
gtk_scrolled_window_set_overlay_scrolling(widget, overlayScrolling.cBool)
|
||||
}
|
||||
if let propagateNaturalHeight, updateProperties {
|
||||
if let propagateNaturalHeight, updateProperties, (storage.previousState as? Self)?.propagateNaturalHeight != propagateNaturalHeight {
|
||||
gtk_scrolled_window_set_propagate_natural_height(widget, propagateNaturalHeight.cBool)
|
||||
}
|
||||
if let propagateNaturalWidth, updateProperties {
|
||||
if let propagateNaturalWidth, updateProperties, (storage.previousState as? Self)?.propagateNaturalWidth != propagateNaturalWidth {
|
||||
gtk_scrolled_window_set_propagate_natural_width(widget, propagateNaturalWidth.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
function(storage, data, updateProperties)
|
||||
}
|
||||
if updateProperties {
|
||||
storage.previousState = self
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user