Browse Source

Fixed some bugs associated with MoveTool

flabbet 4 years ago
parent
commit
bc836ae5bd

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

@@ -22,6 +22,7 @@ namespace PixiEditor.Models.Controllers
     {
         private Document activeDocument;
         private Tool selectedTool;
+        private Coordinates? startPosition = null;
 
         public BitmapManager()
         {
@@ -114,6 +115,12 @@ namespace PixiEditor.Models.Controllers
         {
             if (SelectedTool.CanStartOutsideCanvas || clickedOnCanvas)
             {
+                if (startPosition == null)
+                {
+                    SelectedTool.OnStart(newPosition);
+                    startPosition = newPosition;
+                }
+
                 if (IsOperationTool(SelectedTool))
                 {
                     BitmapOperations.ExecuteTool(newPosition, MouseController.LastMouseMoveCoordinates.ToList(), (BitmapOperationTool)SelectedTool);
@@ -194,6 +201,8 @@ namespace PixiEditor.Models.Controllers
             {
                 BitmapOperations.ApplyPreviewLayer();
             }
+
+            startPosition = null;
         }
 
         private void HighlightPixels(Coordinates newPosition)

+ 39 - 12
PixiEditor/Models/Controllers/BitmapOperationsUtility.cs

@@ -12,6 +12,7 @@ using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Tools;
 using PixiEditor.Models.Undo;
+using PixiEditor.ViewModels;
 
 namespace PixiEditor.Models.Controllers
 {
@@ -87,20 +88,29 @@ namespace PixiEditor.Models.Controllers
                 return;
             }
 
-            foreach (var modifiedLayer in previewLayerChanges)
+            Layer[] layers = new Layer[previewLayerChanges.Count];
+
+            for (int i = 0; i < layers.Length; i++)
+            {
+                layers[i] = Manager.ActiveDocument.Layers.First(x => x.LayerGuid == previewLayerChanges[i].LayerGuid);
+            }
+
+            if (layers.Length > 0)
             {
-                Layer layer = Manager.ActiveDocument.Layers.FirstOrDefault(x => x.LayerGuid == modifiedLayer.LayerGuid);
+                IEnumerable<LayerChange> oldValues =
+                    ApplyToLayers(layers, previewLayerChanges.ToArray());
 
-                if (layer != null)
+                foreach (var oldValue in oldValues)
                 {
-                    BitmapPixelChanges oldValues = ApplyToLayer(layer, modifiedLayer).PixelChanges;
+                    var previewChanges = previewLayerChanges.First(x => x.LayerGuid == oldValue.LayerGuid);
 
                     BitmapChanged?.Invoke(this, new BitmapChangedEventArgs(
-                        modifiedLayer.PixelChanges,
-                        oldValues,
-                        modifiedLayer.LayerGuid));
-                    Manager.ActiveDocument.GeneratePreviewLayer();
+                        previewChanges.PixelChanges,
+                        oldValue.PixelChanges,
+                        previewChanges.LayerGuid));
                 }
+
+                Manager.ActiveDocument.GeneratePreviewLayer();
             }
 
             previewLayerChanges = null;
@@ -136,14 +146,31 @@ namespace PixiEditor.Models.Controllers
 
         private LayerChange ApplyToLayer(Layer layer, LayerChange change)
         {
-            layer.DynamicResize(change.PixelChanges);
+            return ApplyToLayers(new Layer[] { layer }, new LayerChange[] { change })[0];
+        }
 
-            LayerChange oldPixelsValues = new LayerChange(
+        private LayerChange[] ApplyToLayers(Layer[] layers, LayerChange[] changes)
+        {
+            LayerChange[] oldPixelValues = new LayerChange[changes.Length];
+            for (int i = 0; i < layers.Length; i++)
+            {
+                Layer layer = layers[i];
+                LayerChange change = changes.First(x => x.LayerGuid == layer.LayerGuid);
+                layer.DynamicResize(change.PixelChanges);
+
+                oldPixelValues[i] = new LayerChange(
                 GetOldPixelsValues(change.PixelChanges.ChangedPixels.Keys.ToArray()),
                 change.LayerGuid);
+            }
+
+            for (int i = 0; i < layers.Length; i++)
+            {
+                Layer layer = layers[i];
+                LayerChange change = changes.First(x => x.LayerGuid == layer.LayerGuid);
+                layer.SetPixels(change.PixelChanges, false);
+            }
 
-            layer.SetPixels(change.PixelChanges, false);
-            return oldPixelsValues;
+            return oldPixelValues;
         }
 
         private bool MouseCordsNotInLine(List<Coordinates> cords)

+ 1 - 1
PixiEditor/Models/ImageManipulation/BitmapUtils.cs

@@ -108,7 +108,7 @@ namespace PixiEditor.Models.ImageManipulation
 
         public static Dictionary<Guid, Color[]> GetPixelsForSelection(Layer[] layers, Coordinates[] selection)
         {
-            Dictionary<Guid, Color[]> result = new Dictionary<Guid, Color[]>();
+            Dictionary<Guid, Color[]> result = new ();
 
             foreach (Layer layer in layers)
             {

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

@@ -2,6 +2,7 @@
 using System.Windows.Input;
 using PixiEditor.Helpers;
 using PixiEditor.Models.Controllers;
+using PixiEditor.Models.Position;
 using PixiEditor.Models.Tools.ToolSettings;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
 
@@ -74,6 +75,10 @@ namespace PixiEditor.Models.Tools
         {
         }
 
+        public virtual void OnStart(Coordinates clickPosition)
+        {
+        }
+
         public virtual void OnRecordingLeftMouseDown(MouseEventArgs e)
         {
         }

+ 52 - 50
PixiEditor/Models/Tools/Tools/MoveTool.cs

@@ -58,23 +58,28 @@ namespace PixiEditor.Models.Tools.Tools
         }
 
         public override void AfterAddedUndo(UndoManager undoManager)
-        {
-            if (currentSelection != null && currentSelection.Length != 0)
-            {
-                // Inject to default undo system change custom changes made by this tool
-                foreach (var item in startPixelColors)
-                {
-                    BitmapPixelChanges beforeMovePixels = BitmapPixelChanges.FromArrays(startSelection, item.Value);
-                    Change changes = undoManager.UndoStack.Peek();
-                    Guid layerGuid = item.Key;
-
-                    ((LayerChange[])changes.OldValue).First(x => x.LayerGuid == layerGuid).PixelChanges.ChangedPixels
-                        .AddRangeOverride(beforeMovePixels.ChangedPixels);
-
-                    ((LayerChange[])changes.NewValue).First(x => x.LayerGuid == layerGuid).PixelChanges.ChangedPixels
-                        .AddRangeNewOnly(BitmapPixelChanges
-                            .FromSingleColoredArray(startSelection, System.Windows.Media.Colors.Transparent)
-                            .ChangedPixels);
+        {
+            if (currentSelection != null && currentSelection.Length > 0)
+            {
+                Change changes = undoManager.UndoStack.Peek();
+
+                // Inject to default undo system change custom changes made by this tool
+                foreach (var item in startPixelColors)
+                {
+                    BitmapPixelChanges beforeMovePixels = BitmapPixelChanges.FromArrays(startSelection, item.Value);
+                    Guid layerGuid = item.Key;
+                    var oldValue = (LayerChange[])changes.OldValue;
+
+                    if (oldValue.Any(x => x.LayerGuid == layerGuid))
+                    {
+                        oldValue.First(x => x.LayerGuid == layerGuid).PixelChanges.ChangedPixels
+                            .AddRangeOverride(beforeMovePixels.ChangedPixels);
+
+                        ((LayerChange[])changes.NewValue).First(x => x.LayerGuid == layerGuid).PixelChanges.ChangedPixels
+                            .AddRangeNewOnly(BitmapPixelChanges
+                                .FromSingleColoredArray(startSelection, System.Windows.Media.Colors.Transparent)
+                                .ChangedPixels);
+                    }
                 }
             }
         }
@@ -94,42 +99,39 @@ namespace PixiEditor.Models.Tools.Tools
             }
         }
 
-        public override LayerChange[] Use(Layer layer, Coordinates[] mouseMove, Color color)
-        {
-            Coordinates start = mouseMove[^1];
+        public override void OnStart(Coordinates startPos)
+        {
+            ResetSelectionValues(startPos);
 
-            // I am aware that this could be moved to OnMouseDown, but it is executed before Use, so I didn't want to complicate for now
-            if (lastStartMousePos != start)
-            {
-                ResetSelectionValues(start);
-
-                // Move offset if no selection
-                Selection selection = ViewModelMain.Current.BitmapManager.ActiveDocument.ActiveSelection;
-                if (selection != null && selection.SelectedPoints.Count > 0)
-                {
-                    currentSelection = selection.SelectedPoints.ToArray();
-                }
-                else
-                {
-                    currentSelection = Array.Empty<Coordinates>();
-                }
-
-                if (Keyboard.IsKeyDown(Key.LeftCtrl) || MoveAll)
-                {
-                    affectedLayers = ViewModelMain.Current.BitmapManager.ActiveDocument.Layers.Where(x => x.IsVisible)
-                        .ToArray();
-                }
-                else
-                {
-                    affectedLayers = ViewModelMain.Current.BitmapManager.ActiveDocument
-                        .Layers.Where(x => x.IsActive && x.IsVisible).ToArray();
-                }
+            // Move offset if no selection
+            Selection selection = ViewModelMain.Current.BitmapManager.ActiveDocument.ActiveSelection;
+            if (selection != null && selection.SelectedPoints.Count > 0)
+            {
+                currentSelection = selection.SelectedPoints.ToArray();
+            }
+            else
+            {
+                currentSelection = Array.Empty<Coordinates>();
+            }
 
-                startSelection = currentSelection;
-                startPixelColors = BitmapUtils.GetPixelsForSelection(affectedLayers, startSelection);
-                startingOffsets = GetOffsets(affectedLayers);
-            }
+            if (Keyboard.IsKeyDown(Key.LeftCtrl) || MoveAll)
+            {
+                affectedLayers = ViewModelMain.Current.BitmapManager.ActiveDocument.Layers.Where(x => x.IsVisible)
+                    .ToArray();
+            }
+            else
+            {
+                affectedLayers = ViewModelMain.Current.BitmapManager.ActiveDocument
+                    .Layers.Where(x => x.IsActive && x.IsVisible).ToArray();
+            }
+
+            startSelection = currentSelection;
+            startPixelColors = BitmapUtils.GetPixelsForSelection(affectedLayers, startSelection);
+            startingOffsets = GetOffsets(affectedLayers);
+        }
 
+        public override LayerChange[] Use(Layer layer, Coordinates[] mouseMove, Color color)
+        {
             LayerChange[] result = new LayerChange[affectedLayers.Length];
             var end = mouseMove[0];
             for (int i = 0; i < affectedLayers.Length; i++)