Files
aistudio-wpf-diagram/AIStudio.Wpf.Mind/ViewModels/MindDiagramViewModel.cs
艾竹 b36bd4b228 XX
2023-03-25 11:59:31 +08:00

1020 lines
31 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner;
using AIStudio.Wpf.Mind.Helpers;
namespace AIStudio.Wpf.Mind.ViewModels
{
public class MindDiagramViewModel : DiagramViewModel, IMindDiagramViewModel
{
#region
private MindType _mindType = Mind.MindType.Mind;
public MindType MindType
{
get
{
return _mindType;
}
set
{
if (SetProperty(ref _mindType, value))
{
ExecutedChangeMindTypeCommand(value);
}
}
}
private MindThemeModel _mindThemeModel = MindThemeHelper.GetTheme("天空蓝");
public MindThemeModel MindThemeModel
{
get
{
return _mindThemeModel;
}
set
{
SetProperty(ref _mindThemeModel, value);
}
}
public List<MindNode> RootItems
{
get
{
return Items.OfType<MindNode>().Where(p => p.NodeLevel == 0).ToList();
}
}
public MindNode MindSelectedItem
{
get
{
return SelectedItem as MindNode;
}
}
#endregion
#region
private ICommand _addRootCommand;
public ICommand AddRootCommand
{
get
{
return this._addRootCommand ?? (this._addRootCommand = new SimpleCommand(ExecuteEnable, this.ExecuteAddRootCommand));
}
}
private ICommand _addParentCommand;
public ICommand AddParentCommand
{
get
{
return this._addParentCommand ?? (this._addParentCommand = new SimpleCommand(MindLevelEnable, this.ExecuteAddParentCommand));
}
}
private ICommand _addChildCommand;
public ICommand AddChildCommand
{
get
{
return this._addChildCommand ?? (this._addChildCommand = new SimpleCommand(MindExecuteEnable, this.ExecuteAddChildCommand));
}
}
private ICommand _AddPearCommand;
public ICommand AddPearCommand
{
get
{
return this._AddPearCommand ?? (this._AddPearCommand = new SimpleCommand(MindLevelEnable, this.ExecuteAddPearCommand));
}
}
private ICommand _moveForwardCommand;
public ICommand MoveForwardCommand
{
get
{
return this._moveForwardCommand ?? (this._moveForwardCommand = new SimpleCommand(MindExecuteEnable, ExecuteMoveForwardCommand));
}
}
private ICommand _moveBackCommand;
public ICommand MoveBackCommand
{
get
{
return this._moveBackCommand ?? (this._moveBackCommand = new SimpleCommand(MindExecuteEnable, ExecuteMoveBackCommand));
}
}
private ICommand _deleteCommand;
public override ICommand DeleteCommand
{
get
{
return this._deleteCommand ?? (this._deleteCommand = new SimpleCommand(MindLevelEnable, ExecuteDeleteCommand));
}
}
private ICommand _selectBrotherCommand;
public ICommand SelectBrotherCommand
{
get
{
return this._selectBrotherCommand ?? (this._selectBrotherCommand = new SimpleCommand(MindLevelEnable, ExecuteSelectBrotherCommand));
}
}
private ICommand _selectPearCommand;
public ICommand SelectPearCommand
{
get
{
return this._selectPearCommand ?? (this._selectPearCommand = new SimpleCommand(MindLevelEnable, ExecuteSelectPearCommand));
}
}
private ICommand _selectRouteCommand;
public ICommand SelectRouteCommand
{
get
{
return this._selectRouteCommand ?? (this._selectRouteCommand = new SimpleCommand(MindLevelEnable, ExecuteSelectRouteCommand));
}
}
private ICommand _selectChildCommand;
public ICommand SelectChildCommand
{
get
{
return this._selectChildCommand ?? (this._selectChildCommand = new SimpleCommand(MindLevelEnable, ExecuteSelectChildCommand));
}
}
private ICommand _addLinkCommand;
public ICommand AddLinkCommand
{
get
{
return this._addLinkCommand ?? (this._addLinkCommand = new SimpleCommand(MindExecuteEnable, ExecuteAddLinkCommand));
}
}
private ICommand _removeLinkCommand;
public ICommand RemoveLinkCommand
{
get
{
return this._removeLinkCommand ?? (this._removeLinkCommand = new SimpleCommand(MindExecuteEnable, ExecuteRemoveLinkCommand));
}
}
private ICommand _addImageCommand;
public ICommand AddImageCommand
{
get
{
return this._addImageCommand ?? (this._addImageCommand = new SimpleCommand(MindExecuteEnable, ExecuteAddImageCommand));
}
}
private ICommand _removeImageCommand;
public ICommand RemoveImageCommand
{
get
{
return this._removeImageCommand ?? (this._removeImageCommand = new SimpleCommand(MindExecuteEnable, ExecuteRemoveImageCommand));
}
}
private ICommand _addRemarkCommand;
public ICommand AddRemarkCommand
{
get
{
return this._addRemarkCommand ?? (this._addRemarkCommand = new SimpleCommand(MindExecuteEnable, ExecuteAddRemarkCommand));
}
}
private ICommand _removeRemarkCommand;
public ICommand RemoveRemarkCommand
{
get
{
return this._removeRemarkCommand ?? (this._removeRemarkCommand = new SimpleCommand(MindExecuteEnable, ExecuteRemoveRemarkCommand));
}
}
private ICommand _addPriorityCommand;
public ICommand AddPriorityCommand
{
get
{
return this._addPriorityCommand ?? (this._addPriorityCommand = new SimpleCommand(MindExecuteEnable, ExecuteAddPriorityCommand));
}
}
private ICommand _addRatioCommand;
public ICommand AddRatioCommand
{
get
{
return this._addRatioCommand ?? (this._addRatioCommand = new SimpleCommand(MindExecuteEnable, ExecuteAddRatioCommand));
}
}
private ICommand _addTagCommand;
public ICommand AddTagCommand
{
get
{
return this._addTagCommand ?? (this._addTagCommand = new SimpleCommand(MindExecuteEnable, ExecuteAddTagCommand));
}
}
private ICommand _removeTagCommand;
public ICommand RemoveTagCommand
{
get
{
return this._removeTagCommand ?? (this._removeTagCommand = new SimpleCommand(MindExecuteEnable, ExecuteRemoveTagCommand));
}
}
private ICommand _changeMindTypeCommand;
public ICommand ChangeMindTypeCommand
{
get
{
return this._changeMindTypeCommand ?? (this._changeMindTypeCommand = new SimpleCommand(ExecuteEnable, this.ExecutedChangeMindTypeCommand));
}
}
private ICommand _changeMindThemeCommand;
public ICommand ChangeMindThemeCommand
{
get
{
return this._changeMindThemeCommand ?? (this._changeMindThemeCommand = new SimpleCommand(ExecuteEnable, this.ExecutedChangeMindThemeCommand));
}
}
private ICommand _clearThemeCommand;
public ICommand ClearThemeCommand
{
get
{
return this._clearThemeCommand ?? (this._clearThemeCommand = new SimpleCommand(ExecuteEnable, this.ExecutedClearThemeCommand));
}
}
private ICommand _copyThemeCommand;
public ICommand CopyThemeCommand
{
get
{
return this._copyThemeCommand ?? (this._copyThemeCommand = new SimpleCommand(ExecuteEnable, this.ExecutedCopyThemeCommand));
}
}
private ICommand _pasteThemeCommand;
public ICommand PasteThemeCommand
{
get
{
return this._pasteThemeCommand ?? (this._pasteThemeCommand = new SimpleCommand(ExecuteEnable, this.ExecutedPasteThemeCommand));
}
}
private ICommand _expand2LevelCommand;
public ICommand Expand2LevelCommand
{
get
{
return this._expand2LevelCommand ?? (this._expand2LevelCommand = new SimpleCommand(ExecuteEnable, this.ExecutedExpand2LevelCommand));
}
}
#endregion
#region ctor和初始化
public MindDiagramViewModel()
{
}
public override void Init()
{
if (Items.Count == 0)
{
InitRootItem();
}
ResetChildren(RootItems);
RootItems?.ForEach(p => p.LayoutUpdated());
base.Init();
}
public void InitRootItem()
{
ClearSelectedItemsCommand.Execute(null);
MindNode level1node = new MindNode(this) { Root = this, Id = Guid.NewGuid(), Text = "思维导图" };
level1node.InitLayout(true);
Items.Add(level1node);
level1node.IsSelected = true;
CenterMoveCommand.Execute(level1node);
}
protected override void ExecutedResetLayoutCommand(object obj)
{
foreach (var item in Items.OfType<MindNode>())
{
item.Offset = new DiagramDesigner.Geometrys.PointBase();
}
RootItems?.ForEach(p => p.LayoutUpdated());
}
private void ResetChildren(IEnumerable<MindNode> parents)
{
if (parents == null)
return;
foreach (var parent in parents)
{
parent.Children = new System.Collections.ObjectModel.ObservableCollection<MindNode>(Items.OfType<MindNode>().Where(p => p.ParentId == parent.Id));
foreach (var item in Items.OfType<MindNode>().Where(p => p.ParentId == parent.Id).ToList())
{
item.Parent = parent;
item.InitLayout(false);
item.InitConnectLayout();
}
ResetChildren(parent.Children);
}
}
private List<MindNode> GetParent(MindNode node)
{
List<MindNode> mindnode = new List<MindNode>();
while (node.ParentNode != null)
{
mindnode.Add(node.ParentNode);
node = node.ParentNode;
}
return mindnode;
}
private List<MindNode> GetChildren(MindNode parent)
{
List<MindNode> mindnode = new List<MindNode>();
if (parent.Children != null)
{
foreach (var child in parent.Children)
{
mindnode.Add(child);
mindnode.AddRange(GetChildren(child));
}
}
return mindnode;
}
#endregion
#region 使
public bool MindExecuteEnable(object para)
{
if (ExecuteEnable(para) == false) return false;
if (SelectedItem is MindNode) return true;
return false;
}
private bool MindLevelEnable(object obj)
{
if (MindExecuteEnable(obj) == false) return false;
return (SelectedItem as MindNode).NodeLevel != 0;
}
#endregion
#region ,
public void ExecuteAddRootCommand(object parameter)
{
InitRootItem();
}
public void ExecuteAddChildCommand(object parameter)
{
List<MindNode> items = new List<MindNode>();
if (parameter is MindNode parent)
{
}
else if (parameter is IEnumerable<MindNode> para)
{
parent = para.FirstOrDefault();//第一个固定为父节点
items = para.Skip(1).ToList();
}
else
{
parent = SelectedItem as MindNode;
}
if (items?.Count == 0)
{
var node = new MindNode(this) { Text = $"分支主题{parent.Children.Count + 1}"};
items.Add(node);
}
DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var item in items)
{
parent.AddChild(item);
}
parent.LayoutUpdated();
},
() => {
foreach (var item in items)
{
parent.RemoveChild(item);
}
parent.LayoutUpdated();
});
}
public void ExecuteAddParentCommand(object parameter)
{
List<MindNode> items = new List<MindNode>();
if (parameter is MindNode node)
{
}
else if (parameter is IEnumerable<MindNode> para)
{
node = para.FirstOrDefault();//第一个固定为父节点
items = para.Skip(1).ToList();
}
else
{
node = SelectedItem as MindNode;
}
if (node.Parent is MindNode parent)
{
if (items?.Count == 0)
{
items.Add(new MindNode(this) { Text = $"分支主题{parent.Children.Count + 1}" });
}
DoCommandManager.DoNewCommand(this.ToString(),
() => {
int index = parent.Children.IndexOf(node);
parent.AddChild(items[0], index + 1);
parent.RemoveChild(node);
items[0].AddChild(node);
parent.LayoutUpdated();
},
() => {
int index = parent.Children.IndexOf(items[0]);
items[0].RemoveChild(node);
parent.AddChild(node, index + 1);
parent.LayoutUpdated();
});
}
}
public void ExecuteAddPearCommand(object parameter)
{
List<MindNode> items = new List<MindNode>();
if (parameter is MindNode pear)
{
}
else if (parameter is IEnumerable<MindNode> para)
{
pear = para.FirstOrDefault();//第一个固定为同级节点
items = para.Skip(1).ToList();
}
else
{
pear = SelectedItem as MindNode;
}
if (pear.Parent is MindNode parent)
{
if (items?.Count == 0)
{
var node = new MindNode(this) { Text = $"分支主题{parent.Children.Count + 1}" };
items.Add(node);
}
DoCommandManager.DoNewCommand(this.ToString(),
() => {
int index = parent.Children.IndexOf(pear);
for (int i = 0; i < items.Count; i++)
{
parent.AddChild(items[i], index + i + 1);
}
parent.LayoutUpdated();
},
() => {
for (int i = 0; i < items.Count; i++)
{
parent.RemoveChild(items[i]);
}
parent.LayoutUpdated();
});
}
}
private void ExecuteMoveBackCommand(object parameter)
{
if (parameter is MindNode node)
{
}
else
{
node = SelectedItem as MindNode;
}
if (node.Parent is MindNode parent)
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
int index = parent.Children.IndexOf(node);
if (index < parent.Children.Count - 1)
{
parent.RemoveChild(node);
parent.AddChild(node, index + 1);
parent.LayoutUpdated();
}
},
() => {
int index = parent.Children.IndexOf(node);
if (index > 0)
{
parent.RemoveChild(node);
parent.AddChild(node, index - 1);
parent.LayoutUpdated();
}
});
}
}
private void ExecuteMoveForwardCommand(object parameter)
{
if (parameter is MindNode node)
{
}
else
{
node = SelectedItem as MindNode;
}
if (node.Parent is MindNode parent)
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
int index = parent.Children.IndexOf(node);
if (index > 0)
{
parent.RemoveChild(node);
parent.AddChild(node, index - 1);
parent.LayoutUpdated();
}
},
() => {
int index = parent.Children.IndexOf(node);
if (index < parent.Children.Count - 1)
{
parent.RemoveChild(node);
parent.AddChild(node, index + 1);
parent.LayoutUpdated();
}
});
}
}
protected override bool Delete(object parameter)
{
List<MindNode> nodes = new List<MindNode>();
if (parameter is MindNode node1)
{
nodes.Add(node1);
}
else if (parameter is IEnumerable<MindNode> para)
{
nodes.AddRange(para);
}
else
{
nodes.AddRange(SelectedItems.OfType<MindNode>());
}
if (nodes.FirstOrDefault()?.IsEditing != false)
{
return false;
}
if (nodes.Any())
{
Dictionary<MindNode, int> indexs = nodes.ToDictionary(p => p, p => p.ParentNode != null ? p.ParentNode.Children.IndexOf(p) : 0);
DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var node in nodes)
{
if (node.NodeLevel == 0)
{
DirectRemoveItemCommand.Execute(node);
}
else
{
node.ParentNode?.RemoveChild(node, true);
}
}
RootItems.ForEach(p => p.LayoutUpdated());
},
() => {
foreach (var node in nodes)
{
node.ParentNode.AddChild(node, indexs[node]);
}
RootItems.ForEach(p => p.LayoutUpdated());
});
return true;
}
else
return false;
}
#endregion
#region ,
protected override void FixOtherInfo(List<SelectableDesignerItemViewModelBase> items)
{
List<MindNode> parents = new List<MindNode>();
foreach (var item in items.OfType<MindNode>())
{
var parent = Items.OfType<MindNode>().FirstOrDefault(p => p.Id == item.ParentId);
if (parent != null && !items.Contains(parent))
{
parents.Add(parent);
}
else if (item.ParentId == Guid.Empty)
{
parents.Add(item);
item.InitLayout(false);
}
}
ResetChildren(parents);
parents.ForEach(p => p.LayoutUpdated());
}
#endregion
#region
private void ExecuteAddLinkCommand(object obj)
{
if (obj is object[] array && array.Length == 2)
{
SelectedItems.OfType<MindNode>().ToList().ForEach(p => {
if (p.LinkInfo == null)
p.LinkInfo = new LinkInfo();
p.LinkInfo.Link = array[0]?.ToString();
p.LinkInfo.Text = array[1]?.ToString();
});
}
}
private void ExecuteRemoveLinkCommand(object obj)
{
SelectedItems.OfType<MindNode>().ToList().ForEach(p => {
if (p.LinkInfo != null)
{
p.LinkInfo.Link = null;
p.LinkInfo.Text = null;
}
});
}
private void ExecuteAddImageCommand(object obj)
{
if (obj is object[] array && array.Length == 2)
{
SelectedItems.OfType<MindNode>().ToList().ForEach(p => {
if (p.ImageInfo == null)
p.ImageInfo = new ImageInfo();
p.ImageInfo.Url = array[0]?.ToString();
p.ImageInfo.Text = array[1]?.ToString();
});
}
}
private void ExecuteRemoveImageCommand(object obj)
{
SelectedItems.OfType<MindNode>().ToList().ForEach(p => {
if (p.ImageInfo != null)
{
p.ImageInfo.Url = null;
p.ImageInfo.Text = null;
}
});
}
private void ExecuteAddRemarkCommand(object obj)
{
SelectedItems.OfType<MindNode>().ToList().ForEach(p => p.Remark = obj?.ToString());
}
private void ExecuteRemoveRemarkCommand(object obj)
{
SelectedItems.OfType<MindNode>().ToList().ForEach(p => p.Remark = null);
}
private void ExecuteAddPriorityCommand(object obj)
{
if (double.TryParse(obj.ToString(), out var priority))
{
SelectedItems.OfType<MindNode>().ToList().ForEach(p => p.Priority = priority);
}
else
{
SelectedItems.OfType<MindNode>().ToList().ForEach(p => p.Priority = null);
}
}
private void ExecuteAddRatioCommand(object obj)
{
if (double.TryParse(obj.ToString(), out var rate))
{
SelectedItems.OfType<MindNode>().ToList().ForEach(p => p.Rate = rate);
}
else
{
SelectedItems.OfType<MindNode>().ToList().ForEach(p => p.Rate = null);
}
}
private void ExecuteAddTagCommand(object obj)
{
SelectedItems.OfType<MindNode>().ToList().ForEach(p => {
p.Tags.Add(obj?.ToString());
});
}
private void ExecuteRemoveTagCommand(object obj)
{
SelectedItems.OfType<MindNode>().ToList().ForEach(p => {
p.Tags.Remove(obj?.ToString());
});
}
#endregion
#region
private void ExecutedChangeMindTypeCommand(object obj)
{
if (obj is MindType mindType)
{
Items.OfType<MindNode>().ToList().ForEach(item => { item.InitLayout(true); });
Items.OfType<MindNode>().ToList().ForEach(item => { item.InitConnectLayout(); });
RootItems?.ForEach(p => p.LayoutUpdated());
}
}
private void ExecutedChangeMindThemeCommand(object obj)
{
if (obj is string mindThemeModel)
{
MindThemeModel = MindThemeHelper.GetTheme(mindThemeModel);
if (mindThemeModel.StartsWith("CoolLightYellow"))
{
PageBackground = Colors.Black;
}
else
{
PageBackground = Colors.White;
}
Items.OfType<MindNode>().ToList().ForEach(item => { item.ThemeChange(); });
}
}
private void ExecutedClearThemeCommand(object parameter)
{
List<MindNode> nodes = new List<MindNode>();
if (parameter is MindNode node1)
{
nodes.Add(node1);
}
else if (parameter is IEnumerable<MindNode> para)
{
nodes.AddRange(para);
}
else
{
nodes.AddRange(SelectedItems.OfType<MindNode>());
}
if (nodes.Any())
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var node in nodes)
{
node.ThemeChange();
}
},
() => {
//ToDo
});
}
}
private MindNode _formatNode;
private void ExecutedCopyThemeCommand(object parameter)
{
if (parameter is MindNode node)
{
}
else
{
node = SelectedItem as MindNode;
}
if (node != null)
{
_formatNode = node;
}
}
private void ExecutedPasteThemeCommand(object parameter)
{
if (_formatNode != null)
{
List<MindNode> nodes = new List<MindNode>();
if (parameter is MindNode node1)
{
nodes.Add(node1);
}
else if (parameter is IEnumerable<MindNode> para)
{
nodes.AddRange(para);
}
else
{
nodes.AddRange(SelectedItems.OfType<MindNode>());
}
if (nodes.Any())
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var node in nodes)
{
CopyHelper.CopyPropertyValue(_formatNode.ColorViewModel, node.ColorViewModel);
CopyHelper.CopyPropertyValue(_formatNode.FontViewModel, node.FontViewModel);
}
},
() => {
//ToDo
});
}
}
}
#endregion
#region
protected override void ExecuteCenterMoveCommand(object parameter)
{
var rootitem = MindSelectedItem?.RootNode;
if (rootitem != null)
{
rootitem.Left = (PageSize.Width - rootitem.ItemWidth) / 2;
rootitem.Top = (PageSize.Height - rootitem.ItemHeight) / 2;
rootitem?.LayoutUpdated();
FitViewModel = new FitViewModel() { BoundingRect = rootitem.GetBounds() };
}
}
private void ExecutedExpand2LevelCommand(object obj)
{
int level = 0;
int.TryParse(obj?.ToString(), out level);
foreach (var item in Items.OfType<MindNode>())
{
if (item.NodeLevel == 0)
{
continue;
}
else if (item.NodeLevel < level)
{
item.IsExpanded = true;
}
else
{
item.IsExpanded = false;
}
}
}
protected void ExecuteSelectBrotherCommand(object parameter)
{
if (parameter is MindNode node)
{
}
else
{
node = SelectedItem as MindNode;
}
if (node != null && node.ParentNode != null)
{
foreach (var child in node.ParentNode.Children)
{
child.IsSelected = true;
}
}
}
protected void ExecuteSelectPearCommand(object parameter)
{
if (parameter is MindNode node)
{
}
else
{
node = SelectedItem as MindNode;
}
if (node != null)
{
foreach (var item in Items.OfType<MindNode>().Where(p => p.NodeLevel == node.NodeLevel))
{
item.IsSelected = true;
}
}
}
protected void ExecuteSelectRouteCommand(object parameter)
{
if (parameter is MindNode node)
{
}
else
{
node = SelectedItem as MindNode;
}
if (node != null)
{
GetParent(node).ForEach(p => p.IsSelected = true);
}
}
protected void ExecuteSelectChildCommand(object parameter)
{
if (parameter is MindNode node)
{
}
else
{
node = SelectedItem as MindNode;
}
if (node != null)
{
GetChildren(node).ForEach(p => p.IsSelected = true);
}
}
#endregion
}
}