diff --git a/src/Avalonia.Controls/Application.cs b/src/Avalonia.Controls/Application.cs index de27aa94f8..499b65c5b7 100644 --- a/src/Avalonia.Controls/Application.cs +++ b/src/Avalonia.Controls/Application.cs @@ -332,7 +332,6 @@ namespace Avalonia .Bind().ToConstant(InputManager) .Bind().ToTransient() .Bind().ToConstant(_styler) - .Bind().ToSingleton() .Bind().ToConstant(this) .Bind().ToConstant(AvaloniaScheduler.Instance) .Bind().ToConstant(DragDropDevice.Instance) diff --git a/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs b/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs index 179dccaf76..c177d43917 100644 --- a/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs +++ b/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() diff --git a/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevel.cs b/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevel.cs index 4db16c71a5..5becdc0f61 100644 --- a/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevel.cs +++ b/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() diff --git a/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs b/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs index c1489e7138..b98f26b87f 100644 --- a/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs +++ b/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 diff --git a/src/Avalonia.Controls/TopLevel.cs b/src/Avalonia.Controls/TopLevel.cs index 1af347ab4e..9fdc097c3f 100644 --- a/src/Avalonia.Controls/TopLevel.cs +++ b/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; /// /// Initializes static members of the 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; + } + } + /// /// Gets the platform-specific window implementation. /// @@ -235,6 +246,11 @@ namespace Avalonia.Controls { return PlatformImpl?.PointToScreen(p) ?? default(Point); } + + /// + /// Creates the layout manager for this . + /// + protected virtual ILayoutManager CreateLayoutManager() => new LayoutManager(); /// /// Handles a paint notification from . @@ -267,7 +283,7 @@ namespace Avalonia.Controls ClientSize = clientSize; Width = clientSize.Width; Height = clientSize.Height; - LayoutManager.Instance.ExecuteLayoutPass(); + LayoutManager.ExecuteLayoutPass(); Renderer?.Resized(clientSize); } diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs index bfb9973ee6..d1a023c42c 100644 --- a/src/Avalonia.Controls/Window.cs +++ b/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()) { diff --git a/src/Avalonia.Controls/WindowBase.cs b/src/Avalonia.Controls/WindowBase.cs index 5d66bee2f8..c0b664ebc3 100644 --- a/src/Avalonia.Controls/WindowBase.cs +++ b/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); } diff --git a/src/Avalonia.Layout/ILayoutRoot.cs b/src/Avalonia.Layout/ILayoutRoot.cs index 25a6331b38..700b6a8600 100644 --- a/src/Avalonia.Layout/ILayoutRoot.cs +++ b/src/Avalonia.Layout/ILayoutRoot.cs @@ -22,5 +22,10 @@ namespace Avalonia.Layout /// The scaling factor to use in layout. /// double LayoutScaling { get; } + + /// + /// Associated instance of layout manager + /// + ILayoutManager LayoutManager { get; } } } diff --git a/src/Avalonia.Layout/LayoutManager.cs b/src/Avalonia.Layout/LayoutManager.cs index b6b786a077..9cf8521008 100644 --- a/src/Avalonia.Layout/LayoutManager.cs +++ b/src/Avalonia.Layout/LayoutManager.cs @@ -19,11 +19,6 @@ namespace Avalonia.Layout private bool _queued; private bool _running; - /// - /// Gets the layout manager. - /// - public static ILayoutManager Instance => AvaloniaLocator.Current.GetService(); - /// 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); } diff --git a/src/Avalonia.Layout/Layoutable.cs b/src/Avalonia.Layout/Layoutable.cs index 523c720e2f..7112e216ff 100644 --- a/src/Avalonia.Layout/Layoutable.cs +++ b/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(); } } diff --git a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs index 0c46eceef6..7c0e0311a6 100644 --- a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs +++ b/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); } diff --git a/tests/Avalonia.Benchmarks/Layout/Measure.cs b/tests/Avalonia.Benchmarks/Layout/Measure.cs index d1fdae9971..b0490d8a0f 100644 --- a/tests/Avalonia.Benchmarks/Layout/Measure.cs +++ b/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 controls = new List(); 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) diff --git a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs b/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs index 7eb44c5354..54972d5e0a 100644 --- a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs +++ b/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(); diff --git a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs b/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs index fbd98c1a04..b992453fb0 100644 --- a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs +++ b/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)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 diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs index 84ea717bab..bd11cf2e3c 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs @@ -306,7 +306,6 @@ namespace Avalonia.Controls.UnitTests.Primitives var renderInterface = new Mock(); AvaloniaLocator.CurrentMutable - .Bind().ToTransient() .Bind().ToFunc(() => globalStyles.Object) .Bind().ToConstant(new WindowingPlatformMock()) .Bind().ToTransient() diff --git a/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs b/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs index da0719893f..014bf458ea 100644 --- a/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs +++ b/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()); + var services = TestServices.StyledWindow; using (UnitTestApplication.Start(services)) { var impl = new Mock(); - var target = new TestTopLevel(impl.Object); + + var target = new TestTopLevel(impl.Object, Mock.Of()); // 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(); diff --git a/tests/Avalonia.Controls.UnitTests/WindowBaseTests.cs b/tests/Avalonia.Controls.UnitTests/WindowBaseTests.cs index 019f78a2b0..51a4d21392 100644 --- a/tests/Avalonia.Controls.UnitTests/WindowBaseTests.cs +++ b/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))); } diff --git a/tests/Avalonia.Layout.UnitTests/FullLayoutTests.cs b/tests/Avalonia.Layout.UnitTests/FullLayoutTests.cs index 053c77b911..b8b9b69b6c 100644 --- a/tests/Avalonia.Layout.UnitTests/FullLayoutTests.cs +++ b/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().ToConstant(new AssetLoader()) .Bind().ToConstant(new Mock().Object) .Bind().ToConstant(globalStyles.Object) - .Bind().ToConstant(new LayoutManager()) .Bind().ToConstant(new AppBuilder().RuntimePlatform) .Bind().ToConstant(renderInterface.Object) .Bind().ToConstant(new Styler()) diff --git a/tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs b/tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs index 4fce3fec0e..b0e8a3780e 100644 --- a/tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs +++ b/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(); - Size MeasureOverride(ILayoutable control, Size size) - { - order.Add(control); - return new Size(10, 10); - } + var order = new List(); + 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(); - Size MeasureOverride(ILayoutable control, Size size) - { - order.Add(control); - return new Size(10, 10); - } + var order = new List(); + 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().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().ToConstant(layoutManager); - return result; + root.LayoutManager.ExecuteLayoutPass(); + Assert.Equal(new Size(100, 100), panel.DesiredSize); } } } diff --git a/tests/Avalonia.Layout.UnitTests/LayoutableTests.cs b/tests/Avalonia.Layout.UnitTests/LayoutableTests.cs index 410b2ffb2e..31310f7d42 100644 --- a/tests/Avalonia.Layout.UnitTests/LayoutableTests.cs +++ b/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(); - - 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(); - - 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(); - - 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().ToConstant(layoutManager); - return result; + Assert.False(root.IsMeasureValid); + Assert.False(control.IsMeasureValid); + target.Verify(x => x.InvalidateMeasure(root), Times.Once()); } private class TestLayoutable : Layoutable diff --git a/tests/Avalonia.LeakTests/ControlTests.cs b/tests/Avalonia.LeakTests/ControlTests.cs index 6993e32515..4dcd98cb93 100644 --- a/tests/Avalonia.LeakTests/ControlTests.cs +++ b/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(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(window.Find("foo")); Assert.IsType(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(window.Presenter.Child); Assert.IsType(((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(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(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; diff --git a/tests/Avalonia.UnitTests/TestRoot.cs b/tests/Avalonia.UnitTests/TestRoot.cs index dc137e3533..884df33fc0 100644 --- a/tests/Avalonia.UnitTests/TestRoot.cs +++ b/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(); + public double RenderScaling => 1; public IRenderer Renderer { get; set; } diff --git a/tests/Avalonia.UnitTests/TestServices.cs b/tests/Avalonia.UnitTests/TestServices.cs index 8414fe7cd5..d990defe3d 100644 --- a/tests/Avalonia.UnitTests/TestServices.cs +++ b/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(), @@ -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 keyboardDevice = null, IKeyboardNavigationHandler keyboardNavigation = null, - ILayoutManager layoutManager = null, Func 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 KeyboardDevice { get; } public IKeyboardNavigationHandler KeyboardNavigation { get; } - public ILayoutManager LayoutManager { get; } public Func MouseDevice { get; } public IRuntimePlatform Platform { get; } public IPlatformRenderInterface RenderInterface { get; } @@ -119,7 +112,6 @@ namespace Avalonia.UnitTests IInputManager inputManager = null, Func keyboardDevice = null, IKeyboardNavigationHandler keyboardNavigation = null, - ILayoutManager layoutManager = null, Func 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, diff --git a/tests/Avalonia.UnitTests/TestTemplatedRoot.cs b/tests/Avalonia.UnitTests/TestTemplatedRoot.cs index 91e797fa87..2d896435a3 100644 --- a/tests/Avalonia.UnitTests/TestTemplatedRoot.cs +++ b/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(); + public double RenderScaling => 1; public IRenderTarget RenderTarget => null; diff --git a/tests/Avalonia.UnitTests/UnitTestApplication.cs b/tests/Avalonia.UnitTests/UnitTestApplication.cs index dfbcdbb9ae..359198048b 100644 --- a/tests/Avalonia.UnitTests/UnitTestApplication.cs +++ b/tests/Avalonia.UnitTests/UnitTestApplication.cs @@ -50,7 +50,6 @@ namespace Avalonia.UnitTests .Bind().ToConstant(Services.InputManager) .Bind().ToConstant(Services.KeyboardDevice?.Invoke()) .Bind().ToConstant(Services.KeyboardNavigation) - .Bind().ToConstant(Services.LayoutManager) .Bind().ToConstant(Services.MouseDevice?.Invoke()) .Bind().ToConstant(Services.Platform) .Bind().ToConstant(Services.RenderInterface) diff --git a/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs b/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs index df4584518e..3d084b81e1 100644 --- a/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs +++ b/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(); + 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(); + 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(); + 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()); 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()); Image img; @@ -830,12 +830,5 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph } } } - - private IDisposable TestApplication() - { - return UnitTestApplication.Start( - TestServices.MockPlatformRenderInterface.With( - layoutManager: new LayoutManager())); - } } } diff --git a/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs b/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs index ac00b8ccfc..1bece3ae22 100644 --- a/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs +++ b/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(); + var layout = tree.LayoutManager; layout.ExecuteInitialLayoutPass(tree); var animation = new BehaviorSubject(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(); + var layout = tree.LayoutManager; layout.ExecuteInitialLayoutPass(tree); var animation = new BehaviorSubject(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(); + var layout = tree.LayoutManager; layout.ExecuteInitialLayoutPass(tree); var animation = new BehaviorSubject(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(); + var layout = tree.LayoutManager; layout.ExecuteInitialLayoutPass(tree); var animation = new BehaviorSubject(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(); + var layout = tree.LayoutManager; layout.ExecuteInitialLayoutPass(tree); var animation = new BehaviorSubject(0.5);