Browse Source

Merge pull request #6271 from MarchingCube/fix-zindex-ordering

Implement indexed sort for visual children.
release/0.10.7
Nikita Tsukanov 5 years ago
committed by Dan Walmsley
parent
commit
d7fe0022d7
  1. 19
      src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs
  2. 28
      tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs

19
src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs

@ -258,14 +258,25 @@ namespace Avalonia.Rendering.SceneGraph
} }
else if (visualChildren.Count > 1) else if (visualChildren.Count > 1)
{ {
var sortedChildren = new IVisual[visualChildren.Count]; var count = visualChildren.Count;
visualChildren.CopyTo(sortedChildren, 0); var sortedChildren = new (IVisual visual, int index)[count];
Array.Sort(sortedChildren, ZIndexComparer.ComparisonInstance); for (var i = 0; i < count; i++)
{
sortedChildren[i] = (visualChildren[i], i);
}
// Regular Array.Sort is unstable, we need to provide indices as well to avoid reshuffling elements.
Array.Sort(sortedChildren, (lhs, rhs) =>
{
var result = ZIndexComparer.Instance.Compare(lhs.visual, rhs.visual);
return result == 0 ? lhs.index.CompareTo(rhs.index) : result;
});
foreach (var child in sortedChildren) foreach (var child in sortedChildren)
{ {
var childNode = GetOrCreateChildNode(scene, child, node); var childNode = GetOrCreateChildNode(scene, child.Item1, node);
Update(context, scene, (VisualNode)childNode, clip, forceRecurse); Update(context, scene, (VisualNode)childNode, clip, forceRecurse);
} }
} }

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

@ -245,6 +245,34 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
} }
} }
[Fact]
public void Should_Respect_Uniform_ZIndex()
{
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
{
Panel panel;
var tree = new TestRoot
{
Child = panel = new Panel()
};
for (var i = 0; i < 128; i++)
{
panel.Children.Add(new Border());
}
var result = new Scene(tree);
var sceneBuilder = new SceneBuilder();
sceneBuilder.UpdateAll(result);
var panelNode = result.FindNode(tree.Child);
var expected = panel.Children.ToArray();
var actual = panelNode.Children.OfType<IVisualNode>().Select(x => x.Visual).ToArray();
Assert.Equal(expected, actual);
}
}
[Fact] [Fact]
public void ClipBounds_Should_Be_In_Global_Coordinates() public void ClipBounds_Should_Be_In_Global_Coordinates()
{ {

Loading…
Cancel
Save