Beispiel #1
0
        private void DrawBackground()
        {
            var layerName = "backgroundLayer";

            // Remove previous background layer if any
            var prevBackgroundLayer = _actualView.Layer.Sublayers?.FirstOrDefault(x => x.Name == layerName);

            prevBackgroundLayer?.RemoveFromSuperLayer();

            NSBezierPath cornerPath = null;

            if (Element.Sides != 4)
            {
                cornerPath = Bounds.CreatePolygonPath(Element.Sides, Element.CornerRadius.TopLeft, Element.OffsetAngle);
            }
            else
            {
                cornerPath = Bounds.CreateRoundedRectPath(Element.CornerRadius);
            }

            // The layer used to mask other layers we draw on the background.
            var maskLayer = new CAShapeLayer
            {
                Frame = Bounds,
                Path  = cornerPath.ToCGPath()
            };

            _actualView.Layer.Mask          = maskLayer;
            _actualView.Layer.MasksToBounds = true;

            if (Element.BackgroundGradientStops != null && Element.BackgroundGradientStops.Any())
            {
                // Create a gradient layer that draws our background.
                var gradientLayer = CreateGradientLayer(Element.BackgroundGradientStartPoint, Element.BackgroundGradientEndPoint, Bounds);
                gradientLayer.Name = layerName;

                // A range of colors is given. Let's add them.
                var orderedStops = Element.BackgroundGradientStops.OrderBy(x => x.Offset).ToList();
                gradientLayer.Colors    = orderedStops.Select(x => x.Color.ToCGColor()).ToArray();
                gradientLayer.Locations = orderedStops.Select(x => new NSNumber(x.Offset)).ToArray();

                AddLayer(gradientLayer, 0, _actualView);
            }
            else
            {
                // Create a shape layer that draws our background.
                var shapeLayer = new CAShapeLayer
                {
                    Frame         = Bounds,
                    Path          = cornerPath.ToCGPath(),
                    MasksToBounds = true,
                    FillColor     = _colorToRender.CGColor,
                    Name          = layerName
                };

                AddLayer(shapeLayer, 0, _actualView);
            }
        }
Beispiel #2
0
        CGPath?GetRoundedPath(CGRect rect, nfloat left, nfloat top, nfloat right, nfloat bottom)
        {
#if __IOS__
            var path = new UIBezierPath();
#else
            var path = new NSBezierPath();
#endif
            path.MoveTo(new CGPoint(rect.Width - right, rect.Y));

            path.AddArc(new CGPoint((float)rect.X + rect.Width - right, (float)rect.Y + right), (nfloat)right, (float)(Math.PI * 1.5), (float)Math.PI * 2, true);
            path.AddLineTo(new CGPoint(rect.Width, rect.Height - bottom));

            path.AddArc(new CGPoint((float)rect.X + rect.Width - bottom, (float)rect.Y + rect.Height - bottom), (nfloat)bottom, 0, (float)(Math.PI * .5), true);
            path.AddLineTo(new CGPoint(left, rect.Height));

            path.AddArc(new CGPoint((float)rect.X + left, (float)rect.Y + rect.Height - left), (nfloat)left, (float)(Math.PI * .5), (float)Math.PI, true);
            path.AddLineTo(new CGPoint(rect.X, top));

            path.AddArc(new CGPoint((float)rect.X + top, (float)rect.Y + top), (nfloat)top, (float)Math.PI, (float)(Math.PI * 1.5), true);

            path.ClosePath();

#if __IOS__
            return(path.CGPath);
#else
            return(path.ToCGPath());
#endif
        }
Beispiel #3
0
        public static CAShapeLayer ToShape(this LinePath element)
        {
            var line = new CAShapeLayer();

            var bezierPath = new NSBezierPath();

            bezierPath.MoveTo(new CGPoint(element.X1, element.Y1));
            bezierPath.LineTo(new CGPoint(element.X2, element.Y2));
            line.Path = bezierPath.ToCGPath();

            if (!string.IsNullOrEmpty(element.Stroke))
            {
                line.StrokeColor = XExtensions.ConvertToNSColor(element.Stroke).CGColor;
            }

            if (!string.IsNullOrEmpty(element.Fill))
            {
                line.FillColor = XExtensions.ConvertToNSColor(element.Fill).CGColor;
            }

            line.LineWidth = element.StrokeWidth;

            var width  = Math.Max(element.X1, element.X2) - Math.Min(element.X1, element.X2);
            var height = Math.Max(element.Y1, element.Y2) - Math.Min(element.Y1, element.Y2);

            line.Bounds = new CGRect(0, 0, width, height);

            return(line);
        }
Beispiel #4
0
        public override void UpdateLayer()
        {
            Layer.BackgroundColor = NSColor.FromRgb(245, 245, 245).CGColor;

            if (arrowLayers != null)
            {
                arrowLayers.ForEach(layer => layer.RemoveFromSuperLayer());
            }

            arrowLayers = new List <CAShapeLayer> ();

            nfloat lastX    = 8;
            var    lastItem = items [items.Count - 1];

            foreach (var item in items)
            {
                item.Layer.Position = new CGPoint(lastX, Bounds.GetMidY() - 1);
                lastX += item.Layer.Frame.Width + 20;

                if (item.Equals(lastItem))
                {
                    continue;
                }

                var arrow = new CAShapeLayer();
                var path  = new NSBezierPath();
                path.MoveTo(new CGPoint(item.Layer.Frame.Right + 5, Bounds.Height));
                path.LineTo(new CGPoint(item.Layer.Frame.Right + 15, Bounds.GetMidY()));
                path.LineTo(new CGPoint(item.Layer.Frame.Right + 5, 0));

                arrow.ContentsScale = NSScreen.MainScreen.BackingScaleFactor;
                arrow.Path          = path.ToCGPath(false);
                arrow.FillColor     = null;
                arrow.StrokeColor   = NSColor.FromWhite(0.85f, 1.0f).CGColor;

                arrowLayers.Add(arrow);
                Layer.AddSublayer(arrow);
            }
        }
        public static NSImage ToTransformedCorners(NSImage source, double topLeftCornerSize, double topRightCornerSize, double bottomLeftCornerSize, double bottomRightCornerSize,
                                                   CornerTransformType cornersTransformType, double cropWidthRatio, double cropHeightRatio)
        {
            double sourceWidth  = source.CGImage.Width;
            double sourceHeight = source.CGImage.Height;

            double desiredWidth  = sourceWidth;
            double desiredHeight = sourceHeight;

            double desiredRatio = cropWidthRatio / cropHeightRatio;
            double currentRatio = sourceWidth / sourceHeight;

            if (currentRatio > desiredRatio)
            {
                desiredWidth = (cropWidthRatio * sourceHeight / cropHeightRatio);
            }
            else if (currentRatio < desiredRatio)
            {
                desiredHeight = (cropHeightRatio * sourceWidth / cropWidthRatio);
            }

            topLeftCornerSize     = topLeftCornerSize * (desiredWidth + desiredHeight) / 2 / 100;
            topRightCornerSize    = topRightCornerSize * (desiredWidth + desiredHeight) / 2 / 100;
            bottomLeftCornerSize  = bottomLeftCornerSize * (desiredWidth + desiredHeight) / 2 / 100;
            bottomRightCornerSize = bottomRightCornerSize * (desiredWidth + desiredHeight) / 2 / 100;

            float cropX = (float)((sourceWidth - desiredWidth) / 2);
            float cropY = (float)((sourceHeight - desiredHeight) / 2);

            var       colorSpace       = CGColorSpace.CreateDeviceRGB();
            const int bytesPerPixel    = 4;
            int       width            = (int)desiredWidth;
            int       height           = (int)desiredHeight;
            var       bytes            = new byte[width * height * bytesPerPixel];
            int       bytesPerRow      = bytesPerPixel * width;
            const int bitsPerComponent = 8;

            using (var context = new CGBitmapContext(bytes, width, height, bitsPerComponent, bytesPerRow, colorSpace, CGBitmapFlags.PremultipliedLast | CGBitmapFlags.ByteOrder32Big))
            {
                context.BeginPath();

                using (var path = new NSBezierPath())
                {
                    // TopLeft
                    if (cornersTransformType.HasFlag(CornerTransformType.TopLeftCut))
                    {
                        path.MoveTo(new CGPoint(0, topLeftCornerSize));
                        path.LineTo(new CGPoint(topLeftCornerSize, 0));
                    }
                    else if (cornersTransformType.HasFlag(CornerTransformType.TopLeftRounded))
                    {
                        path.MoveTo(new CGPoint(0, topLeftCornerSize));
                        path.QuadCurveToPoint(new CGPoint(topLeftCornerSize, 0), new CGPoint(0, 0));
                    }
                    else
                    {
                        path.MoveTo(new CGPoint(0, 0));
                    }

                    // TopRight
                    if (cornersTransformType.HasFlag(CornerTransformType.TopRightCut))
                    {
                        path.LineTo(new CGPoint(desiredWidth - topRightCornerSize, 0));
                        path.LineTo(new CGPoint(desiredWidth, topRightCornerSize));
                    }
                    else if (cornersTransformType.HasFlag(CornerTransformType.TopRightRounded))
                    {
                        path.LineTo(new CGPoint(desiredWidth - topRightCornerSize, 0));
                        path.QuadCurveToPoint(new CGPoint(desiredWidth, topRightCornerSize), new CGPoint(desiredWidth, 0));
                    }
                    else
                    {
                        path.LineTo(new CGPoint(desiredWidth, 0));
                    }

                    // BottomRight
                    if (cornersTransformType.HasFlag(CornerTransformType.BottomRightCut))
                    {
                        path.LineTo(new CGPoint(desiredWidth, desiredHeight - bottomRightCornerSize));
                        path.LineTo(new CGPoint(desiredWidth - bottomRightCornerSize, desiredHeight));
                    }
                    else if (cornersTransformType.HasFlag(CornerTransformType.BottomRightRounded))
                    {
                        path.LineTo(new CGPoint(desiredWidth, desiredHeight - bottomRightCornerSize));
                        path.QuadCurveToPoint(new CGPoint(desiredWidth - bottomRightCornerSize, desiredHeight), new CGPoint(desiredWidth, desiredHeight));
                    }
                    else
                    {
                        path.LineTo(new CGPoint(desiredWidth, desiredHeight));
                    }

                    // BottomLeft
                    if (cornersTransformType.HasFlag(CornerTransformType.BottomLeftCut))
                    {
                        path.LineTo(new CGPoint(bottomLeftCornerSize, desiredHeight));
                        path.LineTo(new CGPoint(0, desiredHeight - bottomLeftCornerSize));
                    }
                    else if (cornersTransformType.HasFlag(CornerTransformType.BottomLeftRounded))
                    {
                        path.LineTo(new CGPoint(bottomLeftCornerSize, desiredHeight));
                        path.QuadCurveToPoint(new CGPoint(0, desiredHeight - bottomLeftCornerSize), new CGPoint(0, desiredHeight));
                    }
                    else
                    {
                        path.LineTo(new CGPoint(0, desiredHeight));
                    }

                    path.ClosePath();
                    context.AddPath(path.ToCGPath());
                    context.Clip();
                }

                var drawRect = new CGRect(-cropX, -cropY, sourceWidth, sourceHeight);
                context.DrawImage(drawRect, source.CGImage);


                using (var output = context.ToImage())
                {
                    return(new NSImage(output, CGSize.Empty));
                }
            }
        }