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

Feature: Use the tab key to select the next file while renaming #11063

Merged
merged 14 commits into from
Feb 1, 2023
1 change: 1 addition & 0 deletions src/Files.App/UserControls/SearchBox.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
GotFocus="{x:Bind SearchBoxViewModel.SearchRegion_GotFocus}"
ItemTemplate="{StaticResource SuggestionTemplate}"
ItemsSource="{x:Bind SearchBoxViewModel.Suggestions, Mode=OneWay}"
KeyDown="SearchRegion_KeyDown"
PlaceholderText="{helpers:ResourceString Name=NavigationToolbarSearchRegion/PlaceholderText}"
QuerySubmitted="SearchRegion_QuerySubmitted"
Text="{x:Bind SearchBoxViewModel.Query, Mode=TwoWay}"
Expand Down
5 changes: 5 additions & 0 deletions src/Files.App/UserControls/SearchBox.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@ public SearchBoxViewModel SearchBoxViewModel

private void SearchRegion_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs e)
=> SearchBoxViewModel.SearchRegion_TextChanged(sender, e);

private void SearchRegion_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs e)
=> SearchBoxViewModel.SearchRegion_QuerySubmitted(sender, e);

private void SearchRegion_Escaped(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs e)
=> SearchBoxViewModel.SearchRegion_Escaped(sender, e);

private void SearchRegion_KeyDown(object sender, KeyRoutedEventArgs e)
=> SearchBoxViewModel.SearchRegion_KeyDown(sender, e);
}
}
14 changes: 8 additions & 6 deletions src/Files.App/ViewModels/SearchBoxViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Collections.ObjectModel;
using System.Linq;
using Windows.Foundation;
using Windows.System;

namespace Files.App.ViewModels
{
Expand Down Expand Up @@ -44,9 +45,7 @@ public void SetSuggestions(IEnumerable<SuggestionModel> suggestions)

var oldSuggestions = Suggestions.Except(items, suggestionComparer).ToList();
foreach (var oldSuggestion in oldSuggestions)
{
Suggestions.Remove(oldSuggestion);
}

var newSuggestions = items.Except(Suggestions, suggestionComparer).ToList();
foreach (var newSuggestion in newSuggestions)
Expand Down Expand Up @@ -95,9 +94,7 @@ public void SearchRegion_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQue

// Limit to last 5 queries to improve performance
if (oldQueries.Count > 5)
{
oldQueries.RemoveAt(5);
}
}
}

Expand All @@ -109,9 +106,14 @@ public void SearchRegion_Escaped(KeyboardAccelerator sender, KeyboardAccelerator
public void SearchRegion_GotFocus(object sender, RoutedEventArgs e)
{
if (string.IsNullOrWhiteSpace(query))
{
AddRecentQueries();
}
}

public void SearchRegion_KeyDown(object sender, KeyRoutedEventArgs e)
{
e.Handled = e.Key is VirtualKey.Left ||
e.Key is VirtualKey.Right ||
((e.Key is VirtualKey.Up || e.Key is VirtualKey.Down) && Suggestions.Count == 0);
}

public void AddRecentQueries()
Expand Down
7 changes: 5 additions & 2 deletions src/Files.App/Views/LayoutModes/ColumnViewBase.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ protected override void ItemManipulationModel_FocusSelectedItemsInvoked(object?

protected override void ItemManipulationModel_AddSelectedItemInvoked(object? sender, ListedItem e)
{
if (NextRenameIndex != 0 && TryStartRenameNextItem(e))
return;

FileList?.SelectedItems.Add(e);
}

Expand Down Expand Up @@ -369,7 +372,7 @@ private void HandleRightClick(object sender, HoldingRoutedEventArgs e)
ItemManipulationModel.SetSelectedItem(objectPressed);
}

private void FileList_ItemTapped(object sender, TappedRoutedEventArgs e)
private async void FileList_ItemTapped(object sender, TappedRoutedEventArgs e)
{
var ctrlPressed = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down);
var shiftPressed = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down);
Expand Down Expand Up @@ -399,7 +402,7 @@ private void FileList_ItemTapped(object sender, TappedRoutedEventArgs e)
if (FileList.ContainerFromItem(RenamingItem) is ListViewItem listViewItem
&& listViewItem.FindDescendant("ListViewTextBoxItemName") is TextBox textBox)
{
CommitRename(textBox);
await CommitRename(textBox);
}
}
if (item is not null && item.PrimaryItemAttribute == StorageItemTypes.Folder &&
Expand Down
22 changes: 18 additions & 4 deletions src/Files.App/Views/LayoutModes/DetailsLayoutBrowser.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public sealed partial class DetailsLayoutBrowser : StandardViewBase

private InputCursor resizeCursor = InputCursor.CreateFromCoreCursor(new CoreCursor(CoreCursorType.SizeWestEast, 1));

private ListedItem? _nextItemToSelect;

protected override uint IconSize => currentIconSize;

protected override ListViewBase ListViewBase => FileList;
Expand Down Expand Up @@ -95,8 +97,13 @@ protected override void ItemManipulationModel_FocusSelectedItemsInvoked(object?

protected override void ItemManipulationModel_AddSelectedItemInvoked(object? sender, ListedItem e)
{
if (FileList?.Items.Contains(e) ?? false)
FileList.SelectedItems.Add(e);
if (NextRenameIndex != 0)
{
_nextItemToSelect = e;
FileList.LayoutUpdated += FileList_LayoutUpdated;
}
else if (FileList?.Items.Contains(e) ?? false)
FileList!.SelectedItems.Add(e);
}

protected override void ItemManipulationModel_RemoveSelectedItemInvoked(object? sender, ListedItem e)
Expand Down Expand Up @@ -173,6 +180,13 @@ protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
ParentShellPageInstance.FilesystemViewModel.PageTypeUpdated -= FilesystemViewModel_PageTypeUpdated;
}

private void FileList_LayoutUpdated(object? sender, object e)
{
FileList.LayoutUpdated -= FileList_LayoutUpdated;
TryStartRenameNextItem(_nextItemToSelect!);
_nextItemToSelect = null;
}

private void FolderSettings_SortOptionPreferenceUpdated(object? sender, SortOption e)
{
UpdateSortIndicator();
Expand Down Expand Up @@ -401,7 +415,7 @@ private async void ReloadItemIcons()
}
}

private void FileList_ItemTapped(object sender, TappedRoutedEventArgs e)
private async void FileList_ItemTapped(object sender, TappedRoutedEventArgs e)
{
var ctrlPressed = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down);
var shiftPressed = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down);
Expand Down Expand Up @@ -435,7 +449,7 @@ private void FileList_ItemTapped(object sender, TappedRoutedEventArgs e)
if (listViewItem is not null)
{
var textBox = listViewItem.FindDescendant("ItemNameTextBox") as TextBox;
CommitRename(textBox);
await CommitRename(textBox);
}
}
}
Expand Down
12 changes: 7 additions & 5 deletions src/Files.App/Views/LayoutModes/GridViewBrowser.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,10 @@ protected override void ItemManipulationModel_FocusSelectedItemsInvoked(object?

protected override void ItemManipulationModel_AddSelectedItemInvoked(object? sender, ListedItem e)
{
if (FileList?.Items.Contains(e) ?? false)
FileList.SelectedItems.Add(e);
if ((NextRenameIndex != 0 && TryStartRenameNextItem(e)) || (!FileList?.Items.Contains(e) ?? true))
return;

FileList!.SelectedItems.Add(e);
}

protected override void ItemManipulationModel_RemoveSelectedItemInvoked(object? sender, ListedItem e)
Expand Down Expand Up @@ -374,7 +376,7 @@ private async void ReloadSelectedItemsIcon()
}
}

private void FileList_ItemTapped(object sender, TappedRoutedEventArgs e)
private async void FileList_ItemTapped(object sender, TappedRoutedEventArgs e)
{
var ctrlPressed = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down);
var shiftPressed = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down);
Expand Down Expand Up @@ -409,12 +411,12 @@ private void FileList_ItemTapped(object sender, TappedRoutedEventArgs e)
{
Popup popup = gridViewItem.FindDescendant("EditPopup") as Popup;
var textBox = popup.Child as TextBox;
CommitRename(textBox);
await CommitRename(textBox);
}
else
{
var textBox = gridViewItem.FindDescendant("TileViewTextBoxItemName") as TextBox;
CommitRename(textBox);
await CommitRename(textBox);
}
}
}
Expand Down
105 changes: 90 additions & 15 deletions src/Files.App/Views/LayoutModes/StandardLayoutMode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Windows.System;
using Windows.UI.Core;

namespace Files.App
{
public abstract class StandardViewBase : BaseLayout
{
private const int KEY_DOWN_MASK = 0x8000;

protected int NextRenameIndex = 0;

protected abstract ListViewBase ListViewBase
{
get;
Expand Down Expand Up @@ -130,6 +136,7 @@ protected virtual void ZoomIn(object? sender, GroupOption option)
protected virtual async void FileList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SelectedItems = ListViewBase.SelectedItems.Cast<ListedItem>().Where(x => x is not null).ToList();

if (SelectedItems.Count == 1 && App.AppModel.IsQuickLookAvailable)
await QuickLookHelpers.ToggleQuickLook(ParentShellPageInstance, true);
}
Expand Down Expand Up @@ -167,48 +174,113 @@ protected virtual void StartRenameItem(string itemNameTextBox)
textBox.KeyDown += RenameTextBox_KeyDown;

int selectedTextLength = SelectedItem.Name.Length;

if (!SelectedItem.IsShortcut && UserSettingsService.FoldersSettingsService.ShowFileExtensions)
selectedTextLength -= extensionLength;

textBox.Select(0, selectedTextLength);
IsRenamingItem = true;
}

protected abstract void EndRename(TextBox textBox);

protected virtual async void CommitRename(TextBox textBox)
protected virtual async Task CommitRename(TextBox textBox)
{
EndRename(textBox);
string newItemName = textBox.Text.Trim().TrimEnd('.');
await UIFilesystemHelpers.RenameFileItemAsync(RenamingItem, newItemName, ParentShellPageInstance);
}

protected virtual void RenameTextBox_LostFocus(object sender, RoutedEventArgs e)
protected virtual async void RenameTextBox_LostFocus(object sender, RoutedEventArgs e)
{
// This check allows the user to use the text box context menu without ending the rename
if (!(FocusManager.GetFocusedElement(XamlRoot) is AppBarButton or Popup))
{
TextBox textBox = (TextBox)e.OriginalSource;
CommitRename(textBox);
await CommitRename(textBox);
}
}

protected void RenameTextBox_KeyDown(object sender, KeyRoutedEventArgs e)
protected async void RenameTextBox_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Escape)
var textBox = (TextBox)sender;
switch (e.Key)
{
TextBox textBox = (TextBox)sender;
textBox.LostFocus -= RenameTextBox_LostFocus;
textBox.Text = OldItemName;
EndRename(textBox);
e.Handled = true;
case VirtualKey.Escape:
textBox.LostFocus -= RenameTextBox_LostFocus;
textBox.Text = OldItemName;
EndRename(textBox);
e.Handled = true;
break;
case VirtualKey.Enter:
textBox.LostFocus -= RenameTextBox_LostFocus;
await CommitRename(textBox);
e.Handled = true;
break;
case VirtualKey.Up:
textBox.SelectionStart = 0;
e.Handled = true;
break;
case VirtualKey.Down:
textBox.SelectionStart = textBox.Text.Length;
e.Handled = true;
break;
case VirtualKey.Left:
e.Handled = textBox.SelectionStart == 0;
break;
case VirtualKey.Right:
e.Handled = (textBox.SelectionStart + textBox.SelectionLength) == textBox.Text.Length;
break;
case VirtualKey.Tab:
textBox.LostFocus -= RenameTextBox_LostFocus;

var isShiftPressed = (GetKeyState((int)VirtualKey.Shift) & KEY_DOWN_MASK) != 0;
NextRenameIndex = isShiftPressed ? -1 : 1;

if (textBox.Text != OldItemName)
{
await CommitRename(textBox);
}
else
{
var newIndex = ListViewBase.SelectedIndex + NextRenameIndex;
NextRenameIndex = 0;
EndRename(textBox);

if
(
newIndex >= 0 &&
newIndex < ListViewBase.Items.Count
)
{
ListViewBase.SelectedIndex = newIndex;
StartRenameItem();
}
}

e.Handled = true;
break;
}
else if (e.Key == VirtualKey.Enter)
}

protected bool TryStartRenameNextItem(ListedItem item)
{
var nextItemIndex = ListViewBase.Items.IndexOf(item) + NextRenameIndex;
NextRenameIndex = 0;

if
(
nextItemIndex >= 0 &&
nextItemIndex < ListViewBase.Items.Count
)
{
TextBox textBox = (TextBox)sender;
textBox.LostFocus -= RenameTextBox_LostFocus;
CommitRename(textBox);
e.Handled = true;
ListViewBase.SelectedIndex = nextItemIndex;
StartRenameItem();

return true;
}

return false;
}

protected override void Page_CharacterReceived(UIElement sender, CharacterReceivedRoutedEventArgs args)
Expand Down Expand Up @@ -237,5 +309,8 @@ public override void Dispose()
UnhookEvents();
CommandsViewModel?.Dispose();
}

[DllImport("User32.dll")]
private extern static short GetKeyState(int n);
}
}