|
|
|
@ -1,11 +1,10 @@ |
|
|
|
// Copyright (c) The Avalonia Project. All rights reserved.
|
|
|
|
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|
|
|
|
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Linq; |
|
|
|
using Avalonia.Controls; |
|
|
|
using Avalonia.UnitTests; |
|
|
|
using System; |
|
|
|
using Xunit; |
|
|
|
using System.Collections.Generic; |
|
|
|
|
|
|
|
namespace Avalonia.Layout.UnitTests |
|
|
|
{ |
|
|
|
@ -74,7 +73,6 @@ namespace Avalonia.Layout.UnitTests |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
var order = new List<ILayoutable>(); |
|
|
|
Size MeasureOverride(ILayoutable control, Size size) |
|
|
|
{ |
|
|
|
@ -110,7 +108,6 @@ namespace Avalonia.Layout.UnitTests |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
var order = new List<ILayoutable>(); |
|
|
|
Size MeasureOverride(ILayoutable control, Size size) |
|
|
|
{ |
|
|
|
@ -196,9 +193,9 @@ namespace Avalonia.Layout.UnitTests |
|
|
|
Width = 100, |
|
|
|
Height = 100, |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
var arrangeSize = default(Size); |
|
|
|
|
|
|
|
|
|
|
|
root.DoArrangeOverride = (_, s) => |
|
|
|
{ |
|
|
|
arrangeSize = s; |
|
|
|
@ -207,7 +204,7 @@ namespace Avalonia.Layout.UnitTests |
|
|
|
|
|
|
|
root.LayoutManager.ExecuteInitialLayoutPass(root); |
|
|
|
Assert.Equal(new Size(100, 100), arrangeSize); |
|
|
|
|
|
|
|
|
|
|
|
root.Width = 120; |
|
|
|
|
|
|
|
root.LayoutManager.ExecuteLayoutPass(); |
|
|
|
@ -238,7 +235,111 @@ namespace Avalonia.Layout.UnitTests |
|
|
|
border.Height = 100; |
|
|
|
|
|
|
|
root.LayoutManager.ExecuteLayoutPass(); |
|
|
|
Assert.Equal(new Size(100, 100), panel.DesiredSize); |
|
|
|
Assert.Equal(new Size(100, 100), panel.DesiredSize); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public void LayoutManager_Should_Prevent_Infinity_Loop_On_Measure() |
|
|
|
{ |
|
|
|
var control = new LayoutTestControl(); |
|
|
|
var root = new LayoutTestRoot { Child = control }; |
|
|
|
|
|
|
|
root.LayoutManager.ExecuteInitialLayoutPass(root); |
|
|
|
control.Measured = false; |
|
|
|
|
|
|
|
int cnt = 0; |
|
|
|
int maxcnt = 100; |
|
|
|
control.DoMeasureOverride = (l, s) => |
|
|
|
{ |
|
|
|
//emulate a problem in the logic of a control that triggers
|
|
|
|
//invalidate measure during measure
|
|
|
|
//it can lead to infinity loop in layoutmanager
|
|
|
|
if (++cnt < maxcnt) |
|
|
|
{ |
|
|
|
control.InvalidateMeasure(); |
|
|
|
} |
|
|
|
|
|
|
|
return new Size(100, 100); |
|
|
|
}; |
|
|
|
|
|
|
|
control.InvalidateMeasure(); |
|
|
|
|
|
|
|
root.LayoutManager.ExecuteLayoutPass(); |
|
|
|
|
|
|
|
Assert.True(cnt < 100); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public void LayoutManager_Should_Prevent_Infinity_Loop_On_Arrange() |
|
|
|
{ |
|
|
|
var control = new LayoutTestControl(); |
|
|
|
var root = new LayoutTestRoot { Child = control }; |
|
|
|
|
|
|
|
root.LayoutManager.ExecuteInitialLayoutPass(root); |
|
|
|
control.Arranged = false; |
|
|
|
|
|
|
|
int cnt = 0; |
|
|
|
int maxcnt = 100; |
|
|
|
control.DoArrangeOverride = (l, s) => |
|
|
|
{ |
|
|
|
//emulate a problem in the logic of a control that triggers
|
|
|
|
//invalidate measure during arrange
|
|
|
|
//it can lead to infinity loop in layoutmanager
|
|
|
|
if (++cnt < maxcnt) |
|
|
|
{ |
|
|
|
control.InvalidateArrange(); |
|
|
|
} |
|
|
|
|
|
|
|
return new Size(100, 100); |
|
|
|
}; |
|
|
|
|
|
|
|
control.InvalidateArrange(); |
|
|
|
|
|
|
|
root.LayoutManager.ExecuteLayoutPass(); |
|
|
|
|
|
|
|
Assert.True(cnt < 100); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public void LayoutManager_Should_Properly_Arrange_Visuals_Even_There_Are_Issues_With_Previous_Arranged() |
|
|
|
{ |
|
|
|
var nonArrageableTargets = Enumerable.Range(1, 10).Select(_ => new LayoutTestControl()).ToArray(); |
|
|
|
var targets = Enumerable.Range(1, 10).Select(_ => new LayoutTestControl()).ToArray(); |
|
|
|
|
|
|
|
StackPanel panel; |
|
|
|
|
|
|
|
var root = new LayoutTestRoot |
|
|
|
{ |
|
|
|
Child = panel = new StackPanel() |
|
|
|
}; |
|
|
|
|
|
|
|
panel.Children.AddRange(nonArrageableTargets); |
|
|
|
panel.Children.AddRange(targets); |
|
|
|
|
|
|
|
root.LayoutManager.ExecuteInitialLayoutPass(root); |
|
|
|
|
|
|
|
foreach (var c in panel.Children.OfType<LayoutTestControl>()) |
|
|
|
{ |
|
|
|
c.Measured = c.Arranged = false; |
|
|
|
c.InvalidateMeasure(); |
|
|
|
} |
|
|
|
|
|
|
|
foreach (var c in nonArrageableTargets) |
|
|
|
{ |
|
|
|
c.DoArrangeOverride = (l, s) => |
|
|
|
{ |
|
|
|
//emulate a problem in the logic of a control that triggers
|
|
|
|
//invalidate measure during arrange
|
|
|
|
c.InvalidateMeasure(); |
|
|
|
return new Size(100, 100); |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
root.LayoutManager.ExecuteLayoutPass(); |
|
|
|
|
|
|
|
//altough nonArrageableTargets has rubbish logic and can't be measured/arranged properly
|
|
|
|
//layoutmanager should process properly other visuals
|
|
|
|
Assert.All(targets, c => Assert.True(c.Arranged)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|