Skip to content

Commit 86726be

Browse files
authored
Merge pull request #6 from Cosmo/development
Development
2 parents 70972cf + f7e5d69 commit 86726be

File tree

3 files changed

+194
-50
lines changed

3 files changed

+194
-50
lines changed

Sources/OpenSwiftUI/Binding.swift

+8-6
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,28 @@ import Foundation
44
public var transaction: Transaction
55
internal var location: AnyLocation<Value>
66
fileprivate var _value: Value
7+
78
public init(get: @escaping () -> Value, set: @escaping (Value) -> Void) {
89
fatalError()
910
}
11+
1012
public init(get: @escaping () -> Value, set: @escaping (Value, Transaction) -> Void) {
1113
fatalError()
1214
}
15+
1316
public static func constant(_ value: Value) -> Binding<Value> {
1417
fatalError()
1518
}
19+
1620
public var wrappedValue: Value {
17-
get {
18-
fatalError()
19-
}
20-
nonmutating set {
21-
fatalError()
22-
}
21+
get { return location._value.pointee }
22+
nonmutating set { location._value.pointee = newValue }
2323
}
24+
2425
public var projectedValue: Binding<Value> {
2526
fatalError()
2627
}
28+
2729
public subscript<Subject>(dynamicMember keyPath: WritableKeyPath<Value, Subject>) -> Binding<Subject> {
2830
fatalError()
2931
}

Sources/OpenSwiftUI/State.swift

+17-12
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,46 @@ internal class AnyLocationBase {
44
}
55

66
internal class AnyLocation<Value>: AnyLocationBase {
7+
internal let _value = UnsafeMutablePointer<Value>.allocate(capacity: 1)
8+
9+
init(value: Value) {
10+
self._value.pointee = value
11+
}
712
}
813

914
public struct _DynamicPropertyBuffer {
1015
}
1116

12-
@propertyWrapper public struct State<Value> : DynamicProperty {
13-
@usableFromInline
17+
@propertyWrapper public struct State<Value>: DynamicProperty {
1418
internal var _value: Value
1519
internal var _location: AnyLocation<Value>?
1620

1721
public init(wrappedValue value: Value) {
1822
self._value = value
23+
self._location = AnyLocation(value: value)
1924
}
2025

2126
public init(initialValue value: Value) {
22-
_value = value
27+
self._value = value
28+
self._location = AnyLocation(value: value)
2329
}
30+
2431
public var wrappedValue: Value {
25-
get {
26-
fatalError()
27-
}
28-
nonmutating set {
29-
fatalError()
30-
}
32+
get { return _location?._value.pointee ?? _value }
33+
nonmutating set { _location?._value.pointee = newValue }
3134
}
35+
3236
public var projectedValue: Binding<Value> {
33-
fatalError()
37+
return Binding(get: { return self.wrappedValue }, set: { newValue in self.wrappedValue = newValue })
3438
}
39+
3540
public static func _makeProperty<V>(in buffer: inout _DynamicPropertyBuffer, container: _GraphValue<V>, fieldOffset: Int, inputs: inout _GraphInputs) {
3641
fatalError()
3742
}
3843
}
3944

40-
extension State where Value : ExpressibleByNilLiteral {
41-
@inlinable public init() {
45+
extension State where Value: ExpressibleByNilLiteral {
46+
public init() {
4247
self.init(wrappedValue: nil)
4348
}
4449
}

Sources/OpenSwiftUI/Views/Color.swift

+169-32
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,91 @@
1+
import Foundation
2+
3+
public class AnyColorBox {
4+
}
5+
6+
extension AnyColorBox: Hashable {
7+
public func hash(into hasher: inout Hasher) {
8+
hasher.combine(ObjectIdentifier(self).hashValue)
9+
}
10+
}
11+
12+
extension AnyColorBox: Equatable {
13+
public static func == (lhs: AnyColorBox, rhs: AnyColorBox) -> Bool {
14+
return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
15+
}
16+
}
17+
18+
public class SystemColorType: AnyColorBox {
19+
public enum SystemColor: String {
20+
case clear
21+
case black
22+
case white
23+
case gray
24+
case red
25+
case green
26+
case blue
27+
case orange
28+
case yellow
29+
case pink
30+
case purple
31+
case primary
32+
case secondary
33+
case accentColor
34+
}
35+
36+
public let value: SystemColor
37+
38+
internal init(value: SystemColorType.SystemColor) {
39+
self.value = value
40+
}
41+
42+
public var description: String {
43+
return value.rawValue
44+
}
45+
}
46+
47+
public class DisplayP3: AnyColorBox {
48+
public let red: Double
49+
public let green: Double
50+
public let blue: Double
51+
public let opacity: Double
52+
53+
internal init(red: Double, green: Double, blue: Double, opacity: Double) {
54+
self.red = red
55+
self.green = green
56+
self.blue = blue
57+
self.opacity = opacity
58+
}
59+
}
60+
61+
extension Double {
62+
fileprivate var hexString: String {
63+
return String(format: "%02X", Int((self * 255).rounded()))
64+
}
65+
}
66+
67+
public class _Resolved: AnyColorBox {
68+
public let linearRed: Double
69+
public let linearGreen: Double
70+
public let linearBlue: Double
71+
public let opacity: Double
72+
73+
internal init(linearRed: Double, linearGreen: Double, linearBlue: Double, opacity: Double) {
74+
self.linearRed = linearRed
75+
self.linearGreen = linearGreen
76+
self.linearBlue = linearBlue
77+
self.opacity = opacity
78+
}
79+
80+
public var description: String {
81+
return "#\(linearRed.hexString)\(linearGreen.hexString)\(linearBlue.hexString)\(opacity.hexString)"
82+
}
83+
}
84+
185
public struct Color: View, Hashable, CustomStringConvertible {
286
public typealias Body = Never
387

4-
// These values should be private,
5-
// but then they are not accessible
6-
// in implementations of OpenSwiftUI
7-
public let _red: Double
8-
public let _green: Double
9-
public let _blue: Double
10-
public let _opacity: Double
88+
public let provider: AnyColorBox
1189

1290
public enum RGBColorSpace: Equatable {
1391
case sRGB
@@ -16,47 +94,60 @@ public struct Color: View, Hashable, CustomStringConvertible {
1694
}
1795

1896
public init(_ colorSpace: Color.RGBColorSpace = .sRGB, red: Double, green: Double, blue: Double, opacity: Double = 1) {
19-
self._red = red
20-
self._green = green
21-
self._blue = blue
22-
self._opacity = opacity
97+
switch colorSpace {
98+
case .sRGB:
99+
self.provider = _Resolved(linearRed: red, linearGreen: green, linearBlue: blue, opacity: opacity)
100+
case .sRGBLinear:
101+
self.provider = _Resolved(linearRed: red, linearGreen: green, linearBlue: blue, opacity: opacity)
102+
case .displayP3:
103+
self.provider = DisplayP3(red: red, green: green, blue: blue, opacity: opacity)
104+
}
23105
}
24106

25107
public init(_ colorSpace: Color.RGBColorSpace = .sRGB, white: Double, opacity: Double = 1) {
26-
self._red = white
27-
self._green = white
28-
self._blue = white
29-
self._opacity = opacity
108+
switch colorSpace {
109+
case .sRGB:
110+
self.provider = _Resolved(linearRed: white, linearGreen: white, linearBlue: white, opacity: opacity)
111+
case .sRGBLinear:
112+
self.provider = _Resolved(linearRed: white, linearGreen: white, linearBlue: white, opacity: opacity)
113+
case .displayP3:
114+
self.provider = DisplayP3(red: white, green: white, blue: white, opacity: opacity)
115+
}
30116
}
31117

32118
public init(hue: Double, saturation: Double, brightness: Double, opacity: Double = 1) {
33-
// TODO: Implement HSBA to RGBA conversion.
34-
fatalError("Not implemented")
119+
let rgb = Color.hsbToRGB(hue: hue, saturation: saturation, brightness: brightness)
120+
self.provider = _Resolved(linearRed: rgb.red, linearGreen: rgb.green, linearBlue: rgb.blue, opacity: opacity)
121+
}
122+
123+
internal init(_ systemColor: SystemColorType.SystemColor) {
124+
self.provider = SystemColorType(value: systemColor)
35125
}
36126

37127
public var body: Never {
38128
fatalError()
39129
}
40130

41131
public var description: String {
42-
return "Red: \(_red), Green: \(_green), Blue: \(_blue)"
132+
return "\(provider)"
43133
}
44134
}
45135

46136
extension Color {
47-
public static let clear: Color = Color(hue: 0, saturation: 0, brightness: 0, opacity: 0)
48-
public static let black: Color = Color(red: 0, green: 0, blue: 0)
49-
public static let white: Color = Color(red: 1, green: 1, blue: 1)
50-
public static let gray: Color = Color(red: 0.5, green: 0.5, blue: 0.5)
51-
public static let red: Color = Color(red: 1, green: 0, blue: 0)
52-
public static let green: Color = Color(red: 0, green: 1, blue: 0)
53-
public static let blue: Color = Color(red: 0, green: 0, blue: 1)
54-
public static let orange: Color = Color(red: 1, green: 0.5, blue: 0)
55-
public static let yellow: Color = Color(red: 1, green: 1, blue: 0)
56-
public static let pink: Color = Color(red: 1, green: 0, blue: 1)
57-
public static let purple: Color = Color(red: 0.5, green: 0, blue: 1)
58-
public static let primary: Color = Color(red: 1, green: 1, blue: 1)
59-
public static let secondary: Color = Color(red: 0.8, green: 0.8, blue: 0.8)
137+
public static let clear: Color = Color(.clear)
138+
public static let black: Color = Color(.black)
139+
public static let white: Color = Color(.white)
140+
public static let gray: Color = Color(.gray)
141+
public static let red: Color = Color(.red)
142+
public static let green: Color = Color(.green)
143+
public static let blue: Color = Color(.blue)
144+
public static let orange: Color = Color(.orange)
145+
public static let yellow: Color = Color(.yellow)
146+
public static let pink: Color = Color(.pink)
147+
public static let purple: Color = Color(.purple)
148+
public static let primary: Color = Color(.primary)
149+
public static let secondary: Color = Color(.secondary)
150+
public static let accentColor: Color = Color(.accentColor)
60151
}
61152

62153
extension View {
@@ -77,7 +168,53 @@ extension EnvironmentValues {
77168
}
78169

79170

80-
171+
extension Color {
172+
internal static func hsbToRGB(hue: Double, saturation: Double, brightness: Double) -> (red: Double, green: Double, blue: Double) {
173+
// Based on:
174+
// http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
175+
176+
var red: Double = 0
177+
var green: Double = 0
178+
var blue: Double = 0
179+
180+
let i = floor(hue * 6)
181+
let f = hue * 6 - i
182+
let p = brightness * (1 - saturation)
183+
let q = brightness * (1 - f * saturation)
184+
let t = brightness * (1 - (1 - f) * saturation)
185+
186+
switch(i.truncatingRemainder(dividingBy: 6)) {
187+
case 0:
188+
red = brightness
189+
green = t
190+
blue = p
191+
case 1:
192+
red = q
193+
green = brightness
194+
blue = p
195+
case 2:
196+
red = p
197+
green = brightness
198+
blue = t
199+
case 3:
200+
red = p
201+
green = q
202+
blue = brightness
203+
case 4:
204+
red = t
205+
green = p
206+
blue = brightness
207+
case 5:
208+
red = brightness
209+
green = p
210+
blue = q
211+
default:
212+
break
213+
}
214+
215+
return (red, green, blue)
216+
}
217+
}
81218

82219
public enum ColorScheme: CaseIterable {
83220
case light

0 commit comments

Comments
 (0)