From 3aa9b7e60c528d5f5d58a4c6a96442980549831e Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 16 Sep 2015 03:11:49 +0200 Subject: [PATCH] Accept RelativePoint in XAML. --- .../RelativePointTests.cs | 27 ++++++++ .../XamlTestApplication/Views/MainWindow.xaml | 2 +- .../Context/PerspexWiringContext.cs | 1 + .../Converters/RelativePointTypeConverter.cs | 32 +++++++++ .../Perspex.Markup.Xaml.csproj | 1 + src/Perspex.SceneGraph/RelativePoint.cs | 65 ++++++++++++++++++- .../Perspex.SceneGraph.UnitTests.csproj | 1 + 7 files changed, 125 insertions(+), 4 deletions(-) create mode 100644 Tests/Perspex.SceneGraph.UnitTests/RelativePointTests.cs create mode 100644 src/Markup/Perspex.Markup.Xaml/Converters/RelativePointTypeConverter.cs diff --git a/Tests/Perspex.SceneGraph.UnitTests/RelativePointTests.cs b/Tests/Perspex.SceneGraph.UnitTests/RelativePointTests.cs new file mode 100644 index 0000000000..0cd9bdee20 --- /dev/null +++ b/Tests/Perspex.SceneGraph.UnitTests/RelativePointTests.cs @@ -0,0 +1,27 @@ +// Copyright (c) The Perspex Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System.Globalization; +using Xunit; + +namespace Perspex.SceneGraph.UnitTests +{ + public class RelativePointTests + { + [Fact] + public void Parse_Should_Accept_Absolute_Value() + { + var result = RelativePoint.Parse("4,5", CultureInfo.InvariantCulture); + + Assert.Equal(new RelativePoint(4, 5, RelativeUnit.Absolute), result); + } + + [Fact] + public void Parse_Should_Accept_Relative_Value() + { + var result = RelativePoint.Parse("25%, 50%", CultureInfo.InvariantCulture); + + Assert.Equal(new RelativePoint(0.25, 0.5, RelativeUnit.Relative), result); + } + } +} diff --git a/samples/XamlTestApplication/Views/MainWindow.xaml b/samples/XamlTestApplication/Views/MainWindow.xaml index dfe135c193..fd834f4508 100644 --- a/samples/XamlTestApplication/Views/MainWindow.xaml +++ b/samples/XamlTestApplication/Views/MainWindow.xaml @@ -104,7 +104,7 @@ - + diff --git a/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs b/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs index b1223376d2..b75b07b289 100644 --- a/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs +++ b/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs @@ -83,6 +83,7 @@ namespace Perspex.Markup.Xaml.Context new TypeConverterRegistration(typeof(GridLength), new GridLengthTypeConverter()), new TypeConverterRegistration(typeof(Point), new PointTypeConverter()), new TypeConverterRegistration(typeof(PerspexProperty), new PerspexPropertyTypeConverter()), + new TypeConverterRegistration(typeof(RelativePoint), new RelativePointTypeConverter()), new TypeConverterRegistration(typeof(RowDefinitions), new RowDefinitionsTypeConverter()), new TypeConverterRegistration(typeof(Thickness), new ThicknessTypeConverter()), new TypeConverterRegistration(typeof(Selector), new SelectorTypeConverter()), diff --git a/src/Markup/Perspex.Markup.Xaml/Converters/RelativePointTypeConverter.cs b/src/Markup/Perspex.Markup.Xaml/Converters/RelativePointTypeConverter.cs new file mode 100644 index 0000000000..e091717380 --- /dev/null +++ b/src/Markup/Perspex.Markup.Xaml/Converters/RelativePointTypeConverter.cs @@ -0,0 +1,32 @@ +// Copyright (c) The Perspex Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; +using System.Globalization; +using OmniXaml.TypeConversion; + +namespace Perspex.Markup.Xaml.Converters +{ + public class RelativePointTypeConverter : 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 RelativePoint.Parse((string)value, culture); + } + + 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 6d7a8562d5..bc5ce9a459 100644 --- a/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj +++ b/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj @@ -39,6 +39,7 @@ Properties\SharedAssemblyInfo.cs + diff --git a/src/Perspex.SceneGraph/RelativePoint.cs b/src/Perspex.SceneGraph/RelativePoint.cs index da2f652b7a..23c9f49590 100644 --- a/src/Perspex.SceneGraph/RelativePoint.cs +++ b/src/Perspex.SceneGraph/RelativePoint.cs @@ -27,7 +27,7 @@ namespace Perspex /// /// Defines a point that may be defined relative to a containing element. /// - public struct RelativePoint + public struct RelativePoint : IEquatable { /// /// A point at the top left of the containing element. @@ -80,6 +80,63 @@ namespace Perspex /// public RelativeUnit Unit => _unit; + /// + /// Checks for equality between two s. + /// + /// The first point. + /// The second point. + /// True if the points are equal; otherwise false. + public static bool operator ==(RelativePoint left, RelativePoint right) + { + return left.Equals(right); + } + + /// + /// Checks for unequality between two s. + /// + /// The first point. + /// The second point. + /// True if the points are unequal; otherwise false. + public static bool operator !=(RelativePoint left, RelativePoint right) + { + return !left.Equals(right); + } + + /// + /// Checks if the equals another object. + /// + /// The other object. + /// True if the objects are equal, otherwise false. + public override bool Equals(object obj) + { + return (obj is RelativePoint) ? Equals((RelativePoint)obj) : false; + } + + /// + /// Checks if the equals another point. + /// + /// The other point. + /// True if the objects are equal, otherwise false. + public bool Equals(RelativePoint p) + { + return Unit == p.Unit && Point == p.Point; + } + + /// + /// Gets a hashcode for a . + /// + /// A hash code. + public override int GetHashCode() + { + unchecked + { + int hash = 17; + hash = (hash * 23) + Unit.GetHashCode(); + hash = (hash * 23) + Point.GetHashCode(); + return hash; + } + } + /// /// Converts a into pixels. /// @@ -107,6 +164,7 @@ namespace Perspex if (parts.Count == 2) { var unit = RelativeUnit.Absolute; + var scale = 1.0; if (parts[0].EndsWith("%")) { @@ -118,11 +176,12 @@ namespace Perspex parts[0] = parts[0].TrimEnd('%'); parts[1] = parts[1].TrimEnd('%'); unit = RelativeUnit.Relative; + scale = 0.01; } return new RelativePoint( - double.Parse(parts[0], culture), - double.Parse(parts[1], culture), + double.Parse(parts[0], culture) * scale, + double.Parse(parts[1], culture) * scale, unit); } else diff --git a/tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj b/tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj index 68b4c4f121..ad120ab0e3 100644 --- a/tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj +++ b/tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj @@ -85,6 +85,7 @@ +