diff --git a/MainForm.pas b/MainForm.pas index a844dc2..76690e0 100644 --- a/MainForm.pas +++ b/MainForm.pas @@ -1410,6 +1410,17 @@ begin if PbWaterfall <> nil then PbWaterfall.Invalidate; end; end; + rfActiveVfo: + begin + UpdateVfoDisplay; // дисплеи A/B + подсветка RX/TX-кнопок + FSpecView.InvalidateRulerCache; + SyncSpecViewFreq; + FSpecView.DrawSpectrum; + PbSpectrum.Invalidate; + FSpecView.DrawWaterfall; + PbWaterfall.Invalidate; + if PbRuler <> nil then PbRuler.Invalidate; + end; rfVfoB: begin FreqDispB.Frequency := Round(FController.FVfoB); @@ -4358,80 +4369,10 @@ end; // Перестройка на частоту выбранного VFO. CTUN не трогаем. // --------------------------------------------------------------------------- procedure TMainForm.ActivateVfo(Idx: Integer); -var - ActiveFreq: Int64; - NewBand: Integer; - Offset: Double; - HalfSpan: Double; - FreqVisible: Boolean; begin - FController.FActiveVfo := Idx; - - // Частота нового активного VFO - if FController.FActiveVfo = 0 then - ActiveFreq := Round(FController.FVfoA) - else - ActiveFreq := Round(FController.FVfoB); - - // Обновляем визуальный дисплей - UpdateVfoDisplay; - - if FController.FCTun then - begin - // CTUN включён: проверяем, видна ли новая частота на текущем спектре - HalfSpan := FController.FSpanHz / 2; - Offset := ActiveFreq - FController.FCenterFreq; - FreqVisible := (Offset > -HalfSpan) and (Offset < HalfSpan); - - if FreqVisible then - begin - // Частота видна в окне — просто меняем shift, DDC не трогаем - if FController.FWDSPReady then FController.FDSPEngine.SetShift(Offset); - // Сеть не трогаем — DDC (FController.FCenterFreq) остаётся прежним - end - else - begin - // Частота за пределами спектра — центрируем окно и сбрасываем CTUN - FController.FCTun := False; - StyleButton(BtnCTun, False); - FController.FBandCache[FController.FCurrentBand].CTun := False; - FController.FCenterFreq := ActiveFreq; - if FController.FWDSPReady then FController.FDSPEngine.SetShift(0.0); - 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; - end; - end - else - begin - // CTUN выключен: перестраиваем DDC на новую частоту - FController.FCenterFreq := ActiveFreq; - if FController.FWDSPReady then FController.FDSPEngine.SetShift(0.0); - 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; - end; - - // Переключаем кнопку диапазона по новой частоте - NewBand := FreqToBandIdx(ActiveFreq); - if (NewBand >= 0) and (NewBand <> FController.FCurrentBand) then - begin - StyleButton(BtnBand[FController.FCurrentBand], False); - FController.FCurrentBand := NewBand; - StyleButton(BtnBand[FController.FCurrentBand], True); - end; - - FSpecView.InvalidateRulerCache; - SyncSpecViewFreq; - FSpecView.DrawSpectrum; - PbSpectrum.Invalidate; - FSpecView.DrawWaterfall; - PbWaterfall.Invalidate; - if PbRuler <> nil then PbRuler.Invalidate; + // Движок (переключение RX-VFO, CTUN-логика, центр/сеть, диапазон) — в + // контроллере; рендер — OnControllerState(rfActiveVfo/rfBand/rfCTun). + FController.SetActiveVfo(Idx); end; procedure TMainForm.FreqDispAClick(Sender: TObject); diff --git a/RadioController.pas b/RadioController.pas index 81bbda7..d709084 100644 --- a/RadioController.pas +++ b/RadioController.pas @@ -610,7 +610,57 @@ begin end; procedure TRadioController.SetActiveVfo(Idx: Integer); -begin FActiveVfo := Idx; Changed(rfActiveVfo); { TODO wiring: ActivateVfo } end; +// Переключение активного (RX) VFO с перестройкой приёмника на его частоту. +// CTUN: если частота нового VFO видна в текущем окне — только меняем shift +// (DDC/сеть не трогаем); иначе CTUN сбрасывается и центрируемся на частоте. +// Рендер (дисплеи/спектр/band/CTUN-кнопка) — в UI через OnControllerState. +var + ActiveFreq: Double; + HalfSpan, Offset: Double; + FreqVisible: Boolean; + BandIdx: Integer; +begin + FActiveVfo := Idx; + ActiveFreq := ActiveVfoHz; + + if FCTun then + begin + HalfSpan := FSpanHz / 2; + Offset := ActiveFreq - FCenterFreq; + FreqVisible := (Offset > -HalfSpan) and (Offset < HalfSpan); + if FreqVisible then + begin + // Частота видна — просто сдвигаем демодулятор, DDC/сеть не трогаем. + if FWDSPReady and Assigned(FDSPEngine) then FDSPEngine.SetShift(Offset); + end + else + begin + // Частота за окном — сбрасываем CTUN и центрируемся на ней. + FCTun := False; + FBandCache[FCurrentBand].CTun := False; + FCenterFreq := ActiveFreq; + if FWDSPReady and Assigned(FDSPEngine) then FDSPEngine.SetShift(0.0); + PushNetworkState; + Changed(rfCTun); + end; + end + else + begin + FCenterFreq := ActiveFreq; + if FWDSPReady and Assigned(FDSPEngine) then FDSPEngine.SetShift(0.0); + PushNetworkState; + end; + + // Детект диапазона по новой частоте (без пересчёта drive — как исторически). + BandIdx := FreqToBandIdx(ActiveFreq); + if (BandIdx >= 0) and (BandIdx <> FCurrentBand) then + begin + FCurrentBand := BandIdx; + Changed(rfBand); + end; + + Changed(rfActiveVfo); +end; procedure TRadioController.TuneActiveBy(DeltaHz: Double); begin