Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IdeaCode] About TrackerControl in OxyPlot.Wpf.Shared #2035

Open
emako opened this issue Aug 26, 2023 · 0 comments
Open

[IdeaCode] About TrackerControl in OxyPlot.Wpf.Shared #2035

emako opened this issue Aug 26, 2023 · 0 comments

Comments

@emako
Copy link

emako commented Aug 26, 2023

Feature description

I have an idea code about TrackerControl in OxyPlot.Wpf.Shared, which can make TrackerControl to use CornerRadius to create rounded rectangle.
But I am not sure if it can support platforms outside of WPF, so I only propose an idea here when ShowPointer is True.

Rendering like following image.
image

// TrackerControl.cs
private Geometry CreatePointerBorderGeometry(
            HorizontalAlignment ha, VerticalAlignment va, double width, double height, out Thickness margin)
        {
            Point[] points = null;
            double m = this.Distance;
            margin = new Thickness();

            if (ha == HorizontalAlignment.Center && va == VerticalAlignment.Bottom)
            {
                double x0 = 0;
                double x1 = width;
                double x2 = (x0 + x1) / 2;
                double y0 = 0;
                double y1 = height;
                margin = new Thickness(0, 0, 0, m);

                // Use CornerRadius to create rounded rectangle
                var roundedRect = new StreamGeometry();
                using (var context = roundedRect.Open())
                {
                    context.BeginFigure(new Point(x0 + this.CornerRadius, y0), true, true);
                    context.LineTo(new Point(x1 - this.CornerRadius, y0), true, false);
                    context.ArcTo(new Point(x1, y0 + this.CornerRadius), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x1, y1 - this.CornerRadius), true, false);
                    context.ArcTo(new Point(x1 - this.CornerRadius, y1), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x0 + this.CornerRadius, y1), true, false);
                    context.ArcTo(new Point(x0, y1 - this.CornerRadius), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x0, y0 + this.CornerRadius), true, false);
                    context.ArcTo(new Point(x0 + this.CornerRadius, y0), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                }

                // Create arrow points
                points = new[]
                {
                    new Point(x2 + (m / 2), y1),
                    new Point(x2, y1 + m),
                    new Point(x2 - (m / 2), y1),
                };

                // Combine the rounded rectangle and arrow points
                var combinedGeometry = new CombinedGeometry(roundedRect, new PathGeometry(new[] { new PathFigure(new Point(x2 + (m / 2), y1), new[] { new PolyLineSegment(points, true) }, false) }));
                return combinedGeometry;
            }

            if (ha == HorizontalAlignment.Center && va == VerticalAlignment.Top)
            {
                double x0 = 0;
                double x1 = width;
                double x2 = (x0 + x1) / 2;
                double y0 = m;
                double y1 = m + height;
                margin = new Thickness(0, m, 0, 0);

                // Use CornerRadius to create rounded rectangle
                var roundedRect = new StreamGeometry();
                using (var context = roundedRect.Open())
                {
                    context.BeginFigure(new Point(x0 + this.CornerRadius, y0), true, true);
                    context.LineTo(new Point(x1 - this.CornerRadius, y0), true, false);
                    context.ArcTo(new Point(x1, y0 + this.CornerRadius), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x1, y1 - this.CornerRadius), true, false);
                    context.ArcTo(new Point(x1 - this.CornerRadius, y1), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x0 + this.CornerRadius, y1), true, false);
                    context.ArcTo(new Point(x0, y1 - this.CornerRadius), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x0, y0 + this.CornerRadius), true, false);
                    context.ArcTo(new Point(x0 + this.CornerRadius, y0), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                }

                // Create arrow points
                points = new[]
                {
                    new Point(x2 + (m / 2), y0),
                    new Point(x2, y0 - m),
                    new Point(x2 - (m / 2), y0),
                };

                // Combine the rounded rectangle and arrow points
                var combinedGeometry = new CombinedGeometry(roundedRect, new PathGeometry(new[] { new PathFigure(new Point(x2 + (m / 2), y0), new[] { new PolyLineSegment(points, true) }, false) }));
                return combinedGeometry;
            }

            if (ha == HorizontalAlignment.Left && va == VerticalAlignment.Center)
            {
                double x0 = m;
                double x1 = m + width;
                double y0 = 0;
                double y1 = height;
                double y2 = (y0 + y1) / 2;
                margin = new Thickness(m, 0, 0, 0);

                // Use CornerRadius to create rounded rectangle
                var roundedRect = new StreamGeometry();
                using (var context = roundedRect.Open())
                {
                    context.BeginFigure(new Point(x0, y2 + this.CornerRadius), true, true);
                    context.LineTo(new Point(x0, y1 - this.CornerRadius), true, false);
                    context.ArcTo(new Point(x0 + this.CornerRadius, y1), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x1 - this.CornerRadius, y1), true, false);
                    context.ArcTo(new Point(x1, y1 - this.CornerRadius), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x1, y0 + this.CornerRadius), true, false);
                    context.ArcTo(new Point(x1 - this.CornerRadius, y0), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x0 + this.CornerRadius, y0), true, false);
                    context.ArcTo(new Point(x0, y0 + this.CornerRadius), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                }

                // Create arrow points
                points = new[]
                {
                    new Point(x0, y2 + (m / 2)),
                    new Point(x0 - m, y2),
                    new Point(x0, y2 - (m / 2)),
                };

                // Combine the rounded rectangle and arrow points
                var combinedGeometry = new CombinedGeometry(roundedRect, new PathGeometry(new[] { new PathFigure(new Point(x0, y2 + (m / 2)), new[] { new PolyLineSegment(points, true) }, false) }));
                return combinedGeometry;
            }

            if (ha == HorizontalAlignment.Right && va == VerticalAlignment.Center)
            {
                double x0 = 0;
                double x1 = width;
                double y0 = 0;
                double y1 = height;
                double y2 = (y0 + y1) / 2;
                margin = new Thickness(0, 0, m, 0);

                // Use CornerRadius to create rounded rectangle
                var roundedRect = new StreamGeometry();
                using (var context = roundedRect.Open())
                {
                    context.BeginFigure(new Point(x0 + this.CornerRadius, y0), true, true);
                    context.LineTo(new Point(x1 - this.CornerRadius, y0), true, false);
                    context.ArcTo(new Point(x1, y0 + this.CornerRadius), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x1, y1 - this.CornerRadius), true, false);
                    context.ArcTo(new Point(x1 - this.CornerRadius, y1), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x0 + this.CornerRadius, y1), true, false);
                    context.ArcTo(new Point(x0, y1 - this.CornerRadius), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x0, y0 + this.CornerRadius), true, false);
                    context.ArcTo(new Point(x0 + this.CornerRadius, y0), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                }

                // Create arrow points
                points = new[]
                {
                    new Point(x1 + m, y2),
                    new Point(x1, y2 + (m / 2)),
                    new Point(x1, y2 - (m / 2)),
                };

                // Combine the rounded rectangle and arrow points
                var combinedGeometry = new CombinedGeometry(roundedRect, new PathGeometry(new[] { new PathFigure(new Point(x1 + m, y2), new[] { new PolyLineSegment(points, true) }, false) }));
                return combinedGeometry;
            }

            if (ha == HorizontalAlignment.Left && va == VerticalAlignment.Top)
            {
                double x0 = m;
                double x1 = m + width;
                double y0 = m;
                double y1 = m + height;
                margin = new Thickness(m, m, 0, 0);

                // Use CornerRadius to create rounded rectangle
                var roundedRect = new StreamGeometry();
                using (var context = roundedRect.Open())
                {
                    context.BeginFigure(new Point(x0, y0 + this.CornerRadius), true, true);
                    context.LineTo(new Point(x0, y1 - this.CornerRadius), true, false);
                    context.ArcTo(new Point(x0 + this.CornerRadius, y1), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x1 - this.CornerRadius, y1), true, false);
                    context.ArcTo(new Point(x1, y1 - this.CornerRadius), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x1, y0 + this.CornerRadius), true, false);
                    context.ArcTo(new Point(x1 - this.CornerRadius, y0), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x0 + this.CornerRadius, y0), true, false);
                    context.ArcTo(new Point(x0, y0 + this.CornerRadius), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                }

                // Create arrow points
                points = new[]
                {
                    new Point(x0, 0),
                    new Point(x0 - m, y0),
                    new Point(x0, y0 - m),
                };

                // Combine the rounded rectangle and arrow points
                var combinedGeometry = new CombinedGeometry(roundedRect, new PathGeometry(new[] { new PathFigure(new Point(x0, 0), new[] { new PolyLineSegment(points, true) }, false) }));
                return combinedGeometry;
            }

            if (ha == HorizontalAlignment.Right && va == VerticalAlignment.Top)
            {
                double x0 = 0;
                double x1 = width;
                double y0 = m;
                double y1 = m + height;
                margin = new Thickness(0, m, m, 0);

                // Use CornerRadius to create rounded rectangle
                var roundedRect = new StreamGeometry();
                using (var context = roundedRect.Open())
                {
                    context.BeginFigure(new Point(x0 + this.CornerRadius, y0), true, true);
                    context.LineTo(new Point(x1 - this.CornerRadius, y0), true, false);
                    context.ArcTo(new Point(x1, y0 + this.CornerRadius), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x1, y1 - this.CornerRadius), true, false);
                    context.ArcTo(new Point(x1 - this.CornerRadius, y1), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x0 + this.CornerRadius, y1), true, false);
                    context.ArcTo(new Point(x0, y1 - this.CornerRadius), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x0, y0 + this.CornerRadius), true, false);
                    context.ArcTo(new Point(x0 + this.CornerRadius, y0), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                }

                // Create arrow points
                points = new[]
                {
                    new Point(x1 + m, 0),
                    new Point(x1, y0 - m),
                    new Point(x1, y0 + m),
                };

                // Combine the rounded rectangle and arrow points
                var combinedGeometry = new CombinedGeometry(roundedRect, new PathGeometry(new[] { new PathFigure(new Point(x1 + m, 0), new[] { new PolyLineSegment(points, true) }, false) }));
                return combinedGeometry;
            }

            if (ha == HorizontalAlignment.Left && va == VerticalAlignment.Bottom)
            {
                double x0 = m;
                double x1 = m + width;
                double y0 = 0;
                double y1 = height;
                margin = new Thickness(m, 0, 0, m);

                // Use CornerRadius to create rounded rectangle
                var roundedRect = new StreamGeometry();
                using (var context = roundedRect.Open())
                {
                    context.BeginFigure(new Point(x0, y1 + m), true, true);
                    context.LineTo(new Point(x0, y0 + m), true, false);
                    context.ArcTo(new Point(x0 + this.CornerRadius, y0), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x1 - this.CornerRadius, y0), true, false);
                    context.ArcTo(new Point(x1, y0 + this.CornerRadius), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x1, y1 - this.CornerRadius), true, false);
                    context.ArcTo(new Point(x1 - this.CornerRadius, y1), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x0 + this.CornerRadius, y1), true, false);
                    context.ArcTo(new Point(x0, y1 - this.CornerRadius), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                }

                // Create arrow points
                points = new[]
                {
                    new Point(x0, y1 + m),
                    new Point(x0 - m, y1 - m),
                    new Point(x0, y1 - m),
                };

                // Combine the rounded rectangle and arrow points
                var combinedGeometry = new CombinedGeometry(roundedRect, new PathGeometry(new[] { new PathFigure(new Point(x0, y1 + m), new[] { new PolyLineSegment(points, true) }, false) }));
                return combinedGeometry;
            }

            if (ha == HorizontalAlignment.Right && va == VerticalAlignment.Bottom)
            {
                double x0 = 0;
                double x1 = width;
                double y0 = 0;
                double y1 = height;
                margin = new Thickness(0, 0, m, m);

                // Use CornerRadius to create rounded rectangle
                var roundedRect = new StreamGeometry();
                using (var context = roundedRect.Open())
                {
                    context.BeginFigure(new Point(x1 + m, y1 + m), true, true);
                    context.LineTo(new Point(x1 - m, y1), true, false);
                    context.ArcTo(new Point(x1, y1 - this.CornerRadius), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x0 + this.CornerRadius, y1), true, false);
                    context.ArcTo(new Point(x0, y1 - this.CornerRadius), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                    context.LineTo(new Point(x0, y0 + this.CornerRadius), true, false);
                    context.ArcTo(new Point(x0 + this.CornerRadius, y0), new Size(this.CornerRadius, this.CornerRadius), 0, false, SweepDirection.Clockwise, true, false);
                }

                // Create arrow points
                points = new[]
                {
                    new Point(x1 + m, y1 + m),
                    new Point(x1, y1 - m),
                    new Point(x1, y1 + m),
                };

                // Combine the rounded rectangle and arrow points
                var combinedGeometry = new CombinedGeometry(roundedRect, new PathGeometry(new[] { new PathFigure(new Point(x1 + m, y1 + m), new[] { new PolyLineSegment(points, true) }, false) }));
                return combinedGeometry;
            }

            // If no match is found, return null
            return null;
        }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant