Browse Source

Added reverse process to undo and added reverse clip canvas

flabbet 5 years ago
parent
commit
25c96c2ed3

+ 13 - 4
PixiEditor/Models/Controllers/UndoManager.cs

@@ -72,8 +72,16 @@ namespace PixiEditor.Models.Controllers
         public static void Undo()
         {
             _lastChangeWasUndo = true;
-            SetPropertyValue(MainRoot, UndoStack.Peek().Property, UndoStack.Peek().OldValue);
-            RedoStack.Push(UndoStack.Pop());
+            Change change = UndoStack.Pop();
+            if (change.ReverseProcess == null)
+            {
+                SetPropertyValue(MainRoot, change.Property, change.OldValue);
+            }
+            else
+            {
+                change.ReverseProcess(change.ReverseProcessArguments);
+            }
+            RedoStack.Push(change);
         }
 
         /// <summary>
@@ -82,8 +90,9 @@ namespace PixiEditor.Models.Controllers
         public static void Redo()
         {
             _lastChangeWasUndo = true;
-            SetPropertyValue(MainRoot, RedoStack.Peek().Property, RedoStack.Peek().NewValue);
-            UndoStack.Push(RedoStack.Pop());
+            Change change = RedoStack.Pop();
+            SetPropertyValue(MainRoot, change.Property, change.NewValue);
+            UndoStack.Push(change);
 
         }
        

+ 13 - 0
PixiEditor/Models/DataHolders/Change.cs

@@ -13,6 +13,9 @@ namespace PixiEditor.Models.DataHolders
 
         public string Property { get; set; }
 
+        public Action<object[]> ReverseProcess { get; set; } = null;
+        public object[] ReverseProcessArguments;
+
         public Change(string property, object oldValue, object newValue, string description = "")
         {
             Property = property;
@@ -21,6 +24,16 @@ namespace PixiEditor.Models.DataHolders
             NewValue = newValue;
         }
 
+        public Change(string property, Action<object[]> reverseProcess, object[] reverseArguments, 
+            object newValue, string description = "")
+        {
+            Property = property;
+            ReverseProcess = reverseProcess;
+            ReverseProcessArguments = reverseArguments;
+            NewValue = newValue;
+            Description = description;
+        }
+
         public Change()
         {
 

+ 45 - 2
PixiEditor/Models/DataHolders/Document.cs

@@ -78,7 +78,14 @@ namespace PixiEditor.Models.DataHolders
 
         public void Crop(int x, int y, int width, int height)
         {
-            Document copy = DeepClone();
+            object[] reverseArgs = new object[] { x, y, Width, Height, width, height};
+            CropDocument(x, y, width, height);
+            UndoManager.AddUndoChange(new Change("BitmapManager.ActiveDocument", ReverseCrop, 
+                reverseArgs, this, "Crop document"));
+        }
+
+        private void CropDocument(int x, int y, int width, int height)
+        {
             for (int i = 0; i < Layers.Count; i++)
             {
                 Layers[i].LayerBitmap = Layers[i].LayerBitmap.Crop(x, y, width, height);
@@ -87,7 +94,43 @@ namespace PixiEditor.Models.DataHolders
             }
             Height = height;
             Width = width;
-            UndoManager.AddUndoChange(new Change("BitmapManager.ActiveDocument", copy, this, "Crop document"));
+        }
+
+        private void ReverseCrop(object[] arguments) //Reverses process of cropping
+        {
+            int offsetX = (int)arguments[0];
+            int offsetY = (int)arguments[1];
+            int oldWidth = (int)arguments[2]; //oldWidth is the width before first crop
+            int oldHeight = (int)arguments[3];
+            int newWidth = (int)arguments[4]; //newWidth is the width after first crop
+            int newHeight = (int)arguments[5];
+            int sizeOfArgb = 4;
+            if (offsetX < 0) offsetX = 0;
+            if (offsetX + newWidth > oldWidth) newWidth = oldWidth - offsetX;
+            if (offsetY < 0) offsetY = 0;
+            if (offsetY + newHeight > oldHeight) newHeight = oldHeight - offsetY;
+
+            for (int i = 0; i < Layers.Count; i++)
+            {
+                using (var srcContext = Layers[i].LayerBitmap.GetBitmapContext(ReadWriteMode.ReadOnly))
+                {
+                    var result = BitmapFactory.New(oldWidth, oldHeight);
+                    using (var destContext = result.GetBitmapContext())
+                    {
+                        for (int line = 0; line < newHeight; line++)
+                        {
+                            var srcOff = line * newWidth * sizeOfArgb;
+                            var dstOff = ((offsetY + line) * oldWidth + offsetX) * sizeOfArgb;
+                            BitmapContext.BlockCopy(srcContext, srcOff, destContext, dstOff, newWidth * sizeOfArgb);
+                        }
+                        Layers[i].LayerBitmap = result;
+                        Layers[i].Width = oldWidth;
+                        Layers[i].Height = oldHeight;
+                    }
+                }
+            }
+            Width = oldWidth;
+            Height = oldHeight;
         }
 
         public void ClipCanvas()