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 StrokeProperty = AvaloniaProperty.Register< LineDashFrame, ISolidColorBrush >("Stroke"); public ISolidColorBrush Stroke { get => GetValue(StrokeProperty); set => SetValue(StrokeProperty, value); } public static readonly StyledProperty StrokeThicknessProperty = AvaloniaProperty.Register< LineDashFrame, double >("StrokeThickness"); public double StrokeThickness { get => GetValue(StrokeThicknessProperty); set => SetValue(StrokeThicknessProperty, value); } public static readonly StyledProperty StrokeDashLineProperty = AvaloniaProperty.Register< LineDashFrame, double >("StrokeDashLine"); public double StrokeDashLine { get => GetValue(StrokeDashLineProperty); set => SetValue(StrokeDashLineProperty, value); } public static readonly StyledProperty StrokeDashSpaceProperty = AvaloniaProperty.Register< LineDashFrame, double >("StrokeDashSpace"); public double StrokeDashSpace { get => GetValue(StrokeDashSpaceProperty); set => SetValue(StrokeDashSpaceProperty, value); } public static readonly StyledProperty FillProperty = AvaloniaProperty.Register< LineDashFrame, ISolidColorBrush >("Fill"); public ISolidColorBrush Fill { get => GetValue(FillProperty); set => SetValue(FillProperty, value); } public LineDashFrame() { UseLayoutRounding = true; } /// 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(); } } /// 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 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; } }