diff --git a/src/Greenshot.Editor/Drawing/DrawableContainerList.cs b/src/Greenshot.Editor/Drawing/DrawableContainerList.cs
index ef30c037f..2afcaf2fd 100644
--- a/src/Greenshot.Editor/Drawing/DrawableContainerList.cs
+++ b/src/Greenshot.Editor/Drawing/DrawableContainerList.cs
@@ -39,6 +39,14 @@ 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.
///
@@ -672,6 +680,139 @@ namespace Greenshot.Editor.Drawing
};
menu.Items.Add(item);
+ // Push out
+ ToolStripMenuItem alignSubmenu = new ToolStripMenuItem("Push Out");
+
+ // Right
+ item = new ToolStripMenuItem("Right")
+ {
+ Image = (Image)EditorFormResources.GetObject("copyToolStripMenuItem.Image")
+ };
+ item.Click += delegate
+ {
+ PushOut(Direction.RIGHT, surface, this[0]);
+ };
+ alignSubmenu.DropDownItems.Add(item);
+
+ // Left
+ item = new ToolStripMenuItem("Left")
+ {
+ Image = (Image)EditorFormResources.GetObject("copyToolStripMenuItem.Image")
+ };
+ item.Click += delegate
+ {
+ PushOut(Direction.LEFT, surface, this[0]);
+ };
+ alignSubmenu.DropDownItems.Add(item);
+
+ // Top
+ item = new ToolStripMenuItem("Top")
+ {
+ Image = (Image)EditorFormResources.GetObject("copyToolStripMenuItem.Image")
+ };
+ item.Click += delegate
+ {
+ PushOut(Direction.TOP, surface, this[0]);
+ };
+ alignSubmenu.DropDownItems.Add(item);
+
+ // Bottom
+ item = new ToolStripMenuItem("Bottom")
+ {
+ Image = (Image)EditorFormResources.GetObject("copyToolStripMenuItem.Image")
+ };
+ item.Click += delegate
+ {
+ PushOut(Direction.BOTTOM, surface, this[0]);
+ };
+ alignSubmenu.DropDownItems.Add(item);
+ menu.Items.Add(alignSubmenu);
+
+ // Fit menu
+ ToolStripMenuItem fitSubmenu = new ToolStripMenuItem("Fit");
+
+ // Fit width
+ item = new ToolStripMenuItem("Fit to width")
+ {
+ Image = (Image)EditorFormResources.GetObject("copyToolStripMenuItem.Image")
+ };
+ item.Click += delegate
+ {
+ foreach (var item in this)
+ {
+ MakeBoundsChangeUndoable(false);
+ item.Width = surface.Image.Width;
+ }
+ SnapAllToEdge(Direction.LEFT, surface, this);
+ surface.Invalidate(); // not sure if this belongs
+ };
+ fitSubmenu.DropDownItems.Add(item);
+
+ // Fit height
+ item = new ToolStripMenuItem("Fit to height")
+ {
+ Image = (Image)EditorFormResources.GetObject("copyToolStripMenuItem.Image")
+ };
+ item.Click += delegate
+ {
+ foreach (var item in this)
+ {
+ MakeBoundsChangeUndoable(false);
+ item.Height = surface.Image.Height;
+ }
+ SnapAllToEdge(Direction.TOP, surface, this);
+ surface.Invalidate(); // not sure if this belongs
+ };
+ fitSubmenu.DropDownItems.Add(item);
+ menu.Items.Add(fitSubmenu);
+
+ ToolStripMenuItem snapSubmenu = new ToolStripMenuItem("Snap");
+
+ // Snap left
+ item = new ToolStripMenuItem("Snap left")
+ {
+ Image = (Image)EditorFormResources.GetObject("copyToolStripMenuItem.Image")
+ };
+ item.Click += delegate
+ {
+ SnapAllToEdge(Direction.LEFT, surface, this);
+ };
+ snapSubmenu.DropDownItems.Add(item);
+
+ // Snap right
+ item = new ToolStripMenuItem("Snap right")
+ {
+ Image = (Image)EditorFormResources.GetObject("copyToolStripMenuItem.Image")
+ };
+ item.Click += delegate
+ {
+ SnapAllToEdge(Direction.RIGHT, surface, this);
+ };
+ snapSubmenu.DropDownItems.Add(item);
+
+ // Snap to top
+ item = new ToolStripMenuItem("Snap to top")
+ {
+ Image = (Image)EditorFormResources.GetObject("copyToolStripMenuItem.Image")
+ };
+ item.Click += delegate
+ {
+ SnapAllToEdge(Direction.TOP, surface, this);
+ };
+ snapSubmenu.DropDownItems.Add(item);
+
+ // Snap to bottom
+ item = new ToolStripMenuItem("Snap to bottom")
+ {
+ Image = (Image)EditorFormResources.GetObject("copyToolStripMenuItem.Image")
+ };
+ item.Click += delegate
+ {
+ SnapAllToEdge(Direction.BOTTOM, surface, this);
+ };
+ snapSubmenu.DropDownItems.Add(item);
+ menu.Items.Add(snapSubmenu);
+
// Delete
item = new ToolStripMenuItem(Language.GetString(LangKey.editor_deleteelement))
{
@@ -780,5 +921,72 @@ namespace Greenshot.Editor.Drawing
drawableContainer.AdjustToDpi(dpi);
}
}
+
+ ///
+ /// Move an element to one edge of the surface.
+ ///
+ /// Direction to move the element.
+ ///
+ ///
+ public void SnapToEdge(Direction direction, ISurface surface, IDrawableContainer targetElement)
+ {
+ int xMovement = 0, yMovement = 0;
+
+ if (direction == Direction.LEFT)
+ xMovement = -targetElement.Location.X;
+ else if (direction == Direction.RIGHT)
+ xMovement = surface.Image.Width - targetElement.Location.X - targetElement.Width;
+ else if (direction == Direction.TOP)
+ yMovement = -targetElement.Location.Y;
+ else if (direction == Direction.BOTTOM)
+ yMovement = surface.Image.Height - targetElement.Location.Y - targetElement.Height;
+
+ targetElement.MakeBoundsChangeUndoable(allowMerge: false);
+ targetElement.MoveBy(xMovement, yMovement);
+ }
+
+ ///
+ /// Moves all selected elements to one edge of the surface.
+ ///
+ ///
+ ///
+ ///
+ public void SnapAllToEdge(Direction direction, ISurface surface, IDrawableContainerList elements)
+ {
+ foreach (var item in elements)
+ {
+ SnapToEdge(direction, surface, item);
+ }
+ surface.DeselectAllElements();
+ }
+
+ ///
+ /// Push an element entirely outside the current bounds of the surface, expanding the surface to accomodate it.
+ ///
+ /// Direction in which to move element.
+ ///
+ ///
+ public void PushOut(Direction direction, ISurface surface, IDrawableContainer targetElement)
+ {
+ int left = 0, right = 0, top = 0, bottom = 0;
+ if (direction == Direction.LEFT)
+ left = targetElement.Width;
+ else if (direction == Direction.RIGHT)
+ right = targetElement.Width;
+ else if (direction == Direction.TOP)
+ top = targetElement.Height;
+ else if (direction == Direction.BOTTOM)
+ bottom = targetElement.Height;
+
+ surface.ResizeCanvas(left, right, top, bottom);
+
+ // Move target object
+ SnapToEdge(direction, surface, targetElement);
+ if (direction == Direction.LEFT || direction == Direction.RIGHT)
+ SnapToEdge(Direction.TOP, surface, targetElement);
+ else if (direction == Direction.TOP || direction == Direction.BOTTOM)
+ SnapToEdge(Direction.LEFT, surface, targetElement);
+ surface.DeselectAllElements();
+ }
}
}
\ No newline at end of file