Files
Gas-Tank-AR-App/GasTankAR/Views/AR/Projects/ARProjectCreateView.swift

141 lines
5.0 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import SwiftUI
struct ARProjectCreateView: View {
let isEditing: Bool
let onCreate: (String, Tank, Bool) -> Void
@State private var name = ""
@State private var tank = Tank()
@Environment(\.tankCatalog) private var catalog
init(project: ARProject? = nil, onCreate: @escaping (String, Tank, Bool) -> Void) {
isEditing = project != nil
self.onCreate = onCreate
_name = State(initialValue: project?.name ?? "")
_tank = State(initialValue: project?.tank ?? Tank())
}
private var canCreate: Bool {
!name.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
&& catalog.definition(for: tank) != nil
}
var body: some View {
Form {
Section {
VStack(spacing: 8) {
ARProjectTankImage(tank: tank)
.frame(height: 150)
.frame(maxWidth: .infinity)
Text("\(tank.size.volumeTitle) · \(tank.placement.displayName) · \(catalog.displayName(for: tank.color))")
.font(.subheadline).foregroundStyle(.secondary)
}
.padding(.vertical, 8)
}
Section("Name") {
TextField("Projektname", text: $name)
.textInputAutocapitalization(.sentences)
}
Section("Tankkonfiguration") {
ARProjectConfigurationView(tank: $tank)
}
}
.navigationTitle(isEditing ? "Projekt bearbeiten" : "Neues Projekt")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .confirmationAction) {
Button(isEditing ? "Speichern" : "Anlegen") { onCreate(name, tank, false) }
.disabled(!canCreate)
}
}
.safeAreaInset(edge: .bottom) {
Button { onCreate(name, tank, true) } label: {
Label(isEditing ? "Speichern und AR-Modus starten" : "Anlegen und AR-Modus starten", systemImage: "arkit")
.font(.headline).frame(maxWidth: .infinity).padding(.vertical, 10)
}
.buttonStyle(.borderedProminent)
.disabled(!canCreate)
.padding()
.background(.bar)
}
.onAppear { tank = catalog.normalized(tank) }
}
}
struct ARProjectConfigurationView: View {
@Binding var tank: Tank
@Environment(\.tankCatalog) private var catalog
var body: some View {
VStack(alignment: .leading, spacing: 10) {
Text("Volumen").font(.subheadline)
Picker("Volumen", selection: $tank.size) {
ForEach(catalog.sizes(for: tank.placement)) { size in
Text(size.volumeTitle).tag(size)
}
}
.pickerStyle(.segmented)
}
.padding(.vertical, 4)
VStack(alignment: .leading, spacing: 10) {
Text("Aufstellung").font(.subheadline)
Picker("Aufstellung", selection: $tank.placement) {
ForEach(catalog.placements) { placement in
Text(placement.displayName).tag(placement)
}
}
.pickerStyle(.segmented)
}
.padding(.vertical, 4)
HStack {
Text("Farbe")
Spacer()
ForEach(catalog.colors(for: tank.size, placement: tank.placement)) { color in
Button { tank.color = color } label: {
Circle().fill(swatch(color))
.frame(width: 28, height: 28)
.overlay { Circle().strokeBorder(.gray.opacity(0.5), lineWidth: 1) }
.padding(4)
.overlay { Circle().strokeBorder(tank.color == color ? Color.accentColor : .clear, lineWidth: 2) }
.frame(minWidth: 44, minHeight: 44)
}
.buttonStyle(.plain)
.accessibilityLabel(catalog.displayName(for: color))
.accessibilityAddTraits(tank.color == color ? .isSelected : [])
}
Text(catalog.displayName(for: tank.color)).foregroundStyle(.secondary).font(.subheadline)
}
.onChange(of: tank.placement) { _, _ in normalize() }
.onChange(of: tank.size) { _, _ in normalize() }
}
private func normalize() {
tank = catalog.normalized(tank)
tank.showLidOnly = false
}
private func swatch(_ color: TankColor) -> Color {
switch color {
case .white: .white
case .green: Color(red: 0.49, green: 0.65, blue: 0.42)
case .olive: Color(red: 0.37, green: 0.40, blue: 0.22)
}
}
}
#Preview("Projekt konfigurieren") {
NavigationStack {
ARProjectCreateView { _, _, _ in }
}
.frame(width: 600, height: 760)
}
#Preview("Projekt konfigurieren – Dunkel") {
NavigationStack {
ARProjectCreateView { _, _, _ in }
}
.frame(width: 600, height: 760)
.preferredColorScheme(.dark)
}