2025-08-20 12:10:13 +08:00
|
|
|
|
using System.Globalization;
|
|
|
|
|
|
using System.Windows.Data;
|
|
|
|
|
|
|
2026-01-02 17:30:41 +08:00
|
|
|
|
namespace Melskin.Converters.Internal;
|
2025-08-20 12:10:13 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// CreateSlotClipGeometryConverter 是一个实现了 IMultiValueConverter 接口的类,用于根据给定的参数创建一个具有圆角的矩形几何图形。
|
|
|
|
|
|
/// 该转换器接受三个输入值:圆角半径、宽度和高度,并可选地接受一个表示边距的字符串参数。
|
|
|
|
|
|
/// 输出为 RectangleGeometry 对象,可用于定义 UI 元素的剪裁区域。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
internal class CreateSlotClipGeometryConverter : IMultiValueConverter
|
|
|
|
|
|
{
|
|
|
|
|
|
public static readonly CreateSlotClipGeometryConverter Instance = new();
|
|
|
|
|
|
|
|
|
|
|
|
//public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// if (values == null || values.Length < 4 ||
|
|
|
|
|
|
// values[0] is not CornerRadius radius ||
|
|
|
|
|
|
// values[1] is not double width ||
|
|
|
|
|
|
// values[2] is not double height ||
|
|
|
|
|
|
// values[3] is not double paddingValue)
|
|
|
|
|
|
// return null;
|
|
|
|
|
|
|
|
|
|
|
|
// var padding = new Thickness(paddingValue);
|
|
|
|
|
|
// var rectW = Math.Max(0, width - padding.Left - padding.Right);
|
|
|
|
|
|
// var rectH = Math.Max(0, height - padding.Top - padding.Bottom);
|
|
|
|
|
|
|
|
|
|
|
|
// var tl = Math.Max(0, radius.TopLeft);
|
|
|
|
|
|
// var tr = Math.Max(0, radius.TopRight);
|
|
|
|
|
|
// var br = Math.Max(0, radius.BottomRight);
|
|
|
|
|
|
// var bl = Math.Max(0, radius.BottomLeft);
|
|
|
|
|
|
|
|
|
|
|
|
// double left = padding.Left; double top = padding.Top; double right = left + rectW; double bottom = top + rectH;
|
|
|
|
|
|
|
|
|
|
|
|
// // 构造路径
|
|
|
|
|
|
// var figure = new PathFigure { IsClosed = true, IsFilled = true, StartPoint = new Point(left + tl, top) };
|
|
|
|
|
|
// var segments = new PathSegmentCollection
|
|
|
|
|
|
// {
|
|
|
|
|
|
// // Top line + TopRight arc
|
|
|
|
|
|
// new LineSegment(new Point(right - tr, top), true),
|
|
|
|
|
|
// new ArcSegment(new Point(right, top + tr), new Size(tr, tr), 0, false, SweepDirection.Clockwise, true),
|
|
|
|
|
|
// // Right line + BottomRight arc
|
|
|
|
|
|
// new LineSegment(new Point(right, bottom - br), true),
|
|
|
|
|
|
// new ArcSegment(new Point(right - br, bottom), new Size(br, br), 0, false, SweepDirection.Clockwise, true),
|
|
|
|
|
|
// // Bottom line + BottomLeft arc
|
|
|
|
|
|
// new LineSegment(new Point(left + bl, bottom), true),
|
|
|
|
|
|
// new ArcSegment(new Point(left, bottom - bl), new Size(bl, bl), 0, false, SweepDirection.Clockwise, true),
|
|
|
|
|
|
// // Left line + TopLeft arc
|
|
|
|
|
|
// new LineSegment(new Point(left, top + tl), true),
|
|
|
|
|
|
// new ArcSegment(new Point(left + tl, top), new Size(tl, tl), 0, false, SweepDirection.Clockwise, true)
|
|
|
|
|
|
// };
|
|
|
|
|
|
// figure.Segments = segments;
|
|
|
|
|
|
|
|
|
|
|
|
// var geometry = new PathGeometry();
|
|
|
|
|
|
// geometry.Figures.Add(figure);
|
|
|
|
|
|
// return geometry;
|
|
|
|
|
|
//}
|
2025-08-24 13:49:55 +08:00
|
|
|
|
public object? Convert(object[]? values, Type targetType, object parameter, CultureInfo culture)
|
2025-08-20 12:10:13 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (values == null || values.Length < 3 ||
|
|
|
|
|
|
values[0] is not CornerRadius radius ||
|
|
|
|
|
|
values[1] is not double width ||
|
|
|
|
|
|
values[2] is not double height)
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
|
|
var paramStr = parameter as string;
|
|
|
|
|
|
_ = double.TryParse(paramStr, out var margin);
|
|
|
|
|
|
|
|
|
|
|
|
var rectW = width - (2 * margin);
|
|
|
|
|
|
var rectH = height - (2 * margin);
|
|
|
|
|
|
|
|
|
|
|
|
if (rectW < 0) rectW = 0;
|
|
|
|
|
|
if (rectH < 0) rectH = 0;
|
|
|
|
|
|
|
|
|
|
|
|
var left = margin;
|
|
|
|
|
|
var top = margin;
|
|
|
|
|
|
var right = left + rectW;
|
|
|
|
|
|
var bottom = top + rectH;
|
|
|
|
|
|
|
|
|
|
|
|
var tl = Math.Max(0, radius.TopLeft);
|
|
|
|
|
|
var tr = Math.Max(0, radius.TopRight);
|
|
|
|
|
|
var br = Math.Max(0, radius.BottomRight);
|
|
|
|
|
|
var bl = Math.Max(0, radius.BottomLeft);
|
|
|
|
|
|
|
|
|
|
|
|
var figure = new PathFigure
|
|
|
|
|
|
{
|
|
|
|
|
|
IsClosed = true,
|
|
|
|
|
|
IsFilled = true,
|
|
|
|
|
|
StartPoint = new Point(left + tl, top)
|
|
|
|
|
|
};
|
|
|
|
|
|
var segments = new PathSegmentCollection
|
|
|
|
|
|
{
|
|
|
|
|
|
// Top line + TopRight arc
|
|
|
|
|
|
new LineSegment(new Point(right - tr, top), true),
|
|
|
|
|
|
new ArcSegment(new Point(right, top + tr), new Size(tr, tr), 0, false, SweepDirection.Clockwise, true),
|
|
|
|
|
|
// Right line + BottomRight arc
|
|
|
|
|
|
new LineSegment(new Point(right, bottom - br), true),
|
|
|
|
|
|
new ArcSegment(new Point(right - br, bottom), new Size(br, br), 0, false, SweepDirection.Clockwise, true),
|
|
|
|
|
|
// Bottom line + BottomLeft arc
|
|
|
|
|
|
new LineSegment(new Point(left + bl, bottom), true),
|
|
|
|
|
|
new ArcSegment(new Point(left, bottom - bl), new Size(bl, bl), 0, false, SweepDirection.Clockwise, true),
|
|
|
|
|
|
// Left line + TopLeft arc
|
|
|
|
|
|
new LineSegment(new Point(left, top + tl), true),
|
|
|
|
|
|
new ArcSegment(new Point(left + tl, top), new Size(tl, tl), 0, false, SweepDirection.Clockwise, true)
|
|
|
|
|
|
};
|
|
|
|
|
|
figure.Segments = segments;
|
|
|
|
|
|
|
|
|
|
|
|
var geometry = new PathGeometry();
|
|
|
|
|
|
geometry.Figures.Add(figure);
|
|
|
|
|
|
return geometry;
|
|
|
|
|
|
}
|
|
|
|
|
|
//public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// var radius = (CornerRadius)values[0];
|
|
|
|
|
|
// var width = (double)values[1];
|
|
|
|
|
|
// var height = (double)values[2];
|
|
|
|
|
|
|
|
|
|
|
|
// var paramStr = parameter as string;
|
|
|
|
|
|
// _ = double.TryParse(paramStr, out var margin);
|
|
|
|
|
|
|
|
|
|
|
|
// var rectW = width - (2 * margin);
|
|
|
|
|
|
// var rectH = height - (2 * margin);
|
|
|
|
|
|
|
|
|
|
|
|
// //防止初始化时候小于0
|
|
|
|
|
|
// if (rectW < 0)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// rectW = 0;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// if (rectH < 0)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// rectH = 0;
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// RectangleGeometry rectangleGeometry = new()
|
|
|
|
|
|
// {
|
|
|
|
|
|
// RadiusX = radius.BottomLeft,
|
|
|
|
|
|
// RadiusY = radius.TopRight,
|
|
|
|
|
|
// Rect = new Rect(margin, margin, rectW, rectH),
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
// return rectangleGeometry;
|
|
|
|
|
|
//}
|
|
|
|
|
|
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotImplementedException();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|