mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
ui(settings): add responsive page layout
This commit is contained in:
+227
-307
@@ -37,6 +37,10 @@ const
|
||||
// Tag контейнера подвкладки: ApplyTheme красит такие панели фоном страницы,
|
||||
// а не цветом группы (иначе подложка выглядела бы как одна гигантская группа).
|
||||
TAG_PAGE_BG = 909;
|
||||
TAG_RESPONSIVE_CARD = 910;
|
||||
TAG_PAGE_HEADER = 911;
|
||||
TAG_RESPONSIVE_HALF_LEFT = 912;
|
||||
TAG_RESPONSIVE_HALF_RIGHT = 913;
|
||||
|
||||
type
|
||||
// PA: MaxPower в Вт, BandCal[0..10] — калибровка 38.8..100.0 на диапазон
|
||||
@@ -501,11 +505,17 @@ type
|
||||
procedure BtnTXProfDelClick(Sender: TObject);
|
||||
procedure BtnTXProfFactoryClick(Sender: TObject);
|
||||
procedure ApplyTheme(const T: TAppTheme);
|
||||
procedure SettingsResize(Sender: TObject);
|
||||
procedure RelayoutResponsiveCards;
|
||||
procedure NavClick(Sender: TObject);
|
||||
procedure SelectPage(APage: TWinControl; ANav: TFlatButton);
|
||||
|
||||
function MakeLbl(AParent: TWinControl; const Cap: string;
|
||||
ALeft, ATop, AW: Integer): TLabel;
|
||||
function MakeTextBlock(AParent: TWinControl; const Cap: string;
|
||||
ALeft, ATop, AW, AH: Integer): TLabel;
|
||||
procedure MakePageHeader(AParent: TWinControl; const ATitle, ASubtitle: string;
|
||||
ASubtitleHeight: Integer = 20);
|
||||
function MakeCombo(AParent: TWinControl; ALeft, ATop, AW: Integer;
|
||||
OnChange: TNotifyEvent): TFlatComboBox;
|
||||
function MakeGroupPanel(AParent: TWinControl; const Cap: string;
|
||||
@@ -679,7 +689,9 @@ const
|
||||
CLR_INPUT_TEXT = TColor($00202020);
|
||||
BTN_H = 24;
|
||||
GRP_TITLE_H = 22; // высота заголовка в group-панелях (title label + divider)
|
||||
SETTINGS_MARGIN = 22;
|
||||
SETTINGS_CARD_W = 760;
|
||||
SETTINGS_CARD_MAX_W = 934;
|
||||
SETTINGS_FOOTER_H = 52;
|
||||
|
||||
// Первый пункт комбо аудио слайса = «как у приложения» (пустое имя в конфиге).
|
||||
@@ -774,6 +786,8 @@ begin
|
||||
FLoading := False;
|
||||
FRXDevCount := 0;
|
||||
BuildUI;
|
||||
OnResize := SettingsResize;
|
||||
RelayoutResponsiveCards;
|
||||
ApplyTheme(DarkTheme);
|
||||
end;
|
||||
|
||||
@@ -803,6 +817,44 @@ begin
|
||||
Result.Font.Size := 9;
|
||||
end;
|
||||
|
||||
function TSettingsForm.MakeTextBlock(AParent: TWinControl; const Cap: string;
|
||||
ALeft, ATop, AW, AH: Integer): TLabel;
|
||||
begin
|
||||
Result := TLabel.Create(Self);
|
||||
Result.Parent := AParent;
|
||||
Result.Caption := Cap;
|
||||
Result.AutoSize := False;
|
||||
Result.SetBounds(DpiScale(ALeft), DpiScale(ATop),
|
||||
DpiScale(AW), DpiScale(AH));
|
||||
Result.Layout := tlTop;
|
||||
Result.WordWrap := True;
|
||||
Result.Font.Size := 9;
|
||||
Result.Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
|
||||
procedure TSettingsForm.MakePageHeader(AParent: TWinControl;
|
||||
const ATitle, ASubtitle: string; ASubtitleHeight: Integer);
|
||||
var
|
||||
L: TLabel;
|
||||
begin
|
||||
L := TLabel.Create(Self);
|
||||
L.Parent := AParent;
|
||||
L.Caption := ATitle;
|
||||
L.AutoSize := False;
|
||||
L.SetBounds(DpiScale(SETTINGS_MARGIN), DpiScale(16),
|
||||
DpiScale(SETTINGS_CARD_W), DpiScale(32));
|
||||
L.Tag := TAG_PAGE_HEADER;
|
||||
L.Layout := tlCenter;
|
||||
L.Font.Size := 16;
|
||||
L.Font.Style := [fsBold];
|
||||
L.Font.Color := CLR_TEXT;
|
||||
|
||||
if ASubtitle = '' then Exit;
|
||||
L := MakeTextBlock(AParent, ASubtitle, SETTINGS_MARGIN, 48,
|
||||
SETTINGS_CARD_W, ASubtitleHeight);
|
||||
L.Tag := TAG_PAGE_HEADER;
|
||||
end;
|
||||
|
||||
function TSettingsForm.MakeCombo(AParent: TWinControl; ALeft, ATop, AW: Integer;
|
||||
OnChange: TNotifyEvent): TFlatComboBox;
|
||||
begin
|
||||
@@ -833,6 +885,8 @@ begin
|
||||
Result.SetBounds(DpiScale(ALeft), DpiScale(ATop), SAW, DpiScale(AH));
|
||||
Result.BevelOuter := bvNone;
|
||||
Result.Color := CLR_PANEL;
|
||||
if AW = SETTINGS_CARD_W then
|
||||
Result.Tag := TAG_RESPONSIVE_CARD;
|
||||
|
||||
TitleLbl := TLabel.Create(Self);
|
||||
TitleLbl.Parent := Result;
|
||||
@@ -840,6 +894,7 @@ begin
|
||||
TitleLbl.AutoSize := False;
|
||||
TitleLbl.SetBounds(DpiScale(10), DpiScale(2),
|
||||
SAW - DpiScale(20), DpiScale(GRP_TITLE_H - 3));
|
||||
TitleLbl.Anchors := [akLeft, akTop, akRight];
|
||||
TitleLbl.Layout := tlCenter;
|
||||
TitleLbl.Font.Color := CLR_ACCENT;
|
||||
TitleLbl.Font.Size := 9;
|
||||
@@ -848,6 +903,7 @@ begin
|
||||
Divider := TPanel.Create(Self);
|
||||
Divider.Parent := Result;
|
||||
Divider.SetBounds(0, DpiScale(GRP_TITLE_H), SAW, 1);
|
||||
Divider.Anchors := [akLeft, akTop, akRight];
|
||||
Divider.BevelOuter := bvNone;
|
||||
Divider.Color := CLR_BORDER;
|
||||
end;
|
||||
@@ -913,7 +969,9 @@ begin
|
||||
begin
|
||||
Parent := FNavPanel;
|
||||
Caption := 'Settings';
|
||||
AutoSize := False;
|
||||
SetBounds(DpiScale(14), DpiScale(14), DpiScale(160), DpiScale(24));
|
||||
Layout := tlCenter;
|
||||
Font.Size := 14;
|
||||
Font.Style := [fsBold];
|
||||
Font.Color := CLR_TEXT;
|
||||
@@ -923,7 +981,9 @@ begin
|
||||
begin
|
||||
Parent := FNavPanel;
|
||||
Caption := 'EWSDR';
|
||||
AutoSize := False;
|
||||
SetBounds(DpiScale(14), DpiScale(39), DpiScale(160), DpiScale(18));
|
||||
Layout := tlCenter;
|
||||
Font.Size := 9;
|
||||
Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
@@ -1013,6 +1073,74 @@ begin
|
||||
SelectPage(FPageAudio, FNavAudio);
|
||||
end;
|
||||
|
||||
procedure TSettingsForm.SettingsResize(Sender: TObject);
|
||||
begin
|
||||
RelayoutResponsiveCards;
|
||||
end;
|
||||
|
||||
procedure TSettingsForm.RelayoutResponsiveCards;
|
||||
|
||||
procedure ResizeTree(AParent: TWinControl; ACardWidth: Integer);
|
||||
var
|
||||
i, HalfWidth: Integer;
|
||||
Ctrl: TControl;
|
||||
begin
|
||||
HalfWidth := (ACardWidth - DpiScale(16)) div 2;
|
||||
for i := 0 to AParent.ControlCount - 1 do
|
||||
begin
|
||||
Ctrl := AParent.Controls[i];
|
||||
if Ctrl.Tag = TAG_PAGE_HEADER then
|
||||
Ctrl.Width := ACardWidth
|
||||
else if (Ctrl is TPanel) and (Ctrl.Tag = TAG_RESPONSIVE_CARD) then
|
||||
Ctrl.Width := ACardWidth
|
||||
else if (Ctrl is TPanel) and (Ctrl.Tag = TAG_RESPONSIVE_HALF_LEFT) then
|
||||
begin
|
||||
Ctrl.Left := DpiScale(SETTINGS_MARGIN);
|
||||
Ctrl.Width := HalfWidth;
|
||||
end
|
||||
else if (Ctrl is TPanel) and (Ctrl.Tag = TAG_RESPONSIVE_HALF_RIGHT) then
|
||||
begin
|
||||
Ctrl.Left := DpiScale(SETTINGS_MARGIN) + HalfWidth + DpiScale(16);
|
||||
Ctrl.Width := HalfWidth;
|
||||
end
|
||||
else if (Ctrl is TPanel) and (Ctrl.Tag = TAG_PAGE_BG) then
|
||||
Ctrl.Width := ACardWidth + DpiScale(2 * SETTINGS_MARGIN);
|
||||
|
||||
if Ctrl is TWinControl then
|
||||
ResizeTree(TWinControl(Ctrl), ACardWidth);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure ResizePage(APage: TScrollBox);
|
||||
var
|
||||
CardWidth: Integer;
|
||||
begin
|
||||
if (APage = nil) or (APage.ClientWidth <= 0) then Exit;
|
||||
CardWidth := APage.ClientWidth
|
||||
- DpiScale(2 * SETTINGS_MARGIN) - DpiScale(20);
|
||||
CardWidth := EnsureRange(CardWidth, DpiScale(SETTINGS_CARD_W),
|
||||
DpiScale(SETTINGS_CARD_MAX_W));
|
||||
ResizeTree(APage, CardWidth);
|
||||
end;
|
||||
|
||||
begin
|
||||
if FContentPanel = nil then Exit;
|
||||
ResizePage(FPageAudio);
|
||||
ResizePage(FPageDisplay);
|
||||
ResizePage(FPageSpectrum);
|
||||
ResizePage(FPageWaterfall);
|
||||
ResizePage(FPageTransmit);
|
||||
ResizePage(FPagePA);
|
||||
ResizePage(FPageCalib);
|
||||
ResizePage(FPageAdvanced);
|
||||
ResizePage(FPageCAT);
|
||||
ResizePage(FPageSlices);
|
||||
ResizePage(FPageAlex);
|
||||
ResizePage(FPageXvtr);
|
||||
ResizePage(FPageOC);
|
||||
ResizePage(FPageQO);
|
||||
end;
|
||||
|
||||
procedure TSettingsForm.NavClick(Sender: TObject);
|
||||
begin
|
||||
if Sender = FNavAudio then SelectPage(FPageAudio, FNavAudio)
|
||||
@@ -1062,6 +1190,10 @@ begin
|
||||
FNavXvtr.Active := ANav = FNavXvtr;
|
||||
FNavOC.Active := ANav = FNavOC;
|
||||
FNavQO.Active := ANav = FNavQO;
|
||||
|
||||
// Скрытые alClient-страницы LCL не всегда перекладывает до показа.
|
||||
// После переключения берём уже актуальный ClientWidth выбранной страницы.
|
||||
RelayoutResponsiveCards;
|
||||
end;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -1081,24 +1213,8 @@ const
|
||||
var
|
||||
Grp: TPanel;
|
||||
begin
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageAudio;
|
||||
Caption := 'Audio';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(18), DpiScale(400), DpiScale(28));
|
||||
Font.Size := 16;
|
||||
Font.Style := [fsBold];
|
||||
Font.Color := CLR_TEXT;
|
||||
end;
|
||||
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageAudio;
|
||||
Caption := 'Input and output devices used by the receiver and transmitter.';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(48), DpiScale(560), DpiScale(20));
|
||||
Font.Size := 9;
|
||||
Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
MakePageHeader(FPageAudio, 'Audio',
|
||||
'Input and output devices used by the receiver and transmitter.');
|
||||
|
||||
Grp := MakeGroupPanel(FPageAudio, 'Audio Devices', MARGIN, 86, SETTINGS_CARD_W, 184);
|
||||
|
||||
@@ -1146,24 +1262,8 @@ var
|
||||
i: Integer;
|
||||
Grp: TPanel;
|
||||
begin
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageDisplay;
|
||||
Caption := 'Display';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(18), DpiScale(400), DpiScale(28));
|
||||
Font.Size := 16;
|
||||
Font.Style := [fsBold];
|
||||
Font.Color := CLR_TEXT;
|
||||
end;
|
||||
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageDisplay;
|
||||
Caption := 'General visual options. Spectrum and waterfall processing are split into their own pages.';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(48), DpiScale(680), DpiScale(20));
|
||||
Font.Size := 9;
|
||||
Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
MakePageHeader(FPageDisplay, 'Display',
|
||||
'General visual options. Spectrum and waterfall processing are split into their own pages.');
|
||||
|
||||
Grp := MakeGroupPanel(FPageDisplay, 'Visible Panes', MARGIN, 86, SETTINGS_CARD_W, 112);
|
||||
|
||||
@@ -1288,24 +1388,8 @@ var
|
||||
end;
|
||||
|
||||
begin
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageSpectrum;
|
||||
Caption := 'Spectrum';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(18), DpiScale(400), DpiScale(28));
|
||||
Font.Size := 16;
|
||||
Font.Style := [fsBold];
|
||||
Font.Color := CLR_TEXT;
|
||||
end;
|
||||
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageSpectrum;
|
||||
Caption := 'Analyzer, detector, averaging and grid parameters for RX1.';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(48), DpiScale(620), DpiScale(20));
|
||||
Font.Size := 9;
|
||||
Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
MakePageHeader(FPageSpectrum, 'Spectrum',
|
||||
'Analyzer, detector, averaging and grid parameters for RX1.');
|
||||
|
||||
Grp := MakeGroupPanel(FPageSpectrum, 'Analyzer', MARGIN, 86, SETTINGS_CARD_W, 128);
|
||||
MakeLbl(Grp, 'FFT Size:', PAD, R1 + 5, LW);
|
||||
@@ -1342,24 +1426,8 @@ begin
|
||||
for i := 0 to High(GRID_STEP_NAMES) do FCmbGridStep.Items.Add(GRID_STEP_NAMES[i]);
|
||||
FCmbGridStep.ItemIndex := 1;
|
||||
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageWaterfall;
|
||||
Caption := 'Waterfall';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(18), DpiScale(400), DpiScale(28));
|
||||
Font.Size := 16;
|
||||
Font.Style := [fsBold];
|
||||
Font.Color := CLR_TEXT;
|
||||
end;
|
||||
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageWaterfall;
|
||||
Caption := 'Waterfall detector, smoothing and color scale thresholds.';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(48), DpiScale(620), DpiScale(20));
|
||||
Font.Size := 9;
|
||||
Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
MakePageHeader(FPageWaterfall, 'Waterfall',
|
||||
'Waterfall detector, smoothing and color scale thresholds.');
|
||||
|
||||
Grp := MakeGroupPanel(FPageWaterfall, 'Detection && Averaging', MARGIN, 86, SETTINGS_CARD_W, 170);
|
||||
MakeLbl(Grp, 'Detector:', PAD, R1 + 5, LW);
|
||||
@@ -1515,24 +1583,9 @@ var
|
||||
end;
|
||||
|
||||
begin
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageTransmit;
|
||||
Caption := 'Transmit';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(18), DpiScale(400), DpiScale(28));
|
||||
Font.Size := 16;
|
||||
Font.Style := [fsBold];
|
||||
Font.Color := CLR_TEXT;
|
||||
end;
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageTransmit;
|
||||
Caption := 'Profile and EQ hold the active TX profile; '
|
||||
+ 'Hardware and Display are radio properties and do not follow it.';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(48), DpiScale(GRP_W), DpiScale(20));
|
||||
Font.Size := 9;
|
||||
Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
MakePageHeader(FPageTransmit, 'Transmit',
|
||||
'Profile and EQ hold the active TX profile; Hardware and Display are '
|
||||
+ 'radio properties and do not follow it.');
|
||||
|
||||
// ---- Полоса профиля (над подвкладками, видна всегда) --------------------
|
||||
Grp := MakeGroupPanel(FPageTransmit, 'TX Profile', MARGIN, 78, GRP_W, 124);
|
||||
@@ -2209,34 +2262,13 @@ var
|
||||
Spin: TFlatSpinEdit;
|
||||
i, r, c, X, Y: Integer;
|
||||
begin
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPagePA;
|
||||
Caption := 'Power Amplifier';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(18), DpiScale(400), DpiScale(28));
|
||||
Font.Size := 16;
|
||||
Font.Style := [fsBold];
|
||||
Font.Color := CLR_TEXT;
|
||||
end;
|
||||
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPagePA;
|
||||
Caption := 'Output limit and per-band calibration values.';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(48), DpiScale(620), DpiScale(20));
|
||||
Font.Size := 9;
|
||||
Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
MakePageHeader(FPagePA, 'Power Amplifier',
|
||||
'Output limit and per-band calibration values.');
|
||||
|
||||
Grp := MakeGroupPanel(FPagePA, 'Power && Calibration', MARGIN, 86, SETTINGS_CARD_W, GRP_H);
|
||||
|
||||
// Max Power
|
||||
Lbl := TLabel.Create(Self);
|
||||
Lbl.Parent := Grp;
|
||||
Lbl.Caption := 'Max power (W)';
|
||||
Lbl.SetBounds(DpiScale(GRP_PAD), DpiScale(R1 + 6), DpiScale(132), DpiScale(18));
|
||||
Lbl.Font.Color := CLR_TEXTDIM;
|
||||
Lbl.Font.Size := 9;
|
||||
Lbl := MakeLbl(Grp, 'Max power (W)', GRP_PAD, R1 + 6, 132);
|
||||
|
||||
Spin := TFlatSpinEdit.Create(Self);
|
||||
Spin.Parent := Grp;
|
||||
@@ -2252,12 +2284,8 @@ begin
|
||||
FEdMaxPower := Spin;
|
||||
|
||||
// Pluto TX max attenuation @ drive 100% (потолок под внешний усилитель), дБ<0
|
||||
Lbl := TLabel.Create(Self);
|
||||
Lbl.Parent := Grp;
|
||||
Lbl.Caption := 'Pluto TX att @100% (dB)';
|
||||
Lbl.SetBounds(DpiScale(GRP_PAD + 320), DpiScale(R1 + 6), DpiScale(180), DpiScale(18));
|
||||
Lbl.Font.Color := CLR_TEXTDIM;
|
||||
Lbl.Font.Size := 9;
|
||||
Lbl := MakeLbl(Grp, 'Pluto TX att @100% (dB)',
|
||||
GRP_PAD + 320, R1 + 6, 180);
|
||||
|
||||
FEdPlutoTxMaxAtt := TFlatFloatSpinEdit.Create(Self);
|
||||
FEdPlutoTxMaxAtt.Parent := Grp;
|
||||
@@ -2273,12 +2301,8 @@ begin
|
||||
FEdPlutoTxMaxAtt.OnChange := OnPlutoTxMaxAttChange;
|
||||
|
||||
// Calibration label
|
||||
Lbl := TLabel.Create(Self);
|
||||
Lbl.Parent := Grp;
|
||||
Lbl.Caption := 'Calibration per band, 38.8 ... 100.0';
|
||||
Lbl.SetBounds(DpiScale(GRP_PAD), DpiScale(R1 + ROW_H + 12), DpiScale(320), DpiScale(18));
|
||||
Lbl.Font.Color := CLR_TEXTDIM;
|
||||
Lbl.Font.Size := 9;
|
||||
Lbl := MakeLbl(Grp, 'Calibration per band, 38.8 ... 100.0',
|
||||
GRP_PAD, R1 + ROW_H + 12, 320);
|
||||
|
||||
// Band grid 4 columns × 3 rows
|
||||
for i := 0 to 10 do
|
||||
@@ -2288,12 +2312,7 @@ begin
|
||||
X := GRP_PAD + c * (COL_W + 4);
|
||||
Y := R1 + ROW_H + 34 + r * ROW_H;
|
||||
|
||||
Lbl := TLabel.Create(Self);
|
||||
Lbl.Parent := Grp;
|
||||
Lbl.Caption := PA_BAND_NAMES[i] + ':';
|
||||
Lbl.SetBounds(DpiScale(X), DpiScale(Y + 5), DpiScale(LBL_W), DpiScale(18));
|
||||
Lbl.Font.Color := CLR_TEXTDIM;
|
||||
Lbl.Font.Size := 9;
|
||||
Lbl := MakeLbl(Grp, PA_BAND_NAMES[i] + ':', X, Y + 5, LBL_W);
|
||||
|
||||
FEdBandCal[i] := MakeFloatSpin(Grp, X + LBL_W, Y, OnBandCalChange);
|
||||
FEdBandCal[i].Tag := i;
|
||||
@@ -2303,12 +2322,8 @@ begin
|
||||
Grp := MakeGroupPanel(FPagePA, 'VHF Calibration (Transverters)',
|
||||
MARGIN, 86 + GRP_H + 14, SETTINGS_CARD_W, R1 + 4 * ROW_H + 44);
|
||||
|
||||
Lbl := TLabel.Create(Self);
|
||||
Lbl.Parent := Grp;
|
||||
Lbl.Caption := 'Calibration per transverter slot, 38.8 ... 100.0';
|
||||
Lbl.SetBounds(DpiScale(GRP_PAD), DpiScale(R1), DpiScale(420), DpiScale(18));
|
||||
Lbl.Font.Color := CLR_TEXTDIM;
|
||||
Lbl.Font.Size := 9;
|
||||
Lbl := MakeLbl(Grp, 'Calibration per transverter slot, 38.8 ... 100.0',
|
||||
GRP_PAD, R1, 420);
|
||||
|
||||
for i := 0 to CFG_XVTR_COUNT - 1 do
|
||||
begin
|
||||
@@ -2389,24 +2404,8 @@ begin
|
||||
FCalXvtrName[i] := '';
|
||||
end;
|
||||
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageCalib;
|
||||
Caption := 'Calibration';
|
||||
SetBounds(DpiScale(CAL_MARGIN), DpiScale(18), DpiScale(400), DpiScale(28));
|
||||
Font.Size := 16;
|
||||
Font.Style := [fsBold];
|
||||
Font.Color := CLR_TEXT;
|
||||
end;
|
||||
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageCalib;
|
||||
Caption := 'Power/SWR detector, supply voltage/current and S-meter calibration.';
|
||||
SetBounds(DpiScale(CAL_MARGIN), DpiScale(48), DpiScale(620), DpiScale(20));
|
||||
Font.Size := 9;
|
||||
Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
MakePageHeader(FPageCalib, 'Calibration',
|
||||
'Power/SWR detector, supply voltage/current and S-meter calibration.');
|
||||
|
||||
// ── Power / SWR detector ────────────────────────────────────────────────
|
||||
GTop := 86;
|
||||
@@ -2807,15 +2806,8 @@ var
|
||||
Lbl: TLabel;
|
||||
Y, i: Integer;
|
||||
begin
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageAdvanced;
|
||||
Caption := 'Advanced';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(18), DpiScale(400), DpiScale(28));
|
||||
Font.Size := 16;
|
||||
Font.Style := [fsBold];
|
||||
Font.Color := CLR_TEXT;
|
||||
end;
|
||||
MakePageHeader(FPageAdvanced, 'Advanced',
|
||||
'ADC processing and built-in web server settings.');
|
||||
|
||||
// ── ADC ───────────────────────────────────────────────────────────────────
|
||||
Grp := MakeGroupPanel(FPageAdvanced, 'ADC', MARGIN, 86, SETTINGS_CARD_W, 128);
|
||||
@@ -2978,12 +2970,24 @@ procedure TSettingsForm.ApplyTheme(const T: TAppTheme);
|
||||
|
||||
procedure StyleBtn(B: TFlatButton);
|
||||
begin
|
||||
B.ClrNorm := T.Panel;
|
||||
B.ClrBorder := T.Panel;
|
||||
B.ClrHot := T.BG;
|
||||
B.ClrActive := T.Panel;
|
||||
B.ClrText := T.Text;
|
||||
B.ClrTextAct := T.FreqActive;
|
||||
if B.Parent = FNavPanel then
|
||||
begin
|
||||
B.ClrNorm := T.Panel;
|
||||
B.ClrBorder := T.Panel;
|
||||
B.ClrHot := T.BtnHot;
|
||||
B.ClrActive := T.BtnActive;
|
||||
B.ClrText := T.Text;
|
||||
B.ClrTextAct := T.BtnTextActive;
|
||||
end
|
||||
else
|
||||
begin
|
||||
B.ClrNorm := T.BtnNorm;
|
||||
B.ClrBorder := T.BtnBorderNorm;
|
||||
B.ClrHot := T.BtnHot;
|
||||
B.ClrActive := T.BtnActive;
|
||||
B.ClrText := T.BtnText;
|
||||
B.ClrTextAct := T.BtnTextActive;
|
||||
end;
|
||||
B.Invalidate;
|
||||
end;
|
||||
|
||||
@@ -3777,21 +3781,8 @@ var
|
||||
Cmb: TFlatComboBox;
|
||||
Spin: TFlatSpinEdit;
|
||||
begin
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageCAT;
|
||||
Caption := 'CAT';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(18), DpiScale(400), DpiScale(28));
|
||||
Font.Size := 16;
|
||||
Font.Style := [fsBold]; Font.Color := CLR_TEXT;
|
||||
end;
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageCAT;
|
||||
Caption := 'Computer Aided Transceiver — serial port and TCP server settings.';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(48), DpiScale(680), DpiScale(20));
|
||||
Font.Size := 9; Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
MakePageHeader(FPageCAT, 'CAT',
|
||||
'Computer Aided Transceiver — serial port and TCP server settings.');
|
||||
|
||||
for i := 0 to 3 do
|
||||
begin
|
||||
@@ -3801,6 +3792,10 @@ begin
|
||||
gy := 86 + row * (GRP_H + GRP_GAP);
|
||||
|
||||
Grp := MakeGroupPanel(FPageCAT, 'Serial Port ' + IntToStr(i + 1), gx, gy, GRP_W, GRP_H);
|
||||
if col = 0 then
|
||||
Grp.Tag := TAG_RESPONSIVE_HALF_LEFT
|
||||
else
|
||||
Grp.Tag := TAG_RESPONSIVE_HALF_RIGHT;
|
||||
|
||||
Chk := TFlatCheckBox.Create(Self);
|
||||
Chk.Parent := Grp;
|
||||
@@ -3869,6 +3864,7 @@ begin
|
||||
// TCP server group below the two rows of serial port panels
|
||||
gy := 86 + 2 * (GRP_H + GRP_GAP);
|
||||
Grp := MakeGroupPanel(FPageCAT, 'TCP CAT Server', MARGIN, gy, GRP_W * 2 + GRP_GAP, 116);
|
||||
Grp.Tag := TAG_RESPONSIVE_CARD;
|
||||
|
||||
FCATTcpEn := TFlatCheckBox.Create(Self);
|
||||
FCATTcpEn.Parent := Grp;
|
||||
@@ -4000,30 +3996,10 @@ var
|
||||
Spin: TFlatSpinEdit;
|
||||
Cmb: TFlatComboBox;
|
||||
begin
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageSlices;
|
||||
Caption := 'Slices';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(18), DpiScale(400), DpiScale(28));
|
||||
Font.Size := 16;
|
||||
Font.Style := [fsBold]; Font.Color := CLR_TEXT;
|
||||
end;
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageSlices;
|
||||
Caption := 'A separate CAT TCP port per additional slice — external software '
|
||||
+ 'controls its own slice as a standalone transceiver.';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(48), DpiScale(760), DpiScale(20));
|
||||
Font.Size := 9; Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageSlices;
|
||||
Caption := 'Slice A is the main receiver — it is configured on the CAT tab '
|
||||
+ '(serial ports and the main TCP port).';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(66), DpiScale(760), DpiScale(20));
|
||||
Font.Size := 9; Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
MakePageHeader(FPageSlices, 'Slices',
|
||||
'A separate CAT TCP port per additional slice — external software controls '
|
||||
+ 'its own slice as a standalone transceiver.' + LineEnding
|
||||
+ 'Slice A is the main receiver and is configured on the CAT page.', 38);
|
||||
|
||||
for i := 0 to CFG_CAT_SLICE_COUNT - 1 do
|
||||
begin
|
||||
@@ -4033,6 +4009,10 @@ begin
|
||||
gy := 96 + row * (GRP_H + GRP_GAP);
|
||||
|
||||
Grp := MakeGroupPanel(FPageSlices, 'Slice ' + Chr(Ord('B') + i), gx, gy, GRP_W, GRP_H);
|
||||
if col = 0 then
|
||||
Grp.Tag := TAG_RESPONSIVE_HALF_LEFT
|
||||
else
|
||||
Grp.Tag := TAG_RESPONSIVE_HALF_RIGHT;
|
||||
|
||||
Chk := TFlatCheckBox.Create(Self);
|
||||
Chk.Parent := Grp;
|
||||
@@ -4091,39 +4071,13 @@ begin
|
||||
end;
|
||||
|
||||
gy := 96 + ((CFG_CAT_SLICE_COUNT + 1) div 2) * (GRP_H + GRP_GAP);
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageSlices;
|
||||
Caption := 'Audio out/in belong to the slice letter: the setting moves the '
|
||||
+ 'slice sitting on that slot right away and the next one inherits it.';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(gy), DpiScale(760), DpiScale(20));
|
||||
Font.Size := 9; Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
Inc(gy, 18);
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageSlices;
|
||||
Caption := 'Only one slice transmits at a time: while anything is already on '
|
||||
+ 'the air the request is ignored — no take-over.';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(gy), DpiScale(760), DpiScale(20));
|
||||
Font.Size := 9; Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageSlices;
|
||||
Caption := 'Without Auto TX a slice keys up over CAT only when it is already '
|
||||
+ 'the transmit source (TX badge on the slice flag).';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(gy + 18), DpiScale(760), DpiScale(20));
|
||||
Font.Size := 9; Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageSlices;
|
||||
Caption := 'The port is opened even when the slice does not exist yet — until '
|
||||
+ 'it is created CAT answers "radio off" (PS0).';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(gy + 36), DpiScale(760), DpiScale(20));
|
||||
Font.Size := 9; Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
MakeTextBlock(FPageSlices,
|
||||
'Audio routing belongs to the slice letter and is inherited by the next '
|
||||
+ 'receiver placed in that slot.' + LineEnding
|
||||
+ 'Only one slice can transmit. Auto TX selects this slice as the TX source; '
|
||||
+ 'without it, CAT can key only the current TX slice.' + LineEnding
|
||||
+ 'The CAT port stays open before the slice exists and replies with radio-off status.',
|
||||
MARGIN, gy, SETTINGS_CARD_W, 62);
|
||||
end;
|
||||
|
||||
procedure TSettingsForm.FireSliceCATChange;
|
||||
@@ -4289,7 +4243,9 @@ var
|
||||
Result := TLabel.Create(Self);
|
||||
Result.Parent := AParent;
|
||||
Result.Caption := ACap;
|
||||
Result.AutoSize := False;
|
||||
Result.SetBounds(DpiScale(AX), DpiScale(AY), DpiScale(84), DpiScale(18));
|
||||
Result.Layout := tlCenter;
|
||||
Result.Font.Size := 9;
|
||||
Result.Font.Color := CLR_TEXT;
|
||||
end;
|
||||
@@ -4300,7 +4256,10 @@ var
|
||||
begin
|
||||
Parent := AParent;
|
||||
Caption := ACap;
|
||||
AutoSize := False;
|
||||
SetBounds(DpiScale(AX), DpiScale(AY), DpiScale(30), DpiScale(16));
|
||||
Alignment := taCenter;
|
||||
Layout := tlCenter;
|
||||
Font.Size := 9;
|
||||
Font.Color := CLR_TEXTDIM;
|
||||
end;
|
||||
@@ -4309,19 +4268,16 @@ var
|
||||
begin
|
||||
FLoading := True;
|
||||
try
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageAlex;
|
||||
Caption := 'Antenna / Alex';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(18), DpiScale(500), DpiScale(28));
|
||||
Font.Size := 16;
|
||||
Font.Style := [fsBold]; Font.Color := CLR_TEXT;
|
||||
end;
|
||||
MakePageHeader(FPageAlex, 'Antenna / Alex', '');
|
||||
FAlexSubtitle := TLabel.Create(Self);
|
||||
FAlexSubtitle.Parent := FPageAlex;
|
||||
FAlexSubtitle.Caption :=
|
||||
'Per-band RX/TX antenna and secondary path routing for the Alex filter board.';
|
||||
FAlexSubtitle.SetBounds(DpiScale(MARGIN), DpiScale(48), DpiScale(680), DpiScale(20));
|
||||
FAlexSubtitle.AutoSize := False;
|
||||
FAlexSubtitle.SetBounds(DpiScale(MARGIN), DpiScale(48),
|
||||
DpiScale(SETTINGS_CARD_W), DpiScale(20));
|
||||
FAlexSubtitle.Layout := tlTop;
|
||||
FAlexSubtitle.WordWrap := True;
|
||||
FAlexSubtitle.Font.Size := 9;
|
||||
FAlexSubtitle.Font.Color := CLR_TEXTDIM;
|
||||
|
||||
@@ -4812,22 +4768,9 @@ var
|
||||
begin
|
||||
FLoading := True;
|
||||
try
|
||||
// --- Заголовок страницы ---
|
||||
L := TLabel.Create(Self);
|
||||
L.Parent := FPageXvtr;
|
||||
L.Caption := 'Transverters';
|
||||
L.SetBounds(DpiScale(MARGIN), DpiScale(18), DpiScale(500), DpiScale(28));
|
||||
L.Font.Size := 16;
|
||||
L.Font.Style := [fsBold]; L.Font.Color := CLR_TEXT;
|
||||
|
||||
L := TLabel.Create(Self);
|
||||
L.Parent := FPageXvtr;
|
||||
L.Caption := 'Configure up to 8 transverter (XVTR) bands. When a band is selected on the main form, ' +
|
||||
'the VFO shows the displayed (RF) frequency.' + LineEnding +
|
||||
'The radio is internally tuned to the IF: f_IF = f_displayed - LO + LO Error.';
|
||||
L.SetBounds(DpiScale(MARGIN), DpiScale(50), DpiScale(GRP_W), DpiScale(34));
|
||||
L.Font.Size := 9; L.Font.Color := CLR_TEXTDIM;
|
||||
L.WordWrap := True;
|
||||
MakePageHeader(FPageXvtr, 'Transverters',
|
||||
'Configure up to 8 transverter (XVTR) bands. The VFO shows RF frequency; '
|
||||
+ 'the radio tunes to IF: f_IF = f_displayed - LO + LO Error.', 38);
|
||||
|
||||
// --- Group "Slots" --- (последний слот зарезервирован под QO-100 — не строим)
|
||||
GrpY := 100;
|
||||
@@ -4890,18 +4833,14 @@ begin
|
||||
FChkXvtrTunPwr.OnChange := OnXvtrAnyChange;
|
||||
|
||||
// --- Подсказка про колонки внизу ---
|
||||
L := TLabel.Create(Self);
|
||||
L.Parent := FPageXvtr;
|
||||
L.Caption :=
|
||||
L := MakeTextBlock(FPageXvtr,
|
||||
'EN - enable the slot. Label - band button caption. Begin/End - displayed VFO range. ' +
|
||||
'LO - local oscillator. LO Error - fine correction in Hz.' + LineEnding +
|
||||
'RX Gain - transverter RX gain offset. RX Only - block TX. TX Pwr - drive limit. ' +
|
||||
'XVTR RF - use the main HF RF path.' + LineEnding +
|
||||
'Disable PA - keep the internal PA in RX position during TX. ' +
|
||||
'RX Antenna - override the per-band antenna for this slot.';
|
||||
L.SetBounds(DpiScale(MARGIN), DpiScale(GrpY + GRP_TITLE_H + 36 + 16), DpiScale(GRP_W), DpiScale(52));
|
||||
L.Font.Size := 9; L.Font.Color := CLR_TEXTDIM;
|
||||
L.WordWrap := True;
|
||||
'RX Antenna - override the per-band antenna for this slot.',
|
||||
MARGIN, GrpY + GRP_TITLE_H + 36 + 16, GRP_W, 52);
|
||||
|
||||
// Применяем начальное состояние disabled-строк
|
||||
for i := 0 to CFG_XVTR_COUNT - 1 do
|
||||
@@ -5062,19 +5001,16 @@ var
|
||||
begin
|
||||
FLoading := True;
|
||||
try
|
||||
with TLabel.Create(Self) do
|
||||
begin
|
||||
Parent := FPageOC;
|
||||
Caption := 'OC Control';
|
||||
SetBounds(DpiScale(MARGIN), DpiScale(18), DpiScale(500), DpiScale(28));
|
||||
Font.Size := 16;
|
||||
Font.Style := [fsBold]; Font.Color := CLR_TEXT;
|
||||
end;
|
||||
MakePageHeader(FPageOC, 'OC Control', '');
|
||||
FOCSubtitle := TLabel.Create(Self);
|
||||
FOCSubtitle.Parent := FPageOC;
|
||||
FOCSubtitle.Caption :=
|
||||
'Open Collector outputs (Penny/Alex board), per-band and per-transverter. openHPSDR only.';
|
||||
FOCSubtitle.SetBounds(DpiScale(MARGIN), DpiScale(48), DpiScale(680), DpiScale(20));
|
||||
FOCSubtitle.AutoSize := False;
|
||||
FOCSubtitle.SetBounds(DpiScale(MARGIN), DpiScale(48),
|
||||
DpiScale(SETTINGS_CARD_W), DpiScale(20));
|
||||
FOCSubtitle.Layout := tlTop;
|
||||
FOCSubtitle.WordWrap := True;
|
||||
FOCSubtitle.Font.Size := 9;
|
||||
FOCSubtitle.Font.Color := CLR_TEXTDIM;
|
||||
|
||||
@@ -5278,29 +5214,16 @@ var
|
||||
|
||||
procedure QoLabel(const Cap: string; AY: Integer);
|
||||
begin
|
||||
L := TLabel.Create(Self);
|
||||
L.Parent := Grp; L.Caption := Cap;
|
||||
L.SetBounds(DpiScale(LBL_X), DpiScale(AY + 4), DpiScale(LBL_W), DpiScale(18));
|
||||
L.Font.Color := CLR_TEXTDIM; L.Font.Size := 9;
|
||||
L := MakeLbl(Grp, Cap, LBL_X, AY + 4, LBL_W);
|
||||
end;
|
||||
|
||||
begin
|
||||
FLoading := True;
|
||||
try
|
||||
L := TLabel.Create(Self);
|
||||
L.Parent := FPageQO; L.Caption := 'QO-100 (Es''hail-2 NB transponder)';
|
||||
L.SetBounds(DpiScale(MARGIN), DpiScale(18), DpiScale(600), DpiScale(28));
|
||||
L.Font.Size := 16;
|
||||
L.Font.Style := [fsBold]; L.Font.Color := CLR_TEXT;
|
||||
|
||||
L := TLabel.Create(Self);
|
||||
L.Parent := FPageQO;
|
||||
L.Caption := 'Geostationary transponder: RX downlink (~10489.5 MHz) via LNB, ' +
|
||||
'TX uplink (~2400 MHz) direct. VFO is displayed in downlink terms; ' +
|
||||
'RX and TX use separate LOs. Drift is corrected by the beacon lock.';
|
||||
L.SetBounds(DpiScale(MARGIN), DpiScale(50), DpiScale(700), DpiScale(34));
|
||||
L.Font.Size := 9; L.Font.Color := CLR_TEXTDIM;
|
||||
L.WordWrap := True;
|
||||
MakePageHeader(FPageQO, 'QO-100 (Es''hail-2 NB transponder)',
|
||||
'Geostationary transponder: RX downlink (~10489.5 MHz) via LNB and direct '
|
||||
+ 'TX uplink (~2400 MHz). Separate LOs are used; beacon lock corrects drift.',
|
||||
38);
|
||||
|
||||
Grp := MakeGroupPanel(FPageQO, 'Transponder', MARGIN, 100,
|
||||
SETTINGS_CARD_W, GRP_TITLE_H + 9 * 30 + 16);
|
||||
@@ -5349,11 +5272,8 @@ begin
|
||||
FQoPower.Font.Size := 9;
|
||||
FQoPower.OnChange := OnQOAnyChange;
|
||||
|
||||
FQoInfo := TLabel.Create(Self);
|
||||
FQoInfo.Parent := FPageQO;
|
||||
FQoInfo.SetBounds(DpiScale(MARGIN), DpiScale(100 + GRP_TITLE_H + 9 * 30 + 28), DpiScale(700), DpiScale(52));
|
||||
FQoInfo.Font.Color := CLR_TEXTDIM;
|
||||
FQoInfo.Font.Size := 9; FQoInfo.WordWrap := True;
|
||||
FQoInfo := MakeTextBlock(FPageQO, '',
|
||||
MARGIN, 100 + GRP_TITLE_H + 9 * 30 + 28, SETTINGS_CARD_W, 52);
|
||||
finally
|
||||
FLoading := False;
|
||||
end;
|
||||
|
||||
Reference in New Issue
Block a user