152 lines
4.6 KiB
Swift
152 lines
4.6 KiB
Swift
import SwiftUI
|
|
|
|
struct ContentView: View {
|
|
@Bindable var state: AppState
|
|
@Environment(\.horizontalSizeClass) private var sizeClass
|
|
|
|
var body: some View {
|
|
Group {
|
|
if sizeClass == .regular {
|
|
iPadLayout
|
|
} else {
|
|
iPhoneLayout
|
|
}
|
|
}
|
|
.preferredColorScheme(.dark)
|
|
}
|
|
|
|
// MARK: - iPad: NavigationSplitView
|
|
|
|
private var iPadLayout: some View {
|
|
NavigationSplitView {
|
|
sidebar
|
|
} detail: {
|
|
VStack(spacing: 0) {
|
|
StatusBar(state: state)
|
|
Divider()
|
|
tabContent
|
|
}
|
|
}
|
|
}
|
|
|
|
private var sidebar: some View {
|
|
List {
|
|
Section("Measurements") {
|
|
sidebarButton(.eis, "EIS", "waveform.path.ecg")
|
|
sidebarButton(.lsv, "LSV", "chart.xyaxis.line")
|
|
sidebarButton(.amp, "Amperometry", "bolt.fill")
|
|
sidebarButton(.chlorine, "Chlorine", "drop.fill")
|
|
sidebarButton(.ph, "pH", "scalemass")
|
|
}
|
|
Section("Data") {
|
|
sidebarButton(.sessions, "Sessions", "folder")
|
|
sidebarButton(.connection, "Connection", "antenna.radiowaves.left.and.right")
|
|
}
|
|
Section {
|
|
cleanControls
|
|
}
|
|
}
|
|
.navigationTitle("Cue")
|
|
.listStyle(.sidebar)
|
|
}
|
|
|
|
private func sidebarButton(_ tab: Tab, _ title: String, _ icon: String) -> some View {
|
|
Button {
|
|
state.tab = tab
|
|
} label: {
|
|
Label(title, systemImage: icon)
|
|
}
|
|
.listRowBackground(state.tab == tab ? Color.accentColor.opacity(0.2) : nil)
|
|
}
|
|
|
|
private var cleanControls: some View {
|
|
VStack(alignment: .leading, spacing: 6) {
|
|
Text("Electrode Clean")
|
|
.font(.caption.weight(.semibold))
|
|
.foregroundStyle(.secondary)
|
|
HStack(spacing: 6) {
|
|
TextField("mV", text: $state.cleanV)
|
|
.textFieldStyle(.roundedBorder)
|
|
.frame(width: 60)
|
|
#if os(iOS)
|
|
.keyboardType(.numberPad)
|
|
#endif
|
|
TextField("s", text: $state.cleanDur)
|
|
.textFieldStyle(.roundedBorder)
|
|
.frame(width: 45)
|
|
#if os(iOS)
|
|
.keyboardType(.numberPad)
|
|
#endif
|
|
Button("Clean") { state.startClean() }
|
|
.buttonStyle(.bordered)
|
|
.tint(Color(red: 0.65, green: 0.55, blue: 0.15))
|
|
.controlSize(.small)
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - iPhone: TabView
|
|
|
|
private var iPhoneLayout: some View {
|
|
TabView(selection: $state.tab) {
|
|
VStack(spacing: 0) {
|
|
StatusBar(state: state)
|
|
EISView(state: state)
|
|
}
|
|
.tabItem { Label("EIS", systemImage: "waveform.path.ecg") }
|
|
.tag(Tab.eis)
|
|
|
|
VStack(spacing: 0) {
|
|
StatusBar(state: state)
|
|
LSVView(state: state)
|
|
}
|
|
.tabItem { Label("LSV", systemImage: "chart.xyaxis.line") }
|
|
.tag(Tab.lsv)
|
|
|
|
VStack(spacing: 0) {
|
|
StatusBar(state: state)
|
|
AmpView(state: state)
|
|
}
|
|
.tabItem { Label("Amp", systemImage: "bolt.fill") }
|
|
.tag(Tab.amp)
|
|
|
|
VStack(spacing: 0) {
|
|
StatusBar(state: state)
|
|
ChlorineView(state: state)
|
|
}
|
|
.tabItem { Label("Chlorine", systemImage: "drop.fill") }
|
|
.tag(Tab.chlorine)
|
|
|
|
VStack(spacing: 0) {
|
|
StatusBar(state: state)
|
|
PhView(state: state)
|
|
}
|
|
.tabItem { Label("pH", systemImage: "scalemass") }
|
|
.tag(Tab.ph)
|
|
|
|
SessionView(state: state)
|
|
.tabItem { Label("Sessions", systemImage: "folder") }
|
|
.tag(Tab.sessions)
|
|
|
|
ConnectionView(state: state)
|
|
.tabItem { Label("Connection", systemImage: "antenna.radiowaves.left.and.right") }
|
|
.tag(Tab.connection)
|
|
}
|
|
}
|
|
|
|
// MARK: - Tab content
|
|
|
|
@ViewBuilder
|
|
private var tabContent: some View {
|
|
switch state.tab {
|
|
case .eis: EISView(state: state)
|
|
case .lsv: LSVView(state: state)
|
|
case .amp: AmpView(state: state)
|
|
case .chlorine: ChlorineView(state: state)
|
|
case .ph: PhView(state: state)
|
|
case .sessions: SessionView(state: state)
|
|
case .connection: ConnectionView(state: state)
|
|
}
|
|
}
|
|
}
|