Skip to content

Commit

Permalink
feat(geometry_bounds): Added .Bounds support for some Geometry im…
Browse files Browse the repository at this point in the history
…plementations.
  • Loading branch information
carldebilly committed Jul 10, 2021
1 parent a310ea3 commit ee6ed7f
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 11 deletions.
133 changes: 133 additions & 0 deletions src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Media/Given_Geometry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
using System;
using FluentAssertions.Execution;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Windows.Foundation;
using Windows.UI.Xaml.Media;

namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Media
{
[TestClass]
[RunsOnUIThread]
public class Given_Geometry
{
[TestMethod]
public void RectangleGeometry_CheckBounds_CompositeTransform()
{
var geometry = new RectangleGeometry
{
Rect = new Rect(0, 0, 100, 100),
Transform = new CompositeTransform { CenterX = 50, CenterY = 50, Rotation = 45 }
};

geometry.Bounds.Should().Be(new Rect(-20.7, -20.7, 141.4, 141.4), 0.1);
}

[TestMethod]
public void RectangleGeometry_CheckBounds_TranslateTransform()
{
var geometry = new RectangleGeometry
{
Rect = new Rect(0, 0, 100, 100),
Transform = new TranslateTransform { X=20, Y=40 }
};

geometry.Bounds.Should().Be(new Rect(20, 40, 100, 100));
}

[TestMethod]
public void RectangleGeometry_CheckBounds_ScaleTransform()
{
var geometry = new RectangleGeometry
{
Rect = new Rect(0, 0, 100, 100),
Transform = new ScaleTransform { CenterX = 50, CenterY = 150, ScaleX = 2, ScaleY = 0.5 }
};

geometry.Bounds.Should().Be(new Rect(-50, 75, 200, 50), 0.1);
}

[TestMethod]
public void RectangleGeometry_CheckBounds_Origin()
{
var geometry = new RectangleGeometry
{
Rect = new Rect(100, 100, 100, 100)
};

geometry.Bounds.Should().Be(new Rect(100, 100, 100, 100), 0.1);
}

[TestMethod]
public void RectangleGeometry_CheckBounds_Origin_CompositeTransform()
{
var geometry = new RectangleGeometry
{
Rect = new Rect(100, 100, 100, 100),
Transform = new CompositeTransform { CenterX = 150, CenterY = 150, Rotation = 45 }
};

geometry.Bounds.Should().Be(new Rect(79.3, 79.3, 141.4, 141.4), 0.1);
}

[TestMethod]
public void Composite_RectangleGeometry_CheckBounds_Origin()
{
var geometry1 = new RectangleGeometry
{
Rect = new Rect(100, 100, 100, 100)
};
var geometry2 = new RectangleGeometry
{
Rect = new Rect(10, 10, 10, 10)
};

var geometry = new GeometryGroup();
geometry.Children.Add(geometry1);
geometry.Children.Add(geometry2);

using var _ = new AssertionScope();

geometry1.Bounds.Should().Be(new Rect(100, 100, 100, 100), 0.1);
geometry2.Bounds.Should().Be(new Rect(10, 10, 10, 10), 0.1);
geometry.Bounds.Should().Be(new Rect(10, 10, 190, 190), 0.1);
}

[TestMethod]
public void Composite_RectangleGeometry_CheckBounds_Origin_CompositeTransform()
{
var geometry1 = new RectangleGeometry
{
Rect = new Rect(100, 100, 100, 100),
Transform = new CompositeTransform { CenterX = 150, CenterY = 150, Rotation = 45, TranslateX = 100, TranslateY = -100 }
};
var geometry2 = new RectangleGeometry
{
Rect = new Rect(200, 200, 100, 100),
Transform = new CompositeTransform { CenterX = 350, CenterY = 350, ScaleX=2, ScaleY = 0.5 }
};

var geometry = new GeometryGroup();
geometry.Children.Add(geometry1);
geometry.Children.Add(geometry2);

using var _ = new AssertionScope();

geometry1.Bounds.Should().Be(new Rect(179, -21, 141.5, 141.5), 0.5);
geometry2.Bounds.Should().Be(new Rect(50, 275, 200, 50), 0.5);
geometry.Bounds.Should().Be(new Rect(50, -21, 271, 346), 0.5);
}

[TestMethod]
public void EmptyGeometryGroup_CheckBounds()
{
(new GeometryGroup()).Bounds.Should().Be(default(Rect));
}

[TestMethod]
[ExpectedException(typeof(Exception))] // Catastrophic Failure on UWP
public void EmptyGeometry_CheckBounds()
{
Console.WriteLine(Geometry.Empty.Bounds);
}
}
}
10 changes: 0 additions & 10 deletions src/Uno.UI/Generated/3.0.0.0/Windows.UI.Xaml.Media/Geometry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,6 @@ public partial class Geometry : global::Windows.UI.Xaml.DependencyObject
// Skipping already declared property Transform
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
public global::Windows.Foundation.Rect Bounds
{
get
{
throw new global::System.NotImplementedException("The member Rect Geometry.Bounds is not implemented in Uno.");
}
}
#endif
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
public static global::Windows.UI.Xaml.Media.Geometry Empty
{
get
Expand Down
10 changes: 9 additions & 1 deletion src/Uno.UI/UI/Xaml/Media/Geometry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.ComponentModel;
using Uno.Media;
using Windows.Foundation;

#if XAMARIN_IOS_UNIFIED
using Foundation;
Expand All @@ -24,7 +25,7 @@ namespace Windows.UI.Xaml.Media
[TypeConverter(typeof(GeometryConverter))]
public partial class Geometry : DependencyObject, IDisposable
{
public Geometry()
internal Geometry()
{
InitializeBinder();
}
Expand All @@ -38,6 +39,13 @@ public static implicit operator Geometry(string data)
#endif
}

public Windows.Foundation.Rect Bounds => ComputeBounds();

private protected virtual Windows.Foundation.Rect ComputeBounds()
{
throw new NotImplementedException($"Bounds property is not implemented on {GetType().Name}.");
}

#region Transform

public Transform Transform
Expand Down
31 changes: 31 additions & 0 deletions src/Uno.UI/UI/Xaml/Media/GeometryGroup.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Windows.Foundation;
using Windows.UI.Xaml.Markup;
using Uno.UI;

namespace Windows.UI.Xaml.Media
{
Expand Down Expand Up @@ -51,5 +53,34 @@ public GeometryCollection Children
);

#endregion

private protected override Rect ComputeBounds()
{
Rect? bounds = default;

foreach(var geometry in Children)
{
if(bounds is { } b)
{
bounds = b.UnionWith(geometry.Bounds);
}
else
{
bounds = geometry.Bounds;
}
}

if(bounds is { } result)
{
if(Transform is { } t)
{
return t.TransformBounds(result);
}

return result;
}

return default;
}
}
}
12 changes: 12 additions & 0 deletions src/Uno.UI/UI/Xaml/Media/RectangleGeometry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,17 @@ public override CoreGraphics.CGPath ToCGPath()
#endif

#endregion

private protected override Rect ComputeBounds()
{
if(Transform is { } transform)
{
return transform.TransformBounds(Rect);
}
else
{
return Rect;
}
}
}
}

0 comments on commit ee6ed7f

Please sign in to comment.