diff --git a/Files/App.xaml.cs b/Files/App.xaml.cs index 0990f8dbba17..b8d13158811d 100644 --- a/Files/App.xaml.cs +++ b/Files/App.xaml.cs @@ -195,9 +195,9 @@ protected override async void OnLaunched(LaunchActivatedEventArgs e) } else { - if (!(string.IsNullOrEmpty(e.Arguments) && MainPage.AppInstances.Count > 0)) + if (!(string.IsNullOrEmpty(e.Arguments) && MainPageViewModel.AppInstances.Count > 0)) { - await MainPage.AddNewTabByPathAsync(typeof(PaneHolderPage), e.Arguments); + await MainPageViewModel.AddNewTabByPathAsync(typeof(PaneHolderPage), e.Arguments); } } @@ -421,7 +421,7 @@ public static void SaveSessionTabs() // Enumerates through all tabs and gets the { if (AppSettings != null) { - AppSettings.LastSessionPages = MainPage.AppInstances.DefaultIfEmpty().Select(tab => + AppSettings.LastSessionPages = MainPageViewModel.AppInstances.DefaultIfEmpty().Select(tab => { if (tab != null && tab.TabItemArguments != null) { diff --git a/Files/DataModels/SidebarPinnedModel.cs b/Files/DataModels/SidebarPinnedModel.cs index 96ac901566a4..b847c649f188 100644 --- a/Files/DataModels/SidebarPinnedModel.cs +++ b/Files/DataModels/SidebarPinnedModel.cs @@ -2,8 +2,8 @@ using Files.Controllers; using Files.Filesystem; using Files.Helpers; +using Files.UserControls; using Files.ViewModels; -using Files.Views; using Microsoft.Toolkit.Uwp; using Newtonsoft.Json; using System; @@ -12,6 +12,7 @@ using System.Diagnostics; using System.IO; using System.Linq; +using System.Threading; using System.Threading.Tasks; using Windows.Storage; using Windows.UI.Xaml; @@ -96,7 +97,7 @@ public async void AddItem(string item) public async Task ShowHideRecycleBinItemAsync(bool show) { - await MainPage.SideBarItemsSemaphore.WaitAsync(); + await SidebarControl.SideBarItemsSemaphore.WaitAsync(); try { if (show) @@ -129,7 +130,7 @@ public async Task ShowHideRecycleBinItemAsync(bool show) } finally { - MainPage.SideBarItemsSemaphore.Release(); + SidebarControl.SideBarItemsSemaphore.Release(); } } @@ -303,10 +304,10 @@ private void AddItemToSidebarAsync(LocationItem section) /// public async Task AddAllItemsToSidebar() { - await MainPage.SideBarItemsSemaphore.WaitAsync(); + await SidebarControl.SideBarItemsSemaphore.WaitAsync(); try { - MainPage.SideBarItems.BeginBulkOperation(); + SidebarControl.SideBarItems.BeginBulkOperation(); if (homeSection != null) { @@ -319,16 +320,16 @@ public async Task AddAllItemsToSidebar() await AddItemToSidebarAsync(path); } - if (!MainPage.SideBarItems.Contains(favoriteSection)) + if (!SidebarControl.SideBarItems.Contains(favoriteSection)) { - MainPage.SideBarItems.Add(favoriteSection); + SidebarControl.SideBarItems.Add(favoriteSection); } - MainPage.SideBarItems.EndBulkOperation(); + SidebarControl.SideBarItems.EndBulkOperation(); } finally { - MainPage.SideBarItemsSemaphore.Release(); + SidebarControl.SideBarItemsSemaphore.Release(); } await ShowHideRecycleBinItemAsync(App.AppSettings.PinRecycleBinToSideBar); diff --git a/Files/Dialogs/ExceptionDialog.xaml.cs b/Files/Dialogs/ExceptionDialog.xaml.cs index 1341c7f871e9..1614a5607c97 100644 --- a/Files/Dialogs/ExceptionDialog.xaml.cs +++ b/Files/Dialogs/ExceptionDialog.xaml.cs @@ -1,4 +1,5 @@ -using Files.Views; +using Files.ViewModels; +using Files.Views; using System.Linq; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; @@ -20,13 +21,13 @@ public ExceptionDialog() private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) { - if (MainPage.MultitaskingControl.Items.Count == 1) + if (MainPageViewModel.MultitaskingControl.Items.Count == 1) { App.CloseApp(); } - else if (MainPage.MultitaskingControl.Items.Count > 1) + else if (MainPageViewModel.MultitaskingControl.Items.Count > 1) { - MainPage.MultitaskingControl.RemoveTab(MainPage.MultitaskingControl.Items.ElementAt(App.InteractionViewModel.TabStripSelectedIndex)); + MainPageViewModel.MultitaskingControl?.CloseTab(MainPageViewModel.MultitaskingControl.Items.ElementAt(App.InteractionViewModel.TabStripSelectedIndex)); } } diff --git a/Files/Files.csproj b/Files/Files.csproj index 1812a87887aa..83c462d3ff18 100644 --- a/Files/Files.csproj +++ b/Files/Files.csproj @@ -220,7 +220,7 @@ RestartControl.xaml - + @@ -236,6 +236,7 @@ + @@ -290,6 +291,7 @@ + diff --git a/Files/Filesystem/CloudDrivesManager.cs b/Files/Filesystem/CloudDrivesManager.cs index 8d8de241ecea..2b26da591f9b 100644 --- a/Files/Filesystem/CloudDrivesManager.cs +++ b/Files/Filesystem/CloudDrivesManager.cs @@ -1,5 +1,5 @@ using Files.Filesystem.Cloud; -using Files.Views; +using Files.UserControls; using Microsoft.Toolkit.Mvvm.ComponentModel; using Microsoft.Toolkit.Uwp; using NLog; @@ -84,12 +84,12 @@ private async Task SyncSideBarItemsUI() { await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => { - await MainPage.SideBarItemsSemaphore.WaitAsync(); + await SidebarControl.SideBarItemsSemaphore.WaitAsync(); try { - MainPage.SideBarItems.BeginBulkOperation(); + SidebarControl.SideBarItems.BeginBulkOperation(); - var section = MainPage.SideBarItems.FirstOrDefault(x => x.Text == "SidebarCloudDrives".GetLocalized()) as LocationItem; + var section = SidebarControl.SideBarItems.FirstOrDefault(x => x.Text == "SidebarCloudDrives".GetLocalized()) as LocationItem; if (section == null) { section = new LocationItem() @@ -100,7 +100,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio SelectsOnInvoked = false, ChildItems = new ObservableCollection() }; - MainPage.SideBarItems.Add(section); + SidebarControl.SideBarItems.Add(section); } foreach (DriveItem drive in Drives.ToList()) @@ -111,11 +111,11 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio } } - MainPage.SideBarItems.EndBulkOperation(); + SidebarControl.SideBarItems.EndBulkOperation(); } finally { - MainPage.SideBarItemsSemaphore.Release(); + SidebarControl.SideBarItemsSemaphore.Release(); } }); } diff --git a/Files/Filesystem/Drives.cs b/Files/Filesystem/Drives.cs index ca618df8138d..a1f6fd89f682 100644 --- a/Files/Filesystem/Drives.cs +++ b/Files/Filesystem/Drives.cs @@ -1,7 +1,7 @@ using Files.Common; using Files.Enums; +using Files.UserControls; using Files.UserControls.Widgets; -using Files.Views; using Microsoft.Toolkit.Mvvm.ComponentModel; using Microsoft.Toolkit.Uwp; using Microsoft.Toolkit.Uwp.Helpers; @@ -122,12 +122,12 @@ private async Task SyncSideBarItemsUI() { await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => { - await MainPage.SideBarItemsSemaphore.WaitAsync(); + await SidebarControl.SideBarItemsSemaphore.WaitAsync(); try { - MainPage.SideBarItems.BeginBulkOperation(); + SidebarControl.SideBarItems.BeginBulkOperation(); - var section = MainPage.SideBarItems.FirstOrDefault(x => x.Text == "SidebarDrives".GetLocalized()) as LocationItem; + var section = SidebarControl.SideBarItems.FirstOrDefault(x => x.Text == "SidebarDrives".GetLocalized()) as LocationItem; if (section == null) { section = new LocationItem() @@ -138,7 +138,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio SelectsOnInvoked = false, ChildItems = new ObservableCollection() }; - MainPage.SideBarItems.Add(section); + SidebarControl.SideBarItems.Add(section); } foreach (DriveItem drive in Drives.ToList()) @@ -163,11 +163,11 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio } } - MainPage.SideBarItems.EndBulkOperation(); + SidebarControl.SideBarItems.EndBulkOperation(); } finally { - MainPage.SideBarItemsSemaphore.Release(); + SidebarControl.SideBarItemsSemaphore.Release(); } }); } diff --git a/Files/Filesystem/LibraryManager.cs b/Files/Filesystem/LibraryManager.cs index 1ffafb849513..404b7a50677c 100644 --- a/Files/Filesystem/LibraryManager.cs +++ b/Files/Filesystem/LibraryManager.cs @@ -1,6 +1,6 @@ using Files.Helpers; +using Files.UserControls; using Files.ViewModels; -using Files.Views; using Microsoft.Toolkit.Mvvm.ComponentModel; using Microsoft.Toolkit.Uwp; using System; @@ -69,34 +69,34 @@ private async void RemoveEnumerateDrivesAsync(CoreApplicationView sender, Window public async Task RemoveLibrarySideBarItemsUI() { - MainPage.SideBarItems.BeginBulkOperation(); + SidebarControl.SideBarItems.BeginBulkOperation(); try { - var item = (from n in MainPage.SideBarItems where n.Text.Equals("SidebarLibraries".GetLocalized()) select n).FirstOrDefault(); + var item = (from n in SidebarControl.SideBarItems where n.Text.Equals("SidebarLibraries".GetLocalized()) select n).FirstOrDefault(); if (!App.AppSettings.ShowLibrarySection && item != null) { - MainPage.SideBarItems.Remove(item); + SidebarControl.SideBarItems.Remove(item); } } catch (Exception) { } - MainPage.SideBarItems.EndBulkOperation(); + SidebarControl.SideBarItems.EndBulkOperation(); } private async Task SyncLibrarySideBarItemsUI() { await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => { - await MainPage.SideBarItemsSemaphore.WaitAsync(); + await SidebarControl.SideBarItemsSemaphore.WaitAsync(); try { - MainPage.SideBarItems.BeginBulkOperation(); + SidebarControl.SideBarItems.BeginBulkOperation(); try { - if (App.AppSettings.ShowLibrarySection && !MainPage.SideBarItems.Contains(librarySection)) + if (App.AppSettings.ShowLibrarySection && !SidebarControl.SideBarItems.Contains(librarySection)) { librarySection = new LocationItem() { @@ -107,8 +107,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio SelectsOnInvoked = false, ChildItems = new ObservableCollection() }; - - MainPage.SideBarItems.Insert(1, librarySection); + SidebarControl.SideBarItems.Insert(1, librarySection); libraryItems.Clear(); libraryItems.Add(AppSettings.DocumentsPath); @@ -144,13 +143,13 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio { } - MainPage.SideBarItems.EndBulkOperation(); + SidebarControl.SideBarItems.EndBulkOperation(); } finally { - MainPage.SideBarItemsSemaphore.Release(); + SidebarControl.SideBarItemsSemaphore.Release(); } }); } } -} \ No newline at end of file +} diff --git a/Files/Filesystem/NetworkDrivesManager.cs b/Files/Filesystem/NetworkDrivesManager.cs index 7311b742d11b..f685cd9bb1bc 100644 --- a/Files/Filesystem/NetworkDrivesManager.cs +++ b/Files/Filesystem/NetworkDrivesManager.cs @@ -1,5 +1,5 @@ using Files.Helpers; -using Files.Views; +using Files.UserControls; using Microsoft.Toolkit.Mvvm.ComponentModel; using Microsoft.Toolkit.Uwp; using NLog; @@ -107,12 +107,12 @@ private async Task SyncSideBarItemsUI() { await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => { - await MainPage.SideBarItemsSemaphore.WaitAsync(); + await SidebarControl.SideBarItemsSemaphore.WaitAsync(); try { - MainPage.SideBarItems.BeginBulkOperation(); + SidebarControl.SideBarItems.BeginBulkOperation(); - var section = MainPage.SideBarItems.FirstOrDefault(x => x.Text == "SidebarNetworkDrives".GetLocalized()) as LocationItem; + var section = SidebarControl.SideBarItems.FirstOrDefault(x => x.Text == "SidebarNetworkDrives".GetLocalized()) as LocationItem; if (section == null && this.drivesList.Any(d => d.DeviceID != "network-folder")) { section = new LocationItem() @@ -123,7 +123,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio SelectsOnInvoked = false, ChildItems = new ObservableCollection() }; - MainPage.SideBarItems.Add(section); + SidebarControl.SideBarItems.Add(section); } if (section != null) @@ -139,11 +139,11 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio } } - MainPage.SideBarItems.EndBulkOperation(); + SidebarControl.SideBarItems.EndBulkOperation(); } finally { - MainPage.SideBarItemsSemaphore.Release(); + SidebarControl.SideBarItemsSemaphore.Release(); } }); } diff --git a/Files/Filesystem/StorageFileHelpers/StorageFileExtensions.cs b/Files/Filesystem/StorageFileHelpers/StorageFileExtensions.cs index 280747b8b26e..a022eb780753 100644 --- a/Files/Filesystem/StorageFileHelpers/StorageFileExtensions.cs +++ b/Files/Filesystem/StorageFileHelpers/StorageFileExtensions.cs @@ -1,5 +1,6 @@ using Files.Common; using Files.Extensions; +using Files.UserControls; using Files.ViewModels; using Files.Views; using System; @@ -29,7 +30,7 @@ private static PathBoxItem GetPathItem(string component, string path) } else if (component.Contains(":")) { - var allDrives = MainPage.SideBarItems.Where(x => (x as LocationItem)?.ChildItems != null).SelectMany(x => (x as LocationItem).ChildItems); + var allDrives = SidebarControl.SideBarItems.Where(x => (x as LocationItem)?.ChildItems != null).SelectMany(x => (x as LocationItem).ChildItems); return new PathBoxItem() { Title = allDrives.FirstOrDefault(y => y.ItemType == NavigationControlItemType.Drive && y.Path.Contains(component, StringComparison.OrdinalIgnoreCase)) != null ? diff --git a/Files/Filesystem/WSLDistroManager.cs b/Files/Filesystem/WSLDistroManager.cs index 3c4d42ef09cf..2c2505e94b52 100644 --- a/Files/Filesystem/WSLDistroManager.cs +++ b/Files/Filesystem/WSLDistroManager.cs @@ -1,4 +1,4 @@ -using Files.Views; +using Files.UserControls; using Microsoft.Toolkit.Mvvm.ComponentModel; using System; using System.Collections.ObjectModel; @@ -40,17 +40,17 @@ private async Task SyncSideBarItemsUI() { await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => { - await MainPage.SideBarItemsSemaphore.WaitAsync(); + await SidebarControl.SideBarItemsSemaphore.WaitAsync(); try { - MainPage.SideBarItems.BeginBulkOperation(); + SidebarControl.SideBarItems.BeginBulkOperation(); try { var distroFolder = await StorageFolder.GetFolderFromPathAsync(@"\\wsl$\"); if ((await distroFolder.GetFoldersAsync()).Count != 0) { - var section = MainPage.SideBarItems.FirstOrDefault(x => x.Text == "WSL") as LocationItem; + var section = SidebarControl.SideBarItems.FirstOrDefault(x => x.Text == "WSL") as LocationItem; if (section == null) { section = new LocationItem() @@ -61,7 +61,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio SelectsOnInvoked = false, ChildItems = new ObservableCollection() }; - MainPage.SideBarItems.Add(section); + SidebarControl.SideBarItems.Add(section); } foreach (StorageFolder folder in await distroFolder.GetFoldersAsync()) @@ -109,11 +109,11 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio // WSL Not Supported/Enabled } - MainPage.SideBarItems.EndBulkOperation(); + SidebarControl.SideBarItems.EndBulkOperation(); } finally { - MainPage.SideBarItemsSemaphore.Release(); + SidebarControl.SideBarItemsSemaphore.Release(); } }); } diff --git a/Files/Helpers/DeviceHelpers.cs b/Files/Helpers/DriveHelpers.cs similarity index 58% rename from Files/Helpers/DeviceHelpers.cs rename to Files/Helpers/DriveHelpers.cs index 2907d32efae6..1640ef61cf99 100644 --- a/Files/Helpers/DeviceHelpers.cs +++ b/Files/Helpers/DriveHelpers.cs @@ -7,7 +7,7 @@ namespace Files.Helpers { - public static class DeviceHelpers + public static class DriveHelpers { public static async Task EjectDeviceAsync(string path) { @@ -58,5 +58,54 @@ await DialogDisplayHelper.ShowDialogAsync( "EjectNotificationErrorDialogBody".GetLocalized()); } } + + public static string GetDriveTypeIcon(System.IO.DriveInfo drive) + { + string type; + + switch (drive.DriveType) + { + case System.IO.DriveType.CDRom: + type = "\xE958"; + break; + + case System.IO.DriveType.Fixed: + type = "\xEDA2"; + break; + + case System.IO.DriveType.Network: + type = "\xE8CE"; + break; + + case System.IO.DriveType.NoRootDirectory: + type = "\xED25"; + break; + + case System.IO.DriveType.Ram: + type = "\xE950"; + break; + + case System.IO.DriveType.Removable: + type = "\xE88E"; + break; + + case System.IO.DriveType.Unknown: + if (PathNormalization.NormalizePath(drive.Name) != PathNormalization.NormalizePath("A:") && PathNormalization.NormalizePath(drive.Name) != PathNormalization.NormalizePath("B:")) + { + type = "\xEDA2"; + } + else + { + type = "\xE74E"; // Floppy icon + } + break; + + default: + type = "\xEDA2"; // Drive icon + break; + } + + return type; + } } } \ No newline at end of file diff --git a/Files/Helpers/MultitaskingTabsHelpers.cs b/Files/Helpers/MultitaskingTabsHelpers.cs new file mode 100644 index 000000000000..eeaa029c3d8d --- /dev/null +++ b/Files/Helpers/MultitaskingTabsHelpers.cs @@ -0,0 +1,70 @@ +using Files.UserControls.MultitaskingControl; +using Files.ViewModels; +using Microsoft.Toolkit.Uwp; +using Microsoft.UI.Xaml.Controls; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.UI.Xaml; + +namespace Files.Helpers +{ + public static class MultitaskingTabsHelpers + { + public static void CloseTabsToTheRight(TabItem clickedTab) + { + int index = MainPageViewModel.AppInstances.IndexOf(clickedTab); + List tabsToClose = new List(); + + for (int i = index + 1; i < MainPageViewModel.AppInstances.Count; i++) + { + tabsToClose.Add(MainPageViewModel.AppInstances[i]); + } + + foreach (var item in tabsToClose) + { + MainPageViewModel.MultitaskingControl?.CloseTab(item); + } + } + + public static async Task MoveTabToNewWindow(TabItem tab) + { + int index = MainPageViewModel.AppInstances.IndexOf(tab); + TabItemArguments tabItemArguments = MainPageViewModel.AppInstances[index].TabItemArguments; + + MainPageViewModel.MultitaskingControl?.CloseTab(MainPageViewModel.AppInstances[index]); + + if (tabItemArguments != null) + { + await NavigationHelpers.OpenTabInNewWindowAsync(tabItemArguments.Serialize()); + } + else + { + await NavigationHelpers.OpenPathInNewWindowAsync("NewTab".GetLocalized()); + } + } + + public static async Task AddNewTab(Type type, object tabViewItemArgs, int atIndex = -1) + { + FontIconSource fontIconSource = new FontIconSource(); + fontIconSource.FontFamily = App.InteractionViewModel.FontName; + + TabItem tabItem = new TabItem() + { + Header = null, + IconSource = fontIconSource, + Description = null + }; + tabItem.Control.NavigationArguments = new TabItemArguments() + { + InitialPageType = type, + NavigationArg = tabViewItemArgs + }; + tabItem.Control.ContentChanged += MainPageViewModel.Control_ContentChanged; + await MainPageViewModel.UpdateTabInfo(tabItem, tabViewItemArgs); + MainPageViewModel.AppInstances.Insert(atIndex == -1 ? MainPageViewModel.AppInstances.Count : atIndex, tabItem); + } + } +} diff --git a/Files/Helpers/NavigationHelpers.cs b/Files/Helpers/NavigationHelpers.cs index 52dfecb4b9c3..febef6805a0f 100644 --- a/Files/Helpers/NavigationHelpers.cs +++ b/Files/Helpers/NavigationHelpers.cs @@ -2,8 +2,6 @@ using Files.Views; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading.Tasks; using Windows.ApplicationModel.AppService; using Windows.Foundation.Collections; @@ -15,6 +13,7 @@ using Microsoft.Toolkit.Uwp; using Windows.UI.Core; using Windows.ApplicationModel.Core; +using Files.ViewModels; namespace Files.Helpers { @@ -22,7 +21,7 @@ public static class NavigationHelpers { public static async void OpenPathInNewTab(string path) { - await MainPage.AddNewTabByPathAsync(typeof(PaneHolderPage), path); + await MainPageViewModel.AddNewTabByPathAsync(typeof(PaneHolderPage), path); } public static async Task OpenPathInNewWindowAsync(string path) diff --git a/Files/Interacts/BaseLayoutCommandImplementationModel.cs b/Files/Interacts/BaseLayoutCommandImplementationModel.cs index 84623bad2dff..0da86d6ca474 100644 --- a/Files/Interacts/BaseLayoutCommandImplementationModel.cs +++ b/Files/Interacts/BaseLayoutCommandImplementationModel.cs @@ -17,6 +17,7 @@ using System.Diagnostics; using Windows.Foundation; using Windows.UI.Xaml.Input; +using Files.ViewModels; namespace Files.Interacts { @@ -247,7 +248,7 @@ public virtual async void OpenDirectoryInNewTab(RoutedEventArgs e) { await CoreWindow.GetForCurrentThread().Dispatcher.RunAsync(CoreDispatcherPriority.Low, async () => { - await MainPage.AddNewTabByPathAsync(typeof(PaneHolderPage), (listedItem as ShortcutItem)?.TargetPath ?? listedItem.ItemPath); + await MainPageViewModel.AddNewTabByPathAsync(typeof(PaneHolderPage), (listedItem as ShortcutItem)?.TargetPath ?? listedItem.ItemPath); }); } } diff --git a/Files/UserControls/MultitaskingControl/BaseMultitaskingControl.cs b/Files/UserControls/MultitaskingControl/BaseMultitaskingControl.cs index b52e50bff7f1..0a75153b5e26 100644 --- a/Files/UserControls/MultitaskingControl/BaseMultitaskingControl.cs +++ b/Files/UserControls/MultitaskingControl/BaseMultitaskingControl.cs @@ -1,4 +1,5 @@ -using Files.Views; +using Files.ViewModels; +using Files.Views; using Microsoft.UI.Xaml.Controls; using System; using System.Collections.Generic; @@ -30,7 +31,7 @@ public BaseMultitaskingControl() Loaded += MultitaskingControl_Loaded; } - public ObservableCollection Items => MainPage.AppInstances; + public ObservableCollection Items => MainPageViewModel.AppInstances; public List RecentlyClosedTabs { get; private set; } = new List(); @@ -64,12 +65,12 @@ protected void TabStrip_SelectionChanged(object sender, SelectionChangedEventArg protected void TabStrip_TabCloseRequested(TabView sender, TabViewTabCloseRequestedEventArgs args) { - RemoveTab(args.Item as TabItem); + CloseTab(args.Item as TabItem); } protected async void TabView_AddTabButtonClick(TabView sender, object args) { - await MainPage.AddNewTabAsync(); + await MainPageViewModel.AddNewTabAsync(); } public void MultitaskingControl_Loaded(object sender, RoutedEventArgs e) @@ -79,15 +80,15 @@ public void MultitaskingControl_Loaded(object sender, RoutedEventArgs e) public ITabItemContent GetCurrentSelectedTabInstance() { - return MainPage.AppInstances[App.InteractionViewModel.TabStripSelectedIndex].Control?.TabItemContent; + return MainPageViewModel.AppInstances[App.InteractionViewModel.TabStripSelectedIndex].Control?.TabItemContent; } public List GetAllTabInstances() { - return MainPage.AppInstances.Select(x => x.Control?.TabItemContent).ToList(); + return MainPageViewModel.AppInstances.Select(x => x.Control?.TabItemContent).ToList(); } - public void RemoveTab(TabItem tabItem) + public void CloseTab(TabItem tabItem) { if (Items.Count == 1) { diff --git a/Files/UserControls/MultitaskingControl/HorizontalMultitaskingControl.xaml b/Files/UserControls/MultitaskingControl/HorizontalMultitaskingControl.xaml index 661698753694..cef5d6eb2e85 100644 --- a/Files/UserControls/MultitaskingControl/HorizontalMultitaskingControl.xaml +++ b/Files/UserControls/MultitaskingControl/HorizontalMultitaskingControl.xaml @@ -11,7 +11,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:muxc="using:Microsoft.UI.Xaml.Controls" xmlns:primitives="using:Microsoft.UI.Xaml.Controls.Primitives" - xmlns:views="using:Files.Views" + xmlns:vm="using:Files.ViewModels" d:DesignHeight="300" d:DesignWidth="400" mc:Ignorable="d"> @@ -25,7 +25,7 @@ Opening="TabItemContextMenu_Opening"> @@ -33,7 +33,7 @@ @@ -42,7 +42,7 @@ @@ -51,7 +51,7 @@ diff --git a/Files/UserControls/MultitaskingControl/HorizontalMultitaskingControl.xaml.cs b/Files/UserControls/MultitaskingControl/HorizontalMultitaskingControl.xaml.cs index 61c47015915b..e3864a3412d0 100644 --- a/Files/UserControls/MultitaskingControl/HorizontalMultitaskingControl.xaml.cs +++ b/Files/UserControls/MultitaskingControl/HorizontalMultitaskingControl.xaml.cs @@ -131,7 +131,7 @@ private async void TabStrip_TabStripDrop(object sender, DragEventArgs e) var tabViewItemArgs = TabItemArguments.Deserialize(tabViewItemString); ApplicationData.Current.LocalSettings.Values[TabDropHandledIdentifier] = true; - await MainPage.AddNewTabByParam(tabViewItemArgs.InitialPageType, tabViewItemArgs.NavigationArg, index); + await MainPageViewModel.AddNewTabByParam(tabViewItemArgs.InitialPageType, tabViewItemArgs.NavigationArg, index); } private void TabStrip_TabDragCompleted(TabView sender, TabViewTabDragCompletedEventArgs args) @@ -139,7 +139,7 @@ private void TabStrip_TabDragCompleted(TabView sender, TabViewTabDragCompletedEv if (ApplicationData.Current.LocalSettings.Values.ContainsKey(TabDropHandledIdentifier) && (bool)ApplicationData.Current.LocalSettings.Values[TabDropHandledIdentifier]) { - RemoveTab(args.Item as TabItem); + CloseTab(args.Item as TabItem); } else { @@ -162,7 +162,7 @@ private async void TabStrip_TabDroppedOutside(TabView sender, TabViewTabDroppedO var indexOfTabViewItem = sender.TabItems.IndexOf(args.Tab); var tabViewItemArgs = (args.Item as TabItem).TabItemArguments; var selectedTabViewItemIndex = sender.SelectedIndex; - RemoveTab(args.Item as TabItem); + CloseTab(args.Item as TabItem); if (!await NavigationHelpers.OpenTabInNewWindowAsync(tabViewItemArgs.Serialize())) { sender.TabItems.Insert(indexOfTabViewItem, args.Tab); @@ -172,7 +172,7 @@ private async void TabStrip_TabDroppedOutside(TabView sender, TabViewTabDroppedO private void TabItemContextMenu_Opening(object sender, object e) { - if (MainPage.MultitaskingControl.Items.Count == 1) + if (MainPageViewModel.MultitaskingControl.Items.Count == 1) { MenuItemMoveTabToNewWindow.IsEnabled = false; } @@ -186,7 +186,7 @@ private void MenuItemCloseTabsToTheRight_DataContextChanged(FrameworkElement sen { TabItem tabItem = args.NewValue as TabItem; - if (MainPage.AppInstances.IndexOf(tabItem) == MainPage.AppInstances.Count - 1) + if (MainPageViewModel.AppInstances.IndexOf(tabItem) == MainPageViewModel.AppInstances.Count - 1) { MenuItemCloseTabsToTheRight.IsEnabled = false; } diff --git a/Files/UserControls/MultitaskingControl/IMultitaskingControl.cs b/Files/UserControls/MultitaskingControl/IMultitaskingControl.cs index c4ab0001d437..905a990c9dd2 100644 --- a/Files/UserControls/MultitaskingControl/IMultitaskingControl.cs +++ b/Files/UserControls/MultitaskingControl/IMultitaskingControl.cs @@ -16,7 +16,7 @@ public interface IMultitaskingControl public List GetAllTabInstances(); - public void RemoveTab(TabItem tabItem); + public void CloseTab(TabItem tabItem); } public class CurrentInstanceChangedEventArgs : EventArgs diff --git a/Files/UserControls/MultitaskingControl/TabItem/TabItem.cs b/Files/UserControls/MultitaskingControl/TabItem/TabItem.cs index 719c126ce801..fc6f60d8f9a2 100644 --- a/Files/UserControls/MultitaskingControl/TabItem/TabItem.cs +++ b/Files/UserControls/MultitaskingControl/TabItem/TabItem.cs @@ -1,4 +1,5 @@ -using Microsoft.Toolkit.Mvvm.ComponentModel; +using Files.ViewModels; +using Microsoft.Toolkit.Mvvm.ComponentModel; using Microsoft.UI.Xaml.Controls; using Newtonsoft.Json; using System; @@ -55,6 +56,7 @@ public TabItem() public void Unload() { + Control.ContentChanged -= MainPageViewModel.Control_ContentChanged; tabItemArguments = Control?.NavigationArguments; Dispose(); } diff --git a/Files/UserControls/MultitaskingControl/VerticalTabViewControl.xaml.cs b/Files/UserControls/MultitaskingControl/VerticalTabViewControl.xaml.cs index d4a9f25d58f7..b4600528c85e 100644 --- a/Files/UserControls/MultitaskingControl/VerticalTabViewControl.xaml.cs +++ b/Files/UserControls/MultitaskingControl/VerticalTabViewControl.xaml.cs @@ -1,5 +1,6 @@ using Files.Helpers; using Files.Interacts; +using Files.ViewModels; using Files.Views; using Microsoft.Toolkit.Uwp; using Microsoft.UI.Xaml.Controls; @@ -126,7 +127,7 @@ private async void TabStrip_TabStripDrop(object sender, DragEventArgs e) var tabViewItemArgs = TabItemArguments.Deserialize(tabViewItemString); ApplicationData.Current.LocalSettings.Values[TabDropHandledIdentifier] = true; - await MainPage.AddNewTabByParam(tabViewItemArgs.InitialPageType, tabViewItemArgs.NavigationArg, index); + await MainPageViewModel.AddNewTabByParam(tabViewItemArgs.InitialPageType, tabViewItemArgs.NavigationArg, index); } private void TabStrip_TabDragCompleted(TabView sender, TabViewTabDragCompletedEventArgs args) @@ -134,7 +135,7 @@ private void TabStrip_TabDragCompleted(TabView sender, TabViewTabDragCompletedEv if (ApplicationData.Current.LocalSettings.Values.ContainsKey(TabDropHandledIdentifier) && (bool)ApplicationData.Current.LocalSettings.Values[TabDropHandledIdentifier]) { - RemoveTab(args.Item as TabItem); + CloseTab(args.Item as TabItem); } else { @@ -157,7 +158,7 @@ private async void TabStrip_TabDroppedOutside(TabView sender, TabViewTabDroppedO var indexOfTabViewItem = sender.TabItems.IndexOf(args.Tab); var tabViewItemArgs = (args.Item as TabItem).TabItemArguments; var selectedTabViewItemIndex = sender.SelectedIndex; - RemoveTab(args.Item as TabItem); + CloseTab(args.Item as TabItem); if (!await NavigationHelpers.OpenTabInNewWindowAsync(tabViewItemArgs.Serialize())) { sender.TabItems.Insert(indexOfTabViewItem, args.Tab); diff --git a/Files/UserControls/NavigationToolbar.xaml.cs b/Files/UserControls/NavigationToolbar.xaml.cs index 7a1dc8013ebb..4f821244575a 100644 --- a/Files/UserControls/NavigationToolbar.xaml.cs +++ b/Files/UserControls/NavigationToolbar.xaml.cs @@ -1101,9 +1101,9 @@ private void PathboxItemFlyout_Opened(object sender, object e) private void VerticalTabStripInvokeButton_Loaded(object sender, RoutedEventArgs e) { - if (!(MainPage.MultitaskingControl is VerticalTabViewControl)) + if (!(MainPageViewModel.MultitaskingControl is VerticalTabViewControl)) { - MainPage.MultitaskingControl = VerticalTabs; + MainPageViewModel.MultitaskingControl = VerticalTabs; } } diff --git a/Files/UserControls/SidebarControl.xaml b/Files/UserControls/SidebarControl.xaml index 07fa54d0a3d3..f03ddf636916 100644 --- a/Files/UserControls/SidebarControl.xaml +++ b/Files/UserControls/SidebarControl.xaml @@ -133,7 +133,7 @@ IsTitleBarAutoPaddingEnabled="False" ItemInvoked="Sidebar_ItemInvoked" MenuItemTemplateSelector="{StaticResource NavItemSelector}" - MenuItemsSource="{x:Bind local3:MainPage.SideBarItems, Mode=OneWay}" + MenuItemsSource="{x:Bind local:SidebarControl.SideBarItems, Mode=OneWay}" OpenPaneLength="{x:Bind AppSettings.SidebarWidth.Value, Mode=OneWay}" PaneDisplayMode="{x:Bind IsCompact, Mode=OneWay, Converter={StaticResource DisplayModeConverter}}" SelectedItem="{x:Bind SelectedSidebarItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> diff --git a/Files/UserControls/SidebarControl.xaml.cs b/Files/UserControls/SidebarControl.xaml.cs index e03e943987d6..266da29ebbdd 100644 --- a/Files/UserControls/SidebarControl.xaml.cs +++ b/Files/UserControls/SidebarControl.xaml.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Runtime.CompilerServices; +using System.Threading; using System.Windows.Input; using Windows.ApplicationModel.DataTransfer; using Windows.Storage; @@ -21,6 +22,10 @@ namespace Files.UserControls { public sealed partial class SidebarControl : UserControl, INotifyPropertyChanged { + public static SemaphoreSlim SideBarItemsSemaphore = new SemaphoreSlim(1, 1); + + public static BulkConcurrentObservableCollection SideBarItems { get; private set; } = new BulkConcurrentObservableCollection(); + public SettingsViewModel AppSettings => App.AppSettings; public delegate void SidebarItemInvokedEventHandler(object sender, SidebarItemInvokedEventArgs e); @@ -566,7 +571,7 @@ private void SettingsButton_Tapped(object sender, TappedRoutedEventArgs e) private async void EjectDevice_Click(object sender, RoutedEventArgs e) { - await DeviceHelpers.EjectDeviceAsync(RightClickedItem.Path); + await DriveHelpers.EjectDeviceAsync(RightClickedItem.Path); } private void SidebarNavView_Loaded(object sender, RoutedEventArgs e) diff --git a/Files/UserControls/Widgets/DrivesWidget.xaml.cs b/Files/UserControls/Widgets/DrivesWidget.xaml.cs index f32a12d6b538..a98504bd58e9 100644 --- a/Files/UserControls/Widgets/DrivesWidget.xaml.cs +++ b/Files/UserControls/Widgets/DrivesWidget.xaml.cs @@ -59,7 +59,7 @@ private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") private async void EjectDevice_Click(object sender, RoutedEventArgs e) { var item = ((MenuFlyoutItem)sender).DataContext as DriveItem; - await DeviceHelpers.EjectDeviceAsync(item.Path); + await DriveHelpers.EjectDeviceAsync(item.Path); } private void OpenInNewTab_Click(object sender, RoutedEventArgs e) diff --git a/Files/ViewModels/Bundles/BundleItemViewModel.cs b/Files/ViewModels/Bundles/BundleItemViewModel.cs index df711c95bf53..d41b457df3c4 100644 --- a/Files/ViewModels/Bundles/BundleItemViewModel.cs +++ b/Files/ViewModels/Bundles/BundleItemViewModel.cs @@ -126,7 +126,7 @@ public BundleItemViewModel(IShellPage associatedInstance, string path, Filesyste private async void OpenInNewTab() { - await MainPage.AddNewTabByPathAsync(typeof(PaneHolderPage), Path); + await MainPageViewModel.AddNewTabByPathAsync(typeof(PaneHolderPage), Path); } private void OpenInNewPane() diff --git a/Files/ViewModels/InteractionViewModel.cs b/Files/ViewModels/InteractionViewModel.cs index a0d9609c9d9e..ae1e92fa9304 100644 --- a/Files/ViewModels/InteractionViewModel.cs +++ b/Files/ViewModels/InteractionViewModel.cs @@ -63,11 +63,11 @@ public int TabStripSelectedIndex { SetProperty(ref tabStripSelectedIndex, value); } - if (value < MainPage.MultitaskingControl.Items.Count) + if (value < MainPageViewModel.MultitaskingControl.Items.Count) { Frame rootFrame = Window.Current.Content as Frame; var mainView = rootFrame.Content as MainPage; - mainView.SelectedTabItem = MainPage.MultitaskingControl.Items[value]; + mainView.ViewModel.SelectedTabItem = MainPageViewModel.MultitaskingControl.Items[value]; } } } diff --git a/Files/ViewModels/MainPageViewModel.cs b/Files/ViewModels/MainPageViewModel.cs new file mode 100644 index 000000000000..6d25186ac63b --- /dev/null +++ b/Files/ViewModels/MainPageViewModel.cs @@ -0,0 +1,497 @@ +using Files.Helpers; +using Files.UserControls.MultitaskingControl; +using Files.Views; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.Input; +using Microsoft.Toolkit.Uwp; +using System; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Input; +using Windows.Storage; +using Windows.System; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; +using Files.Common; +using Windows.UI.Xaml; +using System.Collections.Generic; +using Files.Filesystem; +using System.Collections.ObjectModel; + +namespace Files.ViewModels +{ + public class MainPageViewModel : ObservableObject + { + private bool isRestoringClosedTab = false; // Avoid reopening two tabs + + public static IMultitaskingControl MultitaskingControl { get; set; } + + public static ObservableCollection AppInstances { get; private set; } = new ObservableCollection(); + + private TabItem selectedTabItem; + + public TabItem SelectedTabItem + { + get => selectedTabItem; + set => SetProperty(ref selectedTabItem, value); + } + + #region Commands + + public ICommand NavigateToNumberedTabKeyboardAcceleratorCommand { get; private set; } + + public ICommand OpenNewWindowAcceleratorCommand { get; private set; } + + public ICommand CloseSelectedTabKeyboardAcceleratorCommand { get; private set; } + + public ICommand AddNewInstanceAcceleratorCommand { get; private set; } + + #endregion + + public MainPageViewModel() + { + // Create commands + NavigateToNumberedTabKeyboardAcceleratorCommand = new RelayCommand(NavigateToNumberedTabKeyboardAccelerator); + OpenNewWindowAcceleratorCommand = new RelayCommand(OpenNewWindowAccelerator); + CloseSelectedTabKeyboardAcceleratorCommand = new RelayCommand(CloseSelectedTabKeyboardAccelerator); + AddNewInstanceAcceleratorCommand = new RelayCommand(AddNewInstanceAccelerator); + } + + #region Command Implementation + + private void NavigateToNumberedTabKeyboardAccelerator(KeyboardAcceleratorInvokedEventArgs e) + { + int indexToSelect = 0; + + switch (e.KeyboardAccelerator.Key) + { + case VirtualKey.Number1: + indexToSelect = 0; + break; + + case VirtualKey.Number2: + indexToSelect = 1; + break; + + case VirtualKey.Number3: + indexToSelect = 2; + break; + + case VirtualKey.Number4: + indexToSelect = 3; + break; + + case VirtualKey.Number5: + indexToSelect = 4; + break; + + case VirtualKey.Number6: + indexToSelect = 5; + break; + + case VirtualKey.Number7: + indexToSelect = 6; + break; + + case VirtualKey.Number8: + indexToSelect = 7; + break; + + case VirtualKey.Number9: + // Select the last tab + indexToSelect = AppInstances.Count - 1; + break; + } + + // Only select the tab if it is in the list + if (indexToSelect < AppInstances.Count) + { + App.InteractionViewModel.TabStripSelectedIndex = indexToSelect; + } + e.Handled = true; + } + + private async void OpenNewWindowAccelerator(KeyboardAcceleratorInvokedEventArgs e) + { + e.Handled = true; + Uri filesUWPUri = new Uri("files-uwp:"); + await Launcher.LaunchUriAsync(filesUWPUri); + } + + private void CloseSelectedTabKeyboardAccelerator(KeyboardAcceleratorInvokedEventArgs e) + { + if (App.InteractionViewModel.TabStripSelectedIndex >= AppInstances.Count) + { + TabItem tabItem = AppInstances[AppInstances.Count - 1]; + MultitaskingControl?.CloseTab(tabItem); + } + else + { + TabItem tabItem = AppInstances[App.InteractionViewModel.TabStripSelectedIndex]; + MultitaskingControl?.CloseTab(tabItem); + } + e.Handled = true; + } + + private async void AddNewInstanceAccelerator(KeyboardAcceleratorInvokedEventArgs e) + { + bool shift = e.KeyboardAccelerator.Modifiers.HasFlag(VirtualKeyModifiers.Shift); + + if (!shift) + { + await AddNewTabByPathAsync(typeof(PaneHolderPage), "NewTab".GetLocalized()); + } + else // ctrl + shift + t, restore recently closed tab + { + if (!isRestoringClosedTab && MultitaskingControl.RecentlyClosedTabs.Any()) + { + isRestoringClosedTab = true; + ITabItem lastTab = MultitaskingControl.RecentlyClosedTabs.Last(); + MultitaskingControl.RecentlyClosedTabs.Remove(lastTab); + await AddNewTabByParam(lastTab.TabItemArguments.InitialPageType, lastTab.TabItemArguments.NavigationArg); + isRestoringClosedTab = false; + } + } + e.Handled = true; + } + + #endregion + + #region Public Helpers + + public static async Task AddNewTabByPathAsync(Type type, string path, int atIndex = -1) + { + Microsoft.UI.Xaml.Controls.FontIconSource fontIconSource = new Microsoft.UI.Xaml.Controls.FontIconSource(); + fontIconSource.FontFamily = App.InteractionViewModel.FontName; + + if (string.IsNullOrEmpty(path)) + { + path = "NewTab".GetLocalized(); + } + + TabItem tabItem = new TabItem() + { + Header = null, + IconSource = fontIconSource, + Description = null + }; + tabItem.Control.NavigationArguments = new TabItemArguments() + { + InitialPageType = type, + NavigationArg = path + }; + tabItem.Control.ContentChanged += Control_ContentChanged; + await UpdateTabInfo(tabItem, path); + AppInstances.Insert(atIndex == -1 ? AppInstances.Count : atIndex, tabItem); + } + + public static async Task UpdateTabInfo(TabItem tabItem, object navigationArg) + { + tabItem.AllowStorageItemDrop = true; + if (navigationArg is PaneNavigationArguments paneArgs) + { + if (!string.IsNullOrEmpty(paneArgs.LeftPaneNavPathParam) && !string.IsNullOrEmpty(paneArgs.RightPaneNavPathParam)) + { + var leftTabInfo = await GetSelectedTabInfoAsync(paneArgs.LeftPaneNavPathParam); + var rightTabInfo = await GetSelectedTabInfoAsync(paneArgs.RightPaneNavPathParam); + tabItem.Header = $"{leftTabInfo.tabLocationHeader} | {rightTabInfo.tabLocationHeader}"; + tabItem.IconSource = leftTabInfo.tabIcon; + } + else + { + (tabItem.Header, tabItem.IconSource) = await GetSelectedTabInfoAsync(paneArgs.LeftPaneNavPathParam); + } + } + else if (navigationArg is string pathArgs) + { + (tabItem.Header, tabItem.IconSource) = await GetSelectedTabInfoAsync(pathArgs); + } + } + + public static async Task<(string tabLocationHeader, Microsoft.UI.Xaml.Controls.IconSource tabIcon)> GetSelectedTabInfoAsync(string currentPath) + { + string tabLocationHeader; + Microsoft.UI.Xaml.Controls.FontIconSource fontIconSource = new Microsoft.UI.Xaml.Controls.FontIconSource(); + fontIconSource.FontFamily = App.InteractionViewModel.FontName; + + if (currentPath == null || currentPath == "SidebarSettings/Text".GetLocalized()) + { + tabLocationHeader = "SidebarSettings/Text".GetLocalized(); + fontIconSource.Glyph = "\xE713"; + } + else if (currentPath == null || currentPath == "NewTab".GetLocalized() || currentPath == "Home") + { + tabLocationHeader = "NewTab".GetLocalized(); + fontIconSource.Glyph = "\xE8A1"; + } + else if (currentPath.Equals(App.AppSettings.DesktopPath, StringComparison.OrdinalIgnoreCase)) + { + tabLocationHeader = "SidebarDesktop".GetLocalized(); + fontIconSource.Glyph = "\xE8FC"; + } + else if (currentPath.Equals(App.AppSettings.DownloadsPath, StringComparison.OrdinalIgnoreCase)) + { + tabLocationHeader = "SidebarDownloads".GetLocalized(); + fontIconSource.Glyph = "\xE896"; + } + else if (currentPath.Equals(App.AppSettings.DocumentsPath, StringComparison.OrdinalIgnoreCase)) + { + tabLocationHeader = "SidebarDocuments".GetLocalized(); + fontIconSource.Glyph = "\xE8A5"; + } + else if (currentPath.Equals(App.AppSettings.PicturesPath, StringComparison.OrdinalIgnoreCase)) + { + tabLocationHeader = "SidebarPictures".GetLocalized(); + fontIconSource.Glyph = "\xEB9F"; + } + else if (currentPath.Equals(App.AppSettings.MusicPath, StringComparison.OrdinalIgnoreCase)) + { + tabLocationHeader = "SidebarMusic".GetLocalized(); + fontIconSource.Glyph = "\xEC4F"; + } + else if (currentPath.Equals(App.AppSettings.VideosPath, StringComparison.OrdinalIgnoreCase)) + { + tabLocationHeader = "SidebarVideos".GetLocalized(); + fontIconSource.Glyph = "\xE8B2"; + } + else if (currentPath.Equals(App.AppSettings.RecycleBinPath, StringComparison.OrdinalIgnoreCase)) + { + var localSettings = ApplicationData.Current.LocalSettings; + tabLocationHeader = localSettings.Values.Get("RecycleBin_Title", "Recycle Bin"); + fontIconSource.FontFamily = Application.Current.Resources["RecycleBinIcons"] as FontFamily; + fontIconSource.Glyph = "\xEF87"; + } + else if (currentPath.Equals(App.AppSettings.NetworkFolderPath, StringComparison.OrdinalIgnoreCase)) + { + tabLocationHeader = "SidebarNetworkDrives".GetLocalized(); + fontIconSource.Glyph = "\uE8CE"; + } + else + { + var matchingCloudDrive = App.CloudDrivesManager.Drives.FirstOrDefault(x => PathNormalization.NormalizePath(currentPath).Equals(PathNormalization.NormalizePath(x.Path), StringComparison.OrdinalIgnoreCase)); + if (matchingCloudDrive != null) + { + fontIconSource.Glyph = "\xE753"; + tabLocationHeader = matchingCloudDrive.Text; + } + else if (PathNormalization.NormalizePath(PathNormalization.GetPathRoot(currentPath)) == PathNormalization.NormalizePath(currentPath)) // If path is a drive's root + { + var matchingNetDrive = App.NetworkDrivesManager.Drives.FirstOrDefault(x => PathNormalization.NormalizePath(currentPath).Contains(PathNormalization.NormalizePath(x.Path), StringComparison.OrdinalIgnoreCase)); + if (matchingNetDrive != null) + { + fontIconSource.Glyph = "\uE8CE"; + tabLocationHeader = matchingNetDrive.Text; + } + else + { + try + { + List drives = System.IO.DriveInfo.GetDrives().ToList(); + System.IO.DriveInfo matchingDrive = drives.FirstOrDefault(x => PathNormalization.NormalizePath(currentPath).Contains(PathNormalization.NormalizePath(x.Name))); + + if (matchingDrive != null) + { + // Go through types and set the icon according to type + string type = DriveHelpers.GetDriveTypeIcon(matchingDrive); + if (!string.IsNullOrWhiteSpace(type)) + { + fontIconSource.Glyph = type; + } + else + { + fontIconSource.Glyph = "\xEDA2"; // Drive icon + } + } + else + { + fontIconSource.Glyph = "\xE74E"; // Floppy icon + } + } + catch (Exception) + { + fontIconSource.Glyph = "\xEDA2"; // Fallback + } + + tabLocationHeader = PathNormalization.NormalizePath(currentPath); + } + } + else + { + fontIconSource.Glyph = "\xE8B7"; // Folder icon + tabLocationHeader = currentPath.TrimEnd(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar).Split('\\', StringSplitOptions.RemoveEmptyEntries).Last(); + + FilesystemResult rootItem = await FilesystemTasks.Wrap(() => DrivesManager.GetRootFromPathAsync(currentPath)); + if (rootItem) + { + StorageFolder currentFolder = await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFolderFromPathAsync(currentPath, rootItem)); + if (currentFolder != null && !string.IsNullOrEmpty(currentFolder.DisplayName)) + { + tabLocationHeader = currentFolder.DisplayName; + } + } + } + } + + return (tabLocationHeader, fontIconSource); + } + + public async void OnNavigatedTo(NavigationEventArgs e) + { + if (e.NavigationMode != NavigationMode.Back) + { + //Initialize the static theme helper to capture a reference to this window + //to handle theme changes without restarting the app + ThemeHelper.Initialize(); + + if (e.Parameter == null || (e.Parameter is string eventStr && string.IsNullOrEmpty(eventStr))) + { + try + { + if (App.AppSettings.ResumeAfterRestart) + { + App.AppSettings.ResumeAfterRestart = false; + + foreach (string tabArgsString in App.AppSettings.LastSessionPages) + { + var tabArgs = TabItemArguments.Deserialize(tabArgsString); + await AddNewTabByParam(tabArgs.InitialPageType, tabArgs.NavigationArg); + } + + if (!App.AppSettings.ContinueLastSessionOnStartUp) + { + App.AppSettings.LastSessionPages = null; + } + } + else if (App.AppSettings.OpenASpecificPageOnStartup) + { + if (App.AppSettings.PagesOnStartupList != null) + { + foreach (string path in App.AppSettings.PagesOnStartupList) + { + await AddNewTabByPathAsync(typeof(PaneHolderPage), path); + } + } + else + { + await AddNewTabAsync(); + } + } + else if (App.AppSettings.ContinueLastSessionOnStartUp) + { + if (App.AppSettings.LastSessionPages != null) + { + foreach (string tabArgsString in App.AppSettings.LastSessionPages) + { + var tabArgs = TabItemArguments.Deserialize(tabArgsString); + await AddNewTabByParam(tabArgs.InitialPageType, tabArgs.NavigationArg); + } + var defaultArg = new TabItemArguments() { InitialPageType = typeof(PaneHolderPage), NavigationArg = "NewTab".GetLocalized() }; + App.AppSettings.LastSessionPages = new string[] { defaultArg.Serialize() }; + } + else + { + await AddNewTabAsync(); + } + } + else + { + await AddNewTabAsync(); + } + } + catch (Exception) + { + await AddNewTabAsync(); + } + } + else + { + if (e.Parameter is string navArgs) + { + await AddNewTabByPathAsync(typeof(PaneHolderPage), navArgs); + } + else if (e.Parameter is TabItemArguments tabArgs) + { + await AddNewTabByParam(tabArgs.InitialPageType, tabArgs.NavigationArg); + } + } + + // Check for required updates + AppUpdater updater = new AppUpdater(); + updater.CheckForUpdatesAsync(); + + // Initial setting of SelectedTabItem + SelectedTabItem = AppInstances[App.InteractionViewModel.TabStripSelectedIndex]; + } + } + + public static async Task AddNewTabAsync() + { + await AddNewTabByPathAsync(typeof(PaneHolderPage), "NewTab".GetLocalized()); + } + + public static async void AddNewTabAtIndex(object sender, RoutedEventArgs e) + { + await AddNewTabByPathAsync(typeof(PaneHolderPage), "NewTab".GetLocalized()); + } + + public static async void DuplicateTabAtIndex(object sender, RoutedEventArgs e) + { + var tabItem = ((FrameworkElement)sender).DataContext as TabItem; + var index = AppInstances.IndexOf(tabItem); + + if (AppInstances[index].TabItemArguments != null) + { + var tabArgs = AppInstances[index].TabItemArguments; + await AddNewTabByParam(tabArgs.InitialPageType, tabArgs.NavigationArg, index + 1); + } + else + { + await AddNewTabByPathAsync(typeof(PaneHolderPage), "NewTab".GetLocalized()); + } + } + + public static void CloseTabsToTheRight(object sender, RoutedEventArgs e) + { + MultitaskingTabsHelpers.CloseTabsToTheRight(((FrameworkElement)sender).DataContext as TabItem); + } + + public static async void MoveTabToNewWindow(object sender, RoutedEventArgs e) + { + await MultitaskingTabsHelpers.MoveTabToNewWindow(((FrameworkElement)sender).DataContext as TabItem); + } + + public static async Task AddNewTabByParam(Type type, object tabViewItemArgs, int atIndex = -1) + { + Microsoft.UI.Xaml.Controls.FontIconSource fontIconSource = new Microsoft.UI.Xaml.Controls.FontIconSource(); + fontIconSource.FontFamily = App.InteractionViewModel.FontName; + + TabItem tabItem = new TabItem() + { + Header = null, + IconSource = fontIconSource, + Description = null + }; + tabItem.Control.NavigationArguments = new TabItemArguments() + { + InitialPageType = type, + NavigationArg = tabViewItemArgs + }; + tabItem.Control.ContentChanged += Control_ContentChanged; + await UpdateTabInfo(tabItem, tabViewItemArgs); + AppInstances.Insert(atIndex == -1 ? AppInstances.Count : atIndex, tabItem); + } + + public static async void Control_ContentChanged(object sender, TabItemArguments e) + { + TabItem matchingTabItem = MainPageViewModel.AppInstances.SingleOrDefault(x => x.Control == sender); + if (matchingTabItem == null) + { + return; + } + await UpdateTabInfo(matchingTabItem, e.NavigationArg); + } + + #endregion + } +} diff --git a/Files/Views/MainPage.xaml b/Files/Views/MainPage.xaml index 5b494f5e51d5..312846f437ae 100644 --- a/Files/Views/MainPage.xaml +++ b/Files/Views/MainPage.xaml @@ -2,77 +2,145 @@ x:Class="Files.Views.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:converters="using:Files.Converters" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:local="using:Files.Views" - xmlns:local1="using:Files" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:muxc="using:Microsoft.UI.Xaml.Controls" - xmlns:usercontrols="using:Files.UserControls.MultitaskingControl" + xmlns:i="using:Microsoft.Xaml.Interactivity" + xmlns:icore="using:Microsoft.Xaml.Interactions.Core" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" KeyboardAcceleratorPlacementMode="Hidden" NavigationCacheMode="Required" mc:Ignorable="d"> + + Modifiers="Control"> + + + + + + + Modifiers="Control"> + + + + + + + Modifiers="Control"> + + + + + + + Modifiers="Control"> + + + + + + + Modifiers="Control"> + + + + + + + Modifiers="Control"> + + + + + + + Modifiers="Control"> + + + + + + + Modifiers="Control"> + + + + + + + Modifiers="Control"> + + + + + + + Modifiers="Control"> + + + + + + + Modifiers="Control"> + + + + + + + Modifiers="Control"> + + + + + + + Modifiers="Control"> + + + + + + + Modifiers="Control,Shift"> + + + + + + - + \ No newline at end of file diff --git a/Files/Views/MainPage.xaml.cs b/Files/Views/MainPage.xaml.cs index c2befbf48cdb..5d2e1513dc68 100644 --- a/Files/Views/MainPage.xaml.cs +++ b/Files/Views/MainPage.xaml.cs @@ -1,64 +1,30 @@ -using Files.Common; -using Files.Filesystem; -using Files.Helpers; -using Files.UserControls.MultitaskingControl; -using Files.ViewModels; -using Microsoft.Toolkit.Uwp; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.IO; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Threading.Tasks; +using Files.ViewModels; using Windows.ApplicationModel.Core; using Windows.ApplicationModel.Resources.Core; -using Windows.Storage; -using Windows.System; using Windows.UI.ViewManagement; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Input; -using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; -using static Files.Helpers.PathNormalization; namespace Files.Views { /// /// The root page of Files /// - public sealed partial class MainPage : Page, INotifyPropertyChanged + public sealed partial class MainPage : Page { - public SettingsViewModel AppSettings => App.AppSettings; - public static IMultitaskingControl MultitaskingControl { get; set; } - - private TabItem selectedTabItem; - - public TabItem SelectedTabItem + public MainPageViewModel ViewModel { - get - { - return selectedTabItem; - } - set - { - selectedTabItem = value; - NotifyPropertyChanged(nameof(SelectedTabItem)); - } + get => (MainPageViewModel)DataContext; + set => DataContext = value; } - - public static ObservableCollection AppInstances = new ObservableCollection(); - public static BulkConcurrentObservableCollection SideBarItems = new BulkConcurrentObservableCollection(); - public static SemaphoreSlim SideBarItemsSemaphore = new SemaphoreSlim(1, 1); - public MainPage() { this.InitializeComponent(); + this.ViewModel = new MainPageViewModel(); + ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.Auto; var CoreTitleBar = CoreApplication.GetCurrentView().TitleBar; CoreTitleBar.ExtendViewIntoTitleBar = true; @@ -72,516 +38,9 @@ public MainPage() AllowDrop = true; } - protected override async void OnNavigatedTo(NavigationEventArgs eventArgs) - { - if (eventArgs.NavigationMode != NavigationMode.Back) - { - //Initialize the static theme helper to capture a reference to this window - //to handle theme changes without restarting the app - ThemeHelper.Initialize(); - - if (eventArgs.Parameter == null || (eventArgs.Parameter is string eventStr && string.IsNullOrEmpty(eventStr))) - { - try - { - if (App.AppSettings.ResumeAfterRestart) - { - App.AppSettings.ResumeAfterRestart = false; - - foreach (string tabArgsString in App.AppSettings.LastSessionPages) - { - var tabArgs = TabItemArguments.Deserialize(tabArgsString); - await AddNewTabByParam(tabArgs.InitialPageType, tabArgs.NavigationArg); - } - - if (!App.AppSettings.ContinueLastSessionOnStartUp) - { - App.AppSettings.LastSessionPages = null; - } - } - else if (App.AppSettings.OpenASpecificPageOnStartup) - { - if (App.AppSettings.PagesOnStartupList != null) - { - foreach (string path in App.AppSettings.PagesOnStartupList) - { - await AddNewTabByPathAsync(typeof(PaneHolderPage), path); - } - } - else - { - await AddNewTabAsync(); - } - } - else if (App.AppSettings.ContinueLastSessionOnStartUp) - { - if (App.AppSettings.LastSessionPages != null) - { - foreach (string tabArgsString in App.AppSettings.LastSessionPages) - { - var tabArgs = TabItemArguments.Deserialize(tabArgsString); - await AddNewTabByParam(tabArgs.InitialPageType, tabArgs.NavigationArg); - } - var defaultArg = new TabItemArguments() { InitialPageType = typeof(PaneHolderPage), NavigationArg = "NewTab".GetLocalized() }; - App.AppSettings.LastSessionPages = new string[] { defaultArg.Serialize() }; - } - else - { - await AddNewTabAsync(); - } - } - else - { - await AddNewTabAsync(); - } - } - catch (Exception) - { - await AddNewTabAsync(); - } - } - else - { - if (eventArgs.Parameter is string navArgs) - { - await AddNewTabByPathAsync(typeof(PaneHolderPage), navArgs); - } - else if (eventArgs.Parameter is TabItemArguments tabArgs) - { - await AddNewTabByParam(tabArgs.InitialPageType, tabArgs.NavigationArg); - } - } - - // Check for required updates - AppUpdater updater = new AppUpdater(); - updater.CheckForUpdatesAsync(); - - // Initial setting of SelectedTabItem - Frame rootFrame = Window.Current.Content as Frame; - var mainView = rootFrame.Content as MainPage; - mainView.SelectedTabItem = AppInstances[App.InteractionViewModel.TabStripSelectedIndex]; - } - } - - public static async Task AddNewTabAsync() - { - await AddNewTabByPathAsync(typeof(PaneHolderPage), "NewTab".GetLocalized()); - } - - public static async void AddNewTabAtIndex(object sender, RoutedEventArgs e) - { - await AddNewTabByPathAsync(typeof(PaneHolderPage), "NewTab".GetLocalized()); - } - - public static async void DuplicateTabAtIndex(object sender, RoutedEventArgs e) - { - var tabItem = ((FrameworkElement)sender).DataContext as TabItem; - var index = AppInstances.IndexOf(tabItem); - - if (AppInstances[index].TabItemArguments != null) - { - var tabArgs = AppInstances[index].TabItemArguments; - await AddNewTabByParam(tabArgs.InitialPageType, tabArgs.NavigationArg, index + 1); - } - else - { - await AddNewTabByPathAsync(typeof(PaneHolderPage), "NewTab".GetLocalized()); - } - } - - public static void CloseTabsToTheRight(object sender, RoutedEventArgs e) - { - TabItem tabItem = ((FrameworkElement)sender).DataContext as TabItem; - int index = AppInstances.IndexOf(tabItem); - List tabsToClose = new List(); - - for (int i = index + 1; i < AppInstances.Count; i++) - { - tabsToClose.Add(AppInstances[i]); - } - - foreach (var item in tabsToClose) - { - MultitaskingControl?.RemoveTab(item); - } - } - - public static async void MoveTabToNewWindow(object sender, RoutedEventArgs e) - { - var tabItem = ((FrameworkElement)sender).DataContext as TabItem; - var index = AppInstances.IndexOf(tabItem); - var tabItemArguments = AppInstances[index].TabItemArguments; - - MultitaskingControl.Items.RemoveAt(index); - - if (tabItemArguments != null) - { - await NavigationHelpers.OpenTabInNewWindowAsync(tabItemArguments.Serialize()); - } - else - { - await NavigationHelpers.OpenPathInNewWindowAsync("NewTab".GetLocalized()); - } - } - - public static async Task AddNewTabByParam(Type type, object tabViewItemArgs, int atIndex = -1) - { - Microsoft.UI.Xaml.Controls.FontIconSource fontIconSource = new Microsoft.UI.Xaml.Controls.FontIconSource(); - fontIconSource.FontFamily = App.InteractionViewModel.FontName; - - TabItem tabItem = new TabItem() - { - Header = null, - IconSource = fontIconSource, - Description = null - }; - tabItem.Control.NavigationArguments = new TabItemArguments() - { - InitialPageType = type, - NavigationArg = tabViewItemArgs - }; - tabItem.Control.ContentChanged += Control_ContentChanged; - await UpdateTabInfo(tabItem, tabViewItemArgs); - AppInstances.Insert(atIndex == -1 ? AppInstances.Count : atIndex, tabItem); - } - - public static async Task AddNewTabByPathAsync(Type type, string path, int atIndex = -1) - { - Microsoft.UI.Xaml.Controls.FontIconSource fontIconSource = new Microsoft.UI.Xaml.Controls.FontIconSource(); - fontIconSource.FontFamily = App.InteractionViewModel.FontName; - - if (string.IsNullOrEmpty(path)) - { - path = "NewTab".GetLocalized(); - } - - TabItem tabItem = new TabItem() - { - Header = null, - IconSource = fontIconSource, - Description = null - }; - tabItem.Control.NavigationArguments = new TabItemArguments() - { - InitialPageType = type, - NavigationArg = path - }; - tabItem.Control.ContentChanged += Control_ContentChanged; - await UpdateTabInfo(tabItem, path); - AppInstances.Insert(atIndex == -1 ? AppInstances.Count : atIndex, tabItem); - } - - private static async Task<(string tabLocationHeader, Microsoft.UI.Xaml.Controls.IconSource tabIcon)> GetSelectedTabInfoAsync(string currentPath) - { - string tabLocationHeader; - Microsoft.UI.Xaml.Controls.FontIconSource fontIconSource = new Microsoft.UI.Xaml.Controls.FontIconSource(); - fontIconSource.FontFamily = App.InteractionViewModel.FontName; - - if (currentPath == null || currentPath == "SidebarSettings/Text".GetLocalized()) - { - tabLocationHeader = "SidebarSettings/Text".GetLocalized(); - fontIconSource.Glyph = "\xE713"; - } - else if (currentPath == null || currentPath == "NewTab".GetLocalized() || currentPath == "Home") - { - tabLocationHeader = "NewTab".GetLocalized(); - fontIconSource.Glyph = "\xE8A1"; - } - else if (currentPath.Equals(App.AppSettings.DesktopPath, StringComparison.OrdinalIgnoreCase)) - { - tabLocationHeader = "SidebarDesktop".GetLocalized(); - fontIconSource.Glyph = "\xE8FC"; - } - else if (currentPath.Equals(App.AppSettings.DownloadsPath, StringComparison.OrdinalIgnoreCase)) - { - tabLocationHeader = "SidebarDownloads".GetLocalized(); - fontIconSource.Glyph = "\xE896"; - } - else if (currentPath.Equals(App.AppSettings.DocumentsPath, StringComparison.OrdinalIgnoreCase)) - { - tabLocationHeader = "SidebarDocuments".GetLocalized(); - fontIconSource.Glyph = "\xE8A5"; - } - else if (currentPath.Equals(App.AppSettings.PicturesPath, StringComparison.OrdinalIgnoreCase)) - { - tabLocationHeader = "SidebarPictures".GetLocalized(); - fontIconSource.Glyph = "\xEB9F"; - } - else if (currentPath.Equals(App.AppSettings.MusicPath, StringComparison.OrdinalIgnoreCase)) - { - tabLocationHeader = "SidebarMusic".GetLocalized(); - fontIconSource.Glyph = "\xEC4F"; - } - else if (currentPath.Equals(App.AppSettings.VideosPath, StringComparison.OrdinalIgnoreCase)) - { - tabLocationHeader = "SidebarVideos".GetLocalized(); - fontIconSource.Glyph = "\xE8B2"; - } - else if (currentPath.Equals(App.AppSettings.RecycleBinPath, StringComparison.OrdinalIgnoreCase)) - { - var localSettings = ApplicationData.Current.LocalSettings; - tabLocationHeader = localSettings.Values.Get("RecycleBin_Title", "Recycle Bin"); - fontIconSource.FontFamily = Application.Current.Resources["RecycleBinIcons"] as FontFamily; - fontIconSource.Glyph = "\xEF87"; - } - else if (currentPath.Equals(App.AppSettings.NetworkFolderPath, StringComparison.OrdinalIgnoreCase)) - { - tabLocationHeader = "SidebarNetworkDrives".GetLocalized(); - fontIconSource.Glyph = "\uE8CE"; - } - else - { - var matchingCloudDrive = App.CloudDrivesManager.Drives.FirstOrDefault(x => NormalizePath(currentPath).Equals(NormalizePath(x.Path), StringComparison.OrdinalIgnoreCase)); - if (matchingCloudDrive != null) - { - fontIconSource.Glyph = "\xE753"; - tabLocationHeader = matchingCloudDrive.Text; - } - else if (NormalizePath(GetPathRoot(currentPath)) == NormalizePath(currentPath)) // If path is a drive's root - { - var matchingNetDrive = App.NetworkDrivesManager.Drives.FirstOrDefault(x => NormalizePath(currentPath).Contains(NormalizePath(x.Path), StringComparison.OrdinalIgnoreCase)); - if (matchingNetDrive != null) - { - fontIconSource.Glyph = "\uE8CE"; - tabLocationHeader = matchingNetDrive.Text; - } - else - { - try - { - List drives = DriveInfo.GetDrives().ToList(); - DriveInfo matchingDrive = drives.FirstOrDefault(x => NormalizePath(currentPath).Contains(NormalizePath(x.Name))); - - if (matchingDrive != null) - { - // Go through types and set the icon according to type - string type = GetDriveTypeIcon(matchingDrive); - if (!string.IsNullOrWhiteSpace(type)) - { - fontIconSource.Glyph = type; - } - else - { - fontIconSource.Glyph = "\xEDA2"; //Drive icon - } - } - else - { - fontIconSource.Glyph = "\xE74E"; //Floppy icon - } - } - catch (Exception) - { - fontIconSource.Glyph = "\xEDA2"; //Fallback - } - - tabLocationHeader = NormalizePath(currentPath); - } - } - else - { - fontIconSource.Glyph = "\xE8B7"; //Folder icon - tabLocationHeader = currentPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar).Split('\\', StringSplitOptions.RemoveEmptyEntries).Last(); - - FilesystemResult rootItem = await FilesystemTasks.Wrap(() => DrivesManager.GetRootFromPathAsync(currentPath)); - if (rootItem) - { - StorageFolder currentFolder = await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFolderFromPathAsync(currentPath, rootItem)); - if (currentFolder != null && !string.IsNullOrEmpty(currentFolder.DisplayName)) - { - tabLocationHeader = currentFolder.DisplayName; - } - } - } - } - - return (tabLocationHeader, fontIconSource); - } - - private static async void Control_ContentChanged(object sender, TabItemArguments e) - { - var matchingTabItem = MainPage.AppInstances.SingleOrDefault(x => x.Control == sender); - if (matchingTabItem == null) - { - return; - } - await UpdateTabInfo(matchingTabItem, e.NavigationArg); - } - - private static async Task UpdateTabInfo(TabItem tabItem, object navigationArg) - { - tabItem.AllowStorageItemDrop = true; - if (navigationArg is PaneNavigationArguments paneArgs) - { - if (!string.IsNullOrEmpty(paneArgs.LeftPaneNavPathParam) && !string.IsNullOrEmpty(paneArgs.RightPaneNavPathParam)) - { - var leftTabInfo = await GetSelectedTabInfoAsync(paneArgs.LeftPaneNavPathParam); - var rightTabInfo = await GetSelectedTabInfoAsync(paneArgs.RightPaneNavPathParam); - tabItem.Header = $"{leftTabInfo.tabLocationHeader} | {rightTabInfo.tabLocationHeader}"; - tabItem.IconSource = leftTabInfo.tabIcon; - } - else - { - (tabItem.Header, tabItem.IconSource) = await GetSelectedTabInfoAsync(paneArgs.LeftPaneNavPathParam); - } - } - else if (navigationArg is string pathArgs) - { - (tabItem.Header, tabItem.IconSource) = await GetSelectedTabInfoAsync(pathArgs); - } - } - - public event PropertyChangedEventHandler PropertyChanged; - - private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - private void NavigateToNumberedTabKeyboardAccelerator_Invoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args) + protected override void OnNavigatedTo(NavigationEventArgs e) { - int indexToSelect = 0; - - switch (sender.Key) - { - case VirtualKey.Number1: - indexToSelect = 0; - break; - - case VirtualKey.Number2: - indexToSelect = 1; - break; - - case VirtualKey.Number3: - indexToSelect = 2; - break; - - case VirtualKey.Number4: - indexToSelect = 3; - break; - - case VirtualKey.Number5: - indexToSelect = 4; - break; - - case VirtualKey.Number6: - indexToSelect = 5; - break; - - case VirtualKey.Number7: - indexToSelect = 6; - break; - - case VirtualKey.Number8: - indexToSelect = 7; - break; - - case VirtualKey.Number9: - // Select the last tab - indexToSelect = AppInstances.Count - 1; - break; - } - - // Only select the tab if it is in the list - if (indexToSelect < AppInstances.Count) - { - App.InteractionViewModel.TabStripSelectedIndex = indexToSelect; - } - args.Handled = true; - } - - private void CloseSelectedTabKeyboardAccelerator_Invoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args) - { - if (App.InteractionViewModel.TabStripSelectedIndex >= AppInstances.Count) - { - var tabItem = AppInstances[AppInstances.Count - 1]; - MultitaskingControl?.RemoveTab(tabItem); - } - else - { - var tabItem = AppInstances[App.InteractionViewModel.TabStripSelectedIndex]; - MultitaskingControl?.RemoveTab(tabItem); - } - args.Handled = true; - } - - private bool isRestoringClosedTab = false; // Avoid reopening two tabs - - private async void AddNewInstanceAccelerator_Invoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args) - { - var shift = args.KeyboardAccelerator.Modifiers.HasFlag(VirtualKeyModifiers.Shift); - if (!shift) - { - await AddNewTabByPathAsync(typeof(PaneHolderPage), "NewTab".GetLocalized()); - } - else // ctrl + shift + t, restore recently closed tab - { - if (!isRestoringClosedTab && MultitaskingControl.RecentlyClosedTabs.Any()) - { - isRestoringClosedTab = true; - var lastTab = MultitaskingControl.RecentlyClosedTabs.Last(); - MultitaskingControl.RecentlyClosedTabs.Remove(lastTab); - await AddNewTabByParam(lastTab.TabItemArguments.InitialPageType, lastTab.TabItemArguments.NavigationArg); - isRestoringClosedTab = false; - } - } - args.Handled = true; - } - - private async void OpenNewWindowAccelerator_Invoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args) - { - args.Handled = true; - var filesUWPUri = new Uri("files-uwp:"); - await Launcher.LaunchUriAsync(filesUWPUri); - } - - private static string GetDriveTypeIcon(DriveInfo drive) - { - string type; - - switch (drive.DriveType) - { - case System.IO.DriveType.CDRom: - type = "\xE958"; - break; - - case System.IO.DriveType.Fixed: - type = "\xEDA2"; - break; - - case System.IO.DriveType.Network: - type = "\xE8CE"; - break; - - case System.IO.DriveType.NoRootDirectory: - type = "\xED25"; - break; - - case System.IO.DriveType.Ram: - type = "\xE950"; - break; - - case System.IO.DriveType.Removable: - type = "\xE88E"; - break; - - case System.IO.DriveType.Unknown: - if (NormalizePath(drive.Name) != NormalizePath("A:") && NormalizePath(drive.Name) != NormalizePath("B:")) - { - type = "\xEDA2"; - } - else - { - type = "\xE74E"; //Floppy icon - } - break; - - default: - type = "\xEDA2"; //Drive icon - break; - } - - return type; + ViewModel.OnNavigatedTo(e); } } } diff --git a/Files/Views/ModernShellPage.xaml.cs b/Files/Views/ModernShellPage.xaml.cs index 74cf65acd60d..ce513ddbeb5d 100644 --- a/Files/Views/ModernShellPage.xaml.cs +++ b/Files/Views/ModernShellPage.xaml.cs @@ -225,7 +225,7 @@ private void InitializeCommands() OpenNewWindowCommand = new RelayCommand(NavigationHelpers.LaunchNewWindow); OpenNewPaneCommand = new RelayCommand(() => PaneHolder?.OpenPathInNewPane("NewTab".GetLocalized())); OpenDirectoryInDefaultTerminalCommand = new RelayCommand(() => NavigationHelpers.OpenDirectoryInTerminal(this.FilesystemViewModel.WorkingDirectory, this)); - AddNewTabToMultitaskingControlCommand = new RelayCommand(async () => await MainPage.AddNewTabByPathAsync(typeof(PaneHolderPage), "NewTab".GetLocalized())); + AddNewTabToMultitaskingControlCommand = new RelayCommand(async () => await MainPageViewModel.AddNewTabByPathAsync(typeof(PaneHolderPage), "NewTab".GetLocalized())); CreateNewFileCommand = new RelayCommand(() => UIFilesystemHelpers.CreateFileFromDialogResultType(AddItemType.File, null, this)); CreateNewFolderCommand = new RelayCommand(() => UIFilesystemHelpers.CreateFileFromDialogResultType(AddItemType.Folder, null, this)); diff --git a/Files/Views/PaneHolderPage.xaml.cs b/Files/Views/PaneHolderPage.xaml.cs index a5ad93b7544d..7f29e599fddd 100644 --- a/Files/Views/PaneHolderPage.xaml.cs +++ b/Files/Views/PaneHolderPage.xaml.cs @@ -378,9 +378,9 @@ public void UpdateSidebarSelectedItem() } INavigationControlItem item = null; - List sidebarItems = MainPage.SideBarItems + List sidebarItems = UserControls.SidebarControl.SideBarItems .Where(x => !string.IsNullOrWhiteSpace(x.Path)) - .Concat(MainPage.SideBarItems.Where(x => (x as LocationItem)?.ChildItems != null).SelectMany(x => (x as LocationItem).ChildItems).Where(x => !string.IsNullOrWhiteSpace(x.Path))) + .Concat(UserControls.SidebarControl.SideBarItems.Where(x => (x as LocationItem)?.ChildItems != null).SelectMany(x => (x as LocationItem).ChildItems).Where(x => !string.IsNullOrWhiteSpace(x.Path))) .ToList(); item = sidebarItems.FirstOrDefault(x => x.Path.Equals(value, StringComparison.OrdinalIgnoreCase)); @@ -545,7 +545,7 @@ private void SidebarControl_SidebarItemInvoked(object sender, SidebarItemInvoked var invokedItemContainer = e.InvokedItemContainer; // All items must have DataContext except Settings item - if (invokedItemContainer.DataContext is null) + if (invokedItemContainer.DataContext is MainPageViewModel) { Frame rootFrame = Window.Current.Content as Frame; rootFrame.Navigate(typeof(Settings)); @@ -595,9 +595,9 @@ private void SidebarControl_SidebarItemInvoked(object sender, SidebarItemInvoked private void HorizontalMultitaskingControl_Loaded(object sender, RoutedEventArgs e) { - if (!(MainPage.MultitaskingControl is HorizontalMultitaskingControl)) + if (!(MainPageViewModel.MultitaskingControl is HorizontalMultitaskingControl)) { - MainPage.MultitaskingControl = horizontalMultitaskingControl; + MainPageViewModel.MultitaskingControl = horizontalMultitaskingControl; } } }