mirror of
https://github.com/greenshot/greenshot
synced 2025-08-22 06:23:24 -07:00
Refactor snap to edge
(cherry picked from commit 9295c343b3797d469e393a4cd2cc771c80fff7ea)
This commit is contained in:
parent
92cbdfb794
commit
1f50db16dc
3 changed files with 66 additions and 58 deletions
|
@ -29,6 +29,14 @@ using Greenshot.Base.Interfaces.Drawing.Adorners;
|
||||||
|
|
||||||
namespace Greenshot.Base.Interfaces.Drawing
|
namespace Greenshot.Base.Interfaces.Drawing
|
||||||
{
|
{
|
||||||
|
public enum Direction
|
||||||
|
{
|
||||||
|
LEFT,
|
||||||
|
RIGHT,
|
||||||
|
TOP,
|
||||||
|
BOTTOM,
|
||||||
|
}
|
||||||
|
|
||||||
public interface IDrawableContainer : INotifyPropertyChanged, IDisposable
|
public interface IDrawableContainer : INotifyPropertyChanged, IDisposable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -111,5 +119,12 @@ namespace Greenshot.Base.Interfaces.Drawing
|
||||||
/// <param name="surface">ISurface</param>
|
/// <param name="surface">ISurface</param>
|
||||||
/// <param name="mouseEventArgs">MouseEventArgs</param>
|
/// <param name="mouseEventArgs">MouseEventArgs</param>
|
||||||
void AddContextMenuItems(ContextMenuStrip menu, ISurface surface, MouseEventArgs mouseEventArgs);
|
void AddContextMenuItems(ContextMenuStrip menu, ISurface surface, MouseEventArgs mouseEventArgs);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Snap the container to the edge of the surface.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="direction">Direction in which to move the container.</param>
|
||||||
|
/// <param name="surface">The surface the container belongs to.</param>
|
||||||
|
void SnapToEdge(Direction direction, ISurface surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -684,5 +684,43 @@ namespace Greenshot.Editor.Drawing
|
||||||
protected virtual void InitializeFields()
|
protected virtual void InitializeFields()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Snap the container to the edge of the surface.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="direction">Direction in which to move the container.</param>
|
||||||
|
/// <param name="surface">The surface the container belongs to.</param>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -39,14 +39,6 @@ using Greenshot.Editor.Memento;
|
||||||
|
|
||||||
namespace Greenshot.Editor.Drawing
|
namespace Greenshot.Editor.Drawing
|
||||||
{
|
{
|
||||||
public enum Direction
|
|
||||||
{
|
|
||||||
LEFT,
|
|
||||||
RIGHT,
|
|
||||||
TOP,
|
|
||||||
BOTTOM,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Dispatches most of a DrawableContainer's public properties and methods to a list of DrawableContainers.
|
/// Dispatches most of a DrawableContainer's public properties and methods to a list of DrawableContainers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -743,7 +735,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
MakeBoundsChangeUndoable(false);
|
MakeBoundsChangeUndoable(false);
|
||||||
item.Width = surface.Image.Width;
|
item.Width = surface.Image.Width;
|
||||||
}
|
}
|
||||||
SnapAllToEdge(Direction.LEFT, surface, this);
|
SnapAllToEdge(Direction.LEFT, surface);
|
||||||
surface.Invalidate(); // not sure if this belongs
|
surface.Invalidate(); // not sure if this belongs
|
||||||
};
|
};
|
||||||
fitSubmenu.DropDownItems.Add(item);
|
fitSubmenu.DropDownItems.Add(item);
|
||||||
|
@ -760,7 +752,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
MakeBoundsChangeUndoable(false);
|
MakeBoundsChangeUndoable(false);
|
||||||
item.Height = surface.Image.Height;
|
item.Height = surface.Image.Height;
|
||||||
}
|
}
|
||||||
SnapAllToEdge(Direction.TOP, surface, this);
|
SnapAllToEdge(Direction.TOP, surface);
|
||||||
surface.Invalidate(); // not sure if this belongs
|
surface.Invalidate(); // not sure if this belongs
|
||||||
};
|
};
|
||||||
fitSubmenu.DropDownItems.Add(item);
|
fitSubmenu.DropDownItems.Add(item);
|
||||||
|
@ -775,7 +767,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
};
|
};
|
||||||
item.Click += delegate
|
item.Click += delegate
|
||||||
{
|
{
|
||||||
SnapAllToEdge(Direction.LEFT, surface, this);
|
SnapAllToEdge(Direction.LEFT, surface);
|
||||||
};
|
};
|
||||||
snapSubmenu.DropDownItems.Add(item);
|
snapSubmenu.DropDownItems.Add(item);
|
||||||
|
|
||||||
|
@ -786,7 +778,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
};
|
};
|
||||||
item.Click += delegate
|
item.Click += delegate
|
||||||
{
|
{
|
||||||
SnapAllToEdge(Direction.RIGHT, surface, this);
|
SnapAllToEdge(Direction.RIGHT, surface);
|
||||||
};
|
};
|
||||||
snapSubmenu.DropDownItems.Add(item);
|
snapSubmenu.DropDownItems.Add(item);
|
||||||
|
|
||||||
|
@ -797,7 +789,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
};
|
};
|
||||||
item.Click += delegate
|
item.Click += delegate
|
||||||
{
|
{
|
||||||
SnapAllToEdge(Direction.TOP, surface, this);
|
SnapAllToEdge(Direction.TOP, surface);
|
||||||
};
|
};
|
||||||
snapSubmenu.DropDownItems.Add(item);
|
snapSubmenu.DropDownItems.Add(item);
|
||||||
|
|
||||||
|
@ -808,7 +800,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
};
|
};
|
||||||
item.Click += delegate
|
item.Click += delegate
|
||||||
{
|
{
|
||||||
SnapAllToEdge(Direction.BOTTOM, surface, this);
|
SnapAllToEdge(Direction.BOTTOM, surface);
|
||||||
};
|
};
|
||||||
snapSubmenu.DropDownItems.Add(item);
|
snapSubmenu.DropDownItems.Add(item);
|
||||||
menu.Items.Add(snapSubmenu);
|
menu.Items.Add(snapSubmenu);
|
||||||
|
@ -922,54 +914,17 @@ namespace Greenshot.Editor.Drawing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Move an element to one edge of the surface.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="direction">Direction to move the element.</param>
|
|
||||||
/// <param name="surface"></param>
|
|
||||||
/// <param name="targetElement"></param>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Moves all selected elements to one edge of the surface.
|
/// Moves all selected elements to one edge of the surface.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="direction"></param>
|
/// <param name="direction"></param>
|
||||||
/// <param name="surface"></param>
|
/// <param name="surface"></param>
|
||||||
/// <param name="elements"></param>
|
///
|
||||||
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();
|
surface.DeselectAllElements();
|
||||||
}
|
}
|
||||||
|
@ -986,12 +941,12 @@ namespace Greenshot.Editor.Drawing
|
||||||
|
|
||||||
surface.ResizeCanvas(expansion.Left, expansion.Right, expansion.Top, expansion.Bottom);
|
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)
|
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)
|
else if (direction == Direction.TOP || direction == Direction.BOTTOM)
|
||||||
SnapToEdge(Direction.LEFT, surface, targetElement);
|
targetElement.SnapToEdge(Direction.LEFT, surface);
|
||||||
|
|
||||||
surface.DeselectAllElements();
|
surface.DeselectAllElements();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue