Skip to content

Commit 0903bad

Browse files
yaira2hishitetsu
andauthored
Feature: Use DPI aware icons in the Details View and List View layouts (#16708)
Signed-off-by: Yair <[email protected]> Co-authored-by: hishitetsu <[email protected]>
1 parent aef53d8 commit 0903bad

File tree

7 files changed

+98
-77
lines changed

7 files changed

+98
-77
lines changed

src/Files.App/Helpers/Layout/LayoutPreferencesManager.cs

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
// Copyright (c) Files Community
22
// Licensed under the MIT License.
33

4-
using Files.App.Data.Enums;
5-
using System.Text.Json;
6-
using Windows.Storage;
74
using Windows.Win32;
85

96
namespace Files.App.Helpers
@@ -205,43 +202,6 @@ public LayoutPreferencesManager(FolderLayoutModes modeOverride) : this()
205202

206203
// Methods
207204

208-
/// <summary>
209-
/// This will round the current icon size to get the best result from the File Explorer thumbnail system.
210-
///
211-
/// Details View:
212-
/// Always uses the Large icon size (32).
213-
///
214-
/// List View:
215-
/// Always uses the Large icon size (32).
216-
///
217-
/// Columns View:
218-
/// Always uses the Large icon size (32).
219-
///
220-
/// Tiles View:
221-
/// Always uses 96, 128, or 256 depending on the layout size.
222-
///
223-
/// Grid View:
224-
/// Always uses 96, 128, or 256 depending on the layout size.
225-
/// </summary>
226-
public uint GetRoundedIconSize()
227-
{
228-
return LayoutMode switch
229-
{
230-
FolderLayoutModes.DetailsView
231-
=> Constants.ShellIconSizes.Large,
232-
FolderLayoutModes.ListView
233-
=> Constants.ShellIconSizes.Large,
234-
FolderLayoutModes.ColumnView
235-
=> Constants.ShellIconSizes.Large,
236-
_ when LayoutMode == FolderLayoutModes.GridView && UserSettingsService.LayoutSettingsService.GridViewSize <= GridViewSizeKind.Small ||
237-
LayoutMode == FolderLayoutModes.TilesView
238-
=> 96,
239-
_ when LayoutMode == FolderLayoutModes.GridView && UserSettingsService.LayoutSettingsService.GridViewSize <= GridViewSizeKind.Large
240-
=> 128,
241-
_ => 256,
242-
};
243-
}
244-
245205
public Type GetLayoutType(string path, bool changeLayoutMode = true)
246206
{
247207
var preferencesItem = GetLayoutPreferencesForPath(path);

src/Files.App/Helpers/Layout/LayoutSizeKindHelper.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,41 @@ public static int GetListViewRowHeight(ListViewSizeKind listViewSizeKind)
9393
}
9494
}
9595

96+
/// <summary>
97+
/// Gets the desired icon size for the requested layout
98+
/// </summary>
99+
/// <param name="folderLayoutMode"></param>
100+
/// <returns></returns>
101+
public static uint GetIconSize(FolderLayoutModes folderLayoutMode)
102+
{
103+
return folderLayoutMode switch
104+
{
105+
// Details
106+
FolderLayoutModes.DetailsView when LayoutSettingsService.DetailsViewSize == DetailsViewSizeKind.Compact => Constants.ShellIconSizes.Small,
107+
FolderLayoutModes.DetailsView when LayoutSettingsService.DetailsViewSize == DetailsViewSizeKind.Small => Constants.ShellIconSizes.Small,
108+
FolderLayoutModes.DetailsView when LayoutSettingsService.DetailsViewSize == DetailsViewSizeKind.Medium => 20,
109+
FolderLayoutModes.DetailsView when LayoutSettingsService.DetailsViewSize == DetailsViewSizeKind.Large => 24,
110+
FolderLayoutModes.DetailsView when LayoutSettingsService.DetailsViewSize == DetailsViewSizeKind.ExtraLarge => Constants.ShellIconSizes.Large,
111+
112+
// List
113+
FolderLayoutModes.ListView when LayoutSettingsService.ListViewSize == ListViewSizeKind.Compact => Constants.ShellIconSizes.Small,
114+
FolderLayoutModes.ListView when LayoutSettingsService.ListViewSize == ListViewSizeKind.Small => Constants.ShellIconSizes.Small,
115+
FolderLayoutModes.ListView when LayoutSettingsService.ListViewSize == ListViewSizeKind.Medium => 20,
116+
FolderLayoutModes.ListView when LayoutSettingsService.ListViewSize == ListViewSizeKind.Large => 24,
117+
FolderLayoutModes.ListView when LayoutSettingsService.ListViewSize == ListViewSizeKind.ExtraLarge => Constants.ShellIconSizes.Large,
118+
119+
// Columns
120+
FolderLayoutModes.ColumnView => Constants.ShellIconSizes.Large,
121+
122+
// Grid and Tiles
123+
FolderLayoutModes.GridView when LayoutSettingsService.GridViewSize <= GridViewSizeKind.Small => 96,
124+
FolderLayoutModes.GridView when LayoutSettingsService.GridViewSize <= GridViewSizeKind.Large => 128,
125+
FolderLayoutModes.TilesView => 96,
126+
127+
_ => 256,
128+
};
129+
}
130+
96131
/// <summary>
97132
/// Gets the desired height for items in the Columns View
98133
/// </summary>

src/Files.App/ViewModels/ShellViewModel.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -973,9 +973,12 @@ private async Task<BitmapImage> GetShieldIcon()
973973
private async Task LoadThumbnailAsync(ListedItem item, CancellationToken cancellationToken)
974974
{
975975
var loadNonCachedThumbnail = false;
976-
var thumbnailSize = folderSettings.GetRoundedIconSize();
976+
var thumbnailSize = LayoutSizeKindHelper.GetIconSize(folderSettings.LayoutMode);
977977
var returnIconOnly = UserSettingsService.FoldersSettingsService.ShowThumbnails == false || thumbnailSize < 48;
978978

979+
// TODO Remove this property when all the layouts can support different icon sizes
980+
var useCurrentScale = folderSettings.LayoutMode == FolderLayoutModes.DetailsView || folderSettings.LayoutMode == FolderLayoutModes.ListView;
981+
979982
byte[]? result = null;
980983

981984
// Non-cached thumbnails take longer to generate
@@ -988,7 +991,7 @@ private async Task LoadThumbnailAsync(ListedItem item, CancellationToken cancell
988991
item.ItemPath,
989992
thumbnailSize,
990993
item.IsFolder,
991-
IconOptions.ReturnThumbnailOnly | IconOptions.ReturnOnlyIfCached);
994+
IconOptions.ReturnThumbnailOnly | IconOptions.ReturnOnlyIfCached | (useCurrentScale ? IconOptions.UseCurrentScale : IconOptions.None));
992995

993996
cancellationToken.ThrowIfCancellationRequested();
994997
loadNonCachedThumbnail = true;
@@ -1001,7 +1004,7 @@ private async Task LoadThumbnailAsync(ListedItem item, CancellationToken cancell
10011004
item.ItemPath,
10021005
thumbnailSize,
10031006
item.IsFolder,
1004-
IconOptions.ReturnIconOnly);
1007+
IconOptions.ReturnIconOnly | (useCurrentScale ? IconOptions.UseCurrentScale : IconOptions.None));
10051008

10061009
cancellationToken.ThrowIfCancellationRequested();
10071010
}
@@ -1013,7 +1016,7 @@ private async Task LoadThumbnailAsync(ListedItem item, CancellationToken cancell
10131016
item.ItemPath,
10141017
thumbnailSize,
10151018
item.IsFolder,
1016-
returnIconOnly ? IconOptions.ReturnIconOnly : IconOptions.None);
1019+
(returnIconOnly ? IconOptions.ReturnIconOnly : IconOptions.None) | (useCurrentScale ? IconOptions.UseCurrentScale : IconOptions.None));
10171020

10181021
cancellationToken.ThrowIfCancellationRequested();
10191022
}
@@ -1059,7 +1062,7 @@ await dispatcherQueue.EnqueueOrInvokeAsync(async () =>
10591062
item.ItemPath,
10601063
thumbnailSize,
10611064
item.IsFolder,
1062-
IconOptions.ReturnThumbnailOnly);
1065+
IconOptions.ReturnThumbnailOnly | (useCurrentScale ? IconOptions.UseCurrentScale : IconOptions.None));
10631066
}
10641067
finally
10651068
{

src/Files.App/Views/Layouts/DetailsLayoutPage.xaml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -903,13 +903,16 @@
903903
Loaded="StackPanel_Loaded"
904904
Orientation="Horizontal">
905905
<!-- Item Thumbnail -->
906-
<Grid HorizontalAlignment="Left" VerticalAlignment="Stretch">
906+
<Grid
907+
Width="{Binding ColumnsViewModel.IconColumn.Length.Value, ElementName=PageRoot, Mode=OneWay}"
908+
HorizontalAlignment="Left"
909+
VerticalAlignment="Stretch">
907910

908911
<!-- Thumbnail -->
909912
<Grid
910913
x:Name="IconBox"
911-
Width="24"
912-
Height="24"
914+
Width="{Binding ColumnsViewModel.IconColumn.Length.Value, ElementName=PageRoot, Mode=OneWay}"
915+
Height="{Binding ColumnsViewModel.IconColumn.Length.Value, ElementName=PageRoot, Mode=OneWay}"
913916
HorizontalAlignment="Center"
914917
VerticalAlignment="Center"
915918
AutomationProperties.Name="{helpers:ResourceString Name=FileBrowserThumbnailIconColumnGrid/AutomationProperties/Name}"
@@ -918,8 +921,7 @@
918921
Tag="ItemImage">
919922
<ContentPresenter
920923
x:Name="PicturePresenter"
921-
Width="20"
922-
Height="20"
924+
Margin="2"
923925
HorizontalAlignment="Center"
924926
VerticalAlignment="Center"
925927
x:Load="{x:Bind LoadFileIcon, Mode=OneWay}"

src/Files.App/Views/Layouts/DetailsLayoutPage.xaml.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ public sealed partial class DetailsLayoutPage : BaseGroupableLayoutPage
3030

3131
private ListedItem? _nextItemToSelect;
3232

33+
/// <summary>
34+
/// This reference is used to prevent unnecessary icon reloading by only reloading icons when their
35+
/// size changes, even if the layout size changes (since some layout sizes share the same icon size).
36+
/// </summary>
37+
private uint currentIconSize;
38+
3339
// Properties
3440

3541
protected override ListViewBase ListViewBase => FileList;
@@ -136,6 +142,8 @@ protected override void OnNavigatedTo(NavigationEventArgs eventArgs)
136142

137143
base.OnNavigatedTo(eventArgs);
138144

145+
currentIconSize = LayoutSizeKindHelper.GetIconSize(FolderLayoutModes.DetailsView);
146+
139147
if (FolderSettings?.ColumnsViewModel is not null)
140148
{
141149
ColumnsViewModel.DateCreatedColumn = FolderSettings.ColumnsViewModel.DateCreatedColumn;
@@ -205,6 +213,14 @@ private void LayoutSettingsService_PropertyChanged(object? sender, PropertyChang
205213

206214
// Restore correct scroll position
207215
ContentScroller?.ChangeView(null, previousOffset, null);
216+
217+
// Check if icons need to be reloaded
218+
var newIconSize = LayoutSizeKindHelper.GetIconSize(FolderLayoutModes.DetailsView);
219+
if (newIconSize != currentIconSize)
220+
{
221+
currentIconSize = newIconSize;
222+
_ = ReloadItemIconsAsync();
223+
}
208224
}
209225
else
210226
{
@@ -255,6 +271,9 @@ private void SetItemContainerStyle()
255271
// Set correct style
256272
FileList.ItemContainerStyle = RegularItemContainerStyle;
257273
}
274+
275+
// Set the width of the icon column. The value is increased by 4px to account for icon overlays.
276+
ColumnsViewModel.IconColumn.UserLength = new GridLength(LayoutSizeKindHelper.GetIconSize(FolderLayoutModes.DetailsView) + 4);
258277
}
259278

260279
private void FileList_LayoutUpdated(object? sender, object e)

src/Files.App/Views/Layouts/GridLayoutPage.xaml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,8 @@
302302
<!-- Thumbnail -->
303303
<Grid
304304
x:Name="IconBox"
305-
Width="24"
306-
Height="24"
305+
Width="{Binding IconBoxSizeListView, ElementName=PageRoot, Mode=OneWay}"
306+
Height="{Binding IconBoxSizeListView, ElementName=PageRoot, Mode=OneWay}"
307307
HorizontalAlignment="Center"
308308
VerticalAlignment="Center"
309309
AutomationProperties.Name="{helpers:ResourceString Name=FileBrowserThumbnailIconColumnGrid/AutomationProperties/Name}"
@@ -312,8 +312,7 @@
312312
Tag="ItemImage">
313313
<ContentPresenter
314314
x:Name="PicturePresenter"
315-
Width="20"
316-
Height="20"
315+
Margin="2"
317316
HorizontalAlignment="Center"
318317
VerticalAlignment="Center"
319318
x:Load="{x:Bind LoadFileIcon, Mode=OneWay}"

src/Files.App/Views/Layouts/GridLayoutPage.xaml.cs

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@ public sealed partial class GridLayoutPage : BaseGroupableLayoutPage
2323
{
2424
// Fields
2525

26+
/// <summary>
27+
/// This reference is used to prevent unnecessary icon reloading by only reloading icons when their
28+
/// size changes, even if the layout size changes (since some layout sizes share the same icon size).
29+
/// </summary>
2630
private uint currentIconSize;
31+
2732
private volatile bool shouldSetVerticalScrollMode;
2833

2934
// Properties
@@ -42,6 +47,14 @@ public int RowHeightListView
4247
get => LayoutSizeKindHelper.GetListViewRowHeight(UserSettingsService.LayoutSettingsService.ListViewSize);
4348
}
4449

50+
/// <summary>
51+
/// Icon Box size in the List View layout. The value is increased by 4px to account for icon overlays.
52+
/// </summary>
53+
public int IconBoxSizeListView
54+
{
55+
get => (int)(LayoutSizeKindHelper.GetIconSize(FolderLayoutModes.ListView) + 4);
56+
}
57+
4558
/// <summary>
4659
/// Item width in the Tiles View layout
4760
/// </summary>
@@ -127,7 +140,7 @@ protected override void OnNavigatedTo(NavigationEventArgs eventArgs)
127140

128141
base.OnNavigatedTo(eventArgs);
129142

130-
currentIconSize = FolderSettings.GetRoundedIconSize();
143+
currentIconSize = LayoutSizeKindHelper.GetIconSize(FolderSettings.LayoutMode);
131144

132145
FolderSettings.LayoutModeChangeRequested -= FolderSettings_LayoutModeChangeRequested;
133146
FolderSettings.LayoutModeChangeRequested += FolderSettings_LayoutModeChangeRequested;
@@ -162,35 +175,34 @@ private void LayoutSettingsService_PropertyChanged(object? sender, PropertyChang
162175
if (e.PropertyName == nameof(ILayoutSettingsService.ListViewSize))
163176
{
164177
NotifyPropertyChanged(nameof(RowHeightListView));
178+
NotifyPropertyChanged(nameof(IconBoxSizeListView));
165179

166180
// Update the container style to match the item size
167181
SetItemContainerStyle();
168-
169-
FolderSettings_IconHeightChanged();
182+
FolderSettings_IconSizeChanged();
170183
}
171184
if (e.PropertyName == nameof(ILayoutSettingsService.TilesViewSize))
172185
{
173186
NotifyPropertyChanged(nameof(ItemWidthTilesView));
174187

175188
// Update the container style to match the item size
176189
SetItemContainerStyle();
177-
FolderSettings_IconHeightChanged();
190+
FolderSettings_IconSizeChanged();
178191
}
179192
if (e.PropertyName == nameof(ILayoutSettingsService.GridViewSize))
180193
{
181194
NotifyPropertyChanged(nameof(ItemWidthGridView));
182195

183196
// Update the container style to match the item size
184197
SetItemContainerStyle();
185-
186-
FolderSettings_IconHeightChanged();
198+
FolderSettings_IconSizeChanged();
187199
}
188200

189201
// Restore correct scroll position
190202
ContentScroller?.ChangeView(previousHorizontalOffset, previousVerticalOffset, null);
191203
}
192204

193-
private async void FolderSettings_LayoutModeChangeRequested(object? sender, LayoutModeEventArgs e)
205+
private void FolderSettings_LayoutModeChangeRequested(object? sender, LayoutModeEventArgs e)
194206
{
195207
if (FolderSettings.LayoutMode == FolderLayoutModes.ListView
196208
|| FolderSettings.LayoutMode == FolderLayoutModes.TilesView
@@ -199,13 +211,7 @@ private async void FolderSettings_LayoutModeChangeRequested(object? sender, Layo
199211
// Set ItemTemplate
200212
SetItemTemplate();
201213
SetItemContainerStyle();
202-
203-
var requestedIconSize = FolderSettings.GetRoundedIconSize();
204-
if (requestedIconSize != currentIconSize)
205-
{
206-
currentIconSize = requestedIconSize;
207-
await ReloadItemIconsAsync();
208-
}
214+
FolderSettings_IconSizeChanged();
209215
}
210216
}
211217

@@ -487,17 +493,14 @@ protected override async void FileList_PreviewKeyDown(object sender, KeyRoutedEv
487493
protected override bool CanGetItemFromElement(object element)
488494
=> element is GridViewItem;
489495

490-
private async void FolderSettings_IconHeightChanged()
496+
private void FolderSettings_IconSizeChanged()
491497
{
492-
// Get new icon size
493-
var requestedIconSize = FolderSettings.GetRoundedIconSize();
494-
495-
// Prevents reloading icons when the icon size hasn't changed
496-
if (requestedIconSize != currentIconSize)
498+
// Check if icons need to be reloaded
499+
var newIconSize = LayoutSizeKindHelper.GetIconSize(FolderSettings.LayoutMode);
500+
if (newIconSize != currentIconSize)
497501
{
498-
// Update icon size before refreshing
499-
currentIconSize = requestedIconSize;
500-
await ReloadItemIconsAsync();
502+
currentIconSize = newIconSize;
503+
_ = ReloadItemIconsAsync();
501504
}
502505
}
503506

0 commit comments

Comments
 (0)