A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

224 lines
6.8 KiB

using System;
using System.Linq;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Controls.Chrome;
using Avalonia.Interactivity;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.VisualTree;
using Xunit;
namespace Avalonia.IntegrationTests.Win32;
public abstract class ExtendClientAreaWindowTests : IDisposable
{
private const double ClientWidth = 200;
private const double ClientHeight = 200;
private Window? _window;
private Window Window
{
get
{
Assert.NotNull(_window);
return _window;
}
}
protected abstract SystemDecorations Decorations { get; }
public static MatrixTheoryData<bool, WindowState> States
=> new([true, false], Enum.GetValues<WindowState>());
private async Task InitWindowAsync(WindowState state, bool canResize)
{
Assert.Null(_window);
_window = new Window
{
CanResize = canResize,
WindowState = state,
SystemDecorations = Decorations,
ExtendClientAreaToDecorationsHint = true,
ExtendClientAreaChromeHints = ExtendClientAreaChromeHints.PreferSystemChrome,
Width = ClientWidth,
Height = ClientHeight,
WindowStartupLocation = WindowStartupLocation.Manual,
Position = new PixelPoint(50, 50),
Content = new Border
{
Background = Brushes.DodgerBlue,
BorderBrush = Brushes.Yellow,
BorderThickness = new Thickness(1)
}
};
_window.Show();
await Window.WhenLoadedAsync();
}
[Theory]
[MemberData(nameof(States))]
public async Task Normal_State_Respects_Client_Size(bool canResize, WindowState initialState)
{
await InitWindowAsync(initialState, canResize);
if (initialState != WindowState.Normal)
Window.WindowState = WindowState.Normal;
// The client size should have been kept
var expected = PixelSize.FromSize(new Size(ClientWidth, ClientHeight), Window.RenderScaling);
var clientSize = Window.GetWin32ClientSize();
Assert.Equal(expected, clientSize);
VerifyNormalState(canResize);
}
protected abstract void VerifyNormalState(bool canResize);
[Theory]
[MemberData(nameof(States))]
public async Task Maximized_State_Fills_Screen_Working_Area(bool canResize, WindowState initialState)
{
await InitWindowAsync(initialState, canResize);
if (initialState != WindowState.Maximized)
Window.WindowState = WindowState.Maximized;
// The client size should match the screen working area
var clientSize = Window.GetWin32ClientSize();
var screenWorkingArea = Window.GetScreen().WorkingArea;
Assert.Equal(screenWorkingArea.Size, clientSize);
VerifyMaximizedState();
}
protected abstract void VerifyMaximizedState();
[Theory]
[MemberData(nameof(States))]
public async Task FullScreen_State_Fills_Screen(bool canResize, WindowState initialState)
{
await InitWindowAsync(initialState, canResize);
if (initialState != WindowState.FullScreen)
Window.WindowState = WindowState.FullScreen;
// The client size should match the screen bounds
var clientSize = Window.GetWin32ClientSize();
var screenBounds = Window.GetScreen().Bounds;
Assert.Equal(screenBounds.Width, clientSize.Width);
Assert.Equal(screenBounds.Height, clientSize.Height);
// The window size should also match the screen bounds
var windowBounds = Window.GetWin32WindowBounds();
Assert.Equal(screenBounds, windowBounds);
// And no visible title bar
AssertNoTitleBar();
}
protected void AssertHasBorder()
{
var clientSize = Window.GetWin32ClientSize();
var windowBounds = Window.GetWin32WindowBounds();
Assert.NotEqual(clientSize.Width, windowBounds.Width);
Assert.NotEqual(clientSize.Height, windowBounds.Height);
}
protected void AssertNoBorder()
{
var clientSize = Window.GetWin32ClientSize();
var windowBounds = Window.GetWin32WindowBounds();
Assert.Equal(clientSize.Width, windowBounds.Width);
Assert.Equal(clientSize.Height, windowBounds.Height);
}
protected (double TitleBarHeight, double ButtonsHeight) GetTitleBarInfo()
{
var titleBar = Window.GetVisualDescendants().OfType<TitleBar>().FirstOrDefault();
Assert.NotNull(titleBar);
var buttons = titleBar.GetVisualDescendants().OfType<CaptionButtons>().FirstOrDefault();
Assert.NotNull(buttons);
return (titleBar.Height, buttons.Height);
}
private void AssertNoTitleBar()
{
var (titleBarHeight, buttonsHeight) = GetTitleBarInfo();
Assert.Equal(0, titleBarHeight);
Assert.Equal(0, buttonsHeight);
}
public void Dispose()
=> _window?.Close();
public sealed class DecorationsFull : ExtendClientAreaWindowTests
{
protected override SystemDecorations Decorations
=> SystemDecorations.Full;
protected override void VerifyNormalState(bool canResize)
{
AssertHasBorder();
AssertLargeTitleBarWithButtons();
}
protected override void VerifyMaximizedState()
=> AssertLargeTitleBarWithButtons();
private void AssertLargeTitleBarWithButtons()
{
var (titleBarHeight, buttonsHeight) = GetTitleBarInfo();
Assert.True(titleBarHeight > 20);
Assert.True(buttonsHeight > 20);
}
}
public sealed class DecorationsBorderOnly : ExtendClientAreaWindowTests
{
protected override SystemDecorations Decorations
=> SystemDecorations.BorderOnly;
protected override void VerifyNormalState(bool canResize)
{
AssertHasBorder();
if (canResize)
AssertSmallTitleBarWithoutButtons();
else
AssertNoTitleBar();
}
protected override void VerifyMaximizedState()
=> AssertNoTitleBar();
private void AssertSmallTitleBarWithoutButtons()
{
var (titleBarHeight, buttonsHeight) = GetTitleBarInfo();
Assert.True(titleBarHeight < 10);
Assert.NotEqual(0, titleBarHeight);
Assert.Equal(0, buttonsHeight);
}
}
public sealed class DecorationsNone : ExtendClientAreaWindowTests
{
protected override SystemDecorations Decorations
=> SystemDecorations.None;
protected override void VerifyNormalState(bool canResize)
{
AssertNoBorder();
AssertNoTitleBar();
}
protected override void VerifyMaximizedState()
=> AssertNoTitleBar();
}
}