diff --git a/packages/Avalonia/Avalonia.csproj b/packages/Avalonia/Avalonia.csproj index af9ed71c5f..4b28527465 100644 --- a/packages/Avalonia/Avalonia.csproj +++ b/packages/Avalonia/Avalonia.csproj @@ -1,6 +1,6 @@  - netstandard2.0;net461;netcoreapp2.0;net6.0 + net6.0;netstandard2.0;net461;netcoreapp2.0 Avalonia diff --git a/readme.md b/readme.md index a8a6399f2f..b38552a010 100644 --- a/readme.md +++ b/readme.md @@ -75,6 +75,12 @@ For more information see the [.NET Foundation Code of Conduct](https://dotnetfou Avalonia is licenced under the [MIT licence](licence.md). +## Support Avalonia + +**BTC**: bc1q05wx78qemgy9x6ytl5ljk2xrt00yqargyjm8gx + +This will be shared with the community and awarded for significant contributions. + ### Backers Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/Avalonia#backer)] diff --git a/samples/ControlCatalog.Android/ControlCatalog.Android.csproj b/samples/ControlCatalog.Android/ControlCatalog.Android.csproj index 1a68c4d732..617b6b6ab0 100644 --- a/samples/ControlCatalog.Android/ControlCatalog.Android.csproj +++ b/samples/ControlCatalog.Android/ControlCatalog.Android.csproj @@ -32,7 +32,7 @@ True False False - armeabi-v7a;x86 + armeabi-v7a;x86;x86_64 Xamarin False False @@ -51,7 +51,7 @@ True False False - armeabi-v7a,x86 + armeabi-v7a,x86;x86_64 Xamarin False False @@ -125,6 +125,10 @@ {42472427-4774-4c81-8aff-9f27b8e31721} Avalonia.Layout + + {c42d2fc1-a531-4ed4-84b9-89aec7c962fc} + Avalonia.Themes.Fluent + {eb582467-6abb-43a1-b052-e981ba910e3a} Avalonia.Visuals diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs index 5e11d8eab2..57f22e7a05 100644 --- a/src/Android/Avalonia.Android/AndroidPlatform.cs +++ b/src/Android/Avalonia.Android/AndroidPlatform.cs @@ -43,11 +43,12 @@ namespace Avalonia.Android AvaloniaLocator.CurrentMutable .Bind().ToTransient() .Bind().ToTransient() + .Bind().ToConstant(new WindowingPlatformStub()) .Bind().ToSingleton() .Bind().ToConstant(Instance) .Bind().ToConstant(new AndroidThreadingInterface()) .Bind().ToTransient() - .Bind().ToSingleton() + .Bind().ToSingleton() .Bind().ToConstant(new ChoreographerTimer()) .Bind().ToConstant(new RenderLoop()) .Bind().ToSingleton() diff --git a/src/Android/Avalonia.Android/Stubs.cs b/src/Android/Avalonia.Android/Stubs.cs new file mode 100644 index 0000000000..f36c01dbc8 --- /dev/null +++ b/src/Android/Avalonia.Android/Stubs.cs @@ -0,0 +1,56 @@ +using System; +using System.IO; +using Avalonia.Platform; + +namespace Avalonia.Android +{ + class WindowingPlatformStub : IWindowingPlatform + { + public IWindowImpl CreateWindow() => throw new NotSupportedException(); + + public IWindowImpl CreateEmbeddableWindow() => throw new NotSupportedException(); + + public ITrayIconImpl CreateTrayIcon() => null; + } + + class PlatformIconLoaderStub : IPlatformIconLoader + { + public IWindowIconImpl LoadIcon(IBitmapImpl bitmap) + { + using (var stream = new MemoryStream()) + { + bitmap.Save(stream); + return LoadIcon(stream); + } + } + + public IWindowIconImpl LoadIcon(Stream stream) + { + var ms = new MemoryStream(); + stream.CopyTo(ms); + return new IconStub(ms); + } + + public IWindowIconImpl LoadIcon(string fileName) + { + using (var file = File.Open(fileName, FileMode.Open)) + return LoadIcon(file); + } + } + + public class IconStub : IWindowIconImpl + { + private readonly MemoryStream _ms; + + public IconStub(MemoryStream stream) + { + _ms = stream; + } + + public void Save(Stream outputStream) + { + _ms.Position = 0; + _ms.CopyTo(outputStream); + } + } +} diff --git a/src/Android/Avalonia.AndroidTestApplication/Resources/Resource.Designer.cs b/src/Android/Avalonia.AndroidTestApplication/Resources/Resource.Designer.cs index 83db67fcee..87fd47df25 100644 --- a/src/Android/Avalonia.AndroidTestApplication/Resources/Resource.Designer.cs +++ b/src/Android/Avalonia.AndroidTestApplication/Resources/Resource.Designer.cs @@ -14,7 +14,7 @@ namespace Avalonia.AndroidTestApplication { - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "12.1.99.62")] public partial class Resource { diff --git a/src/Avalonia.Animation/Avalonia.Animation.csproj b/src/Avalonia.Animation/Avalonia.Animation.csproj index 85938ad958..465b922b72 100644 --- a/src/Avalonia.Animation/Avalonia.Animation.csproj +++ b/src/Avalonia.Animation/Avalonia.Animation.csproj @@ -1,6 +1,6 @@  - netstandard2.0;net6.0 + net6.0;netstandard2.0 diff --git a/src/Avalonia.Base/Avalonia.Base.csproj b/src/Avalonia.Base/Avalonia.Base.csproj index 07614f31db..376075df2a 100644 --- a/src/Avalonia.Base/Avalonia.Base.csproj +++ b/src/Avalonia.Base/Avalonia.Base.csproj @@ -1,6 +1,6 @@  - netstandard2.0;net6.0 + net6.0;netstandard2.0 Avalonia.Base Avalonia True diff --git a/src/Avalonia.Base/AvaloniaLocator.cs b/src/Avalonia.Base/AvaloniaLocator.cs index 0510852ea7..8ec245507b 100644 --- a/src/Avalonia.Base/AvaloniaLocator.cs +++ b/src/Avalonia.Base/AvaloniaLocator.cs @@ -125,6 +125,16 @@ namespace Avalonia { return (T?) resolver.GetService(typeof (T)); } + + public static object GetRequiredService(this IAvaloniaDependencyResolver resolver, Type t) + { + return resolver.GetService(t) ?? throw new InvalidOperationException($"Unable to locate '{t}'."); + } + + public static T GetRequiredService(this IAvaloniaDependencyResolver resolver) + { + return (T?)resolver.GetService(typeof(T)) ?? throw new InvalidOperationException($"Unable to locate '{typeof(T)}'."); + } } } diff --git a/src/Avalonia.Base/Threading/Dispatcher.cs b/src/Avalonia.Base/Threading/Dispatcher.cs index 949c11fbe0..ffc013268d 100644 --- a/src/Avalonia.Base/Threading/Dispatcher.cs +++ b/src/Avalonia.Base/Threading/Dispatcher.cs @@ -56,11 +56,7 @@ namespace Avalonia.Threading /// public void MainLoop(CancellationToken cancellationToken) { - var platform = AvaloniaLocator.Current.GetService(); - - if (platform is null) - throw new InvalidOperationException("Unable to locate IPlatformThreadingInterface"); - + var platform = AvaloniaLocator.Current.GetRequiredService(); cancellationToken.Register(() => platform.Signal(DispatcherPriority.Send)); platform.RunLoop(cancellationToken); } diff --git a/src/Avalonia.Base/Utilities/WeakSubscriptionManager.cs b/src/Avalonia.Base/Utilities/WeakSubscriptionManager.cs index 66223e513d..88b1e3c807 100644 --- a/src/Avalonia.Base/Utilities/WeakSubscriptionManager.cs +++ b/src/Avalonia.Base/Utilities/WeakSubscriptionManager.cs @@ -180,7 +180,7 @@ namespace Avalonia.Utilities { var r = _data[c]; if (r?.TryGetTarget(out var sub) == true) - sub.OnEvent(sender, eventArgs); + sub!.OnEvent(sender, eventArgs); else needCompact = true; } diff --git a/src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj b/src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj index 7884f13ddb..e864ea2007 100644 --- a/src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj +++ b/src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj @@ -6,7 +6,7 @@ tools $(DefineConstants);BUILDTASK;XAMLX_CECIL_INTERNAL;XAMLX_INTERNAL true - NU1605 + NU1605;CS8632 diff --git a/src/Avalonia.Controls.DataGrid/Avalonia.Controls.DataGrid.csproj b/src/Avalonia.Controls.DataGrid/Avalonia.Controls.DataGrid.csproj index d50e8b1115..c89157dc0f 100644 --- a/src/Avalonia.Controls.DataGrid/Avalonia.Controls.DataGrid.csproj +++ b/src/Avalonia.Controls.DataGrid/Avalonia.Controls.DataGrid.csproj @@ -1,6 +1,6 @@  - netstandard2.0;net6.0 + net6.0;netstandard2.0 Avalonia.Controls.DataGrid diff --git a/src/Avalonia.Controls/Avalonia.Controls.csproj b/src/Avalonia.Controls/Avalonia.Controls.csproj index 479bbb49b6..e2c6a714aa 100644 --- a/src/Avalonia.Controls/Avalonia.Controls.csproj +++ b/src/Avalonia.Controls/Avalonia.Controls.csproj @@ -1,6 +1,6 @@  - netstandard2.0;net6.0 + net6.0;netstandard2.0 diff --git a/src/Avalonia.Controls/Button.cs b/src/Avalonia.Controls/Button.cs index 8b22cdd4ec..8537c9acbc 100644 --- a/src/Avalonia.Controls/Button.cs +++ b/src/Avalonia.Controls/Button.cs @@ -304,15 +304,18 @@ namespace Avalonia.Controls /// protected virtual void OnClick() { - OpenFlyout(); + if (IsEffectivelyEnabled) + { + OpenFlyout(); - var e = new RoutedEventArgs(ClickEvent); - RaiseEvent(e); + var e = new RoutedEventArgs(ClickEvent); + RaiseEvent(e); - if (!e.Handled && Command?.CanExecute(CommandParameter) == true) - { - Command.Execute(CommandParameter); - e.Handled = true; + if (!e.Handled && Command?.CanExecute(CommandParameter) == true) + { + Command.Execute(CommandParameter); + e.Handled = true; + } } } diff --git a/src/Avalonia.Controls/Calendar/CalendarDatePicker.cs b/src/Avalonia.Controls/Calendar/CalendarDatePicker.cs index af3fdbd662..a856ee071c 100644 --- a/src/Avalonia.Controls/Calendar/CalendarDatePicker.cs +++ b/src/Avalonia.Controls/Calendar/CalendarDatePicker.cs @@ -1,4 +1,4 @@ -// (c) Copyright Microsoft Corporation. +// (c) Copyright Microsoft Corporation. // This source is subject to the Microsoft Public License (Ms-PL). // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. // All other rights reserved. @@ -425,9 +425,6 @@ namespace Avalonia.Controls { FocusableProperty.OverrideDefaultValue(true); - DisplayDateProperty.Changed.AddClassHandler((x,e) => x.OnDisplayDateChanged(e)); - DisplayDateStartProperty.Changed.AddClassHandler((x,e) => x.OnDisplayDateStartChanged(e)); - DisplayDateEndProperty.Changed.AddClassHandler((x,e) => x.OnDisplayDateEndChanged(e)); IsDropDownOpenProperty.Changed.AddClassHandler((x,e) => x.OnIsDropDownOpenChanged(e)); SelectedDateProperty.Changed.AddClassHandler((x,e) => x.OnSelectedDateChanged(e)); SelectedDateFormatProperty.Changed.AddClassHandler((x,e) => x.OnSelectedDateFormatChanged(e)); @@ -459,18 +456,12 @@ namespace Avalonia.Controls if (_calendar != null) { _calendar.SelectionMode = CalendarSelectionMode.SingleDate; - _calendar.SelectedDate = SelectedDate; - SetCalendarDisplayDate(DisplayDate); - SetCalendarDisplayDateStart(DisplayDateStart); - SetCalendarDisplayDateEnd(DisplayDateEnd); _calendar.DayButtonMouseUp += Calendar_DayButtonMouseUp; _calendar.DisplayDateChanged += Calendar_DisplayDateChanged; _calendar.SelectedDatesChanged += Calendar_SelectedDatesChanged; _calendar.PointerReleased += Calendar_PointerReleased; _calendar.KeyDown += Calendar_KeyDown; - //_calendar.SizeChanged += new SizeChangedEventHandler(Calendar_SizeChanged); - //_calendar.IsTabStop = true; var currentBlackoutDays = BlackoutDates; BlackoutDates = _calendar.BlackoutDates; @@ -587,58 +578,6 @@ namespace Avalonia.Controls SetSelectedDate(); } - private void SetCalendarDisplayDate(DateTime value) - { - if (DateTimeHelper.CompareYearMonth(_calendar.DisplayDate, value) != 0) - { - _calendar.DisplayDate = DisplayDate; - if (DateTime.Compare(_calendar.DisplayDate, DisplayDate) != 0) - { - DisplayDate = _calendar.DisplayDate; - } - } - } - private void OnDisplayDateChanged(AvaloniaPropertyChangedEventArgs e) - { - if (_calendar != null) - { - var value = (DateTime)e.NewValue; - SetCalendarDisplayDate(value); - } - } - private void SetCalendarDisplayDateStart(DateTime? value) - { - _calendar.DisplayDateStart = value; - if (_calendar.DisplayDateStart.HasValue && DisplayDateStart.HasValue && DateTime.Compare(_calendar.DisplayDateStart.Value, DisplayDateStart.Value) != 0) - { - DisplayDateStart = _calendar.DisplayDateStart; - } - } - private void OnDisplayDateStartChanged(AvaloniaPropertyChangedEventArgs e) - { - if (_calendar != null) - { - var value = (DateTime?)e.NewValue; - SetCalendarDisplayDateStart(value); - } - } - private void SetCalendarDisplayDateEnd(DateTime? value) - { - _calendar.DisplayDateEnd = value; - if (_calendar.DisplayDateEnd.HasValue && DisplayDateEnd.HasValue && DateTime.Compare(_calendar.DisplayDateEnd.Value, DisplayDateEnd.Value) != 0) - { - DisplayDateEnd = _calendar.DisplayDateEnd; - } - - } - private void OnDisplayDateEndChanged(AvaloniaPropertyChangedEventArgs e) - { - if (_calendar != null) - { - var value = (DateTime?)e.NewValue; - SetCalendarDisplayDateEnd(value); - } - } private void OnIsDropDownOpenChanged(AvaloniaPropertyChangedEventArgs e) { var oldValue = (bool)e.OldValue; @@ -670,11 +609,6 @@ namespace Avalonia.Controls var addedDate = (DateTime?)e.NewValue; var removedDate = (DateTime?)e.OldValue; - if (_calendar != null && addedDate != _calendar.SelectedDate) - { - _calendar.SelectedDate = addedDate; - } - if (SelectedDate != null) { DateTime day = SelectedDate.Value; diff --git a/src/Avalonia.Controls/Grid.cs b/src/Avalonia.Controls/Grid.cs index 4e60b52f83..74401c450a 100644 --- a/src/Avalonia.Controls/Grid.cs +++ b/src/Avalonia.Controls/Grid.cs @@ -978,7 +978,7 @@ namespace Avalonia.Controls /// width is not registered in columns. /// Passed through to MeasureCell. /// When "true" cells' desired height is not registered in rows. - /// return true when desired size has changed + /// When the method exits, indicates whether the desired size has changed. private void MeasureCellsGroup( int cellsHead, Size referenceSize, diff --git a/src/Avalonia.Controls/SystemDialog.cs b/src/Avalonia.Controls/SystemDialog.cs index 3fac10b2d1..3487f427d7 100644 --- a/src/Avalonia.Controls/SystemDialog.cs +++ b/src/Avalonia.Controls/SystemDialog.cs @@ -66,8 +66,7 @@ namespace Avalonia.Controls { if(parent == null) throw new ArgumentNullException(nameof(parent)); - var service = AvaloniaLocator.Current.GetService() ?? - throw new InvalidOperationException("Unable to locate ISystemDialogImpl."); + var service = AvaloniaLocator.Current.GetRequiredService(); return (await service.ShowFileDialogAsync(this, parent) ?? Array.Empty()).FirstOrDefault(); } @@ -95,8 +94,7 @@ namespace Avalonia.Controls { if(parent == null) throw new ArgumentNullException(nameof(parent)); - var service = AvaloniaLocator.Current.GetService() ?? - throw new InvalidOperationException("Unable to locate ISystemDialogImpl."); + var service = AvaloniaLocator.Current.GetRequiredService(); return service.ShowFileDialogAsync(this, parent); } } @@ -125,8 +123,7 @@ namespace Avalonia.Controls { if(parent == null) throw new ArgumentNullException(nameof(parent)); - var service = AvaloniaLocator.Current.GetService() ?? - throw new InvalidOperationException("Unable to locate ISystemDialogImpl."); + var service = AvaloniaLocator.Current.GetRequiredService(); return service.ShowFolderDialogAsync(this, parent); } } diff --git a/src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj b/src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj index 9d8842f613..f8a7cdc690 100644 --- a/src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj +++ b/src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj @@ -1,6 +1,6 @@  - netstandard2.0;net6.0 + net6.0;netstandard2.0