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/build/CoreLibraries.props b/build/CoreLibraries.props
index 3923bdeeda..d61268173d 100644
--- a/build/CoreLibraries.props
+++ b/build/CoreLibraries.props
@@ -4,7 +4,6 @@
-
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/platformthreading.mm b/native/Avalonia.Native/src/OSX/platformthreading.mm
index e7abedae51..ed00f8c5e1 100644
--- a/native/Avalonia.Native/src/OSX/platformthreading.mm
+++ b/native/Avalonia.Native/src/OSX/platformthreading.mm
@@ -157,11 +157,14 @@ NSArray* _modes;
-(void) perform
{
+ ComPtr cb;
@synchronized (self) {
_signaled = false;
- if(_parent != NULL && _parent->SignaledCallback != NULL)
- _parent->SignaledCallback->Signaled(0, false);
+ if(_parent != NULL)
+ cb = _parent->SignaledCallback;
}
+ if(cb != nullptr)
+ cb->Signaled(0, false);
}
-(void) setParent:(PlatformThreadingInterface *)parent
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/samples/BindingDemo/BindingDemo.csproj b/samples/BindingDemo/BindingDemo.csproj
index 3005fdbc51..ce33f42143 100644
--- a/samples/BindingDemo/BindingDemo.csproj
+++ b/samples/BindingDemo/BindingDemo.csproj
@@ -1,9 +1,10 @@
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/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj
index 4c2769bcc4..11c0a4fa68 100644
--- a/samples/ControlCatalog/ControlCatalog.csproj
+++ b/samples/ControlCatalog/ControlCatalog.csproj
@@ -21,6 +21,7 @@
+
diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml
index cbe2c62890..f3f70719e3 100644
--- a/samples/ControlCatalog/MainView.xaml
+++ b/samples/ControlCatalog/MainView.xaml
@@ -54,14 +54,22 @@
+
-
+
+
+ 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