2013-11-03 23:53:49 +13:00
|
|
|
|
#region License Information (GPL v3)
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
ShareX - A program that allows you to take screenshots and share any file type
|
2016-01-04 04:16:01 +13:00
|
|
|
|
Copyright (c) 2007-2016 ShareX Team
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
|
|
|
|
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 2
|
|
|
|
|
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, write to the Free Software
|
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
|
|
Optionally you can also view the license at <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#endregion License Information (GPL v3)
|
|
|
|
|
|
2014-12-11 09:25:20 +13:00
|
|
|
|
using ShareX.HelpersLib;
|
2015-07-17 07:07:06 +12:00
|
|
|
|
using System;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
2014-12-11 09:25:20 +13:00
|
|
|
|
namespace ShareX.ScreenCaptureLib
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
|
|
|
|
public class AreaManager
|
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
public List<BaseShape> Shapes { get; private set; } = new List<BaseShape>();
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
2016-05-03 20:24:01 +12:00
|
|
|
|
public BaseShape CurrentShape { get; private set; }
|
|
|
|
|
|
2016-05-03 21:35:10 +12:00
|
|
|
|
public ShapeType CurrentShapeType { get; set; } = ShapeType.RegionRectangle;
|
|
|
|
|
|
2016-05-03 20:24:01 +12:00
|
|
|
|
public Rectangle CurrentRectangle
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
if (CurrentShape != null)
|
|
|
|
|
{
|
|
|
|
|
return CurrentShape.Rectangle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Rectangle.Empty;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (CurrentShape != null)
|
|
|
|
|
{
|
|
|
|
|
CurrentShape.Rectangle = value;
|
|
|
|
|
}
|
2016-05-03 19:46:45 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 21:35:10 +12:00
|
|
|
|
public BaseShape[] Regions
|
2016-05-03 19:46:45 +12:00
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
return Shapes.OfType<BaseRegionShape>().ToArray();
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 22:06:58 +12:00
|
|
|
|
public BaseDrawingShape[] DrawingShapes
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Shapes.OfType<BaseDrawingShape>().ToArray();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 21:35:10 +12:00
|
|
|
|
public BaseShape[] ValidRegions
|
2015-07-17 07:07:06 +12:00
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
return Regions.Where(x => IsAreaValid(x.Rectangle)).ToArray();
|
2015-07-17 07:07:06 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 20:24:01 +12:00
|
|
|
|
public bool IsCurrentRegionValid
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2016-05-03 22:06:58 +12:00
|
|
|
|
return IsAreaValid(CurrentRectangle);
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 20:24:01 +12:00
|
|
|
|
public Rectangle CurrentHoverRectangle { get; private set; }
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
|
|
|
|
public bool IsCurrentHoverAreaValid
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
return !CurrentHoverRectangle.IsEmpty;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 22:48:37 +12:00
|
|
|
|
public bool IsCurrentShapeTypeRegion
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return CurrentShapeType == ShapeType.RegionRectangle || CurrentShapeType == ShapeType.RegionRoundedRectangle || CurrentShapeType == ShapeType.RegionEllipse ||
|
|
|
|
|
CurrentShapeType == ShapeType.RegionTriangle || CurrentShapeType == ShapeType.RegionDiamond;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 20:24:01 +12:00
|
|
|
|
public float RoundedRectangleRadius { get; set; } = 25;
|
|
|
|
|
public int RoundedRectangleRadiusIncrement { get; set; } = 3;
|
|
|
|
|
public TriangleAngle TriangleAngle { get; set; } = TriangleAngle.Top;
|
2015-07-17 07:07:06 +12:00
|
|
|
|
|
2015-08-23 01:13:38 +12:00
|
|
|
|
public Point CurrentPosition { get; private set; }
|
|
|
|
|
public Point PositionOnClick { get; private set; }
|
|
|
|
|
|
2013-11-03 23:53:49 +13:00
|
|
|
|
public ResizeManager ResizeManager { get; private set; }
|
|
|
|
|
public bool IsCreating { get; private set; }
|
|
|
|
|
public bool IsMoving { get; private set; }
|
|
|
|
|
|
|
|
|
|
public bool IsResizing
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return ResizeManager.IsResizing;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-23 01:13:38 +12:00
|
|
|
|
public bool IsProportionalResizing { get; private set; }
|
|
|
|
|
public bool IsSnapResizing { get; private set; }
|
|
|
|
|
|
2015-09-25 18:39:08 +12:00
|
|
|
|
public List<SimpleWindowInfo> Windows { get; set; }
|
2013-11-03 23:53:49 +13:00
|
|
|
|
public bool WindowCaptureMode { get; set; }
|
2014-07-10 09:44:08 +12:00
|
|
|
|
public bool IncludeControls { get; set; }
|
2016-05-03 20:24:01 +12:00
|
|
|
|
public int MinimumSize { get; set; } = 3;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
|
|
|
|
private RectangleRegion surface;
|
2016-05-04 01:28:15 +12:00
|
|
|
|
private ContextMenuStrip cmsShapeMenu;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
|
|
|
|
public AreaManager(RectangleRegion surface)
|
|
|
|
|
{
|
|
|
|
|
this.surface = surface;
|
|
|
|
|
|
2016-05-04 01:28:15 +12:00
|
|
|
|
CurrentShapeType = surface.Config.CurrentShapeType;
|
|
|
|
|
|
2016-05-03 20:24:01 +12:00
|
|
|
|
ResizeManager = new ResizeManager(surface, this);
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
|
|
|
|
surface.MouseDown += surface_MouseDown;
|
|
|
|
|
surface.MouseUp += surface_MouseUp;
|
|
|
|
|
surface.KeyDown += surface_KeyDown;
|
|
|
|
|
surface.KeyUp += surface_KeyUp;
|
2016-05-04 01:28:15 +12:00
|
|
|
|
|
|
|
|
|
CreateShapeMenu();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateShapeMenu()
|
|
|
|
|
{
|
|
|
|
|
cmsShapeMenu = new ContextMenuStrip();
|
|
|
|
|
|
|
|
|
|
foreach (ShapeType shapeType in Helpers.GetEnums<ShapeType>())
|
|
|
|
|
{
|
|
|
|
|
ToolStripMenuItem tsmiShapeType = new ToolStripMenuItem(shapeType.GetLocalizedDescription());
|
|
|
|
|
tsmiShapeType.Checked = shapeType == CurrentShapeType;
|
|
|
|
|
tsmiShapeType.Click += (sender, e) =>
|
|
|
|
|
{
|
|
|
|
|
tsmiShapeType.RadioCheck();
|
|
|
|
|
ChangeCurrentShapeType(shapeType);
|
|
|
|
|
};
|
|
|
|
|
cmsShapeMenu.Items.Add(tsmiShapeType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cmsShapeMenu.Items.Add(new ToolStripSeparator());
|
|
|
|
|
|
|
|
|
|
ToolStripMenuItem tsmiChangeBorderColor = new ToolStripMenuItem("Change border color...");
|
|
|
|
|
cmsShapeMenu.Items.Add(tsmiChangeBorderColor);
|
|
|
|
|
ToolStripMenuItem tsmiChangeBorderSize = new ToolStripMenuItem("Change border size...");
|
|
|
|
|
cmsShapeMenu.Items.Add(tsmiChangeBorderSize);
|
|
|
|
|
ToolStripMenuItem tsmiChangeFillColor = new ToolStripMenuItem("Change fill color...");
|
|
|
|
|
cmsShapeMenu.Items.Add(tsmiChangeFillColor);
|
|
|
|
|
|
|
|
|
|
cmsShapeMenu.Items.Add(new ToolStripSeparator());
|
|
|
|
|
|
|
|
|
|
ToolStripMenuItem tsmiCloseMenu = new ToolStripMenuItem("Close");
|
|
|
|
|
tsmiCloseMenu.Click += (sender, e) => cmsShapeMenu.Close();
|
|
|
|
|
cmsShapeMenu.Items.Add(tsmiCloseMenu);
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void surface_KeyDown(object sender, KeyEventArgs e)
|
|
|
|
|
{
|
2015-08-05 00:40:25 +12:00
|
|
|
|
switch (e.KeyCode)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2015-08-20 04:29:00 +12:00
|
|
|
|
case Keys.Insert:
|
|
|
|
|
if (IsCreating)
|
|
|
|
|
{
|
|
|
|
|
EndRegionSelection();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-08-21 04:29:10 +12:00
|
|
|
|
if (ResizeManager.Visible)
|
|
|
|
|
{
|
|
|
|
|
DeselectArea();
|
|
|
|
|
}
|
2016-05-03 20:24:01 +12:00
|
|
|
|
|
|
|
|
|
if (CurrentShape == null || CurrentShape != AreaIntersect())
|
2015-08-21 04:29:10 +12:00
|
|
|
|
{
|
|
|
|
|
RegionSelection(InputManager.MousePosition);
|
|
|
|
|
}
|
2015-08-20 04:29:00 +12:00
|
|
|
|
}
|
|
|
|
|
break;
|
2015-07-17 07:07:06 +12:00
|
|
|
|
case Keys.ShiftKey:
|
2015-08-23 01:13:38 +12:00
|
|
|
|
IsProportionalResizing = true;
|
2015-07-17 07:07:06 +12:00
|
|
|
|
break;
|
2015-08-21 05:33:28 +12:00
|
|
|
|
case Keys.Menu:
|
2015-08-23 01:13:38 +12:00
|
|
|
|
IsSnapResizing = true;
|
2015-08-14 07:23:51 +12:00
|
|
|
|
break;
|
2015-07-17 07:07:06 +12:00
|
|
|
|
case Keys.NumPad1:
|
2016-05-03 23:39:44 +12:00
|
|
|
|
ChangeCurrentShapeType(ShapeType.RegionRectangle);
|
2015-07-17 07:07:06 +12:00
|
|
|
|
break;
|
|
|
|
|
case Keys.NumPad2:
|
2016-05-03 23:39:44 +12:00
|
|
|
|
ChangeCurrentShapeType(ShapeType.RegionRoundedRectangle);
|
2015-07-17 07:07:06 +12:00
|
|
|
|
break;
|
|
|
|
|
case Keys.NumPad3:
|
2016-05-03 23:39:44 +12:00
|
|
|
|
ChangeCurrentShapeType(ShapeType.RegionEllipse);
|
2015-07-17 07:07:06 +12:00
|
|
|
|
break;
|
|
|
|
|
case Keys.NumPad4:
|
2016-05-03 23:39:44 +12:00
|
|
|
|
ChangeCurrentShapeType(ShapeType.RegionTriangle);
|
2015-07-17 07:07:06 +12:00
|
|
|
|
break;
|
|
|
|
|
case Keys.NumPad5:
|
2016-05-03 23:39:44 +12:00
|
|
|
|
ChangeCurrentShapeType(ShapeType.RegionDiamond);
|
2016-05-03 21:35:10 +12:00
|
|
|
|
break;
|
2016-05-03 22:06:58 +12:00
|
|
|
|
case Keys.NumPad7:
|
2016-05-03 23:39:44 +12:00
|
|
|
|
ChangeCurrentShapeType(ShapeType.DrawingRectangle);
|
2016-05-03 21:35:10 +12:00
|
|
|
|
break;
|
2016-05-03 22:06:58 +12:00
|
|
|
|
case Keys.NumPad8:
|
2016-05-03 23:39:44 +12:00
|
|
|
|
ChangeCurrentShapeType(ShapeType.DrawingRoundedRectangle);
|
2016-05-03 22:06:58 +12:00
|
|
|
|
break;
|
2016-05-03 21:35:10 +12:00
|
|
|
|
case Keys.Add:
|
|
|
|
|
switch (CurrentShapeType)
|
|
|
|
|
{
|
|
|
|
|
case ShapeType.RegionRoundedRectangle:
|
|
|
|
|
RoundedRectangleRadius += RoundedRectangleRadiusIncrement;
|
|
|
|
|
UpdateRoundedRectangle();
|
|
|
|
|
break;
|
|
|
|
|
case ShapeType.RegionTriangle:
|
|
|
|
|
if (TriangleAngle == TriangleAngle.Left)
|
|
|
|
|
{
|
|
|
|
|
TriangleAngle = TriangleAngle.Top;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TriangleAngle++;
|
|
|
|
|
}
|
|
|
|
|
UpdateTriangle();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Keys.Subtract:
|
|
|
|
|
switch (CurrentShapeType)
|
|
|
|
|
{
|
|
|
|
|
case ShapeType.RegionRoundedRectangle:
|
|
|
|
|
RoundedRectangleRadius = Math.Max(0, RoundedRectangleRadius - RoundedRectangleRadiusIncrement);
|
|
|
|
|
UpdateRoundedRectangle();
|
|
|
|
|
break;
|
|
|
|
|
case ShapeType.RegionTriangle:
|
|
|
|
|
if (TriangleAngle == TriangleAngle.Top)
|
|
|
|
|
{
|
|
|
|
|
TriangleAngle = TriangleAngle.Left;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TriangleAngle--;
|
|
|
|
|
}
|
|
|
|
|
UpdateTriangle();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-07-17 07:07:06 +12:00
|
|
|
|
break;
|
2016-05-03 21:35:10 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 23:39:44 +12:00
|
|
|
|
private void ChangeCurrentShapeType(ShapeType shapeType)
|
|
|
|
|
{
|
|
|
|
|
CurrentShapeType = shapeType;
|
|
|
|
|
surface.Config.CurrentShapeType = shapeType;
|
|
|
|
|
DeselectArea();
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 21:35:10 +12:00
|
|
|
|
private void UpdateRoundedRectangle()
|
|
|
|
|
{
|
|
|
|
|
if (CurrentShape != null)
|
|
|
|
|
{
|
|
|
|
|
RoundedRectangleRegionShape roundedRectangleShape = CurrentShape as RoundedRectangleRegionShape;
|
|
|
|
|
|
|
|
|
|
if (roundedRectangleShape != null)
|
|
|
|
|
{
|
|
|
|
|
roundedRectangleShape.Radius = RoundedRectangleRadius;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateTriangle()
|
|
|
|
|
{
|
|
|
|
|
if (CurrentShape != null)
|
|
|
|
|
{
|
|
|
|
|
TriangleRegionShape triangleShape = CurrentShape as TriangleRegionShape;
|
|
|
|
|
|
|
|
|
|
if (triangleShape != null)
|
|
|
|
|
{
|
|
|
|
|
triangleShape.Angle = TriangleAngle;
|
|
|
|
|
}
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void surface_KeyUp(object sender, KeyEventArgs e)
|
|
|
|
|
{
|
2015-05-07 04:17:58 +12:00
|
|
|
|
switch (e.KeyCode)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2015-05-07 04:17:58 +12:00
|
|
|
|
case Keys.ShiftKey:
|
2015-08-23 01:13:38 +12:00
|
|
|
|
IsProportionalResizing = false;
|
2015-05-07 04:17:58 +12:00
|
|
|
|
break;
|
2015-08-21 05:33:28 +12:00
|
|
|
|
case Keys.Menu:
|
2015-08-23 01:13:38 +12:00
|
|
|
|
IsSnapResizing = false;
|
2015-08-14 07:23:51 +12:00
|
|
|
|
break;
|
2015-05-07 04:17:58 +12:00
|
|
|
|
case Keys.Delete:
|
|
|
|
|
RemoveCurrentArea();
|
2015-08-21 04:29:10 +12:00
|
|
|
|
if (IsCreating)
|
|
|
|
|
{
|
|
|
|
|
EndRegionSelection();
|
|
|
|
|
}
|
2015-05-07 04:17:58 +12:00
|
|
|
|
break;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Update()
|
|
|
|
|
{
|
|
|
|
|
if (IsMoving)
|
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
Rectangle rect = CurrentRectangle;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
rect.X += InputManager.MouseVelocity.X;
|
|
|
|
|
rect.Y += InputManager.MouseVelocity.Y;
|
2016-05-03 20:24:01 +12:00
|
|
|
|
CurrentRectangle = rect;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 20:24:01 +12:00
|
|
|
|
if (IsCreating && !CurrentRectangle.IsEmpty)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2015-08-23 01:13:38 +12:00
|
|
|
|
CurrentPosition = InputManager.MousePosition0Based;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
2015-08-23 01:13:38 +12:00
|
|
|
|
Point newPosition = CurrentPosition;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
2015-08-23 01:13:38 +12:00
|
|
|
|
if (IsProportionalResizing)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2015-08-23 01:13:38 +12:00
|
|
|
|
newPosition = CaptureHelpers.ProportionalPosition(PositionOnClick, CurrentPosition);
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
|
2015-08-23 01:13:38 +12:00
|
|
|
|
if (IsSnapResizing)
|
2015-08-14 07:23:51 +12:00
|
|
|
|
{
|
2015-08-23 01:13:38 +12:00
|
|
|
|
newPosition = SnapPosition(PositionOnClick, newPosition);
|
2015-08-14 07:23:51 +12:00
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 20:24:01 +12:00
|
|
|
|
CurrentRectangle = CaptureHelpers.CreateRectangle(PositionOnClick, newPosition);
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CheckHover();
|
|
|
|
|
|
|
|
|
|
ResizeManager.Update();
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-14 07:23:51 +12:00
|
|
|
|
private Point SnapPosition(Point posOnClick, Point posCurrent)
|
|
|
|
|
{
|
|
|
|
|
Rectangle currentRect = CaptureHelpers.CreateRectangle(posOnClick, posCurrent);
|
|
|
|
|
Point newPosition = posCurrent;
|
|
|
|
|
|
2015-08-15 13:09:04 +12:00
|
|
|
|
foreach (SnapSize size in surface.Config.SnapSizes)
|
2015-08-14 07:23:51 +12:00
|
|
|
|
{
|
|
|
|
|
if (currentRect.Width.IsBetween(size.Width - surface.Config.SnapDistance, size.Width + surface.Config.SnapDistance) ||
|
|
|
|
|
currentRect.Height.IsBetween(size.Height - surface.Config.SnapDistance, size.Height + surface.Config.SnapDistance))
|
|
|
|
|
{
|
2015-08-23 01:13:38 +12:00
|
|
|
|
newPosition = CaptureHelpers.CalculateNewPosition(posOnClick, posCurrent, size);
|
|
|
|
|
break;
|
2015-08-14 07:23:51 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Rectangle newRect = CaptureHelpers.CreateRectangle(posOnClick, newPosition);
|
|
|
|
|
|
|
|
|
|
if (surface.ScreenRectangle0Based.Contains(newRect))
|
|
|
|
|
{
|
|
|
|
|
return newPosition;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return posCurrent;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-03 23:53:49 +13:00
|
|
|
|
private void CheckHover()
|
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
CurrentHoverRectangle = Rectangle.Empty;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
|
|
|
|
if (!ResizeManager.IsCursorOnNode() && !IsCreating && !IsMoving && !IsResizing)
|
|
|
|
|
{
|
|
|
|
|
Rectangle hoverArea = GetAreaIntersectWithMouse();
|
|
|
|
|
|
|
|
|
|
if (!hoverArea.IsEmpty)
|
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
CurrentHoverRectangle = hoverArea;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
2015-09-25 18:39:08 +12:00
|
|
|
|
else
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2015-09-25 18:39:08 +12:00
|
|
|
|
SimpleWindowInfo window = FindSelectedWindow();
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
2015-09-25 18:39:08 +12:00
|
|
|
|
if (window != null && !window.Rectangle.IsEmpty)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2015-09-25 18:39:08 +12:00
|
|
|
|
hoverArea = CaptureHelpers.ScreenToClient(window.Rectangle);
|
2016-05-03 20:24:01 +12:00
|
|
|
|
CurrentHoverRectangle = Rectangle.Intersect(surface.ScreenRectangle0Based, hoverArea);
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-25 18:39:08 +12:00
|
|
|
|
public SimpleWindowInfo FindSelectedWindow()
|
|
|
|
|
{
|
|
|
|
|
if (Windows != null)
|
|
|
|
|
{
|
|
|
|
|
return Windows.FirstOrDefault(x => x.Rectangle.Contains(InputManager.MousePosition));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-18 01:00:20 +13:00
|
|
|
|
public WindowInfo FindSelectedWindowInfo(Point mousePosition)
|
|
|
|
|
{
|
|
|
|
|
if (Windows != null)
|
|
|
|
|
{
|
2016-01-06 10:21:15 +13:00
|
|
|
|
SimpleWindowInfo windowInfo = Windows.FirstOrDefault(x => x.IsWindow && x.Rectangle.Contains(mousePosition));
|
2015-12-18 01:00:20 +13:00
|
|
|
|
|
|
|
|
|
if (windowInfo != null)
|
|
|
|
|
{
|
|
|
|
|
return windowInfo.WindowInfo;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-03 23:53:49 +13:00
|
|
|
|
private void surface_MouseDown(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
2015-08-20 04:29:00 +12:00
|
|
|
|
if (e.Button == MouseButtons.Left)
|
|
|
|
|
{
|
2015-08-21 04:29:10 +12:00
|
|
|
|
if (!IsCreating)
|
|
|
|
|
{
|
|
|
|
|
RegionSelection(e.Location);
|
|
|
|
|
}
|
2015-08-20 04:29:00 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void surface_MouseUp(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (e.Button == MouseButtons.Left)
|
|
|
|
|
{
|
2015-08-28 02:32:30 +12:00
|
|
|
|
if (IsMoving || IsCreating)
|
|
|
|
|
{
|
|
|
|
|
EndRegionSelection();
|
|
|
|
|
}
|
2015-08-20 04:29:00 +12:00
|
|
|
|
}
|
|
|
|
|
else if (e.Button == MouseButtons.Right)
|
|
|
|
|
{
|
|
|
|
|
CancelRegionSelection();
|
2015-08-28 02:32:30 +12:00
|
|
|
|
if (IsCreating)
|
|
|
|
|
{
|
|
|
|
|
EndRegionSelection();
|
|
|
|
|
}
|
2015-08-20 04:29:00 +12:00
|
|
|
|
}
|
2016-05-04 01:28:15 +12:00
|
|
|
|
else if (e.Button == MouseButtons.Middle)
|
|
|
|
|
{
|
|
|
|
|
cmsShapeMenu.Show(surface, e.Location);
|
|
|
|
|
}
|
2015-08-20 04:29:00 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RegionSelection(Point location)
|
|
|
|
|
{
|
|
|
|
|
if (ResizeManager.IsCursorOnNode())
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 20:24:01 +12:00
|
|
|
|
BaseShape shape = AreaIntersect(InputManager.MousePosition0Based);
|
|
|
|
|
|
2015-08-23 01:13:38 +12:00
|
|
|
|
PositionOnClick = InputManager.MousePosition0Based;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
2016-05-03 23:06:15 +12:00
|
|
|
|
if (shape != null && shape.ShapeType == CurrentShapeType) // Select area
|
2015-08-20 04:29:00 +12:00
|
|
|
|
{
|
|
|
|
|
IsMoving = true;
|
2016-05-03 20:24:01 +12:00
|
|
|
|
CurrentShape = shape;
|
2015-08-20 04:29:00 +12:00
|
|
|
|
SelectArea();
|
|
|
|
|
}
|
|
|
|
|
else if (!IsCreating) // Create new area
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2015-08-20 04:29:00 +12:00
|
|
|
|
DeselectArea();
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
2015-08-20 04:29:00 +12:00
|
|
|
|
Rectangle rect;
|
|
|
|
|
|
|
|
|
|
if (surface.Config.IsFixedSize)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
|
|
|
|
IsMoving = true;
|
2015-08-20 04:29:00 +12:00
|
|
|
|
rect = new Rectangle(new Point(location.X - surface.Config.FixedSize.Width / 2, location.Y - surface.Config.FixedSize.Height / 2), surface.Config.FixedSize);
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
2015-08-20 04:29:00 +12:00
|
|
|
|
else
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2015-08-20 04:29:00 +12:00
|
|
|
|
IsCreating = true;
|
|
|
|
|
rect = new Rectangle(location, new Size(1, 1));
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
2015-08-20 04:29:00 +12:00
|
|
|
|
|
2016-05-03 21:35:10 +12:00
|
|
|
|
AddRegionShape(rect);
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-20 04:29:00 +12:00
|
|
|
|
private void EndRegionSelection()
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2015-08-20 04:29:00 +12:00
|
|
|
|
IsCreating = false;
|
|
|
|
|
IsMoving = false;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
2016-05-03 20:24:01 +12:00
|
|
|
|
if (!CurrentRectangle.IsEmpty)
|
2015-08-20 04:29:00 +12:00
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
if (!IsCurrentRegionValid)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2015-08-20 04:29:00 +12:00
|
|
|
|
RemoveCurrentArea();
|
|
|
|
|
CheckHover();
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
2015-08-20 04:29:00 +12:00
|
|
|
|
else if (surface.Config.QuickCrop)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2015-08-20 04:29:00 +12:00
|
|
|
|
surface.UpdateRegionPath();
|
|
|
|
|
surface.Close(SurfaceResult.Region);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SelectArea();
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
}
|
2015-08-20 04:29:00 +12:00
|
|
|
|
|
2016-05-03 20:24:01 +12:00
|
|
|
|
if (!CurrentHoverRectangle.IsEmpty)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2016-05-03 21:35:10 +12:00
|
|
|
|
AddRegionShape(CurrentHoverRectangle);
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
2015-08-20 04:29:00 +12:00
|
|
|
|
if (surface.Config.QuickCrop)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2015-08-20 04:29:00 +12:00
|
|
|
|
surface.UpdateRegionPath();
|
|
|
|
|
surface.Close(SurfaceResult.Region);
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-08-20 04:29:00 +12:00
|
|
|
|
SelectArea();
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-20 04:29:00 +12:00
|
|
|
|
private void CancelRegionSelection()
|
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
BaseShape shape = AreaIntersect();
|
2015-08-20 04:29:00 +12:00
|
|
|
|
|
2016-05-03 20:24:01 +12:00
|
|
|
|
if (shape != null)
|
2015-08-20 04:29:00 +12:00
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
Shapes.Remove(shape);
|
2015-08-20 04:29:00 +12:00
|
|
|
|
DeselectArea();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
surface.Close(SurfaceResult.Close);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 21:35:10 +12:00
|
|
|
|
private void AddRegionShape(Rectangle rect)
|
2015-07-17 07:07:06 +12:00
|
|
|
|
{
|
2016-05-03 21:35:10 +12:00
|
|
|
|
BaseShape shape = CreateRegionShape(rect);
|
|
|
|
|
Shapes.Add(shape);
|
|
|
|
|
CurrentShape = shape;
|
2015-07-17 07:07:06 +12:00
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 21:35:10 +12:00
|
|
|
|
public BaseShape CreateRegionShape(Rectangle rect)
|
2015-07-17 07:07:06 +12:00
|
|
|
|
{
|
2016-05-03 21:35:10 +12:00
|
|
|
|
BaseShape shape;
|
2015-07-17 07:51:19 +12:00
|
|
|
|
|
2016-05-03 21:35:10 +12:00
|
|
|
|
switch (CurrentShapeType)
|
2015-07-17 07:51:19 +12:00
|
|
|
|
{
|
2016-05-03 21:35:10 +12:00
|
|
|
|
default:
|
|
|
|
|
case ShapeType.RegionRectangle:
|
|
|
|
|
shape = new RectangleRegionShape();
|
|
|
|
|
break;
|
|
|
|
|
case ShapeType.RegionRoundedRectangle:
|
|
|
|
|
shape = new RoundedRectangleRegionShape()
|
|
|
|
|
{
|
|
|
|
|
Radius = RoundedRectangleRadius
|
|
|
|
|
};
|
|
|
|
|
break;
|
|
|
|
|
case ShapeType.RegionEllipse:
|
|
|
|
|
shape = new EllipseRegionShape();
|
|
|
|
|
break;
|
|
|
|
|
case ShapeType.RegionTriangle:
|
|
|
|
|
shape = new TriangleRegionShape()
|
|
|
|
|
{
|
|
|
|
|
Angle = TriangleAngle
|
|
|
|
|
};
|
|
|
|
|
break;
|
|
|
|
|
case ShapeType.RegionDiamond:
|
|
|
|
|
shape = new DiamondRegionShape();
|
|
|
|
|
break;
|
|
|
|
|
case ShapeType.DrawingRectangle:
|
|
|
|
|
shape = new RectangleDrawingShape();
|
|
|
|
|
break;
|
|
|
|
|
case ShapeType.DrawingRoundedRectangle:
|
2016-05-03 23:39:44 +12:00
|
|
|
|
shape = new RoundedRectangleDrawingShape()
|
|
|
|
|
{
|
|
|
|
|
Radius = RoundedRectangleRadius
|
|
|
|
|
};
|
2016-05-03 21:35:10 +12:00
|
|
|
|
break;
|
2015-07-17 07:51:19 +12:00
|
|
|
|
}
|
2016-05-03 21:35:10 +12:00
|
|
|
|
|
|
|
|
|
shape.Rectangle = rect;
|
|
|
|
|
|
|
|
|
|
return shape;
|
2015-07-17 07:07:06 +12:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-03 23:53:49 +13:00
|
|
|
|
private void SelectArea()
|
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
if (!CurrentRectangle.IsEmpty && !surface.Config.IsFixedSize)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
|
|
|
|
ResizeManager.Show();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DeselectArea()
|
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
CurrentShape = null;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
ResizeManager.Hide();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RemoveCurrentArea()
|
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
BaseShape shape = CurrentShape;
|
2016-05-03 19:46:45 +12:00
|
|
|
|
|
|
|
|
|
if (shape != null)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2016-05-03 19:57:49 +12:00
|
|
|
|
Shapes.Remove(shape);
|
2013-11-03 23:53:49 +13:00
|
|
|
|
DeselectArea();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool IsAreaValid(Rectangle rect)
|
|
|
|
|
{
|
|
|
|
|
return !rect.IsEmpty && rect.Width >= MinimumSize && rect.Height >= MinimumSize;
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 20:24:01 +12:00
|
|
|
|
public BaseShape AreaIntersect(Point mousePosition)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
for (int i = Shapes.Count - 1; i >= 0; i--)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2016-05-03 23:39:44 +12:00
|
|
|
|
BaseShape shape = Shapes[i];
|
|
|
|
|
|
|
|
|
|
if (shape.ShapeType == CurrentShapeType && shape.Rectangle.Contains(mousePosition))
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2016-05-03 23:39:44 +12:00
|
|
|
|
return shape;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 20:24:01 +12:00
|
|
|
|
return null;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 20:24:01 +12:00
|
|
|
|
public BaseShape AreaIntersect()
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
|
|
|
|
return AreaIntersect(InputManager.MousePosition0Based);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Rectangle GetAreaIntersectWithMouse()
|
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
BaseShape shape = AreaIntersect();
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
2016-05-03 20:24:01 +12:00
|
|
|
|
if (shape != null)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
return shape.Rectangle;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Rectangle.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool IsAreaIntersect()
|
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
return AreaIntersect() != null;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Rectangle CombineAreas()
|
|
|
|
|
{
|
2016-05-03 20:24:01 +12:00
|
|
|
|
BaseShape[] areas = ValidRegions;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
2015-07-17 03:21:02 +12:00
|
|
|
|
if (areas.Length > 0)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2016-05-03 19:46:45 +12:00
|
|
|
|
Rectangle rect = areas[0].Rectangle;
|
2013-11-03 23:53:49 +13:00
|
|
|
|
|
2015-07-17 03:21:02 +12:00
|
|
|
|
for (int i = 1; i < areas.Length; i++)
|
2013-11-03 23:53:49 +13:00
|
|
|
|
{
|
2016-05-03 19:46:45 +12:00
|
|
|
|
rect = Rectangle.Union(rect, areas[i].Rectangle);
|
2013-11-03 23:53:49 +13:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rect;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Rectangle.Empty;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-09-01 22:43:03 +12:00
|
|
|
|
}
|