Add support for frame
All checks were successful
Deploy Docs / publish (push) Successful in 3m50s
SwiftLint / SwiftLint (push) Successful in 3s

This commit is contained in:
david-swift 2025-01-05 11:07:46 +01:00
parent caa8e6bb6e
commit faffc6da0f
5 changed files with 228 additions and 0 deletions

View File

@ -0,0 +1,37 @@
//
// Alignment.swift
// MacBackend
//
// Created by david-swift on 05.01.2025.
//
import SwiftUI
/// The two-dimensional alignment, consisting of the vertical and horizontal alignment.
public struct Alignment {
/// The center alignment.
public static var center: Self {
.init(vertical: .center, horizontal: .center)
}
/// The vertical alignment.
var vertical: VerticalAlignment
/// The horizontal alignment.
var horizontal: HorizontalAlignment
/// The SwiftUI alignment.
var swiftUI: SwiftUI.Alignment {
.init(horizontal: horizontal.swiftUI, vertical: vertical.swiftUI)
}
/// Initialize an alignment.
/// - Parameters:
/// - vertical: The vertical alignment.
/// - horizontal: The horizontal alignment.
public init(vertical: VerticalAlignment, horizontal: HorizontalAlignment) {
self.vertical = vertical
self.horizontal = horizontal
}
}

View File

@ -0,0 +1,32 @@
//
// HorizontalAlignment.swift
// MacBackend
//
// Created by david-swift on 05.01.25.
//
import SwiftUI
/// The horizontal alignment.
public enum HorizontalAlignment {
/// The leading alignment.
case leading
/// The center alignment.
case center
/// The trailing alignment.
case trailing
/// The SwiftUI alignment.
var swiftUI: SwiftUI.HorizontalAlignment {
switch self {
case .leading:
.leading
case .center:
.center
case .trailing:
.trailing
}
}
}

View File

@ -0,0 +1,32 @@
//
// VerticalAlignment.swift
// MacBackend
//
// Created by david-swift on 05.01.25.
//
import SwiftUI
/// The vertical alignment.
public enum VerticalAlignment {
/// The top alignment.
case top
/// The center alignment.
case center
/// The bottom alignment.
case bottom
/// The SwiftUI alignment.
var swiftUI: SwiftUI.VerticalAlignment {
switch self {
case .top:
.top
case .center:
.center
case .bottom:
.bottom
}
}
}

View File

@ -0,0 +1,95 @@
//
// FrameWrapper.swift
// MacBackend
//
// Created by david-swift on 05.01.2025.
//
import SwiftUI
/// Wrap a view with a view that defines the wrapped view's frame.
public struct FrameWrapper: SwiftUIWidget {
/// The wrapped view.
var content: Body
/// The minimum width.
var minWidth: Double?
/// The ideal width.
var idealWidth: Double?
/// The maximum width.
var maxWidth: Double?
/// The minimum height.
var minHeight: Double?
/// The ideal height.
var idealHeight: Double?
/// The maximum height.
var maxHeight: Double?
/// The alignment inside the frame.
var alignment: Alignment
/// The wrapped views.
public var wrappedViews: [String: Meta.AnyView] {
[.mainContent: content]
}
/// Initialize a wrapper view defining a view's frame.
/// - Parameters:
/// - minWidth: The minimum width.
/// - idealWidth: The ideal width.
/// - maxWidth: The maximum width.
/// - minHeight: The minimum height.
/// - idealHeight: The ideal height.
/// - maxHeight: The maximum height.
/// - alignment: The alignment inside the view's frame.
/// - content: The wrapped view.
public init(
minWidth: Double? = nil,
idealWidth: Double? = nil,
maxWidth: Double? = nil,
minHeight: Double? = nil,
idealHeight: Double? = nil,
maxHeight: Double? = nil,
alignment: Alignment = .center,
@Meta.ViewBuilder content: () -> Body
) {
self.content = content()
self.minWidth = minWidth
self.idealWidth = idealWidth
self.maxWidth = maxWidth
self.minHeight = minHeight
self.idealHeight = idealHeight
self.maxHeight = maxHeight
self.alignment = alignment
}
/// Get the SwiftUI view.
/// - Parameter properties: The widget data.
/// - Returns: The SwiftUI view.
public static func view(properties: Self) -> some SwiftUI.View {
MacBackendView(.mainContent)
.frame(
minWidth: .init(properties.minWidth),
idealWidth: .init(properties.idealWidth),
maxWidth: .init(properties.maxWidth),
minHeight: .init(properties.minHeight),
idealHeight: .init(properties.idealHeight),
maxHeight: .init(properties.maxHeight),
alignment: properties.alignment.swiftUI
)
}
}
extension CGFloat {
/// Initialize a `CGFloat` from a `Double`.
/// - Parameter value: The double value.
public init?(_ value: Double?) {
if let value {
self = .init(value)
} else {
return nil
}
}
}

View File

@ -72,4 +72,36 @@ extension AnyView {
.init(isPresented: isPresented, content: { self }, dialog: dialog)
}
/// Define a view's frame.
/// - Parameters:
/// - minWidth: The minimum width.
/// - idealWidth: The ideal width.
/// - maxWidth: The maximum width.
/// - minHeight: The minimum height.
/// - idealHeight: The ideal height.
/// - maxHeight: The maximum height.
/// - alignment: The alignment inside the view's frame.
/// - Returns: The view.
public func frame(
minWidth: Double? = nil,
idealWidth: Double? = nil,
maxWidth: Double? = nil,
minHeight: Double? = nil,
idealHeight: Double? = nil,
maxHeight: Double? = nil,
alignment: Alignment = .center
) -> AnyView {
FrameWrapper(
minWidth: minWidth,
idealWidth: idealWidth,
maxWidth: maxWidth,
minHeight: minHeight,
idealHeight: idealHeight,
maxHeight: maxHeight,
alignment: alignment
) {
self
}
}
}