diff --git a/src/Files/Views/ColumnShellPage.xaml.cs b/src/Files/Views/ColumnShellPage.xaml.cs index 0b85a92fe220..3858a4e5e99f 100644 --- a/src/Files/Views/ColumnShellPage.xaml.cs +++ b/src/Files/Views/ColumnShellPage.xaml.cs @@ -745,12 +745,54 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio public void Back_Click() { - this.FindAscendant().NavigateBack(); + 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(); + } + } + else + { + this.FindAscendant().NavigateBack(); + } } public void Forward_Click() { - this.FindAscendant().NavigateForward(); + 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(); + } + else + { + this.FindAscendant().NavigateForward(); + } } public void Up_Click() @@ -818,11 +860,9 @@ private void FilesystemViewModel_ItemLoadStatusChanged(object sender, ItemLoadSt break; case ItemLoadStatusChangedEventArgs.ItemLoadStatus.InProgress: - if (this.FindAscendant() is ColumnViewBrowser browser) - { - NavToolbarViewModel.CanGoBack = browser.ParentShellPageInstance.CanNavigateBackward; - NavToolbarViewModel.CanGoForward = browser.ParentShellPageInstance.CanNavigateForward; - } + var browser = this.FindAscendant(); + NavToolbarViewModel.CanGoBack = ItemDisplayFrame.CanGoBack || browser.ParentShellPageInstance.CanNavigateBackward; + NavToolbarViewModel.CanGoForward = ItemDisplayFrame.CanGoForward || browser.ParentShellPageInstance.CanNavigateForward; SetLoadingIndicatorForTabs(true); break; @@ -892,38 +932,7 @@ public void NavigateWithArguments(Type sourcePageType, NavigationArguments navAr public void NavigateToPath(string navigationPath, Type sourcePageType, NavigationArguments navArgs = null) { - if (navArgs != null && navArgs.AssociatedTabInstance != null) - { - ItemDisplayFrame.Navigate( - sourcePageType = typeof(ColumnViewBase), - navArgs, - new SuppressNavigationTransitionInfo()); - } - else - { - if (string.IsNullOrEmpty(navigationPath) || - string.IsNullOrEmpty(FilesystemViewModel?.WorkingDirectory) || - navigationPath.TrimEnd(Path.DirectorySeparatorChar).Equals( - FilesystemViewModel.WorkingDirectory.TrimEnd(Path.DirectorySeparatorChar), - StringComparison.OrdinalIgnoreCase)) // return if already selected - { - if (InstanceViewModel?.FolderSettings is FolderSettingsViewModel fsModel) - { - fsModel.IsLayoutModeChanging = false; - } - return; - } - - ItemDisplayFrame.Navigate(sourcePageType = typeof(ColumnViewBase), - new NavigationArguments() - { - NavPathParam = navigationPath, - AssociatedTabInstance = this - }, - new SuppressNavigationTransitionInfo()); - } - - NavToolbarViewModel.PathControlDisplayText = FilesystemViewModel.WorkingDirectory; + this.FindAscendant().SetSelectedPathOrNavigate(navigationPath, sourcePageType, navArgs); } public void NavigateToPath(string navigationPath, NavigationArguments navArgs = null) @@ -933,13 +942,7 @@ public void NavigateToPath(string navigationPath, NavigationArguments navArgs = public void NavigateHome() { - ItemDisplayFrame.Navigate(typeof(WidgetsPage), - new NavigationArguments() - { - NavPathParam = "Home".GetLocalized(), - AssociatedTabInstance = this - }, - new EntranceNavigationTransitionInfo()); + throw new NotImplementedException("Can't show Home page in Column View"); } public void RemoveLastPageFromBackStack() @@ -960,6 +963,7 @@ public void SubmitSearch(string query, bool searchUnindexedItems) SearchQuery = query, SearchUnindexedItems = searchUnindexedItems, }); + //this.FindAscendant().SetSelectedPathOrNavigate(null, typeof(ColumnViewBase), navArgs); } } } \ No newline at end of file diff --git a/src/Files/Views/LayoutModes/ColumnViewBase.xaml.cs b/src/Files/Views/LayoutModes/ColumnViewBase.xaml.cs index 929f5074c9d9..c497a28bff58 100644 --- a/src/Files/Views/LayoutModes/ColumnViewBase.xaml.cs +++ b/src/Files/Views/LayoutModes/ColumnViewBase.xaml.cs @@ -264,6 +264,10 @@ private void EndRename(TextBox textBox) } else { + // Re-focus selected list item + ListViewItem listViewItem = FileList.ContainerFromItem(RenamingItem) as ListViewItem; + listViewItem?.Focus(FocusState.Programmatic); + textBox.Visibility = Visibility.Collapsed; RenamingTextBlock.Visibility = Visibility.Visible; } @@ -272,10 +276,6 @@ private void EndRename(TextBox textBox) textBox.KeyDown -= RenameTextBox_KeyDown; FileNameTeachingTip.IsOpen = false; IsRenamingItem = false; - - // Re-focus selected list item - ListViewItem listViewItem = FileList.ContainerFromItem(RenamingItem) as ListViewItem; - listViewItem?.Focus(FocusState.Programmatic); } public override void ResetItemOpacity() @@ -435,6 +435,28 @@ private async void FileList_PreviewKeyDown(object sender, KeyRoutedEventArgs e) } } + protected override void Page_CharacterReceived(CoreWindow sender, CharacterReceivedEventArgs args) + { + if (ParentShellPageInstance != null) + { + if (ParentShellPageInstance.CurrentPageType == typeof(ColumnViewBase) && !IsRenamingItem) + { + // Don't block the various uses of enter key (key 13) + var focusedElement = FocusManager.GetFocusedElement() as FrameworkElement; + if (args.KeyCode == 13 + || focusedElement is Button + || focusedElement is TextBox + || focusedElement is PasswordBox + || DependencyObjectHelpers.FindParent(focusedElement) != null) + { + return; + } + + base.Page_CharacterReceived(sender, args); + } + } + } + private void FileList_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e) { var clickedItem = e.OriginalSource as FrameworkElement; @@ -486,18 +508,10 @@ private void FileList_ItemTapped(object sender, TappedRoutedEventArgs e) } // Check if the setting to open items with a single click is turned on if (item != null - && ((item.PrimaryItemAttribute == StorageItemTypes.Folder) || (UserSettingsService.PreferencesSettingsService.OpenFilesWithOneClick && item.PrimaryItemAttribute == StorageItemTypes.File))) + && (UserSettingsService.PreferencesSettingsService.OpenFilesWithOneClick && item.PrimaryItemAttribute == StorageItemTypes.File)) { ResetRenameDoubleClick(); - - if (item.PrimaryItemAttribute == StorageItemTypes.Folder) - { - ItemInvoked?.Invoke(new ColumnParam { NavPathParam = (item is ShortcutItem sht ? sht.TargetPath : item.ItemPath), ListView = FileList }, EventArgs.Empty); - } - else - { - NavigationHelpers.OpenSelectedItems(ParentShellPageInstance, false); - } + NavigationHelpers.OpenSelectedItems(ParentShellPageInstance, false); } else { @@ -514,6 +528,10 @@ private void FileList_ItemTapped(object sender, TappedRoutedEventArgs e) CommitRename(textBox); } } + if (item != null && item.PrimaryItemAttribute == StorageItemTypes.Folder) + { + ItemInvoked?.Invoke(new ColumnParam { NavPathParam = (item is ShortcutItem sht ? sht.TargetPath : item.ItemPath), ListView = FileList }, EventArgs.Empty); + } } } diff --git a/src/Files/Views/LayoutModes/ColumnViewBrowser.xaml.cs b/src/Files/Views/LayoutModes/ColumnViewBrowser.xaml.cs index f63e33718d46..98894f1a7716 100644 --- a/src/Files/Views/LayoutModes/ColumnViewBrowser.xaml.cs +++ b/src/Files/Views/LayoutModes/ColumnViewBrowser.xaml.cs @@ -94,6 +94,7 @@ protected override void InitializeCommandsViewModel() protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) { base.OnNavigatingFrom(e); + this.Dispose(); } #region IDisposable @@ -102,6 +103,7 @@ public override void Dispose() { base.Dispose(); ColumnHost.ActiveBlades.Select(x => ((x.Content as Frame)?.Content as ColumnShellPage).SlimContentPage as ColumnViewBase).Where(x => x != null).ForEach(x => x.ItemInvoked -= ColumnViewBase_ItemInvoked); + ColumnHost.ActiveBlades.ForEach(x => ((x.Content as Frame)?.Content as ColumnShellPage).ContentChanged -= ColumnViewBrowser_ContentChanged); ColumnHost.ActiveBlades.ForEach(x => ((x.Content as Frame)?.Content as UIElement).GotFocus -= ColumnViewBrowser_GotFocus); ColumnHost.ActiveBlades.Select(x => (x.Content as Frame)?.Content).OfType().ForEach(x => x.Dispose()); UnhookEvents(); @@ -117,7 +119,11 @@ private void DismissOtherBlades(ListView listView) private void DismissOtherBlades(BladeItem blade) { - var index = ColumnHost.ActiveBlades.IndexOf(blade); + DismissOtherBlades(ColumnHost.ActiveBlades.IndexOf(blade)); + } + + private void DismissOtherBlades(int index) + { if (index >= 0) { Common.Extensions.IgnoreExceptions(() => @@ -133,6 +139,7 @@ private void DismissOtherBlades(BladeItem blade) columnLayout.ItemInvoked -= ColumnViewBase_ItemInvoked; } ((ColumnHost.ActiveBlades[index + 1].Content as Frame).Content as UIElement).GotFocus -= ColumnViewBrowser_GotFocus; + ((ColumnHost.ActiveBlades[index + 1].Content as Frame).Content as ColumnShellPage).ContentChanged -= ColumnViewBrowser_ContentChanged; ColumnHost.Items.RemoveAt(index + 1); ColumnHost.ActiveBlades.RemoveAt(index + 1); } @@ -171,7 +178,6 @@ private void ColumnViewBrowser_GotFocus(object sender, RoutedEventArgs e) private void ColumnViewBrowser_ContentChanged(object sender, UserControls.MultitaskingControl.TabItemArguments e) { var c = sender as IShellPage; - c.ContentChanged -= ColumnViewBrowser_ContentChanged; (c.SlimContentPage as ColumnViewBase).ItemInvoked -= ColumnViewBase_ItemInvoked; (c.SlimContentPage as ColumnViewBase).ItemInvoked += ColumnViewBase_ItemInvoked; ContentChanged(c); @@ -199,6 +205,68 @@ public void NavigateUp() } } + public void SetSelectedPathOrNavigate(string navigationPath, Type sourcePageType, NavigationArguments navArgs = null) + { + var destPath = navArgs != null ? (navArgs.IsSearchResultPage ? navArgs.SearchPathParam : navArgs.NavPathParam) : navigationPath; + var columnPath = ((ColumnHost.ActiveBlades.Last().Content as Frame)?.Content as ColumnShellPage)?.FilesystemViewModel.WorkingDirectory; + var columnFirstPath = ((ColumnHost.ActiveBlades.First().Content as Frame)?.Content as ColumnShellPage)?.FilesystemViewModel.WorkingDirectory; + + if (string.IsNullOrEmpty(destPath) || string.IsNullOrEmpty(destPath) || string.IsNullOrEmpty(destPath)) + { + ParentShellPageInstance.NavigateToPath(navigationPath, sourcePageType, navArgs); + return; + } + + var destComponents = StorageFileExtensions.GetDirectoryPathComponents(destPath); + var columnComponents = StorageFileExtensions.GetDirectoryPathComponents(columnPath); + var columnFirstComponents = StorageFileExtensions.GetDirectoryPathComponents(columnFirstPath); + + var lastCommonItemIndex = columnComponents + .Select((value, index) => new { value, index }) + .LastOrDefault(x => x.index < destComponents.Count && x.value.Path == destComponents[x.index].Path)?.index ?? -1; + + var relativeIndex = lastCommonItemIndex - (columnFirstComponents.Count - 1); + + if (relativeIndex < 0 || destComponents.Count - (lastCommonItemIndex + 1) > 1) // Going above parent or too deep down + { + ParentShellPageInstance.NavigateToPath(navigationPath, sourcePageType, navArgs); + } + else + { + DismissOtherBlades(relativeIndex); + + for (int ii = lastCommonItemIndex + 1; ii < destComponents.Count; ii++) + { + var frame = new Frame(); + frame.Navigated += Frame_Navigated; + var newblade = new BladeItem(); + newblade.Content = frame; + ColumnHost.Items.Add(newblade); + + if (navArgs != null) + { + frame.Navigate(typeof(ColumnShellPage), new ColumnParam + { + Column = ColumnHost.ActiveBlades.IndexOf(newblade), + IsSearchResultPage = navArgs.IsSearchResultPage, + SearchQuery = navArgs.SearchQuery, + NavPathParam = destComponents[ii].Path, + SearchUnindexedItems = navArgs.SearchUnindexedItems, + SearchPathParam = navArgs.SearchPathParam + }); + } + else + { + frame.Navigate(typeof(ColumnShellPage), new ColumnParam + { + Column = ColumnHost.ActiveBlades.IndexOf(newblade), + NavPathParam = destComponents[ii].Path + }); + } + } + } + } + public void SetSelectedPathOrNavigate(PathNavigationEventArgs e) { if (ColumnHost.ActiveBlades?.Count > 1)