diff --git a/Greenshot/Controls/ZoomControl.cs b/Greenshot/Controls/ZoomControl.cs deleted file mode 100644 index 7837b8ff3..000000000 --- a/Greenshot/Controls/ZoomControl.cs +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Greenshot - a free and open source screenshot tool - * Copyright (C) 2007-2012 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; -using System.Collections.Generic; -using System.Windows.Forms; -using System.Drawing; -using Greenshot.Plugin; -using System.Drawing.Drawing2D; -using GreenshotPlugin.Controls; -using GreenshotPlugin.UnmanagedHelpers; - -namespace Greenshot.Forms { - /// - /// This control will show the area around the mouse of the current capture - /// - public class ZoomControl : Control { - private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ZoomControl)); - private Image imageToZoom = null; - private Point zoomLocation = Point.Empty; - private const int distanceX = 20; - private const int distanceY = 20; - - /// - /// Create a zoom control for the image and with the size - /// - /// - /// - public ZoomControl(Image imageToZoom, Size zoomSize) { - InitializeComponent(); - this.Width = zoomSize.Width; - this.Height = zoomSize.Height; - this.imageToZoom = imageToZoom; - Zoom = 400; - } - - /// - /// Override some special form parameters - /// - protected override CreateParams CreateParams { - get { - var parms = base.CreateParams; - parms.Style &= ~((int)WindowStyleFlags.WS_CLIPCHILDREN); // Turn off WS_CLIPCHILDREN which prevents the screen to be cleared behind this form - parms.ExStyle |= (int)ExtendedWindowStyleFlags.WS_EX_NOACTIVATE | (int)ExtendedWindowStyleFlags.WS_EX_TOOLWINDOW | (int)ExtendedWindowStyleFlags.WS_EX_TOPMOST; - //parms.ExStyle |= (int)ExtendedWindowStyleFlags.WS_EX_TRANSPARENT; - parms.Parent = IntPtr.Zero; // Make parentless - return parms; - } - } - - /// - /// Shows the control as a floating Window child - /// of the desktop. To hide the control again, - /// use the property. - /// - public void ShowFloating() { - if (this.Handle == IntPtr.Zero) { - base.CreateControl(); - } - User32.SetParent(base.Handle, IntPtr.Zero); - User32.ShowWindow(base.Handle, ShowWindowCommand.Show); - } - - /// - /// Make the mouse events pass through - /// - /// - protected override void WndProc(ref Message m) { - const int HTTRANSPARENT = (-1); - switch (m.Msg) { - case (int)WindowsMessages.WM_NCHITTEST: - m.Result = (IntPtr) HTTRANSPARENT; - break; - default: - base.WndProc(ref m); - break; - } - } - - /// - /// Sets the location of the mouse on the screen (using screen coordinates, which might differ from bitmap coordindates in a multi screen setup) - /// - public Point MouseLocation { - set { - Rectangle tl = new Rectangle(value.X - (distanceX + Width), value.Y - (distanceY + Height), Width, Height); - Rectangle tr = new Rectangle(value.X + distanceX, value.Y - (distanceY + Height), Width, Height); - Rectangle bl = new Rectangle(value.X - (distanceX + Width), value.Y + distanceY, Width, Height); - Rectangle br = new Rectangle(value.X + distanceX, value.Y + distanceY, Width, Height); - Rectangle screenBounds = Screen.GetBounds(value); - if (screenBounds.Contains(br)) { - this.Location = br.Location; - } else if (screenBounds.Contains(bl)) { - this.Location = bl.Location; - } else if (screenBounds.Contains(tr)) { - this.Location = tr.Location; - } else { - this.Location = tl.Location; - } - - this.Invalidate(); - } - } - - /// - /// Gets or sets the location of the bitmap to be displayed in zoom (using bitmap coordinates, which might differ from screen coordinates in a multi screen setup) - /// - public Point ZoomLocation { - get { - return zoomLocation; - } - set { - zoomLocation = value; - } - - } - - /// - /// The zoom property - /// - public int Zoom { - get; - set; - } - - /// - /// This makes sure there is no background painted, as we have complete "paint" control it doesn't make sense to do otherwise. - /// - /// - protected override void OnPaintBackground(PaintEventArgs pevent) { - } - - /// - /// Paint the zoom area and the cross - /// - /// - protected override void OnPaint(PaintEventArgs e) { - if (imageToZoom == null) { - return; - } - Graphics graphics = e.Graphics; - graphics.Clear(Color.Black); - graphics.SmoothingMode = SmoothingMode.None; - graphics.InterpolationMode = InterpolationMode.NearestNeighbor; - graphics.CompositingQuality = CompositingQuality.HighSpeed; - graphics.PixelOffsetMode = PixelOffsetMode.Half; - Rectangle clipRectangle = e.ClipRectangle; - float zoomFactor = (float)100 / (float)Zoom; - - int sourceWidth = (int)(Width * zoomFactor); - int sourceHeight = (int)(Height * zoomFactor); - Rectangle sourceRectangle = new Rectangle(ZoomLocation.X - (sourceWidth / 2) + 1, ZoomLocation.Y - (sourceHeight / 2) + 1, sourceWidth, sourceHeight); - Rectangle destinationRectangle = new Rectangle(0, 0, Width, Height); - //graphics.StretchBlt((Bitmap)imageToZoom, sourceRectangle, destinationRectangle); - graphics.DrawImage(imageToZoom, destinationRectangle, sourceRectangle, GraphicsUnit.Pixel); - - int pixelThickness = Zoom / 100; - using (Pen pen = new Pen(Color.Black, pixelThickness)) { - int halfWidth = (Width >> 1) - (pixelThickness >> 1); - int halfWidthEnd = (Width >> 1) - pixelThickness; - int halfHeight = (Height >> 1) - (pixelThickness >> 1); - int halfHeightEnd = (Height >> 1) - pixelThickness; - graphics.DrawLine(pen, halfWidth, 0, halfWidth, halfHeightEnd); - graphics.DrawLine(pen, halfWidth, halfHeightEnd + pixelThickness, halfWidth, Height); - graphics.DrawLine(pen, 0, halfHeight, halfWidthEnd, halfHeight); - graphics.DrawLine(pen, halfWidthEnd + pixelThickness, halfHeight, Width, halfHeight); - } - } - - private void InitializeComponent() { - this.SuspendLayout(); - this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - // Only double-buffer when we are not in a TerminalServerSession - this.DoubleBuffered = !System.Windows.Forms.SystemInformation.TerminalServerSession; - this.Name = "Zoom"; - this.ResumeLayout(false); - } - } -} diff --git a/Greenshot/Forms/CaptureForm.cs b/Greenshot/Forms/CaptureForm.cs index 7729c0057..986e7fd4b 100644 --- a/Greenshot/Forms/CaptureForm.cs +++ b/Greenshot/Forms/CaptureForm.cs @@ -62,10 +62,9 @@ namespace Greenshot.Forms { private ICapture capture = null; private Image capturedImage = null; private Timer timer = null; - + private bool isZooming = true; private Point previousMousePos = Point.Empty; private FixMode fixMode = FixMode.None; - private ZoomControl zoomControl = null; /// /// Property to access the selected capture rectangle @@ -129,7 +128,6 @@ namespace Greenshot.Forms { // clean up this.FormClosed += delegate { - RemoveZoom(); currentForm = null; LOG.Debug("Remove CaptureForm from currentForm"); }; @@ -181,36 +179,6 @@ namespace Greenshot.Forms { } } - /// - /// Create the zoom control - /// - private void CreateZoom() { - if (zoomControl == null) { - zoomControl = new ZoomControl(capturedImage, new Size(200, 200)); - zoomControl.MouseLocation = cursorPos; - zoomControl.ZoomLocation = cursorPosOnBitmap; - zoomControl.ShowFloating(); - } - } - - /// - /// Hide the zoom control - /// - private void RemoveZoom() { - if (zoomControl != null) { - zoomControl.Hide(); - } - } - - /// - /// Create the zoom after the window is showing - /// - /// - protected override void OnShown(EventArgs e) { - base.OnShown(e); - CreateZoom(); - } - #region key handling void CaptureFormKeyUp(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.ShiftKey) { @@ -241,11 +209,7 @@ namespace Greenshot.Forms { Invalidate(); } else if (e.KeyCode == Keys.Z) { // Toggle zoom - if (zoomControl == null) { - CreateZoom(); - } else { - RemoveZoom(); - } + isZooming = !isZooming; } else if (e.KeyCode == Keys.Space) { switch (captureMode) { case CaptureMode.Region: @@ -265,6 +229,11 @@ namespace Greenshot.Forms { #endregion #region events + /// + /// The mousedown handler of the capture form + /// + /// + /// void OnMouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { Point tmpCursorLocation = WindowCapture.GetCursorLocation(); @@ -279,6 +248,11 @@ namespace Greenshot.Forms { } } + /// + /// The mouse up handler of the capture form + /// + /// + /// void OnMouseUp(object sender, MouseEventArgs e) { if (mouseDown) { // If the mouse goes up we set down to false (nice logic!) @@ -301,6 +275,11 @@ namespace Greenshot.Forms { } } + /// + /// This method is used to "fix" the mouse coordinates when keeping shift/ctrl pressed + /// + /// + /// private Point FixMouseCoordinates(Point currentMouse) { if (fixMode == FixMode.Initiated) { if (previousMousePos.X != currentMouse.X) { @@ -317,6 +296,11 @@ namespace Greenshot.Forms { return currentMouse; } + /// + /// The mouse move handler of the capture form + /// + /// + /// void OnMouseMove(object sender, MouseEventArgs e) { // Make sure the mouse coordinates are fixed, when pressing shift mouseMovePos = FixMouseCoordinates(WindowCapture.GetCursorLocation()); @@ -327,10 +311,18 @@ namespace Greenshot.Forms { } } + /// + /// The tick handler of the capture form, this initiates the frame drawing. + /// + /// + /// void timer_Tick(object sender, EventArgs e) { updateFrame(); } + /// + /// update the frame, this only invalidates + /// void updateFrame() { Point lastPos = cursorPos.Clone(); cursorPos = mouseMovePos.Clone(); @@ -347,12 +339,6 @@ namespace Greenshot.Forms { bool horizontalMove = false; bool verticalMove = false; - // Change the zoom location - if (zoomControl != null) { - zoomControl.MouseLocation = cursorPos; - zoomControl.ZoomLocation = cursorPosOnBitmap; - } - if (lastPos.X != cursorPos.X) { horizontalMove = true; } @@ -454,6 +440,10 @@ namespace Greenshot.Forms { } } } + if (isZooming && captureMode != CaptureMode.Window) { + Invalidate(ZoomArea(lastPos, new Size(200, 200))); + Invalidate(ZoomArea(cursorPos, new Size(200, 200))); + } // Force update "now" Update(); } @@ -465,6 +455,73 @@ namespace Greenshot.Forms { protected override void OnPaintBackground(PaintEventArgs pevent) { } + /// + /// Get the area of where the zoom can be drawn + /// + /// + /// + /// + private Rectangle ZoomArea(Point pos, Size size) { + const int distanceX = 20; + const int distanceY = 20; + Rectangle tl = new Rectangle(pos.X - (distanceX + size.Width), pos.Y - (distanceY + size.Height), size.Width, size.Height); + Rectangle tr = new Rectangle(pos.X + distanceX, pos.Y - (distanceY + size.Height), size.Width, size.Height); + Rectangle bl = new Rectangle(pos.X - (distanceX + size.Width), pos.Y + distanceY, size.Width, size.Height); + Rectangle br = new Rectangle(pos.X + distanceX, pos.Y + distanceY, size.Width, size.Height); + Rectangle screenBounds = Screen.GetBounds(pos); + if (screenBounds.Contains(br)) { + return br; + } else if (screenBounds.Contains(bl)) { + return bl; + } else if (screenBounds.Contains(tr)) { + return tr; + } else { + return tl; + } + } + + /// + /// Draw the zoomed area + /// + /// + /// + /// + private void DrawZoom(Graphics graphics, Rectangle sourceRectangle, Rectangle destinationRectangle) { + if (capturedImage == null || !isZooming) { + return; + } + + graphics.SmoothingMode = SmoothingMode.None; + graphics.InterpolationMode = InterpolationMode.NearestNeighbor; + graphics.CompositingQuality = CompositingQuality.HighSpeed; + graphics.PixelOffsetMode = PixelOffsetMode.None; + + using (GraphicsPath path = new GraphicsPath()) { + path.AddEllipse(destinationRectangle); + using (Region clipRegion = new Region(path)) { + graphics.Clip = clipRegion; + graphics.DrawImage(capturedImage, destinationRectangle, sourceRectangle, GraphicsUnit.Pixel); + } + } + + int pixelThickness = destinationRectangle.Width / sourceRectangle.Width; + using (Pen pen = new Pen(Color.Black, pixelThickness)) { + int halfWidth = (destinationRectangle.Width >> 1) - (pixelThickness >> 1); + int halfWidthEnd = (destinationRectangle.Width >> 1) - pixelThickness; + int halfHeight = (destinationRectangle.Height >> 1) - (pixelThickness >> 1); + int halfHeightEnd = (destinationRectangle.Height >> 1) - pixelThickness; + graphics.DrawLine(pen, destinationRectangle.X + halfWidth, destinationRectangle.Y, destinationRectangle.X + halfWidth, destinationRectangle.Y + halfHeightEnd); + graphics.DrawLine(pen, destinationRectangle.X + halfWidth, destinationRectangle.Y + halfHeightEnd + pixelThickness, destinationRectangle.X + halfWidth, destinationRectangle.Y + destinationRectangle.Height); + graphics.DrawLine(pen, destinationRectangle.X, destinationRectangle.Y + halfHeight, destinationRectangle.X + halfWidthEnd, destinationRectangle.Y + halfHeight); + graphics.DrawLine(pen, destinationRectangle.X + halfWidthEnd + pixelThickness, destinationRectangle.Y + halfHeight, destinationRectangle.X + destinationRectangle.Width, destinationRectangle.Y + halfHeight); + } + } + + /// + /// Paint the actual visible parts + /// + /// + /// void OnPaint(object sender, PaintEventArgs e) { Graphics graphics = e.Graphics; Rectangle clipRectangle = e.ClipRectangle; @@ -595,6 +652,15 @@ namespace Greenshot.Forms { } } } + + if (captureMode != CaptureMode.Window) { + const int zoomSourceWidth = 25; + const int zoomSourceHeight = 25; + + Rectangle sourceRectangle = new Rectangle(cursorPosOnBitmap.X - (zoomSourceWidth / 2), cursorPosOnBitmap.Y - (zoomSourceHeight / 2), zoomSourceWidth, zoomSourceHeight); + DrawZoom(graphics, sourceRectangle, ZoomArea(cursorPos, new Size(200, 200))); + + } } #endregion } diff --git a/Greenshot/Greenshot.csproj b/Greenshot/Greenshot.csproj index 3d1a94946..5ba3d9966 100644 --- a/Greenshot/Greenshot.csproj +++ b/Greenshot/Greenshot.csproj @@ -67,9 +67,6 @@ Component - - Form -