@ -2,38 +2,67 @@ using System;
using Avalonia.Collections ;
using Avalonia.Collections ;
using Avalonia.Media ;
using Avalonia.Media ;
# nullable enable
namespace Avalonia.Controls.Shapes
namespace Avalonia.Controls.Shapes
{
{
/// <summary>
/// Provides a base class for shape elements, such as <see cref="Ellipse"/>, <see cref="Polygon"/> and <see cref="Rectangle"/>.
/// </summary>
public abstract class Shape : Control
public abstract class Shape : Control
{
{
public static readonly StyledProperty < IBrush > FillProperty =
/// <summary>
AvaloniaProperty . Register < Shape , IBrush > ( nameof ( Fill ) ) ;
/// Defines the <see cref="Fill"/> property.
/// </summary>
public static readonly StyledProperty < IBrush ? > FillProperty =
AvaloniaProperty . Register < Shape , IBrush ? > ( nameof ( Fill ) ) ;
/// <summary>
/// Defines the <see cref="Stretch"/> property.
/// </summary>
public static readonly StyledProperty < Stretch > StretchProperty =
public static readonly StyledProperty < Stretch > StretchProperty =
AvaloniaProperty . Register < Shape , Stretch > ( nameof ( Stretch ) ) ;
AvaloniaProperty . Register < Shape , Stretch > ( nameof ( Stretch ) ) ;
public static readonly StyledProperty < IBrush > StrokeProperty =
/// <summary>
AvaloniaProperty . Register < Shape , IBrush > ( nameof ( Stroke ) ) ;
/// Defines the <see cref="Stroke"/> property.
/// </summary>
public static readonly StyledProperty < IBrush ? > StrokeProperty =
AvaloniaProperty . Register < Shape , IBrush ? > ( nameof ( Stroke ) ) ;
public static readonly StyledProperty < AvaloniaList < double > > StrokeDashArrayProperty =
/// <summary>
AvaloniaProperty . Register < Shape , AvaloniaList < double > > ( nameof ( StrokeDashArray ) ) ;
/// Defines the <see cref="StrokeDashArray"/> property.
/// </summary>
public static readonly StyledProperty < AvaloniaList < double > ? > StrokeDashArrayProperty =
AvaloniaProperty . Register < Shape , AvaloniaList < double > ? > ( nameof ( StrokeDashArray ) ) ;
/// <summary>
/// Defines the <see cref="StrokeDashOffset"/> property.
/// </summary>
public static readonly StyledProperty < double > StrokeDashOffsetProperty =
public static readonly StyledProperty < double > StrokeDashOffsetProperty =
AvaloniaProperty . Register < Shape , double > ( nameof ( StrokeDashOffset ) ) ;
AvaloniaProperty . Register < Shape , double > ( nameof ( StrokeDashOffset ) ) ;
/// <summary>
/// Defines the <see cref="StrokeThickness"/> property.
/// </summary>
public static readonly StyledProperty < double > StrokeThicknessProperty =
public static readonly StyledProperty < double > StrokeThicknessProperty =
AvaloniaProperty . Register < Shape , double > ( nameof ( StrokeThickness ) ) ;
AvaloniaProperty . Register < Shape , double > ( nameof ( StrokeThickness ) ) ;
/// <summary>
/// Defines the <see cref="StrokeLineCap"/> property.
/// </summary>
public static readonly StyledProperty < PenLineCap > StrokeLineCapProperty =
public static readonly StyledProperty < PenLineCap > StrokeLineCapProperty =
AvaloniaProperty . Register < Shape , PenLineCap > ( nameof ( StrokeLineCap ) , PenLineCap . Flat ) ;
AvaloniaProperty . Register < Shape , PenLineCap > ( nameof ( StrokeLineCap ) , PenLineCap . Flat ) ;
/// <summary>
/// Defines the <see cref="StrokeJoin"/> property.
/// </summary>
public static readonly StyledProperty < PenLineJoin > StrokeJoinProperty =
public static readonly StyledProperty < PenLineJoin > StrokeJoinProperty =
AvaloniaProperty . Register < Shape , PenLineJoin > ( nameof ( StrokeJoin ) , PenLineJoin . Miter ) ;
AvaloniaProperty . Register < Shape , PenLineJoin > ( nameof ( StrokeJoin ) , PenLineJoin . Miter ) ;
private Matrix _ transform = Matrix . Identity ;
private Matrix _ transform = Matrix . Identity ;
private Geometry _d efiningGeometry ;
private Geometry ? _d efiningGeometry ;
private Geometry _ renderedGeometry ;
private Geometry ? _ renderedGeometry ;
bool _ calculateTransformOnArrange = fals e ;
private bool _ calculateTransformOnArrange ;
static Shape ( )
static Shape ( )
{
{
@ -43,7 +72,10 @@ namespace Avalonia.Controls.Shapes
StrokeThicknessProperty , StrokeLineCapProperty , StrokeJoinProperty ) ;
StrokeThicknessProperty , StrokeLineCapProperty , StrokeJoinProperty ) ;
}
}
public Geometry DefiningGeometry
/// <summary>
/// Gets a value that represents the <see cref="Geometry"/> of the shape.
/// </summary>
public Geometry ? DefiningGeometry
{
{
get
get
{
{
@ -56,13 +88,10 @@ namespace Avalonia.Controls.Shapes
}
}
}
}
public IBrush Fill
/// <summary>
{
/// Gets a value that represents the final rendered <see cref="Geometry"/> of the shape.
get { return GetValue ( FillProperty ) ; }
/// </summary>
set { SetValue ( FillProperty , value ) ; }
public Geometry ? RenderedGeometry
}
public Geometry RenderedGeometry
{
{
get
get
{
{
@ -93,42 +122,72 @@ namespace Avalonia.Controls.Shapes
}
}
}
}
/// <summary>
/// Gets or sets the <see cref="IBrush"/> that specifies how the shape's interior is painted.
/// </summary>
public IBrush ? Fill
{
get { return GetValue ( FillProperty ) ; }
set { SetValue ( FillProperty , value ) ; }
}
/// <summary>
/// Gets or sets a <see cref="Stretch"/> enumeration value that describes how the shape fills its allocated space.
/// </summary>
public Stretch Stretch
public Stretch Stretch
{
{
get { return GetValue ( StretchProperty ) ; }
get { return GetValue ( StretchProperty ) ; }
set { SetValue ( StretchProperty , value ) ; }
set { SetValue ( StretchProperty , value ) ; }
}
}
public IBrush Stroke
/// <summary>
/// Gets or sets the <see cref="IBrush"/> that specifies how the shape's outline is painted.
/// </summary>
public IBrush ? Stroke
{
{
get { return GetValue ( StrokeProperty ) ; }
get { return GetValue ( StrokeProperty ) ; }
set { SetValue ( StrokeProperty , value ) ; }
set { SetValue ( StrokeProperty , value ) ; }
}
}
public AvaloniaList < double > StrokeDashArray
/// <summary>
/// Gets or sets a collection of <see cref="double"/> values that indicate the pattern of dashes and gaps that is used to outline shapes.
/// </summary>
public AvaloniaList < double > ? StrokeDashArray
{
{
get { return GetValue ( StrokeDashArrayProperty ) ; }
get { return GetValue ( StrokeDashArrayProperty ) ; }
set { SetValue ( StrokeDashArrayProperty , value ) ; }
set { SetValue ( StrokeDashArrayProperty , value ) ; }
}
}
/// <summary>
/// Gets or sets a value that specifies the distance within the dash pattern where a dash begins.
/// </summary>
public double StrokeDashOffset
public double StrokeDashOffset
{
{
get { return GetValue ( StrokeDashOffsetProperty ) ; }
get { return GetValue ( StrokeDashOffsetProperty ) ; }
set { SetValue ( StrokeDashOffsetProperty , value ) ; }
set { SetValue ( StrokeDashOffsetProperty , value ) ; }
}
}
/// <summary>
/// Gets or sets the width of the shape outline.
/// </summary>
public double StrokeThickness
public double StrokeThickness
{
{
get { return GetValue ( StrokeThicknessProperty ) ; }
get { return GetValue ( StrokeThicknessProperty ) ; }
set { SetValue ( StrokeThicknessProperty , value ) ; }
set { SetValue ( StrokeThicknessProperty , value ) ; }
}
}
/// <summary>
/// Gets or sets a <see cref="PenLineCap"/> enumeration value that describes the shape at the ends of a line.
/// </summary>
public PenLineCap StrokeLineCap
public PenLineCap StrokeLineCap
{
{
get { return GetValue ( StrokeLineCapProperty ) ; }
get { return GetValue ( StrokeLineCapProperty ) ; }
set { SetValue ( StrokeLineCapProperty , value ) ; }
set { SetValue ( StrokeLineCapProperty , value ) ; }
}
}
/// <summary>
/// Gets or sets a <see cref="PenLineJoin"/> enumeration value that specifies the type of join that is used at the vertices of a Shape.
/// </summary>
public PenLineJoin StrokeJoin
public PenLineJoin StrokeJoin
{
{
get { return GetValue ( StrokeJoinProperty ) ; }
get { return GetValue ( StrokeJoinProperty ) ; }
@ -170,12 +229,20 @@ namespace Avalonia.Controls.Shapes
}
}
}
}
protected abstract Geometry CreateDefiningGeometry ( ) ;
/// <summary>
/// Creates the shape's defining geometry.
/// </summary>
/// <returns>Defining <see cref="Geometry"/> of the shape.</returns>
protected abstract Geometry ? CreateDefiningGeometry ( ) ;
/// <summary>
/// Invalidates the geometry of this shape.
/// </summary>
protected void InvalidateGeometry ( )
protected void InvalidateGeometry ( )
{
{
_ renderedGeometry = null ;
_ renderedGeometry = null ;
_d efiningGeometry = null ;
_d efiningGeometry = null ;
InvalidateMeasure ( ) ;
InvalidateMeasure ( ) ;
}
}
@ -321,8 +388,8 @@ namespace Avalonia.Controls.Shapes
// portion changes.
// portion changes.
if ( e . Property = = BoundsProperty )
if ( e . Property = = BoundsProperty )
{
{
var oldBounds = ( Rect ) e . OldValue ;
var oldBounds = ( Rect ) e . OldValue ! ;
var newBounds = ( Rect ) e . NewValue ;
var newBounds = ( Rect ) e . NewValue ! ;
if ( oldBounds . Size = = newBounds . Size )
if ( oldBounds . Size = = newBounds . Size )
{
{