Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/xamarin/Xamarin.PropertyEditing.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Xamarin.PropertyEditing.Tests/CommonColorTests.cs80
-rw-r--r--Xamarin.PropertyEditing.Windows/EditorPropertySelector.cs2
-rw-r--r--Xamarin.PropertyEditing.Windows/ResourceBrushEditorControl.cs8
-rw-r--r--Xamarin.PropertyEditing/Drawing/CommonColor.cs271
-rw-r--r--Xamarin.PropertyEditing/ViewModels/MaterialDesignColorViewModel.cs14
5 files changed, 194 insertions, 181 deletions
diff --git a/Xamarin.PropertyEditing.Tests/CommonColorTests.cs b/Xamarin.PropertyEditing.Tests/CommonColorTests.cs
index f9f579f..3038f7d 100644
--- a/Xamarin.PropertyEditing.Tests/CommonColorTests.cs
+++ b/Xamarin.PropertyEditing.Tests/CommonColorTests.cs
@@ -9,30 +9,32 @@ namespace Xamarin.PropertyEditing.Tests
public class CommonColorTests
{
public static readonly Dictionary<string, ColorTestCase> PrimaryTestCases = new Dictionary<string, ColorTestCase> {
- // { name, r g b c% m% y% k% h° l% s% b% a}
- { "Black", new ColorTestCase( 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0) },
- { "White", new ColorTestCase(255, 255, 255, 0, 0, 0, 0, 0, 100, 0, 100) },
- { "Gray", new ColorTestCase(127, 127, 127, 0, 0, 0, 50, 0, 50, 0, 50) },
- { "Silver", new ColorTestCase(191, 191, 191, 0, 0, 0, 25, 0, 75, 0, 75) },
- { "Red", new ColorTestCase(255, 0, 0, 0, 100, 100, 0, 0, 50, 100, 100) },
- { "Lime", new ColorTestCase( 0, 255, 0, 100, 0, 100, 0, 120, 50, 100, 100) },
- { "Blue", new ColorTestCase( 0, 0, 255, 100, 100, 0, 0, 240, 50, 100, 100) },
- { "Yellow", new ColorTestCase(255, 255, 0, 0, 0, 100, 0, 60, 50, 100, 100) },
- { "Cyan", new ColorTestCase( 0, 255, 255, 100, 0, 0, 0, 180, 50, 100, 100) },
- { "Magenta", new ColorTestCase(255, 0, 255, 0, 100, 0, 0, 300, 50, 100, 100) },
- { "Maroon", new ColorTestCase(127, 0, 0, 0, 100, 100, 50, 0, 25, 100, 50) },
- { "Green", new ColorTestCase( 0, 127, 0, 100, 0, 100, 50, 120, 25, 100, 50) },
- { "Navy", new ColorTestCase( 0, 0, 127, 100, 100, 0, 50, 240, 25, 100, 50) },
- { "Olive", new ColorTestCase(127, 127, 0, 0, 0, 100, 50, 60, 25, 100, 50) },
- { "Purple", new ColorTestCase(127, 0, 127, 0, 100, 0, 50, 300, 25, 100, 50) },
- { "Teal", new ColorTestCase( 0, 127, 127, 100, 0, 0, 50, 180, 25, 100, 50) },
+ // { name, r g b c% m% y% k% h° l% s% b% }
+ { "Black", new ColorTestCase( 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0) },
+ { "White", new ColorTestCase(255, 255, 255, 0, 0, 0, 0, 0, 100, 0, 100) },
+ { "Gray", new ColorTestCase(128, 128, 128, 0, 0, 0, 50, 0, 50, 0, 50) },
+ { "Silver", new ColorTestCase(191, 191, 191, 0, 0, 0, 25, 0, 74.9, 0, 74.9) },
+ { "Red", new ColorTestCase(255, 0, 0, 0, 100, 100, 0, 0, 50, 100, 100) },
+ { "Lime", new ColorTestCase( 0, 255, 0, 100, 0, 100, 0, 120, 50, 100, 100) },
+ { "Blue", new ColorTestCase( 0, 0, 255, 100, 100, 0, 0, 240, 50, 100, 100) },
+ { "Yellow", new ColorTestCase(255, 255, 0, 0, 0, 100, 0, 60, 50, 100, 100) },
+ { "Cyan", new ColorTestCase( 0, 255, 255, 100, 0, 0, 0, 180, 50, 100, 100) },
+ { "Magenta", new ColorTestCase(255, 0, 255, 0, 100, 0, 0, 300, 50, 100, 100) },
+ { "Maroon", new ColorTestCase(128, 0, 0, 0, 100, 100, 50, 0, 25.1, 100, 50) },
+ { "Green", new ColorTestCase( 0, 128, 0, 100, 0, 100, 50, 120, 25.1, 100, 50) },
+ { "Navy", new ColorTestCase( 0, 0, 128, 100, 100, 0, 50, 240, 25.1, 100, 50) },
+ { "Olive", new ColorTestCase(128, 128, 0, 0, 0, 100, 50, 60, 25.1, 100, 50) },
+ { "Purple", new ColorTestCase(128, 0, 128, 0, 100, 0, 50, 300, 25.1, 100, 50) },
+ { "Teal", new ColorTestCase( 0, 128, 128, 100, 0, 0, 50, 180, 25.1, 100, 50) },
};
public static readonly Dictionary<string, ColorTestCase> RGBTestCases = new Dictionary<string, ColorTestCase> {
- // { name, r g b c% m% y% k% h° l% s% b% a}
- { "Orange", new ColorTestCase(255, 164, 0, 0, 35.7, 100, 0, 38.6, 50, 100, 100) },
- { "MediumSpringGreen", new ColorTestCase( 0, 250, 154, 100, 0, 38, 2, 157, 49, 100, 98) },
- { "Chocolate", new ColorTestCase(209, 117, 52, 0, 44, 75.1, 18, 24.8, 47, 75.1, 82) },
+ // { name, r g b c% m% y% k% h° l% s% b% }
+ { "Orange", new ColorTestCase(255, 164, 0, 0, 35.7, 100, 0, 38.6, 50, 100, 100) },
+ { "MediumSpringGreen", new ColorTestCase( 0, 250, 155, 100, 0, 38, 2, 157.2, 49, 100, 98) },
+ { "Chocolate", new ColorTestCase(209, 117, 52, 0, 44, 75.1, 18, 24.8, 51, 75.1, 82) },
+ { "MoreOrange", new ColorTestCase(200, 101, 31, 0, 49.5, 84.5, 21.6, 24.9, 45.3, 84.5, 78.4) },
+ { "Lilac", new ColorTestCase(101, 31, 255, 60.4, 87.8, 0, 0, 258.8, 56.1, 87.8, 100) },
};
[Test, TestCaseSource (typeof(CommonColorTests), "HueColorFromColorCases")]
@@ -71,6 +73,9 @@ namespace Xamarin.PropertyEditing.Tests
foreach (KeyValuePair<string, ColorTestCase> testCaseKVP in PrimaryTestCases) {
yield return new TestCaseData (testCaseKVP.Value.CMYK).Returns (testCaseKVP.Value.Color).SetName ("ColorFromCMYK_" + testCaseKVP.Key);
}
+ foreach (KeyValuePair<string, ColorTestCase> testCaseKVP in RGBTestCases) {
+ yield return new TestCaseData (testCaseKVP.Value.CMYK).Returns (testCaseKVP.Value.Color).SetName ("ColorFromCMYK_" + testCaseKVP.Key);
+ }
}
[Test, TestCaseSource (typeof (CommonColorTests), "HLSFromColorCases")]
@@ -94,6 +99,10 @@ namespace Xamarin.PropertyEditing.Tests
foreach (KeyValuePair<string, ColorTestCase> testCaseKVP in PrimaryTestCases) {
yield return new TestCaseData (testCaseKVP.Value.HLS).Returns (testCaseKVP.Value.Color).SetName ("ColorFromHLS_" + testCaseKVP.Key);
}
+ // HLS -> RGB conversion is the least reliable, and round-tripping it doesn't quite guarantee accurate enough results that they can be tested for arbitrary colors.
+ //foreach (KeyValuePair<string, ColorTestCase> testCaseKVP in RGBTestCases) {
+ // yield return new TestCaseData (testCaseKVP.Value.HLS).Returns (testCaseKVP.Value.Color).SetName ("ColorFromHLS_" + testCaseKVP.Key);
+ //}
}
[Test, TestCaseSource (typeof (CommonColorTests), "HLSRoundTripCases")]
@@ -108,6 +117,9 @@ namespace Xamarin.PropertyEditing.Tests
foreach (KeyValuePair<string, ColorTestCase> testCaseKVP in PrimaryTestCases) {
yield return new TestCaseData (testCaseKVP.Value.HLS).Returns (testCaseKVP.Value.HLS).SetName ("HLSRoundTrip_" + testCaseKVP.Key);
}
+ foreach (KeyValuePair<string, ColorTestCase> testCaseKVP in RGBTestCases) {
+ yield return new TestCaseData (testCaseKVP.Value.HLS).Returns (testCaseKVP.Value.HLS).SetName ("HLSRoundTrip_" + testCaseKVP.Key);
+ }
}
[Test, TestCaseSource (typeof (CommonColorTests), "HSBFromColorCases")]
@@ -131,6 +143,9 @@ namespace Xamarin.PropertyEditing.Tests
foreach (KeyValuePair<string, ColorTestCase> testCaseKVP in PrimaryTestCases) {
yield return new TestCaseData (testCaseKVP.Value.HSB).Returns (testCaseKVP.Value.Color).SetName ("ColorFromHSB_" + testCaseKVP.Key);
}
+ foreach (KeyValuePair<string, ColorTestCase> testCaseKVP in RGBTestCases) {
+ yield return new TestCaseData (testCaseKVP.Value.HSB).Returns (testCaseKVP.Value.Color).SetName ("ColorFromHSB_" + testCaseKVP.Key);
+ }
}
[Test, TestCaseSource (typeof (CommonColorTests), "HSBRoundTripCases")]
@@ -145,6 +160,9 @@ namespace Xamarin.PropertyEditing.Tests
foreach (KeyValuePair<string, ColorTestCase> testCaseKVP in PrimaryTestCases) {
yield return new TestCaseData (testCaseKVP.Value.HSB).Returns (testCaseKVP.Value.HSB).SetName ("HSBRoundTrip_" + testCaseKVP.Key);
}
+ foreach (KeyValuePair<string, ColorTestCase> testCaseKVP in RGBTestCases) {
+ yield return new TestCaseData (testCaseKVP.Value.HSB).Returns (testCaseKVP.Value.HSB).SetName ("HSBRoundTrip_" + testCaseKVP.Key);
+ }
}
[Test]
@@ -189,10 +207,10 @@ namespace Xamarin.PropertyEditing.Tests
public override bool Equals (object obj)
{
var other = (CMYK)obj;
- return Math.Round (other.C - C, 2) == 0
- && Math.Round (other.M - M, 2) == 0
- && Math.Round (other.Y - Y, 2) == 0
- && Math.Round (other.K - K, 2) == 0;
+ return Math.Round (other.C, 2) == Math.Round(C, 2)
+ && Math.Round (other.M, 2) == Math.Round (M, 2)
+ && Math.Round (other.Y, 2) == Math.Round (Y, 2)
+ && Math.Round (other.K, 2) == Math.Round (K, 2);
}
public override string ToString () => $"{{ C:{C:P1}, M:{M:P1}, Y:{Y:P1}, K:{K:P1} }}";
@@ -214,9 +232,9 @@ namespace Xamarin.PropertyEditing.Tests
public override bool Equals (object obj)
{
var other = (HLS)obj;
- return Math.Round (other.Hue - Hue, 1) == 0
- && Math.Round (other.Lightness - Lightness, 1) == 0
- && Math.Round (other.Saturation - Saturation, 1) == 0;
+ return Math.Round (other.Hue, 1) == Math.Round(Hue, 1)
+ && Math.Round (other.Lightness, 1) == Math.Round(Lightness, 1)
+ && Math.Round (other.Saturation, 1) == Math.Round(Saturation, 1);
}
public override string ToString () => $"{{ H:{Hue:F1}°, S:{Saturation:P1}, L:{Lightness:P1} }}";
@@ -238,9 +256,9 @@ namespace Xamarin.PropertyEditing.Tests
public override bool Equals (object obj)
{
var other = (HSB)obj;
- return Math.Round (other.Hue - Hue, 1) == 0
- && Math.Round (other.Saturation - Saturation, 1) == 0
- && Math.Round (other.Brightness - Brightness, 1) == 0;
+ return Math.Round (other.Hue, 1) == Math.Round(Hue, 1)
+ && Math.Round (other.Saturation, 1) == Math.Round(Saturation, 1)
+ && Math.Round (other.Brightness, 1) == Math.Round(Brightness, 1);
}
public override string ToString () => $"{{ H:{Hue:F1}°, S:{Saturation:P1}, B:{Brightness:P1} }}";
diff --git a/Xamarin.PropertyEditing.Windows/EditorPropertySelector.cs b/Xamarin.PropertyEditing.Windows/EditorPropertySelector.cs
index 22118c3..9cddbe8 100644
--- a/Xamarin.PropertyEditing.Windows/EditorPropertySelector.cs
+++ b/Xamarin.PropertyEditing.Windows/EditorPropertySelector.cs
@@ -47,8 +47,6 @@ namespace Xamarin.PropertyEditing.Windows
return base.TryGetTemplateType (type, out templateType);
}
- private static readonly EditorPropertySelector selector;
-
private static readonly Dictionary<Type, Type> TypeMap = new Dictionary<Type, Type> {
{ typeof(BrushPropertyViewModel), typeof(BrushTabbedEditorControl) }
};
diff --git a/Xamarin.PropertyEditing.Windows/ResourceBrushEditorControl.cs b/Xamarin.PropertyEditing.Windows/ResourceBrushEditorControl.cs
index 53876b6..6d3a3ca 100644
--- a/Xamarin.PropertyEditing.Windows/ResourceBrushEditorControl.cs
+++ b/Xamarin.PropertyEditing.Windows/ResourceBrushEditorControl.cs
@@ -1,11 +1,5 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
-using Xamarin.PropertyEditing.Drawing;
using Xamarin.PropertyEditing.ViewModels;
namespace Xamarin.PropertyEditing.Windows
@@ -17,8 +11,6 @@ namespace Xamarin.PropertyEditing.Windows
DefaultStyleKeyProperty.OverrideMetadata (typeof (ResourceBrushEditorControl), new FrameworkPropertyMetadata (typeof (ResourceBrushEditorControl)));
}
- ListBox resourceList;
-
BrushPropertyViewModel ViewModel => DataContext as BrushPropertyViewModel;
}
}
diff --git a/Xamarin.PropertyEditing/Drawing/CommonColor.cs b/Xamarin.PropertyEditing/Drawing/CommonColor.cs
index 632b033..73e563a 100644
--- a/Xamarin.PropertyEditing/Drawing/CommonColor.cs
+++ b/Xamarin.PropertyEditing/Drawing/CommonColor.cs
@@ -9,87 +9,72 @@ namespace Xamarin.PropertyEditing.Drawing
public struct CommonColor : IEquatable<CommonColor>
{
public CommonColor (byte r, byte g, byte b, byte a = 255, string label = null)
+ : this ((double)r, g, b, a, label) { }
+ private CommonColor (double r, double g, double b, byte a = 255, string label = null)
{
+ this.r = r;
+ this.g = g;
+ this.b = b;
A = a;
- R = r;
- G = g;
- B = b;
Label = label;
- c = null;
- m = null;
- y = null;
- k = null;
- hueR = null;
- hueG = 0;
- hueB = 0;
- hue = null;
- lightness = null;
- brightness = null;
- saturation = null;
+ this.c = null;
+ this.m = null;
+ this.y = null;
+ this.k = null;
+ this.hueR = null;
+ this.hueG = 0;
+ this.hueB = 0;
+ this.hue = null;
+ this.lightness = null;
+ this.brightness = null;
+ this.saturation = null;
}
/// <summary>
- /// Alpha channel
- /// </summary>
- public byte A { get; }
-
- /// <summary>
/// Red component
/// </summary>
- public byte R { get; }
+ public byte R => DoubleToByte (this.r);
/// <summary>
/// Green component
/// </summary>
- public byte G { get; }
+ public byte G => DoubleToByte (this.g);
/// <summary>
/// Blue component
/// </summary>
- public byte B { get; }
+ public byte B => DoubleToByte (this.b);
+
+ /// <summary>
+ /// Alpha channel
+ /// </summary>
+ public byte A { get; }
/// <summary>
/// An optional label for the color, that does not affect equality or anything else.
/// </summary>
public string Label { get; set; }
- double? k;
/// <summary>
/// Black component
/// </summary>
- public double K => k ?? (k = (double)(255 - (R >= G ? (R >= B ? R : B) : (G >= B ? G : B))) / 255).Value;
-
- double Complement(byte component, double k)
- {
- if (k == 1) return 0;
- var val = (1 - k - (double)component / 255) / (1 - k);
- if (val < 0) return 0;
- if (val > 1) return 1;
- return val;
- }
-
- double? c;
+ public double K => this.k ?? (this.k =
+ (255 - (this.r >= this.g ? (this.r >= this.b ? this.r : this.b) : (this.g >= this.b ? this.g : this.b))) / 255).Value;
/// <summary>
/// Cyan component
/// </summary>
- public double C => c ?? (c = Complement(R, K)).Value;
+ public double C => this.c ?? (this.c = Complement(this.r, K)).Value;
- double? m;
/// <summary>
/// Magenta component
/// </summary>
- public double M => m ?? (m = Complement(G, K)).Value;
+ public double M => this.m ?? (this.m = Complement(this.g, K)).Value;
- double? y;
/// <summary>
/// Yellow component
/// </summary>
- public double Y => y ?? (y = Complement(B, K)).Value;
+ public double Y => this.y ?? (this.y = Complement(this.b, K)).Value;
- static readonly CommonColor Red = new CommonColor (255, 0, 0);
-
- byte? hueR;
- byte hueG, hueB;
/// <summary>
/// Gets a hue from this color.
/// A hue has the highest component of the passed-in color at 255,
@@ -101,103 +86,103 @@ namespace Xamarin.PropertyEditing.Drawing
/// </summary>
public CommonColor HueColor {
get {
- if (hueR.HasValue) return new CommonColor(hueR.Value, hueG, hueB);
+ if (this.hueR.HasValue)
+ return new CommonColor(this.hueR.Value, this.hueG, this.hueB);
// Map grey to red
if (IsGrey) {
- hueR = 255;
- hueG = 0;
- hueB = 0;
- hue = 0;
- return Red;
+ this.hueR = 255;
+ this.hueG = 0;
+ this.hueB = 0;
+ this.hue = 0;
+ return new CommonColor(255, 0, 0);
}
- var isRedMax = R >= G && R >= B;
- var isGreenMax = G >= R && G >= B;
- var isRedMin = R <= G && R <= B;
- var isGreenMin = G <= R && G <= B;
+ var isRedMax = this.r >= this.g && this.r >= this.b;
+ var isGreenMax = this.g >= this.r && this.g >= this.b;
+ var isRedMin = this.r <= this.g && this.r <= this.b;
+ var isGreenMin = this.g <= this.r && this.g <= this.b;
CommonColor hueColor =
isRedMax ?
// Red is max
isGreenMin ?
// Green is min
- new CommonColor (255, 0, InterpolateComponent (B, G, R)) :
+ new CommonColor (255, 0, InterpolateComponent (this.b, this.g, this.r)) :
// Blue is min
- new CommonColor (255, InterpolateComponent (G, B, R), 0) :
+ new CommonColor (255, InterpolateComponent (this.g, this.b, this.r), 0) :
isGreenMax ?
// Green is max
isRedMin ?
// Red is min
- new CommonColor (0, 255, InterpolateComponent (B, R, G)) :
+ new CommonColor (0, 255, InterpolateComponent (this.b, this.r, this.g)) :
// Blue is min
- new CommonColor (InterpolateComponent (R, B, G), 255, 0) :
+ new CommonColor (InterpolateComponent (this.r, this.b, this.g), 255, 0) :
// Blue is max
isRedMin ?
// Red is min
- new CommonColor (0, InterpolateComponent (G, R, B), 255) :
+ new CommonColor (0, InterpolateComponent (this.g, this.r, this.b), 255) :
// Green is min
- new CommonColor (InterpolateComponent (R, G, B), 0, 255);
+ new CommonColor (InterpolateComponent (this.r, this.g, this.b), 0, 255);
- hueR = hueColor.R;
- hueG = hueColor.G;
- hueB = hueColor.B;
+ this.hueR = hueColor.r;
+ this.hueG = hueColor.g;
+ this.hueB = hueColor.b;
return hueColor;
}
}
- double? hue;
/// <summary>
/// The hue for this color, as an angle between 0 and 360 degrees.
/// </summary>
public double Hue {
get {
- if (hue.HasValue) return hue.Value;
+ if (this.hue.HasValue) return this.hue.Value;
// Map grey to 0 degrees
if (IsGrey) {
- hueR = 255;
- hueG = 0;
- hueB = 0;
- hue = 0;
+ this.hueR = 255;
+ this.hueG = 0;
+ this.hueB = 0;
+ this.hue = 0;
return 0;
}
- var isRedMax = R >= G && R >= B;
- var isGreenMax = G >= R && G >= B;
- var isRedMin = R <= G && R <= B;
- var isGreenMin = G <= R && G < B;
- var d = ((double)(isRedMax ? R : isGreenMax ? G : B) - (isRedMin ? R : isGreenMin ? G : B));
+ var isRedMax = this.r >= this.g && this.r >= this.b;
+ var isGreenMax = this.g >= this.r && this.g >= this.b;
+ var isRedMin = this.r <= this.g && this.r <= this.b;
+ var isGreenMin = this.g <= this.r && this.g <= this.b;
+
+ var d = (isRedMax ? this.r : isGreenMax ? this.g : this.b) - (isRedMin ? this.r : isGreenMin ? this.g : this.b);
- hue =
- isRedMax ? (Mod((G - B) / d, 6)) * 60 :
- isGreenMax ? (((B - R)/ d) + 2) * 60 :
- (((R - G) / d) + 4) * 60;
+ this.hue =
+ isRedMax ? (Mod((this.g - this.b) / d, 6)) * 60 :
+ isGreenMax ? (((this.b - this.r)/ d) + 2) * 60 :
+ (((this.r - this.g) / d) + 4) * 60;
- return hue.Value;
+ return this.hue.Value;
}
}
- double? lightness;
/// <summary>
/// The lightness of the color, where white is 1, black is 0, and primary colors are 0.5.
/// </summary>
public double Lightness {
get {
- if (lightness.HasValue) return lightness.Value;
+ if (this.lightness.HasValue) return this.lightness.Value;
- var isRedMax = R >= G && R >= B;
- var isGreenMax = G >= R && G >= B;
- var isRedMin = R <= G && R <= B;
- var isGreenMin = G <= R && G <= B;
+ var isRedMax = this.r >= this.g && this.r >= this.b;
+ var isGreenMax = this.g >= this.r && this.g >= this.b;
+ var isRedMin = this.r <= this.g && this.r <= this.b;
+ var isGreenMin = this.g <= this.r && this.g <= this.b;
- lightness = ((double)(isRedMax ? R : isGreenMax ? G : B) + (isRedMin ? R : isGreenMin ? G : B)) / 510;
+ this.lightness =
+ ((isRedMax ? this.r : isGreenMax ? this.g : this.b) + (isRedMin ? this.r : isGreenMin ? this.g : this.b)) / 510;
- return lightness.Value;
+ return this.lightness.Value;
}
}
- double? brightness;
/// <summary>
/// A brightness between 0 and 1, 1 being the measure for the hue of the color
/// (the hue being a fully-saturated version of the same color), and 0 being
@@ -205,20 +190,19 @@ namespace Xamarin.PropertyEditing.Drawing
/// </summary>
public double Brightness {
get {
- if (brightness.HasValue) return brightness.Value;
+ if (this.brightness.HasValue) return this.brightness.Value;
CommonColor hue = HueColor;
var isRedMaxed = hue.R == 255;
var isGreenMaxed = hue.G == 255;
- return (brightness =
- isRedMaxed ? (double)R / 255 :
- isGreenMaxed ? (double)G / 255 :
- (double)B / 255
+ return (this.brightness =
+ isRedMaxed ? this.r / 255 :
+ isGreenMaxed ? this.g / 255 :
+ this.b / 255
).Value;
}
}
- double? saturation;
/// <summary>
/// A saturation between 0 and 1, 1 being the measure for the hue of the color
/// (the hue being a fully saturated version of the color), and 0 being the
@@ -226,27 +210,48 @@ namespace Xamarin.PropertyEditing.Drawing
/// </summary>
public double Saturation {
get {
- if (saturation.HasValue) return saturation.Value;
+ if (this.saturation.HasValue) return this.saturation.Value;
- if (IsGrey) return (saturation = 0).Value;
+ if (IsGrey) return (this.saturation = 0).Value;
- var isRedMax = R >= G && R >= B;
- var isGreenMax = G >= R && G >= B;
- var isRedMin = R <= G && R <= B;
- var isGreenMin = G <= R && G <= B;
+ var isRedMax = this.r >= this.g && this.r >= this.b;
+ var isGreenMax = this.g >= this.r && this.g >= this.b;
+ var isRedMin = this.r <= this.g && this.r <= this.b;
+ var isGreenMin = this.g <= this.r && this.g <= this.b;
- var max = (double)(isRedMax ? R : isGreenMax ? G : B);
- var d = (max - (isRedMin ? R : isGreenMin ? G : B));
+ var max = isRedMax ? this.r : isGreenMax ? this.g : this.b;
+ var d = (max - (isRedMin ? this.r : isGreenMin ? this.g : this.b));
- saturation = d / max;
+ this.saturation = d / max;
- return saturation.Value;
+ return this.saturation.Value;
}
}
- static readonly int[][] redRanges = new[] { new[] { 0, 60 }, new[] { 300, 360 } };
- static readonly int[][] greenRanges = new[] { new[] { 60, 180 } };
- static readonly int[][] blueRanges = new[] { new[] { 180, 300 } };
+ private readonly double r;
+ private readonly double g;
+ private readonly double b;
+ private double? k;
+ private double? c;
+ private double? m;
+ private double? y;
+ private double? hue;
+ private double? hueR;
+ private double hueG, hueB;
+ private double? lightness;
+ private double? brightness;
+ private double? saturation;
+
+ private double Complement (double component, double k)
+ {
+ if (k == 1) return 0;
+ var val = (1 - k - component / 255) / (1 - k);
+ return val < 0 ? 0 : val > 1 ? 1 : val;
+ }
+
+ private static readonly int[][] redRanges = new[] { new[] { 0, 60 }, new[] { 300, 360 } };
+ private static readonly int[][] greenRanges = new[] { new[] { 60, 180 } };
+ private static readonly int[][] blueRanges = new[] { new[] { 180, 300 } };
/// <summary>
/// Finds the hue color from a hue angle between 0 and 360 degrees.
@@ -281,20 +286,20 @@ namespace Xamarin.PropertyEditing.Drawing
/// <param name="hue">The hue, between 0 and 360</param>
/// <param name="intervals">A set of intervals where the component is 255.</param>
/// <returns>The value of the component.</returns>
- static byte GetHueComponent (double hue, int[][] intervals)
+ private static double GetHueComponent (double hue, int[][] intervals)
{
if (hue < 0 || hue > 360)
throw new ArgumentOutOfRangeException (nameof (hue), "Position must be between 0 and 6.");
- foreach (int[] interval in intervals) {
+ foreach (var interval in intervals) {
// Component is 255 inside the interval
if (hue >= interval[0] && hue <= interval[1])
return 255;
// Component linearly grows from 0 to 255 60 degrees left of the interval
if (hue >= interval[0] - 60 && hue < interval[0])
- return (byte)((hue - interval[0] + 60) * 255 / 60);
+ return (hue - interval[0] + 60) * 255 / 60;
// Component linearly falls from 255 to 0 60 degrees right of the interval
if (hue > interval[1] && hue <= interval[1] + 60)
- return (byte)(255 - (hue - interval[1]) * 255 / 60);
+ return 255 - (hue - interval[1]) * 255 / 60;
}
// Otherwise, it's zero
return 0;
@@ -311,27 +316,27 @@ namespace Xamarin.PropertyEditing.Drawing
// We're between 0 and 120
if (hueColor.R == 255) {
// We're between 0 and 60, and green is on the rising phase
- return (double)hueColor.G * 60 / 255;
+ return hueColor.g * 60 / 255;
}
// We're between 60 and 120, and red is on the declining phase
- return ((double)(255 - hueColor.R) * 60 / 255 + 60);
+ return ((255 - hueColor.r) * 60 / 255 + 60);
}
else if (hueColor.R == 0) {
// We're between 120 and 240
if (hueColor.G == 255) {
// We're between 120 and 180, and blue is on the rise
- return ((double)hueColor.B * 60 / 255 + 120);
+ return (hueColor.b * 60 / 255 + 120);
}
// We're between 180 and 240, and green is declining
- return ((double)(255 - hueColor.G) * 60 / 255 + 180);
+ return ((255 - hueColor.g) * 60 / 255 + 180);
}
// We're between 240 and 360
if (hueColor.B == 255) {
// We're between 240 and 300, and red is on the rise
- return ((double)hueColor.R * 60 / 255 + 240);
+ return (hueColor.r * 60 / 255 + 240);
}
// We're between 300 and 360, and blue is declining
- return ((double)(255 - hueColor.B) * 60 / 255 + 300);
+ return ((255 - hueColor.b) * 60 / 255 + 300);
}
/// <summary>
@@ -347,11 +352,10 @@ namespace Xamarin.PropertyEditing.Drawing
/// <param name="lowest">The lowest component value</param>
/// <param name="highest">The highest component value</param>
/// <returns>The interpolated third component</returns>
- static byte InterpolateComponent (byte component, byte lowest, byte highest)
+ static double InterpolateComponent (double component, double lowest, double highest)
{
var delta = highest - lowest;
- if (delta == 0) return highest;
- return (byte)((component - lowest) * 255 / delta);
+ return delta == 0 ? highest : (component - lowest) * 255 / delta;
}
/// <summary>
@@ -378,9 +382,9 @@ namespace Xamarin.PropertyEditing.Drawing
throw new ArgumentOutOfRangeException (nameof (k));
}
var color = new CommonColor (
- (byte)(255 * (1 - c) * (1 - k)),
- (byte)(255 * (1 - m) * (1 - k)),
- (byte)(255 * (1 - y) * (1 - k)),
+ 255 * (1 - c) * (1 - k),
+ 255 * (1 - m) * (1 - k),
+ 255 * (1 - y) * (1 - k),
alpha) {
// pre-cache CMYK components, since we know them, and it will improve round-tripping
c = c,
@@ -428,7 +432,7 @@ namespace Xamarin.PropertyEditing.Drawing
hue < 180 || hue >= 300 ? x :
c;
- var color = new CommonColor ((byte)(255 * (r + m)), (byte)(255 * (g + m)), (byte)(255 * (b + m)), alpha) {
+ var color = new CommonColor (255 * (r + m), 255 * (g + m), 255 * (b + m), alpha) {
// Pre-cache HLS components, since we know them, and it will improve round-tripping
hue = hue,
lightness = lightness,
@@ -474,7 +478,7 @@ namespace Xamarin.PropertyEditing.Drawing
hue < 180 || hue >= 300 ? x :
c;
- var color = new CommonColor ((byte)(255 * (r + m)), (byte)(255 * (g + m)), (byte)(255 * (b + m)), alpha) {
+ var color = new CommonColor (255 * (r + m), 255 * (g + m), 255 * (b + m), alpha) {
// Pre-cache HLS components, since we know them, and it will improve round-tripping
hue = hue,
brightness = brightness,
@@ -488,13 +492,16 @@ namespace Xamarin.PropertyEditing.Drawing
private static double Mod (double a, double b) => a - b * Math.Floor (a / b);
- public override bool Equals (object obj)
+ private static byte DoubleToByte(double? d)
{
- if (obj == null) return false;
- if (!(obj is CommonColor otherColor)) return false;
- return Equals (otherColor, false);
+ if (!d.HasValue) return 0;
+ var round = Math.Round (d.Value);
+ return (byte)(round < 0 ? 0 : round > 255 ? 255 : round);
}
+ public override bool Equals (object obj)
+ => obj == null ? false : !(obj is CommonColor otherColor) ? false : Equals (otherColor, false);
+
public bool Equals (CommonColor other) => Equals (other, false);
public bool Equals (CommonColor other, bool ignoreAlpha)
@@ -509,9 +516,9 @@ namespace Xamarin.PropertyEditing.Drawing
public static bool operator != (CommonColor left, CommonColor right) => !Equals (left, right);
public static double SquaredDistance (CommonColor left, CommonColor right)
- => (left.R - right.R) * (left.R - right.R)
- + (left.G - right.G) * (left.G - right.G)
- + (left.B - right.B) * (left.B - right.B);
+ => (left.r - right.r) * (left.r - right.r)
+ + (left.g - right.g) * (left.g - right.g)
+ + (left.b - right.b) * (left.b - right.b);
public override int GetHashCode ()
{
diff --git a/Xamarin.PropertyEditing/ViewModels/MaterialDesignColorViewModel.cs b/Xamarin.PropertyEditing/ViewModels/MaterialDesignColorViewModel.cs
index 1c0453f..c88c328 100644
--- a/Xamarin.PropertyEditing/ViewModels/MaterialDesignColorViewModel.cs
+++ b/Xamarin.PropertyEditing/ViewModels/MaterialDesignColorViewModel.cs
@@ -41,11 +41,9 @@ namespace Xamarin.PropertyEditing.ViewModels
{
get {
// Debug.WriteLine ($"Getting ColorName ({this.colorName})");
- if (this.colorName != null) return this.colorName;
- if (Parent.Value is CommonSolidBrush solidBrush) {
- return (this.colorName = Palette.Name);
- }
- return (this.colorName = Strings.MaterialColorGrey);
+ return this.colorName ??
+ (Parent.Value is CommonSolidBrush solidBrush ? (this.colorName = Palette.Name)
+ : (this.colorName = Strings.MaterialColorGrey));
}
set {
// Debug.WriteLine ($"Setting ColorName to {value}");
@@ -251,9 +249,9 @@ namespace Xamarin.PropertyEditing.ViewModels
Color = new CommonColor (newColor.R, newColor.G, newColor.B, alpha);
}
- private static string[] NormalNames = new[] { "50", "100", "200", "300", "400", "500", "600", "700", "800", "900" };
- private static string[] AccentNames = new[] { "A100", "A200", "A400", "A700" };
- private static string[] BlackAndWhiteNames = new[] { Strings.White, Strings.Black };
+ private static readonly string[] NormalNames = new[] { "50", "100", "200", "300", "400", "500", "600", "700", "800", "900" };
+ private static readonly string[] AccentNames = new[] { "A100", "A200", "A400", "A700" };
+ private static readonly string[] BlackAndWhiteNames = new[] { Strings.White, Strings.Black };
private static MaterialColorScale FindPalette (string colorName, bool isAccent = false)
{