From 4c37fb97721cd954a8820aab82cb561b72c355a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=89=BE=E7=AB=B9?= Date: Sun, 22 Jan 2023 21:46:59 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E7=82=B9=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=87=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewModels/MainWindowViewModel.cs | 2 + AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml | 8 +- .../AIStudio.Wpf.DiagramDesigner.csproj | 1 + .../AttachedProperties/SelectionProps.cs | 35 ++-- .../Controls/DesignerCanvas.cs | 4 +- .../Models/Serializables/ConnectionItem.cs | 6 + .../Models/Serializables/LinkLabelItem.cs | 10 ++ .../UserControls/DiagramControl.xaml | 32 ++-- .../UserControls/TextControl.xaml.cs | 17 +- .../AdditionViewModel/ColorViewModel.cs | 2 +- .../BaseViewModel/ConnectorPoint.cs | 15 +- .../BaseViewModel/ConnectorViewModel.cs | 152 +++++++++------- .../DesignerItemViewModelBase.cs | 15 +- .../BaseViewModel/LinkLabelModel.cs | 167 ++++++++++++++++-- .../SelectableDesignerItemViewModelBase.cs | 12 ++ .../ViewModels/ISelectable.cs | 15 +- 16 files changed, 371 insertions(+), 122 deletions(-) create mode 100644 AIStudio.Wpf.DiagramDesigner/Models/Serializables/LinkLabelItem.cs diff --git a/AIStudio.Wpf.DiagramApp/ViewModels/MainWindowViewModel.cs b/AIStudio.Wpf.DiagramApp/ViewModels/MainWindowViewModel.cs index 506d16a..293f6c0 100644 --- a/AIStudio.Wpf.DiagramApp/ViewModels/MainWindowViewModel.cs +++ b/AIStudio.Wpf.DiagramApp/ViewModels/MainWindowViewModel.cs @@ -1103,6 +1103,8 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels private void SelectedColorExecuted(object para) { + if (para == null) return; + switch (ColorType) { case Models.ColorType.Text: DiagramsViewModel?.SetFont(new FontViewModel() { FontColor = (Color)para }, "FontColor"); break; diff --git a/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml b/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml index e6ff2f6..2a50018 100644 --- a/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml +++ b/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml @@ -998,10 +998,10 @@ - - + + - + - + diff --git a/AIStudio.Wpf.DiagramDesigner/AIStudio.Wpf.DiagramDesigner.csproj b/AIStudio.Wpf.DiagramDesigner/AIStudio.Wpf.DiagramDesigner.csproj index 0014bbf..98b4cb5 100644 --- a/AIStudio.Wpf.DiagramDesigner/AIStudio.Wpf.DiagramDesigner.csproj +++ b/AIStudio.Wpf.DiagramDesigner/AIStudio.Wpf.DiagramDesigner.csproj @@ -24,6 +24,7 @@ + diff --git a/AIStudio.Wpf.DiagramDesigner/AttachedProperties/SelectionProps.cs b/AIStudio.Wpf.DiagramDesigner/AttachedProperties/SelectionProps.cs index a1ccf0d..25d424d 100644 --- a/AIStudio.Wpf.DiagramDesigner/AttachedProperties/SelectionProps.cs +++ b/AIStudio.Wpf.DiagramDesigner/AttachedProperties/SelectionProps.cs @@ -43,33 +43,28 @@ namespace AIStudio.Wpf.DiagramDesigner static void Fe_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { - SelectableDesignerItemViewModelBase selectableDesignerItemViewModelBase = - (SelectableDesignerItemViewModelBase)((FrameworkElement)sender).DataContext; - - if(selectableDesignerItemViewModelBase != null && selectableDesignerItemViewModelBase.IsHitTestVisible) + if (((FrameworkElement)sender).DataContext is ISelectable selectable) { - if ((Keyboard.Modifiers & (ModifierKeys.Shift | ModifierKeys.Control)) != ModifierKeys.None) + if (selectable.IsHitTestVisible) { - if ((Keyboard.Modifiers & (ModifierKeys.Shift)) != ModifierKeys.None) + if ((Keyboard.Modifiers & (ModifierKeys.Shift | ModifierKeys.Control)) != ModifierKeys.None) { - selectableDesignerItemViewModelBase.IsSelected = !selectableDesignerItemViewModelBase.IsSelected; - } + if ((Keyboard.Modifiers & (ModifierKeys.Shift)) != ModifierKeys.None) + { + selectable.IsSelected = !selectable.IsSelected; + } - if ((Keyboard.Modifiers & (ModifierKeys.Control)) != ModifierKeys.None) + if ((Keyboard.Modifiers & (ModifierKeys.Control)) != ModifierKeys.None) + { + selectable.IsSelected = !selectable.IsSelected; + } + } + else if (!selectable.IsSelected) { - selectableDesignerItemViewModelBase.IsSelected = !selectableDesignerItemViewModelBase.IsSelected; + selectable.AddToSelection(true); } } - else if (!selectableDesignerItemViewModelBase.IsSelected) - { - foreach (SelectableDesignerItemViewModelBase item in selectableDesignerItemViewModelBase.Parent.SelectedItems) - item.IsSelected = false; - - selectableDesignerItemViewModelBase.Parent.SelectedItems.Clear(); - //selectableDesignerItemViewModelBase.IsSelected = true; - selectableDesignerItemViewModelBase.Parent.SelectionService.AddToSelection(selectableDesignerItemViewModelBase); - } - } + } } } } diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs b/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs index 0ba8e65..b4d242c 100644 --- a/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs +++ b/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs @@ -413,7 +413,9 @@ namespace AIStudio.Wpf.DiagramDesigner protected override void OnPreviewKeyDown(KeyEventArgs e) { - base.OnPreviewKeyDown(e); + base.OnPreviewKeyDown(e); + + //FFE6E6FA } protected override Size MeasureOverride(Size constraint) diff --git a/AIStudio.Wpf.DiagramDesigner/Models/Serializables/ConnectionItem.cs b/AIStudio.Wpf.DiagramDesigner/Models/Serializables/ConnectionItem.cs index fa923c2..8e1cc9a 100644 --- a/AIStudio.Wpf.DiagramDesigner/Models/Serializables/ConnectionItem.cs +++ b/AIStudio.Wpf.DiagramDesigner/Models/Serializables/ConnectionItem.cs @@ -116,5 +116,11 @@ namespace AIStudio.Wpf.DiagramDesigner Vertices = SerializeHelper.DeserializePointList(value); } } + + [XmlArray] + public List Connectors + { + get; set; + } } } diff --git a/AIStudio.Wpf.DiagramDesigner/Models/Serializables/LinkLabelItem.cs b/AIStudio.Wpf.DiagramDesigner/Models/Serializables/LinkLabelItem.cs new file mode 100644 index 0000000..28af46f --- /dev/null +++ b/AIStudio.Wpf.DiagramDesigner/Models/Serializables/LinkLabelItem.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace AIStudio.Wpf.DiagramDesigner.Models.Serializables +{ + public class LinkLabelItem + { + } +} diff --git a/AIStudio.Wpf.DiagramDesigner/UserControls/DiagramControl.xaml b/AIStudio.Wpf.DiagramDesigner/UserControls/DiagramControl.xaml index 36597e1..502911b 100644 --- a/AIStudio.Wpf.DiagramDesigner/UserControls/DiagramControl.xaml +++ b/AIStudio.Wpf.DiagramDesigner/UserControls/DiagramControl.xaml @@ -541,11 +541,6 @@ - @@ -600,7 +595,7 @@ - + @@ -616,7 +611,24 @@ - + + + + + + + + + + + + + + + @@ -635,7 +647,7 @@ - @@ -651,14 +663,14 @@ - - diff --git a/AIStudio.Wpf.DiagramDesigner/UserControls/TextControl.xaml.cs b/AIStudio.Wpf.DiagramDesigner/UserControls/TextControl.xaml.cs index ba57f08..d61317d 100644 --- a/AIStudio.Wpf.DiagramDesigner/UserControls/TextControl.xaml.cs +++ b/AIStudio.Wpf.DiagramDesigner/UserControls/TextControl.xaml.cs @@ -18,14 +18,14 @@ namespace AIStudio.Wpf.DiagramDesigner /// public partial class TextControl : UserControl { - public static readonly DependencyProperty TextProperty = DependencyProperty.Register( - "DoubleEdit", typeof(bool), typeof(TextControl), new FrameworkPropertyMetadata( + public static readonly DependencyProperty DoubleEditProperty = DependencyProperty.Register( + nameof(DoubleEdit), typeof(bool), typeof(TextControl), new FrameworkPropertyMetadata( true)); public bool DoubleEdit { - get => (bool)GetValue(TextProperty); - set => SetValue(TextProperty, value); + get => (bool)GetValue(DoubleEditProperty); + set => SetValue(DoubleEditProperty, value); } public TextControl() @@ -48,7 +48,10 @@ namespace AIStudio.Wpf.DiagramDesigner PART_ShowText.SelectionStart = PART_ShowText.Text.Length; } - (this.DataContext as SelectableDesignerItemViewModelBase).PropertyChanged += TextControl_PropertyChanged; + if (this.DataContext is ISelectable selectable) + { + selectable.PropertyChanged += TextControl_PropertyChanged; + } TextControl_PropertyChanged(this.DataContext, new System.ComponentModel.PropertyChangedEventArgs("IsSelected")); } @@ -56,9 +59,9 @@ namespace AIStudio.Wpf.DiagramDesigner { if (e.PropertyName == "IsSelected") { - if (sender is SelectableDesignerItemViewModelBase itemViewModelBase) + if (sender is ISelectable selectable) { - if (itemViewModelBase.IsSelected == false) + if (selectable.IsSelected == false) { PART_ShowText.Visibility = Visibility.Collapsed; PART_TextBlock.Visibility = Visibility.Visible; diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/ColorViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/ColorViewModel.cs index 76025de..69b2a12 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/ColorViewModel.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/ColorViewModel.cs @@ -20,7 +20,7 @@ namespace AIStudio.Wpf.DiagramDesigner public ColorViewModel() { LineColor = new ColorObject() { Color = Colors.Gray }; - FillColor = new ColorObject() { Color = Colors.Transparent }; + FillColor = new ColorObject() { Color = Colors.White }; } private IColorObject _lineColor; public IColorObject LineColor diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/ConnectorPoint.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/ConnectorPoint.cs index ab7d142..4e8cf92 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/ConnectorPoint.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/ConnectorPoint.cs @@ -125,7 +125,20 @@ namespace AIStudio.Wpf.DiagramDesigner { SetProperty(ref _colorViewModel, value); } - } + } + + private IFontViewModel _fontViewModel; + public IFontViewModel FontViewModel + { + get + { + return _fontViewModel; + } + set + { + SetProperty(ref _fontViewModel, value); + } + } public static ConnectorPoint operator -(ConnectorPoint a, ConnectorPoint b) { diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/ConnectorViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/ConnectorViewModel.cs index d0333ef..b243b1e 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/ConnectorViewModel.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/ConnectorViewModel.cs @@ -5,10 +5,10 @@ using System.ComponentModel; using System.Linq; using System.Windows; using System.Windows.Input; -//using System.Windows; using System.Windows.Media; using AIStudio.Wpf.DiagramDesigner.Geometrys; using AIStudio.Wpf.DiagramDesigner.Helpers; +using SvgPathProperties; namespace AIStudio.Wpf.DiagramDesigner { @@ -39,7 +39,7 @@ namespace AIStudio.Wpf.DiagramDesigner protected virtual void Init(FullyCreatedConnectorInfo sourceConnectorInfo, ConnectorInfoBase sinkConnectorInfo) { this.Parent = sourceConnectorInfo.DataItem.Parent; - + if (Parent != null && Parent.ColorViewModel != null) { this.ColorViewModel = CopyHelper.Mapper(Parent.ColorViewModel); @@ -60,7 +60,7 @@ namespace AIStudio.Wpf.DiagramDesigner this.SourceConnectorInfo = sourceConnectorInfo; this.SinkConnectorInfo = sinkConnectorInfo; DeleteConnectionCommand = new SimpleCommand(DeleteConnection); - AddVertexCommand = new SimpleCommand(AddVertex); + AddVertexCommand = new SimpleCommand(AddVertex); } protected void LoadDesignerItemViewModel(SelectableDesignerItemBase designerbase) @@ -112,7 +112,7 @@ namespace AIStudio.Wpf.DiagramDesigner } set { - SetProperty(ref _sourceB, value); + SetProperty(ref _sourceB, value); } } @@ -177,7 +177,7 @@ namespace AIStudio.Wpf.DiagramDesigner } private set { - SetProperty(ref _area, value); + SetProperty(ref _area, value); } } @@ -241,7 +241,18 @@ namespace AIStudio.Wpf.DiagramDesigner } } - public List Labels { get; set; } = new List(); + private ObservableCollection _labels = new ObservableCollection(); + public ObservableCollection Labels + { + get + { + return _labels; + } + private set + { + SetProperty(ref _labels, value); + } + } public virtual Dictionary PropertiesSetting { @@ -277,7 +288,7 @@ namespace AIStudio.Wpf.DiagramDesigner set { SetProperty(ref _sinkConnectorInfo, value); - + } } @@ -351,6 +362,12 @@ namespace AIStudio.Wpf.DiagramDesigner vertice.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler; } break; + case nameof(Labels): + foreach (var label in Labels) + { + label.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler; + } + break; case nameof(SourceConnectorInfo): SourceA = PointHelper.GetPointForConnector(SourceConnectorInfo); (SourceConnectorInfo.DataItem as INotifyPropertyChanged).PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler; @@ -362,6 +379,12 @@ namespace AIStudio.Wpf.DiagramDesigner (((FullyCreatedConnectorInfo)SinkConnectorInfo).DataItem as INotifyPropertyChanged).PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler; } break; + case nameof(IsSelected): + if (IsSelected == false) + { + Labels.FirstOrDefault()?.AddToSelection(false); + } + break; } } @@ -395,13 +418,35 @@ namespace AIStudio.Wpf.DiagramDesigner { switch (e.PropertyName) { - case nameof(ConnectorPoint.Left): - case nameof(ConnectorPoint.Top): + case nameof(ConnectorPoint.X): + case nameof(ConnectorPoint.Y): UpdatePathGeneratorResult(); break; } } + else if (sender is LinkLabelModel linkLabelModel) + { + switch (e.PropertyName) + { + case nameof(ConnectorPoint.X): + { + if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs) + { + linkLabelModel.UpdateOffsetX((double)valuePropertyChangedEventArgs.OldValue, (double)valuePropertyChangedEventArgs.NewValue); + } + break; + } + case nameof(ConnectorPoint.Y): + { + if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs) + { + linkLabelModel.UpdateOffsetY((double)valuePropertyChangedEventArgs.OldValue, (double)valuePropertyChangedEventArgs.NewValue); + } + break; + } + } + } } private void UpdateArea() @@ -485,6 +530,12 @@ namespace AIStudio.Wpf.DiagramDesigner StartAngle = PathGeneratorResult.SourceMarkerAngle; EndAngle = PathGeneratorResult.TargetMarkerAngle; + + var paths = Labels.Count > 0 ? PathGeneratorResult.Paths.Select(p => new SvgPath(p)).ToArray() : Array.Empty(); + foreach (var label in Labels) + { + label.UpdatePosition(paths); + } } private void DeleteConnection(object args) @@ -496,22 +547,6 @@ namespace AIStudio.Wpf.DiagramDesigner } } - private void AddVertex(object parameter) - { - MouseButtonEventArgs mosueArg = ((EventToCommandArgs)parameter).EventArgs as MouseButtonEventArgs; - var position = mosueArg.GetPosition(((EventToCommandArgs)parameter).Sender as IInputElement); - - var vertice = new LinkVertexModel(this, new PointBase(position.X, position.Y)); - vertice.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler; - Vertices.Add(vertice); - UpdatePathGeneratorResult(); - - if (!((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)) - { - ShouldInsertAnchor = false; - } - } - private (PointBase? source, PointBase? target) FindConnectionPoints(PointBase[] route) { if (IsPortless) // Portless @@ -544,7 +579,7 @@ namespace AIStudio.Wpf.DiagramDesigner if (port == null) return null; - if (marker == null) + if (marker == 0) return port.MiddlePosition; var pt = port.Position; @@ -588,6 +623,22 @@ namespace AIStudio.Wpf.DiagramDesigner } #region 双击添加 + private void AddVertex(object parameter) + { + MouseButtonEventArgs mosueArg = ((EventToCommandArgs)parameter).EventArgs as MouseButtonEventArgs; + var position = mosueArg.GetPosition(((EventToCommandArgs)parameter).Sender as IInputElement); + + var vertice = new LinkVertexModel(this, new PointBase(position.X, position.Y)); + vertice.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler; + Vertices.Add(vertice); + UpdatePathGeneratorResult(); + + if (!((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)) + { + ShouldInsertAnchor = false; + } + } + protected override void ExecuteEditCommand(object param) { if (this.OutTextItem != null) return; @@ -596,48 +647,25 @@ namespace AIStudio.Wpf.DiagramDesigner public void AddText(string text) { - if (this.Parent is IDiagramViewModel) - { - var diagramVM = this.Parent as IDiagramViewModel; + var label = new LinkLabelModel(this, ""); + label.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler; + label.IsSelected = true; + Labels.Add(label); - TextDesignerItemViewModel textitem = new TextDesignerItemViewModel(); - textitem.ItemWidth = Double.NaN; - textitem.ItemHeight = double.NaN; - //if (this.PathMode == DrawMode.ConnectingLineBoundary.ToString()) - //{ - // var mid = (int)(ConnectionPoints.Count / 2); - // var p = PathGenerators.SegmentMiddlePoint(ConnectionPoints[mid - 1], ConnectionPoints[mid]); - // textitem.Left = this.Area.Left + p.X + 2; - // textitem.Top = this.Area.Top + p.Y - 15; - //} - //else - { - textitem.Left = this.Area.Left + this.Area.Width / 2 - 16; - textitem.Top = this.Area.Top + this.Area.Height / 2 - 5; - } - textitem.Watermark = null; - textitem.ZIndex = diagramVM.Items.Count; - textitem.ParentId = this.Id; - textitem.ParentItem = this; - textitem.ColorViewModel.FillColor = new ColorObject() { Color = Colors.White }; - textitem.Text = text; - - diagramVM.DirectAddItemCommand.Execute(textitem); - - this.OutTextItem = textitem; - } + var paths = Labels.Count > 0 ? PathGeneratorResult.Paths.Select(p => new SvgPath(p)).ToArray() : Array.Empty(); + label.UpdatePosition(paths); } public void OutTextItemLocation(RectangleBase oldArea, RectangleBase newArea) { - if (this.OutTextItem is TextDesignerItemViewModel text) - { - var oldpoint = new PointBase(oldArea.Left + oldArea.Width / 2, oldArea.Top + oldArea.Height / 2); - var newpoint = new PointBase(newArea.Left + newArea.Width / 2, newArea.Top + newArea.Height / 2); + //if (this.OutTextItem is TextDesignerItemViewModel text) + //{ + // var oldpoint = new PointBase(oldArea.Left + oldArea.Width / 2, oldArea.Top + oldArea.Height / 2); + // var newpoint = new PointBase(newArea.Left + newArea.Width / 2, newArea.Top + newArea.Height / 2); - text.Left = text.Left + newpoint.X - oldpoint.X; - text.Top = text.Top + newpoint.Y - oldpoint.Y; - } + // text.Left = text.Left + newpoint.X - oldpoint.X; + // text.Top = text.Top + newpoint.Y - oldpoint.Y; + //} } #endregion } diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs index 5790a6a..0385525 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs @@ -188,7 +188,20 @@ namespace AIStudio.Wpf.DiagramDesigner } } - public bool ShowRotate { get; set; } = true; + private bool _showRotate = false; + [Browsable(true)] + public bool ShowRotate + { + get + { + return _showRotate; + } + set + { + SetProperty(ref _showRotate, value); + } + } + public bool ShowArrow { get; set; } = true; private double _left; diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/LinkLabelModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/LinkLabelModel.cs index a8c6563..8ab14d8 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/LinkLabelModel.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/LinkLabelModel.cs @@ -1,32 +1,171 @@ -namespace AIStudio.Wpf.DiagramDesigner +using System.Linq; +using AIStudio.Wpf.DiagramDesigner.Geometrys; +using SvgPathProperties; + +namespace AIStudio.Wpf.DiagramDesigner { - public class LinkLabelModel : ConnectorPoint + public class LinkLabelModel : ConnectorPoint, ISelectable { - public LinkLabelModel(ConnectorViewModel parent, string id, string content, double? distance = null, ConnectorPoint offset = null) + public LinkLabelModel(ConnectorViewModel parent, string content, double? distance = null, PointBase? offset = null) { Parent = parent; - Content = content; + Text = content; Distance = distance; - Offset = offset; + Offset = offset ?? new PointBase(); + FontViewModel = Parent.FontViewModel; + ColorViewModel = Parent.ColorViewModel; } - public LinkLabelModel(ConnectorViewModel parent, string content, double? distance = null, ConnectorPoint offset = null) + public ConnectorViewModel Parent { - Parent = parent; - Content = content; - Distance = distance; - Offset = offset; + get; + } + + public bool IsHitTestVisible + { + get + { + return Parent.IsHitTestVisible; + } + } + + private string _text; + public string Text + { + get + { + return _text; + } + set + { + SetProperty(ref _text, value); + } } - public ConnectorViewModel Parent { get; } - public string Content { get; set; } /// /// 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 ConnectorPoint Offset { get; set; } + 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) + { + foreach (var item in Parent.Labels) + item.IsSelected = false; + + if (selected == true) + { + IsSelected = true; + } + } + } } diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableDesignerItemViewModelBase.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableDesignerItemViewModelBase.cs index 045a8b1..66fa8d7 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableDesignerItemViewModelBase.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableDesignerItemViewModelBase.cs @@ -364,6 +364,18 @@ namespace AIStudio.Wpf.DiagramDesigner IsSelected = select; } + public void AddToSelection(bool selected) + { + foreach (SelectableDesignerItemViewModelBase item in Parent.SelectedItems) + item.IsSelected = false; + + Parent.SelectedItems.Clear(); + if (selected == true) + { + Parent.SelectionService.AddToSelection(this); + } + } + private void FontViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == "FontCase") diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/ISelectable.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/ISelectable.cs index 98d4686..f6acb43 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/ISelectable.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/ISelectable.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; @@ -7,6 +8,18 @@ namespace AIStudio.Wpf.DiagramDesigner { public interface ISelectable { - bool IsSelected { get; set; } + bool IsSelected + { + get; set; + } + + bool IsHitTestVisible + { + get; + } + + void AddToSelection(bool selected); + + event PropertyChangedEventHandler PropertyChanged; } }