From 77feabd2f5d30fb77e31f20bdcb0cc4a251cc2cd Mon Sep 17 00:00:00 2001 From: Max Katz Date: Wed, 12 Apr 2023 18:35:57 -0700 Subject: [PATCH 1/4] Update WindowingPlatform.cs --- src/Browser/Avalonia.Browser/WindowingPlatform.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Browser/Avalonia.Browser/WindowingPlatform.cs b/src/Browser/Avalonia.Browser/WindowingPlatform.cs index 88e378bd79..be6e28f5cb 100644 --- a/src/Browser/Avalonia.Browser/WindowingPlatform.cs +++ b/src/Browser/Avalonia.Browser/WindowingPlatform.cs @@ -14,11 +14,11 @@ namespace Avalonia.Browser private bool _signaled; private static KeyboardDevice? s_keyboard; - public IWindowImpl CreateWindow() => throw new NotSupportedException(); + public IWindowImpl CreateWindow() => throw new NotSupportedException("Browser doesn't support windowing platform. In order to display a single-view content, set ISingleViewApplicationLifetime.MainView."); IWindowImpl IWindowingPlatform.CreateEmbeddableWindow() { - throw new NotImplementedException(); + throw new NotImplementedException("Browser doesn't support embeddable windowing platform."); } public ITrayIconImpl? CreateTrayIcon() From bb2b2fce5f12679e06c48756edf63e928948bf9b Mon Sep 17 00:00:00 2001 From: Emmanuel Hansen Date: Wed, 12 Apr 2023 12:37:01 +0000 Subject: [PATCH 2/4] correction in calculating bottom inset on android --- .../Avalonia.Android/Platform/AndroidInsetsManager.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Android/Avalonia.Android/Platform/AndroidInsetsManager.cs b/src/Android/Avalonia.Android/Platform/AndroidInsetsManager.cs index 549815a036..251a177432 100644 --- a/src/Android/Avalonia.Android/Platform/AndroidInsetsManager.cs +++ b/src/Android/Avalonia.Android/Platform/AndroidInsetsManager.cs @@ -81,7 +81,7 @@ namespace Avalonia.Android.Platform var renderScaling = _topLevel.RenderScaling; var inset = insets.GetInsets( - (DisplayEdgeToEdge ? + (_displayEdgeToEdge ? WindowInsetsCompat.Type.StatusBars() | WindowInsetsCompat.Type.NavigationBars() | WindowInsetsCompat.Type.DisplayCutout() : 0) | WindowInsetsCompat.Type.Ime()); @@ -91,8 +91,8 @@ namespace Avalonia.Android.Platform return new Thickness(inset.Left / renderScaling, inset.Top / renderScaling, inset.Right / renderScaling, - (imeInset.Bottom > 0 && ((_usesLegacyLayouts && !DisplayEdgeToEdge) || !_usesLegacyLayouts) ? - imeInset.Bottom - navBarInset.Bottom : + (imeInset.Bottom > 0 && ((_usesLegacyLayouts && !_displayEdgeToEdge) || !_usesLegacyLayouts) ? + imeInset.Bottom - (_displayEdgeToEdge ? 0 : navBarInset.Bottom) : inset.Bottom) / renderScaling); } From 8f7deb17ad407a04b4a18f8fc456594ace20bd4b Mon Sep 17 00:00:00 2001 From: jankrib Date: Thu, 13 Apr 2023 13:29:53 +0200 Subject: [PATCH 3/4] Implement HitTestTransformed --- .../Rendering/SceneGraph/CustomDrawOperation.cs | 2 +- .../Rendering/SceneGraph/DrawOperation.cs | 15 +++++++++++++++ .../Rendering/SceneGraph/EllipseNode.cs | 2 +- .../SceneGraph/ExperimentalAcrylicNode.cs | 2 +- .../Rendering/SceneGraph/GeometryNode.cs | 2 +- .../Rendering/SceneGraph/GlyphRunNode.cs | 2 +- .../Rendering/SceneGraph/ImageNode.cs | 2 +- .../Rendering/SceneGraph/LineNode.cs | 2 +- .../Rendering/SceneGraph/OpacityMaskNode.cs | 2 +- .../Rendering/SceneGraph/RectangleNode.cs | 2 +- .../Rendering/SceneGraph/DrawOperationTests.cs | 2 +- 11 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/Avalonia.Base/Rendering/SceneGraph/CustomDrawOperation.cs b/src/Avalonia.Base/Rendering/SceneGraph/CustomDrawOperation.cs index ff2616bfe4..8f5ccb4e51 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/CustomDrawOperation.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/CustomDrawOperation.cs @@ -13,7 +13,7 @@ namespace Avalonia.Rendering.SceneGraph Custom = custom; } - public override bool HitTest(Point p) => Custom.HitTest(p); + public override bool HitTestTransformed(Point p) => Custom.HitTest(p); public override void Render(IDrawingContextImpl context) { diff --git a/src/Avalonia.Base/Rendering/SceneGraph/DrawOperation.cs b/src/Avalonia.Base/Rendering/SceneGraph/DrawOperation.cs index 5b93cd8cfc..786ce28d06 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/DrawOperation.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/DrawOperation.cs @@ -37,5 +37,20 @@ namespace Avalonia.Rendering.SceneGraph } public Matrix Transform { get; } + + public sealed override bool HitTest(Point p) + { + if (Transform.IsIdentity) + return HitTestTransformed(p); + + if (!Transform.HasInverse) + return false; + + var transformedPoint = Transform.Invert().Transform(p); + + return HitTestTransformed(transformedPoint); + } + + public abstract bool HitTestTransformed(Point p); } } diff --git a/src/Avalonia.Base/Rendering/SceneGraph/EllipseNode.cs b/src/Avalonia.Base/Rendering/SceneGraph/EllipseNode.cs index d5f0270cb2..0a2b74e46a 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/EllipseNode.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/EllipseNode.cs @@ -43,7 +43,7 @@ namespace Avalonia.Rendering.SceneGraph public override void Render(IDrawingContextImpl context) => context.DrawEllipse(Brush, Pen, Rect); - public override bool HitTest(Point p) + public override bool HitTestTransformed(Point p) { var center = Rect.Center; diff --git a/src/Avalonia.Base/Rendering/SceneGraph/ExperimentalAcrylicNode.cs b/src/Avalonia.Base/Rendering/SceneGraph/ExperimentalAcrylicNode.cs index e1f79e0e10..22fc49d30e 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/ExperimentalAcrylicNode.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/ExperimentalAcrylicNode.cs @@ -65,6 +65,6 @@ namespace Avalonia.Rendering.SceneGraph } /// - public override bool HitTest(Point p) => Rect.Rect.ContainsExclusive(p); + public override bool HitTestTransformed(Point p) => Rect.Rect.ContainsExclusive(p); } } diff --git a/src/Avalonia.Base/Rendering/SceneGraph/GeometryNode.cs b/src/Avalonia.Base/Rendering/SceneGraph/GeometryNode.cs index f64a3e845d..48af3b0e6b 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/GeometryNode.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/GeometryNode.cs @@ -64,7 +64,7 @@ namespace Avalonia.Rendering.SceneGraph } /// - public override bool HitTest(Point p) + public override bool HitTestTransformed(Point p) { return (Brush != null && Geometry.FillContains(p)) || (Pen != null && Geometry.StrokeContains(Pen, p)); diff --git a/src/Avalonia.Base/Rendering/SceneGraph/GlyphRunNode.cs b/src/Avalonia.Base/Rendering/SceneGraph/GlyphRunNode.cs index 5b975e29e1..b4e28dc254 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/GlyphRunNode.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/GlyphRunNode.cs @@ -53,7 +53,7 @@ namespace Avalonia.Rendering.SceneGraph } /// - public override bool HitTest(Point p) => Bounds.ContainsExclusive(p); + public override bool HitTestTransformed(Point p) => Bounds.ContainsExclusive(p); public override void Dispose() { diff --git a/src/Avalonia.Base/Rendering/SceneGraph/ImageNode.cs b/src/Avalonia.Base/Rendering/SceneGraph/ImageNode.cs index dd9787e8d1..ac946cc8b2 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/ImageNode.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/ImageNode.cs @@ -94,7 +94,7 @@ namespace Avalonia.Rendering.SceneGraph } /// - public override bool HitTest(Point p) => DestRect.ContainsExclusive(p); + public override bool HitTestTransformed(Point p) => DestRect.ContainsExclusive(p); public override void Dispose() { diff --git a/src/Avalonia.Base/Rendering/SceneGraph/LineNode.cs b/src/Avalonia.Base/Rendering/SceneGraph/LineNode.cs index 61bffc3260..1ac6cffe0a 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/LineNode.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/LineNode.cs @@ -66,7 +66,7 @@ namespace Avalonia.Rendering.SceneGraph context.DrawLine(Pen, P1, P2); } - public override bool HitTest(Point p) + public override bool HitTestTransformed(Point p) { var halfThickness = Pen.Thickness / 2; var minX = Math.Min(P1.X, P2.X) - halfThickness; diff --git a/src/Avalonia.Base/Rendering/SceneGraph/OpacityMaskNode.cs b/src/Avalonia.Base/Rendering/SceneGraph/OpacityMaskNode.cs index b0584038a8..1c79a67944 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/OpacityMaskNode.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/OpacityMaskNode.cs @@ -30,7 +30,7 @@ namespace Avalonia.Rendering.SceneGraph /// - public override bool HitTest(Point p) => false; + public override bool HitTestTransformed(Point p) => false; /// /// Determines if this draw operation equals another. diff --git a/src/Avalonia.Base/Rendering/SceneGraph/RectangleNode.cs b/src/Avalonia.Base/Rendering/SceneGraph/RectangleNode.cs index 94f61df47d..e85992be34 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/RectangleNode.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/RectangleNode.cs @@ -74,7 +74,7 @@ namespace Avalonia.Rendering.SceneGraph public override void Render(IDrawingContextImpl context) => context.DrawRectangle(Brush, Pen, Rect, BoxShadows); /// - public override bool HitTest(Point p) + public override bool HitTestTransformed(Point p) { if (Brush != null) { diff --git a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/DrawOperationTests.cs b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/DrawOperationTests.cs index 9d810fa110..c6a552c768 100644 --- a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/DrawOperationTests.cs +++ b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/DrawOperationTests.cs @@ -82,7 +82,7 @@ namespace Avalonia.Base.UnitTests.Rendering.SceneGraph } - public override bool HitTest(Point p) => false; + public override bool HitTestTransformed(Point p) => false; public override void Render(IDrawingContextImpl context) { } } From 076d3c721ec7967e2d032a18bb0bfe4cd39ebbd8 Mon Sep 17 00:00:00 2001 From: jankrib Date: Thu, 13 Apr 2023 14:41:21 +0200 Subject: [PATCH 4/4] Update DrawOperationTests.cs --- .../Rendering/SceneGraph/DrawOperationTests.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/DrawOperationTests.cs b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/DrawOperationTests.cs index c6a552c768..34878bd08d 100644 --- a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/DrawOperationTests.cs +++ b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/DrawOperationTests.cs @@ -74,6 +74,22 @@ namespace Avalonia.Base.UnitTests.Rendering.SceneGraph geometryNode.HitTest(new Point()); } + [Fact] + public void HitTest_RectangleNode_With_Transform_Hits() + { + var geometry = Mock.Of(); + var geometryNode = new RectangleNode( + Matrix.CreateTranslation(20,20), + Brushes.Black, + null, + new RoundedRect(new Rect(0,0,10,10)), + default); + + var actual = geometryNode.HitTest(new Point(25,25)); + + Assert.True(actual); + } + private class TestRectangleDrawOperation : RectangleNode { public TestRectangleDrawOperation(Rect bounds, Matrix transform, Pen pen)