Files
aistudio-wpf-diagram/AIStudio.Wpf.Mind/ViewModels/MindNode.cs

708 lines
27 KiB
C#
Raw Normal View History

2023-02-12 21:30:16 +08:00
using System;
using System.Collections.Generic;
2023-02-19 21:38:28 +08:00
using System.Collections.ObjectModel;
2023-02-12 21:30:16 +08:00
using System.ComponentModel;
2023-02-19 21:38:28 +08:00
using System.IO;
2023-02-14 18:58:26 +08:00
using System.Linq;
2023-02-12 21:30:16 +08:00
using System.Text;
2023-02-19 22:56:47 +08:00
using System.Windows.Controls;
2023-02-19 21:38:28 +08:00
using System.Windows.Media;
2023-02-12 21:30:16 +08:00
using AIStudio.Wpf.DiagramDesigner;
2023-02-19 21:38:28 +08:00
using AIStudio.Wpf.DiagramDesigner.Algorithms;
2023-02-14 18:58:26 +08:00
using AIStudio.Wpf.DiagramDesigner.Geometrys;
2023-02-12 21:30:16 +08:00
using AIStudio.Wpf.DiagramDesigner.Models;
namespace AIStudio.Wpf.Mind.ViewModels
{
public class MindNode : DesignerItemViewModelBase
{
public MindNode(NodeLevel nodeLevel) : this(null, nodeLevel)
{
}
public MindNode(IDiagramViewModel root, NodeLevel nodeLevel) : base(root)
{
NodeLevel = nodeLevel;
2023-02-19 21:38:28 +08:00
LevelInit(true);
2023-02-12 21:30:16 +08:00
}
public MindNode(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer)
{
}
public MindNode(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
{
}
2023-02-19 21:38:28 +08:00
protected override void Init(IDiagramViewModel root)
{
base.Init(root);
EnabledForConnection = false;
AddChildCommand = new SimpleCommand(Command_Enable, ExecuteAddChildCommand);
AddParentCommand = new SimpleCommand(Level_Enable, ExecuteAddParentCommand);
AddPeerCommand = new SimpleCommand(Level_Enable, ExecuteAddPeerCommand);
2023-02-19 22:56:47 +08:00
DeleteCommand = new SimpleCommand(Level_Enable, ExecuteDeleteCommand);
2023-02-19 21:38:28 +08:00
MoveForwardCommand = new SimpleCommand(Command_Enable, ExecuteMoveForwardCommand);
MoveBackCommand = new SimpleCommand(Command_Enable, ExecuteMoveBackCommand);
BuildMenuOptions();
this.PropertyChanged += this.Item_PropertyChanged;
}
2023-02-19 22:56:47 +08:00
private void LevelInit(bool init = false)
2023-02-19 21:38:28 +08:00
{
switch (NodeLevel)
{
case NodeLevel.Level1:
{
ItemWidth = 110;
ItemHeight = 40;
this.ClearConnectors();
var port = new FullyCreatedConnectorInfo(Root, this, ConnectorOrientation.None, true) { XRatio = 0.5, YRatio = 0.5 };
this.AddConnector(port);
IsInnerConnector = true;
ColorViewModel.FillColor.Color = Color.FromRgb(0x73, 0xa1, 0xbf);
ColorViewModel.LineColor.Color = Color.FromRgb(0x73, 0xa1, 0xbf);
FontViewModel.FontColor = Colors.White;
FontViewModel.FontSize = 15;
Spacing = new SizeBase(50, 15);
ShapeViewModel.SinkMarker.PathStyle = ArrowPathStyle.Circle;
ShapeViewModel.SinkMarker.SizeStyle = ArrowSizeStyle.VerySmall;
break;
}
case NodeLevel.Level2:
{
ItemWidth = 80;
ItemHeight = 25;
this.ClearConnectors();
var port1 = new FullyCreatedConnectorInfo(Root, this, ConnectorOrientation.Left, true) { XRatio = 0, YRatio = 0.5 };
this.AddConnector(port1);
var port2 = new FullyCreatedConnectorInfo(Root, this, ConnectorOrientation.Right, true) { XRatio = 1, YRatio = 0.5 };
this.AddConnector(port2);
IsInnerConnector = true;
ColorViewModel.LineColor.Color = Color.FromRgb(0x73, 0xa1, 0xbf);
ShapeViewModel.SinkMarker.PathStyle = ArrowPathStyle.None;
ShapeViewModel.SinkMarker.SizeStyle = ArrowSizeStyle.VerySmall;
break;
}
case NodeLevel.Level3:
{
ItemWidth = 80;
ItemHeight = 25;
this.ClearConnectors();
var port1 = new FullyCreatedConnectorInfo(Root, this, ConnectorOrientation.Left, true) { XRatio = 0, YRatio = 1 };
this.AddConnector(port1);
var port2 = new FullyCreatedConnectorInfo(Root, this, ConnectorOrientation.Right, true) { XRatio = 1, YRatio = 1 };
this.AddConnector(port2);
IsInnerConnector = true;
ColorViewModel.LineColor.Color = Color.FromRgb(0x73, 0xa1, 0xbf);
ShapeViewModel.SinkMarker.PathStyle = ArrowPathStyle.None;
ShapeViewModel.SinkMarker.SizeStyle = ArrowSizeStyle.VerySmall;
break;
}
}
}
private bool Level_Enable(object obj)
{
if (Command_Enable(obj) == false) return false;
return NodeLevel != NodeLevel.Level1;
}
2023-02-19 22:56:47 +08:00
#region
2023-02-12 21:30:16 +08:00
[Browsable(false)]
2023-02-19 22:56:47 +08:00
private NodeLevel _nodeLevel;
2023-02-12 21:30:16 +08:00
public NodeLevel NodeLevel
{
2023-02-19 22:56:47 +08:00
get
{
return _nodeLevel;
}
set
{
SetProperty(ref _nodeLevel, value);
}
2023-02-12 21:30:16 +08:00
}
private double _cornerRadius = 3;
public double CornerRadius
{
get
{
return _cornerRadius;
}
set
{
SetProperty(ref _cornerRadius, value);
}
}
2023-02-13 22:50:50 +08:00
2023-02-19 21:38:28 +08:00
private bool _isExpanded = true;
public bool IsExpanded
{
get
{
return _isExpanded;
}
set
{
SetProperty(ref _isExpanded, value);
}
2023-02-19 22:56:47 +08:00
}
2023-02-19 21:38:28 +08:00
public SizeBase Spacing
2023-02-13 22:50:50 +08:00
{
get; set;
2023-02-19 21:38:28 +08:00
} = new SizeBase(15, 15);
2023-02-13 22:50:50 +08:00
public List<MindNode> Children
{
get; set;
2023-02-16 19:21:37 +08:00
} = new List<MindNode>();
public SizeBase SizeWithSpacing
{
get
{
2023-02-19 21:38:28 +08:00
return this.Size.Add(Spacing.Width * 2, Spacing.Height * 2);
2023-02-16 19:21:37 +08:00
}
}
2023-02-16 23:02:43 +08:00
public SizeBase DesiredSize
{
2023-02-19 21:38:28 +08:00
get; set;
2023-02-16 23:02:43 +08:00
}
2023-02-19 21:38:28 +08:00
public PointBase DesiredPosition
2023-02-16 19:21:37 +08:00
{
2023-02-19 21:38:28 +08:00
get; set;
2023-02-13 22:50:50 +08:00
}
2023-02-14 18:58:26 +08:00
2023-02-19 21:38:28 +08:00
public PointBase Offset
2023-02-16 19:21:37 +08:00
{
2023-02-19 21:38:28 +08:00
get; set;
2023-02-16 23:02:43 +08:00
}
2023-02-14 18:58:26 +08:00
2023-02-19 22:56:47 +08:00
private MindType _mindType;
public MindType MindType
{
get
{
return _mindType;
}
set
{
SetProperty(ref _mindType, value);
}
}
private bool _layoutUpdating;
private bool _isRightLayout = true;
#endregion
#region
2023-02-19 21:38:28 +08:00
public SimpleCommand AddParentCommand
2023-02-16 23:02:43 +08:00
{
2023-02-19 21:38:28 +08:00
get; private set;
2023-02-16 19:21:37 +08:00
}
2023-02-12 21:30:16 +08:00
2023-02-19 21:38:28 +08:00
public SimpleCommand AddChildCommand
2023-02-12 21:30:16 +08:00
{
2023-02-19 21:38:28 +08:00
get; private set;
}
2023-02-12 21:30:16 +08:00
2023-02-19 21:38:28 +08:00
public SimpleCommand AddPeerCommand
{
get; private set;
2023-02-12 21:30:16 +08:00
}
2023-02-19 21:38:28 +08:00
public SimpleCommand DeleteCommand
2023-02-12 21:30:16 +08:00
{
2023-02-19 21:38:28 +08:00
get; private set;
}
2023-02-12 21:30:16 +08:00
2023-02-19 21:38:28 +08:00
public SimpleCommand MoveForwardCommand
{
get; private set;
2023-02-12 21:30:16 +08:00
}
2023-02-19 21:38:28 +08:00
public SimpleCommand MoveBackCommand
2023-02-12 21:30:16 +08:00
{
2023-02-19 21:38:28 +08:00
get; private set;
}
2023-02-19 22:56:47 +08:00
#endregion
2023-02-12 21:30:16 +08:00
2023-02-19 22:56:47 +08:00
#region
2023-02-19 21:38:28 +08:00
private void BuildMenuOptions()
{
menuOptions = new ObservableCollection<CinchMenuItem>();
CinchMenuItem menuItem = new CinchMenuItem();
menuItem.Text = "下级";
menuItem.Command = AddChildCommand;
menuOptions.Add(menuItem);
menuItem = new CinchMenuItem();
menuItem.Text = "同级";
menuItem.Command = AddPeerCommand;
menuOptions.Add(menuItem);
2023-02-19 22:56:47 +08:00
menuItem = new CinchMenuItem();
menuItem.Text = "上级";
menuItem.Command = AddParentCommand;
menuOptions.Add(menuItem);
2023-02-19 21:38:28 +08:00
menuItem = new CinchMenuItem();
menuItem.Text = "前移";
menuItem.Command = MoveForwardCommand;
menuOptions.Add(menuItem);
menuItem = new CinchMenuItem();
menuItem.Text = "后移";
menuItem.Command = MoveBackCommand;
menuOptions.Add(menuItem);
menuItem = new CinchMenuItem();
menuItem.Text = "删除";
menuItem.Command = DeleteCommand;
menuOptions.Add(menuItem);
2023-02-12 21:30:16 +08:00
}
2023-02-19 22:56:47 +08:00
#endregion
2023-02-12 21:30:16 +08:00
2023-02-19 22:56:47 +08:00
#region
2023-02-19 21:38:28 +08:00
public void ExecuteAddChildCommand(object obj)
2023-02-12 21:30:16 +08:00
{
2023-02-19 21:38:28 +08:00
if (obj is MindNode node)
{
}
else
{
if (NodeLevel == NodeLevel.Level1)
node = new MindNode(Root, NodeLevel.Level2) { Text = "分支主题" };
else
node = new MindNode(Root, NodeLevel.Level3) { Text = "分支主题" };
}
AddChild(node);
2023-02-12 21:30:16 +08:00
2023-02-19 21:38:28 +08:00
LayoutUpdated();
2023-02-12 21:30:16 +08:00
}
2023-02-19 21:38:28 +08:00
public void ExecuteAddParentCommand(object obj)
2023-02-14 18:58:26 +08:00
{
2023-02-19 21:38:28 +08:00
if (Parent is MindNode parent)
{
if (obj is MindNode node)
{
}
else
{
if (NodeLevel == NodeLevel.Level1)
{
return;
}
else if (NodeLevel == NodeLevel.Level2)
node = new MindNode(Root, NodeLevel.Level2) { Text = "分支主题" };
else
node = new MindNode(Root, NodeLevel.Level3) { Text = "分支主题" };
}
parent.RemoveChild(this);
int index = parent.Children.IndexOf(this);
parent.AddChild(node, index + 1);
2023-02-19 22:56:47 +08:00
2023-02-19 21:38:28 +08:00
node.AddChild(this);
2023-02-14 18:58:26 +08:00
2023-02-19 21:38:28 +08:00
LayoutUpdated();
}
2023-02-14 18:58:26 +08:00
}
2023-02-19 21:38:28 +08:00
public void ExecuteAddPeerCommand(object obj)
2023-02-14 18:58:26 +08:00
{
2023-02-19 21:38:28 +08:00
if (Parent is MindNode parent)
{
if (obj is MindNode node)
{
}
else
{
if (NodeLevel == NodeLevel.Level1)
{
return;
}
else if (NodeLevel == NodeLevel.Level2)
node = new MindNode(Root, NodeLevel.Level2) { Text = "分支主题" };
else
node = new MindNode(Root, NodeLevel.Level3) { Text = "分支主题" };
}
int index = parent.Children.IndexOf(this);
parent.AddChild(node, index + 1);
LayoutUpdated();
}
2023-02-14 18:58:26 +08:00
}
2023-02-12 21:30:16 +08:00
2023-02-19 21:38:28 +08:00
private void ExecuteMoveBackCommand(object obj)
2023-02-12 21:30:16 +08:00
{
2023-02-19 21:38:28 +08:00
if (Parent is MindNode parent)
{
int index = parent.Children.IndexOf(this);
if (index < parent.Children.Count - 1)
{
parent.RemoveChild(this);
parent.AddChild(this, index + 1);
LayoutUpdated();
}
}
2023-02-12 21:30:16 +08:00
}
2023-02-19 21:38:28 +08:00
private void ExecuteMoveForwardCommand(object obj)
2023-02-12 21:30:16 +08:00
{
2023-02-19 21:38:28 +08:00
if (Parent is MindNode parent)
{
int index = parent.Children.IndexOf(this);
if (index > 0)
{
parent.RemoveChild(this);
parent.AddChild(this, index - 1);
LayoutUpdated();
}
}
}
2023-02-12 21:30:16 +08:00
2023-02-19 21:38:28 +08:00
private void ExecuteDeleteCommand(object obj)
{
if (Parent is MindNode parent)
{
2023-02-19 22:56:47 +08:00
parent.RemoveChild(this, true);
2023-02-19 21:38:28 +08:00
LayoutUpdated();
}
2023-02-12 21:30:16 +08:00
}
2023-02-19 21:38:28 +08:00
public void AddChild(MindNode item, int index = -1)
2023-02-12 21:30:16 +08:00
{
2023-02-19 22:56:47 +08:00
if (this.NodeLevel == NodeLevel.Level1)
{
item.NodeLevel = NodeLevel.Level2;
}
else
{
item.NodeLevel = NodeLevel.Level3;
}
2023-02-19 21:38:28 +08:00
if (index >= 0)
{
this.Children.Insert(index, item);
}
else
{
this.Children.Add(item);
}
item.Parent = this;
Root?.DirectAddItemCommand.Execute(item);
2023-02-12 21:30:16 +08:00
2023-02-19 21:38:28 +08:00
ConnectionViewModel connector = new ConnectionViewModel(Root, this.Connectors.FirstOrDefault(), item.Connectors.FirstOrDefault());
connector.ColorViewModel.LineColor = this.ColorViewModel.LineColor;
connector.SmoothMargin = 20;
connector.SmoothAutoSlope = 0.2;
connector.ShapeViewModel.SinkMarker.PathStyle = this.ShapeViewModel.SinkMarker.PathStyle;
connector.ShapeViewModel.SinkMarker.SizeStyle = this.ShapeViewModel.SinkMarker.SizeStyle;
Root?.DirectAddItemCommand.Execute(connector);
2023-02-19 22:56:47 +08:00
Root?.ClearSelectedItemsCommand.Execute(new SelectableDesignerItemViewModelBase[] { connector });
2023-02-19 21:38:28 +08:00
Root?.BringForwardCommand.Execute(new DesignerItemViewModelBase[] { item });
2023-02-12 21:30:16 +08:00
}
2023-02-19 22:56:47 +08:00
public void RemoveChild(MindNode item, bool removeall = false)
2023-02-12 21:30:16 +08:00
{
2023-02-19 21:38:28 +08:00
item.PropertyChanged -= Item_PropertyChanged;
this.Children.Remove(item);
var connectors = Root?.Items.OfType<ConnectionViewModel>().Where(p => p.SinkConnectorInfoFully?.DataItem == item).ToList();
2023-02-12 21:30:16 +08:00
2023-02-19 21:38:28 +08:00
Root?.DirectRemoveItemCommand.Execute(item);
Root?.DirectRemoveItemCommand.Execute(connectors);
2023-02-19 22:56:47 +08:00
if (removeall)
2023-02-19 21:38:28 +08:00
{
2023-02-19 22:56:47 +08:00
if (item.Children?.Count > 0)
2023-02-19 21:38:28 +08:00
{
2023-02-19 22:56:47 +08:00
foreach (var child in item.Children.ToList())
{
item.RemoveChild(child);
}
2023-02-19 21:38:28 +08:00
}
}
2023-02-12 21:30:16 +08:00
}
2023-02-19 22:56:47 +08:00
#endregion
2023-02-16 19:21:37 +08:00
2023-02-19 21:38:28 +08:00
private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
2023-02-14 18:58:26 +08:00
{
2023-02-19 21:38:28 +08:00
switch (e.PropertyName)
{
case nameof(IsExpanded):
2023-02-19 22:56:47 +08:00
case nameof(ItemWidth):
case nameof(ItemHeight):
case nameof(MindType):
2023-02-19 21:38:28 +08:00
GetLevel1Node()?.LayoutUpdated();
break;
case nameof(NodeLevel):
LevelInit();
break;
case nameof(Left):
{
if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs)
{
if (NodeLevel == NodeLevel.Level1)
{
LayoutUpdated();
}
else
{
UpdateOffsetX((double)valuePropertyChangedEventArgs.OldValue, (double)valuePropertyChangedEventArgs.NewValue);
LayoutUpdated();
}
}
break;
}
case nameof(Top):
{
if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs)
{
if (NodeLevel == NodeLevel.Level1)
{
LayoutUpdated();
}
else
{
UpdateOffsetY((double)valuePropertyChangedEventArgs.OldValue, (double)valuePropertyChangedEventArgs.NewValue);
LayoutUpdated();
}
}
break;
}
}
2023-02-14 18:58:26 +08:00
}
2023-02-12 21:30:16 +08:00
2023-02-19 22:56:47 +08:00
#region
protected MindNode GetLevel1Node()
2023-02-12 21:30:16 +08:00
{
2023-02-19 22:56:47 +08:00
var node = this;
while (node.Parent is MindNode mindNode)
{
node = mindNode;
}
return node;
}
protected MindNode GetLevel2Node()
{
var node = this;
while (node.Parent is MindNode mindNode && mindNode.NodeLevel == NodeLevel.Level2)
{
node = mindNode;
}
return node;
}
protected void UpdateOffsetX(double oldvalue, double newvalue)
{
if (GetLevel1Node()?._layoutUpdating == true) return;
2023-02-12 21:30:16 +08:00
2023-02-19 21:38:28 +08:00
Offset += new VectorBase(newvalue - oldvalue, 0);
2023-02-12 21:30:16 +08:00
}
2023-02-19 22:56:47 +08:00
protected void UpdateOffsetY(double oldvalue, double newvalue)
2023-02-12 21:30:16 +08:00
{
2023-02-19 22:56:47 +08:00
if (GetLevel1Node()?._layoutUpdating == true) return;
2023-02-12 21:30:16 +08:00
2023-02-19 21:38:28 +08:00
Offset += new VectorBase(0, newvalue - oldvalue);
2023-02-12 21:30:16 +08:00
}
2023-02-19 21:38:28 +08:00
public void LayoutUpdated()
2023-02-12 21:30:16 +08:00
{
2023-02-19 21:38:28 +08:00
GetLevel1Node()?.Level1LayoutUpdated();
2023-02-12 21:30:16 +08:00
}
2023-02-19 21:38:28 +08:00
protected void Level1LayoutUpdated()
2023-02-12 21:30:16 +08:00
{
2023-02-19 22:56:47 +08:00
_layoutUpdating = true;
2023-02-19 21:38:28 +08:00
var size = MeasureOverride();
ArrangeOverride();
Root.BringToFrontCommand.Execute(new SelectableDesignerItemViewModelBase[] { this });
Root?.ReconnectLinksToClosestPorts();
2023-02-12 21:30:16 +08:00
2023-02-19 22:56:47 +08:00
_layoutUpdating = false;
2023-02-12 21:30:16 +08:00
}
2023-02-14 18:58:26 +08:00
2023-02-19 21:38:28 +08:00
protected SizeBase MeasureOverride(bool isExpanded = true)
{
2023-02-19 22:56:47 +08:00
switch (MindType)
2023-02-19 21:38:28 +08:00
{
2023-02-19 22:56:47 +08:00
case MindType.Mind:
{
var sizewithSpacing = SizeWithSpacing;
if (Children?.Count > 0)
{
if (NodeLevel == NodeLevel.Level1)
{
var rights = Children.Where((p, index) => index % 2 == 0).ToList();
rights.ForEach(p => p._isRightLayout = true);
var rightsizes = rights.Select(p => p.MeasureOverride(IsExpanded && isExpanded)).ToArray();
var lefts = Children.Where((p, index) => index % 2 == 1).ToList();
lefts.ForEach(p => p._isRightLayout = false);
var leftsizes = lefts.Select(p => p.MeasureOverride(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 = Children.Select(p => p.MeasureOverride(IsExpanded && isExpanded)).ToArray();
sizewithSpacing = new SizeBase(sizewithSpacing.Width + childrensizes.Max(p => p.Width), Math.Max(sizewithSpacing.Height, childrensizes.Sum(p => p.Height)));
}
}
DesiredSize = isExpanded ? sizewithSpacing : new SizeBase(0, 0);
Visible = isExpanded;
var connectors = Root?.Items.OfType<ConnectionViewModel>().Where(p => p.SinkConnectorInfoFully?.DataItem == this).ToList();
connectors?.ForEach(p => p.Visible = Visible);
break;
}
case MindType.Logical:
{
var sizewithSpacing = SizeWithSpacing;
if (Children?.Count > 0)
{
var childrensizes = Children.Select(p => p.MeasureOverride(IsExpanded && isExpanded)).ToArray();
sizewithSpacing = new SizeBase(sizewithSpacing.Width + childrensizes.Max(p => p.Width), Math.Max(sizewithSpacing.Height, childrensizes.Sum(p => p.Height)));
}
DesiredSize = isExpanded ? sizewithSpacing : new SizeBase(0, 0);
Visible = isExpanded;
var connectors = Root?.Items.OfType<ConnectionViewModel>().Where(p => p.SinkConnectorInfoFully?.DataItem == this).ToList();
connectors?.ForEach(p => p.Visible = Visible);
break;
}
default:
{
var sizewithSpacing = SizeWithSpacing;
if (Children?.Count > 0)
{
var childrensizes = Children.Select(p => p.MeasureOverride(IsExpanded && isExpanded)).ToArray();
sizewithSpacing = new SizeBase(sizewithSpacing.Width + childrensizes.Max(p => p.Width), Math.Max(sizewithSpacing.Height, childrensizes.Sum(p => p.Height)));
}
DesiredSize = isExpanded ? sizewithSpacing : new SizeBase(0, 0);
Visible = isExpanded;
var connectors = Root?.Items.OfType<ConnectionViewModel>().Where(p => p.SinkConnectorInfoFully?.DataItem == this).ToList();
connectors?.ForEach(p => p.Visible = Visible);
break;
}
2023-02-19 21:38:28 +08:00
}
return DesiredSize;
2023-02-16 19:21:37 +08:00
}
2023-02-19 21:38:28 +08:00
protected void ArrangeOverride()
2023-02-14 18:58:26 +08:00
{
2023-02-19 22:56:47 +08:00
switch (MindType)
2023-02-19 21:38:28 +08:00
{
2023-02-19 22:56:47 +08:00
case MindType.Mind:
{
if (NodeLevel == NodeLevel.Level1)
{
if (Children?.Count > 0)
{
var rights = Children.Where(p => p._isRightLayout == true).ToList();
double left = MiddlePosition.X + ItemWidth / 2 + Spacing.Width;
double lefttop = MiddlePosition.Y - Math.Min(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;
child.ArrangeOverride();
}
var lefts = Children.Where(p => p._isRightLayout == false).ToList();
double right = MiddlePosition.X - ItemWidth / 2 - Spacing.Width;
double righttop = MiddlePosition.Y - Math.Min(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;
child.ArrangeOverride();
}
}
}
else
{
if (GetLevel2Node()._isRightLayout)
{
double left = MiddlePosition.X + ItemWidth / 2 + Spacing.Width;
double top = MiddlePosition.Y - Math.Min(DesiredSize.Height, Children.Sum(p => p.DesiredSize.Height)) / 2;
if (Children?.Count > 0)
{
foreach (var child in 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;
child.ArrangeOverride();
}
}
}
else
{
double right = MiddlePosition.X - ItemWidth / 2 - Spacing.Width;
double top = MiddlePosition.Y - Math.Min(DesiredSize.Height, Children.Sum(p => p.DesiredSize.Height)) / 2;
if (Children?.Count > 0)
{
foreach (var child in 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;
child.ArrangeOverride();
}
}
}
}
break;
}
case MindType.Logical:
{
double left = MiddlePosition.X + ItemWidth / 2 + Spacing.Width;
double top = MiddlePosition.Y - Math.Min(DesiredSize.Height, Children.Sum(p => p.DesiredSize.Height)) / 2;
if (Children?.Count > 0)
{
foreach (var child in 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;
2023-02-19 21:38:28 +08:00
2023-02-19 22:56:47 +08:00
child.ArrangeOverride();
}
}
break;
}
default:
{
break;
}
2023-02-19 21:38:28 +08:00
}
2023-02-14 18:58:26 +08:00
}
2023-02-19 22:56:47 +08:00
#endregion
2023-02-12 21:30:16 +08:00
}
}