Welkom bij de Tweaking4All gemeenschapsforums!
Voor je gaat deelnemen, bekijk de Forum Regels!
Specifieke onderwerpen: Start het onderwerp met de naam van het programma of systeem.
Bijvoorbeeld “MacOS X – Jouw vraag“, of bijvoorbeeld “MS Word – Jouw Tip of Truc“.
Merk op: Omschakelen naar een andere taal zal niet werken als je een post aan het lezen bent aangezien er waarschijnlijk geen vertaling beschikbaar is.
[Opgelost] Lazarus Pascal - Cross platform Dark Theme detectie
Delphi, Lazarus, Free Pascal
(@hans)
Famed Member Admin
Deelgenomen: 11 jaar geleden
Berichten: 2797
Topic starter
29 augustus 2020 10:59
Ik gebruik zelf het volgende voor cross platform dark theme detectie.
Hierbij vergelijk ik de systeem kleuren clWindow en clWindowText, omdat deze keurig mee veranderen en altijd een hoog contrast hebben met elkaar (om dingen leesbaar te houden).
Het gebruikt geen speciale systeem functies en tot nu toe werkte dit altijd prima onder macOS en Linux. 😊
// t4a_IsThisDarkTheme: Detects if the Dark Theme (true) has been enabled or not (false)
function t4a_ThisIsDarkTheme:boolean;
begin
Result := t4a_ColorToGrayScale(clWindow) < t4a_ColorToGrayScale(clWindowText); // guess dark theme
end;
{ Convert a color to grayscale, observing perception }
function t4a_ColorToGrayScale(aColor:TColor):TColor;
var
GreyNumber:integer;
begin
Result:=ColorToRGB(aColor);
// Convert Color to Grayscale if not yet Grayscale
// Grayscale = (0.3 * Red) + (0.59 * Green) + (0.11 * Blue)
// Alternative = (0.2126 * Red) + (0.7152 * Green) + (0.0722 * Blue)
if (Red(Result)<>Green(Result)) and (Red(Result)<>Blue(Result)) then
begin
GreyNumber:= ( ( MathRound(Red(Result) * 0.3) +
MathRound(Green(Result) * 0.59) +
MathRound(Blue(Result) * 0.11) ) div 3);
if GreyNumber<0 then
GreyNumber:=0
else if GreyNumber>255 then
GreyNumber:=255;
Result:=RGBToColor(GreyNumber,GreyNumber,GreyNumber);
end;
end;
Plaats vervolgens de detectie in een Form.OnPaint event, aangezien deze aangeroepen wordt als een theme veranderd.
procedure TForm1.FormPaint(Sender: TObject);
begin
Label1.Caption := BoolToStr( t4a_ThisIsDarkTheme, 'Dark Theme', 'Light Theme' );
end;
(@hans)
Famed Member Admin
Deelgenomen: 11 jaar geleden
Berichten: 2797
Topic starter
29 augustus 2020 11:21
N.b.: Dit kan uiteraard korter en zonder de grayscale functie:
// t4a_IsThisDarkTheme: Detects if the Dark Theme (true) has been enabled or not (false)
function TForm1.t4a_ThisIsDarkTheme:boolean;
var
RGBWin, RGBText: TColor;
const
Rgray = 0.3;
Ggray = 0.59;
Bgray = 0.11;
begin
RGBWin := ColorToRGB(clWindow);
RGBText:= ColorToRGB(clWindowText);
Result := ((Red(RGBWin)*Rgray)+(Green(RGBWin)*Ggray)+(Blue(RGBWin)*Bgray)) < ((Red(RGBText)*Rgray)+(Green(RGBText)*Ggray)+(Blue(RGBText)*Bgray));
end;
(@hans)
Famed Member Admin
Deelgenomen: 11 jaar geleden
Berichten: 2797
Topic starter
29 augustus 2020 12:32
En het kan zelfs nog korter (met dank aan Alextp van het Lazarus forum):
// by "Hansaplast" & "Alextp" from Lazarus forum
function IsDarkTheme: boolean;
function _Level(C: TColor): double;
begin
Result:= Red(C)*0.3 + Green(C)*0.59 + Blue(C)*0.11;
end;
begin
Result:= _Level(ColorToRGB(clWindow)) < _Level(ColorToRGB(clWindowText));
end;