Browse Source

Merge branch 'master' into fix-pointerleave-not-always-set

pull/2067/head
ahopper 8 years ago
committed by GitHub
parent
commit
b91e431891
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .gitignore
  2. 3
      .gitmodules
  3. 0
      .nuke
  4. 24
      .travis.yml
  5. 33
      Avalonia.sln
  6. 3
      Avalonia.sln.DotSettings
  7. 2
      Directory.Build.props
  8. 23
      appveyor.yml
  9. 25
      azure-pipelines.yml
  10. 312
      build.cake
  11. 226
      build.ps1
  12. 139
      build.sh
  13. 8
      build/BuildTargets.targets
  14. 1
      build/ReferenceCoreLibraries.props
  15. 15
      cake.config
  16. 6
      native/Avalonia.Native/src/OSX/gl.mm
  17. 243
      nukebuild/Build.cs
  18. 142
      nukebuild/BuildParameters.cs
  19. 1
      nukebuild/Numerge
  20. 93
      nukebuild/Shims.cs
  21. 37
      nukebuild/_build.csproj
  22. 24
      nukebuild/_build.csproj.DotSettings
  23. 23
      nukebuild/numerge.config
  24. 22
      packages/Avalonia/Avalonia.csproj
  25. 3
      packages/Avalonia/Avalonia.props
  26. 3
      packages/Avalonia/Avalonia.targets
  27. 3
      packages/Avalonia/AvaloniaBuildTasks.props
  28. 43
      packages/Avalonia/AvaloniaBuildTasks.targets
  29. 6
      readme.md
  30. 10
      samples/ControlCatalog.NetCore/Program.cs
  31. 10
      samples/ControlCatalog/App.xaml
  32. 8
      samples/ControlCatalog/ControlCatalog.csproj
  33. 17
      samples/ControlCatalog/DecoratedWindow.xaml
  34. 1
      samples/ControlCatalog/MainView.xaml
  35. 8
      samples/ControlCatalog/MainWindow.xaml
  36. 4
      samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml
  37. 4
      samples/ControlCatalog/Pages/BorderPage.xaml
  38. 3
      samples/ControlCatalog/Pages/ButtonPage.xaml
  39. 3
      samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml
  40. 3
      samples/ControlCatalog/Pages/CalendarPage.xaml
  41. 4
      samples/ControlCatalog/Pages/CanvasPage.xaml
  42. 10
      samples/ControlCatalog/Pages/CarouselPage.xaml
  43. 3
      samples/ControlCatalog/Pages/CheckBoxPage.xaml
  44. 6
      samples/ControlCatalog/Pages/ContextMenuPage.xaml
  45. 3
      samples/ControlCatalog/Pages/DatePickerPage.xaml
  46. 4
      samples/ControlCatalog/Pages/DialogsPage.xaml
  47. 4
      samples/ControlCatalog/Pages/DragAndDropPage.xaml
  48. 4
      samples/ControlCatalog/Pages/DropDownPage.xaml
  49. 4
      samples/ControlCatalog/Pages/ExpanderPage.xaml
  50. 14
      samples/ControlCatalog/Pages/ImagePage.xaml
  51. 5
      samples/ControlCatalog/Pages/LayoutTransformControlPage.xaml
  52. 4
      samples/ControlCatalog/Pages/ListBoxPage.xaml
  53. 6
      samples/ControlCatalog/Pages/MenuPage.xaml
  54. 3
      samples/ControlCatalog/Pages/NumericUpDownPage.xaml
  55. 6
      samples/ControlCatalog/Pages/ProgressBarPage.xaml
  56. 5
      samples/ControlCatalog/Pages/RadioButtonPage.xaml
  57. 6
      samples/ControlCatalog/Pages/SliderPage.xaml
  58. 44
      samples/ControlCatalog/Pages/TabControlPage.xaml
  59. 4
      samples/ControlCatalog/Pages/TabControlPage.xaml.cs
  60. 15
      samples/ControlCatalog/Pages/TextBoxPage.xaml
  61. 6
      samples/ControlCatalog/Pages/ToolTipPage.xaml
  62. 6
      samples/ControlCatalog/Pages/TreeViewPage.xaml
  63. 3
      samples/ControlCatalog/Pages/ViewboxPage.xaml
  64. 6
      samples/ControlCatalog/SideBar.xaml
  65. 5
      samples/RenderDemo/MainWindow.xaml
  66. 113
      samples/RenderDemo/SideBar.xaml
  67. 1
      src/Avalonia.Animation/Avalonia.Animation.csproj
  68. 4
      src/Avalonia.Base/Avalonia.Base.csproj
  69. 2
      src/Avalonia.Base/Platform/IAssetLoader.cs
  70. 64
      src/Avalonia.Base/Utilities/AvaloniaResourcesIndex.cs
  71. 18
      src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj
  72. 9
      src/Avalonia.Build.Tasks/BuildEngineErrorCode.cs
  73. 21
      src/Avalonia.Build.Tasks/Extensions.cs
  74. 159
      src/Avalonia.Build.Tasks/GenerateAvaloniaResourcesTask.cs
  75. 20
      src/Avalonia.Build.Tasks/XamlFileInfo.cs
  76. 9
      src/Avalonia.Controls/AppBuilderBase.cs
  77. 1
      src/Avalonia.Controls/Avalonia.Controls.csproj
  78. 4
      src/Avalonia.Controls/Button.cs
  79. 87
      src/Avalonia.Controls/DropDown.cs
  80. 32
      src/Avalonia.Controls/DropDownItem.cs
  81. 2
      src/Avalonia.Controls/Generators/TabItemContainerGenerator.cs
  82. 9
      src/Avalonia.Controls/Primitives/SelectingItemsControl.cs
  83. 8
      src/Avalonia.Controls/TabItem.cs
  84. 1
      src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj
  85. 6
      src/Avalonia.DesignerSupport/DesignWindowLoader.cs
  86. 2
      src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs
  87. 1
      src/Avalonia.DesktopRuntime/Avalonia.DesktopRuntime.csproj
  88. 1
      src/Avalonia.Diagnostics/Avalonia.Diagnostics.csproj
  89. 1
      src/Avalonia.Input/Avalonia.Input.csproj
  90. 1
      src/Avalonia.Interactivity/Avalonia.Interactivity.csproj
  91. 1
      src/Avalonia.Layout/Avalonia.Layout.csproj
  92. 1
      src/Avalonia.Logging.Serilog/Avalonia.Logging.Serilog.csproj
  93. 3
      src/Avalonia.Remote.Protocol/DesignMessages.cs
  94. 1
      src/Avalonia.Styling/Avalonia.Styling.csproj
  95. 4
      src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj
  96. 20
      src/Avalonia.Themes.Default/DropDown.xaml
  97. 2
      src/Avalonia.Themes.Default/DropDownItem.xaml
  98. 5
      src/Avalonia.Themes.Default/FocusAdorner.xaml
  99. 4
      src/Avalonia.Themes.Default/MenuItem.xaml
  100. 19
      src/Avalonia.Themes.Default/TabControl.xaml

1
.gitignore

@ -195,3 +195,4 @@ Logs/
ModuleCache.noindex/
Build/Intermediates.noindex/
info.plist
build-intermediate

3
.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

0
.nuke

24
.travis.yml

@ -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

33
Avalonia.sln

@ -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,10 @@ 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
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Shared\RenderHelpers\RenderHelpers.projitems*{3c4c0cb4-0c0f-4450-a37b-148c84ff905f}*SharedItemsImports = 13
@ -213,6 +218,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 +1696,30 @@ 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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

3
Avalonia.sln.DotSettings

@ -35,4 +35,5 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="s_" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypeParameters/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="T" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Avalonia/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

2
Directory.Build.props

@ -1,5 +1,5 @@
<Project>
<PropertyGroup>
<PackageOutputPath Condition="'$(PackageOutputPath)' == ''">$(MSBuildThisFileDirectory)artifacts/nuget</PackageOutputPath>
<PackageOutputPath Condition="'$(PackageOutputPath)' == ''">$(MSBuildThisFileDirectory)build-intermediate/nuget</PackageOutputPath>
</PropertyGroup>
</Project>

23
appveyor.yml

@ -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

25
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:

312
build.cake

@ -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);

226
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
ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile -- $BuildArguments }

139
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[@]}

8
build/BuildTargets.targets

@ -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
build/ReferenceCoreLibraries.props

@ -1,5 +1,4 @@
<Project>
<Import Condition="'$(TargetFramework)' == 'netcoreapp2.0'" Project="CoreLibraries.props" />
<ItemGroup>
<ProjectReference Include="$(MSBuildThisFileDirectory)../packages/Avalonia/Avalonia.csproj" />
</ItemGroup>

15
cake.config

@ -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

6
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;
}

243
nukebuild/Build.cs

@ -0,0 +1,243 @@
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<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 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<Build>(x => x.Package)
: Execute<Build>(x => x.RunTests);
}

142
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<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";
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;
}
}
}

1
nukebuild/Numerge

@ -0,0 +1 @@
Subproject commit 4464343aef5c8ab7a42fcb20a483a6058199f8b8

93
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<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
}
}
}
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);
}
}
}

37
nukebuild/_build.csproj

@ -0,0 +1,37 @@
<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')" />
<Compile Remove="Numerge/**/*.*" />
<Compile Include="Numerge/Numerge/**/*.cs" />
</ItemGroup>
</Project>

24
nukebuild/_build.csproj.DotSettings

@ -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">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</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>

23
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
}
]
}
]
}

22
packages/Avalonia/Avalonia.csproj

@ -1,10 +1,12 @@
<Project Sdk="AggregatePackage.NuGet.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net461;netcoreapp2.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../../src/Avalonia.Remote.Protocol/Avalonia.Remote.Protocol.csproj" EmbedReference="false" />
<ProjectReference Include="../../src/Avalonia.Remote.Protocol/Avalonia.Remote.Protocol.csproj"/>
<ProjectReference Include="../../src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj" />
</ItemGroup>
<PropertyGroup>
@ -27,14 +29,18 @@
<Visible>false</Visible>
<BuildAction>None</BuildAction>
</_PackageFiles>
<_PackageFiles Include="Avalonia.props">
<PackagePath>build/Avalonia.props</PackagePath>
<Visible>false</Visible>
<BuildAction>None</BuildAction>
</_PackageFiles>
</ItemGroup>
</Target>
<ItemGroup>
<Content Include="*.props">
<Pack>true</Pack>
<PackagePath>build\</PackagePath>
</Content>
<Content Include="*.targets">
<Pack>true</Pack>
<PackagePath>build\</PackagePath>
</Content>
</ItemGroup>
<Import Project="..\..\build\SharedVersion.props" />
<Import Project="..\..\build\NetFX.props" />
<Import Project="..\..\build\CoreLibraries.props" />

3
packages/Avalonia/Avalonia.props

@ -2,5 +2,8 @@
<PropertyGroup>
<AvaloniaPreviewerNetCoreToolPath>$(MSBuildThisFileDirectory)\..\tools\netcoreapp2.0\designer\Avalonia.Designer.HostApp.dll</AvaloniaPreviewerNetCoreToolPath>
<AvaloniaPreviewerNetFullToolPath>$(MSBuildThisFileDirectory)\..\tools\net461\designer\Avalonia.Designer.HostApp.exe</AvaloniaPreviewerNetFullToolPath>
<AvaloniaBuildTasksLocation>$(MSBuildThisFileDirectory)\..\tools\netstandard2.0\Avalonia.Build.Tasks.dll</AvaloniaBuildTasksLocation>
<AvaloniaUseExternalMSBuild>false</AvaloniaUseExternalMSBuild>
</PropertyGroup>
<Import Project="$(MSBuildThisFileDirectory)\AvaloniaBuildTasks.props"/>
</Project>

3
packages/Avalonia/Avalonia.targets

@ -0,0 +1,3 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildThisFileDirectory)\AvaloniaBuildTasks.targets"/>
</Project>

3
packages/Avalonia/AvaloniaBuildTasks.props

@ -0,0 +1,3 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>

43
packages/Avalonia/AvaloniaBuildTasks.targets

@ -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>

6
readme.md

@ -2,9 +2,9 @@
# Avalonia
| Gitter Chat | Build Status (Win, Linux, OSX) | Appveyor Build Status | Open Collective |
|---|---|---|---|
| [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/AvaloniaUI/Avalonia?utm_campaign=pr-badge&utm_content=badge&utm_medium=badge&utm_source=badge) | [![Build Status](https://dev.azure.com/AvaloniaUI/AvaloniaUI/_apis/build/status/AvaloniaUI.Avalonia)](https://dev.azure.com/AvaloniaUI/AvaloniaUI/_build/latest?definitionId=4) | [![Build status](https://ci.appveyor.com/api/projects/status/hubk3k0w9idyibfg/branch/master?svg=true)](https://ci.appveyor.com/project/AvaloniaUI/Avalonia/branch/master) | [![Backers on Open Collective](https://opencollective.com/Avalonia/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/Avalonia/sponsors/badge.svg)](#sponsors) |
| Gitter Chat | Build Status (Win, Linux, OSX) | Open Collective |
|---|---|---|
| [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/AvaloniaUI/Avalonia?utm_campaign=pr-badge&utm_content=badge&utm_medium=badge&utm_source=badge) | [![Build Status](https://dev.azure.com/AvaloniaUI/AvaloniaUI/_apis/build/status/AvaloniaUI.Avalonia)](https://dev.azure.com/AvaloniaUI/AvaloniaUI/_build/latest?definitionId=4) | [![Backers on Open Collective](https://opencollective.com/Avalonia/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/Avalonia/sponsors/badge.svg)](#sponsors) |
## About

10
samples/ControlCatalog.NetCore/Program.cs

@ -23,6 +23,7 @@ namespace ControlCatalog.NetCore
break;
}
}
if (args.Contains("--fbdev"))
AppBuilder.Configure<App>().InitializeWithLinuxFramebuffer(tl =>
{
@ -30,7 +31,12 @@ namespace ControlCatalog.NetCore
System.Threading.ThreadPool.QueueUserWorkItem(_ => ConsoleSilencer());
});
else
BuildAvaloniaApp().Start<MainWindow>();
BuildAvaloniaApp().Start(AppMain, args);
}
static void AppMain(Application app, string[] args)
{
app.Run(new MainWindow());
}
/// <summary>
@ -46,4 +52,4 @@ namespace ControlCatalog.NetCore
Console.ReadKey(true);
}
}
}
}

10
samples/ControlCatalog/App.xaml

@ -1,7 +1,9 @@
<Application xmlns="https://github.com/avaloniaui">
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.App">
<Application.Styles>
<StyleInclude Source="resm:Avalonia.Themes.Default.DefaultTheme.xaml?assembly=Avalonia.Themes.Default"/>
<StyleInclude Source="resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default"/>
<StyleInclude Source="avares://Avalonia.Themes.Default/DefaultTheme.xaml"/>
<StyleInclude Source="avares://Avalonia.Themes.Default/Accents/BaseLight.xaml"/>
<Style Selector="TextBlock.h1">
<Setter Property="FontSize" Value="{DynamicResource FontSizeLarge}"/>
<Setter Property="FontWeight" Value="Medium"/>
@ -12,6 +14,6 @@
<Style Selector="TextBlock.h3">
<Setter Property="FontSize" Value="{DynamicResource FontSizeSmall}"/>
</Style>
<StyleInclude Source="resm:ControlCatalog.SideBar.xaml"/>
<StyleInclude Source="/SideBar.xaml"/>
</Application.Styles>
</Application>

8
samples/ControlCatalog/ControlCatalog.csproj

@ -6,10 +6,11 @@
<Compile Update="**\*.xaml.cs">
<DependentUpon>%(Filename)</DependentUpon>
</Compile>
<EmbeddedResource Include="**\*.xaml">
<AvaloniaResource Include="**\*.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Assets\*" />
</AvaloniaResource>
<AvaloniaResource Include="Assets\*" />
<AvaloniaResource Include="Assets\Fonts\*" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Assets\Fonts\SourceSansPro-Bold.ttf" />
@ -24,4 +25,5 @@
</ItemGroup>
<Import Project="..\..\build\Serilog.props" />
<Import Project="..\..\build\BuildTargets.targets" />
</Project>

17
samples/ControlCatalog/DecoratedWindow.xaml

@ -1,7 +1,8 @@
<Window xmlns="https://github.com/avaloniaui" MinWidth="500" MinHeight="300"
<Window xmlns="https://github.com/avaloniaui" MinWidth="500" MinHeight="300"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.DecoratedWindow"
Title="Avalonia Control Gallery"
Icon="resm:ControlCatalog.Assets.test_icon.ico"
xmlns:local="clr-namespace:ControlCatalog" HasSystemDecorations="False">
xmlns:local="clr-namespace:ControlCatalog" HasSystemDecorations="False" Name="Window">
<Grid RowDefinitions="5,*,5" ColumnDefinitions="5,*,5">
<DockPanel Grid.Column="1" Grid.Row="1" >
<Grid Name="TitleBar" Background="LightBlue" DockPanel.Dock="Top" ColumnDefinitions="Auto,*,Auto">
@ -18,7 +19,13 @@
</StackPanel>
</Grid>
<Border Background="White" Margin="5">
<TextBlock>Hello world!</TextBlock>
<StackPanel>
<TextBlock>Hello world!</TextBlock>
<CheckBox IsChecked="{Binding ElementName=Window, Path=HasSystemDecorations}">Decorated</CheckBox>
<CheckBox IsChecked="{Binding ElementName=Window, Path=CanResize}">CanResize</CheckBox>
</StackPanel>
</Border>
</DockPanel>
<Border Name="TopLeft" Background="Red"/>
@ -30,4 +37,4 @@
<Border Name="Bottom" Background="Blue" Grid.Row="2" Grid.Column="1" />
<Border Name="Left" Background="Blue" Grid.Row="1" />
</Grid>
</Window>
</Window>

1
samples/ControlCatalog/MainView.xaml

@ -1,6 +1,7 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:pages="clr-namespace:ControlCatalog.Pages"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.MainView"
Background="{DynamicResource ThemeBackgroundBrush}"
Foreground="{DynamicResource ThemeForegroundBrush}"
FontSize="{DynamicResource FontSizeNormal}">

8
samples/ControlCatalog/MainWindow.xaml

@ -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>

4
samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml

@ -1,4 +1,6 @@
<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.AutoCompleteBoxPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">AutoCompleteBox</TextBlock>
<TextBlock Classes="h2">A control into which the user can input text</TextBlock>

4
samples/ControlCatalog/Pages/BorderPage.xaml

@ -1,4 +1,6 @@
<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.BorderPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">Border</TextBlock>
<TextBlock Classes="h2">A control which decorates a child with a border and background</TextBlock>

3
samples/ControlCatalog/Pages/ButtonPage.xaml

@ -1,5 +1,6 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.Pages.ButtonPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">Button</TextBlock>
<TextBlock Classes="h2">A button control</TextBlock>

3
samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml

@ -1,5 +1,6 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.Pages.ButtonSpinnerPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">ButtonSpinner</TextBlock>

3
samples/ControlCatalog/Pages/CalendarPage.xaml

@ -1,5 +1,6 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.Pages.CalendarPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">Calendar</TextBlock>
<TextBlock Classes="h2">A calendar control for selecting dates</TextBlock>

4
samples/ControlCatalog/Pages/CanvasPage.xaml

@ -1,4 +1,6 @@
<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.CanvasPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">Canvas</TextBlock>
<TextBlock Classes="h2">A panel which lays out its children by explicit coordinates</TextBlock>

10
samples/ControlCatalog/Pages/CarouselPage.xaml

@ -1,4 +1,6 @@
<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.CarouselPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">Carousel</TextBlock>
<TextBlock Classes="h2">An items control that displays its items as pages that fill the control.</TextBlock>
@ -11,9 +13,9 @@
<Carousel.PageTransition>
<PageSlide Duration="0.25" Orientation="Vertical" />
</Carousel.PageTransition>
<Image Source="resm:ControlCatalog.Assets.delicate-arch-896885_640.jpg"/>
<Image Source="resm:ControlCatalog.Assets.hirsch-899118_640.jpg"/>
<Image Source="resm:ControlCatalog.Assets.maple-leaf-888807_640.jpg"/>
<Image Source="/Assets/delicate-arch-896885_640.jpg"/>
<Image Source="/Assets/hirsch-899118_640.jpg"/>
<Image Source="/Assets/maple-leaf-888807_640.jpg"/>
</Carousel>
<Button Name="right" VerticalAlignment="Center" Padding="20">
<Path Data="M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z" Fill="Black"/>

3
samples/ControlCatalog/Pages/CheckBoxPage.xaml

@ -1,5 +1,6 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.Pages.CheckBoxPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">CheckBox</TextBlock>
<TextBlock Classes="h2">A check box control</TextBlock>

6
samples/ControlCatalog/Pages/ContextMenuPage.xaml

@ -1,4 +1,6 @@
<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.ContextMenuPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">Context Menu</TextBlock>
<TextBlock Classes="h2">A right click menu that can be applied to any control.</TextBlock>
@ -19,7 +21,7 @@
</MenuItem>
<MenuItem Header="Menu Item with _Icon">
<MenuItem.Icon>
<Image Source="resm:ControlCatalog.Assets.github_icon.png"/>
<Image Source="/Assets/github_icon.png"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Menu Item with _Checkbox">

3
samples/ControlCatalog/Pages/DatePickerPage.xaml

@ -1,5 +1,6 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.Pages.DatePickerPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">DatePicker</TextBlock>
<TextBlock Classes="h2">A control for selecting dates with a calendar drop-down</TextBlock>

4
samples/ControlCatalog/Pages/DialogsPage.xaml

@ -1,4 +1,6 @@
<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>

4
samples/ControlCatalog/Pages/DragAndDropPage.xaml

@ -1,4 +1,6 @@
<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.DragAndDropPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">Drag+Drop</TextBlock>
<TextBlock Classes="h2">Example of Drag+Drop capabilities</TextBlock>

4
samples/ControlCatalog/Pages/DropDownPage.xaml

@ -1,4 +1,6 @@
<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.DropDownPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">DropDown</TextBlock>
<TextBlock Classes="h2">A drop-down list.</TextBlock>

4
samples/ControlCatalog/Pages/ExpanderPage.xaml

@ -1,4 +1,6 @@
<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.ExpanderPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">Expander</TextBlock>
<TextBlock Classes="h2">Expands to show nested content</TextBlock>

14
samples/ControlCatalog/Pages/ImagePage.xaml

@ -1,4 +1,6 @@
<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.ImagePage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">Image</TextBlock>
<TextBlock Classes="h2">Displays an image</TextBlock>
@ -9,28 +11,28 @@
Spacing="16">
<StackPanel Orientation="Vertical">
<TextBlock>No Stretch</TextBlock>
<Image Source="resm:ControlCatalog.Assets.delicate-arch-896885_640.jpg"
<Image Source="/Assets/delicate-arch-896885_640.jpg"
Width="100" Height="200"
Stretch="None"/>
</StackPanel>
<StackPanel Orientation="Vertical">
<TextBlock>Fill</TextBlock>
<Image Source="resm:ControlCatalog.Assets.delicate-arch-896885_640.jpg"
<Image Source="/Assets/delicate-arch-896885_640.jpg"
Width="100" Height="200"
Stretch="Fill"/>
</StackPanel>
<StackPanel Orientation="Vertical">
<TextBlock>Uniform</TextBlock>
<Image Source="resm:ControlCatalog.Assets.delicate-arch-896885_640.jpg"
<Image Source="/Assets/delicate-arch-896885_640.jpg"
Width="100" Height="200"
Stretch="Uniform"/>
</StackPanel>
<StackPanel Orientation="Vertical">
<TextBlock>UniformToFill</TextBlock>
<Image Source="resm:ControlCatalog.Assets.delicate-arch-896885_640.jpg"
<Image Source="/Assets/delicate-arch-896885_640.jpg"
Width="100" Height="200"
Stretch="UniformToFill"/>
</StackPanel>
@ -40,4 +42,4 @@
<Image Name="Icon" Width="100" Height="200" Stretch="None" />
</StackPanel>
</StackPanel>
</UserControl>
</UserControl>

5
samples/ControlCatalog/Pages/LayoutTransformControlPage.xaml

@ -1,5 +1,6 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.Pages.LayoutTransformControlPage">
<DockPanel>
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto" Margin="16" DockPanel.Dock="Top">
<TextBlock Grid.Column="0" Grid.Row="0">Rotation</TextBlock>
@ -23,4 +24,4 @@
</LayoutTransformControl>
</Grid>
</DockPanel>
</UserControl>
</UserControl>

4
samples/ControlCatalog/Pages/ListBoxPage.xaml

@ -1,4 +1,6 @@
<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.ListBoxPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">ListBox</TextBlock>
<TextBlock Classes="h2">Hosts a collection of ListBoxItem.</TextBlock>

6
samples/ControlCatalog/Pages/MenuPage.xaml

@ -1,4 +1,6 @@
<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.MenuPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">Menu</TextBlock>
<TextBlock Classes="h2">A window menu</TextBlock>
@ -19,7 +21,7 @@
</MenuItem>
<MenuItem Header="Menu Item with _Icon">
<MenuItem.Icon>
<Image Source="resm:ControlCatalog.Assets.github_icon.png"/>
<Image Source="/Assets/github_icon.png"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Menu Item with _Checkbox">

3
samples/ControlCatalog/Pages/NumericUpDownPage.xaml

@ -1,5 +1,6 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.Pages.NumericUpDownPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Margin="2" Classes="h1">Numeric up-down control</TextBlock>
<TextBlock Margin="2" Classes="h2" TextWrapping="Wrap">Numeric up-down control provides a TextBox with button spinners that allow incrementing and decrementing numeric values by using the spinner buttons, keyboard up/down arrows, or mouse wheel.</TextBlock>

6
samples/ControlCatalog/Pages/ProgressBarPage.xaml

@ -1,4 +1,6 @@
<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.ProgressBarPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">ProgressBar</TextBlock>
<TextBlock Classes="h2">A progress bar control</TextBlock>
@ -21,4 +23,4 @@
</StackPanel>
</StackPanel>
</StackPanel>
</UserControl>
</UserControl>

5
samples/ControlCatalog/Pages/RadioButtonPage.xaml

@ -1,5 +1,6 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.Pages.RadioButtonPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">RadioButton</TextBlock>
<TextBlock Classes="h2">Allows the selection of a single option of many</TextBlock>
@ -37,4 +38,4 @@
</StackPanel>
</StackPanel>
</StackPanel>
</UserControl>
</UserControl>

6
samples/ControlCatalog/Pages/SliderPage.xaml

@ -1,4 +1,6 @@
<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.SliderPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">Slider</TextBlock>
<TextBlock Classes="h2">A control that lets the user select from a range of values by moving a Thumb control along a Track.</TextBlock>
@ -18,4 +20,4 @@
</StackPanel>
</StackPanel>
</UserControl>
</UserControl>

44
samples/ControlCatalog/Pages/TabControlPage.xaml

@ -1,4 +1,7 @@
<UserControl xmlns="https://github.com/avaloniaui">
<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"
@ -26,43 +29,19 @@
<TabControl
Margin="0 16"
TabStripPlacement="{Binding TabPlacement}">
<TabItem>
<TabItem.Header>
<TextBlock
Text="Arch"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="8">
</TextBlock>
</TabItem.Header>
<TabItem Header="Arch">
<StackPanel Orientation="Vertical" Spacing="8">
<TextBlock>This is the first page in the TabControl.</TextBlock>
<Image Source="resm:ControlCatalog.Assets.delicate-arch-896885_640.jpg" Width="300"/>
<Image Source="/Assets/delicate-arch-896885_640.jpg" Width="300"/>
</StackPanel>
</TabItem>
<TabItem>
<TabItem.Header>
<TextBlock
Text="Leaf"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="8">
</TextBlock>
</TabItem.Header>
<TabItem Header="Leaf">
<StackPanel Orientation="Vertical" Spacing="8">
<TextBlock>This is the second page in the TabControl.</TextBlock>
<Image Source="resm:ControlCatalog.Assets.maple-leaf-888807_640.jpg" Width="300"/>
<Image Source="/Assets/maple-leaf-888807_640.jpg" Width="300"/>
</StackPanel>
</TabItem>
<TabItem IsEnabled="False">
<TabItem.Header>
<TextBlock
Text="Disabled"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="8">
</TextBlock>
</TabItem.Header>
<TabItem Header="Disabled" IsEnabled="False">
<TextBlock>You should not see this.</TextBlock>
</TabItem>
</TabControl>
@ -82,10 +61,7 @@
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding Header}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="8">
Text="{Binding Header}">
</TextBlock>
</DataTemplate>
</TabControl.ItemTemplate>

4
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
{

15
samples/ControlCatalog/Pages/TextBoxPage.xaml

@ -1,4 +1,6 @@
<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.TextBoxPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">TextBox</TextBlock>
<TextBlock Classes="h2">A control into which the user can input text</TextBlock>
@ -33,11 +35,20 @@
Text="Multiline TextBox with no TextWrapping.&#xD;&#xD;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." />
</StackPanel>
<StackPanel Orientation="Vertical" Spacing="8">
<TextBlock Classes="h2">resm fonts</TextBlock>
<TextBox Width="200" Text="Custom font regular" FontWeight="Normal" FontStyle="Normal" FontFamily="resm:ControlCatalog.Assets.Fonts?assembly=ControlCatalog#Source Sans Pro"/>
<TextBox Width="200" Text="Custom font bold" FontWeight="Bold" FontStyle="Normal" FontFamily="resm:ControlCatalog.Assets.Fonts?assembly=ControlCatalog#Source Sans Pro"/>
<TextBox Width="200" Text="Custom font italic" FontWeight="Normal" FontStyle="Italic" FontFamily="resm:ControlCatalog.Assets.Fonts.SourceSansPro-Italic.ttf?assembly=ControlCatalog#Source Sans Pro"/>
<TextBox Width="200" Text="Custom font italic bold" FontWeight="Bold" FontStyle="Italic" FontFamily="resm:ControlCatalog.Assets.Fonts.SourceSansPro-*.ttf?assembly=ControlCatalog#Source Sans Pro"/>
</StackPanel>
<StackPanel Orientation="Vertical" Spacing="8">
<TextBlock Classes="h2">res fonts</TextBlock>
<TextBox Width="200" Text="Custom font regular" FontWeight="Normal" FontStyle="Normal" FontFamily="avares://ControlCatalog/Assets/Fonts#Source Sans Pro"/>
<TextBox Width="200" Text="Custom font bold" FontWeight="Bold" FontStyle="Normal" FontFamily="avares://ControlCatalog/Assets/Fonts#Source Sans Pro"/>
<TextBox Width="200" Text="Custom font italic" FontWeight="Normal" FontStyle="Italic" FontFamily="/Assets/Fonts/SourceSansPro-Italic.ttf#Source Sans Pro"/>
<TextBox Width="200" Text="Custom font italic bold" FontWeight="Bold" FontStyle="Italic" FontFamily="/Assets/Fonts/SourceSansPro-*.ttf#Source Sans Pro"/>
</StackPanel>
</StackPanel>
</StackPanel>
</UserControl>
</UserControl>

6
samples/ControlCatalog/Pages/ToolTipPage.xaml

@ -1,4 +1,6 @@
<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.ToolTipPage">
<StackPanel Orientation="Vertical"
Spacing="4">
<TextBlock Classes="h1">ToolTip</TextBlock>
@ -38,4 +40,4 @@
</Border>
</Grid>
</StackPanel>
</UserControl>
</UserControl>

6
samples/ControlCatalog/Pages/TreeViewPage.xaml

@ -1,4 +1,6 @@
<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.TreeViewPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">TreeView</TextBlock>
<TextBlock Classes="h2">Displays a hierachical tree of data.</TextBlock>
@ -16,4 +18,4 @@
</TreeView>
</StackPanel>
</StackPanel>
</UserControl>
</UserControl>

3
samples/ControlCatalog/Pages/ViewboxPage.xaml

@ -1,5 +1,6 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
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,

6
samples/ControlCatalog/SideBar.xaml

@ -1,5 +1,6 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
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"/>
@ -17,8 +18,7 @@
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}"
Background="{TemplateBinding Background}">
<ItemsPresenter
Name="PART_ItemsPresenter"
MinWidth="190"
Name="PART_ItemsPresenter"
Items="{TemplateBinding Items}"
ItemsPanel="{TemplateBinding ItemsPanel}"
ItemTemplate="{TemplateBinding ItemTemplate}"

5
samples/RenderDemo/MainWindow.xaml

@ -24,9 +24,6 @@
</MenuItem>
</Menu>
<TabControl Classes="sidebar">
<TabControl.PageTransition>
<CrossFade Duration="0.25"/>
</TabControl.PageTransition>
<TabItem Header="Animations">
<pages:AnimationsPage/>
</TabItem>
@ -38,4 +35,4 @@
</TabItem>
</TabControl>
</DockPanel>
</Window>
</Window>

113
samples/RenderDemo/SideBar.xaml

@ -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>

1
src/Avalonia.Animation/Avalonia.Animation.csproj

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" />

4
src/Avalonia.Base/Avalonia.Base.csproj

@ -4,8 +4,10 @@
<AssemblyName>Avalonia.Base</AssemblyName>
<RootNamespace>Avalonia</RootNamespace>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Avalonia.Build.Tasks\Avalonia.Build.Tasks.csproj"/>
</ItemGroup>
<Import Project="..\..\build\Base.props" />
<Import Project="..\..\build\Binding.props" />
<Import Project="..\..\build\Rx.props" />

2
src/Avalonia.Base/Platform/IAssetLoader.cs

@ -66,6 +66,6 @@ namespace Avalonia.Platform
/// </summary>
/// <param name="uri">The URI.</param>
/// <returns>All matching assets as a tuple of the absolute path to the asset and the assembly containing the asset</returns>
IEnumerable<(string absolutePath, Assembly assembly)> GetAssets(Uri uri);
IEnumerable<Uri> GetAssets(Uri uri, Uri baseUri);
}
}

64
src/Avalonia.Base/Utilities/AvaloniaResourcesIndex.cs

@ -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; }
}
}

18
src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<BuildOutputTargetFolder>tools</BuildOutputTargetFolder>
<DefineConstants>$(DefineConstants);BUILDTASK</DefineConstants>
</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>

9
src/Avalonia.Build.Tasks/BuildEngineErrorCode.cs

@ -0,0 +1,9 @@
namespace Avalonia.Build.Tasks
{
public enum BuildEngineErrorCode
{
InvalidXAML = 1,
DuplicateXClass = 2,
LegacyResmScheme = 3,
}
}

21
src/Avalonia.Build.Tasks/Extensions.cs

@ -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"));
}
}
}

159
src/Avalonia.Build.Tasks/GenerateAvaloniaResourcesTask.cs

@ -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; }
}
}

20
src/Avalonia.Build.Tasks/XamlFileInfo.cs

@ -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
};
}
}
}

9
src/Avalonia.Controls/AppBuilderBase.cs

@ -145,6 +145,15 @@ namespace Avalonia.Controls
Instance.Run(mainWindow);
}
public delegate void AppMainDelegate(Application app, string[] args);
public void Start(AppMainDelegate main, string[] args)
{
Setup();
BeforeStartCallback(Self);
main(Instance, args);
}
/// <summary>
/// Sets up the platform-specific services for the application, but does not run it.
/// </summary>

1
src/Avalonia.Controls/Avalonia.Controls.csproj

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Avalonia.Animation\Avalonia.Animation.csproj" />

4
src/Avalonia.Controls/Button.cs

@ -253,10 +253,8 @@ namespace Avalonia.Controls
IsPressed = false;
e.Handled = true;
var hittest = this.GetVisualsAt(e.GetPosition(this));
if (ClickMode == ClickMode.Release &&
hittest.Any(c => c == this || (c as IStyledElement)?.TemplatedParent == this))
this.GetVisualsAt(e.GetPosition(this)).Any(c => this == c || this.IsVisualAncestorOf(c)))
{
OnClick();
}

87
src/Avalonia.Controls/DropDown.cs

@ -2,9 +2,12 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Linq;
using Avalonia.Controls.Generators;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Shapes;
using Avalonia.Controls.Templates;
using Avalonia.Input;
using Avalonia.LogicalTree;
using Avalonia.Media;
@ -12,12 +15,17 @@ using Avalonia.VisualTree;
namespace Avalonia.Controls
{
/// <summary>
/// A drop-down list control.
/// </summary>
public class DropDown : SelectingItemsControl
{
/// <summary>
/// The default value for the <see cref="ItemsControl.ItemsPanel"/> property.
/// </summary>
private static readonly FuncTemplate<IPanel> DefaultPanel =
new FuncTemplate<IPanel>(() => new VirtualizingStackPanel());
/// <summary>
/// Defines the <see cref="IsDropDownOpen"/> property.
/// </summary>
@ -39,6 +47,12 @@ namespace Avalonia.Controls
public static readonly DirectProperty<DropDown, object> SelectionBoxItemProperty =
AvaloniaProperty.RegisterDirect<DropDown, object>(nameof(SelectionBoxItem), o => o.SelectionBoxItem);
/// <summary>
/// Defines the <see cref="VirtualizationMode"/> property.
/// </summary>
public static readonly StyledProperty<ItemVirtualizationMode> VirtualizationModeProperty =
ItemsPresenter.VirtualizationModeProperty.AddOwner<DropDown>();
private bool _isDropDownOpen;
private Popup _popup;
private object _selectionBoxItem;
@ -48,6 +62,7 @@ namespace Avalonia.Controls
/// </summary>
static DropDown()
{
ItemsPanelProperty.OverrideDefaultValue<DropDown>(DefaultPanel);
FocusableProperty.OverrideDefaultValue<DropDown>(true);
SelectedItemProperty.Changed.AddClassHandler<DropDown>(x => x.SelectedItemChanged);
KeyDownEvent.AddClassHandler<DropDown>(x => x.OnKeyDown, Interactivity.RoutingStrategies.Tunnel);
@ -80,6 +95,15 @@ namespace Avalonia.Controls
set { SetAndRaise(SelectionBoxItemProperty, ref _selectionBoxItem, value); }
}
/// <summary>
/// Gets or sets the virtualization mode for the items.
/// </summary>
public ItemVirtualizationMode VirtualizationMode
{
get { return GetValue(VirtualizationModeProperty); }
set { SetValue(VirtualizationModeProperty, value); }
}
/// <inheritdoc/>
protected override IItemContainerGenerator CreateItemContainerGenerator()
{
@ -138,6 +162,16 @@ namespace Avalonia.Controls
e.Handled = true;
}
}
else if (IsDropDownOpen && SelectedIndex < 0 && ItemCount > 0 &&
(e.Key == Key.Up || e.Key == Key.Down))
{
var firstChild = Presenter?.Panel?.Children.FirstOrDefault(c => CanFocus(c));
if (firstChild != null)
{
FocusManager.Instance?.Focus(firstChild, NavigationMethod.Directional);
e.Handled = true;
}
}
}
/// <inheritdoc/>
@ -159,6 +193,7 @@ namespace Avalonia.Controls
e.Handled = true;
}
}
base.OnPointerPressed(e);
}
@ -168,28 +203,65 @@ namespace Avalonia.Controls
if (_popup != null)
{
_popup.Opened -= PopupOpened;
_popup.Closed -= PopupClosed;
}
_popup = e.NameScope.Get<Popup>("PART_Popup");
_popup.Opened += PopupOpened;
_popup.Closed += PopupClosed;
base.OnTemplateApplied(e);
}
private void PopupOpened(object sender, EventArgs e)
internal void ItemFocused(DropDownItem dropDownItem)
{
var selectedIndex = SelectedIndex;
if (IsDropDownOpen && dropDownItem.IsFocused && dropDownItem.IsArrangeValid)
{
dropDownItem.BringIntoView();
}
}
if (selectedIndex != -1)
private void PopupClosed(object sender, EventArgs e)
{
if (CanFocus(this))
{
var container = ItemContainerGenerator.ContainerFromIndex(selectedIndex);
container?.Focus();
Focus();
}
}
private void PopupOpened(object sender, EventArgs e)
{
TryFocusSelectedItem();
}
private void SelectedItemChanged(AvaloniaPropertyChangedEventArgs e)
{
UpdateSelectionBoxItem(e.NewValue);
TryFocusSelectedItem();
}
private void TryFocusSelectedItem()
{
var selectedIndex = SelectedIndex;
if (IsDropDownOpen && selectedIndex != -1)
{
var container = ItemContainerGenerator.ContainerFromIndex(selectedIndex);
if(container == null && SelectedItems.Count > 0)
{
ScrollIntoView(SelectedItems[0]);
container = ItemContainerGenerator.ContainerFromIndex(selectedIndex);
}
if (container != null && CanFocus(container))
{
container.Focus();
}
}
}
private bool CanFocus(IControl control) => control.Focusable && control.IsEnabledCore && control.IsVisible;
private void UpdateSelectionBoxItem(object item)
{
var contentControl = item as IContentControl;
@ -219,7 +291,8 @@ namespace Avalonia.Controls
}
else
{
SelectionBoxItem = item;
var selector = MemberSelector;
SelectionBoxItem = selector != null ? selector.Select(item) : item;
}
}

32
src/Avalonia.Controls/DropDownItem.cs

@ -2,43 +2,19 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Reactive.Linq;
namespace Avalonia.Controls
{
/// <summary>
/// A selectable item in a <see cref="DropDown"/>.
/// </summary>
public class DropDownItem : ContentControl, ISelectable
public class DropDownItem : ListBoxItem
{
/// <summary>
/// Defines the <see cref="IsSelected"/> property.
/// </summary>
public static readonly StyledProperty<bool> IsSelectedProperty =
AvaloniaProperty.Register<DropDownItem, bool>(nameof(IsSelected));
/// <summary>
/// Initializes static members of the <see cref="DropDownItem"/> class.
/// </summary>
static DropDownItem()
{
FocusableProperty.OverrideDefaultValue<DropDownItem>(true);
}
public DropDownItem()
{
this.GetObservable(DropDownItem.IsFocusedProperty).Subscribe(focused =>
{
PseudoClasses.Set(":selected", focused);
});
}
/// <summary>
/// Gets or sets the selection state of the item.
/// </summary>
public bool IsSelected
{
get { return GetValue(IsSelectedProperty); }
set { SetValue(IsSelectedProperty, value); }
this.GetObservable(DropDownItem.IsFocusedProperty).Where(focused => focused)
.Subscribe(_ => (Parent as DropDown)?.ItemFocused(this));
}
}
}

2
src/Avalonia.Controls/Generators/TabItemContainerGenerator.cs

@ -21,6 +21,8 @@ namespace Avalonia.Controls.Generators
tabItem.ParentTabControl = Owner;
tabItem[~TabControl.TabStripPlacementProperty] = Owner[~TabControl.TabStripPlacementProperty];
if (tabItem.HeaderTemplate == null)
{
tabItem[~HeaderedContentControl.HeaderTemplateProperty] = Owner[~ItemsControl.ItemTemplateProperty];

9
src/Avalonia.Controls/Primitives/SelectingItemsControl.cs

@ -431,9 +431,12 @@ namespace Avalonia.Controls.Primitives
{
if (i.ContainerControl != null && i.Item != null)
{
MarkContainerSelected(
i.ContainerControl,
SelectedItems.Contains(i.Item));
var ms = MemberSelector;
bool selected = ms == null ?
SelectedItems.Contains(i.Item) :
SelectedItems.OfType<object>().Any(v => Equals(ms.Select(v), i.Item));
MarkContainerSelected(i.ContainerControl, selected);
}
}
}

8
src/Avalonia.Controls/TabItem.cs

@ -23,8 +23,6 @@ namespace Avalonia.Controls
public static readonly StyledProperty<bool> IsSelectedProperty =
ListBoxItem.IsSelectedProperty.AddOwner<TabItem>();
private TabControl _parentTabControl;
/// <summary>
/// Initializes static members of the <see cref="TabItem"/> class.
/// </summary>
@ -56,11 +54,7 @@ namespace Avalonia.Controls
set { SetValue(IsSelectedProperty, value); }
}
internal TabControl ParentTabControl
{
get => _parentTabControl;
set => _parentTabControl = value;
}
internal TabControl ParentTabControl { get; set; }
private void UpdateHeader(AvaloniaPropertyChangedEventArgs obj)
{

1
src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>false</IsPackable>
<!-- WARNING! The designer support version number needs to be frozen
To allow projects that implement designer functionality to still
work with newer versions of Avalonia. This version number only

6
src/Avalonia.DesignerSupport/DesignWindowLoader.cs

@ -12,7 +12,7 @@ namespace Avalonia.DesignerSupport
{
public class DesignWindowLoader
{
public static Window LoadDesignerWindow(string xaml, string assemblyPath)
public static Window LoadDesignerWindow(string xaml, string assemblyPath, string xamlFileProjectPath)
{
Window window;
Control control;
@ -26,9 +26,11 @@ namespace Avalonia.DesignerSupport
Uri baseUri = null;
if (assemblyPath != null)
{
if (xamlFileProjectPath == null)
xamlFileProjectPath = "/Designer/Fake.xaml";
//Fabricate fake Uri
baseUri =
new Uri("resm:Fake.xaml?assembly=" + Path.GetFileNameWithoutExtension(assemblyPath));
new Uri($"avares://{Path.GetFileNameWithoutExtension(assemblyPath)}{xamlFileProjectPath}");
}
var localAsm = assemblyPath != null ? Assembly.LoadFile(Path.GetFullPath(assemblyPath)) : null;

2
src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs

@ -199,7 +199,7 @@ namespace Avalonia.DesignerSupport.Remote
s_currentWindow = null;
try
{
s_currentWindow = DesignWindowLoader.LoadDesignerWindow(xaml.Xaml, xaml.AssemblyPath);
s_currentWindow = DesignWindowLoader.LoadDesignerWindow(xaml.Xaml, xaml.AssemblyPath, xaml.XamlFileProjectPath);
s_transport.Send(new UpdateXamlResultMessage(){Handle = s_currentWindow.PlatformImpl?.Handle?.Handle.ToString()});
}
catch (Exception e)

1
src/Avalonia.DesktopRuntime/Avalonia.DesktopRuntime.csproj

@ -2,7 +2,6 @@
<PropertyGroup>
<TargetFrameworks>net461;netcoreapp2.0</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>

1
src/Avalonia.Diagnostics/Avalonia.Diagnostics.csproj

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" />

1
src/Avalonia.Input/Avalonia.Input.csproj

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Avalonia.Animation\Avalonia.Animation.csproj" />

1
src/Avalonia.Interactivity/Avalonia.Interactivity.csproj

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Avalonia.Animation\Avalonia.Animation.csproj" />

1
src/Avalonia.Layout/Avalonia.Layout.csproj

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Avalonia.Animation\Avalonia.Animation.csproj" />

1
src/Avalonia.Logging.Serilog/Avalonia.Logging.Serilog.csproj

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" />

3
src/Avalonia.Remote.Protocol/DesignMessages.cs

@ -7,6 +7,7 @@ namespace Avalonia.Remote.Protocol.Designer
{
public string Xaml { get; set; }
public string AssemblyPath { get; set; }
public string XamlFileProjectPath { get; set; }
}
[AvaloniaRemoteMessageGuid("B7A70093-0C5D-47FD-9261-22086D43A2E2")]
@ -22,4 +23,4 @@ namespace Avalonia.Remote.Protocol.Designer
public string SessionId { get; set; }
}
}
}

1
src/Avalonia.Styling/Avalonia.Styling.csproj

@ -3,7 +3,6 @@
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>Avalonia.Styling</AssemblyName>
<RootNamespace>Avalonia</RootNamespace>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Avalonia.Animation\Avalonia.Animation.csproj" />

4
src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" />
@ -13,7 +12,10 @@
<ProjectReference Include="..\Avalonia.Layout\Avalonia.Layout.csproj" />
<ProjectReference Include="..\Avalonia.Visuals\Avalonia.Visuals.csproj" />
<ProjectReference Include="..\Avalonia.Styling\Avalonia.Styling.csproj" />
<AvaloniaResource Include="DefaultTheme.xaml"/>
<AvaloniaResource Include="Accents/*.xaml"/>
</ItemGroup>
<Import Project="..\..\build\EmbedXaml.props" />
<Import Project="..\..\build\BuildTargets.targets"/>
<Import Project="..\..\build\Rx.props" />
</Project>

20
src/Avalonia.Themes.Default/DropDown.xaml

@ -35,15 +35,21 @@
MinWidth="{Binding Bounds.Width, RelativeSource={RelativeSource TemplatedParent}}"
MaxHeight="{TemplateBinding MaxDropDownHeight}"
PlacementTarget="{TemplateBinding}"
ObeyScreenEdges="True"
StaysOpen="False">
<Border BorderBrush="{DynamicResource ThemeBorderMidBrush}"
BorderThickness="1">
<ScrollViewer>
<ItemsPresenter Name="PART_ItemsPresenter"
Items="{TemplateBinding Items}"
ItemTemplate="{TemplateBinding ItemTemplate}"
MemberSelector="{TemplateBinding MemberSelector}"/>
</ScrollViewer>
<AdornerDecorator Margin="-1 -1 0 0">
<ScrollViewer>
<ItemsPresenter Name="PART_ItemsPresenter"
Items="{TemplateBinding Items}"
ItemsPanel="{TemplateBinding ItemsPanel}"
ItemTemplate="{TemplateBinding ItemTemplate}"
MemberSelector="{TemplateBinding MemberSelector}"
VirtualizationMode="{TemplateBinding VirtualizationMode}"
/>
</ScrollViewer>
</AdornerDecorator>
</Border>
</Popup>
</Grid>
@ -54,4 +60,4 @@
<Style Selector="DropDown:pointerover /template/ Border#border">
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderHighBrush}"/>
</Style>
</Styles>
</Styles>

2
src/Avalonia.Themes.Default/DropDownItem.xaml

@ -18,7 +18,7 @@
</ControlTemplate>
</Setter>
</Style>
<Style Selector="DropDownItem:pointerover /template/ ContentPresenter">
<Setter Property="Background" Value="{DynamicResource ThemeControlHighlightMidBrush}"/>
</Style>

5
src/Avalonia.Themes.Default/FocusAdorner.xaml

@ -3,7 +3,8 @@
<FocusAdornerTemplate>
<Rectangle Stroke="Black"
StrokeThickness="1"
StrokeDashArray="1,2"/>
StrokeDashArray="1,2"
Margin="1"/>
</FocusAdornerTemplate>
</Setter>
</Style>
</Style>

4
src/Avalonia.Themes.Default/MenuItem.xaml

@ -49,7 +49,7 @@
ObeyScreenEdges="True">
<Border Background="{TemplateBinding Background}"
BorderBrush="{DynamicResource ThemeBorderMidBrush}"
BorderThickness="1">
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer>
<Panel>
<ItemsPresenter Name="PART_ItemsPresenter"
@ -107,7 +107,7 @@
ObeyScreenEdges="True">
<Border Background="{TemplateBinding Background}"
BorderBrush="{DynamicResource ThemeBorderMidBrush}"
BorderThickness="1">
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer>
<Panel>
<ItemsPresenter Name="PART_ItemsPresenter"

19
src/Avalonia.Themes.Default/TabControl.xaml

@ -1,10 +1,5 @@
<Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style Selector="TabControl">
<Setter Property="Background" Value="{DynamicResource ThemeBackgroundBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderMidBrush}"/>
<Setter Property="Padding" Value="4"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Style Selector="TabControl">
<Setter Property="Template">
<ControlTemplate>
<Border
@ -35,22 +30,34 @@
</ControlTemplate>
</Setter>
</Style>
<Style Selector="TabControl[TabStripPlacement=Top]">
<Setter Property="Padding" Value="0 4 0 0"/>
</Style>
<Style Selector="TabControl[TabStripPlacement=Top] /template/ ItemsPresenter#PART_ItemsPresenter">
<Setter Property="DockPanel.Dock" Value="Top"/>
</Style>
<Style Selector="TabControl[TabStripPlacement=Bottom] /template/ ItemsPresenter#PART_ItemsPresenter">
<Setter Property="DockPanel.Dock" Value="Bottom"/>
</Style>
<Style Selector="TabControl[TabStripPlacement=Bottom]">
<Setter Property="Padding" Value="0 0 0 4"/>
</Style>
<Style Selector="TabControl[TabStripPlacement=Left] /template/ ItemsPresenter#PART_ItemsPresenter">
<Setter Property="DockPanel.Dock" Value="Left"/>
</Style>
<Style Selector="TabControl[TabStripPlacement=Left] /template/ ItemsPresenter#PART_ItemsPresenter > WrapPanel">
<Setter Property="Orientation" Value="Vertical"/>
</Style>
<Style Selector="TabControl[TabStripPlacement=Left]">
<Setter Property="Padding" Value="4 0 0 0"/>
</Style>
<Style Selector="TabControl[TabStripPlacement=Right] /template/ ItemsPresenter#PART_ItemsPresenter">
<Setter Property="DockPanel.Dock" Value="Right"/>
</Style>
<Style Selector="TabControl[TabStripPlacement=Right] /template/ ItemsPresenter#PART_ItemsPresenter > WrapPanel">
<Setter Property="Orientation" Value="Vertical"/>
</Style>
<Style Selector="TabControl[TabStripPlacement=Right]">
<Setter Property="Padding" Value="0 0 0 4"/>
</Style>
</Styles>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save