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