From 737af0d227b57d4b3427dd943856766c4607195c Mon Sep 17 00:00:00 2001 From: Vladimir Date: Wed, 1 Jul 2026 17:17:46 +0300 Subject: [PATCH] feat(overlay): glassy buttons (zoom-bar style gloss gradient) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DrawButton теперь рисует стеклянную кнопку как ползунок зум-бара: тёмная скруглённая база-фаска + вертикальный глянцевый градиент (ярче вверху, темнее внизу) + блик сверху и тень снизу. Хелпер GlossColor масштабирует яркость цвета. Только при ребилде кэша — CPU-паритет сохранён. Co-Authored-By: Claude Opus 4.8 --- VfoOverlay.pas | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/VfoOverlay.pas b/VfoOverlay.pas index dc6dd73..96946cc 100644 --- a/VfoOverlay.pas +++ b/VfoOverlay.pas @@ -407,17 +407,53 @@ end; { ---- Примитивы отрисовки ---- } +// Масштаб яркости цвета (для стеклянного градиента/фаски). +function GlossColor(Base: TColor; F: Double): TColor; +var + R, G, B: Byte; +begin + RedGreenBlue(ColorToRGB(Base), R, G, B); + Result := RGBToColor(EnsureRange(Round(R * F), 0, 255), + EnsureRange(Round(G * F), 0, 255), + EnsureRange(Round(B * F), 0, 255)); +end; + procedure TVfoOverlay.DrawButton(C: TCanvas; const R: TRect; const Lbl: string; Active, Hot: Boolean; FontSz: Integer); +var + Base: TColor; + Y, H: Integer; + RowT, Gloss: Double; begin - if Active then C.Brush.Color := CLR_ACCENT - else if Hot then C.Brush.Color := CLR_BTN_HOT - else C.Brush.Color := CLR_BTN_NORM; + if Active then Base := CLR_ACCENT + else if Hot then Base := CLR_BTN_HOT + else Base := CLR_BTN_NORM; + + // Скруглённая тёмная база = форма + рамка-фаска. + C.Brush.Color := GlossColor(Base, 0.58); C.Brush.Style := bsSolid; + C.Pen.Color := GlossColor(Base, 0.42); C.Pen.Style := psSolid; - C.Pen.Color := C.Brush.Color; C.RoundRect(R.Left, R.Top, R.Right, R.Bottom, 5, 5); + // Стеклянный вертикальный градиент: ярче вверху, темнее внизу (как ползунок зума). + H := R.Bottom - R.Top; + C.Pen.Style := psClear; + for Y := R.Top + 1 to R.Bottom - 2 do + begin + if H > 3 then RowT := (Y - (R.Top + 1)) / (H - 3) else RowT := 0.0; + Gloss := 1.30 - 0.60 * RowT; + C.Brush.Color := GlossColor(Base, Gloss); + C.FillRect(Rect(R.Left + 2, Y, R.Right - 2, Y + 1)); + end; + + // Блик сверху + тень снизу (объём). + C.Pen.Style := psSolid; + C.Pen.Color := GlossColor(Base, 1.55); + C.Line(R.Left + 2, R.Top + 1, R.Right - 2, R.Top + 1); + C.Pen.Color := GlossColor(Base, 0.40); + C.Line(R.Left + 2, R.Bottom - 2, R.Right - 2, R.Bottom - 2); + if Active then C.Font.Color := CLR_CARD_BG else C.Font.Color := CLR_TEXT; C.Font.Name := 'Courier New';