66using Files . App . Helpers . ContextFlyouts ;
77using Files . App . UserControls . Menus ;
88using Files . App . ViewModels . Layouts ;
9+ using Microsoft . UI . Input ;
910using Microsoft . UI . Xaml ;
1011using Microsoft . UI . Xaml . Controls ;
1112using Microsoft . UI . Xaml . Controls . Primitives ;
2324using Windows . Foundation . Collections ;
2425using Windows . Storage ;
2526using Windows . System ;
27+ using Windows . UI . Core ;
2628using static Files . App . Helpers . PathNormalization ;
2729using DispatcherQueueTimer = Microsoft . UI . Dispatching . DispatcherQueueTimer ;
2830using SortDirection = Files . App . Data . Enums . SortDirection ;
@@ -40,6 +42,8 @@ public abstract class BaseLayoutPage : Page, IBaseLayoutPage, INotifyPropertyCha
4042 protected IFileTagsSettingsService FileTagsSettingsService { get ; } = Ioc . Default . GetService < IFileTagsSettingsService > ( ) ! ;
4143 protected IUserSettingsService UserSettingsService { get ; } = Ioc . Default . GetService < IUserSettingsService > ( ) ! ;
4244 protected ILayoutSettingsService LayoutSettingsService { get ; } = Ioc . Default . GetService < ILayoutSettingsService > ( ) ! ;
45+ protected IGeneralSettingsService GeneralSettingsService { get ; } = Ioc . Default . GetService < IGeneralSettingsService > ( ) ! ;
46+ protected IFoldersSettingsService FoldersSettingsService { get ; } = Ioc . Default . GetService < IFoldersSettingsService > ( ) ! ;
4347 protected ICommandManager Commands { get ; } = Ioc . Default . GetRequiredService < ICommandManager > ( ) ;
4448 public InfoPaneViewModel InfoPaneViewModel { get ; } = Ioc . Default . GetRequiredService < InfoPaneViewModel > ( ) ;
4549 protected readonly IWindowContext WindowContext = Ioc . Default . GetRequiredService < IWindowContext > ( ) ;
@@ -401,7 +405,7 @@ protected override async void OnNavigatedTo(NavigationEventArgs e)
401405 base . OnNavigatedTo ( e ) ;
402406
403407 // Add item jumping handler
404- CharacterReceived += Page_CharacterReceived ;
408+ PreviewKeyDown += Page_PreviewKeyDown ; ;
405409
406410 navigationArguments = ( NavigationArguments ) e . Parameter ;
407411 ParentShellPageInstance = navigationArguments . AssociatedTabInstance ;
@@ -565,7 +569,7 @@ protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
565569 base . OnNavigatingFrom ( e ) ;
566570
567571 // Remove item jumping handler
568- CharacterReceived -= Page_CharacterReceived ;
572+ PreviewKeyDown -= Page_PreviewKeyDown ;
569573 FolderSettings ! . LayoutModeChangeRequested -= BaseFolderSettings_LayoutModeChangeRequested ;
570574 FolderSettings . GroupOptionPreferenceUpdated -= FolderSettings_GroupOptionPreferenceUpdated ;
571575 FolderSettings . GroupDirectionPreferenceUpdated -= FolderSettings_GroupDirectionPreferenceUpdated ;
@@ -996,12 +1000,78 @@ private void RemoveOverflow(CommandBarFlyout contextMenuFlyout)
9961000 overflowSeparator . Visibility = Visibility . Collapsed ;
9971001 }
9981002
999- protected virtual void Page_CharacterReceived ( UIElement sender , CharacterReceivedRoutedEventArgs args )
1003+ protected virtual void Page_PreviewKeyDown ( object sender , KeyRoutedEventArgs e )
10001004 {
1001- if ( ParentShellPageInstance ! . IsCurrentInstance )
1005+ var shellPage = ParentShellPageInstance ;
1006+ if ( shellPage ? . IsCurrentInstance != true )
1007+ return ;
1008+
1009+ var pressedKey = e . Key ;
1010+ var currentFilter = shellPage . ShellViewModel . FilesAndFoldersFilter ?? string . Empty ;
1011+ var isFilterModeOn = FoldersSettingsService . KeyboardTypingBehavior == KeyboardTypingBehavior . FilterItems ;
1012+ var isShiftPressed = InputKeyboardSource . GetKeyStateForCurrentThread ( VirtualKey . Shift )
1013+ . HasFlag ( CoreVirtualKeyStates . Down ) ;
1014+
1015+ // Get typed character
1016+ var typedCharacter = pressedKey switch
10021017 {
1003- char letter = args . Character ;
1004- JumpString += letter . ToString ( ) . ToLowerInvariant ( ) ;
1018+ >= VirtualKey . A and <= VirtualKey . Z => ( char ) ( 'A' + ( pressedKey - VirtualKey . A ) ) ,
1019+ >= VirtualKey . Number0 and <= VirtualKey . Number9 => ( char ) ( '0' + ( pressedKey - VirtualKey . Number0 ) ) ,
1020+ _ when ( int ) pressedKey == ( int ) Keys . OemMinus => isShiftPressed ? '_' : '-' ,
1021+ _ when ( int ) pressedKey == ( int ) Keys . OemPeriod => '.' ,
1022+ _ => ( char ? ) null
1023+ } ;
1024+
1025+ // Handle valid character input
1026+ if ( typedCharacter . HasValue && ! Path . GetInvalidFileNameChars ( ) . Contains ( char . ToLowerInvariant ( typedCharacter . Value ) ) )
1027+ {
1028+ var lowerCharString = char . ToLowerInvariant ( typedCharacter . Value ) . ToString ( ) ;
1029+
1030+ if ( isFilterModeOn )
1031+ {
1032+ if ( ! GeneralSettingsService . ShowFilterHeader )
1033+ GeneralSettingsService . ShowFilterHeader = true ;
1034+ shellPage . ShellViewModel . FilesAndFoldersFilter += lowerCharString ;
1035+ }
1036+ else
1037+ {
1038+ JumpString += lowerCharString ;
1039+ }
1040+ }
1041+ // Handle special keys in filter mode
1042+ else if ( isFilterModeOn && ! string . IsNullOrEmpty ( currentFilter ) )
1043+ {
1044+ switch ( pressedKey )
1045+ {
1046+ case VirtualKey . Space :
1047+ shellPage . ShellViewModel . FilesAndFoldersFilter += " " ;
1048+ break ;
1049+
1050+ case VirtualKey . Back when currentFilter . Length > 1 :
1051+ shellPage . ShellViewModel . FilesAndFoldersFilter = currentFilter [ ..^ 1 ] ;
1052+ break ;
1053+
1054+ case VirtualKey . Back when currentFilter . Length == 1 :
1055+ shellPage . ShellViewModel . FilesAndFoldersFilter = string . Empty ;
1056+ GeneralSettingsService . ShowFilterHeader = false ;
1057+ break ;
1058+ }
1059+ }
1060+
1061+ // Update selection in filter mode
1062+ if ( isFilterModeOn )
1063+ {
1064+ var filterText = shellPage . ShellViewModel . FilesAndFoldersFilter ;
1065+ var matchedItem = shellPage . ShellViewModel . FilesAndFolders
1066+ . FirstOrDefault ( item => ! string . IsNullOrEmpty ( filterText ) &&
1067+ item . Name ? . Contains ( filterText , StringComparison . OrdinalIgnoreCase ) == true ) ;
1068+
1069+ if ( matchedItem != null )
1070+ {
1071+ ItemManipulationModel . SetSelectedItem ( matchedItem ) ;
1072+ ItemManipulationModel . ScrollIntoView ( matchedItem ) ;
1073+ ItemManipulationModel . FocusSelectedItems ( ) ;
1074+ }
10051075 }
10061076 }
10071077
0 commit comments