Browse Source

Added RelativeRectTypeConverter

pull/301/head
Wiesław Šoltés 11 years ago
parent
commit
b13b870741
  1. 22
      samples/XamlTestApplicationPcl/Views/MainWindow.paml
  2. 1
      src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs
  3. 32
      src/Markup/Perspex.Markup.Xaml/Converters/RelativeRectTypeConverter.cs
  4. 1
      src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj
  5. 110
      src/Perspex.SceneGraph/RelativeRect.cs
  6. 1
      tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj
  7. 27
      tests/Perspex.SceneGraph.UnitTests/RelativeRectTests.cs

22
samples/XamlTestApplicationPcl/Views/MainWindow.paml

@ -245,6 +245,28 @@
<Button Grid.Row="1" Grid.Column="1" Content="Animate" HorizontalAlignment="Center"></Button>
</Grid>
</TabItem>
<TabItem Header="Brushes">
<Grid ColumnDefinitions="Auto" RowDefinitions="Auto">
<Border Grid.Row="0" Grid.Column="0" Width="200" Height="200" Margin="10">
<Border.Background>
<VisualBrush TileMode="Tile" Stretch="None" AlignmentX="Left" AlignmentY="Top" SourceRect="0%,0%,100%,100%" DestinationRect="0,0,20,20">
<VisualBrush.Visual>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical">
<Rectangle Width="10" Height="10" Fill="DarkGray"/>
<Rectangle Width="10" Height="10" Fill="LightGray"/>
</StackPanel>
<StackPanel Orientation="Vertical">
<Rectangle Width="10" Height="10" Fill="LightGray"/>
<Rectangle Width="10" Height="10" Fill="DarkGray"/>
</StackPanel>
</StackPanel>
</VisualBrush.Visual>
</VisualBrush>
</Border.Background>
</Border>
</Grid>
</TabItem>
</TabControl>
</Grid>
</Window>

1
src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs

@ -106,6 +106,7 @@ namespace Perspex.Markup.Xaml.Context
new TypeConverterRegistration(typeof(Point), new PointTypeConverter()),
new TypeConverterRegistration(typeof(PerspexProperty), new PerspexPropertyTypeConverter()),
new TypeConverterRegistration(typeof(RelativePoint), new RelativePointTypeConverter()),
new TypeConverterRegistration(typeof(RelativeRect), new RelativeRectTypeConverter()),
new TypeConverterRegistration(typeof(RowDefinitions), new RowDefinitionsTypeConverter()),
new TypeConverterRegistration(typeof(Selector), new SelectorTypeConverter()),
new TypeConverterRegistration(typeof(Thickness), new ThicknessTypeConverter()),

32
src/Markup/Perspex.Markup.Xaml/Converters/RelativeRectTypeConverter.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 RelativeRectTypeConverter : 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 RelativeRect.Parse((string)value, culture);
}
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

1
src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj

@ -39,6 +39,7 @@
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Converters\PerspexListTypeConverter.cs" />
<Compile Include="Converters\RelativeRectTypeConverter.cs" />
<Compile Include="Data\IXamlBinding.cs" />
<Compile Include="Data\MultiBinding.cs" />
<Compile Include="Data\RelativeSource.cs" />

110
src/Perspex.SceneGraph/RelativeRect.cs

@ -1,12 +1,16 @@
// 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 System.Linq;
namespace Perspex
{
/// <summary>
/// Defines a rectangle that may be defined relative to a containing element.
/// </summary>
public struct RelativeRect
public struct RelativeRect : IEquatable<RelativeRect>
{
/// <summary>
/// A rectangle that represents 100% of an area.
@ -83,6 +87,63 @@ namespace Perspex
/// </summary>
public Rect Rect { get; }
/// <summary>
/// Checks for equality between two <see cref="RelativeRect"/>s.
/// </summary>
/// <param name="left">The first rectangle.</param>
/// <param name="right">The second rectangle.</param>
/// <returns>True if the rectangles are equal; otherwise false.</returns>
public static bool operator ==(RelativeRect left, RelativeRect right)
{
return left.Equals(right);
}
/// <summary>
/// Checks for unequality between two <see cref="RelativeRect"/>s.
/// </summary>
/// <param name="left">The first rectangle.</param>
/// <param name="right">The second rectangle.</param>
/// <returns>True if the rectangles are unequal; otherwise false.</returns>
public static bool operator !=(RelativeRect left, RelativeRect right)
{
return !left.Equals(right);
}
/// <summary>
/// Checks if the <see cref="RelativeRect"/> equals another object.
/// </summary>
/// <param name="obj">The other object.</param>
/// <returns>True if the objects are equal, otherwise false.</returns>
public override bool Equals(object obj)
{
return (obj is RelativeRect) ? Equals((RelativeRect)obj) : false;
}
/// <summary>
/// Checks if the <see cref="RelativeRect"/> equals another rectangle.
/// </summary>
/// <param name="p">The other rectangle.</param>
/// <returns>True if the objects are equal, otherwise false.</returns>
public bool Equals(RelativeRect p)
{
return Unit == p.Unit && Rect == p.Rect;
}
/// <summary>
/// Gets a hashcode for a <see cref="RelativeRect"/>.
/// </summary>
/// <returns>A hash code.</returns>
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = (hash * 23) + Unit.GetHashCode();
hash = (hash * 23) + Rect.GetHashCode();
return hash;
}
}
/// <summary>
/// Converts a <see cref="RelativeRect"/> into pixels.
/// </summary>
@ -98,5 +159,52 @@ namespace Perspex
Rect.Width * size.Width,
Rect.Height * size.Height);
}
/// <summary>
/// Parses a <see cref="RelativeRect"/> string.
/// </summary>
/// <param name="s">The string.</param>
/// <param name="culture">The current culture.</param>
/// <returns>The parsed <see cref="RelativeRect"/>.</returns>
public static RelativeRect Parse(string s, CultureInfo culture)
{
var parts = s.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim())
.ToList();
if (parts.Count == 4)
{
var unit = RelativeUnit.Absolute;
var scale = 1.0;
if (parts[0].EndsWith("%"))
{
if (!parts[1].EndsWith("%")
|| !parts[2].EndsWith("%")
|| !parts[3].EndsWith("%"))
{
throw new FormatException("If one coordinate is relative, all other must be too.");
}
parts[0] = parts[0].TrimEnd('%');
parts[1] = parts[1].TrimEnd('%');
parts[2] = parts[2].TrimEnd('%');
parts[3] = parts[3].TrimEnd('%');
unit = RelativeUnit.Relative;
scale = 0.01;
}
return new RelativeRect(
double.Parse(parts[0], culture) * scale,
double.Parse(parts[1], culture) * scale,
double.Parse(parts[2], culture) * scale,
double.Parse(parts[3], culture) * scale,
unit);
}
else
{
throw new FormatException("Invalid Rect.");
}
}
}
}

1
tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj

@ -72,6 +72,7 @@
<Otherwise />
</Choose>
<ItemGroup>
<Compile Include="RelativeRectTests.cs" />
<Compile Include="ThicknessTests.cs" />
<Compile Include="Media\BrushTests.cs" />
<Compile Include="Media\ColorTests.cs" />

27
tests/Perspex.SceneGraph.UnitTests/RelativeRectTests.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 RelativeRectTests
{
[Fact]
public void Parse_Should_Accept_Absolute_Value()
{
var result = RelativeRect.Parse("4,5,50,60", CultureInfo.InvariantCulture);
Assert.Equal(new RelativeRect(4, 5, 50, 60, RelativeUnit.Absolute), result);
}
[Fact]
public void Parse_Should_Accept_Relative_Value()
{
var result = RelativeRect.Parse("10%, 20%, 40%, 70%", CultureInfo.InvariantCulture);
Assert.Equal(new RelativeRect(0.1, 0.2, 0.4, 0.7, RelativeUnit.Relative), result);
}
}
}
Loading…
Cancel
Save