private async void Button_Click(object sender, RoutedEventArgs e) { var picker = new Windows.ApplicationModel.Contacts.ContactPicker(); picker.DesiredFieldsWithContactFieldType.Add(Windows.ApplicationModel.Contacts.ContactFieldType.Email); var contact = await picker.PickContactAsync(); if (contact == null) return; #if WINDOWS_APP var button = sender as Button; var visual = button.TransformToVisual(null); var point = visual.TransformPoint(new Windows.Foundation.Point()); var rect = new Windows.Foundation.Rect(point, button.RenderSize); Windows.ApplicationModel.Contacts.ContactManager.ShowContactCard(contact, rect); #elif WINDOWS_PHONE_APP var dialog = new Windows.UI.Popups.MessageDialog(contact.DisplayName); await dialog.ShowAsync(); #endif }
/// <summary> /// Zoom to rectangle area of the content /// </summary> /// <param name="rectangle">Rectangle area</param> /// <param name="usingContentCoordinates">Sets if content coordinates or screen coordinates was specified</param> public void ZoomToContent(Rect rectangle, bool usingContentCoordinates = true) { //if content isn't UIElement - return if (ContentVisual == null) { return; } // translate the region from the coordinate space of the content // to the coordinate space of the content presenter var transformer = ContentVisual.TransformToVisual(_presenter); var region = usingContentCoordinates ? new Rect( transformer.TransformPoint(new Point(rectangle.Top, rectangle.Left)), transformer.TransformPoint(new Point(rectangle.Bottom, rectangle.Right))) : rectangle; // calculate actual zoom, which must fit the entire selection // while maintaining a 1:1 ratio var aspectX = ActualWidth / region.Width; var aspectY = ActualHeight / region.Height; var newRelativeScale = aspectX < aspectY ? aspectX : aspectY; // ensure that the scale value alls within the valid range if (newRelativeScale > MaxZoom) { newRelativeScale = MaxZoom; } else if (newRelativeScale < MinZoom) { newRelativeScale = MinZoom; } var center = new Point(rectangle.X + rectangle.Width / 2, rectangle.Y + rectangle.Height / 2); var newRelativePosition = new Point((ActualWidth / 2 - center.X) * Zoom, (ActualHeight / 2 - center.Y) * Zoom); TranslateX = newRelativePosition.X; TranslateY = newRelativePosition.Y; Zoom = newRelativeScale; }
private static Drawable GetBackgroundDrawable(Brush background, Windows.Foundation.Rect drawArea, Paint fillPaint, Path maskingPath = null) { if (background is ImageBrush) { throw new InvalidOperationException($"This method should not be called for ImageBrush, use {nameof(DispatchSetImageBrushAsBackground)} instead"); } if (maskingPath == null) { var solidBrush = background as SolidColorBrush; if (solidBrush != null) { return(new ColorDrawable(solidBrush.ColorWithOpacity)); } if (fillPaint != null) { var linearDrawable = new PaintDrawable(); var drawablePaint = linearDrawable.Paint; drawablePaint.Color = fillPaint.Color; drawablePaint.SetShader(fillPaint.Shader); return(linearDrawable); } return(null); } var drawable = new PaintDrawable(); drawable.Shape = new PathShape(maskingPath, (float)drawArea.Width, (float)drawArea.Height); var paint = drawable.Paint; paint.Color = fillPaint.Color; paint.SetShader(fillPaint.Shader); return(drawable); }
protected internal override Shader GetShader(Rect destinationRect) { // Android LinearGradient requires two ore more stop points. if (GradientStops.Count >= 2) { var colors = GradientStops.SelectToArray(s => ((Android.Graphics.Color)s.Color).ToArgb()); var locations = GradientStops.SelectToArray(s => (float)s.Offset); var width = destinationRect.Width; var height = destinationRect.Height; var transform = RelativeTransform?.ToNative(size: new Windows.Foundation.Size(width, height), isBrush: true); //Matrix .MapPoints takes an array of floats var pts = MappingMode == BrushMappingMode.RelativeToBoundingBox ? new[] { (float)(StartPoint.X * width), (float)(StartPoint.Y * height), (float)(EndPoint.X * width), (float)(EndPoint.Y * height) } : new[] { (float)StartPoint.X, (float)StartPoint.Y, (float)EndPoint.X, (float)EndPoint.Y }; transform?.MapPoints(pts); return(new LinearGradient(pts[0], pts[1], pts[2], pts[3], colors, locations, Shader.TileMode.Clamp)); } return(null); }
/// <summary> /// Event handler for <see cref="System.Windows.Forms.Control.SizeChanged" />. If the size of the host control /// has changed, re-run Windows Forms layout on this Control instance. /// </summary> protected void OnWindowXamlHostSizeChanged(object sender, EventArgs e) { if (DesignMode) { return; } if (AutoSize) { if (ChildInternal != null) { // XamlContenHost Control.Size has changed. XAML must perform an Arrange pass. // The XAML Arrange pass will expand XAML content with 'HorizontalStretch' and // 'VerticalStretch' properties to the bounds of the XamlContentHost Control. var rect = new windows.Foundation.Rect(0, 0, Width, Height); rect.Width /= _lastDpi / 96.0f; rect.Height /= _lastDpi / 96.0f; _xamlSource.Content.Measure(new windows.Foundation.Size(rect.Width, rect.Height)); _xamlSource.Content.Arrange(rect); PerformLayout(); } } }
protected void DrawStroke(Android.Graphics.Canvas canvas, Windows.Foundation.Rect strokeArea, Action <Android.Graphics.Canvas, Windows.Foundation.Rect, Paint> drawingMethod) { if (HasStroke) { var strokeThickness = PhysicalStrokeThickness; using (var strokePaint = new Paint(Stroke.GetStrokePaint(strokeArea))) { SetStrokeDashEffect(strokePaint); if (strokeArea.HasZeroArea()) { //Draw the stroke as a fill because the shape has no area strokePaint.SetStyle(Paint.Style.Fill); canvas.DrawCircle((float)(strokeThickness / 2), (float)(strokeThickness / 2), (float)(strokeThickness / 2), strokePaint); } else { strokePaint.StrokeWidth = (float)strokeThickness; drawingMethod(canvas, strokeArea, strokePaint); } } } }
private void ZoomControl_PreviewMouseMove(object sender, PointerRoutedEventArgs e) { var pos = e.GetCurrentPoint(this).Position; switch (ModifierMode) { case ZoomViewModifierMode.None: return; case ZoomViewModifierMode.Pan: var pps = pos.Subtract(_mouseDownPos); var translatex = _startTranslate.X + pps.X; var translatey = _startTranslate.Y + pps.Y; TranslateX = translatex; TranslateY = translatey; //VF UpdateViewport(); break; case ZoomViewModifierMode.ZoomIn: break; case ZoomViewModifierMode.ZoomOut: break; case ZoomViewModifierMode.ZoomBox: var x = Math.Min(_mouseDownPos.X, pos.X); var y = Math.Min(_mouseDownPos.Y, pos.Y); var sizeX = Math.Abs(_mouseDownPos.X - pos.X); var sizeY = Math.Abs(_mouseDownPos.Y - pos.Y); ZoomBox = new Rect(x, y, sizeX, sizeY); break; default: throw new ArgumentOutOfRangeException(); } }
/// <summary> /// Transform bounds relative to FrameworkElement /// </summary> /// <param name="sibling1">base rectangle</param> /// <param name="sibling2">second of pair to transform</param> /// <returns>result of transformed rectangle</returns> private static windows.Foundation.Rect BoundsRelativeTo(FrameworkElement sibling1, System.Windows.Media.Visual sibling2) { windows.Foundation.Rect origin = default(windows.Foundation.Rect); if (sibling1 != null) { // TransformToVisual can throw an exception if two elements don't have a common ancestor try { var transform = sibling1.TransformToVisual(sibling2); var systemWindowsRect = transform.TransformBounds( new Rect(0, 0, sibling1.ActualWidth, sibling1.ActualHeight)); origin.X = systemWindowsRect.X; origin.Y = systemWindowsRect.Y; origin.Width = systemWindowsRect.Width; origin.Height = systemWindowsRect.Height; } catch (System.InvalidOperationException) { } } return(origin); }
private static IDisposable InnerCreateLayers(BindableView view, Windows.Foundation.Rect drawArea, Brush background, Thickness borderThickness, Brush borderBrush, CornerRadius cornerRadius, Action onImageSet ) { var disposables = new CompositeDisposable(); var physicalBorderThickness = borderThickness.LogicalToPhysicalPixels(); if (cornerRadius != 0) { using (Path path = new Path()) { path.SetFillType(Path.FillType.EvenOdd); var radius = new CornerRadius( topLeft: ViewHelper.LogicalToPhysicalPixels(cornerRadius.TopLeft), topRight: ViewHelper.LogicalToPhysicalPixels(cornerRadius.TopRight), bottomRight: ViewHelper.LogicalToPhysicalPixels(cornerRadius.BottomRight), bottomLeft: ViewHelper.LogicalToPhysicalPixels(cornerRadius.BottomLeft) ); var adjustedLineWidth = physicalBorderThickness.Top; var area = new Windows.Foundation.Rect(drawArea.Left, drawArea.Top, drawArea.Width, drawArea.Height); area.Inflate(-adjustedLineWidth / 2, -adjustedLineWidth / 2); // This represents the doubled radii used to draw arcs, with each one maxed at the area's size. // The width and height can vary for the same corner (elliptical arc) var topLeftDiameterHeight = Math.Min(radius.TopLeft * 2, area.Height); var topLeftDiameterWidth = Math.Min(radius.TopLeft * 2, area.Width); var topRightDiameterHeight = Math.Min(radius.TopRight * 2, area.Height); var topRightDiameterWidth = Math.Min(radius.TopRight * 2, area.Width); var bottomLeftDiameterHeight = Math.Min(radius.BottomLeft * 2, area.Height); var bottomLeftDiameterWidth = Math.Min(radius.BottomLeft * 2, area.Width); var bottomRightDiameterHeight = Math.Min(radius.BottomRight * 2, area.Height); var bottomRightDiameterWidth = Math.Min(radius.BottomRight * 2, area.Width); // Top line path.MoveTo((float)(area.X + topLeftDiameterWidth / 2), (float)(area.Y)); path.LineTo((float)(area.Right - topRightDiameterWidth / 2), (float)(area.Y)); // Top right corner path.ArcTo( new RectF( left: (float)(area.Right - topRightDiameterWidth), top: (float)(area.Y), bottom: (float)(area.Y + topRightDiameterHeight), right: (float)(area.Right) ), startAngle: 270, sweepAngle: 90 ); // Right line path.LineTo((float)area.Right, (float)(area.Bottom - bottomRightDiameterHeight / 2)); // Bottom right corner path.ArcTo( new RectF( left: (float)(area.Right - bottomRightDiameterWidth), top: (float)(area.Bottom - bottomRightDiameterHeight), bottom: (float)area.Bottom, right: (float)area.Right ), startAngle: 0, sweepAngle: 90 ); // Bottom line path.LineTo((float)(area.X + bottomLeftDiameterWidth / 2), (float)area.Bottom); // Bottom left corner path.ArcTo( new RectF( left: (float)area.X, top: (float)(area.Bottom - bottomLeftDiameterHeight), bottom: (float)area.Bottom, right: (float)(area.X + bottomLeftDiameterWidth) ), startAngle: 90, sweepAngle: 90 ); // Left line path.LineTo((float)area.X, (float)(area.Y + topLeftDiameterHeight / 2)); // Top left corner path.ArcTo( new RectF( left: (float)area.X, top: (float)area.Y, bottom: (float)(area.Y + topLeftDiameterHeight), right: (float)(area.X + topLeftDiameterWidth) ), startAngle: 180, sweepAngle: 90 ); path.Close(); //We only need to set a background if the drawArea is non-zero if (!drawArea.HasZeroArea()) { var imageBrushBackground = background as ImageBrush; if (imageBrushBackground != null) { //Copy the path because it will be disposed when we exit the using block var pathCopy = new Path(path); var setBackground = DispatchSetImageBrushAsBackground(view, imageBrushBackground, drawArea, onImageSet, pathCopy); disposables.Add(setBackground); } else { var fillPaint = background?.GetFillPaint(drawArea) ?? new Paint() { Color = Android.Graphics.Color.Transparent }; ExecuteWithNoRelayout(view, v => v.SetBackgroundDrawable(GetBackgroundDrawable(background, drawArea, fillPaint, path))); } disposables.Add(() => ExecuteWithNoRelayout(view, v => v.SetBackgroundDrawable(null))); } if (borderThickness != Thickness.Empty && borderBrush != null && !(borderBrush is ImageBrush)) { using (var strokePaint = new Paint(borderBrush.GetStrokePaint(drawArea))) { var overlay = GetOverlayDrawable(strokePaint, physicalBorderThickness, new Size((int)drawArea.Width, (int)drawArea.Height), path); if (overlay != null) { overlay.SetBounds(0, 0, view.Width, view.Height); SetOverlay(view, disposables, overlay); } } } } } else // No corner radius { //We only need to set a background if the drawArea is non-zero if (!drawArea.HasZeroArea()) { var imageBrushBackground = background as ImageBrush; if (imageBrushBackground != null) { var setBackground = DispatchSetImageBrushAsBackground(view, imageBrushBackground, drawArea, onImageSet); disposables.Add(setBackground); } else { var fillPaint = background?.GetFillPaint(drawArea) ?? new Paint() { Color = Android.Graphics.Color.Transparent }; ExecuteWithNoRelayout(view, v => v.SetBackgroundDrawable(GetBackgroundDrawable(background, drawArea, fillPaint))); } disposables.Add(() => ExecuteWithNoRelayout(view, v => v.SetBackgroundDrawable(null))); } if (borderBrush != null && !(borderBrush is ImageBrush)) { //TODO: Handle case that BorderBrush is an ImageBrush using (var strokePaint = borderBrush.GetStrokePaint(drawArea)) { var overlay = GetOverlayDrawable(strokePaint, physicalBorderThickness, new Size(view.Width, view.Height)); if (overlay != null) { overlay.SetBounds(0, 0, view.Width, view.Height); SetOverlay(view, disposables, overlay); } } } } return(disposables); }
//Need this because the current implementation of Foundation.Rect's "IsEmpty" // is not intended to convey information about the Rect's area. internal static bool HasZeroArea(this Windows.Foundation.Rect rect) { return(rect.Width * rect.Height == 0); }
public static bool IsIntersected(Rect r, Point a, Point b) { // var start = new Point(a.X, a.Y); /* line endpoints */ var codeA = GetIntersectionData(r, a); var codeB = GetIntersectionData(r, b); if (codeA.IsInside() && codeB.IsInside()) { return(true); } /* while one of the endpoints are outside of rectangle */ while (!codeA.IsInside() || !codeB.IsInside()) { /* if both points are at one rectangle side then line do not cross the rectangle */ if (codeA.SameSide(codeB)) { return(false); } /* select point with zero code */ sides code; Point c; /* one of the points */ if (!codeA.IsInside()) { code = codeA; c = a; } else { code = codeB; c = b; } /* if c is on the left of r then move c on the line x = r->x_min * if c is on the right side of r then move c on the line x = r->x_max */ if (code.Left) { c.Y += (a.Y - b.Y) * (r.Left - c.X) / (a.X - b.X); c.X = r.Left; } else if (code.Right) { c.Y += (a.Y - b.Y) * (r.Right - c.X) / (a.X - b.X); c.X = r.Right; }/* if c is below r then move c on the line y = r->y_min * if c above the r then move c on the line y = r->y_max */ else if (code.Bottom) { c.X += (a.X - b.X) * (r.Bottom - c.Y) / (a.Y - b.Y); c.Y = r.Bottom; } else if (code.Top) { c.X += (a.X - b.X) * (r.Top - c.Y) / (a.Y - b.Y); c.Y = r.Top; } /* refresh code */ if (code == codeA) { a = c; codeA = GetIntersectionData(r, a); } else { b = c; codeB = GetIntersectionData(r, b); } } return(true); }
private static IDisposable InnerCreateLayers(BindableView view, Windows.Foundation.Rect drawArea, Brush background, Thickness borderThickness, Brush borderBrush, CornerRadius cornerRadius, Action onImageSet ) { var disposables = new CompositeDisposable(); var physicalBorderThickness = borderThickness.LogicalToPhysicalPixels(); if (cornerRadius != 0) { var adjustedLineWidth = physicalBorderThickness.Top; // TODO: handle non-uniform BorderThickness correctly var adjustedArea = drawArea; adjustedArea.Inflate(-adjustedLineWidth / 2, -adjustedLineWidth / 2); using (var path = cornerRadius.GetOutlinePath(adjustedArea.ToRectF())) { path.SetFillType(Path.FillType.EvenOdd); //We only need to set a background if the drawArea is non-zero if (!drawArea.HasZeroArea()) { if (background is ImageBrush imageBrushBackground) { //Copy the path because it will be disposed when we exit the using block var pathCopy = new Path(path); var setBackground = DispatchSetImageBrushAsBackground(view, imageBrushBackground, drawArea, onImageSet, pathCopy); disposables.Add(setBackground); } else if (background is AcrylicBrush acrylicBrush) { var apply = acrylicBrush.Subscribe(view, drawArea, path); disposables.Add(apply); } else { var fillPaint = background?.GetFillPaint(drawArea) ?? new Paint() { Color = Android.Graphics.Color.Transparent }; ExecuteWithNoRelayout(view, v => v.SetBackgroundDrawable(Brush.GetBackgroundDrawable(background, drawArea, fillPaint, path))); } disposables.Add(() => ExecuteWithNoRelayout(view, v => v.SetBackgroundDrawable(null))); } if (borderThickness != Thickness.Empty && borderBrush != null && !(borderBrush is ImageBrush)) { using (var strokePaint = new Paint(borderBrush.GetStrokePaint(drawArea))) { var overlay = GetOverlayDrawable(strokePaint, physicalBorderThickness, new global::System.Drawing.Size((int)drawArea.Width, (int)drawArea.Height), path); if (overlay != null) { overlay.SetBounds(0, 0, view.Width, view.Height); SetOverlay(view, disposables, overlay); } } } } } else // No corner radius { //We only need to set a background if the drawArea is non-zero if (!drawArea.HasZeroArea()) { if (background is ImageBrush imageBrushBackground) { var setBackground = DispatchSetImageBrushAsBackground(view, imageBrushBackground, drawArea, onImageSet); disposables.Add(setBackground); } else if (background is AcrylicBrush acrylicBrush) { var apply = acrylicBrush.Subscribe(view, drawArea, maskingPath: null); disposables.Add(apply); } else { var fillPaint = background?.GetFillPaint(drawArea) ?? new Paint() { Color = Android.Graphics.Color.Transparent }; ExecuteWithNoRelayout(view, v => v.SetBackgroundDrawable(Brush.GetBackgroundDrawable(background, drawArea, fillPaint))); } disposables.Add(() => ExecuteWithNoRelayout(view, v => v.SetBackgroundDrawable(null))); } if (borderBrush != null && !(borderBrush is ImageBrush)) { //TODO: Handle case that BorderBrush is an ImageBrush using (var strokePaint = borderBrush.GetStrokePaint(drawArea)) { var overlay = GetOverlayDrawable(strokePaint, physicalBorderThickness, new global::System.Drawing.Size(view.Width, view.Height)); if (overlay != null) { overlay.SetBounds(0, 0, view.Width, view.Height); SetOverlay(view, disposables, overlay); } } } } return(disposables); }
public static Point GetEdgeEndpoint(Point source, Rect sourceSize, Point target, VertexShape shape) { switch (shape) { case VertexShape.Circle: return GetEdgeEndpointOnCircle(source, Math.Max(sourceSize.Height, sourceSize.Width) * .5, target); case VertexShape.Diamond: return GetEdgeEndpointOnDiamond(source, sourceSize.Width * .5, target); case VertexShape.Triangle: return GetEdgeEndpointOnTriangle(source, sourceSize.Width * .5, target); default: return GetEdgeEndpointOnRectangle(source, sourceSize, target); } }
/// <summary> /// Zoom to rectangle area (MAY BE DEPRECATED). Use ZoomToContent method instead. /// </summary> /// <param name="rect"></param> /// <param name="setDelta"></param> public void ZoomTo(Rect rect, bool setDelta = false) { ZoomToInternal(rect, setDelta); //VF UpdateViewFinderDisplayContentBounds(); //VF UpdateViewport(); }
private static void updateOverlay() { Windows.Foundation.Rect unionRect = BarcodeHelper.MWBgetScanningRect(0); int orientation = BarcodeLib.Scanner.MWBgetDirection(); int width = (int)currentCanvas.ActualWidth; int height = (int)currentCanvas.ActualHeight; if (width <= 0 || height == 0) { DispatcherTimer updateDelayed = new DispatcherTimer(); updateDelayed.Interval = TimeSpan.FromSeconds(0.2); updateDelayed.Tick += delegate { updateOverlay(); updateDelayed.Stop(); }; updateDelayed.Start(); return; } PageOrientation currentOrientation = (((PhoneApplicationFrame)Application.Current.RootVisual).Content as PhoneApplicationPage).Orientation; if ((currentOrientation & PageOrientation.LandscapeRight) == (PageOrientation.LandscapeRight)) { unionRect = new Windows.Foundation.Rect(100 - unionRect.Right, 100 -unionRect.Bottom, unionRect.Width, unionRect.Height); } else if ((currentOrientation & PageOrientation.PortraitUp) == (PageOrientation.PortraitUp)) { unionRect = new Windows.Foundation.Rect(100 - unionRect.Top - unionRect.Height, unionRect.Left, unionRect.Height,unionRect.Width); } int rectLeft = (int)((float)unionRect.Left * width / 100.0); int rectTop = (int)((float)unionRect.Top * height / 100.0); int rectWidth = (int)((float)unionRect.Width * width / 100.0); int rectHeight = (int)((float)unionRect.Height * height / 100.0); int rectRight = (int)((float)unionRect.Right * width / 100.0); int rectBottom = (int)((float)unionRect.Bottom * height / 100.0); if (isViewportVisible) { viewportLayer.Visibility = System.Windows.Visibility.Visible; var bitmapviewport = new WriteableBitmap(width, height); bitmapviewport.FillRectangle(0, 0, width, height, colorFromAlphaAndInt(viewportAlpha, 0)); int lineWidth2 = (int)(viewportLineWidth / 2.0); bitmapviewport.FillRectangle(rectLeft - lineWidth2, rectTop - lineWidth2, rectRight + lineWidth2, rectBottom + lineWidth2, colorFromAlphaAndInt(viewportLineAlpha, viewportLineColor)); bitmapviewport.FillRectangle(rectLeft, rectTop, rectRight, rectBottom, System.Windows.Media.Color.FromArgb(0, 0, 0, 0)); viewportLayer.Source = bitmapviewport; } else { viewportLayer.Visibility = System.Windows.Visibility.Collapsed; } if (isBlinkingLineVisible) { lineLayer.Visibility = System.Windows.Visibility.Visible; addAnimation(); if (width < height) { double pos1f = Math.Log(BarcodeLib.Scanner.MWB_SCANDIRECTION_HORIZONTAL) / Math.Log(2); double pos2f = Math.Log(BarcodeLib.Scanner.MWB_SCANDIRECTION_VERTICAL) / Math.Log(2); int pos1 = (int)(pos1f + 0.01); int pos2 = (int)(pos2f + 0.01); int bit1 = (orientation >> pos1) & 1;// bit at pos1 int bit2 = (orientation >> pos2) & 1;// bit at pos2 int mask = (bit2 << pos1) | (bit1 << pos2); orientation = orientation & 0xc; orientation = orientation | mask; } var bitmapLine = new WriteableBitmap(width, height); int lineWidth2 = (int)(blinkingLineWidth / 2.0); if (((orientation & BarcodeLib.Scanner.MWB_SCANDIRECTION_HORIZONTAL) > 0) || ((orientation & BarcodeLib.Scanner.MWB_SCANDIRECTION_OMNI) > 0)) { bitmapLine.FillRectangle(rectLeft, rectTop + rectHeight / 2 - lineWidth2, rectRight, rectTop + rectHeight / 2 + lineWidth2, colorFromAlphaAndInt(blinkingLineAlpha, blinkingLineColor)); } if (((orientation & BarcodeLib.Scanner.MWB_SCANDIRECTION_VERTICAL) > 0) || ((orientation & BarcodeLib.Scanner.MWB_SCANDIRECTION_OMNI) > 0)) { bitmapLine.FillRectangle(rectLeft + rectWidth / 2 - lineWidth2, rectTop, rectLeft + rectWidth / 2 + lineWidth2, rectBottom, colorFromAlphaAndInt(blinkingLineAlpha, blinkingLineColor)); } if ((orientation & BarcodeLib.Scanner.MWB_SCANDIRECTION_OMNI) > 0) { bitmapLine.DrawLine(rectLeft, rectTop, rectRight, rectBottom, colorFromAlphaAndInt(blinkingLineAlpha, blinkingLineColor)); bitmapLine.DrawLine(rectLeft, rectBottom, rectRight, rectTop, colorFromAlphaAndInt(blinkingLineAlpha, blinkingLineColor)); } lineLayer.Source = bitmapLine; } else { lineLayer.Visibility = System.Windows.Visibility.Collapsed; removeAnimation(); } }
/// <summary> /// Zoom to rectangle area of the content /// </summary> /// <param name="rectangle">Rectangle area</param> /// <param name="usingContentCoordinates">Sets if content coordinates or screen coordinates was specified</param> public void ZoomToContent(Rect rectangle, bool usingContentCoordinates = true) { //if content isn't UIElement - return if (ContentVisual == null) return; // translate the region from the coordinate space of the content // to the coordinate space of the content presenter var transformer = ContentVisual.TransformToVisual(_presenter); var region = usingContentCoordinates ? new Rect( transformer.TransformPoint(new Point(rectangle.Top, rectangle.Left)), transformer.TransformPoint(new Point(rectangle.Bottom, rectangle.Right))) : rectangle; // calculate actual zoom, which must fit the entire selection // while maintaining a 1:1 ratio var aspectX = ActualWidth / region.Width; var aspectY = ActualHeight / region.Height; var newRelativeScale = aspectX < aspectY ? aspectX : aspectY; // ensure that the scale value alls within the valid range if (newRelativeScale > MaxZoom) newRelativeScale = MaxZoom; else if (newRelativeScale < MinZoom) newRelativeScale = MinZoom; var center = new Point(rectangle.X + rectangle.Width / 2, rectangle.Y + rectangle.Height / 2); var newRelativePosition = new Point((ActualWidth / 2 - center.X) * Zoom, (ActualHeight / 2 - center.Y) * Zoom); TranslateX = newRelativePosition.X; TranslateY = newRelativePosition.Y; Zoom = newRelativeScale; }
public static Point GetEdgeEndpointOnRectangle(Point oVertexALocation, Rect oVertexARectangle, Point oVertexBLocation) { /* if (oVertexALocation == oVertexBLocation) return oVertexALocation; Double dVertexAX = oVertexALocation.X; Double dVertexAY = oVertexALocation.Y; Double dVertexBX = oVertexBLocation.X; Double dVertexBY = oVertexBLocation.Y; Double dHalfVertexARectangleWidth = oVertexARectangle.Width / 2.0; Double dHalfVertexARectangleHeight = oVertexARectangle.Height / 2.0; // Get the angle between vertex A and vertex B. Double dEdgeAngle = MathHelper.GetAngleBetweenPointsRadians( oVertexALocation, oVertexBLocation); // Get the angle that defines the aspect ratio of vertex A's rectangle. Double dAspectAngle = Math.Atan2( dHalfVertexARectangleHeight, dHalfVertexARectangleWidth); if (dEdgeAngle >= -dAspectAngle && dEdgeAngle < dAspectAngle) { // For a square, this is -45 degrees to 45 degrees. Debug.Assert(dVertexBX != dVertexAX); return new Point( dVertexAX + dHalfVertexARectangleWidth, dVertexAY + dHalfVertexARectangleWidth * ((dVertexBY - dVertexAY) / (dVertexBX - dVertexAX)) ); } if (dEdgeAngle >= dAspectAngle && dEdgeAngle < Math.PI - dAspectAngle) { // For a square, this is 45 degrees to 135 degrees. //Debug.Assert(dVertexBY != dVertexAY); return new Point( dVertexAX + dHalfVertexARectangleHeight * ((dVertexBX - dVertexAX) / (dVertexAY - dVertexBY)), dVertexAY - dHalfVertexARectangleHeight ); } if (dEdgeAngle < -dAspectAngle && dEdgeAngle >= -Math.PI + dAspectAngle) { // For a square, this is -45 degrees to -135 degrees. Debug.Assert(dVertexBY != dVertexAY); return new Point( dVertexAX + dHalfVertexARectangleHeight * ((dVertexBX - dVertexAX) / (dVertexBY - dVertexAY)), dVertexAY + dHalfVertexARectangleHeight ); } // For a square, this is 135 degrees to 180 degrees and -135 degrees to // -180 degrees. Debug.Assert(dVertexAX != dVertexBX); return new Point( dVertexAX - dHalfVertexARectangleWidth, dVertexAY + dHalfVertexARectangleWidth * ((dVertexBY - dVertexAY) / (dVertexAX - dVertexBX)) );*/ var leftSide = Intersects(new Vector(oVertexALocation.X, oVertexALocation.Y), new Vector(oVertexBLocation.X, oVertexBLocation.Y), new Vector(oVertexARectangle.X, oVertexARectangle.Y), new Vector(oVertexARectangle.X, oVertexARectangle.Y + oVertexARectangle.Height)); var bottomSide = Intersects(new Vector(oVertexALocation.X, oVertexALocation.Y), new Vector(oVertexBLocation.X, oVertexBLocation.Y), new Vector(oVertexARectangle.X, oVertexARectangle.Y + oVertexARectangle.Height), new Vector(oVertexARectangle.X + oVertexARectangle.Width, oVertexARectangle.Y + oVertexARectangle.Height)); var rightSide = Intersects(new Vector(oVertexALocation.X, oVertexALocation.Y), new Vector(oVertexBLocation.X, oVertexBLocation.Y), new Vector(oVertexARectangle.X + oVertexARectangle.Width, oVertexARectangle.Y), new Vector(oVertexARectangle.X + oVertexARectangle.Width, oVertexARectangle.Y + oVertexARectangle.Height)); var topSide = Intersects(new Vector(oVertexALocation.X, oVertexALocation.Y), new Vector(oVertexBLocation.X, oVertexBLocation.Y), new Vector(oVertexARectangle.X, oVertexARectangle.Y), new Vector(oVertexARectangle.X + oVertexARectangle.Width, oVertexARectangle.Y)); var pt = new Point(oVertexALocation.X, oVertexALocation.Y); // Get the rectangle side where intersection of the proposed Edge path occurred. if (leftSide != null) pt = new Point(leftSide.Value.X, leftSide.Value.Y); else if (bottomSide != null) pt = new Point(bottomSide.Value.X, bottomSide.Value.Y); else if (rightSide != null) pt = new Point(rightSide.Value.X, rightSide.Value.Y); else if (topSide != null) pt = new Point(topSide.Value.X, topSide.Value.Y); return pt; }
public static Point GetEdgeEndpointOnDiamond(Point oVertexLocation, Double mDHalfWidth, Point otherEndpoint) { // A diamond is just a rotated square, so the // GetEdgePointOnRectangle() can be used if the // diamond and the other vertex location are first rotated 45 degrees // about the diamond's center. var dHalfSquareWidth = mDHalfWidth / Math.Sqrt(2.0); var oRotatedDiamond = new Rect( oVertexLocation.X - dHalfSquareWidth, oVertexLocation.Y - dHalfSquareWidth, 2.0 * dHalfSquareWidth, 2.0 * dHalfSquareWidth ); var oMatrix = GetRotatedMatrix(oVertexLocation, 45); var oRotatedOtherVertexLocation = oMatrix.Transform(otherEndpoint); var oRotatedEdgeEndpoint = GetEdgeEndpointOnRectangle(oVertexLocation, oRotatedDiamond, oRotatedOtherVertexLocation); // Now rotate the computed edge endpoint in the other direction. oMatrix = GetRotatedMatrix(oVertexLocation, -45); return oMatrix.Transform(oRotatedEdgeEndpoint); // }
public static Point GetEdgeEndpointOnTriangle(Point oVertexLocation, Double mDHalfWidth, Point otherEndpoint) { // Instead of doing geometry calculations similar to what is done in // VertexDrawingHistory.GetEdgePointOnRectangle(), make use of that // method by making the triangle look like a rectangle. First, figure // out how to rotate the triangle about the vertex location so that the // side containing the endpoint is vertical and to the right of the // vertex location. var dEdgeAngle = MathHelper.GetAngleBetweenPointsRadians( oVertexLocation, otherEndpoint); var dEdgeAngleDegrees = MathHelper.RadiansToDegrees(dEdgeAngle); Double dAngleToRotateDegrees; if (dEdgeAngleDegrees >= -30.0 && dEdgeAngleDegrees < 90.0) { dAngleToRotateDegrees = 30.0; } else if (dEdgeAngleDegrees >= -150.0 && dEdgeAngleDegrees < -30.0) { dAngleToRotateDegrees = 270.0; } else { dAngleToRotateDegrees = 150.0; } // Now create a rotated rectangle that is centered on the vertex // location and that has the vertical, endpoint-containing triangle // side as the rectangle's right edge. var dWidth = 2.0 * mDHalfWidth; var oRotatedRectangle = new Rect( oVertexLocation.X, oVertexLocation.Y - mDHalfWidth, dWidth * MathHelper.Tangent30Degrees, dWidth ); var oMatrix = GetRotatedMatrix(oVertexLocation, dAngleToRotateDegrees); // Rotate the other vertex location. var oRotatedOtherVertexLocation = oMatrix.Transform(otherEndpoint); // GetEdgeEndpointOnRectangle will compute an endpoint on the // rectangle's right edge. var oRotatedEdgeEndpoint = GetEdgeEndpointOnRectangle(oVertexLocation, oRotatedRectangle, oRotatedOtherVertexLocation); // Now rotate the edge endpoint in the other direction. oMatrix = GetRotatedMatrix(oVertexLocation, -dAngleToRotateDegrees); return oMatrix.Transform(oRotatedEdgeEndpoint); }
public void BeginDraw(Windows.Foundation.Rect updateRect) { // Express target area as a native RECT type. var updateRectNative = new Rectangle { Left = (int)updateRect.Left, Top = (int)updateRect.Top, Right = (int)updateRect.Right, Bottom = (int)updateRect.Bottom }; // Query for ISurfaceImageSourceNative interface. using (var sisNative = ComObject.QueryInterface <ISurfaceImageSourceNative>(this)) { // Begin drawing - returns a target surface and an offset to use as the top left origin when drawing. try { RawPoint offset; using (var surface = sisNative.BeginDraw(updateRectNative, out offset)) { // Create render target. using (var bitmap = new Bitmap1(d2dContext, surface)) { // Set context's render target. d2dContext.Target = bitmap; } // Begin drawing using D2D context. d2dContext.BeginDraw(); // Apply a clip and transform to constrain updates to the target update area. // This is required to ensure coordinates within the target surface remain // consistent by taking into account the offset returned by BeginDraw, and // can also improve performance by optimizing the area that is drawn by D2D. // Apps should always account for the offset output parameter returned by // BeginDraw, since it may not match the passed updateRect input parameter's location. d2dContext.PushAxisAlignedClip( new RectangleF( (offset.X), (offset.Y), (offset.X + (float)updateRect.Width), (offset.Y + (float)updateRect.Height) ), AntialiasMode.Aliased ); d2dContext.Transform = Matrix3x2.Translation(offset.X, offset.Y); } } catch (SharpDXException ex) { if (ex.ResultCode == SharpDX.DXGI.ResultCode.DeviceRemoved || ex.ResultCode == SharpDX.DXGI.ResultCode.DeviceReset) { // If the device has been removed or reset, attempt to recreate it and continue drawing. CreateDeviceResources(); BeginDraw(updateRect); } else { throw; } } } }
public static Windows.Foundation.Rect Inflate(this Windows.Foundation.Rect rect, Windows.UI.Xaml.Thickness thick) { return(default(Windows.Foundation.Rect)); }
/// <summary> /// Event handler for the Click event on the header. /// In response this function will trigger a Color Bloom transition animation. /// This is achieved by creating a circular solid colored visual directly underneath the /// Pivot header which was clicked, and animating its scale so that it floods a designated bounding box. /// </summary> private void Header_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) { var header = sender as AppBarButton; var headerPosition = header.TransformToVisual(UICanvas).TransformPoint(new Windows.Foundation.Point(0d, 0d)); var initialBounds = new Windows.Foundation.Rect() // maps to a rectangle the size of the header { Width = header.RenderSize.Width, Height = header.RenderSize.Height, X = headerPosition.X, Y = headerPosition.Y }; var finalBounds = Window.Current.Bounds; // maps to the bounds of the current window transition.Start((Windows.UI.Color)_colorsByPivotItem[header.Name], // the color for the circlular bloom initialBounds, // the initial size and position finalBounds); // the area to fill over the animation duration // Add item to queue of transitions var pivotItem = (PivotItem)rootPivot.Items.Single(i => ((AppBarButton)((PivotItem)i).Header).Name.Equals(header.Name)); pendingTransitions.Enqueue(pivotItem); // Make the content visible immediately, when first clicked. Subsequent clicks will be handled by Pivot Control var content = (FrameworkElement)pivotItem.Content; if (content.Visibility == Visibility.Collapsed) { content.Visibility = Visibility.Visible; } }
public static void MWBsetScanningRect(int codeMask, Windows.Foundation.Rect rect) { Scanner.MWBsetScanningRect(codeMask, (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height); }
/// <summary> /// Set autofocus area to tap location and refocus. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private async void videoCanvas_Tap(object sender, System.Windows.Input.GestureEventArgs e) { System.Windows.Point uiTapPoint = e.GetPosition(VideoCanvas); if (PhotoCaptureDevice.IsFocusRegionSupported(_dataContext.Device.SensorLocation) && _focusSemaphore.WaitOne(0)) { // Get tap coordinates as a foundation point Windows.Foundation.Point tapPoint = new Windows.Foundation.Point(uiTapPoint.X, uiTapPoint.Y); double xRatio = VideoCanvas.ActualHeight / _dataContext.Device.PreviewResolution.Width; double yRatio = VideoCanvas.ActualWidth / _dataContext.Device.PreviewResolution.Height; // adjust to center focus on the tap point Windows.Foundation.Point displayOrigin = new Windows.Foundation.Point( tapPoint.Y - _focusRegionSize.Width / 2, (VideoCanvas.ActualWidth - tapPoint.X) - _focusRegionSize.Height / 2); // adjust for resolution difference between preview image and the canvas Windows.Foundation.Point viewFinderOrigin = new Windows.Foundation.Point(displayOrigin.X / xRatio, displayOrigin.Y / yRatio); Windows.Foundation.Rect focusrect = new Windows.Foundation.Rect(viewFinderOrigin, _focusRegionSize); // clip to preview resolution Windows.Foundation.Rect viewPortRect = new Windows.Foundation.Rect(0, 0, _dataContext.Device.PreviewResolution.Width, _dataContext.Device.PreviewResolution.Height); focusrect.Intersect(viewPortRect); _dataContext.Device.FocusRegion = focusrect; // show a focus indicator FocusIndicator.SetValue(Shape.StrokeProperty, _notFocusedBrush); FocusIndicator.SetValue(Canvas.LeftProperty, uiTapPoint.X - _focusRegionSize.Width / 2); FocusIndicator.SetValue(Canvas.TopProperty, uiTapPoint.Y - _focusRegionSize.Height / 2); FocusIndicator.SetValue(Canvas.VisibilityProperty, Visibility.Visible); CameraFocusStatus status = await _dataContext.Device.FocusAsync(); if (status == CameraFocusStatus.Locked) { FocusIndicator.SetValue(Shape.StrokeProperty, _focusedBrush); _manuallyFocused = true; _dataContext.Device.SetProperty(KnownCameraPhotoProperties.LockedAutoFocusParameters, AutoFocusParameters.Exposure & AutoFocusParameters.Focus & AutoFocusParameters.WhiteBalance); } else { _manuallyFocused = false; _dataContext.Device.SetProperty(KnownCameraPhotoProperties.LockedAutoFocusParameters, AutoFocusParameters.None); } _focusSemaphore.Release(); } }
//Load bitmap from ImageBrush and set it as a bitmapDrawable background on target view private static async Task <IDisposable> SetImageBrushAsBackground(CancellationToken ct, BindableView view, ImageBrush background, Windows.Foundation.Rect drawArea, Path maskingPath, Action onImageSet) { var bitmap = await background.GetBitmap(ct, drawArea, maskingPath); onImageSet(); if (ct.IsCancellationRequested || bitmap == null) { bitmap?.Recycle(); bitmap?.Dispose(); return(Disposable.Empty); } var bitmapDrawable = new BitmapDrawable(bitmap); SetDrawableAlpha(bitmapDrawable, (int)(background.Opacity * __opaqueAlpha)); ExecuteWithNoRelayout(view, v => v.SetBackgroundDrawable(bitmapDrawable)); return(Disposable.Create(() => { bitmapDrawable?.Bitmap?.Recycle(); bitmapDrawable?.Dispose(); })); }
/// <summary> /// Event handler for the Click event on the header. /// In response this function will trigger a Color slide transition animation. /// This is achieved by creating a circular solid colored visual directly underneath the /// Pivot header which was clicked, and animating its scale so that it floods a designated bounding box. /// </summary> private void Header_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) { var header = sender as AppBarButton; var currentPivotItem = rootPivot.SelectedItem as PivotItem; var contentHeight = rootPivot.RenderSize.Height - header.RenderSize.Height; var contentWidth = rootPivot.RenderSize.Width; var headerPosition = header.TransformToVisual(UICanvas).TransformPoint(new Windows.Foundation.Point(0d, 0d)); var finalBounds = new Windows.Foundation.Rect() // maps to a rectangle the size of the pivot content { Width = contentWidth, Height = contentHeight, X = Window.Current.Bounds.Width, Y = headerPosition.Y + header.RenderSize.Height }; transition.Start((Windows.UI.Color)_colorsByPivotItem[header.Name], // the color for the colored slide finalBounds); // the area to fill over the animation duration }
/// <summary> /// Begins a photo stream item rendering process loop. Loop is executed asynchronously item by item /// until there are no more items in the queue. /// </summary> private async void Process() { _processingNow++; while (_enabled && Count > 0) { StreamItemViewModel item; if (_priorityQueue.Count > 0) { Busy = true; item = _priorityQueue[0]; _priorityQueue.RemoveAt(0); } else { item = _standardQueue[0]; _standardQueue.RemoveAt(0); } try { WriteableBitmap bitmap = null; using (MemoryStream thumbnailStream = new MemoryStream()) { System.Diagnostics.Debug.Assert(item.RequestedSize != StreamItemViewModel.Size.None); if (item.RequestedSize == StreamItemViewModel.Size.Large) { bitmap = new WriteableBitmap(280, 280); item.Model.Picture.GetImage().CopyTo(thumbnailStream); } else if (item.RequestedSize == StreamItemViewModel.Size.Medium) { bitmap = new WriteableBitmap(140, 140); item.Model.Picture.GetThumbnail().CopyTo(thumbnailStream); } else { bitmap = new WriteableBitmap(70, 70); item.Model.Picture.GetThumbnail().CopyTo(thumbnailStream); } using (EditingSession session = new EditingSession(thumbnailStream.GetWindowsRuntimeBuffer())) { Windows.Foundation.Rect rect; if (session.Dimensions.Width > session.Dimensions.Height) { rect = new Windows.Foundation.Rect() { Width = session.Dimensions.Height, Height = session.Dimensions.Height, X = session.Dimensions.Width / 2 - session.Dimensions.Height / 2, Y = 0 }; } else { rect = new Windows.Foundation.Rect() { Width = session.Dimensions.Width, Height = session.Dimensions.Width, X = 0, Y = session.Dimensions.Height / 2 - session.Dimensions.Width / 2 }; } session.AddFilter(FilterFactory.CreateCropFilter(rect)); if (item.Model.Filter != null) { foreach (IFilter f in item.Model.Filter.Components) { session.AddFilter(f); } } await session.RenderToBitmapAsync(bitmap.AsBitmap()); } } item.TransitionToImage(bitmap); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("Rendering stream item failed:" + ex.Message); item.TransitionToImage(null); } } _processingNow--; if (_processingNow == 0) { Busy = false; } }
private void OnAreaSelected(Rect selection) { if (AreaSelected != null) AreaSelected(this, new AreaSelectedEventArgs(selection)); }
/// <summary> /// Changes the current camera effect. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private async void OnMyCameraMediaElementTapped(object sender, GestureEventArgs e) { var uiTapPoint = e.GetPosition(_mediaElement); if (_focusSemaphore.WaitOne(0)) { // Get tap coordinates as a foundation point var tapPoint = new Windows.Foundation.Point(uiTapPoint.X, uiTapPoint.Y); // adjust to center focus on the tap point var displayOrigin = new Windows.Foundation.Point( tapPoint.X - _focusRegionSize.Width / 2, tapPoint.Y - _focusRegionSize.Height / 2); // adjust for resolution difference between preview image and the canvas var viewFinderOrigin = new Windows.Foundation.Point(displayOrigin.X , displayOrigin.Y); var focusrect = new Windows.Foundation.Rect(viewFinderOrigin, _focusRegionSize); // clip to preview resolution var viewPortRect = new Windows.Foundation.Rect(0, 0,_camera.PreviewResolution.Width,_camera.PreviewResolution.Height); focusrect.Intersect(viewPortRect); _camera.FocusRegion = focusrect; // show a focus indicator FocusIndicator.Margin = new Thickness(uiTapPoint.X - (_focusRegionSize.Width/2), uiTapPoint.Y - (_focusRegionSize.Height/2), 0, 0); FocusIndicator.SetValue(Shape.StrokeProperty, _notFocusedBrush); FocusIndicator.SetValue(Canvas.VisibilityProperty, Visibility.Visible); CameraFocusStatus status = await _camera.FocusAsync(); if (status == CameraFocusStatus.Locked) { FocusIndicator.SetValue(Shape.StrokeProperty, _focusedBrush); _manuallyFocused = true; _camera.SetProperty(KnownCameraPhotoProperties.LockedAutoFocusParameters, AutoFocusParameters.Exposure & AutoFocusParameters.Focus & AutoFocusParameters.WhiteBalance); } else { _manuallyFocused = false; _camera.SetProperty(KnownCameraPhotoProperties.LockedAutoFocusParameters, AutoFocusParameters.None); } _focusSemaphore.Release(); } }
private async Task FocusAtPoint(Point location) { if (PhotoCaptureDevice.IsFocusRegionSupported(PerfectCamera.DataContext.Instance.SensorLocation) && _focusSemaphore.WaitOne(0)) { try { _focusDisplayTimer.Stop(); FocusAnimation.Stop(); Thickness margin = new Thickness(location.X - 45, location.Y - 45, 0, 0); FocusImage.Margin = margin; FocusImage.Visibility = System.Windows.Visibility.Visible; FocusAnimation.Begin(); // Get tap coordinates as a foundation point Windows.Foundation.Point tapPoint = new Windows.Foundation.Point(location.X, location.Y); double xRatio = VideoCanvas.ActualHeight / PerfectCamera.DataContext.Instance.PreviewResolution.Width; double yRatio = VideoCanvas.ActualWidth / PerfectCamera.DataContext.Instance.PreviewResolution.Height; // adjust to center focus on the tap point Windows.Foundation.Point displayOrigin = new Windows.Foundation.Point( tapPoint.Y - _focusRegionSize.Width / 2, (VideoCanvas.ActualWidth - tapPoint.X) - _focusRegionSize.Height / 2); // adjust for resolution difference between preview image and the canvas Windows.Foundation.Point viewFinderOrigin = new Windows.Foundation.Point(displayOrigin.X / xRatio, displayOrigin.Y / yRatio); Windows.Foundation.Rect focusrect = new Windows.Foundation.Rect(viewFinderOrigin, _focusRegionSize); // clip to preview resolution Windows.Foundation.Rect viewPortRect = new Windows.Foundation.Rect(0, 0, PerfectCamera.DataContext.Instance.PreviewResolution.Width, PerfectCamera.DataContext.Instance.PreviewResolution.Height); focusrect.Intersect(viewPortRect); Camera.FocusRegion = focusrect; CameraFocusStatus status = await Camera.FocusAsync(); if (status == CameraFocusStatus.Locked) { _manuallyFocused = true; Camera.SetProperty(KnownCameraPhotoProperties.LockedAutoFocusParameters, AutoFocusParameters.Exposure & AutoFocusParameters.Focus & AutoFocusParameters.WhiteBalance); } else { _manuallyFocused = false; Camera.SetProperty(KnownCameraPhotoProperties.LockedAutoFocusParameters, AutoFocusParameters.None); } } catch (Exception ex) { Debug.WriteLine("ex: {0}", ex.Message); } _focusSemaphore.Release(); } }
/// <summary> /// Returns the fallback solid color brush. /// </summary> /// <param name="destinationRect">Destination rect.</param> /// <returns></returns> protected override Paint GetPaintInner(Rect destinationRect) => new Paint() { Color = FallbackColorWithOpacity, AntiAlias = true };
public void SetManualPosition(Point position) { LastKnownRectSize = new Rect(new Point(position.X - DesiredSize.Width * .5, position.Y - DesiredSize.Height * .5), DesiredSize); Arrange(LastKnownRectSize); }
internal static Android.Graphics.RectF ToRectF(this Windows.Foundation.Rect rect) { return(new Android.Graphics.RectF((float)rect.X, (float)rect.Y, (float)(rect.X + rect.Width), (float)(rect.Y + rect.Height))); }
private async Task <Tuple <ProcessResult, WriteableBitmap> > ProcessFrameAsync(OpticalReaderLib.Frame frame) { //System.Diagnostics.Debug.WriteLine("Start processing"); var rectSize = new Windows.Foundation.Size( ReaderBorder.ActualWidth / Canvas.ActualWidth * frame.Dimensions.Width / _zoom, ReaderBorder.ActualHeight / Canvas.ActualHeight * frame.Dimensions.Height / _zoom); var rectOrigin = new Windows.Foundation.Point( frame.Dimensions.Width / 2 - rectSize.Width / 2, frame.Dimensions.Height / 2 - rectSize.Height / 2); var area = new Windows.Foundation.Rect(rectOrigin, rectSize); ProcessResult result = null; try { result = await OpticalReaderTask.Instance.Processor.ProcessAsync(frame, area, _rotation); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(String.Format("Processing frame failed: {0}\n{1}", ex.Message, ex.StackTrace)); } //System.Diagnostics.Debug.WriteLine("Stop processing"); InterestAreaPolygon.Points = null; if (result != null) { _lastSuccess = DateTime.Now; var thumbnail = GenerateThumbnail(); var interestPointCollection = new PointCollection(); foreach (var point in result.InterestPoints) { interestPointCollection.Add(new System.Windows.Point(point.X, point.Y)); } InterestAreaPolygon.Points = interestPointCollection; return(new Tuple <ProcessResult, WriteableBitmap>(result, thumbnail)); } else { var sinceLastSuccess = DateTime.Now - _lastSuccess; if (sinceLastSuccess > OpticalReaderTask.Instance.FocusInterval) { try { var status = await _device.FocusAsync(); _lastSuccess = DateTime.Now; // todo use camera focus lock status } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(String.Format("Focusing camera failed: {0}\n{1}", ex.Message, ex.StackTrace)); } } return(null); } }
/// <summary> /// Updates or creates a sublayer to render a border-like shape. /// </summary> /// <param name="view">The view to which we should add the layers</param> /// <param name="background">The background brush of the border</param> /// <param name="borderThickness">The border thickness</param> /// <param name="borderBrush">The border brush</param> /// <param name="cornerRadius">The corner radius</param> /// <param name="padding">The padding to apply on the content</param> public void UpdateLayers( FrameworkElement view, Brush background, Thickness borderThickness, Brush borderBrush, CornerRadius cornerRadius, Thickness padding, bool willUpdateMeasures = false ) { // This is required because android Height and Width are hidden by Control. var baseView = view as View; Size targetSize = new Size(baseView.Width, baseView.Height); var drawArea = new Windows.Foundation.Rect(0, 0, targetSize.Width, targetSize.Height); var newState = new LayoutState(drawArea, background, borderThickness, borderBrush, cornerRadius, padding); var previousLayoutState = _currentState; if (!newState.Equals(previousLayoutState)) { bool imageHasChanged = newState.BackgroundImageSource != previousLayoutState?.BackgroundImageSource; bool shouldDisposeEagerly = imageHasChanged || newState.BackgroundImageSource == null; if (shouldDisposeEagerly) { // Clear previous value anyway in order to make sure the previous values are unset before the new ones. // This prevents the case where a second update would set a new background and then set the background to null when disposing the previous. _layerDisposable.Disposable = null; } if ( background != null || (borderThickness != Thickness.Empty && borderBrush != null) ) { Action onImageSet = null; var disposable = InnerCreateLayers(view, drawArea, background, borderThickness, borderBrush, cornerRadius, () => onImageSet?.Invoke()); // Most of the time we immediately dispose the previous layer. In the case where we're using an ImageBrush, // and the backing image hasn't changed, we dispose the previous layer at the moment the new background is applied, // to prevent a visible flicker. if (shouldDisposeEagerly) { _layerDisposable.Disposable = disposable; } else { onImageSet = () => _layerDisposable.Disposable = disposable; } } if (willUpdateMeasures) { view.RequestLayout(); } else { view.Invalidate(); } _currentState = newState; } }
public async Task MeasureSource_Expected_Result( Stretch stretch, string alignment, double imageNaturalWidth, double imageNaturalHeight, double finalWidth, double finalHeight, double expectedX, double expectedY, double expectedWidth, double expectedHeight) { var imageNaturalSize = new Size(imageNaturalWidth, imageNaturalHeight); var finalSize = new Size(finalWidth, finalHeight); var expectedRect = new Rect(expectedX, expectedY, expectedWidth, expectedHeight); HorizontalAlignment horizontal = default; VerticalAlignment vertical = default; switch (alignment[0]) { case 'l': horizontal = HorizontalAlignment.Left; break; case 'c': horizontal = HorizontalAlignment.Center; break; case 'r': horizontal = HorizontalAlignment.Right; break; case 's': horizontal = HorizontalAlignment.Stretch; break; } switch (alignment[1]) { case 't': vertical = VerticalAlignment.Top; break; case 'c': vertical = VerticalAlignment.Center; break; case 'b': vertical = VerticalAlignment.Bottom; break; case 's': vertical = VerticalAlignment.Stretch; break; } var image = new Image { Stretch = stretch, HorizontalAlignment = horizontal, VerticalAlignment = vertical }; var containerRect = image.MeasureSource(finalSize, imageNaturalSize); var measuredRect = image.ArrangeSource(finalSize, containerRect); measuredRect.Should().Be( expectedRect, 0.5, $"Invalid output for image size {imageNaturalSize} when finalSize is {finalSize} using stretch {stretch} alignment {horizontal}/{vertical}"); }
private static RectangleF ConvertToRectF(Windows.Foundation.Rect rect) { return(new RectangleF((float)rect.X, (float)rect.Y, (float)rect.Width, (float)rect.Height)); }
public static void ArrangeSource(this Image image, Windows.Foundation.Rect parent, ref Windows.Foundation.Rect child) { switch (image.HorizontalAlignment) { case HorizontalAlignment.Left: child.X = 0; break; case HorizontalAlignment.Right: child.X = parent.Width - child.Width; break; case HorizontalAlignment.Center: case HorizontalAlignment.Stretch: child.X = (parent.Width * 0.5f) - (child.Width * 0.5f); break; } switch (image.VerticalAlignment) { case VerticalAlignment.Top: child.Y = 0; break; case VerticalAlignment.Bottom: child.Y = parent.Height - child.Height; break; case VerticalAlignment.Center: case VerticalAlignment.Stretch: child.Y = (parent.Height * 0.5f) - (child.Height * 0.5f); break; } // Clamp the results. A non image larger that its size, even if aligned bottom // must be aligned at the top. child.X = Math.Max(child.X, 0); child.Y = Math.Max(child.Y, 0); }
public static bool IsCloseTo(this Windows.Foundation.Rect rect1, Windows.Foundation.Rect rect2) { return(default(bool)); }
private void ZoomToInternal(Rect rect, bool setDelta = false) { var deltaZoom = Math.Min(ActualWidth / rect.Width, ActualHeight / rect.Height); var startHandlePosition = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2); DoZoom(deltaZoom, 1, OrigoPosition, startHandlePosition, OrigoPosition, setDelta); ZoomBox = new Rect(); }
/// <summary> /// Update edge pointer position and angle /// </summary> public virtual Point Update(Point? position, Vector direction, double angle = 0d) { //var vecOffset = new Vector(direction.X * Offset.X, direction.Y * Offset.Y); if (DesiredSize.Width == 0 || DesiredSize.Height == 0 || !position.HasValue) return new Point(); var vecMove = new Vector(direction.X * DesiredSize.Width * .5, direction.Y * DesiredSize.Height * .5); position = new Point(position.Value.X - vecMove.X, position.Value.Y - vecMove.Y);// + vecOffset; if (!double.IsNaN(DesiredSize.Width) && DesiredSize.Width != 0 && !double.IsNaN(position.Value.X)) { LastKnownRectSize = new Rect(new Point(position.Value.X - DesiredSize.Width * .5, position.Value.Y - DesiredSize.Height * .5), DesiredSize); Arrange(LastKnownRectSize); } if(NeedRotation) RenderTransform = new RotateTransform { Angle = angle, CenterX = 0, CenterY = 0 }; return new Point(direction.X * ActualWidth, direction.Y * ActualHeight); }
public static int GetIntersectionPoint(Rect r, Point a, Point b, out Point pt) { var start = new Point(a.X, a.Y); var codeA = GetIntersectionData(r, a); var codeB = GetIntersectionData(r, b); while (!codeA.IsInside() || !codeB.IsInside()) { if (codeA.SameSide(codeB)) { pt = new Point(); return -1; } sides code; Point c; if (!codeA.IsInside()) { code = codeA; c = a; } else { code = codeB; c = b; } if (code.Left) { c.Y += (a.Y - b.Y) * (r.Left - c.X) / (a.X - b.X); c.X = r.Left; } else if (code.Right) { c.Y += (a.Y - b.Y) * (r.Right - c.X) / (a.X - b.X); c.X = r.Right; } else if (code.Bottom) { c.X += (a.X - b.X) * (r.Bottom - c.Y) / (a.Y - b.Y); c.Y = r.Bottom; } else if (code.Top) { c.X += (a.X - b.X) * (r.Top - c.Y) / (a.Y - b.Y); c.Y = r.Top; } if (code == codeA) { a = c; codeA = GetIntersectionData(r, a); } else { b = c; codeB = GetIntersectionData(r, b); } } pt = GetCloserPoint(start, a, b); return 0; }
/// <summary> /// Shows the context menu in the preferred placement relative to the specified selection. /// </summary> /// <param name="selection">The coordinates (in DIPs) of the selected rectangle, relative to the window.</param> /// <param name="preferredPlacement">The preferred placement of the context menu relative to the selection rectangle.</param> /// <returns></returns> public Task <IUICommand> ShowForSelectionAsync(Rect selection, Placement preferredPlacement) { if (Commands.Count > MaxCommands) { throw new InvalidOperationException(); } #if WINDOWS_UWP return(Task.Run <IUICommand>(async() => { foreach (IUICommand command in Commands) { _menu.Commands.Add(new Windows.UI.Popups.UICommand(command.Label, new Windows.UI.Popups.UICommandInvokedHandler((c2) => { command.Invoked?.Invoke(command); }), command.Id)); } Windows.Foundation.Rect r = new Windows.Foundation.Rect(selection.X, selection.Y, selection.Width, selection.Height); var c = await _menu.ShowForSelectionAsync(r, (Windows.UI.Popups.Placement)((int)preferredPlacement)); return c == null ? null : new UICommand(c.Label, new UICommandInvokedHandler((c2) => { c2.Invoked?.Invoke(c2); }), c.Id); })); #elif __ANDROID__ Android.App.AlertDialog.Builder builder = new Android.App.AlertDialog.Builder(Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity); Android.App.AlertDialog dialog = builder.Create(); dialog.SetTitle(Title); dialog.SetMessage(Content); if (Commands.Count == 0) { dialog.SetButton(-1, Resources.System.GetString(Android.Resource.String.Cancel), new EventHandler <Android.Content.DialogClickEventArgs>(Clicked)); } else { for (int i = 0; i < Commands.Count; i++) { dialog.SetButton(-1 - i, Commands[i].Label, new EventHandler <Android.Content.DialogClickEventArgs>(Clicked)); } } dialog.Show(); return(Task.Run <IUICommand>(() => { handle.WaitOne(); return _selectedCommand; })); #elif __IOS__ uac = UIAlertController.Create("", "", UIAlertControllerStyle.ActionSheet); if (Commands.Count == 0) { uac.AddAction(UIAlertAction.Create("Cancel", UIAlertActionStyle.Cancel | UIAlertActionStyle.Default, ActionClicked)); } else { for (int i = 0; i < Commands.Count; i++) { UIAlertAction action = UIAlertAction.Create(Commands[i].Label, UIAlertActionStyle.Default, ActionClicked); uac.AddAction(action); } } UIViewController currentController = UIApplication.SharedApplication.KeyWindow.RootViewController; while (currentController.PresentedViewController != null) { currentController = currentController.PresentedViewController; } // set layout requirements for iPad var popoverController = uac.PopoverPresentationController; if (popoverController != null) { popoverController.SourceView = currentController.View; popoverController.SourceRect = new CoreGraphics.CGRect(selection.X, selection.Y, selection.Width, selection.Height); popoverController.PermittedArrowDirections = PlacementHelper.ToArrowDirection(preferredPlacement); } currentController.PresentViewController(uac, true, null); return(Task.Run <IUICommand>(() => { handle.WaitOne(); return _selectedCommand; })); #else throw new PlatformNotSupportedException(); #endif }
public static sides GetIntersectionData(Rect r, Point p) { return new sides() { Left = p.X < r.Left, Right = p.X > r.Right, Bottom = p.Y > r.Bottom, Top = p.Y < r.Top }; }
public OCRYokoText(OcrWord word) { Text = word.Text; Rect = word.BoundingRect; }
public static bool IsIntersected(Rect r, Point a, Point b) { // var start = new Point(a.X, a.Y); /* line endpoints */ var codeA = GetIntersectionData(r, a); var codeB = GetIntersectionData(r, b); if (codeA.IsInside() && codeB.IsInside()) return true; /* while one of the endpoints are outside of rectangle */ while (!codeA.IsInside() || !codeB.IsInside()) { /* if both points are at one rectangle side then line do not cross the rectangle */ if (codeA.SameSide(codeB)) return false; /* select point with zero code */ sides code; Point c; /* one of the points */ if (!codeA.IsInside()) { code = codeA; c = a; } else { code = codeB; c = b; } /* if c is on the left of r then move c on the line x = r->x_min if c is on the right side of r then move c on the line x = r->x_max */ if (code.Left) { c.Y += (a.Y - b.Y) * (r.Left - c.X) / (a.X - b.X); c.X = r.Left; } else if (code.Right) { c.Y += (a.Y - b.Y) * (r.Right - c.X) / (a.X - b.X); c.X = r.Right; }/* if c is below r then move c on the line y = r->y_min if c above the r then move c on the line y = r->y_max */ else if (code.Bottom) { c.X += (a.X - b.X) * (r.Bottom - c.Y) / (a.Y - b.Y); c.Y = r.Bottom; } else if (code.Top) { c.X += (a.X - b.X) * (r.Top - c.Y) / (a.Y - b.Y); c.Y = r.Top; } /* refresh code */ if (code == codeA) { a = c; codeA = GetIntersectionData(r, a); } else { b = c; codeB = GetIntersectionData(r, b); } } return true; }
public static void MeasureSource(this Image image, Windows.Foundation.Rect parent, ref Windows.Foundation.Rect child) { switch (image.Stretch) { case UniformToFill: var uniformToFillScale = (child.Width * parent.Height >= child.Height * parent.Width) ? parent.Height / child.Height // child is flatter than parent : parent.Width / child.Width; // child is taller than parent child.Width *= uniformToFillScale; child.Height *= uniformToFillScale; break; case Uniform: var uniformScale = (child.Width * parent.Height > child.Height * parent.Width) ? parent.Width / child.Width // child is taller than parent : parent.Height / child.Height; // child is flatter than parent child.Width *= uniformScale; child.Height *= uniformScale; break; case Fill: child.Width = parent.Width; child.Height = parent.Height; break; case None: break; } }
protected override void DeleteFilter() { cropRect = new Windows.Foundation.Rect(0, 0, 0, 0); base.DeleteFilter(); }
private static IDisposable InnerCreateLayers(BindableView view, Windows.Foundation.Rect drawArea, Brush background, Thickness borderThickness, Brush borderBrush, CornerRadius cornerRadius, Action onImageSet ) { var disposables = new CompositeDisposable(); var physicalBorderThickness = borderThickness.LogicalToPhysicalPixels(); if (cornerRadius != 0) { if (view is UIElement uiElement && uiElement.FrameRoundingAdjustment is { } fra) { drawArea.Height += fra.Height; drawArea.Width += fra.Width; } var adjustedArea = drawArea.DeflateBy(physicalBorderThickness); using (var backgroundPath = cornerRadius.GetOutlinePath(adjustedArea.ToRectF())) { //We only need to set a background if the drawArea is non-zero if (!drawArea.HasZeroArea()) { if (background is ImageBrush imageBrushBackground) { //Copy the path because it will be disposed when we exit the using block var pathCopy = new Path(backgroundPath); var setBackground = DispatchSetImageBrushAsBackground(view, imageBrushBackground, drawArea, onImageSet, pathCopy); disposables.Add(setBackground); } else if (background is AcrylicBrush acrylicBrush) { var apply = acrylicBrush.Subscribe(view, drawArea, backgroundPath); disposables.Add(apply); } else { var fillPaint = background?.GetFillPaint(drawArea) ?? new Paint() { Color = Android.Graphics.Color.Transparent }; ExecuteWithNoRelayout(view, v => v.SetBackgroundDrawable(Brush.GetBackgroundDrawable(background, drawArea, fillPaint, backgroundPath))); } disposables.Add(() => ExecuteWithNoRelayout(view, v => v.SetBackgroundDrawable(null))); } if (borderThickness != Thickness.Empty && borderBrush != null && !(borderBrush is ImageBrush)) { using (var strokePaint = new Paint(borderBrush.GetStrokePaint(drawArea))) { //Create the path for the outer and inner rectangles that will become our border shape var borderPath = cornerRadius.GetOutlinePath(drawArea.ToRectF()); borderPath.AddRoundRect(adjustedArea.ToRectF(), cornerRadius.GetRadii(), Path.Direction.Ccw); var overlay = GetOverlayDrawable( strokePaint, physicalBorderThickness, new global::System.Drawing.Size((int)drawArea.Width, (int)drawArea.Height), borderPath); if (overlay != null) { overlay.SetBounds(0, 0, view.Width, view.Height); SetOverlay(view, disposables, overlay); } } } } } else // No corner radius { //We only need to set a background if the drawArea is non-zero if (!drawArea.HasZeroArea()) { if (background is ImageBrush imageBrushBackground) { var setBackground = DispatchSetImageBrushAsBackground(view, imageBrushBackground, drawArea, onImageSet); disposables.Add(setBackground); } else if (background is AcrylicBrush acrylicBrush) { var apply = acrylicBrush.Subscribe(view, drawArea, maskingPath: null); disposables.Add(apply); } else { var fillPaint = background?.GetFillPaint(drawArea) ?? new Paint() { Color = Android.Graphics.Color.Transparent }; ExecuteWithNoRelayout(view, v => v.SetBackgroundDrawable(Brush.GetBackgroundDrawable(background, drawArea, fillPaint))); } disposables.Add(() => ExecuteWithNoRelayout(view, v => v.SetBackgroundDrawable(null))); } } if (borderBrush != null && !(borderBrush is ImageBrush)) { //TODO: Handle case that BorderBrush is an ImageBrush using (var strokePaint = borderBrush.GetStrokePaint(drawArea)) { var overlay = GetOverlayDrawable(strokePaint, physicalBorderThickness, new global::System.Drawing.Size(view.Width, view.Height)); if (overlay != null) { overlay.SetBounds(0, 0, view.Width, view.Height); SetOverlay(view, disposables, overlay); } } } return(disposables); }
private async Task<Tuple<ProcessResult, WriteableBitmap>> ProcessFrameAsync(OpticalReaderLib.Frame frame) { //System.Diagnostics.Debug.WriteLine("Start processing"); var rectSize = new Windows.Foundation.Size( ReaderBorder.ActualWidth / Canvas.ActualWidth * frame.Dimensions.Width / _zoom, ReaderBorder.ActualHeight / Canvas.ActualHeight * frame.Dimensions.Height / _zoom); var rectOrigin = new Windows.Foundation.Point( frame.Dimensions.Width / 2 - rectSize.Width / 2, frame.Dimensions.Height / 2 - rectSize.Height / 2); var area = new Windows.Foundation.Rect(rectOrigin, rectSize); ProcessResult result = null; try { result = await OpticalReaderTask.Instance.Processor.ProcessAsync(frame, area, _rotation); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(String.Format("Processing frame failed: {0}\n{1}", ex.Message, ex.StackTrace)); } //System.Diagnostics.Debug.WriteLine("Stop processing"); InterestAreaPolygon.Points = null; if (result != null) { _lastSuccess = DateTime.Now; var thumbnail = GenerateThumbnail(); var interestPointCollection = new PointCollection(); foreach (var point in result.InterestPoints) { interestPointCollection.Add(new System.Windows.Point(point.X, point.Y)); } InterestAreaPolygon.Points = interestPointCollection; return new Tuple<ProcessResult, WriteableBitmap>(result, thumbnail); } else { var sinceLastSuccess = DateTime.Now - _lastSuccess; if (sinceLastSuccess > OpticalReaderTask.Instance.FocusInterval) { try { var status = await _device.FocusAsync(); _lastSuccess = DateTime.Now; // todo use camera focus lock status } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(String.Format("Focusing camera failed: {0}\n{1}", ex.Message, ex.StackTrace)); } } return null; } }
private static IDisposable DispatchSetImageBrushAsBackground(BindableView view, ImageBrush background, Windows.Foundation.Rect drawArea, Action onImageSet, Path maskingPath = null) { var disposable = new CompositeDisposable(); Dispatch( view?.Dispatcher, async ct => { var bitmapDisposable = await SetImageBrushAsBackground(ct, view, background, drawArea, maskingPath, onImageSet); disposable.Add(bitmapDisposable); } ) .DisposeWith(disposable); return(disposable); }
/// <summary> /// Shows the context menu by the specified selection. /// </summary> /// <param name="selection">The coordinates (in DIPs) of the selected rectangle, relative to the window.</param> /// <returns></returns> public Task<IUICommand> ShowForSelectionAsync(Rect selection) { #if WINDOWS_UWP return Task.Run<IUICommand>(async () => { foreach (IUICommand command in Commands) { _menu.Commands.Add(new Windows.UI.Popups.UICommand(command.Label, new Windows.UI.Popups.UICommandInvokedHandler((c2) => { command.Invoked?.Invoke(command); }), command.Id)); } Windows.Foundation.Rect r = new Windows.Foundation.Rect(selection.X, selection.Y, selection.Width, selection.Height); var c = await _menu.ShowForSelectionAsync(r); return c == null ? null : new UICommand(c.Label, new UICommandInvokedHandler((c2) => { c2.Invoked?.Invoke(c2); }), c.Id); }); #else return ShowForSelectionAsync(selection, Placement.Default); #endif }
public static int GetIntersectionPoint(Rect r, Point a, Point b, out Point pt) { var start = new Point(a.X, a.Y); var codeA = GetIntersectionData(r, a); var codeB = GetIntersectionData(r, b); while (!codeA.IsInside() || !codeB.IsInside()) { if (codeA.SameSide(codeB)) { pt = new Point(); return(-1); } sides code; Point c; if (!codeA.IsInside()) { code = codeA; c = a; } else { code = codeB; c = b; } if (code.Left) { c.Y += (a.Y - b.Y) * (r.Left - c.X) / (a.X - b.X); c.X = r.Left; } else if (code.Right) { c.Y += (a.Y - b.Y) * (r.Right - c.X) / (a.X - b.X); c.X = r.Right; } else if (code.Bottom) { c.X += (a.X - b.X) * (r.Bottom - c.Y) / (a.Y - b.Y); c.Y = r.Bottom; } else if (code.Top) { c.X += (a.X - b.X) * (r.Top - c.Y) / (a.Y - b.Y); c.Y = r.Top; } if (code == codeA) { a = c; codeA = GetIntersectionData(r, a); } else { b = c; codeB = GetIntersectionData(r, b); } } pt = GetCloserPoint(start, a, b); return(0); }
/// <summary> /// Shows the context menu in the preferred placement relative to the specified selection. /// </summary> /// <param name="selection">The coordinates (in DIPs) of the selected rectangle, relative to the window.</param> /// <param name="preferredPlacement">The preferred placement of the context menu relative to the selection rectangle.</param> /// <returns></returns> public Task<IUICommand> ShowForSelectionAsync(Rect selection, Placement preferredPlacement) { if (Commands.Count > MaxCommands) { throw new InvalidOperationException(); } #if WINDOWS_UWP return Task.Run<IUICommand>(async () => { foreach (IUICommand command in Commands) { _menu.Commands.Add(new Windows.UI.Popups.UICommand(command.Label, new Windows.UI.Popups.UICommandInvokedHandler((c2) => { command.Invoked?.Invoke(command); }), command.Id)); } Windows.Foundation.Rect r = new Windows.Foundation.Rect(selection.X, selection.Y, selection.Width, selection.Height); var c = await _menu.ShowForSelectionAsync(r, (Windows.UI.Popups.Placement)((int)preferredPlacement)); return c == null ? null : new UICommand(c.Label, new UICommandInvokedHandler((c2) => { c2.Invoked?.Invoke(c2); }), c.Id); }); #elif __ANDROID__ Android.App.AlertDialog.Builder builder = new Android.App.AlertDialog.Builder(Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity); Android.App.AlertDialog dialog = builder.Create(); dialog.SetTitle(Title); dialog.SetMessage(Content); if (Commands.Count == 0) { dialog.SetButton(-1, Resources.System.GetString(Android.Resource.String.Cancel), new EventHandler<Android.Content.DialogClickEventArgs>(Clicked)); } else { for (int i = 0; i < Commands.Count; i++) { dialog.SetButton(-1 - i, Commands[i].Label, new EventHandler<Android.Content.DialogClickEventArgs>(Clicked)); } } dialog.Show(); return Task.Run<IUICommand>(() => { handle.WaitOne(); return _selectedCommand; }); #elif __IOS__ uac = UIAlertController.Create("", "", UIAlertControllerStyle.ActionSheet); if (Commands.Count == 0) { uac.AddAction(UIAlertAction.Create("Cancel", UIAlertActionStyle.Cancel | UIAlertActionStyle.Default, ActionClicked)); } else { for (int i = 0; i < Commands.Count; i++) { UIAlertAction action = UIAlertAction.Create(Commands[i].Label, UIAlertActionStyle.Default, ActionClicked); uac.AddAction(action); } } UIViewController currentController = UIApplication.SharedApplication.KeyWindow.RootViewController; while (currentController.PresentedViewController != null) currentController = currentController.PresentedViewController; // set layout requirements for iPad var popoverController = uac.PopoverPresentationController; if(popoverController != null) { popoverController.SourceView = currentController.View; popoverController.SourceRect = new CoreGraphics.CGRect(selection.X, selection.Y, selection.Width, selection.Height); popoverController.PermittedArrowDirections = PlacementHelper.ToArrowDirection(preferredPlacement); } currentController.PresentViewController(uac, true, null); return Task.Run<IUICommand>(() => { handle.WaitOne(); return _selectedCommand; }); #else throw new PlatformNotSupportedException(); #endif }
protected virtual void CreateSizeDependentResources(object sender, RenderEventArgs e) { var d3dDevice = DirectX.Direct3D.Device; var d3dContext = DirectX.Direct3D.Context; var d2dContext = DirectX.Direct2D.Context; bool isStereoEnabled = deviceManager.Settings.IsStereo; Cleanup(); // If the swap chain already exists, resize it. if (swapChain != null) { swapChain.ResizeBuffers(2, Width, Height, SharpDX.DXGI.Format.B8G8R8A8_UNorm, SharpDX.DXGI.SwapChainFlags.None); } // Otherwise, create a new one. else { // SwapChain description var desc = CreateSwapChainDescription(); // Once the desired swap chain description is configured, it must be created on the same adapter as our D3D Device // First, retrieve the underlying DXGI Device from the D3D Device. // Creates the swap chain using (var dxgiDevice2 = d3dDevice.QueryInterface <SharpDX.DXGI.Device2>()) using (var dxgiAdapter = dxgiDevice2.Adapter) using (var dxgiFactory2 = dxgiAdapter.GetParent <SharpDX.DXGI.Factory2>()) { swapChain = ToDispose(CreateSwapChain(dxgiFactory2, d3dDevice, desc)); // Ensure that DXGI does not queue more than one frame at a time. This both reduces // latency and ensures that the application will only render after each VSync, minimizing // power consumption. dxgiDevice2.MaximumFrameLatency = 1; } } // Obtain the backbuffer for this window which will be the final 3D rendertarget. backBuffer = ToDispose(SharpDX.Direct3D11.Texture2D.FromSwapChain <SharpDX.Direct3D11.Texture2D>(swapChain, 0)); { RenderTargetViewDescription rtvDescription = new RenderTargetViewDescription() { Dimension = RenderTargetViewDimension.Texture2DArray, Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, Texture2DArray = new RenderTargetViewDescription.Texture2DArrayResource() { MipSlice = 0, FirstArraySlice = 0, ArraySize = 1 } }; // Create a view interface on the rendertarget to use on bind. renderTargetView = ToDispose(new SharpDX.Direct3D11.RenderTargetView(d3dDevice, BackBuffer, rtvDescription)); if (IsStereoEnabled) { RenderTargetViewDescription rtvDescriptionRight = new RenderTargetViewDescription() { Dimension = RenderTargetViewDimension.Texture2DArray, Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, Texture2DArray = new RenderTargetViewDescription.Texture2DArrayResource() { MipSlice = 0, FirstArraySlice = 1, ArraySize = 1 } }; renderTargetViewRight = ToDispose(new SharpDX.Direct3D11.RenderTargetView(d3dDevice, BackBuffer, rtvDescriptionRight)); } // Cache the rendertarget dimensions in our helper class for convenient use. var backBufferDesc = BackBuffer.Description; RenderTargetBounds = new Windows.Foundation.Rect(0, 0, backBufferDesc.Width, backBufferDesc.Height); } // Create a descriptor for the depth/stencil buffer. // Allocate a 2-D surface as the depth/stencil buffer. // Create a DepthStencil view on this surface to use on bind. using (var depthBuffer = new SharpDX.Direct3D11.Texture2D(d3dDevice, new SharpDX.Direct3D11.Texture2DDescription() { Format = SharpDX.DXGI.Format.D24_UNorm_S8_UInt, ArraySize = 1, MipLevels = 1, Width = (int)RenderTargetSize.Width, Height = (int)RenderTargetSize.Height, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), BindFlags = SharpDX.Direct3D11.BindFlags.DepthStencil, })) depthStencilView = ToDispose(new SharpDX.Direct3D11.DepthStencilView(d3dDevice, depthBuffer, new SharpDX.Direct3D11.DepthStencilViewDescription() { Dimension = SharpDX.Direct3D11.DepthStencilViewDimension.Texture2D })); // Create a viewport descriptor of the full window size. var viewport = new SharpDX.ViewportF((float)RenderTargetBounds.X, (float)RenderTargetBounds.Y, (float)RenderTargetBounds.Width, (float)RenderTargetBounds.Height, 0.0f, 1.0f); // Set the current viewport using the descriptor. d3dContext.Rasterizer.SetViewport(viewport); // Now we set up the Direct2D render target bitmap linked to the swapchain. // Whenever we render to this bitmap, it will be directly rendered to the // swapchain associated with the window. var bitmapProperties = new SharpDX.Direct2D1.BitmapProperties1( new SharpDX.Direct2D1.PixelFormat(SharpDX.DXGI.Format.B8G8R8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied), deviceManager.Dpi, deviceManager.Dpi, SharpDX.Direct2D1.BitmapOptions.Target | SharpDX.Direct2D1.BitmapOptions.CannotDraw); // Direct2D needs the dxgi version of the backbuffer surface pointer. // Get a D2D surface from the DXGI back buffer to use as the D2D render target. if (IsStereoEnabled) { using (var dxgiBackBuffer = swapChain.GetBackBuffer <SharpDX.DXGI.Resource1>(0)) { using (var dxgiSurface = new Surface2(dxgiBackBuffer, 0)) bitmapTarget = ToDispose(new SharpDX.Direct2D1.Bitmap1(d2dContext, dxgiSurface, bitmapProperties)); using (var dxgiSurface = new Surface2(dxgiBackBuffer, 1)) bitmapTargetRight = ToDispose(new SharpDX.Direct2D1.Bitmap1(d2dContext, dxgiSurface, bitmapProperties)); } } else { using (var dxgiBackBuffer = swapChain.GetBackBuffer <SharpDX.DXGI.Surface2>(0)) bitmapTarget = ToDispose(new SharpDX.Direct2D1.Bitmap1(d2dContext, dxgiBackBuffer, bitmapProperties)); } // So now we can set the Direct2D render target. d2dContext.Target = BitmapTarget; // Set D2D text anti-alias mode to Grayscale to ensure proper rendering of text on intermediate surfaces. d2dContext.TextAntialiasMode = SharpDX.Direct2D1.TextAntialiasMode.Grayscale; }
/// <summary> /// Renders a thumbnail of requested size from the center of the current image with /// filters applied. /// </summary> /// <param name="side">Side length of square thumbnail to render</param> /// <returns>Rendered thumbnail bitmap</returns> public async Task<Bitmap> RenderThumbnailBitmapAsync(int side) { int minSide = (int)Math.Min(Width, Height); Windows.Foundation.Rect rect = new Windows.Foundation.Rect() { Width = minSide, Height = minSide, X = (Width - minSide) / 2, Y = (Height - minSide) / 2, }; _session.AddFilter(FilterFactory.CreateCropFilter(rect)); Bitmap bitmap = new Bitmap(new Windows.Foundation.Size(side, side), ColorMode.Ayuv4444); try { await _session.RenderToBitmapAsync(bitmap, OutputOption.Stretch); } catch (Exception ex) { bitmap = null; } _session.Undo(); return bitmap; }
protected virtual void CreateSizeDependentResources(TargetBase renderBase) { var d3dDevice = DeviceManager.DeviceDirect3D; var d3dContext = DeviceManager.ContextDirect3D; var d2dContext = DeviceManager.ContextDirect2D; d2dContext.Target = null; SafeDispose(ref renderTargetView); SafeDispose(ref depthStencilView); SafeDispose(ref bitmapTarget); // If the swap chain already exists, resize it. if (swapChain != null) { swapChain.ResizeBuffers(2, Width, Height, SharpDX.DXGI.Format.B8G8R8A8_UNorm, SharpDX.DXGI.SwapChainFlags.None); } // Otherwise, create a new one. else { // SwapChain description var desc = CreateSwapChainDescription(); // Once the desired swap chain description is configured, it must be created on the same adapter as our D3D Device // First, retrieve the underlying DXGI Device from the D3D Device. // Creates the swap chain using (var dxgiDevice2 = d3dDevice.QueryInterface<SharpDX.DXGI.Device2>()) using (var dxgiAdapter = dxgiDevice2.Adapter) using (var dxgiFactory2 = dxgiAdapter.GetParent<SharpDX.DXGI.Factory2>()) { swapChain = ToDispose(CreateSwapChain(dxgiFactory2, d3dDevice, desc)); // Ensure that DXGI does not queue more than one frame at a time. This both reduces // latency and ensures that the application will only render after each VSync, minimizing // power consumption. dxgiDevice2.MaximumFrameLatency = 1; } } // Obtain the backbuffer for this window which will be the final 3D rendertarget. using (var backBuffer = SharpDX.Direct3D11.Texture2D.FromSwapChain<SharpDX.Direct3D11.Texture2D>(swapChain, 0)) { // Create a view interface on the rendertarget to use on bind. renderTargetView = ToDispose(new SharpDX.Direct3D11.RenderTargetView(d3dDevice, backBuffer)); // Cache the rendertarget dimensions in our helper class for convenient use. var backBufferDesc = backBuffer.Description; RenderTargetBounds = new Windows.Foundation.Rect(0, 0, backBufferDesc.Width, backBufferDesc.Height); } // Create a descriptor for the depth/stencil buffer. // Allocate a 2-D surface as the depth/stencil buffer. // Create a DepthStencil view on this surface to use on bind. using (var depthBuffer = new SharpDX.Direct3D11.Texture2D(d3dDevice, new SharpDX.Direct3D11.Texture2DDescription() { Format = SharpDX.DXGI.Format.D24_UNorm_S8_UInt, ArraySize = 1, MipLevels = 1, Width = (int)RenderTargetSize.Width, Height = (int)RenderTargetSize.Height, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), BindFlags = SharpDX.Direct3D11.BindFlags.DepthStencil, })) depthStencilView = ToDispose(new SharpDX.Direct3D11.DepthStencilView(d3dDevice, depthBuffer, new SharpDX.Direct3D11.DepthStencilViewDescription() { Dimension = SharpDX.Direct3D11.DepthStencilViewDimension.Texture2D })); // Create a viewport descriptor of the full window size. var viewport = new SharpDX.Direct3D11.Viewport((float)RenderTargetBounds.X, (float)RenderTargetBounds.Y, (float)RenderTargetBounds.Width, (float)RenderTargetBounds.Height, 0.0f, 1.0f); // Set the current viewport using the descriptor. d3dContext.Rasterizer.SetViewports(viewport); // Now we set up the Direct2D render target bitmap linked to the swapchain. // Whenever we render to this bitmap, it will be directly rendered to the // swapchain associated with the window. var bitmapProperties = new SharpDX.Direct2D1.BitmapProperties1( new SharpDX.Direct2D1.PixelFormat(SharpDX.DXGI.Format.B8G8R8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied), DeviceManager.Dpi, DeviceManager.Dpi, SharpDX.Direct2D1.BitmapOptions.Target | SharpDX.Direct2D1.BitmapOptions.CannotDraw); // Direct2D needs the dxgi version of the backbuffer surface pointer. // Get a D2D surface from the DXGI back buffer to use as the D2D render target. using (var dxgiBackBuffer = swapChain.GetBackBuffer<SharpDX.DXGI.Surface>(0)) bitmapTarget = ToDispose(new SharpDX.Direct2D1.Bitmap1(d2dContext, dxgiBackBuffer, bitmapProperties)); // So now we can set the Direct2D render target. d2dContext.Target = BitmapTarget2D; // Set D2D text anti-alias mode to Grayscale to ensure proper rendering of text on intermediate surfaces. d2dContext.TextAntialiasMode = SharpDX.Direct2D1.TextAntialiasMode.Grayscale; }
/// <summary> /// Converts screen rectangle area to rectangle in content coordinate space according to scale and translation /// </summary> /// <param name="screenRectangle">Screen rectangle data</param> public Rect ToContentRectangle(Rect screenRectangle) { var transformer = TransformToVisual(ContentVisual); var tl = transformer.TransformPoint(new Point(screenRectangle.X, screenRectangle.Y)); var br = transformer.TransformPoint(new Point(screenRectangle.Right, screenRectangle.Bottom)); return new Rect(tl.X, tl.Y, Math.Abs(Math.Abs(br.X) - Math.Abs(tl.X)), Math.Abs(Math.Abs(br.Y) - Math.Abs(tl.Y))); }