Browse Source

Merge pull request #2537 from AvaloniaUI/fixes/2370-rectangles

Fix RectangleNode hit-testing and Rect.Deflate
pull/2679/head
Steven Kirk 7 years ago
committed by GitHub
parent
commit
ac3850d2df
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/Avalonia.Controls/Shapes/Ellipse.cs
  2. 2
      src/Avalonia.Controls/Shapes/Rectangle.cs
  3. 12
      src/Avalonia.Visuals/Rect.cs
  4. 24
      src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs
  5. 6
      tests/Avalonia.RenderTests/Controls/CustomRenderTests.cs

2
src/Avalonia.Controls/Shapes/Ellipse.cs

@ -14,7 +14,7 @@ namespace Avalonia.Controls.Shapes
protected override Geometry CreateDefiningGeometry() 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); return new EllipseGeometry(rect);
} }

2
src/Avalonia.Controls/Shapes/Rectangle.cs

@ -14,7 +14,7 @@ namespace Avalonia.Controls.Shapes
protected override Geometry CreateDefiningGeometry() 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); return new RectangleGeometry(rect);
} }

12
src/Avalonia.Visuals/Rect.cs

@ -256,7 +256,7 @@ namespace Avalonia
/// <summary> /// <summary>
/// Inflates the rectangle. /// Inflates the rectangle.
/// </summary> /// </summary>
/// <param name="thickness">The thickness.</param> /// <param name="thickness">The thickness to be subtracted for each side of the rectangle.</param>
/// <returns>The inflated rectangle.</returns> /// <returns>The inflated rectangle.</returns>
public Rect Inflate(double thickness) public Rect Inflate(double thickness)
{ {
@ -266,7 +266,7 @@ namespace Avalonia
/// <summary> /// <summary>
/// Inflates the rectangle. /// Inflates the rectangle.
/// </summary> /// </summary>
/// <param name="thickness">The thickness.</param> /// <param name="thickness">The thickness to be subtracted for each side of the rectangle.</param>
/// <returns>The inflated rectangle.</returns> /// <returns>The inflated rectangle.</returns>
public Rect Inflate(Thickness thickness) public Rect Inflate(Thickness thickness)
{ {
@ -278,20 +278,18 @@ namespace Avalonia
/// <summary> /// <summary>
/// Deflates the rectangle. /// Deflates the rectangle.
/// </summary> /// </summary>
/// <param name="thickness">The thickness.</param> /// <param name="thickness">The thickness to be subtracted for each side of the rectangle.</param>
/// <returns>The deflated rectangle.</returns> /// <returns>The deflated rectangle.</returns>
/// <remarks>The deflated rectangle size cannot be less than 0.</remarks>
public Rect Deflate(double thickness) public Rect Deflate(double thickness)
{ {
return Deflate(new Thickness(thickness / 2)); return Deflate(new Thickness(thickness));
} }
/// <summary> /// <summary>
/// Deflates the rectangle by a <see cref="Thickness"/>. /// Deflates the rectangle by a <see cref="Thickness"/>.
/// </summary> /// </summary>
/// <param name="thickness">The thickness.</param> /// <param name="thickness">The thickness to be subtracted for each side of the rectangle.</param>
/// <returns>The deflated rectangle.</returns> /// <returns>The deflated rectangle.</returns>
/// <remarks>The deflated rectangle size cannot be less than 0.</remarks>
public Rect Deflate(Thickness thickness) public Rect Deflate(Thickness thickness)
{ {
return new Rect( return new Rect(

24
src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs

@ -105,8 +105,28 @@ namespace Avalonia.Rendering.SceneGraph
} }
} }
// TODO: This doesn't respect CornerRadius yet.
/// <inheritdoc/> /// <inheritdoc/>
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;
}
} }
} }

6
tests/Avalonia.RenderTests/Controls/CustomRenderTests.cs

@ -36,7 +36,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls
new Rect(control.Bounds.Size), new Rect(control.Bounds.Size),
4); 4);
using (context.PushClip(new Rect(control.Bounds.Size).Deflate(20))) using (context.PushClip(new Rect(control.Bounds.Size).Deflate(10)))
{ {
context.FillRectangle( context.FillRectangle(
Brushes.Blue, Brushes.Blue,
@ -100,7 +100,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls
{ {
context.FillRectangle( context.FillRectangle(
Brushes.Blue, Brushes.Blue,
new Rect(control.Bounds.Size).Deflate(20), new Rect(control.Bounds.Size).Deflate(10),
4); 4);
} }
}), }),
@ -140,7 +140,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls
{ {
context.FillRectangle( context.FillRectangle(
Brushes.Blue, Brushes.Blue,
new Rect(control.Bounds.Size).Deflate(20), new Rect(control.Bounds.Size).Deflate(10),
4); 4);
} }
}), }),

Loading…
Cancel
Save