fix: DUP button state consistent with QO-100 auto-duplex

The DUP toggle wrote FDisplayDuplex directly, bypassing the controller's
SetDuplex (which also sets KeepRXDuringTX live and fires rfDuplex). And
MainForm had no rfDuplex render case, so QO-100 auto-enabling duplex
(ActivateXvtr → SetDuplex) left the button unlit while FDisplayDuplex=True
— pressing DUP then turned it OFF when the user expected ON.

Single path now: ApplyDUP just calls SetDuplex; a new rfDuplex render case
styles the button and (when transmitting) switches the display source.
Both the button and QO-100 auto-enable go through it, so the button always
reflects state and KeepRXDuringTX stays in sync.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-19 22:42:41 +03:00
co-authored by Claude Opus 4.8
parent 17d0af4910
commit c849058d36
+26 -17
View File
@@ -1284,6 +1284,28 @@ begin
PbWaterfall.Invalidate;
if PbRuler <> nil then PbRuler.Invalidate;
end;
rfDuplex:
begin
// Единая точка рендера DUP — для кнопки И для авто-вкл в QO-100 (оба идут
// через SetDuplex → rfDuplex). Раньше QO-100 включал DUP, но кнопку не
// подсвечивал → визуал расходился с состоянием.
if BtnDUP <> nil then StyleButton(BtnDUP, FController.FDisplayDuplex);
// На передаче переключаем источник пикселей и сбрасываем буферы, чтобы
// старые TX/RX bin'ы не оставались на следующем кадре.
if FController.FTransmitting then
begin
if FController.FWDSPReady then
FController.FDSPEngine.SetDisplaySourceTX(not FController.FDisplayDuplex);
FSpecView.TXMode := FController.FTransmitting and not FController.FDisplayDuplex;
FSpecView.ResetSpectrumBuf;
FSpecView.ResetWfAvgBuf;
ApplySpecViewGridFromState;
FSpecView.DrawSpectrum;
FSpecView.DrawWaterfall;
PbSpectrum.Invalidate;
PbWaterfall.Invalidate;
end;
end;
rfWfAGC:
FSpecView.WfAGCEnabled := FController.FWfAGCEnabled;
rfWfNF:
@@ -3989,23 +4011,10 @@ end;
// ---------------------------------------------------------------------------
procedure TMainForm.ApplyDUP(Active: Boolean);
begin
FController.FDisplayDuplex := Active;
StyleButton(BtnDUP, FController.FDisplayDuplex);
// Если сейчас идёт передача — переключаем источник пикселей и сбрасываем
// буферы, чтобы старые TX/RX bin'ы не оставались на следующем кадре.
if FController.FTransmitting then
begin
if FController.FWDSPReady then
FController.FDSPEngine.SetDisplaySourceTX(not FController.FDisplayDuplex);
FSpecView.TXMode := FController.FTransmitting and not FController.FDisplayDuplex;
FSpecView.ResetSpectrumBuf;
FSpecView.ResetWfAvgBuf;
ApplySpecViewGridFromState;
FSpecView.DrawSpectrum;
FSpecView.DrawWaterfall;
PbSpectrum.Invalidate;
PbWaterfall.Invalidate;
end;
// Единый путь: контроллер ставит FDisplayDuplex + KeepRXDuringTX (живьём) и шлёт
// rfDuplex → там рендер кнопки/дисплея. Так тумблер и QO-100-авто согласованы
// (раньше кнопка писала FDisplayDuplex напрямую, минуя KeepRXDuringTX и rfDuplex).
FController.SetDuplex(Active);
end;
procedure TMainForm.BtnDUPClick(Sender: TObject);