Browse Source

Merge branch 'master' into api-stability-attributes

pull/8049/head
Benedikt Stebner 4 years ago
committed by GitHub
parent
commit
cb7fa3a507
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      build/CoreLibraries.props
  2. 1
      samples/BindingDemo/BindingDemo.csproj
  3. 2
      samples/ControlCatalog/ControlCatalog.csproj
  4. 3
      samples/IntegrationTestApp/IntegrationTestApp.csproj
  5. 1
      samples/PlatformSanityChecks/PlatformSanityChecks.csproj
  6. 3
      samples/Previewer/Previewer.csproj
  7. 1
      samples/RenderDemo/RenderDemo.csproj
  8. 1
      samples/Sandbox/Sandbox.csproj
  9. 1
      samples/VirtualizationDemo/VirtualizationDemo.csproj
  10. 1
      samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj
  11. 1
      samples/interop/NativeEmbedSample/NativeEmbedSample.csproj
  12. 53
      src/Avalonia.Controls/Viewbox.cs
  13. 13
      src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs
  14. 6
      src/Avalonia.FreeDesktop/NativeMethods.cs
  15. 104
      tests/Avalonia.Controls.UnitTests/ViewboxTests.cs

2
build/CoreLibraries.props

@ -3,8 +3,6 @@
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Base/Avalonia.Base.csproj" /> <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Base/Avalonia.Base.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Controls/Avalonia.Controls.csproj" /> <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Controls/Avalonia.Controls.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj" /> <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Themes.Fluent/Avalonia.Themes.Fluent.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.OpenGL/Avalonia.OpenGL.csproj" /> <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.OpenGL/Avalonia.OpenGL.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Dialogs/Avalonia.Dialogs.csproj" /> <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Dialogs/Avalonia.Dialogs.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Markup/Avalonia.Markup/Avalonia.Markup.csproj" /> <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Markup/Avalonia.Markup/Avalonia.Markup.csproj" />

1
samples/BindingDemo/BindingDemo.csproj

@ -5,6 +5,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" />
<ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" /> <ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" />
<ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" /> <ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" />
</ItemGroup> </ItemGroup>

2
samples/ControlCatalog/ControlCatalog.csproj

@ -25,6 +25,8 @@
<ProjectReference Include="..\..\packages\Avalonia\Avalonia.csproj" /> <ProjectReference Include="..\..\packages\Avalonia\Avalonia.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Controls.ColorPicker\Avalonia.Controls.ColorPicker.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Controls.ColorPicker\Avalonia.Controls.ColorPicker.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Controls.DataGrid\Avalonia.Controls.DataGrid.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Controls.DataGrid\Avalonia.Controls.DataGrid.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Fluent\Avalonia.Themes.Fluent.csproj" />
<ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" /> <ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" />
<ProjectReference Include="..\SampleControls\ControlSamples.csproj" /> <ProjectReference Include="..\SampleControls\ControlSamples.csproj" />
</ItemGroup> </ItemGroup>

3
samples/IntegrationTestApp/IntegrationTestApp.csproj

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
@ -18,6 +18,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Fluent\Avalonia.Themes.Fluent.csproj" />
</ItemGroup> </ItemGroup>
<Import Project="..\..\build\BuildTargets.targets" /> <Import Project="..\..\build\BuildTargets.targets" />

1
samples/PlatformSanityChecks/PlatformSanityChecks.csproj

@ -7,6 +7,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.Desktop\Avalonia.Desktop.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Desktop\Avalonia.Desktop.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" />
<ProjectReference Include="..\..\src\Avalonia.X11\Avalonia.X11.csproj" /> <ProjectReference Include="..\..\src\Avalonia.X11\Avalonia.X11.csproj" />
</ItemGroup> </ItemGroup>

3
samples/Previewer/Previewer.csproj

@ -9,6 +9,9 @@
</Compile> </Compile>
<EmbeddedResource Include="**\*.xaml" /> <EmbeddedResource Include="**\*.xaml" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" />
</ItemGroup>
<Import Project="..\..\build\SampleApp.props" /> <Import Project="..\..\build\SampleApp.props" />
<Import Project="..\..\build\ReferenceCoreLibraries.props" /> <Import Project="..\..\build\ReferenceCoreLibraries.props" />

1
samples/RenderDemo/RenderDemo.csproj

@ -12,6 +12,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Fluent\Avalonia.Themes.Fluent.csproj" />
<ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" /> <ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" />
<ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" /> <ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" />
<ProjectReference Include="..\SampleControls\ControlSamples.csproj" /> <ProjectReference Include="..\SampleControls\ControlSamples.csproj" />

1
samples/Sandbox/Sandbox.csproj

@ -10,6 +10,7 @@
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Controls.ColorPicker\Avalonia.Controls.ColorPicker.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Controls.ColorPicker\Avalonia.Controls.ColorPicker.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Controls.DataGrid\Avalonia.Controls.DataGrid.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Controls.DataGrid\Avalonia.Controls.DataGrid.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Fluent\Avalonia.Themes.Fluent.csproj" />
</ItemGroup> </ItemGroup>
<Import Project="..\..\build\SampleApp.props" /> <Import Project="..\..\build\SampleApp.props" />

1
samples/VirtualizationDemo/VirtualizationDemo.csproj

@ -5,6 +5,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" /> <ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" />
<ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" /> <ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" />
<ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" /> <ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" />
</ItemGroup> </ItemGroup>

1
samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj

@ -22,6 +22,7 @@
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" />
<ProjectReference Include="..\..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj" /> <ProjectReference Include="..\..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj" />
<ProjectReference Include="..\..\..\src\Windows\Avalonia.Win32\Avalonia.Win32.csproj" /> <ProjectReference Include="..\..\..\src\Windows\Avalonia.Win32\Avalonia.Win32.csproj" />
<ProjectReference Include="..\..\MiniMvvm\MiniMvvm.csproj" /> <ProjectReference Include="..\..\MiniMvvm\MiniMvvm.csproj" />

1
samples/interop/NativeEmbedSample/NativeEmbedSample.csproj

@ -9,6 +9,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="MonoMac.NetStandard" Version="0.0.4" /> <PackageReference Include="MonoMac.NetStandard" Version="0.0.4" />
<ProjectReference Include="..\..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" />
<ProjectReference Include="..\..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj" /> <ProjectReference Include="..\..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj" />
<ProjectReference Include="..\..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" /> <ProjectReference Include="..\..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
<ProjectReference Include="..\..\..\src\Avalonia.X11\Avalonia.X11.csproj" /> <ProjectReference Include="..\..\..\src\Avalonia.X11\Avalonia.X11.csproj" />

53
src/Avalonia.Controls/Viewbox.cs

@ -1,4 +1,5 @@
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Media.Immutable;
using Avalonia.Metadata; using Avalonia.Metadata;
namespace Avalonia.Controls namespace Avalonia.Controls
@ -8,7 +9,7 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public class Viewbox : Control public class Viewbox : Control
{ {
private Decorator _containerVisual; private readonly ViewboxContainer _containerVisual;
/// <summary> /// <summary>
/// Defines the <see cref="Stretch"/> property. /// Defines the <see cref="Stretch"/> property.
@ -37,9 +38,10 @@ namespace Avalonia.Controls
public Viewbox() public Viewbox()
{ {
_containerVisual = new Decorator(); // The Child control is hosted inside a ViewboxContainer control so that the transform
// can be applied independently of the Viewbox and Child transforms.
_containerVisual = new ViewboxContainer();
_containerVisual.RenderTransformOrigin = RelativePoint.TopLeft; _containerVisual.RenderTransformOrigin = RelativePoint.TopLeft;
LogicalChildren.Add(_containerVisual);
VisualChildren.Add(_containerVisual); VisualChildren.Add(_containerVisual);
} }
@ -88,7 +90,22 @@ namespace Avalonia.Controls
if (change.Property == ChildProperty) if (change.Property == ChildProperty)
{ {
_containerVisual.Child = change.GetNewValue<IControl>(); var (oldChild, newChild) = change.GetOldAndNewValue<IControl>();
if (oldChild is not null)
{
((ISetLogicalParent)oldChild).SetParent(null);
LogicalChildren.Remove(oldChild);
}
_containerVisual.Child = newChild;
if (newChild is not null)
{
((ISetLogicalParent)newChild).SetParent(this);
LogicalChildren.Add(newChild);
}
InvalidateMeasure(); InvalidateMeasure();
} }
} }
@ -120,7 +137,7 @@ namespace Avalonia.Controls
var childSize = child.DesiredSize; var childSize = child.DesiredSize;
var scale = Stretch.CalculateScaling(finalSize, childSize, StretchDirection); var scale = Stretch.CalculateScaling(finalSize, childSize, StretchDirection);
InternalTransform = new ScaleTransform(scale.X, scale.Y); InternalTransform = new ImmutableTransform(Matrix.CreateScale(scale.X, scale.Y));
child.Arrange(new Rect(childSize)); child.Arrange(new Rect(childSize));
@ -129,5 +146,31 @@ namespace Avalonia.Controls
return finalSize; return finalSize;
} }
/// <summary>
/// A simple container control which hosts its child as a visual but not logical child.
/// </summary>
private class ViewboxContainer : Control
{
private IControl? _child;
public IControl? Child
{
get => _child;
set
{
if (_child != value)
{
if (_child is not null)
VisualChildren.Remove(_child);
_child = value;
if (_child is not null)
VisualChildren.Add(_child);
}
}
}
}
} }
} }

13
src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs

@ -36,6 +36,13 @@ namespace Avalonia.FreeDesktop
private string GetSymlinkTarget(string x) => Path.GetFullPath(Path.Combine(DevByLabelDir, NativeMethods.ReadLink(x))); private string GetSymlinkTarget(string x) => Path.GetFullPath(Path.Combine(DevByLabelDir, NativeMethods.ReadLink(x)));
private string UnescapeString(string input, string regexText, int escapeBase) =>
new Regex(regexText).Replace(input, m => Convert.ToChar(Convert.ToByte(m.Groups[1].Value, escapeBase)).ToString());
private string UnescapePathFromProcMounts(string input) => UnescapeString(input, @"\\(\d{3})", 8);
private string UnescapeDeviceLabel(string input) => UnescapeString(input, @"\\x([0-9a-f]{2})", 16);
private void Poll(long _) private void Poll(long _)
{ {
var fProcPartitions = File.ReadAllLines(ProcPartitionsDir) var fProcPartitions = File.ReadAllLines(ProcPartitionsDir)
@ -47,14 +54,14 @@ namespace Avalonia.FreeDesktop
var fProcMounts = File.ReadAllLines(ProcMountsDir) var fProcMounts = File.ReadAllLines(ProcMountsDir)
.Select(x => x.Split(' ')) .Select(x => x.Split(' '))
.Select(x => (x[0], x[1])) .Select(x => (x[0], UnescapePathFromProcMounts(x[1])))
.Where(x => !x.Item2.StartsWith("/snap/", StringComparison.InvariantCultureIgnoreCase)); .Where(x => !x.Item2.StartsWith("/snap/", StringComparison.InvariantCultureIgnoreCase));
var labelDirEnum = Directory.Exists(DevByLabelDir) ? var labelDirEnum = Directory.Exists(DevByLabelDir) ?
new DirectoryInfo(DevByLabelDir).GetFiles() : Enumerable.Empty<FileInfo>(); new DirectoryInfo(DevByLabelDir).GetFiles() : Enumerable.Empty<FileInfo>();
var labelDevPathPairs = labelDirEnum var labelDevPathPairs = labelDirEnum
.Select(x => (GetSymlinkTarget(x.FullName), x.Name)); .Select(x => (GetSymlinkTarget(x.FullName), UnescapeDeviceLabel(x.Name)));
var q1 = from mount in fProcMounts var q1 = from mount in fProcMounts
join device in fProcPartitions on mount.Item1 equals device.Item2 join device in fProcPartitions on mount.Item1 equals device.Item2
@ -64,7 +71,7 @@ namespace Avalonia.FreeDesktop
{ {
VolumePath = mount.Item2, VolumePath = mount.Item2,
VolumeSizeBytes = device.Item1, VolumeSizeBytes = device.Item1,
VolumeLabel = x.Name VolumeLabel = x.Item2
}; };
var mountVolInfos = q1.ToArray(); var mountVolInfos = q1.ToArray();

6
src/Avalonia.FreeDesktop/NativeMethods.cs

@ -14,15 +14,15 @@ namespace Avalonia.FreeDesktop
public static string ReadLink(string path) public static string ReadLink(string path)
{ {
var symlinkMaxSize = Encoding.ASCII.GetMaxByteCount(path.Length); var symlinkSize = Encoding.UTF8.GetByteCount(path);
var bufferSize = 4097; // PATH_MAX is (usually?) 4096, but we need to know if the result was truncated var bufferSize = 4097; // PATH_MAX is (usually?) 4096, but we need to know if the result was truncated
var symlink = ArrayPool<byte>.Shared.Rent(symlinkMaxSize + 1); var symlink = ArrayPool<byte>.Shared.Rent(symlinkSize + 1);
var buffer = ArrayPool<byte>.Shared.Rent(bufferSize); var buffer = ArrayPool<byte>.Shared.Rent(bufferSize);
try try
{ {
var symlinkSize = Encoding.UTF8.GetBytes(path, 0, path.Length, symlink, 0); Encoding.UTF8.GetBytes(path, 0, path.Length, symlink, 0);
symlink[symlinkSize] = 0; symlink[symlinkSize] = 0;
var size = readlink(symlink, buffer, bufferSize); var size = readlink(symlink, buffer, bufferSize);

104
tests/Avalonia.Controls.UnitTests/ViewboxTests.cs

@ -1,4 +1,5 @@
using Avalonia.Controls.Shapes; using Avalonia.Controls.Shapes;
using Avalonia.LogicalTree;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.UnitTests; using Avalonia.UnitTests;
using Xunit; using Xunit;
@ -18,11 +19,10 @@ namespace Avalonia.Controls.UnitTests
target.Arrange(new Rect(new Point(0, 0), target.DesiredSize)); target.Arrange(new Rect(new Point(0, 0), target.DesiredSize));
Assert.Equal(new Size(200, 100), target.DesiredSize); Assert.Equal(new Size(200, 100), target.DesiredSize);
var scaleTransform = target.InternalTransform as ScaleTransform;
Assert.True(TryGetScale(target, out Vector scale));
Assert.NotNull(scaleTransform); Assert.Equal(2.0, scale.X);
Assert.Equal(2.0, scaleTransform.ScaleX); Assert.Equal(2.0, scale.Y);
Assert.Equal(2.0, scaleTransform.ScaleY);
} }
[Fact] [Fact]
@ -36,11 +36,10 @@ namespace Avalonia.Controls.UnitTests
target.Arrange(new Rect(new Point(0, 0), target.DesiredSize)); target.Arrange(new Rect(new Point(0, 0), target.DesiredSize));
Assert.Equal(new Size(100, 50), target.DesiredSize); Assert.Equal(new Size(100, 50), target.DesiredSize);
var scaleTransform = target.InternalTransform as ScaleTransform;
Assert.True(TryGetScale(target, out Vector scale));
Assert.NotNull(scaleTransform); Assert.Equal(1.0, scale.X);
Assert.Equal(1.0, scaleTransform.ScaleX); Assert.Equal(1.0, scale.Y);
Assert.Equal(1.0, scaleTransform.ScaleY);
} }
[Fact] [Fact]
@ -54,11 +53,10 @@ namespace Avalonia.Controls.UnitTests
target.Arrange(new Rect(new Point(0, 0), target.DesiredSize)); target.Arrange(new Rect(new Point(0, 0), target.DesiredSize));
Assert.Equal(new Size(200, 200), target.DesiredSize); Assert.Equal(new Size(200, 200), target.DesiredSize);
var scaleTransform = target.InternalTransform as ScaleTransform;
Assert.True(TryGetScale(target, out Vector scale));
Assert.NotNull(scaleTransform); Assert.Equal(2.0, scale.X);
Assert.Equal(2.0, scaleTransform.ScaleX); Assert.Equal(4.0, scale.Y);
Assert.Equal(4.0, scaleTransform.ScaleY);
} }
[Fact] [Fact]
@ -72,11 +70,10 @@ namespace Avalonia.Controls.UnitTests
target.Arrange(new Rect(new Point(0, 0), target.DesiredSize)); target.Arrange(new Rect(new Point(0, 0), target.DesiredSize));
Assert.Equal(new Size(200, 200), target.DesiredSize); Assert.Equal(new Size(200, 200), target.DesiredSize);
var scaleTransform = target.InternalTransform as ScaleTransform;
Assert.True(TryGetScale(target, out Vector scale));
Assert.NotNull(scaleTransform); Assert.Equal(4.0, scale.X);
Assert.Equal(4.0, scaleTransform.ScaleX); Assert.Equal(4.0, scale.Y);
Assert.Equal(4.0, scaleTransform.ScaleY);
} }
[Fact] [Fact]
@ -90,11 +87,10 @@ namespace Avalonia.Controls.UnitTests
target.Arrange(new Rect(new Point(0, 0), target.DesiredSize)); target.Arrange(new Rect(new Point(0, 0), target.DesiredSize));
Assert.Equal(new Size(400, 200), target.DesiredSize); Assert.Equal(new Size(400, 200), target.DesiredSize);
var scaleTransform = target.InternalTransform as ScaleTransform;
Assert.True(TryGetScale(target, out Vector scale));
Assert.NotNull(scaleTransform); Assert.Equal(4.0, scale.X);
Assert.Equal(4.0, scaleTransform.ScaleX); Assert.Equal(4.0, scale.Y);
Assert.Equal(4.0, scaleTransform.ScaleY);
} }
[Fact] [Fact]
@ -108,11 +104,10 @@ namespace Avalonia.Controls.UnitTests
target.Arrange(new Rect(new Point(0, 0), target.DesiredSize)); target.Arrange(new Rect(new Point(0, 0), target.DesiredSize));
Assert.Equal(new Size(200, 100), target.DesiredSize); Assert.Equal(new Size(200, 100), target.DesiredSize);
var scaleTransform = target.InternalTransform as ScaleTransform;
Assert.True(TryGetScale(target, out Vector scale));
Assert.NotNull(scaleTransform); Assert.Equal(2.0, scale.X);
Assert.Equal(2.0, scaleTransform.ScaleX); Assert.Equal(2.0, scale.Y);
Assert.Equal(2.0, scaleTransform.ScaleY);
} }
[Theory] [Theory]
@ -136,11 +131,9 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal(new Size(expectedWidth, expectedHeight), target.DesiredSize); Assert.Equal(new Size(expectedWidth, expectedHeight), target.DesiredSize);
var scaleTransform = target.InternalTransform as ScaleTransform; Assert.True(TryGetScale(target, out Vector scale));
Assert.Equal(expectedScale, scale.X);
Assert.NotNull(scaleTransform); Assert.Equal(expectedScale, scale.Y);
Assert.Equal(expectedScale, scaleTransform.ScaleX);
Assert.Equal(expectedScale, scaleTransform.ScaleY);
} }
[Theory] [Theory]
@ -164,11 +157,44 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal(new Size(expectedWidth, expectedHeight), target.DesiredSize); Assert.Equal(new Size(expectedWidth, expectedHeight), target.DesiredSize);
var scaleTransform = target.InternalTransform as ScaleTransform; Assert.True(TryGetScale(target, out Vector scale));
Assert.Equal(expectedScale, scale.X);
Assert.Equal(expectedScale, scale.Y);
}
[Fact]
public void Child_Should_Be_Logical_Child_Of_Viewbox()
{
var target = new Viewbox();
Assert.Empty(target.GetLogicalChildren());
var child = new Canvas();
target.Child = child;
Assert.Single(target.GetLogicalChildren(), child);
Assert.Same(child.GetLogicalParent(), target);
target.Child = null;
Assert.Empty(target.GetLogicalChildren());
Assert.Null(child.GetLogicalParent());
}
private bool TryGetScale(Viewbox viewbox, out Vector scale)
{
if (viewbox.InternalTransform is null)
{
scale = default;
return false;
}
var matrix = viewbox.InternalTransform.Value;
Matrix.TryDecomposeTransform(matrix, out var decomposed);
Assert.NotNull(scaleTransform); scale = decomposed.Scale;
Assert.Equal(expectedScale, scaleTransform.ScaleX); return true;
Assert.Equal(expectedScale, scaleTransform.ScaleY);
} }
} }
} }

Loading…
Cancel
Save