|
|
|
@ -21,13 +21,19 @@ namespace Avalonia.Controls.Shapes |
|
|
|
|
|
|
|
public static readonly StyledProperty<AvaloniaList<double>> StrokeDashArrayProperty = |
|
|
|
AvaloniaProperty.Register<Shape, AvaloniaList<double>>(nameof(StrokeDashArray)); |
|
|
|
|
|
|
|
|
|
|
|
public static readonly StyledProperty<double> StrokeDashOffsetProperty = |
|
|
|
AvaloniaProperty.Register<Shape, double>(nameof(StrokeDashOffset)); |
|
|
|
|
|
|
|
public static readonly StyledProperty<double> StrokeThicknessProperty = |
|
|
|
AvaloniaProperty.Register<Shape, double>(nameof(StrokeThickness)); |
|
|
|
|
|
|
|
public static readonly StyledProperty<PenLineCap> StrokeLineCapProperty = |
|
|
|
AvaloniaProperty.Register<Shape, PenLineCap>(nameof(StrokeLineCap), PenLineCap.Flat); |
|
|
|
|
|
|
|
public static readonly StyledProperty<PenLineJoin> StrokeJoinProperty = |
|
|
|
AvaloniaProperty.Register<Shape, PenLineJoin>(nameof(StrokeJoin), PenLineJoin.Miter); |
|
|
|
|
|
|
|
private Matrix _transform = Matrix.Identity; |
|
|
|
private Geometry _definingGeometry; |
|
|
|
private Geometry _renderedGeometry; |
|
|
|
@ -36,7 +42,9 @@ namespace Avalonia.Controls.Shapes |
|
|
|
static Shape() |
|
|
|
{ |
|
|
|
AffectsMeasure<Shape>(StretchProperty, StrokeThicknessProperty); |
|
|
|
AffectsRender<Shape>(FillProperty, StrokeProperty, StrokeDashArrayProperty); |
|
|
|
|
|
|
|
AffectsRender<Shape>(FillProperty, StrokeProperty, StrokeDashArrayProperty, StrokeDashOffsetProperty, |
|
|
|
StrokeThicknessProperty, StrokeLineCapProperty, StrokeJoinProperty); |
|
|
|
} |
|
|
|
|
|
|
|
public Geometry DefiningGeometry |
|
|
|
@ -106,7 +114,7 @@ namespace Avalonia.Controls.Shapes |
|
|
|
get { return GetValue(StrokeDashArrayProperty); } |
|
|
|
set { SetValue(StrokeDashArrayProperty, value); } |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public double StrokeDashOffset |
|
|
|
{ |
|
|
|
get { return GetValue(StrokeDashOffsetProperty); } |
|
|
|
@ -119,13 +127,17 @@ namespace Avalonia.Controls.Shapes |
|
|
|
set { SetValue(StrokeThicknessProperty, value); } |
|
|
|
} |
|
|
|
|
|
|
|
public PenLineCap StrokeDashCap { get; set; } = PenLineCap.Flat; |
|
|
|
|
|
|
|
public PenLineCap StrokeStartLineCap { get; set; } = PenLineCap.Flat; |
|
|
|
|
|
|
|
public PenLineCap StrokeEndLineCap { get; set; } = PenLineCap.Flat; |
|
|
|
public PenLineCap StrokeLineCap |
|
|
|
{ |
|
|
|
get { return GetValue(StrokeLineCapProperty); } |
|
|
|
set { SetValue(StrokeLineCapProperty, value); } |
|
|
|
} |
|
|
|
|
|
|
|
public PenLineJoin StrokeJoin { get; set; } = PenLineJoin.Miter; |
|
|
|
public PenLineJoin StrokeJoin |
|
|
|
{ |
|
|
|
get { return GetValue(StrokeJoinProperty); } |
|
|
|
set { SetValue(StrokeJoinProperty, value); } |
|
|
|
} |
|
|
|
|
|
|
|
public override void Render(DrawingContext context) |
|
|
|
{ |
|
|
|
@ -133,8 +145,8 @@ namespace Avalonia.Controls.Shapes |
|
|
|
|
|
|
|
if (geometry != null) |
|
|
|
{ |
|
|
|
var pen = new Pen(Stroke, StrokeThickness, new DashStyle(StrokeDashArray, StrokeDashOffset), |
|
|
|
StrokeDashCap, StrokeStartLineCap, StrokeEndLineCap, StrokeJoin); |
|
|
|
var pen = new Pen(Stroke, StrokeThickness, new DashStyle(StrokeDashArray, StrokeDashOffset), |
|
|
|
StrokeLineCap, StrokeJoin); |
|
|
|
context.DrawGeometry(Fill, pen, geometry); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -169,11 +181,11 @@ namespace Avalonia.Controls.Shapes |
|
|
|
|
|
|
|
protected void InvalidateGeometry() |
|
|
|
{ |
|
|
|
this._renderedGeometry = null; |
|
|
|
this._definingGeometry = null; |
|
|
|
_renderedGeometry = null; |
|
|
|
_definingGeometry = null; |
|
|
|
InvalidateMeasure(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected override Size MeasureOverride(Size availableSize) |
|
|
|
{ |
|
|
|
bool deferCalculateTransform; |
|
|
|
@ -203,10 +215,10 @@ namespace Avalonia.Controls.Shapes |
|
|
|
return CalculateShapeSizeAndSetTransform(availableSize); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected override Size ArrangeOverride(Size finalSize) |
|
|
|
{ |
|
|
|
if(_calculateTransformOnArrange) |
|
|
|
if (_calculateTransformOnArrange) |
|
|
|
{ |
|
|
|
_calculateTransformOnArrange = false; |
|
|
|
CalculateShapeSizeAndSetTransform(finalSize); |
|
|
|
@ -312,25 +324,25 @@ namespace Avalonia.Controls.Shapes |
|
|
|
|
|
|
|
private static void AffectsGeometryInvalidate(AvaloniaPropertyChangedEventArgs e) |
|
|
|
{ |
|
|
|
var control = e.Sender as Shape; |
|
|
|
if (!(e.Sender is Shape control)) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (control != null) |
|
|
|
// If the geometry is invalidated when Bounds changes, only invalidate when the Size
|
|
|
|
// portion changes.
|
|
|
|
if (e.Property == BoundsProperty) |
|
|
|
{ |
|
|
|
// 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; |
|
|
|
var oldBounds = (Rect)e.OldValue; |
|
|
|
var newBounds = (Rect)e.NewValue; |
|
|
|
|
|
|
|
if (oldBounds.Size == newBounds.Size) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
if (oldBounds.Size == newBounds.Size) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
control.InvalidateGeometry(); |
|
|
|
} |
|
|
|
|
|
|
|
control.InvalidateGeometry(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|