添加几个裁剪参数

This commit is contained in:
艾竹
2024-01-01 20:37:06 +08:00
parent c2bce7c912
commit a611f1b11b
5 changed files with 473 additions and 34 deletions

View File

@@ -5,6 +5,7 @@ using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using System.Windows.Resources;
using AIStudio.Wpf.DiagramDesigner.Helpers;
using AIStudio.Wpf.DiagramDesigner.Models;
@@ -220,6 +221,48 @@ namespace AIStudio.Wpf.DiagramDesigner
#endregion
#region AutoGrowth
public static readonly DependencyProperty AutoGrowthProperty =
DependencyProperty.Register(nameof(AutoGrowth),
typeof(bool),
typeof(DesignerCanvas),
new FrameworkPropertyMetadata(true));
public bool AutoGrowth
{
get
{
return (bool)GetValue(AutoGrowthProperty);
}
set
{
SetValue(AutoGrowthProperty, value);
}
}
#endregion
#region CornerRadius
public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.Register(nameof(CornerRadius),
typeof(CornerRadius),
typeof(DesignerCanvas),
new FrameworkPropertyMetadata(new CornerRadius()));
public CornerRadius CornerRadius
{
get
{
return (CornerRadius)GetValue(CornerRadiusProperty);
}
set
{
SetValue(CornerRadiusProperty, value);
}
}
#endregion
#region GridMarginSize mm
public static readonly DependencyProperty GridMarginSizeProperty =
@@ -291,6 +334,164 @@ namespace AIStudio.Wpf.DiagramDesigner
DrawGrid(dc, rect);
}
public static Geometry GetRoundRectangle(Rect baseRect, Thickness borderThickness, CornerRadius cornerRadius)
{
// Normalizing the corner radius
if (cornerRadius.TopLeft < double.Epsilon)
{
cornerRadius.TopLeft = 0.0;
}
if (cornerRadius.TopRight < double.Epsilon)
{
cornerRadius.TopRight = 0.0;
}
if (cornerRadius.BottomLeft < double.Epsilon)
{
cornerRadius.BottomLeft = 0.0;
}
if (cornerRadius.BottomRight < double.Epsilon)
{
cornerRadius.BottomRight = 0.0;
}
// Taking the border thickness into account
var leftHalf = borderThickness.Left * 0.5;
if (leftHalf < double.Epsilon)
{
leftHalf = 0.0;
}
var topHalf = borderThickness.Top * 0.5;
if (topHalf < double.Epsilon)
{
topHalf = 0.0;
}
var rightHalf = borderThickness.Right * 0.5;
if (rightHalf < double.Epsilon)
{
rightHalf = 0.0;
}
var bottomHalf = borderThickness.Bottom * 0.5;
if (bottomHalf < double.Epsilon)
{
bottomHalf = 0.0;
}
// Create the rectangles for the corners that needs to be curved in the base rectangle
// TopLeft Rectangle
var topLeftRect = new Rect(
baseRect.Location.X,
baseRect.Location.Y,
Math.Max(0.0, cornerRadius.TopLeft - leftHalf),
Math.Max(0.0, cornerRadius.TopLeft - rightHalf));
// TopRight Rectangle
var topRightRect = new Rect(
baseRect.Location.X + baseRect.Width - cornerRadius.TopRight + rightHalf,
baseRect.Location.Y,
Math.Max(0.0, cornerRadius.TopRight - rightHalf),
Math.Max(0.0, cornerRadius.TopRight - topHalf));
// BottomRight Rectangle
var bottomRightRect = new Rect(
baseRect.Location.X + baseRect.Width - cornerRadius.BottomRight + rightHalf,
baseRect.Location.Y + baseRect.Height - cornerRadius.BottomRight + bottomHalf,
Math.Max(0.0, cornerRadius.BottomRight - rightHalf),
Math.Max(0.0, cornerRadius.BottomRight - bottomHalf));
// BottomLeft Rectangle
var bottomLeftRect = new Rect(
baseRect.Location.X,
baseRect.Location.Y + baseRect.Height - cornerRadius.BottomLeft + bottomHalf,
Math.Max(0.0, cornerRadius.BottomLeft - leftHalf),
Math.Max(0.0, cornerRadius.BottomLeft - bottomHalf));
// Adjust the _width of the TopLeft and TopRight rectangles so that they are proportional to the _width of the baseRect
if (topLeftRect.Right > topRightRect.Left)
{
var newWidth = (topLeftRect.Width / (topLeftRect.Width + topRightRect.Width)) * baseRect.Width;
topLeftRect = new Rect(topLeftRect.Location.X, topLeftRect.Location.Y, newWidth, topLeftRect.Height);
topRightRect = new Rect(
baseRect.Left + newWidth,
topRightRect.Location.Y,
Math.Max(0.0, baseRect.Width - newWidth),
topRightRect.Height);
}
// Adjust the height of the TopRight and BottomRight rectangles so that they are proportional to the height of the baseRect
if (topRightRect.Bottom > bottomRightRect.Top)
{
var newHeight = (topRightRect.Height / (topRightRect.Height + bottomRightRect.Height)) * baseRect.Height;
topRightRect = new Rect(topRightRect.Location.X, topRightRect.Location.Y, topRightRect.Width, newHeight);
bottomRightRect = new Rect(
bottomRightRect.Location.X,
baseRect.Top + newHeight,
bottomRightRect.Width,
Math.Max(0.0, baseRect.Height - newHeight));
}
// Adjust the _width of the BottomLeft and BottomRight rectangles so that they are proportional to the _width of the baseRect
if (bottomRightRect.Left < bottomLeftRect.Right)
{
var newWidth = (bottomLeftRect.Width / (bottomLeftRect.Width + bottomRightRect.Width)) * baseRect.Width;
bottomLeftRect = new Rect(bottomLeftRect.Location.X, bottomLeftRect.Location.Y, newWidth, bottomLeftRect.Height);
bottomRightRect = new Rect(
baseRect.Left + newWidth,
bottomRightRect.Location.Y,
Math.Max(0.0, baseRect.Width - newWidth),
bottomRightRect.Height);
}
// Adjust the height of the TopLeft and BottomLeft rectangles so that they are proportional to the height of the baseRect
if (bottomLeftRect.Top < topLeftRect.Bottom)
{
var newHeight = (topLeftRect.Height / (topLeftRect.Height + bottomLeftRect.Height)) * baseRect.Height;
topLeftRect = new Rect(topLeftRect.Location.X, topLeftRect.Location.Y, topLeftRect.Width, newHeight);
bottomLeftRect = new Rect(
bottomLeftRect.Location.X,
baseRect.Top + newHeight,
bottomLeftRect.Width,
Math.Max(0.0, baseRect.Height - newHeight));
}
var roundedRectGeometry = new StreamGeometry();
using (var context = roundedRectGeometry.Open())
{
// Begin from the Bottom of the TopLeft Arc and proceed clockwise
context.BeginFigure(topLeftRect.BottomLeft, true, true);
// TopLeft Arc
context.ArcTo(topLeftRect.TopRight, topLeftRect.Size, 0, false, SweepDirection.Clockwise, true, true);
// Top Line
context.LineTo(topRightRect.TopLeft, true, true);
// TopRight Arc
context.ArcTo(topRightRect.BottomRight, topRightRect.Size, 0, false, SweepDirection.Clockwise, true, true);
// Right Line
context.LineTo(bottomRightRect.TopRight, true, true);
// BottomRight Arc
context.ArcTo(bottomRightRect.BottomLeft, bottomRightRect.Size, 0, false, SweepDirection.Clockwise, true, true);
// Bottom Line
context.LineTo(bottomLeftRect.BottomRight, true, true);
// BottomLeft Arc
context.ArcTo(bottomLeftRect.TopLeft, bottomLeftRect.Size, 0, false, SweepDirection.Clockwise, true, true);
}
return roundedRectGeometry;
}
#endregion
protected virtual void DrawGrid(DrawingContext dc, Rect rect)
{
//using .5 forces wpf to draw a single pixel line
@@ -302,7 +503,6 @@ namespace AIStudio.Wpf.DiagramDesigner
dc.DrawLine(new Pen(new SolidColorBrush(GridColor), 1), new Point(i, GridMarginSize.Height), new Point(i, rect.Height - GridMarginSize.Height));
dc.DrawLine(new Pen(new SolidColorBrush(GridColor), 1), new Point(rect.Width - GridMarginSize.Width, GridMarginSize.Height), new Point(rect.Width - GridMarginSize.Width, rect.Height - GridMarginSize.Height));
}
#endregion
#region Format/Move
private void _service_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
@@ -616,29 +816,36 @@ namespace AIStudio.Wpf.DiagramDesigner
protected override Size MeasureOverride(Size constraint)
{
Size size = new Size();
foreach (UIElement element in this.InternalChildren)
if (AutoGrowth)
{
double left = Canvas.GetLeft(element);
double top = Canvas.GetTop(element);
left = double.IsNaN(left) ? 0 : left;
top = double.IsNaN(top) ? 0 : top;
//measure desired size for each child
element.Measure(constraint);
Size desiredSize = element.DesiredSize;
if (!double.IsNaN(desiredSize.Width) && !double.IsNaN(desiredSize.Height))
Size size = new Size();
foreach (UIElement element in this.InternalChildren)
{
size.Width = Math.Max(size.Width, left + desiredSize.Width);
size.Height = Math.Max(size.Height, top + desiredSize.Height);
}
}
// add margin
size.Width += 10;
size.Height += 10;
double left = Canvas.GetLeft(element);
double top = Canvas.GetTop(element);
left = double.IsNaN(left) ? 0 : left;
top = double.IsNaN(top) ? 0 : top;
return size;
//measure desired size for each child
element.Measure(constraint);
Size desiredSize = element.DesiredSize;
if (!double.IsNaN(desiredSize.Width) && !double.IsNaN(desiredSize.Height))
{
size.Width = Math.Max(size.Width, left + desiredSize.Width);
size.Height = Math.Max(size.Height, top + desiredSize.Height);
}
}
// add margin
size.Width += 10;
size.Height += 10;
return size;
}
else
{
return base.MeasureOverride(constraint);
}
}
private Connector HitTesting(Point hitPoint)