Browse Source

Duplication with selection fix

Krzysztof Krysiński 2 months ago
parent
commit
6ce1e651b0

+ 37 - 8
src/PixiEditor.ChangeableDocument/Changes/Drawing/PreviewShiftLayers_UpdateableChange.cs

@@ -14,15 +14,18 @@ internal class PreviewShiftLayers_UpdateableChange : InterruptableUpdateableChan
     private List<Guid> layerGuids;
     private VecD delta;
     private Dictionary<Guid, ShapeVectorData> originalShapes;
+    private RectD? clipRect;
+    private VectorPath? clipPath;
 
     private int frame;
 
     [GenerateUpdateableChangeActions]
-    public PreviewShiftLayers_UpdateableChange(List<Guid> layerGuids, VecD delta, int frame)
+    public PreviewShiftLayers_UpdateableChange(List<Guid> layerGuids, RectD clipRect, VecD delta, int frame)
     {
         this.delta = delta;
         this.layerGuids = layerGuids;
         this.frame = frame;
+        this.clipRect = clipRect.IsZeroOrNegativeArea ? null : clipRect;
     }
 
     public override bool InitializeAndValidate(Document target)
@@ -50,6 +53,14 @@ internal class PreviewShiftLayers_UpdateableChange : InterruptableUpdateableChan
                 originalShapes[layerGuid] = transformableObject.EmbeddedShapeData;
                 transformableObject.EmbeddedShapeData = null;
             }
+            else if (layer is ImageLayerNode imgLayer)
+            {
+                var image = imgLayer.GetLayerImageAtFrame(frame);
+                if (image is null)
+                {
+                    return false;
+                }
+            }
         }
 
         return true;
@@ -68,16 +79,25 @@ internal class PreviewShiftLayers_UpdateableChange : InterruptableUpdateableChan
         {
             var layer = target.FindMemberOrThrow<LayerNode>(layerGuid);
 
-            if (layer is ImageLayerNode)
+            if (layer is ImageLayerNode imgNode)
             {
-                var area = ShiftLayerHelper.DrawShiftedLayer(target, layerGuid, true, (VecI)delta, frame);
+                if (clipRect.HasValue)
+                {
+                    clipPath?.Dispose();
+                    clipPath = new VectorPath();
+                    clipPath.AddRect(clipRect.Value);
+                    clipPath.Offset((VecI)delta);
+                }
+
+                var area = ShiftLayerHelper.DrawShiftedLayer(target, layerGuid, true, (VecI)delta, frame, clipPath);
+
                 changes.Add(new LayerImageArea_ChangeInfo(layerGuid, area));
             }
             else if (layer is VectorLayerNode vectorLayer)
             {
                 StrokeJoin join = StrokeJoin.Miter;
                 StrokeCap cap = StrokeCap.Butt;
-                
+
                 (vectorLayer.EmbeddedShapeData as PathVectorData)?.Path.Dispose();
 
                 var originalShape = originalShapes[layerGuid];
@@ -90,8 +110,9 @@ internal class PreviewShiftLayers_UpdateableChange : InterruptableUpdateableChan
                     cap = shape.StrokeLineCap;
                 }
 
-                VecD mappedDelta = originalShape.TransformationMatrix.Invert().MapVector((float)delta.X, (float)delta.Y);
-                
+                VecD mappedDelta = originalShape.TransformationMatrix.Invert()
+                    .MapVector((float)delta.X, (float)delta.Y);
+
                 var finalMatrix = Matrix3X3.CreateTranslation((float)mappedDelta.X, (float)mappedDelta.Y);
 
                 path.AddPath(path, finalMatrix, AddPathMode.Append);
@@ -106,9 +127,10 @@ internal class PreviewShiftLayers_UpdateableChange : InterruptableUpdateableChan
                     StrokeLineJoin = join,
                     StrokeLineCap = cap
                 };
-                
+
                 vectorLayer.EmbeddedShapeData = newShapeData;
-                changes.Add(new VectorShape_ChangeInfo(layerGuid, ShiftLayer_UpdateableChange.AffectedAreaFromBounds(target, layerGuid, frame)));
+                changes.Add(new VectorShape_ChangeInfo(layerGuid,
+                    ShiftLayer_UpdateableChange.AffectedAreaFromBounds(target, layerGuid, frame)));
             }
         }
 
@@ -139,6 +161,7 @@ internal class PreviewShiftLayers_UpdateableChange : InterruptableUpdateableChan
                 var image = imgLayer.GetLayerImageAtFrame(frame);
                 var affected = image.FindAffectedArea();
                 image.CancelChanges();
+                image.SetClippingPath(null);
                 changes.Add(new LayerImageArea_ChangeInfo(layerGuid, affected));
             }
             else if (layer is VectorLayerNode transformableObject)
@@ -150,4 +173,10 @@ internal class PreviewShiftLayers_UpdateableChange : InterruptableUpdateableChan
 
         return changes;
     }
+
+    public override void Dispose()
+    {
+        base.Dispose();
+        clipPath?.Dispose();
+    }
 }

+ 9 - 1
src/PixiEditor.ChangeableDocument/Changes/Drawing/ShiftLayerHelper.cs

@@ -1,18 +1,26 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 using Drawie.Backend.Core.Numerics;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 
 namespace PixiEditor.ChangeableDocument.Changes.Drawing;
 
 internal static class ShiftLayerHelper
 {
-    public static AffectedArea DrawShiftedLayer(Document target, Guid layerGuid, bool keepOriginal, VecI delta, int frame)
+    public static AffectedArea DrawShiftedLayer(Document target, Guid layerGuid, bool keepOriginal, VecI delta,
+        int frame, VectorPath? clipPath = null)
     {
         var targetImage = target.FindMemberOrThrow<ImageLayerNode>(layerGuid).GetLayerImageAtFrame(frame);
         var prevArea = targetImage.FindAffectedArea();
         targetImage.CancelChanges();
         if (!keepOriginal)
             targetImage.EnqueueClear();
+
+        if (clipPath != null)
+        {
+            targetImage.SetClippingPath(clipPath);
+        }
+
         targetImage.EnqueueDrawCommitedChunkyImage(delta, targetImage, false, false);
         var curArea = targetImage.FindAffectedArea();
 

+ 9 - 1
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/TransformSelectedExecutor.cs

@@ -294,7 +294,9 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
                 to.X - from.X,
                 to.Y - from.Y);
 
-            internals.ActionAccumulator.AddActions(new PreviewShiftLayers_Action(selectedMembers, delta,
+            RectD clipRect = lastCorners.AABBBounds;
+            internals.ActionAccumulator.AddActions(new PreviewShiftLayers_Action(
+                selectedMembers, clipRect, delta,
                 document!.AnimationHandler.ActiveFrameBindable));
         }
     }
@@ -395,6 +397,12 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
 
         actions.Add(new ShiftLayer_Action(newLayerGuids, delta, document!.AnimationHandler.ActiveFrameBindable));
 
+        if (original is { IsEmpty: false })
+        {
+            original.Offset((VecI)delta);
+            actions.Add(new SetSelection_Action(original));
+        }
+
         internals!.ActionAccumulator.AddFinishedActions(actions.ToArray());
 
         actions.Clear();

+ 3 - 3
src/PixiEditor/ViewModels/Tools/Tools/PenToolViewModel.cs

@@ -18,7 +18,7 @@ namespace PixiEditor.ViewModels.Tools.Tools
     [Command.Tool(Key = Key.B)]
     internal class PenToolViewModel : ShapeTool, IPenToolHandler
     {
-        private double actualToolSize;
+        private double actualToolSize = 1;
 
         public override string ToolNameLocalizationKey => "PEN_TOOL";
 
@@ -31,7 +31,7 @@ namespace PixiEditor.ViewModels.Tools.Tools
         {
             Cursor = Cursors.PreciseCursor;
             Toolbar = ToolbarFactory.Create<PenToolViewModel, PenToolbar>(this);
-            
+
             ViewModelMain.Current.ToolsSubViewModel.SelectedToolChanged += SelectedToolChanged;
         }
 
@@ -82,7 +82,7 @@ namespace PixiEditor.ViewModels.Tools.Tools
                 var setting = toolbar.Settings.FirstOrDefault(x => x.Name == nameof(toolbar.ToolSize));
                 if (setting is SizeSettingViewModel sizeSetting)
                 {
-                    sizeSetting.Value = 1;
+                    sizeSetting.Value = 1d;
                 }
             }