Skip to content

Commit 2e829a1

Browse files
committed
POC
1 parent 44b4ce5 commit 2e829a1

File tree

12 files changed

+136
-11
lines changed

12 files changed

+136
-11
lines changed

src/Files.App/Actions/Show/ToggleFilterHeaderAction.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public Task ExecuteAsync(object? parameter = null)
3131

3232
if (IsOn)
3333
ContentPageContext.ShellPage!.ShellViewModel.InvokeFocusFilterHeader();
34+
else
35+
ContentPageContext.ShellPage!.ShellViewModel.FilesAndFoldersFilter = string.Empty;
3436

3537
return Task.CompletedTask;
3638
}

src/Files.App/Data/Contracts/IFoldersSettingsService.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,10 @@ public interface IFoldersSettingsService : IBaseSettingsService, INotifyProperty
8989
/// Gets or sets a value indicating which format to use when displaying item sizes.
9090
/// </summary>
9191
SizeUnitTypes SizeUnitFormat { get; set; }
92+
93+
/// <summary>
94+
/// Gets or sets a value indicating the keyboard typing behavior.
95+
/// </summary>
96+
KeyboardTypingBehavior KeyboardTypingBehavior { get; set; }
9297
}
9398
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
namespace Files.App.Data.Enums
5+
{
6+
public enum KeyboardTypingBehavior
7+
{
8+
/// <summary>
9+
/// Jump to matching item.
10+
/// </summary>
11+
JumpToFile,
12+
13+
/// <summary>
14+
/// Filter items.
15+
/// </summary>
16+
FilterItems
17+
}
18+
}

src/Files.App/Services/Settings/FoldersSettingsService.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ public SizeUnitTypes SizeUnitFormat
114114
set => Set(value);
115115
}
116116

117+
/// <inheritdoc/>
118+
public KeyboardTypingBehavior KeyboardTypingBehavior
119+
{
120+
get => (KeyboardTypingBehavior)Get((long)KeyboardTypingBehavior.JumpToFile);
121+
set => Set((long)value);
122+
}
123+
117124
protected override void RaiseOnSettingChangedEvent(object sender, SettingChangedEventArgs e)
118125
{
119126
base.RaiseOnSettingChangedEvent(sender, e);

src/Files.App/Strings/en-US/Resources.resw

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4272,5 +4272,14 @@
42724272
</data>
42734273
<data name="Filename" xml:space="preserve">
42744274
<value>Filename</value>
4275+
</data>
4276+
<data name="KeyboardTypingBehavior" xml:space="preserve">
4277+
<value>Behavior when typing in the file area</value>
4278+
</data>
4279+
<data name="JumpToFile" xml:space="preserve">
4280+
<value>Jump to file</value>
4281+
</data>
4282+
<data name="FilterItems" xml:space="preserve">
4283+
<value>Filter items</value>
42754284
</data>
42764285
</root>

src/Files.App/ViewModels/Settings/FoldersViewModel.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public sealed partial class FoldersViewModel : ObservableObject
99

1010

1111
public Dictionary<SizeUnitTypes, string> SizeUnitsOptions { get; private set; } = [];
12+
public Dictionary<KeyboardTypingBehavior, string> KeyboardTypingBehaviors { get; private set; } = [];
1213

1314
public FoldersViewModel()
1415
{
@@ -18,6 +19,11 @@ public FoldersViewModel()
1819
SizeUnitsOptions.Add(SizeUnitTypes.BinaryUnits, Strings.Binary.GetLocalizedResource());
1920
SizeUnitsOptions.Add(SizeUnitTypes.DecimalUnits, Strings.Decimal.GetLocalizedResource());
2021
SizeUnitFormat = SizeUnitsOptions[UserSettingsService.FoldersSettingsService.SizeUnitFormat];
22+
23+
// Keyboard typing behavior
24+
KeyboardTypingBehaviors.Add(Data.Enums.KeyboardTypingBehavior.JumpToFile, Strings.JumpToFile.GetLocalizedResource());
25+
KeyboardTypingBehaviors.Add(Data.Enums.KeyboardTypingBehavior.FilterItems, Strings.FilterItems.GetLocalizedResource());
26+
KeyboardTypingBehavior = KeyboardTypingBehaviors[UserSettingsService.FoldersSettingsService.KeyboardTypingBehavior];
2127
}
2228

2329
// Properties
@@ -274,5 +280,18 @@ public string SizeUnitFormat
274280
}
275281
}
276282
}
283+
284+
private string keyboardTypingBehavior;
285+
public string KeyboardTypingBehavior
286+
{
287+
get => keyboardTypingBehavior;
288+
set
289+
{
290+
if (SetProperty(ref keyboardTypingBehavior, value))
291+
{
292+
UserSettingsService.FoldersSettingsService.KeyboardTypingBehavior = KeyboardTypingBehaviors.First(e => e.Value == value).Key;
293+
}
294+
}
295+
}
277296
}
278297
}

src/Files.App/ViewModels/ShellViewModel.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,13 @@ private void FilesAndFolderFilterUpdated()
764764
_ = ApplyFilesAndFoldersChangesAsync();
765765
}
766766

767+
private void ClearFilesAndFolderFilter()
768+
{
769+
if (!string.IsNullOrEmpty(FilesAndFoldersFilter) && UserSettingsService.FoldersSettingsService.KeyboardTypingBehavior == KeyboardTypingBehavior.FilterItems)
770+
UserSettingsService.GeneralSettingsService.ShowFilterHeader = false;
771+
772+
FilesAndFoldersFilter = null;
773+
}
767774

768775
// Apply changes immediately after manipulating on filesAndFolders completed
769776
public async Task ApplyFilesAndFoldersChangesAsync()
@@ -1886,7 +1893,7 @@ await dispatcherQueue.EnqueueOrInvokeAsync(() =>
18861893
{
18871894
GetDesktopIniFileData();
18881895
CheckForBackgroundImage();
1889-
FilesAndFoldersFilter = null;
1896+
ClearFilesAndFolderFilter();
18901897
},
18911898
Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
18921899
});

src/Files.App/Views/Layouts/BaseGroupableLayoutPage.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ protected override void UnhookEvents()
9595
ItemManipulationModel.RefreshItemsThumbnailInvoked -= ItemManipulationModel_RefreshItemsThumbnail;
9696
}
9797

98-
protected override void Page_CharacterReceived(UIElement sender, CharacterReceivedRoutedEventArgs args)
98+
protected override void Page_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
9999
{
100100
if (ParentShellPageInstance is null ||
101101
ParentShellPageInstance.CurrentPageType != this.GetType() ||
@@ -112,7 +112,7 @@ focusedElement is PasswordBox ||
112112
DependencyObjectHelpers.FindParent<ContentDialog>(focusedElement) is not null)
113113
return;
114114

115-
base.Page_CharacterReceived(sender, args);
115+
base.Page_PreviewKeyDown(sender, e);
116116
}
117117

118118
// Virtual methods

src/Files.App/Views/Layouts/BaseLayoutPage.cs

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Files.App.Helpers.ContextFlyouts;
77
using Files.App.UserControls.Menus;
88
using Files.App.ViewModels.Layouts;
9+
using Microsoft.UI.Input;
910
using Microsoft.UI.Xaml;
1011
using Microsoft.UI.Xaml.Controls;
1112
using Microsoft.UI.Xaml.Controls.Primitives;
@@ -23,6 +24,7 @@
2324
using Windows.Foundation.Collections;
2425
using Windows.Storage;
2526
using Windows.System;
27+
using Windows.UI.Core;
2628
using static Files.App.Helpers.PathNormalization;
2729
using DispatcherQueueTimer = Microsoft.UI.Dispatching.DispatcherQueueTimer;
2830
using SortDirection = Files.App.Data.Enums.SortDirection;
@@ -401,7 +403,7 @@ protected override async void OnNavigatedTo(NavigationEventArgs e)
401403
base.OnNavigatedTo(e);
402404

403405
// Add item jumping handler
404-
CharacterReceived += Page_CharacterReceived;
406+
PreviewKeyDown += Page_PreviewKeyDown; ;
405407

406408
navigationArguments = (NavigationArguments)e.Parameter;
407409
ParentShellPageInstance = navigationArguments.AssociatedTabInstance;
@@ -565,7 +567,7 @@ protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
565567
base.OnNavigatingFrom(e);
566568

567569
// Remove item jumping handler
568-
CharacterReceived -= Page_CharacterReceived;
570+
PreviewKeyDown -= Page_PreviewKeyDown;
569571
FolderSettings!.LayoutModeChangeRequested -= BaseFolderSettings_LayoutModeChangeRequested;
570572
FolderSettings.GroupOptionPreferenceUpdated -= FolderSettings_GroupOptionPreferenceUpdated;
571573
FolderSettings.GroupDirectionPreferenceUpdated -= FolderSettings_GroupDirectionPreferenceUpdated;
@@ -996,12 +998,54 @@ private void RemoveOverflow(CommandBarFlyout contextMenuFlyout)
996998
overflowSeparator.Visibility = Visibility.Collapsed;
997999
}
9981000

999-
protected virtual void Page_CharacterReceived(UIElement sender, CharacterReceivedRoutedEventArgs args)
1001+
protected virtual void Page_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
10001002
{
1001-
if (ParentShellPageInstance!.IsCurrentInstance)
1003+
if (ParentShellPageInstance?.IsCurrentInstance != true)
1004+
return;
1005+
1006+
var key = e.Key;
1007+
var filter = ParentShellPageInstance.ShellViewModel.FilesAndFoldersFilter;
1008+
bool isShiftDown = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down);
1009+
1010+
// OEM codes
1011+
bool isOemMinus = (int)key == 189;
1012+
bool isOemPeriod = (int)key == 190;
1013+
1014+
char? keyChar = key switch
10021015
{
1003-
char letter = args.Character;
1004-
JumpString += letter.ToString().ToLowerInvariant();
1016+
>= VirtualKey.A and <= VirtualKey.Z => (char)('A' + (key - VirtualKey.A)),
1017+
>= VirtualKey.Number0 and <= VirtualKey.Number9 => (char)('0' + (key - VirtualKey.Number0)),
1018+
_ => isOemMinus ? (isShiftDown ? '_' : '-') :
1019+
isOemPeriod ? '.' : null
1020+
};
1021+
1022+
if (keyChar is char ch &&
1023+
!Path.GetInvalidFileNameChars().Contains(char.ToLowerInvariant(ch)))
1024+
{
1025+
string typedChar = char.ToLowerInvariant(ch).ToString();
1026+
1027+
if (UserSettingsService.FoldersSettingsService.KeyboardTypingBehavior == KeyboardTypingBehavior.FilterItems)
1028+
{
1029+
if (!UserSettingsService.GeneralSettingsService.ShowFilterHeader)
1030+
UserSettingsService.GeneralSettingsService.ShowFilterHeader = true;
1031+
1032+
ParentShellPageInstance.ShellViewModel.FilesAndFoldersFilter += typedChar;
1033+
}
1034+
1035+
JumpString += typedChar;
1036+
}
1037+
else if (key == VirtualKey.Space && !string.IsNullOrEmpty(filter) &&
1038+
UserSettingsService.FoldersSettingsService.KeyboardTypingBehavior == KeyboardTypingBehavior.FilterItems)
1039+
{
1040+
ParentShellPageInstance.ShellViewModel.FilesAndFoldersFilter += " ";
1041+
}
1042+
else if (key == VirtualKey.Back && !string.IsNullOrEmpty(filter) &&
1043+
UserSettingsService.FoldersSettingsService.KeyboardTypingBehavior == KeyboardTypingBehavior.FilterItems)
1044+
{
1045+
ParentShellPageInstance.ShellViewModel.FilesAndFoldersFilter = filter[..^1];
1046+
1047+
if (string.IsNullOrEmpty(ParentShellPageInstance.ShellViewModel.FilesAndFoldersFilter))
1048+
UserSettingsService.GeneralSettingsService.ShowFilterHeader = false;
10051049
}
10061050
}
10071051

src/Files.App/Views/MainPage.xaml.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ private async Task OnPreviewKeyDownAsync(KeyRoutedEventArgs e)
216216
if (source?.FindAscendantOrSelf<TextBox>() is not null)
217217
break;
218218

219+
// Prevent the back key from executing a command if the filter header is not empty
220+
if (e.Key is VirtualKey.Back && UserSettingsService.FoldersSettingsService.KeyboardTypingBehavior == KeyboardTypingBehavior.FilterItems && !string.IsNullOrEmpty(SidebarAdaptiveViewModel.PaneHolder?.ActivePaneOrColumn!.ShellViewModel.FilesAndFoldersFilter))
221+
break;
222+
219223
// Execute command for hotkey
220224
var command = Commands[hotKey];
221225

0 commit comments

Comments
 (0)