Parcourir la source

Fixed duplicate on corners resize

flabbet il y a 7 mois
Parent
commit
cbf2013a1e

+ 10 - 2
src/PixiEditor/Models/DocumentModels/ChangeExecutionController.cs

@@ -221,12 +221,20 @@ internal class ChangeExecutionController
         currentSession?.OnLeftMouseButtonUp(argsPositionOnCanvas);
         currentSession?.OnLeftMouseButtonUp(argsPositionOnCanvas);
     }
     }
 
 
-    public void TransformMovedInlet(ShapeCorners corners)
+    public void TransformChangedInlet(ShapeCorners corners)
     {
     {
         if (currentSession is ITransformableExecutor transformableExecutor)
         if (currentSession is ITransformableExecutor transformableExecutor)
         {
         {
             LastTransformState = corners;
             LastTransformState = corners;
-            transformableExecutor.OnTransformMoved(corners);
+            transformableExecutor.OnTransformChanged(corners);
+        }
+    }
+    
+    public void TransformDraggedInlet(VecD from, VecD to)
+    {
+        if (currentSession is ITransformDraggedEvent transformableExecutor)
+        {
+            transformableExecutor.OnTransformDragged(from, to);
         }
         }
     }
     }
 
 

+ 1 - 1
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/DrawableShapeToolExecutor.cs

@@ -140,7 +140,7 @@ internal abstract class DrawableShapeToolExecutor<T> : SimpleShapeToolExecutor w
         return pos1;
         return pos1;
     }
     }
 
 
-    public override void OnTransformMoved(ShapeCorners corners)
+    public override void OnTransformChanged(ShapeCorners corners)
     {
     {
         if (ActiveMode != ShapeToolMode.Transform)
         if (ActiveMode != ShapeToolMode.Transform)
             return;
             return;

+ 9 - 0
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/Features/ITransformDraggedEvent.cs

@@ -0,0 +1,9 @@
+using ChunkyImageLib.DataHolders;
+using Drawie.Numerics;
+
+namespace PixiEditor.Models.DocumentModels.UpdateableChangeExecutors.Features;
+
+public interface ITransformDraggedEvent : IExecutorFeature
+{
+    public void OnTransformDragged(VecD from, VecD to);
+}

+ 1 - 1
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/Features/ITransformableExecutor.cs

@@ -6,7 +6,7 @@ namespace PixiEditor.Models.DocumentModels.UpdateableChangeExecutors.Features;
 public interface ITransformableExecutor : IExecutorFeature
 public interface ITransformableExecutor : IExecutorFeature
 {
 {
     public bool IsTransforming { get; }
     public bool IsTransforming { get; }
-    public void OnTransformMoved(ShapeCorners corners); 
+    public void OnTransformChanged(ShapeCorners corners); 
     public void OnTransformApplied();
     public void OnTransformApplied();
     public void OnLineOverlayMoved(VecD start, VecD end);
     public void OnLineOverlayMoved(VecD start, VecD end);
     public void OnSelectedObjectNudged(VecI distance);
     public void OnSelectedObjectNudged(VecI distance);

+ 1 - 1
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/PasteImageExecutor.cs

@@ -62,7 +62,7 @@ internal class PasteImageExecutor : UpdateableChangeExecutor, ITransformableExec
 
 
     public bool IsTransforming => true; 
     public bool IsTransforming => true; 
 
 
-    public void OnTransformMoved(ShapeCorners corners)
+    public void OnTransformChanged(ShapeCorners corners)
     {
     {
         internals!.ActionAccumulator.AddActions(new PasteImage_Action(image, corners, memberGuid.Value, false, drawOnMask, document!.AnimationHandler.ActiveFrameBindable, default));
         internals!.ActionAccumulator.AddActions(new PasteImage_Action(image, corners, memberGuid.Value, false, drawOnMask, document!.AnimationHandler.ActiveFrameBindable, default));
     }
     }

+ 1 - 1
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/SimpleShapeToolExecutor.cs

@@ -145,7 +145,7 @@ internal abstract class SimpleShapeToolExecutor : UpdateableChangeExecutor,
 
 
     public bool IsTransforming => ActiveMode == ShapeToolMode.Transform; 
     public bool IsTransforming => ActiveMode == ShapeToolMode.Transform; 
 
 
-    public virtual void OnTransformMoved(ShapeCorners corners)
+    public virtual void OnTransformChanged(ShapeCorners corners)
     {
     {
         
         
     }
     }

+ 1 - 1
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/TransformReferenceLayerExecutor.cs

@@ -22,7 +22,7 @@ internal class TransformReferenceLayerExecutor : UpdateableChangeExecutor, ITran
 
 
     public bool IsTransforming => true;
     public bool IsTransforming => true;
 
 
-    public void OnTransformMoved(ShapeCorners corners)
+    public void OnTransformChanged(ShapeCorners corners)
     {
     {
         internals!.ActionAccumulator.AddActions(new TransformReferenceLayer_Action(corners));
         internals!.ActionAccumulator.AddActions(new TransformReferenceLayer_Action(corners));
     }
     }

+ 15 - 7
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/TransformSelectedExecutor.cs

@@ -20,7 +20,8 @@ using PixiEditor.ViewModels.Document.Nodes;
 
 
 namespace PixiEditor.Models.DocumentModels.UpdateableChangeExecutors;
 namespace PixiEditor.Models.DocumentModels.UpdateableChangeExecutors;
 #nullable enable
 #nullable enable
-internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransformableExecutor, IMidChangeUndoableExecutor,
+internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransformableExecutor, ITransformDraggedEvent,
+    IMidChangeUndoableExecutor,
     ITransformStoppedEvent
     ITransformStoppedEvent
 {
 {
     private Dictionary<Guid, ShapeCorners> memberCorners = new();
     private Dictionary<Guid, ShapeCorners> memberCorners = new();
@@ -242,13 +243,13 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
 
 
     public bool IsTransforming => isInProgress;
     public bool IsTransforming => isInProgress;
 
 
-    public void OnTransformMoved(ShapeCorners corners)
+    public void OnTransformChanged(ShapeCorners corners)
     {
     {
         DoTransform(corners);
         DoTransform(corners);
         lastCorners = corners;
         lastCorners = corners;
     }
     }
 
 
-    private void DoTransform(ShapeCorners corners)
+    public void OnTransformDragged(VecD from, VecD to)
     {
     {
         if (!isInProgress)
         if (!isInProgress)
             return;
             return;
@@ -263,13 +264,20 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
             }
             }
 
 
             VecD delta = new VecD(
             VecD delta = new VecD(
-                corners.AABBBounds.TopLeft.X - cornersOnStartDuplicate.AABBBounds.TopLeft.X,
-                corners.AABBBounds.TopLeft.Y - cornersOnStartDuplicate.AABBBounds.TopLeft.Y);
+                to.X - from.X,
+                to.Y - from.Y);
 
 
             internals.ActionAccumulator.AddActions(new PreviewShiftLayers_Action(selectedMembers, delta,
             internals.ActionAccumulator.AddActions(new PreviewShiftLayers_Action(selectedMembers, delta,
                 document!.AnimationHandler.ActiveFrameBindable));
                 document!.AnimationHandler.ActiveFrameBindable));
-            return;
         }
         }
+    }
+
+    private void DoTransform(ShapeCorners corners)
+    {
+        if (!isInProgress)
+            return;
+
+        if (duplicateOnStop) return;
 
 
         if (!movedOnce)
         if (!movedOnce)
         {
         {
@@ -460,6 +468,6 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
     public bool IsFeatureEnabled(IExecutorFeature feature)
     public bool IsFeatureEnabled(IExecutorFeature feature)
     {
     {
         return feature is ITransformableExecutor && IsTransforming || feature is IMidChangeUndoableExecutor ||
         return feature is ITransformableExecutor && IsTransforming || feature is IMidChangeUndoableExecutor ||
-               feature is ITransformStoppedEvent;
+               feature is ITransformStoppedEvent || feature is ITransformDraggedEvent;
     }
     }
 }
 }

+ 2 - 1
src/PixiEditor/ViewModels/Document/DocumentViewModel.cs

@@ -236,7 +236,8 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
         NodeGraph = new NodeGraphViewModel(this, Internals);
         NodeGraph = new NodeGraphViewModel(this, Internals);
 
 
         TransformViewModel = new(this);
         TransformViewModel = new(this);
-        TransformViewModel.TransformMoved += (args) => Internals.ChangeController.TransformMovedInlet(args);
+        TransformViewModel.TransformChanged += (args) => Internals.ChangeController.TransformChangedInlet(args);
+        TransformViewModel.TransformDragged += (from, to) => Internals.ChangeController.TransformDraggedInlet(from, to);
         TransformViewModel.TransformStopped += () => Internals.ChangeController.TransformStoppedInlet();
         TransformViewModel.TransformStopped += () => Internals.ChangeController.TransformStoppedInlet();
 
 
         PathOverlayViewModel = new(this, Internals);
         PathOverlayViewModel = new(this, Internals);

+ 9 - 2
src/PixiEditor/ViewModels/Document/TransformOverlays/DocumentTransformViewModel.cs

@@ -135,7 +135,7 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
         set
         set
         {
         {
             SetProperty(ref corners, value);
             SetProperty(ref corners, value);
-            TransformMoved?.Invoke(value);
+            TransformChanged?.Invoke(value);
         }
         }
     }
     }
 
 
@@ -190,8 +190,15 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
                 new RelayCommand<MouseOnCanvasEventArgs>(x => PassthroughPointerPressed?.Invoke(x));
                 new RelayCommand<MouseOnCanvasEventArgs>(x => PassthroughPointerPressed?.Invoke(x));
         }
         }
     }
     }
+    
+    private RelayCommand<(VecD, VecD)>? transformDraggedCommand;
+    public RelayCommand<(VecD, VecD)> TransformDraggedCommand
+    {
+        get => transformDraggedCommand ??= new RelayCommand<(VecD from, VecD to)>(x => TransformDragged?.Invoke(x.from, x.to));
+    }
 
 
-    public event Action<ShapeCorners>? TransformMoved;
+    public event Action<ShapeCorners>? TransformChanged;
+    public event Action<VecD, VecD> TransformDragged;
     public event Action TransformStopped; 
     public event Action TransformStopped; 
 
 
     private DocumentTransformMode activeTransformMode = DocumentTransformMode.Scale_Rotate_NoShear_NoPerspective;
     private DocumentTransformMode activeTransformMode = DocumentTransformMode.Scale_Rotate_NoShear_NoPerspective;

+ 6 - 0
src/PixiEditor/Views/Main/ViewportControls/ViewportOverlays.cs

@@ -347,6 +347,11 @@ internal class ViewportOverlays
         {
         {
             Source = Viewport, Path = "Document.TransformViewModel.LockShear", Mode = BindingMode.OneWay
             Source = Viewport, Path = "Document.TransformViewModel.LockShear", Mode = BindingMode.OneWay
         };
         };
+        
+        Binding transformDraggedBinding = new()
+        {
+            Source = Viewport, Path = "Document.TransformViewModel.TransformDraggedCommand", Mode = BindingMode.OneWay
+        };
 
 
         transformOverlay.Bind(Visual.IsVisibleProperty, isVisibleBinding);
         transformOverlay.Bind(Visual.IsVisibleProperty, isVisibleBinding);
         transformOverlay.Bind(TransformOverlay.ActionCompletedProperty, actionCompletedBinding);
         transformOverlay.Bind(TransformOverlay.ActionCompletedProperty, actionCompletedBinding);
@@ -366,6 +371,7 @@ internal class ViewportOverlays
         transformOverlay.Bind(TransformOverlay.ScaleFromCenterProperty, scaleFromCenterBinding);
         transformOverlay.Bind(TransformOverlay.ScaleFromCenterProperty, scaleFromCenterBinding);
         transformOverlay.Bind(TransformOverlay.CanAlignToPixelsProperty, canAlignToPixelsBinding);
         transformOverlay.Bind(TransformOverlay.CanAlignToPixelsProperty, canAlignToPixelsBinding);
         transformOverlay.Bind(TransformOverlay.LockShearProperty, lockShearBinding);
         transformOverlay.Bind(TransformOverlay.LockShearProperty, lockShearBinding);
+        transformOverlay.Bind(TransformOverlay.TransformDraggedCommandProperty, transformDraggedBinding);
     }
     }
     
     
     private void BindVectorPathOverlay()
     private void BindVectorPathOverlay()

+ 14 - 0
src/PixiEditor/Views/Overlays/TransformOverlay/TransformOverlay.cs

@@ -179,6 +179,15 @@ internal class TransformOverlay : Overlay
         get => GetValue(LockShearProperty);
         get => GetValue(LockShearProperty);
         set => SetValue(LockShearProperty, value);
         set => SetValue(LockShearProperty, value);
     }
     }
+
+    public static readonly StyledProperty<ICommand> TransformDraggedCommandProperty = AvaloniaProperty.Register<TransformOverlay, ICommand>(
+        nameof(TransformDraggedCommand));
+
+    public ICommand TransformDraggedCommand
+    {
+        get => GetValue(TransformDraggedCommandProperty);
+        set => SetValue(TransformDraggedCommandProperty, value);
+    }
     
     
     static TransformOverlay()
     static TransformOverlay()
     {
     {
@@ -770,9 +779,14 @@ internal class TransformOverlay : Overlay
         SnappingController.HighlightedXAxis = snapDeltaResult.SnapAxisXName;
         SnappingController.HighlightedXAxis = snapDeltaResult.SnapAxisXName;
         SnappingController.HighlightedYAxis = snapDeltaResult.SnapAxisYName;
         SnappingController.HighlightedYAxis = snapDeltaResult.SnapAxisYName;
 
 
+        VecD from = originOnStartMove;
+        
         Corners = ApplyCornersWithDelta(cornersOnStartMove, delta, snapDelta);
         Corners = ApplyCornersWithDelta(cornersOnStartMove, delta, snapDelta);
 
 
         InternalState = InternalState with { Origin = originOnStartMove + delta + snapDelta };
         InternalState = InternalState with { Origin = originOnStartMove + delta + snapDelta };
+        
+        VecD to = InternalState.Origin;
+        TransformDraggedCommand?.Execute((from, to));
     }
     }
 
 
     private ShapeCorners ApplyCornersWithDelta(ShapeCorners corners, VecD delta, VecD snapDelta)
     private ShapeCorners ApplyCornersWithDelta(ShapeCorners corners, VecD delta, VecD snapDelta)