mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
add gradient
This commit is contained in:
+102
-33
@@ -318,6 +318,8 @@ type
|
|||||||
BtnSNB: TFlatButton;
|
BtnSNB: TFlatButton;
|
||||||
BtnANF: TFlatButton;
|
BtnANF: TFlatButton;
|
||||||
BtnMute: TFlatButton;
|
BtnMute: TFlatButton;
|
||||||
|
BtnWfAGC: TFlatButton;
|
||||||
|
BtnWfNF: TFlatButton;
|
||||||
|
|
||||||
PanelSMeterRight: TPanel; // контейнер S-метра справа
|
PanelSMeterRight: TPanel; // контейнер S-метра справа
|
||||||
PbSMeterRight: TPaintBox;// новый большой S-метр справа
|
PbSMeterRight: TPaintBox;// новый большой S-метр справа
|
||||||
@@ -342,8 +344,6 @@ type
|
|||||||
BtnSpan384k: TFlatButton;
|
BtnSpan384k: TFlatButton;
|
||||||
BtnSpan768k: TFlatButton;
|
BtnSpan768k: TFlatButton;
|
||||||
BtnSpan1536k: TFlatButton;
|
BtnSpan1536k: TFlatButton;
|
||||||
BtnWfAGC: TFlatButton;
|
|
||||||
BtnWfNF: TFlatButton;
|
|
||||||
BtnHidePanel: TFlatButton; // скрыть/показать левую панель
|
BtnHidePanel: TFlatButton; // скрыть/показать левую панель
|
||||||
PbSpectrum: TPaintBox;
|
PbSpectrum: TPaintBox;
|
||||||
PbRuler: TPaintBox; // полоса частотных меток между спектром и водопадом
|
PbRuler: TPaintBox; // полоса частотных меток между спектром и водопадом
|
||||||
@@ -1161,7 +1161,7 @@ begin
|
|||||||
// RX controls
|
// RX controls
|
||||||
PanelRX := TPanel.Create(Self);
|
PanelRX := TPanel.Create(Self);
|
||||||
PanelRX.Parent := PanelLeft;
|
PanelRX.Parent := PanelLeft;
|
||||||
PanelRX.SetBounds(0, Y, LEFT_W, 120);
|
PanelRX.SetBounds(0, Y, LEFT_W, 150);
|
||||||
PanelRX.BevelOuter := bvNone;
|
PanelRX.BevelOuter := bvNone;
|
||||||
|
|
||||||
// AGC mode — 5 кнопок в ряд
|
// AGC mode — 5 кнопок в ряд
|
||||||
@@ -1207,8 +1207,10 @@ begin
|
|||||||
BtnSNB := MakeBtn(PanelRX, 'SNB', 2*W+6, 96, W, BTN_SM, BtnSNBClick);
|
BtnSNB := MakeBtn(PanelRX, 'SNB', 2*W+6, 96, W, BTN_SM, BtnSNBClick);
|
||||||
BtnANF := MakeBtn(PanelRX, 'ANF', 3*W+8, 96, W, BTN_SM, BtnANFClick);
|
BtnANF := MakeBtn(PanelRX, 'ANF', 3*W+8, 96, W, BTN_SM, BtnANFClick);
|
||||||
BtnMute:= MakeBtn(PanelRX, 'MUTE', 4*W+10, 96, W, BTN_SM, BtnMuteClick);
|
BtnMute:= MakeBtn(PanelRX, 'MUTE', 4*W+10, 96, W, BTN_SM, BtnMuteClick);
|
||||||
|
BtnWfAGC := MakeBtn(PanelRX, 'WF AGC', 2, 122, (LEFT_W - 6) div 2, BTN_SM, BtnWfAGCClick);
|
||||||
|
BtnWfNF := MakeBtn(PanelRX, 'WF NF', 4 + (LEFT_W - 6) div 2, 122, (LEFT_W - 6) div 2, BTN_SM, BtnWfNFClick);
|
||||||
|
|
||||||
Inc(Y, 124);
|
Inc(Y, 154);
|
||||||
|
|
||||||
// S-Meter
|
// S-Meter
|
||||||
|
|
||||||
@@ -1294,10 +1296,15 @@ begin
|
|||||||
StyleSpanButton(BtnSpan768k, False);
|
StyleSpanButton(BtnSpan768k, False);
|
||||||
StyleSpanButton(BtnSpan1536k, False);
|
StyleSpanButton(BtnSpan1536k, False);
|
||||||
|
|
||||||
// Waterfall AGC + Noise Floor кнопки справа в той же панели
|
BtnHidePanel := MakeBtn(PanelRight, '◀', 0, 0, 28, 28, BtnHidePanelClick);
|
||||||
BtnWfAGC := MakeBtn(PanelSpanButtons, 'WF AGC', 379, 3, 62, BTN_SM, BtnWfAGCClick);
|
BtnHidePanel.Font.Size := 10;
|
||||||
BtnWfNF := MakeBtn(PanelSpanButtons, 'WF NF', 445, 3, 58, BTN_SM, BtnWfNFClick);
|
BtnHidePanel.ClrNorm := TColor($00543F18);
|
||||||
BtnHidePanel := MakeBtn(PanelSpanButtons, '◀ HIDE', 510, 3, 64, BTN_SM, BtnHidePanelClick);
|
BtnHidePanel.ClrHot := TColor($00624B1D);
|
||||||
|
BtnHidePanel.ClrActive := TColor($00624B1D);
|
||||||
|
BtnHidePanel.ClrBorder := TColor($00685624);
|
||||||
|
BtnHidePanel.ClrText := TColor($00D8E6EE);
|
||||||
|
BtnHidePanel.ClrTextAct := TColor($00F0FAFF);
|
||||||
|
BtnHidePanel.BringToFront;
|
||||||
|
|
||||||
// Большой S-метр — на главной форме поверх двух панелей
|
// Большой S-метр — на главной форме поверх двух панелей
|
||||||
// S-метр: Parent=Self, перекрывает Toolbar+SpanButtons вертикально
|
// S-метр: Parent=Self, перекрывает Toolbar+SpanButtons вертикально
|
||||||
@@ -1359,7 +1366,6 @@ procedure TMainForm.ResizeSMeter;
|
|||||||
// По Y: от самого верха формы до низа PanelSpanButtons (Toolbar+Span = 66px).
|
// По Y: от самого верха формы до низа PanelSpanButtons (Toolbar+Span = 66px).
|
||||||
// По X: 40% ширины PanelRight, прижат к правому краю.
|
// По X: 40% ширины PanelRight, прижат к правому краю.
|
||||||
const
|
const
|
||||||
LEFT_PANEL_W = 232; // ширина левой панели (LEFT_W)
|
|
||||||
MARGIN = 3;
|
MARGIN = 3;
|
||||||
var
|
var
|
||||||
FW, FH: Integer;
|
FW, FH: Integer;
|
||||||
@@ -1370,11 +1376,11 @@ var
|
|||||||
SMBot: Integer;
|
SMBot: Integer;
|
||||||
begin
|
begin
|
||||||
if (PanelSMeterRight = nil) or (PanelToolbar = nil) or
|
if (PanelSMeterRight = nil) or (PanelToolbar = nil) or
|
||||||
(PanelSpanButtons = nil) then Exit;
|
(PanelSpanButtons = nil) or (PanelLeft = nil) then Exit;
|
||||||
|
|
||||||
FW := ClientWidth;
|
FW := ClientWidth;
|
||||||
// Ширина зоны спектра (PanelRight)
|
// Ширина зоны спектра (PanelRight)
|
||||||
RightW := FW - LEFT_PANEL_W;
|
RightW := FW - PanelLeft.Width;
|
||||||
if RightW < 200 then Exit;
|
if RightW < 200 then Exit;
|
||||||
|
|
||||||
// Ширина S-метра = 40% от PanelRight
|
// Ширина S-метра = 40% от PanelRight
|
||||||
@@ -1499,12 +1505,12 @@ end;
|
|||||||
procedure TMainForm.StyleSpanButton(B: TFlatButton; Active: Boolean);
|
procedure TMainForm.StyleSpanButton(B: TFlatButton; Active: Boolean);
|
||||||
begin
|
begin
|
||||||
B.Active := Active;
|
B.Active := Active;
|
||||||
B.ClrNorm := TColor($0013191B);
|
B.ClrNorm := TColor($00543F18);
|
||||||
B.ClrActive := TColor($001E3C1E);
|
B.ClrActive := TColor($00624B1D);
|
||||||
B.ClrHot := TColor($001E2D1E);
|
B.ClrHot := TColor($00624B1D);
|
||||||
B.ClrBorder := TColor($005A7A5A);
|
B.ClrBorder := TColor($00685624);
|
||||||
B.ClrText := TColor($0090B890);
|
B.ClrText := TColor($00D8E6EE);
|
||||||
B.ClrTextAct := TColor($00AAFFAA);
|
B.ClrTextAct := TColor($00F0FAFF);
|
||||||
B.Font.Name := 'Courier New';
|
B.Font.Name := 'Courier New';
|
||||||
B.Font.Size := 7;
|
B.Font.Size := 7;
|
||||||
end;
|
end;
|
||||||
@@ -1545,6 +1551,8 @@ begin
|
|||||||
BtnSpan384k.SetBounds(X, BaseY + BTN_TOP, W384, HBTN); Inc(X, W384 + 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);
|
BtnSpan768k.SetBounds(X, BaseY + BTN_TOP, W768, HBTN); Inc(X, W768 + GAP);
|
||||||
BtnSpan1536k.SetBounds(X, BaseY + BTN_TOP, W1536, HBTN);
|
BtnSpan1536k.SetBounds(X, BaseY + BTN_TOP, W1536, HBTN);
|
||||||
|
if BtnHidePanel <> nil then
|
||||||
|
BtnHidePanel.SetBounds(BaseX, BaseY + BTN_TOP, 28, HBTN);
|
||||||
|
|
||||||
BtnSpan48k.Visible := True;
|
BtnSpan48k.Visible := True;
|
||||||
BtnSpan96k.Visible := True;
|
BtnSpan96k.Visible := True;
|
||||||
@@ -1559,6 +1567,7 @@ begin
|
|||||||
BtnSpan384k.BringToFront;
|
BtnSpan384k.BringToFront;
|
||||||
BtnSpan768k.BringToFront;
|
BtnSpan768k.BringToFront;
|
||||||
BtnSpan1536k.BringToFront;
|
BtnSpan1536k.BringToFront;
|
||||||
|
if BtnHidePanel <> nil then BtnHidePanel.BringToFront;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
@@ -1728,6 +1737,58 @@ begin
|
|||||||
Desc.AlphaShift := 24; Desc.AlphaPrec := 8;
|
Desc.AlphaShift := 24; Desc.AlphaPrec := 8;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function MixColorBGR(C1, C2: TColor; T: Double): TColor;
|
||||||
|
var
|
||||||
|
B1, G1, R1: Integer;
|
||||||
|
B2, G2, R2: Integer;
|
||||||
|
B, G, R: Integer;
|
||||||
|
begin
|
||||||
|
if T < 0.0 then T := 0.0 else
|
||||||
|
if T > 1.0 then T := 1.0;
|
||||||
|
|
||||||
|
B1 := (C1 shr 16) and $FF; G1 := (C1 shr 8) and $FF; R1 := C1 and $FF;
|
||||||
|
B2 := (C2 shr 16) and $FF; G2 := (C2 shr 8) and $FF; R2 := C2 and $FF;
|
||||||
|
|
||||||
|
B := Round(B1 + (B2 - B1) * T);
|
||||||
|
G := Round(G1 + (G2 - G1) * T);
|
||||||
|
R := Round(R1 + (R2 - R1) * T);
|
||||||
|
Result := TColor((B shl 16) or (G shl 8) or R);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure PaintVerticalGradient(C: TCanvas; W, H: Integer; TopColor, BottomColor: TColor);
|
||||||
|
var
|
||||||
|
Y: Integer;
|
||||||
|
T: Double;
|
||||||
|
begin
|
||||||
|
if (W <= 0) or (H <= 0) then Exit;
|
||||||
|
C.Pen.Style := psClear;
|
||||||
|
C.Brush.Style := bsSolid;
|
||||||
|
for Y := 0 to H - 1 do
|
||||||
|
begin
|
||||||
|
T := Y / Max(1, H - 1);
|
||||||
|
C.Brush.Color := MixColorBGR(TopColor, BottomColor, T);
|
||||||
|
C.FillRect(Rect(0, Y, W, Y + 1));
|
||||||
|
end;
|
||||||
|
C.Pen.Style := psSolid;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure PaintHorizontalFade(C: TCanvas; X1, X2, H: Integer; LeftColor, RightColor: TColor);
|
||||||
|
var
|
||||||
|
X: Integer;
|
||||||
|
T: Double;
|
||||||
|
begin
|
||||||
|
if (H <= 0) or (X2 <= X1) then Exit;
|
||||||
|
C.Pen.Style := psClear;
|
||||||
|
C.Brush.Style := bsSolid;
|
||||||
|
for X := X1 to X2 - 1 do
|
||||||
|
begin
|
||||||
|
T := (X - X1) / Max(1, X2 - X1 - 1);
|
||||||
|
C.Brush.Color := MixColorBGR(LeftColor, RightColor, T);
|
||||||
|
C.FillRect(Rect(X, 0, X + 1, H));
|
||||||
|
end;
|
||||||
|
C.Pen.Style := psSolid;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TMainForm.DrawSpectrumGradient(const SpPts: array of TPoint; W, H: Integer);
|
procedure TMainForm.DrawSpectrumGradient(const SpPts: array of TPoint; W, H: Integer);
|
||||||
// ═══════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════
|
||||||
// Попиксельный градиент через кэшированный FSpecGradImg.
|
// Попиксельный градиент через кэшированный FSpecGradImg.
|
||||||
@@ -1815,6 +1876,7 @@ var
|
|||||||
SrcF, Frac, dBv: Double;
|
SrcF, Frac, dBv: Double;
|
||||||
S0, S1: Integer;
|
S0, S1: Integer;
|
||||||
InvRange: Double;
|
InvRange: Double;
|
||||||
|
LabelBandW: Integer;
|
||||||
begin
|
begin
|
||||||
if FSpectrumBitmap = nil then Exit;
|
if FSpectrumBitmap = nil then Exit;
|
||||||
W := FSpectrumBitmap.Width;
|
W := FSpectrumBitmap.Width;
|
||||||
@@ -1832,16 +1894,22 @@ begin
|
|||||||
FGridBitmapH := H;
|
FGridBitmapH := H;
|
||||||
FGridBitmap.SetSize(W, H);
|
FGridBitmap.SetSize(W, H);
|
||||||
GC := FGridBitmap.Canvas;
|
GC := FGridBitmap.Canvas;
|
||||||
GC.Brush.Color := TColor($00050505);
|
PaintVerticalGradient(GC, W, H, TColor($0020160B), TColor($006C4F1F));
|
||||||
GC.FillRect(Rect(0, 0, W, H));
|
LabelBandW := 28;
|
||||||
|
GC.Pen.Style := psClear;
|
||||||
|
GC.Brush.Style := bsSolid;
|
||||||
|
GC.Brush.Color := TColor($00543F18);
|
||||||
|
GC.FillRect(Rect(0, 0, LabelBandW, H));
|
||||||
|
GC.Pen.Style := psSolid;
|
||||||
GC.Font.Size := 7;
|
GC.Font.Size := 7;
|
||||||
GC.Font.Name := 'Courier New';
|
GC.Font.Name := 'Courier New';
|
||||||
GC.Font.Color := CLR_TEXTDIM;
|
GC.Font.Color := TColor($00A8C9D9);
|
||||||
dB := -30.0;
|
GC.Brush.Style := bsClear;
|
||||||
|
dB := -40.0;
|
||||||
while dB >= DBmin do
|
while dB >= DBmin do
|
||||||
begin
|
begin
|
||||||
Yp := Round((DBmax - dB) * InvRange * H);
|
Yp := Round((DBmax - dB) * InvRange * H);
|
||||||
GC.Pen.Color := CLR_BORDER;
|
GC.Pen.Color := TColor($00685624);
|
||||||
GC.Pen.Width := 1;
|
GC.Pen.Width := 1;
|
||||||
GC.MoveTo(0, Yp); GC.LineTo(W-1, Yp);
|
GC.MoveTo(0, Yp); GC.LineTo(W-1, Yp);
|
||||||
GC.TextOut(1, Yp - 9, Format('%4.0f', [dB]));
|
GC.TextOut(1, Yp - 9, Format('%4.0f', [dB]));
|
||||||
@@ -1850,7 +1918,7 @@ begin
|
|||||||
for i := 0 to 8 do
|
for i := 0 to 8 do
|
||||||
begin
|
begin
|
||||||
GX := ScaleX(i, 8, W);
|
GX := ScaleX(i, 8, W);
|
||||||
GC.Pen.Color := CLR_BORDER;
|
GC.Pen.Color := TColor($00685624);
|
||||||
GC.MoveTo(GX, 0); GC.LineTo(GX, H);
|
GC.MoveTo(GX, 0); GC.LineTo(GX, H);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@@ -1866,7 +1934,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
X1 := Max(0, Min(W-1, VfoX + Round(Lo_Hz / FSpanHz * W)));
|
X1 := Max(0, Min(W-1, VfoX + Round(Lo_Hz / FSpanHz * W)));
|
||||||
X2 := Max(0, Min(W-1, VfoX + Round(Hi_Hz / FSpanHz * W)));
|
X2 := Max(0, Min(W-1, VfoX + Round(Hi_Hz / FSpanHz * W)));
|
||||||
C.Brush.Color := TColor($00102828);
|
C.Brush.Color := TColor($006A4E22);
|
||||||
C.Brush.Style := bsSolid;
|
C.Brush.Style := bsSolid;
|
||||||
C.Pen.Style := psClear;
|
C.Pen.Style := psClear;
|
||||||
if X2 > X1 then C.FillRect(Rect(X1, 0, X2, H));
|
if X2 > X1 then C.FillRect(Rect(X1, 0, X2, H));
|
||||||
@@ -2457,24 +2525,24 @@ begin
|
|||||||
FRulerBitmap.SetSize(W, H);
|
FRulerBitmap.SetSize(W, H);
|
||||||
|
|
||||||
C := FRulerBitmap.Canvas;
|
C := FRulerBitmap.Canvas;
|
||||||
C.Brush.Color := TColor($00141414);
|
PaintVerticalGradient(C, W, H, TColor($00372A12), TColor($00705A2A));
|
||||||
C.FillRect(Rect(0, 0, W, H));
|
C.Pen.Color := TColor($00685624);
|
||||||
C.Pen.Color := CLR_BORDER;
|
|
||||||
C.Pen.Width := 1;
|
C.Pen.Width := 1;
|
||||||
C.MoveTo(0, 0); C.LineTo(W, 0);
|
C.MoveTo(0, 0); C.LineTo(W, 0);
|
||||||
C.MoveTo(0, H-1); C.LineTo(W, H-1);
|
C.MoveTo(0, H-1); C.LineTo(W, H-1);
|
||||||
C.Font.Name := 'Courier New';
|
C.Font.Name := 'Courier New';
|
||||||
C.Font.Size := 7;
|
C.Font.Size := 7;
|
||||||
|
C.Brush.Style := bsClear;
|
||||||
FreqStart := FCenterFreq - FSpanHz / 2;
|
FreqStart := FCenterFreq - FSpanHz / 2;
|
||||||
for i := 0 to 8 do
|
for i := 0 to 8 do
|
||||||
begin
|
begin
|
||||||
X := ScaleX(i, 8, W);
|
X := ScaleX(i, 8, W);
|
||||||
C.Pen.Color := CLR_BORDER;
|
C.Pen.Color := TColor($00685624);
|
||||||
C.MoveTo(X, 0); C.LineTo(X, H div 2);
|
C.MoveTo(X, 0); C.LineTo(X, H div 2);
|
||||||
FreqHz := FreqStart + i * FSpanHz / 8;
|
FreqHz := FreqStart + i * FSpanHz / 8;
|
||||||
Lbl := Format('%.3f', [FreqHz / 1e6]);
|
Lbl := Format('%.3f', [FreqHz / 1e6]);
|
||||||
TW := C.TextWidth(Lbl);
|
TW := C.TextWidth(Lbl);
|
||||||
C.Font.Color := TColor($00888888);
|
C.Font.Color := TColor($00C8D8E2);
|
||||||
C.TextOut(X - TW div 2, H div 2 - 1, Lbl);
|
C.TextOut(X - TW div 2, H div 2 - 1, Lbl);
|
||||||
end;
|
end;
|
||||||
VfoX := Round((FVfoA - FCenterFreq + FSpanHz / 2) / FSpanHz * W);
|
VfoX := Round((FVfoA - FCenterFreq + FSpanHz / 2) / FSpanHz * W);
|
||||||
@@ -3746,11 +3814,10 @@ end;
|
|||||||
procedure TMainForm.BtnHidePanelClick(Sender: TObject);
|
procedure TMainForm.BtnHidePanelClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
FPanelHidden := not FPanelHidden;
|
FPanelHidden := not FPanelHidden;
|
||||||
PanelLeft.Visible := not FPanelHidden;
|
|
||||||
if FPanelHidden then
|
if FPanelHidden then
|
||||||
begin
|
begin
|
||||||
BtnHidePanel.Caption := '▶ SHOW';
|
PanelLeft.Width := 0;
|
||||||
// PbSpectrum — TGraphicControl, не TWinControl, используем PanelRight
|
BtnHidePanel.Caption := '▶';
|
||||||
FVfoOverlay.Parent := PanelRight;
|
FVfoOverlay.Parent := PanelRight;
|
||||||
FVfoOverlay.Width := 260;
|
FVfoOverlay.Width := 260;
|
||||||
FVfoOverlay.Height := 130;
|
FVfoOverlay.Height := 130;
|
||||||
@@ -3761,9 +3828,11 @@ begin
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
BtnHidePanel.Caption := '◀ HIDE';
|
PanelLeft.Width := 232;
|
||||||
|
BtnHidePanel.Caption := '◀';
|
||||||
FVfoOverlay.Visible := False;
|
FVfoOverlay.Visible := False;
|
||||||
end;
|
end;
|
||||||
|
ResizeSpectrumPanels;
|
||||||
ResizeSMeter;
|
ResizeSMeter;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user