csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.7 KiB
140 lines
4.7 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Specialized;
|
|
using Avalonia.Animation;
|
|
using Avalonia.Collections;
|
|
using Avalonia.Media.Immutable;
|
|
using Avalonia.Reactive;
|
|
|
|
#nullable enable
|
|
|
|
namespace Avalonia.Media
|
|
{
|
|
/// <summary>
|
|
/// Represents the sequence of dashes and gaps that will be applied by a <see cref="Pen"/>.
|
|
/// </summary>
|
|
public class DashStyle : Animatable, IDashStyle, IAffectsRender
|
|
{
|
|
/// <summary>
|
|
/// Defines the <see cref="Dashes"/> property.
|
|
/// </summary>
|
|
public static readonly StyledProperty<AvaloniaList<double>?> DashesProperty =
|
|
AvaloniaProperty.Register<DashStyle, AvaloniaList<double>?>(nameof(Dashes));
|
|
|
|
/// <summary>
|
|
/// Defines the <see cref="Offset"/> property.
|
|
/// </summary>
|
|
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;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="DashStyle"/> class.
|
|
/// </summary>
|
|
public DashStyle()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="DashStyle"/> class.
|
|
/// </summary>
|
|
/// <param name="dashes">The dashes collection.</param>
|
|
/// <param name="offset">The dash sequence offset.</param>
|
|
public DashStyle(IEnumerable<double>? dashes, double offset)
|
|
{
|
|
Dashes = (dashes as AvaloniaList<double>) ?? new AvaloniaList<double>(dashes ?? Array.Empty<double>());
|
|
Offset = offset;
|
|
}
|
|
|
|
static DashStyle()
|
|
{
|
|
void RaiseInvalidated(AvaloniaPropertyChangedEventArgs e)
|
|
{
|
|
((DashStyle)e.Sender).Invalidated?.Invoke(e.Sender, EventArgs.Empty);
|
|
}
|
|
|
|
DashesProperty.Changed.Subscribe(RaiseInvalidated);
|
|
OffsetProperty.Changed.Subscribe(RaiseInvalidated);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents a dashed <see cref="DashStyle"/>.
|
|
/// </summary>
|
|
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 ??= new ImmutableDashStyle(new double[] { 0, 2 }, 0);
|
|
|
|
/// <summary>
|
|
/// Represents a dashed dotted <see cref="DashStyle"/>.
|
|
/// </summary>
|
|
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 ??= new ImmutableDashStyle(new double[] { 2, 2, 0, 2, 0, 2 }, 1);
|
|
|
|
/// <summary>
|
|
/// Gets or sets the length of alternating dashes and gaps.
|
|
/// </summary>
|
|
public AvaloniaList<double>? Dashes
|
|
{
|
|
get => GetValue(DashesProperty);
|
|
set => SetValue(DashesProperty, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets how far in the dash sequence the stroke will start.
|
|
/// </summary>
|
|
public double Offset
|
|
{
|
|
get => GetValue(OffsetProperty);
|
|
set => SetValue(OffsetProperty, value);
|
|
}
|
|
|
|
IReadOnlyList<double>? IDashStyle.Dashes => Dashes;
|
|
|
|
/// <summary>
|
|
/// Raised when the dash style changes.
|
|
/// </summary>
|
|
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(AvaloniaPropertyChangedEventArgs change)
|
|
{
|
|
base.OnPropertyChanged(change);
|
|
|
|
if (change.Property == DashesProperty)
|
|
{
|
|
var (oldValue, newValue) = change.GetOldAndNewValue<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);
|
|
}
|
|
}
|
|
}
|
|
|