From de1f4b772d5bbb9d30a008fb14d5732b17a745b5 Mon Sep 17 00:00:00 2001 From: Uladzimir Karpenka Date: Tue, 9 Jun 2026 09:52:11 +0300 Subject: [PATCH] Phase 5: make RestoreBand a full controller command (self-retune) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit controller.RestoreBand now does the final receiver retune on the active VFO (SetVfoA/SetVfoB) itself — channel orchestration rides the OnAfterTune hook — and emits rfBandRestore so the UI resets the waterfall-average buffer (desktop-only, fires on explicit band change, not per-tune). MainForm.RestoreBand collapses to a thin delegate. RestoreBand is now headless-complete: desktop band buttons, channels, connect- restore, and (soon) web/CAT can call it directly. Preserves the active-VFO retune (active B no longer centers on A) from the batch-15 fix. Co-Authored-By: Claude Opus 4.8 --- MainForm.pas | 18 +++++------------- RadioController.pas | 15 ++++++++++----- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/MainForm.pas b/MainForm.pas index c926ab0..32b469b 100644 --- a/MainForm.pas +++ b/MainForm.pas @@ -714,20 +714,9 @@ end; procedure TMainForm.RestoreBand(BandIdx: Integer); begin - if (BandIdx < 0) or (BandIdx >= CFG_BAND_COUNT) then Exit; - // Сброс порогов водопада — только при явной смене диапазона (не на каждом - // пересечении границы при тюнинге, поэтому здесь, а не в rfBand-рендере). - FSpecView.ResetWfAvgBuf; - // Состояние + DSP + события рендера — в контроллере. + // Тонкий делегат: состояние+DSP+финальная перестройка+рендер — в команде + // контроллера; сброс Wf-avg буфера — в OnControllerState(rfBandRestore). FController.RestoreBand(BandIdx); - // Финальная перестройка приёмника на АКТИВНЫЙ VFO. Если активен B — нельзя - // центрироваться на VFO A (иначе движок слушает A, а маркер/мышь — на B). - // VFO A идёт через ApplyVfoA (канальная оркестрация: auto-CTCSS, pre-channel - // drive); VFO B — через SetVfoB (перестройка + рендер rfVfoB). - if FController.FActiveVfo = 0 then - ApplyVfoA(Round(FController.FVfoA)) - else - FController.SetVfoB(Round(FController.FVfoB)); end; procedure TMainForm.SaveAllAndExit; @@ -1232,6 +1221,9 @@ begin for i := 0 to CFG_XVTR_COUNT - 1 do if BtnXvtrBand[i] <> nil then StyleButton(BtnXvtrBand[i], i = FController.FCurrentXvtr); + rfBandRestore: + // Явная смена диапазона: сброс порогов водопада (не на каждом тюне). + FSpecView.ResetWfAvgBuf; rfMute: begin StyleButton(BtnMute, FController.FMuted); diff --git a/RadioController.pas b/RadioController.pas index bd1ef92..591b7ab 100644 --- a/RadioController.pas +++ b/RadioController.pas @@ -59,7 +59,7 @@ type rfMode, rfFilter, rfFilterBW, rfAGCMode, rfAGCTop, rfVolume, rfMute, rfDrive, rfAtten, - rfBand, rfXvtr, + rfBand, rfXvtr, rfBandRestore, // rfBandRestore: явная смена диапазона (сброс Wf-avg в UI) rfCenterFreq, rfSpan, rfSampleRate, rfCTun, rfDuplex, rfRunning, rfConnected, rfTransmitting, rfTuning, @@ -1136,12 +1136,13 @@ begin end; procedure TRadioController.RestoreBand(BandIdx: Integer); -// Загружает состояние диапазона из кэша, применяет к DSP и шлёт события рендера. -// Финальную перестройку VFO A (с канальной оркестрацией) делает вызывающий -// UI-путь через ApplyVfoA(FVfoA); здесь FVfoA лишь выставляется. +// Загружает состояние диапазона из кэша, применяет к DSP, делает финальную +// перестройку приёмника на активный VFO и шлёт события рендера. Полная команда — +// зовётся напрямую desktop/web/channel/connect-restore. var B: TBandSettings; begin if (BandIdx < 0) or (BandIdx >= CFG_BAND_COUNT) then Exit; + Changed(rfBandRestore); // явная смена диапазона → UI сбросит Wf-avg буфер B := FBandCache[BandIdx]; FCurrentBand := BandIdx; @@ -1154,7 +1155,11 @@ begin FDriveLevel := CalcDriveByte; Changed(rfVfoB); - // rfVfoA НЕ шлём: финальную перестройку делает ApplyVfoA в UI-обёртке. + // Финальная перестройка приёмника на АКТИВНЫЙ VFO. VFO A — через SetVfoA + // (хук OnAfterTune несёт канальную оркестрацию); VFO B — через SetVfoB. + // Иначе смена диапазона при активном B центрировала бы приёмник на A. + if FActiveVfo = 0 then SetVfoA(FVfoA) + else SetVfoB(FVfoB); end; function TRadioController.ActiveVfoHz: Double;