committed by
GitHub
200 changed files with 5401 additions and 1911 deletions
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -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 |
|||
@ -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 |
|||
@ -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<Parameters>(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<Parameters>((context, buildContext) => |
|||
{ |
|||
Information("Finished running tasks."); |
|||
}); |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
// TASKS |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
|
|||
Task("Clean-Impl") |
|||
.Does<Parameters>(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<Parameters>(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<string>(){"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<Parameters>((context, data) => !data.SkipTests) |
|||
.Does<Parameters>(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<Parameters>((context, data) => !data.SkipTests) |
|||
.Does<Parameters>(data => |
|||
{ |
|||
RunCoreTest("./tests/Avalonia.DesignerSupport.Tests", data, false); |
|||
}); |
|||
|
|||
Task("Run-Render-Tests-Impl") |
|||
.WithCriteria<Parameters>((context, data) => !data.SkipTests) |
|||
.WithCriteria<Parameters>((context, data) => data.IsRunningOnWindows) |
|||
.Does<Parameters>(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<Parameters>((context, data) => !data.SkipTests) |
|||
.WithCriteria<Parameters>((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<Parameters>(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<Parameters>(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); |
|||
@ -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 |
|||
ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile -- $BuildArguments } |
|||
|
|||
@ -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[@]} |
|||
|
|||
@ -0,0 +1,8 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<PropertyGroup> |
|||
<AvaloniaBuildTasksLocation>$(MSBuildThisFileDirectory)\..\src\Avalonia.Build.Tasks\bin\$(Configuration)\netstandard2.0\Avalonia.Build.Tasks.dll</AvaloniaBuildTasksLocation> |
|||
<AvaloniaUseExternalMSBuild>true</AvaloniaUseExternalMSBuild> |
|||
</PropertyGroup> |
|||
<Import Project="$(MSBuildThisFileDirectory)\..\packages\Avalonia\AvaloniaBuildTasks.props"/> |
|||
<Import Project="$(MSBuildThisFileDirectory)\..\packages\Avalonia\AvaloniaBuildTasks.targets"/> |
|||
</Project> |
|||
@ -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 |
|||
@ -0,0 +1,231 @@ |
|||
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.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<string>(){"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.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 && Parameters.IsRunningOnWindows) |
|||
.DependsOn(Compile) |
|||
.Executes(() => |
|||
{ |
|||
RunCoreTest("./tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj", true); |
|||
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 CreateNugetPackages => _ => _ |
|||
.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 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<Build>(x => x.Package) |
|||
: Execute<Build>(x => x.RunTests); |
|||
|
|||
} |
|||
@ -0,0 +1,140 @@ |
|||
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 NugetRoot { get; } |
|||
public AbsolutePath ZipRoot { get; } |
|||
public AbsolutePath BinRoot { get; } |
|||
public AbsolutePath TestResultsRoot { get; } |
|||
public string DirSuffix { get; } |
|||
public List<string> 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"; |
|||
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); |
|||
} |
|||
|
|||
private static string GetVersion() |
|||
{ |
|||
var xdoc = XDocument.Load("./build/SharedVersion.props"); |
|||
return xdoc.Descendants().First(x => x.Name.LocalName == "Version").Value; |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,79 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.IO.Compression; |
|||
using System.Linq; |
|||
using Nuke.Common; |
|||
using Nuke.Common.IO; |
|||
|
|||
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<string> 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
|
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<OutputType>Exe</OutputType> |
|||
<TargetFramework>netcoreapp2.0</TargetFramework> |
|||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> |
|||
<RootNamespace></RootNamespace> |
|||
<IsPackable>False</IsPackable> |
|||
<NoWarn>CS0649;CS0169</NoWarn> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Nuke.Common" Version="0.12.3" /> |
|||
<PackageReference Include="xunit.runner.console" Version="2.3.1" /> |
|||
<PackageReference Include="JetBrains.dotMemoryUnit" Version="3.0.20171219.105559" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<NukeMetadata Include="**\*.json" Exclude="bin\**;obj\**" /> |
|||
<NukeExternalFiles Include="**\*.*.ext" Exclude="bin\**;obj\**" /> |
|||
<None Remove="*.csproj.DotSettings;*.ref.*.txt" /> |
|||
|
|||
<!-- Common build related files --> |
|||
<None Include="..\build.ps1" /> |
|||
<None Include="..\build.sh" /> |
|||
<None Include="..\.nuke" /> |
|||
<None Include="..\global.json" Condition="Exists('..\global.json')" /> |
|||
<None Include="..\nuget.config" Condition="Exists('..\nuget.config')" /> |
|||
<None Include="..\Jenkinsfile" Condition="Exists('..\Jenkinsfile')" /> |
|||
<None Include="..\appveyor.yml" Condition="Exists('..\appveyor.yml')" /> |
|||
<None Include="..\.travis.yml" Condition="Exists('..\.travis.yml')" /> |
|||
<None Include="..\GitVersion.yml" Condition="Exists('..\GitVersion.yml')" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,24 @@ |
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> |
|||
<s:Boolean x:Key="/Default/CodeInspection/ImplicitNullability/EnableFields/@EntryValue">False</s:Boolean> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/DEFAULT_INTERNAL_MODIFIER/@EntryValue">Implicit</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/DEFAULT_PRIVATE_MODIFIER/@EntryValue">Implicit</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/METHOD_OR_OPERATOR_BODY/@EntryValue">ExpressionBody</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/ThisQualifier/INSTANCE_MEMBERS_QUALIFY_MEMBERS/@EntryValue">0</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue">NEXT_LINE</s:String> |
|||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_USER_LINEBREAKS/@EntryValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_AFTER_INVOCATION_LPAR/@EntryValue">False</s:Boolean> |
|||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_ATTRIBUTE_LENGTH_FOR_SAME_LINE/@EntryValue">120</s:Int64> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">IF_OWNER_IS_SINGLE_LINE</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_ARGUMENTS_STYLE/@EntryValue">WRAP_IF_LONG</s:String> |
|||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ANONYMOUSMETHOD_ON_SINGLE_LINE/@EntryValue">False</s:Boolean> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> |
|||
@ -0,0 +1,3 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<Import Project="$(MSBuildThisFileDirectory)\AvaloniaBuildTasks.targets"/> |
|||
</Project> |
|||
@ -0,0 +1,3 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,43 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<PropertyGroup> |
|||
<_AvaloniaUseExternalMSBuild>$(AvaloniaUseExternalMSBuild)</_AvaloniaUseExternalMSBuild> |
|||
<_AvaloniaUseExternalMSBuild Condition="'$(_AvaloniaForceInternalMSBuild)' == 'true'">false</_AvaloniaUseExternalMSBuild> |
|||
</PropertyGroup> |
|||
|
|||
<UsingTask TaskName="GenerateAvaloniaResourcesTask" |
|||
AssemblyFile="$(AvaloniaBuildTasksLocation)" |
|||
/> |
|||
|
|||
|
|||
<Target Name="AddAvaloniaResources" BeforeTargets="ResolveReferences"> |
|||
<PropertyGroup> |
|||
<AvaloniaResourcesTemporaryFilePath Condition="'$(AvaloniaResourcesTemporaryFilePath)' == ''">$(IntermediateOutputPath)/Avalonia/resources</AvaloniaResourcesTemporaryFilePath> |
|||
</PropertyGroup> |
|||
<ItemGroup> |
|||
<EmbeddedResource Include="$(AvaloniaResourcesTemporaryFilePath)"> |
|||
<LogicalName>!AvaloniaResources</LogicalName> |
|||
</EmbeddedResource> |
|||
</ItemGroup> |
|||
</Target> |
|||
|
|||
<Target Name="GenerateAvaloniaResources" |
|||
BeforeTargets="CoreCompile;CoreResGen" |
|||
Inputs="@(AvaloniaResource);$(MSBuildAllProjects)" |
|||
Outputs="$(AvaloniaResourcesTemporaryFilePath)" |
|||
DependsOnTargets="$(BuildAvaloniaResourcesDependsOn);AddAvaloniaResources;ResolveReferences"> |
|||
<GenerateAvaloniaResourcesTask |
|||
Condition="'$(_AvaloniaUseExternalMSBuild)' != 'true'" |
|||
Output="$(AvaloniaResourcesTemporaryFilePath)" |
|||
Root="$(MSBuildProjectDirectory)" |
|||
Resources="@(AvaloniaResource)" |
|||
EmbeddedResources="@(EmbeddedResources)"/> |
|||
<Exec |
|||
Condition="'$(_AvaloniaUseExternalMSBuild)' == 'true'" |
|||
Command="dotnet msbuild /nodereuse:false $(MSBuildProjectFile) /t:GenerateAvaloniaResources /p:_AvaloniaForceInternalMSBuild=true /p:Configuration=$(Configuration)"/> |
|||
|
|||
</Target> |
|||
|
|||
<ItemGroup> |
|||
<UpToDateCheckInput Include="@(AvaloniaResource)" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
@ -1,33 +1,42 @@ |
|||
<UserControl xmlns="https://github.com/avaloniaui" |
|||
xmlns:pages="clr-namespace:ControlCatalog.Pages" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
|||
<TabControl Classes="sidebar" Name="Sidebar"> |
|||
<TabControl.PageTransition> |
|||
<CrossFade Duration="0.25"/> |
|||
</TabControl.PageTransition> |
|||
<TabItem Header="AutoCompleteBox"><pages:AutoCompleteBoxPage/></TabItem> |
|||
<TabItem Header="Border"><pages:BorderPage/></TabItem> |
|||
<TabItem Header="Button"><pages:ButtonPage/></TabItem> |
|||
<TabItem Header="ButtonSpinner"><pages:ButtonSpinnerPage/></TabItem> |
|||
<TabItem Header="Calendar"><pages:CalendarPage/></TabItem> |
|||
<TabItem Header="Canvas"><pages:CanvasPage/></TabItem> |
|||
<TabItem Header="Carousel"><pages:CarouselPage/></TabItem> |
|||
<TabItem Header="CheckBox"><pages:CheckBoxPage/></TabItem> |
|||
<TabItem Header="ContextMenu"><pages:ContextMenuPage/></TabItem> |
|||
<TabItem Header="DatePicker"><pages:DatePickerPage/></TabItem> |
|||
<TabItem Header="Drag+Drop"><pages:DragAndDropPage/></TabItem> |
|||
<TabItem Header="DropDown"><pages:DropDownPage/></TabItem> |
|||
<TabItem Header="Expander"><pages:ExpanderPage/></TabItem> |
|||
<TabItem Header="Image"><pages:ImagePage/></TabItem> |
|||
<TabItem Header="LayoutTransformControl"><pages:LayoutTransformControlPage/></TabItem> |
|||
<TabItem Header="ListBox"><pages:ListBoxPage/></TabItem> |
|||
<TabItem Header="Menu"><pages:MenuPage/></TabItem> |
|||
<TabItem Header="NumericUpDown"><pages:NumericUpDownPage/></TabItem> |
|||
<TabItem Header="ProgressBar"><pages:ProgressBarPage/></TabItem> |
|||
<TabItem Header="RadioButton"><pages:RadioButtonPage/></TabItem> |
|||
<TabItem Header="Slider"><pages:SliderPage/></TabItem> |
|||
<TabItem Header="TextBox"><pages:TextBoxPage/></TabItem> |
|||
<TabItem Header="ToolTip"><pages:ToolTipPage/></TabItem> |
|||
<TabItem Header="TreeView"><pages:TreeViewPage/></TabItem> |
|||
</TabControl> |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
x:Class="ControlCatalog.MainView" |
|||
Background="{DynamicResource ThemeBackgroundBrush}" |
|||
Foreground="{DynamicResource ThemeForegroundBrush}" |
|||
FontSize="{DynamicResource FontSizeNormal}"> |
|||
<Grid> |
|||
<DropDown x:Name="Themes" SelectedIndex="0" Width="100" Margin="8" HorizontalAlignment="Right" VerticalAlignment="Bottom"> |
|||
<DropDownItem>Light</DropDownItem> |
|||
<DropDownItem>Dark</DropDownItem> |
|||
</DropDown> |
|||
<TabControl Classes="sidebar" Name="Sidebar"> |
|||
<TabItem Header="AutoCompleteBox"><pages:AutoCompleteBoxPage/></TabItem> |
|||
<TabItem Header="Border"><pages:BorderPage/></TabItem> |
|||
<TabItem Header="Button"><pages:ButtonPage/></TabItem> |
|||
<TabItem Header="ButtonSpinner"><pages:ButtonSpinnerPage/></TabItem> |
|||
<TabItem Header="Calendar"><pages:CalendarPage/></TabItem> |
|||
<TabItem Header="Canvas"><pages:CanvasPage/></TabItem> |
|||
<TabItem Header="Carousel"><pages:CarouselPage/></TabItem> |
|||
<TabItem Header="CheckBox"><pages:CheckBoxPage/></TabItem> |
|||
<TabItem Header="ContextMenu"><pages:ContextMenuPage/></TabItem> |
|||
<TabItem Header="DatePicker"><pages:DatePickerPage/></TabItem> |
|||
<TabItem Header="Drag+Drop"><pages:DragAndDropPage/></TabItem> |
|||
<TabItem Header="DropDown"><pages:DropDownPage/></TabItem> |
|||
<TabItem Header="Expander"><pages:ExpanderPage/></TabItem> |
|||
<TabItem Header="Image"><pages:ImagePage/></TabItem> |
|||
<TabItem Header="LayoutTransformControl"><pages:LayoutTransformControlPage/></TabItem> |
|||
<TabItem Header="ListBox"><pages:ListBoxPage/></TabItem> |
|||
<TabItem Header="Menu"><pages:MenuPage/></TabItem> |
|||
<TabItem Header="NumericUpDown"><pages:NumericUpDownPage/></TabItem> |
|||
<TabItem Header="ProgressBar"><pages:ProgressBarPage/></TabItem> |
|||
<TabItem Header="RadioButton"><pages:RadioButtonPage/></TabItem> |
|||
<TabItem Header="Slider"><pages:SliderPage/></TabItem> |
|||
<TabItem Header="TextBox"><pages:TextBoxPage/></TabItem> |
|||
<TabItem Header="ToolTip"><pages:ToolTipPage/></TabItem> |
|||
<TabItem Header="TreeView"><pages:TreeViewPage/></TabItem> |
|||
<TabItem Header="TabControl"><pages:TabControlPage/></TabItem> |
|||
<TabItem Header="Viewbox"><pages:ViewboxPage/></TabItem> |
|||
</TabControl> |
|||
</Grid> |
|||
</UserControl> |
|||
|
|||
@ -1,6 +1,8 @@ |
|||
<Window xmlns="https://github.com/avaloniaui" MinWidth="500" MinHeight="300" |
|||
Title="Avalonia Control Gallery" |
|||
Icon="resm:ControlCatalog.Assets.test_icon.ico?assembly=ControlCatalog" |
|||
xmlns:local="clr-namespace:ControlCatalog"> |
|||
Icon="/Assets/test_icon.ico" |
|||
xmlns:local="clr-namespace:ControlCatalog" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
x:Class="ControlCatalog.MainWindow"> |
|||
<local:MainView/> |
|||
</Window> |
|||
</Window> |
|||
|
|||
@ -1,12 +1,11 @@ |
|||
<UserControl xmlns="https://github.com/avaloniaui"> |
|||
<UserControl xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
x:Class="ControlCatalog.Pages.DialogsPage"> |
|||
<StackPanel Orientation="Vertical" Spacing="4" Margin="4"> |
|||
<Button Name="OpenFile">Open File</Button> |
|||
<Button Name="SaveFile">Save File</Button> |
|||
<Button Name="SelectFolder">Select Folder</Button> |
|||
<StackPanel Orientation="Horizontal"> |
|||
<CheckBox Name="IsModal" IsChecked="True"/> |
|||
<TextBlock>Modal to window</TextBlock> |
|||
</StackPanel> |
|||
<Button Name="DecoratedWindow">Decorated window</Button> |
|||
<Button Name="Dialog">Dialog</Button> |
|||
</StackPanel> |
|||
</UserControl> |
|||
|
|||
@ -0,0 +1,100 @@ |
|||
<UserControl |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
x:Class="ControlCatalog.Pages.TabControlPage" |
|||
xmlns="https://github.com/avaloniaui"> |
|||
<DockPanel> |
|||
<TextBlock |
|||
DockPanel.Dock="Top" |
|||
Classes="h1" |
|||
Text="TabControl" |
|||
Margin="4"> |
|||
</TextBlock> |
|||
<TextBlock |
|||
DockPanel.Dock="Top" |
|||
Classes="h2" |
|||
Text="A tab control that displays a tab strip along with the content of the selected tab" |
|||
Margin="4"> |
|||
</TextBlock> |
|||
<Grid |
|||
ColumnDefinitions="*,*" |
|||
RowDefinitions="*,100"> |
|||
<DockPanel |
|||
Grid.Column="0" |
|||
Margin="4"> |
|||
<TextBlock |
|||
DockPanel.Dock="Top" |
|||
Classes="h1" |
|||
Text="From Inline TabItems"> |
|||
</TextBlock> |
|||
<TabControl |
|||
Margin="0 16" |
|||
TabStripPlacement="{Binding TabPlacement}"> |
|||
<TabItem Header="Arch"> |
|||
<StackPanel Orientation="Vertical" Spacing="8"> |
|||
<TextBlock>This is the first page in the TabControl.</TextBlock> |
|||
<Image Source="/Assets/delicate-arch-896885_640.jpg" Width="300"/> |
|||
</StackPanel> |
|||
</TabItem> |
|||
<TabItem Header="Leaf"> |
|||
<StackPanel Orientation="Vertical" Spacing="8"> |
|||
<TextBlock>This is the second page in the TabControl.</TextBlock> |
|||
<Image Source="/Assets/maple-leaf-888807_640.jpg" Width="300"/> |
|||
</StackPanel> |
|||
</TabItem> |
|||
<TabItem Header="Disabled" IsEnabled="False"> |
|||
<TextBlock>You should not see this.</TextBlock> |
|||
</TabItem> |
|||
</TabControl> |
|||
</DockPanel> |
|||
<DockPanel |
|||
Grid.Column="1" |
|||
Margin="4"> |
|||
<TextBlock |
|||
DockPanel.Dock="Top" |
|||
Classes="h1" |
|||
Text="From DataTemplate"> |
|||
</TextBlock> |
|||
<TabControl |
|||
Items="{Binding Tabs}" |
|||
Margin="0 16" |
|||
TabStripPlacement="{Binding TabPlacement}"> |
|||
<TabControl.ItemTemplate> |
|||
<DataTemplate> |
|||
<TextBlock |
|||
Text="{Binding Header}"> |
|||
</TextBlock> |
|||
</DataTemplate> |
|||
</TabControl.ItemTemplate> |
|||
<TabControl.ContentTemplate> |
|||
<DataTemplate> |
|||
<StackPanel Orientation="Vertical" Spacing="8"> |
|||
<TextBlock Text="{Binding Text}"/> |
|||
<Image Source="{Binding Image}" Width="300"/> |
|||
</StackPanel> |
|||
</DataTemplate> |
|||
</TabControl.ContentTemplate> |
|||
<TabControl.Styles> |
|||
<Style Selector="TabItem"> |
|||
<Setter Property="IsEnabled" Value="{Binding IsEnabled}"/> |
|||
</Style> |
|||
</TabControl.Styles> |
|||
</TabControl> |
|||
</DockPanel> |
|||
<StackPanel |
|||
Grid.Row="1" |
|||
Grid.ColumnSpan="2" |
|||
Orientation="Horizontal" |
|||
Spacing="8" |
|||
HorizontalAlignment="Center" |
|||
VerticalAlignment="Center"> |
|||
<TextBlock VerticalAlignment="Center">Tab Placement:</TextBlock> |
|||
<DropDown SelectedIndex="{Binding TabPlacement, Mode=TwoWay}"> |
|||
<DropDownItem>Left</DropDownItem> |
|||
<DropDownItem>Bottom</DropDownItem> |
|||
<DropDownItem>Right</DropDownItem> |
|||
<DropDownItem>Top</DropDownItem> |
|||
</DropDown> |
|||
</StackPanel> |
|||
</Grid> |
|||
</DockPanel> |
|||
</UserControl> |
|||
@ -0,0 +1,80 @@ |
|||
using System; |
|||
|
|||
using Avalonia; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Markup.Xaml; |
|||
using Avalonia.Media.Imaging; |
|||
using Avalonia.Platform; |
|||
|
|||
using ReactiveUI; |
|||
|
|||
namespace ControlCatalog.Pages |
|||
{ |
|||
using System.Collections.Generic; |
|||
|
|||
public class TabControlPage : UserControl |
|||
{ |
|||
public TabControlPage() |
|||
{ |
|||
InitializeComponent(); |
|||
|
|||
DataContext = new PageViewModel |
|||
{ |
|||
Tabs = new[] |
|||
{ |
|||
new TabItemViewModel |
|||
{ |
|||
Header = "Arch", |
|||
Text = "This is the first templated tab page.", |
|||
Image = LoadBitmap("avares://ControlCatalog/Assets/delicate-arch-896885_640.jpg"), |
|||
}, |
|||
new TabItemViewModel |
|||
{ |
|||
Header = "Leaf", |
|||
Text = "This is the second templated tab page.", |
|||
Image = LoadBitmap("avares://ControlCatalog/Assets/maple-leaf-888807_640.jpg"), |
|||
}, |
|||
new TabItemViewModel |
|||
{ |
|||
Header = "Disabled", |
|||
Text = "You should not see this.", |
|||
IsEnabled = false, |
|||
}, |
|||
}, |
|||
TabPlacement = Dock.Top, |
|||
}; |
|||
} |
|||
|
|||
private void InitializeComponent() |
|||
{ |
|||
AvaloniaXamlLoader.Load(this); |
|||
} |
|||
|
|||
private IBitmap LoadBitmap(string uri) |
|||
{ |
|||
var assets = AvaloniaLocator.Current.GetService<IAssetLoader>(); |
|||
return new Bitmap(assets.Open(new Uri(uri))); |
|||
} |
|||
|
|||
private class PageViewModel : ReactiveObject |
|||
{ |
|||
private Dock _tabPlacement; |
|||
|
|||
public TabItemViewModel[] Tabs { get; set; } |
|||
|
|||
public Dock TabPlacement |
|||
{ |
|||
get { return _tabPlacement; } |
|||
set { this.RaiseAndSetIfChanged(ref _tabPlacement, value); } |
|||
} |
|||
} |
|||
|
|||
private class TabItemViewModel |
|||
{ |
|||
public string Header { get; set; } |
|||
public string Text { get; set; } |
|||
public IBitmap Image { get; set; } |
|||
public bool IsEnabled { get; set; } = true; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,66 @@ |
|||
<UserControl xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
x:Class="ControlCatalog.Pages.ViewboxPage"> |
|||
<UserControl.Resources> |
|||
<StreamGeometry x:Key="Acorn"> |
|||
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 |
|||
</StreamGeometry> |
|||
</UserControl.Resources> |
|||
|
|||
<Grid RowDefinitions="Auto,*"> |
|||
<StackPanel Orientation="Vertical" Spacing="4"> |
|||
<TextBlock Classes="h1">Viewbox</TextBlock> |
|||
<TextBlock Classes="h2">A control used to scale single child.</TextBlock> |
|||
</StackPanel> |
|||
<Grid ColumnDefinitions="Auto,*,*" |
|||
RowDefinitions="*,*,*,*" |
|||
Grid.Row="1" Margin="48" |
|||
MaxWidth="400"> |
|||
<TextBlock Grid.Row="0" VerticalAlignment="Center">None</TextBlock> |
|||
<TextBlock Grid.Row="1" VerticalAlignment="Center">Fill</TextBlock> |
|||
<TextBlock Grid.Row="2" VerticalAlignment="Center">Uniform</TextBlock> |
|||
<TextBlock Grid.Row="3" VerticalAlignment="Center">UniformToFill</TextBlock> |
|||
|
|||
<Viewbox Grid.Row="0" Grid.Column="1" Stretch="None"> |
|||
<TextBlock>Hello World!</TextBlock> |
|||
</Viewbox> |
|||
<Viewbox Grid.Row="1" Grid.Column="1" Stretch="Fill"> |
|||
<TextBlock>Hello World!</TextBlock> |
|||
</Viewbox> |
|||
<Viewbox Grid.Row="2" Grid.Column="1" Stretch="Uniform"> |
|||
<TextBlock>Hello World!</TextBlock> |
|||
</Viewbox> |
|||
<Viewbox Grid.Row="3" Grid.Column="1" Stretch="UniformToFill"> |
|||
<TextBlock>Hello World!</TextBlock> |
|||
</Viewbox> |
|||
|
|||
<Viewbox Grid.Row="0" Grid.Column="2" Stretch="None"> |
|||
<Path Fill="Blue" Data="{StaticResource Acorn}"/> |
|||
</Viewbox> |
|||
<Viewbox Grid.Row="1" Grid.Column="2" Stretch="Fill"> |
|||
<Path Fill="Blue" Data="{StaticResource Acorn}"/> |
|||
</Viewbox> |
|||
<Viewbox Grid.Row="2" Grid.Column="2" Stretch="Uniform"> |
|||
<Path Fill="Blue" Data="{StaticResource Acorn}"/> |
|||
</Viewbox> |
|||
<Viewbox Grid.Row="3" Grid.Column="2" Stretch="UniformToFill"> |
|||
<Path Fill="Blue" Data="{StaticResource Acorn}"/> |
|||
</Viewbox> |
|||
</Grid> |
|||
</Grid> |
|||
</UserControl> |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -1,52 +1,67 @@ |
|||
<Styles xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > |
|||
<Style Selector="TabControl.sidebar"> |
|||
<Setter Property="Template"> |
|||
<ControlTemplate> |
|||
<DockPanel> |
|||
<ScrollViewer MinWidth="190" Background="{DynamicResource ThemeAccentBrush}" DockPanel.Dock="Left"> |
|||
<TabStrip Name="PART_TabStrip" |
|||
MemberSelector="{x:Static TabControl.HeaderSelector}" |
|||
Items="{TemplateBinding Items}" |
|||
SelectedIndex="{TemplateBinding SelectedIndex, Mode=TwoWay}"> |
|||
<TabStrip.ItemsPanel> |
|||
<ItemsPanelTemplate> |
|||
<StackPanel Orientation="Vertical"/> |
|||
</ItemsPanelTemplate> |
|||
</TabStrip.ItemsPanel> |
|||
</TabStrip> |
|||
</ScrollViewer> |
|||
<Carousel Name="PART_Content" |
|||
Margin="8 0 0 0" |
|||
MemberSelector="{x:Static TabControl.ContentSelector}" |
|||
Items="{TemplateBinding Items}" |
|||
SelectedIndex="{TemplateBinding SelectedIndex}" |
|||
PageTransition="{TemplateBinding PageTransition}" |
|||
Grid.Row="1"/> |
|||
</DockPanel> |
|||
</ControlTemplate> |
|||
</Setter> |
|||
</Style> |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
x:Class="ControlCatalog.SideBar"> |
|||
<Style Selector="TabControl.sidebar"> |
|||
<Setter Property="TabStripPlacement" Value="Left"/> |
|||
<Setter Property="Padding" Value="8 0 0 0"/> |
|||
<Setter Property="Background" Value="{DynamicResource ThemeAccentBrush}"/> |
|||
<Setter Property="Template"> |
|||
<ControlTemplate> |
|||
<Border |
|||
Margin="{TemplateBinding Margin}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}"> |
|||
<DockPanel> |
|||
<ScrollViewer |
|||
Name="PART_ScrollViewer" |
|||
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}" |
|||
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}" |
|||
Background="{TemplateBinding Background}"> |
|||
<ItemsPresenter |
|||
Name="PART_ItemsPresenter" |
|||
Items="{TemplateBinding Items}" |
|||
ItemsPanel="{TemplateBinding ItemsPanel}" |
|||
ItemTemplate="{TemplateBinding ItemTemplate}" |
|||
MemberSelector="{TemplateBinding MemberSelector}"> |
|||
</ItemsPresenter> |
|||
</ScrollViewer> |
|||
<ContentPresenter |
|||
Name="PART_Content" |
|||
Margin="{TemplateBinding Padding}" |
|||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" |
|||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" |
|||
Content="{TemplateBinding SelectedContent}" |
|||
ContentTemplate="{TemplateBinding SelectedContentTemplate}"> |
|||
</ContentPresenter> |
|||
</DockPanel> |
|||
</Border> |
|||
</ControlTemplate> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style Selector="TabControl.sidebar TabStripItem"> |
|||
<Setter Property="Foreground" Value="White"/> |
|||
<Setter Property="FontSize" Value="14"/> |
|||
<Setter Property="Margin" Value="0"/> |
|||
<Setter Property="Padding" Value="16"/> |
|||
<Setter Property="Opacity" Value="0.5"/> |
|||
<Setter Property="Transitions"> |
|||
<Transitions> |
|||
<DoubleTransition Property="Opacity" Duration="0:0:0.2"/> |
|||
</Transitions> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style Selector="TabControl.sidebar TabStripItem:pointerover"> |
|||
<Setter Property="Opacity" Value="1"/> |
|||
</Style> |
|||
|
|||
<Style Selector="TabControl.sidebar TabStripItem:selected"> |
|||
<Setter Property="Background" Value="{DynamicResource ThemeAccentBrush2}"/> |
|||
<Setter Property="Opacity" Value="1"/> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem"> |
|||
<Setter Property="BorderThickness" Value="0"/> |
|||
<Setter Property="Foreground" Value="White"/> |
|||
<Setter Property="FontSize" Value="14"/> |
|||
<Setter Property="Margin" Value="0"/> |
|||
<Setter Property="Padding" Value="16"/> |
|||
<Setter Property="Opacity" Value="0.5"/> |
|||
<Setter Property="Transitions"> |
|||
<Transitions> |
|||
<DoubleTransition Property="Opacity" Duration="0:0:0.5"/> |
|||
</Transitions> |
|||
</Setter> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:pointerover"> |
|||
<Setter Property="Opacity" Value="1"/> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:pointerover /template/ ContentPresenter#PART_ContentPresenter"> |
|||
<Setter Property="Background" Value="Transparent"/> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:selected"> |
|||
<Setter Property="Opacity" Value="1"/> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:selected /template/ ContentPresenter#PART_ContentPresenter"> |
|||
<Setter Property="Background" Value="{DynamicResource ThemeAccentBrush2}"/> |
|||
</Style> |
|||
</Styles> |
|||
|
|||
@ -1,53 +1,66 @@ |
|||
<Styles xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:a="clr-namespace:Avalonia.Media.Animations;assembly=Avalonia.Media.Animations"> |
|||
<Style Selector="TabControl.sidebar"> |
|||
<Setter Property="Template"> |
|||
<ControlTemplate> |
|||
<DockPanel> |
|||
<ScrollViewer MinWidth="190" Background="{DynamicResource ThemeAccentBrush}" DockPanel.Dock="Left"> |
|||
<TabStrip Name="PART_TabStrip" |
|||
MemberSelector="{x:Static TabControl.HeaderSelector}" |
|||
Items="{TemplateBinding Items}" |
|||
SelectedIndex="{TemplateBinding SelectedIndex, Mode=TwoWay}"> |
|||
<TabStrip.ItemsPanel> |
|||
<ItemsPanelTemplate> |
|||
<StackPanel Orientation="Vertical"/> |
|||
</ItemsPanelTemplate> |
|||
</TabStrip.ItemsPanel> |
|||
</TabStrip> |
|||
</ScrollViewer> |
|||
<Carousel Name="PART_Content" |
|||
Margin="8 0 0 0" |
|||
MemberSelector="{x:Static TabControl.ContentSelector}" |
|||
Items="{TemplateBinding Items}" |
|||
SelectedIndex="{TemplateBinding SelectedIndex}" |
|||
PageTransition="{TemplateBinding PageTransition}" |
|||
Grid.Row="1"/> |
|||
</DockPanel> |
|||
</ControlTemplate> |
|||
</Setter> |
|||
</Style> |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > |
|||
<Style Selector="TabControl.sidebar"> |
|||
<Setter Property="TabStripPlacement" Value="Left"/> |
|||
<Setter Property="Padding" Value="8 0 0 0"/> |
|||
<Setter Property="Background" Value="{DynamicResource ThemeAccentBrush}"/> |
|||
<Setter Property="Template"> |
|||
<ControlTemplate> |
|||
<Border |
|||
Margin="{TemplateBinding Margin}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}"> |
|||
<DockPanel> |
|||
<ScrollViewer |
|||
Name="PART_ScrollViewer" |
|||
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}" |
|||
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}" |
|||
Background="{TemplateBinding Background}"> |
|||
<ItemsPresenter |
|||
Name="PART_ItemsPresenter" |
|||
Items="{TemplateBinding Items}" |
|||
ItemsPanel="{TemplateBinding ItemsPanel}" |
|||
ItemTemplate="{TemplateBinding ItemTemplate}" |
|||
MemberSelector="{TemplateBinding MemberSelector}"> |
|||
</ItemsPresenter> |
|||
</ScrollViewer> |
|||
<ContentPresenter |
|||
Name="PART_Content" |
|||
Margin="{TemplateBinding Padding}" |
|||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" |
|||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" |
|||
Content="{TemplateBinding SelectedContent}" |
|||
ContentTemplate="{TemplateBinding SelectedContentTemplate}"> |
|||
</ContentPresenter> |
|||
</DockPanel> |
|||
</Border> |
|||
</ControlTemplate> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style Selector="TabControl.sidebar TabStripItem"> |
|||
<Setter Property="Foreground" Value="White"/> |
|||
<Setter Property="FontSize" Value="14"/> |
|||
<Setter Property="Margin" Value="0"/> |
|||
<Setter Property="Padding" Value="16"/> |
|||
<Setter Property="Opacity" Value="0.5"/> |
|||
<Setter Property="Transitions"> |
|||
<Transitions> |
|||
<DoubleTransition Property="Opacity" Duration="0:0:0.2"/> |
|||
</Transitions> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style Selector="TabControl.sidebar TabStripItem:pointerover"> |
|||
<Setter Property="Opacity" Value="1"/> |
|||
</Style> |
|||
|
|||
<Style Selector="TabControl.sidebar TabStripItem:selected"> |
|||
<Setter Property="Background" Value="{DynamicResource ThemeAccentBrush2}"/> |
|||
<Setter Property="Opacity" Value="1"/> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem"> |
|||
<Setter Property="BorderThickness" Value="0"/> |
|||
<Setter Property="Foreground" Value="White"/> |
|||
<Setter Property="FontSize" Value="14"/> |
|||
<Setter Property="Margin" Value="0"/> |
|||
<Setter Property="Padding" Value="16"/> |
|||
<Setter Property="Opacity" Value="0.5"/> |
|||
<Setter Property="Transitions"> |
|||
<Transitions> |
|||
<DoubleTransition Property="Opacity" Duration="0:0:0.5"/> |
|||
</Transitions> |
|||
</Setter> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:pointerover"> |
|||
<Setter Property="Opacity" Value="1"/> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:pointerover /template/ ContentPresenter#PART_ContentPresenter"> |
|||
<Setter Property="Background" Value="Transparent"/> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:selected"> |
|||
<Setter Property="Opacity" Value="1"/> |
|||
</Style> |
|||
<Style Selector="TabControl.sidebar > TabItem:selected /template/ ContentPresenter#PART_ContentPresenter"> |
|||
<Setter Property="Background" Value="{DynamicResource ThemeAccentBrush2}"/> |
|||
</Style> |
|||
</Styles> |
|||
|
|||
@ -0,0 +1,64 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Runtime.CompilerServices; |
|||
using System.Runtime.Serialization; |
|||
using System.Runtime.Serialization.Json; |
|||
|
|||
// ReSharper disable AssignNullToNotNullAttribute
|
|||
|
|||
namespace Avalonia.Utilities |
|||
{ |
|||
#if !BUILDTASK
|
|||
public |
|||
#endif
|
|||
static class AvaloniaResourcesIndexReaderWriter |
|||
{ |
|||
private const int LastKnownVersion = 1; |
|||
public static List<AvaloniaResourcesIndexEntry> Read(Stream stream) |
|||
{ |
|||
var ver = new BinaryReader(stream).ReadInt32(); |
|||
if (ver > LastKnownVersion) |
|||
throw new Exception("Resources index format version is not known"); |
|||
var index = (AvaloniaResourcesIndex) |
|||
new DataContractSerializer(typeof(AvaloniaResourcesIndex)).ReadObject(stream); |
|||
return index.Entries; |
|||
} |
|||
|
|||
public static void Write(Stream stream, List<AvaloniaResourcesIndexEntry> entries) |
|||
{ |
|||
new BinaryWriter(stream).Write(LastKnownVersion); |
|||
new DataContractSerializer(typeof(AvaloniaResourcesIndex)).WriteObject(stream, |
|||
new AvaloniaResourcesIndex() |
|||
{ |
|||
Entries = entries |
|||
}); |
|||
} |
|||
} |
|||
|
|||
[DataContract] |
|||
#if !BUILDTASK
|
|||
public |
|||
#endif
|
|||
class AvaloniaResourcesIndex |
|||
{ |
|||
[DataMember] |
|||
public List<AvaloniaResourcesIndexEntry> Entries { get; set; } = new List<AvaloniaResourcesIndexEntry>(); |
|||
} |
|||
|
|||
[DataContract] |
|||
#if !BUILDTASK
|
|||
public |
|||
#endif
|
|||
class AvaloniaResourcesIndexEntry |
|||
{ |
|||
[DataMember] |
|||
public string Path { get; set; } |
|||
|
|||
[DataMember] |
|||
public int Offset { get; set; } |
|||
|
|||
[DataMember] |
|||
public int Size { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<BuildOutputTargetFolder>tools</BuildOutputTargetFolder> |
|||
<DefineConstants>$(DefineConstants);BUILDTASK</DefineConstants> |
|||
<Packable>false</Packable> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<Compile Include="../Avalonia.Base/Utilities/AvaloniaResourcesIndex.cs"> |
|||
<Link>Shared/AvaloniaResourcesIndex.cs</Link> |
|||
</Compile> |
|||
<Compile Include="../Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaResourceXamlInfo.cs"> |
|||
<Link>Shared/AvaloniaResourceXamlInfo.cs</Link> |
|||
</Compile> |
|||
<PackageReference Include="Microsoft.Build.Framework" Version="15.1.548" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
@ -0,0 +1,9 @@ |
|||
namespace Avalonia.Build.Tasks |
|||
{ |
|||
public enum BuildEngineErrorCode |
|||
{ |
|||
InvalidXAML = 1, |
|||
DuplicateXClass = 2, |
|||
LegacyResmScheme = 3, |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
using Microsoft.Build.Framework; |
|||
|
|||
namespace Avalonia.Build.Tasks |
|||
{ |
|||
public static class Extensions |
|||
{ |
|||
static string FormatErrorCode(BuildEngineErrorCode code) => $"AVLN:{(int)code:0000}"; |
|||
|
|||
public static void LogError(this IBuildEngine engine, BuildEngineErrorCode code, string file, string message) |
|||
{ |
|||
engine.LogErrorEvent(new BuildErrorEventArgs("Avalonia", FormatErrorCode(code), file ?? "", 0, 0, 0, 0, message, |
|||
"", "Avalonia")); |
|||
} |
|||
|
|||
public static void LogWarning(this IBuildEngine engine, BuildEngineErrorCode code, string file, string message) |
|||
{ |
|||
engine.LogWarningEvent(new BuildWarningEventArgs("Avalonia", FormatErrorCode(code), file ?? "", 0, 0, 0, 0, message, |
|||
"", "Avalonia")); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,159 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Runtime.Serialization; |
|||
using System.Runtime.Serialization.Json; |
|||
using System.Text; |
|||
using Avalonia.Markup.Xaml.PortableXaml; |
|||
using Avalonia.Utilities; |
|||
using Microsoft.Build.Framework; |
|||
using SPath=System.IO.Path; |
|||
namespace Avalonia.Build.Tasks |
|||
{ |
|||
public class GenerateAvaloniaResourcesTask : ITask |
|||
{ |
|||
[Required] |
|||
public ITaskItem[] Resources { get; set; } |
|||
[Required] |
|||
public string Root { get; set; } |
|||
[Required] |
|||
public string Output { get; set; } |
|||
[Required] |
|||
public ITaskItem[] EmbeddedResources { get; set; } |
|||
|
|||
class Source |
|||
{ |
|||
public string Path { get; set; } |
|||
public int Size { get; set; } |
|||
private byte[] _data; |
|||
private string _sourcePath; |
|||
|
|||
public Source(string file, string root) |
|||
{ |
|||
file = SPath.GetFullPath(file); |
|||
root = SPath.GetFullPath(root); |
|||
var fileUri = new Uri(file, UriKind.Absolute); |
|||
var rootUri = new Uri(root, UriKind.Absolute); |
|||
rootUri = new Uri(rootUri.ToString().TrimEnd('/') + '/'); |
|||
Path = '/' + rootUri.MakeRelativeUri(fileUri).ToString().TrimStart('/'); |
|||
_sourcePath = file; |
|||
Size = (int)new FileInfo(_sourcePath).Length; |
|||
} |
|||
|
|||
public string SystemPath => _sourcePath ?? Path; |
|||
|
|||
public Source(string path, byte[] data) |
|||
{ |
|||
Path = path; |
|||
_data = data; |
|||
Size = data.Length; |
|||
} |
|||
|
|||
public Stream Open() |
|||
{ |
|||
if (_data != null) |
|||
return new MemoryStream(_data, false); |
|||
return File.OpenRead(_sourcePath); |
|||
} |
|||
|
|||
public string ReadAsString() |
|||
{ |
|||
if (_data != null) |
|||
return Encoding.UTF8.GetString(_data); |
|||
return File.ReadAllText(_sourcePath); |
|||
} |
|||
} |
|||
|
|||
List<Source> BuildResourceSources() => Resources.Select(r => new Source(r.ItemSpec, Root)).ToList(); |
|||
|
|||
private void Pack(Stream output, List<Source> sources) |
|||
{ |
|||
var offsets = new Dictionary<Source, int>(); |
|||
var coffset = 0; |
|||
foreach (var s in sources) |
|||
{ |
|||
offsets[s] = coffset; |
|||
coffset += s.Size; |
|||
} |
|||
var index = sources.Select(s => new AvaloniaResourcesIndexEntry |
|||
{ |
|||
Path = s.Path, |
|||
Size = s.Size, |
|||
Offset = offsets[s] |
|||
}).ToList(); |
|||
var ms = new MemoryStream(); |
|||
AvaloniaResourcesIndexReaderWriter.Write(ms, index); |
|||
new BinaryWriter(output).Write((int)ms.Length); |
|||
ms.Position = 0; |
|||
ms.CopyTo(output); |
|||
foreach (var s in sources) |
|||
{ |
|||
using(var input = s.Open()) |
|||
input.CopyTo(output); |
|||
} |
|||
} |
|||
|
|||
private bool PreProcessXamlFiles(List<Source> sources) |
|||
{ |
|||
var typeToXamlIndex = new Dictionary<string, string>(); |
|||
|
|||
foreach (var s in sources.ToList()) |
|||
{ |
|||
if (s.Path.ToLowerInvariant().EndsWith(".xaml") || s.Path.ToLowerInvariant().EndsWith(".paml")) |
|||
{ |
|||
XamlFileInfo info; |
|||
try |
|||
{ |
|||
info = XamlFileInfo.Parse(s.ReadAsString()); |
|||
} |
|||
catch(Exception e) |
|||
{ |
|||
BuildEngine.LogError(BuildEngineErrorCode.InvalidXAML, s.SystemPath, "File doesn't contain valid XAML: " + e); |
|||
return false; |
|||
} |
|||
|
|||
if (info.XClass != null) |
|||
{ |
|||
if (typeToXamlIndex.ContainsKey(info.XClass)) |
|||
{ |
|||
|
|||
BuildEngine.LogError(BuildEngineErrorCode.DuplicateXClass, s.SystemPath, |
|||
$"Duplicate x:Class directive, {info.XClass} is already used in {typeToXamlIndex[info.XClass]}"); |
|||
return false; |
|||
} |
|||
typeToXamlIndex[info.XClass] = s.Path; |
|||
} |
|||
} |
|||
} |
|||
|
|||
var xamlInfo = new AvaloniaResourceXamlInfo |
|||
{ |
|||
ClassToResourcePathIndex = typeToXamlIndex |
|||
}; |
|||
var ms = new MemoryStream(); |
|||
new DataContractSerializer(typeof(AvaloniaResourceXamlInfo)).WriteObject(ms, xamlInfo); |
|||
sources.Add(new Source("/!AvaloniaResourceXamlInfo", ms.ToArray())); |
|||
return true; |
|||
} |
|||
|
|||
public bool Execute() |
|||
{ |
|||
foreach(var r in EmbeddedResources.Where(r=>r.ItemSpec.EndsWith(".xaml")||r.ItemSpec.EndsWith(".paml"))) |
|||
BuildEngine.LogWarning(BuildEngineErrorCode.LegacyResmScheme, r.ItemSpec, |
|||
"XAML file is packed using legacy EmbeddedResource/resm scheme, relative URIs won't work"); |
|||
var resources = BuildResourceSources(); |
|||
|
|||
if (!PreProcessXamlFiles(resources)) |
|||
return false; |
|||
var dir = Path.GetDirectoryName(Output); |
|||
Directory.CreateDirectory(dir); |
|||
using (var file = File.Create(Output)) |
|||
Pack(file, resources); |
|||
return true; |
|||
} |
|||
|
|||
public IBuildEngine BuildEngine { get; set; } |
|||
public ITaskHost HostObject { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System.Xml.Linq; |
|||
|
|||
namespace Avalonia.Build.Tasks |
|||
{ |
|||
public class XamlFileInfo |
|||
{ |
|||
public string XClass { get; set; } |
|||
|
|||
public static XamlFileInfo Parse(string data) |
|||
{ |
|||
var xdoc = XDocument.Parse(data); |
|||
var xclass = xdoc.Root.Attribute(XName.Get("Class", "http://schemas.microsoft.com/winfx/2006/xaml")); |
|||
return new XamlFileInfo |
|||
{ |
|||
XClass = xclass?.Value |
|||
}; |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,59 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using Avalonia.Controls.Primitives; |
|||
|
|||
namespace Avalonia.Controls.Generators |
|||
{ |
|||
public class TabItemContainerGenerator : ItemContainerGenerator<TabItem> |
|||
{ |
|||
public TabItemContainerGenerator(TabControl owner) |
|||
: base(owner, ContentControl.ContentProperty, ContentControl.ContentTemplateProperty) |
|||
{ |
|||
Owner = owner; |
|||
} |
|||
|
|||
public new TabControl Owner { get; } |
|||
|
|||
protected override IControl CreateContainer(object item) |
|||
{ |
|||
var tabItem = (TabItem)base.CreateContainer(item); |
|||
|
|||
tabItem.ParentTabControl = Owner; |
|||
|
|||
tabItem[~TabControl.TabStripPlacementProperty] = Owner[~TabControl.TabStripPlacementProperty]; |
|||
|
|||
if (tabItem.HeaderTemplate == null) |
|||
{ |
|||
tabItem[~HeaderedContentControl.HeaderTemplateProperty] = Owner[~ItemsControl.ItemTemplateProperty]; |
|||
} |
|||
|
|||
if (tabItem.Header == null) |
|||
{ |
|||
if (item is IHeadered headered) |
|||
{ |
|||
tabItem.Header = headered.Header; |
|||
} |
|||
else |
|||
{ |
|||
if (!(tabItem.DataContext is IControl)) |
|||
{ |
|||
tabItem.Header = tabItem.DataContext; |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (!(tabItem.Content is IControl)) |
|||
{ |
|||
tabItem[~ContentControl.ContentTemplateProperty] = Owner[~TabControl.ContentTemplateProperty]; |
|||
} |
|||
|
|||
if (tabItem.Content == null) |
|||
{ |
|||
tabItem[~ContentControl.ContentProperty] = tabItem[~StyledElement.DataContextProperty]; |
|||
} |
|||
|
|||
return tabItem; |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue