Browse Source

Move tool wip

Equbuxu 3 years ago
parent
commit
8e5fbb66a6

+ 1 - 1
PixiEditor/Models/Controllers/ClipboardController.cs

@@ -34,7 +34,7 @@ namespace PixiEditor.Models.Controllers
         public static void CopyToClipboard(Layer[] layers, Coordinates[] selection, int originalImageWidth, int originalImageHeight, SerializableDocument document = null)
         public static void CopyToClipboard(Layer[] layers, Coordinates[] selection, int originalImageWidth, int originalImageHeight, SerializableDocument document = null)
         {
         {
             Clipboard.Clear();
             Clipboard.Clear();
-            using Surface surface = BitmapUtils.CombineLayers(originalImageWidth, originalImageHeight, layers);
+            using Surface surface = BitmapUtils.CombineLayers(new Int32Rect(0, 0, originalImageWidth, originalImageHeight), layers);
             DataObject data = new DataObject();
             DataObject data = new DataObject();
 
 
             WriteableBitmap combinedBitmaps = surface.ToWriteableBitmap();
             WriteableBitmap combinedBitmaps = surface.ToWriteableBitmap();

+ 5 - 0
PixiEditor/Models/DataHolders/Selection.cs

@@ -57,6 +57,11 @@ namespace PixiEditor.Models.DataHolders
             SelectionLayer.SetPixels(BitmapPixelChanges.FromSingleColoredArray(selection, selectionColor));
             SelectionLayer.SetPixels(BitmapPixelChanges.FromSingleColoredArray(selection, selectionColor));
         }
         }
 
 
+        public void TranslateSelection(int dX, int dY)
+        {
+            //TODO implement
+        }
+
         public void SetSelection(Int32Rect rect, bool isCirclular, SelectionType mode)
         public void SetSelection(Int32Rect rect, bool isCirclular, SelectionType mode)
         {
         {
             using SKPaint paint = new()
             using SKPaint paint = new()

+ 11 - 3
PixiEditor/Models/ImageManipulation/BitmapUtils.cs

@@ -9,6 +9,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Runtime.CompilerServices;
 using System.Runtime.CompilerServices;
+using System.Windows;
 using System.Windows.Media;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Media.Imaging;
 
 
@@ -16,9 +17,9 @@ namespace PixiEditor.Models.ImageManipulation
 {
 {
     public static class BitmapUtils
     public static class BitmapUtils
     {
     {
-        public static Surface CombineLayers(int width, int height, IEnumerable<Layer> layers, LayerStructure structure = null)
+        public static Surface CombineLayers(Int32Rect portion, IEnumerable<Layer> layers,  LayerStructure structure = null)
         {
         {
-            Surface finalSurface = new(width, height);
+            Surface finalSurface = new(portion.Width, portion.Height);
             using SKPaint paint = new();
             using SKPaint paint = new();
 
 
             for (int i = 0; i < layers.Count(); i++)
             for (int i = 0; i < layers.Count(); i++)
@@ -34,7 +35,14 @@ namespace PixiEditor.Models.ImageManipulation
                     throw new InvalidOperationException("Layers must not extend beyond canvas borders");
                     throw new InvalidOperationException("Layers must not extend beyond canvas borders");
                 }
                 }
 
 
-                layer.LayerBitmap.SkiaSurface.Draw(finalSurface.SkiaSurface.Canvas, layer.OffsetX, layer.OffsetY, paint);
+                using SKImage snapshot = layer.LayerBitmap.SkiaSurface.Snapshot();
+                int x = portion.X - layer.OffsetX;
+                int y = portion.Y - layer.OffsetY;
+                finalSurface.SkiaSurface.Canvas.DrawImage(
+                    snapshot,
+                    new SKRect(x, y, portion.Width + x, portion.Height + y),
+                    new SKRect(0, 0, portion.Width, portion.Height),
+                    paint);
             }
             }
 
 
             return finalSurface;
             return finalSurface;

+ 1 - 1
PixiEditor/Models/Layers/LayerHelper.cs

@@ -69,7 +69,7 @@ namespace PixiEditor.Models.Layers
             int height = yCloser.Height + offsetY + yOther.Height;
             int height = yCloser.Height + offsetY + yOther.Height;
 
 
             // Merge both layers into a bitmap
             // Merge both layers into a bitmap
-            Surface mergedBitmap = BitmapUtils.CombineLayers((int)documentsSize.X, (int)documentsSize.Y, new Layer[] { thisLayer, otherLayer });
+            Surface mergedBitmap = BitmapUtils.CombineLayers(new Int32Rect(0, 0, (int)documentsSize.X, (int)documentsSize.Y), new Layer[] { thisLayer, otherLayer });
             mergedBitmap = mergedBitmap.Crop(xCloser.OffsetX, yCloser.OffsetY, width, height);
             mergedBitmap = mergedBitmap.Crop(xCloser.OffsetX, yCloser.OffsetY, width, height);
 
 
             // Create the new layer with the merged bitmap
             // Create the new layer with the merged bitmap

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

@@ -92,10 +92,6 @@ namespace PixiEditor.Models.Tools
         {
         {
         }
         }
 
 
-        public virtual void AfterAddedUndo(UndoManager undoManager)
-        {
-        }
-
         public virtual void OnSelected()
         public virtual void OnSelected()
         {
         {
         }
         }

+ 5 - 1
PixiEditor/Models/Tools/Tools/MagicWandTool.cs

@@ -11,6 +11,7 @@ using PixiEditor.ViewModels;
 using SkiaSharp;
 using SkiaSharp;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Collections.ObjectModel;
+using System.Windows;
 using System.Windows.Input;
 using System.Windows.Input;
 
 
 namespace PixiEditor.Models.Tools.Tools
 namespace PixiEditor.Models.Tools.Tools
@@ -93,7 +94,10 @@ namespace PixiEditor.Models.Tools.Tools
 
 
         private void ValidateCache(Document document)
         private void ValidateCache(Document document)
         {
         {
-            cachedDocument ??= new Layer("_CombinedLayers", BitmapUtils.CombineLayers(document.Width, document.Height, document.Layers, document.LayerStructure));
+            cachedDocument ??= new Layer("_CombinedLayers", BitmapUtils.CombineLayers(
+                new Int32Rect(0, 0, document.Width, document.Height),
+                document.Layers,
+                document.LayerStructure));
         }
         }
     }
     }
 }
 }

+ 147 - 110
PixiEditor/Models/Tools/Tools/MoveTool.cs

@@ -2,6 +2,7 @@
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.Enums;
 using PixiEditor.Models.Enums;
 using PixiEditor.Models.ImageManipulation;
 using PixiEditor.Models.ImageManipulation;
+using PixiEditor.Models.IO;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Undo;
 using PixiEditor.Models.Undo;
@@ -9,6 +10,8 @@ using PixiEditor.ViewModels;
 using SkiaSharp;
 using SkiaSharp;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Windows;
 using System.Windows;
 using System.Windows.Input;
 using System.Windows.Input;
@@ -19,21 +22,29 @@ namespace PixiEditor.Models.Tools.Tools
     public class MoveTool : BitmapOperationTool
     public class MoveTool : BitmapOperationTool
     {
     {
         private Layer[] affectedLayers;
         private Layer[] affectedLayers;
-        private Dictionary<Guid, bool> clearedPixels = new Dictionary<Guid, bool>();
-        private Coordinates[] currentSelection;
-        private Coordinates lastMouseMove;
-        private Dictionary<Guid, SKColor[]> startPixelColors;
-        private Dictionary<Guid, SKColor[]> endPixelColors;
-        private Dictionary<Guid, Thickness> startingOffsets;
-        private Coordinates[] startSelection;
-        private bool updateViewModelSelection = true;
+        private Surface previewLayerData;
+        private SKPaint maskingPaint = new()
+        {
+            BlendMode = SKBlendMode.DstIn,
+        };
+        private Coordinates moveStartPos;
+        private Int32Rect moveStartRect;
+
+        //private Dictionary<Guid, bool> clearedPixels = new Dictionary<Guid, bool>();
+        //private Coordinates[] currentSelection;
+        //private Coordinates lastMouseMove;
+        //private Dictionary<Guid, SKColor[]> startPixelColors;
+        //private Dictionary<Guid, SKColor[]> endPixelColors;
+        //private Dictionary<Guid, Thickness> startingOffsets;
+        //private Coordinates[] startSelection;
+        //private bool updateViewModelSelection = true;
 
 
         public MoveTool(BitmapManager bitmapManager)
         public MoveTool(BitmapManager bitmapManager)
         {
         {
             ActionDisplay = "Hold mouse to move selected pixels. Hold Ctrl to move all layers.";
             ActionDisplay = "Hold mouse to move selected pixels. Hold Ctrl to move all layers.";
             Cursor = Cursors.Arrow;
             Cursor = Cursors.Arrow;
             RequiresPreviewLayer = true;
             RequiresPreviewLayer = true;
-            UseDefaultUndoMethod = true;
+            UseDefaultUndoMethod = false;
 
 
             BitmapManager = bitmapManager;
             BitmapManager = bitmapManager;
         }
         }
@@ -62,7 +73,7 @@ namespace PixiEditor.Models.Tools.Tools
             }
             }
         }
         }
 
 
-        public override void AfterAddedUndo(UndoManager undoManager)
+        public void AfterAddedUndo(UndoManager undoManager)
         {
         {
             //if (currentSelection == null || currentSelection.Length == 0)
             //if (currentSelection == null || currentSelection.Length == 0)
             //{
             //{
@@ -92,25 +103,26 @@ namespace PixiEditor.Models.Tools.Tools
 
 
         // This adds undo if there is no selection, reason why this isn't in AfterUndoAdded,
         // This adds undo if there is no selection, reason why this isn't in AfterUndoAdded,
         // is because it doesn't fire if no pixel changes were made.
         // is because it doesn't fire if no pixel changes were made.
-        public override void OnStoppedRecordingMouseUp(MouseEventArgs e)
-        {
-            if (currentSelection != null && currentSelection.Length == 0)
-            {
-                BitmapManager.ActiveDocument.UndoManager.AddUndoChange(new Change(
-                    ApplyOffsets,
-                    new object[] { startingOffsets },
-                    ApplyOffsets,
-                    new object[] { GetOffsets(affectedLayers) },
-                    "Move layers"));
-            }
-        }
+        //public override void OnStoppedRecordingMouseUp(MouseEventArgs e)
+        //{
+        //    if (currentSelection != null && currentSelection.Length == 0)
+        //    {
+        //        BitmapManager.ActiveDocument.UndoManager.AddUndoChange(new Change(
+        //            ApplyOffsets,
+        //            new object[] { startingOffsets },
+        //            ApplyOffsets,
+        //            new object[] { GetOffsets(affectedLayers) },
+        //            "Move layers"));
+        //    }
+        //}
 
 
         public override void OnStart(Coordinates startPos)
         public override void OnStart(Coordinates startPos)
         {
         {
-            ResetSelectionValues(startPos);
+            //ResetSelectionValues(startPos);
             // Move offset if no selection
             // Move offset if no selection
             Document doc = BitmapManager.ActiveDocument;
             Document doc = BitmapManager.ActiveDocument;
             Selection selection = doc.ActiveSelection;
             Selection selection = doc.ActiveSelection;
+            /*
             if (selection != null && selection.SelectedPoints.Count > 0)
             if (selection != null && selection.SelectedPoints.Count > 0)
             {
             {
                 currentSelection = selection.SelectedPoints.ToArray();
                 currentSelection = selection.SelectedPoints.ToArray();
@@ -118,7 +130,7 @@ namespace PixiEditor.Models.Tools.Tools
             else
             else
             {
             {
                 currentSelection = Array.Empty<Coordinates>();
                 currentSelection = Array.Empty<Coordinates>();
-            }
+            }*/
             if (Keyboard.IsKeyDown(Key.LeftCtrl) || MoveAll)
             if (Keyboard.IsKeyDown(Key.LeftCtrl) || MoveAll)
             {
             {
                 affectedLayers = doc.Layers.Where(x => x.IsVisible).ToArray();
                 affectedLayers = doc.Layers.Where(x => x.IsVisible).ToArray();
@@ -127,111 +139,136 @@ namespace PixiEditor.Models.Tools.Tools
             {
             {
                 affectedLayers = doc.Layers.Where(x => x.IsActive && doc.GetFinalLayerIsVisible(x)).ToArray();
                 affectedLayers = doc.Layers.Where(x => x.IsActive && doc.GetFinalLayerIsVisible(x)).ToArray();
             }
             }
-            startSelection = currentSelection;
-            startPixelColors = BitmapUtils.GetPixelsForSelection(affectedLayers, startSelection);
-            startingOffsets = GetOffsets(affectedLayers);
+
+
+            Layer selLayer = selection.SelectionLayer;
+            moveStartRect = new(selLayer.OffsetX, selLayer.OffsetY, selLayer.Width, selLayer.Height);
+            previewLayerData?.Dispose();
+            previewLayerData = BitmapUtils.CombineLayers(moveStartRect, affectedLayers, BitmapManager.ActiveDocument.LayerStructure);
+            using var selSnap = selLayer.LayerBitmap.SkiaSurface.Snapshot();
+            previewLayerData.SkiaSurface.Canvas.DrawImage(selSnap, -moveStartRect.X, -moveStartRect.Y, maskingPaint);
+
+            moveStartPos = startPos;
+            //startSelection = currentSelection;
+            //startPixelColors = BitmapUtils.GetPixelsForSelection(affectedLayers, startSelection);
+            //startingOffsets = GetOffsets(affectedLayers);
         }
         }
 
 
         public override void Use(Layer layer, List<Coordinates> mouseMove, SKColor color)
         public override void Use(Layer layer, List<Coordinates> mouseMove, SKColor color)
         {
         {
             //LayerChange[] result = new LayerChange[affectedLayers.Length];
             //LayerChange[] result = new LayerChange[affectedLayers.Length];
-            //var end = mouseMove[0];
-            //var lastSelection = currentSelection.ToArray();
-            //for (int i = 0; i < affectedLayers.Length; i++)
-            //{
-            //    if (currentSelection.Length > 0)
-            //    {
-            //        endPixelColors = BitmapUtils.GetPixelsForSelection(affectedLayers, currentSelection);
-            //        var changes = MoveSelection(affectedLayers[i], mouseMove);
-            //        ClearSelectedPixels(affectedLayers[i], lastSelection);
 
 
-            //        changes = RemoveTransparentPixels(changes);
 
 
-            //        result[i] = new LayerChange(changes, affectedLayers[i]);
-            //    }
-            //    else
-            //    {
-            //        var vector = Transform.GetTranslation(lastMouseMove, end);
-            //        affectedLayers[i].Offset = new Thickness(affectedLayers[i].OffsetX + vector.X, affectedLayers[i].OffsetY + vector.Y, 0, 0);
-            //        result[i] = new LayerChange(BitmapPixelChanges.Empty, affectedLayers[i]);
-            //    }
-            //}
+            Coordinates newPos = mouseMove[0];
+            int dX = newPos.X - moveStartPos.X;
+            int dY = newPos.Y - moveStartPos.Y;
 
 
-            //lastMouseMove = end;
+            int newX = moveStartRect.X + dX;
+            int newY = moveStartRect.Y + dY;
+            
+            
+            layer.DynamicResizeAbsolute(newX + moveStartRect.Width, newY + moveStartRect.Height, newX, newY);
+            previewLayerData.SkiaSurface.Draw(layer.LayerBitmap.SkiaSurface.Canvas, newX - layer.OffsetX, newY - layer.OffsetY, Surface.ReplacingPaint);
+            layer.InvokeLayerBitmapChange(new Int32Rect(newX, newY, moveStartRect.Width, moveStartRect.Height));
+            
 
 
-            // return result;
-        }
-        public BitmapPixelChanges MoveSelection(Layer layer, IEnumerable<Coordinates> mouseMove)
-        {
-            Coordinates end = mouseMove.First();
-
-            currentSelection = TranslateSelection(end);
-            if (updateViewModelSelection)
+            /*var end = mouseMove[0];
+            var lastSelection = currentSelection.ToArray();
+            for (int i = 0; i < affectedLayers.Length; i++)
             {
             {
-                ViewModelMain.Current.BitmapManager.ActiveDocument.ActiveSelection.SetSelection(currentSelection, SelectionType.New);
+                if (currentSelection.Length > 0)
+                {
+                    endPixelColors = BitmapUtils.GetPixelsForSelection(affectedLayers, currentSelection);
+                    var changes = MoveSelection(affectedLayers[i], mouseMove);
+                    ClearSelectedPixels(affectedLayers[i], lastSelection);
+
+                    changes = RemoveTransparentPixels(changes);
+
+                    result[i] = new LayerChange(changes, affectedLayers[i]);
+                }
+                else
+                {
+                    var vector = Transform.GetTranslation(lastMouseMove, end);
+                    affectedLayers[i].Offset = new Thickness(affectedLayers[i].OffsetX + vector.X, affectedLayers[i].OffsetY + vector.Y, 0, 0);
+                    result[i] = new LayerChange(BitmapPixelChanges.Empty, affectedLayers[i]);
+                }
             }
             }
+
             lastMouseMove = end;
             lastMouseMove = end;
-            return BitmapPixelChanges.FromArrays(currentSelection, startPixelColors[layer.LayerGuid]);
-        }
-        private void ApplyOffsets(object[] parameters)
-        {
-            Dictionary<Guid, Thickness> offsets = (Dictionary<Guid, Thickness>)parameters[0];
-            foreach (var offset in offsets)
-            {
-                Layer layer = ViewModelMain.Current?.BitmapManager?.
-                    ActiveDocument?.Layers?.First(x => x.LayerGuid == offset.Key);
-                layer.Offset = offset.Value;
-            }
+
+            return result;*/
         }
         }
+        //public BitmapPixelChanges MoveSelection(Layer layer, IEnumerable<Coordinates> mouseMove)
+        //{
+        //    Coordinates end = mouseMove.First();
 
 
-        private Dictionary<Guid, Thickness> GetOffsets(Layer[] layers)
-        {
-            Dictionary<Guid, Thickness> dict = new Dictionary<Guid, Thickness>();
-            for (int i = 0; i < layers.Length; i++)
-            {
-                dict.Add(layers[i].LayerGuid, layers[i].Offset);
-            }
+        //    currentSelection = TranslateSelection(end);
+        //    if (updateViewModelSelection)
+        //    {
+        //        ViewModelMain.Current.BitmapManager.ActiveDocument.ActiveSelection.SetSelection(currentSelection, SelectionType.New);
+        //    }
+        //    lastMouseMove = end;
+        //    return BitmapPixelChanges.FromArrays(currentSelection, startPixelColors[layer.LayerGuid]);
+        //}
+        //private void ApplyOffsets(object[] parameters)
+        //{
+        //    Dictionary<Guid, Thickness> offsets = (Dictionary<Guid, Thickness>)parameters[0];
+        //    foreach (var offset in offsets)
+        //    {
+        //        Layer layer = ViewModelMain.Current?.BitmapManager?.
+        //            ActiveDocument?.Layers?.First(x => x.LayerGuid == offset.Key);
+        //        layer.Offset = offset.Value;
+        //    }
+        //}
 
 
-            return dict;
-        }
+        //private Dictionary<Guid, Thickness> GetOffsets(Layer[] layers)
+        //{
+        //    Dictionary<Guid, Thickness> dict = new Dictionary<Guid, Thickness>();
+        //    for (int i = 0; i < layers.Length; i++)
+        //    {
+        //        dict.Add(layers[i].LayerGuid, layers[i].Offset);
+        //    }
 
 
-        private BitmapPixelChanges RemoveTransparentPixels(BitmapPixelChanges pixels)
-        {
-            foreach (var item in pixels.ChangedPixels.Where(x => x.Value.Alpha == 0).ToList())
-            {
-                pixels.ChangedPixels.Remove(item.Key);
-            }
-            return pixels;
-        }
+        //    return dict;
+        //}
 
 
-        private void ResetSelectionValues(Coordinates start)
-        {
-            lastMouseMove = start;
-            clearedPixels = new Dictionary<Guid, bool>();
-            endPixelColors = new Dictionary<Guid, SKColor[]>();
-            currentSelection = null;
-            affectedLayers = null;
-            updateViewModelSelection = true;
-            startPixelColors = null;
-            startSelection = null;
-        }
+        //private BitmapPixelChanges RemoveTransparentPixels(BitmapPixelChanges pixels)
+        //{
+        //    foreach (var item in pixels.ChangedPixels.Where(x => x.Value.Alpha == 0).ToList())
+        //    {
+        //        pixels.ChangedPixels.Remove(item.Key);
+        //    }
+        //    return pixels;
+        //}
 
 
-        private Coordinates[] TranslateSelection(Coordinates end)
-        {
-            Coordinates translation = Transform.GetTranslation(lastMouseMove, end);
-            return Transform.Translate(currentSelection, translation);
-        }
+        //private void ResetSelectionValues(Coordinates start)
+        //{
+        //    lastMouseMove = start;
+        //    clearedPixels = new Dictionary<Guid, bool>();
+        //    endPixelColors = new Dictionary<Guid, SKColor[]>();
+        //    currentSelection = null;
+        //    affectedLayers = null;
+        //    updateViewModelSelection = true;
+        //    startPixelColors = null;
+        //    startSelection = null;
+        //}
 
 
-        private void ClearSelectedPixels(Layer layer, Coordinates[] selection)
-        {
-            Guid layerGuid = layer.LayerGuid;
-            if (!clearedPixels.ContainsKey(layerGuid) || clearedPixels[layerGuid] == false)
-            {
-                BitmapManager.ActiveDocument.Layers.First(x => x == layer)
-                    .SetPixels(BitmapPixelChanges.FromSingleColoredArray(selection, SKColors.Transparent));
+        //private Coordinates[] TranslateSelection(Coordinates end)
+        //{
+        //    Coordinates translation = Transform.GetTranslation(lastMouseMove, end);
+        //    return Transform.Translate(currentSelection, translation);
+        //}
 
 
-                clearedPixels[layerGuid] = true;
-            }
-        }
+        //private void ClearSelectedPixels(Layer layer, Coordinates[] selection)
+        //{
+        //    Guid layerGuid = layer.LayerGuid;
+        //    if (!clearedPixels.ContainsKey(layerGuid) || clearedPixels[layerGuid] == false)
+        //    {
+        //        BitmapManager.ActiveDocument.Layers.First(x => x == layer)
+        //            .SetPixels(BitmapPixelChanges.FromSingleColoredArray(selection, SKColors.Transparent));
+
+        //        clearedPixels[layerGuid] = true;
+        //    }
+        //}
     }
     }
 }
 }

+ 0 - 1
PixiEditor/ViewModels/SubViewModels/Main/UndoViewModel.cs

@@ -34,7 +34,6 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
             if (activeDoc is null) return;
             if (activeDoc is null) return;
 
 
             selectedTool.AddUndoProcess(activeDoc);
             selectedTool.AddUndoProcess(activeDoc);
-            selectedTool.AfterAddedUndo(activeDoc.UndoManager);
         }
         }
 
 
         /// <summary>
         /// <summary>