Propagate DPI Changes down to Drawable Containers and Adorners and Resize Grippers Accordingly (#200)

* Propagate DPI Changes down to Drawable Containers and Adorners and Resize Grippers Accordingly
* Make Grippers Slightly Larger
* Add White Border to Grippers for Better Contrast on Dark Backgrounds
This commit is contained in:
jklingen 2020-08-06 21:29:55 +02:00 committed by GitHub
parent 926855cd70
commit f159a871ca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 185 additions and 128 deletions

View file

@ -22,6 +22,7 @@
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Windows.Forms; using System.Windows.Forms;
using GreenshotPlugin.Core;
using GreenshotPlugin.Interfaces.Drawing; using GreenshotPlugin.Interfaces.Drawing;
using GreenshotPlugin.Interfaces.Drawing.Adorners; using GreenshotPlugin.Interfaces.Drawing.Adorners;
@ -31,7 +32,8 @@ namespace Greenshot.Drawing.Adorners
{ {
public virtual EditStatus EditStatus { get; protected set; } = EditStatus.IDLE; public virtual EditStatus EditStatus { get; protected set; } = EditStatus.IDLE;
protected Size _size = new Size(4, 4); private static readonly Size defaultSize = new Size(6, 6);
protected Size _size = defaultSize;
public AbstractAdorner(IDrawableContainer owner) public AbstractAdorner(IDrawableContainer owner)
{ {
@ -139,6 +141,15 @@ namespace Greenshot.Drawing.Adorners
} }
} }
/// <summary>
/// Adjust UI elements to the supplied DPI settings
/// </summary>
/// <param name="dpi"></param>
public void AdjustToDpi(uint dpi)
{
_size = DpiHelper.ScaleWithDpi(defaultSize, dpi);
}
/// <summary> /// <summary>
/// Draw the adorner /// Draw the adorner
/// </summary> /// </summary>

View file

@ -145,14 +145,12 @@ namespace Greenshot.Drawing.Adorners
var bounds = BoundsOnSurface; var bounds = BoundsOnSurface;
GraphicsState state = targetGraphics.Save(); GraphicsState state = targetGraphics.Save();
targetGraphics.SmoothingMode = SmoothingMode.None;
targetGraphics.CompositingMode = CompositingMode.SourceCopy; targetGraphics.CompositingMode = CompositingMode.SourceCopy;
targetGraphics.PixelOffsetMode = PixelOffsetMode.Half;
targetGraphics.InterpolationMode = InterpolationMode.NearestNeighbor;
try try
{ {
targetGraphics.FillRectangle(Brushes.Black, bounds.X, bounds.Y, bounds.Width, bounds.Height); targetGraphics.FillRectangle(Brushes.Black, bounds);
targetGraphics.DrawRectangle(new Pen(Brushes.White), bounds);
} }
catch catch
{ {

View file

@ -172,12 +172,10 @@ namespace Greenshot.Drawing.Adorners
var bounds = BoundsOnSurface; var bounds = BoundsOnSurface;
GraphicsState state = targetGraphics.Save(); GraphicsState state = targetGraphics.Save();
targetGraphics.SmoothingMode = SmoothingMode.None;
targetGraphics.CompositingMode = CompositingMode.SourceCopy; targetGraphics.CompositingMode = CompositingMode.SourceCopy;
targetGraphics.PixelOffsetMode = PixelOffsetMode.Half;
targetGraphics.InterpolationMode = InterpolationMode.NearestNeighbor;
targetGraphics.FillRectangle(Brushes.Black, bounds.X, bounds.Y, bounds.Width , bounds.Height); targetGraphics.FillRectangle(Brushes.Black, bounds);
targetGraphics.DrawRectangle(new Pen(Brushes.White), bounds);
targetGraphics.Restore(state); targetGraphics.Restore(state);
} }
} }

View file

@ -1,118 +1,119 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: http://getgreenshot.org/ * For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Windows.Forms; using System.Windows.Forms;
using GreenshotPlugin.Interfaces.Drawing; using GreenshotPlugin.Interfaces.Drawing;
namespace Greenshot.Drawing.Adorners namespace Greenshot.Drawing.Adorners
{ {
/// <summary> /// <summary>
/// This implements the special "gripper" for the Speech-Bubble tail /// This implements the special "gripper" for the Speech-Bubble tail
/// </summary> /// </summary>
public class TargetAdorner : AbstractAdorner public class TargetAdorner : AbstractAdorner
{ {
public TargetAdorner(IDrawableContainer owner, Point location) : base(owner) public TargetAdorner(IDrawableContainer owner, Point location) : base(owner)
{ {
Location = location; Location = location;
} }
/// <summary> /// <summary>
/// Handle the mouse down /// Handle the mouse down
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="mouseEventArgs"></param> /// <param name="mouseEventArgs"></param>
public override void MouseDown(object sender, MouseEventArgs mouseEventArgs) public override void MouseDown(object sender, MouseEventArgs mouseEventArgs)
{ {
EditStatus = EditStatus.MOVING; EditStatus = EditStatus.MOVING;
} }
/// <summary> /// <summary>
/// Handle the mouse move /// Handle the mouse move
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="mouseEventArgs"></param> /// <param name="mouseEventArgs"></param>
public override void MouseMove(object sender, MouseEventArgs mouseEventArgs) public override void MouseMove(object sender, MouseEventArgs mouseEventArgs)
{ {
if (EditStatus != EditStatus.MOVING) if (EditStatus != EditStatus.MOVING)
{ {
return; return;
} }
Owner.Invalidate(); Owner.Invalidate();
Point newGripperLocation = new Point(mouseEventArgs.X, mouseEventArgs.Y); Point newGripperLocation = new Point(mouseEventArgs.X, mouseEventArgs.Y);
Rectangle imageBounds = new Rectangle(0, 0, Owner.Parent.Image.Width, Owner.Parent.Image.Height); Rectangle imageBounds = new Rectangle(0, 0, Owner.Parent.Image.Width, Owner.Parent.Image.Height);
// Check if gripper inside the parent (surface), if not we need to move it inside // Check if gripper inside the parent (surface), if not we need to move it inside
// This was made for BUG-1682 // This was made for BUG-1682
if (!imageBounds.Contains(newGripperLocation)) if (!imageBounds.Contains(newGripperLocation))
{ {
if (newGripperLocation.X > imageBounds.Right) if (newGripperLocation.X > imageBounds.Right)
{ {
newGripperLocation.X = imageBounds.Right - 5; newGripperLocation.X = imageBounds.Right - 5;
} }
if (newGripperLocation.X < imageBounds.Left) if (newGripperLocation.X < imageBounds.Left)
{ {
newGripperLocation.X = imageBounds.Left; newGripperLocation.X = imageBounds.Left;
} }
if (newGripperLocation.Y > imageBounds.Bottom) if (newGripperLocation.Y > imageBounds.Bottom)
{ {
newGripperLocation.Y = imageBounds.Bottom - 5; newGripperLocation.Y = imageBounds.Bottom - 5;
} }
if (newGripperLocation.Y < imageBounds.Top) if (newGripperLocation.Y < imageBounds.Top)
{ {
newGripperLocation.Y = imageBounds.Top; newGripperLocation.Y = imageBounds.Top;
} }
} }
Location = newGripperLocation; Location = newGripperLocation;
Owner.Invalidate(); Owner.Invalidate();
} }
/// <summary> /// <summary>
/// Draw the adorner /// Draw the adorner
/// </summary> /// </summary>
/// <param name="paintEventArgs">PaintEventArgs</param> /// <param name="paintEventArgs">PaintEventArgs</param>
public override void Paint(PaintEventArgs paintEventArgs) public override void Paint(PaintEventArgs paintEventArgs)
{ {
Graphics targetGraphics = paintEventArgs.Graphics; Graphics targetGraphics = paintEventArgs.Graphics;
var bounds = BoundsOnSurface; var bounds = BoundsOnSurface;
targetGraphics.FillRectangle(Brushes.Green, bounds.X, bounds.Y, bounds.Width, bounds.Height); targetGraphics.FillRectangle(Brushes.Green, bounds);
} targetGraphics.DrawRectangle(new Pen(Brushes.White), bounds);
}
/// <summary>
/// Made sure this adorner is transformed /// <summary>
/// </summary> /// Made sure this adorner is transformed
/// <param name="matrix">Matrix</param> /// </summary>
public override void Transform(Matrix matrix) /// <param name="matrix">Matrix</param>
{ public override void Transform(Matrix matrix)
if (matrix == null) {
{ if (matrix == null)
return; {
} return;
Point[] points = new[] { Location }; }
matrix.TransformPoints(points); Point[] points = new[] { Location };
Location = points[0]; matrix.TransformPoints(points);
} Location = points[0];
} }
} }
}

View file

@ -369,6 +369,18 @@ namespace Greenshot.Drawing
Draw(graphics, renderMode); Draw(graphics, renderMode);
} }
/// <summary>
/// Adjust UI elements to the supplied DPI settings
/// </summary>
/// <param name="dpi"></param>
public void AdjustToDpi(uint dpi)
{
foreach(var adorner in Adorners)
{
adorner.AdjustToDpi(dpi);
}
}
public virtual bool Contains(int x, int y) { public virtual bool Contains(int x, int y) {
return Bounds.Contains(x , y); return Bounds.Contains(x , y);
} }

View file

@ -604,5 +604,16 @@ namespace Greenshot.Drawing {
// Do not change this code. Put cleanup code in Dispose(bool disposing) above. // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true); Dispose(true);
} }
}
/// <summary>
/// Adjust UI elements to the supplied DPI settings
/// </summary>
/// <param name="dpi"></param>
public void AdjustToDpi(uint dpi)
{
foreach (var drawableContainer in this) {
drawableContainer.AdjustToDpi(dpi);
}
}
}
} }

View file

@ -432,6 +432,17 @@ namespace Greenshot.Drawing
/// </summary> /// </summary>
public ICaptureDetails CaptureDetails { get; set; } public ICaptureDetails CaptureDetails { get; set; }
/// <summary>
/// Adjust UI elements to the supplied DPI settings
/// </summary>
/// <param name="dpi"></param>
public void AdjustToDpi(uint dpi)
{
foreach (var element in this._elements) {
element.AdjustToDpi(dpi);
}
}
/// <summary> /// <summary>
/// Base Surface constructor /// Base Surface constructor
/// </summary> /// </summary>

View file

@ -101,6 +101,8 @@ namespace Greenshot {
destinationsToolStrip.ImageScalingSize = newSize; destinationsToolStrip.ImageScalingSize = newSize;
propertiesToolStrip.ImageScalingSize = newSize; propertiesToolStrip.ImageScalingSize = newSize;
propertiesToolStrip.MinimumSize = new Size(150, newSize.Height + 10); propertiesToolStrip.MinimumSize = new Size(150, newSize.Height + 10);
_surface.AdjustToDpi(dpi);
} }
public ImageEditorForm(ISurface iSurface, bool outputMade) public ImageEditorForm(ISurface iSurface, bool outputMade)

View file

@ -87,5 +87,11 @@ namespace GreenshotPlugin.Interfaces.Drawing.Adorners
/// </summary> /// </summary>
/// <param name="matrix">Matrix</param> /// <param name="matrix">Matrix</param>
void Transform(Matrix matrix); void Transform(Matrix matrix);
/// <summary>
/// Adjust UI elements to the supplied DPI settings
/// </summary>
/// <param name="dpi"></param>
void AdjustToDpi(uint dpi);
} }
} }

View file

@ -120,6 +120,12 @@ namespace GreenshotPlugin.Interfaces.Drawing
/// Available adorners for the DrawableContainer /// Available adorners for the DrawableContainer
/// </summary> /// </summary>
IList<IAdorner> Adorners { get; } IList<IAdorner> Adorners { get; }
/// <summary>
/// Adjust UI elements to the supplied DPI settings
/// </summary>
/// <param name="dpi"></param>
void AdjustToDpi(uint dpi);
} }
public interface IDrawableContainerList : IList<IDrawableContainer>, IDisposable public interface IDrawableContainerList : IList<IDrawableContainer>, IDisposable
@ -167,6 +173,7 @@ namespace GreenshotPlugin.Interfaces.Drawing
void PushElementsToBottom(IDrawableContainerList elements); void PushElementsToBottom(IDrawableContainerList elements);
void ShowContextMenu(MouseEventArgs e, ISurface surface); void ShowContextMenu(MouseEventArgs e, ISurface surface);
void HandleFieldChangedEvent(object sender, FieldChangedEventArgs e); void HandleFieldChangedEvent(object sender, FieldChangedEventArgs e);
void AdjustToDpi(uint dpi);
} }
public interface ITextContainer : IDrawableContainer public interface ITextContainer : IDrawableContainer