|
|
|
@ -1,11 +1,14 @@ |
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Collections.Specialized; |
|
|
|
using Avalonia.Animation; |
|
|
|
using Avalonia.Collections; |
|
|
|
using Avalonia.Media.Immutable; |
|
|
|
|
|
|
|
#nullable enable |
|
|
|
|
|
|
|
namespace Avalonia.Media |
|
|
|
{ |
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Linq; |
|
|
|
using Avalonia.Animation; |
|
|
|
using Avalonia.Media.Immutable; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Represents the sequence of dashes and gaps that will be applied by a <see cref="Pen"/>.
|
|
|
|
/// </summary>
|
|
|
|
@ -14,8 +17,8 @@ namespace Avalonia.Media |
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="Dashes"/> property.
|
|
|
|
/// </summary>
|
|
|
|
public static readonly StyledProperty<IReadOnlyList<double>> DashesProperty = |
|
|
|
AvaloniaProperty.Register<DashStyle, IReadOnlyList<double>>(nameof(Dashes)); |
|
|
|
public static readonly StyledProperty<AvaloniaList<double>> DashesProperty = |
|
|
|
AvaloniaProperty.Register<DashStyle, AvaloniaList<double>>(nameof(Dashes)); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="Offset"/> property.
|
|
|
|
@ -23,10 +26,10 @@ namespace Avalonia.Media |
|
|
|
public static readonly StyledProperty<double> OffsetProperty = |
|
|
|
AvaloniaProperty.Register<DashStyle, double>(nameof(Offset)); |
|
|
|
|
|
|
|
private static ImmutableDashStyle s_dash; |
|
|
|
private static ImmutableDashStyle s_dot; |
|
|
|
private static ImmutableDashStyle s_dashDot; |
|
|
|
private static ImmutableDashStyle s_dashDotDot; |
|
|
|
private static ImmutableDashStyle? s_dash; |
|
|
|
private static ImmutableDashStyle? s_dot; |
|
|
|
private static ImmutableDashStyle? s_dashDot; |
|
|
|
private static ImmutableDashStyle? s_dashDotDot; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Initializes a new instance of the <see cref="DashStyle"/> class.
|
|
|
|
@ -41,9 +44,9 @@ namespace Avalonia.Media |
|
|
|
/// </summary>
|
|
|
|
/// <param name="dashes">The dashes collection.</param>
|
|
|
|
/// <param name="offset">The dash sequence offset.</param>
|
|
|
|
public DashStyle(IEnumerable<double> dashes, double offset) |
|
|
|
public DashStyle(IEnumerable<double>? dashes, double offset) |
|
|
|
{ |
|
|
|
Dashes = (IReadOnlyList<double>)dashes?.ToList() ?? Array.Empty<double>(); |
|
|
|
Dashes = (dashes as AvaloniaList<double>) ?? new AvaloniaList<double>(dashes ?? Array.Empty<double>()); |
|
|
|
Offset = offset; |
|
|
|
} |
|
|
|
|
|
|
|
@ -61,31 +64,27 @@ namespace Avalonia.Media |
|
|
|
/// <summary>
|
|
|
|
/// Represents a dashed <see cref="DashStyle"/>.
|
|
|
|
/// </summary>
|
|
|
|
public static IDashStyle Dash => |
|
|
|
s_dash ?? (s_dash = new ImmutableDashStyle(new double[] { 2, 2 }, 1)); |
|
|
|
public static IDashStyle Dash => s_dash ??= new ImmutableDashStyle(new double[] { 2, 2 }, 1); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Represents a dotted <see cref="DashStyle"/>.
|
|
|
|
/// </summary>
|
|
|
|
public static IDashStyle Dot => |
|
|
|
s_dot ?? (s_dot = new ImmutableDashStyle(new double[] { 0, 2 }, 0)); |
|
|
|
public static IDashStyle Dot => s_dot ??= new ImmutableDashStyle(new double[] { 0, 2 }, 0); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Represents a dashed dotted <see cref="DashStyle"/>.
|
|
|
|
/// </summary>
|
|
|
|
public static IDashStyle DashDot => |
|
|
|
s_dashDot ?? (s_dashDot = new ImmutableDashStyle(new double[] { 2, 2, 0, 2 }, 1)); |
|
|
|
public static IDashStyle DashDot => s_dashDot ??= new ImmutableDashStyle(new double[] { 2, 2, 0, 2 }, 1); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Represents a dashed double dotted <see cref="DashStyle"/>.
|
|
|
|
/// </summary>
|
|
|
|
public static IDashStyle DashDotDot => |
|
|
|
s_dashDotDot ?? (s_dashDotDot = new ImmutableDashStyle(new double[] { 2, 2, 0, 2, 0, 2 }, 1)); |
|
|
|
public static IDashStyle DashDotDot => s_dashDotDot ??= new ImmutableDashStyle(new double[] { 2, 2, 0, 2, 0, 2 }, 1); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the length of alternating dashes and gaps.
|
|
|
|
/// </summary>
|
|
|
|
public IReadOnlyList<double> Dashes |
|
|
|
public AvaloniaList<double> Dashes |
|
|
|
{ |
|
|
|
get => GetValue(DashesProperty); |
|
|
|
set => SetValue(DashesProperty, value); |
|
|
|
@ -100,15 +99,43 @@ namespace Avalonia.Media |
|
|
|
set => SetValue(OffsetProperty, value); |
|
|
|
} |
|
|
|
|
|
|
|
IReadOnlyList<double> IDashStyle.Dashes => Dashes; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Raised when the dash style changes.
|
|
|
|
/// </summary>
|
|
|
|
public event EventHandler Invalidated; |
|
|
|
public event EventHandler? Invalidated; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Returns an immutable clone of the <see cref="DashStyle"/>.
|
|
|
|
/// </summary>
|
|
|
|
/// <returns></returns>
|
|
|
|
public ImmutableDashStyle ToImmutable() => new ImmutableDashStyle(Dashes, Offset); |
|
|
|
|
|
|
|
protected override void OnPropertyChanged<T>(AvaloniaPropertyChangedEventArgs<T> change) |
|
|
|
{ |
|
|
|
base.OnPropertyChanged(change); |
|
|
|
|
|
|
|
if (change.Property == DashesProperty) |
|
|
|
{ |
|
|
|
var oldValue = change.OldValue.GetValueOrDefault<AvaloniaList<double>>(); |
|
|
|
var newValue = change.NewValue.GetValueOrDefault<AvaloniaList<double>>(); |
|
|
|
|
|
|
|
if (oldValue is object) |
|
|
|
{ |
|
|
|
oldValue.CollectionChanged -= DashesChanged; |
|
|
|
} |
|
|
|
|
|
|
|
if (newValue is object) |
|
|
|
{ |
|
|
|
newValue.CollectionChanged += DashesChanged; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void DashesChanged(object sender, NotifyCollectionChangedEventArgs e) |
|
|
|
{ |
|
|
|
Invalidated?.Invoke(this, e); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|