From 43b94e997c9aa77b004480962e4ee34c8f2742b7 Mon Sep 17 00:00:00 2001 From: Jumar Macato Date: Tue, 18 Aug 2020 17:28:13 +0800 Subject: [PATCH 1/6] Expose Cut Copy and Paste methods for binding for context menus --- src/Avalonia.Controls/TextBox.cs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index 4e742b3b7b..86f66fa90d 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -417,7 +417,7 @@ namespace Avalonia.Controls SelectionEnd = 0; RevealPassword = false; } - + _presenter?.HideCaret(); } @@ -460,13 +460,21 @@ namespace Avalonia.Controls return text; } - private async void Copy() + public async void Cut() + { + _undoRedoHelper.Snapshot(); + Copy(); + DeleteSelection(); + _undoRedoHelper.Snapshot(); + } + + public async void Copy() { await ((IClipboard)AvaloniaLocator.Current.GetService(typeof(IClipboard))) .SetTextAsync(GetSelection()); } - private async void Paste() + public async void Paste() { var text = await ((IClipboard)AvaloniaLocator.Current.GetService(typeof(IClipboard))).GetTextAsync(); if (text == null) @@ -511,23 +519,18 @@ namespace Avalonia.Controls { if (!IsPasswordBox) { - _undoRedoHelper.Snapshot(); - Copy(); - DeleteSelection(); - _undoRedoHelper.Snapshot(); + Cut(); } handled = true; } else if (Match(keymap.Paste)) { - Paste(); handled = true; } else if (Match(keymap.Undo)) { - try { _isUndoingRedoing = true; From fb75a836be99b012b159243db55119e391fa3b02 Mon Sep 17 00:00:00 2001 From: Jumar Macato Date: Tue, 18 Aug 2020 19:00:19 +0800 Subject: [PATCH 2/6] add context menu --- samples/ControlCatalog/Pages/TextBoxPage.xaml | 74 +++++++++---------- src/Avalonia.Controls/TextBox.cs | 74 +++++++++++++++++-- 2 files changed, 104 insertions(+), 44 deletions(-) diff --git a/samples/ControlCatalog/Pages/TextBoxPage.xaml b/samples/ControlCatalog/Pages/TextBoxPage.xaml index 481a459159..88094c70f3 100644 --- a/samples/ControlCatalog/Pages/TextBoxPage.xaml +++ b/samples/ControlCatalog/Pages/TextBoxPage.xaml @@ -1,61 +1,57 @@ + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="ControlCatalog.Pages.TextBoxPage"> + + + + + + + + + + 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 86f66fa90d..7798c71377 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" }; @@ -370,6 +389,33 @@ namespace Avalonia.Controls set { SetAndRaise(NewLineProperty, ref _newLine, value); } } + /// + /// 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"); @@ -387,9 +433,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); @@ -404,6 +460,8 @@ namespace Avalonia.Controls SelectAll(); } + UpdateCommandStates(); + _presenter?.ShowCaret(); } @@ -418,6 +476,8 @@ namespace Avalonia.Controls RevealPassword = false; } + UpdateCommandStates(); + _presenter?.HideCaret(); } @@ -462,6 +522,9 @@ namespace Avalonia.Controls public async void Cut() { + var text = GetSelection(); + if (text is null) return; + _undoRedoHelper.Snapshot(); Copy(); DeleteSelection(); @@ -470,17 +533,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 e93ac83ae43b9a2b88311cc11c8e2aa793b3eab5 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 18 Aug 2020 15:14:56 +0100 Subject: [PATCH 3/6] 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 7798c71377..3b81b5b020 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 5ea8c57f760e755edd03d12f06c13bfda5f2f1f1 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 18 Aug 2020 15:15:22 +0100 Subject: [PATCH 4/6] 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 8384cccada..e9d5857d67 100644 --- a/src/Avalonia.Themes.Default/TextBox.xaml +++ b/src/Avalonia.Themes.Default/TextBox.xaml @@ -1,4 +1,11 @@ + + + + + + +