Smarter zoom - keep selected elements in sight

This commit is contained in:
Killy 2020-05-01 18:16:33 +03:00
parent d93c9d6a3a
commit ef5b5deb7a
4 changed files with 62 additions and 11 deletions

View file

@ -235,6 +235,30 @@ namespace Greenshot.Drawing {
return false; return false;
} }
/// <summary>
/// A rectangle containing DrawingBounds of all drawableContainers in this list,
/// or empty rectangle if nothing is there.
/// </summary>
public Rectangle DrawingBounds
{
get
{
if (Count == 0)
{
return Rectangle.Empty;
}
else
{
var result = this[0].DrawingBounds;
for (int i = 1; i < Count; i++)
{
result = Rectangle.Union(result, this[i].DrawingBounds);
}
return result;
}
}
}
/// <summary> /// <summary>
/// Triggers all elements in the list ot be redrawn. /// Triggers all elements in the list ot be redrawn.
/// </summary> /// </summary>

View file

@ -1922,6 +1922,13 @@ namespace Greenshot.Drawing
); );
} }
/// <summary>
/// Get the rectangle bounding all selected elements (in surface coordinates space),
/// or empty rectangle if nothing is selcted.
/// </summary>
public Rectangle GetSelectionRectangle()
=> ToSurfaceCoordinates(selectedElements.DrawingBounds);
/// <summary> /// <summary>
/// Duplicate all the selecteded elements /// Duplicate all the selecteded elements
/// </summary> /// </summary>

View file

@ -1580,21 +1580,37 @@ namespace Greenshot {
{ {
return; return;
} }
if (value == Surface.ZoomFactor)
{
return;
}
// Store old scroll position // Store scroll position
// When no scroll is currently needed - prefer top left corner. var rc = surface.GetVisibleRectangle(); // use visible rc by default
var horizontalCenter = 0.0;
var verticalCenter = 0.0;
var rc = surface.GetVisibleRectangle();
var size = surface.Size; var size = surface.Size;
if (size.Width > rc.Width) if (value > Surface.ZoomFactor) // being smart on zoom-in
{ {
horizontalCenter = 1.0 * (rc.Left + rc.Width / 2) / size.Width; var sel = surface.GetSelectionRectangle();
} if (sel != Rectangle.Empty)
if (size.Height > rc.Height) {
{ rc.Intersect(sel); // zoom to visible part of selection
verticalCenter = 1.0 * (rc.Top + rc.Height / 2) / size.Height; }
else
{
// if image fits completely to currently visible rc and there are no things to focus on
// - prefer top left corner to zoom-in as less disorienting for screenshots
if (size.Width < rc.Width)
{
rc.Width = 0;
}
if (size.Height < rc.Height)
{
rc.Height = 0;
}
}
} }
var horizontalCenter = 1.0 * (rc.Left + rc.Width / 2) / size.Width;
var verticalCenter = 1.0 * (rc.Top + rc.Height / 2) / size.Height;
// Set the new zoom value // Set the new zoom value
Surface.ZoomFactor = value; Surface.ZoomFactor = value;

View file

@ -145,6 +145,10 @@ namespace GreenshotPlugin.Interfaces.Drawing
get; get;
set; set;
} }
Rectangle DrawingBounds
{
get;
}
void MakeBoundsChangeUndoable(bool allowMerge); void MakeBoundsChangeUndoable(bool allowMerge);
void Transform(Matrix matrix); void Transform(Matrix matrix);
void MoveBy(int dx, int dy); void MoveBy(int dx, int dy);