diff --git a/Greenshot/Drawing/Adorners/AbstractAdorner.cs b/Greenshot/Drawing/Adorners/AbstractAdorner.cs
new file mode 100644
index 000000000..685ec779f
--- /dev/null
+++ b/Greenshot/Drawing/Adorners/AbstractAdorner.cs
@@ -0,0 +1,147 @@
+/*
+ * 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 .
+ */
+
+using Greenshot.Plugin.Drawing;
+using Greenshot.Plugin.Drawing.Adorners;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+using System;
+
+namespace Greenshot.Drawing.Adorners
+{
+ public class AbstractAdorner : IAdorner
+ {
+ public virtual EditStatus EditStatus { get; protected set; } = EditStatus.IDLE;
+
+ protected Size _size = new Size(4, 4);
+
+ public AbstractAdorner(IDrawableContainer owner)
+ {
+ Owner = owner;
+ }
+
+ ///
+ /// Returns the cursor for when the mouse is over the adorner
+ ///
+ public virtual Cursor Cursor
+ {
+ get
+ {
+ return Cursors.SizeAll;
+ }
+ }
+
+ public virtual IDrawableContainer Owner
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Test if the point is inside the adorner
+ ///
+ ///
+ ///
+ public virtual bool HitTest(Point point)
+ {
+ Rectangle hitBounds = Bounds;
+ hitBounds.Inflate(3, 3);
+ return hitBounds.Contains(point);
+ }
+
+ ///
+ /// Handle the mouse down
+ ///
+ ///
+ ///
+ public virtual void MouseDown(object sender, MouseEventArgs mouseEventArgs)
+ {
+ }
+
+ ///
+ /// Handle the mouse move
+ ///
+ ///
+ ///
+ public virtual void MouseMove(object sender, MouseEventArgs mouseEventArgs)
+ {
+ }
+
+ ///
+ /// Handle the mouse up
+ ///
+ ///
+ ///
+ public virtual void MouseUp(object sender, MouseEventArgs mouseEventArgs)
+ {
+ EditStatus = EditStatus.IDLE;
+ }
+
+ ///
+ /// Return the location of the adorner
+ ///
+ public virtual Point Location
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Return the bounds of the Adorner
+ ///
+ public virtual Rectangle Bounds
+ {
+ get
+ {
+ Point location = Location;
+ return new Rectangle(location.X - (_size.Width / 2), location.Y - (_size.Height / 2), _size.Width, _size.Height);
+ }
+ }
+
+ ///
+ /// The adorner is active if the edit status is not idle or undrawn
+ ///
+ public virtual bool IsActive
+ {
+ get
+ {
+ return EditStatus != EditStatus.IDLE && EditStatus != EditStatus.UNDRAWN;
+ }
+ }
+
+ ///
+ /// Draw the adorner
+ ///
+ /// PaintEventArgs
+ public virtual void Paint(PaintEventArgs paintEventArgs)
+ {
+ }
+
+ ///
+ /// We ignore the Transform, as the coordinates are directly bound to those of the owner
+ ///
+ ///
+ public virtual void Transform(Matrix matrix)
+ {
+ }
+ }
+}
diff --git a/Greenshot/Drawing/Adorners/MoveAdorner.cs b/Greenshot/Drawing/Adorners/MoveAdorner.cs
new file mode 100644
index 000000000..78e00e2dd
--- /dev/null
+++ b/Greenshot/Drawing/Adorners/MoveAdorner.cs
@@ -0,0 +1,165 @@
+/*
+ * 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 .
+ */
+
+using Greenshot.Helpers;
+using Greenshot.Plugin.Drawing;
+using Greenshot.Plugin.Drawing.Adorners;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+
+namespace Greenshot.Drawing.Adorners
+{
+ ///
+ /// This is the adorner for the line based containers
+ ///
+ public class MoveAdorner : AbstractAdorner
+ {
+ private Rectangle _boundsBeforeResize = Rectangle.Empty;
+ private RectangleF _boundsAfterResize = RectangleF.Empty;
+
+ public Positions Position { get; private set; }
+
+ public MoveAdorner(IDrawableContainer owner, Positions position) : base(owner)
+ {
+ Position = position;
+ }
+
+ ///
+ /// Returns the cursor for when the mouse is over the adorner
+ ///
+ public override Cursor Cursor
+ {
+ get
+ {
+ return Cursors.SizeAll;
+ }
+ }
+
+ ///
+ /// Handle the mouse down
+ ///
+ ///
+ ///
+ public override void MouseDown(object sender, MouseEventArgs mouseEventArgs)
+ {
+ EditStatus = EditStatus.RESIZING;
+ _boundsBeforeResize = new Rectangle(Owner.Left, Owner.Top, Owner.Width, Owner.Height);
+ _boundsAfterResize = _boundsBeforeResize;
+ }
+
+ ///
+ /// Handle the mouse move
+ ///
+ ///
+ ///
+ public override void MouseMove(object sender, MouseEventArgs mouseEventArgs)
+ {
+ if (EditStatus != EditStatus.RESIZING)
+ {
+ return;
+ }
+ Owner.Invalidate();
+ Owner.MakeBoundsChangeUndoable(false);
+
+ // 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(mouseEventArgs.X, mouseEventArgs.Y), ScaleHelper.GetScaleOptions());
+
+ // apply scaled bounds to this DrawableContainer
+ Owner.ApplyBounds(_boundsAfterResize);
+
+ Owner.Invalidate();
+ }
+
+ ///
+ /// Return the location of the adorner
+ ///
+ public override 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);
+ }
+ }
+
+ ///
+ /// Draw the adorner
+ ///
+ /// PaintEventArgs
+ public override void Paint(PaintEventArgs paintEventArgs)
+ {
+ Graphics targetGraphics = paintEventArgs.Graphics;
+ Rectangle clipRectangle = paintEventArgs.ClipRectangle;
+
+ var bounds = Bounds;
+ GraphicsState state = targetGraphics.Save();
+
+ targetGraphics.SmoothingMode = SmoothingMode.None;
+ targetGraphics.CompositingMode = CompositingMode.SourceCopy;
+ targetGraphics.PixelOffsetMode = PixelOffsetMode.Half;
+ targetGraphics.InterpolationMode = InterpolationMode.NearestNeighbor;
+
+ targetGraphics.FillRectangle(Brushes.Black, bounds.X, bounds.Y, bounds.Width , bounds.Height);
+ targetGraphics.Restore(state);
+ }
+ }
+}
diff --git a/Greenshot/Drawing/Adorners/ResizeAdorner.cs b/Greenshot/Drawing/Adorners/ResizeAdorner.cs
new file mode 100644
index 000000000..da536b1f5
--- /dev/null
+++ b/Greenshot/Drawing/Adorners/ResizeAdorner.cs
@@ -0,0 +1,186 @@
+/*
+ * 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 .
+ */
+
+using Greenshot.Helpers;
+using Greenshot.Plugin.Drawing;
+using Greenshot.Plugin.Drawing.Adorners;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+
+namespace Greenshot.Drawing.Adorners
+{
+ ///
+ /// This is the default "legacy" gripper adorner, not the one used for the tail in the speech-bubble
+ ///
+ public class ResizeAdorner : AbstractAdorner
+ {
+ private Rectangle _boundsBeforeResize = Rectangle.Empty;
+ private RectangleF _boundsAfterResize = RectangleF.Empty;
+
+ public Positions Position { get; private set; }
+
+ public ResizeAdorner(IDrawableContainer owner, Positions position) : base(owner)
+ {
+ Position = position;
+ }
+
+ ///
+ /// Returns the cursor for when the mouse is over the adorner
+ ///
+ public override Cursor Cursor
+ {
+ get
+ {
+ bool isNotSwitched = Owner.Width >= 0;
+ if (Owner.Height < 0)
+ {
+ isNotSwitched = !isNotSwitched;
+ }
+ switch (Position)
+ {
+ case Positions.TopLeft:
+ case Positions.BottomRight:
+ return isNotSwitched ? Cursors.SizeNWSE : Cursors.SizeNESW;
+ case Positions.TopRight:
+ case Positions.BottomLeft:
+ return isNotSwitched ? 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;
+ }
+ }
+ }
+
+ ///
+ /// Handle the mouse down
+ ///
+ ///
+ ///
+ public override void MouseDown(object sender, MouseEventArgs mouseEventArgs)
+ {
+ EditStatus = EditStatus.RESIZING;
+ _boundsBeforeResize = new Rectangle(Owner.Left, Owner.Top, Owner.Width, Owner.Height);
+ _boundsAfterResize = _boundsBeforeResize;
+ }
+
+ ///
+ /// Handle the mouse move
+ ///
+ ///
+ ///
+ public override void MouseMove(object sender, MouseEventArgs mouseEventArgs)
+ {
+ if (EditStatus != EditStatus.RESIZING)
+ {
+ return;
+ }
+ Owner.Invalidate();
+ Owner.MakeBoundsChangeUndoable(false);
+
+ // 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(mouseEventArgs.X, mouseEventArgs.Y), ScaleHelper.GetScaleOptions());
+
+ // apply scaled bounds to this DrawableContainer
+ Owner.ApplyBounds(_boundsAfterResize);
+
+ Owner.Invalidate();
+ }
+
+ ///
+ /// Return the location of the adorner
+ ///
+ public override 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);
+ }
+ }
+
+ ///
+ /// Draw the adorner
+ ///
+ /// PaintEventArgs
+ public override void Paint(PaintEventArgs paintEventArgs)
+ {
+ Graphics targetGraphics = paintEventArgs.Graphics;
+ Rectangle clipRectangle = paintEventArgs.ClipRectangle;
+
+ var bounds = Bounds;
+ GraphicsState state = targetGraphics.Save();
+
+ targetGraphics.SmoothingMode = SmoothingMode.None;
+ targetGraphics.CompositingMode = CompositingMode.SourceCopy;
+ targetGraphics.PixelOffsetMode = PixelOffsetMode.Half;
+ targetGraphics.InterpolationMode = InterpolationMode.NearestNeighbor;
+
+ targetGraphics.FillRectangle(Brushes.Black, bounds.X, bounds.Y, bounds.Width , bounds.Height);
+ targetGraphics.Restore(state);
+ }
+ }
+}
diff --git a/Greenshot/Drawing/Adorners/TargetAdorner.cs b/Greenshot/Drawing/Adorners/TargetAdorner.cs
new file mode 100644
index 000000000..27e499bac
--- /dev/null
+++ b/Greenshot/Drawing/Adorners/TargetAdorner.cs
@@ -0,0 +1,119 @@
+/*
+ * 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 .
+ */
+
+using Greenshot.Plugin.Drawing;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+
+namespace Greenshot.Drawing.Adorners
+{
+ ///
+ /// This implements the special "gripper" for the Speech-Bubble tail
+ ///
+ public class TargetAdorner : AbstractAdorner
+ {
+
+ public TargetAdorner(IDrawableContainer owner, Point location) : base(owner)
+ {
+ Location = location;
+ }
+
+ ///
+ /// Handle the mouse down
+ ///
+ ///
+ ///
+ public override void MouseDown(object sender, MouseEventArgs mouseEventArgs)
+ {
+ EditStatus = EditStatus.MOVING;
+ }
+
+ ///
+ /// Handle the mouse move
+ ///
+ ///
+ ///
+ public override void MouseMove(object sender, MouseEventArgs mouseEventArgs)
+ {
+ if (EditStatus != EditStatus.MOVING)
+ {
+ return;
+ }
+
+ 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();
+ }
+
+ ///
+ /// Draw the adorner
+ ///
+ /// PaintEventArgs
+ public override void Paint(PaintEventArgs paintEventArgs)
+ {
+ Graphics targetGraphics = paintEventArgs.Graphics;
+ Rectangle clipRectangle = paintEventArgs.ClipRectangle;
+
+ var bounds = Bounds;
+ targetGraphics.FillRectangle(Brushes.Green, bounds.X, bounds.Y, bounds.Width, bounds.Height);
+ }
+
+ ///
+ /// Made sure this adorner is transformed
+ ///
+ /// Matrix
+ public override void Transform(Matrix matrix)
+ {
+ if (matrix == null)
+ {
+ return;
+ }
+ Point[] points = new[] { Location };
+ matrix.TransformPoints(points);
+ Location = points[0];
+ }
+ }
+}
diff --git a/Greenshot/Drawing/CropContainer.cs b/Greenshot/Drawing/CropContainer.cs
index 676836f93..e1bf7a78a 100644
--- a/Greenshot/Drawing/CropContainer.cs
+++ b/Greenshot/Drawing/CropContainer.cs
@@ -20,6 +20,7 @@
*/
using System.Drawing;
+using System.Runtime.Serialization;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
@@ -30,8 +31,19 @@ namespace Greenshot.Drawing {
///
public class CropContainer : DrawableContainer {
public CropContainer(Surface parent) : base(parent) {
+ Init();
}
+ protected override void OnDeserialized(StreamingContext streamingContext)
+ {
+ base.OnDeserialized(streamingContext);
+ Init();
+ }
+
+ private void Init()
+ {
+ CreateDefaultAdorners();
+ }
protected override void InitializeFields() {
AddField(GetType(), FieldType.FLAGS, FieldType.Flag.CONFIRMABLE);
}
diff --git a/Greenshot/Drawing/CursorContainer.cs b/Greenshot/Drawing/CursorContainer.cs
index 2b5969c92..98bc77358 100644
--- a/Greenshot/Drawing/CursorContainer.cs
+++ b/Greenshot/Drawing/CursorContainer.cs
@@ -26,6 +26,7 @@ using System.Windows.Forms;
using Greenshot.Plugin.Drawing;
using System.Drawing.Drawing2D;
using log4net;
+using System.Runtime.Serialization;
namespace Greenshot.Drawing {
///
@@ -38,9 +39,21 @@ namespace Greenshot.Drawing {
protected Cursor cursor;
public CursorContainer(Surface parent) : base(parent) {
+ Init();
}
- public CursorContainer(Surface parent, string filename) : base(parent) {
+ protected override void OnDeserialized(StreamingContext streamingContext)
+ {
+ base.OnDeserialized(streamingContext);
+ Init();
+ }
+
+ private void Init()
+ {
+ CreateDefaultAdorners();
+ }
+
+ public CursorContainer(Surface parent, string filename) : this(parent) {
Load(filename);
}
diff --git a/Greenshot/Drawing/DrawableContainer.cs b/Greenshot/Drawing/DrawableContainer.cs
index 9b3a10952..f65480b2b 100644
--- a/Greenshot/Drawing/DrawableContainer.cs
+++ b/Greenshot/Drawing/DrawableContainer.cs
@@ -20,6 +20,7 @@
*/
using Greenshot.Configuration;
+using Greenshot.Drawing.Adorners;
using Greenshot.Drawing.Fields;
using Greenshot.Drawing.Filters;
using Greenshot.Helpers;
@@ -27,15 +28,18 @@ 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;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
+using System.Runtime.Serialization;
using System.Windows.Forms;
-namespace Greenshot.Drawing {
+namespace Greenshot.Drawing
+{
///
/// represents a rectangle, ellipse, label or whatever. Can contain filters, too.
/// serializable for clipboard support
@@ -46,10 +50,23 @@ namespace Greenshot.Drawing {
public abstract class DrawableContainer : AbstractFieldHolderWithChildren, IDrawableContainer {
private static readonly ILog LOG = LogManager.GetLogger(typeof(DrawableContainer));
protected static readonly EditorConfiguration EditorConfig = IniConfig.GetIniSection();
- private bool _isMadeUndoable;
private const int M11 = 0;
private const int M22 = 3;
+ [OnDeserialized]
+ private void OnDeserializedInit(StreamingContext context)
+ {
+ _adorners = new List();
+ OnDeserialized(context);
+ }
+
+ ///
+ /// Override to implement your own deserialization logic, like initializing properties which are not serialized
+ ///
+ ///
+ protected virtual void OnDeserialized(StreamingContext streamingContext)
+ {
+ }
protected EditStatus _defaultEditMode = EditStatus.DRAWING;
public EditStatus DefaultEditMode {
@@ -71,16 +88,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);
@@ -115,14 +122,10 @@ namespace Greenshot.Drawing {
get { return _parent; }
set { SwitchParent((Surface)value); }
}
- [NonSerialized]
- protected Gripper[] _grippers;
- private bool layoutSuspended;
[NonSerialized]
- private Gripper _targetGripper;
-
- public Gripper TargetGripper {
+ private TargetAdorner _targetGripper;
+ public TargetAdorner TargetGripper {
get {
return _targetGripper;
}
@@ -158,7 +161,6 @@ namespace Greenshot.Drawing {
return;
}
left = value;
- DoLayout();
}
}
@@ -170,7 +172,6 @@ namespace Greenshot.Drawing {
return;
}
top = value;
- DoLayout();
}
}
@@ -182,7 +183,6 @@ namespace Greenshot.Drawing {
return;
}
width = value;
- DoLayout();
}
}
@@ -194,7 +194,6 @@ namespace Greenshot.Drawing {
return;
}
height = value;
- DoLayout();
}
}
@@ -218,6 +217,19 @@ namespace Greenshot.Drawing {
}
}
+ ///
+ /// List of available Adorners
+ ///
+ [NonSerialized]
+ private IList _adorners = new List();
+ public IList Adorners
+ {
+ get
+ {
+ return _adorners;
+ }
+ }
+
[NonSerialized]
// will store current bounds of this DrawableContainer before starting a resize
protected Rectangle _boundsBeforeResize = Rectangle.Empty;
@@ -246,7 +258,6 @@ namespace Greenshot.Drawing {
public DrawableContainer(Surface parent) {
InitializeFields();
_parent = parent;
- InitControls();
}
public void Add(IFilter filter) {
@@ -303,7 +314,7 @@ namespace Greenshot.Drawing {
Left = _parent.Width - Width - lineThickness/2;
}
if (horizontalAlignment == HorizontalAlignment.Center) {
- Left = _parent.Width / 2 - Width / 2 - lineThickness/2;
+ Left = (_parent.Width / 2) - (Width / 2) - lineThickness/2;
}
if (verticalAlignment == VerticalAlignment.TOP) {
@@ -313,195 +324,42 @@ namespace Greenshot.Drawing {
Top = _parent.Height - Height - lineThickness/2;
}
if (verticalAlignment == VerticalAlignment.CENTER) {
- Top = _parent.Height / 2 - Height / 2 - lineThickness/2;
+ Top = (_parent.Height / 2) - (Height / 2) - lineThickness/2;
}
}
public virtual bool InitContent() { return true; }
public virtual void OnDoubleClick() {}
-
- private void InitControls() {
- InitGrippers();
-
- DoLayout();
- }
-
- ///
- /// Move the TargetGripper around, confined to the surface to solve BUG-1682
- ///
- ///
- ///
- 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;
- }
///
/// Initialize a target gripper
///
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);
+ Adorners.Add(_targetGripper);
}
- 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
- }
- }
-
- public void SuspendLayout() {
- layoutSuspended = true;
- }
-
- public void ResumeLayout() {
- layoutSuspended = false;
- 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};
+ ///
+ /// Create the default adorners for a rectangle based container
+ ///
- _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;
- }
+ protected void CreateDefaultAdorners() {
+ if (Adorners.Count > 0)
+ {
+ LOG.Warn("Adorners are already defined!");
}
- }
-
- 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;
+ // Create the GripperAdorners
+ Adorners.Add(new ResizeAdorner(this, Positions.TopLeft));
+ Adorners.Add(new ResizeAdorner(this, Positions.TopCenter));
+ Adorners.Add(new ResizeAdorner(this, Positions.TopRight));
+ Adorners.Add(new ResizeAdorner(this, Positions.BottomLeft));
+ Adorners.Add(new ResizeAdorner(this, Positions.BottomCenter));
+ Adorners.Add(new ResizeAdorner(this, Positions.BottomRight));
+ Adorners.Add(new ResizeAdorner(this, Positions.MiddleLeft));
+ Adorners.Add(new ResizeAdorner(this, Positions.MiddleRight));
}
- 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 {
get {
return Filters.Count > 0;
@@ -556,43 +414,10 @@ 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;
Height = height;
- ResumeLayout();
}
///
@@ -604,10 +429,8 @@ namespace Greenshot.Drawing {
}
public void MoveBy(int dx, int dy) {
- SuspendLayout();
Left += dx;
Top += dy;
- ResumeLayout();
}
///
@@ -630,7 +453,6 @@ namespace Greenshot.Drawing {
/// true if the event is handled, false if the surface needs to handle it
public virtual bool HandleMouseMove(int x, int y) {
Invalidate();
- SuspendLayout();
// reset "workrbench" rectangle to current bounds
_boundsAfterResize.X = _boundsBeforeResize.Left;
@@ -643,7 +465,6 @@ namespace Greenshot.Drawing {
// apply scaled bounds to this DrawableContainer
ApplyBounds(_boundsAfterResize);
- ResumeLayout();
Invalidate();
return true;
}
@@ -657,28 +478,8 @@ 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);
- }
+ _parent = newParent;
foreach(IFilter filter in Filters) {
filter.Parent = this;
}
@@ -775,26 +576,16 @@ namespace Greenshot.Drawing {
if (matrix == null) {
return;
}
- 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();
+
}
protected virtual ScaleHelper.IDoubleProcessor GetAngleRoundProcessor() {
diff --git a/Greenshot/Drawing/DrawableContainerList.cs b/Greenshot/Drawing/DrawableContainerList.cs
index 46daf9773..692295966 100644
--- a/Greenshot/Drawing/DrawableContainerList.cs
+++ b/Greenshot/Drawing/DrawableContainerList.cs
@@ -171,26 +171,6 @@ namespace Greenshot.Drawing {
}
}
- ///
- /// Hides the grippers of all elements in the list.
- ///
- public void HideGrippers() {
- foreach(var dc in this) {
- dc.HideGrippers();
- dc.Invalidate();
- }
- }
-
- ///
- /// Shows the grippers of all elements in the list.
- ///
- public void ShowGrippers() {
- foreach(var dc in this) {
- dc.ShowGrippers();
- dc.Invalidate();
- }
- }
-
///
/// Indicates whether on of the elements is clickable at the given location
///
diff --git a/Greenshot/Drawing/EllipseContainer.cs b/Greenshot/Drawing/EllipseContainer.cs
index c4fe278e1..9ccec37f3 100644
--- a/Greenshot/Drawing/EllipseContainer.cs
+++ b/Greenshot/Drawing/EllipseContainer.cs
@@ -33,6 +33,7 @@ namespace Greenshot.Drawing {
[Serializable()]
public class EllipseContainer : DrawableContainer {
public EllipseContainer(Surface parent) : base(parent) {
+ CreateDefaultAdorners();
}
protected override void InitializeFields() {
diff --git a/Greenshot/Drawing/Fields/AbstractFieldHolder.cs b/Greenshot/Drawing/Fields/AbstractFieldHolder.cs
index 4bb0316fb..1c4a98037 100644
--- a/Greenshot/Drawing/Fields/AbstractFieldHolder.cs
+++ b/Greenshot/Drawing/Fields/AbstractFieldHolder.cs
@@ -53,7 +53,7 @@ namespace Greenshot.Drawing.Fields {
private readonly List fields = new List();
[OnDeserialized]
- private void OnDeserialized(StreamingContext context) {
+ private void OnFieldHolderDeserialized(StreamingContext context) {
fieldsByType = new Dictionary();
// listen to changing properties
foreach(Field field in fields) {
diff --git a/Greenshot/Drawing/Fields/AbstractFieldHolderWithChildren.cs b/Greenshot/Drawing/Fields/AbstractFieldHolderWithChildren.cs
index 3114ffc46..a81308d0e 100644
--- a/Greenshot/Drawing/Fields/AbstractFieldHolderWithChildren.cs
+++ b/Greenshot/Drawing/Fields/AbstractFieldHolderWithChildren.cs
@@ -45,8 +45,8 @@ namespace Greenshot.Drawing.Fields {
fieldChangedEventHandler = OnFieldChanged;
}
- [OnDeserialized()]
- private void OnDeserialized(StreamingContext context) {
+ [OnDeserialized]
+ private void OnFieldHolderWithChildrenDeserialized(StreamingContext context) {
// listen to changing properties
foreach(IFieldHolder fieldHolder in Children) {
fieldHolder.FieldChanged += fieldChangedEventHandler;
diff --git a/Greenshot/Drawing/FilterContainer.cs b/Greenshot/Drawing/FilterContainer.cs
index 7e6b2336e..1607fbdf4 100644
--- a/Greenshot/Drawing/FilterContainer.cs
+++ b/Greenshot/Drawing/FilterContainer.cs
@@ -24,6 +24,7 @@ using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
using System.Drawing.Drawing2D;
+using System.Runtime.Serialization;
namespace Greenshot.Drawing {
///
@@ -40,6 +41,18 @@ namespace Greenshot.Drawing {
}
public FilterContainer(Surface parent) : base(parent) {
+ Init();
+ }
+
+ protected override void OnDeserialized(StreamingContext streamingContext)
+ {
+ base.OnDeserialized(streamingContext);
+ Init();
+ }
+
+ private void Init()
+ {
+ CreateDefaultAdorners();
}
protected override void InitializeFields() {
diff --git a/Greenshot/Drawing/FreehandContainer.cs b/Greenshot/Drawing/FreehandContainer.cs
index 5294f5bd5..ec927017b 100644
--- a/Greenshot/Drawing/FreehandContainer.cs
+++ b/Greenshot/Drawing/FreehandContainer.cs
@@ -47,7 +47,6 @@ namespace Greenshot.Drawing {
/// Constructor
///
public FreehandContainer(Surface parent) : base(parent) {
- Init();
Width = parent.Width;
Height = parent.Height;
Top = 0;
@@ -59,16 +58,6 @@ namespace Greenshot.Drawing {
AddField(GetType(), FieldType.LINE_COLOR, Color.Red);
}
-
- protected void Init() {
- if (_grippers != null) {
- for (int i = 0; i < _grippers.Length; i++) {
- _grippers[i].Enabled = false;
- _grippers[i].Visible = false;
- }
- }
- }
-
public override void Transform(Matrix matrix) {
Point[] points = capturePoints.ToArray();
@@ -78,11 +67,7 @@ namespace Greenshot.Drawing {
RecalculatePath();
}
- [OnDeserialized]
- private void OnDeserialized(StreamingContext context) {
- InitGrippers();
- DoLayout();
- Init();
+ protected override void OnDeserialized(StreamingContext context) {
RecalculatePath();
}
@@ -256,17 +241,6 @@ namespace Greenshot.Drawing {
return freehandPath.GetHashCode();
}
- ///
- /// This is overriden to prevent the grippers to be modified.
- /// Might not be the best way...
- ///
- protected override void DoLayout() {
- }
-
- public override void ShowGrippers() {
- ResumeLayout();
- }
-
public override bool ClickableAt(int x, int y) {
bool returnValue = base.ClickableAt(x, y);
if (returnValue) {
diff --git a/Greenshot/Drawing/HighlightContainer.cs b/Greenshot/Drawing/HighlightContainer.cs
index 701592539..5b8b783e2 100644
--- a/Greenshot/Drawing/HighlightContainer.cs
+++ b/Greenshot/Drawing/HighlightContainer.cs
@@ -42,8 +42,8 @@ namespace Greenshot.Drawing {
AddField(GetType(), FieldType.PREPARED_FILTER_HIGHLIGHT, PreparedFilter.TEXT_HIGHTLIGHT);
}
- [OnDeserialized]
- private void OnDeserialized(StreamingContext context) {
+ protected override void OnDeserialized(StreamingContext context)
+ {
Init();
}
diff --git a/Greenshot/Drawing/IconContainer.cs b/Greenshot/Drawing/IconContainer.cs
index 846ee3cde..a72b39496 100644
--- a/Greenshot/Drawing/IconContainer.cs
+++ b/Greenshot/Drawing/IconContainer.cs
@@ -24,6 +24,7 @@ using System.IO;
using Greenshot.Plugin.Drawing;
using System.Drawing.Drawing2D;
using log4net;
+using System.Runtime.Serialization;
namespace Greenshot.Drawing {
///
@@ -36,6 +37,18 @@ namespace Greenshot.Drawing {
protected Icon icon;
public IconContainer(Surface parent) : base(parent) {
+ Init();
+ }
+
+ protected override void OnDeserialized(StreamingContext streamingContext)
+ {
+ base.OnDeserialized(streamingContext);
+ Init();
+ }
+
+ private void Init()
+ {
+ CreateDefaultAdorners();
}
public IconContainer(Surface parent, string filename) : base(parent) {
diff --git a/Greenshot/Drawing/ImageContainer.cs b/Greenshot/Drawing/ImageContainer.cs
index 25894af74..ca1742195 100644
--- a/Greenshot/Drawing/ImageContainer.cs
+++ b/Greenshot/Drawing/ImageContainer.cs
@@ -27,6 +27,7 @@ using GreenshotPlugin.Core;
using System.Drawing.Drawing2D;
using Greenshot.Core;
using log4net;
+using System.Runtime.Serialization;
namespace Greenshot.Drawing {
///
@@ -58,6 +59,18 @@ namespace Greenshot.Drawing {
public ImageContainer(Surface parent) : base(parent) {
FieldChanged += BitmapContainer_OnFieldChanged;
+ Init();
+ }
+
+ protected override void OnDeserialized(StreamingContext streamingContext)
+ {
+ base.OnDeserialized(streamingContext);
+ Init();
+ }
+
+ private void Init()
+ {
+ CreateDefaultAdorners();
}
protected override void InitializeFields() {
diff --git a/Greenshot/Drawing/LineContainer.cs b/Greenshot/Drawing/LineContainer.cs
index b11486901..47776ff00 100644
--- a/Greenshot/Drawing/LineContainer.cs
+++ b/Greenshot/Drawing/LineContainer.cs
@@ -26,6 +26,7 @@ using System.Runtime.Serialization;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
+using Greenshot.Drawing.Adorners;
namespace Greenshot.Drawing {
///
@@ -45,19 +46,14 @@ namespace Greenshot.Drawing {
AddField(GetType(), FieldType.SHADOW, true);
}
- [OnDeserialized()]
- private void OnDeserialized(StreamingContext context) {
- InitGrippers();
- DoLayout();
+ protected override void OnDeserialized(StreamingContext context)
+ {
Init();
}
protected void Init() {
- if (_grippers != null) {
- foreach (int index in new[] { 1, 2, 3, 5, 6, 7 }) {
- _grippers[index].Enabled = false;
- }
- }
+ Adorners.Add(new MoveAdorner(this, Positions.TopLeft));
+ Adorners.Add(new MoveAdorner(this, Positions.BottomRight));
}
public override void Draw(Graphics graphics, RenderMode rm) {
@@ -113,8 +109,6 @@ namespace Greenshot.Drawing {
protected override ScaleHelper.IDoubleProcessor GetAngleRoundProcessor() {
return ScaleHelper.LineAngleRoundBehavior.Instance;
- }
-
-
+ }
}
}
diff --git a/Greenshot/Drawing/ObfuscateContainer.cs b/Greenshot/Drawing/ObfuscateContainer.cs
index 80f395c31..032291527 100644
--- a/Greenshot/Drawing/ObfuscateContainer.cs
+++ b/Greenshot/Drawing/ObfuscateContainer.cs
@@ -37,15 +37,16 @@ namespace Greenshot.Drawing {
base.InitializeFields();
AddField(GetType(), FieldType.PREPARED_FILTER_OBFUSCATE, PreparedFilter.PIXELIZE);
}
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext context) {
+
+ protected override void OnDeserialized(StreamingContext context)
+ {
Init();
}
private void Init() {
FieldChanged += ObfuscateContainer_OnFieldChanged;
ConfigurePreparedFilters();
+ CreateDefaultAdorners();
}
protected void ObfuscateContainer_OnFieldChanged(object sender, FieldChangedEventArgs e) {
diff --git a/Greenshot/Drawing/Gripper.cs b/Greenshot/Drawing/Positions.cs
similarity index 54%
rename from Greenshot/Drawing/Gripper.cs
rename to Greenshot/Drawing/Positions.cs
index 7a65fc57a..63d7cb759 100644
--- a/Greenshot/Drawing/Gripper.cs
+++ b/Greenshot/Drawing/Positions.cs
@@ -19,38 +19,20 @@
* along with this program. If not, see .
*/
-using System.Drawing;
-using System.Windows.Forms;
-
-namespace Greenshot.Drawing {
+namespace Greenshot.Drawing
+{
///
- /// Grippers are the dragable edges of our containers
+ /// Position
///
- public class Gripper : Label {
- ///
- /// Constants for anchor/gripper position:
- /// 0 1 2
- /// 7 3
- /// 6 5 4
- ///
- public const int POSITION_TOP_LEFT = 0;
- public const int POSITION_TOP_CENTER = 1;
- public const int POSITION_TOP_RIGHT = 2;
- 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;
- }
+ public enum Positions : int
+ {
+ TopLeft = 0,
+ TopCenter = 1,
+ TopRight = 2,
+ MiddleRight = 3,
+ BottomRight = 4,
+ BottomCenter = 5,
+ BottomLeft = 6,
+ MiddleLeft = 7
}
}
diff --git a/Greenshot/Drawing/RectangleContainer.cs b/Greenshot/Drawing/RectangleContainer.cs
index 933adb180..d12f215eb 100644
--- a/Greenshot/Drawing/RectangleContainer.cs
+++ b/Greenshot/Drawing/RectangleContainer.cs
@@ -25,6 +25,7 @@ using System.Drawing.Drawing2D;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
+using System.Runtime.Serialization;
namespace Greenshot.Drawing {
///
@@ -34,6 +35,22 @@ namespace Greenshot.Drawing {
public class RectangleContainer : DrawableContainer {
public RectangleContainer(Surface parent) : base(parent) {
+ Init();
+ }
+
+ ///
+ /// Do some logic to make sure all field are initiated correctly
+ ///
+ /// StreamingContext
+ protected override void OnDeserialized(StreamingContext streamingContext)
+ {
+ base.OnDeserialized(streamingContext);
+ Init();
+ }
+
+ private void Init()
+ {
+ CreateDefaultAdorners();
}
protected override void InitializeFields() {
diff --git a/Greenshot/Drawing/SpeechbubbleContainer.cs b/Greenshot/Drawing/SpeechbubbleContainer.cs
index 4bbc91c29..f49768329 100644
--- a/Greenshot/Drawing/SpeechbubbleContainer.cs
+++ b/Greenshot/Drawing/SpeechbubbleContainer.cs
@@ -28,7 +28,8 @@ using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Runtime.Serialization;
-namespace Greenshot.Drawing {
+namespace Greenshot.Drawing
+{
///
/// Description of SpeechbubbleContainer.
///
@@ -56,8 +57,8 @@ namespace Greenshot.Drawing {
/// Restore the target gripper
///
///
- [OnDeserialized]
- private void SetValuesOnDeserialized(StreamingContext context) {
+ protected override void OnDeserialized(StreamingContext context)
+ {
InitTargetGripper(Color.Green, _storedTargetGripperLocation);
}
#endregion
@@ -115,7 +116,7 @@ namespace Greenshot.Drawing {
if (TargetGripper.Location != newGripperLocation) {
Invalidate();
- TargetGripperMove(newGripperLocation.X, newGripperLocation.Y);
+ TargetGripper.Location = newGripperLocation;
Invalidate();
}
return returnValue;
@@ -177,8 +178,7 @@ namespace Greenshot.Drawing {
private GraphicsPath CreateTail() {
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 tailWidth = (Math.Abs(rect.Width) + Math.Abs(rect.Height)) / 20;
+ int tailLength = GeometryHelper.Distance2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetGripper.Left, TargetGripper.Top); int tailWidth = (Math.Abs(rect.Width) + Math.Abs(rect.Height)) / 20;
// This should fix a problem with the tail being to wide
tailWidth = Math.Min(Math.Abs(rect.Width) / 2, tailWidth);
@@ -189,7 +189,6 @@ namespace Greenshot.Drawing {
tail.AddLine(tailWidth, 0, 0, -tailLength);
tail.CloseFigure();
- int tailAngle = 90 + (int)GeometryHelper.Angle2D(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2, TargetGripper.Left, TargetGripper.Top);
using (Matrix tailMatrix = new Matrix()) {
tailMatrix.Translate(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2);
diff --git a/Greenshot/Drawing/StepLabelContainer.cs b/Greenshot/Drawing/StepLabelContainer.cs
index e42076c82..636fd4540 100644
--- a/Greenshot/Drawing/StepLabelContainer.cs
+++ b/Greenshot/Drawing/StepLabelContainer.cs
@@ -45,6 +45,12 @@ namespace Greenshot.Drawing {
public StepLabelContainer(Surface parent) : base(parent) {
parent.AddStepLabel(this);
InitContent();
+ Init();
+ }
+
+ private void Init()
+ {
+ CreateDefaultAdorners();
}
#region Number serializing
@@ -75,8 +81,9 @@ namespace Greenshot.Drawing {
/// Restore values that don't serialize
///
///
- [OnDeserialized]
- private void SetValuesOnDeserialized(StreamingContext context) {
+ protected override void OnDeserialized(StreamingContext context)
+ {
+ Init();
_stringFormat = new StringFormat();
_stringFormat.Alignment = StringAlignment.Center;
_stringFormat.LineAlignment = StringAlignment.Center;
diff --git a/Greenshot/Drawing/Surface.cs b/Greenshot/Drawing/Surface.cs
index 22c1aea93..13dec90c0 100644
--- a/Greenshot/Drawing/Surface.cs
+++ b/Greenshot/Drawing/Surface.cs
@@ -27,6 +27,7 @@ using Greenshot.IniFile;
using Greenshot.Memento;
using Greenshot.Plugin;
using Greenshot.Plugin.Drawing;
+using Greenshot.Plugin.Drawing.Adorners;
using GreenshotPlugin.Controls;
using GreenshotPlugin.Core;
using log4net;
@@ -40,7 +41,8 @@ using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
-namespace Greenshot.Drawing {
+namespace Greenshot.Drawing
+{
///
/// Description of Surface.
@@ -991,12 +993,46 @@ namespace Greenshot.Drawing {
Invalidate();
}
+ ///
+ /// Check if an adorner was "hit", and change the cursor if so
+ ///
+ /// MouseEventArgs
+ /// IAdorner
+ private IAdorner FindActiveAdorner(MouseEventArgs mouseEventArgs)
+ {
+ foreach(IDrawableContainer drawableContainer in selectedElements)
+ {
+ foreach(IAdorner adorner in drawableContainer.Adorners)
+ {
+
+ if (adorner.IsActive || adorner.HitTest(mouseEventArgs.Location))
+ {
+ if (adorner.Cursor != null)
+ {
+ Cursor = adorner.Cursor;
+ }
+ return adorner;
+ }
+ }
+ }
+ return null;
+ }
+
///
/// This event handler is called when someone presses the mouse on a surface.
///
///
///
void SurfaceMouseDown(object sender, MouseEventArgs e) {
+
+ // Handle Adorners
+ var adorner = FindActiveAdorner(e);
+ if (adorner != null)
+ {
+ adorner.MouseDown(sender, e);
+ return;
+ }
+
_mouseStart = e.Location;
// check contextmenu
@@ -1068,6 +1104,15 @@ namespace Greenshot.Drawing {
///
///
void SurfaceMouseUp(object sender, MouseEventArgs e) {
+
+ // Handle Adorners
+ var adorner = FindActiveAdorner(e);
+ if (adorner != null)
+ {
+ adorner.MouseUp(sender, e);
+ return;
+ }
+
Point currentMouse = new Point(e.X, e.Y);
_elements.Status = EditStatus.IDLE;
@@ -1101,7 +1146,7 @@ namespace Greenshot.Drawing {
}
if (selectedElements.Count > 0) {
- selectedElements.ShowGrippers();
+ selectedElements.Invalidate();
selectedElements.Selected = true;
}
@@ -1129,6 +1174,14 @@ namespace Greenshot.Drawing {
///
///
void SurfaceMouseMove(object sender, MouseEventArgs e) {
+ // Handle Adorners
+ var adorner = FindActiveAdorner(e);
+ if (adorner != null)
+ {
+ adorner.MouseMove(sender, e);
+ return;
+ }
+
Point currentMouse = e.Location;
if (DrawingMode != DrawingModes.None) {
@@ -1140,7 +1193,7 @@ namespace Greenshot.Drawing {
if (_mouseDown) {
if (_mouseDownElement != null) { // an element is currently dragged
_mouseDownElement.Invalidate();
- selectedElements.HideGrippers();
+ selectedElements.Invalidate();
// Move the element
if (_mouseDownElement.Selected) {
if (!_isSurfaceMoveMadeUndoable) {
@@ -1206,15 +1259,15 @@ namespace Greenshot.Drawing {
public Image GetImageForExport() {
return GetImage(RenderMode.EXPORT);
}
-
+
///
/// This is the event handler for the Paint Event, try to draw as little as possible!
///
///
- ///
- void SurfacePaint(object sender, PaintEventArgs e) {
- Graphics targetGraphics = e.Graphics;
- Rectangle clipRectangle = e.ClipRectangle;
+ /// PaintEventArgs
+ void SurfacePaint(object sender, PaintEventArgs paintEventArgs) {
+ Graphics targetGraphics = paintEventArgs.Graphics;
+ Rectangle clipRectangle = paintEventArgs.ClipRectangle;
if (Rectangle.Empty.Equals(clipRectangle)) {
LOG.Debug("Empty cliprectangle??");
return;
@@ -1249,6 +1302,17 @@ namespace Greenshot.Drawing {
targetGraphics.DrawImage(Image, clipRectangle, clipRectangle, GraphicsUnit.Pixel);
_elements.Draw(targetGraphics, null, RenderMode.EDIT, clipRectangle);
}
+
+ // No clipping for the adorners
+ targetGraphics.ResetClip();
+ // Draw adorners last
+ foreach (var drawableContainer in selectedElements)
+ {
+ foreach(var adorner in drawableContainer.Adorners)
+ {
+ adorner.Paint(paintEventArgs);
+ }
+ }
}
private void DrawBackground(Graphics targetGraphics, Rectangle clipRectangle) {
@@ -1539,9 +1603,9 @@ namespace Greenshot.Drawing {
///
///
public void DeselectElement(IDrawableContainer container) {
- container.HideGrippers();
container.Selected = false;
selectedElements.Remove(container);
+ container.Invalidate();
FieldAggregator.UnbindElement(container);
if (_movingElementChanged != null) {
SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs();
@@ -1557,10 +1621,9 @@ namespace Greenshot.Drawing {
if (HasSelectedElements) {
while(selectedElements.Count > 0) {
IDrawableContainer element = selectedElements[0];
- element.Invalidate();
- element.HideGrippers();
element.Selected = false;
selectedElements.Remove(element);
+ element.Invalidate();
FieldAggregator.UnbindElement(element);
}
if (_movingElementChanged != null) {
@@ -1578,7 +1641,6 @@ namespace Greenshot.Drawing {
public void SelectElement(IDrawableContainer container) {
if (!selectedElements.Contains(container)) {
selectedElements.Add(container);
- container.ShowGrippers();
container.Selected = true;
FieldAggregator.BindElement(container);
if (_movingElementChanged != null) {
diff --git a/Greenshot/Drawing/TextContainer.cs b/Greenshot/Drawing/TextContainer.cs
index 6c58e2683..1b369ea78 100644
--- a/Greenshot/Drawing/TextContainer.cs
+++ b/Greenshot/Drawing/TextContainer.cs
@@ -97,9 +97,13 @@ namespace Greenshot.Drawing {
AddField(GetType(), FieldType.TEXT_HORIZONTAL_ALIGNMENT, StringAlignment.Center);
AddField(GetType(), FieldType.TEXT_VERTICAL_ALIGNMENT, StringAlignment.Center);
}
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext context) {
+
+ ///
+ /// Do some logic to make sure all field are initiated correctly
+ ///
+ /// StreamingContext
+ protected override void OnDeserialized(StreamingContext streamingContext) {
+ base.OnDeserialized(streamingContext);
Init();
}
diff --git a/Greenshot/Greenshot.csproj b/Greenshot/Greenshot.csproj
index ee50aa76a..0fc6043a0 100644
--- a/Greenshot/Greenshot.csproj
+++ b/Greenshot/Greenshot.csproj
@@ -75,7 +75,12 @@
+
+
+
+
+
@@ -101,9 +106,6 @@
-
- Component
-
diff --git a/Greenshot/Helpers/ScaleHelper.cs b/Greenshot/Helpers/ScaleHelper.cs
index 7f348b932..2af56cb2f 100644
--- a/Greenshot/Helpers/ScaleHelper.cs
+++ b/Greenshot/Helpers/ScaleHelper.cs
@@ -116,15 +116,15 @@ namespace Greenshot.Helpers {
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);
}
- 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);
}
- 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);
}
@@ -135,7 +135,7 @@ namespace Greenshot.Helpers {
/// position of the handle/gripper being used for resized, see constants in Gripper.cs, e.g. Gripper.POSITION_TOP_LEFT
/// coordinates of the used handle/gripper
/// ScaleOptions to use when scaling
- 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) {
options = GetScaleOptions();
}
@@ -154,7 +154,7 @@ namespace Greenshot.Helpers {
resizeHandleCoords.X -= 2 * (resizeHandleCoords.X - rectCenterX);
resizeHandleCoords.Y -= 2 * (resizeHandleCoords.Y - rectCenterY);
// scale again with opposing handle and mirrored coordinates
- resizeHandlePosition = (resizeHandlePosition + 4) % 8;
+ resizeHandlePosition = (Positions)((((int)resizeHandlePosition) + 4) % 8);
scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords);
} else {
scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords);
@@ -168,47 +168,47 @@ namespace Greenshot.Helpers {
/// bounds of the current rectangle, scaled values will be written to this reference
/// position of the handle/gripper being used for resized, see constants in Gripper.cs, e.g. Gripper.POSITION_TOP_LEFT
/// coordinates of the used handle/gripper
- private static void scale(ref RectangleF originalRectangle, int resizeHandlePosition, PointF resizeHandleCoords) {
+ private static void scale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords) {
switch(resizeHandlePosition) {
- case Gripper.POSITION_TOP_LEFT:
+ case Positions.TopLeft:
originalRectangle.Width = originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X;
originalRectangle.Height = originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y;
originalRectangle.X = resizeHandleCoords.X;
originalRectangle.Y = resizeHandleCoords.Y;
break;
- case Gripper.POSITION_TOP_CENTER:
+ case Positions.TopCenter:
originalRectangle.Height = originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y;
originalRectangle.Y = resizeHandleCoords.Y;
break;
- case Gripper.POSITION_TOP_RIGHT:
+ case Positions.TopRight:
originalRectangle.Width = resizeHandleCoords.X - originalRectangle.Left;
originalRectangle.Height = originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y;
originalRectangle.Y = resizeHandleCoords.Y;
break;
- case Gripper.POSITION_MIDDLE_LEFT:
+ case Positions.MiddleLeft:
originalRectangle.Width = originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X;
originalRectangle.X = resizeHandleCoords.X;
break;
- case Gripper.POSITION_MIDDLE_RIGHT:
+ case Positions.MiddleRight:
originalRectangle.Width = resizeHandleCoords.X - originalRectangle.Left;
break;
- case Gripper.POSITION_BOTTOM_LEFT:
+ case Positions.BottomLeft:
originalRectangle.Width = originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X;
originalRectangle.Height = resizeHandleCoords.Y - originalRectangle.Top;
originalRectangle.X = resizeHandleCoords.X;
break;
- case Gripper.POSITION_BOTTOM_CENTER:
+ case Positions.BottomCenter:
originalRectangle.Height = resizeHandleCoords.Y - originalRectangle.Top;
break;
- case Gripper.POSITION_BOTTOM_RIGHT:
+ case Positions.BottomRight:
originalRectangle.Width = resizeHandleCoords.X - originalRectangle.Left;
originalRectangle.Height = resizeHandleCoords.Y - originalRectangle.Top;
break;
@@ -218,19 +218,19 @@ namespace Greenshot.Helpers {
}
}
-
+
///
/// Adjusts resizeHandleCoords so that aspect ratio is kept after resizing a given rectangle with provided arguments
///
/// bounds of the current rectangle
- /// position of the handle/gripper being used for resized, see constants in Gripper.cs, e.g. Gripper.POSITION_TOP_LEFT
+ /// position of the handle/gripper being used for resized, see Position
/// coordinates of the used handle/gripper, adjusted coordinates will be written to this reference
- 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 newWidth, newHeight, newRatio;
switch(resizeHandlePosition) {
- case Gripper.POSITION_TOP_LEFT:
+ case Positions.TopLeft:
newWidth = originalRectangle.Right - resizeHandleCoords.X;
newHeight = originalRectangle.Bottom - resizeHandleCoords.Y;
newRatio = newWidth / newHeight;
@@ -241,7 +241,7 @@ namespace Greenshot.Helpers {
}
break;
- case Gripper.POSITION_TOP_RIGHT:
+ case Positions.TopRight:
newWidth = resizeHandleCoords.X - originalRectangle.Left;
newHeight = originalRectangle.Bottom - resizeHandleCoords.Y;
newRatio = newWidth / newHeight;
@@ -252,7 +252,7 @@ namespace Greenshot.Helpers {
}
break;
- case Gripper.POSITION_BOTTOM_LEFT:
+ case Positions.BottomLeft:
newWidth = originalRectangle.Right - resizeHandleCoords.X;
newHeight = resizeHandleCoords.Y - originalRectangle.Top;
newRatio = newWidth / newHeight;
@@ -263,7 +263,7 @@ namespace Greenshot.Helpers {
}
break;
- case Gripper.POSITION_BOTTOM_RIGHT:
+ case Positions.BottomRight:
newWidth = resizeHandleCoords.X - originalRectangle.Left;
newHeight = resizeHandleCoords.Y - originalRectangle.Top;
newRatio = newWidth / newHeight;
@@ -282,10 +282,10 @@ namespace Greenshot.Helpers {
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();
diff --git a/GreenshotPlugin/GreenshotPlugin.csproj b/GreenshotPlugin/GreenshotPlugin.csproj
index f29b3b79b..8bc85a253 100644
--- a/GreenshotPlugin/GreenshotPlugin.csproj
+++ b/GreenshotPlugin/GreenshotPlugin.csproj
@@ -67,6 +67,7 @@
+
diff --git a/GreenshotPlugin/Interfaces/Drawing/Adorners/IAdorner.cs b/GreenshotPlugin/Interfaces/Drawing/Adorners/IAdorner.cs
new file mode 100644
index 000000000..27f825de4
--- /dev/null
+++ b/GreenshotPlugin/Interfaces/Drawing/Adorners/IAdorner.cs
@@ -0,0 +1,91 @@
+/*
+ * 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 .
+ */
+
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+
+namespace Greenshot.Plugin.Drawing.Adorners
+{
+ public interface IAdorner
+ {
+ ///
+ /// Returns if this adorner is active
+ ///
+ bool IsActive { get; }
+
+ ///
+ /// The current edit status, this is needed to locate the adorner to send events to
+ ///
+ EditStatus EditStatus { get; }
+
+ ///
+ /// The owner of this adorner
+ ///
+ IDrawableContainer Owner { get; }
+
+ ///
+ /// Is the current point "over" the Adorner?
+ /// If this is the case, the
+ ///
+ /// Point to test
+ /// true if so
+ bool HitTest(Point point);
+
+ ///
+ /// Handle the MouseDown event
+ ///
+ ///
+ /// MouseEventArgs
+ void MouseDown(object sender, MouseEventArgs mouseEventArgs);
+
+ ///
+ /// Handle the MouseUp event
+ ///
+ ///
+ /// MouseEventArgs
+ void MouseUp(object sender, MouseEventArgs mouseEventArgs);
+
+ ///
+ /// Handle the MouseMove event
+ ///
+ ///
+ /// MouseEventArgs
+ void MouseMove(object sender, MouseEventArgs mouseEventArgs);
+
+ ///
+ /// Gets the cursor that should be displayed for this behavior.
+ ///
+ Cursor Cursor { get; }
+
+ ///
+ /// Draw the adorner
+ ///
+ /// PaintEventArgs
+ void Paint(PaintEventArgs paintEventArgs);
+
+ ///
+ /// Called if the owner is transformed
+ ///
+ /// Matrix
+ void Transform(Matrix matrix);
+ }
+}
diff --git a/GreenshotPlugin/Interfaces/Drawing/Container.cs b/GreenshotPlugin/Interfaces/Drawing/Container.cs
index 7be49e852..afae80489 100644
--- a/GreenshotPlugin/Interfaces/Drawing/Container.cs
+++ b/GreenshotPlugin/Interfaces/Drawing/Container.cs
@@ -24,6 +24,9 @@ using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.ComponentModel;
+using System.Collections.Generic;
+using Greenshot.Plugin.Drawing.Adorners;
+using System.Runtime.Serialization;
namespace Greenshot.Plugin.Drawing {
public enum RenderMode {EDIT, EXPORT};
@@ -73,7 +76,9 @@ namespace Greenshot.Plugin.Drawing {
Rectangle DrawingBounds {
get;
}
-
+
+ void ApplyBounds(RectangleF newBounds);
+
bool hasFilters {
get;
}
@@ -85,8 +90,6 @@ namespace Greenshot.Plugin.Drawing {
void AlignToParent(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment);
void Invalidate();
bool ClickableAt(int x, int y);
- void HideGrippers();
- void ShowGrippers();
void MoveBy(int x, int y);
void Transform(Matrix matrix);
bool HandleMouseDown(int x, int y);
@@ -97,6 +100,11 @@ namespace Greenshot.Plugin.Drawing {
EditStatus DefaultEditMode {
get;
}
+
+ ///
+ /// Available adorners for the DrawableContainer
+ ///
+ IList Adorners { get; }
}
public interface ITextContainer: IDrawableContainer {
diff --git a/GreenshotPlugin/Interfaces/Generic.cs b/GreenshotPlugin/Interfaces/Generic.cs
index 96283027a..29a66597f 100644
--- a/GreenshotPlugin/Interfaces/Generic.cs
+++ b/GreenshotPlugin/Interfaces/Generic.cs
@@ -197,5 +197,7 @@ namespace Greenshot.Plugin {
get;
set;
}
+ int Width { get; }
+ int Height { get; }
}
}
\ No newline at end of file