Browse Source

Move tool still wip

Equbuxu 3 years ago
parent
commit
9c933b02c9

+ 4 - 1
Custom.ruleset

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <?xml version="1.0" encoding="utf-8"?>
-<RuleSet Name="Name" Description="Description" ToolsVersion="16.0">
+<RuleSet Name="Name" Description="Description" ToolsVersion="17.0">
   <Rules AnalyzerId="Microsoft.CodeAnalysis.CSharp" RuleNamespace="Microsoft.CodeAnalysis.CSharp">
   <Rules AnalyzerId="Microsoft.CodeAnalysis.CSharp" RuleNamespace="Microsoft.CodeAnalysis.CSharp">
     <Rule Id="AD0001" Action="None" />
     <Rule Id="AD0001" Action="None" />
   </Rules>
   </Rules>
@@ -19,6 +19,7 @@
     <Rule Id="SA1005" Action="None" />
     <Rule Id="SA1005" Action="None" />
     <Rule Id="SA1008" Action="None" />
     <Rule Id="SA1008" Action="None" />
     <Rule Id="SA1009" Action="None" />
     <Rule Id="SA1009" Action="None" />
+    <Rule Id="SA1028" Action="None" />
     <Rule Id="SA1101" Action="None" />
     <Rule Id="SA1101" Action="None" />
     <Rule Id="SA1110" Action="None" />
     <Rule Id="SA1110" Action="None" />
     <Rule Id="SA1111" Action="None" />
     <Rule Id="SA1111" Action="None" />
@@ -35,6 +36,8 @@
     <Rule Id="SA1139" Action="None" />
     <Rule Id="SA1139" Action="None" />
     <Rule Id="SA1200" Action="None" />
     <Rule Id="SA1200" Action="None" />
     <Rule Id="SA1201" Action="None" />
     <Rule Id="SA1201" Action="None" />
+    <Rule Id="SA1202" Action="None" />
+    <Rule Id="SA1204" Action="None" />
     <Rule Id="SA1207" Action="None" />
     <Rule Id="SA1207" Action="None" />
     <Rule Id="SA1208" Action="None" />
     <Rule Id="SA1208" Action="None" />
     <Rule Id="SA1209" Action="None" />
     <Rule Id="SA1209" Action="None" />

+ 6 - 2
PixiEditor/Models/DataHolders/Selection.cs

@@ -21,7 +21,7 @@ namespace PixiEditor.Models.DataHolders
         {
         {
             SelectedPoints = new ObservableCollection<Coordinates>(selectedPoints);
             SelectedPoints = new ObservableCollection<Coordinates>(selectedPoints);
             SelectionLayer = new Layer("_selectionLayer");
             SelectionLayer = new Layer("_selectionLayer");
-            selectionBlue = new SKColor(142, 202, 255, 127);
+            selectionBlue = new SKColor(142, 202, 255, 255);
         }
         }
 
 
         public ObservableCollection<Coordinates> SelectedPoints { get; private set; }
         public ObservableCollection<Coordinates> SelectedPoints { get; private set; }
@@ -59,7 +59,11 @@ namespace PixiEditor.Models.DataHolders
 
 
         public void TranslateSelection(int dX, int dY)
         public void TranslateSelection(int dX, int dY)
         {
         {
-            //TODO implement
+            selectionLayer.Offset = new Thickness(selectionLayer.OffsetX + dX, selectionLayer.OffsetY + dY, 0, 0);
+            for (int i = 0; i < SelectedPoints.Count; i++)
+            {
+                SelectedPoints[i] = new Coordinates(SelectedPoints[i].X + dX, SelectedPoints[i].Y + dY);
+            }
         }
         }
 
 
         public void SetSelection(Int32Rect rect, bool isCirclular, SelectionType mode)
         public void SetSelection(Int32Rect rect, bool isCirclular, SelectionType mode)

+ 8 - 8
PixiEditor/Models/Layers/Layer.cs

@@ -336,14 +336,14 @@ namespace PixiEditor.Models.Layers
                 return;
                 return;
             }
             }
 
 
-            if (dynamicResize)
+            if (applyOffset)
             {
             {
-                DynamicResize(pixels);
+                pixels.ChangedPixels = GetRelativePosition(pixels.ChangedPixels);
             }
             }
 
 
-            if (applyOffset)
+            if (dynamicResize)
             {
             {
-                pixels.ChangedPixels = GetRelativePosition(pixels.ChangedPixels);
+                DynamicResize(pixels);
             }
             }
 
 
             LastRelativeCoordinates = pixels.ChangedPixels;
             LastRelativeCoordinates = pixels.ChangedPixels;
@@ -409,10 +409,10 @@ namespace PixiEditor.Models.Layers
             ResetOffset(pixels);
             ResetOffset(pixels);
             Tuple<DoubleCoords, bool> borderData = ExtractBorderData(pixels);
             Tuple<DoubleCoords, bool> borderData = ExtractBorderData(pixels);
             DoubleCoords minMaxCords = borderData.Item1;
             DoubleCoords minMaxCords = borderData.Item1;
-            int newMaxX = minMaxCords.Coords2.X - OffsetX;
-            int newMaxY = minMaxCords.Coords2.Y - OffsetY;
-            int newMinX = minMaxCords.Coords1.X - OffsetX;
-            int newMinY = minMaxCords.Coords1.Y - OffsetY;
+            int newMaxX = minMaxCords.Coords2.X;
+            int newMaxY = minMaxCords.Coords2.Y;
+            int newMinX = minMaxCords.Coords1.X;
+            int newMinY = minMaxCords.Coords1.Y;
 
 
             if (!(pixels.WasBuiltAsSingleColored && pixels.ChangedPixels.First().Value.Alpha == 0))
             if (!(pixels.WasBuiltAsSingleColored && pixels.ChangedPixels.First().Value.Alpha == 0))
             {
             {

+ 0 - 1
PixiEditor/Models/Tools/BitmapOperationTool.cs

@@ -22,7 +22,6 @@ namespace PixiEditor.Models.Tools
 
 
         private StorageBasedChange _change;
         private StorageBasedChange _change;
 
 
-
         public abstract void Use(Layer layer, List<Coordinates> mouseMove, SKColor color);
         public abstract void Use(Layer layer, List<Coordinates> mouseMove, SKColor color);
 
 
         /// <summary>
         /// <summary>

+ 122 - 17
PixiEditor/Models/Tools/Tools/MoveTool.cs

@@ -21,15 +21,27 @@ namespace PixiEditor.Models.Tools.Tools
 {
 {
     public class MoveTool : BitmapOperationTool
     public class MoveTool : BitmapOperationTool
     {
     {
-        private Layer[] affectedLayers;
-        private Surface previewLayerData;
-        private SKPaint maskingPaint = new()
+        private static readonly SKPaint maskingPaint = new()
         {
         {
             BlendMode = SKBlendMode.DstIn,
             BlendMode = SKBlendMode.DstIn,
         };
         };
+
+        private static readonly SKPaint inverseMaskingPaint = new()
+        {
+            BlendMode = SKBlendMode.DstOut,
+        };
+
+        private Layer[] affectedLayers;
+        private Surface[] currentlyDragged;
+        private Surface previewLayerData;
+        
         private Coordinates moveStartPos;
         private Coordinates moveStartPos;
         private Int32Rect moveStartRect;
         private Int32Rect moveStartRect;
 
 
+        private Coordinates lastDragDelta;
+
+        private StorageBasedChange change;
+
         //private Dictionary<Guid, bool> clearedPixels = new Dictionary<Guid, bool>();
         //private Dictionary<Guid, bool> clearedPixels = new Dictionary<Guid, bool>();
         //private Coordinates[] currentSelection;
         //private Coordinates[] currentSelection;
         //private Coordinates lastMouseMove;
         //private Coordinates lastMouseMove;
@@ -116,21 +128,39 @@ namespace PixiEditor.Models.Tools.Tools
         //    }
         //    }
         //}
         //}
 
 
+        public override void AddUndoProcess(Document document)
+        {
+            var args = new object[] { change.Document };
+            document.UndoManager.AddUndoChange(change.ToChange(UndoProcess, args));
+            change = null;
+        }
+
+        private void UndoProcess(Layer[] layers, UndoLayer[] data, object[] args)
+        {
+            if (args.Length > 0 && args[0] is Document document)
+            {
+                for (int i = 0; i < layers.Length; i++)
+                {
+                    Layer layer = layers[i];
+                    document.Layers.RemoveAt(data[i].LayerIndex);
+
+                    document.Layers.Insert(data[i].LayerIndex, layer);
+                    if (data[i].IsActive)
+                    {
+                        document.SetMainActiveLayer(data[i].LayerIndex);
+                    }
+                }
+
+            }
+        }
+
         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)
-            {
-                currentSelection = selection.SelectedPoints.ToArray();
-            }
-            else
-            {
-                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();
@@ -140,20 +170,64 @@ 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();
             }
             }
 
 
+            change = new StorageBasedChange(doc, affectedLayers, true);
 
 
             Layer selLayer = selection.SelectionLayer;
             Layer selLayer = selection.SelectionLayer;
             moveStartRect = new(selLayer.OffsetX, selLayer.OffsetY, selLayer.Width, selLayer.Height);
             moveStartRect = new(selLayer.OffsetX, selLayer.OffsetY, selLayer.Width, selLayer.Height);
+            moveStartPos = startPos;
+            lastDragDelta = new Coordinates(0, 0);
+
             previewLayerData?.Dispose();
             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);
+            previewLayerData = CreateCombinedPreview(selLayer, affectedLayers);
 
 
-            moveStartPos = startPos;
+            if (currentlyDragged != null)
+            {
+                foreach (var surface in currentlyDragged)
+                    surface.Dispose();
+            }
+
+            currentlyDragged = ExtractDraggedPortions(selLayer, affectedLayers);
+
+            
             //startSelection = currentSelection;
             //startSelection = currentSelection;
             //startPixelColors = BitmapUtils.GetPixelsForSelection(affectedLayers, startSelection);
             //startPixelColors = BitmapUtils.GetPixelsForSelection(affectedLayers, startSelection);
             //startingOffsets = GetOffsets(affectedLayers);
             //startingOffsets = GetOffsets(affectedLayers);
         }
         }
 
 
+        private Surface CreateCombinedPreview(Layer selLayer, Layer[] layersToCombine)
+        {
+            var combined = BitmapUtils.CombineLayers(moveStartRect, layersToCombine, BitmapManager.ActiveDocument.LayerStructure);
+            using var selSnap = selLayer.LayerBitmap.SkiaSurface.Snapshot();
+            combined.SkiaSurface.Canvas.DrawImage(selSnap, 0, 0, maskingPaint);
+            return combined;
+        }
+        private static Surface[] ExtractDraggedPortions(Layer selLayer, Layer[] draggedLayers)
+        {
+            using var selSnap = selLayer.LayerBitmap.SkiaSurface.Snapshot();
+            Surface[] output = new Surface[draggedLayers.Length];
+            int count = 0;
+            foreach (Layer layer in draggedLayers)
+            {
+                Surface portion = new Surface(selLayer.Width, selLayer.Height);
+                SKRect selLayerRect = new SKRect(0, 0, selLayer.Width, selLayer.Height);
+
+                int x = selLayer.OffsetX - layer.OffsetX;
+                int y = selLayer.OffsetY - layer.OffsetY;
+
+                using (var layerSnap = layer.LayerBitmap.SkiaSurface.Snapshot())
+                    portion.SkiaSurface.Canvas.DrawImage(layerSnap, new SKRect(x, y, x + selLayer.Width, y + selLayer.Height), selLayerRect, Surface.ReplacingPaint);
+                portion.SkiaSurface.Canvas.DrawImage(selSnap, 0, 0, maskingPaint);
+                output[count] = portion;
+                count++;
+
+                layer.LayerBitmap.SkiaSurface.Canvas.DrawImage(selSnap, new SKRect(0, 0, selLayer.Width, selLayer.Height), 
+                    new SKRect(selLayer.OffsetX-layer.OffsetX, selLayer.OffsetY-layer.OffsetY, selLayer.OffsetX - layer.OffsetX + selLayer.Width, selLayer.OffsetY - layer.OffsetY + selLayer.Height), 
+                    inverseMaskingPaint);
+                layer.InvokeLayerBitmapChange(new Int32Rect(selLayer.OffsetX, selLayer.OffsetY, selLayer.Width, selLayer.Height));
+            }
+            return output;
+        }
+
         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];
@@ -162,14 +236,17 @@ namespace PixiEditor.Models.Tools.Tools
             Coordinates newPos = mouseMove[0];
             Coordinates newPos = mouseMove[0];
             int dX = newPos.X - moveStartPos.X;
             int dX = newPos.X - moveStartPos.X;
             int dY = newPos.Y - moveStartPos.Y;
             int dY = newPos.Y - moveStartPos.Y;
+            BitmapManager.ActiveDocument.ActiveSelection.TranslateSelection(dX - lastDragDelta.X, dY - lastDragDelta.Y);
+            lastDragDelta = new Coordinates(dX, dY);
+
 
 
             int newX = moveStartRect.X + dX;
             int newX = moveStartRect.X + dX;
             int newY = moveStartRect.Y + dY;
             int newY = moveStartRect.Y + dY;
             
             
-            
             layer.DynamicResizeAbsolute(newX + moveStartRect.Width, newY + moveStartRect.Height, newX, newY);
             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);
             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));
             layer.InvokeLayerBitmapChange(new Int32Rect(newX, newY, moveStartRect.Width, moveStartRect.Height));
+
             
             
 
 
             /*var end = mouseMove[0];
             /*var end = mouseMove[0];
@@ -198,6 +275,34 @@ namespace PixiEditor.Models.Tools.Tools
 
 
             return result;*/
             return result;*/
         }
         }
+
+        public override void OnStoppedRecordingMouseUp(MouseEventArgs e)
+        {
+            base.OnStoppedRecordingMouseUp(e);
+
+            BitmapManager.ActiveDocument.PreviewLayer.ClearCanvas();
+
+            ApplySurfacesToLayers(currentlyDragged, affectedLayers, new Coordinates(moveStartRect.X + lastDragDelta.X, moveStartRect.Y + lastDragDelta.Y));
+            foreach (var surface in currentlyDragged)
+                surface.Dispose();
+            currentlyDragged = null;
+        }
+
+        private static void ApplySurfacesToLayers(Surface[] surfaces, Layer[] layers, Coordinates position)
+        {
+            int count = 0;
+            foreach (Surface surface in surfaces)
+            {
+                var layer = layers[count];
+                using SKImage snapshot = surface.SkiaSurface.Snapshot();
+                layer.DynamicResizeAbsolute(position.X + surface.Width, position.Y + surface.Height, position.X, position.Y);
+                layer.LayerBitmap.SkiaSurface.Canvas.DrawImage(snapshot, position.X - layer.OffsetX, position.Y - layer.OffsetY);
+                layer.InvokeLayerBitmapChange(new Int32Rect(position.X, position.Y, surface.Width, surface.Height));
+
+                count++;
+            }
+        }
+
         //public BitmapPixelChanges MoveSelection(Layer layer, IEnumerable<Coordinates> mouseMove)
         //public BitmapPixelChanges MoveSelection(Layer layer, IEnumerable<Coordinates> mouseMove)
         //{
         //{
         //    Coordinates end = mouseMove.First();
         //    Coordinates end = mouseMove.First();

+ 2 - 1
PixiEditor/Views/UserControls/DrawingViewPort.xaml

@@ -72,7 +72,8 @@
                                       VerticalAlignment="Top" HorizontalAlignment="Left"
                                       VerticalAlignment="Top" HorizontalAlignment="Left"
                                       Width="{Binding ActiveSelection.SelectionLayer.Width}"
                                       Width="{Binding ActiveSelection.SelectionLayer.Width}"
                                       Height="{Binding ActiveSelection.SelectionLayer.Height}"
                                       Height="{Binding ActiveSelection.SelectionLayer.Height}"
-                                      Margin="{Binding ActiveSelection.SelectionLayer.Offset}"/>
+                                      Margin="{Binding ActiveSelection.SelectionLayer.Offset}"
+                                      Opacity="0.5"/>
                 
                 
                 <Grid ShowGridLines="True" Width="{Binding Width}" Height="{Binding Height}" Panel.ZIndex="10" 
                 <Grid ShowGridLines="True" Width="{Binding Width}" Height="{Binding Height}" Panel.ZIndex="10" 
                       Visibility="{Binding GridLinesVisible, Converter={StaticResource BoolToVisibilityConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:DrawingViewPort}}}">
                       Visibility="{Binding GridLinesVisible, Converter={StaticResource BoolToVisibilityConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:DrawingViewPort}}}">