mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-26 04:47:35 +00:00
feat(slices): независимый rate панадаптеров (селектор в шапке)
- Создание пана: rate наследуется от главного с клампом ≤768к (вне сетки → 384к); за сменой rate главного паны не следуют - Клик по «NNN kHz» в шапке пана N → меню полной сетки железа (PanRateAllowed = Caps.RatePresets ∩ кратные 48 кГц; захардкоженный PAN_DDC_RATES удалён) - WDSPEngine.SetPanRate: под FSliceLock пересбор аккумулятора/анализатора пана + переоткрытие слайс-каналов на новом rate (state сохраняется) - RadioController.SetPanDDCRate: движок → реконфиг DDC (SetPanDDC) → кламп слайсов к новой полосе; FPanADC[] хранится (база под 3.4) - Шапка: rate отдельным лейблом (у панов N кликабелен, акцент/рука) Смоук-тест без железа ALL PASS (тон: спектр+аудио слайса живы через 384→192→768). Проверено юзером на экране. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+80
-6
@@ -184,6 +184,9 @@ type
|
||||
FPanSplitMinTop: Integer;
|
||||
FPanSplitMaxTop: Integer;
|
||||
FPendingPanClose: Integer; // «×» шапки: PanId к закрытию в тике (0 = нет)
|
||||
// Меню rate пана («NNN kHz» в шапке панов N; создаётся лениво).
|
||||
FPanRateMenu: TPopupMenu;
|
||||
FPanRateMenuPanId: Integer;
|
||||
FSpecView: TSpectrumView;
|
||||
FWidebandView: TWidebandView;
|
||||
FUseOpenGLSpectrum: Boolean;
|
||||
@@ -570,6 +573,8 @@ type
|
||||
procedure DestroyAllExtraPans; // stop/выход
|
||||
procedure UpdatePanHeaders; // текст+видимость шапок
|
||||
procedure UpdateAddPanButton;
|
||||
procedure OnPanRateClick(Sender: TObject); // «NNN kHz» шапки пана N
|
||||
procedure PanRateMenuItemClick(Sender: TObject);
|
||||
procedure AddSliceAtFreqPan(P: TPanafallPanel; Hz: Double);
|
||||
procedure PanClickTune(P: TPanafallPanel; X, W: Integer); // клик по фону пана N
|
||||
procedure PanViewWindow(P: TPanafallPanel; out VC, VS: Double);
|
||||
@@ -2679,6 +2684,11 @@ begin
|
||||
begin
|
||||
FPans[i].HeaderPanel.Color := T.Panel;
|
||||
FPans[i].HeaderLabel.Font.Color := T.Text;
|
||||
// Rate-лейбл: кликабельный (паны N) подсвечиваем акцентом селектора.
|
||||
if FPans[i].RateClickable then
|
||||
FPans[i].HeaderRateLabel.Font.Color := T.BtnTextActive
|
||||
else
|
||||
FPans[i].HeaderRateLabel.Font.Color := T.Text;
|
||||
end;
|
||||
if i > 0 then
|
||||
begin
|
||||
@@ -5297,6 +5307,54 @@ begin
|
||||
FActiveSliceId := Id;
|
||||
end;
|
||||
|
||||
procedure TMainForm.OnPanRateClick(Sender: TObject);
|
||||
// Клик по «NNN kHz» в шапке пана N: меню с полной сеткой rate бэкенда
|
||||
// (фильтр PanRateAllowed — кратные 48 кГц). Текущий rate отмечен галкой.
|
||||
var
|
||||
P: TPanafallPanel;
|
||||
MI: TMenuItem;
|
||||
i, kHz: Integer;
|
||||
begin
|
||||
if not (Sender is TPanafallPanel) then Exit;
|
||||
P := TPanafallPanel(Sender);
|
||||
if (P.PanId < 1) or not FController.PanDDCActive(P.PanId) then Exit;
|
||||
if FPanRateMenu = nil then
|
||||
FPanRateMenu := TPopupMenu.Create(Self);
|
||||
FPanRateMenu.Items.Clear;
|
||||
for i := 0 to High(FController.BackendCaps.RatePresets) do
|
||||
begin
|
||||
kHz := FController.BackendCaps.RatePresets[i] div 1000;
|
||||
if not FController.PanRateAllowed(Word(kHz)) then Continue;
|
||||
MI := TMenuItem.Create(FPanRateMenu);
|
||||
MI.Caption := Format('%d kHz', [kHz]);
|
||||
MI.Tag := kHz;
|
||||
MI.Checked := kHz = FController.PanDDCRateKHz(P.PanId);
|
||||
MI.OnClick := PanRateMenuItemClick;
|
||||
FPanRateMenu.Items.Add(MI);
|
||||
end;
|
||||
if FPanRateMenu.Items.Count = 0 then Exit;
|
||||
FPanRateMenuPanId := P.PanId;
|
||||
FPanRateMenu.PopUp; // в позиции курсора
|
||||
end;
|
||||
|
||||
procedure TMainForm.PanRateMenuItemClick(Sender: TObject);
|
||||
var
|
||||
P: TPanafallPanel;
|
||||
PanId: Integer;
|
||||
begin
|
||||
PanId := FPanRateMenuPanId;
|
||||
FPanRateMenuPanId := 0;
|
||||
if (PanId < 1) or (PanId >= MAX_PANS) then Exit;
|
||||
P := FPans[PanId];
|
||||
if P = nil then Exit;
|
||||
if not FController.SetPanDDCRate(PanId, Word(TMenuItem(Sender).Tag)) then Exit;
|
||||
// Вьюха/шапка/флаги под новый span (слайсы могли клампнуться к краям).
|
||||
SyncPanViews;
|
||||
P.PushAllSliceFlagStates;
|
||||
P.LayoutFlags;
|
||||
MarkPanDirty(P);
|
||||
end;
|
||||
|
||||
procedure TMainForm.PanClickTune(P: TPanafallPanel; X, W: Integer);
|
||||
// Клик по фону доп. пана = перестроить его слайс на частоту клика (аналог
|
||||
// DoSpectrumClick главного: снап к 100 Гц). Цель — активный слайс, если он
|
||||
@@ -5347,11 +5405,17 @@ begin
|
||||
P.HeaderVisible := N > 1;
|
||||
if P.BtnClosePan <> nil then P.BtnClosePan.Visible := (N > 1) and (i > 0);
|
||||
if i = 0 then
|
||||
P.SetHeaderText(Format('PAN 0 · %.6f MHz · %d kHz',
|
||||
[FController.FCenterFreq / 1e6, FController.FSampleRate div 1000]))
|
||||
begin
|
||||
P.SetHeaderText(Format('PAN 0 · %.6f MHz ·',
|
||||
[FController.FCenterFreq / 1e6]));
|
||||
P.SetHeaderRate(Format('%d kHz', [FController.FSampleRate div 1000]));
|
||||
end
|
||||
else
|
||||
P.SetHeaderText(Format('PAN %d · %.6f MHz · %d kHz',
|
||||
[i, FController.PanDDCFreq(i) / 1e6, FController.PanDDCRateKHz(i)]));
|
||||
begin
|
||||
P.SetHeaderText(Format('PAN %d · %.6f MHz ·',
|
||||
[i, FController.PanDDCFreq(i) / 1e6]));
|
||||
P.SetHeaderRate(Format('%d kHz', [FController.PanDDCRateKHz(i)]));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
@@ -5370,6 +5434,7 @@ procedure TMainForm.OnAddPanClick(Sender: TObject);
|
||||
// ADC 0; в центре автоматически создаётся первый слайс.
|
||||
var
|
||||
PanId, i: Integer;
|
||||
RateKHz: Word;
|
||||
Freq: Double;
|
||||
P: TPanafallPanel;
|
||||
Split: TPanel;
|
||||
@@ -5380,8 +5445,15 @@ begin
|
||||
if FPans[i] = nil then begin PanId := i; Break; end;
|
||||
if PanId < 0 then Exit;
|
||||
|
||||
// Rate наследуется от главного пана с клампом сверху (768к — потолок доп.
|
||||
// пана по Ethernet/CPU; 48/96/192к наследуются как есть). Не из сетки
|
||||
// (напр. Pluto-подобные) — контроллер откатит на 384к. Дальше rate пана
|
||||
// независим: селектор «NNN kHz» в шапке, за сменой rate главного НЕ следует.
|
||||
RateKHz := FController.FSampleRate div 1000;
|
||||
if RateKHz > 768 then RateKHz := 768;
|
||||
|
||||
Freq := ActiveVfoFreq;
|
||||
if not FController.AddPanDDC(PanId, Freq, 384, 0) then Exit;
|
||||
if not FController.AddPanDDC(PanId, Freq, RateKHz, 0) then Exit;
|
||||
|
||||
P := TPanafallPanel.Create(nil, FUseOpenGLSpectrum);
|
||||
P.PanId := PanId;
|
||||
@@ -5392,6 +5464,8 @@ begin
|
||||
P.OnFlagsInvalidate := OnVfoOverlayInvalidate;
|
||||
P.OnPanClose := OnPanHeaderClose;
|
||||
P.OnSplitterMoved := RightPanelResize; // ratio обновлён → полный re-layout
|
||||
P.OnRateClick := OnPanRateClick; // «NNN kHz» в шапке → меню rate
|
||||
P.RateClickable := True;
|
||||
P.SpectrumMouseDown := PanNSpectrumMouseDown;
|
||||
P.SpectrumMouseMove := PanNSpectrumMouseMove;
|
||||
P.SpectrumMouseUp := PanNSpectrumMouseUp;
|
||||
@@ -5416,7 +5490,7 @@ begin
|
||||
P.View.WfFrameInterval := EffectiveWfInterval;
|
||||
P.View.PAMaxPower := FController.FPAMaxPower;
|
||||
P.View.CenterFreq := Freq;
|
||||
P.View.SpanHz := 384000;
|
||||
P.View.SpanHz := FController.PanDDCRateKHz(PanId) * 1000.0;
|
||||
// VFO/TX-маркеры главного на доп. пане не рисуем — уводим за пределы окна.
|
||||
P.View.VfoA := -1e15;
|
||||
P.View.VfoB := -1e15;
|
||||
|
||||
Reference in New Issue
Block a user