#region License Information (GPL v3)
/*
ShareX - A program that allows you to take screenshots and share any file type
Copyright (c) 2007-2016 ShareX Team
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 .
*/
#endregion License Information (GPL v3)
using ShareX.HelpersLib;
using ShareX.ScreenCaptureLib.Properties;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Windows.Forms;
namespace ShareX.ScreenCaptureLib
{
internal class ShapeManager : IDisposable
{
public List Shapes { get; private set; } = new List();
private BaseShape currentShape;
public BaseShape CurrentShape
{
get
{
return currentShape;
}
private set
{
currentShape = value;
if (currentShape != null)
{
currentShape.OnConfigSave();
}
OnCurrentShapeChanged(currentShape);
}
}
private ShapeType currentShapeType;
public ShapeType CurrentShapeType
{
get
{
return currentShapeType;
}
private set
{
currentShapeType = value;
if (form.IsAnnotationMode)
{
if (IsCurrentShapeTypeRegion)
{
Config.LastRegionTool = CurrentShapeType;
}
else
{
Config.LastAnnotationTool = CurrentShapeType;
}
UpdateCursor();
}
DeselectCurrentShape();
OnCurrentShapeTypeChanged(currentShapeType);
}
}
public Rectangle CurrentRectangle
{
get
{
if (CurrentShape != null)
{
return CurrentShape.Rectangle;
}
return Rectangle.Empty;
}
}
public bool IsCurrentShapeValid => CurrentShape != null && CurrentShape.IsValidShape;
public BaseShape[] Regions => Shapes.OfType().ToArray();
public BaseShape[] ValidRegions => Regions.Where(x => x.IsValidShape).ToArray();
public BaseDrawingShape[] DrawingShapes => Shapes.OfType().ToArray();
public BaseEffectShape[] EffectShapes => Shapes.OfType().ToArray();
public BaseShape CurrentHoverShape { get; private set; }
public bool IsCurrentHoverShapeValid => CurrentHoverShape != null && CurrentHoverShape.IsValidShape;
public bool IsCurrentShapeTypeRegion
{
get
{
return IsShapeTypeRegion(CurrentShapeType);
}
}
public bool IsCreating { get; set; }
public bool IsMoving { get; set; }
public bool IsResizing { get; set; }
public bool IsCornerMoving { get; private set; }
public bool IsProportionalResizing { get; private set; }
public bool IsSnapResizing { get; private set; }
public List Windows { get; set; }
public bool WindowCaptureMode { get; set; }
public bool IncludeControls { get; set; }
public RegionCaptureOptions Config { get; private set; }
public AnnotationOptions AnnotationOptions => Config.AnnotationOptions;
public List ResizeNodes { get; private set; }
private bool nodesVisible;
public bool NodesVisible
{
get
{
return nodesVisible;
}
set
{
nodesVisible = value;
if (!nodesVisible)
{
foreach (ResizeNode node in ResizeNodes)
{
node.Visible = false;
}
}
else
{
BaseShape shape = CurrentShape;
if (shape != null)
{
shape.OnNodePositionUpdate();
shape.OnNodeVisible();
}
}
}
}
public bool IsCursorOnNode => NodesVisible && ResizeNodes.Any(node => node.IsCursorHover);
public event Action CurrentShapeChanged;
public event Action CurrentShapeTypeChanged;
private RegionCaptureForm form;
private Form menuForm;
private ContextMenuStrip cmsContextMenu;
private ToolStripSeparator tssObjectOptions, tssShapeOptions;
private ToolStripButton tsbDeleteSelected, tsbDeleteAll;
private ToolStripMenuItem tsmiBorderColor, tsmiFillColor, tsmiHighlightColor, tsmiQuickCrop;
private ToolStripLabeledNumericUpDown tslnudBorderSize, tslnudCornerRadius, tslnudBlurRadius, tslnudPixelateSize;
private bool isLeftPressed, isRightPressed, isUpPressed, isDownPressed, allowOptionsMenu;
private Stopwatch cmsCloseTimer;
public ShapeManager(RegionCaptureForm form)
{
this.form = form;
Config = form.Config;
ResizeNodes = new List();
for (int i = 0; i < 9; i++)
{
ResizeNode node = new ResizeNode();
form.DrawableObjects.Add(node);
ResizeNodes.Add(node);
}
ResizeNodes[(int)NodePosition.BottomRight].Order = 10;
form.Shown += form_Shown;
form.LostFocus += form_LostFocus;
form.MouseDown += form_MouseDown;
form.MouseUp += form_MouseUp;
form.MouseDoubleClick += form_MouseDoubleClick;
form.MouseWheel += form_MouseWheel;
form.KeyDown += form_KeyDown;
form.KeyUp += form_KeyUp;
if (form.IsAnnotationMode)
{
CreateContextMenu();
}
CurrentShape = null;
if (form.Mode == RegionCaptureMode.Annotation)
{
CurrentShapeType = Config.LastRegionTool;
}
else if (form.Mode == RegionCaptureMode.Editor)
{
CurrentShapeType = Config.LastAnnotationTool;
}
else
{
CurrentShapeType = ShapeType.RegionRectangle;
}
}
private void form_Shown(object sender, EventArgs e)
{
CreateMenu();
}
private void CreateMenu()
{
menuForm = new Form()
{
AutoScaleDimensions = new SizeF(6F, 13F),
AutoScaleMode = AutoScaleMode.Font,
AutoSize = true,
AutoSizeMode = AutoSizeMode.GrowAndShrink,
ClientSize = new Size(759, 509),
FormBorderStyle = FormBorderStyle.None,
Location = new Point(100, 100),
ShowInTaskbar = false,
Text = "RegionCaptureFormMenu"
};
menuForm.SuspendLayout();
ToolStripEx tsMain = new ToolStripEx()
{
AutoSize = false,
CanOverflow = false,
ClickThrough = true,
Dock = DockStyle.None,
Location = new Point(0, 0),
Padding = new Padding(0, 0, 0, 0),
Size = new Size(552, 30),
TabIndex = 0,
Text = "ToolStrip"
};
menuForm.Controls.Add(tsMain);
#region Main
string buttonText;
if (form.Mode == RegionCaptureMode.Editor)
{
buttonText = "Cancel annotation";
}
else
{
buttonText = Resources.ShapeManager_CreateContextMenu_Cancel_capture;
}
ToolStripButton tsbCancelCapture = new ToolStripButton(buttonText);
tsbCancelCapture.DisplayStyle = ToolStripItemDisplayStyle.Image;
tsbCancelCapture.Image = Resources.prohibition;
tsbCancelCapture.MouseDown += (sender, e) => form.Close();
tsMain.Items.Add(tsbCancelCapture);
#endregion Main
#region Selected object
tssObjectOptions = new ToolStripSeparator();
tsMain.Items.Add(tssObjectOptions);
tsbDeleteSelected = new ToolStripButton(Resources.ShapeManager_CreateContextMenu_Delete_selected_object);
tsbDeleteSelected.DisplayStyle = ToolStripItemDisplayStyle.Image;
tsbDeleteSelected.Image = Resources.layer__minus;
tsbDeleteSelected.MouseDown += (sender, e) => DeleteCurrentShape();
tsMain.Items.Add(tsbDeleteSelected);
tsbDeleteAll = new ToolStripButton(Resources.ShapeManager_CreateContextMenu_Delete_all_objects);
tsbDeleteAll.DisplayStyle = ToolStripItemDisplayStyle.Image;
tsbDeleteAll.Image = Resources.minus;
tsbDeleteAll.MouseDown += (sender, e) => DeleteAllShapes();
tsMain.Items.Add(tsbDeleteAll);
#endregion Selected object
#region Tools
tsMain.Items.Add(new ToolStripSeparator());
foreach (ShapeType shapeType in Helpers.GetEnums())
{
if (form.Mode == RegionCaptureMode.Editor && IsShapeTypeRegion(shapeType))
{
continue;
}
ToolStripButton tsbShapeType = new ToolStripButton(shapeType.GetLocalizedDescription());
tsbShapeType.DisplayStyle = ToolStripItemDisplayStyle.Image;
Image img = null;
switch (shapeType)
{
case ShapeType.RegionRectangle:
img = Resources.layer_shape_region;
break;
case ShapeType.RegionRoundedRectangle:
img = Resources.layer_shape_round_region;
break;
case ShapeType.RegionEllipse:
img = Resources.layer_shape_ellipse_region;
break;
case ShapeType.RegionFreehand:
img = Resources.layer_shape_polygon;
break;
case ShapeType.DrawingRectangle:
img = Resources.layer_shape;
break;
case ShapeType.DrawingRoundedRectangle:
img = Resources.layer_shape_round;
break;
case ShapeType.DrawingEllipse:
img = Resources.layer_shape_ellipse;
break;
case ShapeType.DrawingFreehand:
img = Resources.layer_shape_curve;
break;
case ShapeType.DrawingLine:
img = Resources.layer_shape_line;
break;
case ShapeType.DrawingArrow:
img = Resources.layer_shape_arrow;
break;
case ShapeType.DrawingText:
img = Resources.layer_shape_text;
break;
case ShapeType.DrawingSpeechBalloon:
img = Resources.balloon_box_left;
break;
case ShapeType.DrawingStep:
img = Resources.counter_reset;
break;
case ShapeType.DrawingImage:
img = Resources.image;
break;
case ShapeType.EffectBlur:
img = Resources.layer_shade;
break;
case ShapeType.EffectPixelate:
img = Resources.grid;
break;
case ShapeType.EffectHighlight:
img = Resources.highlighter_text;
break;
}
tsbShapeType.Image = img;
tsbShapeType.Checked = shapeType == CurrentShapeType;
tsbShapeType.Tag = shapeType;
tsbShapeType.MouseDown += (sender, e) =>
{
tsbShapeType.RadioCheck();
CurrentShapeType = shapeType;
};
tsMain.Items.Add(tsbShapeType);
}
#endregion Tools
menuForm.ResumeLayout(false);
menuForm.Show(form);
UpdateContextMenu();
}
private void CreateContextMenu()
{
cmsContextMenu = new ContextMenuStrip(form.components);
cmsContextMenu.Renderer = new ToolStripCheckedBoldRenderer();
cmsContextMenu.IgnoreSeparatorClick();
cmsContextMenu.PreviewKeyDown += (sender, e) =>
{
if (e.KeyCode == Keys.Escape)
{
e.IsInputKey = true;
}
};
cmsContextMenu.KeyUp += (sender, e) =>
{
if (e.KeyCode == Keys.Escape)
{
cmsContextMenu.Close();
}
};
cmsContextMenu.Closed += (sender, e) =>
{
if (e.CloseReason == ToolStripDropDownCloseReason.AppClicked)
{
cmsCloseTimer = Stopwatch.StartNew();
}
};
#region Editor mode
if (form.Mode == RegionCaptureMode.Editor)
{
ToolStripMenuItem tsmiCompleteEdit = new ToolStripMenuItem("Run after capture tasks");
tsmiCompleteEdit.Image = Resources.tick;
tsmiCompleteEdit.Click += (sender, e) => form.Close(RegionResult.AnnotateRunAfterCaptureTasks);
cmsContextMenu.Items.Add(tsmiCompleteEdit);
ToolStripMenuItem tsmiSaveImage = new ToolStripMenuItem("Save image");
tsmiSaveImage.Enabled = !string.IsNullOrEmpty(form.ImageFilePath);
tsmiSaveImage.Image = Resources.disk_black;
tsmiSaveImage.Click += (sender, e) => form.Close(RegionResult.AnnotateSaveImage);
cmsContextMenu.Items.Add(tsmiSaveImage);
ToolStripMenuItem tsmiSaveImageAs = new ToolStripMenuItem("Save image as...");
tsmiSaveImageAs.Image = Resources.disks_black;
tsmiSaveImageAs.Click += (sender, e) => form.Close(RegionResult.AnnotateSaveImageAs);
cmsContextMenu.Items.Add(tsmiSaveImageAs);
ToolStripMenuItem tsmiCopyImage = new ToolStripMenuItem("Copy image to clipboard");
tsmiCopyImage.Image = Resources.clipboard;
tsmiCopyImage.Click += (sender, e) => form.Close(RegionResult.AnnotateCopyImage);
cmsContextMenu.Items.Add(tsmiCopyImage);
ToolStripMenuItem tsmiUploadImage = new ToolStripMenuItem("Upload image");
tsmiUploadImage.Image = Resources.drive_globe;
tsmiUploadImage.Click += (sender, e) => form.Close(RegionResult.AnnotateUploadImage);
cmsContextMenu.Items.Add(tsmiUploadImage);
ToolStripMenuItem tsmiPrintImage = new ToolStripMenuItem("Print image...");
tsmiPrintImage.Image = Resources.printer;
tsmiPrintImage.Click += (sender, e) => form.Close(RegionResult.AnnotatePrintImage);
cmsContextMenu.Items.Add(tsmiPrintImage);
ToolStripSeparator tssEditorMode = new ToolStripSeparator();
cmsContextMenu.Items.Add(tssEditorMode);
}
#endregion Editor mode
#region Shape options
tssShapeOptions = new ToolStripSeparator();
cmsContextMenu.Items.Add(tssShapeOptions);
tsmiBorderColor = new ToolStripMenuItem(Resources.ShapeManager_CreateContextMenu_Border_color___);
tsmiBorderColor.Click += (sender, e) =>
{
PauseForm();
ShapeType shapeType = CurrentShapeType;
Color borderColor;
if (shapeType == ShapeType.DrawingText || shapeType == ShapeType.DrawingSpeechBalloon)
{
borderColor = AnnotationOptions.TextBorderColor;
}
else if (shapeType == ShapeType.DrawingStep)
{
borderColor = AnnotationOptions.StepBorderColor;
}
else
{
borderColor = AnnotationOptions.BorderColor;
}
using (ColorPickerForm dialogColor = new ColorPickerForm(borderColor))
{
if (dialogColor.ShowDialog() == DialogResult.OK)
{
if (shapeType == ShapeType.DrawingText || shapeType == ShapeType.DrawingSpeechBalloon)
{
AnnotationOptions.TextBorderColor = dialogColor.NewColor;
}
else if (shapeType == ShapeType.DrawingStep)
{
AnnotationOptions.StepBorderColor = dialogColor.NewColor;
}
else
{
AnnotationOptions.BorderColor = dialogColor.NewColor;
}
UpdateContextMenu();
UpdateCurrentShape();
UpdateCursor();
}
}
ResumeForm();
};
cmsContextMenu.Items.Add(tsmiBorderColor);
tslnudBorderSize = new ToolStripLabeledNumericUpDown(Resources.ShapeManager_CreateContextMenu_Border_size_);
tslnudBorderSize.Content.Minimum = 0;
tslnudBorderSize.Content.Maximum = 20;
tslnudBorderSize.Content.ValueChanged = (sender, e) =>
{
ShapeType shapeType = CurrentShapeType;
int borderSize = (int)tslnudBorderSize.Content.Value;
if (shapeType == ShapeType.DrawingText || shapeType == ShapeType.DrawingSpeechBalloon)
{
AnnotationOptions.TextBorderSize = borderSize;
}
else if (shapeType == ShapeType.DrawingStep)
{
AnnotationOptions.StepBorderSize = borderSize;
}
else
{
AnnotationOptions.BorderSize = borderSize;
}
UpdateCurrentShape();
UpdateCursor();
};
cmsContextMenu.Items.Add(tslnudBorderSize);
tsmiFillColor = new ToolStripMenuItem(Resources.ShapeManager_CreateContextMenu_Fill_color___);
tsmiFillColor.Click += (sender, e) =>
{
PauseForm();
ShapeType shapeType = CurrentShapeType;
Color fillColor;
if (shapeType == ShapeType.DrawingText || shapeType == ShapeType.DrawingSpeechBalloon)
{
fillColor = AnnotationOptions.TextFillColor;
}
else if (shapeType == ShapeType.DrawingStep)
{
fillColor = AnnotationOptions.StepFillColor;
}
else
{
fillColor = AnnotationOptions.FillColor;
}
using (ColorPickerForm dialogColor = new ColorPickerForm(fillColor))
{
if (dialogColor.ShowDialog() == DialogResult.OK)
{
if (shapeType == ShapeType.DrawingText || shapeType == ShapeType.DrawingSpeechBalloon)
{
AnnotationOptions.TextFillColor = dialogColor.NewColor;
}
else if (shapeType == ShapeType.DrawingStep)
{
AnnotationOptions.StepFillColor = dialogColor.NewColor;
}
else
{
AnnotationOptions.FillColor = dialogColor.NewColor;
}
UpdateContextMenu();
UpdateCurrentShape();
}
}
ResumeForm();
};
cmsContextMenu.Items.Add(tsmiFillColor);
tslnudCornerRadius = new ToolStripLabeledNumericUpDown(Resources.ShapeManager_CreateContextMenu_Corner_radius_);
tslnudCornerRadius.Content.Minimum = 0;
tslnudCornerRadius.Content.Maximum = 150;
tslnudCornerRadius.Content.Increment = 3;
tslnudCornerRadius.Content.ValueChanged = (sender, e) =>
{
ShapeType shapeType = CurrentShapeType;
if (shapeType == ShapeType.RegionRoundedRectangle || shapeType == ShapeType.DrawingRoundedRectangle)
{
AnnotationOptions.RoundedRectangleRadius = (int)tslnudCornerRadius.Content.Value;
}
else if (shapeType == ShapeType.DrawingText)
{
AnnotationOptions.TextCornerRadius = (int)tslnudCornerRadius.Content.Value;
}
UpdateCurrentShape();
};
cmsContextMenu.Items.Add(tslnudCornerRadius);
tslnudBlurRadius = new ToolStripLabeledNumericUpDown(Resources.ShapeManager_CreateContextMenu_Blur_radius_);
tslnudBlurRadius.Content.Minimum = 2;
tslnudBlurRadius.Content.Maximum = 100;
tslnudBlurRadius.Content.ValueChanged = (sender, e) =>
{
AnnotationOptions.BlurRadius = (int)tslnudBlurRadius.Content.Value;
UpdateCurrentShape();
};
cmsContextMenu.Items.Add(tslnudBlurRadius);
tslnudPixelateSize = new ToolStripLabeledNumericUpDown(Resources.ShapeManager_CreateContextMenu_Pixel_size_);
tslnudPixelateSize.Content.Minimum = 2;
tslnudPixelateSize.Content.Maximum = 100;
tslnudPixelateSize.Content.ValueChanged = (sender, e) =>
{
AnnotationOptions.PixelateSize = (int)tslnudPixelateSize.Content.Value;
UpdateCurrentShape();
};
cmsContextMenu.Items.Add(tslnudPixelateSize);
tsmiHighlightColor = new ToolStripMenuItem(Resources.ShapeManager_CreateContextMenu_Highlight_color___);
tsmiHighlightColor.Click += (sender, e) =>
{
PauseForm();
using (ColorPickerForm dialogColor = new ColorPickerForm(AnnotationOptions.HighlightColor))
{
if (dialogColor.ShowDialog() == DialogResult.OK)
{
AnnotationOptions.HighlightColor = dialogColor.NewColor;
UpdateContextMenu();
UpdateCurrentShape();
}
}
ResumeForm();
};
cmsContextMenu.Items.Add(tsmiHighlightColor);
#endregion Shape options
#region Capture
if (form.Mode != RegionCaptureMode.Editor)
{
cmsContextMenu.Items.Add(new ToolStripSeparator());
ToolStripMenuItem tsmiFullscreenCapture = new ToolStripMenuItem(Resources.ShapeManager_CreateContextMenu_Capture_fullscreen);
tsmiFullscreenCapture.Image = Resources.layer_fullscreen;
tsmiFullscreenCapture.Click += (sender, e) => form.Close(RegionResult.Fullscreen);
cmsContextMenu.Items.Add(tsmiFullscreenCapture);
ToolStripMenuItem tsmiActiveMonitorCapture = new ToolStripMenuItem(Resources.ShapeManager_CreateContextMenu_Capture_active_monitor);
tsmiActiveMonitorCapture.Image = Resources.monitor;
tsmiActiveMonitorCapture.Click += (sender, e) => form.Close(RegionResult.ActiveMonitor);
cmsContextMenu.Items.Add(tsmiActiveMonitorCapture);
ToolStripMenuItem tsmiMonitorCapture = new ToolStripMenuItem(Resources.ShapeManager_CreateContextMenu_Capture_monitor);
tsmiMonitorCapture.HideImageMargin();
tsmiMonitorCapture.Image = Resources.monitor_window;
cmsContextMenu.Items.Add(tsmiMonitorCapture);
tsmiMonitorCapture.DropDownItems.Clear();
Screen[] screens = Screen.AllScreens;
for (int i = 0; i < screens.Length; i++)
{
Screen screen = screens[i];
ToolStripMenuItem tsmi = new ToolStripMenuItem(string.Format("{0}. {1}x{2}", i + 1, screen.Bounds.Width, screen.Bounds.Height));
int index = i;
tsmi.Click += (sender, e) =>
{
form.MonitorIndex = index;
form.Close(RegionResult.Monitor);
};
tsmiMonitorCapture.DropDownItems.Add(tsmi);
}
}
#endregion Capture
#region Options
if (form.Mode != RegionCaptureMode.Editor)
{
cmsContextMenu.Items.Add(new ToolStripSeparator());
ToolStripMenuItem tsmiOptions = new ToolStripMenuItem(Resources.ShapeManager_CreateContextMenu_Options);
tsmiOptions.Image = Resources.gear;
cmsContextMenu.Items.Add(tsmiOptions);
tsmiQuickCrop = new ToolStripMenuItem(Resources.ShapeManager_CreateContextMenu_Multi_region_mode);
tsmiQuickCrop.Checked = !Config.QuickCrop;
tsmiQuickCrop.CheckOnClick = true;
tsmiQuickCrop.Click += (sender, e) => Config.QuickCrop = !tsmiQuickCrop.Checked;
tsmiOptions.DropDownItems.Add(tsmiQuickCrop);
ToolStripMenuItem tsmiTips = new ToolStripMenuItem(Resources.ShapeManager_CreateContextMenu_Show_tips);
tsmiTips.Checked = Config.ShowTips;
tsmiTips.CheckOnClick = true;
tsmiTips.Click += (sender, e) => Config.ShowTips = tsmiTips.Checked;
tsmiOptions.DropDownItems.Add(tsmiTips);
ToolStripMenuItem tsmiShowInfo = new ToolStripMenuItem(Resources.ShapeManager_CreateContextMenu_Show_position_and_size_info);
tsmiShowInfo.Checked = Config.ShowInfo;
tsmiShowInfo.CheckOnClick = true;
tsmiShowInfo.Click += (sender, e) => Config.ShowInfo = tsmiShowInfo.Checked;
tsmiOptions.DropDownItems.Add(tsmiShowInfo);
ToolStripMenuItem tsmiShowMagnifier = new ToolStripMenuItem(Resources.ShapeManager_CreateContextMenu_Show_magnifier);
tsmiShowMagnifier.Checked = Config.ShowMagnifier;
tsmiShowMagnifier.CheckOnClick = true;
tsmiShowMagnifier.Click += (sender, e) => Config.ShowMagnifier = tsmiShowMagnifier.Checked;
tsmiOptions.DropDownItems.Add(tsmiShowMagnifier);
ToolStripMenuItem tsmiUseSquareMagnifier = new ToolStripMenuItem(Resources.ShapeManager_CreateContextMenu_Square_shape_magnifier);
tsmiUseSquareMagnifier.Checked = Config.UseSquareMagnifier;
tsmiUseSquareMagnifier.CheckOnClick = true;
tsmiUseSquareMagnifier.Click += (sender, e) => Config.UseSquareMagnifier = tsmiUseSquareMagnifier.Checked;
tsmiOptions.DropDownItems.Add(tsmiUseSquareMagnifier);
ToolStripLabeledNumericUpDown tslnudMagnifierPixelCount = new ToolStripLabeledNumericUpDown(Resources.ShapeManager_CreateContextMenu_Magnifier_pixel_count_);
tslnudMagnifierPixelCount.Content.Minimum = RegionCaptureOptions.MagnifierPixelCountMinimum;
tslnudMagnifierPixelCount.Content.Maximum = RegionCaptureOptions.MagnifierPixelCountMaximum;
tslnudMagnifierPixelCount.Content.Increment = 2;
tslnudMagnifierPixelCount.Content.Value = Config.MagnifierPixelCount;
tslnudMagnifierPixelCount.Content.ValueChanged = (sender, e) => Config.MagnifierPixelCount = (int)tslnudMagnifierPixelCount.Content.Value;
tsmiOptions.DropDownItems.Add(tslnudMagnifierPixelCount);
ToolStripLabeledNumericUpDown tslnudMagnifierPixelSize = new ToolStripLabeledNumericUpDown(Resources.ShapeManager_CreateContextMenu_Magnifier_pixel_size_);
tslnudMagnifierPixelSize.Content.Minimum = RegionCaptureOptions.MagnifierPixelSizeMinimum;
tslnudMagnifierPixelSize.Content.Maximum = RegionCaptureOptions.MagnifierPixelSizeMaximum;
tslnudMagnifierPixelSize.Content.Value = Config.MagnifierPixelSize;
tslnudMagnifierPixelSize.Content.ValueChanged = (sender, e) => Config.MagnifierPixelSize = (int)tslnudMagnifierPixelSize.Content.Value;
tsmiOptions.DropDownItems.Add(tslnudMagnifierPixelSize);
ToolStripMenuItem tsmiShowCrosshair = new ToolStripMenuItem(Resources.ShapeManager_CreateContextMenu_Show_screen_wide_crosshair);
tsmiShowCrosshair.Checked = Config.ShowCrosshair;
tsmiShowCrosshair.CheckOnClick = true;
tsmiShowCrosshair.Click += (sender, e) => Config.ShowCrosshair = tsmiShowCrosshair.Checked;
tsmiOptions.DropDownItems.Add(tsmiShowCrosshair);
ToolStripMenuItem tsmiFixedSize = new ToolStripMenuItem(Resources.ShapeManager_CreateContextMenu_Fixed_size_region_mode);
tsmiFixedSize.Checked = Config.IsFixedSize;
tsmiFixedSize.CheckOnClick = true;
tsmiFixedSize.Click += (sender, e) => Config.IsFixedSize = tsmiFixedSize.Checked;
tsmiOptions.DropDownItems.Add(tsmiFixedSize);
ToolStripDoubleLabeledNumericUpDown tslnudFixedSize = new ToolStripDoubleLabeledNumericUpDown(Resources.ShapeManager_CreateContextMenu_Width_,
Resources.ShapeManager_CreateContextMenu_Height_);
tslnudFixedSize.Content.Minimum = 10;
tslnudFixedSize.Content.Maximum = 10000;
tslnudFixedSize.Content.Increment = 10;
tslnudFixedSize.Content.Value = Config.FixedSize.Width;
tslnudFixedSize.Content.Value2 = Config.FixedSize.Height;
tslnudFixedSize.Content.ValueChanged = (sender, e) => Config.FixedSize = new Size((int)tslnudFixedSize.Content.Value, (int)tslnudFixedSize.Content.Value2);
tsmiOptions.DropDownItems.Add(tslnudFixedSize);
ToolStripMenuItem tsmiShowFPS = new ToolStripMenuItem(Resources.ShapeManager_CreateContextMenu_Show_FPS);
tsmiShowFPS.Checked = Config.ShowFPS;
tsmiShowFPS.CheckOnClick = true;
tsmiShowFPS.Click += (sender, e) => Config.ShowFPS = tsmiShowFPS.Checked;
tsmiOptions.DropDownItems.Add(tsmiShowFPS);
}
#endregion Options
CurrentShapeTypeChanged += shapeType => UpdateContextMenu();
CurrentShapeChanged += shape => UpdateContextMenu();
}
private void UpdateContextMenu()
{
if (menuForm == null) return;
ShapeType shapeType = CurrentShapeType;
tssObjectOptions.Visible = tsbDeleteAll.Visible = Shapes.Count > 0;
tsbDeleteSelected.Visible = CurrentShape != null;
foreach (ToolStripMenuItem tsmi in cmsContextMenu.Items.OfType().Where(x => x.Tag is ShapeType))
{
if ((ShapeType)tsmi.Tag == shapeType)
{
tsmi.RadioCheck();
break;
}
}
Color borderColor;
if (shapeType == ShapeType.DrawingText || shapeType == ShapeType.DrawingSpeechBalloon)
{
borderColor = AnnotationOptions.TextBorderColor;
}
else if (shapeType == ShapeType.DrawingStep)
{
borderColor = AnnotationOptions.StepBorderColor;
}
else
{
borderColor = AnnotationOptions.BorderColor;
}
if (tsmiBorderColor.Image != null) tsmiBorderColor.Image.Dispose();
tsmiBorderColor.Image = ImageHelpers.CreateColorPickerIcon(borderColor, new Rectangle(0, 0, 16, 16));
int borderSize;
if (shapeType == ShapeType.DrawingText || shapeType == ShapeType.DrawingSpeechBalloon)
{
borderSize = AnnotationOptions.TextBorderSize;
}
else if (shapeType == ShapeType.DrawingStep)
{
borderSize = AnnotationOptions.StepBorderSize;
}
else
{
borderSize = AnnotationOptions.BorderSize;
}
tslnudBorderSize.Content.Value = borderSize;
Color fillColor;
if (shapeType == ShapeType.DrawingText || shapeType == ShapeType.DrawingSpeechBalloon)
{
fillColor = AnnotationOptions.TextFillColor;
}
else if (shapeType == ShapeType.DrawingStep)
{
fillColor = AnnotationOptions.StepFillColor;
}
else
{
fillColor = AnnotationOptions.FillColor;
}
if (tsmiFillColor.Image != null) tsmiFillColor.Image.Dispose();
tsmiFillColor.Image = ImageHelpers.CreateColorPickerIcon(fillColor, new Rectangle(0, 0, 16, 16));
int cornerRadius = 0;
if (shapeType == ShapeType.RegionRoundedRectangle || shapeType == ShapeType.DrawingRoundedRectangle)
{
cornerRadius = AnnotationOptions.RoundedRectangleRadius;
}
else if (shapeType == ShapeType.DrawingText)
{
cornerRadius = AnnotationOptions.TextCornerRadius;
}
tslnudCornerRadius.Content.Value = cornerRadius;
tslnudBlurRadius.Content.Value = AnnotationOptions.BlurRadius;
tslnudPixelateSize.Content.Value = AnnotationOptions.PixelateSize;
if (tsmiHighlightColor.Image != null) tsmiHighlightColor.Image.Dispose();
tsmiHighlightColor.Image = ImageHelpers.CreateColorPickerIcon(AnnotationOptions.HighlightColor, new Rectangle(0, 0, 16, 16));
switch (shapeType)
{
default:
tssShapeOptions.Visible = false;
break;
case ShapeType.RegionRoundedRectangle:
case ShapeType.DrawingRectangle:
case ShapeType.DrawingRoundedRectangle:
case ShapeType.DrawingEllipse:
case ShapeType.DrawingFreehand:
case ShapeType.DrawingLine:
case ShapeType.DrawingArrow:
case ShapeType.DrawingText:
case ShapeType.DrawingSpeechBalloon:
case ShapeType.DrawingStep:
case ShapeType.EffectBlur:
case ShapeType.EffectPixelate:
case ShapeType.EffectHighlight:
tssShapeOptions.Visible = true;
break;
}
switch (shapeType)
{
default:
tsmiBorderColor.Visible = false;
tslnudBorderSize.Visible = false;
break;
case ShapeType.DrawingRectangle:
case ShapeType.DrawingRoundedRectangle:
case ShapeType.DrawingEllipse:
case ShapeType.DrawingFreehand:
case ShapeType.DrawingLine:
case ShapeType.DrawingArrow:
case ShapeType.DrawingText:
case ShapeType.DrawingSpeechBalloon:
case ShapeType.DrawingStep:
tsmiBorderColor.Visible = true;
tslnudBorderSize.Visible = true;
break;
}
switch (shapeType)
{
default:
tsmiFillColor.Visible = false;
break;
case ShapeType.DrawingRectangle:
case ShapeType.DrawingRoundedRectangle:
case ShapeType.DrawingEllipse:
case ShapeType.DrawingText:
case ShapeType.DrawingSpeechBalloon:
case ShapeType.DrawingStep:
tsmiFillColor.Visible = true;
break;
}
switch (shapeType)
{
default:
tslnudCornerRadius.Visible = false;
break;
case ShapeType.RegionRoundedRectangle:
case ShapeType.DrawingRoundedRectangle:
case ShapeType.DrawingText:
tslnudCornerRadius.Visible = true;
break;
}
tslnudBlurRadius.Visible = shapeType == ShapeType.EffectBlur;
tslnudPixelateSize.Visible = shapeType == ShapeType.EffectPixelate;
tsmiHighlightColor.Visible = shapeType == ShapeType.EffectHighlight;
}
private void form_LostFocus(object sender, EventArgs e)
{
IsCornerMoving = IsProportionalResizing = IsSnapResizing = false;
}
private void form_MouseDown(object sender, MouseEventArgs e)
{
allowOptionsMenu = cmsCloseTimer == null || cmsCloseTimer.ElapsedMilliseconds > 100;
if (e.Button == MouseButtons.Left)
{
if (!IsCreating)
{
StartRegionSelection();
}
}
}
private void form_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (IsMoving || IsCreating)
{
EndRegionSelection();
}
}
else if (e.Button == MouseButtons.Right)
{
if (IsCreating)
{
DeleteCurrentShape();
EndRegionSelection();
}
else if (form.IsAnnotationMode)
{
RunAction(Config.MouseRightClickAction);
}
else if (IsShapeIntersect())
{
DeleteIntersectShape();
}
else
{
form.Close();
}
}
else if (e.Button == MouseButtons.Middle)
{
RunAction(Config.MouseMiddleClickAction);
}
else if (e.Button == MouseButtons.XButton1)
{
RunAction(Config.Mouse4ClickAction);
}
else if (e.Button == MouseButtons.XButton2)
{
RunAction(Config.Mouse5ClickAction);
}
}
private void form_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (IsCurrentShapeTypeRegion && ValidRegions.Length > 0)
{
form.UpdateRegionPath();
form.Close(RegionResult.Region);
}
else if (CurrentShape != null && !IsCreating)
{
CurrentShape.OnDoubleClicked();
}
}
}
private void form_MouseWheel(object sender, MouseEventArgs e)
{
if (Control.ModifierKeys.HasFlag(Keys.Control) && form.Mode == RegionCaptureMode.Annotation)
{
if (e.Delta > 0)
{
CurrentShapeType = CurrentShapeType.Previous();
}
else if (e.Delta < 0)
{
CurrentShapeType = CurrentShapeType.Next();
}
}
else
{
if (e.Delta > 0)
{
Config.MagnifierPixelCount = Math.Min(Config.MagnifierPixelCount + 2, RegionCaptureOptions.MagnifierPixelCountMaximum);
}
else if (e.Delta < 0)
{
Config.MagnifierPixelCount = Math.Max(Config.MagnifierPixelCount - 2, RegionCaptureOptions.MagnifierPixelCountMinimum);
}
}
}
private void form_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.ControlKey:
IsCornerMoving = true;
break;
case Keys.ShiftKey:
IsProportionalResizing = true;
break;
case Keys.Menu:
IsSnapResizing = true;
break;
case Keys.Left:
case Keys.A:
isLeftPressed = true;
break;
case Keys.Right:
case Keys.D:
isRightPressed = true;
break;
case Keys.Up:
case Keys.W:
isUpPressed = true;
break;
case Keys.Down:
case Keys.S:
isDownPressed = true;
break;
}
switch (e.KeyData)
{
case Keys.Insert:
if (IsCreating)
{
EndRegionSelection();
}
else
{
StartRegionSelection();
}
break;
case Keys.Control | Keys.Z:
UndoShape();
break;
}
if (!IsCreating)
{
if (form.Mode == RegionCaptureMode.Annotation)
{
switch (e.KeyData)
{
case Keys.Tab:
SwapShapeType();
break;
case Keys.NumPad0:
CurrentShapeType = ShapeType.RegionRectangle;
break;
}
}
if (form.IsAnnotationMode)
{
switch (e.KeyData)
{
case Keys.NumPad1:
CurrentShapeType = ShapeType.DrawingRectangle;
break;
case Keys.NumPad2:
CurrentShapeType = ShapeType.DrawingRoundedRectangle;
break;
case Keys.NumPad3:
CurrentShapeType = ShapeType.DrawingEllipse;
break;
case Keys.NumPad4:
CurrentShapeType = ShapeType.DrawingLine;
break;
case Keys.NumPad5:
CurrentShapeType = ShapeType.DrawingArrow;
break;
case Keys.NumPad6:
CurrentShapeType = ShapeType.DrawingText;
break;
case Keys.NumPad7:
CurrentShapeType = ShapeType.DrawingStep;
break;
case Keys.NumPad8:
CurrentShapeType = ShapeType.EffectBlur;
break;
case Keys.NumPad9:
CurrentShapeType = ShapeType.EffectPixelate;
break;
case Keys.Control | Keys.V:
PasteFromClipboard();
break;
}
}
}
int speed;
if (e.Shift)
{
speed = RegionCaptureOptions.MoveSpeedMaximum;
}
else
{
speed = RegionCaptureOptions.MoveSpeedMinimum;
}
int x = 0;
if (isLeftPressed)
{
x -= speed;
}
if (isRightPressed)
{
x += speed;
}
int y = 0;
if (isUpPressed)
{
y -= speed;
}
if (isDownPressed)
{
y += speed;
}
if (x != 0 || y != 0)
{
BaseShape shape = CurrentShape;
if (shape == null || IsCreating)
{
Cursor.Position = Cursor.Position.Add(x, y);
}
else
{
if (e.Control)
{
shape.Move(x, y);
}
else
{
shape.Resize(x, y, !e.Alt);
}
}
}
}
private void form_KeyUp(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.ControlKey:
IsCornerMoving = false;
break;
case Keys.ShiftKey:
IsProportionalResizing = false;
break;
case Keys.Menu:
IsSnapResizing = false;
break;
case Keys.Left:
case Keys.A:
isLeftPressed = false;
break;
case Keys.Right:
case Keys.D:
isRightPressed = false;
break;
case Keys.Up:
case Keys.W:
isUpPressed = false;
break;
case Keys.Down:
case Keys.S:
isDownPressed = false;
break;
}
switch (e.KeyData)
{
case Keys.Delete:
DeleteCurrentShape();
if (IsCreating)
{
EndRegionSelection();
}
break;
}
if (form.IsAnnotationMode)
{
switch (e.KeyData)
{
case Keys.Apps:
OpenOptionsMenu();
break;
case Keys.Q:
Config.QuickCrop = !Config.QuickCrop;
tsmiQuickCrop.Checked = !Config.QuickCrop;
break;
}
}
}
private void RunAction(RegionCaptureAction action)
{
switch (action)
{
case RegionCaptureAction.CancelCapture:
form.Close();
break;
case RegionCaptureAction.RemoveShapeCancelCapture:
if (IsShapeIntersect())
{
DeleteIntersectShape();
}
else
{
form.Close();
}
break;
case RegionCaptureAction.RemoveShape:
DeleteIntersectShape();
break;
case RegionCaptureAction.OpenOptionsMenu:
if (allowOptionsMenu)
{
OpenOptionsMenu();
}
break;
case RegionCaptureAction.SwapToolType:
SwapShapeType();
break;
case RegionCaptureAction.CaptureFullscreen:
form.Close(RegionResult.Fullscreen);
break;
case RegionCaptureAction.CaptureActiveMonitor:
form.Close(RegionResult.ActiveMonitor);
break;
}
}
public void Update()
{
OrderStepShapes();
BaseShape shape = CurrentShape;
if (shape != null)
{
shape.OnUpdate();
}
CheckHover();
UpdateNodes();
}
private void StartRegionSelection()
{
if (IsCursorOnNode)
{
return;
}
BaseShape shape = GetIntersectShape();
if (shape != null && shape.ShapeType == CurrentShapeType) // Select shape
{
IsMoving = true;
CurrentShape = shape;
SelectCurrentShape();
}
else if (!IsCreating) // Create new shape
{
DeselectCurrentShape();
shape = AddShape();
shape.OnCreating();
}
}
private void EndRegionSelection()
{
bool wasCreating = IsCreating;
IsCreating = false;
IsMoving = false;
BaseShape shape = CurrentShape;
if (shape != null)
{
if (!shape.IsValidShape)
{
shape.Rectangle = Rectangle.Empty;
CheckHover();
if (IsCurrentHoverShapeValid)
{
shape.Rectangle = CurrentHoverShape.Rectangle;
}
else
{
DeleteCurrentShape();
shape = null;
}
}
if (shape != null)
{
if (Config.QuickCrop && IsCurrentShapeTypeRegion)
{
form.UpdateRegionPath();
form.Close(RegionResult.Region);
}
else
{
if (wasCreating)
{
shape.OnCreated();
}
SelectCurrentShape();
}
}
}
}
private BaseShape AddShape()
{
BaseShape shape = CreateShape();
AddShape(shape);
return shape;
}
private void AddShape(BaseShape shape)
{
Shapes.Add(shape);
CurrentShape = shape;
}
private BaseShape CreateShape()
{
return CreateShape(CurrentShapeType);
}
private BaseShape CreateShape(ShapeType shapeType)
{
BaseShape shape;
switch (shapeType)
{
default:
case ShapeType.RegionRectangle:
shape = new RectangleRegionShape();
break;
case ShapeType.RegionRoundedRectangle:
shape = new RoundedRectangleRegionShape();
break;
case ShapeType.RegionEllipse:
shape = new EllipseRegionShape();
break;
case ShapeType.RegionFreehand:
shape = new FreehandRegionShape();
break;
case ShapeType.DrawingRectangle:
shape = new RectangleDrawingShape();
break;
case ShapeType.DrawingRoundedRectangle:
shape = new RoundedRectangleDrawingShape();
break;
case ShapeType.DrawingEllipse:
shape = new EllipseDrawingShape();
break;
case ShapeType.DrawingFreehand:
shape = new FreehandDrawingShape();
break;
case ShapeType.DrawingLine:
shape = new LineDrawingShape();
break;
case ShapeType.DrawingArrow:
shape = new ArrowDrawingShape();
break;
case ShapeType.DrawingText:
shape = new TextDrawingShape();
break;
case ShapeType.DrawingSpeechBalloon:
shape = new SpeechBalloonDrawingShape();
break;
case ShapeType.DrawingStep:
shape = new StepDrawingShape();
break;
case ShapeType.DrawingImage:
shape = new ImageDrawingShape();
break;
case ShapeType.EffectBlur:
shape = new BlurEffectShape();
break;
case ShapeType.EffectPixelate:
shape = new PixelateEffectShape();
break;
case ShapeType.EffectHighlight:
shape = new HighlightEffectShape();
break;
}
shape.Manager = this;
shape.OnConfigLoad();
return shape;
}
private void UpdateCurrentShape()
{
BaseShape shape = CurrentShape;
if (shape != null)
{
shape.OnConfigLoad();
}
}
private void SwapShapeType()
{
if (form.Mode == RegionCaptureMode.Annotation)
{
if (IsCurrentShapeTypeRegion)
{
CurrentShapeType = Config.LastAnnotationTool;
}
else
{
CurrentShapeType = Config.LastRegionTool;
}
}
}
private void OpenOptionsMenu()
{
SelectIntersectShape();
if (form.IsAnnotationMode && cmsContextMenu != null)
{
cmsContextMenu.Show(form, InputManager.MousePosition0Based.Add(-10, -10));
Config.ShowMenuTip = false;
}
}
public Point SnapPosition(Point posOnClick, Point posCurrent)
{
Size currentSize = CaptureHelpers.CreateRectangle(posOnClick, posCurrent).Size;
Vector2 vector = new Vector2(currentSize.Width, currentSize.Height);
SnapSize snapSize = (from size in Config.SnapSizes
let distance = MathHelpers.Distance(vector, new Vector2(size.Width, size.Height))
where distance > 0 && distance < RegionCaptureOptions.SnapDistance
orderby distance
select size).FirstOrDefault();
if (snapSize != null)
{
Point posNew = CaptureHelpers.CalculateNewPosition(posOnClick, posCurrent, snapSize);
Rectangle newRect = CaptureHelpers.CreateRectangle(posOnClick, posNew);
if (form.ScreenRectangle0Based.Contains(newRect))
{
return posNew;
}
}
return posCurrent;
}
private void CheckHover()
{
CurrentHoverShape = null;
if (!IsCursorOnNode && !IsCreating && !IsMoving && !IsResizing)
{
BaseShape shape = GetIntersectShape();
if (shape != null && shape.IsValidShape)
{
CurrentHoverShape = shape;
}
else
{
switch (CurrentShapeType)
{
case ShapeType.RegionFreehand:
case ShapeType.DrawingFreehand:
case ShapeType.DrawingLine:
case ShapeType.DrawingArrow:
case ShapeType.DrawingText:
case ShapeType.DrawingSpeechBalloon:
case ShapeType.DrawingStep:
case ShapeType.DrawingImage:
return;
}
if (Config.IsFixedSize && IsCurrentShapeTypeRegion)
{
Point location = InputManager.MousePosition0Based;
CurrentHoverShape = new RectangleRegionShape()
{
Rectangle = new Rectangle(new Point(location.X - Config.FixedSize.Width / 2, location.Y - Config.FixedSize.Height / 2), Config.FixedSize)
};
}
else
{
SimpleWindowInfo window = FindSelectedWindow();
if (window != null && !window.Rectangle.IsEmpty)
{
Rectangle hoverArea = CaptureHelpers.ScreenToClient(window.Rectangle);
CurrentHoverShape = new RectangleRegionShape()
{
Rectangle = Rectangle.Intersect(form.ScreenRectangle0Based, hoverArea)
};
}
}
}
}
}
public SimpleWindowInfo FindSelectedWindow()
{
if (Windows != null)
{
return Windows.FirstOrDefault(x => x.Rectangle.Contains(InputManager.MousePosition));
}
return null;
}
public WindowInfo FindSelectedWindowInfo(Point position)
{
if (Windows != null)
{
SimpleWindowInfo windowInfo = Windows.FirstOrDefault(x => x.IsWindow && x.Rectangle.Contains(position));
if (windowInfo != null)
{
return windowInfo.WindowInfo;
}
}
return null;
}
public Image RenderOutputImage(Image img)
{
Bitmap bmp = new Bitmap(img);
if (DrawingShapes.Length > 0 || EffectShapes.Length > 0)
{
using (Graphics g = Graphics.FromImage(bmp))
{
foreach (BaseEffectShape shape in EffectShapes)
{
if (shape != null)
{
shape.OnDrawFinal(g, bmp);
}
}
foreach (BaseDrawingShape shape in DrawingShapes)
{
if (shape != null)
{
shape.OnDraw(g);
}
}
}
}
return bmp;
}
private void SelectShape(BaseShape shape)
{
if (shape != null)
{
shape.ShowNodes();
}
}
private void SelectCurrentShape()
{
SelectShape(CurrentShape);
}
private void SelectIntersectShape()
{
BaseShape shape = GetIntersectShape();
if (shape != null)
{
CurrentShape = shape;
SelectShape(shape);
}
}
private void DeselectShape(BaseShape shape)
{
if (shape == CurrentShape)
{
CurrentShape = null;
NodesVisible = false;
}
}
private void DeselectCurrentShape()
{
DeselectShape(CurrentShape);
}
public void DeleteShape(BaseShape shape)
{
if (shape != null)
{
shape.Dispose();
Shapes.Remove(shape);
DeselectShape(shape);
}
}
private void DeleteCurrentShape()
{
DeleteShape(CurrentShape);
}
private void DeleteIntersectShape()
{
DeleteShape(GetIntersectShape());
}
private void DeleteAllShapes()
{
foreach (BaseShape shape in Shapes)
{
shape.Dispose();
}
Shapes.Clear();
DeselectCurrentShape();
}
public BaseShape GetIntersectShape()
{
return GetIntersectShape(InputManager.MousePosition0Based);
}
public BaseShape GetIntersectShape(Point position)
{
for (int i = Shapes.Count - 1; i >= 0; i--)
{
BaseShape shape = Shapes[i];
if (shape.ShapeType == CurrentShapeType && shape.Intersects(position))
{
return shape;
}
}
return null;
}
public bool IsShapeIntersect()
{
return GetIntersectShape() != null;
}
public void UndoShape()
{
if (Shapes.Count > 0)
{
DeleteShape(Shapes[Shapes.Count - 1]);
}
}
private bool IsShapeTypeRegion(ShapeType shapeType)
{
switch (shapeType)
{
case ShapeType.RegionRectangle:
case ShapeType.RegionRoundedRectangle:
case ShapeType.RegionEllipse:
case ShapeType.RegionFreehand:
return true;
}
return false;
}
private void UpdateNodes()
{
BaseShape shape = CurrentShape;
if (shape != null && NodesVisible)
{
if (InputManager.IsMouseDown(MouseButtons.Left))
{
shape.OnNodeUpdate();
}
else
{
IsResizing = false;
}
shape.OnNodePositionUpdate();
}
}
private void UpdateCursor()
{
try
{
Cursor cursor = Helpers.CreateCursor(Resources.Crosshair);
if ((CurrentShapeType == ShapeType.DrawingRectangle || CurrentShapeType == ShapeType.DrawingRoundedRectangle || CurrentShapeType == ShapeType.DrawingEllipse ||
CurrentShapeType == ShapeType.DrawingFreehand || CurrentShapeType == ShapeType.DrawingLine || CurrentShapeType == ShapeType.DrawingArrow) &&
Config.AnnotationOptions.BorderSize > 0)
{
using (Bitmap bmp = new Bitmap(32, 32))
using (Graphics g = Graphics.FromImage(bmp))
{
if (Config.AnnotationOptions.BorderSize < 5)
{
using (Pen pen = new Pen(Config.AnnotationOptions.BorderColor, Config.AnnotationOptions.BorderSize) { Alignment = PenAlignment.Inset })
{
g.DrawRectangleProper(pen, new Rectangle(0, 0, 10, 10));
}
}
else
{
using (Brush brush = new SolidBrush(Config.AnnotationOptions.BorderColor))
{
g.FillRectangle(brush, new Rectangle(0, 0, 10, 10));
}
}
cursor.Draw(g, new Rectangle(0, 0, 32, 32));
cursor.Dispose();
IntPtr iconPtr = IntPtr.Zero;
try
{
iconPtr = bmp.GetHicon();
IconInfo iconInfo = new IconInfo();
NativeMethods.GetIconInfo(iconPtr, out iconInfo);
iconInfo.xHotspot = 15;
iconInfo.yHotspot = 15;
iconInfo.fIcon = false;
IntPtr newIconPtr = NativeMethods.CreateIconIndirect(ref iconInfo);
cursor = new Cursor(newIconPtr);
}
finally
{
if (iconPtr != IntPtr.Zero) NativeMethods.DestroyIcon(iconPtr);
}
}
}
Cursor temp = form.Cursor;
form.Cursor = cursor;
if (temp != null) temp.Dispose();
}
catch (Exception e)
{
DebugHelper.WriteException(e);
}
}
public void PauseForm()
{
form.Pause();
}
public void ResumeForm()
{
form.Resume();
}
public void OrderStepShapes()
{
int i = 1;
foreach (StepDrawingShape shape in Shapes.OfType())
{
shape.Number = i++;
}
}
private void PasteFromClipboard()
{
if (Clipboard.ContainsImage())
{
Image img = ClipboardHelpers.GetImage();
if (img != null)
{
CurrentShapeType = ShapeType.DrawingImage;
ImageDrawingShape shape = (ImageDrawingShape)CreateShape(ShapeType.DrawingImage);
shape.StartPosition = shape.EndPosition = InputManager.MousePosition0Based;
shape.SetImage(img, true);
AddShape(shape);
SelectCurrentShape();
}
}
else if (Clipboard.ContainsText())
{
string text = Clipboard.GetText();
if (!string.IsNullOrEmpty(text))
{
CurrentShapeType = ShapeType.DrawingText;
TextDrawingShape shape = (TextDrawingShape)CreateShape(ShapeType.DrawingText);
shape.StartPosition = shape.EndPosition = InputManager.MousePosition0Based;
shape.Text = text.Trim();
shape.AutoSize(true);
AddShape(shape);
SelectCurrentShape();
}
}
}
private void OnCurrentShapeChanged(BaseShape shape)
{
if (CurrentShapeChanged != null)
{
CurrentShapeChanged(shape);
}
}
private void OnCurrentShapeTypeChanged(ShapeType shapeType)
{
if (CurrentShapeTypeChanged != null)
{
CurrentShapeTypeChanged(shapeType);
}
}
public void Dispose()
{
DeleteAllShapes();
}
}
}