mirror of
https://github.com/greenshot/greenshot
synced 2025-08-19 13:10:00 -07:00
Trying to replace the Gripper (which is a Label/Control) with adorners (custom code). This should prevent the slow cleanup, reduce resources and speedup the editor. Also we should have better "UI" feedback. This is still very experimental.
This commit is contained in:
parent
e9ab99c5ac
commit
31db071394
15 changed files with 643 additions and 349 deletions
232
Greenshot/Drawing/Adorners/GripperAdorner.cs
Normal file
232
Greenshot/Drawing/Adorners/GripperAdorner.cs
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
/*
|
||||||
|
* Greenshot - a free and open source screenshot tool
|
||||||
|
* Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
|
||||||
|
*
|
||||||
|
* For more information see: http://getgreenshot.org/
|
||||||
|
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation, either version 1 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Greenshot.Helpers;
|
||||||
|
using Greenshot.Plugin;
|
||||||
|
using Greenshot.Plugin.Drawing;
|
||||||
|
using Greenshot.Plugin.Drawing.Adorners;
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
|
||||||
|
namespace Greenshot.Drawing.Adorners
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This is the default "legacy" gripper adorner, not the one used for the tail in the speech-bubble
|
||||||
|
/// </summary>
|
||||||
|
public class GripperAdorner : IAdorner
|
||||||
|
{
|
||||||
|
private Rectangle _boundsBeforeResize = Rectangle.Empty;
|
||||||
|
private RectangleF _boundsAfterResize = RectangleF.Empty;
|
||||||
|
private EditStatus _editStatus;
|
||||||
|
|
||||||
|
public Positions Position { get; private set; }
|
||||||
|
|
||||||
|
public GripperAdorner(IDrawableContainer owner, Positions position)
|
||||||
|
{
|
||||||
|
Owner = owner;
|
||||||
|
Position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the cursor for when the mouse is over the adorner
|
||||||
|
/// </summary>
|
||||||
|
public Cursor Cursor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
bool horizontalSwitched = Owner.Width < 0;
|
||||||
|
switch (Position)
|
||||||
|
{
|
||||||
|
case Positions.TopLeft:
|
||||||
|
case Positions.BottomRight:
|
||||||
|
return horizontalSwitched ? Cursors.SizeNWSE : Cursors.SizeNESW;
|
||||||
|
case Positions.TopRight:
|
||||||
|
case Positions.BottomLeft:
|
||||||
|
return horizontalSwitched ? Cursors.SizeNESW : Cursors.SizeNWSE;
|
||||||
|
case Positions.MiddleLeft:
|
||||||
|
case Positions.MiddleRight:
|
||||||
|
return Cursors.SizeWE;
|
||||||
|
case Positions.TopCenter:
|
||||||
|
case Positions.BottomCenter:
|
||||||
|
return Cursors.SizeNS;
|
||||||
|
default:
|
||||||
|
return Cursors.SizeAll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDrawableContainer Owner
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test if the point is inside the adorner
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="point"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool HitTest(Point point)
|
||||||
|
{
|
||||||
|
return Bounds.Contains(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle the mouse down
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="mouseEventArgs"></param>
|
||||||
|
public void MouseDown(object sender, MouseEventArgs mouseEventArgs)
|
||||||
|
{
|
||||||
|
_editStatus = EditStatus.RESIZING;
|
||||||
|
_boundsBeforeResize = new Rectangle(Owner.Left, Owner.Top, Owner.Width, Owner.Height);
|
||||||
|
_boundsAfterResize = _boundsBeforeResize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle the mouse move
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="mouseEventArgs"></param>
|
||||||
|
public void MouseMove(object sender, MouseEventArgs mouseEventArgs)
|
||||||
|
{
|
||||||
|
Owner.Invalidate();
|
||||||
|
int absX = Owner.Left + mouseEventArgs.X;
|
||||||
|
int absY = Owner.Top + mouseEventArgs.Y;
|
||||||
|
|
||||||
|
if (_editStatus.Equals(EditStatus.RESIZING))
|
||||||
|
{
|
||||||
|
Owner.MakeBoundsChangeUndoable(false);
|
||||||
|
|
||||||
|
//SuspendLayout();
|
||||||
|
|
||||||
|
// reset "workbench" rectangle to current bounds
|
||||||
|
_boundsAfterResize.X = _boundsBeforeResize.X;
|
||||||
|
_boundsAfterResize.Y = _boundsBeforeResize.Y;
|
||||||
|
_boundsAfterResize.Width = _boundsBeforeResize.Width;
|
||||||
|
_boundsAfterResize.Height = _boundsBeforeResize.Height;
|
||||||
|
|
||||||
|
// calculate scaled rectangle
|
||||||
|
ScaleHelper.Scale(ref _boundsAfterResize, Position, new PointF(absX, absY), ScaleHelper.GetScaleOptions());
|
||||||
|
|
||||||
|
// apply scaled bounds to this DrawableContainer
|
||||||
|
Owner.ApplyBounds(_boundsAfterResize);
|
||||||
|
|
||||||
|
//ResumeLayout();
|
||||||
|
Owner.DoLayout();
|
||||||
|
}
|
||||||
|
Owner.Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle the mouse up
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="mouseEventArgs"></param>
|
||||||
|
public void MouseUp(object sender, MouseEventArgs mouseEventArgs)
|
||||||
|
{
|
||||||
|
_editStatus = EditStatus.IDLE;
|
||||||
|
Owner.Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the location of the adorner
|
||||||
|
/// </summary>
|
||||||
|
public Point Location {
|
||||||
|
get
|
||||||
|
{
|
||||||
|
int x = 0,y = 0;
|
||||||
|
switch (Position)
|
||||||
|
{
|
||||||
|
case Positions.TopLeft:
|
||||||
|
x = Owner.Left;
|
||||||
|
y = Owner.Top;
|
||||||
|
break;
|
||||||
|
case Positions.BottomLeft:
|
||||||
|
x = Owner.Left;
|
||||||
|
y = Owner.Top + Owner.Height;
|
||||||
|
break;
|
||||||
|
case Positions.MiddleLeft:
|
||||||
|
x = Owner.Left;
|
||||||
|
y = Owner.Top + (Owner.Height / 2);
|
||||||
|
break;
|
||||||
|
case Positions.TopCenter:
|
||||||
|
x = Owner.Left + (Owner.Width / 2);
|
||||||
|
y = Owner.Top;
|
||||||
|
break;
|
||||||
|
case Positions.BottomCenter:
|
||||||
|
x = Owner.Left + (Owner.Width / 2);
|
||||||
|
y = Owner.Top + Owner.Height;
|
||||||
|
break;
|
||||||
|
case Positions.TopRight:
|
||||||
|
x = Owner.Left + Owner.Width;
|
||||||
|
y = Owner.Top;
|
||||||
|
break;
|
||||||
|
case Positions.BottomRight:
|
||||||
|
x = Owner.Left + Owner.Width;
|
||||||
|
y = Owner.Top + Owner.Height;
|
||||||
|
break;
|
||||||
|
case Positions.MiddleRight:
|
||||||
|
x = Owner.Left + Owner.Width;
|
||||||
|
y = Owner.Top + (Owner.Height / 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return new Point(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the bounds of the Adorner
|
||||||
|
/// </summary>
|
||||||
|
public Rectangle Bounds
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Point location = Location;
|
||||||
|
Size size = new Size(10, 10);
|
||||||
|
return new Rectangle(location.X - (size.Width / 2), location.Y - (size.Height / 2), size.Width, size.Height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draw the adorner
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="paintEventArgs">PaintEventArgs</param>
|
||||||
|
public void Paint(PaintEventArgs paintEventArgs)
|
||||||
|
{
|
||||||
|
Graphics targetGraphics = paintEventArgs.Graphics;
|
||||||
|
Rectangle clipRectangle = paintEventArgs.ClipRectangle;
|
||||||
|
|
||||||
|
var bounds = Bounds;
|
||||||
|
targetGraphics.DrawRectangle(Pens.Black, bounds.X, bounds.Y, bounds.Width , bounds.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// We ignore the Transform, as the coordinates are directly bound to those of the owner
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="matrix"></param>
|
||||||
|
public void Transform(Matrix matrix)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
177
Greenshot/Drawing/Adorners/TargetAdorner.cs
Normal file
177
Greenshot/Drawing/Adorners/TargetAdorner.cs
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
/*
|
||||||
|
* Greenshot - a free and open source screenshot tool
|
||||||
|
* Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
|
||||||
|
*
|
||||||
|
* For more information see: http://getgreenshot.org/
|
||||||
|
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation, either version 1 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Greenshot.Plugin.Drawing;
|
||||||
|
using Greenshot.Plugin.Drawing.Adorners;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace Greenshot.Drawing.Adorners
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This implements the special "gripper" for the Speech-Bubble tail
|
||||||
|
/// </summary>
|
||||||
|
public class TargetAdorner : IAdorner
|
||||||
|
{
|
||||||
|
private EditStatus _editStatus;
|
||||||
|
|
||||||
|
public TargetAdorner(IDrawableContainer owner, Point location)
|
||||||
|
{
|
||||||
|
Owner = owner;
|
||||||
|
Location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the cursor for when the mouse is over the adorner
|
||||||
|
/// </summary>
|
||||||
|
public Cursor Cursor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Cursors.SizeAll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDrawableContainer Owner
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test if the point is inside the adorner
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="point"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool HitTest(Point point)
|
||||||
|
{
|
||||||
|
return Bounds.Contains(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle the mouse down
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="mouseEventArgs"></param>
|
||||||
|
public void MouseDown(object sender, MouseEventArgs mouseEventArgs)
|
||||||
|
{
|
||||||
|
_editStatus = EditStatus.MOVING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle the mouse move
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="mouseEventArgs"></param>
|
||||||
|
public void MouseMove(object sender, MouseEventArgs mouseEventArgs)
|
||||||
|
{
|
||||||
|
Owner.Invalidate();
|
||||||
|
Point newGripperLocation = new Point(mouseEventArgs.X, mouseEventArgs.Y);
|
||||||
|
Rectangle surfaceBounds = new Rectangle(0, 0, Owner.Parent.Width, Owner.Parent.Height);
|
||||||
|
// Check if gripper inside the parent (surface), if not we need to move it inside
|
||||||
|
// This was made for BUG-1682
|
||||||
|
if (!surfaceBounds.Contains(newGripperLocation))
|
||||||
|
{
|
||||||
|
if (newGripperLocation.X > surfaceBounds.Right)
|
||||||
|
{
|
||||||
|
newGripperLocation.X = surfaceBounds.Right - 5;
|
||||||
|
}
|
||||||
|
if (newGripperLocation.X < surfaceBounds.Left)
|
||||||
|
{
|
||||||
|
newGripperLocation.X = surfaceBounds.Left;
|
||||||
|
}
|
||||||
|
if (newGripperLocation.Y > surfaceBounds.Bottom)
|
||||||
|
{
|
||||||
|
newGripperLocation.Y = surfaceBounds.Bottom - 5;
|
||||||
|
}
|
||||||
|
if (newGripperLocation.Y < surfaceBounds.Top)
|
||||||
|
{
|
||||||
|
newGripperLocation.Y = surfaceBounds.Top;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Location = newGripperLocation;
|
||||||
|
Owner.Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle the mouse up
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="mouseEventArgs"></param>
|
||||||
|
public void MouseUp(object sender, MouseEventArgs mouseEventArgs)
|
||||||
|
{
|
||||||
|
_editStatus = EditStatus.IDLE;
|
||||||
|
Owner.Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the location of the adorner
|
||||||
|
/// </summary>
|
||||||
|
public Point Location
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the bounds of the Adorner
|
||||||
|
/// </summary>
|
||||||
|
public Rectangle Bounds
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Point location = Location;
|
||||||
|
Size size = new Size(10, 10);
|
||||||
|
return new Rectangle(location.X - (size.Width / 2), location.Y - (size.Height / 2), size.Width, size.Height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draw the adorner
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="paintEventArgs">PaintEventArgs</param>
|
||||||
|
public void Paint(PaintEventArgs paintEventArgs)
|
||||||
|
{
|
||||||
|
Graphics targetGraphics = paintEventArgs.Graphics;
|
||||||
|
Rectangle clipRectangle = paintEventArgs.ClipRectangle;
|
||||||
|
|
||||||
|
var bounds = Bounds;
|
||||||
|
targetGraphics.DrawRectangle(Pens.Green, bounds.X, bounds.Y, bounds.Width, bounds.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Made sure this adorner is transformed
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="matrix">Matrix</param>
|
||||||
|
public void Transform(Matrix matrix)
|
||||||
|
{
|
||||||
|
if (matrix == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Point[] points = new[] { Location };
|
||||||
|
matrix.TransformPoints(points);
|
||||||
|
Location = points[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Greenshot.Configuration;
|
using Greenshot.Configuration;
|
||||||
|
using Greenshot.Drawing.Adorners;
|
||||||
using Greenshot.Drawing.Fields;
|
using Greenshot.Drawing.Fields;
|
||||||
using Greenshot.Drawing.Filters;
|
using Greenshot.Drawing.Filters;
|
||||||
using Greenshot.Helpers;
|
using Greenshot.Helpers;
|
||||||
|
@ -27,6 +28,7 @@ using Greenshot.IniFile;
|
||||||
using Greenshot.Memento;
|
using Greenshot.Memento;
|
||||||
using Greenshot.Plugin;
|
using Greenshot.Plugin;
|
||||||
using Greenshot.Plugin.Drawing;
|
using Greenshot.Plugin.Drawing;
|
||||||
|
using Greenshot.Plugin.Drawing.Adorners;
|
||||||
using log4net;
|
using log4net;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -35,7 +37,8 @@ using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace Greenshot.Drawing {
|
namespace Greenshot.Drawing
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// represents a rectangle, ellipse, label or whatever. Can contain filters, too.
|
/// represents a rectangle, ellipse, label or whatever. Can contain filters, too.
|
||||||
/// serializable for clipboard support
|
/// serializable for clipboard support
|
||||||
|
@ -73,16 +76,6 @@ namespace Greenshot.Drawing {
|
||||||
if (!disposing) {
|
if (!disposing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_grippers != null) {
|
|
||||||
for (int i = 0; i < _grippers.Length; i++) {
|
|
||||||
if (_grippers[i] == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_grippers[i].Dispose();
|
|
||||||
_grippers[i] = null;
|
|
||||||
}
|
|
||||||
_grippers = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
FieldAggregator aggProps = _parent.FieldAggregator;
|
FieldAggregator aggProps = _parent.FieldAggregator;
|
||||||
aggProps.UnbindElement(this);
|
aggProps.UnbindElement(this);
|
||||||
|
@ -117,14 +110,13 @@ namespace Greenshot.Drawing {
|
||||||
get { return _parent; }
|
get { return _parent; }
|
||||||
set { SwitchParent((Surface)value); }
|
set { SwitchParent((Surface)value); }
|
||||||
}
|
}
|
||||||
[NonSerialized]
|
|
||||||
protected Gripper[] _grippers;
|
|
||||||
private bool layoutSuspended;
|
private bool layoutSuspended;
|
||||||
|
|
||||||
[NonSerialized]
|
[NonSerialized]
|
||||||
private Gripper _targetGripper;
|
private TargetAdorner _targetGripper;
|
||||||
|
|
||||||
public Gripper TargetGripper {
|
public TargetAdorner TargetGripper {
|
||||||
get {
|
get {
|
||||||
return _targetGripper;
|
return _targetGripper;
|
||||||
}
|
}
|
||||||
|
@ -220,6 +212,11 @@ namespace Greenshot.Drawing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of available Adorners
|
||||||
|
/// </summary>
|
||||||
|
public IList<IAdorner> Adorners { get; } = new List<IAdorner>();
|
||||||
|
|
||||||
[NonSerialized]
|
[NonSerialized]
|
||||||
// will store current bounds of this DrawableContainer before starting a resize
|
// will store current bounds of this DrawableContainer before starting a resize
|
||||||
protected Rectangle _boundsBeforeResize = Rectangle.Empty;
|
protected Rectangle _boundsBeforeResize = Rectangle.Empty;
|
||||||
|
@ -329,73 +326,23 @@ namespace Greenshot.Drawing {
|
||||||
DoLayout();
|
DoLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Move the TargetGripper around, confined to the surface to solve BUG-1682
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="newX"></param>
|
|
||||||
/// <param name="newY"></param>
|
|
||||||
protected virtual void TargetGripperMove(int newX, int newY) {
|
|
||||||
Point newGripperLocation = new Point(newX, newY);
|
|
||||||
Rectangle surfaceBounds = new Rectangle(0, 0, _parent.Width, _parent.Height);
|
|
||||||
// Check if gripper inside the parent (surface), if not we need to move it inside
|
|
||||||
// This was made for BUG-1682
|
|
||||||
if (!surfaceBounds.Contains(newGripperLocation)) {
|
|
||||||
if (newGripperLocation.X > surfaceBounds.Right) {
|
|
||||||
newGripperLocation.X = surfaceBounds.Right - 5;
|
|
||||||
}
|
|
||||||
if (newGripperLocation.X < surfaceBounds.Left) {
|
|
||||||
newGripperLocation.X = surfaceBounds.Left;
|
|
||||||
}
|
|
||||||
if (newGripperLocation.Y > surfaceBounds.Bottom) {
|
|
||||||
newGripperLocation.Y = surfaceBounds.Bottom - 5;
|
|
||||||
}
|
|
||||||
if (newGripperLocation.Y < surfaceBounds.Top) {
|
|
||||||
newGripperLocation.Y = surfaceBounds.Top;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_targetGripper.Left = newGripperLocation.X;
|
|
||||||
_targetGripper.Top = newGripperLocation.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initialize a target gripper
|
/// Initialize a target gripper
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected void InitTargetGripper(Color gripperColor, Point location) {
|
protected void InitTargetGripper(Color gripperColor, Point location) {
|
||||||
_targetGripper = new Gripper {
|
_targetGripper = new TargetAdorner(this, location);
|
||||||
Cursor = Cursors.SizeAll,
|
|
||||||
BackColor = gripperColor,
|
|
||||||
Visible = false,
|
|
||||||
Parent = _parent,
|
|
||||||
Location = location
|
|
||||||
};
|
|
||||||
_targetGripper.MouseDown += GripperMouseDown;
|
|
||||||
_targetGripper.MouseUp += GripperMouseUp;
|
|
||||||
_targetGripper.MouseMove += GripperMouseMove;
|
|
||||||
if (_parent != null) {
|
|
||||||
_parent.Controls.Add(_targetGripper); // otherwise we'll attach them in switchParent
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void InitGrippers() {
|
protected void InitGrippers() {
|
||||||
|
// Create the GripperAdorners
|
||||||
_grippers = new Gripper[8];
|
Adorners.Add(new GripperAdorner(this, Positions.TopLeft));
|
||||||
for(int i=0; i<_grippers.Length; i++) {
|
Adorners.Add(new GripperAdorner(this, Positions.TopCenter));
|
||||||
_grippers[i] = new Gripper();
|
Adorners.Add(new GripperAdorner(this, Positions.TopRight));
|
||||||
_grippers[i].Position = i;
|
Adorners.Add(new GripperAdorner(this, Positions.BottomLeft));
|
||||||
_grippers[i].MouseDown += GripperMouseDown;
|
Adorners.Add(new GripperAdorner(this, Positions.BottomCenter));
|
||||||
_grippers[i].MouseUp += GripperMouseUp;
|
Adorners.Add(new GripperAdorner(this, Positions.BottomRight));
|
||||||
_grippers[i].MouseMove += GripperMouseMove;
|
Adorners.Add(new GripperAdorner(this, Positions.MiddleLeft));
|
||||||
_grippers[i].Visible = false;
|
Adorners.Add(new GripperAdorner(this, Positions.MiddleRight));
|
||||||
_grippers[i].Parent = _parent;
|
|
||||||
}
|
|
||||||
_grippers[Gripper.POSITION_TOP_CENTER].Cursor = Cursors.SizeNS;
|
|
||||||
_grippers[Gripper.POSITION_MIDDLE_RIGHT].Cursor = Cursors.SizeWE;
|
|
||||||
_grippers[Gripper.POSITION_BOTTOM_CENTER].Cursor = Cursors.SizeNS;
|
|
||||||
_grippers[Gripper.POSITION_MIDDLE_LEFT].Cursor = Cursors.SizeWE;
|
|
||||||
if (_parent != null) {
|
|
||||||
_parent.Controls.AddRange(_grippers); // otherwise we'll attach them in switchParent
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SuspendLayout() {
|
public void SuspendLayout() {
|
||||||
|
@ -407,101 +354,8 @@ namespace Greenshot.Drawing {
|
||||||
DoLayout();
|
DoLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void DoLayout() {
|
public virtual void DoLayout() {
|
||||||
if (_grippers == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!layoutSuspended) {
|
|
||||||
int[] xChoords = {Left-2,Left+Width/2-2,Left+Width-2};
|
|
||||||
int[] yChoords = {Top-2,Top+Height/2-2,Top+Height-2};
|
|
||||||
|
|
||||||
_grippers[Gripper.POSITION_TOP_LEFT].Left = xChoords[0]; _grippers[Gripper.POSITION_TOP_LEFT].Top = yChoords[0];
|
|
||||||
_grippers[Gripper.POSITION_TOP_CENTER].Left = xChoords[1]; _grippers[Gripper.POSITION_TOP_CENTER].Top = yChoords[0];
|
|
||||||
_grippers[Gripper.POSITION_TOP_RIGHT].Left = xChoords[2]; _grippers[Gripper.POSITION_TOP_RIGHT].Top = yChoords[0];
|
|
||||||
_grippers[Gripper.POSITION_MIDDLE_RIGHT].Left = xChoords[2]; _grippers[Gripper.POSITION_MIDDLE_RIGHT].Top = yChoords[1];
|
|
||||||
_grippers[Gripper.POSITION_BOTTOM_RIGHT].Left = xChoords[2]; _grippers[Gripper.POSITION_BOTTOM_RIGHT].Top = yChoords[2];
|
|
||||||
_grippers[Gripper.POSITION_BOTTOM_CENTER].Left = xChoords[1]; _grippers[Gripper.POSITION_BOTTOM_CENTER].Top = yChoords[2];
|
|
||||||
_grippers[Gripper.POSITION_BOTTOM_LEFT].Left = xChoords[0]; _grippers[Gripper.POSITION_BOTTOM_LEFT].Top = yChoords[2];
|
|
||||||
_grippers[Gripper.POSITION_MIDDLE_LEFT].Left = xChoords[0]; _grippers[Gripper.POSITION_MIDDLE_LEFT].Top = yChoords[1];
|
|
||||||
|
|
||||||
if((_grippers[Gripper.POSITION_TOP_LEFT].Left < _grippers[Gripper.POSITION_BOTTOM_RIGHT].Left && _grippers[Gripper.POSITION_TOP_LEFT].Top < _grippers[Gripper.POSITION_BOTTOM_RIGHT].Top) ||
|
|
||||||
_grippers[Gripper.POSITION_TOP_LEFT].Left > _grippers[Gripper.POSITION_BOTTOM_RIGHT].Left && _grippers[Gripper.POSITION_TOP_LEFT].Top > _grippers[Gripper.POSITION_BOTTOM_RIGHT].Top) {
|
|
||||||
_grippers[Gripper.POSITION_TOP_LEFT].Cursor = Cursors.SizeNWSE;
|
|
||||||
_grippers[Gripper.POSITION_TOP_RIGHT].Cursor = Cursors.SizeNESW;
|
|
||||||
_grippers[Gripper.POSITION_BOTTOM_RIGHT].Cursor = Cursors.SizeNWSE;
|
|
||||||
_grippers[Gripper.POSITION_BOTTOM_LEFT].Cursor = Cursors.SizeNESW;
|
|
||||||
} else if((_grippers[Gripper.POSITION_TOP_LEFT].Left > _grippers[Gripper.POSITION_BOTTOM_RIGHT].Left && _grippers[Gripper.POSITION_TOP_LEFT].Top < _grippers[Gripper.POSITION_BOTTOM_RIGHT].Top) ||
|
|
||||||
_grippers[Gripper.POSITION_TOP_LEFT].Left < _grippers[Gripper.POSITION_BOTTOM_RIGHT].Left && _grippers[Gripper.POSITION_TOP_LEFT].Top > _grippers[Gripper.POSITION_BOTTOM_RIGHT].Top) {
|
|
||||||
_grippers[Gripper.POSITION_TOP_LEFT].Cursor = Cursors.SizeNESW;
|
|
||||||
_grippers[Gripper.POSITION_TOP_RIGHT].Cursor = Cursors.SizeNWSE;
|
|
||||||
_grippers[Gripper.POSITION_BOTTOM_RIGHT].Cursor = Cursors.SizeNESW;
|
|
||||||
_grippers[Gripper.POSITION_BOTTOM_LEFT].Cursor = Cursors.SizeNWSE;
|
|
||||||
} else if (_grippers[Gripper.POSITION_TOP_LEFT].Left == _grippers[Gripper.POSITION_BOTTOM_RIGHT].Left) {
|
|
||||||
_grippers[Gripper.POSITION_TOP_LEFT].Cursor = Cursors.SizeNS;
|
|
||||||
_grippers[Gripper.POSITION_BOTTOM_RIGHT].Cursor = Cursors.SizeNS;
|
|
||||||
} else if (_grippers[Gripper.POSITION_TOP_LEFT].Top == _grippers[Gripper.POSITION_BOTTOM_RIGHT].Top) {
|
|
||||||
_grippers[Gripper.POSITION_TOP_LEFT].Cursor = Cursors.SizeWE;
|
|
||||||
_grippers[Gripper.POSITION_BOTTOM_RIGHT].Cursor = Cursors.SizeWE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GripperMouseDown(object sender, MouseEventArgs e) {
|
|
||||||
Gripper originatingGripper = (Gripper)sender;
|
|
||||||
if (originatingGripper != _targetGripper) {
|
|
||||||
Status = EditStatus.RESIZING;
|
|
||||||
_boundsBeforeResize = new Rectangle(left, top, width, height);
|
|
||||||
_boundsAfterResize = new RectangleF(_boundsBeforeResize.Left, _boundsBeforeResize.Top, _boundsBeforeResize.Width, _boundsBeforeResize.Height);
|
|
||||||
} else {
|
|
||||||
Status = EditStatus.MOVING;
|
|
||||||
}
|
|
||||||
isMadeUndoable = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GripperMouseUp(object sender, MouseEventArgs e) {
|
|
||||||
Gripper originatingGripper = (Gripper)sender;
|
|
||||||
if (originatingGripper != _targetGripper) {
|
|
||||||
_boundsBeforeResize = Rectangle.Empty;
|
|
||||||
_boundsAfterResize = RectangleF.Empty;
|
|
||||||
isMadeUndoable = false;
|
|
||||||
}
|
|
||||||
Status = EditStatus.IDLE;
|
|
||||||
Invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GripperMouseMove(object sender, MouseEventArgs e) {
|
|
||||||
Invalidate();
|
|
||||||
Gripper originatingGripper = (Gripper)sender;
|
|
||||||
int absX = originatingGripper.Left + e.X;
|
|
||||||
int absY = originatingGripper.Top + e.Y;
|
|
||||||
if (originatingGripper == _targetGripper && Status.Equals(EditStatus.MOVING)) {
|
|
||||||
TargetGripperMove(absX, absY);
|
|
||||||
} else if (Status.Equals(EditStatus.RESIZING)) {
|
|
||||||
// check if we already made this undoable
|
|
||||||
if (!isMadeUndoable) {
|
|
||||||
// don't allow another undo until we are finished with this move
|
|
||||||
isMadeUndoable = true;
|
|
||||||
// Make undo-able
|
|
||||||
MakeBoundsChangeUndoable(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
SuspendLayout();
|
|
||||||
|
|
||||||
// reset "workbench" rectangle to current bounds
|
|
||||||
_boundsAfterResize.X = _boundsBeforeResize.X;
|
|
||||||
_boundsAfterResize.Y = _boundsBeforeResize.Y;
|
|
||||||
_boundsAfterResize.Width = _boundsBeforeResize.Width;
|
|
||||||
_boundsAfterResize.Height = _boundsBeforeResize.Height;
|
|
||||||
|
|
||||||
// calculate scaled rectangle
|
|
||||||
ScaleHelper.Scale(ref _boundsAfterResize, originatingGripper.Position, new PointF(absX, absY), ScaleHelper.GetScaleOptions());
|
|
||||||
|
|
||||||
// apply scaled bounds to this DrawableContainer
|
|
||||||
ApplyBounds(_boundsAfterResize);
|
|
||||||
|
|
||||||
ResumeLayout();
|
|
||||||
}
|
|
||||||
Invalidate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool hasFilters {
|
public bool hasFilters {
|
||||||
|
@ -558,38 +412,6 @@ namespace Greenshot.Drawing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ShowGrippers() {
|
|
||||||
if (_grippers != null) {
|
|
||||||
for (int i = 0; i < _grippers.Length; i++) {
|
|
||||||
if (_grippers[i].Enabled) {
|
|
||||||
_grippers[i].Show();
|
|
||||||
} else {
|
|
||||||
_grippers[i].Hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_targetGripper != null) {
|
|
||||||
if (_targetGripper.Enabled) {
|
|
||||||
_targetGripper.Show();
|
|
||||||
} else {
|
|
||||||
_targetGripper.Hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ResumeLayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void HideGrippers() {
|
|
||||||
SuspendLayout();
|
|
||||||
if (_grippers != null) {
|
|
||||||
for (int i = 0; i < _grippers.Length; i++) {
|
|
||||||
_grippers[i].Hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_targetGripper != null) {
|
|
||||||
_targetGripper.Hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResizeTo(int width, int height, int anchorPosition) {
|
public void ResizeTo(int width, int height, int anchorPosition) {
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
Width = width;
|
Width = width;
|
||||||
|
@ -659,28 +481,6 @@ namespace Greenshot.Drawing {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void SwitchParent(Surface newParent) {
|
protected virtual void SwitchParent(Surface newParent) {
|
||||||
// Target gripper
|
|
||||||
if (_parent != null && _targetGripper != null) {
|
|
||||||
_parent.Controls.Remove(_targetGripper);
|
|
||||||
}
|
|
||||||
// Normal grippers
|
|
||||||
if (_parent != null && _grippers != null) {
|
|
||||||
for (int i=0; i<_grippers.Length; i++) {
|
|
||||||
_parent.Controls.Remove(_grippers[i]);
|
|
||||||
}
|
|
||||||
} else if (_grippers == null) {
|
|
||||||
InitControls();
|
|
||||||
}
|
|
||||||
_parent = newParent;
|
|
||||||
// Target gripper
|
|
||||||
if (_parent != null && _targetGripper != null) {
|
|
||||||
_parent.Controls.Add(_targetGripper);
|
|
||||||
}
|
|
||||||
// Normal grippers
|
|
||||||
if (_grippers != null) {
|
|
||||||
_parent.Controls.AddRange(_grippers);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach(IFilter filter in Filters) {
|
foreach(IFilter filter in Filters) {
|
||||||
filter.Parent = this;
|
filter.Parent = this;
|
||||||
}
|
}
|
||||||
|
@ -778,22 +578,13 @@ namespace Greenshot.Drawing {
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
Point topLeft = new Point(Left, Top);
|
Point topLeft = new Point(Left, Top);
|
||||||
Point bottomRight = new Point(Left + Width, Top + Height);
|
Point bottomRight = new Point(Left + Width, Top + Height);
|
||||||
Point[] points;
|
Point[] points = new[] { topLeft, bottomRight };
|
||||||
if (TargetGripper != null) {
|
|
||||||
points = new[] {topLeft, bottomRight, TargetGripper.Location};
|
|
||||||
|
|
||||||
} else {
|
|
||||||
points = new[] { topLeft, bottomRight };
|
|
||||||
}
|
|
||||||
matrix.TransformPoints(points);
|
matrix.TransformPoints(points);
|
||||||
|
|
||||||
Left = points[0].X;
|
Left = points[0].X;
|
||||||
Top = points[0].Y;
|
Top = points[0].Y;
|
||||||
Width = points[1].X - points[0].X;
|
Width = points[1].X - points[0].X;
|
||||||
Height = points[1].Y - points[0].Y;
|
Height = points[1].Y - points[0].Y;
|
||||||
if (TargetGripper != null) {
|
|
||||||
TargetGripper.Location = points[points.Length-1];
|
|
||||||
}
|
|
||||||
ResumeLayout();
|
ResumeLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,26 +171,6 @@ namespace Greenshot.Drawing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hides the grippers of all elements in the list.
|
|
||||||
/// </summary>
|
|
||||||
public void HideGrippers() {
|
|
||||||
foreach(var dc in this) {
|
|
||||||
dc.HideGrippers();
|
|
||||||
dc.Invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Shows the grippers of all elements in the list.
|
|
||||||
/// </summary>
|
|
||||||
public void ShowGrippers() {
|
|
||||||
foreach(var dc in this) {
|
|
||||||
dc.ShowGrippers();
|
|
||||||
dc.Invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates whether on of the elements is clickable at the given location
|
/// Indicates whether on of the elements is clickable at the given location
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -63,12 +63,7 @@ namespace Greenshot.Drawing {
|
||||||
|
|
||||||
|
|
||||||
protected void Init() {
|
protected void Init() {
|
||||||
if (_grippers != null) {
|
// TODO: Remove grippers
|
||||||
for (int i = 0; i < _grippers.Length; i++) {
|
|
||||||
_grippers[i].Enabled = false;
|
|
||||||
_grippers[i].Visible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Transform(Matrix matrix) {
|
public override void Transform(Matrix matrix) {
|
||||||
|
@ -258,17 +253,6 @@ namespace Greenshot.Drawing {
|
||||||
return freehandPath.GetHashCode();
|
return freehandPath.GetHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is overriden to prevent the grippers to be modified.
|
|
||||||
/// Might not be the best way...
|
|
||||||
/// </summary>
|
|
||||||
protected override void DoLayout() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ShowGrippers() {
|
|
||||||
ResumeLayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool ClickableAt(int x, int y) {
|
public override bool ClickableAt(int x, int y) {
|
||||||
bool returnValue = base.ClickableAt(x, y);
|
bool returnValue = base.ClickableAt(x, y);
|
||||||
if (returnValue) {
|
if (returnValue) {
|
||||||
|
|
|
@ -53,11 +53,7 @@ namespace Greenshot.Drawing {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Init() {
|
protected void Init() {
|
||||||
if (_grippers != null) {
|
// TODO: Remove the unneeded grippers (1, 2, 3, 5, 6, 7)
|
||||||
foreach (int index in new[] { 1, 2, 3, 5, 6, 7 }) {
|
|
||||||
_grippers[index].Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw(Graphics graphics, RenderMode rm) {
|
public override void Draw(Graphics graphics, RenderMode rm) {
|
||||||
|
|
|
@ -19,38 +19,20 @@
|
||||||
* 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;
|
namespace Greenshot.Drawing
|
||||||
using System.Windows.Forms;
|
{
|
||||||
|
|
||||||
namespace Greenshot.Drawing {
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Grippers are the dragable edges of our containers
|
/// Position
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Gripper : Label {
|
public enum Positions : int
|
||||||
/// <summary>
|
{
|
||||||
/// Constants for anchor/gripper position:
|
TopLeft = 0,
|
||||||
/// 0 1 2
|
TopCenter = 1,
|
||||||
/// 7 3
|
TopRight = 2,
|
||||||
/// 6 5 4
|
MiddleRight = 3,
|
||||||
/// </summary>
|
BottomRight = 4,
|
||||||
public const int POSITION_TOP_LEFT = 0;
|
BottomCenter = 5,
|
||||||
public const int POSITION_TOP_CENTER = 1;
|
BottomLeft = 6,
|
||||||
public const int POSITION_TOP_RIGHT = 2;
|
MiddleLeft = 7
|
||||||
public const int POSITION_MIDDLE_RIGHT = 3;
|
|
||||||
public const int POSITION_BOTTOM_RIGHT = 4;
|
|
||||||
public const int POSITION_BOTTOM_CENTER = 5;
|
|
||||||
public const int POSITION_BOTTOM_LEFT = 6;
|
|
||||||
public const int POSITION_MIDDLE_LEFT = 7;
|
|
||||||
|
|
||||||
public int Position {
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Gripper() {
|
|
||||||
Width = 5;
|
|
||||||
Height = 5;
|
|
||||||
BackColor = Color.Black;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -118,7 +118,7 @@ namespace Greenshot.Drawing {
|
||||||
|
|
||||||
if (TargetGripper.Location != newGripperLocation) {
|
if (TargetGripper.Location != newGripperLocation) {
|
||||||
Invalidate();
|
Invalidate();
|
||||||
TargetGripperMove(newGripperLocation.X, newGripperLocation.Y);
|
TargetGripper.Location = newGripperLocation;
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
return returnValue;
|
return returnValue;
|
||||||
|
@ -180,7 +180,7 @@ namespace Greenshot.Drawing {
|
||||||
private GraphicsPath CreateTail() {
|
private GraphicsPath CreateTail() {
|
||||||
Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
|
Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
|
||||||
|
|
||||||
int tailLength = GeometryHelper.Distance2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetGripper.Left, TargetGripper.Top);
|
int tailLength = GeometryHelper.Distance2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetGripper.Location.X, TargetGripper.Location.Y);
|
||||||
int tailWidth = (Math.Abs(rect.Width) + Math.Abs(rect.Height)) / 20;
|
int tailWidth = (Math.Abs(rect.Width) + Math.Abs(rect.Height)) / 20;
|
||||||
|
|
||||||
// This should fix a problem with the tail being to wide
|
// This should fix a problem with the tail being to wide
|
||||||
|
@ -192,7 +192,7 @@ namespace Greenshot.Drawing {
|
||||||
tail.AddLine(tailWidth, 0, 0, -tailLength);
|
tail.AddLine(tailWidth, 0, 0, -tailLength);
|
||||||
tail.CloseFigure();
|
tail.CloseFigure();
|
||||||
|
|
||||||
int tailAngle = 90 + (int)GeometryHelper.Angle2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetGripper.Left, TargetGripper.Top);
|
int tailAngle = 90 + (int)GeometryHelper.Angle2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetGripper.Location.X, TargetGripper.Location.Y);
|
||||||
|
|
||||||
using (Matrix tailMatrix = new Matrix()) {
|
using (Matrix tailMatrix = new Matrix()) {
|
||||||
tailMatrix.Translate(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2));
|
tailMatrix.Translate(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2));
|
||||||
|
|
|
@ -21,12 +21,14 @@
|
||||||
|
|
||||||
using Greenshot.Configuration;
|
using Greenshot.Configuration;
|
||||||
using Greenshot.Core;
|
using Greenshot.Core;
|
||||||
|
using Greenshot.Drawing.Adorners;
|
||||||
using Greenshot.Drawing.Fields;
|
using Greenshot.Drawing.Fields;
|
||||||
using Greenshot.Helpers;
|
using Greenshot.Helpers;
|
||||||
using Greenshot.IniFile;
|
using Greenshot.IniFile;
|
||||||
using Greenshot.Memento;
|
using Greenshot.Memento;
|
||||||
using Greenshot.Plugin;
|
using Greenshot.Plugin;
|
||||||
using Greenshot.Plugin.Drawing;
|
using Greenshot.Plugin.Drawing;
|
||||||
|
using Greenshot.Plugin.Drawing.Adorners;
|
||||||
using GreenshotPlugin.Controls;
|
using GreenshotPlugin.Controls;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
@ -991,12 +993,45 @@ namespace Greenshot.Drawing {
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if an adorner was "hit", and change the cursor if so
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="mouseEventArgs">MouseEventArgs</param>
|
||||||
|
/// <returns>IAdorner</returns>
|
||||||
|
private IAdorner AdornersHitTest(MouseEventArgs mouseEventArgs)
|
||||||
|
{
|
||||||
|
foreach(IDrawableContainer drawableContainer in selectedElements)
|
||||||
|
{
|
||||||
|
foreach(IAdorner adorner in drawableContainer.Adorners)
|
||||||
|
{
|
||||||
|
if (adorner.HitTest(mouseEventArgs.Location))
|
||||||
|
{
|
||||||
|
if (adorner.Cursor != null)
|
||||||
|
{
|
||||||
|
Cursor = adorner.Cursor;
|
||||||
|
}
|
||||||
|
return adorner;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This event handler is called when someone presses the mouse on a surface.
|
/// This event handler is called when someone presses the mouse on a surface.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender"></param>
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
void SurfaceMouseDown(object sender, MouseEventArgs e) {
|
void SurfaceMouseDown(object sender, MouseEventArgs e) {
|
||||||
|
|
||||||
|
// Handle Adorners
|
||||||
|
var adorner = AdornersHitTest(e);
|
||||||
|
if (adorner != null)
|
||||||
|
{
|
||||||
|
adorner.MouseDown(sender, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_mouseStart = e.Location;
|
_mouseStart = e.Location;
|
||||||
|
|
||||||
// check contextmenu
|
// check contextmenu
|
||||||
|
@ -1065,6 +1100,15 @@ namespace Greenshot.Drawing {
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender"></param>
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
void SurfaceMouseUp(object sender, MouseEventArgs e) {
|
void SurfaceMouseUp(object sender, MouseEventArgs e) {
|
||||||
|
|
||||||
|
// Handle Adorners
|
||||||
|
var adorner = AdornersHitTest(e);
|
||||||
|
if (adorner != null)
|
||||||
|
{
|
||||||
|
adorner.MouseUp(sender, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Point currentMouse = new Point(e.X, e.Y);
|
Point currentMouse = new Point(e.X, e.Y);
|
||||||
|
|
||||||
_elements.Status = EditStatus.IDLE;
|
_elements.Status = EditStatus.IDLE;
|
||||||
|
@ -1098,7 +1142,7 @@ namespace Greenshot.Drawing {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedElements.Count > 0) {
|
if (selectedElements.Count > 0) {
|
||||||
selectedElements.ShowGrippers();
|
selectedElements.Invalidate();
|
||||||
selectedElements.Selected = true;
|
selectedElements.Selected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1126,6 +1170,14 @@ namespace Greenshot.Drawing {
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender"></param>
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
void SurfaceMouseMove(object sender, MouseEventArgs e) {
|
void SurfaceMouseMove(object sender, MouseEventArgs e) {
|
||||||
|
// Handle Adorners
|
||||||
|
var adorner = AdornersHitTest(e);
|
||||||
|
if (adorner != null)
|
||||||
|
{
|
||||||
|
adorner.MouseMove(sender, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Point currentMouse = e.Location;
|
Point currentMouse = e.Location;
|
||||||
|
|
||||||
if (DrawingMode != DrawingModes.None) {
|
if (DrawingMode != DrawingModes.None) {
|
||||||
|
@ -1137,7 +1189,7 @@ namespace Greenshot.Drawing {
|
||||||
if (_mouseDown) {
|
if (_mouseDown) {
|
||||||
if (_mouseDownElement != null) { // an element is currently dragged
|
if (_mouseDownElement != null) { // an element is currently dragged
|
||||||
_mouseDownElement.Invalidate();
|
_mouseDownElement.Invalidate();
|
||||||
selectedElements.HideGrippers();
|
selectedElements.Invalidate();
|
||||||
// Move the element
|
// Move the element
|
||||||
if (_mouseDownElement.Selected) {
|
if (_mouseDownElement.Selected) {
|
||||||
if (!_isSurfaceMoveMadeUndoable) {
|
if (!_isSurfaceMoveMadeUndoable) {
|
||||||
|
@ -1208,10 +1260,10 @@ namespace Greenshot.Drawing {
|
||||||
/// This is the event handler for the Paint Event, try to draw as little as possible!
|
/// This is the event handler for the Paint Event, try to draw as little as possible!
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender"></param>
|
||||||
/// <param name="e"></param>
|
/// <param name="paintEventArgs">PaintEventArgs</param>
|
||||||
void SurfacePaint(object sender, PaintEventArgs e) {
|
void SurfacePaint(object sender, PaintEventArgs paintEventArgs) {
|
||||||
Graphics targetGraphics = e.Graphics;
|
Graphics targetGraphics = paintEventArgs.Graphics;
|
||||||
Rectangle clipRectangle = e.ClipRectangle;
|
Rectangle clipRectangle = paintEventArgs.ClipRectangle;
|
||||||
if (Rectangle.Empty.Equals(clipRectangle)) {
|
if (Rectangle.Empty.Equals(clipRectangle)) {
|
||||||
LOG.Debug("Empty cliprectangle??");
|
LOG.Debug("Empty cliprectangle??");
|
||||||
return;
|
return;
|
||||||
|
@ -1246,6 +1298,15 @@ namespace Greenshot.Drawing {
|
||||||
targetGraphics.DrawImage(Image, clipRectangle, clipRectangle, GraphicsUnit.Pixel);
|
targetGraphics.DrawImage(Image, clipRectangle, clipRectangle, GraphicsUnit.Pixel);
|
||||||
_elements.Draw(targetGraphics, null, RenderMode.EDIT, clipRectangle);
|
_elements.Draw(targetGraphics, null, RenderMode.EDIT, clipRectangle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw adorners last
|
||||||
|
foreach(var drawableContainer in selectedElements)
|
||||||
|
{
|
||||||
|
foreach(var adorner in drawableContainer.Adorners)
|
||||||
|
{
|
||||||
|
adorner.Paint(paintEventArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawBackground(Graphics targetGraphics, Rectangle clipRectangle) {
|
private void DrawBackground(Graphics targetGraphics, Rectangle clipRectangle) {
|
||||||
|
@ -1531,9 +1592,9 @@ namespace Greenshot.Drawing {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="container"></param>
|
/// <param name="container"></param>
|
||||||
public void DeselectElement(IDrawableContainer container) {
|
public void DeselectElement(IDrawableContainer container) {
|
||||||
container.HideGrippers();
|
|
||||||
container.Selected = false;
|
container.Selected = false;
|
||||||
selectedElements.Remove(container);
|
selectedElements.Remove(container);
|
||||||
|
container.Invalidate();
|
||||||
FieldAggregator.UnbindElement(container);
|
FieldAggregator.UnbindElement(container);
|
||||||
if (_movingElementChanged != null) {
|
if (_movingElementChanged != null) {
|
||||||
SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs();
|
SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs();
|
||||||
|
@ -1549,10 +1610,9 @@ namespace Greenshot.Drawing {
|
||||||
if (HasSelectedElements) {
|
if (HasSelectedElements) {
|
||||||
while(selectedElements.Count > 0) {
|
while(selectedElements.Count > 0) {
|
||||||
IDrawableContainer element = selectedElements[0];
|
IDrawableContainer element = selectedElements[0];
|
||||||
element.Invalidate();
|
|
||||||
element.HideGrippers();
|
|
||||||
element.Selected = false;
|
element.Selected = false;
|
||||||
selectedElements.Remove(element);
|
selectedElements.Remove(element);
|
||||||
|
element.Invalidate();
|
||||||
FieldAggregator.UnbindElement(element);
|
FieldAggregator.UnbindElement(element);
|
||||||
}
|
}
|
||||||
if (_movingElementChanged != null) {
|
if (_movingElementChanged != null) {
|
||||||
|
@ -1570,7 +1630,6 @@ namespace Greenshot.Drawing {
|
||||||
public void SelectElement(IDrawableContainer container) {
|
public void SelectElement(IDrawableContainer container) {
|
||||||
if (!selectedElements.Contains(container)) {
|
if (!selectedElements.Contains(container)) {
|
||||||
selectedElements.Add(container);
|
selectedElements.Add(container);
|
||||||
container.ShowGrippers();
|
|
||||||
container.Selected = true;
|
container.Selected = true;
|
||||||
FieldAggregator.BindElement(container);
|
FieldAggregator.BindElement(container);
|
||||||
if (_movingElementChanged != null) {
|
if (_movingElementChanged != null) {
|
||||||
|
|
|
@ -75,7 +75,10 @@
|
||||||
<Compile Include="Destinations\FileWithDialogDestination.cs" />
|
<Compile Include="Destinations\FileWithDialogDestination.cs" />
|
||||||
<Compile Include="Destinations\PickerDestination.cs" />
|
<Compile Include="Destinations\PickerDestination.cs" />
|
||||||
<Compile Include="Destinations\PrinterDestination.cs" />
|
<Compile Include="Destinations\PrinterDestination.cs" />
|
||||||
|
<Compile Include="Drawing\Adorners\GripperAdorner.cs" />
|
||||||
|
<Compile Include="Drawing\Adorners\TargetAdorner.cs" />
|
||||||
<Compile Include="Drawing\ArrowContainer.cs" />
|
<Compile Include="Drawing\ArrowContainer.cs" />
|
||||||
|
<Compile Include="Drawing\Positions.cs" />
|
||||||
<Compile Include="Drawing\StepLabelContainer.cs" />
|
<Compile Include="Drawing\StepLabelContainer.cs" />
|
||||||
<Compile Include="Drawing\ImageContainer.cs" />
|
<Compile Include="Drawing\ImageContainer.cs" />
|
||||||
<Compile Include="Drawing\CropContainer.cs" />
|
<Compile Include="Drawing\CropContainer.cs" />
|
||||||
|
@ -101,9 +104,6 @@
|
||||||
<Compile Include="Drawing\Filters\MagnifierFilter.cs" />
|
<Compile Include="Drawing\Filters\MagnifierFilter.cs" />
|
||||||
<Compile Include="Drawing\Filters\PixelizationFilter.cs" />
|
<Compile Include="Drawing\Filters\PixelizationFilter.cs" />
|
||||||
<Compile Include="Drawing\Filters\BlurFilter.cs" />
|
<Compile Include="Drawing\Filters\BlurFilter.cs" />
|
||||||
<Compile Include="Drawing\Gripper.cs">
|
|
||||||
<SubType>Component</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Drawing\HighlightContainer.cs" />
|
<Compile Include="Drawing\HighlightContainer.cs" />
|
||||||
<Compile Include="Drawing\IconContainer.cs" />
|
<Compile Include="Drawing\IconContainer.cs" />
|
||||||
<Compile Include="Drawing\LineContainer.cs" />
|
<Compile Include="Drawing\LineContainer.cs" />
|
||||||
|
|
|
@ -119,15 +119,15 @@ namespace Greenshot.Helpers {
|
||||||
return GetAlignedRectangle(newRect, targetRect, alignment);
|
return GetAlignedRectangle(newRect, targetRect, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RationalScale(ref RectangleF originalRectangle, int resizeHandlePosition, PointF resizeHandleCoords) {
|
public static void RationalScale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords) {
|
||||||
Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords, ScaleOptions.Rational);
|
Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords, ScaleOptions.Rational);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void CenteredScale(ref RectangleF originalRectangle, int resizeHandlePosition, PointF resizeHandleCoords) {
|
public static void CenteredScale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords) {
|
||||||
Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords, ScaleOptions.Centered);
|
Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords, ScaleOptions.Centered);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Scale(ref RectangleF originalRectangle, int resizeHandlePosition, PointF resizeHandleCoords) {
|
public static void Scale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords) {
|
||||||
Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords, null);
|
Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ namespace Greenshot.Helpers {
|
||||||
/// <param name="resizeHandlePosition">position of the handle/gripper being used for resized, see constants in Gripper.cs, e.g. Gripper.POSITION_TOP_LEFT</param>
|
/// <param name="resizeHandlePosition">position of the handle/gripper being used for resized, see constants in Gripper.cs, e.g. Gripper.POSITION_TOP_LEFT</param>
|
||||||
/// <param name="resizeHandleCoords">coordinates of the used handle/gripper</param>
|
/// <param name="resizeHandleCoords">coordinates of the used handle/gripper</param>
|
||||||
/// <param name="options">ScaleOptions to use when scaling</param>
|
/// <param name="options">ScaleOptions to use when scaling</param>
|
||||||
public static void Scale(ref RectangleF originalRectangle, int resizeHandlePosition, PointF resizeHandleCoords, ScaleOptions? options) {
|
public static void Scale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords, ScaleOptions? options) {
|
||||||
if(options == null) {
|
if(options == null) {
|
||||||
options = GetScaleOptions();
|
options = GetScaleOptions();
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,7 @@ namespace Greenshot.Helpers {
|
||||||
resizeHandleCoords.X -= 2 * (resizeHandleCoords.X - rectCenterX);
|
resizeHandleCoords.X -= 2 * (resizeHandleCoords.X - rectCenterX);
|
||||||
resizeHandleCoords.Y -= 2 * (resizeHandleCoords.Y - rectCenterY);
|
resizeHandleCoords.Y -= 2 * (resizeHandleCoords.Y - rectCenterY);
|
||||||
// scale again with opposing handle and mirrored coordinates
|
// scale again with opposing handle and mirrored coordinates
|
||||||
resizeHandlePosition = (resizeHandlePosition + 4) % 8;
|
resizeHandlePosition = (Positions)((((int)resizeHandlePosition) + 4) % 8);
|
||||||
scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords);
|
scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords);
|
||||||
} else {
|
} else {
|
||||||
scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords);
|
scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords);
|
||||||
|
@ -171,47 +171,47 @@ namespace Greenshot.Helpers {
|
||||||
/// <param name="originalRectangle">bounds of the current rectangle, scaled values will be written to this reference</param>
|
/// <param name="originalRectangle">bounds of the current rectangle, scaled values will be written to this reference</param>
|
||||||
/// <param name="resizeHandlePosition">position of the handle/gripper being used for resized, see constants in Gripper.cs, e.g. Gripper.POSITION_TOP_LEFT</param>
|
/// <param name="resizeHandlePosition">position of the handle/gripper being used for resized, see constants in Gripper.cs, e.g. Gripper.POSITION_TOP_LEFT</param>
|
||||||
/// <param name="resizeHandleCoords">coordinates of the used handle/gripper</param>
|
/// <param name="resizeHandleCoords">coordinates of the used handle/gripper</param>
|
||||||
private static void scale(ref RectangleF originalRectangle, int resizeHandlePosition, PointF resizeHandleCoords) {
|
private static void scale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords) {
|
||||||
switch(resizeHandlePosition) {
|
switch(resizeHandlePosition) {
|
||||||
|
|
||||||
case Gripper.POSITION_TOP_LEFT:
|
case Positions.TopLeft:
|
||||||
originalRectangle.Width = originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X;
|
originalRectangle.Width = originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X;
|
||||||
originalRectangle.Height = originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y;
|
originalRectangle.Height = originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y;
|
||||||
originalRectangle.X = resizeHandleCoords.X;
|
originalRectangle.X = resizeHandleCoords.X;
|
||||||
originalRectangle.Y = resizeHandleCoords.Y;
|
originalRectangle.Y = resizeHandleCoords.Y;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Gripper.POSITION_TOP_CENTER:
|
case Positions.TopCenter:
|
||||||
originalRectangle.Height = originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y;
|
originalRectangle.Height = originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y;
|
||||||
originalRectangle.Y = resizeHandleCoords.Y;
|
originalRectangle.Y = resizeHandleCoords.Y;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Gripper.POSITION_TOP_RIGHT:
|
case Positions.TopRight:
|
||||||
originalRectangle.Width = resizeHandleCoords.X - originalRectangle.Left;
|
originalRectangle.Width = resizeHandleCoords.X - originalRectangle.Left;
|
||||||
originalRectangle.Height = originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y;
|
originalRectangle.Height = originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y;
|
||||||
originalRectangle.Y = resizeHandleCoords.Y;
|
originalRectangle.Y = resizeHandleCoords.Y;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Gripper.POSITION_MIDDLE_LEFT:
|
case Positions.MiddleLeft:
|
||||||
originalRectangle.Width = originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X;
|
originalRectangle.Width = originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X;
|
||||||
originalRectangle.X = resizeHandleCoords.X;
|
originalRectangle.X = resizeHandleCoords.X;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Gripper.POSITION_MIDDLE_RIGHT:
|
case Positions.MiddleRight:
|
||||||
originalRectangle.Width = resizeHandleCoords.X - originalRectangle.Left;
|
originalRectangle.Width = resizeHandleCoords.X - originalRectangle.Left;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Gripper.POSITION_BOTTOM_LEFT:
|
case Positions.BottomLeft:
|
||||||
originalRectangle.Width = originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X;
|
originalRectangle.Width = originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X;
|
||||||
originalRectangle.Height = resizeHandleCoords.Y - originalRectangle.Top;
|
originalRectangle.Height = resizeHandleCoords.Y - originalRectangle.Top;
|
||||||
originalRectangle.X = resizeHandleCoords.X;
|
originalRectangle.X = resizeHandleCoords.X;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Gripper.POSITION_BOTTOM_CENTER:
|
case Positions.BottomCenter:
|
||||||
originalRectangle.Height = resizeHandleCoords.Y - originalRectangle.Top;
|
originalRectangle.Height = resizeHandleCoords.Y - originalRectangle.Top;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Gripper.POSITION_BOTTOM_RIGHT:
|
case Positions.BottomRight:
|
||||||
originalRectangle.Width = resizeHandleCoords.X - originalRectangle.Left;
|
originalRectangle.Width = resizeHandleCoords.X - originalRectangle.Left;
|
||||||
originalRectangle.Height = resizeHandleCoords.Y - originalRectangle.Top;
|
originalRectangle.Height = resizeHandleCoords.Y - originalRectangle.Top;
|
||||||
break;
|
break;
|
||||||
|
@ -226,14 +226,14 @@ namespace Greenshot.Helpers {
|
||||||
/// Adjusts resizeHandleCoords so that aspect ratio is kept after resizing a given rectangle with provided arguments
|
/// Adjusts resizeHandleCoords so that aspect ratio is kept after resizing a given rectangle with provided arguments
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="originalRectangle">bounds of the current rectangle</param>
|
/// <param name="originalRectangle">bounds of the current rectangle</param>
|
||||||
/// <param name="resizeHandlePosition">position of the handle/gripper being used for resized, see constants in Gripper.cs, e.g. Gripper.POSITION_TOP_LEFT</param>
|
/// <param name="resizeHandlePosition">position of the handle/gripper being used for resized, see Position</param>
|
||||||
/// <param name="resizeHandleCoords">coordinates of the used handle/gripper, adjusted coordinates will be written to this reference</param>
|
/// <param name="resizeHandleCoords">coordinates of the used handle/gripper, adjusted coordinates will be written to this reference</param>
|
||||||
private static void adjustCoordsForRationalScale(RectangleF originalRectangle, int resizeHandlePosition, ref PointF resizeHandleCoords) {
|
private static void adjustCoordsForRationalScale(RectangleF originalRectangle, Positions resizeHandlePosition, ref PointF resizeHandleCoords) {
|
||||||
float originalRatio = originalRectangle.Width / originalRectangle.Height;
|
float originalRatio = originalRectangle.Width / originalRectangle.Height;
|
||||||
float newWidth, newHeight, newRatio;
|
float newWidth, newHeight, newRatio;
|
||||||
switch(resizeHandlePosition) {
|
switch(resizeHandlePosition) {
|
||||||
|
|
||||||
case Gripper.POSITION_TOP_LEFT:
|
case Positions.TopLeft:
|
||||||
newWidth = originalRectangle.Right - resizeHandleCoords.X;
|
newWidth = originalRectangle.Right - resizeHandleCoords.X;
|
||||||
newHeight = originalRectangle.Bottom - resizeHandleCoords.Y;
|
newHeight = originalRectangle.Bottom - resizeHandleCoords.Y;
|
||||||
newRatio = newWidth / newHeight;
|
newRatio = newWidth / newHeight;
|
||||||
|
@ -244,7 +244,7 @@ namespace Greenshot.Helpers {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Gripper.POSITION_TOP_RIGHT:
|
case Positions.TopRight:
|
||||||
newWidth = resizeHandleCoords.X - originalRectangle.Left;
|
newWidth = resizeHandleCoords.X - originalRectangle.Left;
|
||||||
newHeight = originalRectangle.Bottom - resizeHandleCoords.Y;
|
newHeight = originalRectangle.Bottom - resizeHandleCoords.Y;
|
||||||
newRatio = newWidth / newHeight;
|
newRatio = newWidth / newHeight;
|
||||||
|
@ -255,7 +255,7 @@ namespace Greenshot.Helpers {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Gripper.POSITION_BOTTOM_LEFT:
|
case Positions.BottomLeft:
|
||||||
newWidth = originalRectangle.Right - resizeHandleCoords.X;
|
newWidth = originalRectangle.Right - resizeHandleCoords.X;
|
||||||
newHeight = resizeHandleCoords.Y - originalRectangle.Top;
|
newHeight = resizeHandleCoords.Y - originalRectangle.Top;
|
||||||
newRatio = newWidth / newHeight;
|
newRatio = newWidth / newHeight;
|
||||||
|
@ -266,7 +266,7 @@ namespace Greenshot.Helpers {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Gripper.POSITION_BOTTOM_RIGHT:
|
case Positions.BottomRight:
|
||||||
newWidth = resizeHandleCoords.X - originalRectangle.Left;
|
newWidth = resizeHandleCoords.X - originalRectangle.Left;
|
||||||
newHeight = resizeHandleCoords.Y - originalRectangle.Top;
|
newHeight = resizeHandleCoords.Y - originalRectangle.Top;
|
||||||
newRatio = newWidth / newHeight;
|
newRatio = newWidth / newHeight;
|
||||||
|
@ -285,10 +285,10 @@ namespace Greenshot.Helpers {
|
||||||
|
|
||||||
public static void Scale(Rectangle boundsBeforeResize, int cursorX, int cursorY, ref RectangleF boundsAfterResize, IDoubleProcessor angleRoundBehavior) {
|
public static void Scale(Rectangle boundsBeforeResize, int cursorX, int cursorY, ref RectangleF boundsAfterResize, IDoubleProcessor angleRoundBehavior) {
|
||||||
|
|
||||||
Scale(boundsBeforeResize, Gripper.POSITION_TOP_LEFT, cursorX, cursorY, ref boundsAfterResize, angleRoundBehavior);
|
Scale(boundsBeforeResize, Positions.TopLeft, cursorX, cursorY, ref boundsAfterResize, angleRoundBehavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Scale(Rectangle boundsBeforeResize, int gripperPosition, int cursorX, int cursorY, ref RectangleF boundsAfterResize, IDoubleProcessor angleRoundBehavior) {
|
public static void Scale(Rectangle boundsBeforeResize, Positions gripperPosition, int cursorX, int cursorY, ref RectangleF boundsAfterResize, IDoubleProcessor angleRoundBehavior) {
|
||||||
|
|
||||||
ScaleOptions opts = GetScaleOptions();
|
ScaleOptions opts = GetScaleOptions();
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
<Compile Include="IEInterop\IHTMLWindow3.cs" />
|
<Compile Include="IEInterop\IHTMLWindow3.cs" />
|
||||||
<Compile Include="IEInterop\IHTMLWindow4.cs" />
|
<Compile Include="IEInterop\IHTMLWindow4.cs" />
|
||||||
<Compile Include="IEInterop\IWebBrowser2.cs" />
|
<Compile Include="IEInterop\IWebBrowser2.cs" />
|
||||||
|
<Compile Include="Interfaces\Drawing\Adorners\IAdorner.cs" />
|
||||||
<Compile Include="Interop\Base.cs" />
|
<Compile Include="Interop\Base.cs" />
|
||||||
<Compile Include="Interop\ComProgIdAttribute.cs" />
|
<Compile Include="Interop\ComProgIdAttribute.cs" />
|
||||||
<Compile Include="Interop\COMWrapper.cs" />
|
<Compile Include="Interop\COMWrapper.cs" />
|
||||||
|
|
81
GreenshotPlugin/Interfaces/Drawing/Adorners/IAdorner.cs
Normal file
81
GreenshotPlugin/Interfaces/Drawing/Adorners/IAdorner.cs
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Greenshot - a free and open source screenshot tool
|
||||||
|
* Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
|
||||||
|
*
|
||||||
|
* For more information see: http://getgreenshot.org/
|
||||||
|
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation, either version 1 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace Greenshot.Plugin.Drawing.Adorners
|
||||||
|
{
|
||||||
|
public interface IAdorner
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The owner of this adorner
|
||||||
|
/// </summary>
|
||||||
|
IDrawableContainer Owner { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is the current point "over" the Adorner?
|
||||||
|
/// If this is the case, the
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="point">Point to test</param>
|
||||||
|
/// <returns>true if so</returns>
|
||||||
|
bool HitTest(Point point);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle the MouseDown event
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="mouseEventArgs">MouseEventArgs</param>
|
||||||
|
void MouseDown(object sender, MouseEventArgs mouseEventArgs);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle the MouseUp event
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="mouseEventArgs">MouseEventArgs</param>
|
||||||
|
void MouseUp(object sender, MouseEventArgs mouseEventArgs);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle the MouseMove event
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="mouseEventArgs">MouseEventArgs</param>
|
||||||
|
void MouseMove(object sender, MouseEventArgs mouseEventArgs);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the cursor that should be displayed for this behavior.
|
||||||
|
/// </summary>
|
||||||
|
Cursor Cursor { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draw the adorner
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="paintEventArgs">PaintEventArgs</param>
|
||||||
|
void Paint(PaintEventArgs paintEventArgs);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called if the owner is transformed
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="matrix">Matrix</param>
|
||||||
|
void Transform(Matrix matrix);
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,8 @@ using System.Drawing.Drawing2D;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Greenshot.Plugin.Drawing.Adorners;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Drawing {
|
namespace Greenshot.Plugin.Drawing {
|
||||||
public enum RenderMode {EDIT, EXPORT};
|
public enum RenderMode {EDIT, EXPORT};
|
||||||
|
@ -74,6 +76,10 @@ namespace Greenshot.Plugin.Drawing {
|
||||||
get;
|
get;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApplyBounds(RectangleF newBounds);
|
||||||
|
|
||||||
|
void DoLayout();
|
||||||
|
|
||||||
bool hasFilters {
|
bool hasFilters {
|
||||||
get;
|
get;
|
||||||
}
|
}
|
||||||
|
@ -85,8 +91,6 @@ namespace Greenshot.Plugin.Drawing {
|
||||||
void AlignToParent(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment);
|
void AlignToParent(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment);
|
||||||
void Invalidate();
|
void Invalidate();
|
||||||
bool ClickableAt(int x, int y);
|
bool ClickableAt(int x, int y);
|
||||||
void HideGrippers();
|
|
||||||
void ShowGrippers();
|
|
||||||
void MoveBy(int x, int y);
|
void MoveBy(int x, int y);
|
||||||
void Transform(Matrix matrix);
|
void Transform(Matrix matrix);
|
||||||
bool HandleMouseDown(int x, int y);
|
bool HandleMouseDown(int x, int y);
|
||||||
|
@ -97,6 +101,11 @@ namespace Greenshot.Plugin.Drawing {
|
||||||
EditStatus DefaultEditMode {
|
EditStatus DefaultEditMode {
|
||||||
get;
|
get;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Available adorners for the DrawableContainer
|
||||||
|
/// </summary>
|
||||||
|
IList<IAdorner> Adorners { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ITextContainer: IDrawableContainer {
|
public interface ITextContainer: IDrawableContainer {
|
||||||
|
|
|
@ -198,5 +198,7 @@ namespace Greenshot.Plugin {
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
int Width { get; }
|
||||||
|
int Height { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue