Browse Source

Even shape drawing snapping

flabbet 8 months ago
parent
commit
8dfe49eff3

+ 42 - 2
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/ComplexShapeToolExecutor.cs

@@ -60,7 +60,8 @@ internal abstract class ComplexShapeToolExecutor<T> : SimpleShapeToolExecutor wh
                 toolbar.StrokeColor = colorsVM.PrimaryColor.ToColor();
             }
 
-            document!.TransformHandler.ShowTransform(TransformMode, false, new ShapeCorners((RectD)lastRect.Inflate(1)), false);
+            document!.TransformHandler.ShowTransform(TransformMode, false, new ShapeCorners((RectD)lastRect.Inflate(1)),
+                false);
             document.TransformHandler.ShowHandles = false;
             document.TransformHandler.IsSizeBoxEnabled = true;
             return ExecutionState.Success;
@@ -207,7 +208,19 @@ internal abstract class ComplexShapeToolExecutor<T> : SimpleShapeToolExecutor wh
 
     protected override void PrecisePositionChangeDrawingMode(VecD pos)
     {
-        var snapped = Snap(pos, startDrawingPos, true);
+        VecI adjustedPos = (VecI)pos.Floor();
+
+        VecD snapped = adjustedPos;
+        if (toolViewModel.DrawEven)
+        {
+            adjustedPos = GetSquaredPosition((VecI)startDrawingPos, adjustedPos);
+            VecD dir = (adjustedPos - startDrawingPos).Normalize();
+            snapped = Snap(adjustedPos, startDrawingPos, dir, true);
+        }
+        else
+        {
+            snapped = Snap(adjustedPos, startDrawingPos, true);
+        }
 
         noMovement = false;
 
@@ -244,6 +257,33 @@ internal abstract class ComplexShapeToolExecutor<T> : SimpleShapeToolExecutor wh
         return snapped;
     }
 
+    protected VecD Snap(VecD pos, VecD adjustPos, VecD dir, bool highlight = false)
+    {
+        VecD snapped =
+            document.SnappingHandler.SnappingController.GetSnapPoint(pos, dir, out string snapXAxis,
+                out string snapYAxis);
+
+        if (highlight)
+        {
+            HighlightSnapAxis(snapXAxis, snapYAxis);
+        }
+
+        if (snapped != VecI.Zero)
+        {
+            if (adjustPos.X < pos.X)
+            {
+                snapped -= new VecI(1, 0);
+            }
+
+            if (adjustPos.Y < pos.Y)
+            {
+                snapped -= new VecI(0, 1);
+            }
+        }
+
+        return snapped;
+    }
+
     private void HighlightSnapAxis(string snapXAxis, string snapYAxis)
     {
         document.SnappingHandler.SnappingController.HighlightedXAxis = snapXAxis;

+ 2 - 2
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/RasterEllipseToolExecutor.cs

@@ -17,9 +17,9 @@ internal class RasterEllipseToolExecutor : ComplexShapeToolExecutor<IRasterEllip
         VecI startPos = (VecI)Snap(startDrawingPos, curPos).Floor();
         if (firstDraw)
             rect = new RectI(curPos, VecI.Zero);
-        else if (toolViewModel!.DrawCircle)
+        /*else if (toolViewModel!.DrawCircle)
             rect = GetSquaredCoordinates(startPos, curPos);
-        else
+        else*/
             rect = RectI.FromTwoPixels(startPos, curPos);
 
         lastRect = rect;

+ 2 - 2
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/RasterRectangleToolExecutor.cs

@@ -18,9 +18,9 @@ internal class RasterRectangleToolExecutor : ComplexShapeToolExecutor<IRasterRec
         VecI startPos = (VecI)Snap(startDrawingPos, curPos).Floor();
         if (firstDraw)
             rect = new RectI(curPos, VecI.Zero);
-        else if (toolViewModel!.DrawSquare)
+        /*else if (toolViewModel!.DrawSquare)
             rect = GetSquaredCoordinates(startPos, curPos);
-        else
+        else*/
             rect = RectI.FromTwoPixels(startPos, curPos);
         lastRect = rect;
         lastRadians = rotationRad;

+ 2 - 2
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/VectorEllipseToolExecutor.cs

@@ -38,9 +38,9 @@ internal class VectorEllipseToolExecutor : ComplexShapeToolExecutor<IVectorEllip
         VecI startPos = (VecI)Snap(startDrawingPos, curPos).Floor();
         if (firstDraw)
             rect = new RectI(curPos, VecI.Zero);
-        else if (toolViewModel!.DrawCircle)
+        /*else if (toolViewModel!.DrawCircle)
             rect = GetSquaredCoordinates(startPos, curPos);
-        else
+        else*/
             rect = RectI.FromTwoPixels(startPos, curPos);
 
         firstCenter = rect.Center;

+ 2 - 2
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/VectorRectangleToolExecutor.cs

@@ -38,9 +38,9 @@ internal class VectorRectangleToolExecutor : ComplexShapeToolExecutor<IVectorRec
         VecI startPos = (VecI)Snap(startDrawingPos, curPos).Floor();
         if (firstDraw)
             rect = new RectI(curPos, VecI.Zero);
-        else if (toolViewModel!.DrawSquare)
+        /*else if (toolViewModel!.DrawSquare)
             rect = GetSquaredCoordinates(startPos, curPos);
-        else
+        else*/
             rect = RectI.FromTwoPixels(startPos, curPos);
 
         firstCenter = rect.Center;

+ 0 - 1
src/PixiEditor/Models/Handlers/Tools/IRasterEllipseToolHandler.cs

@@ -2,5 +2,4 @@
 
 internal interface IRasterEllipseToolHandler : IShapeToolHandler
 {
-    public bool DrawCircle { get; }
 }

+ 0 - 1
src/PixiEditor/Models/Handlers/Tools/IRasterRectangleToolHandler.cs

@@ -2,5 +2,4 @@
 
 internal interface IRasterRectangleToolHandler : IShapeToolHandler
 {
-    public bool DrawSquare { get; }
 }

+ 1 - 1
src/PixiEditor/Models/Handlers/Tools/IShapeToolHandler.cs

@@ -2,5 +2,5 @@
 
 internal interface IShapeToolHandler : IToolHandler
 {
-
+    public bool DrawEven { get; }
 }

+ 0 - 1
src/PixiEditor/Models/Handlers/Tools/IVectorEllipseToolHandler.cs

@@ -2,5 +2,4 @@
 
 internal interface IVectorEllipseToolHandler : IShapeToolHandler
 {
-    public bool DrawCircle { get; }
 }

+ 0 - 1
src/PixiEditor/Models/Handlers/Tools/IVectorRectangleToolHandler.cs

@@ -2,5 +2,4 @@
 
 internal interface IVectorRectangleToolHandler : IShapeToolHandler
 {
-    public bool DrawSquare { get; }
 }

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

@@ -13,6 +13,7 @@ internal abstract class ShapeTool : ToolViewModel, IShapeToolHandler
     public override bool UsesColor => true;
 
     public override bool IsErasable => true;
+    public bool DrawEven { get; protected set; }
 
     public ShapeTool()
     {
@@ -27,4 +28,5 @@ internal abstract class ShapeTool : ToolViewModel, IShapeToolHandler
             ViewModelMain.Current.DocumentManagerSubViewModel.ActiveDocument?.Operations.TryStopToolLinkedExecutor();
         }
     }
+
 }

+ 2 - 3
src/PixiEditor/ViewModels/Tools/Tools/RasterEllipseToolViewModel.cs

@@ -23,7 +23,6 @@ internal class RasterEllipseToolViewModel : ShapeTool, IRasterEllipseToolHandler
 
     public override Type[]? SupportedLayerTypes { get; } = { typeof(IRasterLayerHandler) };
     public override LocalizedString Tooltip => new LocalizedString("ELLIPSE_TOOL_TOOLTIP", Shortcut);
-    public bool DrawCircle { get; private set; }
 
     public override string DefaultIcon => PixiPerfectIcons.LowResCircle;
 
@@ -34,12 +33,12 @@ internal class RasterEllipseToolViewModel : ShapeTool, IRasterEllipseToolHandler
         if (shiftIsDown)
         {
             ActionDisplay = "ELLIPSE_TOOL_ACTION_DISPLAY_SHIFT";
-            DrawCircle = true;
+            DrawEven = true;
         }
         else
         {
             ActionDisplay = defaultActionDisplay;
-            DrawCircle = false;
+            DrawEven = false;
         }
     }
 

+ 2 - 3
src/PixiEditor/ViewModels/Tools/Tools/RasterRectangleToolViewModel.cs

@@ -24,7 +24,6 @@ internal class RasterRectangleToolViewModel : ShapeTool, IRasterRectangleToolHan
     public override LocalizedString Tooltip => new LocalizedString("RECTANGLE_TOOL_TOOLTIP", Shortcut);
 
     public bool Filled { get; set; } = false;
-    public bool DrawSquare { get; private set; } = false;
 
     public override string DefaultIcon => PixiPerfectIcons.LowResSquare;
 
@@ -34,12 +33,12 @@ internal class RasterRectangleToolViewModel : ShapeTool, IRasterRectangleToolHan
     {
         if (shiftIsDown)
         {
-            DrawSquare = true;
+            DrawEven = true;
             ActionDisplay = "RECTANGLE_TOOL_ACTION_DISPLAY_SHIFT";
         }
         else
         {
-            DrawSquare = false;
+            DrawEven = false;
             ActionDisplay = defaultActionDisplay;
         }
     }

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

@@ -26,7 +26,6 @@ internal class VectorEllipseToolViewModel : ShapeTool, IVectorEllipseToolHandler
     // This doesn't include a Vector layer because it is designed to create new layer each use
     public override Type[]? SupportedLayerTypes { get; } = [];
     public override LocalizedString Tooltip => new LocalizedString("ELLIPSE_TOOL_TOOLTIP", Shortcut);
-    public bool DrawCircle { get; private set; }
 
     public override string DefaultIcon => PixiPerfectIcons.Circle;
 
@@ -43,12 +42,12 @@ internal class VectorEllipseToolViewModel : ShapeTool, IVectorEllipseToolHandler
     {
         if (shiftIsDown)
         {
-            DrawCircle = true;
+            DrawEven = true;
             ActionDisplay = "RECTANGLE_TOOL_ACTION_DISPLAY_SHIFT";
         }
         else
         {
-            DrawCircle = false;
+            DrawEven = false;
             ActionDisplay = defaultActionDisplay;
         }
     }

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

@@ -25,7 +25,6 @@ internal class VectorRectangleToolViewModel : ShapeTool, IVectorRectangleToolHan
 
     public override Type[]? SupportedLayerTypes { get; } = [];
     public override LocalizedString Tooltip => new LocalizedString("RECTANGLE_TOOL_TOOLTIP", Shortcut);
-    public bool DrawSquare { get; private set; }
 
     public override string DefaultIcon => PixiPerfectIcons.Square;
 
@@ -36,12 +35,12 @@ internal class VectorRectangleToolViewModel : ShapeTool, IVectorRectangleToolHan
     {
         if (shiftIsDown)
         {
-            DrawSquare = true;
+            DrawEven = true;
             ActionDisplay = "RECTANGLE_TOOL_ACTION_DISPLAY_SHIFT";
         }
         else
         {
-            DrawSquare = false;
+            DrawEven = false;
             ActionDisplay = defaultActionDisplay;
         }
     }