From 22758b730e5482c8cf5fb73a015ae55ae939a116 Mon Sep 17 00:00:00 2001 From: robloo Date: Mon, 21 Mar 2022 11:43:41 -0400 Subject: [PATCH] Add ContrastBrushConverter --- .../Converters/ContrastBrushConverter.cs | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/Avalonia.Controls/ColorPicker/Converters/ContrastBrushConverter.cs diff --git a/src/Avalonia.Controls/ColorPicker/Converters/ContrastBrushConverter.cs b/src/Avalonia.Controls/ColorPicker/Converters/ContrastBrushConverter.cs new file mode 100644 index 0000000000..79c38ea53f --- /dev/null +++ b/src/Avalonia.Controls/ColorPicker/Converters/ContrastBrushConverter.cs @@ -0,0 +1,88 @@ +using System; +using System.Globalization; +using Avalonia; +using Avalonia.Controls.Primitives; +using Avalonia.Data.Converters; +using Avalonia.Media; + +namespace FinancialManager.UWP +{ + /// + /// Gets a color, either black or white, depending on the perceived brightness of the supplied color. + /// + public class ContrastBrushConverter : IValueConverter + { + /// + /// Gets or sets the alpha channel threshold below which a default color is used instead of black/white. + /// + public byte AlphaThreshold { get; set; } = 128; + + /// + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + Color comparisonColor; + Color? defaultColor = null; + + // Get the changing color to compare against + if (value is Color valueColor) + { + comparisonColor = valueColor; + } + else if (value is HsvColor valueHsvColor) + { + comparisonColor = valueHsvColor.ToRgb(); + } + else if (value is SolidColorBrush valueBrush) + { + comparisonColor = valueBrush.Color; + } + else + { + // Invalid color value provided + return AvaloniaProperty.UnsetValue; + } + + // Get the default color when transparency is high + if (parameter is Color parameterColor) + { + defaultColor = parameterColor; + } + else if (parameter is HsvColor parameterHsvColor) + { + defaultColor = parameterHsvColor.ToRgb(); + } + else if (parameter is SolidColorBrush parameterBrush) + { + defaultColor = parameterBrush.Color; + } + + if (comparisonColor.A < AlphaThreshold && + defaultColor.HasValue) + { + // If the transparency is less than the threshold just use the default brush + // This can commonly be something like the TextControlForeground brush + return new SolidColorBrush(defaultColor.Value); + } + else + { + // Chose a white/black brush based on contrast to the base color + if (ColorHelpers.GetRelativeLuminance(comparisonColor) > 0.5) + { + // Bright color, use a dark for contrast + return new SolidColorBrush(Colors.Black); + } + else + { + // Dark color, use a light for contrast + return new SolidColorBrush(Colors.White); + } + } + } + + /// + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +}