mirror of
https://github.com/greenshot/greenshot
synced 2025-07-30 03:30:02 -07:00
Zoom feature for the editor
This commit is contained in:
parent
38739ce427
commit
8b45489b11
18 changed files with 585 additions and 52 deletions
|
@ -116,6 +116,23 @@ namespace Greenshot.Drawing.Adorners
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the bounds of the Adorner as displayed on the parent Surface
|
||||
/// </summary>
|
||||
protected virtual Rectangle SurfaceBounds
|
||||
{
|
||||
get
|
||||
{
|
||||
Point[] points = { Location };
|
||||
var matrix = Owner.Parent.ZoomMatrix;
|
||||
if (!matrix.IsIdentity)
|
||||
{
|
||||
matrix.TransformPoints(points);
|
||||
}
|
||||
return new Rectangle(points[0].X - _size.Width / 2, points[0].Y - _size.Height / 2, _size.Width, _size.Height);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The adorner is active if the edit status is not idle or undrawn
|
||||
/// </summary>
|
||||
|
|
|
@ -142,7 +142,7 @@ namespace Greenshot.Drawing.Adorners
|
|||
{
|
||||
Graphics targetGraphics = paintEventArgs.Graphics;
|
||||
|
||||
var bounds = Bounds;
|
||||
var bounds = SurfaceBounds;
|
||||
GraphicsState state = targetGraphics.Save();
|
||||
|
||||
targetGraphics.SmoothingMode = SmoothingMode.None;
|
||||
|
|
|
@ -169,7 +169,7 @@ namespace Greenshot.Drawing.Adorners
|
|||
{
|
||||
Graphics targetGraphics = paintEventArgs.Graphics;
|
||||
|
||||
var bounds = Bounds;
|
||||
var bounds = SurfaceBounds;
|
||||
GraphicsState state = targetGraphics.Save();
|
||||
|
||||
targetGraphics.SmoothingMode = SmoothingMode.None;
|
||||
|
|
|
@ -96,7 +96,7 @@ namespace Greenshot.Drawing.Adorners
|
|||
{
|
||||
Graphics targetGraphics = paintEventArgs.Graphics;
|
||||
|
||||
var bounds = Bounds;
|
||||
var bounds = SurfaceBounds;
|
||||
targetGraphics.FillRectangle(Brushes.Green, bounds.X, bounds.Y, bounds.Width, bounds.Height);
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,15 @@ namespace Greenshot.Drawing {
|
|||
/// We need to override the DrawingBound, return a rectangle in the size of the image, to make sure this element is always draw
|
||||
/// (we create a transparent brown over the complete picture)
|
||||
/// </summary>
|
||||
public override Rectangle DrawingBounds => new Rectangle(0,0,_parent?.Width??0, _parent?.Height ?? 0);
|
||||
public override Rectangle DrawingBounds {
|
||||
get {
|
||||
if (_parent?.Image is Image image) {
|
||||
return new Rectangle(0, 0, image.Width, image.Height);
|
||||
} else {
|
||||
return new Rectangle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Draw(Graphics g, RenderMode rm) {
|
||||
if (_parent == null)
|
||||
|
@ -67,17 +75,18 @@ namespace Greenshot.Drawing {
|
|||
using Brush cropBrush = new SolidBrush(Color.FromArgb(100, 150, 150, 100));
|
||||
Rectangle cropRectangle = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
|
||||
Rectangle selectionRect = new Rectangle(cropRectangle.Left - 1, cropRectangle.Top - 1, cropRectangle.Width + 1, cropRectangle.Height + 1);
|
||||
Size imageSize = _parent.Image.Size;
|
||||
|
||||
DrawSelectionBorder(g, selectionRect);
|
||||
|
||||
// top
|
||||
g.FillRectangle(cropBrush, new Rectangle(0, 0, _parent.Width, cropRectangle.Top));
|
||||
g.FillRectangle(cropBrush, new Rectangle(0, 0, imageSize.Width, cropRectangle.Top));
|
||||
// left
|
||||
g.FillRectangle(cropBrush, new Rectangle(0, cropRectangle.Top, cropRectangle.Left, cropRectangle.Height));
|
||||
// right
|
||||
g.FillRectangle(cropBrush, new Rectangle(cropRectangle.Left + cropRectangle.Width, cropRectangle.Top, _parent.Width - (cropRectangle.Left + cropRectangle.Width), cropRectangle.Height));
|
||||
g.FillRectangle(cropBrush, new Rectangle(cropRectangle.Left + cropRectangle.Width, cropRectangle.Top, imageSize.Width - (cropRectangle.Left + cropRectangle.Width), cropRectangle.Height));
|
||||
// bottom
|
||||
g.FillRectangle(cropBrush, new Rectangle(0, cropRectangle.Top + cropRectangle.Height, _parent.Width, _parent.Height - (cropRectangle.Top + cropRectangle.Height)));
|
||||
g.FillRectangle(cropBrush, new Rectangle(0, cropRectangle.Top + cropRectangle.Height, imageSize.Width, imageSize.Height - (cropRectangle.Top + cropRectangle.Height)));
|
||||
}
|
||||
|
||||
public override bool HasContextMenu {
|
||||
|
|
|
@ -298,7 +298,7 @@ namespace Greenshot.Drawing
|
|||
|
||||
public virtual void Invalidate() {
|
||||
if (Status != EditStatus.UNDRAWN) {
|
||||
_parent?.Invalidate(DrawingBounds);
|
||||
_parent?.InvalidateElements(DrawingBounds);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -286,7 +286,7 @@ namespace Greenshot.Drawing {
|
|||
{
|
||||
region = Rectangle.Union(region, dc.DrawingBounds);
|
||||
}
|
||||
Parent.Invalidate(region);
|
||||
Parent.InvalidateElements(region);
|
||||
}
|
||||
/// <summary>
|
||||
/// Indicates whether the given list of elements can be pulled up,
|
||||
|
|
|
@ -298,10 +298,34 @@ namespace Greenshot.Drawing
|
|||
set
|
||||
{
|
||||
_image = value;
|
||||
Size = _image.Size;
|
||||
UpdateSize();
|
||||
}
|
||||
}
|
||||
|
||||
[NonSerialized]
|
||||
private float _zoomFactor = 1.0f;
|
||||
public float ZoomFactor
|
||||
{
|
||||
get => _zoomFactor;
|
||||
set
|
||||
{
|
||||
_zoomFactor = value;
|
||||
ZoomMatrix = new Matrix(_zoomFactor, 0, 0, _zoomFactor, 0, 0);
|
||||
UpdateSize();
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix ZoomMatrix { get; private set; } = new Matrix(1, 0, 0, 1, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the surface size as zoomed image size.
|
||||
/// </summary>
|
||||
private void UpdateSize()
|
||||
{
|
||||
var size = _image.Size;
|
||||
Size = new Size((int)(size.Width * _zoomFactor), (int)(size.Height * _zoomFactor));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The field aggregator is that which is used to have access to all the fields inside the currently selected elements.
|
||||
/// e.g. used to decided if and which line thickness is shown when multiple elements are selected.
|
||||
|
@ -447,7 +471,6 @@ namespace Greenshot.Drawing
|
|||
|
||||
// Set new values
|
||||
Image = newImage;
|
||||
Size = newImage.Size;
|
||||
|
||||
_modified = true;
|
||||
}
|
||||
|
@ -1086,6 +1109,12 @@ namespace Greenshot.Drawing
|
|||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Translate mouse coordinates as if they were applied directly to unscaled image.
|
||||
/// </summary>
|
||||
private MouseEventArgs InverseZoomMouseCoordinates(MouseEventArgs e)
|
||||
=> new MouseEventArgs(e.Button, e.Clicks, (int)(e.X / _zoomFactor), (int)(e.Y / _zoomFactor), e.Delta);
|
||||
|
||||
/// <summary>
|
||||
/// This event handler is called when someone presses the mouse on a surface.
|
||||
/// </summary>
|
||||
|
@ -1093,6 +1122,7 @@ namespace Greenshot.Drawing
|
|||
/// <param name="e"></param>
|
||||
private void SurfaceMouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
e = InverseZoomMouseCoordinates(e);
|
||||
|
||||
// Handle Adorners
|
||||
var adorner = FindActiveAdorner(e);
|
||||
|
@ -1187,6 +1217,7 @@ namespace Greenshot.Drawing
|
|||
/// <param name="e"></param>
|
||||
private void SurfaceMouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
e = InverseZoomMouseCoordinates(e);
|
||||
|
||||
// Handle Adorners
|
||||
var adorner = FindActiveAdorner(e);
|
||||
|
@ -1276,6 +1307,8 @@ namespace Greenshot.Drawing
|
|||
/// <param name="e"></param>
|
||||
private void SurfaceMouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
e = InverseZoomMouseCoordinates(e);
|
||||
|
||||
// Handle Adorners
|
||||
var adorner = FindActiveAdorner(e);
|
||||
if (adorner != null)
|
||||
|
@ -1371,6 +1404,25 @@ namespace Greenshot.Drawing
|
|||
return GetImage(RenderMode.EXPORT);
|
||||
}
|
||||
|
||||
private Rectangle ZoomClipRectangle(Rectangle rc, double scale)
|
||||
=> new Rectangle(
|
||||
(int)(rc.X * scale),
|
||||
(int)(rc.Y * scale),
|
||||
(int)((rc.Width + 1) * scale) + 1, // making sure to redraw enough pixels when moving scaled image
|
||||
(int)((rc.Height + 1) * scale) + 1
|
||||
);
|
||||
|
||||
private RectangleF ZoomClipRectangle(RectangleF rc, double scale)
|
||||
=> new RectangleF(
|
||||
(float)Math.Floor(rc.X * scale),
|
||||
(float)Math.Floor(rc.Y * scale),
|
||||
(float)Math.Ceiling(rc.Width * scale),
|
||||
(float)Math.Ceiling(rc.Height * scale)
|
||||
);
|
||||
|
||||
public void InvalidateElements(Rectangle rc)
|
||||
=> Invalidate(ZoomClipRectangle(rc, _zoomFactor));
|
||||
|
||||
/// <summary>
|
||||
/// This is the event handler for the Paint Event, try to draw as little as possible!
|
||||
/// </summary>
|
||||
|
@ -1379,14 +1431,16 @@ namespace Greenshot.Drawing
|
|||
private void SurfacePaint(object sender, PaintEventArgs paintEventArgs)
|
||||
{
|
||||
Graphics targetGraphics = paintEventArgs.Graphics;
|
||||
Rectangle clipRectangle = paintEventArgs.ClipRectangle;
|
||||
if (Rectangle.Empty.Equals(clipRectangle))
|
||||
Rectangle targetClipRectangle = paintEventArgs.ClipRectangle;
|
||||
if (Rectangle.Empty.Equals(targetClipRectangle))
|
||||
{
|
||||
LOG.Debug("Empty cliprectangle??");
|
||||
return;
|
||||
}
|
||||
Rectangle imageClipRectangle = ZoomClipRectangle(targetClipRectangle, 1.0 / _zoomFactor);
|
||||
|
||||
if (_elements.HasIntersectingFilters(clipRectangle))
|
||||
bool isZoomedIn = ZoomFactor > 1f;
|
||||
if (_elements.HasIntersectingFilters(imageClipRectangle) || isZoomedIn)
|
||||
{
|
||||
if (_buffer != null)
|
||||
{
|
||||
|
@ -1409,18 +1463,38 @@ namespace Greenshot.Drawing
|
|||
//graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
//graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||
//graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
DrawBackground(graphics, clipRectangle);
|
||||
graphics.DrawImage(Image, clipRectangle, clipRectangle, GraphicsUnit.Pixel);
|
||||
graphics.SetClip(targetGraphics);
|
||||
_elements.Draw(graphics, _buffer, RenderMode.EDIT, clipRectangle);
|
||||
DrawBackground(graphics, imageClipRectangle);
|
||||
graphics.DrawImage(Image, imageClipRectangle, imageClipRectangle, GraphicsUnit.Pixel);
|
||||
graphics.SetClip(ZoomClipRectangle(targetGraphics.ClipBounds, 1.0 / _zoomFactor));
|
||||
_elements.Draw(graphics, _buffer, RenderMode.EDIT, imageClipRectangle);
|
||||
}
|
||||
targetGraphics.DrawImage(_buffer, clipRectangle, clipRectangle, GraphicsUnit.Pixel);
|
||||
targetGraphics.ScaleTransform(_zoomFactor, _zoomFactor);
|
||||
if (isZoomedIn)
|
||||
{
|
||||
var state = targetGraphics.Save();
|
||||
targetGraphics.SmoothingMode = SmoothingMode.None;
|
||||
targetGraphics.InterpolationMode = InterpolationMode.NearestNeighbor;
|
||||
targetGraphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||
targetGraphics.PixelOffsetMode = PixelOffsetMode.None;
|
||||
|
||||
targetGraphics.DrawImage(_buffer, imageClipRectangle, imageClipRectangle, GraphicsUnit.Pixel);
|
||||
|
||||
targetGraphics.Restore(state);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawBackground(targetGraphics, clipRectangle);
|
||||
targetGraphics.DrawImage(Image, clipRectangle, clipRectangle, GraphicsUnit.Pixel);
|
||||
_elements.Draw(targetGraphics, null, RenderMode.EDIT, clipRectangle);
|
||||
targetGraphics.DrawImage(_buffer, imageClipRectangle, imageClipRectangle, GraphicsUnit.Pixel);
|
||||
}
|
||||
targetGraphics.ResetTransform();
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawBackground(targetGraphics, targetClipRectangle);
|
||||
|
||||
targetGraphics.ScaleTransform(_zoomFactor, _zoomFactor);
|
||||
targetGraphics.DrawImage(Image, imageClipRectangle, imageClipRectangle, GraphicsUnit.Pixel);
|
||||
_elements.Draw(targetGraphics, null, RenderMode.EDIT, imageClipRectangle);
|
||||
targetGraphics.ResetTransform();
|
||||
}
|
||||
|
||||
// No clipping for the adorners
|
||||
|
|
|
@ -442,14 +442,20 @@ namespace Greenshot.Drawing
|
|||
correction = -1;
|
||||
}
|
||||
Rectangle absRectangle = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
|
||||
_textBox.Left = absRectangle.Left + lineWidth;
|
||||
_textBox.Top = absRectangle.Top + lineWidth;
|
||||
Point[] points = { absRectangle.Location, absRectangle.Location + absRectangle.Size };
|
||||
var matrix = Parent.ZoomMatrix;
|
||||
if (!matrix.IsIdentity)
|
||||
{
|
||||
matrix.TransformPoints(points);
|
||||
}
|
||||
_textBox.Left = points[0].X + lineWidth;
|
||||
_textBox.Top = points[0].Y + lineWidth;
|
||||
if (lineThickness <= 1)
|
||||
{
|
||||
lineWidth = 0;
|
||||
}
|
||||
_textBox.Width = absRectangle.Width - 2 * lineWidth + correction;
|
||||
_textBox.Height = absRectangle.Height - 2 * lineWidth + correction;
|
||||
_textBox.Width = points[1].X - points[0].X - 2 * lineWidth + correction;
|
||||
_textBox.Height = points[1].Y - points[0].Y - 2 * lineWidth + correction;
|
||||
}
|
||||
|
||||
public override void ApplyBounds(RectangleF newBounds)
|
||||
|
|
212
Greenshot/Forms/ImageEditorForm.Designer.cs
generated
212
Greenshot/Forms/ImageEditorForm.Designer.cs
generated
|
@ -194,6 +194,26 @@ namespace Greenshot {
|
|||
this.alignLeftToolStripMenuItem = new GreenshotPlugin.Controls.GreenshotToolStripMenuItem();
|
||||
this.alignCenterToolStripMenuItem = new GreenshotPlugin.Controls.GreenshotToolStripMenuItem();
|
||||
this.alignRightToolStripMenuItem = new GreenshotPlugin.Controls.GreenshotToolStripMenuItem();
|
||||
this.zoomMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.zoomInMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.zoomOutMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.zoomMenuSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.zoomBestFitMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.zoomMenuSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.zoom25MenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.zoom50MenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.zoom66MenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.zoom75MenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.zoomMenuSeparator3 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.zoomActualSizeMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.zoomMenuSeparator4 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.zoom200MenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.zoom300MenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.zoom400MenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.zoom600MenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.zoomStatusDropDownBtn = new System.Windows.Forms.ToolStripDropDownButton();
|
||||
this.zoomMainMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.statusStripSpacer = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.topToolStripContainer.BottomToolStripPanel.SuspendLayout();
|
||||
this.topToolStripContainer.ContentPanel.SuspendLayout();
|
||||
this.topToolStripContainer.LeftToolStripPanel.SuspendLayout();
|
||||
|
@ -203,6 +223,7 @@ namespace Greenshot {
|
|||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.toolsToolStrip.SuspendLayout();
|
||||
this.menuStrip1.SuspendLayout();
|
||||
this.zoomMenuStrip.SuspendLayout();
|
||||
this.destinationsToolStrip.SuspendLayout();
|
||||
this.propertiesToolStrip.SuspendLayout();
|
||||
this.fileSavedStatusContextMenu.SuspendLayout();
|
||||
|
@ -238,7 +259,9 @@ namespace Greenshot {
|
|||
this.statusStrip1.Dock = System.Windows.Forms.DockStyle.None;
|
||||
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.dimensionsLabel,
|
||||
this.statusLabel});
|
||||
this.statusLabel,
|
||||
this.statusStripSpacer,
|
||||
this.zoomStatusDropDownBtn});
|
||||
this.statusStrip1.Location = new System.Drawing.Point(0, 0);
|
||||
this.statusStrip1.Name = "statusStrip1";
|
||||
this.statusStrip1.Size = new System.Drawing.Size(785, 24);
|
||||
|
@ -538,6 +561,7 @@ namespace Greenshot {
|
|||
this.editToolStripMenuItem,
|
||||
this.objectToolStripMenuItem,
|
||||
this.pluginToolStripMenuItem,
|
||||
this.zoomMainMenuItem,
|
||||
this.helpToolStripMenuItem});
|
||||
this.menuStrip1.Name = "menuStrip1";
|
||||
this.menuStrip1.BackColor = System.Drawing.SystemColors.Control;
|
||||
|
@ -1624,6 +1648,171 @@ namespace Greenshot {
|
|||
this.alignRightToolStripMenuItem.Name = "alignRightToolStripMenuItem";
|
||||
this.alignRightToolStripMenuItem.Tag = System.Drawing.StringAlignment.Far;
|
||||
//
|
||||
// zoomMainMenuItem
|
||||
//
|
||||
this.zoomMainMenuItem.DropDown = this.zoomMenuStrip;
|
||||
this.zoomMainMenuItem.Name = "zoomMainMenuItem";
|
||||
this.zoomMainMenuItem.Size = new System.Drawing.Size(51, 20);
|
||||
this.zoomMainMenuItem.Text = "Zoom";
|
||||
//
|
||||
// zoomMenuStrip
|
||||
//
|
||||
this.zoomMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.zoomInMenuItem,
|
||||
this.zoomOutMenuItem,
|
||||
this.zoomMenuSeparator1,
|
||||
this.zoomBestFitMenuItem,
|
||||
this.zoomMenuSeparator2,
|
||||
this.zoom25MenuItem,
|
||||
this.zoom50MenuItem,
|
||||
this.zoom66MenuItem,
|
||||
this.zoom75MenuItem,
|
||||
this.zoomMenuSeparator3,
|
||||
this.zoomActualSizeMenuItem,
|
||||
this.zoomMenuSeparator4,
|
||||
this.zoom200MenuItem,
|
||||
this.zoom300MenuItem,
|
||||
this.zoom400MenuItem,
|
||||
this.zoom600MenuItem});
|
||||
this.zoomMenuStrip.Name = "zoomMenuStrip";
|
||||
this.zoomMenuStrip.Size = new System.Drawing.Size(210, 292);
|
||||
//
|
||||
// zoomInMenuItem
|
||||
//
|
||||
this.zoomInMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("zoomInMenuItem.Image")));
|
||||
this.zoomInMenuItem.Name = "zoomInMenuItem";
|
||||
this.zoomInMenuItem.ShortcutKeyDisplayString = "Ctrl++";
|
||||
this.zoomInMenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.zoomInMenuItem.Text = "Zoom In";
|
||||
this.zoomInMenuItem.Click += new System.EventHandler(this.ZoomInMenuItemClick);
|
||||
//
|
||||
// zoomOutMenuItem
|
||||
//
|
||||
this.zoomOutMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("zoomOutMenuItem.Image")));
|
||||
this.zoomOutMenuItem.Name = "zoomOutMenuItem";
|
||||
this.zoomOutMenuItem.ShortcutKeyDisplayString = "Ctrl+-";
|
||||
this.zoomOutMenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.zoomOutMenuItem.Text = "Zoom Out";
|
||||
this.zoomOutMenuItem.Click += new System.EventHandler(this.ZoomOutMenuItemClick);
|
||||
//
|
||||
// zoomMenuSeparator1
|
||||
//
|
||||
this.zoomMenuSeparator1.Name = "zoomMenuSeparator1";
|
||||
this.zoomMenuSeparator1.Size = new System.Drawing.Size(206, 6);
|
||||
//
|
||||
// zoomBestFitMenuItem
|
||||
//
|
||||
this.zoomBestFitMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("zoomBestFitMenuItem.Image")));
|
||||
this.zoomBestFitMenuItem.Name = "zoomBestFitMenuItem";
|
||||
this.zoomBestFitMenuItem.ShortcutKeyDisplayString = "Ctrl+*";
|
||||
this.zoomBestFitMenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.zoomBestFitMenuItem.Text = "Best Fit";
|
||||
this.zoomBestFitMenuItem.Click += new System.EventHandler(this.ZoomBestFitMenuItemClick);
|
||||
//
|
||||
// zoomMenuSeparator2
|
||||
//
|
||||
this.zoomMenuSeparator2.Name = "zoomMenuSeparator2";
|
||||
this.zoomMenuSeparator2.Size = new System.Drawing.Size(206, 6);
|
||||
//
|
||||
// zoom25MenuItem
|
||||
//
|
||||
this.zoom25MenuItem.Name = "zoom25MenuItem";
|
||||
this.zoom25MenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.zoom25MenuItem.Tag = "25";
|
||||
this.zoom25MenuItem.Text = "25%";
|
||||
this.zoom25MenuItem.Click += new System.EventHandler(this.ZoomSetValueMenuItemClick);
|
||||
//
|
||||
// zoom50MenuItem
|
||||
//
|
||||
this.zoom50MenuItem.Name = "zoom50MenuItem";
|
||||
this.zoom50MenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.zoom50MenuItem.Tag = "50";
|
||||
this.zoom50MenuItem.Text = "50%";
|
||||
this.zoom50MenuItem.Click += new System.EventHandler(this.ZoomSetValueMenuItemClick);
|
||||
//
|
||||
// zoom66MenuItem
|
||||
//
|
||||
this.zoom66MenuItem.Name = "zoom66MenuItem";
|
||||
this.zoom66MenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.zoom66MenuItem.Tag = "66";
|
||||
this.zoom66MenuItem.Text = "66%";
|
||||
this.zoom66MenuItem.Click += new System.EventHandler(this.ZoomSetValueMenuItemClick);
|
||||
//
|
||||
// zoom75MenuItem
|
||||
//
|
||||
this.zoom75MenuItem.Name = "zoom75MenuItem";
|
||||
this.zoom75MenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.zoom75MenuItem.Tag = "75";
|
||||
this.zoom75MenuItem.Text = "75%";
|
||||
this.zoom75MenuItem.Click += new System.EventHandler(this.ZoomSetValueMenuItemClick);
|
||||
//
|
||||
// zoomMenuSeparator3
|
||||
//
|
||||
this.zoomMenuSeparator3.Name = "zoomMenuSeparator3";
|
||||
this.zoomMenuSeparator3.Size = new System.Drawing.Size(206, 6);
|
||||
//
|
||||
// zoomActualSizeMenuItem
|
||||
//
|
||||
this.zoomActualSizeMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("zoomActualSizeMenuItem.Image")));
|
||||
this.zoomActualSizeMenuItem.Name = "zoomActualSizeMenuItem";
|
||||
this.zoomActualSizeMenuItem.ShortcutKeyDisplayString = "Ctrl+/";
|
||||
this.zoomActualSizeMenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.zoomActualSizeMenuItem.Tag = "100";
|
||||
this.zoomActualSizeMenuItem.Text = "100% - Actual Size";
|
||||
this.zoomActualSizeMenuItem.Click += new System.EventHandler(this.ZoomSetValueMenuItemClick);
|
||||
//
|
||||
// zoomMenuSeparator4
|
||||
//
|
||||
this.zoomMenuSeparator4.Name = "zoomMenuSeparator4";
|
||||
this.zoomMenuSeparator4.Size = new System.Drawing.Size(206, 6);
|
||||
//
|
||||
// zoom200MenuItem
|
||||
//
|
||||
this.zoom200MenuItem.Name = "zoom200MenuItem";
|
||||
this.zoom200MenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.zoom200MenuItem.Tag = "200";
|
||||
this.zoom200MenuItem.Text = "200%";
|
||||
this.zoom200MenuItem.Click += new System.EventHandler(this.ZoomSetValueMenuItemClick);
|
||||
//
|
||||
// zoom300MenuItem
|
||||
//
|
||||
this.zoom300MenuItem.Name = "zoom300MenuItem";
|
||||
this.zoom300MenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.zoom300MenuItem.Tag = "300";
|
||||
this.zoom300MenuItem.Text = "300%";
|
||||
this.zoom300MenuItem.Click += new System.EventHandler(this.ZoomSetValueMenuItemClick);
|
||||
//
|
||||
// zoom400MenuItem
|
||||
//
|
||||
this.zoom400MenuItem.Name = "zoom400MenuItem";
|
||||
this.zoom400MenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.zoom400MenuItem.Tag = "400";
|
||||
this.zoom400MenuItem.Text = "400%";
|
||||
this.zoom400MenuItem.Click += new System.EventHandler(this.ZoomSetValueMenuItemClick);
|
||||
//
|
||||
// zoom600MenuItem
|
||||
//
|
||||
this.zoom600MenuItem.Name = "zoom600MenuItem";
|
||||
this.zoom600MenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.zoom600MenuItem.Tag = "600";
|
||||
this.zoom600MenuItem.Text = "600%";
|
||||
this.zoom600MenuItem.Click += new System.EventHandler(this.ZoomSetValueMenuItemClick);
|
||||
//
|
||||
// statusStripSpacer
|
||||
//
|
||||
this.statusStripSpacer.Name = "statusStripSpacer";
|
||||
this.statusStripSpacer.Size = new System.Drawing.Size(599, 19);
|
||||
this.statusStripSpacer.Spring = true;
|
||||
//
|
||||
// zoomStatusDropDownBtn
|
||||
//
|
||||
this.zoomStatusDropDownBtn.DropDown = this.zoomMenuStrip;
|
||||
this.zoomStatusDropDownBtn.Image = ((System.Drawing.Image)(resources.GetObject("zoomStatusDropDownBtn.Image")));
|
||||
this.zoomStatusDropDownBtn.ImageTransparentColor = System.Drawing.Color.Magenta;
|
||||
this.zoomStatusDropDownBtn.Name = "zoomStatusDropDownBtn";
|
||||
this.zoomStatusDropDownBtn.Size = new System.Drawing.Size(64, 22);
|
||||
this.zoomStatusDropDownBtn.Text = "100%";
|
||||
//
|
||||
// ImageEditorForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
|
||||
|
@ -1645,6 +1834,7 @@ namespace Greenshot {
|
|||
this.statusStrip1.ResumeLayout(true);
|
||||
this.tableLayoutPanel1.ResumeLayout(true);
|
||||
this.toolsToolStrip.ResumeLayout(true);
|
||||
this.zoomMenuStrip.ResumeLayout(false);
|
||||
this.menuStrip1.ResumeLayout(true);
|
||||
this.destinationsToolStrip.ResumeLayout(true);
|
||||
this.propertiesToolStrip.ResumeLayout(true);
|
||||
|
@ -1794,5 +1984,25 @@ namespace Greenshot {
|
|||
private Greenshot.Controls.ToolStripColorButton btnLineColor;
|
||||
private GreenshotPlugin.Controls.GreenshotToolStripMenuItem autoCropToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator17;
|
||||
private System.Windows.Forms.ContextMenuStrip zoomMenuStrip;
|
||||
private System.Windows.Forms.ToolStripMenuItem zoomInMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem zoomOutMenuItem;
|
||||
private System.Windows.Forms.ToolStripSeparator zoomMenuSeparator1;
|
||||
private System.Windows.Forms.ToolStripMenuItem zoomBestFitMenuItem;
|
||||
private System.Windows.Forms.ToolStripSeparator zoomMenuSeparator2;
|
||||
private System.Windows.Forms.ToolStripMenuItem zoom25MenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem zoom50MenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem zoom66MenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem zoom75MenuItem;
|
||||
private System.Windows.Forms.ToolStripSeparator zoomMenuSeparator3;
|
||||
private System.Windows.Forms.ToolStripMenuItem zoomActualSizeMenuItem;
|
||||
private System.Windows.Forms.ToolStripSeparator zoomMenuSeparator4;
|
||||
private System.Windows.Forms.ToolStripMenuItem zoom200MenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem zoom300MenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem zoom400MenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem zoom600MenuItem;
|
||||
private System.Windows.Forms.ToolStripDropDownButton zoomStatusDropDownBtn;
|
||||
private System.Windows.Forms.ToolStripMenuItem zoomMainMenuItem;
|
||||
private System.Windows.Forms.ToolStripStatusLabel statusStripSpacer;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,6 +66,12 @@ namespace Greenshot {
|
|||
// whether part of the editor controls are disabled depending on selected item(s)
|
||||
private bool _controlsDisabledDueToConfirmable;
|
||||
|
||||
/// <summary>
|
||||
/// All provided zoom values (in percents) in ascending order.
|
||||
/// </summary>
|
||||
private readonly int[] ZOOM_VALUES = new[] { 25, 50, 66, 75, 100, 200, 300, 400, 600 };
|
||||
private int _zoomValue = 100;
|
||||
|
||||
/// <summary>
|
||||
/// An Implementation for the IImageEditor, this way Plugins have access to the HWND handles wich can be used with Win32 API calls.
|
||||
/// </summary>
|
||||
|
@ -420,20 +426,14 @@ namespace Greenshot {
|
|||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void SurfaceSizeChanged(object sender, EventArgs e) {
|
||||
if (EditorConfiguration.MatchSizeToCapture) {
|
||||
// Set editor's initial size to the size of the surface plus the size of the chrome
|
||||
Size imageSize = Surface.Image.Size;
|
||||
Size currentFormSize = Size;
|
||||
Size currentImageClientSize = panel1.ClientSize;
|
||||
int minimumFormWidth = 650;
|
||||
int minimumFormHeight = 530;
|
||||
int newWidth = Math.Max(minimumFormWidth, currentFormSize.Width - currentImageClientSize.Width + imageSize.Width);
|
||||
int newHeight = Math.Max(minimumFormHeight, currentFormSize.Height - currentImageClientSize.Height + imageSize.Height);
|
||||
Size = new Size(newWidth, newHeight);
|
||||
private void SurfaceSizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (EditorConfiguration.MatchSizeToCapture)
|
||||
{
|
||||
Size = GetOptimalWindowSize();
|
||||
}
|
||||
dimensionsLabel.Text = Surface.Image.Width + "x" + Surface.Image.Height;
|
||||
ImageEditorFormResize(sender, new EventArgs());
|
||||
AlignCanvasPositionAfterResize();
|
||||
}
|
||||
|
||||
public ISurface Surface {
|
||||
|
@ -863,12 +863,31 @@ namespace Greenshot {
|
|||
case Keys.OemPeriod: // Rotate CW Ctrl + .
|
||||
RotateCwToolstripButtonClick(sender, e);
|
||||
break;
|
||||
case Keys.Add: // Ctrl + +
|
||||
case Keys.Add: // Ctrl + Num+
|
||||
case Keys.Oemplus: // Ctrl + +
|
||||
ZoomInMenuItemClick(sender, e);
|
||||
break;
|
||||
case Keys.Subtract: // Ctrl + Num-
|
||||
case Keys.OemMinus: // Ctrl + -
|
||||
ZoomOutMenuItemClick(sender, e);
|
||||
break;
|
||||
case Keys.Divide: // Ctrl + Num/
|
||||
case Keys.OemQuestion: // Ctrl + / (?)
|
||||
ZoomSetValueMenuItemClick(zoomActualSizeMenuItem, e);
|
||||
break;
|
||||
case Keys.Multiply: // Ctrl + Num*
|
||||
case Keys.D8: // Ctrl + 8 (*)
|
||||
ZoomBestFitMenuItemClick(sender, e);
|
||||
break;
|
||||
}
|
||||
} else if (e.Modifiers.Equals(Keys.Control | Keys.Shift)) {
|
||||
switch (e.KeyCode) {
|
||||
case Keys.Add: // Ctrl + Shift + Num+
|
||||
case Keys.Oemplus: // Ctrl + Shift + +
|
||||
EnlargeCanvasToolStripMenuItemClick(sender, e);
|
||||
break;
|
||||
case Keys.Subtract: // Ctrl + -
|
||||
case Keys.OemMinus: // Ctrl + -
|
||||
case Keys.Subtract: // Ctrl + Shift + Num-
|
||||
case Keys.OemMinus: // Ctrl + Shift + -
|
||||
ShrinkCanvasToolStripMenuItemClick(sender, e);
|
||||
break;
|
||||
}
|
||||
|
@ -1444,28 +1463,130 @@ namespace Greenshot {
|
|||
}
|
||||
|
||||
private void ImageEditorFormResize(object sender, EventArgs e) {
|
||||
AlignCanvasPositionAfterResize();
|
||||
}
|
||||
|
||||
private void AlignCanvasPositionAfterResize() {
|
||||
if (Surface?.Image == null || panel1 == null) {
|
||||
return;
|
||||
}
|
||||
Size imageSize = Surface.Image.Size;
|
||||
Size currentClientSize = panel1.ClientSize;
|
||||
var canvas = Surface as Control;
|
||||
Size canvasSize = canvas.Size;
|
||||
Size currentClientSize = panel1.ClientSize;
|
||||
Panel panel = (Panel) canvas?.Parent;
|
||||
if (panel == null) {
|
||||
return;
|
||||
}
|
||||
int offsetX = -panel.HorizontalScroll.Value;
|
||||
int offsetY = -panel.VerticalScroll.Value;
|
||||
if (currentClientSize.Width > imageSize.Width) {
|
||||
canvas.Left = offsetX + (currentClientSize.Width - imageSize.Width) / 2;
|
||||
if (currentClientSize.Width > canvasSize.Width) {
|
||||
canvas.Left = offsetX + (currentClientSize.Width - canvasSize.Width) / 2;
|
||||
} else {
|
||||
canvas.Left = offsetX + 0;
|
||||
}
|
||||
if (currentClientSize.Height > imageSize.Height) {
|
||||
canvas.Top = offsetY + (currentClientSize.Height - imageSize.Height) / 2;
|
||||
if (currentClientSize.Height > canvasSize.Height) {
|
||||
canvas.Top = offsetY + (currentClientSize.Height - canvasSize.Height) / 2;
|
||||
} else {
|
||||
canvas.Top = offsetY + 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compute a size as a sum of surface size and chrome.
|
||||
/// Upper bound is working area of the screen. Lower bound is fixed value.
|
||||
/// </summary>
|
||||
private Size GetOptimalWindowSize() {
|
||||
var surfaceSize = (Surface as Control).Size;
|
||||
var chromeSize = GetChromeSize();
|
||||
var newWidth = chromeSize.Width + surfaceSize.Width;
|
||||
var newHeight = chromeSize.Height + surfaceSize.Height;
|
||||
|
||||
// Upper bound. Don't make it bigger than the available working area.
|
||||
var screen = Screen.FromControl(this);
|
||||
var workingArea = screen.WorkingArea;
|
||||
newWidth = Math.Min(newWidth, workingArea.Width);
|
||||
newHeight = Math.Min(newHeight, workingArea.Height);
|
||||
|
||||
// Lower bound. Don't make it smaller than a fixed value.
|
||||
int minimumFormWidth = 650;
|
||||
int minimumFormHeight = 530;
|
||||
newWidth = Math.Max(minimumFormWidth, newWidth);
|
||||
newHeight = Math.Max(minimumFormHeight, newHeight);
|
||||
|
||||
return new Size(newWidth, newHeight);
|
||||
}
|
||||
|
||||
private Size GetChromeSize()
|
||||
=> Size - panel1.ClientSize;
|
||||
|
||||
/// <summary>
|
||||
/// Compute a size that the form can take without getting out of working area of the screen.
|
||||
/// </summary>
|
||||
private Size GetAvailableScreenSpace() {
|
||||
var screen = Screen.FromControl(this);
|
||||
var screenBounds = screen.Bounds;
|
||||
var workingArea = screen.WorkingArea;
|
||||
if (Left > screenBounds.Left && Top > screenBounds.Top) {
|
||||
return new Size(workingArea.Width - Left, workingArea.Height - Top);
|
||||
} else {
|
||||
return workingArea.Size;
|
||||
}
|
||||
}
|
||||
|
||||
private void ZoomInMenuItemClick(object sender, EventArgs e) {
|
||||
var nextIndex = Array.FindIndex(ZOOM_VALUES, v => v > _zoomValue);
|
||||
var nextValue = nextIndex < 0 ? ZOOM_VALUES[ZOOM_VALUES.Length - 1] : ZOOM_VALUES[nextIndex];
|
||||
|
||||
ZoomSetValue(nextValue);
|
||||
}
|
||||
|
||||
private void ZoomOutMenuItemClick(object sender, EventArgs e) {
|
||||
var nextIndex = Array.FindLastIndex(ZOOM_VALUES, v => v < _zoomValue);
|
||||
var nextValue = nextIndex < 0 ? ZOOM_VALUES[0] : ZOOM_VALUES[nextIndex];
|
||||
|
||||
ZoomSetValue(nextValue);
|
||||
}
|
||||
|
||||
private void ZoomSetValueMenuItemClick(object sender, EventArgs e) {
|
||||
var senderMenuItem = (ToolStripMenuItem)sender;
|
||||
int zoomPercent = int.Parse((string)senderMenuItem.Tag);
|
||||
|
||||
ZoomSetValue(zoomPercent);
|
||||
}
|
||||
|
||||
private void ZoomBestFitMenuItemClick(object sender, EventArgs e) {
|
||||
var maxWindowSize = GetAvailableScreenSpace();
|
||||
var chromeSize = GetChromeSize();
|
||||
var maxImageSize = maxWindowSize - chromeSize;
|
||||
var imageSize = Surface.Image.Size;
|
||||
|
||||
static bool isFit(int zoom, int source, int boundary)
|
||||
=> source * zoom / 100 <= boundary;
|
||||
|
||||
var nextValue = Array.FindLast(
|
||||
ZOOM_VALUES,
|
||||
zoom => isFit(zoom, imageSize.Width, maxImageSize.Width)
|
||||
&& isFit(zoom, imageSize.Height, maxImageSize.Height)
|
||||
);
|
||||
|
||||
ZoomSetValue(nextValue);
|
||||
}
|
||||
|
||||
private void ZoomSetValue(int value) {
|
||||
_zoomValue = value;
|
||||
Surface.ZoomFactor = 1f * value / 100;
|
||||
|
||||
// Update zoom controls
|
||||
string valueString = value.ToString();
|
||||
zoomStatusDropDownBtn.Text = valueString + "%";
|
||||
foreach (var item in zoomMenuStrip.Items) {
|
||||
if (item is ToolStripMenuItem menuItem) {
|
||||
menuItem.Checked = menuItem.Tag as string == valueString;
|
||||
}
|
||||
}
|
||||
|
||||
Size = GetOptimalWindowSize();
|
||||
AlignCanvasPositionAfterResize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -937,6 +937,84 @@
|
|||
BIhPAPEZIL7CAAQ6fptA+D+IJskFIM2cgtoMKm6rQfg/iEY3oB9oC8jWozBbgXquAvFykGYQkDJuZlBy
|
||||
WQvC/0E0QRfANIJoLmF9BnXPHTD8H8QmyQD9wBMMSPg/iE20ATK6uQwWUTeR8X8Qn2gDHJOfM6Dh/yA+
|
||||
igHkZijqZSZyXQAA4IG1TpHFZ2gAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="zoomInMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAABl0RVh0U29m
|
||||
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJKSURBVDhPY/j//z+DX8FVDBxZ/ZAhqeWVRkrbm7lA
|
||||
fB+If0HpuSBxkDxIHU4DIqruB0bXPrzftODpia0n3+668/zLiaNXPh3oXf7yFEgcJA9SBzbALeMsCvbI
|
||||
Oq/hk3fx/rSND3ccufH60MuPP259+vb7+etPP28/evPt7PztT3b5AuVB6sAGWMUcQMdz83svnth96cWB
|
||||
q48/ngBpBor9B9FP3n47d+3JpxMlEy6dAqkDG6Djtwkd35+77e72M/feXbj78suDd19+fQCK/QfRID5I
|
||||
fOme+3tA6sAGqLitRse/dp5/fgCkGMj+j44/fvv97PC118eA7F9gA5Rc1qLj+wu239sNsgmk+Ofvv5+B
|
||||
Yv9BNDgsPv68tWrfw0MgdWAD1D13oOO52W3nz+6/+urw/ZdfT4M0AcXgYQAMyHPF3RcvgdSBDXBwcGCw
|
||||
s7NjsLW1ZbCxsWEwd8q0Mgo+/GLe5gdnbz77fBoU+mCbgfSz998vbtj/6pRxyMn7egHHILGAbIC1tbU8
|
||||
0JDijsl7/ltFXnjVOOP5pZNXvpx+/u7H9VNXv5zpmPvymk3crfvmkdcDDYPPQNIBzACgRi03N/eaHTv2
|
||||
/BcVFWtWs2qxc0x+PheI7wPxLyg91z7xiYZF1E0GFAOAtlsEBga3HTly5r+iolIPCwuLqpJxCYNTyisM
|
||||
DDSAAcUAoO3eCQkpEy5evPtfT89gGlCzMRAzEG2Aubl5ya1br/7b2zvPY2VldQFpJskAPT09LRERkRag
|
||||
5hiYZhAWlrEhzgDy8X8GAJItIDq7n94UAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="zoomOutMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAABl0RVh0U29m
|
||||
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIySURBVDhPY/j//z+DtrY2g559IYNfwVU4jqx+yJDU
|
||||
8kojpe3NXCC+D8S/oPRckDhIHqQObACyRhiOqLofGF378H7Tgqcntp58u+vO8y8njl75dKB3+ctTIHGQ
|
||||
PEgd2AC3jLMo2CPrvIZP3sX70zY+3HHkxutDj958O/vk7bdzIAxiz9/+ZJcvUB6kDmyAVcwBdDw3v/fi
|
||||
id2XXhy4+vjjCZhmGL725NOJkgmXToHUgQ3Q8duEju/P3XZ3+5l77y7cffnlAToGiS/dc38PSB3YABW3
|
||||
1ej4187zzw+AFAPZ/9Hxx2+/nx2+9voYkP0LbICSy1p0fH/B9nu7QTaBFH/69vs5Mn798eetVfseHgKp
|
||||
Axug7rkDHc/Nbjt/dv/VV4fvv/x6Gj0MgAF5rrj74iWQOrABDg4ODHZ2dgy2trYMNjY2DOZOmVZGwYdf
|
||||
zNv84OzNZ59RDHj2/vvFDftfnTIOOXlfL+AYJBaQDbC2tpYHGlLcMXnPf6vIC68aZzy/dPLKl9PP3/24
|
||||
furqlzMdc19es4m7dd888nqgYfAZSDqAGQDUqOXm5l6zY8ee/6KiYs1qVi12jsnP5wLxfSD+BaXn2ic+
|
||||
0bCIusmAYgDQdovAwOC2I0fO/FdUVOphYWFRVTIuYXBKeYWBgQYwoBgAtN07ISFlwsWLd//r6RlMA2o2
|
||||
BmIGog0wNzcvuXXr1X97e+d5rKysLiDNJBmgp6enJSIi0gLUHAPTDMLCMjbEGUA+/s8AAJUZIgOF4ptY
|
||||
AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="zoomBestFitMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAABl0RVh0U29m
|
||||
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJISURBVDhPnZLLaxNRFIfvIvkLTF0J0uAjNDKoWaTk
|
||||
bS1RUYshLowWqZqFD/BBs/KxUEMoaKEgiJuRbqRQ6UaojTqUYGpJYmpMSFuMxklK2mmmmba2kzSZINd7
|
||||
pk1p4qa6+Djn3vs73x24gzDGSKvVIsp6B3XcntzEdS+LLnt5jdtXoAksQdqoNOzDOeRkwdbBGufuso4L
|
||||
D7Lso/7Z0HBYeP+DE0OfkiuB3oF8BPbhHHKywH51oo7j12OaUzfj7ADDhTJ8MbNclOZWSlUOgH5wdD50
|
||||
mpxDThYYOgON0Ld646F0XsyQHgOFpYpcgZywNuPpS0QgJwsOdLxphKXfpkdAQHq8KErL0EOFNfSvGJaB
|
||||
nCzYY3/diPQuxgUgmBfWMHx6Tih9gQrrX6XqXHBqYRxyskDdPtQI2z/y8wMISI8r1d+rMAwV1iAYHM1+
|
||||
hJws2H/C3wh9wxebyC4UZ0iPAV4oyxVYKkpc95N4AnKywGazIYvFgsxmMzKZTEjfds1w2BmcH2JmvxdW
|
||||
K5svAIjlKj8cLCR1Z8MsdWZ8/RW2CoxG424i6e55xmCD6yv/8AWXCCfFz9xieToyKUZ76PyU6WKK1bum
|
||||
HYec0fX/oCYggy12+7H7fj+Dm5p2Pt5n8FqOXOFoAkuQNiptvZTTtJ7/huoE5PZWh8PpGxuL4uZm9VOF
|
||||
QrFXrfOgNjf/F0SA6gTk9pNdXe6+eDyNKergczKsI6BtC/R6vSeV4rHVevSlUqlsh+F/ElAU1aJSqbxk
|
||||
uLM2DOzYZdqe4P/B6A86Ah9NBTgWLgAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="zoomActualSizeMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAABl0RVh0U29m
|
||||
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJXSURBVDhPnZLda1JhHMefC/0Lcl0FMelFZhwqLxy+
|
||||
t4YV1UjsImvFKi+qQS9MuujlohIZ1GAQjG7O2k0ERdALpW3SZNpQ0zllall6NKwzj1OWczId8fT8zuaY
|
||||
drO6+PBwvs/393kezjkIY4ykUimitNdQ19XoGqabGXTOyknMtjmawBBqqysNOexDjxesH6xz4gZjOHU7
|
||||
w9wd+eF96yuMfmPL3o8zJdfA05wfctiHHi/QXwg2cPBSSHLkcpgZepVxeD7nJ+YXaz9LlWU2X6p+/T5X
|
||||
CT62Z0ePkn3o8QJFt6sZ+spA2DsWmXVlC5VMrzWESYZBQp6nYtmS1zIY8UOPF+zqet0MQ79L2kEQSBWn
|
||||
i+XaPMlwMldOQwY8cTJO6PGCbfrnzdTeh1i+CMDJJFu7AeCO5SehxwvEnS+aYUbsqTEY5n4tJarLvxdI
|
||||
hmGF9wCCZx8yE9DjBTsPOZqhe22h4HiUc8+VqtnT1/2YZBhWuAV5kVN998MR6PECnU6HNBoNUqvVSKVS
|
||||
IXnHRcVeo3t2+E06mOYW4zBUp7BQTb0c5/yy4z6GOja58hXWC5RK5VYi6et/6MQK0zR35xEb8c2UP7HF
|
||||
pbg/Wg7007mY6kyCkZvihj3GwMp/UBeQwTa9/sAth8OJW1o239uhsGr2nWdpAkOora609mxW0n7yC2oQ
|
||||
kNPbDQajzeMJ4NZW8QOBQLBdLLOgDjP3F0SAGgTk9MM9PebBcDiJKWr3EBmWEdCGBXK53JJIcFir3T8s
|
||||
FAo7YfifBBRFtYlEIisZ7q4PA5u2qDYm+H8w+gNv9h/ta4LougAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="zoomStatusDropDownBtn.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHYSURBVDhPY8AH4ltfa6S0vZ6b3Pr6PhD/AtEgPkgcqgQ3
|
||||
iKi6Hxhd8/B+0/ynJ7acfLvrzrPPJ45c+Xigd9nLUyBxkDxUKSZwyzmj4Z176f7UjQ92HL7++tCjN9/O
|
||||
Pn7z7RwIg9jztz3e5QOUB6mDakEFVjH75xb0Xjyx++KLA1cefToO0wzD1558OlE84eJpkDqoFlSg7bvp
|
||||
/pytd3aADMCFl+6+vwekDqoFFSi7rf614/xzuGJ0Fzx+++3soauvjoHUQbWgAiXnNffn77i3G6wZqBib
|
||||
ASv3PTgEUgfVggrUPLfPzWo/d3bv5VeH77/4fBrdgEevv54r7rpwCaQOqgUVWDpmWhkGHXoxf/P9szef
|
||||
fkIx4Nn7b5fW73t5yjj45H2doKOYsWBpaSlvbW1d3DF5z3/LyAuvGqY/vXTiyqfTz999v37qyucz7fNe
|
||||
XrOOvXXfNOIaZjqwsbHRcnV1r9mxY89/UVHRZlXLZjuH5GdzHZOf3XdMevYLRIP49vFPMW0G2moRGBjc
|
||||
duTImf8KCko9bGxsqlApwgBos098fPKEixfv/tfT05/KyspqDJUiDpiZmZXcuvXqv52d8zxmZmYXqDDx
|
||||
wMDAQEtYWLgFaHMMVIhegIEBADK7VwLsrsplAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="btnStepLabel01.Image" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
|
@ -1026,4 +1104,7 @@
|
|||
<metadata name="fileSavedStatusContextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="zoomMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>782, 17</value>
|
||||
</metadata>
|
||||
</root>
|
BIN
Greenshot/icons/fugue/magnifier-zoom-actual.png
Normal file
BIN
Greenshot/icons/fugue/magnifier-zoom-actual.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 742 B |
BIN
Greenshot/icons/fugue/magnifier-zoom-fit.png
Normal file
BIN
Greenshot/icons/fugue/magnifier-zoom-fit.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 726 B |
BIN
Greenshot/icons/fugue/magnifier-zoom-in.png
Normal file
BIN
Greenshot/icons/fugue/magnifier-zoom-in.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 733 B |
BIN
Greenshot/icons/fugue/magnifier-zoom-out.png
Normal file
BIN
Greenshot/icons/fugue/magnifier-zoom-out.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 707 B |
BIN
Greenshot/icons/fugue/magnifier-zoom.png
Normal file
BIN
Greenshot/icons/fugue/magnifier-zoom.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 676 B |
|
@ -21,6 +21,7 @@
|
|||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using GreenshotPlugin.Effects;
|
||||
|
@ -147,8 +148,13 @@ namespace GreenshotPlugin.Interfaces
|
|||
/// <param name="container"></param>
|
||||
/// <returns>This returns false if the container is deleted but still in the undo stack</returns>
|
||||
bool IsOnSurface(IDrawableContainer container);
|
||||
void Invalidate(Rectangle rectangleToInvalidate);
|
||||
void Invalidate();
|
||||
/// <summary>
|
||||
/// Invalidates the specified region of the Surface.
|
||||
/// Takes care of the Surface zoom level, accepts rectangle in the coordinate space of the Image.
|
||||
/// </summary>
|
||||
/// <param name="rectangleToInvalidate">Bounding rectangle for updated elements, in the coordinate space of the Image.</param>
|
||||
void InvalidateElements(Rectangle rectangleToInvalidate);
|
||||
bool Modified
|
||||
{
|
||||
get;
|
||||
|
@ -189,6 +195,15 @@ namespace GreenshotPlugin.Interfaces
|
|||
int Width { get; }
|
||||
int Height { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Zoom value applied to the surface. 1.0f for actual size (100%).
|
||||
/// </summary>
|
||||
float ZoomFactor { get; set; }
|
||||
/// <summary>
|
||||
/// Matrix representing zoom applied to the surface.
|
||||
/// </summary>
|
||||
Matrix ZoomMatrix { get; }
|
||||
|
||||
void MakeUndoable(IMemento memento, bool allowMerge);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue