diff --git a/MainForm.pas b/MainForm.pas index 1d4584b..299897f 100644 --- a/MainForm.pas +++ b/MainForm.pas @@ -241,6 +241,7 @@ type FShowWaterfall: Boolean; FShowWideband: Boolean; FWidebandFill: Boolean; + FSpectrumFill: Boolean; FDisplayFPS: Integer; FWaterfallDirty: Boolean; FWidebandDirty: Boolean; @@ -729,7 +730,7 @@ type function PullSoundCardMic(MaxN: Integer): Integer; function BuildMicLineSelectByte: Byte; procedure ApplyVisibility(ShowSpectrum, ShowWaterfall, ShowWideband, - WidebandFill: Boolean); + WidebandFill, SpectrumFill: Boolean); procedure ApplyFPS(FPS: Integer); procedure ApplyFreqMhzDigits(Digits: Integer); @@ -951,6 +952,7 @@ begin Result.ShowWaterfall := FShowWaterfall; Result.ShowWideband := FShowWideband; Result.WidebandFill := FWidebandFill; + Result.SpectrumFill := FSpectrumFill; Result.DisplayDuplex := FDisplayDuplex; Result.DisplayFPS := FDisplayFPS; Result.LightTheme := FLightTheme; @@ -1295,6 +1297,7 @@ begin FShowWaterfall := True; FShowWideband := False; FWidebandFill := False; + FSpectrumFill := True; FDisplayFPS := 60; FFreqMhzDigits := 3; FSplitterRatio := 0.40; @@ -4098,6 +4101,8 @@ begin FWidebandFill := G_Settings.WidebandFill; if Assigned(FWidebandView) then FWidebandView.SetFillSpectrum(FWidebandFill); + FSpectrumFill := G_Settings.SpectrumFill; + FSpecView.FillSpectrum := FSpectrumFill; FDisplayDuplex := G_Settings.DisplayDuplex; if BtnDUP <> nil then StyleButton(BtnDUP, FDisplayDuplex); if G_Settings.DisplayFPS > 0 then @@ -7503,14 +7508,16 @@ begin end; procedure TMainForm.ApplyVisibility(ShowSpectrum, ShowWaterfall, - ShowWideband, WidebandFill: Boolean); + ShowWideband, WidebandFill, SpectrumFill: Boolean); begin FShowSpectrum := ShowSpectrum; FShowWaterfall := ShowWaterfall; FShowWideband := ShowWideband; FWidebandFill := WidebandFill; + FSpectrumFill := SpectrumFill; if Assigned(FWidebandView) then FWidebandView.SetFillSpectrum(FWidebandFill); + FSpecView.FillSpectrum := FSpectrumFill; if Assigned(FNetwork) and FNetwork.Connected then FNetwork.ConfigureWideband(0, FShowWideband, 512, 16, 70, 32); ResizeSpectrumPanels; @@ -7597,7 +7604,8 @@ begin FCATLastGlobal.CATTcpPort); // Перечисляем PA устройства SF.RefreshAudioDevices(FAudioOut, FAudioIn); - SF.LoadVisibility(FShowSpectrum, FShowWaterfall, FShowWideband, FWidebandFill); + SF.LoadVisibility(FShowSpectrum, FShowWaterfall, FShowWideband, FWidebandFill, + FSpectrumFill); SF.LoadWfAGCNF(FWfAGCEnabled, FWfNFEnabled); SF.LoadADCSettings(FDitherEnabled, FRandomEnabled); SF.LoadWebSettings(FWebEnabled, FWebPort, FWebBindAddr, FWebUser, FWebPass); diff --git a/Settings.pas b/Settings.pas index 8437c07..ec8f571 100644 --- a/Settings.pas +++ b/Settings.pas @@ -224,6 +224,7 @@ type ShowWaterfall: Boolean; // True = draw waterfall on main form ShowWideband: Boolean; // True = draw raw ADC wideband pane on main form WidebandFill: Boolean; // True = fill wideband spectrum with gradient + SpectrumFill: Boolean; // True = fill main spectrum under the curve with gradient DisplayDuplex: Boolean; // DUP: при TX показывать RX-водопад, TX-фильтр overlay'ем // --- Display FPS --- DisplayFPS: Integer; // spectrum/waterfall timer fps (1..100) @@ -402,6 +403,7 @@ begin G.ShowWaterfall := True; G.ShowWideband := False; G.WidebandFill := False; + G.SpectrumFill := True; G.DisplayDuplex := False; G.DisplayFPS := 60; G.FreqMhzDigits := 3; @@ -621,6 +623,7 @@ begin G.ShowWaterfall := JB(GObj,'show_waterfall',True); G.ShowWideband := JB(GObj,'show_wideband',False); G.WidebandFill := JB(GObj,'wideband_fill',False); + G.SpectrumFill := JB(GObj,'spectrum_fill',True); G.DisplayDuplex := JB(GObj,'display_duplex',False); G.DisplayFPS := JI(GObj,'display_fps',60); G.LightTheme := JB(GObj,'light_theme',False); @@ -708,6 +711,7 @@ begin JW(O,'show_waterfall',G.ShowWaterfall); JW(O,'show_wideband',G.ShowWideband); JW(O,'wideband_fill',G.WidebandFill); + JW(O,'spectrum_fill',G.SpectrumFill); JW(O,'display_duplex',G.DisplayDuplex); JW(O,'display_fps',G.DisplayFPS); JW(O,'light_theme',G.LightTheme); diff --git a/SettingsForm.pas b/SettingsForm.pas index a6f8a10..aa5fddc 100644 --- a/SettingsForm.pas +++ b/SettingsForm.pas @@ -50,7 +50,7 @@ type TOnAudioInDevChange = procedure(DevIndex: Integer; const DevName: string) of object; TOnAudioBufferChange = procedure(BufferSize: Integer) of object; TOnVisibilityChange = procedure(ShowSpectrum, ShowWaterfall, ShowWideband, - WidebandFill: Boolean) of object; + WidebandFill, SpectrumFill: Boolean) of object; TOnFPSChange = procedure(FPS: Integer) of object; TOnThemeChange = procedure(LightTheme: Boolean) of object; TOnWfAGCNFChange = procedure(WfAGC, WfNF: Boolean) of object; @@ -123,6 +123,7 @@ type FChkShowWaterfall: TFlatCheckBox; FChkShowWideband: TFlatCheckBox; FChkWidebandFill: TFlatCheckBox; + FChkSpectrumFill: TFlatCheckBox; FCmbFPS: TFlatComboBox; FChkLightTheme: TFlatCheckBox; FCmbFreqMhzDigits: TFlatComboBox; @@ -375,7 +376,7 @@ type procedure RefreshAudioDevices(AudioOut: TAudioOutput; AudioIn: TAudioInput); procedure LoadAudioBufferSize(BufferSize: Integer); procedure LoadVisibility(ShowSpectrum, ShowWaterfall, ShowWideband, - WidebandFill: Boolean); + WidebandFill, SpectrumFill: Boolean); procedure LoadFPS(FPS: Integer); procedure LoadLightTheme(ALight: Boolean); procedure LoadFreqMhzDigits(Digits: Integer); @@ -846,6 +847,16 @@ begin FChkWidebandFill.Font.Size := 9; FChkWidebandFill.OnChange := OnVisibilityChkChange; + FChkSpectrumFill := TFlatCheckBox.Create(Self); + FChkSpectrumFill.Parent := Grp; + FChkSpectrumFill.Caption := 'Spectrum gradient fill'; + FChkSpectrumFill.SetBounds(PAD, R1 + 28, CHKW, 22); + FChkSpectrumFill.Checked := True; + FChkSpectrumFill.Font.Color := CLR_TEXT; + FChkSpectrumFill.Font.Name := UI_FONT; + FChkSpectrumFill.Font.Size := 9; + FChkSpectrumFill.OnChange := OnVisibilityChkChange; + Grp := MakeGroupPanel(FPageDisplay, 'Performance', MARGIN, 212, 650, 92); MakeLbl(Grp, 'Refresh rate', PAD, R1 + 5, LW); @@ -2328,7 +2339,7 @@ begin end; procedure TSettingsForm.LoadVisibility(ShowSpectrum, ShowWaterfall, - ShowWideband, WidebandFill: Boolean); + ShowWideband, WidebandFill, SpectrumFill: Boolean); begin FLoading := True; try @@ -2336,6 +2347,7 @@ begin FChkShowWaterfall.Checked := ShowWaterfall; FChkShowWideband.Checked := ShowWideband; FChkWidebandFill.Checked := WidebandFill; + FChkSpectrumFill.Checked := SpectrumFill; finally FLoading := False; end; @@ -2357,7 +2369,7 @@ begin if FLoading then Exit; if not Assigned(FOnVisibilityChange) then Exit; FOnVisibilityChange(FChkShowSpectrum.Checked, FChkShowWaterfall.Checked, - FChkShowWideband.Checked, FChkWidebandFill.Checked); + FChkShowWideband.Checked, FChkWidebandFill.Checked, FChkSpectrumFill.Checked); end; procedure TSettingsForm.OnLightThemeChkChange(Sender: TObject); diff --git a/SpectrumView.pas b/SpectrumView.pas index faf2bd1..ca6a65f 100644 --- a/SpectrumView.pas +++ b/SpectrumView.pas @@ -39,6 +39,7 @@ type FFMGridLastSpan: Double; FSpPts: array of TPoint; FSpPtsLen: Integer; + FFillSpectrum: Boolean; // ── Тема ───────────────────────────────────────────────────────────────── FTheme: TAppTheme; FLightTheme: Boolean; @@ -95,6 +96,7 @@ type procedure SetTXSpanHz(V: Double); procedure SetMarkerActive(V: Boolean); procedure SetMarkerX(V: Integer); + procedure SetFillSpectrum(V: Boolean); procedure DrawSpectrumGradient(const SpPts: array of TPoint; W, H: Integer); procedure DrawMarkerLine(C: TCanvas; W, H: Integer); procedure BlendBand(X1, X2, H: Integer; R, G, B, Alpha: Byte); @@ -191,6 +193,7 @@ type // ── Флаги обновления ────────────────────────────────────────────────────── property SpectrumDirty: Boolean read FSpectrumDirty write FSpectrumDirty; + property FillSpectrum: Boolean read FFillSpectrum write SetFillSpectrum; property WaterfallDirty: Boolean read GetWaterfallDirty write SetWaterfallDirty; property WfFrameInterval: Integer read GetWfFrameInterval write SetWfFrameInterval; @@ -304,6 +307,7 @@ begin FSpectrumBufCount := 1024; FSpectrumDirty := True; FLightTheme := False; + FFillSpectrum := True; FTheme := DarkTheme; // Sub-views FWaterfall := TWaterfallView.Create; @@ -388,6 +392,13 @@ begin FWaterfall.MarkerX := V; end; +procedure TSpectrumView.SetFillSpectrum(V: Boolean); +begin + if FFillSpectrum = V then Exit; + FFillSpectrum := V; + FSpectrumDirty := True; +end; + function TSpectrumView.GetWaterfallDirty: Boolean; begin Result := FWaterfall.WaterfallDirty; @@ -898,9 +909,12 @@ begin end; FSpPts[W] := Point(W-1, H); FSpPts[W+1] := Point(0, H); - // ── 5. Градиент ─────────────────────────────────────────────────────────── - C.Brush.Style := bsSolid; C.Pen.Style := psClear; - DrawSpectrumGradient(FSpPts, W, H); + // ── 5. Градиент (заливка под кривой) ────────────────────────────────────── + if FFillSpectrum then + begin + C.Brush.Style := bsSolid; C.Pen.Style := psClear; + DrawSpectrumGradient(FSpPts, W, H); + end; // ── 6. Линия спектра ────────────────────────────────────────────────────── C.Pen.Style := psSolid; C.Pen.Color := FTheme.SpecLine; C.Pen.Width := 1;