#if CARPLAY_DEMO import SwiftUI /// Die Libelle auf dem Fahrzeugdisplay. /// /// Quer geteilt: links die Blase, rechts in Worten, was zu tun ist. Beim /// Rangieren wird abwechselnd auf Display und Umfeld geschaut – deshalb steht /// die Aussage in einem Satz da, statt sich aus zwei Zahlen ergeben zu müssen. /// /// Die Groessen sind auf die 400 × 240 **Punkte** ausgelegt, die CarPlay /// liefert – nicht auf die 800 × 480 Pixel. Das ist die Falle: In Pixeln /// gedachte Schriftgroessen sind auf dem Fahrzeugdisplay doppelt zu gross und /// schneiden den Text ab. struct CarPlayLevelScreen: View { @Environment(CarPlayLevelSource.self) private var source private var state: LevelState { LevelState(pitch: source.pitch, roll: source.roll) } var body: some View { ZStack { Color.black.ignoresSafeArea() if CarPlaySpeedGate.shared.isStationary { levelling } else { driving } } .onAppear { CarPlaySpeedGate.shared.start() } .onDisappear { CarPlaySpeedGate.shared.stop() } } private var levelling: some View { HStack(spacing: 18) { LevelBubble(pitch: source.pitch, roll: source.roll) VStack(alignment: .leading, spacing: 10) { VStack(alignment: .leading, spacing: 2) { let lines = state.shortInstructions ForEach(lines.isEmpty ? ["Keine Verbindung"] : lines, id: \.self) { line in Text(line) .font(.system(size: 20, weight: .semibold, design: .rounded)) .foregroundStyle(state.isLevel ? .green : .white) .lineLimit(1) .minimumScaleFactor(0.8) } } HStack(spacing: 16) { tile("Längs", LevelDirectionFormatting.pitchTile(source.pitch)) tile("Quer", LevelDirectionFormatting.rollTile(source.roll)) } if source.isSimulated { // Ohne diesen Hinweis wäre ein Screenshot aus dem Simulator // eine Behauptung über Messwerte, die es nicht gab. Text("Simulierte Werte") .font(.system(size: 11, weight: .medium)) .foregroundStyle(.orange) } } .frame(maxWidth: .infinity, alignment: .leading) } .padding(16) } private var driving: some View { VStack(spacing: 10) { Image(systemName: "car.fill") .font(.system(size: 30)) Text("Nivellierung nur im Stand") .font(.system(size: 20, weight: .semibold, design: .rounded)) } .foregroundStyle(.white.opacity(0.7)) } private func tile(_ label: String, _ value: String) -> some View { VStack(alignment: .leading, spacing: 1) { Text(label) .font(.system(size: 11, weight: .medium)) .foregroundStyle(.secondary) Text(value) .font(.system(size: 22, weight: .semibold, design: .rounded)) .monospacedDigit() .foregroundStyle(.white) } } } #endif