From 8ad42aec49630cf4be41f393f4c3d578533a29fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=89=BE=E7=AB=B9?= Date: Sat, 8 Apr 2023 21:48:43 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=86=E7=BB=84=EF=BC=8C=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E5=88=86=E7=BB=84=20ReDo=20UnDo=20=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml | 8 +- .../Controls/DesignerCanvas.cs | 4 +- .../Controls/DragThumb.cs | 9 +- .../Controls/ResizeThumb.cs | 5 +- .../Controls/RotateThumb.cs | 5 +- .../Helpers/DoCommandManager.cs | 16 +--- .../UserControls/TextControl.xaml | 4 +- .../UserControls/TextControl.xaml.cs | 4 + .../BaseViewModel/ConnectionViewModel.cs | 15 +++- .../Connector/ConnectorLabelModel.cs | 4 +- .../Connector/ConnectorVertexModel.cs | 2 +- .../ViewModels/BaseViewModel/DiagramOption.cs | 8 +- .../BaseViewModel/DiagramViewModel.cs | 88 +++++++++++++------ .../BaseViewModel/SelectableViewModelBase.cs | 2 +- AIStudio.Wpf.Mind/ViewModels/MindNode.cs | 11 +++ 15 files changed, 123 insertions(+), 62 deletions(-) diff --git a/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml b/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml index e196eb0..4ebda94 100644 --- a/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml +++ b/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml @@ -991,13 +991,13 @@ - - + + - + - + diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs b/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs index 2b281ae..319c723 100644 --- a/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs +++ b/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs @@ -540,7 +540,7 @@ namespace AIStudio.Wpf.DiagramDesigner DragObject dragObject = e.Data.GetData(typeof(DragObject)) as DragObject; if (dragObject != null) { - _viewModel.ClearSelectedItemsCommand.Execute(null); + _viewModel.ClearSelectedItems(); Point position = e.GetPosition(this); if (dragObject.DesignerItem is SerializableObject serializableObject) { @@ -587,7 +587,7 @@ namespace AIStudio.Wpf.DiagramDesigner { foreach (var file in files) { - _viewModel.ClearSelectedItemsCommand.Execute(null); + _viewModel.ClearSelectedItems(); Point position = e.GetPosition(this); ImageItemViewModel itemBase = new ImageItemViewModel(); itemBase.Icon = file; diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs b/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs index 51b6deb..5b27208 100644 --- a/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs +++ b/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Windows; using System.Windows.Controls.Primitives; using System.Windows.Media; @@ -59,7 +60,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls designerItems = designerItems.Distinct().ToList(); - DiagramViewModel.DoCommandManager.BeginDo = true; + Interlocked.Increment(ref DiagramViewModel.DoCommandManager.BeginDo); foreach (DesignerItemViewModelBase item in designerItems.OfType()) { item.SetOldValue(item.TopLeft, nameof(item.TopLeft)); @@ -76,8 +77,8 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls private void DragThumb_DragCompleted(object sender, DragCompletedEventArgs e) { if (drag == false) - { - DiagramViewModel.DoCommandManager.BeginDo = false; + { + Interlocked.Decrement(ref DiagramViewModel.DoCommandManager.BeginDo); return; } @@ -91,7 +92,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls Dictionary> infos = designerItems.OfType().ToDictionary(p => p, p => new Tuple(p.GetOldValue(nameof(p.TopLeft)), p.TopLeft)); - DiagramViewModel.DoCommandManager.BeginDo = false; + Interlocked.Decrement(ref DiagramViewModel.DoCommandManager.BeginDo); DiagramViewModel.DoCommandManager.DoNewCommand(this.ToString(), () => { foreach (var info in infos) diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/ResizeThumb.cs b/AIStudio.Wpf.DiagramDesigner/Controls/ResizeThumb.cs index d187a11..dcae788 100644 --- a/AIStudio.Wpf.DiagramDesigner/Controls/ResizeThumb.cs +++ b/AIStudio.Wpf.DiagramDesigner/Controls/ResizeThumb.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; @@ -35,7 +36,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls { designerItems = designerItem.Root.SelectedItems.ToList(); - DiagramViewModel.DoCommandManager.BeginDo = true; + Interlocked.Increment(ref DiagramViewModel.DoCommandManager.BeginDo); foreach (DesignerItemViewModelBase item in designerItems.OfType()) { item.SetOldValue(item.Size, nameof(item.Size)); @@ -57,7 +58,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls designerItems.OfType().ToDictionary(p => p, p => new Tuple(p.GetOldValue(nameof(p.Size)), p.Size)); - DiagramViewModel.DoCommandManager.BeginDo = false; + Interlocked.Decrement(ref DiagramViewModel.DoCommandManager.BeginDo); DiagramViewModel.DoCommandManager.DoNewCommand(this.ToString(), () => { foreach (var info in infos) diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/RotateThumb.cs b/AIStudio.Wpf.DiagramDesigner/Controls/RotateThumb.cs index 3af9cf6..80ac038 100644 --- a/AIStudio.Wpf.DiagramDesigner/Controls/RotateThumb.cs +++ b/AIStudio.Wpf.DiagramDesigner/Controls/RotateThumb.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; @@ -42,7 +43,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls { designerItems = designerItem.Root.SelectedItems.ToList(); - DiagramViewModel.DoCommandManager.BeginDo = true; + Interlocked.Increment(ref DiagramViewModel.DoCommandManager.BeginDo); foreach (DesignerItemViewModelBase item in designerItems.OfType()) { item.SetOldValue(this.designerItem.Angle, nameof(this.designerItem.Angle)); @@ -78,7 +79,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls Dictionary> infos = designerItems.OfType().ToDictionary(p => p, p => new Tuple(p.GetOldValue(nameof(p.Angle)), p.Angle)); - DiagramViewModel.DoCommandManager.BeginDo = false; + Interlocked.Decrement(ref DiagramViewModel.DoCommandManager.BeginDo); DiagramViewModel.DoCommandManager.DoNewCommand(this.ToString(), () => { foreach (var info in infos) diff --git a/AIStudio.Wpf.DiagramDesigner/Helpers/DoCommandManager.cs b/AIStudio.Wpf.DiagramDesigner/Helpers/DoCommandManager.cs index 12c68f8..14f231d 100644 --- a/AIStudio.Wpf.DiagramDesigner/Helpers/DoCommandManager.cs +++ b/AIStudio.Wpf.DiagramDesigner/Helpers/DoCommandManager.cs @@ -66,23 +66,13 @@ namespace AIStudio.Wpf.DiagramDesigner UnDoActionStack = new Stack(); } - private bool _beginDo; - public bool BeginDo - { - get - { - return _beginDo; - } - set - { - _beginDo = value; - } - } + public int BeginDo; + private bool _undoing; public void DoNewCommand(string name, Action action, Action unDoAction, Action clearAction = null, bool doit = true) { - if (BeginDo == true) + if (BeginDo > 0) return; if (_undoing == true) return; diff --git a/AIStudio.Wpf.DiagramDesigner/UserControls/TextControl.xaml b/AIStudio.Wpf.DiagramDesigner/UserControls/TextControl.xaml index 2fc44b0..cb561ab 100644 --- a/AIStudio.Wpf.DiagramDesigner/UserControls/TextControl.xaml +++ b/AIStudio.Wpf.DiagramDesigner/UserControls/TextControl.xaml @@ -19,7 +19,7 @@ e.KeyboardDevice.Modifiers == ModifierKeys.None && e.Key == Key.Down; - [Description("Group Keyboard shortcut (CTRL+Shift+G by default)")] + [Description("Group Keyboard shortcut (CTRL+G by default)")] public Func Group { get; set; } = e => e.KeyboardDevice.Modifiers == ModifierKeys.Control && e.Key == Key.G; + [Description("Ungroup Keyboard shortcut (Shift+G by default)")] + public Func Ungroup + { + get; set; + } = e => e.KeyboardDevice.Modifiers == ModifierKeys.Shift | e.Key == Key.G; + } } diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs index c676784..f5ec615 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs @@ -5,6 +5,7 @@ using System.ComponentModel; using System.Linq; using System.Reactive.Linq; using System.Windows; +using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using AIStudio.Wpf.DiagramDesigner.Geometrys; @@ -1195,7 +1196,15 @@ namespace AIStudio.Wpf.DiagramDesigner if (attr != null && attr.Length != 0) { //加入ReDo - DoCommandManager.DoNewCommand(sender.ToString() + e.PropertyName, () => Do(sender, e.PropertyName, valuePropertyChangedEventArgs.NewValue), () => UnDo(sender, e.PropertyName, valuePropertyChangedEventArgs.OldValue), null, false); + DoCommandManager.DoNewCommand(sender.ToString() + e.PropertyName, + () => { + Do(sender, e.PropertyName, valuePropertyChangedEventArgs.NewValue); + }, + () => { + UnDo(sender, e.PropertyName, valuePropertyChangedEventArgs.OldValue); + }, + null, + false); Event?.Invoke(sender, new DiagramEventArgs(valuePropertyChangedEventArgs.PropertyName, valuePropertyChangedEventArgs.NewValue, valuePropertyChangedEventArgs.OldValue, selectable?.Id)); } @@ -2480,7 +2489,7 @@ namespace AIStudio.Wpf.DiagramDesigner var oldcenter = BoundingRect.Center; foreach (var item in selectedItems.OfType()) { - item.Left = item.Left - oldcenter.X + PageSize.Width / 2; + item.Left = item.Left - oldcenter.X + PageSize.Width / 2; item.Top = item.Top - oldcenter.Y + PageSize.Height / 2; } @@ -2541,7 +2550,7 @@ namespace AIStudio.Wpf.DiagramDesigner foreach (var item in infos) { item.Key.Size = item.Value; - } + } }); } } @@ -2695,15 +2704,6 @@ namespace AIStudio.Wpf.DiagramDesigner items = SelectedItems?.OfType().Where(p => p.ParentId == Guid.Empty).ToList(); } - var groups = items.OfType().Where(p => p.IsGroup && p.ParentId == Guid.Empty).ToList(); - - //解除分组 - if (groupItem == null && groups.Count > 0) - { - ExecuteUngroupCommand(groups); - return; - } - RectangleBase rect = DiagramViewModelHelper.GetBoundingRectangle(items); if (groupItem == null) @@ -2711,16 +2711,24 @@ namespace AIStudio.Wpf.DiagramDesigner groupItem = new GroupDesignerItemViewModel(); } - Add(groupItem, true); + DoCommandManager.DoNewCommand(this.ToString(), + () => { + Add(groupItem); + foreach (DesignerItemViewModelBase item in items) + item.ParentId = groupItem.Id; + groupItem.Resize(); + ClearSelectedItems(); + SelectionService.AddToSelection(groupItem); + }, + () => { + Remove(groupItem); + foreach (DesignerItemViewModelBase item in items) + { + item.IsSelected = true; + item.ParentId = Guid.Empty; + } + }); - foreach (DesignerItemViewModelBase item in items) - item.ParentId = groupItem.Id; - - groupItem.Resize(); - - ClearSelectedItemsCommand.Execute(null); - //groupItem.IsSelected = true; - SelectionService.AddToSelection(groupItem); } private void ExecuteUngroupCommand(object parameter) @@ -2728,22 +2736,45 @@ namespace AIStudio.Wpf.DiagramDesigner List groups; if (parameter is IEnumerable para) { - groups = para.ToList(); + groups = para.Where(p => p.IsGroup && p.ParentId == Guid.Empty).ToList(); } else { groups = SelectedItems?.OfType().Where(p => p.IsGroup && p.ParentId == Guid.Empty).ToList(); } + Dictionary> items = new Dictionary>(); foreach (DesignerItemViewModelBase groupRoot in groups) { var children = SelectedItems.OfType().Where(p => p.ParentId == groupRoot.Id); foreach (DesignerItemViewModelBase child in children) - child.ParentId = Guid.Empty; - - RemoveItemCommand.Execute(groupRoot); - UpdateZIndex(); + items.Add(child, new Tuple(child.ParentId, child.ZIndex)); } + + DoCommandManager.DoNewCommand(this.ToString(), + () => { + foreach (DesignerItemViewModelBase groupRoot in groups) + { + Remove(groupRoot); + } + foreach (var item in items) + { + item.Key.ParentId = Guid.Empty; + } + UpdateZIndex(); + }, + () => { + foreach (DesignerItemViewModelBase groupRoot in groups) + { + Add(groupRoot); + } + foreach (var item in items) + { + item.Key.ParentId = item.Value.Item1; + item.Key.ZIndex = item.Value.Item2; + } + }); + } private bool BelongToSameGroup(IGroupable item1, IGroupable item2) @@ -2817,6 +2848,11 @@ namespace AIStudio.Wpf.DiagramDesigner GroupCommand.Execute(null); return true; } + else if (DiagramOption.ShortcutOption.Ungroup(e)) + { + UngroupCommand.Execute(null); + return true; + } return false; } diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableViewModelBase.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableViewModelBase.cs index b096d55..928fd2d 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableViewModelBase.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableViewModelBase.cs @@ -158,7 +158,7 @@ namespace AIStudio.Wpf.DiagramDesigner private bool _isSelected; [Browsable(false)] - [CanDo] + //[CanDo] public bool IsSelected { get diff --git a/AIStudio.Wpf.Mind/ViewModels/MindNode.cs b/AIStudio.Wpf.Mind/ViewModels/MindNode.cs index e9a8ce7..70788e5 100644 --- a/AIStudio.Wpf.Mind/ViewModels/MindNode.cs +++ b/AIStudio.Wpf.Mind/ViewModels/MindNode.cs @@ -8,6 +8,7 @@ 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; @@ -239,6 +240,7 @@ namespace AIStudio.Wpf.Mind.ViewModels } private bool _isExpanded = true; + [CanDo] public bool IsExpanded { get @@ -322,6 +324,7 @@ namespace AIStudio.Wpf.Mind.ViewModels #region 附加信息属性 private LinkInfo _linkInfo; + [CanDo] public LinkInfo LinkInfo { get @@ -335,6 +338,7 @@ namespace AIStudio.Wpf.Mind.ViewModels } private ImageInfo _imageInfo; + [CanDo] public ImageInfo ImageInfo { get @@ -348,6 +352,7 @@ namespace AIStudio.Wpf.Mind.ViewModels } private string _remark; + [CanDo] [Browsable(true)] public string Remark { @@ -362,6 +367,7 @@ namespace AIStudio.Wpf.Mind.ViewModels } private double? _priority; + [CanDo] public double? Priority { get @@ -375,6 +381,7 @@ namespace AIStudio.Wpf.Mind.ViewModels } private double? _rate; + [CanDo] public double? Rate { get @@ -388,6 +395,7 @@ namespace AIStudio.Wpf.Mind.ViewModels } private ObservableCollection _tags; + [CanDo] public ObservableCollection Tags { get @@ -568,6 +576,7 @@ namespace AIStudio.Wpf.Mind.ViewModels { if (GetLevel0Node()?.LayoutUpdating == true) return; + Interlocked.Increment(ref Root.DoCommandManager.BeginDo); switch (e.PropertyName) { case nameof(Left): @@ -591,6 +600,7 @@ namespace AIStudio.Wpf.Mind.ViewModels case nameof(ItemWidth): case nameof(ItemHeight): { + UpdatedLayout(); break; } @@ -608,6 +618,7 @@ namespace AIStudio.Wpf.Mind.ViewModels break; } } + Interlocked.Decrement(ref Root.DoCommandManager.BeginDo); } protected override void FontViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)