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 <noreply@anthropic.com>
This commit is contained in:
Uladzimir Karpenka
2026-06-05 14:00:46 +03:00
co-authored by Claude Opus 4.8
parent 831e5c3a31
commit c249b46b17
2 changed files with 27 additions and 30 deletions
+16 -29
View File
@@ -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);
+11 -1
View File
@@ -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 местами и перестраиваем приёмник на новую частоту активного