Skip to content

Commit 686264e

Browse files
committed
Replaced the placeholder with the actual data sources
1 parent c93e9c0 commit 686264e

File tree

7 files changed

+97
-105
lines changed

7 files changed

+97
-105
lines changed

src/Files.App.Storage/Storables/HomeFolder/HomeFolder.cs

+26-23
Original file line numberDiff line numberDiff line change
@@ -46,37 +46,40 @@ public IAsyncEnumerable<IStorableChild> GetQuickAccessFolderAsync(CancellationTo
4646
}
4747

4848
/// <inheritdoc/>
49-
public async IAsyncEnumerable<IStorableChild> GetLogicalDrivesAsync([EnumeratorCancellation] CancellationToken cancellationToken = default)
49+
public IAsyncEnumerable<IStorableChild> GetLogicalDrivesAsync(CancellationToken cancellationToken = default)
5050
{
51-
var availableDrives = PInvoke.GetLogicalDrives();
52-
if (availableDrives is 0)
53-
yield break;
51+
return GetLogicalDrives().ToAsyncEnumerable();
5452

55-
int count = BitOperations.PopCount(availableDrives);
56-
var driveLetters = new char[count];
57-
58-
count = 0;
59-
char driveLetter = 'A';
60-
while (availableDrives is not 0)
53+
IEnumerable<IStorableChild> GetLogicalDrives()
6154
{
62-
if ((availableDrives & 1) is not 0)
63-
driveLetters[count++] = driveLetter;
55+
var availableDrives = PInvoke.GetLogicalDrives();
56+
if (availableDrives is 0)
57+
yield break;
6458

65-
availableDrives >>= 1;
66-
driveLetter++;
67-
}
59+
int count = BitOperations.PopCount(availableDrives);
60+
var driveLetters = new char[count];
6861

69-
foreach (int letter in driveLetters)
70-
{
71-
cancellationToken.ThrowIfCancellationRequested();
62+
count = 0;
63+
char driveLetter = 'A';
64+
while (availableDrives is not 0)
65+
{
66+
if ((availableDrives & 1) is not 0)
67+
driveLetters[count++] = driveLetter;
7268

73-
if (WindowsStorable.TryParse($"{letter}:\\") is not IWindowsStorable driveRoot)
74-
throw new InvalidOperationException();
69+
availableDrives >>= 1;
70+
driveLetter++;
71+
}
7572

76-
yield return new WindowsFolder(driveRoot.ThisPtr);
77-
await Task.Yield();
78-
}
73+
foreach (char letter in driveLetters)
74+
{
75+
cancellationToken.ThrowIfCancellationRequested();
76+
77+
if (WindowsStorable.TryParse($"{letter}:\\") is not IWindowsStorable driveRoot)
78+
throw new InvalidOperationException();
7979

80+
yield return new WindowsFolder(driveRoot.ThisPtr);
81+
}
82+
}
8083
}
8184

8285
/// <inheritdoc/>

src/Files.App.Storage/Storables/WindowsStorage/IWindowsStorable.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace Files.App.Storage
88
{
9-
public interface IWindowsStorable
9+
public interface IWindowsStorable: IDisposable
1010
{
1111
ComPtr<IShellItem> ThisPtr { get; }
1212
}

src/Files.App.Storage/Storables/WindowsStorage/WindowsFile.cs

+1-9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
namespace Files.App.Storage
99
{
1010
[DebuggerDisplay("{" + nameof(ToString) + "()}")]
11-
public sealed class WindowsFile : WindowsStorable, IChildFile, IDisposable
11+
public sealed class WindowsFile : WindowsStorable, IChildFile
1212
{
1313
public WindowsFile(ComPtr<IShellItem> nativeObject)
1414
{
@@ -19,13 +19,5 @@ public Task<Stream> OpenStreamAsync(FileAccess accessMode, CancellationToken can
1919
{
2020
throw new NotImplementedException();
2121
}
22-
23-
// Disposer
24-
25-
/// <inheritdoc/>
26-
public void Dispose()
27-
{
28-
ThisPtr.Dispose();
29-
}
3022
}
3123
}

src/Files.App.Storage/Storables/WindowsStorage/WindowsFolder.cs

+43-60
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99

1010
namespace Files.App.Storage
1111
{
12-
[DebuggerDisplay("{" + nameof(ToString) + "()")]
13-
public sealed class WindowsFolder : WindowsStorable, IChildFolder, IDisposable
12+
[DebuggerDisplay("{" + nameof(ToString) + "()}")]
13+
public sealed class WindowsFolder : WindowsStorable, IChildFolder
1414
{
1515
public WindowsFolder(ComPtr<IShellItem> nativeObject)
1616
{
@@ -26,81 +26,64 @@ public unsafe WindowsFolder(IShellItem* nativeObject)
2626

2727
public unsafe WindowsFolder(Guid folderId)
2828
{
29-
Guid folderIdLocal = folderId;
30-
Guid IID_IShellItem = IShellItem.IID_Guid;
3129
ComPtr<IShellItem> pItem = default;
3230

33-
HRESULT hr = PInvoke.SHGetKnownFolderItem(&folderIdLocal, KNOWN_FOLDER_FLAG.KF_FLAG_DEFAULT, HANDLE.Null, &IID_IShellItem, (void**)pItem.GetAddressOf());
34-
if (hr.Succeeded)
31+
HRESULT hr = PInvoke.SHGetKnownFolderItem(&folderId, KNOWN_FOLDER_FLAG.KF_FLAG_DEFAULT, HANDLE.Null, IID.IID_IShellItem, (void**)pItem.GetAddressOf());
32+
if (hr.Failed)
3533
{
36-
ThisPtr = pItem;
37-
return;
38-
}
34+
fixed (char* pszShellPath = $"Shell:::{folderId:B}")
35+
hr = PInvoke.SHCreateItemFromParsingName(pszShellPath, null, IID.IID_IShellItem, (void**)pItem.GetAddressOf());
3936

40-
fixed (char* pszShellPath = $"Shell:::{folderId:B}")
41-
hr = PInvoke.SHCreateItemFromParsingName(pszShellPath, null, &IID_IShellItem, (void**)pItem.GetAddressOf());
42-
if (hr.Succeeded)
43-
{
44-
ThisPtr = pItem;
45-
return;
37+
// Invalid FOLDERID; this should never happen.
38+
hr.ThrowOnFailure();
4639
}
40+
41+
ThisPtr = pItem;
4742
}
4843

49-
public async IAsyncEnumerable<IStorableChild> GetItemsAsync(StorableType type = StorableType.All, [EnumeratorCancellation] CancellationToken cancellationToken = default)
44+
public IAsyncEnumerable<IStorableChild> GetItemsAsync(StorableType type = StorableType.All, CancellationToken cancellationToken = default)
5045
{
51-
using ComPtr<IEnumShellItems> pEnumShellItems = GetEnumShellItems();
52-
while (GetNext(pEnumShellItems) is { } pShellItem && !pShellItem.IsNull)
53-
{
54-
cancellationToken.ThrowIfCancellationRequested();
46+
return GetItems().ToAsyncEnumerable();
5547

56-
var pShellFolder = pShellItem.As<IShellFolder>();
57-
var isFolder = IsFolder(pShellItem);
48+
unsafe IEnumerable<IStorableChild> GetItems()
49+
{
50+
ComPtr<IEnumShellItems> pEnumShellItems = default;
51+
GetEnumerator();
5852

59-
if (type is StorableType.File && !isFolder)
53+
ComPtr<IShellItem> pShellItem = default;
54+
while (GetNext() && !pShellItem.IsNull)
6055
{
61-
yield return new WindowsFile(pShellItem);
56+
cancellationToken.ThrowIfCancellationRequested();
57+
var isFolder = pShellItem.HasShellAttributes(SFGAO_FLAGS.SFGAO_FOLDER);
58+
59+
if (type is StorableType.File && !isFolder)
60+
{
61+
yield return new WindowsFile(pShellItem);
62+
}
63+
else if (type is StorableType.Folder && isFolder)
64+
{
65+
yield return new WindowsFolder(pShellItem);
66+
}
67+
else
68+
{
69+
continue;
70+
}
6271
}
63-
else if (type is StorableType.Folder && isFolder)
72+
73+
yield break;
74+
75+
unsafe void GetEnumerator()
6476
{
65-
yield return new WindowsFile(pShellItem);
77+
HRESULT hr = ThisPtr.Get()->BindToHandler(null, BHID.BHID_EnumItems, IID.IID_IEnumShellItems, (void**)pEnumShellItems.GetAddressOf());
78+
hr.ThrowIfFailedOnDebug();
6679
}
67-
else
80+
81+
unsafe bool GetNext()
6882
{
69-
continue;
83+
HRESULT hr = pEnumShellItems.Get()->Next(1, pShellItem.GetAddressOf());
84+
return hr.ThrowIfFailedOnDebug() == HRESULT.S_OK;
7085
}
71-
72-
await Task.Yield();
7386
}
74-
75-
unsafe ComPtr<IEnumShellItems> GetEnumShellItems()
76-
{
77-
ComPtr<IEnumShellItems> pEnumShellItems = default;
78-
Guid IID_IEnumShellItems = typeof(IEnumShellItems).GUID;
79-
Guid BHID_EnumItems = PInvoke.BHID_EnumItems;
80-
HRESULT hr = ThisPtr.Get()->BindToHandler(null, &BHID_EnumItems, &IID_IEnumShellItems, (void**)pEnumShellItems.GetAddressOf());
81-
return pEnumShellItems;
82-
}
83-
84-
unsafe ComPtr<IShellItem> GetNext(ComPtr<IEnumShellItems> pEnumShellItems)
85-
{
86-
ComPtr<IShellItem> pShellItem = default;
87-
HRESULT hr = pEnumShellItems.Get()->Next(1, pShellItem.GetAddressOf());
88-
return pShellItem;
89-
}
90-
91-
unsafe bool IsFolder(ComPtr<IShellItem> pShellItem)
92-
{
93-
return pShellItem.Get()->GetAttributes(SFGAO_FLAGS.SFGAO_FOLDER, out var specifiedAttribute).Succeeded &&
94-
specifiedAttribute is SFGAO_FLAGS.SFGAO_FOLDER;
95-
}
96-
}
97-
98-
// Disposer
99-
100-
/// <inheritdoc/>
101-
public void Dispose()
102-
{
103-
ThisPtr.Dispose();
10487
}
10588
}
10689
}

src/Files.App.Storage/Storables/WindowsStorage/WindowsStorable.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Files.App.Storage
1010
{
1111
public abstract class WindowsStorable : IWindowsStorable, IStorableChild
1212
{
13-
public ComPtr<IShellItem> ThisPtr { get; protected set; } = default;
13+
public ComPtr<IShellItem> ThisPtr { get; protected set; }
1414

1515
public string Id => this.GetDisplayName(SIGDN.SIGDN_FILESYSPATH);
1616

@@ -65,6 +65,12 @@ public abstract class WindowsStorable : IWindowsStorable, IStorableChild
6565
return Task.FromResult<IFolder?>(new WindowsFolder(pParentFolder));
6666
}
6767

68+
/// <inheritdoc/>
69+
public void Dispose()
70+
{
71+
ThisPtr.Dispose();
72+
}
73+
6874
/// <inheritdoc/>
6975
public override string ToString()
7076
{

src/Files.App.Storage/Storables/WindowsStorage/WindowsStorableHelpers.Shell.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public unsafe static string GetDisplayName(this IWindowsStorable storable, SIGDN
4848
HRESULT hr = storable.ThisPtr.Get()->GetDisplayName(options, (PWSTR*)pszName.GetAddressOf());
4949

5050
return hr.ThrowIfFailedOnDebug().Succeeded
51-
? (*pszName.Get()).ToString()
51+
? new string((char*)pszName.Get())
5252
: string.Empty;
5353
}
5454
}

src/Files.App/UserControls/NavigationToolbar.xaml.cs

+18-10
Original file line numberDiff line numberDiff line change
@@ -286,18 +286,26 @@ private async void BreadcrumbBar_ItemDropDownFlyoutOpening(object sender, Breadc
286286
{
287287
if (e.IsRootItem)
288288
{
289-
// TODO: Populate a different flyout for the root item
289+
IHomeFolder homeFolder = new HomeFolder();
290+
290291
e.Flyout.Items.Add(new MenuFlyoutHeaderItem() { Text = "Quick access" });
291-
e.Flyout.Items.Add(new MenuFlyoutItem() { Text = "Desktop" });
292-
e.Flyout.Items.Add(new MenuFlyoutItem() { Text = "Download" });
293-
e.Flyout.Items.Add(new MenuFlyoutItem() { Text = "Documents" });
294-
e.Flyout.Items.Add(new MenuFlyoutItem() { Text = "Pictures" });
295-
e.Flyout.Items.Add(new MenuFlyoutItem() { Text = "Music" });
296-
e.Flyout.Items.Add(new MenuFlyoutItem() { Text = "Videos" });
297-
e.Flyout.Items.Add(new MenuFlyoutItem() { Text = "Recycle bin" });
292+
293+
await foreach (var storable in homeFolder.GetQuickAccessFolderAsync())
294+
{
295+
if (storable is not IWindowsStorable windowsStorable)
296+
continue;
297+
298+
e.Flyout.Items.Add(new MenuFlyoutItem() { Text = windowsStorable.GetDisplayName(Windows.Win32.UI.Shell.SIGDN.SIGDN_PARENTRELATIVEFORUI) });
299+
windowsStorable.Dispose();
300+
}
301+
298302
e.Flyout.Items.Add(new MenuFlyoutHeaderItem() { Text = "Drives" });
299-
e.Flyout.Items.Add(new MenuFlyoutItem() { Text = "Local Disk (C:)" });
300-
e.Flyout.Items.Add(new MenuFlyoutItem() { Text = "Local Disk (D:)" });
303+
304+
await foreach (IWindowsStorable storable in homeFolder.GetLogicalDrivesAsync())
305+
{
306+
e.Flyout.Items.Add(new MenuFlyoutItem() { Text = storable.GetDisplayName(Windows.Win32.UI.Shell.SIGDN.SIGDN_PARENTRELATIVEFORUI) });
307+
storable.Dispose();
308+
}
301309

302310
return;
303311
}

0 commit comments

Comments
 (0)