From 22c217979658b4dbacedbda33dee15d9c2212580 Mon Sep 17 00:00:00 2001 From: Jaex Date: Wed, 23 Feb 2022 14:15:45 +0300 Subject: [PATCH] #5883: Also support active monitor mode in light and transparent region captures --- ShareX.HelpersLib/Extensions/Extensions.cs | 8 +--- ShareX.HelpersLib/Helpers/CaptureHelpers.cs | 32 +++++++++++++++ ShareX.HistoryLib/Forms/ImageHistoryForm.cs | 1 - .../Forms/RegionCaptureForm.cs | 7 ++-- .../Forms/RegionCaptureLightForm.cs | 41 +++++++++++++------ .../Forms/RegionCaptureTransparentForm.cs | 37 ++++++++++++----- .../RegionHelpers/ImageEditorScrollbar.cs | 6 +-- ShareX/CaptureHelpers/CaptureRegion.cs | 7 +++- 8 files changed, 101 insertions(+), 38 deletions(-) diff --git a/ShareX.HelpersLib/Extensions/Extensions.cs b/ShareX.HelpersLib/Extensions/Extensions.cs index 04361ec15..207720555 100644 --- a/ShareX.HelpersLib/Extensions/Extensions.cs +++ b/ShareX.HelpersLib/Extensions/Extensions.cs @@ -197,11 +197,7 @@ public static RectangleF Offset(this RectangleF rect, float offset) public static RectangleF Scale(this RectangleF rect, float scaleFactor) { - return new RectangleF( - rect.X * scaleFactor, - rect.Y * scaleFactor, - rect.Width * scaleFactor, - rect.Height * scaleFactor); + return new RectangleF(rect.X * scaleFactor, rect.Y * scaleFactor, rect.Width * scaleFactor, rect.Height * scaleFactor); } public static Rectangle Round(this RectangleF rect) @@ -248,7 +244,7 @@ public static Rectangle SizeOffset(this Rectangle rect, int offset) { return rect.SizeOffset(offset, offset); } - + public static RectangleF SizeOffset(this RectangleF rect, float offset) { return rect.SizeOffset(offset, offset); diff --git a/ShareX.HelpersLib/Helpers/CaptureHelpers.cs b/ShareX.HelpersLib/Helpers/CaptureHelpers.cs index e544b4fff..f0e2e73e6 100644 --- a/ShareX.HelpersLib/Helpers/CaptureHelpers.cs +++ b/ShareX.HelpersLib/Helpers/CaptureHelpers.cs @@ -192,6 +192,38 @@ public static bool CheckPixelColor(int x, int y, Color color, byte variation) targetColor.B.IsBetween((byte)(color.B - variation), (byte)(color.B + variation)); } + public static Rectangle CreateRectangle(int x, int y, int x2, int y2) + { + int width, height; + + if (x <= x2) + { + width = x2 - x + 1; + } + else + { + width = x - x2 + 1; + x = x2; + } + + if (y <= y2) + { + height = y2 - y + 1; + } + else + { + height = y - y2 + 1; + y = y2; + } + + return new Rectangle(x, y, width, height); + } + + public static Rectangle CreateRectangle(Point pos, Point pos2) + { + return CreateRectangle(pos.X, pos.Y, pos2.X, pos2.Y); + } + public static RectangleF CreateRectangle(float x, float y, float x2, float y2) { float width, height; diff --git a/ShareX.HistoryLib/Forms/ImageHistoryForm.cs b/ShareX.HistoryLib/Forms/ImageHistoryForm.cs index 2f132006e..793f100f2 100644 --- a/ShareX.HistoryLib/Forms/ImageHistoryForm.cs +++ b/ShareX.HistoryLib/Forms/ImageHistoryForm.cs @@ -28,7 +28,6 @@ using ShareX.HistoryLib.Properties; using System; using System.Collections.Generic; -using System.Drawing; using System.IO; using System.Linq; using System.Text.RegularExpressions; diff --git a/ShareX.ScreenCaptureLib/Forms/RegionCaptureForm.cs b/ShareX.ScreenCaptureLib/Forms/RegionCaptureForm.cs index 09812b3f6..b15521e74 100644 --- a/ShareX.ScreenCaptureLib/Forms/RegionCaptureForm.cs +++ b/ShareX.ScreenCaptureLib/Forms/RegionCaptureForm.cs @@ -261,8 +261,8 @@ private void InitializeComponent() Shown += RegionCaptureForm_Shown; KeyDown += RegionCaptureForm_KeyDown; MouseDown += RegionCaptureForm_MouseDown; - MouseEnter += RegionCaptureForm_MouseEnter; MouseWheel += RegionCaptureForm_MouseWheel; + MouseEnter += RegionCaptureForm_MouseEnter; Resize += RegionCaptureForm_Resize; LocationChanged += RegionCaptureForm_LocationChanged; LostFocus += RegionCaptureForm_LostFocus; @@ -743,8 +743,9 @@ private void Zoom(bool zoomIn, bool atMouse = true) if (Pan(scaledCenterAfter.X - scaledCenterBefore.X, scaledCenterAfter.Y - scaledCenterBefore.Y)) { CanvasCenterOffset = new Vector2((CanvasRectangle.X + CanvasRectangle.Width / 2f) * ZoomFactor - clientCenter.X, - (CanvasRectangle.Y + CanvasRectangle.Height / 2f) * ZoomFactor - clientCenter.Y); + (CanvasRectangle.Y + CanvasRectangle.Height / 2f) * ZoomFactor - clientCenter.Y); } + UpdateTitle(); } @@ -876,7 +877,7 @@ protected override void OnPaint(PaintEventArgs e) if (IsEditorMode && !CanvasRectangle.Contains(ClientArea)) { g.Clear(canvasBackgroundColor); - g.DrawRectangleProper(canvasBorderPen, CanvasRectangle.Offset(1F)); + g.DrawRectangleProper(canvasBorderPen, CanvasRectangle.Offset(1f)); } DrawBackground(g); diff --git a/ShareX.ScreenCaptureLib/Forms/RegionCaptureLightForm.cs b/ShareX.ScreenCaptureLib/Forms/RegionCaptureLightForm.cs index 24dfebb46..5c2fb8ac2 100644 --- a/ShareX.ScreenCaptureLib/Forms/RegionCaptureLightForm.cs +++ b/ShareX.ScreenCaptureLib/Forms/RegionCaptureLightForm.cs @@ -37,16 +37,14 @@ public sealed class RegionCaptureLightForm : Form { private const int MinimumRectangleSize = 3; - public static RectangleF LastSelectionRectangle0Based { get; private set; } + public static Rectangle LastSelectionRectangle0Based { get; private set; } - public RectangleF ScreenRectangle { get; private set; } - - public RectangleF ScreenRectangle0Based => new RectangleF(0, 0, ScreenRectangle.Width, ScreenRectangle.Height); - - public RectangleF SelectionRectangle { get; private set; } - - public RectangleF SelectionRectangle0Based => new RectangleF(SelectionRectangle.X - ScreenRectangle.X, SelectionRectangle.Y - ScreenRectangle.Y, + public Rectangle ScreenRectangle { get; private set; } + public Rectangle ScreenRectangle0Based => new Rectangle(0, 0, ScreenRectangle.Width, ScreenRectangle.Height); + public Rectangle SelectionRectangle { get; private set; } + public Rectangle SelectionRectangle0Based => new Rectangle(SelectionRectangle.X - ScreenRectangle.X, SelectionRectangle.Y - ScreenRectangle.Y, SelectionRectangle.Width, SelectionRectangle.Height); + public bool ActiveMonitorMode { get; private set; } private Timer timer; private Bitmap backgroundImage; @@ -56,7 +54,7 @@ public sealed class RegionCaptureLightForm : Form private bool isMouseDown; private Stopwatch penTimer; - public RegionCaptureLightForm(Screenshot screenshot) + public RegionCaptureLightForm(Screenshot screenshot, bool activeMonitorMode = false) { backgroundImage = screenshot.CaptureFullscreen(); backgroundBrush = new TextureBrush(backgroundImage); @@ -64,7 +62,17 @@ public RegionCaptureLightForm(Screenshot screenshot) borderDotPen2 = new Pen(Color.White, 1); borderDotPen2.DashPattern = new float[] { 5, 5 }; penTimer = Stopwatch.StartNew(); - ScreenRectangle = CaptureHelpers.GetScreenBounds(); + + ActiveMonitorMode = activeMonitorMode; + + if (ActiveMonitorMode) + { + ScreenRectangle = CaptureHelpers.GetActiveScreenBounds(); + } + else + { + ScreenRectangle = CaptureHelpers.GetScreenBounds(); + } InitializeComponent(); Icon = ShareXResources.Icon; @@ -92,7 +100,7 @@ private void InitializeComponent() AutoScaleMode = AutoScaleMode.None; StartPosition = FormStartPosition.Manual; - Bounds = Rectangle.Round(ScreenRectangle); + Bounds = ScreenRectangle; FormBorderStyle = FormBorderStyle.None; SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); Text = "ShareX - " + Resources.RectangleLight_InitializeComponent_Rectangle_capture_light; @@ -105,6 +113,7 @@ private void InitializeComponent() KeyUp += RectangleLight_KeyUp; MouseDown += RectangleLight_MouseDown; MouseUp += RectangleLight_MouseUp; + MouseEnter += RegionLight_MouseEnter; ResumeLayout(false); } @@ -162,9 +171,17 @@ private void RectangleLight_MouseUp(object sender, MouseEventArgs e) } } + private void RegionLight_MouseEnter(object sender, EventArgs e) + { + if (ActiveMonitorMode) + { + Cursor.Clip = Bounds; + } + } + public Bitmap GetAreaImage() { - RectangleF rect = SelectionRectangle0Based; + Rectangle rect = SelectionRectangle0Based; if (rect.Width > 0 && rect.Height > 0) { diff --git a/ShareX.ScreenCaptureLib/Forms/RegionCaptureTransparentForm.cs b/ShareX.ScreenCaptureLib/Forms/RegionCaptureTransparentForm.cs index ef5cb6928..fc89f3930 100644 --- a/ShareX.ScreenCaptureLib/Forms/RegionCaptureTransparentForm.cs +++ b/ShareX.ScreenCaptureLib/Forms/RegionCaptureTransparentForm.cs @@ -37,21 +37,17 @@ public sealed class RegionCaptureTransparentForm : LayeredForm { private const int MinimumRectangleSize = 3; - public static RectangleF LastSelectionRectangle0Based { get; private set; } + public static Rectangle LastSelectionRectangle0Based { get; private set; } public Rectangle ScreenRectangle { get; private set; } - public Rectangle ScreenRectangle0Based => new Rectangle(0, 0, ScreenRectangle.Width, ScreenRectangle.Height); - public Rectangle SelectionRectangle { get; private set; } - public Rectangle SelectionRectangle0Based => new Rectangle(SelectionRectangle.X - ScreenRectangle.X, SelectionRectangle.Y - ScreenRectangle.Y, SelectionRectangle.Width, SelectionRectangle.Height); - private Rectangle PreviousSelectionRectangle { get; set; } - - private Rectangle PreviousSelectionRectangle0Based => new Rectangle(PreviousSelectionRectangle.X - ScreenRectangle.X, PreviousSelectionRectangle.Y - ScreenRectangle.Y, - PreviousSelectionRectangle.Width, PreviousSelectionRectangle.Height); + private Rectangle PreviousSelectionRectangle0Based => new Rectangle(PreviousSelectionRectangle.X - ScreenRectangle.X, + PreviousSelectionRectangle.Y - ScreenRectangle.Y, PreviousSelectionRectangle.Width, PreviousSelectionRectangle.Height); + public bool ActiveMonitorMode { get; private set; } private Timer timer; private Bitmap backgroundImage; @@ -61,14 +57,24 @@ public sealed class RegionCaptureTransparentForm : LayeredForm private bool isMouseDown; private Stopwatch penTimer; - public RegionCaptureTransparentForm() + public RegionCaptureTransparentForm(bool activeMonitorMode = false) { clearPen = new Pen(Color.FromArgb(1, 0, 0, 0)); borderDotPen = new Pen(Color.Black, 1); borderDotPen2 = new Pen(Color.White, 1); borderDotPen2.DashPattern = new float[] { 5, 5 }; penTimer = Stopwatch.StartNew(); - ScreenRectangle = CaptureHelpers.GetScreenBounds(); + + ActiveMonitorMode = activeMonitorMode; + + if (ActiveMonitorMode) + { + ScreenRectangle = CaptureHelpers.GetActiveScreenBounds(); + } + else + { + ScreenRectangle = CaptureHelpers.GetScreenBounds(); + } backgroundImage = new Bitmap(ScreenRectangle.Width, ScreenRectangle.Height); gBackgroundImage = Graphics.FromImage(backgroundImage); @@ -88,6 +94,7 @@ public RegionCaptureTransparentForm() KeyUp += RectangleTransparent_KeyUp; MouseDown += RectangleTransparent_MouseDown; MouseUp += RectangleTransparent_MouseUp; + MouseEnter += RectangleTransparent_MouseEnter; timer = new Timer { Interval = 10 }; timer.Tick += timer_Tick; @@ -158,6 +165,14 @@ private void RectangleTransparent_MouseUp(object sender, MouseEventArgs e) } } + private void RectangleTransparent_MouseEnter(object sender, EventArgs e) + { + if (ActiveMonitorMode) + { + Cursor.Clip = Bounds; + } + } + public Bitmap GetAreaImage(Screenshot screenshot) { Rectangle rect = SelectionRectangle0Based; @@ -174,7 +189,7 @@ private void timer_Tick(object sender, EventArgs e) { currentPosition = CaptureHelpers.GetCursorPosition(); PreviousSelectionRectangle = SelectionRectangle; - SelectionRectangle = CaptureHelpers.CreateRectangle(positionOnClick.X, positionOnClick.Y, currentPosition.X, currentPosition.Y).Round(); + SelectionRectangle = CaptureHelpers.CreateRectangle(positionOnClick.X, positionOnClick.Y, currentPosition.X, currentPosition.Y); UpdateBackgroundImage(); } diff --git a/ShareX.ScreenCaptureLib/RegionHelpers/ImageEditorScrollbar.cs b/ShareX.ScreenCaptureLib/RegionHelpers/ImageEditorScrollbar.cs index 3ceccc98d..f227ec4cc 100644 --- a/ShareX.ScreenCaptureLib/RegionHelpers/ImageEditorScrollbar.cs +++ b/ShareX.ScreenCaptureLib/RegionHelpers/ImageEditorScrollbar.cs @@ -198,9 +198,9 @@ private void Scroll(Point position) float centerOffsetNew = ((trackLengthInternal / 2.0f) - mousePositionLocal) / trackLengthInternal * inImageSize; - Vector2 canvasCenterOffset = Orientation == Orientation.Horizontal - ? new Vector2(centerOffsetNew, form.CanvasCenterOffset.Y) - : new Vector2(form.CanvasCenterOffset.X, centerOffsetNew); + Vector2 canvasCenterOffset = Orientation == Orientation.Horizontal ? + new Vector2(centerOffsetNew, form.CanvasCenterOffset.Y) : + new Vector2(form.CanvasCenterOffset.X, centerOffsetNew); form.PanToOffset(canvasCenterOffset); } } diff --git a/ShareX/CaptureHelpers/CaptureRegion.cs b/ShareX/CaptureHelpers/CaptureRegion.cs index c6297cd2d..ce3a7a3b2 100644 --- a/ShareX/CaptureHelpers/CaptureRegion.cs +++ b/ShareX/CaptureHelpers/CaptureRegion.cs @@ -119,8 +119,10 @@ protected TaskMetadata ExecuteRegionCapture(TaskSettings taskSettings) protected TaskMetadata ExecuteRegionCaptureLight(TaskSettings taskSettings) { Bitmap bmp = null; + Screenshot screenshot = TaskHelpers.GetScreenshot(taskSettings); + bool activeMonitorMode = taskSettings.CaptureSettings.SurfaceOptions.ActiveMonitorMode; - using (RegionCaptureLightForm rectangleLight = new RegionCaptureLightForm(TaskHelpers.GetScreenshot(taskSettings))) + using (RegionCaptureLightForm rectangleLight = new RegionCaptureLightForm(screenshot, activeMonitorMode)) { if (rectangleLight.ShowDialog() == DialogResult.OK) { @@ -139,8 +141,9 @@ protected TaskMetadata ExecuteRegionCaptureLight(TaskSettings taskSettings) protected TaskMetadata ExecuteRegionCaptureTransparent(TaskSettings taskSettings) { Bitmap bmp = null; + bool activeMonitorMode = taskSettings.CaptureSettings.SurfaceOptions.ActiveMonitorMode; - using (RegionCaptureTransparentForm rectangleTransparent = new RegionCaptureTransparentForm()) + using (RegionCaptureTransparentForm rectangleTransparent = new RegionCaptureTransparentForm(activeMonitorMode)) { if (rectangleTransparent.ShowDialog() == DialogResult.OK) {