2023-01-22 21:46:59 +08:00
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using AIStudio.Wpf.DiagramDesigner.Geometrys;
|
|
|
|
|
|
using SvgPathProperties;
|
|
|
|
|
|
|
|
|
|
|
|
namespace AIStudio.Wpf.DiagramDesigner
|
2023-01-08 09:22:37 +08:00
|
|
|
|
{
|
2023-01-22 22:10:39 +08:00
|
|
|
|
public class ConnectorLabelModel : ConnectorPoint, ISelectable
|
2023-01-08 09:22:37 +08:00
|
|
|
|
{
|
2023-01-22 22:10:39 +08:00
|
|
|
|
public ConnectorLabelModel(ConnectorViewModel parent, string content, double? distance = null, PointBase? offset = null)
|
2023-01-08 09:22:37 +08:00
|
|
|
|
{
|
|
|
|
|
|
Parent = parent;
|
2023-01-22 21:46:59 +08:00
|
|
|
|
Text = content;
|
2023-01-08 09:22:37 +08:00
|
|
|
|
Distance = distance;
|
2023-01-22 21:46:59 +08:00
|
|
|
|
Offset = offset ?? new PointBase();
|
|
|
|
|
|
FontViewModel = Parent.FontViewModel;
|
|
|
|
|
|
ColorViewModel = Parent.ColorViewModel;
|
2023-01-08 09:22:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-22 21:46:59 +08:00
|
|
|
|
public ConnectorViewModel Parent
|
2023-01-08 09:22:37 +08:00
|
|
|
|
{
|
2023-01-22 21:46:59 +08:00
|
|
|
|
get;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool IsHitTestVisible
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return Parent.IsHitTestVisible;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private string _text;
|
|
|
|
|
|
public string Text
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _text;
|
|
|
|
|
|
}
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
SetProperty(ref _text, value);
|
|
|
|
|
|
}
|
2023-01-08 09:22:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 3 types of values are possible:
|
|
|
|
|
|
/// <para>- A number between 0 and 1: Position relative to the link's length</para>
|
|
|
|
|
|
/// <para>- A positive number, greater than 1: Position away from the start</para>
|
|
|
|
|
|
/// <para>- A negative number, less than 0: Position away from the end</para>
|
|
|
|
|
|
/// </summary>
|
2023-01-22 21:46:59 +08:00
|
|
|
|
public double? Distance
|
|
|
|
|
|
{
|
|
|
|
|
|
get; set;
|
|
|
|
|
|
}
|
|
|
|
|
|
public PointBase Offset
|
|
|
|
|
|
{
|
|
|
|
|
|
get; set;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool _isSelected;
|
|
|
|
|
|
public bool IsSelected
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _isSelected;
|
|
|
|
|
|
}
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SetProperty(ref _isSelected, value))
|
|
|
|
|
|
{
|
|
|
|
|
|
//如果没有文字,失去焦点自动清除
|
|
|
|
|
|
if (_isSelected == false && string.IsNullOrEmpty(Text))
|
|
|
|
|
|
{
|
|
|
|
|
|
Parent.Labels.Remove(this);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override PointBase Position
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return new PointBase(Parent.Area.Left + Left, Parent.Area.Top + Top);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override PointBase MiddlePosition => new PointBase(Parent.Area.Left + Left + ConnectorWidth / 2, Parent.Area.Top + Top + ConnectorHeight / 2);
|
|
|
|
|
|
|
|
|
|
|
|
private bool updating = false;
|
|
|
|
|
|
|
|
|
|
|
|
public void UpdatePosition(SvgPath[] paths)
|
|
|
|
|
|
{
|
|
|
|
|
|
var position = FindPosition(paths);
|
|
|
|
|
|
if (position == null)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
updating = true;
|
|
|
|
|
|
X = position.Value.X;
|
|
|
|
|
|
Y = position.Value.Y;
|
|
|
|
|
|
updating = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public PointBase? FindPosition(SvgPath[] paths)
|
|
|
|
|
|
{
|
|
|
|
|
|
var totalLength = paths.Sum(p => p.Length);
|
|
|
|
|
|
|
|
|
|
|
|
double length;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (Distance >= 0 && Distance <= 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
length = Distance.Value * totalLength;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (Distance > 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
length = Distance.Value;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (Distance < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
length = totalLength + Distance.Value;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
length = totalLength * (Parent.Labels.IndexOf(this) + 1) / (Parent.Labels.Count + 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var path in paths)
|
|
|
|
|
|
{
|
|
|
|
|
|
var pathLength = path.Length;
|
|
|
|
|
|
if (length < pathLength)
|
|
|
|
|
|
{
|
|
|
|
|
|
var pt = path.GetPointAtLength(length);
|
|
|
|
|
|
return new PointBase(pt.X + Offset.X, pt.Y + Offset.Y);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
length -= pathLength;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void UpdateOffsetX(double oldvalue, double newvalue)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (updating == true) return;
|
|
|
|
|
|
|
|
|
|
|
|
Offset += new VectorBase(newvalue - oldvalue, 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void UpdateOffsetY(double oldvalue, double newvalue)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (updating == true) return;
|
|
|
|
|
|
|
|
|
|
|
|
Offset += new VectorBase(0, newvalue - oldvalue);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void AddToSelection(bool selected)
|
|
|
|
|
|
{
|
2023-01-22 22:10:39 +08:00
|
|
|
|
foreach (var item in Parent.Labels.ToList())
|
2023-01-22 21:46:59 +08:00
|
|
|
|
item.IsSelected = false;
|
|
|
|
|
|
|
|
|
|
|
|
if (selected == true)
|
|
|
|
|
|
{
|
|
|
|
|
|
IsSelected = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-08 09:22:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|