From 64ee636489f211b35b2f9974cb97ba3ec7d67008 Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Tue, 19 Apr 2022 15:02:01 -0700 Subject: [PATCH 1/5] Fix focus on rename UI opening --- .../CommandHandlers/RenameCommandHandler.cs | 34 +++++++++++-------- .../Adornment/InlineRenameAdornment.xaml.cs | 8 +++-- .../AbstractRenameCommandHandler.cs | 8 ++--- ...tractRenameCommandHandler_RenameHandler.cs | 2 +- ...AbstractRenameCommandHandler_TabHandler.cs | 8 ++--- 5 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs b/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs index 586f40a466758..bb280e6b15d8b 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs @@ -13,6 +13,8 @@ using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Extensions; using Microsoft.CodeAnalysis.Telemetry; +using Microsoft.VisualStudio.Shell.Interop; +using System.Windows; #if !COCOA using System.Linq; @@ -41,39 +43,41 @@ public RenameCommandHandler(IThreadingContext threadingContext, InlineRenameServ } #if !COCOA - protected override bool DashboardShouldReceiveKeyboardNavigation(ITextView textView) - => GetDashboard(textView) is { } dashboard && dashboard.ShouldReceiveKeyboardNavigation; + protected override bool AdornmentShouldReceiveKeyboardNavigation(ITextView textView) + => GetAdornment(textView) is Dashboard dashboard + ? dashboard.ShouldReceiveKeyboardNavigation + : true; // Always receive keyboard navigation for the inline adornment protected override void SetFocusToTextView(ITextView textView) { (textView as IWpfTextView)?.VisualElement.Focus(); } - protected override void SetFocusToDashboard(ITextView textView) + protected override void SetFocusToAdornment(ITextView textView) { - if (GetDashboard(textView) is { } dashboard) + if (GetAdornment(textView) is UIElement adornment) { - dashboard.Focus(); + adornment.Focus(); } } - protected override void SetDashboardFocusToNextElement(ITextView textView) + protected override void SetAdornmentFocusToNextElement(ITextView textView) { - if (GetDashboard(textView) is { } dashboard) + if (GetAdornment(textView) is Dashboard dashboard) { dashboard.FocusNextElement(); } } - protected override void SetDashboardFocusToPreviousElement(ITextView textView) + protected override void SetAdornmentFocusToPreviousElement(ITextView textView) { - if (GetDashboard(textView) is { } dashboard) + if (GetAdornment(textView) is Dashboard dashboard) { dashboard.FocusNextElement(); } } - private static Dashboard? GetDashboard(ITextView textView) + private static UIElement? GetAdornment(ITextView textView) { // If our adornment layer somehow didn't get composed, GetAdornmentLayer will throw. // Don't crash if that happens. @@ -81,7 +85,7 @@ protected override void SetDashboardFocusToPreviousElement(ITextView textView) { var adornment = ((IWpfTextView)textView).GetAdornmentLayer("RoslynRenameDashboard"); return adornment.Elements.Any() - ? adornment.Elements[0].Adornment as Dashboard + ? adornment.Elements[0].Adornment : null; } catch (ArgumentOutOfRangeException) @@ -124,7 +128,7 @@ protected override void Commit(InlineRenameSession activeSession, ITextView text } } #else - protected override bool DashboardShouldReceiveKeyboardNavigation(ITextView textView) + protected override bool AdornmentShouldReceiveKeyboardNavigation(ITextView textView) => false; protected override void SetFocusToTextView(ITextView textView) @@ -132,17 +136,17 @@ protected override void SetFocusToTextView(ITextView textView) // No action taken for Cocoa } - protected override void SetFocusToDashboard(ITextView textView) + protected override void SetFocusToAdornment(ITextView textView) { // No action taken for Cocoa } - protected override void SetDashboardFocusToNextElement(ITextView textView) + protected override void SetAdornmentFocusToNextElement(ITextView textView) { // No action taken for Cocoa } - protected override void SetDashboardFocusToPreviousElement(ITextView textView) + protected override void SetAdornmentFocusToPreviousElement(ITextView textView) { // No action taken for Cocoa } diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornment.xaml.cs b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornment.xaml.cs index 9138e5550fa4a..eb78f081cc65f 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornment.xaml.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornment.xaml.cs @@ -29,8 +29,12 @@ public InlineRenameAdornment(InlineRenameAdornmentViewModel viewModel, ITextView _textView.LostAggregateFocus += TextView_LostFocus; _textView.Caret.PositionChanged += TextView_CursorChanged; - // On initialization focus the first tab target - Initialized += (s, e) => MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); + // On load focus the first tab target + Loaded += (s, e) => + { + Focus(); + MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); + }; InitializeComponent(); PositionAdornment(); diff --git a/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler.cs b/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler.cs index 22d0027ba9c8f..908ed357152ff 100644 --- a/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler.cs +++ b/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler.cs @@ -28,15 +28,15 @@ protected AbstractRenameCommandHandler( public string DisplayName => EditorFeaturesResources.Rename; - protected abstract bool DashboardShouldReceiveKeyboardNavigation(ITextView textView); + protected abstract bool AdornmentShouldReceiveKeyboardNavigation(ITextView textView); protected abstract void SetFocusToTextView(ITextView textView); - protected abstract void SetFocusToDashboard(ITextView textView); + protected abstract void SetFocusToAdornment(ITextView textView); - protected abstract void SetDashboardFocusToPreviousElement(ITextView textView); + protected abstract void SetAdornmentFocusToPreviousElement(ITextView textView); - protected abstract void SetDashboardFocusToNextElement(ITextView textView); + protected abstract void SetAdornmentFocusToNextElement(ITextView textView); private CommandState GetCommandState(Func nextHandler) { diff --git a/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler_RenameHandler.cs b/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler_RenameHandler.cs index 822784904259d..d762156c45e02 100644 --- a/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler_RenameHandler.cs +++ b/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler_RenameHandler.cs @@ -67,7 +67,7 @@ private void ExecuteRenameWorker(RenameCommandArgs args, CommandExecutionContext // If so, focus the dashboard if (_renameService.ActiveSession.TryGetContainingEditableSpan(caretPoint.Value, out _)) { - SetFocusToDashboard(args.TextView); + SetFocusToAdornment(args.TextView); return; } else diff --git a/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler_TabHandler.cs b/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler_TabHandler.cs index aa56c00d35c4e..82b8e618a0d01 100644 --- a/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler_TabHandler.cs +++ b/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler_TabHandler.cs @@ -20,9 +20,9 @@ public CommandState GetCommandState(TabKeyCommandArgs args, Func n public void ExecuteCommand(TabKeyCommandArgs args, Action nextHandler, CommandExecutionContext context) { // If the Dashboard is focused, just navigate through its UI. - if (DashboardShouldReceiveKeyboardNavigation(args.TextView)) + if (AdornmentShouldReceiveKeyboardNavigation(args.TextView)) { - SetDashboardFocusToNextElement(args.TextView); + SetAdornmentFocusToNextElement(args.TextView); return; } @@ -52,9 +52,9 @@ public CommandState GetCommandState(BackTabKeyCommandArgs args, Func Date: Wed, 20 Apr 2022 15:39:15 -0700 Subject: [PATCH 2/5] Remove uneeded using --- .../InlineRename/CommandHandlers/RenameCommandHandler.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs b/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs index bb280e6b15d8b..157dc99b1a949 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs @@ -13,7 +13,6 @@ using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Extensions; using Microsoft.CodeAnalysis.Telemetry; -using Microsoft.VisualStudio.Shell.Interop; using System.Windows; #if !COCOA From b0c78f7a1b5c95397c0548d2e9c211add6074259 Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Fri, 29 Apr 2022 14:33:24 -0700 Subject: [PATCH 3/5] Fix typing, namespace, and naming to better reflect the architecture --- .../CommandHandlers/RenameCommandHandler.cs | 12 +++++----- ...RenameAdornment.xaml => RenameFlyout.xaml} | 3 +-- ...Adornment.xaml.cs => RenameFlyout.xaml.cs} | 8 +++---- ...tViewModel.cs => RenameFlyoutViewModel.cs} | 6 ++--- .../{Dashboard.xaml => RenameDashboard.xaml} | 9 ++++---- ...hboard.xaml.cs => RenameDashboard.xaml.cs} | 12 +++++----- ...er.cs => RenameDashboardAutomationPeer.cs} | 4 ++-- ...Severity.cs => RenameDashboardSeverity.cs} | 2 +- ...ewModel.cs => RenameDashboardViewModel.cs} | 14 ++++++------ .../InlineRename/UI/InlineRenameAdornment.cs | 18 +++++++++++++++ .../UI/InlineRenameAdornmentManager.cs | 11 +++++----- .../Test2/Rename/DashboardTests.vb | 22 +++++++++---------- .../Test2/Rename/RenameCommandHandlerTests.vb | 2 +- 13 files changed, 69 insertions(+), 54 deletions(-) rename src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/{InlineRenameAdornment.xaml => RenameFlyout.xaml} (97%) rename src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/{InlineRenameAdornment.xaml.cs => RenameFlyout.xaml.cs} (94%) rename src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/{InlineRenameAdornmentViewModel.cs => RenameFlyoutViewModel.cs} (97%) rename src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/{Dashboard.xaml => RenameDashboard.xaml} (98%) rename src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/{Dashboard.xaml.cs => RenameDashboard.xaml.cs} (98%) rename src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/{DashboardAutomationPeer.cs => RenameDashboardAutomationPeer.cs} (85%) rename src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/{DashboardSeverity.cs => RenameDashboardSeverity.cs} (89%) rename src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/{DashboardViewModel.cs => RenameDashboardViewModel.cs} (95%) create mode 100644 src/EditorFeatures/Core.Wpf/InlineRename/UI/InlineRenameAdornment.cs diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs b/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs index 157dc99b1a949..96a15b5f339b7 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs @@ -43,7 +43,7 @@ public RenameCommandHandler(IThreadingContext threadingContext, InlineRenameServ #if !COCOA protected override bool AdornmentShouldReceiveKeyboardNavigation(ITextView textView) - => GetAdornment(textView) is Dashboard dashboard + => GetAdornment(textView) is RenameDashboard dashboard ? dashboard.ShouldReceiveKeyboardNavigation : true; // Always receive keyboard navigation for the inline adornment @@ -54,7 +54,7 @@ protected override void SetFocusToTextView(ITextView textView) protected override void SetFocusToAdornment(ITextView textView) { - if (GetAdornment(textView) is UIElement adornment) + if (GetAdornment(textView) is { } adornment) { adornment.Focus(); } @@ -62,7 +62,7 @@ protected override void SetFocusToAdornment(ITextView textView) protected override void SetAdornmentFocusToNextElement(ITextView textView) { - if (GetAdornment(textView) is Dashboard dashboard) + if (GetAdornment(textView) is RenameDashboard dashboard) { dashboard.FocusNextElement(); } @@ -70,13 +70,13 @@ protected override void SetAdornmentFocusToNextElement(ITextView textView) protected override void SetAdornmentFocusToPreviousElement(ITextView textView) { - if (GetAdornment(textView) is Dashboard dashboard) + if (GetAdornment(textView) is RenameDashboard dashboard) { dashboard.FocusNextElement(); } } - private static UIElement? GetAdornment(ITextView textView) + private static InlineRenameAdornment? GetAdornment(ITextView textView) { // If our adornment layer somehow didn't get composed, GetAdornmentLayer will throw. // Don't crash if that happens. @@ -84,7 +84,7 @@ protected override void SetAdornmentFocusToPreviousElement(ITextView textView) { var adornment = ((IWpfTextView)textView).GetAdornmentLayer("RoslynRenameDashboard"); return adornment.Elements.Any() - ? adornment.Elements[0].Adornment + ? adornment.Elements[0].Adornment as InlineRenameAdornment : null; } catch (ArgumentOutOfRangeException) diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornment.xaml b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/RenameFlyout.xaml similarity index 97% rename from src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornment.xaml rename to src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/RenameFlyout.xaml index a1dd57a5407e6..15ca5f9e88dd2 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornment.xaml +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/RenameFlyout.xaml @@ -1,10 +1,9 @@ - /// Interaction logic for InlineRenameAdornment.xaml /// - internal partial class InlineRenameAdornment : UserControl, IDisposable + internal partial class RenameFlyout : UserControl, IDisposable { - private readonly InlineRenameAdornmentViewModel _viewModel; + private readonly RenameFlyoutViewModel _viewModel; private readonly ITextView _textView; - public InlineRenameAdornment(InlineRenameAdornmentViewModel viewModel, ITextView textView) + public RenameFlyout(RenameFlyoutViewModel viewModel, ITextView textView) { DataContext = _viewModel = viewModel; _textView = textView; diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornmentViewModel.cs b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/RenameFlyoutViewModel.cs similarity index 97% rename from src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornmentViewModel.cs rename to src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/RenameFlyoutViewModel.cs index c9932ebf66ef6..91b9e5d33d184 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornmentViewModel.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/RenameFlyoutViewModel.cs @@ -14,16 +14,16 @@ using Microsoft.CodeAnalysis.Rename; using Microsoft.VisualStudio.PlatformUI.OleComponentSupport; -namespace Microsoft.CodeAnalysis.Editor.InlineRename.Adornment +namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename { - internal class InlineRenameAdornmentViewModel : INotifyPropertyChanged, IDisposable + internal class RenameFlyoutViewModel : INotifyPropertyChanged, IDisposable { private readonly InlineRenameSession _session; private OleComponent? _oleComponent; private bool _disposedValue; public event PropertyChangedEventHandler? PropertyChanged; - public InlineRenameAdornmentViewModel(InlineRenameSession session) + public RenameFlyoutViewModel(InlineRenameSession session) { _session = session; _session.ReplacementTextChanged += OnReplacementTextChanged; diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/Dashboard.xaml b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/RenameDashboard.xaml similarity index 98% rename from src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/Dashboard.xaml rename to src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/RenameDashboard.xaml index f0a17489c9676..0cbe0c93e247f 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/Dashboard.xaml +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/RenameDashboard.xaml @@ -1,5 +1,4 @@ - - + @@ -47,7 +46,7 @@ Stretch="Uniform" Data="F1 M 0,0L 2,0L 5,3L 8,0L 10,0L 6,4L 10,8L 8,8L 5,5L 2,8L 0,8L 4,4L 0,0 Z" /> - + @@ -252,4 +251,4 @@ - + diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/Dashboard.xaml.cs b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/RenameDashboard.xaml.cs similarity index 98% rename from src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/Dashboard.xaml.cs rename to src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/RenameDashboard.xaml.cs index 33391dd5aa541..7d64068ea639e 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/Dashboard.xaml.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/RenameDashboard.xaml.cs @@ -22,9 +22,9 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename { - internal partial class Dashboard : UserControl, IDisposable + internal partial class RenameDashboard : InlineRenameAdornment { - private readonly DashboardViewModel _model; + private readonly RenameDashboardViewModel _model; private readonly IWpfTextView _textView; private readonly IAdornmentLayer _findAdornmentLayer; private PresentationSource _presentationSource; @@ -45,8 +45,8 @@ internal partial class Dashboard : UserControl, IDisposable RenameShortcutKey.PreviewChanges }; - public Dashboard( - DashboardViewModel model, + public RenameDashboard( + RenameDashboardViewModel model, IEditorFormatMapService editorFormatMapService, IWpfTextView textView) { @@ -253,7 +253,7 @@ protected override void OnAccessKey(AccessKeyEventArgs e) } protected override AutomationPeer OnCreateAutomationPeer() - => new DashboardAutomationPeer(this, _model.OriginalName); + => new RenameDashboardAutomationPeer(this, _model.OriginalName); private void DisconnectFromPresentationSource() { @@ -363,7 +363,7 @@ private void Commit() } } - public void Dispose() + public override void Dispose() { _textView.GotAggregateFocus -= OnTextViewGotAggregateFocus; _textView.LostAggregateFocus -= OnTextViewLostAggregateFocus; diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/DashboardAutomationPeer.cs b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/RenameDashboardAutomationPeer.cs similarity index 85% rename from src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/DashboardAutomationPeer.cs rename to src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/RenameDashboardAutomationPeer.cs index a4c917b22f663..7d255741224b1 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/DashboardAutomationPeer.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/RenameDashboardAutomationPeer.cs @@ -12,11 +12,11 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename /// /// Custom AutomationPeer to announce that an Inline Rename session has begun. /// - internal class DashboardAutomationPeer : UserControlAutomationPeer + internal class RenameDashboardAutomationPeer : UserControlAutomationPeer { private readonly string _identifier; - public DashboardAutomationPeer(UserControl owner, string identifier) : base(owner) + public RenameDashboardAutomationPeer(UserControl owner, string identifier) : base(owner) => _identifier = identifier; protected override bool HasKeyboardFocusCore() diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/DashboardSeverity.cs b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/RenameDashboardSeverity.cs similarity index 89% rename from src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/DashboardSeverity.cs rename to src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/RenameDashboardSeverity.cs index bb77e09dbc0c6..2c55c302d9d89 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/DashboardSeverity.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/RenameDashboardSeverity.cs @@ -6,7 +6,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename { - internal enum DashboardSeverity + internal enum RenameDashboardSeverity { None, Info, diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/DashboardViewModel.cs b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/RenameDashboardViewModel.cs similarity index 95% rename from src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/DashboardViewModel.cs rename to src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/RenameDashboardViewModel.cs index 9578fd2a2fcc8..c452cfa5cb78c 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/DashboardViewModel.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/RenameDashboardViewModel.cs @@ -15,18 +15,18 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename { - internal class DashboardViewModel : INotifyPropertyChanged, IDisposable + internal class RenameDashboardViewModel : INotifyPropertyChanged, IDisposable { private readonly InlineRenameSession _session; - private DashboardSeverity _severity = DashboardSeverity.None; + private RenameDashboardSeverity _severity = RenameDashboardSeverity.None; private string _searchText; private int _resolvableConflictCount; private int _unresolvableConflictCount; private string _errorText; private bool _isReplacementTextValid; - public DashboardViewModel(InlineRenameSession session) + public RenameDashboardViewModel(InlineRenameSession session) { _session = session; _searchText = EditorFeaturesResources.Searching; @@ -141,21 +141,21 @@ private void UpdateSeverity() if (_errorText != null || _unresolvableConflictCount > 0) { - _severity = DashboardSeverity.Error; + _severity = RenameDashboardSeverity.Error; } else if (_resolvableConflictCount > 0) { - _severity = DashboardSeverity.Info; + _severity = RenameDashboardSeverity.Info; } else { - _severity = DashboardSeverity.None; + _severity = RenameDashboardSeverity.None; } } public InlineRenameSession Session => _session; - public DashboardSeverity Severity => _severity; + public RenameDashboardSeverity Severity => _severity; public bool AllowFileRename => _session.FileRenameInfo == InlineRenameFileRenameInfo.Allowed && _isReplacementTextValid; public bool ShowFileRename => _session.FileRenameInfo != InlineRenameFileRenameInfo.NotAllowed; diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/UI/InlineRenameAdornment.cs b/src/EditorFeatures/Core.Wpf/InlineRename/UI/InlineRenameAdornment.cs new file mode 100644 index 0000000000000..58e5e9d917ce5 --- /dev/null +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/InlineRenameAdornment.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; + +namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename +{ + internal abstract class InlineRenameAdornment : UserControl, IDisposable + { + public abstract void Dispose(); + } +} diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/UI/InlineRenameAdornmentManager.cs b/src/EditorFeatures/Core.Wpf/InlineRename/UI/InlineRenameAdornmentManager.cs index 2b7ba9ad31710..d02febbe2b0fd 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/UI/InlineRenameAdornmentManager.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/InlineRenameAdornmentManager.cs @@ -7,7 +7,6 @@ using System.Runtime.CompilerServices; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor.InlineRename; -using Microsoft.CodeAnalysis.Editor.InlineRename.Adornment; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.Text.Classification; @@ -72,8 +71,8 @@ private void UpdateAdornments() var useInlineAdornment = _globalOptionService.GetOption(InlineRenameExperimentationOptions.UseInlineAdornment); if (useInlineAdornment) { - var adornment = new InlineRenameAdornment( - (InlineRenameAdornmentViewModel)s_createdViewModels.GetValue(_renameService.ActiveSession, session => new InlineRenameAdornmentViewModel(session)), + var adornment = new RenameFlyout( + (RenameFlyoutViewModel)s_createdViewModels.GetValue(_renameService.ActiveSession, session => new RenameFlyoutViewModel(session)), _textView); _adornmentLayer.AddAdornment( @@ -85,13 +84,13 @@ private void UpdateAdornments() } else { - var newAdornment = new Dashboard( - (DashboardViewModel)s_createdViewModels.GetValue(_renameService.ActiveSession, session => new DashboardViewModel(session)), + var newAdornment = new RenameDashboard( + (RenameDashboardViewModel)s_createdViewModels.GetValue(_renameService.ActiveSession, session => new RenameDashboardViewModel(session)), _editorFormatMapService, _textView); _adornmentLayer.AddAdornment(AdornmentPositioningBehavior.ViewportRelative, null, null, newAdornment, - (tag, adornment) => ((Dashboard)adornment).Dispose()); + (tag, adornment) => ((RenameDashboard)adornment).Dispose()); } } } diff --git a/src/EditorFeatures/Test2/Rename/DashboardTests.vb b/src/EditorFeatures/Test2/Rename/DashboardTests.vb index eee1bf947cd4f..6a1906fa21596 100644 --- a/src/EditorFeatures/Test2/Rename/DashboardTests.vb +++ b/src/EditorFeatures/Test2/Rename/DashboardTests.vb @@ -96,7 +96,7 @@ class Program renameOverloads:=True, hasRenameOverload:=True, unresolvableConflictText:=String.Format(EditorFeaturesResources._0_unresolvable_conflict_s, 1), - severity:=DashboardSeverity.Error) + severity:=RenameDashboardSeverity.Error) End Function @@ -116,7 +116,7 @@ class AttributeAttribute : System.Attribute { } newName:="AttributeAttributeAttribute", searchResultText:=EditorFeaturesResources.Rename_will_update_1_reference_in_1_file, resolvableConflictText:=String.Format(EditorFeaturesResources._0_conflict_s_will_be_resolved, 1), - severity:=DashboardSeverity.Info) + severity:=RenameDashboardSeverity.Info) End Function @@ -334,7 +334,7 @@ class $$Program newName:="goo", searchResultText:=String.Format(EditorFeaturesResources.Rename_will_update_0_references_in_1_file, 2), resolvableConflictText:=String.Format(EditorFeaturesResources._0_conflict_s_will_be_resolved, 1), - severity:=DashboardSeverity.Info) + severity:=RenameDashboardSeverity.Info) End Function @@ -359,7 +359,7 @@ class $$Program newName:="goo", searchResultText:=String.Format(EditorFeaturesResources.Rename_will_update_0_references_in_1_file, 2), resolvableConflictText:=String.Format(EditorFeaturesResources._0_conflict_s_will_be_resolved, 2), - severity:=DashboardSeverity.Info) + severity:=RenameDashboardSeverity.Info) End Function @@ -382,7 +382,7 @@ class $$Program newName:="goo", searchResultText:=EditorFeaturesResources.Rename_will_update_1_reference_in_1_file, unresolvableConflictText:=String.Format(EditorFeaturesResources._0_unresolvable_conflict_s, 1), - severity:=DashboardSeverity.Error) + severity:=RenameDashboardSeverity.Error) End Function @@ -407,7 +407,7 @@ class $$Program newName:="goo", searchResultText:=String.Format(EditorFeaturesResources.Rename_will_update_0_references_in_1_file, 3), unresolvableConflictText:=String.Format(EditorFeaturesResources._0_unresolvable_conflict_s, 3), - severity:=DashboardSeverity.Error) + severity:=RenameDashboardSeverity.Error) End Function @@ -444,7 +444,7 @@ class $$Program newName:="Bar", searchResultText:=String.Format(EditorFeaturesResources.Rename_will_update_0_references_in_1_files, 4, 2), resolvableConflictText:=String.Format(EditorFeaturesResources._0_conflict_s_will_be_resolved, 1), - severity:=DashboardSeverity.Info) + severity:=RenameDashboardSeverity.Info) End Function @@ -543,7 +543,7 @@ class D : B Optional renameFile As Boolean = False, Optional resolvableConflictText As String = Nothing, Optional unresolvableConflictText As String = Nothing, - Optional severity As DashboardSeverity = DashboardSeverity.None + Optional severity As RenameDashboardSeverity = RenameDashboardSeverity.None ) As Tasks.Task Using workspace = CreateWorkspaceWithWaiter(test, host) @@ -577,14 +577,14 @@ class D : B edit.Apply() End Using - Using dashboard = New Dashboard( - New DashboardViewModel(DirectCast(sessionInfo.Session, InlineRenameSession)), + Using dashboard = New RenameDashboard( + New RenameDashboardViewModel(DirectCast(sessionInfo.Session, InlineRenameSession)), editorFormatMapService:=Nothing, textView:=cursorDocument.GetTextView()) Await WaitForRename(workspace) - Dim model = DirectCast(dashboard.DataContext, DashboardViewModel) + Dim model = DirectCast(dashboard.DataContext, RenameDashboardViewModel) Assert.Equal(searchResultText, model.SearchText) diff --git a/src/EditorFeatures/Test2/Rename/RenameCommandHandlerTests.vb b/src/EditorFeatures/Test2/Rename/RenameCommandHandlerTests.vb index 9c568374c2f08..89b402dda2697 100644 --- a/src/EditorFeatures/Test2/Rename/RenameCommandHandlerTests.vb +++ b/src/EditorFeatures/Test2/Rename/RenameCommandHandlerTests.vb @@ -238,7 +238,7 @@ End Class Await WaitForRename(workspace) ' Unfocus the dashboard - Dim dashboard = DirectCast(view.GetAdornmentLayer("RoslynRenameDashboard").Elements(0).Adornment, Dashboard) + Dim dashboard = DirectCast(view.GetAdornmentLayer("RoslynRenameDashboard").Elements(0).Adornment, RenameDashboard) dashboard.ShouldReceiveKeyboardNavigation = False commandHandler.ExecuteCommand(New TabKeyCommandArgs(view, view.TextBuffer), From 9151e966d4e663653e83ab2c3ac381c1e6e2c6a0 Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Wed, 11 May 2022 16:32:21 -0700 Subject: [PATCH 4/5] Fix AdornmentShouldReceiveKeyboardNavigation for when no adornment is availble --- .../InlineRename/CommandHandlers/RenameCommandHandler.cs | 9 ++++++--- .../Core.Wpf/InlineRename/UI/Adornment/RenameFlyout.xaml | 5 ++--- .../InlineRename/UI/Adornment/RenameFlyout.xaml.cs | 4 ++-- .../CSharp/CSharpAutomaticBraceCompletion.cs | 1 + 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs b/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs index 96a15b5f339b7..1cf526764e1e3 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs @@ -43,9 +43,12 @@ public RenameCommandHandler(IThreadingContext threadingContext, InlineRenameServ #if !COCOA protected override bool AdornmentShouldReceiveKeyboardNavigation(ITextView textView) - => GetAdornment(textView) is RenameDashboard dashboard - ? dashboard.ShouldReceiveKeyboardNavigation - : true; // Always receive keyboard navigation for the inline adornment + => GetAdornment(textView) switch + { + RenameDashboard dashboard => dashboard.ShouldReceiveKeyboardNavigation, + RenameFlyout flyout => true, // Always receive keyboard navigation for the inline adornment + _ => false + }; protected override void SetFocusToTextView(ITextView textView) { diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/RenameFlyout.xaml b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/RenameFlyout.xaml index 15ca5f9e88dd2..133d27528bc6b 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/RenameFlyout.xaml +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/RenameFlyout.xaml @@ -1,4 +1,4 @@ - - + diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/RenameFlyout.xaml.cs b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/RenameFlyout.xaml.cs index ea45a412e6bc4..2e47494b93514 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/RenameFlyout.xaml.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/RenameFlyout.xaml.cs @@ -13,7 +13,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename /// /// Interaction logic for InlineRenameAdornment.xaml /// - internal partial class RenameFlyout : UserControl, IDisposable + internal partial class RenameFlyout : InlineRenameAdornment { private readonly RenameFlyoutViewModel _viewModel; private readonly ITextView _textView; @@ -71,7 +71,7 @@ private void PositionAdornment() Canvas.SetLeft(this, left); } - public void Dispose() + public override void Dispose() { _viewModel.Dispose(); diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpAutomaticBraceCompletion.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpAutomaticBraceCompletion.cs index 326429ff2813b..55980cc53afd2 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpAutomaticBraceCompletion.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpAutomaticBraceCompletion.cs @@ -299,6 +299,7 @@ class C { [WpfTheory, CombinatorialData, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void DoubleQuote_InsertionAndTabCompletion(bool showCompletionInArgumentLists) + { SetUpEditor(@" class C { From 1dbac08b8b67776f906d60b80c69e0be1c3aa4d4 Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Thu, 12 May 2022 14:50:26 -0700 Subject: [PATCH 5/5] Build correctness fix --- .../InlineRename/CommandHandlers/RenameCommandHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs b/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs index 1cf526764e1e3..8e357e7501559 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs @@ -46,7 +46,7 @@ protected override bool AdornmentShouldReceiveKeyboardNavigation(ITextView textV => GetAdornment(textView) switch { RenameDashboard dashboard => dashboard.ShouldReceiveKeyboardNavigation, - RenameFlyout flyout => true, // Always receive keyboard navigation for the inline adornment + RenameFlyout => true, // Always receive keyboard navigation for the inline adornment _ => false };