Skip to content

Commit

Permalink
Open source
Browse files Browse the repository at this point in the history
  • Loading branch information
tattn committed Oct 16, 2023
1 parent e6ac7a8 commit b66f62a
Show file tree
Hide file tree
Showing 9 changed files with 334 additions and 27 deletions.
2 changes: 1 addition & 1 deletion app/xcode/Sources/VCamBridge/FilterParameterPreset.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ extension FilterParameterPreset {
private let currentFilterParameterPresetId = UUID()

public extension ExternalState {
static var currentFilterParameterPreset: ExternalState<FilterParameterPreset> {
static var currentDisplayParameterPreset: ExternalState<FilterParameterPreset> {
.init(id: currentFilterParameterPresetId) {
FilterParameterPreset(string: UniBridge.shared.currentDisplayParameter.wrappedValue)
} set: {
Expand Down
34 changes: 34 additions & 0 deletions app/xcode/Sources/VCamBridge/LensFlare.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// LensFlare.swift
//
//
// Created by Tatsuya Tanaka on 2022/03/22.
//

import Foundation
import VCamLocalization

public enum LensFlare: Int32, CaseIterable, Identifiable, CustomStringConvertible {
case none, type1, type2, type3, type4

public var id: Self { self }

public static func initOrNone(_ value: Int32) -> Self {
.init(rawValue: value) ?? .none
}

public var description: String {
switch self {
case .none:
return L10n.none.text
case .type1:
return L10n.typeNo("1").text
case .type2:
return L10n.typeNo("2").text
case .type3:
return L10n.typeNo("3").text
case .type4:
return L10n.typeNo("4").text
}
}
}
37 changes: 33 additions & 4 deletions app/xcode/Sources/VCamBridge/UniBridge+ExternalStateBinding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,42 @@

import Foundation

private let baseUUID = UUID()
private let baseUUID = UUID().uuid

private func uuid(_ keyPath: WritableKeyPath<uuid_t, UInt8>, typeValue: Int32) -> UUID {
var uuid = baseUUID
uuid[keyPath: keyPath] = UInt8(typeValue)
return UUID(uuid: 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))
self.init(id: uuid(\.0, typeValue: type.rawValue), get: { mapper.get(type) }, set: mapper.set(type))
}

init(_ type: UniBridge.FloatType) where Value == CGFloat {
let mapper = UniBridge.shared.floatMapper
self.init(id: uuid(\.1, typeValue: type.rawValue), get: { mapper.get(type) }, set: mapper.set(type))
}

init(_ type: UniBridge.IntType) where Value == Int32 {
let mapper = UniBridge.shared.intMapper
self.init(id: uuid(\.2, typeValue: type.rawValue), get: { mapper.get(type) }, set: mapper.set(type))
}

init(_ type: UniBridge.StringType) where Value == String {
let mapper = UniBridge.shared.stringMapper
self.init(id: uuid(\.3, typeValue: type.rawValue), get: { mapper.get(type) }, set: mapper.set(type))
}

init<Element>(_ type: UniBridge.ArrayType, as: Array<Element>.Type) where Value == Array<Element> {
let mapper = UniBridge.shared.arrayMapper
self.init(id: uuid(\.4, typeValue: type.rawValue), get: { mapper.binding(type, size: type.arraySize).wrappedValue }, set: mapper.set(type))
}

init(_ type: UniBridge.StructType, as: Value.Type = Value.self) where Value: ValueBindingStructType {
let mapper = UniBridge.shared.structMapper
self.init(id: uuid(\.5, typeValue: type.rawValue), get: { mapper.binding(type).wrappedValue }, set: { mapper.binding(type).wrappedValue = $0 })
}
}
8 changes: 8 additions & 0 deletions app/xcode/Sources/VCamUI/UIComponent/ColorEditField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@ public struct ColorEditField: View {
public var body: some View {
ColorPicker(selection: $value) {
Text(label, bundle: .localize).bold()
#if !DEBUG
.offset(x: 0, y: 16) // Workaround for release build
#endif
}
}
}

extension ColorEditField: Equatable {
public static func == (lhs: Self, rhs: Self) -> Bool {
lhs.value == rhs.value && lhs.label == rhs.label
}
}
33 changes: 33 additions & 0 deletions app/xcode/Sources/VCamUI/UIComponent/UniFloatEditField.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// UniFloatEditField.swift
//
//
// Created by Tatsuya Tanaka on 2023/02/22.
//

import SwiftUI
import VCamBridge

public struct UniFloatEditField: View {
public init(_ label: LocalizedStringKey, type: UniBridge.FloatType, format: String = "%.1f", range: ClosedRange<CGFloat>) {
self.label = label
_value = ExternalStateBinding(type)
self.format = format
self.range = range
}

private let label: LocalizedStringKey
@ExternalStateBinding private var value: CGFloat
private let format: String
private let range: ClosedRange<CGFloat>

public var body: some View {
ValueEditField(label, value: $value, format: format, type: .slider(range))
}
}

extension UniFloatEditField: Equatable {
public static func == (lhs: Self, rhs: Self) -> Bool {
lhs.value == rhs.value && lhs.range == rhs.range && lhs.label == rhs.label
}
}
33 changes: 13 additions & 20 deletions app/xcode/Sources/VCamUI/UIComponent/VCamSection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,21 @@ public struct VCamSection<Content: View>: View {
@State private var isExpanded = false

public var body: some View {
// switch to DisclosureGroup?
VStack(alignment: .leading, spacing: 0) {
HStack {
Image(systemName: isExpanded ? "chevron.down" : "chevron.right")
.foregroundColor(.secondary)
Text(title, bundle: .localize).bold()
Spacer()
DisclosureGroup.init(isExpanded: $isExpanded) {
VStack(alignment: .leading, spacing: 0) {
content
}
.contentShape(Rectangle())
.onTapGesture {
withAnimation {
isExpanded.toggle()
.padding(.top, 8)
.padding(.leading)
} label: {
Text(title, bundle: .localize)
.bold()
.contentShape(Rectangle())
.onTapGesture {
withAnimation {
isExpanded.toggle()
}
}
}
if isExpanded {
VStack(alignment: .leading, spacing: 0) {
content
}
.padding(.top, 8).padding(.leading)
} else {
Color.clear.frame(height: 8)
}
}
}
}
40 changes: 38 additions & 2 deletions app/xcode/Sources/VCamUI/UIComponent/ValueEditField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,30 @@ public struct ValueEditField: View {
let format: String
let type: EditType

@State private var valueText = ""
@State private var debounceTask: Task<Void, Never>?

public var body: some View {
HStack(spacing: 2) {
HStack(spacing: 2) {
Text(label, bundle: .localize).bold()
if !valueHidden {
Text("[\(.init(format: format, value))]")
Text("[\(valueText)]")
.lineLimit(1)
.font(.caption2)
.fontWeight(.thin)
.foregroundColor(.secondary)
.onChange(of: value) { newValue in
debounceTask?.cancel()
debounceTask = Task {
do {
try await Task.sleep(nanoseconds: NSEC_PER_MSEC * 100)
} catch {
return
}
valueText = .init(format: format, newValue)
}
}
}
}
.layoutPriority(1)
Expand All @@ -43,10 +58,31 @@ public struct ValueEditField: View {
.textFieldStyle(.roundedBorder)
}
}
.onAppear {
valueText = .init(format: format, value)
}
}

public enum EditType {
public enum EditType: Equatable {
case slider(ClosedRange<CGFloat>, onEditingChanged: (Bool) -> Void = { _ in })
case stepper

public static func == (lhs: Self, rhs: Self) -> Bool {
switch (lhs, rhs) {
case let (.slider(lrange, _), .slider(rrange, _)): lrange == rrange
case (.stepper, .stepper): true
case (.slider, .stepper), (.stepper, .slider): false
}
}
}
}

extension ValueEditField: Equatable {
public static func == (lhs: Self, rhs: Self) -> Bool {
lhs.value == rhs.value &&
lhs.valueHidden == rhs.valueHidden &&
lhs.format == rhs.format &&
lhs.type == rhs.type &&
lhs.label == rhs.label
}
}
42 changes: 42 additions & 0 deletions app/xcode/Sources/VCamUI/VCamContentView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// VCamContentView.swift
//
//
// Created by Tatsuya Tanaka on 2022/04/09.
//

import Foundation
import SwiftUI

public struct VCamContentView: View {
public init() {}

@EnvironmentObject var state: VCamUIState

public var body: some View {
content()
.frame(maxWidth: .infinity)
.padding(8)
.background(.thinMaterial)
}

@ViewBuilder
func content() -> some View {
switch state.currentMenu {
case .main:
VCamMainView()
case .screenEffect:
VCamDisplayView()
case .recording:
VCamRecordingView()
}
}
}

struct VCamUI_Preview: PreviewProvider {
static var previews: some View {
return VCamContentView()
.frame(width: 500, height: 300)
.background(Color.white)
}
}
Loading

0 comments on commit b66f62a

Please sign in to comment.