From 06a90001363fdcb542b531a74ed2c18f714f58c4 Mon Sep 17 00:00:00 2001 From: Arturs Artamonovs Date: Fri, 17 Jan 2025 09:27:56 +0000 Subject: waterfallui: data get processed and drawn, ui controlls are dummy --- Waterfall_UI/ContentView.swift | 194 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 Waterfall_UI/ContentView.swift (limited to 'Waterfall_UI/ContentView.swift') diff --git a/Waterfall_UI/ContentView.swift b/Waterfall_UI/ContentView.swift new file mode 100644 index 0000000..6c09fec --- /dev/null +++ b/Waterfall_UI/ContentView.swift @@ -0,0 +1,194 @@ +// +// ContentView.swift +// Waterfall_UI +// +// Created by Jacky Jack on 06/01/2025. +// + +import SwiftUI +import SwiftData + +private struct DeviceChoose: Identifiable { + let deviceName: String + var id: String { deviceName } +} + +private let deviceList: [DeviceChoose] = [ + DeviceChoose(deviceName:"RtlSDR SN:00000000"), + DeviceChoose(deviceName:"BladeRF SN:00000000"), + DeviceChoose(deviceName:"AirSpy SN:00000000"), + DeviceChoose(deviceName:"AirSpyHF SN:00000000") +] + +private struct SampleRateChoose: Identifiable { + let sampleRate: Int + var id: String { String(sampleRate) } +} + +private let sampleRateList: [SampleRateChoose] = [ + SampleRateChoose(sampleRate:1000), + SampleRateChoose(sampleRate:100000) +] + +private struct FFTOptions: Identifiable { + let binsize: Int + var id: String { String(binsize) } +} + +private let fftBinsList: [FFTOptions] = [ + FFTOptions(binsize: 512), + FFTOptions(binsize: 1024), + FFTOptions(binsize: 2048), + FFTOptions(binsize: 4096), +] + +struct ContentView: View { + @Environment(\.modelContext) private var modelContext + + @EnvironmentObject var sdrSpectrum: SDRSpectrum + + @Query private var items: [Item] + + @State private var selectedDevice: String = deviceList[0].deviceName + @State private var selectedSampleRate: String = String(sampleRateList[0].sampleRate) + @State private var setFrequency: Int = 100000000 + @State private var toggleAGC: Bool = false + @State private var selectorFFTBin: String = String(fftBinsList[0].binsize) + @State private var statusMessage: String = "" + + + var body: some View { + /* + NavigationSplitView { + List { + ForEach(items) { item in + NavigationLink { + Text("Item at \(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))") + } label: { + Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard)) + } + } + .onDelete(perform: deleteItems) + } + .navigationSplitViewColumnWidth(min: 180, ideal: 200) + .toolbar { + ToolbarItem { + Button(action: addItem) { + Label("Add Item", systemImage: "plus") + } + } + } + } detail: { + Text("Select an item") + } + */ + HStack { + VStack { + Text("Hardware")//.border(.red) + Picker("Device", selection:$selectedDevice) { + ForEach(deviceList) { device in + Text("\(device.deviceName)") + } + } + .onChange(of: selectedDevice) { + statusMessage = "selected \(selectedDevice)" + } + Picker("SampleRate", selection:$selectedSampleRate) { + ForEach(sampleRateList) { samplerate in + Text("\(samplerate.sampleRate)") + } + }.onChange(of:selectedSampleRate) { + statusMessage = "selected \(selectedSampleRate)" + } + Divider() + HStack { + Text("Control") + Button("Start") { + print("Start") + statusMessage = "Running" + } + Button("Stop") { + print("Stop") + statusMessage = "Idle" + } + } + Divider() + Text("Config") + HStack { + Text("Frequency: ") + TextField("Frquency: ", value: $setFrequency, format: .number) + .onChange(of: setFrequency) { + statusMessage = "frequency \(setFrequency)" + } + .onSubmit { + statusMessage = "frequency submit" + } + Text("Hz") + } + Toggle("AGC",isOn: $toggleAGC) + .onChange(of: toggleAGC) { + if (self.toggleAGC) { + statusMessage = "AGC on" + } else { + statusMessage = "AGC off" + } + } + Divider() + Text("FFT View") + Picker("FFT bins", selection:$selectorFFTBin) { + ForEach(fftBinsList) { binssize in + Text("\(binssize.binsize)") + } + } + .onChange(of: selectorFFTBin) { + statusMessage = "set fft bins \(selectorFFTBin)" + } + Spacer() + Divider()//.border(.red) + + HStack { + Text("Version: \(software_version)")//.border(.red) + Spacer() + } + } + Divider() + VStack { + //Text("Right")//.border(.red) + Divider() + Image(decorative: sdrSpectrum.outputImage, + scale: 1, + orientation: .left) + .resizable() + .scaledToFit() + .rotationEffect(Angle(degrees: 90)) + Spacer() + Divider()//.border(.red) + + HStack { + Spacer() + Text("Status message: \(statusMessage)")//.border(.red) + } + } + } + } + + private func addItem() { + withAnimation { + let newItem = Item(timestamp: Date()) + modelContext.insert(newItem) + } + } + + private func deleteItems(offsets: IndexSet) { + withAnimation { + for index in offsets { + modelContext.delete(items[index]) + } + } + } +} + +#Preview { + ContentView() + .modelContainer(for: Item.self, inMemory: true) +} -- cgit v1.2.3