Browse Source

Fixed blending again, snapping improvements and transient press

Krzysztof Krysiński 4 months ago
parent
commit
e03e0c207e

+ 1 - 10
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/RenderNode.cs

@@ -42,7 +42,7 @@ public abstract class RenderNode : Node, IPreviewRenderable, IHighDpiRenderNode
         lastDocumentSize = context.DocumentSize;
         lastDocumentSize = context.DocumentSize;
     }
     }
 
 
-    private void Paint(RenderContext context, DrawingSurface surface)
+    protected virtual void Paint(RenderContext context, DrawingSurface surface)
     {
     {
         DrawingSurface target = surface;
         DrawingSurface target = surface;
         bool useIntermediate = !AllowHighDpiRendering
         bool useIntermediate = !AllowHighDpiRendering
@@ -51,15 +51,6 @@ public abstract class RenderNode : Node, IPreviewRenderable, IHighDpiRenderNode
         if (useIntermediate)
         if (useIntermediate)
         {
         {
             Texture intermediate = textureCache.RequestTexture(-6451, context.DocumentSize, context.ProcessingColorSpace);
             Texture intermediate = textureCache.RequestTexture(-6451, context.DocumentSize, context.ProcessingColorSpace);
-
-            int saved = intermediate.DrawingSurface.Canvas.Save();
-            Matrix3X3 fitMatrix = Matrix3X3.CreateScale(
-                (float)context.DocumentSize.X / surface.DeviceClipBounds.Size.X,
-                (float)context.DocumentSize.Y / surface.DeviceClipBounds.Size.Y);
-            intermediate.DrawingSurface.Canvas.SetMatrix(fitMatrix);
-            intermediate.DrawingSurface.Canvas.DrawSurface(surface, 0, 0);
-            intermediate.DrawingSurface.Canvas.RestoreToCount(saved);
-
             target = intermediate.DrawingSurface;
             target = intermediate.DrawingSurface;
         }
         }
 
 

+ 5 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/StructureNode.cs

@@ -124,6 +124,11 @@ public abstract class StructureNode : RenderNode, IReadOnlyStructureNode, IRende
         }
         }
     }
     }
 
 
+    protected override void Paint(RenderContext context, DrawingSurface surface)
+    {
+        OnPaint(context, surface);
+    }
+
     protected override void OnPaint(RenderContext context, DrawingSurface renderTarget)
     protected override void OnPaint(RenderContext context, DrawingSurface renderTarget)
     {
     {
         if (Output.Connections.Count > 0)
         if (Output.Connections.Count > 0)

+ 5 - 6
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/DrawableShapeToolExecutor.cs

@@ -128,7 +128,7 @@ internal abstract class DrawableShapeToolExecutor<T> : SimpleShapeToolExecutor w
     protected abstract void DrawShape(VecD currentPos, double rotationRad, bool firstDraw);
     protected abstract void DrawShape(VecD currentPos, double rotationRad, bool firstDraw);
     protected abstract IAction SettingsChangedAction(string name, object value);
     protected abstract IAction SettingsChangedAction(string name, object value);
     protected abstract IAction TransformMovedAction(ShapeData data, ShapeCorners corners);
     protected abstract IAction TransformMovedAction(ShapeData data, ShapeCorners corners);
-    protected virtual bool InitShapeData(IReadOnlyShapeVectorData data) { return true; }
+    protected virtual bool InitShapeData(IReadOnlyShapeVectorData data) { return false; }
     protected abstract bool CanEditShape(IStructureMemberHandler layer);
     protected abstract bool CanEditShape(IStructureMemberHandler layer);
     protected abstract IAction EndDrawAction();
     protected abstract IAction EndDrawAction();
     protected virtual DocumentTransformMode TransformMode => DocumentTransformMode.Scale_Rotate_NoShear_NoPerspective;
     protected virtual DocumentTransformMode TransformMode => DocumentTransformMode.Scale_Rotate_NoShear_NoPerspective;
@@ -234,7 +234,6 @@ internal abstract class DrawableShapeToolExecutor<T> : SimpleShapeToolExecutor w
                 EndDrawAction(),
                 EndDrawAction(),
                 SettingsChangedAction("FillAndStroke", color),
                 SettingsChangedAction("FillAndStroke", color),
                 EndDrawAction());
                 EndDrawAction());
-            // TODO add to undo
         }
         }
     }
     }
 
 
@@ -315,7 +314,7 @@ internal abstract class DrawableShapeToolExecutor<T> : SimpleShapeToolExecutor w
 
 
         if (highlight)
         if (highlight)
         {
         {
-            HighlightSnapAxis(snapXAxis, snapYAxis);
+            HighlightSnapAxis(snapXAxis, snapYAxis, string.IsNullOrEmpty(snapXAxis) && string.IsNullOrEmpty(snapYAxis) ? null : snapped);
         }
         }
 
 
         if (AlignToPixels)
         if (AlignToPixels)
@@ -345,7 +344,7 @@ internal abstract class DrawableShapeToolExecutor<T> : SimpleShapeToolExecutor w
 
 
         if (highlight)
         if (highlight)
         {
         {
-            HighlightSnapAxis(snapXAxis, snapYAxis);
+            HighlightSnapAxis(snapXAxis, snapYAxis, string.IsNullOrEmpty(snapXAxis) && string.IsNullOrEmpty(snapYAxis) ? null : snapped);
         }
         }
 
 
         if (snapped != VecI.Zero)
         if (snapped != VecI.Zero)
@@ -364,11 +363,11 @@ internal abstract class DrawableShapeToolExecutor<T> : SimpleShapeToolExecutor w
         return snapped;
         return snapped;
     }
     }
 
 
-    private void HighlightSnapAxis(string snapXAxis, string snapYAxis)
+    private void HighlightSnapAxis(string snapXAxis, string snapYAxis, VecD? snapPoint)
     {
     {
         document.SnappingHandler.SnappingController.HighlightedXAxis = snapXAxis;
         document.SnappingHandler.SnappingController.HighlightedXAxis = snapXAxis;
         document.SnappingHandler.SnappingController.HighlightedYAxis = snapYAxis;
         document.SnappingHandler.SnappingController.HighlightedYAxis = snapYAxis;
-        document.SnappingHandler.SnappingController.HighlightedPoint = null;
+        document.SnappingHandler.SnappingController.HighlightedPoint = snapPoint;
     }
     }
 
 
     public override void OnSettingsChanged(string name, object value)
     public override void OnSettingsChanged(string name, object value)

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

@@ -157,6 +157,11 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
     public bool AnySymmetryAxisEnabledBindable =>
     public bool AnySymmetryAxisEnabledBindable =>
         HorizontalSymmetryAxisEnabledBindable || VerticalSymmetryAxisEnabledBindable;
         HorizontalSymmetryAxisEnabledBindable || VerticalSymmetryAxisEnabledBindable;
 
 
+
+    public bool OverlayEventsSuppressed => overlaySuppressors.Count > 0;
+
+    private readonly HashSet<string> overlaySuppressors = new();
+
     private VecI size = new VecI(64, 64);
     private VecI size = new VecI(64, 64);
     public int Width => size.X;
     public int Width => size.X;
     public int Height => size.Y;
     public int Height => size.Y;
@@ -224,6 +229,7 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
     public AnimationDataViewModel AnimationDataViewModel { get; }
     public AnimationDataViewModel AnimationDataViewModel { get; }
     public TextOverlayViewModel TextOverlayViewModel { get; }
     public TextOverlayViewModel TextOverlayViewModel { get; }
 
 
+
     public IReadOnlyCollection<IStructureMemberHandler> SoftSelectedStructureMembers => softSelectedStructureMembers;
     public IReadOnlyCollection<IStructureMemberHandler> SoftSelectedStructureMembers => softSelectedStructureMembers;
     private DocumentInternalParts Internals { get; }
     private DocumentInternalParts Internals { get; }
     INodeGraphHandler IDocument.NodeGraphHandler => NodeGraph;
     INodeGraphHandler IDocument.NodeGraphHandler => NodeGraph;
@@ -437,7 +443,8 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
             mappedNodeIds.Add(id, guid);
             mappedNodeIds.Add(id, guid);
             Guid pairGuid = Guid.Empty;
             Guid pairGuid = Guid.Empty;
 
 
-            if (serializedNode.PairId != null && mappedNodeIds.TryGetValue(serializedNode.PairId.Value, out Guid pairId))
+            if (serializedNode.PairId != null &&
+                mappedNodeIds.TryGetValue(serializedNode.PairId.Value, out Guid pairId))
             {
             {
                 pairGuid = pairId;
                 pairGuid = pairId;
             }
             }
@@ -769,6 +776,18 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
         return bitmap.GetSRGBPixel(new VecI((int)transformed.X, (int)transformed.Y));
         return bitmap.GetSRGBPixel(new VecI((int)transformed.X, (int)transformed.Y));
     }
     }
 
 
+    public void SuppressAllOverlayEvents(string suppressor)
+    {
+        overlaySuppressors.Add(suppressor);
+        OnPropertyChanged(nameof(OverlayEventsSuppressed));
+    }
+
+    public void RestoreAllOverlayEvents(string suppressor)
+    {
+        overlaySuppressors.Remove(suppressor);
+        OnPropertyChanged(nameof(OverlayEventsSuppressed));
+    }
+
     public Color PickColorFromCanvas(VecI pos, DocumentScope scope, KeyFrameTime frameTime, string? customOutput = null)
     public Color PickColorFromCanvas(VecI pos, DocumentScope scope, KeyFrameTime frameTime, string? customOutput = null)
     {
     {
         // there is a tiny chance that the image might get disposed by another thread
         // there is a tiny chance that the image might get disposed by another thread
@@ -778,7 +797,9 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
             // via a passthrough action to avoid all the try catches
             // via a passthrough action to avoid all the try catches
             if (scope == DocumentScope.Canvas)
             if (scope == DocumentScope.Canvas)
             {
             {
-                using Surface tmpSurface = new Surface(SizeBindable); // new Surface is on purpose, Surface.ForDisplay doesn't work here
+                using Surface
+                    tmpSurface =
+                        new Surface(SizeBindable); // new Surface is on purpose, Surface.ForDisplay doesn't work here
                 Renderer.RenderDocument(tmpSurface.DrawingSurface, frameTime, SizeBindable, customOutput);
                 Renderer.RenderDocument(tmpSurface.DrawingSurface, frameTime, SizeBindable, customOutput);
 
 
                 return tmpSurface.GetSrgbPixel(pos);
                 return tmpSurface.GetSrgbPixel(pos);

+ 12 - 0
src/PixiEditor/ViewModels/Tools/Tools/ColorPickerToolViewModel.cs

@@ -170,4 +170,16 @@ internal class ColorPickerToolViewModel : ToolViewModel, IColorPickerHandler
 
 
     public override void KeyChanged(bool ctrlIsDown, bool shiftIsDown, bool altIsDown, Key argsKey) =>
     public override void KeyChanged(bool ctrlIsDown, bool shiftIsDown, bool altIsDown, Key argsKey) =>
         UpdateActionDisplay(ctrlIsDown, shiftIsDown);
         UpdateActionDisplay(ctrlIsDown, shiftIsDown);
+
+    protected override void OnSelected(bool restoring)
+    {
+        base.OnSelected(restoring);
+        ViewModelMain.Current.DocumentManagerSubViewModel.ActiveDocument.SuppressAllOverlayEvents(ToolName);
+    }
+
+    protected override void OnDeselecting(bool transient)
+    {
+        base.OnDeselecting(transient);
+        ViewModelMain.Current.DocumentManagerSubViewModel.ActiveDocument.RestoreAllOverlayEvents(ToolName);
+    }
 }
 }

+ 7 - 0
src/PixiEditor/ViewModels/Tools/Tools/MoveViewportToolViewModel.cs

@@ -28,5 +28,12 @@ internal class MoveViewportToolViewModel : ToolViewModel
     protected override void OnSelected(bool restoring)
     protected override void OnSelected(bool restoring)
     {
     {
         ActionDisplay = new LocalizedString("MOVE_VIEWPORT_ACTION_DISPLAY");
         ActionDisplay = new LocalizedString("MOVE_VIEWPORT_ACTION_DISPLAY");
+        ViewModelMain.Current.DocumentManagerSubViewModel.ActiveDocument.SuppressAllOverlayEvents(ToolName);
+    }
+
+    protected override void OnDeselecting(bool transient)
+    {
+        base.OnDeselecting(transient);
+        ViewModelMain.Current.DocumentManagerSubViewModel.ActiveDocument.RestoreAllOverlayEvents(ToolName);
     }
     }
 }
 }

+ 0 - 2
src/PixiEditor/ViewModels/Tools/Tools/VectorEllipseToolViewModel.cs

@@ -60,8 +60,6 @@ internal class VectorEllipseToolViewModel : ShapeTool, IVectorEllipseToolHandler
 
 
     protected override void OnSelected(bool restoring)
     protected override void OnSelected(bool restoring)
     {
     {
-        if (restoring) return;
-
         ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument?.Tools.UseVectorEllipseTool();
         ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument?.Tools.UseVectorEllipseTool();
     }
     }
 
 

+ 0 - 2
src/PixiEditor/ViewModels/Tools/Tools/VectorLineToolViewModel.cs

@@ -72,8 +72,6 @@ internal class VectorLineToolViewModel : ShapeTool, IVectorLineToolHandler
 
 
     protected override void OnSelected(bool restoring)
     protected override void OnSelected(bool restoring)
     {
     {
-        if (restoring) return;
-
         var document = ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument;
         var document = ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument;
         document.Tools.UseVectorLineTool();
         document.Tools.UseVectorLineTool();
     }
     }

+ 0 - 2
src/PixiEditor/ViewModels/Tools/Tools/VectorPathToolViewModel.cs

@@ -119,8 +119,6 @@ internal class VectorPathToolViewModel : ShapeTool, IVectorPathToolHandler
     
     
     protected override void OnSelected(bool restoring)
     protected override void OnSelected(bool restoring)
     {
     {
-        if (restoring) return;
-
         ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument?.Tools.UseVectorPathTool();
         ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument?.Tools.UseVectorPathTool();
         isActivated = true;
         isActivated = true;
     }
     }

+ 0 - 2
src/PixiEditor/ViewModels/Tools/Tools/VectorRectangleToolViewModel.cs

@@ -73,8 +73,6 @@ internal class VectorRectangleToolViewModel : ShapeTool, IVectorRectangleToolHan
 
 
     protected override void OnSelected(bool restoring)
     protected override void OnSelected(bool restoring)
     {
     {
-        if (restoring) return;
-
         ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument?.Tools.UseVectorRectangleTool();
         ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument?.Tools.UseVectorRectangleTool();
     }
     }
 
 

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

@@ -69,6 +69,13 @@ internal class ViewportOverlays
         textOverlay = new TextOverlay();
         textOverlay = new TextOverlay();
         BindTextOverlay();
         BindTextOverlay();
 
 
+        Binding suppressOverlayEventsBinding = new()
+        {
+            Source = Viewport,
+            Path = "Document.OverlayEventsSuppressed",
+            Mode = BindingMode.OneWay
+        };
+
         Viewport.ActiveOverlays.Add(gridLinesOverlay);
         Viewport.ActiveOverlays.Add(gridLinesOverlay);
         Viewport.ActiveOverlays.Add(referenceLayerOverlay);
         Viewport.ActiveOverlays.Add(referenceLayerOverlay);
         Viewport.ActiveOverlays.Add(selectionOverlay);
         Viewport.ActiveOverlays.Add(selectionOverlay);
@@ -79,6 +86,11 @@ internal class ViewportOverlays
         Viewport.ActiveOverlays.Add(snappingOverlay);
         Viewport.ActiveOverlays.Add(snappingOverlay);
         Viewport.ActiveOverlays.Add(brushShapeOverlay);
         Viewport.ActiveOverlays.Add(brushShapeOverlay);
         Viewport.ActiveOverlays.Add(textOverlay);
         Viewport.ActiveOverlays.Add(textOverlay);
+
+        foreach (var overlay in Viewport.ActiveOverlays)
+        {
+            overlay.Bind(Overlay.SuppressEventsProperty, suppressOverlayEventsBinding);
+        }
     }
     }
 
 
     private void BindReferenceLayerOverlay()
     private void BindReferenceLayerOverlay()

+ 20 - 1
src/PixiEditor/Views/Overlays/Overlay.cs

@@ -57,6 +57,18 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
     public Handle? CapturedHandle { get; set; } = null!;
     public Handle? CapturedHandle { get; set; } = null!;
     public VecD PointerPosition { get; internal set; }
     public VecD PointerPosition { get; internal set; }
 
 
+    public static readonly StyledProperty<bool> SuppressEventsProperty = AvaloniaProperty.Register<Overlay, bool>(
+        nameof(SuppressEvents));
+
+    public bool SuppressEvents
+    {
+        get => GetValue(SuppressEventsProperty);
+        set
+        {
+            SetValue(SuppressEventsProperty, value);
+        }
+    }
+
     private readonly Dictionary<AvaloniaProperty, OverlayTransition> activeTransitions = new();
     private readonly Dictionary<AvaloniaProperty, OverlayTransition> activeTransitions = new();
 
 
     private DispatcherTimer? transitionTimer;
     private DispatcherTimer? transitionTimer;
@@ -99,6 +111,7 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
 
 
     public void EnterPointer(OverlayPointerArgs args)
     public void EnterPointer(OverlayPointerArgs args)
     {
     {
+        if(SuppressEvents) return;
         OnOverlayPointerEntered(args);
         OnOverlayPointerEntered(args);
         if (args.Handled) return;
         if (args.Handled) return;
         InvokeHandleEvent(HandleEventType.PointerEnteredOverlay, args);
         InvokeHandleEvent(HandleEventType.PointerEnteredOverlay, args);
@@ -108,6 +121,7 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
 
 
     public void ExitPointer(OverlayPointerArgs args)
     public void ExitPointer(OverlayPointerArgs args)
     {
     {
+        if(SuppressEvents) return;
         OnOverlayPointerExited(args);
         OnOverlayPointerExited(args);
         if (args.Handled) return;
         if (args.Handled) return;
         InvokeHandleEvent(HandleEventType.PointerExitedOverlay, args);
         InvokeHandleEvent(HandleEventType.PointerExitedOverlay, args);
@@ -117,6 +131,7 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
 
 
     public void MovePointer(OverlayPointerArgs args)
     public void MovePointer(OverlayPointerArgs args)
     {
     {
+        if(SuppressEvents) return;
         InvokeHandleEvent(HandleEventType.PointerMovedOverlay, args);
         InvokeHandleEvent(HandleEventType.PointerMovedOverlay, args);
         if (args.Handled) return;
         if (args.Handled) return;
         OnOverlayPointerMoved(args);
         OnOverlayPointerMoved(args);
@@ -138,6 +153,7 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
 
 
     public void PressPointer(OverlayPointerArgs args)
     public void PressPointer(OverlayPointerArgs args)
     {
     {
+        if(SuppressEvents) return;
         InvokeHandleEvent(HandleEventType.PointerPressedOverlay, args);
         InvokeHandleEvent(HandleEventType.PointerPressedOverlay, args);
         if (args.Handled) return;
         if (args.Handled) return;
         OnOverlayPointerPressed(args);
         OnOverlayPointerPressed(args);
@@ -147,6 +163,7 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
 
 
     public void ReleasePointer(OverlayPointerArgs args)
     public void ReleasePointer(OverlayPointerArgs args)
     {
     {
+        if(SuppressEvents) return;
         InvokeHandleEvent(HandleEventType.PointerReleasedOverlay, args);
         InvokeHandleEvent(HandleEventType.PointerReleasedOverlay, args);
         if (args.Handled)
         if (args.Handled)
         {
         {
@@ -165,19 +182,21 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
     
     
     public void KeyPressed(KeyEventArgs args)
     public void KeyPressed(KeyEventArgs args)
     {
     {
+        if(SuppressEvents) return;
         OnKeyPressed(args.Key, args.KeyModifiers, args.KeySymbol);
         OnKeyPressed(args.Key, args.KeyModifiers, args.KeySymbol);
         KeyPressedOverlay?.Invoke(args.Key, args.KeyModifiers);
         KeyPressedOverlay?.Invoke(args.Key, args.KeyModifiers);
     }
     }
 
 
     public void KeyReleased(KeyEventArgs keyEventArgs)
     public void KeyReleased(KeyEventArgs keyEventArgs)
     {
     {
+        if(SuppressEvents) return;
         OnKeyReleased(keyEventArgs.Key, keyEventArgs.KeyModifiers);
         OnKeyReleased(keyEventArgs.Key, keyEventArgs.KeyModifiers);
         KeyReleasedOverlay?.Invoke(keyEventArgs.Key, keyEventArgs.KeyModifiers);
         KeyReleasedOverlay?.Invoke(keyEventArgs.Key, keyEventArgs.KeyModifiers);
     }
     }
 
 
     public virtual bool TestHit(VecD point)
     public virtual bool TestHit(VecD point)
     {
     {
-        return Handles.Any(handle => handle.IsWithinHandle(handle.Position, new VecD(point.X, point.Y), ZoomScale));
+        return !SuppressEvents && Handles.Any(handle => handle.IsWithinHandle(handle.Position, new VecD(point.X, point.Y), ZoomScale));
     }
     }
 
 
     public void AddHandle(Handle handle)
     public void AddHandle(Handle handle)

+ 1 - 1
src/PixiEditor/Views/Overlays/SnappingOverlay.cs

@@ -53,7 +53,7 @@ internal class SnappingOverlay : Overlay
 
 
     public override void RenderOverlay(Canvas context, RectD canvasBounds)
     public override void RenderOverlay(Canvas context, RectD canvasBounds)
     {
     {
-        if (SnappingController is null)
+        if (SnappingController is null || SuppressEvents)
         {
         {
             return;
             return;
         }
         }

+ 7 - 2
src/PixiEditor/Views/Overlays/TransformOverlay/TransformOverlay.cs

@@ -902,9 +902,9 @@ internal class TransformOverlay : Overlay
                 InternalState.ProportionalAngle2, cornersOnStartAnchorDrag, targetPos,
                 InternalState.ProportionalAngle2, cornersOnStartAnchorDrag, targetPos,
                 ScaleFromCenter,
                 ScaleFromCenter,
                 SnappingController,
                 SnappingController,
-                out string snapX, out string snapY, out VecD? snapPoint);
+                out string snapX, out string snapY);
 
 
-            HighlightSnappedAxis(snapX, snapY, snapPoint);
+            VecD? snapPoint = null;
 
 
             if (newCorners is not null)
             if (newCorners is not null)
             {
             {
@@ -917,8 +917,13 @@ internal class TransformOverlay : Overlay
                     : (ShapeCorners)newCorners;
                     : (ShapeCorners)newCorners;
 
 
                 Corners = (ShapeCorners)newCorners;
                 Corners = (ShapeCorners)newCorners;
+                if (!string.IsNullOrEmpty(snapX) || !string.IsNullOrEmpty(snapY))
+                {
+                    snapPoint = TransformHelper.GetAnchorPosition((ShapeCorners)newCorners, (Anchor)capturedAnchor);
+                }
             }
             }
 
 
+            HighlightSnappedAxis(snapX, snapY, snapPoint);
             UpdateOriginPos();
             UpdateOriginPos();
         }
         }
         else if (TransformHelper.IsSide((Anchor)capturedAnchor))
         else if (TransformHelper.IsSide((Anchor)capturedAnchor))

+ 1 - 7
src/PixiEditor/Views/Overlays/TransformOverlay/TransformUpdateHelper.cs

@@ -13,7 +13,7 @@ internal static class TransformUpdateHelper
     public static ShapeCorners? UpdateShapeFromCorner
     public static ShapeCorners? UpdateShapeFromCorner
     (Anchor targetCorner, TransformCornerFreedom freedom, double propAngle1, double propAngle2, ShapeCorners corners,
     (Anchor targetCorner, TransformCornerFreedom freedom, double propAngle1, double propAngle2, ShapeCorners corners,
         VecD desiredPos, bool scaleFromCenter,
         VecD desiredPos, bool scaleFromCenter,
-        SnappingController? snappingController, out string snapX, out string snapY, out VecD? snapPoint)
+        SnappingController? snappingController, out string snapX, out string snapY)
     {
     {
         if (!TransformHelper.IsCorner(targetCorner))
         if (!TransformHelper.IsCorner(targetCorner))
             throw new ArgumentException($"{targetCorner} is not a corner");
             throw new ArgumentException($"{targetCorner} is not a corner");
@@ -21,7 +21,6 @@ internal static class TransformUpdateHelper
         if (freedom == TransformCornerFreedom.Locked)
         if (freedom == TransformCornerFreedom.Locked)
         {
         {
             snapX = snapY = "";
             snapX = snapY = "";
-            snapPoint = null;
             return corners;
             return corners;
         }
         }
 
 
@@ -33,7 +32,6 @@ internal static class TransformUpdateHelper
             VecD oppositePos = TransformHelper.GetAnchorPosition(corners, opposite);
             VecD oppositePos = TransformHelper.GetAnchorPosition(corners, opposite);
 
 
             snapX = snapY = "";
             snapX = snapY = "";
-            snapPoint = null;
 
 
             // constrain desired pos to a "propotional" diagonal line if needed
             // constrain desired pos to a "propotional" diagonal line if needed
             if (freedom == TransformCornerFreedom.ScaleProportionally && corners.IsRect)
             if (freedom == TransformCornerFreedom.ScaleProportionally && corners.IsRect)
@@ -45,7 +43,6 @@ internal static class TransformUpdateHelper
                 if (snappingController is not null)
                 if (snappingController is not null)
                 {
                 {
                     desiredPos = snappingController.GetSnapPoint(desiredPos, direction, out snapX, out snapY);
                     desiredPos = snappingController.GetSnapPoint(desiredPos, direction, out snapX, out snapY);
-                    snapPoint = string.IsNullOrEmpty(snapX) && string.IsNullOrEmpty(snapY) ? null : desiredPos;
                 }
                 }
             }
             }
             else if (freedom == TransformCornerFreedom.ScaleProportionally)
             else if (freedom == TransformCornerFreedom.ScaleProportionally)
@@ -56,7 +53,6 @@ internal static class TransformUpdateHelper
                 if (snappingController is not null)
                 if (snappingController is not null)
                 {
                 {
                     desiredPos = snappingController.GetSnapPoint(desiredPos, direction, out snapX, out snapY);
                     desiredPos = snappingController.GetSnapPoint(desiredPos, direction, out snapX, out snapY);
-                    snapPoint = string.IsNullOrEmpty(snapX) && string.IsNullOrEmpty(snapY) ? null : desiredPos;
                 }
                 }
             }
             }
             else
             else
@@ -64,7 +60,6 @@ internal static class TransformUpdateHelper
                 if (snappingController is not null)
                 if (snappingController is not null)
                 {
                 {
                     desiredPos = snappingController.GetSnapPoint(desiredPos, out snapX, out snapY);
                     desiredPos = snappingController.GetSnapPoint(desiredPos, out snapX, out snapY);
-                    snapPoint = string.IsNullOrEmpty(snapX) && string.IsNullOrEmpty(snapY) ? null : desiredPos;
                 }
                 }
             }
             }
 
 
@@ -143,7 +138,6 @@ internal static class TransformUpdateHelper
         if (freedom == TransformCornerFreedom.Free)
         if (freedom == TransformCornerFreedom.Free)
         {
         {
             snapX = snapY = "";
             snapX = snapY = "";
-            snapPoint = null;
             ShapeCorners newCorners = TransformHelper.UpdateCorner(corners, targetCorner, desiredPos);
             ShapeCorners newCorners = TransformHelper.UpdateCorner(corners, targetCorner, desiredPos);
             return newCorners.IsLegal ? newCorners : null;
             return newCorners.IsLegal ? newCorners : null;
         }
         }

+ 1 - 0
src/PixiEditor/Views/Rendering/Scene.cs

@@ -305,6 +305,7 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
                 }
                 }
 
 
                 overlay.PointerPosition = lastMousePosition;
                 overlay.PointerPosition = lastMousePosition;
+
                 overlay.ZoomScale = Scale;
                 overlay.ZoomScale = Scale;
 
 
                 if (!overlay.CanRender()) continue;
                 if (!overlay.CanRender()) continue;