diff --git a/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs b/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
index a30f02fc42..a93f730c0d 100644
--- a/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
+++ b/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
@@ -14,6 +14,10 @@ using System.Threading;
namespace Avalonia.Rendering
{
+ ///
+ /// A renderer which renders the state of the visual tree to an intermediate scene graph
+ /// representation which is then rendered on a rendering thread.
+ ///
public class DeferredRenderer : RendererBase, IRenderer, IVisualBrushRenderer
{
private readonly IDispatcher _dispatcher;
@@ -33,6 +37,14 @@ namespace Avalonia.Rendering
private DisplayDirtyRects _dirtyRectsDisplay = new DisplayDirtyRects();
private IDrawOperation _currentDraw;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The control to render.
+ /// The render loop.
+ /// The scene builder to use. Optional.
+ /// The layer factory to use. Optional.
+ /// The dispatcher to use. Optional.
public DeferredRenderer(
IRenderRoot root,
IRenderLoop renderLoop,
@@ -56,6 +68,16 @@ namespace Avalonia.Rendering
}
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The control to render.
+ /// The render target.
+ /// The scene builder to use. Optional.
+ /// The layer factory to use. Optional.
+ ///
+ /// This constructor is intended to be used for unit testing.
+ ///
public DeferredRenderer(
IVisual root,
IRenderTarget renderTarget,
@@ -73,15 +95,26 @@ namespace Avalonia.Rendering
_layers = new RenderLayers(_layerFactory);
}
+ ///
public bool DrawFps { get; set; }
+
+ ///
public bool DrawDirtyRects { get; set; }
+
+ ///
+ /// Gets or sets a path to which rendered frame should be rendered for debugging.
+ ///
public string DebugFramesPath { get; set; }
+ ///
public void AddDirty(IVisual visual)
{
_dirty?.Add(visual);
}
+ ///
+ /// Disposes of the renderer and detaches from the render loop.
+ ///
public void Dispose()
{
if (_renderLoop != null)
@@ -90,6 +123,7 @@ namespace Avalonia.Rendering
}
}
+ ///
public IEnumerable HitTest(Point p, Func filter)
{
if (_renderLoop == null && (_dirty == null || _dirty.Count > 0))
@@ -101,19 +135,23 @@ namespace Avalonia.Rendering
return _scene.HitTest(p, filter);
}
+ ///
public void Paint(Rect rect)
{
}
+ ///
public void Resized(Size size)
{
}
+ ///
Size IVisualBrushRenderer.GetRenderTargetSize(IVisualBrush brush)
{
return (_currentDraw as BrushDrawOperation)?.ChildScenes?[brush.Visual]?.Size ?? Size.Empty;
}
+ ///
void IVisualBrushRenderer.RenderVisualBrush(IDrawingContextImpl context, IVisualBrush brush)
{
var childScene = (_currentDraw as BrushDrawOperation)?.ChildScenes?[brush.Visual];
diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/BrushDrawOperation.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/BrushDrawOperation.cs
index 7c65cf5445..3b858f7b38 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/BrushDrawOperation.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/BrushDrawOperation.cs
@@ -1,4 +1,7 @@
-using System;
+// 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 System.Collections.Generic;
using Avalonia.Media;
using Avalonia.Platform;
@@ -6,19 +9,40 @@ using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph
{
+ ///
+ /// Base class for draw operations that can use a brush.
+ ///
internal abstract class BrushDrawOperation : IDrawOperation
{
+ ///
public abstract Rect Bounds { get; }
+
+ ///
public abstract bool HitTest(Point p);
+
+ ///
+ /// Gets a collection of child scenes that are needed to draw visual brushes.
+ ///
public abstract IDictionary ChildScenes { get; }
+ ///
public abstract void Render(IDrawingContextImpl context);
+ ///
+ /// Converts a possibly mutable brush to an immutable brush.
+ ///
+ /// The brush.
+ /// An immutable brush
protected IBrush ToImmutable(IBrush brush)
{
return (brush as IMutableBrush)?.ToImmutable() ?? brush;
}
+ ///
+ /// Converts pen with a possibly mutable brush to a pen with an immutable brush.
+ ///
+ /// The pen.
+ /// A pen with an immutable brush
protected Pen ToImmutable(Pen pen)
{
var brush = pen?.Brush != null ? ToImmutable(pen.Brush) : null;
diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs
index 03a4929808..48bba84da7 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs
@@ -9,6 +9,9 @@ using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph
{
+ ///
+ /// A drawing context which builds a scene graph.
+ ///
internal class DeferredDrawingContextImpl : IDrawingContextImpl
{
private readonly ISceneBuilder _sceneBuilder;
@@ -16,16 +19,34 @@ namespace Avalonia.Rendering.SceneGraph
private int _childIndex;
private int _drawOperationindex;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A scene builder used for constructing child scenes for visual brushes.
+ ///
+ /// The scene layers.
public DeferredDrawingContextImpl(ISceneBuilder sceneBuilder, SceneLayers layers)
{
_sceneBuilder = sceneBuilder;
Layers = layers;
}
+ ///
public Matrix Transform { get; set; } = Matrix.Identity;
+ ///
+ /// Gets the layers in the scene being built.
+ ///
public SceneLayers Layers { get; }
+ ///
+ /// Informs the drawing context of the visual node that is about to be rendered.
+ ///
+ /// The visual node.
+ ///
+ /// An object which when disposed will commit the changes to visual node.
+ ///
public UpdateState BeginUpdate(VisualNode node)
{
Contract.Requires(node != null);
@@ -50,21 +71,33 @@ namespace Avalonia.Rendering.SceneGraph
return state;
}
+ ///
public void Clear(Color color)
{
// Cannot clear a deferred scene.
}
+ ///
public void Dispose()
{
// Nothing to do here as we allocate no unmanaged resources.
}
+ ///
+ /// Removes any remaining drawing operations from the visual node.
+ ///
+ ///
+ /// Drawing operations are updated in place, overwriting existing drawing operations if
+ /// they are different. Once drawing has completed for the current visual node, it is
+ /// possible that there are stale drawing operations at the end of the list. This method
+ /// trims these stale drawing operations.
+ ///
public void TrimChildren()
{
_node.TrimChildren(_childIndex);
}
+ ///
public void DrawGeometry(IBrush brush, Pen pen, IGeometryImpl geometry)
{
var next = NextDrawAs();
@@ -79,6 +112,7 @@ namespace Avalonia.Rendering.SceneGraph
}
}
+ ///
public void DrawImage(IBitmapImpl source, double opacity, Rect sourceRect, Rect destRect)
{
var next = NextDrawAs();
@@ -93,18 +127,20 @@ namespace Avalonia.Rendering.SceneGraph
}
}
+ ///
public void DrawImage(IBitmapImpl source, IBrush opacityMask, Rect opacityMaskRect, Rect sourceRect)
{
throw new NotImplementedException();
}
+ ///
public void DrawLine(Pen pen, Point p1, Point p2)
{
var next = NextDrawAs();
if (next == null || !next.Equals(Transform, pen, p1, p2))
{
- Add(new LineNode(Transform, pen, p1, p2));
+ Add(new LineNode(Transform, pen, p1, p2, CreateChildScene(pen.Brush)));
}
else
{
@@ -112,6 +148,7 @@ namespace Avalonia.Rendering.SceneGraph
}
}
+ ///
public void DrawRectangle(Pen pen, Rect rect, float cornerRadius = 0)
{
var next = NextDrawAs();
@@ -126,13 +163,14 @@ namespace Avalonia.Rendering.SceneGraph
}
}
+ ///
public void DrawText(IBrush foreground, Point origin, IFormattedTextImpl text)
{
var next = NextDrawAs();
if (next == null || !next.Equals(Transform, foreground, origin, text))
{
- Add(new TextNode(Transform, foreground, origin, text));
+ Add(new TextNode(Transform, foreground, origin, text, CreateChildScene(foreground)));
}
else
{
@@ -140,6 +178,7 @@ namespace Avalonia.Rendering.SceneGraph
}
}
+ ///
public void FillRectangle(IBrush brush, Rect rect, float cornerRadius = 0)
{
var next = NextDrawAs();
@@ -154,41 +193,49 @@ namespace Avalonia.Rendering.SceneGraph
}
}
+ ///
public void PopClip()
{
// TODO: Implement
}
+ ///
public void PopGeometryClip()
{
// TODO: Implement
}
+ ///
public void PopOpacity()
{
// TODO: Implement
}
+ ///
public void PopOpacityMask()
{
// TODO: Implement
}
+ ///
public void PushClip(Rect clip)
{
// TODO: Implement
}
+ ///
public void PushGeometryClip(IGeometryImpl clip)
{
// TODO: Implement
}
+ ///
public void PushOpacity(double opacity)
{
// TODO: Implement
}
+ ///
public void PushOpacityMask(IBrush mask, Rect bounds)
{
// TODO: Implement
diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/GeometryNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/GeometryNode.cs
index 7cbc0ed28e..55c6a2b9b3 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/GeometryNode.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/GeometryNode.cs
@@ -9,8 +9,19 @@ using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph
{
+ ///
+ /// A node in the scene graph which represents a geometry draw.
+ ///
internal class GeometryNode : BrushDrawOperation
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The transform.
+ /// The fill brush.
+ /// The stroke pen.
+ /// The geometry.
+ /// Child scenes for drawing visual brushes.
public GeometryNode(
Matrix transform,
IBrush brush,
@@ -26,13 +37,44 @@ namespace Avalonia.Rendering.SceneGraph
ChildScenes = childScenes;
}
+ ///
public override Rect Bounds { get; }
+
+ ///
+ /// Gets the transform with which the node will be drawn.
+ ///
public Matrix Transform { get; }
+
+ ///
+ /// Gets the fill brush.
+ ///
public IBrush Brush { get; }
+
+ ///
+ /// Gets the stroke pen.
+ ///
public Pen Pen { get; }
+
+ ///
+ /// Gets the geometry to draw.
+ ///
public IGeometryImpl Geometry { get; }
+
+ ///
public override IDictionary ChildScenes { get; }
+ ///
+ /// Determines if this draw operation equals another.
+ ///
+ /// The transform of the other draw operation.
+ /// The fill of the other draw operation.
+ /// The stroke of the other draw operation.
+ /// The geometry of the other draw operation.
+ /// True if the draw operations are the same, otherwise false.
+ ///
+ /// The properties of the other draw operation are passed in as arguments to prevent
+ /// allocation of a not-yet-constructed draw operation object.
+ ///
public bool Equals(Matrix transform, IBrush brush, Pen pen, IGeometryImpl geometry)
{
return transform == Transform &&
@@ -41,12 +83,14 @@ namespace Avalonia.Rendering.SceneGraph
Equals(geometry, Geometry);
}
+ ///
public override void Render(IDrawingContextImpl context)
{
context.Transform = Transform;
context.DrawGeometry(Brush, Pen, Geometry);
}
+ ///
public override bool HitTest(Point p)
{
p *= Transform.Invert();
diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/ISceneBuilder.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/ISceneBuilder.cs
index a62e9ade93..dd993fbb8c 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/ISceneBuilder.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/ISceneBuilder.cs
@@ -2,9 +2,23 @@
namespace Avalonia.Rendering.SceneGraph
{
+ ///
+ /// Builds a scene graph from a visual tree.
+ ///
public interface ISceneBuilder
{
- bool Update(Scene scene, IVisual visual);
+ ///
+ /// Builds the initial scene graph for a visual tree.
+ ///
+ /// The scene to build.
void UpdateAll(Scene scene);
+
+ ///
+ /// Updates the visual (and potentially its children) in a scene.
+ ///
+ /// The scene.
+ /// The visual to update.
+ /// True if changes were made, otherwise false.
+ bool Update(Scene scene, IVisual visual);
}
}
\ No newline at end of file
diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/ImageNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/ImageNode.cs
index ad9f7ff0a3..b34ce42dc2 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/ImageNode.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/ImageNode.cs
@@ -2,14 +2,23 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
-using System.Collections.Generic;
-using Avalonia.Media;
using Avalonia.Platform;
namespace Avalonia.Rendering.SceneGraph
{
+ ///
+ /// A node in the scene graph which represents an image draw.
+ ///
internal class ImageNode : IDrawOperation
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The transform.
+ /// The image to draw.
+ /// The draw opacity.
+ /// The source rect.
+ /// The destination rect.
public ImageNode(Matrix transform, IBitmapImpl source, double opacity, Rect sourceRect, Rect destRect)
{
Bounds = destRect.TransformToAABB(transform);
@@ -20,14 +29,47 @@ namespace Avalonia.Rendering.SceneGraph
DestRect = destRect;
}
+ ///
public Rect Bounds { get; }
+
+ ///
+ /// Gets the transform with which the node will be drawn.
+ ///
public Matrix Transform { get; }
+
+ ///
+ /// Gets the image to draw.
+ ///
public IBitmapImpl Source { get; }
+
+ ///
+ /// Gets the draw opacity.
+ ///
public double Opacity { get; }
+
+ ///
+ /// Gets the source rect.
+ ///
public Rect SourceRect { get; }
+
+ ///
+ /// Gets the destination rect.
+ ///
public Rect DestRect { get; }
- public IDictionary ChildScenes => null;
+ ///
+ /// Determines if this draw operation equals another.
+ ///
+ /// The transform of the other draw operation.
+ /// The image of the other draw operation.
+ /// The opacity of the other draw operation.
+ /// The source rect of the other draw operation.
+ /// The dest rect of the other draw operation.
+ /// True if the draw operations are the same, otherwise false.
+ ///
+ /// The properties of the other draw operation are passed in as arguments to prevent
+ /// allocation of a not-yet-constructed draw operation object.
+ ///
public bool Equals(Matrix transform, IBitmapImpl source, double opacity, Rect sourceRect, Rect destRect)
{
return transform == Transform &&
@@ -37,12 +79,14 @@ namespace Avalonia.Rendering.SceneGraph
destRect == DestRect;
}
+ ///
public void Render(IDrawingContextImpl context)
{
context.Transform = Transform;
context.DrawImage(Source, Opacity, SourceRect, DestRect);
}
+ ///
public bool HitTest(Point p) => Bounds.Contains(p);
}
}
diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/LineNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/LineNode.cs
index 05bb4872db..46da8c7900 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/LineNode.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/LineNode.cs
@@ -9,24 +9,72 @@ using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph
{
+ ///
+ /// A node in the scene graph which represents a line draw.
+ ///
internal class LineNode : BrushDrawOperation
{
- public LineNode(Matrix transform, Pen pen, Point p1, Point p2)
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The transform.
+ /// The stroke pen.
+ /// The start point of the line.
+ /// The end point of the line.
+ /// Child scenes for drawing visual brushes.
+ public LineNode(
+ Matrix transform,
+ Pen pen,
+ Point p1,
+ Point p2,
+ IDictionary childScenes = null)
{
Bounds = new Rect(P1, P2);
Transform = transform;
Pen = ToImmutable(pen);
P1 = p1;
P2 = p2;
+ ChildScenes = childScenes;
}
+ ///
public override Rect Bounds { get; }
+
+ ///
+ /// Gets the transform with which the node will be drawn.
+ ///
public Matrix Transform { get; }
+
+ ///
+ /// Gets the stroke pen.
+ ///
public Pen Pen { get; }
+
+ ///
+ /// Gets the start point of the line.
+ ///
public Point P1 { get; }
+
+ ///
+ /// Gets the end point of the line.
+ ///
public Point P2 { get; }
- public override IDictionary ChildScenes => null;
+ ///
+ public override IDictionary ChildScenes { get; }
+
+ ///
+ /// Determines if this draw operation equals another.
+ ///
+ /// The transform of the other draw operation.
+ /// The stroke of the other draw operation.
+ /// The start point of the other draw operation.
+ /// The end point of the other draw operation.
+ /// True if the draw operations are the same, otherwise false.
+ ///
+ /// The properties of the other draw operation are passed in as arguments to prevent
+ /// allocation of a not-yet-constructed draw operation object.
+ ///
public bool Equals(Matrix transform, Pen pen, Point p1, Point p2)
{
return transform == Transform && pen == Pen && p1 == P1 && p2 == P2;
diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs
index ab931ca623..33cccf5732 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs
@@ -9,8 +9,20 @@ using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph
{
+ ///
+ /// A node in the scene graph which represents a rectangle draw.
+ ///
internal class RectangleNode : BrushDrawOperation
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The transform.
+ /// The fill brush.
+ /// The stroke pen.
+ /// The rectanle to draw.
+ /// The rectangle corner radius.
+ /// Child scenes for drawing visual brushes.
public RectangleNode(
Matrix transform,
IBrush brush,
@@ -28,14 +40,50 @@ namespace Avalonia.Rendering.SceneGraph
ChildScenes = childScenes;
}
+ ///
public override Rect Bounds { get; }
+
+ ///
+ /// Gets the transform with which the node will be drawn.
+ ///
public Matrix Transform { get; }
+
+ ///
+ /// Gets the fill brush.
+ ///
public IBrush Brush { get; }
+
+ ///
+ /// Gets the stroke pen.
+ ///
public Pen Pen { get; }
+
+ ///
+ /// Gets the rectangle to draw.
+ ///
public Rect Rect { get; }
+
+ ///
+ /// Gets the rectangle corner radius.
+ ///
public float CornerRadius { get; }
+
+ ///
public override IDictionary ChildScenes { get; }
+ ///
+ /// Determines if this draw operation equals another.
+ ///
+ /// The transform of the other draw operation.
+ /// The fill of the other draw operation.
+ /// The stroke of the other draw operation.
+ /// The rectangle of the other draw operation.
+ /// The rectangle corner radius of the other draw operation.
+ /// True if the draw operations are the same, otherwise false.
+ ///
+ /// The properties of the other draw operation are passed in as arguments to prevent
+ /// allocation of a not-yet-constructed draw operation object.
+ ///
public bool Equals(Matrix transform, IBrush brush, Pen pen, Rect rect, float cornerRadius)
{
return transform == Transform &&
@@ -45,6 +93,7 @@ namespace Avalonia.Rendering.SceneGraph
cornerRadius == CornerRadius;
}
+ ///
public override void Render(IDrawingContextImpl context)
{
context.Transform = Transform;
@@ -60,6 +109,7 @@ namespace Avalonia.Rendering.SceneGraph
}
}
+ ///
public override bool HitTest(Point p) => Bounds.Contains(p);
}
}
diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs
index 3a15be144c..6db092c266 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs
@@ -3,15 +3,21 @@
using System;
using System.Collections.Generic;
-using Avalonia;
using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph
{
+ ///
+ /// Represents a scene graph used by the .
+ ///
public class Scene
{
private Dictionary _index;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The root visual to draw.
public Scene(IVisual rootVisual)
: this(
new VisualNode(rootVisual, null),
@@ -22,7 +28,7 @@ namespace Avalonia.Rendering.SceneGraph
_index.Add(rootVisual, Root);
}
- internal Scene(VisualNode root, Dictionary index, SceneLayers layers, int id)
+ private Scene(VisualNode root, Dictionary index, SceneLayers layers, int id)
{
Contract.Requires(root != null);
@@ -35,12 +41,35 @@ namespace Avalonia.Rendering.SceneGraph
root.LayerRoot = root.Visual;
}
+ ///
+ /// Gets an ID identifying the scene. This is incremented each time the scene is cloned.
+ ///
public int Id { get; }
+
+ ///
+ /// Gets the layers for the scene.
+ ///
public SceneLayers Layers { get; }
+
+ ///
+ /// Gets the root node of the scene graph.
+ ///
public IVisualNode Root { get; }
+
+ ///
+ /// Gets or sets the size of the scene in device independent pixels.
+ ///
public Size Size { get; set; }
+
+ ///
+ /// Gets or sets the scene scaling.
+ ///
public double Scaling { get; set; } = 1;
+ ///
+ /// Adds a node to the scene index.
+ ///
+ /// The node.
public void Add(IVisualNode node)
{
Contract.Requires(node != null);
@@ -48,6 +77,10 @@ namespace Avalonia.Rendering.SceneGraph
_index.Add(node.Visual, node);
}
+ ///
+ /// Clones the scene.
+ ///
+ /// The cloned scene.
public Scene Clone()
{
var index = new Dictionary();
@@ -62,6 +95,13 @@ namespace Avalonia.Rendering.SceneGraph
return result;
}
+ ///
+ /// Tries to find a node in the scene graph representing the specified visual.
+ ///
+ /// The visual.
+ ///
+ /// The node representing the visual or null if it could not be found.
+ ///
public IVisualNode FindNode(IVisual visual)
{
IVisualNode node;
@@ -69,11 +109,21 @@ namespace Avalonia.Rendering.SceneGraph
return node;
}
+ ///
+ /// Gets the visuals at a point in the scene.
+ ///
+ /// The point.
+ /// A filter. May be null.
+ /// The visuals at the specified point.
public IEnumerable HitTest(Point p, Func filter)
{
return HitTest(Root, p, null, filter);
}
+ ///
+ /// Removes a node from the scene index.
+ ///
+ /// The node.
public void Remove(IVisualNode node)
{
Contract.Requires(node != null);
diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs
index 7adebcd1dc..e54648fe8d 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs
@@ -10,8 +10,12 @@ using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph
{
+ ///
+ /// Builds a scene graph from a visual tree.
+ ///
public class SceneBuilder : ISceneBuilder
{
+ ///
public void UpdateAll(Scene scene)
{
Contract.Requires(scene != null);
@@ -27,6 +31,7 @@ namespace Avalonia.Rendering.SceneGraph
}
}
+ ///
public bool Update(Scene scene, IVisual visual)
{
Contract.Requires(scene != null);
diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/SceneLayer.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/SceneLayer.cs
index 253842ea3b..c17fbb08c9 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/SceneLayer.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/SceneLayer.cs
@@ -5,8 +5,16 @@ using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph
{
+ ///
+ /// Represents a layer in a .
+ ///
public class SceneLayer
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The visual at the root of the layer.
+ /// The distance from the scene root.
public SceneLayer(IVisual layerRoot, int distanceFromRoot)
{
LayerRoot = layerRoot;
@@ -14,6 +22,10 @@ namespace Avalonia.Rendering.SceneGraph
DistanceFromRoot = distanceFromRoot;
}
+ ///
+ /// Clones the layer.
+ ///
+ /// The cloned layer.
public SceneLayer Clone()
{
return new SceneLayer(LayerRoot, DistanceFromRoot)
@@ -25,12 +37,39 @@ namespace Avalonia.Rendering.SceneGraph
};
}
+ ///
+ /// Gets the visual at the root of the layer.
+ ///
public IVisual LayerRoot { get; }
+
+ ///
+ /// Gets the dirty rectangles for the layer.
+ ///
public DirtyRects Dirty { get; }
+
+ ///
+ /// Gets the distance of the layer root from the root of the scene.
+ ///
public int DistanceFromRoot { get; }
+
+ ///
+ /// Gets or sets the opacity of the layer.
+ ///
public double Opacity { get; set; } = 1;
+
+ ///
+ /// Gets or sets the opacity mask for the layer.
+ ///
public IBrush OpacityMask { get; set; }
+
+ ///
+ /// Gets or sets the target rectangle for the layer opacity mask.
+ ///
public Rect OpacityMaskRect { get; set; }
+
+ ///
+ /// Gets the layer's geometry clip.
+ ///
public IGeometryImpl GeometryClip { get; set; }
}
}
diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/SceneLayers.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/SceneLayers.cs
index 1d3c796da7..5960b4f560 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/SceneLayers.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/SceneLayers.cs
@@ -5,19 +5,32 @@ using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph
{
+ ///
+ /// Holds a collection of layers for a .
+ ///
public class SceneLayers : IEnumerable
{
private readonly IVisual _root;
private readonly List _inner = new List();
private readonly Dictionary _index = new Dictionary();
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The scene's root visual.
public SceneLayers(IVisual root)
{
_root = root;
}
+ ///
+ /// Gets the number of layers in the scene.
+ ///
public int Count => _inner.Count;
+ ///
+ /// Gets a value indicating whether any of the layers have a dirty region.
+ ///
public bool HasDirty
{
get
@@ -34,9 +47,25 @@ namespace Avalonia.Rendering.SceneGraph
}
}
+ ///
+ /// Gets a layer by index.
+ ///
+ /// The index of the layer.
+ /// The layer.
public SceneLayer this[int index] => _inner[index];
+
+ ///
+ /// Gets a layer by its root visual.
+ ///
+ /// The layer's root visual.
+ /// The layer.
public SceneLayer this[IVisual visual] => _index[visual];
+ ///
+ /// Adds a layer to the scene.
+ ///
+ /// The root visual of the layer.
+ /// The created layer.
public SceneLayer Add(IVisual layerRoot)
{
Contract.Requires(layerRoot != null);
@@ -49,6 +78,10 @@ namespace Avalonia.Rendering.SceneGraph
return layer;
}
+ ///
+ /// Makes a deep clone of the layers.
+ ///
+ /// The cloned layers.
public SceneLayers Clone()
{
var result = new SceneLayers(_root);
@@ -63,6 +96,13 @@ namespace Avalonia.Rendering.SceneGraph
return result;
}
+ ///
+ /// Tests whether a layer exists with the specified root visual.
+ ///
+ /// The root visual.
+ ///
+ /// True if a layer exists with the specified root visual, otherwise false.
+ ///
public bool Exists(IVisual layerRoot)
{
Contract.Requires(layerRoot != null);
@@ -70,6 +110,11 @@ namespace Avalonia.Rendering.SceneGraph
return _index.ContainsKey(layerRoot);
}
+ ///
+ /// Tries to find a layer with the specified root visual.
+ ///
+ /// The root visual.
+ /// The layer if found, otherwise null.
public SceneLayer Find(IVisual layerRoot)
{
SceneLayer result;
@@ -77,6 +122,11 @@ namespace Avalonia.Rendering.SceneGraph
return result;
}
+ ///
+ /// Gets an existing layer or creates a new one if no existing layer is found.
+ ///
+ /// The root visual.
+ /// The layer.
public SceneLayer GetOrAdd(IVisual layerRoot)
{
Contract.Requires(layerRoot != null);
@@ -91,6 +141,11 @@ namespace Avalonia.Rendering.SceneGraph
return result;
}
+ ///
+ /// Removes a layer from the scene.
+ ///
+ /// The root visual.
+ /// True if a matching layer was removed, otherwise false.
public bool Remove(IVisual layerRoot)
{
Contract.Requires(layerRoot != null);
@@ -105,6 +160,11 @@ namespace Avalonia.Rendering.SceneGraph
return layer != null;
}
+ ///
+ /// Removes a layer from the scene.
+ ///
+ /// The layer.
+ /// True if the layer was part of the scene, otherwise false.
public bool Remove(SceneLayer layer)
{
Contract.Requires(layer != null);
@@ -113,7 +173,10 @@ namespace Avalonia.Rendering.SceneGraph
return _inner.Remove(layer);
}
+ ///
public IEnumerator GetEnumerator() => _inner.GetEnumerator();
+
+ ///
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
private int FindInsertIndex(SceneLayer insert)
diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/TextNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/TextNode.cs
index df119365a6..3dc1500af0 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/TextNode.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/TextNode.cs
@@ -9,30 +9,79 @@ using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph
{
+ ///
+ /// A node in the scene graph which represents a text draw.
+ ///
internal class TextNode : BrushDrawOperation
{
- public TextNode(Matrix transform, IBrush foreground, Point origin, IFormattedTextImpl text)
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The transform.
+ /// The foreground brush.
+ /// The draw origin.
+ /// The text to draw.
+ /// Child scenes for drawing visual brushes.
+ public TextNode(
+ Matrix transform,
+ IBrush foreground,
+ Point origin,
+ IFormattedTextImpl text,
+ IDictionary childScenes = null)
{
Bounds = new Rect(origin, text.Size).TransformToAABB(transform);
Transform = transform;
Foreground = ToImmutable(foreground);
Origin = origin;
Text = text;
+ ChildScenes = childScenes;
}
+ ///
public override Rect Bounds { get; }
+
+ ///
+ /// Gets the transform with which the node will be drawn.
+ ///
public Matrix Transform { get; }
+
+ ///
+ /// Gets the foreground brush.
+ ///
public IBrush Foreground { get; }
+
+ ///
+ /// Gets the draw origin.
+ ///
public Point Origin { get; }
+
+ ///
+ /// Gets the text to draw.
+ ///
public IFormattedTextImpl Text { get; }
- public override IDictionary ChildScenes => null;
+ ///
+ public override IDictionary ChildScenes { get; }
+
+ ///
public override void Render(IDrawingContextImpl context)
{
context.Transform = Transform;
context.DrawText(Foreground, Origin, Text);
}
+ ///
+ /// Determines if this draw operation equals another.
+ ///
+ /// The transform of the other draw operation.
+ /// The foregroundof the other draw operation.
+ /// The draw origin of the other draw operation.
+ /// The text of the other draw operation.
+ /// True if the draw operations are the same, otherwise false.
+ ///
+ /// The properties of the other draw operation are passed in as arguments to prevent
+ /// allocation of a not-yet-constructed draw operation object.
+ ///
internal bool Equals(Matrix transform, IBrush foreground, Point origin, IFormattedTextImpl text)
{
return transform == Transform &&
@@ -41,6 +90,7 @@ namespace Avalonia.Rendering.SceneGraph
Equals(text, Text);
}
+ ///
public override bool HitTest(Point p) => Bounds.Contains(p);
}
}