Browse Source

Merge pull request #1014 from AvaloniaUI/extract-layout-manager

Extract layout manager to ILayoutRoot
pull/1734/head
Jeremy Koritzinsky 8 years ago
committed by GitHub
parent
commit
08be99c273
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      src/Avalonia.Controls/Application.cs
  2. 2
      src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs
  3. 2
      src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevel.cs
  4. 2
      src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs
  5. 18
      src/Avalonia.Controls/TopLevel.cs
  6. 4
      src/Avalonia.Controls/Window.cs
  7. 5
      src/Avalonia.Controls/WindowBase.cs
  8. 5
      src/Avalonia.Layout/ILayoutRoot.cs
  9. 7
      src/Avalonia.Layout/LayoutManager.cs
  10. 10
      src/Avalonia.Layout/Layoutable.cs
  11. 2
      src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs
  12. 14
      tests/Avalonia.Benchmarks/Layout/Measure.cs
  13. 18
      tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs
  14. 123
      tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs
  15. 1
      tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs
  16. 17
      tests/Avalonia.Controls.UnitTests/TopLevelTests.cs
  17. 2
      tests/Avalonia.Controls.UnitTests/WindowBaseTests.cs
  18. 7
      tests/Avalonia.Layout.UnitTests/FullLayoutTests.cs
  19. 325
      tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs
  20. 87
      tests/Avalonia.Layout.UnitTests/LayoutableTests.cs
  21. 28
      tests/Avalonia.LeakTests/ControlTests.cs
  22. 4
      tests/Avalonia.UnitTests/TestRoot.cs
  23. 11
      tests/Avalonia.UnitTests/TestServices.cs
  24. 4
      tests/Avalonia.UnitTests/TestTemplatedRoot.cs
  25. 1
      tests/Avalonia.UnitTests/UnitTestApplication.cs
  26. 29
      tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs
  27. 20
      tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs

1
src/Avalonia.Controls/Application.cs

@ -332,7 +332,6 @@ namespace Avalonia
.Bind<IInputManager>().ToConstant(InputManager)
.Bind<IKeyboardNavigationHandler>().ToTransient<KeyboardNavigationHandler>()
.Bind<IStyler>().ToConstant(_styler)
.Bind<ILayoutManager>().ToSingleton<LayoutManager>()
.Bind<IApplicationLifecycle>().ToConstant(this)
.Bind<IScheduler>().ToConstant(AvaloniaScheduler.Instance)
.Bind<IDragDropDevice>().ToConstant(DragDropDevice.Instance)

2
src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs

@ -28,7 +28,7 @@ namespace Avalonia.Controls.Embedding
{
EnsureInitialized();
ApplyTemplate();
LayoutManager.Instance.ExecuteInitialLayoutPass(this);
LayoutManager.ExecuteInitialLayoutPass(this);
}
private void EnsureInitialized()

2
src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevel.cs

@ -22,7 +22,7 @@ namespace Avalonia.Controls.Embedding.Offscreen
{
EnsureInitialized();
ApplyTemplate();
LayoutManager.Instance.ExecuteInitialLayoutPass(this);
LayoutManager.ExecuteInitialLayoutPass(this);
}
private void EnsureInitialized()

2
src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs

@ -518,7 +518,7 @@ namespace Avalonia.Controls.Presenters
}
var container = generator.ContainerFromIndex(index);
var layoutManager = LayoutManager.Instance;
var layoutManager = (Owner.GetVisualRoot() as ILayoutRoot)?.LayoutManager;
// We need to do a layout here because it's possible that the container we moved to
// is only partially visible due to differing item sizes. If the container is only

18
src/Avalonia.Controls/TopLevel.cs

@ -54,6 +54,7 @@ namespace Avalonia.Controls
private readonly IApplicationLifecycle _applicationLifecycle;
private readonly IPlatformRenderInterface _renderInterface;
private Size _clientSize;
private ILayoutManager _layoutManager;
/// <summary>
/// Initializes static members of the <see cref="TopLevel"/> class.
@ -147,6 +148,16 @@ namespace Avalonia.Controls
protected set { SetAndRaise(ClientSizeProperty, ref _clientSize, value); }
}
public ILayoutManager LayoutManager
{
get
{
if (_layoutManager == null)
_layoutManager = CreateLayoutManager();
return _layoutManager;
}
}
/// <summary>
/// Gets the platform-specific window implementation.
/// </summary>
@ -235,6 +246,11 @@ namespace Avalonia.Controls
{
return PlatformImpl?.PointToScreen(p) ?? default(Point);
}
/// <summary>
/// Creates the layout manager for this <see cref="TopLevel" />.
/// </summary>
protected virtual ILayoutManager CreateLayoutManager() => new LayoutManager();
/// <summary>
/// Handles a paint notification from <see cref="ITopLevelImpl.Resized"/>.
@ -267,7 +283,7 @@ namespace Avalonia.Controls
ClientSize = clientSize;
Width = clientSize.Width;
Height = clientSize.Height;
LayoutManager.Instance.ExecuteLayoutPass();
LayoutManager.ExecuteLayoutPass();
Renderer?.Resized(clientSize);
}

4
src/Avalonia.Controls/Window.cs

@ -374,7 +374,7 @@ namespace Avalonia.Controls
EnsureInitialized();
IsVisible = true;
LayoutManager.Instance.ExecuteInitialLayoutPass(this);
LayoutManager.ExecuteInitialLayoutPass(this);
using (BeginAutoSizing())
{
@ -416,7 +416,7 @@ namespace Avalonia.Controls
EnsureInitialized();
SetWindowStartupLocation();
IsVisible = true;
LayoutManager.Instance.ExecuteInitialLayoutPass(this);
LayoutManager.ExecuteInitialLayoutPass(this);
using (BeginAutoSizing())
{

5
src/Avalonia.Controls/WindowBase.cs

@ -179,10 +179,9 @@ namespace Avalonia.Controls
if (!_hasExecutedInitialLayoutPass)
{
LayoutManager.Instance.ExecuteInitialLayoutPass(this);
LayoutManager.ExecuteInitialLayoutPass(this);
_hasExecutedInitialLayoutPass = true;
}
PlatformImpl?.Show();
Renderer?.Start();
}
@ -262,7 +261,7 @@ namespace Avalonia.Controls
Height = clientSize.Height;
}
ClientSize = clientSize;
LayoutManager.Instance.ExecuteLayoutPass();
LayoutManager.ExecuteLayoutPass();
Renderer?.Resized(clientSize);
}

5
src/Avalonia.Layout/ILayoutRoot.cs

@ -22,5 +22,10 @@ namespace Avalonia.Layout
/// The scaling factor to use in layout.
/// </summary>
double LayoutScaling { get; }
/// <summary>
/// Associated instance of layout manager
/// </summary>
ILayoutManager LayoutManager { get; }
}
}

7
src/Avalonia.Layout/LayoutManager.cs

@ -19,11 +19,6 @@ namespace Avalonia.Layout
private bool _queued;
private bool _running;
/// <summary>
/// Gets the layout manager.
/// </summary>
public static ILayoutManager Instance => AvaloniaLocator.Current.GetService<ILayoutManager>();
/// <inheritdoc/>
public void InvalidateMeasure(ILayoutable control)
{
@ -170,7 +165,7 @@ namespace Avalonia.Layout
{
root.Measure(Size.Infinity);
}
else
else if (control.PreviousMeasure.HasValue)
{
control.Measure(control.PreviousMeasure.Value);
}

10
src/Avalonia.Layout/Layoutable.cs

@ -389,7 +389,7 @@ namespace Avalonia.Layout
if (((ILayoutable)this).IsAttachedToVisualTree)
{
LayoutManager.Instance?.InvalidateMeasure(this);
(VisualRoot as ILayoutRoot)?.LayoutManager.InvalidateMeasure(this);
InvalidateVisual();
}
OnMeasureInvalidated();
@ -406,12 +406,8 @@ namespace Avalonia.Layout
Logger.Verbose(LogArea.Layout, this, "Invalidated arrange");
IsArrangeValid = false;
if (((ILayoutable)this).IsAttachedToVisualTree)
{
LayoutManager.Instance?.InvalidateArrange(this);
InvalidateVisual();
}
(VisualRoot as ILayoutRoot)?.LayoutManager?.InvalidateArrange(this);
InvalidateVisual();
}
}

2
src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs

@ -49,7 +49,7 @@ namespace Avalonia.Win32.Interop.Wpf
protected override void HandleResized(Size clientSize)
{
ClientSize = clientSize;
LayoutManager.Instance.ExecuteLayoutPass();
LayoutManager.ExecuteLayoutPass();
Renderer?.Resized(clientSize);
}

14
tests/Avalonia.Benchmarks/Layout/Measure.cs

@ -8,26 +8,18 @@ using BenchmarkDotNet.Attributes;
namespace Avalonia.Benchmarks.Layout
{
[MemoryDiagnoser]
public class Measure : IDisposable
public class Measure
{
private IDisposable _app;
private TestRoot root;
private List<Control> controls = new List<Control>();
public Measure()
{
_app = UnitTestApplication.Start(TestServices.RealLayoutManager);
var panel = new StackPanel();
root = new TestRoot { Child = panel };
controls.Add(panel);
CreateChildren(panel, 3, 5);
LayoutManager.Instance.ExecuteInitialLayoutPass(root);
}
public void Dispose()
{
_app.Dispose();
root.LayoutManager.ExecuteInitialLayoutPass(root);
}
[Benchmark]
@ -43,7 +35,7 @@ namespace Avalonia.Benchmarks.Layout
}
}
LayoutManager.Instance.ExecuteLayoutPass();
root.LayoutManager.ExecuteLayoutPass();
}
private void CreateChildren(IPanel parent, int childCount, int iterations)

18
tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs

@ -12,6 +12,7 @@ using Avalonia.Layout;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.UnitTests;
using Avalonia.VisualTree;
using Xunit;
namespace Avalonia.Controls.UnitTests.Presenters
@ -219,13 +220,13 @@ namespace Avalonia.Controls.UnitTests.Presenters
[Fact]
public void Changing_VirtualizationMode_None_To_Simple_Should_Add_Correct_Number_Of_Controls()
{
using (UnitTestApplication.Start(TestServices.RealLayoutManager))
using (UnitTestApplication.Start(new TestServices()))
{
var target = CreateTarget(mode: ItemVirtualizationMode.None);
var scroll = (ScrollContentPresenter)target.Parent;
var scroll = (TestScroller)target.Parent;
scroll.Measure(new Size(100, 100));
scroll.Arrange(new Rect(0, 0, 100, 100));
scroll.Width = scroll.Height = 100;
scroll.LayoutManager.ExecuteInitialLayoutPass(scroll);
// Ensure than an intermediate measure pass doesn't add more controls than it
// should. This can happen if target gets measured with Size.Infinity which
@ -237,7 +238,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
};
target.VirtualizationMode = ItemVirtualizationMode.Simple;
LayoutManager.Instance.ExecuteLayoutPass();
((ILayoutRoot)scroll.GetVisualRoot()).LayoutManager.ExecuteLayoutPass();
Assert.Equal(10, target.Panel.Children.Count);
}
@ -315,12 +316,17 @@ namespace Avalonia.Controls.UnitTests.Presenters
});
}
private class TestScroller : ScrollContentPresenter, IRenderRoot
private class TestScroller : ScrollContentPresenter, IRenderRoot, ILayoutRoot
{
public IRenderer Renderer { get; }
public Size ClientSize { get; }
public double RenderScaling => 1;
public Size MaxClientSize => Size.Infinity;
public double LayoutScaling => 1;
public ILayoutManager LayoutManager { get; } = new LayoutManager();
public IRenderTarget CreateRenderTarget()
{
throw new NotImplementedException();

123
tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs

@ -12,6 +12,7 @@ using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Input;
using Avalonia.Layout;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.UnitTests;
@ -564,11 +565,10 @@ namespace Avalonia.Controls.UnitTests.Presenters
[Fact]
public void Scrolling_To_Item_In_Zero_Sized_Presenter_Doesnt_Throw()
{
using (UnitTestApplication.Start(TestServices.RealLayoutManager))
using (UnitTestApplication.Start(new TestServices()))
{
var target = CreateTarget(itemCount: 10);
var items = (IList<string>)target.Items;
target.ApplyTemplate();
target.Measure(Size.Empty);
target.Arrange(Rect.Empty);
@ -723,10 +723,10 @@ namespace Avalonia.Controls.UnitTests.Presenters
public void GetControlInDirection_Down_Should_Return_Existing_Container_If_Materialized()
{
var target = CreateTarget();
var scroller = (TestScroller)target.Parent;
target.ApplyTemplate();
target.Measure(new Size(100, 100));
target.Arrange(new Rect(0, 0, 100, 100));
scroller.Width = scroller.Height = 100;
scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
var from = target.Panel.Children[5];
var result = ((ILogicalScrollable)target).GetControlInDirection(
@ -740,10 +740,10 @@ namespace Avalonia.Controls.UnitTests.Presenters
public void GetControlInDirection_Down_Should_Scroll_If_Necessary()
{
var target = CreateTarget();
var scroller = (TestScroller)target.Parent;
target.ApplyTemplate();
target.Measure(new Size(100, 100));
target.Arrange(new Rect(0, 0, 100, 100));
scroller.Width = scroller.Height = 100;
scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
var from = target.Panel.Children[9];
var result = ((ILogicalScrollable)target).GetControlInDirection(
@ -757,44 +757,40 @@ namespace Avalonia.Controls.UnitTests.Presenters
[Fact]
public void GetControlInDirection_Down_Should_Scroll_If_Partially_Visible()
{
using (UnitTestApplication.Start(TestServices.RealLayoutManager))
{
var target = CreateTarget();
var scroller = (ScrollContentPresenter)target.Parent;
var target = CreateTarget();
var scroller = (TestScroller)target.Parent;
scroller.Measure(new Size(100, 95));
scroller.Arrange(new Rect(0, 0, 100, 95));
scroller.Width = 100;
scroller.Height = 95;
scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
var from = target.Panel.Children[8];
var result = ((ILogicalScrollable)target).GetControlInDirection(
NavigationDirection.Down,
from);
var from = target.Panel.Children[8];
var result = ((ILogicalScrollable)target).GetControlInDirection(
NavigationDirection.Down,
from);
Assert.Equal(new Vector(0, 1), ((ILogicalScrollable)target).Offset);
Assert.Same(target.Panel.Children[8], result);
}
Assert.Equal(new Vector(0, 1), ((ILogicalScrollable)target).Offset);
Assert.Same(target.Panel.Children[8], result);
}
[Fact]
public void GetControlInDirection_Up_Should_Scroll_If_Partially_Visible_Item_Is_Currently_Shown()
{
using (UnitTestApplication.Start(TestServices.RealLayoutManager))
{
var target = CreateTarget();
var scroller = (ScrollContentPresenter)target.Parent;
var target = CreateTarget();
var scroller = (TestScroller)target.Parent;
scroller.Measure(new Size(100, 95));
scroller.Arrange(new Rect(0, 0, 100, 95));
((ILogicalScrollable)target).Offset = new Vector(0, 11);
scroller.Width = 100;
scroller.Height = 95;
scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
((ILogicalScrollable)target).Offset = new Vector(0, 11);
var from = target.Panel.Children[1];
var result = ((ILogicalScrollable)target).GetControlInDirection(
NavigationDirection.Up,
from);
var from = target.Panel.Children[1];
var result = ((ILogicalScrollable)target).GetControlInDirection(
NavigationDirection.Up,
from);
Assert.Equal(new Vector(0, 10), ((ILogicalScrollable)target).Offset);
Assert.Same(target.Panel.Children[0], result);
}
Assert.Equal(new Vector(0, 10), ((ILogicalScrollable)target).Offset);
Assert.Same(target.Panel.Children[0], result);
}
[Fact]
@ -835,10 +831,10 @@ namespace Avalonia.Controls.UnitTests.Presenters
public void GetControlInDirection_Right_Should_Return_Existing_Container_If_Materialized()
{
var target = CreateTarget(orientation: Orientation.Horizontal);
var scroller = (TestScroller)target.Parent;
target.ApplyTemplate();
target.Measure(new Size(100, 100));
target.Arrange(new Rect(0, 0, 100, 100));
scroller.Width = scroller.Height = 100;
scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
var from = target.Panel.Children[5];
var result = ((ILogicalScrollable)target).GetControlInDirection(
@ -852,10 +848,10 @@ namespace Avalonia.Controls.UnitTests.Presenters
public void GetControlInDirection_Right_Should_Scroll_If_Necessary()
{
var target = CreateTarget(orientation: Orientation.Horizontal);
var scroller = (TestScroller)target.Parent;
target.ApplyTemplate();
target.Measure(new Size(100, 100));
target.Arrange(new Rect(0, 0, 100, 100));
scroller.Width = scroller.Height = 100;
scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
var from = target.Panel.Children[9];
var result = ((ILogicalScrollable)target).GetControlInDirection(
@ -869,32 +865,31 @@ namespace Avalonia.Controls.UnitTests.Presenters
[Fact]
public void GetControlInDirection_Right_Should_Scroll_If_Partially_Visible()
{
using (UnitTestApplication.Start(TestServices.RealLayoutManager))
{
var target = CreateTarget(orientation: Orientation.Horizontal);
var scroller = (ScrollContentPresenter)target.Parent;
var target = CreateTarget(orientation: Orientation.Horizontal);
var scroller = (TestScroller)target.Parent;
scroller.Measure(new Size(95, 100));
scroller.Arrange(new Rect(0, 0, 95, 100));
scroller.Width = 95;
scroller.Height = 100;
scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
var from = target.Panel.Children[8];
var result = ((ILogicalScrollable)target).GetControlInDirection(
NavigationDirection.Right,
from);
var from = target.Panel.Children[8];
var result = ((ILogicalScrollable)target).GetControlInDirection(
NavigationDirection.Right,
from);
Assert.Equal(new Vector(1, 0), ((ILogicalScrollable)target).Offset);
Assert.Same(target.Panel.Children[8], result);
}
Assert.Equal(new Vector(1, 0), ((ILogicalScrollable)target).Offset);
Assert.Same(target.Panel.Children[8], result);
}
[Fact]
public void GetControlInDirection_Left_Should_Scroll_If_Partially_Visible_Item_Is_Currently_Shown()
{
var target = CreateTarget(orientation: Orientation.Horizontal);
var scroller = (TestScroller)target.Parent;
target.ApplyTemplate();
target.Measure(new Size(95, 100));
target.Arrange(new Rect(0, 0, 95, 100));
scroller.Width = 95;
scroller.Height = 100;
scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
((ILogicalScrollable)target).Offset = new Vector(11, 0);
var from = target.Panel.Children[1];
@ -1010,7 +1005,6 @@ namespace Avalonia.Controls.UnitTests.Presenters
};
scroller.UpdateChild();
return result;
}
@ -1032,12 +1026,18 @@ namespace Avalonia.Controls.UnitTests.Presenters
});
}
private class TestScroller : ScrollContentPresenter, IRenderRoot
private class TestScroller : ScrollContentPresenter, IRenderRoot, ILayoutRoot
{
public IRenderer Renderer { get; }
public Size ClientSize { get; }
public double RenderScaling => 1;
public Size MaxClientSize => Size.Infinity;
public double LayoutScaling => 1;
public ILayoutManager LayoutManager { get; } = new LayoutManager();
public IRenderTarget CreateRenderTarget()
{
throw new NotImplementedException();
@ -1057,6 +1057,11 @@ namespace Avalonia.Controls.UnitTests.Presenters
{
throw new NotImplementedException();
}
protected override Size MeasureOverride(Size availableSize)
{
return base.MeasureOverride(availableSize);
}
}
private class TestItemsPresenter : ItemsPresenter

1
tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs

@ -306,7 +306,6 @@ namespace Avalonia.Controls.UnitTests.Primitives
var renderInterface = new Mock<IPlatformRenderInterface>();
AvaloniaLocator.CurrentMutable
.Bind<ILayoutManager>().ToTransient<LayoutManager>()
.Bind<IGlobalStyles>().ToFunc(() => globalStyles.Object)
.Bind<IWindowingPlatform>().ToConstant(new WindowingPlatformMock())
.Bind<IStyler>().ToTransient<Styler>()

17
tests/Avalonia.Controls.UnitTests/TopLevelTests.cs

@ -74,15 +74,16 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void Layout_Pass_Should_Not_Be_Automatically_Scheduled()
{
var services = TestServices.StyledWindow.With(layoutManager: Mock.Of<ILayoutManager>());
var services = TestServices.StyledWindow;
using (UnitTestApplication.Start(services))
{
var impl = new Mock<ITopLevelImpl>();
var target = new TestTopLevel(impl.Object);
var target = new TestTopLevel(impl.Object, Mock.Of<ILayoutManager>());
// The layout pass should be scheduled by the derived class.
var layoutManagerMock = Mock.Get(LayoutManager.Instance);
var layoutManagerMock = Mock.Get(target.LayoutManager);
layoutManagerMock.Verify(x => x.ExecuteLayoutPass(), Times.Never);
}
}
@ -107,7 +108,7 @@ namespace Avalonia.Controls.UnitTests
}
};
LayoutManager.Instance.ExecuteInitialLayoutPass(target);
target.LayoutManager.ExecuteInitialLayoutPass(target);
Assert.Equal(new Rect(0, 0, 321, 432), target.Bounds);
}
@ -122,7 +123,7 @@ namespace Avalonia.Controls.UnitTests
impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
var target = new TestTopLevel(impl.Object);
LayoutManager.Instance.ExecuteLayoutPass();
target.LayoutManager.ExecuteLayoutPass();
Assert.Equal(double.NaN, target.Width);
Assert.Equal(double.NaN, target.Height);
@ -248,13 +249,17 @@ namespace Avalonia.Controls.UnitTests
private class TestTopLevel : TopLevel
{
private readonly ILayoutManager _layoutManager;
public bool IsClosed { get; private set; }
public TestTopLevel(ITopLevelImpl impl)
public TestTopLevel(ITopLevelImpl impl, ILayoutManager layoutManager = null)
: base(impl)
{
_layoutManager = layoutManager ?? new LayoutManager();
}
protected override ILayoutManager CreateLayoutManager() => _layoutManager;
protected override void HandleApplicationExiting()
{
base.HandleApplicationExiting();

2
tests/Avalonia.Controls.UnitTests/WindowBaseTests.cs

@ -40,7 +40,7 @@ namespace Avalonia.Controls.UnitTests
IsVisible = true,
};
LayoutManager.Instance.ExecuteInitialLayoutPass(target);
target.LayoutManager.ExecuteInitialLayoutPass(target);
Mock.Get(impl).Verify(x => x.Resize(new Size(321, 432)));
}

7
tests/Avalonia.Layout.UnitTests/FullLayoutTests.cs

@ -57,11 +57,11 @@ namespace Avalonia.Layout.UnitTests
};
window.Show();
LayoutManager.Instance.ExecuteInitialLayoutPass(window);
window.LayoutManager.ExecuteInitialLayoutPass(window);
Assert.Equal(new Size(400, 400), border.Bounds.Size);
textBlock.Width = 200;
LayoutManager.Instance.ExecuteLayoutPass();
window.LayoutManager.ExecuteLayoutPass();
Assert.Equal(new Size(200, 400), border.Bounds.Size);
}
@ -99,7 +99,7 @@ namespace Avalonia.Layout.UnitTests
};
window.Show();
LayoutManager.Instance.ExecuteInitialLayoutPass(window);
window.LayoutManager.ExecuteInitialLayoutPass(window);
Assert.Equal(new Size(800, 600), window.Bounds.Size);
Assert.Equal(new Size(200, 200), scrollViewer.Bounds.Size);
@ -200,7 +200,6 @@ namespace Avalonia.Layout.UnitTests
.Bind<IAssetLoader>().ToConstant(new AssetLoader())
.Bind<IInputManager>().ToConstant(new Mock<IInputManager>().Object)
.Bind<IGlobalStyles>().ToConstant(globalStyles.Object)
.Bind<ILayoutManager>().ToConstant(new LayoutManager())
.Bind<IRuntimePlatform>().ToConstant(new AppBuilder().RuntimePlatform)
.Bind<IPlatformRenderInterface>().ToConstant(renderInterface.Object)
.Bind<IStyler>().ToConstant(new Styler())

325
tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs

@ -14,290 +14,231 @@ namespace Avalonia.Layout.UnitTests
[Fact]
public void Measures_And_Arranges_InvalidateMeasured_Control()
{
var target = new LayoutManager();
var control = new LayoutTestControl();
var root = new LayoutTestRoot { Child = control };
using (Start(target))
{
var control = new LayoutTestControl();
var root = new LayoutTestRoot { Child = control };
target.ExecuteInitialLayoutPass(root);
control.Measured = control.Arranged = false;
root.LayoutManager.ExecuteInitialLayoutPass(root);
control.Measured = control.Arranged = false;
control.InvalidateMeasure();
target.ExecuteLayoutPass();
control.InvalidateMeasure();
root.LayoutManager.ExecuteLayoutPass();
Assert.True(control.Measured);
Assert.True(control.Arranged);
}
Assert.True(control.Measured);
Assert.True(control.Arranged);
}
[Fact]
public void Arranges_InvalidateArranged_Control()
{
var target = new LayoutManager();
var control = new LayoutTestControl();
var root = new LayoutTestRoot { Child = control };
using (Start(target))
{
var control = new LayoutTestControl();
var root = new LayoutTestRoot { Child = control };
root.LayoutManager.ExecuteInitialLayoutPass(root);
control.Measured = control.Arranged = false;
target.ExecuteInitialLayoutPass(root);
control.Measured = control.Arranged = false;
control.InvalidateArrange();
root.LayoutManager.ExecuteLayoutPass();
control.InvalidateArrange();
target.ExecuteLayoutPass();
Assert.False(control.Measured);
Assert.True(control.Arranged);
}
Assert.False(control.Measured);
Assert.True(control.Arranged);
}
[Fact]
public void Measures_Parent_Of_Newly_Added_Control()
{
var target = new LayoutManager();
using (Start(target))
{
var control = new LayoutTestControl();
var root = new LayoutTestRoot();
var control = new LayoutTestControl();
var root = new LayoutTestRoot();
target.ExecuteInitialLayoutPass(root);
root.Child = control;
root.Measured = root.Arranged = false;
root.LayoutManager.ExecuteInitialLayoutPass(root);
root.Child = control;
root.Measured = root.Arranged = false;
target.ExecuteLayoutPass();
root.LayoutManager.ExecuteLayoutPass();
Assert.True(root.Measured);
Assert.True(root.Arranged);
Assert.True(control.Measured);
Assert.True(control.Arranged);
}
Assert.True(root.Measured);
Assert.True(root.Arranged);
Assert.True(control.Measured);
Assert.True(control.Arranged);
}
[Fact]
public void Measures_In_Correct_Order()
{
var target = new LayoutManager();
using (Start(target))
LayoutTestControl control1;
LayoutTestControl control2;
var root = new LayoutTestRoot
{
LayoutTestControl control1;
LayoutTestControl control2;
var root = new LayoutTestRoot
Child = control1 = new LayoutTestControl
{
Child = control1 = new LayoutTestControl
{
Child = control2 = new LayoutTestControl(),
}
};
Child = control2 = new LayoutTestControl(),
}
};
var order = new List<ILayoutable>();
Size MeasureOverride(ILayoutable control, Size size)
{
order.Add(control);
return new Size(10, 10);
}
var order = new List<ILayoutable>();
Size MeasureOverride(ILayoutable control, Size size)
{
order.Add(control);
return new Size(10, 10);
}
root.DoMeasureOverride = MeasureOverride;
control1.DoMeasureOverride = MeasureOverride;
control2.DoMeasureOverride = MeasureOverride;
target.ExecuteInitialLayoutPass(root);
root.DoMeasureOverride = MeasureOverride;
control1.DoMeasureOverride = MeasureOverride;
control2.DoMeasureOverride = MeasureOverride;
root.LayoutManager.ExecuteInitialLayoutPass(root);
control2.InvalidateMeasure();
control1.InvalidateMeasure();
root.InvalidateMeasure();
control2.InvalidateMeasure();
control1.InvalidateMeasure();
root.InvalidateMeasure();
order.Clear();
target.ExecuteLayoutPass();
order.Clear();
root.LayoutManager.ExecuteLayoutPass();
Assert.Equal(new ILayoutable[] { root, control1, control2 }, order);
}
Assert.Equal(new ILayoutable[] { root, control1, control2 }, order);
}
[Fact]
public void Measures_Root_And_Grandparent_In_Correct_Order()
{
var target = new LayoutManager();
using (Start(target))
LayoutTestControl control1;
LayoutTestControl control2;
var root = new LayoutTestRoot
{
LayoutTestControl control1;
LayoutTestControl control2;
var root = new LayoutTestRoot
Child = control1 = new LayoutTestControl
{
Child = control1 = new LayoutTestControl
{
Child = control2 = new LayoutTestControl(),
}
};
Child = control2 = new LayoutTestControl(),
}
};
var order = new List<ILayoutable>();
Size MeasureOverride(ILayoutable control, Size size)
{
order.Add(control);
return new Size(10, 10);
}
var order = new List<ILayoutable>();
Size MeasureOverride(ILayoutable control, Size size)
{
order.Add(control);
return new Size(10, 10);
}
root.DoMeasureOverride = MeasureOverride;
control1.DoMeasureOverride = MeasureOverride;
control2.DoMeasureOverride = MeasureOverride;
target.ExecuteInitialLayoutPass(root);
root.DoMeasureOverride = MeasureOverride;
control1.DoMeasureOverride = MeasureOverride;
control2.DoMeasureOverride = MeasureOverride;
root.LayoutManager.ExecuteInitialLayoutPass(root);
control2.InvalidateMeasure();
root.InvalidateMeasure();
control2.InvalidateMeasure();
root.InvalidateMeasure();
order.Clear();
target.ExecuteLayoutPass();
order.Clear();
root.LayoutManager.ExecuteLayoutPass();
Assert.Equal(new ILayoutable[] { root, control2 }, order);
}
Assert.Equal(new ILayoutable[] { root, control2 }, order);
}
[Fact]
public void Doesnt_Measure_Non_Invalidated_Root()
{
var target = new LayoutManager();
var control = new LayoutTestControl();
var root = new LayoutTestRoot { Child = control };
using (Start(target))
{
var control = new LayoutTestControl();
var root = new LayoutTestRoot { Child = control };
target.ExecuteInitialLayoutPass(root);
root.Measured = root.Arranged = false;
control.Measured = control.Arranged = false;
root.LayoutManager.ExecuteInitialLayoutPass(root);
root.Measured = root.Arranged = false;
control.Measured = control.Arranged = false;
control.InvalidateMeasure();
target.ExecuteLayoutPass();
control.InvalidateMeasure();
root.LayoutManager.ExecuteLayoutPass();
Assert.False(root.Measured);
Assert.False(root.Arranged);
Assert.True(control.Measured);
Assert.True(control.Arranged);
}
Assert.False(root.Measured);
Assert.False(root.Arranged);
Assert.True(control.Measured);
Assert.True(control.Arranged);
}
[Fact]
public void Doesnt_Measure_Removed_Control()
{
var target = new LayoutManager();
var control = new LayoutTestControl();
var root = new LayoutTestRoot { Child = control };
using (Start(target))
{
var control = new LayoutTestControl();
var root = new LayoutTestRoot { Child = control };
root.LayoutManager.ExecuteInitialLayoutPass(root);
control.Measured = control.Arranged = false;
target.ExecuteInitialLayoutPass(root);
control.Measured = control.Arranged = false;
control.InvalidateMeasure();
root.Child = null;
root.LayoutManager.ExecuteLayoutPass();
control.InvalidateMeasure();
root.Child = null;
target.ExecuteLayoutPass();
Assert.False(control.Measured);
Assert.False(control.Arranged);
}
Assert.False(control.Measured);
Assert.False(control.Arranged);
}
[Fact]
public void Measures_Root_With_Infinity()
{
var target = new LayoutManager();
var root = new LayoutTestRoot();
var availableSize = default(Size);
using (Start(target))
{
var root = new LayoutTestRoot();
var availableSize = default(Size);
// Should not measure with this size.
root.MaxClientSize = new Size(123, 456);
// Should not measure with this size.
root.MaxClientSize = new Size(123, 456);
root.DoMeasureOverride = (_, s) =>
{
availableSize = s;
return new Size(100, 100);
};
root.DoMeasureOverride = (_, s) =>
{
availableSize = s;
return new Size(100, 100);
};
target.ExecuteInitialLayoutPass(root);
root.LayoutManager.ExecuteInitialLayoutPass(root);
Assert.Equal(Size.Infinity, availableSize);
}
Assert.Equal(Size.Infinity, availableSize);
}
[Fact]
public void Arranges_Root_With_DesiredSize()
{
var target = new LayoutManager();
using (Start(target))
var root = new LayoutTestRoot
{
var root = new LayoutTestRoot
{
Width = 100,
Height = 100,
};
Width = 100,
Height = 100,
};
var arrangeSize = default(Size);
var arrangeSize = default(Size);
root.DoArrangeOverride = (_, s) =>
{
arrangeSize = s;
return s;
};
target.ExecuteInitialLayoutPass(root);
Assert.Equal(new Size(100, 100), arrangeSize);
root.Width = 120;
root.DoArrangeOverride = (_, s) =>
{
arrangeSize = s;
return s;
};
root.LayoutManager.ExecuteInitialLayoutPass(root);
Assert.Equal(new Size(100, 100), arrangeSize);
target.ExecuteLayoutPass();
Assert.Equal(new Size(120, 100), arrangeSize);
}
root.Width = 120;
root.LayoutManager.ExecuteLayoutPass();
Assert.Equal(new Size(120, 100), arrangeSize);
}
[Fact]
public void Invalidating_Child_Remeasures_Parent()
{
var target = new LayoutManager();
Border border;
StackPanel panel;
using (Start(target))
var root = new LayoutTestRoot
{
AvaloniaLocator.CurrentMutable.Bind<ILayoutManager>().ToConstant(target);
Border border;
StackPanel panel;
var root = new LayoutTestRoot
Child = panel = new StackPanel
{
Child = panel = new StackPanel
Children =
{
Children =
{
(border = new Border())
}
(border = new Border())
}
};
target.ExecuteInitialLayoutPass(root);
Assert.Equal(new Size(0, 0), root.DesiredSize);
}
};
border.Width = 100;
border.Height = 100;
root.LayoutManager.ExecuteInitialLayoutPass(root);
Assert.Equal(new Size(0, 0), root.DesiredSize);
target.ExecuteLayoutPass();
Assert.Equal(new Size(100, 100), panel.DesiredSize);
}
}
border.Width = 100;
border.Height = 100;
private IDisposable Start(LayoutManager layoutManager)
{
var result = AvaloniaLocator.EnterScope();
AvaloniaLocator.CurrentMutable.Bind<ILayoutManager>().ToConstant(layoutManager);
return result;
root.LayoutManager.ExecuteLayoutPass();
Assert.Equal(new Size(100, 100), panel.DesiredSize);
}
}
}

87
tests/Avalonia.Layout.UnitTests/LayoutableTests.cs

@ -102,80 +102,73 @@ namespace Avalonia.Layout.UnitTests
public void Only_Calls_LayoutManager_InvalidateMeasure_Once()
{
var target = new Mock<ILayoutManager>();
using (Start(target.Object))
var control = new Decorator();
var root = new LayoutTestRoot
{
var control = new Decorator();
var root = new LayoutTestRoot { Child = control };
Child = control,
LayoutManager = target.Object,
};
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
target.ResetCalls();
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
target.ResetCalls();
control.InvalidateMeasure();
control.InvalidateMeasure();
control.InvalidateMeasure();
control.InvalidateMeasure();
target.Verify(x => x.InvalidateMeasure(control), Times.Once());
}
target.Verify(x => x.InvalidateMeasure(control), Times.Once());
}
[Fact]
public void Only_Calls_LayoutManager_InvalidateArrange_Once()
{
var target = new Mock<ILayoutManager>();
using (Start(target.Object))
var control = new Decorator();
var root = new LayoutTestRoot
{
var control = new Decorator();
var root = new LayoutTestRoot { Child = control };
Child = control,
LayoutManager = target.Object,
};
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
target.ResetCalls();
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
target.ResetCalls();
control.InvalidateArrange();
control.InvalidateArrange();
control.InvalidateArrange();
control.InvalidateArrange();
target.Verify(x => x.InvalidateArrange(control), Times.Once());
}
target.Verify(x => x.InvalidateArrange(control), Times.Once());
}
[Fact]
public void Attaching_Control_To_Tree_Invalidates_Parent_Measure()
{
var target = new Mock<ILayoutManager>();
using (Start(target.Object))
var control = new Decorator();
var root = new LayoutTestRoot
{
var control = new Decorator();
var root = new LayoutTestRoot { Child = control };
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
Assert.True(control.IsMeasureValid);
Child = control,
LayoutManager = target.Object,
};
root.Child = null;
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
Assert.True(control.IsMeasureValid);
Assert.False(control.IsMeasureValid);
Assert.True(root.IsMeasureValid);
root.Child = null;
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
target.ResetCalls();
Assert.False(control.IsMeasureValid);
Assert.True(root.IsMeasureValid);
root.Child = control;
target.ResetCalls();
Assert.False(root.IsMeasureValid);
Assert.False(control.IsMeasureValid);
target.Verify(x => x.InvalidateMeasure(root), Times.Once());
}
}
root.Child = control;
private IDisposable Start(ILayoutManager layoutManager)
{
var result = AvaloniaLocator.EnterScope();
AvaloniaLocator.CurrentMutable.Bind<ILayoutManager>().ToConstant(layoutManager);
return result;
Assert.False(root.IsMeasureValid);
Assert.False(control.IsMeasureValid);
target.Verify(x => x.InvalidateMeasure(root), Times.Once());
}
private class TestLayoutable : Layoutable

28
tests/Avalonia.LeakTests/ControlTests.cs

@ -42,12 +42,12 @@ namespace Avalonia.LeakTests
window.Show();
// Do a layout and make sure that Canvas gets added to visual tree.
LayoutManager.Instance.ExecuteInitialLayoutPass(window);
window.LayoutManager.ExecuteInitialLayoutPass(window);
Assert.IsType<Canvas>(window.Presenter.Child);
// Clear the content and ensure the Canvas is removed.
window.Content = null;
LayoutManager.Instance.ExecuteLayoutPass();
window.LayoutManager.ExecuteLayoutPass();
Assert.Null(window.Presenter.Child);
return window;
@ -78,13 +78,13 @@ namespace Avalonia.LeakTests
window.Show();
// Do a layout and make sure that Canvas gets added to visual tree.
LayoutManager.Instance.ExecuteInitialLayoutPass(window);
window.LayoutManager.ExecuteInitialLayoutPass(window);
Assert.IsType<Canvas>(window.Find<Canvas>("foo"));
Assert.IsType<Canvas>(window.Presenter.Child);
// Clear the content and ensure the Canvas is removed.
window.Content = null;
LayoutManager.Instance.ExecuteLayoutPass();
window.LayoutManager.ExecuteLayoutPass();
Assert.Null(window.Presenter.Child);
return window;
@ -116,13 +116,13 @@ namespace Avalonia.LeakTests
// Do a layout and make sure that ScrollViewer gets added to visual tree and its
// template applied.
LayoutManager.Instance.ExecuteInitialLayoutPass(window);
window.LayoutManager.ExecuteInitialLayoutPass(window);
Assert.IsType<ScrollViewer>(window.Presenter.Child);
Assert.IsType<Canvas>(((ScrollViewer)window.Presenter.Child).Presenter.Child);
// Clear the content and ensure the ScrollViewer is removed.
window.Content = null;
LayoutManager.Instance.ExecuteLayoutPass();
window.LayoutManager.ExecuteLayoutPass();
Assert.Null(window.Presenter.Child);
return window;
@ -153,13 +153,13 @@ namespace Avalonia.LeakTests
// Do a layout and make sure that TextBox gets added to visual tree and its
// template applied.
LayoutManager.Instance.ExecuteInitialLayoutPass(window);
window.LayoutManager.ExecuteInitialLayoutPass(window);
Assert.IsType<TextBox>(window.Presenter.Child);
Assert.NotEmpty(window.Presenter.Child.GetVisualChildren());
// Clear the content and ensure the TextBox is removed.
window.Content = null;
LayoutManager.Instance.ExecuteLayoutPass();
window.LayoutManager.ExecuteLayoutPass();
Assert.Null(window.Presenter.Child);
return window;
@ -197,14 +197,14 @@ namespace Avalonia.LeakTests
// Do a layout and make sure that TextBox gets added to visual tree and its
// Text property set.
LayoutManager.Instance.ExecuteInitialLayoutPass(window);
window.LayoutManager.ExecuteInitialLayoutPass(window);
Assert.IsType<TextBox>(window.Presenter.Child);
Assert.Equal("foo", ((TextBox)window.Presenter.Child).Text);
// Clear the content and DataContext and ensure the TextBox is removed.
window.Content = null;
window.DataContext = null;
LayoutManager.Instance.ExecuteLayoutPass();
window.LayoutManager.ExecuteLayoutPass();
Assert.Null(window.Presenter.Child);
return window;
@ -235,7 +235,7 @@ namespace Avalonia.LeakTests
// Do a layout and make sure that TextBox gets added to visual tree and its
// template applied.
LayoutManager.Instance.ExecuteInitialLayoutPass(window);
window.LayoutManager.ExecuteInitialLayoutPass(window);
Assert.Same(textBox, window.Presenter.Child);
// Get the border from the TextBox template.
@ -247,7 +247,7 @@ namespace Avalonia.LeakTests
// Clear the content and ensure the TextBox is removed.
window.Content = null;
LayoutManager.Instance.ExecuteLayoutPass();
window.LayoutManager.ExecuteLayoutPass();
Assert.Null(window.Presenter.Child);
// Check that the TextBox has no subscriptions to its Classes collection.
@ -289,12 +289,12 @@ namespace Avalonia.LeakTests
window.Show();
// Do a layout and make sure that TreeViewItems get realized.
LayoutManager.Instance.ExecuteInitialLayoutPass(window);
window.LayoutManager.ExecuteInitialLayoutPass(window);
Assert.Single(target.ItemContainerGenerator.Containers);
// Clear the content and ensure the TreeView is removed.
window.Content = null;
LayoutManager.Instance.ExecuteLayoutPass();
window.LayoutManager.ExecuteLayoutPass();
Assert.Null(window.Presenter.Child);
return window;

4
tests/Avalonia.UnitTests/TestRoot.cs

@ -43,9 +43,9 @@ namespace Avalonia.UnitTests
public double LayoutScaling => 1;
public double RenderScaling => 1;
public ILayoutManager LayoutManager { get; set; } = new LayoutManager();
public ILayoutManager LayoutManager => AvaloniaLocator.Current.GetService<ILayoutManager>();
public double RenderScaling => 1;
public IRenderer Renderer { get; set; }

11
tests/Avalonia.UnitTests/TestServices.cs

@ -23,7 +23,6 @@ namespace Avalonia.UnitTests
{
public static readonly TestServices StyledWindow = new TestServices(
assetLoader: new AssetLoader(),
layoutManager: new LayoutManager(),
platform: new AppBuilder().RuntimePlatform,
renderInterface: new MockPlatformRenderInterface(),
standardCursorFactory: Mock.Of<IStandardCursorFactory>(),
@ -52,10 +51,7 @@ namespace Avalonia.UnitTests
keyboardDevice: () => new KeyboardDevice(),
keyboardNavigation: new KeyboardNavigationHandler(),
inputManager: new InputManager());
public static readonly TestServices RealLayoutManager = new TestServices(
layoutManager: new LayoutManager());
public static readonly TestServices RealStyler = new TestServices(
styler: new Styler());
@ -65,7 +61,6 @@ namespace Avalonia.UnitTests
IInputManager inputManager = null,
Func<IKeyboardDevice> keyboardDevice = null,
IKeyboardNavigationHandler keyboardNavigation = null,
ILayoutManager layoutManager = null,
Func<IMouseDevice> mouseDevice = null,
IRuntimePlatform platform = null,
IPlatformRenderInterface renderInterface = null,
@ -83,7 +78,6 @@ namespace Avalonia.UnitTests
InputManager = inputManager;
KeyboardDevice = keyboardDevice;
KeyboardNavigation = keyboardNavigation;
LayoutManager = layoutManager;
MouseDevice = mouseDevice;
Platform = platform;
RenderInterface = renderInterface;
@ -101,7 +95,6 @@ namespace Avalonia.UnitTests
public IFocusManager FocusManager { get; }
public Func<IKeyboardDevice> KeyboardDevice { get; }
public IKeyboardNavigationHandler KeyboardNavigation { get; }
public ILayoutManager LayoutManager { get; }
public Func<IMouseDevice> MouseDevice { get; }
public IRuntimePlatform Platform { get; }
public IPlatformRenderInterface RenderInterface { get; }
@ -119,7 +112,6 @@ namespace Avalonia.UnitTests
IInputManager inputManager = null,
Func<IKeyboardDevice> keyboardDevice = null,
IKeyboardNavigationHandler keyboardNavigation = null,
ILayoutManager layoutManager = null,
Func<IMouseDevice> mouseDevice = null,
IRuntimePlatform platform = null,
IPlatformRenderInterface renderInterface = null,
@ -138,7 +130,6 @@ namespace Avalonia.UnitTests
inputManager: inputManager ?? InputManager,
keyboardDevice: keyboardDevice ?? KeyboardDevice,
keyboardNavigation: keyboardNavigation ?? KeyboardNavigation,
layoutManager: layoutManager ?? LayoutManager,
mouseDevice: mouseDevice ?? MouseDevice,
platform: platform ?? Platform,
renderInterface: renderInterface ?? RenderInterface,

4
tests/Avalonia.UnitTests/TestTemplatedRoot.cs

@ -39,9 +39,9 @@ namespace Avalonia.UnitTests
public double LayoutScaling => 1;
public double RenderScaling => 1;
public ILayoutManager LayoutManager { get; set; } = new LayoutManager();
public ILayoutManager LayoutManager => AvaloniaLocator.Current.GetService<ILayoutManager>();
public double RenderScaling => 1;
public IRenderTarget RenderTarget => null;

1
tests/Avalonia.UnitTests/UnitTestApplication.cs

@ -50,7 +50,6 @@ namespace Avalonia.UnitTests
.Bind<IInputManager>().ToConstant(Services.InputManager)
.Bind<IKeyboardDevice>().ToConstant(Services.KeyboardDevice?.Invoke())
.Bind<IKeyboardNavigationHandler>().ToConstant(Services.KeyboardNavigation)
.Bind<ILayoutManager>().ToConstant(Services.LayoutManager)
.Bind<IMouseDevice>().ToConstant(Services.MouseDevice?.Invoke())
.Bind<IRuntimePlatform>().ToConstant(Services.Platform)
.Bind<IPlatformRenderInterface>().ToConstant(Services.RenderInterface)

29
tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs

@ -522,7 +522,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
[Fact]
public void Should_Update_ClipBounds_For_Negative_Margin()
{
using (TestApplication())
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
{
Decorator decorator;
Border border;
@ -542,7 +542,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
}
};
var layout = AvaloniaLocator.Current.GetService<ILayoutManager>();
var layout = tree.LayoutManager;
layout.ExecuteInitialLayoutPass(tree);
var scene = new Scene(tree);
@ -566,7 +566,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
[Fact]
public void Should_Update_Descendent_Tranform_When_Margin_Changed()
{
using (TestApplication())
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
{
Decorator decorator;
Border border;
@ -585,7 +585,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
}
};
var layout = AvaloniaLocator.Current.GetService<ILayoutManager>();
var layout = tree.LayoutManager;
layout.ExecuteInitialLayoutPass(tree);
var scene = new Scene(tree);
@ -613,7 +613,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
[Fact]
public void DirtyRects_Should_Contain_Old_And_New_Bounds_When_Margin_Changed()
{
using (TestApplication())
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
{
Decorator decorator;
Border border;
@ -633,7 +633,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
}
};
var layout = AvaloniaLocator.Current.GetService<ILayoutManager>();
var layout = tree.LayoutManager;
layout.ExecuteInitialLayoutPass(tree);
var scene = new Scene(tree);
@ -660,7 +660,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
[Fact]
public void Resizing_Scene_Should_Add_DirtyRects()
{
using (TestApplication())
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
{
Decorator decorator;
Border border;
@ -707,7 +707,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
[Fact]
public void Setting_Opacity_Should_Add_Descendent_Bounds_To_DirtyRects()
{
using (TestApplication())
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
{
Decorator decorator;
Border border;
@ -744,7 +744,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
[Fact]
public void Should_Set_GeometryClip()
{
using (TestApplication())
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
{
var clip = StreamGeometry.Parse("M100,0 L0,100 100,100");
Decorator decorator;
@ -768,7 +768,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
[Fact]
public void Disposing_Scene_Releases_DrawOperation_References()
{
using (TestApplication())
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
{
var bitmap = RefCountable.Create(Mock.Of<IBitmapImpl>());
Image img;
@ -800,7 +800,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
[Fact]
public void Replacing_Control_Releases_DrawOperation_Reference()
{
using (TestApplication())
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
{
var bitmap = RefCountable.Create(Mock.Of<IBitmapImpl>());
Image img;
@ -830,12 +830,5 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
}
}
}
private IDisposable TestApplication()
{
return UnitTestApplication.Start(
TestServices.MockPlatformRenderInterface.With(
layoutManager: new LayoutManager()));
}
}
}

20
tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs

@ -17,7 +17,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
[Fact]
public void Control_With_Animated_Opacity_And_Children_Should_Start_New_Layer()
{
using (TestApplication())
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
{
Decorator decorator;
Border border;
@ -39,7 +39,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
}
};
var layout = AvaloniaLocator.Current.GetService<ILayoutManager>();
var layout = tree.LayoutManager;
layout.ExecuteInitialLayoutPass(tree);
var animation = new BehaviorSubject<double>(0.5);
@ -85,7 +85,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
[Fact]
public void Control_With_Animated_Opacity_And_No_Children_Should_Not_Start_New_Layer()
{
using (TestApplication())
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
{
Decorator decorator;
Border border;
@ -104,7 +104,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
}
};
var layout = AvaloniaLocator.Current.GetService<ILayoutManager>();
var layout = tree.LayoutManager;
layout.ExecuteInitialLayoutPass(tree);
var animation = new BehaviorSubject<double>(0.5);
@ -121,7 +121,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
[Fact]
public void Removing_Control_With_Animated_Opacity_Should_Remove_Layers()
{
using (TestApplication())
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
{
Decorator decorator;
Border border;
@ -146,7 +146,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
}
};
var layout = AvaloniaLocator.Current.GetService<ILayoutManager>();
var layout = tree.LayoutManager;
layout.ExecuteInitialLayoutPass(tree);
var animation = new BehaviorSubject<double>(0.5);
@ -171,7 +171,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
[Fact]
public void Hiding_Transparent_Control_Should_Remove_Layers()
{
using (TestApplication())
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
{
Decorator decorator;
Border border;
@ -196,7 +196,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
}
};
var layout = AvaloniaLocator.Current.GetService<ILayoutManager>();
var layout = tree.LayoutManager;
layout.ExecuteInitialLayoutPass(tree);
var animation = new BehaviorSubject<double>(0.5);
@ -221,7 +221,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
[Fact]
public void GeometryClip_Should_Affect_Child_Layers()
{
using (TestApplication())
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
{
var clip = StreamGeometry.Parse("M100,0 L0,100 100,100");
Decorator decorator;
@ -240,7 +240,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
}
};
var layout = AvaloniaLocator.Current.GetService<ILayoutManager>();
var layout = tree.LayoutManager;
layout.ExecuteInitialLayoutPass(tree);
var animation = new BehaviorSubject<double>(0.5);

Loading…
Cancel
Save