|
|
@@ -26,7 +26,7 @@ namespace Perspex.Controls.Shapes
|
|
|
PerspexProperty.Register<Shape, double>("StrokeThickness");
|
|
|
|
|
|
private Matrix _transform = Matrix.Identity;
|
|
|
-
|
|
|
+ private Geometry _definingGeometry;
|
|
|
private Geometry _renderedGeometry;
|
|
|
|
|
|
static Shape()
|
|
|
@@ -38,9 +38,17 @@ namespace Perspex.Controls.Shapes
|
|
|
AffectsMeasure(StrokeThicknessProperty);
|
|
|
}
|
|
|
|
|
|
- public abstract Geometry DefiningGeometry
|
|
|
+ public Geometry DefiningGeometry
|
|
|
{
|
|
|
- get;
|
|
|
+ get
|
|
|
+ {
|
|
|
+ if (_definingGeometry == null)
|
|
|
+ {
|
|
|
+ _definingGeometry = CreateDefiningGeometry();
|
|
|
+ }
|
|
|
+
|
|
|
+ return _definingGeometry;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
public Brush Fill
|
|
|
@@ -110,6 +118,28 @@ namespace Perspex.Controls.Shapes
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// Marks a property as affecting the shape's geometry.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="property">The property.</param>
|
|
|
+ /// <remarks>
|
|
|
+ /// After a call to this method in a control's static constructor, any change to the
|
|
|
+ /// property will cause <see cref="InvalidateGeometry"/> to be called on the element.
|
|
|
+ /// </remarks>
|
|
|
+ protected static void AffectsGeometry(PerspexProperty property)
|
|
|
+ {
|
|
|
+ property.Changed.Subscribe(AffectsGeometryInvalidate);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected abstract Geometry CreateDefiningGeometry();
|
|
|
+
|
|
|
+ protected void InvalidateGeometry()
|
|
|
+ {
|
|
|
+ this._renderedGeometry = null;
|
|
|
+ this._definingGeometry = null;
|
|
|
+ InvalidateMeasure();
|
|
|
+ }
|
|
|
+
|
|
|
protected override Size MeasureOverride(Size availableSize)
|
|
|
{
|
|
|
// This should probably use GetRenderBounds(strokeThickness) but then the calculations
|
|
|
@@ -195,5 +225,28 @@ namespace Perspex.Controls.Shapes
|
|
|
|
|
|
return new Size(shapeSize.Width * sx, shapeSize.Height * sy);
|
|
|
}
|
|
|
+
|
|
|
+ private static void AffectsGeometryInvalidate(PerspexPropertyChangedEventArgs e)
|
|
|
+ {
|
|
|
+ var control = e.Sender as Shape;
|
|
|
+
|
|
|
+ if (control != null)
|
|
|
+ {
|
|
|
+ // If the geometry is invalidated when Bounds changes, only invalidate when the Size
|
|
|
+ // portion changes.
|
|
|
+ if (e.Property == BoundsProperty)
|
|
|
+ {
|
|
|
+ var oldBounds = (Rect)e.OldValue;
|
|
|
+ var newBounds = (Rect)e.NewValue;
|
|
|
+
|
|
|
+ if (oldBounds.Size == newBounds.Size)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ control.InvalidateGeometry();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|