Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial FocusState support #34

Merged
merged 3 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions Sources/OpenSwiftUI/EventHandling/Focus/FocusState.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
//
// FocusState.swift
// OpenSwiftUI
//
// Created by Kyle on 2024/2/1.
// Lastest Version: iOS 15.5
// Status: WIP
// ID: 274D264A38B51DC68ACC48A91353B7D0

@frozen
@propertyWrapper
public struct FocusState<Value>: DynamicProperty where Value: Hashable {
@frozen
@propertyWrapper
public struct Binding {
@OpenSwiftUI.Binding
private var binding: Value

init(binding: OpenSwiftUI.Binding<Value>) {
_binding = binding
}

public var wrappedValue: Value {
get { binding }
nonmutating set { binding = newValue }
}

public var projectedValue: FocusState<Value>.Binding {
self
}

var propertyID: ObjectIdentifier {
if let location = _binding.location as? FocusStoreLocation<Value> {
location.id
} else {
#if canImport(ObjectiveC)
ObjectIdentifier(PrivateType.self)
#else
ObjectIdentifier(unsafeBitCast(0, to: AnyObject.self))
#endif
}
}

private enum PrivateType {}
}

var value: Value
var location: AnyLocation<Value>?
var resetValue: Value
public var wrappedValue: Value {
get {
getValue(forReading: true)
}
nonmutating set {
guard let location else {
return
}
location.set(newValue, transaction: Transaction())
}
}

public var projectedValue: FocusState<Value>.Binding {
let value = getValue(forReading: false)
let binding: OpenSwiftUI.Binding<Value>
if let location {
binding = OpenSwiftUI.Binding(value: value, location: location)
} else {
Log.runtimeIssues("Accessing FocusState's value outside of the body of a View. This will result in a constant Binding of the initial value and will not update.")
binding = .constant(value)
}
return Binding(binding: binding)
}

public static func _makeProperty<V>(in buffer: inout _DynamicPropertyBuffer, container: _GraphValue<V>, fieldOffset: Int, inputs: inout _GraphInputs) {
// TODO
}

public init() where Value == Bool {
value = false
location = nil
resetValue = false
}

public init<T>() where Value == T?, T: Hashable {
value = nil
location = nil
resetValue = nil
}

private func getValue(forReading: Bool) -> Value {
guard let location else {
return value
}
if GraphHost.isUpdating {
if forReading {
location.wasRead = true
}
return value
} else {
return location.get()
}
}
}
23 changes: 23 additions & 0 deletions Sources/OpenSwiftUI/EventHandling/Focus/FocusStore.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// FIXME
protocol ResponderNode {}

struct FocusStore {
var seed: VersionSeed
var focusedResponders: ContiguousArray<ResponderNode>
var plists: [ObjectIdentifier : PropertyList]
}

// MARK: - FocusStore.Key

extension FocusStore {
struct Key<V: Hashable>: PropertyKey {
static var defaultValue: Entry<V>? { nil }
}
}

// MARK: - FocusStore.Item
extension FocusStore {
struct Entry<Value: Hashable> {

}
}
33 changes: 33 additions & 0 deletions Sources/OpenSwiftUI/EventHandling/Focus/FocusStoreLocation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
class FocusStoreLocation<A: Hashable>: AnyLocation<A> {
override var wasRead: Bool {
get {
_wasRead
}
set {
_wasRead = newValue
}
}

override func get() -> A {
fatalError("TODO")
}

override func set(_ value: A, transaction: Transaction) {
fatalError("TODO")
}

typealias Value = A

override init() { fatalError() }

var store: FocusStore
weak var host: GraphHost?
var resetValue: A
var focusSeed: VersionSeed
var failedAssignment: (A, VersionSeed)?
var resolvedEntry: FocusStore.Entry<A>?
var resolvedSeed: VersionSeed
var _wasRead: Bool

var id: ObjectIdentifier { ObjectIdentifier(self) }
}
11 changes: 11 additions & 0 deletions Sources/OpenSwiftUI/EventHandling/Focus/FocusedValueKey.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//
// FocusedValueKey.swift
// OpenSwiftUI
//
// Created by Kyle on 2024/2/1.
// Lastest Version: iOS 15.5
// Status: Complete

public protocol FocusedValueKey {
associatedtype Value
}
Loading