diff --git a/.gitignore b/.gitignore
index 63d68f324..6dd4cfed8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,6 +24,7 @@ po/Makefile.in.in
po/POTFILES
po/stamp-it
xdg/pinta.desktop
+.vs
# Help
help/*/*.mo
diff --git a/Pinta.Core/Effects/Utility.cs b/Pinta.Core/Effects/Utility.cs
index 69267d7a1..a9f92c038 100644
--- a/Pinta.Core/Effects/Utility.cs
+++ b/Pinta.Core/Effects/Utility.cs
@@ -639,5 +639,26 @@ public static int FastDivideShortByByte(ushort n, byte d)
0x80808081, 0x00000000, 39 // 255
};
- }
+ ///
+ /// Gets the nearest step angle in radians.
+ ///
+ /// The nearest step angle in radians.
+ /// Angle in radians.
+ /// Number of steps to divide the circle.
+ public static double GetNearestStepAngle (double angle, int steps)
+ {
+ double fullTurn = 2 * Math.PI;
+ double stepAngle = fullTurn / steps;
+ double normalizedAngle = angle % fullTurn;
+ int sector = Convert.ToInt32 (Math.Truncate ((normalizedAngle % fullTurn) / stepAngle));
+
+ var leftStepAngle = sector * stepAngle;
+ var rightStepAngle = (sector + 1) * stepAngle;
+
+ if ((angle - leftStepAngle) < (rightStepAngle - angle))
+ return leftStepAngle;
+ else
+ return rightStepAngle;
+ }
+ }
}
diff --git a/Pinta.Tools/Tools/BaseTransformTool.cs b/Pinta.Tools/Tools/BaseTransformTool.cs
index 7c4a88e4b..69c79c167 100644
--- a/Pinta.Tools/Tools/BaseTransformTool.cs
+++ b/Pinta.Tools/Tools/BaseTransformTool.cs
@@ -31,19 +31,21 @@ namespace Pinta.Tools
{
public abstract class BaseTransformTool : BaseTool
{
- #region Members
- private readonly Matrix transform = new Matrix();
+ #region Members
+ private readonly int rotate_steps = 32;
+ private readonly Matrix transform = new Matrix();
private Rectangle source_rect;
private PointD original_point;
private bool is_dragging = false;
private bool is_rotating = false;
- #endregion
-
- #region Constructor
- ///
- /// Initializes a new instance of the class.
- ///
- public BaseTransformTool ()
+ private bool rotateBySteps = false;
+ #endregion
+
+ #region Constructor
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public BaseTransformTool ()
{
}
#endregion
@@ -115,7 +117,10 @@ protected virtual void OnFinishTransform()
if (is_rotating)
{
- transform.Translate(center.X, center.Y);
+ if (rotateBySteps)
+ angle = Utility.GetNearestStepAngle (angle, rotate_steps);
+
+ transform.Translate(center.X, center.Y);
transform.Rotate(-angle);
transform.Translate(-center.X, -center.Y);
}
@@ -134,7 +139,17 @@ protected override void OnMouseUp (Gtk.DrawingArea canvas, Gtk.ButtonReleaseEven
OnFinishTransform();
}
- #endregion
- }
+
+ protected override void OnKeyDown (Gtk.DrawingArea canvas, Gtk.KeyPressEventArgs args)
+ {
+ rotateBySteps = (args.Event.Key == Gdk.Key.Shift_L);
+ }
+
+ protected override void OnKeyUp (Gtk.DrawingArea canvas, Gtk.KeyReleaseEventArgs args)
+ {
+ rotateBySteps = false;
+ }
+ #endregion
+ }
}
diff --git a/Pinta.Tools/Tools/MoveSelectedTool.cs b/Pinta.Tools/Tools/MoveSelectedTool.cs
index de241deba..b3ea06579 100644
--- a/Pinta.Tools/Tools/MoveSelectedTool.cs
+++ b/Pinta.Tools/Tools/MoveSelectedTool.cs
@@ -46,7 +46,7 @@ public class MoveSelectedTool : BaseTransformTool
get { return "Tools.Move.png"; }
}
public override string StatusBarText {
- get { return Catalog.GetString ("Left click and drag the selection to move selected content. Right click and drag the selection to rotate selected content."); }
+ get { return Catalog.GetString ("Left click and drag the selection to move selected content. Right click and drag the selection to rotate selected content. Hold Shift to rotate in steps."); }
}
public override Gdk.Cursor DefaultCursor {
get { return new Gdk.Cursor (Gdk.Display.Default, PintaCore.Resources.GetIcon ("Tools.Move.png"), 0, 0); }
diff --git a/Pinta.Tools/Tools/MoveSelectionTool.cs b/Pinta.Tools/Tools/MoveSelectionTool.cs
index 35bdc6d65..923a5a91e 100644
--- a/Pinta.Tools/Tools/MoveSelectionTool.cs
+++ b/Pinta.Tools/Tools/MoveSelectionTool.cs
@@ -45,7 +45,7 @@ public class MoveSelectionTool : BaseTransformTool
get { return "Tools.MoveSelection.png"; }
}
public override string StatusBarText {
- get { return Catalog.GetString ("Left click and drag the selection to move selection outline. Right click and drag the selection to rotate selection outline."); }
+ get { return Catalog.GetString ("Left click and drag the selection to move selection outline. Right click and drag the selection to rotate selection outline. Hold Shift to rotate in steps."); }
}
public override Gdk.Cursor DefaultCursor {
get { return new Gdk.Cursor (Gdk.Display.Default, PintaCore.Resources.GetIcon ("Tools.MoveSelection.png"), 0, 0); }