Browse Source

Added undo for adding layer and moving it, fixed selection bug

flabbet 4 years ago
parent
commit
d0d7232a70

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

@@ -140,6 +140,7 @@ namespace PixiEditor.Models.Controllers
             {
                 ActiveDocument.PreviewLayer = null;
             }
+
             SelectedTool?.Toolbar.SaveToolbarSettings();
             SelectedTool = tool;
             SelectedTool.Toolbar.LoadSharedSettings();

+ 46 - 1
PixiEditor/Models/DataHolders/Document.cs

@@ -286,11 +286,32 @@ namespace PixiEditor.Models.DataHolders
                 ActiveLayer.IsActive = false;
             }
 
+            if (Layers.Any(x => x.IsActive))
+            {
+                Layers.First(x => x.IsActive).IsActive = false;
+            }
+
             ActiveLayerIndex = index;
             ActiveLayer.IsActive = true;
             LayersChanged?.Invoke(this, new LayersChangedEventArgs(index, LayerAction.SetActive));
         }
 
+        public void MoveLayerIndexBy(int layerIndex, int amount)
+        {
+            Layers.Move(layerIndex, layerIndex + amount);
+            if (ActiveLayerIndex == layerIndex)
+            {
+                SetActiveLayer(layerIndex + amount);
+            }
+
+            UndoManager.AddUndoChange(new Change(
+                MoveLayerProcess,
+                new object[] { layerIndex + amount, -amount },
+                MoveLayerProcess,
+                new object[] { layerIndex, amount }, 
+                "Move layer"));
+        }
+
         public void AddNewLayer(string name, WriteableBitmap bitmap, bool setAsActive = true)
         {
             AddNewLayer(name, bitmap.PixelWidth, bitmap.PixelHeight, setAsActive);
@@ -314,6 +335,18 @@ namespace PixiEditor.Models.DataHolders
                 SetActiveLayer(Layers.Count - 1);
             }
 
+            if (Layers.Count > 1)
+            {
+                StorageBasedChange storageChange = new StorageBasedChange(this, new[] { Layers[^1] });
+                UndoManager.AddUndoChange(
+                    storageChange.ToChange(
+                        RemoveLayerProcess,
+                        new object[] { Layers[^1].LayerGuid },
+                        RestoreLayerProcess,
+                        new object[] { new Layer[] { Layers[^1] }, storageChange.StoredLayers },
+                        "Add layer"));
+            }
+
             LayersChanged?.Invoke(this, new LayersChangedEventArgs(0, LayerAction.Add));
         }
 
@@ -332,7 +365,7 @@ namespace PixiEditor.Models.DataHolders
             }
         }
 
-        public void RemoveLayer(int layerIndex, bool addToUndo = true)
+        public void RemoveLayer(int layerIndex)
         {
             if (Layers.Count == 0)
             {
@@ -352,6 +385,18 @@ namespace PixiEditor.Models.DataHolders
             }
         }
 
+        private void MoveLayerProcess(object[] parameter)
+        {
+            int layerIndex = (int)parameter[0];
+            int amount = (int)parameter[1];
+            MoveLayerIndexBy(layerIndex, amount);
+        }
+
+        private void RestoreLayerProcess(object[] parameters)
+        {
+            RestoreLayersProcess((Layer[])parameters[0], (UndoLayer[])parameters[1]);
+        }
+
         private void RestoreLayersProcess(Layer[] layers, UndoLayer[] layersData)
         {
             for (int i = 0; i < layers.Length; i++)

+ 17 - 0
PixiEditor/Models/Undo/StorageBasedChange.cs

@@ -107,6 +107,23 @@ namespace PixiEditor.Models.Undo
             return new Change(finalUndoProcess, null, fianlRedoProcess, redoProcessParameters, description);
         }
 
+        public Change ToChange(Action<object[]> undoProcess, object[] undoProcessParameters, Action<object[]> redoProcess, object[] redoProcessParameters, string description = "")
+        {
+            Action<object[]> finalUndoProcess = parameters =>
+            {
+                Layer[] layers = LoadLayersFromDevice();
+                undoProcess(parameters.Concat(new object[] { layers, StoredLayers }).ToArray());
+            };
+
+            Action<object[]> fianlRedoProcess = parameters =>
+            {
+                SaveLayersOnDevice();
+                redoProcess(parameters);
+            };
+
+            return new Change(finalUndoProcess, undoProcessParameters, fianlRedoProcess, redoProcessParameters, description);
+        }
+
         private void GenerateUndoLayers()
         {
             StoredLayers = new UndoLayer[layersToStore.Count()];

+ 2 - 10
PixiEditor/ViewModels/SubViewModels/Main/LayersViewModel.cs

@@ -60,21 +60,13 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
         public void MoveLayerToFront(object parameter)
         {
             int oldIndex = (int)parameter;
-            Owner.BitmapManager.ActiveDocument.Layers.Move(oldIndex, oldIndex + 1);
-            if (Owner.BitmapManager.ActiveDocument.ActiveLayerIndex == oldIndex)
-            {
-                Owner.BitmapManager.ActiveDocument.SetActiveLayer(oldIndex + 1);
-            }
+            Owner.BitmapManager.ActiveDocument.MoveLayerIndexBy(oldIndex, 1);
         }
 
         public void MoveLayerToBack(object parameter)
         {
             int oldIndex = (int)parameter;
-            Owner.BitmapManager.ActiveDocument.Layers.Move(oldIndex, oldIndex - 1);
-            if (Owner.BitmapManager.ActiveDocument.ActiveLayerIndex == oldIndex)
-            {
-                Owner.BitmapManager.ActiveDocument.SetActiveLayer(oldIndex - 1);
-            }
+            Owner.BitmapManager.ActiveDocument.MoveLayerIndexBy(oldIndex, -1);
         }
 
         public bool CanMoveToFront(object property)

+ 1 - 6
PixiEditorTests/ModelsTests/LayersTests/LayersTestHelper.cs

@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using PixiEditor.Models.Layers;
+using PixiEditor.Models.Layers;
 using Xunit;
 
 namespace PixiEditorTests.ModelsTests.LayersTests