From 7cdaeac4411bb95d56b7602c3c99a38de17b6437 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 16 May 2019 18:41:58 +0200 Subject: [PATCH 1/2] Make Rect.Deflate consistent with Rect.Inflate. `Rect.Deflate` was halving the thickness passed into it whereas `Rect.Inflate` wasn't. Make both methods consistent and _not_ halve the thickness. --- src/Avalonia.Controls/Shapes/Ellipse.cs | 2 +- src/Avalonia.Controls/Shapes/Rectangle.cs | 2 +- src/Avalonia.Visuals/Rect.cs | 12 +++++------- .../Controls/CustomRenderTests.cs | 6 +++--- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/Avalonia.Controls/Shapes/Ellipse.cs b/src/Avalonia.Controls/Shapes/Ellipse.cs index 8cb73bf5c6..f80bf5d967 100644 --- a/src/Avalonia.Controls/Shapes/Ellipse.cs +++ b/src/Avalonia.Controls/Shapes/Ellipse.cs @@ -14,7 +14,7 @@ namespace Avalonia.Controls.Shapes protected override Geometry CreateDefiningGeometry() { - var rect = new Rect(Bounds.Size).Deflate(StrokeThickness); + var rect = new Rect(Bounds.Size).Deflate(StrokeThickness / 2); return new EllipseGeometry(rect); } diff --git a/src/Avalonia.Controls/Shapes/Rectangle.cs b/src/Avalonia.Controls/Shapes/Rectangle.cs index 375b0b719a..b803bde588 100644 --- a/src/Avalonia.Controls/Shapes/Rectangle.cs +++ b/src/Avalonia.Controls/Shapes/Rectangle.cs @@ -14,7 +14,7 @@ namespace Avalonia.Controls.Shapes protected override Geometry CreateDefiningGeometry() { - var rect = new Rect(Bounds.Size).Deflate(StrokeThickness); + var rect = new Rect(Bounds.Size).Deflate(StrokeThickness / 2); return new RectangleGeometry(rect); } diff --git a/src/Avalonia.Visuals/Rect.cs b/src/Avalonia.Visuals/Rect.cs index 530a47729f..49d4724b9a 100644 --- a/src/Avalonia.Visuals/Rect.cs +++ b/src/Avalonia.Visuals/Rect.cs @@ -256,7 +256,7 @@ namespace Avalonia /// /// Inflates the rectangle. /// - /// The thickness. + /// The thickness to be subtracted for each side of the rectangle. /// The inflated rectangle. public Rect Inflate(double thickness) { @@ -266,7 +266,7 @@ namespace Avalonia /// /// Inflates the rectangle. /// - /// The thickness. + /// The thickness to be subtracted for each side of the rectangle. /// The inflated rectangle. public Rect Inflate(Thickness thickness) { @@ -278,20 +278,18 @@ namespace Avalonia /// /// Deflates the rectangle. /// - /// The thickness. + /// The thickness to be subtracted for each side of the rectangle. /// The deflated rectangle. - /// The deflated rectangle size cannot be less than 0. public Rect Deflate(double thickness) { - return Deflate(new Thickness(thickness / 2)); + return Deflate(new Thickness(thickness)); } /// /// Deflates the rectangle by a . /// - /// The thickness. + /// The thickness to be subtracted for each side of the rectangle. /// The deflated rectangle. - /// The deflated rectangle size cannot be less than 0. public Rect Deflate(Thickness thickness) { return new Rect( diff --git a/tests/Avalonia.RenderTests/Controls/CustomRenderTests.cs b/tests/Avalonia.RenderTests/Controls/CustomRenderTests.cs index 6a01536b12..d3a935c281 100644 --- a/tests/Avalonia.RenderTests/Controls/CustomRenderTests.cs +++ b/tests/Avalonia.RenderTests/Controls/CustomRenderTests.cs @@ -36,7 +36,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls new Rect(control.Bounds.Size), 4); - using (context.PushClip(new Rect(control.Bounds.Size).Deflate(20))) + using (context.PushClip(new Rect(control.Bounds.Size).Deflate(10))) { context.FillRectangle( Brushes.Blue, @@ -100,7 +100,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls { context.FillRectangle( Brushes.Blue, - new Rect(control.Bounds.Size).Deflate(20), + new Rect(control.Bounds.Size).Deflate(10), 4); } }), @@ -140,7 +140,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls { context.FillRectangle( Brushes.Blue, - new Rect(control.Bounds.Size).Deflate(20), + new Rect(control.Bounds.Size).Deflate(10), 4); } }), From 88f2bd791d17ff67b6d369a4b19d9d836fb6856e Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 16 May 2019 18:58:07 +0200 Subject: [PATCH 2/2] Fix hit testing in RectangleNode. There were two problems here: - As #2370 describes we were tested against the rotated AABB of the rectangle - We were hit-testing non-filled rectangles as filled rectangles Fixes #2370 --- .../Rendering/SceneGraph/RectangleNode.cs | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs index 33cc39cbe3..c622dc8a43 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs @@ -105,8 +105,28 @@ namespace Avalonia.Rendering.SceneGraph } } - // TODO: This doesn't respect CornerRadius yet. /// - public override bool HitTest(Point p) => Bounds.Contains(p); + public override bool HitTest(Point p) + { + // TODO: This doesn't respect CornerRadius yet. + if (Transform.HasInverse) + { + p *= Transform.Invert(); + + if (Brush != null) + { + var rect = Rect.Inflate((Pen?.Thickness / 2) ?? 0); + return rect.Contains(p); + } + else + { + var borderRect = Rect.Inflate((Pen?.Thickness / 2) ?? 0); + var emptyRect = Rect.Deflate((Pen?.Thickness / 2) ?? 0); + return borderRect.Contains(p) && !emptyRect.Contains(p); + } + } + + return false; + } } }