Initial commit
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
import MusicAssistantCore
|
||||
import SwiftUI
|
||||
|
||||
struct MusicalParametersEditorView: View {
|
||||
@Binding var project: SongProject
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
ManualAutoIntegerRow(
|
||||
title: "BPM",
|
||||
value: manualAutoIntegerBinding(\.bpm)
|
||||
)
|
||||
ManualAutoTextRow(
|
||||
title: "Key",
|
||||
value: manualAutoTextBinding(\.key),
|
||||
placeholder: "D"
|
||||
)
|
||||
ManualAutoTextRow(
|
||||
title: "Scale",
|
||||
value: manualAutoTextBinding(\.scale),
|
||||
placeholder: "minor"
|
||||
)
|
||||
ManualAutoTextRow(
|
||||
title: "Maqam",
|
||||
value: manualAutoTextBinding(\.maqam),
|
||||
placeholder: "Hijaz"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private func manualAutoIntegerBinding(
|
||||
_ keyPath: WritableKeyPath<SongProject, ManualAutoValue<Int>?>
|
||||
) -> Binding<ManualAutoValue<Int>> {
|
||||
Binding {
|
||||
project[keyPath: keyPath] ?? ManualAutoValue(mode: .auto)
|
||||
} set: { newValue in
|
||||
project[keyPath: keyPath] = newValue
|
||||
}
|
||||
}
|
||||
|
||||
private func manualAutoTextBinding(
|
||||
_ keyPath: WritableKeyPath<SongProject, ManualAutoValue<String>?>
|
||||
) -> Binding<ManualAutoValue<String>> {
|
||||
Binding {
|
||||
project[keyPath: keyPath] ?? ManualAutoValue(mode: .auto)
|
||||
} set: { newValue in
|
||||
project[keyPath: keyPath] = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct ManualAutoIntegerRow: View {
|
||||
let title: String
|
||||
@Binding var value: ManualAutoValue<Int>
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
ManualAutoPicker(title: title, mode: modeBinding)
|
||||
|
||||
if value.mode == .manual {
|
||||
TextField(title, text: integerTextBinding)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var modeBinding: Binding<ControlMode> {
|
||||
Binding {
|
||||
value.mode
|
||||
} set: { newMode in
|
||||
value.mode = newMode
|
||||
if newMode == .auto {
|
||||
value.value = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var integerTextBinding: Binding<String> {
|
||||
Binding {
|
||||
value.value.map(String.init) ?? ""
|
||||
} set: { newValue in
|
||||
value.value = Int(newValue.trimmingCharacters(in: .whitespacesAndNewlines))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct ManualAutoTextRow: View {
|
||||
let title: String
|
||||
@Binding var value: ManualAutoValue<String>
|
||||
let placeholder: String
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
ManualAutoPicker(title: title, mode: modeBinding)
|
||||
|
||||
if value.mode == .manual {
|
||||
TextField(placeholder, text: textBinding)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var modeBinding: Binding<ControlMode> {
|
||||
Binding {
|
||||
value.mode
|
||||
} set: { newMode in
|
||||
value.mode = newMode
|
||||
if newMode == .auto {
|
||||
value.value = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var textBinding: Binding<String> {
|
||||
Binding {
|
||||
value.value ?? ""
|
||||
} set: { newValue in
|
||||
let trimmedValue = newValue.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
value.value = trimmedValue.isEmpty ? nil : trimmedValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct ManualAutoPicker: View {
|
||||
let title: String
|
||||
@Binding var mode: ControlMode
|
||||
|
||||
var body: some View {
|
||||
Picker(title, selection: $mode) {
|
||||
Text("Auto").tag(ControlMode.auto)
|
||||
Text("Manual").tag(ControlMode.manual)
|
||||
}
|
||||
.pickerStyle(.segmented)
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
MusicalParametersEditorPreview()
|
||||
}
|
||||
|
||||
private struct MusicalParametersEditorPreview: View {
|
||||
@State private var project = SongProject(
|
||||
title: "Parameters",
|
||||
idea: "Preview",
|
||||
bpm: ManualAutoValue(mode: .manual, value: 96),
|
||||
key: ManualAutoValue(mode: .auto),
|
||||
scale: ManualAutoValue(mode: .manual, value: "minor"),
|
||||
maqam: ManualAutoValue(mode: .auto)
|
||||
)
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
MusicalParametersEditorView(project: $project)
|
||||
}
|
||||
.formStyle(.grouped)
|
||||
.frame(width: 340)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user