mirror of
https://github.com/greenshot/greenshot
synced 2025-08-19 21:13:23 -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
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
using Greenshot.Configuration;
|
||||
using Greenshot.Drawing.Adorners;
|
||||
using Greenshot.Drawing.Fields;
|
||||
using Greenshot.Drawing.Filters;
|
||||
using Greenshot.Helpers;
|
||||
|
@ -27,6 +28,7 @@ using Greenshot.IniFile;
|
|||
using Greenshot.Memento;
|
||||
using Greenshot.Plugin;
|
||||
using Greenshot.Plugin.Drawing;
|
||||
using Greenshot.Plugin.Drawing.Adorners;
|
||||
using log4net;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -35,7 +37,8 @@ using System.Drawing;
|
|||
using System.Drawing.Drawing2D;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Greenshot.Drawing {
|
||||
namespace Greenshot.Drawing
|
||||
{
|
||||
/// <summary>
|
||||
/// represents a rectangle, ellipse, label or whatever. Can contain filters, too.
|
||||
/// serializable for clipboard support
|
||||
|
@ -73,16 +76,6 @@ namespace Greenshot.Drawing {
|
|||
if (!disposing) {
|
||||
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;
|
||||
aggProps.UnbindElement(this);
|
||||
|
@ -117,14 +110,13 @@ namespace Greenshot.Drawing {
|
|||
get { return _parent; }
|
||||
set { SwitchParent((Surface)value); }
|
||||
}
|
||||
[NonSerialized]
|
||||
protected Gripper[] _grippers;
|
||||
|
||||
private bool layoutSuspended;
|
||||
|
||||
[NonSerialized]
|
||||
private Gripper _targetGripper;
|
||||
private TargetAdorner _targetGripper;
|
||||
|
||||
public Gripper TargetGripper {
|
||||
public TargetAdorner TargetGripper {
|
||||
get {
|
||||
return _targetGripper;
|
||||
}
|
||||
|
@ -220,6 +212,11 @@ namespace Greenshot.Drawing {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of available Adorners
|
||||
/// </summary>
|
||||
public IList<IAdorner> Adorners { get; } = new List<IAdorner>();
|
||||
|
||||
[NonSerialized]
|
||||
// will store current bounds of this DrawableContainer before starting a resize
|
||||
protected Rectangle _boundsBeforeResize = Rectangle.Empty;
|
||||
|
@ -329,73 +326,23 @@ namespace Greenshot.Drawing {
|
|||
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>
|
||||
/// Initialize a target gripper
|
||||
/// </summary>
|
||||
protected void InitTargetGripper(Color gripperColor, Point location) {
|
||||
_targetGripper = new Gripper {
|
||||
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
|
||||
}
|
||||
_targetGripper = new TargetAdorner(this, location);
|
||||
}
|
||||
|
||||
protected void InitGrippers() {
|
||||
|
||||
_grippers = new Gripper[8];
|
||||
for(int i=0; i<_grippers.Length; i++) {
|
||||
_grippers[i] = new Gripper();
|
||||
_grippers[i].Position = i;
|
||||
_grippers[i].MouseDown += GripperMouseDown;
|
||||
_grippers[i].MouseUp += GripperMouseUp;
|
||||
_grippers[i].MouseMove += GripperMouseMove;
|
||||
_grippers[i].Visible = false;
|
||||
_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
|
||||
}
|
||||
// Create the GripperAdorners
|
||||
Adorners.Add(new GripperAdorner(this, Positions.TopLeft));
|
||||
Adorners.Add(new GripperAdorner(this, Positions.TopCenter));
|
||||
Adorners.Add(new GripperAdorner(this, Positions.TopRight));
|
||||
Adorners.Add(new GripperAdorner(this, Positions.BottomLeft));
|
||||
Adorners.Add(new GripperAdorner(this, Positions.BottomCenter));
|
||||
Adorners.Add(new GripperAdorner(this, Positions.BottomRight));
|
||||
Adorners.Add(new GripperAdorner(this, Positions.MiddleLeft));
|
||||
Adorners.Add(new GripperAdorner(this, Positions.MiddleRight));
|
||||
}
|
||||
|
||||
public void SuspendLayout() {
|
||||
|
@ -407,101 +354,8 @@ namespace Greenshot.Drawing {
|
|||
DoLayout();
|
||||
}
|
||||
|
||||
protected 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};
|
||||
public virtual void DoLayout() {
|
||||
|
||||
_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 {
|
||||
|
@ -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) {
|
||||
SuspendLayout();
|
||||
Width = width;
|
||||
|
@ -659,28 +481,6 @@ namespace Greenshot.Drawing {
|
|||
}
|
||||
|
||||
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) {
|
||||
filter.Parent = this;
|
||||
}
|
||||
|
@ -778,22 +578,13 @@ namespace Greenshot.Drawing {
|
|||
SuspendLayout();
|
||||
Point topLeft = new Point(Left, Top);
|
||||
Point bottomRight = new Point(Left + Width, Top + Height);
|
||||
Point[] points;
|
||||
if (TargetGripper != null) {
|
||||
points = new[] {topLeft, bottomRight, TargetGripper.Location};
|
||||
|
||||
} else {
|
||||
points = new[] { topLeft, bottomRight };
|
||||
}
|
||||
Point[] points = new[] { topLeft, bottomRight };
|
||||
matrix.TransformPoints(points);
|
||||
|
||||
Left = points[0].X;
|
||||
Top = points[0].Y;
|
||||
Width = points[1].X - points[0].X;
|
||||
Height = points[1].Y - points[0].Y;
|
||||
if (TargetGripper != null) {
|
||||
TargetGripper.Location = points[points.Length-1];
|
||||
}
|
||||
ResumeLayout();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue