Show folder names immediately and refresh stale index sizes without walking the whole drive.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
178
src/Explorer.App/ExplorerAddressBar.xaml.cs
Normal file
178
src/Explorer.App/ExplorerAddressBar.xaml.cs
Normal file
@@ -0,0 +1,178 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using Explorer.Presentation.ViewModels;
|
||||
|
||||
namespace Explorer.App;
|
||||
|
||||
public partial class ExplorerAddressBar : UserControl
|
||||
{
|
||||
private bool _suppressLostFocus;
|
||||
|
||||
public ExplorerAddressBar()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContextChanged += OnDataContextChanged;
|
||||
IsVisibleChanged += (_, _) =>
|
||||
{
|
||||
if (IsVisible && DataContext is ExplorerPaneViewModel { IsEditingPath: true })
|
||||
{
|
||||
FocusEditor();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void FocusEditor()
|
||||
{
|
||||
Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
PathCombo.ApplyTemplate();
|
||||
if (PathCombo.Template.FindName("PART_EditableTextBox", PathCombo) is TextBox box)
|
||||
{
|
||||
box.Focus();
|
||||
box.SelectAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
PathCombo.Focus();
|
||||
}
|
||||
}, DispatcherPriority.Loaded);
|
||||
}
|
||||
|
||||
private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.OldValue is ExplorerPaneViewModel previous)
|
||||
{
|
||||
previous.PropertyChanged -= OnPanePropertyChanged;
|
||||
}
|
||||
|
||||
if (e.NewValue is ExplorerPaneViewModel pane)
|
||||
{
|
||||
pane.PropertyChanged += OnPanePropertyChanged;
|
||||
if (pane.IsEditingPath)
|
||||
{
|
||||
FocusEditor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPanePropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(ExplorerPaneViewModel.IsEditingPath)
|
||||
&& sender is ExplorerPaneViewModel { IsEditingPath: true })
|
||||
{
|
||||
FocusEditor();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnBreadcrumbMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.OriginalSource is DependencyObject origin && IsInsideButton(origin))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (DataContext is not ExplorerPaneViewModel pane)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pane.BeginEditPath();
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnPathKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (DataContext is not ExplorerPaneViewModel pane)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.Key == Key.Enter)
|
||||
{
|
||||
CommitPath();
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.Key == Key.Escape)
|
||||
{
|
||||
_suppressLostFocus = true;
|
||||
pane.CancelEditPath();
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPathHistorySelected(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (sender is not ComboBox combo || e.AddedItems.Count == 0 || e.AddedItems[0] is not string path)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (DataContext is not ExplorerPaneViewModel pane)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (NavigationTreeViewModel.PathsEqual(path, pane.CurrentPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (combo.IsDropDownOpen || combo.IsKeyboardFocusWithin)
|
||||
{
|
||||
pane.PathEditText = path;
|
||||
CommitPath();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPathLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
|
||||
{
|
||||
Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
if (_suppressLostFocus)
|
||||
{
|
||||
_suppressLostFocus = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (PathCombo.IsDropDownOpen || PathCombo.IsKeyboardFocusWithin)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (DataContext is ExplorerPaneViewModel pane)
|
||||
{
|
||||
pane.CancelEditPath();
|
||||
}
|
||||
}, DispatcherPriority.Input);
|
||||
}
|
||||
|
||||
private void CommitPath()
|
||||
{
|
||||
if (Window.GetWindow(this)?.DataContext is MainViewModel vm)
|
||||
{
|
||||
vm.GoCommand.Execute(null);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsInsideButton(DependencyObject origin)
|
||||
{
|
||||
for (var current = origin; current is not null;)
|
||||
{
|
||||
if (current is Button)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
current = current is Visual
|
||||
? VisualTreeHelper.GetParent(current)
|
||||
: LogicalTreeHelper.GetParent(current);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user