瀏覽代碼

Merge pull request #101 from PixiEditor/clipboard-undo

Added clipboard undo support
Krzysztof Krysiński 4 年之前
父節點
當前提交
9bc10ee8f9

+ 1 - 1
PixiEditor/Models/Controllers/BitmapManager.cs

@@ -248,7 +248,7 @@ namespace PixiEditor.Models.Controllers
             SelectedTool.OnStoppedRecordingMouseUp(new MouseEventArgs(Mouse.PrimaryDevice, (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()));
             if (IsOperationTool(SelectedTool) && ((BitmapOperationTool)SelectedTool).RequiresPreviewLayer)
             {
-                BitmapOperations.StopAction();
+                BitmapOperations.ApplyPreviewLayer();
             }
         }
 

+ 9 - 3
PixiEditor/Models/Controllers/BitmapOperationsUtility.cs

@@ -29,15 +29,21 @@ namespace PixiEditor.Models.Controllers
 
         public void DeletePixels(Layer[] layers, Coordinates[] pixels)
         {
+            if (Manager.ActiveDocument == null)
+            {
+                return;
+            }
+
             BitmapPixelChanges changes = BitmapPixelChanges.FromSingleColoredArray(pixels, Color.FromArgb(0, 0, 0, 0));
             Dictionary<Layer, Color[]> oldValues = BitmapUtils.GetPixelsForSelection(layers, pixels);
             LayerChange[] old = new LayerChange[layers.Length];
             LayerChange[] newChange = new LayerChange[layers.Length];
             for (int i = 0; i < layers.Length; i++)
             {
+                int indexOfLayer = Manager.ActiveDocument.Layers.IndexOf(layers[i]);
                 old[i] = new LayerChange(
-                    BitmapPixelChanges.FromArrays(pixels, oldValues[layers[i]]), i);
-                newChange[i] = new LayerChange(changes, i);
+                    BitmapPixelChanges.FromArrays(pixels, oldValues[layers[i]]), indexOfLayer);
+                newChange[i] = new LayerChange(changes, indexOfLayer);
                 layers[i].SetPixels(changes);
             }
 
@@ -69,7 +75,7 @@ namespace PixiEditor.Models.Controllers
         /// <summary>
         ///     Applies pixels from preview layer to selected layer.
         /// </summary>
-        public void StopAction()
+        public void ApplyPreviewLayer()
         {
             if (lastModifiedLayers == null)
             {

+ 24 - 0
PixiEditor/Models/Controllers/ClipboardController.cs

@@ -2,6 +2,7 @@
 using System.Linq;
 using System.Windows;
 using System.Windows.Media.Imaging;
+using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.ImageManipulation;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
@@ -44,9 +45,32 @@ namespace PixiEditor.Models.Controllers
             if (image != null)
             {
                 AddImageToLayers(image);
+                int latestLayerIndex = ViewModelMain.Current.BitmapManager.ActiveDocument.Layers.Count - 1;
+                UndoManager.AddUndoChange(
+                    new Change(RemoveLayerProcess, new object[] { latestLayerIndex }, AddLayerProcess, new object[] { image }));
             }
         }
 
+        private static void RemoveLayerProcess(object[] parameters)
+        {
+            if (parameters.Length == 0 || !(parameters[0] is int))
+            {
+                return;
+            }
+
+            ViewModelMain.Current.BitmapManager.RemoveLayer((int)parameters[0]);
+        }
+
+        private static void AddLayerProcess(object[] parameters)
+        {
+            if (parameters.Length == 0 || !(parameters[0] is WriteableBitmap))
+            {
+                return;
+            }
+
+            AddImageToLayers((WriteableBitmap)parameters[0]);
+        }
+
         /// <summary>
         ///     Gets image from clipboard, supported PNG, Dib and Bitmap.
         /// </summary>

+ 3 - 2
PixiEditor/Models/Controllers/UndoManager.cs

@@ -32,13 +32,14 @@ namespace PixiEditor.Models.Controllers
         /// </summary>
         public static void AddUndoChange(Change change)
         {
-            // Clears RedoStack if las move wasn't redo or undo and if redo stack is greater than 0
+            lastChangeWasUndo = false;
+
+            // Clears RedoStack if last move wasn't redo or undo and if redo stack is greater than 0.
             if (lastChangeWasUndo == false && RedoStack.Count > 0)
             {
                 RedoStack.Clear();
             }
 
-            lastChangeWasUndo = false;
             change.Root ??= MainRoot;
             UndoStack.Push(change);
         }

+ 3 - 0
PixiEditor/Models/DataHolders/BitmapPixelChanges.cs

@@ -1,9 +1,12 @@
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Linq;
 using System.Windows.Media;
+using System.Windows.Media.Imaging;
 using PixiEditor.Exceptions;
 using PixiEditor.Helpers.Extensions;
+using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 
 namespace PixiEditor.Models.DataHolders

+ 1 - 0
PixiEditor/Models/Tools/Tools/PenTool.cs

@@ -5,6 +5,7 @@ using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Tools.ToolSettings.Settings;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
+using PixiEditor.ViewModels;
 
 namespace PixiEditor.Models.Tools.Tools
 {

+ 2 - 1
PixiEditor/Models/Tools/Tools/SelectTool.cs

@@ -49,7 +49,8 @@ namespace PixiEditor.Models.Tools.Tools
                 ViewModelMain.Current.SelectionSubViewModel.ActiveSelection.Clear();
             }
 
-            UndoManager.AddUndoChange(new Change("ActiveSelection", oldSelection, ViewModelMain.Current.SelectionSubViewModel.ActiveSelection, "Select pixels"));
+            UndoManager.AddUndoChange(
+                new Change("ActiveSelection", oldSelection, ViewModelMain.Current.SelectionSubViewModel.ActiveSelection, "Select pixels", ViewModelMain.Current.SelectionSubViewModel));
         }
 
         public override void Use(Coordinates[] pixels)

+ 5 - 5
PixiEditor/ViewModels/SubViewModels/Main/ClipboardViewModel.cs

@@ -6,6 +6,7 @@ using System.Windows.Media;
 using PixiEditor.Helpers;
 using PixiEditor.Models.Controllers;
 using PixiEditor.Models.DataHolders;
+using PixiEditor.Models.Position;
 
 namespace PixiEditor.ViewModels.SubViewModels.Main
 {
@@ -37,10 +38,9 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
         public void Cut(object parameter)
         {
             Copy(null);
-            Owner.BitmapManager.ActiveLayer.SetPixels(
-                BitmapPixelChanges.FromSingleColoredArray(
-                    Owner.SelectionSubViewModel.ActiveSelection.SelectedPoints.ToArray(),
-                    Colors.Transparent));
+            Owner.BitmapManager.BitmapOperations.DeletePixels(
+                new[] { Owner.BitmapManager.ActiveDocument.ActiveLayer },
+                Owner.SelectionSubViewModel.ActiveSelection.SelectedPoints.ToArray());
         }
 
         public void Paste(object parameter)
@@ -56,7 +56,7 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
         private void Copy(object parameter)
         {
             ClipboardController.CopyToClipboard(
-                Owner.BitmapManager.ActiveDocument.Layers.ToArray(),
+                new[] { Owner.BitmapManager.ActiveDocument.ActiveLayer },
                 Owner.SelectionSubViewModel.ActiveSelection.SelectedPoints.ToArray(),
                 Owner.BitmapManager.ActiveDocument.Width,
                 Owner.BitmapManager.ActiveDocument.Height);

+ 1 - 0
PixiEditor/ViewModels/SubViewModels/Main/UndoViewModel.cs

@@ -33,6 +33,7 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
         {
             UndoCommand = new RelayCommand(Undo, CanUndo);
             RedoCommand = new RelayCommand(Redo, CanRedo);
+            UndoManager.SetMainRoot(this);
         }
 
         public void TriggerNewUndoChange(Tool toolUsed)

+ 0 - 1
PixiEditor/ViewModels/ViewModelMain.cs

@@ -133,7 +133,6 @@ namespace PixiEditor.ViewModels
                     new Shortcut(Key.N, FileSubViewModel.OpenNewFilePopupCommand, modifier: ModifierKeys.Control)
                 }
             };
-            UndoManager.SetMainRoot(this);
             BitmapManager.PrimaryColor = ColorsSubViewModel.PrimaryColor;
             Current = this;
         }

+ 1 - 0
PixiEditorTests/ModelsTests/ControllersTests/BitmapOperationsUtilityTests.cs

@@ -14,6 +14,7 @@ namespace PixiEditorTests.ModelsTests.ControllersTests
         public void TestThatBitmapOperationsUtilityDeletesPixels()
         {
             BitmapOperationsUtility util = new BitmapOperationsUtility(new BitmapManager());
+            util.Manager.ActiveDocument = new Document(10, 10);
 
             Layer testLayer = new Layer("test layer", 10, 10);
             Coordinates[] cords = { new Coordinates(0, 0), new Coordinates(1, 1) };

+ 1 - 1
PixiEditorTests/ViewModelsTests/ViewModelMainTests.cs

@@ -18,7 +18,7 @@ namespace PixiEditorTests.ViewModelsTests
         {
             ViewModelMain viewModel = new ViewModelMain();
 
-            Assert.Equal(viewModel, UndoManager.MainRoot);
+            Assert.Equal(viewModel.UndoSubViewModel, UndoManager.MainRoot);
             Assert.NotNull(viewModel.ChangesController);
             Assert.NotNull(viewModel.ShortcutController);
             Assert.NotEmpty(viewModel.ShortcutController.Shortcuts);