Browse Source

Fixed resize undo destroys quality

flabbet 4 years ago
parent
commit
ac5bb5f7f9

+ 16 - 0
PixiEditor/Helpers/Extensions/ObservableCollectionEx.cs

@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace PixiEditor.Helpers.Extensions
+{
+    public static class ObservableCollectionEx
+    {
+        public static void AddRange<T>(this ObservableCollection<T> collection, IEnumerable<T> items)
+        {
+            foreach (var item in items)
+            {
+                collection.Add(item);
+            }
+        }
+    }
+}

+ 50 - 30
PixiEditor/Models/DataHolders/Document/Document.Operations.cs

@@ -1,10 +1,13 @@
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Windows;
+using PixiEditor.Helpers.Extensions;
 using PixiEditor.Models.Enums;
+using PixiEditor.Models.Layers;
 using PixiEditor.Models.Undo;
 
 namespace PixiEditor.Models.DataHolders
@@ -13,25 +16,6 @@ namespace PixiEditor.Models.DataHolders
     {
         public event EventHandler<DocumentSizeChangedEventArgs> DocumentSizeChanged;
 
-        /// <summary>
-        ///     Resizes canvas.
-        /// </summary>
-        /// <param name="offset">Offset of content in new canvas. It will move layer to that offset.</param>
-        /// <param name="newWidth">New canvas size.</param>
-        /// <param name="newHeight">New canvas height.</param>
-        private void ResizeCanvas(Thickness[] offset, int newWidth, int newHeight)
-        {
-            for (int i = 0; i < Layers.Count; i++)
-            {
-                Layers[i].Offset = offset[i];
-                Layers[i].MaxWidth = newWidth;
-                Layers[i].MaxHeight = newHeight;
-            }
-
-            Width = newWidth;
-            Height = newHeight;
-        }
-
         /// <summary>
         ///     Resizes canvas to specified width and height to selected anchor.
         /// </summary>
@@ -75,23 +59,59 @@ namespace PixiEditor.Models.DataHolders
         {
             object[] reverseArgs = { Width, Height };
             object[] args = { newWidth, newHeight };
-            ResizeDocument(args);
-            UndoManager.AddUndoChange(new Change(
-                ResizeDocument,
-                reverseArgs,
-                ResizeDocument,
-                args,
-                "Resize document"));
+            StorageBasedChange change = new StorageBasedChange(this, Layers);
+
+            ResizeDocument(newWidth, newHeight);
+
+            UndoManager.AddUndoChange(
+                change.ToChange(
+                    RestoreDocumentLayersProcess,
+                    reverseArgs,
+                    ResizeDocumentProcess,
+                    args,
+                    "Resize document"));
+        }
+
+        private void RestoreDocumentLayersProcess(Layer[] layers, UndoLayer[] data, object[] args)
+        {
+            Width = (int)args[0];
+            Height = (int)args[1];
+            Layers.Clear();
+            Layers.AddRange(layers);
         }
 
-        private void ResizeDocument(object[] arguments)
+        /// <summary>
+        ///     Resizes canvas.
+        /// </summary>
+        /// <param name="offset">Offset of content in new canvas. It will move layer to that offset.</param>
+        /// <param name="newWidth">New canvas size.</param>
+        /// <param name="newHeight">New canvas height.</param>
+        private void ResizeCanvas(Thickness[] offset, int newWidth, int newHeight)
+        {
+            for (int i = 0; i < Layers.Count; i++)
+            {
+                Layers[i].Offset = offset[i];
+                Layers[i].MaxWidth = newWidth;
+                Layers[i].MaxHeight = newHeight;
+            }
+
+            Width = newWidth;
+            Height = newHeight;
+        }
+
+        private void ResizeDocumentProcess(object[] args)
+        {
+            if (args.Length > 1 && args[0] is int width && args[1] is int height) 
+            {
+                ResizeDocument(width, height);
+            }
+        }
+
+        private void ResizeDocument(int newWidth, int newHeight)
         {
             int oldWidth = Width;
             int oldHeight = Height;
 
-            int newWidth = (int)arguments[0];
-            int newHeight = (int)arguments[1];
-
             for (int i = 0; i < Layers.Count; i++)
             {
                 float widthRatio = (float)newWidth / Width;