Files
luma/Luma/CustomInstrumentConfigView.swift
Ole André Vadla Ravnås bf06ef8b8e Make HookPack/custom-instrument panes scrollable
Wrap the config view in ScrollView (SwiftUI) and the detail
UI's outer Box in a ScrolledWindow (GTK) so widgets past the
visible area can be reached.
2026-05-20 21:31:56 +02:00

92 lines
3.1 KiB
Swift

import LumaCore
import SwiftUI
struct CustomInstrumentConfigView: View {
let defID: UUID
@Binding var config: CustomInstrumentConfig
let engine: Engine
@Binding var selection: SidebarItemID?
@Environment(\.instrumentInstance) private var instrumentInstance
private var def: CustomInstrumentDef? {
engine.customInstruments.def(withId: defID)
}
var body: some View {
ScrollView {
VStack(alignment: .leading, spacing: 12) {
header
GroupBox("Features") {
Group {
if let def, !def.features.isEmpty {
VStack(alignment: .leading, spacing: 12) {
ForEach(def.features) { feature in
InstrumentFeatureRow(
feature: feature,
state: stateBinding(for: feature)
)
}
}
} else {
Text("This custom instrument does not declare any features.")
.font(.subheadline)
.foregroundStyle(.secondary)
}
}
.padding(.leading, 12)
.padding(.vertical, 4)
.frame(maxWidth: .infinity, alignment: .leading)
}
if let def {
InstrumentWidgetsRenderer(
widgets: def.widgets,
engine: engine,
selection: $selection
)
}
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(8)
}
}
private var header: some View {
HStack(spacing: 8) {
if let def {
InstrumentIconView(icon: def.icon, pointSize: 14)
Text(def.name).font(.headline)
} else {
Text("Custom Instrument").font(.headline)
}
Spacer()
if instrumentInstance != nil {
Button("Edit Source\u{2026}") {
if let entrypoint = def?.entrypoint {
selection = .customInstrumentFile(defID, entrypoint)
} else {
selection = .customInstrumentDef(defID)
}
}
.accessibilityIdentifier("customInstrument.editSource")
}
}
}
private func stateBinding(for feature: CustomInstrumentDef.Feature) -> Binding<FeatureState> {
Binding(
get: {
config.features[feature.id]
?? FeatureState(enabled: feature.enabledByDefault, value: feature.schema.defaultValue)
},
set: { newValue in
var updated = config
updated.features[feature.id] = newValue
config = updated
}
)
}
}