Improve settings layout and TX equalizer

This commit is contained in:
2026-05-20 14:35:53 +03:00
parent ad02fa3f77
commit 1b39bc6746
3 changed files with 762 additions and 76 deletions
+686
View File
@@ -0,0 +1,686 @@
unit EqualizerControl;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Controls, Graphics, LCLType, Types, Math,
FlatButton, AppTheme;
type
TEqualizerControl = class(TCustomControl)
private
FEnabledEQ: Boolean;
FBandCount: Integer;
FPreampGain: Double;
FGains: array[1..10] of Double;
FFreqs: array[1..10] of Double;
FDragging: Integer; // -1=preamp, 1..10=band, 0=none
FHover: Integer;
FOnChange: TNotifyEvent;
FClrBG: TColor;
FClrPanel: TColor;
FClrBorder: TColor;
FClrGrid: TColor;
FClrText: TColor;
FClrTextDim: TColor;
FClrAccent: TColor;
FClrCurve: TColor;
FBtnEQ: TFlatButton;
FBtnBands3: TFlatButton;
FBtnBands10: TFlatButton;
FButtonTheme: TAppTheme;
function GetBandGain(Index: Integer): Double;
function GetBandFreq(Index: Integer): Double;
procedure SetEnabledEQ(V: Boolean);
procedure SetBandCount(V: Integer);
procedure SetPreampGain(V: Double);
procedure SetBandGain(Index: Integer; V: Double);
procedure SetBandFreq(Index: Integer; V: Double);
function TopRect: TRect;
function PreampRect: TRect;
function GraphRect: TRect;
function TilesRect: TRect;
function GainToY(G: Double; const R: TRect): Integer;
function YToGain(Y: Integer; const R: TRect): Double;
function BandX(Index: Integer; const R: TRect): Integer;
function XToFreq(X: Integer; const R: TRect): Double;
function BandColor(Index: Integer): TColor;
function InternalBandFreq(Index: Integer): Double;
function ResponseAtFreq(AFreq: Double): Double;
function FormatFreq(AFreq: Double): string;
function HitTestControl(X, Y: Integer): Integer;
procedure DrawTiles;
procedure LayoutButtons;
procedure StyleButton(B: TFlatButton; Active: Boolean);
procedure UpdateButtonStates;
procedure OnEQButtonClick(Sender: TObject);
procedure OnBands3Click(Sender: TObject);
procedure OnBands10Click(Sender: TObject);
procedure Changed;
protected
procedure Paint; override;
procedure Resize; override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseLeave; override;
function DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; override;
function DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; override;
public
constructor Create(AOwner: TComponent); override;
procedure SetThemeColors(ABG, APanel, ABorder, AGrid, AText, ATextDim,
AAccent, ACurve: TColor);
procedure SetAppTheme(const ATheme: TAppTheme);
procedure SetBand(Index: Integer; AFreq, AGain: Double);
property EQEnabled: Boolean read FEnabledEQ write SetEnabledEQ;
property BandCount: Integer read FBandCount write SetBandCount;
property PreampGain: Double read FPreampGain write SetPreampGain;
property BandGain[Index: Integer]: Double read GetBandGain write SetBandGain;
property BandFreq[Index: Integer]: Double read GetBandFreq write SetBandFreq;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;
implementation
const
MIN_GAIN = -15.0;
MAX_GAIN = 15.0;
VIS_MIN_GAIN = -20.0;
VIS_MAX_GAIN = 20.0;
MIN_FREQ = 20.0;
MAX_FREQ = 20000.0;
TOP_H = 44;
BOTTOM_H = 82;
constructor TEqualizerControl.Create(AOwner: TComponent);
var
i: Integer;
begin
inherited Create(AOwner);
Width := 720;
Height := 300;
FEnabledEQ := False;
FBandCount := 10;
FPreampGain := 0.0;
FDragging := 0;
FHover := 0;
for i := 1 to 10 do
begin
FGains[i] := 0.0;
FFreqs[i] := 0.0;
end;
FClrBG := TColor($001A1A1A);
FClrPanel := TColor($00202020);
FClrBorder := TColor($00303030);
FClrGrid := TColor($00383838);
FClrText := TColor($00E0E0E0);
FClrTextDim := TColor($00888888);
FClrAccent := TColor($0040FF80);
FClrCurve := TColor($0055DDEE);
FButtonTheme := DarkTheme;
Cursor := crHandPoint;
FBtnEQ := TFlatButton.Create(Self);
FBtnEQ.Parent := Self;
FBtnEQ.Caption := 'Equalizer';
FBtnEQ.OnClick := @OnEQButtonClick;
FBtnBands3 := TFlatButton.Create(Self);
FBtnBands3.Parent := Self;
FBtnBands3.Caption := '3 Band';
FBtnBands3.OnClick := @OnBands3Click;
FBtnBands10 := TFlatButton.Create(Self);
FBtnBands10.Parent := Self;
FBtnBands10.Caption := '10 Band';
FBtnBands10.OnClick := @OnBands10Click;
LayoutButtons;
UpdateButtonStates;
end;
procedure TEqualizerControl.SetThemeColors(ABG, APanel, ABorder, AGrid,
AText, ATextDim, AAccent, ACurve: TColor);
begin
FClrBG := ABG;
FClrPanel := APanel;
FClrBorder := ABorder;
FClrGrid := AGrid;
FClrText := AText;
FClrTextDim := ATextDim;
FClrAccent := AAccent;
FClrCurve := ACurve;
UpdateButtonStates;
Invalidate;
end;
procedure TEqualizerControl.SetAppTheme(const ATheme: TAppTheme);
begin
FButtonTheme := ATheme;
UpdateButtonStates;
Invalidate;
end;
function TEqualizerControl.GetBandGain(Index: Integer): Double;
begin
if (Index >= 1) and (Index <= 10) then Result := FGains[Index]
else Result := 0.0;
end;
function TEqualizerControl.GetBandFreq(Index: Integer): Double;
begin
if (Index >= 1) and (Index <= 10) then Result := FFreqs[Index]
else Result := 0.0;
end;
procedure TEqualizerControl.Changed;
begin
UpdateButtonStates;
Invalidate;
if Assigned(FOnChange) then FOnChange(Self);
end;
procedure TEqualizerControl.SetEnabledEQ(V: Boolean);
begin
if FEnabledEQ = V then Exit;
FEnabledEQ := V;
Changed;
end;
procedure TEqualizerControl.SetBandCount(V: Integer);
begin
if V <= 3 then V := 3 else V := 10;
if FBandCount = V then Exit;
FBandCount := V;
Changed;
end;
procedure TEqualizerControl.SetPreampGain(V: Double);
begin
V := EnsureRange(V, MIN_GAIN, MAX_GAIN);
if Abs(FPreampGain - V) < 0.001 then Exit;
FPreampGain := V;
Changed;
end;
procedure TEqualizerControl.SetBandGain(Index: Integer; V: Double);
begin
if (Index < 1) or (Index > 10) then Exit;
V := EnsureRange(V, MIN_GAIN, MAX_GAIN);
if Abs(FGains[Index] - V) < 0.001 then Exit;
FGains[Index] := V;
Changed;
end;
procedure TEqualizerControl.SetBandFreq(Index: Integer; V: Double);
begin
if (Index < 1) or (Index > 10) then Exit;
V := EnsureRange(V, MIN_FREQ, MAX_FREQ);
if Abs(FFreqs[Index] - V) < 0.001 then Exit;
FFreqs[Index] := V;
Changed;
end;
procedure TEqualizerControl.SetBand(Index: Integer; AFreq, AGain: Double);
begin
if (Index < 1) or (Index > 10) then Exit;
if AFreq <= 0.0 then
FFreqs[Index] := MIN_FREQ * Power(MAX_FREQ / MIN_FREQ, (Index - 1) / 9)
else
FFreqs[Index] := EnsureRange(AFreq, MIN_FREQ, MAX_FREQ);
FGains[Index] := EnsureRange(AGain, MIN_GAIN, MAX_GAIN);
Invalidate;
end;
function TEqualizerControl.GraphRect: TRect;
var
R: TRect;
begin
R := TopRect;
Result := Rect(R.Left + 54, R.Top, R.Right, R.Bottom);
end;
function TEqualizerControl.TopRect: TRect;
begin
Result := Rect(40, TOP_H, Width - 26, Height - BOTTOM_H - 10);
end;
function TEqualizerControl.PreampRect: TRect;
var
R: TRect;
begin
R := TopRect;
Result := Rect(R.Left, R.Top, R.Left + 38, R.Bottom);
end;
function TEqualizerControl.TilesRect: TRect;
begin
Result := Rect(40, Height - BOTTOM_H + 12, Width - 26, Height - 6);
end;
function TEqualizerControl.GainToY(G: Double; const R: TRect): Integer;
begin
G := EnsureRange(G, VIS_MIN_GAIN, VIS_MAX_GAIN);
Result := R.Bottom - Round((G - VIS_MIN_GAIN) / (VIS_MAX_GAIN - VIS_MIN_GAIN) * (R.Bottom - R.Top));
end;
function TEqualizerControl.YToGain(Y: Integer; const R: TRect): Double;
begin
Result := VIS_MIN_GAIN + (R.Bottom - EnsureRange(Y, R.Top, R.Bottom)) /
Max(1, R.Bottom - R.Top) * (VIS_MAX_GAIN - VIS_MIN_GAIN);
Result := EnsureRange(Result, MIN_GAIN, MAX_GAIN);
end;
function TEqualizerControl.BandX(Index: Integer; const R: TRect): Integer;
var
F: Double;
begin
F := EnsureRange(InternalBandFreq(Index), MIN_FREQ, MAX_FREQ);
Result := R.Left + Round(Ln(F / MIN_FREQ) / Ln(MAX_FREQ / MIN_FREQ) * (R.Right - R.Left));
end;
function TEqualizerControl.XToFreq(X: Integer; const R: TRect): Double;
var
P: Double;
begin
P := EnsureRange((X - R.Left) / Max(1, R.Right - R.Left), 0.0, 1.0);
Result := MIN_FREQ * Power(MAX_FREQ / MIN_FREQ, P);
end;
function TEqualizerControl.BandColor(Index: Integer): TColor;
const
C: array[1..10] of TColor = (
TColor($00E05A2A), TColor($00D99028), TColor($00C9B72C), TColor($006FBF45),
TColor($003DBE70), TColor($0035B7C4), TColor($003B88E0), TColor($006456E8),
TColor($00A653D6), TColor($00D34F9D));
begin
if (Index >= 1) and (Index <= 10) then Result := C[Index]
else Result := FClrAccent;
end;
function TEqualizerControl.InternalBandFreq(Index: Integer): Double;
begin
if (Index >= 1) and (Index <= 10) and (FFreqs[Index] > 0.0) then
Result := FFreqs[Index]
else
Result := MIN_FREQ * Power(MAX_FREQ / MIN_FREQ, EnsureRange((Index - 1) / 9, 0.0, 1.0));
end;
function TEqualizerControl.ResponseAtFreq(AFreq: Double): Double;
var
i, N: Integer;
D, W, Sum, LF, LBand: Double;
begin
Result := FPreampGain;
LF := Ln(EnsureRange(AFreq, MIN_FREQ, MAX_FREQ));
Sum := 0.0;
N := FBandCount;
for i := 1 to N do
begin
LBand := Ln(InternalBandFreq(i));
D := (LF - LBand) / 0.30;
W := Exp(-0.5 * D * D);
Sum := Sum + FGains[i] * W;
end;
Result := Result + Sum;
Result := EnsureRange(Result, -24.0, 24.0);
end;
function TEqualizerControl.FormatFreq(AFreq: Double): string;
begin
if AFreq >= 1000.0 then
Result := FormatFloat('0.#', AFreq / 1000.0) + 'k'
else
Result := FormatFloat('0', AFreq);
end;
function TEqualizerControl.HitTestControl(X, Y: Integer): Integer;
var
R: TRect;
i, BX, BY, N: Integer;
begin
Result := 0;
R := PreampRect;
if PtInRect(R, Point(X, Y)) then Exit(-1);
R := GraphRect;
N := FBandCount;
for i := 1 to N do
begin
BX := BandX(i, R);
BY := GainToY(FGains[i], R);
if (Abs(X - BX) <= 12) and (Abs(Y - BY) <= 12) then
Exit(i);
end;
end;
procedure TEqualizerControl.DrawTiles;
var
R, TR: TRect;
i, TileW, X: Integer;
C: TColor;
S: string;
begin
R := TilesRect;
TileW := Max(1, (R.Right - R.Left) div 10);
Canvas.Font.Size := 8;
Canvas.Brush.Style := bsSolid;
for i := 1 to 10 do
begin
X := R.Left + (i - 1) * TileW;
TR := Rect(X, R.Top, X + TileW - 2, R.Bottom);
C := BandColor(i);
if i <= FBandCount then Canvas.Brush.Color := TColor($00262626)
else Canvas.Brush.Color := TColor($001F1F1F);
Canvas.Pen.Color := FClrBorder;
Canvas.Rectangle(TR);
Canvas.Pen.Color := C;
Canvas.Brush.Style := bsClear;
Canvas.Arc(TR.Left + 16, TR.Top + 6, TR.Left + 48, TR.Top + 30,
TR.Left + 18, TR.Top + 22, TR.Left + 46, TR.Top + 22);
Canvas.Brush.Style := bsSolid;
Canvas.Brush.Color := C;
Canvas.Ellipse(TR.Left + 30, TR.Top + 13, TR.Left + 38, TR.Top + 21);
Canvas.Brush.Style := bsClear;
Canvas.Font.Color := FClrTextDim;
S := FormatFreq(InternalBandFreq(i));
Canvas.TextOut(TR.Left + 6, TR.Top + 34, S);
Canvas.Font.Color := C;
Canvas.TextOut(TR.Left + 6, TR.Top + 49, FormatFloat('0.0', FGains[i]));
Canvas.Brush.Style := bsSolid;
end;
Canvas.Font.Size := 9;
end;
procedure TEqualizerControl.LayoutButtons;
begin
if FBtnEQ <> nil then
FBtnEQ.SetBounds(18, 12, 94, 22);
if FBtnBands3 <> nil then
FBtnBands3.SetBounds(Width - 210, 12, 102, 24);
if FBtnBands10 <> nil then
FBtnBands10.SetBounds(Width - 100, 12, 82, 24);
end;
procedure TEqualizerControl.StyleButton(B: TFlatButton; Active: Boolean);
begin
if B = nil then Exit;
B.Active := Active;
B.ClrNorm := FButtonTheme.BtnNorm;
B.ClrActive := FButtonTheme.BtnActive;
B.ClrHot := FButtonTheme.BtnHot;
if Active then
B.ClrBorder := FButtonTheme.BtnBorderActive
else
B.ClrBorder := FButtonTheme.BtnBorderNorm;
B.ClrText := FButtonTheme.BtnText;
B.ClrTextAct := FButtonTheme.BtnTextActive;
B.Font.Name := 'Courier New';
B.Font.Size := 8;
B.Invalidate;
end;
procedure TEqualizerControl.UpdateButtonStates;
begin
StyleButton(FBtnEQ, FEnabledEQ);
StyleButton(FBtnBands3, FBandCount = 3);
StyleButton(FBtnBands10, FBandCount = 10);
end;
procedure TEqualizerControl.OnEQButtonClick(Sender: TObject);
begin
EQEnabled := not FEnabledEQ;
end;
procedure TEqualizerControl.OnBands3Click(Sender: TObject);
begin
BandCount := 3;
end;
procedure TEqualizerControl.OnBands10Click(Sender: TObject);
begin
BandCount := 10;
end;
procedure TEqualizerControl.Paint;
var
R, PR: TRect;
i, X, Y, PrevX, PrevY, N, ZeroY, AxisY, PreX, CurveL, CurveR: Integer;
GX, GY, LastFillY, FillBottom: Integer;
FreqMarks: array[0..9] of Double;
S: string;
G, F: Double;
begin
Canvas.Brush.Color := FClrBG;
Canvas.FillRect(ClientRect);
Canvas.Font.Name := Font.Name;
Canvas.Font.Size := 9;
Canvas.Brush.Style := bsClear;
Canvas.Brush.Style := bsClear;
Canvas.Font.Color := FClrTextDim;
Canvas.TextOut(126, 16, Format('Preamp %.1f dB', [FPreampGain]));
R := GraphRect;
PR := PreampRect;
Canvas.Brush.Style := bsSolid;
Canvas.Brush.Color := FClrPanel;
Canvas.Pen.Color := FClrBorder;
Canvas.Rectangle(PR);
PreX := (PR.Left + PR.Right) div 2;
Canvas.Pen.Color := TColor($00424242);
Canvas.Pen.Width := 3;
Canvas.Line(PreX, PR.Top + 12, PreX, PR.Bottom - 22);
Canvas.Pen.Width := 1;
Y := GainToY(FPreampGain, PR);
Y := EnsureRange(Y, PR.Top + 12, PR.Bottom - 22);
Canvas.Brush.Color := TColor($00303030);
Canvas.Pen.Color := FClrAccent;
Canvas.Ellipse(PreX - 7, Y - 7, PreX + 8, Y + 8);
Canvas.Brush.Color := FClrAccent;
Canvas.Pen.Color := FClrAccent;
Canvas.Ellipse(PreX - 3, Y - 3, PreX + 4, Y + 4);
Canvas.Brush.Style := bsClear;
Canvas.Font.Size := 8;
Canvas.Font.Color := FClrTextDim;
Canvas.TextOut(PreX - Canvas.TextWidth('Pre') div 2, PR.Bottom - 16, 'Pre');
Canvas.Font.Size := 9;
Canvas.Brush.Style := bsSolid;
Canvas.Brush.Color := FClrPanel;
Canvas.Pen.Color := FClrBorder;
Canvas.Rectangle(R);
FreqMarks[0] := 20; FreqMarks[1] := 50; FreqMarks[2] := 100;
FreqMarks[3] := 200; FreqMarks[4] := 500; FreqMarks[5] := 1000;
FreqMarks[6] := 2000; FreqMarks[7] := 5000; FreqMarks[8] := 10000;
FreqMarks[9] := 20000;
Canvas.Pen.Color := FClrGrid;
Canvas.Font.Size := 8;
for i := 0 to High(FreqMarks) do
begin
X := R.Left + Round(Ln(FreqMarks[i] / MIN_FREQ) / Ln(MAX_FREQ / MIN_FREQ) *
(R.Right - R.Left));
Canvas.Line(X, R.Top + 1, X, R.Bottom - 1);
end;
for i := -20 to 20 do
if (i mod 5) = 0 then
begin
Y := GainToY(i, R);
Canvas.Line(R.Left + 1, Y, R.Right - 1, Y);
Canvas.Brush.Style := bsClear;
Canvas.Font.Color := FClrTextDim;
if (i <> 0) and (Abs(i) <> 5) and (i >= -15) and (i <= 15) then
begin
if i > 0 then S := '+' + IntToStr(i) + 'dB'
else S := IntToStr(i) + 'dB';
Canvas.TextOut(R.Left + 4, Y - (Canvas.TextHeight(S) * 3 div 5), S);
end;
end;
ZeroY := GainToY(0, R);
Canvas.Pen.Color := FClrBorder;
Canvas.Line(R.Left + 1, ZeroY, R.Right - 1, ZeroY);
Canvas.Brush.Color := TColor($00304438);
Canvas.Pen.Color := TColor($00304438);
FillBottom := ZeroY;
LastFillY := ZeroY;
CurveL := R.Left + 2;
CurveR := R.Right - 2;
for GX := CurveL to CurveR do
begin
F := XToFreq(GX, R);
G := ResponseAtFreq(F);
GY := GainToY(EnsureRange(G, MIN_GAIN, MAX_GAIN), R);
if GX = R.Left then
LastFillY := GY
else
Canvas.Polygon([Point(GX - 1, LastFillY), Point(GX, GY),
Point(GX, FillBottom), Point(GX - 1, FillBottom)]);
LastFillY := GY;
end;
PrevX := CurveL;
PrevY := GainToY(EnsureRange(ResponseAtFreq(XToFreq(CurveL, R)), MIN_GAIN, MAX_GAIN), R);
Canvas.Pen.Color := FClrCurve;
Canvas.Pen.Width := 2;
for GX := CurveL + 1 to CurveR do
begin
F := XToFreq(GX, R);
GY := GainToY(EnsureRange(ResponseAtFreq(F), MIN_GAIN, MAX_GAIN), R);
Canvas.Line(PrevX, PrevY, GX, GY);
PrevX := GX;
PrevY := GY;
end;
Canvas.Pen.Width := 1;
N := FBandCount;
for i := 1 to N do
begin
X := BandX(i, R);
Y := GainToY(FGains[i], R);
Canvas.Brush.Color := BandColor(i);
Canvas.Pen.Color := FClrBG;
Canvas.Ellipse(X - 5, Y - 5, X + 6, Y + 6);
if i = FHover then
begin
Canvas.Brush.Style := bsClear;
Canvas.Pen.Color := clWhite;
Canvas.Ellipse(X - 9, Y - 9, X + 10, Y + 10);
Canvas.Brush.Style := bsSolid;
end;
end;
Canvas.Font.Color := FClrTextDim;
Canvas.Brush.Style := bsClear;
Canvas.Font.Size := 8;
AxisY := ZeroY + 4;
for i := 0 to High(FreqMarks) do
begin
X := R.Left + Round(Ln(FreqMarks[i] / MIN_FREQ) / Ln(MAX_FREQ / MIN_FREQ) *
(R.Right - R.Left));
S := FormatFreq(FreqMarks[i]);
if i = 0 then
Canvas.TextOut(X, AxisY, S)
else if i = High(FreqMarks) then
Canvas.TextOut(X - Canvas.TextWidth(S), AxisY, S)
else
Canvas.TextOut(X - Canvas.TextWidth(S) div 2, AxisY, S);
end;
Canvas.Font.Size := 9;
DrawTiles;
end;
procedure TEqualizerControl.Resize;
begin
inherited Resize;
LayoutButtons;
end;
procedure TEqualizerControl.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
H: Integer;
begin
inherited MouseDown(Button, Shift, X, Y);
if Button <> mbLeft then Exit;
H := HitTestControl(X, Y);
case H of
-1:
begin
FDragging := -1;
PreampGain := YToGain(Y, PreampRect);
end;
1..10:
begin
FDragging := H;
BandGain[H] := YToGain(Y, GraphRect);
BandFreq[H] := XToFreq(X, GraphRect);
end;
end;
end;
procedure TEqualizerControl.MouseMove(Shift: TShiftState; X, Y: Integer);
var
H: Integer;
begin
inherited MouseMove(Shift, X, Y);
if FDragging = -1 then
PreampGain := YToGain(Y, PreampRect)
else if FDragging > 0 then
begin
BandGain[FDragging] := YToGain(Y, GraphRect);
BandFreq[FDragging] := XToFreq(X, GraphRect);
end
else
begin
H := HitTestControl(X, Y);
if H < 0 then H := 0;
if FHover <> H then
begin
FHover := H;
Invalidate;
end;
end;
end;
procedure TEqualizerControl.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
inherited MouseUp(Button, Shift, X, Y);
FDragging := 0;
end;
procedure TEqualizerControl.MouseLeave;
begin
inherited MouseLeave;
FHover := 0;
Invalidate;
end;
function TEqualizerControl.DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean;
var
H: Integer;
begin
H := HitTestControl(MousePos.X, MousePos.Y);
if H = -1 then PreampGain := FPreampGain + 0.5
else if H > 0 then BandGain[H] := FGains[H] + 0.5;
Result := H <> 0;
end;
function TEqualizerControl.DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean;
var
H: Integer;
begin
H := HitTestControl(MousePos.X, MousePos.Y);
if H = -1 then PreampGain := FPreampGain - 0.5
else if H > 0 then BandGain[H] := FGains[H] - 0.5;
Result := H <> 0;
end;
end.
+72 -76
View File
@@ -27,7 +27,7 @@ uses
Classes, SysUtils, Math, Classes, SysUtils, Math,
Forms, Controls, Graphics, Dialogs, Forms, Controls, Graphics, Dialogs,
StdCtrls, ExtCtrls, Spin, StdCtrls, ExtCtrls, Spin,
FlatButton, AudioOutput, AudioInput, AppTheme, Settings; FlatButton, EqualizerControl, AudioOutput, AudioInput, AppTheme, Settings;
type type
// PA: MaxPower в Вт, BandCal[0..10] — калибровка 38.8..100.0 на диапазон // PA: MaxPower в Вт, BandCal[0..10] — калибровка 38.8..100.0 на диапазон
@@ -164,10 +164,7 @@ type
FEdTXPHRStages: TSpinEdit; FEdTXPHRStages: TSpinEdit;
FEdTXPHRFreq: TFloatSpinEdit; FEdTXPHRFreq: TFloatSpinEdit;
// EQ // EQ
FChkTXEQOn: TCheckBox; FTXEQControl: TEqualizerControl;
FCmbTXEQBands: TComboBox;
FEdTXEQGain: array[0..10] of TFloatSpinEdit;
FEdTXEQFreq: array[0..10] of TFloatSpinEdit;
// AM // AM
FEdTXAMCarrier: TFloatSpinEdit; FEdTXAMCarrier: TFloatSpinEdit;
// FM // FM
@@ -1007,10 +1004,10 @@ const
PAD = 18; PAD = 18;
LW = 150; LW = 150;
CX = PAD + LW + 12; CX = PAD + LW + 12;
STEP = 32; STEP = 42;
R1 = 42; R1 = 42;
SPW = 96; SPW = 96;
CMB_W = 200; GRP_W = 760;
var var
Grp: TPanel; Grp: TPanel;
@@ -1090,7 +1087,7 @@ begin
// ---- Mic options ---- // ---- Mic options ----
// Mic source (Radio vs SoundCard) определяется автоматически по источнику PTT. // Mic source (Radio vs SoundCard) определяется автоматически по источнику PTT.
Y := 86; Y := 86;
Grp := MakeGroupPanel(FPageTransmit, 'Microphone', MARGIN, Y, 700, 188); Grp := MakeGroupPanel(FPageTransmit, 'Microphone', MARGIN, Y, GRP_W, 188);
// Row 0: Mic jack selector | Boost (Mic In) или LineInGain (Line In) | Bias | PTT // Row 0: Mic jack selector | Boost (Mic In) или LineInGain (Line In) | Bias | PTT
MakeLbl(Grp, 'Mic jack', PAD, R1 + 5, 65); MakeLbl(Grp, 'Mic jack', PAD, R1 + 5, 65);
@@ -1124,7 +1121,7 @@ begin
// ---- Tune (TUN button) ---- // ---- Tune (TUN button) ----
Inc(Y, 188 + 12); Inc(Y, 188 + 12);
Grp := MakeGroupPanel(FPageTransmit, 'Tune (TUN)', MARGIN, Y, 700, 100); Grp := MakeGroupPanel(FPageTransmit, 'Tune (TUN)', MARGIN, Y, GRP_W, 100);
MakeLbl(Grp, 'Tune level (%)', PAD, R1 + 5, LW); MakeLbl(Grp, 'Tune level (%)', PAD, R1 + 5, LW);
FEdTUNLevel := MkSpin(Grp, CX, R1, 0, 100, 10); FEdTUNLevel := MkSpin(Grp, CX, R1, 0, 100, 10);
@@ -1133,7 +1130,7 @@ begin
// ---- TX bandpass filter ---- // ---- TX bandpass filter ----
Inc(Y, 100 + 12); Inc(Y, 100 + 12);
Grp := MakeGroupPanel(FPageTransmit, 'TX Filter (bandpass)', MARGIN, Y, 700, 200); Grp := MakeGroupPanel(FPageTransmit, 'TX Filter (bandpass)', MARGIN, Y, GRP_W, 220);
MakeLbl(Grp, 'Low cut (Hz)', PAD, R1 + 5, LW); MakeLbl(Grp, 'Low cut (Hz)', PAD, R1 + 5, LW);
FEdTXFiltLow := MkSpin(Grp, CX, R1, 0, 8000, 100); FEdTXFiltLow := MkSpin(Grp, CX, R1, 0, 8000, 100);
@@ -1157,8 +1154,8 @@ begin
FCmbTXFiltWindow.ItemIndex := 1; FCmbTXFiltWindow.ItemIndex := 1;
// ---- Compressor / Leveler / ALC / Phase Rotator ---- // ---- Compressor / Leveler / ALC / Phase Rotator ----
Inc(Y, 200 + 12); Inc(Y, 220 + 12);
Grp := MakeGroupPanel(FPageTransmit, 'Dynamic processing', MARGIN, Y, 700, 220); Grp := MakeGroupPanel(FPageTransmit, 'Dynamic processing', MARGIN, Y, GRP_W, 220);
FChkTXCompOn := MkChk(Grp, PAD, R1, 220, 'Compressor'); FChkTXCompOn := MkChk(Grp, PAD, R1, 220, 'Compressor');
MakeLbl(Grp, 'Gain (dB)', PAD + 230, R1 + 5, 80); MakeLbl(Grp, 'Gain (dB)', PAD + 230, R1 + 5, 80);
@@ -1184,31 +1181,20 @@ begin
// ---- TX EQ ---- // ---- TX EQ ----
Inc(Y, 220 + 12); Inc(Y, 220 + 12);
Grp := MakeGroupPanel(FPageTransmit, 'TX Equalizer', MARGIN, Y, 700, 320); Grp := MakeGroupPanel(FPageTransmit, 'TX Equalizer', MARGIN, Y, GRP_W, 390);
FChkTXEQOn := MkChk(Grp, PAD, R1, 200, 'Enable EQ'); FTXEQControl := TEqualizerControl.Create(Self);
MakeLbl(Grp, 'Bands', PAD + 230, R1 + 5, 60); FTXEQControl.Parent := Grp;
FCmbTXEQBands := MkCmb(Grp, PAD + 290, R1, 80); FTXEQControl.SetBounds(PAD, R1, GRP_W - 2 * PAD, 326);
FCmbTXEQBands.Items.AddStrings(['3','10']); FTXEQControl.Font.Name := UI_FONT;
FCmbTXEQBands.ItemIndex := 1; FTXEQControl.Font.Size := 9;
FTXEQControl.SetThemeColors(CLR_PANEL, TColor($00202020), CLR_BORDER,
// 11 строк: [0]=Preamp, [1..10]=полосы. Freq+Gain в одной строке. TColor($00383838), CLR_TEXT, CLR_TEXTDIM, CLR_ACCENT, TColor($0055DDEE));
for i := 0 to 10 do FTXEQControl.OnChange := OnTXAnyChange;
begin
if i = 0 then
MakeLbl(Grp, 'Preamp (dB)', PAD, R1 + STEP + i * 22 + 3, 100)
else
MakeLbl(Grp, Format('Band %d', [i]), PAD, R1 + STEP + i * 22 + 3, 80);
FEdTXEQFreq[i] := MkFloat(Grp, PAD + 90, R1 + STEP + i * 22, 0.0, 0.0, 20000.0, 10.0);
FEdTXEQFreq[i].Width := 100;
MakeLbl(Grp, 'gain', PAD + 200, R1 + STEP + i * 22 + 3, 30);
FEdTXEQGain[i] := MkFloat(Grp, PAD + 230, R1 + STEP + i * 22, 0.0, -15.0, 15.0, 0.5);
FEdTXEQGain[i].Width := 80;
end;
// ---- AM / FM / CTCSS ---- // ---- AM / FM / CTCSS ----
Inc(Y, 320 + 12); Inc(Y, 390 + 12);
Grp := MakeGroupPanel(FPageTransmit, 'AM / FM / CTCSS', MARGIN, Y, 700, 220); Grp := MakeGroupPanel(FPageTransmit, 'AM / FM / CTCSS', MARGIN, Y, GRP_W, 260);
MakeLbl(Grp, 'AM carrier level', PAD, R1 + 5, LW); MakeLbl(Grp, 'AM carrier level', PAD, R1 + 5, LW);
FEdTXAMCarrier := MkFloat(Grp, CX, R1, 0.5, 0.0, 1.0, 0.05); FEdTXAMCarrier := MkFloat(Grp, CX, R1, 0.5, 0.0, 1.0, 0.05);
@@ -1231,8 +1217,8 @@ begin
FEdTXCTCSSFreq := MkFloat(Grp, PAD + 320, R1 + 4 * STEP, 100.0, 50.0, 300.0, 0.1); FEdTXCTCSSFreq := MkFloat(Grp, PAD + 320, R1 + 4 * STEP, 100.0, 50.0, 300.0, 0.1);
// ---- TX Display (отдельный analyzer для TX-спектра/водопада) ---- // ---- TX Display (отдельный analyzer для TX-спектра/водопада) ----
Inc(Y, 220 + 12); Inc(Y, 260 + 12);
Grp := MakeGroupPanel(FPageTransmit, 'TX Display (Analyzer)', MARGIN, Y, 700, 290); Grp := MakeGroupPanel(FPageTransmit, 'TX Display (Analyzer)', MARGIN, Y, GRP_W, 318);
MakeLbl(Grp, 'FFT size', PAD, R1 + 5, LW); MakeLbl(Grp, 'FFT size', PAD, R1 + 5, LW);
FCmbTXFFT := MkCmb(Grp, CX, R1, 140); FCmbTXFFT := MkCmb(Grp, CX, R1, 140);
@@ -1269,8 +1255,8 @@ begin
FEdTXWfAvgTime := MkFloat(Grp, PAD + 540, R1 + 5 * STEP, 120.0, 1.0, 5000.0, 1.0); FEdTXWfAvgTime := MkFloat(Grp, PAD + 540, R1 + 5 * STEP, 120.0, 1.0, 5000.0, 1.0);
// ---- TX Grid (RefLevel / Range / GridStep — отдельные от RX) ---- // ---- TX Grid (RefLevel / Range / GridStep — отдельные от RX) ----
Inc(Y, 290 + 12); Inc(Y, 318 + 12);
Grp := MakeGroupPanel(FPageTransmit, 'TX Grid', MARGIN, Y, 700, 170); Grp := MakeGroupPanel(FPageTransmit, 'TX Grid', MARGIN, Y, GRP_W, 170);
MakeLbl(Grp, 'Reference level', PAD, R1 + 5, LW); MakeLbl(Grp, 'Reference level', PAD, R1 + 5, LW);
FEdTXRefLevel := TEdit.Create(Self); FEdTXRefLevel := TEdit.Create(Self);
@@ -1330,13 +1316,16 @@ begin
if FChkTXPHROn <> nil then FTX.PhaseRotOn := FChkTXPHROn.Checked; if FChkTXPHROn <> nil then FTX.PhaseRotOn := FChkTXPHROn.Checked;
if FEdTXPHRStages <> nil then FTX.PhaseRotStages := FEdTXPHRStages.Value; if FEdTXPHRStages <> nil then FTX.PhaseRotStages := FEdTXPHRStages.Value;
if FEdTXPHRFreq <> nil then FTX.PhaseRotFreq := FEdTXPHRFreq.Value; if FEdTXPHRFreq <> nil then FTX.PhaseRotFreq := FEdTXPHRFreq.Value;
if FChkTXEQOn <> nil then FTX.EQOn := FChkTXEQOn.Checked; if FTXEQControl <> nil then
if FCmbTXEQBands <> nil then
if FCmbTXEQBands.ItemIndex = 0 then FTX.EQNumBands := 3 else FTX.EQNumBands := 10;
for i := 0 to 10 do
begin begin
if FEdTXEQGain[i] <> nil then FTX.EQGains[i] := FEdTXEQGain[i].Value; FTX.EQOn := FTXEQControl.EQEnabled;
if FEdTXEQFreq[i] <> nil then FTX.EQFreqs[i] := FEdTXEQFreq[i].Value; FTX.EQNumBands := FTXEQControl.BandCount;
FTX.EQGains[0] := FTXEQControl.PreampGain;
for i := 1 to 10 do
begin
FTX.EQGains[i] := FTXEQControl.BandGain[i];
FTX.EQFreqs[i] := FTXEQControl.BandFreq[i];
end;
end; end;
if FEdTXAMCarrier <> nil then FTX.AMCarrierLevel := FEdTXAMCarrier.Value; if FEdTXAMCarrier <> nil then FTX.AMCarrierLevel := FEdTXAMCarrier.Value;
if FEdTXFMDev <> nil then FTX.FMDeviation := FEdTXFMDev.Value; if FEdTXFMDev <> nil then FTX.FMDeviation := FEdTXFMDev.Value;
@@ -1443,14 +1432,13 @@ begin
if FChkTXPHROn <> nil then FChkTXPHROn.Checked := T.PhaseRotOn; if FChkTXPHROn <> nil then FChkTXPHROn.Checked := T.PhaseRotOn;
if FEdTXPHRStages <> nil then FEdTXPHRStages.Value := T.PhaseRotStages; if FEdTXPHRStages <> nil then FEdTXPHRStages.Value := T.PhaseRotStages;
if FEdTXPHRFreq <> nil then FEdTXPHRFreq.Value := T.PhaseRotFreq; if FEdTXPHRFreq <> nil then FEdTXPHRFreq.Value := T.PhaseRotFreq;
if FChkTXEQOn <> nil then FChkTXEQOn.Checked := T.EQOn; if FTXEQControl <> nil then
if FCmbTXEQBands <> nil then
if T.EQNumBands <= 3 then FCmbTXEQBands.ItemIndex := 0
else FCmbTXEQBands.ItemIndex := 1;
for i := 0 to 10 do
begin begin
if FEdTXEQGain[i] <> nil then FEdTXEQGain[i].Value := T.EQGains[i]; FTXEQControl.EQEnabled := T.EQOn;
if FEdTXEQFreq[i] <> nil then FEdTXEQFreq[i].Value := T.EQFreqs[i]; FTXEQControl.BandCount := T.EQNumBands;
FTXEQControl.PreampGain := T.EQGains[0];
for i := 1 to 10 do
FTXEQControl.SetBand(i, T.EQFreqs[i], T.EQGains[i]);
end; end;
if FEdTXAMCarrier <> nil then FEdTXAMCarrier.Value := T.AMCarrierLevel; if FEdTXAMCarrier <> nil then FEdTXAMCarrier.Value := T.AMCarrierLevel;
if FEdTXFMDev <> nil then FEdTXFMDev.Value := T.FMDeviation; if FEdTXFMDev <> nil then FEdTXFMDev.Value := T.FMDeviation;
@@ -1523,10 +1511,13 @@ end;
procedure TSettingsForm.BuildPATab; procedure TSettingsForm.BuildPATab;
const const
MARGIN = 22; MARGIN = 22;
LBL_W = 46; LBL_W = 54;
ED_W = 72; ED_W = 72;
COL_W = LBL_W + ED_W + 8; COL_W = LBL_W + ED_W + 14;
COLS = 4; COLS = 4;
VHF_LBL_W = 170;
VHF_COL_W = VHF_LBL_W + ED_W + 48;
VHF_COLS = 2;
ROW_H = 32; ROW_H = 32;
GRP_PAD = 18; GRP_PAD = 18;
R1 = 42; R1 = 42;
@@ -1579,7 +1570,7 @@ begin
Font.Color := CLR_TEXTDIM; Font.Color := CLR_TEXTDIM;
end; end;
Grp := MakeGroupPanel(FPagePA, 'Power && Calibration', MARGIN, 86, 650, GRP_H); Grp := MakeGroupPanel(FPagePA, 'Power && Calibration', MARGIN, 86, 700, GRP_H);
// Max Power // Max Power
Lbl := TLabel.Create(Self); Lbl := TLabel.Create(Self);
@@ -1635,33 +1626,35 @@ begin
// ── VHF Calibration (Transverters) ────────────────────────────────────── // ── VHF Calibration (Transverters) ──────────────────────────────────────
Grp := MakeGroupPanel(FPagePA, 'VHF Calibration (Transverters)', Grp := MakeGroupPanel(FPagePA, 'VHF Calibration (Transverters)',
MARGIN, 86 + GRP_H + 14, 650, 2 * ROW_H + 62); MARGIN, 86 + GRP_H + 14, 700, R1 + 4 * ROW_H + 44);
Lbl := TLabel.Create(Self); Lbl := TLabel.Create(Self);
Lbl.Parent := Grp; Lbl.Parent := Grp;
Lbl.Caption := 'Calibration per transverter slot, 38.8 ... 100.0'; Lbl.Caption := 'Calibration per transverter slot, 38.8 ... 100.0';
Lbl.SetBounds(GRP_PAD, 16, 400, 18); Lbl.SetBounds(GRP_PAD, R1, 420, 18);
Lbl.Font.Color := CLR_TEXTDIM; Lbl.Font.Color := CLR_TEXTDIM;
Lbl.Font.Name := UI_FONT; Lbl.Font.Name := UI_FONT;
Lbl.Font.Size := 9; Lbl.Font.Size := 9;
for i := 0 to CFG_XVTR_COUNT - 1 do for i := 0 to CFG_XVTR_COUNT - 1 do
begin begin
r := i div COLS; r := i div VHF_COLS;
c := i mod COLS; c := i mod VHF_COLS;
X := GRP_PAD + c * (COL_W + 4); X := GRP_PAD + c * VHF_COL_W;
Y := 38 + r * ROW_H; Y := R1 + 24 + r * ROW_H;
Lbl := TLabel.Create(Self); Lbl := TLabel.Create(Self);
Lbl.Parent := Grp; Lbl.Parent := Grp;
Lbl.Caption := 'VHF' + IntToStr(i) + ':'; Lbl.Caption := 'VHF' + IntToStr(i) + ':';
Lbl.SetBounds(X, Y + 5, LBL_W, 18); Lbl.AutoSize := False;
Lbl.SetBounds(X, Y + 5, VHF_LBL_W, 18);
Lbl.Font.Color := CLR_TEXTDIM; Lbl.Font.Color := CLR_TEXTDIM;
Lbl.Font.Name := UI_FONT; Lbl.Font.Name := UI_FONT;
Lbl.Font.Size := 9; Lbl.Font.Size := 9;
Lbl.ShowHint := True;
FVHFCalLabels[i] := Lbl; FVHFCalLabels[i] := Lbl;
FEdVHFCal[i] := MakeFloatSpin(Grp, X + LBL_W, Y, OnVHFCalEdit); FEdVHFCal[i] := MakeFloatSpin(Grp, X + VHF_LBL_W + 8, Y, OnVHFCalEdit);
FEdVHFCal[i].Tag := i; FEdVHFCal[i].Tag := i;
end; end;
@@ -1673,8 +1666,8 @@ const
GRP_PAD = 18; GRP_PAD = 18;
LBL_W = 110; LBL_W = 110;
ED_W = 200; ED_W = 200;
BTN_H = 22; ROW_H = 42;
ROW_H = 28; R1 = 42;
var var
Grp: TPanel; Grp: TPanel;
Chk: TCheckBox; Chk: TCheckBox;
@@ -1694,12 +1687,12 @@ begin
end; end;
// ── ADC ─────────────────────────────────────────────────────────────────── // ── ADC ───────────────────────────────────────────────────────────────────
Grp := MakeGroupPanel(FPageAdvanced, 'ADC', MARGIN, 62, 420, 82); Grp := MakeGroupPanel(FPageAdvanced, 'ADC', MARGIN, 86, 420, 128);
Chk := TCheckBox.Create(Self); Chk := TCheckBox.Create(Self);
Chk.Parent := Grp; Chk.Parent := Grp;
Chk.Caption := 'Dither Enabled'; Chk.Caption := 'Dither Enabled';
Chk.SetBounds(GRP_PAD, 24, 260, BTN_H); Chk.SetBounds(GRP_PAD, R1, 260, 22);
Chk.Font.Name := UI_FONT; Chk.Font.Name := UI_FONT;
Chk.Font.Size := 9; Chk.Font.Size := 9;
Chk.Font.Color := CLR_TEXT; Chk.Font.Color := CLR_TEXT;
@@ -1710,7 +1703,7 @@ begin
Chk := TCheckBox.Create(Self); Chk := TCheckBox.Create(Self);
Chk.Parent := Grp; Chk.Parent := Grp;
Chk.Caption := 'Random Enabled'; Chk.Caption := 'Random Enabled';
Chk.SetBounds(GRP_PAD, 50, 260, BTN_H); Chk.SetBounds(GRP_PAD, R1 + ROW_H, 260, 22);
Chk.Font.Name := UI_FONT; Chk.Font.Name := UI_FONT;
Chk.Font.Size := 9; Chk.Font.Size := 9;
Chk.Font.Color := CLR_TEXT; Chk.Font.Color := CLR_TEXT;
@@ -1719,13 +1712,13 @@ begin
FChkRandom := Chk; FChkRandom := Chk;
// ── Web Server ──────────────────────────────────────────────────────────── // ── Web Server ────────────────────────────────────────────────────────────
Grp := MakeGroupPanel(FPageAdvanced, 'Web Server', MARGIN, 160, 420, 196); Grp := MakeGroupPanel(FPageAdvanced, 'Web Server', MARGIN, 230, 500, 252);
Y := 24; Y := R1;
Chk := TCheckBox.Create(Self); Chk := TCheckBox.Create(Self);
Chk.Parent := Grp; Chk.Parent := Grp;
Chk.Caption := 'Enabled'; Chk.Caption := 'Enabled';
Chk.SetBounds(GRP_PAD, Y, 260, BTN_H); Chk.SetBounds(GRP_PAD, Y, 260, 22);
Chk.Font.Name := UI_FONT; Chk.Font.Name := UI_FONT;
Chk.Font.Size := 9; Chk.Font.Size := 9;
Chk.Font.Color := CLR_TEXT; Chk.Font.Color := CLR_TEXT;
@@ -1733,11 +1726,11 @@ begin
Chk.OnChange := OnWebAnyChange; Chk.OnChange := OnWebAnyChange;
FChkWebEnabled := Chk; FChkWebEnabled := Chk;
Y := Y + ROW_H + 4; Y := Y + ROW_H;
MakeLbl(Grp, 'Port:', GRP_PAD, Y + 4, LBL_W); MakeLbl(Grp, 'Port:', GRP_PAD, Y + 4, LBL_W);
Spin := TSpinEdit.Create(Self); Spin := TSpinEdit.Create(Self);
Spin.Parent := Grp; Spin.Parent := Grp;
Spin.SetBounds(GRP_PAD + LBL_W, Y, 90, BTN_H + 2); Spin.SetBounds(GRP_PAD + LBL_W + 12, Y, 90, BTN_H);
Spin.Color := CLR_INPUT; Spin.Color := CLR_INPUT;
Spin.Font.Color := CLR_INPUT_TEXT; Spin.Font.Color := CLR_INPUT_TEXT;
Spin.Font.Name := UI_FONT; Spin.Font.Name := UI_FONT;
@@ -1752,7 +1745,7 @@ begin
MakeLbl(Grp, 'Interface:', GRP_PAD, Y + 4, LBL_W); MakeLbl(Grp, 'Interface:', GRP_PAD, Y + 4, LBL_W);
Ed := TEdit.Create(Self); Ed := TEdit.Create(Self);
Ed.Parent := Grp; Ed.Parent := Grp;
Ed.SetBounds(GRP_PAD + LBL_W, Y, ED_W, BTN_H + 2); Ed.SetBounds(GRP_PAD + LBL_W + 12, Y, ED_W, BTN_H);
Ed.Color := CLR_INPUT; Ed.Color := CLR_INPUT;
Ed.Font.Color := CLR_INPUT_TEXT; Ed.Font.Color := CLR_INPUT_TEXT;
Ed.Font.Name := UI_FONT; Ed.Font.Name := UI_FONT;
@@ -1765,7 +1758,7 @@ begin
MakeLbl(Grp, 'Username:', GRP_PAD, Y + 4, LBL_W); MakeLbl(Grp, 'Username:', GRP_PAD, Y + 4, LBL_W);
Ed := TEdit.Create(Self); Ed := TEdit.Create(Self);
Ed.Parent := Grp; Ed.Parent := Grp;
Ed.SetBounds(GRP_PAD + LBL_W, Y, ED_W, BTN_H + 2); Ed.SetBounds(GRP_PAD + LBL_W + 12, Y, ED_W, BTN_H);
Ed.Color := CLR_INPUT; Ed.Color := CLR_INPUT;
Ed.Font.Color := CLR_INPUT_TEXT; Ed.Font.Color := CLR_INPUT_TEXT;
Ed.Font.Name := UI_FONT; Ed.Font.Name := UI_FONT;
@@ -1778,7 +1771,7 @@ begin
MakeLbl(Grp, 'Password:', GRP_PAD, Y + 4, LBL_W); MakeLbl(Grp, 'Password:', GRP_PAD, Y + 4, LBL_W);
Ed := TEdit.Create(Self); Ed := TEdit.Create(Self);
Ed.Parent := Grp; Ed.Parent := Grp;
Ed.SetBounds(GRP_PAD + LBL_W, Y, ED_W, BTN_H + 2); Ed.SetBounds(GRP_PAD + LBL_W + 12, Y, ED_W, BTN_H);
Ed.Color := CLR_INPUT; Ed.Color := CLR_INPUT;
Ed.Font.Color := CLR_INPUT_TEXT; Ed.Font.Color := CLR_INPUT_TEXT;
Ed.Font.Name := UI_FONT; Ed.Font.Name := UI_FONT;
@@ -1853,7 +1846,9 @@ procedure TSettingsForm.ApplyTheme(const T: TAppTheme);
for i := 0 to C.ControlCount - 1 do for i := 0 to C.ControlCount - 1 do
begin begin
Ctrl := C.Controls[i]; Ctrl := C.Controls[i];
if Ctrl is TFlatButton then if Ctrl is TEqualizerControl then
TEqualizerControl(Ctrl).SetAppTheme(T)
else if Ctrl is TFlatButton then
StyleBtn(TFlatButton(Ctrl)) StyleBtn(TFlatButton(Ctrl))
else if Ctrl is TScrollBox then else if Ctrl is TScrollBox then
begin begin
@@ -3219,6 +3214,7 @@ begin
FVHFCalLabels[i].Caption := 'VHF' + IntToStr(i) + ' (' + X.Entries[i].ButtonText + '):' FVHFCalLabels[i].Caption := 'VHF' + IntToStr(i) + ' (' + X.Entries[i].ButtonText + '):'
else else
FVHFCalLabels[i].Caption := 'VHF' + IntToStr(i) + ':'; FVHFCalLabels[i].Caption := 'VHF' + IntToStr(i) + ':';
FVHFCalLabels[i].Hint := FVHFCalLabels[i].Caption;
end; end;
end; end;
if FChkXvtrTunPwr <> nil then FChkXvtrTunPwr.Checked := X.UseXVTRTunePower; if FChkXvtrTunPwr <> nil then FChkXvtrTunPwr.Checked := X.UseXVTRTunePower;
+4
View File
@@ -123,6 +123,10 @@
<Filename Value="FlatSlider.pas"/> <Filename Value="FlatSlider.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
</Unit> </Unit>
<Unit>
<Filename Value="EqualizerControl.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit> <Unit>
<Filename Value="FreqDisplay.pas"/> <Filename Value="FreqDisplay.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>