Skip to content

Commit c11935b

Browse files
committed
Implement Path in WinUIBackend
1 parent 7b283e3 commit c11935b

File tree

7 files changed

+363
-12
lines changed

7 files changed

+363
-12
lines changed

Examples/Package.resolved

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Examples/Package.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,9 @@ let package = Package(
6565
name: "NotesExample",
6666
dependencies: exampleDependencies
6767
),
68+
.executableTarget(
69+
name: "PathsExample",
70+
dependencies: exampleDependencies
71+
)
6872
]
6973
)
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import SwiftCrossUI
2+
import DefaultBackend
3+
import Foundation // for sin, cos
4+
5+
struct ArcShape: StyledShape {
6+
var startAngle: Double
7+
var endAngle: Double
8+
var clockwise: Bool
9+
10+
var strokeColor: Color? = Color.green
11+
let fillColor: Color? = nil
12+
let strokeStyle: StrokeStyle? = StrokeStyle(width: 5.0)
13+
14+
func path(in bounds: Path.Rect) -> Path {
15+
let radius = min(bounds.width, bounds.height) / 2.0 - 2.5
16+
17+
return Path()
18+
.move(to: bounds.center + radius * SIMD2(x: cos(startAngle), y: sin(startAngle)))
19+
.addArc(
20+
center: bounds.center,
21+
radius: radius,
22+
startAngle: startAngle,
23+
endAngle: endAngle,
24+
clockwise: clockwise
25+
)
26+
}
27+
28+
func size(fitting proposal: SIMD2<Int>) -> ViewSize {
29+
let diameter = max(11, min(proposal.x, proposal.y))
30+
return ViewSize(
31+
size: SIMD2(x: diameter, y: diameter),
32+
idealSize: SIMD2(x: 100, y: 100),
33+
idealWidthForProposedHeight: proposal.y,
34+
idealHeightForProposedWidth: proposal.x,
35+
minimumWidth: 11,
36+
minimumHeight: 11,
37+
maximumWidth: nil,
38+
maximumHeight: nil
39+
)
40+
}
41+
}
42+
43+
struct PathsApp: App {
44+
var body: some Scene {
45+
WindowGroup("PathsApp") {
46+
HStack {
47+
ZStack {
48+
RoundedRectangle(cornerRadius: 12)
49+
.fill(.gray)
50+
51+
HStack {
52+
VStack {
53+
Text("Clockwise")
54+
55+
HStack {
56+
ArcShape(startAngle: .pi * 2.0/3.0, endAngle: .pi * 1.5, clockwise: true)
57+
58+
ArcShape(startAngle: .pi * 1.5, endAngle: .pi * 1.0/3.0, clockwise: true)
59+
}
60+
61+
HStack {
62+
ArcShape(startAngle: .pi * 1.5, endAngle: .pi * 2.0/3.0, clockwise: true)
63+
64+
ArcShape(startAngle: .pi * 1.0/3.0, endAngle: .pi * 1.5, clockwise: true)
65+
}
66+
}
67+
68+
VStack {
69+
Text("Counter-clockwise")
70+
71+
HStack {
72+
ArcShape(startAngle: .pi * 1.5, endAngle: .pi * 2.0/3.0, clockwise: false)
73+
74+
ArcShape(startAngle: .pi * 1.0/3.0, endAngle: .pi * 1.5, clockwise: false)
75+
}
76+
77+
HStack {
78+
ArcShape(startAngle: .pi * 2.0/3.0, endAngle: .pi * 1.5, clockwise: false)
79+
80+
ArcShape(startAngle: .pi * 1.5, endAngle: .pi * 1.0/3.0, clockwise: false)
81+
}
82+
}
83+
}.padding()
84+
}
85+
.padding()
86+
87+
Ellipse()
88+
.fill(.blue)
89+
.padding()
90+
}
91+
}
92+
}
93+
}
94+
95+
// Even though this file isn't called main.swift, `@main` isn't allowed and this is
96+
PathsApp.main()

Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ let package = Package(
107107
),
108108
.package(
109109
url: "https://github.com/stackotter/swift-winui",
110-
branch: "42fe0034b7162f2de71ceea95725915d1147455a"
110+
branch: "a81bc36e3ac056fbc740e9df30ff0d80af5ecd21"
111111
),
112112
// .package(
113113
// url: "https://github.com/stackotter/TermKit",

Sources/SwiftCrossUI/Path.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,13 +266,32 @@ public struct Path {
266266
return self
267267
}
268268

269+
/// Add an arc segment to the path.
270+
///
271+
/// The behavior is not defined if the starting point is not what is implied by `center`,
272+
/// `radius`, and `startAngle`. Some backends (such as UIKit) will add a line segment
273+
/// to connect the arc to the starting point, while others (such as WinUI) will move the
274+
/// arc in unintuitive ways. If this arc is the first segment of the current path, or
275+
/// the previous segment was a rectangle or circle, be sure to call ``move(to:)`` before
276+
/// this.
277+
/// - Parameters:
278+
/// - center: The location of the center of the circle.
279+
/// - radius: The radius of the circle.
280+
/// - startAngle: The angle of the start of the arc, measured in radians clockwise from
281+
// right. Must be between 0 and 2pi (inclusive).
282+
/// - endAngle: The angle of the end of the arc, measured in radians clockwise from right.
283+
/// Must be between 0 and 2pi (inclusive).
284+
/// - clockwise: `true` if the arc is to be drawn clockwise, `false` if the arc is to
285+
/// be drawn counter-clockwise. Used to determine whether to draw the larger arc or
286+
/// the smaller arc identified by the given start and end angles.
269287
public consuming func addArc(
270288
center: SIMD2<Double>,
271289
radius: Double,
272290
startAngle: Double,
273291
endAngle: Double,
274292
clockwise: Bool
275293
) -> Path {
294+
assert((0.0 ... (2.0 * .pi)).contains(startAngle) && (0.0 ... (2.0 * .pi)).contains(endAngle))
276295
actions.append(
277296
.arc(
278297
center: center,

0 commit comments

Comments
 (0)