From 5a9bcc03f33f518aa98293dd96c47f87602e1989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=89=BE=E7=AB=B9?= Date: Sun, 11 Jun 2023 23:58:22 +0800 Subject: [PATCH] =?UTF-8?q?Revert=20"Revert=20"block=20=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E6=8B=96=E6=8B=BD=E5=88=B0=E5=86=85=E9=83=A8=EF=BC=8C=E8=BF=98?= =?UTF-8?q?=E6=9C=89=E5=B0=91=E9=87=8F=E9=97=AE=E9=A2=98=E5=BE=85=E8=A7=A3?= =?UTF-8?q?=E5=86=B3""?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit fcd7beb193b1a87856c5a28163cc50403c6317e0. --- AIStudio.Wpf.DiagramApp/App.xaml | 3 +- .../Models/CustomToolBoxData.cs | 16 +- .../ViewModels/BlockViewModel.cs | 48 ++ .../ViewModels/MainWindowViewModel.cs | 9 + .../ViewModels/PageViewModel.cs | 30 +- .../ViewModels/SFCViewModel.cs | 2 +- .../ViewModels/ScriptViewModel.cs | 13 +- .../ViewModels/ToolBoxViewModel.cs | 9 +- AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml | 112 +++-- ...esigner.Additionals_c3dwds1m_wpftmp.csproj | 309 +++++++++++++ ...esigner.Additionals_ltmcgkh5_wpftmp.csproj | 300 ++++++++++++ ...esigner.Additionals_uoedrdjs_wpftmp.csproj | 235 ++++++++++ .../AttachedProperties/DragAndDropProps.cs | 2 + .../AttachedProperties/WidthAndHeightProps.cs | 100 ++++ .../Controls/BlockConnector.cs | 33 ++ .../Controls/DesignerCanvas.cs | 154 +++++-- .../Controls/DragThumb.cs | 58 +-- .../Controls/ItemsContainer.cs | 200 ++++++++ .../Controls/ResizeThumb.cs | 20 +- .../Controls/RotateThumb.cs | 4 +- .../Enums/DiagramType.cs | 3 +- .../Geometrys/PointBase.cs | 6 + .../Helpers/PointHelper.cs | 4 +- .../Models/DragObject.cs | 33 +- .../Models/ToolBoxData.cs | 7 +- .../Themes/ConnectorItem.xaml | 59 ++- .../Themes/DesignerItem.xaml | 67 ++- .../UserControls/ConnectorContainer.xaml.cs | 4 +- .../UserControls/DiagramControl.xaml | 19 +- .../Container/ItemsContainerInfo.cs | 213 +++++++++ .../DesignerItemViewModelBase.cs | 62 ++- .../BaseViewModel/DiagramViewModel.cs | 158 ++++++- .../BaseViewModel/DiagramViewModelHelper.cs | 4 +- .../BlockContainDesignerItemViewModel.cs | 60 +++ .../BlockContainListDesignerItemViewModel.cs | 51 ++ .../BlockDesignerItemViewModel.cs | 64 ++- .../DefaultViewModel/GifImageItemViewModel.cs | 4 +- .../ViewModels/IDiagramViewModel.cs | 4 + Extensions/AIStudio.Wpf.Block/A.png | Bin 0 -> 11835 bytes .../AIStudio.Wpf.Block.csproj | 26 ++ .../AIStudio.Wpf.Block_4a4h4ycz_wpftmp.csproj | 246 ++++++++++ .../AIStudio.Wpf.Block_attaon4q_wpftmp.csproj | 244 ++++++++++ .../AIStudio.Wpf.Block_axsfel0m_wpftmp.csproj | 177 +++++++ .../AIStudio.Wpf.Block_gkma3gbh_wpftmp.csproj | 244 ++++++++++ .../AIStudio.Wpf.Block_ohjhbtlx_wpftmp.csproj | 244 ++++++++++ .../Controls/BlockDecorator.cs | 114 +++++ .../AIStudio.Wpf.Block/Controls/BlockPanel.cs | 114 +++++ .../Controls/EndBlockBorder.cs | 144 ++++++ .../Controls/NextBlockBorder.cs | 164 +++++++ .../Controls/NextFor2BlockPanel.cs | 435 ++++++++++++++++++ .../Controls/NextForBlockPanel.cs | 309 +++++++++++++ .../Controls/OperationBlockBorder.cs | 114 +++++ .../Controls/StartBlockBorder.cs | 147 ++++++ .../Controls/VariableBlockBorder.cs | 114 +++++ .../AIStudio.Wpf.Block/Models/BlockType.cs | 138 ++++++ .../Models/ConstParameter.cs | 16 + .../AIStudio.Wpf.Block/Models/IParameter.cs | 16 + .../AIStudio.Wpf.Block/Models/VarParameter.cs | 13 + .../Themes/BlockItemViewModel.xaml | 68 +++ .../AIStudio.Wpf.Block/Themes/Brushes.xaml | 30 ++ .../AIStudio.Wpf.Block/Themes/Geometries.xaml | 6 + .../AddBlockItemViewModel.cs | 64 +++ .../ControlBlockItemViewModel.cs | 36 ++ .../KeyboardPressBlockItemViewModel.cs | 47 ++ .../ControlModules/StartBlockItemViewModel.cs | 30 ++ .../WaitTimeBlockItemViewModel.cs | 50 ++ .../VariableBlockItemViewModel.cs | 50 ++ .../AIStudio.Wpf.SFC_gn4tlqoy_wpftmp.csproj | 236 ++++++++++ .../AIStudio.Wpf.SFC_hjulhjj0_wpftmp.csproj | 236 ++++++++++ ...AIStudio.Wpf.Script_5k10wu0u_wpftmp.csproj | 203 ++++++++ ...AIStudio.Wpf.Script_a4fgwrgk_wpftmp.csproj | 276 +++++++++++ ...AIStudio.Wpf.Script_l225ygvw_wpftmp.csproj | 276 +++++++++++ ...AIStudio.Wpf.Script_vs4rptnz_wpftmp.csproj | 268 +++++++++++ 73 files changed, 7132 insertions(+), 242 deletions(-) create mode 100644 AIStudio.Wpf.DiagramApp/ViewModels/BlockViewModel.cs create mode 100644 AIStudio.Wpf.DiagramDesigner.Additionals/AIStudio.Wpf.DiagramDesigner.Additionals_c3dwds1m_wpftmp.csproj create mode 100644 AIStudio.Wpf.DiagramDesigner.Additionals/AIStudio.Wpf.DiagramDesigner.Additionals_ltmcgkh5_wpftmp.csproj create mode 100644 AIStudio.Wpf.DiagramDesigner.Additionals/AIStudio.Wpf.DiagramDesigner.Additionals_uoedrdjs_wpftmp.csproj create mode 100644 AIStudio.Wpf.DiagramDesigner/AttachedProperties/WidthAndHeightProps.cs create mode 100644 AIStudio.Wpf.DiagramDesigner/Controls/BlockConnector.cs create mode 100644 AIStudio.Wpf.DiagramDesigner/Controls/ItemsContainer.cs create mode 100644 AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Container/ItemsContainerInfo.cs create mode 100644 AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/BlockContainDesignerItemViewModel.cs create mode 100644 AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/BlockContainListDesignerItemViewModel.cs create mode 100644 Extensions/AIStudio.Wpf.Block/A.png create mode 100644 Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block.csproj create mode 100644 Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_4a4h4ycz_wpftmp.csproj create mode 100644 Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_attaon4q_wpftmp.csproj create mode 100644 Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_axsfel0m_wpftmp.csproj create mode 100644 Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_gkma3gbh_wpftmp.csproj create mode 100644 Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_ohjhbtlx_wpftmp.csproj create mode 100644 Extensions/AIStudio.Wpf.Block/Controls/BlockDecorator.cs create mode 100644 Extensions/AIStudio.Wpf.Block/Controls/BlockPanel.cs create mode 100644 Extensions/AIStudio.Wpf.Block/Controls/EndBlockBorder.cs create mode 100644 Extensions/AIStudio.Wpf.Block/Controls/NextBlockBorder.cs create mode 100644 Extensions/AIStudio.Wpf.Block/Controls/NextFor2BlockPanel.cs create mode 100644 Extensions/AIStudio.Wpf.Block/Controls/NextForBlockPanel.cs create mode 100644 Extensions/AIStudio.Wpf.Block/Controls/OperationBlockBorder.cs create mode 100644 Extensions/AIStudio.Wpf.Block/Controls/StartBlockBorder.cs create mode 100644 Extensions/AIStudio.Wpf.Block/Controls/VariableBlockBorder.cs create mode 100644 Extensions/AIStudio.Wpf.Block/Models/BlockType.cs create mode 100644 Extensions/AIStudio.Wpf.Block/Models/ConstParameter.cs create mode 100644 Extensions/AIStudio.Wpf.Block/Models/IParameter.cs create mode 100644 Extensions/AIStudio.Wpf.Block/Models/VarParameter.cs create mode 100644 Extensions/AIStudio.Wpf.Block/Themes/BlockItemViewModel.xaml create mode 100644 Extensions/AIStudio.Wpf.Block/Themes/Brushes.xaml create mode 100644 Extensions/AIStudio.Wpf.Block/Themes/Geometries.xaml create mode 100644 Extensions/AIStudio.Wpf.Block/ViewModels/ArithmeticModules/AddBlockItemViewModel.cs create mode 100644 Extensions/AIStudio.Wpf.Block/ViewModels/ControlModules/ControlBlockItemViewModel.cs create mode 100644 Extensions/AIStudio.Wpf.Block/ViewModels/ControlModules/KeyboardPressBlockItemViewModel.cs create mode 100644 Extensions/AIStudio.Wpf.Block/ViewModels/ControlModules/StartBlockItemViewModel.cs create mode 100644 Extensions/AIStudio.Wpf.Block/ViewModels/EventModules/WaitTimeBlockItemViewModel.cs create mode 100644 Extensions/AIStudio.Wpf.Block/ViewModels/VariableModules/VariableBlockItemViewModel.cs create mode 100644 Extensions/AIStudio.Wpf.SFC/AIStudio.Wpf.SFC_gn4tlqoy_wpftmp.csproj create mode 100644 Extensions/AIStudio.Wpf.SFC/AIStudio.Wpf.SFC_hjulhjj0_wpftmp.csproj create mode 100644 Extensions/AIStudio.Wpf.Script/AIStudio.Wpf.Script_5k10wu0u_wpftmp.csproj create mode 100644 Extensions/AIStudio.Wpf.Script/AIStudio.Wpf.Script_a4fgwrgk_wpftmp.csproj create mode 100644 Extensions/AIStudio.Wpf.Script/AIStudio.Wpf.Script_l225ygvw_wpftmp.csproj create mode 100644 Extensions/AIStudio.Wpf.Script/AIStudio.Wpf.Script_vs4rptnz_wpftmp.csproj diff --git a/AIStudio.Wpf.DiagramApp/App.xaml b/AIStudio.Wpf.DiagramApp/App.xaml index 7e1527f..5142858 100644 --- a/AIStudio.Wpf.DiagramApp/App.xaml +++ b/AIStudio.Wpf.DiagramApp/App.xaml @@ -16,7 +16,8 @@ - + + diff --git a/AIStudio.Wpf.DiagramApp/Models/CustomToolBoxData.cs b/AIStudio.Wpf.DiagramApp/Models/CustomToolBoxData.cs index a8a8b0f..24d4637 100644 --- a/AIStudio.Wpf.DiagramApp/Models/CustomToolBoxData.cs +++ b/AIStudio.Wpf.DiagramApp/Models/CustomToolBoxData.cs @@ -14,7 +14,7 @@ namespace AIStudio.Wpf.DiagramApp.Models { public class PathToolBoxData : ToolBoxData { - public PathToolBoxData(string icon, Type type, double width = 32, double height = 32, Size? desiredSize = null, string description = null) : base(null, icon, type, width, height, desiredSize, description) + public PathToolBoxData(string icon, Type type, double width = 32, double height = 32, Size? desiredSize = null, Size? desiredMinSize = null, string description = null) : base(null, icon, type, width, height, desiredSize, desiredMinSize, description) { ColorViewModel.FillColor.Color = Colors.Orange; } @@ -23,7 +23,7 @@ namespace AIStudio.Wpf.DiagramApp.Models public class TextToolBoxData : ToolBoxData { - public TextToolBoxData(string text, Type type, double width = 32, double height = 32, Size? desiredSize = null, string description = null) : base(text, null, type, width, height, desiredSize, description) + public TextToolBoxData(string text, Type type, double width = 32, double height = 32, Size? desiredSize = null, Size? desiredMinSize = null, string description = null) : base(text, null, type, width, height, desiredSize, desiredMinSize, description) { ColorViewModel.FillColor.Color = Colors.Orange; } @@ -32,7 +32,7 @@ namespace AIStudio.Wpf.DiagramApp.Models public class EllipseTextToolBoxData : ToolBoxData { - public EllipseTextToolBoxData(string text, Type type, double width = 32, double height = 32, Size? desiredSize = null, string description = null) : base(text, null, type, width, height, desiredSize, description) + public EllipseTextToolBoxData(string text, Type type, double width = 32, double height = 32, Size? desiredSize = null, Size? desiredMinSize = null, string description = null) : base(text, null, type, width, height, desiredSize, desiredMinSize, description) { ColorViewModel.FillColor.Color = Colors.Orange; } @@ -41,7 +41,7 @@ namespace AIStudio.Wpf.DiagramApp.Models public class ImageToolBoxData : ToolBoxData { - public ImageToolBoxData(string icon, Type type, double width = 32, double height = 32, Size? desiredSize = null, string description = null) : base(null, icon, type, width, height, desiredSize, description) + public ImageToolBoxData(string icon, Type type, double width = 32, double height = 32, Size? desiredSize = null, Size? desiredMinSize = null, string description = null) : base(null, icon, type, width, height, desiredSize, desiredMinSize, description) { } @@ -57,7 +57,7 @@ namespace AIStudio.Wpf.DiagramApp.Models { get; set; } - public DesignerItemToolBoxData(DesignerItemBase designerItemBase, string filename, Type type, double width = 32, double height = 32, Size? desiredSize = null, string description = null) : base(null, null, type, width, height, desiredSize, description) + public DesignerItemToolBoxData(DesignerItemBase designerItemBase, string filename, Type type, double width = 32, double height = 32, Size? desiredSize = null, Size? desiredMinSize = null, string description = null) : base(null, null, type, width, height, desiredSize, desiredMinSize, description) { Addition = designerItemBase; DesignerItemViewModel = Activator.CreateInstance(type, null, designerItemBase) as DesignerItemViewModelBase; @@ -84,7 +84,7 @@ namespace AIStudio.Wpf.DiagramApp.Models { get; set; } - public MultipleDesignerItemToolBoxData(SerializableObject designerItemBase, string filename, double width = 32, double height = 32, Size? desiredSize = null, string description = null) : base(null, null, typeof(List), width, height, desiredSize, description) + public MultipleDesignerItemToolBoxData(SerializableObject designerItemBase, string filename, double width = 32, double height = 32, Size? desiredSize = null, Size? desiredMinSize = null, string description = null) : base(null, null, typeof(List), width, height, desiredSize, desiredMinSize, description) { SelectableDesignerItemViewModels = designerItemBase.ToObject(); @@ -111,7 +111,7 @@ namespace AIStudio.Wpf.DiagramApp.Models public class SvgToolBoxData : ToolBoxData { - public SvgToolBoxData(string filename, Type type, double width = 32, double height = 32, Size? desiredSize = null, string description = null) : base(null, filename, type, width, height, desiredSize, description) + public SvgToolBoxData(string filename, Type type, double width = 32, double height = 32, Size? desiredSize = null, Size? desiredMinSize = null, string description = null) : base(null, filename, type, width, height, desiredSize, desiredMinSize, description) { ColorViewModel.FillColor.Color = Colors.Blue; } @@ -119,7 +119,7 @@ namespace AIStudio.Wpf.DiagramApp.Models public class MediaToolBoxData : ToolBoxData { - public MediaToolBoxData(string icon, Type type, double width = 32, double height = 32, Size? desiredSize = null, string description = null) : base(icon, null, type, width, height, desiredSize, description) + public MediaToolBoxData(string icon, Type type, double width = 32, double height = 32, Size? desiredSize = null, Size? desiredMinSize = null, string description = null) : base(icon, null, type, width, height, desiredSize, desiredMinSize, description) { } diff --git a/AIStudio.Wpf.DiagramApp/ViewModels/BlockViewModel.cs b/AIStudio.Wpf.DiagramApp/ViewModels/BlockViewModel.cs new file mode 100644 index 0000000..21e1260 --- /dev/null +++ b/AIStudio.Wpf.DiagramApp/ViewModels/BlockViewModel.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +//using AIStudio.Wpf.Block.ViewModels; +using AIStudio.Wpf.DiagramApp.Models; +using AIStudio.Wpf.DiagramDesigner; + +namespace AIStudio.Wpf.DiagramApp.ViewModels +{ + internal class BlockViewModel : PageViewModel + { + public BlockViewModel(string title, string status, DiagramType diagramType) : base(title, status, diagramType) + { + + } + public BlockViewModel(string filename, DiagramDocument diagramDocument) : base(filename, diagramDocument) + { + + } + + protected override void InitDiagramViewModel() + { + base.InitDiagramViewModel(); + + DiagramViewModel.DiagramOption.LayoutOption.ShowGrid = false; + } + + protected override void Init(bool initNew) + { + base.Init(initNew); + + //StartBlockItemViewModel start = new StartBlockItemViewModel(DiagramViewModel) { Left = 28, Top = 28 }; + //DiagramViewModel.Add(start); + + //WaitTimeBlockItemViewModel waittime = new WaitTimeBlockItemViewModel(DiagramViewModel) { Left = 28, Top = 28 }; + //DiagramViewModel.Add(waittime); + + //AddBlockItemViewModel add = new AddBlockItemViewModel(DiagramViewModel) { Left = 28, Top = 28 }; + //DiagramViewModel.Add(add); + + //KeyboardPressBlockItemViewModel keyboardPress = new KeyboardPressBlockItemViewModel(DiagramViewModel) { Left = 28, Top = 28 }; + //DiagramViewModel.Add(keyboardPress); + } + } +} diff --git a/AIStudio.Wpf.DiagramApp/ViewModels/MainWindowViewModel.cs b/AIStudio.Wpf.DiagramApp/ViewModels/MainWindowViewModel.cs index 19d3573..a3b77a2 100644 --- a/AIStudio.Wpf.DiagramApp/ViewModels/MainWindowViewModel.cs +++ b/AIStudio.Wpf.DiagramApp/ViewModels/MainWindowViewModel.cs @@ -21,6 +21,7 @@ using AIStudio.Wpf.DiagramDesigner.ViewModels; using AIStudio.Wpf.DiagramDesigner.ViewModels.BaseViewModel; using AIStudio.Wpf.Mind; using AIStudio.Wpf.Mind.Models; +using ControlzEx.Controls; namespace AIStudio.Wpf.DiagramApp.ViewModels { @@ -545,6 +546,10 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels { flow = new DrawingViewModel(filename, diagram); } + else if (diagram.DiagramType == DiagramType.Block) + { + flow = new BlockViewModel(filename, diagram); + } else { flow = new PageViewModel(filename, diagram); @@ -668,6 +673,10 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels { PageViewModel = new DrawingViewModel(NewNameHelper.GetNewName(PageViewModels.Select(p => p.Title), "新建-"), "*", (DiagramType)Enum.Parse(typeof(DiagramType), type)); } + else if (type == DiagramType.Block.ToString()) + { + PageViewModel = new BlockViewModel(NewNameHelper.GetNewName(PageViewModels.Select(p => p.Title), "新建-"), "*", (DiagramType)Enum.Parse(typeof(DiagramType), type)); + } else { PageViewModel = new PageViewModel(NewNameHelper.GetNewName(PageViewModels.Select(p => p.Title), "新建-"), "*", (DiagramType)Enum.Parse(typeof(DiagramType), type)); diff --git a/AIStudio.Wpf.DiagramApp/ViewModels/PageViewModel.cs b/AIStudio.Wpf.DiagramApp/ViewModels/PageViewModel.cs index 5c3c94c..71d5659 100644 --- a/AIStudio.Wpf.DiagramApp/ViewModels/PageViewModel.cs +++ b/AIStudio.Wpf.DiagramApp/ViewModels/PageViewModel.cs @@ -20,6 +20,7 @@ using ZXing; using AIStudio.Wpf.DiagramDesigner.Helpers; using AIStudio.Wpf.DiagramDesigner.ViewModels; using AIStudio.Wpf.DiagramDesigner.ViewModels.BaseViewModel; +using System.Threading.Tasks; namespace AIStudio.Wpf.DiagramApp.ViewModels { @@ -34,29 +35,48 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels } } + public PageViewModel(string title, string status, DiagramType diagramType, string subType = null) { Title = title; Status = status; DiagramType = diagramType; SubType = subType; - Init(true); + } public PageViewModel(string filename) { FileName = filename; string ext = Path.GetExtension(filename); - var diagramDocument = OpenFile(filename, ext); - OpenFile(diagramDocument, ext); + DiagramDocument = OpenFile(filename, ext); } public PageViewModel(string filename, DiagramDocument diagramDocument) { FileName = filename; - string ext = Path.GetExtension(filename); - OpenFile(diagramDocument, ext); + DiagramDocument = diagramDocument; } + DiagramDocument DiagramDocument; + public virtual void View_Loaded(object sender, EventArgs e) + { + //await Task.Run(() => { + //Application.Current.Dispatcher.Invoke(() => { + if (string.IsNullOrEmpty(FileName)) + { + Init(true); + } + else + { + string ext = Path.GetExtension(FileName); + OpenFile(DiagramDocument, ext); + } + //}); + //}); + + } + + protected virtual void InitDiagramViewModel() { diff --git a/AIStudio.Wpf.DiagramApp/ViewModels/SFCViewModel.cs b/AIStudio.Wpf.DiagramApp/ViewModels/SFCViewModel.cs index 77065c9..a700752 100644 --- a/AIStudio.Wpf.DiagramApp/ViewModels/SFCViewModel.cs +++ b/AIStudio.Wpf.DiagramApp/ViewModels/SFCViewModel.cs @@ -13,7 +13,7 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels { public SFCViewModel(string title, string status, DiagramType diagramType) : base(title, status, diagramType) { - Init(true); + } public SFCViewModel(string filename, DiagramDocument diagramDocument) : base(filename, diagramDocument) diff --git a/AIStudio.Wpf.DiagramApp/ViewModels/ScriptViewModel.cs b/AIStudio.Wpf.DiagramApp/ViewModels/ScriptViewModel.cs index 47f9189..d0bafdc 100644 --- a/AIStudio.Wpf.DiagramApp/ViewModels/ScriptViewModel.cs +++ b/AIStudio.Wpf.DiagramApp/ViewModels/ScriptViewModel.cs @@ -27,7 +27,7 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels public ScriptViewModel(string title, string status, DiagramType diagramType) : base(title, status, diagramType) { - Init(true); + } public ScriptViewModel(string filename, DiagramDocument diagramDocument) : base(filename, diagramDocument) @@ -61,8 +61,8 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels ConsoleLogViewModel logNode = new ConsoleLogViewModel(DiagramViewModel) { Name = "Log", Left = 150, Top = 420 }; DiagramViewModel.Add(logNode); - IntScriptViewModel intLog = new IntScriptViewModel(DiagramViewModel) { Name = "Int", Left = 40, Top = 220 }; - DiagramViewModel.Add(intLog); + IntScriptViewModel intNode = new IntScriptViewModel(DiagramViewModel) { Name = "Int", Left = 40, Top = 220 }; + DiagramViewModel.Add(intNode); ColorBoxFactoryScriptViewModel factoryNode = new ColorBoxFactoryScriptViewModel(DiagramViewModel) { Name = "ColorBoxFactory", Left = 150, Top = 150 }; DiagramViewModel.Add(factoryNode); @@ -111,7 +111,7 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels collectorNode7.Tag = new ColorBoxModel("紫色|六边形", "M 0,20 L 10,0 H 50 L 60,20 L 50,40 H10 Z", Colors.Purple); DiagramViewModel.Add(collectorNode7); - ConnectionViewModel int_factoryConnector = new ConnectionViewModel(DiagramViewModel, intLog.Output[0], factoryNode.Input[0], DrawMode.ConnectingLineSmooth, RouterMode.RouterNormal); + ConnectionViewModel int_factoryConnector = new ConnectionViewModel(DiagramViewModel, intNode.Output[0], factoryNode.Input[0], DrawMode.ConnectingLineSmooth, RouterMode.RouterNormal); DiagramViewModel.Add(int_factoryConnector); ConnectionViewModel bool_switchConnector = new ConnectionViewModel(DiagramViewModel, boolNode.Output[0], switchNode.Input[0], DrawMode.ConnectingLineSmooth, RouterMode.RouterNormal); @@ -191,7 +191,9 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels { item.Execute(); } - readDataTimer.Start(); + + if (readDataTimer != null) + readDataTimer.Start(); } public override void Dispose() @@ -200,6 +202,7 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels readDataTimer.Stop(); readDataTimer.Dispose(); + readDataTimer = null; foreach (var item in DiagramViewModel.Items.OfType().OrderBy(p => p.OrderNumber).ToList()) { diff --git a/AIStudio.Wpf.DiagramApp/ViewModels/ToolBoxViewModel.cs b/AIStudio.Wpf.DiagramApp/ViewModels/ToolBoxViewModel.cs index d8d7bb8..6aab3aa 100644 --- a/AIStudio.Wpf.DiagramApp/ViewModels/ToolBoxViewModel.cs +++ b/AIStudio.Wpf.DiagramApp/ViewModels/ToolBoxViewModel.cs @@ -119,9 +119,16 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels List defaultToolBoxItems = new List(); defaultToolBoxItems.Add(new TextToolBoxData("", typeof(DefaultDesignerItemViewModel))); - var blockitem = new TextToolBoxData("", typeof(BlockDesignerItemViewModel), 64, 32, new Size(130, 65)); + var blockitem = new TextToolBoxData("Block", typeof(BlockDesignerItemViewModel), 64, 32, desiredMinSize: new Size(130, 65)); blockitem.ColorViewModel.FillColor.Color = Color.FromRgb(0x00, 0x2F, 0xA7); defaultToolBoxItems.Add(blockitem); + var blockitem2 = new TextToolBoxData("Contain", typeof(BlockContainDesignerItemViewModel), 64, 32, desiredMinSize: new Size(130, 65)); + blockitem2.ColorViewModel.FillColor.Color = Color.FromRgb(0x00, 0x2F, 0xA7); + defaultToolBoxItems.Add(blockitem2); + var blockitem3 = new TextToolBoxData("ContainList", typeof(BlockContainListDesignerItemViewModel), 64, 32, desiredMinSize: new Size(130, 65)); + blockitem3.ColorViewModel.FillColor.Color = Color.FromRgb(0x00, 0x2F, 0xA7); + defaultToolBoxItems.Add(blockitem3); + ToolBoxCategory.Add(new ToolBoxCategory() { Header = "Default", ToolBoxItems = new ObservableCollection(defaultToolBoxItems), IsExpanded = true }); ToolBoxCategory.Add(new ToolBoxCategory() { Header = "Svg", ToolBoxItems = new ObservableCollection() }); diff --git a/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml b/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml index 6338ccc..577ec0f 100644 --- a/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml +++ b/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml @@ -103,6 +103,9 @@ + @@ -2651,70 +2654,76 @@ - + + + + + + - - - - - - - + + + + + + - - + - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + diff --git a/AIStudio.Wpf.DiagramDesigner.Additionals/AIStudio.Wpf.DiagramDesigner.Additionals_c3dwds1m_wpftmp.csproj b/AIStudio.Wpf.DiagramDesigner.Additionals/AIStudio.Wpf.DiagramDesigner.Additionals_c3dwds1m_wpftmp.csproj new file mode 100644 index 0000000..4c693ab --- /dev/null +++ b/AIStudio.Wpf.DiagramDesigner.Additionals/AIStudio.Wpf.DiagramDesigner.Additionals_c3dwds1m_wpftmp.csproj @@ -0,0 +1,309 @@ + + + AIStudio.Wpf.DiagramDesigner.Additionals + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\AIStudio.Wpf.DiagramDesigner.Additionals\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.DiagramDesigner.Additionals + + + + true + true + AIStudio.Wpf.Controls + akwkevin + https://gitee.com/akwkevin + A.png + + + 1.0.1 + 一个Wpf的Diagram控件帮助库 + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AIStudio.Wpf.DiagramDesigner.Additionals/AIStudio.Wpf.DiagramDesigner.Additionals_ltmcgkh5_wpftmp.csproj b/AIStudio.Wpf.DiagramDesigner.Additionals/AIStudio.Wpf.DiagramDesigner.Additionals_ltmcgkh5_wpftmp.csproj new file mode 100644 index 0000000..a5374c7 --- /dev/null +++ b/AIStudio.Wpf.DiagramDesigner.Additionals/AIStudio.Wpf.DiagramDesigner.Additionals_ltmcgkh5_wpftmp.csproj @@ -0,0 +1,300 @@ + + + AIStudio.Wpf.DiagramDesigner.Additionals + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\AIStudio.Wpf.DiagramDesigner.Additionals\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.DiagramDesigner.Additionals + + + + true + true + AIStudio.Wpf.Controls + akwkevin + https://gitee.com/akwkevin + A.png + + + 1.0.1 + 一个Wpf的Diagram控件帮助库 + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AIStudio.Wpf.DiagramDesigner.Additionals/AIStudio.Wpf.DiagramDesigner.Additionals_uoedrdjs_wpftmp.csproj b/AIStudio.Wpf.DiagramDesigner.Additionals/AIStudio.Wpf.DiagramDesigner.Additionals_uoedrdjs_wpftmp.csproj new file mode 100644 index 0000000..53e7f62 --- /dev/null +++ b/AIStudio.Wpf.DiagramDesigner.Additionals/AIStudio.Wpf.DiagramDesigner.Additionals_uoedrdjs_wpftmp.csproj @@ -0,0 +1,235 @@ + + + AIStudio.Wpf.DiagramDesigner.Additionals + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\AIStudio.Wpf.DiagramDesigner.Additionals\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.DiagramDesigner.Additionals + + + + true + true + AIStudio.Wpf.Controls + akwkevin + https://gitee.com/akwkevin + A.png + + + 1.0.1 + 一个Wpf的Diagram控件帮助库 + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AIStudio.Wpf.DiagramDesigner/AttachedProperties/DragAndDropProps.cs b/AIStudio.Wpf.DiagramDesigner/AttachedProperties/DragAndDropProps.cs index 741dd5c..1cc3f43 100644 --- a/AIStudio.Wpf.DiagramDesigner/AttachedProperties/DragAndDropProps.cs +++ b/AIStudio.Wpf.DiagramDesigner/AttachedProperties/DragAndDropProps.cs @@ -77,7 +77,9 @@ namespace AIStudio.Wpf.DiagramDesigner DragObject dataObject = new DragObject(); dataObject.ContentType = toolBoxData.Type; dataObject.DesiredSize = toolBoxData.DesiredSize; + dataObject.DesiredMinSize = toolBoxData.DesiredMinSize; dataObject.Icon = toolBoxData.Icon; + dataObject.Text = toolBoxData.Text; dataObject.ColorViewModel = toolBoxData.ColorViewModel; dataObject.DesignerItem = toolBoxData.Addition; diff --git a/AIStudio.Wpf.DiagramDesigner/AttachedProperties/WidthAndHeightProps.cs b/AIStudio.Wpf.DiagramDesigner/AttachedProperties/WidthAndHeightProps.cs new file mode 100644 index 0000000..debea6b --- /dev/null +++ b/AIStudio.Wpf.DiagramDesigner/AttachedProperties/WidthAndHeightProps.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace AIStudio.Wpf.DiagramDesigner +{ + + public static class WidthAndHeightProps + { + public static readonly DependencyProperty ActiveProperty = DependencyProperty.RegisterAttached( + "Active", + typeof(bool), + typeof(WidthAndHeightProps), + new FrameworkPropertyMetadata(OnActiveChanged)); + + public static bool GetActive(FrameworkElement frameworkElement) + { + return (bool)frameworkElement.GetValue(ActiveProperty); + } + + public static void SetActive(FrameworkElement frameworkElement, bool active) + { + frameworkElement.SetValue(ActiveProperty, active); + } + + public static readonly DependencyProperty BoundActualWidthProperty = DependencyProperty.RegisterAttached( + "BoundActualWidth", + typeof(double), + typeof(WidthAndHeightProps)); + + public static double GetBoundActualWidth(FrameworkElement frameworkElement) + { + return (double)frameworkElement.GetValue(BoundActualWidthProperty); + } + + public static void SetBoundActualWidth(FrameworkElement frameworkElement, double width) + { + frameworkElement.SetValue(BoundActualWidthProperty, width); + } + + public static readonly DependencyProperty BoundActualHeightProperty = DependencyProperty.RegisterAttached( + "BoundActualHeight", + typeof(double), + typeof(WidthAndHeightProps)); + + public static double GetBoundActualHeight(FrameworkElement frameworkElement) + { + return (double)frameworkElement.GetValue(BoundActualHeightProperty); + } + + public static void SetBoundActualHeight(FrameworkElement frameworkElement, double height) + { + frameworkElement.SetValue(BoundActualHeightProperty, height); + } + + private static void OnActiveChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) + { + if (!(dependencyObject is FrameworkElement frameworkElement)) + { + return; + } + + if ((bool)e.NewValue) + { + frameworkElement.SizeChanged -= OnFrameworkElementSizeChanged; + frameworkElement.SizeChanged += OnFrameworkElementSizeChanged; + frameworkElement.Loaded -= FrameworkElement_Loaded; + frameworkElement.Loaded += FrameworkElement_Loaded; + + } + else + { + frameworkElement.SizeChanged -= OnFrameworkElementSizeChanged; + frameworkElement.Loaded -= FrameworkElement_Loaded; + } + } + + private static void FrameworkElement_Loaded(object sender, RoutedEventArgs e) + { + UpdateObservedSizesForFrameworkElement(sender as FrameworkElement); + } + + private static void OnFrameworkElementSizeChanged(object sender, SizeChangedEventArgs e) + { + if (sender is FrameworkElement frameworkElement) + { + UpdateObservedSizesForFrameworkElement(frameworkElement); + } + } + + private static void UpdateObservedSizesForFrameworkElement(FrameworkElement frameworkElement) + { + frameworkElement.SetCurrentValue(BoundActualWidthProperty, frameworkElement.ActualWidth); + frameworkElement.SetCurrentValue(BoundActualHeightProperty, frameworkElement.ActualHeight); + } + } +} diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/BlockConnector.cs b/AIStudio.Wpf.DiagramDesigner/Controls/BlockConnector.cs new file mode 100644 index 0000000..639ce98 --- /dev/null +++ b/AIStudio.Wpf.DiagramDesigner/Controls/BlockConnector.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; + +namespace AIStudio.Wpf.DiagramDesigner +{ + public class BlockConnector : ContentControl + { + public ConnectorOrientation Orientation { get; set; } + + public ConnectorInfoBase Info + { + get + { + if (Content is ConnectorInfoBase connectorInfo) + return connectorInfo; + + return this.DataContext as ConnectorInfoBase; + } + } + + } + + public class BlockBorder : Border + { + } + +} diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs b/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs index 3e8bd85..40560cb 100644 --- a/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs +++ b/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs @@ -1,22 +1,14 @@ using System; -using System.Collections.Generic; -using System.IO; +using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; -using System.Windows.Markup; using System.Windows.Media; -using System.Xml; -using System.Linq; -using System.Windows.Shapes; using System.Windows.Resources; -using System.Runtime.InteropServices; -using Newtonsoft.Json; using AIStudio.Wpf.DiagramDesigner.Models; using AIStudio.Wpf.DiagramDesigner.ViewModels; using AIStudio.Wpf.DiagramDesigner.ViewModels.BaseViewModel; -using System.Diagnostics; namespace AIStudio.Wpf.DiagramDesigner { @@ -37,7 +29,7 @@ namespace AIStudio.Wpf.DiagramDesigner return DiagramServicesProvider.Instance.Provider; } } - private ConnectionViewModel partialConnection; + private ConnectionViewModel _partialConnection; private Point? rubberbandSelectionStartPoint = null; @@ -63,10 +55,10 @@ namespace AIStudio.Wpf.DiagramDesigner Point point = sourceDataItem.MiddlePosition; - partialConnection = new ConnectionViewModel(_viewModel, sourceDataItem, new PartCreatedConnectorInfo(point.X, point.Y), LineDrawMode, RouterMode); + _partialConnection = new ConnectionViewModel(_viewModel, sourceDataItem, new PartCreatedConnectorInfo(point.X, point.Y), LineDrawMode, RouterMode); - _viewModel.Add(partialConnection); - partialConnection.ZIndex = -1; + _viewModel.Add(_partialConnection); + _partialConnection.ZIndex = -1; } } } @@ -91,6 +83,30 @@ namespace AIStudio.Wpf.DiagramDesigner } } } + + private ItemsContainer _sourceItemsContainer; + public ItemsContainer SourceItemsContainer + { + get + { + return _sourceItemsContainer; + } + set + { + if (_sourceItemsContainer != value) + { + _sourceItemsContainer = value; + if (_sourceItemsContainer != null) + { + ItemsContainerInfo sourceDataItem = _sourceItemsContainer.Info; + + sourceDataItem.DataItem.RemoveChild(_sourceItemsContainer.DragObject); + + EnterMove(); + } + } + } + } private DrawMode DrawMode { @@ -467,7 +483,7 @@ namespace AIStudio.Wpf.DiagramDesigner { if (e.LeftButton == MouseButtonState.Pressed) { - partialConnection.SinkConnectorInfo = new PartCreatedConnectorInfo(currentPoint.X, currentPoint.Y); + _partialConnection.SinkConnectorInfo = new PartCreatedConnectorInfo(currentPoint.X, currentPoint.Y); SinkConnector = HitTesting(currentPoint); if (SinkConnector?.Info?.CanAttachTo(SourceConnector?.Info) == false) @@ -477,14 +493,24 @@ namespace AIStudio.Wpf.DiagramDesigner if (_viewModel.DiagramOption.SnappingOption.EnableSnapping) { - var nearPort = _viewModel.FindNearPortToAttachTo(partialConnection); + var nearPort = _viewModel.FindNearPortToAttachTo(_partialConnection); if (nearPort != null) { - partialConnection.SinkConnectorInfo = nearPort; + _partialConnection.SinkConnectorInfo = nearPort; } } } } + else if (SourceItemsContainer != null) + { + if (e.LeftButton == MouseButtonState.Pressed) + { + SourceItemsContainer.DragObject.Left = currentPoint.X - SourceItemsContainer.DragOffset.X; + SourceItemsContainer.DragObject.Top = currentPoint.Y - SourceItemsContainer.DragOffset.Y; + + _viewModel.PreviewNearBlock(new System.Collections.Generic.List { SourceItemsContainer.DragObject }); + } + } else { // if mouse button is not pressed we have no drag operation, ... @@ -526,10 +552,10 @@ namespace AIStudio.Wpf.DiagramDesigner { ConnectorInfoBase sinkDataItem = SinkConnector.Info; - _viewModel.Delete(partialConnection); + _viewModel.Delete(_partialConnection); _viewModel.AddCommand.Execute(new ConnectionViewModel(_viewModel, sourceDataItem, sinkDataItem, LineDrawMode, RouterMode)); } - else if (partialConnection.IsFullConnection)//自动连接模式 + else if (_partialConnection.IsFullConnection)//自动连接模式 { _viewModel.ClearNearPort(); } @@ -538,19 +564,26 @@ namespace AIStudio.Wpf.DiagramDesigner Point currentPoint = e.GetPosition(this); ConnectorInfoBase sinkDataItem = new PartCreatedConnectorInfo(currentPoint.X, currentPoint.Y); - _viewModel.Delete(partialConnection); + _viewModel.Delete(_partialConnection); _viewModel.AddCommand.Execute(new ConnectionViewModel(_viewModel, sourceDataItem, sinkDataItem, LineDrawMode, RouterMode)); } else { //Need to remove last item as we did not finish drawing the path - _viewModel.Delete(partialConnection); + _viewModel.Delete(_partialConnection); } } + else if (SourceItemsContainer != null) + { + _viewModel.FinishNearBlock(new System.Collections.Generic.List { SourceItemsContainer.DragObject }); + ExitCursor(); + } SourceConnector = null; SinkConnector = null; - partialConnection = null; + _partialConnection = null; + + SourceItemsContainer = null; _service.DrawModeViewModel.ResetDrawMode(); } @@ -624,6 +657,36 @@ namespace AIStudio.Wpf.DiagramDesigner return null; } + protected override void OnDragOver(DragEventArgs e) + { + DragObject dragObject = e.Data.GetData(typeof(DragObject)) as DragObject; + if (dragObject != null && (dragObject.ContentType == typeof(BlockDesignerItemViewModel) || dragObject.ContentType.IsSubclassOf(typeof(BlockDesignerItemViewModel)))) + { + var position = e.GetPosition(this); + + BlockDesignerItemViewModel itemBase = Activator.CreateInstance(dragObject.ContentType) as BlockDesignerItemViewModel; + itemBase.Text = dragObject.Text; + itemBase.Icon = dragObject.Icon; + itemBase.ColorViewModel = CopyHelper.Mapper(dragObject.ColorViewModel); + if (dragObject.DesiredSize != null) + { + itemBase.ItemWidth = dragObject.DesiredSize.Value.Width; + itemBase.ItemHeight = dragObject.DesiredSize.Value.Height; + } + if (dragObject.DesiredMinSize != null) + { + itemBase.MinItemWidth = dragObject.DesiredMinSize.Value.Width; + itemBase.MinItemHeight = dragObject.DesiredMinSize.Value.Height; + } + itemBase.Left = Math.Max(0, position.X - itemBase.GetItemWidth() / 2); + itemBase.Top = Math.Max(0, position.Y - itemBase.GetItemHeight() / 2); + + _viewModel.PreviewNearBlock(new System.Collections.Generic.List { itemBase }); + } + + base.OnDragOver(e); + } + protected override void OnDrop(DragEventArgs e) { base.OnDrop(e); @@ -640,8 +703,8 @@ namespace AIStudio.Wpf.DiagramDesigner var designerItems = serializableObject.ToObject(); var minleft = designerItems.OfType().Min(p => p.Left); var mintop = designerItems.OfType().Min(p => p.Top); - var maxright = designerItems.OfType().Max(p => p.Left + p.ItemWidth); - var maxbottom = designerItems.OfType().Max(p => p.Top + p.ItemHeight); + var maxright = designerItems.OfType().Max(p => p.Left + p.GetItemWidth()); + var maxbottom = designerItems.OfType().Max(p => p.Top + p.GetItemHeight()); var itemswidth = maxright - minleft; var itemsheight = maxbottom - mintop; @@ -662,6 +725,7 @@ namespace AIStudio.Wpf.DiagramDesigner else { itemBase = Activator.CreateInstance(dragObject.ContentType) as DesignerItemViewModelBase; + itemBase.Text = dragObject.Text; itemBase.Icon = dragObject.Icon; itemBase.ColorViewModel = CopyHelper.Mapper(dragObject.ColorViewModel); if (dragObject.DesiredSize != null) @@ -669,28 +733,42 @@ namespace AIStudio.Wpf.DiagramDesigner itemBase.ItemWidth = dragObject.DesiredSize.Value.Width; itemBase.ItemHeight = dragObject.DesiredSize.Value.Height; } + if (dragObject.DesiredMinSize != null) + { + itemBase.MinItemWidth = dragObject.DesiredMinSize.Value.Width; + itemBase.MinItemHeight = dragObject.DesiredMinSize.Value.Height; + } + } - itemBase.Left = Math.Max(0, position.X - itemBase.ItemWidth / 2); - itemBase.Top = Math.Max(0, position.Y - itemBase.ItemHeight / 2); + itemBase.Left = Math.Max(0, position.X - itemBase.GetItemWidth() / 2); + itemBase.Top = Math.Max(0, position.Y - itemBase.GetItemHeight() / 2); _viewModel.AddCommand.Execute(itemBase); + + if (itemBase is BlockDesignerItemViewModel block) + { + _viewModel.FinishNearBlock(new System.Collections.Generic.List { block }); + } } } - var dragFile = e.Data.GetData(DataFormats.FileDrop); - if (dragFile != null && dragFile is string[] files) + else { - foreach (var file in files) + var dragFile = e.Data.GetData(DataFormats.FileDrop); + if (dragFile != null && dragFile is string[] files) { - _viewModel.ClearSelectedItems(); - Point position = e.GetPosition(this); - ImageItemViewModel itemBase = new ImageItemViewModel(); - itemBase.Icon = file; - itemBase.Suffix = System.IO.Path.GetExtension(itemBase.Icon).ToLower(); - itemBase.InitWidthAndHeight(); - itemBase.AutoSize(); + foreach (var file in files) + { + _viewModel.ClearSelectedItems(); + Point position = e.GetPosition(this); + ImageItemViewModel itemBase = new ImageItemViewModel(); + itemBase.Icon = file; + itemBase.Suffix = System.IO.Path.GetExtension(itemBase.Icon).ToLower(); + itemBase.InitWidthAndHeight(); + itemBase.AutoSize(); - itemBase.Left = Math.Max(0, position.X - itemBase.ItemWidth / 2); - itemBase.Top = Math.Max(0, position.Y - itemBase.ItemHeight / 2); - _viewModel.AddCommand.Execute(itemBase); + itemBase.Left = Math.Max(0, position.X - itemBase.GetItemWidth() / 2); + itemBase.Top = Math.Max(0, position.Y - itemBase.GetItemHeight() / 2); + _viewModel.AddCommand.Execute(itemBase); + } } } e.Handled = true; diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs b/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs index a5a563c..e734321 100644 --- a/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs +++ b/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs @@ -21,10 +21,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls public IDiagramViewModel DiagramViewModel { - get - { - return (this.DataContext as SelectableDesignerItemViewModelBase)?.Root; - } + get;set; } private List designerItems; @@ -35,6 +32,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls drag = false; SelectableDesignerItemViewModelBase designerItem = this.DataContext as SelectableDesignerItemViewModelBase; + DiagramViewModel = designerItem?.Root; if (designerItem != null && designerItem.IsSelected) { @@ -99,47 +97,9 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls var blocks = designerItems.OfType().ToList(); if (blocks.Any()) { - foreach (BlockDesignerItemViewModel item in blocks) - { - var portTuple = DiagramViewModel.FindNearPortToAttachTo(item, true); - var portParent = portTuple.Item1; - var portNext = portTuple.Item2; - - if (portParent != null) - { - (portParent.DataItem as BlockDesignerItemViewModel).AddNext(item); - portParent.BeAttachTo = false; - portParent.DisableAttachTo = false; - } - else - { - if (item.Parent != null) - { - (item.Parent as BlockDesignerItemViewModel).Next = null; - item.Parent = null; - item.ParentId = new Guid(); - } - } - - if (portNext != null) - { - item.AddNext(portNext.DataItem as BlockDesignerItemViewModel); - portNext.BeAttachTo = false; - portNext.DisableAttachTo = false; - } - else - { - if (item.Next != null) - { - item.Next.Parent = null; - item.Next.ParentId = new Guid(); - item.Next = null; - } - } - } - //-DiagramViewModel.ClearNearPort(); + DiagramViewModel.FinishNearBlock(blocks); } - + Dictionary> infos = designerItems.OfType().ToDictionary(p => p, p => new Tuple(p.GetOldValue(nameof(p.TopLeft)), p.TopLeft)); @@ -207,14 +167,8 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls } var blocks = designerItems.OfType().ToList(); - if (blocks.Any()) - { - DiagramViewModel.ClearNearPort(); - foreach (BlockDesignerItemViewModel item in blocks) - { - DiagramViewModel.FindNearPortToAttachTo(item, false); - } - } + DiagramViewModel.PreviewNearBlock(blocks); + e.Handled = true; } } diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/ItemsContainer.cs b/AIStudio.Wpf.DiagramDesigner/Controls/ItemsContainer.cs new file mode 100644 index 0000000..a2e4ac8 --- /dev/null +++ b/AIStudio.Wpf.DiagramDesigner/Controls/ItemsContainer.cs @@ -0,0 +1,200 @@ +using System; +using System.ComponentModel; +using System.Runtime.CompilerServices; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; +using AIStudio.Wpf.DiagramDesigner.Helpers; + +namespace AIStudio.Wpf.DiagramDesigner +{ + public class ItemsContainer : ContentControl + { + static ItemsContainer() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ItemsContainer), new FrameworkPropertyMetadata(typeof(ItemsContainer))); + } + + public static readonly DependencyProperty BorderProperty = DependencyProperty.Register( + nameof(Border), typeof(object), typeof(ItemsContainer), new PropertyMetadata(default(object))); + + public object Border + { + get => GetValue(BorderProperty); + set => SetValue(BorderProperty, value); + } + + public static readonly DependencyProperty BorderTemplateProperty = DependencyProperty.Register( + nameof(BorderTemplate), typeof(DataTemplate), typeof(ItemsContainer), new PropertyMetadata(default(DataTemplate))); + + [Bindable(true), Category("Content")] + public DataTemplate BorderTemplate + { + get => (DataTemplate)GetValue(BorderTemplateProperty); + set => SetValue(BorderTemplateProperty, value); + } + + public static readonly DependencyProperty BorderTemplateSelectorProperty = DependencyProperty.Register( + nameof(BorderTemplateSelector), typeof(DataTemplateSelector), typeof(ItemsContainer), new PropertyMetadata(default(DataTemplateSelector))); + + [Bindable(true), Category("Content")] + public DataTemplateSelector BorderTemplateSelector + { + get => (DataTemplateSelector)GetValue(BorderTemplateSelectorProperty); + set => SetValue(BorderTemplateSelectorProperty, value); + } + + public static readonly DependencyProperty BorderStringFormatProperty = DependencyProperty.Register( + nameof(BorderStringFormat), typeof(string), typeof(ItemsContainer), new PropertyMetadata(default(string))); + + [Bindable(true), Category("Content")] + public string BorderStringFormat + { + get => (string)GetValue(BorderStringFormatProperty); + set => SetValue(BorderStringFormatProperty, value); + } + + + public static readonly DependencyProperty ParentPanelProperty = + DependencyProperty.Register(nameof(ParentPanel), typeof(FrameworkElement), typeof(ItemsContainer), + new FrameworkPropertyMetadata(null)); + + public FrameworkElement ParentPanel + { + get + { + return (FrameworkElement)GetValue(ParentPanelProperty); + } + set + { + SetValue(ParentPanelProperty, value); + } + } + + public static readonly DependencyProperty GetOffSetFuncProperty = + DependencyProperty.Register(nameof(GetOffSetFunc), + typeof(Func), + typeof(ItemsContainer), + new FrameworkPropertyMetadata(null)); + public Func GetOffSetFunc + { + get + { + return (Func)this.GetValue(GetOffSetFuncProperty); + } + set + { + this.SetValue(GetOffSetFuncProperty, value); + } + } + + public Func GetOffSet + { + get + { + return new Func(() => this.TransformToAncestor(ParentPanel).Transform(new Point(0, 0))); + } + } + + public ItemsContainerInfo Info + { + get + { + if (Border is ItemsContainerInfo itemsContainerInfo) + return itemsContainerInfo; + + return this.DataContext as ItemsContainerInfo; + } + } + + public BlockDesignerItemViewModel DragObject + { + get; private set; + } + + public Point DragOffset + { + get; private set; + } + + public ItemsContainer() + { + + } + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + GetOffSetFunc = GetOffSet; + } + + Point? firstPoint; + protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) + { + base.OnMouseLeftButtonDown(e); + firstPoint = e.GetPosition(this); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + + if (firstPoint != null) + { + var currentPoint = e.GetPosition(this); + if (Math.Sqrt(Math.Pow(firstPoint.Value.X - currentPoint.X, 2) + Math.Pow(firstPoint.Value.Y - currentPoint.Y, 2)) > 5) + { + if (Info?.Children?.Count > 0) + { + var borders = VisualHelper.FindVisualChildren(this); + foreach (var border in borders) + { + var point = border.TransformToAncestor(this).Transform(new Point(0, 0)); + var rect = new Rect(point.X, point.Y, border.ActualWidth, border.ActualHeight); + if (rect.Contains(currentPoint)) + { + DragObject = border.DataContext as BlockDesignerItemViewModel; + DragOffset = new Point(currentPoint.X - point.X, currentPoint.Y - point.Y); + break; + } + } + + if (DragObject != null) + { + DesignerCanvas canvas = GetDesignerCanvas(this); + if (canvas != null) + { + canvas.SourceItemsContainer = this; + } + } + } + firstPoint = null; + } + } + } + protected override void OnMouseUp(MouseButtonEventArgs e) + { + base.OnMouseUp(e); + + firstPoint = null; + DragObject = null; + } + + public ConnectorOrientation Orientation + { + get; set; + } + + // iterate through visual tree to get parent DesignerCanvas + private DesignerCanvas GetDesignerCanvas(DependencyObject element) + { + while (element != null && !(element is DesignerCanvas)) + element = VisualTreeHelper.GetParent(element); + + return element as DesignerCanvas; + } + + } +} diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/ResizeThumb.cs b/AIStudio.Wpf.DiagramDesigner/Controls/ResizeThumb.cs index dcae788..86d0158 100644 --- a/AIStudio.Wpf.DiagramDesigner/Controls/ResizeThumb.cs +++ b/AIStudio.Wpf.DiagramDesigner/Controls/ResizeThumb.cs @@ -95,13 +95,13 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls { case VerticalAlignment.Bottom: dragDeltaVertical = Math.Min(-e.VerticalChange, minDeltaVertical); - scale = (item.ItemHeight - dragDeltaVertical) / item.ItemHeight; + scale = (item.GetItemHeight() - dragDeltaVertical) / item.GetItemHeight(); DragBottom(scale, item, DiagramViewModel.SelectionService); break; case VerticalAlignment.Top: double top = item.Top; dragDeltaVertical = Math.Min(Math.Max(-minTop, e.VerticalChange), minDeltaVertical); - scale = (item.ItemHeight - dragDeltaVertical) / item.ItemHeight; + scale = (item.GetItemHeight() - dragDeltaVertical) / item.GetItemHeight(); DragTop(scale, item, DiagramViewModel.SelectionService); break; default: @@ -113,12 +113,12 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls case HorizontalAlignment.Left: double left = item.Left; dragDeltaHorizontal = Math.Min(Math.Max(-minLeft, e.HorizontalChange), minDeltaHorizontal); - scale = (item.ItemWidth - dragDeltaHorizontal) / item.ItemWidth; + scale = (item.GetItemWidth() - dragDeltaHorizontal) / item.GetItemWidth(); DragLeft(scale, item, DiagramViewModel.SelectionService); break; case HorizontalAlignment.Right: dragDeltaHorizontal = Math.Min(-e.HorizontalChange, minDeltaHorizontal); - scale = (item.ItemWidth - dragDeltaHorizontal) / item.ItemWidth; + scale = (item.GetItemWidth() - dragDeltaHorizontal) / item.GetItemWidth(); DragRight(scale, item, DiagramViewModel.SelectionService); break; default: @@ -137,26 +137,26 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls { IEnumerable groupItems = selectionService.GetGroupMembers(item, false).Cast(); - double groupLeft = item.Left + item.ItemWidth; + double groupLeft = item.Left + item.GetItemWidth(); foreach (DesignerItemViewModelBase groupItem in groupItems) { double groupItemLeft = groupItem.Left; double delta = (groupLeft - groupItemLeft) * (scale - 1); groupItem.Left = groupItemLeft - delta; - groupItem.ItemWidth = groupItem.ItemWidth * scale; + groupItem.ItemWidth = groupItem.GetItemWidth() * scale; } } private void DragTop(double scale, DesignerItemViewModelBase item, SelectionService selectionService) { IEnumerable groupItems = selectionService.GetGroupMembers(item, false).Cast(); - double groupBottom = item.Top + item.ItemHeight; + double groupBottom = item.Top + item.GetItemHeight(); foreach (DesignerItemViewModelBase groupItem in groupItems) { double groupItemTop = groupItem.Top; double delta = (groupBottom - groupItemTop) * (scale - 1); groupItem.Top = groupItemTop - delta; - groupItem.ItemHeight = groupItem.ItemHeight * scale; + groupItem.ItemHeight = groupItem.GetItemHeight() * scale; } } @@ -171,7 +171,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls double delta = (groupItemLeft - groupLeft) * (scale - 1); groupItem.Left = groupItemLeft + delta; - groupItem.ItemWidth = groupItem.ItemWidth * scale; + groupItem.ItemWidth = groupItem.GetItemWidth() * scale; } } @@ -185,7 +185,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls double delta = (groupItemTop - groupTop) * (scale - 1); groupItem.Top = groupItemTop + delta; - groupItem.ItemHeight = groupItem.ItemHeight * scale; + groupItem.ItemHeight = groupItem.GetItemHeight() * scale; } } diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/RotateThumb.cs b/AIStudio.Wpf.DiagramDesigner/Controls/RotateThumb.cs index 80ac038..25ae658 100644 --- a/AIStudio.Wpf.DiagramDesigner/Controls/RotateThumb.cs +++ b/AIStudio.Wpf.DiagramDesigner/Controls/RotateThumb.cs @@ -53,8 +53,8 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls if (this.designerCanvas != null) { this.centerPoint = - new Point(this.designerItem.Left + this.designerItem.ItemWidth * 0.5, - this.designerItem.Top + this.designerItem.ItemHeight * 0.5); + new Point(this.designerItem.Left + this.designerItem.GetItemHeight() * 0.5, + this.designerItem.Top + this.designerItem.GetItemHeight() * 0.5); Point startPoint = Mouse.GetPosition(this.designerCanvas); this.startVector = Point.Subtract(startPoint, this.centerPoint); diff --git a/AIStudio.Wpf.DiagramDesigner/Enums/DiagramType.cs b/AIStudio.Wpf.DiagramDesigner/Enums/DiagramType.cs index 443564d..dcf24e6 100644 --- a/AIStudio.Wpf.DiagramDesigner/Enums/DiagramType.cs +++ b/AIStudio.Wpf.DiagramDesigner/Enums/DiagramType.cs @@ -12,6 +12,7 @@ namespace AIStudio.Wpf.DiagramDesigner SFC, Mind, Script, - Drawing + Drawing, + Block } } diff --git a/AIStudio.Wpf.DiagramDesigner/Geometrys/PointBase.cs b/AIStudio.Wpf.DiagramDesigner/Geometrys/PointBase.cs index 2ac36aa..9e30444 100644 --- a/AIStudio.Wpf.DiagramDesigner/Geometrys/PointBase.cs +++ b/AIStudio.Wpf.DiagramDesigner/Geometrys/PointBase.cs @@ -16,6 +16,12 @@ namespace AIStudio.Wpf.DiagramDesigner.Geometrys _y = y; } + public PointBase(Point point) + { + _x = point.X; + _y = point.Y; + } + /// /// 中间X /// diff --git a/AIStudio.Wpf.DiagramDesigner/Helpers/PointHelper.cs b/AIStudio.Wpf.DiagramDesigner/Helpers/PointHelper.cs index c9645c3..ed84f96 100644 --- a/AIStudio.Wpf.DiagramDesigner/Helpers/PointHelper.cs +++ b/AIStudio.Wpf.DiagramDesigner/Helpers/PointHelper.cs @@ -17,8 +17,8 @@ namespace AIStudio.Wpf.DiagramDesigner var connectorHeight = double.IsNaN(connector.ConnectorHeight) ? 0 : connector.ConnectorHeight; var left = connector.DataItem.Left; var top = connector.DataItem.Top; - var itemWidth = connector.DataItem.ItemWidth; - var itemHeight = connector.DataItem.ItemHeight; + var itemWidth = connector.DataItem.GetItemWidth(); + var itemHeight = connector.DataItem.GetItemHeight(); if (connector.IsInnerPoint) { diff --git a/AIStudio.Wpf.DiagramDesigner/Models/DragObject.cs b/AIStudio.Wpf.DiagramDesigner/Models/DragObject.cs index 712fbde..74720f2 100644 --- a/AIStudio.Wpf.DiagramDesigner/Models/DragObject.cs +++ b/AIStudio.Wpf.DiagramDesigner/Models/DragObject.cs @@ -9,10 +9,33 @@ namespace AIStudio.Wpf.DiagramDesigner // Wraps info of the dragged object into a class public class DragObject { - public Size? DesiredSize { get; set; } - public Type ContentType { get; set; } - public string Icon { get; set; } - public IColorViewModel ColorViewModel { get; set; } - public object DesignerItem { get; set; } + public Size? DesiredSize + { + get; set; + } + public Size? DesiredMinSize + { + get; set; + } + public Type ContentType + { + get; set; + } + public string Icon + { + get; set; + } + public string Text + { + get; set; + } + public IColorViewModel ColorViewModel + { + get; set; + } + public object DesignerItem + { + get; set; + } } } diff --git a/AIStudio.Wpf.DiagramDesigner/Models/ToolBoxData.cs b/AIStudio.Wpf.DiagramDesigner/Models/ToolBoxData.cs index 333a6e7..6fafc6c 100644 --- a/AIStudio.Wpf.DiagramDesigner/Models/ToolBoxData.cs +++ b/AIStudio.Wpf.DiagramDesigner/Models/ToolBoxData.cs @@ -36,6 +36,10 @@ namespace AIStudio.Wpf.DiagramDesigner { get; set; } + public Size? DesiredMinSize + { + get; set; + } public string Description { get; set; @@ -46,7 +50,7 @@ namespace AIStudio.Wpf.DiagramDesigner get; set; } - public ToolBoxData(string text, string icon, Type type, double width, double height, Size? desiredSize = null, string description = null) + public ToolBoxData(string text, string icon, Type type, double width, double height, Size? desiredSize = null, Size? desiredMinSize = null, string description = null) { this.Text = text; this.Icon = icon; @@ -54,6 +58,7 @@ namespace AIStudio.Wpf.DiagramDesigner this.Width = width; this.Height = height; this.DesiredSize = desiredSize; + this.DesiredMinSize = desiredMinSize; this.ColorViewModel = new ColorViewModel(); this.Description = description; } diff --git a/AIStudio.Wpf.DiagramDesigner/Themes/ConnectorItem.xaml b/AIStudio.Wpf.DiagramDesigner/Themes/ConnectorItem.xaml index 6b5a4ac..aa0855b 100644 --- a/AIStudio.Wpf.DiagramDesigner/Themes/ConnectorItem.xaml +++ b/AIStudio.Wpf.DiagramDesigner/Themes/ConnectorItem.xaml @@ -5,7 +5,7 @@ - + @@ -70,7 +70,7 @@ - + @@ -115,7 +115,7 @@ - + @@ -158,6 +158,58 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AIStudio.Wpf.DiagramDesigner/Themes/DesignerItem.xaml b/AIStudio.Wpf.DiagramDesigner/Themes/DesignerItem.xaml index c314b4e..fcd5ed0 100644 --- a/AIStudio.Wpf.DiagramDesigner/Themes/DesignerItem.xaml +++ b/AIStudio.Wpf.DiagramDesigner/Themes/DesignerItem.xaml @@ -12,6 +12,7 @@ + @@ -98,14 +99,72 @@ - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/AIStudio.Wpf.DiagramDesigner/UserControls/ConnectorContainer.xaml.cs b/AIStudio.Wpf.DiagramDesigner/UserControls/ConnectorContainer.xaml.cs index f1b76c3..e959e21 100644 --- a/AIStudio.Wpf.DiagramDesigner/UserControls/ConnectorContainer.xaml.cs +++ b/AIStudio.Wpf.DiagramDesigner/UserControls/ConnectorContainer.xaml.cs @@ -38,8 +38,8 @@ namespace AIStudio.Wpf.DiagramDesigner var connector = ItemContainerGenerator.ContainerFromItem(item) as ContentPresenter; if (connector != null) { - Canvas.SetLeft(connector, vm.DataItem.ItemWidth * vm.XRatio - vm.ConnectorWidth / 2); - Canvas.SetTop(connector, vm.DataItem.ItemHeight * vm.YRatio - vm.ConnectorHeight / 2); + Canvas.SetLeft(connector, vm.DataItem.GetItemWidth() * vm.XRatio - vm.ConnectorWidth / 2); + Canvas.SetTop(connector, vm.DataItem.GetItemHeight() * vm.YRatio - vm.ConnectorHeight / 2); } } diff --git a/AIStudio.Wpf.DiagramDesigner/UserControls/DiagramControl.xaml b/AIStudio.Wpf.DiagramDesigner/UserControls/DiagramControl.xaml index c52ec44..9e22d2a 100644 --- a/AIStudio.Wpf.DiagramDesigner/UserControls/DiagramControl.xaml +++ b/AIStudio.Wpf.DiagramDesigner/UserControls/DiagramControl.xaml @@ -344,25 +344,25 @@ - - - - + + + @@ -855,16 +861,13 @@ - - + - - diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Container/ItemsContainerInfo.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Container/ItemsContainerInfo.cs new file mode 100644 index 0000000..8f87660 --- /dev/null +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Container/ItemsContainerInfo.cs @@ -0,0 +1,213 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Media; +using AIStudio.Wpf.DiagramDesigner.Geometrys; +using AIStudio.Wpf.DiagramDesigner.Models; + +namespace AIStudio.Wpf.DiagramDesigner +{ + public class ItemsContainerInfo : SelectableViewModelBase + { + public ItemsContainerInfo(BlockDesignerItemViewModel dataItem) : this(null, dataItem) + { + + } + + public ItemsContainerInfo(IDiagramViewModel root, BlockDesignerItemViewModel dataItem) : base(root) + { + this.Parent = dataItem; + } + + public ItemsContainerInfo(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer) + { + + } + + public ItemsContainerInfo(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType) + { + + } + + //public override SelectableItemBase GetSerializableObject() + //{ + // return new ConnectorInfoItemBase(this); + //} + + protected override void Init(IDiagramViewModel root, bool initNew) + { + base.Init(root, initNew); + } + + protected override void InitNew() + { + ColorViewModel = new ColorViewModel() + { + LineWidth = 1, + LineColor = new ColorObject() { Color = Color.FromArgb(0xAA, 0x00, 0x00, 0x80) }, + FillColor = new ColorObject() { Color = Colors.Transparent }, + }; + } + + protected override void LoadDesignerItemViewModel(SelectableItemBase designerbase) + { + base.LoadDesignerItemViewModel(designerbase); + + //if (designerbase is ConnectorInfoItemBase designer) + //{ + // PhysicalConnectorWidth = designer.PhysicalConnectorWidth; + // PhysicalConnectorHeight = designer.PhysicalConnectorHeight; + // Orientation = designer.Orientation; + //} + } + + #region 属性 + private double _itemWidth = double.NaN; + public double ItemWidth + { + get + { + return _itemWidth; + } + set + { + if (value <= 0) return; + SetProperty(ref _itemWidth, value); + } + } + + private double _itemHeight = double.NaN; + public double ItemHeight + { + get + { + return _itemHeight; + } + set + { + if (value <= 0) return; + SetProperty(ref _itemHeight, value); + } + } + + private double _actualItemWidth; + public double ActualItemWidth + { + get + { + return _actualItemWidth; + } + set + { + SetProperty(ref _actualItemWidth, value); + } + } + + private double _actualItemHeight; + public double ActualItemHeight + { + get + { + return _actualItemHeight; + } + set + { + SetProperty(ref _actualItemHeight, value); + } + } + + //public PointBase Position + //{ + // get + // { + // var offset = GetOffSetFunc?.Invoke() ?? new Point(0, 0); + // return new PointBase(DataItem.Left + offset.X, DataItem.Top + offset.Y); + // } + //} + + //public PointBase MiddlePosition + //{ + // get + // { + // return new PointBase(Position.X + GetItemWidth() / 2, Position.Y + GetItemHeight() / 2); + // } + //} + + public RectangleBase GetBounds() + { + var offset = GetOffSetFunc?.Invoke() ?? new Point(0, 0); + + return new RectangleBase(DataItem.Left + offset.X, DataItem.Top + offset.Y, GetItemWidth(), GetItemHeight()); + } + + public BlockDesignerItemViewModel DataItem + { + get + { + return Parent as BlockDesignerItemViewModel; + } + } + + public ObservableCollection Children + { + get; set; + } = new ObservableCollection(); + + + private Func _getOffSetFunc; + public Func GetOffSetFunc + { + get + { + return _getOffSetFunc; + } + set + { + SetProperty(ref _getOffSetFunc, value); + } + } + + private bool _beAttachTo; + public bool BeAttachTo + { + get + { + return _beAttachTo; + } + set + { + SetProperty(ref _beAttachTo, value); + } + } + + private bool _disableAttachTo; + public bool DisableAttachTo + { + get + { + return _disableAttachTo; + } + set + { + SetProperty(ref _disableAttachTo, value); + } + } + + public virtual bool CanAttachTo(DesignerItemViewModelBase item) + => item != null && item != this.DataItem && !item.IsReadOnly && item is BlockDesignerItemViewModel; + #endregion + + public double GetItemWidth() + { + return double.IsNaN(ItemWidth) ? ActualItemWidth : ItemWidth; + } + + public double GetItemHeight() + { + return double.IsNaN(ItemHeight) ? ActualItemHeight : ItemHeight; + } + } +} diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs index 5637f32..02c4501 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs @@ -261,7 +261,7 @@ namespace AIStudio.Wpf.DiagramDesigner { get { - return new SizeBase(ItemWidth, ItemHeight); + return new SizeBase(GetItemWidth(), GetItemHeight()); } set { @@ -445,7 +445,7 @@ namespace AIStudio.Wpf.DiagramDesigner { get { - return new Point(Left + ItemWidth, Top + ItemHeight); + return new Point(Left + GetItemWidth(), Top + GetItemHeight()); } } @@ -557,6 +557,32 @@ namespace AIStudio.Wpf.DiagramDesigner } } + private double _actualItemWidth; + public double ActualItemWidth + { + get + { + return _actualItemWidth; + } + set + { + SetProperty(ref _actualItemWidth, value); + } + } + + private double _actualItemHeight; + public double ActualItemHeight + { + get + { + return _actualItemHeight; + } + set + { + SetProperty(ref _actualItemHeight, value); + } + } + /// /// 连接点是否可以按偏移自定义 /// @@ -637,9 +663,9 @@ namespace AIStudio.Wpf.DiagramDesigner { if (Root.DiagramOption.LayoutOption.CellHorizontalAlignment == CellHorizontalAlignment.Center) { - if (Root.DiagramOption.LayoutOption.GridCellSize.Width > this.ItemWidth) + if (Root.DiagramOption.LayoutOption.GridCellSize.Width > this.GetItemWidth()) { - this.Left = (int)(this.Left / Root.DiagramOption.LayoutOption.GridCellSize.Width) * Root.DiagramOption.LayoutOption.GridCellSize.Width + Root.DiagramOption.LayoutOption.GridMarginSize.Width + (Root.DiagramOption.LayoutOption.GridCellSize.Width - this.ItemWidth) / 2; + this.Left = (int)(this.Left / Root.DiagramOption.LayoutOption.GridCellSize.Width) * Root.DiagramOption.LayoutOption.GridCellSize.Width + Root.DiagramOption.LayoutOption.GridMarginSize.Width + (Root.DiagramOption.LayoutOption.GridCellSize.Width - this.GetItemWidth()) / 2; } } else if (Root.DiagramOption.LayoutOption.CellHorizontalAlignment == CellHorizontalAlignment.Left) @@ -648,17 +674,17 @@ namespace AIStudio.Wpf.DiagramDesigner } else if (Root.DiagramOption.LayoutOption.CellHorizontalAlignment == CellHorizontalAlignment.Right) { - if (Root.DiagramOption.LayoutOption.GridCellSize.Width > this.ItemWidth) + if (Root.DiagramOption.LayoutOption.GridCellSize.Width > this.GetItemWidth()) { - this.Left = (int)(this.Left / Root.DiagramOption.LayoutOption.GridCellSize.Width) * Root.DiagramOption.LayoutOption.GridCellSize.Width + Root.DiagramOption.LayoutOption.GridMarginSize.Width + (Root.DiagramOption.LayoutOption.GridCellSize.Width - this.ItemWidth); + this.Left = (int)(this.Left / Root.DiagramOption.LayoutOption.GridCellSize.Width) * Root.DiagramOption.LayoutOption.GridCellSize.Width + Root.DiagramOption.LayoutOption.GridMarginSize.Width + (Root.DiagramOption.LayoutOption.GridCellSize.Width - this.GetItemWidth()); } } if (Root.DiagramOption.LayoutOption.CellVerticalAlignment == CellVerticalAlignment.Center) { - if (Root.DiagramOption.LayoutOption.GridCellSize.Height > this.ItemHeight) + if (Root.DiagramOption.LayoutOption.GridCellSize.Height > this.GetItemHeight()) { - this.Top = (int)(this.Top / Root.DiagramOption.LayoutOption.GridCellSize.Height) * Root.DiagramOption.LayoutOption.GridCellSize.Height + Root.DiagramOption.LayoutOption.GridMarginSize.Height + (Root.DiagramOption.LayoutOption.GridCellSize.Height - this.ItemHeight) / 2; + this.Top = (int)(this.Top / Root.DiagramOption.LayoutOption.GridCellSize.Height) * Root.DiagramOption.LayoutOption.GridCellSize.Height + Root.DiagramOption.LayoutOption.GridMarginSize.Height + (Root.DiagramOption.LayoutOption.GridCellSize.Height - this.GetItemHeight()) / 2; } } else if (Root.DiagramOption.LayoutOption.CellVerticalAlignment == CellVerticalAlignment.Top) @@ -667,9 +693,9 @@ namespace AIStudio.Wpf.DiagramDesigner } else if (Root.DiagramOption.LayoutOption.CellVerticalAlignment == CellVerticalAlignment.Bottom) { - if (Root.DiagramOption.LayoutOption.GridCellSize.Height > this.ItemHeight) + if (Root.DiagramOption.LayoutOption.GridCellSize.Height > this.GetItemHeight()) { - this.Top = (int)(this.Top / Root.DiagramOption.LayoutOption.GridCellSize.Height) * Root.DiagramOption.LayoutOption.GridCellSize.Height + Root.DiagramOption.LayoutOption.GridMarginSize.Height + (Root.DiagramOption.LayoutOption.GridCellSize.Height - this.ItemHeight); + this.Top = (int)(this.Top / Root.DiagramOption.LayoutOption.GridCellSize.Height) * Root.DiagramOption.LayoutOption.GridCellSize.Height + Root.DiagramOption.LayoutOption.GridMarginSize.Height + (Root.DiagramOption.LayoutOption.GridCellSize.Height - this.GetItemHeight()); } } } @@ -740,14 +766,24 @@ namespace AIStudio.Wpf.DiagramDesigner var left = leftPort == null ? Position.X : Math.Min(Position.X, leftPort.Position.X); var top = topPort == null ? Position.Y : Math.Min(Position.Y, topPort.Position.Y); - var right = rightPort == null ? Position.X + ItemWidth : - Math.Max(rightPort.Position.X + rightPort.ConnectorWidth, Position.X + ItemWidth); + var right = rightPort == null ? Position.X + GetItemWidth() : + Math.Max(rightPort.Position.X + rightPort.ConnectorWidth, Position.X + GetItemWidth()); var bottom = bottomPort == null ? Position.Y + ItemHeight : - Math.Max(bottomPort.Position.Y + bottomPort.ConnectorHeight, Position.Y + ItemHeight); + Math.Max(bottomPort.Position.Y + bottomPort.ConnectorHeight, Position.Y + GetItemHeight()); return new RectangleBase(left, top, right, bottom, true); } + public double GetItemWidth() + { + return double.IsNaN(ItemWidth) ? ActualItemWidth : ItemWidth; + } + + public double GetItemHeight() + { + return double.IsNaN(ItemHeight) ? ActualItemHeight : ItemHeight; + } + public IShape GetShape() => ShapeDefiner(this); public override string ToString() diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs index 83f3d69..7a2bc4f 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs @@ -1449,7 +1449,7 @@ namespace AIStudio.Wpf.DiagramDesigner return items; } - protected void ExecuteDeleteCommand(object parameter) + protected virtual void ExecuteDeleteCommand(object parameter) { var items = Delete(parameter, false); if (items.Any()) @@ -1580,11 +1580,11 @@ namespace AIStudio.Wpf.DiagramDesigner DoCommandManager.DoNewCommand(this.ToString(), () => { - double mid = selectedItems.Select(p => p.Top + p.ItemHeight / 2).Average(); + double mid = selectedItems.Select(p => p.Top + p.GetItemHeight() / 2).Average(); foreach (DesignerItemViewModelBase item in selectedItems) { - item.Top = mid - item.ItemHeight / 2; + item.Top = mid - item.GetItemHeight() / 2; } }, () => { @@ -1618,11 +1618,11 @@ namespace AIStudio.Wpf.DiagramDesigner DoCommandManager.DoNewCommand(this.ToString(), () => { - double top = selectedItems.OrderBy(p => p.Top + p.ItemHeight).Select(p => p.Top + p.ItemHeight).LastOrDefault(); + double top = selectedItems.OrderBy(p => p.Top + p.GetItemHeight()).Select(p => p.Top + p.GetItemHeight()).LastOrDefault(); foreach (DesignerItemViewModelBase item in selectedItems) { - item.Top = top - item.ItemHeight; + item.Top = top - item.GetItemHeight(); } }, () => { @@ -1694,11 +1694,11 @@ namespace AIStudio.Wpf.DiagramDesigner DoCommandManager.DoNewCommand(this.ToString(), () => { - double mid = selectedItems.Select(p => p.Left + p.ItemWidth / 2).Average(); + double mid = selectedItems.Select(p => p.Left + p.GetItemWidth() / 2).Average(); foreach (DesignerItemViewModelBase item in selectedItems) { - item.Left = mid - item.ItemWidth / 2; + item.Left = mid - item.GetItemWidth() / 2; } }, () => { @@ -1732,11 +1732,11 @@ namespace AIStudio.Wpf.DiagramDesigner DoCommandManager.DoNewCommand(this.ToString(), () => { - double right = selectedItems.OrderBy(p => p.Left + p.ItemWidth).Select(p => p.Left + p.ItemWidth).LastOrDefault(); + double right = selectedItems.OrderBy(p => p.Left + p.GetItemWidth()).Select(p => p.Left + p.GetItemWidth()).LastOrDefault(); foreach (DesignerItemViewModelBase item in selectedItems) { - item.Left = right - item.ItemWidth; + item.Left = right - item.GetItemWidth(); } }, () => { @@ -1975,8 +1975,8 @@ namespace AIStudio.Wpf.DiagramDesigner foreach (DesignerItemViewModelBase item in selectedItems) { left = Math.Min(left, item.Left); - right = Math.Max(right, item.Left + item.ItemWidth); - sumWidth += item.ItemWidth; + right = Math.Max(right, item.Left + item.GetItemWidth()); + sumWidth += item.GetItemWidth(); } double distance = Math.Max(0, (right - left - sumWidth) / (selectedItems.Count() - 1)); @@ -1989,7 +1989,7 @@ namespace AIStudio.Wpf.DiagramDesigner { di.Left += delta; } - offset = offset + item.ItemWidth + distance; + offset = offset + item.GetItemWidth() + distance; } }, @@ -2030,8 +2030,8 @@ namespace AIStudio.Wpf.DiagramDesigner foreach (DesignerItemViewModelBase item in selectedItems) { top = Math.Min(top, item.Top); - bottom = Math.Max(bottom, item.Top + item.ItemHeight); - sumHeight += item.ItemHeight; + bottom = Math.Max(bottom, item.Top + item.GetItemHeight()); + sumHeight += item.GetItemHeight(); } double distance = Math.Max(0, (bottom - top - sumHeight) / (selectedItems.Count() - 1)); @@ -2044,7 +2044,7 @@ namespace AIStudio.Wpf.DiagramDesigner { di.Top += +delta; } - offset = offset + item.ItemHeight + distance; + offset = offset + item.GetItemHeight() + distance; } }, () => { @@ -2264,8 +2264,8 @@ namespace AIStudio.Wpf.DiagramDesigner () => { foreach (var item in selectedItems) { - item.ItemWidth = selectedItems.FirstOrDefault().ItemWidth; - item.ItemHeight = selectedItems.FirstOrDefault().ItemHeight; + item.ItemWidth = selectedItems.FirstOrDefault().GetItemWidth(); + item.ItemHeight = selectedItems.FirstOrDefault().GetItemHeight(); } }, () => { @@ -2295,13 +2295,13 @@ namespace AIStudio.Wpf.DiagramDesigner if (selectedItems.Count > 1) { - Dictionary infos = selectedItems.ToDictionary(p => p, p => p.ItemWidth); + Dictionary infos = selectedItems.ToDictionary(p => p, p => p.GetItemWidth()); DoCommandManager.DoNewCommand(this.ToString(), () => { foreach (var item in selectedItems) { - item.ItemWidth = selectedItems.FirstOrDefault().ItemWidth; + item.ItemWidth = selectedItems.FirstOrDefault().GetItemWidth(); } }, () => { @@ -2331,13 +2331,13 @@ namespace AIStudio.Wpf.DiagramDesigner if (selectedItems.Count > 1) { - Dictionary infos = selectedItems.ToDictionary(p => p, p => p.ItemHeight); + Dictionary infos = selectedItems.ToDictionary(p => p, p => p.GetItemHeight()); DoCommandManager.DoNewCommand(this.ToString(), () => { foreach (var item in selectedItems) { - item.ItemHeight = selectedItems.FirstOrDefault().ItemHeight; + item.ItemHeight = selectedItems.FirstOrDefault().GetItemHeight(); } }, () => { @@ -3145,6 +3145,37 @@ namespace AIStudio.Wpf.DiagramDesigner return new Tuple(parent, next); } + public ItemsContainerInfo FindNearContainerToAttachTo(BlockDesignerItemViewModel blockDesignerItemViewModel) + { + if (blockDesignerItemViewModel == null) + return null; + + List items; + + items = Items.OfType(). + Where(p => p != blockDesignerItemViewModel) + .ToList(); + + foreach (var port in items.SelectMany(n => n.Contains)) + { + if (port.GetBounds().IntersectsWith(blockDesignerItemViewModel.GetBounds())) //如果两个位置相交 + { + port.DataItem.ShowConnectors = true; + if (port.CanAttachTo(blockDesignerItemViewModel) == true) + { + port.BeAttachTo = true; + } + else + { + port.DisableAttachTo = true; + } + return port; + } + } + + return null; + } + public void ClearNearPort() { Items.OfType().ToList().SelectMany(n => n.Connectors).Where(p => p.BeAttachTo == true || p.DisableAttachTo == true).ToList() @@ -3152,6 +3183,91 @@ namespace AIStudio.Wpf.DiagramDesigner p.DisableAttachTo = false; p.BeAttachTo = false; }); + + + } + + public void ClearNearContain() + { + Items.OfType().ToList().SelectMany(n => n.Contains).Where(p => p.BeAttachTo == true || p.DisableAttachTo == true).ToList() + .ForEach(p => { + p.DisableAttachTo = false; + p.BeAttachTo = false; + }); + } + #endregion + + #region Block拖拽预览-拖拽完成 + public void PreviewNearBlock(List blocks) + { + if (blocks.Any()) + { + ClearNearPort(); + ClearNearContain(); + foreach (BlockDesignerItemViewModel item in blocks) + { + var contain = FindNearContainerToAttachTo(item); + if (contain != null) + { + continue; + } + FindNearPortToAttachTo(item, false); + } + } + } + + + + public void FinishNearBlock(List blocks) + { + if (blocks.Any()) + { + ClearNearPort(); + ClearNearContain(); + foreach (BlockDesignerItemViewModel item in blocks) + { + var contain = FindNearContainerToAttachTo(item); + if (contain != null) + { + (contain.DataItem as BlockDesignerItemViewModel).AddChild(item); + contain.BeAttachTo = false; + contain.DisableAttachTo = false; + continue; + } + + var portTuple = FindNearPortToAttachTo(item, true); + var portParent = portTuple.Item1; + var portNext = portTuple.Item2; + + if (portParent != null) + { + (portParent.DataItem as BlockDesignerItemViewModel).AddNext(item); + portParent.BeAttachTo = false; + portParent.DisableAttachTo = false; + } + else + { + if (item.Parent != null) + { + (item.Parent as BlockDesignerItemViewModel).RemoveNext(); + } + } + + if (portNext != null) + { + item.AddNext(portNext.DataItem as BlockDesignerItemViewModel); + portNext.BeAttachTo = false; + portNext.DisableAttachTo = false; + } + else + { + if (item.Next != null) + { + item.RemoveNext(); + } + } + } + } } #endregion diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModelHelper.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModelHelper.cs index 671a529..4ca1dd9 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModelHelper.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModelHelper.cs @@ -26,8 +26,8 @@ namespace AIStudio.Wpf.DiagramDesigner x1 = Math.Min(item.Left, x1); y1 = Math.Min(item.Top, y1); - x2 = Math.Max(item.Left + item.ItemWidth, x2); - y2 = Math.Max(item.Top + item.ItemHeight, y2); + x2 = Math.Max(item.Left + item.GetItemWidth(), x2); + y2 = Math.Max(item.Top + item.GetItemHeight(), y2); } return new RectangleBase(new PointBase(x1, y1), new PointBase(x2, y2)); diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/BlockContainDesignerItemViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/BlockContainDesignerItemViewModel.cs new file mode 100644 index 0000000..49f05b5 --- /dev/null +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/BlockContainDesignerItemViewModel.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using AIStudio.Wpf.DiagramDesigner.Models; + +namespace AIStudio.Wpf.DiagramDesigner +{ + public class BlockContainDesignerItemViewModel : BlockDesignerItemViewModel + { + public BlockContainDesignerItemViewModel() + { + } + + public BlockContainDesignerItemViewModel(IDiagramViewModel root) : base(root) + { + } + + public BlockContainDesignerItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer) + { + } + + public BlockContainDesignerItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType) + { + } + + protected override void InitNew() + { + base.InitNew(); + + Contains.Add(new ItemsContainerInfo(this.Root, this)); + } + + public override void AddChild(BlockDesignerItemViewModel child) + { + var oldchildren = FirstContain.Children.FirstOrDefault(); + if (oldchildren != null) + { + this.RemoveChild(oldchildren); + } + + Root.Items.Remove(child); + FirstContain.Children.Add(child); + + base.AddChild(child); + } + + public override void RemoveChild(BlockDesignerItemViewModel child) + { + Root.Items.Add(child); + FirstContain.Children.Remove(child); + + this.RemoveFromSelection(); + child.AddToSelection(true, false); + + base.RemoveChild(child); + } + } +} diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/BlockContainListDesignerItemViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/BlockContainListDesignerItemViewModel.cs new file mode 100644 index 0000000..e0b9a7b --- /dev/null +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/BlockContainListDesignerItemViewModel.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using AIStudio.Wpf.DiagramDesigner.Models; + +namespace AIStudio.Wpf.DiagramDesigner +{ + public class BlockContainListDesignerItemViewModel : BlockDesignerItemViewModel + { + public BlockContainListDesignerItemViewModel() + { + } + + public BlockContainListDesignerItemViewModel(IDiagramViewModel root) : base(root) + { + } + + public BlockContainListDesignerItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer) + { + } + + public BlockContainListDesignerItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType) + { + } + + protected override void InitNew() + { + base.InitNew(); + + Contains.Add(new ItemsContainerInfo(this.Root, this)); + } + + public override void AddChild(BlockDesignerItemViewModel child) + { + Root.Items.Remove(child); + FirstContain.Children.Add(child); + + base.AddChild(child); + } + + public override void RemoveChild(BlockDesignerItemViewModel child) + { + Root.Items.Add(child); + FirstContain.Children.Remove(child); + + base.RemoveChild(child); + } + } +} diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/BlockDesignerItemViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/BlockDesignerItemViewModel.cs index 86d2f2a..c203747 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/BlockDesignerItemViewModel.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/BlockDesignerItemViewModel.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -27,28 +28,57 @@ namespace AIStudio.Wpf.DiagramDesigner protected override void InitNew() { + ItemWidth = double.NaN; + ItemHeight = double.NaN; AddConnector(new BlockConnectorInfo(this.Root, this, ConnectorOrientation.Top)); AddConnector(new BlockConnectorInfo(this.Root, this, ConnectorOrientation.Bottom)); + IsReadOnlyText = true; } public BlockDesignerItemViewModel Next { - get;set; + get; set; } public void AddNext(BlockDesignerItemViewModel next) { + this.ParentId = new Guid(); + this.Parent = null; next.Left = this.Left; - next.Top = this.Top + this.ItemHeight; + next.Top = this.Top + this.GetItemHeight(); next.ParentId = this.Id; next.Parent = this; this.Next = next; - if (next.Next != null) + //if (oldnext != null) + //{ + // next.AddNext(oldnext); + //} + } + + public void RemoveNext() + { + var next = this.Next; + if (next != null) { - next.AddNext(next.Next); + next.ParentId = new Guid(); + next.Parent = null; + this.Next = null; } } + public BlockDesignerItemViewModel GetLastNext() + { + var next = this.Next; + if (next != null) + { + while (next.Next != null) + { + next = next.Next; + } + } + return next; + } + public override void AddToSelection(bool selected, bool clearother) { if (clearother) @@ -64,5 +94,31 @@ namespace AIStudio.Wpf.DiagramDesigner IsSelected = selected; } + + + public virtual void AddChild(BlockDesignerItemViewModel child) + { + child.RemoveFromSelection(); + this.AddToSelection(true, false); + } + + public virtual void RemoveChild(BlockDesignerItemViewModel child) + { + this.RemoveFromSelection(); + child.AddToSelection(true, false); + } + + public ObservableCollection Contains + { + get; set; + } = new ObservableCollection(); + + public ItemsContainerInfo FirstContain + { + get + { + return Contains?.FirstOrDefault(); + } + } } } diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/GifImageItemViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/GifImageItemViewModel.cs index dad8b97..b3ab989 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/GifImageItemViewModel.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/DefaultViewModel/GifImageItemViewModel.cs @@ -115,8 +115,8 @@ namespace AIStudio.Wpf.DiagramDesigner FullyCreatedConnectorInfo connector = new FullyCreatedConnectorInfo(this, ConnectorOrientation.None, true); MouseButtonEventArgs mosueArg = ((EventToCommandArgs)parameter).EventArgs as MouseButtonEventArgs; var position = mosueArg.GetPosition(((EventToCommandArgs)parameter).Sender as IInputElement); - connector.XRatio = (position.X - connector.ConnectorWidth / 2) / connector.DataItem.ItemWidth; - connector.YRatio = (position.Y - connector.ConnectorHeight / 2) / connector.DataItem.ItemHeight; + connector.XRatio = (position.X - connector.ConnectorWidth / 2) / connector.DataItem.GetItemWidth(); + connector.YRatio = (position.Y - connector.ConnectorHeight / 2) / connector.DataItem.GetItemHeight(); AddConnector(connector); } diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/IDiagramViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/IDiagramViewModel.cs index ba861c1..68114cc 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/IDiagramViewModel.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/IDiagramViewModel.cs @@ -366,7 +366,11 @@ namespace AIStudio.Wpf.DiagramDesigner FullyCreatedConnectorInfo FindNearPortToAttachTo(ConnectionViewModel partialConnection, ConnectorVertexType connectorVertexType); FullyCreatedConnectorInfo FindNearPortToAttachTo(ConnectionViewModel partialConnection); Tuple FindNearPortToAttachTo(BlockDesignerItemViewModel blockDesignerItemViewModel, bool isExist); + ItemsContainerInfo FindNearContainerToAttachTo(BlockDesignerItemViewModel blockDesignerItemViewModel); void ClearNearPort(); + void ClearNearContain(); + void PreviewNearBlock(List blocks); + void FinishNearBlock(List blocks); #endregion event PropertyChangedEventHandler PropertyChanged; diff --git a/Extensions/AIStudio.Wpf.Block/A.png b/Extensions/AIStudio.Wpf.Block/A.png new file mode 100644 index 0000000000000000000000000000000000000000..b6949fae3d9962793e33e0959509bb6bfed04dc0 GIT binary patch literal 11835 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 TVIkWS0QpFW%6zL3*7p5>@a(=e literal 0 HcmV?d00001 diff --git a/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block.csproj b/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block.csproj new file mode 100644 index 0000000..8c745f5 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block.csproj @@ -0,0 +1,26 @@ + + + + true + AIStudio.Wpf.Controls + akwkevin + https://gitee.com/akwkevin + A.png + + + 1.0.7 + 一个Wpf的流程图控件 + + + + + True + + + + + + + + + diff --git a/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_4a4h4ycz_wpftmp.csproj b/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_4a4h4ycz_wpftmp.csproj new file mode 100644 index 0000000..b366cc1 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_4a4h4ycz_wpftmp.csproj @@ -0,0 +1,246 @@ + + + AIStudio.Wpf.Block + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\Extensions\AIStudio.Wpf.Block\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.Block + + + + true + AIStudio.Wpf.Controls + akwkevin + https://gitee.com/akwkevin + A.png + + + 1.0.7 + 一个Wpf的流程图控件 + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_attaon4q_wpftmp.csproj b/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_attaon4q_wpftmp.csproj new file mode 100644 index 0000000..98ee754 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_attaon4q_wpftmp.csproj @@ -0,0 +1,244 @@ + + + AIStudio.Wpf.Block + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\Extensions\AIStudio.Wpf.Block\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.Block + + + + true + AIStudio.Wpf.Controls + akwkevin + https://gitee.com/akwkevin + A.png + + + 1.0.7 + 一个Wpf的流程图控件 + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_axsfel0m_wpftmp.csproj b/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_axsfel0m_wpftmp.csproj new file mode 100644 index 0000000..18a4093 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_axsfel0m_wpftmp.csproj @@ -0,0 +1,177 @@ + + + AIStudio.Wpf.Block + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\Extensions\AIStudio.Wpf.Block\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.Block + + + + true + AIStudio.Wpf.Controls + akwkevin + https://gitee.com/akwkevin + A.png + + + 1.0.7 + 一个Wpf的流程图控件 + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_gkma3gbh_wpftmp.csproj b/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_gkma3gbh_wpftmp.csproj new file mode 100644 index 0000000..98ee754 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_gkma3gbh_wpftmp.csproj @@ -0,0 +1,244 @@ + + + AIStudio.Wpf.Block + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\Extensions\AIStudio.Wpf.Block\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.Block + + + + true + AIStudio.Wpf.Controls + akwkevin + https://gitee.com/akwkevin + A.png + + + 1.0.7 + 一个Wpf的流程图控件 + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_ohjhbtlx_wpftmp.csproj b/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_ohjhbtlx_wpftmp.csproj new file mode 100644 index 0000000..98ee754 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/AIStudio.Wpf.Block_ohjhbtlx_wpftmp.csproj @@ -0,0 +1,244 @@ + + + AIStudio.Wpf.Block + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\Extensions\AIStudio.Wpf.Block\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.Block + + + + true + AIStudio.Wpf.Controls + akwkevin + https://gitee.com/akwkevin + A.png + + + 1.0.7 + 一个Wpf的流程图控件 + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Extensions/AIStudio.Wpf.Block/Controls/BlockDecorator.cs b/Extensions/AIStudio.Wpf.Block/Controls/BlockDecorator.cs new file mode 100644 index 0000000..df7b037 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/Controls/BlockDecorator.cs @@ -0,0 +1,114 @@ +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; + +namespace AIStudio.Wpf.Block.Controls +{ + public class BlockDecorator : Decorator + { + #region 依赖属性 + public static readonly DependencyProperty BackgroundProperty = + DependencyProperty.Register(nameof(Background), typeof(Brush), typeof(BlockDecorator) + , new PropertyMetadata(new SolidColorBrush(Color.FromRgb(255, 255, 255)))); + /// + /// 背景色,默认值为#FFFFFF,白色 + /// + public Brush Background + { + get + { + return (Brush)GetValue(BackgroundProperty); + } + set + { + SetValue(BackgroundProperty, value); + } + } + + public static readonly DependencyProperty PaddingProperty = + DependencyProperty.Register(nameof(Padding), typeof(Thickness), typeof(BlockDecorator) + , new PropertyMetadata(new Thickness(0, 0, 0, 0))); + /// + /// 内边距 + /// + public Thickness Padding + { + get + { + return (Thickness)GetValue(PaddingProperty); + } + set + { + SetValue(PaddingProperty, value); + } + } + + public static readonly DependencyProperty BorderBrushProperty = + DependencyProperty.Register(nameof(BorderBrush), typeof(Brush), typeof(BlockDecorator) + , new PropertyMetadata(default(Brush))); + /// + /// 边框颜色 + /// + public Brush BorderBrush + { + get + { + return (Brush)GetValue(BorderBrushProperty); + } + set + { + SetValue(BorderBrushProperty, value); + } + } + + public static readonly DependencyProperty BorderThicknessProperty = + DependencyProperty.Register(nameof(BorderThickness), typeof(Thickness), typeof(BlockDecorator), new PropertyMetadata(new Thickness(0d))); + /// + /// 边框大小 + /// + public Thickness BorderThickness + { + get + { + return (Thickness)GetValue(BorderThicknessProperty); + } + set + { + SetValue(BorderThicknessProperty, value); + } + } + #endregion + + protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) + { + Point hitPoint = hitTestParameters.HitPoint; + + // 在此处实现自定义的命中测试逻辑 + if (IsPointInsideCustomRegion(hitPoint)) + { + return new PointHitTestResult(this, hitPoint); + } + + return null; // 不命中 + } + + private bool IsPointInsideCustomRegion(Point point) + { + // 在此处检测点是否在自定义区域内 + // 返回 true 表示命中,返回 false 表示不命中 + return false; + } + + protected Brush CreateFillBrush() + { + Brush result = null; + + System.Windows.Media.GradientStopCollection gsc = new System.Windows.Media.GradientStopCollection(); + gsc.Add(new System.Windows.Media.GradientStop(((SolidColorBrush)this.Background).Color, 0)); + LinearGradientBrush backGroundBrush = new LinearGradientBrush(gsc, new Point(0, 0), new Point(0, 1)); + result = backGroundBrush; + + return result; + } + } +} diff --git a/Extensions/AIStudio.Wpf.Block/Controls/BlockPanel.cs b/Extensions/AIStudio.Wpf.Block/Controls/BlockPanel.cs new file mode 100644 index 0000000..85049a9 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/Controls/BlockPanel.cs @@ -0,0 +1,114 @@ +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; + +namespace AIStudio.Wpf.Block.Controls +{ + public class BlockPanel : Panel + { + #region 依赖属性 + public static readonly DependencyProperty BackgroundProperty = + DependencyProperty.Register(nameof(Background), typeof(Brush), typeof(BlockPanel) + , new PropertyMetadata(new SolidColorBrush(Color.FromRgb(255, 255, 255)))); + /// + /// 背景色,默认值为#FFFFFF,白色 + /// + public Brush Background + { + get + { + return (Brush)GetValue(BackgroundProperty); + } + set + { + SetValue(BackgroundProperty, value); + } + } + + public static readonly DependencyProperty PaddingProperty = + DependencyProperty.Register(nameof(Padding), typeof(Thickness), typeof(BlockPanel) + , new PropertyMetadata(new Thickness(0, 0, 0, 0))); + /// + /// 内边距 + /// + public Thickness Padding + { + get + { + return (Thickness)GetValue(PaddingProperty); + } + set + { + SetValue(PaddingProperty, value); + } + } + + public static readonly DependencyProperty BorderBrushProperty = + DependencyProperty.Register(nameof(BorderBrush), typeof(Brush), typeof(BlockPanel) + , new PropertyMetadata(default(Brush))); + /// + /// 边框颜色 + /// + public Brush BorderBrush + { + get + { + return (Brush)GetValue(BorderBrushProperty); + } + set + { + SetValue(BorderBrushProperty, value); + } + } + + public static readonly DependencyProperty BorderThicknessProperty = + DependencyProperty.Register(nameof(BorderThickness), typeof(Thickness), typeof(BlockPanel), new PropertyMetadata(new Thickness(0d))); + /// + /// 边框大小 + /// + public Thickness BorderThickness + { + get + { + return (Thickness)GetValue(BorderThicknessProperty); + } + set + { + SetValue(BorderThicknessProperty, value); + } + } + #endregion + + protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) + { + Point hitPoint = hitTestParameters.HitPoint; + + // 在此处实现自定义的命中测试逻辑 + if (IsPointInsideCustomRegion(hitPoint)) + { + return new PointHitTestResult(this, hitPoint); + } + + return null; // 不命中 + } + + private bool IsPointInsideCustomRegion(Point point) + { + // 在此处检测点是否在自定义区域内 + // 返回 true 表示命中,返回 false 表示不命中 + return false; + } + + protected Brush CreateFillBrush() + { + Brush result = null; + + System.Windows.Media.GradientStopCollection gsc = new System.Windows.Media.GradientStopCollection(); + gsc.Add(new System.Windows.Media.GradientStop(((SolidColorBrush)this.Background).Color, 0)); + LinearGradientBrush backGroundBrush = new LinearGradientBrush(gsc, new Point(0, 0), new Point(0, 1)); + result = backGroundBrush; + + return result; + } + } +} diff --git a/Extensions/AIStudio.Wpf.Block/Controls/EndBlockBorder.cs b/Extensions/AIStudio.Wpf.Block/Controls/EndBlockBorder.cs new file mode 100644 index 0000000..f61ab79 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/Controls/EndBlockBorder.cs @@ -0,0 +1,144 @@ +using System; +using System.Windows; +using System.Windows.Media; + +namespace AIStudio.Wpf.Block.Controls +{ + public class EndBlockBorder : BlockDecorator + { + public EndBlockBorder() + { + + } + + #region 方法重写 + public double Insideheight { get; set; } = 6; + public double Insidewidth { get; set; } = 21; + public double Insideoffset { get; set; } = 14; + public double Minwidth { get; set; } = 86; + public double Minheight { get; set; } = 34; + /// + /// 该方法用于测量整个控件的大小 + /// + /// + /// 控件的大小 + protected override Size MeasureOverride(Size constraint) + { + Thickness padding = this.Padding; + + Size result = new Size(); + if (Child != null) + { + //测量子控件的大小 + Child.Measure(constraint); + + result.Width = Math.Max(Minwidth, Child.DesiredSize.Width + padding.Left + padding.Right); + result.Height = Math.Max(Minheight, Child.DesiredSize.Height + padding.Top + padding.Bottom); + } + else + { + result.Width = Minwidth; + result.Height = Minheight; + } + return result; + } + + /// + /// 设置子控件的大小与位置 + /// + /// + /// + protected override Size ArrangeOverride(Size arrangeSize) + { + Thickness padding = this.Padding; + if (Child != null) + { + Child.Arrange(new Rect(new Point(padding.Left, padding.Top), + new Size(Math.Max(Minwidth - padding.Left - padding.Right, Child.DesiredSize.Width ), Math.Max(Minheight - padding.Top - padding.Bottom, Child.DesiredSize.Height)))); + } + return arrangeSize; + } + + /// + /// 绘制控件 + /// + /// + protected override void OnRender(DrawingContext drawingContext) + { + Thickness padding = this.Padding; + + Pen pen = new Pen(); + pen.Brush = this.BorderBrush; + pen.Thickness = this.BorderThickness.Left;// NextForBlockBorder.RoundLayoutValue(BorderThickness.Left, DoubleUtil.DpiScaleX); + + Geometry cg = CreateGeometry(Math.Max(Minwidth, Child?.DesiredSize.Width??0 + padding.Left + padding.Right), Math.Max(Minheight, Child?.DesiredSize.Height??0 + padding.Top + padding.Bottom)); + Brush brush = CreateFillBrush(); + + GuidelineSet guideLines = new GuidelineSet(); + drawingContext.PushGuidelineSet(guideLines); + drawingContext.DrawGeometry(brush, pen, cg); + + } + #endregion + + #region 私有方法 + private Geometry CreateGeometry(double x, double y) + { + #region + PathFigure pf = new PathFigure(); + pf.IsClosed = true; + pf.StartPoint = new Point(0, 2); + + //第一横线 + ArcSegment seg1 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(2, 0) }; + pf.Segments.Add(seg1); + + LineSegment seg2 = new LineSegment() { Point = new Point(Insideoffset, 0) }; + pf.Segments.Add(seg2); + + //第二in + QuadraticBezierSegment seg3 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + 1, 0), Point2 = new Point(Insideoffset + 2, 2) }; + pf.Segments.Add(seg3); + + QuadraticBezierSegment seg4 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + 4, 6), Point2 = new Point(Insideoffset + 5, 6) }; + pf.Segments.Add(seg4); + + LineSegment seg5 = new LineSegment() { Point = new Point(Insideoffset + Insidewidth - 5, 6) }; + pf.Segments.Add(seg5); + + QuadraticBezierSegment seg6 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + Insidewidth - 4, 6), Point2 = new Point(Insideoffset + Insidewidth - 2, 2) }; + pf.Segments.Add(seg6); + + QuadraticBezierSegment seg7 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + Insidewidth - 1, 0), Point2 = new Point(Insideoffset + Insidewidth, 0) }; + pf.Segments.Add(seg7); + + //第三横线 + LineSegment seg8 = new LineSegment() { Point = new Point(x - 2, 0) }; + pf.Segments.Add(seg8); + + //第四竖线 + ArcSegment seg9 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x, 2) }; + pf.Segments.Add(seg9); + + LineSegment seg10 = new LineSegment() { Point = new Point(x, y - 2) }; + pf.Segments.Add(seg10); + + //第五横线 + ArcSegment seg11 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x - 2, y) }; + pf.Segments.Add(seg11); + + LineSegment seg12 = new LineSegment() { Point = new Point(2, y) }; + pf.Segments.Add(seg12); + + ArcSegment seg13 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(0, y - 2) }; + pf.Segments.Add(seg13); + + PathGeometry g1 = new PathGeometry(); + g1.Figures.Add(pf); + #endregion + + return g1; + } + #endregion + } +} diff --git a/Extensions/AIStudio.Wpf.Block/Controls/NextBlockBorder.cs b/Extensions/AIStudio.Wpf.Block/Controls/NextBlockBorder.cs new file mode 100644 index 0000000..8552a4a --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/Controls/NextBlockBorder.cs @@ -0,0 +1,164 @@ +using System; +using System.Windows; +using System.Windows.Media; + +namespace AIStudio.Wpf.Block.Controls +{ + public class NextBlockBorder : BlockDecorator + { + public NextBlockBorder() + { + + } + + #region 方法重写 + public double Insideheight { get; set; } = 6; + public double Insidewidth { get; set; } = 21; + public double Insideoffset { get; set; } = 14; + public double Minwidth { get; set; } = 86; + public double Minheight { get; set; } = 34; + /// + /// 该方法用于测量整个控件的大小 + /// + /// + /// 控件的大小 + protected override Size MeasureOverride(Size constraint) + { + Thickness padding = this.Padding; + + Size result = new Size(); + if (Child != null) + { + //测量子控件的大小 + Child.Measure(constraint); + + result.Width = Math.Max(Minwidth, Child.DesiredSize.Width + padding.Left + padding.Right); + result.Height = Math.Max(Minheight, Child.DesiredSize.Height + padding.Top + padding.Bottom); + } + else + { + result.Width = Minwidth; + result.Height = Minheight; + } + return result; + } + + /// + /// 设置子控件的大小与位置 + /// + /// + /// + protected override Size ArrangeOverride(Size arrangeSize) + { + Thickness padding = this.Padding; + if (Child != null) + { + Child.Arrange(new Rect(new Point(padding.Left, padding.Top), + new Size(Math.Max(Minwidth - padding.Left - padding.Right, Child.DesiredSize.Width ), Math.Max(Minheight - padding.Top - padding.Bottom, Child.DesiredSize.Height)))); + } + return arrangeSize; + } + + /// + /// 绘制控件 + /// + /// + protected override void OnRender(DrawingContext drawingContext) + { + Thickness padding = this.Padding; + + Pen pen = new Pen(); + pen.Brush = this.BorderBrush; + pen.Thickness = this.BorderThickness.Left;// NextForBlockBorder.RoundLayoutValue(BorderThickness.Left, DoubleUtil.DpiScaleX); + + Geometry cg = CreateGeometry(Math.Max(Minwidth, Child?.DesiredSize.Width??0 + padding.Left + padding.Right), Math.Max(Minheight, Child?.DesiredSize.Height??0 + padding.Top + padding.Bottom)); + Brush brush = CreateFillBrush(); + + GuidelineSet guideLines = new GuidelineSet(); + drawingContext.PushGuidelineSet(guideLines); + drawingContext.DrawGeometry(brush, pen, cg); + + } + #endregion + + #region 私有方法 + private Geometry CreateGeometry(double x, double y) + { + #region + PathFigure pf = new PathFigure(); + pf.IsClosed = true; + pf.StartPoint = new Point(0, 2); + + //第一横线 + ArcSegment seg1 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(2, 0) }; + pf.Segments.Add(seg1); + + LineSegment seg2 = new LineSegment() { Point = new Point(Insideoffset, 0) }; + pf.Segments.Add(seg2); + + //第二in + QuadraticBezierSegment seg3 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + 1, 0), Point2 = new Point(Insideoffset + 2, 2) }; + pf.Segments.Add(seg3); + + QuadraticBezierSegment seg4 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + 4, 6), Point2 = new Point(Insideoffset + 5, 6) }; + pf.Segments.Add(seg4); + + LineSegment seg5 = new LineSegment() { Point = new Point(Insideoffset + Insidewidth - 5, 6) }; + pf.Segments.Add(seg5); + + QuadraticBezierSegment seg6 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + Insidewidth - 4, 6), Point2 = new Point(Insideoffset + Insidewidth - 2, 2) }; + pf.Segments.Add(seg6); + + QuadraticBezierSegment seg7 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + Insidewidth - 1, 0), Point2 = new Point(Insideoffset + Insidewidth, 0) }; + pf.Segments.Add(seg7); + + //第三横线 + LineSegment seg8 = new LineSegment() { Point = new Point(x - 2, 0) }; + pf.Segments.Add(seg8); + + //第四竖线 + ArcSegment seg9 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x, 2) }; + pf.Segments.Add(seg9); + + LineSegment seg10 = new LineSegment() { Point = new Point(x, y - 2) }; + pf.Segments.Add(seg10); + + //第五横线 + ArcSegment seg11 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x - 2, y) }; + pf.Segments.Add(seg11); + + LineSegment seg12 = new LineSegment() { Point = new Point(Insideoffset + Insidewidth, y) }; + pf.Segments.Add(seg12); + + //第六in + QuadraticBezierSegment seg13 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + Insidewidth - 1, y), Point2 = new Point(Insideoffset + Insidewidth - 2, y + 2) }; + pf.Segments.Add(seg13); + + QuadraticBezierSegment seg14 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + Insidewidth - 4, y + Insideheight), Point2 = new Point(Insideoffset + Insidewidth - 5, y + Insideheight) }; + pf.Segments.Add(seg14); + + LineSegment seg15 = new LineSegment() { Point = new Point(Insideoffset + 5, y + Insideheight) }; + pf.Segments.Add(seg15); + + QuadraticBezierSegment seg16 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + 4, y + Insideheight), Point2 = new Point(Insideoffset + 2, y + 2) }; + pf.Segments.Add(seg16); + + QuadraticBezierSegment seg17 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + 1, y), Point2 = new Point(Insideoffset, y) }; + pf.Segments.Add(seg17); + + //第七横线 + LineSegment seg18 = new LineSegment() { Point = new Point(2, y) }; + pf.Segments.Add(seg18); + + ArcSegment seg19 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(0, y - 2) }; + pf.Segments.Add(seg19); + + PathGeometry g1 = new PathGeometry(); + g1.Figures.Add(pf); + #endregion + + return g1; + } + #endregion + } +} diff --git a/Extensions/AIStudio.Wpf.Block/Controls/NextFor2BlockPanel.cs b/Extensions/AIStudio.Wpf.Block/Controls/NextFor2BlockPanel.cs new file mode 100644 index 0000000..988c193 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/Controls/NextFor2BlockPanel.cs @@ -0,0 +1,435 @@ +using System; +using System.ComponentModel; +using System.Data; +using System.Runtime.InteropServices; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; + +namespace AIStudio.Wpf.Block.Controls +{ + + public class NextFor2BlockPanel : BlockPanel + { + public NextFor2BlockPanel() + { + + } + + #region 方法重写 + private UIElement Header + { + get + { + return InternalChildren.Count >= 0 ? InternalChildren[0] : null; + } + } + + private UIElement Content1 + { + get + { + return InternalChildren.Count >= 1 ? InternalChildren[1] : null; + } + } + + private UIElement Footer1 + { + get + { + return InternalChildren.Count >= 2 ? InternalChildren[2] : null; + } + } + + private UIElement Content2 + { + get + { + return InternalChildren.Count >= 3 ? InternalChildren[3] : null; + } + } + + private UIElement Footer2 + { + get + { + return InternalChildren.Count >= 4 ? InternalChildren[4] : null; + } + } + + public double Insideheight { get; set; } = 6; + public double Insidewidth { get; set; } = 21; + public double insideoffset { get; set; } = 14; + public double Leftpanelwidth { get; set; } = 10; + public double Minwidth { get; set; } = 109; + public double Minheaderheight { get; set; } = 34; + public double Mincontentheight { get; set; } = 16; + public double Minfooterheight { get; set; } = 26; + + + private double _width; + private double _headerheight; + private double _content1height; + private double _footer1height; + private double _content2height; + private double _footer2height; + /// + /// 该方法用于测量整个控件的大小 + /// + /// + /// 控件的大小 + protected override Size MeasureOverride(Size constraint) + { + Thickness padding = this.Padding; + + _width = Minwidth; + if (Header != null) + { + //测量子控件的大小 + Header.Measure(constraint); + _width = Math.Max(Minwidth, Header.DesiredSize.Width + padding.Left + padding.Right); + _headerheight = Math.Max(Minheaderheight, Header.DesiredSize.Height + padding.Top + padding.Bottom); + } + else + { + _headerheight = Minheaderheight; + } + + if (Content1 != null) + { + //测量子控件的大小 + Content1.Measure(constraint); + _width = Math.Max(Minwidth, Content1.DesiredSize.Width + padding.Left + padding.Right + Leftpanelwidth); + _content1height = Math.Max(Mincontentheight, Content1.DesiredSize.Height + padding.Top + padding.Bottom); + } + else + { + _content1height = Mincontentheight; + } + + if (Footer1 != null) + { + //测量子控件的大小 + Footer1.Measure(constraint); + _width = Math.Max(Minwidth, Footer1.DesiredSize.Width + padding.Left + padding.Right); + _footer1height = Math.Max(Minfooterheight, Footer1.DesiredSize.Height + padding.Top + padding.Bottom); + } + else + { + _footer1height = Minfooterheight; + } + + if (Content2!= null) + { + //测量子控件的大小 + Content2.Measure(constraint); + _width = Math.Max(Minwidth, Content2.DesiredSize.Width + padding.Left + padding.Right + Leftpanelwidth); + _content2height = Math.Max(Mincontentheight, Content2.DesiredSize.Height + padding.Top + padding.Bottom); + } + else + { + _content2height = Mincontentheight; + } + + if (Footer2 != null) + { + //测量子控件的大小 + Footer2.Measure(constraint); + _width = Math.Max(Minwidth, Footer2.DesiredSize.Width + padding.Left + padding.Right); + _footer2height = Math.Max(Minfooterheight, Footer2.DesiredSize.Height + padding.Top + padding.Bottom); + } + else + { + _footer2height = Minfooterheight; + } + + return new Size(_width, _headerheight + _content1height + _footer1height + _content2height + _footer2height); + } + + /// + /// 设置子控件的大小与位置 + /// + /// + /// + protected override Size ArrangeOverride(Size arrangeSize) + { + Thickness padding = this.Padding; + + if (Header != null) + { + Header.Arrange(new Rect(new Point(padding.Left, padding.Top), new Size(_width - padding.Left - padding.Right, _headerheight - padding.Top - padding.Bottom))); + } + + + if (Content1 != null) + { + Content1.Arrange(new Rect(new Point(padding.Left + Leftpanelwidth, padding.Top + _headerheight), new Size(_width - Leftpanelwidth - padding.Left - padding.Right, _content1height - padding.Top - padding.Bottom))); + } + + + if (Footer1 != null) + { + Footer1.Arrange(new Rect(new Point(padding.Left, padding.Top + _headerheight + _content1height), new Size(_width - padding.Left - padding.Right, _footer1height - padding.Top - padding.Bottom))); + } + + if (Content2 != null) + { + Content2.Arrange(new Rect(new Point(padding.Left + Leftpanelwidth, padding.Top + _headerheight + _content1height + _footer1height), new Size(_width - Leftpanelwidth - padding.Left - padding.Right, _content2height - padding.Top - padding.Bottom))); + } + + + if (Footer2 != null) + { + Footer2.Arrange(new Rect(new Point(padding.Left, padding.Top + _headerheight + _content1height + _footer1height + _content2height), new Size(_width - padding.Left - padding.Right, _footer2height - padding.Top - padding.Bottom))); + } + + + return base.ArrangeOverride(arrangeSize); + } + + /// + /// 绘制控件 + /// + /// + protected override void OnRender(DrawingContext drawingContext) + { + Thickness padding = this.Padding; + + Pen pen = new Pen(); + pen.Brush = this.BorderBrush; + pen.Thickness = this.BorderThickness.Left;// NextForBlockBorder.RoundLayoutValue(BorderThickness.Left, DoubleUtil.DpiScaleX); + + Geometry cg = CreateGeometry(_width, _headerheight, _content1height, _footer1height, _content2height, _footer2height); + Brush brush = CreateFillBrush(); + + GuidelineSet guideLines = new GuidelineSet(); + drawingContext.PushGuidelineSet(guideLines); + drawingContext.DrawGeometry(brush, pen, cg); + + base.OnRender(drawingContext); + } + #endregion + + #region 私有方法 + private Geometry CreateGeometry(double x, double y0, double y1, double y2, double y3, double y4) + { + #region + PathFigure pf = new PathFigure(); + pf.IsClosed = true; + pf.StartPoint = new Point(0, 2); + + //第一横线 + ArcSegment seg1 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(2, 0) }; + pf.Segments.Add(seg1); + + LineSegment seg2 = new LineSegment() { Point = new Point(insideoffset, 0) }; + pf.Segments.Add(seg2); + + //第二in + QuadraticBezierSegment seg3 = new QuadraticBezierSegment() { Point1 = new Point(insideoffset + 1, 0), Point2 = new Point(insideoffset + 2, 2) }; + pf.Segments.Add(seg3); + + QuadraticBezierSegment seg4 = new QuadraticBezierSegment() { Point1 = new Point(insideoffset + 4, Insideheight), Point2 = new Point(insideoffset + 5, Insideheight) }; + pf.Segments.Add(seg4); + + LineSegment seg5 = new LineSegment() { Point = new Point(insideoffset + Insidewidth - 5, Insideheight) }; + pf.Segments.Add(seg5); + + QuadraticBezierSegment seg6 = new QuadraticBezierSegment() { Point1 = new Point(insideoffset + Insidewidth - 4, Insideheight), Point2 = new Point(insideoffset + Insidewidth - 2, 2) }; + pf.Segments.Add(seg6); + + QuadraticBezierSegment seg7 = new QuadraticBezierSegment() { Point1 = new Point(insideoffset + Insidewidth - 1, 0), Point2 = new Point(insideoffset + Insidewidth, 0) }; + pf.Segments.Add(seg7); + + //第三横线 + LineSegment seg8 = new LineSegment() { Point = new Point(x - 2, 0) }; + pf.Segments.Add(seg8); + + //第四竖线 + ArcSegment seg9 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x, 2) }; + pf.Segments.Add(seg9); + + LineSegment seg10 = new LineSegment() { Point = new Point(x, y0 - 2) }; + pf.Segments.Add(seg10); + + //第五横线 + ArcSegment seg11 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x - 2, y0) }; + pf.Segments.Add(seg11); + + LineSegment seg12 = new LineSegment() { Point = new Point(Leftpanelwidth + insideoffset + Insidewidth, y0) }; + pf.Segments.Add(seg12); + + //第六in + QuadraticBezierSegment seg13 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + insideoffset + Insidewidth - 1, y0), Point2 = new Point(Leftpanelwidth + insideoffset + Insidewidth - 2, y0 + 2) }; + pf.Segments.Add(seg13); + + QuadraticBezierSegment seg14 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + insideoffset + Insidewidth - 4, y0 + Insideheight), Point2 = new Point(Leftpanelwidth + insideoffset + Insidewidth - 5, y0 + Insideheight) }; + pf.Segments.Add(seg14); + + LineSegment seg15 = new LineSegment() { Point = new Point(Leftpanelwidth + insideoffset + 5, y0 + Insideheight) }; + pf.Segments.Add(seg15); + + QuadraticBezierSegment seg16 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + insideoffset + 4, y0 + Insideheight), Point2 = new Point(Leftpanelwidth + insideoffset + 2, y0 + 2) }; + pf.Segments.Add(seg16); + + QuadraticBezierSegment seg17 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + insideoffset + 1, y0), Point2 = new Point(insideoffset, y0) }; + pf.Segments.Add(seg17); + + //第七横线 + LineSegment seg18 = new LineSegment() { Point = new Point(Leftpanelwidth + 2, y0) }; + pf.Segments.Add(seg18); + + ArcSegment seg19 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Counterclockwise, Point = new Point(Leftpanelwidth, y0 + 2) }; + pf.Segments.Add(seg19); + + //第八竖线 + LineSegment seg20 = new LineSegment() { Point = new Point(Leftpanelwidth, y0 + y1 - 2) }; + pf.Segments.Add(seg20); + + ArcSegment seg21 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Counterclockwise, Point = new Point(Leftpanelwidth + 2, y0 + y1) }; + pf.Segments.Add(seg21); + + //第九横线 + LineSegment seg22 = new LineSegment() { Point = new Point(Leftpanelwidth + insideoffset, y0 + y1) }; + pf.Segments.Add(seg22); + + //第十in + QuadraticBezierSegment seg23 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + insideoffset + 1, y0 + y1), Point2 = new Point(Leftpanelwidth + insideoffset + 2, y0 + y1 + 2) }; + pf.Segments.Add(seg23); + + QuadraticBezierSegment seg24 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + insideoffset + 4, y0 + y1 + Insideheight), Point2 = new Point(Leftpanelwidth + insideoffset + 5, y0 + y1 + Insideheight) }; + pf.Segments.Add(seg24); + + LineSegment seg25 = new LineSegment() { Point = new Point(Leftpanelwidth + insideoffset + Insidewidth - 5, y0 + y1 + Insideheight) }; + pf.Segments.Add(seg25); + + QuadraticBezierSegment seg26 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + insideoffset + Insidewidth - 4, y0 + y1 + Insideheight), Point2 = new Point(Leftpanelwidth + insideoffset + Insidewidth - 2, y0 + y1 + 2) }; + pf.Segments.Add(seg26); + + QuadraticBezierSegment seg27 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + insideoffset + Insidewidth - 1, y0 + y1), Point2 = new Point(Leftpanelwidth + insideoffset + Insidewidth, y0 + y1) }; + pf.Segments.Add(seg27); + + //第十一横线 + LineSegment seg28 = new LineSegment() { Point = new Point(x - 2, y0 + y1) }; + pf.Segments.Add(seg28); + + //第十二竖线 + ArcSegment seg29 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x, y0 + y1 + 2) }; + pf.Segments.Add(seg29); + + LineSegment seg30 = new LineSegment() { Point = new Point(x, y0 + y1 + y2 - 2) }; + pf.Segments.Add(seg30); + + //第十三横线 + ArcSegment seg31 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x - 2, y0 + y1 + y2) }; + pf.Segments.Add(seg31); + + + + LineSegment seg32 = new LineSegment() { Point = new Point(Leftpanelwidth + insideoffset + Insidewidth, y0 + y1 + y2) }; + pf.Segments.Add(seg32); + + //第十四in + QuadraticBezierSegment seg33 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + insideoffset + Insidewidth - 1, y0 + y1 + y2), Point2 = new Point(Leftpanelwidth + insideoffset + Insidewidth - 2, y0 + y1 + y2 + 2) }; + pf.Segments.Add(seg33); + + QuadraticBezierSegment seg34 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + insideoffset + Insidewidth - 4, y0 + y1 + y2 + Insideheight), Point2 = new Point(Leftpanelwidth + insideoffset + Insidewidth - 5, y0 + y1 + y2 + Insideheight) }; + pf.Segments.Add(seg34); + + LineSegment seg35 = new LineSegment() { Point = new Point(Leftpanelwidth + insideoffset + 5, y0 + y1 + y2 + Insideheight) }; + pf.Segments.Add(seg35); + + QuadraticBezierSegment seg36 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + insideoffset + 4, y0 + y1 + y2 + Insideheight), Point2 = new Point(Leftpanelwidth + insideoffset + 2, y0 + y1 + y2 + 2) }; + pf.Segments.Add(seg36); + + QuadraticBezierSegment seg37 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + insideoffset + 1, y0 + y1 + y2), Point2 = new Point(Leftpanelwidth + insideoffset, y0 + y1 + y2) }; + pf.Segments.Add(seg37); + + //第十五横线 + LineSegment seg38 = new LineSegment() { Point = new Point(Leftpanelwidth + 2, y0 + y1 + y2) }; + pf.Segments.Add(seg38); + + ArcSegment seg39 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Counterclockwise, Point = new Point(Leftpanelwidth, y0 + y1 + y2 + 2) }; + pf.Segments.Add(seg39); + + //第十六竖向 + LineSegment seg40 = new LineSegment() { Point = new Point(Leftpanelwidth, y0 + y1 + y2 + y3 - 2) }; + pf.Segments.Add(seg40); + + ArcSegment seg41 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Counterclockwise, Point = new Point(Leftpanelwidth + 2, y0 + y1 + y2 + y3) }; + pf.Segments.Add(seg41); + + //第十七横线 + LineSegment seg42 = new LineSegment() { Point = new Point(Leftpanelwidth + insideoffset, y0 + y1 + y2 + y3) }; + pf.Segments.Add(seg42); + + //第十八in + QuadraticBezierSegment seg43 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + insideoffset + 1, y0 + y1 + y2 + y3), Point2 = new Point(Leftpanelwidth + insideoffset + 2, y0 + y1 + y2 + y3 + 2) }; + pf.Segments.Add(seg43); + + QuadraticBezierSegment seg44 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + insideoffset + 4, y0 + y1 + y2 + y3 + Insideheight), Point2 = new Point(Leftpanelwidth + insideoffset + 5, y0 + y1 + y2 + y3 + Insideheight) }; + pf.Segments.Add(seg44); + + LineSegment seg45 = new LineSegment() { Point = new Point(Leftpanelwidth + insideoffset + Insidewidth - 5, y0 + y1 + y2 + y3 + Insideheight) }; + pf.Segments.Add(seg45); + + QuadraticBezierSegment seg46 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + insideoffset + Insidewidth - 4, y0 + y1 + y2 + y3 + Insideheight), Point2 = new Point(Leftpanelwidth + insideoffset + Insidewidth - 2, y0 + y1 + y2 + y3 + 2) }; + pf.Segments.Add(seg46); + + QuadraticBezierSegment seg47 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + insideoffset + Insidewidth - 1, y0 + y1 + y2 + y3), Point2 = new Point(Leftpanelwidth + insideoffset + Insidewidth, y0 + y1 + y2 + y3) }; + pf.Segments.Add(seg47); + + //第十一横线 + LineSegment seg48 = new LineSegment() { Point = new Point(x - 2, y0 + y1 + y2 + y3) }; + pf.Segments.Add(seg48); + + //第十二竖线 + ArcSegment seg49 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x, y0 + y1 + y2 + y3 + 2) }; + pf.Segments.Add(seg49); + + LineSegment seg50 = new LineSegment() { Point = new Point(x, y0 + y1 + y2 + y3 + y4 - 2) }; + pf.Segments.Add(seg50); + + //第十三横线 + ArcSegment seg51 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x - 2, y0 + y1 + y2 + y3 + y4) }; + pf.Segments.Add(seg51); + + + + LineSegment seg52 = new LineSegment() { Point = new Point(insideoffset + Insidewidth, y0 + y1 + y2 + y3 + y4) }; + pf.Segments.Add(seg52); + + //第十四in + QuadraticBezierSegment seg53 = new QuadraticBezierSegment() { Point1 = new Point(insideoffset + Insidewidth - 1, y0 + y1 + y2 + y3 + y4), Point2 = new Point(insideoffset + Insidewidth - 2, y0 + y1 + y2 + y3 + y4 + 2) }; + pf.Segments.Add(seg53); + + QuadraticBezierSegment seg54 = new QuadraticBezierSegment() { Point1 = new Point(insideoffset + Insidewidth - 4, y0 + y1 + y2 + y3 + y4 + Insideheight), Point2 = new Point(insideoffset + Insidewidth - 5, y0 + y1 + y2 + y3 + y4 + Insideheight) }; + pf.Segments.Add(seg54); + + LineSegment seg55 = new LineSegment() { Point = new Point(insideoffset + 5, y0 + y1 + y2 + y3 + y4 + Insideheight) }; + pf.Segments.Add(seg55); + + QuadraticBezierSegment seg56 = new QuadraticBezierSegment() { Point1 = new Point(insideoffset + 4, y0 + y1 + y2 + y3 + y4 + Insideheight), Point2 = new Point(insideoffset + 2, y0 + y1 + y2 + y3 + y4 + 2) }; + pf.Segments.Add(seg56); + + QuadraticBezierSegment seg57 = new QuadraticBezierSegment() { Point1 = new Point(insideoffset + 1, y0 + y1 + y2 + y3 + y4), Point2 = new Point(insideoffset, y0 + y1 + y2 + y3 + y4) }; + pf.Segments.Add(seg57); + + //第十五横线 + LineSegment seg58 = new LineSegment() { Point = new Point(2, y0 + y1 + y2 + y3 + y4) }; + pf.Segments.Add(seg58); + + ArcSegment seg59 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Counterclockwise, Point = new Point(0, y0 + y1 + y2 + y3 + y4 - 2) }; + pf.Segments.Add(seg59); + + + PathGeometry g1 = new PathGeometry(); + g1.Figures.Add(pf); + #endregion + + return g1; + } + + #endregion + } +} diff --git a/Extensions/AIStudio.Wpf.Block/Controls/NextForBlockPanel.cs b/Extensions/AIStudio.Wpf.Block/Controls/NextForBlockPanel.cs new file mode 100644 index 0000000..5880309 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/Controls/NextForBlockPanel.cs @@ -0,0 +1,309 @@ +using System; +using System.ComponentModel; +using System.Data; +using System.Runtime.InteropServices; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; + +namespace AIStudio.Wpf.Block.Controls +{ + + public class NextForBlockPanel : BlockPanel + { + public NextForBlockPanel() + { + + } + + #region 方法重写 + private UIElement Header + { + get + { + return InternalChildren.Count >= 0 ? InternalChildren[0] : null; + } + } + + private UIElement Content + { + get + { + return InternalChildren.Count >= 1 ? InternalChildren[1] : null; + } + } + + private UIElement Footer + { + get + { + return InternalChildren.Count >= 2 ? InternalChildren[2] : null; + } + } + + public double Insideheight { get; set; } = 6; + public double Insidewidth { get; set; } = 21; + public double Insideoffset { get; set; } = 14; + public double Leftpanelwidth { get; set; } = 10; + public double Minwidth { get; set; } = 109; + public double Minheaderheight { get; set; } = 34; + public double Mincontentheight { get; set; } = 16; + public double Minfooterheight { get; set; } = 26; + + + private double _width; + private double _headerheight; + private double _contentheight; + private double _footerheight; + /// + /// 该方法用于测量整个控件的大小 + /// + /// + /// 控件的大小 + protected override Size MeasureOverride(Size constraint) + { + Thickness padding = this.Padding; + + _width = Minwidth; + if (Header != null) + { + //测量子控件的大小 + Header.Measure(constraint); + _width = Math.Max(Minwidth, Header.DesiredSize.Width + padding.Left + padding.Right); + _headerheight = Math.Max(Minheaderheight, Header.DesiredSize.Height + padding.Top + padding.Bottom); + } + else + { + _headerheight = Minheaderheight; + } + + if (Content != null) + { + //测量子控件的大小 + Content.Measure(constraint); + _width = Math.Max(Minwidth, Content.DesiredSize.Width + padding.Left + padding.Right + Leftpanelwidth); + _contentheight = Math.Max(Mincontentheight, Content.DesiredSize.Height + padding.Top + padding.Bottom); + } + else + { + _contentheight = Mincontentheight; + } + + if (Footer != null) + { + //测量子控件的大小 + Footer.Measure(constraint); + _width = Math.Max(Minwidth, Footer.DesiredSize.Width + padding.Left + padding.Right); + _footerheight = Math.Max(Minfooterheight, Footer.DesiredSize.Height + padding.Top + padding.Bottom); + } + else + { + _footerheight = Minfooterheight; + } + + return new Size(_width, _headerheight + _contentheight + _footerheight); + } + + /// + /// 设置子控件的大小与位置 + /// + /// + /// + protected override Size ArrangeOverride(Size arrangeSize) + { + Thickness padding = this.Padding; + + if (Header != null) + { + Header.Arrange(new Rect(new Point(padding.Left, padding.Top), new Size(_width - padding.Left - padding.Right, _headerheight - padding.Top - padding.Bottom))); + } + + + if (Content != null) + { + Content.Arrange(new Rect(new Point(padding.Left + Leftpanelwidth, padding.Top + _headerheight), new Size(_width - Leftpanelwidth - padding.Left - padding.Right, _contentheight - padding.Top - padding.Bottom))); + } + + + if (Footer != null) + { + Footer.Arrange(new Rect(new Point(padding.Left, padding.Top + _headerheight + _contentheight), new Size(_width - padding.Left - padding.Right, _footerheight - padding.Top - padding.Bottom))); + } + + + return base.ArrangeOverride(arrangeSize); + } + + /// + /// 绘制控件 + /// + /// + protected override void OnRender(DrawingContext drawingContext) + { + Thickness padding = this.Padding; + + Pen pen = new Pen(); + pen.Brush = this.BorderBrush; + pen.Thickness = this.BorderThickness.Left;// NextForBlockBorder.RoundLayoutValue(BorderThickness.Left, DoubleUtil.DpiScaleX); + + Geometry cg = CreateGeometry(_width, _headerheight, _contentheight, _footerheight); + Brush brush = CreateFillBrush(); + + GuidelineSet guideLines = new GuidelineSet(); + drawingContext.PushGuidelineSet(guideLines); + drawingContext.DrawGeometry(brush, pen, cg); + + base.OnRender(drawingContext); + } + #endregion + + #region 私有方法 + private Geometry CreateGeometry(double x, double y0, double y1, double y2) + { + #region + PathFigure pf = new PathFigure(); + pf.IsClosed = true; + pf.StartPoint = new Point(0, 2); + + //第一横线 + ArcSegment seg1 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(2, 0) }; + pf.Segments.Add(seg1); + + LineSegment seg2 = new LineSegment() { Point = new Point(Insideoffset, 0) }; + pf.Segments.Add(seg2); + + //第二in + QuadraticBezierSegment seg3 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + 1, 0), Point2 = new Point(Insideoffset + 2, 2) }; + pf.Segments.Add(seg3); + + QuadraticBezierSegment seg4 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + 4, Insideheight), Point2 = new Point(Insideoffset + 5, Insideheight) }; + pf.Segments.Add(seg4); + + LineSegment seg5 = new LineSegment() { Point = new Point(Insideoffset + Insidewidth - 5, Insideheight) }; + pf.Segments.Add(seg5); + + QuadraticBezierSegment seg6 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + Insidewidth - 4, Insideheight), Point2 = new Point(Insideoffset + Insidewidth - 2, 2) }; + pf.Segments.Add(seg6); + + QuadraticBezierSegment seg7 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + Insidewidth - 1, 0), Point2 = new Point(Insideoffset + Insidewidth, 0) }; + pf.Segments.Add(seg7); + + //第三横线 + LineSegment seg8 = new LineSegment() { Point = new Point(x - 2, 0) }; + pf.Segments.Add(seg8); + + //第四竖线 + ArcSegment seg9 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x, 2) }; + pf.Segments.Add(seg9); + + LineSegment seg10 = new LineSegment() { Point = new Point(x, y0 - 2) }; + pf.Segments.Add(seg10); + + //第五横线 + ArcSegment seg11 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x - 2, y0) }; + pf.Segments.Add(seg11); + + LineSegment seg12 = new LineSegment() { Point = new Point(Leftpanelwidth + Insideoffset + Insidewidth, y0) }; + pf.Segments.Add(seg12); + + //第六in + QuadraticBezierSegment seg13 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + Insideoffset + Insidewidth - 1, y0), Point2 = new Point(Leftpanelwidth + Insideoffset + Insidewidth - 2, y0 + 2) }; + pf.Segments.Add(seg13); + + QuadraticBezierSegment seg14 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + Insideoffset + Insidewidth - 4, y0 + Insideheight), Point2 = new Point(Leftpanelwidth + Insideoffset + Insidewidth - 5, y0 + Insideheight) }; + pf.Segments.Add(seg14); + + LineSegment seg15 = new LineSegment() { Point = new Point(Leftpanelwidth + Insideoffset + 5, y0 + Insideheight) }; + pf.Segments.Add(seg15); + + QuadraticBezierSegment seg16 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + Insideoffset + 4, y0 + Insideheight), Point2 = new Point(Leftpanelwidth + Insideoffset + 2, y0 + 2) }; + pf.Segments.Add(seg16); + + QuadraticBezierSegment seg17 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + Insideoffset + 1, y0), Point2 = new Point(Insideoffset, y0) }; + pf.Segments.Add(seg17); + + //第七横线 + LineSegment seg18 = new LineSegment() { Point = new Point(Leftpanelwidth + 2, y0) }; + pf.Segments.Add(seg18); + + ArcSegment seg19 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Counterclockwise, Point = new Point(Leftpanelwidth, y0 + 2) }; + pf.Segments.Add(seg19); + + //第八竖线 + LineSegment seg20 = new LineSegment() { Point = new Point(Leftpanelwidth, y0 + y1 - 2) }; + pf.Segments.Add(seg20); + + ArcSegment seg21 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Counterclockwise, Point = new Point(Leftpanelwidth + 2, y0 + y1) }; + pf.Segments.Add(seg21); + + //第九横线 + LineSegment seg22 = new LineSegment() { Point = new Point(Leftpanelwidth + Insideoffset, y0 + y1) }; + pf.Segments.Add(seg22); + + //第十in + QuadraticBezierSegment seg23 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + Insideoffset + 1, y0 + y1), Point2 = new Point(Leftpanelwidth + Insideoffset + 2, y0 + y1 + 2) }; + pf.Segments.Add(seg23); + + QuadraticBezierSegment seg24 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + Insideoffset + 4, y0 + y1 + Insideheight), Point2 = new Point(Leftpanelwidth + Insideoffset + 5, y0 + y1 + Insideheight) }; + pf.Segments.Add(seg24); + + LineSegment seg25 = new LineSegment() { Point = new Point(Leftpanelwidth + Insideoffset + Insidewidth - 5, y0 + y1 + Insideheight) }; + pf.Segments.Add(seg25); + + QuadraticBezierSegment seg26 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + Insideoffset + Insidewidth - 4, y0 + y1 + Insideheight), Point2 = new Point(Leftpanelwidth + Insideoffset + Insidewidth - 2, y0 + y1 + 2) }; + pf.Segments.Add(seg26); + + QuadraticBezierSegment seg27 = new QuadraticBezierSegment() { Point1 = new Point(Leftpanelwidth + Insideoffset + Insidewidth - 1, y0 + y1), Point2 = new Point(Leftpanelwidth + Insideoffset + Insidewidth, y0 + y1) }; + pf.Segments.Add(seg27); + + //第十一横线 + LineSegment seg28 = new LineSegment() { Point = new Point(x - 2, y0 + y1) }; + pf.Segments.Add(seg28); + + //第十二竖线 + ArcSegment seg29 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x, y0 + y1 + 2) }; + pf.Segments.Add(seg29); + + LineSegment seg30 = new LineSegment() { Point = new Point(x, y0 + y1 + y2 - 2) }; + pf.Segments.Add(seg30); + + //第十三横线 + ArcSegment seg31 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x - 2, y0 + y1 + y2) }; + pf.Segments.Add(seg31); + + LineSegment seg32 = new LineSegment() { Point = new Point(Insideoffset + Insidewidth, y0 + y1 + y2) }; + pf.Segments.Add(seg32); + + //第十四in + QuadraticBezierSegment seg33 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + Insidewidth - 1, y0 + y1 + y2), Point2 = new Point(Insideoffset + Insidewidth - 2, y0 + y1 + y2 + 2) }; + pf.Segments.Add(seg33); + + QuadraticBezierSegment seg34 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + Insidewidth - 4, y0 + y1 + y2 + Insideheight), Point2 = new Point(Insideoffset + Insidewidth - 5, y0 + y1 + y2 + Insideheight) }; + pf.Segments.Add(seg34); + + LineSegment seg35 = new LineSegment() { Point = new Point(Insideoffset + 5, y0 + y1 + y2 + Insideheight) }; + pf.Segments.Add(seg35); + + QuadraticBezierSegment seg36 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + 4, y0 + y1 + y2 + Insideheight), Point2 = new Point(Insideoffset + 2, y0 + y1 + y2 + 2) }; + pf.Segments.Add(seg36); + + QuadraticBezierSegment seg37 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + 1, y0 + y1 + y2), Point2 = new Point(Insideoffset, y0 + y1 + y2) }; + pf.Segments.Add(seg37); + + //第十五横线 + LineSegment seg38 = new LineSegment() { Point = new Point(2, y0 + y1 + y2) }; + pf.Segments.Add(seg38); + + ArcSegment seg39 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(0, y0 + y1 + y2 - 2) }; + pf.Segments.Add(seg39); + + PathGeometry g1 = new PathGeometry(); + g1.Figures.Add(pf); + #endregion + + return g1; + } + + #endregion + } +} diff --git a/Extensions/AIStudio.Wpf.Block/Controls/OperationBlockBorder.cs b/Extensions/AIStudio.Wpf.Block/Controls/OperationBlockBorder.cs new file mode 100644 index 0000000..723afb1 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/Controls/OperationBlockBorder.cs @@ -0,0 +1,114 @@ +using System; +using System.Windows; +using System.Windows.Media; + +namespace AIStudio.Wpf.Block.Controls +{ + public class OperationBlockBorder : BlockDecorator + { + public OperationBlockBorder() + { + + } + + #region 方法重写 + public double Minwidth { get; set; } = 100; + public double Minheight { get; set; } = 30; + + /// + /// 该方法用于测量整个控件的大小 + /// + /// + /// 控件的大小 + protected override Size MeasureOverride(Size constraint) + { + Thickness padding = this.Padding; + + Size result = new Size(); + if (Child != null) + { + //测量子控件的大小 + Child.Measure(constraint); + + result.Width = Math.Max(Minwidth, Child.DesiredSize.Width + padding.Left + padding.Right); + result.Height = Math.Max(Minheight, Child.DesiredSize.Height + padding.Top + padding.Bottom); + } + else + { + result.Width = Minwidth; + result.Height = Minheight; + } + return result; + } + + /// + /// 设置子控件的大小与位置 + /// + /// + /// + protected override Size ArrangeOverride(Size arrangeSize) + { + Thickness padding = this.Padding; + if (Child != null) + { + Child.Arrange(new Rect(new Point(padding.Left, padding.Top), + new Size(Math.Max(Minwidth - padding.Left - padding.Right, Child.DesiredSize.Width), Math.Max(Minheight - padding.Top - padding.Bottom, Child.DesiredSize.Height)))); + } + return arrangeSize; + } + + /// + /// 绘制控件 + /// + /// + protected override void OnRender(DrawingContext drawingContext) + { + Thickness padding = this.Padding; + + Pen pen = new Pen(); + pen.Brush = this.BorderBrush; + pen.Thickness = this.BorderThickness.Left;// NextForBlockBorder.RoundLayoutValue(BorderThickness.Left, DoubleUtil.DpiScaleX); + + Geometry cg = CreateGeometry(Math.Max(Minwidth, Child?.DesiredSize.Width ?? 0 + padding.Left + padding.Right), Math.Max(Minheight, Child?.DesiredSize.Height ?? 0 + padding.Top + padding.Bottom)); + Brush brush = CreateFillBrush(); + + GuidelineSet guideLines = new GuidelineSet(); + drawingContext.PushGuidelineSet(guideLines); + drawingContext.DrawGeometry(brush, pen, cg); + } + #endregion + + #region 私有方法 + //按Element的大小计算 + private Geometry CreateGeometry(double x, double y) + { + #region + PathFigure pf = new PathFigure(); + pf.IsClosed = true; + pf.StartPoint = new Point(0, y/ 2 + 1); + + + LineSegment seg1 = new LineSegment() { Point = new Point(y / 2 + 1, 0) }; + pf.Segments.Add(seg1); + + LineSegment seg2 = new LineSegment() { Point = new Point(x - y / 2 - 1, 0) }; + pf.Segments.Add(seg2); + + LineSegment seg3 = new LineSegment() { Point = new Point(x, y / 2) }; + pf.Segments.Add(seg3); + + LineSegment seg4 = new LineSegment() { Point = new Point(x - y / 2 - 1, y) }; + pf.Segments.Add(seg4); + + LineSegment seg5 = new LineSegment() { Point = new Point(y / 2 + 1, y) }; + pf.Segments.Add(seg5); + + PathGeometry g1 = new PathGeometry(); + g1.Figures.Add(pf); + #endregion + + return g1; + } + #endregion + } +} diff --git a/Extensions/AIStudio.Wpf.Block/Controls/StartBlockBorder.cs b/Extensions/AIStudio.Wpf.Block/Controls/StartBlockBorder.cs new file mode 100644 index 0000000..393646e --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/Controls/StartBlockBorder.cs @@ -0,0 +1,147 @@ +using System; +using System.Windows; +using System.Windows.Media; + +namespace AIStudio.Wpf.Block.Controls +{ + public class StartBlockBorder : BlockDecorator + { + public StartBlockBorder() + { + + } + + #region 方法重写 + public double Outsideheight { get; set; } = 13; + public double Outsidewidth { get; set; } = 70; + public double Insideheight { get; set; } = 6; + public double Insidewidth { get; set; } = 21; + public double Insideoffset { get; set; } = 14; + public double Minwidth { get; set; } = 86; + public double Minheight { get; set; } = 47; + + /// + /// 该方法用于测量整个控件的大小 + /// + /// + /// 控件的大小 + protected override Size MeasureOverride(Size constraint) + { + Thickness padding = this.Padding; + + Size result = new Size(); + if (Child != null) + { + //测量子控件的大小 + Child.Measure(constraint); + + result.Width = Math.Max(Minwidth, Child.DesiredSize.Width + padding.Left + padding.Right); + result.Height = Math.Max(Minheight, Child.DesiredSize.Height + padding.Top + padding.Bottom + Outsideheight); + } + else + { + result.Width = Minwidth; + result.Height = Minheight; + } + return result; + } + + /// + /// 设置子控件的大小与位置 + /// + /// + /// + protected override Size ArrangeOverride(Size arrangeSize) + { + Thickness padding = this.Padding; + if (Child != null) + { + Child.Arrange(new Rect(new Point(padding.Left, Outsideheight + padding.Top), + new Size(Math.Max(Minwidth - padding.Left - padding.Right, Child.DesiredSize.Width), Math.Max(Minheight - Outsideheight - padding.Top - padding.Bottom, Child.DesiredSize.Height )))); + } + return arrangeSize; + } + + /// + /// 绘制控件 + /// + /// + protected override void OnRender(DrawingContext drawingContext) + { + Thickness padding = this.Padding; + + Pen pen = new Pen(); + pen.Brush = this.BorderBrush; + pen.Thickness = this.BorderThickness.Left;// NextForBlockBorder.RoundLayoutValue(BorderThickness.Left, DoubleUtil.DpiScaleX); + + Geometry cg = CreateGeometry(Math.Max(Minwidth, Child?.DesiredSize.Width ?? 0 + padding.Left + padding.Right), Math.Max(Minheight - Outsideheight, Child?.DesiredSize.Height ?? 0 + padding.Top + padding.Bottom)); + Brush brush = CreateFillBrush(); + + GuidelineSet guideLines = new GuidelineSet(); + drawingContext.PushGuidelineSet(guideLines); + drawingContext.DrawGeometry(brush, pen, cg); + } + #endregion + + #region 私有方法 + //按Element的大小计算 + private Geometry CreateGeometry(double x, double y) + { + #region + PathFigure pf = new PathFigure(); + pf.IsClosed = true; + pf.StartPoint = new Point(0, Outsideheight); + + //第一横线 + QuadraticBezierSegment seg1 = new QuadraticBezierSegment() { Point1 = new Point(Outsidewidth / 2, 3 - Outsideheight), Point2 = new Point(Outsidewidth, Outsideheight) }; + pf.Segments.Add(seg1); + + LineSegment seg2 = new LineSegment() { Point = new Point(x - 2, Outsideheight) }; + pf.Segments.Add(seg2); + + //第二竖线 + ArcSegment seg3 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x, Outsideheight + 2) }; + pf.Segments.Add(seg3); + + LineSegment seg4 = new LineSegment() { Point = new Point(x, Outsideheight + y - 2) }; + pf.Segments.Add(seg4); + + //第三横线 + ArcSegment seg5 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x - 2, Outsideheight + y) }; + pf.Segments.Add(seg5); + + LineSegment seg6 = new LineSegment() { Point = new Point(Insideoffset + Insidewidth, Outsideheight + y) }; + pf.Segments.Add(seg6); + + //第四in + QuadraticBezierSegment seg7 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + Insidewidth - 1, Outsideheight + y), Point2 = new Point(Insideoffset + Insidewidth - 2, Outsideheight + y + 2) }; + pf.Segments.Add(seg7); + + QuadraticBezierSegment seg8 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + Insidewidth - 4, Outsideheight + y + Insideheight), Point2 = new Point(Insideoffset + Insidewidth - 5, Outsideheight + y + Insideheight) }; + pf.Segments.Add(seg8); + + LineSegment seg9 = new LineSegment() { Point = new Point(Insideoffset + 5, Outsideheight + y + Insideheight) }; + pf.Segments.Add(seg9); + + QuadraticBezierSegment seg10 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + 4, Outsideheight + y + Insideheight), Point2 = new Point(Insideoffset + 2, Outsideheight + y + 2) }; + pf.Segments.Add(seg10); + + QuadraticBezierSegment seg11 = new QuadraticBezierSegment() { Point1 = new Point(Insideoffset + 1, Outsideheight + y), Point2 = new Point(Insideoffset, Outsideheight + y) }; + pf.Segments.Add(seg11); + + //第五横线 + LineSegment seg12 = new LineSegment() { Point = new Point(2, Outsideheight + y) }; + pf.Segments.Add(seg12); + + ArcSegment seg13 = new ArcSegment() { Size = new Size(2, 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(0, Outsideheight + y - 2) }; + pf.Segments.Add(seg13); + + PathGeometry g1 = new PathGeometry(); + g1.Figures.Add(pf); + #endregion + + return g1; + } + #endregion + } +} diff --git a/Extensions/AIStudio.Wpf.Block/Controls/VariableBlockBorder.cs b/Extensions/AIStudio.Wpf.Block/Controls/VariableBlockBorder.cs new file mode 100644 index 0000000..c4b6d2f --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/Controls/VariableBlockBorder.cs @@ -0,0 +1,114 @@ +using System; +using System.Windows; +using System.Windows.Input; +using System.Windows.Media; + +namespace AIStudio.Wpf.Block.Controls +{ + public class VariableBlockBorder : BlockDecorator + { + public VariableBlockBorder() + { + + } + + #region 方法重写 + public double Minwidth { get; set; } = 64; + public double Minheight { get; set; } = 28; + + /// + /// 该方法用于测量整个控件的大小 + /// + /// + /// 控件的大小 + protected override Size MeasureOverride(Size constraint) + { + Thickness padding = this.Padding; + + Size result = new Size(); + if (Child != null) + { + //测量子控件的大小 + Child.Measure(constraint); + + result.Width = Math.Max(Minwidth, Child.DesiredSize.Width + padding.Left + padding.Right); + result.Height = Math.Max(Minheight, Child.DesiredSize.Height + padding.Top + padding.Bottom); + } + else + { + result.Width = Minwidth; + result.Height = Minheight; + } + return result; + } + + /// + /// 设置子控件的大小与位置 + /// + /// + /// + protected override Size ArrangeOverride(Size arrangeSize) + { + Thickness padding = this.Padding; + if (Child != null) + { + Child.Arrange(new Rect(new Point(padding.Left, padding.Top), + new Size(Math.Max(Minwidth - padding.Left - padding.Right, Child.DesiredSize.Width), Math.Max(Minheight - padding.Top - padding.Bottom, Child.DesiredSize.Height)))); + } + return arrangeSize; + } + + /// + /// 绘制控件 + /// + /// + protected override void OnRender(DrawingContext drawingContext) + { + Thickness padding = this.Padding; + + Pen pen = new Pen(); + pen.Brush = this.BorderBrush; + pen.Thickness = this.BorderThickness.Left;// NextForBlockBorder.RoundLayoutValue(BorderThickness.Left, DoubleUtil.DpiScaleX); + + Geometry cg = CreateGeometry(Math.Max(Minwidth, Child?.DesiredSize.Width ?? 0 + padding.Left + padding.Right), Math.Max(Minheight, Child?.DesiredSize.Height ?? 0 + padding.Top + padding.Bottom)); + Brush brush = CreateFillBrush(); + + GuidelineSet guideLines = new GuidelineSet(); + drawingContext.PushGuidelineSet(guideLines); + drawingContext.DrawGeometry(brush, pen, cg); + } + #endregion + + #region 私有方法 + //按Element的大小计算 + private Geometry CreateGeometry(double x, double y) + { + #region + PathFigure pf = new PathFigure(); + pf.IsClosed = true; + pf.StartPoint = new Point(y / 2, 0); + + + LineSegment seg1 = new LineSegment() { Point = new Point(x - y / 2, 0) }; + pf.Segments.Add(seg1); + + ArcSegment seg2= new ArcSegment() { Size = new Size(y / 2, y / 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(x - y / 2, y) }; + pf.Segments.Add(seg2); + + LineSegment seg3 = new LineSegment() { Point = new Point(y / 2, y) }; + pf.Segments.Add(seg3); + + ArcSegment seg4 = new ArcSegment() { Size = new Size(y / 2, y / 2), SweepDirection = SweepDirection.Clockwise, Point = new Point(y / 2, 0) }; + pf.Segments.Add(seg4); + + PathGeometry g1 = new PathGeometry(); + g1.Figures.Add(pf); + #endregion + + return g1; + } + #endregion + + + } +} diff --git a/Extensions/AIStudio.Wpf.Block/Models/BlockType.cs b/Extensions/AIStudio.Wpf.Block/Models/BlockType.cs new file mode 100644 index 0000000..617cf47 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/Models/BlockType.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AIStudio.Wpf.Block.Models +{ + public enum BlockType + { + //运动 + [Description("移动")] + Move, + [Description("右转")] + TurnRight, + [Description("左转")] + TurnLeft, + [Description("移到")] + MoveTo, + [Description("移到坐标")] + MoveToPoint, + [Description("在几s内移到")] + TimeMoveTo, + [Description("在几s内移到坐标")] + TimeMoveToPoint, + [Description("面向方向")] + FaceTo, + [Description("面向鼠标")] + FaceToMouse, + [Description("将X坐标增加")] + PointXAdd, + [Description("将X坐标设为")] + PointXSet, + [Description("将Y坐标增加")] + PointYAdd, + [Description("将Y坐标设为")] + PointYSet, + [Description("碰到边缘就反弹")] + BorderBounce, + [Description("旋转方式")] + RotationMethod, + [Description("X坐标")] + PointX, + [Description("Y坐标")] + PointY, + [Description("方向")] + Direction, + //外观 + //声音 + //事件 + [Description("当开始被点击")] + Start, + [Description("当键盘按下")] + KeyboardPress, + [Description("当角色被点击")] + WhenRoleClicked, + [Description("当背景切换")] + WhenBackgroundSwitch, + [Description("当大于")] + WhenGreaterThan, + [Description("当接收到")] + WhenReceivedMessage, + [Description("广播消息")] + BroadcastMessage, + [Description("广播消息并等待")] + BroadcastMessageAndWaiting, + [Description("等待1s")] + WaitTime, + [Description("循环执行")] + For, + [Description("一直执行")] + Always, + [Description("如果")] + If, + [Description("如果否则")] + IfElse, + [Description("等待条件")] + Wait, + [Description("重复执行直到")] + While, + [Description("停止")] + Stop, + [Description("克隆")] + Clone, + [Description("删除此克隆体")] + DeleteThisClone, + //侦测 + //运算 + [Description("加")] + Add, + [Description("减")] + Subtract, + [Description("乘")] + Multiply, + [Description("除")] + Division, + [Description("除")] + Random, + [Description("大于")] + GreaterThan, + [Description("小于")] + LessThan, + [Description("等于")] + EqualThan, + [Description("与")] + And, + [Description("或")] + Or, + [Description("不成立")] + Not, + [Description("字符串连接")] + StringAdd, + [Description("第几个字符")] + StringIndex, + [Description("字符数")] + StringLength, + [Description("包含")] + StringContain, + [Description("余数")] + Mod, + [Description("四舍五入")] + Round, + [Description("绝对值")] + Abs, + //变量 + [Description("变量")] + Variable, + [Description("设为")] + SetValue, + [Description("增加")] + Increase, + [Description("显示变量")] + VariableVisable, + [Description("隐藏变量")] + VariableHidden, + } +} diff --git a/Extensions/AIStudio.Wpf.Block/Models/ConstParameter.cs b/Extensions/AIStudio.Wpf.Block/Models/ConstParameter.cs new file mode 100644 index 0000000..440d0dd --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/Models/ConstParameter.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AIStudio.Wpf.Block.Models +{ + public class ConstParameter : IParameter + { + public double? Value + { + get;set; + } + } +} diff --git a/Extensions/AIStudio.Wpf.Block/Models/IParameter.cs b/Extensions/AIStudio.Wpf.Block/Models/IParameter.cs new file mode 100644 index 0000000..bc51972 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/Models/IParameter.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AIStudio.Wpf.Block.Models +{ + public interface IParameter + { + //double Value + //{ + // get; + //} + } +} diff --git a/Extensions/AIStudio.Wpf.Block/Models/VarParameter.cs b/Extensions/AIStudio.Wpf.Block/Models/VarParameter.cs new file mode 100644 index 0000000..071af07 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/Models/VarParameter.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AIStudio.Wpf.Block.Models +{ + public class VarParameter : IParameter + { + + } +} diff --git a/Extensions/AIStudio.Wpf.Block/Themes/BlockItemViewModel.xaml b/Extensions/AIStudio.Wpf.Block/Themes/BlockItemViewModel.xaml new file mode 100644 index 0000000..33a35da --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/Themes/BlockItemViewModel.xaml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Extensions/AIStudio.Wpf.Block/Themes/Brushes.xaml b/Extensions/AIStudio.Wpf.Block/Themes/Brushes.xaml new file mode 100644 index 0000000..f9df8c8 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/Themes/Brushes.xaml @@ -0,0 +1,30 @@ + + + #ffbf00 + #cc9900 + White + #ffab19 + #cf8b17 + White + #59c059 + #389438 + White + + #4cbf56 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Extensions/AIStudio.Wpf.Block/Themes/Geometries.xaml b/Extensions/AIStudio.Wpf.Block/Themes/Geometries.xaml new file mode 100644 index 0000000..5ca17af --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/Themes/Geometries.xaml @@ -0,0 +1,6 @@ + + + M152.474 62.225c-26.856 0-56.286 21.748-56.286 48.663v802.451c0 26.798 28.773 48.653 55.579 48.653 26.789 0 56.286-21.857 56.286-48.663v-802.434c0-26.914-28.78-48.663-55.579-48.663zM730.146 129.011c-157.836 0-157.836-64.694-315.663-64.694-91.108 0-161.46 42.504-161.46 42.504l-0.658 484.313s71.010-42.446 162.119-42.446c157.827 0 157.827 64.694 315.663 64.694 98.74 0 197.923-51.845 197.923-51.845v-484.264s-99.183 51.737-197.923 51.737z + \ No newline at end of file diff --git a/Extensions/AIStudio.Wpf.Block/ViewModels/ArithmeticModules/AddBlockItemViewModel.cs b/Extensions/AIStudio.Wpf.Block/ViewModels/ArithmeticModules/AddBlockItemViewModel.cs new file mode 100644 index 0000000..30672f9 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/ViewModels/ArithmeticModules/AddBlockItemViewModel.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using AIStudio.Wpf.Block.Models; +using AIStudio.Wpf.DiagramDesigner; +using AIStudio.Wpf.DiagramDesigner.Models; + +namespace AIStudio.Wpf.Block.ViewModels +{ + public class AddBlockItemViewModel : BlockDesignerItemViewModel + { + public AddBlockItemViewModel() + { + } + + public AddBlockItemViewModel(IDiagramViewModel root) : base(root) + { + } + + public AddBlockItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer) + { + } + + public AddBlockItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType) + { + } + + protected override void InitNew() + { + ItemWidth = double.NaN; + ItemHeight = double.NaN; + Add1 = new ConstParameter(); + Add2 = new ConstParameter(); + } + + private IParameter _add1; + public IParameter Add1 + { + get + { + return _add1; + } + set + { + SetProperty(ref _add1, value); + } + } + + private IParameter _add2; + public IParameter Add2 + { + get + { + return _add2; + } + set + { + SetProperty(ref _add2, value); + } + } + } +} diff --git a/Extensions/AIStudio.Wpf.Block/ViewModels/ControlModules/ControlBlockItemViewModel.cs b/Extensions/AIStudio.Wpf.Block/ViewModels/ControlModules/ControlBlockItemViewModel.cs new file mode 100644 index 0000000..30c86bd --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/ViewModels/ControlModules/ControlBlockItemViewModel.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using AIStudio.Wpf.DiagramDesigner; +using AIStudio.Wpf.DiagramDesigner.Models; + +namespace AIStudio.Wpf.Block.ViewModels +{ + public class ControlBlockItemViewModel : BlockDesignerItemViewModel + { + public ControlBlockItemViewModel() + { + } + + public ControlBlockItemViewModel(IDiagramViewModel root) : base(root) + { + } + + public ControlBlockItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer) + { + } + + public ControlBlockItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType) + { + } + + protected override void InitNew() + { + ItemWidth = double.NaN; + ItemHeight = double.NaN; + AddConnector(new BlockConnectorInfo(this.Root, this, ConnectorOrientation.Bottom)); + } + } +} diff --git a/Extensions/AIStudio.Wpf.Block/ViewModels/ControlModules/KeyboardPressBlockItemViewModel.cs b/Extensions/AIStudio.Wpf.Block/ViewModels/ControlModules/KeyboardPressBlockItemViewModel.cs new file mode 100644 index 0000000..63114c4 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/ViewModels/ControlModules/KeyboardPressBlockItemViewModel.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using AIStudio.Wpf.DiagramDesigner; +using AIStudio.Wpf.DiagramDesigner.Models; + +namespace AIStudio.Wpf.Block.ViewModels +{ + public class KeyboardPressBlockItemViewModel : ControlBlockItemViewModel + { + public KeyboardPressBlockItemViewModel() + { + } + + public KeyboardPressBlockItemViewModel(IDiagramViewModel root) : base(root) + { + } + + public KeyboardPressBlockItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer) + { + } + + public KeyboardPressBlockItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType) + { + } + + public List KeyItemsSource + { + get;set; + } + + private string _key; + public string Key + { + get + { + return _key; + } + set + { + SetProperty(ref _key, value); + } + } + } +} diff --git a/Extensions/AIStudio.Wpf.Block/ViewModels/ControlModules/StartBlockItemViewModel.cs b/Extensions/AIStudio.Wpf.Block/ViewModels/ControlModules/StartBlockItemViewModel.cs new file mode 100644 index 0000000..d5e3e1c --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/ViewModels/ControlModules/StartBlockItemViewModel.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using AIStudio.Wpf.DiagramDesigner; +using AIStudio.Wpf.DiagramDesigner.Models; + +namespace AIStudio.Wpf.Block.ViewModels +{ + public class StartBlockItemViewModel : ControlBlockItemViewModel + { + public StartBlockItemViewModel() + { + } + + public StartBlockItemViewModel(IDiagramViewModel root) : base(root) + { + } + + public StartBlockItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer) + { + } + + public StartBlockItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType) + { + } + + } +} diff --git a/Extensions/AIStudio.Wpf.Block/ViewModels/EventModules/WaitTimeBlockItemViewModel.cs b/Extensions/AIStudio.Wpf.Block/ViewModels/EventModules/WaitTimeBlockItemViewModel.cs new file mode 100644 index 0000000..e36318c --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/ViewModels/EventModules/WaitTimeBlockItemViewModel.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using AIStudio.Wpf.Block.Models; +using AIStudio.Wpf.DiagramDesigner; +using AIStudio.Wpf.DiagramDesigner.Models; + +namespace AIStudio.Wpf.Block.ViewModels +{ + public class WaitTimeBlockItemViewModel : BlockDesignerItemViewModel + { + public WaitTimeBlockItemViewModel() + { + } + + public WaitTimeBlockItemViewModel(IDiagramViewModel root) : base(root) + { + } + + public WaitTimeBlockItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer) + { + } + + public WaitTimeBlockItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType) + { + } + + protected override void InitNew() + { + ItemWidth = double.NaN; + ItemHeight = double.NaN; + Second = new ConstParameter(); + } + + private IParameter _second; + public IParameter Second + { + get + { + return _second; + } + set + { + SetProperty(ref _second, value); + } + } + } +} diff --git a/Extensions/AIStudio.Wpf.Block/ViewModels/VariableModules/VariableBlockItemViewModel.cs b/Extensions/AIStudio.Wpf.Block/ViewModels/VariableModules/VariableBlockItemViewModel.cs new file mode 100644 index 0000000..ffe346c --- /dev/null +++ b/Extensions/AIStudio.Wpf.Block/ViewModels/VariableModules/VariableBlockItemViewModel.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using AIStudio.Wpf.Block.Models; +using AIStudio.Wpf.DiagramDesigner; +using AIStudio.Wpf.DiagramDesigner.Models; + +namespace AIStudio.Wpf.Block.ViewModels.VariableModules +{ + public class VariableBlockItemViewModel : BlockDesignerItemViewModel + { + public VariableBlockItemViewModel() + { + } + + public VariableBlockItemViewModel(IDiagramViewModel root) : base(root) + { + } + + public VariableBlockItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer) + { + } + + public VariableBlockItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType) + { + } + + protected override void InitNew() + { + ItemWidth = double.NaN; + ItemHeight = double.NaN; + Value = new VarParameter(); + } + + private IParameter _value; + public IParameter Value + { + get + { + return _value; + } + set + { + SetProperty(ref _value, value); + } + } + } +} diff --git a/Extensions/AIStudio.Wpf.SFC/AIStudio.Wpf.SFC_gn4tlqoy_wpftmp.csproj b/Extensions/AIStudio.Wpf.SFC/AIStudio.Wpf.SFC_gn4tlqoy_wpftmp.csproj new file mode 100644 index 0000000..fa98620 --- /dev/null +++ b/Extensions/AIStudio.Wpf.SFC/AIStudio.Wpf.SFC_gn4tlqoy_wpftmp.csproj @@ -0,0 +1,236 @@ + + + AIStudio.Wpf.SFC + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\Extensions\AIStudio.Wpf.SFC\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.SFC + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Extensions/AIStudio.Wpf.SFC/AIStudio.Wpf.SFC_hjulhjj0_wpftmp.csproj b/Extensions/AIStudio.Wpf.SFC/AIStudio.Wpf.SFC_hjulhjj0_wpftmp.csproj new file mode 100644 index 0000000..fa98620 --- /dev/null +++ b/Extensions/AIStudio.Wpf.SFC/AIStudio.Wpf.SFC_hjulhjj0_wpftmp.csproj @@ -0,0 +1,236 @@ + + + AIStudio.Wpf.SFC + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\Extensions\AIStudio.Wpf.SFC\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.SFC + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Extensions/AIStudio.Wpf.Script/AIStudio.Wpf.Script_5k10wu0u_wpftmp.csproj b/Extensions/AIStudio.Wpf.Script/AIStudio.Wpf.Script_5k10wu0u_wpftmp.csproj new file mode 100644 index 0000000..59edb5e --- /dev/null +++ b/Extensions/AIStudio.Wpf.Script/AIStudio.Wpf.Script_5k10wu0u_wpftmp.csproj @@ -0,0 +1,203 @@ + + + AIStudio.Wpf.Script + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\Extensions\AIStudio.Wpf.Script\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.Script + + + + true + AIStudio.Wpf.Controls + akwkevin + https://gitee.com/akwkevin + A.png + + + 1.0.6 + 一个Wpf的脚本生成模块 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Extensions/AIStudio.Wpf.Script/AIStudio.Wpf.Script_a4fgwrgk_wpftmp.csproj b/Extensions/AIStudio.Wpf.Script/AIStudio.Wpf.Script_a4fgwrgk_wpftmp.csproj new file mode 100644 index 0000000..abd163d --- /dev/null +++ b/Extensions/AIStudio.Wpf.Script/AIStudio.Wpf.Script_a4fgwrgk_wpftmp.csproj @@ -0,0 +1,276 @@ + + + AIStudio.Wpf.Script + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\Extensions\AIStudio.Wpf.Script\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.Script + + + + true + AIStudio.Wpf.Controls + akwkevin + https://gitee.com/akwkevin + A.png + + + 1.0.6 + 一个Wpf的脚本生成模块 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Extensions/AIStudio.Wpf.Script/AIStudio.Wpf.Script_l225ygvw_wpftmp.csproj b/Extensions/AIStudio.Wpf.Script/AIStudio.Wpf.Script_l225ygvw_wpftmp.csproj new file mode 100644 index 0000000..abd163d --- /dev/null +++ b/Extensions/AIStudio.Wpf.Script/AIStudio.Wpf.Script_l225ygvw_wpftmp.csproj @@ -0,0 +1,276 @@ + + + AIStudio.Wpf.Script + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\Extensions\AIStudio.Wpf.Script\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.Script + + + + true + AIStudio.Wpf.Controls + akwkevin + https://gitee.com/akwkevin + A.png + + + 1.0.6 + 一个Wpf的脚本生成模块 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Extensions/AIStudio.Wpf.Script/AIStudio.Wpf.Script_vs4rptnz_wpftmp.csproj b/Extensions/AIStudio.Wpf.Script/AIStudio.Wpf.Script_vs4rptnz_wpftmp.csproj new file mode 100644 index 0000000..186a2f4 --- /dev/null +++ b/Extensions/AIStudio.Wpf.Script/AIStudio.Wpf.Script_vs4rptnz_wpftmp.csproj @@ -0,0 +1,268 @@ + + + AIStudio.Wpf.Script + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\Extensions\AIStudio.Wpf.Script\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.Script + + + + true + AIStudio.Wpf.Controls + akwkevin + https://gitee.com/akwkevin + A.png + + + 1.0.6 + 一个Wpf的脚本生成模块 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file