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.





Share:
Notifications
Clear all

Lazarus Pascal - Cross platform Dark Theme detectie  

  RSS

 Hans
(@hans)
Noble Member Admin
Lid geworden: 7 jaar geleden
Berichten: 1542
29 augustus 2020 11: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;   
 
This topic was modified 2 maanden geleden by Hans

ReageerCitaat
 Hans
(@hans)
Noble Member Admin
Lid geworden: 7 jaar geleden
Berichten: 1542
29 augustus 2020 12: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;

ReageerCitaat
 Hans
(@hans)
Noble Member Admin
Lid geworden: 7 jaar geleden
Berichten: 1542
29 augustus 2020 13: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;

ReageerCitaat
Share: