new layout

This commit is contained in:
2026-04-30 10:24:10 +03:00
parent 1b2fbfe2c8
commit ece5a70041
2 changed files with 173 additions and 98 deletions
+7 -5
View File
@@ -83,6 +83,8 @@ begin
end; end;
procedure TFlatButton.Paint; procedure TFlatButton.Paint;
const
CORNER = 3;
var var
R: TRect; R: TRect;
TW, TH: Integer; TW, TH: Integer;
@@ -90,21 +92,21 @@ var
begin begin
R := ClientRect; R := ClientRect;
// Фон
if FActive then BG := FClrActive if FActive then BG := FClrActive
else if FHot then BG := FClrHot else if FHot then BG := FClrHot
else BG := FClrNorm; else BG := FClrNorm;
// Фон со скруглёнными углами
Canvas.Brush.Color := BG; Canvas.Brush.Color := BG;
Canvas.Brush.Style := bsSolid; Canvas.Brush.Style := bsSolid;
Canvas.Pen.Style := psClear; Canvas.Pen.Color := BG;
Canvas.FillRect(R); Canvas.Pen.Style := psSolid;
Canvas.RoundRect(R.Left, R.Top, R.Right, R.Bottom, CORNER * 2, CORNER * 2);
// Рамка // Рамка
Canvas.Pen.Style := psSolid;
Canvas.Pen.Color := FClrBorder; Canvas.Pen.Color := FClrBorder;
Canvas.Brush.Style := bsClear; Canvas.Brush.Style := bsClear;
Canvas.Rectangle(R); Canvas.RoundRect(R.Left, R.Top, R.Right - 1, R.Bottom - 1, CORNER * 2, CORNER * 2);
// Текст // Текст
if FActive then Canvas.Font.Color := FClrTextAct if FActive then Canvas.Font.Color := FClrTextAct
+166 -93
View File
@@ -33,19 +33,20 @@ uses
SpectrumView; SpectrumView;
const const
CLR_BG = TColor($00101010); CLR_BG = TColor($00101010);
CLR_PANEL = TColor($00181818); CLR_PANEL = TColor($00181818);
CLR_BORDER = TColor($00303030); CLR_BORDER = TColor($00303030);
CLR_FREQ = TColor($0000FF00); CLR_FREQ = TColor($0000FF00);
CLR_FREQ_DIM = TColor($00008000); CLR_FREQ_DIM = TColor($00007800);
CLR_AMBER = TColor($0000AAFF); CLR_AMBER = TColor($0000AAFF);
CLR_ACTIVE = TColor($00003300); CLR_ACTIVE = TColor($000C3010);
CLR_INACTIVE = TColor($00202020); CLR_ACTIVE_BDR = TColor($00387838);
CLR_TEXT = TColor($00CCCCCC); CLR_INACTIVE = TColor($001A1A1A);
CLR_TEXTDIM = TColor($00666666); CLR_TEXT = TColor($00CCCCCC);
CLR_METER_ON = TColor($0000CC44); CLR_TEXTDIM = TColor($00666666);
CLR_METER_OVR= TColor($000000CC); CLR_METER_ON = TColor($0000CC44);
CLR_SPECTRUM = TColor($0044FF44); CLR_METER_OVR = TColor($000000CC);
CLR_SPECTRUM = TColor($0044FF44);
WDSP_WISDOM_FILE = 'wdspWisdom00'; WDSP_WISDOM_FILE = 'wdspWisdom00';
BAND_COUNT = 11; BAND_COUNT = 11;
@@ -261,6 +262,7 @@ type
BtnDiscover: TFlatButton; BtnDiscover: TFlatButton;
BtnStartStop: TFlatButton; // START / STOP (connect+run в одном) BtnStartStop: TFlatButton; // START / STOP (connect+run в одном)
BtnSettings: TFlatButton; // открыть диалог настроек BtnSettings: TFlatButton; // открыть диалог настроек
PanelSep: TPanel; // 1px разделитель под тулбаром
// ---- Left panel ---- // ---- Left panel ----
PanelLeft: TPanel; PanelLeft: TPanel;
@@ -1257,12 +1259,28 @@ begin
PanelToolbar.Align := alTop; PanelToolbar.Align := alTop;
PanelToolbar.Height := 36; PanelToolbar.Height := 36;
PanelToolbar.BevelOuter := bvNone; PanelToolbar.BevelOuter := bvNone;
PanelToolbar.Color := CLR_PANEL;
X := 4; X := 4;
BtnDiscover := MakeBtn(PanelToolbar, 'DISCOVER', X, 3, 80, BTN_H, BtnDiscoverClick); BtnDiscover := MakeBtn(PanelToolbar, 'DISCOVER', X, 3, 80, BTN_H, BtnDiscoverClick);
BtnStartStop := MakeBtn(PanelToolbar, 'START', X+84, 3, 76, BTN_H, BtnStartStopClick); BtnStartStop := MakeBtn(PanelToolbar, 'START', X+84, 3, 76, BTN_H, BtnStartStopClick);
BtnSettings := MakeBtn(PanelToolbar, 'SETUP', X+164, 3, 66, BTN_H, BtnSettingsClick); BtnSettings := MakeBtn(PanelToolbar, 'SETUP', X+164, 3, 66, BTN_H, BtnSettingsClick);
// DISCOVER — синеватый акцент
BtnDiscover.ClrNorm := TColor($00101828);
BtnDiscover.ClrHot := TColor($00182038);
BtnDiscover.ClrActive := TColor($00182038);
BtnDiscover.ClrBorder := TColor($00304860);
BtnDiscover.ClrText := TColor($0090B8D0);
BtnDiscover.ClrTextAct := TColor($00B0D0F0);
// START/STOP — зелёный тон в обоих состояниях
BtnStartStop.ClrNorm := TColor($00101810);
BtnStartStop.ClrBorder := TColor($00304830);
BtnStartStop.ClrText := TColor($0090C090);
// ---- Separator line ----
// ---- Status bar ---- // ---- Status bar ----
StatusBar1 := TStatusBar.Create(Self); StatusBar1 := TStatusBar.Create(Self);
StatusBar1.Parent := Self; StatusBar1.Parent := Self;
@@ -1284,14 +1302,14 @@ begin
PanelLeft.Width := LEFT_W; PanelLeft.Width := LEFT_W;
PanelLeft.BevelOuter := bvNone; PanelLeft.BevelOuter := bvNone;
Y := 2; Y := 38; // gap below separator: separator at y=66, content starts at y=74
// Compact top VFO group // Compact top VFO group
PanelTopVfoGroup := TPanel.Create(Self); PanelTopVfoGroup := TPanel.Create(Self);
PanelTopVfoGroup.Parent := Self; PanelTopVfoGroup.Parent := Self;
PanelTopVfoGroup.SetBounds(0, 0, TOP_VFO_W * 2 + 64, 60); PanelTopVfoGroup.SetBounds(0, 0, TOP_VFO_W * 2 + 64, 60);
PanelTopVfoGroup.BevelOuter := bvNone; PanelTopVfoGroup.BevelOuter := bvNone;
PanelTopVfoGroup.Color := CLR_PANEL; PanelTopVfoGroup.Color := TColor($00181818);
// VFO A // VFO A
PanelTopVfoA := TPanel.Create(Self); PanelTopVfoA := TPanel.Create(Self);
@@ -1305,9 +1323,9 @@ begin
PanelVfoA.SetBounds(0, 0, TOP_VFO_W, TOP_VFO_FREQ_H); PanelVfoA.SetBounds(0, 0, TOP_VFO_W, TOP_VFO_FREQ_H);
PanelVfoA.BevelOuter := bvNone; PanelVfoA.BevelOuter := bvNone;
BtnTopVfoASelect := MakeBtn(PanelVfoA, 'A', 0, 7, 18, 16, BtnTopVfoASelectClick); BtnTopVfoASelect := MakeBtn(PanelVfoA, 'A', 0, 5, 20, 18, BtnTopVfoASelectClick);
BtnTopVfoASelect.Font.Name := 'Courier New'; BtnTopVfoASelect.Font.Name := 'Courier New';
BtnTopVfoASelect.Font.Size := 6; BtnTopVfoASelect.Font.Size := 7;
BtnTopVfoASelect.Font.Bold := True; BtnTopVfoASelect.Font.Bold := True;
BtnTopVfoASelect.ClrNorm := TColor($00303030); BtnTopVfoASelect.ClrNorm := TColor($00303030);
BtnTopVfoASelect.ClrHot := TColor($00404040); BtnTopVfoASelect.ClrHot := TColor($00404040);
@@ -1316,9 +1334,9 @@ begin
BtnTopVfoASelect.ClrText := CLR_TEXTDIM; BtnTopVfoASelect.ClrText := CLR_TEXTDIM;
BtnTopVfoASelect.ClrTextAct := CLR_TEXT; BtnTopVfoASelect.ClrTextAct := CLR_TEXT;
BtnTopVfoATX := MakeBtn(PanelVfoA, 'TX', 0, 25, 18, 16, BtnTopVfoATXClick); BtnTopVfoATX := MakeBtn(PanelVfoA, 'TX', 0, 25, 20, 18, BtnTopVfoATXClick);
BtnTopVfoATX.Font.Name := 'Courier New'; BtnTopVfoATX.Font.Name := 'Courier New';
BtnTopVfoATX.Font.Size := 6; BtnTopVfoATX.Font.Size := 7;
BtnTopVfoATX.Font.Bold := True; BtnTopVfoATX.Font.Bold := True;
BtnTopVfoATX.ClrNorm := TColor($00303030); BtnTopVfoATX.ClrNorm := TColor($00303030);
BtnTopVfoATX.ClrHot := TColor($00404040); BtnTopVfoATX.ClrHot := TColor($00404040);
@@ -1362,9 +1380,9 @@ begin
PanelVfoB.SetBounds(0, 0, TOP_VFO_W, TOP_VFO_FREQ_H); PanelVfoB.SetBounds(0, 0, TOP_VFO_W, TOP_VFO_FREQ_H);
PanelVfoB.BevelOuter := bvNone; PanelVfoB.BevelOuter := bvNone;
BtnTopVfoBSelect := MakeBtn(PanelVfoB, 'B', 0, 7, 18, 16, BtnTopVfoBSelectClick); BtnTopVfoBSelect := MakeBtn(PanelVfoB, 'B', 0, 5, 20, 18, BtnTopVfoBSelectClick);
BtnTopVfoBSelect.Font.Name := 'Courier New'; BtnTopVfoBSelect.Font.Name := 'Courier New';
BtnTopVfoBSelect.Font.Size := 6; BtnTopVfoBSelect.Font.Size := 7;
BtnTopVfoBSelect.Font.Bold := True; BtnTopVfoBSelect.Font.Bold := True;
BtnTopVfoBSelect.ClrNorm := TColor($00303030); BtnTopVfoBSelect.ClrNorm := TColor($00303030);
BtnTopVfoBSelect.ClrHot := TColor($00404040); BtnTopVfoBSelect.ClrHot := TColor($00404040);
@@ -1373,9 +1391,9 @@ begin
BtnTopVfoBSelect.ClrText := CLR_TEXTDIM; BtnTopVfoBSelect.ClrText := CLR_TEXTDIM;
BtnTopVfoBSelect.ClrTextAct := CLR_TEXT; BtnTopVfoBSelect.ClrTextAct := CLR_TEXT;
BtnTopVfoBTX := MakeBtn(PanelVfoB, 'TX', 0, 25, 18, 16, BtnTopVfoBTXClick); BtnTopVfoBTX := MakeBtn(PanelVfoB, 'TX', 0, 25, 20, 18, BtnTopVfoBTXClick);
BtnTopVfoBTX.Font.Name := 'Courier New'; BtnTopVfoBTX.Font.Name := 'Courier New';
BtnTopVfoBTX.Font.Size := 6; BtnTopVfoBTX.Font.Size := 7;
BtnTopVfoBTX.Font.Bold := True; BtnTopVfoBTX.Font.Bold := True;
BtnTopVfoBTX.ClrNorm := TColor($00303030); BtnTopVfoBTX.ClrNorm := TColor($00303030);
BtnTopVfoBTX.ClrHot := TColor($00404040); BtnTopVfoBTX.ClrHot := TColor($00404040);
@@ -1407,18 +1425,23 @@ begin
FreqDispB.OnChange := FreqDispBChanged; FreqDispB.OnChange := FreqDispBChanged;
FreqDispB.OnClick := FreqDispBClick; FreqDispB.OnClick := FreqDispBClick;
// VFO transfer buttons (between A and B) // VFO transfer buttons — горизонтальный ряд по центру
PanelVfoButtons := TPanel.Create(Self); PanelVfoButtons := TPanel.Create(Self);
PanelVfoButtons.Parent := PanelTopVfoGroup; PanelVfoButtons.Parent := PanelTopVfoGroup;
PanelVfoButtons.SetBounds(0, 0, 56, 60); PanelVfoButtons.SetBounds(0, 0, 140, 20);
PanelVfoButtons.BevelOuter := bvNone; PanelVfoButtons.BevelOuter := bvNone;
PanelVfoButtons.Color := TColor($00181818);
BtnVfoSwap := MakeBtn(PanelVfoButtons, 'A<>B', 0, 0, 52, TOP_VFO_BTN_H, BtnVfoSwapClick); BtnVfoACopyB := MakeBtn(PanelVfoButtons, 'A>B', 0, 0, 44, 20, BtnVfoACopyBClick);
BtnVfoACopyB := MakeBtn(PanelVfoButtons, 'A>B', 0, 0, 52, TOP_VFO_BTN_H, BtnVfoACopyBClick); BtnVfoSwap := MakeBtn(PanelVfoButtons, 'A<>B', 0, 0, 44, 20, BtnVfoSwapClick);
BtnVfoBCopyA := MakeBtn(PanelVfoButtons, 'B>A', 0, 0, 52, TOP_VFO_BTN_H, BtnVfoBCopyAClick); BtnVfoBCopyA := MakeBtn(PanelVfoButtons, 'B>A', 0, 0, 44, 20, BtnVfoBCopyAClick);
BtnVfoSwap.Font.Size := 6; // Янтарный стиль, шрифт под размер кнопок
BtnVfoACopyB.Font.Size := 6; StyleSpanButton(BtnVfoACopyB, False);
BtnVfoBCopyA.Font.Size := 6; StyleSpanButton(BtnVfoSwap, False);
StyleSpanButton(BtnVfoBCopyA, False);
BtnVfoACopyB.Font.Size := 7;
BtnVfoSwap.Font.Size := 7;
BtnVfoBCopyA.Font.Size := 7;
LayoutTopVfoBlock; LayoutTopVfoBlock;
@@ -1598,7 +1621,7 @@ begin
PanelSpanButtons := TPanel.Create(Self); PanelSpanButtons := TPanel.Create(Self);
PanelSpanButtons.Parent := PanelRight; PanelSpanButtons.Parent := PanelRight;
PanelSpanButtons.Align := alTop; PanelSpanButtons.Align := alTop;
PanelSpanButtons.Height := 30; PanelSpanButtons.Height := 38;
PanelSpanButtons.BevelOuter := bvNone; PanelSpanButtons.BevelOuter := bvNone;
LblSpan := TLabel.Create(Self); LblSpan := TLabel.Create(Self);
@@ -1635,6 +1658,15 @@ begin
BtnHidePanel.ClrTextAct := TColor($00F0FAFF); BtnHidePanel.ClrTextAct := TColor($00F0FAFF);
BtnHidePanel.BringToFront; BtnHidePanel.BringToFront;
// Разделитель: на уровне формы, под всеми верхними элементами
PanelSep := TPanel.Create(Self);
PanelSep.Parent := Self;
PanelSep.Align := alNone;
PanelSep.BevelOuter := bvNone;
PanelSep.ParentColor := False;
PanelSep.Color := TColor($00606060);
PanelSep.SetBounds(0, PanelToolbar.Height + 30, ClientWidth, 2);
// Большой S-метр — на главной форме поверх двух панелей // Большой S-метр — на главной форме поверх двух панелей
// S-метр: Parent=Self, перекрывает Toolbar+SpanButtons вертикально // S-метр: Parent=Self, перекрывает Toolbar+SpanButtons вертикально
PanelSMeterRight := TPanel.Create(Self); PanelSMeterRight := TPanel.Create(Self);
@@ -1798,33 +1830,24 @@ const
MARGIN = 4; MARGIN = 4;
TOP_OFFSET = 2; TOP_OFFSET = 2;
TOP_VFO_FREQ_H = 47; TOP_VFO_FREQ_H = 47;
VFO_BTN_W = 18; VFO_BTN_W = 20;
VFO_BTN_FREQ_GAP = 4; VFO_BTN_FREQ_GAP = 4;
VFO_FREQ_LEFT_PAD = 2; VFO_FREQ_LEFT_PAD = 2;
VFO_FREQ_RIGHT_PAD = 8; VFO_FREQ_RIGHT_PAD = 8;
TRANSFER_LEFT_GAP = 12; XFER_BTN_W = 44;
TRANSFER_RIGHT_GAP = 24; XFER_BTN_H = 20;
TRANSFER_W = 52; XFER_BTN_GAP = 4;
TRANSFER_BTN_H = 16; XFER_PANEL_W = XFER_BTN_W * 3 + XFER_BTN_GAP * 2; // = 140
TRANSFER_BTN_GAP = 3; XFER_SIDE_GAP = 14; // минимальный зазор между VFO и кнопками трансфера
SETTINGS_GAP = 4; SETTINGS_GAP = 8;
MAX_SPREAD = 100; // максимальный дополнительный отступ с каждой стороны при растяжении
// VFO-B получает левый отступ = правому паддингу VFO-A для симметрии зазоров
VFO_B_LEFT_PAD = VFO_FREQ_LEFT_PAD + VFO_FREQ_RIGHT_PAD; // = 10
var var
BlockH: Integer; BlockH, FreqTop, SafeLeft, SafeRight, GroupLeft, GroupTop: Integer;
BtnY: Integer; RightW, SMW, SMLeft, AvailW, MinGroupW, ExtraPerSide, DynGap: Integer;
FreqTop: Integer; TopVfoAW, TopVfoBW, NeedFreqAW, NeedFreqBW, FreqTextW, GroupW: Integer;
SafeLeft: Integer; XferX, XferY: Integer;
SafeRight: Integer;
GroupLeft: Integer;
GroupTop: Integer;
RightW: Integer;
SMW: Integer;
SMLeft: Integer;
TopVfoAW: Integer;
TopVfoBW: Integer;
NeedFreqAW: Integer;
NeedFreqBW: Integer;
FreqTextW: Integer;
GroupW: Integer;
begin begin
if (PanelToolbar = nil) or (PanelSpanButtons = nil) or (PanelTopVfoGroup = nil) or if (PanelToolbar = nil) or (PanelSpanButtons = nil) or (PanelTopVfoGroup = nil) or
(PanelTopVfoA = nil) or (PanelTopVfoB = nil) then Exit; (PanelTopVfoA = nil) or (PanelTopVfoB = nil) then Exit;
@@ -1833,14 +1856,15 @@ begin
Canvas.Font.Size := FreqDispB.FontSize; Canvas.Font.Size := FreqDispB.FontSize;
Canvas.Font.Style := [fsBold]; Canvas.Font.Style := [fsBold];
FreqDispA.Left := VFO_BTN_W + VFO_BTN_FREQ_GAP - VFO_FREQ_LEFT_PAD; FreqDispA.Left := VFO_BTN_W + VFO_BTN_FREQ_GAP - VFO_FREQ_LEFT_PAD;
FreqDispB.Left := VFO_BTN_W + VFO_BTN_FREQ_GAP - VFO_FREQ_LEFT_PAD; FreqDispB.Left := VFO_B_LEFT_PAD + VFO_BTN_W + VFO_BTN_FREQ_GAP - VFO_FREQ_LEFT_PAD;
FreqTextW := Canvas.TextWidth('000.000.000'); FreqTextW := Canvas.TextWidth('000.000.000');
NeedFreqAW := FreqDispA.Left + FreqTextW + VFO_FREQ_LEFT_PAD + VFO_FREQ_RIGHT_PAD; NeedFreqAW := FreqDispA.Left + FreqTextW + VFO_FREQ_LEFT_PAD + VFO_FREQ_RIGHT_PAD;
NeedFreqBW := FreqDispB.Left + FreqTextW + VFO_FREQ_LEFT_PAD + VFO_FREQ_RIGHT_PAD; NeedFreqBW := FreqDispB.Left + FreqTextW + VFO_FREQ_LEFT_PAD + VFO_FREQ_RIGHT_PAD;
TopVfoAW := NeedFreqAW; TopVfoAW := NeedFreqAW;
TopVfoBW := NeedFreqBW; TopVfoBW := NeedFreqBW;
GroupW := TopVfoAW + TRANSFER_LEFT_GAP + TRANSFER_W +
TRANSFER_RIGHT_GAP + TopVfoBW; // Минимальная ширина компактной группы
MinGroupW := TopVfoAW + XFER_SIDE_GAP + XFER_PANEL_W + XFER_SIDE_GAP + TopVfoBW;
SafeLeft := MARGIN; SafeLeft := MARGIN;
if BtnSettings <> nil then if BtnSettings <> nil then
@@ -1851,57 +1875,67 @@ begin
RightW := ClientWidth - PanelLeft.Width; RightW := ClientWidth - PanelLeft.Width;
if RightW > 200 then if RightW > 200 then
begin begin
SMW := Round(RightW * SMETER_WIDTH_RATIO); SMW := Round(RightW * SMETER_WIDTH_RATIO);
SMLeft := ClientWidth - SMW - SMETER_MARGIN; SMLeft := ClientWidth - SMW - SMETER_MARGIN;
SafeRight := Min(SafeRight, SMLeft - TOP_SMETER_GAP); SafeRight := Min(SafeRight, SMLeft - TOP_SMETER_GAP);
end; end;
end; end;
if SafeLeft + GroupW > SafeRight then AvailW := SafeRight - SafeLeft;
if AvailW < MinGroupW then
begin begin
PanelTopVfoGroup.Visible := False; PanelTopVfoGroup.Visible := False;
Exit; Exit;
end; end;
PanelTopVfoGroup.Visible := True; // Динамический зазор: растёт с шириной окна, но не больше MAX_SPREAD
PanelTopVfoA.Visible := True; ExtraPerSide := Min((AvailW - MinGroupW) div 2, MAX_SPREAD);
PanelTopVfoB.Visible := True; DynGap := XFER_SIDE_GAP + ExtraPerSide;
BlockH := PanelToolbar.Height + PanelSpanButtons.Height - (MARGIN * 2); GroupW := TopVfoAW + DynGap + XFER_PANEL_W + DynGap + TopVfoBW;
BlockH := PanelToolbar.Height + 30 - (MARGIN * 2); // 30 = span row content, not full PanelSpanButtons
if BlockH < 56 then BlockH := 56; if BlockH < 56 then BlockH := 56;
GroupLeft := SafeLeft + (SafeRight - SafeLeft - GroupW) div 2;
GroupTop := TOP_OFFSET; // Центрируем группу в доступном пространстве
GroupLeft := SafeLeft + (AvailW - GroupW) div 2;
GroupTop := TOP_OFFSET;
PanelTopVfoGroup.SetBounds(GroupLeft, GroupTop, GroupW, BlockH); PanelTopVfoGroup.SetBounds(GroupLeft, GroupTop, GroupW, BlockH);
PanelTopVfoGroup.Visible := True;
// VFO-A: левый край группы
PanelTopVfoA.SetBounds(0, 0, TopVfoAW, BlockH); PanelTopVfoA.SetBounds(0, 0, TopVfoAW, BlockH);
PanelTopVfoA.Visible := True;
PanelVfoA.SetBounds(0, 0, TopVfoAW, TOP_VFO_FREQ_H); PanelVfoA.SetBounds(0, 0, TopVfoAW, TOP_VFO_FREQ_H);
FreqTop := ((BtnTopVfoASelect.Top + BtnTopVfoASelect.Height + FreqTop := ((BtnTopVfoASelect.Top + BtnTopVfoASelect.Height +
BtnTopVfoATX.Top) div 2) - (TOP_VFO_FREQ_H div 2); BtnTopVfoATX.Top) div 2) - (TOP_VFO_FREQ_H div 2);
FreqDispA.SetBounds(FreqDispA.Left, FreqDispA.Top, FreqDispA.SetBounds(FreqDispA.Left, FreqTop,
FreqTextW + VFO_FREQ_LEFT_PAD + VFO_FREQ_RIGHT_PAD, TOP_VFO_FREQ_H); FreqTextW + VFO_FREQ_LEFT_PAD + VFO_FREQ_RIGHT_PAD, TOP_VFO_FREQ_H);
FreqDispA.Top := FreqTop;
BtnTopVfoASelect.Left := 0; BtnTopVfoASelect.Left := 0;
BtnTopVfoATX.Left := 0; BtnTopVfoATX.Left := 0;
PanelVfoButtons.SetBounds(TopVfoAW + TRANSFER_LEFT_GAP, 0, TRANSFER_W, BlockH); // Кнопки трансфера: горизонтальный ряд, вертикально по центру
BtnY := (PanelVfoButtons.Height - (TRANSFER_BTN_H * 3 + TRANSFER_BTN_GAP * 2)) div 2; XferX := TopVfoAW + DynGap;
if BtnY < 0 then BtnY := 0; XferY := (BlockH - XFER_BTN_H) div 2;
BtnVfoSwap.SetBounds(0, BtnY, TRANSFER_W, TRANSFER_BTN_H); PanelVfoButtons.SetBounds(XferX, XferY, XFER_PANEL_W, XFER_BTN_H);
BtnVfoACopyB.SetBounds(0, BtnY + TRANSFER_BTN_H + TRANSFER_BTN_GAP, BtnVfoACopyB.SetBounds(0, 0, XFER_BTN_W, XFER_BTN_H);
TRANSFER_W, TRANSFER_BTN_H); BtnVfoSwap.SetBounds(XFER_BTN_W + XFER_BTN_GAP, 0, XFER_BTN_W, XFER_BTN_H);
BtnVfoBCopyA.SetBounds(0, BtnY + (TRANSFER_BTN_H + TRANSFER_BTN_GAP) * 2, BtnVfoBCopyA.SetBounds((XFER_BTN_W + XFER_BTN_GAP) * 2, 0, XFER_BTN_W, XFER_BTN_H);
TRANSFER_W, TRANSFER_BTN_H);
PanelTopVfoB.SetBounds(TopVfoAW + TRANSFER_LEFT_GAP + TRANSFER_W + // VFO-B: правый край группы
TRANSFER_RIGHT_GAP, PanelTopVfoB.SetBounds(TopVfoAW + DynGap + XFER_PANEL_W + DynGap, 0, TopVfoBW, BlockH);
0, TopVfoBW, BlockH); PanelTopVfoB.Visible := True;
PanelVfoB.SetBounds(0, 0, TopVfoBW, TOP_VFO_FREQ_H); PanelVfoB.SetBounds(0, 0, TopVfoBW, TOP_VFO_FREQ_H);
FreqTop := ((BtnTopVfoBSelect.Top + BtnTopVfoBSelect.Height + FreqTop := ((BtnTopVfoBSelect.Top + BtnTopVfoBSelect.Height +
BtnTopVfoBTX.Top) div 2) - (TOP_VFO_FREQ_H div 2); BtnTopVfoBTX.Top) div 2) - (TOP_VFO_FREQ_H div 2);
FreqDispB.SetBounds(FreqDispB.Left, FreqDispB.Top, FreqDispB.SetBounds(FreqDispB.Left, FreqTop,
FreqTextW + VFO_FREQ_LEFT_PAD + VFO_FREQ_RIGHT_PAD, TOP_VFO_FREQ_H); FreqTextW + VFO_FREQ_LEFT_PAD + VFO_FREQ_RIGHT_PAD, TOP_VFO_FREQ_H);
FreqDispB.Top := FreqTop; BtnTopVfoBSelect.Left := VFO_B_LEFT_PAD;
BtnTopVfoBSelect.Left := 0; BtnTopVfoBTX.Left := VFO_B_LEFT_PAD;
BtnTopVfoBTX.Left := 0;
if PanelSep <> nil then
PanelSep.SetBounds(0, PanelToolbar.Height + 30, ClientWidth, 2);
PanelTopVfoGroup.BringToFront; PanelTopVfoGroup.BringToFront;
end; end;
@@ -1934,7 +1968,7 @@ begin
// Y: от верха формы+margin до низа PanelSpanButtons-margin // Y: от верха формы+margin до низа PanelSpanButtons-margin
SMTop := SMETER_MARGIN; SMTop := SMETER_MARGIN;
SMBot := PanelToolbar.Height + PanelSpanButtons.Height - SMETER_MARGIN; SMBot := PanelToolbar.Height + 30 - SMETER_MARGIN; // 30 = span row content, ends before separator
PanelSMeterRight.SetBounds(SMLeft, SMTop, SMW, SMBot - SMTop); PanelSMeterRight.SetBounds(SMLeft, SMTop, SMW, SMBot - SMTop);
PanelSMeterRight.BringToFront; PanelSMeterRight.BringToFront;
@@ -2110,8 +2144,9 @@ begin
B.Active := Active; B.Active := Active;
B.ClrNorm := CLR_INACTIVE; B.ClrNorm := CLR_INACTIVE;
B.ClrActive := CLR_ACTIVE; B.ClrActive := CLR_ACTIVE;
B.ClrHot := TColor($00323232); B.ClrHot := TColor($00282828);
B.ClrBorder := TColor($00505050); if Active then B.ClrBorder := CLR_ACTIVE_BDR
else B.ClrBorder := TColor($00444444);
B.ClrText := CLR_TEXT; B.ClrText := CLR_TEXT;
B.ClrTextAct := TColor($0000FF88); B.ClrTextAct := TColor($0000FF88);
B.Font.Name := 'Courier New'; B.Font.Name := 'Courier New';
@@ -2213,21 +2248,59 @@ begin
if FActiveVfo = 0 then if FActiveVfo = 0 then
begin begin
// VFO-A активен: яркий зелёный
FreqDispA.ColorNormal := CLR_FREQ; FreqDispA.ColorNormal := CLR_FREQ;
FreqDispB.ColorNormal := CLR_FREQ_DIM; FreqDispB.ColorNormal := CLR_FREQ_DIM;
LblVfoALabel.Font.Color := CLR_FREQ; LblVfoALabel.Font.Color := CLR_FREQ;
LblVfoBLabel.Font.Color := CLR_TEXTDIM; LblVfoBLabel.Font.Color := CLR_TEXTDIM;
if BtnTopVfoASelect <> nil then StyleButton(BtnTopVfoASelect, True); // Активный VFO-A: зелёный акцент
if BtnTopVfoBSelect <> nil then StyleButton(BtnTopVfoBSelect, False); if BtnTopVfoASelect <> nil then begin
BtnTopVfoASelect.ClrNorm := TColor($00101C10);
BtnTopVfoASelect.ClrActive := TColor($00182818);
BtnTopVfoASelect.ClrHot := TColor($00182818);
BtnTopVfoASelect.ClrBorder := TColor($004A7A4A);
BtnTopVfoASelect.ClrText := TColor($0060B860);
BtnTopVfoASelect.ClrTextAct := TColor($0040FF60);
BtnTopVfoASelect.Active := True;
BtnTopVfoASelect.Invalidate;
end;
// Неактивный VFO-B: приглушённый
if BtnTopVfoBSelect <> nil then begin
BtnTopVfoBSelect.ClrNorm := TColor($001A1A1A);
BtnTopVfoBSelect.ClrActive := TColor($00282828);
BtnTopVfoBSelect.ClrHot := TColor($00252525);
BtnTopVfoBSelect.ClrBorder := TColor($00404040);
BtnTopVfoBSelect.ClrText := CLR_TEXTDIM;
BtnTopVfoBSelect.ClrTextAct := CLR_TEXT;
BtnTopVfoBSelect.Active := False;
BtnTopVfoBSelect.Invalidate;
end;
end else begin end else begin
// VFO-B активен: яркий зелёный
FreqDispA.ColorNormal := CLR_FREQ_DIM; FreqDispA.ColorNormal := CLR_FREQ_DIM;
FreqDispB.ColorNormal := CLR_FREQ; FreqDispB.ColorNormal := CLR_FREQ;
LblVfoALabel.Font.Color := CLR_TEXTDIM; LblVfoALabel.Font.Color := CLR_TEXTDIM;
LblVfoBLabel.Font.Color := CLR_FREQ; LblVfoBLabel.Font.Color := CLR_FREQ;
if BtnTopVfoASelect <> nil then StyleButton(BtnTopVfoASelect, False); // Неактивный VFO-A: приглушённый
if BtnTopVfoBSelect <> nil then StyleButton(BtnTopVfoBSelect, True); if BtnTopVfoASelect <> nil then begin
BtnTopVfoASelect.ClrNorm := TColor($001A1A1A);
BtnTopVfoASelect.ClrActive := TColor($00282828);
BtnTopVfoASelect.ClrHot := TColor($00252525);
BtnTopVfoASelect.ClrBorder := TColor($00404040);
BtnTopVfoASelect.ClrText := CLR_TEXTDIM;
BtnTopVfoASelect.ClrTextAct := CLR_TEXT;
BtnTopVfoASelect.Active := False;
BtnTopVfoASelect.Invalidate;
end;
// Активный VFO-B: зелёный акцент
if BtnTopVfoBSelect <> nil then begin
BtnTopVfoBSelect.ClrNorm := TColor($00101C10);
BtnTopVfoBSelect.ClrActive := TColor($00182818);
BtnTopVfoBSelect.ClrHot := TColor($00182818);
BtnTopVfoBSelect.ClrBorder := TColor($004A7A4A);
BtnTopVfoBSelect.ClrText := TColor($0060B860);
BtnTopVfoBSelect.ClrTextAct := TColor($0040FF60);
BtnTopVfoBSelect.Active := True;
BtnTopVfoBSelect.Invalidate;
end;
end; end;
if BtnTopVfoATX <> nil then if BtnTopVfoATX <> nil then
begin begin