From a0f4b044db4f5a327ad1a4843dc2a18e0f50ec12 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Wed, 5 Aug 2026 16:07:25 +0300 Subject: [PATCH] ui(spectrum): theme sample rate overlay --- MainForm.pas | 1 + SampleRateOverlay.pas | 69 ++++++++++++++++++++++++++++--------------- 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/MainForm.pas b/MainForm.pas index 84ae375..4601580 100644 --- a/MainForm.pas +++ b/MainForm.pas @@ -3180,6 +3180,7 @@ begin if FLeftScrollBar <> nil then FLeftScrollBar.SetColors(T.Panel, T.Border, T.SliderThumbHot, T.SliderThumbDrag); + if FSampleRateOverlay <> nil then FSampleRateOverlay.SetTheme(T); DP(PanelTopVfoGroup); DP(PanelTopVfoA); DP(PanelTopVfoB); DP(PanelVfoA); DP(PanelVfoB); DP(PanelVfoButtons); DP(PanelBands); DP(PanelMode); DP(PanelFilter); diff --git a/SampleRateOverlay.pas b/SampleRateOverlay.pas index 89a10bf..e9fb73d 100644 --- a/SampleRateOverlay.pas +++ b/SampleRateOverlay.pas @@ -13,7 +13,7 @@ unit SampleRateOverlay; interface uses - Classes, SysUtils, Controls, Graphics, Types, Math; + Classes, SysUtils, Controls, Graphics, Types, Math, AppTheme; type TSpanSelectEvent = procedure(SampleRate: Integer) of object; @@ -35,6 +35,7 @@ type FTop: Integer; FWidth: Integer; FHeight: Integer; + FTheme: TAppTheme; FHitRects: array[0..10] of TRect; // [0]=hide button, [1..]=span buttons FHitValues: array[0..10] of Integer; // 0=hide, else sample rate @@ -76,6 +77,7 @@ type procedure SetRatePresets(const Rates: array of Integer); procedure SetRatePresetsDefault; // HPSDR 48k..1536k procedure SetPanelHidden(Hidden: Boolean); + procedure SetTheme(const T: TAppTheme); property Left: Integer read FLeft; property Top: Integer read FTop; property Width: Integer read FWidth; @@ -97,9 +99,6 @@ const PAD_Y = 4; BTN_GAP = 3; - CLR_TEXT = TColor($00D8E6EE); - CLR_BTN_BDR = TColor($00685624); - procedure BlendRect(Target: TBitmap; const Rct: TRect; R, G, B, Alpha: Byte); var Y, X, InvA: Integer; @@ -141,6 +140,16 @@ begin end; end; +procedure BlendColorRect(Target: TBitmap; const Rct: TRect; + Color: TColor; Alpha: Byte); +var + C: LongInt; +begin + C := ColorToRGB(Color); + BlendRect(Target, Rct, C and $FF, (C shr 8) and $FF, + (C shr 16) and $FF, Alpha); +end; + function SpanBtnWidth(const Name: string; C: TCanvas): Integer; begin C.Font.Name := 'Courier New'; @@ -160,6 +169,7 @@ begin FHotIdx := -1; FWidth := 320; FHeight := SPAN_H + PAD_Y * 2; + FTheme := DarkTheme; FCache := TBitmap.Create; FCache.PixelFormat := pf32bit; FCacheW := 0; @@ -224,30 +234,34 @@ begin if ContentW > W then ContentW := W; FullR := Rect(OriginX, OriginY, OriginX + ContentW, OriginY + H); - BlendRect(Target, FullR, $14, $14, $14, 104); - BlendRect(Target, Rect(FullR.Left, FullR.Top, FullR.Right, FullR.Top + 1), - $80, $80, $80, 56); - BlendRect(Target, Rect(FullR.Left, FullR.Bottom - 1, FullR.Right, FullR.Bottom), - $00, $00, $00, 48); - BlendRect(Target, Rect(FullR.Left, FullR.Top, FullR.Left + 1, FullR.Bottom), - $80, $80, $80, 42); - BlendRect(Target, Rect(FullR.Right - 1, FullR.Top, FullR.Right, FullR.Bottom), - $00, $00, $00, 42); + BlendColorRect(Target, FullR, FTheme.Panel, 210); + BlendColorRect(Target, + Rect(FullR.Left, FullR.Top, FullR.Right, FullR.Top + 1), + FTheme.Border, 150); + BlendColorRect(Target, + Rect(FullR.Left, FullR.Bottom - 1, FullR.Right, FullR.Bottom), + FTheme.Border, 120); + BlendColorRect(Target, + Rect(FullR.Left, FullR.Top, FullR.Left + 1, FullR.Bottom), + FTheme.Border, 120); + BlendColorRect(Target, + Rect(FullR.Right - 1, FullR.Top, FullR.Right, FullR.Bottom), + FTheme.Border, 120); X := OriginX + PAD_X; HR := Rect(X, OriginY + PAD_Y, X + HIDE_W, OriginY + PAD_Y + SPAN_H); IsHot := FHotIdx = 0; - if IsHot then BlendRect(Target, HR, $1D, $4B, $62, 206) - else BlendRect(Target, HR, $18, $3F, $54, 182); + if IsHot then BlendColorRect(Target, HR, FTheme.SpanActive, 230) + else BlendColorRect(Target, HR, FTheme.SpanNorm, 215); C.Pen.Style := psSolid; - C.Pen.Color := CLR_BTN_BDR; + C.Pen.Color := FTheme.SpanBorder; C.Brush.Style := bsClear; C.Rectangle(HR); C.Font.Size := 8; if FPanelHidden then Cap := '>' else Cap := '<'; TW := C.TextWidth(Cap); - C.Font.Color := CLR_TEXT; + C.Font.Color := FTheme.SpanText; C.Brush.Style := bsClear; C.TextOut(HR.Left + (HIDE_W - TW) div 2, HR.Top + (SPAN_H - TH) div 2, Cap); @@ -262,16 +276,16 @@ begin IsAct := FRates[I] = FCurrentRate; IsHot := FHotIdx = I + 1; - if IsAct then BlendRect(Target, HR, $20, $5A, $78, 220) - else if IsHot then BlendRect(Target, HR, $1D, $4B, $62, 206) - else BlendRect(Target, HR, $18, $3F, $54, 182); + if IsAct then BlendColorRect(Target, HR, FTheme.SpanActive, 240) + else if IsHot then BlendColorRect(Target, HR, FTheme.SpanActive, 230) + else BlendColorRect(Target, HR, FTheme.SpanNorm, 215); C.Pen.Style := psSolid; - C.Pen.Color := CLR_BTN_BDR; + C.Pen.Color := FTheme.SpanBorder; C.Brush.Style := bsClear; C.Rectangle(HR); TW := C.TextWidth(FNames[I]); - C.Font.Color := CLR_TEXT; + C.Font.Color := FTheme.SpanText; C.Brush.Style := bsClear; C.TextOut(HR.Left + (BtnW - TW) div 2, HR.Top + (SPAN_H - TH) div 2, FNames[I]); @@ -470,7 +484,7 @@ begin ContentW := Min(ContentW, W); Target.SetSize(ContentW, H); - Target.Canvas.Brush.Color := TColor($00141414); + Target.Canvas.Brush.Color := FTheme.Panel; Target.Canvas.Brush.Style := bsSolid; Target.Canvas.Pen.Style := psClear; Target.Canvas.FillRect(Rect(0, 0, ContentW, H)); @@ -480,7 +494,7 @@ begin try HitTarget.PixelFormat := pf32bit; HitTarget.SetSize(Max(1, FLeft + ContentW), Max(1, FTop + H)); - HitTarget.Canvas.Brush.Color := TColor($00141414); + HitTarget.Canvas.Brush.Color := FTheme.Panel; HitTarget.Canvas.FillRect(Rect(0, 0, HitTarget.Width, HitTarget.Height)); DrawSelf(HitTarget, HitTarget.Canvas, FLeft, FTop, ContentW, H); finally @@ -575,4 +589,11 @@ begin RequestInvalidate; end; +procedure TSampleRateOverlay.SetTheme(const T: TAppTheme); +begin + FTheme := T; + FCacheDirty := True; + RequestInvalidate; +end; + end.