diff --git a/.gitignore b/.gitignore
index e67d986a8a..a9a8fd36b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -176,3 +176,5 @@ nuget
Avalonia.XBuild.sln
project.lock.json
.idea/*
+**/obj-Skia/*
+**/obj-Direct2D1/*
diff --git a/.ncrunch/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject b/.ncrunch/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject
index a8c3abe8f2..04ab17c4e1 100644
--- a/.ncrunch/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject
+++ b/.ncrunch/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject
@@ -1,7 +1,6 @@
- 1000
- True
+ 3000
True
\ No newline at end of file
diff --git a/appveyor.yml b/appveyor.yml
index ba3680d0b9..76d1ae3e1c 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
-os: Previous Visual Studio 2017
+os: Visual Studio 2017
platform:
- Any CPU
skip_branch_with_pr: true
diff --git a/build.cake b/build.cake
index eb5918832e..61fda13695 100644
--- a/build.cake
+++ b/build.cake
@@ -93,7 +93,7 @@ Task("Clean")
CleanDirectory(parameters.NugetRoot);
CleanDirectory(parameters.ZipRoot);
CleanDirectory(parameters.BinRoot);
- CleanDirectory(parameters.TestsRoot);
+ CleanDirectory(parameters.DesignerTestsRoot);
});
Task("Restore-NuGet-Packages")
@@ -124,14 +124,9 @@ Task("Restore-NuGet-Packages")
void DotNetCoreBuild()
{
- DotNetCoreRestore("samples\\ControlCatalog.NetCore");
- DotNetBuild("samples\\ControlCatalog.NetCore");
+ DotNetCoreBuild("samples\\ControlCatalog.NetCore");
}
-Task("DotNetCoreBuild")
- .IsDependentOn("Clean")
- .Does(() => DotNetCoreBuild());
-
Task("Build")
.IsDependentOn("Restore-NuGet-Packages")
.Does(() =>
@@ -140,11 +135,11 @@ Task("Build")
{
MSBuild(parameters.MSBuildSolution, settings => {
settings.SetConfiguration(parameters.Configuration);
+ settings.SetVerbosity(Verbosity.Minimal);
settings.WithProperty("Platform", "\"" + parameters.Platform + "\"");
settings.WithProperty("UseRoslynPathHack", "true");
- settings.SetVerbosity(Verbosity.Minimal);
- settings.WithProperty("Windows", "True");
settings.UseToolVersion(MSBuildToolVersion.VS2017);
+ settings.WithProperty("Windows", "True");
settings.SetNodeReuse(false);
});
}
@@ -160,10 +155,9 @@ void RunCoreTest(string project, Parameters parameters, bool coreOnly = false)
if(!project.EndsWith(".csproj"))
project = System.IO.Path.Combine(project, System.IO.Path.GetFileName(project)+".csproj");
Information("Running tests from " + project);
- DotNetCoreRestore(project);
var frameworks = new List(){"netcoreapp2.0"};
if(parameters.IsRunningOnWindows)
- frameworks.Add("net461");
+ frameworks.Add("net47");
foreach(var fw in frameworks)
{
if(!fw.StartsWith("netcoreapp") && coreOnly)
@@ -178,8 +172,11 @@ void RunCoreTest(string project, Parameters parameters, bool coreOnly = false)
}
}
-Task("Run-Net-Core-Unit-Tests")
- .IsDependentOn("Clean")
+Task("Run-Unit-Tests")
+ .IsDependentOn("Build")
+ .IsDependentOn("Run-Designer-Unit-Tests")
+ .IsDependentOn("Run-Render-Tests")
+ .WithCriteria(() => !parameters.SkipTests)
.Does(() => {
RunCoreTest("./tests/Avalonia.Base.UnitTests", parameters, false);
RunCoreTest("./tests/Avalonia.Controls.UnitTests", parameters, false);
@@ -190,27 +187,25 @@ Task("Run-Net-Core-Unit-Tests")
RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests", parameters, false);
RunCoreTest("./tests/Avalonia.Styling.UnitTests", parameters, false);
RunCoreTest("./tests/Avalonia.Visuals.UnitTests", parameters, false);
- if(parameters.IsRunningOnWindows)
- RunCoreTest("./tests/Avalonia.RenderTests/Avalonia.Skia.RenderTests.csproj", parameters, true);
+ if (parameters.IsRunningOnWindows)
+ {
+ RunCoreTest("./tests/Avalonia.Direct2D1.UnitTests", parameters, true);
+ }
});
-Task("Run-Unit-Tests")
- .IsDependentOn("Run-Net-Core-Unit-Tests")
+Task("Run-Render-Tests")
.IsDependentOn("Build")
- //.IsDependentOn("Run-Leak-Tests")
- .WithCriteria(() => !parameters.SkipTests)
+ .WithCriteria(() => !parameters.SkipTests && parameters.IsRunningOnWindows)
+ .Does(() => {
+ RunCoreTest("./tests/Avalonia.RenderTests/Avalonia.Skia.RenderTests.csproj", parameters, true);
+ RunCoreTest("./tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.csproj", parameters, true);
+ });
+
+Task("Run-Designer-Unit-Tests")
+ .IsDependentOn("Build")
+ .WithCriteria(() => !parameters.SkipTests && parameters.IsRunningOnWindows)
.Does(() =>
{
- if(!parameters.IsRunningOnWindows)
- return;
-
- var unitTests = GetDirectories("./tests/Avalonia.*.UnitTests")
- .Select(dir => System.IO.Path.GetFileName(dir.FullPath))
- .Where( name => !name.Contains("Skia")) // Run in the Run-Net-Core-Unit-Tests target
- .Where(name => parameters.IsRunningOnWindows ? true : !name.Contains("Direct2D"))
- .Select(name => MakeAbsolute(File("./tests/" + name + "/bin/" + parameters.DirSuffix + "/" + name + ".dll")))
- .ToList();
-
var toolPath = (parameters.IsPlatformAnyCPU || parameters.IsPlatformX86) ?
Context.Tools.Resolve("xunit.console.x86.exe") :
Context.Tools.Resolve("xunit.console.exe");
@@ -219,27 +214,10 @@ Task("Run-Unit-Tests")
{
ToolPath = toolPath,
Parallelism = ParallelismOption.None,
- ShadowCopy = false
+ ShadowCopy = false,
};
- xUnitSettings.NoAppDomain = !parameters.IsRunningOnWindows;
-
- foreach(var test in unitTests.Where(testFile => FileExists(testFile)))
- {
- CopyDirectory(test.GetDirectory(), parameters.TestsRoot);
- }
-
- var testsInDirectoryToRun = new List();
- if(parameters.IsRunningOnWindows)
- {
- testsInDirectoryToRun.AddRange(GetFiles("./artifacts/tests/*Tests.dll"));
- }
- else
- {
- testsInDirectoryToRun.AddRange(GetFiles("./artifacts/tests/*.UnitTests.dll"));
- }
-
- XUnit2(testsInDirectoryToRun, xUnitSettings);
+ XUnit2("./artifacts/designer-tests/Avalonia.DesignerSupport.Tests.dll", xUnitSettings);
});
Task("Copy-Files")
@@ -427,7 +405,7 @@ Task("Default").Does(() =>
if(parameters.IsRunningOnWindows)
RunTarget("Package");
else
- RunTarget("Run-Net-Core-Unit-Tests");
+ RunTarget("Run-Unit-Tests");
});
Task("AppVeyor")
.IsDependentOn("Zip-Files")
@@ -435,7 +413,7 @@ Task("AppVeyor")
.IsDependentOn("Publish-NuGet");
Task("Travis")
- .IsDependentOn("Run-Net-Core-Unit-Tests");
+ .IsDependentOn("Run-Unit-Tests");
///////////////////////////////////////////////////////////////////////////////
// EXECUTE
diff --git a/parameters.cake b/parameters.cake
index 7406618763..c727b3107f 100644
--- a/parameters.cake
+++ b/parameters.cake
@@ -30,7 +30,7 @@ public class Parameters
public DirectoryPath NugetRoot { get; private set; }
public DirectoryPath ZipRoot { get; private set; }
public DirectoryPath BinRoot { get; private set; }
- public DirectoryPath TestsRoot { get; private set; }
+ public DirectoryPath DesignerTestsRoot { get; private set; }
public string DirSuffix { get; private set; }
public string DirSuffixIOS { get; private set; }
public DirectoryPathCollection BuildDirs { get; private set; }
@@ -106,7 +106,7 @@ public class Parameters
NugetRoot = ArtifactsDir.Combine("nuget");
ZipRoot = ArtifactsDir.Combine("zip");
BinRoot = ArtifactsDir.Combine("bin");
- TestsRoot = ArtifactsDir.Combine("tests");
+ DesignerTestsRoot = ArtifactsDir.Combine("designer-tests");
BuildDirs = context.GetDirectories("**/bin") + context.GetDirectories("**/obj");
diff --git a/samples/BindingTest/App.config b/samples/BindingTest/App.config
index 373b3a13f8..538be69997 100644
--- a/samples/BindingTest/App.config
+++ b/samples/BindingTest/App.config
@@ -1,7 +1,7 @@
-
+
diff --git a/samples/BindingTest/BindingTest.csproj b/samples/BindingTest/BindingTest.csproj
index 9f3fed5522..a17fe0eed1 100644
--- a/samples/BindingTest/BindingTest.csproj
+++ b/samples/BindingTest/BindingTest.csproj
@@ -9,7 +9,7 @@
Properties
BindingTest
BindingTest
- v4.6.1
+ v4.7
512
true
diff --git a/samples/ControlCatalog.Desktop/App.config b/samples/ControlCatalog.Desktop/App.config
index 68403e421f..cd4593817b 100644
--- a/samples/ControlCatalog.Desktop/App.config
+++ b/samples/ControlCatalog.Desktop/App.config
@@ -1,7 +1,7 @@
-
+
diff --git a/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj b/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
index cfa2f89b0e..8a5959e361 100644
--- a/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
+++ b/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
@@ -9,7 +9,7 @@
Properties
ControlCatalog.Desktop
ControlCatalog.Desktop
- v4.6.1
+ v4.7
512
true
diff --git a/samples/RenderTest/App.config b/samples/RenderTest/App.config
index 68403e421f..cd4593817b 100644
--- a/samples/RenderTest/App.config
+++ b/samples/RenderTest/App.config
@@ -1,7 +1,7 @@
-
+
diff --git a/samples/RenderTest/RenderTest.csproj b/samples/RenderTest/RenderTest.csproj
index 4a471a831a..b33d5d3c70 100644
--- a/samples/RenderTest/RenderTest.csproj
+++ b/samples/RenderTest/RenderTest.csproj
@@ -9,7 +9,7 @@
Properties
RenderTest
RenderTest
- v4.6.1
+ v4.7
512
true
diff --git a/samples/VirtualizationTest/App.config b/samples/VirtualizationTest/App.config
index 68403e421f..cd4593817b 100644
--- a/samples/VirtualizationTest/App.config
+++ b/samples/VirtualizationTest/App.config
@@ -1,7 +1,7 @@
-
+
diff --git a/samples/VirtualizationTest/VirtualizationTest.csproj b/samples/VirtualizationTest/VirtualizationTest.csproj
index 147355aed1..0d498d827f 100644
--- a/samples/VirtualizationTest/VirtualizationTest.csproj
+++ b/samples/VirtualizationTest/VirtualizationTest.csproj
@@ -9,7 +9,7 @@
Properties
VirtualizationTest
VirtualizationTest
- v4.6.1
+ v4.7
512
true
diff --git a/scripts/ReplaceNugetCache.ps1 b/scripts/ReplaceNugetCache.ps1
index 4ad31db274..a03d442bff 100644
--- a/scripts/ReplaceNugetCache.ps1
+++ b/scripts/ReplaceNugetCache.ps1
@@ -2,3 +2,4 @@ copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp2.0\Avalonia**.dll ~\
copy ..\samples\ControlCatalog.NetCore.\bin\Debug\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netstandard2.0\
copy ..\samples\ControlCatalog.NetCore.\bin\Debug\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia.gtk3\$args\lib\netstandard2.0\
copy ..\samples\ControlCatalog.NetCore.\bin\Debug\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia.win32\$args\lib\netstandard2.0\
+copy ..\samples\ControlCatalog.NetCore.\bin\Debug\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia.skia\$args\lib\netstandard2.0\
diff --git a/scripts/ReplaceNugetCache.sh b/scripts/ReplaceNugetCache.sh
index 636aec5f23..d50f4152e8 100755
--- a/scripts/ReplaceNugetCache.sh
+++ b/scripts/ReplaceNugetCache.sh
@@ -3,4 +3,6 @@
cp ../samples/ControlCatalog.NetCore/bin/Debug/netcoreapp2.0/Avalonia**.dll ~/.nuget/packages/avalonia/$1/lib/netcoreapp2.0/
cp ../samples/ControlCatalog.NetCore/bin/Debug/netcoreapp2.0/Avalonia**.dll ~/.nuget/packages/avalonia/$1/lib/netstandard2.0/
cp ../samples/ControlCatalog.NetCore/bin/Debug/netcoreapp2.0/Avalonia**.dll ~/.nuget/packages/avalonia.gtk3/$1/lib/netstandard2.0/
+ cp ../samples/ControlCatalog.NetCore/bin/Debug/netcoreapp2.0/Avalonia**.dll ~/.nuget/packages/avalonia.skia/$1/lib/netstandard2.0/
+
diff --git a/scripts/ReplaceNugetCacheRelease.ps1 b/scripts/ReplaceNugetCacheRelease.ps1
index f188c81c51..1c19e00400 100644
--- a/scripts/ReplaceNugetCacheRelease.ps1
+++ b/scripts/ReplaceNugetCacheRelease.ps1
@@ -1,4 +1,5 @@
copy ..\samples\ControlCatalog.NetCore\bin\Release\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netcoreapp2.0\
copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netstandard2.0\
copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia.gtk3\$args\lib\netstandard2.0\
-copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia.win32\$args\lib\netstandard2.0\
\ No newline at end of file
+copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia.win32\$args\lib\netstandard2.0\
+copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia.skia\$args\lib\netstandard2.0\
\ No newline at end of file
diff --git a/src/Android/Avalonia.Android/Resources/Resource.Designer.cs b/src/Android/Avalonia.Android/Resources/Resource.Designer.cs
index e66c2800d3..80cbbc51ec 100644
--- a/src/Android/Avalonia.Android/Resources/Resource.Designer.cs
+++ b/src/Android/Avalonia.Android/Resources/Resource.Designer.cs
@@ -40,14 +40,11 @@ namespace Avalonia.Android
public partial class String
{
- // aapt resource value: 0x7f020002
- public static int ApplicationName = 2130837506;
-
// aapt resource value: 0x7f020001
- public static int Hello = 2130837505;
+ public static int ApplicationName = 2130837505;
// aapt resource value: 0x7f020000
- public static int library_name = 2130837504;
+ public static int Hello = 2130837504;
static String()
{
diff --git a/src/Android/Avalonia.AndroidTestApplication/MainActivity.cs b/src/Android/Avalonia.AndroidTestApplication/MainActivity.cs
index 7973ad72e5..ad2cec2ae3 100644
--- a/src/Android/Avalonia.AndroidTestApplication/MainActivity.cs
+++ b/src/Android/Avalonia.AndroidTestApplication/MainActivity.cs
@@ -56,7 +56,7 @@ namespace Avalonia.AndroidTestApplication
{
Margin = new Thickness(30),
Background = Brushes.Yellow,
- Children = new Avalonia.Controls.Controls
+ Children =
{
new TextBlock
{
diff --git a/src/Avalonia.Animation/Avalonia.Animation.csproj b/src/Avalonia.Animation/Avalonia.Animation.csproj
index bafac2b261..2101c5669d 100644
--- a/src/Avalonia.Animation/Avalonia.Animation.csproj
+++ b/src/Avalonia.Animation/Avalonia.Animation.csproj
@@ -11,7 +11,7 @@
DEBUG;TRACE
prompt
4
- bin\Debug\Avalonia.Animation.XML
+ bin\Debug\Avalonia.Animation.xml
false
@@ -21,7 +21,7 @@
TRACE
prompt
4
- bin\Release\Avalonia.Animation.XML
+ bin\Release\Avalonia.Animation.xml
CS1591
true
diff --git a/src/Avalonia.Base/Avalonia.Base.csproj b/src/Avalonia.Base/Avalonia.Base.csproj
index 58c510f483..54537841a9 100644
--- a/src/Avalonia.Base/Avalonia.Base.csproj
+++ b/src/Avalonia.Base/Avalonia.Base.csproj
@@ -12,7 +12,7 @@
DEBUG;TRACE
prompt
4
- bin\Debug\Avalonia.Base.XML
+ bin\Debug\Avalonia.Base.xml
CS1591
@@ -22,7 +22,7 @@
TRACE
prompt
4
- bin\Release\Avalonia.Base.XML
+ bin\Release\Avalonia.Base.xml
CS1591
true
diff --git a/src/Avalonia.Base/AvaloniaObject.cs b/src/Avalonia.Base/AvaloniaObject.cs
index efcbb57244..17e6ea8f0f 100644
--- a/src/Avalonia.Base/AvaloniaObject.cs
+++ b/src/Avalonia.Base/AvaloniaObject.cs
@@ -51,6 +51,21 @@ namespace Avalonia
///
private EventHandler _propertyChanged;
+ private DeferredSetter _directDeferredSetter;
+
+ ///
+ /// Delayed setter helper for direct properties. Used to fix #855.
+ ///
+ private DeferredSetter DirectPropertyDeferredSetter
+ {
+ get
+ {
+ return _directDeferredSetter ??
+ (_directDeferredSetter = new DeferredSetter());
+ }
+ }
+
+
///
/// Initializes a new instance of the class.
///
@@ -225,6 +240,19 @@ namespace Avalonia
return (T)GetValue((AvaloniaProperty)property);
}
+ ///
+ /// Checks whether a is animating.
+ ///
+ /// The property.
+ /// True if the property is animating, otherwise false.
+ public bool IsAnimating(AvaloniaProperty property)
+ {
+ Contract.Requires(property != null);
+ VerifyAccess();
+
+ return _values.TryGetValue(property, out PriorityValue value) ? value.IsAnimating : false;
+ }
+
///
/// Checks whether a is set on this object.
///
@@ -311,9 +339,6 @@ namespace Avalonia
var description = GetDescription(source);
- var scheduler = AvaloniaLocator.Current.GetService() ?? ImmediateScheduler.Instance;
- source = source.ObserveOn(scheduler);
-
if (property.IsDirect)
{
if (property.IsReadOnly)
@@ -539,6 +564,45 @@ namespace Avalonia
}
}
+ ///
+ /// A callback type for encapsulating complex logic for setting direct properties.
+ ///
+ /// The type of the property.
+ /// The value to which to set the property.
+ /// The backing field for the property.
+ /// A wrapper for the property-changed notification.
+ protected delegate void SetAndRaiseCallback(T value, ref T field, Action notifyWrapper);
+
+ ///
+ /// Sets the backing field for a direct avalonia property, raising the
+ /// event if the value has changed.
+ ///
+ /// The type of the property.
+ /// The property.
+ /// The backing field.
+ /// A callback called to actually set the value to the backing field.
+ /// The value.
+ ///
+ /// True if the value changed, otherwise false.
+ ///
+ protected bool SetAndRaise(
+ AvaloniaProperty property,
+ ref T field,
+ SetAndRaiseCallback setterCallback,
+ T value)
+ {
+ Contract.Requires(setterCallback != null);
+ return DirectPropertyDeferredSetter.SetAndNotify(
+ property,
+ ref field,
+ (object val, ref T backing, Action notify) =>
+ {
+ setterCallback((T)val, ref backing, notify);
+ return true;
+ },
+ value);
+ }
+
///
/// Sets the backing field for a direct avalonia property, raising the
/// event if the value has changed.
@@ -553,17 +617,32 @@ namespace Avalonia
protected bool SetAndRaise(AvaloniaProperty property, ref T field, T value)
{
VerifyAccess();
- if (!object.Equals(field, value))
- {
- var old = field;
- field = value;
- RaisePropertyChanged(property, old, value, BindingPriority.LocalValue);
- return true;
- }
- else
- {
- return false;
- }
+ return SetAndRaise(
+ property,
+ ref field,
+ (T val, ref T backing, Action notifyWrapper)
+ => SetAndRaiseCore(property, ref backing, val, notifyWrapper),
+ value);
+ }
+
+ ///
+ /// Default assignment logic for SetAndRaise.
+ ///
+ /// The type of the property.
+ /// The property.
+ /// The backing field.
+ /// The value.
+ /// A wrapper for the property-changed notification.
+ ///
+ /// True if the value changed, otherwise false.
+ ///
+ private bool SetAndRaiseCore(AvaloniaProperty property, ref T field, T value, Action notifyWrapper)
+ {
+ var old = field;
+ field = value;
+
+ notifyWrapper(() => RaisePropertyChanged(property, old, value, BindingPriority.LocalValue));
+ return true;
}
///
@@ -661,29 +740,41 @@ namespace Avalonia
/// The value.
private void SetDirectValue(AvaloniaProperty property, object value)
{
- var notification = value as BindingNotification;
-
- if (notification != null)
+ void Set()
{
- notification.LogIfError(this, property);
- value = notification.Value;
- }
+ var notification = value as BindingNotification;
- if (notification == null || notification.ErrorType == BindingErrorType.Error || notification.HasValue)
- {
- var metadata = (IDirectPropertyMetadata)property.GetMetadata(GetType());
- var accessor = (IDirectPropertyAccessor)GetRegistered(property);
- var finalValue = value == AvaloniaProperty.UnsetValue ?
- metadata.UnsetValue : value;
+ if (notification != null)
+ {
+ notification.LogIfError(this, property);
+ value = notification.Value;
+ }
- LogPropertySet(property, value, BindingPriority.LocalValue);
+ if (notification == null || notification.ErrorType == BindingErrorType.Error || notification.HasValue)
+ {
+ var metadata = (IDirectPropertyMetadata)property.GetMetadata(GetType());
+ var accessor = (IDirectPropertyAccessor)GetRegistered(property);
+ var finalValue = value == AvaloniaProperty.UnsetValue ?
+ metadata.UnsetValue : value;
- accessor.SetValue(this, finalValue);
+ LogPropertySet(property, value, BindingPriority.LocalValue);
+
+ accessor.SetValue(this, finalValue);
+ }
+
+ if (notification != null)
+ {
+ UpdateDataValidation(property, notification);
+ }
}
- if (notification != null)
+ if (Dispatcher.UIThread.CheckAccess())
+ {
+ Set();
+ }
+ else
{
- UpdateDataValidation(property, notification);
+ Dispatcher.UIThread.InvokeAsync(Set);
}
}
diff --git a/src/Avalonia.Base/AvaloniaObjectExtensions.cs b/src/Avalonia.Base/AvaloniaObjectExtensions.cs
index e96679e643..1da2ecb942 100644
--- a/src/Avalonia.Base/AvaloniaObjectExtensions.cs
+++ b/src/Avalonia.Base/AvaloniaObjectExtensions.cs
@@ -138,17 +138,9 @@ namespace Avalonia
AvaloniaProperty property,
BindingPriority priority = BindingPriority.LocalValue)
{
- // TODO: Subject.Create is not yet in stable Rx : once it is, remove the
- // AnonymousSubject classes and use Subject.Create.
- var output = new Subject
diff --git a/tests/Avalonia.Input.UnitTests/Avalonia.Input.UnitTests.csproj b/tests/Avalonia.Input.UnitTests/Avalonia.Input.UnitTests.csproj
index 98a1312782..1f66290dd9 100644
--- a/tests/Avalonia.Input.UnitTests/Avalonia.Input.UnitTests.csproj
+++ b/tests/Avalonia.Input.UnitTests/Avalonia.Input.UnitTests.csproj
@@ -1,6 +1,6 @@
- net461;netcoreapp2.0
+ net47;netcoreapp2.0
Library
diff --git a/tests/Avalonia.Input.UnitTests/KeyGestureParseTests.cs b/tests/Avalonia.Input.UnitTests/KeyGestureParseTests.cs
deleted file mode 100644
index d26b03ad80..0000000000
--- a/tests/Avalonia.Input.UnitTests/KeyGestureParseTests.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Xunit;
-
-namespace Avalonia.Input.UnitTests
-{
- public class KeyGestureParseTests
- {
- private static readonly Dictionary SampleData = new Dictionary
- {
- {"Ctrl+A", new KeyGesture {Key = Key.A, Modifiers = InputModifiers.Control}},
- {" \tShift\t+Alt +B", new KeyGesture {Key = Key.B, Modifiers = InputModifiers.Shift|InputModifiers.Alt} },
- {"Control++", new KeyGesture {Key = Key.OemPlus, Modifiers = InputModifiers.Control} }
- };
-
-
-
- [Fact]
- public void Key_Gesture_Is_Able_To_Parse_Sample_Data()
- {
- foreach (var d in SampleData)
- Assert.Equal(d.Value, KeyGesture.Parse(d.Key));
- }
- }
-}
diff --git a/tests/Avalonia.Input.UnitTests/KeyGestureTests.cs b/tests/Avalonia.Input.UnitTests/KeyGestureTests.cs
new file mode 100644
index 0000000000..006ed1140e
--- /dev/null
+++ b/tests/Avalonia.Input.UnitTests/KeyGestureTests.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Avalonia.Input.UnitTests
+{
+ public class KeyGestureTests
+ {
+ public static readonly IEnumerable SampleData = new object[][]
+ {
+ new object[]{"Ctrl+A", new KeyGesture {Key = Key.A, Modifiers = InputModifiers.Control}},
+ new object[]{" \tShift\t+Alt +B", new KeyGesture {Key = Key.B, Modifiers = InputModifiers.Shift|InputModifiers.Alt} },
+ new object[]{"Control++", new KeyGesture {Key = Key.OemPlus, Modifiers = InputModifiers.Control} }
+ };
+
+
+
+ [Theory]
+ [MemberData(nameof(SampleData))]
+ public void Key_Gesture_Is_Able_To_Parse_Sample_Data(string text, KeyGesture gesture)
+ {
+ Assert.Equal(gesture, KeyGesture.Parse(text));
+ }
+
+ [Theory]
+ [InlineData(Key.OemMinus, Key.Subtract)]
+ [InlineData(Key.OemPlus, Key.Add)]
+ [InlineData(Key.OemPeriod, Key.Decimal)]
+ public void Key_Gesture_Matches_NumPad_To_Regular_Digit(Key gestureKey, Key pressedKey)
+ {
+ var keyGesture = new KeyGesture
+ {
+ Key = gestureKey
+ };
+ Assert.True(keyGesture.Matches(new KeyEventArgs
+ {
+ Key = pressedKey
+ }));
+ }
+ }
+}
diff --git a/tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Arrows.cs b/tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Arrows.cs
index 2b9b0baf01..b81b724e2a 100644
--- a/tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Arrows.cs
+++ b/tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Arrows.cs
@@ -6,8 +6,6 @@ using Xunit;
namespace Avalonia.Input.UnitTests
{
- using Controls = Controls.Controls;
-
public class KeyboardNavigationTests_Arrows
{
[Fact]
@@ -18,12 +16,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
(current = new Button { Name = "Button2" }),
@@ -33,7 +31,7 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -56,12 +54,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
new Button { Name = "Button2" },
@@ -71,7 +69,7 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button4" }),
new Button { Name = "Button5" },
@@ -94,12 +92,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
new Button { Name = "Button2" },
@@ -123,16 +121,16 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
new Button { Name = "Button2" },
@@ -144,7 +142,7 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button4" }),
new Button { Name = "Button5" },
@@ -167,7 +165,7 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button1" }),
}
@@ -187,17 +185,17 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button1" }),
new Button { Name = "Button2" },
@@ -209,7 +207,7 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -232,12 +230,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Cycle,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
(current = new Button { Name = "Button2" }),
@@ -246,7 +244,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -269,12 +267,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Cycle,
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button1" }),
new Button { Name = "Button2" },
@@ -283,7 +281,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -306,12 +304,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
(current = new Button { Name = "Button2" }),
@@ -321,7 +319,7 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained,
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -343,12 +341,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
new Button { Name = "Button2" },
@@ -358,7 +356,7 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained,
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -380,12 +378,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.None,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
(current = new Button { Name = "Button2" }),
@@ -395,7 +393,7 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained,
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -418,12 +416,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
(next = new Button { Name = "Button2" }),
@@ -433,7 +431,7 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained,
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -456,12 +454,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
new Button { Name = "Button2" },
@@ -471,7 +469,7 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
(current = new Button { Name = "Button4" }),
new Button { Name = "Button5" },
@@ -495,12 +493,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
new Button { Name = "Button2" },
@@ -524,16 +522,16 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
new Button { Name = "Button2" },
@@ -545,7 +543,7 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
(current = new Button { Name = "Button4" }),
new Button { Name = "Button5" },
@@ -568,16 +566,16 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
(current = new Button { Name = "Button1" }),
new Button { Name = "Button2" },
@@ -589,7 +587,7 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue,
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -632,12 +630,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Cycle,
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button1" }),
(current = new Button { Name = "Button2" }),
@@ -647,7 +645,7 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Cycle,
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -670,12 +668,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Cycle,
- Children = new Controls
+ Children =
{
(current = new Button { Name = "Button1" }),
new Button { Name = "Button2" },
@@ -685,7 +683,7 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Cycle,
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -708,12 +706,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained,
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button1" }),
(current = new Button { Name = "Button2" }),
@@ -723,7 +721,7 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained,
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -745,12 +743,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained,
- Children = new Controls
+ Children =
{
(current = new Button { Name = "Button1" }),
new Button { Name = "Button2" },
@@ -760,7 +758,7 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained,
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -783,7 +781,7 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
[KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained,
- Children = new Controls
+ Children =
{
(current = new Decorator
{
diff --git a/tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Tab.cs b/tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Tab.cs
index 2cc7a4281b..ad70dcd470 100644
--- a/tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Tab.cs
+++ b/tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Tab.cs
@@ -6,8 +6,6 @@ using Xunit;
namespace Avalonia.Input.UnitTests
{
- using Controls = Controls.Controls;
-
public class KeyboardNavigationTests_Tab
{
[Fact]
@@ -18,11 +16,11 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
(current = new Button { Name = "Button2" }),
@@ -31,7 +29,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -54,11 +52,11 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
new Button { Name = "Button2" },
@@ -67,7 +65,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button4" }),
new Button { Name = "Button5" },
@@ -90,11 +88,11 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button1" }),
new Button { Name = "Button2" },
@@ -104,11 +102,11 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.None,
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -133,11 +131,11 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
new Button { Name = "Button2" },
@@ -161,15 +159,15 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
new Button { Name = "Button2" },
@@ -180,7 +178,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button4" }),
new Button { Name = "Button5" },
@@ -202,7 +200,7 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button1" }),
}
@@ -221,15 +219,15 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button1" }),
new Button { Name = "Button2" },
@@ -240,7 +238,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -263,12 +261,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
(current = new Button { Name = "Button2" }),
@@ -277,7 +275,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -300,12 +298,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle,
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button1" }),
new Button { Name = "Button2" },
@@ -314,7 +312,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -337,12 +335,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Contained,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
(current = new Button { Name = "Button2" }),
@@ -351,7 +349,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -373,12 +371,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Contained,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
new Button { Name = "Button2" },
@@ -387,7 +385,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -410,12 +408,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Once,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
(current = new Button { Name = "Button2" }),
@@ -424,7 +422,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button4" }),
new Button { Name = "Button5" },
@@ -448,12 +446,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
(container = new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Once,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
(next = new Button { Name = "Button2" }),
@@ -462,7 +460,7 @@ namespace Avalonia.Input.UnitTests
}),
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -487,12 +485,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.None,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
(current = new Button { Name = "Button2" }),
@@ -501,7 +499,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button4" }),
new Button { Name = "Button5" },
@@ -525,12 +523,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
(container = new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.None,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
new Button { Name = "Button2" },
@@ -539,7 +537,7 @@ namespace Avalonia.Input.UnitTests
}),
new StackPanel
{
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button4" }),
new Button { Name = "Button5" },
@@ -564,11 +562,11 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
(next = new Button { Name = "Button2" }),
@@ -577,7 +575,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -600,11 +598,11 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
new Button { Name = "Button2" },
@@ -613,7 +611,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
(current = new Button { Name = "Button4" }),
new Button { Name = "Button5" },
@@ -636,11 +634,11 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
new Button { Name = "Button2" },
@@ -664,15 +662,15 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
new Button { Name = "Button2" },
@@ -683,7 +681,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
(current = new Button { Name = "Button4" }),
new Button { Name = "Button5" },
@@ -706,15 +704,15 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
(current = new Button { Name = "Button1" }),
new Button { Name = "Button2" },
@@ -725,7 +723,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -767,12 +765,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle,
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button1" }),
(current = new Button { Name = "Button2" }),
@@ -781,7 +779,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -804,12 +802,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle,
- Children = new Controls
+ Children =
{
(current = new Button { Name = "Button1" }),
new Button { Name = "Button2" },
@@ -818,7 +816,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -841,12 +839,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Contained,
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button1" }),
(current = new Button { Name = "Button2" }),
@@ -855,7 +853,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -877,12 +875,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Contained,
- Children = new Controls
+ Children =
{
(current = new Button { Name = "Button1" }),
new Button { Name = "Button2" },
@@ -891,7 +889,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
@@ -914,11 +912,11 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
new Button { Name = "Button2" },
@@ -928,7 +926,7 @@ namespace Avalonia.Input.UnitTests
new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Once,
- Children = new Controls
+ Children =
{
new Button { Name = "Button4" },
(current = new Button { Name = "Button5" }),
@@ -952,12 +950,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
(container = new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Once,
- Children = new Controls
+ Children =
{
new Button { Name = "Button1" },
(next = new Button { Name = "Button2" }),
@@ -966,7 +964,7 @@ namespace Avalonia.Input.UnitTests
}),
new StackPanel
{
- Children = new Controls
+ Children =
{
(current = new Button { Name = "Button4" }),
new Button { Name = "Button5" },
@@ -991,12 +989,12 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
- Children = new Controls
+ Children =
{
new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Once,
- Children = new Controls
+ Children =
{
(next = new Button { Name = "Button1" }),
new Button { Name = "Button2" },
@@ -1005,7 +1003,7 @@ namespace Avalonia.Input.UnitTests
},
new StackPanel
{
- Children = new Controls
+ Children =
{
(current = new Button { Name = "Button4" }),
new Button { Name = "Button5" },
@@ -1028,7 +1026,7 @@ namespace Avalonia.Input.UnitTests
var top = new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Contained,
- Children = new Controls
+ Children =
{
(current = new Decorator
{
diff --git a/tests/Avalonia.Interactivity.UnitTests/Avalonia.Interactivity.UnitTests.csproj b/tests/Avalonia.Interactivity.UnitTests/Avalonia.Interactivity.UnitTests.csproj
index 78d2128478..3fb2439af8 100644
--- a/tests/Avalonia.Interactivity.UnitTests/Avalonia.Interactivity.UnitTests.csproj
+++ b/tests/Avalonia.Interactivity.UnitTests/Avalonia.Interactivity.UnitTests.csproj
@@ -1,6 +1,6 @@
- net461;netcoreapp2.0
+ net47;netcoreapp2.0
Library
diff --git a/tests/Avalonia.Layout.UnitTests/Avalonia.Layout.UnitTests.csproj b/tests/Avalonia.Layout.UnitTests/Avalonia.Layout.UnitTests.csproj
index 0020ff46d9..ae6f4d463a 100644
--- a/tests/Avalonia.Layout.UnitTests/Avalonia.Layout.UnitTests.csproj
+++ b/tests/Avalonia.Layout.UnitTests/Avalonia.Layout.UnitTests.csproj
@@ -1,6 +1,6 @@
- net461;netcoreapp2.0
+ net47;netcoreapp2.0
Library
diff --git a/tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs b/tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs
index 361e7678be..4fce3fec0e 100644
--- a/tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs
+++ b/tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs
@@ -275,10 +275,10 @@ namespace Avalonia.Layout.UnitTests
{
Child = panel = new StackPanel
{
- Children = new Controls.Controls
- {
- (border = new Border())
- }
+ Children =
+ {
+ (border = new Border())
+ }
}
};
diff --git a/tests/Avalonia.LeakTests/Avalonia.LeakTests.csproj b/tests/Avalonia.LeakTests/Avalonia.LeakTests.csproj
index 46bd4ee324..7ecc3797ed 100644
--- a/tests/Avalonia.LeakTests/Avalonia.LeakTests.csproj
+++ b/tests/Avalonia.LeakTests/Avalonia.LeakTests.csproj
@@ -9,7 +9,7 @@
Properties
Avalonia.LeakTests
Avalonia.LeakTests
- v4.6.1
+ v4.7
512
diff --git a/tests/Avalonia.LeakTests/app.config b/tests/Avalonia.LeakTests/app.config
index 01de951354..71e6d0a02e 100644
--- a/tests/Avalonia.LeakTests/app.config
+++ b/tests/Avalonia.LeakTests/app.config
@@ -1,15 +1,15 @@
-
+
-
-
+
+
-
-
+
+
-
\ No newline at end of file
+
diff --git a/tests/Avalonia.Markup.UnitTests/Avalonia.Markup.UnitTests.csproj b/tests/Avalonia.Markup.UnitTests/Avalonia.Markup.UnitTests.csproj
index 5d3b04e24b..4db9bc45ad 100644
--- a/tests/Avalonia.Markup.UnitTests/Avalonia.Markup.UnitTests.csproj
+++ b/tests/Avalonia.Markup.UnitTests/Avalonia.Markup.UnitTests.csproj
@@ -1,6 +1,6 @@
- net461;netcoreapp2.0
+ net47;netcoreapp2.0
Library
diff --git a/tests/Avalonia.Markup.UnitTests/ControlLocatorTests.cs b/tests/Avalonia.Markup.UnitTests/ControlLocatorTests.cs
index a5414f1e8c..b3e983036d 100644
--- a/tests/Avalonia.Markup.UnitTests/ControlLocatorTests.cs
+++ b/tests/Avalonia.Markup.UnitTests/ControlLocatorTests.cs
@@ -23,7 +23,7 @@ namespace Avalonia.Markup.UnitTests
{
Child = new StackPanel
{
- Children = new Controls.Controls
+ Children =
{
(target = new TextBlock { Name = "target" }),
(relativeTo = new TextBlock { Name = "start" }),
@@ -49,7 +49,7 @@ namespace Avalonia.Markup.UnitTests
{
Child = (panel = new StackPanel
{
- Children = new Controls.Controls
+ Children =
{
(relativeTo = new TextBlock
{
@@ -84,7 +84,7 @@ namespace Avalonia.Markup.UnitTests
{
Child = panel = new StackPanel
{
- Children = new Controls.Controls
+ Children =
{
(target = new TextBlock { Name = "target" }),
(relativeTo = new TextBlock { Name = "start" }),
@@ -114,7 +114,7 @@ namespace Avalonia.Markup.UnitTests
{
Child = new StackPanel
{
- Children = new Controls.Controls
+ Children =
{
(relativeTo = new TextBlock
{
@@ -129,7 +129,7 @@ namespace Avalonia.Markup.UnitTests
{
Child = new StackPanel
{
- Children = new Controls.Controls
+ Children =
{
(target2 = new TextBlock { Name = "target" }),
}
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj b/tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj
index eb6dc8b5e5..02fbf23687 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj
@@ -1,6 +1,6 @@
- net461;netcoreapp2.0
+ net47;netcoreapp2.0
Library
@@ -21,6 +21,7 @@
+
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests.cs
index 230e61f300..71c5385c23 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests.cs
@@ -13,6 +13,7 @@ using Moq;
using Xunit;
using System.ComponentModel;
using System.Runtime.CompilerServices;
+using Avalonia.UnitTests;
namespace Avalonia.Markup.Xaml.UnitTests.Data
{
@@ -337,6 +338,167 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data
Assert.Equal("foo", target.Content);
}
+ [Fact]
+ public void StyledProperty_SetValue_Should_Not_Cause_StackOverflow_And_Have_Correct_Values()
+ {
+ var viewModel = new TestStackOverflowViewModel()
+ {
+ Value = 50
+ };
+
+ var target = new StyledPropertyClass();
+
+ target.Bind(StyledPropertyClass.DoubleValueProperty,
+ new Binding("Value") { Mode = BindingMode.TwoWay, Source = viewModel });
+
+ var child = new StyledPropertyClass();
+
+ child.Bind(StyledPropertyClass.DoubleValueProperty,
+ new Binding("DoubleValue")
+ {
+ Mode = BindingMode.TwoWay,
+ Source = target
+ });
+
+ Assert.Equal(1, viewModel.SetterInvokedCount);
+
+ //here in real life stack overflow exception is thrown issue #855 and #824
+ target.DoubleValue = 51.001;
+
+ Assert.Equal(2, viewModel.SetterInvokedCount);
+
+ double expected = 51;
+
+ Assert.Equal(expected, viewModel.Value);
+ Assert.Equal(expected, target.DoubleValue);
+ Assert.Equal(expected, child.DoubleValue);
+ }
+
+ [Fact]
+ public void SetValue_Should_Not_Cause_StackOverflow_And_Have_Correct_Values()
+ {
+ var viewModel = new TestStackOverflowViewModel()
+ {
+ Value = 50
+ };
+
+ var target = new DirectPropertyClass();
+
+ target.Bind(DirectPropertyClass.DoubleValueProperty, new Binding("Value")
+ {
+ Mode = BindingMode.TwoWay,
+ Source = viewModel
+ });
+
+ var child = new DirectPropertyClass();
+
+ child.Bind(DirectPropertyClass.DoubleValueProperty,
+ new Binding("DoubleValue")
+ {
+ Mode = BindingMode.TwoWay,
+ Source = target
+ });
+
+ Assert.Equal(1, viewModel.SetterInvokedCount);
+
+ //here in real life stack overflow exception is thrown issue #855 and #824
+ target.DoubleValue = 51.001;
+
+ Assert.Equal(2, viewModel.SetterInvokedCount);
+
+ double expected = 51;
+
+ Assert.Equal(expected, viewModel.Value);
+ Assert.Equal(expected, target.DoubleValue);
+ Assert.Equal(expected, child.DoubleValue);
+ }
+
+ private class StyledPropertyClass : AvaloniaObject
+ {
+ public static readonly StyledProperty DoubleValueProperty =
+ AvaloniaProperty.Register(nameof(DoubleValue));
+
+ public double DoubleValue
+ {
+ get { return GetValue(DoubleValueProperty); }
+ set { SetValue(DoubleValueProperty, value); }
+ }
+ }
+
+ private class DirectPropertyClass : AvaloniaObject
+ {
+ public static readonly DirectProperty DoubleValueProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(DoubleValue),
+ o => o.DoubleValue,
+ (o, v) => o.DoubleValue = v);
+
+ private double _doubleValue;
+ public double DoubleValue
+ {
+ get { return _doubleValue; }
+ set { SetAndRaise(DoubleValueProperty, ref _doubleValue, value); }
+ }
+ }
+
+ private class TestStackOverflowViewModel : INotifyPropertyChanged
+ {
+ public int SetterInvokedCount { get; private set; }
+
+ public const int MaxInvokedCount = 1000;
+
+ private double _value;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public double Value
+ {
+ get { return _value; }
+ set
+ {
+ if (_value != value)
+ {
+ SetterInvokedCount++;
+ if (SetterInvokedCount < MaxInvokedCount)
+ {
+ _value = (int)value;
+ if (_value > 75) _value = 75;
+ if (_value < 25) _value = 25;
+ }
+ else
+ {
+ _value = value;
+ }
+
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
+ }
+ }
+ }
+ }
+
+
+ [Fact]
+ public void Binding_With_Null_Path_Works()
+ {
+ using (UnitTestApplication.Start(TestServices.StyledWindow))
+ {
+ var xaml = @"
+
+
+";
+ var loader = new AvaloniaXamlLoader();
+ var window = (Window)loader.Load(xaml);
+ var textBlock = window.FindControl("textBlock");
+
+ window.DataContext = "foo";
+ window.ApplyTemplate();
+
+ Assert.Equal("foo", textBlock.Text);
+ }
+ }
+
private class TwoWayBindingTest : Control
{
public static readonly StyledProperty TwoWayProperty =
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_ElementName.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_ElementName.cs
index 40a4a6f0b3..d582964987 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_ElementName.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_ElementName.cs
@@ -18,7 +18,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data
{
Child = new StackPanel
{
- Children = new Controls.Controls
+ Children =
{
new TextBlock
{
@@ -54,7 +54,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data
{
Child = new StackPanel
{
- Children = new Controls.Controls
+ Children =
{
(source = new TextBlock
{
@@ -89,7 +89,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data
{
Child = stackPanel = new StackPanel
{
- Children = new Controls.Controls
+ Children =
{
(target = new TextBlock
{
@@ -126,7 +126,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data
{
Child = stackPanel = new StackPanel
{
- Children = new Controls.Controls
+ Children =
{
(target = new ContentControl
{
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_TemplatedParent.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_TemplatedParent.cs
index 197afe46ee..ccb13039f1 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_TemplatedParent.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_TemplatedParent.cs
@@ -11,6 +11,9 @@ using Avalonia.Markup.Xaml.Data;
using Avalonia.Styling;
using Xunit;
using System.Reactive.Disposables;
+using Avalonia.UnitTests;
+using Avalonia.VisualTree;
+using System.Linq;
namespace Avalonia.Markup.Xaml.UnitTests.Data
{
@@ -56,6 +59,35 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data
BindingPriority.TemplatedParent));
}
+ [Fact]
+ public void TemplateBinding_With_Null_Path_Works()
+ {
+ using (UnitTestApplication.Start(TestServices.StyledWindow))
+ {
+ var xaml = @"
+
+
+";
+ var loader = new AvaloniaXamlLoader();
+ var window = (Window)loader.Load(xaml);
+ var button = window.FindControl
-
+
diff --git a/tests/Avalonia.UnitTests/TestRoot.cs b/tests/Avalonia.UnitTests/TestRoot.cs
index 9ec053f075..dc137e3533 100644
--- a/tests/Avalonia.UnitTests/TestRoot.cs
+++ b/tests/Avalonia.UnitTests/TestRoot.cs
@@ -16,8 +16,6 @@ namespace Avalonia.UnitTests
public class TestRoot : Decorator, IFocusScope, ILayoutRoot, IInputRoot, INameScope, IRenderRoot, IStyleRoot
{
private readonly NameScope _nameScope = new NameScope();
- private readonly IRenderTarget _renderTarget = Mock.Of(
- x => x.CreateDrawingContext(It.IsAny()) == Mock.Of());
public TestRoot()
{
@@ -65,7 +63,21 @@ namespace Avalonia.UnitTests
IStyleHost IStyleHost.StylingParent => StylingParent;
- public IRenderTarget CreateRenderTarget() => _renderTarget;
+ public IRenderTarget CreateRenderTarget()
+ {
+ var dc = new Mock();
+ dc.Setup(x => x.CreateLayer(It.IsAny())).Returns(() =>
+ {
+ var layerDc = new Mock();
+ var layer = new Mock();
+ layer.Setup(x => x.CreateDrawingContext(It.IsAny())).Returns(layerDc.Object);
+ return layer.Object;
+ });
+
+ var result = new Mock();
+ result.Setup(x => x.CreateDrawingContext(It.IsAny())).Returns(dc.Object);
+ return result.Object;
+ }
public void Invalidate(Rect rect)
{
diff --git a/tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj b/tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj
index 6dc9e3324d..74a48f9ce7 100644
--- a/tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj
+++ b/tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj
@@ -1,6 +1,6 @@
- net461;netcoreapp2.0
+ net47;netcoreapp2.0
diff --git a/tests/Avalonia.Visuals.UnitTests/RenderTests_Culling.cs b/tests/Avalonia.Visuals.UnitTests/RenderTests_Culling.cs
index bcb5250be6..b87e72516b 100644
--- a/tests/Avalonia.Visuals.UnitTests/RenderTests_Culling.cs
+++ b/tests/Avalonia.Visuals.UnitTests/RenderTests_Culling.cs
@@ -21,7 +21,7 @@ namespace Avalonia.Visuals.UnitTests
Width = 100,
Height = 100,
ClipToBounds = true,
- Children = new Controls.Controls
+ Children =
{
(target = new TestControl
{
@@ -47,7 +47,7 @@ namespace Avalonia.Visuals.UnitTests
Width = 100,
Height = 100,
ClipToBounds = true,
- Children = new Controls.Controls
+ Children =
{
(target = new TestControl
{
@@ -74,7 +74,7 @@ namespace Avalonia.Visuals.UnitTests
Width = 100,
Height = 100,
ClipToBounds = true,
- Children = new Controls.Controls
+ Children =
{
new Canvas
{
@@ -82,7 +82,7 @@ namespace Avalonia.Visuals.UnitTests
Height = 100,
[Canvas.LeftProperty] = 50,
[Canvas.TopProperty] = 50,
- Children = new Controls.Controls
+ Children =
{
(target = new TestControl
{
@@ -111,7 +111,7 @@ namespace Avalonia.Visuals.UnitTests
Width = 100,
Height = 100,
ClipToBounds = true,
- Children = new Controls.Controls
+ Children =
{
(target = new TestControl
{
@@ -138,7 +138,7 @@ namespace Avalonia.Visuals.UnitTests
Width = 100,
Height = 100,
ClipToBounds = true,
- Children = new Controls.Controls
+ Children =
{
new Border
{
diff --git a/tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs b/tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs
index cec95d4807..c97070a2aa 100644
--- a/tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs
+++ b/tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Reactive.Subjects;
using Avalonia.Controls;
+using Avalonia.Data;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.Rendering;
@@ -19,28 +21,18 @@ namespace Avalonia.Visuals.UnitTests.Rendering
[Fact]
public void First_Frame_Calls_UpdateScene_On_Dispatcher()
{
- var loop = new Mock();
var root = new TestRoot();
var dispatcher = new Mock();
dispatcher.Setup(x => x.InvokeAsync(It.IsAny(), DispatcherPriority.Render))
.Callback((a, p) => a());
- var target = new DeferredRenderer(
- root,
- loop.Object,
- sceneBuilder: MockSceneBuilder(root).Object,
- dispatcher: dispatcher.Object);
+ CreateTargetAndRunFrame(root, dispatcher: dispatcher.Object);
- target.Start();
- RunFrame(loop);
-
-#if !NETCOREAPP1_1 // Delegate.Method is not available in netcoreapp1.1
dispatcher.Verify(x =>
x.InvokeAsync(
It.Is(a => a.Method.Name == "UpdateScene"),
DispatcherPriority.Render));
-#endif
}
[Fact]
@@ -49,15 +41,8 @@ namespace Avalonia.Visuals.UnitTests.Rendering
var loop = new Mock();
var root = new TestRoot();
var sceneBuilder = MockSceneBuilder(root);
- var dispatcher = new ImmediateDispatcher();
- var target = new DeferredRenderer(
- root,
- loop.Object,
- sceneBuilder: sceneBuilder.Object,
- dispatcher: dispatcher);
- target.Start();
- RunFrame(loop);
+ CreateTargetAndRunFrame(root, sceneBuilder: sceneBuilder.Object);
sceneBuilder.Verify(x => x.UpdateAll(It.IsAny()));
}
@@ -68,12 +53,10 @@ namespace Avalonia.Visuals.UnitTests.Rendering
var loop = new Mock();
var root = new TestRoot();
var sceneBuilder = MockSceneBuilder(root);
- var dispatcher = new ImmediateDispatcher();
var target = new DeferredRenderer(
root,
loop.Object,
- sceneBuilder: sceneBuilder.Object,
- dispatcher: dispatcher);
+ sceneBuilder: sceneBuilder.Object);
target.Start();
IgnoreFirstFrame(loop, sceneBuilder);
@@ -127,12 +110,93 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
[Fact]
- public void Frame_Should_Create_Layer_For_Root()
+ public void Should_Push_Opacity_For_Controls_With_Less_Than_1_Opacity()
+ {
+ var root = new TestRoot
+ {
+ Width = 100,
+ Height = 100,
+ Child = new Border
+ {
+ Background = Brushes.Red,
+ Opacity = 0.5,
+ }
+ };
+
+ root.Measure(Size.Infinity);
+ root.Arrange(new Rect(root.DesiredSize));
+
+ var target = CreateTargetAndRunFrame(root);
+ var context = GetLayerContext(target, root);
+ var animation = new BehaviorSubject(0.5);
+
+ context.Verify(x => x.PushOpacity(0.5), Times.Once);
+ context.Verify(x => x.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100), 0), Times.Once);
+ context.Verify(x => x.PopOpacity(), Times.Once);
+ }
+
+ [Fact]
+ public void Should_Not_Draw_Controls_With_0_Opacity()
+ {
+ var root = new TestRoot
+ {
+ Width = 100,
+ Height = 100,
+ Child = new Border
+ {
+ Background = Brushes.Red,
+ Opacity = 0,
+ Child = new Border
+ {
+ Background = Brushes.Green,
+ }
+ }
+ };
+
+ root.Measure(Size.Infinity);
+ root.Arrange(new Rect(root.DesiredSize));
+
+ var target = CreateTargetAndRunFrame(root);
+ var context = GetLayerContext(target, root);
+ var animation = new BehaviorSubject(0.5);
+
+ context.Verify(x => x.PushOpacity(0.5), Times.Never);
+ context.Verify(x => x.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100), 0), Times.Never);
+ context.Verify(x => x.PopOpacity(), Times.Never);
+ }
+
+ [Fact]
+ public void Should_Push_Opacity_Mask()
+ {
+ var root = new TestRoot
+ {
+ Width = 100,
+ Height = 100,
+ Child = new Border
+ {
+ Background = Brushes.Red,
+ OpacityMask = Brushes.Green,
+ }
+ };
+
+ root.Measure(Size.Infinity);
+ root.Arrange(new Rect(root.DesiredSize));
+
+ var target = CreateTargetAndRunFrame(root);
+ var context = GetLayerContext(target, root);
+ var animation = new BehaviorSubject(0.5);
+
+ context.Verify(x => x.PushOpacityMask(Brushes.Green, new Rect(0, 0, 100, 100)), Times.Once);
+ context.Verify(x => x.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100), 0), Times.Once);
+ context.Verify(x => x.PopOpacityMask(), Times.Once);
+ }
+
+ [Fact]
+ public void Should_Create_Layer_For_Root()
{
var loop = new Mock();
var root = new TestRoot();
var rootLayer = new Mock();
- var dispatcher = new ImmediateDispatcher();
var sceneBuilder = new Mock();
sceneBuilder.Setup(x => x.UpdateAll(It.IsAny()))
@@ -143,23 +207,53 @@ namespace Avalonia.Visuals.UnitTests.Rendering
});
var renderInterface = new Mock();
+ var target = CreateTargetAndRunFrame(root, sceneBuilder: sceneBuilder.Object);
- var target = new DeferredRenderer(
- root,
- loop.Object,
- sceneBuilder: sceneBuilder.Object,
- //layerFactory: layers.Object,
- dispatcher: dispatcher);
+ Assert.Single(target.Layers);
+ }
- target.Start();
+ [Fact]
+ public void Should_Create_And_Delete_Layers_For_Controls_With_Animated_Opacity()
+ {
+ Border border;
+ var root = new TestRoot
+ {
+ Width = 100,
+ Height = 100,
+ Child = new Border
+ {
+ Background = Brushes.Red,
+ Child = border = new Border
+ {
+ Background = Brushes.Green,
+ Child = new Canvas(),
+ Opacity = 0.9,
+ }
+ }
+ };
+
+ root.Measure(Size.Infinity);
+ root.Arrange(new Rect(root.DesiredSize));
+
+ var loop = new Mock();
+ var target = CreateTargetAndRunFrame(root, loop: loop);
+
+ Assert.Equal(new[] { root }, target.Layers.Select(x => x.LayerRoot));
+
+ var animation = new BehaviorSubject(0.5);
+ border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
RunFrame(loop);
- var context = Mock.Get(root.CreateRenderTarget().CreateDrawingContext(null));
- context.Verify(x => x.CreateLayer(root.ClientSize));
+ Assert.Equal(new IVisual[] { root, border }, target.Layers.Select(x => x.LayerRoot));
+
+ animation.OnCompleted();
+ RunFrame(loop);
+
+ Assert.Equal(new[] { root }, target.Layers.Select(x => x.LayerRoot));
}
[Fact]
- public void Should_Create_And_Delete_Layers_For_Transparent_Controls()
+ public void Should_Not_Create_Layer_For_Childless_Control_With_Animated_Opacity()
{
Border border;
var root = new TestRoot
@@ -176,51 +270,96 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
+ var animation = new BehaviorSubject(0.5);
+ border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
+
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
- var rootLayer = CreateLayer();
- var borderLayer = CreateLayer();
- var renderTargetContext = Mock.Get(root.CreateRenderTarget().CreateDrawingContext(null));
- renderTargetContext.SetupSequence(x => x.CreateLayer(It.IsAny()))
- .Returns(rootLayer)
- .Returns(borderLayer);
-
var loop = new Mock();
- var target = new DeferredRenderer(
- root,
- loop.Object,
- dispatcher: new ImmediateDispatcher());
- root.Renderer = target;
+ var target = CreateTargetAndRunFrame(root, loop: loop);
- target.Start();
- RunFrame(loop);
+ Assert.Single(target.Layers);
+ }
+
+ [Fact]
+ public void Should_Not_Push_Opacity_For_Transparent_Layer_Root_Control()
+ {
+ Border border;
+ var root = new TestRoot
+ {
+ Width = 100,
+ Height = 100,
+ Child = border = new Border
+ {
+ Background = Brushes.Red,
+ Child = new Canvas(),
+ }
+ };
+
+ var animation = new BehaviorSubject(0.5);
+ border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
- var rootContext = Mock.Get(rootLayer.CreateDrawingContext(null));
- var borderContext = Mock.Get(borderLayer.CreateDrawingContext(null));
+ root.Measure(Size.Infinity);
+ root.Arrange(new Rect(root.DesiredSize));
- rootContext.Verify(x => x.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100), 0), Times.Once);
- rootContext.Verify(x => x.FillRectangle(Brushes.Green, new Rect(0, 0, 100, 100), 0), Times.Once);
- borderContext.Verify(x => x.FillRectangle(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never);
+ var target = CreateTargetAndRunFrame(root);
+ var context = GetLayerContext(target, border);
- rootContext.ResetCalls();
- borderContext.ResetCalls();
- border.Opacity = 0.5;
- RunFrame(loop);
+ context.Verify(x => x.PushOpacity(0.5), Times.Never);
+ context.Verify(x => x.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100), 0), Times.Once);
+ context.Verify(x => x.PopOpacity(), Times.Never);
+ }
+
+ [Fact]
+ public void Should_Draw_Transparent_Layer_With_Correct_Opacity()
+ {
+ Border border;
+ var root = new TestRoot
+ {
+ Width = 100,
+ Height = 100,
+ Child = border = new Border
+ {
+ Background = Brushes.Red,
+ Child = new Canvas(),
+ }
+ };
+
+ var animation = new BehaviorSubject(0.5);
+ border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
+
+ root.Measure(Size.Infinity);
+ root.Arrange(new Rect(root.DesiredSize));
- rootContext.Verify(x => x.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100), 0), Times.Once);
- rootContext.Verify(x => x.FillRectangle(Brushes.Green, new Rect(0, 0, 100, 100), 0), Times.Never);
- borderContext.Verify(x => x.FillRectangle(Brushes.Green, new Rect(0, 0, 100, 100), 0), Times.Once);
+ var target = CreateTargetAndRunFrame(root);
+ var context = Mock.Get(target.RenderTarget.CreateDrawingContext(null));
+ var borderLayer = target.Layers[border].Bitmap;
- rootContext.ResetCalls();
- borderContext.ResetCalls();
- border.Opacity = 1;
+ context.Verify(x => x.DrawImage(borderLayer, 0.5, It.IsAny(), It.IsAny()));
+ }
+
+ private DeferredRenderer CreateTargetAndRunFrame(
+ TestRoot root,
+ Mock loop = null,
+ ISceneBuilder sceneBuilder = null,
+ IDispatcher dispatcher = null)
+ {
+ loop = loop ?? new Mock();
+ var target = new DeferredRenderer(
+ root,
+ loop.Object,
+ sceneBuilder: sceneBuilder,
+ dispatcher: dispatcher ?? new ImmediateDispatcher());
+ root.Renderer = target;
+ target.Start();
RunFrame(loop);
+ return target;
+ }
- Mock.Get(borderLayer).Verify(x => x.Dispose());
- rootContext.Verify(x => x.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100), 0), Times.Once);
- rootContext.Verify(x => x.FillRectangle(Brushes.Green, new Rect(0, 0, 100, 100), 0), Times.Once);
- borderContext.Verify(x => x.FillRectangle(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never);
+ private Mock GetLayerContext(DeferredRenderer renderer, IControl layerRoot)
+ {
+ return Mock.Get(renderer.Layers[layerRoot].Bitmap.CreateDrawingContext(null));
}
private void IgnoreFirstFrame(Mock loop, Mock sceneBuilder)
diff --git a/tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs b/tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs
index 9e2f1fc293..3a9e45a02b 100644
--- a/tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs
+++ b/tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs
@@ -154,7 +154,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
{
Width = 200,
Height = 200,
- Children = new Controls.Controls
+ Children =
{
new Border
{
@@ -198,7 +198,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
{
Width = 200,
Height = 200,
- Children = new Controls.Controls
+ Children =
{
new Border
{
@@ -255,7 +255,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
Height = 200,
Background = Brushes.Red,
ClipToBounds = false,
- Children = new Controls.Controls
+ Children =
{
new Border
{
@@ -303,7 +303,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
Width = 100,
Height = 200,
Background = Brushes.Red,
- Children = new Controls.Controls
+ Children =
{
new Panel()
{
@@ -312,7 +312,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
Background = Brushes.Red,
Margin = new Thickness(0, 100, 0, 0),
ClipToBounds = true,
- Children = new Controls.Controls
+ Children =
{
(target = new Border()
{
@@ -354,7 +354,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
Width = 100,
Height = 200,
Background = Brushes.Red,
- Children = new Controls.Controls
+ Children =
{
(target = new Border()
{
@@ -374,7 +374,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
{
Content = new StackPanel()
{
- Children = new Controls.Controls
+ Children =
{
(item1 = new Border()
{
diff --git a/tests/Avalonia.Visuals.UnitTests/Rendering/ImmediateRendererTests_HitTesting.cs b/tests/Avalonia.Visuals.UnitTests/Rendering/ImmediateRendererTests_HitTesting.cs
index c8a19a9f46..9a1d8cb59c 100644
--- a/tests/Avalonia.Visuals.UnitTests/Rendering/ImmediateRendererTests_HitTesting.cs
+++ b/tests/Avalonia.Visuals.UnitTests/Rendering/ImmediateRendererTests_HitTesting.cs
@@ -126,7 +126,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
{
Width = 200,
Height = 200,
- Children = new Controls.Controls
+ Children =
{
new Border
{
@@ -171,7 +171,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
{
Width = 200,
Height = 200,
- Children = new Controls.Controls
+ Children =
{
new Border
{
@@ -238,7 +238,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
Height = 200,
Background = Brushes.Red,
ClipToBounds = false,
- Children = new Controls.Controls
+ Children =
{
new Border
{
@@ -287,7 +287,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
Width = 100,
Height = 200,
Background = Brushes.Red,
- Children = new Controls.Controls
+ Children =
{
new Panel()
{
@@ -296,7 +296,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
Background = Brushes.Red,
Margin = new Thickness(0, 100, 0, 0),
ClipToBounds = true,
- Children = new Controls.Controls
+ Children =
{
(target = new Border()
{
@@ -339,7 +339,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
Width = 100,
Height = 200,
Background = Brushes.Red,
- Children = new Controls.Controls
+ Children =
{
(target = new Border()
{
@@ -359,7 +359,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
{
Content = new StackPanel()
{
- Children = new Controls.Controls
+ Children =
{
(item1 = new Border()
{
diff --git a/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs b/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs
index d0f7671956..44b9ebe8ce 100644
--- a/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs
+++ b/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs
@@ -9,6 +9,8 @@ using Xunit;
using Avalonia.Layout;
using Moq;
using Avalonia.Platform;
+using System.Reactive.Subjects;
+using Avalonia.Data;
namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
{
@@ -620,13 +622,15 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
Margin = new Thickness(0, 10, 0, 0),
Child = border = new Border
{
- Opacity = 0.5,
Background = Brushes.Red,
Child = canvas = new Canvas(),
}
}
};
+ var animation = new BehaviorSubject(0.5);
+ border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
+
var scene = new Scene(tree);
var sceneBuilder = new SceneBuilder();
sceneBuilder.UpdateAll(scene);
diff --git a/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs b/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs
index ed74f12075..f2d137249a 100644
--- a/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs
+++ b/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs
@@ -7,14 +7,15 @@ using Avalonia.UnitTests;
using Avalonia.VisualTree;
using Xunit;
using Avalonia.Layout;
-using Avalonia.Rendering;
+using System.Reactive.Subjects;
+using Avalonia.Data;
namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
{
public partial class SceneBuilderTests
{
[Fact]
- public void Control_With_Transparency_Should_Start_New_Layer()
+ public void Control_With_Animated_Opacity_And_Children_Should_Start_New_Layer()
{
using (TestApplication())
{
@@ -31,10 +32,9 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
Padding = new Thickness(11),
Child = border = new Border
{
- Opacity = 0.5,
Background = Brushes.Red,
Padding = new Thickness(12),
- Child = canvas = new Canvas(),
+ Child = canvas = new Canvas()
}
}
};
@@ -42,6 +42,9 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
var layout = AvaloniaLocator.Current.GetService();
layout.ExecuteInitialLayoutPass(tree);
+ var animation = new BehaviorSubject(0.5);
+ border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
+
var scene = new Scene(tree);
var sceneBuilder = new SceneBuilder();
sceneBuilder.UpdateAll(scene);
@@ -58,7 +61,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
Assert.Equal(2, scene.Layers.Count());
Assert.Empty(scene.Layers.Select(x => x.LayerRoot).Except(new IVisual[] { tree, border }));
- border.Opacity = 1;
+ animation.OnCompleted();
scene = scene.Clone();
sceneBuilder.Update(scene, border);
@@ -80,13 +83,12 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
}
[Fact]
- public void Control_With_OpacityMask_Should_Start_New_Layer()
+ public void Control_With_Animated_Opacity_And_No_Children_Should_Not_Start_New_Layer()
{
using (TestApplication())
{
Decorator decorator;
Border border;
- Canvas canvas;
var tree = new TestRoot
{
Padding = new Thickness(10),
@@ -97,10 +99,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
Padding = new Thickness(11),
Child = border = new Border
{
- OpacityMask = Brushes.Red,
Background = Brushes.Red,
- Padding = new Thickness(12),
- Child = canvas = new Canvas(),
}
}
};
@@ -108,45 +107,19 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
var layout = AvaloniaLocator.Current.GetService();
layout.ExecuteInitialLayoutPass(tree);
+ var animation = new BehaviorSubject(0.5);
+ border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
+
var scene = new Scene(tree);
var sceneBuilder = new SceneBuilder();
sceneBuilder.UpdateAll(scene);
- var rootNode = (VisualNode)scene.Root;
- var borderNode = (VisualNode)scene.FindNode(border);
- var canvasNode = (VisualNode)scene.FindNode(canvas);
-
- Assert.Same(tree, rootNode.LayerRoot);
- Assert.Same(border, borderNode.LayerRoot);
- Assert.Same(border, canvasNode.LayerRoot);
- Assert.Equal(Brushes.Red, scene.Layers[border].OpacityMask);
-
- Assert.Equal(2, scene.Layers.Count());
- Assert.Empty(scene.Layers.Select(x => x.LayerRoot).Except(new IVisual[] { tree, border }));
-
- border.OpacityMask = null;
- scene = scene.Clone();
-
- sceneBuilder.Update(scene, border);
-
- rootNode = (VisualNode)scene.Root;
- borderNode = (VisualNode)scene.FindNode(border);
- canvasNode = (VisualNode)scene.FindNode(canvas);
-
- Assert.Same(tree, rootNode.LayerRoot);
- Assert.Same(tree, borderNode.LayerRoot);
- Assert.Same(tree, canvasNode.LayerRoot);
Assert.Single(scene.Layers);
-
- var rootDirty = scene.Layers[tree].Dirty;
-
- Assert.Single(rootDirty);
- Assert.Equal(new Rect(21, 21, 58, 78), rootDirty.Single());
}
}
[Fact]
- public void Removing_Transparent_Control_Should_Remove_Layers()
+ public void Removing_Control_With_Animated_Opacity_Should_Remove_Layers()
{
using (TestApplication())
{
@@ -163,13 +136,12 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
Padding = new Thickness(11),
Child = border = new Border
{
- Opacity = 0.5,
Background = Brushes.Red,
Padding = new Thickness(12),
Child = canvas = new Canvas
{
- Opacity = 0.75,
- },
+ Children = { new TextBlock() },
+ }
}
}
};
@@ -177,6 +149,10 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
var layout = AvaloniaLocator.Current.GetService();
layout.ExecuteInitialLayoutPass(tree);
+ var animation = new BehaviorSubject(0.5);
+ border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
+ canvas.Bind(Canvas.OpacityProperty, animation, BindingPriority.Animation);
+
var scene = new Scene(tree);
var sceneBuilder = new SceneBuilder();
sceneBuilder.UpdateAll(scene);
@@ -210,13 +186,12 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
Padding = new Thickness(11),
Child = border = new Border
{
- Opacity = 0.5,
Background = Brushes.Red,
Padding = new Thickness(12),
Child = canvas = new Canvas
{
- Opacity = 0.75,
- },
+ Children = { new TextBlock() },
+ }
}
}
};
@@ -224,6 +199,10 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
var layout = AvaloniaLocator.Current.GetService();
layout.ExecuteInitialLayoutPass(tree);
+ var animation = new BehaviorSubject(0.5);
+ border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
+ canvas.Bind(Canvas.OpacityProperty, animation, BindingPriority.Animation);
+
var scene = new Scene(tree);
var sceneBuilder = new SceneBuilder();
sceneBuilder.UpdateAll(scene);
@@ -256,6 +235,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
Child = border = new Border
{
Opacity = 0.5,
+ Child = new Canvas(),
}
}
};
@@ -263,6 +243,9 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
var layout = AvaloniaLocator.Current.GetService();
layout.ExecuteInitialLayoutPass(tree);
+ var animation = new BehaviorSubject(0.5);
+ border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
+
var scene = new Scene(tree);
var sceneBuilder = new SceneBuilder();
sceneBuilder.UpdateAll(scene);