mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-26 22:57:34 +00:00
feat(overlay): redesign VfoOverlay in SmartSDR slice-flag style
Полный редизайн накладки поверх спектра: шапка (слайс-бейдж A/B, ширина фильтра, кликабельный SPLIT, индикатор TX), метр-ряд (индикаторы NR/NB/ANF/ SNB + сигнал-бар), крупная частота + S, нижний бар с fly-out пикерами. - Fly-out движок MODE/DSP/AUD (раскрываются под баром, карточка растёт): MODE — сетка режимов 4×2 + фильтры; DSP — NR/NB/SNB/ANF + AGC; AUD — выбор аудио-устройства вывода (задел под слайсы). - Слайдер громкости (click+drag) + mute; SPLIT-toggle; live TX-индикатор. - Все контролы подключены к RadioController (SetVolume/ToggleMute/SetSplit/ EnumOutputDevices→ApplyAudioDevice); wire в MainForm + HandleMouseUp, чтобы клик по накладке не уходил в спектр. - FormatFreq на Int64 (double накапливал ошибку в десятки Гц на ~10 ГГц QO-100). - S-метр ниже по высоте + плавный градиент по уровню dBm: тёмно-зелёный→ зелёный→жёлтый→красный (красный к ~S9+18). - Кэш+dirty рендер сохранён (CPU-паритет со старой накладкой), GL-путь через DrawOverlayBitmap. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+70
-2
@@ -519,6 +519,12 @@ type
|
||||
procedure OnModeFilterSelect(Mode: Integer; FilterBW: Integer);
|
||||
procedure OnVfoOverlayDSPChange(NRMode, NBMode: Integer; SNBOn, ANFOn: Boolean);
|
||||
procedure OnVfoOverlayAGCChange(AGCMode: Integer);
|
||||
procedure OnVfoOverlayVolume(Vol: Integer);
|
||||
procedure OnVfoOverlayMute(Sender: TObject);
|
||||
procedure OnVfoOverlayAudioDevice(DevIndex: Integer; const DevName: string);
|
||||
procedure OnVfoOverlaySplit(Sender: TObject);
|
||||
procedure PushVfoOverlayExtState;
|
||||
procedure PushVfoOverlayAudioDevices;
|
||||
procedure OnVfoOverlayInvalidate(Sender: TObject);
|
||||
procedure PbSpectrumDblClick(Sender: TObject);
|
||||
procedure TrkDriveChange(Sender: TObject);
|
||||
@@ -956,6 +962,10 @@ begin
|
||||
FVfoOverlay.OnSelect := OnModeFilterSelect;
|
||||
FVfoOverlay.OnDSPChange := OnVfoOverlayDSPChange;
|
||||
FVfoOverlay.OnAGCChange := OnVfoOverlayAGCChange;
|
||||
FVfoOverlay.OnVolume := OnVfoOverlayVolume;
|
||||
FVfoOverlay.OnMute := OnVfoOverlayMute;
|
||||
FVfoOverlay.OnAudioDevice := OnVfoOverlayAudioDevice;
|
||||
FVfoOverlay.OnSplit := OnVfoOverlaySplit;
|
||||
FVfoOverlay.OnInvalidate := OnVfoOverlayInvalidate;
|
||||
FVfoOverlay.Visible := False;
|
||||
FPanelHidden := False;
|
||||
@@ -3251,6 +3261,7 @@ begin
|
||||
begin
|
||||
FVfoOverlay.UpdateSMeter(FController.FLastSMeter);
|
||||
FVfoOverlay.UpdateVfo(FController.FVfoA);
|
||||
PushVfoOverlayExtState;
|
||||
PositionVfoOverlay;
|
||||
end;
|
||||
// Панорама и водопад теперь рисуются независимо по факту новых кадров.
|
||||
@@ -4501,6 +4512,12 @@ end;
|
||||
procedure TMainForm.PbSpectrumMouseUp(Sender: TObject; Button: TMouseButton;
|
||||
Shift: TShiftState; X, Y: Integer);
|
||||
begin
|
||||
if Assigned(FVfoOverlay) and FVfoOverlay.HandleMouseUp(X, Y) then
|
||||
begin
|
||||
FSpecDrag := False;
|
||||
PbSpectrum.Cursor := crDefault;
|
||||
Exit; // клик/drag по накладке — не пускаем в спектр
|
||||
end;
|
||||
if Button = mbLeft then
|
||||
begin
|
||||
if (Abs(X - FSpecDragX0) < 4) then
|
||||
@@ -4989,11 +5006,13 @@ begin
|
||||
begin
|
||||
FLeftPanelW := PanelLeft.Width; // сохраняем реальную ширину (учитывает DPI на Win32)
|
||||
PanelLeft.Width := 0;
|
||||
FVfoOverlay.Width := 260;
|
||||
FVfoOverlay.Height := 136; // OVL_H_NORM — расширяется сам при открытии AGC-пикера
|
||||
FVfoOverlay.Width := OVL_W;
|
||||
FVfoOverlay.Height := FVfoOverlay.BaseHeight; // растёт сам при открытии fly-out
|
||||
FVfoOverlay.SetState(FController.FMode, FController.FFilterBW, FController.FVfoA, FController.FLastSMeter);
|
||||
FVfoOverlay.SetDSPState(FController.FNRMode, FController.FNBMode, FController.FSNB, FController.FANF, FController.FAGCMode);
|
||||
FVfoOverlay.Visible := True;
|
||||
PushVfoOverlayExtState;
|
||||
PushVfoOverlayAudioDevices;
|
||||
PositionVfoOverlay;
|
||||
end
|
||||
else
|
||||
@@ -5098,6 +5117,55 @@ begin
|
||||
FController.SetAGCMode(AGCMode);
|
||||
end;
|
||||
|
||||
procedure TMainForm.OnVfoOverlayVolume(Vol: Integer);
|
||||
begin
|
||||
FController.SetVolume(Vol);
|
||||
end;
|
||||
|
||||
procedure TMainForm.OnVfoOverlayMute(Sender: TObject);
|
||||
begin
|
||||
FController.ToggleMute;
|
||||
end;
|
||||
|
||||
procedure TMainForm.OnVfoOverlaySplit(Sender: TObject);
|
||||
begin
|
||||
FController.SetSplit(not FController.FSplitTxB);
|
||||
PushVfoOverlayExtState;
|
||||
end;
|
||||
|
||||
procedure TMainForm.OnVfoOverlayAudioDevice(DevIndex: Integer; const DevName: string);
|
||||
begin
|
||||
ApplyAudioDevice(DevIndex, DevName);
|
||||
PushVfoOverlayAudioDevices; // обновить подсветку текущего устройства
|
||||
end;
|
||||
|
||||
procedure TMainForm.PushVfoOverlayExtState;
|
||||
begin
|
||||
if not (Assigned(FVfoOverlay) and FVfoOverlay.Visible) then Exit;
|
||||
FVfoOverlay.SetExtState(FController.FVolume, FController.FMuted,
|
||||
FController.FSplitTxB, FController.FTransmitting);
|
||||
end;
|
||||
|
||||
procedure TMainForm.PushVfoOverlayAudioDevices;
|
||||
var
|
||||
Names: TStringList;
|
||||
Indices: array[0..63] of Integer;
|
||||
Cnt, I: Integer;
|
||||
Idx: array of Integer;
|
||||
begin
|
||||
if not (Assigned(FVfoOverlay) and Assigned(FController.FAudioOut)) then Exit;
|
||||
Names := TStringList.Create;
|
||||
try
|
||||
Cnt := 0;
|
||||
FController.FAudioOut.EnumOutputDevices(Names, Indices, Cnt);
|
||||
SetLength(Idx, Cnt);
|
||||
for I := 0 to Cnt - 1 do Idx[I] := Indices[I];
|
||||
FVfoOverlay.SetAudioDevices(Names, Idx, FController.FAudioOutDevName);
|
||||
finally
|
||||
Names.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.OnVfoOverlayInvalidate(Sender: TObject);
|
||||
begin
|
||||
FSpectrumDirty := True;
|
||||
|
||||
+641
-381
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user