mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 19:45:09 +00:00
Replace PanelSpanButtons with SampleRateOverlay overlay
- Add SampleRateOverlay.pas: TCustomControl overlay (top-left of spectrum) with hide-panel button and 6 span buttons (48k–1536k), same hit-test pattern as VfoOverlay - Consolidate toolbar: move PanelTopVfoGroup and PanelSMeterRight into PanelToolbar (height 72) instead of floating on the form - Remove PanelSpanButtons (alTop spacer) that caused the ~1cm black strip at the top of the spectrum - Add separator line inside PanelToolbar anchored to its bottom edge, with 16px left/right margins - Fix left panel blocks starting Y offset (was 38, now 0) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+75
-212
@@ -22,7 +22,8 @@ unit MainForm;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, StrUtils, FreqDisplay, DeviceForm, VfoOverlay, FlatButton, FlatSlider, FlatDropDown, AppTheme, Forms, Controls, Graphics, Dialogs,
|
||||
Classes, SysUtils, StrUtils, FreqDisplay, DeviceForm, VfoOverlay, SampleRateOverlay,
|
||||
FlatButton, FlatSlider, FlatDropDown, AppTheme, Forms, Controls, Graphics, Dialogs,
|
||||
StdCtrls, ExtCtrls, ComCtrls, Buttons, Menus, Math, Types,
|
||||
LCLIntf, LCLType, GraphType,
|
||||
HPSDRProtocol, HPSDRNetwork,
|
||||
@@ -179,8 +180,9 @@ type
|
||||
FDeviceCount: Integer;
|
||||
FDeviceDialog: TDeviceDialog;
|
||||
FPendingIP: string; // IP устройства для подключения
|
||||
FVfoOverlay: TVfoOverlay; // накладка SmartSDR-стиль на спектре
|
||||
FPanelHidden: Boolean; // True = левая панель скрыта
|
||||
FVfoOverlay: TVfoOverlay; // накладка SmartSDR-стиль на спектре
|
||||
FSampleRateOverlay: TSampleRateOverlay; // оверлей span/hide слева вверху спектра
|
||||
FPanelHidden: Boolean; // True = левая панель скрыта
|
||||
FPendingBoardType: Integer; // BoardType устройства для подключения
|
||||
|
||||
// ---- DSP + Audio ----
|
||||
@@ -341,12 +343,11 @@ type
|
||||
FSpectrumTimer: TTimer;
|
||||
FAfterShowTimer:TTimer; // однократный таймер для пост-инициализации
|
||||
|
||||
// ---- Toolbar ----
|
||||
// ---- Top panel (toolbar + VFO group + S-meter) ----
|
||||
PanelToolbar: TPanel;
|
||||
BtnDiscover: TFlatButton;
|
||||
BtnStartStop: TFlatButton; // START / STOP (connect+run в одном)
|
||||
BtnSettings: TFlatButton; // открыть диалог настроек
|
||||
PanelSep: TPanel; // 1px разделитель под тулбаром
|
||||
BtnStartStop: TFlatButton;
|
||||
BtnSettings: TFlatButton;
|
||||
|
||||
// ---- Left panel ----
|
||||
PanelLeft: TPanel;
|
||||
@@ -418,16 +419,7 @@ type
|
||||
BtnTUN: TFlatButton;
|
||||
|
||||
// ---- Right panel ----
|
||||
PanelRight: TPanel;
|
||||
PanelSpanButtons: TPanel;
|
||||
LblSpan: TLabel;
|
||||
BtnSpan48k: TFlatButton;
|
||||
BtnSpan96k: TFlatButton;
|
||||
BtnSpan192k: TFlatButton;
|
||||
BtnSpan384k: TFlatButton;
|
||||
BtnSpan768k: TFlatButton;
|
||||
BtnSpan1536k: TFlatButton;
|
||||
BtnHidePanel: TFlatButton; // скрыть/показать левую панель
|
||||
PanelRight: TPanel;
|
||||
PbSpectrum: TPaintBox;
|
||||
PbRuler: TPaintBox; // полоса частотных меток между спектром и водопадом
|
||||
PanelSplitter: TPanel; // перетаскиваемый разделитель спектр/водопад
|
||||
@@ -445,7 +437,9 @@ type
|
||||
procedure SetStatusText(Index: Integer; const Text: string);
|
||||
procedure SetRadioOfflineStatus(const ConnText: string; ClearDevice: Boolean = False);
|
||||
procedure ApplyStatusTheme(const T: TAppTheme);
|
||||
procedure PositionSpanOverlayButtons;
|
||||
procedure PositionSampleRateOverlay;
|
||||
procedure OnSampleRateSelect(SampleRate: Integer);
|
||||
procedure OnSampleRateHidePanel;
|
||||
procedure UpdateVfoDisplay;
|
||||
function FormatFreq(Hz: Double): string;
|
||||
procedure LayoutTopVfoBlock;
|
||||
@@ -551,7 +545,6 @@ type
|
||||
procedure BtnNBClick(Sender: TObject);
|
||||
procedure BtnSNBClick(Sender: TObject);
|
||||
procedure BtnANFClick(Sender: TObject);
|
||||
procedure BtnSpanClick(Sender: TObject);
|
||||
// Веб-интерфейс: callbacks от TWebServer
|
||||
procedure WebOnFreq(Hz: Double);
|
||||
procedure WebOnMode(Mode: Integer);
|
||||
@@ -660,7 +653,6 @@ type
|
||||
procedure ActivateXvtrBand(Idx: Integer);
|
||||
procedure DeactivateXvtr;
|
||||
// -------------------------------------------------------------------------
|
||||
procedure BtnHidePanelClick(Sender: TObject);
|
||||
procedure BtnSettingsClick(Sender: TObject);
|
||||
procedure PositionVfoOverlay;
|
||||
procedure OnModeFilterSelect(Mode: Integer; FilterBW: Integer);
|
||||
@@ -1127,14 +1119,9 @@ begin
|
||||
|
||||
// --- Sample Rate / Span ---
|
||||
// SampleRate — глобальный, не per-band. Не восстанавливаем из диапазона.
|
||||
// Обновляем только FSpanHz для отображения (берём текущий FSampleRate)
|
||||
FSpanHz := FSampleRate;
|
||||
StyleSpanButton(BtnSpan48k, FSampleRate = 48000);
|
||||
StyleSpanButton(BtnSpan96k, FSampleRate = 96000);
|
||||
StyleSpanButton(BtnSpan192k, FSampleRate = 192000);
|
||||
StyleSpanButton(BtnSpan384k, FSampleRate = 384000);
|
||||
StyleSpanButton(BtnSpan768k, FSampleRate = 768000);
|
||||
StyleSpanButton(BtnSpan1536k, FSampleRate = 1536000);
|
||||
if Assigned(FSampleRateOverlay) then
|
||||
FSampleRateOverlay.SetCurrentRate(FSampleRate);
|
||||
|
||||
// --- VFO A: центрируем на новой частоте, сбрасываем shift ---
|
||||
FCenterFreq := B.VfoA; // DDC = центр диапазона
|
||||
@@ -1375,12 +1362,6 @@ begin
|
||||
FCurrentXvtr := -1;
|
||||
|
||||
BuildUI;
|
||||
StyleSpanButton(BtnSpan48k, FSampleRate = 48000);
|
||||
StyleSpanButton(BtnSpan96k, FSampleRate = 96000);
|
||||
StyleSpanButton(BtnSpan192k, FSampleRate = 192000);
|
||||
StyleSpanButton(BtnSpan384k, FSampleRate = 384000);
|
||||
StyleSpanButton(BtnSpan768k, FSampleRate = 768000);
|
||||
StyleSpanButton(BtnSpan1536k, FSampleRate = 1536000);
|
||||
ResizeSMeter;
|
||||
ApplyDarkTheme;
|
||||
UpdateVfoDisplay;
|
||||
@@ -1501,6 +1482,7 @@ const
|
||||
var
|
||||
i, X, Y, W: Integer;
|
||||
B: TFlatButton;
|
||||
SepLine: TPanel;
|
||||
|
||||
function MakeBtn(Parent: TWinControl; const Cap: string;
|
||||
ALeft, ATop, AW, AH: Integer; Handler: TNotifyEvent): TFlatButton;
|
||||
@@ -1535,7 +1517,7 @@ begin
|
||||
PanelToolbar := TPanel.Create(Self);
|
||||
PanelToolbar.Parent := Self;
|
||||
PanelToolbar.Align := alTop;
|
||||
PanelToolbar.Height := 36;
|
||||
PanelToolbar.Height := 72;
|
||||
PanelToolbar.BevelOuter := bvNone;
|
||||
PanelToolbar.Color := CLR_PANEL;
|
||||
|
||||
@@ -1557,7 +1539,13 @@ begin
|
||||
BtnStartStop.ClrBorder := TColor($00304830);
|
||||
BtnStartStop.ClrText := TColor($0090C090);
|
||||
|
||||
// ---- Separator line ----
|
||||
// Линия-разделитель внутри PanelToolbar, прижата к его нижнему краю
|
||||
SepLine := TPanel.Create(Self);
|
||||
SepLine.Parent := PanelToolbar;
|
||||
SepLine.BevelOuter := bvNone;
|
||||
SepLine.Color := TColor($00606060);
|
||||
SepLine.SetBounds(16, PanelToolbar.Height - 10, PanelToolbar.Width - 32, 2);
|
||||
SepLine.Anchors := [akLeft, akRight, akBottom];
|
||||
|
||||
// ---- Status bar ----
|
||||
StatusPanel := TMainStatusBar.Create(Self);
|
||||
@@ -1570,11 +1558,11 @@ begin
|
||||
PanelLeft.Width := LEFT_W;
|
||||
PanelLeft.BevelOuter := bvNone;
|
||||
|
||||
Y := 38; // gap below separator: separator at y=66, content starts at y=74
|
||||
Y := 0;
|
||||
|
||||
// Compact top VFO group
|
||||
PanelTopVfoGroup := TPanel.Create(Self);
|
||||
PanelTopVfoGroup.Parent := Self;
|
||||
PanelTopVfoGroup.Parent := PanelToolbar;
|
||||
PanelTopVfoGroup.SetBounds(0, 0, TOP_VFO_W * 2 + 64, 60);
|
||||
PanelTopVfoGroup.BevelOuter := bvNone;
|
||||
PanelTopVfoGroup.Color := TColor($00181818);
|
||||
@@ -1940,59 +1928,15 @@ begin
|
||||
PanelRight.BevelOuter := bvNone;
|
||||
PanelRight.OnResize := RightPanelResize;
|
||||
|
||||
PanelSpanButtons := TPanel.Create(Self);
|
||||
PanelSpanButtons.Parent := PanelRight;
|
||||
PanelSpanButtons.Align := alTop;
|
||||
PanelSpanButtons.Height := 38;
|
||||
PanelSpanButtons.BevelOuter := bvNone;
|
||||
FSampleRateOverlay := TSampleRateOverlay.Create(Self);
|
||||
FSampleRateOverlay.Parent := PanelRight;
|
||||
FSampleRateOverlay.OnSpanSelect := OnSampleRateSelect;
|
||||
FSampleRateOverlay.OnHidePanel := OnSampleRateHidePanel;
|
||||
FSampleRateOverlay.SetCurrentRate(FSampleRate);
|
||||
|
||||
LblSpan := TLabel.Create(Self);
|
||||
LblSpan.Parent := PanelSpanButtons; LblSpan.Left := 4; LblSpan.Top := 8;
|
||||
LblSpan.Caption := 'SPAN:'; LblSpan.Font.Color := CLR_TEXTDIM;
|
||||
LblSpan.Font.Name := 'Courier New'; LblSpan.Font.Size := 7;
|
||||
|
||||
BtnSpan48k := MakeBtn(PanelSpanButtons, '48k', 50, 3, 46, BTN_SM, BtnSpanClick);
|
||||
BtnSpan96k := MakeBtn(PanelSpanButtons, '96k', 99, 3, 46, BTN_SM, BtnSpanClick);
|
||||
BtnSpan192k := MakeBtn(PanelSpanButtons, '192k', 148, 3, 52, BTN_SM, BtnSpanClick);
|
||||
BtnSpan384k := MakeBtn(PanelSpanButtons, '384k', 203, 3, 52, BTN_SM, BtnSpanClick);
|
||||
BtnSpan768k := MakeBtn(PanelSpanButtons, '768k', 258, 3, 52, BTN_SM, BtnSpanClick);
|
||||
BtnSpan1536k := MakeBtn(PanelSpanButtons, '1536k', 313, 3, 58, BTN_SM, BtnSpanClick);
|
||||
BtnSpan48k.Tag := 48000;
|
||||
BtnSpan96k.Tag := 96000;
|
||||
BtnSpan192k.Tag := 192000;
|
||||
BtnSpan384k.Tag := 384000;
|
||||
BtnSpan768k.Tag := 768000;
|
||||
BtnSpan1536k.Tag := 1536000;
|
||||
StyleSpanButton(BtnSpan48k, False);
|
||||
StyleSpanButton(BtnSpan96k, False);
|
||||
StyleSpanButton(BtnSpan192k, True);
|
||||
StyleSpanButton(BtnSpan384k, False);
|
||||
StyleSpanButton(BtnSpan768k, False);
|
||||
StyleSpanButton(BtnSpan1536k, False);
|
||||
|
||||
BtnHidePanel := MakeBtn(PanelRight, '◀', 0, 0, 28, 28, BtnHidePanelClick);
|
||||
BtnHidePanel.Font.Size := 10;
|
||||
BtnHidePanel.ClrNorm := TColor($00543F18);
|
||||
BtnHidePanel.ClrHot := TColor($00624B1D);
|
||||
BtnHidePanel.ClrActive := TColor($00624B1D);
|
||||
BtnHidePanel.ClrBorder := TColor($00685624);
|
||||
BtnHidePanel.ClrText := TColor($00D8E6EE);
|
||||
BtnHidePanel.ClrTextAct := TColor($00F0FAFF);
|
||||
BtnHidePanel.BringToFront;
|
||||
|
||||
// Разделитель: на уровне формы, под всеми верхними элементами
|
||||
PanelSep := TPanel.Create(Self);
|
||||
PanelSep.Parent := Self;
|
||||
PanelSep.Align := alNone;
|
||||
PanelSep.BevelOuter := bvNone;
|
||||
PanelSep.ParentColor := False;
|
||||
PanelSep.Color := TColor($00606060);
|
||||
PanelSep.SetBounds(16, PanelToolbar.Height + 30, ClientWidth - 32, 2);
|
||||
|
||||
// Большой S-метр — на главной форме поверх двух панелей
|
||||
// S-метр: Parent=Self, перекрывает Toolbar+SpanButtons вертикально
|
||||
// S-метр — внутри PanelToolbar, справа
|
||||
PanelSMeterRight := TPanel.Create(Self);
|
||||
PanelSMeterRight.Parent := Self;
|
||||
PanelSMeterRight.Parent := PanelToolbar;
|
||||
PanelSMeterRight.BevelOuter := bvNone;
|
||||
PanelSMeterRight.Color := CLR_PANEL;
|
||||
PbSMeterRight := TPaintBox.Create(Self);
|
||||
@@ -2033,16 +1977,6 @@ begin
|
||||
PbWaterfall.OnMouseMove := PbWaterfallMouseMove;
|
||||
PbWaterfall.OnMouseUp := PbWaterfallMouseUp;
|
||||
|
||||
// SPAN кнопки как оверлей на спектре (в стиле web)
|
||||
BtnSpan48k.Parent := PanelRight;
|
||||
BtnSpan96k.Parent := PanelRight;
|
||||
BtnSpan192k.Parent := PanelRight;
|
||||
BtnSpan384k.Parent := PanelRight;
|
||||
BtnSpan768k.Parent := PanelRight;
|
||||
BtnSpan1536k.Parent := PanelRight;
|
||||
LblSpan.Visible := False;
|
||||
PositionSpanOverlayButtons;
|
||||
|
||||
// Initial layout
|
||||
ResizeSpectrumPanels;
|
||||
end;
|
||||
@@ -2089,7 +2023,7 @@ begin
|
||||
P := PanelRight.ScreenToClient(PanelSplitter.ClientToScreen(Point(X, Y)));
|
||||
DeltaY := P.Y - FSplitterDragY0;
|
||||
|
||||
TopOff := PanelSpanButtons.Height;
|
||||
TopOff := 0;
|
||||
AvailH := PanelRight.ClientHeight - TopOff - RULER_H - SPLITTER_H;
|
||||
if AvailH <= 0 then Exit;
|
||||
|
||||
@@ -2127,7 +2061,7 @@ begin
|
||||
P := PanelRight.ScreenToClient(PanelSplitter.ClientToScreen(Point(X, Y)));
|
||||
DeltaY := P.Y - FSplitterDragY0;
|
||||
|
||||
TopOff := PanelSpanButtons.Height;
|
||||
TopOff := 0;
|
||||
AvailH := PanelRight.ClientHeight - TopOff - RULER_H - SPLITTER_H;
|
||||
if AvailH <= 0 then Exit;
|
||||
|
||||
@@ -2173,7 +2107,7 @@ var
|
||||
TopVfoAW, TopVfoBW, NeedFreqAW, NeedFreqBW, FreqTextW, GroupW: Integer;
|
||||
XferX, XferY: Integer;
|
||||
begin
|
||||
if (PanelToolbar = nil) or (PanelSpanButtons = nil) or (PanelTopVfoGroup = nil) or
|
||||
if (PanelToolbar = nil) or (PanelTopVfoGroup = nil) or
|
||||
(PanelTopVfoA = nil) or (PanelTopVfoB = nil) then Exit;
|
||||
|
||||
Canvas.Font.Name := FreqDispB.FontName;
|
||||
@@ -2217,16 +2151,14 @@ begin
|
||||
DynGap := XFER_SIDE_GAP + ExtraPerSide;
|
||||
GroupW := TopVfoAW + DynGap + XFER_PANEL_W + DynGap + TopVfoBW;
|
||||
|
||||
BlockH := PanelToolbar.Height + 30 - (MARGIN * 2); // 30 = span row content, not full PanelSpanButtons
|
||||
BlockH := PanelToolbar.Height - (MARGIN * 2) - 8;
|
||||
if BlockH < 56 then BlockH := 56;
|
||||
|
||||
// Центрируем группу в доступном пространстве
|
||||
GroupLeft := SafeLeft + (AvailW - GroupW) div 2;
|
||||
GroupTop := TOP_OFFSET;
|
||||
|
||||
// Ось выравнивания: центр S-метра на форме (SMTop=3, SMBot=63) → y=33
|
||||
// Относительно PanelTopVfoGroup (GroupTop=2): CenterY = 33 - 2 = 31
|
||||
CenterY := (PanelToolbar.Height + 30) div 2 - GroupTop;
|
||||
CenterY := PanelToolbar.Height div 2 - GroupTop;
|
||||
|
||||
PanelTopVfoGroup.SetBounds(GroupLeft, GroupTop, GroupW, BlockH);
|
||||
PanelTopVfoGroup.Visible := True;
|
||||
@@ -2264,15 +2196,11 @@ begin
|
||||
FreqDispB.SetBounds(FreqDispB.Left, FreqTop,
|
||||
FreqTextW + VFO_FREQ_LEFT_PAD + VFO_FREQ_RIGHT_PAD, TOP_VFO_FREQ_H);
|
||||
|
||||
if PanelSep <> nil then
|
||||
PanelSep.SetBounds(16, PanelToolbar.Height + 30, ClientWidth - 32, 2);
|
||||
|
||||
PanelTopVfoGroup.BringToFront;
|
||||
end;
|
||||
|
||||
procedure TMainForm.ResizeSMeter;
|
||||
// PanelSMeterRight на главной форме (Parent=Self).
|
||||
// По Y: от самого верха формы до низа PanelSpanButtons (Toolbar+Span = 66px).
|
||||
// По Y: от самого верха формы до низа тулбара.
|
||||
var
|
||||
FW: Integer;
|
||||
RightW: Integer; // ширина PanelRight
|
||||
@@ -2281,8 +2209,7 @@ var
|
||||
SMTop: Integer;
|
||||
SMBot: Integer;
|
||||
begin
|
||||
if (PanelSMeterRight = nil) or (PanelToolbar = nil) or
|
||||
(PanelSpanButtons = nil) or (PanelLeft = nil) then Exit;
|
||||
if (PanelSMeterRight = nil) or (PanelToolbar = nil) or (PanelLeft = nil) then Exit;
|
||||
|
||||
LayoutTopVfoBlock;
|
||||
|
||||
@@ -2294,15 +2221,13 @@ begin
|
||||
// Ширина S-метра = 32% от PanelRight
|
||||
SMW := Round(RightW * SMETER_WIDTH_RATIO);
|
||||
|
||||
// X: прижат к правому краю формы
|
||||
// X: прижат к правому краю PanelToolbar
|
||||
SMLeft := FW - SMW - SMETER_MARGIN;
|
||||
|
||||
// Y: от верха формы+margin до низа PanelSpanButtons-margin
|
||||
SMTop := SMETER_MARGIN;
|
||||
SMBot := PanelToolbar.Height + 30 - SMETER_MARGIN; // 30 = span row content, ends before separator
|
||||
SMBot := PanelToolbar.Height - SMETER_MARGIN - 9;
|
||||
|
||||
PanelSMeterRight.SetBounds(SMLeft, SMTop, SMW, SMBot - SMTop);
|
||||
PanelSMeterRight.BringToFront;
|
||||
end;
|
||||
|
||||
procedure TMainForm.ResizeSpectrumPanels;
|
||||
@@ -2320,7 +2245,7 @@ begin
|
||||
if Assigned(FSpecView) then SyncSpecViewFreq;
|
||||
RW := PanelRight.ClientWidth;
|
||||
RH := PanelRight.ClientHeight;
|
||||
TopOff := PanelSpanButtons.Height;
|
||||
TopOff := 0;
|
||||
// S-метр позиционируется отдельно в ResizeSMeter
|
||||
ResizeSMeter;
|
||||
|
||||
@@ -2334,7 +2259,7 @@ begin
|
||||
FSpectrumWidth := RW;
|
||||
FSpectrumHeight := 0;
|
||||
FWaterfallHeight := 0;
|
||||
PositionSpanOverlayButtons;
|
||||
PositionSampleRateOverlay;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
@@ -2351,7 +2276,7 @@ begin
|
||||
PbRuler.Visible := True;
|
||||
PanelSplitter.Visible := False;
|
||||
PbWaterfall.Visible := False;
|
||||
PositionSpanOverlayButtons;
|
||||
PositionSampleRateOverlay;
|
||||
FSpectrumWidth := RW;
|
||||
FSpectrumHeight := SH;
|
||||
FWaterfallHeight := 0;
|
||||
@@ -2380,7 +2305,7 @@ begin
|
||||
PbWaterfall.Visible := True;
|
||||
PbRuler.SetBounds(0, TopOff + WH, RW, RULER_H);
|
||||
PbRuler.Visible := True;
|
||||
PositionSpanOverlayButtons;
|
||||
PositionSampleRateOverlay;
|
||||
FSpectrumWidth := RW;
|
||||
FSpectrumHeight := 0;
|
||||
FWaterfallHeight := WH;
|
||||
@@ -2424,7 +2349,7 @@ begin
|
||||
// Водопад — под сплиттером
|
||||
PbWaterfall.SetBounds(0, TopOff + SH + RULER_H + SPLITTER_H, RW, WH);
|
||||
|
||||
PositionSpanOverlayButtons;
|
||||
PositionSampleRateOverlay;
|
||||
|
||||
// Обновляем переменные размеров
|
||||
FSpectrumWidth := RW;
|
||||
@@ -2471,7 +2396,7 @@ begin
|
||||
if PanelFMCTCSS <> nil then DP(PanelFMCTCSS);
|
||||
if PanelFMStep <> nil then DP(PanelFMStep);
|
||||
DP(PanelRX); DP(PanelTX);
|
||||
DP(PanelRight); DP(PanelSpanButtons);
|
||||
DP(PanelRight);
|
||||
|
||||
PbSpectrum.Color := T.BG;
|
||||
PbWaterfall.Color := T.BG;
|
||||
@@ -2481,7 +2406,7 @@ begin
|
||||
|
||||
// Метки
|
||||
DL(LblAGCTop, False);
|
||||
DL(LblDrv); DL(LblSpan);
|
||||
DL(LblDrv);
|
||||
if LblFMSQ <> nil then DL(LblFMSQ, False);
|
||||
|
||||
// Кнопки тулбара
|
||||
@@ -2518,17 +2443,10 @@ begin
|
||||
StyleButton(BtnMOX, BtnMOX.Active);
|
||||
StyleButton(BtnTUN, BtnTUN.Active);
|
||||
|
||||
// Span / VFO-copy / HidePanel
|
||||
StyleSpanButton(BtnSpan48k, BtnSpan48k.Active);
|
||||
StyleSpanButton(BtnSpan96k, BtnSpan96k.Active);
|
||||
StyleSpanButton(BtnSpan192k, BtnSpan192k.Active);
|
||||
StyleSpanButton(BtnSpan384k, BtnSpan384k.Active);
|
||||
StyleSpanButton(BtnSpan768k, BtnSpan768k.Active);
|
||||
StyleSpanButton(BtnSpan1536k, BtnSpan1536k.Active);
|
||||
// VFO-copy
|
||||
StyleSpanButton(BtnVfoACopyB, False);
|
||||
StyleSpanButton(BtnVfoSwap, False);
|
||||
StyleSpanButton(BtnVfoBCopyA, False);
|
||||
if BtnHidePanel <> nil then StyleSpanButton(BtnHidePanel, False);
|
||||
|
||||
// Ползунки
|
||||
DS(TrkAGC); DS(TrkVolume); DS(TrkDrive);
|
||||
@@ -2618,59 +2536,17 @@ begin
|
||||
B.Font.Size := 7;
|
||||
end;
|
||||
|
||||
procedure TMainForm.PositionSpanOverlayButtons;
|
||||
procedure TMainForm.PositionSampleRateOverlay;
|
||||
const
|
||||
BTN_TOP = 6;
|
||||
GAP = 3;
|
||||
W48 = 40;
|
||||
W96 = 40;
|
||||
W192 = 44;
|
||||
W384 = 44;
|
||||
W768 = 44;
|
||||
W1536 = 50;
|
||||
HBTN = 18;
|
||||
var
|
||||
X, NeedW, BaseX, BaseY: Integer;
|
||||
MARGIN = 4;
|
||||
begin
|
||||
if (PbSpectrum = nil) or (BtnSpan48k = nil) then Exit;
|
||||
NeedW := W48 + W96 + W192 + W384 + W768 + W1536 + GAP * 5 + 8;
|
||||
if PbSpectrum.Width < NeedW then
|
||||
begin
|
||||
BtnSpan48k.Visible := False;
|
||||
BtnSpan96k.Visible := False;
|
||||
BtnSpan192k.Visible := False;
|
||||
BtnSpan384k.Visible := False;
|
||||
BtnSpan768k.Visible := False;
|
||||
BtnSpan1536k.Visible := False;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
BaseX := PbSpectrum.Left;
|
||||
BaseY := PbSpectrum.Top;
|
||||
X := BaseX + 56;
|
||||
BtnSpan48k.SetBounds(X, BaseY + BTN_TOP, W48, HBTN); Inc(X, W48 + GAP);
|
||||
BtnSpan96k.SetBounds(X, BaseY + BTN_TOP, W96, HBTN); Inc(X, W96 + GAP);
|
||||
BtnSpan192k.SetBounds(X, BaseY + BTN_TOP, W192, HBTN); Inc(X, W192 + GAP);
|
||||
BtnSpan384k.SetBounds(X, BaseY + BTN_TOP, W384, HBTN); Inc(X, W384 + GAP);
|
||||
BtnSpan768k.SetBounds(X, BaseY + BTN_TOP, W768, HBTN); Inc(X, W768 + GAP);
|
||||
BtnSpan1536k.SetBounds(X, BaseY + BTN_TOP, W1536, HBTN);
|
||||
if BtnHidePanel <> nil then
|
||||
BtnHidePanel.SetBounds(BaseX, BaseY + BTN_TOP, 28, HBTN);
|
||||
|
||||
BtnSpan48k.Visible := True;
|
||||
BtnSpan96k.Visible := True;
|
||||
BtnSpan192k.Visible := True;
|
||||
BtnSpan384k.Visible := True;
|
||||
BtnSpan768k.Visible := True;
|
||||
BtnSpan1536k.Visible := True;
|
||||
|
||||
BtnSpan48k.BringToFront;
|
||||
BtnSpan96k.BringToFront;
|
||||
BtnSpan192k.BringToFront;
|
||||
BtnSpan384k.BringToFront;
|
||||
BtnSpan768k.BringToFront;
|
||||
BtnSpan1536k.BringToFront;
|
||||
if BtnHidePanel <> nil then BtnHidePanel.BringToFront;
|
||||
if (FSampleRateOverlay = nil) or (PbSpectrum = nil) then Exit;
|
||||
FSampleRateOverlay.SetBounds(
|
||||
PbSpectrum.Left + MARGIN,
|
||||
PbSpectrum.Top + MARGIN,
|
||||
FSampleRateOverlay.Width,
|
||||
FSampleRateOverlay.Height);
|
||||
FSampleRateOverlay.BringToFront;
|
||||
end;
|
||||
|
||||
// ===========================================================================
|
||||
@@ -3954,6 +3830,8 @@ begin
|
||||
begin
|
||||
FSampleRate := G_Settings.SampleRate;
|
||||
FSpanHz := FSampleRate;
|
||||
if Assigned(FSampleRateOverlay) then
|
||||
FSampleRateOverlay.SetCurrentRate(FSampleRate);
|
||||
end;
|
||||
BtnNR.Tag := EnsureRange(G_Settings.NRMode, 0, 4); UpdateNRButton;
|
||||
BtnNB.Tag := EnsureRange(G_Settings.NBMode, 0, 2); UpdateNBButton;
|
||||
@@ -5390,13 +5268,12 @@ begin
|
||||
FSettings.SaveWebSettings(W);
|
||||
end;
|
||||
|
||||
procedure TMainForm.BtnHidePanelClick(Sender: TObject);
|
||||
procedure TMainForm.OnSampleRateHidePanel;
|
||||
begin
|
||||
FPanelHidden := not FPanelHidden;
|
||||
if FPanelHidden then
|
||||
begin
|
||||
PanelLeft.Width := 0;
|
||||
BtnHidePanel.Caption := '▶';
|
||||
FVfoOverlay.Parent := PanelRight;
|
||||
FVfoOverlay.Width := 260;
|
||||
FVfoOverlay.Height := 136; // OVL_H_NORM — расширяется сам при открытии AGC-пикера
|
||||
@@ -5409,9 +5286,10 @@ begin
|
||||
else
|
||||
begin
|
||||
PanelLeft.Width := 232;
|
||||
BtnHidePanel.Caption := '◀';
|
||||
FVfoOverlay.Visible := False;
|
||||
end;
|
||||
if Assigned(FSampleRateOverlay) then
|
||||
FSampleRateOverlay.SetPanelHidden(FPanelHidden);
|
||||
ResizeSpectrumPanels;
|
||||
ResizeSMeter;
|
||||
end;
|
||||
@@ -5492,25 +5370,20 @@ begin
|
||||
FBandCache[FCurrentBand].AGCMode := FAGCMode;
|
||||
end;
|
||||
|
||||
procedure TMainForm.BtnSpanClick(Sender: TObject);
|
||||
procedure TMainForm.OnSampleRateSelect(SampleRate: Integer);
|
||||
var
|
||||
NewRate: Integer;
|
||||
DDCRate: Word;
|
||||
begin
|
||||
NewRate := (Sender as TFlatButton).Tag;
|
||||
NewRate := SampleRate;
|
||||
if NewRate = FSampleRate then Exit;
|
||||
|
||||
FSampleRate := NewRate;
|
||||
FSpanHz := NewRate;
|
||||
DDCRate := NewRate div 1000;
|
||||
|
||||
// Обновляем кнопки сразу — UI отзывчив
|
||||
StyleSpanButton(BtnSpan48k, FSampleRate = 48000);
|
||||
StyleSpanButton(BtnSpan96k, FSampleRate = 96000);
|
||||
StyleSpanButton(BtnSpan192k, FSampleRate = 192000);
|
||||
StyleSpanButton(BtnSpan384k, FSampleRate = 384000);
|
||||
StyleSpanButton(BtnSpan768k, FSampleRate = 768000);
|
||||
StyleSpanButton(BtnSpan1536k, FSampleRate = 1536000);
|
||||
if Assigned(FSampleRateOverlay) then
|
||||
FSampleRateOverlay.SetCurrentRate(NewRate);
|
||||
Application.ProcessMessages;
|
||||
|
||||
FBandCache[FCurrentBand].SpanHz := FSpanHz; // для обратной совместимости
|
||||
@@ -5762,27 +5635,17 @@ begin
|
||||
end;
|
||||
|
||||
procedure TMainForm.SyncWebSpan;
|
||||
const
|
||||
ValidSpans: array[0..5] of Integer = (48000, 96000, 192000, 384000, 768000, 1536000);
|
||||
var
|
||||
ValidSpans: array[0..5] of Integer;
|
||||
Found: Boolean;
|
||||
i: Integer;
|
||||
Btn: TFlatButton;
|
||||
begin
|
||||
ValidSpans[0]:=48000; ValidSpans[1]:=96000; ValidSpans[2]:=192000;
|
||||
ValidSpans[3]:=384000; ValidSpans[4]:=768000; ValidSpans[5]:=1536000;
|
||||
Found := False;
|
||||
for i := 0 to 5 do
|
||||
if ValidSpans[i] = FWebSyncInt then begin Found := True; Break; end;
|
||||
if not Found then Exit;
|
||||
if FWebSyncInt = FSampleRate then Exit;
|
||||
Btn := nil;
|
||||
if FWebSyncInt = 48000 then Btn := BtnSpan48k
|
||||
else if FWebSyncInt = 96000 then Btn := BtnSpan96k
|
||||
else if FWebSyncInt = 192000 then Btn := BtnSpan192k
|
||||
else if FWebSyncInt = 384000 then Btn := BtnSpan384k
|
||||
else if FWebSyncInt = 768000 then Btn := BtnSpan768k
|
||||
else if FWebSyncInt = 1536000 then Btn := BtnSpan1536k;
|
||||
if Assigned(Btn) then BtnSpanClick(Btn);
|
||||
for i := 0 to High(ValidSpans) do
|
||||
if ValidSpans[i] = FWebSyncInt then
|
||||
begin
|
||||
OnSampleRateSelect(FWebSyncInt);
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.WebOnVolume(V: Integer);
|
||||
|
||||
Reference in New Issue
Block a user