mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +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:
+72
-19
@@ -98,6 +98,9 @@ type
|
||||
FHeaderRateLabel: TLabel; // «NNN kHz»; у панов N>0 кликабелен (селектор rate)
|
||||
FRateClickable: Boolean;
|
||||
FOnRateClick: TNotifyEvent;
|
||||
FHeaderBandLabel: TLabel; // «20m»; кликабелен на КВ (селектор диапазона пана, 3.6)
|
||||
FBandClickable: Boolean;
|
||||
FOnBandClick: TNotifyEvent;
|
||||
FHeaderADCLabel: TLabel; // «RX1»/«RX2»; кликабелен при 2 АЦП (тумблер, 3.4)
|
||||
FADCClickable: Boolean;
|
||||
FOnADCClick: TNotifyEvent;
|
||||
@@ -122,6 +125,9 @@ type
|
||||
procedure BtnAddPanClick(Sender: TObject);
|
||||
procedure HeaderRateClick(Sender: TObject);
|
||||
procedure SetRateClickable(AValue: Boolean);
|
||||
procedure HeaderBandClick(Sender: TObject);
|
||||
procedure SetBandClickable(AValue: Boolean);
|
||||
procedure LayoutHeaderLabels; // каскад left-лейблов (band/rate/adc)
|
||||
procedure HeaderADCClick(Sender: TObject);
|
||||
procedure SetADCClickable(AValue: Boolean);
|
||||
procedure BtnPopPanClick(Sender: TObject);
|
||||
@@ -210,6 +216,12 @@ type
|
||||
procedure SetHeaderRate(const S: string);
|
||||
property RateClickable: Boolean read FRateClickable write SetRateClickable;
|
||||
property OnRateClick: TNotifyEvent read FOnRateClick write FOnRateClick;
|
||||
// Бейдж диапазона «20m» (3.6, только КВ-паны N): пустой текст = скрыт,
|
||||
// клик = меню КВ-диапазонов (хозяин).
|
||||
procedure SetHeaderBand(const S: string);
|
||||
property BandClickable: Boolean read FBandClickable write SetBandClickable;
|
||||
property OnBandClick: TNotifyEvent read FOnBandClick write FOnBandClick;
|
||||
property HeaderBandLabel: TLabel read FHeaderBandLabel;
|
||||
// Бейдж ADC-источника «RX1»/«RX2» (3.4): показывается при NumADCs>1,
|
||||
// клик = тумблер АЦП (хозяин).
|
||||
procedure SetHeaderADC(const S: string);
|
||||
@@ -439,6 +451,12 @@ begin
|
||||
FHeaderRateLabel.Parent := FHeaderPanel;
|
||||
FHeaderRateLabel.AutoSize := True;
|
||||
FHeaderRateLabel.OnClick := HeaderRateClick;
|
||||
// Band-бейдж «20m» (3.6): между текстом пана и rate; пустой = скрыт.
|
||||
FHeaderBandLabel := TLabel.Create(Self);
|
||||
FHeaderBandLabel.Parent := FHeaderPanel;
|
||||
FHeaderBandLabel.AutoSize := True;
|
||||
FHeaderBandLabel.Visible := False;
|
||||
FHeaderBandLabel.OnClick := HeaderBandClick;
|
||||
// ADC-бейдж «RX1»/«RX2» (3.4): пустой текст = скрыт (одноАЦПшные платы).
|
||||
FHeaderADCLabel := TLabel.Create(Self);
|
||||
FHeaderADCLabel.Parent := FHeaderPanel;
|
||||
@@ -483,24 +501,63 @@ begin
|
||||
if Assigned(FOnAddPan) then FOnAddPan(Self);
|
||||
end;
|
||||
|
||||
procedure TPanafallPanel.LayoutHeaderLabels;
|
||||
// Единый каскад left-лейблов шапки: [текст пана] [band?] [rate] [adc?].
|
||||
// Скрытые (Visible=False) лейблы пропускаются, чтобы не оставлять дыр.
|
||||
var X: Integer;
|
||||
begin
|
||||
if FHeaderLabel = nil then Exit;
|
||||
X := FHeaderLabel.Left + FHeaderLabel.Width + 6;
|
||||
if (FHeaderBandLabel <> nil) and FHeaderBandLabel.Visible then
|
||||
begin
|
||||
FHeaderBandLabel.Left := X;
|
||||
Inc(X, FHeaderBandLabel.Width + 10);
|
||||
end;
|
||||
if FHeaderRateLabel <> nil then
|
||||
begin
|
||||
FHeaderRateLabel.Left := X;
|
||||
Inc(X, FHeaderRateLabel.Width + 10);
|
||||
end;
|
||||
if FHeaderADCLabel <> nil then
|
||||
FHeaderADCLabel.Left := X;
|
||||
end;
|
||||
|
||||
procedure TPanafallPanel.SetHeaderText(const S: string);
|
||||
begin
|
||||
if FHeaderLabel = nil then Exit;
|
||||
if FHeaderLabel.Caption = S then Exit;
|
||||
FHeaderLabel.Caption := S;
|
||||
// Rate-лейбл прижат к основному тексту — сдвинуть за новой шириной.
|
||||
if FHeaderRateLabel <> nil then
|
||||
FHeaderRateLabel.Left := FHeaderLabel.Left + FHeaderLabel.Width + 6;
|
||||
LayoutHeaderLabels; // ширина текста изменилась — сдвинуть хвост
|
||||
end;
|
||||
|
||||
procedure TPanafallPanel.SetHeaderRate(const S: string);
|
||||
begin
|
||||
if FHeaderRateLabel = nil then Exit;
|
||||
if FHeaderRateLabel.Caption <> S then FHeaderRateLabel.Caption := S;
|
||||
if FHeaderLabel <> nil then
|
||||
FHeaderRateLabel.Left := FHeaderLabel.Left + FHeaderLabel.Width + 6;
|
||||
if FHeaderADCLabel <> nil then
|
||||
FHeaderADCLabel.Left := FHeaderRateLabel.Left + FHeaderRateLabel.Width + 10;
|
||||
LayoutHeaderLabels;
|
||||
end;
|
||||
|
||||
procedure TPanafallPanel.SetHeaderBand(const S: string);
|
||||
begin
|
||||
if FHeaderBandLabel = nil then Exit;
|
||||
if FHeaderBandLabel.Caption <> S then FHeaderBandLabel.Caption := S;
|
||||
FHeaderBandLabel.Visible := S <> '';
|
||||
LayoutHeaderLabels;
|
||||
end;
|
||||
|
||||
procedure TPanafallPanel.SetBandClickable(AValue: Boolean);
|
||||
begin
|
||||
FBandClickable := AValue;
|
||||
if FHeaderBandLabel <> nil then
|
||||
begin
|
||||
if AValue then FHeaderBandLabel.Cursor := crHandPoint
|
||||
else FHeaderBandLabel.Cursor := crArrow;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPanafallPanel.HeaderBandClick(Sender: TObject);
|
||||
begin
|
||||
if FBandClickable and Assigned(FOnBandClick) then FOnBandClick(Self);
|
||||
end;
|
||||
|
||||
procedure TPanafallPanel.SetRateClickable(AValue: Boolean);
|
||||
@@ -525,8 +582,7 @@ begin
|
||||
if FHeaderADCLabel = nil then Exit;
|
||||
if FHeaderADCLabel.Caption <> S then FHeaderADCLabel.Caption := S;
|
||||
FHeaderADCLabel.Visible := S <> '';
|
||||
if FHeaderRateLabel <> nil then
|
||||
FHeaderADCLabel.Left := FHeaderRateLabel.Left + FHeaderRateLabel.Width + 10;
|
||||
LayoutHeaderLabels;
|
||||
end;
|
||||
|
||||
procedure TPanafallPanel.SetADCClickable(AValue: Boolean);
|
||||
@@ -569,16 +625,13 @@ var BtnS, X: Integer;
|
||||
begin
|
||||
if FHeaderLabel <> nil then
|
||||
FHeaderLabel.Top := (H - FHeaderLabel.Height) div 2;
|
||||
if (FHeaderRateLabel <> nil) and (FHeaderLabel <> nil) then
|
||||
begin
|
||||
FHeaderRateLabel.Top := (H - FHeaderRateLabel.Height) div 2;
|
||||
FHeaderRateLabel.Left := FHeaderLabel.Left + FHeaderLabel.Width + 6;
|
||||
end;
|
||||
if (FHeaderADCLabel <> nil) and (FHeaderRateLabel <> nil) then
|
||||
begin
|
||||
FHeaderADCLabel.Top := (H - FHeaderADCLabel.Height) div 2;
|
||||
FHeaderADCLabel.Left := FHeaderRateLabel.Left + FHeaderRateLabel.Width + 10;
|
||||
end;
|
||||
if FHeaderBandLabel <> nil then
|
||||
FHeaderBandLabel.Top := (H - FHeaderBandLabel.Height) div 2;
|
||||
if FHeaderRateLabel <> nil then
|
||||
FHeaderRateLabel.Top := (H - FHeaderRateLabel.Height) div 2;
|
||||
if FHeaderADCLabel <> nil then
|
||||
FHeaderADCLabel.Top := (H - FHeaderADCLabel.Height) div 2;
|
||||
LayoutHeaderLabels; // единый каскад left-позиций
|
||||
// Кнопки шапки прижаты вправо, справа налево: [×] [⧉] [◑]. Позиция каждой
|
||||
// зависит от видимости соседей (у пана 0 нет × и ⧉ — ◑ уезжает к краю).
|
||||
BtnS := H - 4;
|
||||
|
||||
Reference in New Issue
Block a user