Browse Source

Merge pull request #8599 from jinek/fixes/scene-hittest-exclusive

Scene hittest now uses exclusive `Rect.Contains`. Fixes https://githu
pull/8646/head
Max Katz 4 years ago
committed by GitHub
parent
commit
9548da6696
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/Avalonia.Base/Rendering/SceneGraph/ExperimentalAcrylicNode.cs
  2. 2
      src/Avalonia.Base/Rendering/SceneGraph/GlyphRunNode.cs
  3. 2
      src/Avalonia.Base/Rendering/SceneGraph/ImageNode.cs
  4. 4
      src/Avalonia.Base/Rendering/SceneGraph/RectangleNode.cs
  5. 2
      src/Avalonia.Base/Rendering/SceneGraph/Scene.cs
  6. 26
      tests/Avalonia.Base.UnitTests/Rendering/CompositorHitTestingTests.cs
  7. 32
      tests/Avalonia.Base.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs

2
src/Avalonia.Base/Rendering/SceneGraph/ExperimentalAcrylicNode.cs

@ -83,7 +83,7 @@ namespace Avalonia.Rendering.SceneGraph
if (Material != null)
{
var rect = Rect.Rect;
return rect.Contains(p);
return rect.ContainsExclusive(p);
}
}

2
src/Avalonia.Base/Rendering/SceneGraph/GlyphRunNode.cs

@ -73,6 +73,6 @@ namespace Avalonia.Rendering.SceneGraph
}
/// <inheritdoc/>
public override bool HitTest(Point p) => Bounds.Contains(p);
public override bool HitTest(Point p) => Bounds.ContainsExclusive(p);
}
}

2
src/Avalonia.Base/Rendering/SceneGraph/ImageNode.cs

@ -109,7 +109,7 @@ namespace Avalonia.Rendering.SceneGraph
}
/// <inheritdoc/>
public override bool HitTest(Point p) => Bounds.Contains(p);
public override bool HitTest(Point p) => Bounds.ContainsExclusive(p);
public override void Dispose()
{

4
src/Avalonia.Base/Rendering/SceneGraph/RectangleNode.cs

@ -103,13 +103,13 @@ namespace Avalonia.Rendering.SceneGraph
if (Brush != null)
{
var rect = Rect.Rect.Inflate((Pen?.Thickness / 2) ?? 0);
return rect.Contains(p);
return rect.ContainsExclusive(p);
}
else
{
var borderRect = Rect.Rect.Inflate((Pen?.Thickness / 2) ?? 0);
var emptyRect = Rect.Rect.Deflate((Pen?.Thickness / 2) ?? 0);
return borderRect.Contains(p) && !emptyRect.Contains(p);
return borderRect.ContainsExclusive(p) && !emptyRect.ContainsExclusive(p);
}
}

2
src/Avalonia.Base/Rendering/SceneGraph/Scene.cs

@ -300,7 +300,7 @@ namespace Avalonia.Rendering.SceneGraph
if (node.ClipToBounds)
{
clip = clip == null ? node.ClipBounds : clip.Value.Intersect(node.ClipBounds);
clipped = !clip.Value.Contains(_point);
clipped = !clip.Value.ContainsExclusive(_point);
}
if (node.GeometryClip != null)

26
tests/Avalonia.Base.UnitTests/Rendering/CompositorHitTestingTests.cs

@ -408,10 +408,34 @@ public class CompositorHitTestingTests : CompositorTestsBase
s.AssertHitTest(175, 100, null);
}
}
[Fact]
public void HitTest_Should_Not_Hit_Controls_Next_Pixel()
{
using (var s = new CompositorServices(new Size(200, 200)))
{
Border targetRectangle;
var stackPanel = new StackPanel
{
Orientation = Orientation.Vertical,
HorizontalAlignment = HorizontalAlignment.Left,
Children =
{
new Border { Width = 10, Height = 10, Background= Brushes.Red},
{ targetRectangle = new Border { Width = 10, Height = 10, Background = Brushes.Green} }
}
};
s.TopLevel.Content = stackPanel;
s.AssertHitTest(new Point(5, 10), null, targetRectangle);
}
}
private IDisposable TestApplication()
{
return UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
}
}
}

32
tests/Avalonia.Base.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs

@ -537,6 +537,38 @@ namespace Avalonia.Base.UnitTests.Rendering
}
}
[Fact]
public void HitTest_Should_Not_Hit_Controls_Next_Pixel()
{
using (TestApplication())
{
Border targetRectangle;
var root = new TestRoot
{
Width = 50,
Height = 200,
Child = new StackPanel
{
Orientation = Orientation.Vertical,
HorizontalAlignment = HorizontalAlignment.Left,
Children =
{
new Border { Width = 50, Height = 50, Background = Brushes.Red},
{ targetRectangle = new Border { Width = 50, Height = 50, Background = Brushes.Green} }
}
}
};
root.Renderer = new DeferredRenderer(root, null);
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
var result = root.Renderer.HitTest(new Point(25, 50), root, null);
Assert.Equal(new[] { targetRectangle }, result);
}
}
private IDisposable TestApplication()
{
return UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);

Loading…
Cancel
Save