using System.Linq; using AIStudio.Wpf.DiagramDesigner.Geometrys; using SvgPathProperties; namespace AIStudio.Wpf.DiagramDesigner { public class ConnectorLabelModel : ConnectorPoint, ISelectable { public ConnectorLabelModel(ConnectorViewModel parent, string content, double? distance = null, PointBase? offset = null) { Parent = parent; Text = content; Distance = distance; Offset = offset ?? new PointBase(); FontViewModel = Parent.FontViewModel; ColorViewModel = Parent.ColorViewModel; DeleteLabelCommand = new SimpleCommand(DeleteLabel); } public ConnectorViewModel Parent { get; } public bool IsHitTestVisible { get { return Parent.IsHitTestVisible; } } private string _text; public string Text { get { return _text; } set { SetProperty(ref _text, value); } } /// /// 3 types of values are possible: /// - A number between 0 and 1: Position relative to the link's length /// - A positive number, greater than 1: Position away from the start /// - A negative number, less than 0: Position away from the end /// 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 SimpleCommand DeleteLabelCommand { get; set; } 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) { foreach (var item in Parent.Labels.ToList()) item.IsSelected = false; if (selected == true) { IsSelected = true; } } private void DeleteLabel(object parameter) { if (parameter is ConnectorLabelModel label) { Parent.Labels.Remove(label); } } } }