Skip to content

Commit 8fdbd2f

Browse files
authored
Update ViewGeomery documentation (#298)
* Update ViewGeomery documentation * Optimize RootGeometry
1 parent 83f62dc commit 8fdbd2f

File tree

2 files changed

+95
-18
lines changed

2 files changed

+95
-18
lines changed

Sources/OpenSwiftUICore/Layout/View/ViewGeometry.swift

Lines changed: 90 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,54 +8,133 @@
88
package import Foundation
99
package import OpenGraphShims
1010

11+
/// A type that represents the position and dimensions of a view in its parent's coordinate space.
12+
///
13+
/// `ViewGeometry` encapsulates both the origin (position) and dimensions (size and alignment guides)
14+
/// of a view. It provides methods to access alignment guides and convert to other geometric types.
1115
package struct ViewGeometry: Equatable {
16+
/// The position of the view in its parent's coordinate space.
1217
package var origin: ViewOrigin
18+
19+
/// The size and alignment information of the view.
1320
package var dimensions: ViewDimensions
14-
21+
22+
/// Creates a view geometry with the specified origin and dimensions.
23+
///
24+
/// - Parameters:
25+
/// - origin: The position of the view.
26+
/// - dimensions: The size and alignment information of the view.
1527
package init(origin: ViewOrigin, dimensions: ViewDimensions) {
1628
self.origin = origin
1729
self.dimensions = dimensions
1830
}
19-
31+
32+
/// Creates a view geometry at the default origin with the specified dimensions.
33+
///
34+
/// - Parameter dimensions: The size and alignment information of the view.
2035
package init(dimensions: ViewDimensions) {
2136
self.init(origin: ViewOrigin(), dimensions: dimensions)
2237
}
23-
38+
39+
/// Creates a view geometry with the specified CGPoint origin and dimensions.
40+
///
41+
/// - Parameters:
42+
/// - origin: The position of the view as a CGPoint.
43+
/// - dimensions: The size and alignment information of the view.
2444
package init(origin: CGPoint, dimensions: ViewDimensions) {
2545
self.init(origin: ViewOrigin(origin), dimensions: dimensions)
2646
}
27-
47+
48+
/// Creates a view geometry using placement and dimensions information.
49+
///
50+
/// - Parameters:
51+
/// - p: The placement that determines the origin of the view.
52+
/// - d: The size and alignment information of the view.
2853
package init(placement p: _Placement, dimensions d: ViewDimensions) {
2954
self.origin = ViewOrigin(p.frameOrigin(childSize: d.size.value))
3055
self.dimensions = d
3156
}
32-
57+
58+
/// Returns the position of the specified horizontal alignment guide.
59+
///
60+
/// - Parameter guide: The horizontal alignment guide to measure.
61+
/// - Returns: The x-coordinate of the alignment guide in the parent's coordinate space.
3362
package subscript(guide: HorizontalAlignment) -> CGFloat { dimensions[guide] }
63+
64+
/// Returns the position of the specified vertical alignment guide.
65+
///
66+
/// - Parameter guide: The vertical alignment guide to measure.
67+
/// - Returns: The y-coordinate of the alignment guide in the parent's coordinate space.
3468
package subscript(guide: VerticalAlignment) -> CGFloat { dimensions[guide] }
69+
70+
/// Returns the explicit position of the specified horizontal alignment guide if available.
71+
///
72+
/// - Parameter guide: The horizontal alignment guide to measure.
73+
/// - Returns: The x-coordinate of the alignment guide, or nil if not explicitly defined.
3574
package subscript(explicit guide: HorizontalAlignment) -> CGFloat? { dimensions[explicit: guide] }
75+
76+
/// Returns the explicit position of the specified vertical alignment guide if available.
77+
///
78+
/// - Parameter guide: The vertical alignment guide to measure.
79+
/// - Returns: The y-coordinate of the alignment guide, or nil if not explicitly defined.
3680
package subscript(explicit guide: VerticalAlignment) -> CGFloat? { dimensions[explicit: guide] }
3781
}
3882

83+
/// Extension to provide convenient accessors for `Attribute<ViewGeometry>`.
3984
extension Attribute where Value == ViewGeometry {
85+
/// Returns an attribute representing the origin of the view geometry.
86+
///
87+
/// - Returns: An attribute containing the view's origin.
4088
package func origin() -> Attribute<ViewOrigin> { self[keyPath: \.origin] }
89+
90+
/// Returns an attribute representing the size of the view geometry.
91+
///
92+
/// - Returns: An attribute containing the view's size.
4193
package func size() -> Attribute<ViewSize> { self[keyPath: \.dimensions.size] }
4294
}
4395

4496
extension ViewGeometry {
97+
/// The frame of the view as a CGRect.
98+
///
99+
/// This property combines the origin and size information into a CGRect.
45100
package var frame: CGRect {
46101
CGRect(origin: origin.value, size: dimensions.size.value)
47102
}
48-
103+
104+
/// A view geometry value representing an invalid state.
105+
///
106+
/// This value is used to indicate errors or uninitialized states.
49107
package static let invalidValue = ViewGeometry(origin: ViewOrigin(invalid: ()), dimensions: .invalidValue)
50-
108+
109+
/// Indicates whether this view geometry is in an invalid state.
51110
package var isInvalid: Bool { origin.x.isNaN }
52-
111+
112+
/// A view geometry with zero origin and zero dimensions.
113+
///
114+
/// This property provides a convenient way to create a view geometry at the origin
115+
/// with zero size.
53116
package static let zero = ViewGeometry(origin: CGPoint.zero, dimensions: .zero)
54-
117+
118+
/// Returns the position of the specified alignment key.
119+
///
120+
/// - Parameter key: The alignment key to measure.
121+
/// - Returns: The coordinate of the alignment guide in the parent's coordinate space.
55122
package subscript(key: AlignmentKey) -> CGFloat { dimensions[key] }
56-
123+
124+
/// Returns the explicit position of the specified alignment key if available.
125+
///
126+
/// - Parameter key: The alignment key to measure.
127+
/// - Returns: The coordinate of the alignment guide, or nil if not explicitly defined.
57128
package subscript(explicit key: AlignmentKey) -> CGFloat? { dimensions[explicit: key] }
58-
129+
130+
/// Adjusts the origin to account for right-to-left layout direction.
131+
///
132+
/// This method flips the x-coordinate when in right-to-left layout mode to maintain
133+
/// proper visual alignment from the right edge of the parent.
134+
///
135+
/// - Parameters:
136+
/// - layoutDirection: The layout direction to apply.
137+
/// - parentSize: The size of the parent container.
59138
package mutating func finalizeLayoutDirection(_ layoutDirection: LayoutDirection, parentSize: CGSize) {
60139
guard layoutDirection == .rightToLeft else { return }
61140
origin.x = parentSize.width - frame.maxX

Sources/OpenSwiftUICore/View/Graph/ViewGraph.swift

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -634,20 +634,18 @@ package struct RootGeometry: Rule, AsyncAttribute {
634634
origin += (proposal-fittingSize) * 0.5
635635
}
636636

637-
// For RTL layout, adjust the x position to maintain proper visual alignment
638-
if let layoutDirection, layoutDirection == .rightToLeft {
639-
// This flips the x-coordinate to maintain proper visual layout in RTL mode
640-
origin.x = proposedSize.width - CGRect(origin: origin, size: fittingSize).maxX
641-
}
642-
643-
return ViewGeometry(
637+
var geometry = ViewGeometry(
644638
origin: ViewOrigin(origin),
645639
dimensions: ViewDimensions(
646640
guideComputer: layoutComputer,
647641
size: fittingSize,
648642
proposal: .init(proposal)
649643
)
650644
)
645+
if let layoutDirection {
646+
geometry.finalizeLayoutDirection(layoutDirection, parentSize: proposedSize.value)
647+
}
648+
return geometry
651649
}
652650
}
653651

0 commit comments

Comments
 (0)