Skip to content

Commit 889108d

Browse files
committed
Add LayoutSubview and LayoutSubviews
1 parent eb5f4a8 commit 889108d

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+
public import Foundation
2+
#if canImport(Darwin)
3+
public import CoreGraphics
4+
#endif
5+
package import OpenGraphShims
6+
7+
// MARK: - LayoutValueKey
8+
9+
public protocol LayoutValueKey {
10+
associatedtype Value
11+
static var defaultValue: Value { get }
12+
}
13+
14+
// MARK: - LayoutSubview
15+
16+
public struct LayoutSubview: Equatable {
17+
let proxy: LayoutProxy
18+
let index: Int32
19+
let containerLayoutDirection: LayoutDirection
20+
21+
public var priority: Double {
22+
proxy.layoutPriority
23+
}
24+
25+
public func dimensions(in size: ProposedViewSize) -> ViewDimensions {
26+
proxy.dimensions(in: _ProposedSize(width: size.width, height: size.height))
27+
}
28+
29+
package func place(in geometry: ViewGeometry, layoutDirection: LayoutDirection = .leftToRight) {
30+
fatalError("TODO")
31+
}
32+
33+
public var spacing: ViewSpacing {
34+
ViewSpacing(proxy.spacing(), layoutDirection: containerLayoutDirection)
35+
}
36+
37+
public func place(at point: CGPoint, anchor: UnitPoint = .topLeading, proposal: ProposedViewSize) {
38+
place(at: point, anchor: anchor, dimensions: proxy.dimensions(in: .init(proposal)))
39+
}
40+
41+
package func _trait<K: _ViewTraitKey>(key: K.Type) -> K.Value {
42+
proxy[key]
43+
}
44+
45+
public subscript<K: LayoutValueKey>(key: K.Type) -> K.Value where K: _ViewTraitKey {
46+
proxy[key]
47+
}
48+
49+
public func sizeThatFits(_ size: ProposedViewSize) -> CGSize {
50+
proxy.size(in: .init(width: size.width, height: size.height))
51+
}
52+
53+
package func lengthThatFits(_ size: ProposedViewSize, in axis: Axis) -> CGFloat {
54+
proxy.lengthThatFits(.init(width: size.width, height: size.height), in: axis)
55+
}
56+
57+
package func place(at point: CGPoint, anchor: UnitPoint = .topLeading, dimensions: ViewDimensions) {
58+
let origin: CGPoint = .init(point - anchor.in(dimensions.size.value))
59+
guard !origin.isNaN else {
60+
fatalError("view origin is invalid: \(origin)")
61+
}
62+
place(
63+
in: ViewGeometry(origin: origin, dimensions: dimensions),
64+
layoutDirection: containerLayoutDirection
65+
)
66+
}
67+
}
68+
69+
// MARK: - LayoutSubviews
70+
71+
public struct LayoutSubviews: RandomAccessCollection, Equatable {
72+
package var context: AnyRuleContext
73+
private var storage: Storage
74+
public var layoutDirection: LayoutDirection
75+
76+
private enum Storage: Equatable {
77+
case direct([LayoutProxyAttributes])
78+
case indirect([IndexedAttributes])
79+
80+
struct IndexedAttributes: Equatable {
81+
var attributes: LayoutProxyAttributes
82+
var index: Int32
83+
}
84+
}
85+
86+
public typealias Element = LayoutSubview
87+
public typealias Index = Int
88+
public typealias SubSequence = LayoutSubviews
89+
90+
public var startIndex: Int { 0 }
91+
92+
public var endIndex: Index {
93+
switch storage {
94+
case .direct(let attributes):
95+
return attributes.endIndex
96+
case .indirect(let attributes):
97+
return attributes.endIndex
98+
}
99+
}
100+
101+
public subscript(index: Index) -> Element {
102+
switch storage {
103+
case .direct(let attributes):
104+
LayoutSubview(
105+
proxy: LayoutProxy(context: context, attributes: attributes[index]),
106+
index: Int32(index),
107+
containerLayoutDirection: layoutDirection
108+
)
109+
case .indirect(let attributes):
110+
LayoutSubview(
111+
proxy: LayoutProxy(context: context, attributes: attributes[index].attributes),
112+
index: attributes[index].index,
113+
containerLayoutDirection: layoutDirection
114+
)
115+
}
116+
}
117+
118+
public subscript(range: Range<Int>) -> LayoutSubviews {
119+
LayoutSubviews(
120+
context: context,
121+
storage: .indirect(range.map { index in
122+
Storage.IndexedAttributes(
123+
attributes: self[index].proxy.attributes,
124+
index: Int32(index)
125+
)
126+
}),
127+
layoutDirection: layoutDirection
128+
)
129+
}
130+
131+
package subscript<Indeces>(indices: Indeces) -> LayoutSubviews where Indeces: Sequence, Indeces.Element == Int {
132+
selecting(indices: indices)
133+
}
134+
135+
package func selecting<Indices>(indices: Indices) -> LayoutSubviews where Indices: Sequence, Indices.Element == Int {
136+
return LayoutSubviews(
137+
context: context,
138+
storage: .indirect(indices.map { index in
139+
Storage.IndexedAttributes(
140+
attributes: self[index].proxy.attributes,
141+
index: Int32(index)
142+
)
143+
}),
144+
layoutDirection: layoutDirection
145+
)
146+
}
147+
}

0 commit comments

Comments
 (0)