19 changed files with 565 additions and 179 deletions
@ -1,25 +0,0 @@ |
|||
// 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; |
|||
using Avalonia.Media; |
|||
|
|||
namespace Avalonia.Rendering.SceneGraph |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a node in the low-level scene graph.
|
|||
/// </summary>
|
|||
public interface ISceneNode |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the bounds of the visible content in the node.
|
|||
/// </summary>
|
|||
Rect Bounds { get; } |
|||
|
|||
/// <summary>
|
|||
/// Renders the node to a drawing context.
|
|||
/// </summary>
|
|||
/// <param name="context">The drawing context.</param>
|
|||
void Render(IDrawingContextImpl context); |
|||
} |
|||
} |
|||
@ -0,0 +1,179 @@ |
|||
using System; |
|||
using System.Linq; |
|||
using Avalonia.Media; |
|||
using Avalonia.Rendering; |
|||
using Avalonia.Rendering.SceneGraph; |
|||
using Avalonia.VisualTree; |
|||
using Moq; |
|||
using Xunit; |
|||
|
|||
namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph |
|||
{ |
|||
public class DeferredDrawingContextImplTests |
|||
{ |
|||
[Fact] |
|||
public void Should_Add_VisualNode() |
|||
{ |
|||
var parent = new VisualNode(Mock.Of<IVisual>(), null); |
|||
var child = new VisualNode(Mock.Of<IVisual>(), null); |
|||
var target = new DeferredDrawingContextImpl(); |
|||
|
|||
target.BeginUpdate(parent); |
|||
target.BeginUpdate(child); |
|||
|
|||
Assert.Equal(1, parent.Children.Count); |
|||
Assert.Same(child, parent.Children[0]); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Not_Replace_Identical_VisualNode() |
|||
{ |
|||
var parent = new VisualNode(Mock.Of<IVisual>(), null); |
|||
var child = new VisualNode(Mock.Of<IVisual>(), null); |
|||
|
|||
parent.AddChild(child); |
|||
|
|||
var target = new DeferredDrawingContextImpl(); |
|||
|
|||
target.BeginUpdate(parent); |
|||
target.BeginUpdate(child); |
|||
|
|||
Assert.Equal(1, parent.Children.Count); |
|||
Assert.Same(child, parent.Children[0]); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Replace_Different_VisualNode() |
|||
{ |
|||
var parent = new VisualNode(Mock.Of<IVisual>(), null); |
|||
var child1 = new VisualNode(Mock.Of<IVisual>(), null); |
|||
var child2 = new VisualNode(Mock.Of<IVisual>(), null); |
|||
|
|||
parent.AddChild(child1); |
|||
|
|||
var target = new DeferredDrawingContextImpl(); |
|||
|
|||
target.BeginUpdate(parent); |
|||
target.BeginUpdate(child2); |
|||
|
|||
Assert.Equal(1, parent.Children.Count); |
|||
Assert.Same(child2, parent.Children[0]); |
|||
} |
|||
|
|||
[Fact] |
|||
public void TrimChildren_Should_Trim_Children() |
|||
{ |
|||
var node = new VisualNode(Mock.Of<IVisual>(), null); |
|||
|
|||
node.AddChild(new VisualNode(Mock.Of<IVisual>(), node)); |
|||
node.AddChild(new VisualNode(Mock.Of<IVisual>(), node)); |
|||
node.AddChild(new VisualNode(Mock.Of<IVisual>(), node)); |
|||
node.AddChild(new VisualNode(Mock.Of<IVisual>(), node)); |
|||
|
|||
var target = new DeferredDrawingContextImpl(); |
|||
var child1 = new VisualNode(Mock.Of<IVisual>(), null); |
|||
var child2 = new VisualNode(Mock.Of<IVisual>(), null); |
|||
|
|||
target.BeginUpdate(node); |
|||
using (target.BeginUpdate(child1)) { } |
|||
using (target.BeginUpdate(child2)) { } |
|||
target.TrimChildren(); |
|||
|
|||
Assert.Equal(2, node.Children.Count); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Add_DrawOperations() |
|||
{ |
|||
var node = new VisualNode(Mock.Of<IVisual>(), null); |
|||
var target = new DeferredDrawingContextImpl(); |
|||
|
|||
using (target.BeginUpdate(node)) |
|||
{ |
|||
target.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100)); |
|||
target.DrawRectangle(new Pen(Brushes.Green, 1), new Rect(0, 0, 100, 100)); |
|||
} |
|||
|
|||
Assert.Equal(2, node.DrawOperations.Count); |
|||
Assert.IsType<RectangleNode>(node.DrawOperations[0]); |
|||
Assert.IsType<RectangleNode>(node.DrawOperations[1]); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Not_Replace_Identical_DrawOperation() |
|||
{ |
|||
var node = new VisualNode(Mock.Of<IVisual>(), null); |
|||
var operation = new RectangleNode(Matrix.Identity, Brushes.Red, null, new Rect(0, 0, 100, 100), 0); |
|||
var target = new DeferredDrawingContextImpl(); |
|||
|
|||
node.AddDrawOperation(operation); |
|||
|
|||
using (target.BeginUpdate(node)) |
|||
{ |
|||
target.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100)); |
|||
} |
|||
|
|||
Assert.Equal(1, node.DrawOperations.Count); |
|||
Assert.Same(operation, node.DrawOperations.Single()); |
|||
|
|||
Assert.IsType<RectangleNode>(node.DrawOperations[0]); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Replace_Different_DrawOperation() |
|||
{ |
|||
var node = new VisualNode(Mock.Of<IVisual>(), null); |
|||
var operation = new RectangleNode(Matrix.Identity, Brushes.Red, null, new Rect(0, 0, 100, 100), 0); |
|||
var target = new DeferredDrawingContextImpl(); |
|||
|
|||
node.AddDrawOperation(operation); |
|||
|
|||
using (target.BeginUpdate(node)) |
|||
{ |
|||
target.FillRectangle(Brushes.Green, new Rect(0, 0, 100, 100)); |
|||
} |
|||
|
|||
Assert.Equal(1, node.DrawOperations.Count); |
|||
Assert.NotSame(operation, node.DrawOperations.Single()); |
|||
|
|||
Assert.IsType<RectangleNode>(node.DrawOperations[0]); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Update_DirtyRects() |
|||
{ |
|||
var node = new VisualNode(Mock.Of<IVisual>(), null); |
|||
var operation = new RectangleNode(Matrix.Identity, Brushes.Red, null, new Rect(0, 0, 100, 100), 0); |
|||
var dirtyRects = new DirtyRects(); |
|||
var target = new DeferredDrawingContextImpl(dirtyRects); |
|||
|
|||
using (target.BeginUpdate(node)) |
|||
{ |
|||
target.FillRectangle(Brushes.Green, new Rect(0, 0, 100, 100)); |
|||
} |
|||
|
|||
Assert.Equal(new Rect(0, 0, 100, 100), dirtyRects.Single()); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Trim_DrawOperations() |
|||
{ |
|||
var node = new VisualNode(Mock.Of<IVisual>(), null); |
|||
|
|||
node.AddDrawOperation(new RectangleNode(Matrix.Identity, Brushes.Red, null, new Rect(0, 0, 10, 100), 0)); |
|||
node.AddDrawOperation(new RectangleNode(Matrix.Identity, Brushes.Red, null, new Rect(0, 0, 20, 100), 0)); |
|||
node.AddDrawOperation(new RectangleNode(Matrix.Identity, Brushes.Red, null, new Rect(0, 0, 30, 100), 0)); |
|||
node.AddDrawOperation(new RectangleNode(Matrix.Identity, Brushes.Red, null, new Rect(0, 0, 40, 100), 0)); |
|||
|
|||
var target = new DeferredDrawingContextImpl(); |
|||
|
|||
using (target.BeginUpdate(node)) |
|||
{ |
|||
target.FillRectangle(Brushes.Green, new Rect(0, 0, 10, 100)); |
|||
target.FillRectangle(Brushes.Blue, new Rect(0, 0, 20, 100)); |
|||
} |
|||
|
|||
Assert.Equal(2, node.DrawOperations.Count); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,80 @@ |
|||
using System; |
|||
using Avalonia.Rendering.SceneGraph; |
|||
using Avalonia.VisualTree; |
|||
using Moq; |
|||
using Xunit; |
|||
|
|||
namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph |
|||
{ |
|||
public class VisualNodeTests |
|||
{ |
|||
[Fact] |
|||
public void Empty_Children_Collections_Should_Be_Shared() |
|||
{ |
|||
var node1 = new VisualNode(Mock.Of<IVisual>(), null); |
|||
var node2 = new VisualNode(Mock.Of<IVisual>(), null); |
|||
|
|||
Assert.Same(node1.Children, node2.Children); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Adding_Child_Should_Create_Collection() |
|||
{ |
|||
var node = new VisualNode(Mock.Of<IVisual>(), null); |
|||
var collection = node.Children; |
|||
|
|||
node.AddChild(Mock.Of<IVisualNode>()); |
|||
|
|||
Assert.NotSame(collection, node.Children); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Empty_DrawOperations_Collections_Should_Be_Shared() |
|||
{ |
|||
var node1 = new VisualNode(Mock.Of<IVisual>(), null); |
|||
var node2 = new VisualNode(Mock.Of<IVisual>(), null); |
|||
|
|||
Assert.Same(node1.DrawOperations, node2.DrawOperations); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Adding_DrawOperation_Should_Create_Collection() |
|||
{ |
|||
var node = new VisualNode(Mock.Of<IVisual>(), null); |
|||
var collection = node.DrawOperations; |
|||
|
|||
node.AddDrawOperation(Mock.Of<IDrawOperation>()); |
|||
|
|||
Assert.NotSame(collection, node.DrawOperations); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Cloned_Nodes_Should_Share_DrawOperations_Collection() |
|||
{ |
|||
var node1 = new VisualNode(Mock.Of<IVisual>(), null); |
|||
node1.AddDrawOperation(Mock.Of<IDrawOperation>()); |
|||
|
|||
var node2 = node1.Clone(null); |
|||
|
|||
Assert.Same(node1.DrawOperations, node2.DrawOperations); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Adding_DrawOperation_To_Cloned_Node_Should_Create_New_Collection() |
|||
{ |
|||
var node1 = new VisualNode(Mock.Of<IVisual>(), null); |
|||
var operation1 = Mock.Of<IDrawOperation>(); |
|||
node1.AddDrawOperation(operation1); |
|||
|
|||
var node2 = node1.Clone(null); |
|||
var operation2 = Mock.Of<IDrawOperation>(); |
|||
node2.ReplaceDrawOperation(0, operation2); |
|||
|
|||
Assert.NotSame(node1.DrawOperations, node2.DrawOperations); |
|||
Assert.Equal(1, node1.DrawOperations.Count); |
|||
Assert.Equal(1, node2.DrawOperations.Count); |
|||
Assert.Same(operation1, node1.DrawOperations[0]); |
|||
Assert.Same(operation2, node2.DrawOperations[0]); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue