Skip to content

Commit f276b1e

Browse files
committed
Update example
1 parent 15c1695 commit f276b1e

File tree

2 files changed

+78
-66
lines changed

2 files changed

+78
-66
lines changed

Example/ShaftExample/Sources/ShaftExample/main.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ struct ContentView: View {
1414
var body: some View {
1515
VStack {
1616
Color.red
17-
.frame(width: 50, height: 30)
17+
.frame(width: 100, height: 60)
1818
Spacer()
1919
Color.blue
20-
.frame(width: 50, height: 30)
20+
.frame(width: 100, height: 60)
21+
.rotationEffect(.degrees(45))
2122
Spacer()
2223
Color.green
23-
.frame(width: 50, height: 30)
24+
.frame(width: 100, height: 60)
2425
}
2526
}
2627
}

Sources/OpenSwiftUIShaftBackend/DisplayListConverter.swift

Lines changed: 74 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -8,85 +8,94 @@
88
import Foundation
99
import OpenSwiftUICore
1010
import Shaft
11+
import SwiftMath
1112

1213
/// Converts OpenSwiftUI DisplayList structures into Shaft widgets
1314
final class DisplayListConverter {
1415
private var contentsScale: Float = 1.0
15-
16+
1617
init() {}
17-
18+
1819
/// Convert a DisplayList to a Shaft widget tree
1920
func convertDisplayList(
2021
_ displayList: OpenSwiftUICore.DisplayList,
2122
contentsScale: CGFloat
2223
) -> Widget {
2324
self.contentsScale = Float(contentsScale)
24-
25+
2526
// Handle empty display list
2627
guard !displayList.items.isEmpty else {
2728
return SizedBox(width: 0, height: 0)
2829
}
29-
30+
3031
// Convert all items
3132
let widgets = displayList.items.compactMap { convertItem($0) }
32-
33+
3334
// If single item, return it directly
34-
if widgets.count == 1 {
35-
return widgets[0]
36-
}
37-
35+
// if widgets.count == 1 {
36+
// return widgets[0]
37+
// }
38+
3839
// Multiple items - stack them
3940
return Stack { widgets }
4041
}
41-
42+
4243
/// Convert a single DisplayList.Item to a Shaft widget
4344
private func convertItem(_ item: OpenSwiftUICore.DisplayList.Item) -> Widget {
4445
// Each item has a frame and a value
4546
let frame = item.frame
46-
47-
switch item.value {
48-
case .empty:
49-
return SizedBox()
50-
51-
case .content(let content):
52-
// Actual renderable content
53-
mark("frame: \(frame)")
54-
return Positioned(left: Float(frame.minX), top: Float(frame.minY), width: Float(frame.width), height: Float(frame.height)) {
47+
48+
let result =
49+
switch item.value {
50+
case .empty:
51+
SizedBox()
52+
53+
case .content(let content):
54+
// Actual renderable content
5555
convertContent(content)
56+
57+
case .effect(let effect, let childList):
58+
// Effect applied to child display list
59+
// let childWidget =
60+
applyEffect(effect, to: convertDisplayList(
61+
childList, contentsScale: CGFloat(contentsScale)
62+
))
63+
64+
case .states(let states):
65+
// State-dependent display lists
66+
// For now, just render the first state if available
67+
if let firstState = states.first {
68+
convertDisplayList(firstState.1, contentsScale: CGFloat(contentsScale))
69+
} else {
70+
Text("states not implemented")
71+
}
5672
}
57-
58-
case .effect(let effect, let childList):
59-
// Effect applied to child display list
60-
let childWidget = convertDisplayList(childList, contentsScale: CGFloat(contentsScale))
61-
return applyEffect(effect, to: childWidget)
62-
63-
case .states(let states):
64-
// State-dependent display lists
65-
// For now, just render the first state if available
66-
if let firstState = states.first {
67-
return convertDisplayList(firstState.1, contentsScale: CGFloat(contentsScale))
68-
}
69-
return Text("states not implemented")
73+
74+
return Positioned(
75+
left: Float(frame.minX), top: Float(frame.minY),
76+
width: Float(frame.width), height: Float(frame.height)
77+
) {
78+
result
7079
}
7180
}
72-
81+
7382
/// Convert Content to Shaft widget
7483
private func convertContent(
7584
_ content: OpenSwiftUICore.DisplayList.Content,
7685
) -> Widget {
7786
switch content.value {
7887
case .color(let resolvedColor):
7988
return convertColor(resolvedColor)
80-
89+
8190
case .text(let textView, let size):
8291
return convertText(textView, size: size)
83-
92+
8493
case .shape(let path, let paint, let fillStyle):
8594
return convertShape(path: path, paint: paint, fillStyle: fillStyle)
86-
95+
8796
case .image(let graphicsImage):
8897
return convertImage(graphicsImage)
89-
98+
9099
case .flattened(let displayList, let offset, _):
91100
// Nested display list
92101
let childWidget = convertDisplayList(displayList, contentsScale: CGFloat(contentsScale))
@@ -99,12 +108,12 @@ final class DisplayListConverter {
99108
}
100109
}
101110
return childWidget
102-
111+
103112
default:
104113
return Text("\(content.value) not implemented")
105114
}
106115
}
107-
116+
108117
/// Apply an effect to a widget
109118
private func applyEffect(
110119
_ effect: OpenSwiftUICore.DisplayList.Effect,
@@ -113,62 +122,64 @@ final class DisplayListConverter {
113122
switch effect {
114123
case .identity:
115124
return widget
116-
125+
117126
case .opacity(let alpha):
118127
// TODO: Shaft doesn't have Opacity widget - need to implement custom
119128
// For now, just return the widget without opacity
120129
return widget
121-
130+
122131
case .transform(let transform):
123132
return applyTransform(transform, to: widget)
124-
133+
125134
case .clip(let path, _, _):
126135
// TODO: Implement clipping with path
127136
return widget
128-
137+
129138
case .mask(let maskList, _):
130139
// TODO: Implement masking
131140
return widget
132-
141+
133142
case .geometryGroup, .compositingGroup, .backdropGroup:
134143
// Grouping effects - just return widget for now
135144
return widget
136-
145+
137146
case .properties, .blendMode, .filter:
138147
// Advanced effects - not supported initially
139148
return widget
140-
149+
141150
case .archive, .platformGroup, .animation, .contentTransition, .view, .accessibility,
142-
.platform, .state, .interpolatorRoot, .interpolatorLayer, .interpolatorAnimation:
151+
.platform, .state, .interpolatorRoot, .interpolatorLayer, .interpolatorAnimation:
143152
// Complex features - not supported initially
144153
return widget
145154
}
146155
}
147-
156+
148157
/// Apply transform to widget
149158
private func applyTransform(
150159
_ transform: OpenSwiftUICore.DisplayList.Transform,
151160
to widget: Widget
152161
) -> Widget {
162+
mark("transform: \(transform)")
153163
switch transform {
154164
case .affine(let affineTransform):
155-
// Extract translation for now
156-
let tx = Float(affineTransform.tx)
157-
let ty = Float(affineTransform.ty)
158-
if tx != 0 || ty != 0 {
159-
return Positioned(left: tx, top: ty) { widget }
160-
}
161-
// TODO: Handle rotation and scale
165+
// TODO: affine transform
162166
return widget
163-
164-
case .rotation, .rotation3D, .projection:
167+
168+
case .rotation(let data):
169+
return Transform(
170+
transform: Matrix4x4f.rotate(z: .init(radians: Float(data.angle.radians)))
171+
) {
172+
widget
173+
}
174+
175+
case .rotation3D, .projection:
165176
// TODO: Implement 3D transforms
166177
return widget
167178
}
168179
}
169-
180+
170181
// MARK: - Content Converters
171-
182+
172183
private func convertColor(
173184
_ resolvedColor: OpenSwiftUICore.Color.Resolved,
174185
) -> Widget {
@@ -178,10 +189,10 @@ final class DisplayListConverter {
178189
let g = UInt8(resolvedColor.linearGreen * 255)
179190
let b = UInt8(resolvedColor.linearBlue * 255)
180191
let shaftColor = Shaft.Color.argb(a, r, g, b)
181-
192+
182193
return DecoratedBox(decoration: .box(color: shaftColor))
183194
}
184-
195+
185196
private func convertText(
186197
_ textView: StyledTextContentView,
187198
size: CGSize,
@@ -191,7 +202,7 @@ final class DisplayListConverter {
191202
// For now, return a placeholder
192203
return Text("TODO: Extract text")
193204
}
194-
205+
195206
private func convertShape(
196207
path: OpenSwiftUICore.Path,
197208
paint: AnyResolvedPaint,
@@ -201,7 +212,7 @@ final class DisplayListConverter {
201212
// TODO: Handle paint and fill styles
202213
return Text("TODO: Extract shape")
203214
}
204-
215+
205216
private func convertImage(
206217
_ graphicsImage: GraphicsImage,
207218
) -> Widget {

0 commit comments

Comments
 (0)