7
7
8
8
package import Foundation
9
9
10
+ /// A size proposal that can have specified or unspecified dimensions.
11
+ ///
12
+ /// A proposed size is used in the layout system to communicate size constraints
13
+ /// to views and layout containers. Either dimension can be specified with a concrete
14
+ /// value or left unspecified (nil), allowing the receiver to choose its own size
15
+ /// for that dimension.
10
16
public struct _ProposedSize {
17
+ /// The proposed width, or `nil` if unspecified.
11
18
package var width : CGFloat ?
19
+
20
+ /// The proposed height, or `nil` if unspecified.
12
21
package var height : CGFloat ?
13
22
23
+ /// Creates a proposed size with optional width and height values.
24
+ ///
25
+ /// - Parameters:
26
+ /// - width: The proposed width, or `nil` if unspecified.
27
+ /// - height: The proposed height, or `nil` if unspecified.
14
28
package init ( width: CGFloat ? = nil , height: CGFloat ? = nil ) {
15
29
self . width = width
16
30
self . height = height
17
31
}
18
32
33
+ /// Creates a proposed size with both dimensions unspecified.
19
34
package init ( ) {
20
35
self . width = nil
21
36
self . height = nil
22
37
}
23
38
39
+ /// Converts to a concrete `CGSize` by replacing unspecified dimensions with the provided defaults.
40
+ ///
41
+ /// - Parameter defaults: The default size to use for unspecified dimensions.
42
+ /// - Returns: A `CGSize` with concrete values for both dimensions.
24
43
package func fixingUnspecifiedDimensions( at defaults: CGSize ) -> CGSize {
25
44
CGSize ( width: width ?? defaults. width, height: height ?? defaults. height)
26
45
}
27
46
47
+ /// Converts to a concrete `CGSize` by replacing unspecified dimensions with a default value of 10.0.
48
+ ///
49
+ /// - Returns: A `CGSize` with concrete values for both dimensions.
28
50
package func fixingUnspecifiedDimensions( ) -> CGSize {
29
51
CGSize ( width: width ?? 10.0 , height: height ?? 10.0 )
30
52
}
31
53
54
+ /// Creates a new proposed size by scaling both dimensions by the given factor.
55
+ ///
56
+ /// - Parameter s: The scale factor to apply.
57
+ /// - Returns: A new proposed size with scaled dimensions.
32
58
package func scaled( by s: CGFloat ) -> _ProposedSize {
33
59
_ProposedSize ( width: width. map { $0 * s } , height: height. map { $0 * s } )
34
60
}
35
61
62
+ /// A proposed size with both dimensions set to zero.
36
63
package static let zero = _ProposedSize ( width: 0 , height: 0 )
64
+
65
+ /// A proposed size with both dimensions set to infinity.
37
66
package static let infinity = _ProposedSize ( width: . infinity, height: . infinity)
67
+
68
+ /// A proposed size with both dimensions unspecified.
38
69
package static let unspecified = _ProposedSize ( width: nil , height: nil )
39
70
}
40
71
@@ -44,32 +75,54 @@ extension _ProposedSize: Sendable {}
44
75
extension _ProposedSize : Hashable { }
45
76
46
77
extension _ProposedSize {
78
+ /// Creates a proposed size from a concrete `CGSize`.
79
+ ///
80
+ /// - Parameter s: The concrete size to convert.
47
81
package init ( _ s: CGSize ) {
48
82
width = s. width
49
83
height = s. height
50
84
}
51
85
}
52
86
53
87
extension CGSize {
88
+ /// Creates a `CGSize` from a proposed size if both dimensions are specified.
89
+ ///
90
+ /// - Parameter p: The proposed size to convert.
91
+ /// - Returns: A `CGSize` if both dimensions are specified, or `nil` otherwise.
54
92
package init ? ( _ p: _ProposedSize ) {
55
93
guard let width = p. width, let height = p. height else { return nil }
56
94
self . init ( width: width, height: height)
57
95
}
58
96
}
59
97
60
98
extension _ProposedSize {
99
+ /// Creates a new proposed size by reducing both dimensions by the specified edge insets.
100
+ ///
101
+ /// - Parameter insets: The edge insets to apply.
102
+ /// - Returns: A new proposed size with insets applied.
61
103
package func inset( by insets: EdgeInsets ) -> _ProposedSize {
62
104
_ProposedSize (
63
105
width: width. map { max ( $0 - insets. leading - insets. trailing, . zero) } ,
64
106
height: height. map { max ( $0 - insets. top - insets. bottom, . zero) }
65
107
)
66
108
}
67
109
110
+ /// Accesses the dimension specified by the given axis.
111
+ ///
112
+ /// - Parameter axis: The axis to access (.horizontal for width, .vertical for height).
113
+ /// - Returns: The dimension for the specified axis.
68
114
package subscript( axis: Axis ) -> CGFloat ? {
69
115
get { axis == . horizontal ? width : height }
70
116
set { if axis == . horizontal { width = newValue } else { height = newValue } }
71
117
}
72
118
119
+ /// Creates a proposed size by assigning dimensions based on the specified axis.
120
+ ///
121
+ /// - Parameters:
122
+ /// - l1: The dimension for the first axis.
123
+ /// - first: The first axis (.horizontal or .vertical).
124
+ /// - l2: The dimension for the second axis.
125
+ /// - Returns: A new proposed size with dimensions assigned according to the axes.
73
126
package init ( _ l1: CGFloat ? , in first: Axis , by l2: CGFloat ? ) {
74
127
self = first == . horizontal ? _ProposedSize ( width: l1, height: l2) : _ProposedSize ( width: l2, height: l1)
75
128
}
0 commit comments