diff --git a/src/Files.App/Helpers/Layout/LayoutPreferencesManager.cs b/src/Files.App/Helpers/Layout/LayoutPreferencesManager.cs index 7f17895d5c85..5f350b9dba5e 100644 --- a/src/Files.App/Helpers/Layout/LayoutPreferencesManager.cs +++ b/src/Files.App/Helpers/Layout/LayoutPreferencesManager.cs @@ -1,9 +1,6 @@ // Copyright (c) Files Community // Licensed under the MIT License. -using Files.App.Data.Enums; -using System.Text.Json; -using Windows.Storage; using Windows.Win32; namespace Files.App.Helpers @@ -205,43 +202,6 @@ public LayoutPreferencesManager(FolderLayoutModes modeOverride) : this() // Methods - /// - /// This will round the current icon size to get the best result from the File Explorer thumbnail system. - /// - /// Details View: - /// Always uses the Large icon size (32). - /// - /// List View: - /// Always uses the Large icon size (32). - /// - /// Columns View: - /// Always uses the Large icon size (32). - /// - /// Tiles View: - /// Always uses 96, 128, or 256 depending on the layout size. - /// - /// Grid View: - /// Always uses 96, 128, or 256 depending on the layout size. - /// - public uint GetRoundedIconSize() - { - return LayoutMode switch - { - FolderLayoutModes.DetailsView - => Constants.ShellIconSizes.Large, - FolderLayoutModes.ListView - => Constants.ShellIconSizes.Large, - FolderLayoutModes.ColumnView - => Constants.ShellIconSizes.Large, - _ when LayoutMode == FolderLayoutModes.GridView && UserSettingsService.LayoutSettingsService.GridViewSize <= GridViewSizeKind.Small || - LayoutMode == FolderLayoutModes.TilesView - => 96, - _ when LayoutMode == FolderLayoutModes.GridView && UserSettingsService.LayoutSettingsService.GridViewSize <= GridViewSizeKind.Large - => 128, - _ => 256, - }; - } - public Type GetLayoutType(string path, bool changeLayoutMode = true) { var preferencesItem = GetLayoutPreferencesForPath(path); diff --git a/src/Files.App/Helpers/Layout/LayoutSizeKindHelper.cs b/src/Files.App/Helpers/Layout/LayoutSizeKindHelper.cs index 9f45fad22c2f..25bda5f6dc5d 100644 --- a/src/Files.App/Helpers/Layout/LayoutSizeKindHelper.cs +++ b/src/Files.App/Helpers/Layout/LayoutSizeKindHelper.cs @@ -93,6 +93,41 @@ public static int GetListViewRowHeight(ListViewSizeKind listViewSizeKind) } } + /// + /// Gets the desired icon size for the requested layout + /// + /// + /// + public static uint GetIconSize(FolderLayoutModes folderLayoutMode) + { + return folderLayoutMode switch + { + // Details + FolderLayoutModes.DetailsView when LayoutSettingsService.DetailsViewSize == DetailsViewSizeKind.Compact => Constants.ShellIconSizes.Small, + FolderLayoutModes.DetailsView when LayoutSettingsService.DetailsViewSize == DetailsViewSizeKind.Small => Constants.ShellIconSizes.Small, + FolderLayoutModes.DetailsView when LayoutSettingsService.DetailsViewSize == DetailsViewSizeKind.Medium => 20, + FolderLayoutModes.DetailsView when LayoutSettingsService.DetailsViewSize == DetailsViewSizeKind.Large => 24, + FolderLayoutModes.DetailsView when LayoutSettingsService.DetailsViewSize == DetailsViewSizeKind.ExtraLarge => Constants.ShellIconSizes.Large, + + // List + FolderLayoutModes.ListView when LayoutSettingsService.ListViewSize == ListViewSizeKind.Compact => Constants.ShellIconSizes.Small, + FolderLayoutModes.ListView when LayoutSettingsService.ListViewSize == ListViewSizeKind.Small => Constants.ShellIconSizes.Small, + FolderLayoutModes.ListView when LayoutSettingsService.ListViewSize == ListViewSizeKind.Medium => 20, + FolderLayoutModes.ListView when LayoutSettingsService.ListViewSize == ListViewSizeKind.Large => 24, + FolderLayoutModes.ListView when LayoutSettingsService.ListViewSize == ListViewSizeKind.ExtraLarge => Constants.ShellIconSizes.Large, + + // Columns + FolderLayoutModes.ColumnView => Constants.ShellIconSizes.Large, + + // Grid and Tiles + FolderLayoutModes.GridView when LayoutSettingsService.GridViewSize <= GridViewSizeKind.Small => 96, + FolderLayoutModes.GridView when LayoutSettingsService.GridViewSize <= GridViewSizeKind.Large => 128, + FolderLayoutModes.TilesView => 96, + + _ => 256, + }; + } + /// /// Gets the desired height for items in the Columns View /// diff --git a/src/Files.App/ViewModels/ShellViewModel.cs b/src/Files.App/ViewModels/ShellViewModel.cs index e70acabdcdf1..40b950b695be 100644 --- a/src/Files.App/ViewModels/ShellViewModel.cs +++ b/src/Files.App/ViewModels/ShellViewModel.cs @@ -973,9 +973,12 @@ private async Task GetShieldIcon() private async Task LoadThumbnailAsync(ListedItem item, CancellationToken cancellationToken) { var loadNonCachedThumbnail = false; - var thumbnailSize = folderSettings.GetRoundedIconSize(); + var thumbnailSize = LayoutSizeKindHelper.GetIconSize(folderSettings.LayoutMode); var returnIconOnly = UserSettingsService.FoldersSettingsService.ShowThumbnails == false || thumbnailSize < 48; + // TODO Remove this property when all the layouts can support different icon sizes + var useCurrentScale = folderSettings.LayoutMode == FolderLayoutModes.DetailsView || folderSettings.LayoutMode == FolderLayoutModes.ListView; + byte[]? result = null; // Non-cached thumbnails take longer to generate @@ -988,7 +991,7 @@ private async Task LoadThumbnailAsync(ListedItem item, CancellationToken cancell item.ItemPath, thumbnailSize, item.IsFolder, - IconOptions.ReturnThumbnailOnly | IconOptions.ReturnOnlyIfCached); + IconOptions.ReturnThumbnailOnly | IconOptions.ReturnOnlyIfCached | (useCurrentScale ? IconOptions.UseCurrentScale : IconOptions.None)); cancellationToken.ThrowIfCancellationRequested(); loadNonCachedThumbnail = true; @@ -1001,7 +1004,7 @@ private async Task LoadThumbnailAsync(ListedItem item, CancellationToken cancell item.ItemPath, thumbnailSize, item.IsFolder, - IconOptions.ReturnIconOnly); + IconOptions.ReturnIconOnly | (useCurrentScale ? IconOptions.UseCurrentScale : IconOptions.None)); cancellationToken.ThrowIfCancellationRequested(); } @@ -1013,7 +1016,7 @@ private async Task LoadThumbnailAsync(ListedItem item, CancellationToken cancell item.ItemPath, thumbnailSize, item.IsFolder, - returnIconOnly ? IconOptions.ReturnIconOnly : IconOptions.None); + (returnIconOnly ? IconOptions.ReturnIconOnly : IconOptions.None) | (useCurrentScale ? IconOptions.UseCurrentScale : IconOptions.None)); cancellationToken.ThrowIfCancellationRequested(); } @@ -1059,7 +1062,7 @@ await dispatcherQueue.EnqueueOrInvokeAsync(async () => item.ItemPath, thumbnailSize, item.IsFolder, - IconOptions.ReturnThumbnailOnly); + IconOptions.ReturnThumbnailOnly | (useCurrentScale ? IconOptions.UseCurrentScale : IconOptions.None)); } finally { diff --git a/src/Files.App/Views/Layouts/DetailsLayoutPage.xaml b/src/Files.App/Views/Layouts/DetailsLayoutPage.xaml index fd0cccd58557..74174bcaee2b 100644 --- a/src/Files.App/Views/Layouts/DetailsLayoutPage.xaml +++ b/src/Files.App/Views/Layouts/DetailsLayoutPage.xaml @@ -903,13 +903,16 @@ Loaded="StackPanel_Loaded" Orientation="Horizontal"> - + + /// This reference is used to prevent unnecessary icon reloading by only reloading icons when their + /// size changes, even if the layout size changes (since some layout sizes share the same icon size). + /// + private uint currentIconSize; + // Properties protected override ListViewBase ListViewBase => FileList; @@ -136,6 +142,8 @@ protected override void OnNavigatedTo(NavigationEventArgs eventArgs) base.OnNavigatedTo(eventArgs); + currentIconSize = LayoutSizeKindHelper.GetIconSize(FolderLayoutModes.DetailsView); + if (FolderSettings?.ColumnsViewModel is not null) { ColumnsViewModel.DateCreatedColumn = FolderSettings.ColumnsViewModel.DateCreatedColumn; @@ -205,6 +213,14 @@ private void LayoutSettingsService_PropertyChanged(object? sender, PropertyChang // Restore correct scroll position ContentScroller?.ChangeView(null, previousOffset, null); + + // Check if icons need to be reloaded + var newIconSize = LayoutSizeKindHelper.GetIconSize(FolderLayoutModes.DetailsView); + if (newIconSize != currentIconSize) + { + currentIconSize = newIconSize; + _ = ReloadItemIconsAsync(); + } } else { @@ -255,6 +271,9 @@ private void SetItemContainerStyle() // Set correct style FileList.ItemContainerStyle = RegularItemContainerStyle; } + + // Set the width of the icon column. The value is increased by 4px to account for icon overlays. + ColumnsViewModel.IconColumn.UserLength = new GridLength(LayoutSizeKindHelper.GetIconSize(FolderLayoutModes.DetailsView) + 4); } private void FileList_LayoutUpdated(object? sender, object e) diff --git a/src/Files.App/Views/Layouts/GridLayoutPage.xaml b/src/Files.App/Views/Layouts/GridLayoutPage.xaml index de9dff0df41c..4a394e65df23 100644 --- a/src/Files.App/Views/Layouts/GridLayoutPage.xaml +++ b/src/Files.App/Views/Layouts/GridLayoutPage.xaml @@ -302,8 +302,8 @@ + /// This reference is used to prevent unnecessary icon reloading by only reloading icons when their + /// size changes, even if the layout size changes (since some layout sizes share the same icon size). + /// private uint currentIconSize; + private volatile bool shouldSetVerticalScrollMode; // Properties @@ -42,6 +47,14 @@ public int RowHeightListView get => LayoutSizeKindHelper.GetListViewRowHeight(UserSettingsService.LayoutSettingsService.ListViewSize); } + /// + /// Icon Box size in the List View layout. The value is increased by 4px to account for icon overlays. + /// + public int IconBoxSizeListView + { + get => (int)(LayoutSizeKindHelper.GetIconSize(FolderLayoutModes.ListView) + 4); + } + /// /// Item width in the Tiles View layout /// @@ -127,7 +140,7 @@ protected override void OnNavigatedTo(NavigationEventArgs eventArgs) base.OnNavigatedTo(eventArgs); - currentIconSize = FolderSettings.GetRoundedIconSize(); + currentIconSize = LayoutSizeKindHelper.GetIconSize(FolderSettings.LayoutMode); FolderSettings.LayoutModeChangeRequested -= FolderSettings_LayoutModeChangeRequested; FolderSettings.LayoutModeChangeRequested += FolderSettings_LayoutModeChangeRequested; @@ -162,11 +175,11 @@ private void LayoutSettingsService_PropertyChanged(object? sender, PropertyChang if (e.PropertyName == nameof(ILayoutSettingsService.ListViewSize)) { NotifyPropertyChanged(nameof(RowHeightListView)); + NotifyPropertyChanged(nameof(IconBoxSizeListView)); // Update the container style to match the item size SetItemContainerStyle(); - - FolderSettings_IconHeightChanged(); + FolderSettings_IconSizeChanged(); } if (e.PropertyName == nameof(ILayoutSettingsService.TilesViewSize)) { @@ -174,7 +187,7 @@ private void LayoutSettingsService_PropertyChanged(object? sender, PropertyChang // Update the container style to match the item size SetItemContainerStyle(); - FolderSettings_IconHeightChanged(); + FolderSettings_IconSizeChanged(); } if (e.PropertyName == nameof(ILayoutSettingsService.GridViewSize)) { @@ -182,15 +195,14 @@ private void LayoutSettingsService_PropertyChanged(object? sender, PropertyChang // Update the container style to match the item size SetItemContainerStyle(); - - FolderSettings_IconHeightChanged(); + FolderSettings_IconSizeChanged(); } // Restore correct scroll position ContentScroller?.ChangeView(previousHorizontalOffset, previousVerticalOffset, null); } - private async void FolderSettings_LayoutModeChangeRequested(object? sender, LayoutModeEventArgs e) + private void FolderSettings_LayoutModeChangeRequested(object? sender, LayoutModeEventArgs e) { if (FolderSettings.LayoutMode == FolderLayoutModes.ListView || FolderSettings.LayoutMode == FolderLayoutModes.TilesView @@ -199,13 +211,7 @@ private async void FolderSettings_LayoutModeChangeRequested(object? sender, Layo // Set ItemTemplate SetItemTemplate(); SetItemContainerStyle(); - - var requestedIconSize = FolderSettings.GetRoundedIconSize(); - if (requestedIconSize != currentIconSize) - { - currentIconSize = requestedIconSize; - await ReloadItemIconsAsync(); - } + FolderSettings_IconSizeChanged(); } } @@ -487,17 +493,14 @@ protected override async void FileList_PreviewKeyDown(object sender, KeyRoutedEv protected override bool CanGetItemFromElement(object element) => element is GridViewItem; - private async void FolderSettings_IconHeightChanged() + private void FolderSettings_IconSizeChanged() { - // Get new icon size - var requestedIconSize = FolderSettings.GetRoundedIconSize(); - - // Prevents reloading icons when the icon size hasn't changed - if (requestedIconSize != currentIconSize) + // Check if icons need to be reloaded + var newIconSize = LayoutSizeKindHelper.GetIconSize(FolderSettings.LayoutMode); + if (newIconSize != currentIconSize) { - // Update icon size before refreshing - currentIconSize = requestedIconSize; - await ReloadItemIconsAsync(); + currentIconSize = newIconSize; + _ = ReloadItemIconsAsync(); } }