diff --git a/.gitignore b/.gitignore
index 6ee6057d5f..2b2c9c3d0d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -195,3 +195,4 @@ Logs/
ModuleCache.noindex/
Build/Intermediates.noindex/
info.plist
+build-intermediate
diff --git a/.gitmodules b/.gitmodules
index 2d2a9ac497..22c56307b0 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
[submodule "src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github"]
path = src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github
url = https://github.com/AvaloniaUI/Portable.Xaml.git
+[submodule "nukebuild/Numerge"]
+ path = nukebuild/Numerge
+ url = https://github.com/kekekeks/Numerge.git
diff --git a/.ncrunch/Avalonia.Native.v3.ncrunchproject b/.ncrunch/Avalonia.Native.v3.ncrunchproject
new file mode 100644
index 0000000000..319cd523ce
--- /dev/null
+++ b/.ncrunch/Avalonia.Native.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ True
+
+
\ No newline at end of file
diff --git a/.nuke b/.nuke
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index b0c0c807cb..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-language: csharp
-os:
- - linux
-dist: trusty
-osx_image: xcode8.3
-env:
- global:
- - DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
- - DOTNET_CLI_TELEMETRY_OPTOUT=1
-mono:
- - 5.2.0
-dotnet: 2.1.200
-script:
- - sudo apt-get update
- - sudo apt-get install castxml
- - ./build.sh --target "Travis" --configuration "Release"
-notifications:
- email: false
- webhooks:
- urls:
- - https://webhooks.gitter.im/e/98f653320ef2b7506c05
- on_success: change
- on_failure: always
- on_start: never
diff --git a/Avalonia.sln b/Avalonia.sln
index 7fa5f7736a..3ed931933a 100644
--- a/Avalonia.sln
+++ b/Avalonia.sln
@@ -1,4 +1,4 @@
-Microsoft Visual Studio Solution File, Format Version 12.00
+Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2027
MinimumVisualStudioVersion = 10.0.40219.1
@@ -147,6 +147,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1
build\Splat.props = build\Splat.props
build\System.Memory.props = build\System.Memory.props
build\XUnit.props = build\XUnit.props
+ build\BuildTargets.targets = build\BuildTargets.targets
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{4D6FAF79-58B4-482F-9122-0668C346364C}"
@@ -188,6 +189,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia", "packages\Avalon
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Desktop", "src\Avalonia.Desktop\Avalonia.Desktop.csproj", "{3C471044-3640-45E3-B1B2-16D2FF8399EE}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Build.Tasks", "src\Avalonia.Build.Tasks\Avalonia.Build.Tasks.csproj", "{BF28998D-072C-439A-AFBB-2FE5021241E0}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "nukebuild\_build.csproj", "{3F00BC43-5095-477F-93D8-E65B08179A00}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Animation.UnitTests", "tests\Avalonia.Animation.UnitTests\Avalonia.Animation.UnitTests.csproj", "{AF227847-E65C-4BE9-BCE9-B551357788E0}"
+EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Shared\RenderHelpers\RenderHelpers.projitems*{3c4c0cb4-0c0f-4450-a37b-148c84ff905f}*SharedItemsImports = 13
@@ -213,6 +220,10 @@ Global
Release|iPhoneSimulator = Release|iPhoneSimulator
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {3F00BC43-5095-477F-93D8-E65B08179A00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3F00BC43-5095-477F-93D8-E65B08179A00}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3F00BC43-5095-477F-93D8-E65B08179A00}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3F00BC43-5095-477F-93D8-E65B08179A00}.Release|Any CPU.Build.0 = Release|Any CPU
{B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@@ -1687,6 +1698,54 @@ Global
{3C471044-3640-45E3-B1B2-16D2FF8399EE}.Release|iPhone.Build.0 = Release|Any CPU
{3C471044-3640-45E3-B1B2-16D2FF8399EE}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{3C471044-3640-45E3-B1B2-16D2FF8399EE}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Release|iPhone.Build.0 = Release|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {BF28998D-072C-439A-AFBB-2FE5021241E0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Release|iPhone.Build.0 = Release|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {AF227847-E65C-4BE9-BCE9-B551357788E0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1740,6 +1799,7 @@ Global
{E1240B49-7B4B-4371-A00E-068778C5CF0B} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{D49233F8-F29C-47DD-9975-C4C9E4502720} = {E870DCD7-F46A-498D-83FC-D0FD13E0A11C}
{3C471044-3640-45E3-B1B2-16D2FF8399EE} = {E870DCD7-F46A-498D-83FC-D0FD13E0A11C}
+ {AF227847-E65C-4BE9-BCE9-B551357788E0} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A}
diff --git a/Avalonia.sln.DotSettings b/Avalonia.sln.DotSettings
index d61208c358..1361172fff 100644
--- a/Avalonia.sln.DotSettings
+++ b/Avalonia.sln.DotSettings
@@ -35,4 +35,5 @@
<Policy Inspect="True" Prefix="s_" Suffix="" Style="aaBb" />
<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
<Policy Inspect="False" Prefix="T" Suffix="" Style="AaBb" />
- <Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" />
\ No newline at end of file
+ <Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" />
+ True
\ No newline at end of file
diff --git a/Directory.Build.props b/Directory.Build.props
index 50476c81f1..1f26df9bbc 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,5 +1,5 @@
- $(MSBuildThisFileDirectory)artifacts/nuget
+ $(MSBuildThisFileDirectory)build-intermediate/nuget
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index 484fb4586f..0000000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-os: Visual Studio 2017
-skip_branch_with_pr: true
-configuration:
-- Release
-environment:
- DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
- DOTNET_CLI_TELEMETRY_OPTOUT: 1
- NUGET_API_URL: https://www.nuget.org/api/v2/package
- MYGET_API_KEY:
- secure: OtVfyN3ErqQrDTnWH2HDfJDlCiu/i4/X4wFmK3ZXXP7HmCiXYPSbTjMPwwdOxRaK
- MYGET_API_URL: https://www.myget.org/F/avalonia-ci/api/v2/package
-init:
-- ps: if (Test-Path env:nuget_address) {[System.IO.File]::AppendAllText("C:\Windows\System32\drivers\etc\hosts", "`n$($env:nuget_address)`tapi.nuget.org")}
-before_build:
-- git submodule update --init
-build_script:
-- ps: .\build.ps1 -Target "AppVeyor" -Configuration "$env:configuration"
-
-test: off
-artifacts:
- - path: artifacts\nuget\*.nupkg
- - path: artifacts\zip\*.zip
- - path: artifacts\inspectcode.xml
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index f6929f8dee..8c5380e65e 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -11,19 +11,18 @@ jobs:
sudo apt-get install castxml
- task: CmdLine@2
- displayName: 'Install Cake'
+ displayName: 'Install Nuke'
inputs:
script: |
- dotnet tool install -g Cake.Tool --version 0.30.0
-
+ dotnet tool install --global Nuke.GlobalTool --version 0.12.3
- task: CmdLine@2
- displayName: 'Run Cake'
+ displayName: 'Run Nuke'
inputs:
script: |
export PATH="$PATH:$HOME/.dotnet/tools"
dotnet --info
printenv
- dotnet cake build.cake -target="Azure-Linux" -configuration="Release"
+ nuke --target CiAzureLinux --configuration=Release
- task: PublishTestResults@2
inputs:
@@ -55,13 +54,13 @@ jobs:
script: brew install castxml
- task: CmdLine@2
- displayName: 'Install Cake'
+ displayName: 'Install Nuke'
inputs:
script: |
- dotnet tool install -g Cake.Tool --version 0.30.0
+ dotnet tool install --global Nuke.GlobalTool --version 0.12.3
- task: CmdLine@2
- displayName: 'Run Cake'
+ displayName: 'Run Nuke'
inputs:
script: |
export COREHOST_TRACE=0
@@ -72,7 +71,7 @@ jobs:
export PATH="$PATH:$HOME/.dotnet/tools"
dotnet --info
printenv
- dotnet cake build.cake -target="Azure-OSX" -configuration="Release"
+ nuke --target CiAzureOSX --configuration Release
- task: PublishTestResults@2
inputs:
@@ -97,17 +96,17 @@ jobs:
vmImage: 'vs2017-win2016'
steps:
- task: CmdLine@2
- displayName: 'Install Cake'
+ displayName: 'Install Nuke'
inputs:
script: |
- dotnet tool install -g Cake.Tool --version 0.30.0
+ dotnet tool install --global Nuke.GlobalTool --version 0.12.3
- task: CmdLine@2
- displayName: 'Run Cake'
+ displayName: 'Run Nuke'
inputs:
script: |
set PATH=%PATH%;%USERPROFILE%\.dotnet\tools
- dotnet cake build.cake -target="Azure-Windows" -configuration="Release"
+ nuke --target CiAzureWindows --configuration Release
- task: PublishTestResults@2
inputs:
diff --git a/build.cake b/build.cake
deleted file mode 100644
index f10a12c4e6..0000000000
--- a/build.cake
+++ /dev/null
@@ -1,312 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// TOOLS
-///////////////////////////////////////////////////////////////////////////////
-
-#tool "nuget:?package=NuGet.CommandLine&version=4.7.1"
-#tool "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2018.2.3"
-#tool "nuget:?package=xunit.runner.console&version=2.3.1"
-#tool "nuget:?package=JetBrains.dotMemoryUnit&version=3.0.20171219.105559"
-
-///////////////////////////////////////////////////////////////////////////////
-// USINGS
-///////////////////////////////////////////////////////////////////////////////
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
-
-///////////////////////////////////////////////////////////////////////////////
-// SCRIPTS
-///////////////////////////////////////////////////////////////////////////////
-
-#load "./parameters.cake"
-
-///////////////////////////////////////////////////////////////////////////////
-// SETUP
-///////////////////////////////////////////////////////////////////////////////
-
-Setup(context =>
-{
- var parameters = new Parameters(context);
-
- Information("Building version {0} of Avalonia ({1}) using version {2} of Cake.",
- parameters.Version,
- parameters.Configuration,
- typeof(ICakeContext).Assembly.GetName().Version.ToString());
-
- if (parameters.IsRunningOnAppVeyor)
- {
- Information("Repository Name: " + BuildSystem.AppVeyor.Environment.Repository.Name);
- Information("Repository Branch: " + BuildSystem.AppVeyor.Environment.Repository.Branch);
- }
- Information("Target:" + context.TargetTask.Name);
- Information("Configuration: " + parameters.Configuration);
- Information("IsLocalBuild: " + parameters.IsLocalBuild);
- Information("IsRunningOnUnix: " + parameters.IsRunningOnUnix);
- Information("IsRunningOnWindows: " + parameters.IsRunningOnWindows);
- Information("IsRunningOnAppVeyor: " + parameters.IsRunningOnAppVeyor);
- Information("IsRunnongOnAzure:" + parameters.IsRunningOnAzure);
- Information("IsPullRequest: " + parameters.IsPullRequest);
- Information("IsMainRepo: " + parameters.IsMainRepo);
- Information("IsMasterBranch: " + parameters.IsMasterBranch);
- Information("IsReleaseBranch: " + parameters.IsReleaseBranch);
- Information("IsTagged: " + parameters.IsTagged);
- Information("IsReleasable: " + parameters.IsReleasable);
- Information("IsMyGetRelease: " + parameters.IsMyGetRelease);
- Information("IsNuGetRelease: " + parameters.IsNuGetRelease);
-
- return parameters;
-});
-
-///////////////////////////////////////////////////////////////////////////////
-// TEARDOWN
-///////////////////////////////////////////////////////////////////////////////
-
-Teardown((context, buildContext) =>
-{
- Information("Finished running tasks.");
-});
-
-///////////////////////////////////////////////////////////////////////////////
-// TASKS
-///////////////////////////////////////////////////////////////////////////////
-
-Task("Clean-Impl")
- .Does(data =>
-{
- CleanDirectories(data.BuildDirs);
- CleanDirectory(data.ArtifactsDir);
- CleanDirectory(data.NugetRoot);
- CleanDirectory(data.ZipRoot);
- CleanDirectory(data.TestResultsRoot);
-});
-
-void DotNetCoreBuild(Parameters parameters)
-{
- var settings = new DotNetCoreBuildSettings
- {
- Configuration = parameters.Configuration,
- MSBuildSettings = new DotNetCoreMSBuildSettings
- {
- Properties =
- {
- { "PackageVersion", new [] { parameters.Version } }
- }
- }
- };
-
- DotNetCoreBuild(parameters.MSBuildSolution, settings);
-}
-
-Task("Build-Impl")
- .Does(data =>
-{
- if(data.IsRunningOnWindows)
- {
- MSBuild(data.MSBuildSolution, settings => {
- settings.SetConfiguration(data.Configuration);
- settings.SetVerbosity(Verbosity.Minimal);
- settings.WithProperty("iOSRoslynPathHackRequired", "true");
- settings.WithProperty("PackageVersion", data.Version);
- settings.UseToolVersion(MSBuildToolVersion.VS2017);
- settings.WithRestore();
- });
- }
- else
- {
- DotNetCoreBuild(data);
- }
-});
-
-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);
- var frameworks = new List(){"netcoreapp2.0"};
- foreach(var fw in frameworks)
- {
- if(!fw.StartsWith("netcoreapp") && coreOnly)
- continue;
- Information("Running for " + fw);
-
- var settings = new DotNetCoreTestSettings {
- Configuration = parameters.Configuration,
- Framework = fw,
- NoBuild = true,
- NoRestore = true
- };
-
- if (parameters.PublishTestResults)
- {
- settings.Logger = "trx";
- settings.ResultsDirectory = parameters.TestResultsRoot;
- }
-
- DotNetCoreTest(project, settings);
- }
-}
-
-Task("Run-Unit-Tests-Impl")
- .WithCriteria((context, data) => !data.SkipTests)
- .Does(data =>
-{
- RunCoreTest("./tests/Avalonia.Base.UnitTests", data, false);
- RunCoreTest("./tests/Avalonia.Controls.UnitTests", data, false);
- RunCoreTest("./tests/Avalonia.Input.UnitTests", data, false);
- RunCoreTest("./tests/Avalonia.Interactivity.UnitTests", data, false);
- RunCoreTest("./tests/Avalonia.Layout.UnitTests", data, false);
- RunCoreTest("./tests/Avalonia.Markup.UnitTests", data, false);
- RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests", data, false);
- RunCoreTest("./tests/Avalonia.Styling.UnitTests", data, false);
- RunCoreTest("./tests/Avalonia.Visuals.UnitTests", data, false);
- RunCoreTest("./tests/Avalonia.Skia.UnitTests", data, false);
- RunCoreTest("./tests/Avalonia.ReactiveUI.UnitTests", data, false);
- if (data.IsRunningOnWindows)
- {
- RunCoreTest("./tests/Avalonia.Direct2D1.UnitTests", data, false);
- }
-});
-
-Task("Run-Designer-Tests-Impl")
- .WithCriteria((context, data) => !data.SkipTests)
- .Does(data =>
-{
- RunCoreTest("./tests/Avalonia.DesignerSupport.Tests", data, false);
-});
-
-Task("Run-Render-Tests-Impl")
- .WithCriteria((context, data) => !data.SkipTests)
- .WithCriteria((context, data) => data.IsRunningOnWindows)
- .Does(data =>
-{
- RunCoreTest("./tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj", data, true);
- RunCoreTest("./tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj", data, true);
-});
-
-Task("Run-Leak-Tests-Impl")
- .WithCriteria((context, data) => !data.SkipTests)
- .WithCriteria((context, data) => data.IsRunningOnWindows)
- .Does(() =>
-{
- var dotMemoryUnit = Context.Tools.Resolve("dotMemoryUnit.exe");
- var leakTestsExitCode = StartProcess(dotMemoryUnit, new ProcessSettings
- {
- Arguments = new ProcessArgumentBuilder()
- .Append(Context.Tools.Resolve("xunit.console.x86.exe").FullPath)
- .Append("--propagate-exit-code")
- .Append("--")
- .Append("tests\\Avalonia.LeakTests\\bin\\Release\\net461\\Avalonia.LeakTests.dll"),
- Timeout = 120000
- });
-
- if (leakTestsExitCode != 0)
- {
- throw new Exception("Leak Tests failed");
- }
-});
-
-Task("Zip-Files-Impl")
- .Does(data =>
-{
- Zip(data.BinRoot, data.ZipCoreArtifacts);
-
- Zip(data.NugetRoot, data.ZipNuGetArtifacts);
-
- Zip(data.ZipSourceControlCatalogDesktopDirs,
- data.ZipTargetControlCatalogDesktopDirs,
- GetFiles(data.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.dll") +
- GetFiles(data.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.config") +
- GetFiles(data.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.so") +
- GetFiles(data.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.dylib") +
- GetFiles(data.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.exe"));
-});
-
-void DotNetCorePack(Parameters parameters)
-{
- var settings = new DotNetCorePackSettings
- {
- Configuration = parameters.Configuration,
- MSBuildSettings = new DotNetCoreMSBuildSettings
- {
- Properties =
- {
- { "PackageVersion", new [] { parameters.Version } }
- }
- }
- };
-
- DotNetCorePack(parameters.MSBuildSolution, settings);
-}
-
-Task("Create-NuGet-Packages-Impl")
- .Does(data =>
-{
- if(data.IsRunningOnWindows)
- {
- MSBuild(data.MSBuildSolution, settings => {
- settings.SetConfiguration(data.Configuration);
- settings.SetVerbosity(Verbosity.Minimal);
- settings.WithProperty("iOSRoslynPathHackRequired", "true");
- settings.WithProperty("PackageVersion", data.Version);
- settings.UseToolVersion(MSBuildToolVersion.VS2017);
- settings.WithRestore();
- settings.WithTarget("Pack");
- });
- }
- else
- {
- DotNetCorePack(data);
- }
-});
-
-///////////////////////////////////////////////////////////////////////////////
-// TARGETS
-///////////////////////////////////////////////////////////////////////////////
-
-Task("Build")
- .IsDependentOn("Clean-Impl")
- .IsDependentOn("Build-Impl");
-
-Task("Run-Tests")
- .IsDependentOn("Build")
- .IsDependentOn("Run-Unit-Tests-Impl")
- .IsDependentOn("Run-Render-Tests-Impl")
- .IsDependentOn("Run-Designer-Tests-Impl")
- .IsDependentOn("Run-Leak-Tests-Impl");
-
-Task("Package")
- .IsDependentOn("Run-Tests")
- .IsDependentOn("Create-NuGet-Packages-Impl");
-
-Task("AppVeyor")
- .IsDependentOn("Package")
- .IsDependentOn("Zip-Files-Impl");
-
-Task("Travis")
- .IsDependentOn("Run-Tests");
-
-Task("Azure-Linux")
- .IsDependentOn("Run-Tests");
-
-Task("Azure-OSX")
- .IsDependentOn("Package")
- .IsDependentOn("Zip-Files-Impl");
-
-Task("Azure-Windows")
- .IsDependentOn("Package")
- .IsDependentOn("Zip-Files-Impl");
-
-///////////////////////////////////////////////////////////////////////////////
-// EXECUTE
-///////////////////////////////////////////////////////////////////////////////
-
-var target = Context.Argument("target", "Default");
-
-if (target == "Default")
-{
- target = Context.IsRunningOnWindows() ? "Package" : "Run-Tests";
-}
-
-RunTarget(target);
diff --git a/build.ps1 b/build.ps1
index 46696db2b2..57e2f80075 100644
--- a/build.ps1
+++ b/build.ps1
@@ -1,201 +1,69 @@
-##########################################################################
-# This is the Cake bootstrapper script for PowerShell.
-# This file was downloaded from https://github.com/cake-build/resources
-# Feel free to change this file to fit your needs.
-##########################################################################
-
-<#
-
-.SYNOPSIS
-This is a Powershell script to bootstrap a Cake build.
-
-.DESCRIPTION
-This Powershell script will download NuGet if missing, restore NuGet tools (including Cake)
-and execute your Cake build script with the parameters you provide.
-
-.PARAMETER Script
-The build script to execute.
-.PARAMETER Target
-The build script target to run.
-.PARAMETER Platform
-The build platform to use.
-.PARAMETER Configuration
-The build configuration to use.
-.PARAMETER Verbosity
-Specifies the amount of information to be displayed.
-.PARAMETER Experimental
-Tells Cake to use the latest Roslyn release.
-.PARAMETER WhatIf
-Performs a dry run of the build script.
-No tasks will be executed.
-.PARAMETER Mono
-Tells Cake to use the Mono scripting engine.
-.PARAMETER SkipToolPackageRestore
-Skips restoring of packages.
-.PARAMETER SkipTests
-Skips unit tests
-.PARAMETER ScriptArgs
-Remaining arguments are added here.
-
-.LINK
-http://cakebuild.net
-
-#>
-
[CmdletBinding()]
Param(
- [string]$Script = "build.cake",
- [string]$Target = "Default",
- [ValidateSet("Any CPU", "x86", "x64", "NetCoreOnly", "iPhone")]
- [string]$Platform = "Any CPU",
- [ValidateSet("Release", "Debug")]
- [string]$Configuration = "Release",
- [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
- [string]$Verbosity = "Verbose",
- [switch]$Experimental,
- [Alias("DryRun","Noop")]
- [switch]$WhatIf,
- [switch]$Mono,
- [switch]$SkipToolPackageRestore,
+ #[switch]$CustomParam,
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
- [string[]]$ScriptArgs
+ [string[]]$BuildArguments
)
-[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null
-function MD5HashFile([string] $filePath)
-{
- if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf))
- {
- return $null
- }
-
- [System.IO.Stream] $file = $null;
- [System.Security.Cryptography.MD5] $md5 = $null;
- try
- {
- $md5 = [System.Security.Cryptography.MD5]::Create()
- $file = [System.IO.File]::OpenRead($filePath)
- return [System.BitConverter]::ToString($md5.ComputeHash($file))
- }
- finally
- {
- if ($file -ne $null)
- {
- $file.Dispose()
- }
- }
-}
-
-Write-Host "Preparing to run build script..."
-
-if(!$PSScriptRoot){
- $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
-}
+Write-Output "Windows PowerShell $($Host.Version)"
-$TOOLS_DIR = Join-Path $PSScriptRoot "tools"
-$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe"
-$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe"
-$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
-$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config"
-$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum"
+Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { exit 1 }
+$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
-# Should we use mono?
-$UseMono = "";
-if($Mono.IsPresent) {
- Write-Verbose -Message "Using the Mono based scripting engine."
- $UseMono = "-mono"
-}
+###########################################################################
+# CONFIGURATION
+###########################################################################
-# Should we use the new Roslyn?
-$UseExperimental = "";
-if($Experimental.IsPresent -and !($Mono.IsPresent)) {
- Write-Verbose -Message "Using experimental version of Roslyn."
- $UseExperimental = "-experimental"
-}
+$BuildProjectFile = "$PSScriptRoot\nukebuild\_build.csproj"
+$TempDirectory = "$PSScriptRoot\\.tmp"
-# Is this a dry run?
-$UseDryRun = "";
-if($WhatIf.IsPresent) {
- $UseDryRun = "-dryrun"
-}
+$DotNetGlobalFile = "$PSScriptRoot\\global.json"
+$DotNetInstallUrl = "https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.ps1"
+$DotNetChannel = "Current"
-# Is this a dry run?
-$UseSkipTests = "";
-if($SkipTests.IsPresent) {
- $UseSkipTests = "-skip-tests"
-}
+$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 1
+$env:DOTNET_CLI_TELEMETRY_OPTOUT = 1
+$env:NUGET_XMLDOC_MODE = "skip"
-# Make sure tools folder exists
-if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
- Write-Verbose -Message "Creating tools directory..."
- New-Item -Path $TOOLS_DIR -Type directory | out-null
-}
+###########################################################################
+# EXECUTION
+###########################################################################
-# Make sure that packages.config exist.
-if (!(Test-Path $PACKAGES_CONFIG)) {
- Write-Verbose -Message "Downloading packages.config..."
- try { (New-Object System.Net.WebClient).DownloadFile("http://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch {
- Throw "Could not download packages.config."
- }
+function ExecSafe([scriptblock] $cmd) {
+ & $cmd
+ if ($LASTEXITCODE) { exit $LASTEXITCODE }
}
-# Try find NuGet.exe in path if not exists
-if (!(Test-Path $NUGET_EXE)) {
- Write-Verbose -Message "Trying to find nuget.exe in PATH..."
- $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_) }
- $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1
- if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) {
- Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)."
- $NUGET_EXE = $NUGET_EXE_IN_PATH.FullName
+# If global.json exists, load expected version
+if (Test-Path $DotNetGlobalFile) {
+ $DotNetGlobal = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json)
+ if ($DotNetGlobal.PSObject.Properties["sdk"] -and $DotNetGlobal.sdk.PSObject.Properties["version"]) {
+ $DotNetVersion = $DotNetGlobal.sdk.version
}
}
-# Try download NuGet.exe if not exists
-if (!(Test-Path $NUGET_EXE)) {
- Write-Verbose -Message "Downloading NuGet.exe..."
- try {
- (New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE)
- } catch {
- Throw "Could not download NuGet.exe."
- }
+# If dotnet is installed locally, and expected version is not set or installation matches the expected version
+if ((Get-Command "dotnet" -ErrorAction SilentlyContinue) -ne $null -and `
+ (!(Test-Path variable:DotNetVersion) -or $(& dotnet --version) -eq $DotNetVersion)) {
+ $env:DOTNET_EXE = (Get-Command "dotnet").Path
}
-
-# Save nuget.exe path to environment to be available to child processed
-$ENV:NUGET_EXE = $NUGET_EXE
-
-# Restore tools from NuGet?
-if(-Not $SkipToolPackageRestore.IsPresent) {
- Push-Location
- Set-Location $TOOLS_DIR
-
- # Check for changes in packages.config and remove installed tools if true.
- [string] $md5Hash = MD5HashFile($PACKAGES_CONFIG)
- if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or
- ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
- Write-Verbose -Message "Missing or changed package.config hash..."
- Remove-Item * -Recurse -Exclude packages.config,nuget.exe
+else {
+ $DotNetDirectory = "$TempDirectory\dotnet-win"
+ $env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe"
+
+ # Download install script
+ $DotNetInstallFile = "$TempDirectory\dotnet-install.ps1"
+ md -force $TempDirectory > $null
+ (New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile)
+
+ # Install by channel or version
+ if (!(Test-Path variable:DotNetVersion)) {
+ ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Channel $DotNetChannel -NoPath }
+ } else {
+ ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath }
}
-
- Write-Verbose -Message "Restoring tools from NuGet..."
- $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`""
-
- if ($LASTEXITCODE -ne 0) {
- Throw "An error occured while restoring NuGet tools."
- }
- else
- {
- $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII"
- }
- Write-Verbose -Message ($NuGetOutput | out-string)
- Pop-Location
}
-# Make sure that Cake has been installed.
-if (!(Test-Path $CAKE_EXE)) {
- Throw "Could not find Cake.exe at $CAKE_EXE"
-}
+Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)"
-# Start Cake
-Write-Host "Running build script..."
-Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -platform=`"$Platform`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseSkipTests $UseMono $UseDryRun $UseExperimental $ScriptArgs"
-exit $LASTEXITCODE
\ No newline at end of file
+ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile -- $BuildArguments }
diff --git a/build.sh b/build.sh
index 206a55d171..40b1c225a6 100755
--- a/build.sh
+++ b/build.sh
@@ -1,105 +1,72 @@
#!/usr/bin/env bash
-##########################################################################
-# This is the Cake bootstrapper script for Linux and OS X.
-# This file was downloaded from https://github.com/cake-build/resources
-# Feel free to change this file to fit your needs.
-##########################################################################
+echo $(bash --version 2>&1 | head -n 1)
-# Define directories.
-SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
-TOOLS_DIR=$SCRIPT_DIR/tools
-NUGET_EXE=$TOOLS_DIR/nuget.exe
-CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe
-PACKAGES_CONFIG=$TOOLS_DIR/packages.config
-PACKAGES_CONFIG_MD5=$TOOLS_DIR/packages.config.md5sum
-
-# Define md5sum or md5 depending on Linux/OSX
-MD5_EXE=
-if [[ "$(uname -s)" == "Darwin" ]]; then
- MD5_EXE="md5 -r"
-else
- MD5_EXE="md5sum"
-fi
-
-# Define default arguments.
-SCRIPT="build.cake"
-TARGET="Default"
-CONFIGURATION="Release"
-PLATFORM="Any CPU"
-VERBOSITY="verbose"
-DRYRUN=
-SKIP_TESTS=
-SHOW_VERSION=false
-SCRIPT_ARGUMENTS=()
-
-# Parse arguments.
+#CUSTOMPARAM=0
+BUILD_ARGUMENTS=()
for i in "$@"; do
- case $1 in
- -s|--script) SCRIPT="$2"; shift ;;
- -t|--target) TARGET="$2"; shift ;;
- -p|--platform) PLATFORM="$2"; shift ;;
- -c|--configuration) CONFIGURATION="$2"; shift ;;
- --skip-tests) SKIP_TESTS="-skip-tests"; shift ;;
- -v|--verbosity) VERBOSITY="$2"; shift ;;
- -d|--dryrun) DRYRUN="-dryrun" ;;
- --version) SHOW_VERSION=true ;;
- --) shift; SCRIPT_ARGUMENTS+=("$@"); break ;;
- *) SCRIPT_ARGUMENTS+=("$1") ;;
+ case $(echo $1 | awk '{print tolower($0)}') in
+ # -custom-param) CUSTOMPARAM=1;;
+ *) BUILD_ARGUMENTS+=("$1") ;;
esac
shift
done
-# Make sure the tools folder exist.
-if [ ! -d "$TOOLS_DIR" ]; then
- mkdir "$TOOLS_DIR"
-fi
+set -eo pipefail
+SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
-# Make sure that packages.config exist.
-if [ ! -f "$TOOLS_DIR/packages.config" ]; then
- echo "Downloading packages.config..."
- curl -Lsfo "$TOOLS_DIR/packages.config" http://cakebuild.net/download/bootstrapper/packages
- if [ $? -ne 0 ]; then
- echo "An error occured while downloading packages.config."
- exit 1
- fi
-fi
+###########################################################################
+# CONFIGURATION
+###########################################################################
-# Download NuGet if it does not exist.
-if [ ! -f "$NUGET_EXE" ]; then
- echo "Downloading NuGet..."
- curl -Lsfo "$NUGET_EXE" https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
- if [ $? -ne 0 ]; then
- echo "An error occured while downloading nuget.exe."
- exit 1
- fi
-fi
+BUILD_PROJECT_FILE="$SCRIPT_DIR/nukebuild/_build.csproj"
+TEMP_DIRECTORY="$SCRIPT_DIR//.tmp"
-# Restore tools from NuGet.
-pushd "$TOOLS_DIR" >/dev/null
-if [ ! -f $PACKAGES_CONFIG_MD5 ] || [ "$( cat $PACKAGES_CONFIG_MD5 | sed 's/\r$//' )" != "$( $MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' )" ]; then
- find . -type d ! -name . | xargs rm -rf
-fi
+DOTNET_GLOBAL_FILE="$SCRIPT_DIR//global.json"
+DOTNET_INSTALL_URL="https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.sh"
+DOTNET_CHANNEL="Current"
-mono "$NUGET_EXE" install -ExcludeVersion
-if [ $? -ne 0 ]; then
- echo "Could not restore NuGet packages."
- exit 1
-fi
+export DOTNET_CLI_TELEMETRY_OPTOUT=1
+export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
+export NUGET_XMLDOC_MODE="skip"
-$MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' >| $PACKAGES_CONFIG_MD5
+###########################################################################
+# EXECUTION
+###########################################################################
-popd >/dev/null
+function FirstJsonValue {
+ perl -nle 'print $1 if m{"'$1'": "([^"\-]+)",?}' <<< ${@:2}
+}
-# Make sure that Cake has been installed.
-if [ ! -f "$CAKE_EXE" ]; then
- echo "Could not find Cake.exe at '$CAKE_EXE'."
- exit 1
+# If global.json exists, load expected version
+if [ -f "$DOTNET_GLOBAL_FILE" ]; then
+ DOTNET_VERSION=$(FirstJsonValue "version" $(cat "$DOTNET_GLOBAL_FILE"))
+ if [ "$DOTNET_VERSION" == "" ]; then
+ unset DOTNET_VERSION
+ fi
fi
-# Start Cake
-if $SHOW_VERSION; then
- exec mono "$CAKE_EXE" -version
+# If dotnet is installed locally, and expected version is not set or installation matches the expected version
+if [[ -x "$(command -v dotnet)" && (-z ${DOTNET_VERSION+x} || $(dotnet --version) == "$DOTNET_VERSION") ]]; then
+ export DOTNET_EXE="$(command -v dotnet)"
else
- exec mono "$CAKE_EXE" $SCRIPT -verbosity=$VERBOSITY -platform="$PLATFORM" -configuration="$CONFIGURATION" -target=$TARGET $DRYRUN $SKIP_TESTS "${SCRIPT_ARGUMENTS[@]}"
+ DOTNET_DIRECTORY="$TEMP_DIRECTORY/dotnet-unix"
+ export DOTNET_EXE="$DOTNET_DIRECTORY/dotnet"
+
+ # Download install script
+ DOTNET_INSTALL_FILE="$TEMP_DIRECTORY/dotnet-install.sh"
+ mkdir -p "$TEMP_DIRECTORY"
+ curl -Lsfo "$DOTNET_INSTALL_FILE" "$DOTNET_INSTALL_URL"
+ chmod +x "$DOTNET_INSTALL_FILE"
+
+ # Install by channel or version
+ if [ -z ${DOTNET_VERSION+x} ]; then
+ "$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --channel "$DOTNET_CHANNEL" --no-path
+ else
+ "$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --version "$DOTNET_VERSION" --no-path
+ fi
fi
+
+echo "Microsoft (R) .NET Core SDK version $("$DOTNET_EXE" --version)"
+
+"$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" -- ${BUILD_ARGUMENTS[@]}
diff --git a/build/BuildTargets.targets b/build/BuildTargets.targets
new file mode 100644
index 0000000000..08ec039ec7
--- /dev/null
+++ b/build/BuildTargets.targets
@@ -0,0 +1,8 @@
+
+
+ $(MSBuildThisFileDirectory)\..\src\Avalonia.Build.Tasks\bin\$(Configuration)\netstandard2.0\Avalonia.Build.Tasks.dll
+ true
+
+
+
+
diff --git a/build/Magick.NET-Q16-AnyCPU.props b/build/Magick.NET-Q16-AnyCPU.props
index 4e600a1c11..21d9cdcb1f 100644
--- a/build/Magick.NET-Q16-AnyCPU.props
+++ b/build/Magick.NET-Q16-AnyCPU.props
@@ -1,5 +1,5 @@
-
+
diff --git a/build/ReferenceCoreLibraries.props b/build/ReferenceCoreLibraries.props
index bd9d6ad843..cffc2e0324 100644
--- a/build/ReferenceCoreLibraries.props
+++ b/build/ReferenceCoreLibraries.props
@@ -1,5 +1,4 @@
-
diff --git a/build/SkiaSharp.props b/build/SkiaSharp.props
index 35c979a95e..a43c99e978 100644
--- a/build/SkiaSharp.props
+++ b/build/SkiaSharp.props
@@ -1,6 +1,6 @@
-
-
+
+
diff --git a/cake.config b/cake.config
deleted file mode 100644
index 8089cd4084..0000000000
--- a/cake.config
+++ /dev/null
@@ -1,15 +0,0 @@
-; This is the default configuration file for Cake.
-; This file was downloaded from https://github.com/cake-build/resources
-
-[Nuget]
-Source=https://api.nuget.org/v3/index.json
-UseInProcessClient=true
-LoadDependencies=false
-
-[Paths]
-Tools=./tools
-Addins=./tools/Addins
-Modules=./tools/Modules
-
-[Settings]
-SkipVerification=false
diff --git a/native/Avalonia.Native/src/OSX/gl.mm b/native/Avalonia.Native/src/OSX/gl.mm
index a62098a074..083adc927d 100644
--- a/native/Avalonia.Native/src/OSX/gl.mm
+++ b/native/Avalonia.Native/src/OSX/gl.mm
@@ -208,9 +208,8 @@ public:
virtual ~AvnGlRenderingSession()
{
- glFlush();
[_context flushBuffer];
- [_context setView:nil];
+ [NSOpenGLContext clearCurrentContext];
CGLUnlockContext([_context CGLContextObj]);
[_view unlockFocus];
}
@@ -241,9 +240,8 @@ public:
auto gl = _context;
CGLLockContext([_context CGLContextObj]);
[gl setView: _view];
+ [gl update];
[gl makeCurrentContext];
- auto frame = [_view frame];
-
*ret = new AvnGlRenderingSession(_window, _view, gl);
return S_OK;
}
diff --git a/nukebuild/.editorconfig b/nukebuild/.editorconfig
new file mode 100644
index 0000000000..d6009b3c0f
--- /dev/null
+++ b/nukebuild/.editorconfig
@@ -0,0 +1,8 @@
+# editorconfig.org
+
+# top-most EditorConfig file
+root = false
+
+# C# files
+[*.cs]
+dotnet_style_require_accessibility_modifiers = never
diff --git a/nukebuild/Build.cs b/nukebuild/Build.cs
new file mode 100644
index 0000000000..a14842cfd3
--- /dev/null
+++ b/nukebuild/Build.cs
@@ -0,0 +1,245 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Threading;
+using Nuke.Common;
+using Nuke.Common.Git;
+using Nuke.Common.ProjectModel;
+using Nuke.Common.Tooling;
+using Nuke.Common.Tools.DotNet;
+using Nuke.Common.Tools.MSBuild;
+using Nuke.Common.Utilities;
+using static Nuke.Common.EnvironmentInfo;
+using static Nuke.Common.IO.FileSystemTasks;
+using static Nuke.Common.IO.PathConstruction;
+using static Nuke.Common.Tools.MSBuild.MSBuildTasks;
+using static Nuke.Common.Tools.DotNet.DotNetTasks;
+using static Nuke.Common.Tools.Xunit.XunitTasks;
+
+
+/*
+ Before editing this file, install support plugin for your IDE,
+ running and debugging a particular target (optionally without deps) would be way easier
+ ReSharper/Rider - https://plugins.jetbrains.com/plugin/10803-nuke-support
+ VSCode - https://marketplace.visualstudio.com/items?itemName=nuke.support
+
+ */
+
+partial class Build : NukeBuild
+{
+ BuildParameters Parameters { get; set; }
+ protected override void OnBuildInitialized()
+ {
+ Parameters = new BuildParameters(this);
+ Information("Building version {0} of Avalonia ({1}) using version {2} of Nuke.",
+ Parameters.Version,
+ Parameters.Configuration,
+ typeof(NukeBuild).Assembly.GetName().Version.ToString());
+
+ if (Parameters.IsLocalBuild)
+ {
+ Information("Repository Name: " + Parameters.RepositoryName);
+ Information("Repository Branch: " + Parameters.RepositoryBranch);
+ }
+ Information("Configuration: " + Parameters.Configuration);
+ Information("IsLocalBuild: " + Parameters.IsLocalBuild);
+ Information("IsRunningOnUnix: " + Parameters.IsRunningOnUnix);
+ Information("IsRunningOnWindows: " + Parameters.IsRunningOnWindows);
+ Information("IsRunningOnAzure:" + Parameters.IsRunningOnAzure);
+ Information("IsPullRequest: " + Parameters.IsPullRequest);
+ Information("IsMainRepo: " + Parameters.IsMainRepo);
+ Information("IsMasterBranch: " + Parameters.IsMasterBranch);
+ Information("IsReleaseBranch: " + Parameters.IsReleaseBranch);
+ Information("IsReleasable: " + Parameters.IsReleasable);
+ Information("IsMyGetRelease: " + Parameters.IsMyGetRelease);
+ Information("IsNuGetRelease: " + Parameters.IsNuGetRelease);
+ }
+
+ Target Clean => _ => _.Executes(() =>
+ {
+ DeleteDirectories(Parameters.BuildDirs);
+ EnsureCleanDirectories(Parameters.BuildDirs);
+ EnsureCleanDirectory(Parameters.ArtifactsDir);
+ EnsureCleanDirectory(Parameters.NugetIntermediateRoot);
+ EnsureCleanDirectory(Parameters.NugetRoot);
+ EnsureCleanDirectory(Parameters.ZipRoot);
+ EnsureCleanDirectory(Parameters.TestResultsRoot);
+ });
+
+ Target Compile => _ => _
+ .DependsOn(Clean)
+ .Executes(() =>
+ {
+
+ if (Parameters.IsRunningOnWindows)
+ MSBuild(Parameters.MSBuildSolution, c => c
+ .SetArgumentConfigurator(a => a.Add("/r"))
+ .SetConfiguration(Parameters.Configuration)
+ .SetVerbosity(MSBuildVerbosity.Minimal)
+ .AddProperty("PackageVersion", Parameters.Version)
+ .AddProperty("iOSRoslynPathHackRequired", "true")
+ .SetToolsVersion(MSBuildToolsVersion._15_0)
+ .AddTargets("Build")
+ );
+
+ else
+ DotNetBuild(Parameters.MSBuildSolution, c => c
+ .AddProperty("PackageVersion", Parameters.Version)
+ .SetConfiguration(Parameters.Configuration)
+ );
+ });
+
+ void RunCoreTest(string project, bool coreOnly = false)
+ {
+ if(!project.EndsWith(".csproj"))
+ project = System.IO.Path.Combine(project, System.IO.Path.GetFileName(project)+".csproj");
+ Information("Running tests from " + project);
+ var frameworks = new List(){"netcoreapp2.0"};
+ foreach(var fw in frameworks)
+ {
+ if(!fw.StartsWith("netcoreapp") && coreOnly)
+ continue;
+ Information("Running for " + fw);
+ DotNetTest(c =>
+ {
+ c = c
+ .SetProjectFile(project)
+ .SetConfiguration(Parameters.Configuration)
+ .SetFramework(fw)
+ .EnableNoBuild()
+ .EnableNoRestore();
+ // NOTE: I can see that we could maybe add another extension method "Switch" or "If" to make this more convenient
+ if (Parameters.PublishTestResults)
+ c = c.SetLogger("trx").SetResultsDirectory(Parameters.TestResultsRoot);
+ return c;
+ });
+ }
+ }
+
+ Target RunCoreLibsTests => _ => _
+ .OnlyWhen(() => !Parameters.SkipTests)
+ .DependsOn(Compile)
+ .Executes(() =>
+ {
+ RunCoreTest("./tests/Avalonia.Animation.UnitTests", false);
+ RunCoreTest("./tests/Avalonia.Base.UnitTests", false);
+ RunCoreTest("./tests/Avalonia.Controls.UnitTests", false);
+ RunCoreTest("./tests/Avalonia.Input.UnitTests", false);
+ RunCoreTest("./tests/Avalonia.Interactivity.UnitTests", false);
+ RunCoreTest("./tests/Avalonia.Layout.UnitTests", false);
+ RunCoreTest("./tests/Avalonia.Markup.UnitTests", false);
+ RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests", false);
+ RunCoreTest("./tests/Avalonia.Styling.UnitTests", false);
+ RunCoreTest("./tests/Avalonia.Visuals.UnitTests", false);
+ RunCoreTest("./tests/Avalonia.Skia.UnitTests", false);
+ RunCoreTest("./tests/Avalonia.ReactiveUI.UnitTests", false);
+ });
+
+ Target RunRenderTests => _ => _
+ .OnlyWhen(() => !Parameters.SkipTests)
+ .DependsOn(Compile)
+ .Executes(() =>
+ {
+ RunCoreTest("./tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj", true);
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ RunCoreTest("./tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj", true);
+ });
+
+ Target RunDesignerTests => _ => _
+ .OnlyWhen(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows)
+ .DependsOn(Compile)
+ .Executes(() =>
+ {
+ RunCoreTest("./tests/Avalonia.DesignerSupport.Tests", false);
+ });
+
+ [PackageExecutable("JetBrains.dotMemoryUnit", "dotMemoryUnit.exe")] readonly Tool DotMemoryUnit;
+
+ Target RunLeakTests => _ => _
+ .OnlyWhen(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows)
+ .DependsOn(Compile)
+ .Executes(() =>
+ {
+ var testAssembly = "tests\\Avalonia.LeakTests\\bin\\Release\\net461\\Avalonia.LeakTests.dll";
+ DotMemoryUnit(
+ $"{XunitPath.DoubleQuoteIfNeeded()} --propagate-exit-code -- {testAssembly}",
+ timeout: 120_000);
+ });
+
+ Target ZipFiles => _ => _
+ .After(CreateNugetPackages, Compile, RunCoreLibsTests, Package)
+ .Executes(() =>
+ {
+ var data = Parameters;
+ Zip(data.ZipCoreArtifacts, data.BinRoot);
+ Zip(data.ZipNuGetArtifacts, data.NugetRoot);
+ Zip(data.ZipTargetControlCatalogDesktopDir,
+ GlobFiles(data.ZipSourceControlCatalogDesktopDir, "*.dll").Concat(
+ GlobFiles(data.ZipSourceControlCatalogDesktopDir, "*.config")).Concat(
+ GlobFiles(data.ZipSourceControlCatalogDesktopDir, "*.so")).Concat(
+ GlobFiles(data.ZipSourceControlCatalogDesktopDir, "*.dylib")).Concat(
+ GlobFiles(data.ZipSourceControlCatalogDesktopDir, "*.exe")));
+ });
+
+ Target CreateIntermediateNugetPackages => _ => _
+ .DependsOn(Compile)
+ .After(RunTests)
+ .Executes(() =>
+ {
+ if (Parameters.IsRunningOnWindows)
+
+ MSBuild(Parameters.MSBuildSolution, c => c
+ .SetConfiguration(Parameters.Configuration)
+ .SetVerbosity(MSBuildVerbosity.Minimal)
+ .AddProperty("PackageVersion", Parameters.Version)
+ .AddProperty("iOSRoslynPathHackRequired", "true")
+ .SetToolsVersion(MSBuildToolsVersion._15_0)
+ .AddTargets("Pack"));
+ else
+ DotNetPack(Parameters.MSBuildSolution, c =>
+ c.SetConfiguration(Parameters.Configuration)
+ .AddProperty("PackageVersion", Parameters.Version));
+ });
+
+ Target CreateNugetPackages => _ => _
+ .DependsOn(CreateIntermediateNugetPackages)
+ .Executes(() =>
+ {
+ var config = Numerge.MergeConfiguration.LoadFile(RootDirectory / "nukebuild" / "numerge.config");
+ EnsureCleanDirectory(Parameters.NugetRoot);
+ if(!Numerge.NugetPackageMerger.Merge(Parameters.NugetIntermediateRoot, Parameters.NugetRoot, config,
+ new NumergeNukeLogger()))
+ throw new Exception("Package merge failed");
+ });
+
+ Target RunTests => _ => _
+ .DependsOn(RunCoreLibsTests)
+ .DependsOn(RunRenderTests)
+ .DependsOn(RunDesignerTests)
+ .DependsOn(RunLeakTests);
+
+ Target Package => _ => _
+ .DependsOn(RunTests)
+ .DependsOn(CreateNugetPackages);
+
+ Target CiAzureLinux => _ => _
+ .DependsOn(RunTests);
+
+ Target CiAzureOSX => _ => _
+ .DependsOn(Package)
+ .DependsOn(ZipFiles);
+
+ Target CiAzureWindows => _ => _
+ .DependsOn(Package)
+ .DependsOn(ZipFiles);
+
+
+ public static int Main() =>
+ RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
+ ? Execute(x => x.Package)
+ : Execute(x => x.RunTests);
+
+}
diff --git a/nukebuild/BuildParameters.cs b/nukebuild/BuildParameters.cs
new file mode 100644
index 0000000000..5f8ec7267e
--- /dev/null
+++ b/nukebuild/BuildParameters.cs
@@ -0,0 +1,142 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Xml.Linq;
+using Nuke.Common;
+using Nuke.Common.BuildServers;
+using Nuke.Common.Execution;
+using Nuke.Common.IO;
+using static Nuke.Common.IO.FileSystemTasks;
+using static Nuke.Common.IO.PathConstruction;
+using static Nuke.Common.Tools.MSBuild.MSBuildTasks;
+
+public partial class Build
+{
+ [Parameter("configuration")]
+ public string NukeArgConfiguration { get; set; }
+
+ [Parameter("skip-tests")]
+ public bool NukeArgSkipTests { get; set; }
+
+ [Parameter("force-nuget-version")]
+ public string NukeArgForceNugetVersion { get; set; }
+
+ public class BuildParameters
+ {
+ public string Configuration { get; }
+ public bool SkipTests { get; }
+ public string MainRepo { get; }
+ public string MasterBranch { get; }
+ public string RepositoryName { get; }
+ public string RepositoryBranch { get; }
+ public string ReleaseConfiguration { get; }
+ public string ReleaseBranchPrefix { get; }
+ public string MSBuildSolution { get; }
+ public bool IsLocalBuild { get; }
+ public bool IsRunningOnUnix { get; }
+ public bool IsRunningOnWindows { get; }
+ public bool IsRunningOnAzure { get; }
+ public bool IsPullRequest { get; }
+ public bool IsMainRepo { get; }
+ public bool IsMasterBranch { get; }
+ public bool IsReleaseBranch { get; }
+ public bool IsReleasable { get; }
+ public bool IsMyGetRelease { get; }
+ public bool IsNuGetRelease { get; }
+ public bool PublishTestResults { get; }
+ public string Version { get; }
+ public AbsolutePath ArtifactsDir { get; }
+ public AbsolutePath NugetIntermediateRoot { get; }
+ public AbsolutePath NugetRoot { get; }
+ public AbsolutePath ZipRoot { get; }
+ public AbsolutePath BinRoot { get; }
+ public AbsolutePath TestResultsRoot { get; }
+ public string DirSuffix { get; }
+ public List BuildDirs { get; }
+ public string FileZipSuffix { get; }
+ public AbsolutePath ZipCoreArtifacts { get; }
+ public AbsolutePath ZipNuGetArtifacts { get; }
+ public AbsolutePath ZipSourceControlCatalogDesktopDir { get; }
+ public AbsolutePath ZipTargetControlCatalogDesktopDir { get; }
+
+
+ public BuildParameters(Build b)
+ {
+ // ARGUMENTS
+ Configuration = b.NukeArgConfiguration ?? "Release";
+ SkipTests = b.NukeArgSkipTests;
+
+ // CONFIGURATION
+ MainRepo = "https://github.com/AvaloniaUI/Avalonia";
+ MasterBranch = "refs/heads/master";
+ ReleaseBranchPrefix = "refs/heads/release/";
+ ReleaseConfiguration = "Release";
+ MSBuildSolution = RootDirectory / "dirs.proj";
+
+ // PARAMETERS
+ IsLocalBuild = Host == HostType.Console;
+ IsRunningOnUnix = Environment.OSVersion.Platform == PlatformID.Unix ||
+ Environment.OSVersion.Platform == PlatformID.MacOSX;
+ IsRunningOnWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
+ IsRunningOnAzure = Host == HostType.TeamServices ||
+ Environment.GetEnvironmentVariable("LOGNAME") == "vsts";
+
+ if (IsRunningOnAzure)
+ {
+ RepositoryName = TeamServices.Instance.RepositoryUri;
+ RepositoryBranch = TeamServices.Instance.SourceBranch;
+ IsPullRequest = TeamServices.Instance.PullRequestId.HasValue;
+ IsMainRepo = StringComparer.OrdinalIgnoreCase.Equals(MainRepo, TeamServices.Instance.RepositoryUri);
+ }
+ IsMainRepo =
+ StringComparer.OrdinalIgnoreCase.Equals(MainRepo,
+ RepositoryName);
+ IsMasterBranch = StringComparer.OrdinalIgnoreCase.Equals(MasterBranch,
+ RepositoryBranch);
+ IsReleaseBranch = RepositoryBranch?.StartsWith(ReleaseBranchPrefix, StringComparison.OrdinalIgnoreCase) ==
+ true;
+
+ IsReleasable = StringComparer.OrdinalIgnoreCase.Equals(ReleaseConfiguration, Configuration);
+ IsMyGetRelease = IsReleasable;
+ IsNuGetRelease = IsMainRepo && IsReleasable && IsReleaseBranch;
+
+ // VERSION
+ Version = b.NukeArgForceNugetVersion ?? GetVersion();
+
+ if (IsRunningOnAzure)
+ {
+ if (!IsNuGetRelease)
+ {
+ // Use AssemblyVersion with Build as version
+ Version += "-build" + Environment.GetEnvironmentVariable("BUILD_BUILDID") + "-beta";
+ }
+
+ PublishTestResults = true;
+ }
+
+ // DIRECTORIES
+ ArtifactsDir = RootDirectory / "artifacts";
+ NugetRoot = ArtifactsDir / "nuget";
+ NugetIntermediateRoot = RootDirectory / "build-intermediate" / "nuget";
+ ZipRoot = ArtifactsDir / "zip";
+ BinRoot = ArtifactsDir / "bin";
+ TestResultsRoot = ArtifactsDir / "test-results";
+ BuildDirs = GlobDirectories(RootDirectory, "**bin").Concat(GlobDirectories(RootDirectory, "**obj")).ToList();
+ DirSuffix = Configuration;
+ FileZipSuffix = Version + ".zip";
+ ZipCoreArtifacts = ZipRoot / ("Avalonia-" + FileZipSuffix);
+ ZipNuGetArtifacts = ZipRoot / ("Avalonia-NuGet-" + FileZipSuffix);
+ ZipSourceControlCatalogDesktopDir =
+ RootDirectory / ("samples/ControlCatalog.Desktop/bin/" + DirSuffix + "/net461");
+ ZipTargetControlCatalogDesktopDir = ZipRoot / ("ControlCatalog.Desktop-" + FileZipSuffix);
+ }
+
+ string GetVersion()
+ {
+ var xdoc = XDocument.Load(RootDirectory / "build/SharedVersion.props");
+ return xdoc.Descendants().First(x => x.Name.LocalName == "Version").Value;
+ }
+ }
+
+}
diff --git a/nukebuild/Numerge b/nukebuild/Numerge
new file mode 160000
index 0000000000..4464343aef
--- /dev/null
+++ b/nukebuild/Numerge
@@ -0,0 +1 @@
+Subproject commit 4464343aef5c8ab7a42fcb20a483a6058199f8b8
diff --git a/nukebuild/Shims.cs b/nukebuild/Shims.cs
new file mode 100644
index 0000000000..461d617643
--- /dev/null
+++ b/nukebuild/Shims.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.IO.Compression;
+using System.Linq;
+using Nuke.Common;
+using Nuke.Common.IO;
+using Numerge;
+
+public partial class Build
+{
+ static void Information(string info)
+ {
+ Logger.Info(info);
+ }
+
+ static void Information(string info, params object[] args)
+ {
+ Logger.Info(info, args);
+ }
+
+ private void Zip(PathConstruction.AbsolutePath target, params string[] paths) => Zip(target, paths.AsEnumerable());
+
+ private void Zip(PathConstruction.AbsolutePath target, IEnumerable paths)
+ {
+ var targetPath = target.ToString();
+ bool finished = false, atLeastOneFileAdded = false;
+ try
+ {
+ using (var targetStream = File.Create(targetPath))
+ using(var archive = new System.IO.Compression.ZipArchive(targetStream, ZipArchiveMode.Create))
+ {
+ void AddFile(string path, string relativePath)
+ {
+ var e = archive.CreateEntry(relativePath.Replace("\\", "/"), CompressionLevel.Optimal);
+ using (var entryStream = e.Open())
+ using (var fileStream = File.OpenRead(path))
+ fileStream.CopyTo(entryStream);
+ atLeastOneFileAdded = true;
+ }
+
+ foreach (var path in paths)
+ {
+ if (Directory.Exists(path))
+ {
+ var dirInfo = new DirectoryInfo(path);
+ var rootPath = Path.GetDirectoryName(dirInfo.FullName);
+ foreach(var fsEntry in dirInfo.EnumerateFileSystemInfos("*", SearchOption.AllDirectories))
+ {
+ if (fsEntry is FileInfo)
+ {
+ var relPath = Path.GetRelativePath(rootPath, fsEntry.FullName);
+ AddFile(fsEntry.FullName, relPath);
+ }
+ }
+ }
+ else if(File.Exists(path))
+ {
+ var name = Path.GetFileName(path);
+ AddFile(path, name);
+ }
+ }
+ }
+
+ finished = true;
+ }
+ finally
+ {
+ try
+ {
+ if (!finished || !atLeastOneFileAdded)
+ File.Delete(targetPath);
+ }
+ catch
+ {
+ //Ignore
+ }
+ }
+ }
+
+ class NumergeNukeLogger : INumergeLogger
+ {
+ public void Log(NumergeLogLevel level, string message)
+ {
+ if(level == NumergeLogLevel.Error)
+ Logger.Error(message);
+ else if (level == NumergeLogLevel.Warning)
+ Logger.Warn(message);
+ else
+ Logger.Info(message);
+ }
+ }
+}
diff --git a/nukebuild/_build.csproj b/nukebuild/_build.csproj
new file mode 100644
index 0000000000..e02acff007
--- /dev/null
+++ b/nukebuild/_build.csproj
@@ -0,0 +1,37 @@
+
+
+
+ Exe
+ netcoreapp2.0
+ false
+
+ False
+ CS0649;CS0169
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nukebuild/_build.csproj.DotSettings b/nukebuild/_build.csproj.DotSettings
new file mode 100644
index 0000000000..9aac7d8e8d
--- /dev/null
+++ b/nukebuild/_build.csproj.DotSettings
@@ -0,0 +1,24 @@
+
+ False
+ Implicit
+ Implicit
+ ExpressionBody
+ 0
+ NEXT_LINE
+ True
+ False
+ 120
+ IF_OWNER_IS_SINGLE_LINE
+ WRAP_IF_LONG
+ False
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
diff --git a/nukebuild/numerge.config b/nukebuild/numerge.config
new file mode 100644
index 0000000000..e4e15d693d
--- /dev/null
+++ b/nukebuild/numerge.config
@@ -0,0 +1,23 @@
+{
+ "Packages":
+ [
+ {
+ "Id": "Avalonia",
+ "MergeAll": true,
+ "Exclude": ["Avalonia.Remote.Protocol"],
+ "IncomingIncludeAssetsOverride": "",
+ "Merge": [
+ {
+ "Id": "Avalonia.Build.Tasks",
+ "IgnoreMissingFrameworkBinaries": true,
+ "DoNotMergeDependencies": true
+ },
+ {
+ "Id": "Avalonia.DesktopRuntime",
+ "IgnoreMissingFrameworkBinaries": true,
+ "IgnoreMissingFrameworkDependencies": true
+ }
+ ]
+ }
+ ]
+}
diff --git a/packages/Avalonia/Avalonia.csproj b/packages/Avalonia/Avalonia.csproj
index dee42fb795..489cb228aa 100644
--- a/packages/Avalonia/Avalonia.csproj
+++ b/packages/Avalonia/Avalonia.csproj
@@ -1,10 +1,12 @@
-
+
netstandard2.0;net461;netcoreapp2.0
-
+
+
+
@@ -27,14 +29,18 @@
false
None
- <_PackageFiles Include="Avalonia.props">
- build/Avalonia.props
- false
- None
-
-
+
+
+ true
+ build\
+
+
+ true
+ build\
+
+
diff --git a/packages/Avalonia/Avalonia.props b/packages/Avalonia/Avalonia.props
index 8234dc4fde..6f21971d3d 100644
--- a/packages/Avalonia/Avalonia.props
+++ b/packages/Avalonia/Avalonia.props
@@ -2,5 +2,8 @@
$(MSBuildThisFileDirectory)\..\tools\netcoreapp2.0\designer\Avalonia.Designer.HostApp.dll
$(MSBuildThisFileDirectory)\..\tools\net461\designer\Avalonia.Designer.HostApp.exe
+ $(MSBuildThisFileDirectory)\..\tools\netstandard2.0\Avalonia.Build.Tasks.dll
+ false
+
diff --git a/packages/Avalonia/Avalonia.targets b/packages/Avalonia/Avalonia.targets
new file mode 100644
index 0000000000..50306f2cdc
--- /dev/null
+++ b/packages/Avalonia/Avalonia.targets
@@ -0,0 +1,3 @@
+
+
+
diff --git a/packages/Avalonia/AvaloniaBuildTasks.props b/packages/Avalonia/AvaloniaBuildTasks.props
new file mode 100644
index 0000000000..30bafa37ee
--- /dev/null
+++ b/packages/Avalonia/AvaloniaBuildTasks.props
@@ -0,0 +1,3 @@
+
+
+
diff --git a/packages/Avalonia/AvaloniaBuildTasks.targets b/packages/Avalonia/AvaloniaBuildTasks.targets
new file mode 100644
index 0000000000..10f971cc4c
--- /dev/null
+++ b/packages/Avalonia/AvaloniaBuildTasks.targets
@@ -0,0 +1,43 @@
+
+
+ <_AvaloniaUseExternalMSBuild>$(AvaloniaUseExternalMSBuild)
+ <_AvaloniaUseExternalMSBuild Condition="'$(_AvaloniaForceInternalMSBuild)' == 'true'">false
+
+
+
+
+
+
+
+ $(IntermediateOutputPath)/Avalonia/resources
+
+
+
+ !AvaloniaResources
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/readme.md b/readme.md
index 9d113cf2ef..9280125323 100644
--- a/readme.md
+++ b/readme.md
@@ -2,9 +2,9 @@
# Avalonia
-| Gitter Chat | Build Status (Win, Linux, OSX) | Appveyor Build Status | Open Collective |
-|---|---|---|---|
-| [](https://gitter.im/AvaloniaUI/Avalonia?utm_campaign=pr-badge&utm_content=badge&utm_medium=badge&utm_source=badge) | [](https://dev.azure.com/AvaloniaUI/AvaloniaUI/_build/latest?definitionId=4) | [](https://ci.appveyor.com/project/AvaloniaUI/Avalonia/branch/master) | [](#backers) [](#sponsors) |
+| Gitter Chat | Build Status (Win, Linux, OSX) | Open Collective |
+|---|---|---|
+| [](https://gitter.im/AvaloniaUI/Avalonia?utm_campaign=pr-badge&utm_content=badge&utm_medium=badge&utm_source=badge) | [](https://dev.azure.com/AvaloniaUI/AvaloniaUI/_build/latest?definitionId=4) | [](#backers) [](#sponsors) |
## About
diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs
index 1f53dedc14..57c8b700df 100644
--- a/samples/ControlCatalog.NetCore/Program.cs
+++ b/samples/ControlCatalog.NetCore/Program.cs
@@ -23,6 +23,7 @@ namespace ControlCatalog.NetCore
break;
}
}
+
if (args.Contains("--fbdev"))
AppBuilder.Configure().InitializeWithLinuxFramebuffer(tl =>
{
@@ -30,7 +31,12 @@ namespace ControlCatalog.NetCore
System.Threading.ThreadPool.QueueUserWorkItem(_ => ConsoleSilencer());
});
else
- BuildAvaloniaApp().Start();
+ BuildAvaloniaApp().Start(AppMain, args);
+ }
+
+ static void AppMain(Application app, string[] args)
+ {
+ app.Run(new MainWindow());
}
///
@@ -46,4 +52,4 @@ namespace ControlCatalog.NetCore
Console.ReadKey(true);
}
}
-}
\ No newline at end of file
+}
diff --git a/samples/ControlCatalog/App.xaml b/samples/ControlCatalog/App.xaml
index 19a22bb6ed..67220e6dd0 100644
--- a/samples/ControlCatalog/App.xaml
+++ b/samples/ControlCatalog/App.xaml
@@ -1,7 +1,9 @@
-
+
-
-
+
+
-
+
diff --git a/samples/ControlCatalog/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj
index d0a746f87d..463a8a8db6 100644
--- a/samples/ControlCatalog/ControlCatalog.csproj
+++ b/samples/ControlCatalog/ControlCatalog.csproj
@@ -6,10 +6,11 @@
%(Filename)
-
+
Designer
-
-
+
+
+
@@ -24,4 +25,5 @@
+
diff --git a/samples/ControlCatalog/DecoratedWindow.xaml b/samples/ControlCatalog/DecoratedWindow.xaml
index b2f6497caa..cb6016b324 100644
--- a/samples/ControlCatalog/DecoratedWindow.xaml
+++ b/samples/ControlCatalog/DecoratedWindow.xaml
@@ -1,7 +1,8 @@
-
+ xmlns:local="clr-namespace:ControlCatalog" HasSystemDecorations="False" Name="Window">
@@ -18,7 +19,13 @@
- Hello world!
+
+ Hello world!
+
+ Decorated
+
+ CanResize
+
@@ -30,4 +37,4 @@
-
\ No newline at end of file
+
diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml
index 06f808b726..0f7f2e80a8 100644
--- a/samples/ControlCatalog/MainView.xaml
+++ b/samples/ControlCatalog/MainView.xaml
@@ -1,31 +1,42 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ x:Class="ControlCatalog.MainView"
+ Background="{DynamicResource ThemeBackgroundBrush}"
+ Foreground="{DynamicResource ThemeForegroundBrush}"
+ FontSize="{DynamicResource FontSizeNormal}">
+
+
+ Light
+ Dark
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/MainView.xaml.cs b/samples/ControlCatalog/MainView.xaml.cs
index 0be5d25a09..a498b17bdd 100644
--- a/samples/ControlCatalog/MainView.xaml.cs
+++ b/samples/ControlCatalog/MainView.xaml.cs
@@ -2,6 +2,7 @@ using System.Collections;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
+using Avalonia.Markup.Xaml.Styling;
using Avalonia.Platform;
using ControlCatalog.Pages;
@@ -27,6 +28,22 @@ namespace ControlCatalog
});
}
+ var light = AvaloniaXamlLoader.Parse(@"");
+ var dark = AvaloniaXamlLoader.Parse(@"");
+ var themes = this.Find("Themes");
+ themes.SelectionChanged += (sender, e) =>
+ {
+ switch (themes.SelectedIndex)
+ {
+ case 0:
+ Styles[0] = light;
+ break;
+ case 1:
+ Styles[0] = dark;
+ break;
+ }
+ };
+ Styles.Add(light);
}
private void InitializeComponent()
diff --git a/samples/ControlCatalog/MainWindow.xaml b/samples/ControlCatalog/MainWindow.xaml
index 7029273a84..4bae60b2a6 100644
--- a/samples/ControlCatalog/MainWindow.xaml
+++ b/samples/ControlCatalog/MainWindow.xaml
@@ -1,6 +1,8 @@
+ Icon="/Assets/test_icon.ico"
+ xmlns:local="clr-namespace:ControlCatalog"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ x:Class="ControlCatalog.MainWindow">
-
\ No newline at end of file
+
diff --git a/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml b/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml
index 28bdc7ac71..0ca3567970 100644
--- a/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml
+++ b/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml
@@ -1,4 +1,6 @@
-
+
AutoCompleteBox
A control into which the user can input text
diff --git a/samples/ControlCatalog/Pages/BorderPage.xaml b/samples/ControlCatalog/Pages/BorderPage.xaml
index 09f591d59d..c30056d5e5 100644
--- a/samples/ControlCatalog/Pages/BorderPage.xaml
+++ b/samples/ControlCatalog/Pages/BorderPage.xaml
@@ -1,4 +1,6 @@
-
+
Border
A control which decorates a child with a border and background
diff --git a/samples/ControlCatalog/Pages/ButtonPage.xaml b/samples/ControlCatalog/Pages/ButtonPage.xaml
index a4690e32e1..39d89590c2 100644
--- a/samples/ControlCatalog/Pages/ButtonPage.xaml
+++ b/samples/ControlCatalog/Pages/ButtonPage.xaml
@@ -1,5 +1,6 @@
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ x:Class="ControlCatalog.Pages.ButtonPage">
Button
A button control
diff --git a/samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml b/samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml
index fba15f6e77..c3f9f65dd9 100644
--- a/samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml
+++ b/samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml
@@ -1,5 +1,6 @@
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ x:Class="ControlCatalog.Pages.ButtonSpinnerPage">
ButtonSpinner
diff --git a/samples/ControlCatalog/Pages/CalendarPage.xaml b/samples/ControlCatalog/Pages/CalendarPage.xaml
index c47fd766fb..dbd0dba37b 100644
--- a/samples/ControlCatalog/Pages/CalendarPage.xaml
+++ b/samples/ControlCatalog/Pages/CalendarPage.xaml
@@ -1,5 +1,6 @@
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ x:Class="ControlCatalog.Pages.CalendarPage">
Calendar
A calendar control for selecting dates
diff --git a/samples/ControlCatalog/Pages/CanvasPage.xaml b/samples/ControlCatalog/Pages/CanvasPage.xaml
index d6c138a4f7..d154e717a4 100644
--- a/samples/ControlCatalog/Pages/CanvasPage.xaml
+++ b/samples/ControlCatalog/Pages/CanvasPage.xaml
@@ -1,4 +1,6 @@
-
+
Canvas
A panel which lays out its children by explicit coordinates
diff --git a/samples/ControlCatalog/Pages/CarouselPage.xaml b/samples/ControlCatalog/Pages/CarouselPage.xaml
index cf9b13c00c..b08ff565e3 100644
--- a/samples/ControlCatalog/Pages/CarouselPage.xaml
+++ b/samples/ControlCatalog/Pages/CarouselPage.xaml
@@ -1,4 +1,6 @@
-
+
Carousel
An items control that displays its items as pages that fill the control.
@@ -11,9 +13,9 @@
-
-
-
+
+
+
-
\ No newline at end of file
+
diff --git a/samples/ControlCatalog/Pages/SliderPage.xaml b/samples/ControlCatalog/Pages/SliderPage.xaml
index 6db71b5fcc..58f7b881fe 100644
--- a/samples/ControlCatalog/Pages/SliderPage.xaml
+++ b/samples/ControlCatalog/Pages/SliderPage.xaml
@@ -1,4 +1,6 @@
-
+
Slider
A control that lets the user select from a range of values by moving a Thumb control along a Track.
@@ -18,4 +20,4 @@
-
\ No newline at end of file
+
diff --git a/samples/ControlCatalog/Pages/TabControlPage.xaml b/samples/ControlCatalog/Pages/TabControlPage.xaml
index 5b10e7d790..01ddc0ddca 100644
--- a/samples/ControlCatalog/Pages/TabControlPage.xaml
+++ b/samples/ControlCatalog/Pages/TabControlPage.xaml
@@ -1,4 +1,7 @@
-
+
-
-
-
-
-
+
This is the first page in the TabControl.
-
+
-
-
-
-
-
+
This is the second page in the TabControl.
-
+
-
-
-
-
-
+
You should not see this.
@@ -82,10 +61,7 @@
+ Text="{Binding Header}">
diff --git a/samples/ControlCatalog/Pages/TabControlPage.xaml.cs b/samples/ControlCatalog/Pages/TabControlPage.xaml.cs
index 808d90a49c..a38a3ab4cb 100644
--- a/samples/ControlCatalog/Pages/TabControlPage.xaml.cs
+++ b/samples/ControlCatalog/Pages/TabControlPage.xaml.cs
@@ -26,13 +26,13 @@ namespace ControlCatalog.Pages
{
Header = "Arch",
Text = "This is the first templated tab page.",
- Image = LoadBitmap("resm:ControlCatalog.Assets.delicate-arch-896885_640.jpg?assembly=ControlCatalog"),
+ Image = LoadBitmap("avares://ControlCatalog/Assets/delicate-arch-896885_640.jpg"),
},
new TabItemViewModel
{
Header = "Leaf",
Text = "This is the second templated tab page.",
- Image = LoadBitmap("resm:ControlCatalog.Assets.maple-leaf-888807_640.jpg?assembly=ControlCatalog"),
+ Image = LoadBitmap("avares://ControlCatalog/Assets/maple-leaf-888807_640.jpg"),
},
new TabItemViewModel
{
diff --git a/samples/ControlCatalog/Pages/TextBoxPage.xaml b/samples/ControlCatalog/Pages/TextBoxPage.xaml
index 5f94e15cec..0c0a4d705b 100644
--- a/samples/ControlCatalog/Pages/TextBoxPage.xaml
+++ b/samples/ControlCatalog/Pages/TextBoxPage.xaml
@@ -1,4 +1,6 @@
-
+
TextBox
A control into which the user can input text
@@ -33,11 +35,20 @@
Text="Multiline TextBox with no TextWrapping.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est." />
+ resm fonts
+
+
+ res fonts
+
+
+
+
+
-
\ No newline at end of file
+
diff --git a/samples/ControlCatalog/Pages/ToolTipPage.xaml b/samples/ControlCatalog/Pages/ToolTipPage.xaml
index ad832b9b82..cbe1e3059c 100644
--- a/samples/ControlCatalog/Pages/ToolTipPage.xaml
+++ b/samples/ControlCatalog/Pages/ToolTipPage.xaml
@@ -1,4 +1,6 @@
-
+
ToolTip
@@ -38,4 +40,4 @@
-
\ No newline at end of file
+
diff --git a/samples/ControlCatalog/Pages/TreeViewPage.xaml b/samples/ControlCatalog/Pages/TreeViewPage.xaml
index 1ab49dbb30..f8f3cd5848 100644
--- a/samples/ControlCatalog/Pages/TreeViewPage.xaml
+++ b/samples/ControlCatalog/Pages/TreeViewPage.xaml
@@ -1,4 +1,6 @@
-
+
TreeView
Displays a hierachical tree of data.
@@ -16,4 +18,4 @@
-
\ No newline at end of file
+
diff --git a/samples/ControlCatalog/Pages/ViewboxPage.xaml b/samples/ControlCatalog/Pages/ViewboxPage.xaml
new file mode 100644
index 0000000000..e78cf2bc22
--- /dev/null
+++ b/samples/ControlCatalog/Pages/ViewboxPage.xaml
@@ -0,0 +1,66 @@
+
+
+
+ F1 M 16.6309,18.6563C 17.1309,
+ 8.15625 29.8809,14.1563 29.8809,
+ 14.1563C 30.8809,11.1563 34.1308,
+ 11.4063 34.1308,11.4063C 33.5,12
+ 34.6309,13.1563 34.6309,13.1563C
+ 32.1309,13.1562 31.1309,14.9062
+ 31.1309,14.9062C 41.1309,23.9062
+ 32.6309,27.9063 32.6309,27.9062C
+ 24.6309,24.9063 21.1309,22.1562
+ 16.6309,18.6563 Z M 16.6309,19.9063C
+ 21.6309,24.1563 25.1309,26.1562
+ 31.6309,28.6562C 31.6309,28.6562
+ 26.3809,39.1562 18.3809,36.1563C
+ 18.3809,36.1563 18,38 16.3809,36.9063C
+ 15,36 16.3809,34.9063 16.3809,34.9063C
+ 16.3809,34.9063 10.1309,30.9062 16.6309,19.9063 Z
+
+
+
+
+
+ Viewbox
+ A control used to scale single child.
+
+
+ None
+ Fill
+ Uniform
+ UniformToFill
+
+
+ Hello World!
+
+
+ Hello World!
+
+
+ Hello World!
+
+
+ Hello World!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/ViewboxPage.xaml.cs b/samples/ControlCatalog/Pages/ViewboxPage.xaml.cs
new file mode 100644
index 0000000000..1b5f4bc7f4
--- /dev/null
+++ b/samples/ControlCatalog/Pages/ViewboxPage.xaml.cs
@@ -0,0 +1,18 @@
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace ControlCatalog.Pages
+{
+ public class ViewboxPage : UserControl
+ {
+ public ViewboxPage()
+ {
+ this.InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
diff --git a/samples/ControlCatalog/SideBar.xaml b/samples/ControlCatalog/SideBar.xaml
index 3ec8e43b07..f97a3064e7 100644
--- a/samples/ControlCatalog/SideBar.xaml
+++ b/samples/ControlCatalog/SideBar.xaml
@@ -1,5 +1,6 @@
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ x:Class="ControlCatalog.SideBar">
+
@@ -120,6 +150,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+
diff --git a/samples/RenderDemo/Pages/ClippingPage.xaml b/samples/RenderDemo/Pages/ClippingPage.xaml
index 2bdecfc0ef..ca1b297363 100644
--- a/samples/RenderDemo/Pages/ClippingPage.xaml
+++ b/samples/RenderDemo/Pages/ClippingPage.xaml
@@ -8,7 +8,7 @@ xmlns="https://github.com/avaloniaui">
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
+
-
-
-
-
-
+
+
+
+
+
diff --git a/src/Avalonia.Animation/Animatable.cs b/src/Avalonia.Animation/Animatable.cs
index 516f383b92..4b0f76c5d5 100644
--- a/src/Avalonia.Animation/Animatable.cs
+++ b/src/Avalonia.Animation/Animatable.cs
@@ -7,6 +7,7 @@ using System.Linq;
using System.Reactive.Linq;
using Avalonia.Collections;
using Avalonia.Data;
+using Avalonia.Animation.Animators;
namespace Avalonia.Animation
{
diff --git a/src/Avalonia.Animation/Animation.cs b/src/Avalonia.Animation/Animation.cs
index d7efc69e10..ae6deb585c 100644
--- a/src/Avalonia.Animation/Animation.cs
+++ b/src/Avalonia.Animation/Animation.cs
@@ -7,68 +7,209 @@ using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Threading.Tasks;
+using Avalonia.Animation.Animators;
using Avalonia.Animation.Easings;
using Avalonia.Collections;
+using Avalonia.Data;
+using Avalonia.Metadata;
namespace Avalonia.Animation
{
///
/// Tracks the progress of an animation.
///
- public class Animation : AvaloniaList, IAnimation
+ public class Animation : AvaloniaObject, IAnimation
{
+ ///
+ /// Defines the property.
+ ///
+ public static readonly DirectProperty DurationProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(_duration),
+ o => o._duration,
+ (o, v) => o._duration = v);
+
+ ///
+ /// Defines the property.
+ ///
+ public static readonly DirectProperty IterationCountProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(_iterationCount),
+ o => o._iterationCount,
+ (o, v) => o._iterationCount = v);
+
+ ///
+ /// Defines the property.
+ ///
+ public static readonly DirectProperty PlaybackDirectionProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(_playbackDirection),
+ o => o._playbackDirection,
+ (o, v) => o._playbackDirection = v);
+
+ ///
+ /// Defines the property.
+ ///
+ public static readonly DirectProperty FillModeProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(_fillMode),
+ o => o._fillMode,
+ (o, v) => o._fillMode = v);
+
+ ///
+ /// Defines the property.
+ ///
+ public static readonly DirectProperty EasingProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(_easing),
+ o => o._easing,
+ (o, v) => o._easing = v);
+
+ ///
+ /// Defines the property.
+ ///
+ public static readonly DirectProperty DelayProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(_delay),
+ o => o._delay,
+ (o, v) => o._delay = v);
+
+ ///
+ /// Defines the property.
+ ///
+ public static readonly DirectProperty DelayBetweenIterationsProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(_delayBetweenIterations),
+ o => o._delayBetweenIterations,
+ (o, v) => o._delayBetweenIterations = v);
+
+ ///
+ /// Defines the property.
+ ///
+ public static readonly DirectProperty SpeedRatioProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(_speedRatio),
+ o => o._speedRatio,
+ (o, v) => o._speedRatio = v,
+ defaultBindingMode: BindingMode.TwoWay);
+
+ private TimeSpan _duration;
+ private IterationCount _iterationCount = new IterationCount(1);
+ private PlaybackDirection _playbackDirection;
+ private FillMode _fillMode;
+ private Easing _easing = new LinearEasing();
+ private TimeSpan _delay = TimeSpan.Zero;
+ private TimeSpan _delayBetweenIterations = TimeSpan.Zero;
+ private double _speedRatio = 1d;
+
///
/// Gets or sets the active time of this animation.
///
- public TimeSpan Duration { get; set; }
+ public TimeSpan Duration
+ {
+ get { return _duration; }
+ set { SetAndRaise(DurationProperty, ref _duration, value); }
+ }
///
/// Gets or sets the repeat count for this animation.
///
- public RepeatCount RepeatCount { get; set; }
+ public IterationCount IterationCount
+ {
+ get { return _iterationCount; }
+ set { SetAndRaise(IterationCountProperty, ref _iterationCount, value); }
+ }
///
/// Gets or sets the playback direction for this animation.
///
- public PlaybackDirection PlaybackDirection { get; set; }
+ public PlaybackDirection PlaybackDirection
+ {
+ get { return _playbackDirection; }
+ set { SetAndRaise(PlaybackDirectionProperty, ref _playbackDirection, value); }
+ }
///
/// Gets or sets the value fill mode for this animation.
- ///
- public FillMode FillMode { get; set; }
+ ///
+ public FillMode FillMode
+ {
+ get { return _fillMode; }
+ set { SetAndRaise(FillModeProperty, ref _fillMode, value); }
+ }
///
/// Gets or sets the easing function to be used for this animation.
///
- public Easing Easing { get; set; } = new LinearEasing();
-
- ///
- /// Gets or sets the speed multiple for this animation.
- ///
- public double SpeedRatio { get; set; } = 1d;
+ public Easing Easing
+ {
+ get { return _easing; }
+ set { SetAndRaise(EasingProperty, ref _easing, value); }
+ }
///
- /// Gets or sets the delay time for this animation.
+ /// Gets or sets the initial delay time for this animation.
///
- ///
- /// Describes a delay to be added before the animation starts, and optionally between
- /// repeats of the animation if is set.
- ///
- public TimeSpan Delay { get; set; }
+ public TimeSpan Delay
+ {
+ get { return _delay; }
+ set { SetAndRaise(DelayProperty, ref _delay, value); }
+ }
///
- /// Gets or sets a value indicating whether will be applied between
- /// iterations of the animation.
+ /// Gets or sets the delay time in between iterations.
+ ///
+ public TimeSpan DelayBetweenIterations
+ {
+ get { return _delayBetweenIterations; }
+ set { SetAndRaise(DelayBetweenIterationsProperty, ref _delayBetweenIterations, value); }
+ }
+
+ ///
+ /// Gets or sets the speed multiple for this animation.
///
- ///
- /// If this property is not set, then will only be applied to the first
- /// iteration of the animation.
- ///
- public bool DelayBetweenIterations { get; set; }
+ public double SpeedRatio
+ {
+ get { return _speedRatio; }
+ set { SetAndRaise(SpeedRatioProperty, ref _speedRatio, value); }
+ }
+
+ ///
+ /// Obsolete: Do not use this property, use instead.
+ ///
+ ///
+ [Obsolete("This property has been superceded by IterationCount.")]
+ public string RepeatCount
+ {
+ get { return IterationCount.ToString(); }
+ set
+ {
+ var val = value.ToUpper();
+ val = val.Replace("LOOP", "INFINITE");
+ val = val.Replace("NONE", "1");
+ IterationCount = IterationCount.Parse(val);
+ }
+ }
+
+ ///
+ /// Gets the children of the .
+ ///
+ [Content]
+ public KeyFrames Children { get; } = new KeyFrames();
private readonly static List<(Func Condition, Type Animator)> Animators = new List<(Func, Type)>
{
- ( prop => typeof(double).IsAssignableFrom(prop.PropertyType), typeof(DoubleAnimator) )
+ ( prop => typeof(bool).IsAssignableFrom(prop.PropertyType), typeof(BoolAnimator) ),
+ ( prop => typeof(byte).IsAssignableFrom(prop.PropertyType), typeof(ByteAnimator) ),
+ ( prop => typeof(Int16).IsAssignableFrom(prop.PropertyType), typeof(Int16Animator) ),
+ ( prop => typeof(Int32).IsAssignableFrom(prop.PropertyType), typeof(Int32Animator) ),
+ ( prop => typeof(Int64).IsAssignableFrom(prop.PropertyType), typeof(Int64Animator) ),
+ ( prop => typeof(UInt16).IsAssignableFrom(prop.PropertyType), typeof(UInt16Animator) ),
+ ( prop => typeof(UInt32).IsAssignableFrom(prop.PropertyType), typeof(UInt32Animator) ),
+ ( prop => typeof(UInt64).IsAssignableFrom(prop.PropertyType), typeof(UInt64Animator) ),
+ ( prop => typeof(float).IsAssignableFrom(prop.PropertyType), typeof(FloatAnimator) ),
+ ( prop => typeof(double).IsAssignableFrom(prop.PropertyType), typeof(DoubleAnimator) ),
+ ( prop => typeof(decimal).IsAssignableFrom(prop.PropertyType), typeof(DecimalAnimator) ),
};
public static void RegisterAnimator(Func condition)
@@ -95,9 +236,9 @@ namespace Avalonia.Animation
var animatorKeyFrames = new List();
var subscriptions = new List();
- foreach (var keyframe in this)
+ foreach (var keyframe in Children)
{
- foreach (var setter in keyframe)
+ foreach (var setter in keyframe.Setters)
{
var handler = GetAnimatorType(setter.Property);
@@ -179,7 +320,7 @@ namespace Avalonia.Animation
{
var run = new TaskCompletionSource