Skip to content

Commit 77cccbc

Browse files
committed
Add LayoutProxy implementation
1 parent 783b8c4 commit 77cccbc

File tree

1 file changed

+147
-0
lines changed

1 file changed

+147
-0
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
//
2+
// LayoutProxy.swift
3+
// OpenSwiftUICore
4+
//
5+
// Audited for iOS 18.0
6+
// Status: Complete
7+
8+
package import OpenGraphShims
9+
10+
package struct LayoutProxyAttributes: Equatable {
11+
@OptionalAttribute
12+
var layoutComputer: LayoutComputer?
13+
14+
@OptionalAttribute
15+
var traitList: (any ViewList)?
16+
17+
package init(layoutComputer: OptionalAttribute<LayoutComputer>, traitsList: OptionalAttribute<any ViewList>) {
18+
_layoutComputer = layoutComputer
19+
_traitList = traitsList
20+
}
21+
22+
package init(traitsList: OptionalAttribute<any ViewList>) {
23+
_layoutComputer = OptionalAttribute()
24+
_traitList = traitsList
25+
}
26+
27+
package init(layoutComputer: OptionalAttribute<LayoutComputer>) {
28+
_layoutComputer = layoutComputer
29+
_traitList = OptionalAttribute()
30+
}
31+
32+
package init() {
33+
_layoutComputer = OptionalAttribute()
34+
_traitList = OptionalAttribute()
35+
}
36+
37+
package var isEmpty: Bool {
38+
$layoutComputer == nil && $traitList == nil
39+
}
40+
}
41+
42+
package struct LayoutProxy: Equatable {
43+
var context: AnyRuleContext
44+
45+
var attributes: LayoutProxyAttributes
46+
47+
package init(context: AnyRuleContext, attributes: LayoutProxyAttributes) {
48+
self.context = context
49+
self.attributes = attributes
50+
}
51+
52+
package init(context: AnyRuleContext, layoutComputer: Attribute<LayoutComputer>?) {
53+
self.context = context
54+
self.attributes = LayoutProxyAttributes(layoutComputer: .init(layoutComputer))
55+
}
56+
57+
package var layoutComputer: LayoutComputer {
58+
guard let layoutComputer = attributes.$layoutComputer else {
59+
return .defaultValue
60+
}
61+
return context[layoutComputer]
62+
}
63+
64+
package var traits: ViewTraitCollection? {
65+
guard let traitList = attributes.$traitList else {
66+
return nil
67+
}
68+
return context[traitList].traits
69+
}
70+
71+
package subscript<K>(key: K.Type) -> K.Value where K: _ViewTraitKey {
72+
traits.map { $0[key] } ?? K.defaultValue
73+
}
74+
75+
package func spacing() -> Spacing {
76+
layoutComputer.spacing()
77+
}
78+
79+
package func idealSize() -> CGSize {
80+
size(in: .unspecified)
81+
}
82+
83+
package func size(in proposedSize: _ProposedSize) -> CGSize {
84+
layoutComputer.sizeThatFits(proposedSize)
85+
}
86+
87+
package func lengthThatFits(_ proposal: _ProposedSize, in direction: Axis) -> CGFloat {
88+
layoutComputer.lengthThatFits(proposal, in: direction)
89+
}
90+
91+
package func dimensions(in proposedSize: _ProposedSize) -> ViewDimensions {
92+
let computer = layoutComputer
93+
return ViewDimensions(
94+
guideComputer: computer,
95+
size: computer.sizeThatFits(proposedSize),
96+
proposal: _ProposedSize(
97+
width: proposedSize.width ?? .nan,
98+
height: proposedSize.height ?? .nan
99+
)
100+
)
101+
}
102+
103+
package func finallyPlaced(at p: _Placement, in parentSize: CGSize, layoutDirection: LayoutDirection) -> ViewGeometry {
104+
let dimensions = dimensions(in: p.proposedSize_)
105+
var geometry = ViewGeometry(
106+
placement: p,
107+
dimensions: dimensions
108+
)
109+
geometry.finalizeLayoutDirection(layoutDirection, parentSize: parentSize)
110+
return geometry
111+
}
112+
113+
package func explicitAlignment(_ k: AlignmentKey, at mySize: ViewSize) -> CGFloat? {
114+
layoutComputer.explicitAlignment(k, at: mySize)
115+
}
116+
117+
package var layoutPriority: Double {
118+
layoutComputer.layoutPriority()
119+
}
120+
121+
package var ignoresAutomaticPadding: Bool {
122+
layoutComputer.ignoresAutomaticPadding()
123+
}
124+
125+
package var requiresSpacingProjection: Bool {
126+
layoutComputer.requiresSpacingProjection()
127+
}
128+
}
129+
130+
package struct LayoutProxyCollection: RandomAccessCollection {
131+
var context: AnyRuleContext
132+
133+
var attributes: [LayoutProxyAttributes]
134+
135+
package init(context: AnyRuleContext, attributes: [LayoutProxyAttributes]) {
136+
self.context = context
137+
self.attributes = attributes
138+
}
139+
140+
package var startIndex: Int { .zero }
141+
142+
package var endIndex: Int { attributes.endIndex }
143+
144+
package subscript(index: Int) -> LayoutProxy {
145+
LayoutProxy(context: context, attributes: attributes[index])
146+
}
147+
}

0 commit comments

Comments
 (0)