22// DynamicLayoutView.swift
33// OpenSwiftUICore
44//
5+ // Audited for 6.5.4
56// Status: WIP
67// ID: FF3C661D9D8317A1C8FE2B7FD4EDE12C (SwiftUICore)
78
89import OpenAttributeGraphShims
910
10- // MARK: - DynamicLayoutComputer
11+ // MARK: - Layout + makeDynamicView
1112
12- private struct DynamicLayoutComputer < L> : StatefulRule , AsyncAttribute , CustomStringConvertible where L: Layout {
13- @Attribute
14- var layout : L
13+ extension Layout {
14+ static func makeDynamicView(
15+ root: _GraphValue < Self > ,
16+ inputs: _ViewInputs ,
17+ properties: LayoutProperties ,
18+ list: Attribute < any ViewList >
19+ ) -> _ViewOutputs {
20+ var inputs = inputs
21+ let containsScrollable = inputs. preferences. containsScrollable
22+ let containsScrollTargetRoleContent = inputs. preferences. containsScrollTargetRoleContent
23+ let scrollTargetRole = inputs. scrollTargetRole
24+ let scrollTargetRemovePreference = inputs. scrollTargetRemovePreference
25+ let withinAccessibilityRotor = inputs. withinAccessibilityRotor
26+
27+ // FIXME
28+ var layoutComputer : Attribute < LayoutComputer > !
29+ let childGeometry : Attribute < [ ViewGeometry ] > ?
30+ let needLayout = inputs. requestsLayoutComputer || inputs. needsGeometry
31+ if needLayout || containsScrollable || withinAccessibilityRotor {
32+ layoutComputer = Attribute (
33+ DynamicLayoutComputer (
34+ layout: root. value,
35+ environment: inputs. environment,
36+ containerInfo: . init( ) ,
37+ layoutMap: . init( )
38+ )
39+ )
40+ childGeometry = Attribute (
41+ LayoutChildGeometries (
42+ parentSize: inputs. size,
43+ parentPosition: inputs. position,
44+ layoutComputer: layoutComputer
45+ )
46+ )
47+ } else {
48+ childGeometry = nil // .nil here
49+ }
50+
51+ // var context2
52+ var childInputs = inputs
53+ childInputs. requestsLayoutComputer = false
54+
55+ if containsScrollTargetRoleContent && scrollTargetRemovePreference {
56+ inputs. preferences. containsScrollTargetRoleContent = false
57+ inputs. preferences. containsScrollStateRequest = false
58+ }
59+ if let role = scrollTargetRole. attribute {
60+ childInputs. base. scrollTargetRole = . init( )
61+ childInputs. base. scrollTargetRemovePreference = true
62+ childInputs. base. setScrollPosition ( storage: nil , kind: . scrollContent)
63+ childInputs. base. setScrollPositionAnchor ( . init( ) , kind: . scrollContent)
64+ }
65+ _openSwiftUIUnimplementedFailure ( )
66+ }
67+ }
68+
69+ // MARK: - DynamicLayoutViewChildGeometry
70+
71+ private struct DynamicLayoutViewChildGeometry : StatefulRule , AsyncAttribute {
72+ @Attribute var containerInfo : DynamicContainer . Info
73+ @Attribute var childGeometries : [ ViewGeometry ]
74+ let id : DynamicContainerID
75+
76+ typealias Value = ViewGeometry
77+
78+ func updateValue( ) {
79+ guard let index = containerInfo. viewIndex ( id: id) , index < childGeometries. count else {
80+ if !hasValue {
81+ value = . zero
82+ }
83+ return
84+ }
85+ value = childGeometries [ index]
86+ }
87+ }
88+
89+ // TODO: - DynamicLayoutViewAdaptor
1590
16- @Attribute
17- var environment : EnvironmentValues
91+ // MARK: - DynamicLayoutComputer
1892
19- @OptionalAttribute
20- var containerInfo : DynamicContainer . Info ?
93+ private struct DynamicLayoutComputer < L> : StatefulRule , AsyncAttribute , CustomStringConvertible where L: Layout {
94+ @Attribute var layout : L
95+ @Attribute var environment : EnvironmentValues
96+ @OptionalAttribute var containerInfo : DynamicContainer . Info ?
2197
2298 var layoutMap : DynamicLayoutMap
2399
@@ -35,3 +111,113 @@ private struct DynamicLayoutComputer<L>: StatefulRule, AsyncAttribute, CustomStr
35111 " \( L . self) → LayoutComputer "
36112 }
37113}
114+
115+ // TODO: DynamicLayoutScrollable
116+
117+ struct DynamicLayoutScrollable { }
118+
119+ // TODO: - ViewListContentTransition
120+
121+ // FIXME
122+ struct ContentTransitionEffect { }
123+
124+ private struct ViewListContentTransition < T> : StatefulRule , AsyncAttribute where T: Transition {
125+ var helper : TransitionHelper < T >
126+ @Attribute var size : ViewSize
127+ @Attribute var environment : EnvironmentValues
128+
129+ init (
130+ helper: TransitionHelper < T > ,
131+ size: Attribute < ViewSize > ,
132+ environment: Attribute < EnvironmentValues >
133+ ) {
134+ self . helper = helper
135+ self . _size = size
136+ self . _environment = environment
137+ }
138+
139+ typealias Value = ContentTransitionEffect
140+
141+ func updateValue( ) {
142+ _openSwiftUIUnimplementedFailure ( )
143+ }
144+ }
145+
146+ // MARK: - ViewListArchivedAnimation
147+
148+ private struct ViewListArchivedAnimation : Rule , AsyncAttribute {
149+ struct Effect : _RendererEffect {
150+ var animation : Animation ?
151+ var value : StrongHash ?
152+
153+ func effectValue( size: CGSize ) -> DisplayList . Effect {
154+ guard let value else {
155+ return . identity
156+ }
157+ return . interpolatorAnimation(
158+ . init(
159+ value: value,
160+ animation: animation
161+ )
162+ )
163+ }
164+ }
165+
166+ @OptionalAttribute var traitsList : ( any ViewList ) ?
167+
168+ var value : Effect {
169+ guard let traitsList else {
170+ return . init( )
171+ }
172+ guard let trait = traitsList. traits. archivedAnimationTrait else {
173+ return . init( )
174+ }
175+ return Effect ( animation: trait. animation, value: trait. hash)
176+ }
177+ }
178+
179+ // MARK: - TransitionHelper
180+
181+ private struct TransitionHelper < T> where T: Transition {
182+ @OptionalAttribute var list : ( any ViewList ) ?
183+ @Attribute var info : DynamicContainer . Info
184+ let uniqueID : UInt32
185+ var transition : T
186+ var phase : TransitionPhase
187+
188+ mutating func update( ) -> Bool {
189+ var changed = false
190+ if let index = info. indexMap [ uniqueID] {
191+ let itemInfo = info. items [ index]
192+ if let itemPhase = itemInfo. phase {
193+ changed = phase != itemPhase
194+ phase = itemPhase
195+ }
196+ }
197+ guard phase != . didDisappear else {
198+ return changed
199+ }
200+ let traits = list? . traits ?? . init( )
201+ traits. transition. base ( as: T . self) . map {
202+ transition = $0
203+ changed = true
204+ }
205+ return changed
206+ }
207+ }
208+
209+ // MARK: - ViewListTransition
210+
211+ private struct ViewListTransition < T> : StatefulRule , AsyncAttribute where T: Transition {
212+ var helper : TransitionHelper < T >
213+
214+ typealias Value = T . Body
215+
216+ mutating func updateValue( ) {
217+ let changed = helper. update ( )
218+ guard changed || !hasValue else {
219+ return
220+ }
221+ value = helper. transition. body ( content: . init( ) , phase: helper. phase)
222+ }
223+ }
0 commit comments