Browse Source

Added undo

Krzysztof Krysiński 3 years ago
parent
commit
d216d61ffb

+ 15 - 17
PixiEditor/Models/Controllers/LayerStackRenderer.cs

@@ -116,23 +116,21 @@ namespace PixiEditor.Models.Controllers
                 Int32Rect layerRect = new Int32Rect(layer.OffsetX, layer.OffsetY, layer.Width, layer.Height);
                 Int32Rect layerRect = new Int32Rect(layer.OffsetX, layer.OffsetY, layer.Width, layer.Height);
                 Int32Rect layerPortion = layerRect.Intersect(dirtyRectangle);
                 Int32Rect layerPortion = layerRect.Intersect(dirtyRectangle);
 
 
-                using (var snapshot = layer.LayerBitmap.SkiaSurface.Snapshot())
-                {
-                    finalSurface.SkiaSurface.Canvas.DrawImage(
-                        snapshot,
-                        new SKRect(
-                            layerPortion.X - layer.OffsetX,
-                            layerPortion.Y - layer.OffsetY,
-                            layerPortion.X - layer.OffsetX + layerPortion.Width,
-                            layerPortion.Y - layer.OffsetY + layerPortion.Height),
-                        new SKRect(
-                            layerPortion.X,
-                            layerPortion.Y,
-                            layerPortion.X + layerPortion.Width,
-                            layerPortion.Y + layerPortion.Height
-                        ),
-                        BlendingPaint);
-                }
+                using var snapshot = layer.LayerBitmap.SkiaSurface.Snapshot();
+                finalSurface.SkiaSurface.Canvas.DrawImage(
+                    snapshot,
+                    new SKRect(
+                        layerPortion.X - layer.OffsetX,
+                        layerPortion.Y - layer.OffsetY,
+                        layerPortion.X - layer.OffsetX + layerPortion.Width,
+                        layerPortion.Y - layer.OffsetY + layerPortion.Height),
+                    new SKRect(
+                        layerPortion.X,
+                        layerPortion.Y,
+                        layerPortion.X + layerPortion.Width,
+                        layerPortion.Y + layerPortion.Height
+                    ),
+                    BlendingPaint);
             }
             }
             finalBitmap.Lock();
             finalBitmap.Lock();
             using (var snapshot = finalSurface.SkiaSurface.Snapshot())
             using (var snapshot = finalSurface.SkiaSurface.Snapshot())

+ 23 - 4
PixiEditor/Models/DataHolders/Document/Document.Operations.cs

@@ -17,12 +17,21 @@ namespace PixiEditor.Models.DataHolders
 
 
         public void ReplaceColor(SKColor oldColor, SKColor newColor)
         public void ReplaceColor(SKColor oldColor, SKColor newColor)
         {
         {
-            foreach (var layer in Layers)
-            {
-                layer.ReplaceColor(oldColor, newColor);
-            }
+            StorageBasedChange change = new(this, Layers);
+
+            var args = new object[] { oldColor, newColor };
+
+            ReplaceColorProcess(args);
+
+            UndoManager.AddUndoChange(change.ToChange(
+                StorageBasedChange.BasicUndoProcess,
+                new object[] { this },
+                ReplaceColorProcess,
+                args,
+                "Resize canvas"));
         }
         }
 
 
+
         /// <summary>
         /// <summary>
         ///     Resizes canvas to specified width and height to selected anchor.
         ///     Resizes canvas to specified width and height to selected anchor.
         /// </summary>
         /// </summary>
@@ -119,6 +128,16 @@ namespace PixiEditor.Models.DataHolders
                     "Resize document"));
                     "Resize document"));
         }
         }
 
 
+        private void ReplaceColorProcess(object[] args)
+        {
+            SKColor oldColor = (SKColor)args[0];
+            SKColor newColor = (SKColor)args[1];
+
+            foreach (var layer in Layers)
+            {
+                layer.ReplaceColor(oldColor, newColor);
+            }
+        }
 
 
         private void FlipDocumentProcess(object[] processArgs)
         private void FlipDocumentProcess(object[] processArgs)
         {
         {

+ 15 - 24
PixiEditor/Models/Layers/Layer.cs

@@ -14,6 +14,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using System.Windows;
 using System.Windows;
 using System.Windows.Media;
 using System.Windows.Media;
+using PixiEditor.Models.Dialogs;
 
 
 namespace PixiEditor.Models.Layers
 namespace PixiEditor.Models.Layers
 {
 {
@@ -711,38 +712,28 @@ namespace PixiEditor.Models.Layers
             int maxThreads = Environment.ProcessorCount;
             int maxThreads = Environment.ProcessorCount;
             int rowsPerThread = Height / maxThreads;
             int rowsPerThread = Height / maxThreads;
 
 
-            Thread[] threads = new Thread[maxThreads];
-
-            for (int i = 0; i < maxThreads; i++)
+            Parallel.For(0, maxThreads, i =>
             {
             {
-                var i1 = i;
-                threads[i] = new Thread(() =>
+                int startRow = i * rowsPerThread;
+                int endRow = (i + 1) * rowsPerThread;
+                if (i == maxThreads - 1)
                 {
                 {
-                    int startRow = i1 * rowsPerThread;
-                    int endRow = (i1 + 1) * rowsPerThread;
-                    if (i1 == maxThreads - 1)
-                    {
-                        endRow = Height;
-                    }
+                    endRow = Height;
+                }
 
 
-                    for (int y = startRow; y < endRow; y++)
+                for (int y = startRow; y < endRow; y++)
+                {
+                    for (int x = 0; x < Width; x++)
                     {
                     {
-                        for (int x = 0; x < Width; x++)
+                        if (LayerBitmap.GetSRGBPixel(x, y) == oldColor)
                         {
                         {
-                            if (LayerBitmap.GetSRGBPixel(x, y) == oldColor)
-                            {
-                                LayerBitmap.SetSRGBPixelUnmanaged(x, y, newColor);
-                            }
+                            LayerBitmap.SetSRGBPixelUnmanaged(x, y, newColor);
                         }
                         }
                     }
                     }
-                });
-
-                threads[i].Start();
-            }
-
-            threads.ToList().ForEach(x => x.Join());
+                }
+            });
 
 
-            layerBitmap.SkiaSurface.Canvas.DrawSurface(layerBitmap.SkiaSurface, 0, 0, new SKPaint { BlendMode = SKBlendMode.Dst });
+            layerBitmap.SkiaSurface.Canvas.DrawPaint(new SKPaint { BlendMode = SKBlendMode.Dst });
 
 
             InvokeLayerBitmapChange();
             InvokeLayerBitmapChange();
         }
         }

+ 25 - 5
PixiEditor/ViewModels/SubViewModels/Main/ColorsViewModel.cs

@@ -16,6 +16,7 @@ using System.Threading.Tasks;
 using System.Windows;
 using System.Windows;
 using PixiEditor.Models.Controllers;
 using PixiEditor.Models.Controllers;
 using PixiEditor.Models.ExternalServices;
 using PixiEditor.Models.ExternalServices;
+using PixiEditor.Models.Undo;
 using PixiEditor.Views.Dialogs;
 using PixiEditor.Views.Dialogs;
 
 
 namespace PixiEditor.ViewModels.SubViewModels.Main
 namespace PixiEditor.ViewModels.SubViewModels.Main
@@ -86,15 +87,34 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
             if (activeDocument != null)
             if (activeDocument != null)
             {
             {
                 activeDocument.ReplaceColor(colors.oldColor, colors.newColor);
                 activeDocument.ReplaceColor(colors.oldColor, colors.newColor);
-                int oldIndex = activeDocument.Palette.IndexOf(colors.oldColor);
-                if (oldIndex != -1)
-                {
-                    activeDocument.Palette[oldIndex] = colors.newColor;
-                }
+                ReplacePaletteColor(colors, activeDocument);
+                activeDocument.UndoManager.AddUndoChange(new Change(
+                    ReplacePaletteColorProcess,
+                    new object[] { (colors.newColor, colors.oldColor), activeDocument },
+                    ReplacePaletteColorProcess,
+                    new object[] { colors, activeDocument }));
+                activeDocument.UndoManager.SquashUndoChanges(2, $"Replace color {colors.oldColor} with {colors.newColor}");
             }
             }
 
 
         }
         }
 
 
+        private static void ReplacePaletteColorProcess(object[] args)
+        {
+            (SKColor oldColor, SKColor newColor) colors = ((SKColor, SKColor))args[0];
+            Document activeDocument = (Document)args[1];
+
+            ReplacePaletteColor(colors, activeDocument);
+        }
+
+        private static void ReplacePaletteColor((SKColor oldColor, SKColor newColor) colors, Document activeDocument)
+        {
+            int oldIndex = activeDocument.Palette.IndexOf(colors.oldColor);
+            if (oldIndex != -1)
+            {
+                activeDocument.Palette[oldIndex] = colors.newColor;
+            }
+        }
+
         private async void OwnerOnStartupEvent(object? sender, EventArgs e)
         private async void OwnerOnStartupEvent(object? sender, EventArgs e)
         {
         {
             await ImportLospecPalette();
             await ImportLospecPalette();