diff --git a/Perspex.SceneGraph/GlobalSuppressions.cs b/Perspex.SceneGraph/GlobalSuppressions.cs
new file mode 100644
index 0000000000..3d080850f1
--- /dev/null
+++ b/Perspex.SceneGraph/GlobalSuppressions.cs
@@ -0,0 +1,14 @@
+// -----------------------------------------------------------------------
+//
+// Copyright 2015 MIT Licence. See licence.md for more information.
+//
+// -----------------------------------------------------------------------
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(
+ "StyleCop.CSharp.MaintainabilityRules",
+ "SA1401:Fields must be private",
+ Justification = "PerspexProperty fields should not be private.")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(
+ "StyleCop.CSharp.DocumentationRules",
+ "SA1609:Property documentation must have value",
+ Justification = "This rule is fscking pointless")]
\ No newline at end of file
diff --git a/Perspex.SceneGraph/IVisual.cs b/Perspex.SceneGraph/IVisual.cs
index d43c13e0d3..c7bbf551c9 100644
--- a/Perspex.SceneGraph/IVisual.cs
+++ b/Perspex.SceneGraph/IVisual.cs
@@ -13,10 +13,10 @@ namespace Perspex
/// Represents a node in the visual scene graph.
///
///
- /// The interface defines the interface required for a renderer to
- /// render a scene graph. You should not usually need to reference this interface unless
- /// you are writing a renderer; instead use the extension methods defined in
- /// to traverse the scene graph. This interface is
+ /// The interface defines the interface required for a renderer to
+ /// render a scene graph. You should not usually need to reference this interface unless
+ /// you are writing a renderer; instead use the extension methods defined in
+ /// to traverse the scene graph. This interface is
/// implemented by . It should not be necessary to implement it
/// anywhere else.
///
@@ -25,7 +25,6 @@ namespace Perspex
///
/// Gets the bounds of the scene graph node.
///
- ///
Rect Bounds { get; }
///
@@ -78,7 +77,7 @@ namespace Perspex
/// Returns a transform that transforms the visual's coordinates into the coordinates
/// of the specified .
///
- ///
+ /// The visual to translate the coordinates to.
/// A containing the transform.
Matrix TransformToVisual(IVisual visual);
}
diff --git a/Perspex.SceneGraph/Visual.cs b/Perspex.SceneGraph/Visual.cs
index 5b3a1e2e6a..fb8a307765 100644
--- a/Perspex.SceneGraph/Visual.cs
+++ b/Perspex.SceneGraph/Visual.cs
@@ -20,35 +20,77 @@ namespace Perspex
using Serilog;
using Serilog.Core.Enrichers;
+ ///
+ /// Base class for controls that provides rendering and related visual properties.
+ ///
+ ///
+ /// The class acts as a node in the Perspex scene graph and holds
+ /// all the information needed for an to render the control.
+ /// To traverse the scene graph (aka Visual Tree), use the extension methods defined
+ /// in .
+ ///
public class Visual : Animatable, IVisual
{
+ ///
+ /// Defines the property.
+ ///
public static readonly PerspexProperty BoundsProperty =
- PerspexProperty.Register("Bounds");
+ PerspexProperty.Register(nameof(Bounds));
+ ///
+ /// Defines the property.
+ ///
public static readonly PerspexProperty ClipToBoundsProperty =
- PerspexProperty.Register("ClipToBounds");
+ PerspexProperty.Register(nameof(ClipToBounds));
+ ///
+ /// Defines the property.
+ ///
public static readonly PerspexProperty IsVisibleProperty =
- PerspexProperty.Register("IsVisible", true);
+ PerspexProperty.Register(nameof(IsVisible), true);
+ ///
+ /// Defines the property.
+ ///
public static readonly PerspexProperty OpacityProperty =
- PerspexProperty.Register("Opacity", 1);
+ PerspexProperty.Register(nameof(Opacity), 1);
+ ///
+ /// Defines the property.
+ ///
public static readonly PerspexProperty RenderTransformProperty =
- PerspexProperty.Register("RenderTransform");
+ PerspexProperty.Register(nameof(RenderTransform));
+ ///
+ /// Defines the property.
+ ///
public static readonly PerspexProperty TransformOriginProperty =
- PerspexProperty.Register("TransformOrigin", defaultValue: Origin.Default);
+ PerspexProperty.Register(nameof(TransformOrigin), defaultValue: Origin.Default);
+ ///
+ /// Defines the property.
+ ///
public static readonly PerspexProperty ZIndexProperty =
- PerspexProperty.Register("ZIndex");
+ PerspexProperty.Register(nameof(ZIndex));
+ ///
+ /// Holds the children of the visual.
+ ///
private PerspexList visualChildren;
+ ///
+ /// Holds the parent of the visual.
+ ///
private Visual visualParent;
+ ///
+ /// The logger for visual-level events.
+ ///
private ILogger visualLogger;
+ ///
+ /// Initializes static members of the class.
+ ///
static Visual()
{
AffectsRender(IsVisibleProperty);
@@ -56,6 +98,9 @@ namespace Perspex
RenderTransformProperty.Changed.Subscribe(RenderTransformChanged);
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
public Visual()
{
this.visualLogger = Log.ForContext(new[]
@@ -69,53 +114,80 @@ namespace Perspex
this.visualChildren.CollectionChanged += this.VisualChildrenChanged;
}
+ ///
+ /// Gets the bounds of the scene graph node.
+ ///
public Rect Bounds
{
get { return this.GetValue(BoundsProperty); }
protected set { this.SetValue(BoundsProperty, value); }
}
+ ///
+ /// Gets a value indicating whether the scene graph node should be clipped to its bounds.
+ ///
public bool ClipToBounds
{
get { return this.GetValue(ClipToBoundsProperty); }
set { this.SetValue(ClipToBoundsProperty, value); }
}
+ ///
+ /// Gets a value indicating whether this scene graph node is visible.
+ ///
public bool IsVisible
{
get { return this.GetValue(IsVisibleProperty); }
set { this.SetValue(IsVisibleProperty, value); }
}
+ ///
+ /// Gets the opacity of the scene graph node.
+ ///
public double Opacity
{
get { return this.GetValue(OpacityProperty); }
set { this.SetValue(OpacityProperty, value); }
}
+ ///
+ /// Gets the render transform of the scene graph node.
+ ///
public Transform RenderTransform
{
get { return this.GetValue(RenderTransformProperty); }
set { this.SetValue(RenderTransformProperty, value); }
}
+ ///
+ /// Gets the transform origin of the scene graph node.
+ ///
public Origin TransformOrigin
{
get { return this.GetValue(TransformOriginProperty); }
set { this.SetValue(TransformOriginProperty, value); }
}
+ ///
+ /// Gets the Z index of the node.
+ ///
public int ZIndex
{
get { return this.GetValue(ZIndexProperty); }
set { this.SetValue(ZIndexProperty, value); }
}
+ ///
+ /// Gets the scene graph node's child nodes.
+ ///
IPerspexReadOnlyList IVisual.VisualChildren
{
get { return this.visualChildren; }
}
+ ///
+ /// Gets the scene graph node's parent node.
+ ///
IVisual IVisual.VisualParent
{
get
@@ -124,6 +196,9 @@ namespace Perspex
}
}
+ ///
+ /// Invalidates the visual and queues a repaint.
+ ///
public void InvalidateVisual()
{
IRenderRoot root = this.GetSelfAndVisualAncestors()
@@ -136,17 +211,32 @@ namespace Perspex
}
}
+ ///
+ /// Renders the visual to a .
+ ///
+ /// The drawing context.
public virtual void Render(IDrawingContext context)
{
Contract.Requires(context != null);
}
+ ///
+ /// Converts a point from control coordinates to screen coordinates.
+ ///
+ /// The point to convert.
+ /// The point in screen coordinates.
public Point PointToScreen(Point point)
{
var p = GetOffsetFromRoot(this);
return p.Item1.TranslatePointToScreen(point + p.Item2);
}
+ ///
+ /// Returns a transform that transforms the visual's coordinates into the coordinates
+ /// of the specified .
+ ///
+ /// The visual to translate the coordinates to.
+ /// A containing the transform.
public Matrix TransformToVisual(IVisual visual)
{
var thisOffset = GetOffsetFromRoot(this).Item2;
@@ -154,11 +244,25 @@ namespace Perspex
return Matrix.Translation(-thatOffset) * Matrix.Translation(thisOffset);
}
+ ///
+ /// Indicates that a property change should cause to be
+ /// called.
+ ///
+ /// The property.
+ ///
+ /// This method should be called in a control's static constructor for each property
+ /// on the control which when changed should cause a redraw. This is similar to WPF's
+ /// FrameworkPropertyMetadata.AffectsRender flag.
+ ///
protected static void AffectsRender(PerspexProperty property)
{
property.Changed.Subscribe(AffectsRenderInvalidate);
}
+ ///
+ /// Adds a visual child to the control.
+ ///
+ /// The child to add.
protected void AddVisualChild(Visual visual)
{
Contract.Requires(visual != null);
@@ -166,6 +270,10 @@ namespace Perspex
this.visualChildren.Add(visual);
}
+ ///
+ /// Adds visual children to the control.
+ ///
+ /// The children to add.
protected void AddVisualChildren(IEnumerable visuals)
{
Contract.Requires(visuals != null);
@@ -173,11 +281,18 @@ namespace Perspex
this.visualChildren.AddRange(visuals);
}
+ ///
+ /// Removes all visual children from the control.
+ ///
protected void ClearVisualChildren()
{
this.visualChildren.Clear();
}
+ ///
+ /// Removes a visual child from the control;
+ ///
+ /// The child to remove.
protected void RemoveVisualChild(Visual visual)
{
Contract.Requires(visual != null);
@@ -185,6 +300,10 @@ namespace Perspex
this.visualChildren.Remove(visual);
}
+ ///
+ /// Removes a visual children from the control;
+ ///
+ /// The children to remove.
protected void RemoveVisualChildren(IEnumerable visuals)
{
Contract.Requires(visuals != null);
@@ -195,18 +314,31 @@ namespace Perspex
}
}
+ ///
+ /// Called when the control is added to a visual tree.
+ ///
+ /// The root of the visual tree.
protected virtual void OnAttachedToVisualTree(IRenderRoot root)
{
}
- protected virtual void OnDetachedFromVisualTree(IRenderRoot oldRoot)
+ ///
+ /// Called when the control is removed from a visual tree.
+ ///
+ /// The root of the visual tree.
+ protected virtual void OnDetachedFromVisualTree(IRenderRoot root)
{
}
+ [Obsolete("Use OnAttachedToVisualTree instead")]
protected virtual void OnVisualParentChanged(Visual oldParent)
{
}
+ ///
+ /// Called when a property changes that should invalidate the visual.
+ ///
+ /// The event args.
private static void AffectsRenderInvalidate(PerspexPropertyChangedEventArgs e)
{
Visual visual = e.Sender as Visual;
@@ -217,6 +349,11 @@ namespace Perspex
}
}
+ ///
+ /// Gets the root of the controls visual tree and the distance from the root.
+ ///
+ /// The visual.
+ /// A tuple containing the root and the distance from the root
private static Tuple GetOffsetFromRoot(IVisual v)
{
var result = new Vector();
@@ -235,6 +372,10 @@ namespace Perspex
return Tuple.Create((IRenderRoot)v, result);
}
+ ///
+ /// Called when a visual's changes.
+ ///
+ /// The event args.
private static void RenderTransformChanged(PerspexPropertyChangedEventArgs e)
{
var sender = e.Sender as Visual;
@@ -258,11 +399,20 @@ namespace Perspex
}
}
+ ///
+ /// Called when the event is fired.
+ ///
+ /// The sender.
+ /// The event args.
private void RenderTransformChanged(object sender, EventArgs e)
{
this.InvalidateVisual();
}
+ ///
+ /// Sets the visual parent of the Visual.
+ ///
+ /// The visual parent.
private void SetVisualParent(Visual value)
{
if (this.visualParent != value)
@@ -291,6 +441,11 @@ namespace Perspex
}
}
+ ///
+ /// Called when the collection changes.
+ ///
+ /// The sender.
+ /// The event args.
private void VisualChildrenChanged(object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
@@ -315,6 +470,11 @@ namespace Perspex
}
}
+ ///
+ /// Calls the method for this control
+ /// and all of its visual descendents.
+ ///
+ /// The root of the visual tree.
private void NotifyAttachedToVisualTree(IRenderRoot root)
{
this.visualLogger.Verbose("Attached to visual tree");
@@ -330,17 +490,22 @@ namespace Perspex
}
}
- private void NotifyDetachedFromVisualTree(IRenderRoot oldRoot)
+ ///
+ /// Calls the method for this control
+ /// and all of its visual descendents.
+ ///
+ /// The root of the visual tree.
+ private void NotifyDetachedFromVisualTree(IRenderRoot root)
{
this.visualLogger.Verbose("Detached from visual tree");
- this.OnDetachedFromVisualTree(oldRoot);
+ this.OnDetachedFromVisualTree(root);
if (this.visualChildren != null)
{
foreach (Visual child in this.visualChildren.OfType())
{
- child.NotifyDetachedFromVisualTree(oldRoot);
+ child.NotifyDetachedFromVisualTree(root);
}
}
}