PFD/cockpit polish + KAP140 autopilot + UI refinements

- PFD: full-screen 2D attitude, G1000 yellow+magenta chevron symbology, rAF
  60fps horizon smoothing, translucent tapes, slimmer softkey bar, header fixes
- Collapsible macOS-dark sidebar (Inter), VFR six-pack + engine cluster + tach
- KAP140 autopilot on the analog page; GMC-710 AFCS tab
- FMS rebuilt as an X-Plane-style CDU; PWA; settings panel (knob mode)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-01 17:20:16 +02:00
parent ebc33a78b7
commit 354ea5d44b
10 changed files with 253 additions and 82 deletions
+32 -4
View File
@@ -45,9 +45,14 @@ export default function App() {
const [navWide, setNavWide] = useState(() => localStorage.getItem('navWide') === '1');
const go = (id) => { setTab(id); history.replaceState(null, '', `#${id}`); };
const toggleNav = () => setNavWide((w) => { localStorage.setItem('navWide', w ? '0' : '1'); return !w; });
// Knob interaction: 'arrows' (visible ˄‹›˅, touch-friendly) or 'zones' (click
// the knob face). Settable in the settings panel, remembered.
const [knobMode, setKnobMode] = useState(() => localStorage.getItem('knobMode') || 'arrows');
const [settings, setSettings] = useState(false);
const setKnob = (m) => { localStorage.setItem('knobMode', m); setKnobMode(m); };
// Synthetic-terrain (3D) vs. classic blue/brown attitude — toggled by the
// PFD → SYN TERR softkey, exactly like the real XPLANE 1000.
const [svt3d, setSvt3d] = useState(true);
const [svt3d, setSvt3d] = useState(false);
// The PFD INSET map (bottom-left) is off by default and toggled by its softkey.
const [inset, setInset] = useState(false);
// INSET map options (base layer + declutter), set from the INSET submenu.
@@ -82,6 +87,13 @@ export default function App() {
</button>
))}
</nav>
<button className="snav-i sb-gear" onClick={() => setSettings(true)} title="Einstellungen">
<svg className="snav-ic" viewBox="0 0 22 22" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
<circle cx="11" cy="11" r="3.2" />
<path d="M11 2.5v2M11 17.5v2M2.5 11h2M17.5 11h2M5 5l1.4 1.4M15.6 15.6L17 17M17 5l-1.4 1.4M6.4 15.6L5 17" />
</svg>
<span className="snav-lbl">Einstellungen</span>
</button>
<div className={`sb-conn ${connKind}`} title={connText}>
<span className="dot" />
<span className="snav-lbl">{connText}</span>
@@ -90,7 +102,7 @@ export default function App() {
<main className="screen">
{tab === 'pfd' && (
<Bezel variant="pfd" xp={xp} svt3d={svt3d} onToggleSvt={() => setSvt3d((v) => !v)}
<Bezel variant="pfd" xp={xp} knobMode={knobMode} svt3d={svt3d} onToggleSvt={() => setSvt3d((v) => !v)}
inset={inset} onSetInset={setInset} insetMode={insetMode} onInsetMode={setInsetMode}
nrst={nrst} onToggleNrst={() => setNrst((v) => !v)} onDirect={() => setDto(true)}
tmr={tmr} onToggleTmr={() => setTmr((v) => !v)} onProc={() => setProc(true)}>
@@ -99,17 +111,33 @@ export default function App() {
</Bezel>
)}
{tab === 'mfd' && (
<Bezel variant="mfd" xp={xp} mapMode={mapMode} onMapMode={setMapMode} onDirect={() => setDto(true)} onProc={() => setProc(true)}>
<Bezel variant="mfd" xp={xp} knobMode={knobMode} mapMode={mapMode} onMapMode={setMapMode} onDirect={() => setDto(true)} onProc={() => setProc(true)}>
<MFD values={xp.values} flightPlan={xp.flightPlan} fp={xp.fp} mapMode={mapMode} />
</Bezel>
)}
{tab === 'map' && <MapView values={xp.values} flightPlan={xp.flightPlan} fp={xp.fp} />}
{tab === 'fms' && <CDU xp={xp} />}
{tab === 'vfr' && <VFR values={xp.values} />}
{tab === 'vfr' && <VFR xp={xp} />}
{tab === 'ap' && <AutopilotPanel xp={xp} />}
</main>
{dto && <DirectTo xp={xp} onClose={() => setDto(false)} />}
{proc && <Proc xp={xp} onClose={() => setProc(false)} />}
{settings && (
<div className="dlg-backdrop" onClick={() => setSettings(false)}>
<div className="dlg" onClick={(e) => e.stopPropagation()} style={{ minWidth: 360 }}>
<div className="dlg-head">EINSTELLUNGEN</div>
<div style={{ padding: 14 }}>
<div className="set-lbl">Knopf-Bedienung</div>
<div className="set-opt">
<button className={`fbtn ${knobMode === 'arrows' ? 'add' : ''}`} onClick={() => setKnob('arrows')}>Pfeiltasten ˄˅</button>
<button className={`fbtn ${knobMode === 'zones' ? 'add' : ''}`} onClick={() => setKnob('zones')}>Klickzonen am Knopf</button>
</div>
<div className="set-hint">Pfeiltasten sind touch-freundlich. Klickzonen: oben/unten = grob, links/rechts = fein, Mitte = PUSH.</div>
</div>
<div className="dlg-actions"><button className="fbtn" onClick={() => setSettings(false)}>Schließen</button></div>
</div>
</div>
)}
</div>
);
}