unit AutoColors;
{$mode ObjFPC}{$H+}
interface
uses
Graphics;
const
clWindowText20: TColor = clNone;
clWindowText40: TColor = clNone;
clWindowText60: TColor = clNone;
clWindowText80: TColor = clNone;
// default color names from the VGA standard,
// will stay unmodified on light themes
clAutoAqua: TColor = clAqua;
clAutoBlack: TColor = clBlack;
clAutoBlue: TColor = clBlue;
clAutoFuchsia: TColor = clFuchsia;
clAutoGray: TColor = clGray;
clAutoGreen: TColor = clGreen;
clAutoLime: TColor = clLime;
clAutoMaroon: TColor = clMaroon;
clAutoNavy: TColor = clNavy;
clAutoOlive: TColor = clOlive;
clAutoPurple: TColor = clPurple;
clAutoRed: TColor = clRed;
clAutoSilver: TColor = clSilver;
clAutoTeal: TColor = clTeal;
clAutoWhite: TColor = clWhite;
clAutoYellow: TColor = clYellow;
type
TThemeForce = (
forceDark,
forceLight,
forceAuto
);
function Mix(A, B: TColor; Ratio: Integer): TColor;
function IsDarkTheme: Boolean;
procedure UpdateThemeColors(Force: TThemeForce=forceAuto);
implementation
function Mix(A, B: TColor; Ratio: Integer): TColor;
var
RgbA, RgbB: LongInt;
Compl: Integer;
begin
RgbA := ColorToRGB(A);
RgbB := ColorToRGB(B);
Compl := 10 - Ratio;
Result := RGBToColor(
(Red(RgbA) * Compl + Red(RgbB) * Ratio) div 10,
(Green(RgbA) * Compl + Green(RgbB) * Ratio) div 10,
(Blue(RgbA) * Compl + Blue(RgbB) * Ratio) div 10
);
end;
function IsDarkTheme: Boolean;
var
ColW, ColT: LongInt;
begin
ColW := ColorToRGB(clWindow);
ColT := ColorToRGB(clWindowText);
Result := Red(ColW) + Green(ColW) + Blue(ColW) < Red(ColT) + Green(ColT) + Blue(ColT);
end;
procedure UpdateThemeColors(Force: TThemeForce);
var
Dark: Boolean;
begin
case Force of
forceDark: Dark := True;
forceLight: Dark := False;
forceAuto: Dark := IsDarkTheme;
end;
clWindowText20 := Mix(clWindow, clWindowText, 2);
clWindowText40 := Mix(clWindow, clWindowText, 4);
clWindowText60 := Mix(clWindow, clWindowText, 6);
clWindowText80 := Mix(clWindow, clWindowText, 8);
if Dark then begin // tweaked for dark theme
clAutoBlack := clWhite;
clAutoWhite := clBlack;
clAutoAqua := Mix(clAqua, clBlack, 5);
clAutoLime := Mix(clGreen, clYellow, 4);
clAutoSilver := Mix(clSilver, clBlack, 5);
clAutoYellow := Mix(clYellow, clRed, 5);
clAutoBlue := Mix(clBlue, clWhite, 6);
clAutoNavy := Mix(clBlue, clWhite, 4);
clAutoOlive := Mix(clOlive, clWhite, 2);
clAutoGreen := Mix(clGreen, clWhite, 2);
clAutoMaroon := Mix(Mix(clMaroon, clRed, 2), clWhite, 3);
clAutoPurple := Mix(clPurple, clWhite, 5);
clAutoTeal := Mix(clTeal, clWhite, 2);
end
else begin // defaults for light theme
clAutoBlack := clBlack;
clAutoWhite := clWhite;
clAutoAqua := clAqua;
clAutoLime := clLime;
clAutoSilver := clSilver;
clAutoYellow := clYellow;
clAutoBlue := clBlue;
clAutoNavy := clNavy;
clAutoOlive := clOlive;
clAutoGreen := clGreen;
clAutoMaroon := clMaroon;
clAutoPurple := clPurple;
clAutoTeal := clTeal;
end;
end;
initialization
UpdateThemeColors;
end.