/// <summary> /// Updates the region of interest with a proposed region of interest ensuring /// the new region of interest is within the bounds of the video preview. When /// a new region of interest is set, the region of interest is redrawn. /// </summary> /// <param name="proposedRegionOfInterest"></param> public void SetRegionOfInterestWithProposedRegionOfInterest(CGRect proposedRegionOfInterest) { // We standardize to ensure we have positive widths and heights with an origin at the top left. var videoPreviewRect = this.VideoPreviewLayer.MapToLayerCoordinates(new CGRect(0, 0, 1, 1)).Standardize(); // Intersect the video preview view with the view's frame to only get // the visible portions of the video preview view. var visibleVideoPreviewRect = CGRect.Intersect(videoPreviewRect, this.Frame); var oldRegionOfInterest = this.RegionOfInterest; var newRegionOfInterest = proposedRegionOfInterest.Standardize(); // Move the region of interest in bounds. if (this.currentControlCorner == ControlCorner.None) { nfloat xOffset = 0; nfloat yOffset = 0; if (!visibleVideoPreviewRect.Contains(newRegionOfInterest.CornerTopLeft())) { xOffset = NMath.Max(visibleVideoPreviewRect.GetMinX() - newRegionOfInterest.GetMinX(), 0); yOffset = NMath.Max(visibleVideoPreviewRect.GetMinY() - newRegionOfInterest.GetMinY(), 0); } if (!visibleVideoPreviewRect.Contains(visibleVideoPreviewRect.CornerBottomRight())) { xOffset = NMath.Min(visibleVideoPreviewRect.GetMaxX() - newRegionOfInterest.GetMaxX(), xOffset); yOffset = NMath.Min(visibleVideoPreviewRect.GetMaxY() - newRegionOfInterest.GetMaxY(), yOffset); } newRegionOfInterest.Offset(xOffset, yOffset); } // Clamp the size when the region of interest is being resized. visibleVideoPreviewRect.Intersect(newRegionOfInterest); newRegionOfInterest = visibleVideoPreviewRect; // Fix a minimum width of the region of interest. if (proposedRegionOfInterest.Size.Width < this.MinimumRegionOfInterestSize) { switch (this.currentControlCorner) { case ControlCorner.TopLeft: case ControlCorner.BottomLeft: var x = oldRegionOfInterest.Location.X + oldRegionOfInterest.Size.Width - this.MinimumRegionOfInterestSize; newRegionOfInterest.X = x; newRegionOfInterest.Width = this.MinimumRegionOfInterestSize; break; case ControlCorner.TopRight: newRegionOfInterest.X = oldRegionOfInterest.Location.X; newRegionOfInterest.Width = this.MinimumRegionOfInterestSize; break; default: newRegionOfInterest.Location = oldRegionOfInterest.Location; newRegionOfInterest.Width = this.MinimumRegionOfInterestSize; break; } } // Fix a minimum height of the region of interest. if (proposedRegionOfInterest.Height < this.MinimumRegionOfInterestSize) { switch (currentControlCorner) { case ControlCorner.TopLeft: case ControlCorner.TopRight: newRegionOfInterest.Y = oldRegionOfInterest.Y + oldRegionOfInterest.Height - this.MinimumRegionOfInterestSize; newRegionOfInterest.Height = this.MinimumRegionOfInterestSize; break; case ControlCorner.BottomLeft: newRegionOfInterest.Y = oldRegionOfInterest.Y; newRegionOfInterest.Height = this.MinimumRegionOfInterestSize; break; default: newRegionOfInterest.Location = oldRegionOfInterest.Location; newRegionOfInterest.Height = this.MinimumRegionOfInterestSize; break; } } this.RegionOfInterest = newRegionOfInterest; this.SetNeedsLayout(); }
// Updates the region of interest with a proposed region of interest ensuring // the new region of interest is within the bounds of the video preview. When // a new region of interest is set, the region of interest is redrawn. public void SetRegionOfInterestWithProposedRegionOfInterest (CGRect proposedRegionOfInterest) { // We standardize to ensure we have positive widths and heights with an origin at the top left. var videoPreviewRect = VideoPreviewLayer.MapToLayerCoordinates (new CGRect (0, 0, 1, 1)).Standardize (); // Intersect the video preview view with the view's frame to only get // the visible portions of the video preview view. var visibleVideoPreviewRect = CGRect.Intersect (videoPreviewRect, Frame); var oldRegion = RegionOfInterest; var newRegion = proposedRegionOfInterest.Standardize (); // Move the region of interest in bounds. if (currentControlCorner == ControlCorner.None) { nfloat xOffset = 0; nfloat yOffset = 0; if (!visibleVideoPreviewRect.Contains (newRegion.CornerTopLeft())) { xOffset = NMath.Max (visibleVideoPreviewRect.GetMinX () - newRegion.GetMinX (), 0); yOffset = NMath.Max (visibleVideoPreviewRect.GetMinY () - newRegion.GetMinY (), 0); } if (!visibleVideoPreviewRect.Contains (visibleVideoPreviewRect.CornerBottomRight())) { xOffset = NMath.Min (visibleVideoPreviewRect.GetMaxX () - newRegion.GetMaxX (), xOffset); yOffset = NMath.Min (visibleVideoPreviewRect.GetMaxY () - newRegion.GetMaxY (), yOffset); } newRegion.Offset (xOffset, yOffset); } // Clamp the size when the region of interest is being resized. visibleVideoPreviewRect.Intersect(newRegion); newRegion = visibleVideoPreviewRect; // Fix a minimum width of the region of interest. if (proposedRegionOfInterest.Size.Width < MinimumRegionOfInterestSize) { switch (currentControlCorner) { case ControlCorner.TopLeft: case ControlCorner.BottomLeft: var x = oldRegion.Location.X + oldRegion.Size.Width - MinimumRegionOfInterestSize; newRegion = newRegion.WithX (x).WithWidth (MinimumRegionOfInterestSize); break; case ControlCorner.TopRight: newRegion = newRegion.WithX (oldRegion.Location.X) .WithWidth (MinimumRegionOfInterestSize); break; default: newRegion = newRegion.WithLocation (oldRegion.Location) .WithWidth (MinimumRegionOfInterestSize); break; } } // Fix a minimum height of the region of interest. if (proposedRegionOfInterest.Height < MinimumRegionOfInterestSize) { switch (currentControlCorner) { case ControlCorner.TopLeft: case ControlCorner.TopRight: newRegion = newRegion.WithY (oldRegion.Y + oldRegion.Height - MinimumRegionOfInterestSize) .WithHeight (MinimumRegionOfInterestSize); break; case ControlCorner.BottomLeft: newRegion = newRegion.WithY (oldRegion.Y) .WithHeight (MinimumRegionOfInterestSize); break; default: newRegion = newRegion.WithLocation (oldRegion.Location) .WithHeight (MinimumRegionOfInterestSize); break; } } RegionOfInterest = newRegion; SetNeedsLayout (); }