diff --git a/src/Avalonia.Controls.ColorPicker/ColorSlider/ColorSlider.cs b/src/Avalonia.Controls.ColorPicker/ColorSlider/ColorSlider.cs index 987d08ec64..3c38c6ed1b 100644 --- a/src/Avalonia.Controls.ColorPicker/ColorSlider/ColorSlider.cs +++ b/src/Avalonia.Controls.ColorPicker/ColorSlider/ColorSlider.cs @@ -60,7 +60,7 @@ namespace Avalonia.Controls.Primitives perceivedColor = GetEquivalentBackgroundColor(Color); } - if (ColorHelpers.GetRelativeLuminance(perceivedColor) <= 0.5) + if (ColorHelper.GetRelativeLuminance(perceivedColor) <= 0.5) { PseudoClasses.Set(pcDarkSelector, false); PseudoClasses.Set(pcLightSelector, true); @@ -90,7 +90,7 @@ namespace Avalonia.Controls.Primitives if (pixelWidth != 0 && pixelHeight != 0) { - var bitmap = await ColorHelpers.CreateComponentBitmapAsync( + var bitmap = await ColorPickerHelpers.CreateComponentBitmapAsync( pixelWidth, pixelHeight, Orientation, @@ -102,7 +102,7 @@ namespace Avalonia.Controls.Primitives if (bitmap != null) { - Background = new ImageBrush(ColorHelpers.CreateBitmapFromPixelData(bitmap, pixelWidth, pixelHeight)); + Background = new ImageBrush(ColorPickerHelpers.CreateBitmapFromPixelData(bitmap, pixelWidth, pixelHeight)); } } } diff --git a/src/Avalonia.Controls.ColorPicker/ColorSpectrum/ColorSpectrum.cs b/src/Avalonia.Controls.ColorPicker/ColorSpectrum/ColorSpectrum.cs index 3a58fc048f..245592207e 100644 --- a/src/Avalonia.Controls.ColorPicker/ColorSpectrum/ColorSpectrum.cs +++ b/src/Avalonia.Controls.ColorPicker/ColorSpectrum/ColorSpectrum.cs @@ -152,9 +152,9 @@ namespace Avalonia.Controls.Primitives } if (_selectionEllipsePanel != null && - ColorNameHelpers.ToDisplayNameExists) + ColorHelper.ToDisplayNameExists) { - ToolTip.SetTip(_selectionEllipsePanel, ColorNameHelpers.ToDisplayName(Color)); + ToolTip.SetTip(_selectionEllipsePanel, ColorHelper.ToDisplayName(Color)); } // If we haven't yet created our bitmaps, do so now. @@ -319,7 +319,7 @@ namespace Avalonia.Controls.Primitives IncrementAmount amount = isControlDown ? IncrementAmount.Large : IncrementAmount.Small; HsvColor hsvColor = HsvColor; - UpdateColor(ColorHelpers.IncrementColorComponent( + UpdateColor(ColorPickerHelpers.IncrementColorComponent( new Hsv(hsvColor), incrementComponent, direction, @@ -336,7 +336,7 @@ namespace Avalonia.Controls.Primitives { // We only want to bother with the color name tool tip if we can provide color names. if (_selectionEllipsePanel != null && - ColorNameHelpers.ToDisplayNameExists) + ColorHelper.ToDisplayNameExists) { ToolTip.SetIsOpen(_selectionEllipsePanel, true); } @@ -351,7 +351,7 @@ namespace Avalonia.Controls.Primitives { // We only want to bother with the color name tool tip if we can provide color names. if (_selectionEllipsePanel != null && - ColorNameHelpers.ToDisplayNameExists) + ColorHelper.ToDisplayNameExists) { ToolTip.SetIsOpen(_selectionEllipsePanel, false); } @@ -366,7 +366,7 @@ namespace Avalonia.Controls.Primitives { // We only want to bother with the color name tool tip if we can provide color names. if (_selectionEllipsePanel != null && - ColorNameHelpers.ToDisplayNameExists) + ColorHelper.ToDisplayNameExists) { ToolTip.SetIsOpen(_selectionEllipsePanel, false); } @@ -533,9 +533,9 @@ namespace Avalonia.Controls.Primitives ColorChanged?.Invoke(this, colorChangedEventArgs); if (_selectionEllipsePanel != null && - ColorNameHelpers.ToDisplayNameExists) + ColorHelper.ToDisplayNameExists) { - ToolTip.SetTip(_selectionEllipsePanel, ColorNameHelpers.ToDisplayName(Color)); + ToolTip.SetTip(_selectionEllipsePanel, ColorHelper.ToDisplayName(Color)); } } } @@ -840,7 +840,7 @@ namespace Avalonia.Controls.Primitives // We only want to bother with the color name tool tip if we can provide color names. if (IsFocused && _selectionEllipsePanel != null && - ColorNameHelpers.ToDisplayNameExists) + ColorHelper.ToDisplayNameExists) { ToolTip.SetIsOpen(_selectionEllipsePanel, true); } @@ -1059,8 +1059,8 @@ namespace Avalonia.Controls.Primitives ColorSpectrumComponents components2 = Components; - WriteableBitmap minBitmap = ColorHelpers.CreateBitmapFromPixelData(bgraMinPixelData, pixelWidth, pixelHeight); - WriteableBitmap maxBitmap = ColorHelpers.CreateBitmapFromPixelData(bgraMaxPixelData, pixelWidth, pixelHeight); + WriteableBitmap minBitmap = ColorPickerHelpers.CreateBitmapFromPixelData(bgraMinPixelData, pixelWidth, pixelHeight); + WriteableBitmap maxBitmap = ColorPickerHelpers.CreateBitmapFromPixelData(bgraMaxPixelData, pixelWidth, pixelHeight); switch (components2) { @@ -1076,10 +1076,10 @@ namespace Avalonia.Controls.Primitives case ColorSpectrumComponents.ValueSaturation: case ColorSpectrumComponents.SaturationValue: _hueRedBitmap = minBitmap; - _hueYellowBitmap = ColorHelpers.CreateBitmapFromPixelData(bgraMiddle1PixelData, pixelWidth, pixelHeight); - _hueGreenBitmap = ColorHelpers.CreateBitmapFromPixelData(bgraMiddle2PixelData, pixelWidth, pixelHeight); - _hueCyanBitmap = ColorHelpers.CreateBitmapFromPixelData(bgraMiddle3PixelData, pixelWidth, pixelHeight); - _hueBlueBitmap = ColorHelpers.CreateBitmapFromPixelData(bgraMiddle4PixelData, pixelWidth, pixelHeight); + _hueYellowBitmap = ColorPickerHelpers.CreateBitmapFromPixelData(bgraMiddle1PixelData, pixelWidth, pixelHeight); + _hueGreenBitmap = ColorPickerHelpers.CreateBitmapFromPixelData(bgraMiddle2PixelData, pixelWidth, pixelHeight); + _hueCyanBitmap = ColorPickerHelpers.CreateBitmapFromPixelData(bgraMiddle3PixelData, pixelWidth, pixelHeight); + _hueBlueBitmap = ColorPickerHelpers.CreateBitmapFromPixelData(bgraMiddle4PixelData, pixelWidth, pixelHeight); _huePurpleBitmap = maxBitmap; break; } @@ -1598,7 +1598,7 @@ namespace Avalonia.Controls.Primitives displayedColor = Color; } - var lum = ColorHelpers.GetRelativeLuminance(displayedColor); + var lum = ColorHelper.GetRelativeLuminance(displayedColor); return lum <= 0.5; } diff --git a/src/Avalonia.Controls.ColorPicker/Converters/ColorToDisplayNameConverter.cs b/src/Avalonia.Controls.ColorPicker/Converters/ColorToDisplayNameConverter.cs index 94a529b549..02105668bb 100644 --- a/src/Avalonia.Controls.ColorPicker/Converters/ColorToDisplayNameConverter.cs +++ b/src/Avalonia.Controls.ColorPicker/Converters/ColorToDisplayNameConverter.cs @@ -51,7 +51,7 @@ namespace Avalonia.Controls.Converters } else { - return ColorNameHelpers.ToDisplayName(color); + return ColorHelper.ToDisplayName(color); } } diff --git a/src/Avalonia.Controls.ColorPicker/Helpers/ColorNameHelpers.cs b/src/Avalonia.Controls.ColorPicker/Helpers/ColorHelper.cs similarity index 75% rename from src/Avalonia.Controls.ColorPicker/Helpers/ColorNameHelpers.cs rename to src/Avalonia.Controls.ColorPicker/Helpers/ColorHelper.cs index 303a52f00b..32a898ee71 100644 --- a/src/Avalonia.Controls.ColorPicker/Helpers/ColorNameHelpers.cs +++ b/src/Avalonia.Controls.ColorPicker/Helpers/ColorHelper.cs @@ -7,13 +7,39 @@ using System.Text; namespace Avalonia.Controls.Primitives { /// - /// Contains helpers useful when working with color names. + /// Contains helpers useful when working with colors. /// - public static class ColorNameHelpers + public static class ColorHelper { private static readonly Dictionary cachedDisplayNames = new Dictionary(); private static readonly object cacheMutex = new object(); + /// + /// Gets the relative (perceptual) luminance/brightness of the given color. + /// 1 is closer to white while 0 is closer to black. + /// + /// The color to calculate relative luminance for. + /// The relative (perceptual) luminance/brightness of the given color. + public static double GetRelativeLuminance(Color color) + { + // The equation for relative luminance is given by + // + // L = 0.2126 * Rg + 0.7152 * Gg + 0.0722 * Bg + // + // where Xg = { X/3294 if X <= 10, (R/269 + 0.0513)^2.4 otherwise } + // + // If L is closer to 1, then the color is closer to white; if it is closer to 0, + // then the color is closer to black. This is based on the fact that the human + // eye perceives green to be much brighter than red, which in turn is perceived to be + // brighter than blue. + + double rg = color.R <= 10 ? color.R / 3294.0 : Math.Pow(color.R / 269.0 + 0.0513, 2.4); + double gg = color.G <= 10 ? color.G / 3294.0 : Math.Pow(color.G / 269.0 + 0.0513, 2.4); + double bg = color.B <= 10 ? color.B / 3294.0 : Math.Pow(color.B / 269.0 + 0.0513, 2.4); + + return (0.2126 * rg + 0.7152 * gg + 0.0722 * bg); + } + /// /// Determines if color display names are supported based on the current thread culture. /// diff --git a/src/Avalonia.Controls.ColorPicker/Helpers/ColorHelpers.cs b/src/Avalonia.Controls.ColorPicker/Helpers/ColorPickerHelpers.cs similarity index 92% rename from src/Avalonia.Controls.ColorPicker/Helpers/ColorHelpers.cs rename to src/Avalonia.Controls.ColorPicker/Helpers/ColorPickerHelpers.cs index 3b2dc5a805..c1904a3c30 100644 --- a/src/Avalonia.Controls.ColorPicker/Helpers/ColorHelpers.cs +++ b/src/Avalonia.Controls.ColorPicker/Helpers/ColorPickerHelpers.cs @@ -16,7 +16,10 @@ using Avalonia.Utilities; namespace Avalonia.Controls.Primitives { - internal static class ColorHelpers + /// + /// Contains internal, special-purpose helpers used with the color picker. + /// + internal static class ColorPickerHelpers { /// /// Generates a new bitmap of the specified size by changing a specific color component. @@ -34,7 +37,7 @@ namespace Avalonia.Controls.Primitives /// during calculation with the HSVA color model. /// This will ensure colors are always discernible regardless of saturation/value. /// A new bitmap representing a gradient of color component values. - internal static async Task CreateComponentBitmapAsync( + public static async Task CreateComponentBitmapAsync( int width, int height, Orientation orientation, @@ -314,7 +317,7 @@ namespace Avalonia.Controls.Primitives { Hsv newHsv = originalHsv; - if (amount == IncrementAmount.Small || !ColorNameHelpers.ToDisplayNameExists) + if (amount == IncrementAmount.Small || !ColorHelper.ToDisplayNameExists) { // In order to avoid working with small values that can incur rounding issues, // we'll multiple saturation and value by 100 to put them in the range of 0-100 instead of 0-1. @@ -405,7 +408,7 @@ namespace Avalonia.Controls.Primitives // in the middle of that color's bounds. Hsv newHsv = originalHsv; - string originalColorName = ColorNameHelpers.ToDisplayName(originalHsv.ToRgb().ToColor()); + string originalColorName = ColorHelper.ToDisplayName(originalHsv.ToRgb().ToColor()); string newColorName = originalColorName; // Note: *newValue replaced with ref local variable for C#, must be initialized @@ -460,7 +463,7 @@ namespace Avalonia.Controls.Primitives { newValue = maxBound; shouldFindMidPoint = false; - newColorName = ColorNameHelpers.ToDisplayName(newHsv.ToRgb().ToColor()); + newColorName = ColorHelper.ToDisplayName(newHsv.ToRgb().ToColor()); break; } } @@ -475,7 +478,7 @@ namespace Avalonia.Controls.Primitives { newValue = minBound; shouldFindMidPoint = false; - newColorName = ColorNameHelpers.ToDisplayName(newHsv.ToRgb().ToColor()); + newColorName = ColorHelper.ToDisplayName(newHsv.ToRgb().ToColor()); break; } } @@ -490,7 +493,7 @@ namespace Avalonia.Controls.Primitives break; } - newColorName = ColorNameHelpers.ToDisplayName(newHsv.ToRgb().ToColor()); + newColorName = ColorHelper.ToDisplayName(newHsv.ToRgb().ToColor()); } if (shouldFindMidPoint) @@ -563,7 +566,7 @@ namespace Avalonia.Controls.Primitives } } - currentColorName = ColorNameHelpers.ToDisplayName(currentHsv.ToRgb().ToColor()); + currentColorName = ColorHelper.ToDisplayName(currentHsv.ToRgb().ToColor()); } newValue = (startValue + currentValue + startEndOffset) / 2; @@ -622,31 +625,5 @@ namespace Avalonia.Controls.Primitives return bitmap; } - - /// - /// Gets the relative (perceptual) luminance/brightness of the given color. - /// 1 is closer to white while 0 is closer to black. - /// - /// The color to calculate relative luminance for. - /// The relative (perceptual) luminance/brightness of the given color. - public static double GetRelativeLuminance(Color color) - { - // The equation for relative luminance is given by - // - // L = 0.2126 * Rg + 0.7152 * Gg + 0.0722 * Bg - // - // where Xg = { X/3294 if X <= 10, (R/269 + 0.0513)^2.4 otherwise } - // - // If L is closer to 1, then the color is closer to white; if it is closer to 0, - // then the color is closer to black. This is based on the fact that the human - // eye perceives green to be much brighter than red, which in turn is perceived to be - // brighter than blue. - - double rg = color.R <= 10 ? color.R / 3294.0 : Math.Pow(color.R / 269.0 + 0.0513, 2.4); - double gg = color.G <= 10 ? color.G / 3294.0 : Math.Pow(color.G / 269.0 + 0.0513, 2.4); - double bg = color.B <= 10 ? color.B / 3294.0 : Math.Pow(color.B / 269.0 + 0.0513, 2.4); - - return (0.2126 * rg + 0.7152 * gg + 0.0722 * bg); - } } }