-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
455 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// | ||
// ExternalStateBinding.swift | ||
// | ||
// | ||
// Created by Tatsuya Tanaka on 2023/02/13. | ||
// | ||
|
||
import SwiftUI | ||
|
||
public struct ExternalState<Value: Hashable> { | ||
let id: UUID | ||
let get: () -> Value | ||
let set: (Value) -> Void | ||
} | ||
|
||
extension ExternalState { | ||
init(id: UUID, binding: @autoclosure @escaping () -> Binding<Value>) { | ||
self.id = id | ||
self.get = { binding().wrappedValue } | ||
self.set = { binding().wrappedValue = $0 } | ||
} | ||
} | ||
|
||
private final class Reloader: ObservableObject {} | ||
private var reloaders: [UUID: Reloader] = [:] | ||
|
||
/// Bind the state outside of SwiftUI and rebuild the UI as needed | ||
@propertyWrapper @dynamicMemberLookup public struct ExternalStateBinding<Value: Hashable>: DynamicProperty { | ||
public init(id: UUID, get: @escaping () -> Value, set: @escaping (Value) -> Void) { | ||
self.id = id | ||
self.get = get | ||
self.set = set | ||
|
||
if let reloader = reloaders[id] { | ||
self.reloader = reloader | ||
} else { | ||
reloader = Reloader() | ||
reloaders[id] = reloader | ||
} | ||
} | ||
|
||
public init(_ state: ExternalState<Value>) { | ||
self.init(id: state.id, get: state.get, set: state.set) | ||
} | ||
|
||
private let id: UUID | ||
private let get: () -> Value | ||
private let set: (Value) -> Void | ||
|
||
@ObservedObject private var reloader: Reloader | ||
@State private var lastValue: Value? | ||
|
||
public var wrappedValue: Value { | ||
get { get() } | ||
nonmutating set { | ||
set(newValue) | ||
if lastValue != newValue { | ||
reloader.objectWillChange.send() | ||
} | ||
} | ||
} | ||
|
||
public var projectedValue: Binding<Value> { | ||
.init(get: get, set: { wrappedValue = $0 }) | ||
} | ||
|
||
public subscript<Subject>(dynamicMember keyPath: ReferenceWritableKeyPath<Value, Subject>) -> ExternalStateBinding<Subject> { | ||
get { | ||
.init(id: id, get: { wrappedValue[keyPath: keyPath] }, set: { wrappedValue[keyPath: keyPath] = $0 }) | ||
} | ||
set { | ||
wrappedValue[keyPath: keyPath] = newValue.wrappedValue | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// | ||
// FilterParameterPreset.swift | ||
// | ||
// | ||
// Created by Tatsuya Tanaka on 2022/03/22. | ||
// | ||
|
||
import Foundation | ||
import VCamLocalization | ||
|
||
public struct FilterParameterPreset: CaseIterable, Hashable, Identifiable, CustomStringConvertible { | ||
public static var allCases: [FilterParameterPreset] { | ||
let params = UniBridge.shared.allDisplayParameterPresets.components(separatedBy: ",") | ||
return params.compactMap { | ||
let values = $0.components(separatedBy: "@") | ||
guard values.count == 2 else { return nil } | ||
return FilterParameterPreset(id: values[0], description: values[1]) | ||
} | ||
} | ||
|
||
public static let newPreset = Self.init(id: "", description: L10n.newPreset.text) | ||
|
||
public let id: String | ||
public var description: String | ||
} | ||
|
||
extension FilterParameterPreset { | ||
public init(string: String) { | ||
let values = string.components(separatedBy: "@") | ||
if values.count == 2 { | ||
self = FilterParameterPreset(id: values[0], description: values[1]) | ||
} else { | ||
self = .newPreset | ||
} | ||
} | ||
} | ||
|
||
private let currentFilterParameterPresetId = UUID() | ||
|
||
public extension ExternalState { | ||
static var currentFilterParameterPreset: ExternalState<FilterParameterPreset> { | ||
.init(id: currentFilterParameterPresetId) { | ||
FilterParameterPreset(string: UniBridge.shared.currentDisplayParameter.wrappedValue) | ||
} set: { | ||
UniBridge.shared.currentDisplayParameter.wrappedValue = "\($0.id)@\($0.description)" | ||
UniBridge.shared.applyDisplayParameter() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
app/xcode/Sources/VCamBridge/UniBridge+ExternalStateBinding.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// | ||
// UniBridge+ExternalStateBinding.swift | ||
// | ||
// | ||
// Created by Tatsuya Tanaka on 2023/4/14. | ||
// | ||
|
||
import Foundation | ||
|
||
private let baseUUID = UUID() | ||
|
||
public extension ExternalStateBinding { | ||
init(_ type: UniBridge.BoolType) where Value == Bool { | ||
var uuid = baseUUID.uuid | ||
uuid.0 = UInt8(type.rawValue) | ||
let mapper = UniBridge.shared.boolMapper | ||
self.init(id: UUID(uuid: uuid), get: { mapper.get(type) }, set: mapper.set(type)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ | |
|
||
import AppKit | ||
import VCamEntity | ||
import VCamBridge | ||
import VCamLocalization | ||
import struct SwiftUI.Image | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ | |
|
||
import AppKit | ||
import VCamEntity | ||
import VCamBridge | ||
import VCamLocalization | ||
import struct SwiftUI.Image | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// | ||
// VCamMainView.swift | ||
// | ||
// | ||
// Created by Tatsuya Tanaka on 2022/02/20. | ||
// | ||
|
||
import SwiftUI | ||
import VCamEntity | ||
import VCamCamera | ||
import VCamTracking | ||
|
||
public struct VCamMainView: View { | ||
public init() {} | ||
|
||
@UniState(.message, name: "message") private var message | ||
|
||
@State private var isCameraExtensionDisallow = false | ||
|
||
public var body: some View { | ||
VStack(alignment: .leading) { | ||
if isCameraExtensionDisallow { | ||
Button { | ||
MacWindowManager.shared.openSettingsVirtualCamera() | ||
} label: { | ||
Image(systemName: "exclamationmark.triangle") | ||
Text(L10n.cameraExtensionAwaitingUserApproval.key, bundle: .localize) | ||
} | ||
.font(.footnote) | ||
.frame(maxWidth: .infinity, alignment: .trailing) | ||
} | ||
|
||
HStack { | ||
SelectAllTextField(placeholder: L10n.message.text, text: $message) | ||
FlatButton { | ||
Tracking.shared.resetCalibration() | ||
} label: { | ||
Text(L10n.calibrate.key, bundle: .localize) | ||
.font(.callout) | ||
} | ||
.flatButtonStyle(.label) | ||
.help(L10n.helpCalibrate.text) | ||
} | ||
|
||
VCamShortcutGridView() | ||
} | ||
.task { | ||
if let property = try? await CameraExtension().extensionProperties() { | ||
isCameraExtensionDisallow = property.isAwaitingUserApproval | ||
} | ||
} | ||
} | ||
} | ||
|
||
#Preview { | ||
VCamMainView() | ||
.padding(4) | ||
} | ||
|
||
#Preview { | ||
VCamShortcutGridView(shortcutManager: VCamShortcutManager(shortcuts: [ | ||
.create(), | ||
.create(), | ||
])) | ||
.padding(4) | ||
} |
Oops, something went wrong.