033a9d406a
Aligned to the official X-Plane 1000 manual: - NAV radio: active RIGHT / standby LEFT (boxed) per S.12 (COM already correct) - ALT UNIT softkey (IN / HPA) in the PFD submenu, baro readout converts (S.20) - DCLTR cycles 3 levels (land / +NDB / flight-plan only) with DCLTR-n label (S.56) - TOPO and TERRAIN are now independent toggles (relief vs awareness overlay) (S.57) - Barometric MINIMUMS: BARO MIN bug + readout on the altimeter, amber "MINIMUMS" annunciation at/below the decision altitude; set via TMR/REF (lifted to App) - OBS mode: HSI course follows the CRS knob (magenta "OBS"), sequencing suspended - New Audio Panel tab (COM mic/receive, MKR/DME/ADF, intercom, Display Backup) (S.91) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
94 lines
4.1 KiB
React
94 lines
4.1 KiB
React
import React, { useState } from 'react';
|
|
|
|
// X1000 Audio Panel (Manual S.91). Selects which radios are heard, which COM is
|
|
// used to transmit (MIC), marker/DME/ADF Morse audio, intercom, and the Display
|
|
// Backup (reversionary) key. Selections are local state with authentic lit keys.
|
|
//
|
|
// COM MIC is single-select (one transmit radio); the receive/audio keys and the
|
|
// Morse keys toggle independently — exactly like the real unit.
|
|
export default function AudioPanel({ xp }) {
|
|
const [mic, setMic] = useState('com1'); // transmit radio: com1 | com2 | tel
|
|
const [recv, setRecv] = useState({ com1: true }); // receive/audio selections
|
|
const [hiSens, setHiSens] = useState(false);
|
|
const [crew, setCrew] = useState('pilot');
|
|
const [vol, setVol] = useState(60);
|
|
|
|
const r = (k) => !!recv[k];
|
|
const toggle = (k) => setRecv((s) => ({ ...s, [k]: !s[k] }));
|
|
// a single audio key: lit green for MIC (transmit), cyan for receive/Morse
|
|
const Key = ({ k, label, sub, on, kind = 'recv', onClick }) => (
|
|
<button className={`apk ${kind} ${on ? 'on' : ''}`} onClick={onClick}>
|
|
<span className="apk-l">{label}</span>{sub && <span className="apk-s">{sub}</span>}
|
|
</button>
|
|
);
|
|
|
|
return (
|
|
<div className="audio-panel">
|
|
<div className="apnl">
|
|
<div className="apnl-title">AUDIO PANEL</div>
|
|
|
|
<div className="apnl-grp">
|
|
<div className="apnl-h">COM</div>
|
|
<div className="apnl-row">
|
|
<Key label="COM1 MIC" kind="mic" on={mic === 'com1'} onClick={() => setMic('com1')} />
|
|
<Key label="COM1" on={r('com1')} onClick={() => toggle('com1')} />
|
|
</div>
|
|
<div className="apnl-row">
|
|
<Key label="COM2 MIC" kind="mic" on={mic === 'com2'} onClick={() => setMic('com2')} />
|
|
<Key label="COM2" on={r('com2')} onClick={() => toggle('com2')} />
|
|
</div>
|
|
<div className="apnl-row">
|
|
<Key label="COM 1/2" on={false} onClick={() => setMic((m) => (m === 'com1' ? 'com2' : 'com1'))} />
|
|
<Key label="TEL" kind="mic" on={mic === 'tel'} onClick={() => setMic('tel')} />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="apnl-grp">
|
|
<div className="apnl-h">CABIN / SPEAKER</div>
|
|
<div className="apnl-row">
|
|
<Key label="PA" on={r('pa')} onClick={() => toggle('pa')} />
|
|
<Key label="SPKR" on={r('spkr')} onClick={() => toggle('spkr')} />
|
|
</div>
|
|
<div className="apnl-row">
|
|
<Key label="MKR / MUTE" on={r('mkr')} onClick={() => toggle('mkr')} />
|
|
<Key label="HI SENS" on={hiSens} onClick={() => setHiSens((v) => !v)} />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="apnl-grp">
|
|
<div className="apnl-h">NAV</div>
|
|
<div className="apnl-row">
|
|
<Key label="DME" on={r('dme')} onClick={() => toggle('dme')} />
|
|
<Key label="NAV1" on={r('nav1')} onClick={() => toggle('nav1')} />
|
|
</div>
|
|
<div className="apnl-row">
|
|
<Key label="ADF" on={r('adf')} onClick={() => toggle('adf')} />
|
|
<Key label="NAV2" on={r('nav2')} onClick={() => toggle('nav2')} />
|
|
</div>
|
|
<div className="apnl-row">
|
|
<Key label="AUX" on={r('aux')} onClick={() => toggle('aux')} />
|
|
<Key label="MAN SQ" on={r('msq')} onClick={() => toggle('msq')} />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="apnl-grp">
|
|
<div className="apnl-h">CREW · ICS</div>
|
|
<div className="apnl-row">
|
|
<Key label="PILOT" kind="mic" on={crew === 'pilot'} onClick={() => setCrew('pilot')} />
|
|
<Key label="COPLT" kind="mic" on={crew === 'copilot'} onClick={() => setCrew('copilot')} />
|
|
</div>
|
|
<div className="apnl-vol">
|
|
<span>PILOT INTERCOM VOL</span>
|
|
<input type="range" min="0" max="100" value={vol} onChange={(e) => setVol(+e.target.value)} />
|
|
<b>{vol}</b>
|
|
</div>
|
|
</div>
|
|
|
|
<button className="apnl-backup" onClick={() => xp && xp.command && xp.command('mfd_softkey1')} title="Display Backup (reversionary)">
|
|
DISPLAY BACKUP
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|