Files
ShrlAlgoToolkit/AntDesignWPF/Converters/ArcEndPointConverter.cs
2025-07-31 20:12:24 +08:00

64 lines
2.5 KiB
C#

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;
//https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/blob/master/src/MaterialDesignThemes.Wpf/Converters/CircularProgressBar/ArcEndPointConverter.cs
namespace AntDesignWPF.Converters
{
public class ArcEndPointConverter : MarkupExtension, IMultiValueConverter
{
/// <summary>
/// CircularProgressBar draws two arcs to support a full circle at 100 %.
/// With one arc at 100 % the start point is identical the end point, so nothing is drawn.
/// Midpoint at half of current percentage is the endpoint of the first arc
/// and the start point of the second arc.
/// </summary>
public const string ParameterMidPoint = "MidPoint";
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
double actualWidth = values[0].ExtractDouble();
double value = values[1].ExtractDouble();
double minimum = values[2].ExtractDouble();
double maximum = values[3].ExtractDouble();
if (new[] { actualWidth, value, minimum, maximum }.AnyNan())
return Binding.DoNothing;
if (values.Length == 5)
{
double fullIndeterminateScaling = values[4].ExtractDouble();
if (!double.IsNaN(fullIndeterminateScaling) && fullIndeterminateScaling > 0.0)
{
value = (maximum - minimum) * fullIndeterminateScaling;
}
}
double percent = maximum <= minimum ? 1.0 : (value - minimum) / (maximum - minimum);
if (Equals(parameter, ParameterMidPoint))
percent /= 2;
double degrees = 360 * percent;
double radians = degrees * (Math.PI / 180);
var centre = new Point(actualWidth / 2, actualWidth / 2);
double hypotenuseRadius = (actualWidth / 2);
double adjacent = Math.Cos(radians) * hypotenuseRadius;
double opposite = Math.Sin(radians) * hypotenuseRadius;
return new Point(centre.X + opposite, centre.Y - adjacent);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException();
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
}