示例#1
0
        private CGPath CreateCornerPath(double topLeft, double topRight, double bottomRight, double bottomLeft, CGRect insetBounds)
        {
            var cornerPath = new CGPath();

            // Start of our path is where the top left horizontal starts.
            cornerPath.MoveToPoint(new CGPoint(topLeft + insetBounds.X, insetBounds.Y));

            // Top line + top right corner
            cornerPath.AddLineToPoint(new CGPoint(insetBounds.Width - topRight, insetBounds.Y));
            cornerPath.AddArc((float)(insetBounds.X + insetBounds.Width - topRight), (float)(insetBounds.Y + topRight), (float)topRight, (float)(Math.PI * 1.5), (float)Math.PI * 2, false);

            // Right side + bottom right corner
            cornerPath.AddLineToPoint(insetBounds.Width + insetBounds.X, (float)(insetBounds.Height - bottomRight));
            cornerPath.AddArc((float)(insetBounds.X + insetBounds.Width - bottomRight), (float)(insetBounds.Y + insetBounds.Height - bottomRight), (float)bottomRight, 0, (float)(Math.PI * .5), false);

            // Bottom side + bottom left corner
            cornerPath.AddLineToPoint((float)(insetBounds.X + bottomLeft), insetBounds.Height + insetBounds.Y);
            cornerPath.AddArc((float)(insetBounds.X + bottomLeft), (float)(insetBounds.Y + insetBounds.Height - bottomLeft), (float)bottomLeft, (float)(Math.PI * .5), (float)Math.PI, false);

            // Left side + top left corner
            cornerPath.AddLineToPoint(insetBounds.X, (float)(insetBounds.Y + topLeft));
            cornerPath.AddArc((float)(insetBounds.X + topLeft), (float)(insetBounds.Y + topLeft), (float)topLeft, (float)Math.PI, (float)(Math.PI * 1.5), false);

            return(cornerPath);
        }
示例#2
0
        private CGPath NewBadgePathForTextSize(CGSize size)
        {
            nfloat arcRadius = (nfloat)Math.Ceiling((size.Height + Pad) / 2.0f);

            nfloat badgeWidthAdjustment = size.Width - (size.Height / 2.0f);
            nfloat badgeWidth           = 2.0f * arcRadius;
            var    m_pi_2 = (float)(Math.PI / 2);

            if (badgeWidthAdjustment > 0.0)
            {
                badgeWidth += badgeWidthAdjustment;
            }

            CGPath badgePath = new CGPath();

            //Add main circle
            badgePath.MoveToPoint(arcRadius, 0.0f);
            badgePath.AddArc(arcRadius, arcRadius, arcRadius, 3.0f * m_pi_2, m_pi_2, true);
            badgePath.AddLineToPoint(badgeWidth - arcRadius, 2.0f * arcRadius);
            badgePath.AddArc(badgeWidth - arcRadius, arcRadius, arcRadius, m_pi_2, 3.0f * m_pi_2, true);
            badgePath.AddLineToPoint(arcRadius, 0.0f);

            //Add sub circle
            badgePath.MoveToPoint(arcRadius, 0.0f);
            badgePath.AddArc(arcRadius, arcRadius, arcRadius / 2, m_pi_2, 3.0f * m_pi_2, false);
            badgePath.AddLineToPoint(badgeWidth - arcRadius, 2.0f * arcRadius);
            badgePath.AddArc(badgeWidth - arcRadius, arcRadius, arcRadius / 2, 3.0f * m_pi_2, m_pi_2, false);
            badgePath.AddLineToPoint(arcRadius, 0.0f);

            return(badgePath);
        }
示例#3
0
        protected virtual void DrawHeart(CGContext context, float x, float y, float width, float height, float cornerRadius, bool fill, bool stroke)
        {
            var length = Math.Min(height, width);

            var startPoint = new CGPoint(x, y + 2f * length / 3f);
            var p1         = new CGPoint(x, y + length);
            var p2         = new CGPoint(x + 2f * length / 3f, y + length);
            var c1         = new CGPoint(x + 2f * length / 3f, y + 2f * length / 3f);
            var c2         = new CGPoint(x + length / 3f, y + length / 3f);
            var radius     = length / 3f;

            var path = new CGPath();

            path.MoveToPoint(startPoint.X, startPoint.Y);

            path.AddArcToPoint(p1.X, p1.Y, p2.X, p2.Y, cornerRadius);
            path.AddLineToPoint(p2.X, p2.Y);
            path.AddArc(c1.X, c1.Y, radius, (float)-Math.PI / 2f, (float)Math.PI / 2f, false);
            path.AddArc(c2.X, c2.Y, radius, 0f, (float)Math.PI, true);
            path.CloseSubpath();

            var transform = CGAffineTransform.MakeTranslation(-length / 3f, -length * 2f / 3f);

            transform.Rotate((float)-Math.PI / 4f);
            transform.Scale(0.85f, 0.85f);
            transform.Translate(width / 2f, 1.1f * height / 2f);
            path = path.CopyByTransformingPath(transform);
            context.AddPath(path);

            this.DrawPath(context, fill, stroke);
        }
示例#4
0
        private static CGPath RoundedRect(nfloat left, nfloat top, nfloat right, nfloat bottom, nfloat r)
        {
            var path = new CGPath();

            if (r < 0)
            {
                r = 0;
            }
            var width  = right - left;
            var height = bottom - top;

            if (r > width / 2)
            {
                r = width / 2;
            }
            if (r > height / 2)
            {
                r = height / 2;
            }

            path.MoveToPoint(left, bottom);
            path.AddLineToPoint(left, top - r);
            path.AddArc(left + r, top + r, r, (float)Math.PI, (float)Math.PI * 3 / 2, false);
            path.AddLineToPoint(right - r, top);
            path.AddArc(right - r, top + r, r, (float)Math.PI / 2, 0, false);
            path.AddLineToPoint(right, bottom);
            path.CloseSubpath();

            return(path);
        }
示例#5
0
        CGPath CircleDrawing(float currentProgress)
        {
            var path   = new CGPath();
            var angle  = (Math.PI / 180) * (ProgressButtonIntegers.StartPosition.AsInt() - (int)currentProgress) * ProgressButtonFloats.CurrentProgress.AsFloat();
            var center = new  PointF(Rectangle.Height * 2 - ProgressButtonFloats.CenterPointX.AsFloat(), Rectangle.Height * 2);
            int radius = ProgressButtonIntegers.Radius.AsInt();

            path.MoveToPoint(new PointF(center.X, radius + center.Y));
            path.AddArc(center.X, center.Y, radius, Convert.ToSingle(Math.PI / 2), Convert.ToSingle(angle), true);
            path.AddArc(center.X, center.Y, radius - ProgressButtonFloats.CenterRadius.AsFloat(), Convert.ToSingle(angle), Convert.ToSingle(Math.PI / 2), false);
            return(path);
        }
示例#6
0
 protected virtual CGPath CreateTokenPath(SizeF size, bool innerPath)
 {
     return(Wrap.Function("CreateTokenPath", delegate()
     {
         CGPath path = new CGPath();
         float arcValue = (size.Height / 2) - 1;
         float radius = arcValue - (innerPath ? (1 / UIScreen.MainScreen.Scale) : 0);
         path.AddArc(arcValue, arcValue, radius, (float)(Math.PI / 2f), (float)(Math.PI * 3 / 2f), false);
         path.AddArc(size.Width - arcValue, arcValue, radius, (float)(Math.PI * 3 / 2), (float)(Math.PI / 2), false);
         path.CloseSubpath();
         return path;
     }));
 }
            private Arc DrawArc(CGContext context, double radius, CGPoint center, nfloat startingThickness, nfloat endingThickness, nfloat startingAngle, nfloat endingAngle)
            {
                using (CGPath path = new CGPath())
                {
                    context.SetLineWidth(0);
                    var deltaAngle = MathF.Abs(endingAngle - startingAngle);

                    // projectedEndingThickness is the ending thickness we would have if the two arcs
                    // subtended an angle of 180 degrees at their respective centers instead of deltaAngle
                    var projectedEndingThickness = startingThickness + (endingThickness - startingThickness) * (180.0f / deltaAngle);

                    var centerOffset      = (projectedEndingThickness - startingThickness) / 4.0f;
                    var centerForInnerArc = new CGPoint(center.X + centerOffset * Math.Cos(startingAngle * Math.PI / 180.0f),
                                                        center.Y + centerOffset * Math.Sin(startingAngle * Math.PI / 180.0f));
                    var centerForOuterArc = new CGPoint(center.X - centerOffset * Math.Cos(startingAngle * Math.PI / 180.0f),
                                                        center.Y - centerOffset * Math.Sin(startingAngle * Math.PI / 180.0f));

                    var radiusForInnerArc = (nfloat)radius - (startingThickness + projectedEndingThickness) / 4;
                    var radiusForOuterArc = (nfloat)radius + (startingThickness + projectedEndingThickness) / 4;

                    path.AddArc(
                        centerForInnerArc.X,
                        centerForInnerArc.Y,
                        radiusForInnerArc,
                        endingAngle * MathF.PI / 180.0f,
                        startingAngle * MathF.PI / 180.0f,
                        true);

                    var arc = new Arc()
                    {
                        Center        = centerForInnerArc,
                        Radius        = radiusForInnerArc,
                        StartingAngle = endingAngle * MathF.PI / 180.0f,
                        EndingAngle   = startingAngle * MathF.PI / 180.0f
                    };

                    path.AddArc(
                        centerForOuterArc.X,
                        centerForOuterArc.Y,
                        radiusForOuterArc,
                        startingAngle * MathF.PI / 180.0f,
                        endingAngle * MathF.PI / 180.0f,
                        false);

                    context.AddPath(path);

                    context.FillPath();

                    return(arc);
                }
            }
示例#8
0
        private CGPath CGPathCreateArc(CGPoint center, nfloat radius, nfloat startAngle, nfloat endAngle, nfloat lineStroke)
        {
            var path = new CGPath();

            path.AddArc(center.X, center.Y, radius, startAngle, endAngle, false);
            return(path.CopyByStrokingPath(lineStroke, CGLineCap.Butt, CGLineJoin.Miter, 10));
        }
        public void DrawGraph(CGContext g, nfloat x0, nfloat y0, nfloat piMult)
        {
            //_g = g;
            _x0 = x0;
            _y0 = y0;

            _g.SetLineWidth(_lineWidth);
            //_piMult = piMult;

            // Draw circle
            CGPath path = new CGPath();

            UIColor.FromRGB(155, 155, 155).SetStroke();
            path.AddArc(_x0, _y0, _radius, 0.79f * (float)Math.PI, (2.21f) * (float)Math.PI, false);
            _g.AddPath(path);
            _g.DrawPath(CGPathDrawingMode.Stroke);
            //SetNeedsDisplay();

            CGPath path2 = new CGPath();

            _barColor.SetStroke();
            path2.AddArc(_x0, _y0, _radius, 0.79f * (float)Math.PI, (0.79f * (float)Math.PI + (float)(0.71 * _piMult) * (float)Math.PI), false);
            //path2.AddArc(x0, y0, _radius, -0.5f * (float)Math.PI, 0.5f * (float)Math.PI + _piMult * (float)Math.PI * 0.99, true);
            _g.AddPath(path2);
            _g.DrawPath(CGPathDrawingMode.Stroke);
            //SetNeedsDisplay();
        }
示例#10
0
        private CGPath CGPathCreateArc(PointF center, float radius, double startAngle, double endAngle, float lineStroke)
        {
            var path = new CGPath();

            path.AddArc(center.X, center.Y, radius, Convert.ToSingle(startAngle), Convert.ToSingle(endAngle), false);
            return(path.CopyByStrokingPath(lineStroke, CGLineCap.Butt, CGLineJoin.Miter, 10));
        }
        private void StartAnimatingTransaction()
        {
            CATransaction.Begin();


            float M_PI_2 = ((float)(Math.PI)) / 2.0f;

            CGAffineTransform tnull = CGAffineTransform.MakeIdentity();

            CGPath circlePath = new CGPath();

            circlePath.MoveToPoint(tnull, Frame.Width / 2.0f, Frame.Height - circleSize / 2.0f);
            circlePath.AddArc(tnull, Frame.Width / 2.0f, Frame.Height / 2.0f, radius - 15 / 2, M_PI_2, -M_PI_2 * 3, false);

            for (int i = 0; i < Layer.Sublayers.Length; i++)
            {
                CALayer circleLayer = Layer.Sublayers[i];

                CAKeyFrameAnimation circleAnimation = CAKeyFrameAnimation.GetFromKeyPath("position");
                circleAnimation.BeginTime       = CAAnimation.CurrentMediaTime() + 0.2f * i;
                circleAnimation.Duration        = 1.5;
                circleAnimation.TimingFunction  = CAMediaTimingFunction.FromControlPoints(0.15f, 0.60f, 0.85f, 0.4f);
                circleAnimation.CalculationMode = CAKeyFrameAnimation.AnimationPaced;
                circleAnimation.Path            = circlePath;
                circleAnimation.RepeatCount     = float.MaxValue;
                if (circleLayer == this.Layer.Sublayers[Layer.Sublayers.Length - 1])
                {
                    circleAnimation.WeakDelegate = this;
                }
                circleLayer.AddAnimation(circleAnimation, "circleAnimation");
            }
            //CGPathRelease(circlePath);

            CATransaction.Commit();
        }
        // TODO Optimize circle drawing by removing allocation of CGPath
        // (maybe by drawing via BitmapContext, per pixel:
        // https://stackoverflow.com/questions/34987442/drawing-pixels-on-the-screen-using-coregraphics-in-swift)
        private void DrawProgressRing(CGContext g, nfloat x0, nfloat y0,
                                      nfloat progress, nfloat lineThickness, nfloat radius,
                                      UIColor backColor, UIColor frontColor)
        {
            g.SetLineWidth(lineThickness);

            // Draw background circle
            CGPath path = new CGPath();

            backColor.SetStroke();

            path.AddArc(x0, y0, radius, 0, 2.0f * (float)Math.PI, true);
            g.AddPath(path);
            g.DrawPath(CGPathDrawingMode.Stroke);

            // Draw progress circle
            var pathStatus = new CGPath();

            frontColor.SetStroke();

            var startingAngle = 1.5f * (float)Math.PI;

            pathStatus.AddArc(x0, y0, radius, startingAngle, startingAngle + progress * 2 * (float)Math.PI, false);

            g.AddPath(pathStatus);
            g.DrawPath(CGPathDrawingMode.Stroke);
        }
示例#13
0
        private UIImage CreatePieSegment(CGSize size, nfloat endAngle)
        {
            // Add the arc
            var arc = new CGPath();

            arc.MoveToPoint(size.Width / 2.0f, size.Height / 2.0f);
            arc.AddLineToPoint(size.Width / 2.0f, 0);
            arc.AddArc(size.Width / 2.0f, size.Height / 2.0f, size.Width / 2.0f, _startAngle, endAngle, false);
            arc.AddLineToPoint(size.Width / 2.0f, size.Height / 2.0f);

            // Stroke the arc
            UIGraphics.BeginImageContextWithOptions(size, false, 0);

            var context = UIGraphics.GetCurrentContext();

            context.AddPath(arc);
            context.SetFillColor(UIColor.FromRGBA(0f, 0f, 0f, 1f).CGColor);
            context.FillPath();

            // Get the mask image
            var image = UIGraphics.GetImageFromCurrentImageContext();

            UIGraphics.EndImageContext();

            return(image);
        }
示例#14
0
        public override void Draw(CGRect rect)
        {
            //get graphics context
            using (CGContext g = UIGraphics.GetCurrentContext())
            {                
                g.SetLineWidth(_lineWidth);
                //set up drawing attributes
                UIColor.Clear.SetFill();

                if (_isRound)
                {
                    var circle = new CGPath();
                    var circleSize = rect.Size.Width / 2;
                    circle.AddArc(circleSize, circleSize, circleSize, 0, endangle, true);
                    Console.WriteLine("circleSize: {0}", circleSize);
                    g.AddPath(circle);
                }
                else
                {
                    //create geometry
                    var rectangle = new CGPath();
                    rectangle.AddRect(new RectangleF(0f, 0f, (float)rect.Size.Width, (float)rect.Size.Height));
                    rectangle.CloseSubpath();
                    //add geometry to graphics context and draw it
                    g.AddPath(rectangle);
                }

                g.SetStrokeColor(_color.CGColor);
                g.SetAlpha(_transparancy);
                
                g.DrawPath(CGPathDrawingMode.Stroke);
            }
        }
        private UIImage CreatePieSegment(CGSize size, nfloat endAngle)
        {
            // Add the arc
            var arc = new CGPath();

            arc.MoveToPoint(size.Width / 2.0f, size.Height / 2.0f);
            arc.AddLineToPoint(size.Width / 2.0f, 0);
            arc.AddArc(size.Width / 2.0f, size.Height / 2.0f, size.Width / 2.0f, _startAngle, endAngle, false);
            arc.AddLineToPoint(size.Width / 2.0f, size.Height / 2.0f);

            // Stroke the arc
            UIGraphics.BeginImageContextWithOptions(size, false, 0);

            var context = UIGraphics.GetCurrentContext();

            context.AddPath(arc);
            context.SetFillColor(UIColor.FromRGBA(0f, 0f, 0f, 1f).CGColor);
            context.FillPath();

            // Get the mask image
            var image = UIGraphics.GetImageFromCurrentImageContext();

            UIGraphics.EndImageContext();

            return image;
        }
示例#16
0
        public void RenderExplodedMine()
        {
            RemoveAllChildren();
            var s    = new SKShapeNode();
            var path = new CGPath();

            path.MoveToPoint(0, 0);
            path.AddLineToPoint(size, 0);
            path.AddLineToPoint(size, size);
            path.AddLineToPoint(0, size);
            path.AddLineToPoint(0, 0);
            s.Path        = path.CopyByTransformingPath(CGAffineTransform.MakeTranslation(x * size, y * size));
            s.StrokeColor = NSColor.FromCalibratedRgb(0.502f, 0.502f, 0.502f);
            s.FillColor   = NSColor.FromCalibratedRgb(0.8f, 0.8f, 0.8f);
            AddChild(s);

            var s1 = new SKShapeNode();
            var p1 = new CGPath();

            p1.AddArc(x * size + size / 2, y * size + size / 2, size / 4, 0, 2 * (float)Math.PI, true);
            s1.Path        = p1;
            s1.StrokeColor = NSColor.FromCalibratedRgb(0.2f, 0.2f, 0.2f);
            s1.FillColor   = NSColor.FromCalibratedRgb(0.8f, 0.0f, 0.0f);
            AddChild(s1);
        }
示例#17
0
        public override void Draw(CGRect rect)
        {
            base.Draw(rect);
            using (CGContext context = UIGraphics.GetCurrentContext())
            {
                var    radius = this.Frame.Width / 2;
                CGPath path   = new CGPath();
                path.AddArc(this.Frame.Width / 2, this.Frame.Height / 2, radius - 1, 0, (nfloat)(360 * radians), true);
                ViewColor.SetColor();
                context.AddPath(path);
                context.DrawPath(CGPathDrawingMode.FillStroke);

                UIColor.White.SetColor();
                CTFont             font            = new CTFont("Arial", 20);
                NSAttributedString stringToBeDrawn = new NSAttributedString(text, new CTStringAttributes()
                {
                    Font = font,
                    ForegroundColorFromContext = true,
                });

                context.TranslateCTM(this.Frame.Width / 2 - stringToBeDrawn.Size.Width / 2, this.Frame.Height / 2 + stringToBeDrawn.Size.Height / 4);
                context.ScaleCTM(1, -1);
                CTLine line = new CTLine(stringToBeDrawn);
                line.Draw(context);

                font            = null;
                stringToBeDrawn = null;
                path            = null;
            }
        }
        public Stream GetFilledCircleWithCenteredText(int imgSize, string rgbCircleColor, string txt, string rgbTextColor, string fontFamilyName, int fontSize)
        {
            Stream result = null;

            using (UIImage image = new UIImage())
            {
                UIGraphics.BeginImageContext(new SizeF(imgSize, imgSize));

                CGRect rect = new CGRect(0, 0, imgSize, imgSize);

                image.Draw(rect);

                using (CGContext g = UIGraphics.GetCurrentContext())
                {
                    float x = (float)(rect.X + (rect.Width / 2));
                    float y = (float)(rect.Y + (rect.Height / 2));

                    // Draws the circle
                    UIColor background = FromHexString(rgbCircleColor);
                    g.SetLineWidth(1);
                    g.SetFillColor(background.CGColor);
                    g.SetStrokeColor(background.CGColor);

                    CGPath path = new CGPath();
                    path.AddArc(x, y, NMath.Min(rect.Width, rect.Height) / 2 - 1f, 0, 2.0f * (float)Math.PI, true);
                    g.AddPath(path);
                    g.DrawPath((CGPathDrawingMode.FillStroke));


                    // Draws the text
                    g.SetFillColor(FromHexString(rgbTextColor).CGColor);

                    var attributedString = new NSAttributedString(txt, new CoreText.CTStringAttributes {
                        ForegroundColorFromContext = true, Font = new CoreText.CTFont(fontFamilyName, fontSize * 2)
                    });

                    using (var textLine = new CoreText.CTLine(attributedString))
                    {
                        g.TranslateCTM(x - (textLine.GetBounds(CoreText.CTLineBoundsOptions.UseGlyphPathBounds).Width / 2), y + (textLine.GetBounds(CoreText.CTLineBoundsOptions.UseGlyphPathBounds).Height / 2));
                        g.ScaleCTM(1, -1);
                        textLine.Draw(g);
                    }
                }

                var resultImage = UIGraphics.GetImageFromCurrentImageContext();

                UIGraphics.EndImageContext();

                NSData data = resultImage.AsPNG();

                result = data.AsStream();
            }

            return(result);
        }
示例#19
0
        private CGPath CGPathCreateArc(CGPoint center, nfloat radius, nfloat startAngle, nfloat endAngle)
        {
            var    path = new CGPath();
            CGPath resultPath;

            if (IsDonut)
            {
                path.AddArc(center.X, center.Y, radius, startAngle, endAngle, false);
                resultPath = path.CopyByStrokingPath(DonutLineStroke, CGLineCap.Butt, CGLineJoin.Miter, 10);
                path.Dispose();
            }
            else
            {
                path.MoveToPoint(center.X, center.Y);
                path.AddArc(center.X, center.Y, radius, startAngle, endAngle, false);
                path.CloseSubpath();
                resultPath = path;
            }
            return(resultPath);
        }
示例#20
0
        private CGPath CGPathCreateArc(PointF center, float radius, double startAngle, double endAngle)
        {
            var    path = new CGPath();
            CGPath resultPath;

            if (IsDonut)
            {
                path.AddArc(center.X, center.Y, radius, Convert.ToSingle(startAngle), Convert.ToSingle(endAngle), false);
                resultPath = path.CopyByStrokingPath(DonutLineStroke, CGLineCap.Butt, CGLineJoin.Miter, 10);
                path.Dispose();
            }
            else
            {
                path.MoveToPoint(center.X, center.Y);
                path.AddArc(center.X, center.Y, radius, Convert.ToSingle(startAngle), Convert.ToSingle(endAngle), false);
                path.CloseSubpath();
                resultPath = path;
            }
            return(resultPath);
        }
示例#21
0
        private void DrawMine()
        {
            var s1 = new SKShapeNode();
            var p1 = new CGPath();

            p1.AddArc(size / 2, size / 2, size / 4, 0, 2 * (float)Math.PI, true);
            s1.Path        = p1.CopyByTransformingPath(CGAffineTransform.MakeTranslation(x * size, y * size));
            s1.StrokeColor = NSColor.FromCalibratedRgb(0.2f, 0.2f, 0.2f);
            s1.FillColor   = NSColor.FromCalibratedRgb(0.4f, 0.4f, 0.4f);
            AddChild(s1);
        }
示例#22
0
        CAShapeLayer SetupBackgroundLayer()
        {
            var path   = new CGPath();
            var angle  = (Math.PI / 180) * (ProgressButtonIntegers.StartPosition.AsInt() - ProgressButtonIntegers.Size.AsInt()) * ProgressButtonFloats.CurrentProgress.AsFloat();
            var center = new PointF(Rectangle.Height * 2 - ProgressButtonFloats.CenterMargin.AsFloat(), Rectangle.Height * 2);
            int radius = (int)Rectangle.Height;

            path.MoveToPoint(new PointF(center.X, ProgressButtonFloats.CenterSize.AsFloat() + center.Y));
            path.AddArc(center.X, center.Y, radius, Convert.ToSingle(Math.PI / 2), Convert.ToSingle(angle), true);
            path.AddArc(center.X, center.Y, radius - ProgressButtonFloats.CenterRadius.AsFloat(), Convert.ToSingle(angle), Convert.ToSingle(Math.PI / 2), false);
            // var _backgroundImage = ProgressButtonImages.BackgroundImage.AsResourceNsImage();

            _colorAnimationRing = new CAShapeLayer
            {
                FillColor = ProgressButtonColors.ProgressColorDisableState.AsResourceCgColor(),
                Path      = path
            };

            return(_colorAnimationRing);
        }
示例#23
0
        private CGPath CreateCornerPath(double topLeft, double topRight, double bottomRight, double bottomLeft, CGRect insetBounds)
        {
            var cornerPath = new CGPath();

            cornerPath.MoveToPoint(new CGPoint(topLeft + insetBounds.X, insetBounds.Y));

            cornerPath.AddLineToPoint(new CGPoint(insetBounds.Width - topRight, insetBounds.Y));
            cornerPath.AddArc((float)(insetBounds.X + insetBounds.Width - topRight), (float)(insetBounds.Y + topRight), (float)topRight, (float)(Math.PI * 1.5), (float)Math.PI * 2, false);

            cornerPath.AddLineToPoint(insetBounds.Width + insetBounds.X, (float)(insetBounds.Height - bottomRight));
            cornerPath.AddArc((float)(insetBounds.X + insetBounds.Width - bottomRight), (float)(insetBounds.Y + insetBounds.Height - bottomRight), (float)bottomRight, 0, (float)(Math.PI * .5), false);

            cornerPath.AddLineToPoint((float)(insetBounds.X + bottomLeft), insetBounds.Height + insetBounds.Y);
            cornerPath.AddArc((float)(insetBounds.X + bottomLeft), (float)(insetBounds.Y + insetBounds.Height - bottomLeft), (float)bottomLeft, (float)(Math.PI * .5), (float)Math.PI, false);

            cornerPath.AddLineToPoint(insetBounds.X, (float)(insetBounds.Y + topLeft));
            cornerPath.AddArc((float)(insetBounds.X + topLeft), (float)(insetBounds.Y + topLeft), (float)topLeft, (float)Math.PI, (float)(Math.PI * 1.5), false);

            return(cornerPath);
        }
示例#24
0
        public void DrawGraph(CGContext g, nfloat x, nfloat y)
        {
            g.SetLineWidth(_lineWidth);

            // Draw circle
            CGPath path = new CGPath();

            _backColor.SetStroke();
            path.AddArc(x, y, _radius, 0, FULL_CIRCLE, true);
            g.AddPath(path);
            g.DrawPath(CGPathDrawingMode.Stroke);
        }
示例#25
0
            public override void DrawInContext(CoreGraphics.CGContext ctx)
            {
                CGRect       rect       = this.BoundsRect();
                CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB();

                nfloat [] colors = new nfloat[] {
                    0.42f, 0.66f, 0.31f, 1.0f,
                    0.95f, 0.76f, 0.20f, 1.0f,
                    0.80f, 0.25f, 0.15f, 1.0f
                };

                CGGradient gradient = new CGGradient(colorSpace, colors, null);

                nuint tickSpaces  = this.Axis.MajorTickCount - 1;
                nuint pointsCount = 5;

                if (this.Chart.Frame.Size.Height < this.Chart.Frame.Size.Width)
                {
                    pointsCount = 3;
                }

                nfloat diameter           = 8;
                nfloat spaceHeight        = rect.Size.Height / tickSpaces;
                nfloat spacing            = (spaceHeight - (pointsCount * diameter)) / (pointsCount + 1);
                nuint  allPointsCount     = pointsCount * tickSpaces;
                CGPath multipleCirclePath = new CGPath();
                double y = rect.GetMinY() + diameter / 2.0f + spacing;

                for (uint i = 1; i <= allPointsCount; i++)
                {
                    CGPoint center = new CGPoint(rect.GetMidX(), y);
                    CGPath  path   = new CGPath();
                    path.AddArc(center.X, center.Y, (nfloat)diameter / 2.0f, 0, (nfloat)Math.PI * 2, true);
                    multipleCirclePath.AddPath(path);
                    y += spacing + diameter;
                    if (i % pointsCount == 0)
                    {
                        y += spacing;
                    }
                }

                ctx.SaveState();
                ctx.AddPath(multipleCirclePath);
                ctx.Clip();
                CGPoint startPoint = new CGPoint(rect.GetMidX(), rect.GetMinY());
                CGPoint endPoint   = new CGPoint(rect.GetMidX(), rect.GetMaxY());

                ctx.DrawLinearGradient(gradient, startPoint, endPoint, 0);
                ctx.RestoreState();

                base.DrawInContext(ctx);
            }
示例#26
0
        private void BCDrawOneWedge(double a1, double a2, UIColor color, string lbl, CGContext ctxt)
        {
            // ----------------------------------------------------------------
            var path = new CGPath();

            var p0 = new CGPoint(X, Y);
//         var p1 = new CGPoint (x + rOuter * Math.Cos (a1), y + rOuter * Math.Sin (a1));
//         var p2 = new CGPoint (x + rOuter * Math.Cos (a2), y + rOuter * Math.Sin (a2));
//         var q1 = new CGPoint (x + rInner * Math.Cos (a1), y + rInner * Math.Sin (a1));
//         var q2 = new CGPoint (x + rInner * Math.Cos (a2), y + rInner * Math.Sin (a2));

            CGPoint p1, p2, q1, q2;

            p1 = GetPoint(p0, a1, rOuter);
            p2 = GetPoint(p0, a2, rOuter);
            q1 = GetPoint(p0, a1, rInner);
            q2 = GetPoint(p0, a2, rInner);

            path.MoveToPoint(q1);
            path.AddLineToPoint(p1);
            path.AddArc((nfloat)X, (nfloat)Y, (nfloat)rOuter, (nfloat)a1, (nfloat)a2, true);
            path.AddLineToPoint(q2);
            path.AddArc((nfloat)X, (nfloat)Y, (nfloat)rInner, (nfloat)a2, (nfloat)a1, false);

            path.CloseSubpath();

            color.SetFill();

            ctxt.AddPath(path);
            ctxt.DrawPath(CGPathDrawingMode.EOFillStroke);

            // Write the segment label, if wedge is wide enough...
            // .35 radians is about 20 deg. This is arbitrary cutoff.
            if (lbl != "" && Math.Abs(a2 - a1) >= 0.35)
            {
                var pCenter = GetPoint(p0, (a2 + a1) * 0.5F, (rOuter + rInner) * 0.5F);
                WriteWedgeLabel(lbl, pCenter.X - 10.0F, pCenter.Y, ctxt);
            }
        }
        private void UpdateBorderLayer(PancakeView pancake)
        {
            // The border layer needs to be updated because the Bounds are only available later.
            if (pancake.BorderThickness > 0 && _borderLayer != null)
            {
                var insetBounds = Bounds.Inset(pancake.BorderThickness, pancake.BorderThickness);

                // Create arcs for the given corner radius.
                var cornerPath = new CGPath();

                // Start of our path is where the top left horizontal starts.
                cornerPath.MoveToPoint(new CGPoint(pancake.CornerRadius.TopLeft + insetBounds.X, insetBounds.Y));

                // Top line + top right corner
                cornerPath.AddLineToPoint(new CGPoint(insetBounds.Width - pancake.CornerRadius.TopRight, insetBounds.Y));
                cornerPath.AddArc((float)(insetBounds.X + insetBounds.Width - pancake.CornerRadius.TopRight), (float)(insetBounds.Y + pancake.CornerRadius.TopRight), (float)pancake.CornerRadius.TopRight, (float)(Math.PI * 1.5), (float)Math.PI * 2, false);

                // Right side + bottom right corner
                cornerPath.AddLineToPoint(insetBounds.Width + insetBounds.X, (float)(insetBounds.Height - pancake.CornerRadius.BottomRight));
                cornerPath.AddArc((float)(insetBounds.X + insetBounds.Width - pancake.CornerRadius.BottomRight), (float)(insetBounds.Y + insetBounds.Height - pancake.CornerRadius.BottomRight), (float)pancake.CornerRadius.BottomRight, 0, (float)(Math.PI * .5), false);

                // Bottom side + bottom left corner
                cornerPath.AddLineToPoint((float)(insetBounds.X + pancake.CornerRadius.BottomLeft), insetBounds.Height + insetBounds.Y);
                cornerPath.AddArc((float)(insetBounds.X + pancake.CornerRadius.BottomLeft), (float)(insetBounds.Y + insetBounds.Height - pancake.CornerRadius.BottomLeft), (float)pancake.CornerRadius.BottomLeft, (float)(Math.PI * .5), (float)Math.PI, false);

                // Left side + top left corner
                cornerPath.AddLineToPoint(insetBounds.X, (float)(insetBounds.Y + pancake.CornerRadius.TopLeft));
                cornerPath.AddArc((float)(insetBounds.X + pancake.CornerRadius.TopLeft), (float)(insetBounds.Y + pancake.CornerRadius.TopLeft), (float)pancake.CornerRadius.TopLeft, (float)Math.PI, (float)(Math.PI * 1.5), false);

                _borderLayer.Frame = Bounds;
                _borderLayer.Path  = cornerPath;

                // Dash pattern for the border.
                if (pancake.BorderIsDashed)
                {
                    _borderLayer.LineDashPattern = new NSNumber[] { new NSNumber(5), new NSNumber(2) };
                }
            }
        }
示例#28
0
        public void AddArc()
        {
            var matrix = CGAffineTransform.MakeIdentity();

            using (CGPath p1 = new CGPath())
                using (CGPath p2 = new CGPath()) {
                    Assert.IsTrue(p1.IsEmpty, "IsEmpty-1");
                    p1.AddArc(0, 0, 10, 0, 90, true);
                    p2.AddArc(matrix, 0, 0, 10, 0, 90, true);
                    Assert.IsFalse(p1.IsEmpty, "IsEmpty-2");
                    Assert.That(p1, Is.EqualTo(p2), "CGPathEqualToPath");
                }
        }
		void AddAnchorDotToSprite (SKSpriteNode sprite)
		{
			CGPath myPath = new CGPath ();
			myPath.AddArc (0, 0, 10, 0, (float) Math.PI * 2, true);
			myPath.CloseSubpath ();

			SKShapeNode dot = new SKShapeNode () {
				Path = myPath,
				FillColor = UIColor.Green,
				LineWidth = 0.0f
			};
			sprite.AddChild (dot);
		}
        // Shared initialization code
        void Initialize()
        {
            WantsLayer = true;

            var center = new CGPoint(Frame.Width / 2, Frame.Height / 2);

            outerCircleLayer = new CAShapeLayer();

            var    path  = new CGPath();
            nfloat radis = (Frame.Width - 2) / 2;

            path.AddArc(center.X, center.Y, radis, 0, (float)(2 * Math.PI), true);

            outerCircleLayer.Path        = path;
            outerCircleLayer.FillColor   = NSColor.Clear.CGColor;
            outerCircleLayer.LineWidth   = 1.0f;
            outerCircleLayer.StrokeColor = NSColor.White.CGColor;
            outerCircleLayer.StrokeStart = 0.0f;
            outerCircleLayer.StrokeEnd   = 1.0f;

            Layer.AddSublayer(outerCircleLayer);

            progressLayer = new CAShapeLayer();

            var progressPath = new CGPath();

            float start = (float)(Math.PI / 2);
            float end   = (float)(-3 * Math.PI / 2);

            radis = (Frame.Width - 6) / 2;

            progressPath.AddArc(center.X, center.Y, radis, start, end, true);

            progressLayer.Path        = progressPath;
            progressLayer.FillColor   = NSColor.Clear.CGColor;
            progressLayer.LineWidth   = 3.0f;
            progressLayer.StrokeColor = NSColor.White.CGColor;
            progressLayer.StrokeStart = 0;
            progressLayer.StrokeEnd   = 0.0f;
            Layer.AddSublayer(progressLayer);

            //Circle progress view center
            var centerRectLayer = new CAShapeLayer();

            centerRectLayer.Bounds          = new CGRect(0, 0, 8, 8);
            centerRectLayer.Position        = center;
            centerRectLayer.FillColor       = NSColor.White.CGColor;
            centerRectLayer.BackgroundColor = NSColor.White.CGColor;
            Layer.AddSublayer(centerRectLayer);
        }
示例#31
0
 public override void Draw(CGRect rect)
 {
     base.Draw(rect);
     using (var gctx = UIGraphics.GetCurrentContext())
     {
         var pathStatus = new CGPath ();
         pathStatus.AddArc(rect.GetMidX(), rect.GetMidY(), (rect.Width>rect.Height?rect.Height/2:rect.Width/2)/2,
             1.5f* (float)Math.PI, this.angle * (float)Math.PI+1.5f* (float)Math.PI, false);
         gctx.SetLineWidth (rect.Width>rect.Height?rect.Height/2:rect.Width/2);
         gctx.SetStrokeColor (color);
         gctx.AddPath (pathStatus);
         gctx.DrawPath (CGPathDrawingMode.Stroke);
     }
 }
        private CGPath NewBadgePathForTextSize(SizeF size)
        {
            float arcRadius = (float)Math.Ceiling((size.Height + this.Pad) / 2.0f);

            float badgeWidthAdjustment = size.Width - (size.Height / 2.0f);
            float badgeWidth           = 2.0f * arcRadius;

            if (badgeWidthAdjustment > 0.0)
            {
                badgeWidth += badgeWidthAdjustment;
            }

            CGPath badgePath = new CGPath();

            var m_pi_2 = (float)(Math.PI / 2);

            badgePath.MoveToPoint(arcRadius, 0.0f);
            badgePath.AddArc(arcRadius, arcRadius, arcRadius, 3.0f * m_pi_2, m_pi_2, true);
            badgePath.AddLineToPoint(badgeWidth - arcRadius, 2.0f * arcRadius);
            badgePath.AddArc(badgeWidth - arcRadius, arcRadius, arcRadius, m_pi_2, 3.0f * m_pi_2, true);
            badgePath.AddLineToPoint(arcRadius, 0.0f);

            return(badgePath);
        }
示例#33
0
		public PlanetNode (CGPoint initialPosition, float size = defaultSize)
		{
			var path = new CGPath ();
			path.AddArc (0, 0, size, 0, (float)Math.PI * 2f, true);
			Path = path;
			StrokeColor = UIColor.Clear;
			FillColor = UIColor.Green;
			Position = initialPosition;
			// use a local variable to avoid multiple virtual call to the `PhysicsBody` property
			var body = SKPhysicsBody.CreateCircularBody (size);
			body.CategoryBitMask = Category.Planet;
			body.CollisionBitMask = Category.Planet | Category.Edge;
			body.ContactTestBitMask = 0;
			PhysicsBody = body;
		}
示例#34
0
 public AsteroidNode(PointF initialPosition, float size = defaultSize)
 {
     var path = new CGPath ();
     path.AddArc (0, 0, size, 0, (float)Math.PI * 2f, true);
     Path = path;
     StrokeColor = UIColor.Clear;
     FillColor = UIColor.Brown;
     Position = initialPosition;
     // use a local variable to avoid multiple virtual call to the `PhysicsBody` property
     var body = SKPhysicsBody.BodyWithCircleOfRadius (size);
     body.CategoryBitMask = Category.Asteroid;
     body.CollisionBitMask = Category.Ship | Category.Asteroid | Category.Edge;
     body.ContactTestBitMask = Category.Planet;
     PhysicsBody = body;
 }
示例#35
0
        public override void Draw(CGRect rect)
        {
            base.Draw(rect);
            using (var context = UIGraphics.GetCurrentContext())
            {
                var element = (CircleShape)Element;

                context.SetFillColor(element.ShapeColor.ToUIColor().CGColor);
                CGPath path = new CGPath();
                path.AddArc(this.Bounds.Width / 2, this.Bounds.Height / 2, (nfloat)element.CircleRadius, 0, FULL_CIRCLE, false);
                context.AddPath(path);
                context.DrawPath(CGPathDrawingMode.Fill);

                path.Dispose();
            }
        }
示例#36
0
		public CustomLayerBasedView (CGRect rect) : base (rect)
		{
			WantsLayer = true;

			CAShapeLayer shapeLayer = new CAShapeLayer ();
		
			// Create a circle path
			CGPath path = new CGPath ();
			path.AddArc (rect.Width / 2, rect.Height / 2, (rect.Height / 2) - 10, (float)(-(Math.PI / 2)), (float)(3 * Math.PI / 2), false);
			shapeLayer.Path = path;
			shapeLayer.Position = new CGPoint (Bounds.Width / 2, Bounds.Height / 2);
			shapeLayer.FillColor = NSColor.LightGray.CGColor;
			shapeLayer.StrokeColor = NSColor.Blue.CGColor;
			shapeLayer.LineWidth = 2;
			Layer = shapeLayer;
		}
        void AddAnchorDotToSprite(SKSpriteNode sprite)
        {
            CGPath myPath = new CGPath();

            myPath.AddArc(0, 0, 10, 0, (float)Math.PI * 2, true);
            myPath.CloseSubpath();

            SKShapeNode dot = new SKShapeNode()
            {
                Path      = myPath,
                FillColor = UIColor.Green,
                LineWidth = 0.0f
            };

            sprite.AddChild(dot);
        }
示例#38
0
			public override void DrawInContext (CoreGraphics.CGContext ctx)
			{
				CGRect rect = this.BoundsRect();
				CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB ();
				nfloat [] colors = new nfloat[] {
					0.42f, 0.66f, 0.31f, 1.0f,
					0.95f, 0.76f, 0.20f, 1.0f,
					0.80f, 0.25f, 0.15f, 1.0f
				};

				CGGradient gradient = new CGGradient (colorSpace, colors, null);

				nuint tickSpaces = this.Axis.MajorTickCount - 1;
				nuint pointsCount = 5;
				if (this.Chart.Frame.Size.Height < this.Chart.Frame.Size.Width) {
					pointsCount = 3;
				}

				nfloat diameter = 8;
				nfloat spaceHeight = rect.Size.Height / tickSpaces;
				nfloat spacing = (spaceHeight - (pointsCount * diameter)) / (pointsCount + 1);
				nuint allPointsCount = pointsCount * tickSpaces;
				CGPath multipleCirclePath = new CGPath ();
				double y = rect.GetMinY() +  diameter / 2.0f  + spacing;

				for (uint i = 1; i <= allPointsCount; i++) {
					CGPoint center = new CGPoint (rect.GetMidX (), y);
					CGPath path = new CGPath ();
					path.AddArc (center.X, center.Y, (nfloat)diameter/2.0f, 0, (nfloat)Math.PI * 2, true);
					multipleCirclePath.AddPath (path);
					y += spacing + diameter;
					if (i % pointsCount == 0) {
						y += spacing;
					}
				}

				ctx.SaveState ();
				ctx.AddPath (multipleCirclePath);
				ctx.Clip ();
				CGPoint startPoint = new CGPoint (rect.GetMidX (), rect.GetMinY ());
				CGPoint endPoint = new CGPoint (rect.GetMidX (), rect.GetMaxY());
				ctx.DrawLinearGradient (gradient, startPoint, endPoint, 0);
				ctx.RestoreState ();

				base.DrawInContext (ctx);
			}
        public void DrawGraph(CGContext g,nfloat x0,nfloat y0)
        {
            g.SetLineWidth (_lineWidth);

            // Draw background circle
            CGPath path = new CGPath ();
            _backColor.SetStroke ();
            path.AddArc (x0, y0, _radius, 0, 2.0f * (float)Math.PI, true);
            g.AddPath (path);
            g.DrawPath (CGPathDrawingMode.Stroke);

            // Draw overlay circle
            var pathStatus = new CGPath ();
            _frontColor.SetStroke ();
            pathStatus.AddArc(x0, y0, _radius, 0, _degrees * (float)Math.PI, false);
            g.AddPath (pathStatus);
            g.DrawPath (CGPathDrawingMode.Stroke);
        }
        public override void Draw(CGRect rect)
        {
            base.Draw(rect);

            using (CGContext g = UIGraphics.GetCurrentContext())
            {
                // Set up drawing attributes
                g.SetLineWidth(1);
                UIColor.Red.SetStroke();

                // Set up the drawing path
                var path = new CGPath();
                path.AddArc(_center.X, _center.Y, _radius, 0.0F, 2 * ((float)Math.PI), false);

                // Add path to context and draw
                g.AddPath(path);
                g.DrawPath(CGPathDrawingMode.Stroke);
            }
        }
		private void DrawThatMesmerizingThing ()
		{
			using (var ctx = UIGraphics.GetCurrentContext ())
			{
				ctx.SetLineWidth (8);

				UIColor.White.SetFill ();
				UIColor.Black.SetStroke ();

				for (var x = 0; x < 10; x++) 
				{
					var path = new CGPath ();
					path.AddArc (Frame.GetMidX (), Frame.GetMidY (), Dimensions[x].R, (nfloat)(Dimensions[x].Et * Math.PI), (nfloat)(Dimensions[x].St * Math.PI), false);
					ctx.AddPath (path);
				}

				ctx.DrawPath (CGPathDrawingMode.FillStroke);
			}
		}
示例#42
0
		public override void Draw(CGRect rect)
		{
			base.Draw(rect);

			//get graphics context
			using (var g = UIGraphics.GetCurrentContext())
			{
				// set up drawing attributes
				g.SetLineWidth(10.0f);
				UIColor.Green.SetFill();
				UIColor.Blue.SetStroke();

				// create geometry
				var path = new CGPath();
				path.AddArc(Bounds.GetMidX(), Bounds.GetMidY(), 50f, 0, 2.0f * (float)Math.PI, true);

				// add geometry to graphics context and draw
				g.AddPath(path);
				g.DrawPath(CGPathDrawingMode.FillStroke);
			}
		}
 public override void ViewDidLoad ()
 {
     base.ViewDidLoad ();
     
     // draw a new banana image              
     addBanana.TouchUpInside += delegate {
         
         // create a graphics context with an in memory bitmap backing store
         UIGraphics.BeginImageContext (new SizeF (100.0f, 100.0f));
         
         // get graphics context
         CGContext gctx = UIGraphics.GetCurrentContext ();
         
         // set up drawing attributes
         gctx.SetLineWidth (5);
         UIColor.Brown.SetStroke ();
         UIColor.Yellow.SetFill ();
         
         // create geometry
         var path = new CGPath ();
         path.AddArc (0, 0, 50, 0, (float)Math.PI / 2, false);
         path.CloseSubpath ();
         
         // add geometry to graphics context and draw it
         gctx.AddPath (path);
         gctx.DrawPath (CGPathDrawingMode.FillStroke);
         
         // get a UIImage from the context
         UIImage bananaImage = UIGraphics.GetImageFromCurrentImageContext ();
         
         // clean up
         UIGraphics.EndImageContext ();
         
         // use the UIImage
         iv.Image = bananaImage;
     };
 }
        private CGPath NewBadgePathForTextSize(SizeF size)
        {
            float arcRadius = (float)Math.Ceiling((size.Height + this.Pad) / 2.0f);

            float badgeWidthAdjustment = size.Width - (size.Height / 2.0f);
            float badgeWidth = 2.0f * arcRadius;

            if (badgeWidthAdjustment > 0.0)
            {
                badgeWidth += badgeWidthAdjustment;
            }

            CGPath badgePath = new CGPath();

            var m_pi_2 = (float)(Math.PI / 2);

            badgePath.MoveToPoint(arcRadius, 0.0f);
            badgePath.AddArc(arcRadius, arcRadius, arcRadius, 3.0f * m_pi_2, m_pi_2, true);
            badgePath.AddLineToPoint(badgeWidth - arcRadius, 2.0f * arcRadius);
            badgePath.AddArc(badgeWidth - arcRadius, arcRadius, arcRadius, m_pi_2, 3.0f * m_pi_2, true);
            badgePath.AddLineToPoint(arcRadius, 0.0f);

            return badgePath;
        }
示例#45
0
 private CGPath CGPathCreateArc (CGPoint center, nfloat radius, nfloat startAngle, nfloat endAngle)
 {
     var path = new CGPath ();
     CGPath resultPath;
     if (IsDonut) {
         path.AddArc (center.X, center.Y, radius, startAngle, endAngle, false);
         resultPath = path.CopyByStrokingPath (DonutLineStroke, CGLineCap.Butt, CGLineJoin.Miter, 10);
         path.Dispose ();
     } else {
         path.MoveToPoint (center.X, center.Y);
         path.AddArc (center.X, center.Y, radius, startAngle, endAngle, false);
         path.CloseSubpath ();
         resultPath = path;
     }
     return resultPath;
 }
示例#46
0
		public override void Draw (CGRect rect)
		{
			DirectionArrow dv = (DirectionArrow)Element;

			var bounds = Bounds;

			float width;
			float height;

			width = height = (float)Math.Min(Bounds.Width, Bounds.Height);

			float centerX = width / 2.0f;
			float centerY = height / 2.0f;
			float size = (width * 0.8f) / 2.0f;
			float sizeSmall = size * 0.6f;

			// Draw background circle
			using (var context = UIGraphics.GetCurrentContext ()) {
				context.SetFillColor (dv.CircleColor.ToCGColor ());
				context.SetStrokeColor (dv.CircleColor.ToCGColor ());
				context.SetLineWidth (0.0f);
				// Draw circle
				using (CGPath path = new CGPath ()) {

					// Set colors and line widhts
					context.SetLineWidth (0.0f);
					context.SetStrokeColor (dv.CircleColor.ToCGColor ());
					context.SetFillColor (dv.CircleColor.ToCGColor ());
					// Draw circle
					path.AddArc (centerX, centerY, centerX, 0.0f, (float)Math.PI * 2.0f, true);
					path.CloseSubpath ();
					// Draw path
					context.AddPath (path);
					context.DrawPath (CGPathDrawingMode.FillStroke);

				}
			}

			// Check, if we inside of the zone
			if (double.IsPositiveInfinity(dv.Direction)) {
				// Draw circle, because we are here
				using (var context = UIGraphics.GetCurrentContext ()) {
					context.SetFillColor (dv.ArrowColor.ToCGColor ());
					context.SetStrokeColor (dv.ArrowColor.ToCGColor ());
					context.SetLineWidth (5.0f);
					// Draw circle
					using (CGPath path = new CGPath ()) {
						// Draw circle
						path.AddArc (centerX, centerY, centerX * 0.3f, 0.0f, (float)Math.PI * 2.0f, true);
						path.CloseSubpath ();
						// Draw path
						context.AddPath (path);
						context.DrawPath (CGPathDrawingMode.FillStroke);
					}
				}

				return;
			}

			// Check, if the direction is invalid
			if (double.IsNegativeInfinity(dv.Direction)) {
				// Draw cross, because direction is invalid
				using (var context = UIGraphics.GetCurrentContext()) {
					context.SetFillColor(dv.ArrowColor.ToCGColor());
					context.SetStrokeColor(dv.ArrowColor.ToCGColor());
					context.SetLineWidth(0.1875f * width);
					context.SetLineCap(CGLineCap.Round);
					// Draw circle
					using (CGPath path = new CGPath ()) {
						// Draw cross
						var points = new List<CGPoint>(2);

						points.Add(new CGPoint(centerX - centerX * 0.4f, centerY - centerY * 0.4f));
						points.Add(new CGPoint(centerX + centerX * 0.4f, centerY + centerY * 0.4f));

						path.AddLines(points.ToArray());

						path.CloseSubpath ();
						context.AddPath (path);

						points = new List<CGPoint>(2);

						points.Add(new CGPoint(centerX - centerX * 0.4f, centerY + centerY * 0.4f));
						points.Add(new CGPoint(centerX + centerX * 0.4f, centerY - centerY * 0.4f));

						path.AddLines(points.ToArray());

						path.CloseSubpath ();
						context.AddPath (path);

						context.SetLineCap(CGLineCap.Round);
						context.DrawPath(CGPathDrawingMode.Stroke);
					}
				}

				return;
			}

			// We have a direction, so draw an arrow
			var direction = 180.0 - dv.Direction;
			if (direction < 0)
				direction += 360.0;
			direction = direction % 360.0;

			double rad1 = direction / 180.0 * Math.PI;
			double rad2 = (direction + 180.0 + 30.0) / 180.0 * Math.PI;
			double rad3 = (direction + 180.0 - 30.0) / 180.0 * Math.PI; 
			double rad4 = (direction + 180.0) / 180.0 * Math.PI; 

			CGPoint p1 = new CGPoint((float) (centerX + size * Math.Sin (rad1)), (float) (centerY + size * Math.Cos (rad1)));
			CGPoint p2 = new CGPoint((float) (centerX + size * Math.Sin (rad2)), (float) (centerY + size * Math.Cos (rad2)));
			CGPoint p3 = new CGPoint((float) (centerX + size * Math.Sin (rad3)), (float) (centerY + size * Math.Cos (rad3)));
			CGPoint p4 = new CGPoint((float) (centerX + sizeSmall * Math.Sin (rad4)), (float) (centerY + sizeSmall * Math.Cos (rad4)));

			using (var context = UIGraphics.GetCurrentContext ()) {

				// Draw first half of arrow
				using (CGPath path = new CGPath ()) {

					context.SetLineWidth (0.5f);
					context.SetStrokeColor (dv.ArrowColor.ToCGColor ()); //1f, 0, 0, 1);
					context.SetFillColor (dv.ArrowColor.ToCGColor ());

					path.AddLines (new CGPoint[] { p1, p2, p4 });
					path.CloseSubpath ();

					context.AddPath (path);
					context.DrawPath (CGPathDrawingMode.FillStroke);

				}

				// Draw second half of arrow
				using (CGPath path = new CGPath()) {

					context.SetStrokeColor (dv.ArrowColor.ToCGColor ());
					context.SetFillColor (dv.ArrowColor.ToCGColor ()); // was 0.5f
				
					path.AddLines (new CGPoint[] { p1, p3, p4 });
					path.CloseSubpath ();

					context.AddPath (path);
					context.DrawPath (CGPathDrawingMode.FillStroke);

				}
			}
		}
    public override void ObserveValue (NSString keyPath, NSObject ofObject, NSDictionary change, IntPtr context)
    {
        if (keyPath == "contentInset") {
            if (!_ignoreInset && !_ignoreInsetBlock) {
                OriginalContentInset = ((NSValue) change ["new"]).UIEdgeInsetsValue;

                Frame = (_vertical)
                    ? new RectangleF (0, - (TotalViewHeight + ScrollView.ContentInset.Top), ScrollView.Bounds.Size.Width, TotalViewHeight)
                    : new RectangleF (- (TotalViewHeight + ScrollView.ContentInset.Left), 0, TotalViewHeight, ScrollView.Bounds.Size.Height);
            }
            
            return;
        }
        
        if (!Enabled || _ignoreOffset)
            return;
        
        var newContentOffset = ((NSValue) change ["new"]).PointFValue;
        float offset;
        
        if (_vertical) {
            offset = newContentOffset.Y + OriginalContentInset.Top;
        } else {
            offset = newContentOffset.X + OriginalContentInset.Left;
        }
        
        if (_refreshing) {
            if (offset != 0) {
                // Keep thing pinned at the top
                
                CATransaction.Begin ();
                CATransaction.DisableActions = true;
                
                _shapeLayer.Position = (_vertical)
                    ? new PointF (0, MaxDistance + offset + OpenedViewHeight)
                        : new PointF (MaxDistance + offset + OpenedViewHeight, 0);
                
                CATransaction.Commit ();
                
                if (_vertical) {
                    _activity.Center = new PointF (
                        (float) Math.Floor (Bounds.Width / 2.0f),
                        Math.Min (
                        offset + Bounds.Height + (float) Math.Floor (OpenedViewHeight / 2.0f),
                        Bounds.Height - OpenedViewHeight / 2.0f
                        )
                        );
                } else {
                    _activity.Center = new PointF (
                        Math.Min (
                        offset + Bounds.Width + (float) Math.Floor (OpenedViewHeight / 2.0f),
                        Bounds.Width - OpenedViewHeight / 2.0f
                        ),
                        (float) Math.Floor (Bounds.Height / 2.0f)
                        );
                }
                
                _ignoreInset = true;
                _ignoreOffset = true;
                
                if (offset < 0) {
                    // Set the inset depending on the situation
                    if (offset >= -OpenedViewHeight) {
                        if (!ScrollView.Dragging) {
                            if (!_didSetInset) {
                                _didSetInset = true;
                                _hasSectionHeaders = false;
                                
                                if (ScrollView is UITableView) {
                                    var tableView = (UITableView) ScrollView;
                                    for (var i = 0; i < tableView.NumberOfSections (); i++) {
                                        if (tableView.RectForHeaderInSection (i).Size.Height > 0) {
                                            _hasSectionHeaders = true;
                                            break;
                                        }
                                    }
                                }
                            }
                            
                            if (_hasSectionHeaders) {
                                ScrollView.ContentInset = (_vertical)
                                    ? new UIEdgeInsets (Math.Min (-offset, OpenedViewHeight) + OriginalContentInset.Top, OriginalContentInset.Left, OriginalContentInset.Bottom, OriginalContentInset.Right)
                                    : new UIEdgeInsets (OriginalContentInset.Top, Math.Min (-offset, OpenedViewHeight) + OriginalContentInset.Left, OriginalContentInset.Bottom, OriginalContentInset.Right);
                            } else {
                                ScrollView.ContentInset = (_vertical)
                                    ? new UIEdgeInsets (OpenedViewHeight + OriginalContentInset.Top, OriginalContentInset.Left, OriginalContentInset.Bottom, OriginalContentInset.Right)
                                    : new UIEdgeInsets (OriginalContentInset.Top, OriginalContentInset.Left + OpenedViewHeight, OriginalContentInset.Bottom, OriginalContentInset.Right);
                            }
                        } else if (_didSetInset && _hasSectionHeaders) {
                            ScrollView.ContentInset = (_vertical)
                                ? new UIEdgeInsets (-offset + OriginalContentInset.Top, OriginalContentInset.Left, OriginalContentInset.Bottom, OriginalContentInset.Right)
                                : new UIEdgeInsets (OriginalContentInset.Top, -offset + OriginalContentInset.Left, OriginalContentInset.Bottom, OriginalContentInset.Right);
                        }
                        
                    }
                } else if (_hasSectionHeaders) {
                    ScrollView.ContentInset = OriginalContentInset;
                }
                
                _ignoreInset = false;
                _ignoreOffset = false;
            }
            
            return;
        } else {
            // Check if we can trigger a new refresh and if we can draw the control
            bool dontDraw = false;
            
            if (!_canRefresh) {
                if (offset >= 0) {
                    // We can refresh again after the control is scrolled out of view
                    _canRefresh = true;
                    _didSetInset = false;
                } else {
                    dontDraw = true;
                }
            } else {
                if (offset >= 0) {
                    // Don't draw if the control is not visible
                    dontDraw = true;
                }
            }
            
            if (offset > 0 && _lastOffset > offset && !ScrollView.Tracking) {
                // If we are scrolling too fast, don't draw, and don't trigger unless the scrollView bounced back
                _canRefresh = false;
                dontDraw = true;
            }
            
            if (dontDraw) {
                _shapeLayer.Path = null;
                _shapeLayer.ShadowPath = new CGPath (IntPtr.Zero);
                _arrowLayer.Path = null;
                _highlightLayer.Path = null;
                _lastOffset = offset;
                return;
            }
        }
        
        _lastOffset = offset;
        bool triggered = false;
        
        CGPath path = new CGPath ();
        
        //Calculate some useful points and values
        var verticalShift = Math.Max (0, -((MaxTopRadius + MaxBottomRadius + MaxTopPadding + MaxBottomPadding) + offset));
        var distance = Math.Min (MaxDistance, Math.Abs (verticalShift));
        var percentage = 1 - (distance / MaxDistance);
        
        PointF headOrigin;
        float headRadius;
        
        if (_vertical) {
            float currentTopPadding = lerp (MinTopPadding, MaxTopPadding, percentage);
            float currentTopRadius = lerp (MinTopRadius, MaxTopRadius, percentage);
            float currentBottomRadius = lerp (MinBottomRadius, MaxBottomRadius, percentage);
            float currentBottomPadding = lerp (MinBottomPadding, MaxBottomPadding, percentage);
            
            var bottomOrigin = new PointF ((float) Math.Floor (Bounds.Width / 2.0f), Bounds.Height - currentBottomPadding - currentBottomRadius);
            var topOrigin = PointF.Empty;
            
            if (distance == 0) {
                topOrigin = new PointF ((float) Math.Floor (Bounds.Width / 2.0f), bottomOrigin.Y);
            } else {
                topOrigin = new PointF ((float) Math.Floor (Bounds.Width / 2.0f), Bounds.Height + offset + currentTopPadding + currentTopRadius);
                
                if (percentage == 0) {
                    bottomOrigin.Y -= ((Math.Abs (verticalShift) - MaxDistance));
                    triggered = true;
                }
            }
            
            //Top semicircle
            path.AddArc (topOrigin.X, topOrigin.Y, currentTopRadius, 0, (float) Math.PI, true);
            
            //Left curve
            var leftCp1 = new PointF (lerp ((topOrigin.X - currentTopRadius), (bottomOrigin.X - currentBottomRadius), 0.1f), lerp (topOrigin.Y, bottomOrigin.Y, .2f));
            var leftCp2 = new PointF (lerp ((topOrigin.X - currentTopRadius), (bottomOrigin.X - currentBottomRadius), 0.9f), lerp (topOrigin.Y, bottomOrigin.Y, .2f));
            var leftDestination = new PointF (bottomOrigin.X - currentBottomRadius, bottomOrigin.Y);
            
            path.AddCurveToPoint (leftCp1, leftCp2, leftDestination);
            
            //Bottom semicircle
            path.AddArc (bottomOrigin.X, bottomOrigin.Y, currentBottomRadius, (float) Math.PI, 0, true);
            
            //Right curve
            var rightCp2 = new PointF (lerp ((topOrigin.X + currentTopRadius), (bottomOrigin.X + currentBottomRadius), 0.1f), lerp (topOrigin.Y, bottomOrigin.Y, .2f));
            var rightCp1 = new PointF (lerp ((topOrigin.X + currentTopRadius), (bottomOrigin.X + currentBottomRadius), 0.9f), lerp (topOrigin.Y, bottomOrigin.Y, .2f));
            var rightDestination = new PointF (bottomOrigin.X + currentTopRadius, topOrigin.Y);
            
            path.AddCurveToPoint (rightCp1, rightCp2, rightDestination);
            
            headOrigin = topOrigin;
            headRadius = currentTopRadius;
        } else {
            float currentLeftPadding = lerp (MinTopPadding, MaxTopPadding, percentage);
            float currentLeftRadius = lerp (MinTopRadius, MaxTopRadius, percentage);
            float currentRightRadius = lerp (MinBottomRadius, MaxBottomRadius, percentage);
            float currentRightPadding = lerp (MinBottomPadding, MaxBottomPadding, percentage);
            
            var rightOrigin = new PointF (Bounds.Width - currentRightPadding - currentRightRadius, (float) Math.Floor (Bounds.Height / 2.0f));
            var leftOrigin = PointF.Empty;
            
            if (distance == 0) {
                leftOrigin = new PointF (rightOrigin.X, (float) Math.Floor (Bounds.Size.Height / 2.0f));
            } else {
                leftOrigin = new PointF (Bounds.Size.Width + offset + currentLeftPadding + currentLeftRadius, (float) Math.Floor (Bounds.Height / 2.0f));
                
                if (percentage == 0) {
                    rightOrigin.X -= ((Math.Abs (verticalShift) - MaxDistance));
                    triggered = true;
                }
            }
            
            //Left cemicircle
            path.AddArc (leftOrigin.X, leftOrigin.Y, currentLeftRadius, (float) -Math.PI / 2.0f, (float) Math.PI / 2.0f, true);
            
            // Bottom curve
            var bottomCp1 = new PointF (lerp (leftOrigin.X, rightOrigin.X, .2f), lerp ((leftOrigin.Y + currentLeftRadius), (rightOrigin.Y + currentRightRadius), .1f));
            var bottomCp2 = new PointF (lerp (leftOrigin.X, rightOrigin.X, .2f), lerp ((leftOrigin.Y + currentLeftRadius), (rightOrigin.Y + currentRightRadius), .9f));
            var bottomDestination = new PointF (rightOrigin.X, rightOrigin.Y + currentRightRadius);
            
            path.AddCurveToPoint (bottomCp1, bottomCp2, bottomDestination);
            
            //Right semicircle
            path.AddArc (rightOrigin.X, rightOrigin.Y, currentRightRadius, (float) Math.PI / 2.0f, 3 * (float) Math.PI / 2.0f, true);
            
            //Top curve
            var topCp2 = new PointF (lerp (leftOrigin.X, rightOrigin.X, .2f), lerp ((leftOrigin.Y - currentLeftRadius), (rightOrigin.Y - currentRightRadius), .1f));
            var topCp1 = new PointF (lerp (leftOrigin.X, rightOrigin.X, .2f), lerp ((leftOrigin.Y - currentLeftRadius), (rightOrigin.Y - currentRightRadius), .9f));
            var topDestination = new PointF (leftOrigin.X, leftOrigin.Y - currentLeftRadius);
            
            path.AddCurveToPoint (topCp1, topCp2, topDestination);
            
            headOrigin = leftOrigin;
            headRadius = currentLeftRadius;
        }
        
        path.CloseSubpath ();
        
        if (!triggered) {
            // Set paths
            
            _shapeLayer.Path = path;
            _shapeLayer.ShadowPath = path;
            
            // Add the arrow shape
            
            var currentArrowSize = lerp (MinArrowSize, MaxArrowSize, percentage);
            var currentArrowRadius = lerp (MinArrowRadius, MaxArrowRadius, percentage);
            
            var arrowBigRadius = currentArrowRadius + (currentArrowSize / 2.0f);
            var arrowSmallRadius = currentArrowRadius - (currentArrowSize / 2.0f);
            
            var arrowPath = new CGPath ();
            arrowPath.AddArc (headOrigin.X, headOrigin.Y, arrowBigRadius, 0, 3 * (float) Math.PI / 2.0f, false);
            arrowPath.AddLineToPoint (headOrigin.X, headOrigin.Y - arrowBigRadius - currentArrowSize);
            arrowPath.AddLineToPoint (headOrigin.X + (2 * currentArrowSize), headOrigin.Y - arrowBigRadius + (currentArrowSize / 2.0f));
            arrowPath.AddLineToPoint (headOrigin.X, headOrigin.Y - arrowBigRadius + (2 * currentArrowSize));
            arrowPath.AddLineToPoint (headOrigin.X, headOrigin.Y - arrowBigRadius + currentArrowSize);
            arrowPath.AddArc (headOrigin.X, headOrigin.Y, arrowSmallRadius, 3 * (float) Math.PI / 2.0f, 0, true);
            arrowPath.CloseSubpath ();
            
            _arrowLayer.Path = arrowPath;
            _arrowLayer.FillRule =  CAShapeLayer.FillRuleEvenOdd;
            arrowPath.Dispose ();
            
            // Add the highlight shape
            
            var highlightPath = new CGPath ();
            if (_vertical) {
                highlightPath.AddArc (headOrigin.X, headOrigin.Y, headRadius, 0, (float) Math.PI, true);
                highlightPath.AddArc (headOrigin.X, headOrigin.Y + 1.25f, headRadius, (float) Math.PI, 0, false);
            } else {
                highlightPath.AddArc (headOrigin.X, headOrigin.Y, headRadius, - (float) Math.PI / 2.0f, (float) Math.PI / 2.0f, true);
                highlightPath.AddArc (headOrigin.X + 1.25f, headOrigin.Y, headRadius, (float) Math.PI / 2.0f, - (float) Math.PI / 2.0f, false);
            }
            
            _highlightLayer.Path = highlightPath;
            _highlightLayer.FillRule = CAShapeLayer.FillRuleNonZero;
            highlightPath.Dispose ();
        } else {
            // Start the shape disappearance animation
            var radius = lerp (MinBottomRadius, MaxBottomRadius, .2f);
            var pathMorph = CABasicAnimation.FromKeyPath ("path");
            
            pathMorph.Duration = .15f;
            pathMorph.FillMode = CAFillMode.Forwards;
            pathMorph.RemovedOnCompletion = false;
            
            var toPath = new CGPath ();
            
            if (_vertical) {
                toPath.AddArc (headOrigin.X, headOrigin.Y, radius, 0, (float)Math.PI, true);
                toPath.AddCurveToPoint (headOrigin.X - radius, headOrigin.Y, headOrigin.X - radius, headOrigin.Y, headOrigin.X - radius, headOrigin.Y);
                toPath.AddArc (headOrigin.X, headOrigin.Y, radius, (float) Math.PI, 0, true);
                toPath.AddCurveToPoint (headOrigin.X + radius, headOrigin.Y, headOrigin.X + radius, headOrigin.Y, headOrigin.X + radius, headOrigin.Y);
            } else {
                toPath.AddArc (headOrigin.X, headOrigin.Y, radius, - (float) Math.PI / 2.0f, (float) Math.PI / 2.0f, true);
                toPath.AddCurveToPoint (headOrigin.X, headOrigin.Y + radius, headOrigin.X, headOrigin.Y + radius, headOrigin.X, headOrigin.Y + radius);
                toPath.AddArc (headOrigin.X, headOrigin.Y, radius, (float) Math.PI / 2.0f, - (float) Math.PI / 2.0f, true);
                toPath.AddCurveToPoint (headOrigin.X, headOrigin.Y - radius, headOrigin.X, headOrigin.Y - radius, headOrigin.X, headOrigin.Y - radius);
            }
            
            toPath.CloseSubpath ();
            
            pathMorph.To = new NSValue (toPath.Handle);
            _shapeLayer.AddAnimation (pathMorph, null);
            
            var shadowPathMorph = CABasicAnimation.FromKeyPath ("shadowPath");
            shadowPathMorph.Duration = .15f;
            shadowPathMorph.FillMode = CAFillMode.Forwards;
            shadowPathMorph.RemovedOnCompletion = false;
            shadowPathMorph.To = new NSValue (toPath.Handle);
            
            _shapeLayer.AddAnimation (shadowPathMorph, null);
            toPath.Dispose ();
            
            var shapeAlphaAnimation = CABasicAnimation.FromKeyPath ("opacity");
            shapeAlphaAnimation.Duration = .1f;
            shapeAlphaAnimation.BeginTime = CABasicAnimation.CurrentMediaTime () + .1;
            shapeAlphaAnimation.To = new NSNumber (0);
            shapeAlphaAnimation.FillMode = CAFillMode.Forwards;
            shapeAlphaAnimation.RemovedOnCompletion = false;
            _shapeLayer.AddAnimation (shapeAlphaAnimation, null);
            
            var alphaAnimation = CABasicAnimation.FromKeyPath ("opacity");
            alphaAnimation.Duration = .1f;
            alphaAnimation.To = new NSNumber (0);
            alphaAnimation.FillMode = CAFillMode.Forwards;
            alphaAnimation.RemovedOnCompletion = false;
            
            _arrowLayer.AddAnimation (alphaAnimation, null);
            _highlightLayer.AddAnimation (alphaAnimation, null);
            
            CATransaction.Begin ();
            CATransaction.DisableActions = true;
            _activity.Layer.Transform = CATransform3D.MakeScale (.1f, .1f, 1);
            CATransaction.Commit ();
            
            UIView.Animate (.2f, .15f, UIViewAnimationOptions.CurveLinear, () => {
                _activity.Alpha = 1;
                _activity.Layer.Transform = CATransform3D.MakeScale (1, 1, 1);
            }, null);
            
            _refreshing = true;
            _canRefresh = false;
            
            SendActionForControlEvents (UIControlEvent.ValueChanged);
        }
        
        path.Dispose ();
    }
示例#48
0
 private CGPath CGPathCreateArc (CGPoint center, nfloat radius, nfloat startAngle, nfloat endAngle, nfloat lineStroke)
 {
     var path = new CGPath ();
     path.AddArc (center.X, center.Y, radius, startAngle, endAngle, false);
     return path.CopyByStrokingPath (lineStroke, CGLineCap.Butt, CGLineJoin.Miter, 10);
 }
示例#49
0
 protected virtual CGPath CreateTokenPath(SizeF size, bool innerPath) 
 {
     return Wrap.Function("CreateTokenPath", delegate()
     {
         CGPath path = new CGPath();
         float arcValue = (size.Height / 2) - 1;
         float radius = arcValue - (innerPath ? (1 / UIScreen.MainScreen.Scale) : 0);
         path.AddArc(arcValue, arcValue, radius, (float)(Math.PI / 2f), (float)(Math.PI * 3 / 2f), false);
         path.AddArc(size.Width - arcValue, arcValue, radius, (float)(Math.PI * 3 / 2), (float)(Math.PI / 2), false);
         path.CloseSubpath();
         return path;
     });
 }
        public override void ObserveValue(NSString keyPath, NSObject ofObject, NSDictionary change, IntPtr context)
        {
            //base.ObserveValue(keyPath, ofObject, change, context);
            if (keyPath.ToString().ToLower() == "contentInset".ToLower())
            {
                if (!_ignoreInset)
                {
                    this.originalContentInset = (change["new"] as NSValue).UIEdgeInsetsValue;
                    this.Frame = new RectangleF(0, -1 * (kTotalViewHeight + this.scrollView.ContentInset.Top), this.scrollView.Frame.Size.Width, kTotalViewHeight);
                }
                return;
            }

            if (!this.Enabled || this._ignoreOffset)
                return;

            float offset = (change["new"] as NSValue).PointFValue.Y + this.originalContentInset.Top;

            if (_refreshing)
            {
                if (offset != 0)
                {
                    // keep thing pinned at the top
                    CATransaction.Begin();
                    CATransaction.SetValueForKey(NSNumber.FromBoolean(true), CATransaction.DisableActionsKey);
                    _shapeLayer.Position = new PointF(0, kMaxDistance + offset + kOpenedViewHeight);
                    CATransaction.Commit();

                    this.activity.Center = new PointF((float)Math.Floor(this.Frame.Size.Width / 2), (float)Math.Min(offset + this.Frame.Size.Height + Math.Floor(kOpenedViewHeight / 2), this.Frame.Size.Height - kOpenedViewHeight / 2));

                    _ignoreInset = true;
                    _ignoreOffset = true;

                    if (offset < 0)
                    {
                        // set the inset depending on the situation
                        if (offset >= kOpenedViewHeight * -1)
                        {
                            if (!this.scrollView.Dragging)
                            {
                                if (!_didSetInset)
                                {
                                    _didSetInset = true;
                                    _hasSectionHeaders = false;
                                    if (this.scrollView is UITableView)
                                    {
                                        for (int i = 0; i < (this.scrollView as UITableView).NumberOfSections(); ++i)
                                        {
                                            if ((this.scrollView as UITableView).RectForHeaderInSection(i).Size.Height != 0)
                                            {
                                                _hasSectionHeaders = true;
                                                break;
                                            }
                                        }
                                    }
                                }
                                if (_hasSectionHeaders)
                                    this.scrollView.ContentInset = new UIEdgeInsets(Math.Min(offset * -1, kOpenedViewHeight) + this.originalContentInset.Top, this.originalContentInset.Left, this.originalContentInset.Bottom, this.originalContentInset.Right);
                                else
                                    this.scrollView.ContentInset = new UIEdgeInsets(kOpenedViewHeight + this.originalContentInset.Top, this.originalContentInset.Left, this.originalContentInset.Bottom, this.originalContentInset.Right);
                            }
                            else if(_didSetInset && _hasSectionHeaders)
                            {
                                this.scrollView.ContentInset = new UIEdgeInsets(-1 * offset + this.originalContentInset.Top, this.originalContentInset.Left, this.originalContentInset.Bottom, this.originalContentInset.Right);
                            }
                        }
                    }
                    else if (_hasSectionHeaders)
                    {
                        this.scrollView.ContentInset = this.originalContentInset;
                    }
                    _ignoreInset = false;
                    _ignoreOffset = false;
                }
                return;
            }
            else
            {
                // check if we can trigger a new refresh and if we can draw the control
                bool dontDraw = false;  // line 230
                if (!_canRefresh)
                {
                    if (offset >= 0)
                    {
                        // we can refresh again after the control is scrolled out of view
                        _canRefresh = true;
                        _didSetInset = false;
                    }
                    else
                    {
                        dontDraw = true;
                    }
                }
                else
                {
                    if (offset >= 0)
                    {
                        // don't draw if the control is not visible
                        dontDraw = true;
                    }
                }
                if (offset > 0 && _lastOffset > offset  && !this.scrollView.Tracking)
                {
                    // if we are scrolling too fast, don't draw, and don't trigger unless the scrollView bounced back

                    // removed behavior Heath
                    //_canRefresh = false;
                    //dontDraw = true;
                }
                if (dontDraw)
                {
                    _shapeLayer.Path = null;
                    _shapeLayer.ShadowPath = new CGPath(IntPtr.Zero);
                    _arrowLayer.Path = null;
                    _highlightLayer.Path = null;
                    _lastOffset = offset;
                    return;
                }
            }

            _lastOffset = offset;  // line 260

            bool triggered = false;

            CGPath path = new CGPath();

            // calculate some useful points and values
            float verticalShift = (float)Math.Max(0, -1 * ((kMaxTopRadius + kMaxBottomRadius + kMaxTopPadding + kMaxBottomPadding) + offset));
            float distance = (float)Math.Min(kMaxDistance, (float)Math.Abs(verticalShift));
            float percentage = 1 - (distance / kMaxDistance);

            float currentTopPadding = lerp(kMinTopPadding, kMaxTopPadding, percentage);
            float currentTopRadius = lerp(kMinTopRadius, kMaxTopRadius, percentage);
            float currentBottomRadius = lerp(kMinBottomRadius, kMaxBottomRadius, percentage);
            float currentBottomPadding = lerp(kMinBottomPadding, kMaxBottomPadding, percentage);

            PointF bottomOrigin = new PointF((float)Math.Floor(this.Bounds.Size.Width / 2), this.Bounds.Size.Height - currentBottomPadding - currentBottomRadius);
            PointF topOrigin = PointF.Empty;
            if (distance == 0)
            {
                topOrigin = new PointF((float)Math.Floor(this.Bounds.Size.Width / 2), bottomOrigin.Y);
            }
            else
            {
                topOrigin = new PointF((float)Math.Floor(this.Bounds.Size.Width / 2), this.Bounds.Size.Height + offset + currentTopPadding + currentTopRadius);
                if (percentage == 0)
                {
                    bottomOrigin.Y -= (float)Math.Abs(verticalShift) - kMaxDistance;
                    triggered = true;
                }
            }

            // top semicircle
            path.AddArc(topOrigin.X, topOrigin.Y, currentTopRadius, 0, (float)Math.PI, true);

            // left curve
            PointF leftCp1 = new PointF(lerp((topOrigin.X - currentTopRadius), (bottomOrigin.X - currentBottomRadius), 0.1f), lerp(topOrigin.Y, bottomOrigin.Y, 0.2f));
            PointF leftCp2 = new PointF(lerp((topOrigin.X - currentTopRadius), (bottomOrigin.X - currentBottomRadius), 0.9f), lerp(topOrigin.Y, bottomOrigin.Y, 0.2f));
            PointF leftDestination = new PointF(bottomOrigin.X - currentBottomRadius, bottomOrigin.Y);

            path.AddCurveToPoint(leftCp1, leftCp2, leftDestination);

            // bottom semicircle
            path.AddArc(bottomOrigin.X, bottomOrigin.Y, currentBottomRadius, (float)Math.PI, 0, true);

            // right curve
            PointF rightCp2 = new PointF(lerp((topOrigin.X + currentTopRadius), (bottomOrigin.X + currentBottomRadius), 0.1f), lerp(topOrigin.Y, bottomOrigin.Y, 0.2f));
            PointF rightCp1 = new PointF(lerp((topOrigin.X + currentTopRadius), (bottomOrigin.X + currentBottomRadius), 0.9f), lerp(topOrigin.Y, bottomOrigin.Y, 0.2f));
            PointF rightDestination = new PointF(bottomOrigin.X + currentTopRadius, topOrigin.Y);

            path.AddCurveToPoint (rightCp1, rightCp2, rightDestination);
            path.CloseSubpath();

            if (!triggered) // line 309
            {
                // set paths
                _shapeLayer.Path = path;
                _shapeLayer.ShadowPath = path;

                // add the arrow shape
                float currentArrowSize = lerp(kMinArrowSize, kMaxArrowSize, percentage);
                float currentArrowRadius = lerp(kMinArrowRadius, kMaxArrowRadius, percentage);
                float arrowBigRadius = currentArrowRadius + (currentArrowSize / 2);
                float arrowSmallRadius = currentArrowRadius - (currentArrowSize / 2);
                CGPath arrowPath = new CGPath();
                /*
                arrowPath.AddArc(topOrigin.X, topOrigin.Y, arrowBigRadius, 0, 3 * (float)Math.PI, false);
                arrowPath.AddLineToPoint(topOrigin.X, topOrigin.Y - arrowBigRadius - currentArrowSize);
                arrowPath.AddLineToPoint(topOrigin.X + (2 * currentArrowSize), topOrigin.Y - arrowBigRadius + (currentArrowSize / 2));
                arrowPath.AddLineToPoint(topOrigin.X, topOrigin.Y - arrowBigRadius + (2 * currentArrowSize));
                arrowPath.AddLineToPoint(topOrigin.X, topOrigin.Y - arrowBigRadius + currentArrowSize);
                arrowPath.AddArc(topOrigin.X, topOrigin.Y, arrowSmallRadius, 3 * (float)Math.PI, 0, true);
                */
                arrowPath.AddArc (topOrigin.X, topOrigin.Y, arrowBigRadius, 0, 3 * (float) Math.PI / 2.0f, false);
                arrowPath.AddLineToPoint (topOrigin.X, topOrigin.Y - arrowBigRadius - currentArrowSize);
                arrowPath.AddLineToPoint (topOrigin.X + (2 * currentArrowSize), topOrigin.Y - arrowBigRadius + (currentArrowSize / 2.0f));
                arrowPath.AddLineToPoint (topOrigin.X, topOrigin.Y - arrowBigRadius + (2 * currentArrowSize));
                arrowPath.AddLineToPoint (topOrigin.X, topOrigin.Y - arrowBigRadius + currentArrowSize);
                arrowPath.AddArc (topOrigin.X, topOrigin.Y, arrowSmallRadius, 3 * (float) Math.PI / 2.0f, 0, true);

                arrowPath.CloseSubpath();
                _arrowLayer.Path = arrowPath;
                _arrowLayer.FillRule = CAShapeLayer.FillRuleEvenOdd;
                arrowPath.Dispose();

                // add the highlight shape
                CGPath highlightPath = new CGPath();
                highlightPath.AddArc(topOrigin.X, topOrigin.Y, currentTopRadius, 0, (float)Math.PI, true);
                highlightPath.AddArc(topOrigin.X, topOrigin.Y + 1.25f, currentTopRadius, (float)Math.PI, 0, false);

                _highlightLayer.Path = highlightPath;
                _highlightLayer.FillRule = CAShapeLayer.FillRuleNonZero;
                highlightPath.Dispose();
            }
            else
            {
                // start the shape disappearance animation
                float radius = lerp(kMinBottomRadius, kMaxBottomRadius, 0.2f);
                CABasicAnimation pathMorph = CABasicAnimation.FromKeyPath("path");
                pathMorph.Duration = 0.15f;
                pathMorph.FillMode = CAFillMode.Forwards;
                pathMorph.RemovedOnCompletion = false;

                CGPath toPath = new CGPath();
                toPath.AddArc(topOrigin.X, topOrigin.Y, radius, 0, (float)Math.PI, true);
                toPath.AddCurveToPoint(topOrigin.X - radius, topOrigin.Y, topOrigin.X - radius, topOrigin.Y, topOrigin.X - radius, topOrigin.Y);
                toPath.AddArc(topOrigin.X, topOrigin.Y, radius, (float)Math.PI, 0, true);
                toPath.AddCurveToPoint(topOrigin.X + radius, topOrigin.Y, topOrigin.X + radius, topOrigin.Y, topOrigin.X + radius, topOrigin.Y);
                toPath.CloseSubpath();

                pathMorph.To = new NSValue(toPath.Handle);
                _shapeLayer.AddAnimation(pathMorph, null);

                CABasicAnimation shadowPathMorph = CABasicAnimation.FromKeyPath("shadowPath");
                shadowPathMorph.Duration = 0.15f;
                shadowPathMorph.FillMode = CAFillMode.Forwards;
                shadowPathMorph.RemovedOnCompletion = false;
                shadowPathMorph.To = new NSValue(toPath.Handle);

                _shapeLayer.AddAnimation(shadowPathMorph, null);
                toPath.Dispose();

                CABasicAnimation shapeAlphaAnimation = CABasicAnimation.FromKeyPath("opacity");
                shapeAlphaAnimation.Duration = 0.1f;
                shapeAlphaAnimation.BeginTime = CAAnimation.CurrentMediaTime() + 0.1f;
                shapeAlphaAnimation.To = new NSNumber(0);
                shapeAlphaAnimation.FillMode = CAFillMode.Forwards;
                shapeAlphaAnimation.RemovedOnCompletion = false;
                _shapeLayer.AddAnimation(shapeAlphaAnimation, null);

                CABasicAnimation alphaAnimation = CABasicAnimation.FromKeyPath("opacity");
                alphaAnimation.Duration = 0.1f;
                alphaAnimation.To = new NSNumber (0);
                alphaAnimation.FillMode = CAFillMode.Forwards;
                alphaAnimation.RemovedOnCompletion = false;

                _arrowLayer.AddAnimation(alphaAnimation, null);
                _highlightLayer.AddAnimation(alphaAnimation, null);

                CATransaction.Begin();
                CATransaction.DisableActions = true;
                activity.Layer.Transform = CATransform3D.MakeScale(0.1f, 0.1f, 1f);
                CATransaction.Commit();

                UIView.Animate (0.2f, 0.15f, UIViewAnimationOptions.CurveLinear, () => {
                    activity.Alpha = 1;
                    activity.Layer.Transform = CATransform3D.MakeScale(1, 1, 1);
                }, null);

                _refreshing = true;
                _canRefresh = false;
                this.SendActionForControlEvents(UIControlEvent.ValueChanged);

                if (this.Action != null)
                    this.Action();
            }
            path.Dispose();
        }
示例#51
0
		public override void Draw (RectangleF rect)
		{
			//base.Draw (rect);
			
			float radius = 7.0f;
			float stroke = 1.0f;
						
			var context = UIGraphics.GetCurrentContext ();
			
			rect.Size.Width -= stroke + 14f;
			rect.Size.Height -= stroke + CalloutMapAnnotationViewHeightAboveParent
				- offsetFromParent.Y + CalloutMapAnnotationViewBottomShadowBufferSize;
			
			rect.Location.X += stroke / 2.0f + 7.0f;
			rect.Location.Y += stroke / 2.0f;
			
			SizeF size = new SizeF(rect.Size);
			size.Height -= 8;			

			var path = new CGPath ();
			path.MoveToPoint (rect.Location.X, rect.Location.Y + radius);
			path.AddLineToPoint(rect.Location.X, rect.Location.Y + size.Height - radius);									
			
			path.AddArc (rect.Location.X + radius, rect.Location.Y + size.Height - radius, 
			                    radius, (float)Math.PI, (float)Math.PI / 2.0f, true);
			/*
			 * 
			 * 
			 * 
			 */
			 
			path.AddArc(rect.Location.X + rect.Size.Width - radius, rect.Location.Y + size.Height - radius,
			            radius, (float)Math.PI / 2.0f, 0.0f, true);
						
			path.AddLineToPoint(rect.Location.X + size.Width, rect.Location.Y + radius);			
			path.AddArc(rect.Location.X + size.Width - radius, rect.Location.Y + radius,
			            radius, 0.0f, - (float)Math.PI / 2.0f, true);					
			
			path.AddLineToPoint(rect.Location.X + radius, rect.Location.Y);			
			
			path.AddArc(rect.Location.X + radius, rect.Location.Y + radius, radius,
			            - (float)Math.PI / 2.0f, (float)Math.PI, true);
			
			path.CloseSubpath ();
			
			float red, green, blue, alpha;
			UIColor.Black.GetRGBA(out red, out green, out blue, out alpha);
			UIColor color = UIColor.FromRGBA(red, green, blue, .6f);
			color.SetFill();
						
			var bounds = Bounds;
			var b = new SizeF(16, 8);
			context.MoveTo ((bounds.Width - b.Width) / 2 - 8, bounds.Height - 2 - b.Height);
			context.AddLineToPoint (bounds.Width/2 - 8, bounds.Height - 2);
			context.AddLineToPoint ((bounds.Width + b.Width) / 2 - 8, bounds.Height - b.Height - 2);
			context.ClosePath ();			
			
			context.AddPath(path);
			context.SaveState();
			context.SetShadowWithColor (new SizeF (0, yShadowOffset), 6, UIColor.FromWhiteAlpha(0.0f, 0.5f).CGColor);
			context.FillPath();
			context.RestoreState();					
			
			if (Annotation is CalloutMapAnnotation)
			{
				var annotation = (Annotation as CalloutMapAnnotation);
				blocks = new List<Block>();
				GetSize(annotation, blocks, bounds);
				
				foreach (Block block in blocks)
				{
					if (block.Type == BlockType.Text)
					{
						block.TextColor.SetColor();
						if (block.LineBreakMode.HasValue)
							DrawString (block.Value, block.Bounds, block.Font, block.LineBreakMode.Value, UITextAlignment.Left);
						else
							DrawString (block.Value, block.Bounds, block.Font);
					}
				}
			}			
		}
        private void StartAnimatingTransaction()
        {
            CATransaction.Begin();

            float M_PI_2 = ((float) (Math.PI)) / 2.0f;

            CGAffineTransform tnull = CGAffineTransform.MakeIdentity ();

            CGPath circlePath = new CGPath ();
            circlePath.MoveToPoint(tnull,Frame.Width/2.0f,Frame.Height-circleSize/2.0f);
            circlePath.AddArc(tnull,Frame.Width/2.0f,Frame.Height/2.0f,radius-15/2,M_PI_2, -M_PI_2*3,false);

            for (int i = 0; i < Layer.Sublayers.Length; i++)
            {
                CALayer circleLayer = Layer.Sublayers[i];

                CAKeyFrameAnimation circleAnimation = CAKeyFrameAnimation.GetFromKeyPath ("position");
                circleAnimation.BeginTime = CAAnimation.CurrentMediaTime() + 0.2f*i;
                circleAnimation.Duration = 1.5;
                circleAnimation.TimingFunction = CAMediaTimingFunction.FromControlPoints (0.15f, 0.60f, 0.85f, 0.4f);
                circleAnimation.CalculationMode = CAKeyFrameAnimation.AnimationPaced;
                circleAnimation.Path = circlePath;
                circleAnimation.RepeatCount = float.MaxValue;
                if (circleLayer == this.Layer.Sublayers[Layer.Sublayers.Length-1])
                {
                    circleAnimation.WeakDelegate = this;
                }
                circleLayer.AddAnimation (circleAnimation, "circleAnimation");
            }
            //CGPathRelease(circlePath);

            CATransaction.Commit();
        }
示例#53
0
            private void DrawRect(CGContext g, CGRect rect, Thickness borderThickness, Brush borderBrush, Brush fill, CornerRadius cornerRadius)
            {
                var center = new CGPoint(rect.Left + cornerRadius.TopLeft + borderThickness.Left / 2, rect.Top + cornerRadius.TopLeft + borderThickness.Top / 2);
                var strokeColor = borderBrush != null ? borderBrush.ToUIColor(rect.Size).CGColor : UIColor.Black.CGColor;
                g.SetStrokeColor(strokeColor);
                g.SetFillColor(strokeColor);
                List<Arc> innerArcs = new List<Arc>();
                if (cornerRadius.TopLeft != 0)
                {
                    innerArcs.Add(this.DrawArc(g, cornerRadius.TopLeft, center, borderThickness.LeftF(), borderThickness.TopF(), 180f, 270f));
                }
                else
                {
                    innerArcs.Add(new Arc() { Center = center });
                }
                g.BeginPath();
                g.SetLineWidth(borderThickness.TopF());
                g.MoveTo((nfloat)cornerRadius.TopLeft, borderThickness.TopF() / 2);
                g.AddLineToPoint(rect.Right - (nfloat)cornerRadius.TopRight - borderThickness.RightF() / 2, borderThickness.TopF() / 2);
                g.StrokePath();
                center = new CGPoint(rect.Right - cornerRadius.TopRight - borderThickness.Right / 2, rect.Top + cornerRadius.TopRight + borderThickness.Top / 2);
                if (cornerRadius.TopRight != 0)
                {
                    innerArcs.Add(this.DrawArc(g, cornerRadius.TopRight, center, borderThickness.TopF(), borderThickness.RightF(), -90f, 0f));
                }
                else
                {
                    innerArcs.Add(new Arc { Center = center });
                }
                g.BeginPath();
                g.SetLineWidth(borderThickness.RightF());
                g.MoveTo(rect.Right - borderThickness.RightF() / 2, (nfloat)cornerRadius.TopRight);
                g.AddLineToPoint(rect.Right - borderThickness.RightF() / 2, rect.Height - (nfloat)cornerRadius.BottomRight);
                g.StrokePath();
                center = new CGPoint(rect.Right - cornerRadius.BottomRight - borderThickness.Right / 2, rect.Bottom - cornerRadius.BottomRight - borderThickness.Bottom / 2);
                if (cornerRadius.BottomRight != 0)
                {
                    innerArcs.Add(this.DrawArc(g, cornerRadius.BottomRight, center, borderThickness.RightF(), borderThickness.BottomF(), 0f, 90f));
                }
                else
                {
                    innerArcs.Add(new Arc() { Center = center });
                }
                g.BeginPath();
                g.SetLineWidth(borderThickness.BottomF());
                g.MoveTo(rect.Right - (nfloat)cornerRadius.BottomRight, rect.Bottom - borderThickness.BottomF() / 2);
                g.AddLineToPoint(rect.Left + (nfloat)cornerRadius.BottomLeft, rect.Bottom - borderThickness.BottomF() / 2);
                g.StrokePath();
                center = new CGPoint((rect.Left + cornerRadius.BottomLeft + borderThickness.Left / 2), (rect.Bottom - cornerRadius.BottomLeft - borderThickness.Bottom / 2));
                if (cornerRadius.BottomLeft != 0)
                {
                    innerArcs.Add(this.DrawArc(g, cornerRadius.BottomLeft, center, borderThickness.BottomF(), borderThickness.LeftF(), 90f, 180f));
                }
                else
                {
                    innerArcs.Add(new Arc() { Center = center });
                }
                g.SetLineWidth((nfloat)borderThickness.Left);
                g.MoveTo(rect.Left + borderThickness.LeftF() / 2, rect.Bottom - (nfloat)cornerRadius.BottomLeft);
                g.AddLineToPoint(rect.Left + borderThickness.LeftF() / 2, rect.Top + (nfloat)cornerRadius.TopLeft);
                g.StrokePath();
                if (fill != null)
                {
                    var fillColor = fill.ToUIColor(rect.Size).CGColor;
                    g.SetFillColor(fillColor);
                    g.SetLineWidth(0);
                    using (CGPath path = new CGPath())
                    {
                        path.AddArc(
                            innerArcs[0].Center.X,
                            innerArcs[0].Center.Y,
                            innerArcs[0].Radius,
                            innerArcs[0].EndingAngle,
                            innerArcs[0].StartingAngle,
                            false);

                        path.AddArc(
                            innerArcs[1].Center.X,
                            innerArcs[1].Center.Y,
                            innerArcs[1].Radius,
                            innerArcs[1].EndingAngle,
                            innerArcs[1].StartingAngle,
                            false);

                        path.AddArc(
                            innerArcs[2].Center.X,
                            innerArcs[2].Center.Y,
                            innerArcs[2].Radius,
                            innerArcs[2].EndingAngle,
                            innerArcs[2].StartingAngle,
                            false);

                        path.AddArc(
                            innerArcs[3].Center.X,
                            innerArcs[3].Center.Y,
                            innerArcs[3].Radius,
                            innerArcs[3].EndingAngle,
                            innerArcs[3].StartingAngle,
                            false);

                        g.AddPath(path);
                        g.DrawPath(CGPathDrawingMode.Fill);
                    }
                }
            }
示例#54
0
            private Arc DrawArc(CGContext context, double radius, CGPoint center, nfloat startingThickness, nfloat endingThickness, nfloat startingAngle, nfloat endingAngle)
            {
                using (CGPath path = new CGPath())
                {
                    context.SetLineWidth(0);
                    var deltaAngle = MathF.Abs(endingAngle - startingAngle);

                    // projectedEndingThickness is the ending thickness we would have if the two arcs
                    // subtended an angle of 180 degrees at their respective centers instead of deltaAngle
                    var projectedEndingThickness = startingThickness + (endingThickness - startingThickness) * (180.0f / deltaAngle);

                    var centerOffset = (projectedEndingThickness - startingThickness) / 4.0f;
                    var centerForInnerArc = new CGPoint(center.X + centerOffset * Math.Cos(startingAngle * Math.PI / 180.0f),
                        center.Y + centerOffset * Math.Sin(startingAngle * Math.PI / 180.0f));
                    var centerForOuterArc = new CGPoint(center.X - centerOffset * Math.Cos(startingAngle * Math.PI / 180.0f),
                        center.Y - centerOffset * Math.Sin(startingAngle * Math.PI / 180.0f));

                    var radiusForInnerArc = (nfloat)radius - (startingThickness + projectedEndingThickness) / 4;
                    var radiusForOuterArc = (nfloat)radius + (startingThickness + projectedEndingThickness) / 4;

                    path.AddArc(
                        centerForInnerArc.X,
                        centerForInnerArc.Y,
                        radiusForInnerArc,
                        endingAngle * MathF.PI / 180.0f,
                        startingAngle * MathF.PI / 180.0f,
                        true);

                    var arc = new Arc()
                    {
                        Center = centerForInnerArc,
                        Radius = radiusForInnerArc,
                        StartingAngle = endingAngle * MathF.PI / 180.0f,
                        EndingAngle = startingAngle * MathF.PI / 180.0f
                    };

                    path.AddArc(
                        centerForOuterArc.X,
                        centerForOuterArc.Y,
                        radiusForOuterArc,
                        startingAngle * MathF.PI / 180.0f,
                        endingAngle * MathF.PI / 180.0f,
                        false);

                    context.AddPath(path);

                    context.FillPath();

                    return arc;
                }
            }