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.
118 lines
3.5 KiB
118 lines
3.5 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.Diagnostics.CodeAnalysis; |
|
using Avalonia; |
|
using Avalonia.Media; |
|
using FluentAvalonia.UI.Controls; |
|
|
|
namespace StabilityMatrix.Avalonia.Controls; |
|
|
|
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] |
|
public class LineDashFrame : Frame |
|
{ |
|
protected override Type StyleKeyOverride { get; } = typeof(Frame); |
|
|
|
public static readonly StyledProperty<ISolidColorBrush> StrokeProperty = AvaloniaProperty.Register< |
|
LineDashFrame, |
|
ISolidColorBrush |
|
>("Stroke"); |
|
|
|
public ISolidColorBrush Stroke |
|
{ |
|
get => GetValue(StrokeProperty); |
|
set => SetValue(StrokeProperty, value); |
|
} |
|
|
|
public static readonly StyledProperty<double> StrokeThicknessProperty = AvaloniaProperty.Register< |
|
LineDashFrame, |
|
double |
|
>("StrokeThickness"); |
|
|
|
public double StrokeThickness |
|
{ |
|
get => GetValue(StrokeThicknessProperty); |
|
set => SetValue(StrokeThicknessProperty, value); |
|
} |
|
|
|
public static readonly StyledProperty<double> StrokeDashLineProperty = AvaloniaProperty.Register< |
|
LineDashFrame, |
|
double |
|
>("StrokeDashLine"); |
|
|
|
public double StrokeDashLine |
|
{ |
|
get => GetValue(StrokeDashLineProperty); |
|
set => SetValue(StrokeDashLineProperty, value); |
|
} |
|
|
|
public static readonly StyledProperty<double> StrokeDashSpaceProperty = AvaloniaProperty.Register< |
|
LineDashFrame, |
|
double |
|
>("StrokeDashSpace"); |
|
|
|
public double StrokeDashSpace |
|
{ |
|
get => GetValue(StrokeDashSpaceProperty); |
|
set => SetValue(StrokeDashSpaceProperty, value); |
|
} |
|
|
|
public static readonly StyledProperty<ISolidColorBrush> FillProperty = AvaloniaProperty.Register< |
|
LineDashFrame, |
|
ISolidColorBrush |
|
>("Fill"); |
|
|
|
public ISolidColorBrush Fill |
|
{ |
|
get => GetValue(FillProperty); |
|
set => SetValue(FillProperty, value); |
|
} |
|
|
|
public LineDashFrame() |
|
{ |
|
UseLayoutRounding = true; |
|
} |
|
|
|
/// <inheritdoc /> |
|
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) |
|
{ |
|
base.OnPropertyChanged(change); |
|
|
|
if ( |
|
change.Property == StrokeProperty |
|
|| change.Property == StrokeThicknessProperty |
|
|| change.Property == StrokeDashLineProperty |
|
|| change.Property == StrokeDashSpaceProperty |
|
|| change.Property == FillProperty |
|
) |
|
{ |
|
InvalidateVisual(); |
|
} |
|
} |
|
|
|
/// <inheritdoc /> |
|
public override void Render(DrawingContext context) |
|
{ |
|
var width = Bounds.Width; |
|
var height = Bounds.Height; |
|
|
|
context.DrawRectangle(Fill, null, new Rect(0, 0, width, height)); |
|
|
|
var dashPen = new Pen(Stroke, StrokeThickness) { DashStyle = new DashStyle(GetDashArray(width), 0) }; |
|
|
|
context.DrawLine(dashPen, new Point(0, 0), new Point(width, 0)); |
|
context.DrawLine(dashPen, new Point(0, height), new Point(width, height)); |
|
context.DrawLine(dashPen, new Point(0, 0), new Point(0, height)); |
|
context.DrawLine(dashPen, new Point(width, 0), new Point(width, height)); |
|
} |
|
|
|
private IEnumerable<double> GetDashArray(double length) |
|
{ |
|
var availableLength = length - StrokeDashLine; |
|
var lines = (int)Math.Round(availableLength / (StrokeDashLine + StrokeDashSpace)); |
|
availableLength -= lines * StrokeDashLine; |
|
var actualSpacing = availableLength / lines; |
|
|
|
yield return StrokeDashLine / StrokeThickness; |
|
yield return actualSpacing / StrokeThickness; |
|
} |
|
}
|
|
|