Browse Source

Make single click cancel shape transform

Equbuxu 3 years ago
parent
commit
ca7a631dab

+ 12 - 2
src/PixiEditor.ChangeableDocument/Changes/Drawing/DrawEllipse_UpdateableChange.cs

@@ -41,8 +41,12 @@ internal class DrawEllipse_UpdateableChange : UpdateableChange
         var oldAffectedChunks = targetImage.FindAffectedChunks();
 
         targetImage.CancelChanges();
-        DrawingChangeHelper.ApplyClipsSymmetriesEtc(target, targetImage, memberGuid, drawOnMask);
-        targetImage.EnqueueDrawEllipse(location, strokeColor, fillColor, strokeWidth);
+
+        if (!location.IsZeroOrNegativeArea)
+        {
+            DrawingChangeHelper.ApplyClipsSymmetriesEtc(target, targetImage, memberGuid, drawOnMask);
+            targetImage.EnqueueDrawEllipse(location, strokeColor, fillColor, strokeWidth);
+        }
 
         var affectedChunks = targetImage.FindAffectedChunks();
         affectedChunks.UnionWith(oldAffectedChunks);
@@ -52,6 +56,12 @@ internal class DrawEllipse_UpdateableChange : UpdateableChange
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply, out bool ignoreInUndo)
     {
+        if (location.IsZeroOrNegativeArea)
+        {
+            ignoreInUndo = true;
+            return new None();
+        }
+
         var image = DrawingChangeHelper.GetTargetImageOrThrow(target, memberGuid, drawOnMask);
         var chunks = UpdateEllipse(target, image);
         storedChunks = new CommittedChunkStorage(image, image.FindAffectedChunks());

+ 17 - 8
src/PixiEditor.ChangeableDocument/Changes/Drawing/DrawLine_UpdateableChange.cs

@@ -2,7 +2,7 @@
 
 namespace PixiEditor.ChangeableDocument.Changes.Drawing;
 
-internal class DrawLine_UpdateableChange : UpdateableChange 
+internal class DrawLine_UpdateableChange : UpdateableChange
 {
     private readonly Guid memberGuid;
     private VecI from;
@@ -35,7 +35,7 @@ internal class DrawLine_UpdateableChange : UpdateableChange
         this.caps = caps;
         this.strokeWidth = strokeWidth;
     }
-    
+
     public override OneOf<Success, Error> InitializeAndValidate(Document target)
     {
         if (!DrawingChangeHelper.IsValidForDrawing(target, memberGuid, drawOnMask))
@@ -48,11 +48,14 @@ internal class DrawLine_UpdateableChange : UpdateableChange
         var image = DrawingChangeHelper.GetTargetImageOrThrow(target, memberGuid, drawOnMask);
         var oldAffected = image.FindAffectedChunks();
         image.CancelChanges();
-        DrawingChangeHelper.ApplyClipsSymmetriesEtc(target, image, memberGuid, drawOnMask);
-        if (strokeWidth == 1)
-            image.EnqueueDrawBresenhamLine(from, to, color, SKBlendMode.SrcOver);
-        else
-            image.EnqueueDrawSkiaLine(from, to, caps, strokeWidth, color, SKBlendMode.SrcOver);
+        if (from != to)
+        {
+            DrawingChangeHelper.ApplyClipsSymmetriesEtc(target, image, memberGuid, drawOnMask);
+            if (strokeWidth == 1)
+                image.EnqueueDrawBresenhamLine(from, to, color, SKBlendMode.SrcOver);
+            else
+                image.EnqueueDrawSkiaLine(from, to, caps, strokeWidth, color, SKBlendMode.SrcOver);
+        }
         var totalAffected = image.FindAffectedChunks();
         totalAffected.UnionWith(oldAffected);
         return totalAffected;
@@ -65,13 +68,19 @@ internal class DrawLine_UpdateableChange : UpdateableChange
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply, out bool ignoreInUndo)
     {
+        if (from == to)
+        {
+            ignoreInUndo = true;
+            return new None();
+        }
+
         var image = DrawingChangeHelper.GetTargetImageOrThrow(target, memberGuid, drawOnMask);
         var affected = CommonApply(target);
         if (savedChunks is not null)
             throw new InvalidOperationException("Trying to save chunks while there are saved chunks already");
         savedChunks = new CommittedChunkStorage(image, image.FindAffectedChunks());
         image.CommitChanges();
-        
+
         ignoreInUndo = false;
         return DrawingChangeHelper.CreateChunkChangeInfo(memberGuid, affected, drawOnMask);
     }

+ 12 - 2
src/PixiEditor.ChangeableDocument/Changes/Drawing/DrawRectangle_UpdateableChange.cs

@@ -33,8 +33,12 @@ internal class DrawRectangle_UpdateableChange : UpdateableChange
         var oldAffectedChunks = targetImage.FindAffectedChunks();
 
         targetImage.CancelChanges();
-        DrawingChangeHelper.ApplyClipsSymmetriesEtc(target, targetImage, memberGuid, drawOnMask);
-        targetImage.EnqueueDrawRectangle(rect);
+
+        if (!(rect.Size.X <= 0 || rect.Size.Y <= 0))
+        {
+            DrawingChangeHelper.ApplyClipsSymmetriesEtc(target, targetImage, memberGuid, drawOnMask);
+            targetImage.EnqueueDrawRectangle(rect);
+        }
 
         var affectedChunks = targetImage.FindAffectedChunks();
         affectedChunks.UnionWith(oldAffectedChunks);
@@ -51,6 +55,12 @@ internal class DrawRectangle_UpdateableChange : UpdateableChange
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply, out bool ignoreInUndo)
     {
+        if (rect.Size.X <= 0 || rect.Size.Y <= 0)
+        {
+            ignoreInUndo = true;
+            return new None();
+        }
+
         ChunkyImage targetImage = DrawingChangeHelper.GetTargetImageOrThrow(target, memberGuid, drawOnMask);
         var affectedChunks = UpdateRectangle(target, targetImage);
         storedChunks = new CommittedChunkStorage(targetImage, affectedChunks);

+ 5 - 3
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/EllipseToolExecutor.cs

@@ -7,10 +7,12 @@ namespace PixiEditor.Models.DocumentModels.UpdateableChangeExecutors;
 #nullable enable
 internal class EllipseToolExecutor : ShapeToolExecutor<EllipseToolViewModel>
 {
-    private void DrawEllipseOrCircle(VecI curPos)
+    private void DrawEllipseOrCircle(VecI curPos, bool firstDraw)
     {
         RectI rect;
-        if (toolViewModel!.DrawCircle)
+        if (firstDraw)
+            rect = new RectI(curPos, VecI.Zero);
+        else if (toolViewModel!.DrawCircle)
             rect = GetSquaredCoordinates(startPos, curPos);
         else
             rect = RectI.FromTwoPixels(startPos, curPos);
@@ -22,7 +24,7 @@ internal class EllipseToolExecutor : ShapeToolExecutor<EllipseToolViewModel>
 
     public override ExecutorType Type => ExecutorType.ToolLinked;
     protected override DocumentTransformMode TransformMode => DocumentTransformMode.NoRotation;
-    protected override void DrawShape(VecI currentPos) => DrawEllipseOrCircle(currentPos);
+    protected override void DrawShape(VecI currentPos, bool firstDraw) => DrawEllipseOrCircle(currentPos, firstDraw);
 
     protected override IAction TransformMovedAction(ShapeData data, ShapeCorners corners) =>
         new DrawEllipse_Action(memberGuid, (RectI)RectD.FromCenterAndSize(data.Center, data.Size), strokeColor,

+ 4 - 4
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/LineToolExecutor.cs

@@ -30,13 +30,13 @@ internal class LineToolExecutor : ShapeToolExecutor<LineToolViewModel>
         memberGuid = member.GuidValue;
 
         colorsVM.AddSwatch(strokeColor);
-        DrawShape(startPos);
+        DrawShape(startPos, true);
         return ExecutionState.Success;
     }
 
-    private void DrawLine(VecI curPos)
+    private void DrawLine(VecI curPos, bool firstDraw)
     {
-        RectI rect = RectI.FromTwoPixels(startPos, curPos);
+        RectI rect = firstDraw ? new RectI(curPos, VecI.Zero) : RectI.FromTwoPixels(startPos, curPos);
         if (rect.Width == 0)
             rect.Width = 1;
         if (rect.Height == 0)
@@ -47,7 +47,7 @@ internal class LineToolExecutor : ShapeToolExecutor<LineToolViewModel>
         internals!.ActionAccumulator.AddActions(new DrawLine_Action(memberGuid, startPos, curPos, strokeWidth, strokeColor, SKStrokeCap.Butt, drawOnMask));
     }
 
-    protected override void DrawShape(VecI currentPos) => DrawLine(currentPos);
+    protected override void DrawShape(VecI currentPos, bool firstDraw) => DrawLine(currentPos, firstDraw);
 
     protected override IAction TransformMovedAction(ShapeData data, ShapeCorners corners)
     {

+ 5 - 3
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/RectangleToolExecutor.cs

@@ -8,10 +8,12 @@ namespace PixiEditor.Models.DocumentModels.UpdateableChangeExecutors;
 internal class RectangleToolExecutor : ShapeToolExecutor<RectangleToolViewModel>
 {
     public override ExecutorType Type => ExecutorType.ToolLinked;
-    private void DrawRectangle(VecI curPos)
+    private void DrawRectangle(VecI curPos, bool firstDraw)
     {
         RectI rect;
-        if (toolViewModel!.DrawSquare)
+        if (firstDraw)
+            rect = new RectI(curPos, VecI.Zero);
+        else if (toolViewModel!.DrawSquare)
             rect = GetSquaredCoordinates(startPos, curPos);
         else
             rect = RectI.FromTwoPixels(startPos, curPos);
@@ -20,7 +22,7 @@ internal class RectangleToolExecutor : ShapeToolExecutor<RectangleToolViewModel>
         internals!.ActionAccumulator.AddActions(new DrawRectangle_Action(memberGuid, new ShapeData(rect.Center, rect.Size, 0, strokeWidth, strokeColor, fillColor), drawOnMask));
     }
 
-    protected override void DrawShape(VecI currentPos) => DrawRectangle(currentPos);
+    protected override void DrawShape(VecI currentPos, bool first) => DrawRectangle(currentPos, first);
 
     protected override IAction TransformMovedAction(ShapeData data, ShapeCorners corners) => new DrawRectangle_Action(memberGuid, data, drawOnMask);
 

+ 12 - 4
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/ShapeToolExecutor.cs

@@ -22,6 +22,8 @@ internal abstract class ShapeToolExecutor<T> : UpdateableChangeExecutor where T
     protected VecI startPos;
     protected RectI lastRect;
 
+    private bool noMovement = true;
+
     public override ExecutionState Start()
     {
         ColorsViewModel? colorsVM = ViewModelMain.Current?.ColorsSubViewModel;
@@ -43,11 +45,11 @@ internal abstract class ShapeToolExecutor<T> : UpdateableChangeExecutor where T
         memberGuid = member.GuidValue;
 
         colorsVM.AddSwatch(strokeColor);
-        DrawShape(startPos);
+        DrawShape(startPos, true);
         return ExecutionState.Success;
     }
 
-    protected abstract void DrawShape(VecI currentPos);
+    protected abstract void DrawShape(VecI currentPos, bool firstDraw);
     protected abstract IAction TransformMovedAction(ShapeData data, ShapeCorners corners);
     protected abstract IAction EndDrawAction();
     protected virtual DocumentTransformMode TransformMode => DocumentTransformMode.Rotation;
@@ -86,14 +88,20 @@ internal abstract class ShapeToolExecutor<T> : UpdateableChangeExecutor where T
     {
         if (transforming)
             return;
-
-        DrawShape(pos);
+        noMovement = false;
+        DrawShape(pos, false);
     }
 
     public override void OnLeftMouseButtonUp()
     {
         if (transforming)
             return;
+        if (noMovement)
+        {
+            internals!.ActionAccumulator.AddFinishedActions(EndDrawAction());
+            onEnded?.Invoke(this);
+            return;
+        }
         transforming = true;
         document!.TransformViewModel.ShowTransform(TransformMode, false, new ShapeCorners(lastRect));
     }