diff --git a/Greenshot/Drawing/DrawableContainer.cs b/Greenshot/Drawing/DrawableContainer.cs index 65ff42de3..e7caf7ea3 100644 --- a/Greenshot/Drawing/DrawableContainer.cs +++ b/Greenshot/Drawing/DrawableContainer.cs @@ -302,33 +302,6 @@ namespace Greenshot.Drawing } } - public void AlignToParent(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) { - if (_parent == null) - { - return; - } - int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); - if (horizontalAlignment == HorizontalAlignment.Left) { - Left = lineThickness/2; - } - if (horizontalAlignment == HorizontalAlignment.Right) { - Left = _parent.Width - Width - lineThickness/2; - } - if (horizontalAlignment == HorizontalAlignment.Center) { - Left = (_parent.Width / 2) - (Width / 2) - lineThickness/2; - } - - if (verticalAlignment == VerticalAlignment.TOP) { - Top = lineThickness/2; - } - if (verticalAlignment == VerticalAlignment.BOTTOM) { - Top = _parent.Height - Height - lineThickness/2; - } - if (verticalAlignment == VerticalAlignment.CENTER) { - Top = (_parent.Height / 2) - (Height / 2) - lineThickness/2; - } - } - public virtual bool InitContent() { return true; } public virtual void OnDoubleClick() {} diff --git a/Greenshot/Drawing/Surface.cs b/Greenshot/Drawing/Surface.cs index e9d26ef05..4435a7f39 100644 --- a/Greenshot/Drawing/Surface.cs +++ b/Greenshot/Drawing/Surface.cs @@ -305,6 +305,8 @@ namespace Greenshot.Drawing [NonSerialized] private Matrix _zoomMatrix = new Matrix(1, 0, 0, 1, 0, 0); [NonSerialized] + private Matrix _inverseZoomMatrix = new Matrix(1, 0, 0, 1, 0, 0); + [NonSerialized] private float _zoomFactor = 1.0f; public float ZoomFactor { @@ -313,6 +315,7 @@ namespace Greenshot.Drawing { _zoomFactor = value; _zoomMatrix = new Matrix(_zoomFactor, 0, 0, _zoomFactor, 0, 0); + _inverseZoomMatrix = new Matrix(1f / _zoomFactor, 0, 0, 1f / _zoomFactor, 0, 0); UpdateSize(); } } @@ -803,9 +806,9 @@ namespace Greenshot.Drawing return cursorContainer; } - public ITextContainer AddTextContainer(string text, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, FontFamily family, float size, bool italic, bool bold, bool shadow, int borderSize, Color color, Color fillColor) + public ITextContainer AddTextContainer(string text, int x, int y, FontFamily family, float size, bool italic, bool bold, bool shadow, int borderSize, Color color, Color fillColor) { - TextContainer textContainer = new TextContainer(this) {Text = text}; + TextContainer textContainer = new TextContainer(this) {Text = text, Left = x, Top = y}; textContainer.SetFieldValue(FieldType.FONT_FAMILY, family.Name); textContainer.SetFieldValue(FieldType.FONT_BOLD, bold); textContainer.SetFieldValue(FieldType.FONT_ITALIC, italic); @@ -816,8 +819,6 @@ namespace Greenshot.Drawing textContainer.SetFieldValue(FieldType.SHADOW, shadow); // Make sure the Text fits textContainer.FitToText(); - // Align to Surface - textContainer.AlignToParent(horizontalAlignment, verticalAlignment); //AggregatedProperties.UpdateElement(textContainer); AddElement(textContainer); @@ -1817,43 +1818,72 @@ namespace Greenshot.Drawing } else if (ClipboardHelper.ContainsImage(clipboard)) { - int x = 10; - int y = 10; - - // FEATURE-995: Added a check for the current mouse cursor location, to paste the image on that location. - var mousePositionOnControl = PointToClient(MousePosition); - if (ClientRectangle.Contains(mousePositionOnControl)) - { - x = mousePositionOnControl.X; - y = mousePositionOnControl.Y; - } + Point pasteLocation = GetPasteLocation(0.1f, 0.1f); foreach (Image clipboardImage in ClipboardHelper.GetImages(clipboard)) { if (clipboardImage != null) { DeselectAllElements(); - IImageContainer container = AddImageContainer(clipboardImage as Bitmap, x, y); + IImageContainer container = AddImageContainer(clipboardImage as Bitmap, pasteLocation.X, pasteLocation.Y); SelectElement(container); clipboardImage.Dispose(); - x += 10; - y += 10; + pasteLocation.X += 10; + pasteLocation.Y += 10; } } } else if (ClipboardHelper.ContainsText(clipboard)) { + Point pasteLocation = GetPasteLocation(0.4f, 0.4f); + string text = ClipboardHelper.GetText(clipboard); if (text != null) { DeselectAllElements(); - ITextContainer textContainer = AddTextContainer(text, HorizontalAlignment.Center, VerticalAlignment.CENTER, + ITextContainer textContainer = AddTextContainer(text, pasteLocation.X, pasteLocation.Y, FontFamily.GenericSansSerif, 12f, false, false, false, 2, Color.Black, Color.Transparent); SelectElement(textContainer); } } } + /// + /// Find a location to paste elements. + /// If mouse is over the surface - use it's position, otherwise use the visible area. + /// Return a point in image coordinate space. + /// + /// 0.0f for the left edge of visible area, 1.0f for the right edge of visible area. + /// 0.0f for the top edge of visible area, 1.0f for the bottom edge of visible area. + private Point GetPasteLocation(float horizontalRatio = 0.5f, float verticalRatio = 0.5f) + { + var point = PointToClient(MousePosition); + var rc = GetVisibleRectangle(); + if (!rc.Contains(point)) + { + point = new Point( + rc.Left + (int)(rc.Width * horizontalRatio), + rc.Top + (int)(rc.Height * verticalRatio) + ); + } + return ToImageCoordinates(point); + } + + /// + /// Get the rectangle bounding the part of this Surface currently visible in the editor (in surface coordinate space). + /// + private Rectangle GetVisibleRectangle() + { + var bounds = Bounds; + var clientArea = Parent.ClientRectangle; + return new Rectangle( + Math.Max(0, -bounds.Left), + Math.Max(0, -bounds.Top), + clientArea.Width, + clientArea.Height + ); + } + /// /// Duplicate all the selecteded elements /// @@ -2127,7 +2157,38 @@ namespace Greenshot.Drawing { Point[] points = { rc.Location, rc.Location + rc.Size }; _zoomMatrix.TransformPoints(points); - return new Rectangle(points[0].X, points[0].Y, points[1].X - points[0].X, points[1].Y - points[1].Y); + return new Rectangle( + points[0].X, + points[0].Y, + points[1].X - points[0].X, + points[1].Y - points[0].Y + ); + } + } + + public Point ToImageCoordinates(Point point) + { + Point[] points = { point }; + _inverseZoomMatrix.TransformPoints(points); + return points[0]; + } + + public Rectangle ToImageCoordinates(Rectangle rc) + { + if (_inverseZoomMatrix.IsIdentity) + { + return rc; + } + else + { + Point[] points = { rc.Location, rc.Location + rc.Size }; + _inverseZoomMatrix.TransformPoints(points); + return new Rectangle( + points[0].X, + points[0].Y, + points[1].X - points[0].X, + points[1].Y - points[0].Y + ); } } } diff --git a/GreenshotPlugin/Interfaces/Drawing/Container.cs b/GreenshotPlugin/Interfaces/Drawing/Container.cs index b2b6e3d19..35a6cf50a 100644 --- a/GreenshotPlugin/Interfaces/Drawing/Container.cs +++ b/GreenshotPlugin/Interfaces/Drawing/Container.cs @@ -102,7 +102,6 @@ namespace GreenshotPlugin.Interfaces.Drawing get; set; } - void AlignToParent(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment); void Invalidate(); bool ClickableAt(int x, int y); void MoveBy(int x, int y); diff --git a/GreenshotPlugin/Interfaces/ISurface.cs b/GreenshotPlugin/Interfaces/ISurface.cs index a94415cbc..e32247188 100644 --- a/GreenshotPlugin/Interfaces/ISurface.cs +++ b/GreenshotPlugin/Interfaces/ISurface.cs @@ -84,8 +84,8 @@ namespace GreenshotPlugin.Interfaces /// The TextContainer will be "re"sized to the text size. /// /// String to show - /// Left, Center, Right - /// TOP, CENTER, BOTTOM + /// Where to put the container, X coordinate in the Image coordinate space + /// Where to put the container, Y coordinate in the Image coordinate space /// FontFamily /// Font Size in float /// bool true if italic @@ -94,7 +94,7 @@ namespace GreenshotPlugin.Interfaces /// size of border (0 for none) /// Color of string /// Color of background (e.g. Color.Transparent) - ITextContainer AddTextContainer(string text, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, FontFamily family, float size, bool italic, bool bold, bool shadow, int borderSize, Color color, Color fillColor); + ITextContainer AddTextContainer(string text, int x, int y, FontFamily family, float size, bool italic, bool bold, bool shadow, int borderSize, Color color, Color fillColor); IImageContainer AddImageContainer(Image image, int x, int y); ICursorContainer AddCursorContainer(Cursor cursor, int x, int y); @@ -208,6 +208,16 @@ namespace GreenshotPlugin.Interfaces /// /// A rectangle in the coordinate space of the image. Rectangle ToSurfaceCoordinates(Rectangle rc); + /// + /// Translate a point from surface coorditate space to image coordinate space. + /// + /// A point in the coordinate space of the surface. + Point ToImageCoordinates(Point point); + /// + /// Translate a rectangle from surface coorditate space to image coordinate space. + /// + /// A rectangle in the coordinate space of the surface. + Rectangle ToImageCoordinates(Rectangle rc); void MakeUndoable(IMemento memento, bool allowMerge); }