diff --git a/src/Greenshot.Base/Interfaces/Drawing/IDrawableContainer.cs b/src/Greenshot.Base/Interfaces/Drawing/IDrawableContainer.cs index 80e2bd140..27ab67425 100644 --- a/src/Greenshot.Base/Interfaces/Drawing/IDrawableContainer.cs +++ b/src/Greenshot.Base/Interfaces/Drawing/IDrawableContainer.cs @@ -29,6 +29,14 @@ using Greenshot.Base.Interfaces.Drawing.Adorners; namespace Greenshot.Base.Interfaces.Drawing { + public enum Direction + { + LEFT, + RIGHT, + TOP, + BOTTOM, + } + public interface IDrawableContainer : INotifyPropertyChanged, IDisposable { /// @@ -111,5 +119,12 @@ namespace Greenshot.Base.Interfaces.Drawing /// ISurface /// MouseEventArgs void AddContextMenuItems(ContextMenuStrip menu, ISurface surface, MouseEventArgs mouseEventArgs); + + /// + /// Snap the container to the edge of the surface. + /// + /// Direction in which to move the container. + /// The surface the container belongs to. + void SnapToEdge(Direction direction, ISurface surface); } } \ No newline at end of file diff --git a/src/Greenshot.Editor/Drawing/DrawableContainer.cs b/src/Greenshot.Editor/Drawing/DrawableContainer.cs index cac23dc3a..4961dda01 100644 --- a/src/Greenshot.Editor/Drawing/DrawableContainer.cs +++ b/src/Greenshot.Editor/Drawing/DrawableContainer.cs @@ -684,5 +684,43 @@ namespace Greenshot.Editor.Drawing protected virtual void InitializeFields() { } + + /// + /// Snap the container to the edge of the surface. + /// + /// Direction in which to move the container. + /// The surface the container belongs to. + public void SnapToEdge(Direction direction, ISurface surface) + { + Size surfaceBounds = new(surface.Image.Width, surface.Image.Height); + NativeRectFloat newBounds = GetLocationAfterSnap(direction, this.Bounds, surfaceBounds); + + this.MakeBoundsChangeUndoable(allowMerge: false); + this.ApplyBounds(newBounds); + } + + private static NativeRectFloat GetLocationAfterSnap(Direction direction, NativeRect bounds, Size surfaceSize) + { + switch (direction) + { + case Direction.LEFT: + bounds = bounds.ChangeX(0); + break; + case Direction.RIGHT: + bounds = bounds.Offset(offsetX: surfaceSize.Width - bounds.Right); + break; + case Direction.TOP: + bounds = bounds.ChangeY(0); + break; + case Direction.BOTTOM: + bounds = bounds.Offset(offsetY: surfaceSize.Height - bounds.Bottom); + break; + default: + break; + } + return bounds; + } + + } } \ No newline at end of file diff --git a/src/Greenshot.Editor/Drawing/DrawableContainerList.cs b/src/Greenshot.Editor/Drawing/DrawableContainerList.cs index f6c419b50..95d75addd 100644 --- a/src/Greenshot.Editor/Drawing/DrawableContainerList.cs +++ b/src/Greenshot.Editor/Drawing/DrawableContainerList.cs @@ -39,14 +39,6 @@ using Greenshot.Editor.Memento; namespace Greenshot.Editor.Drawing { - public enum Direction - { - LEFT, - RIGHT, - TOP, - BOTTOM, - } - /// /// Dispatches most of a DrawableContainer's public properties and methods to a list of DrawableContainers. /// @@ -743,7 +735,7 @@ namespace Greenshot.Editor.Drawing MakeBoundsChangeUndoable(false); item.Width = surface.Image.Width; } - SnapAllToEdge(Direction.LEFT, surface, this); + SnapAllToEdge(Direction.LEFT, surface); surface.Invalidate(); // not sure if this belongs }; fitSubmenu.DropDownItems.Add(item); @@ -760,7 +752,7 @@ namespace Greenshot.Editor.Drawing MakeBoundsChangeUndoable(false); item.Height = surface.Image.Height; } - SnapAllToEdge(Direction.TOP, surface, this); + SnapAllToEdge(Direction.TOP, surface); surface.Invalidate(); // not sure if this belongs }; fitSubmenu.DropDownItems.Add(item); @@ -775,7 +767,7 @@ namespace Greenshot.Editor.Drawing }; item.Click += delegate { - SnapAllToEdge(Direction.LEFT, surface, this); + SnapAllToEdge(Direction.LEFT, surface); }; snapSubmenu.DropDownItems.Add(item); @@ -786,7 +778,7 @@ namespace Greenshot.Editor.Drawing }; item.Click += delegate { - SnapAllToEdge(Direction.RIGHT, surface, this); + SnapAllToEdge(Direction.RIGHT, surface); }; snapSubmenu.DropDownItems.Add(item); @@ -797,7 +789,7 @@ namespace Greenshot.Editor.Drawing }; item.Click += delegate { - SnapAllToEdge(Direction.TOP, surface, this); + SnapAllToEdge(Direction.TOP, surface); }; snapSubmenu.DropDownItems.Add(item); @@ -808,7 +800,7 @@ namespace Greenshot.Editor.Drawing }; item.Click += delegate { - SnapAllToEdge(Direction.BOTTOM, surface, this); + SnapAllToEdge(Direction.BOTTOM, surface); }; snapSubmenu.DropDownItems.Add(item); menu.Items.Add(snapSubmenu); @@ -922,54 +914,17 @@ namespace Greenshot.Editor.Drawing } } - /// - /// Move an element to one edge of the surface. - /// - /// Direction to move the element. - /// - /// - public void SnapToEdge(Direction direction, ISurface surface, IDrawableContainer targetElement) - { - Size surfaceBounds = new(surface.Image.Width, surface.Image.Height); - NativeRectFloat newBounds = SnapHelper(direction, targetElement.Bounds, surfaceBounds); - - targetElement.MakeBoundsChangeUndoable(allowMerge: false); - targetElement.ApplyBounds(newBounds); - } - - public static NativeRectFloat SnapHelper(Direction direction, NativeRect bounds, Size surfaceSize) - { - switch (direction) - { - case Direction.LEFT: - bounds = bounds.ChangeX(0); - break; - case Direction.RIGHT: - bounds = bounds.Offset(offsetX: surfaceSize.Width - bounds.Right); - break; - case Direction.TOP: - bounds = bounds.ChangeY(0); - break; - case Direction.BOTTOM: - bounds = bounds.Offset(offsetY: surfaceSize.Height - bounds.Bottom); - break; - default: - break; - } - return bounds; - } - /// /// Moves all selected elements to one edge of the surface. /// /// /// - /// - public void SnapAllToEdge(Direction direction, ISurface surface, IDrawableContainerList elements) + /// + public void SnapAllToEdge(Direction direction, ISurface surface) { - foreach (var item in elements) + foreach (IDrawableContainer item in this) { - SnapToEdge(direction, surface, item); + item.SnapToEdge(direction, surface); } surface.DeselectAllElements(); } @@ -986,12 +941,12 @@ namespace Greenshot.Editor.Drawing surface.ResizeCanvas(expansion.Left, expansion.Right, expansion.Top, expansion.Bottom); - SnapToEdge(direction, surface, targetElement); + targetElement.SnapToEdge(direction, surface); if (direction == Direction.LEFT || direction == Direction.RIGHT) - SnapToEdge(Direction.TOP, surface, targetElement); + targetElement.SnapToEdge(Direction.TOP, surface); else if (direction == Direction.TOP || direction == Direction.BOTTOM) - SnapToEdge(Direction.LEFT, surface, targetElement); + targetElement.SnapToEdge(Direction.LEFT, surface); surface.DeselectAllElements(); }