|
|
|
@ -13,6 +13,11 @@ namespace Avalonia.Controls.Primitives.Converters |
|
|
|
/// </remarks>
|
|
|
|
public class AccentColorConverter : IValueConverter |
|
|
|
{ |
|
|
|
/// <summary>
|
|
|
|
/// The amount to change the Value component for each accent color step.
|
|
|
|
/// </summary>
|
|
|
|
public const double ValueDelta = 0.1; |
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
public object? Convert( |
|
|
|
object? value, |
|
|
|
@ -96,54 +101,13 @@ namespace Avalonia.Controls.Primitives.Converters |
|
|
|
/// <returns>The new accent color.</returns>
|
|
|
|
public static HsvColor GetAccent(HsvColor hsvColor, int accentStep) |
|
|
|
{ |
|
|
|
// Accent steps are taken from the FluentTheme:
|
|
|
|
// SystemAccentColors.cs -> CalculateAccentShades()
|
|
|
|
//
|
|
|
|
// This is currently believed to be the most accurate representation of the algorithm in Windows.
|
|
|
|
// It replaces the previous implementation which adjusted Value +/- 10% per step.
|
|
|
|
// Any changes to FluentTheme's accent color calculation should be copied here.
|
|
|
|
|
|
|
|
const double dark1step = 28.5 / 255d; |
|
|
|
const double dark2step = 49 / 255d; |
|
|
|
const double dark3step = 74.5 / 255d; |
|
|
|
const double light1step = 39 / 255d; |
|
|
|
const double light2step = 70 / 255d; |
|
|
|
const double light3step = 103 / 255d; |
|
|
|
|
|
|
|
if (accentStep != 0) |
|
|
|
{ |
|
|
|
// Temporary colors are used to preserve Hue through the RGB conversion
|
|
|
|
// Otherwise, at Black/White hue information would be lost
|
|
|
|
// This should be improved in the future with direct conversions to/from HSV/HSL.
|
|
|
|
var hslAccent = hsvColor.ToHsl(); |
|
|
|
|
|
|
|
double lightnessAdjustment = 0.0; |
|
|
|
switch (accentStep) |
|
|
|
{ |
|
|
|
case -3: |
|
|
|
lightnessAdjustment = -dark3step; |
|
|
|
break; |
|
|
|
case -2: |
|
|
|
lightnessAdjustment = -dark2step; |
|
|
|
break; |
|
|
|
case -1: |
|
|
|
lightnessAdjustment = -dark1step; |
|
|
|
break; |
|
|
|
case 1: |
|
|
|
lightnessAdjustment = light1step; |
|
|
|
break; |
|
|
|
case 2: |
|
|
|
lightnessAdjustment = light2step; |
|
|
|
break; |
|
|
|
case 3: |
|
|
|
lightnessAdjustment = light3step; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
var adjustedHsl = new HslColor(hslAccent.A, hslAccent.H, hslAccent.S, hslAccent.L + lightnessAdjustment); |
|
|
|
// Rounding may be required here
|
|
|
|
double colorValue = hsvColor.V; |
|
|
|
colorValue += (accentStep * AccentColorConverter.ValueDelta); |
|
|
|
colorValue = Math.Round(colorValue, 2); |
|
|
|
|
|
|
|
return adjustedHsl.ToHsv(); |
|
|
|
return new HsvColor(hsvColor.A, hsvColor.H, hsvColor.S, colorValue); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
|