feat(k3): align RIT/XIT and the power step with the other consoles
'None of the consoles look alike' is the complaint ShiftRow exists to answer, and the Elecraft panel was still driving its offset with a row of nudge buttons. It now uses the shared control — ±, wheel, typed value — plus the same Ctrl+←/→ 10 Hz clarifier the Icom and TCI panels have. The K3 keeps ONE offset for RIT and XIT, so both rows show it, exactly like the Icom's. The backend gains the absolute setter the shared control speaks (SetKenwoodRITOffset, funnelled through the same RO write as the nudge), and the power slider moves in 1 W steps — nobody asks a K3 for 'between 10 and 15 watts' in fives. Also per review: the chase switches are labelled 'Chase POTA' / 'Chase SOTA', matching 'Chase new grids' beside them.
This commit is contained in:
@@ -4,12 +4,13 @@ import {
|
||||
GetKenwoodState, RefreshKenwood, SetKenwoodPower, SetKenwoodAFGain, SetKenwoodTX, TuneKenwoodATU,
|
||||
SetKenwoodRFGain, SetKenwoodMicGain, SetKenwoodSquelch, SetKenwoodPreamp, SetKenwoodAtt,
|
||||
SetKenwoodNB, SetKenwoodNR, SetKenwoodAGC, SetKenwoodFilter, SetKenwoodAntenna,
|
||||
SetKenwoodRIT, SetKenwoodXIT, ClearKenwoodRIT, SetKenwoodKeySpeed, ToggleKenwoodATU, NudgeKenwoodRIT, SetKenwoodPanelMode,
|
||||
SetKenwoodRIT, SetKenwoodXIT, ClearKenwoodRIT, SetKenwoodKeySpeed, ToggleKenwoodATU, SetKenwoodRITOffset, SetKenwoodPanelMode,
|
||||
GetCATState,
|
||||
} from '../../wailsjs/go/main/App';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { useI18n } from '@/lib/i18n';
|
||||
import { sMeterRST } from '@/lib/rst';
|
||||
import { ShiftRow } from '@/components/ShiftRow';
|
||||
import { MeterBar } from '@/components/MeterBar';
|
||||
import { WheelRange } from '@/components/WheelRange';
|
||||
|
||||
@@ -102,6 +103,21 @@ function isDataMode(m?: string): boolean {
|
||||
export function ElecraftPanel({ onReportRST }: { onReportRST?: (rst: string) => void }) {
|
||||
const { t } = useI18n();
|
||||
const [st, setSt] = useState<KenwoodState>(ZERO);
|
||||
// Ctrl+Left/Right shifts the RIT by ±10 Hz while RIT is on — the same
|
||||
// keyboard clarifier the Icom and TCI consoles have, for zero-beating a
|
||||
// caller without touching the mouse.
|
||||
const stRef = useRef(st); stRef.current = st;
|
||||
useEffect(() => {
|
||||
const onKey = (e: KeyboardEvent) => {
|
||||
if (!e.ctrlKey || (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight')) return;
|
||||
const v = stRef.current;
|
||||
if (!v.available || !v.rit) return;
|
||||
e.preventDefault();
|
||||
SetKenwoodRITOffset((v.rit_offset || 0) + (e.key === 'ArrowRight' ? 10 : -10)).catch(() => {});
|
||||
};
|
||||
window.addEventListener('keydown', onKey);
|
||||
return () => window.removeEventListener('keydown', onKey);
|
||||
}, []);
|
||||
const [freqHz, setFreqHz] = useState(0);
|
||||
const [err, setErr] = useState('');
|
||||
// Optimistic overlay: a slider must follow the finger, not the poll. Dropped
|
||||
@@ -248,7 +264,7 @@ export function ElecraftPanel({ onReportRST }: { onReportRST?: (rst: string) =>
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-x-6 gap-y-2">
|
||||
<label className="flex items-center gap-2 text-xs">
|
||||
<span className="w-16 shrink-0 text-muted-foreground">{t('k3.power')}</span>
|
||||
<WheelRange min={0} max={110} step={5} disabled={off}
|
||||
<WheelRange min={0} max={110} step={1} disabled={off}
|
||||
value={view.rf_power ?? 0}
|
||||
onChange={(n) => put({ rf_power: n }, () => SetKenwoodPower(n))} />
|
||||
<span className="w-12 text-right font-mono tabular-nums">{view.rf_power ?? 0} W</span>
|
||||
@@ -311,21 +327,18 @@ export function ElecraftPanel({ onReportRST }: { onReportRST?: (rst: string) =>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* RIT / XIT. Clear zeroes both offsets at once — the radio's own RC,
|
||||
and what an operator means by "clear it". */}
|
||||
{/* RIT / XIT — the shared ShiftRow, exactly as the Icom and TCI consoles
|
||||
drive theirs: ± / wheel / type, Ctrl+←/→ while RIT is on. The K3 has
|
||||
ONE offset for both, so both rows show it, like the Icom's. */}
|
||||
<div className="space-y-1.5">
|
||||
<ShiftRow label="RIT" accent="#8b5cf6" on={view.rit} hz={view.rit_offset || 0} disabled={off}
|
||||
onToggle={() => SetKenwoodRIT(!view.rit).catch(setErrMsg)}
|
||||
onSet={(hz) => SetKenwoodRITOffset(hz).catch(setErrMsg)} />
|
||||
<ShiftRow label="XIT" accent="#f59e0b" on={view.xit} hz={view.rit_offset || 0} disabled={off}
|
||||
onToggle={() => SetKenwoodXIT(!view.xit).catch(setErrMsg)}
|
||||
onSet={(hz) => SetKenwoodRITOffset(hz).catch(setErrMsg)} />
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-1.5">
|
||||
<Toggle label="RIT" on={view.rit} off={off} onClick={() => SetKenwoodRIT(!view.rit).catch(setErrMsg)} />
|
||||
<Toggle label="XIT" on={view.xit} off={off} onClick={() => SetKenwoodXIT(!view.xit).catch(setErrMsg)} />
|
||||
{/* The offset itself. A lit RIT button says the feature is on and
|
||||
nothing about where it has put the receiver. */}
|
||||
{[-100, -10, 10, 100].map((d) => (
|
||||
<Toggle key={d} label={(d > 0 ? '+' : '') + d} on={false} off={off}
|
||||
onClick={() => NudgeKenwoodRIT(d).catch(setErrMsg)} />
|
||||
))}
|
||||
<span className="text-[11px] font-mono tabular-nums text-muted-foreground w-16">
|
||||
{view.rit_offset > 0 ? '+' : ''}{view.rit_offset || 0} Hz
|
||||
</span>
|
||||
<Toggle label={t('k3.clear')} on={false} off={off} onClick={() => ClearKenwoodRIT().catch(setErrMsg)} />
|
||||
{/* Antenna only when the radio answered AN — a K3 without the internal
|
||||
ATU has one socket and no switch to offer. */}
|
||||
{view.antenna > 0 && (<>
|
||||
|
||||
Reference in New Issue
Block a user