From f14aac365bf6bc12b5d7133c22ce0ddd839fc0f2 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Fri, 15 Feb 2019 14:48:10 +0300 Subject: [PATCH 001/234] WIP --- .gitmodules | 3 + .../Pages/ButtonSpinnerPage.xaml.cs | 2 +- .../UsableDuringInitializationAttribute.cs | 10 ++ .../Controls/NameScopeExtensions.cs | 3 +- src/Avalonia.Visuals/Visual.cs | 2 + .../Avalonia.Markup.Xaml.csproj | 18 ++ .../AvaloniaTypeConverters.cs | 1 + .../AvaloniaXamlLoader.cs | 15 +- .../AvaloniaPropertyTypeConverter.cs | 4 +- .../Converters/BitmapTypeConverter.cs | 4 +- .../Converters/FontFamilyTypeConverter.cs | 2 +- .../Converters/IconTypeConverter.cs | 2 +- src/Markup/Avalonia.Markup.Xaml/Extensions.cs | 47 +++++ .../MarkupExtensions/BindingExtension.cs | 11 +- .../DynamicResourceExtension.cs | 16 +- .../MarkupExtensions/ResourceInclude.cs | 2 +- .../MarkupExtensions/StyleIncludeExtension.cs | 5 +- .../PortableXaml/TypeDescriptorExtensions.cs | 4 +- .../XamlIl/AvaloniaXamlIlRuntimeCompiler.cs | 160 ++++++++++++++++++ .../AvaloniaPropertyDescriptorEmitter.cs | 21 +++ .../AvaloniaXamlIlCompiler.cs | 61 +++++++ .../AvaloniaXamlIlLanguage.cs | 153 +++++++++++++++++ .../XamlIl/CompilerExtensions/README.md | 4 + .../Transformers/AddNameScopeRegistration.cs | 79 +++++++++ .../IgnoredDirectivesTransformer.cs | 27 +++ .../KnownPseudoMarkupExtensionsTransformer.cs | 26 +++ .../Transformers/XNameTransformer.cs | 33 ++++ .../IAvaloniaXamlIlParentStackProvider.cs | 9 + ...valoniaXamlIlXmlNamespaceInfoProviderV1.cs | 15 ++ .../XamlIl/Runtime/XamlIlRuntimeHelpers.cs | 121 +++++++++++++ .../Avalonia.Markup.Xaml/XamlIl/xamlil.github | 1 + 31 files changed, 827 insertions(+), 34 deletions(-) create mode 100644 src/Avalonia.Base/Metadata/UsableDuringInitializationAttribute.cs create mode 100644 src/Markup/Avalonia.Markup.Xaml/Extensions.cs create mode 100644 src/Markup/Avalonia.Markup.Xaml/XamlIl/AvaloniaXamlIlRuntimeCompiler.cs create mode 100644 src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaPropertyDescriptorEmitter.cs create mode 100644 src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompiler.cs create mode 100644 src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlLanguage.cs create mode 100644 src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/README.md create mode 100644 src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AddNameScopeRegistration.cs create mode 100644 src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/IgnoredDirectivesTransformer.cs create mode 100644 src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/KnownPseudoMarkupExtensionsTransformer.cs create mode 100644 src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/XNameTransformer.cs create mode 100644 src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/IAvaloniaXamlIlParentStackProvider.cs create mode 100644 src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/IAvaloniaXamlIlXmlNamespaceInfoProviderV1.cs create mode 100644 src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs create mode 160000 src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github diff --git a/.gitmodules b/.gitmodules index 22c56307b0..22a241f120 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "nukebuild/Numerge"] path = nukebuild/Numerge url = https://github.com/kekekeks/Numerge.git +[submodule "src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github"] + path = src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github + url = https://github.com/kekekeks/XamlIl.git diff --git a/samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml.cs b/samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml.cs index 1f753ab3ea..c5042baccb 100644 --- a/samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml.cs +++ b/samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml.cs @@ -18,7 +18,7 @@ namespace ControlCatalog.Pages AvaloniaXamlLoader.Load(this); } - private void OnSpin(object sender, SpinEventArgs e) + public void OnSpin(object sender, SpinEventArgs e) { var spinner = (ButtonSpinner)sender; var txtBox = (TextBlock)spinner.Content; diff --git a/src/Avalonia.Base/Metadata/UsableDuringInitializationAttribute.cs b/src/Avalonia.Base/Metadata/UsableDuringInitializationAttribute.cs new file mode 100644 index 0000000000..753a96b9ce --- /dev/null +++ b/src/Avalonia.Base/Metadata/UsableDuringInitializationAttribute.cs @@ -0,0 +1,10 @@ +using System; + +namespace Avalonia.Metadata +{ + [AttributeUsage(AttributeTargets.Class)] + public class UsableDuringInitializationAttribute : Attribute + { + + } +} diff --git a/src/Avalonia.Styling/Controls/NameScopeExtensions.cs b/src/Avalonia.Styling/Controls/NameScopeExtensions.cs index 491e4d71a7..991a97a614 100644 --- a/src/Avalonia.Styling/Controls/NameScopeExtensions.cs +++ b/src/Avalonia.Styling/Controls/NameScopeExtensions.cs @@ -71,10 +71,11 @@ namespace Avalonia.Controls { Contract.Requires(control != null); - return control.GetSelfAndLogicalAncestors() + var scope = control.GetSelfAndLogicalAncestors() .OfType() .Select(x => (x as INameScope) ?? NameScope.GetNameScope(x)) .FirstOrDefault(x => x != null); + return scope; } } } diff --git a/src/Avalonia.Visuals/Visual.cs b/src/Avalonia.Visuals/Visual.cs index f26c21d1b6..3360ba84c1 100644 --- a/src/Avalonia.Visuals/Visual.cs +++ b/src/Avalonia.Visuals/Visual.cs @@ -9,6 +9,7 @@ using Avalonia.Collections; using Avalonia.Data; using Avalonia.Logging; using Avalonia.Media; +using Avalonia.Metadata; using Avalonia.Rendering; using Avalonia.VisualTree; @@ -23,6 +24,7 @@ namespace Avalonia /// to render the control. To traverse the visual tree, use the /// extension methods defined in . /// + [UsableDuringInitialization] public class Visual : StyledElement, IVisual { /// diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj index 38d207a31d..4603d31fae 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj +++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj @@ -15,6 +15,7 @@ + @@ -50,8 +51,21 @@ + + + + + + + + + + + + + @@ -63,6 +77,10 @@ + + + + diff --git a/src/Markup/Avalonia.Markup.Xaml/AvaloniaTypeConverters.cs b/src/Markup/Avalonia.Markup.Xaml/AvaloniaTypeConverters.cs index c30822aacb..2b6572e1a2 100644 --- a/src/Markup/Avalonia.Markup.Xaml/AvaloniaTypeConverters.cs +++ b/src/Markup/Avalonia.Markup.Xaml/AvaloniaTypeConverters.cs @@ -29,6 +29,7 @@ namespace Avalonia.Markup.Xaml /// public static class AvaloniaTypeConverters { + // When adding item to that list make sure to modify AvaloniaXamlIlLanguage private static Dictionary _converters = new Dictionary() { { typeof(AvaloniaList<>), typeof(AvaloniaListConverter<>) }, diff --git a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs index a825deeae3..dd413ee10f 100644 --- a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs +++ b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs @@ -13,6 +13,7 @@ using System.Reflection; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.Text; +using Avalonia.Markup.Xaml.XamlIl; namespace Avalonia.Markup.Xaml { @@ -23,6 +24,8 @@ namespace Avalonia.Markup.Xaml { private readonly AvaloniaXamlSchemaContext _context = GetContext(); + public bool EnforceCompilerForRuntimeXaml { get; set; } = true; + public bool IsDesignMode { get => _context.IsDesignMode; @@ -137,13 +140,13 @@ namespace Avalonia.Markup.Xaml using (var stream = asset.stream) { var absoluteUri = uri.IsAbsoluteUri ? uri : new Uri(baseUri, uri); - try + //try { return Load(stream, asset.assembly, rootInstance, absoluteUri); } - catch (Exception e) + //catch (Exception e) { - throw new XamlLoadException("Error loading xaml at " + absoluteUri + ": " + e.Message, e); + //throw new XamlLoadException("Error loading xaml at " + absoluteUri + ": " + e.Message, e); } } } @@ -179,6 +182,12 @@ namespace Avalonia.Markup.Xaml /// The loaded object. public object Load(Stream stream, Assembly localAssembly, object rootInstance = null, Uri uri = null) { + if (EnforceCompilerForRuntimeXaml) + { + return AvaloniaXamlIlRuntimeCompiler.Load(stream, localAssembly, rootInstance, uri); + } + + var readerSettings = new XamlXmlReaderSettings() { BaseUri = uri, diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs index 8a0ba64582..18a7fe9ab6 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs @@ -28,8 +28,8 @@ namespace Avalonia.Markup.Xaml.Converters var parser = new PropertyParser(); var (ns, owner, propertyName) = parser.Parse(new CharacterReader(((string)value).AsSpan())); var ownerType = TryResolveOwnerByName(context, ns, owner); - var targetType = context.GetFirstAmbientValue()?.TargetType ?? - context.GetFirstAmbientValue + + + + + + + + + + + + + + + + + + + From 9ec7c7ce4bf09825ea0682961b1277b0c6ed5457 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Thu, 11 Apr 2019 00:15:30 +0100 Subject: [PATCH 039/234] sensible close delay. --- src/Avalonia.Controls/Notifications/NotificationManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Controls/Notifications/NotificationManager.cs b/src/Avalonia.Controls/Notifications/NotificationManager.cs index 8e6ad0a90b..236d67a35f 100644 --- a/src/Avalonia.Controls/Notifications/NotificationManager.cs +++ b/src/Avalonia.Controls/Notifications/NotificationManager.cs @@ -26,7 +26,7 @@ namespace Avalonia.Controls.Notifications } if (expirationTime == null) - expirationTime = TimeSpan.FromSeconds(25); + expirationTime = TimeSpan.FromSeconds(5); if (areaName == string.Empty && _window == null) { From 1bb3156950a3caa3af8395a8ab5a36cba8e7bd47 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Thu, 11 Apr 2019 17:11:09 +0200 Subject: [PATCH 040/234] Introduce StartupEventArgs and ExitEventArgs --- samples/BindingDemo/App.xaml.cs | 3 +- samples/ControlCatalog.NetCore/Program.cs | 13 ++---- samples/ControlCatalog/App.xaml.cs | 10 ++--- samples/PlatformSanityChecks/App.xaml.cs | 3 +- samples/Previewer/App.xaml.cs | 5 ++- samples/RenderDemo/App.xaml.cs | 3 +- samples/VirtualizationDemo/App.xaml.cs | 3 +- .../interop/Direct3DInteropSample/App.paml.cs | 3 +- src/Avalonia.Controls/AppBuilderBase.cs | 1 - src/Avalonia.Controls/Application.cs | 43 +++++++++---------- .../IApplicationLifecycle.cs | 12 ++++-- .../Controls/ExitEventArgs.cs | 12 ++++++ .../Controls/StartupEventArgs.cs | 30 +++++++++++++ .../App.xaml.cs | 8 +--- 14 files changed, 93 insertions(+), 56 deletions(-) create mode 100644 src/Avalonia.Styling/Controls/ExitEventArgs.cs create mode 100644 src/Avalonia.Styling/Controls/StartupEventArgs.cs diff --git a/samples/BindingDemo/App.xaml.cs b/samples/BindingDemo/App.xaml.cs index 01c52a2a49..d95241372f 100644 --- a/samples/BindingDemo/App.xaml.cs +++ b/samples/BindingDemo/App.xaml.cs @@ -3,13 +3,12 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Logging.Serilog; using Avalonia.Markup.Xaml; -using Serilog; namespace BindingDemo { public class App : Application { - public override void Initialize() + protected override void OnStartup(StartupEventArgs e) { AvaloniaXamlLoader.Load(this); } diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs index ee4c3fe350..42be488569 100644 --- a/samples/ControlCatalog.NetCore/Program.cs +++ b/samples/ControlCatalog.NetCore/Program.cs @@ -3,13 +3,11 @@ using System.Diagnostics; using System.Linq; using System.Threading; using Avalonia; -using Avalonia.Skia; namespace ControlCatalog.NetCore { static class Program - { - + { static void Main(string[] args) { Thread.CurrentThread.TrySetApartmentState(ApartmentState.STA); @@ -28,15 +26,10 @@ namespace ControlCatalog.NetCore AppBuilder.Configure().InitializeWithLinuxFramebuffer(tl => { tl.Content = new MainView(); - System.Threading.ThreadPool.QueueUserWorkItem(_ => ConsoleSilencer()); + ThreadPool.QueueUserWorkItem(_ => ConsoleSilencer()); }); else - BuildAvaloniaApp().Start(AppMain, args); - } - - static void AppMain(Application app, string[] args) - { - app.Run(); + BuildAvaloniaApp().Start(); } /// diff --git a/samples/ControlCatalog/App.xaml.cs b/samples/ControlCatalog/App.xaml.cs index 6fbcecfd6e..1f466d9f91 100644 --- a/samples/ControlCatalog/App.xaml.cs +++ b/samples/ControlCatalog/App.xaml.cs @@ -1,18 +1,16 @@ using Avalonia; +using Avalonia.Controls; using Avalonia.Markup.Xaml; namespace ControlCatalog { public class App : Application { - public override void Initialize() + protected override void OnStartup(StartupEventArgs e) { - AvaloniaXamlLoader.Load(this); - } + base.OnStartup(e); - protected override void OnStartup() - { - base.OnStartup(); + AvaloniaXamlLoader.Load(this); var mainWindow = new MainWindow(); diff --git a/samples/PlatformSanityChecks/App.xaml.cs b/samples/PlatformSanityChecks/App.xaml.cs index 508fc1e34b..b8f8350156 100644 --- a/samples/PlatformSanityChecks/App.xaml.cs +++ b/samples/PlatformSanityChecks/App.xaml.cs @@ -1,11 +1,12 @@ using Avalonia; +using Avalonia.Controls; using Avalonia.Markup.Xaml; namespace PlatformSanityChecks { public class App : Application { - public override void Initialize() + protected override void OnStartup(StartupEventArgs e) { AvaloniaXamlLoader.Load(this); } diff --git a/samples/Previewer/App.xaml.cs b/samples/Previewer/App.xaml.cs index fffa987a27..0fc42583a5 100644 --- a/samples/Previewer/App.xaml.cs +++ b/samples/Previewer/App.xaml.cs @@ -1,14 +1,15 @@ using Avalonia; +using Avalonia.Controls; using Avalonia.Markup.Xaml; namespace Previewer { public class App : Application { - public override void Initialize() + protected override void OnStartup(StartupEventArgs e) { AvaloniaXamlLoader.Load(this); } } -} \ No newline at end of file +} diff --git a/samples/RenderDemo/App.xaml.cs b/samples/RenderDemo/App.xaml.cs index 0f627961e6..4ac844983b 100644 --- a/samples/RenderDemo/App.xaml.cs +++ b/samples/RenderDemo/App.xaml.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using Avalonia; +using Avalonia.Controls; using Avalonia.Logging.Serilog; using Avalonia.Markup.Xaml; @@ -9,7 +10,7 @@ namespace RenderDemo { public class App : Application { - public override void Initialize() + protected override void OnStartup(StartupEventArgs e) { AvaloniaXamlLoader.Load(this); } diff --git a/samples/VirtualizationDemo/App.xaml.cs b/samples/VirtualizationDemo/App.xaml.cs index b220807443..787bbf8d11 100644 --- a/samples/VirtualizationDemo/App.xaml.cs +++ b/samples/VirtualizationDemo/App.xaml.cs @@ -2,13 +2,14 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using Avalonia; +using Avalonia.Controls; using Avalonia.Markup.Xaml; namespace VirtualizationDemo { public class App : Application { - public override void Initialize() + protected override void OnStartup(StartupEventArgs e) { AvaloniaXamlLoader.Load(this); } diff --git a/samples/interop/Direct3DInteropSample/App.paml.cs b/samples/interop/Direct3DInteropSample/App.paml.cs index 1b6d5fd39c..b08c02509c 100644 --- a/samples/interop/Direct3DInteropSample/App.paml.cs +++ b/samples/interop/Direct3DInteropSample/App.paml.cs @@ -1,11 +1,12 @@ using Avalonia; +using Avalonia.Controls; using Avalonia.Markup.Xaml; namespace Direct3DInteropSample { public class App : Application { - public override void Initialize() + protected override void OnStartup(StartupEventArgs e) { AvaloniaXamlLoader.Load(this); } diff --git a/src/Avalonia.Controls/AppBuilderBase.cs b/src/Avalonia.Controls/AppBuilderBase.cs index cda49a12b3..568b04c78c 100644 --- a/src/Avalonia.Controls/AppBuilderBase.cs +++ b/src/Avalonia.Controls/AppBuilderBase.cs @@ -292,7 +292,6 @@ namespace Avalonia.Controls WindowingSubsystemInitializer(); RenderingSubsystemInitializer(); Instance.RegisterServices(); - Instance.Initialize(); AfterSetupCallback(Self); } } diff --git a/src/Avalonia.Controls/Application.cs b/src/Avalonia.Controls/Application.cs index 383b994e70..2893505655 100644 --- a/src/Avalonia.Controls/Application.cs +++ b/src/Avalonia.Controls/Application.cs @@ -55,10 +55,10 @@ namespace Avalonia } /// - public event EventHandler Startup; + public event EventHandler Startup; /// - public event EventHandler Exit; + public event EventHandler Exit; /// public event EventHandler ResourcesChanged; @@ -199,14 +199,7 @@ namespace Avalonia /// /// true if this instance is shutting down; otherwise, false. /// - internal bool IsShuttingDown { get; set; } - - /// - /// Initializes the application by loading XAML etc. - /// - public virtual void Initialize() - { - } + internal bool IsShuttingDown { get; private set; } public void Run() { @@ -217,7 +210,7 @@ namespace Avalonia _mainLoopCancellationTokenSource = new CancellationTokenSource(); - Dispatcher.UIThread.Post(OnStartup, DispatcherPriority.Send); + Dispatcher.UIThread.Post(() => OnStartup(new StartupEventArgs()), DispatcherPriority.Send); Run(_mainLoopCancellationTokenSource.Token); } @@ -233,7 +226,7 @@ namespace Avalonia // Make sure we call OnExit in case an error happened and OnExit() wasn't called explicitly if (!IsShuttingDown) { - OnExit(); + OnExit(new ExitEventArgs()); } } @@ -248,10 +241,10 @@ namespace Avalonia throw new Exception("Run should only called once"); } - closable.Closed += (s, e) => OnExit(); - _mainLoopCancellationTokenSource = new CancellationTokenSource(); + closable.Closed += (s, e) => _mainLoopCancellationTokenSource?.Cancel(); + Run(_mainLoopCancellationTokenSource.Token); } @@ -284,26 +277,34 @@ namespace Avalonia Run(_mainLoopCancellationTokenSource.Token); } - protected virtual void OnStartup() + protected virtual void OnStartup(StartupEventArgs e) { - Startup?.Invoke(this, EventArgs.Empty); + Startup?.Invoke(this, e); } - protected virtual void OnExit() + protected virtual void OnExit(ExitEventArgs e) { - Exit?.Invoke(this, EventArgs.Empty); + Exit?.Invoke(this, e); + + Environment.ExitCode = e.ApplicationExitCode; } /// public void Shutdown() + { + Shutdown(0); + } + + /// + public void Shutdown(int exitCode) { IsShuttingDown = true; Windows.Clear(); - _mainLoopCancellationTokenSource?.Cancel(); + OnExit(new ExitEventArgs { ApplicationExitCode = exitCode }); - OnExit(); + _mainLoopCancellationTokenSource?.Cancel(); } /// @@ -314,8 +315,6 @@ namespace Avalonia Styles.TryGetResource(key, out value); } - - /// /// Register's the services needed by Avalonia. /// diff --git a/src/Avalonia.Controls/IApplicationLifecycle.cs b/src/Avalonia.Controls/IApplicationLifecycle.cs index c088ceb0eb..958c448d3e 100644 --- a/src/Avalonia.Controls/IApplicationLifecycle.cs +++ b/src/Avalonia.Controls/IApplicationLifecycle.cs @@ -10,16 +10,22 @@ namespace Avalonia.Controls /// /// Sent when the application is starting up. /// - event EventHandler Startup; + event EventHandler Startup; /// /// Sent when the application is exiting. /// - event EventHandler Exit; + event EventHandler Exit; /// - /// Exits the application. + /// Shuts down an application that returns the specified exit code to the operating system. /// void Shutdown(); + + /// + /// Shuts down an application that returns the specified exit code to the operating system. + /// + /// An integer exit code for an application. The default exit code is 0. + void Shutdown(int exitCode); } } diff --git a/src/Avalonia.Styling/Controls/ExitEventArgs.cs b/src/Avalonia.Styling/Controls/ExitEventArgs.cs new file mode 100644 index 0000000000..1a4ee15f17 --- /dev/null +++ b/src/Avalonia.Styling/Controls/ExitEventArgs.cs @@ -0,0 +1,12 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Controls +{ + public class ExitEventArgs : EventArgs + { + public int ApplicationExitCode { get; set; } + } +} diff --git a/src/Avalonia.Styling/Controls/StartupEventArgs.cs b/src/Avalonia.Styling/Controls/StartupEventArgs.cs new file mode 100644 index 0000000000..8b66ce0dc2 --- /dev/null +++ b/src/Avalonia.Styling/Controls/StartupEventArgs.cs @@ -0,0 +1,30 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Avalonia.Controls +{ + public class StartupEventArgs : EventArgs + { + private string[] _args; + + public IReadOnlyList Args => _args ?? (_args = GetArgs()); + + private static string[] GetArgs() + { + try + { + var args = Environment.GetCommandLineArgs(); + + return args.Length > 1 ? args.Skip(1).ToArray() : new string[0]; + } + catch (NotSupportedException) + { + return new string[0]; + } + } + } +} diff --git a/tests/Avalonia.DesignerSupport.TestApp/App.xaml.cs b/tests/Avalonia.DesignerSupport.TestApp/App.xaml.cs index 653a51232b..e2fc6ab7a2 100644 --- a/tests/Avalonia.DesignerSupport.TestApp/App.xaml.cs +++ b/tests/Avalonia.DesignerSupport.TestApp/App.xaml.cs @@ -1,15 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Avalonia.Controls; using Avalonia.Markup.Xaml; namespace Avalonia.DesignerSupport.TestApp { public class App : Application { - public override void Initialize() + protected override void OnStartup(StartupEventArgs e) { AvaloniaXamlLoader.Load(this); } From baa7c9da69b232b13386bfb414ff537a744f4a81 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Thu, 11 Apr 2019 17:49:56 +0200 Subject: [PATCH 041/234] Makes ScrollBar Thumb stylable --- src/Avalonia.Themes.Default/ScrollBar.xaml | 34 +++++++++++++++------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/Avalonia.Themes.Default/ScrollBar.xaml b/src/Avalonia.Themes.Default/ScrollBar.xaml index 2cb8ce2d24..edd678ed56 100644 --- a/src/Avalonia.Themes.Default/ScrollBar.xaml +++ b/src/Avalonia.Themes.Default/ScrollBar.xaml @@ -31,11 +31,18 @@ Focusable="False"/> - - - - - + + + - - - - - + + + Date: Fri, 12 Apr 2019 00:43:14 +0800 Subject: [PATCH 042/234] Add some bubble notification animations + make IsClosing a direct property. --- .../Notifications/Notification.cs | 17 +++++++++-- .../NotificationArea.xaml | 28 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Controls/Notifications/Notification.cs b/src/Avalonia.Controls/Notifications/Notification.cs index c7cd176513..fbf28c07e5 100644 --- a/src/Avalonia.Controls/Notifications/Notification.cs +++ b/src/Avalonia.Controls/Notifications/Notification.cs @@ -2,13 +2,14 @@ using System.Reactive.Linq; using System.Threading.Tasks; using Avalonia.Controls.Primitives; +using Avalonia.Data; using Avalonia.Interactivity; namespace Avalonia.Controls.Notifications { public class Notification : ContentControl { - private TimeSpan _closingAnimationTime = TimeSpan.Zero; + private TimeSpan _closingAnimationTime = TimeSpan.FromSeconds(0.25); static Notification() { @@ -42,7 +43,19 @@ namespace Avalonia.Controls.Notifications }); } - public bool IsClosing { get; set; } + private bool _isClosing; + + /// + /// Determines if the notification is already closing. + /// + public bool IsClosing + { + get { return _isClosing; } + private set { SetAndRaise(IsClosingProperty, ref _isClosing, value); } + } + + public static readonly DirectProperty IsClosingProperty = + AvaloniaProperty.RegisterDirect(nameof(IsClosing), o => o.IsClosing); /// /// Defines the event. diff --git a/src/Avalonia.Themes.Default/NotificationArea.xaml b/src/Avalonia.Themes.Default/NotificationArea.xaml index 3d3f4b8c20..2b2dd2a797 100644 --- a/src/Avalonia.Themes.Default/NotificationArea.xaml +++ b/src/Avalonia.Themes.Default/NotificationArea.xaml @@ -28,6 +28,34 @@ + + + + + + + + + + + + + + + + From 1b869ff27b68901d8db4b7235e199b7f00355581 Mon Sep 17 00:00:00 2001 From: Dariusz Komosinski Date: Fri, 12 Apr 2019 11:32:41 +0200 Subject: [PATCH 045/234] Get rid of not needed interfaces. --- .../Platform/IEllipseGeometryImpl.cs | 12 ------------ src/Avalonia.Visuals/Platform/ILineGeometryImpl.cs | 12 ------------ .../Platform/IPlatformRenderInterface.cs | 12 ++++++------ .../Platform/IRectangleGeometryImpl.cs | 12 ------------ src/Skia/Avalonia.Skia/EllipseGeometryImpl.cs | 3 +-- src/Skia/Avalonia.Skia/LineGeometryImpl.cs | 3 +-- src/Skia/Avalonia.Skia/PlatformRenderInterface.cs | 6 +++--- src/Skia/Avalonia.Skia/RectangleGeometryImpl.cs | 3 +-- src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs | 6 +++--- .../Avalonia.Direct2D1/Media/EllipseGeometryImpl.cs | 3 +-- .../Avalonia.Direct2D1/Media/LineGeometryImpl.cs | 3 +-- .../Media/RectangleGeometryImpl.cs | 3 +-- .../MockPlatformRenderInterface.cs | 12 ++++++------ .../VisualTree/MockRenderInterface.cs | 6 +++--- 14 files changed, 27 insertions(+), 69 deletions(-) delete mode 100644 src/Avalonia.Visuals/Platform/IEllipseGeometryImpl.cs delete mode 100644 src/Avalonia.Visuals/Platform/ILineGeometryImpl.cs delete mode 100644 src/Avalonia.Visuals/Platform/IRectangleGeometryImpl.cs diff --git a/src/Avalonia.Visuals/Platform/IEllipseGeometryImpl.cs b/src/Avalonia.Visuals/Platform/IEllipseGeometryImpl.cs deleted file mode 100644 index 982cf286a3..0000000000 --- a/src/Avalonia.Visuals/Platform/IEllipseGeometryImpl.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -namespace Avalonia.Platform -{ - /// - /// Defines the platform-specific interface for a . - /// - public interface IEllipseGeometryImpl : IGeometryImpl - { - } -} diff --git a/src/Avalonia.Visuals/Platform/ILineGeometryImpl.cs b/src/Avalonia.Visuals/Platform/ILineGeometryImpl.cs deleted file mode 100644 index a8aa46fb13..0000000000 --- a/src/Avalonia.Visuals/Platform/ILineGeometryImpl.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -namespace Avalonia.Platform -{ - /// - /// Defines the platform-specific interface for a . - /// - public interface ILineGeometryImpl : IGeometryImpl - { - } -} diff --git a/src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs b/src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs index 45ce8f5874..87db9251e1 100644 --- a/src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs +++ b/src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs @@ -40,23 +40,23 @@ namespace Avalonia.Platform /// Creates an ellipse geometry implementation. /// /// The bounds of the ellipse. - /// An . - IEllipseGeometryImpl CreateEllipseGeometry(Rect rect); + /// An ellipse geometry.. + IGeometryImpl CreateEllipseGeometry(Rect rect); /// /// Creates a line geometry implementation. /// /// The start of the line. /// The end of the line. - /// An . - ILineGeometryImpl CreateLineGeometry(Point p1, Point p2); + /// A line geometry. + IGeometryImpl CreateLineGeometry(Point p1, Point p2); /// /// Creates a rectangle geometry implementation. /// /// The bounds of the rectangle. - /// An . - IRectangleGeometryImpl CreateRectangleGeometry(Rect rect); + /// A rectangle. + IGeometryImpl CreateRectangleGeometry(Rect rect); /// /// Creates a stream geometry implementation. diff --git a/src/Avalonia.Visuals/Platform/IRectangleGeometryImpl.cs b/src/Avalonia.Visuals/Platform/IRectangleGeometryImpl.cs deleted file mode 100644 index 7ada2c874d..0000000000 --- a/src/Avalonia.Visuals/Platform/IRectangleGeometryImpl.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -namespace Avalonia.Platform -{ - /// - /// Defines the platform-specific interface for a . - /// - public interface IRectangleGeometryImpl : IGeometryImpl - { - } -} diff --git a/src/Skia/Avalonia.Skia/EllipseGeometryImpl.cs b/src/Skia/Avalonia.Skia/EllipseGeometryImpl.cs index 92a0a5ff80..aae1dd8cef 100644 --- a/src/Skia/Avalonia.Skia/EllipseGeometryImpl.cs +++ b/src/Skia/Avalonia.Skia/EllipseGeometryImpl.cs @@ -1,7 +1,6 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. -using Avalonia.Platform; using SkiaSharp; namespace Avalonia.Skia @@ -9,7 +8,7 @@ namespace Avalonia.Skia /// /// A Skia implementation of a . /// - internal class EllipseGeometryImpl : GeometryImpl, IEllipseGeometryImpl + internal class EllipseGeometryImpl : GeometryImpl { public override Rect Bounds { get; } public override SKPath EffectivePath { get; } diff --git a/src/Skia/Avalonia.Skia/LineGeometryImpl.cs b/src/Skia/Avalonia.Skia/LineGeometryImpl.cs index a78c76d44a..e929e153d1 100644 --- a/src/Skia/Avalonia.Skia/LineGeometryImpl.cs +++ b/src/Skia/Avalonia.Skia/LineGeometryImpl.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; -using Avalonia.Platform; using SkiaSharp; namespace Avalonia.Skia @@ -10,7 +9,7 @@ namespace Avalonia.Skia /// /// A Skia implementation of a . /// - internal class LineGeometryImpl : GeometryImpl, ILineGeometryImpl + internal class LineGeometryImpl : GeometryImpl { public override Rect Bounds { get; } public override SKPath EffectivePath { get; } diff --git a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs index f1e89bc464..6240a1cb4b 100644 --- a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs +++ b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs @@ -50,11 +50,11 @@ namespace Avalonia.Skia return new FormattedTextImpl(text, typeface, textAlignment, wrapping, constraint, spans); } - public IEllipseGeometryImpl CreateEllipseGeometry(Rect rect) => new EllipseGeometryImpl(rect); + public IGeometryImpl CreateEllipseGeometry(Rect rect) => new EllipseGeometryImpl(rect); - public ILineGeometryImpl CreateLineGeometry(Point p1, Point p2) => new LineGeometryImpl(p1, p2); + public IGeometryImpl CreateLineGeometry(Point p1, Point p2) => new LineGeometryImpl(p1, p2); - public IRectangleGeometryImpl CreateRectangleGeometry(Rect rect) => new RectangleGeometryImpl(rect); + public IGeometryImpl CreateRectangleGeometry(Rect rect) => new RectangleGeometryImpl(rect); /// public IStreamGeometryImpl CreateStreamGeometry() diff --git a/src/Skia/Avalonia.Skia/RectangleGeometryImpl.cs b/src/Skia/Avalonia.Skia/RectangleGeometryImpl.cs index 235cd37b56..a873e8e2df 100644 --- a/src/Skia/Avalonia.Skia/RectangleGeometryImpl.cs +++ b/src/Skia/Avalonia.Skia/RectangleGeometryImpl.cs @@ -1,7 +1,6 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. -using Avalonia.Platform; using SkiaSharp; namespace Avalonia.Skia @@ -9,7 +8,7 @@ namespace Avalonia.Skia /// /// A Skia implementation of a . /// - internal class RectangleGeometryImpl : GeometryImpl, IRectangleGeometryImpl + internal class RectangleGeometryImpl : GeometryImpl { public override Rect Bounds { get; } public override SKPath EffectivePath { get; } diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs index cb37a93bb3..5ab9a8f74d 100644 --- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs @@ -182,9 +182,9 @@ namespace Avalonia.Direct2D1 return new WriteableWicBitmapImpl(size, dpi, format); } - public IEllipseGeometryImpl CreateEllipseGeometry(Rect rect) => new EllipseGeometryImpl(rect); - public ILineGeometryImpl CreateLineGeometry(Point p1, Point p2) => new LineGeometryImpl(p1, p2); - public IRectangleGeometryImpl CreateRectangleGeometry(Rect rect) => new RectangleGeometryImpl(rect); + public IGeometryImpl CreateEllipseGeometry(Rect rect) => new EllipseGeometryImpl(rect); + public IGeometryImpl CreateLineGeometry(Point p1, Point p2) => new LineGeometryImpl(p1, p2); + public IGeometryImpl CreateRectangleGeometry(Rect rect) => new RectangleGeometryImpl(rect); public IStreamGeometryImpl CreateStreamGeometry() => new StreamGeometryImpl(); public IBitmapImpl LoadBitmap(string fileName) diff --git a/src/Windows/Avalonia.Direct2D1/Media/EllipseGeometryImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/EllipseGeometryImpl.cs index c6bf475ed1..9440966406 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/EllipseGeometryImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/EllipseGeometryImpl.cs @@ -1,7 +1,6 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. -using Avalonia.Platform; using SharpDX.Direct2D1; namespace Avalonia.Direct2D1.Media @@ -9,7 +8,7 @@ namespace Avalonia.Direct2D1.Media /// /// A Direct2D implementation of a . /// - internal class EllipseGeometryImpl : GeometryImpl, IEllipseGeometryImpl + internal class EllipseGeometryImpl : GeometryImpl { /// /// Initializes a new instance of the class. diff --git a/src/Windows/Avalonia.Direct2D1/Media/LineGeometryImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/LineGeometryImpl.cs index b2d11247b9..6b73fce309 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/LineGeometryImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/LineGeometryImpl.cs @@ -1,7 +1,6 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. -using Avalonia.Platform; using SharpDX.Direct2D1; namespace Avalonia.Direct2D1.Media @@ -9,7 +8,7 @@ namespace Avalonia.Direct2D1.Media /// /// A Direct2D implementation of a . /// - internal class LineGeometryImpl : StreamGeometryImpl, ILineGeometryImpl + internal class LineGeometryImpl : StreamGeometryImpl { /// /// Initializes a new instance of the class. diff --git a/src/Windows/Avalonia.Direct2D1/Media/RectangleGeometryImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/RectangleGeometryImpl.cs index 55b2b66b3f..194de4dd14 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/RectangleGeometryImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/RectangleGeometryImpl.cs @@ -1,7 +1,6 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. -using Avalonia.Platform; using SharpDX.Direct2D1; namespace Avalonia.Direct2D1.Media @@ -9,7 +8,7 @@ namespace Avalonia.Direct2D1.Media /// /// A Direct2D implementation of a . /// - internal class RectangleGeometryImpl : GeometryImpl, IRectangleGeometryImpl + internal class RectangleGeometryImpl : GeometryImpl { /// /// Initializes a new instance of the class. diff --git a/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs b/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs index c73c30365b..a3cc3dec17 100644 --- a/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs +++ b/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs @@ -22,19 +22,19 @@ namespace Avalonia.UnitTests return Mock.Of(); } - public IEllipseGeometryImpl CreateEllipseGeometry(Rect rect) + public IGeometryImpl CreateEllipseGeometry(Rect rect) { - return Mock.Of(); + return Mock.Of(); } - public ILineGeometryImpl CreateLineGeometry(Point p1, Point p2) + public IGeometryImpl CreateLineGeometry(Point p1, Point p2) { - return Mock.Of(); + return Mock.Of(); } - public IRectangleGeometryImpl CreateRectangleGeometry(Rect rect) + public IGeometryImpl CreateRectangleGeometry(Rect rect) { - return Mock.Of(); + return Mock.Of(); } public IRenderTarget CreateRenderTarget(IEnumerable surfaces) diff --git a/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs b/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs index 34be5f1dde..03470670d2 100644 --- a/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs +++ b/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs @@ -56,17 +56,17 @@ namespace Avalonia.Visuals.UnitTests.VisualTree throw new NotImplementedException(); } - public IEllipseGeometryImpl CreateEllipseGeometry(Rect rect) + public IGeometryImpl CreateEllipseGeometry(Rect rect) { throw new NotImplementedException(); } - public ILineGeometryImpl CreateLineGeometry(Point p1, Point p2) + public IGeometryImpl CreateLineGeometry(Point p1, Point p2) { throw new NotImplementedException(); } - public IRectangleGeometryImpl CreateRectangleGeometry(Rect rect) + public IGeometryImpl CreateRectangleGeometry(Rect rect) { throw new NotImplementedException(); } From 55e64e4c744b6836c26cc4409561b3930c441632 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Fri, 12 Apr 2019 11:32:59 +0200 Subject: [PATCH 046/234] Move Thumb style outside the control template --- src/Avalonia.Themes.Default/ScrollBar.xaml | 40 +++++++--------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/src/Avalonia.Themes.Default/ScrollBar.xaml b/src/Avalonia.Themes.Default/ScrollBar.xaml index edd678ed56..ca308b33c3 100644 --- a/src/Avalonia.Themes.Default/ScrollBar.xaml +++ b/src/Avalonia.Themes.Default/ScrollBar.xaml @@ -30,20 +30,7 @@ Classes="repeattrack" Focusable="False"/> - - - - - + - - - - - + + From 7e042158977c4111a67e901b21bbfe289897033e Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Fri, 12 Apr 2019 11:41:59 +0200 Subject: [PATCH 047/234] No longer set first window opened as MainWindow --- samples/ControlCatalog/App.xaml.cs | 2 ++ src/Avalonia.Controls/Application.cs | 2 ++ src/Avalonia.Controls/Window.cs | 14 -------------- .../ApplicationTests.cs | 13 ------------- 4 files changed, 4 insertions(+), 27 deletions(-) diff --git a/samples/ControlCatalog/App.xaml.cs b/samples/ControlCatalog/App.xaml.cs index 1f466d9f91..100cfa634e 100644 --- a/samples/ControlCatalog/App.xaml.cs +++ b/samples/ControlCatalog/App.xaml.cs @@ -15,6 +15,8 @@ namespace ControlCatalog var mainWindow = new MainWindow(); mainWindow.Show(); + + MainWindow = mainWindow; } } } diff --git a/src/Avalonia.Controls/Application.cs b/src/Avalonia.Controls/Application.cs index 2893505655..b750e570b3 100644 --- a/src/Avalonia.Controls/Application.cs +++ b/src/Avalonia.Controls/Application.cs @@ -272,6 +272,8 @@ namespace Avalonia { mainWindow.Show(); } + + MainWindow = mainWindow; } Run(_mainLoopCancellationTokenSource.Token); diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs index 648256e667..411685800e 100644 --- a/src/Avalonia.Controls/Window.cs +++ b/src/Avalonia.Controls/Window.cs @@ -49,8 +49,6 @@ namespace Avalonia.Controls /// public class Window : WindowBase, IStyleable, IFocusScope, ILayoutRoot, INameScope { - private static bool s_hasAddedFirstWindow; - /// /// Defines the property. /// @@ -262,18 +260,6 @@ namespace Avalonia.Controls } Application.Current.Windows.Add(window); - - if (s_hasAddedFirstWindow) - { - return; - } - - s_hasAddedFirstWindow = true; - - if (Application.Current.MainWindow == null) - { - Application.Current.MainWindow = window; - } } private static void RemoveWindow(Window window) diff --git a/tests/Avalonia.Controls.UnitTests/ApplicationTests.cs b/tests/Avalonia.Controls.UnitTests/ApplicationTests.cs index 7cedd9b69a..f362e691dc 100644 --- a/tests/Avalonia.Controls.UnitTests/ApplicationTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ApplicationTests.cs @@ -129,18 +129,5 @@ namespace Avalonia.Controls.UnitTests Assert.True(raised); } } - - [Fact] - public void Should_Have_MainWindow_After_First_Window_Shown() - { - using (UnitTestApplication.Start(TestServices.StyledWindow)) - { - var mainWindow = new Window(); - - mainWindow.Show(); - - Assert.Equal(mainWindow, Application.Current.MainWindow); - } - } } } From 05978b0ba620649e547f4f778ed145d407abfc94 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Fri, 12 Apr 2019 11:50:53 +0200 Subject: [PATCH 048/234] Make sure Shutdown is only called once --- src/Avalonia.Controls/Application.cs | 33 +++++++++---------- .../Controls/ExitEventArgs.cs | 6 +++- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/Avalonia.Controls/Application.cs b/src/Avalonia.Controls/Application.cs index b750e570b3..99fc2e7367 100644 --- a/src/Avalonia.Controls/Application.cs +++ b/src/Avalonia.Controls/Application.cs @@ -215,21 +215,6 @@ namespace Avalonia Run(_mainLoopCancellationTokenSource.Token); } - /// - /// Runs the application's main loop until the is canceled. - /// - /// The token to track - public void Run(CancellationToken token) - { - Dispatcher.UIThread.MainLoop(token); - - // Make sure we call OnExit in case an error happened and OnExit() wasn't called explicitly - if (!IsShuttingDown) - { - OnExit(new ExitEventArgs()); - } - } - /// /// Runs the application's main loop until the is closed. /// @@ -279,6 +264,17 @@ namespace Avalonia Run(_mainLoopCancellationTokenSource.Token); } + /// + /// Runs the application's main loop until the is canceled. + /// + /// The token to track + public void Run(CancellationToken token) + { + Dispatcher.UIThread.MainLoop(token); + + Shutdown(); + } + protected virtual void OnStartup(StartupEventArgs e) { Startup?.Invoke(this, e); @@ -287,8 +283,6 @@ namespace Avalonia protected virtual void OnExit(ExitEventArgs e) { Exit?.Invoke(this, e); - - Environment.ExitCode = e.ApplicationExitCode; } /// @@ -300,6 +294,11 @@ namespace Avalonia /// public void Shutdown(int exitCode) { + if (IsShuttingDown) + { + return; + } + IsShuttingDown = true; Windows.Clear(); diff --git a/src/Avalonia.Styling/Controls/ExitEventArgs.cs b/src/Avalonia.Styling/Controls/ExitEventArgs.cs index 1a4ee15f17..2e6409e296 100644 --- a/src/Avalonia.Styling/Controls/ExitEventArgs.cs +++ b/src/Avalonia.Styling/Controls/ExitEventArgs.cs @@ -7,6 +7,10 @@ namespace Avalonia.Controls { public class ExitEventArgs : EventArgs { - public int ApplicationExitCode { get; set; } + public int ApplicationExitCode + { + get => Environment.ExitCode; + set => Environment.ExitCode = value; + } } } From 6fbe1c2180ef45a940e193f1b4637e64eaab80ed Mon Sep 17 00:00:00 2001 From: Jumar Macato Date: Fri, 12 Apr 2019 19:35:31 +0800 Subject: [PATCH 049/234] More animations shenanigans. --- .../LayoutTransformControl.cs | 1 + .../Notifications/Notification.cs | 32 ++++++++++++++--- .../NotificationArea.xaml | 34 ++++++++++++------- 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/Avalonia.Controls/LayoutTransformControl.cs b/src/Avalonia.Controls/LayoutTransformControl.cs index 950d4f34da..482cfc5320 100644 --- a/src/Avalonia.Controls/LayoutTransformControl.cs +++ b/src/Avalonia.Controls/LayoutTransformControl.cs @@ -51,6 +51,7 @@ namespace Avalonia.Controls { if (TransformRoot == null || LayoutTransform == null) { + LayoutTransform = RenderTransform; return base.ArrangeOverride(finalSize); } diff --git a/src/Avalonia.Controls/Notifications/Notification.cs b/src/Avalonia.Controls/Notifications/Notification.cs index 54de4bcce7..c75e805892 100644 --- a/src/Avalonia.Controls/Notifications/Notification.cs +++ b/src/Avalonia.Controls/Notifications/Notification.cs @@ -9,11 +9,12 @@ namespace Avalonia.Controls.Notifications { public class Notification : ContentControl { - private TimeSpan _closingAnimationTime = TimeSpan.FromSeconds(1); + // private TimeSpan _closingAnimationTime = TimeSpan.FromSeconds(1); static Notification() { //CloseOnClickProperty.Changed.AddClassHandler