From 95b6343f8f217f281f59127dff4928113d5bc94b Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Thu, 16 Feb 2023 13:02:20 +0600 Subject: [PATCH] Respect AdornerLayer.IsClipEnabled --- .../Server/ServerCompositionVisual.cs | 5 +- src/Avalonia.Base/composition-schema.xml | 1 + .../Primitives/AdornerLayer.cs | 5 +- .../Controls/AdornerTests.cs | 81 +++++++++++------- ...s_Properly_Clipped_Clip_False.expected.png | Bin 0 -> 694 bytes ...s_Properly_Clipped_Clip_True.expected.png} | Bin ...s_Properly_Clipped_Clip_False.expected.png | Bin 0 -> 694 bytes ...s_Properly_Clipped_Clip_True.expected.png} | Bin 8 files changed, 56 insertions(+), 36 deletions(-) create mode 100644 tests/TestFiles/Direct2D1/Controls/Adorner/Focus_Adorner_Is_Properly_Clipped_Clip_False.expected.png rename tests/TestFiles/Direct2D1/Controls/Adorner/{Focus_Adorner_Is_Properly_Clipped.expected.png => Focus_Adorner_Is_Properly_Clipped_Clip_True.expected.png} (100%) create mode 100644 tests/TestFiles/Skia/Controls/Adorner/Focus_Adorner_Is_Properly_Clipped_Clip_False.expected.png rename tests/TestFiles/Skia/Controls/Adorner/{Focus_Adorner_Is_Properly_Clipped.expected.png => Focus_Adorner_Is_Properly_Clipped_Clip_True.expected.png} (100%) diff --git a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs index e33dc999dc..98be861afa 100644 --- a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs +++ b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs @@ -48,7 +48,8 @@ namespace Avalonia.Rendering.Composition.Server { canvas.PostTransform = Matrix.Identity; canvas.Transform = Matrix.Identity; - canvas.PushClip(AdornedVisual._combinedTransformedClipBounds); + if (AdornerIsClipped) + canvas.PushClip(AdornedVisual._combinedTransformedClipBounds); } var transform = GlobalTransformMatrix; canvas.PostTransform = MatrixUtils.ToMatrix(transform); @@ -74,7 +75,7 @@ namespace Avalonia.Rendering.Composition.Server canvas.PopGeometryClip(); if (ClipToBounds && !HandlesClipToBounds) canvas.PopClip(); - if (AdornedVisual != null) + if (AdornedVisual != null && AdornerIsClipped) canvas.PopClip(); if(Opacity != 1) canvas.PopOpacity(); diff --git a/src/Avalonia.Base/composition-schema.xml b/src/Avalonia.Base/composition-schema.xml index 36fd9fe709..31722974ee 100644 --- a/src/Avalonia.Base/composition-schema.xml +++ b/src/Avalonia.Base/composition-schema.xml @@ -26,6 +26,7 @@ + diff --git a/src/Avalonia.Controls/Primitives/AdornerLayer.cs b/src/Avalonia.Controls/Primitives/AdornerLayer.cs index 79719912ea..611d57a980 100644 --- a/src/Avalonia.Controls/Primitives/AdornerLayer.cs +++ b/src/Avalonia.Controls/Primitives/AdornerLayer.cs @@ -279,8 +279,11 @@ namespace Avalonia.Controls.Primitives private void UpdateAdornedElement(Visual adorner, Visual? adorned) { if (adorner.CompositionVisual != null) + { adorner.CompositionVisual.AdornedVisual = adorned?.CompositionVisual; - + adorner.CompositionVisual.AdornerIsClipped = GetIsClipEnabled(adorner); + } + var info = adorner.GetValue(s_adornedElementInfoProperty); if (info != null) diff --git a/tests/Avalonia.RenderTests/Controls/AdornerTests.cs b/tests/Avalonia.RenderTests/Controls/AdornerTests.cs index c0159aecff..b158bf798d 100644 --- a/tests/Avalonia.RenderTests/Controls/AdornerTests.cs +++ b/tests/Avalonia.RenderTests/Controls/AdornerTests.cs @@ -1,3 +1,4 @@ +using System.Runtime.CompilerServices; using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Controls.Primitives; @@ -18,56 +19,70 @@ public class AdornerTests : TestBase { } - [Fact] - public async Task Focus_Adorner_Is_Properly_Clipped() + async Task CheckAdornedContent(Control content, Control adorned, Control adorner, int width = 200, int height = 200, + [CallerMemberName] string testName = "") { - Border adorned; var tree = new Decorator { Child = new VisualLayerManager { - Child = new Border - { - Background = Brushes.Red, - Padding = new Thickness(10, 50, 10,10), - Child = new Border() - { - Background = Brushes.White, - ClipToBounds = true, - Padding = new Thickness(0, -30, 0, 0), - Child = adorned = new Border - { - Background = Brushes.Green, - VerticalAlignment = VerticalAlignment.Top, - Height = 100, - Width = 50 - } - } - } + Child = content }, - Width = 200, - Height = 200 - }; - var adorner = new Border - { - BorderThickness = new Thickness(2), - BorderBrush = Brushes.Black + Width = width, + Height = height }; - + var size = new Size(tree.Width, tree.Height); tree.Measure(size); tree.Arrange(new Rect(size)); - - + adorned.AttachedToVisualTree += delegate { AdornerLayer.SetAdornedElement(adorner, adorned); AdornerLayer.GetAdornerLayer(adorned)!.Children.Add(adorner); }; + tree.Measure(size); tree.Arrange(new Rect(size)); - await RenderToFile(tree); - CompareImages(skipImmediate: true); + await RenderToFile(tree, testName: testName); + CompareImages(skipImmediate: true, testName: testName); + } + + [Theory, + InlineData(true), + InlineData(false) + ] + public async Task Focus_Adorner_Is_Properly_Clipped(bool clip) + { + Border adorned; + var content = new Border + { + Background = Brushes.Red, + Padding = new Thickness(10, 50, 10, 10), + Child = new Border() + { + Background = Brushes.White, + ClipToBounds = true, + Padding = new Thickness(0, -30, 0, 0), + Child = adorned = new Border + { + Background = Brushes.Green, + VerticalAlignment = VerticalAlignment.Top, + Height = 100, + Width = 50 + } + } + }; + var adorner = new Border + { + BorderThickness = new Thickness(2), + BorderBrush = Brushes.Black + }; + if (!clip) + AdornerLayer.SetIsClipEnabled(adorner, false); + await CheckAdornedContent(content, adorned, adorner, + testName: "Focus_Adorner_Is_Properly_Clipped_Clip_" + clip); } + } \ No newline at end of file diff --git a/tests/TestFiles/Direct2D1/Controls/Adorner/Focus_Adorner_Is_Properly_Clipped_Clip_False.expected.png b/tests/TestFiles/Direct2D1/Controls/Adorner/Focus_Adorner_Is_Properly_Clipped_Clip_False.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..4821c22c397099cdae149b5ed9cc367ab9844a66 GIT binary patch literal 694 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yu@pObhHwBu4M$1`0|Qg8r;B4q z#hkZyHf9|*5OD}x`Q-5D=dUhYT6t$y!XgXX^pB4oHtwjJ{Y)yE_d&S)ZuW+7H31H$ zMg<~?g4?zSrk=UWJm-iq%ki5E0yz`dW4^N0P3QgLW5&VK=paB5(egO|^SaghJgOJ{ z{JQJyp7*kk6TiP-zxj{l>HRkp1X!3H2R{J}SlM62vcKQXJ!@IsU(oeb=eR}1G&7Et z+wU0H9Xb2^|4{J=IJAMjc`L^hHHRkp1X!3H2R{J}SlM62vcKQXJ!@IsU(oeb=eR}1G&7Et z+wU0H9Xb2^|4{J=IJAMjc`L^hH