From c249b46b17a7bd73aa6674ef83cd5a7562dfcb90 Mon Sep 17 00:00:00 2001 From: Uladzimir Karpenka Date: Fri, 5 Jun 2026 14:00:46 +0300 Subject: [PATCH] Phase 3 (batch 17): move CTUN center scroll (SetCenter) into the controller SetCenter was a Phase-1 skeleton; filled it with the CTUN view-scroll logic: set FCenterFreq, shift the demodulator by (active VFO - center), push a full HP frame, and emit Changed(rfCenterFreq). The UI renders via OnControllerState (invalidate ruler cache + deferred spectrum redraw, since a drag emits many events). Both entry points now call FController.SetCenter: the desktop CTUN drag (DoSpectrumDrag) and the web center scroll (SyncWebCenter). Removes the duplicated inline shift/network logic from both. Side effect / latent fix: the web center scroll previously only called UpdateState without SendFullHP (the desktop path did both), so a web scroll did not push the new DDC center to the radio immediately. Routing it through PushNetworkState now sends the full HP frame like the desktop path. Co-Authored-By: Claude Opus 4.8 --- MainForm.pas | 45 ++++++++++++++++----------------------------- RadioController.pas | 12 +++++++++++- 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/MainForm.pas b/MainForm.pas index 9a35489..be212bf 100644 --- a/MainForm.pas +++ b/MainForm.pas @@ -1304,6 +1304,16 @@ begin PbWaterfall.Invalidate; if PbRuler <> nil then PbRuler.Invalidate; end; + rfCenterFreq: + begin + // CTUN-скролл центра (drag/web): ruler-метки сдвинулись → инвалидируем + // кэш; спектр откладываем (FSpectrumDirty) — drag шлёт много событий. + FSpecView.InvalidateRulerCache; + SyncSpecViewFreq; + FSpectrumDirty := True; + PbSpectrum.Invalidate; + if PbRuler <> nil then PbRuler.Invalidate; + end; rfVfoB: begin FreqDispB.Frequency := Round(FController.FVfoB); @@ -4728,24 +4738,9 @@ begin dPix := PixelX - FSpecDragX0; dFreq := dPix / PanelWidth * FController.FSpanHz; if FController.FCTun then - begin - // CTUN ON: drag двигает окно просмотра (FController.FCenterFreq/DDC) - // VFO остаётся, shift обновляется = VFO - новый FController.FCenterFreq - FController.FCenterFreq := FSpecDragFreq - dFreq; - if FController.FWDSPReady then - begin - if FController.FActiveVfo = 0 then - FController.FDSPEngine.SetShift(FController.FVfoA - FController.FCenterFreq) - else - FController.FDSPEngine.SetShift(FController.FVfoB - FController.FCenterFreq); - end; - if FController.FNetwork.Connected and FController.FNetwork.Running then - begin - FController.FNetwork.UpdateState(XvtrTranslate(FController.FCenterFreq), XvtrTranslate(ActiveTXFreqHz), FController.FDriveLevel, FController.FTransmitting, True, True); - FController.FNetwork.SendFullHP; - end; - FSpectrumDirty := True; - end + // CTUN ON: drag двигает окно просмотра (DDC-центр) без смены VFO; shift, + // сеть и рендер — в контроллере SetCenter / OnControllerState(rfCenterFreq). + FController.SetCenter(FSpecDragFreq - dFreq) else begin // CTUN OFF: drag двигает VFO, FController.FCenterFreq следует через Apply @@ -6118,17 +6113,9 @@ end; procedure TMainForm.SyncWebCenter; begin - // Сдвигаем DDC-центр без смены VFO (аналог CTUN-drag в десктопе) - FController.FCenterFreq := FWebSyncFreq; - if FController.FWDSPReady then - begin - if FController.FActiveVfo = 0 then FController.FDSPEngine.SetShift(FController.FVfoA - FController.FCenterFreq) - else FController.FDSPEngine.SetShift(FController.FVfoB - FController.FCenterFreq); - end; - if FController.FNetwork.Connected and FController.FNetwork.Running then - FController.FNetwork.UpdateState(XvtrTranslate(FController.FCenterFreq), XvtrTranslate(ActiveTXFreqHz), FController.FDriveLevel, FController.FTransmitting, True, True); - FSpecView.InvalidateRulerCache; - FSpectrumDirty := True; + // Сдвигаем DDC-центр без смены VFO (аналог CTUN-drag в десктопе). + // Движок (shift, сеть) + рендер (rfCenterFreq) — в контроллере SetCenter. + FController.SetCenter(FWebSyncFreq); end; procedure TMainForm.WebOnMOX(On_: Boolean); diff --git a/RadioController.pas b/RadioController.pas index 095fb90..3403e38 100644 --- a/RadioController.pas +++ b/RadioController.pas @@ -893,7 +893,17 @@ begin end; procedure TRadioController.SetCenter(Hz: Double); -begin FCenterFreq := Hz; Changed(rfCenterFreq); { TODO wiring } end; +// CTUN-скролл окна просмотра: двигаем DDC-центр БЕЗ смены VFO. Демодулятор +// сдвигаем = активный VFO − новый центр; полный HP-кадр в радио. Рендер +// (ruler/спектр) — в UI через OnControllerState(rfCenterFreq). +// Точки входа: десктопный CTUN-drag и web (SyncWebCenter). +begin + FCenterFreq := Hz; + if FWDSPReady and Assigned(FDSPEngine) then + FDSPEngine.SetShift(ActiveVfoHz - FCenterFreq); + PushNetworkState; + Changed(rfCenterFreq); +end; procedure TRadioController.VfoSwap; // Меняем VFO A/B местами и перестраиваем приёмник на новую частоту активного