Skip to content

Improve keyboard navigation in column view #7425

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

Merged
merged 29 commits into from
Jan 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
93519eb
[WIP]
gave92 Dec 29, 2021
e67a7a9
[WIP]
gave92 Dec 30, 2021
e7cc6af
Cool things with Composition
gave92 Dec 30, 2021
c28445d
Select first list item on arrowdown
gave92 Dec 30, 2021
6ed54cb
Enable jumpstring when header is selected
gave92 Dec 30, 2021
2081751
Avoid losing focus ctrl+shift+arrow when renaming
gave92 Dec 30, 2021
9adc33b
Remove unused FileList_FocusItem0
gave92 Dec 30, 2021
839fae9
Extend fix for #6481 to grid and column
gave92 Dec 30, 2021
b1549e6
Allow resize columns by arrow keys
gave92 Dec 30, 2021
fb7191d
Focus selected item on key down
gave92 Dec 30, 2021
dc86600
Fix focus getting trappend in ListView & trigger footer button by key…
gave92 Dec 30, 2021
5871743
Extend fix for foooter to GridView
gave92 Dec 30, 2021
c4f6d67
Fix #2977 and auto focus file list
gave92 Dec 30, 2021
3588699
Add timeout to fecth drives thumbnail??
gave92 Dec 30, 2021
cf184a1
Open column on Enter
gave92 Jan 1, 2022
4fa3436
Emable back-forward toolbar buttons in column view
gave92 Jan 1, 2022
c0cee24
Extend fix for #2977 to columnview
gave92 Jan 1, 2022
3a6d0d4
Fix #5681 for grid & column view
gave92 Jan 1, 2022
601ac2c
Remove redundant resources from columnviewbrowser
gave92 Jan 1, 2022
9896930
Use got focus for setting current instance
gave92 Jan 1, 2022
30768be
Do not change inactive listview opacity
gave92 Jan 1, 2022
f6ca4c9
Only set current instance once
gave92 Jan 2, 2022
41d4558
Fix Ctrl+Shift+<-/->/W focus
gave92 Jan 2, 2022
d9ab474
Revert "Add timeout to fecth drives thumbnail??"
gave92 Jan 2, 2022
70d6504
Prevent column change on pointer up
gave92 Jan 3, 2022
6c28fe5
Scroll focused column into view
gave92 Jan 3, 2022
d88b61f
Use arrow keys to navigate columnview (#5375)
gave92 Jan 3, 2022
e03011d
Merge branch 'main' into pr/7425
yaira2 Jan 4, 2022
ed446e5
Merge branch 'main' into pr/7425
yaira2 Jan 5, 2022
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 @@ -186,13 +186,16 @@ private void RectangleSelection_PointerReleased(object sender, PointerRoutedEven
selectionChanged(sender, null);
}
}
if (selectionState == SelectionState.Active)
//if (selectionState == SelectionState.Active)
{
// Always trigger SelectionEnded to focus the file list when clicking on the empty space (#2977)
OnSelectionEnded();
}

selectionStrategy = null;
selectionState = SelectionState.Inactive;

e.Handled = true;
}

private void RectangleSelection_LayoutUpdated(object sender, object e)
Expand Down
54 changes: 12 additions & 42 deletions src/Files/Views/ColumnShellPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ public sealed partial class ColumnShellPage : Page, IShellPage, INotifyPropertyC
public IFilesystemHelpers FilesystemHelpers { get; private set; }
private CancellationTokenSource cancellationTokenSource;

public bool CanNavigateBackward => ItemDisplayFrame.CanGoBack;
public bool CanNavigateForward => ItemDisplayFrame.CanGoForward;
public bool CanNavigateBackward => false;
public bool CanNavigateForward => false;

public FolderSettingsViewModel FolderSettings => InstanceViewModel?.FolderSettings;

Expand Down Expand Up @@ -375,7 +375,8 @@ private void ColumnShellPage_BackRequested(object sender, BackRequestedEventArgs
{
if (IsCurrentInstance)
{
if (ItemDisplayFrame.CanGoBack)
var browser = this.FindAscendant<ColumnViewBrowser>();
if (browser.ParentShellPageInstance.CanNavigateBackward)
{
e.Handled = true;
Back_Click();
Expand Down Expand Up @@ -744,51 +745,17 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio

public void Back_Click()
{
NavToolbarViewModel.CanGoBack = false;
if (ItemDisplayFrame.CanGoBack)
{
var previousPageContent = ItemDisplayFrame.BackStack[ItemDisplayFrame.BackStack.Count - 1];
var previousPageNavPath = previousPageContent.Parameter as NavigationArguments;
previousPageNavPath.IsLayoutSwitch = false;
if (previousPageContent.SourcePageType != typeof(WidgetsPage))
{
// Update layout type
InstanceViewModel.FolderSettings.GetLayoutType(previousPageNavPath.IsSearchResultPage ? previousPageNavPath.SearchPathParam : previousPageNavPath.NavPathParam);
}
SelectSidebarItemFromPath(previousPageContent.SourcePageType);

if (previousPageContent.SourcePageType == typeof(WidgetsPage))
{
ItemDisplayFrame.GoBack(new EntranceNavigationTransitionInfo());
}
else
{
ItemDisplayFrame.GoBack();
}
}
this.FindAscendant<ColumnViewBrowser>().NavigateBack();
}

public void Forward_Click()
{
NavToolbarViewModel.CanGoForward = false;
if (ItemDisplayFrame.CanGoForward)
{
var incomingPageContent = ItemDisplayFrame.ForwardStack[ItemDisplayFrame.ForwardStack.Count - 1];
var incomingPageNavPath = incomingPageContent.Parameter as NavigationArguments;
incomingPageNavPath.IsLayoutSwitch = false;
if (incomingPageContent.SourcePageType != typeof(WidgetsPage))
{
// Update layout type
InstanceViewModel.FolderSettings.GetLayoutType(incomingPageNavPath.IsSearchResultPage ? incomingPageNavPath.SearchPathParam : incomingPageNavPath.NavPathParam);
}
SelectSidebarItemFromPath(incomingPageContent.SourcePageType);
ItemDisplayFrame.GoForward();
}
this.FindAscendant<ColumnViewBrowser>().NavigateForward();
}

public void Up_Click()
{
this.FindAscendant<ColumnViewBrowser>().UpColumn();
this.FindAscendant<ColumnViewBrowser>().NavigateUp();
}

private void SelectSidebarItemFromPath(Type incomingSourcePageType = null)
Expand Down Expand Up @@ -851,14 +818,17 @@ private void FilesystemViewModel_ItemLoadStatusChanged(object sender, ItemLoadSt
break;

case ItemLoadStatusChangedEventArgs.ItemLoadStatus.InProgress:
NavToolbarViewModel.CanGoBack = ItemDisplayFrame.CanGoBack;
NavToolbarViewModel.CanGoForward = ItemDisplayFrame.CanGoForward;
var browser = this.FindAscendant<ColumnViewBrowser>();
NavToolbarViewModel.CanGoBack = browser.ParentShellPageInstance.CanNavigateBackward;
NavToolbarViewModel.CanGoForward = browser.ParentShellPageInstance.CanNavigateForward;
SetLoadingIndicatorForTabs(true);
break;

case ItemLoadStatusChangedEventArgs.ItemLoadStatus.Complete:
SetLoadingIndicatorForTabs(false);
NavToolbarViewModel.CanRefresh = true;
// Set focus to the file list to allow arrow navigation
ContentPage?.ItemManipulationModel.FocusFileList();
// Select previous directory
if (!string.IsNullOrWhiteSpace(e.PreviousDirectory))
{
Expand Down
54 changes: 47 additions & 7 deletions src/Files/Views/LayoutModes/ColumnViewBase.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.System;
using Windows.UI.Core;
Expand All @@ -24,8 +25,8 @@ public sealed partial class ColumnViewBase : BaseLayout
public ColumnViewBase() : base()
{
this.InitializeComponent();
CurrentColumn = this;
var selectionRectangle = RectangleSelection.Create(FileList, SelectionRectangle, FileList_SelectionChanged);
selectionRectangle.SelectionEnded += SelectionRectangle_SelectionEnded;
}

protected override void HookEvents()
Expand Down Expand Up @@ -160,6 +161,12 @@ protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
base.OnNavigatingFrom(e);
}

private async void SelectionRectangle_SelectionEnded(object sender, EventArgs e)
{
await Task.Delay(200);
FileList.Focus(FocusState.Programmatic);
}

private async void ReloadItemIcons()
{
ParentShellPageInstance.FilesystemViewModel.CancelExtendedPropertiesLoading();
Expand Down Expand Up @@ -288,9 +295,6 @@ public override void Dispose()

#endregion IDisposable

public static ColumnViewBase CurrentColumn;
private ListViewItem listViewItem;

private async void FileList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SelectedItems = FileList.SelectedItems.Cast<ListedItem>().Where(x => x != null).ToList();
Expand Down Expand Up @@ -339,7 +343,14 @@ private async void FileList_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
{
if (!IsRenamingItem)
{
NavigationHelpers.OpenSelectedItems(ParentShellPageInstance, false);
if (IsItemSelected && SelectedItem.PrimaryItemAttribute == StorageItemTypes.Folder)
{
ItemInvoked?.Invoke(new ColumnParam { NavPathParam = (SelectedItem is ShortcutItem sht ? sht.TargetPath : SelectedItem.ItemPath), ListView = FileList }, EventArgs.Empty);
}
else
{
NavigationHelpers.OpenSelectedItems(ParentShellPageInstance, false);
}
e.Handled = true;
}
}
Expand Down Expand Up @@ -374,6 +385,37 @@ private async void FileList_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
// Unfocus the ListView so keyboard shortcut can be handled (alt + shift + "+")
NavToolbar?.Focus(FocusState.Pointer);
}
else if (e.Key == VirtualKey.Up || e.Key == VirtualKey.Down)
{
// If list has only one item, select it on arrow down/up (#5681)
if (!IsItemSelected && FileList.Items.Count == 1)
{
FileList.SelectedIndex = 0;
e.Handled = true;
}
}
else if (e.Key == VirtualKey.Left) // Left arrow: select parent folder (previous column)
{
if (!IsRenamingItem && !ParentShellPageInstance.NavToolbarViewModel.IsEditModeEnabled)
{
if ((ParentShellPageInstance as ColumnShellPage).ColumnParams.Column > 0)
{
FocusManager.TryMoveFocus(FocusNavigationDirection.Previous);
}
e.Handled = true;
}
}
else if (e.Key == VirtualKey.Right) // Right arrow: open selected folder
{
if (!IsRenamingItem && !ParentShellPageInstance.NavToolbarViewModel.IsEditModeEnabled)
{
if (IsItemSelected && SelectedItem.PrimaryItemAttribute == StorageItemTypes.Folder)
{
ItemInvoked?.Invoke(new ColumnParam { NavPathParam = (SelectedItem is ShortcutItem sht ? sht.TargetPath : SelectedItem.ItemPath), ListView = FileList }, EventArgs.Empty);
}
e.Handled = true;
}
}
}

private void FileList_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
Expand All @@ -385,7 +427,6 @@ private void FileList_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
if (item.PrimaryItemAttribute == StorageItemTypes.Folder)
{
listViewItem = FileList.ContainerFromItem(item) as ListViewItem;
ItemInvoked?.Invoke(new ColumnParam { NavPathParam = (item is ShortcutItem sht ? sht.TargetPath : item.ItemPath), ListView = FileList }, EventArgs.Empty);
}
else
Expand Down Expand Up @@ -442,7 +483,6 @@ private void FileList_ItemTapped(object sender, TappedRoutedEventArgs e)

if (item.PrimaryItemAttribute == StorageItemTypes.Folder)
{
listViewItem = FileList.ContainerFromItem(item) as ListViewItem;
ItemInvoked?.Invoke(new ColumnParam { NavPathParam = (item is ShortcutItem sht ? sht.TargetPath : item.ItemPath), ListView = FileList }, EventArgs.Empty);
}
else
Expand Down
103 changes: 0 additions & 103 deletions src/Files/Views/LayoutModes/ColumnViewBrowser.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,116 +19,13 @@
</icore:EventTriggerBehavior>
</i:Interaction.Behaviors>
<local:BaseLayout.Resources>
<converters:BoolNegationConverter x:Key="BoolNegationConverter" />
<converters:BoolToVisibilityConverter
x:Key="NegatedBoolToVisibilityConverter"
FalseValue="Visible"
TrueValue="Collapsed" />
<converters:EmptyObjectToObjectConverter
x:Key="EmptyObjectToObjectConverter"
EmptyValue="Collapsed"
NotEmptyValue="Visible" />

<converters:BoolToVisibilityConverter
x:Key="BoolToVisibilityConverter"
FalseValue="Collapsed"
TrueValue="Visible" />

<converters1:BoolToSelectionMode x:Key="BoolToSelectionModeConverter" />
<Style TargetType="controls:BladeItem">
<Setter Property="Background" Value="Transparent" />
<Setter Property="TitleBarVisibility" Value="Collapsed" />
<Setter Property="BorderThickness" Value="0,0,1,0" />
<Setter Property="BorderBrush" Value="{ThemeResource ControlStrokeColorDefault}" />
<Setter Property="Width" Value="300" />
</Style>
<Style TargetType="ListViewHeaderItem">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource GridViewHeaderItemThemeFontSize}" />
<Setter Property="Background" Value="{ThemeResource GridViewHeaderItemBackground}" />
<Setter Property="Margin" Value="0,0,0,4" />
<Setter Property="Padding" Value="12,8,12,0" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="MinHeight" Value="{ThemeResource GridViewHeaderItemMinHeight}" />
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewHeaderItem">
<Grid
x:Name="HeaderItemRootGrid"
Margin="0,0,4,0"
HorizontalAlignment="Stretch"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
PointerCanceled="StackPanel_PointerCanceled"
PointerEntered="StackPanel_PointerEntered"
PointerExited="StackPanel_PointerCanceled"
PointerPressed="RootPanel_PointerPressed"
PointerReleased="StackPanel_PointerCanceled">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ContentPresenter
x:Name="ContentPresenter"
Grid.Column="0"
Margin="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}" />
<Rectangle
Grid.Column="1"
Height="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Stroke="{ThemeResource GridViewHeaderItemDividerStroke}"
StrokeThickness="0.5" />

<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />

<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HeaderItemRootGrid" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HeaderItemRootGrid" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPointerOver}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<VisualState.Setters>
<!--<Setter Target="ContentPresenter.(local:AnimatedIcon.State)" Value="PointerOver" />-->
</VisualState.Setters>
</VisualState>

<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HeaderItemRootGrid" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPressed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HeaderItemRootGrid" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPressed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<VisualState.Setters>
<!--<Setter Target="ContentPresenter.(local:AnimatedIcon.State)" Value="Pressed" />-->
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</local:BaseLayout.Resources>
<Grid x:Name="RootGrid" ContextFlyout="{x:Bind BaseContextMenuFlyout}">
<controls:BladeView x:Name="ColumnHost">
Expand Down
Loading