PushpinBorder for all platforms

This commit is contained in:
Clemens 2022-02-05 15:52:17 +01:00
parent 4a38e1e1e9
commit a4f19a5976
16 changed files with 291 additions and 164 deletions

View file

@ -9,8 +9,18 @@ using System.Windows.Media;
namespace MapControl
{
public class PushpinBorder : Decorator
public partial class PushpinBorder : Decorator
{
public static readonly DependencyProperty ArrowSizeProperty = DependencyProperty.Register(
nameof(ArrowSize), typeof(Size), typeof(PushpinBorder),
new FrameworkPropertyMetadata(new Size(10d, 20d),
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty BorderWidthProperty = DependencyProperty.Register(
nameof(BorderWidth), typeof(double), typeof(PushpinBorder),
new FrameworkPropertyMetadata(0d,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty BackgroundProperty = DependencyProperty.Register(
nameof(Background), typeof(Brush), typeof(PushpinBorder),
new FrameworkPropertyMetadata(null,
@ -21,11 +31,6 @@ namespace MapControl
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty BorderThicknessProperty = DependencyProperty.Register(
nameof(BorderThickness), typeof(double), typeof(PushpinBorder),
new FrameworkPropertyMetadata(0d,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register(
nameof(CornerRadius), typeof(CornerRadius), typeof(PushpinBorder),
new FrameworkPropertyMetadata(new CornerRadius(),
@ -36,11 +41,6 @@ namespace MapControl
new FrameworkPropertyMetadata(new Thickness(2),
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty ArrowSizeProperty = DependencyProperty.Register(
nameof(ArrowSize), typeof(Size), typeof(PushpinBorder),
new FrameworkPropertyMetadata(new Size(10d, 20d),
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender));
public Brush Background
{
get { return (Brush)GetValue(BackgroundProperty); }
@ -53,12 +53,6 @@ namespace MapControl
set { SetValue(BorderBrushProperty, value); }
}
public double BorderThickness
{
get { return (double)GetValue(BorderThicknessProperty); }
set { SetValue(BorderThicknessProperty, value); }
}
public CornerRadius CornerRadius
{
get { return (CornerRadius)GetValue(CornerRadiusProperty); }
@ -71,16 +65,10 @@ namespace MapControl
set { SetValue(PaddingProperty, value); }
}
public Size ArrowSize
{
get { return (Size)GetValue(ArrowSizeProperty); }
set { SetValue(ArrowSizeProperty, value); }
}
protected override Size MeasureOverride(Size constraint)
{
var width = Padding.Left + Padding.Right;
var height = Padding.Top + Padding.Bottom;
var width = 2d * BorderWidth + Padding.Left + Padding.Right;
var height = 2d * BorderWidth + Padding.Top + Padding.Bottom;
if (Child != null)
{
@ -89,17 +77,17 @@ namespace MapControl
height += Child.DesiredSize.Height;
}
var minWidth = Math.Max(
var minWidth = BorderWidth + Math.Max(
CornerRadius.TopLeft + CornerRadius.TopRight,
CornerRadius.BottomLeft + CornerRadius.BottomRight + ArrowSize.Width);
var minHeight = Math.Max(
var minHeight = BorderWidth + Math.Max(
CornerRadius.TopLeft + CornerRadius.BottomLeft,
CornerRadius.TopRight + CornerRadius.BottomRight);
return new Size(
Math.Max(width, minWidth) + BorderThickness,
Math.Max(height, minHeight) + BorderThickness + ArrowSize.Height);
Math.Max(width, minWidth),
Math.Max(height, minHeight) + ArrowSize.Height);
}
protected override Size ArrangeOverride(Size size)
@ -107,7 +95,10 @@ namespace MapControl
if (Child != null)
{
Child.Arrange(new Rect(
Padding.Left, Padding.Top, size.Width - Padding.Right, size.Height - Padding.Bottom));
BorderWidth + Padding.Left,
BorderWidth + Padding.Top,
size.Width - BorderWidth - Padding.Right,
size.Height - BorderWidth - Padding.Bottom));
}
return size;
@ -118,91 +109,13 @@ namespace MapControl
var pen = new Pen
{
Brush = BorderBrush,
Thickness = BorderThickness,
Thickness = BorderWidth,
LineJoin = PenLineJoin.Round
};
drawingContext.DrawGeometry(Background, pen, BuildGeometry(RenderSize));
drawingContext.DrawGeometry(Background, pen, BuildGeometry());
base.OnRender(drawingContext);
}
private Geometry BuildGeometry(Size size)
{
var x1 = BorderThickness / 2d;
var y1 = BorderThickness / 2d;
var x2 = size.Width - x1;
var y3 = size.Height - y1;
var y2 = y3 - ArrowSize.Height;
var aw = ArrowSize.Width;
var r1 = CornerRadius.TopLeft;
var r2 = CornerRadius.TopRight;
var r3 = CornerRadius.BottomRight;
var r4 = CornerRadius.BottomLeft;
var figure = new PathFigure
{
StartPoint = new Point(x1, y1 + r1),
IsClosed = true,
IsFilled = true
};
figure.Segments.Add(ArcTo(x1 + r1, y1, r1));
figure.Segments.Add(LineTo(x2 - r2, y1));
figure.Segments.Add(ArcTo(x2, y1 + r2, r2));
if (HorizontalAlignment == HorizontalAlignment.Right)
{
figure.Segments.Add(LineTo(x2, y3));
figure.Segments.Add(LineTo(x2 - aw, y2));
}
else
{
figure.Segments.Add(LineTo(x2, y2 - r3));
figure.Segments.Add(ArcTo(x2 - r3, y2, r3));
}
if (HorizontalAlignment != HorizontalAlignment.Left && HorizontalAlignment != HorizontalAlignment.Right)
{
var c = size.Width / 2d;
figure.Segments.Add(LineTo(c + aw / 2d, y2));
figure.Segments.Add(LineTo(c, y3));
figure.Segments.Add(LineTo(c - aw / 2d, y2));
}
if (HorizontalAlignment == HorizontalAlignment.Left)
{
figure.Segments.Add(LineTo(x1 + aw, y2));
figure.Segments.Add(LineTo(x1, y3));
}
else
{
figure.Segments.Add(LineTo(x1 + r4, y2));
figure.Segments.Add(ArcTo(x1, y2 - r4, r4));
}
var geometry = new PathGeometry();
geometry.Figures.Add(figure);
return geometry;
}
private static LineSegment LineTo(double x, double y)
{
return new LineSegment
{
Point = new Point(x, y)
};
}
private static ArcSegment ArcTo(double x, double y, double r)
{
return new ArcSegment
{
Point = new Point(x, y),
Size = new Size(r, r),
SweepDirection = SweepDirection.Clockwise
};
}
}
}

View file

@ -62,7 +62,7 @@
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1"
BorderWidth="1"
CornerRadius="5">
<ContentPresenter
Content="{TemplateBinding Content}"