From c22707607602e23fd0f5d64e686560a155603895 Mon Sep 17 00:00:00 2001 From: kwai Date: Tue, 21 Feb 2023 19:47:46 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewModels/MindViewModel.cs | 29 +- AIStudio.Wpf.Mind/Helpers/DirectoryLayout.cs | 156 +++++++ AIStudio.Wpf.Mind/Helpers/IMindLayout.cs | 14 + AIStudio.Wpf.Mind/Helpers/LogicalLayout.cs | 128 +++++ AIStudio.Wpf.Mind/Helpers/MindLayout.cs | 199 ++++++++ AIStudio.Wpf.Mind/Themes/MindNode.xaml | 16 +- AIStudio.Wpf.Mind/ViewModels/MindNode.cs | 438 +++--------------- 7 files changed, 594 insertions(+), 386 deletions(-) create mode 100644 AIStudio.Wpf.Mind/Helpers/DirectoryLayout.cs create mode 100644 AIStudio.Wpf.Mind/Helpers/IMindLayout.cs create mode 100644 AIStudio.Wpf.Mind/Helpers/LogicalLayout.cs create mode 100644 AIStudio.Wpf.Mind/Helpers/MindLayout.cs diff --git a/AIStudio.Wpf.DiagramApp/ViewModels/MindViewModel.cs b/AIStudio.Wpf.DiagramApp/ViewModels/MindViewModel.cs index 054a19e..545fc3e 100644 --- a/AIStudio.Wpf.DiagramApp/ViewModels/MindViewModel.cs +++ b/AIStudio.Wpf.DiagramApp/ViewModels/MindViewModel.cs @@ -11,6 +11,7 @@ using System.Windows; using System.Windows.Media; using AIStudio.Wpf.DiagramDesigner; using AIStudio.Wpf.Mind.ViewModels; +using AIStudio.Wpf.Mind; namespace AIStudio.Wpf.Flowchart { @@ -35,30 +36,44 @@ namespace AIStudio.Wpf.Flowchart DiagramViewModel.AllowDrop = false; } + + private MindType _mindType = Mind.MindType.Directory; + public MindType MindType + { + get + { + return _mindType; + } + set + { + SetProperty(ref _mindType, value); + } + } + protected override void Init() { base.Init(); - MindNode level1node = new MindNode(DiagramViewModel, Mind.NodeLevel.Level1) { Text = "思维导图" }; + MindNode level1node = new MindNode(DiagramViewModel, Mind.NodeLevel.Level1, MindType) { Text = "思维导图" }; DiagramViewModel.DirectAddItemCommand.Execute(level1node); DiagramViewModel.CenterMoveCommand.Execute(level1node); - MindNode level2node1_1 = new MindNode(DiagramViewModel, Mind.NodeLevel.Level2) { Text = "分支主题1" }; + MindNode level2node1_1 = new MindNode(DiagramViewModel, Mind.NodeLevel.Level2, MindType) { Text = "分支主题1" }; level1node.AddChild(level2node1_1); - MindNode level3node1_1_1 = new MindNode(DiagramViewModel, Mind.NodeLevel.Level3) { Text = "分支主题1_1" }; + MindNode level3node1_1_1 = new MindNode(DiagramViewModel, Mind.NodeLevel.Level3, MindType) { Text = "分支主题1_1" }; level2node1_1.AddChild(level3node1_1_1); - MindNode level3node1_1_2 = new MindNode(DiagramViewModel, Mind.NodeLevel.Level3) { Text = "分支主题1_2" }; + MindNode level3node1_1_2 = new MindNode(DiagramViewModel, Mind.NodeLevel.Level3, MindType) { Text = "分支主题1_2" }; level2node1_1.AddChild(level3node1_1_2); - MindNode level3node1_1_3 = new MindNode(DiagramViewModel, Mind.NodeLevel.Level3) { Text = "分支主题1_3" }; + MindNode level3node1_1_3 = new MindNode(DiagramViewModel, Mind.NodeLevel.Level3, MindType) { Text = "分支主题1_3" }; level2node1_1.AddChild(level3node1_1_3); - MindNode level2node1_2 = new MindNode(DiagramViewModel, Mind.NodeLevel.Level2) { Text = "分支主题2" }; + MindNode level2node1_2 = new MindNode(DiagramViewModel, Mind.NodeLevel.Level2, MindType) { Text = "分支主题2" }; level1node.AddChild(level2node1_2); - MindNode level2node1_3 = new MindNode(DiagramViewModel, Mind.NodeLevel.Level2) { Text = "分支主题3" }; + MindNode level2node1_3 = new MindNode(DiagramViewModel, Mind.NodeLevel.Level2, MindType) { Text = "分支主题3" }; level1node.AddChild(level2node1_3); DiagramViewModel.ClearSelectedItemsCommand.Execute(null); diff --git a/AIStudio.Wpf.Mind/Helpers/DirectoryLayout.cs b/AIStudio.Wpf.Mind/Helpers/DirectoryLayout.cs new file mode 100644 index 0000000..3d99d9e --- /dev/null +++ b/AIStudio.Wpf.Mind/Helpers/DirectoryLayout.cs @@ -0,0 +1,156 @@ +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 DirectoryLayout : 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.Spacing = new SizeBase(50, 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.25, 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; + break; + } + case NodeLevel.Level3: + { + mindNode.ItemWidth = 80; + mindNode.ItemHeight = 25; + mindNode.ClearConnectors(); + + var port1 = new FullyCreatedConnectorInfo(mindNode.Root, mindNode, ConnectorOrientation.Left, true) { XRatio = 0, YRatio = 0.5 }; + mindNode.AddConnector(port1); + var port2 = new FullyCreatedConnectorInfo(mindNode.Root, mindNode, ConnectorOrientation.Bottom, true) { XRatio = 0.25, 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); + break; + } + } + } + + public void LayoutUpdated(MindNode mindNode) + { + if (mindNode == null) return; + + mindNode.LayoutUpdating = true; + var size = MeasureOverride(mindNode); + ArrangeOverride(mindNode); + + mindNode.Root.BringToFrontCommand.Execute(new SelectableDesignerItemViewModelBase[] { mindNode }); + mindNode.Root?.ReconnectLinksToClosestPorts(); + + mindNode.LayoutUpdating = false; + } + + + public SizeBase MeasureOverride(MindNode mindNode, bool isExpanded = true) + { + var sizewithSpacing = mindNode.SizeWithSpacing; + if (mindNode.Children?.Count > 0) + { + if (mindNode.NodeLevel == NodeLevel.Level1) + { + 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)); + } + 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)); + } + } + 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; + } + + public void ArrangeOverride(MindNode mindNode) + { + if (mindNode.NodeLevel == NodeLevel.Level1) + { + 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.Spacing.Width + child.Offset.X; + child.Top = top + child.Spacing.Height + child.Offset.Y; + child.DesiredPosition = child.Position; + left += child.DesiredSize.Width; + + ArrangeOverride(child); + } + } + } + else + { + double left = mindNode.MiddlePosition.X; + 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.Offset.X; + child.Top = top + child.Spacing.Height + child.Offset.Y; + child.DesiredPosition = child.Position; + top += child.DesiredSize.Height; + + ArrangeOverride(child); + } + } + } + } + } +} diff --git a/AIStudio.Wpf.Mind/Helpers/IMindLayout.cs b/AIStudio.Wpf.Mind/Helpers/IMindLayout.cs new file mode 100644 index 0000000..fe1373b --- /dev/null +++ b/AIStudio.Wpf.Mind/Helpers/IMindLayout.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; +using AIStudio.Wpf.Mind.ViewModels; + +namespace AIStudio.Wpf.Mind.Helpers +{ + public interface IMindLayout + { + void Appearance(MindNode mindNode); + void LayoutUpdated(MindNode mindNode); + + } +} diff --git a/AIStudio.Wpf.Mind/Helpers/LogicalLayout.cs b/AIStudio.Wpf.Mind/Helpers/LogicalLayout.cs new file mode 100644 index 0000000..a155955 --- /dev/null +++ b/AIStudio.Wpf.Mind/Helpers/LogicalLayout.cs @@ -0,0 +1,128 @@ +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 LogicalLayout : 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.None, true) { XRatio = 0.5, YRatio = 0.5 }; + 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.Spacing = new SizeBase(50, 15); + mindNode.ShapeViewModel.SinkMarker.PathStyle = ArrowPathStyle.Circle; + 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.Left, true) { XRatio = 0, YRatio = 0.5 }; + mindNode.AddConnector(port1); + var port2 = new FullyCreatedConnectorInfo(mindNode.Root, mindNode, ConnectorOrientation.Right, true) { XRatio = 1, YRatio = 0.5 }; + 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; + break; + } + case NodeLevel.Level3: + { + mindNode.ItemWidth = 80; + mindNode.ItemHeight = 25; + mindNode.ClearConnectors(); + + var port1 = new FullyCreatedConnectorInfo(mindNode.Root, mindNode, ConnectorOrientation.Left, true) { XRatio = 0, YRatio = 1 }; + mindNode.AddConnector(port1); + var port2 = new FullyCreatedConnectorInfo(mindNode.Root, mindNode, ConnectorOrientation.Right, true) { XRatio = 1, 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, 1); + break; + } + } + } + + public void LayoutUpdated(MindNode mindNode) + { + if (mindNode == null) return; + + mindNode.LayoutUpdating = true; + var size = MeasureOverride(mindNode); + ArrangeOverride(mindNode); + + mindNode.Root.BringToFrontCommand.Execute(new SelectableDesignerItemViewModelBase[] { mindNode }); + mindNode.Root?.ReconnectLinksToClosestPorts(); + + mindNode.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(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; + } + + public void ArrangeOverride(MindNode mindNode) + { + 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; + if (mindNode.Children?.Count > 0) + { + foreach (var child in mindNode.Children) + { + child.Left = left + child.Spacing.Width + child.Offset.X; + child.Top = top + child.DesiredSize.Height / 2 - child.ItemHeight / 2 + child.Offset.Y; + child.DesiredPosition = child.Position; + top += child.DesiredSize.Height; + + ArrangeOverride(child); + } + } + + } + } +} diff --git a/AIStudio.Wpf.Mind/Helpers/MindLayout.cs b/AIStudio.Wpf.Mind/Helpers/MindLayout.cs new file mode 100644 index 0000000..da8a984 --- /dev/null +++ b/AIStudio.Wpf.Mind/Helpers/MindLayout.cs @@ -0,0 +1,199 @@ +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 MindLayout : 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.None, true) { XRatio = 0.5, YRatio = 0.5 }; + 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.Spacing = new SizeBase(50, 15); + mindNode.ShapeViewModel.SinkMarker.PathStyle = ArrowPathStyle.Circle; + 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.Left, true) { XRatio = 0, YRatio = 0.5 }; + mindNode.AddConnector(port1); + var port2 = new FullyCreatedConnectorInfo(mindNode.Root, mindNode, ConnectorOrientation.Right, true) { XRatio = 1, YRatio = 0.5 }; + 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; + break; + } + case NodeLevel.Level3: + { + mindNode.ItemWidth = 80; + mindNode.ItemHeight = 25; + mindNode.ClearConnectors(); + + var port1 = new FullyCreatedConnectorInfo(mindNode.Root, mindNode, ConnectorOrientation.Left, true) { XRatio = 0, YRatio = 1 }; + mindNode.AddConnector(port1); + var port2 = new FullyCreatedConnectorInfo(mindNode.Root, mindNode, ConnectorOrientation.Right, true) { XRatio = 1, 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, 1); + break; + } + } + } + + + public void LayoutUpdated(MindNode mindNode) + { + if (mindNode == null) return; + + mindNode.LayoutUpdating = true; + var size = MeasureOverride(mindNode); + ArrangeOverride(mindNode); + + mindNode.Root.BringToFrontCommand.Execute(new SelectableDesignerItemViewModelBase[] { mindNode }); + mindNode.Root?.ReconnectLinksToClosestPorts(); + + mindNode.LayoutUpdating = false; + } + + public SizeBase MeasureOverride(MindNode mindNode, bool isExpanded = true) + { + 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); + 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); + 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)))); + } + else + { + 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; + } + + public void ArrangeOverride(MindNode mindNode) + { + if (mindNode.NodeLevel == NodeLevel.Level1) + { + if (mindNode.Children?.Count > 0) + { + var rights = mindNode.Children.Where(p => p.IsRightLayout == true).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) + { + child.Left = left + child.Spacing.Width + child.Offset.X; + child.Top = lefttop + child.DesiredSize.Height / 2 - child.ItemHeight / 2 + child.Offset.Y; + child.DesiredPosition = child.Position; + lefttop += child.DesiredSize.Height; + + ArrangeOverride(child); + } + + var lefts = mindNode.Children.Where(p => p.IsRightLayout == false).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) + { + child.Left = right - child.Spacing.Width - child.ItemWidth + child.Offset.X; + child.Top = righttop + child.DesiredSize.Height / 2 - child.ItemHeight / 2 + child.Offset.Y; + child.DesiredPosition = child.Position; + righttop += child.DesiredSize.Height; + + ArrangeOverride(child); + } + } + } + else + { + if (mindNode.GetLevel2Node().IsRightLayout) + { + 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; + if (mindNode.Children?.Count > 0) + { + foreach (var child in mindNode.Children) + { + child.Left = left + child.Spacing.Width + child.Offset.X; + child.Top = top + child.DesiredSize.Height / 2 - child.ItemHeight / 2 + child.Offset.Y; + child.DesiredPosition = child.Position; + top += child.DesiredSize.Height; + + ArrangeOverride(child); + } + } + } + else + { + double right = 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; + if (mindNode.Children?.Count > 0) + { + foreach (var child in mindNode.Children) + { + child.Left = right - child.Spacing.Width - child.ItemWidth + child.Offset.X; + child.Top = top + child.DesiredSize.Height / 2 - child.ItemHeight / 2 + child.Offset.Y; + child.DesiredPosition = child.Position; + top += child.DesiredSize.Height; + + ArrangeOverride(child); + } + } + } + } + + } + + + } +} diff --git a/AIStudio.Wpf.Mind/Themes/MindNode.xaml b/AIStudio.Wpf.Mind/Themes/MindNode.xaml index 44eac42..46f2380 100644 --- a/AIStudio.Wpf.Mind/Themes/MindNode.xaml +++ b/AIStudio.Wpf.Mind/Themes/MindNode.xaml @@ -6,6 +6,7 @@ +