mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +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:
+62
-2
@@ -95,6 +95,9 @@ type
|
||||
FStackHeight: Integer; // высота региона (0 = до низа родителя)
|
||||
FHeaderPanel: TPanel; // шапка пана (видна при панах >= 2)
|
||||
FHeaderLabel: TLabel;
|
||||
FHeaderRateLabel: TLabel; // «NNN kHz»; у панов N>0 кликабелен (селектор rate)
|
||||
FRateClickable: Boolean;
|
||||
FOnRateClick: TNotifyEvent;
|
||||
FBtnClosePan: TFlatButton; // «×» в шапке (только паны N>0)
|
||||
FBtnAddPan: TFlatButton; // «⊞» в ряду пан/зума (только пан 0)
|
||||
FHeaderVisible: Boolean;
|
||||
@@ -105,6 +108,8 @@ type
|
||||
|
||||
procedure BtnClosePanClick(Sender: TObject);
|
||||
procedure BtnAddPanClick(Sender: TObject);
|
||||
procedure HeaderRateClick(Sender: TObject);
|
||||
procedure SetRateClickable(AValue: Boolean);
|
||||
procedure PositionHeaderChildren(RW, H: Integer);
|
||||
// Видимое частотное окно ЭТОГО пана: пан 0 — окно главного (зум/пан),
|
||||
// паны N — центр их DDC ± rate/2 (пан-зум — этап 3.3+).
|
||||
@@ -169,11 +174,17 @@ type
|
||||
property PanId: Integer read FPanId write FPanId;
|
||||
property StackTop: Integer read FStackTop write FStackTop;
|
||||
property StackHeight: Integer read FStackHeight write FStackHeight;
|
||||
// Шапка пана: текст ставит хозяин (частота/rate), «×» → OnPanClose.
|
||||
// Шапка пана: текст ставит хозяин (частота), rate — отдельным лейблом
|
||||
// (SetHeaderRate); у панов N>0 хозяин делает его кликабельным (селектор
|
||||
// rate, RateClickable + OnRateClick). «×» → OnPanClose.
|
||||
property HeaderVisible: Boolean read FHeaderVisible write FHeaderVisible;
|
||||
procedure SetHeaderText(const S: string);
|
||||
procedure SetHeaderRate(const S: string);
|
||||
property RateClickable: Boolean read FRateClickable write SetRateClickable;
|
||||
property OnRateClick: TNotifyEvent read FOnRateClick write FOnRateClick;
|
||||
property HeaderPanel: TPanel read FHeaderPanel;
|
||||
property HeaderLabel: TLabel read FHeaderLabel;
|
||||
property HeaderRateLabel: TLabel read FHeaderRateLabel;
|
||||
property BtnClosePan: TFlatButton read FBtnClosePan;
|
||||
property BtnAddPan: TFlatButton read FBtnAddPan;
|
||||
// Ряд пан/зума: у панов N>0 скрыт (их зум — этап 3.3+).
|
||||
@@ -210,6 +221,7 @@ type
|
||||
// Флаг A виден: панель хозяина скрыта (MainFlagPinned) ИЛИ есть слайсы B+.
|
||||
procedure UpdateMainFlagVisibility;
|
||||
procedure PushSliceFlagState(SliceId: Integer);
|
||||
procedure PushAllSliceFlagStates; // все флаги панели (после смены rate и т.п.)
|
||||
procedure PushMainFlagExtState;
|
||||
procedure PushMainFlagAudioDevices;
|
||||
// Тик: S-метр/частота главного флага + позиции + троттленный S-метр слайсов.
|
||||
@@ -362,6 +374,12 @@ begin
|
||||
FHeaderLabel.Parent := FHeaderPanel;
|
||||
FHeaderLabel.AutoSize := True;
|
||||
FHeaderLabel.Left := 8;
|
||||
// Rate — отдельным лейблом за основным текстом: у панов N>0 он кликабелен
|
||||
// (селектор rate DDC), у пана 0 — просто текст.
|
||||
FHeaderRateLabel := TLabel.Create(Self);
|
||||
FHeaderRateLabel.Parent := FHeaderPanel;
|
||||
FHeaderRateLabel.AutoSize := True;
|
||||
FHeaderRateLabel.OnClick := HeaderRateClick;
|
||||
FBtnClosePan := MakeFlatBtn(FHeaderPanel, '×', 0, 0, 10, 10, BtnClosePanClick);
|
||||
FBtnClosePan.Visible := False; // хозяин включает у панов N>0
|
||||
end;
|
||||
@@ -378,7 +396,37 @@ end;
|
||||
|
||||
procedure TPanafallPanel.SetHeaderText(const S: string);
|
||||
begin
|
||||
if FHeaderLabel <> nil then FHeaderLabel.Caption := S;
|
||||
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;
|
||||
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;
|
||||
end;
|
||||
|
||||
procedure TPanafallPanel.SetRateClickable(AValue: Boolean);
|
||||
begin
|
||||
FRateClickable := AValue;
|
||||
if FHeaderRateLabel <> nil then
|
||||
begin
|
||||
if AValue then
|
||||
FHeaderRateLabel.Cursor := crHandPoint
|
||||
else
|
||||
FHeaderRateLabel.Cursor := crArrow;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPanafallPanel.HeaderRateClick(Sender: TObject);
|
||||
begin
|
||||
if FRateClickable and Assigned(FOnRateClick) then FOnRateClick(Self);
|
||||
end;
|
||||
|
||||
procedure TPanafallPanel.ViewWindow(out VC, VS: Double);
|
||||
@@ -399,6 +447,11 @@ var BtnS: 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 FBtnClosePan <> nil then
|
||||
begin
|
||||
BtnS := H - 4;
|
||||
@@ -1025,6 +1078,13 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPanafallPanel.PushAllSliceFlagStates;
|
||||
var i: Integer;
|
||||
begin
|
||||
for i := 0 to High(FSliceFlags) do
|
||||
if FSliceFlags[i] <> nil then PushSliceFlagState(FSliceFlags[i].SliceId);
|
||||
end;
|
||||
|
||||
procedure TPanafallPanel.PushMainFlagExtState;
|
||||
begin
|
||||
if not (Assigned(FMainFlag) and FMainFlag.Visible) or (FController = nil) then Exit;
|
||||
|
||||
Reference in New Issue
Block a user