Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collapse the rename UI when commit starts #75213

Merged
merged 5 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
Focusable="False"
UseLayoutRounding="True"
Cursor="Arrow"
Visibility="{Binding Path=Visibility}"
x:Name="control">

<UserControl.Resources>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Interop;
using Microsoft.CodeAnalysis.Editor.InlineRename;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
Expand Down Expand Up @@ -52,6 +53,7 @@ public RenameFlyoutViewModel(
Session.ReplacementTextChanged += OnReplacementTextChanged;
Session.ReplacementsComputed += OnReplacementsComputed;
Session.ReferenceLocationsChanged += OnReferenceLocationsChanged;
Session.CommitStateChange += CommitStateChange;
StartingSelection = selectionSpan;
InitialTrackingSpan = session.TriggerSpan.CreateTrackingSpan(SpanTrackingMode.EdgeInclusive);
var smartRenameSession = smartRenameSessionFactory?.Value.CreateSmartRenameSession(Session.TriggerSpan);
Expand All @@ -63,6 +65,9 @@ public RenameFlyoutViewModel(
RegisterOleComponent();
}

private void CommitStateChange(object sender, EventArgs args)
=> Visibility = this.Session.IsCommitInProgress ? Visibility.Collapsed : Visibility.Visible;

public SmartRenameViewModel? SmartRenameViewModel { get; }

public string IdentifierText
Expand Down Expand Up @@ -208,6 +213,13 @@ public bool IsRenameOverloadsVisible

public TextSpan StartingSelection { get; }

private Visibility _visibility;
public Visibility Visibility
{
get => _visibility;
set => Set(ref _visibility, value);
}

public bool Submit()
{
if (StatusSeverity == Severity.Error)
Expand Down Expand Up @@ -310,6 +322,7 @@ protected virtual void Dispose(bool disposing)
{
Session.ReplacementTextChanged -= OnReplacementTextChanged;
Session.ReplacementsComputed -= OnReplacementsComputed;
Session.CommitStateChange -= CommitStateChange;

if (SmartRenameViewModel is not null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
Focusable="True"
x:Name="dashboard"
AutomationProperties.AutomationId="Microsoft.CodeAnalysis.EditorFeatures.InlineRenameDialog"
Visibility="{Binding Path=Visibility}"
UseLayoutRounding="True">
<!--
!!!IMPORTANT!!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,7 @@ public RenameDashboard(
_textView = textView;
this.DataContext = model;

this.Visibility = textView.HasAggregateFocus ? Visibility.Visible : Visibility.Collapsed;

_textView.GotAggregateFocus += OnTextViewGotAggregateFocus;
_textView.LostAggregateFocus += OnTextViewLostAggregateFocus;
_textView.VisualElement.SizeChanged += OnElementSizeChanged;
this.SizeChanged += OnElementSizeChanged;

Expand Down Expand Up @@ -311,13 +308,9 @@ private void PositionDashboard()

private void OnTextViewGotAggregateFocus(object sender, EventArgs e)
{
this.Visibility = Visibility.Visible;
PositionDashboard();
}

private void OnTextViewLostAggregateFocus(object sender, EventArgs e)
=> this.Visibility = Visibility.Collapsed;

private void CloseButton_Click(object sender, RoutedEventArgs e)
{
_model.Session.Cancel();
Expand Down Expand Up @@ -365,7 +358,6 @@ private void Commit()
public override void Dispose()
{
_textView.GotAggregateFocus -= OnTextViewGotAggregateFocus;
_textView.LostAggregateFocus -= OnTextViewLostAggregateFocus;
_textView.VisualElement.SizeChanged -= OnElementSizeChanged;
this.SizeChanged -= OnElementSizeChanged;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,56 @@
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.InlineRename;
using Microsoft.VisualStudio.Text.Editor;

namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename
{
internal class RenameDashboardViewModel : INotifyPropertyChanged, IDisposable
{
private readonly IThreadingContext _threadingContext;
private readonly IWpfTextView _textView;
private RenameDashboardSeverity _severity = RenameDashboardSeverity.None;
private int _resolvableConflictCount;
private int _unresolvableConflictCount;
private bool _isReplacementTextValid;
private Visibility _visibility;

public RenameDashboardViewModel(InlineRenameSession session)
public RenameDashboardViewModel(InlineRenameSession session, IThreadingContext threadingContext, IWpfTextView wpfTextView)
{
Session = session;
SearchText = EditorFeaturesResources.Searching;
_textView = wpfTextView;

Session.ReferenceLocationsChanged += OnReferenceLocationsChanged;
Session.ReplacementsComputed += OnReplacementsComputed;
Session.ReplacementTextChanged += OnReplacementTextChanged;
Session.CommitStateChange += CommitStateChange;

_textView.GotAggregateFocus += GotAggregateFocus;
_textView.LostAggregateFocus += LostAggregateFocus;

// Set the flag to true by default if we're showing the option.
_isReplacementTextValid = true;
_threadingContext = threadingContext;
RefreshVisibility();
}

private void LostAggregateFocus(object sender, EventArgs _)
=> RefreshVisibility();

private void GotAggregateFocus(object sender, EventArgs _)
=> RefreshVisibility();

private void CommitStateChange(object sender, EventArgs _)
=> RefreshVisibility();

private void RefreshVisibility()
=> Visibility = !Session.IsCommitInProgress && _textView.HasAggregateFocus
? Visibility.Visible : Visibility.Collapsed;

public event PropertyChangedEventHandler PropertyChanged;

private void OnReferenceLocationsChanged(object sender, ImmutableArray<InlineRenameLocation> renameLocations)
Expand Down Expand Up @@ -153,6 +179,24 @@ private void UpdateSeverity()
_ => EditorFeaturesResources.Rename_symbols_file
};

public Visibility Visibility
{
get
{
_threadingContext.ThrowIfNotOnUIThread();
return _visibility;
}
set
{
_threadingContext.ThrowIfNotOnUIThread();
if (_visibility != value)
{
_visibility = value;
NotifyPropertyChanged();
}
}
}

public string HeaderText
{
get
Expand Down Expand Up @@ -292,6 +336,9 @@ public void Dispose()
Session.ReplacementTextChanged -= OnReplacementTextChanged;
Session.ReferenceLocationsChanged -= OnReferenceLocationsChanged;
Session.ReplacementsComputed -= OnReplacementsComputed;
Session.CommitStateChange -= CommitStateChange;
_textView.GotAggregateFocus -= GotAggregateFocus;
_textView.LostAggregateFocus -= LostAggregateFocus;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ private void UpdateAdornments()
else
{
var newAdornment = new RenameDashboard(
(RenameDashboardViewModel)s_createdViewModels.GetValue(_renameService.ActiveSession, session => new RenameDashboardViewModel(session)),
(RenameDashboardViewModel)s_createdViewModels.GetValue(_renameService.ActiveSession, session => new RenameDashboardViewModel(session, _threadingContext, _textView)),
_editorFormatMapService,
_textView);

Expand Down
12 changes: 11 additions & 1 deletion src/EditorFeatures/Core/InlineRename/InlineRenameSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -339,12 +339,13 @@ private void UpdateReferenceLocationsTask()
public bool PreviewChanges { get; private set; }
public bool HasRenameOverloads => RenameInfo.HasOverloads;
public bool MustRenameOverloads => RenameInfo.MustRenameOverloads;

public IInlineRenameUndoManager UndoManager { get; }
public bool IsCommitInProgress { get; private set; } = false;

public event EventHandler<ImmutableArray<InlineRenameLocation>> ReferenceLocationsChanged;
public event EventHandler<IInlineRenameReplacementInfo> ReplacementsComputed;
public event EventHandler ReplacementTextChanged;
public event EventHandler CommitStateChange;

internal OpenTextBufferManager GetBufferManager(ITextBuffer buffer)
=> _openTextBuffers[buffer];
Expand Down Expand Up @@ -792,6 +793,10 @@ private async Task<bool> CommitWorkerAsync(bool previewChanges, bool canUseBackg

try
{
// Notify the UI commit starts.
this.IsCommitInProgress = true;
this.CommitStateChange?.Invoke(this, EventArgs.Empty);

if (canUseBackgroundWorkIndicator)
{
// We do not cancel on edit because as part of the rename system we have asynchronous work still
Expand Down Expand Up @@ -827,6 +832,11 @@ private async Task<bool> CommitWorkerAsync(bool previewChanges, bool canUseBackg
RenameLogMessage.UserActionOutcome.Canceled | RenameLogMessage.UserActionOutcome.Committed, previewChanges);
return false;
}
finally
{
this.IsCommitInProgress = false;
this.CommitStateChange?.Invoke(this, EventArgs.Empty);
}

return true;
}
Expand Down
6 changes: 4 additions & 2 deletions src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb
Original file line number Diff line number Diff line change
Expand Up @@ -585,8 +585,11 @@ class D : B
edit.Apply()
End Using

Dim threadingContext = workspace.ExportProvider.GetExport(Of IThreadingContext)().Value

Dim textView = cursorDocument.GetTextView()
Using dashboard = New RenameDashboard(
New RenameDashboardViewModel(DirectCast(sessionInfo.Session, InlineRenameSession)),
New RenameDashboardViewModel(DirectCast(sessionInfo.Session, InlineRenameSession), threadingContext, textView),
editorFormatMapService:=Nothing,
textView:=cursorDocument.GetTextView())

Expand Down Expand Up @@ -624,7 +627,6 @@ class D : B
Dim TestQuickInfoBroker = New TestQuickInfoBroker()
Dim listenerProvider = workspace.ExportProvider.GetExport(Of IAsynchronousOperationListenerProvider)().Value
Dim editorFormatMapService = workspace.ExportProvider.GetExport(Of IEditorFormatMapService)().Value
Dim threadingContext = workspace.ExportProvider.GetExport(Of IThreadingContext)().Value

Using flyout = New RenameFlyout(
New RenameFlyoutViewModel(DirectCast(sessionInfo.Session, InlineRenameSession), selectionSpan:=Nothing, registerOleComponent:=False, globalOptions, threadingContext, listenerProvider, Nothing), ' Don't registerOleComponent in tests, it requires OleComponentManagers that don't exist in our host
Expand Down
Loading