From 48555edbc6524368c183fa8a24ac23ae3a5fbf0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=89=BE=E7=AB=B9?= Date: Mon, 1 May 2023 00:10:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=8A=A8=E7=94=BB=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E4=B8=8D=E5=90=8C=E7=9A=84=E5=BD=A2=E7=8A=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Converters/ConectorValueConverter.cs | 12 ++++ .../Enums/ConnectorValueType.cs | 1 + .../Helpers/Extention.Object.cs | 10 ++++ .../Serializables/SelectableItemBase.cs | 16 +++++ .../UserControls/LineControl.xaml | 2 +- .../UserControls/LineControl.xaml.cs | 60 +++++++++++++++---- .../AdditionViewModel/AnimationViewModel.cs | 31 ++++++++++ .../Interface/IAnimationViewModel.cs | 15 +++++ .../ViewModels/AdditionViewModel/SharpPath.cs | 5 ++ .../Connector/LogicalConnectorInfo.cs | 4 ++ .../BaseViewModel/DiagramViewModel.cs | 4 +- .../LogicalGateItemViewModelBase.cs | 50 ++++++++++++---- .../Animations/PathAnimationViewModel.cs | 2 - 13 files changed, 183 insertions(+), 29 deletions(-) diff --git a/AIStudio.Wpf.DiagramDesigner/Converters/ConectorValueConverter.cs b/AIStudio.Wpf.DiagramDesigner/Converters/ConectorValueConverter.cs index 7eb4290..84c6205 100644 --- a/AIStudio.Wpf.DiagramDesigner/Converters/ConectorValueConverter.cs +++ b/AIStudio.Wpf.DiagramDesigner/Converters/ConectorValueConverter.cs @@ -1,4 +1,5 @@ using AIStudio.Wpf.DiagramDesigner; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; @@ -39,6 +40,17 @@ namespace AIStudio.Wpf.DiagramDesigner { return logicalConnectorInfo.ConnectorValue.ToString("f3"); } + else if (logicalConnectorInfo.ConnectorValueType == ConnectorValueType.JsonString) + { + if (logicalConnectorInfo.ConnectorString != null) + { + JObject obj = JObject.Parse(logicalConnectorInfo.ConnectorString); + if (obj.ContainsKey("Text")) + { + return obj["Text"].ToString(); + } + } + } else { return logicalConnectorInfo.ConnectorString; diff --git a/AIStudio.Wpf.DiagramDesigner/Enums/ConnectorValueType.cs b/AIStudio.Wpf.DiagramDesigner/Enums/ConnectorValueType.cs index fed1710..93f51d2 100644 --- a/AIStudio.Wpf.DiagramDesigner/Enums/ConnectorValueType.cs +++ b/AIStudio.Wpf.DiagramDesigner/Enums/ConnectorValueType.cs @@ -12,5 +12,6 @@ namespace AIStudio.Wpf.DiagramDesigner Bool = 2, ValueType = 99, String = 100, + JsonString = 101, } } diff --git a/AIStudio.Wpf.DiagramDesigner/Helpers/Extention.Object.cs b/AIStudio.Wpf.DiagramDesigner/Helpers/Extention.Object.cs index ca1b733..9b446c0 100644 --- a/AIStudio.Wpf.DiagramDesigner/Helpers/Extention.Object.cs +++ b/AIStudio.Wpf.DiagramDesigner/Helpers/Extention.Object.cs @@ -70,6 +70,16 @@ namespace AIStudio.Wpf.DiagramDesigner return JsonConvert.SerializeObject(obj); } + public static T ToObject(this string str) + { + return JsonConvert.DeserializeObject(str); + } + + public static object ToObject(this string str, Type type) + { + return JsonConvert.DeserializeObject(str, type); + } + public static JsonSerializerSettings Settings { get; set; } = new JsonSerializerSettings { DateFormatString = "yyyy-MM-dd HH:mm:ss.fff", diff --git a/AIStudio.Wpf.DiagramDesigner/Models/Serializables/SelectableItemBase.cs b/AIStudio.Wpf.DiagramDesigner/Models/Serializables/SelectableItemBase.cs index f44231f..21b687d 100644 --- a/AIStudio.Wpf.DiagramDesigner/Models/Serializables/SelectableItemBase.cs +++ b/AIStudio.Wpf.DiagramDesigner/Models/Serializables/SelectableItemBase.cs @@ -470,6 +470,22 @@ namespace AIStudio.Wpf.DiagramDesigner } } + [XmlAttribute] + public bool Repeat + { + get; set; + } + + public bool Start + { + get; set; + } + + public int Completed + { + get;set; + } + public event PropertyChangedEventHandler PropertyChanged; } diff --git a/AIStudio.Wpf.DiagramDesigner/UserControls/LineControl.xaml b/AIStudio.Wpf.DiagramDesigner/UserControls/LineControl.xaml index 5a96612..4368380 100644 --- a/AIStudio.Wpf.DiagramDesigner/UserControls/LineControl.xaml +++ b/AIStudio.Wpf.DiagramDesigner/UserControls/LineControl.xaml @@ -109,7 +109,7 @@ Data="{Binding AnimationViewModel.AnimationPath.Path}" Fill="{Binding AnimationViewModel.Color,Converter={StaticResource ColorBrushConverter}}" Width="{Binding AnimationViewModel.AnimationPath.Width}" - Height="{Binding ColorViewModel.AnimationPath.Height}" + Height="{Binding AnimationViewModel.AnimationPath.Height}" Panel.ZIndex="1" /> diff --git a/AIStudio.Wpf.DiagramDesigner/UserControls/LineControl.xaml.cs b/AIStudio.Wpf.DiagramDesigner/UserControls/LineControl.xaml.cs index 8a04b0f..7b162f8 100644 --- a/AIStudio.Wpf.DiagramDesigner/UserControls/LineControl.xaml.cs +++ b/AIStudio.Wpf.DiagramDesigner/UserControls/LineControl.xaml.cs @@ -42,7 +42,7 @@ namespace AIStudio.Wpf.DiagramDesigner if (this.DataContext is ConnectionViewModel connector && connector.AnimationViewModel != null) { connector.AnimationViewModel.PropertyChanged -= Connector_PropertyChanged; - connector.AnimationViewModel.PropertyChanged += Connector_PropertyChanged; + connector.AnimationViewModel.PropertyChanged += Connector_PropertyChanged; } this.ball.Visibility = Visibility.Collapsed; await DoAnimation(); @@ -56,6 +56,11 @@ namespace AIStudio.Wpf.DiagramDesigner case nameof(AnimationViewModel.Duration): await DoAnimation(); break; + case nameof(AnimationViewModel.Start): + await Application.Current.Dispatcher.BeginInvoke(async () => { + await DoAnimation(); + }); + break; } } @@ -64,26 +69,36 @@ namespace AIStudio.Wpf.DiagramDesigner { if (this.DataContext is ConnectionViewModel connector && connector.IsFullConnection) { - await System.Threading.Tasks.Task.Delay(100); + if (connector.AnimationViewModel.Repeat == false) + { + if (connector.AnimationViewModel.Start == false || connector.AnimationViewModel.Completed == 1) + { + return; + } + connector.AnimationViewModel.Completed = 1; + connector.AnimationViewModel.Start = false; + } + + await System.Threading.Tasks.Task.Delay(10); switch (connector.AnimationViewModel.Animation) { - case LineAnimation.None: - _story?.Stop(this); - ball.Visibility = Visibility.Collapsed; + case LineAnimation.None: + _story?.Stop(this); + ball.Visibility = Visibility.Collapsed; break; case LineAnimation.PathAnimation: if (connector.ColorViewModel.FillColor.BrushType == BrushType.SolidColorBrush && connector.ColorViewModel.FillColor.Color == Colors.White) { connector.ColorViewModel.FillColor.Color = Colors.Red; } - PathAnimation(connector.AnimationViewModel.Duration); + PathAnimation(connector.AnimationViewModel); break; case LineAnimation.DashAnimation: if (connector.ColorViewModel.LineDashStyle == LineDashStyle.None) { connector.ColorViewModel.LineDashStyle = LineDashStyle.Dash1; } - DashAnimation(connector.AnimationViewModel.Duration); + DashAnimation(connector.AnimationViewModel); break; } } @@ -91,14 +106,14 @@ namespace AIStudio.Wpf.DiagramDesigner Storyboard _story; - private void PathAnimation(double second) + private void PathAnimation(IAnimationViewModel animationViewModel) { this.ball.Visibility = Visibility.Visible; Canvas.SetTop(this.ball, -this.ball.ActualHeight / 2); Canvas.SetLeft(this.ball, -this.ball.ActualWidth / 2); - this.ball.RenderTransformOrigin = new Point(0.5, 0.5); + this.ball.RenderTransformOrigin = new Point(0.5, 0.5); TranslateTransform translate = new TranslateTransform(); RotateTransform rotate = new RotateTransform(); @@ -114,7 +129,7 @@ namespace AIStudio.Wpf.DiagramDesigner DoubleAnimationUsingPath animationX = new DoubleAnimationUsingPath(); animationX.PathGeometry = this.line.Data?.GetFlattenedPathGeometry(); animationX.Source = PathAnimationSource.X; - animationX.Duration = new Duration(TimeSpan.FromSeconds(second)); + animationX.Duration = new Duration(TimeSpan.FromSeconds(animationViewModel.Duration)); DoubleAnimationUsingPath animationY = new DoubleAnimationUsingPath(); animationY.PathGeometry = this.line.Data?.GetFlattenedPathGeometry(); @@ -134,7 +149,15 @@ namespace AIStudio.Wpf.DiagramDesigner _story.Children.Add(animationY); _story.Children.Add(animationAngle); _story.Completed += (s, d) => { - _story.Begin(this, true); + if (animationViewModel.Repeat) + { + _story.Begin(this, true); + } + else + { + this.ball.Visibility = Visibility.Collapsed; + animationViewModel.Completed = 100; + } }; Storyboard.SetTargetName(animationX, "translate"); Storyboard.SetTargetName(animationY, "translate"); @@ -147,12 +170,12 @@ namespace AIStudio.Wpf.DiagramDesigner } - private void DashAnimation(double second) + private void DashAnimation(IAnimationViewModel animationViewModel) { this.ball.Visibility = Visibility.Collapsed; - var animation = new DoubleAnimation(0, -10, new Duration(TimeSpan.FromSeconds(second))) + var animation = new DoubleAnimation(0, -10, new Duration(TimeSpan.FromSeconds(animationViewModel.Duration))) { RepeatBehavior = RepeatBehavior.Forever, }; @@ -163,6 +186,17 @@ namespace AIStudio.Wpf.DiagramDesigner _story = new Storyboard(); _story.RepeatBehavior = RepeatBehavior.Forever; _story.Children.Add(animation); + _story.Completed += (s, d) => { + if (animationViewModel.Repeat) + { + _story.Begin(this, true); + } + else + { + this.ball.Visibility = Visibility.Collapsed; + animationViewModel.Completed = 100; + } + }; _story.Begin(this, true); } diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/AnimationViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/AnimationViewModel.cs index f424054..db0a361 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/AnimationViewModel.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/AnimationViewModel.cs @@ -79,6 +79,37 @@ namespace AIStudio.Wpf.DiagramDesigner } } + private bool _repeat = true; + public bool Repeat + { + get + { + return _repeat; + } + set + { + SetProperty(ref _repeat, value); + } + } + + private bool _start; + public bool Start + { + get + { + return _start; + } + set + { + SetProperty(ref _start, value); + } + } + + public int Completed + { + get; set; + } + private void AnimationViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (sender == AnimationPath) diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/Interface/IAnimationViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/Interface/IAnimationViewModel.cs index 9a3ee2d..4d67f76 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/Interface/IAnimationViewModel.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/Interface/IAnimationViewModel.cs @@ -26,6 +26,21 @@ namespace AIStudio.Wpf.DiagramDesigner { get; set; } + + bool Repeat + { + get; set; + } + + bool Start + { + get; set; + } + + int Completed + { + get; set; + } event PropertyChangedEventHandler PropertyChanged; } } diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/SharpPath.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/SharpPath.cs index cb0230f..0b280c7 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/SharpPath.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/SharpPath.cs @@ -9,6 +9,11 @@ namespace AIStudio.Wpf.DiagramDesigner public static SharpPath Arrow { get; } = new SharpPath("M 0 -5 10 0 0 5 z", 10, 10, PathStyle.Arrow, SizeStyle.Middle); public static SharpPath Circle { get; } = new SharpPath("M 0, 0 a 5,5 0 1,0 10,0 a 5,5 0 1,0 -10,0", 10, 10, PathStyle.Circle, SizeStyle.Middle); public static SharpPath Square { get; } = new SharpPath("M 0 -5 10 -5 10 5 0 5 z", 10, 10, PathStyle.Square, SizeStyle.Middle); + public static SharpPath Triangle { get; } = new SharpPath("M1,21H23L12,2", 10, 10, PathStyle.Square, SizeStyle.Middle); + public static SharpPath Rhombus { get; } = new SharpPath("M 0,20 L 30 0 L 60,20 L 30,40 Z", 10, 10, PathStyle.Square, SizeStyle.Middle); + public static SharpPath Trapezoid { get; } = new SharpPath("M 0 0 H 60 L 50 40 H 10 Z", 10, 10, PathStyle.Square, SizeStyle.Middle); + public static SharpPath Pentagram { get; } = new SharpPath("M 9,2 11,7 17,7 12,10 14,15 9,12 4,15 6,10 1,7 7,7 Z", 10, 10, PathStyle.Square, SizeStyle.Middle); + public static SharpPath Hexagon { get; } = new SharpPath("M 0,20 L 10,0 H 50 L 60,20 L 50,40 H10 Z", 10, 10, PathStyle.Square, SizeStyle.Middle); public static readonly Dictionary ArrowDictionary = new Dictionary() { diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Connector/LogicalConnectorInfo.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Connector/LogicalConnectorInfo.cs index a02a117..67de55d 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Connector/LogicalConnectorInfo.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Connector/LogicalConnectorInfo.cs @@ -144,6 +144,10 @@ namespace AIStudio.Wpf.DiagramDesigner { return true; } + else if (logical.ConnectorValueType == ConnectorValueType.JsonString && this.ConnectorValueType == logical.ConnectorValueType) + { + return true; + } else if (logical.ConnectorValueType <= ConnectorValueType.ValueType && this.ConnectorValueType <= ConnectorValueType.ValueType) { return true; diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs index 040b7ce..ac7953b 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs @@ -1403,9 +1403,9 @@ namespace AIStudio.Wpf.DiagramDesigner } var logical = item as LogicalGateItemViewModelBase; - if (logical != null && logical.LogicalType > 0) + if (logical != null) { - logical.OrderNumber = Items.OfType().Count(p => (int)p.LogicalType > 0) + 1; + logical.OrderNumber = Items.OfType().Count() + 1; } var designerItemViewModelBase = item as DesignerItemViewModelBase; diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/LogicalGateItemViewModelBase.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/LogicalGateItemViewModelBase.cs index 7087579..fd11fd8 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/LogicalGateItemViewModelBase.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/LogicalGateItemViewModelBase.cs @@ -5,6 +5,7 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using AIStudio.Wpf.DiagramDesigner.Enums; @@ -253,14 +254,16 @@ namespace AIStudio.Wpf.DiagramDesigner continue; } - if (connector.SourceConnectorInfo.DataItem is LogicalGateItemViewModelBase) + if (connector.SourceConnectorInfo.DataItem is LogicalGateItemViewModelBase sourceItem) { var output = (connector.SourceConnectorInfo as LogicalConnectorInfo); - connector.ColorViewModel.LineColor.Color = output.ColorViewModel.FillColor.Color; - connector.ColorViewModel.FillColor.Color = output.ColorViewModel.FillColor.Color; - if (input.Value.CanAttachTo(output)) + if (EnableInputValue(connector, input.Value, output)) { + connector.ColorViewModel.LineColor.Color = output.ColorViewModel.FillColor.Color; + connector.ColorViewModel.FillColor.Color = output.ColorViewModel.FillColor.Color; + connector.AnimationViewModel.Color = output.ColorViewModel.FillColor.Color; + input.Value.ConnectorValue = output.ConnectorValue; input.Value.ConnectorString = output.ConnectorString; input.Value.ColorViewModel.FillColor.Color = connector.SourceConnectorInfo.ColorViewModel.FillColor.Color; @@ -272,13 +275,10 @@ namespace AIStudio.Wpf.DiagramDesigner { input.Value.ConnectorValueType = ((connector.SourceConnectorInfo as LogicalConnectorInfo).ConnectorValueType == ConnectorValueType.Bool) ? ConnectorValueType.Bool : ConnectorValueType.Int; } + + sourceItem.ClearOutputValue(connector, output); } - else - { - input.Value.ErrorCode = ConnectorErrorCode.ConnErr; - input.Value.ErrorMessage = "连接类型不匹配"; - input.Value.ColorViewModel.FillColor.Color = Colors.DarkRed; - } + sourceItem.StartAnimation(output); } } } @@ -310,16 +310,44 @@ namespace AIStudio.Wpf.DiagramDesigner } } } - else + else if (output.Value.ConnectorValueType <= ConnectorValueType.ValueType) { output.Value.ColorViewModel.FillColor.Color = Colors.Green; } } } + public virtual bool EnableInputValue(ConnectionViewModel connector, LogicalConnectorInfo input, LogicalConnectorInfo output) + { + if (!input.CanAttachTo(output)) + { + input.ErrorCode = ConnectorErrorCode.ConnErr; + input.ErrorMessage = "连接类型不匹配"; + input.ColorViewModel.FillColor.Color = Colors.DarkRed; + return false; + } + + return true; + } + + public virtual void ClearOutputValue(ConnectionViewModel connector, LogicalConnectorInfo output) + { + + } + + public virtual void StartAnimation(LogicalConnectorInfo output) + { + + } + protected ConnectionViewModel GetSourceItem(FullyCreatedConnectorInfo sinkConnector) { return Root?.Items.OfType().FirstOrDefault(p => p.SinkConnectorInfo == sinkConnector); } + + protected ConnectionViewModel GetSinkItem(FullyCreatedConnectorInfo sourceConnector) + { + return Root?.Items.OfType().FirstOrDefault(p => p.SourceConnectorInfo == sourceConnector); + } } } diff --git a/Demos/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Animations/PathAnimationViewModel.cs b/Demos/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Animations/PathAnimationViewModel.cs index 12f6fbc..2ea2379 100644 --- a/Demos/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Animations/PathAnimationViewModel.cs +++ b/Demos/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Animations/PathAnimationViewModel.cs @@ -29,12 +29,10 @@ namespace AIStudio.Wpf.DiagramDesigner.Demo.ViewModels DiagramViewModel.Add(node3); ConnectionViewModel connector1 = new ConnectionViewModel(DiagramViewModel, node1.RightConnector, node2.LeftConnector, DrawMode.ConnectingLineSmooth, RouterMode.RouterNormal); - connector1.ColorViewModel.FillColor.Color = Colors.Red; connector1.AnimationViewModel.Animation = LineAnimation.PathAnimation; DiagramViewModel.Add(connector1); ConnectionViewModel connector2 = new ConnectionViewModel(DiagramViewModel, node2.RightConnector, node3.RightConnector, DrawMode.ConnectingLineStraight, RouterMode.RouterOrthogonal); - connector2.ColorViewModel.FillColor.Color = Colors.Red; connector2.AnimationViewModel.Animation = LineAnimation.PathAnimation; DiagramViewModel.Add(connector2); }