diff --git a/Greenshot/Drawing/Adorners/GripperAdorner.cs b/Greenshot/Drawing/Adorners/GripperAdorner.cs new file mode 100644 index 000000000..532fdcedb --- /dev/null +++ b/Greenshot/Drawing/Adorners/GripperAdorner.cs @@ -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 . + */ + +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 +{ + /// + /// This is the default "legacy" gripper adorner, not the one used for the tail in the speech-bubble + /// + 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; + } + + /// + /// Returns the cursor for when the mouse is over the adorner + /// + 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; + } + + /// + /// Test if the point is inside the adorner + /// + /// + /// + public bool HitTest(Point point) + { + return Bounds.Contains(point); + } + + /// + /// Handle the mouse down + /// + /// + /// + public 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 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(); + } + + /// + /// Handle the mouse up + /// + /// + /// + public void MouseUp(object sender, MouseEventArgs mouseEventArgs) + { + _editStatus = EditStatus.IDLE; + Owner.Invalidate(); + } + + /// + /// Return the location of the adorner + /// + 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); + } + } + + /// + /// Return the bounds of the Adorner + /// + 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); + } + } + + /// + /// Draw the adorner + /// + /// PaintEventArgs + 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); + } + + /// + /// We ignore the Transform, as the coordinates are directly bound to those of the owner + /// + /// + public void Transform(Matrix matrix) + { + } + } +} diff --git a/Greenshot/Drawing/Adorners/TargetAdorner.cs b/Greenshot/Drawing/Adorners/TargetAdorner.cs new file mode 100644 index 000000000..965bed5a6 --- /dev/null +++ b/Greenshot/Drawing/Adorners/TargetAdorner.cs @@ -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 . + */ + +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 implements the special "gripper" for the Speech-Bubble tail + /// + public class TargetAdorner : IAdorner + { + private EditStatus _editStatus; + + public TargetAdorner(IDrawableContainer owner, Point location) + { + Owner = owner; + Location = location; + } + + /// + /// Returns the cursor for when the mouse is over the adorner + /// + public Cursor Cursor + { + get + { + return Cursors.SizeAll; + } + } + + public IDrawableContainer Owner + { + get; + set; + } + + /// + /// Test if the point is inside the adorner + /// + /// + /// + public bool HitTest(Point point) + { + return Bounds.Contains(point); + } + + /// + /// Handle the mouse down + /// + /// + /// + public void MouseDown(object sender, MouseEventArgs mouseEventArgs) + { + _editStatus = EditStatus.MOVING; + } + + /// + /// Handle the mouse move + /// + /// + /// + 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(); + } + + /// + /// Handle the mouse up + /// + /// + /// + public void MouseUp(object sender, MouseEventArgs mouseEventArgs) + { + _editStatus = EditStatus.IDLE; + Owner.Invalidate(); + } + + /// + /// Return the location of the adorner + /// + public Point Location + { + get; + set; + } + + /// + /// Return the bounds of the Adorner + /// + 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); + } + } + + /// + /// Draw the adorner + /// + /// PaintEventArgs + 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); + } + + /// + /// Made sure this adorner is transformed + /// + /// Matrix + public void Transform(Matrix matrix) + { + if (matrix == null) + { + return; + } + Point[] points = new[] { Location }; + matrix.TransformPoints(points); + Location = points[0]; + } + } +} diff --git a/Greenshot/Drawing/DrawableContainer.cs b/Greenshot/Drawing/DrawableContainer.cs index aa4ffce43..cdd7125d6 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,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 +{ /// /// 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 { } } + /// + /// List of available Adorners + /// + public IList Adorners { get; } = new List(); + [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(); } - /// - /// 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); } 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(); } diff --git a/Greenshot/Drawing/DrawableContainerList.cs b/Greenshot/Drawing/DrawableContainerList.cs index 570949a40..5dd4bb79d 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/FreehandContainer.cs b/Greenshot/Drawing/FreehandContainer.cs index b30937c2b..553d28294 100644 --- a/Greenshot/Drawing/FreehandContainer.cs +++ b/Greenshot/Drawing/FreehandContainer.cs @@ -63,12 +63,7 @@ namespace Greenshot.Drawing { protected void Init() { - if (_grippers != null) { - for (int i = 0; i < _grippers.Length; i++) { - _grippers[i].Enabled = false; - _grippers[i].Visible = false; - } - } + // TODO: Remove grippers } public override void Transform(Matrix matrix) { @@ -258,17 +253,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/LineContainer.cs b/Greenshot/Drawing/LineContainer.cs index 4189134ac..37357b4fa 100644 --- a/Greenshot/Drawing/LineContainer.cs +++ b/Greenshot/Drawing/LineContainer.cs @@ -53,11 +53,7 @@ namespace Greenshot.Drawing { } protected void Init() { - if (_grippers != null) { - foreach (int index in new[] { 1, 2, 3, 5, 6, 7 }) { - _grippers[index].Enabled = false; - } - } + // TODO: Remove the unneeded grippers (1, 2, 3, 5, 6, 7) } public override void Draw(Graphics graphics, RenderMode rm) { 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/SpeechbubbleContainer.cs b/Greenshot/Drawing/SpeechbubbleContainer.cs index 64ede51e8..6b2f6e7ba 100644 --- a/Greenshot/Drawing/SpeechbubbleContainer.cs +++ b/Greenshot/Drawing/SpeechbubbleContainer.cs @@ -118,7 +118,7 @@ namespace Greenshot.Drawing { if (TargetGripper.Location != newGripperLocation) { Invalidate(); - TargetGripperMove(newGripperLocation.X, newGripperLocation.Y); + TargetGripper.Location = newGripperLocation; Invalidate(); } return returnValue; @@ -180,7 +180,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 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; // 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.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()) { tailMatrix.Translate(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2)); diff --git a/Greenshot/Drawing/Surface.cs b/Greenshot/Drawing/Surface.cs index b28e2a86f..2dd451493 100644 --- a/Greenshot/Drawing/Surface.cs +++ b/Greenshot/Drawing/Surface.cs @@ -21,12 +21,14 @@ using Greenshot.Configuration; using Greenshot.Core; +using Greenshot.Drawing.Adorners; using Greenshot.Drawing.Fields; using Greenshot.Helpers; 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; @@ -991,12 +993,45 @@ namespace Greenshot.Drawing { Invalidate(); } + /// + /// Check if an adorner was "hit", and change the cursor if so + /// + /// MouseEventArgs + /// IAdorner + 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; + } + /// /// This event handler is called when someone presses the mouse on a surface. /// /// /// void SurfaceMouseDown(object sender, MouseEventArgs e) { + + // Handle Adorners + var adorner = AdornersHitTest(e); + if (adorner != null) + { + adorner.MouseDown(sender, e); + return; + } + _mouseStart = e.Location; // check contextmenu @@ -1065,6 +1100,15 @@ namespace Greenshot.Drawing { /// /// 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); _elements.Status = EditStatus.IDLE; @@ -1098,7 +1142,7 @@ namespace Greenshot.Drawing { } if (selectedElements.Count > 0) { - selectedElements.ShowGrippers(); + selectedElements.Invalidate(); selectedElements.Selected = true; } @@ -1126,6 +1170,14 @@ namespace Greenshot.Drawing { /// /// void SurfaceMouseMove(object sender, MouseEventArgs e) { + // Handle Adorners + var adorner = AdornersHitTest(e); + if (adorner != null) + { + adorner.MouseMove(sender, e); + return; + } + Point currentMouse = e.Location; if (DrawingMode != DrawingModes.None) { @@ -1137,7 +1189,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) { @@ -1203,15 +1255,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; @@ -1246,6 +1298,15 @@ namespace Greenshot.Drawing { targetGraphics.DrawImage(Image, clipRectangle, clipRectangle, GraphicsUnit.Pixel); _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) { @@ -1531,9 +1592,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(); @@ -1549,10 +1610,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) { @@ -1570,7 +1630,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/Greenshot.csproj b/Greenshot/Greenshot.csproj index ee50aa76a..8a1c1de40 100644 --- a/Greenshot/Greenshot.csproj +++ b/Greenshot/Greenshot.csproj @@ -75,7 +75,10 @@ + + + @@ -101,9 +104,6 @@ - - Component - diff --git a/Greenshot/Helpers/ScaleHelper.cs b/Greenshot/Helpers/ScaleHelper.cs index 77557fc73..ffab1be15 100644 --- a/Greenshot/Helpers/ScaleHelper.cs +++ b/Greenshot/Helpers/ScaleHelper.cs @@ -119,15 +119,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); } @@ -138,7 +138,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(); } @@ -157,7 +157,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); @@ -171,47 +171,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; @@ -221,19 +221,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; @@ -244,7 +244,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; @@ -255,7 +255,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; @@ -266,7 +266,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; @@ -285,10 +285,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 917a12654..bef018b9f 100644 --- a/GreenshotPlugin/GreenshotPlugin.csproj +++ b/GreenshotPlugin/GreenshotPlugin.csproj @@ -66,6 +66,7 @@ + diff --git a/GreenshotPlugin/Interfaces/Drawing/Adorners/IAdorner.cs b/GreenshotPlugin/Interfaces/Drawing/Adorners/IAdorner.cs new file mode 100644 index 000000000..cf3c3fa70 --- /dev/null +++ b/GreenshotPlugin/Interfaces/Drawing/Adorners/IAdorner.cs @@ -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 . + */ + +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace Greenshot.Plugin.Drawing.Adorners +{ + public interface IAdorner + { + /// + /// 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..cd96f774b 100644 --- a/GreenshotPlugin/Interfaces/Drawing/Container.cs +++ b/GreenshotPlugin/Interfaces/Drawing/Container.cs @@ -24,6 +24,8 @@ using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Windows.Forms; using System.ComponentModel; +using System.Collections.Generic; +using Greenshot.Plugin.Drawing.Adorners; namespace Greenshot.Plugin.Drawing { public enum RenderMode {EDIT, EXPORT}; @@ -73,7 +75,11 @@ namespace Greenshot.Plugin.Drawing { Rectangle DrawingBounds { get; } - + + void ApplyBounds(RectangleF newBounds); + + void DoLayout(); + bool hasFilters { get; } @@ -85,8 +91,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 +101,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 73e6c2cf6..ed49327dd 100644 --- a/GreenshotPlugin/Interfaces/Generic.cs +++ b/GreenshotPlugin/Interfaces/Generic.cs @@ -198,5 +198,7 @@ namespace Greenshot.Plugin { get; set; } + int Width { get; } + int Height { get; } } } \ No newline at end of file