Add support for GtkFixed
This commit is contained in:
parent
77dd38e712
commit
574aca245a
53
Sources/Adwaita/View/Fixed+.swift
Normal file
53
Sources/Adwaita/View/Fixed+.swift
Normal file
@ -0,0 +1,53 @@
|
||||
//
|
||||
// Fixed+.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 21.07.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
extension Fixed {
|
||||
|
||||
/// Place an element in the coordinate system.
|
||||
/// - Parameters:
|
||||
/// - xCoordinate: The x coordinate.
|
||||
/// - yCoordinate: The y coordinate.
|
||||
/// - id: A unique identifier.
|
||||
/// - view: The element.
|
||||
/// - Returns: The coordinate system with the element.
|
||||
public func element(
|
||||
x xCoordinate: Double,
|
||||
y yCoordinate: Double,
|
||||
id: String,
|
||||
@ViewBuilder view: @escaping () -> Body
|
||||
) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.appearFunctions.append { storage, modifiers in
|
||||
let view = view().storage(modifiers: modifiers)
|
||||
gtk_fixed_put(
|
||||
storage.pointer?.cast(),
|
||||
view.pointer?.cast(),
|
||||
xCoordinate,
|
||||
yCoordinate
|
||||
)
|
||||
storage.content[id] = [view]
|
||||
}
|
||||
newSelf.updateFunctions.append { storage, modifiers, updateProperties in
|
||||
guard let content = storage.content[id]?.first else {
|
||||
return
|
||||
}
|
||||
view().updateStorage(content, modifiers: modifiers, updateProperties: updateProperties)
|
||||
if updateProperties {
|
||||
gtk_fixed_move(
|
||||
storage.pointer?.cast(),
|
||||
content.pointer?.cast(),
|
||||
xCoordinate,
|
||||
yCoordinate
|
||||
)
|
||||
}
|
||||
}
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
107
Sources/Adwaita/View/Generated/Fixed.swift
Normal file
107
Sources/Adwaita/View/Generated/Fixed.swift
Normal file
@ -0,0 +1,107 @@
|
||||
//
|
||||
// Fixed.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 21.07.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// `GtkFixed` places its child widgets at fixed positions and with fixed sizes.
|
||||
///
|
||||
/// `GtkFixed` performs no automatic layout management.
|
||||
///
|
||||
/// For most applications, you should not use this container! It keeps
|
||||
/// you from having to learn about the other GTK containers, but it
|
||||
/// results in broken applications. With `GtkFixed`, the following
|
||||
/// things will result in truncated text, overlapping widgets, and
|
||||
/// other display bugs:
|
||||
///
|
||||
/// - Themes, which may change widget sizes.
|
||||
///
|
||||
/// - Fonts other than the one you used to write the app will of course
|
||||
/// change the size of widgets containing text; keep in mind that
|
||||
/// users may use a larger font because of difficulty reading the
|
||||
/// default, or they may be using a different OS that provides different fonts.
|
||||
///
|
||||
/// - Translation of text into other languages changes its size. Also,
|
||||
/// display of non-English text will use a different font in many
|
||||
/// cases.
|
||||
///
|
||||
/// In addition, `GtkFixed` does not pay attention to text direction and
|
||||
/// thus may produce unwanted results if your app is run under right-to-left
|
||||
/// languages such as Hebrew or Arabic. That is: normally GTK will order
|
||||
/// containers appropriately for the text direction, e.g. to put labels to
|
||||
/// the right of the thing they label when using an RTL language, but it can’t
|
||||
/// do that with `GtkFixed`. So if you need to reorder widgets depending on
|
||||
/// the text direction, you would need to manually detect it and adjust child
|
||||
/// positions accordingly.
|
||||
///
|
||||
/// Finally, fixed positioning makes it kind of annoying to add/remove
|
||||
/// UI elements, since you have to reposition all the other elements. This
|
||||
/// is a long-term maintenance problem for your application.
|
||||
///
|
||||
/// 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 {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage, [(View) -> View], Bool) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage, [(View) -> View]) -> 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.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(gtk_fixed_new()?.opaque())
|
||||
for function in appearFunctions {
|
||||
function(storage, modifiers)
|
||||
}
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
storage.modify { widget in
|
||||
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage, modifiers, updateProperties)
|
||||
}
|
||||
}
|
||||
|
||||
/// The accessible role of the given `GtkAccessible` implementation.
|
||||
///
|
||||
/// The accessible role cannot be changed once set.
|
||||
public func accessibleRole(_ accessibleRole: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.accessibleRole = accessibleRole
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
@ -271,7 +271,8 @@ struct GenerationConfiguration {
|
||||
class: "Separator",
|
||||
initializer: "gtk_separator_new(GTK_ORIENTATION_VERTICAL)",
|
||||
excludeProperties: ["orientation"]
|
||||
)
|
||||
),
|
||||
.init(class: "Fixed")
|
||||
]
|
||||
|
||||
/// The unshortening map.
|
||||
|
28
Tests/FixedDemo.swift
Normal file
28
Tests/FixedDemo.swift
Normal file
@ -0,0 +1,28 @@
|
||||
//
|
||||
// FixedDemo.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 21.07.24.
|
||||
//
|
||||
|
||||
// swiftlint:disable missing_docs
|
||||
|
||||
import Adwaita
|
||||
import Foundation
|
||||
|
||||
struct FixedDemo: View {
|
||||
|
||||
@State private var button = (x: 0.0, y: 0.0)
|
||||
|
||||
var view: Body {
|
||||
Fixed()
|
||||
.element(x: button.x, y: button.y, id: "button") {
|
||||
Button("Move") {
|
||||
button = (x: Double.random(in: 0...100), y: Double.random(in: 0...100))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// swiftlint:enable missing_docs
|
@ -31,6 +31,7 @@ enum Page: String, Identifiable, CaseIterable, Codable, CustomStringConvertible
|
||||
case navigationView
|
||||
case picture
|
||||
case idle
|
||||
case fixed
|
||||
|
||||
var id: Self {
|
||||
self
|
||||
@ -102,6 +103,8 @@ enum Page: String, Identifiable, CaseIterable, Codable, CustomStringConvertible
|
||||
return "Display an image"
|
||||
case .idle:
|
||||
return "Update UI from an asynchronous context"
|
||||
case .fixed:
|
||||
return "Place widgets in a coordinate system"
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,6 +150,8 @@ enum Page: String, Identifiable, CaseIterable, Codable, CustomStringConvertible
|
||||
PictureDemo(url: pictureURL, app: app, window: window)
|
||||
case .idle:
|
||||
IdleDemo()
|
||||
case .fixed:
|
||||
FixedDemo()
|
||||
}
|
||||
}
|
||||
// swiftlint:enable cyclomatic_complexity
|
||||
|
Loading…
Reference in New Issue
Block a user