Browse Source
* Add unit tests for decoration hit testing * Fix chrome hit testing * macOS: handle TitleBar element rolepull/21219/head
committed by
GitHub
5 changed files with 155 additions and 14 deletions
@ -0,0 +1,147 @@ |
|||
using System; |
|||
using Avalonia.Controls.Chrome; |
|||
using Avalonia.Controls.Platform; |
|||
using Avalonia.Controls.Templates; |
|||
using Avalonia.Input; |
|||
using Avalonia.Markup.Xaml.Templates; |
|||
using Avalonia.Media; |
|||
using Avalonia.Styling; |
|||
using Avalonia.Threading; |
|||
using Avalonia.UnitTests; |
|||
using Avalonia.VisualTree; |
|||
using Xunit; |
|||
|
|||
namespace Avalonia.Controls.UnitTests; |
|||
|
|||
public sealed class PresentationSourceTests : ScopedTestBase |
|||
{ |
|||
[Fact] |
|||
public void ChromeHitTest_Prefers_Overlay_Over_Content() |
|||
{ |
|||
var overlay = new Border |
|||
{ |
|||
Background = Brushes.Red, |
|||
[WindowDecorationProperties.ElementRoleProperty] = WindowDecorationsElementRole.TitleBar |
|||
}; |
|||
|
|||
var content = new Border |
|||
{ |
|||
Background = Brushes.Blue |
|||
}; |
|||
|
|||
DoChromeHitTest( |
|||
underlay: null, |
|||
content: content, |
|||
overlay: overlay, |
|||
expectedChromeVisual: overlay, |
|||
expectedRole: WindowDecorationsElementRole.TitleBar); |
|||
} |
|||
|
|||
[Fact] |
|||
public void ChromeHitTest_Prefers_Content_Over_Underlay() |
|||
{ |
|||
var underlay = new Border |
|||
{ |
|||
Background = Brushes.Red, |
|||
[WindowDecorationProperties.ElementRoleProperty] = WindowDecorationsElementRole.TitleBar |
|||
}; |
|||
|
|||
var content = new Border |
|||
{ |
|||
Background = Brushes.Blue |
|||
}; |
|||
|
|||
DoChromeHitTest( |
|||
underlay: underlay, |
|||
content: content, |
|||
overlay: null, |
|||
expectedChromeVisual: content, |
|||
expectedRole: null); |
|||
} |
|||
|
|||
private static void DoChromeHitTest( |
|||
Control? underlay, |
|||
Control? content, |
|||
Control? overlay, |
|||
Visual? expectedChromeVisual, |
|||
WindowDecorationsElementRole? expectedRole) |
|||
{ |
|||
const double width = 100; |
|||
const double height = 100; |
|||
|
|||
if (underlay is not null) |
|||
{ |
|||
underlay.Width = width; |
|||
underlay.Height = height; |
|||
} |
|||
|
|||
if (content is not null) |
|||
{ |
|||
content.Width = width; |
|||
content.Height = height; |
|||
} |
|||
|
|||
if (overlay is not null) |
|||
{ |
|||
overlay.Width = width; |
|||
overlay.Height = height; |
|||
} |
|||
|
|||
using var app = UnitTestApplication.Start(TestServices.StyledWindow); |
|||
|
|||
var decorations = new WindowDrawnDecorationsContent |
|||
{ |
|||
Underlay = underlay, |
|||
Overlay = overlay |
|||
}; |
|||
|
|||
Application.Current!.Resources.Add(typeof(WindowDrawnDecorations), CreateDecorationsTheme(decorations)); |
|||
|
|||
var renderTimer = new CompositorTestServices.ManualRenderTimer(); |
|||
var compositor = RendererMocks.CreateDummyCompositor(renderTimer); |
|||
var windowImpl = MockWindowingPlatform.CreateWindowMock(width, height, compositor); |
|||
windowImpl.Setup(w => w.IsClientAreaExtendedToDecorations).Returns(true); |
|||
windowImpl.Setup(w => w.RequestedDrawnDecorations).Returns(PlatformRequestedDrawnDecoration.TitleBar); |
|||
windowImpl.Setup(w => w.NeedsManagedDecorations).Returns(true); |
|||
|
|||
var window = new Window(windowImpl.Object) |
|||
{ |
|||
WindowDecorations = WindowDecorations.Full, |
|||
ExtendClientAreaToDecorationsHint = true, |
|||
Content = content |
|||
}; |
|||
|
|||
window.Show(); |
|||
|
|||
Dispatcher.CurrentDispatcher.RunJobs(null, TestContext.Current.CancellationToken); |
|||
renderTimer.TriggerTick(); |
|||
Dispatcher.CurrentDispatcher.RunJobs(null, TestContext.Current.CancellationToken); |
|||
|
|||
var hitTestPoint = new Point(width / 2, height / 2); |
|||
|
|||
var clientVisual = window.GetVisualAt(hitTestPoint); |
|||
Assert.Same(window.Content, clientVisual); |
|||
|
|||
var chromeVisual = window.PresentationSource.RootVisual.GetVisualAt(hitTestPoint); |
|||
Assert.Same(expectedChromeVisual, chromeVisual); |
|||
|
|||
var chromeRole = ((IInputRoot)window.PresentationSource).HitTestChromeElement(hitTestPoint); |
|||
Assert.Equal(expectedRole, chromeRole); |
|||
} |
|||
|
|||
private static ControlTheme CreateDecorationsTheme(WindowDrawnDecorationsContent content) |
|||
{ |
|||
var template = new WindowDrawnDecorationsTemplate |
|||
{ |
|||
Content = (IServiceProvider? _) => new TemplateResult<WindowDrawnDecorationsContent>(content, new NameScope()) |
|||
}; |
|||
|
|||
return new ControlTheme(typeof(WindowDrawnDecorations)) |
|||
{ |
|||
Setters = |
|||
{ |
|||
new Setter(WindowDrawnDecorations.TemplateProperty, template) |
|||
} |
|||
}; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue