Skip to content

Commit b458649

Browse files
authored
Code Quality: Icon improvements (#14792)
1 parent d7349ec commit b458649

22 files changed

+362
-183
lines changed

src/Files.App/Data/Items/DriveItem.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22
// Licensed under the MIT License. See the LICENSE.
33

44
using Files.App.Storage.WindowsStorage;
5-
using Files.Core.Storage;
6-
using Files.Core.Storage.Enums;
7-
using Files.Core.Storage.LocatableStorage;
8-
using Files.Core.Storage.NestedStorage;
95
using Microsoft.UI.Xaml;
106
using Microsoft.UI.Xaml.Controls;
117
using Microsoft.UI.Xaml.Media.Imaging;
@@ -317,7 +313,16 @@ public int CompareTo(INavigationControlItem other)
317313
public async Task LoadThumbnailAsync()
318314
{
319315
if (!string.IsNullOrEmpty(DeviceID) && !string.Equals(DeviceID, "network-folder"))
320-
IconData ??= await FileThumbnailHelper.LoadIconWithoutOverlayAsync(DeviceID, Constants.ShellIconSizes.Small, false, false, true, true);
316+
{
317+
var result = await FileThumbnailHelper.GetIconAsync(
318+
DeviceID,
319+
Constants.ShellIconSizes.Small,
320+
false,
321+
false,
322+
IconOptions.ReturnIconOnly | IconOptions.UseCurrentScale);
323+
324+
IconData ??= result.IconData;
325+
}
321326

322327
if (Root is not null)
323328
{

src/Files.App/Data/Items/SidebarLibraryItem.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,16 @@ public async Task<bool> CheckDefaultSaveFolderAccess()
4646

4747
public async Task LoadLibraryIconAsync()
4848
{
49-
IconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Path, Constants.ShellIconSizes.Small, false, false, true, true);
49+
var result = await FileThumbnailHelper.GetIconAsync(
50+
Path,
51+
Constants.ShellIconSizes.Small,
52+
false,
53+
false,
54+
IconOptions.ReturnIconOnly | IconOptions.UseCurrentScale);
5055

51-
if (IconData is not null)
52-
Icon = await IconData.ToBitmapAsync();
56+
var bitmapImage = await result.IconData.ToBitmapAsync();
57+
if (bitmapImage is not null)
58+
Icon = bitmapImage;
5359
}
5460

5561
public override int GetHashCode() => Path.GetHashCode(System.StringComparison.OrdinalIgnoreCase);

src/Files.App/Data/Items/WidgetDriveCardItem.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,18 @@ public WidgetDriveCardItem(DriveItem item)
2626

2727
public async Task LoadCardThumbnailAsync()
2828
{
29-
thumbnailData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Item.Path, Constants.ShellIconSizes.Large, true, false, true, true);
30-
31-
// Thumbnail data is valid, set the item icon
32-
if (thumbnailData is not null && thumbnailData.Length > 0)
33-
Thumbnail = await MainWindow.Instance.DispatcherQueue.EnqueueOrInvokeAsync(() => thumbnailData.ToBitmapAsync(), Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
29+
var result = await FileThumbnailHelper.GetIconAsync(
30+
Item.Path,
31+
Constants.ShellIconSizes.Large,
32+
true,
33+
false,
34+
IconOptions.ReturnIconOnly | IconOptions.UseCurrentScale);
35+
36+
thumbnailData = result.IconData;
37+
38+
var bitmapImage = await MainWindow.Instance.DispatcherQueue.EnqueueOrInvokeAsync(() => thumbnailData.ToBitmapAsync(), Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
39+
if (bitmapImage is not null)
40+
Thumbnail = bitmapImage;
3441
}
3542

3643
public int CompareTo(WidgetDriveCardItem? other)

src/Files.App/Data/Items/WidgetFolderCardItem.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,15 @@ public WidgetFolderCardItem(LocationItem item, string text, bool isPinned)
5050

5151
public async Task LoadCardThumbnailAsync()
5252
{
53-
_thumbnailData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Path, Constants.ShellIconSizes.Large, true, false, true, true);
54-
55-
if (_thumbnailData is not null && _thumbnailData.Length > 0)
53+
var result = await FileThumbnailHelper.GetIconAsync(
54+
Path,
55+
Constants.ShellIconSizes.Large,
56+
true,
57+
false,
58+
IconOptions.ReturnIconOnly | IconOptions.UseCurrentScale);
59+
60+
_thumbnailData = result.IconData;
61+
if (_thumbnailData is not null)
5662
Thumbnail = await MainWindow.Instance.DispatcherQueue.EnqueueOrInvokeAsync(() => _thumbnailData.ToBitmapAsync(), Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
5763
}
5864
}

src/Files.App/Data/Models/AppModel.cs

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ public void Clipboard_ContentChanged(object sender, object e)
2727
}
2828
}
2929

30-
private int tabStripSelectedIndex = 0;
30+
private int _TabStripSelectedIndex = 0;
3131
public int TabStripSelectedIndex
3232
{
33-
get => tabStripSelectedIndex;
33+
get => _TabStripSelectedIndex;
3434
set
3535
{
36-
SetProperty(ref tabStripSelectedIndex, value);
36+
SetProperty(ref _TabStripSelectedIndex, value);
3737

3838
if (value >= 0 && value < MainPageViewModel.AppInstances.Count)
3939
{
@@ -44,85 +44,88 @@ public int TabStripSelectedIndex
4444
}
4545
}
4646

47-
private bool isAppElevated = false;
47+
private bool _IsAppElevated = false;
4848
public bool IsAppElevated
4949
{
50-
get => isAppElevated;
51-
set => SetProperty(ref isAppElevated, value);
50+
get => _IsAppElevated;
51+
set => SetProperty(ref _IsAppElevated, value);
5252
}
5353

54-
private bool isPasteEnabled = false;
54+
private bool _IsPasteEnabled = false;
5555
public bool IsPasteEnabled
5656
{
57-
get => isPasteEnabled;
58-
set => SetProperty(ref isPasteEnabled, value);
57+
get => _IsPasteEnabled;
58+
set => SetProperty(ref _IsPasteEnabled, value);
5959
}
6060

61-
private volatile int isMainWindowClosed = 0;
61+
private volatile int _IsMainWindowClosed = 0;
6262
public bool IsMainWindowClosed
6363
{
64-
get => isMainWindowClosed == 1;
64+
get => _IsMainWindowClosed == 1;
6565
set
6666
{
67-
int orig = Interlocked.Exchange(ref isMainWindowClosed, value ? 1 : 0);
68-
if (isMainWindowClosed != orig)
67+
int orig = Interlocked.Exchange(ref _IsMainWindowClosed, value ? 1 : 0);
68+
if (_IsMainWindowClosed != orig)
6969
OnPropertyChanged();
7070
}
7171
}
7272

73-
private int propertiesWindowCount = 0;
73+
private int _PropertiesWindowCount = 0;
7474
public int PropertiesWindowCount
7575
{
76-
get => propertiesWindowCount;
76+
get => _PropertiesWindowCount;
7777
}
7878

7979
public int IncrementPropertiesWindowCount()
8080
{
81-
var result = Interlocked.Increment(ref propertiesWindowCount);
81+
var result = Interlocked.Increment(ref _PropertiesWindowCount);
8282
OnPropertyChanged(nameof(PropertiesWindowCount));
8383
return result;
8484
}
8585

8686
public int DecrementPropertiesWindowCount()
8787
{
88-
var result = Interlocked.Decrement(ref propertiesWindowCount);
88+
var result = Interlocked.Decrement(ref _PropertiesWindowCount);
8989
OnPropertyChanged(nameof(PropertiesWindowCount));
9090
return result;
9191
}
9292

93-
private bool forceProcessTermination = false;
93+
private bool _ForceProcessTermination = false;
9494
public bool ForceProcessTermination
9595
{
96-
get => forceProcessTermination;
97-
set => SetProperty(ref forceProcessTermination, value);
96+
get => _ForceProcessTermination;
97+
set => SetProperty(ref _ForceProcessTermination, value);
9898
}
9999

100-
private string googleDrivePath = string.Empty;
100+
private string _GoogleDrivePath = string.Empty;
101101
/// <summary>
102102
/// Gets or sets a value indicating the path for Google Drive.
103103
/// </summary>
104104
public string GoogleDrivePath
105105
{
106-
get => googleDrivePath;
107-
set => SetProperty(ref googleDrivePath, value);
106+
get => _GoogleDrivePath;
107+
set => SetProperty(ref _GoogleDrivePath, value);
108108
}
109109

110-
private string pCloudDrivePath = string.Empty;
110+
private string _PCloudDrivePath = string.Empty;
111111
/// <summary>
112112
/// Gets or sets a value indicating the path for pCloud Drive.
113113
/// </summary>
114114
public string PCloudDrivePath
115115
{
116-
get => pCloudDrivePath;
117-
set => SetProperty(ref pCloudDrivePath, value);
116+
get => _PCloudDrivePath;
117+
set => SetProperty(ref _PCloudDrivePath, value);
118118
}
119119

120120
/// <summary>
121121
/// Gets or sets a value indicating the AppWindow DPI.
122+
/// TODO update value if the DPI changes
122123
/// </summary>
123-
public float AppWindowDpi
124+
private float _AppWindowDPI = InteropHelpers.GetDpiForWindow(MainWindow.Instance.WindowHandle) / 96f;
125+
public float AppWindowDPI
124126
{
125-
get => InteropHelpers.GetDpiForWindow(MainWindow.Instance.WindowHandle) / 96f;
127+
get => _AppWindowDPI;
128+
set => SetProperty(ref _AppWindowDPI, value);
126129
}
127130
}
128131
}

src/Files.App/Data/Models/ItemViewModel.cs

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,12 @@ private async Task LoadItemThumbnailAsync(ListedItem item)
945945
{
946946
var getIconOnly = UserSettingsService.FoldersSettingsService.ShowThumbnails == false || thumbnailSize < 48;
947947
var getThumbnailOnly = !item.IsExecutable && !getIconOnly;
948-
var iconInfo = await FileThumbnailHelper.LoadIconAndOverlayAsync(item.ItemPath, thumbnailSize, false, getThumbnailOnly, getIconOnly);
948+
var iconInfo = await FileThumbnailHelper.GetIconAsync(
949+
item.ItemPath,
950+
thumbnailSize,
951+
false,
952+
getThumbnailOnly,
953+
getIconOnly ? IconOptions.ReturnIconOnly : IconOptions.None);
949954

950955
if (!iconInfo.isIconCached)
951956
{
@@ -962,7 +967,13 @@ await dispatcherQueue.EnqueueOrInvokeAsync(async () =>
962967
var cancellationTokenSource = new CancellationTokenSource(3000);
963968
while (!iconInfo.isIconCached)
964969
{
965-
iconInfo = await FileThumbnailHelper.LoadIconAndOverlayAsync(item.ItemPath, thumbnailSize, false, getThumbnailOnly, getIconOnly);
970+
iconInfo = await FileThumbnailHelper.GetIconAsync(
971+
item.ItemPath,
972+
thumbnailSize,
973+
false,
974+
getThumbnailOnly,
975+
getIconOnly ? IconOptions.ReturnIconOnly : IconOptions.None);
976+
966977
cancellationTokenSource.Token.ThrowIfCancellationRequested();
967978
await Task.Delay(500);
968979
}
@@ -984,28 +995,39 @@ await dispatcherQueue.EnqueueOrInvokeAsync(async () =>
984995
!item.IsExecutable
985996
)
986997
{
987-
var fileIcon = await FileThumbnailHelper.LoadIconAndOverlayAsync(item.ItemPath, thumbnailSize, false, false, true);
998+
var fileIcon = await FileThumbnailHelper.GetIconAsync(
999+
item.ItemPath,
1000+
thumbnailSize,
1001+
false,
1002+
false,
1003+
IconOptions.ReturnIconOnly);
1004+
9881005
var bitmapImage = await fileIcon.IconData.ToBitmapAsync();
9891006
DefaultIcons.TryAdd(item.FileExtension.ToLowerInvariant(), bitmapImage);
9901007
}
9911008

9921009
}, Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
9931010
}
9941011

995-
if (iconInfo.OverlayData is not null)
1012+
var iconOverlay = await FileThumbnailHelper.GetIconOverlayAsync(item.ItemPath, false);
1013+
if (iconOverlay is not null)
9961014
{
9971015
// Assign the icon overlay to the listed item
9981016
await dispatcherQueue.EnqueueOrInvokeAsync(async () =>
9991017
{
1000-
item.IconOverlay = await iconInfo.OverlayData.ToBitmapAsync();
1018+
item.IconOverlay = await iconOverlay.ToBitmapAsync();
10011019
item.ShieldIcon = await GetShieldIcon();
10021020
}, Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
10031021
}
10041022
}
10051023
else
10061024
{
10071025
var getIconOnly = UserSettingsService.FoldersSettingsService.ShowThumbnails == false || thumbnailSize < 48;
1008-
var iconInfo = await FileThumbnailHelper.LoadIconAndOverlayAsync(item.ItemPath, thumbnailSize, true, false, getIconOnly);
1026+
var iconInfo = await FileThumbnailHelper.GetIconAsync(
1027+
item.ItemPath,
1028+
thumbnailSize,
1029+
true,
1030+
false, getIconOnly ? IconOptions.ReturnIconOnly : IconOptions.None);
10091031

10101032
if (iconInfo.IconData is not null)
10111033
{
@@ -1015,11 +1037,12 @@ await dispatcherQueue.EnqueueOrInvokeAsync(async () =>
10151037
}, Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
10161038
}
10171039

1018-
if (iconInfo.OverlayData is not null)
1040+
var iconOverlay = await FileThumbnailHelper.GetIconOverlayAsync(item.ItemPath, true);
1041+
if (iconOverlay is not null)
10191042
{
10201043
await dispatcherQueue.EnqueueOrInvokeAsync(async () =>
10211044
{
1022-
item.IconOverlay = await iconInfo.OverlayData.ToBitmapAsync();
1045+
item.IconOverlay = await iconOverlay.ToBitmapAsync();
10231046
item.ShieldIcon = await GetShieldIcon();
10241047
}, Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
10251048
}
@@ -1284,10 +1307,15 @@ await SafetyExtensions.IgnoreExceptions(() =>
12841307
ImageSource? groupImage = null;
12851308
if (item.PrimaryItemAttribute != StorageItemTypes.Folder || item.IsArchive)
12861309
{
1287-
var headerIconInfo = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(item.ItemPath, Constants.ShellIconSizes.Large, false, false, true, true);
1310+
var headerIconInfo = await FileThumbnailHelper.GetIconAsync(
1311+
item.ItemPath,
1312+
Constants.ShellIconSizes.Large,
1313+
false,
1314+
false,
1315+
IconOptions.ReturnIconOnly | IconOptions.UseCurrentScale);
12881316

1289-
if (headerIconInfo is not null && !item.IsShortcut)
1290-
groupImage = await dispatcherQueue.EnqueueOrInvokeAsync(() => headerIconInfo.ToBitmapAsync(), Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
1317+
if (headerIconInfo.IconData is not null && !item.IsShortcut)
1318+
groupImage = await dispatcherQueue.EnqueueOrInvokeAsync(() => headerIconInfo.IconData.ToBitmapAsync(), Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
12911319

12921320
// The groupImage is null if loading icon from fulltrust process failed
12931321
if (!item.IsShortcut && !item.IsHiddenItem && !FtpHelpers.IsFtpPath(item.ItemPath) && groupImage is null)

src/Files.App/Data/Models/SidebarPinnedModel.cs

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

4-
using Files.App.UserControls.Widgets;
54
using System.Collections.Specialized;
65
using System.IO;
76
using System.Text.Json.Serialization;
8-
using Windows.Storage.FileProperties;
97

108
namespace Files.App.Data.Models
119
{
@@ -102,11 +100,18 @@ public async Task<LocationItem> CreateLocationItemFromPathAsync(string path)
102100
locationItem.IsInvalid = false;
103101
if (res && res.Result is not null)
104102
{
105-
var iconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(res.Result.Path, Constants.ShellIconSizes.Small, true, false, true, true);
106-
locationItem.IconData = iconData;
107-
108-
if (locationItem.IconData is not null)
109-
locationItem.Icon = await MainWindow.Instance.DispatcherQueue.EnqueueOrInvokeAsync(() => locationItem.IconData.ToBitmapAsync());
103+
var result = await FileThumbnailHelper.GetIconAsync(
104+
res.Result.Path,
105+
Constants.ShellIconSizes.Small,
106+
true,
107+
false,
108+
IconOptions.ReturnIconOnly | IconOptions.UseCurrentScale);
109+
110+
locationItem.IconData = result.IconData;
111+
112+
var bitmapImage = await MainWindow.Instance.DispatcherQueue.EnqueueOrInvokeAsync(() => locationItem.IconData.ToBitmapAsync(), Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
113+
if (bitmapImage is not null)
114+
locationItem.Icon = bitmapImage;
110115
}
111116
}
112117
else

src/Files.App/Helpers/Navigation/NavigationHelpers.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,15 @@ private static async Task UpdateTabInfoAsync(TabBarItem tabItem, object navigati
188188

189189
if (iconSource.ImageSource is null)
190190
{
191-
var iconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(currentPath, Constants.ShellIconSizes.Small, true, false, true, true);
192-
if (iconData is not null)
193-
iconSource.ImageSource = await iconData.ToBitmapAsync();
191+
var result = await FileThumbnailHelper.GetIconAsync(
192+
currentPath,
193+
Constants.ShellIconSizes.Small,
194+
true,
195+
false,
196+
IconOptions.ReturnIconOnly | IconOptions.UseCurrentScale);
197+
198+
if (result.IconData is not null)
199+
iconSource.ImageSource = await result.IconData.ToBitmapAsync();
194200
}
195201

196202
return (tabLocationHeader, iconSource, toolTipText);

0 commit comments

Comments
 (0)