Pagina1 van 1
Forum

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.



Deel:
Meldingen
Alles wissen

[Opgelost] Lazarus Pascal - Cross platform Dark Theme detectie

3 Berichten
1 Gebruikers
0 Reactions
1,236 Bekeken
 Hans
(@hans)
Famed Member Admin
Deelgenomen: 11 jaar geleden
Berichten: 2797
Topic starter  
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;   
 

   
BeantwoordenCiteren
 Hans
(@hans)
Famed Member Admin
Deelgenomen: 11 jaar geleden
Berichten: 2797
Topic starter  

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;

   
BeantwoordenCiteren
 Hans
(@hans)
Famed Member Admin
Deelgenomen: 11 jaar geleden
Berichten: 2797
Topic starter  

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;

   
BeantwoordenCiteren
Deel: