Browse Source

Added test for SCV.BringDescendentIntoView

pull/330/head
Steven Kirk 10 years ago
parent
commit
bd6b6bad67
  1. 29
      src/Perspex.SceneGraph/Visual.cs
  2. 14
      src/Perspex.SceneGraph/VisualTree/VisualExtensions.cs
  3. 22
      tests/Perspex.Controls.UnitTests/Presenters/ScrollContentPresenterTests.cs

29
src/Perspex.SceneGraph/Visual.cs

@ -307,8 +307,9 @@ namespace Perspex
/// <returns>A <see cref="Matrix"/> containing the transform.</returns>
public Matrix TransformToVisual(IVisual visual)
{
var thisOffset = GetOffsetFromRoot(this).Item2;
var thatOffset = GetOffsetFromRoot(visual).Item2;
var common = this.FindCommonVisualAncestor(visual);
var thisOffset = GetOffsetFrom(common, this);
var thatOffset = GetOffsetFrom(common, visual);
return Matrix.CreateTranslation(-thatOffset) * Matrix.CreateTranslation(thisOffset);
}
@ -468,6 +469,30 @@ namespace Perspex
}
}
/// <summary>
/// Gets the visual offset from the specified ancestor.
/// </summary>
/// <param name="ancestor">The ancestor visual.</param>
/// <param name="visual">The visual.</param>
/// <returns>The visual offset.</returns>
private static Vector GetOffsetFrom(IVisual ancestor, IVisual visual)
{
var result = new Vector();
while (visual != ancestor)
{
result = new Vector(result.X + visual.Bounds.X, result.Y + visual.Bounds.Y);
visual = visual.VisualParent;
if (visual == null)
{
throw new ArgumentException("'visual' is not a descendent of 'ancestor'.");
}
}
return result;
}
/// <summary>
/// Gets the root of the controls visual tree and the distance from the root.
/// </summary>

14
src/Perspex.SceneGraph/VisualTree/VisualExtensions.cs

@ -8,10 +8,22 @@ using System.Linq;
namespace Perspex.VisualTree
{
/// <summary>
/// Provides extension methods for working with visual tree.
/// Provides extension methods for working with the visual tree.
/// </summary>
public static class VisualExtensions
{
/// <summary>
/// Tries to get the first common ancestor of two visuals.
/// </summary>
/// <param name="visual">The first visual.</param>
/// <param name="target">The second visual.</param>
/// <returns>The common ancestor, or null if not found.</returns>
public static IVisual FindCommonVisualAncestor(this IVisual visual, IVisual target)
{
return visual.GetSelfAndVisualAncestors().Intersect(target.GetSelfAndVisualAncestors())
.FirstOrDefault();
}
/// <summary>
/// Enumerates the ancestors of an <see cref="IVisual"/> in the visual tree.
/// </summary>

22
tests/Perspex.Controls.UnitTests/Presenters/ScrollContentPresenterTests.cs

@ -189,6 +189,28 @@ namespace Perspex.Controls.UnitTests.Presenters
Assert.Equal(new Vector(10, 10), target.Offset);
}
[Fact]
public void BringDescendentIntoView_Should_Work()
{
var target = new ScrollContentPresenter
{
Width = 100,
Height = 100,
Content = new Border
{
Width = 200,
Height = 200,
}
};
target.ApplyTemplate();
target.Measure(Size.Infinity);
target.Arrange(new Rect(0, 0, 100, 100));
target.BringDescendentIntoView(target.Child, new Rect(200, 200, 0, 0));
Assert.Equal(new Vector(100, 100), target.Offset);
}
private class TestControl : Control
{
protected override Size MeasureOverride(Size availableSize)

Loading…
Cancel
Save