diff --git a/AIStudio.Wpf.DiagramApp/AIStudio.Wpf.DiagramApp_vv4u11rm_wpftmp.csproj b/AIStudio.Wpf.DiagramApp/AIStudio.Wpf.DiagramApp_vv4u11rm_wpftmp.csproj new file mode 100644 index 0000000..29132b9 --- /dev/null +++ b/AIStudio.Wpf.DiagramApp/AIStudio.Wpf.DiagramApp_vv4u11rm_wpftmp.csproj @@ -0,0 +1,1053 @@ + + + AIStudio.Wpf.DiagramApp + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\AIStudio.Wpf.DiagramApp\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.DiagramApp + + + + WinExe + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + 8.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AIStudio.Wpf.DiagramApp/ViewModels/MindViewModel.cs b/AIStudio.Wpf.DiagramApp/ViewModels/MindViewModel.cs index 545fc3e..0dca1e1 100644 --- a/AIStudio.Wpf.DiagramApp/ViewModels/MindViewModel.cs +++ b/AIStudio.Wpf.DiagramApp/ViewModels/MindViewModel.cs @@ -37,7 +37,7 @@ namespace AIStudio.Wpf.Flowchart } - private MindType _mindType = Mind.MindType.Directory; + private MindType _mindType = Mind.MindType.Organizational; public MindType MindType { get @@ -55,8 +55,10 @@ namespace AIStudio.Wpf.Flowchart base.Init(); MindNode level1node = new MindNode(DiagramViewModel, Mind.NodeLevel.Level1, MindType) { Text = "思维导图" }; + level1node.Left = 220; + level1node.Top = 15; DiagramViewModel.DirectAddItemCommand.Execute(level1node); - DiagramViewModel.CenterMoveCommand.Execute(level1node); + //DiagramViewModel.CenterMoveCommand.Execute(level1node); MindNode level2node1_1 = new MindNode(DiagramViewModel, Mind.NodeLevel.Level2, MindType) { Text = "分支主题1" }; level1node.AddChild(level2node1_1); diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs index f63fd94..85ff160 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs @@ -71,6 +71,15 @@ namespace AIStudio.Wpf.DiagramDesigner } #region 属性 + + public FullyCreatedConnectorInfo FirstConnector + { + get + { + return connectors?.FirstOrDefault(); + } + } + public FullyCreatedConnectorInfo TopConnector { get diff --git a/AIStudio.Wpf.Mind/Helpers/DirectoryLayout.cs b/AIStudio.Wpf.Mind/Helpers/DirectoryLayout.cs index 3d99d9e..e27f90d 100644 --- a/AIStudio.Wpf.Mind/Helpers/DirectoryLayout.cs +++ b/AIStudio.Wpf.Mind/Helpers/DirectoryLayout.cs @@ -31,7 +31,6 @@ namespace AIStudio.Wpf.Mind.Helpers mindNode.ColorViewModel.LineColor.Color = Color.FromRgb(0x73, 0xa1, 0xbf); mindNode.FontViewModel.FontColor = Colors.White; mindNode.FontViewModel.FontSize = 15; - mindNode.Spacing = new SizeBase(50, 15); mindNode.ShapeViewModel.SinkMarker.PathStyle = ArrowPathStyle.None; mindNode.ShapeViewModel.SinkMarker.SizeStyle = ArrowSizeStyle.VerySmall; @@ -80,14 +79,13 @@ namespace AIStudio.Wpf.Mind.Helpers { if (mindNode == null) return; - mindNode.LayoutUpdating = true; + mindNode.GetLevel1Node().LayoutUpdating = true; var size = MeasureOverride(mindNode); ArrangeOverride(mindNode); mindNode.Root.BringToFrontCommand.Execute(new SelectableDesignerItemViewModelBase[] { mindNode }); - mindNode.Root?.ReconnectLinksToClosestPorts(); - mindNode.LayoutUpdating = false; + mindNode.GetLevel1Node().LayoutUpdating = false; } @@ -104,13 +102,11 @@ namespace AIStudio.Wpf.Mind.Helpers else { var childrensizes = mindNode.Children.Select(p => MeasureOverride(p, mindNode.IsExpanded && isExpanded)).ToArray(); - sizewithSpacing = new SizeBase(sizewithSpacing.Width * 0.5 + childrensizes.Max(p => p.Width), sizewithSpacing.Height + childrensizes.Sum(p => p.Height)); + sizewithSpacing = new SizeBase(Math.Max(sizewithSpacing.Width, sizewithSpacing.Width * 0.5 + childrensizes.Max(p => p.Width)), sizewithSpacing.Height + childrensizes.Sum(p => p.Height)); } } mindNode.DesiredSize = isExpanded ? sizewithSpacing : new SizeBase(0, 0); mindNode.Visible = isExpanded; - var connectors = mindNode.Root?.Items.OfType().Where(p => p.SinkConnectorInfoFully?.DataItem == mindNode).ToList(); - connectors?.ForEach(p => p.Visible = mindNode.Visible); return mindNode.DesiredSize; } @@ -131,6 +127,11 @@ namespace AIStudio.Wpf.Mind.Helpers left += child.DesiredSize.Width; ArrangeOverride(child); + + var connect = mindNode.Root?.Items.OfType().FirstOrDefault(p => p.SourceConnectorInfo?.DataItem == mindNode && p.SinkConnectorInfoFully?.DataItem == child); + connect?.SetSourcePort(mindNode.FirstConnector); + connect?.SetSinkPort(child.TopConnector); + connect.Visible = child.Visible; } } } @@ -148,6 +149,11 @@ namespace AIStudio.Wpf.Mind.Helpers top += child.DesiredSize.Height; ArrangeOverride(child); + + var connect = mindNode.Root?.Items.OfType().FirstOrDefault(p => p.SourceConnectorInfo?.DataItem == mindNode && p.SinkConnectorInfoFully?.DataItem == child); + connect?.SetSourcePort(mindNode.BottomConnector); + connect?.SetSinkPort(child.LeftConnector); + connect.Visible = child.Visible; } } } diff --git a/AIStudio.Wpf.Mind/Helpers/LogicalLayout.cs b/AIStudio.Wpf.Mind/Helpers/LogicalLayout.cs index a155955..e232eff 100644 --- a/AIStudio.Wpf.Mind/Helpers/LogicalLayout.cs +++ b/AIStudio.Wpf.Mind/Helpers/LogicalLayout.cs @@ -80,14 +80,13 @@ namespace AIStudio.Wpf.Mind.Helpers { if (mindNode == null) return; - mindNode.LayoutUpdating = true; + mindNode.GetLevel1Node().LayoutUpdating = true; var size = MeasureOverride(mindNode); ArrangeOverride(mindNode); mindNode.Root.BringToFrontCommand.Execute(new SelectableDesignerItemViewModelBase[] { mindNode }); - mindNode.Root?.ReconnectLinksToClosestPorts(); - mindNode.LayoutUpdating = false; + mindNode.GetLevel1Node().LayoutUpdating = false; } public SizeBase MeasureOverride(MindNode mindNode, bool isExpanded = true) @@ -100,8 +99,6 @@ namespace AIStudio.Wpf.Mind.Helpers } mindNode.DesiredSize = isExpanded ? sizewithSpacing : new SizeBase(0, 0); mindNode.Visible = isExpanded; - var connectors = mindNode.Root?.Items.OfType().Where(p => p.SinkConnectorInfoFully?.DataItem == mindNode).ToList(); - connectors?.ForEach(p => p.Visible = mindNode.Visible); return mindNode.DesiredSize; } @@ -120,6 +117,11 @@ namespace AIStudio.Wpf.Mind.Helpers top += child.DesiredSize.Height; ArrangeOverride(child); + + var connect = mindNode.Root?.Items.OfType().FirstOrDefault(p => p.SourceConnectorInfo?.DataItem == mindNode && p.SinkConnectorInfoFully?.DataItem == child); + connect?.SetSourcePort(mindNode.RightConnector ?? mindNode.FirstConnector); + connect?.SetSinkPort(child.LeftConnector); + connect.Visible = child.Visible; } } diff --git a/AIStudio.Wpf.Mind/Helpers/MindLayout.cs b/AIStudio.Wpf.Mind/Helpers/MindLayout.cs index da8a984..c9dbe00 100644 --- a/AIStudio.Wpf.Mind/Helpers/MindLayout.cs +++ b/AIStudio.Wpf.Mind/Helpers/MindLayout.cs @@ -81,29 +81,27 @@ namespace AIStudio.Wpf.Mind.Helpers { if (mindNode == null) return; - mindNode.LayoutUpdating = true; + mindNode.GetLevel1Node().LayoutUpdating = true; var size = MeasureOverride(mindNode); ArrangeOverride(mindNode); mindNode.Root.BringToFrontCommand.Execute(new SelectableDesignerItemViewModelBase[] { mindNode }); - mindNode.Root?.ReconnectLinksToClosestPorts(); - mindNode.LayoutUpdating = false; + mindNode.GetLevel1Node().LayoutUpdating = false; } public SizeBase MeasureOverride(MindNode mindNode, bool isExpanded = true) { - var sizewithSpacing = mindNode.SizeWithSpacing; + var sizewithSpacing = mindNode.SizeWithSpacing; if (mindNode.Children?.Count > 0) { if (mindNode.NodeLevel == NodeLevel.Level1) { var rights = mindNode.Children.Where((p, index) => index % 2 == 0).ToList(); - rights.ForEach(p => p.IsRightLayout = true); + rights.ForEach(p => p.ConnectorOrientation = ConnectorOrientation.Left); var rightsizes = rights.Select(p => MeasureOverride(p, mindNode.IsExpanded && isExpanded)).ToArray(); - var lefts = mindNode.Children.Where((p, index) => index % 2 == 1).ToList(); - lefts.ForEach(p => p.IsRightLayout = false); + lefts.ForEach(p => p.ConnectorOrientation = ConnectorOrientation.Right); var leftsizes = lefts.Select(p => MeasureOverride(p, mindNode.IsExpanded && isExpanded)).ToArray(); sizewithSpacing = new SizeBase(sizewithSpacing.Width + rightsizes.Max(p => p.Width) + +leftsizes.Max(p => p.Width), Math.Max(sizewithSpacing.Height, Math.Max(rightsizes.Sum(p => p.Height), leftsizes.Sum(p => p.Height)))); } @@ -112,11 +110,9 @@ namespace AIStudio.Wpf.Mind.Helpers var childrensizes = mindNode.Children.Select(p => MeasureOverride(p, mindNode.IsExpanded && isExpanded)).ToArray(); sizewithSpacing = new SizeBase(sizewithSpacing.Width + childrensizes.Max(p => p.Width), Math.Max(sizewithSpacing.Height, childrensizes.Sum(p => p.Height))); } - } + } mindNode.DesiredSize = isExpanded ? sizewithSpacing : new SizeBase(0, 0); mindNode.Visible = isExpanded; - var connectors = mindNode.Root?.Items.OfType().Where(p => p.SinkConnectorInfoFully?.DataItem == mindNode).ToList(); - connectors?.ForEach(p => p.Visible = mindNode.Visible); return mindNode.DesiredSize; } @@ -127,7 +123,7 @@ namespace AIStudio.Wpf.Mind.Helpers { if (mindNode.Children?.Count > 0) { - var rights = mindNode.Children.Where(p => p.IsRightLayout == true).ToList(); + var rights = mindNode.Children.Where(p => p.ConnectorOrientation == ConnectorOrientation.Left).ToList(); double left = mindNode.MiddlePosition.X + mindNode.ItemWidth / 2 + mindNode.Spacing.Width; double lefttop = mindNode.MiddlePosition.Y - Math.Min(mindNode.DesiredSize.Height, rights.Sum(p => p.DesiredSize.Height)) / 2; foreach (var child in rights) @@ -138,9 +134,14 @@ namespace AIStudio.Wpf.Mind.Helpers lefttop += child.DesiredSize.Height; ArrangeOverride(child); + + var connect = mindNode.Root?.Items.OfType().FirstOrDefault(p => p.SourceConnectorInfo?.DataItem == mindNode && p.SinkConnectorInfoFully?.DataItem == child); + connect?.SetSourcePort(mindNode.FirstConnector); + connect?.SetSinkPort(child.LeftConnector); + connect.Visible = child.Visible; } - var lefts = mindNode.Children.Where(p => p.IsRightLayout == false).ToList(); + var lefts = mindNode.Children.Where(p => p.ConnectorOrientation == ConnectorOrientation.Right).ToList(); double right = mindNode.MiddlePosition.X - mindNode.ItemWidth / 2 - mindNode.Spacing.Width; double righttop = mindNode.MiddlePosition.Y - Math.Min(mindNode.DesiredSize.Height, lefts.Sum(p => p.DesiredSize.Height)) / 2; foreach (var child in lefts) @@ -151,12 +152,17 @@ namespace AIStudio.Wpf.Mind.Helpers righttop += child.DesiredSize.Height; ArrangeOverride(child); + + var connect = mindNode.Root?.Items.OfType().FirstOrDefault(p => p.SourceConnectorInfo?.DataItem == mindNode && p.SinkConnectorInfoFully?.DataItem == child); + connect?.SetSourcePort(mindNode.FirstConnector); + connect?.SetSinkPort(child.RightConnector); + connect.Visible = child.Visible; } } } else { - if (mindNode.GetLevel2Node().IsRightLayout) + if (mindNode.GetLevel2Node().ConnectorOrientation == ConnectorOrientation.Left) { double left = mindNode.MiddlePosition.X + mindNode.ItemWidth / 2 + mindNode.Spacing.Width; double top = mindNode.MiddlePosition.Y - Math.Min(mindNode.DesiredSize.Height, mindNode.Children.Sum(p => p.DesiredSize.Height)) / 2; @@ -170,6 +176,11 @@ namespace AIStudio.Wpf.Mind.Helpers top += child.DesiredSize.Height; ArrangeOverride(child); + + var connect = mindNode.Root?.Items.OfType().FirstOrDefault(p => p.SourceConnectorInfo?.DataItem == mindNode && p.SinkConnectorInfoFully?.DataItem == child); + connect?.SetSourcePort(mindNode.RightConnector); + connect?.SetSinkPort(child.LeftConnector); + connect.Visible = child.Visible; } } } @@ -187,6 +198,11 @@ namespace AIStudio.Wpf.Mind.Helpers top += child.DesiredSize.Height; ArrangeOverride(child); + + var connect = mindNode.Root?.Items.OfType().FirstOrDefault(p => p.SourceConnectorInfo?.DataItem == mindNode && p.SinkConnectorInfoFully?.DataItem == child); + connect?.SetSourcePort(mindNode.LeftConnector); + connect?.SetSinkPort(child.RightConnector); + connect.Visible = child.Visible; } } } diff --git a/AIStudio.Wpf.Mind/Helpers/OrganizationalLayout.cs b/AIStudio.Wpf.Mind/Helpers/OrganizationalLayout.cs new file mode 100644 index 0000000..bb4daa6 --- /dev/null +++ b/AIStudio.Wpf.Mind/Helpers/OrganizationalLayout.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Media; +using AIStudio.Wpf.DiagramDesigner; +using AIStudio.Wpf.DiagramDesigner.Algorithms; +using AIStudio.Wpf.DiagramDesigner.Geometrys; +using AIStudio.Wpf.Mind.ViewModels; + +namespace AIStudio.Wpf.Mind.Helpers +{ + public class OrganizationalLayout : IMindLayout + { + public void Appearance(MindNode mindNode) + { + switch (mindNode.NodeLevel) + { + case NodeLevel.Level1: + { + mindNode.ItemWidth = 110; + mindNode.ItemHeight = 40; + mindNode.ClearConnectors(); + + var port = new FullyCreatedConnectorInfo(mindNode.Root, mindNode, ConnectorOrientation.Bottom, true) { XRatio = 0.5, YRatio = 1 }; + mindNode.AddConnector(port); + + mindNode.IsInnerConnector = true; + + mindNode.ColorViewModel.FillColor.Color = Color.FromRgb(0x73, 0xa1, 0xbf); + mindNode.ColorViewModel.LineColor.Color = Color.FromRgb(0x73, 0xa1, 0xbf); + mindNode.FontViewModel.FontColor = Colors.White; + mindNode.FontViewModel.FontSize = 15; + mindNode.ShapeViewModel.SinkMarker.PathStyle = ArrowPathStyle.None; + mindNode.ShapeViewModel.SinkMarker.SizeStyle = ArrowSizeStyle.VerySmall; + break; + } + case NodeLevel.Level2: + { + mindNode.ItemWidth = 80; + mindNode.ItemHeight = 25; + mindNode.ClearConnectors(); + var port1 = new FullyCreatedConnectorInfo(mindNode.Root, mindNode, ConnectorOrientation.Top, true) { XRatio = 0.5, YRatio = 0 }; + mindNode.AddConnector(port1); + var port2 = new FullyCreatedConnectorInfo(mindNode.Root, mindNode, ConnectorOrientation.Bottom, true) { XRatio = 0.5, YRatio = 1 }; + mindNode.AddConnector(port2); + + mindNode.IsInnerConnector = true; + + mindNode.ColorViewModel.LineColor.Color = Color.FromRgb(0x73, 0xa1, 0xbf); + mindNode.ShapeViewModel.SinkMarker.PathStyle = ArrowPathStyle.None; + mindNode.ShapeViewModel.SinkMarker.SizeStyle = ArrowSizeStyle.VerySmall; + mindNode.ConnectorOrientation = ConnectorOrientation.Top; + break; + } + case NodeLevel.Level3: + { + mindNode.ItemWidth = 80; + mindNode.ItemHeight = 25; + mindNode.ClearConnectors(); + + var port1 = new FullyCreatedConnectorInfo(mindNode.Root, mindNode, ConnectorOrientation.Top, true) { XRatio = 0.5, YRatio = 0 }; + mindNode.AddConnector(port1); + var port2 = new FullyCreatedConnectorInfo(mindNode.Root, mindNode, ConnectorOrientation.Bottom, true) { XRatio = 0.5, YRatio = 1 }; + mindNode.AddConnector(port2); + + mindNode.IsInnerConnector = true; + mindNode.ColorViewModel.LineColor.Color = Color.FromRgb(0x73, 0xa1, 0xbf); + mindNode.ShapeViewModel.SinkMarker.PathStyle = ArrowPathStyle.None; + mindNode.ShapeViewModel.SinkMarker.SizeStyle = ArrowSizeStyle.VerySmall; + mindNode.CornerRadius = new System.Windows.CornerRadius(0); + mindNode.BorderThickness = new System.Windows.Thickness(0, 0, 0, 0); + mindNode.ConnectorOrientation = ConnectorOrientation.Top; + break; + } + } + } + + public void LayoutUpdated(MindNode mindNode) + { + if (mindNode == null) return; + + mindNode.GetLevel1Node().LayoutUpdating = true; + var size = MeasureOverride(mindNode); + ArrangeOverride(mindNode); + + mindNode.Root.BringToFrontCommand.Execute(new SelectableDesignerItemViewModelBase[] { mindNode }); + + mindNode.GetLevel1Node().LayoutUpdating = false; + } + + + public SizeBase MeasureOverride(MindNode mindNode, bool isExpanded = true) + { + var sizewithSpacing = mindNode.SizeWithSpacing; + if (mindNode.Children?.Count > 0) + { + var childrensizes = mindNode.Children.Select(p => MeasureOverride(p, mindNode.IsExpanded && isExpanded)).ToArray(); + sizewithSpacing = new SizeBase(Math.Max(sizewithSpacing.Width, childrensizes.Sum(p => p.Width)), sizewithSpacing.Height + childrensizes.Max(p => p.Height)); + } + mindNode.DesiredSize = isExpanded ? sizewithSpacing : new SizeBase(0, 0); + mindNode.Visible = isExpanded; + + return mindNode.DesiredSize; + } + + public void ArrangeOverride(MindNode mindNode) + { + double left = mindNode.MiddlePosition.X - Math.Max(mindNode.DesiredSize.Width, mindNode.Children.Sum(p => p.DesiredSize.Width)) / 2; + double top = mindNode.MiddlePosition.Y + mindNode.ItemHeight / 2 + mindNode.Spacing.Height; + if (mindNode.Children?.Count > 0) + { + foreach (var child in mindNode.Children) + { + child.Left = left + child.DesiredSize.Width / 2 - child.ItemWidth + child.Spacing.Width + child.Offset.X; + child.Top = top + child.Spacing.Height + child.Offset.Y; + child.DesiredPosition = child.Position; + left += child.DesiredSize.Width; + + ArrangeOverride(child); + + var connect = mindNode.Root?.Items.OfType().FirstOrDefault(p => p.SourceConnectorInfo?.DataItem == mindNode && p.SinkConnectorInfoFully?.DataItem == child); + connect?.SetSourcePort(mindNode.BottomConnector); + connect?.SetSinkPort(child.TopConnector); + connect.Visible = child.Visible; + } + } + + } + } +} diff --git a/AIStudio.Wpf.Mind/Themes/MindNode.xaml b/AIStudio.Wpf.Mind/Themes/MindNode.xaml index 46f2380..a347efb 100644 --- a/AIStudio.Wpf.Mind/Themes/MindNode.xaml +++ b/AIStudio.Wpf.Mind/Themes/MindNode.xaml @@ -91,10 +91,15 @@ - + + + + + + @@ -125,10 +130,15 @@ - + + + + + + diff --git a/AIStudio.Wpf.Mind/ViewModels/MindNode.cs b/AIStudio.Wpf.Mind/ViewModels/MindNode.cs index 728ab55..4be2377 100644 --- a/AIStudio.Wpf.Mind/ViewModels/MindNode.cs +++ b/AIStudio.Wpf.Mind/ViewModels/MindNode.cs @@ -185,16 +185,16 @@ namespace AIStudio.Wpf.Mind.ViewModels get; set; } - private bool _isRightLayout = true; - public bool IsRightLayout + private ConnectorOrientation _connectorOrientation = ConnectorOrientation.Left; + public ConnectorOrientation ConnectorOrientation { get { - return _isRightLayout; + return _connectorOrientation; } set { - SetProperty(ref _isRightLayout, value); + SetProperty(ref _connectorOrientation, value); } } @@ -356,9 +356,9 @@ namespace AIStudio.Wpf.Mind.ViewModels else { if (NodeLevel == NodeLevel.Level1) - node = new MindNode(Root, NodeLevel.Level2) { Text = "分支主题" }; + node = new MindNode(Root, NodeLevel.Level2, this.MindType) { Text = "分支主题" }; else - node = new MindNode(Root, NodeLevel.Level3) { Text = "分支主题" }; + node = new MindNode(Root, NodeLevel.Level3, this.MindType) { Text = "分支主题" }; } AddChild(node); @@ -379,9 +379,9 @@ namespace AIStudio.Wpf.Mind.ViewModels return; } else if (NodeLevel == NodeLevel.Level2) - node = new MindNode(Root, NodeLevel.Level2) { Text = "分支主题" }; + node = new MindNode(Root, NodeLevel.Level2, this.MindType) { Text = "分支主题" }; else - node = new MindNode(Root, NodeLevel.Level3) { Text = "分支主题" }; + node = new MindNode(Root, NodeLevel.Level3, this.MindType) { Text = "分支主题" }; } parent.RemoveChild(this); @@ -408,9 +408,9 @@ namespace AIStudio.Wpf.Mind.ViewModels return; } else if (NodeLevel == NodeLevel.Level2) - node = new MindNode(Root, NodeLevel.Level2) { Text = "分支主题" }; + node = new MindNode(Root, NodeLevel.Level2, this.MindType) { Text = "分支主题" }; else - node = new MindNode(Root, NodeLevel.Level3) { Text = "分支主题" }; + node = new MindNode(Root, NodeLevel.Level3, this.MindType) { Text = "分支主题" }; } int index = parent.Children.IndexOf(this); parent.AddChild(node, index + 1); @@ -482,6 +482,7 @@ namespace AIStudio.Wpf.Mind.ViewModels switch (MindType) { case MindType.Directory: + case MindType.Organizational: drawMode = DrawMode.ConnectingLineStraight; routerMode = AIStudio.Wpf.DiagramDesigner.RouterMode.RouterOrthogonal; break; @@ -527,6 +528,8 @@ namespace AIStudio.Wpf.Mind.ViewModels private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e) { + if (GetLevel1Node()?.LayoutUpdating == true) return; + switch (e.PropertyName) { case nameof(IsExpanded): @@ -539,17 +542,17 @@ namespace AIStudio.Wpf.Mind.ViewModels case nameof(NodeLevel): MindLayout?.Appearance(this); break; - case nameof(MindType): - if (NodeLevel == NodeLevel.Level1) - { - MindLayout?.Appearance(this); - LayoutUpdated(); - } - else - { - GetLevel1Node().MindType = MindType; - } - break; + //case nameof(MindType): + // if (NodeLevel == NodeLevel.Level1) + // { + // MindLayout?.Appearance(this); + // LayoutUpdated(); + // } + // else + // { + // GetLevel1Node().MindType = MindType; + // } + // break; case nameof(Left): { if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs) @@ -608,15 +611,11 @@ namespace AIStudio.Wpf.Mind.ViewModels protected void UpdateOffsetX(double oldvalue, double newvalue) { - if (GetLevel1Node()?.LayoutUpdating == true) return; - Offset += new VectorBase(newvalue - oldvalue, 0); } protected void UpdateOffsetY(double oldvalue, double newvalue) { - if (GetLevel1Node()?.LayoutUpdating == true) return; - Offset += new VectorBase(0, newvalue - oldvalue); }