Browse Source

Fixed undo

flabbet 5 years ago
parent
commit
8c5057cd77

+ 21 - 14
PixiEditor/Models/Controllers/BitmapOperationsUtility.cs

@@ -60,11 +60,11 @@ namespace PixiEditor.Models.Controllers
             if (_lastModifiedLayers == null) return;
             for (int i = 0; i < _lastModifiedLayers.Length; i++)
             {
-                BitmapPixelChanges oldValues =
-                    GetOldPixelsValues(_lastModifiedLayers[i].PixelChanges.ChangedPixels.Keys.ToArray());
-                Manager.ActiveDocument.Layers[_lastModifiedLayers[i].LayerIndex]
-                    .ApplyPixels(_lastModifiedLayers[i].PixelChanges);
-                BitmapChanged?.Invoke(this, new BitmapChangedEventArgs(_lastModifiedLayers[i].PixelChanges,
+                var layer = Manager.ActiveDocument.Layers[_lastModifiedLayers[i].LayerIndex];
+
+                BitmapPixelChanges oldValues = ApplyToLayer(layer, _lastModifiedLayers[i]).PixelChanges;
+
+               BitmapChanged?.Invoke(this, new BitmapChangedEventArgs(_lastModifiedLayers[i].PixelChanges,
                     oldValues, _lastModifiedLayers[i].LayerIndex));
                 Manager.PreviewLayer.Clear();
             }
@@ -83,10 +83,8 @@ namespace PixiEditor.Models.Controllers
                 for (int i = 0; i < modifiedLayers.Length; i++)
                 {
                     var layer = Manager.ActiveDocument.Layers[modifiedLayers[i].LayerIndex];
-                    oldPixelsValues[i] = new LayerChange(
-                        GetOldPixelsValues(modifiedLayers[i].PixelChanges.ChangedPixels.Keys.ToArray()),
-                        modifiedLayers[i].LayerIndex);
-                    layer.ApplyPixels(modifiedLayers[i].PixelChanges);
+                    oldPixelsValues[i] = ApplyToLayer(layer, modifiedLayers[i]);
+                    
                     BitmapChanged?.Invoke(this, new BitmapChangedEventArgs(modifiedLayers[i].PixelChanges,
                         oldPixelsValues[i].PixelChanges, modifiedLayers[i].LayerIndex));
                 }
@@ -97,6 +95,18 @@ namespace PixiEditor.Models.Controllers
             }
         }
 
+        private LayerChange ApplyToLayer(Layer layer, LayerChange change)
+        {
+            layer.DynamicResize(change.PixelChanges);
+
+            var oldPixelsValues = new LayerChange(
+                GetOldPixelsValues(change.PixelChanges.ChangedPixels.Keys.ToArray()),
+                change.LayerIndex);
+
+            layer.ApplyPixels(change.PixelChanges, false);
+            return oldPixelsValues;
+        }
+
         private bool MouseCordsNotInLine(List<Coordinates> cords)
         {
             return cords[0].X == cords[^1].X || cords[0].Y == cords[^1].Y;
@@ -122,14 +132,11 @@ namespace PixiEditor.Models.Controllers
             Dictionary<Coordinates, Color> values = new Dictionary<Coordinates, Color>();
             using (Manager.ActiveLayer.LayerBitmap.GetBitmapContext(ReadWriteMode.ReadOnly))
             {
-                coordinates = Manager.ActiveLayer.ConvertToRelativeCoordinates(coordinates);
+                var relativeCoords = Manager.ActiveLayer.ConvertToRelativeCoordinates(coordinates);
                 for (int i = 0; i < coordinates.Length; i++)
                 {
-                    if (coordinates[i].X < 0 || coordinates[i].X > Manager.ActiveLayer.Width - 1 ||
-                        coordinates[i].Y < 0 || coordinates[i].Y > Manager.ActiveLayer.Height - 1)
-                        continue;
                     values.Add(coordinates[i],
-                        Manager.ActiveLayer.LayerBitmap.GetPixel(coordinates[i].X, coordinates[i].Y));
+                        Manager.ActiveLayer.GetPixel(relativeCoords[i].X, relativeCoords[i].Y));
                 }
 
             }

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

@@ -7,7 +7,6 @@ namespace PixiEditor.Models.Controllers
 {
     public static class UndoManager
     {
-        private static List<Change> _recordedChanges = new List<Change>();
         private static bool _lastChangeWasUndo;
         public static StackEx<Change> UndoStack { get; set; } = new StackEx<Change>();
         public static StackEx<Change> RedoStack { get; set; } = new StackEx<Change>();
@@ -27,30 +26,17 @@ namespace PixiEditor.Models.Controllers
             MainRoot = root;
         }
 
-
-        public static void AddUndoChange(Change change)
-        {
-            if (_lastChangeWasUndo == false && RedoStack.Count > 0
-            ) //Cleares RedoStack if las move wasn't redo or undo and if redo stack is greater than 0
-                RedoStack.Clear();
-            _lastChangeWasUndo = false;
-            UndoStack.Push(change);
-        }
-
         /// <summary>
         ///     Adds property change to UndoStack
         /// </summary>
-        /// <param name="property">Changed property name.</param>
-        /// <param name="oldValue">Old value of property.</param>
-        /// <param name="newValue">New value of property.</param>
-        /// <param name="undoDescription">Description of change.</param>
-        public static void AddUndoChange(string property, object oldValue, object newValue, string undoDescription = "")
+        /// <param name="change"></param>
+        public static void AddUndoChange(Change change)
         {
             if (_lastChangeWasUndo == false && RedoStack.Count > 0
-            ) //Cleares RedoStack if las move wasn't redo or undo and if redo stack is greater than 0
+            ) //Clears RedoStack if las move wasn't redo or undo and if redo stack is greater than 0
                 RedoStack.Clear();
             _lastChangeWasUndo = false;
-            UndoStack.Push(new Change(property, oldValue, newValue, undoDescription));
+            UndoStack.Push(change);
         }
 
         /// <summary>

+ 34 - 9
PixiEditor/Models/Layers/Layer.cs

@@ -90,6 +90,8 @@ namespace PixiEditor.Models.Layers
         public int MaxWidth { get; set; } = int.MaxValue;
         public int MaxHeight { get; set; } = int.MaxValue;
 
+        public Dictionary<Coordinates,Color> LastRelativeCoordinates;
+
         public Layer(string name, int width, int height)
         {
             Name = name;
@@ -115,18 +117,40 @@ namespace PixiEditor.Models.Layers
         /// <returns>Color of a pixel</returns>
         public Color GetPixelWithOffset(int x, int y)
         {
-            return LayerBitmap.GetPixel(x - OffsetX + 1, y - OffsetY + 1);
+            return GetPixel(x - OffsetX + 1, y - OffsetY + 1);
+        }
+
+        /// <summary>
+        ///     Returns pixel color on x and y.
+        /// </summary>
+        /// <param name="x">X coordinate</param>
+        /// <param name="y">Y Coordinate</param>
+        /// <returns>Color of pixel, if out of bounds, returns transparent pixel.</returns>
+        public Color GetPixel(int x, int y)
+        {
+            if (x > Width - 1 || x < 0 || y > Height - 1 || y < 0)
+            {
+                return System.Windows.Media.Colors.Transparent;
+            }
+
+            return LayerBitmap.GetPixel(x, y);
         }
 
         /// <summary>
         ///     Applies pixels to layer
         /// </summary>
-        /// <param name="pixels"></param>
-        public void ApplyPixels(BitmapPixelChanges pixels)
+        /// <param name="pixels">Pixels to apply</param>
+        /// <param name="dynamicResize">Resizes bitmap to fit content</param>
+        /// <param name="applyOffset">Converts pixels coordinates to relative to bitmap</param>
+        public void ApplyPixels(BitmapPixelChanges pixels, bool dynamicResize = true, bool applyOffset = true)
         {
             if (pixels.ChangedPixels == null || pixels.ChangedPixels.Count == 0) return;
-            DynamicResize(pixels);
-            pixels.ChangedPixels = ApplyOffset(pixels.ChangedPixels);
+            if(dynamicResize)
+                DynamicResize(pixels);
+            if(applyOffset)
+                pixels.ChangedPixels = ApplyOffset(pixels.ChangedPixels);
+            LastRelativeCoordinates = pixels.ChangedPixels;
+
             using (var ctx = LayerBitmap.GetBitmapContext())
             {
                 foreach (var coords in pixels.ChangedPixels)
@@ -146,12 +170,13 @@ namespace PixiEditor.Models.Layers
 
         public Coordinates[] ConvertToRelativeCoordinates(Coordinates[] nonRelativeCords)
         {
+            Coordinates[] result = new Coordinates[nonRelativeCords.Length];
             for (int i = 0; i < nonRelativeCords.Length; i++)
             {
-                nonRelativeCords[i] = new Coordinates(nonRelativeCords[i].X - OffsetX, nonRelativeCords[i].Y - OffsetY);
+                result[i] = new Coordinates(nonRelativeCords[i].X - OffsetX, nonRelativeCords[i].Y - OffsetY);
             }
 
-            return nonRelativeCords;
+            return result;
         }
 
         /// <summary>
@@ -168,13 +193,13 @@ namespace PixiEditor.Models.Layers
             int newMinX = minMaxCords.Coords1.X - OffsetX;
             int newMinY = minMaxCords.Coords1.Y - OffsetY;
 
-            if (pixels.ChangedPixels.First().Value.A != 0 && pixels.WasBuiltAsSingleColored)
+            if (!(pixels.WasBuiltAsSingleColored && pixels.ChangedPixels.First().Value.A == 0))
             {
                 if (newMaxX + 1 > Width || newMaxY + 1 > Height)
                 {
                     IncreaseSizeToBottom(newMaxX, newMaxY);
                 }
-                else if (newMinX < 0 || newMinY < 0)
+                if (newMinX < 0 || newMinY < 0)
                 {
                     IncreaseSizeToTop(newMinX, newMinY);
                 }

+ 5 - 0
PixiEditor/Models/Tools/BitmapPixelChanges.cs

@@ -22,6 +22,11 @@ namespace PixiEditor.Models.Tools
             WasBuiltAsSingleColored = false;
         }
 
+        public void UpdateChangedPixels(Dictionary<Coordinates, Color> changedPixels)
+        {
+            ChangedPixels = changedPixels;
+        }
+
         /// <summary>
         ///     Builds BitmapPixelChanges with only one color for specified coordinates
         /// </summary>