From cd180770fbd46ff4f33721ed5ca81f477c72c0db Mon Sep 17 00:00:00 2001 From: Kiminuo Date: Wed, 19 Aug 2020 12:33:14 +0200 Subject: [PATCH 01/37] AppBuilderBase: Allow to specify app factory. --- src/Avalonia.Controls/AppBuilderBase.cs | 17 +++++++ .../AppBuilderTests.cs | 44 ++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Controls/AppBuilderBase.cs b/src/Avalonia.Controls/AppBuilderBase.cs index d69052ad3d..f616a42cac 100644 --- a/src/Avalonia.Controls/AppBuilderBase.cs +++ b/src/Avalonia.Controls/AppBuilderBase.cs @@ -88,6 +88,23 @@ namespace Avalonia.Controls }; } + /// + /// Begin configuring an . + /// + /// Factory function for . + /// The subclass of to configure. + /// is useful for passing of dependencies to . + /// An instance. + public static TAppBuilder Configure(Func appFactory) + where TApp : Application + { + return new TAppBuilder() + { + ApplicationType = typeof(TApp), + _appFactory = appFactory + }; + } + protected TAppBuilder Self => (TAppBuilder)this; public TAppBuilder AfterSetup(Action callback) diff --git a/tests/Avalonia.Controls.UnitTests/AppBuilderTests.cs b/tests/Avalonia.Controls.UnitTests/AppBuilderTests.cs index b5004bc6a5..06ec9158fe 100644 --- a/tests/Avalonia.Controls.UnitTests/AppBuilderTests.cs +++ b/tests/Avalonia.Controls.UnitTests/AppBuilderTests.cs @@ -1,4 +1,5 @@ -using Avalonia.Controls.UnitTests; +using System; +using Avalonia.Controls.UnitTests; using Avalonia.Platform; using Xunit; @@ -18,6 +19,22 @@ namespace Avalonia.Controls.UnitTests { } + public class AppWithDependencies : Application + { + public AppWithDependencies() + { + throw new NotSupportedException(); + } + + public AppWithDependencies(object dependencyA, object dependencyB) + { + DependencyA = dependencyA; + DependencyB = dependencyB; + } + public object DependencyA { get; } + public object DependencyB { get; } + } + public class DefaultModule { public static bool IsLoaded = false; @@ -53,7 +70,30 @@ namespace Avalonia.Controls.UnitTests IsLoaded = true; } } - + + [Fact] + public void UseAppFactory() + { + using (AvaloniaLocator.EnterScope()) + { + ResetModuleLoadStates(); + + Func appFactory = () => new AppWithDependencies(dependencyA: new object(), dependencyB: new object()); + + var builder = AppBuilder.Configure(appFactory) + .UseWindowingSubsystem(() => { }) + .UseRenderingSubsystem(() => { }) + .UseAvaloniaModules() + .SetupWithoutStarting(); + + AppWithDependencies app = (AppWithDependencies)builder.Instance; + Assert.NotNull(app.DependencyA); + Assert.NotNull(app.DependencyB); + + Assert.True(DefaultModule.IsLoaded); + } + } + [Fact] public void LoadsDefaultModule() { From 0706c8217605c2a4e1ad2fcc1ae3924a653c896c Mon Sep 17 00:00:00 2001 From: Jumar Macato Date: Wed, 19 Aug 2020 21:48:32 +0800 Subject: [PATCH 02/37] Fix Missing CaretBrush on DefaultTheme's TextBox --- src/Avalonia.Themes.Default/TextBox.xaml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Avalonia.Themes.Default/TextBox.xaml b/src/Avalonia.Themes.Default/TextBox.xaml index 8384cccada..9c1914de66 100644 --- a/src/Avalonia.Themes.Default/TextBox.xaml +++ b/src/Avalonia.Themes.Default/TextBox.xaml @@ -1,5 +1,6 @@ + TextBox A control into which the user can input text - + - + - + - + - - - + + + - - resm fonts - - - - - - - - res fonts - - - - - + + resm fonts + + + + + + + + res fonts + + + + + diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index 559932bf80..d803d03258 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -1,3 +1,4 @@ +using System.Windows.Input; using Avalonia.Input.Platform; using System; using System.Collections.Generic; @@ -103,6 +104,21 @@ namespace Avalonia.Controls public static readonly StyledProperty RevealPasswordProperty = AvaloniaProperty.Register(nameof(RevealPassword)); + + public static readonly DirectProperty CanCutProperty = + AvaloniaProperty.RegisterDirect( + nameof(CanCut), + o => o.CanCut); + + public static readonly DirectProperty CanCopyProperty = + AvaloniaProperty.RegisterDirect( + nameof(CanCopy), + o => o.CanCopy); + + public static readonly DirectProperty CanPasteProperty = + AvaloniaProperty.RegisterDirect( + nameof(CanPaste), + o => o.CanPaste); struct UndoRedoState : IEquatable { @@ -126,6 +142,9 @@ namespace Avalonia.Controls private UndoRedoHelper _undoRedoHelper; private bool _isUndoingRedoing; private bool _ignoreTextChanges; + private bool _canCut; + private bool _canCopy; + private bool _canPaste; private string _newLine = Environment.NewLine; private static readonly string[] invalidCharacters = new String[1] { "\u007f" }; @@ -378,6 +397,33 @@ namespace Avalonia.Controls SelectionStart = SelectionEnd = CaretIndex; } + /// + /// Property for determining if the Cut command can be executed. + /// + public bool CanCut + { + get { return _canCut; } + private set { SetAndRaise(CanCutProperty, ref _canCut, value); } + } + + /// + /// Property for determining if the Copy command can be executed. + /// + public bool CanCopy + { + get { return _canCopy; } + private set { SetAndRaise(CanCopyProperty, ref _canCopy, value); } + } + + /// + /// Property for determining if the Paste command can be executed. + /// + public bool CanPaste + { + get { return _canPaste; } + private set { SetAndRaise(CanPasteProperty, ref _canPaste, value); } + } + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { _presenter = e.NameScope.Get("PART_TextPresenter"); @@ -395,9 +441,19 @@ namespace Avalonia.Controls if (change.Property == TextProperty) { UpdatePseudoclasses(); + UpdateCommandStates(); } } + private void UpdateCommandStates() + { + var text = GetSelection(); + var b1 = string.IsNullOrEmpty(text); + CanCopy = !b1; + CanCut = !b1; + CanPaste = !IsReadOnly; + } + protected override void OnGotFocus(GotFocusEventArgs e) { base.OnGotFocus(e); @@ -412,6 +468,8 @@ namespace Avalonia.Controls SelectAll(); } + UpdateCommandStates(); + _presenter?.ShowCaret(); } @@ -425,6 +483,8 @@ namespace Avalonia.Controls RevealPassword = false; } + UpdateCommandStates(); + _presenter?.HideCaret(); } @@ -469,6 +529,9 @@ namespace Avalonia.Controls public async void Cut() { + var text = GetSelection(); + if (text is null) return; + _undoRedoHelper.Snapshot(); Copy(); DeleteSelection(); @@ -477,17 +540,18 @@ namespace Avalonia.Controls public async void Copy() { + var text = GetSelection(); + if (text is null) return; + await ((IClipboard)AvaloniaLocator.Current.GetService(typeof(IClipboard))) - .SetTextAsync(GetSelection()); + .SetTextAsync(text); } public async void Paste() { var text = await ((IClipboard)AvaloniaLocator.Current.GetService(typeof(IClipboard))).GetTextAsync(); - if (text == null) - { - return; - } + + if (text is null) return; _undoRedoHelper.Snapshot(); HandleTextInput(text); From 6f96ef6fbd45889f657f4877181ae932617aacf9 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 18 Aug 2020 15:14:56 +0100 Subject: [PATCH 18/37] add gesture text. --- samples/ControlCatalog/Pages/TextBoxPage.xaml | 6 +++--- src/Avalonia.Controls/TextBox.cs | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/samples/ControlCatalog/Pages/TextBoxPage.xaml b/samples/ControlCatalog/Pages/TextBoxPage.xaml index 88094c70f3..5317e46e81 100644 --- a/samples/ControlCatalog/Pages/TextBoxPage.xaml +++ b/samples/ControlCatalog/Pages/TextBoxPage.xaml @@ -3,9 +3,9 @@ - - - + + + diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index d803d03258..7a3afbb718 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -19,6 +19,15 @@ namespace Avalonia.Controls { public class TextBox : TemplatedControl, UndoRedoHelper.IUndoRedoHost { + public static KeyGesture CutGesture { get; } = + AvaloniaLocator.Current.GetService()?.Cut.FirstOrDefault(); + + public static KeyGesture CopyGesture { get; } = AvaloniaLocator.Current + .GetService()?.Copy.FirstOrDefault(); + + public static KeyGesture PasteGesture { get; } = AvaloniaLocator.Current + .GetService()?.Paste.FirstOrDefault(); + public static readonly StyledProperty AcceptsReturnProperty = AvaloniaProperty.Register(nameof(AcceptsReturn)); From a82cd0012239ceee4689f0e1ac5666ed8186af79 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 18 Aug 2020 15:15:22 +0100 Subject: [PATCH 19/37] move standard textbox context menu to the templates. --- samples/ControlCatalog/Pages/TextBoxPage.xaml | 12 ------------ src/Avalonia.Themes.Default/TextBox.xaml | 8 ++++++++ src/Avalonia.Themes.Fluent/TextBox.xaml | 7 +++++++ 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/samples/ControlCatalog/Pages/TextBoxPage.xaml b/samples/ControlCatalog/Pages/TextBoxPage.xaml index 5317e46e81..df410c2116 100644 --- a/samples/ControlCatalog/Pages/TextBoxPage.xaml +++ b/samples/ControlCatalog/Pages/TextBoxPage.xaml @@ -1,18 +1,6 @@ - - - - - - - - - - TextBox A control into which the user can input text diff --git a/src/Avalonia.Themes.Default/TextBox.xaml b/src/Avalonia.Themes.Default/TextBox.xaml index 9c1914de66..87e900508c 100644 --- a/src/Avalonia.Themes.Default/TextBox.xaml +++ b/src/Avalonia.Themes.Default/TextBox.xaml @@ -1,4 +1,11 @@ + + + + + + +