diff --git a/Tests/Perspex.Controls.UnitTests/GridLengthTests.cs b/Tests/Perspex.Controls.UnitTests/GridLengthTests.cs new file mode 100644 index 0000000000..f2c81a9e88 --- /dev/null +++ b/Tests/Perspex.Controls.UnitTests/GridLengthTests.cs @@ -0,0 +1,93 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2015 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Controls.UnitTests +{ + using System; + using System.Linq; + using Xunit; + + public class GridLengthTests + { + [Fact] + public void Parse_Should_Parse_Auto() + { + var result = GridLength.Parse("Auto"); + + Assert.Equal(GridLength.Auto, result); + } + + [Fact] + public void Parse_Should_Parse_Auto_Lowercase() + { + var result = GridLength.Parse("auto"); + + Assert.Equal(GridLength.Auto, result); + } + + [Fact] + public void Parse_Should_Parse_Star() + { + var result = GridLength.Parse("*"); + + Assert.Equal(new GridLength(1, GridUnitType.Star), result); + } + + [Fact] + public void Parse_Should_Parse_Star_Value() + { + var result = GridLength.Parse("2*"); + + Assert.Equal(new GridLength(2, GridUnitType.Star), result); + } + + [Fact] + public void Parse_Should_Parse_Pixel_Value() + { + var result = GridLength.Parse("2"); + + Assert.Equal(new GridLength(2, GridUnitType.Pixel), result); + } + + [Fact] + public void Parse_Should_Throw_FormatException_For_Invalid_String() + { + Assert.Throws(() => GridLength.Parse("2x")); + } + + [Fact] + public void ParseLengths_Accepts_Comma_Separators() + { + var result = GridLength.ParseLengths("*,Auto,2*,4").ToList(); + + Assert.Equal( + new[] + { + new GridLength(1, GridUnitType.Star), + GridLength.Auto, + new GridLength(2, GridUnitType.Star), + new GridLength(4, GridUnitType.Pixel), + }, + result); + } + + [Fact] + public void ParseLengths_Accepts_Space_Separators() + { + var result = GridLength.ParseLengths("* Auto 2* 4").ToList(); + + Assert.Equal( + new[] + { + new GridLength(1, GridUnitType.Star), + GridLength.Auto, + new GridLength(2, GridUnitType.Star), + new GridLength(4, GridUnitType.Pixel), + }, + result); + } + } +} diff --git a/Tests/Perspex.SceneGraph.UnitTests/Media/BrushTests.cs b/Tests/Perspex.SceneGraph.UnitTests/Media/BrushTests.cs new file mode 100644 index 0000000000..19a31aae7f --- /dev/null +++ b/Tests/Perspex.SceneGraph.UnitTests/Media/BrushTests.cs @@ -0,0 +1,77 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2015 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.SceneGraph.UnitTests.Media +{ + using System; + using Perspex.Media; + using Xunit; + + public class BrushTests + { + [Fact] + public void Parse_Parses_RGB_Hash_Brush() + { + var result = (SolidColorBrush)Brush.Parse("#ff8844"); + + Assert.Equal(0xff, result.Color.R); + Assert.Equal(0x88, result.Color.G); + Assert.Equal(0x44, result.Color.B); + Assert.Equal(0xff, result.Color.A); + } + + [Fact] + public void Parse_Parses_ARGB_Hash_Brush() + { + var result = (SolidColorBrush)Brush.Parse("#40ff8844"); + + Assert.Equal(0xff, result.Color.R); + Assert.Equal(0x88, result.Color.G); + Assert.Equal(0x44, result.Color.B); + Assert.Equal(0x40, result.Color.A); + } + + [Fact] + public void Parse_Parses_Named_Brush_Lowercase() + { + var result = (SolidColorBrush)Brush.Parse("red"); + + Assert.Equal(0xff, result.Color.R); + Assert.Equal(0x00, result.Color.G); + Assert.Equal(0x00, result.Color.B); + Assert.Equal(0xff, result.Color.A); + } + + [Fact] + public void Parse_Parses_Named_Brush_Uppercase() + { + var result = (SolidColorBrush)Brush.Parse("RED"); + + Assert.Equal(0xff, result.Color.R); + Assert.Equal(0x00, result.Color.G); + Assert.Equal(0x00, result.Color.B); + Assert.Equal(0xff, result.Color.A); + } + + [Fact] + public void Parse_Hex_Value_Doesnt_Accept_Too_Few_Chars() + { + Assert.Throws(() => Brush.Parse("#ff")); + } + + [Fact] + public void Parse_Hex_Value_Doesnt_Accept_Too_Many_Chars() + { + Assert.Throws(() => Brush.Parse("#ff5555555")); + } + + [Fact] + public void Parse_Hex_Value_Doesnt_Accept_Invalid_Number() + { + Assert.Throws(() => Brush.Parse("#ff808g80")); + } + } +} diff --git a/Tests/Perspex.SceneGraph.UnitTests/Media/ColorTests.cs b/Tests/Perspex.SceneGraph.UnitTests/Media/ColorTests.cs new file mode 100644 index 0000000000..722fc6e8cd --- /dev/null +++ b/Tests/Perspex.SceneGraph.UnitTests/Media/ColorTests.cs @@ -0,0 +1,77 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2015 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.SceneGraph.UnitTests.Media +{ + using System; + using Perspex.Media; + using Xunit; + + public class ColorTests + { + [Fact] + public void Parse_Parses_RGB_Hash_Color() + { + var result = Color.Parse("#ff8844"); + + Assert.Equal(0xff, result.R); + Assert.Equal(0x88, result.G); + Assert.Equal(0x44, result.B); + Assert.Equal(0xff, result.A); + } + + [Fact] + public void Parse_Parses_ARGB_Hash_Color() + { + var result = Color.Parse("#40ff8844"); + + Assert.Equal(0xff, result.R); + Assert.Equal(0x88, result.G); + Assert.Equal(0x44, result.B); + Assert.Equal(0x40, result.A); + } + + [Fact] + public void Parse_Parses_Named_Color_Lowercase() + { + var result = Color.Parse("red"); + + Assert.Equal(0xff, result.R); + Assert.Equal(0x00, result.G); + Assert.Equal(0x00, result.B); + Assert.Equal(0xff, result.A); + } + + [Fact] + public void Parse_Parses_Named_Color_Uppercase() + { + var result = Color.Parse("RED"); + + Assert.Equal(0xff, result.R); + Assert.Equal(0x00, result.G); + Assert.Equal(0x00, result.B); + Assert.Equal(0xff, result.A); + } + + [Fact] + public void Parse_Hex_Value_Doesnt_Accept_Too_Few_Chars() + { + Assert.Throws(() => Color.Parse("#ff")); + } + + [Fact] + public void Parse_Hex_Value_Doesnt_Accept_Too_Many_Chars() + { + Assert.Throws(() => Color.Parse("#ff5555555")); + } + + [Fact] + public void Parse_Hex_Value_Doesnt_Accept_Invalid_Number() + { + Assert.Throws(() => Color.Parse("#ff808g80")); + } + } +} diff --git a/samples/XamlTestApplication/Views/MainWindow.xaml b/samples/XamlTestApplication/Views/MainWindow.xaml index 3294edb8b0..da27d04242 100644 --- a/samples/XamlTestApplication/Views/MainWindow.xaml +++ b/samples/XamlTestApplication/Views/MainWindow.xaml @@ -2,11 +2,7 @@ xmlns="https://github.com/grokys/Perspex" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Perspex Test Application" Height="350" Width="525"> - - - - - + diff --git a/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs b/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs index f78418f20d..88a67c8287 100644 --- a/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs +++ b/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs @@ -83,10 +83,12 @@ namespace Perspex.Markup.Xaml.Context var typeConverterProvider = new TypeConverterProvider(); var converters = new[] { - new TypeConverterRegistration(typeof (Bitmap), new BitmapConverter()), - new TypeConverterRegistration(typeof (GridLength), new GridLengthTypeConverter()), - new TypeConverterRegistration(typeof (Brush), new BrushConverter()), - new TypeConverterRegistration(typeof (Thickness), new ThicknessConverter()), + new TypeConverterRegistration(typeof(Bitmap), new BitmapConverter()), + new TypeConverterRegistration(typeof(Brush), new BrushConverter()), + new TypeConverterRegistration(typeof(ColumnDefinitions), new ColumnDefinitionsTypeConverter()), + new TypeConverterRegistration(typeof(GridLength), new GridLengthTypeConverter()), + new TypeConverterRegistration(typeof(RowDefinitions), new RowDefinitionsTypeConverter()), + new TypeConverterRegistration(typeof(Thickness), new ThicknessConverter()), }; typeConverterProvider.AddAll(converters); @@ -98,13 +100,13 @@ namespace Perspex.Markup.Xaml.Context var contentPropertyProvider = new ContentPropertyProvider(); var contentProperties = new Collection { - new ContentPropertyDefinition(typeof (ContentControl), "Content"), - new ContentPropertyDefinition(typeof (Decorator), "Child"), - new ContentPropertyDefinition(typeof (ItemsControl), "Items"), - new ContentPropertyDefinition(typeof (Panel), "Children"), - new ContentPropertyDefinition(typeof (TextBlock), "Text"), - new ContentPropertyDefinition(typeof (TextBox), "Text"), - new ContentPropertyDefinition(typeof (XamlDataTemplate), "Content"), + new ContentPropertyDefinition(typeof(ContentControl), "Content"), + new ContentPropertyDefinition(typeof(Decorator), "Child"), + new ContentPropertyDefinition(typeof(ItemsControl), "Items"), + new ContentPropertyDefinition(typeof(Panel), "Children"), + new ContentPropertyDefinition(typeof(TextBlock), "Text"), + new ContentPropertyDefinition(typeof(TextBox), "Text"), + new ContentPropertyDefinition(typeof(XamlDataTemplate), "Content"), }; contentPropertyProvider.AddAll(contentProperties); diff --git a/src/Markup/Perspex.Markup.Xaml/Converters/BitmapConverter.cs b/src/Markup/Perspex.Markup.Xaml/Converters/BitmapConverter.cs index 46acc4a68a..f9b3e96ba4 100644 --- a/src/Markup/Perspex.Markup.Xaml/Converters/BitmapConverter.cs +++ b/src/Markup/Perspex.Markup.Xaml/Converters/BitmapConverter.cs @@ -15,23 +15,22 @@ namespace Perspex.Markup.Xaml.Converters { public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) { - return true; + return sourceType == typeof(string); } public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) { - return true; + return false; } public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) { - var path = (string)value; - return new Bitmap(path); + return new Bitmap((string)value); } public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) { - return new Bitmap(10, 10); + throw new NotImplementedException(); } } } \ No newline at end of file diff --git a/src/Markup/Perspex.Markup.Xaml/Converters/BrushConverter.cs b/src/Markup/Perspex.Markup.Xaml/Converters/BrushConverter.cs index 63efc9f5c1..6c5466340f 100644 --- a/src/Markup/Perspex.Markup.Xaml/Converters/BrushConverter.cs +++ b/src/Markup/Perspex.Markup.Xaml/Converters/BrushConverter.cs @@ -8,75 +8,24 @@ namespace Perspex.Markup.Xaml.Converters { using System; using System.Globalization; - using System.Reflection; - using System.Text; using Media; - using Media.Imaging; using OmniXaml.TypeConversion; - using Platform; public class BrushConverter : ITypeConverter { public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) { - return true; + return sourceType == typeof(string); } public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) { - return true; + return false; } public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) { - var colorString = (string)value; - - var color = DecodeColor(colorString); - - if (color != null) - { - return new SolidColorBrush(color.Value); - } - else - { - var member = typeof(Brushes).GetTypeInfo().GetDeclaredProperty(colorString); - - if (member != null) - { - return (Brush)member.GetValue(null); - } - } - - throw new InvalidOperationException("Invalid color string."); - } - - private static Color? DecodeColor(string colorString) - { - if (colorString[0] == '#') - { - var restOfValue = colorString.Remove(0, 1); - - if (restOfValue.Length == 8) - { - var a = Convert.ToByte(restOfValue.Substring(0, 2), 16); - var r = Convert.ToByte(restOfValue.Substring(2, 2), 16); - var g = Convert.ToByte(restOfValue.Substring(6, 2), 16); - var b = Convert.ToByte(restOfValue.Substring(8, 2), 16); - return Color.FromArgb(a, r, g, b); - } - - if (restOfValue.Length == 6) - { - var r = Convert.ToByte(restOfValue.Substring(0, 2), 16); - var g = Convert.ToByte(restOfValue.Substring(2, 2), 16); - var b = Convert.ToByte(restOfValue.Substring(4, 2), 16); - return Color.FromRgb(r, g, b); - } - - throw new InvalidOperationException("The color code format cannot be parsed"); - } - - return null; + return Brush.Parse((string)value); } public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) diff --git a/src/Markup/Perspex.Markup.Xaml/Converters/ColumnDefinitionsTypeConverter.cs b/src/Markup/Perspex.Markup.Xaml/Converters/ColumnDefinitionsTypeConverter.cs new file mode 100644 index 0000000000..14893cd1db --- /dev/null +++ b/src/Markup/Perspex.Markup.Xaml/Converters/ColumnDefinitionsTypeConverter.cs @@ -0,0 +1,36 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2015 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Markup.Xaml.Converters +{ + using System; + using System.Globalization; + using Controls; + using OmniXaml.TypeConversion; + + public class ColumnDefinitionsTypeConverter : ITypeConverter + { + public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) + { + return sourceType == typeof(string); + } + + public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) + { + return false; + } + + public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) + { + return new ColumnDefinitions((string)value); + } + + public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/src/Markup/Perspex.Markup.Xaml/Converters/GridLengthTypeConverter.cs b/src/Markup/Perspex.Markup.Xaml/Converters/GridLengthTypeConverter.cs index 5609597369..1eea9e90d0 100644 --- a/src/Markup/Perspex.Markup.Xaml/Converters/GridLengthTypeConverter.cs +++ b/src/Markup/Perspex.Markup.Xaml/Converters/GridLengthTypeConverter.cs @@ -13,39 +13,24 @@ namespace Perspex.Markup.Xaml.Converters public class GridLengthTypeConverter : ITypeConverter { - public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) + public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) { - var str = value as string; - - if (str != null) - { - if (string.Equals(str, "Auto")) - { - return new GridLength(0, GridUnitType.Auto); - } - } - - return new GridLength(1, GridUnitType.Star); + return sourceType == typeof(string); } - public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) + public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) { - if ((string) value == "Auto") - { - return new GridLength(0, GridUnitType.Auto); - } - - return new GridLength(1, GridUnitType.Star); + return false; } - public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) + public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) { - return true; + return GridLength.Parse((string)value); } - public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) + public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) { - return true; + throw new NotImplementedException(); } } } \ No newline at end of file diff --git a/src/Markup/Perspex.Markup.Xaml/Converters/RowDefinitionsTypeConverter.cs b/src/Markup/Perspex.Markup.Xaml/Converters/RowDefinitionsTypeConverter.cs new file mode 100644 index 0000000000..a432584224 --- /dev/null +++ b/src/Markup/Perspex.Markup.Xaml/Converters/RowDefinitionsTypeConverter.cs @@ -0,0 +1,36 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2015 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Markup.Xaml.Converters +{ + using System; + using System.Globalization; + using Controls; + using OmniXaml.TypeConversion; + + public class RowDefinitionsTypeConverter : ITypeConverter + { + public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) + { + return sourceType == typeof(string); + } + + public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) + { + return false; + } + + public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) + { + return new RowDefinitions((string)value); + } + + public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj b/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj index 814427175f..f0965e351f 100644 --- a/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj +++ b/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj @@ -38,6 +38,8 @@ Properties\SharedAssemblyInfo.cs + + diff --git a/src/Perspex.Controls/ColumnDefinitions.cs b/src/Perspex.Controls/ColumnDefinitions.cs index ce020377eb..05dac937ed 100644 --- a/src/Perspex.Controls/ColumnDefinitions.cs +++ b/src/Perspex.Controls/ColumnDefinitions.cs @@ -8,7 +8,6 @@ namespace Perspex.Controls { using System.Linq; using Perspex.Collections; - using Perspex.Controls.Parsers; /// /// A collection of s. @@ -28,7 +27,7 @@ namespace Perspex.Controls /// A string representation of the column definitions. public ColumnDefinitions(string s) { - this.AddRange(GridLengthsParser.Parse(s).Select(x => new ColumnDefinition(x))); + this.AddRange(GridLength.ParseLengths(s).Select(x => new ColumnDefinition(x))); } } } \ No newline at end of file diff --git a/src/Perspex.Controls/GridLength.cs b/src/Perspex.Controls/GridLength.cs index 1e477b3417..9a7e605923 100644 --- a/src/Perspex.Controls/GridLength.cs +++ b/src/Perspex.Controls/GridLength.cs @@ -7,6 +7,8 @@ namespace Perspex.Controls { using System; + using System.Collections.Generic; + using System.Linq; /// /// Defines the valid units for a . @@ -192,5 +194,41 @@ namespace Perspex.Controls string s = this.value.ToString(); return this.IsStar ? s + "*" : s; } + + /// + /// Parses a string to return a . + /// + /// The string. + /// The . + public static GridLength Parse(string s) + { + s = s.ToUpperInvariant(); + + if (s == "AUTO") + { + return GridLength.Auto; + } + else if (s.EndsWith("*")) + { + var valueString = s.Substring(0, s.Length - 1).Trim(); + var value = valueString.Length > 0 ? double.Parse(valueString) : 1; + return new GridLength(value, GridUnitType.Star); + } + else + { + var value = double.Parse(s); + return new GridLength(value, GridUnitType.Pixel); + } + } + + /// + /// Parses a string to return a collection of s. + /// + /// The string. + /// The . + public static IEnumerable ParseLengths(string s) + { + return s.Split(new[] { ',', ' ' }).Select(x => Parse(x)); + } } } \ No newline at end of file diff --git a/src/Perspex.Controls/Parsers/GridLengthsParser.cs b/src/Perspex.Controls/Parsers/GridLengthsParser.cs deleted file mode 100644 index 64df91d723..0000000000 --- a/src/Perspex.Controls/Parsers/GridLengthsParser.cs +++ /dev/null @@ -1,52 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright 2014 MIT Licence. See licence.md for more information. -// -// ----------------------------------------------------------------------- - -namespace Perspex.Controls.Parsers -{ - using System; - using System.Collections.Generic; - using System.Linq; - - /// - /// Parses a string of s for and - /// . - /// - public static class GridLengthsParser - { - /// - /// Parses a string of s. - /// - /// The string. - /// A collection of s. - public static IEnumerable Parse(string s) - { - var parts = s.Split(',').Select(x => x.ToUpperInvariant().Trim()); - - foreach (var part in parts) - { - if (part == "AUTO") - { - yield return GridLength.Auto; - } - else if (part.EndsWith("*")) - { - var valueString = part.Substring(0, part.Length - 1).Trim(); - var value = valueString.Length > 0 ? double.Parse(valueString) : 1; - yield return new GridLength(value, GridUnitType.Star); - } - else if (part.EndsWith("PX")) - { - var value = double.Parse(part.Substring(0, part.Length - 2)); - yield return new GridLength(value, GridUnitType.Pixel); - } - else - { - throw new FormatException("Invalid grid length: " + part); - } - } - } - } -} diff --git a/src/Perspex.Controls/Perspex.Controls.csproj b/src/Perspex.Controls/Perspex.Controls.csproj index c095c37e8a..209290d807 100644 --- a/src/Perspex.Controls/Perspex.Controls.csproj +++ b/src/Perspex.Controls/Perspex.Controls.csproj @@ -50,7 +50,6 @@ - diff --git a/src/Perspex.Controls/RowDefinitions.cs b/src/Perspex.Controls/RowDefinitions.cs index 6a975a2297..f9a22b5186 100644 --- a/src/Perspex.Controls/RowDefinitions.cs +++ b/src/Perspex.Controls/RowDefinitions.cs @@ -8,7 +8,6 @@ namespace Perspex.Controls { using System.Linq; using Perspex.Collections; - using Perspex.Controls.Parsers; /// /// A collection of s. @@ -28,7 +27,7 @@ namespace Perspex.Controls /// A string representation of the row definitions. public RowDefinitions(string s) { - this.AddRange(GridLengthsParser.Parse(s).Select(x => new RowDefinition(x))); + this.AddRange(GridLength.ParseLengths(s).Select(x => new RowDefinition(x))); } } } \ No newline at end of file diff --git a/src/Perspex.SceneGraph/Media/Brush.cs b/src/Perspex.SceneGraph/Media/Brush.cs index 26e5953621..e082e26773 100644 --- a/src/Perspex.SceneGraph/Media/Brush.cs +++ b/src/Perspex.SceneGraph/Media/Brush.cs @@ -1,23 +1,61 @@ // ----------------------------------------------------------------------- // -// Copyright 2014 MIT Licence. See licence.md for more information. +// Copyright 2015 MIT Licence. See licence.md for more information. // // ----------------------------------------------------------------------- namespace Perspex.Media { + using System; + using System.Linq; + using System.Reflection; + /// /// Describes how an area is painted. /// public abstract class Brush : PerspexObject { + /// + /// Defines the property. + /// public static readonly PerspexProperty OpacityProperty = - PerspexProperty.Register(nameof(Opacity), 1.0); + PerspexProperty.Register(nameof(Opacity), 1.0); + /// + /// Gets or sets the opacity of the brush. + /// public double Opacity { get { return this.GetValue(OpacityProperty); } set { this.SetValue(OpacityProperty, value); } } + + /// + /// Parses a brush string. + /// + /// The brush string. + /// The . + public static Brush Parse(string s) + { + if (s[0] == '#') + { + return new SolidColorBrush(Color.Parse(s)); + } + else + { + var upper = s.ToUpperInvariant(); + var member = typeof(Brushes).GetTypeInfo().DeclaredProperties + .FirstOrDefault(x => x.Name.ToUpperInvariant() == upper); + + if (member != null) + { + return (Brush)member.GetValue(null); + } + else + { + throw new FormatException($"Invalid brush string: '{s}'."); + } + } + } } } diff --git a/src/Perspex.SceneGraph/Media/Color.cs b/src/Perspex.SceneGraph/Media/Color.cs index c070d3d9a3..2a1281d3ee 100644 --- a/src/Perspex.SceneGraph/Media/Color.cs +++ b/src/Perspex.SceneGraph/Media/Color.cs @@ -6,6 +6,11 @@ namespace Perspex.Media { + using System; + using System.Globalization; + using System.Linq; + using System.Reflection; + /// /// An ARGB color. /// @@ -84,6 +89,45 @@ namespace Perspex.Media }; } + /// + /// Parses a color string. + /// + /// The color string. + /// The . + public static Color Parse(string s) + { + if (s[0] == '#') + { + var or = 0u; + + if (s.Length == 7) + { + or = 0xff000000; + } + else if (s.Length != 9) + { + throw new FormatException($"Invalid color string: '{s}'."); + } + + return FromUInt32(uint.Parse(s.Substring(1), NumberStyles.HexNumber) | or); + } + else + { + var upper = s.ToUpperInvariant(); + var member = typeof(Colors).GetTypeInfo().DeclaredProperties + .FirstOrDefault(x => x.Name.ToUpperInvariant() == upper); + + if (member != null) + { + return (Color)member.GetValue(null); + } + else + { + throw new FormatException($"Invalid color string: '{s}'."); + } + } + } + /// /// Returns the string representation of the color. /// diff --git a/tests/Perspex.Controls.UnitTests/Parsers/GridLengthsParserTests.cs b/tests/Perspex.Controls.UnitTests/Parsers/GridLengthsParserTests.cs deleted file mode 100644 index 340923056b..0000000000 --- a/tests/Perspex.Controls.UnitTests/Parsers/GridLengthsParserTests.cs +++ /dev/null @@ -1,54 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright 2015 MIT Licence. See licence.md for more information. -// -// ----------------------------------------------------------------------- - -namespace Perspex.Controls.UnitTests.Parsers -{ - using System; - using System.Linq; - using Perspex.Controls.Parsers; - using Xunit; - - public class GridLengthsParserTests - { - [Fact] - public void Parser_Should_Correctly_Parse_Grid_Lengths() - { - var s = "*,Auto,2*,4px"; - var result = GridLengthsParser.Parse(s); - - Assert.Equal( - new[] - { - new GridLength(1, GridUnitType.Star), - GridLength.Auto, - new GridLength(2, GridUnitType.Star), - new GridLength(4, GridUnitType.Pixel), - }, - result); - } - - [Fact] - public void Parser_Should_Throw_For_Invalid_Star_Value() - { - var s = "*,Auto,x*,4px"; - Assert.Throws(() => GridLengthsParser.Parse(s).ToList()); - } - - [Fact] - public void Parser_Should_Throw_For_Invalid_Unit_Value() - { - var s = "*,Auto,4ab,4px"; - Assert.Throws(() => GridLengthsParser.Parse(s).ToList()); - } - - [Fact] - public void Parser_Should_Throw_For_Empty_Entry() - { - var s = "*,Auto,,4px"; - Assert.Throws(() => GridLengthsParser.Parse(s).ToList()); - } - } -} diff --git a/tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj b/tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj index 0736d59726..610cef7365 100644 --- a/tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj +++ b/tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj @@ -91,11 +91,11 @@ + - diff --git a/tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj b/tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj index 00077dfeea..ff8383a1b0 100644 --- a/tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj +++ b/tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj @@ -81,6 +81,8 @@ + +