using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using AIStudio.Wpf.DiagramDesigner.Geometrys; using AIStudio.Wpf.DiagramDesigner.Models; using static System.Net.Mime.MediaTypeNames; namespace AIStudio.Wpf.DiagramDesigner { public class BlockDesignerItemViewModel : DesignerItemViewModelBase { public BlockDesignerItemViewModel() { } public BlockDesignerItemViewModel(IDiagramViewModel root) : base(root) { } public BlockDesignerItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer) { } public BlockDesignerItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType) { } public override SelectableItemBase GetSerializableObject() { return new BlockDesignerItem(this); } protected override void InitNew() { ItemWidth = double.NaN; ItemHeight = double.NaN; AddConnector(new BlockConnectorInfo(this.Root, this, ConnectorOrientation.Top)); AddConnector(new BlockConnectorInfo(this.Root, this, ConnectorOrientation.Bottom)); } protected override void Init(IDiagramViewModel root, bool initNew) { base.Init(root, initNew); IsReadOnlyText = true; } protected override void LoadDesignerItemViewModel(SelectableItemBase designerbase) { base.LoadDesignerItemViewModel(designerbase); if (designerbase is BlockDesignerItem designer) { if (designer.Connectors != null) { ClearConnectors(); foreach (var connector in designer.Connectors) { BlockConnectorInfo fullyCreatedConnectorInfo = new BlockConnectorInfo(this.Root, this, connector); AddConnector(fullyCreatedConnectorInfo); } } if (designer.Containers != null) { ClearContainers(); foreach (var container in designer.Containers) { BlockItemsContainerInfo blockitemsContainerInfo = new BlockItemsContainerInfo(this.Root, this, container); AddContainer(blockitemsContainerInfo); } } } } public void AddNext(BlockDesignerItemViewModel next, bool first = true) { if (this.Next == next) { AlignNext(next); return; } if (next.Prev != null) { next.Prev.RemoveNext(); } var oldnext = RemoveNext(); next.Left = this.Left; next.Top = this.Top + this.GetItemHeight(); next.ParentId = this.Id; next.Prev = this; this.Next = next; if (next.Next != null) { next.AlignNext(next.Next); } if (oldnext != null && first == true) { //if (this.GetItemHeight() > 0) //{ // GetLast().AddNext(oldnext, false); //} //else { System.Windows.Application.Current?.Dispatcher.BeginInvoke(new Action(async () => { await Task.Delay(10); GetLast().AddNext(oldnext, false); })); } } } public void AlignNext(BlockDesignerItemViewModel next) { if (next != null && this.Next == next) { next.Left = this.Left; next.Top = this.Top + this.GetItemHeight(); if (next.Next != null) { next.AlignNext(next.Next); } } } public BlockDesignerItemViewModel RemoveNext() { var next = this.Next; if (next != null) { next.ParentId = new Guid(); next.Prev = null; this.Next = null; return next; } else { return null; } } public override void AddToSelection(bool selected, bool clearother) { if (clearother) { foreach (SelectableDesignerItemViewModelBase item in Root.SelectedItems.ToList()) { if (item != this) { item.RemoveFromSelection(); } } } IsSelected = selected; } public virtual void InsertChild(BlockDesignerItemViewModel child, BlockItemsContainerInfo container, int index) { if (container == null) { container = FirstContainer; } if (container.OnlyOneChild) { var oldchildren = container.Children.FirstOrDefault(); if (oldchildren != null) { this.RemoveChild(oldchildren, container); } Root.Items.Remove(child); if (child.Prev != null) { child.Prev.RemoveNext(); } if (child.Next != null) { child.RemoveNext(); } container.InsertChild(child, index); } else { var list = child.GetNexts(true); list.Reverse(); list.ForEach(p => { Root.Items.Remove(p); if (p.Prev != null) { p.Prev.RemoveNext(); } if (p.Next != null) { p.RemoveNext(); } container.InsertChild(p, index); }); } child.RemoveFromSelection(); this.GetRootContainItem.AddToSelection(true, true); //if (this.GetItemHeight() > 0) //{ // AlignNext(this.Next); //} //else { System.Windows.Application.Current?.Dispatcher.BeginInvoke(new Action(async () => { await Task.Delay(10); AlignNext(this.Next); })); } } public virtual void RemoveChild(BlockDesignerItemViewModel child, BlockItemsContainerInfo container) { if (container == null) { container = FirstContainer; } Root.Items.Add(child); container.RemoveChild(child); this.RemoveFromSelection(); child.AddToSelection(true, true); //if (this.GetItemHeight() > 0) //{ // AlignNext(this.Next); //} //else { System.Windows.Application.Current?.Dispatcher.BeginInvoke(new Action(async () => { await Task.Delay(10); AlignNext(this.Next); })); } } private bool _isExecuting; public bool IsExecuting { get { return _isExecuting; } set { SetProperty(ref _isExecuting, value); } } public string Flag { get; set; } public int BlockLevel { get { if (Prev == null) { return 0; } else { return Prev.BlockLevel + 1; } } } public BlockDesignerItemViewModel Prev { get { return Parent as BlockDesignerItemViewModel; } set { if (Parent != value) { Parent = value; } } } public BlockDesignerItemViewModel Next { get; set; } public BlockItemsContainerInfo ParentContainer { get; set; } public ObservableCollection Containers { get; set; } = new ObservableCollection(); public BlockItemsContainerInfo FirstContainer { get { return Containers?.FirstOrDefault(); } } public BlockItemsContainerInfo SecondContainer { get { return Containers?.Skip(1)?.FirstOrDefault(); } } public BlockItemsContainerInfo ThirdContainer { get { return Containers?.Skip(2)?.FirstOrDefault(); } } public BlockDesignerItemViewModel GetFirst() { var parent = this.Prev; while (parent?.Prev != null) { parent = parent.Prev; } return parent; } public BlockDesignerItemViewModel GetLast() { var next = this; while (next.Next != null) { next = next.Next; } return next; } public List GetNexts(bool self) { List blockDesignerItemViewModels = new List(); if (self) { blockDesignerItemViewModels.Add(this); } var next = this; while (next != null) { next = next.Next; if (next != null) { blockDesignerItemViewModels.Add(next); } } return blockDesignerItemViewModels; } public void AddContainer(BlockItemsContainerInfo container) { Containers.Add(container); RaisePropertyChanged(nameof(FirstContainer)); RaisePropertyChanged(nameof(SecondContainer)); RaisePropertyChanged(nameof(ThirdContainer)); } public void RemoveContainer(BlockItemsContainerInfo container) { Containers.Remove(container); RaisePropertyChanged(nameof(FirstContainer)); RaisePropertyChanged(nameof(SecondContainer)); RaisePropertyChanged(nameof(ThirdContainer)); } public void ClearContainers() { Containers.Clear(); RaisePropertyChanged(nameof(FirstContainer)); RaisePropertyChanged(nameof(SecondContainer)); RaisePropertyChanged(nameof(ThirdContainer)); } public List GetAllContainers() { return Containers.SelectMany(p => p.GetAllContainers(p.Children, true)).ToList(); } public BlockDesignerItemViewModel GetRootContainItem { get { if (ParentContainer == null) { return this; } else { return ParentContainer.DataItem.GetRootContainItem; } } } #region 执行 protected override async void ExecuteEditCommand(object param) { await (this.GetFirst() ?? this).Execute(); } public override async void PreviewExecuteEdit() { var items = (this.GetFirst() ?? this).GetNexts(true); items.ForEach(p => p.IsExecuting = true); } public override async void ExitPreviewExecuteEdit() { var items = (this.GetFirst() ?? this).GetNexts(true); items.ForEach(p => p.IsExecuting = false); } public async Task Execute() { await BeforeExecute(); await Executing(); await AfterExecute(); } public virtual Task BeforeExecute() { IsExecuting = true; return Task.CompletedTask; } public virtual Task Executing() { return Task.CompletedTask; } public virtual async Task AfterExecute() { if (IsExecuting) { IsExecuting = false; if (Next != null) await Next.Execute(); } } public virtual object GetResult() { if (FirstContainer != null) { return FirstContainer.GetResult(); } else if (SecondContainer != null) { return SecondContainer.GetResult(); } else if (ThirdContainer != null) { return ThirdContainer.GetResult(); } return null; } #endregion } #region 扩展 public class BlockContainDesignerItemViewModel : BlockDesignerItemViewModel { public BlockContainDesignerItemViewModel() { } public BlockContainDesignerItemViewModel(IDiagramViewModel root) : base(root) { } public BlockContainDesignerItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer) { } public BlockContainDesignerItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType) { } protected override void InitNew() { base.InitNew(); Containers.Add(new BlockItemsContainerInfo(this.Root, this, true, null)); } } public class BlockContainListDesignerItemViewModel : BlockDesignerItemViewModel { public BlockContainListDesignerItemViewModel() { } public BlockContainListDesignerItemViewModel(IDiagramViewModel root) : base(root) { } public BlockContainListDesignerItemViewModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer) { } public BlockContainListDesignerItemViewModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType) { } protected override void InitNew() { base.InitNew(); Containers.Add(new BlockItemsContainerInfo(this.Root, this, false, null)); } } #endregion #region 帮助 public class BlockDesignerItemTempLink { public List Items { get; set; } = new List(); public RectangleBase GetBounds() { return Items.FirstOrDefault().GetBounds(); } public List Connectors { get { List connectors = new List(); if (Items.FirstOrDefault().TopConnector != null) { connectors.Add(Items.FirstOrDefault().TopConnector); } if (Items.FirstOrDefault().LeftConnector != null) { connectors.Add(Items.FirstOrDefault().LeftConnector); } if (Items.LastOrDefault().BottomConnector != null) { connectors.Add(Items.LastOrDefault().BottomConnector); } if (Items.LastOrDefault().RightConnector != null) { connectors.Add(Items.LastOrDefault().RightConnector); } return connectors; } } public static List Build(List blocks) { List links = new List(); foreach (var block in blocks.OrderBy(p => p.BlockLevel).ToList()) { bool success = false; foreach (var link in links) { if (link.Items.LastOrDefault() == block.Prev) { link.Items.Add(block); success = true; } } if (success == false) { BlockDesignerItemTempLink link = new BlockDesignerItemTempLink(); link.Items.Add(block); links.Add(link); } } return links; } } #endregion }