项目结构调整

This commit is contained in:
艾竹
2023-04-16 20:11:40 +08:00
parent cbfbf96033
commit 81f91f3f35
2124 changed files with 218 additions and 5516 deletions

View File

@@ -0,0 +1,813 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.Design;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Input;
using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
using AIStudio.Wpf.DiagramDesigner.Helpers;
using AIStudio.Wpf.DiagramDesigner.Models;
using AIStudio.Wpf.DiagramDesigner.Serializable;
using AIStudio.Wpf.DiagramDesigner.Serializable.ViewModels;
using AIStudio.Wpf.Mind.Controls;
using AIStudio.Wpf.Mind.Helpers;
using AIStudio.Wpf.Mind.Models;
namespace AIStudio.Wpf.Mind.ViewModels
{
public class MindNode : DiagramItemViewModel
{
public MindNode() : this(null)
{
}
public MindNode(IDiagramViewModel root) : base(root)
{
}
public MindNode(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer)
{
InitLayout(false);
}
public MindNode(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
{
InitLayout(false);
}
public override SelectableItemBase GetSerializableObject()
{
return new MindNodeDesignerItem(this);
}
public override DiagramNode ToDiagram()
{
var mindNodeModel = new MindNodeModel();
mindNodeModel.MindType = MindType;
mindNodeModel.MindTheme = MindTheme;
mindNodeModel.Spacing = Spacing;
mindNodeModel.Offset = Offset;
mindNodeModel.IsExpanded = IsExpanded;
mindNodeModel.LinkInfoModel = new LinkInfoModel(LinkInfo);
mindNodeModel.ImageInfoModel = new ImageInfoModel(ImageInfo);
mindNodeModel.Remark = Remark;
mindNodeModel.Priority = Priority;
mindNodeModel.Rate = Rate;
if (Tags != null)
{
mindNodeModel.Tags = new List<string>(Tags);
}
return mindNodeModel;
}
protected override void Init(IDiagramViewModel root, bool initNew)
{
base.Init(root, initNew);
EnabledForConnection = false;
AlwayForResized = true;
CustomText = true;
IsInnerConnector = true;
AddChildCommand = (Root as IMindDiagramViewModel)?.AddChildCommand;
AddParentCommand = (Root as IMindDiagramViewModel)?.AddParentCommand;
AddPearCommand = (Root as IMindDiagramViewModel)?.AddPearCommand;
DeleteCommand = (Root as IMindDiagramViewModel)?.DeleteCommand;
MoveForwardCommand = (Root as IMindDiagramViewModel)?.MoveForwardCommand;
MoveBackCommand = (Root as IMindDiagramViewModel)?.MoveBackCommand;
ExportCommand = (Root as IMindDiagramViewModel)?.ExportCommand;
ImportCommand = (Root as IMindDiagramViewModel)?.ImportCommand;
BuildMenuOptions();
Tags = new ObservableCollection<string>();
}
protected override void InitNew()
{
this.ClearConnectors();
}
public void InitLayout(bool initAppearance)
{
IsLoaded = false;
var layout = TypeHelper.GetType(this.MindType.ToString() + "Layout");
MindLayout = layout != null ? (System.Activator.CreateInstance(layout) as IMindLayout) : new MindLayout();
MindLayout.Appearance(this, MindTheme, initAppearance);
IsLoaded = true;
}
public void InitConnectionLayout()
{
var connector = Root?.Items.OfType<ConnectionViewModel>().Where(p => p.IsFullConnection).FirstOrDefault(p => p.SinkConnectorInfoFully.DataItem == this);
if (connector != null)
{
MindLayout?.GetOrSetConnectionViewModel(connector.SourceConnectorInfo.DataItem as MindNode, connector.SinkConnectorInfoFully.DataItem as MindNode, connector);
}
else if (ParentNode != null)
{
connector = MindLayout?.GetOrSetConnectionViewModel(ParentNode, this, null);
Root?.Add(new SelectableDesignerItemViewModelBase[] { connector });
connector.ZIndex = -1;
connector.IsSelected = false;
}
}
public void UpdatedLayout()
{
MindLayout?.UpdatedLayout(GetLevel0Node());
}
public void ThemeChange()
{
MindThemeHelper.ThemeChange(this, MindTheme);
}
protected override void LoadDesignerItemViewModel(SelectableItemBase designerbase)
{
base.LoadDesignerItemViewModel(designerbase);
if (designerbase is MindNodeDesignerItem designer)
{
MindType = designer.MindType;
MindTheme = designer.MindTheme;
Spacing = designer.Spacing;
Offset = designer.Offset;
IsExpanded = designer.IsExpanded;
if (string.IsNullOrEmpty(designer.LinkInfoItem?.Url) && string.IsNullOrEmpty(designer.LinkInfoItem?.Text))
{
LinkInfo = null;
}
else
{
LinkInfo = new LinkInfo(designer.LinkInfoItem?.Url, designer.LinkInfoItem?.Text);
}
if (string.IsNullOrEmpty(designer.ImageInfoItem?.Url) && string.IsNullOrEmpty(designer.ImageInfoItem?.Text))
{
ImageInfo = null;
}
else
{
ImageInfo = new ImageInfo(designer.ImageInfoItem?.Url, designer.ImageInfoItem?.Text);
}
Remark = designer.Remark;
if (double.TryParse(designer.Priority ?? "", out var priority))
{
Priority = priority;
}
if (double.TryParse(designer.Rate ?? "", out var rate))
{
Rate = rate;
}
if (designer.Tags != null)
{
Tags = new ObservableCollection<string>(designer.Tags);
}
}
}
#region
private MindType _mindType = MindType.Mind;
public MindType MindType
{
get
{
return GetLevel0Node()._mindType;
}
set
{
GetLevel0Node()._mindType = value;
}
}
private MindTheme _mindTheme;
public MindTheme MindTheme
{
get
{
return GetLevel0Node()._mindTheme;
}
set
{
GetLevel0Node()._mindTheme = value;
}
}
public IMindLayout MindLayout
{
get; set;
}
public MindNode ParentNode
{
get
{
return Parent as MindNode;
}
}
public MindNode RootNode
{
get
{
return GetLevel0Node();
}
}
public int NodeLevel
{
get
{
if (ParentNode == null)
{
return 0;
}
else
{
return ParentNode.NodeLevel + 1;
}
}
}
private bool _isExpanded = true;
[CanDo]
public bool IsExpanded
{
get
{
return _isExpanded;
}
set
{
SetProperty(ref _isExpanded, value);
}
}
public SizeBase Spacing
{
get; set;
} = new SizeBase(15, 15);
private ObservableCollection<MindNode> _children = new ObservableCollection<MindNode>();
public ObservableCollection<MindNode> Children
{
get
{
return _children;
}
set
{
SetProperty(ref _children, value);
}
}
public SizeBase SizeWithSpacing
{
get
{
return this.Size.Add(Spacing.Width * 2, Spacing.Height * 2);
}
}
public SizeBase DesiredSize
{
get; set;
}
public PointBase DesiredPosition
{
get; set;
}
public PointBase DesiredMiddlePosition
{
get
{
return new PointBase(this.DesiredPosition.X + ItemWidth / 2, this.DesiredPosition.Y + ItemHeight / 2);
}
}
public PointBase Offset
{
get; set;
}
private ConnectorOrientation _connectorOrientation = ConnectorOrientation.Left;
public ConnectorOrientation ConnectorOrientation
{
get
{
return _connectorOrientation;
}
set
{
SetProperty(ref _connectorOrientation, value);
}
}
public bool LayoutUpdating
{
get; set;
}
#endregion
#region
private LinkInfo _linkInfo;
[CanDo]
public LinkInfo LinkInfo
{
get
{
return _linkInfo;
}
set
{
SetProperty(ref _linkInfo, value);
}
}
private ImageInfo _imageInfo;
[CanDo]
public ImageInfo ImageInfo
{
get
{
return _imageInfo;
}
set
{
SetProperty(ref _imageInfo, value);
}
}
private string _remark;
[CanDo]
[Browsable(true)]
public string Remark
{
get
{
return _remark;
}
set
{
SetProperty(ref _remark, value);
}
}
private double? _priority;
[CanDo]
public double? Priority
{
get
{
return _priority;
}
set
{
SetProperty(ref _priority, value);
}
}
private double? _rate;
[CanDo]
public double? Rate
{
get
{
return _rate;
}
set
{
SetProperty(ref _rate, value);
}
}
private ObservableCollection<string> _tags;
[CanDo]
public ObservableCollection<string> Tags
{
get
{
return _tags;
}
set
{
if (_tags != null)
{
_tags.CollectionChanged -= _tags_CollectionChanged;
}
SetProperty(ref _tags, value);
if (_tags != null)
{
_tags.CollectionChanged += _tags_CollectionChanged;
}
}
}
private void _tags_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (var item in e.NewItems.OfType<string>())
{
var width = GetTextDisplayWidthHelper.GetTextDisplayWidth(item, new FontFamily(FontViewModel.FontFamily), FontViewModel.FontStyle, FontViewModel.FontWeight, FontViewModel.FontStretch, 12) + 6;
ItemWidth += width;
}
}
if (e.OldItems != null)
{
foreach (var item in e.OldItems.OfType<string>())
{
var width = GetTextDisplayWidthHelper.GetTextDisplayWidth(item, new FontFamily(FontViewModel.FontFamily), FontViewModel.FontStyle, FontViewModel.FontWeight, FontViewModel.FontStretch, 12) + 6;
ItemWidth -= width;
}
}
}
#endregion
#region
public ICommand AddParentCommand
{
get; private set;
}
public ICommand AddChildCommand
{
get; private set;
}
public ICommand AddPearCommand
{
get; private set;
}
public ICommand DeleteCommand
{
get; private set;
}
public ICommand MoveForwardCommand
{
get; private set;
}
public ICommand MoveBackCommand
{
get; private set;
}
public ICommand ExportCommand
{
get; private set;
}
public ICommand ImportCommand
{
get; private set;
}
#endregion
#region
private void BuildMenuOptions()
{
menuOptions = new ObservableCollection<CinchMenuItem>();
CinchMenuItem menuItem = new CinchMenuItem();
menuItem.Text = "下级";
menuItem.Command = AddChildCommand;
menuItem.CommandParameter = this;
menuOptions.Add(menuItem);
menuItem = new CinchMenuItem();
menuItem.Text = "同级";
menuItem.Command = AddPearCommand;
menuItem.CommandParameter = this;
menuOptions.Add(menuItem);
menuItem = new CinchMenuItem();
menuItem.Text = "上级";
menuItem.Command = AddParentCommand;
menuItem.CommandParameter = this;
menuOptions.Add(menuItem);
menuItem = new CinchMenuItem();
menuItem.Text = "前移";
menuItem.Command = MoveForwardCommand;
menuItem.CommandParameter = this;
menuOptions.Add(menuItem);
menuItem = new CinchMenuItem();
menuItem.Text = "后移";
menuItem.Command = MoveBackCommand;
menuItem.CommandParameter = this;
menuOptions.Add(menuItem);
menuItem = new CinchMenuItem();
menuItem.Text = "删除";
menuItem.Command = DeleteCommand;
menuItem.CommandParameter = this;
menuOptions.Add(menuItem);
menuItem = new CinchMenuItem();
menuItem.Text = "导出节点";
menuItem.Command = ExportCommand;
menuItem.CommandParameter = this;
menuOptions.Add(menuItem);
menuItem = new CinchMenuItem();
menuItem.Text = "导入节点";
menuItem.Command = ImportCommand;
menuItem.CommandParameter = this;
menuOptions.Add(menuItem);
}
#endregion
#region
public void AddTo(MindNode parent, int index = -1, bool isSelected = true)
{
//parent为空为根节点
if (index >= 0)
{
parent?.Children.Insert(index, this);
}
else
{
parent?.Children.Add(this);
}
this.Parent = parent;
this.ParentId = parent?.Id ?? Guid.Empty;
this.Offset = parent?.Offset ?? new PointBase();
this.InitLayout(true);//因为节点的层级不同的样式所以需要Parent确定后才能初始化
this.InitConnectionLayout();
Root?.Add(this);
if (isSelected)
{
if (parent != null)
{
parent.IsSelected = false;
}
this.IsSelected = true;
}
}
public void RemoveFrom()
{
this.IsLoaded = false;
if (this.ParentNode != null)
{
this.ParentNode.Children.Remove(this);
}
var connectors = Root?.Items.OfType<ConnectionViewModel>().Where(p => p.SinkConnectorInfoFully?.DataItem == this).ToList();
Root?.Remove(this);
Root?.Remove(connectors);
}
#endregion
#region
protected override void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (IsLoaded == false) return;
if (GetLevel0Node()?.LayoutUpdating == true) return;
Interlocked.Increment(ref Root.DoCommandManager.BeginDo);
switch (e.PropertyName)
{
case nameof(Left):
{
if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs)
{
UpdateOffsetX((double)valuePropertyChangedEventArgs.OldValue, (double)valuePropertyChangedEventArgs.NewValue);
Console.WriteLine((sender as MindNode).Text);
}
break;
}
case nameof(Top):
{
if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs)
{
UpdateOffsetY((double)valuePropertyChangedEventArgs.OldValue, (double)valuePropertyChangedEventArgs.NewValue);
}
break;
}
case nameof(IsExpanded):
case nameof(ItemWidth):
case nameof(ItemHeight):
{
UpdatedLayout();
break;
}
case nameof(NodeLevel):
MindLayout?.Appearance(this);
break;
case nameof(Text):
case nameof(Rate):
case nameof(Priority):
case nameof(Remark):
case nameof(LinkInfo):
case nameof(ImageInfo):
{
SetItemWidthHeight();
break;
}
case nameof(FontViewModel.FontSize):
SetItemWidthHeight();
break;
}
Interlocked.Decrement(ref Root.DoCommandManager.BeginDo);
}
#endregion
#region
public MindNode GetLevel0Node()
{
var node = this;
while (node.Parent is MindNode mindNode)
{
node = mindNode;
}
return node;
}
public MindNode GetLevel1Node()
{
var node = this;
while (node.Parent is MindNode mindNode)
{
if (node.NodeLevel == 1)
{
break;
}
node = mindNode;
}
return node;
}
public List<MindNode> GetParent()
{
var node = this;
List<MindNode> mindnode = new List<MindNode>();
while (node.ParentNode != null)
{
mindnode.Add(node.ParentNode);
node = node.ParentNode;
}
return mindnode;
}
public List<MindNode> GetChildren(bool self = false)
{
List<MindNode> mindnode = new List<MindNode>();
if (self)
{
mindnode.Add(this);
}
if (this.Children != null)
{
foreach (var child in this.Children)
{
mindnode.Add(child);
mindnode.AddRange(child.GetChildren());
}
}
return mindnode;
}
public string GetChildrenText(bool self = false)
{
StringBuilder sb = new StringBuilder();
List<MindNode> mindnode = new List<MindNode>();
if (self)
{
sb.AppendLine(this.Text);
}
if (this.Children != null)
{
foreach (var child in this.Children)
{
sb.AppendLine($"{new String('\t', child.NodeLevel)}{child.Text}");
sb.Append(child.GetChildrenText());
}
}
return sb.ToString();
}
protected void UpdateOffsetX(double oldvalue, double newvalue)
{
Offset += new VectorBase(newvalue - oldvalue, 0);
}
protected void UpdateOffsetY(double oldvalue, double newvalue)
{
Offset += new VectorBase(0, newvalue - oldvalue);
}
private void SetItemWidthHeight()
{
double width = 0;
double height = 0;
width += GetTextDisplayWidthHelper.GetTextDisplayWidth(Text, new FontFamily(FontViewModel.FontFamily), FontViewModel.FontStyle, FontViewModel.FontWeight, FontViewModel.FontStretch, FontViewModel.FontSize) + 30;
width += Rate == null ? 0 : 24;
width += Priority == null ? 0 : 24;
width += Remark == null ? 0 : 24;
width += LinkInfo == null ? 0 : 24;
var defaultTheme = MindThemeHelper.GetNodeDefaultTheme(this);
if (ImageInfo != null)
{
width = Math.Max(width, 160);
height = defaultTheme.ItemHeight / defaultTheme.FontSize * FontViewModel.FontSize + 135;
}
else
{
height = defaultTheme.ItemHeight / defaultTheme.FontSize * FontViewModel.FontSize;
}
ItemWidth = width;
ItemHeight = height;
}
public override void AddToSelection(bool selected)
{
foreach (SelectableDesignerItemViewModelBase item in Root.SelectedItems.ToList())
item.IsSelected = false;
Root.SelectedItems.Clear();
IsSelected = selected;
}
#endregion
}
public class LinkInfo
{
public string Url
{
get; set;
}
public string Text
{
get; set;
}
public LinkInfo()
{
}
public LinkInfo(string url, string text)
{
Url = url;
Text = text;
}
public LinkInfo(LinkInfo info)
{
Url = info?.Url;
Text = info?.Text;
}
}
public class ImageInfo
{
public string Url
{
get; set;
}
public string Text
{
get; set;
}
public ImageInfo()
{
}
public ImageInfo(string url, string text)
{
Url = url;
Text = text;
}
public ImageInfo(ImageInfo info)
{
Url = info?.Url;
Text = info?.Text;
}
}
}