Skip to content

Commit aa1d8a8

Browse files
authored
Merge pull request #172 from OpenSwiftUIProject/optimize/layout
Update View Layout
2 parents 141e356 + 3239212 commit aa1d8a8

File tree

69 files changed

+2302
-356
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+2302
-356
lines changed

Sources/OpenSwiftUI/View/Control/Slider/Slider.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ private struct Clamping<Value>: Projection where Value: BinaryFloatingPoint {
650650
}
651651

652652
func set(base: inout Value, newValue: Double) {
653-
base = clamp(Value(newValue), min: 0, max: 1)
653+
base = Value(newValue).clamp(min: 0, max: 1)
654654
}
655655
}
656656

Sources/OpenSwiftUICore/Animation/TODO/Animatable.swift

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
// Audited for iOS 15.5
66
// Status: Blocked by Graph
77

8-
public import Foundation
9-
108
// MARK: - Animatable
119

1210
/// A type that describes how to animate a property of a view.
@@ -49,36 +47,3 @@ extension Animatable where AnimatableData == EmptyAnimatableData {
4947
// TODO
5048
}
5149
}
52-
53-
// MARK: - Animatable + CoreGraphics
54-
55-
extension CGPoint: Animatable {
56-
public var animatableData: AnimatablePair<CGFloat, CGFloat> {
57-
@inlinable
58-
get { .init(x, y) }
59-
@inlinable
60-
set { (x, y) = newValue[] }
61-
}
62-
}
63-
64-
extension CGSize: Animatable {
65-
public var animatableData: AnimatablePair<CGFloat, CGFloat> {
66-
@inlinable
67-
get { .init(width, height) }
68-
@inlinable
69-
set { (width, height) = newValue[] }
70-
}
71-
}
72-
73-
extension CGRect: Animatable {
74-
public var animatableData: AnimatablePair<CGPoint.AnimatableData, CGSize.AnimatableData> {
75-
@inlinable
76-
get {
77-
.init(origin.animatableData, size.animatableData)
78-
}
79-
@inlinable
80-
set {
81-
(origin.animatableData, size.animatableData) = newValue[]
82-
}
83-
}
84-
}
Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
//
22
// CodableProxy.swift
3-
// OpenSwiftUI
3+
// OpenSwiftUICore
44
//
5-
// Audited for iOS 15.5
6-
// Status: Complete
5+
// Audited for iOS 18.0
6+
// Status: WIP
77

8-
protocol CodableProxy: Codable {
9-
associatedtype Base
10-
var base: Base { get }
11-
}
12-
13-
protocol CodableByProxy {
8+
package protocol CodableByProxy {
149
associatedtype CodingProxy: Codable
1510
var codingProxy: CodingProxy { get }
1611

1712
static func unwrap(codingProxy: CodingProxy) -> Self
1813
}
14+
15+
package protocol CodableProxy: Codable {
16+
associatedtype Base
17+
var base: Base { get }
18+
}
19+
20+
extension CodableByProxy where Self == CodingProxy.Base, CodingProxy: CodableProxy {
21+
package static func unwrap(codingProxy: CodingProxy) -> Self {
22+
codingProxy.base
23+
}
24+
}

Sources/OpenSwiftUICore/Data/Update.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
//
55
// Audited for iOS 18.0
66
// Status: Blocked by Signpost
7-
// ID: EA173074DA35FA471DC70643259B7E74 (RELEASE_2021)
8-
// ID: 61534957AEEC2EDC447ABDC13B4D426F (RELEASE_2024)
7+
// ID: EA173074DA35FA471DC70643259B7E74 (SwiftUI)
8+
// ID: 61534957AEEC2EDC447ABDC13B4D426F (SwiftUICore)
99

1010
import OpenSwiftUI_SPI
1111
import OpenGraphShims
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//
2+
// CGAffineTransform+Extension.swift
3+
// OpenSwiftUICore
4+
//
5+
// Audited for iOS 18.0
6+
// Status: Complete
7+
8+
#if canImport(Darwin)
9+
10+
package import CoreGraphics
11+
12+
extension CGAffineTransform {
13+
package init(rotation: Angle) {
14+
let sin = sin(rotation.radians)
15+
let cos = cos(rotation.radians)
16+
self.init(a: cos, b: sin, c: -sin, d: cos, tx: 0, ty: 0)
17+
}
18+
19+
package var isTranslation: Bool {
20+
return a == 1 && b == 0 && c == 0 && d == 1
21+
}
22+
23+
package var isRectilinear: Bool {
24+
return (b == 0 && c == 0) || (a == 0 && d == 0)
25+
}
26+
27+
package var isUniform: Bool {
28+
guard isRectilinear else {
29+
return false
30+
}
31+
return a == d && b == c
32+
}
33+
34+
package func rotated(by angle: Angle) -> CGAffineTransform {
35+
CGAffineTransform(rotation: angle).concatenating(self)
36+
}
37+
38+
package var scale: CGFloat {
39+
let m = a * a + b * b
40+
let n = c * c + d * d
41+
42+
if m == 1.0 && n == 1.0 {
43+
return 1.0
44+
} else {
45+
return (sqrt(m) + sqrt(n)) / 2
46+
}
47+
}
48+
}
49+
50+
extension CGAffineTransform: ProtobufMessage {
51+
package func encode(to encoder: inout ProtobufEncoder) throws {
52+
encoder.cgFloatField(1, a, defaultValue: 1)
53+
encoder.cgFloatField(2, b, defaultValue: 0)
54+
encoder.cgFloatField(3, c, defaultValue: 0)
55+
encoder.cgFloatField(4, d, defaultValue: 1)
56+
encoder.cgFloatField(5, tx, defaultValue: 0)
57+
encoder.cgFloatField(6, ty, defaultValue: 0)
58+
}
59+
60+
package init(from decoder: inout ProtobufDecoder) throws {
61+
var transform = CGAffineTransform.identity
62+
while let field = try decoder.nextField() {
63+
switch field.tag {
64+
case 1: transform.a = try decoder.cgFloatField(field)
65+
case 2: transform.b = try decoder.cgFloatField(field)
66+
case 3: transform.c = try decoder.cgFloatField(field)
67+
case 4: transform.d = try decoder.cgFloatField(field)
68+
case 5: transform.tx = try decoder.cgFloatField(field)
69+
case 6: transform.ty = try decoder.cgFloatField(field)
70+
default: try decoder.skipField(field)
71+
}
72+
}
73+
self = transform
74+
}
75+
}
76+
77+
#endif
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
//
2+
// CGPoint+Extension.swift
3+
// OpenSwiftUICore
4+
//
5+
// Audited for iOS 18.0
6+
// Status: Complete
7+
8+
public import Foundation
9+
10+
@_spi(ForOpenSwiftUIOnly) public typealias PlatformPoint = CGPoint
11+
12+
extension CGPoint {
13+
@inlinable
14+
package static var infinity: CGPoint {
15+
.init(x: CGFloat.infinity, y: CGFloat.infinity)
16+
}
17+
18+
@inlinable
19+
package init(_ size: CGSize) {
20+
self.init(x: size.width, y: size.height)
21+
}
22+
23+
@inlinable
24+
package var isFinite: Bool {
25+
x.isFinite && y.isFinite
26+
}
27+
28+
@inlinable
29+
package func offsetBy(dx: CGFloat, dy: CGFloat) -> CGPoint {
30+
CGPoint(x: x + dx, y: y + dy)
31+
}
32+
33+
@inlinable
34+
package func offsetBy(dx: CGFloat) -> CGPoint {
35+
offsetBy(dx: dx, dy: 0)
36+
}
37+
38+
@inlinable
39+
package func offsetBy(dy: CGFloat) -> CGPoint {
40+
offsetBy(dx: 0, dy: dy)
41+
}
42+
43+
@inlinable
44+
package func offset(by offset: CGSize) -> CGPoint {
45+
offsetBy(dx: offset.width, dy: offset.height)
46+
}
47+
48+
@inlinable
49+
package func scaledBy(x: CGFloat, y: CGFloat) -> CGPoint {
50+
CGPoint(x: self.x * x, y: self.y * y)
51+
}
52+
53+
@inlinable
54+
package func scaledBy(x: CGFloat) -> CGPoint {
55+
scaledBy(x: x, y: 1)
56+
}
57+
58+
@inlinable
59+
package func scaledBy(y: CGFloat) -> CGPoint {
60+
scaledBy(x: 1, y: y)
61+
}
62+
63+
@inlinable
64+
package func scaled(by scale: CGFloat) -> CGPoint {
65+
scaledBy(x: scale, y: scale)
66+
}
67+
68+
@inlinable
69+
package var isNaN: Bool {
70+
x.isNaN || y.isNaN
71+
}
72+
73+
@inlinable
74+
package var flushingNaNs: CGPoint {
75+
CGPoint(x: !x.isNaN ? x : 0, y: !y.isNaN ? y : 0)
76+
}
77+
78+
@inlinable
79+
package func approximates(_ other: CGPoint, epsilon: CGFloat) -> Bool {
80+
x.approximates(other.x, epsilon: epsilon)
81+
&& y.approximates(other.y, epsilon: epsilon)
82+
}
83+
84+
@inlinable
85+
package mutating func clamp(size: CGSize) {
86+
x.clamp(to: 0...size.width)
87+
y.clamp(to: 0...size.height)
88+
}
89+
90+
@inlinable
91+
package func clamped(size: CGSize) -> CGPoint {
92+
var point = self
93+
point.clamp(size: size)
94+
return point
95+
}
96+
97+
@inlinable
98+
package mutating func clamp(rect: CGRect) {
99+
x.clamp(to: rect.x...rect.size.width)
100+
y.clamp(to: rect.y...rect.size.height)
101+
}
102+
103+
@inlinable
104+
package func clamped(rect: CGRect) -> CGPoint {
105+
var point = self
106+
point.clamp(rect: rect)
107+
return point
108+
}
109+
}
110+
111+
extension CGPoint {
112+
@inlinable
113+
package subscript(d: Axis) -> CGFloat {
114+
get { d == .horizontal ? x : y }
115+
set { if d == .horizontal { x = newValue } else { y = newValue } }
116+
}
117+
118+
@inlinable
119+
package init(_ l1: CGFloat, in first: Axis, by l2: CGFloat) {
120+
self = first == .horizontal ? CGPoint(x: l1, y: l2) : CGPoint(x: l2, y: l1)
121+
}
122+
}
123+
124+
extension CGPoint: Animatable {
125+
public var animatableData: AnimatablePair<CGFloat, CGFloat> {
126+
@inlinable
127+
get { .init(x, y) }
128+
@inlinable
129+
set { (x, y) = (newValue.first, newValue.second) }
130+
}
131+
}
132+
133+
extension CGPoint: ProtobufMessage {
134+
package func encode(to encoder: inout ProtobufEncoder) {
135+
encoder.cgFloatField(1, x)
136+
encoder.cgFloatField(2, y)
137+
}
138+
139+
package init(from decoder: inout ProtobufDecoder) throws {
140+
var x: CGFloat = .zero
141+
var y: CGFloat = .zero
142+
while let field = try decoder.nextField() {
143+
switch field.tag {
144+
case 1: x = try decoder.cgFloatField(field)
145+
case 2: y = try decoder.cgFloatField(field)
146+
default: try decoder.skipField(field)
147+
}
148+
}
149+
self.init(x: x, y: y)
150+
}
151+
}

0 commit comments

Comments
 (0)