diff --git a/.ncrunch/BindingDemo.v3.ncrunchproject b/.ncrunch/BindingDemo.v3.ncrunchproject
new file mode 100644
index 0000000000..319cd523ce
--- /dev/null
+++ b/.ncrunch/BindingDemo.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ True
+
+
\ No newline at end of file
diff --git a/.ncrunch/RenderDemo.v3.ncrunchproject b/.ncrunch/RenderDemo.v3.ncrunchproject
new file mode 100644
index 0000000000..319cd523ce
--- /dev/null
+++ b/.ncrunch/RenderDemo.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ True
+
+
\ No newline at end of file
diff --git a/.ncrunch/VirtualizationDemo.v3.ncrunchproject b/.ncrunch/VirtualizationDemo.v3.ncrunchproject
new file mode 100644
index 0000000000..319cd523ce
--- /dev/null
+++ b/.ncrunch/VirtualizationDemo.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ True
+
+
\ No newline at end of file
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index accad63faa..b70e0bf77f 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -14,7 +14,7 @@ jobs:
displayName: 'Install Nuke'
inputs:
script: |
- dotnet tool install --global Nuke.GlobalTool --version 0.12.3
+ dotnet tool install --global Nuke.GlobalTool --version 0.24.0
- task: CmdLine@2
displayName: 'Run Nuke'
inputs:
@@ -35,16 +35,16 @@ jobs:
vmImage: 'macOS-10.14'
steps:
- task: UseDotNet@2
- displayName: 'Use .NET Core SDK 3.0.x'
+ displayName: 'Use .NET Core SDK 3.1.101'
inputs:
packageType: sdk
- version: 3.0.x
+ version: 3.1.101
- task: UseDotNet@2
- displayName: 'Use .NET Core Runtime 2.1.x'
+ displayName: 'Use .NET Core Runtime 3.1.1'
inputs:
packageType: runtime
- version: 2.1.x
+ version: 3.1.1
- task: CmdLine@2
displayName: 'Install Mono 5.18'
@@ -74,7 +74,7 @@ jobs:
displayName: 'Install Nuke'
inputs:
script: |
- dotnet tool install --global Nuke.GlobalTool --version 0.12.3
+ dotnet tool install --global Nuke.GlobalTool --version 0.24.0
- task: CmdLine@2
displayName: 'Run Nuke'
@@ -116,7 +116,7 @@ jobs:
displayName: 'Install Nuke'
inputs:
script: |
- dotnet tool install --global Nuke.GlobalTool --version 0.12.3
+ dotnet tool install --global Nuke.GlobalTool --version 0.24.0
- task: CmdLine@2
displayName: 'Run Nuke'
diff --git a/global.json b/global.json
index 1e599211d4..a3fdca9bed 100644
--- a/global.json
+++ b/global.json
@@ -1,4 +1,7 @@
{
+ "sdk": {
+ "version": "3.1.101"
+ },
"msbuild-sdks": {
"Microsoft.Build.Traversal": "1.0.43",
"MSBuild.Sdk.Extras": "2.0.46",
diff --git a/native/Avalonia.Native/inc/avalonia-native.h b/native/Avalonia.Native/inc/avalonia-native.h
index 4a960d47a1..ee57f54e59 100644
--- a/native/Avalonia.Native/inc/avalonia-native.h
+++ b/native/Avalonia.Native/inc/avalonia-native.h
@@ -25,6 +25,12 @@ struct IAvnGlSurfaceRenderingSession;
struct IAvnAppMenu;
struct IAvnAppMenuItem;
+enum SystemDecorations {
+ SystemDecorationsNone = 0,
+ SystemDecorationsBorderOnly = 1,
+ SystemDecorationsFull = 2,
+};
+
struct AvnSize
{
double Width, Height;
@@ -236,7 +242,7 @@ AVNCOM(IAvnWindow, 04) : virtual IAvnWindowBase
{
virtual HRESULT ShowDialog (IAvnWindow* parent) = 0;
virtual HRESULT SetCanResize(bool value) = 0;
- virtual HRESULT SetHasDecorations(bool value) = 0;
+ virtual HRESULT SetHasDecorations(SystemDecorations value) = 0;
virtual HRESULT SetTitle (void* utf8Title) = 0;
virtual HRESULT SetTitleBarColor (AvnColor color) = 0;
virtual HRESULT SetWindowState(AvnWindowState state) = 0;
diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm
index b6ce172ffa..2c03407732 100644
--- a/native/Avalonia.Native/src/OSX/window.mm
+++ b/native/Avalonia.Native/src/OSX/window.mm
@@ -115,7 +115,6 @@ public:
[NSApp activateIgnoringOtherApps:YES];
[Window setTitle:_lastTitle];
- [Window setTitleVisibility:NSWindowTitleVisible];
return S_OK;
}
@@ -411,7 +410,7 @@ class WindowImpl : public virtual WindowBaseImpl, public virtual IAvnWindow, pub
{
private:
bool _canResize = true;
- bool _hasDecorations = true;
+ SystemDecorations _hasDecorations = SystemDecorationsFull;
CGRect _lastUndecoratedFrame;
AvnWindowState _lastWindowState;
@@ -476,23 +475,26 @@ private:
bool IsZoomed ()
{
- return _hasDecorations ? [Window isZoomed] : UndecoratedIsMaximized();
+ return _hasDecorations != SystemDecorationsNone ? [Window isZoomed] : UndecoratedIsMaximized();
}
void DoZoom()
{
- if (_hasDecorations)
+ switch (_hasDecorations)
{
- [Window performZoom:Window];
- }
- else
- {
- if (!UndecoratedIsMaximized())
- {
- _lastUndecoratedFrame = [Window frame];
- }
-
- [Window zoom:Window];
+ case SystemDecorationsNone:
+ if (!UndecoratedIsMaximized())
+ {
+ _lastUndecoratedFrame = [Window frame];
+ }
+
+ [Window zoom:Window];
+ break;
+
+ case SystemDecorationsBorderOnly:
+ case SystemDecorationsFull:
+ [Window performZoom:Window];
+ break;
}
}
@@ -506,13 +508,35 @@ private:
}
}
- virtual HRESULT SetHasDecorations(bool value) override
+ virtual HRESULT SetHasDecorations(SystemDecorations value) override
{
@autoreleasepool
{
_hasDecorations = value;
UpdateStyle();
-
+
+ switch (_hasDecorations)
+ {
+ case SystemDecorationsNone:
+ [Window setHasShadow:NO];
+ [Window setTitleVisibility:NSWindowTitleHidden];
+ [Window setTitlebarAppearsTransparent:YES];
+ break;
+
+ case SystemDecorationsBorderOnly:
+ [Window setHasShadow:YES];
+ [Window setTitleVisibility:NSWindowTitleHidden];
+ [Window setTitlebarAppearsTransparent:YES];
+ break;
+
+ case SystemDecorationsFull:
+ [Window setHasShadow:YES];
+ [Window setTitleVisibility:NSWindowTitleVisible];
+ [Window setTitlebarAppearsTransparent:NO];
+ [Window setTitle:_lastTitle];
+ break;
+ }
+
return S_OK;
}
}
@@ -523,7 +547,6 @@ private:
{
_lastTitle = [NSString stringWithUTF8String:(const char*)utf8title];
[Window setTitle:_lastTitle];
- [Window setTitleVisibility:NSWindowTitleVisible];
return S_OK;
}
@@ -645,10 +668,26 @@ protected:
virtual NSWindowStyleMask GetStyle() override
{
unsigned long s = NSWindowStyleMaskBorderless;
- if(_hasDecorations)
- s = s | NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
- if(_canResize)
- s = s | NSWindowStyleMaskResizable;
+
+ switch (_hasDecorations)
+ {
+ case SystemDecorationsNone:
+ break;
+
+ case SystemDecorationsBorderOnly:
+ s = s | NSWindowStyleMaskTitled | NSWindowStyleMaskFullSizeContentView;
+ break;
+
+ case SystemDecorationsFull:
+ s = s | NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskBorderless;
+ if(_canResize)
+ {
+ s = s | NSWindowStyleMaskResizable;
+ }
+
+ break;
+ }
+
return s;
}
};
diff --git a/nukebuild/Build.cs b/nukebuild/Build.cs
index 7b3b8465ce..358846a14e 100644
--- a/nukebuild/Build.cs
+++ b/nukebuild/Build.cs
@@ -13,6 +13,7 @@ using Nuke.Common.Tooling;
using Nuke.Common.Tools.DotNet;
using Nuke.Common.Tools.MSBuild;
using Nuke.Common.Utilities;
+using Nuke.Common.Utilities.Collections;
using static Nuke.Common.EnvironmentInfo;
using static Nuke.Common.IO.FileSystemTasks;
using static Nuke.Common.IO.PathConstruction;
@@ -26,11 +27,13 @@ using static Nuke.Common.Tools.VSWhere.VSWhereTasks;
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
{
+ [Solution("Avalonia.sln")] readonly Solution Solution;
+
static Lazy MsBuildExe = new Lazy(() =>
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
@@ -54,7 +57,7 @@ partial class Build : NukeBuild
protected override void OnBuildInitialized()
{
Parameters = new BuildParameters(this);
- Information("Building version {0} of Avalonia ({1}) using version {2} of Nuke.",
+ Information("Building version {0} of Avalonia ({1}) using version {2} of Nuke.",
Parameters.Version,
Parameters.Configuration,
typeof(NukeBuild).Assembly.GetName().Version.ToString());
@@ -93,29 +96,24 @@ partial class Build : NukeBuild
string projectFile,
Configure configurator = null)
{
- return MSBuild(projectFile, c =>
- {
+ return MSBuild(c => c
+ .SetProjectFile(projectFile)
// This is required for VS2019 image on Azure Pipelines
- if (Parameters.IsRunningOnWindows && Parameters.IsRunningOnAzure)
- {
- var javaSdk = Environment.GetEnvironmentVariable("JAVA_HOME_8_X64");
- if (javaSdk != null)
- c = c.AddProperty("JavaSdkDirectory", javaSdk);
- }
-
- c = c.AddProperty("PackageVersion", Parameters.Version)
- .AddProperty("iOSRoslynPathHackRequired", "true")
- .SetToolPath(MsBuildExe.Value)
- .SetConfiguration(Parameters.Configuration)
- .SetVerbosity(MSBuildVerbosity.Minimal);
- c = configurator?.Invoke(c) ?? c;
- return c;
- });
+ .When(Parameters.IsRunningOnWindows &&
+ Parameters.IsRunningOnAzure, c => c
+ .AddProperty("JavaSdkDirectory", GetVariable("JAVA_HOME_8_X64")))
+ .AddProperty("PackageVersion", Parameters.Version)
+ .AddProperty("iOSRoslynPathHackRequired", true)
+ .SetToolPath(MsBuildExe.Value)
+ .SetConfiguration(Parameters.Configuration)
+ .SetVerbosity(MSBuildVerbosity.Minimal)
+ .Apply(configurator));
}
+
Target Clean => _ => _.Executes(() =>
{
- DeleteDirectories(Parameters.BuildDirs);
- EnsureCleanDirectories(Parameters.BuildDirs);
+ Parameters.BuildDirs.ForEach(DeleteDirectory);
+ Parameters.BuildDirs.ForEach(EnsureCleanDirectory);
EnsureCleanDirectory(Parameters.ArtifactsDir);
EnsureCleanDirectory(Parameters.NugetIntermediateRoot);
EnsureCleanDirectory(Parameters.NugetRoot);
@@ -134,97 +132,84 @@ partial class Build : NukeBuild
);
else
- DotNetBuild(Parameters.MSBuildSolution, c => c
+ DotNetBuild(c => c
+ .SetProjectFile(Parameters.MSBuildSolution)
.AddProperty("PackageVersion", Parameters.Version)
.SetConfiguration(Parameters.Configuration)
);
});
-
- void RunCoreTest(string project)
+
+ void RunCoreTest(string projectName)
{
- if(!project.EndsWith(".csproj"))
- project = System.IO.Path.Combine(project, System.IO.Path.GetFileName(project)+".csproj");
- Information("Running tests from " + project);
- XDocument xdoc;
- using (var s = File.OpenRead(project))
- xdoc = XDocument.Load(s);
-
- List frameworks = null;
- var targets = xdoc.Root.Descendants("TargetFrameworks").FirstOrDefault();
- if (targets != null)
- frameworks = targets.Value.Split(';').Where(f => !string.IsNullOrWhiteSpace(f)).ToList();
- else
- frameworks = new List {xdoc.Root.Descendants("TargetFramework").First().Value};
-
- foreach(var fw in frameworks)
+ Information($"Running tests from {projectName}");
+ var project = Solution.GetProject(projectName).NotNull("project != null");
+
+ foreach (var fw in project.GetTargetFrameworks())
{
if (fw.StartsWith("net4")
- && RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
+ && RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
&& Environment.GetEnvironmentVariable("FORCE_LINUX_TESTS") != "1")
{
- Information($"Skipping {fw} tests on Linux - https://github.com/mono/mono/issues/13969");
+ Information($"Skipping {projectName} ({fw}) tests on Linux - https://github.com/mono/mono/issues/13969");
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;
- });
+ Information($"Running for {projectName} ({fw}) ...");
+
+ DotNetTest(c => c
+ .SetProjectFile(project)
+ .SetConfiguration(Parameters.Configuration)
+ .SetFramework(fw)
+ .EnableNoBuild()
+ .EnableNoRestore()
+ .When(Parameters.PublishTestResults, c => c
+ .SetLogger("trx")
+ .SetResultsDirectory(Parameters.TestResultsRoot)));
}
}
Target RunCoreLibsTests => _ => _
- .OnlyWhen(() => !Parameters.SkipTests)
+ .OnlyWhenStatic(() => !Parameters.SkipTests)
.DependsOn(Compile)
.Executes(() =>
{
- RunCoreTest("./tests/Avalonia.Animation.UnitTests");
- RunCoreTest("./tests/Avalonia.Base.UnitTests");
- RunCoreTest("./tests/Avalonia.Controls.UnitTests");
- RunCoreTest("./tests/Avalonia.Controls.DataGrid.UnitTests");
- RunCoreTest("./tests/Avalonia.Input.UnitTests");
- RunCoreTest("./tests/Avalonia.Interactivity.UnitTests");
- RunCoreTest("./tests/Avalonia.Layout.UnitTests");
- RunCoreTest("./tests/Avalonia.Markup.UnitTests");
- RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests");
- RunCoreTest("./tests/Avalonia.Styling.UnitTests");
- RunCoreTest("./tests/Avalonia.Visuals.UnitTests");
- RunCoreTest("./tests/Avalonia.Skia.UnitTests");
- RunCoreTest("./tests/Avalonia.ReactiveUI.UnitTests");
+ RunCoreTest("Avalonia.Animation.UnitTests");
+ RunCoreTest("Avalonia.Base.UnitTests");
+ RunCoreTest("Avalonia.Controls.UnitTests");
+ RunCoreTest("Avalonia.Controls.DataGrid.UnitTests");
+ RunCoreTest("Avalonia.Input.UnitTests");
+ RunCoreTest("Avalonia.Interactivity.UnitTests");
+ RunCoreTest("Avalonia.Layout.UnitTests");
+ RunCoreTest("Avalonia.Markup.UnitTests");
+ RunCoreTest("Avalonia.Markup.Xaml.UnitTests");
+ RunCoreTest("Avalonia.Styling.UnitTests");
+ RunCoreTest("Avalonia.Visuals.UnitTests");
+ RunCoreTest("Avalonia.Skia.UnitTests");
+ RunCoreTest("Avalonia.ReactiveUI.UnitTests");
});
Target RunRenderTests => _ => _
- .OnlyWhen(() => !Parameters.SkipTests)
+ .OnlyWhenStatic(() => !Parameters.SkipTests)
.DependsOn(Compile)
.Executes(() =>
{
- RunCoreTest("./tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj");
+ RunCoreTest("Avalonia.Skia.RenderTests");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- RunCoreTest("./tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj");
+ RunCoreTest("Avalonia.Direct2D1.RenderTests");
});
-
+
Target RunDesignerTests => _ => _
- .OnlyWhen(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows)
+ .OnlyWhenStatic(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows)
.DependsOn(Compile)
.Executes(() =>
{
- RunCoreTest("./tests/Avalonia.DesignerSupport.Tests");
+ RunCoreTest("Avalonia.DesignerSupport.Tests");
});
[PackageExecutable("JetBrains.dotMemoryUnit", "dotMemoryUnit.exe")] readonly Tool DotMemoryUnit;
Target RunLeakTests => _ => _
- .OnlyWhen(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows)
+ .OnlyWhenStatic(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows)
.DependsOn(Compile)
.Executes(() =>
{
@@ -235,7 +220,7 @@ partial class Build : NukeBuild
});
Target ZipFiles => _ => _
- .After(CreateNugetPackages, Compile, RunCoreLibsTests, Package)
+ .After(CreateNugetPackages, Compile, RunCoreLibsTests, Package)
.Executes(() =>
{
var data = Parameters;
@@ -259,9 +244,10 @@ partial class Build : NukeBuild
MsBuildCommon(Parameters.MSBuildSolution, c => c
.AddTargets("Pack"));
else
- DotNetPack(Parameters.MSBuildSolution, c =>
- c.SetConfiguration(Parameters.Configuration)
- .AddProperty("PackageVersion", Parameters.Version));
+ DotNetPack(c => c
+ .SetProject(Parameters.MSBuildSolution)
+ .SetConfiguration(Parameters.Configuration)
+ .AddProperty("PackageVersion", Parameters.Version));
});
Target CreateNugetPackages => _ => _
@@ -274,32 +260,40 @@ partial class Build : NukeBuild
new NumergeNukeLogger()))
throw new Exception("Package merge failed");
});
-
+
Target RunTests => _ => _
.DependsOn(RunCoreLibsTests)
.DependsOn(RunRenderTests)
.DependsOn(RunDesignerTests)
.DependsOn(RunLeakTests);
-
+
Target Package => _ => _
.DependsOn(RunTests)
.DependsOn(CreateNugetPackages);
-
+
Target CiAzureLinux => _ => _
.DependsOn(RunTests);
-
+
Target CiAzureOSX => _ => _
.DependsOn(Package)
.DependsOn(ZipFiles);
-
+
Target CiAzureWindows => _ => _
.DependsOn(Package)
.DependsOn(ZipFiles);
-
+
public static int Main() =>
RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? Execute(x => x.Package)
: Execute(x => x.RunTests);
}
+
+public static class ToolSettingsExtensions
+{
+ public static T Apply(this T settings, Configure configurator)
+ {
+ return configurator != null ? configurator(settings) : settings;
+ }
+}
diff --git a/nukebuild/BuildParameters.cs b/nukebuild/BuildParameters.cs
index 65ba5e9756..149716b416 100644
--- a/nukebuild/BuildParameters.cs
+++ b/nukebuild/BuildParameters.cs
@@ -4,24 +4,21 @@ 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.CI.AzurePipelines;
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 Configuration { get; set; }
-
+
[Parameter("skip-tests")]
public bool SkipTests { get; set; }
-
+
[Parameter("force-nuget-version")]
public string ForceNugetVersion { get; set; }
-
+
public class BuildParameters
{
public string Configuration { get; }
@@ -79,15 +76,15 @@ public partial class Build
IsRunningOnUnix = Environment.OSVersion.Platform == PlatformID.Unix ||
Environment.OSVersion.Platform == PlatformID.MacOSX;
IsRunningOnWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
- IsRunningOnAzure = Host == HostType.TeamServices ||
+ IsRunningOnAzure = Host == HostType.AzurePipelines ||
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);
+ RepositoryName = AzurePipelines.Instance.RepositoryUri;
+ RepositoryBranch = AzurePipelines.Instance.SourceBranch;
+ IsPullRequest = AzurePipelines.Instance.PullRequestId.HasValue;
+ IsMainRepo = StringComparer.OrdinalIgnoreCase.Equals(MainRepo, AzurePipelines.Instance.RepositoryUri);
}
IsMainRepo =
StringComparer.OrdinalIgnoreCase.Equals(MainRepo,
diff --git a/nukebuild/Shims.cs b/nukebuild/Shims.cs
index 461d617643..1ac14bf622 100644
--- a/nukebuild/Shims.cs
+++ b/nukebuild/Shims.cs
@@ -19,9 +19,9 @@ public partial class Build
Logger.Info(info, args);
}
- private void Zip(PathConstruction.AbsolutePath target, params string[] paths) => Zip(target, paths.AsEnumerable());
+ private void Zip(AbsolutePath target, params string[] paths) => Zip(target, paths.AsEnumerable());
- private void Zip(PathConstruction.AbsolutePath target, IEnumerable paths)
+ private void Zip(AbsolutePath target, IEnumerable paths)
{
var targetPath = target.ToString();
bool finished = false, atLeastOneFileAdded = false;
@@ -38,7 +38,7 @@ public partial class Build
fileStream.CopyTo(entryStream);
atLeastOneFileAdded = true;
}
-
+
foreach (var path in paths)
{
if (Directory.Exists(path))
@@ -64,7 +64,7 @@ public partial class Build
finished = true;
}
- finally
+ finally
{
try
{
diff --git a/nukebuild/_build.csproj b/nukebuild/_build.csproj
index 2a736e4653..584c36d033 100644
--- a/nukebuild/_build.csproj
+++ b/nukebuild/_build.csproj
@@ -2,7 +2,7 @@
Exe
- netcoreapp2.0
+ netcoreapp3.1
false
False
@@ -10,7 +10,7 @@
-
+
@@ -20,11 +20,11 @@
-
+
-
+
diff --git a/packages/Avalonia/Avalonia.csproj b/packages/Avalonia/Avalonia.csproj
index 2c5a09bee7..9f7593b702 100644
--- a/packages/Avalonia/Avalonia.csproj
+++ b/packages/Avalonia/Avalonia.csproj
@@ -1,6 +1,6 @@
- netstandard2.0;net461;netcoreapp2.0
+ netstandard2.0;net461;netcoreapp3.1
Avalonia
@@ -20,8 +20,8 @@
Platform=$(Platform)" />
- <_PackageFiles Include="$(DesignerHostAppPath)/Avalonia.Designer.HostApp/bin/$(Configuration)/netcoreapp2.0/Avalonia.Designer.HostApp.dll">
- tools/netcoreapp2.0/designer
+ <_PackageFiles Include="$(DesignerHostAppPath)/Avalonia.Designer.HostApp/bin/$(Configuration)/netcoreapp3.1/Avalonia.Designer.HostApp.dll">
+ tools/netcoreapp3.1/designer
false
None
diff --git a/packages/Avalonia/Avalonia.props b/packages/Avalonia/Avalonia.props
index 6f21971d3d..99d53c1e03 100644
--- a/packages/Avalonia/Avalonia.props
+++ b/packages/Avalonia/Avalonia.props
@@ -1,6 +1,6 @@
- $(MSBuildThisFileDirectory)\..\tools\netcoreapp2.0\designer\Avalonia.Designer.HostApp.dll
+ $(MSBuildThisFileDirectory)\..\tools\netcoreapp3.1\designer\Avalonia.Designer.HostApp.dll
$(MSBuildThisFileDirectory)\..\tools\net461\designer\Avalonia.Designer.HostApp.exe
$(MSBuildThisFileDirectory)\..\tools\netstandard2.0\Avalonia.Build.Tasks.dll
false
diff --git a/readme.md b/readme.md
index 42b1e52205..40471b3b28 100644
--- a/readme.md
+++ b/readme.md
@@ -8,25 +8,21 @@
## About
-**Avalonia** is a WPF/UWP-inspired cross-platform XAML-based UI framework providing a flexible styling system and supporting a wide range of Operating Systems such as Windows (.NET Framework, .NET Core), Linux (via Xorg), macOS and with experimental support for Android and iOS.
+**Avalonia** is a cross-platform XAML-based UI framework providing a flexible styling system and supporting a wide range of Operating Systems such as Windows (.NET Framework, .NET Core), Linux (via Xorg), macOS.
-**Avalonia** is ready for **General-Purpose Desktop App Development**. However, there may be some bugs and [breaking changes](https://github.com/AvaloniaUI/Avalonia/wiki/Breaking-Changes) as we continue along into this project's development. To see the status of some of our features, please see our [Roadmap here](https://github.com/AvaloniaUI/Avalonia/issues/2239).
+**Avalonia** is ready for **General-Purpose Desktop App Development**. However, there may be some bugs and breaking changes as we continue along into this project's development.
-| Control catalog | Desktop platforms | Mobile platforms |
-|---|---|---|
-|
|
|
|
+To see the status of some of our features, please see our [Roadmap here](https://github.com/AvaloniaUI/Avalonia/issues/2239).
-[Awesome Avalonia](https://github.com/AvaloniaCommunity/awesome-avalonia) is curated list of awesome Avalonia UI tools, libraries, projects and resources.
+You can also see what [breaking changes](https://github.com/AvaloniaUI/Avalonia/issues/3538) we have planned and what our [past breaking changes](https://github.com/AvaloniaUI/Avalonia/wiki/Breaking-Changes) have been.
-## Getting Started
-
-Avalonia [Visual Studio Extension](https://marketplace.visualstudio.com/items?itemName=AvaloniaTeam.AvaloniaforVisualStudio) contains project and control templates that will help you get started. After installing it, open "New Project" dialog in Visual Studio, choose "Avalonia" in "Visual C#" section, select "Avalonia .NET Core Application" and press OK (screenshot). Now you can write code and markup that will work on multiple platforms!
+[Awesome Avalonia](https://github.com/AvaloniaCommunity/awesome-avalonia) is community-curated list of awesome Avalonia UI tools, libraries, projects and resources. Go and see what people are building with Avalonia!
-For those without Visual Studio, a starter guide for .NET Core CLI can be found [here](http://avaloniaui.net/docs/quickstart/create-new-project#net-core).
+## Getting Started
-If you need to develop Avalonia app with JetBrains Rider, go and *vote* on [this issue](https://youtrack.jetbrains.com/issue/RIDER-39247) in their tracker. JetBrains won't do things without their users telling them that they want the feature, so only **YOU** can make it happen.
+The Avalonia [Visual Studio Extension](https://marketplace.visualstudio.com/items?itemName=AvaloniaTeam.AvaloniaforVisualStudio) contains project and control templates that will help you get started, or you can use the .NET Core CLI. For a starer guide see our [documentation](http://avaloniaui.net/docs/quickstart/create-new-project).
-Avalonia is delivered via NuGet package manager. You can find the packages here: [stable(ish)](https://www.nuget.org/packages/Avalonia/)
+Avalonia is delivered via NuGet package manager. You can find the packages here: https://www.nuget.org/packages/Avalonia/
Use these commands in the Package Manager console to install Avalonia manually:
```
@@ -34,18 +30,17 @@ Install-Package Avalonia
Install-Package Avalonia.Desktop
```
-## Bleeding Edge Builds
+## JetBrains Rider
-or use nightly build feeds as described here:
-https://github.com/AvaloniaUI/Avalonia/wiki/Using-nightly-build-feed
+If you need to develop Avalonia app with JetBrains Rider, go and *vote* on [this issue](https://youtrack.jetbrains.com/issue/RIDER-39247) in their tracker. JetBrains won't do things without their users telling them that they want the feature, so only **YOU** can make it happen.
-## Documentation
+## Bleeding Edge Builds
-You can take a look at the [getting started page](http://avaloniaui.net/docs/quickstart/) for an overview of how to get started but probably the best thing to do for now is to already know a little bit about WPF/Silverlight/UWP/XAML and ask questions in our [Gitter room](https://gitter.im/AvaloniaUI/Avalonia).
+We also have a [nightly build](https://github.com/AvaloniaUI/Avalonia/wiki/Using-nightly-build-feed) which tracks the current state of master. Although these packages are less stable than the release on NuGet.org, you'll get all the latest features and bugfixes right away and many of our users actually prefer this feed!
-There's also a high-level [architecture document](http://avaloniaui.net/architecture/project-structure) that is currently a little bit out of date, and I've also started writing blog posts on Avalonia at http://grokys.github.io/.
+## Documentation
-Contributions for our docs are always welcome!
+Documentation can be found on our website at http://avaloniaui.net/docs/. We also have a [tutorial](http://avaloniaui.net/docs/tutorial/) over there for newcomers.
## Building and Using
@@ -60,14 +55,12 @@ Please read the [contribution guidelines](http://avaloniaui.net/contributing/con
This project exists thanks to all the people who contribute. [[Contribute](http://avaloniaui.net/contributing/contributing)].
-
### Backers
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/Avalonia#backer)]
-
### Sponsors
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/Avalonia#sponsor)]
diff --git a/samples/BindingDemo/BindingDemo.csproj b/samples/BindingDemo/BindingDemo.csproj
index a3f16dc222..ce33f42143 100644
--- a/samples/BindingDemo/BindingDemo.csproj
+++ b/samples/BindingDemo/BindingDemo.csproj
@@ -1,7 +1,7 @@
Exe
- netcoreapp2.0;net461
+ netcoreapp3.1
diff --git a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj
index 7919c3ac5a..772af9eacd 100644
--- a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj
+++ b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj
@@ -2,7 +2,7 @@
Exe
- netcoreapp2.0
+ netcoreapp3.1
true
diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml
index b95e01c5ae..f3f70719e3 100644
--- a/samples/ControlCatalog/MainView.xaml
+++ b/samples/ControlCatalog/MainView.xaml
@@ -59,10 +59,17 @@
-
+
+
+ No Decorations
+ Border Only
+ Full Decorations
+
+
Light
Dark
-
+
+
diff --git a/samples/ControlCatalog/MainView.xaml.cs b/samples/ControlCatalog/MainView.xaml.cs
index acb9bc5bc6..5f71b2ecd9 100644
--- a/samples/ControlCatalog/MainView.xaml.cs
+++ b/samples/ControlCatalog/MainView.xaml.cs
@@ -56,6 +56,20 @@ namespace ControlCatalog
}
};
Styles.Add(light);
+
+ var decorations = this.Find("Decorations");
+ decorations.SelectionChanged += (sender, e) =>
+ {
+ Window window = (Window)VisualRoot;
+ window.SystemDecorations = (SystemDecorations)decorations.SelectedIndex;
+ };
+ }
+
+ protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
+ {
+ base.OnAttachedToVisualTree(e);
+ var decorations = this.Find("Decorations");
+ decorations.SelectedIndex = (int)((Window)VisualRoot).SystemDecorations;
}
}
}
diff --git a/samples/ControlCatalog/MainWindow.xaml b/samples/ControlCatalog/MainWindow.xaml
index 248f94082d..d25de9c1f5 100644
--- a/samples/ControlCatalog/MainWindow.xaml
+++ b/samples/ControlCatalog/MainWindow.xaml
@@ -14,7 +14,7 @@
-
+
@@ -22,7 +22,9 @@
-
+
diff --git a/samples/ControlCatalog/MainWindow.xaml.cs b/samples/ControlCatalog/MainWindow.xaml.cs
index 38cbde9d92..b40fdb4a17 100644
--- a/samples/ControlCatalog/MainWindow.xaml.cs
+++ b/samples/ControlCatalog/MainWindow.xaml.cs
@@ -1,13 +1,11 @@
+using System;
+using System.Runtime.InteropServices;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Notifications;
-using Avalonia.Controls.Primitives;
+using Avalonia.Input;
using Avalonia.Markup.Xaml;
-using Avalonia.Threading;
using ControlCatalog.ViewModels;
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
namespace ControlCatalog
{
@@ -35,6 +33,12 @@ namespace ControlCatalog
mainMenu.AttachedToVisualTree += MenuAttached;
}
+ public static string MenuQuitHeader => RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "Quit Avalonia" : "E_xit";
+
+ public static KeyGesture MenuQuitGesture => RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ?
+ new KeyGesture(Key.Q, KeyModifiers.Meta) :
+ new KeyGesture(Key.F4, KeyModifiers.Alt);
+
public void MenuAttached(object sender, VisualTreeAttachmentEventArgs e)
{
if (NativeMenu.GetIsNativeMenuExported(this) && sender is Menu mainMenu)
diff --git a/samples/ControlCatalog/Pages/ImagePage.xaml b/samples/ControlCatalog/Pages/ImagePage.xaml
index 9b8f8af765..f61931ed72 100644
--- a/samples/ControlCatalog/Pages/ImagePage.xaml
+++ b/samples/ControlCatalog/Pages/ImagePage.xaml
@@ -7,7 +7,7 @@
Displays an image
-
+
Bitmap
@@ -22,6 +22,23 @@
+ Crop
+
+ None
+ Center
+ TopLeft
+ TopRight
+ BottomLeft
+ BottomRight
+
+
+
+
+
+
+
+
+
Drawing
None
diff --git a/samples/ControlCatalog/Pages/ImagePage.xaml.cs b/samples/ControlCatalog/Pages/ImagePage.xaml.cs
index bbe89d1dfd..d8f4d6d5a2 100644
--- a/samples/ControlCatalog/Pages/ImagePage.xaml.cs
+++ b/samples/ControlCatalog/Pages/ImagePage.xaml.cs
@@ -1,6 +1,10 @@
+using System;
+using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
+using Avalonia.Media.Imaging;
+using Avalonia.Platform;
namespace ControlCatalog.Pages
{
@@ -8,12 +12,14 @@ namespace ControlCatalog.Pages
{
private readonly Image _bitmapImage;
private readonly Image _drawingImage;
+ private readonly Image _croppedImage;
public ImagePage()
{
InitializeComponent();
_bitmapImage = this.FindControl("bitmapImage");
_drawingImage = this.FindControl("drawingImage");
+ _croppedImage = this.FindControl("croppedImage");
}
private void InitializeComponent()
@@ -38,5 +44,32 @@ namespace ControlCatalog.Pages
_drawingImage.Stretch = (Stretch)comboxBox.SelectedIndex;
}
}
+
+ public void BitmapCropChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (_croppedImage != null)
+ {
+ var comboxBox = (ComboBox)sender;
+ var croppedBitmap = _croppedImage.Source as CroppedBitmap;
+ croppedBitmap.SourceRect = GetCropRect(comboxBox.SelectedIndex);
+ }
+ }
+
+ private PixelRect GetCropRect(int index)
+ {
+ var bitmapWidth = 640;
+ var bitmapHeight = 426;
+ var cropSize = new PixelSize(320, 240);
+ return index switch
+ {
+ 1 => new PixelRect(new PixelPoint((bitmapWidth - cropSize.Width) / 2, (bitmapHeight - cropSize.Width) / 2), cropSize),
+ 2 => new PixelRect(new PixelPoint(0, 0), cropSize),
+ 3 => new PixelRect(new PixelPoint(bitmapWidth - cropSize.Width, 0), cropSize),
+ 4 => new PixelRect(new PixelPoint(0, bitmapHeight - cropSize.Height), cropSize),
+ 5 => new PixelRect(new PixelPoint(bitmapWidth - cropSize.Width, bitmapHeight - cropSize.Height), cropSize),
+ _ => PixelRect.Empty
+ };
+
+ }
}
}
diff --git a/samples/ControlCatalog/Pages/MenuPage.xaml b/samples/ControlCatalog/Pages/MenuPage.xaml
index 868f0df6ad..de9ea34e80 100644
--- a/samples/ControlCatalog/Pages/MenuPage.xaml
+++ b/samples/ControlCatalog/Pages/MenuPage.xaml
@@ -16,13 +16,13 @@
Defined in XAML