mirror of
https://github.com/ShareX/ShareX.git
synced 2024-10-01 09:47:22 +13:00
Merge pull request #6084 from EricTetz/develop
Support zooming in image editor
This commit is contained in:
commit
cd499d73d5
19 changed files with 251 additions and 67 deletions
|
@ -144,6 +144,11 @@ public static Point Add(this Point point, Point offset)
|
|||
return new Point(point.X + offset.X, point.Y + offset.Y);
|
||||
}
|
||||
|
||||
public static Point Scale(this Point point, float scaleFactor)
|
||||
{
|
||||
return new Point((int)Math.Round(point.X * scaleFactor), (int)Math.Round(point.Y * scaleFactor));
|
||||
}
|
||||
|
||||
public static Size Offset(this Size size, int offset)
|
||||
{
|
||||
return size.Offset(offset, offset);
|
||||
|
@ -159,6 +164,15 @@ public static Rectangle Offset(this Rectangle rect, int offset)
|
|||
return new Rectangle(rect.X - offset, rect.Y - offset, rect.Width + (offset * 2), rect.Height + (offset * 2));
|
||||
}
|
||||
|
||||
public static Rectangle Scale(this Rectangle rect, float scaleFactor)
|
||||
{
|
||||
return new Rectangle(
|
||||
(int)Math.Round(rect.X * scaleFactor),
|
||||
(int)Math.Round(rect.Y * scaleFactor),
|
||||
(int)Math.Round(rect.Width * scaleFactor),
|
||||
(int)Math.Round(rect.Height * scaleFactor));
|
||||
}
|
||||
|
||||
public static Rectangle LocationOffset(this Rectangle rect, int x, int y)
|
||||
{
|
||||
return new Rectangle(rect.X + x, rect.Y + y, rect.Width, rect.Height);
|
||||
|
|
|
@ -34,20 +34,36 @@ public class GraphicsQualityManager : IDisposable
|
|||
private CompositingQuality previousCompositingQuality;
|
||||
private InterpolationMode previousInterpolationMode;
|
||||
private SmoothingMode previousSmoothingMode;
|
||||
private PixelOffsetMode previousPixelOffsetMode;
|
||||
private Graphics g;
|
||||
|
||||
public GraphicsQualityManager(Graphics g, bool setHighQuality = true)
|
||||
public enum Quality
|
||||
{
|
||||
Low,
|
||||
High,
|
||||
}
|
||||
|
||||
public GraphicsQualityManager(Graphics g, Quality? quality = Quality.High)
|
||||
{
|
||||
this.g = g;
|
||||
|
||||
previousCompositingQuality = g.CompositingQuality;
|
||||
previousInterpolationMode = g.InterpolationMode;
|
||||
previousSmoothingMode = g.SmoothingMode;
|
||||
previousPixelOffsetMode = g.PixelOffsetMode;
|
||||
|
||||
if (setHighQuality)
|
||||
if (!quality.HasValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (quality.Value == Quality.High)
|
||||
{
|
||||
SetHighQuality();
|
||||
}
|
||||
else if (quality.Value == Quality.Low)
|
||||
{
|
||||
SetLowQuality();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetHighQuality()
|
||||
|
@ -60,6 +76,17 @@ public void SetHighQuality()
|
|||
}
|
||||
}
|
||||
|
||||
public void SetLowQuality()
|
||||
{
|
||||
if (g != null)
|
||||
{
|
||||
g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
|
||||
g.InterpolationMode = InterpolationMode.NearestNeighbor;
|
||||
g.SmoothingMode = SmoothingMode.HighSpeed;
|
||||
g.CompositingQuality = CompositingQuality.HighSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (g != null)
|
||||
|
@ -67,6 +94,7 @@ public void Dispose()
|
|||
g.CompositingQuality = previousCompositingQuality;
|
||||
g.InterpolationMode = previousInterpolationMode;
|
||||
g.SmoothingMode = previousSmoothingMode;
|
||||
g.PixelOffsetMode = previousPixelOffsetMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ You should have received a copy of the GNU General Public License
|
|||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
|
@ -87,6 +88,22 @@ public sealed class RegionCaptureForm : Form
|
|||
private TextAnimation editorPanTipAnimation;
|
||||
private Cursor defaultCursor, openHandCursor, closedHandCursor;
|
||||
private Color canvasBackgroundColor, canvasBorderColor, textColor, textShadowColor, textBackgroundColor, textOuterBorderColor, textInnerBorderColor;
|
||||
private float zoomFactor = 1;
|
||||
|
||||
public float ZoomFactor
|
||||
{
|
||||
get { return zoomFactor; }
|
||||
set { zoomFactor = Math.Max(0.2F, Math.Min(6F, value)); } // constrain range from 20% - 600%
|
||||
}
|
||||
|
||||
public void ZoomTransform(Graphics g, bool invertZoom = false)
|
||||
{
|
||||
if (Math.Round(ZoomFactor * 100) != 100)
|
||||
{
|
||||
float scale = invertZoom ? 1 / ZoomFactor : ZoomFactor;
|
||||
g.ScaleTransform(scale, scale);
|
||||
}
|
||||
}
|
||||
|
||||
public RegionCaptureForm(RegionCaptureMode mode, RegionCaptureOptions options, Bitmap canvas = null)
|
||||
{
|
||||
|
@ -162,6 +179,9 @@ public RegionCaptureForm(RegionCaptureMode mode, RegionCaptureOptions options, B
|
|||
InitializeComponent();
|
||||
}
|
||||
|
||||
public Point ScaledClientMousePosition => InputManager.ClientMousePosition.Scale(1 / ZoomFactor);
|
||||
public Point ScaledClientMouseVelocity => InputManager.MouseVelocity.Scale(1 / ZoomFactor);
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
SuspendLayout();
|
||||
|
@ -236,6 +256,7 @@ private void InitializeComponent()
|
|||
Shown += RegionCaptureForm_Shown;
|
||||
KeyDown += RegionCaptureForm_KeyDown;
|
||||
MouseDown += RegionCaptureForm_MouseDown;
|
||||
MouseWheel += RegionCaptureForm_MouseWheel;
|
||||
Resize += RegionCaptureForm_Resize;
|
||||
LocationChanged += RegionCaptureForm_LocationChanged;
|
||||
LostFocus += RegionCaptureForm_LostFocus;
|
||||
|
@ -249,35 +270,41 @@ internal void UpdateTitle()
|
|||
{
|
||||
if (forceClose) return;
|
||||
|
||||
string text;
|
||||
var title = new StringBuilder();
|
||||
|
||||
if (IsEditorMode)
|
||||
{
|
||||
text = "ShareX - " + Resources.RegionCaptureForm_InitializeComponent_ImageEditor;
|
||||
title.AppendFormat("ShareX - {0}", Resources.RegionCaptureForm_InitializeComponent_ImageEditor);
|
||||
|
||||
if (Canvas != null)
|
||||
{
|
||||
text += $" - {Canvas.Width}x{Canvas.Height}";
|
||||
title.AppendFormat(" - {0}x{1}", Canvas.Width, Canvas.Height);
|
||||
}
|
||||
|
||||
string fileName = Helpers.GetFileNameSafe(ImageFilePath);
|
||||
|
||||
if (!string.IsNullOrEmpty(fileName))
|
||||
{
|
||||
text += " - " + fileName;
|
||||
title.AppendFormat(" - {0}", fileName);
|
||||
}
|
||||
|
||||
if (!IsFullscreen && Options.ShowFPS)
|
||||
{
|
||||
text += " - FPS: " + FPSManager.FPS.ToString();
|
||||
title.AppendFormat(" - FPS: {0}", FPSManager.FPS.ToString());
|
||||
}
|
||||
|
||||
double zoomPercentage = Math.Round(ZoomFactor * 100);
|
||||
if (zoomPercentage != 100)
|
||||
{
|
||||
title.AppendFormat(" - ZOOM: {0}%", zoomPercentage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
text = "ShareX - " + Resources.BaseRegionForm_InitializeComponent_Region_capture;
|
||||
title.AppendFormat("ShareX - {0}", Resources.BaseRegionForm_InitializeComponent_Region_capture);
|
||||
}
|
||||
|
||||
Text = text;
|
||||
Text = title.ToString();
|
||||
}
|
||||
|
||||
private void Prepare(Bitmap canvas = null)
|
||||
|
@ -409,6 +436,8 @@ private void Pan(int deltaX, int deltaY, bool usePanningStretch = true)
|
|||
Rectangle limitRectangle = new Rectangle(ClientArea.X + panLimitSize.Width, ClientArea.Y + panLimitSize.Height,
|
||||
ClientArea.Width - (panLimitSize.Width * 2), ClientArea.Height - (panLimitSize.Height * 2));
|
||||
|
||||
limitRectangle = limitRectangle.Scale(1 / ZoomFactor);
|
||||
|
||||
deltaX = Math.Max(deltaX, limitRectangle.Left - CanvasRectangle.Right);
|
||||
deltaX = Math.Min(deltaX, limitRectangle.Right - CanvasRectangle.Left);
|
||||
deltaY = Math.Max(deltaY, limitRectangle.Top - CanvasRectangle.Bottom);
|
||||
|
@ -447,12 +476,13 @@ private void AutomaticPan(Vector2 centerOffset)
|
|||
{
|
||||
if (IsEditorMode)
|
||||
{
|
||||
int x = (int)Math.Round((ClientArea.Width * 0.5f) + centerOffset.X);
|
||||
int y = (int)Math.Round((ClientArea.Height * 0.5f) + centerOffset.Y);
|
||||
int newX = x - (CanvasRectangle.Width / 2);
|
||||
int newY = y - (CanvasRectangle.Height / 2);
|
||||
int deltaX = newX - CanvasRectangle.X;
|
||||
int deltaY = newY - CanvasRectangle.Y;
|
||||
Rectangle canvas = CanvasRectangle.Scale(ZoomFactor);
|
||||
float x = ClientArea.Width / 2 + centerOffset.X;
|
||||
float y = ClientArea.Height / 2 + centerOffset.Y;
|
||||
float newX = x - canvas.Width / 2;
|
||||
float newY = y - canvas.Height / 2;
|
||||
int deltaX = (int)Math.Round((newX - canvas.X) / ZoomFactor);
|
||||
int deltaY = (int)Math.Round((newY - canvas.Y) / ZoomFactor);
|
||||
Pan(deltaX, deltaY, false);
|
||||
}
|
||||
}
|
||||
|
@ -515,10 +545,17 @@ private void RegionCaptureForm_Shown(object sender, EventArgs e)
|
|||
}
|
||||
}
|
||||
|
||||
if (IsEditorMode && Options.ShowEditorPanTip && editorPanTipAnimation != null)
|
||||
if (IsEditorMode)
|
||||
{
|
||||
if (Options.ShowEditorPanTip && editorPanTipAnimation != null)
|
||||
{
|
||||
editorPanTipAnimation.Start();
|
||||
}
|
||||
if (Options.ZoomToFitOnOpen)
|
||||
{
|
||||
ZoomToFit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RegionCaptureForm_Resize(object sender, EventArgs e)
|
||||
|
@ -618,6 +655,19 @@ internal void RegionCaptureForm_KeyDown(object sender, KeyEventArgs e)
|
|||
case Keys.Control | Keys.C:
|
||||
CopyAreaInfo();
|
||||
break;
|
||||
case Keys.Control | Keys.Alt | Keys.D0:
|
||||
ZoomToFit();
|
||||
break;
|
||||
case Keys.Control | Keys.D0:
|
||||
ZoomFactor = 1;
|
||||
CenterCanvas();
|
||||
break;
|
||||
case Keys.Control | Keys.Oemplus:
|
||||
Zoom(true, false);
|
||||
break;
|
||||
case Keys.Control | Keys.OemMinus:
|
||||
Zoom(false, false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IsEditorMode && e.KeyData >= Keys.D0 && e.KeyData <= Keys.D9)
|
||||
|
@ -642,6 +692,46 @@ private void RegionCaptureForm_MouseDown(object sender, MouseEventArgs e)
|
|||
}
|
||||
}
|
||||
|
||||
private void RegionCaptureForm_MouseWheel(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (!IsEditorMode || !ModifierKeys.HasFlag(Keys.Control))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Zoom(e.Delta > 0);
|
||||
}
|
||||
|
||||
private void Zoom(bool closer, bool atMouse = true)
|
||||
{
|
||||
const float ZoomScaleAmount = 1.1F;
|
||||
|
||||
Point centerBefore = atMouse ? ScaledClientMousePosition : ScaledClientCenter;
|
||||
ZoomFactor *= closer ? ZoomScaleAmount : 1 / ZoomScaleAmount;
|
||||
Point centerAfter = atMouse ? ScaledClientMousePosition : ScaledClientCenter;
|
||||
|
||||
Point delta = new Point(centerAfter.X - centerBefore.X, centerAfter.Y - centerBefore.Y);
|
||||
Pan(delta);
|
||||
|
||||
UpdateTitle();
|
||||
}
|
||||
|
||||
private void ZoomToFit()
|
||||
{
|
||||
ZoomFactor = Math.Min((float)ClientArea.Width/CanvasRectangle.Width, (float)ClientArea.Height/CanvasRectangle.Height);
|
||||
CenterCanvas();
|
||||
}
|
||||
|
||||
private Point ScaledClientCenter
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Point(
|
||||
(int)Math.Round(ClientArea.Width / 2f / ZoomFactor),
|
||||
(int)Math.Round(ClientArea.Height / 2f / ZoomFactor));
|
||||
}
|
||||
}
|
||||
|
||||
private void MonitorKey(int index)
|
||||
{
|
||||
if (index == 0)
|
||||
|
@ -727,7 +817,7 @@ private void UpdateCoordinates()
|
|||
|
||||
if (ShapeManager.IsPanning)
|
||||
{
|
||||
Pan(InputManager.MouseVelocity);
|
||||
Pan(ScaledClientMouseVelocity);
|
||||
UpdateCenterOffset();
|
||||
}
|
||||
|
||||
|
@ -758,17 +848,16 @@ protected override void OnPaint(PaintEventArgs e)
|
|||
|
||||
Graphics g = e.Graphics;
|
||||
|
||||
ZoomTransform(g);
|
||||
|
||||
if (IsEditorMode && !CanvasRectangle.Contains(ClientArea))
|
||||
{
|
||||
g.Clear(canvasBackgroundColor);
|
||||
g.DrawRectangleProper(canvasBorderPen, CanvasRectangle.Offset(1));
|
||||
}
|
||||
|
||||
g.CompositingMode = CompositingMode.SourceCopy;
|
||||
g.FillRectangle(backgroundBrush, CanvasRectangle);
|
||||
g.CompositingMode = CompositingMode.SourceOver;
|
||||
|
||||
Draw(g);
|
||||
DrawBackground(g);
|
||||
DrawShapes(g);
|
||||
|
||||
if (Options.ShowFPS && IsFullscreen)
|
||||
{
|
||||
|
@ -779,9 +868,22 @@ protected override void OnPaint(PaintEventArgs e)
|
|||
{
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
g.PixelOffsetMode = PixelOffsetMode.Default;
|
||||
g.InterpolationMode = InterpolationMode.Default;
|
||||
}
|
||||
|
||||
private void Draw(Graphics g)
|
||||
private void DrawBackground(Graphics g)
|
||||
{
|
||||
using (GraphicsQualityManager quality = new GraphicsQualityManager(g, GraphicsQualityManager.Quality.Low))
|
||||
{
|
||||
g.CompositingMode = CompositingMode.SourceCopy;
|
||||
g.DrawImage(backgroundBrush.Image, CanvasRectangle);
|
||||
g.CompositingMode = CompositingMode.SourceOver;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawShapes(Graphics g)
|
||||
{
|
||||
// Draw snap rectangles
|
||||
if (ShapeManager.IsCreating && ShapeManager.IsSnapResizing)
|
||||
|
@ -1040,7 +1142,10 @@ private void DrawTextAnimation(Graphics g, TextAnimation textAnimation, Rectangl
|
|||
using (Brush textBrush = new SolidBrush(Color.FromArgb((int)(textAnimation.Opacity * 255), textColor)))
|
||||
using (Brush textShadowBrush = new SolidBrush(Color.FromArgb((int)(textAnimation.Opacity * 255), textShadowColor)))
|
||||
{
|
||||
Matrix transform = g.Transform;
|
||||
ZoomTransform(g, true);
|
||||
DrawInfoText(g, textAnimation.Text, textRectangle, infoFontMedium, padding, backgroundBrush, outerBorderPen, innerBorderPen, textBrush, textShadowBrush);
|
||||
g.Transform = transform;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1077,7 +1182,7 @@ private string GetInfoText()
|
|||
{
|
||||
if (IsEditorMode)
|
||||
{
|
||||
Point canvasRelativePosition = new Point(InputManager.ClientMousePosition.X - CanvasRectangle.X, InputManager.ClientMousePosition.Y - CanvasRectangle.Y);
|
||||
Point canvasRelativePosition = new Point(ScaledClientMousePosition.X - CanvasRectangle.X, ScaledClientMousePosition.Y - CanvasRectangle.Y);
|
||||
return $"X: {canvasRelativePosition.X} Y: {canvasRelativePosition.Y}";
|
||||
}
|
||||
else if (Mode == RegionCaptureMode.ScreenColorPicker || Options.UseCustomInfoText)
|
||||
|
@ -1105,7 +1210,7 @@ private string GetInfoText()
|
|||
private void DrawCrosshair(Graphics g)
|
||||
{
|
||||
int offset = 5;
|
||||
Point mousePos = InputManager.ClientMousePosition;
|
||||
Point mousePos = ScaledClientMousePosition;
|
||||
Point left = new Point(mousePos.X - offset, mousePos.Y), left2 = new Point(0, mousePos.Y);
|
||||
Point right = new Point(mousePos.X + offset, mousePos.Y), right2 = new Point(ClientArea.Width - 1, mousePos.Y);
|
||||
Point top = new Point(mousePos.X, mousePos.Y - offset), top2 = new Point(mousePos.X, 0);
|
||||
|
@ -1138,8 +1243,6 @@ private void DrawCrosshair(Graphics g)
|
|||
|
||||
private void DrawCursorGraphics(Graphics g)
|
||||
{
|
||||
Point mousePos = InputManager.ClientMousePosition;
|
||||
Rectangle currentScreenRect0Based = CaptureHelpers.GetActiveScreenBounds0Based();
|
||||
int cursorOffsetX = 10, cursorOffsetY = 10, itemGap = 10, itemCount = 0;
|
||||
Size totalSize = Size.Empty;
|
||||
|
||||
|
@ -1151,7 +1254,7 @@ private void DrawCursorGraphics(Graphics g)
|
|||
if (itemCount > 0) totalSize.Height += itemGap;
|
||||
magnifierPosition = totalSize.Height;
|
||||
|
||||
magnifier = Magnifier(Canvas, mousePos, Options.MagnifierPixelCount, Options.MagnifierPixelCount, Options.MagnifierPixelSize);
|
||||
magnifier = Magnifier(Canvas, ScaledClientMousePosition, Options.MagnifierPixelCount, Options.MagnifierPixelCount, Options.MagnifierPixelSize);
|
||||
totalSize.Width = Math.Max(totalSize.Width, magnifier.Width);
|
||||
|
||||
totalSize.Height += magnifier.Height;
|
||||
|
@ -1178,6 +1281,8 @@ private void DrawCursorGraphics(Graphics g)
|
|||
//itemCount++;
|
||||
}
|
||||
|
||||
Point mousePos = InputManager.ClientMousePosition;
|
||||
Rectangle currentScreenRect0Based = CaptureHelpers.GetActiveScreenBounds0Based();
|
||||
int x = mousePos.X + cursorOffsetX;
|
||||
|
||||
if (x + totalSize.Width > currentScreenRect0Based.Right)
|
||||
|
@ -1192,8 +1297,10 @@ private void DrawCursorGraphics(Graphics g)
|
|||
y = mousePos.Y - cursorOffsetY - totalSize.Height;
|
||||
}
|
||||
|
||||
Matrix initialTranform = g.Transform;
|
||||
if (Options.ShowMagnifier)
|
||||
{
|
||||
ZoomTransform(g, true);
|
||||
if (Options.UseSquareMagnifier)
|
||||
{
|
||||
g.DrawImage(magnifier, x, y + magnifierPosition, magnifier.Width, magnifier.Height);
|
||||
|
@ -1212,6 +1319,7 @@ private void DrawCursorGraphics(Graphics g)
|
|||
g.DrawEllipse(Pens.Black, x, y + magnifierPosition, magnifier.Width - 1, magnifier.Height - 1);
|
||||
}
|
||||
}
|
||||
g.Transform = initialTranform;
|
||||
}
|
||||
|
||||
if (Options.ShowInfo)
|
||||
|
@ -1242,7 +1350,9 @@ private void DrawCursorGraphics(Graphics g)
|
|||
infoTextRect.Location = new Point(x + (totalSize.Width / 2) - (infoTextRect.Width / 2), y + infoTextPosition);
|
||||
Point padding = new Point(infoTextPadding, infoTextPadding);
|
||||
|
||||
ZoomTransform(g, true);
|
||||
DrawInfoText(g, infoText, infoTextRect, infoFont, padding);
|
||||
g.Transform = initialTranform;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2076,6 +2076,15 @@ internal static string ShapeManager_CreateToolbar_UploadImage {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Zoom to fit on open.
|
||||
/// </summary>
|
||||
internal static string ShapeManager_CreateToolbar_ZoomToFitOnOpen {
|
||||
get {
|
||||
return ResourceManager.GetString("ShapeManager_CreateToolbar_ZoomToFitOnOpen", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cursor type:.
|
||||
/// </summary>
|
||||
|
|
|
@ -379,6 +379,9 @@
|
|||
<data name="ShapeManager_CreateToolbar_EditorStartMode" xml:space="preserve">
|
||||
<value>Editor start mode:</value>
|
||||
</data>
|
||||
<data name="ShapeManager_CreateToolbar_ZoomToFitOnOpen" xml:space="preserve">
|
||||
<value>Zoom to fit on open</value>
|
||||
</data>
|
||||
<data name="layer_shade" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\layer-shade.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
|
|
|
@ -90,6 +90,7 @@ public class RegionCaptureOptions
|
|||
|
||||
// Image editor
|
||||
public ImageEditorStartMode ImageEditorStartMode = ImageEditorStartMode.AutoSize;
|
||||
public bool ZoomToFitOnOpen = false;
|
||||
public WindowState ImageEditorWindowState = new WindowState();
|
||||
public bool EditorAutoCopyImage = false;
|
||||
public bool AutoCloseEditorOnTask = false;
|
||||
|
|
|
@ -60,11 +60,13 @@ public void Update()
|
|||
|
||||
if (Orientation == Orientation.Horizontal)
|
||||
{
|
||||
isScrollbarNeeded = form.CanvasRectangle.Left < form.ClientArea.Left || form.CanvasRectangle.Right > form.ClientArea.Right;
|
||||
isScrollbarNeeded = form.CanvasRectangle.Left < form.ClientArea.Left
|
||||
|| (form.CanvasRectangle.Right * form.ZoomFactor) > form.ClientArea.Right;
|
||||
}
|
||||
else
|
||||
{
|
||||
isScrollbarNeeded = form.CanvasRectangle.Top < form.ClientArea.Top || form.CanvasRectangle.Bottom > form.ClientArea.Bottom;
|
||||
isScrollbarNeeded = form.CanvasRectangle.Top < form.ClientArea.Top
|
||||
|| (form.CanvasRectangle.Bottom * form.ZoomFactor) > form.ClientArea.Bottom;
|
||||
}
|
||||
|
||||
Visible = isScrollbarNeeded || IsDragging;
|
||||
|
@ -145,6 +147,8 @@ public override void OnDraw(Graphics g)
|
|||
using (Brush trackBrush = new SolidBrush(TrackColor))
|
||||
using (Brush thumbBrush = new SolidBrush(thumbColor))
|
||||
{
|
||||
var savedTransform = g.Transform;
|
||||
form.ZoomTransform(g, true);
|
||||
if (IsCapsule)
|
||||
{
|
||||
g.SmoothingMode = SmoothingMode.HighQuality;
|
||||
|
@ -161,6 +165,7 @@ public override void OnDraw(Graphics g)
|
|||
g.FillRectangle(trackBrush, Rectangle);
|
||||
g.FillRectangle(thumbBrush, ThumbRectangle);
|
||||
}
|
||||
g.Transform = savedTransform;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@ public virtual BaseShape Duplicate()
|
|||
|
||||
public virtual void OnCreating()
|
||||
{
|
||||
Point pos = InputManager.ClientMousePosition;
|
||||
Point pos = Manager.Form.ScaledClientMousePosition;
|
||||
|
||||
if (Options.IsFixedSize && ShapeCategory == ShapeCategory.Region)
|
||||
{
|
||||
|
@ -270,11 +270,11 @@ public virtual void OnUpdate()
|
|||
{
|
||||
if (Manager.IsCreating)
|
||||
{
|
||||
Point pos = InputManager.ClientMousePosition;
|
||||
Point pos = Manager.Form.ScaledClientMousePosition;
|
||||
|
||||
if (Manager.IsCornerMoving && !Manager.IsPanning)
|
||||
{
|
||||
StartPosition = StartPosition.Add(InputManager.MouseVelocity);
|
||||
StartPosition = StartPosition.Add(Manager.Form.ScaledClientMouseVelocity);
|
||||
}
|
||||
|
||||
if (Manager.IsProportionalResizing || ForceProportionalResizing)
|
||||
|
@ -303,7 +303,7 @@ public virtual void OnUpdate()
|
|||
}
|
||||
else if (Manager.IsMoving && !Manager.IsPanning)
|
||||
{
|
||||
Move(InputManager.MouseVelocity);
|
||||
Move(Manager.Form.ScaledClientMouseVelocity);
|
||||
}
|
||||
|
||||
if (LimitRectangleToInsideCanvas)
|
||||
|
@ -361,13 +361,13 @@ public virtual void OnNodeUpdate()
|
|||
|
||||
if (Manager.IsCornerMoving || Manager.IsPanning)
|
||||
{
|
||||
tempStartPos.Offset(InputManager.MouseVelocity);
|
||||
tempEndPos.Offset(InputManager.MouseVelocity);
|
||||
tempNodePos.Offset(InputManager.MouseVelocity);
|
||||
tempRectangle.LocationOffset(InputManager.MouseVelocity);
|
||||
tempStartPos.Offset(Manager.Form.ScaledClientMouseVelocity);
|
||||
tempEndPos.Offset(Manager.Form.ScaledClientMouseVelocity);
|
||||
tempNodePos.Offset(Manager.Form.ScaledClientMouseVelocity);
|
||||
tempRectangle.LocationOffset(Manager.Form.ScaledClientMouseVelocity);
|
||||
}
|
||||
|
||||
Point pos = InputManager.ClientMousePosition;
|
||||
Point pos = Manager.Form.ScaledClientMousePosition;
|
||||
Point startPos = tempStartPos;
|
||||
Point endPos = tempEndPos;
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ public override void ShowNodes()
|
|||
public override void OnCreating()
|
||||
{
|
||||
Manager.IsMoving = true;
|
||||
UpdateCursor(Manager.GetSelectedCursor().Handle, InputManager.ClientMousePosition);
|
||||
UpdateCursor(Manager.GetSelectedCursor().Handle, Manager.Form.ScaledClientMousePosition);
|
||||
OnCreated();
|
||||
}
|
||||
|
||||
|
|
|
@ -73,11 +73,11 @@ public override void OnUpdate()
|
|||
{
|
||||
if (Manager.IsCornerMoving && !Manager.IsPanning)
|
||||
{
|
||||
Move(InputManager.MouseVelocity);
|
||||
Move(Manager.Form.ScaledClientMouseVelocity);
|
||||
}
|
||||
else
|
||||
{
|
||||
Point pos = InputManager.ClientMousePosition;
|
||||
Point pos = Manager.Form.ScaledClientMousePosition;
|
||||
|
||||
if (positions.Count == 0 || (!Manager.IsProportionalResizing && LastPosition != pos))
|
||||
{
|
||||
|
@ -101,7 +101,7 @@ public override void OnUpdate()
|
|||
}
|
||||
else if (Manager.IsMoving)
|
||||
{
|
||||
Move(InputManager.MouseVelocity);
|
||||
Move(Manager.Form.ScaledClientMouseVelocity);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ public class ImageFileDrawingShape : ImageDrawingShape
|
|||
{
|
||||
public override void OnCreating()
|
||||
{
|
||||
Point pos = InputManager.ClientMousePosition;
|
||||
Point pos = Manager.Form.ScaledClientMousePosition;
|
||||
Rectangle = new Rectangle(pos.X, pos.Y, 1, 1);
|
||||
|
||||
if (Manager.IsCtrlModifier && LoadImageFile(AnnotationOptions.LastImageFilePath, true))
|
||||
|
|
|
@ -236,7 +236,7 @@ public override void OnNodeUpdate()
|
|||
CenterNodeActive = true;
|
||||
}
|
||||
|
||||
Points[i] = InputManager.ClientMousePosition;
|
||||
Points[i] = Manager.Form.ScaledClientMousePosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ public override void OnNodeUpdate()
|
|||
|
||||
if (TailNode.IsDragging)
|
||||
{
|
||||
TailPosition = InputManager.ClientMousePosition;
|
||||
TailPosition = Manager.Form.ScaledClientMousePosition;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ public StepDrawingShape()
|
|||
public override void OnCreating()
|
||||
{
|
||||
Manager.IsMoving = true;
|
||||
Point pos = InputManager.ClientMousePosition;
|
||||
Point pos = Manager.Form.ScaledClientMousePosition;
|
||||
Rectangle = new Rectangle(new Point(pos.X - (Rectangle.Width / 2), pos.Y - (Rectangle.Height / 2)), Rectangle.Size);
|
||||
int tailOffset = 5;
|
||||
TailPosition = Rectangle.Location.Add(Rectangle.Width + tailOffset, Rectangle.Height + tailOffset);
|
||||
|
@ -94,7 +94,7 @@ public override void OnNodeUpdate()
|
|||
if (TailNode.IsDragging)
|
||||
{
|
||||
IsTailActive = true;
|
||||
TailPosition = InputManager.ClientMousePosition;
|
||||
TailPosition = Manager.Form.ScaledClientMousePosition;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ public override void ShowNodes()
|
|||
|
||||
public override void OnCreating()
|
||||
{
|
||||
Point pos = InputManager.ClientMousePosition;
|
||||
Point pos = Manager.Form.ScaledClientMousePosition;
|
||||
Rectangle = new Rectangle(pos.X, pos.Y, 1, 1);
|
||||
|
||||
if (Manager.IsCtrlModifier && LoadSticker(AnnotationOptions.LastStickerPath, AnnotationOptions.StickerSize))
|
||||
|
|
|
@ -100,7 +100,7 @@ protected void DrawText(Graphics g, string text, Color textColor, TextDrawingOpt
|
|||
|
||||
public override void OnCreating()
|
||||
{
|
||||
Point pos = InputManager.ClientMousePosition;
|
||||
Point pos = Manager.Form.ScaledClientMousePosition;
|
||||
Rectangle = new Rectangle(pos.X, pos.Y, 1, 1);
|
||||
|
||||
if (ShowTextInputBox())
|
||||
|
|
|
@ -68,11 +68,11 @@ public override void OnUpdate()
|
|||
{
|
||||
if (Manager.IsCornerMoving)
|
||||
{
|
||||
Move(InputManager.MouseVelocity);
|
||||
Move(Manager.Form.ScaledClientMouseVelocity);
|
||||
}
|
||||
else
|
||||
{
|
||||
Point pos = InputManager.ClientMousePosition;
|
||||
Point pos = Manager.Form.ScaledClientMousePosition;
|
||||
|
||||
if (points.Count == 0 || (!Manager.IsProportionalResizing && LastPosition != pos))
|
||||
{
|
||||
|
@ -96,7 +96,7 @@ public override void OnUpdate()
|
|||
}
|
||||
else if (Manager.IsMoving)
|
||||
{
|
||||
Move(InputManager.MouseVelocity);
|
||||
Move(Manager.Form.ScaledClientMouseVelocity);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -501,6 +501,10 @@ private void form_MouseDoubleClick(object sender, MouseEventArgs e)
|
|||
|
||||
private void form_MouseWheel(object sender, MouseEventArgs e)
|
||||
{
|
||||
if ((Control.ModifierKeys & Keys.Control) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (e.Delta > 0)
|
||||
{
|
||||
if (Options.ShowMagnifier)
|
||||
|
@ -1035,12 +1039,8 @@ private void EndPanning()
|
|||
IsPanning = false;
|
||||
}
|
||||
|
||||
internal void UpdateObjects()
|
||||
internal void UpdateObjects(ImageEditorControl[] objects, Point mousePosition)
|
||||
{
|
||||
ImageEditorControl[] objects = DrawableObjects.OrderByDescending(x => x.Order).ToArray();
|
||||
|
||||
Point position = InputManager.ClientMousePosition;
|
||||
|
||||
if (objects.All(x => !x.IsDragging))
|
||||
{
|
||||
for (int i = 0; i < objects.Length; i++)
|
||||
|
@ -1049,13 +1049,13 @@ internal void UpdateObjects()
|
|||
|
||||
if (obj.Visible)
|
||||
{
|
||||
obj.IsCursorHover = obj.Rectangle.Contains(position);
|
||||
obj.IsCursorHover = obj.Rectangle.Contains(mousePosition);
|
||||
|
||||
if (obj.IsCursorHover)
|
||||
{
|
||||
if (InputManager.IsMousePressed(MouseButtons.Left))
|
||||
{
|
||||
obj.OnMouseDown(position);
|
||||
obj.OnMouseDown(mousePosition);
|
||||
}
|
||||
|
||||
for (int j = i + 1; j < objects.Length; j++)
|
||||
|
@ -1080,13 +1080,21 @@ internal void UpdateObjects()
|
|||
{
|
||||
if (obj.IsDragging)
|
||||
{
|
||||
obj.OnMouseUp(position);
|
||||
obj.OnMouseUp(mousePosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateObjects()
|
||||
{
|
||||
ImageEditorControl[] scrollbars = DrawableObjects.Where(x => x is ImageEditorScrollbar).ToArray();
|
||||
ImageEditorControl[] shapes = DrawableObjects.Except(scrollbars).OrderByDescending(x => x.Order).ToArray();
|
||||
UpdateObjects(shapes, Form.ScaledClientMousePosition);
|
||||
UpdateObjects(scrollbars, InputManager.ClientMousePosition);
|
||||
}
|
||||
|
||||
internal void DrawObjects(Graphics g)
|
||||
{
|
||||
foreach (ImageEditorControl obj in DrawableObjects)
|
||||
|
@ -1288,7 +1296,7 @@ private BaseShape CheckHover()
|
|||
|
||||
if (Options.IsFixedSize && IsCurrentShapeTypeRegion)
|
||||
{
|
||||
Point location = InputManager.ClientMousePosition;
|
||||
Point location = Form.ScaledClientMousePosition;
|
||||
|
||||
BaseShape rectangleRegionShape = CreateShape(ShapeType.RegionRectangle);
|
||||
rectangleRegionShape.Rectangle = new Rectangle(new Point(location.X - (Options.FixedSize.Width / 2),
|
||||
|
@ -1484,7 +1492,7 @@ private void ClearTools()
|
|||
|
||||
public BaseShape GetIntersectShape()
|
||||
{
|
||||
return GetIntersectShape(InputManager.ClientMousePosition);
|
||||
return GetIntersectShape(Form.ScaledClientMousePosition);
|
||||
}
|
||||
|
||||
public BaseShape GetIntersectShape(Point position)
|
||||
|
@ -1680,7 +1688,7 @@ private void DuplicateCurrrentShape(bool insertMousePosition)
|
|||
{
|
||||
if (insertMousePosition)
|
||||
{
|
||||
shapeCopy.MoveAbsolute(InputManager.ClientMousePosition, true);
|
||||
shapeCopy.MoveAbsolute(Form.ScaledClientMousePosition, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1726,7 +1734,7 @@ private void PasteFromClipboard(bool insertMousePosition)
|
|||
|
||||
if (insertMousePosition)
|
||||
{
|
||||
pos = InputManager.ClientMousePosition;
|
||||
pos = Form.ScaledClientMousePosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1821,7 +1829,7 @@ public Color GetColor(Bitmap bmp, Point pos)
|
|||
|
||||
public Color GetCurrentColor(Bitmap bmp)
|
||||
{
|
||||
return GetColor(bmp, InputManager.ClientMousePosition);
|
||||
return GetColor(bmp, Form.ScaledClientMousePosition);
|
||||
}
|
||||
|
||||
public Color GetCurrentColor()
|
||||
|
|
|
@ -885,6 +885,12 @@ internal void CreateToolbar()
|
|||
(sender, e) => Options.ImageEditorStartMode = (ImageEditorStartMode)tscbImageEditorStartMode.Content.SelectedIndex;
|
||||
tsddbOptions.DropDownItems.Add(tscbImageEditorStartMode);
|
||||
|
||||
ToolStripMenuItem tsmiZoomToFitOnOpen = new ToolStripMenuItem(Resources.ShapeManager_CreateToolbar_ZoomToFitOnOpen);
|
||||
tsmiZoomToFitOnOpen.Checked = Options.ZoomToFitOnOpen;
|
||||
tsmiZoomToFitOnOpen.CheckOnClick = true;
|
||||
tsmiZoomToFitOnOpen.Click += (sender, e) => Options.ZoomToFitOnOpen = tsmiZoomToFitOnOpen.Checked;
|
||||
tsddbOptions.DropDownItems.Add(tsmiZoomToFitOnOpen);
|
||||
|
||||
ToolStripMenuItem tsmiEditorAutoCopyImage = new ToolStripMenuItem(Resources.AutoCopyImageToClipboard);
|
||||
tsmiEditorAutoCopyImage.Checked = Options.EditorAutoCopyImage;
|
||||
tsmiEditorAutoCopyImage.CheckOnClick = true;
|
||||
|
|
Loading…
Reference in a new issue