mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 17:27:32 +00:00
feat(slices): выбор КВ-диапазона на панах N (Flex-style band-селектор)
Кликабельный бейдж диапазона («20m») в шапке пана N → popup-меню КВ-бандов. На выбор — по-флексовому: ретюн DDC на VfoA диапазона (из общего band-кэша, как пан 0), активный приёмник садится на VfoA с mode/filter/AGC + zoom/pan этого диапазона, прочие слайсы пана убираются (вне новой полосы). Только на настоящих КВ (не XVTR, не Pluto). - TPanafallPanel: FHeaderBandLabel + OnBandClick/BandClickable/SetHeaderBand; каскад left-лейблов шапки вынесен в LayoutHeaderLabels (band/rate/adc без дыр при скрытии). - MainForm: OnPanBandClick/PanBandMenuItemClick/ApplyPanBand + PanBandSelectorVisible (гейт КВ); band-лейбл в UpdatePanHeaders (по FreqToBandIdx частоты DDC), тема в ApplyPanHeaderTheme. Ограничение: per-slice AGC-Top в движке нет — подтягиваются mode/filter/AGC-mode/zoom/pan, но не индивидуальный AGC-Top диапазона. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+120
-1
@@ -202,6 +202,8 @@ type
|
||||
// Меню rate пана («NNN kHz» в шапке панов N; создаётся лениво).
|
||||
FPanRateMenu: TPopupMenu;
|
||||
FPanRateMenuPanId: Integer;
|
||||
FPanBandMenu: TPopupMenu; // селектор диапазона пана N (3.6, КВ)
|
||||
FPanBandMenuPanId: Integer;
|
||||
// Pop-out (3.5): пан N в отдельном OS-окне. nil = пан в стеке.
|
||||
FPanFloatForm: array[1..MAX_PANS-1] of TForm;
|
||||
FSpecView: TSpectrumView;
|
||||
@@ -604,6 +606,10 @@ type
|
||||
procedure UpdateAddPanButton;
|
||||
procedure OnPanRateClick(Sender: TObject); // «NNN kHz» шапки пана N
|
||||
procedure PanRateMenuItemClick(Sender: TObject);
|
||||
procedure OnPanBandClick(Sender: TObject); // «20m» шапки пана N (3.6)
|
||||
procedure PanBandMenuItemClick(Sender: TObject);
|
||||
procedure ApplyPanBand(P: TPanafallPanel; BandIdx: Integer); // Flex-style смена банда пана
|
||||
function PanBandSelectorVisible: Boolean; // КВ (не XVTR, не Pluto)
|
||||
procedure OnPanADCClick(Sender: TObject); // бейдж «RX1/RX2» (3.4)
|
||||
// Per-pan дисплей (3.6): «◑» → поповер палитры/gamma/уровней.
|
||||
procedure OnPanDisplayClick(Sender: TObject);
|
||||
@@ -5638,6 +5644,95 @@ begin
|
||||
MarkPanDirty(P);
|
||||
end;
|
||||
|
||||
function TMainForm.PanBandSelectorVisible: Boolean;
|
||||
// Селектор диапазона пана — только на «настоящих КВ»: не в XVTR и не Pluto
|
||||
// (у Pluto/трансвертера band-стек другой, сценарий не актуален).
|
||||
begin
|
||||
Result := (FController.FCurrentXvtr < 0) and not FController.IsPluto;
|
||||
end;
|
||||
|
||||
procedure TMainForm.OnPanBandClick(Sender: TObject);
|
||||
// Клик по бейджу диапазона в шапке пана N: меню КВ-диапазонов, текущий (по
|
||||
// частоте DDC пана) отмечен галкой.
|
||||
var
|
||||
P: TPanafallPanel;
|
||||
MI: TMenuItem;
|
||||
i, CurBand: 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 not PanBandSelectorVisible then Exit;
|
||||
CurBand := FreqToBandIdx(FController.PanDDCFreq(P.PanId), False);
|
||||
if FPanBandMenu = nil then
|
||||
FPanBandMenu := TPopupMenu.Create(Self);
|
||||
FPanBandMenu.Items.Clear;
|
||||
for i := 0 to CFG_BAND_COUNT - 1 do
|
||||
begin
|
||||
if BandName(i, False) = '' then Continue; // 6m-дубль/пустые слоты
|
||||
MI := TMenuItem.Create(FPanBandMenu);
|
||||
MI.Caption := BandName(i, False);
|
||||
MI.Tag := i;
|
||||
MI.Checked := i = CurBand;
|
||||
MI.OnClick := PanBandMenuItemClick;
|
||||
FPanBandMenu.Items.Add(MI);
|
||||
end;
|
||||
if FPanBandMenu.Items.Count = 0 then Exit;
|
||||
FPanBandMenuPanId := P.PanId;
|
||||
FPanBandMenu.PopUp;
|
||||
end;
|
||||
|
||||
procedure TMainForm.PanBandMenuItemClick(Sender: TObject);
|
||||
var PanId: Integer;
|
||||
begin
|
||||
PanId := FPanBandMenuPanId;
|
||||
FPanBandMenuPanId := 0;
|
||||
if (PanId < 1) or (PanId >= MAX_PANS) then Exit;
|
||||
if FPans[PanId] = nil then Exit;
|
||||
ApplyPanBand(FPans[PanId], TMenuItem(Sender).Tag);
|
||||
end;
|
||||
|
||||
procedure TMainForm.ApplyPanBand(P: TPanafallPanel; BandIdx: Integer);
|
||||
// Flex-style смена диапазона пана N: ретюн DDC на VfoA диапазона (из общего
|
||||
// band-кэша, как пан 0), активный приёмник садится на VfoA с mode/filter/AGC
|
||||
// (+zoom/pan) диапазона, прочие слайсы пана убираются (они вне новой полосы).
|
||||
var
|
||||
B: TBandSettings;
|
||||
Freq: Double;
|
||||
Lo, Hi, Id: Integer;
|
||||
begin
|
||||
if (P = nil) or (P.PanId < 1) then Exit;
|
||||
if not PanBandSelectorVisible then Exit;
|
||||
if (BandIdx < 0) or (BandIdx >= CFG_BAND_COUNT) then Exit;
|
||||
B := FController.FBandCache[BandIdx];
|
||||
Freq := B.VfoA;
|
||||
// Кэш диапазона мог нести чужую частоту (дефолты/битый конфиг) — тогда центр
|
||||
// диапазона по плану.
|
||||
if FreqToBandIdx(Freq, False) <> BandIdx then
|
||||
Freq := BandDefaultFreq(BandIdx, False);
|
||||
|
||||
// Слайсы вне новой полосы — снести до ретюна DDC.
|
||||
P.DestroyAllSliceFlags;
|
||||
FActiveSliceId := 0;
|
||||
// Ретюн DDC пана + зум/пан диапазона.
|
||||
FController.SetPanDDCFreq(P.PanId, Freq);
|
||||
FController.SetPanZoomPan(P.PanId,
|
||||
EnsureRange(B.ZoomFactor, 0.0, 1.0), EnsureRange(B.PanSlider, 0.0, 1.0));
|
||||
// Один приёмник на VfoA с настройками диапазона.
|
||||
TRadioController.FilterEdgesFor(B.Mode, B.FilterBW, Lo, Hi);
|
||||
Id := FController.AddSlice(Freq, B.Mode, Lo, Hi,
|
||||
TRadioController.AGCModeFromUI(B.AGCMode), 0.7, -1, '', P.PanId);
|
||||
if Id >= 0 then
|
||||
begin
|
||||
P.CreateSliceFlag(Id);
|
||||
FActiveSliceId := Id;
|
||||
end;
|
||||
// Синк вьюхи/зум-бара/флагов/шапки под новый центр.
|
||||
P.PushAllSliceFlagStates;
|
||||
RefreshPanZoom(P);
|
||||
UpdatePanHeaders;
|
||||
end;
|
||||
|
||||
procedure TMainForm.OnPanADCClick(Sender: TObject);
|
||||
// Бейдж «RX1/RX2»: тумблер ADC-источника пана (двух-АЦПшные платы, 3.4).
|
||||
var
|
||||
@@ -5934,6 +6029,14 @@ begin
|
||||
P.HeaderRateLabel.Font.Color := T.BtnTextActive
|
||||
else
|
||||
P.HeaderRateLabel.Font.Color := T.Text;
|
||||
// Band-лейбл (3.6): кликабельный — акцент селектора.
|
||||
if P.HeaderBandLabel <> nil then
|
||||
begin
|
||||
if P.BandClickable then
|
||||
P.HeaderBandLabel.Font.Color := T.BtnTextActive
|
||||
else
|
||||
P.HeaderBandLabel.Font.Color := T.Text;
|
||||
end;
|
||||
// ADC-бейдж кликабелен на 2-АЦПшных платах — тоже акцент.
|
||||
if P.ADCClickable then
|
||||
P.HeaderADCLabel.Font.Color := T.BtnTextActive
|
||||
@@ -5945,7 +6048,7 @@ procedure TMainForm.UpdatePanHeaders;
|
||||
// Текст/видимость шапок: у одного пана шапки нет, у стека — у всех;
|
||||
// у плавающего (pop-out) пана шапка всегда (там его rate/ADC/×).
|
||||
var
|
||||
i, N, NADC: Integer;
|
||||
i, N, NADC, bi: Integer;
|
||||
P: TPanafallPanel;
|
||||
begin
|
||||
N := PanCount;
|
||||
@@ -5972,6 +6075,21 @@ begin
|
||||
[i, FController.PanDDCFreq(i) / 1e6]));
|
||||
P.SetHeaderRate(Format('%d kHz', [FController.PanDDCRateKHz(i)]));
|
||||
end;
|
||||
// Бейдж диапазона (3.6): только паны N на «настоящих КВ»; клик = меню.
|
||||
if (i > 0) and PanBandSelectorVisible then
|
||||
begin
|
||||
bi := FreqToBandIdx(FController.PanDDCFreq(i), False);
|
||||
if (bi >= 0) and (BandName(bi, False) <> '') then
|
||||
P.SetHeaderBand(BandName(bi, False))
|
||||
else
|
||||
P.SetHeaderBand('—');
|
||||
P.BandClickable := True;
|
||||
end
|
||||
else
|
||||
begin
|
||||
P.SetHeaderBand('');
|
||||
P.BandClickable := False;
|
||||
end;
|
||||
// Бейдж АЦП: только на двух-АЦПшных платах; клик = тумблер.
|
||||
if NADC > 1 then
|
||||
begin
|
||||
@@ -6027,6 +6145,7 @@ begin
|
||||
P.OnADCClick := OnPanADCClick; // «RX1/RX2» тумблер АЦП (3.4)
|
||||
P.OnPanPopOut := OnPanPopOutClick; // «⧉» в отдельное окно (3.5)
|
||||
P.OnDisplayClick := OnPanDisplayClick; // «◑» дисплей-поповер (3.6)
|
||||
P.OnBandClick := OnPanBandClick; // «20m» селектор диапазона (3.6, КВ)
|
||||
P.SpectrumMouseDown := PanNSpectrumMouseDown;
|
||||
P.SpectrumMouseMove := PanNSpectrumMouseMove;
|
||||
P.SpectrumMouseUp := PanNSpectrumMouseUp;
|
||||
|
||||
Reference in New Issue
Block a user