From 85732bc5817e54cf5ea19fcdd1bfb676189769e5 Mon Sep 17 00:00:00 2001 From: Benedikt Stebner Date: Fri, 16 Jun 2023 12:04:15 +0200 Subject: [PATCH 01/43] Make sure Windows InputMethod deletes current selection before preeditText is set --- .../Avalonia.Win32/Input/Imm32InputMethod.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/Windows/Avalonia.Win32/Input/Imm32InputMethod.cs b/src/Windows/Avalonia.Win32/Input/Imm32InputMethod.cs index 05074cc82e..8502f5b41a 100644 --- a/src/Windows/Avalonia.Win32/Input/Imm32InputMethod.cs +++ b/src/Windows/Avalonia.Win32/Input/Imm32InputMethod.cs @@ -324,6 +324,11 @@ namespace Avalonia.Win32.Input if (IsActive) { Client.SetPreeditText(null); + + if (Client.SupportsSurroundingText && Client.SurroundingText.AnchorOffset != Client.SurroundingText.CursorOffset) + { + KeyPress(Key.Delete); + } } IsComposing = true; @@ -393,6 +398,19 @@ namespace Avalonia.Win32.Input return (int)(ptr.ToInt64() & 0xffffffff); } + private void KeyPress(Key key) + { + if (_parent?.Input != null) + { + _parent.Input(new RawKeyEventArgs(KeyboardDevice.Instance!, (ulong)DateTime.Now.Ticks, _parent.Owner, + RawKeyEventType.KeyDown, key, RawInputModifiers.None)); + + _parent.Input(new RawKeyEventArgs(KeyboardDevice.Instance!, (ulong)DateTime.Now.Ticks, _parent.Owner, + RawKeyEventType.KeyUp, key, RawInputModifiers.None)); + + } + } + ~Imm32InputMethod() { _caretManager.TryDestroy(); From 4e642b3e8cfd8dbde390494c5f2da30e46212920 Mon Sep 17 00:00:00 2001 From: robloo Date: Sun, 18 Jun 2023 10:59:38 -0400 Subject: [PATCH 02/43] Add OnSizeChanged method to Control --- src/Avalonia.Controls/Control.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Controls/Control.cs b/src/Avalonia.Controls/Control.cs index ae7d4f3fb4..885b3f302e 100644 --- a/src/Avalonia.Controls/Control.cs +++ b/src/Avalonia.Controls/Control.cs @@ -357,6 +357,15 @@ namespace Avalonia.Controls RaiseEvent(eventArgs); } + /// + /// Invoked just before the event. + /// + /// The event args. + protected virtual void OnSizeChanged(SizeChangedEventArgs e) + { + RaiseEvent(e); + } + /// protected sealed override void OnAttachedToVisualTreeCore(VisualTreeAttachmentEventArgs e) { @@ -435,6 +444,10 @@ namespace Avalonia.Controls } } + /// + /// Returns a new, type-specific implementation for the control. + /// + /// The type-specific implementation. protected virtual AutomationPeer OnCreateAutomationPeer() { return new NoneAutomationPeer(this); @@ -459,6 +472,7 @@ namespace Avalonia.Controls return _automationPeer; } + /// protected override void OnPointerReleased(PointerReleasedEventArgs e) { base.OnPointerReleased(e); @@ -473,6 +487,7 @@ namespace Avalonia.Controls } } + /// protected override void OnKeyUp(KeyEventArgs e) { base.OnKeyUp(e); @@ -531,7 +546,7 @@ namespace Avalonia.Controls previousSize: new Size(oldValue.Width, oldValue.Height), newSize: new Size(newValue.Width, newValue.Height)); - RaiseEvent(sizeChangedEventArgs); + OnSizeChanged(sizeChangedEventArgs); } } } From 85390a1812f5fedd19b64ff64ce5bd794dba31cd Mon Sep 17 00:00:00 2001 From: robloo Date: Sun, 18 Jun 2023 11:19:01 -0400 Subject: [PATCH 03/43] Add EventArgs parameter to OnLoaded/Unloaded methods --- .../AppWithoutLifetime/MainWindow.axaml.cs | 5 +++-- samples/AppWithoutLifetime/Sub.axaml.cs | 6 ++++-- samples/SafeAreaDemo/Views/MainView.xaml.cs | 6 ++++-- src/Avalonia.Controls/Control.cs | 20 +++++++++---------- src/Avalonia.Controls/ToggleSwitch.cs | 6 ++++-- 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/samples/AppWithoutLifetime/MainWindow.axaml.cs b/samples/AppWithoutLifetime/MainWindow.axaml.cs index d27d5d5653..df3ed3cea0 100644 --- a/samples/AppWithoutLifetime/MainWindow.axaml.cs +++ b/samples/AppWithoutLifetime/MainWindow.axaml.cs @@ -17,10 +17,11 @@ public partial class MainWindow : Window AvaloniaXamlLoader.Load(this); } - protected override void OnLoaded() + /// + protected override void OnLoaded(RoutedEventArgs e) { this.AttachDevTools(); - base.OnLoaded(); + base.OnLoaded(e); } public void Open(object sender, RoutedEventArgs e) diff --git a/samples/AppWithoutLifetime/Sub.axaml.cs b/samples/AppWithoutLifetime/Sub.axaml.cs index 50c770b3a2..3a7ce787bc 100644 --- a/samples/AppWithoutLifetime/Sub.axaml.cs +++ b/samples/AppWithoutLifetime/Sub.axaml.cs @@ -1,5 +1,6 @@ using Avalonia; using Avalonia.Controls; +using Avalonia.Interactivity; using Avalonia.Markup.Xaml; namespace AppWithoutLifetime; @@ -16,9 +17,10 @@ public partial class Sub : Window AvaloniaXamlLoader.Load(this); } - protected override void OnLoaded() + /// + protected override void OnLoaded(RoutedEventArgs e) { this.AttachDevTools(); - base.OnLoaded(); + base.OnLoaded(e); } } diff --git a/samples/SafeAreaDemo/Views/MainView.xaml.cs b/samples/SafeAreaDemo/Views/MainView.xaml.cs index 2b651225e7..4b8c5e5f15 100644 --- a/samples/SafeAreaDemo/Views/MainView.xaml.cs +++ b/samples/SafeAreaDemo/Views/MainView.xaml.cs @@ -1,4 +1,5 @@ using Avalonia.Controls; +using Avalonia.Interactivity; using Avalonia.Markup.Xaml; using SafeAreaDemo.ViewModels; @@ -11,9 +12,10 @@ namespace SafeAreaDemo.Views AvaloniaXamlLoader.Load(this); } - protected override void OnLoaded() + /// + protected override void OnLoaded(RoutedEventArgs e) { - base.OnLoaded(); + base.OnLoaded(e); var insetsManager = TopLevel.GetTopLevel(this)?.InsetsManager; if (insetsManager != null && DataContext is MainViewModel viewModel) diff --git a/src/Avalonia.Controls/Control.cs b/src/Avalonia.Controls/Control.cs index ae7d4f3fb4..6c45374c21 100644 --- a/src/Avalonia.Controls/Control.cs +++ b/src/Avalonia.Controls/Control.cs @@ -316,7 +316,8 @@ namespace Avalonia.Controls ((ILogical)this).IsAttachedToLogicalTree) { _isLoaded = true; - OnLoaded(); + + OnLoaded(new RoutedEventArgs(LoadedEvent, this)); } } @@ -333,28 +334,27 @@ namespace Avalonia.Controls _loadedQueue.Remove(this); _isLoaded = false; - OnUnloaded(); + + OnUnloaded(new RoutedEventArgs(UnloadedEvent, this)); } } /// /// Invoked just before the event. /// - protected virtual void OnLoaded() + /// The event args. + protected virtual void OnLoaded(RoutedEventArgs e) { - var eventArgs = new RoutedEventArgs(LoadedEvent); - eventArgs.Source = null; - RaiseEvent(eventArgs); + RaiseEvent(e); } /// /// Invoked just before the event. /// - protected virtual void OnUnloaded() + /// The event args. + protected virtual void OnUnloaded(RoutedEventArgs e) { - var eventArgs = new RoutedEventArgs(UnloadedEvent); - eventArgs.Source = null; - RaiseEvent(eventArgs); + RaiseEvent(e); } /// diff --git a/src/Avalonia.Controls/ToggleSwitch.cs b/src/Avalonia.Controls/ToggleSwitch.cs index 48b068d324..dc6b946381 100644 --- a/src/Avalonia.Controls/ToggleSwitch.cs +++ b/src/Avalonia.Controls/ToggleSwitch.cs @@ -3,6 +3,7 @@ using Avalonia.Controls.Metadata; using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; +using Avalonia.Interactivity; using Avalonia.LogicalTree; namespace Avalonia.Controls @@ -200,9 +201,10 @@ namespace Avalonia.Controls } } - protected override void OnLoaded() + /// + protected override void OnLoaded(RoutedEventArgs e) { - base.OnLoaded(); + base.OnLoaded(e); UpdateKnobTransitions(); } From 87b8c63c1b7ce8e1753ee063da919819d6814434 Mon Sep 17 00:00:00 2001 From: robloo Date: Sun, 18 Jun 2023 12:16:58 -0400 Subject: [PATCH 04/43] Add Distance method to Point --- src/Avalonia.Base/Point.cs | 13 +++++++++++++ src/Avalonia.Base/Vector.cs | 14 ++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/Avalonia.Base/Point.cs b/src/Avalonia.Base/Point.cs index 331cce4a76..e3ea21d1eb 100644 --- a/src/Avalonia.Base/Point.cs +++ b/src/Avalonia.Base/Point.cs @@ -164,6 +164,19 @@ namespace Avalonia /// The resulting point. public static Point operator *(Point point, Matrix matrix) => matrix.Transform(point); + /// + /// Computes the Euclidean distance between the two given points. + /// + /// The first point. + /// The second point. + /// The Euclidean distance. + public static double Distance(Point value1, Point value2) + { + double distanceSquared = ((value2.X - value1.X) * (value2.X - value1.X)) + + ((value2.Y - value1.Y) * (value2.Y - value1.Y)); + return Math.Sqrt(distanceSquared); + } + /// /// Parses a string. /// diff --git a/src/Avalonia.Base/Vector.cs b/src/Avalonia.Base/Vector.cs index 15722901a6..fffe206835 100644 --- a/src/Avalonia.Base/Vector.cs +++ b/src/Avalonia.Base/Vector.cs @@ -359,7 +359,7 @@ namespace Avalonia internal Vector(Vector2 v) : this(v.X, v.Y) { - + } /// @@ -379,21 +379,27 @@ namespace Avalonia /// public static Vector Max(Vector left, Vector right) => new(Math.Max(left.X, right.X), Math.Max(left.Y, right.Y)); - + /// /// Returns a vector whose elements are the minimum of each of the pairs of elements in two specified vectors /// public static Vector Min(Vector left, Vector right) => new(Math.Min(left.X, right.X), Math.Min(left.Y, right.Y)); - + /// /// Computes the Euclidean distance between the two given points. /// + /// The first point. + /// The second point. + /// The Euclidean distance. public static double Distance(Vector value1, Vector value2) => Math.Sqrt(DistanceSquared(value1, value2)); - + /// /// Returns the Euclidean distance squared between two specified points /// + /// The first point. + /// The second point. + /// The Euclidean distance squared. public static double DistanceSquared(Vector value1, Vector value2) { var difference = value1 - value2; From 97d595a74b54455a06992ae98e1aa89de0ff2668 Mon Sep 17 00:00:00 2001 From: enycw001 <3189263@qq.com> Date: Mon, 19 Jun 2023 18:08:28 +0800 Subject: [PATCH 05/43] fix_patterns --- .../Internal/ManagedFileChooserFilterViewModel.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Avalonia.Dialogs/Internal/ManagedFileChooserFilterViewModel.cs b/src/Avalonia.Dialogs/Internal/ManagedFileChooserFilterViewModel.cs index 8389a25386..8e24da97a4 100644 --- a/src/Avalonia.Dialogs/Internal/ManagedFileChooserFilterViewModel.cs +++ b/src/Avalonia.Dialogs/Internal/ManagedFileChooserFilterViewModel.cs @@ -18,9 +18,9 @@ namespace Avalonia.Dialogs.Internal return; } - _patterns = filter.Patterns? - .Select(e => new Regex(Regex.Escape(e).Replace(@"\*", ".*").Replace(@"\?", "."), RegexOptions.Singleline | RegexOptions.IgnoreCase)) - .ToArray(); + _patterns = filter.Patterns? + .Select(e => new Regex("^" + Regex.Escape(e).Replace("\\*", ".*") + "$", RegexOptions.Singleline | RegexOptions.IgnoreCase)) + .ToArray(); } public bool Match(string filename) From 84c2efde2264ea488c2830c6d41af817ec2b2149 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Mon, 19 Jun 2023 22:21:10 -0400 Subject: [PATCH 06/43] Minor app builder fix --- src/Avalonia.Controls/AppBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Controls/AppBuilder.cs b/src/Avalonia.Controls/AppBuilder.cs index 77cc9d4dcb..1cac22c8ce 100644 --- a/src/Avalonia.Controls/AppBuilder.cs +++ b/src/Avalonia.Controls/AppBuilder.cs @@ -151,7 +151,7 @@ namespace Avalonia } throw new InvalidOperationException( - $"Unable to create AppBuilder from type {entryPointType.Name}." + + $"Unable to create AppBuilder from type \"{entryPointType.FullName}\". " + $"Input type either needs to have BuildAvaloniaApp -> AppBuilder method or inherit Application type."); } From 112648c1a8bb0de8a5f17a3175b66f0719e76fd7 Mon Sep 17 00:00:00 2001 From: Emmanuel Hansen Date: Tue, 23 May 2023 16:04:39 +0000 Subject: [PATCH 07/43] drop splash screen activity --- .../ControlCatalog.Android.csproj | 9 ++ .../ControlCatalog.Android/MainActivity.cs | 12 ++- .../ControlCatalog.Android/SplashActivity.cs | 35 -------- samples/MobileSandbox.Android/MainActivity.cs | 5 +- .../MobileSandbox.Android.csproj | 10 +++ .../MobileSandbox.Android/SplashActivity.cs | 17 ---- .../AvaloniaMainActivity.App.cs | 60 +++++++++++++ .../Avalonia.Android/AvaloniaMainActivity.cs | 88 +++++++------------ .../AvaloniaSplashActivity.cs | 40 --------- 9 files changed, 125 insertions(+), 151 deletions(-) delete mode 100644 samples/ControlCatalog.Android/SplashActivity.cs delete mode 100644 samples/MobileSandbox.Android/SplashActivity.cs create mode 100644 src/Android/Avalonia.Android/AvaloniaMainActivity.App.cs delete mode 100644 src/Android/Avalonia.Android/AvaloniaSplashActivity.cs diff --git a/samples/ControlCatalog.Android/ControlCatalog.Android.csproj b/samples/ControlCatalog.Android/ControlCatalog.Android.csproj index a43ea4539a..f668067f80 100644 --- a/samples/ControlCatalog.Android/ControlCatalog.Android.csproj +++ b/samples/ControlCatalog.Android/ControlCatalog.Android.csproj @@ -10,6 +10,11 @@ apk true + + + + + Resources\drawable\Icon.png @@ -37,6 +42,10 @@ + + + + diff --git a/samples/ControlCatalog.Android/MainActivity.cs b/samples/ControlCatalog.Android/MainActivity.cs index 486d14661e..9b5b06e5fb 100644 --- a/samples/ControlCatalog.Android/MainActivity.cs +++ b/samples/ControlCatalog.Android/MainActivity.cs @@ -5,8 +5,16 @@ using Avalonia.Android; namespace ControlCatalog.Android { - [Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.Main", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)] - public class MainActivity : AvaloniaMainActivity + [Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)] + public class MainActivity : AvaloniaMainActivity { + protected override Avalonia.AppBuilder CustomizeAppBuilder(Avalonia.AppBuilder builder) + { + return base.CustomizeAppBuilder(builder) + .AfterSetup(_ => + { + Pages.EmbedSample.Implementation = new EmbedSampleAndroid(); + }); + } } } diff --git a/samples/ControlCatalog.Android/SplashActivity.cs b/samples/ControlCatalog.Android/SplashActivity.cs deleted file mode 100644 index a0b68b129b..0000000000 --- a/samples/ControlCatalog.Android/SplashActivity.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Android.App; -using Android.Content; -using Android.Content.PM; -using Android.OS; -using Avalonia.Android; - -namespace ControlCatalog.Android -{ - [Activity(Theme = "@style/MyTheme.Splash", MainLauncher = true, NoHistory = true)] - public class SplashActivity : AvaloniaSplashActivity - { - protected override Avalonia.AppBuilder CustomizeAppBuilder(Avalonia.AppBuilder builder) - { - return base.CustomizeAppBuilder(builder) - .AfterSetup(_ => - { - Pages.EmbedSample.Implementation = new EmbedSampleAndroid(); - }); - } - - protected override void OnCreate(Bundle? savedInstanceState) - { - base.OnCreate(savedInstanceState); - } - - protected override void OnResume() - { - base.OnResume(); - - StartActivity(new Intent(Application.Context, typeof(MainActivity))); - - Finish(); - } - } -} diff --git a/samples/MobileSandbox.Android/MainActivity.cs b/samples/MobileSandbox.Android/MainActivity.cs index d65f0dec92..807afb0bd0 100644 --- a/samples/MobileSandbox.Android/MainActivity.cs +++ b/samples/MobileSandbox.Android/MainActivity.cs @@ -1,12 +1,11 @@ using Android.App; using Android.Content.PM; -using Avalonia; using Avalonia.Android; namespace MobileSandbox.Android { - [Activity(Label = "MobileSandbox.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)] - public class MainActivity : AvaloniaMainActivity + [Activity(Label = "MobileSandbox.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)] + public class MainActivity : AvaloniaMainActivity { } } diff --git a/samples/MobileSandbox.Android/MobileSandbox.Android.csproj b/samples/MobileSandbox.Android/MobileSandbox.Android.csproj index 94f0d31e4d..3b67d79f7b 100644 --- a/samples/MobileSandbox.Android/MobileSandbox.Android.csproj +++ b/samples/MobileSandbox.Android/MobileSandbox.Android.csproj @@ -10,6 +10,12 @@ apk true + + + + + + Resources\drawable\Icon.png @@ -37,6 +43,10 @@ + + + + diff --git a/samples/MobileSandbox.Android/SplashActivity.cs b/samples/MobileSandbox.Android/SplashActivity.cs deleted file mode 100644 index ced092554d..0000000000 --- a/samples/MobileSandbox.Android/SplashActivity.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Android.App; -using Android.Content; -using Avalonia.Android; - -namespace MobileSandbox.Android -{ - [Activity(Theme = "@style/MyTheme.Splash", MainLauncher = true, NoHistory = true)] - public class SplashActivity : AvaloniaSplashActivity - { - protected override void OnResume() - { - base.OnResume(); - - StartActivity(new Intent(Application.Context, typeof(MainActivity))); - } - } -} diff --git a/src/Android/Avalonia.Android/AvaloniaMainActivity.App.cs b/src/Android/Avalonia.Android/AvaloniaMainActivity.App.cs new file mode 100644 index 0000000000..3fcfde3ee4 --- /dev/null +++ b/src/Android/Avalonia.Android/AvaloniaMainActivity.App.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Avalonia.Android +{ + partial class AvaloniaMainActivity where TApp : Application, new() + { + protected virtual AppBuilder CustomizeAppBuilder(AppBuilder builder) => builder.UseAndroid(); + + private static AppBuilder? s_appBuilder; + internal static object ViewContent; + + public object Content + { + get + { + return ViewContent; + } + set + { + ViewContent = value; + if (View != null) + View.Content = value; + } + } + + protected AppBuilder CreateAppBuilder() + { + var builder = AppBuilder.Configure(); + + return CustomizeAppBuilder(builder); + } + + private void InitializeApp() + { + if (s_appBuilder == null) + { + var builder = CreateAppBuilder(); + + builder.SetupWithLifetime(new SingleViewLifetime()); + + s_appBuilder = builder; + } + + View = new AvaloniaView(this); + if (ViewContent != null) + { + View.Content = ViewContent; + } + + if (Avalonia.Application.Current.ApplicationLifetime is SingleViewLifetime lifetime) + { + lifetime.View = View; + } + } + } +} diff --git a/src/Android/Avalonia.Android/AvaloniaMainActivity.cs b/src/Android/Avalonia.Android/AvaloniaMainActivity.cs index b2cd150933..499924d8fb 100644 --- a/src/Android/Avalonia.Android/AvaloniaMainActivity.cs +++ b/src/Android/Avalonia.Android/AvaloniaMainActivity.cs @@ -11,27 +11,49 @@ using AndroidX.AppCompat.App; namespace Avalonia.Android { - public abstract class AvaloniaMainActivity : AppCompatActivity, IActivityResultHandler, IActivityNavigationService + public class AvaloniaMainActivity : AppCompatActivity, IActivityResultHandler, IActivityNavigationService { - internal static object ViewContent; - public Action ActivityResult { get; set; } public Action RequestPermissionsResult { get; set; } + + public event EventHandler BackRequested; + + public override void OnBackPressed() + { + var eventArgs = new AndroidBackRequestedEventArgs(); + + BackRequested?.Invoke(this, eventArgs); + + if (!eventArgs.Handled) + { + base.OnBackPressed(); + } + } + + protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data) + { + base.OnActivityResult(requestCode, resultCode, data); + + ActivityResult?.Invoke(requestCode, resultCode, data); + } + + public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults) + { + base.OnRequestPermissionsResult(requestCode, permissions, grantResults); + + RequestPermissionsResult?.Invoke(requestCode, permissions, grantResults); + } + } + + public abstract partial class AvaloniaMainActivity : AvaloniaMainActivity where TApp : Application, new() + { internal AvaloniaView View; private GlobalLayoutListener _listener; protected override void OnCreate(Bundle savedInstanceState) { - View = new AvaloniaView(this); - if (ViewContent != null) - { - View.Content = ViewContent; - } + InitializeApp(); - if (Avalonia.Application.Current.ApplicationLifetime is SingleViewLifetime lifetime) - { - lifetime.View = View; - } base.OnCreate(savedInstanceState); SetContentView(View); @@ -41,20 +63,6 @@ namespace Avalonia.Android View.ViewTreeObserver?.AddOnGlobalLayoutListener(_listener); } - public object Content - { - get - { - return ViewContent; - } - set - { - ViewContent = value; - if (View != null) - View.Content = value; - } - } - protected override void OnResume() { base.OnResume(); @@ -66,20 +74,6 @@ namespace Avalonia.Android } } - public event EventHandler BackRequested; - - public override void OnBackPressed() - { - var eventArgs = new AndroidBackRequestedEventArgs(); - - BackRequested?.Invoke(this, eventArgs); - - if (!eventArgs.Handled) - { - base.OnBackPressed(); - } - } - protected override void OnDestroy() { View.Content = null; @@ -89,20 +83,6 @@ namespace Avalonia.Android base.OnDestroy(); } - protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data) - { - base.OnActivityResult(requestCode, resultCode, data); - - ActivityResult?.Invoke(requestCode, resultCode, data); - } - - public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults) - { - base.OnRequestPermissionsResult(requestCode, permissions, grantResults); - - RequestPermissionsResult?.Invoke(requestCode, permissions, grantResults); - } - class GlobalLayoutListener : Java.Lang.Object, ViewTreeObserver.IOnGlobalLayoutListener { private AvaloniaView _view; diff --git a/src/Android/Avalonia.Android/AvaloniaSplashActivity.cs b/src/Android/Avalonia.Android/AvaloniaSplashActivity.cs deleted file mode 100644 index 38038ef26c..0000000000 --- a/src/Android/Avalonia.Android/AvaloniaSplashActivity.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Android.OS; -using AndroidX.AppCompat.App; - -namespace Avalonia.Android -{ - public abstract class AvaloniaSplashActivity : AppCompatActivity - { - protected abstract AppBuilder CreateAppBuilder(); - - private static AppBuilder s_appBuilder; - - protected override void OnCreate(Bundle? savedInstanceState) - { - base.OnCreate(savedInstanceState); - - if (s_appBuilder == null) - { - var builder = CreateAppBuilder(); - - var lifetime = new SingleViewLifetime(); - - builder.SetupWithLifetime(lifetime); - - s_appBuilder = builder; - } - } - } - - public abstract class AvaloniaSplashActivity : AvaloniaSplashActivity where TApp : Application, new() - { - protected virtual AppBuilder CustomizeAppBuilder(AppBuilder builder) => builder.UseAndroid(); - - protected override AppBuilder CreateAppBuilder() - { - var builder = AppBuilder.Configure(); - - return CustomizeAppBuilder(builder); - } - } -} From 97f81c6d571f453661206e0c95db73277b89ca81 Mon Sep 17 00:00:00 2001 From: Emmanuel Hansen Date: Tue, 23 May 2023 16:05:03 +0000 Subject: [PATCH 08/43] add animated splash screens for android api 31+ --- .../drawable-night-v31/avalonia_anim.xml | 66 +++++++++++++++++ .../Resources/drawable-v31/avalonia_anim.xml | 71 +++++++++++++++++++ .../Resources/values-v31/styles.xml | 21 ++++++ .../Resources/values/styles.xml | 11 +-- .../drawable-night-v31/avalonia_anim.xml | 66 +++++++++++++++++ .../Resources/drawable-v31/avalonia_anim.xml | 71 +++++++++++++++++++ .../Resources/values-night/colors.xml | 4 ++ .../Resources/values-v31/styles.xml | 16 +++++ .../Resources/values/styles.xml | 7 +- 9 files changed, 317 insertions(+), 16 deletions(-) create mode 100644 samples/ControlCatalog.Android/Resources/drawable-night-v31/avalonia_anim.xml create mode 100644 samples/ControlCatalog.Android/Resources/drawable-v31/avalonia_anim.xml create mode 100644 samples/ControlCatalog.Android/Resources/values-v31/styles.xml create mode 100644 samples/MobileSandbox.Android/Resources/drawable-night-v31/avalonia_anim.xml create mode 100644 samples/MobileSandbox.Android/Resources/drawable-v31/avalonia_anim.xml create mode 100644 samples/MobileSandbox.Android/Resources/values-night/colors.xml create mode 100644 samples/MobileSandbox.Android/Resources/values-v31/styles.xml diff --git a/samples/ControlCatalog.Android/Resources/drawable-night-v31/avalonia_anim.xml b/samples/ControlCatalog.Android/Resources/drawable-night-v31/avalonia_anim.xml new file mode 100644 index 0000000000..dde4b5a7dd --- /dev/null +++ b/samples/ControlCatalog.Android/Resources/drawable-night-v31/avalonia_anim.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/ControlCatalog.Android/Resources/drawable-v31/avalonia_anim.xml b/samples/ControlCatalog.Android/Resources/drawable-v31/avalonia_anim.xml new file mode 100644 index 0000000000..94f27d9e63 --- /dev/null +++ b/samples/ControlCatalog.Android/Resources/drawable-v31/avalonia_anim.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/ControlCatalog.Android/Resources/values-v31/styles.xml b/samples/ControlCatalog.Android/Resources/values-v31/styles.xml new file mode 100644 index 0000000000..d5ecec4391 --- /dev/null +++ b/samples/ControlCatalog.Android/Resources/values-v31/styles.xml @@ -0,0 +1,21 @@ + + + + + + + + diff --git a/samples/ControlCatalog.Android/Resources/values/styles.xml b/samples/ControlCatalog.Android/Resources/values/styles.xml index 3e1270256d..6e534de2f0 100644 --- a/samples/ControlCatalog.Android/Resources/values/styles.xml +++ b/samples/ControlCatalog.Android/Resources/values/styles.xml @@ -6,16 +6,7 @@ - - - - - diff --git a/samples/MobileSandbox.Android/Resources/drawable-night-v31/avalonia_anim.xml b/samples/MobileSandbox.Android/Resources/drawable-night-v31/avalonia_anim.xml new file mode 100644 index 0000000000..dde4b5a7dd --- /dev/null +++ b/samples/MobileSandbox.Android/Resources/drawable-night-v31/avalonia_anim.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/MobileSandbox.Android/Resources/drawable-v31/avalonia_anim.xml b/samples/MobileSandbox.Android/Resources/drawable-v31/avalonia_anim.xml new file mode 100644 index 0000000000..94f27d9e63 --- /dev/null +++ b/samples/MobileSandbox.Android/Resources/drawable-v31/avalonia_anim.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/MobileSandbox.Android/Resources/values-night/colors.xml b/samples/MobileSandbox.Android/Resources/values-night/colors.xml new file mode 100644 index 0000000000..3d47b6fc58 --- /dev/null +++ b/samples/MobileSandbox.Android/Resources/values-night/colors.xml @@ -0,0 +1,4 @@ + + + #212121 + diff --git a/samples/MobileSandbox.Android/Resources/values-v31/styles.xml b/samples/MobileSandbox.Android/Resources/values-v31/styles.xml new file mode 100644 index 0000000000..7518f078e5 --- /dev/null +++ b/samples/MobileSandbox.Android/Resources/values-v31/styles.xml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/samples/MobileSandbox.Android/Resources/values/styles.xml b/samples/MobileSandbox.Android/Resources/values/styles.xml index 2759d2904a..22085806da 100644 --- a/samples/MobileSandbox.Android/Resources/values/styles.xml +++ b/samples/MobileSandbox.Android/Resources/values/styles.xml @@ -6,12 +6,7 @@ - - - From 10941d7686b3e5dbbb18bead44cfc315235513e4 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Tue, 20 Jun 2023 05:20:46 -0400 Subject: [PATCH 09/43] Fix ColorPalette TryGetResource --- .../ColorPaletteResourcesCollection.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Avalonia.Themes.Fluent/ColorPaletteResourcesCollection.cs b/src/Avalonia.Themes.Fluent/ColorPaletteResourcesCollection.cs index 261de5497d..f26f6d8660 100644 --- a/src/Avalonia.Themes.Fluent/ColorPaletteResourcesCollection.cs +++ b/src/Avalonia.Themes.Fluent/ColorPaletteResourcesCollection.cs @@ -30,11 +30,22 @@ internal class ColorPaletteResourcesCollection : AvaloniaDictionary Count > 0; public bool TryGetResource(object key, ThemeVariant? theme, out object? value) { - theme ??= ThemeVariant.Default; - if (base.TryGetValue(theme, out var paletteResources) - && paletteResources.TryGetResource(key, theme, out value)) + if (theme is not null) { - return true; + if (base.TryGetValue(theme, out var themePaletteResources) + && themePaletteResources.TryGetResource(key, theme, out value)) + { + return true; + } + } + + if (theme != ThemeVariant.Default) + { + if (base.TryGetValue(ThemeVariant.Default, out var defaultPaletteResources) + && defaultPaletteResources.TryGetResource(key, ThemeVariant.Default, out value)) + { + return true; + } } value = null; From 9d051a6a64c6039bd8b075c7997468741a78acc8 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 21 Jun 2023 09:39:02 +0200 Subject: [PATCH 10/43] Added failing test for #11484. --- .../AvaloniaObjectTests_Coercion.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Coercion.cs b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Coercion.cs index 42720cbb4c..e664829677 100644 --- a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Coercion.cs +++ b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Coercion.cs @@ -243,6 +243,19 @@ namespace Avalonia.Base.UnitTests Assert.Equal(new[] { 11 }, target.CoerceFooInvocations); } + [Fact] + public void Second_Coerce_Of_Default_Value_Is_Passed_Uncoerced_Value() + { + var target = new Class1(); + + target.MinFoo = 20; + target.CoerceFooInvocations.Clear(); + target.CoerceValue(Class1.FooProperty); + target.CoerceValue(Class1.FooProperty); + + Assert.Equal(new[] { 11, 11 }, target.CoerceFooInvocations); + } + [Fact] public void ClearValue_Respects_Coerced_Default_Value() { From a2d572e006cfd30eb6825f0cf3e33b55cef0e91e Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 21 Jun 2023 09:43:28 +0200 Subject: [PATCH 11/43] Don't set uncoerced value to coerced default val. Fixes #11484 --- src/Avalonia.Base/PropertyStore/EffectiveValue`1.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Base/PropertyStore/EffectiveValue`1.cs b/src/Avalonia.Base/PropertyStore/EffectiveValue`1.cs index 4518289335..a69d7b7094 100644 --- a/src/Avalonia.Base/PropertyStore/EffectiveValue`1.cs +++ b/src/Avalonia.Base/PropertyStore/EffectiveValue`1.cs @@ -216,7 +216,7 @@ namespace Avalonia.PropertyStore valueChanged = !EqualityComparer.Default.Equals(Value, v); Value = v; Priority = priority; - if (_uncommon is not null) + if (!isCoercedDefaultValue && _uncommon is not null) _uncommon._uncoercedValue = value; } @@ -225,7 +225,7 @@ namespace Avalonia.PropertyStore baseValueChanged = !EqualityComparer.Default.Equals(_baseValue, v); _baseValue = v; BasePriority = priority; - if (_uncommon is not null) + if (!isCoercedDefaultValue && _uncommon is not null) _uncommon._uncoercedBaseValue = value; } From 21647102bb620e544220fb116ddeea484f30285f Mon Sep 17 00:00:00 2001 From: Julien Lebosquain Date: Wed, 21 Jun 2023 12:30:49 +0200 Subject: [PATCH 12/43] Fix simple theme for TransitioningContentControl --- .../Controls/TransitioningContentControl.xaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Avalonia.Themes.Simple/Controls/TransitioningContentControl.xaml b/src/Avalonia.Themes.Simple/Controls/TransitioningContentControl.xaml index ceccdf56c7..5f532df848 100644 --- a/src/Avalonia.Themes.Simple/Controls/TransitioningContentControl.xaml +++ b/src/Avalonia.Themes.Simple/Controls/TransitioningContentControl.xaml @@ -13,11 +13,10 @@ BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}" ContentTemplate="{TemplateBinding ContentTemplate}" - Content="{TemplateBinding Content}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" /> - Date: Wed, 21 Jun 2023 15:05:19 +0200 Subject: [PATCH 13/43] First draft --- src/Avalonia.Dialogs/AboutAvaloniaDialog.xaml | 148 +++++++----------- .../AboutAvaloniaDialog.xaml.cs | 5 +- 2 files changed, 62 insertions(+), 91 deletions(-) diff --git a/src/Avalonia.Dialogs/AboutAvaloniaDialog.xaml b/src/Avalonia.Dialogs/AboutAvaloniaDialog.xaml index 22362fa5f5..2bd33ac296 100644 --- a/src/Avalonia.Dialogs/AboutAvaloniaDialog.xaml +++ b/src/Avalonia.Dialogs/AboutAvaloniaDialog.xaml @@ -6,106 +6,74 @@ MinWidth="430" MinHeight="475" Title="About Avalonia" - Background="Purple" FontFamily="/Assets/Roboto-Light.ttf#Roboto" x:Class="Avalonia.Dialogs.AboutAvaloniaDialog" x:DataType="dialogs:AboutAvaloniaDialog"> + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -