예제 #1
0
        public static APath ToAPath(this Geometry geometry, Context context)
        {
            APath path = new APath();

            float density = context.Resources.DisplayMetrics.Density;

            if (geometry is LineGeometry)
            {
                LineGeometry lineGeometry = geometry as LineGeometry;

                path.MoveTo(
                    density * (float)lineGeometry.StartPoint.X,
                    density * (float)lineGeometry.StartPoint.Y);

                path.LineTo(
                    density * (float)lineGeometry.EndPoint.X,
                    density * (float)lineGeometry.EndPoint.Y);
            }
            else if (geometry is RectangleGeometry)
            {
                FormsRectangle rect = (geometry as RectangleGeometry).Rect;

                path.AddRect(
                    density * (float)rect.Left,
                    density * (float)rect.Top,
                    density * (float)rect.Right,
                    density * (float)rect.Bottom,
                    APath.Direction.Cw);
            }
            else if (geometry is EllipseGeometry)
            {
                EllipseGeometry ellipseGeometry = geometry as EllipseGeometry;

                path.AddOval(new RectF(
                                 density * (float)(ellipseGeometry.Center.X - ellipseGeometry.RadiusX),
                                 density * (float)(ellipseGeometry.Center.Y - ellipseGeometry.RadiusY),
                                 density * (float)(ellipseGeometry.Center.X + ellipseGeometry.RadiusX),
                                 density * (float)(ellipseGeometry.Center.Y + ellipseGeometry.RadiusY)),
                             APath.Direction.Cw);
            }
            else if (geometry is GeometryGroup)
            {
                GeometryGroup geometryGroup = geometry as GeometryGroup;

                path.SetFillType(geometryGroup.FillRule == FillRule.Nonzero ? APath.FillType.Winding : APath.FillType.EvenOdd);

                foreach (Geometry child in geometryGroup.Children)
                {
                    APath childPath = child.ToAPath(context);
                    path.AddPath(childPath);
                }
            }
            else if (geometry is PathGeometry)
            {
                PathGeometry pathGeometry = geometry as PathGeometry;

                path.SetFillType(pathGeometry.FillRule == FillRule.Nonzero ? APath.FillType.Winding : APath.FillType.EvenOdd);

                foreach (PathFigure pathFigure in pathGeometry.Figures)
                {
                    path.MoveTo(
                        density * (float)pathFigure.StartPoint.X,
                        density * (float)pathFigure.StartPoint.Y);

                    Point lastPoint = pathFigure.StartPoint;

                    foreach (PathSegment pathSegment in pathFigure.Segments)
                    {
                        // LineSegment
                        if (pathSegment is LineSegment)
                        {
                            LineSegment lineSegment = pathSegment as LineSegment;

                            path.LineTo(
                                density * (float)lineSegment.Point.X,
                                density * (float)lineSegment.Point.Y);
                            lastPoint = lineSegment.Point;
                        }
                        // PolylineSegment
                        else if (pathSegment is PolyLineSegment)
                        {
                            PolyLineSegment polylineSegment = pathSegment as PolyLineSegment;
                            PointCollection points          = polylineSegment.Points;

                            for (int i = 0; i < points.Count; i++)
                            {
                                path.LineTo(
                                    density * (float)points[i].X,
                                    density * (float)points[i].Y);
                            }
                            lastPoint = points[points.Count - 1];
                        }
                        // BezierSegment
                        else if (pathSegment is BezierSegment)
                        {
                            BezierSegment bezierSegment = pathSegment as BezierSegment;

                            path.CubicTo(
                                density * (float)bezierSegment.Point1.X, density * (float)bezierSegment.Point1.Y,
                                density * (float)bezierSegment.Point2.X, density * (float)bezierSegment.Point2.Y,
                                density * (float)bezierSegment.Point3.X, density * (float)bezierSegment.Point3.Y);

                            lastPoint = bezierSegment.Point3;
                        }
                        // PolyBezierSegment
                        else if (pathSegment is PolyBezierSegment)
                        {
                            PolyBezierSegment polyBezierSegment = pathSegment as PolyBezierSegment;
                            PointCollection   points            = polyBezierSegment.Points;

                            if (points.Count >= 3)
                            {
                                for (int i = 0; i < points.Count; i += 3)
                                {
                                    path.CubicTo(
                                        density * (float)points[i + 0].X, density * (float)points[i + 0].Y,
                                        density * (float)points[i + 1].X, density * (float)points[i + 1].Y,
                                        density * (float)points[i + 2].X, density * (float)points[i + 2].Y);
                                }
                            }

                            lastPoint = points[points.Count - 1];
                        }
                        // QuadraticBezierSegment
                        else if (pathSegment is QuadraticBezierSegment)
                        {
                            QuadraticBezierSegment bezierSegment = pathSegment as QuadraticBezierSegment;

                            path.QuadTo(
                                density * (float)bezierSegment.Point1.X, density * (float)bezierSegment.Point1.Y,
                                density * (float)bezierSegment.Point2.X, density * (float)bezierSegment.Point2.Y);

                            lastPoint = bezierSegment.Point2;
                        }
                        // PolyQuadraticBezierSegment
                        else if (pathSegment is PolyQuadraticBezierSegment)
                        {
                            PolyQuadraticBezierSegment polyBezierSegment = pathSegment as PolyQuadraticBezierSegment;
                            PointCollection            points            = polyBezierSegment.Points;

                            if (points.Count >= 2)
                            {
                                for (int i = 0; i < points.Count; i += 2)
                                {
                                    path.QuadTo(
                                        density * (float)points[i + 0].X, density * (float)points[i + 0].Y,
                                        density * (float)points[i + 1].X, density * (float)points[i + 1].Y);
                                }
                            }

                            lastPoint = points[points.Count - 1];
                        }
                        // ArcSegment
                        else if (pathSegment is ArcSegment)
                        {
                            ArcSegment arcSegment = pathSegment as ArcSegment;

                            List <Point> points = new List <Point>();

                            GeometryHelper.FlattenArc(
                                points,
                                lastPoint,
                                arcSegment.Point,
                                arcSegment.Size.Width,
                                arcSegment.Size.Height,
                                arcSegment.RotationAngle,
                                arcSegment.IsLargeArc,
                                arcSegment.SweepDirection == SweepDirection.CounterClockwise,
                                1);

                            for (int i = 0; i < points.Count; i++)
                            {
                                path.LineTo(
                                    density * (float)points[i].X,
                                    density * (float)points[i].Y);
                            }

                            if (points.Count > 0)
                            {
                                lastPoint = points[points.Count - 1];
                            }
                        }
                    }

                    if (pathFigure.IsClosed)
                    {
                        path.Close();
                    }
                }
            }

            return(path);
        }
예제 #2
0
        public static PathData ToCGPath(this Geometry geometry, Transform renderTransform = null)
        {
            PathData pathData = new PathData
            {
                Data = new CGPath()
            };

            CGAffineTransform transform;

            if (renderTransform == null)
            {
                transform = CGAffineTransform.MakeIdentity();
            }
            else
            {
                transform = renderTransform.ToCGAffineTransform();
            }

            if (geometry is LineGeometry)
            {
                LineGeometry lineGeometry = geometry as LineGeometry;
                pathData.Data.MoveToPoint(transform, lineGeometry.StartPoint.ToPointF());
                pathData.Data.AddLineToPoint(transform, lineGeometry.EndPoint.ToPointF());
            }
            else if (geometry is RectangleGeometry)
            {
                var rect = (geometry as RectangleGeometry).Rect;
                pathData.Data.AddRect(transform, new CGRect(rect.X, rect.Y, rect.Width, rect.Height));
            }
            else if (geometry is EllipseGeometry)
            {
                EllipseGeometry ellipseGeometry = geometry as EllipseGeometry;

                CGRect rect = new CGRect(
                    ellipseGeometry.Center.X - ellipseGeometry.RadiusX,
                    ellipseGeometry.Center.Y - ellipseGeometry.RadiusY,
                    ellipseGeometry.RadiusX * 2,
                    ellipseGeometry.RadiusY * 2);

                pathData.Data.AddEllipseInRect(transform, rect);
            }
            else if (geometry is GeometryGroup)
            {
                GeometryGroup geometryGroup = geometry as GeometryGroup;

                pathData.IsNonzeroFillRule = geometryGroup.FillRule == FillRule.Nonzero;

                foreach (Geometry child in geometryGroup.Children)
                {
                    PathData pathChild = child.ToCGPath(renderTransform);
                    pathData.Data.AddPath(pathChild.Data);
                }
            }
            else if (geometry is PathGeometry)
            {
                PathGeometry pathGeometry = geometry as PathGeometry;

                pathData.IsNonzeroFillRule = pathGeometry.FillRule == FillRule.Nonzero;

                foreach (PathFigure pathFigure in pathGeometry.Figures)
                {
                    pathData.Data.MoveToPoint(transform, pathFigure.StartPoint.ToPointF());
                    Point lastPoint = pathFigure.StartPoint;

                    foreach (PathSegment pathSegment in pathFigure.Segments)
                    {
                        // LineSegment
                        if (pathSegment is LineSegment)
                        {
                            LineSegment lineSegment = pathSegment as LineSegment;

                            pathData.Data.AddLineToPoint(transform, lineSegment.Point.ToPointF());
                            lastPoint = lineSegment.Point;
                        }
                        // PolyLineSegment
                        else if (pathSegment is PolyLineSegment)
                        {
                            PolyLineSegment polylineSegment = pathSegment as PolyLineSegment;
                            PointCollection points          = polylineSegment.Points;

                            for (int i = 0; i < points.Count; i++)
                            {
                                pathData.Data.AddLineToPoint(transform, points[i].ToPointF());
                            }

                            lastPoint = points[points.Count - 1];
                        }

                        // BezierSegment
                        if (pathSegment is BezierSegment)
                        {
                            BezierSegment bezierSegment = pathSegment as BezierSegment;

                            pathData.Data.AddCurveToPoint(
                                transform,
                                bezierSegment.Point1.ToPointF(),
                                bezierSegment.Point2.ToPointF(),
                                bezierSegment.Point3.ToPointF());

                            lastPoint = bezierSegment.Point3;
                        }
                        // PolyBezierSegment
                        else if (pathSegment is PolyBezierSegment)
                        {
                            PolyBezierSegment polyBezierSegment = pathSegment as PolyBezierSegment;
                            PointCollection   points            = polyBezierSegment.Points;

                            if (points.Count >= 3)
                            {
                                for (int i = 0; i < points.Count; i += 3)
                                {
                                    pathData.Data.AddCurveToPoint(
                                        transform,
                                        points[i].ToPointF(),
                                        points[i + 1].ToPointF(),
                                        points[i + 2].ToPointF());
                                }
                            }

                            lastPoint = points[points.Count - 1];
                        }

                        // QuadraticBezierSegment
                        if (pathSegment is QuadraticBezierSegment)
                        {
                            QuadraticBezierSegment bezierSegment = pathSegment as QuadraticBezierSegment;

                            pathData.Data.AddQuadCurveToPoint(
                                transform,
                                new nfloat(bezierSegment.Point1.X),
                                new nfloat(bezierSegment.Point1.Y),
                                new nfloat(bezierSegment.Point2.X),
                                new nfloat(bezierSegment.Point2.Y));

                            lastPoint = bezierSegment.Point2;
                        }
                        // PolyQuadraticBezierSegment
                        else if (pathSegment is PolyQuadraticBezierSegment)
                        {
                            PolyQuadraticBezierSegment polyBezierSegment = pathSegment as PolyQuadraticBezierSegment;
                            PointCollection            points            = polyBezierSegment.Points;

                            if (points.Count >= 2)
                            {
                                for (int i = 0; i < points.Count; i += 2)
                                {
                                    pathData.Data.AddQuadCurveToPoint(
                                        transform,
                                        new nfloat(points[i + 0].X),
                                        new nfloat(points[i + 0].Y),
                                        new nfloat(points[i + 1].X),
                                        new nfloat(points[i + 1].Y));
                                }
                            }

                            lastPoint = points[points.Count - 1];
                        }
                        // ArcSegment
                        else if (pathSegment is ArcSegment)
                        {
                            ArcSegment arcSegment = pathSegment as ArcSegment;

                            List <Point> points = new List <Point>();

                            GeometryHelper.FlattenArc(
                                points,
                                lastPoint,
                                arcSegment.Point,
                                arcSegment.Size.Width,
                                arcSegment.Size.Height,
                                arcSegment.RotationAngle,
                                arcSegment.IsLargeArc,
                                arcSegment.SweepDirection == SweepDirection.CounterClockwise,
                                1);

                            CGPoint[] cgpoints = new CGPoint[points.Count];

                            for (int i = 0; i < points.Count; i++)
                            {
                                cgpoints[i] = transform.TransformPoint(points[i].ToPointF());
                            }

                            pathData.Data.AddLines(cgpoints);

                            lastPoint = points.Count > 0 ? points[points.Count - 1] : Point.Zero;
                        }
                    }

                    if (pathFigure.IsClosed)
                    {
                        pathData.Data.CloseSubpath();
                    }
                }
            }

            return(pathData);
        }
예제 #3
0
        IView CreateSampleCursorSelection()
        {
            var layout = new Microsoft.Maui.Controls.Layout2.GridLayout()
            {
                ColumnSpacing = 5, RowSpacing = 8, BackgroundColor = Colors.LightGreen
            };

            layout.AddRowDefinition(new RowDefinition()
            {
                Height = new GridLength(50)
            });

            layout.AddColumnDefinition(new ColumnDefinition()
            {
                Width = new GridLength(150)
            });
            layout.AddColumnDefinition(new ColumnDefinition()
            {
                Width = new GridLength(80)
            });
            layout.AddColumnDefinition(new ColumnDefinition()
            {
                Width = new GridLength(80)
            });

            Entry targetEntry = new() { Placeholder = "Selectable Text" };
            Entry forPosition = new() { Keyboard = Keyboard.Numeric, Placeholder = "CursorPos" };

            forPosition.TextChanged += (sender, args) =>
            {
                if (!int.TryParse(args.NewTextValue, out int newPos))
                {
                    return;
                }
                targetEntry.CursorPosition = newPos;
            };

            Entry forSelectionLen = new() { Keyboard = Keyboard.Numeric, Placeholder = "SelectionLen" };

            forSelectionLen.TextChanged += (sender, args) =>
            {
                if (!int.TryParse(args.NewTextValue, out int newSelectionLen))
                {
                    return;
                }
                targetEntry.SelectionLength = newSelectionLen;
            };

            layout.Add(targetEntry);
            layout.Add(forPosition);
            layout.SetColumn(forPosition, 1);
            layout.Add(forSelectionLen);
            layout.SetColumn(forSelectionLen, 2);

            return(layout);
        }

        IView CreateTransformations()
        {
            var label = new Button
            {
                BackgroundColor = Colors.Red,
                TextColor       = Colors.White,
                Text            = "Transformations",
            };

            var rotationSlider = new Slider
            {
                Minimum = -360,
                Maximum = 360
            };

            rotationSlider.ValueChanged += (sender, e) => label.Rotation = e.NewValue;

            var verticalStack = new VerticalStackLayout
            {
                rotationSlider,
                label,
            };

            return(verticalStack);
        }

        IView CreateAnimations()
        {
            var image = new Image {
                Source = "dotnet_bot.png", VerticalOptions = LayoutOptions.CenterAndExpand
            };
            var animateButton = new Button {
                Text = "Animate", VerticalOptions = LayoutOptions.End
            };

            animateButton.Clicked += async(sender, args) =>
            {
                await image.RotateTo(360, 2000);

                image.Rotation = 0;
            };

            var verticalStack = new VerticalStackLayout
            {
                image,
                animateButton,
            };

            return(verticalStack);
        }

        IView CreateShapes()
        {
            var ellipse = new Ellipse {
                Fill = new SolidColorBrush(Colors.Red), Stroke = new SolidColorBrush(Colors.Blue), StrokeThickness = 4, HeightRequest = 120, WidthRequest = 200
            };

            var line = new Line {
                X1 = 0, Y1 = 0, X2 = 80, Y2 = 90, Fill = new SolidColorBrush(Colors.Red), Stroke = new SolidColorBrush(Colors.Green), StrokeThickness = 4, StrokeDashArray = new double[] { 2, 2 }, HeightRequest = 200, WidthRequest = 200
            };
            Geometry pathData = (Geometry) new PathGeometryConverter().ConvertFromInvariantString("M15.999996,0L31.999999,13.000001 15.999996,26.199999 0,13.000001z");
            var      path     = new Microsoft.Maui.Controls.Shapes.Path {
                Data = pathData, Fill = new SolidColorBrush(Colors.Pink), Stroke = new SolidColorBrush(Colors.Red), StrokeThickness = 1, HeightRequest = 100, WidthRequest = 100
            };

            var polyline = new Polyline {
                Points = new[] { new Point(10, 10), new Point(100, 50), new Point(50, 90) }, Stroke = new SolidColorBrush(Colors.Black), StrokeThickness = 2, StrokeDashArray = new double[] { 1, 1, 1, 1 }, HeightRequest = 100, WidthRequest = 100
            };

            var polygon = new Polygon {
                Points = new[] { new Point(10, 10), new Point(100, 50), new Point(50, 90) }, Fill = new SolidColorBrush(Colors.LightBlue), Stroke = new SolidColorBrush(Colors.Black), StrokeThickness = 2, StrokeDashArray = new double[] { 2, 2 }, HeightRequest = 100, WidthRequest = 100
            };

            var rectangle = new Microsoft.Maui.Controls.Shapes.Rectangle {
                RadiusX = 12, RadiusY = 6, Fill = new LinearGradientBrush(new GradientStopCollection {
                    new GradientStop(Colors.Green, 0), new GradientStop(Colors.Blue, 1)
                }, new Point(0, 0), new Point(1, 0)), Stroke = new SolidColorBrush(Colors.Purple), StrokeThickness = 8, StrokeDashArray = new float[] { 2, 2 }, HeightRequest = 120, WidthRequest = 200
            };

            var verticalStack = new VerticalStackLayout
            {
                ellipse,
                line,
                path,
                polyline,
                polygon,
                rectangle
            };

            return(verticalStack);
        }

        void AddTextResizeDemo(Microsoft.Maui.ILayout layout)
        {
            var resizeTestButton = new Button {
                Text = "Resize Test"
            };

            var resizeTestLabel = new Label {
                Text = "Short Text", BackgroundColor = Colors.LightBlue, HorizontalOptions = LayoutOptions.Start
            };
            var explicitWidthTestLabel = new Label {
                Text = "Short Text", BackgroundColor = Colors.LightGreen, WidthRequest = 200
            };
            var widthAndHeightTestLabel = new Label {
                Text = "Short Text", BackgroundColor = Colors.MediumSeaGreen, WidthRequest = 150, HeightRequest = 40
            };

            resizeTestButton.Clicked += (sender, args) =>
            {
                if (resizeTestLabel.Text == "Short Text")
                {
                    resizeTestLabel.Text         = LoremIpsum;
                    explicitWidthTestLabel.Text  = LoremIpsum;
                    widthAndHeightTestLabel.Text = LoremIpsum;
                }
                else
                {
                    resizeTestLabel.Text         = "Short Text";
                    explicitWidthTestLabel.Text  = "Short Text";
                    widthAndHeightTestLabel.Text = "Short Text";
                }
            };

            layout.Add(resizeTestButton);
            layout.Add(resizeTestLabel);
            layout.Add(widthAndHeightTestLabel);
            layout.Add(explicitWidthTestLabel);
        }

        void SetupVisibilityTest()
        {
            var layout = new VerticalStackLayout()
            {
                BackgroundColor = Colors.BurlyWood
            };

            var button1 = new Button {
                Text = "Controls", Margin = new Thickness(0, 40)
            };

            var button2 = new Button {
                Text = "MAUI"
            };

            var controlsLabel = new Label {
                Text = "Controls Label"
            };

            controlsLabel.IsVisible = true;

            var alwaysVisible = new Label {
                Text = "Always visible"
            };

            var mauiLabel = new VisibilityLabel()
            {
                Text = "Core Label"
            };

            button1.Clicked += (sender, args) =>
            {
                controlsLabel.IsVisible = !controlsLabel.IsVisible;
            };

            button2.Clicked += (sender, args) =>
            {
                switch ((mauiLabel as IFrameworkElement).Visibility)
                {
                case Visibility.Visible:
                    mauiLabel.SetVisibility(Visibility.Hidden);
                    break;

                case Visibility.Hidden:
                    mauiLabel.SetVisibility(Visibility.Collapsed);
                    break;

                case Visibility.Collapsed:
                    mauiLabel.SetVisibility(Visibility.Visible);
                    break;
                }
            };

            layout.Add(button1);
            layout.Add(button2);
            layout.Add(controlsLabel);
            layout.Add(mauiLabel);
            layout.Add(alwaysVisible);

            Content = layout;
        }

        class TestDrawable : IDrawable
        {