diff --git a/src/Greenshot.Editor/Drawing/Adorners/MoveAdorner.cs b/src/Greenshot.Editor/Drawing/Adorners/MoveAdorner.cs index 46fcdb1b0..61fc8de11 100644 --- a/src/Greenshot.Editor/Drawing/Adorners/MoveAdorner.cs +++ b/src/Greenshot.Editor/Drawing/Adorners/MoveAdorner.cs @@ -78,7 +78,7 @@ namespace Greenshot.Editor.Drawing.Adorners _boundsAfterResize = _boundsBeforeResize; // calculate scaled rectangle - ScaleHelper.Scale(ref _boundsAfterResize, Position, new PointF(mouseEventArgs.X, mouseEventArgs.Y), ScaleHelper.GetScaleOptions()); + _boundsAfterResize = ScaleHelper.Scale(_boundsAfterResize, Position, new PointF(mouseEventArgs.X, mouseEventArgs.Y), ScaleHelper.GetScaleOptions()); // apply scaled bounds to this DrawableContainer Owner.ApplyBounds(_boundsAfterResize); diff --git a/src/Greenshot.Editor/Drawing/Adorners/ResizeAdorner.cs b/src/Greenshot.Editor/Drawing/Adorners/ResizeAdorner.cs index aaad53355..523684232 100644 --- a/src/Greenshot.Editor/Drawing/Adorners/ResizeAdorner.cs +++ b/src/Greenshot.Editor/Drawing/Adorners/ResizeAdorner.cs @@ -101,7 +101,7 @@ namespace Greenshot.Editor.Drawing.Adorners _boundsAfterResize = _boundsBeforeResize; // calculate scaled rectangle - ScaleHelper.Scale(ref _boundsAfterResize, Position, new PointF(mouseEventArgs.X, mouseEventArgs.Y), ScaleHelper.GetScaleOptions()); + _boundsAfterResize = ScaleHelper.Scale(_boundsAfterResize, Position, new PointF(mouseEventArgs.X, mouseEventArgs.Y), ScaleHelper.GetScaleOptions()); // apply scaled bounds to this DrawableContainer Owner.ApplyBounds(_boundsAfterResize); diff --git a/src/Greenshot.Editor/Drawing/CropContainer.cs b/src/Greenshot.Editor/Drawing/CropContainer.cs index f72f4e72c..2aee4252f 100644 --- a/src/Greenshot.Editor/Drawing/CropContainer.cs +++ b/src/Greenshot.Editor/Drawing/CropContainer.cs @@ -250,7 +250,7 @@ namespace Greenshot.Editor.Drawing break; } } - ScaleHelper.Scale(_boundsBeforeResize, x, y, ref _boundsAfterResize, GetAngleRoundProcessor()); + _boundsAfterResize = ScaleHelper.Scale(_boundsBeforeResize, x, y, GetAngleRoundProcessor()); // apply scaled bounds to this DrawableContainer ApplyBounds(_boundsAfterResize); diff --git a/src/Greenshot.Editor/Drawing/DrawableContainer.cs b/src/Greenshot.Editor/Drawing/DrawableContainer.cs index f80831df2..be4638164 100644 --- a/src/Greenshot.Editor/Drawing/DrawableContainer.cs +++ b/src/Greenshot.Editor/Drawing/DrawableContainer.cs @@ -488,7 +488,7 @@ namespace Greenshot.Editor.Drawing public virtual bool IsConfirmable => false; /// - /// Make a following bounds change on this drawablecontainer undoable! + /// Make a following bounds change on this DrawableContainer undoable! /// /// true means allow the moves to be merged public virtual void MakeBoundsChangeUndoable(bool allowMerge) @@ -514,7 +514,7 @@ namespace Greenshot.Editor.Drawing /// true if the event is handled, false if the surface needs to handle it public virtual bool HandleMouseDown(int x, int y) { - _boundsBeforeResize = _boundsBeforeResize.MoveTo(x, y); + _boundsBeforeResize = Bounds.MoveTo(x, y); Left = x; Top = y; return true; @@ -531,9 +531,9 @@ namespace Greenshot.Editor.Drawing Invalidate(); // reset "workbench" rectangle to current bounds - _boundsAfterResize = _boundsBeforeResize; + _boundsAfterResize = new NativeRectFloat(_boundsBeforeResize.Left, _boundsBeforeResize.Top, x - _boundsAfterResize.Left, y - _boundsAfterResize.Top); - ScaleHelper.Scale(_boundsBeforeResize, x, y, ref _boundsAfterResize, GetAngleRoundProcessor()); + _boundsAfterResize = ScaleHelper.Scale(_boundsAfterResize, x, y, GetAngleRoundProcessor()); // apply scaled bounds to this DrawableContainer ApplyBounds(_boundsAfterResize); @@ -668,7 +668,7 @@ namespace Greenshot.Editor.Drawing protected virtual ScaleHelper.IDoubleProcessor GetAngleRoundProcessor() { - return ScaleHelper.ShapeAngleRoundBehavior.Instance; + return ScaleHelper.ShapeAngleRoundBehavior.INSTANCE; } public virtual bool HasContextMenu => true; diff --git a/src/Greenshot.Editor/Drawing/LineContainer.cs b/src/Greenshot.Editor/Drawing/LineContainer.cs index 5029870a0..ef4a68707 100644 --- a/src/Greenshot.Editor/Drawing/LineContainer.cs +++ b/src/Greenshot.Editor/Drawing/LineContainer.cs @@ -117,7 +117,7 @@ namespace Greenshot.Editor.Drawing protected override ScaleHelper.IDoubleProcessor GetAngleRoundProcessor() { - return ScaleHelper.LineAngleRoundBehavior.Instance; + return ScaleHelper.LineAngleRoundBehavior.INSTANCE; } } } \ No newline at end of file diff --git a/src/Greenshot.Editor/Forms/ImageEditorForm.cs b/src/Greenshot.Editor/Forms/ImageEditorForm.cs index 9c627accc..87c3813c7 100644 --- a/src/Greenshot.Editor/Forms/ImageEditorForm.cs +++ b/src/Greenshot.Editor/Forms/ImageEditorForm.cs @@ -1096,13 +1096,8 @@ namespace Greenshot.Editor.Forms /// /// This is a "work-around" for the MouseWheel event which doesn't get to the panel /// - /// - /// - /// - /// This is a "work-around" for the MouseWheel event which doesn't get to the panel - /// - /// - /// + /// object + /// MouseEventArgs private void PanelMouseWheel(object sender, MouseEventArgs e) { if (System.Windows.Forms.Control.ModifierKeys.Equals(Keys.Control)) diff --git a/src/Greenshot.Editor/Helpers/ScaleHelper.cs b/src/Greenshot.Editor/Helpers/ScaleHelper.cs index b75e8caad..4f4e7dc7a 100644 --- a/src/Greenshot.Editor/Helpers/ScaleHelper.cs +++ b/src/Greenshot.Editor/Helpers/ScaleHelper.cs @@ -59,13 +59,13 @@ namespace Greenshot.Editor.Helpers /// the target size of the element /// in case the aspect ratio of currentSize and targetSize differs: shall the scaled size fit into targetSize (i.e. that one of its dimensions is smaller - false) or vice versa (true) /// a new SizeF object indicating the width and height the element should be scaled to - public static SizeF GetScaledSize(SizeF currentSize, SizeF targetSize, bool crop) + public static NativeSizeFloat GetScaledSize(NativeSizeFloat currentSize, NativeSizeFloat targetSize, bool crop) { float wFactor = targetSize.Width / currentSize.Width; float hFactor = targetSize.Height / currentSize.Height; float factor = crop ? Math.Max(wFactor, hFactor) : Math.Min(wFactor, hFactor); - return new SizeF(currentSize.Width * factor, currentSize.Height * factor); + return new NativeSizeFloat(currentSize.Width * factor, currentSize.Height * factor); } /// @@ -75,58 +75,39 @@ namespace Greenshot.Editor.Helpers /// the rectangle reference for alignment of the element /// the System.Drawing.ContentAlignment value indicating how the element is to be aligned should the width or height differ from targetSize /// a new RectangleF object with Location aligned aligned to targetRect - public static RectangleF GetAlignedRectangle(RectangleF currentRect, RectangleF targetRect, ContentAlignment alignment) + public static NativeRectFloat GetAlignedRectangle(NativeRectFloat currentRect, NativeRectFloat targetRect, ContentAlignment alignment) { - RectangleF newRect = new RectangleF(targetRect.Location, currentRect.Size); - switch (alignment) + var newRect = new NativeRectFloat(targetRect.Location, currentRect.Size); + return alignment switch { - case ContentAlignment.TopCenter: - newRect.X = (targetRect.Width - currentRect.Width) / 2; - break; - case ContentAlignment.TopRight: - newRect.X = targetRect.Width - currentRect.Width; - break; - case ContentAlignment.MiddleLeft: - newRect.Y = (targetRect.Height - currentRect.Height) / 2; - break; - case ContentAlignment.MiddleCenter: - newRect.Y = (targetRect.Height - currentRect.Height) / 2; - newRect.X = (targetRect.Width - currentRect.Width) / 2; - break; - case ContentAlignment.MiddleRight: - newRect.Y = (targetRect.Height - currentRect.Height) / 2; - newRect.X = targetRect.Width - currentRect.Width; - break; - case ContentAlignment.BottomLeft: - newRect.Y = targetRect.Height - currentRect.Height; - break; - case ContentAlignment.BottomCenter: - newRect.Y = targetRect.Height - currentRect.Height; - newRect.X = (targetRect.Width - currentRect.Width) / 2; - break; - case ContentAlignment.BottomRight: - newRect.Y = targetRect.Height - currentRect.Height; - newRect.X = targetRect.Width - currentRect.Width; - break; - } - - return newRect; + // TODO: Can ContentAlignment be replaced with Positions? + ContentAlignment.TopCenter => newRect.ChangeX((targetRect.Width - currentRect.Width) / 2), + ContentAlignment.TopRight => newRect.ChangeX(targetRect.Width - currentRect.Width), + ContentAlignment.MiddleLeft => newRect.ChangeY((targetRect.Height - currentRect.Height) / 2), + ContentAlignment.MiddleCenter => newRect.ChangeY((targetRect.Height - currentRect.Height) / 2).ChangeX((targetRect.Width - currentRect.Width) / 2), + ContentAlignment.MiddleRight => newRect.ChangeY((targetRect.Height - currentRect.Height) / 2).ChangeX(targetRect.Width - currentRect.Width), + ContentAlignment.BottomLeft => newRect.ChangeY(targetRect.Height - currentRect.Height), + ContentAlignment.BottomCenter => newRect.ChangeY(targetRect.Height - currentRect.Height).ChangeX((targetRect.Width - currentRect.Width) / 2), + ContentAlignment.BottomRight => newRect.ChangeY(targetRect.Height - currentRect.Height).ChangeX(targetRect.Width - currentRect.Width), + _ => newRect + }; } /// /// Calculates target size of a given rectangle scaled by dragging one of its handles (corners) /// - /// bounds of the current rectangle, scaled values will be written to this reference + /// bounds of the current rectangle /// position of the handle/gripper being used for resized, see constants in Gripper.cs, e.g. Gripper.POSITION_TOP_LEFT /// coordinates of the used handle/gripper /// ScaleOptions to use when scaling - public static void Scale(ref NativeRectFloat originalRectangle, Positions resizeHandlePosition, NativePointFloat resizeHandleCoords, ScaleOptions? options) + /// NativeRectFloat scaled originalRectangle + public static NativeRectFloat Scale(NativeRectFloat originalRectangle, Positions resizeHandlePosition, NativePointFloat resizeHandleCoords, ScaleOptions? options) { options ??= GetScaleOptions(); if ((options & ScaleOptions.Rational) == ScaleOptions.Rational) { - AdjustCoordsForRationalScale(originalRectangle, resizeHandlePosition, ref resizeHandleCoords); + resizeHandleCoords = AdjustCoordsForRationalScale(originalRectangle, resizeHandlePosition, resizeHandleCoords); } if ((options & ScaleOptions.Centered) == ScaleOptions.Centered) @@ -135,96 +116,40 @@ namespace Greenshot.Editor.Helpers float rectCenterX = originalRectangle.Left + originalRectangle.Width / 2; float rectCenterY = originalRectangle.Top + originalRectangle.Height / 2; // scale rectangle using handle coordinates - Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords); + originalRectangle = Scale(originalRectangle, resizeHandlePosition, resizeHandleCoords); // mirror handle coordinates via rectangle center coordinates resizeHandleCoords = resizeHandleCoords.Offset(-2 * (resizeHandleCoords.X - rectCenterX), -2 * (resizeHandleCoords.Y - rectCenterY)); // scale again with opposing handle and mirrored coordinates resizeHandlePosition = (Positions) ((((int) resizeHandlePosition) + 4) % 8); - Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords); + originalRectangle = Scale(originalRectangle, resizeHandlePosition, resizeHandleCoords); } else { - Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords); + originalRectangle = Scale(originalRectangle, resizeHandlePosition, resizeHandleCoords); } + + return originalRectangle; } /// /// Calculates target size of a given rectangle scaled by dragging one of its handles (corners) /// - /// bounds of the current rectangle, scaled values will be written to this reference + /// bounds of the current rectangle /// position of the handle/gripper being used for resized, see constants in Gripper.cs, e.g. Gripper.POSITION_TOP_LEFT /// coordinates of the used handle/gripper - private static void Scale(ref NativeRectFloat originalRectangle, Positions resizeHandlePosition, NativePointFloat resizeHandleCoords) + /// NativeRectFloat with the scaled originalRectangle + private static NativeRectFloat Scale(NativeRectFloat originalRectangle, Positions resizeHandlePosition, NativePointFloat resizeHandleCoords) { - switch (resizeHandlePosition) + return resizeHandlePosition switch { - case Positions.TopLeft: - originalRectangle = new NativeRectFloat( - resizeHandleCoords.X, - resizeHandleCoords.Y, - originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X, - originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y); - break; - - case Positions.TopCenter: - originalRectangle = new NativeRectFloat( - originalRectangle.X, - resizeHandleCoords.Y, - originalRectangle.Width, - originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y); - break; - - case Positions.TopRight: - originalRectangle = new NativeRectFloat( - originalRectangle.X, - resizeHandleCoords.Y, - resizeHandleCoords.X - originalRectangle.Left, - originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y); - break; - - case Positions.MiddleLeft: - originalRectangle = new NativeRectFloat( - resizeHandleCoords.X, - originalRectangle.Y, - originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X, - originalRectangle.Height); - break; - - case Positions.MiddleRight: - originalRectangle = new NativeRectFloat( - originalRectangle.X, - originalRectangle.Y, - resizeHandleCoords.X - originalRectangle.Left, - originalRectangle.Height); - break; - - case Positions.BottomLeft: - originalRectangle = new NativeRectFloat( - resizeHandleCoords.X, - originalRectangle.Y, - originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X, - resizeHandleCoords.Y - originalRectangle.Top); - break; - - case Positions.BottomCenter: - originalRectangle = new NativeRectFloat( - originalRectangle.X, - originalRectangle.Y, - originalRectangle.Width, - resizeHandleCoords.Y - originalRectangle.Top); - break; - - case Positions.BottomRight: - originalRectangle = new NativeRectFloat( - originalRectangle.X, - originalRectangle.Y, - resizeHandleCoords.X - originalRectangle.Left, - resizeHandleCoords.Y - originalRectangle.Top); - break; - - default: - throw new ArgumentException("Position cannot be handled: " + resizeHandlePosition); - } + Positions.TopLeft => new NativeRectFloat(resizeHandleCoords.X, resizeHandleCoords.Y, originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X, originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y), + Positions.TopCenter => new NativeRectFloat(originalRectangle.X, resizeHandleCoords.Y, originalRectangle.Width, originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y), + Positions.TopRight => new NativeRectFloat(originalRectangle.X, resizeHandleCoords.Y, resizeHandleCoords.X - originalRectangle.Left, originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y), + Positions.MiddleLeft => new NativeRectFloat(resizeHandleCoords.X, originalRectangle.Y, originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X, originalRectangle.Height), + Positions.MiddleRight => new NativeRectFloat(originalRectangle.X, originalRectangle.Y, resizeHandleCoords.X - originalRectangle.Left, originalRectangle.Height), Positions.BottomLeft => new NativeRectFloat(resizeHandleCoords.X, originalRectangle.Y, originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X, resizeHandleCoords.Y - originalRectangle.Top), + Positions.BottomCenter => new NativeRectFloat(originalRectangle.X, originalRectangle.Y, originalRectangle.Width, resizeHandleCoords.Y - originalRectangle.Top), Positions.BottomRight => new NativeRectFloat(originalRectangle.X, originalRectangle.Y, resizeHandleCoords.X - originalRectangle.Left, resizeHandleCoords.Y - originalRectangle.Top), + _ => throw new ArgumentException("Position cannot be handled: " + resizeHandlePosition) + }; } /// @@ -235,37 +160,40 @@ namespace Greenshot.Editor.Helpers /// /// bounds of the current rectangle /// position of the handle/gripper being used for resized, see Position - /// coordinates of the used handle/gripper, adjusted coordinates will be written to this reference - private static void AdjustCoordsForRationalScale(NativeRectFloat originalRectangle, Positions resizeHandlePosition, ref NativePointFloat resizeHandleCoords) + /// coordinates of the used handle/gripper + /// NativePointFloat with the adjusted coordinates + private static NativePointFloat AdjustCoordsForRationalScale(NativeRectFloat originalRectangle, Positions resizeHandlePosition, NativePointFloat resizeHandleCoords) { - SizeF selectedRectangle, newSize; + NativeSizeFloat selectedRectangle, newSize; switch (resizeHandlePosition) { case Positions.TopLeft: - selectedRectangle = new SizeF(originalRectangle.Right - resizeHandleCoords.X, originalRectangle.Bottom - resizeHandleCoords.Y); + selectedRectangle = new NativeSizeFloat(originalRectangle.Right - resizeHandleCoords.X, originalRectangle.Bottom - resizeHandleCoords.Y); newSize = GetNewSizeForRationalScale(originalRectangle.Size, selectedRectangle); resizeHandleCoords = new NativePointFloat(originalRectangle.Right - newSize.Width, originalRectangle.Bottom - newSize.Height); break; case Positions.TopRight: - selectedRectangle = new SizeF(resizeHandleCoords.X - originalRectangle.Left, originalRectangle.Bottom - resizeHandleCoords.Y); + selectedRectangle = new NativeSizeFloat(resizeHandleCoords.X - originalRectangle.Left, originalRectangle.Bottom - resizeHandleCoords.Y); newSize = GetNewSizeForRationalScale(originalRectangle.Size, selectedRectangle); resizeHandleCoords = new NativePointFloat(originalRectangle.Left + newSize.Width, originalRectangle.Bottom - newSize.Height); break; case Positions.BottomLeft: - selectedRectangle = new SizeF(originalRectangle.Right - resizeHandleCoords.X, resizeHandleCoords.Y - originalRectangle.Top); + selectedRectangle = new NativeSizeFloat(originalRectangle.Right - resizeHandleCoords.X, resizeHandleCoords.Y - originalRectangle.Top); newSize = GetNewSizeForRationalScale(originalRectangle.Size, selectedRectangle); resizeHandleCoords = new NativePointFloat(originalRectangle.Right - newSize.Width, originalRectangle.Top + newSize.Height); break; case Positions.BottomRight: - selectedRectangle = new SizeF(resizeHandleCoords.X - originalRectangle.Left, resizeHandleCoords.Y - originalRectangle.Top); + selectedRectangle = new NativeSizeFloat(resizeHandleCoords.X - originalRectangle.Left, resizeHandleCoords.Y - originalRectangle.Top); newSize = GetNewSizeForRationalScale(originalRectangle.Size, selectedRectangle); resizeHandleCoords = new NativePointFloat(originalRectangle.Left + newSize.Width, originalRectangle.Top + newSize.Height); break; } + + return resizeHandleCoords; } /// @@ -299,21 +227,21 @@ namespace Greenshot.Editor.Helpers return newSize; } - public static void Scale(NativeRect boundsBeforeResize, int cursorX, int cursorY, ref NativeRectFloat boundsAfterResize) + public static NativeRectFloat Scale(NativeRect boundsBeforeResize, int cursorX, int cursorY) { - Scale(boundsBeforeResize, cursorX, cursorY, ref boundsAfterResize, null); + return Scale(boundsBeforeResize, cursorX, cursorY, null); } - public static void Scale(NativeRect boundsBeforeResize, int cursorX, int cursorY, ref NativeRectFloat boundsAfterResize, IDoubleProcessor angleRoundBehavior) + public static NativeRectFloat Scale(NativeRect boundsBeforeResize, int cursorX, int cursorY, IDoubleProcessor angleRoundBehavior) { - Scale(boundsBeforeResize, Positions.TopLeft, cursorX, cursorY, ref boundsAfterResize, angleRoundBehavior); + return Scale(boundsBeforeResize, Positions.TopLeft, cursorX, cursorY, angleRoundBehavior); } - public static void Scale(NativeRect boundsBeforeResize, Positions gripperPosition, int cursorX, int cursorY, ref NativeRectFloat boundsAfterResize, - IDoubleProcessor angleRoundBehavior) + public static NativeRectFloat Scale(NativeRect boundsBeforeResize, Positions gripperPosition, int cursorX, int cursorY, IDoubleProcessor angleRoundBehavior) { ScaleOptions opts = GetScaleOptions(); + NativeRectFloat result = boundsBeforeResize; bool rationalScale = (opts & ScaleOptions.Rational) == ScaleOptions.Rational; bool centeredScale = (opts & ScaleOptions.Centered) == ScaleOptions.Centered; @@ -328,17 +256,19 @@ namespace Greenshot.Editor.Helpers int dist = GeometryHelper.Distance2D(boundsBeforeResize.X, boundsBeforeResize.Y, cursorX, cursorY); - boundsAfterResize = boundsAfterResize + result = result .ChangeWidth((int)Math.Round(dist * Math.Cos(angle / 180 * Math.PI))) .ChangeHeight((int) Math.Round(dist * Math.Sin(angle / 180 * Math.PI))); } if (centeredScale) { - float wdiff = boundsAfterResize.Width - boundsBeforeResize.Width; - float hdiff = boundsAfterResize.Height - boundsBeforeResize.Height; - boundsAfterResize = boundsAfterResize.Inflate(wdiff, hdiff); + float wdiff = result.Width - result.Width; + float hdiff = result.Height - result.Height; + result = result.Inflate(wdiff, hdiff); } + + return result; } /// the current ScaleOptions depending on modifier keys held down @@ -359,7 +289,7 @@ namespace Greenshot.Editor.Helpers public class ShapeAngleRoundBehavior : IDoubleProcessor { - public static ShapeAngleRoundBehavior Instance = new(); + public static readonly ShapeAngleRoundBehavior INSTANCE = new(); private ShapeAngleRoundBehavior() { @@ -373,7 +303,7 @@ namespace Greenshot.Editor.Helpers public class LineAngleRoundBehavior : IDoubleProcessor { - public static LineAngleRoundBehavior Instance = new(); + public static readonly LineAngleRoundBehavior INSTANCE = new(); private LineAngleRoundBehavior() {