feat(pans): сетка FM-каналов и шаг тюнинга на доп. панадаптерах

Доп. паны не имеют своего FMode — режим берётся со слайсов пана:
PanHasFMSlice(PanId) = есть слайс в FM/DMR/FMRAW. По нему SyncPanZoomUI
выставляет View.FMGridStepHz = FM_STEP_HZ[FFMStepIdx], как SyncSpecViewFreq
делает для главного пана (сеттер сам гасит кэши спектра и линейки).

Тюнинг слайса привязан к той же сетке:
  • колесо над слайсом/доп. паном — было зашито 12500 и только DMR/FMRAW,
    теперь FM_STEP_HZ[FFMStepIdx] во всех трёх канальных режимах (гейт FFMStepOn);
  • PanClickTune — там была та же зашитая 12500, теперь шаг режима целевого
    слайса, как в DoSpectrumClick главного пана.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 19:22:30 +03:00
co-authored by Claude Opus 4.8
parent c857aa9d4b
commit 02288292ff
2 changed files with 48 additions and 9 deletions
+32 -9
View File
@@ -5983,12 +5983,24 @@ end;
procedure TMainForm.SyncPanZoomUI(P: TPanafallPanel);
// Вьюха и зум-бар пана ← контроллер (после смены зума/центра/rate пана).
var VC, VS: Double;
var VC, VS, StepHz: Double;
begin
if (P = nil) or (P.PanId = 0) then Exit;
FController.GetPanViewWindow(P.PanId, VC, VS);
P.View.CenterFreq := VC;
P.View.SpanHz := VS;
// Сетка каналов по шагу FM — как на главном пане, но по режиму слайсов
// ЭТОГО пана (у доп. панов нет своего FMode).
if FController.PanHasFMSlice(P.PanId) then
StepHz := FM_STEP_HZ[FController.FFMStepIdx]
else
StepHz := 0;
if Abs(P.View.FMGridStepHz - StepHz) > 0.5 then
begin
P.View.FMGridStepHz := StepHz; // сеттер сам сбросит кэши спектра/линейки
MarkPanDirty(P);
if P.PbRuler <> nil then P.PbRuler.Invalidate;
end;
P.ZoomBar.SetFreq(FController.PanDDCFreq(P.PanId),
FController.PanDDCRateKHz(P.PanId) * 1000.0);
P.ZoomBar.SetState(FController.PanZoomFactor(P.PanId),
@@ -6422,7 +6434,7 @@ procedure TMainForm.PanClickTune(P: TPanafallPanel; X, W: Integer);
var
VC, VS, LoHz, HiHz: Double;
Hz, StepHz: Int64;
Id: Integer;
Id, ModeHere: Integer;
S: TCtrlSlice;
begin
PanViewWindow(P, VC, VS);
@@ -6432,11 +6444,18 @@ begin
Id := FActiveSliceId
else
Id := P.FirstSliceId;
StepHz := 100;
if ((Id <> 0) and FController.GetSlice(Id, S) and
(S.Mode in [MODE_DMR, MODE_FMRAW])) or
((Id = 0) and (FController.FMode in [MODE_DMR, MODE_FMRAW])) then
StepHz := 12500;
// Канальные режимы: клик садится на ту же сетку, что нарисована на пане.
if Id <> 0 then
begin
if FController.GetSlice(Id, S) then ModeHere := S.Mode
else ModeHere := FController.FMode;
end
else
ModeHere := FController.FMode;
if (ModeHere in [MODE_FM, MODE_DMR, MODE_FMRAW]) and FController.FFMStepOn then
StepHz := FM_STEP_HZ[FController.FFMStepIdx]
else
StepHz := 100;
Hz := Round(VC + (X / W - 0.5) * VS);
Hz := ((Hz + StepHz div 2) div StepHz) * StepHz;
FController.CapturedSpan(LoHz, HiHz, P.PanId);
@@ -8003,8 +8022,12 @@ begin
end;
if (SliceId <> 0) and FController.GetSlice(SliceId, Sl) then
begin
if (Sl.Mode in [MODE_DMR, MODE_FMRAW]) and
not ((ssCtrl in Shift) or (ssShift in Shift)) then Step := 12500
// Канальные режимы: шаг = выбранный шаг сетки (тот же, что рисуется на
// пане), как на главном панадаптере. Ctrl/Shift — обычные мелкие шаги.
if (Sl.Mode in [MODE_FM, MODE_DMR, MODE_FMRAW]) and
FController.FFMStepOn and
not ((ssCtrl in Shift) or (ssShift in Shift)) then
Step := FM_STEP_HZ[FController.FFMStepIdx]
else if (ssCtrl in Shift) and (ssShift in Shift) then Step := 1000000
else if ssCtrl in Shift then Step := 1000
else if ssShift in Shift then Step := 10